From 2d53d324d1910af9c2a3c324bf5e8d238f7541bd Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 4 May 2022 20:51:56 -0500 Subject: [PATCH 01/91] Disk plotting alpha 1 (#181) * Added ability to plot using the disk via the `diskplot` command. Co-authored-by: hugepants Co-authored-by: Chris Marslender Co-authored-by: Amine Khaldi --- .gitattributes | 3 + ...ild-asset-linux.sh => build-asset-unix.sh} | 16 +- .github/actions/get-version.sh | 26 +- .github/workflows/attach-release-assets.yml | 8 +- .github/workflows/build-release.yml | 89 +- .gitignore | 40 +- .idea/.gitignore | 8 + .idea/bladebit.iml | 2 + .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/deployment.xml | 14 + .idea/misc.xml | 50 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .vscode/c_cpp_properties.json | 66 +- .vscode/launch.json | 183 +- .vscode/settings.json | 220 +- .vscode/tasks.json | 301 +- CMakeLists.txt | 744 +- CMakeSettings.json | 24 + LICENSE | 400 +- NOTICE | 1474 +- README.md | 8 +- TODO.md | 15 + VERSION | 3 +- bladebit.natvis | 56 +- build.sh | 12 + cmake_modules/FindCatch2.cmake | 9 + cmake_modules/FindNUMA.cmake | 46 +- embed-version.sh | 27 + extract-version.sh | 66 +- src/ChiaConsts.h | 308 +- src/Config.h | 92 +- src/Globals.h | 355 +- src/Platform.h | 106 +- src/PlotContext.cpp | 10 +- src/PlotContext.h | 167 +- src/PlotWriter.cpp | 900 +- src/PlotWriter.h | 214 +- src/SysHost.h | 170 +- src/Types.h | 121 +- src/Util.cpp | 35 - src/Util.h | 309 - src/Version.h | 72 +- src/View.h | 62 +- src/algorithm/RadixSort.h | 672 +- src/algorithm/YSort.cpp | 1020 +- src/algorithm/YSort.h | 68 +- src/b3/blake3.c | 1210 +- src/b3/blake3.h | 112 +- src/b3/blake3_avx2.c | 650 +- src/b3/blake3_avx2_x86-64_unix.S | 3604 ++-- src/b3/blake3_avx512.c | 2408 +-- src/b3/blake3_avx512_x86-64_unix.S | 5144 +++--- src/b3/blake3_dispatch.c | 498 +- src/b3/blake3_impl.h | 470 +- src/b3/blake3_portable.c | 336 +- src/b3/blake3_sse41.c | 1118 +- src/b3/blake3_sse41_x86-64_unix.S | 4028 ++--- src/bech32/segwit_addr.c | 430 +- src/bech32/segwit_addr.h | 228 +- src/fse/LICENSE | 44 +- src/fse/README.md | 76 +- src/fse/bitstream.h | 916 +- src/fse/compiler.h | 222 +- src/fse/debug.c | 88 +- src/fse/debug.h | 242 +- src/fse/entropy_common.c | 480 +- src/fse/error_private.h | 232 +- src/fse/error_public.h | 130 +- src/fse/fse.h | 1416 +- src/fse/fse_compress.c | 1428 +- src/fse/fse_decompress.c | 618 +- src/fse/hist.c | 390 +- src/fse/hist.h | 184 +- src/fse/huf.h | 668 +- src/fse/mem.h | 724 +- src/io/BucketStream.cpp | 204 + src/io/BucketStream.h | 74 + src/io/FileStream.cpp | 4 +- src/io/FileStream.h | 206 +- src/io/HybridStream.cpp | 304 + src/io/HybridStream.h | 41 + src/io/IOUtil.cpp | 4 + src/io/IOUtil.h | 9 + src/io/IStream.h | 33 + src/io/MemoryStream.h | 21 + src/main.cpp | 954 +- src/main_old.h | 786 + src/pch.cpp | 2 +- src/pch.h | 56 +- src/platform/linux/SysHost_Linux.cpp | 847 +- src/platform/macos/SysHost_Macos.cpp | 399 +- src/platform/unix/FileStream_Unix.cpp | 564 +- src/platform/unix/Thread_Unix.cpp | 492 +- src/platform/win32/FileStream_Win32.cpp | 864 +- src/platform/win32/SysHost_Win32.cpp | 1115 +- src/platform/win32/Thread_Win32.cpp | 256 +- src/plotdisk/BitBucketWriter.h | 185 + src/plotdisk/BlockWriter.h | 91 + src/plotdisk/DiskBufferQueue.cpp | 1071 ++ src/plotdisk/DiskBufferQueue.h | 357 + src/plotdisk/DiskF1.h | 229 + src/plotdisk/DiskFp.h | 1243 ++ src/plotdisk/DiskFxGen.h | 6 + src/plotdisk/DiskPairReader.h | 591 + src/plotdisk/DiskPlotBounded.cpp | 202 + src/plotdisk/DiskPlotBounded.h | 4 + src/plotdisk/DiskPlotConfig.h | 74 + src/plotdisk/DiskPlotContext.h | 90 + src/plotdisk/DiskPlotDebug.cpp | 622 + src/plotdisk/DiskPlotDebug.h | 438 + src/plotdisk/DiskPlotInfo.h | 64 + src/plotdisk/DiskPlotPhase1.cpp | 452 + src/plotdisk/DiskPlotPhase1.h | 41 + src/plotdisk/DiskPlotPhase2.cpp | 537 + src/plotdisk/DiskPlotPhase2.h | 35 + src/plotdisk/DiskPlotPhase3.cpp | 1620 ++ src/plotdisk/DiskPlotPhase3.cpp.disabled | 1434 ++ src/plotdisk/DiskPlotPhase3.h | 128 + src/plotdisk/DiskPlotter.cpp | 566 + src/plotdisk/DiskPlotter.h | 39 + src/plotdisk/FileId.h | 134 + src/plotdisk/FpFxGen.h | 189 + src/plotdisk/FpGroupMatcher.h | 303 + src/plotdisk/IOTransforms.h | 24 + src/plotdisk/jobs/IOJob.cpp | 257 + src/plotdisk/jobs/IOJob.h | 52 + src/plotdisk/jobs/JobShared.h | 18 + src/plotdisk/jobs/LookupMapJob.h | 181 + src/plotdisk/jobs/UnpackMapJob.cpp | 52 + src/plotdisk/jobs/UnpackMapJob.h | 78 + src/plotdisk/main_diskplot.h | 493 + src/plotdisk/transforms/FxTransform.h | 38 + src/{memplot => plotmem}/DbgHelper.cpp | 2 +- src/{memplot => plotmem}/DbgHelper.h | 22 + src/{memplot => plotmem}/FxSort.h | 0 src/{memplot => plotmem}/LPGen.h | 58 + src/{memplot => plotmem}/MemPhase1.cpp | 2 +- src/{memplot => plotmem}/MemPhase1.h | 31 +- src/{memplot => plotmem}/MemPhase2.cpp | 0 src/{memplot => plotmem}/MemPhase2.h | 0 src/{memplot => plotmem}/MemPhase3.cpp | 6 +- src/{memplot => plotmem}/MemPhase3.h | 0 src/{memplot => plotmem}/MemPhase4.cpp | 2 +- src/{memplot => plotmem}/MemPhase4.h | 6 +- src/{memplot => plotmem}/MemPlotter.cpp | 4 +- src/{memplot => plotmem}/MemPlotter.h | 0 src/{memplot => plotmem}/ParkWriter.h | 10 +- src/{memplot => plotting}/CTables.h | 0 src/plotting/DTables.h | 14376 ++++++++++++++++ src/plotting/GenSortKey.h | 140 + src/plotting/GlobalPlotConfig.h | 29 + src/plotting/PlotTools.cpp | 152 + src/plotting/PlotTools.h | 56 + src/plotting/PlotTypes.h | 15 + src/plotting/TableWriter.cpp | 1 + src/plotting/TableWriter.h | 443 + src/plotting/Tables.h | 174 + src/plotting/WorkHeap.cpp | 267 + src/plotting/WorkHeap.h | 80 + src/pos/chacha8.cpp | 298 +- src/pos/chacha8.h | 50 +- src/sandbox/Sandbox.h | 6 + src/sandbox/TestF1Buckets.cpp | 104 + .../sandbox_main.cpp} | 0 src/{test => sandbox}/test_numa_sort.cpp | 4 +- src/threading/AutoResetSignal.cpp | 161 + src/threading/AutoResetSignal.h | 42 + src/threading/Fence.cpp | 70 + src/threading/Fence.h | 137 + src/threading/MTJob.h | 479 + src/threading/Semaphore.cpp | 305 +- src/threading/Semaphore.h | 50 +- src/threading/Thread.h | 133 +- src/threading/ThreadPool.cpp | 438 +- src/threading/ThreadPool.h | 144 +- src/tools/FSETableGenerator.cpp | 195 + src/tools/IOTester.cpp | 299 + src/tools/MemTester.cpp | 99 + src/tools/PlotComparer.cpp | 745 + src/tools/PlotReader.cpp | 774 + src/tools/PlotReader.h | 212 + src/tools/PlotTools.h | 12 + src/tools/PlotTools_Main.old.h | 115 + src/tools/PlotValidator.cpp | 1092 ++ src/uint128_t/LICENSE | 21 + src/uint128_t/README.md | 48 + src/uint128_t/endianness.h | 26 + src/uint128_t/uint128_t.build | 10 + src/uint128_t/uint128_t.cpp | 548 + src/uint128_t/uint128_t.h | 8 + src/uint128_t/uint128_t.include | 533 + src/uint128_t/uint128_t_config.include | 18 + src/util/Array.h | 57 + src/util/Array.inl | 175 + src/util/BitField.h | 91 + src/util/BitView.h | 895 + src/util/CliParser.h | 354 + src/util/KeyTools.cpp | 107 + src/util/KeyTools.h | 51 + src/util/Log.cpp | 385 +- src/util/Log.h | 81 +- src/util/SPCQueue.h | 128 + src/util/SPCQueue.inl | 357 + src/util/Span.h | 70 + src/util/StackAllocator.h | 138 + src/util/Util.cpp | 117 + src/util/Util.h | 544 + src/util/jobs/MemJobs.h | 127 + strip-debug-symbols.sh | 11 + symbolicate-crash.sh | 39 + tests/TestBucketStream.cpp | 127 + tests/TestSPCQueue.cpp | 92 + tests/TestUtil.h | 45 + 214 files changed, 61122 insertions(+), 21798 deletions(-) create mode 100644 .gitattributes rename .github/actions/{build-asset-linux.sh => build-asset-unix.sh} (63%) create mode 100644 .idea/.gitignore create mode 100644 .idea/bladebit.iml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/deployment.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 CMakeSettings.json create mode 100644 TODO.md create mode 100755 build.sh create mode 100644 cmake_modules/FindCatch2.cmake create mode 100755 embed-version.sh mode change 100644 => 100755 extract-version.sh delete mode 100644 src/Util.cpp delete mode 100644 src/Util.h create mode 100644 src/io/BucketStream.cpp create mode 100644 src/io/BucketStream.h create mode 100644 src/io/HybridStream.cpp create mode 100644 src/io/HybridStream.h create mode 100644 src/io/IOUtil.cpp create mode 100644 src/io/IOUtil.h create mode 100644 src/io/IStream.h create mode 100644 src/io/MemoryStream.h create mode 100644 src/main_old.h create mode 100644 src/plotdisk/BitBucketWriter.h create mode 100644 src/plotdisk/BlockWriter.h create mode 100644 src/plotdisk/DiskBufferQueue.cpp create mode 100644 src/plotdisk/DiskBufferQueue.h create mode 100644 src/plotdisk/DiskF1.h create mode 100644 src/plotdisk/DiskFp.h create mode 100644 src/plotdisk/DiskFxGen.h create mode 100644 src/plotdisk/DiskPairReader.h create mode 100644 src/plotdisk/DiskPlotBounded.cpp create mode 100644 src/plotdisk/DiskPlotBounded.h create mode 100644 src/plotdisk/DiskPlotConfig.h create mode 100644 src/plotdisk/DiskPlotContext.h create mode 100644 src/plotdisk/DiskPlotDebug.cpp create mode 100644 src/plotdisk/DiskPlotDebug.h create mode 100644 src/plotdisk/DiskPlotInfo.h create mode 100644 src/plotdisk/DiskPlotPhase1.cpp create mode 100644 src/plotdisk/DiskPlotPhase1.h create mode 100644 src/plotdisk/DiskPlotPhase2.cpp create mode 100644 src/plotdisk/DiskPlotPhase2.h create mode 100644 src/plotdisk/DiskPlotPhase3.cpp create mode 100644 src/plotdisk/DiskPlotPhase3.cpp.disabled create mode 100644 src/plotdisk/DiskPlotPhase3.h create mode 100644 src/plotdisk/DiskPlotter.cpp create mode 100644 src/plotdisk/DiskPlotter.h create mode 100644 src/plotdisk/FileId.h create mode 100644 src/plotdisk/FpFxGen.h create mode 100644 src/plotdisk/FpGroupMatcher.h create mode 100644 src/plotdisk/IOTransforms.h create mode 100644 src/plotdisk/jobs/IOJob.cpp create mode 100644 src/plotdisk/jobs/IOJob.h create mode 100644 src/plotdisk/jobs/JobShared.h create mode 100644 src/plotdisk/jobs/LookupMapJob.h create mode 100644 src/plotdisk/jobs/UnpackMapJob.cpp create mode 100644 src/plotdisk/jobs/UnpackMapJob.h create mode 100644 src/plotdisk/main_diskplot.h create mode 100644 src/plotdisk/transforms/FxTransform.h rename src/{memplot => plotmem}/DbgHelper.cpp (98%) rename src/{memplot => plotmem}/DbgHelper.h (96%) rename src/{memplot => plotmem}/FxSort.h (100%) rename src/{memplot => plotmem}/LPGen.h (75%) rename src/{memplot => plotmem}/MemPhase1.cpp (99%) rename src/{memplot => plotmem}/MemPhase1.h (51%) rename src/{memplot => plotmem}/MemPhase2.cpp (100%) rename src/{memplot => plotmem}/MemPhase2.h (100%) rename src/{memplot => plotmem}/MemPhase3.cpp (99%) rename src/{memplot => plotmem}/MemPhase3.h (100%) rename src/{memplot => plotmem}/MemPhase4.cpp (99%) rename src/{memplot => plotmem}/MemPhase4.h (98%) rename src/{memplot => plotmem}/MemPlotter.cpp (99%) rename src/{memplot => plotmem}/MemPlotter.h (100%) rename src/{memplot => plotmem}/ParkWriter.h (99%) rename src/{memplot => plotting}/CTables.h (100%) create mode 100644 src/plotting/DTables.h create mode 100644 src/plotting/GenSortKey.h create mode 100644 src/plotting/GlobalPlotConfig.h create mode 100644 src/plotting/PlotTools.cpp create mode 100644 src/plotting/PlotTools.h create mode 100644 src/plotting/PlotTypes.h create mode 100644 src/plotting/TableWriter.cpp create mode 100644 src/plotting/TableWriter.h create mode 100644 src/plotting/Tables.h create mode 100644 src/plotting/WorkHeap.cpp create mode 100644 src/plotting/WorkHeap.h create mode 100644 src/sandbox/Sandbox.h create mode 100644 src/sandbox/TestF1Buckets.cpp rename src/{test/test_main.cpp => sandbox/sandbox_main.cpp} (100%) rename src/{test => sandbox}/test_numa_sort.cpp (99%) create mode 100644 src/threading/AutoResetSignal.cpp create mode 100644 src/threading/AutoResetSignal.h create mode 100644 src/threading/Fence.cpp create mode 100644 src/threading/Fence.h create mode 100644 src/threading/MTJob.h create mode 100644 src/tools/FSETableGenerator.cpp create mode 100644 src/tools/IOTester.cpp create mode 100644 src/tools/MemTester.cpp create mode 100644 src/tools/PlotComparer.cpp create mode 100644 src/tools/PlotReader.cpp create mode 100644 src/tools/PlotReader.h create mode 100644 src/tools/PlotTools.h create mode 100644 src/tools/PlotTools_Main.old.h create mode 100644 src/tools/PlotValidator.cpp create mode 100644 src/uint128_t/LICENSE create mode 100644 src/uint128_t/README.md create mode 100644 src/uint128_t/endianness.h create mode 100644 src/uint128_t/uint128_t.build create mode 100644 src/uint128_t/uint128_t.cpp create mode 100644 src/uint128_t/uint128_t.h create mode 100644 src/uint128_t/uint128_t.include create mode 100644 src/uint128_t/uint128_t_config.include create mode 100644 src/util/Array.h create mode 100644 src/util/Array.inl create mode 100644 src/util/BitField.h create mode 100644 src/util/BitView.h create mode 100644 src/util/CliParser.h create mode 100644 src/util/KeyTools.cpp create mode 100644 src/util/KeyTools.h create mode 100644 src/util/SPCQueue.h create mode 100644 src/util/SPCQueue.inl create mode 100644 src/util/Span.h create mode 100644 src/util/StackAllocator.h create mode 100644 src/util/Util.cpp create mode 100644 src/util/Util.h create mode 100644 src/util/jobs/MemJobs.h create mode 100755 strip-debug-symbols.sh create mode 100755 symbolicate-crash.sh create mode 100644 tests/TestBucketStream.cpp create mode 100644 tests/TestSPCQueue.cpp create mode 100644 tests/TestUtil.h diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..016487ef --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto + +*.sh text eol=lf \ No newline at end of file diff --git a/.github/actions/build-asset-linux.sh b/.github/actions/build-asset-unix.sh similarity index 63% rename from .github/actions/build-asset-linux.sh rename to .github/actions/build-asset-unix.sh index 6706499d..2ff28d7c 100755 --- a/.github/actions/build-asset-linux.sh +++ b/.github/actions/build-asset-unix.sh @@ -5,9 +5,15 @@ # - BB_ARTIFACT_NAME # - BB_VERSION # -set -e -set -o pipefail +set -eo pipefail +thread_count=2 + +if [[ $OSTYPE == 'darwin'* ]]; then + thread_count=$(sysctl -n hw.logicalcpu) +else + thread_count=$(nproc --all) +fi # TODO: Use specific GCC version echo "System: $(uname -s)" @@ -15,15 +21,15 @@ gcc --version mkdir build && cd build cmake .. -bash -e -o pipefail ../extract-version.sh -cmake --build . --target bladebit --config Release -j $(nproc --all) +bash -eo pipefail ../embed-version.sh +cmake --build . --target bladebit --config Release -j $thread_count chmod +x ./bladebit # Ensure bladebit version matches expected version bb_version="$(./bladebit --version | xargs)" if [[ "$bb_version" != "$BB_VERSION" ]]; then - >&2 echo "Incorrect bladebit version. Got but '$bb_version' expected '$BB_VERSION'." + >&2 echo "Incorrect bladebit version. Got '$bb_version' but expected '$BB_VERSION'." exit 1 fi diff --git a/.github/actions/get-version.sh b/.github/actions/get-version.sh index 70190ec0..4c7ed90b 100755 --- a/.github/actions/get-version.sh +++ b/.github/actions/get-version.sh @@ -1,23 +1,31 @@ #! /usr/bin/env bash # NOTE: This is meant to be run from the repo root dir # -set -e -set -o pipefail +set -eo pipefail os=$1 arch=$2 -version=$(cat VERSION) -suffix= -ext="tar.gz" +version_cmp=($(./extract-version.sh)) -if [[ "$GITHUB_REF_NAME" != "master" ]]; then - suffix="-$GITHUB_REF_NAME" -fi +ver_maj=${version_cmp[0]} +ver_min=${version_cmp[1]} +ver_rev=${version_cmp[2]} +ver_suffix=${version_cmp[3]} + +version="${ver_maj}.${ver_min}.${ver_rev}${ver_suffix}" + +# echo "Ref name: '$GITHUB_REF_NAME'" +# if [[ "$GITHUB_REF_NAME" != "master" ]]; then +# suffix="-${GITHUB_REF_NAME}" +# fi + +ext="tar.gz" if [[ "$os" == "windows" ]]; then ext="zip" fi echo "::set-output name=BB_VERSION::$version" -echo "::set-output name=BB_ARTIFACT_NAME::bladebit-v${version}${suffix}-${os}-${arch}.${ext}" +echo "::set-output name=BB_ARTIFACT_NAME::bladebit-v${version}-${os}-${arch}.${ext}" + diff --git a/.github/workflows/attach-release-assets.yml b/.github/workflows/attach-release-assets.yml index 53e9ddd9..50818edd 100644 --- a/.github/workflows/attach-release-assets.yml +++ b/.github/workflows/attach-release-assets.yml @@ -10,13 +10,13 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: master # Setup Node - - uses: actions/setup-node@v2 - with: { node-version: '14' } + - uses: actions/setup-node@v3 + with: { node-version: '16' } - run: cd .github/actions && npm install @octokit/action # Upload Artifacts as Release Assets @@ -35,6 +35,8 @@ jobs: bladebit-v${BB_VERSION}-ubuntu-arm64.tar.gz bladebit-v${BB_VERSION}-centos-arm64.tar.gz bladebit-v${BB_VERSION}-windows-x86-64.zip + bladebit-v${BB_VERSION}-macos-arm64.tar.gz + bladebit-v${BB_VERSION}-macos-x86-64.tar.gz ) mkdir -p bin diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 2651162b..db4d6908 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Version Number id: version_number @@ -22,7 +22,7 @@ jobs: env: BB_ARTIFACT_NAME: ${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} BB_VERSION: ${{steps.version_number.outputs.BB_VERSION}} - run: .github/actions/build-asset-linux.sh + run: .github/actions/build-asset-unix.sh - name: Upload Artifact Ubuntu x86-64 uses: actions/upload-artifact@v2 @@ -34,10 +34,10 @@ jobs: build-centos-x86-64: runs-on: ubuntu-20.04 container: - image: centos:8 + image: quay.io/centos/centos:stream8 steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Version Number id: version_number @@ -54,7 +54,7 @@ jobs: BB_VERSION: ${{steps.version_number.outputs.BB_VERSION}} run: | source /opt/rh/gcc-toolset-9/enable - .github/actions/build-asset-linux.sh + .github/actions/build-asset-unix.sh - name: Upload Artifact CentOS x86-64 uses: actions/upload-artifact@v2 @@ -64,15 +64,15 @@ jobs: if-no-files-found: error build-ubuntu-arm64: - runs-on: [ARM64] + runs-on: [ARM64, Linux] container: - image: ubuntu:20.04 + image: chianetwork/ubuntu-20.04-builder:latest defaults: run: shell: bash steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Version Number id: version_number @@ -82,13 +82,13 @@ jobs: run: | export DEBIAN_FRONTEND=noninteractive apt update - apt install -y build-essential git cmake libgmp-dev libnuma-dev + apt install -y build-essential git libgmp-dev libnuma-dev - name: Build env: BB_ARTIFACT_NAME: ${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} BB_VERSION: ${{steps.version_number.outputs.BB_VERSION}} - run: .github/actions/build-asset-linux.sh + run: .github/actions/build-asset-unix.sh - name: Upload Artifact Ubuntu ARM64 uses: actions/upload-artifact@v2 @@ -98,12 +98,12 @@ jobs: if-no-files-found: error build-centos-arm64: - runs-on: [ARM64] + runs-on: [ARM64, Linux] container: - image: centos:8 + image: quay.io/centos/centos:stream8 steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Version Number id: version_number @@ -120,7 +120,7 @@ jobs: BB_VERSION: ${{steps.version_number.outputs.BB_VERSION}} run: | source /opt/rh/gcc-toolset-9/enable - .github/actions/build-asset-linux.sh + .github/actions/build-asset-unix.sh - name: Upload Artifact CentOS ARM64 uses: actions/upload-artifact@v2 @@ -133,7 +133,7 @@ jobs: runs-on: windows-2019 steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Version Number shell: bash @@ -149,7 +149,7 @@ jobs: mkdir build && cd build cmake .. - bash -e -o pipefail ../extract-version.sh + bash -e -o pipefail ../embed-version.sh cat ../src/Version.h cmake --build . --target bladebit --config Release @@ -173,3 +173,60 @@ jobs: path: ${{ github.workspace }}/bin/${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} if-no-files-found: error + build-macos-arm64: + runs-on: [macOS, ARM64] + steps: + - name: Cleanup Environment + uses: Chia-Network/actions/clean-workspace@main + + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: Get Version Number + id: version_number + run: bash -e .github/actions/get-version.sh macos arm64 + + - name: Install Prerequisites + run: brew install cmake + + - name: Build + env: + BB_ARTIFACT_NAME: ${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} + BB_VERSION: ${{steps.version_number.outputs.BB_VERSION}} + run: .github/actions/build-asset-unix.sh + + - name: Upload Artifact macOS arm64 + uses: actions/upload-artifact@v2 + with: + name: ${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} + path: ${{ github.workspace }}/bin/${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} + if-no-files-found: error + + build-macos-x86-64: + runs-on: macOS-latest + steps: + - name: Cleanup Environment + uses: Chia-Network/actions/clean-workspace@main + + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: Get Version Number + id: version_number + run: .github/actions/get-version.sh macos x86-64 + + - name: Install Prerequisites + run: brew install cmake + + - name: Build + env: + BB_ARTIFACT_NAME: ${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} + BB_VERSION: ${{steps.version_number.outputs.BB_VERSION}} + run: .github/actions/build-asset-unix.sh + + - name: Upload Artifact macOS x86-64 + uses: actions/upload-artifact@v2 + with: + name: ${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} + path: ${{ github.workspace }}/bin/${{ steps.version_number.outputs.BB_ARTIFACT_NAME }} + if-no-files-found: error diff --git a/.gitignore b/.gitignore index 2b57b132..76391d19 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,21 @@ -.[bB]in/ -.[oP]bj/ -[bB]in/ -[oP]bj/ -[tT]mp/ -_[tT]mp/ - -.vs/ -.sandbox/ -.dist/ -.keys/ -dist/ - -.DS_Store -*.log -park*_hash.txt - -lib/* -build/ +.[bB]in/ +.[oP]bj/ +[bB]in/ +[oP]bj/ +[tT]mp/ +_[tT]mp/ + +.vs/ +.sandbox/ +.dist/ +.keys/ +dist/ +out/ + +.DS_Store +*.log +park*_hash.txt + +lib/* +build*/ +cmake-build*/ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/bladebit.iml b/.idea/bladebit.iml new file mode 100644 index 00000000..f08604bb --- /dev/null +++ b/.idea/bladebit.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..f23d5249 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 00000000..00345774 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..b8e73a4a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,50 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..92fd63aa --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index a6220f2e..8ae95aee 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,25 +1,43 @@ -{ - "configurations": [ - { - "name": "Win32", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [ - "_DEBUG", - "UNICODE", - "_UNICODE" - ], - "windowsSdkVersion": "10.0.19041.0", - "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\Hostx64\\x64\\cl.exe", - "cStandard": "c17", - "cppStandard": "c++17", - "intelliSenseMode": "windows-msvc-x64", - "configurationProvider": "ms-vscode.cmake-tools" - ,"forcedInclude": [ - "src/pch.h" - ] - } - ], - "version": 4 +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "windowsSdkVersion": "10.0.19041.0", + "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\Hostx64\\x64\\cl.exe", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "windows-msvc-x64", + "configurationProvider": "ms-vscode.cmake-tools", + "forcedInclude": [ + "src/pch.h" + ] + }, + { + "name": "macOS", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "macFrameworkPath": [ + "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks" + ], + "compilerPath": "/usr/bin/clang", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "macos-clang-arm64", + "configurationProvider": "ms-vscode.cmake-tools", + "forcedInclude": [ + "src/pch.h" + ] + } + ], + "version": 4 } \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 7ce970ce..fc18bfa4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "version": "0.2.0", "configurations": [ { - "name" : "Bladebit", + "name" : "Bladebit RAM", "type" : "cppdbg", "request" : "launch", "stopAtEntry" : false, @@ -38,35 +38,198 @@ "-v", "${workspaceFolder}/.sandbox" ] - } + }, - ,{ - "name" : "Bladebit Dev", + { + "name" : "Bladebit Disk", "type" : "cppdbg", "request" : "launch", "stopAtEntry" : false, "cwd" : "${workspaceFolder}", - "preLaunchTask" : "build_dev_debug", + "preLaunchTask" : "build_debug", "console" : "internalConsole", + "program": "${workspaceFolder}/build/bladebit", + + "osx": { + "MIMode": "lldb" + }, + "windows": { "type" : "cppvsdbg", - "program": "${workspaceFolder}/build/debug/bladebit_dev.exe" + "program": "${workspaceFolder}/build/debug/bladebit.exe" }, + + "args": [ + "-f", "ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef", + "-p", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8", +// "-c", "xch1uf48n3f50xrs7zds0uek9wp9wmyza6crnex6rw8kwm3jnm39y82q5mvps6", + // "-t", "7", + "-w", + // "-v", + "-i", "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835", // No overflow + "--memo", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef01b7bf8a22a9ac82a003e07b551c851ea683839f3e1beb8ac9ede57d2c020669", + + // "-i", "7a709594087cca18cffa37be61bdecf9b6b465de91acb06ecb6dbe0f4a536f73", // Yes overflow + // "--memo", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef207d52406afa2b6d7d92ea778f407205bd9dca40816c1b1cacfca2a6612b93eb", + + "--show-memo", + "diskplot", + "-t1", "~/plot/tmp", + // "--f1-threads", "12", + "--f1-threads", "3", + "--fp-threads", "62", + // "--fp-threads", "50", + + // "--f1-threads", "7", + // "--fp-threads", "7", + + // "--cache", "200G", + // "--cache", "96G", + // "--cache", "106G", + // "--cache", "64G", + // "-s", + // "-b", "1024", + + "--c-threads", "26", + "--p2-threads", "24", + "--p3-threads", "48", + "~/plot/tmp" + ], + // ,"stopAtEntry": true - "linux": { - "program": "${workspaceFolder}/build/bladebit_dev" - }, + "environment": [] + }, + + { + "name" : "IOTest", + + "type" : "cppdbg", + "request" : "launch", + "stopAtEntry" : false, + "cwd" : "${workspaceFolder}", + "preLaunchTask" : "build_debug", + "console" : "internalConsole", + "program" : "${workspaceFolder}/build/bladebit", + "windows": { + "type" : "cppvsdbg", + "program": "${workspaceFolder}/build/debug/bladebit.exe" + }, + "osx": { - "program": "${workspaceFolder}/build/bladebit_dev" + "program" : "${workspaceFolder}/build/bladebit", + "MIMode": "lldb" }, + "environment": [], + + "args": [ + + // "-t", "32", + // "iotest", + // "memtest", + // "-s", "64MB" + // "-s", "32G", + // "-m", "32G", + // "/mnt/p5510a/disk_tmp" + + /// macOS + "-t", "8", + "memtest", + "-s", "6G", + ".sandbox" + ] + }, + + { + "name" : "Tests", + + "type" : "cppdbg", + "request" : "launch", + "stopAtEntry" : false, + "cwd" : "${workspaceFolder}", + "preLaunchTask" : "build_tests_debug", + "console" : "internalConsole", + + "program": "${workspaceRoot}/build/tests", + "environment": [], "args": [ + "-b", + // "F1CompressToBits" + // "F1GenBucketized" + // "FxSort" + // "FxDisk" + // "F1Disk" + "PairsAndMap" ] } + + + + ,{ + "name" : "Plot Tool", + + "type" : "cppdbg", + "request" : "launch", + "stopAtEntry" : false, + "cwd" : "${workspaceFolder}", + "preLaunchTask" : "build_debug", + "console" : "internalConsole", + + "program": "${workspaceFolder}/build/bladebit", + + "windows": { + "type" : "cppvsdbg", + "program": "${workspaceFolder}/build/debug/bladebit.exe" + }, + + "environment": [], + + "args": [ + /// Validate + "-t", "32", + // "-t", "1", + // "validate", + // "-m", + // "-u", + // "-o", "99.7", + // "/mnt/p5510a/disk_tmp/plot-k32-2022-04-12-13-03-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot.tmp", + + // "/mnt/p5510a/disk_tmp/plot.dat" + + /// Compare + "plotcmp", + "/mnt/p5510a/disk_tmp/plot-k32-2022-04-12-13-53-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot", + "/mnt/p5510a/disk_tmp/plot-k32-2022-04-12-13-03-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot" + ] + }, + + { + "name" : "FSEGen", + + "type" : "cppdbg", + "request" : "launch", + "stopAtEntry" : false, + "cwd" : "${workspaceFolder}", + "preLaunchTask" : "build_fsegen_debug", + "console" : "internalConsole", + + "program": "${workspaceRoot}/build/fsegen", + + // "windows": { + // "type" : "cppvsdbg", + // "program": "${workspaceFolder}/build/debug/fsegen.exe" + // }, + + "environment": [], + + "args": [ + ] + } + ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index d79f45ad..e7653b02 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,112 +1,110 @@ -{ - "cSpell.ignoreWords": [ - "ndebug", - "nominmax" - ], - "files.associations": { - "Fastfile": "ruby", - "*.plist": "xml", - "*.sd": "yaml", - "*.json": "jsonc", - "*.ir": "llvm", - "*.qs": "javascript", - "*.ac": "shellscript", - "player": "json", - "*.userprefs": "xml", - "memory": "cpp", - "cstddef": "cpp", - "string": "cpp", - "chrono": "cpp", - "atomic": "cpp", - "cerrno": "cpp", - "*.tcc": "cpp", - "fstream": "cpp", - "type_traits": "cpp", - "algorithm": "cpp", - "cmath": "cpp", - "array": "cpp", - "deque": "cpp", - "vector": "cpp", - "string_view": "cpp", - "cctype": "cpp", - "clocale": "cpp", - "cstdarg": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "unordered_map": "cpp", - "exception": "cpp", - "memory_resource": "cpp", - "optional": "cpp", - "ratio": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "utility": "cpp", - "initializer_list": "cpp", - "iosfwd": "cpp", - "istream": "cpp", - "limits": "cpp", - "new": "cpp", - "ostream": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "typeinfo": "cpp", - "bitset": "cpp", - "functional": "cpp", - "iomanip": "cpp", - "regex": "cpp", - "future": "cpp", - "bit": "cpp", - "cinttypes": "cpp", - "codecvt": "cpp", - "condition_variable": "cpp", - "cstring": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "unordered_set": "cpp", - "iterator": "cpp", - "numeric": "cpp", - "random": "cpp", - "iostream": "cpp", - "mutex": "cpp", - "shared_mutex": "cpp", - "variant": "cpp", - "segwit_addr.h": "c", - "complex": "cpp", - "forward_list": "cpp", - "typeindex": "cpp", - "valarray": "cpp", - "__bit_reference": "cpp", - "__config": "cpp", - "__debug": "cpp", - "__errc": "cpp", - "__functional_base": "cpp", - "__hash_table": "cpp", - "__locale": "cpp", - "__mutex_base": "cpp", - "__node_handle": "cpp", - "__nullptr": "cpp", - "__split_buffer": "cpp", - "__string": "cpp", - "__threading_support": "cpp", - "__tree": "cpp", - "__tuple": "cpp", - "ios": "cpp", - "locale": "cpp", - "stack": "cpp" - }, - "cSpell.words": [ - "Ryzen" - ], - "C_Cpp.errorSquiggles": "Enabled", - "cmake.configureOnOpen": true, - "cmake.sourceDirectory": "${workspaceFolder}/." - - ,"cmake.generator": "Unix Makefiles" +{ + "cSpell.ignoreWords": [ + "ndebug", + "nominmax" + ], + "files.associations": { + "Fastfile": "ruby", + "*.plist": "xml", + "*.sd": "yaml", + "*.json": "jsonc", + "*.ir": "llvm", + "*.qs": "javascript", + "*.ac": "shellscript", + "player": "json", + "*.userprefs": "xml", + "memory": "cpp", + "cstddef": "cpp", + "string": "cpp", + "chrono": "cpp", + "atomic": "cpp", + "cerrno": "cpp", + "*.tcc": "cpp", + "fstream": "cpp", + "type_traits": "cpp", + "algorithm": "cpp", + "cmath": "cpp", + "array": "cpp", + "deque": "cpp", + "vector": "cpp", + "string_view": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cstdarg": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "unordered_map": "cpp", + "exception": "cpp", + "memory_resource": "cpp", + "optional": "cpp", + "ratio": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "typeinfo": "cpp", + "bitset": "cpp", + "functional": "cpp", + "iomanip": "cpp", + "regex": "cpp", + "future": "cpp", + "bit": "cpp", + "cinttypes": "cpp", + "codecvt": "cpp", + "condition_variable": "cpp", + "cstring": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_set": "cpp", + "iterator": "cpp", + "numeric": "cpp", + "random": "cpp", + "iostream": "cpp", + "mutex": "cpp", + "shared_mutex": "cpp", + "variant": "cpp", + "segwit_addr.h": "c", + "complex": "cpp", + "forward_list": "cpp", + "typeindex": "cpp", + "valarray": "cpp", + "__bit_reference": "cpp", + "__config": "cpp", + "__debug": "cpp", + "__errc": "cpp", + "__functional_base": "cpp", + "__hash_table": "cpp", + "__locale": "cpp", + "__mutex_base": "cpp", + "__node_handle": "cpp", + "__nullptr": "cpp", + "__split_buffer": "cpp", + "__string": "cpp", + "__threading_support": "cpp", + "__tree": "cpp", + "__tuple": "cpp", + "ios": "cpp", + "locale": "cpp", + "stack": "cpp", + "*.include": "cpp" + }, + "cSpell.words": [ + "Ryzen" + ], + "C_Cpp.errorSquiggles": "Enabled", + "cmake.configureOnOpen": true } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 535f178b..be6ce096 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,73 +1,230 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "type" : "shell", - "label" : "build_debug", - "detail" : "Build Debug Bladebit", - "command": "cmake", - - "args": [ - "--build", ".", - "--target", "bladebit", - "--config", "Debug", - "-j", "24" - ], - - "windows":{ - }, - - "linux":{ - "problemMatcher": [ "$gcc" ] - }, - - "osx":{ - "problemMatcher": [ "$gcc" ] - }, - - "options": { - "cwd": "${workspaceFolder}/build" - }, - - "group": { - "kind": "build", - "isDefault": true - } - } - - // Build Debug Develop - ,{ - "type" : "shell", - "label" : "build_dev_debug", - "detail" : "Build Develop Debug", - "command": "cmake", - - "args": [ - "--build", ".", - "--target", "bladebit_dev", - "--config", "Debug", - "-j", "24" - ], - - "windows":{ - }, - - "linux":{ - "problemMatcher": [ "$gcc" ] - }, - - "osx":{ - "problemMatcher": [ "$gcc" ] - }, - - "options": { - "cwd": "${workspaceFolder}/build" - }, - - "group": { - "kind": "build", - "isDefault": true - } - } - ] +{ + "version": "2.0.0", + "tasks": [ + { + "type" : "shell", + "label" : "build_debug", + "detail" : "Build Debug Bladebit", + "command": "cmake", + + "args": [ + "--build", ".", + "--target", "bladebit", + "--config", "Debug", + "-j", "24" + ], + + "windows":{ + }, + + "linux":{ + "problemMatcher": [ "$gcc" ] + }, + + "osx":{ + "problemMatcher": [ "$gcc" ] + }, + + "options": { + "cwd": "${workspaceFolder}/build" + }, + + "group": { + "kind": "build", + "isDefault": true + } + }, + + { + "type" : "shell", + "label" : "rebuild_debug", + "detail" : "Rebuild Debug Bladebit", + "command": "cmake", + + "args": [ + "--build", ".", + "--clean-first", + "--target", "bladebit", + "--config", "Debug", + "-j", "24" + ], + + "windows":{ + }, + + "linux":{ + "problemMatcher": [ "$gcc" ] + }, + + "osx":{ + "problemMatcher": [ "$gcc" ] + }, + + "options": { + "cwd": "${workspaceFolder}/build" + }, + + "group": { + "kind": "build", + "isDefault": true + } + } + + // Build Debug Develop + ,{ + "type" : "shell", + "label" : "build_dev_debug", + "detail" : "Build Develop Debug", + "command": "cmake", + + "args": [ + "--build", ".", + "--target", "bladebit_dev", + "--config", "Debug", + "-j", "24" + ], + + "windows":{ + }, + + "linux":{ + "problemMatcher": [ "$gcc" ] + }, + + "osx":{ + "problemMatcher": [ "$gcc" ] + }, + + "options": { + "cwd": "${workspaceFolder}/build" + }, + + "group": { + "kind": "build", + "isDefault": true + } + } + + // Build Tests Debug + ,{ + "type" : "shell", + "label" : "build_tests_debug", + "command": "cmake", + + "args": [ + "--build", ".", + "--target", "tests", + "--config", "Debug", + "-j", "24" + ], + + "problemMatcher": [ "$gcc" ], + + "windows":{ + "problemMatcher":[ "$msCompile" ] + }, + + "options": { + "cwd": "${workspaceFolder}/build" + }, + + "group": { + "kind": "build", + "isDefault": true + } + } + + // Build Disk Debug + ,{ + "type" : "shell", + "label" : "build_disk_debug", + "detail" : "Build Disk Debug", + "command": "cmake", + + "args": [ + "--build", ".", + "--target", "bladebit_disk", + "--config", "Debug", + "-j", "24" + ], + + "windows":{ + }, + + "linux":{ + "problemMatcher": [ "$gcc" ] + }, + + "osx":{ + "problemMatcher": [ "$gcc" ] + }, + + "options": { + "cwd": "${workspaceFolder}/build" + }, + + "group": { + "kind": "build", + "isDefault": true + } + } + + // Build plot_tool tool + ,{ + "type" : "shell", + "label" : "build_plot_tool_debug", + "command": "cmake", + + "args": [ + "--build", ".", + "--target", "plot_tool", + "--config", "Debug", + "-j", "24" + ], + + "problemMatcher": [ "$gcc" ], + + "windows":{ + "problemMatcher":[ "$msCompile" ] + }, + + "options": { + "cwd": "${workspaceFolder}/build" + }, + + "group": { + "kind": "build", + "isDefault": true + } + } + + // Build fsegen + ,{ + "type" : "shell", + "label" : "build_fsegen_debug", + "command": "cmake", + + "args": [ + "--build", ".", + "--target", "fsegen", + "--config", "Debug", + "-j", "24" + ], + + "problemMatcher": [ "$gcc" ], + + "windows":{ + "problemMatcher":[ "$msCompile" ] + }, + + "options": { + "cwd": "${workspaceFolder}/build" + }, + + "group": { + "kind": "build", + "isDefault": true + } + } + ] } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 517c4405..e2a5306d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,322 +1,422 @@ -cmake_minimum_required(VERSION 3.14 FATAL_ERROR) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_CONFIGURATION_TYPES Release Debug) - -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" - CACHE STRING "Possible values are: Release, Debug" - FORCE - ) -endif() -message("Config: ${CMAKE_BUILD_TYPE}") - -project(bladebit) - -# On CI, update Version.h from our VERSION file -# if(DEFINED ENV{CI}) -# message("Updating Version.h") -# if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") -# execute_process(COMMAND bash.exe extract-version.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -# else() -# execute_process(COMMAND bash extract-version.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -# endif() -# endif() - - - -set(CMAKE_MODULE_PATH - ${CMAKE_MODULE_PATH} - ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules -) - -# Grab BLS -include(FetchContent) - -FetchContent_Declare( - bls - GIT_REPOSITORY https://github.com/Chia-Network/bls-signatures.git - GIT_TAG 1.0.6 -) - -set(BUILD_BLS_PYTHON_BINDINGS "0" CACHE STRING "0") -set(BUILD_BLS_TESTS "0" CACHE STRING "") -set(BUILD_BLS_BENCHMARKS "0" CACHE STRING "") -FetchContent_MakeAvailable(bls) - -# Config -set(CMAKE_C_FLAGS_RELEASE_INIT) -set(CMAKE_C_FLAGS_DEBUG_INIT) -set(CMAKE_CXX_FLAGS_RELEASE_INIT) -set(CMAKE_CXX_FLAGS_DEBUG_INIT) - - -set(c_opts) -set(link_opts) - -set(release_c_opts) -set(debug_c_opts) -set(dev_c_opts) - -set(release_link_opts) -set(debug_link_opts) - -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - - # MSVC - set(c_opts - /std:c++17 - /Zc:__cplusplus - /MP - /Zi - # /EHsc- - # /Wall - /W3 - /WX - /FIpch.h - /wd4068 - /wd4464 - /wd4668 - /wd4820 - /wd4514 - /wd4626 - /wd5027 - /DUNICODE=1 - /DWIN32_LEAN_AND_MEAN=1 - /DNOMINMAX=1 - /D_CRT_SECURE_NO_WARNINGS=1 - /D_HAS_EXCEPTIONS=0 - ${c_opts}) - - set(link_opts - /SUBSYSTEM:CONSOLE - /STACK:33554432,1048576 - ${link_opts}) - - set(release_c_opts - /MT - /Oi - /O2 - /Gy - /GL - /DNDEBUG=1 - /D_NDEBUG=1 - ${release_c_opts}) - - set(debug_c_opts - /MTd - /Od - /DDEBUG=1 - /D_DEBUG=1 - ${debug_c_opts}) - - set(dev_c_opts - ${dev_c_opts}) - - - set(release_link_opts - /DEBUG:FULL - /LTCG - /OPT:REF,ICF,LBR - ${release_link_opts}) - - set(debug_link_opts - /DEBUG:FASTLINK - /OPT:NOREF,NOICF,NOLBR - /INCREMENTAL - ${debug_link_opts}) - - # Dependency config - target_compile_options(bls PRIVATE /MP) - target_compile_options(relic_s PRIVATE /MP) - target_compile_options(sodium PRIVATE /MP) - - target_compile_options(bls PRIVATE $<$:/MT>) - target_compile_options(relic_s PRIVATE $<$:/MT>) - target_compile_options(sodium PRIVATE $<$:/MT>) - - target_compile_options(bls PRIVATE $<$:/MTd>) - target_compile_options(relic_s PRIVATE $<$:/MTd>) - target_compile_options(sodium PRIVATE $<$:/MTd>) - -else() - - # *Nix - set(c_opts --include=pch.h -Wall -Wno-comment -Wno-unknown-pragmas -g ${c_opts}) - - set(release_c_opts - -O3 -flto - -D_NDEBUG=1 - -DNDEBUG=1 - ${release_c_opts}) - - set(debug_c_opts - -O0 - -DDEBUG=1 - -D_DEBUG=1 - ${debug_c_opts}) - - set(dev_c_opts - ${dev_c_opts}) - - # GCC - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - - set(c_opts -fmax-errors=5 ${c_opts}) - - # Clang - elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - - set(c_opts_FLAGS -ferror-limit=5 -fdeclspec -Wunknown-pragmas ${c_opts}) - - endif() - -endif() - - -# Main Sources -file(GLOB_RECURSE bb_sources - RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - CONFIGURE_DEPENDS - LIST_DIRECTORIES false - src/*.cpp - src/*.c -) - -# Headers -file(GLOB_RECURSE bb_headers - RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - CONFIGURE_DEPENDS - LIST_DIRECTORIES false - src/*.h - src/*.hpp - src/*.inl -) - -# Configure dependent on config/platform/architecture -list(FILTER bb_sources EXCLUDE REGEX "src/main\.cpp") -list(FILTER bb_sources EXCLUDE REGEX "src/(test|platform)/.+") -list(FILTER bb_sources EXCLUDE REGEX "src/b3/blake3_(avx|sse).+") - -# Architecture -if(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64" OR ${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "AMD64") - - if(NOT MSVC) - - list(APPEND bb_sources - src/b3/blake3_avx2_x86-64_unix.S - src/b3/blake3_avx512_x86-64_unix.S - src/b3/blake3_sse41_x86-64_unix.S - ) - - set_source_files_properties( - src/b3/blake3_avx2_x86-64_unix.S - src/b3/blake3_avx512_x86-64_unix.S - src/b3/blake3_sse41_x86-64_unix.S - PROPERTIES LANGUAGE C) - else() - list(APPEND bb_sources - src/b3/blake3_avx2.c - src/b3/blake3_avx512.c - src/b3/blake3_sse41.c - ) - # Disable blake3 convertion loss of data warnings - set_source_files_properties( - src/b3/blake3_avx2.c - src/b3/blake3_avx512.c - src/b3/blake3_sse41.c - PROPERTIES COMPILE_FLAGS - /wd4244 - ) - endif() - -elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "arm64" OR ${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "aarch64") -else() - message( FATAL_ERROR "Unsupported architecture '${CMAKE_HOST_SYSTEM_PROCESSOR}'" ) -endif() - -# OS -if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - - file(GLOB_RECURSE src_linux RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - CONFIGURE_DEPENDS LIST_DIRECTORIES false - src/platform/unix/*.cpp - src/platform/linux/*.cpp - ) - list(APPEND bb_sources ${src_linux}) - -elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") - - file(GLOB_RECURSE src_win RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - CONFIGURE_DEPENDS LIST_DIRECTORIES false - src/platform/win32/*.cpp - ) - list(APPEND bb_sources ${src_win}) - -elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - - file(GLOB_RECURSE src_mac RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - CONFIGURE_DEPENDS LIST_DIRECTORIES false - src/platform/unix/*.cpp - src/platform/macos/*.cpp - ) - list(APPEND bb_sources ${src_mac}) - -else() - message( FATAL_ERROR "Unsupported operating system '${CMAKE_SYSTEM_NAME}'" ) -endif() - -# Dev config? -file(GLOB_RECURSE src_dev RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - CONFIGURE_DEPENDS LIST_DIRECTORIES false - src/test/*.cpp -) - -file(GLOB_RECURSE headers_dev RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - CONFIGURE_DEPENDS LIST_DIRECTORIES false - src/test/*.h -) - - -# Exe -find_package(Threads REQUIRED) - -set(platform_libs) - -if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - find_package(NUMA REQUIRED) - set(platform_libs ${NUMA_LIBRARY} gmp) -endif() - -set(bb_include_dirs - ${INCLUDE_DIRECTORIES} - ${CMAKE_CURRENT_SOURCE_DIR}/src -) - - -# BladeBit -add_executable(bladebit src/main.cpp ${bb_sources} ${bb_headers}) -add_executable(bladebit_dev EXCLUDE_FROM_ALL src/test/test_main.cpp ${bb_sources} ${src_dev} ${bb_headers} ${headers_dev}) - -macro(config_proj tgt) - - target_compile_options(${tgt} PRIVATE $<$:${c_opts} ${release_c_opts}>) - target_compile_options(${tgt} PRIVATE $<$:${c_opts} ${debug_c_opts}>) - target_link_options(${tgt} PRIVATE $<$:${link_opts} ${release_link_opts}>) - target_link_options(${tgt} PRIVATE $<$:${link_opts} ${debug_link_opts}>) - - target_include_directories(${tgt} PRIVATE ${bb_include_dirs}) - target_link_libraries(${tgt} Threads::Threads bls ${platform_libs}) -endmacro() - -config_proj(bladebit) -config_proj(bladebit_dev) - - -# Pretty source view for IDE projects -source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src - FILES ${bb_sources} ${bb_headers} ${src_dev} ${headers_dev} -) - +cmake_minimum_required(VERSION 3.20 FATAL_ERROR) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_CONFIGURATION_TYPES Release Debug) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" + CACHE STRING "Possible values are: Release, Debug" + FORCE + ) +endif() + +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14" CACHE STRING "macOS minimum supported version.") +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" CACHE STRING "MSVC Runtime Library") + +project(bladebit C CXX ASM) + +message("Config : ${CMAKE_BUILD_TYPE}") +message("Compiler : ${CMAKE_CXX_COMPILER_ID}") +if(DEFINED ENV{CI}) + message("CI build : true") +else() + message("CI build : false") +endif() + +set(CMAKE_MODULE_PATH + ${CMAKE_MODULE_PATH} + ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules +) + + +# +# Grab Dependencies +# +set(platform_libs) + +# BLS +include(FetchContent) + +FetchContent_Declare( + bls + GIT_REPOSITORY https://github.com/Chia-Network/bls-signatures.git + GIT_TAG 1.0.10 +) + +set(BUILD_BLS_PYTHON_BINDINGS "0" CACHE STRING "0") +set(BUILD_BLS_TESTS "0" CACHE STRING "") +set(BUILD_BLS_BENCHMARKS "0" CACHE STRING "") +FetchContent_MakeAvailable(bls) + +# Threads +find_package(Threads REQUIRED) + +# NUMA +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + find_package(NUMA REQUIRED) + set(platform_libs ${NUMA_LIBRARY}) +endif() + +# Catch +# TODO: Add configuration var to disable this +include(cmake_modules/FindCatch2.cmake) +set_target_properties(Catch2 PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +set_target_properties(Catch2WithMain PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + + +# Config +set(c_opts) +set(link_opts) + +set(release_c_opts) +set(debug_c_opts) +set(dev_c_opts) + +set(release_link_opts) +set(debug_link_opts) + +option(BENCHMARK_MODE "Enable benchmark mode for memplot. No final plot is written." OFF) +if(BENCHMARK_MODE) + add_compile_definitions("BB_BENCHMARK_MODE=1") +endif() + +option(ENABLE_DISK_METRICS "Enable I/O metrics for diskplot." OFF) +if(ENABLE_DISK_METRICS) + add_compile_definitions("BB_IO_METRICS_ON=1") +endif() + +# Embed version inline when in dev mode +if((NOT DEFINED ENV{CI}) AND (NOT DEFINED CACHE{bb_version_embedded})) + message("Embedding local build version") + + set(bb_version_embedded on CACHE BOOL "Version embedding has already happened.") + + set(cmd_ver bash) + if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(cmd_ver bash.exe) + endif() + + execute_process(COMMAND ${cmd_ver} extract-version.sh major OUTPUT_VARIABLE bb_ver_maj WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND_ERROR_IS_FATAL ANY) + execute_process(COMMAND ${cmd_ver} extract-version.sh minor OUTPUT_VARIABLE bb_ver_min WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND_ERROR_IS_FATAL ANY) + execute_process(COMMAND ${cmd_ver} extract-version.sh revision OUTPUT_VARIABLE bb_ver_rev WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND_ERROR_IS_FATAL ANY) + execute_process(COMMAND ${cmd_ver} extract-version.sh suffix OUTPUT_VARIABLE bb_ver_suffix WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND_ERROR_IS_FATAL ANY) + execute_process(COMMAND ${cmd_ver} extract-version.sh commit OUTPUT_VARIABLE bb_ver_commit WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND_ERROR_IS_FATAL ANY) + + # Remove trailing whitespace incurred in windows gitbash + string(STRIP "${bb_ver_maj}" bb_ver_maj) + string(STRIP "${bb_ver_min}" bb_ver_min) + string(STRIP "${bb_ver_rev}" bb_ver_rev) + string(STRIP "${bb_ver_suffix}" bb_ver_suffix) + string(STRIP "${bb_ver_commit}" bb_ver_commit) + + set(bb_ver_suffix ${bb_ver_suffix}-dev) + + # This is slow on windows, so let's cache them + set(bb_ver_maj ${bb_ver_maj} CACHE STRING "") + set(bb_ver_min ${bb_ver_min} CACHE STRING "") + set(bb_ver_rev ${bb_ver_rev} CACHE STRING "") + set(bb_ver_suffix ${bb_ver_suffix} CACHE STRING "") + set(bb_ver_commit ${bb_ver_commit} CACHE STRING "") +endif() + +if(NOT DEFINED ENV{CI}) + add_compile_definitions(BLADEBIT_VERSION_MAJ=${bb_ver_maj}) + add_compile_definitions(BLADEBIT_VERSION_MIN=${bb_ver_min}) + add_compile_definitions(BLADEBIT_VERSION_REV=${bb_ver_rev}) + add_compile_definitions(BLADEBIT_VERSION_SUFFIX="${bb_ver_suffix}") + add_compile_definitions(BLADEBIT_GIT_COMMIT="${bb_ver_commit}") +endif() + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + # MSVC + set(c_opts + /std:c++17 + /Zc:__cplusplus + /MP + /Zi + # /EHsc- + # /Wall + /W3 + /WX + /FIpch.h + /wd4068 + /wd4464 + /wd4668 + /wd4820 + /wd4514 + /wd4626 + /wd5027 + /DUNICODE=1 + /DWIN32_LEAN_AND_MEAN=1 + /DNOMINMAX=1 + /D_CRT_SECURE_NO_WARNINGS=1 + /D_HAS_EXCEPTIONS=0 + ${c_opts}) + + set(link_opts + /SUBSYSTEM:CONSOLE + /STACK:33554432,1048576 + ${link_opts}) + + set(release_c_opts + /Oi + /O2 + /Gy + /GL + /DNDEBUG=1 + /D_NDEBUG=1 + ${release_c_opts}) + + set(debug_c_opts + /Od + /DDEBUG=1 + /D_DEBUG=1 + ${debug_c_opts}) + + set(dev_c_opts + ${dev_c_opts}) + + + set(release_link_opts + /DEBUG:FULL + /LTCG + /OPT:REF,ICF,LBR + ${release_link_opts}) + + set(debug_link_opts +# /DEBUG:FASTLINK + /OPT:NOREF,NOICF,NOLBR +# /INCREMENTAL + ${debug_link_opts}) + + # Dependency config + target_compile_options(bls PRIVATE /MP) + target_compile_options(relic_s PRIVATE /MP) + target_compile_options(sodium PRIVATE /MP) + + target_compile_options(bls PRIVATE $<$:/MT>) + target_compile_options(relic_s PRIVATE $<$:/MT>) + target_compile_options(sodium PRIVATE $<$:/MT>) + + target_compile_options(bls PRIVATE $<$:/MTd>) + target_compile_options(relic_s PRIVATE $<$:/MTd>) + target_compile_options(sodium PRIVATE $<$:/MTd>) + +else() + + # *Nix + set(c_opts --include=pch.h -Wall -Wno-comment -Wno-unknown-pragmas -g ${c_opts}) + + set(release_c_opts + -O3 #-flto + -D_NDEBUG=1 + -DNDEBUG=1 + ${release_c_opts}) + + set(debug_c_opts + -O0 + -DDEBUG=1 + -D_DEBUG=1 + ${debug_c_opts}) + + set(dev_c_opts + ${dev_c_opts}) + + set(link_opts -g -rdynamic #-flto + ${link_opts}) + + # GCC + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + + set(c_opts -fmax-errors=5 ${c_opts}) + + # Avoid ranlib error: plugin needed to handle lto objectR "gcc-ar") + # set(c_opts -ffat-lto-objects ${c_opts}) + + # Build with native architecture when not building release packages + if(NOT DEFINED ENV{CI}) + set(c_opts -march=native ${c_opts}) + endif() + + # Clang + elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + + set(c_opts -ferror-limit=5 -fdeclspec -Wno-empty-body ${c_opts}) + + endif() + +endif() + +# +# Sources +# +file(GLOB_RECURSE bb_sources + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS + LIST_DIRECTORIES false + src/*.cpp + src/*.c +) +set(src_full ${bb_sources}) + +# Headers +file(GLOB_RECURSE bb_headers + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS + LIST_DIRECTORIES false + src/*.h + src/*.hpp + src/*.inl +) + +# Ignore some sources +list(FILTER bb_sources EXCLUDE REGEX "src/main\\.cpp") +list(FILTER bb_sources EXCLUDE REGEX "src/tools/FSETableGenerator.cpp") +list(FILTER bb_sources EXCLUDE REGEX "src/sandbox/.+") +list(FILTER bb_sources EXCLUDE REGEX "src/platform/.+") +list(FILTER bb_sources EXCLUDE REGEX "src/b3/blake3_(avx|sse).+") +list(FILTER bb_sources EXCLUDE REGEX "src/uint128_t/.+") + + +# Project-specific sources +file(GLOB_RECURSE src_tests RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS LIST_DIRECTORIES false + tests/*.cpp +) + +file(GLOB_RECURSE src_dev RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS LIST_DIRECTORIES false + src/sandbox/*.cpp + src/sandbox/*.h +) + + +# Configure dependent on config/platform/architecture +# Architecture +if(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64" OR ${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "AMD64") + + if(NOT MSVC) + list(APPEND bb_sources + src/b3/blake3_avx2_x86-64_unix.S + src/b3/blake3_avx512_x86-64_unix.S + src/b3/blake3_sse41_x86-64_unix.S + ) + else() + list(APPEND bb_sources + src/b3/blake3_avx2.c + src/b3/blake3_avx512.c + src/b3/blake3_sse41.c + src/uint128_t/uint128_t.cpp + ) + # Disable blake3 conversion loss of data warnings + set_source_files_properties( + src/b3/blake3_avx2.c + src/b3/blake3_avx512.c + src/b3/blake3_sse41.c + PROPERTIES COMPILE_FLAGS + /wd4244 + ) + endif() + +elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "arm64" OR ${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "aarch64") +else() + message( FATAL_ERROR "Unsupported architecture '${CMAKE_HOST_SYSTEM_PROCESSOR}'" ) +endif() + +# OS +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + + file(GLOB_RECURSE src_linux RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS LIST_DIRECTORIES false + src/platform/unix/*.cpp + src/platform/linux/*.cpp + ) + list(APPEND bb_sources ${src_linux}) + +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + + file(GLOB_RECURSE src_win RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS LIST_DIRECTORIES false + src/platform/win32/*.cpp + ) + list(APPEND bb_sources ${src_win}) + +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + + file(GLOB_RECURSE src_mac RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS LIST_DIRECTORIES false + src/platform/unix/*.cpp + src/platform/macos/*.cpp + ) + list(APPEND bb_sources ${src_mac}) + +else() + message( FATAL_ERROR "Unsupported operating system '${CMAKE_SYSTEM_NAME}'" ) +endif() + + +# +# Targets +# +set(bb_include_dirs + ${INCLUDE_DIRECTORIES} + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +# macro(config_proj tgt) +# message("Configuring target ${tgt}:${CMAKE_BUILD_TYPE}.") +# target_compile_options(${tgt} PRIVATE $<$:${c_opts} ${release_c_opts}>) +# target_compile_options(${tgt} PRIVATE $<$:${c_opts} ${debug_c_opts}>) +# target_link_options(${tgt} PRIVATE $<$:${link_opts} ${release_link_opts}>) +# target_link_options(${tgt} PRIVATE $<$:${link_opts} ${debug_link_opts}>) + +# target_include_directories(${tgt} PRIVATE ${bb_include_dirs}) +# endmacro() + +# BladeBit +add_library(lib_bladebit ${bb_sources} ${bb_headers}) + +set_target_properties(lib_bladebit PROPERTIES + OUTPUT_NAME bladebit + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" +) +target_link_libraries(lib_bladebit PUBLIC Threads::Threads bls ${platform_libs}) +target_include_directories(lib_bladebit PUBLIC ${bb_include_dirs}) + +target_compile_options(lib_bladebit PUBLIC $<$:${c_opts} ${release_c_opts}>) +target_compile_options(lib_bladebit PUBLIC $<$:${c_opts} ${debug_c_opts}>) +target_link_options(lib_bladebit PUBLIC $<$:${link_opts} ${release_link_opts}>) +target_link_options(lib_bladebit PUBLIC $<$:${link_opts} ${debug_link_opts}>) + +add_executable(bladebit ${bb_headers} src/main.cpp) +target_link_libraries(bladebit PRIVATE lib_bladebit) + +add_executable(bladebit_dev EXCLUDE_FROM_ALL src/sandbox/sandbox_main.cpp ${src_dev} ${bb_headers}) +target_link_libraries(bladebit_dev PRIVATE lib_bladebit) + +# Tools +add_executable(fsegen src/tools/FSETableGenerator.cpp ${bb_sources} ${bb_headers}) +target_link_libraries(fsegen PRIVATE lib_bladebit) + +# add_executable(plot_tool +# src/tools/PlotTools_Main.cpp +# src/tools/PlotReader.cpp +# src/tools/PlotValidator.cpp +# src/tools/PlotComparer.cpp +# ${bb_headers} +# ) +# target_link_libraries(plot_tool PRIVATE lib_bladebit) + +# Tests +add_executable(tests ${src_tests} ${bb_headers}) +set_target_properties(tests PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +target_link_libraries(tests PRIVATE lib_bladebit Catch2::Catch2WithMain) + +# Pretty source view for IDE projects +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src + FILES ${src_full} ${bb_headers} +) + diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 00000000..fb51b4bc --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,24 @@ +{ + "configurations": [ + { + "name": "x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "ctestCommandArgs": "" + }, + { + "name": "MemTest", + "generator": "Ninja", + "configurationType": "Debug", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ] + } + ] +} \ No newline at end of file diff --git a/LICENSE b/LICENSE index 1f11ebce..6bbf859d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,201 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Harold Brenes, Chia Network Inc - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Harold Brenes, Chia Network Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and limitations under the License. \ No newline at end of file diff --git a/NOTICE b/NOTICE index 6d3c00df..2e0e2ee5 100644 --- a/NOTICE +++ b/NOTICE @@ -1,738 +1,738 @@ -Chiapos -https://github.com/Chia-Network/chiapos - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -BLS Signatures Library -https://github.com/Chia-Network/bls-signatures - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - -Libsodium license - The libsodium static library is licensed under the ISC license which requires the following copyright notice. - -ISC License - - Copyright (c) 2013-2020 Frank Denis - - Permission to use, copy, modify, and/or 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. - -GMP license - GMP is distributed under the GNU LGPL v3 license - -Relic license - Relic is used with the Apache 2.0 license - - -BLAKE3 -https://github.com/BLAKE3-team/BLAKE3 - - This work is released into the public domain with CC0 1.0. Alternatively, it is - licensed under the Apache License 2.0. - - ------------------------------------------------------------------------------- - - 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. - - ------------------------------------------------------------------------------- - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2019 Jack O'Connor and Samuel Neves - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and +Chiapos +https://github.com/Chia-Network/chiapos + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +BLS Signatures Library +https://github.com/Chia-Network/bls-signatures + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + +Libsodium license + The libsodium static library is licensed under the ISC license which requires the following copyright notice. + +ISC License + + Copyright (c) 2013-2020 Frank Denis + + Permission to use, copy, modify, and/or 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. + +GMP license + GMP is distributed under the GNU LGPL v3 license + +Relic license + Relic is used with the Apache 2.0 license + + +BLAKE3 +https://github.com/BLAKE3-team/BLAKE3 + + This work is released into the public domain with CC0 1.0. Alternatively, it is + licensed under the Apache License 2.0. + + ------------------------------------------------------------------------------- + + 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. + + ------------------------------------------------------------------------------- + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Jack O'Connor and Samuel Neves + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 0912251a..ea17e8a3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Only **Linux** & **Windows** are supported. Install the following packages: ```bash -# CentOS or Amazon Linux +# CentOS or RHEL-based sudo yum group install -y "Development Tools" sudo yum install -y cmake gmp-devel numactl-devel @@ -25,19 +25,17 @@ sudo apt install -y build-essential cmake libgmp-dev libnuma-dev ``` ### Windows -Must have [Visual Studio 2019](https://visualstudio.microsoft.com/vs/) or its build tools installed. +Must have at least [Visual Studio 2019](https://visualstudio.microsoft.com/vs/) or its build tools installed. ## Building - ```bash # Clone the repo & its submodules git clone https://github.com/Chia-Network/bladebit.git && cd bladebit # Create a build directory for cmake and cd into it -mkdir build -cd build +mkdir -p build && cd build # Generate config files & build cmake .. diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..50bd5463 --- /dev/null +++ b/TODO.md @@ -0,0 +1,15 @@ +# Current Bladebit Disk Beta TODOS + +- [x] Fix compiler issues that popped up on macOS/clang after eliminating wrnings on Linux & Windows. +- [] Fix 128 buckets bug (linepoints are not serialized incorrectly) +- [x] Fix 1024 buckets bug (crashes on P1 T4, probably related to below large block crash) +- [] Fix 1024 buckets bug on P3 +- [] Fix crash on P1 T4 w/ RAID, which actually seems to be w/ big block sizes. (I believe this is due to not rounding up some buffers to block sizes. There's anote about this in fp code.) +- [x] Add no-direct-io flag for both tmp dirs +- [] Add no-direct-io flag for final plot +- [] Add synchronos tmp IO (good with cache) +- [] Perhaps add a different queue for t2 if it's a different physical disk +- [] Add method to reduce cache requirements to 96G instead of 192G +- [] Add non-overflowing version +- [] Bring in avx256 linepoint conversion (already implemented in an old BB branch) +- diff --git a/VERSION b/VERSION index b966e81a..867eb04d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1,2 @@ -1.2.4 \ No newline at end of file +2.0.0 +-alpha0 \ No newline at end of file diff --git a/bladebit.natvis b/bladebit.natvis index a0cb31fd..1a670f01 100644 --- a/bladebit.natvis +++ b/bladebit.natvis @@ -1,13 +1,45 @@ - - - - - [{length}] - - - length - values[$i] - - - + + + + + [{length}] + + + length + values[$i] + + + + + + {{empty}} + [{_length} / {_capacity}] {{ {_elements[0]} }} + [{_length} / {_capacity}] {{ {_elements[0]}, {_elements[1]} }} + [{_length} / {_capacity}] {{ {_elements[0]}, {_elements[1]}, {_elements[2]} }} + [{_length} / {_capacity}] {{ {_elements[0]}, {_elements[1]}, {_elements[2]}, {_elements[3]} }} + [{_length} / {_capacity}] {{ {_elements[0]}, {_elements[1]}, {_elements[2]}, {_elements[3]}, {_elements[4]} }} + [{_length} / {_capacity}] {{ {_elements[0]}, {_elements[1]}, {_elements[2]}, {_elements[3]}, {_elements[4]}, ... }} + + + + _length + _elements[$i] + + + + + + [Address: {(void*)address} Size: {size}] + + + {(void*)address} ( {(uintptr_t)address} ) + + + {(void*)(address + size)} ( {(uintptr_t)(address + size)} ) + + size + + + + \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..e0a8744f --- /dev/null +++ b/build.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e +_dir=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) +cd $_dir + +build_dir=build-release +mkdir -p ${build_dir} +cd ${build_dir} + +cmake .. -DCMAKE_BUILD_TYPE=Release +cmake --build . --target clean --config Release +cmake --build . --target bladebit --config Release -j32 diff --git a/cmake_modules/FindCatch2.cmake b/cmake_modules/FindCatch2.cmake new file mode 100644 index 00000000..ddced5a8 --- /dev/null +++ b/cmake_modules/FindCatch2.cmake @@ -0,0 +1,9 @@ +Include(FetchContent) + +FetchContent_Declare( + Catch2 + GIT_REPOSITORY https://github.com/catchorg/Catch2.git + GIT_TAG v3.0.0-preview4 +) + +FetchContent_MakeAvailable(Catch2) diff --git a/cmake_modules/FindNUMA.cmake b/cmake_modules/FindNUMA.cmake index c5d288ba..741fa8db 100644 --- a/cmake_modules/FindNUMA.cmake +++ b/cmake_modules/FindNUMA.cmake @@ -1,24 +1,24 @@ -# Find libnuma -# -# NUMA_FOUND : True if libnuma was found -# NUMA_INCLUDE_DIR : Where to find numa.h & numaif.h -# NUMA_LIBRARY : Library to link - -include(FindPackageHandleStandardArgs) - -find_path(NUMA_INCLUDE_DIR - NAMES numa.h numaif.h - HINTS ${INCLUDE_INSTALL_DIR}) - -find_library(NUMA_LIBRARY - NAMES numa - HINTS ${LIB_INSTALL_DIR}) - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(NUMA - REQUIRED_VARS NUMA_INCLUDE_DIR NUMA_LIBRARY) - -mark_as_advanced( - NUMA_INCLUDE_DIR +# Find libnuma +# +# NUMA_FOUND : True if libnuma was found +# NUMA_INCLUDE_DIR : Where to find numa.h & numaif.h +# NUMA_LIBRARY : Library to link + +include(FindPackageHandleStandardArgs) + +find_path(NUMA_INCLUDE_DIR + NAMES numa.h numaif.h + HINTS ${INCLUDE_INSTALL_DIR}) + +find_library(NUMA_LIBRARY + NAMES numa + HINTS ${LIB_INSTALL_DIR}) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(NUMA + REQUIRED_VARS NUMA_INCLUDE_DIR NUMA_LIBRARY) + +mark_as_advanced( + NUMA_INCLUDE_DIR NUMA_LIBRARY) \ No newline at end of file diff --git a/embed-version.sh b/embed-version.sh new file mode 100755 index 00000000..c2e1dd7b --- /dev/null +++ b/embed-version.sh @@ -0,0 +1,27 @@ +#! /usr/bin/env bash +set -eo pipefail +cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" + +version=($(./extract-version.sh)) + +ver_maj=${version[0]} +ver_min=${version[1]} +ver_rev=${version[2]} +ver_suffix=${version[3]} +git_commit=${version[4]} + +echo "Version: $ver_maj.$ver_min.$ver_rev$ver_suffix" +echo "Commit : $git_commit" + +sed_inline= +if [[ $OSTYPE == 'darwin'* ]]; then + sed_inline="\'\'" +fi + +version_header='src/Version.h' +sed -i ${sed_inline} -E -r "s/([[:space:]]*#define[[:space:]]+BLADEBIT_VERSION_MAJ[[:space:]]+)([0-9]+)/\1$ver_maj/g" $version_header +sed -i ${sed_inline} -E -r "s/([[:space:]]*#define[[:space:]]+BLADEBIT_VERSION_MIN[[:space:]]+)([0-9]+)/\1$ver_min/g" $version_header +sed -i ${sed_inline} -E -r "s/([[:space:]]*#define[[:space:]]+BLADEBIT_VERSION_REV[[:space:]]+)([0-9]+)/\1$ver_rev/g" $version_header +sed -i ${sed_inline} -E -r "s/([[:space:]]*#define[[:space:]]+BLADEBIT_VERSION_SUFFIX[[:space:]]+)(\".*\")/\1\"$ver_suffix\"/g" $version_header +sed -i ${sed_inline} -E -r "s/([[:space:]]*#define[[:space:]]+BLADEBIT_GIT_COMMIT[[:space:]]+)(\".*\")/\1\"$git_commit\"/g" $version_header + diff --git a/extract-version.sh b/extract-version.sh old mode 100644 new mode 100755 index 11c8ca3c..c15e8107 --- a/extract-version.sh +++ b/extract-version.sh @@ -1,33 +1,73 @@ #! /usr/bin/env bash -set -e -set -o pipefail +set -eo pipefail _dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd)" cd $_dir -set IFS= +# Arguments +ver_component=$1 # The user specified a specified component from the full verison. + # See the case switch below. -version_str=$(cat VERSION | xargs) +# Grab version specified in the file +set IFS= +version_str=$(cat VERSION | head -n 1 | xargs) +version_suffix=$(cat VERSION | tail -n 1 | xargs) version_header='src/Version.h' +if [[ "$version_str" == "$version_suffix" ]]; then + version_suffix= +fi + ver_maj=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1/' | xargs) ver_min=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\2/' | xargs) ver_rev=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\3/' | xargs) -set +e -git_commit=$(git rev-parse HEAD) -set -e +git_commit=$GITHUB_SHA if [[ -z $git_commit ]]; then - git_commit=$GITHUB_SHA + set +e + git_commit=$(git rev-parse HEAD) + set -e fi if [[ -z $git_commit ]]; then git_commit="unknown" fi -echo "Version: $ver_maj.$ver_min.$ver_rev-$git_commit" +# Check if the user wants a specific component +if [[ -n $ver_component ]]; then + + case "$ver_component" in + + "major") + echo -n $ver_maj + ;; -sed -i -E -r "s/(#define BLADEBIT_VERSION_MAJ )([0-9]+)/\1$ver_maj/g" $version_header -sed -i -E -r "s/(#define BLADEBIT_VERSION_MIN )([0-9]+)/\1$ver_min/g" $version_header -sed -i -E -r "s/(#define BLADEBIT_VERSION_REV )([0-9]+)/\1$ver_rev/g" $version_header -sed -i -E -r "s/(#define BLADEBIT_GIT_COMMIT )(.+)/\1\"$git_commit\"/g" $version_header + "minor") + echo -n $ver_min + ;; + + "revision") + echo -n $ver_rev + ;; + + "suffix") + echo -n $version_suffix + ;; + + "commit") + echo -n $git_commit + ;; + + *) + >&2 echo "Invalid version component '${ver_component}'" + exit 1 + ;; + esac + exit 0 +fi +# Emit all version components +echo "$ver_maj" +echo "$ver_min" +echo "$ver_rev" +echo "$version_suffix" +echo "$git_commit" diff --git a/src/ChiaConsts.h b/src/ChiaConsts.h index ee8006e9..e5ef6ece 100644 --- a/src/ChiaConsts.h +++ b/src/ChiaConsts.h @@ -1,143 +1,165 @@ -#pragma once -#include "Util.h" - -// Hard-coded k to 32 -#define _K 32 -#define ENTRIES_PER_TABLE ( 1ull << _K ) - -enum class TableId -{ - Table1 = 0, - Table2 = 1, - Table3 = 2, - Table4 = 3, - Table5 = 4, - Table6 = 5, - Table7 = 6 - - ,_Count -}; - -/// -/// These are extracted from chiapos. -/// Comments are taken directly from chiapos unless otherwise specified. -/// - -// F1 evaluations are done in batches of 2^kBatchSizes -#define kBatchSizes 8 - -// ChaCha8 block size -#define kF1BlockSizeBits 512 - -// Extra bits of output from the f functions. Instead of being a function from k -> k bits, -// it's a function from k -> k + kExtraBits bits. This allows less collisions in matches. -// Refer to the paper for mathematical motivations. -#define kExtraBits 6 - -// Convenience variable -#define kExtraBitsPow (1 << kExtraBits) - -// B and C groups which constitute a bucket, or BC group. These groups determine how -// elements match with each other. Two elements must be in adjacent buckets to match. -#define kB 119ull -#define kC 127ull -#define kBC (kB * kC) - -// This (times k) is the length of the metadata that must be kept for each entry. For example, -// for a table 4 entry, we must keep 4k additional bits for each entry, which is used to compute f5. -// @Harold: Not that we changed this from 1-indexing in the chiapos implementation -// to use 0-indexing. So index 0 == table 1. -const byte kVectorLens[] = { 0, 1, 2, 4, 4, 3, 2 }; - -// Defined in PlotContext.cpp -extern uint16_t L_targets[2][kBC][kExtraBitsPow]; - - -// How many f7s per C1 entry, and how many C1 entries per C2 entry -#define kCheckpoint1Interval 10000 -#define kCheckpoint2Interval 10000 - -// EPP for the final file, the higher this is, the less variability, and lower delta -// Note: if this is increased, ParkVector size must increase -#define kEntriesPerPark 2048 - -// To store deltas for EPP entries, the average delta must be less than this number of bits -#define kMaxAverageDeltaTable1 5.6 -#define kMaxAverageDelta 3.5 - -// C3 entries contain deltas for f7 values, the max average size is the following -#define kC3BitsPerEntry 2.4 - -// The number of bits in the stub is k minus this value -#define kStubMinusBits 3 - -// The ANS encoding R values for the 7 final plot tables -// Tweaking the R values might allow lowering of the max average deltas, -// and reducing final plot size -const double kRValues[7] = { 4.7, 2.75, 2.75, 2.7, 2.6, 2.45 }; - -// The ANS encoding R value for the C3 checkpoint table -#define kC3R 1.0 - -#define kPOSMagic "Proof of Space Plot" -#define kFormatDescription "v1.0" - -// Initializes L_targets table -//----------------------------------------------------------- -inline void LoadLTargets() -{ - static bool _initialized = false; - - if( _initialized ) - return; - - _initialized = true; - - for( byte parity = 0; parity < 2; parity++ ) - { - for( uint16 i = 0; i < kBC; i++ ) - { - uint16_t indJ = i / kC; - - for( uint16 m = 0; m < kExtraBitsPow; m++ ) - { - const uint16 yr = ((indJ + m) % kB) * kC + (((2 * m + parity) * (2 * m + parity) + i) % kC); - - L_targets[parity][i][m] = yr; - } - } - } -} - - -// This is the full size of the deltas section in a park. However, it will not be fully filled -//----------------------------------------------------------- -inline size_t CalculateMaxDeltasSize( TableId tableId ) -{ - if( tableId == TableId::Table1 ) - return CDiv( (size_t)((kEntriesPerPark - 1) * kMaxAverageDeltaTable1), 8 ); - - return CDiv( (size_t)( (kEntriesPerPark - 1) * kMaxAverageDelta ), 8 ); -} - -/// Fixed size for parks -//----------------------------------------------------------- -inline size_t CalculateParkSize( TableId tableId ) -{ - return - CDiv( _K * 2, 8 ) + // LinePoint size - CDiv( (kEntriesPerPark - 1) * (_K - kStubMinusBits), 8 ) + // Stub Size - CalculateMaxDeltasSize( tableId ); // Max delta - - // return CalculateLinePointSize(k) + CalculateStubsSize(k) + - // CalculateMaxDeltasSize(k, table_index); -} - -// Calculates the size of one C3 park. This will store bits for each f7 between -// two C1 checkpoints, depending on how many times that f7 is present. For low -// values of k, we need extra space to account for the additional variability. -constexpr inline static size_t CalculateC3Size() -{ - return (size_t)CDiv( kC3BitsPerEntry * kCheckpoint1Interval, 8 ); -} - +#pragma once +#include "util/Util.h" +#include "plotting/Tables.h" + +// Hard-coded k to 32 +#define _K 32 +#define ENTRIES_PER_TABLE ( 1ull << _K ) + +/// +/// These are extracted from chiapos. +/// Comments are taken directly from chiapos unless otherwise specified. +/// + +// F1 evaluations are done in batches of 2^kBatchSizes +#define kBatchSizes 8 + +// ChaCha8 block size +#define kF1BlockSizeBits 512 + +#define kF1BlockSize (kF1BlockSizeBits / 8u) + +// Extra bits of output from the f functions. Instead of being a function from k -> k bits, +// it's a function from k -> k + kExtraBits bits. This allows less collisions in matches. +// Refer to the paper for mathematical motivations. +#define kExtraBits 6 + +// Convenience variable +#define kExtraBitsPow (1 << kExtraBits) + +// B and C groups which constitute a bucket, or BC group. These groups determine how +// elements match with each other. Two elements must be in adjacent buckets to match. +#define kB 119ull +#define kC 127ull +#define kBC (kB * kC) + +// This (times k) is the length of the metadata that must be kept for each entry. For example, +// for a table 4 entry, we must keep 4k additional bits for each entry, which is used to compute f5. +// @Harold: Not that we changed this from 1-indexing in the chiapos implementation +// to use 0-indexing. So index 0 == table 1. +const byte kVectorLens[] = { 0, 1, 2, 4, 4, 3, 2 }; + +// Defined in PlotContext.cpp +extern uint16_t L_targets[2][kBC][kExtraBitsPow]; + + +// How many f7s per C1 entry, and how many C1 entries per C2 entry +#define kCheckpoint1Interval 10000 +#define kCheckpoint2Interval 10000 + +// EPP for the final file, the higher this is, the less variability, and lower delta +// Note: if this is increased, ParkVector size must increase +#define kEntriesPerPark 2048 + +// To store deltas for EPP entries, the average delta must be less than this number of bits +#define kMaxAverageDeltaTable1 5.6 +#define kMaxAverageDelta 3.5 + +// C3 entries contain deltas for f7 values, the max average size is the following +#define kC3BitsPerEntry 2.4 + +// The number of bits in the stub is k minus this value +#define kStubMinusBits 3 + +// The ANS encoding R values for the 7 final plot tables +// Tweaking the R values might allow lowering of the max average deltas, +// and reducing final plot size +const double kRValues[7] = { 4.7, 2.75, 2.75, 2.7, 2.6, 2.45 }; + +// The ANS encoding R value for the C3 checkpoint table +#define kC3R 1.0 + +#define kPOSMagic "Proof of Space Plot" +#define kFormatDescription "v1.0" + +// Initializes L_targets table +//----------------------------------------------------------- +inline void LoadLTargets() +{ + static bool _initialized = false; + + if( _initialized ) + return; + + _initialized = true; + + for( byte parity = 0; parity < 2; parity++ ) + { + for( uint16 i = 0; i < kBC; i++ ) + { + uint16_t indJ = i / kC; + + for( uint16 m = 0; m < kExtraBitsPow; m++ ) + { + const uint16 yr = ((indJ + m) % kB) * kC + (((2 * m + parity) * (2 * m + parity) + i) % kC); + + L_targets[parity][i][m] = yr; + } + } + } +} + + +// This is the full size of the deltas section in a park. However, it will not be fully filled +//----------------------------------------------------------- +inline constexpr size_t CalculateMaxDeltasSize( const TableId tableId ) +{ + ASSERT( tableId < TableId::Table7 ); + + if( tableId == TableId::Table1 ) + return CDiv( (size_t)((kEntriesPerPark - 1) * kMaxAverageDeltaTable1), 8 ); + + return CDiv( (size_t)( (kEntriesPerPark - 1) * kMaxAverageDelta ), 8 ); +} + +/// Fixed size for parks +//----------------------------------------------------------- +inline size_t CalculateParkSize( TableId tableId ) +{ + return + CDiv( _K * 2, 8 ) + // LinePoint size + CDiv( (kEntriesPerPark - 1) * (_K - kStubMinusBits), 8 ) + // Stub Size + CalculateMaxDeltasSize( tableId ); // Max delta + + // return CalculateLinePointSize(k) + CalculateStubsSize(k) + + // CalculateMaxDeltasSize(k, table_index); +} + +//----------------------------------------------------------- +inline constexpr size_t CalculateParkSize( const TableId tableId, const uint32 k ) +{ + ASSERT( k >= 20 ); + + return + CDiv( k * 2, 8 ) + // LinePoint size + CDiv( (kEntriesPerPark - 1) * (k - kStubMinusBits), 8 ) + // Stub Size + CalculateMaxDeltasSize( tableId ); // Max delta + + // return CalculateLinePointSize(k) + CalculateStubsSize(k) + + // CalculateMaxDeltasSize(k, table_index); +} + +// Calculates the size of one C3 park. This will store bits for each f7 between +// two C1 checkpoints, depending on how many times that f7 is present. +constexpr inline static size_t CalculateC3Size() +{ + return (size_t)CDiv( kC3BitsPerEntry * kCheckpoint1Interval, 8 ); +} + +//----------------------------------------------------------- +inline constexpr static size_t CalculatePark7Size( const uint k ) +{ + return CDiv( (k + 1) * (uint64)kEntriesPerPark, 8 ); +} + +//----------------------------------------------------------- +constexpr inline static size_t LinePointSizeBits( uint32 k ) +{ + return (size_t)k * 2; +} + +//----------------------------------------------------------- +constexpr inline static size_t LinePointSizeBytes( uint32 k ) +{ + return CDiv( LinePointSizeBits( k ), 8 ); +} diff --git a/src/Config.h b/src/Config.h index 28d6a36d..35b12788 100644 --- a/src/Config.h +++ b/src/Config.h @@ -1,43 +1,49 @@ - -// Maximum number of supported threads. -// Jobs will be stack allocated to this size. -// #TODO: This should perhaps be named max jobs. -#define MAX_THREADS 256 - -// Perform Y sorts at the block level. -// Unrolling loops by chacha block size. -#define Y_SORT_BLOCK_MODE 1 - -/// -/// Debug Stuff -/// - -// #define DBG_VERIFY_SORT_F1 1 -// #define DBG_VERIFY_SORT_FX 1 - -// #define DBG_VALIDATE_KB_GROUPS 1 -// #define DBG_TEST_PAIRS 1 - -// #define DBG_WRITE_Y_VALUES 1 - -// #define BOUNDS_PROTECTION 1 - -#define DBG_TEST_PROOF_RANGE { 167000899, 3 } -// #define DBG_DUMP_PROOFS 1 - -// #define DBG_WRITE_PHASE_1_TABLES 1 -#if !DBG_WRITE_PHASE_1_TABLES - // #define DBG_READ_PHASE_1_TABLES 1 -#endif - -// #define DBG_WRITE_MARKED_TABLES 1 -#if !DBG_WRITE_MARKED_TABLES - // #define DBG_READ_MARKED_TABLES 1 -#endif - -// #define DBG_WRITE_LINE_POINTS 1 -// #define DBG_WRITE_SORTED_F7_TABLE 1 - -// Enable to test plotting times without writing to disk -// #define BB_BENCHMARK_MODE 1 - + +// Maximum number of supported threads. +// Jobs will be stack allocated to this size. +// #TODO: This should perhaps be named max jobs. +#define MAX_THREADS 256 +#define BB_MAX_JOBS MAX_THREADS + +// Perform Y sorts at the block level. +// Unrolling loops by chacha block size. +#define Y_SORT_BLOCK_MODE 1 + +/// +/// Debug Stuff +/// + +// #define DBG_VERIFY_SORT_F1 1 +// #define DBG_VERIFY_SORT_FX 1 + +// #define DBG_VALIDATE_KB_GROUPS 1 +// #define DBG_TEST_PAIRS 1 + +// #define DBG_WRITE_Y_VALUES 1 + +// #define BOUNDS_PROTECTION 1 + +#define DBG_TEST_PROOF_RANGE { 167000899, 3 } +// #define DBG_DUMP_PROOFS 1 + +// #define DBG_WRITE_PHASE_1_TABLES 1 +#if !DBG_WRITE_PHASE_1_TABLES + // #define DBG_READ_PHASE_1_TABLES 1 +#endif + +// #define DBG_WRITE_MARKED_TABLES 1 +#if !DBG_WRITE_MARKED_TABLES + // #define DBG_READ_MARKED_TABLES 1 +#endif + +// #define DBG_WRITE_LINE_POINTS 1 +// #define DBG_WRITE_SORTED_F7_TABLE 1 + +// Enable to test plotting times without writing to disk +// #define BB_BENCHMARK_MODE 1 + +// Enable for verbose debug logging. +// Good for tracking internal state changes and finding bugs. +// #define DBG_LOG_ENABLE 1 + + diff --git a/src/Globals.h b/src/Globals.h index ac2a4100..b0e5916a 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -1,155 +1,200 @@ -#pragma once - -#define DEFER( m, ...) m( __VA_ARGS__ ) -#define XSTR( x ) #x -#define STR( x ) XSTR( x ) - - - -#ifdef _MSC_VER - #define FORCE_INLINE __forceinline - #define WARNING_PUSH Unimplemented - - #ifdef _M_ARM - #define PLATFORM_IS_ARM 1 - #endif -#else - - #if __aarch64__ - #define PLATFORM_IS_ARM 1 - #endif - - #if defined( __clang__ ) - #define FORCE_INLINE __attribute__((always_inline)) - // #define WARNING_PUSH _Pragma( STR() ) - #elif defined( __GNUC__ ) - #define FORCE_INLINE __attribute__((always_inline)) - #endif -#endif - -#if __linux__ || __APPLE__ - #define PLATFORM_IS_UNIX 1 -#endif - -#if __linux__ - #define PLATFORM_IS_LINUX 1 -#elif __APPLE__ - #define PLATFORM_IS_APPLE 1 - - #include - #if TARGET_OS_MAC - #define PLATFORM_IS_MACOS 1 - #else - error Unsupported Apple platform. - #endif - -#elif defined( _WIN32 ) - #define PLATFORM_IS_WINDOWS 1 -#endif - - -#define TimerBegin() std::chrono::steady_clock::now() -#define TimerEnd( startTime ) \ - (std::chrono::duration_cast( std::chrono::steady_clock::now() - (startTime) ).count() / 1000.0) - - - -#define ImplementFlagOps( FlagType ) \ -inline FlagType operator | ( FlagType lhs, FlagType rhs ) \ -{ \ - using FlagT = typename std::underlying_type::type; \ - return static_cast( static_cast( lhs ) | static_cast( rhs ) ); \ -} \ - \ -inline FlagType& operator |= ( FlagType& lhs, FlagType rhs ) \ -{ \ - using FlagT = typename std::underlying_type::type; \ - lhs = static_cast( static_cast( lhs ) | static_cast( rhs ) ); \ - return lhs; \ -} \ - \ -inline FlagType operator & ( FlagType lhs, FlagType rhs ) \ -{ \ - using FlagT = typename std::underlying_type::type; \ - return static_cast( static_cast( lhs ) & static_cast( rhs ) ); \ -} \ - \ -inline FlagType& operator &= ( FlagType& lhs, FlagType rhs ) \ -{ \ - using FlagT = typename std::underlying_type::type; \ - lhs = static_cast( static_cast( lhs ) & static_cast( rhs ) ); \ - return lhs; \ -} \ - \ -inline FlagType operator ~ ( FlagType lhs ) \ -{ \ - using FlagT = typename std::underlying_type::type; \ - lhs = static_cast( ~static_cast( lhs ) ); \ - return lhs; \ -} - - - -template< typename T> -inline bool IsFlagSet( T flags, T flag ) -{ - using UT = typename std::underlying_type::type; - return ( static_cast( flags ) & static_cast( flag ) ) != static_cast( 0 ); -} - -template< typename T> -inline bool AreAllFlagSet( T flagsToCheck, T flagsRequired ) -{ - using UT = typename std::underlying_type::type; - return ( static_cast( flagsToCheck ) & static_cast( flagsRequired ) ) == static_cast( flagsRequired ); -} - -template< typename T> -inline T SetFlag( T& flags, T flag ) -{ - using UT = typename std::underlying_type::type; - flags = static_cast( static_cast( flags ) | static_cast( flag ) ); - - return flags; -} - -template< typename T> -inline T UnSetFlag( T& flags, T flag ) -{ - using UT = typename std::underlying_type::type; - flags = static_cast( static_cast( flags ) & ~( static_cast( flag ) ) ); - - return flags; -} - -template< typename T> -inline T ToggleFlag( T& flags, T flag, bool value ) -{ - if( value ) - SetFlag( flags, flag ); - else - UnSetFlag( flags, flag ); - - return flags; -} - - -template -struct Span -{ - T* values; - size_t length; - - inline Span(){} - - inline Span( T* values, size_t length ) - : values( values ) - , length( length ) - {} - - inline T& operator[]( unsigned int index ) const { return this->values[index]; } - inline T& operator[]( int index ) const { return this->values[index]; } - -}; - -typedef Span ByteSpan; +#pragma once + +#define DEFER( m, ...) m( __VA_ARGS__ ) +#define XSTR( x ) #x +#define STR( x ) XSTR( x ) + + + +#ifdef _MSC_VER + #define FORCE_INLINE __forceinline + #define WARNING_PUSH Unimplemented + + #ifdef _M_ARM + #define PLATFORM_IS_ARM 1 + #endif +#else + + #if __aarch64__ + #define PLATFORM_IS_ARM 1 + #endif + + #if defined( __clang__ ) + #define FORCE_INLINE __attribute__((always_inline)) + // #define WARNING_PUSH _Pragma( STR() ) + #elif defined( __GNUC__ ) + #define FORCE_INLINE __attribute__((always_inline)) + #endif +#endif + +#if __linux__ || __APPLE__ + #define PLATFORM_IS_UNIX 1 +#endif + +#if __linux__ + #define PLATFORM_IS_LINUX 1 +#elif __APPLE__ + #define PLATFORM_IS_APPLE 1 + + #include + #if TARGET_OS_MAC + #define PLATFORM_IS_MACOS 1 + #else + error Unsupported Apple platform. + #endif + +#elif defined( _WIN32 ) + #define PLATFORM_IS_WINDOWS 1 +#endif + + +#define TimerBegin() std::chrono::steady_clock::now() +#define TimerEnd( startTime ) \ + (std::chrono::duration_cast( std::chrono::steady_clock::now() - (startTime) ).count() / 1000.0) + +#define TimerEndTicks( startTime ) \ + (std::chrono::steady_clock::now() - (startTime)) + +#define TicksToSeconds( duration ) \ + ( std::chrono::duration_cast( (duration) ).count() * 1e-9 ) + + +#define ImplementFlagOps( FlagType ) \ +inline FlagType operator | ( FlagType lhs, FlagType rhs ) \ +{ \ + using FlagT = typename std::underlying_type::type; \ + return static_cast( static_cast( lhs ) | static_cast( rhs ) ); \ +} \ + \ +inline FlagType& operator |= ( FlagType& lhs, FlagType rhs ) \ +{ \ + using FlagT = typename std::underlying_type::type; \ + lhs = static_cast( static_cast( lhs ) | static_cast( rhs ) ); \ + return lhs; \ +} \ + \ +inline FlagType operator & ( FlagType lhs, FlagType rhs ) \ +{ \ + using FlagT = typename std::underlying_type::type; \ + return static_cast( static_cast( lhs ) & static_cast( rhs ) ); \ +} \ + \ +inline FlagType& operator &= ( FlagType& lhs, FlagType rhs ) \ +{ \ + using FlagT = typename std::underlying_type::type; \ + lhs = static_cast( static_cast( lhs ) & static_cast( rhs ) ); \ + return lhs; \ +} \ + \ +inline FlagType operator ~ ( FlagType lhs ) \ +{ \ + using FlagT = typename std::underlying_type::type; \ + lhs = static_cast( ~static_cast( lhs ) ); \ + return lhs; \ +} + +#define ImplementArithmeticOps( EnumType ) \ +constexpr inline EnumType operator+( EnumType lhs, EnumType rhs ) \ +{ \ + using BaseT = typename std::underlying_type::type; \ + return static_cast( static_cast( lhs ) + \ + static_cast( rhs ) ); \ +} \ +constexpr inline EnumType operator+( EnumType lhs, int rhs ) \ +{ \ + using BaseT = typename std::underlying_type::type; \ + return static_cast( static_cast( lhs ) + rhs); \ +} \ + \ +constexpr inline EnumType operator-( EnumType lhs, EnumType rhs ) \ +{ \ + using BaseT = typename std::underlying_type::type; \ + return static_cast( static_cast( lhs ) - \ + static_cast( rhs ) ); \ +} \ +constexpr inline EnumType operator-( EnumType lhs, int rhs ) \ +{ \ + using BaseT = typename std::underlying_type::type; \ + return static_cast( static_cast( lhs ) - rhs );\ +} \ +/* Prefix ++*/ \ +constexpr inline EnumType& operator++( EnumType& self ) \ +{ \ + self = self + static_cast( 1 ); \ + return self; \ +} \ +/* Postfix ++*/ \ +constexpr inline EnumType operator++( EnumType& self, int ) \ +{ \ + return ++self; \ +} \ +/* Prefix --*/ \ +constexpr inline EnumType& operator--( EnumType& self ) \ +{ \ + self = self - static_cast( 1 ); \ + return self; \ +} \ +/* Postfix --*/ \ +constexpr inline EnumType operator--( EnumType& self, int ) \ +{ \ + return --self; \ +} \ + \ + + +template< typename T> +inline bool IsFlagSet( T flags, T flag ) +{ + using UT = typename std::underlying_type::type; + return ( static_cast( flags ) & static_cast( flag ) ) != static_cast( 0 ); +} + +template< typename T> +inline bool AreAllFlagSet( T flagsToCheck, T flagsRequired ) +{ + using UT = typename std::underlying_type::type; + return ( static_cast( flagsToCheck ) & static_cast( flagsRequired ) ) == static_cast( flagsRequired ); +} + +template< typename T> +inline T SetFlag( T& flags, T flag ) +{ + using UT = typename std::underlying_type::type; + flags = static_cast( static_cast( flags ) | static_cast( flag ) ); + + return flags; +} + +template< typename T> +inline T UnSetFlag( T& flags, T flag ) +{ + using UT = typename std::underlying_type::type; + flags = static_cast( static_cast( flags ) & ~( static_cast( flag ) ) ); + + return flags; +} + +template< typename T> +inline T ToggleFlag( T& flags, T flag, bool value ) +{ + if( value ) + SetFlag( flags, flag ); + else + UnSetFlag( flags, flag ); + + return flags; +} + + +template +struct NBytes +{ + uint8_t data[_size]; + + inline uint8_t& operator[]( size_t index ) const { return this->values[index]; } + inline uint8_t& operator[]( uint32_t index ) const { return this->values[index]; } + inline uint8_t& operator[]( int32_t index ) const { return this->values[index]; } + inline uint8_t& operator[]( int64_t index ) const { return this->values[index]; } +}; + + diff --git a/src/Platform.h b/src/Platform.h index c11f94f3..5e731d76 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -1,43 +1,63 @@ -#pragma once - -#ifdef _WIN32 - - #define NOMINMAX 1 - #define WIN32_LEAN_AND_MEAN 1 - #include - - typedef HANDLE ThreadId; - typedef HANDLE SemaphoreId; - -// *nix -#elif __linux__ || __APPLE__ - - #ifndef _GNU_SOURCE - #define _GNU_SOURCE - #endif - - #ifndef _LARGEFILE64_SOURCE - #define _LARGEFILE64_SOURCE - #endif - - #include - #include - #include - #include - #include - #include - - #if __linux__ - #include - #elif __APPLE__ - #include - #include - #endif - - - typedef pthread_t ThreadId; - typedef sem_t SemaphoreId; - -#else - #error Unsupported platform -#endif +#pragma once + +#ifdef _WIN32 + + #define NOMINMAX 1 + #define WIN32_LEAN_AND_MEAN 1 + // #NOTE: Not including globally anymore as we're getting some naming conflicts + //#include + + #include + + // Must match Windows.h definitions. + typedef void* HANDLE; + #define INVALID_WIN32_HANDLE ((HANDLE)(intptr_t)-1) // Same as INVALID_HANDLE_VALUE + typedef HANDLE ThreadId; + typedef HANDLE SemaphoreId; + + #define BBDebugBreak() __debugbreak() + +// *nix +#elif __linux__ || __APPLE__ + + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif + + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + + #include + #include + #include + #include + #include + #include + #include + + #if __linux__ + #include + + typedef pthread_t ThreadId; + typedef sem_t SemaphoreId; + #elif __APPLE__ + #include + + typedef pthread_t ThreadId; + typedef dispatch_semaphore_t SemaphoreId; + #endif + + #define BBDebugBreak() raise( SIGTRAP ) + + +#else + #error Unsupported platform +#endif + + +#if !_DEBUG + #undef BBDebugBreak + #define BBDebugBreak() +#endif + diff --git a/src/PlotContext.cpp b/src/PlotContext.cpp index 05240861..41bb4894 100644 --- a/src/PlotContext.cpp +++ b/src/PlotContext.cpp @@ -1,5 +1,5 @@ -#include "PlotContext.h" -#include "SysHost.h" - -uint16_t L_targets[2][kBC][kExtraBitsPow]; - +#include "PlotContext.h" +#include "SysHost.h" + +uint16_t L_targets[2][kBC][kExtraBitsPow]; + diff --git a/src/PlotContext.h b/src/PlotContext.h index 035372aa..c216a6b3 100644 --- a/src/PlotContext.h +++ b/src/PlotContext.h @@ -1,86 +1,81 @@ -#pragma once -#include "Config.h" -#include "ChiaConsts.h" -#include "threading/ThreadPool.h" -#include "PlotWriter.h" - -struct PlotRequest -{ - const byte* plotId; // Id of the plot we want to create - const char* outPath; // Output plot path - const byte* memo; // Plot memo - uint16 memoSize; - bool IsFinalPlot; -}; - -struct Pair -{ - uint32 left; - uint32 right; -}; -static_assert( sizeof( Pair ) == 8, "Invalid Pair struct." ); - - -/// -/// Context for a in-memory plotting -/// -struct MemPlotContext -{ - // They id of the plot being plotted - const byte* plotId; - - const byte* plotMemo; - uint16 plotMemoSize; - - // How many threads to use for the thread pool? - // #TODO: Remove this, just use the thread pool's count. - uint32 threadCount; - - // Thread pool to use when running jobs - ThreadPool* threadPool; - - /// - /// Buffers - /// - // Permanent table data buffers - uint32* t1XBuffer ; // 16 GiB - Pair* t2LRBuffer; // 32 GiB - Pair* t3LRBuffer; // 32 GiB - Pair* t4LRBuffer; // 32 GiB - Pair* t5LRBuffer; // 32 GiB - Pair* t6LRBuffer; // 32 GiB - Pair* t7LRBuffer; // 32 GiB - uint32* t7YBuffer ; // 16 GiB - - // Temporary read/write y buffers - uint64* yBuffer0; // 32GiB each - uint64* yBuffer1; - - // Temporary read/write metadata buffers - uint64* metaBuffer0; // 64GiB each - uint64* metaBuffer1; - - uint64 maxKBCGroups; - uint64 maxPairs; // Max total pairs our buffer can hold - - // Number of entries per-table - uint64 entryCount[7]; - - // Added by Phase 2: - byte* usedEntries[6]; // Used entries per each table. - // These are only used for tables 2-6 (inclusive). - // These buffers map to regions in yBuffer0. - - DiskPlotWriter* plotWriter; - - // The buffer used to write to disk the Phase 4 data. - // This may be metaBuffer0 or a an L/R buffer from - // table 3 and up, the highest one available to use. - // If null, then no buffer is in use. - byte* p4WriteBuffer; - byte* p4WriteBufferWriter; - - // How many plots we've made so far - uint64 plotCount; -}; - +#pragma once +#include "Config.h" +#include "ChiaConsts.h" +#include "threading/ThreadPool.h" +#include "PlotWriter.h" +#include "plotting/PlotTypes.h" + +struct PlotRequest +{ + const byte* plotId; // Id of the plot we want to create + const char* outPath; // Output plot path + const byte* memo; // Plot memo + uint16 memoSize; + bool IsFinalPlot; +}; + + + +/// +/// Context for a in-memory plotting +/// +struct MemPlotContext +{ + // They id of the plot being plotted + const byte* plotId; + + const byte* plotMemo; + uint16 plotMemoSize; + + // How many threads to use for the thread pool? + // #TODO: Remove this, just use the thread pool's count. + uint32 threadCount; + + // Thread pool to use when running jobs + ThreadPool* threadPool; + + /// + /// Buffers + /// + // Permanent table data buffers + uint32* t1XBuffer ; // 16 GiB + Pair* t2LRBuffer; // 32 GiB + Pair* t3LRBuffer; // 32 GiB + Pair* t4LRBuffer; // 32 GiB + Pair* t5LRBuffer; // 32 GiB + Pair* t6LRBuffer; // 32 GiB + Pair* t7LRBuffer; // 32 GiB + uint32* t7YBuffer ; // 16 GiB + + // Temporary read/write y buffers + uint64* yBuffer0; // 32GiB each + uint64* yBuffer1; + + // Temporary read/write metadata buffers + uint64* metaBuffer0; // 64GiB each + uint64* metaBuffer1; + + uint64 maxKBCGroups; + uint64 maxPairs; // Max total pairs our buffer can hold + + // Number of entries per-table + uint64 entryCount[7]; + + // Added by Phase 2: + byte* usedEntries[6]; // Used entries per each table. + // These are only used for tables 2-6 (inclusive). + // These buffers map to regions in yBuffer0. + + DiskPlotWriter* plotWriter; + + // The buffer used to write to disk the Phase 4 data. + // This may be metaBuffer0 or a an L/R buffer from + // table 3 and up, the highest one available to use. + // If null, then no buffer is in use. + byte* p4WriteBuffer; + byte* p4WriteBufferWriter; + + // How many plots we've made so far + uint64 plotCount; +}; + diff --git a/src/PlotWriter.cpp b/src/PlotWriter.cpp index 65b9b13c..471ccd73 100644 --- a/src/PlotWriter.cpp +++ b/src/PlotWriter.cpp @@ -1,450 +1,450 @@ -#include "PlotWriter.h" -#include "ChiaConsts.h" -#include "SysHost.h" -#include "Config.h" - -//----------------------------------------------------------- -DiskPlotWriter::DiskPlotWriter() - : _writeSignal ( 0 ) - , _plotFinishedSignal( 0 ) -{ - #if BB_BENCHMARK_MODE - return; - #endif - // Start writer thread - _writerThread.Run( WriterMain, this ); -} - -//----------------------------------------------------------- -DiskPlotWriter::~DiskPlotWriter() -{ - #if BB_BENCHMARK_MODE - return; - #endif - - // Signal writer thread to exit, if it hasn't already - _terminateSignal.store( true, std::memory_order_release ); - _writeSignal.Release(); - - // Wait for thread to exit - _plotFinishedSignal.Wait(); - - if( _headerBuffer ) - SysHost::VirtualFree( _headerBuffer ); - - if( _file ) - delete _file; -} - -//----------------------------------------------------------- -bool DiskPlotWriter::BeginPlot( const char* plotFilePath, FileStream& file, const byte plotId[32], const byte* plotMemo, const uint16 plotMemoSize ) -{ - #if BB_BENCHMARK_MODE - _filePath = plotFilePath; - return true; - #endif - - ASSERT( plotMemo ); - ASSERT( plotMemoSize ); - - // Make sure we're not still writing a plot - if( _file || _error || !file.IsOpen() ) - return false; - - const size_t headerSize = - ( sizeof( kPOSMagic ) - 1 ) + - 32 + // plot id - 1 + // k - 2 + // kFormatDescription length - ( sizeof( kFormatDescription ) - 1 ) + - 2 + // Memo length - plotMemoSize + // Memo - 80 // Table pointers - ; - - ASSERT( plotFilePath ); - _filePath = plotFilePath; - - - const size_t paddedHeaderSize = RoundUpToNextBoundary( headerSize, (int)file.BlockSize() ); - - byte* header = _headerBuffer; - - // Do we need to realloc? - if( _headerSize ) - { - ASSERT( _headerBuffer ); - - const size_t currentPaddedHeaderSize = RoundUpToNextBoundary( _headerSize, (int)file.BlockSize() ); - - if( currentPaddedHeaderSize != paddedHeaderSize ) - { - SysHost::VirtualFree( header ); - header = nullptr; - } - } - - // Alloc the header buffer if we need to - if( !header ) - { - header = (byte*)SysHost::VirtualAlloc( paddedHeaderSize ); - - // Zero-out padded portion and table pointers - memset( header+headerSize-80, 0, paddedHeaderSize-headerSize-80 ); - } - - - // Write the header - { - // Magic - byte* headerWriter = header; - memcpy( headerWriter, kPOSMagic, sizeof( kPOSMagic ) - 1 ); - headerWriter += sizeof( kPOSMagic ) - 1; - - // Plot Id - memcpy( headerWriter, plotId, 32 ); - headerWriter += 32; - - // K - *headerWriter++ = (byte)_K; - - // Format description - *((uint16*)headerWriter) = Swap16( (uint16)(sizeof( kFormatDescription ) - 1) ); - headerWriter += 2; - memcpy( headerWriter, kFormatDescription, sizeof( kFormatDescription ) - 1 ); - headerWriter += sizeof( kFormatDescription ) - 1; - - // Memo - *((uint16*)headerWriter) = Swap16( plotMemoSize ); - headerWriter += 2; - memcpy( headerWriter, plotMemo, plotMemoSize ); - headerWriter += plotMemoSize; - - // Tables will be copied at the end. - } - - // Seek to the aligned position after the header - if( !file.Seek( (int64)paddedHeaderSize, SeekOrigin::Begin ) ) - { - _error = file.GetError(); - return false; - } - - // Save header so that we can actually write it to the end of the file - _headerBuffer = header; - _headerSize = headerSize; - - // Store initial table offset - _tablePointers[0] = paddedHeaderSize; - _position = paddedHeaderSize; - - // Give ownership of the file to the writer thread and signal it - _tableIndex = 0; - _file = &file; - _writeSignal.Release(); - - return true; -} - -//----------------------------------------------------------- -bool DiskPlotWriter::WriteTable( const void* buffer, size_t size ) -{ - #if BB_BENCHMARK_MODE - return true; - #endif - - if( !SubmitTable( buffer, size ) ) - return false; - - // Signal the writer thread that there is a new table to write - _writeSignal.Release(); - - return true; -} - -//----------------------------------------------------------- -bool DiskPlotWriter::SubmitTable( const void* buffer, size_t size ) -{ - #if BB_BENCHMARK_MODE - return true; - #endif - - // Make sure the thread has already started. - // We must have no errors - if( !_file || _error ) - return false; - - const uint tableIndex = _tableIndex.load( std::memory_order_relaxed ); - ASSERT( tableIndex < 10 ); - - // Can't overflow tables - if( tableIndex >= 10 ) - return false; - - ASSERT( buffer ); - ASSERT( size ); - - _tablebuffers[tableIndex].buffer = (byte*)buffer; - _tablebuffers[tableIndex].size = size; - - // Store the value - _tableIndex.store( tableIndex + 1, std::memory_order_release ); - - return true; -} - -// //----------------------------------------------------------- -// bool DiskPlotWriter::FlushTables() -// { -// // Make sure the thread has already started. -// if( _headerSize < 1 ) -// return false; - -// // We must have no errors -// if( _error ) -// return false; - -// // Signal the writer thread for each table we have -// const uint tableIndex = _tableIndex.load( std::memory_order_relaxed ); - -// for( uint i = 0; i < tableIndex; i++ ) -// _writeSignal.Release(); - -// return true; -// } - -//----------------------------------------------------------- -bool DiskPlotWriter::WaitUntilFinishedWriting() -{ -#if BB_BENCHMARK_MODE - return true; -#else - - // For re-entry checks - if( !_file && _plotFinishedSignal.GetCount() == 0 ) - return true; - - do { - _plotFinishedSignal.Wait(); - } while( _file ); - - ASSERT( _file == nullptr ); - - return _error == 0; -#endif -} - - -/// -/// Writer thread -/// -//----------------------------------------------------------- -void DiskPlotWriter::WriterMain( void* data ) -{ - SysHost::SetCurrentThreadAffinityCpuId( 0 ); - - ASSERT( data ); - DiskPlotWriter* self = reinterpret_cast( data ); - - self->WriterThread(); -} - -//----------------------------------------------------------- -void DiskPlotWriter::WriterThread() -{ - if( _terminateSignal.load( std::memory_order_relaxed ) ) - return; - - FileStream* file = nullptr; - - uint tableIndex = 0; // Local table index - - // Buffer for writing - size_t blockBufferSize = 0; - byte* blockBuffer = nullptr; - size_t blockSize = 0; - - for( ;; ) - { - // Wait to be signalled by the main thread - _writeSignal.Wait(); - - if( _terminateSignal.load( std::memory_order_relaxed ) ) - break; - - // Started writing a new table, ensure we have a file - if( file == nullptr ) - { - file = _file; - - // We may have been signalled multiple times to write tables - // and we grabbed the tables without waiting for the signal, - // so it might occurr that we don't have a file yet. - if( !file ) - continue; - - // Reset table index - tableIndex = 0; - _lastTableIndexWritten.store( 0, std::memory_order_release ); - - // Allocate a new block buffer, if we need to - blockSize = file->BlockSize(); - if( blockSize > blockBufferSize ) - { - if( blockBuffer ) - SysHost::VirtualFree( blockBuffer ); - - blockBufferSize = blockSize; - blockBuffer = (byte*)SysHost::VirtualAlloc( blockBufferSize ); - - if( !blockBuffer ) - Fatal( "Failed to allocate buffer for writing to disk." ); - } - } - - // See if we have a new table to write (should always be the case when we're signaled) - uint newIndex = _tableIndex.load( std::memory_order_acquire ); - - while( tableIndex < newIndex ) - { - TableBuffer& table = _tablebuffers[tableIndex]; - - const byte* writeBuffer = table.buffer; - - // Write as many blocks as we can, - // then write the remainder by copying it to our own block-aligned buffer - const size_t blockCount = table.size / blockSize; - size_t sizeToWrite = blockCount * blockSize; - - const size_t remainder = table.size - sizeToWrite; - - while( sizeToWrite ) - { - ssize_t sizeWritten = file->Write( writeBuffer, sizeToWrite ); - if( sizeWritten < 1 ) - { - // Error occurred, stop writing. - _error = file->GetError(); - break; - } - ASSERT( (size_t)sizeWritten <= sizeToWrite ); - - sizeToWrite -= (size_t)sizeWritten; - writeBuffer += sizeWritten; - }; - - // Break out if we got a write error - if( _error ) - break; - - // Write remainder, if we have any - if( remainder ) - { - memset( blockBuffer, 0, blockSize ); - memcpy( blockBuffer, writeBuffer, remainder ); - - ssize_t sizeWritten = file->Write( blockBuffer, blockSize ); - if( sizeWritten < 1 ) - { - _error = file->GetError(); - break; - } - - ASSERT( (size_t)sizeWritten == blockSize ); - } - - if( !file->Flush() ) - { - _error = file->GetError(); - break; - } - - // Go to the next table - tableIndex ++; - _lastTableIndexWritten.store( tableIndex, std::memory_order_release ); - - _position += RoundUpToNextBoundary( table.size, (int)blockSize ); - - // Save the table pointer - _tablePointers[tableIndex] = _position; - } - - if( _error ) - break; - - // Have we finished writing the last table? - if( tableIndex >= 10 ) - { - ASSERT( tableIndex == 10 ); - - // We now need to seek to the beginning so that we can write the header - // with the table pointers set - if( file->Seek( 0, SeekOrigin::Begin ) ) - { - const size_t alignedHeaderSize = _tablePointers[0]; - - // Convert to BE - for( uint i = 0; i < 10; i++ ) - _tablePointers[i] = Swap64( _tablePointers[i] ); - - memcpy( _headerBuffer + (_headerSize-80), _tablePointers, 80 ); - - if( file->Write( _headerBuffer, alignedHeaderSize ) != (ssize_t)alignedHeaderSize ) - _error = file->GetError(); - } - else - _error = file->GetError(); - - // Plot data cleanup - if( !file->Flush() ) - _error = file->GetError(); - - file->Close(); - delete file; - file = nullptr; - _file = nullptr; - - _tableIndex = 0; - - // Signal that we've finished writing the plot - _plotFinishedSignal.Release(); - } - } - - - /// - /// Cleanup - /// - if( blockBuffer ) - SysHost::VirtualFree( blockBuffer ); - - // Close the file in case we had an error - if( file ) - { - file->Close(); - delete file; - } - - _file = nullptr; - - // Signal that this thread is finished - _plotFinishedSignal.Release(); -} - -//----------------------------------------------------------- -size_t DiskPlotWriter::AlignToBlockSize( size_t size ) -{ - #if BB_BENCHMARK_MODE - return RoundUpToNextBoundary( size, 4096 ); - #endif - - ASSERT( _file ); - - // Shoud never be called without a file - if( !_file ) - return size; - - return RoundUpToNextBoundary( size, (int)_file->BlockSize() ); -} - - +#include "PlotWriter.h" +#include "ChiaConsts.h" +#include "SysHost.h" +#include "Config.h" + +//----------------------------------------------------------- +DiskPlotWriter::DiskPlotWriter() + : _writeSignal ( 0 ) + , _plotFinishedSignal( 0 ) +{ + #if BB_BENCHMARK_MODE + return; + #endif + // Start writer thread + _writerThread.Run( WriterMain, this ); +} + +//----------------------------------------------------------- +DiskPlotWriter::~DiskPlotWriter() +{ + #if BB_BENCHMARK_MODE + return; + #endif + + // Signal writer thread to exit, if it hasn't already + _terminateSignal.store( true, std::memory_order_release ); + _writeSignal.Release(); + + // Wait for thread to exit + _plotFinishedSignal.Wait(); + + if( _headerBuffer ) + SysHost::VirtualFree( _headerBuffer ); + + if( _file ) + delete _file; +} + +//----------------------------------------------------------- +bool DiskPlotWriter::BeginPlot( const char* plotFilePath, FileStream& file, const byte plotId[32], const byte* plotMemo, const uint16 plotMemoSize ) +{ + #if BB_BENCHMARK_MODE + _filePath = plotFilePath; + return true; + #endif + + ASSERT( plotMemo ); + ASSERT( plotMemoSize ); + + // Make sure we're not still writing a plot + if( _file || _error || !file.IsOpen() ) + return false; + + const size_t headerSize = + ( sizeof( kPOSMagic ) - 1 ) + + 32 + // plot id + 1 + // k + 2 + // kFormatDescription length + ( sizeof( kFormatDescription ) - 1 ) + + 2 + // Memo length + plotMemoSize + // Memo + 80 // Table pointers + ; + + ASSERT( plotFilePath ); + _filePath = plotFilePath; + + + const size_t paddedHeaderSize = RoundUpToNextBoundary( headerSize, (int)file.BlockSize() ); + + byte* header = _headerBuffer; + + // Do we need to realloc? + if( _headerSize ) + { + ASSERT( _headerBuffer ); + + const size_t currentPaddedHeaderSize = RoundUpToNextBoundary( _headerSize, (int)file.BlockSize() ); + + if( currentPaddedHeaderSize != paddedHeaderSize ) + { + SysHost::VirtualFree( header ); + header = nullptr; + } + } + + // Alloc the header buffer if we need to + if( !header ) + { + header = (byte*)SysHost::VirtualAlloc( paddedHeaderSize ); + + // Zero-out padded portion and table pointers + memset( header+headerSize-80, 0, paddedHeaderSize-headerSize-80 ); + } + + + // Write the header + { + // Magic + byte* headerWriter = header; + memcpy( headerWriter, kPOSMagic, sizeof( kPOSMagic ) - 1 ); + headerWriter += sizeof( kPOSMagic ) - 1; + + // Plot Id + memcpy( headerWriter, plotId, 32 ); + headerWriter += 32; + + // K + *headerWriter++ = (byte)_K; + + // Format description + *((uint16*)headerWriter) = Swap16( (uint16)(sizeof( kFormatDescription ) - 1) ); + headerWriter += 2; + memcpy( headerWriter, kFormatDescription, sizeof( kFormatDescription ) - 1 ); + headerWriter += sizeof( kFormatDescription ) - 1; + + // Memo + *((uint16*)headerWriter) = Swap16( plotMemoSize ); + headerWriter += 2; + memcpy( headerWriter, plotMemo, plotMemoSize ); + headerWriter += plotMemoSize; + + // Tables will be copied at the end. + } + + // Seek to the aligned position after the header + if( !file.Seek( (int64)paddedHeaderSize, SeekOrigin::Begin ) ) + { + _error = file.GetError(); + return false; + } + + // Save header so that we can actually write it to the end of the file + _headerBuffer = header; + _headerSize = headerSize; + + // Store initial table offset + _tablePointers[0] = paddedHeaderSize; + _position = paddedHeaderSize; + + // Give ownership of the file to the writer thread and signal it + _tableIndex = 0; + _file = &file; + _writeSignal.Release(); + + return true; +} + +//----------------------------------------------------------- +bool DiskPlotWriter::WriteTable( const void* buffer, size_t size ) +{ + #if BB_BENCHMARK_MODE + return true; + #endif + + if( !SubmitTable( buffer, size ) ) + return false; + + // Signal the writer thread that there is a new table to write + _writeSignal.Release(); + + return true; +} + +//----------------------------------------------------------- +bool DiskPlotWriter::SubmitTable( const void* buffer, size_t size ) +{ + #if BB_BENCHMARK_MODE + return true; + #endif + + // Make sure the thread has already started. + // We must have no errors + if( !_file || _error ) + return false; + + const uint tableIndex = _tableIndex.load( std::memory_order_relaxed ); + ASSERT( tableIndex < 10 ); + + // Can't overflow tables + if( tableIndex >= 10 ) + return false; + + ASSERT( buffer ); + ASSERT( size ); + + _tablebuffers[tableIndex].buffer = (byte*)buffer; + _tablebuffers[tableIndex].size = size; + + // Store the value + _tableIndex.store( tableIndex + 1, std::memory_order_release ); + + return true; +} + +// //----------------------------------------------------------- +// bool DiskPlotWriter::FlushTables() +// { +// // Make sure the thread has already started. +// if( _headerSize < 1 ) +// return false; + +// // We must have no errors +// if( _error ) +// return false; + +// // Signal the writer thread for each table we have +// const uint tableIndex = _tableIndex.load( std::memory_order_relaxed ); + +// for( uint i = 0; i < tableIndex; i++ ) +// _writeSignal.Release(); + +// return true; +// } + +//----------------------------------------------------------- +bool DiskPlotWriter::WaitUntilFinishedWriting() +{ +#if BB_BENCHMARK_MODE + return true; +#else + + // For re-entry checks + if( !_file && _plotFinishedSignal.GetCount() == 0 ) + return true; + + do { + _plotFinishedSignal.Wait(); + } while( _file ); + + ASSERT( _file == nullptr ); + + return _error == 0; +#endif +} + + +/// +/// Writer thread +/// +//----------------------------------------------------------- +void DiskPlotWriter::WriterMain( void* data ) +{ + SysHost::SetCurrentThreadAffinityCpuId( 0 ); + + ASSERT( data ); + DiskPlotWriter* self = reinterpret_cast( data ); + + self->WriterThread(); +} + +//----------------------------------------------------------- +void DiskPlotWriter::WriterThread() +{ + if( _terminateSignal.load( std::memory_order_relaxed ) ) + return; + + FileStream* file = nullptr; + + uint tableIndex = 0; // Local table index + + // Buffer for writing + size_t blockBufferSize = 0; + byte* blockBuffer = nullptr; + size_t blockSize = 0; + + for( ;; ) + { + // Wait to be signalled by the main thread + _writeSignal.Wait(); + + if( _terminateSignal.load( std::memory_order_relaxed ) ) + break; + + // Started writing a new table, ensure we have a file + if( file == nullptr ) + { + file = _file; + + // We may have been signalled multiple times to write tables + // and we grabbed the tables without waiting for the signal, + // so it might occurr that we don't have a file yet. + if( !file ) + continue; + + // Reset table index + tableIndex = 0; + _lastTableIndexWritten.store( 0, std::memory_order_release ); + + // Allocate a new block buffer, if we need to + blockSize = file->BlockSize(); + if( blockSize > blockBufferSize ) + { + if( blockBuffer ) + SysHost::VirtualFree( blockBuffer ); + + blockBufferSize = blockSize; + blockBuffer = (byte*)SysHost::VirtualAlloc( blockBufferSize ); + + if( !blockBuffer ) + Fatal( "Failed to allocate buffer for writing to disk." ); + } + } + + // See if we have a new table to write (should always be the case when we're signaled) + uint newIndex = _tableIndex.load( std::memory_order_acquire ); + + while( tableIndex < newIndex ) + { + TableBuffer& table = _tablebuffers[tableIndex]; + + const byte* writeBuffer = table.buffer; + + // Write as many blocks as we can, + // then write the remainder by copying it to our own block-aligned buffer + const size_t blockCount = table.size / blockSize; + size_t sizeToWrite = blockCount * blockSize; + + const size_t remainder = table.size - sizeToWrite; + + while( sizeToWrite ) + { + ssize_t sizeWritten = file->Write( writeBuffer, sizeToWrite ); + if( sizeWritten < 1 ) + { + // Error occurred, stop writing. + _error = file->GetError(); + break; + } + ASSERT( (size_t)sizeWritten <= sizeToWrite ); + + sizeToWrite -= (size_t)sizeWritten; + writeBuffer += sizeWritten; + }; + + // Break out if we got a write error + if( _error ) + break; + + // Write remainder, if we have any + if( remainder ) + { + memset( blockBuffer, 0, blockSize ); + memcpy( blockBuffer, writeBuffer, remainder ); + + ssize_t sizeWritten = file->Write( blockBuffer, blockSize ); + if( sizeWritten < 1 ) + { + _error = file->GetError(); + break; + } + + ASSERT( (size_t)sizeWritten == blockSize ); + } + + if( !file->Flush() ) + { + _error = file->GetError(); + break; + } + + // Go to the next table + tableIndex ++; + _lastTableIndexWritten.store( tableIndex, std::memory_order_release ); + + _position += RoundUpToNextBoundary( table.size, (int)blockSize ); + + // Save the table pointer + _tablePointers[tableIndex] = _position; + } + + if( _error ) + break; + + // Have we finished writing the last table? + if( tableIndex >= 10 ) + { + ASSERT( tableIndex == 10 ); + + // We now need to seek to the beginning so that we can write the header + // with the table pointers set + if( file->Seek( 0, SeekOrigin::Begin ) ) + { + const size_t alignedHeaderSize = _tablePointers[0]; + + // Convert to BE + for( uint i = 0; i < 10; i++ ) + _tablePointers[i] = Swap64( _tablePointers[i] ); + + memcpy( _headerBuffer + (_headerSize-80), _tablePointers, 80 ); + + if( file->Write( _headerBuffer, alignedHeaderSize ) != (ssize_t)alignedHeaderSize ) + _error = file->GetError(); + } + else + _error = file->GetError(); + + // Plot data cleanup + if( !file->Flush() ) + _error = file->GetError(); + + file->Close(); + delete file; + file = nullptr; + _file = nullptr; + + _tableIndex = 0; + + // Signal that we've finished writing the plot + _plotFinishedSignal.Release(); + } + } + + + /// + /// Cleanup + /// + if( blockBuffer ) + SysHost::VirtualFree( blockBuffer ); + + // Close the file in case we had an error + if( file ) + { + file->Close(); + delete file; + } + + _file = nullptr; + + // Signal that this thread is finished + _plotFinishedSignal.Release(); +} + +//----------------------------------------------------------- +size_t DiskPlotWriter::AlignToBlockSize( size_t size ) +{ + #if BB_BENCHMARK_MODE + return RoundUpToNextBoundary( size, 4096 ); + #endif + + ASSERT( _file ); + + // Shoud never be called without a file + if( !_file ) + return size; + + return RoundUpToNextBoundary( size, (int)_file->BlockSize() ); +} + + diff --git a/src/PlotWriter.h b/src/PlotWriter.h index c7504084..71e9e954 100644 --- a/src/PlotWriter.h +++ b/src/PlotWriter.h @@ -1,107 +1,107 @@ -#pragma once -#include "io/FileStream.h" -#include "threading/Thread.h" -#include "threading/Semaphore.h" - -/** - * Handles writing the final plot to disk - * - * Final file format is as follows: - * [Header] - * - "Proof of Space Plot" (utf-8) : 19 bytes - * - unique plot id : 32 bytes - * - k : 1 byte - * - format description length : 2 bytes - * - format description : * bytes - * - memo length : 2 bytes - * - memo : * bytes - * - table pointers : 80 bytes (8 * 10 ) - * [(Optional_Padding)] - * [Table1_Parks] - * [Table2_Parks] - * [Table3_Parks] - * [Table4_Parks] - * [Table5_Parks] - * [Table6_Parks] - * [Table7_Parks] - * [C1_Table] - * [C2_Table] - * [C3_Table_Parks] - */ -class DiskPlotWriter -{ -public: - DiskPlotWriter(); - ~DiskPlotWriter(); - - // Begins writing a new plot. Any previous plot must have finished before calling this - bool BeginPlot( const char* plotFilePath, FileStream& file, const byte plotId[32], - const byte* plotMemo, const uint16 plotMemoSize ); - - // Submits and signals the writing thread to write a table - bool WriteTable( const void* buffer, size_t size ); - - // Submits the table for writing, but does not actually write it to disk yet - bool SubmitTable( const void* buffer, size_t size ); - - // Flush pending tables to write - // bool FlushTables(); - - // Returns true if there's no errors. - // If there are any errors, call GetError() to obtain the file write error. - bool WaitUntilFinishedWriting(); - - // Returns true if the plotter has finished writing the last queued plot. - // (We nullify our reference when the file has been closed and finished.) - inline bool HasFinishedWriting() { return _file == nullptr; } - - // If gotten after flush, they will be in big-endian format - inline const uint64* GetTablePointers() { return _tablePointers; } - - template - inline T* AlignPointerToBlockSize( void* pointer ) - { - return (T*)(uintptr_t)AlignToBlockSize( (uintptr_t)pointer ); - } - - inline int GetError() { return _error; } - - inline const std::string& FilePath() { return _filePath; } - - // Number of tables written - inline uint TablesWritten() { return _lastTableIndexWritten.load( std::memory_order_acquire ); } - -private: - static void WriterMain( void* data ); - void WriterThread(); - size_t AlignToBlockSize( size_t size ); - - struct TableBuffer - { - const byte* buffer; - size_t size; - }; - -private: - FileStream* _file = nullptr; - std::string _filePath; - size_t _headerSize = 0; - byte* _headerBuffer = nullptr; - size_t _position = 0; // Current write position - uint64 _tablePointers[10] = { 0 }; // Pointers to the table begin position - TableBuffer _tablebuffers [10]; // Table buffers passed to us for writing. - - std::atomic _tableIndex = 0; // Next table index to write - std::atomic _lastTableIndexWritten = 10; // Index of the latest table that was fully written to disk. (Owned by writer thread.) - // That is, index-1 is the index of the last table written. - // We start it at 10 (all tables written), to denote that we have - // no tables pending to write. - - int _error = 0; // Set if there was an error writing the plot file - - Thread _writerThread; - Semaphore _writeSignal; // Main thread signals writer thread to write a new table - Semaphore _plotFinishedSignal; // Writer thread signals that it's finished writing a plot - std::atomic _terminateSignal = false; // Main thread signals us to exit -}; - +#pragma once +#include "io/FileStream.h" +#include "threading/Thread.h" +#include "threading/Semaphore.h" + +/** + * Handles writing the final plot to disk + * + * Final file format is as follows: + * [Header] + * - "Proof of Space Plot" (utf-8) : 19 bytes + * - unique plot id : 32 bytes + * - k : 1 byte + * - format description length : 2 bytes + * - format description : * bytes + * - memo length : 2 bytes + * - memo : * bytes + * - table pointers : 80 bytes (8 * 10 ) + * [(Optional_Padding)] + * [Table1_Parks] + * [Table2_Parks] + * [Table3_Parks] + * [Table4_Parks] + * [Table5_Parks] + * [Table6_Parks] + * [Table7_Parks] + * [C1_Table] + * [C2_Table] + * [C3_Table_Parks] + */ +class DiskPlotWriter +{ +public: + DiskPlotWriter(); + ~DiskPlotWriter(); + + // Begins writing a new plot. Any previous plot must have finished before calling this + bool BeginPlot( const char* plotFilePath, FileStream& file, const byte plotId[32], + const byte* plotMemo, const uint16 plotMemoSize ); + + // Submits and signals the writing thread to write a table + bool WriteTable( const void* buffer, size_t size ); + + // Submits the table for writing, but does not actually write it to disk yet + bool SubmitTable( const void* buffer, size_t size ); + + // Flush pending tables to write + // bool FlushTables(); + + // Returns true if there's no errors. + // If there are any errors, call GetError() to obtain the file write error. + bool WaitUntilFinishedWriting(); + + // Returns true if the plotter has finished writing the last queued plot. + // (We nullify our reference when the file has been closed and finished.) + inline bool HasFinishedWriting() { return _file == nullptr; } + + // If gotten after flush, they will be in big-endian format + inline const uint64* GetTablePointers() { return _tablePointers; } + + template + inline T* AlignPointerToBlockSize( void* pointer ) + { + return (T*)(uintptr_t)AlignToBlockSize( (uintptr_t)pointer ); + } + + inline int GetError() { return _error; } + + inline const std::string& FilePath() { return _filePath; } + + // Number of tables written + inline uint TablesWritten() { return _lastTableIndexWritten.load( std::memory_order_acquire ); } + +private: + static void WriterMain( void* data ); + void WriterThread(); + size_t AlignToBlockSize( size_t size ); + + struct TableBuffer + { + const byte* buffer; + size_t size; + }; + +private: + FileStream* _file = nullptr; + std::string _filePath; + size_t _headerSize = 0; + byte* _headerBuffer = nullptr; + size_t _position = 0; // Current write position + uint64 _tablePointers[10] = { 0 }; // Pointers to the table begin position + TableBuffer _tablebuffers [10]; // Table buffers passed to us for writing. + + std::atomic _tableIndex = 0; // Next table index to write + std::atomic _lastTableIndexWritten = 10; // Index of the latest table that was fully written to disk. (Owned by writer thread.) + // That is, index-1 is the index of the last table written. + // We start it at 10 (all tables written), to denote that we have + // no tables pending to write. + + int _error = 0; // Set if there was an error writing the plot file + + Thread _writerThread; + Semaphore _writeSignal; // Main thread signals writer thread to write a new table + Semaphore _plotFinishedSignal; // Writer thread signals that it's finished writing a plot + std::atomic _terminateSignal = false; // Main thread signals us to exit +}; + diff --git a/src/SysHost.h b/src/SysHost.h index 0176af31..b9e23121 100644 --- a/src/SysHost.h +++ b/src/SysHost.h @@ -1,85 +1,87 @@ -#pragma once - -enum class VProtect : uint -{ - None = 0, // No protection / Clear protection - - Read = 1 << 0, // Allow reads. (Make pages read-only.) - Write = 1 << 1, // Allow writes. (Make pages write-only.) - NoAccess = 1 << 2, // No memory access allowed at all - - ReadWrite = Read | Write // Make pages read/writable -}; -ImplementFlagOps( VProtect ); - -struct NumaInfo -{ - uint nodeCount; // How many NUMA nodes in the system - uint cpuCount; // Total cpu count used by nodes - Span* cpuIds; // CPU ids of each node - - #ifdef _WIN32 -// Span procGroup; // Processor group each cpu belongs to. - #endif -}; - -class SysHost -{ -public: - - // Get the system page size in bytes - static size_t GetPageSize(); - - // Get total physical system ram in bytes - static size_t GetTotalSystemMemory(); - - /// Gets the currently available (unused) system ram in bytes - static size_t GetAvailableSystemMemory(); - - /// Get the total number of logical CPUs in the system - static uint GetLogicalCPUCount(); - - /// Create an allocation in the virtual memory space - /// If initialize == true, then all pages are touched so that - /// the pages are actually assigned. - static void* VirtualAlloc( size_t size, bool initialize = false ); - - static void VirtualFree( void* ptr ); - - static bool VirtualProtect( void* ptr, size_t size, VProtect flags = VProtect::NoAccess ); - - /// Set the processor affinity mask for the current process - // static uint64 SetCurrentProcessAffinityMask( uint64 mask ); - - /// Set the processor affinity mask for the current thread -// static uint64 SetCurrentThreadAffinityMask( uint64 mask ); - - /// Set the processor affinity mask to a specific cpu id for the current thread - static bool SetCurrentThreadAffinityCpuId( uint32 cpuId ); - - /// Install a crash handler to dump stack traces upon crash - static void InstallCrashHandler(); - - /// Generate random data - /// (We basically do what libsodium does here) - static void Random( byte* buffer, size_t size ); - - /// Get system's NUMA info, if it has any - static const NumaInfo* GetNUMAInfo(); - - /// Assign memory pages to a NUMA node - static void NumaAssignPages( void* ptr, size_t size, uint node ); - - /// Set interleave NUMA mode for allocations in the calling thread - static bool NumaSetThreadInterleavedMode(); - - /// Set interleave NUMA mode for the specified memory regions. - /// NOTE: Pages must not yet be faulted. - static bool NumaSetMemoryInterleavedMode( void* ptr, size_t size ); - - /// Get the node a memory page belongs to. - /// Returns a negative value upon failure. - /// NOTE: Pages must first be faulted on linuz. - static int NumaGetNodeFromPage( void* ptr ); - +#pragma once + +enum class VProtect : uint +{ + NoAccess = 0, // No memory access allowed at all + + Read = 1 << 0, // Allow reads. (Make pages read-only.) + Write = 1 << 1, // Allow writes. (Make pages write-only.) // NOTE: This is not guaranteed depending on implementation. + + ReadWrite = Read | Write // Make pages read/writable +}; +ImplementFlagOps( VProtect ); + +struct NumaInfo +{ + uint nodeCount; // How many NUMA nodes in the system + uint cpuCount; // Total cpu count used by nodes + Span* cpuIds; // CPU ids of each node + + #ifdef _WIN32 +// Span procGroup; // Processor group each cpu belongs to. + #endif +}; + +class SysHost +{ +public: + + // Get the system page size in bytes + static size_t GetPageSize(); + + // Get total physical system ram in bytes + static size_t GetTotalSystemMemory(); + + /// Gets the currently available (unused) system ram in bytes + static size_t GetAvailableSystemMemory(); + + /// Get the total number of logical CPUs in the system + static uint GetLogicalCPUCount(); + + /// Create an allocation in the virtual memory space + /// If initialize == true, then all pages are touched so that + /// the pages are actually assigned. + static void* VirtualAlloc( size_t size, bool initialize = false ); + + static void VirtualFree( void* ptr ); + + static bool VirtualProtect( void* ptr, size_t size, VProtect flags = VProtect::NoAccess ); + + /// Set the processor affinity mask for the current process + // static uint64 SetCurrentProcessAffinityMask( uint64 mask ); + + /// Set the processor affinity mask for the current thread +// static uint64 SetCurrentThreadAffinityMask( uint64 mask ); + + /// Set the processor affinity mask to a specific cpu id for the current thread + static bool SetCurrentThreadAffinityCpuId( uint32 cpuId ); + + /// Install a crash handler to dump stack traces upon crash + static void InstallCrashHandler(); + + /// Dump stack trace to stderr + static void DumpStackTrace(); + + /// Generate random data + /// (We basically do what libsodium does here) + static void Random( byte* buffer, size_t size ); + + /// Get system's NUMA info, if it has any + static const NumaInfo* GetNUMAInfo(); + + /// Assign memory pages to a NUMA node + static void NumaAssignPages( void* ptr, size_t size, uint node ); + + /// Set interleave NUMA mode for allocations in the calling thread + static bool NumaSetThreadInterleavedMode(); + + /// Set interleave NUMA mode for the specified memory regions. + /// NOTE: Pages must not yet be faulted. + static bool NumaSetMemoryInterleavedMode( void* ptr, size_t size ); + + /// Get the node a memory page belongs to. + /// Returns a negative value upon failure. + /// NOTE: Pages must first be faulted on linux. + static int NumaGetNodeFromPage( void* ptr ); + }; \ No newline at end of file diff --git a/src/Types.h b/src/Types.h index 4b7eb921..d4056f35 100644 --- a/src/Types.h +++ b/src/Types.h @@ -1,54 +1,67 @@ -#pragma once - -typedef uint8_t byte; -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef unsigned long long int uint64; - -#if !uint - typedef uint32 uint; -#endif - -#if !ssize_t - typedef int64_t ssize_t; -#endif - -typedef uint8 u8; -typedef uint16 u16; -typedef uint32 u32; -typedef uint64 u64; - -typedef int8_t sbyte; -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef long long int int64; - -typedef int8 i8; -typedef int16 i16; -typedef int32 i32; -typedef int64 i64; - -typedef float float32; -typedef double float64; -typedef float32 f32; -typedef float64 f64; - -typedef uint32 size_t32; -typedef uint64 size_t64; - -static_assert( sizeof( byte ) == 1, "byte must be 1" ); -static_assert( sizeof( uint8 ) == 1, "uint8 must be 1" ); -static_assert( sizeof( uint16 ) == 2, "uint16 must be 2" ); -static_assert( sizeof( uint32 ) == 4, "uint32 must be 4" ); -static_assert( sizeof( uint64 ) == 8, "uint64 must be 8" ); - -static_assert( sizeof( sbyte ) == 1, "sbyte must be 1" ); -static_assert( sizeof( int8 ) == 1, "int8 must be 1" ); -static_assert( sizeof( int16 ) == 2, "int16 must be 2" ); -static_assert( sizeof( int32 ) == 4, "int32 must be 4" ); -static_assert( sizeof( int64 ) == 8, "int64 must be 8" ); - -static_assert( sizeof( float32 ) == 4, "float32 must be 4" ); -static_assert( sizeof( float64 ) == 8, "float64 must be 8" ); +#pragma once + +typedef uint8_t byte; +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; + +// Prevent compiler whining about %llu when uint64: +typedef long long unsigned int llu; + +#if !uint + typedef uint32 uint; +#endif + +#if _WIN32 + typedef int64_t ssize_t; +#endif + +typedef uint8 u8; +typedef uint16 u16; +typedef uint32 u32; +typedef uint64 u64; + +typedef int8_t sbyte; +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef long long int int64; + +typedef int8 i8; +typedef int16 i16; +typedef int32 i32; +typedef int64 i64; + +typedef float float32; +typedef double float64; +typedef float32 f32; +typedef float64 f64; + +typedef uint32 size_t32; +typedef uint64 size_t64; + +static_assert( sizeof( byte ) == 1, "byte must be 1" ); +static_assert( sizeof( uint8 ) == 1, "uint8 must be 1" ); +static_assert( sizeof( uint16 ) == 2, "uint16 must be 2" ); +static_assert( sizeof( uint32 ) == 4, "uint32 must be 4" ); +static_assert( sizeof( uint64 ) == 8, "uint64 must be 8" ); + +static_assert( sizeof( sbyte ) == 1, "sbyte must be 1" ); +static_assert( sizeof( int8 ) == 1, "int8 must be 1" ); +static_assert( sizeof( int16 ) == 2, "int16 must be 2" ); +static_assert( sizeof( int32 ) == 4, "int32 must be 4" ); +static_assert( sizeof( int64 ) == 8, "int64 must be 8" ); + +static_assert( sizeof( float32 ) == 4, "float32 must be 4" ); +static_assert( sizeof( float64 ) == 8, "float64 must be 8" ); + +#ifdef __SIZEOF_INT128__ + typedef __uint128_t uint128_t; +#else + #include "uint128_t/uint128_t.h" +#endif + +typedef uint128_t uint128; + +typedef std::chrono::steady_clock::duration Duration; diff --git a/src/Util.cpp b/src/Util.cpp deleted file mode 100644 index 00988b7d..00000000 --- a/src/Util.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "Util.h" -#include "util/Log.h" - -//----------------------------------------------------------- -void VFatal( const char* message, va_list args ) -{ - Log::Error( "Fatal Error:" ); - Log::WriteError( " " ); - Log::Error( message, args ); - Log::FlushError(); - - ASSERT( 0 ); - exit( 1 ); -} - -//----------------------------------------------------------- -void Fatal( const char* message, ... ) -{ - va_list args; - va_start( args, message ); - VFatal( message, args ); - va_end( args ); -} - -//----------------------------------------------------------- -void FatalIf( bool condition, const char* message, ... ) -{ - if( condition ) - { - va_list args; - va_start( args, message ); - VFatal( message, args ); - va_end( args ); - } -} \ No newline at end of file diff --git a/src/Util.h b/src/Util.h deleted file mode 100644 index fd819d0c..00000000 --- a/src/Util.h +++ /dev/null @@ -1,309 +0,0 @@ -#pragma once - -#include -#include - -#ifdef _MSC_VER - #define Swap16( x ) _byteswap_ushort( x ) - #define Swap32( x ) _byteswap_ulong( x ) - #define Swap64( x ) _byteswap_uint64( x ) -#elif defined( __GNUC__ ) - #define Swap16( x ) __builtin_bswap16( x ) - #define Swap32( x ) __builtin_bswap32( x ) - #define Swap64( x ) __builtin_bswap64( x ) -#else - #error Byte swapping intrinsics not configured for this compiler. -#endif - - -/// Byte size conversions -#define KB *(1<<10) -#define MB *(1<<20) -#define GB *(1<<30) - -#define BtoKB /(1<<10) -#define BtoMB /(1<<20) -#define BtoGB /(1<<30) - - -/// -/// Assorted utility functions -/// - -// Post a message and exit with error -//----------------------------------------------------------- -void Fatal( const char* message, ... ); - -void FatalIf( bool condition, const char* message, ... ); - -//----------------------------------------------------------- -template -inline void ZeroMem( T* ptr ) -{ - memset( ptr, 0, sizeof( T ) ); -} - -//----------------------------------------------------------- -template -inline void ZeroMem( T* ptr, size_t count ) -{ - ASSERT( count > 0 ); - memset( ptr, 0, sizeof( T ) * count ); -} - -// Like ceil div, but tells you how man times to multiply -// a in order to fit into b-sized chunks -//----------------------------------------------------------- -template -constexpr inline T CDiv( T a, int b ) -{ - return ( a + (T)b - 1 ) / (T)b; -} - -/// Divides by and rounds -/// it up to the next factor of -//----------------------------------------------------------- -template -inline T CeildDiv( T dividend, T divisor ) -{ - return dividend + ( divisor - ( dividend % divisor ) ) % divisor; -} - -// Round up a number to the next upper boundary. -// For example, if we want to round up some bytes to the -// next 8-byte boundary. -// This is the same as CeilDiv, but with a more intuitive name. -//----------------------------------------------------------- -template -inline T RoundUpToNextBoundary( T value, int boundary ) -{ - return CeildDiv( value, (T)boundary ); -} - -const char HEX_TO_BIN[256] = { - 0, // 0 00 NUL - 0, // 1 01 SOH - 0, // 2 02 STX - 0, // 3 03 ETX - 0, // 4 04 EOT - 0, // 5 05 ENQ - 0, // 6 06 ACK - 0, // 7 07 BEL - 0, // 8 08 BS - 0, // 9 09 HT - 0, // 10 0A LF - 0, // 11 0B VT - 0, // 12 0C FF - 0, // 13 0D CR - 0, // 14 0E SO - 0, // 15 0F SI - 0, // 16 10 DLE - 0, // 17 11 DC1 - 0, // 18 12 DC2 - 0, // 19 13 DC3 - 0, // 20 14 DC4 - 0, // 21 15 NAK - 0, // 22 16 SYN - 0, // 23 17 ETB - 0, // 24 18 CAN - 0, // 25 19 EM - 0, // 26 1A SUB - 0, // 27 1B ESC - 0, // 28 1C FS - 0, // 29 1D GS - 0, // 30 1E RS - 0, // 31 1F US - 0, // 32 20 space - 0, // 33 21 ! - 0, // 34 22 " - 0, // 35 23 # - 0, // 36 24 $ - 0, // 37 25 % - 0, // 38 26 & - 0, // 39 27 ' - 0, // 40 28 ( - 0, // 41 29 ) - 0, // 42 2A * - 0, // 43 2B + - 0, // 44 2C , - 0, // 45 2D - - 0, // 46 2E . - 0, // 47 2F / - 0, // 48 30 0 - 1, // 49 31 1 - 2, // 50 32 2 - 3, // 51 33 3 - 4, // 52 34 4 - 5, // 53 35 5 - 6, // 54 36 6 - 7, // 55 37 7 - 8, // 56 38 8 - 9, // 57 39 9 - 0, // 58 3A : - 0, // 59 3B ; - 0, // 60 3C < - 0, // 61 3D = - 0, // 62 3E > - 0, // 63 3F ? - 0, // 64 40 @ - 10, // 65 41 A - 11, // 66 42 B - 12, // 67 43 C - 13, // 68 44 D - 14, // 69 45 E - 15, // 70 46 F - 0, // 71 47 G - 0, // 72 48 H - 0, // 73 49 I - 0, // 74 4A J - 0, // 75 4B K - 0, // 76 4C L - 0, // 77 4D M - 0, // 78 4E N - 0, // 79 4F O - 0, // 80 50 P - 0, // 81 51 Q - 0, // 82 52 R - 0, // 83 53 S - 0, // 84 54 T - 0, // 85 55 U - 0, // 86 56 V - 0, // 87 57 W - 0, // 88 58 X - 0, // 89 59 Y - 0, // 90 5A Z - 0, // 91 5B [ - 0, // 92 5C \ // - 0, // 93 5D ] - 0, // 94 5E ^ - 0, // 95 5F _ - 0, // 96 60 ` - 10, // 97 61 a - 11, // 98 62 b - 12, // 99 63 c - 13, // 100 64 d - 14, // 101 65 e - 15, // 102 66 f - 0, // 103 67 g - 0, // 104 68 h - 0, // 105 69 i - 0, // 106 6A j - 0, // 107 6B k - 0, // 108 6C l - 0, // 109 6D m - 0, // 110 6E n - 0, // 111 6F o - 0, // 112 70 p - 0, // 113 71 q - 0, // 114 72 r - 0, // 115 73 s - 0, // 116 74 t - 0, // 117 75 u - 0, // 118 76 v - 0, // 119 77 w - 0, // 120 78 x - 0, // 121 79 y - 0, // 122 7A z - 0, // 123 7B { - 0, // 124 7C | - 0, // 125 7D } - 0, // 126 7E ~ - 0, // 127 7F DEL - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -//----------------------------------------------------------- -inline void HexStrToBytes( const char* str, const size_t strSize, - byte* dst, size_t dstSize ) -{ - ASSERT( str && strSize ); - ASSERT( dst && dstSize ); - - const size_t maxSize = (strSize / 2) * 2; - const char* end = str + maxSize; - - ASSERT( dstSize >= maxSize / 2 ); - - int i = 0; - while( str < end ) - { - byte msb = (byte)HEX_TO_BIN[(int)str[0]]; - byte lsb = (byte)HEX_TO_BIN[(int)str[1]]; - - byte v = lsb + msb * 16u; - dst[i++] = v; - str += 2; - } -} - -//----------------------------------------------------------- -// Encode bytes into hex format -// Return: -// 0 if OK -// -1 if Needed more space in the dst buffer to write -// -2 if the required dstSize would overflow -//----------------------------------------------------------- -inline int BytesToHexStr( const byte* src, size_t srcSize, - char* dst, size_t dstSize, - size_t& numEncoded, - bool uppercase = false ) -{ - const char HEXUC[] = "0123456789ABCDEF"; - const char HEXLC[] = "0123456789abcdef"; - - const char* HEX = uppercase ? HEXUC : HEXLC; - - const size_t MAX_SRC_SIZE = std::numeric_limits::max() / 2; - - numEncoded = 0; - int ret = 0; - - if( dstSize == 0 ) - { - return -1; - } - - size_t maxEncode = srcSize; - size_t dstRequired; - - // Check for overflow - if( maxEncode > MAX_SRC_SIZE ) - { - maxEncode = MAX_SRC_SIZE; - dstRequired = std::numeric_limits::max(); - numEncoded = MAX_SRC_SIZE; - ret = -2; - } - else - { - dstRequired = maxEncode * 2; - numEncoded = maxEncode; - } - - // Cap the encode count to the dst buffer size - if( dstRequired > dstSize ) - { - ret = -1; - numEncoded = dstSize/2; - } - - const byte* s = src; - const byte* end = src + numEncoded; - char* d = dst; - - while( s < end ) - { - d[0] = (char)HEX[(*s >> 4) & 0x0F]; - d[1] = (char)HEX[*s & 15]; - - s++; - d += 2; - } - - return ret; -} - diff --git a/src/Version.h b/src/Version.h index 9098d2ff..1f0e772a 100644 --- a/src/Version.h +++ b/src/Version.h @@ -1,10 +1,71 @@ #pragma once -#define BLADEBIT_VERSION_MAJ 1 -#define BLADEBIT_VERSION_MIN 2 -#define BLADEBIT_VERSION_REV 0 +#ifndef BLADEBIT_VERSION_MAJ + #define BLADEBIT_VERSION_MAJ 0 +#endif + +#ifndef BLADEBIT_VERSION_MIN + #define BLADEBIT_VERSION_MIN 0 +#endif + +#ifndef BLADEBIT_VERSION_REV + #define BLADEBIT_VERSION_REV 0 +#endif + +#ifndef BLADEBIT_VERSION_SUFFIX + #define BLADEBIT_VERSION_SUFFIX "-dev" +#endif + +#ifndef BLADEBIT_GIT_COMMIT + #define BLADEBIT_GIT_COMMIT "unknown" +#endif + +// Record compiler version +#if defined( __clang__ ) + struct BBCompilerVer + { + static constexpr const char* compiler = "clang"; + static constexpr uint32_t major = __clang_major__; + static constexpr uint32_t minor = __clang_minor__; + static constexpr uint32_t revision = __clang_patchlevel__; + }; +#elif defined( __GNUC__ ) + struct BBCompilerVer + { + static constexpr const char* compiler = "gcc"; + static constexpr uint32_t major = __GNUC__; + static constexpr uint32_t minor = __GNUC_MINOR__; + static constexpr uint32_t revision = __GNUC_PATCHLEVEL__; + }; +#elif defined( _MSC_VER ) + struct BBCompilerVer + { + static constexpr const char* compiler = "msvc"; + static constexpr uint32_t major = _MSC_VER / 100u; + static constexpr uint32_t minor = _MSC_VER - major * 100u; + static constexpr uint32_t revision = _MSC_FULL_VER - _MSC_VER * 100000u; + }; + +#else + #warning "Unknown compiler" + struct BBCompilerVer + { + static constexpr const char* compiler = "unknown"; + static constexpr uint32_t major = 0; + static constexpr uint32_t minor = 0; + static constexpr uint32_t revision = 0; + }; +#endif + +// #NOTE: Not thread safe +inline const char* BBGetCompilerVersion() +{ + static char c[256] = {}; + sprintf( c, "%s %u.%u.%u", BBCompilerVer::compiler, BBCompilerVer::major, + BBCompilerVer::minor, BBCompilerVer::revision ); + return c; +} -#define BLADEBIT_GIT_COMMIT "dev" #define BLADEBIT_VERSION \ ((uint64)BLADEBIT_VERSION_MAJ) << 32 \ @@ -12,5 +73,6 @@ ((uint64)BLADEBIT_VERSION_REV) #define BLADEBIT_VERSION_STR \ - STR( BLADEBIT_VERSION_MAJ ) "." STR( BLADEBIT_VERSION_MIN ) "." STR( BLADEBIT_VERSION_REV ) + STR( BLADEBIT_VERSION_MAJ ) "." STR( BLADEBIT_VERSION_MIN ) "." STR( BLADEBIT_VERSION_REV ) \ + BLADEBIT_VERSION_SUFFIX diff --git a/src/View.h b/src/View.h index ce500f70..89767f68 100644 --- a/src/View.h +++ b/src/View.h @@ -1,32 +1,32 @@ -#pragma once - -template -struct View -{ - T* _ptr; - size_t _count; - - //----------------------------------------------------------- - inline View( T* ptr, size_t count ) - : _ptr ( ptr ) - , _count( count ) - {} - - //----------------------------------------------------------- - inline View( T* ptr ) - : _ptr ( ptr ) - , _count( 0 ) - {} - - - //----------------------------------------------------------- - inline T* operator-> () const { return this->_ptr; } - - //----------------------------------------------------------- - inline operator T* ( ) const { return this->_ptr; } - - // Returns true if the object ptr is not null - inline operator bool() const { return this->_ptr != nullptr; } - - +#pragma once + +template +struct View +{ + T* _ptr; + size_t _count; + + //----------------------------------------------------------- + inline View( T* ptr, size_t count ) + : _ptr ( ptr ) + , _count( count ) + {} + + //----------------------------------------------------------- + inline View( T* ptr ) + : _ptr ( ptr ) + , _count( 0 ) + {} + + + //----------------------------------------------------------- + inline T* operator-> () const { return this->_ptr; } + + //----------------------------------------------------------- + inline operator T* ( ) const { return this->_ptr; } + + // Returns true if the object ptr is not null + inline operator bool() const { return this->_ptr != nullptr; } + + }; \ No newline at end of file diff --git a/src/algorithm/RadixSort.h b/src/algorithm/RadixSort.h index 86dde153..e096ec39 100644 --- a/src/algorithm/RadixSort.h +++ b/src/algorithm/RadixSort.h @@ -1,326 +1,346 @@ -#pragma once -#include "threading/ThreadPool.h" -#include - -class RadixSort256 -{ - template - struct SortJob - { - uint id; // Id 0 is in charge of performing the non-parallel steps. - uint threadCount; // How many threads are participating in the sort - - // When All threads have finished, we can - // thread 0 (the control thread) can calculate jobs and signal them to continue - std::atomic* finishedCount; - std::atomic* releaseLock; - - uint64* counts; // Counts array for each thread - uint64* pfxSums; // Prefix sums for each thread. We use a different buffers to avoid copying to tmp buffers. - - uint64 startIndex; // Scan start index - uint64 length; // entry count in our scan region - - T1* input; - T1* tmp; - - // For sort key gen jobs - T2* keyInput; - T2* keyTmp; - }; - - enum SortMode - { - Void = 0, - ModeSingle = 1 << 0, - SortAndGenKey = 1 << 1, // Sort input and generate a key in keyInput at the same time - }; - -public: - template - static void Sort( ThreadPool& pool, T1* input, T1* tmp, uint64 length ); - - template - static void SortWithKey( ThreadPool& pool, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ); - - template - static void SortY( ThreadPool& pool, uint64* input, uint64* tmp, uint64 length ); - - template - static void SortYWithKey( ThreadPool& pool, uint64* input, uint64* tmp, uint32* keyInput, uint32* keyTmp, uint64 length ); - -private: - - template - static void DoSort( ThreadPool& pool, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ); - - template - static void RadixSortThread( SortJob* job ); -}; - - -//----------------------------------------------------------- -template -inline void RadixSort256::Sort( ThreadPool& pool, T1* input, T1* tmp, uint64 length ) -{ - DoSort( pool, input, tmp, nullptr, nullptr, length ); -} - -//----------------------------------------------------------- -template -inline void RadixSort256::SortWithKey( ThreadPool& pool, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ) -{ - DoSort( pool, input, tmp, keyInput, keyTmp, length ); -} - -//----------------------------------------------------------- -template -inline void RadixSort256::SortY( ThreadPool& pool, uint64* input, uint64* tmp, uint64 length ) -{ - DoSort( pool, input, tmp, nullptr, nullptr, length ); -} - -//----------------------------------------------------------- -template -inline void RadixSort256::SortYWithKey( ThreadPool& pool, uint64* input, uint64* tmp, uint32* keyInput, uint32* keyTmp, uint64 length ) -{ - DoSort( pool, input, tmp, keyInput, keyTmp, length ); -} - -//----------------------------------------------------------- -template -void inline RadixSort256::DoSort( ThreadPool& pool, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ) -{ - const uint threadCount = ThreadCount > pool.ThreadCount() ? pool.ThreadCount() : ThreadCount; - const uint64 entriesPerThread = length / threadCount; - const uint64 trailingEntries = length - ( entriesPerThread * threadCount ); - - // #TODO: Make sure we have enough stack space for this. - // Create a large stack, or allocate this on the heap... - // In which case, make this an instance method and have preallocated buffers for the jobs too - // Since we don't know the thread count ahead of time, maybe we should just make sure we allocate enough space for the jobs - // and use an instance instead... - uint64 counts [ThreadCount*256]; - uint64 prefixSums[ThreadCount*256]; - - std::atomic finishedCount = 0; - std::atomic releaseLock = 0; - SortJob jobs[ThreadCount]; - - for( uint i = 0; i < threadCount; i++ ) - { - auto& job = jobs[i]; - - job.id = i; - job.threadCount = threadCount; - job.finishedCount = &finishedCount; - job.releaseLock = &releaseLock; - job.counts = counts; - job.pfxSums = prefixSums; - job.startIndex = i * entriesPerThread; - job.length = entriesPerThread; - job.input = input; - job.tmp = tmp; - - job.keyInput = keyInput; - job.keyTmp = keyTmp; - } - - jobs[threadCount-1].length += trailingEntries; - - if constexpr ( Mode == SortAndGenKey ) - pool.RunJob( RadixSortThread, jobs, threadCount ); - else - pool.RunJob( RadixSortThread, jobs, threadCount ); -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" - -//----------------------------------------------------------- -template -void RadixSort256::RadixSortThread( SortJob* job ) -{ - constexpr uint Radix = 256; - - constexpr uint32 iterations = MaxIter > 0 ? MaxIter : sizeof( T1 ); - const uint32 shiftBase = 8; - - uint32 shift = 0; - - const uint id = job->id; - const uint threadCount = job->threadCount; - std::atomic& finishedCount = *job->finishedCount; - std::atomic& releaseLock = *job->releaseLock; - - uint64* counts = job->counts + id * Radix; - uint64* prefixSum = job->pfxSums + id * Radix; - const uint64 length = job->length; - const uint64 offset = job->startIndex; - T1* input = job->input; - T1* tmp = job->tmp; - - T2* keyInput; - T2* keyTmp; - - if constexpr ( IsKeyed ) - { - keyInput = job->keyInput; - keyTmp = job->keyTmp; - } - - for( uint32 iter = 0; iter < iterations ; iter++, shift += shiftBase ) - { - // Zero-out the counts - memset( counts, 0, sizeof( uint64 ) * Radix ); - - // Grab our scan region from the input - const T1* src = input + offset; - - const T2* keySrc; - if constexpr ( IsKeyed ) - keySrc = keyInput + offset; - - - // Store the occurrences of the current 'digit' - for( uint64 i = 0; i < length; i++ ) - counts[(src[i] >> shift) & 0xFF]++; - - // Synchronize with other threads to comput the correct prefix sum - if( id == 0 ) - { - // This is the control thread, it is in charge of computing the shared prefix sums. - - // Wait for all threads to finish - while( finishedCount.load( std::memory_order_relaxed ) != threadCount-1 ); - - uint64* allCounts = job->counts; - uint64* allPfxSums = job->pfxSums; - - // Use the last thread's prefix sum buffer as it will use - // it does not require a second pass - uint64* prefixSumBuffer = allPfxSums + (threadCount - 1) * Radix; - - // First sum all the counts. Start by copying ours to the last - memcpy( prefixSumBuffer, counts, sizeof( uint64 ) * Radix ); - - // Now add the rest of the thread's counts - for( uint i = 1; i < threadCount; i++ ) - { - uint64* tCounts = allCounts + i * Radix; - - for( uint32 j = 0; j < Radix; j++ ) - prefixSumBuffer[j] += tCounts[j]; - } - - // Now we have the sum of all thread's counts, - // we can calculate the prefix sum, which is - // equivalent to the last thread's prefix sum - for( uint32 j = 1; j < Radix; j++ ) - prefixSumBuffer[j] += prefixSumBuffer[j-1]; - - const uint64* nextThreadCountBuffer = allCounts + (threadCount - 1) * Radix; - - // Now assign the adjusted prefix sum to each thread below the last thread - // NOTE: We are traveling backwards from the last thread - for( uint i = 1; i < threadCount; i++ ) - { - uint64* tPrefixSum = prefixSumBuffer - Radix; - - // This thread's prefix sum is equal to the next thread's - // prefix sum minus the next thread's count - for( uint32 j = 0; j < Radix; j++ ) - tPrefixSum[j] = prefixSumBuffer[j] - nextThreadCountBuffer[j]; - - prefixSumBuffer = tPrefixSum; - nextThreadCountBuffer -= Radix; - } - - // Finished, init release lock & signal other threads - releaseLock .store( 0, std::memory_order_release ); - finishedCount.store( 0, std::memory_order_release ); - } - else - { - // Signal we've finished so we can calculate the shared prefix sum - uint count = finishedCount.load( std::memory_order_acquire ); - - while( !finishedCount.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); - - // Wait for the control thread (id == 0 ) to signal us so - // that we can continue working. - while( finishedCount.load( std::memory_order_relaxed ) != 0 ); - - // Ensure all threads have been released - count = releaseLock.load( std::memory_order_acquire ); - while( !releaseLock.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); - while( releaseLock.load( std::memory_order_relaxed ) != threadCount-1 ); - } - - // Populate output array (access input in reverse now) - // This writes to the whole output array, not just our section. - // This can cause false sharing, but given that our inputs are - // extremely large, and the accesses are random, we don't expect - // a lot of this to be happening. - for( uint64 i = length; i > 0; ) - { - // Read the value & prefix sum index - const T1 value = src[--i]; - - const uint64 idx = (value >> shift) & 0xFF; - - // Store it at the right location by reading the count - const uint64 dstIdx = --prefixSum[idx]; - tmp[dstIdx] = value; - - if constexpr ( IsKeyed ) - keyTmp[dstIdx] = keySrc[i]; - } - - // Swap arrays - T1* t = input; - input = tmp; - tmp = t; - - if constexpr ( IsKeyed ) - { - T2* tk = keyInput; - keyInput = keyTmp; - keyTmp = tk; - } - - // If not the last iteration, signal we've finished so we can - // safely read from the arrays after swapped. (all threads must finish writing) - if( (iter+1) < iterations ) - { - if( id == 0 ) - { - // Wait for all threads - while( finishedCount.load( std::memory_order_relaxed ) != (threadCount-1) ); - - // Finished, init release lock & signal other threads - releaseLock .store( 0, std::memory_order_release ); - finishedCount.store( 0, std::memory_order_release ); - } - else - { - // Signal control thread - uint count = finishedCount.load( std::memory_order_acquire ); - - while( !finishedCount.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); - - // Wait for control thread to signal us - while( finishedCount.load( std::memory_order_relaxed ) != 0 ); - - // Ensure all threads have been released - count = releaseLock.load( std::memory_order_acquire ); - while( !releaseLock.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); - while( releaseLock.load( std::memory_order_relaxed ) != threadCount-1 ); - } - } - } -} - -#pragma GCC diagnostic pop - - +#pragma once +#include "threading/ThreadPool.h" +#include + +class RadixSort256 +{ + template + struct SortJob + { + uint id; // Id 0 is in charge of performing the non-parallel steps. + uint threadCount; // How many threads are participating in the sort + + // When All threads have finished, we can + // thread 0 (the control thread) can calculate jobs and signal them to continue + std::atomic* finishedCount; + std::atomic* releaseLock; + + uint64* counts; // Counts array for each thread + uint64* pfxSums; // Prefix sums for each thread. We use a different buffers to avoid copying to tmp buffers. + + uint64 startIndex; // Scan start index + uint64 length; // entry count in our scan region + + T1* input; + T1* tmp; + + // For sort key gen jobs + T2* keyInput; + T2* keyTmp; + }; + + enum SortMode + { + Void = 0, + ModeSingle = 1 << 0, + SortAndGenKey = 1 << 1, // Sort input and generate a key in keyInput at the same time + }; + +public: + template + static void Sort( ThreadPool& pool, T1* input, T1* tmp, uint64 length ); + + template + static void Sort( ThreadPool& pool, const uint32 threadCount, T1* input, T1* tmp, uint64 length ); + + template + static void SortWithKey( ThreadPool& pool, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ); + + template + static void SortWithKey( ThreadPool& pool, const uint32 threadCount, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ); + + template + static void SortY( ThreadPool& pool, uint64* input, uint64* tmp, uint64 length ); + + template + static void SortYWithKey( ThreadPool& pool, uint64* input, uint64* tmp, uint32* keyInput, uint32* keyTmp, uint64 length ); + +private: + + template + static void DoSort( ThreadPool& pool, const uint32 desiredThreadCount, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ); + + template + static void RadixSortThread( SortJob* job ); +}; + + +//----------------------------------------------------------- +template +inline void RadixSort256::Sort( ThreadPool& pool, T1* input, T1* tmp, uint64 length ) +{ + DoSort( pool, 0, input, tmp, nullptr, nullptr, length ); +} + +//----------------------------------------------------------- +template +inline void RadixSort256::Sort( ThreadPool& pool, const uint32 threadCount, T1* input, T1* tmp, uint64 length ) +{ + DoSort( pool, threadCount, input, tmp, nullptr, nullptr, length ); +} + +//----------------------------------------------------------- +template +inline void RadixSort256::SortWithKey( ThreadPool& pool, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ) +{ + DoSort( pool, 0, input, tmp, keyInput, keyTmp, length ); +} + +//----------------------------------------------------------- +template +inline void RadixSort256::SortWithKey( ThreadPool& pool, const uint32 threadCount, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ) +{ + DoSort( pool, threadCount, input, tmp, keyInput, keyTmp, length ); +} + +//----------------------------------------------------------- +template +inline void RadixSort256::SortY( ThreadPool& pool, uint64* input, uint64* tmp, uint64 length ) +{ + DoSort( pool, 0, input, tmp, nullptr, nullptr, length ); +} + +//----------------------------------------------------------- +template +inline void RadixSort256::SortYWithKey( ThreadPool& pool, uint64* input, uint64* tmp, uint32* keyInput, uint32* keyTmp, uint64 length ) +{ + DoSort( pool, 0, input, tmp, keyInput, keyTmp, length ); +} + +//----------------------------------------------------------- +template +void inline RadixSort256::DoSort( ThreadPool& pool, const uint32 desiredThreadCount, T1* input, T1* tmp, TK* keyInput, TK* keyTmp, uint64 length ) +{ + const uint32 threadCount = desiredThreadCount == 0 ? pool.ThreadCount() : std::min( desiredThreadCount, pool.ThreadCount() ); + const uint64 entriesPerThread = length / threadCount; + const uint64 trailingEntries = length - ( entriesPerThread * threadCount ); + + // #TODO: Make sure we have enough stack space for this. + // Create a large stack, or allocate this on the heap... + // In which case, make this an instance method and have preallocated buffers for the jobs too + // Since we don't know the thread count ahead of time, maybe we should just make sure we allocate enough space for the jobs + // and use an instance instead... + uint64 counts [ThreadCount*256]; + uint64 prefixSums[ThreadCount*256]; + + std::atomic finishedCount = 0; + std::atomic releaseLock = 0; + SortJob jobs[ThreadCount]; + + for( uint i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job.id = i; + job.threadCount = threadCount; + job.finishedCount = &finishedCount; + job.releaseLock = &releaseLock; + job.counts = counts; + job.pfxSums = prefixSums; + job.startIndex = i * entriesPerThread; + job.length = entriesPerThread; + job.input = input; + job.tmp = tmp; + + job.keyInput = keyInput; + job.keyTmp = keyTmp; + } + + jobs[threadCount-1].length += trailingEntries; + + if constexpr ( Mode == SortAndGenKey ) + pool.RunJob( RadixSortThread, jobs, threadCount ); + else + pool.RunJob( RadixSortThread, jobs, threadCount ); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" + +//----------------------------------------------------------- +template +void RadixSort256::RadixSortThread( SortJob* job ) +{ + constexpr uint Radix = 256; + + constexpr uint32 iterations = MaxIter > 0 ? MaxIter : sizeof( T1 ); + const uint32 shiftBase = 8; + + uint32 shift = 0; + + const uint id = job->id; + const uint threadCount = job->threadCount; + std::atomic& finishedCount = *job->finishedCount; + std::atomic& releaseLock = *job->releaseLock; + + uint64* counts = job->counts + id * Radix; + uint64* prefixSum = job->pfxSums + id * Radix; + const uint64 length = job->length; + const uint64 offset = job->startIndex; + T1* input = job->input; + T1* tmp = job->tmp; + + T2* keyInput; + T2* keyTmp; + + if constexpr ( IsKeyed ) + { + keyInput = job->keyInput; + keyTmp = job->keyTmp; + } + + for( uint32 iter = 0; iter < iterations ; iter++, shift += shiftBase ) + { + // Zero-out the counts + memset( counts, 0, sizeof( uint64 ) * Radix ); + + // Grab our scan region from the input + const T1* src = input + offset; + + const T2* keySrc; + if constexpr ( IsKeyed ) + keySrc = keyInput + offset; + + + // Store the occurrences of the current 'digit' + for( uint64 i = 0; i < length; i++ ) + counts[(src[i] >> shift) & 0xFF]++; + + // Synchronize with other threads to compute the correct prefix sum + if( id == 0 ) + { + // This is the control thread, it is in charge of computing the shared prefix sums. + + // Wait for all threads to finish + while( finishedCount.load( std::memory_order_relaxed ) != threadCount-1 ); + + uint64* allCounts = job->counts; + uint64* allPfxSums = job->pfxSums; + + // Use the last thread's prefix sum buffer as it will use + // it does not require a second pass + uint64* prefixSumBuffer = allPfxSums + (threadCount - 1) * Radix; + + // First sum all the counts. Start by copying ours to the last + memcpy( prefixSumBuffer, counts, sizeof( uint64 ) * Radix ); + + // Now add the rest of the thread's counts + for( uint i = 1; i < threadCount; i++ ) + { + uint64* tCounts = allCounts + i * Radix; + + for( uint32 j = 0; j < Radix; j++ ) + prefixSumBuffer[j] += tCounts[j]; + } + + // Now we have the sum of all thread's counts, + // we can calculate the prefix sum, which is + // equivalent to the last thread's prefix sum + for( uint32 j = 1; j < Radix; j++ ) + prefixSumBuffer[j] += prefixSumBuffer[j-1]; + + const uint64* nextThreadCountBuffer = allCounts + (threadCount - 1) * Radix; + + // Now assign the adjusted prefix sum to each thread below the last thread + // NOTE: We are traveling backwards from the last thread + for( uint i = 1; i < threadCount; i++ ) + { + uint64* tPrefixSum = prefixSumBuffer - Radix; + + // This thread's prefix sum is equal to the next thread's + // prefix sum minus the next thread's count + for( uint32 j = 0; j < Radix; j++ ) + tPrefixSum[j] = prefixSumBuffer[j] - nextThreadCountBuffer[j]; + + prefixSumBuffer = tPrefixSum; + nextThreadCountBuffer -= Radix; + } + + // Finished, init release lock & signal other threads + releaseLock .store( 0, std::memory_order_release ); + finishedCount.store( 0, std::memory_order_release ); + } + else + { + // Signal we've finished so we can calculate the shared prefix sum + uint count = finishedCount.load( std::memory_order_acquire ); + + while( !finishedCount.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); + + // Wait for the control thread (id == 0 ) to signal us so + // that we can continue working. + while( finishedCount.load( std::memory_order_relaxed ) != 0 ); + + // Ensure all threads have been released + count = releaseLock.load( std::memory_order_acquire ); + while( !releaseLock.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); + while( releaseLock.load( std::memory_order_relaxed ) != threadCount-1 ); + } + + // Populate output array (access input in reverse now) + // This writes to the whole output array, not just our section. + // This can cause false sharing, but given that our inputs are + // extremely large, and the accesses are random, we don't expect + // a lot of this to be happening. + for( uint64 i = length; i > 0; ) + { + // Read the value & prefix sum index + const T1 value = src[--i]; + + const uint64 idx = (value >> shift) & 0xFF; + + // Store it at the right location by reading the count + const uint64 dstIdx = --prefixSum[idx]; + tmp[dstIdx] = value; + + if constexpr ( IsKeyed ) + keyTmp[dstIdx] = keySrc[i]; + } + + // Swap arrays + T1* t = input; + input = tmp; + tmp = t; + + if constexpr ( IsKeyed ) + { + T2* tk = keyInput; + keyInput = keyTmp; + keyTmp = tk; + } + + // If not the last iteration, signal we've finished so we can + // safely read from the arrays after swapped. (all threads must finish writing) + if( (iter+1) < iterations ) + { + if( id == 0 ) + { + // Wait for all threads + while( finishedCount.load( std::memory_order_relaxed ) != (threadCount-1) ); + + // Finished, init release lock & signal other threads + releaseLock .store( 0, std::memory_order_release ); + finishedCount.store( 0, std::memory_order_release ); + } + else + { + // Signal control thread + uint count = finishedCount.load( std::memory_order_acquire ); + + while( !finishedCount.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); + + // Wait for control thread to signal us + while( finishedCount.load( std::memory_order_relaxed ) != 0 ); + + // Ensure all threads have been released + count = releaseLock.load( std::memory_order_acquire ); + while( !releaseLock.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); + while( releaseLock.load( std::memory_order_relaxed ) != threadCount-1 ); + } + } + } +} + +#pragma GCC diagnostic pop + + diff --git a/src/algorithm/YSort.cpp b/src/algorithm/YSort.cpp index 78d2a1a7..45585e9e 100644 --- a/src/algorithm/YSort.cpp +++ b/src/algorithm/YSort.cpp @@ -1,510 +1,510 @@ -#include "YSort.h" -#include "SysHost.h" -#include "threading/ThreadPool.h" -#include "Util.h" -#include "util/Log.h" -#include "Config.h" -#include "ChiaConsts.h" - - -template -struct SortYBaseJob -{ - JobT* jobs; - - std::atomic* finishedCount; - std::atomic* releaseLock; - - // #TODO: Convert these to a pointer of pointers so that we don't have to - // load to iterate on the job struct itself, which is really heavy, - // and will load more data than we need in the cache. - uint32* counts; // Counts array for each thread. This is set by the thread itself - void* pfxSum; - - uint id; - uint threadCount; - -protected: - template - void CalculatePrefixSum( uint id, uint32* counts, TPrefix* pfxSum ); - - void SyncThreads(); - void LockThreads(); - void ReleaseThreads(); - -}; - -struct SortYJob : SortYBaseJob -{ - uint64 length; // Total entries length - - uint64* input; - uint64* tmp; - - uint32* sortKey; - uint32* sortKeyTmp; - - template - static void SortYThread( SortYJob* job ); - -private: - template - void SortBucket( const uint64 bucket, const uint offset, - const uint bucketOffset, const uint32 length, - uint32* counts, uint32* pfxSum, - uint32* input, YT* tmp, - uint32* sortKey, uint32* sortKeyTmp ); -}; - -struct NumaSortJob -{ - uint id; - uint threadCount; - uint node; - uint nodeCount; - uint threadGroup; - - uint pageCount; - uint pageStart; - uint trailers; - - std::atomic* finishedCount; - std::atomic* releaseLock; - - byte* pages; - byte* tmpPages; - - byte* sortKeyPages; - byte* tmpSortKeyPages; - - byte* countsPerPage; // Count buffer, which is kept per page - - uint32* counts; // Counts array for each thread. - uint64* pfxSum; // Prefix sums for each thread. We use a different buffers to avoid copying to tmp buffers. -}; - - -//----------------------------------------------------------- -YSorter::YSorter( ThreadPool& pool ) - : _pool( pool ) -{ - // const NumaInfo* numa = SysHost::GetNUMAInfo(); - // if( !numa ) - // Fatal( "Cannot use NUMA y-sort on non-NUMA info." ); -} - -//----------------------------------------------------------- -YSorter::~YSorter() -{ - -} - -//----------------------------------------------------------- -void YSorter::Sort( uint64 length, uint64* yBuffer, uint64* yTmp ) -{ - DoSort( false, length, yBuffer, yTmp, nullptr, nullptr ); -} - -//----------------------------------------------------------- -void YSorter::Sort( - uint64 length, - uint64* yBuffer, uint64* yTmp, - uint32* sortKey, uint32* sortKeyTmp ) -{ - ASSERT( sortKey && sortKeyTmp ); - DoSort( true, length, yBuffer, yTmp, sortKey, sortKeyTmp ); -} - -//----------------------------------------------------------- -void YSorter::DoSort( bool useSortKey, uint64 length, - uint64* yBuffer, uint64* yTmp, - uint32* sortKey, uint32* sortKeyTmp ) -{ - ASSERT( length ); - ASSERT( yBuffer && yTmp ); - - ThreadPool& pool = _pool; - const uint threadCount = pool.ThreadCount(); - - SortYJob jobs[MAX_THREADS]; - - std::atomic finishedCount = 0; - std::atomic releaseLock = 0; - - for( uint i = 0; i < MAX_THREADS; i++ ) - { - SortYJob& job = jobs[i]; - - job.jobs = jobs; - job.finishedCount = &finishedCount; - job.releaseLock = &releaseLock; - job.length = length; - job.counts = nullptr; - job.pfxSum = nullptr; - job.id = i; - job.threadCount = threadCount; - job.length = length; - job.input = yBuffer; - job.tmp = yTmp; - - job.sortKey = sortKey; - job.sortKeyTmp = sortKeyTmp; - } - - if( useSortKey ) - pool.RunJob( SortYJob::SortYThread, jobs, threadCount ); - else - pool.RunJob( SortYJob::SortYThread, jobs, threadCount ); -} - -//----------------------------------------------------------- -template -void SortYJob::SortYThread( SortYJob* job ) -{ - constexpr uint Radix = 256; - constexpr uint Buckets = (1u << kExtraBits); - - const uint id = job->id; - const uint threadCount = job->threadCount; - - uint64* input = job->input; - uint64* tmp = job->tmp; - - uint32* sortKey = job->sortKey; - uint32* sortKeyTmp = job->sortKeyTmp; - - uint32 counts[Radix]; - job->counts = counts; - - // Sort the last most significant byte first, yielding 256 buckets and - // stripping out that byte, leaving us with a 32-bit element size for the radix sort. - { - uint64 pfxSum[Buckets]; - - memset( counts, 0, sizeof( counts ) ); - memset( pfxSum, 0, sizeof( pfxSum ) ); - - uint64 length = job->length / threadCount; - const uint64 offset = length * id; - - if( id == threadCount - 1 ) - length += job->length - ( length * threadCount ); - - uint64* src = input + offset; - const uint64* end = src + length; - - uint32* sortKeySrc; - if constexpr ( HasSortKey ) - sortKeySrc = sortKey + offset; - - // Get counts - #if !Y_SORT_BLOCK_MODE - do { counts[*src >> 32]++; } - while( ++src < end ); - #else - const uint64 numBlocks = length / 8; - const uint64* blockEnd = src + numBlocks * 8; - do - { - counts[src[0] >> 32]++; - counts[src[1] >> 32]++; - counts[src[2] >> 32]++; - counts[src[3] >> 32]++; - - counts[src[4] >> 32]++; - counts[src[5] >> 32]++; - counts[src[6] >> 32]++; - counts[src[7] >> 32]++; - - src += 8; - } while( src < blockEnd ); - - while( src < end ) - counts[*src++ >> 32]++; - #endif - - // Get prefix sum - job->pfxSum = pfxSum; - job->CalculatePrefixSum( id, counts, pfxSum ); - - // Sort into buckets - src = input + offset; - uint32* tmp32 = (uint32*)tmp; - // do - for( uint64 i = length; i > 0; ) - { - const uint64 value = src[--i]; //*src; - const byte bucket = (byte)( value >> 32 ); - - const uint64 idx = --pfxSum[bucket]; - tmp32[idx] = (uint32)value; - - if constexpr ( HasSortKey ) - sortKeyTmp[idx] = sortKeySrc[i]; - } - // } while( ++src < end ); - - std::swap( input, tmp ); - - if constexpr ( HasSortKey ) - std::swap( sortKey, sortKeyTmp ); - } - - // Get lengths for each bucket - { - SortYJob* jobs = job->jobs; - - uint bucketLengths[Buckets]; - memset( bucketLengths, 0, sizeof( bucketLengths ) ); - - for( uint i = 0; i < threadCount; i++ ) - { - const uint32* tCounts = jobs[i].counts; - - for( uint j = 0; j < Buckets; j++ ) - bucketLengths[j] += tCounts[j]; - } - - // Ensure all threads have finished writing to tmp - job->SyncThreads(); - - - // Now do a radix sort on the 3/4 bytes for each 32-bit entries stored in each bucket. - uint pfxSum[Radix]; - job->pfxSum = pfxSum; - - uint bucketOffset = 0; - for( uint bucket = 0; bucket < Buckets; bucket++ ) - { - uint length = bucketLengths[bucket] / threadCount; - const uint offset = bucketOffset + length * id; - - // Add the remainder if we're the last thread - if( id == threadCount-1 ) - length += bucketLengths[bucket] - (threadCount * length); - - job->SortBucket( bucket, offset, bucketOffset, length, counts, pfxSum, (uint32*)input, (uint32*)tmp , sortKey, sortKeyTmp ); - job->SortBucket( bucket, offset, bucketOffset, length, counts, pfxSum, (uint32*)tmp , (uint32*)input, sortKeyTmp, sortKey ); - job->SortBucket( bucket, offset, bucketOffset, length, counts, pfxSum, (uint32*)input, (uint32*)tmp , sortKey, sortKeyTmp ); - - bucketOffset += bucketLengths[bucket]; - } - - // Now do a final expansion sort for the MSB of the 32-bit entries. - // NOTE: This has to be done as a last step, because if we do it within each - // bucket in the previous step, we would overwrite adjacent buckets during the expansion. - - bucketOffset = 0; - - for( uint bucket = 0; bucket < Buckets; bucket++ ) - { - uint length = bucketLengths[bucket] / threadCount; - const uint offset = bucketOffset + length * id; - - // Add the remainder if we're the last thread - if( id == threadCount-1 ) - length += bucketLengths[bucket] - (threadCount * length); - - job->SortBucket( ((uint64)bucket) << 32, offset, bucketOffset, length, counts, pfxSum, (uint32*)tmp, input, sortKeyTmp, sortKey ); - - bucketOffset += bucketLengths[bucket]; - } - } -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wattributes" - -//----------------------------------------------------------- -template -FORCE_INLINE void SortYJob::SortBucket( const uint64 bucket, const uint offset, - const uint bucketOffset, const uint32 length, - uint32* counts, uint32* pfxSum, - uint32* input, YT* tmp, - uint32* sortKey, uint32* sortKeyTmp ) -{ - const uint Radix = 256; - - const uint32* start = input + offset; - const uint32* end = start + length; - - uint32* src = (uint32*)start; - uint32* keySrc; - - if constexpr ( HasSortKey ) - keySrc = sortKey + offset; - - - // Get counts - memset( counts, 0, sizeof( uint32 ) * Radix ); - -#if !Y_SORT_BLOCK_MODE - do { counts[(*src >> shift) & 0xFF]++; } - while( ++src < end ); -#else - // Assume block size = 64 bytes - const uint64 numBlocks = length / 16; - const uint32* blockEnd = src + numBlocks * 16; - do - { - counts[(src[0] >> shift) & 0xFF]++; - counts[(src[1] >> shift) & 0xFF]++; - counts[(src[2] >> shift) & 0xFF]++; - counts[(src[3] >> shift) & 0xFF]++; - counts[(src[4] >> shift) & 0xFF]++; - counts[(src[5] >> shift) & 0xFF]++; - counts[(src[6] >> shift) & 0xFF]++; - counts[(src[7] >> shift) & 0xFF]++; - - counts[(src[8 ] >> shift) & 0xFF]++; - counts[(src[9 ] >> shift) & 0xFF]++; - counts[(src[10] >> shift) & 0xFF]++; - counts[(src[11] >> shift) & 0xFF]++; - counts[(src[12] >> shift) & 0xFF]++; - counts[(src[13] >> shift) & 0xFF]++; - counts[(src[14] >> shift) & 0xFF]++; - counts[(src[15] >> shift) & 0xFF]++; - - src += 16; - } while( src < blockEnd ); - - while( src < end ) - counts[(*src++ >> shift) & 0xFF]++; -#endif - - // Get prefix sum - CalculatePrefixSum( id, counts, pfxSum ); - - // Store in new location, iterating backwards - src = (uint32*)start; - YT* dst = tmp + bucketOffset; - - uint32* keyDst; - if constexpr ( HasSortKey ) - keyDst = sortKeyTmp + bucketOffset; - - for( uint64 i = length; i > 0; ) - { - YT value = src[--i]; - const byte cIdx = (byte)( value >> shift ); - - const uint32 dstIdx = --pfxSum[cIdx]; - - // Expand with bucket id - if constexpr ( std::is_same::value ) - value |= bucket; - - dst[dstIdx] = value; - - if constexpr ( HasSortKey ) - keyDst[dstIdx] = keySrc[i]; - - } - - SyncThreads(); -} - - - -//----------------------------------------------------------- -void SortYNumaThread( NumaSortJob* job ) -{ - // Count entries for this radix in each page & store counts in that page's count buffer - -} - -//----------------------------------------------------------- -template -template -FORCE_INLINE void SortYBaseJob::CalculatePrefixSum( uint id, uint32* counts, TPrefix* pfxSum ) -{ - const uint threadCount = this->threadCount; - const auto* jobs = this->jobs; - - SyncThreads(); - - // Add all thread's counts - memset( pfxSum, 0, sizeof( TPrefix ) * Radix ); - - for( uint t = 0; t < threadCount; t++ ) - { - const uint* tCounts = jobs[t].counts; - - for( uint i = 0; i < Radix; i++ ) - pfxSum[i] += tCounts[i]; - } - - // Calculate prefix sum for this thread - for( uint i = 1; i < Radix; i++ ) - pfxSum[i] += pfxSum[i-1]; - - // Substract the count from all threads after ours - for( uint t = id+1; t < threadCount; t++ ) - { - const uint* tCounts = jobs[t].counts; - - for( uint i = 0; i < Radix; i++ ) - pfxSum[i] -= tCounts[i]; - } -} - -//----------------------------------------------------------- -template -FORCE_INLINE void SortYBaseJob::SyncThreads() -{ - auto& finishedCount = *this->finishedCount; - auto& releaseLock = *this->releaseLock; - const uint threadThreshold = this->threadCount - 1; - - // Reset the release lock - if( id == 0 ) - { - // Wait for all threads to finish - while( finishedCount.load( std::memory_order_relaxed ) != threadThreshold ); - - // Finished, initialize release lock & signal other threads - releaseLock .store( 0, std::memory_order_release ); - finishedCount.store( 0, std::memory_order_release ); - } - else - { - // Signal we've finished so we can calculate the shared prefix sum - uint count = finishedCount.load( std::memory_order_acquire ); - - while( !finishedCount.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); - - // Wait for the control thread (id == 0 ) to signal us - while( finishedCount.load( std::memory_order_relaxed ) != 0 ); - - // Ensure all threads have been released - count = releaseLock.load( std::memory_order_acquire ); - while( !releaseLock.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); - while( releaseLock.load( std::memory_order_relaxed ) != threadThreshold ); - } -} - -//----------------------------------------------------------- -template -FORCE_INLINE void SortYBaseJob::LockThreads() -{ - auto& finishedCount = *this->finishedCount; - const uint threadThreshold = this->threadCount - 1; - - // Wait for all threads to finish - while( finishedCount.load( std::memory_order_relaxed ) != threadThreshold ); -} - -//----------------------------------------------------------- -template -FORCE_INLINE void SortYBaseJob::ReleaseThreads() -{ - auto& finishedCount = *this->finishedCount; - auto& releaseLock = *this->releaseLock; - - // Finished, init release lock & signal other threads - releaseLock .store( 0, std::memory_order_release ); - finishedCount.store( 0, std::memory_order_release ); -} - -#pragma GCC diagnostic pop - +#include "YSort.h" +#include "SysHost.h" +#include "threading/ThreadPool.h" +#include "util/Util.h" +#include "util/Log.h" +#include "Config.h" +#include "ChiaConsts.h" + + +template +struct SortYBaseJob +{ + JobT* jobs; + + std::atomic* finishedCount; + std::atomic* releaseLock; + + // #TODO: Convert these to a pointer of pointers so that we don't have to + // load to iterate on the job struct itself, which is really heavy, + // and will load more data than we need in the cache. + uint32* counts; // Counts array for each thread. This is set by the thread itself + void* pfxSum; + + uint id; + uint threadCount; + +protected: + template + void CalculatePrefixSum( uint id, uint32* counts, TPrefix* pfxSum ); + + void SyncThreads(); + void LockThreads(); + void ReleaseThreads(); + +}; + +struct SortYJob : SortYBaseJob +{ + uint64 length; // Total entries length + + uint64* input; + uint64* tmp; + + uint32* sortKey; + uint32* sortKeyTmp; + + template + static void SortYThread( SortYJob* job ); + +private: + template + void SortBucket( const uint64 bucket, const uint offset, + const uint bucketOffset, const uint32 length, + uint32* counts, uint32* pfxSum, + uint32* input, YT* tmp, + uint32* sortKey, uint32* sortKeyTmp ); +}; + +struct NumaSortJob +{ + uint id; + uint threadCount; + uint node; + uint nodeCount; + uint threadGroup; + + uint pageCount; + uint pageStart; + uint trailers; + + std::atomic* finishedCount; + std::atomic* releaseLock; + + byte* pages; + byte* tmpPages; + + byte* sortKeyPages; + byte* tmpSortKeyPages; + + byte* countsPerPage; // Count buffer, which is kept per page + + uint32* counts; // Counts array for each thread. + uint64* pfxSum; // Prefix sums for each thread. We use a different buffers to avoid copying to tmp buffers. +}; + + +//----------------------------------------------------------- +YSorter::YSorter( ThreadPool& pool ) + : _pool( pool ) +{ + // const NumaInfo* numa = SysHost::GetNUMAInfo(); + // if( !numa ) + // Fatal( "Cannot use NUMA y-sort on non-NUMA info." ); +} + +//----------------------------------------------------------- +YSorter::~YSorter() +{ + +} + +//----------------------------------------------------------- +void YSorter::Sort( uint64 length, uint64* yBuffer, uint64* yTmp ) +{ + DoSort( false, length, yBuffer, yTmp, nullptr, nullptr ); +} + +//----------------------------------------------------------- +void YSorter::Sort( + uint64 length, + uint64* yBuffer, uint64* yTmp, + uint32* sortKey, uint32* sortKeyTmp ) +{ + ASSERT( sortKey && sortKeyTmp ); + DoSort( true, length, yBuffer, yTmp, sortKey, sortKeyTmp ); +} + +//----------------------------------------------------------- +void YSorter::DoSort( bool useSortKey, uint64 length, + uint64* yBuffer, uint64* yTmp, + uint32* sortKey, uint32* sortKeyTmp ) +{ + ASSERT( length ); + ASSERT( yBuffer && yTmp ); + + ThreadPool& pool = _pool; + const uint threadCount = pool.ThreadCount(); + + SortYJob jobs[MAX_THREADS]; + + std::atomic finishedCount = 0; + std::atomic releaseLock = 0; + + for( uint i = 0; i < MAX_THREADS; i++ ) + { + SortYJob& job = jobs[i]; + + job.jobs = jobs; + job.finishedCount = &finishedCount; + job.releaseLock = &releaseLock; + job.length = length; + job.counts = nullptr; + job.pfxSum = nullptr; + job.id = i; + job.threadCount = threadCount; + job.length = length; + job.input = yBuffer; + job.tmp = yTmp; + + job.sortKey = sortKey; + job.sortKeyTmp = sortKeyTmp; + } + + if( useSortKey ) + pool.RunJob( SortYJob::SortYThread, jobs, threadCount ); + else + pool.RunJob( SortYJob::SortYThread, jobs, threadCount ); +} + +//----------------------------------------------------------- +template +void SortYJob::SortYThread( SortYJob* job ) +{ + constexpr uint Radix = 256; + constexpr uint Buckets = (1u << kExtraBits); + + const uint id = job->id; + const uint threadCount = job->threadCount; + + uint64* input = job->input; + uint64* tmp = job->tmp; + + uint32* sortKey = job->sortKey; + uint32* sortKeyTmp = job->sortKeyTmp; + + uint32 counts[Radix]; + job->counts = counts; + + // Sort the most-significant-byte first, yielding 64 buckets and + // stripping out that byte, leaving us with a 32-bit element size for the radix sort. + { + uint64 pfxSum[Buckets]; + + memset( counts, 0, sizeof( counts ) ); + memset( pfxSum, 0, sizeof( pfxSum ) ); + + uint64 length = job->length / threadCount; + const uint64 offset = length * id; + + if( id == threadCount - 1 ) + length += job->length - ( length * threadCount ); + + uint64* src = input + offset; + const uint64* end = src + length; + + uint32* sortKeySrc; + if constexpr ( HasSortKey ) + sortKeySrc = sortKey + offset; + + // Get counts + #if !Y_SORT_BLOCK_MODE + do { counts[*src >> 32]++; } + while( ++src < end ); + #else + const uint64 numBlocks = length / 8; + const uint64* blockEnd = src + numBlocks * 8; + do + { + counts[src[0] >> 32]++; + counts[src[1] >> 32]++; + counts[src[2] >> 32]++; + counts[src[3] >> 32]++; + + counts[src[4] >> 32]++; + counts[src[5] >> 32]++; + counts[src[6] >> 32]++; + counts[src[7] >> 32]++; + + src += 8; + } while( src < blockEnd ); + + while( src < end ) + counts[*src++ >> 32]++; + #endif + + // Get prefix sum + job->pfxSum = pfxSum; + job->CalculatePrefixSum( id, counts, pfxSum ); + + // Sort into buckets + src = input + offset; + uint32* tmp32 = (uint32*)tmp; + // do + for( uint64 i = length; i > 0; ) + { + const uint64 value = src[--i]; //*src; + const byte bucket = (byte)( value >> 32 ); + + const uint64 idx = --pfxSum[bucket]; + tmp32[idx] = (uint32)value; + + if constexpr ( HasSortKey ) + sortKeyTmp[idx] = sortKeySrc[i]; + } + // } while( ++src < end ); + + std::swap( input, tmp ); + + if constexpr ( HasSortKey ) + std::swap( sortKey, sortKeyTmp ); + } + + // Get lengths for each bucket + { + SortYJob* jobs = job->jobs; + + uint bucketLengths[Buckets]; + memset( bucketLengths, 0, sizeof( bucketLengths ) ); + + for( uint i = 0; i < threadCount; i++ ) + { + const uint32* tCounts = jobs[i].counts; + + for( uint j = 0; j < Buckets; j++ ) + bucketLengths[j] += tCounts[j]; + } + + // Ensure all threads have finished writing to tmp + job->SyncThreads(); + + + // Now do a radix sort on the 3/4 bytes for each 32-bit entries stored in each bucket. + uint pfxSum[Radix]; + job->pfxSum = pfxSum; + + uint bucketOffset = 0; + for( uint bucket = 0; bucket < Buckets; bucket++ ) + { + uint length = bucketLengths[bucket] / threadCount; + const uint offset = bucketOffset + length * id; + + // Add the remainder if we're the last thread + if( id == threadCount-1 ) + length += bucketLengths[bucket] - (threadCount * length); + + job->SortBucket( bucket, offset, bucketOffset, length, counts, pfxSum, (uint32*)input, (uint32*)tmp , sortKey, sortKeyTmp ); + job->SortBucket( bucket, offset, bucketOffset, length, counts, pfxSum, (uint32*)tmp , (uint32*)input, sortKeyTmp, sortKey ); + job->SortBucket( bucket, offset, bucketOffset, length, counts, pfxSum, (uint32*)input, (uint32*)tmp , sortKey, sortKeyTmp ); + + bucketOffset += bucketLengths[bucket]; + } + + // Now do a final expansion sort for the MSB of the 32-bit entries. + // NOTE: This has to be done as a last step, because if we do it within each + // bucket in the previous step, we would overwrite adjacent buckets during the expansion. + + bucketOffset = 0; + + for( uint bucket = 0; bucket < Buckets; bucket++ ) + { + uint length = bucketLengths[bucket] / threadCount; + const uint offset = bucketOffset + length * id; + + // Add the remainder if we're the last thread + if( id == threadCount-1 ) + length += bucketLengths[bucket] - (threadCount * length); + + job->SortBucket( ((uint64)bucket) << 32, offset, bucketOffset, length, counts, pfxSum, (uint32*)tmp, input, sortKeyTmp, sortKey ); + + bucketOffset += bucketLengths[bucket]; + } + } +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattributes" + +//----------------------------------------------------------- +template +FORCE_INLINE void SortYJob::SortBucket( const uint64 bucket, const uint offset, + const uint bucketOffset, const uint32 length, + uint32* counts, uint32* pfxSum, + uint32* input, YT* tmp, + uint32* sortKey, uint32* sortKeyTmp ) +{ + const uint Radix = 256; + + const uint32* start = input + offset; + const uint32* end = start + length; + + uint32* src = (uint32*)start; + uint32* keySrc; + + if constexpr ( HasSortKey ) + keySrc = sortKey + offset; + + + // Get counts + memset( counts, 0, sizeof( uint32 ) * Radix ); + +#if !Y_SORT_BLOCK_MODE + do { counts[(*src >> shift) & 0xFF]++; } + while( ++src < end ); +#else + // Assume block size = 64 bytes + const uint64 numBlocks = length / 16; + const uint32* blockEnd = src + numBlocks * 16; + do + { + counts[(src[0] >> shift) & 0xFF]++; + counts[(src[1] >> shift) & 0xFF]++; + counts[(src[2] >> shift) & 0xFF]++; + counts[(src[3] >> shift) & 0xFF]++; + counts[(src[4] >> shift) & 0xFF]++; + counts[(src[5] >> shift) & 0xFF]++; + counts[(src[6] >> shift) & 0xFF]++; + counts[(src[7] >> shift) & 0xFF]++; + + counts[(src[8 ] >> shift) & 0xFF]++; + counts[(src[9 ] >> shift) & 0xFF]++; + counts[(src[10] >> shift) & 0xFF]++; + counts[(src[11] >> shift) & 0xFF]++; + counts[(src[12] >> shift) & 0xFF]++; + counts[(src[13] >> shift) & 0xFF]++; + counts[(src[14] >> shift) & 0xFF]++; + counts[(src[15] >> shift) & 0xFF]++; + + src += 16; + } while( src < blockEnd ); + + while( src < end ) + counts[(*src++ >> shift) & 0xFF]++; +#endif + + // Get prefix sum + CalculatePrefixSum( id, counts, pfxSum ); + + // Store in new location, iterating backwards + src = (uint32*)start; + YT* dst = tmp + bucketOffset; + + uint32* keyDst; + if constexpr ( HasSortKey ) + keyDst = sortKeyTmp + bucketOffset; + + for( uint64 i = length; i > 0; ) + { + YT value = src[--i]; + const byte cIdx = (byte)( value >> shift ); + + const uint32 dstIdx = --pfxSum[cIdx]; + + // Expand with bucket id + if constexpr ( std::is_same::value ) + value |= bucket; + + dst[dstIdx] = value; + + if constexpr ( HasSortKey ) + keyDst[dstIdx] = keySrc[i]; + + } + + SyncThreads(); +} + + + +//----------------------------------------------------------- +void SortYNumaThread( NumaSortJob* job ) +{ + // Count entries for this radix in each page & store counts in that page's count buffer + +} + +//----------------------------------------------------------- +template +template +FORCE_INLINE void SortYBaseJob::CalculatePrefixSum( uint id, uint32* counts, TPrefix* pfxSum ) +{ + const uint threadCount = this->threadCount; + const auto* jobs = this->jobs; + + SyncThreads(); + + // Add all thread's counts + memset( pfxSum, 0, sizeof( TPrefix ) * Radix ); + + for( uint t = 0; t < threadCount; t++ ) + { + const uint* tCounts = jobs[t].counts; + + for( uint i = 0; i < Radix; i++ ) + pfxSum[i] += tCounts[i]; + } + + // Calculate prefix sum for this thread + for( uint i = 1; i < Radix; i++ ) + pfxSum[i] += pfxSum[i-1]; + + // Substract the count from all threads after ours + for( uint t = id+1; t < threadCount; t++ ) + { + const uint* tCounts = jobs[t].counts; + + for( uint i = 0; i < Radix; i++ ) + pfxSum[i] -= tCounts[i]; + } +} + +//----------------------------------------------------------- +template +FORCE_INLINE void SortYBaseJob::SyncThreads() +{ + auto& finishedCount = *this->finishedCount; + auto& releaseLock = *this->releaseLock; + const uint threadThreshold = this->threadCount - 1; + + // Reset the release lock + if( id == 0 ) + { + // Wait for all threads to finish + while( finishedCount.load( std::memory_order_relaxed ) != threadThreshold ); + + // Finished, initialize release lock & signal other threads + releaseLock .store( 0, std::memory_order_release ); + finishedCount.store( 0, std::memory_order_release ); + } + else + { + // Signal we've finished so we can calculate the shared prefix sum + uint count = finishedCount.load( std::memory_order_acquire ); + + while( !finishedCount.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); + + // Wait for the control thread (id == 0 ) to signal us + while( finishedCount.load( std::memory_order_relaxed ) != 0 ); + + // Ensure all threads have been released + count = releaseLock.load( std::memory_order_acquire ); + while( !releaseLock.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); + while( releaseLock.load( std::memory_order_relaxed ) != threadThreshold ); + } +} + +//----------------------------------------------------------- +template +FORCE_INLINE void SortYBaseJob::LockThreads() +{ + auto& finishedCount = *this->finishedCount; + const uint threadThreshold = this->threadCount - 1; + + // Wait for all threads to finish + while( finishedCount.load( std::memory_order_relaxed ) != threadThreshold ); +} + +//----------------------------------------------------------- +template +FORCE_INLINE void SortYBaseJob::ReleaseThreads() +{ + auto& finishedCount = *this->finishedCount; + auto& releaseLock = *this->releaseLock; + + // Finished, init release lock & signal other threads + releaseLock .store( 0, std::memory_order_release ); + finishedCount.store( 0, std::memory_order_release ); +} + +#pragma GCC diagnostic pop + diff --git a/src/algorithm/YSort.h b/src/algorithm/YSort.h index b44ef973..40c68815 100644 --- a/src/algorithm/YSort.h +++ b/src/algorithm/YSort.h @@ -1,34 +1,34 @@ -#pragma once - - -class ThreadPool; - - -class YSorter -{ -public: - YSorter( ThreadPool& pool ); - ~YSorter(); - - // template - void Sort( - uint64 length, - uint64* yBuffer, uint64* yTmp ); - - void Sort( - uint64 length, - uint64* yBuffer, uint64* yTmp, - uint32* sortKey, uint32* sortKeyTmp ); - -private: - void DoSort( bool useSortKey, uint64 length, - uint64* yBuffer, uint64* yTmp, - uint32* sortKey, uint32* sortKeyTmp ); -private: - ThreadPool& _pool; - // byte* _pageCounts; -}; - - - - +#pragma once + + +class ThreadPool; + + +class YSorter +{ +public: + YSorter( ThreadPool& pool ); + ~YSorter(); + + // template + void Sort( + uint64 length, + uint64* yBuffer, uint64* yTmp ); + + void Sort( + uint64 length, + uint64* yBuffer, uint64* yTmp, + uint32* sortKey, uint32* sortKeyTmp ); + +private: + void DoSort( bool useSortKey, uint64 length, + uint64* yBuffer, uint64* yTmp, + uint32* sortKey, uint32* sortKeyTmp ); +private: + ThreadPool& _pool; + // byte* _pageCounts; +}; + + + + diff --git a/src/b3/blake3.c b/src/b3/blake3.c index f7973db3..5c999a71 100644 --- a/src/b3/blake3.c +++ b/src/b3/blake3.c @@ -1,605 +1,605 @@ -#include -#include -#include - -#include "blake3.h" -#include "blake3_impl.h" - -INLINE void chunk_state_init(blake3_chunk_state *self, const uint32_t key[8], - uint8_t flags) { - memcpy(self->cv, key, BLAKE3_KEY_LEN); - self->chunk_counter = 0; - memset(self->buf, 0, BLAKE3_BLOCK_LEN); - self->buf_len = 0; - self->blocks_compressed = 0; - self->flags = flags; -} - -INLINE void chunk_state_reset(blake3_chunk_state *self, const uint32_t key[8], - uint64_t chunk_counter) { - memcpy(self->cv, key, BLAKE3_KEY_LEN); - self->chunk_counter = chunk_counter; - self->blocks_compressed = 0; - memset(self->buf, 0, BLAKE3_BLOCK_LEN); - self->buf_len = 0; -} - -INLINE size_t chunk_state_len(const blake3_chunk_state *self) { - return (BLAKE3_BLOCK_LEN * (size_t)self->blocks_compressed) + - ((size_t)self->buf_len); -} - -INLINE size_t chunk_state_fill_buf(blake3_chunk_state *self, - const uint8_t *input, size_t input_len) { - size_t take = BLAKE3_BLOCK_LEN - ((size_t)self->buf_len); - if (take > input_len) { - take = input_len; - } - uint8_t *dest = self->buf + ((size_t)self->buf_len); - memcpy(dest, input, take); - self->buf_len += (uint8_t)take; - return take; -} - -INLINE uint8_t chunk_state_maybe_start_flag(const blake3_chunk_state *self) { - if (self->blocks_compressed == 0) { - return CHUNK_START; - } else { - return 0; - } -} - -typedef struct { - uint32_t input_cv[8]; - uint64_t counter; - uint8_t block[BLAKE3_BLOCK_LEN]; - uint8_t block_len; - uint8_t flags; -} output_t; - -INLINE output_t make_output(const uint32_t input_cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags) { - output_t ret; - memcpy(ret.input_cv, input_cv, 32); - memcpy(ret.block, block, BLAKE3_BLOCK_LEN); - ret.block_len = block_len; - ret.counter = counter; - ret.flags = flags; - return ret; -} - -// Chaining values within a given chunk (specifically the compress_in_place -// interface) are represented as words. This avoids unnecessary bytes<->words -// conversion overhead in the portable implementation. However, the hash_many -// interface handles both user input and parent node blocks, so it accepts -// bytes. For that reason, chaining values in the CV stack are represented as -// bytes. -INLINE void output_chaining_value(const output_t *self, uint8_t cv[32]) { - uint32_t cv_words[8]; - memcpy(cv_words, self->input_cv, 32); - blake3_compress_in_place(cv_words, self->block, self->block_len, - self->counter, self->flags); - memcpy(cv, cv_words, 32); -} - -INLINE void output_root_bytes(const output_t *self, uint64_t seek, uint8_t *out, - size_t out_len) { - uint64_t output_block_counter = seek / 64; - size_t offset_within_block = seek % 64; - uint8_t wide_buf[64]; - while (out_len > 0) { - blake3_compress_xof(self->input_cv, self->block, self->block_len, - output_block_counter, self->flags | ROOT, wide_buf); - size_t available_bytes = 64 - offset_within_block; - size_t memcpy_len; - if (out_len > available_bytes) { - memcpy_len = available_bytes; - } else { - memcpy_len = out_len; - } - memcpy(out, wide_buf + offset_within_block, memcpy_len); - out += memcpy_len; - out_len -= memcpy_len; - output_block_counter += 1; - offset_within_block = 0; - } -} - -INLINE void chunk_state_update(blake3_chunk_state *self, const uint8_t *input, - size_t input_len) { - if (self->buf_len > 0) { - size_t take = chunk_state_fill_buf(self, input, input_len); - input += take; - input_len -= take; - if (input_len > 0) { - blake3_compress_in_place( - self->cv, self->buf, BLAKE3_BLOCK_LEN, self->chunk_counter, - self->flags | chunk_state_maybe_start_flag(self)); - self->blocks_compressed += 1; - self->buf_len = 0; - memset(self->buf, 0, BLAKE3_BLOCK_LEN); - } - } - - while (input_len > BLAKE3_BLOCK_LEN) { - blake3_compress_in_place(self->cv, input, BLAKE3_BLOCK_LEN, - self->chunk_counter, - self->flags | chunk_state_maybe_start_flag(self)); - self->blocks_compressed += 1; - input += BLAKE3_BLOCK_LEN; - input_len -= BLAKE3_BLOCK_LEN; - } - - size_t take = chunk_state_fill_buf(self, input, input_len); - input += take; - input_len -= take; -} - -INLINE output_t chunk_state_output(const blake3_chunk_state *self) { - uint8_t block_flags = - self->flags | chunk_state_maybe_start_flag(self) | CHUNK_END; - return make_output(self->cv, self->buf, self->buf_len, self->chunk_counter, - block_flags); -} - -INLINE output_t parent_output(const uint8_t block[BLAKE3_BLOCK_LEN], - const uint32_t key[8], uint8_t flags) { - return make_output(key, block, BLAKE3_BLOCK_LEN, 0, flags | PARENT); -} - -// Given some input larger than one chunk, return the number of bytes that -// should go in the left subtree. This is the largest power-of-2 number of -// chunks that leaves at least 1 byte for the right subtree. -INLINE size_t left_len(size_t content_len) { - // Subtract 1 to reserve at least one byte for the right side. content_len - // should always be greater than BLAKE3_CHUNK_LEN. - size_t full_chunks = (content_len - 1) / BLAKE3_CHUNK_LEN; - return round_down_to_power_of_2(full_chunks) * BLAKE3_CHUNK_LEN; -} - -// Use SIMD parallelism to hash up to MAX_SIMD_DEGREE chunks at the same time -// on a single thread. Write out the chunk chaining values and return the -// number of chunks hashed. These chunks are never the root and never empty; -// those cases use a different codepath. -INLINE size_t compress_chunks_parallel(const uint8_t *input, size_t input_len, - const uint32_t key[8], - uint64_t chunk_counter, uint8_t flags, - uint8_t *out) { -#if defined(BLAKE3_TESTING) - assert(0 < input_len); - assert(input_len <= MAX_SIMD_DEGREE * BLAKE3_CHUNK_LEN); -#endif - - const uint8_t *chunks_array[MAX_SIMD_DEGREE]; - size_t input_position = 0; - size_t chunks_array_len = 0; - while (input_len - input_position >= BLAKE3_CHUNK_LEN) { - chunks_array[chunks_array_len] = &input[input_position]; - input_position += BLAKE3_CHUNK_LEN; - chunks_array_len += 1; - } - - blake3_hash_many(chunks_array, chunks_array_len, - BLAKE3_CHUNK_LEN / BLAKE3_BLOCK_LEN, key, chunk_counter, - true, flags, CHUNK_START, CHUNK_END, out); - - // Hash the remaining partial chunk, if there is one. Note that the empty - // chunk (meaning the empty message) is a different codepath. - if (input_len > input_position) { - uint64_t counter = chunk_counter + (uint64_t)chunks_array_len; - blake3_chunk_state chunk_state; - chunk_state_init(&chunk_state, key, flags); - chunk_state.chunk_counter = counter; - chunk_state_update(&chunk_state, &input[input_position], - input_len - input_position); - output_t output = chunk_state_output(&chunk_state); - output_chaining_value(&output, &out[chunks_array_len * BLAKE3_OUT_LEN]); - return chunks_array_len + 1; - } else { - return chunks_array_len; - } -} - -// Use SIMD parallelism to hash up to MAX_SIMD_DEGREE parents at the same time -// on a single thread. Write out the parent chaining values and return the -// number of parents hashed. (If there's an odd input chaining value left over, -// return it as an additional output.) These parents are never the root and -// never empty; those cases use a different codepath. -INLINE size_t compress_parents_parallel(const uint8_t *child_chaining_values, - size_t num_chaining_values, - const uint32_t key[8], uint8_t flags, - uint8_t *out) { -#if defined(BLAKE3_TESTING) - assert(2 <= num_chaining_values); - assert(num_chaining_values <= 2 * MAX_SIMD_DEGREE_OR_2); -#endif - - const uint8_t *parents_array[MAX_SIMD_DEGREE_OR_2]; - size_t parents_array_len = 0; - while (num_chaining_values - (2 * parents_array_len) >= 2) { - parents_array[parents_array_len] = - &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN]; - parents_array_len += 1; - } - - blake3_hash_many(parents_array, parents_array_len, 1, key, - 0, // Parents always use counter 0. - false, flags | PARENT, - 0, // Parents have no start flags. - 0, // Parents have no end flags. - out); - - - #pragma GCC diagnostic push - #if !defined( __clang__ ) - #pragma GCC diagnostic ignored "-Wstringop-overflow" - #endif - - // If there's an odd child left over, it becomes an output. - if (num_chaining_values > 2 * parents_array_len) { - memcpy(&out[parents_array_len * BLAKE3_OUT_LEN], - &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN], - BLAKE3_OUT_LEN); - return parents_array_len + 1; - } else { - return parents_array_len; - } - #pragma GCC diagnostic pop -} - -// The wide helper function returns (writes out) an array of chaining values -// and returns the length of that array. The number of chaining values returned -// is the dyanmically detected SIMD degree, at most MAX_SIMD_DEGREE. Or fewer, -// if the input is shorter than that many chunks. The reason for maintaining a -// wide array of chaining values going back up the tree, is to allow the -// implementation to hash as many parents in parallel as possible. -// -// As a special case when the SIMD degree is 1, this function will still return -// at least 2 outputs. This guarantees that this function doesn't perform the -// root compression. (If it did, it would use the wrong flags, and also we -// wouldn't be able to implement exendable ouput.) Note that this function is -// not used when the whole input is only 1 chunk long; that's a different -// codepath. -// -// Why not just have the caller split the input on the first update(), instead -// of implementing this special rule? Because we don't want to limit SIMD or -// multi-threading parallelism for that update(). -static size_t blake3_compress_subtree_wide(const uint8_t *input, - size_t input_len, - const uint32_t key[8], - uint64_t chunk_counter, - uint8_t flags, uint8_t *out) { - // Note that the single chunk case does *not* bump the SIMD degree up to 2 - // when it is 1. If this implementation adds multi-threading in the future, - // this gives us the option of multi-threading even the 2-chunk case, which - // can help performance on smaller platforms. - if (input_len <= blake3_simd_degree() * BLAKE3_CHUNK_LEN) { - return compress_chunks_parallel(input, input_len, key, chunk_counter, flags, - out); - } - - // With more than simd_degree chunks, we need to recurse. Start by dividing - // the input into left and right subtrees. (Note that this is only optimal - // as long as the SIMD degree is a power of 2. If we ever get a SIMD degree - // of 3 or something, we'll need a more complicated strategy.) - size_t left_input_len = left_len(input_len); - size_t right_input_len = input_len - left_input_len; - const uint8_t *right_input = &input[left_input_len]; - uint64_t right_chunk_counter = - chunk_counter + (uint64_t)(left_input_len / BLAKE3_CHUNK_LEN); - - // Make space for the child outputs. Here we use MAX_SIMD_DEGREE_OR_2 to - // account for the special case of returning 2 outputs when the SIMD degree - // is 1. - uint8_t cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN]; - size_t degree = blake3_simd_degree(); - if (left_input_len > BLAKE3_CHUNK_LEN && degree == 1) { - // The special case: We always use a degree of at least two, to make - // sure there are two outputs. Except, as noted above, at the chunk - // level, where we allow degree=1. (Note that the 1-chunk-input case is - // a different codepath.) - degree = 2; - } - uint8_t *right_cvs = &cv_array[degree * BLAKE3_OUT_LEN]; - - // Recurse! If this implementation adds multi-threading support in the - // future, this is where it will go. - size_t left_n = blake3_compress_subtree_wide(input, left_input_len, key, - chunk_counter, flags, cv_array); - size_t right_n = blake3_compress_subtree_wide( - right_input, right_input_len, key, right_chunk_counter, flags, right_cvs); - - // The special case again. If simd_degree=1, then we'll have left_n=1 and - // right_n=1. Rather than compressing them into a single output, return - // them directly, to make sure we always have at least two outputs. - if (left_n == 1) { - memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN); - return 2; - } - - // Otherwise, do one layer of parent node compression. - size_t num_chaining_values = left_n + right_n; - return compress_parents_parallel(cv_array, num_chaining_values, key, flags, - out); -} - -// Hash a subtree with compress_subtree_wide(), and then condense the resulting -// list of chaining values down to a single parent node. Don't compress that -// last parent node, however. Instead, return its message bytes (the -// concatenated chaining values of its children). This is necessary when the -// first call to update() supplies a complete subtree, because the topmost -// parent node of that subtree could end up being the root. It's also necessary -// for extended output in the general case. -// -// As with compress_subtree_wide(), this function is not used on inputs of 1 -// chunk or less. That's a different codepath. -INLINE void compress_subtree_to_parent_node( - const uint8_t *input, size_t input_len, const uint32_t key[8], - uint64_t chunk_counter, uint8_t flags, uint8_t out[2 * BLAKE3_OUT_LEN]) { -#if defined(BLAKE3_TESTING) - assert(input_len > BLAKE3_CHUNK_LEN); -#endif - - uint8_t cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN]; - size_t num_cvs = blake3_compress_subtree_wide(input, input_len, key, - chunk_counter, flags, cv_array); - - // If MAX_SIMD_DEGREE is greater than 2 and there's enough input, - // compress_subtree_wide() returns more than 2 chaining values. Condense - // them into 2 by forming parent nodes repeatedly. - uint8_t out_array[MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN / 2]; - while (num_cvs > 2) { - num_cvs = - compress_parents_parallel(cv_array, num_cvs, key, flags, out_array); - memcpy(cv_array, out_array, num_cvs * BLAKE3_OUT_LEN); - } - memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN); -} - -INLINE void hasher_init_base(blake3_hasher *self, const uint32_t key[8], - uint8_t flags) { - memcpy(self->key, key, BLAKE3_KEY_LEN); - chunk_state_init(&self->chunk, key, flags); - self->cv_stack_len = 0; -} - -void blake3_hasher_init(blake3_hasher *self) { hasher_init_base(self, IV, 0); } - -void blake3_hasher_init_keyed(blake3_hasher *self, - const uint8_t key[BLAKE3_KEY_LEN]) { - uint32_t key_words[8]; - load_key_words(key, key_words); - hasher_init_base(self, key_words, KEYED_HASH); -} - -void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context) { - blake3_hasher context_hasher; - hasher_init_base(&context_hasher, IV, DERIVE_KEY_CONTEXT); - blake3_hasher_update(&context_hasher, context, strlen(context)); - uint8_t context_key[BLAKE3_KEY_LEN]; - blake3_hasher_finalize(&context_hasher, context_key, BLAKE3_KEY_LEN); - uint32_t context_key_words[8]; - load_key_words(context_key, context_key_words); - hasher_init_base(self, context_key_words, DERIVE_KEY_MATERIAL); -} - -// As described in hasher_push_cv() below, we do "lazy merging", delaying -// merges until right before the next CV is about to be added. This is -// different from the reference implementation. Another difference is that we -// aren't always merging 1 chunk at a time. Instead, each CV might represent -// any power-of-two number of chunks, as long as the smaller-above-larger stack -// order is maintained. Instead of the "count the trailing 0-bits" algorithm -// described in the spec, we use a "count the total number of 1-bits" variant -// that doesn't require us to retain the subtree size of the CV on top of the -// stack. The principle is the same: each CV that should remain in the stack is -// represented by a 1-bit in the total number of chunks (or bytes) so far. -INLINE void hasher_merge_cv_stack(blake3_hasher *self, uint64_t total_len) { - size_t post_merge_stack_len = (size_t)popcnt(total_len); - while (self->cv_stack_len > post_merge_stack_len) { - uint8_t *parent_node = - &self->cv_stack[(self->cv_stack_len - 2) * BLAKE3_OUT_LEN]; - output_t output = parent_output(parent_node, self->key, self->chunk.flags); - output_chaining_value(&output, parent_node); - self->cv_stack_len -= 1; - } -} - -// In reference_impl.rs, we merge the new CV with existing CVs from the stack -// before pushing it. We can do that because we know more input is coming, so -// we know none of the merges are root. -// -// This setting is different. We want to feed as much input as possible to -// compress_subtree_wide(), without setting aside anything for the chunk_state. -// If the user gives us 64 KiB, we want to parallelize over all 64 KiB at once -// as a single subtree, if at all possible. -// -// This leads to two problems: -// 1) This 64 KiB input might be the only call that ever gets made to update. -// In this case, the root node of the 64 KiB subtree would be the root node -// of the whole tree, and it would need to be ROOT finalized. We can't -// compress it until we know. -// 2) This 64 KiB input might complete a larger tree, whose root node is -// similarly going to be the the root of the whole tree. For example, maybe -// we have 196 KiB (that is, 128 + 64) hashed so far. We can't compress the -// node at the root of the 256 KiB subtree until we know how to finalize it. -// -// The second problem is solved with "lazy merging". That is, when we're about -// to add a CV to the stack, we don't merge it with anything first, as the -// reference impl does. Instead we do merges using the *previous* CV that was -// added, which is sitting on top of the stack, and we put the new CV -// (unmerged) on top of the stack afterwards. This guarantees that we never -// merge the root node until finalize(). -// -// Solving the first problem requires an additional tool, -// compress_subtree_to_parent_node(). That function always returns the top -// *two* chaining values of the subtree it's compressing. We then do lazy -// merging with each of them separately, so that the second CV will always -// remain unmerged. (That also helps us support extendable output when we're -// hashing an input all-at-once.) -INLINE void hasher_push_cv(blake3_hasher *self, uint8_t new_cv[BLAKE3_OUT_LEN], - uint64_t chunk_counter) { - hasher_merge_cv_stack(self, chunk_counter); - memcpy(&self->cv_stack[self->cv_stack_len * BLAKE3_OUT_LEN], new_cv, - BLAKE3_OUT_LEN); - self->cv_stack_len += 1; -} - -void blake3_hasher_update(blake3_hasher *self, const void *input, - size_t input_len) { - // Explicitly checking for zero avoids causing UB by passing a null pointer - // to memcpy. This comes up in practice with things like: - // std::vector v; - // blake3_hasher_update(&hasher, v.data(), v.size()); - if (input_len == 0) { - return; - } - - const uint8_t *input_bytes = (const uint8_t *)input; - - // If we have some partial chunk bytes in the internal chunk_state, we need - // to finish that chunk first. - if (chunk_state_len(&self->chunk) > 0) { - size_t take = BLAKE3_CHUNK_LEN - chunk_state_len(&self->chunk); - if (take > input_len) { - take = input_len; - } - chunk_state_update(&self->chunk, input_bytes, take); - input_bytes += take; - input_len -= take; - // If we've filled the current chunk and there's more coming, finalize this - // chunk and proceed. In this case we know it's not the root. - if (input_len > 0) { - output_t output = chunk_state_output(&self->chunk); - uint8_t chunk_cv[32]; - output_chaining_value(&output, chunk_cv); - hasher_push_cv(self, chunk_cv, self->chunk.chunk_counter); - chunk_state_reset(&self->chunk, self->key, self->chunk.chunk_counter + 1); - } else { - return; - } - } - - // Now the chunk_state is clear, and we have more input. If there's more than - // a single chunk (so, definitely not the root chunk), hash the largest whole - // subtree we can, with the full benefits of SIMD (and maybe in the future, - // multi-threading) parallelism. Two restrictions: - // - The subtree has to be a power-of-2 number of chunks. Only subtrees along - // the right edge can be incomplete, and we don't know where the right edge - // is going to be until we get to finalize(). - // - The subtree must evenly divide the total number of chunks up until this - // point (if total is not 0). If the current incomplete subtree is only - // waiting for 1 more chunk, we can't hash a subtree of 4 chunks. We have - // to complete the current subtree first. - // Because we might need to break up the input to form powers of 2, or to - // evenly divide what we already have, this part runs in a loop. - while (input_len > BLAKE3_CHUNK_LEN) { - size_t subtree_len = round_down_to_power_of_2(input_len); - uint64_t count_so_far = self->chunk.chunk_counter * BLAKE3_CHUNK_LEN; - // Shrink the subtree_len until it evenly divides the count so far. We know - // that subtree_len itself is a power of 2, so we can use a bitmasking - // trick instead of an actual remainder operation. (Note that if the caller - // consistently passes power-of-2 inputs of the same size, as is hopefully - // typical, this loop condition will always fail, and subtree_len will - // always be the full length of the input.) - // - // An aside: We don't have to shrink subtree_len quite this much. For - // example, if count_so_far is 1, we could pass 2 chunks to - // compress_subtree_to_parent_node. Since we'll get 2 CVs back, we'll still - // get the right answer in the end, and we might get to use 2-way SIMD - // parallelism. The problem with this optimization, is that it gets us - // stuck always hashing 2 chunks. The total number of chunks will remain - // odd, and we'll never graduate to higher degrees of parallelism. See - // https://github.com/BLAKE3-team/BLAKE3/issues/69. - while ((((uint64_t)(subtree_len - 1)) & count_so_far) != 0) { - subtree_len /= 2; - } - // The shrunken subtree_len might now be 1 chunk long. If so, hash that one - // chunk by itself. Otherwise, compress the subtree into a pair of CVs. - uint64_t subtree_chunks = subtree_len / BLAKE3_CHUNK_LEN; - if (subtree_len <= BLAKE3_CHUNK_LEN) { - blake3_chunk_state chunk_state; - chunk_state_init(&chunk_state, self->key, self->chunk.flags); - chunk_state.chunk_counter = self->chunk.chunk_counter; - chunk_state_update(&chunk_state, input_bytes, subtree_len); - output_t output = chunk_state_output(&chunk_state); - uint8_t cv[BLAKE3_OUT_LEN]; - output_chaining_value(&output, cv); - hasher_push_cv(self, cv, chunk_state.chunk_counter); - } else { - // This is the high-performance happy path, though getting here depends - // on the caller giving us a long enough input. - uint8_t cv_pair[2 * BLAKE3_OUT_LEN]; - compress_subtree_to_parent_node(input_bytes, subtree_len, self->key, - self->chunk.chunk_counter, - self->chunk.flags, cv_pair); - hasher_push_cv(self, cv_pair, self->chunk.chunk_counter); - hasher_push_cv(self, &cv_pair[BLAKE3_OUT_LEN], - self->chunk.chunk_counter + (subtree_chunks / 2)); - } - self->chunk.chunk_counter += subtree_chunks; - input_bytes += subtree_len; - input_len -= subtree_len; - } - - // If there's any remaining input less than a full chunk, add it to the chunk - // state. In that case, also do a final merge loop to make sure the subtree - // stack doesn't contain any unmerged pairs. The remaining input means we - // know these merges are non-root. This merge loop isn't strictly necessary - // here, because hasher_push_chunk_cv already does its own merge loop, but it - // simplifies blake3_hasher_finalize below. - if (input_len > 0) { - chunk_state_update(&self->chunk, input_bytes, input_len); - hasher_merge_cv_stack(self, self->chunk.chunk_counter); - } -} - -void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out, - size_t out_len) { - blake3_hasher_finalize_seek(self, 0, out, out_len); -} - -void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek, - uint8_t *out, size_t out_len) { - // Explicitly checking for zero avoids causing UB by passing a null pointer - // to memcpy. This comes up in practice with things like: - // std::vector v; - // blake3_hasher_finalize(&hasher, v.data(), v.size()); - if (out_len == 0) { - return; - } - - // If the subtree stack is empty, then the current chunk is the root. - if (self->cv_stack_len == 0) { - output_t output = chunk_state_output(&self->chunk); - output_root_bytes(&output, seek, out, out_len); - return; - } - // If there are any bytes in the chunk state, finalize that chunk and do a - // roll-up merge between that chunk hash and every subtree in the stack. In - // this case, the extra merge loop at the end of blake3_hasher_update - // guarantees that none of the subtrees in the stack need to be merged with - // each other first. Otherwise, if there are no bytes in the chunk state, - // then the top of the stack is a chunk hash, and we start the merge from - // that. - output_t output; - size_t cvs_remaining; - if (chunk_state_len(&self->chunk) > 0) { - cvs_remaining = self->cv_stack_len; - output = chunk_state_output(&self->chunk); - } else { - // There are always at least 2 CVs in the stack in this case. - cvs_remaining = self->cv_stack_len - 2; - output = parent_output(&self->cv_stack[cvs_remaining * 32], self->key, - self->chunk.flags); - } - while (cvs_remaining > 0) { - cvs_remaining -= 1; - uint8_t parent_block[BLAKE3_BLOCK_LEN]; - memcpy(parent_block, &self->cv_stack[cvs_remaining * 32], 32); - output_chaining_value(&output, &parent_block[32]); - output = parent_output(parent_block, self->key, self->chunk.flags); - } - output_root_bytes(&output, seek, out, out_len); -} +#include +#include +#include + +#include "blake3.h" +#include "blake3_impl.h" + +INLINE void chunk_state_init(blake3_chunk_state *self, const uint32_t key[8], + uint8_t flags) { + memcpy(self->cv, key, BLAKE3_KEY_LEN); + self->chunk_counter = 0; + memset(self->buf, 0, BLAKE3_BLOCK_LEN); + self->buf_len = 0; + self->blocks_compressed = 0; + self->flags = flags; +} + +INLINE void chunk_state_reset(blake3_chunk_state *self, const uint32_t key[8], + uint64_t chunk_counter) { + memcpy(self->cv, key, BLAKE3_KEY_LEN); + self->chunk_counter = chunk_counter; + self->blocks_compressed = 0; + memset(self->buf, 0, BLAKE3_BLOCK_LEN); + self->buf_len = 0; +} + +INLINE size_t chunk_state_len(const blake3_chunk_state *self) { + return (BLAKE3_BLOCK_LEN * (size_t)self->blocks_compressed) + + ((size_t)self->buf_len); +} + +INLINE size_t chunk_state_fill_buf(blake3_chunk_state *self, + const uint8_t *input, size_t input_len) { + size_t take = BLAKE3_BLOCK_LEN - ((size_t)self->buf_len); + if (take > input_len) { + take = input_len; + } + uint8_t *dest = self->buf + ((size_t)self->buf_len); + memcpy(dest, input, take); + self->buf_len += (uint8_t)take; + return take; +} + +INLINE uint8_t chunk_state_maybe_start_flag(const blake3_chunk_state *self) { + if (self->blocks_compressed == 0) { + return CHUNK_START; + } else { + return 0; + } +} + +typedef struct { + uint32_t input_cv[8]; + uint64_t counter; + uint8_t block[BLAKE3_BLOCK_LEN]; + uint8_t block_len; + uint8_t flags; +} output_t; + +INLINE output_t make_output(const uint32_t input_cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags) { + output_t ret; + memcpy(ret.input_cv, input_cv, 32); + memcpy(ret.block, block, BLAKE3_BLOCK_LEN); + ret.block_len = block_len; + ret.counter = counter; + ret.flags = flags; + return ret; +} + +// Chaining values within a given chunk (specifically the compress_in_place +// interface) are represented as words. This avoids unnecessary bytes<->words +// conversion overhead in the portable implementation. However, the hash_many +// interface handles both user input and parent node blocks, so it accepts +// bytes. For that reason, chaining values in the CV stack are represented as +// bytes. +INLINE void output_chaining_value(const output_t *self, uint8_t cv[32]) { + uint32_t cv_words[8]; + memcpy(cv_words, self->input_cv, 32); + blake3_compress_in_place(cv_words, self->block, self->block_len, + self->counter, self->flags); + memcpy(cv, cv_words, 32); +} + +INLINE void output_root_bytes(const output_t *self, uint64_t seek, uint8_t *out, + size_t out_len) { + uint64_t output_block_counter = seek / 64; + size_t offset_within_block = seek % 64; + uint8_t wide_buf[64]; + while (out_len > 0) { + blake3_compress_xof(self->input_cv, self->block, self->block_len, + output_block_counter, self->flags | ROOT, wide_buf); + size_t available_bytes = 64 - offset_within_block; + size_t memcpy_len; + if (out_len > available_bytes) { + memcpy_len = available_bytes; + } else { + memcpy_len = out_len; + } + memcpy(out, wide_buf + offset_within_block, memcpy_len); + out += memcpy_len; + out_len -= memcpy_len; + output_block_counter += 1; + offset_within_block = 0; + } +} + +INLINE void chunk_state_update(blake3_chunk_state *self, const uint8_t *input, + size_t input_len) { + if (self->buf_len > 0) { + size_t take = chunk_state_fill_buf(self, input, input_len); + input += take; + input_len -= take; + if (input_len > 0) { + blake3_compress_in_place( + self->cv, self->buf, BLAKE3_BLOCK_LEN, self->chunk_counter, + self->flags | chunk_state_maybe_start_flag(self)); + self->blocks_compressed += 1; + self->buf_len = 0; + memset(self->buf, 0, BLAKE3_BLOCK_LEN); + } + } + + while (input_len > BLAKE3_BLOCK_LEN) { + blake3_compress_in_place(self->cv, input, BLAKE3_BLOCK_LEN, + self->chunk_counter, + self->flags | chunk_state_maybe_start_flag(self)); + self->blocks_compressed += 1; + input += BLAKE3_BLOCK_LEN; + input_len -= BLAKE3_BLOCK_LEN; + } + + size_t take = chunk_state_fill_buf(self, input, input_len); + input += take; + input_len -= take; +} + +INLINE output_t chunk_state_output(const blake3_chunk_state *self) { + uint8_t block_flags = + self->flags | chunk_state_maybe_start_flag(self) | CHUNK_END; + return make_output(self->cv, self->buf, self->buf_len, self->chunk_counter, + block_flags); +} + +INLINE output_t parent_output(const uint8_t block[BLAKE3_BLOCK_LEN], + const uint32_t key[8], uint8_t flags) { + return make_output(key, block, BLAKE3_BLOCK_LEN, 0, flags | PARENT); +} + +// Given some input larger than one chunk, return the number of bytes that +// should go in the left subtree. This is the largest power-of-2 number of +// chunks that leaves at least 1 byte for the right subtree. +INLINE size_t left_len(size_t content_len) { + // Subtract 1 to reserve at least one byte for the right side. content_len + // should always be greater than BLAKE3_CHUNK_LEN. + size_t full_chunks = (content_len - 1) / BLAKE3_CHUNK_LEN; + return round_down_to_power_of_2(full_chunks) * BLAKE3_CHUNK_LEN; +} + +// Use SIMD parallelism to hash up to MAX_SIMD_DEGREE chunks at the same time +// on a single thread. Write out the chunk chaining values and return the +// number of chunks hashed. These chunks are never the root and never empty; +// those cases use a different codepath. +INLINE size_t compress_chunks_parallel(const uint8_t *input, size_t input_len, + const uint32_t key[8], + uint64_t chunk_counter, uint8_t flags, + uint8_t *out) { +#if defined(BLAKE3_TESTING) + assert(0 < input_len); + assert(input_len <= MAX_SIMD_DEGREE * BLAKE3_CHUNK_LEN); +#endif + + const uint8_t *chunks_array[MAX_SIMD_DEGREE]; + size_t input_position = 0; + size_t chunks_array_len = 0; + while (input_len - input_position >= BLAKE3_CHUNK_LEN) { + chunks_array[chunks_array_len] = &input[input_position]; + input_position += BLAKE3_CHUNK_LEN; + chunks_array_len += 1; + } + + blake3_hash_many(chunks_array, chunks_array_len, + BLAKE3_CHUNK_LEN / BLAKE3_BLOCK_LEN, key, chunk_counter, + true, flags, CHUNK_START, CHUNK_END, out); + + // Hash the remaining partial chunk, if there is one. Note that the empty + // chunk (meaning the empty message) is a different codepath. + if (input_len > input_position) { + uint64_t counter = chunk_counter + (uint64_t)chunks_array_len; + blake3_chunk_state chunk_state; + chunk_state_init(&chunk_state, key, flags); + chunk_state.chunk_counter = counter; + chunk_state_update(&chunk_state, &input[input_position], + input_len - input_position); + output_t output = chunk_state_output(&chunk_state); + output_chaining_value(&output, &out[chunks_array_len * BLAKE3_OUT_LEN]); + return chunks_array_len + 1; + } else { + return chunks_array_len; + } +} + +// Use SIMD parallelism to hash up to MAX_SIMD_DEGREE parents at the same time +// on a single thread. Write out the parent chaining values and return the +// number of parents hashed. (If there's an odd input chaining value left over, +// return it as an additional output.) These parents are never the root and +// never empty; those cases use a different codepath. +INLINE size_t compress_parents_parallel(const uint8_t *child_chaining_values, + size_t num_chaining_values, + const uint32_t key[8], uint8_t flags, + uint8_t *out) { +#if defined(BLAKE3_TESTING) + assert(2 <= num_chaining_values); + assert(num_chaining_values <= 2 * MAX_SIMD_DEGREE_OR_2); +#endif + + const uint8_t *parents_array[MAX_SIMD_DEGREE_OR_2]; + size_t parents_array_len = 0; + while (num_chaining_values - (2 * parents_array_len) >= 2) { + parents_array[parents_array_len] = + &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN]; + parents_array_len += 1; + } + + blake3_hash_many(parents_array, parents_array_len, 1, key, + 0, // Parents always use counter 0. + false, flags | PARENT, + 0, // Parents have no start flags. + 0, // Parents have no end flags. + out); + + + #pragma GCC diagnostic push + #if !defined( __clang__ ) + #pragma GCC diagnostic ignored "-Wstringop-overflow" + #endif + + // If there's an odd child left over, it becomes an output. + if (num_chaining_values > 2 * parents_array_len) { + memcpy(&out[parents_array_len * BLAKE3_OUT_LEN], + &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN], + BLAKE3_OUT_LEN); + return parents_array_len + 1; + } else { + return parents_array_len; + } + #pragma GCC diagnostic pop +} + +// The wide helper function returns (writes out) an array of chaining values +// and returns the length of that array. The number of chaining values returned +// is the dyanmically detected SIMD degree, at most MAX_SIMD_DEGREE. Or fewer, +// if the input is shorter than that many chunks. The reason for maintaining a +// wide array of chaining values going back up the tree, is to allow the +// implementation to hash as many parents in parallel as possible. +// +// As a special case when the SIMD degree is 1, this function will still return +// at least 2 outputs. This guarantees that this function doesn't perform the +// root compression. (If it did, it would use the wrong flags, and also we +// wouldn't be able to implement exendable ouput.) Note that this function is +// not used when the whole input is only 1 chunk long; that's a different +// codepath. +// +// Why not just have the caller split the input on the first update(), instead +// of implementing this special rule? Because we don't want to limit SIMD or +// multi-threading parallelism for that update(). +static size_t blake3_compress_subtree_wide(const uint8_t *input, + size_t input_len, + const uint32_t key[8], + uint64_t chunk_counter, + uint8_t flags, uint8_t *out) { + // Note that the single chunk case does *not* bump the SIMD degree up to 2 + // when it is 1. If this implementation adds multi-threading in the future, + // this gives us the option of multi-threading even the 2-chunk case, which + // can help performance on smaller platforms. + if (input_len <= blake3_simd_degree() * BLAKE3_CHUNK_LEN) { + return compress_chunks_parallel(input, input_len, key, chunk_counter, flags, + out); + } + + // With more than simd_degree chunks, we need to recurse. Start by dividing + // the input into left and right subtrees. (Note that this is only optimal + // as long as the SIMD degree is a power of 2. If we ever get a SIMD degree + // of 3 or something, we'll need a more complicated strategy.) + size_t left_input_len = left_len(input_len); + size_t right_input_len = input_len - left_input_len; + const uint8_t *right_input = &input[left_input_len]; + uint64_t right_chunk_counter = + chunk_counter + (uint64_t)(left_input_len / BLAKE3_CHUNK_LEN); + + // Make space for the child outputs. Here we use MAX_SIMD_DEGREE_OR_2 to + // account for the special case of returning 2 outputs when the SIMD degree + // is 1. + uint8_t cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN]; + size_t degree = blake3_simd_degree(); + if (left_input_len > BLAKE3_CHUNK_LEN && degree == 1) { + // The special case: We always use a degree of at least two, to make + // sure there are two outputs. Except, as noted above, at the chunk + // level, where we allow degree=1. (Note that the 1-chunk-input case is + // a different codepath.) + degree = 2; + } + uint8_t *right_cvs = &cv_array[degree * BLAKE3_OUT_LEN]; + + // Recurse! If this implementation adds multi-threading support in the + // future, this is where it will go. + size_t left_n = blake3_compress_subtree_wide(input, left_input_len, key, + chunk_counter, flags, cv_array); + size_t right_n = blake3_compress_subtree_wide( + right_input, right_input_len, key, right_chunk_counter, flags, right_cvs); + + // The special case again. If simd_degree=1, then we'll have left_n=1 and + // right_n=1. Rather than compressing them into a single output, return + // them directly, to make sure we always have at least two outputs. + if (left_n == 1) { + memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN); + return 2; + } + + // Otherwise, do one layer of parent node compression. + size_t num_chaining_values = left_n + right_n; + return compress_parents_parallel(cv_array, num_chaining_values, key, flags, + out); +} + +// Hash a subtree with compress_subtree_wide(), and then condense the resulting +// list of chaining values down to a single parent node. Don't compress that +// last parent node, however. Instead, return its message bytes (the +// concatenated chaining values of its children). This is necessary when the +// first call to update() supplies a complete subtree, because the topmost +// parent node of that subtree could end up being the root. It's also necessary +// for extended output in the general case. +// +// As with compress_subtree_wide(), this function is not used on inputs of 1 +// chunk or less. That's a different codepath. +INLINE void compress_subtree_to_parent_node( + const uint8_t *input, size_t input_len, const uint32_t key[8], + uint64_t chunk_counter, uint8_t flags, uint8_t out[2 * BLAKE3_OUT_LEN]) { +#if defined(BLAKE3_TESTING) + assert(input_len > BLAKE3_CHUNK_LEN); +#endif + + uint8_t cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN]; + size_t num_cvs = blake3_compress_subtree_wide(input, input_len, key, + chunk_counter, flags, cv_array); + + // If MAX_SIMD_DEGREE is greater than 2 and there's enough input, + // compress_subtree_wide() returns more than 2 chaining values. Condense + // them into 2 by forming parent nodes repeatedly. + uint8_t out_array[MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN / 2]; + while (num_cvs > 2) { + num_cvs = + compress_parents_parallel(cv_array, num_cvs, key, flags, out_array); + memcpy(cv_array, out_array, num_cvs * BLAKE3_OUT_LEN); + } + memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN); +} + +INLINE void hasher_init_base(blake3_hasher *self, const uint32_t key[8], + uint8_t flags) { + memcpy(self->key, key, BLAKE3_KEY_LEN); + chunk_state_init(&self->chunk, key, flags); + self->cv_stack_len = 0; +} + +void blake3_hasher_init(blake3_hasher *self) { hasher_init_base(self, IV, 0); } + +void blake3_hasher_init_keyed(blake3_hasher *self, + const uint8_t key[BLAKE3_KEY_LEN]) { + uint32_t key_words[8]; + load_key_words(key, key_words); + hasher_init_base(self, key_words, KEYED_HASH); +} + +void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context) { + blake3_hasher context_hasher; + hasher_init_base(&context_hasher, IV, DERIVE_KEY_CONTEXT); + blake3_hasher_update(&context_hasher, context, strlen(context)); + uint8_t context_key[BLAKE3_KEY_LEN]; + blake3_hasher_finalize(&context_hasher, context_key, BLAKE3_KEY_LEN); + uint32_t context_key_words[8]; + load_key_words(context_key, context_key_words); + hasher_init_base(self, context_key_words, DERIVE_KEY_MATERIAL); +} + +// As described in hasher_push_cv() below, we do "lazy merging", delaying +// merges until right before the next CV is about to be added. This is +// different from the reference implementation. Another difference is that we +// aren't always merging 1 chunk at a time. Instead, each CV might represent +// any power-of-two number of chunks, as long as the smaller-above-larger stack +// order is maintained. Instead of the "count the trailing 0-bits" algorithm +// described in the spec, we use a "count the total number of 1-bits" variant +// that doesn't require us to retain the subtree size of the CV on top of the +// stack. The principle is the same: each CV that should remain in the stack is +// represented by a 1-bit in the total number of chunks (or bytes) so far. +INLINE void hasher_merge_cv_stack(blake3_hasher *self, uint64_t total_len) { + size_t post_merge_stack_len = (size_t)popcnt(total_len); + while (self->cv_stack_len > post_merge_stack_len) { + uint8_t *parent_node = + &self->cv_stack[(self->cv_stack_len - 2) * BLAKE3_OUT_LEN]; + output_t output = parent_output(parent_node, self->key, self->chunk.flags); + output_chaining_value(&output, parent_node); + self->cv_stack_len -= 1; + } +} + +// In reference_impl.rs, we merge the new CV with existing CVs from the stack +// before pushing it. We can do that because we know more input is coming, so +// we know none of the merges are root. +// +// This setting is different. We want to feed as much input as possible to +// compress_subtree_wide(), without setting aside anything for the chunk_state. +// If the user gives us 64 KiB, we want to parallelize over all 64 KiB at once +// as a single subtree, if at all possible. +// +// This leads to two problems: +// 1) This 64 KiB input might be the only call that ever gets made to update. +// In this case, the root node of the 64 KiB subtree would be the root node +// of the whole tree, and it would need to be ROOT finalized. We can't +// compress it until we know. +// 2) This 64 KiB input might complete a larger tree, whose root node is +// similarly going to be the the root of the whole tree. For example, maybe +// we have 196 KiB (that is, 128 + 64) hashed so far. We can't compress the +// node at the root of the 256 KiB subtree until we know how to finalize it. +// +// The second problem is solved with "lazy merging". That is, when we're about +// to add a CV to the stack, we don't merge it with anything first, as the +// reference impl does. Instead we do merges using the *previous* CV that was +// added, which is sitting on top of the stack, and we put the new CV +// (unmerged) on top of the stack afterwards. This guarantees that we never +// merge the root node until finalize(). +// +// Solving the first problem requires an additional tool, +// compress_subtree_to_parent_node(). That function always returns the top +// *two* chaining values of the subtree it's compressing. We then do lazy +// merging with each of them separately, so that the second CV will always +// remain unmerged. (That also helps us support extendable output when we're +// hashing an input all-at-once.) +INLINE void hasher_push_cv(blake3_hasher *self, uint8_t new_cv[BLAKE3_OUT_LEN], + uint64_t chunk_counter) { + hasher_merge_cv_stack(self, chunk_counter); + memcpy(&self->cv_stack[self->cv_stack_len * BLAKE3_OUT_LEN], new_cv, + BLAKE3_OUT_LEN); + self->cv_stack_len += 1; +} + +void blake3_hasher_update(blake3_hasher *self, const void *input, + size_t input_len) { + // Explicitly checking for zero avoids causing UB by passing a null pointer + // to memcpy. This comes up in practice with things like: + // std::vector v; + // blake3_hasher_update(&hasher, v.data(), v.size()); + if (input_len == 0) { + return; + } + + const uint8_t *input_bytes = (const uint8_t *)input; + + // If we have some partial chunk bytes in the internal chunk_state, we need + // to finish that chunk first. + if (chunk_state_len(&self->chunk) > 0) { + size_t take = BLAKE3_CHUNK_LEN - chunk_state_len(&self->chunk); + if (take > input_len) { + take = input_len; + } + chunk_state_update(&self->chunk, input_bytes, take); + input_bytes += take; + input_len -= take; + // If we've filled the current chunk and there's more coming, finalize this + // chunk and proceed. In this case we know it's not the root. + if (input_len > 0) { + output_t output = chunk_state_output(&self->chunk); + uint8_t chunk_cv[32]; + output_chaining_value(&output, chunk_cv); + hasher_push_cv(self, chunk_cv, self->chunk.chunk_counter); + chunk_state_reset(&self->chunk, self->key, self->chunk.chunk_counter + 1); + } else { + return; + } + } + + // Now the chunk_state is clear, and we have more input. If there's more than + // a single chunk (so, definitely not the root chunk), hash the largest whole + // subtree we can, with the full benefits of SIMD (and maybe in the future, + // multi-threading) parallelism. Two restrictions: + // - The subtree has to be a power-of-2 number of chunks. Only subtrees along + // the right edge can be incomplete, and we don't know where the right edge + // is going to be until we get to finalize(). + // - The subtree must evenly divide the total number of chunks up until this + // point (if total is not 0). If the current incomplete subtree is only + // waiting for 1 more chunk, we can't hash a subtree of 4 chunks. We have + // to complete the current subtree first. + // Because we might need to break up the input to form powers of 2, or to + // evenly divide what we already have, this part runs in a loop. + while (input_len > BLAKE3_CHUNK_LEN) { + size_t subtree_len = round_down_to_power_of_2(input_len); + uint64_t count_so_far = self->chunk.chunk_counter * BLAKE3_CHUNK_LEN; + // Shrink the subtree_len until it evenly divides the count so far. We know + // that subtree_len itself is a power of 2, so we can use a bitmasking + // trick instead of an actual remainder operation. (Note that if the caller + // consistently passes power-of-2 inputs of the same size, as is hopefully + // typical, this loop condition will always fail, and subtree_len will + // always be the full length of the input.) + // + // An aside: We don't have to shrink subtree_len quite this much. For + // example, if count_so_far is 1, we could pass 2 chunks to + // compress_subtree_to_parent_node. Since we'll get 2 CVs back, we'll still + // get the right answer in the end, and we might get to use 2-way SIMD + // parallelism. The problem with this optimization, is that it gets us + // stuck always hashing 2 chunks. The total number of chunks will remain + // odd, and we'll never graduate to higher degrees of parallelism. See + // https://github.com/BLAKE3-team/BLAKE3/issues/69. + while ((((uint64_t)(subtree_len - 1)) & count_so_far) != 0) { + subtree_len /= 2; + } + // The shrunken subtree_len might now be 1 chunk long. If so, hash that one + // chunk by itself. Otherwise, compress the subtree into a pair of CVs. + uint64_t subtree_chunks = subtree_len / BLAKE3_CHUNK_LEN; + if (subtree_len <= BLAKE3_CHUNK_LEN) { + blake3_chunk_state chunk_state; + chunk_state_init(&chunk_state, self->key, self->chunk.flags); + chunk_state.chunk_counter = self->chunk.chunk_counter; + chunk_state_update(&chunk_state, input_bytes, subtree_len); + output_t output = chunk_state_output(&chunk_state); + uint8_t cv[BLAKE3_OUT_LEN]; + output_chaining_value(&output, cv); + hasher_push_cv(self, cv, chunk_state.chunk_counter); + } else { + // This is the high-performance happy path, though getting here depends + // on the caller giving us a long enough input. + uint8_t cv_pair[2 * BLAKE3_OUT_LEN]; + compress_subtree_to_parent_node(input_bytes, subtree_len, self->key, + self->chunk.chunk_counter, + self->chunk.flags, cv_pair); + hasher_push_cv(self, cv_pair, self->chunk.chunk_counter); + hasher_push_cv(self, &cv_pair[BLAKE3_OUT_LEN], + self->chunk.chunk_counter + (subtree_chunks / 2)); + } + self->chunk.chunk_counter += subtree_chunks; + input_bytes += subtree_len; + input_len -= subtree_len; + } + + // If there's any remaining input less than a full chunk, add it to the chunk + // state. In that case, also do a final merge loop to make sure the subtree + // stack doesn't contain any unmerged pairs. The remaining input means we + // know these merges are non-root. This merge loop isn't strictly necessary + // here, because hasher_push_chunk_cv already does its own merge loop, but it + // simplifies blake3_hasher_finalize below. + if (input_len > 0) { + chunk_state_update(&self->chunk, input_bytes, input_len); + hasher_merge_cv_stack(self, self->chunk.chunk_counter); + } +} + +void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out, + size_t out_len) { + blake3_hasher_finalize_seek(self, 0, out, out_len); +} + +void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek, + uint8_t *out, size_t out_len) { + // Explicitly checking for zero avoids causing UB by passing a null pointer + // to memcpy. This comes up in practice with things like: + // std::vector v; + // blake3_hasher_finalize(&hasher, v.data(), v.size()); + if (out_len == 0) { + return; + } + + // If the subtree stack is empty, then the current chunk is the root. + if (self->cv_stack_len == 0) { + output_t output = chunk_state_output(&self->chunk); + output_root_bytes(&output, seek, out, out_len); + return; + } + // If there are any bytes in the chunk state, finalize that chunk and do a + // roll-up merge between that chunk hash and every subtree in the stack. In + // this case, the extra merge loop at the end of blake3_hasher_update + // guarantees that none of the subtrees in the stack need to be merged with + // each other first. Otherwise, if there are no bytes in the chunk state, + // then the top of the stack is a chunk hash, and we start the merge from + // that. + output_t output; + size_t cvs_remaining; + if (chunk_state_len(&self->chunk) > 0) { + cvs_remaining = self->cv_stack_len; + output = chunk_state_output(&self->chunk); + } else { + // There are always at least 2 CVs in the stack in this case. + cvs_remaining = self->cv_stack_len - 2; + output = parent_output(&self->cv_stack[cvs_remaining * 32], self->key, + self->chunk.flags); + } + while (cvs_remaining > 0) { + cvs_remaining -= 1; + uint8_t parent_block[BLAKE3_BLOCK_LEN]; + memcpy(parent_block, &self->cv_stack[cvs_remaining * 32], 32); + output_chaining_value(&output, &parent_block[32]); + output = parent_output(parent_block, self->key, self->chunk.flags); + } + output_root_bytes(&output, seek, out, out_len); +} diff --git a/src/b3/blake3.h b/src/b3/blake3.h index 5060e38b..4648200e 100644 --- a/src/b3/blake3.h +++ b/src/b3/blake3.h @@ -1,56 +1,56 @@ -#ifndef BLAKE3_H -#define BLAKE3_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define BLAKE3_KEY_LEN 32 -#define BLAKE3_OUT_LEN 32 -#define BLAKE3_BLOCK_LEN 64 -#define BLAKE3_CHUNK_LEN 1024 -#define BLAKE3_MAX_DEPTH 54 -#define BLAKE3_MAX_SIMD_DEGREE 16 - -// This struct is a private implementation detail. It has to be here because -// it's part of blake3_hasher below. -typedef struct { - uint32_t cv[8]; - uint64_t chunk_counter; - uint8_t buf[BLAKE3_BLOCK_LEN]; - uint8_t buf_len; - uint8_t blocks_compressed; - uint8_t flags; -} blake3_chunk_state; - -typedef struct { - uint32_t key[8]; - blake3_chunk_state chunk; - uint8_t cv_stack_len; - // The stack size is MAX_DEPTH + 1 because we do lazy merging. For example, - // with 7 chunks, we have 3 entries in the stack. Adding an 8th chunk - // requires a 4th entry, rather than merging everything down to 1, because we - // don't know whether more input is coming. This is different from how the - // reference implementation does things. - uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN]; -} blake3_hasher; - -void blake3_hasher_init(blake3_hasher *self); -void blake3_hasher_init_keyed(blake3_hasher *self, - const uint8_t key[BLAKE3_KEY_LEN]); -void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context); -void blake3_hasher_update(blake3_hasher *self, const void *input, - size_t input_len); -void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out, - size_t out_len); -void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek, - uint8_t *out, size_t out_len); - -#ifdef __cplusplus -} -#endif - -#endif /* BLAKE3_H */ +#ifndef BLAKE3_H +#define BLAKE3_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLAKE3_KEY_LEN 32 +#define BLAKE3_OUT_LEN 32 +#define BLAKE3_BLOCK_LEN 64 +#define BLAKE3_CHUNK_LEN 1024 +#define BLAKE3_MAX_DEPTH 54 +#define BLAKE3_MAX_SIMD_DEGREE 16 + +// This struct is a private implementation detail. It has to be here because +// it's part of blake3_hasher below. +typedef struct { + uint32_t cv[8]; + uint64_t chunk_counter; + uint8_t buf[BLAKE3_BLOCK_LEN]; + uint8_t buf_len; + uint8_t blocks_compressed; + uint8_t flags; +} blake3_chunk_state; + +typedef struct { + uint32_t key[8]; + blake3_chunk_state chunk; + uint8_t cv_stack_len; + // The stack size is MAX_DEPTH + 1 because we do lazy merging. For example, + // with 7 chunks, we have 3 entries in the stack. Adding an 8th chunk + // requires a 4th entry, rather than merging everything down to 1, because we + // don't know whether more input is coming. This is different from how the + // reference implementation does things. + uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN]; +} blake3_hasher; + +void blake3_hasher_init(blake3_hasher *self); +void blake3_hasher_init_keyed(blake3_hasher *self, + const uint8_t key[BLAKE3_KEY_LEN]); +void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context); +void blake3_hasher_update(blake3_hasher *self, const void *input, + size_t input_len); +void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out, + size_t out_len); +void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek, + uint8_t *out, size_t out_len); + +#ifdef __cplusplus +} +#endif + +#endif /* BLAKE3_H */ diff --git a/src/b3/blake3_avx2.c b/src/b3/blake3_avx2.c index c5a2ce9e..ada3cb82 100644 --- a/src/b3/blake3_avx2.c +++ b/src/b3/blake3_avx2.c @@ -1,325 +1,325 @@ -#include "blake3_impl.h" - -#include - -#define DEGREE 8 - -INLINE __m256i loadu(const uint8_t src[32]) { - return _mm256_loadu_si256((const __m256i *)src); -} - -INLINE void storeu(__m256i src, uint8_t dest[16]) { - _mm256_storeu_si256((__m256i *)dest, src); -} - -INLINE __m256i addv(__m256i a, __m256i b) { return _mm256_add_epi32(a, b); } - -// Note that clang-format doesn't like the name "xor" for some reason. -INLINE __m256i xorv(__m256i a, __m256i b) { return _mm256_xor_si256(a, b); } - -INLINE __m256i set1(uint32_t x) { return _mm256_set1_epi32((int32_t)x); } - -INLINE __m256i rot16(__m256i x) { - return _mm256_shuffle_epi8( - x, _mm256_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, - 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2)); -} - -INLINE __m256i rot12(__m256i x) { - return _mm256_or_si256(_mm256_srli_epi32(x, 12), _mm256_slli_epi32(x, 32 - 12)); -} - -INLINE __m256i rot8(__m256i x) { - return _mm256_shuffle_epi8( - x, _mm256_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1, - 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1)); -} - -INLINE __m256i rot7(__m256i x) { - return _mm256_or_si256(_mm256_srli_epi32(x, 7), _mm256_slli_epi32(x, 32 - 7)); -} - -INLINE void round_fn(__m256i v[16], __m256i m[16], size_t r) { - v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); - v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); - v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); - v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); - v[0] = addv(v[0], v[4]); - v[1] = addv(v[1], v[5]); - v[2] = addv(v[2], v[6]); - v[3] = addv(v[3], v[7]); - v[12] = xorv(v[12], v[0]); - v[13] = xorv(v[13], v[1]); - v[14] = xorv(v[14], v[2]); - v[15] = xorv(v[15], v[3]); - v[12] = rot16(v[12]); - v[13] = rot16(v[13]); - v[14] = rot16(v[14]); - v[15] = rot16(v[15]); - v[8] = addv(v[8], v[12]); - v[9] = addv(v[9], v[13]); - v[10] = addv(v[10], v[14]); - v[11] = addv(v[11], v[15]); - v[4] = xorv(v[4], v[8]); - v[5] = xorv(v[5], v[9]); - v[6] = xorv(v[6], v[10]); - v[7] = xorv(v[7], v[11]); - v[4] = rot12(v[4]); - v[5] = rot12(v[5]); - v[6] = rot12(v[6]); - v[7] = rot12(v[7]); - v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); - v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); - v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); - v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); - v[0] = addv(v[0], v[4]); - v[1] = addv(v[1], v[5]); - v[2] = addv(v[2], v[6]); - v[3] = addv(v[3], v[7]); - v[12] = xorv(v[12], v[0]); - v[13] = xorv(v[13], v[1]); - v[14] = xorv(v[14], v[2]); - v[15] = xorv(v[15], v[3]); - v[12] = rot8(v[12]); - v[13] = rot8(v[13]); - v[14] = rot8(v[14]); - v[15] = rot8(v[15]); - v[8] = addv(v[8], v[12]); - v[9] = addv(v[9], v[13]); - v[10] = addv(v[10], v[14]); - v[11] = addv(v[11], v[15]); - v[4] = xorv(v[4], v[8]); - v[5] = xorv(v[5], v[9]); - v[6] = xorv(v[6], v[10]); - v[7] = xorv(v[7], v[11]); - v[4] = rot7(v[4]); - v[5] = rot7(v[5]); - v[6] = rot7(v[6]); - v[7] = rot7(v[7]); - - v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); - v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); - v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); - v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); - v[0] = addv(v[0], v[5]); - v[1] = addv(v[1], v[6]); - v[2] = addv(v[2], v[7]); - v[3] = addv(v[3], v[4]); - v[15] = xorv(v[15], v[0]); - v[12] = xorv(v[12], v[1]); - v[13] = xorv(v[13], v[2]); - v[14] = xorv(v[14], v[3]); - v[15] = rot16(v[15]); - v[12] = rot16(v[12]); - v[13] = rot16(v[13]); - v[14] = rot16(v[14]); - v[10] = addv(v[10], v[15]); - v[11] = addv(v[11], v[12]); - v[8] = addv(v[8], v[13]); - v[9] = addv(v[9], v[14]); - v[5] = xorv(v[5], v[10]); - v[6] = xorv(v[6], v[11]); - v[7] = xorv(v[7], v[8]); - v[4] = xorv(v[4], v[9]); - v[5] = rot12(v[5]); - v[6] = rot12(v[6]); - v[7] = rot12(v[7]); - v[4] = rot12(v[4]); - v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); - v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); - v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); - v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); - v[0] = addv(v[0], v[5]); - v[1] = addv(v[1], v[6]); - v[2] = addv(v[2], v[7]); - v[3] = addv(v[3], v[4]); - v[15] = xorv(v[15], v[0]); - v[12] = xorv(v[12], v[1]); - v[13] = xorv(v[13], v[2]); - v[14] = xorv(v[14], v[3]); - v[15] = rot8(v[15]); - v[12] = rot8(v[12]); - v[13] = rot8(v[13]); - v[14] = rot8(v[14]); - v[10] = addv(v[10], v[15]); - v[11] = addv(v[11], v[12]); - v[8] = addv(v[8], v[13]); - v[9] = addv(v[9], v[14]); - v[5] = xorv(v[5], v[10]); - v[6] = xorv(v[6], v[11]); - v[7] = xorv(v[7], v[8]); - v[4] = xorv(v[4], v[9]); - v[5] = rot7(v[5]); - v[6] = rot7(v[6]); - v[7] = rot7(v[7]); - v[4] = rot7(v[4]); -} - -INLINE void transpose_vecs(__m256i vecs[DEGREE]) { - // Interleave 32-bit lanes. The low unpack is lanes 00/11/44/55, and the high - // is 22/33/66/77. - __m256i ab_0145 = _mm256_unpacklo_epi32(vecs[0], vecs[1]); - __m256i ab_2367 = _mm256_unpackhi_epi32(vecs[0], vecs[1]); - __m256i cd_0145 = _mm256_unpacklo_epi32(vecs[2], vecs[3]); - __m256i cd_2367 = _mm256_unpackhi_epi32(vecs[2], vecs[3]); - __m256i ef_0145 = _mm256_unpacklo_epi32(vecs[4], vecs[5]); - __m256i ef_2367 = _mm256_unpackhi_epi32(vecs[4], vecs[5]); - __m256i gh_0145 = _mm256_unpacklo_epi32(vecs[6], vecs[7]); - __m256i gh_2367 = _mm256_unpackhi_epi32(vecs[6], vecs[7]); - - // Interleave 64-bit lates. The low unpack is lanes 00/22 and the high is - // 11/33. - __m256i abcd_04 = _mm256_unpacklo_epi64(ab_0145, cd_0145); - __m256i abcd_15 = _mm256_unpackhi_epi64(ab_0145, cd_0145); - __m256i abcd_26 = _mm256_unpacklo_epi64(ab_2367, cd_2367); - __m256i abcd_37 = _mm256_unpackhi_epi64(ab_2367, cd_2367); - __m256i efgh_04 = _mm256_unpacklo_epi64(ef_0145, gh_0145); - __m256i efgh_15 = _mm256_unpackhi_epi64(ef_0145, gh_0145); - __m256i efgh_26 = _mm256_unpacklo_epi64(ef_2367, gh_2367); - __m256i efgh_37 = _mm256_unpackhi_epi64(ef_2367, gh_2367); - - // Interleave 128-bit lanes. - vecs[0] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x20); - vecs[1] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x20); - vecs[2] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x20); - vecs[3] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x20); - vecs[4] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x31); - vecs[5] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x31); - vecs[6] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x31); - vecs[7] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x31); -} - -INLINE void transpose_msg_vecs(const uint8_t *const *inputs, - size_t block_offset, __m256i out[16]) { - out[0] = loadu(&inputs[0][block_offset + 0 * sizeof(__m256i)]); - out[1] = loadu(&inputs[1][block_offset + 0 * sizeof(__m256i)]); - out[2] = loadu(&inputs[2][block_offset + 0 * sizeof(__m256i)]); - out[3] = loadu(&inputs[3][block_offset + 0 * sizeof(__m256i)]); - out[4] = loadu(&inputs[4][block_offset + 0 * sizeof(__m256i)]); - out[5] = loadu(&inputs[5][block_offset + 0 * sizeof(__m256i)]); - out[6] = loadu(&inputs[6][block_offset + 0 * sizeof(__m256i)]); - out[7] = loadu(&inputs[7][block_offset + 0 * sizeof(__m256i)]); - out[8] = loadu(&inputs[0][block_offset + 1 * sizeof(__m256i)]); - out[9] = loadu(&inputs[1][block_offset + 1 * sizeof(__m256i)]); - out[10] = loadu(&inputs[2][block_offset + 1 * sizeof(__m256i)]); - out[11] = loadu(&inputs[3][block_offset + 1 * sizeof(__m256i)]); - out[12] = loadu(&inputs[4][block_offset + 1 * sizeof(__m256i)]); - out[13] = loadu(&inputs[5][block_offset + 1 * sizeof(__m256i)]); - out[14] = loadu(&inputs[6][block_offset + 1 * sizeof(__m256i)]); - out[15] = loadu(&inputs[7][block_offset + 1 * sizeof(__m256i)]); - for (size_t i = 0; i < 8; ++i) { - _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); - } - transpose_vecs(&out[0]); - transpose_vecs(&out[8]); -} - -INLINE void load_counters(uint64_t counter, bool increment_counter, - __m256i *out_lo, __m256i *out_hi) { - const __m256i mask = _mm256_set1_epi32(-(int32_t)increment_counter); - const __m256i add0 = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); - const __m256i add1 = _mm256_and_si256(mask, add0); - __m256i l = _mm256_add_epi32(_mm256_set1_epi32(counter), add1); - __m256i carry = _mm256_cmpgt_epi32(_mm256_xor_si256(add1, _mm256_set1_epi32(0x80000000)), - _mm256_xor_si256( l, _mm256_set1_epi32(0x80000000))); - __m256i h = _mm256_sub_epi32(_mm256_set1_epi32(counter >> 32), carry); - *out_lo = l; - *out_hi = h; -} - -void blake3_hash8_avx2(const uint8_t *const *inputs, size_t blocks, - const uint32_t key[8], uint64_t counter, - bool increment_counter, uint8_t flags, - uint8_t flags_start, uint8_t flags_end, uint8_t *out) { - __m256i h_vecs[8] = { - set1(key[0]), set1(key[1]), set1(key[2]), set1(key[3]), - set1(key[4]), set1(key[5]), set1(key[6]), set1(key[7]), - }; - __m256i counter_low_vec, counter_high_vec; - load_counters(counter, increment_counter, &counter_low_vec, - &counter_high_vec); - uint8_t block_flags = flags | flags_start; - - for (size_t block = 0; block < blocks; block++) { - if (block + 1 == blocks) { - block_flags |= flags_end; - } - __m256i block_len_vec = set1(BLAKE3_BLOCK_LEN); - __m256i block_flags_vec = set1(block_flags); - __m256i msg_vecs[16]; - transpose_msg_vecs(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); - - __m256i v[16] = { - h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], - h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], - set1(IV[0]), set1(IV[1]), set1(IV[2]), set1(IV[3]), - counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, - }; - round_fn(v, msg_vecs, 0); - round_fn(v, msg_vecs, 1); - round_fn(v, msg_vecs, 2); - round_fn(v, msg_vecs, 3); - round_fn(v, msg_vecs, 4); - round_fn(v, msg_vecs, 5); - round_fn(v, msg_vecs, 6); - h_vecs[0] = xorv(v[0], v[8]); - h_vecs[1] = xorv(v[1], v[9]); - h_vecs[2] = xorv(v[2], v[10]); - h_vecs[3] = xorv(v[3], v[11]); - h_vecs[4] = xorv(v[4], v[12]); - h_vecs[5] = xorv(v[5], v[13]); - h_vecs[6] = xorv(v[6], v[14]); - h_vecs[7] = xorv(v[7], v[15]); - - block_flags = flags; - } - - transpose_vecs(h_vecs); - storeu(h_vecs[0], &out[0 * sizeof(__m256i)]); - storeu(h_vecs[1], &out[1 * sizeof(__m256i)]); - storeu(h_vecs[2], &out[2 * sizeof(__m256i)]); - storeu(h_vecs[3], &out[3 * sizeof(__m256i)]); - storeu(h_vecs[4], &out[4 * sizeof(__m256i)]); - storeu(h_vecs[5], &out[5 * sizeof(__m256i)]); - storeu(h_vecs[6], &out[6 * sizeof(__m256i)]); - storeu(h_vecs[7], &out[7 * sizeof(__m256i)]); -} - -#if !defined(BLAKE3_NO_SSE41) -void blake3_hash_many_sse41(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out); -#else -void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out); -#endif - -void blake3_hash_many_avx2(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out) { - while (num_inputs >= DEGREE) { - blake3_hash8_avx2(inputs, blocks, key, counter, increment_counter, flags, - flags_start, flags_end, out); - if (increment_counter) { - counter += DEGREE; - } - inputs += DEGREE; - num_inputs -= DEGREE; - out = &out[DEGREE * BLAKE3_OUT_LEN]; - } -#if !defined(BLAKE3_NO_SSE41) - blake3_hash_many_sse41(inputs, num_inputs, blocks, key, counter, - increment_counter, flags, flags_start, flags_end, out); -#else - blake3_hash_many_portable(inputs, num_inputs, blocks, key, counter, - increment_counter, flags, flags_start, flags_end, - out); -#endif -} +#include "blake3_impl.h" + +#include + +#define DEGREE 8 + +INLINE __m256i loadu(const uint8_t src[32]) { + return _mm256_loadu_si256((const __m256i *)src); +} + +INLINE void storeu(__m256i src, uint8_t dest[16]) { + _mm256_storeu_si256((__m256i *)dest, src); +} + +INLINE __m256i addv(__m256i a, __m256i b) { return _mm256_add_epi32(a, b); } + +// Note that clang-format doesn't like the name "xor" for some reason. +INLINE __m256i xorv(__m256i a, __m256i b) { return _mm256_xor_si256(a, b); } + +INLINE __m256i set1(uint32_t x) { return _mm256_set1_epi32((int32_t)x); } + +INLINE __m256i rot16(__m256i x) { + return _mm256_shuffle_epi8( + x, _mm256_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, + 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2)); +} + +INLINE __m256i rot12(__m256i x) { + return _mm256_or_si256(_mm256_srli_epi32(x, 12), _mm256_slli_epi32(x, 32 - 12)); +} + +INLINE __m256i rot8(__m256i x) { + return _mm256_shuffle_epi8( + x, _mm256_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1, + 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1)); +} + +INLINE __m256i rot7(__m256i x) { + return _mm256_or_si256(_mm256_srli_epi32(x, 7), _mm256_slli_epi32(x, 32 - 7)); +} + +INLINE void round_fn(__m256i v[16], __m256i m[16], size_t r) { + v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); + v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); + v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); + v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); + v[0] = addv(v[0], v[4]); + v[1] = addv(v[1], v[5]); + v[2] = addv(v[2], v[6]); + v[3] = addv(v[3], v[7]); + v[12] = xorv(v[12], v[0]); + v[13] = xorv(v[13], v[1]); + v[14] = xorv(v[14], v[2]); + v[15] = xorv(v[15], v[3]); + v[12] = rot16(v[12]); + v[13] = rot16(v[13]); + v[14] = rot16(v[14]); + v[15] = rot16(v[15]); + v[8] = addv(v[8], v[12]); + v[9] = addv(v[9], v[13]); + v[10] = addv(v[10], v[14]); + v[11] = addv(v[11], v[15]); + v[4] = xorv(v[4], v[8]); + v[5] = xorv(v[5], v[9]); + v[6] = xorv(v[6], v[10]); + v[7] = xorv(v[7], v[11]); + v[4] = rot12(v[4]); + v[5] = rot12(v[5]); + v[6] = rot12(v[6]); + v[7] = rot12(v[7]); + v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); + v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); + v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); + v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); + v[0] = addv(v[0], v[4]); + v[1] = addv(v[1], v[5]); + v[2] = addv(v[2], v[6]); + v[3] = addv(v[3], v[7]); + v[12] = xorv(v[12], v[0]); + v[13] = xorv(v[13], v[1]); + v[14] = xorv(v[14], v[2]); + v[15] = xorv(v[15], v[3]); + v[12] = rot8(v[12]); + v[13] = rot8(v[13]); + v[14] = rot8(v[14]); + v[15] = rot8(v[15]); + v[8] = addv(v[8], v[12]); + v[9] = addv(v[9], v[13]); + v[10] = addv(v[10], v[14]); + v[11] = addv(v[11], v[15]); + v[4] = xorv(v[4], v[8]); + v[5] = xorv(v[5], v[9]); + v[6] = xorv(v[6], v[10]); + v[7] = xorv(v[7], v[11]); + v[4] = rot7(v[4]); + v[5] = rot7(v[5]); + v[6] = rot7(v[6]); + v[7] = rot7(v[7]); + + v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); + v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); + v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); + v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); + v[0] = addv(v[0], v[5]); + v[1] = addv(v[1], v[6]); + v[2] = addv(v[2], v[7]); + v[3] = addv(v[3], v[4]); + v[15] = xorv(v[15], v[0]); + v[12] = xorv(v[12], v[1]); + v[13] = xorv(v[13], v[2]); + v[14] = xorv(v[14], v[3]); + v[15] = rot16(v[15]); + v[12] = rot16(v[12]); + v[13] = rot16(v[13]); + v[14] = rot16(v[14]); + v[10] = addv(v[10], v[15]); + v[11] = addv(v[11], v[12]); + v[8] = addv(v[8], v[13]); + v[9] = addv(v[9], v[14]); + v[5] = xorv(v[5], v[10]); + v[6] = xorv(v[6], v[11]); + v[7] = xorv(v[7], v[8]); + v[4] = xorv(v[4], v[9]); + v[5] = rot12(v[5]); + v[6] = rot12(v[6]); + v[7] = rot12(v[7]); + v[4] = rot12(v[4]); + v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); + v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); + v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); + v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); + v[0] = addv(v[0], v[5]); + v[1] = addv(v[1], v[6]); + v[2] = addv(v[2], v[7]); + v[3] = addv(v[3], v[4]); + v[15] = xorv(v[15], v[0]); + v[12] = xorv(v[12], v[1]); + v[13] = xorv(v[13], v[2]); + v[14] = xorv(v[14], v[3]); + v[15] = rot8(v[15]); + v[12] = rot8(v[12]); + v[13] = rot8(v[13]); + v[14] = rot8(v[14]); + v[10] = addv(v[10], v[15]); + v[11] = addv(v[11], v[12]); + v[8] = addv(v[8], v[13]); + v[9] = addv(v[9], v[14]); + v[5] = xorv(v[5], v[10]); + v[6] = xorv(v[6], v[11]); + v[7] = xorv(v[7], v[8]); + v[4] = xorv(v[4], v[9]); + v[5] = rot7(v[5]); + v[6] = rot7(v[6]); + v[7] = rot7(v[7]); + v[4] = rot7(v[4]); +} + +INLINE void transpose_vecs(__m256i vecs[DEGREE]) { + // Interleave 32-bit lanes. The low unpack is lanes 00/11/44/55, and the high + // is 22/33/66/77. + __m256i ab_0145 = _mm256_unpacklo_epi32(vecs[0], vecs[1]); + __m256i ab_2367 = _mm256_unpackhi_epi32(vecs[0], vecs[1]); + __m256i cd_0145 = _mm256_unpacklo_epi32(vecs[2], vecs[3]); + __m256i cd_2367 = _mm256_unpackhi_epi32(vecs[2], vecs[3]); + __m256i ef_0145 = _mm256_unpacklo_epi32(vecs[4], vecs[5]); + __m256i ef_2367 = _mm256_unpackhi_epi32(vecs[4], vecs[5]); + __m256i gh_0145 = _mm256_unpacklo_epi32(vecs[6], vecs[7]); + __m256i gh_2367 = _mm256_unpackhi_epi32(vecs[6], vecs[7]); + + // Interleave 64-bit lates. The low unpack is lanes 00/22 and the high is + // 11/33. + __m256i abcd_04 = _mm256_unpacklo_epi64(ab_0145, cd_0145); + __m256i abcd_15 = _mm256_unpackhi_epi64(ab_0145, cd_0145); + __m256i abcd_26 = _mm256_unpacklo_epi64(ab_2367, cd_2367); + __m256i abcd_37 = _mm256_unpackhi_epi64(ab_2367, cd_2367); + __m256i efgh_04 = _mm256_unpacklo_epi64(ef_0145, gh_0145); + __m256i efgh_15 = _mm256_unpackhi_epi64(ef_0145, gh_0145); + __m256i efgh_26 = _mm256_unpacklo_epi64(ef_2367, gh_2367); + __m256i efgh_37 = _mm256_unpackhi_epi64(ef_2367, gh_2367); + + // Interleave 128-bit lanes. + vecs[0] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x20); + vecs[1] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x20); + vecs[2] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x20); + vecs[3] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x20); + vecs[4] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x31); + vecs[5] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x31); + vecs[6] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x31); + vecs[7] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x31); +} + +INLINE void transpose_msg_vecs(const uint8_t *const *inputs, + size_t block_offset, __m256i out[16]) { + out[0] = loadu(&inputs[0][block_offset + 0 * sizeof(__m256i)]); + out[1] = loadu(&inputs[1][block_offset + 0 * sizeof(__m256i)]); + out[2] = loadu(&inputs[2][block_offset + 0 * sizeof(__m256i)]); + out[3] = loadu(&inputs[3][block_offset + 0 * sizeof(__m256i)]); + out[4] = loadu(&inputs[4][block_offset + 0 * sizeof(__m256i)]); + out[5] = loadu(&inputs[5][block_offset + 0 * sizeof(__m256i)]); + out[6] = loadu(&inputs[6][block_offset + 0 * sizeof(__m256i)]); + out[7] = loadu(&inputs[7][block_offset + 0 * sizeof(__m256i)]); + out[8] = loadu(&inputs[0][block_offset + 1 * sizeof(__m256i)]); + out[9] = loadu(&inputs[1][block_offset + 1 * sizeof(__m256i)]); + out[10] = loadu(&inputs[2][block_offset + 1 * sizeof(__m256i)]); + out[11] = loadu(&inputs[3][block_offset + 1 * sizeof(__m256i)]); + out[12] = loadu(&inputs[4][block_offset + 1 * sizeof(__m256i)]); + out[13] = loadu(&inputs[5][block_offset + 1 * sizeof(__m256i)]); + out[14] = loadu(&inputs[6][block_offset + 1 * sizeof(__m256i)]); + out[15] = loadu(&inputs[7][block_offset + 1 * sizeof(__m256i)]); + for (size_t i = 0; i < 8; ++i) { + _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); + } + transpose_vecs(&out[0]); + transpose_vecs(&out[8]); +} + +INLINE void load_counters(uint64_t counter, bool increment_counter, + __m256i *out_lo, __m256i *out_hi) { + const __m256i mask = _mm256_set1_epi32(-(int32_t)increment_counter); + const __m256i add0 = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); + const __m256i add1 = _mm256_and_si256(mask, add0); + __m256i l = _mm256_add_epi32(_mm256_set1_epi32(counter), add1); + __m256i carry = _mm256_cmpgt_epi32(_mm256_xor_si256(add1, _mm256_set1_epi32(0x80000000)), + _mm256_xor_si256( l, _mm256_set1_epi32(0x80000000))); + __m256i h = _mm256_sub_epi32(_mm256_set1_epi32(counter >> 32), carry); + *out_lo = l; + *out_hi = h; +} + +void blake3_hash8_avx2(const uint8_t *const *inputs, size_t blocks, + const uint32_t key[8], uint64_t counter, + bool increment_counter, uint8_t flags, + uint8_t flags_start, uint8_t flags_end, uint8_t *out) { + __m256i h_vecs[8] = { + set1(key[0]), set1(key[1]), set1(key[2]), set1(key[3]), + set1(key[4]), set1(key[5]), set1(key[6]), set1(key[7]), + }; + __m256i counter_low_vec, counter_high_vec; + load_counters(counter, increment_counter, &counter_low_vec, + &counter_high_vec); + uint8_t block_flags = flags | flags_start; + + for (size_t block = 0; block < blocks; block++) { + if (block + 1 == blocks) { + block_flags |= flags_end; + } + __m256i block_len_vec = set1(BLAKE3_BLOCK_LEN); + __m256i block_flags_vec = set1(block_flags); + __m256i msg_vecs[16]; + transpose_msg_vecs(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); + + __m256i v[16] = { + h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], + h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], + set1(IV[0]), set1(IV[1]), set1(IV[2]), set1(IV[3]), + counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, + }; + round_fn(v, msg_vecs, 0); + round_fn(v, msg_vecs, 1); + round_fn(v, msg_vecs, 2); + round_fn(v, msg_vecs, 3); + round_fn(v, msg_vecs, 4); + round_fn(v, msg_vecs, 5); + round_fn(v, msg_vecs, 6); + h_vecs[0] = xorv(v[0], v[8]); + h_vecs[1] = xorv(v[1], v[9]); + h_vecs[2] = xorv(v[2], v[10]); + h_vecs[3] = xorv(v[3], v[11]); + h_vecs[4] = xorv(v[4], v[12]); + h_vecs[5] = xorv(v[5], v[13]); + h_vecs[6] = xorv(v[6], v[14]); + h_vecs[7] = xorv(v[7], v[15]); + + block_flags = flags; + } + + transpose_vecs(h_vecs); + storeu(h_vecs[0], &out[0 * sizeof(__m256i)]); + storeu(h_vecs[1], &out[1 * sizeof(__m256i)]); + storeu(h_vecs[2], &out[2 * sizeof(__m256i)]); + storeu(h_vecs[3], &out[3 * sizeof(__m256i)]); + storeu(h_vecs[4], &out[4 * sizeof(__m256i)]); + storeu(h_vecs[5], &out[5 * sizeof(__m256i)]); + storeu(h_vecs[6], &out[6 * sizeof(__m256i)]); + storeu(h_vecs[7], &out[7 * sizeof(__m256i)]); +} + +#if !defined(BLAKE3_NO_SSE41) +void blake3_hash_many_sse41(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out); +#else +void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out); +#endif + +void blake3_hash_many_avx2(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out) { + while (num_inputs >= DEGREE) { + blake3_hash8_avx2(inputs, blocks, key, counter, increment_counter, flags, + flags_start, flags_end, out); + if (increment_counter) { + counter += DEGREE; + } + inputs += DEGREE; + num_inputs -= DEGREE; + out = &out[DEGREE * BLAKE3_OUT_LEN]; + } +#if !defined(BLAKE3_NO_SSE41) + blake3_hash_many_sse41(inputs, num_inputs, blocks, key, counter, + increment_counter, flags, flags_start, flags_end, out); +#else + blake3_hash_many_portable(inputs, num_inputs, blocks, key, counter, + increment_counter, flags, flags_start, flags_end, + out); +#endif +} diff --git a/src/b3/blake3_avx2_x86-64_unix.S b/src/b3/blake3_avx2_x86-64_unix.S index d2b14d44..a9ea84e7 100644 --- a/src/b3/blake3_avx2_x86-64_unix.S +++ b/src/b3/blake3_avx2_x86-64_unix.S @@ -1,1802 +1,1802 @@ -#ifdef __x86_64__ -.intel_syntax noprefix -.global _blake3_hash_many_avx2 -.global blake3_hash_many_avx2 -#ifdef __APPLE__ -.text -#else -.section .text -#endif - .p2align 6 -_blake3_hash_many_avx2: -blake3_hash_many_avx2: - push r15 - push r14 - push r13 - push r12 - push rbx - push rbp - mov rbp, rsp - sub rsp, 680 - and rsp, 0xFFFFFFFFFFFFFFC0 - neg r9d - vmovd xmm0, r9d - vpbroadcastd ymm0, xmm0 - vmovdqa ymmword ptr [rsp+0x280], ymm0 - vpand ymm1, ymm0, ymmword ptr [ADD0+rip] - vpand ymm2, ymm0, ymmword ptr [ADD1+rip] - vmovdqa ymmword ptr [rsp+0x220], ymm2 - vmovd xmm2, r8d - vpbroadcastd ymm2, xmm2 - vpaddd ymm2, ymm2, ymm1 - vmovdqa ymmword ptr [rsp+0x240], ymm2 - vpxor ymm1, ymm1, ymmword ptr [CMP_MSB_MASK+rip] - vpxor ymm2, ymm2, ymmword ptr [CMP_MSB_MASK+rip] - vpcmpgtd ymm2, ymm1, ymm2 - shr r8, 32 - vmovd xmm3, r8d - vpbroadcastd ymm3, xmm3 - vpsubd ymm3, ymm3, ymm2 - vmovdqa ymmword ptr [rsp+0x260], ymm3 - shl rdx, 6 - mov qword ptr [rsp+0x2A0], rdx - cmp rsi, 8 - jc 3f -2: - vpbroadcastd ymm0, dword ptr [rcx] - vpbroadcastd ymm1, dword ptr [rcx+0x4] - vpbroadcastd ymm2, dword ptr [rcx+0x8] - vpbroadcastd ymm3, dword ptr [rcx+0xC] - vpbroadcastd ymm4, dword ptr [rcx+0x10] - vpbroadcastd ymm5, dword ptr [rcx+0x14] - vpbroadcastd ymm6, dword ptr [rcx+0x18] - vpbroadcastd ymm7, dword ptr [rcx+0x1C] - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - mov r10, qword ptr [rdi+0x10] - mov r11, qword ptr [rdi+0x18] - mov r12, qword ptr [rdi+0x20] - mov r13, qword ptr [rdi+0x28] - mov r14, qword ptr [rdi+0x30] - mov r15, qword ptr [rdi+0x38] - movzx eax, byte ptr [rbp+0x38] - movzx ebx, byte ptr [rbp+0x40] - or eax, ebx - xor edx, edx -.p2align 5 -9: - movzx ebx, byte ptr [rbp+0x48] - or ebx, eax - add rdx, 64 - cmp rdx, qword ptr [rsp+0x2A0] - cmove eax, ebx - mov dword ptr [rsp+0x200], eax - vmovups xmm8, xmmword ptr [r8+rdx-0x40] - vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x40], 0x01 - vmovups xmm9, xmmword ptr [r9+rdx-0x40] - vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x40], 0x01 - vunpcklpd ymm12, ymm8, ymm9 - vunpckhpd ymm13, ymm8, ymm9 - vmovups xmm10, xmmword ptr [r10+rdx-0x40] - vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x40], 0x01 - vmovups xmm11, xmmword ptr [r11+rdx-0x40] - vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x40], 0x01 - vunpcklpd ymm14, ymm10, ymm11 - vunpckhpd ymm15, ymm10, ymm11 - vshufps ymm8, ymm12, ymm14, 136 - vmovaps ymmword ptr [rsp], ymm8 - vshufps ymm9, ymm12, ymm14, 221 - vmovaps ymmword ptr [rsp+0x20], ymm9 - vshufps ymm10, ymm13, ymm15, 136 - vmovaps ymmword ptr [rsp+0x40], ymm10 - vshufps ymm11, ymm13, ymm15, 221 - vmovaps ymmword ptr [rsp+0x60], ymm11 - vmovups xmm8, xmmword ptr [r8+rdx-0x30] - vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x30], 0x01 - vmovups xmm9, xmmword ptr [r9+rdx-0x30] - vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x30], 0x01 - vunpcklpd ymm12, ymm8, ymm9 - vunpckhpd ymm13, ymm8, ymm9 - vmovups xmm10, xmmword ptr [r10+rdx-0x30] - vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x30], 0x01 - vmovups xmm11, xmmword ptr [r11+rdx-0x30] - vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x30], 0x01 - vunpcklpd ymm14, ymm10, ymm11 - vunpckhpd ymm15, ymm10, ymm11 - vshufps ymm8, ymm12, ymm14, 136 - vmovaps ymmword ptr [rsp+0x80], ymm8 - vshufps ymm9, ymm12, ymm14, 221 - vmovaps ymmword ptr [rsp+0xA0], ymm9 - vshufps ymm10, ymm13, ymm15, 136 - vmovaps ymmword ptr [rsp+0xC0], ymm10 - vshufps ymm11, ymm13, ymm15, 221 - vmovaps ymmword ptr [rsp+0xE0], ymm11 - vmovups xmm8, xmmword ptr [r8+rdx-0x20] - vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x20], 0x01 - vmovups xmm9, xmmword ptr [r9+rdx-0x20] - vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x20], 0x01 - vunpcklpd ymm12, ymm8, ymm9 - vunpckhpd ymm13, ymm8, ymm9 - vmovups xmm10, xmmword ptr [r10+rdx-0x20] - vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x20], 0x01 - vmovups xmm11, xmmword ptr [r11+rdx-0x20] - vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x20], 0x01 - vunpcklpd ymm14, ymm10, ymm11 - vunpckhpd ymm15, ymm10, ymm11 - vshufps ymm8, ymm12, ymm14, 136 - vmovaps ymmword ptr [rsp+0x100], ymm8 - vshufps ymm9, ymm12, ymm14, 221 - vmovaps ymmword ptr [rsp+0x120], ymm9 - vshufps ymm10, ymm13, ymm15, 136 - vmovaps ymmword ptr [rsp+0x140], ymm10 - vshufps ymm11, ymm13, ymm15, 221 - vmovaps ymmword ptr [rsp+0x160], ymm11 - vmovups xmm8, xmmword ptr [r8+rdx-0x10] - vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x10], 0x01 - vmovups xmm9, xmmword ptr [r9+rdx-0x10] - vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x10], 0x01 - vunpcklpd ymm12, ymm8, ymm9 - vunpckhpd ymm13, ymm8, ymm9 - vmovups xmm10, xmmword ptr [r10+rdx-0x10] - vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x10], 0x01 - vmovups xmm11, xmmword ptr [r11+rdx-0x10] - vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x10], 0x01 - vunpcklpd ymm14, ymm10, ymm11 - vunpckhpd ymm15, ymm10, ymm11 - vshufps ymm8, ymm12, ymm14, 136 - vmovaps ymmword ptr [rsp+0x180], ymm8 - vshufps ymm9, ymm12, ymm14, 221 - vmovaps ymmword ptr [rsp+0x1A0], ymm9 - vshufps ymm10, ymm13, ymm15, 136 - vmovaps ymmword ptr [rsp+0x1C0], ymm10 - vshufps ymm11, ymm13, ymm15, 221 - vmovaps ymmword ptr [rsp+0x1E0], ymm11 - vpbroadcastd ymm15, dword ptr [rsp+0x200] - prefetcht0 [r8+rdx+0x80] - prefetcht0 [r12+rdx+0x80] - prefetcht0 [r9+rdx+0x80] - prefetcht0 [r13+rdx+0x80] - prefetcht0 [r10+rdx+0x80] - prefetcht0 [r14+rdx+0x80] - prefetcht0 [r11+rdx+0x80] - prefetcht0 [r15+rdx+0x80] - vpaddd ymm0, ymm0, ymmword ptr [rsp] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x40] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x80] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0xC0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm0, ymmword ptr [rsp+0x240] - vpxor ymm13, ymm1, ymmword ptr [rsp+0x260] - vpxor ymm14, ymm2, ymmword ptr [BLAKE3_BLOCK_LEN+rip] - vpxor ymm15, ymm3, ymm15 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [BLAKE3_IV_0+rip] - vpaddd ymm9, ymm13, ymmword ptr [BLAKE3_IV_1+rip] - vpaddd ymm10, ymm14, ymmword ptr [BLAKE3_IV_2+rip] - vpaddd ymm11, ymm15, ymmword ptr [BLAKE3_IV_3+rip] - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x20] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x60] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0xA0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0xE0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x100] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x140] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x180] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1C0] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x120] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x160] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1A0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1E0] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x40] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x60] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0xE0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x80] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0xC0] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x140] - vpaddd ymm2, ymm2, ymmword ptr [rsp] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1A0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x20] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x180] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x120] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1E0] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x160] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0xA0] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1C0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x100] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x60] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x140] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1A0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0xE0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x80] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x180] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x40] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1C0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0xC0] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x120] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x160] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x100] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0xA0] - vpaddd ymm1, ymm1, ymmword ptr [rsp] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1E0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x20] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x140] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x180] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1C0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1A0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0xE0] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x120] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x60] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1E0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x80] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x160] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0xA0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x20] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x40] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x100] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0xC0] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x180] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x120] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1E0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1C0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1A0] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x160] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x140] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x100] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0xE0] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0xA0] - vpaddd ymm2, ymm2, ymmword ptr [rsp] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0xC0] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x40] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x60] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x20] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x80] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x120] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x160] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x100] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1E0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1C0] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0xA0] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x180] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x20] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1A0] - vpaddd ymm1, ymm1, ymmword ptr [rsp] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x40] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x80] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x60] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x140] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0xC0] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0xE0] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x160] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0xA0] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x20] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x100] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1E0] - vpaddd ymm1, ymm1, ymmword ptr [rsp] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x120] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0xC0] - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxor ymm12, ymm12, ymm0 - vpxor ymm13, ymm13, ymm1 - vpxor ymm14, ymm14, ymm2 - vpxor ymm15, ymm15, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpshufb ymm15, ymm15, ymm8 - vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxor ymm4, ymm4, ymm8 - vpxor ymm5, ymm5, ymm9 - vpxor ymm6, ymm6, ymm10 - vpxor ymm7, ymm7, ymm11 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1C0] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x40] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x60] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0xE0] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vmovdqa ymmword ptr [rsp+0x200], ymm8 - vpsrld ymm8, ymm5, 12 - vpslld ymm5, ymm5, 20 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 12 - vpslld ymm6, ymm6, 20 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 12 - vpslld ymm7, ymm7, 20 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 12 - vpslld ymm4, ymm4, 20 - vpor ymm4, ymm4, ymm8 - vpaddd ymm0, ymm0, ymmword ptr [rsp+0x140] - vpaddd ymm1, ymm1, ymmword ptr [rsp+0x180] - vpaddd ymm2, ymm2, ymmword ptr [rsp+0x80] - vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1A0] - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxor ymm15, ymm15, ymm0 - vpxor ymm12, ymm12, ymm1 - vpxor ymm13, ymm13, ymm2 - vpxor ymm14, ymm14, ymm3 - vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] - vpshufb ymm15, ymm15, ymm8 - vpshufb ymm12, ymm12, ymm8 - vpshufb ymm13, ymm13, ymm8 - vpshufb ymm14, ymm14, ymm8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] - vpaddd ymm9, ymm9, ymm14 - vpxor ymm5, ymm5, ymm10 - vpxor ymm6, ymm6, ymm11 - vpxor ymm7, ymm7, ymm8 - vpxor ymm4, ymm4, ymm9 - vpxor ymm0, ymm0, ymm8 - vpxor ymm1, ymm1, ymm9 - vpxor ymm2, ymm2, ymm10 - vpxor ymm3, ymm3, ymm11 - vpsrld ymm8, ymm5, 7 - vpslld ymm5, ymm5, 25 - vpor ymm5, ymm5, ymm8 - vpsrld ymm8, ymm6, 7 - vpslld ymm6, ymm6, 25 - vpor ymm6, ymm6, ymm8 - vpsrld ymm8, ymm7, 7 - vpslld ymm7, ymm7, 25 - vpor ymm7, ymm7, ymm8 - vpsrld ymm8, ymm4, 7 - vpslld ymm4, ymm4, 25 - vpor ymm4, ymm4, ymm8 - vpxor ymm4, ymm4, ymm12 - vpxor ymm5, ymm5, ymm13 - vpxor ymm6, ymm6, ymm14 - vpxor ymm7, ymm7, ymm15 - movzx eax, byte ptr [rbp+0x38] - jne 9b - mov rbx, qword ptr [rbp+0x50] - vunpcklps ymm8, ymm0, ymm1 - vunpcklps ymm9, ymm2, ymm3 - vunpckhps ymm10, ymm0, ymm1 - vunpcklps ymm11, ymm4, ymm5 - vunpcklps ymm0, ymm6, ymm7 - vshufps ymm12, ymm8, ymm9, 78 - vblendps ymm1, ymm8, ymm12, 0xCC - vshufps ymm8, ymm11, ymm0, 78 - vunpckhps ymm13, ymm2, ymm3 - vblendps ymm2, ymm11, ymm8, 0xCC - vblendps ymm3, ymm12, ymm9, 0xCC - vperm2f128 ymm12, ymm1, ymm2, 0x20 - vmovups ymmword ptr [rbx], ymm12 - vunpckhps ymm14, ymm4, ymm5 - vblendps ymm4, ymm8, ymm0, 0xCC - vunpckhps ymm15, ymm6, ymm7 - vperm2f128 ymm7, ymm3, ymm4, 0x20 - vmovups ymmword ptr [rbx+0x20], ymm7 - vshufps ymm5, ymm10, ymm13, 78 - vblendps ymm6, ymm5, ymm13, 0xCC - vshufps ymm13, ymm14, ymm15, 78 - vblendps ymm10, ymm10, ymm5, 0xCC - vblendps ymm14, ymm14, ymm13, 0xCC - vperm2f128 ymm8, ymm10, ymm14, 0x20 - vmovups ymmword ptr [rbx+0x40], ymm8 - vblendps ymm15, ymm13, ymm15, 0xCC - vperm2f128 ymm13, ymm6, ymm15, 0x20 - vmovups ymmword ptr [rbx+0x60], ymm13 - vperm2f128 ymm9, ymm1, ymm2, 0x31 - vperm2f128 ymm11, ymm3, ymm4, 0x31 - vmovups ymmword ptr [rbx+0x80], ymm9 - vperm2f128 ymm14, ymm10, ymm14, 0x31 - vperm2f128 ymm15, ymm6, ymm15, 0x31 - vmovups ymmword ptr [rbx+0xA0], ymm11 - vmovups ymmword ptr [rbx+0xC0], ymm14 - vmovups ymmword ptr [rbx+0xE0], ymm15 - vmovdqa ymm0, ymmword ptr [rsp+0x220] - vpaddd ymm1, ymm0, ymmword ptr [rsp+0x240] - vmovdqa ymmword ptr [rsp+0x240], ymm1 - vpxor ymm0, ymm0, ymmword ptr [CMP_MSB_MASK+rip] - vpxor ymm2, ymm1, ymmword ptr [CMP_MSB_MASK+rip] - vpcmpgtd ymm2, ymm0, ymm2 - vmovdqa ymm0, ymmword ptr [rsp+0x260] - vpsubd ymm2, ymm0, ymm2 - vmovdqa ymmword ptr [rsp+0x260], ymm2 - add rdi, 64 - add rbx, 256 - mov qword ptr [rbp+0x50], rbx - sub rsi, 8 - cmp rsi, 8 - jnc 2b - test rsi, rsi - jnz 3f -4: - vzeroupper - mov rsp, rbp - pop rbp - pop rbx - pop r12 - pop r13 - pop r14 - pop r15 - ret -.p2align 5 -3: - mov rbx, qword ptr [rbp+0x50] - mov r15, qword ptr [rsp+0x2A0] - movzx r13d, byte ptr [rbp+0x38] - movzx r12d, byte ptr [rbp+0x48] - test rsi, 0x4 - je 3f - vbroadcasti128 ymm0, xmmword ptr [rcx] - vbroadcasti128 ymm1, xmmword ptr [rcx+0x10] - vmovdqa ymm8, ymm0 - vmovdqa ymm9, ymm1 - vbroadcasti128 ymm12, xmmword ptr [rsp+0x240] - vbroadcasti128 ymm13, xmmword ptr [rsp+0x260] - vpunpckldq ymm14, ymm12, ymm13 - vpunpckhdq ymm15, ymm12, ymm13 - vpermq ymm14, ymm14, 0x50 - vpermq ymm15, ymm15, 0x50 - vbroadcasti128 ymm12, xmmword ptr [BLAKE3_BLOCK_LEN+rip] - vpblendd ymm14, ymm14, ymm12, 0x44 - vpblendd ymm15, ymm15, ymm12, 0x44 - vmovdqa ymmword ptr [rsp], ymm14 - vmovdqa ymmword ptr [rsp+0x20], ymm15 - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - mov r10, qword ptr [rdi+0x10] - mov r11, qword ptr [rdi+0x18] - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -.p2align 5 -2: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - mov dword ptr [rsp+0x200], eax - vmovups ymm2, ymmword ptr [r8+rdx-0x40] - vinsertf128 ymm2, ymm2, xmmword ptr [r9+rdx-0x40], 0x01 - vmovups ymm3, ymmword ptr [r8+rdx-0x30] - vinsertf128 ymm3, ymm3, xmmword ptr [r9+rdx-0x30], 0x01 - vshufps ymm4, ymm2, ymm3, 136 - vshufps ymm5, ymm2, ymm3, 221 - vmovups ymm2, ymmword ptr [r8+rdx-0x20] - vinsertf128 ymm2, ymm2, xmmword ptr [r9+rdx-0x20], 0x01 - vmovups ymm3, ymmword ptr [r8+rdx-0x10] - vinsertf128 ymm3, ymm3, xmmword ptr [r9+rdx-0x10], 0x01 - vshufps ymm6, ymm2, ymm3, 136 - vshufps ymm7, ymm2, ymm3, 221 - vpshufd ymm6, ymm6, 0x93 - vpshufd ymm7, ymm7, 0x93 - vmovups ymm10, ymmword ptr [r10+rdx-0x40] - vinsertf128 ymm10, ymm10, xmmword ptr [r11+rdx-0x40], 0x01 - vmovups ymm11, ymmword ptr [r10+rdx-0x30] - vinsertf128 ymm11, ymm11, xmmword ptr [r11+rdx-0x30], 0x01 - vshufps ymm12, ymm10, ymm11, 136 - vshufps ymm13, ymm10, ymm11, 221 - vmovups ymm10, ymmword ptr [r10+rdx-0x20] - vinsertf128 ymm10, ymm10, xmmword ptr [r11+rdx-0x20], 0x01 - vmovups ymm11, ymmword ptr [r10+rdx-0x10] - vinsertf128 ymm11, ymm11, xmmword ptr [r11+rdx-0x10], 0x01 - vshufps ymm14, ymm10, ymm11, 136 - vshufps ymm15, ymm10, ymm11, 221 - vpshufd ymm14, ymm14, 0x93 - vpshufd ymm15, ymm15, 0x93 - prefetcht0 [r8+rdx+0x80] - prefetcht0 [r9+rdx+0x80] - prefetcht0 [r10+rdx+0x80] - prefetcht0 [r11+rdx+0x80] - vpbroadcastd ymm2, dword ptr [rsp+0x200] - vmovdqa ymm3, ymmword ptr [rsp] - vmovdqa ymm11, ymmword ptr [rsp+0x20] - vpblendd ymm3, ymm3, ymm2, 0x88 - vpblendd ymm11, ymm11, ymm2, 0x88 - vbroadcasti128 ymm2, xmmword ptr [BLAKE3_IV+rip] - vmovdqa ymm10, ymm2 - mov al, 7 -9: - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm8, ymm8, ymm12 - vmovdqa ymmword ptr [rsp+0x40], ymm4 - nop - vmovdqa ymmword ptr [rsp+0x60], ymm12 - nop - vpaddd ymm0, ymm0, ymm1 - vpaddd ymm8, ymm8, ymm9 - vpxor ymm3, ymm3, ymm0 - vpxor ymm11, ymm11, ymm8 - vbroadcasti128 ymm4, xmmword ptr [ROT16+rip] - vpshufb ymm3, ymm3, ymm4 - vpshufb ymm11, ymm11, ymm4 - vpaddd ymm2, ymm2, ymm3 - vpaddd ymm10, ymm10, ymm11 - vpxor ymm1, ymm1, ymm2 - vpxor ymm9, ymm9, ymm10 - vpsrld ymm4, ymm1, 12 - vpslld ymm1, ymm1, 20 - vpor ymm1, ymm1, ymm4 - vpsrld ymm4, ymm9, 12 - vpslld ymm9, ymm9, 20 - vpor ymm9, ymm9, ymm4 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm0, ymm0, ymm1 - vpaddd ymm8, ymm8, ymm9 - vmovdqa ymmword ptr [rsp+0x80], ymm5 - vmovdqa ymmword ptr [rsp+0xA0], ymm13 - vpxor ymm3, ymm3, ymm0 - vpxor ymm11, ymm11, ymm8 - vbroadcasti128 ymm4, xmmword ptr [ROT8+rip] - vpshufb ymm3, ymm3, ymm4 - vpshufb ymm11, ymm11, ymm4 - vpaddd ymm2, ymm2, ymm3 - vpaddd ymm10, ymm10, ymm11 - vpxor ymm1, ymm1, ymm2 - vpxor ymm9, ymm9, ymm10 - vpsrld ymm4, ymm1, 7 - vpslld ymm1, ymm1, 25 - vpor ymm1, ymm1, ymm4 - vpsrld ymm4, ymm9, 7 - vpslld ymm9, ymm9, 25 - vpor ymm9, ymm9, ymm4 - vpshufd ymm0, ymm0, 0x93 - vpshufd ymm8, ymm8, 0x93 - vpshufd ymm3, ymm3, 0x4E - vpshufd ymm11, ymm11, 0x4E - vpshufd ymm2, ymm2, 0x39 - vpshufd ymm10, ymm10, 0x39 - vpaddd ymm0, ymm0, ymm6 - vpaddd ymm8, ymm8, ymm14 - vpaddd ymm0, ymm0, ymm1 - vpaddd ymm8, ymm8, ymm9 - vpxor ymm3, ymm3, ymm0 - vpxor ymm11, ymm11, ymm8 - vbroadcasti128 ymm4, xmmword ptr [ROT16+rip] - vpshufb ymm3, ymm3, ymm4 - vpshufb ymm11, ymm11, ymm4 - vpaddd ymm2, ymm2, ymm3 - vpaddd ymm10, ymm10, ymm11 - vpxor ymm1, ymm1, ymm2 - vpxor ymm9, ymm9, ymm10 - vpsrld ymm4, ymm1, 12 - vpslld ymm1, ymm1, 20 - vpor ymm1, ymm1, ymm4 - vpsrld ymm4, ymm9, 12 - vpslld ymm9, ymm9, 20 - vpor ymm9, ymm9, ymm4 - vpaddd ymm0, ymm0, ymm7 - vpaddd ymm8, ymm8, ymm15 - vpaddd ymm0, ymm0, ymm1 - vpaddd ymm8, ymm8, ymm9 - vpxor ymm3, ymm3, ymm0 - vpxor ymm11, ymm11, ymm8 - vbroadcasti128 ymm4, xmmword ptr [ROT8+rip] - vpshufb ymm3, ymm3, ymm4 - vpshufb ymm11, ymm11, ymm4 - vpaddd ymm2, ymm2, ymm3 - vpaddd ymm10, ymm10, ymm11 - vpxor ymm1, ymm1, ymm2 - vpxor ymm9, ymm9, ymm10 - vpsrld ymm4, ymm1, 7 - vpslld ymm1, ymm1, 25 - vpor ymm1, ymm1, ymm4 - vpsrld ymm4, ymm9, 7 - vpslld ymm9, ymm9, 25 - vpor ymm9, ymm9, ymm4 - vpshufd ymm0, ymm0, 0x39 - vpshufd ymm8, ymm8, 0x39 - vpshufd ymm3, ymm3, 0x4E - vpshufd ymm11, ymm11, 0x4E - vpshufd ymm2, ymm2, 0x93 - vpshufd ymm10, ymm10, 0x93 - dec al - je 9f - vmovdqa ymm4, ymmword ptr [rsp+0x40] - vmovdqa ymm5, ymmword ptr [rsp+0x80] - vshufps ymm12, ymm4, ymm5, 214 - vpshufd ymm13, ymm4, 0x0F - vpshufd ymm4, ymm12, 0x39 - vshufps ymm12, ymm6, ymm7, 250 - vpblendd ymm13, ymm13, ymm12, 0xAA - vpunpcklqdq ymm12, ymm7, ymm5 - vpblendd ymm12, ymm12, ymm6, 0x88 - vpshufd ymm12, ymm12, 0x78 - vpunpckhdq ymm5, ymm5, ymm7 - vpunpckldq ymm6, ymm6, ymm5 - vpshufd ymm7, ymm6, 0x1E - vmovdqa ymmword ptr [rsp+0x40], ymm13 - vmovdqa ymmword ptr [rsp+0x80], ymm12 - vmovdqa ymm12, ymmword ptr [rsp+0x60] - vmovdqa ymm13, ymmword ptr [rsp+0xA0] - vshufps ymm5, ymm12, ymm13, 214 - vpshufd ymm6, ymm12, 0x0F - vpshufd ymm12, ymm5, 0x39 - vshufps ymm5, ymm14, ymm15, 250 - vpblendd ymm6, ymm6, ymm5, 0xAA - vpunpcklqdq ymm5, ymm15, ymm13 - vpblendd ymm5, ymm5, ymm14, 0x88 - vpshufd ymm5, ymm5, 0x78 - vpunpckhdq ymm13, ymm13, ymm15 - vpunpckldq ymm14, ymm14, ymm13 - vpshufd ymm15, ymm14, 0x1E - vmovdqa ymm13, ymm6 - vmovdqa ymm14, ymm5 - vmovdqa ymm5, ymmword ptr [rsp+0x40] - vmovdqa ymm6, ymmword ptr [rsp+0x80] - jmp 9b -9: - vpxor ymm0, ymm0, ymm2 - vpxor ymm1, ymm1, ymm3 - vpxor ymm8, ymm8, ymm10 - vpxor ymm9, ymm9, ymm11 - mov eax, r13d - cmp rdx, r15 - jne 2b - vmovdqu xmmword ptr [rbx], xmm0 - vmovdqu xmmword ptr [rbx+0x10], xmm1 - vextracti128 xmmword ptr [rbx+0x20], ymm0, 0x01 - vextracti128 xmmword ptr [rbx+0x30], ymm1, 0x01 - vmovdqu xmmword ptr [rbx+0x40], xmm8 - vmovdqu xmmword ptr [rbx+0x50], xmm9 - vextracti128 xmmword ptr [rbx+0x60], ymm8, 0x01 - vextracti128 xmmword ptr [rbx+0x70], ymm9, 0x01 - vmovaps xmm8, xmmword ptr [rsp+0x280] - vmovaps xmm0, xmmword ptr [rsp+0x240] - vmovaps xmm1, xmmword ptr [rsp+0x250] - vmovaps xmm2, xmmword ptr [rsp+0x260] - vmovaps xmm3, xmmword ptr [rsp+0x270] - vblendvps xmm0, xmm0, xmm1, xmm8 - vblendvps xmm2, xmm2, xmm3, xmm8 - vmovaps xmmword ptr [rsp+0x240], xmm0 - vmovaps xmmword ptr [rsp+0x260], xmm2 - add rbx, 128 - add rdi, 32 - sub rsi, 4 -3: - test rsi, 0x2 - je 3f - vbroadcasti128 ymm0, xmmword ptr [rcx] - vbroadcasti128 ymm1, xmmword ptr [rcx+0x10] - vmovd xmm13, dword ptr [rsp+0x240] - vpinsrd xmm13, xmm13, dword ptr [rsp+0x260], 1 - vpinsrd xmm13, xmm13, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - vmovd xmm14, dword ptr [rsp+0x244] - vpinsrd xmm14, xmm14, dword ptr [rsp+0x264], 1 - vpinsrd xmm14, xmm14, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - vinserti128 ymm13, ymm13, xmm14, 0x01 - vbroadcasti128 ymm14, xmmword ptr [ROT16+rip] - vbroadcasti128 ymm15, xmmword ptr [ROT8+rip] - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -.p2align 5 -2: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - mov dword ptr [rsp+0x200], eax - vbroadcasti128 ymm2, xmmword ptr [BLAKE3_IV+rip] - vpbroadcastd ymm8, dword ptr [rsp+0x200] - vpblendd ymm3, ymm13, ymm8, 0x88 - vmovups ymm8, ymmword ptr [r8+rdx-0x40] - vinsertf128 ymm8, ymm8, xmmword ptr [r9+rdx-0x40], 0x01 - vmovups ymm9, ymmword ptr [r8+rdx-0x30] - vinsertf128 ymm9, ymm9, xmmword ptr [r9+rdx-0x30], 0x01 - vshufps ymm4, ymm8, ymm9, 136 - vshufps ymm5, ymm8, ymm9, 221 - vmovups ymm8, ymmword ptr [r8+rdx-0x20] - vinsertf128 ymm8, ymm8, xmmword ptr [r9+rdx-0x20], 0x01 - vmovups ymm9, ymmword ptr [r8+rdx-0x10] - vinsertf128 ymm9, ymm9, xmmword ptr [r9+rdx-0x10], 0x01 - vshufps ymm6, ymm8, ymm9, 136 - vshufps ymm7, ymm8, ymm9, 221 - vpshufd ymm6, ymm6, 0x93 - vpshufd ymm7, ymm7, 0x93 - mov al, 7 -9: - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm0, ymm0, ymm1 - vpxor ymm3, ymm3, ymm0 - vpshufb ymm3, ymm3, ymm14 - vpaddd ymm2, ymm2, ymm3 - vpxor ymm1, ymm1, ymm2 - vpsrld ymm8, ymm1, 12 - vpslld ymm1, ymm1, 20 - vpor ymm1, ymm1, ymm8 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm0, ymm0, ymm1 - vpxor ymm3, ymm3, ymm0 - vpshufb ymm3, ymm3, ymm15 - vpaddd ymm2, ymm2, ymm3 - vpxor ymm1, ymm1, ymm2 - vpsrld ymm8, ymm1, 7 - vpslld ymm1, ymm1, 25 - vpor ymm1, ymm1, ymm8 - vpshufd ymm0, ymm0, 0x93 - vpshufd ymm3, ymm3, 0x4E - vpshufd ymm2, ymm2, 0x39 - vpaddd ymm0, ymm0, ymm6 - vpaddd ymm0, ymm0, ymm1 - vpxor ymm3, ymm3, ymm0 - vpshufb ymm3, ymm3, ymm14 - vpaddd ymm2, ymm2, ymm3 - vpxor ymm1, ymm1, ymm2 - vpsrld ymm8, ymm1, 12 - vpslld ymm1, ymm1, 20 - vpor ymm1, ymm1, ymm8 - vpaddd ymm0, ymm0, ymm7 - vpaddd ymm0, ymm0, ymm1 - vpxor ymm3, ymm3, ymm0 - vpshufb ymm3, ymm3, ymm15 - vpaddd ymm2, ymm2, ymm3 - vpxor ymm1, ymm1, ymm2 - vpsrld ymm8, ymm1, 7 - vpslld ymm1, ymm1, 25 - vpor ymm1, ymm1, ymm8 - vpshufd ymm0, ymm0, 0x39 - vpshufd ymm3, ymm3, 0x4E - vpshufd ymm2, ymm2, 0x93 - dec al - jz 9f - vshufps ymm8, ymm4, ymm5, 214 - vpshufd ymm9, ymm4, 0x0F - vpshufd ymm4, ymm8, 0x39 - vshufps ymm8, ymm6, ymm7, 250 - vpblendd ymm9, ymm9, ymm8, 0xAA - vpunpcklqdq ymm8, ymm7, ymm5 - vpblendd ymm8, ymm8, ymm6, 0x88 - vpshufd ymm8, ymm8, 0x78 - vpunpckhdq ymm5, ymm5, ymm7 - vpunpckldq ymm6, ymm6, ymm5 - vpshufd ymm7, ymm6, 0x1E - vmovdqa ymm5, ymm9 - vmovdqa ymm6, ymm8 - jmp 9b -9: - vpxor ymm0, ymm0, ymm2 - vpxor ymm1, ymm1, ymm3 - mov eax, r13d - cmp rdx, r15 - jne 2b - vmovdqu xmmword ptr [rbx], xmm0 - vmovdqu xmmword ptr [rbx+0x10], xmm1 - vextracti128 xmmword ptr [rbx+0x20], ymm0, 0x01 - vextracti128 xmmword ptr [rbx+0x30], ymm1, 0x01 - vmovaps ymm8, ymmword ptr [rsp+0x280] - vmovaps ymm0, ymmword ptr [rsp+0x240] - vmovups ymm1, ymmword ptr [rsp+0x248] - vmovaps ymm2, ymmword ptr [rsp+0x260] - vmovups ymm3, ymmword ptr [rsp+0x268] - vblendvps ymm0, ymm0, ymm1, ymm8 - vblendvps ymm2, ymm2, ymm3, ymm8 - vmovaps ymmword ptr [rsp+0x240], ymm0 - vmovaps ymmword ptr [rsp+0x260], ymm2 - add rbx, 64 - add rdi, 16 - sub rsi, 2 -3: - test rsi, 0x1 - je 4b - vmovdqu xmm0, xmmword ptr [rcx] - vmovdqu xmm1, xmmword ptr [rcx+0x10] - vmovd xmm3, dword ptr [rsp+0x240] - vpinsrd xmm3, xmm3, dword ptr [rsp+0x260], 1 - vpinsrd xmm13, xmm3, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - vmovdqa xmm14, xmmword ptr [ROT16+rip] - vmovdqa xmm15, xmmword ptr [ROT8+rip] - mov r8, qword ptr [rdi] - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -.p2align 5 -2: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - vmovdqa xmm2, xmmword ptr [BLAKE3_IV+rip] - vmovdqa xmm3, xmm13 - vpinsrd xmm3, xmm3, eax, 3 - vmovups xmm8, xmmword ptr [r8+rdx-0x40] - vmovups xmm9, xmmword ptr [r8+rdx-0x30] - vshufps xmm4, xmm8, xmm9, 136 - vshufps xmm5, xmm8, xmm9, 221 - vmovups xmm8, xmmword ptr [r8+rdx-0x20] - vmovups xmm9, xmmword ptr [r8+rdx-0x10] - vshufps xmm6, xmm8, xmm9, 136 - vshufps xmm7, xmm8, xmm9, 221 - vpshufd xmm6, xmm6, 0x93 - vpshufd xmm7, xmm7, 0x93 - mov al, 7 -9: - vpaddd xmm0, xmm0, xmm4 - vpaddd xmm0, xmm0, xmm1 - vpxor xmm3, xmm3, xmm0 - vpshufb xmm3, xmm3, xmm14 - vpaddd xmm2, xmm2, xmm3 - vpxor xmm1, xmm1, xmm2 - vpsrld xmm8, xmm1, 12 - vpslld xmm1, xmm1, 20 - vpor xmm1, xmm1, xmm8 - vpaddd xmm0, xmm0, xmm5 - vpaddd xmm0, xmm0, xmm1 - vpxor xmm3, xmm3, xmm0 - vpshufb xmm3, xmm3, xmm15 - vpaddd xmm2, xmm2, xmm3 - vpxor xmm1, xmm1, xmm2 - vpsrld xmm8, xmm1, 7 - vpslld xmm1, xmm1, 25 - vpor xmm1, xmm1, xmm8 - vpshufd xmm0, xmm0, 0x93 - vpshufd xmm3, xmm3, 0x4E - vpshufd xmm2, xmm2, 0x39 - vpaddd xmm0, xmm0, xmm6 - vpaddd xmm0, xmm0, xmm1 - vpxor xmm3, xmm3, xmm0 - vpshufb xmm3, xmm3, xmm14 - vpaddd xmm2, xmm2, xmm3 - vpxor xmm1, xmm1, xmm2 - vpsrld xmm8, xmm1, 12 - vpslld xmm1, xmm1, 20 - vpor xmm1, xmm1, xmm8 - vpaddd xmm0, xmm0, xmm7 - vpaddd xmm0, xmm0, xmm1 - vpxor xmm3, xmm3, xmm0 - vpshufb xmm3, xmm3, xmm15 - vpaddd xmm2, xmm2, xmm3 - vpxor xmm1, xmm1, xmm2 - vpsrld xmm8, xmm1, 7 - vpslld xmm1, xmm1, 25 - vpor xmm1, xmm1, xmm8 - vpshufd xmm0, xmm0, 0x39 - vpshufd xmm3, xmm3, 0x4E - vpshufd xmm2, xmm2, 0x93 - dec al - jz 9f - vshufps xmm8, xmm4, xmm5, 214 - vpshufd xmm9, xmm4, 0x0F - vpshufd xmm4, xmm8, 0x39 - vshufps xmm8, xmm6, xmm7, 250 - vpblendd xmm9, xmm9, xmm8, 0xAA - vpunpcklqdq xmm8, xmm7, xmm5 - vpblendd xmm8, xmm8, xmm6, 0x88 - vpshufd xmm8, xmm8, 0x78 - vpunpckhdq xmm5, xmm5, xmm7 - vpunpckldq xmm6, xmm6, xmm5 - vpshufd xmm7, xmm6, 0x1E - vmovdqa xmm5, xmm9 - vmovdqa xmm6, xmm8 - jmp 9b -9: - vpxor xmm0, xmm0, xmm2 - vpxor xmm1, xmm1, xmm3 - mov eax, r13d - cmp rdx, r15 - jne 2b - vmovdqu xmmword ptr [rbx], xmm0 - vmovdqu xmmword ptr [rbx+0x10], xmm1 - jmp 4b - - -#ifdef __APPLE__ -.static_data -#else -.section .rodata -#endif -.p2align 6 -ADD0: - .long 0, 1, 2, 3, 4, 5, 6, 7 -ADD1: - .long 8, 8, 8, 8, 8, 8, 8, 8 -BLAKE3_IV_0: - .long 0x6A09E667, 0x6A09E667, 0x6A09E667, 0x6A09E667 - .long 0x6A09E667, 0x6A09E667, 0x6A09E667, 0x6A09E667 -BLAKE3_IV_1: - .long 0xBB67AE85, 0xBB67AE85, 0xBB67AE85, 0xBB67AE85 - .long 0xBB67AE85, 0xBB67AE85, 0xBB67AE85, 0xBB67AE85 -BLAKE3_IV_2: - .long 0x3C6EF372, 0x3C6EF372, 0x3C6EF372, 0x3C6EF372 - .long 0x3C6EF372, 0x3C6EF372, 0x3C6EF372, 0x3C6EF372 -BLAKE3_IV_3: - .long 0xA54FF53A, 0xA54FF53A, 0xA54FF53A, 0xA54FF53A - .long 0xA54FF53A, 0xA54FF53A, 0xA54FF53A, 0xA54FF53A -BLAKE3_BLOCK_LEN: - .long 0x00000040, 0x00000040, 0x00000040, 0x00000040 - .long 0x00000040, 0x00000040, 0x00000040, 0x00000040 -ROT16: - .byte 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13 -ROT8: - .byte 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12 -CMP_MSB_MASK: - .long 0x80000000, 0x80000000, 0x80000000, 0x80000000 - .long 0x80000000, 0x80000000, 0x80000000, 0x80000000 -BLAKE3_IV: - .long 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A - -#endif // __x86_64__ +#ifdef __x86_64__ +.intel_syntax noprefix +.global _blake3_hash_many_avx2 +.global blake3_hash_many_avx2 +#ifdef __APPLE__ +.text +#else +.section .text +#endif + .p2align 6 +_blake3_hash_many_avx2: +blake3_hash_many_avx2: + push r15 + push r14 + push r13 + push r12 + push rbx + push rbp + mov rbp, rsp + sub rsp, 680 + and rsp, 0xFFFFFFFFFFFFFFC0 + neg r9d + vmovd xmm0, r9d + vpbroadcastd ymm0, xmm0 + vmovdqa ymmword ptr [rsp+0x280], ymm0 + vpand ymm1, ymm0, ymmword ptr [ADD0+rip] + vpand ymm2, ymm0, ymmword ptr [ADD1+rip] + vmovdqa ymmword ptr [rsp+0x220], ymm2 + vmovd xmm2, r8d + vpbroadcastd ymm2, xmm2 + vpaddd ymm2, ymm2, ymm1 + vmovdqa ymmword ptr [rsp+0x240], ymm2 + vpxor ymm1, ymm1, ymmword ptr [CMP_MSB_MASK+rip] + vpxor ymm2, ymm2, ymmword ptr [CMP_MSB_MASK+rip] + vpcmpgtd ymm2, ymm1, ymm2 + shr r8, 32 + vmovd xmm3, r8d + vpbroadcastd ymm3, xmm3 + vpsubd ymm3, ymm3, ymm2 + vmovdqa ymmword ptr [rsp+0x260], ymm3 + shl rdx, 6 + mov qword ptr [rsp+0x2A0], rdx + cmp rsi, 8 + jc 3f +2: + vpbroadcastd ymm0, dword ptr [rcx] + vpbroadcastd ymm1, dword ptr [rcx+0x4] + vpbroadcastd ymm2, dword ptr [rcx+0x8] + vpbroadcastd ymm3, dword ptr [rcx+0xC] + vpbroadcastd ymm4, dword ptr [rcx+0x10] + vpbroadcastd ymm5, dword ptr [rcx+0x14] + vpbroadcastd ymm6, dword ptr [rcx+0x18] + vpbroadcastd ymm7, dword ptr [rcx+0x1C] + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + mov r10, qword ptr [rdi+0x10] + mov r11, qword ptr [rdi+0x18] + mov r12, qword ptr [rdi+0x20] + mov r13, qword ptr [rdi+0x28] + mov r14, qword ptr [rdi+0x30] + mov r15, qword ptr [rdi+0x38] + movzx eax, byte ptr [rbp+0x38] + movzx ebx, byte ptr [rbp+0x40] + or eax, ebx + xor edx, edx +.p2align 5 +9: + movzx ebx, byte ptr [rbp+0x48] + or ebx, eax + add rdx, 64 + cmp rdx, qword ptr [rsp+0x2A0] + cmove eax, ebx + mov dword ptr [rsp+0x200], eax + vmovups xmm8, xmmword ptr [r8+rdx-0x40] + vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x40], 0x01 + vmovups xmm9, xmmword ptr [r9+rdx-0x40] + vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x40], 0x01 + vunpcklpd ymm12, ymm8, ymm9 + vunpckhpd ymm13, ymm8, ymm9 + vmovups xmm10, xmmword ptr [r10+rdx-0x40] + vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x40], 0x01 + vmovups xmm11, xmmword ptr [r11+rdx-0x40] + vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x40], 0x01 + vunpcklpd ymm14, ymm10, ymm11 + vunpckhpd ymm15, ymm10, ymm11 + vshufps ymm8, ymm12, ymm14, 136 + vmovaps ymmword ptr [rsp], ymm8 + vshufps ymm9, ymm12, ymm14, 221 + vmovaps ymmword ptr [rsp+0x20], ymm9 + vshufps ymm10, ymm13, ymm15, 136 + vmovaps ymmword ptr [rsp+0x40], ymm10 + vshufps ymm11, ymm13, ymm15, 221 + vmovaps ymmword ptr [rsp+0x60], ymm11 + vmovups xmm8, xmmword ptr [r8+rdx-0x30] + vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x30], 0x01 + vmovups xmm9, xmmword ptr [r9+rdx-0x30] + vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x30], 0x01 + vunpcklpd ymm12, ymm8, ymm9 + vunpckhpd ymm13, ymm8, ymm9 + vmovups xmm10, xmmword ptr [r10+rdx-0x30] + vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x30], 0x01 + vmovups xmm11, xmmword ptr [r11+rdx-0x30] + vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x30], 0x01 + vunpcklpd ymm14, ymm10, ymm11 + vunpckhpd ymm15, ymm10, ymm11 + vshufps ymm8, ymm12, ymm14, 136 + vmovaps ymmword ptr [rsp+0x80], ymm8 + vshufps ymm9, ymm12, ymm14, 221 + vmovaps ymmword ptr [rsp+0xA0], ymm9 + vshufps ymm10, ymm13, ymm15, 136 + vmovaps ymmword ptr [rsp+0xC0], ymm10 + vshufps ymm11, ymm13, ymm15, 221 + vmovaps ymmword ptr [rsp+0xE0], ymm11 + vmovups xmm8, xmmword ptr [r8+rdx-0x20] + vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x20], 0x01 + vmovups xmm9, xmmword ptr [r9+rdx-0x20] + vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x20], 0x01 + vunpcklpd ymm12, ymm8, ymm9 + vunpckhpd ymm13, ymm8, ymm9 + vmovups xmm10, xmmword ptr [r10+rdx-0x20] + vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x20], 0x01 + vmovups xmm11, xmmword ptr [r11+rdx-0x20] + vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x20], 0x01 + vunpcklpd ymm14, ymm10, ymm11 + vunpckhpd ymm15, ymm10, ymm11 + vshufps ymm8, ymm12, ymm14, 136 + vmovaps ymmword ptr [rsp+0x100], ymm8 + vshufps ymm9, ymm12, ymm14, 221 + vmovaps ymmword ptr [rsp+0x120], ymm9 + vshufps ymm10, ymm13, ymm15, 136 + vmovaps ymmword ptr [rsp+0x140], ymm10 + vshufps ymm11, ymm13, ymm15, 221 + vmovaps ymmword ptr [rsp+0x160], ymm11 + vmovups xmm8, xmmword ptr [r8+rdx-0x10] + vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x10], 0x01 + vmovups xmm9, xmmword ptr [r9+rdx-0x10] + vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x10], 0x01 + vunpcklpd ymm12, ymm8, ymm9 + vunpckhpd ymm13, ymm8, ymm9 + vmovups xmm10, xmmword ptr [r10+rdx-0x10] + vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x10], 0x01 + vmovups xmm11, xmmword ptr [r11+rdx-0x10] + vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x10], 0x01 + vunpcklpd ymm14, ymm10, ymm11 + vunpckhpd ymm15, ymm10, ymm11 + vshufps ymm8, ymm12, ymm14, 136 + vmovaps ymmword ptr [rsp+0x180], ymm8 + vshufps ymm9, ymm12, ymm14, 221 + vmovaps ymmword ptr [rsp+0x1A0], ymm9 + vshufps ymm10, ymm13, ymm15, 136 + vmovaps ymmword ptr [rsp+0x1C0], ymm10 + vshufps ymm11, ymm13, ymm15, 221 + vmovaps ymmword ptr [rsp+0x1E0], ymm11 + vpbroadcastd ymm15, dword ptr [rsp+0x200] + prefetcht0 [r8+rdx+0x80] + prefetcht0 [r12+rdx+0x80] + prefetcht0 [r9+rdx+0x80] + prefetcht0 [r13+rdx+0x80] + prefetcht0 [r10+rdx+0x80] + prefetcht0 [r14+rdx+0x80] + prefetcht0 [r11+rdx+0x80] + prefetcht0 [r15+rdx+0x80] + vpaddd ymm0, ymm0, ymmword ptr [rsp] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x40] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x80] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0xC0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm0, ymmword ptr [rsp+0x240] + vpxor ymm13, ymm1, ymmword ptr [rsp+0x260] + vpxor ymm14, ymm2, ymmword ptr [BLAKE3_BLOCK_LEN+rip] + vpxor ymm15, ymm3, ymm15 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [BLAKE3_IV_0+rip] + vpaddd ymm9, ymm13, ymmword ptr [BLAKE3_IV_1+rip] + vpaddd ymm10, ymm14, ymmword ptr [BLAKE3_IV_2+rip] + vpaddd ymm11, ymm15, ymmword ptr [BLAKE3_IV_3+rip] + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x20] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x60] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0xA0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0xE0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x100] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x140] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x180] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1C0] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x120] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x160] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1A0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1E0] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x40] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x60] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0xE0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x80] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0xC0] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x140] + vpaddd ymm2, ymm2, ymmword ptr [rsp] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1A0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x20] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x180] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x120] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1E0] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x160] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0xA0] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1C0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x100] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x60] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x140] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1A0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0xE0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x80] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x180] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x40] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1C0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0xC0] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x120] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x160] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x100] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0xA0] + vpaddd ymm1, ymm1, ymmword ptr [rsp] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1E0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x20] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x140] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x180] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1C0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1A0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0xE0] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x120] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x60] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1E0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x80] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x160] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0xA0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x20] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x40] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x100] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0xC0] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x180] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x120] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x1E0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1C0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1A0] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x160] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x140] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x100] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0xE0] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0xA0] + vpaddd ymm2, ymm2, ymmword ptr [rsp] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0xC0] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x40] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x60] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x20] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x80] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x120] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x160] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x100] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1E0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1C0] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0xA0] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x180] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x20] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1A0] + vpaddd ymm1, ymm1, ymmword ptr [rsp] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x40] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x80] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x60] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x140] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0xC0] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0xE0] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x160] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0xA0] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x20] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x100] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1E0] + vpaddd ymm1, ymm1, ymmword ptr [rsp] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x120] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0xC0] + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxor ymm12, ymm12, ymm0 + vpxor ymm13, ymm13, ymm1 + vpxor ymm14, ymm14, ymm2 + vpxor ymm15, ymm15, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpshufb ymm15, ymm15, ymm8 + vpaddd ymm8, ymm12, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxor ymm4, ymm4, ymm8 + vpxor ymm5, ymm5, ymm9 + vpxor ymm6, ymm6, ymm10 + vpxor ymm7, ymm7, ymm11 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x1C0] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x40] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x60] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0xE0] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT16+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vmovdqa ymmword ptr [rsp+0x200], ymm8 + vpsrld ymm8, ymm5, 12 + vpslld ymm5, ymm5, 20 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 12 + vpslld ymm6, ymm6, 20 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 12 + vpslld ymm7, ymm7, 20 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 12 + vpslld ymm4, ymm4, 20 + vpor ymm4, ymm4, ymm8 + vpaddd ymm0, ymm0, ymmword ptr [rsp+0x140] + vpaddd ymm1, ymm1, ymmword ptr [rsp+0x180] + vpaddd ymm2, ymm2, ymmword ptr [rsp+0x80] + vpaddd ymm3, ymm3, ymmword ptr [rsp+0x1A0] + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxor ymm15, ymm15, ymm0 + vpxor ymm12, ymm12, ymm1 + vpxor ymm13, ymm13, ymm2 + vpxor ymm14, ymm14, ymm3 + vbroadcasti128 ymm8, xmmword ptr [ROT8+rip] + vpshufb ymm15, ymm15, ymm8 + vpshufb ymm12, ymm12, ymm8 + vpshufb ymm13, ymm13, ymm8 + vpshufb ymm14, ymm14, ymm8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm13, ymmword ptr [rsp+0x200] + vpaddd ymm9, ymm9, ymm14 + vpxor ymm5, ymm5, ymm10 + vpxor ymm6, ymm6, ymm11 + vpxor ymm7, ymm7, ymm8 + vpxor ymm4, ymm4, ymm9 + vpxor ymm0, ymm0, ymm8 + vpxor ymm1, ymm1, ymm9 + vpxor ymm2, ymm2, ymm10 + vpxor ymm3, ymm3, ymm11 + vpsrld ymm8, ymm5, 7 + vpslld ymm5, ymm5, 25 + vpor ymm5, ymm5, ymm8 + vpsrld ymm8, ymm6, 7 + vpslld ymm6, ymm6, 25 + vpor ymm6, ymm6, ymm8 + vpsrld ymm8, ymm7, 7 + vpslld ymm7, ymm7, 25 + vpor ymm7, ymm7, ymm8 + vpsrld ymm8, ymm4, 7 + vpslld ymm4, ymm4, 25 + vpor ymm4, ymm4, ymm8 + vpxor ymm4, ymm4, ymm12 + vpxor ymm5, ymm5, ymm13 + vpxor ymm6, ymm6, ymm14 + vpxor ymm7, ymm7, ymm15 + movzx eax, byte ptr [rbp+0x38] + jne 9b + mov rbx, qword ptr [rbp+0x50] + vunpcklps ymm8, ymm0, ymm1 + vunpcklps ymm9, ymm2, ymm3 + vunpckhps ymm10, ymm0, ymm1 + vunpcklps ymm11, ymm4, ymm5 + vunpcklps ymm0, ymm6, ymm7 + vshufps ymm12, ymm8, ymm9, 78 + vblendps ymm1, ymm8, ymm12, 0xCC + vshufps ymm8, ymm11, ymm0, 78 + vunpckhps ymm13, ymm2, ymm3 + vblendps ymm2, ymm11, ymm8, 0xCC + vblendps ymm3, ymm12, ymm9, 0xCC + vperm2f128 ymm12, ymm1, ymm2, 0x20 + vmovups ymmword ptr [rbx], ymm12 + vunpckhps ymm14, ymm4, ymm5 + vblendps ymm4, ymm8, ymm0, 0xCC + vunpckhps ymm15, ymm6, ymm7 + vperm2f128 ymm7, ymm3, ymm4, 0x20 + vmovups ymmword ptr [rbx+0x20], ymm7 + vshufps ymm5, ymm10, ymm13, 78 + vblendps ymm6, ymm5, ymm13, 0xCC + vshufps ymm13, ymm14, ymm15, 78 + vblendps ymm10, ymm10, ymm5, 0xCC + vblendps ymm14, ymm14, ymm13, 0xCC + vperm2f128 ymm8, ymm10, ymm14, 0x20 + vmovups ymmword ptr [rbx+0x40], ymm8 + vblendps ymm15, ymm13, ymm15, 0xCC + vperm2f128 ymm13, ymm6, ymm15, 0x20 + vmovups ymmword ptr [rbx+0x60], ymm13 + vperm2f128 ymm9, ymm1, ymm2, 0x31 + vperm2f128 ymm11, ymm3, ymm4, 0x31 + vmovups ymmword ptr [rbx+0x80], ymm9 + vperm2f128 ymm14, ymm10, ymm14, 0x31 + vperm2f128 ymm15, ymm6, ymm15, 0x31 + vmovups ymmword ptr [rbx+0xA0], ymm11 + vmovups ymmword ptr [rbx+0xC0], ymm14 + vmovups ymmword ptr [rbx+0xE0], ymm15 + vmovdqa ymm0, ymmword ptr [rsp+0x220] + vpaddd ymm1, ymm0, ymmword ptr [rsp+0x240] + vmovdqa ymmword ptr [rsp+0x240], ymm1 + vpxor ymm0, ymm0, ymmword ptr [CMP_MSB_MASK+rip] + vpxor ymm2, ymm1, ymmword ptr [CMP_MSB_MASK+rip] + vpcmpgtd ymm2, ymm0, ymm2 + vmovdqa ymm0, ymmword ptr [rsp+0x260] + vpsubd ymm2, ymm0, ymm2 + vmovdqa ymmword ptr [rsp+0x260], ymm2 + add rdi, 64 + add rbx, 256 + mov qword ptr [rbp+0x50], rbx + sub rsi, 8 + cmp rsi, 8 + jnc 2b + test rsi, rsi + jnz 3f +4: + vzeroupper + mov rsp, rbp + pop rbp + pop rbx + pop r12 + pop r13 + pop r14 + pop r15 + ret +.p2align 5 +3: + mov rbx, qword ptr [rbp+0x50] + mov r15, qword ptr [rsp+0x2A0] + movzx r13d, byte ptr [rbp+0x38] + movzx r12d, byte ptr [rbp+0x48] + test rsi, 0x4 + je 3f + vbroadcasti128 ymm0, xmmword ptr [rcx] + vbroadcasti128 ymm1, xmmword ptr [rcx+0x10] + vmovdqa ymm8, ymm0 + vmovdqa ymm9, ymm1 + vbroadcasti128 ymm12, xmmword ptr [rsp+0x240] + vbroadcasti128 ymm13, xmmword ptr [rsp+0x260] + vpunpckldq ymm14, ymm12, ymm13 + vpunpckhdq ymm15, ymm12, ymm13 + vpermq ymm14, ymm14, 0x50 + vpermq ymm15, ymm15, 0x50 + vbroadcasti128 ymm12, xmmword ptr [BLAKE3_BLOCK_LEN+rip] + vpblendd ymm14, ymm14, ymm12, 0x44 + vpblendd ymm15, ymm15, ymm12, 0x44 + vmovdqa ymmword ptr [rsp], ymm14 + vmovdqa ymmword ptr [rsp+0x20], ymm15 + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + mov r10, qword ptr [rdi+0x10] + mov r11, qword ptr [rdi+0x18] + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +.p2align 5 +2: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + mov dword ptr [rsp+0x200], eax + vmovups ymm2, ymmword ptr [r8+rdx-0x40] + vinsertf128 ymm2, ymm2, xmmword ptr [r9+rdx-0x40], 0x01 + vmovups ymm3, ymmword ptr [r8+rdx-0x30] + vinsertf128 ymm3, ymm3, xmmword ptr [r9+rdx-0x30], 0x01 + vshufps ymm4, ymm2, ymm3, 136 + vshufps ymm5, ymm2, ymm3, 221 + vmovups ymm2, ymmword ptr [r8+rdx-0x20] + vinsertf128 ymm2, ymm2, xmmword ptr [r9+rdx-0x20], 0x01 + vmovups ymm3, ymmword ptr [r8+rdx-0x10] + vinsertf128 ymm3, ymm3, xmmword ptr [r9+rdx-0x10], 0x01 + vshufps ymm6, ymm2, ymm3, 136 + vshufps ymm7, ymm2, ymm3, 221 + vpshufd ymm6, ymm6, 0x93 + vpshufd ymm7, ymm7, 0x93 + vmovups ymm10, ymmword ptr [r10+rdx-0x40] + vinsertf128 ymm10, ymm10, xmmword ptr [r11+rdx-0x40], 0x01 + vmovups ymm11, ymmword ptr [r10+rdx-0x30] + vinsertf128 ymm11, ymm11, xmmword ptr [r11+rdx-0x30], 0x01 + vshufps ymm12, ymm10, ymm11, 136 + vshufps ymm13, ymm10, ymm11, 221 + vmovups ymm10, ymmword ptr [r10+rdx-0x20] + vinsertf128 ymm10, ymm10, xmmword ptr [r11+rdx-0x20], 0x01 + vmovups ymm11, ymmword ptr [r10+rdx-0x10] + vinsertf128 ymm11, ymm11, xmmword ptr [r11+rdx-0x10], 0x01 + vshufps ymm14, ymm10, ymm11, 136 + vshufps ymm15, ymm10, ymm11, 221 + vpshufd ymm14, ymm14, 0x93 + vpshufd ymm15, ymm15, 0x93 + prefetcht0 [r8+rdx+0x80] + prefetcht0 [r9+rdx+0x80] + prefetcht0 [r10+rdx+0x80] + prefetcht0 [r11+rdx+0x80] + vpbroadcastd ymm2, dword ptr [rsp+0x200] + vmovdqa ymm3, ymmword ptr [rsp] + vmovdqa ymm11, ymmword ptr [rsp+0x20] + vpblendd ymm3, ymm3, ymm2, 0x88 + vpblendd ymm11, ymm11, ymm2, 0x88 + vbroadcasti128 ymm2, xmmword ptr [BLAKE3_IV+rip] + vmovdqa ymm10, ymm2 + mov al, 7 +9: + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm8, ymm8, ymm12 + vmovdqa ymmword ptr [rsp+0x40], ymm4 + nop + vmovdqa ymmword ptr [rsp+0x60], ymm12 + nop + vpaddd ymm0, ymm0, ymm1 + vpaddd ymm8, ymm8, ymm9 + vpxor ymm3, ymm3, ymm0 + vpxor ymm11, ymm11, ymm8 + vbroadcasti128 ymm4, xmmword ptr [ROT16+rip] + vpshufb ymm3, ymm3, ymm4 + vpshufb ymm11, ymm11, ymm4 + vpaddd ymm2, ymm2, ymm3 + vpaddd ymm10, ymm10, ymm11 + vpxor ymm1, ymm1, ymm2 + vpxor ymm9, ymm9, ymm10 + vpsrld ymm4, ymm1, 12 + vpslld ymm1, ymm1, 20 + vpor ymm1, ymm1, ymm4 + vpsrld ymm4, ymm9, 12 + vpslld ymm9, ymm9, 20 + vpor ymm9, ymm9, ymm4 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm0, ymm0, ymm1 + vpaddd ymm8, ymm8, ymm9 + vmovdqa ymmword ptr [rsp+0x80], ymm5 + vmovdqa ymmword ptr [rsp+0xA0], ymm13 + vpxor ymm3, ymm3, ymm0 + vpxor ymm11, ymm11, ymm8 + vbroadcasti128 ymm4, xmmword ptr [ROT8+rip] + vpshufb ymm3, ymm3, ymm4 + vpshufb ymm11, ymm11, ymm4 + vpaddd ymm2, ymm2, ymm3 + vpaddd ymm10, ymm10, ymm11 + vpxor ymm1, ymm1, ymm2 + vpxor ymm9, ymm9, ymm10 + vpsrld ymm4, ymm1, 7 + vpslld ymm1, ymm1, 25 + vpor ymm1, ymm1, ymm4 + vpsrld ymm4, ymm9, 7 + vpslld ymm9, ymm9, 25 + vpor ymm9, ymm9, ymm4 + vpshufd ymm0, ymm0, 0x93 + vpshufd ymm8, ymm8, 0x93 + vpshufd ymm3, ymm3, 0x4E + vpshufd ymm11, ymm11, 0x4E + vpshufd ymm2, ymm2, 0x39 + vpshufd ymm10, ymm10, 0x39 + vpaddd ymm0, ymm0, ymm6 + vpaddd ymm8, ymm8, ymm14 + vpaddd ymm0, ymm0, ymm1 + vpaddd ymm8, ymm8, ymm9 + vpxor ymm3, ymm3, ymm0 + vpxor ymm11, ymm11, ymm8 + vbroadcasti128 ymm4, xmmword ptr [ROT16+rip] + vpshufb ymm3, ymm3, ymm4 + vpshufb ymm11, ymm11, ymm4 + vpaddd ymm2, ymm2, ymm3 + vpaddd ymm10, ymm10, ymm11 + vpxor ymm1, ymm1, ymm2 + vpxor ymm9, ymm9, ymm10 + vpsrld ymm4, ymm1, 12 + vpslld ymm1, ymm1, 20 + vpor ymm1, ymm1, ymm4 + vpsrld ymm4, ymm9, 12 + vpslld ymm9, ymm9, 20 + vpor ymm9, ymm9, ymm4 + vpaddd ymm0, ymm0, ymm7 + vpaddd ymm8, ymm8, ymm15 + vpaddd ymm0, ymm0, ymm1 + vpaddd ymm8, ymm8, ymm9 + vpxor ymm3, ymm3, ymm0 + vpxor ymm11, ymm11, ymm8 + vbroadcasti128 ymm4, xmmword ptr [ROT8+rip] + vpshufb ymm3, ymm3, ymm4 + vpshufb ymm11, ymm11, ymm4 + vpaddd ymm2, ymm2, ymm3 + vpaddd ymm10, ymm10, ymm11 + vpxor ymm1, ymm1, ymm2 + vpxor ymm9, ymm9, ymm10 + vpsrld ymm4, ymm1, 7 + vpslld ymm1, ymm1, 25 + vpor ymm1, ymm1, ymm4 + vpsrld ymm4, ymm9, 7 + vpslld ymm9, ymm9, 25 + vpor ymm9, ymm9, ymm4 + vpshufd ymm0, ymm0, 0x39 + vpshufd ymm8, ymm8, 0x39 + vpshufd ymm3, ymm3, 0x4E + vpshufd ymm11, ymm11, 0x4E + vpshufd ymm2, ymm2, 0x93 + vpshufd ymm10, ymm10, 0x93 + dec al + je 9f + vmovdqa ymm4, ymmword ptr [rsp+0x40] + vmovdqa ymm5, ymmword ptr [rsp+0x80] + vshufps ymm12, ymm4, ymm5, 214 + vpshufd ymm13, ymm4, 0x0F + vpshufd ymm4, ymm12, 0x39 + vshufps ymm12, ymm6, ymm7, 250 + vpblendd ymm13, ymm13, ymm12, 0xAA + vpunpcklqdq ymm12, ymm7, ymm5 + vpblendd ymm12, ymm12, ymm6, 0x88 + vpshufd ymm12, ymm12, 0x78 + vpunpckhdq ymm5, ymm5, ymm7 + vpunpckldq ymm6, ymm6, ymm5 + vpshufd ymm7, ymm6, 0x1E + vmovdqa ymmword ptr [rsp+0x40], ymm13 + vmovdqa ymmword ptr [rsp+0x80], ymm12 + vmovdqa ymm12, ymmword ptr [rsp+0x60] + vmovdqa ymm13, ymmword ptr [rsp+0xA0] + vshufps ymm5, ymm12, ymm13, 214 + vpshufd ymm6, ymm12, 0x0F + vpshufd ymm12, ymm5, 0x39 + vshufps ymm5, ymm14, ymm15, 250 + vpblendd ymm6, ymm6, ymm5, 0xAA + vpunpcklqdq ymm5, ymm15, ymm13 + vpblendd ymm5, ymm5, ymm14, 0x88 + vpshufd ymm5, ymm5, 0x78 + vpunpckhdq ymm13, ymm13, ymm15 + vpunpckldq ymm14, ymm14, ymm13 + vpshufd ymm15, ymm14, 0x1E + vmovdqa ymm13, ymm6 + vmovdqa ymm14, ymm5 + vmovdqa ymm5, ymmword ptr [rsp+0x40] + vmovdqa ymm6, ymmword ptr [rsp+0x80] + jmp 9b +9: + vpxor ymm0, ymm0, ymm2 + vpxor ymm1, ymm1, ymm3 + vpxor ymm8, ymm8, ymm10 + vpxor ymm9, ymm9, ymm11 + mov eax, r13d + cmp rdx, r15 + jne 2b + vmovdqu xmmword ptr [rbx], xmm0 + vmovdqu xmmword ptr [rbx+0x10], xmm1 + vextracti128 xmmword ptr [rbx+0x20], ymm0, 0x01 + vextracti128 xmmword ptr [rbx+0x30], ymm1, 0x01 + vmovdqu xmmword ptr [rbx+0x40], xmm8 + vmovdqu xmmword ptr [rbx+0x50], xmm9 + vextracti128 xmmword ptr [rbx+0x60], ymm8, 0x01 + vextracti128 xmmword ptr [rbx+0x70], ymm9, 0x01 + vmovaps xmm8, xmmword ptr [rsp+0x280] + vmovaps xmm0, xmmword ptr [rsp+0x240] + vmovaps xmm1, xmmword ptr [rsp+0x250] + vmovaps xmm2, xmmword ptr [rsp+0x260] + vmovaps xmm3, xmmword ptr [rsp+0x270] + vblendvps xmm0, xmm0, xmm1, xmm8 + vblendvps xmm2, xmm2, xmm3, xmm8 + vmovaps xmmword ptr [rsp+0x240], xmm0 + vmovaps xmmword ptr [rsp+0x260], xmm2 + add rbx, 128 + add rdi, 32 + sub rsi, 4 +3: + test rsi, 0x2 + je 3f + vbroadcasti128 ymm0, xmmword ptr [rcx] + vbroadcasti128 ymm1, xmmword ptr [rcx+0x10] + vmovd xmm13, dword ptr [rsp+0x240] + vpinsrd xmm13, xmm13, dword ptr [rsp+0x260], 1 + vpinsrd xmm13, xmm13, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + vmovd xmm14, dword ptr [rsp+0x244] + vpinsrd xmm14, xmm14, dword ptr [rsp+0x264], 1 + vpinsrd xmm14, xmm14, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + vinserti128 ymm13, ymm13, xmm14, 0x01 + vbroadcasti128 ymm14, xmmword ptr [ROT16+rip] + vbroadcasti128 ymm15, xmmword ptr [ROT8+rip] + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +.p2align 5 +2: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + mov dword ptr [rsp+0x200], eax + vbroadcasti128 ymm2, xmmword ptr [BLAKE3_IV+rip] + vpbroadcastd ymm8, dword ptr [rsp+0x200] + vpblendd ymm3, ymm13, ymm8, 0x88 + vmovups ymm8, ymmword ptr [r8+rdx-0x40] + vinsertf128 ymm8, ymm8, xmmword ptr [r9+rdx-0x40], 0x01 + vmovups ymm9, ymmword ptr [r8+rdx-0x30] + vinsertf128 ymm9, ymm9, xmmword ptr [r9+rdx-0x30], 0x01 + vshufps ymm4, ymm8, ymm9, 136 + vshufps ymm5, ymm8, ymm9, 221 + vmovups ymm8, ymmword ptr [r8+rdx-0x20] + vinsertf128 ymm8, ymm8, xmmword ptr [r9+rdx-0x20], 0x01 + vmovups ymm9, ymmword ptr [r8+rdx-0x10] + vinsertf128 ymm9, ymm9, xmmword ptr [r9+rdx-0x10], 0x01 + vshufps ymm6, ymm8, ymm9, 136 + vshufps ymm7, ymm8, ymm9, 221 + vpshufd ymm6, ymm6, 0x93 + vpshufd ymm7, ymm7, 0x93 + mov al, 7 +9: + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm0, ymm0, ymm1 + vpxor ymm3, ymm3, ymm0 + vpshufb ymm3, ymm3, ymm14 + vpaddd ymm2, ymm2, ymm3 + vpxor ymm1, ymm1, ymm2 + vpsrld ymm8, ymm1, 12 + vpslld ymm1, ymm1, 20 + vpor ymm1, ymm1, ymm8 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm0, ymm0, ymm1 + vpxor ymm3, ymm3, ymm0 + vpshufb ymm3, ymm3, ymm15 + vpaddd ymm2, ymm2, ymm3 + vpxor ymm1, ymm1, ymm2 + vpsrld ymm8, ymm1, 7 + vpslld ymm1, ymm1, 25 + vpor ymm1, ymm1, ymm8 + vpshufd ymm0, ymm0, 0x93 + vpshufd ymm3, ymm3, 0x4E + vpshufd ymm2, ymm2, 0x39 + vpaddd ymm0, ymm0, ymm6 + vpaddd ymm0, ymm0, ymm1 + vpxor ymm3, ymm3, ymm0 + vpshufb ymm3, ymm3, ymm14 + vpaddd ymm2, ymm2, ymm3 + vpxor ymm1, ymm1, ymm2 + vpsrld ymm8, ymm1, 12 + vpslld ymm1, ymm1, 20 + vpor ymm1, ymm1, ymm8 + vpaddd ymm0, ymm0, ymm7 + vpaddd ymm0, ymm0, ymm1 + vpxor ymm3, ymm3, ymm0 + vpshufb ymm3, ymm3, ymm15 + vpaddd ymm2, ymm2, ymm3 + vpxor ymm1, ymm1, ymm2 + vpsrld ymm8, ymm1, 7 + vpslld ymm1, ymm1, 25 + vpor ymm1, ymm1, ymm8 + vpshufd ymm0, ymm0, 0x39 + vpshufd ymm3, ymm3, 0x4E + vpshufd ymm2, ymm2, 0x93 + dec al + jz 9f + vshufps ymm8, ymm4, ymm5, 214 + vpshufd ymm9, ymm4, 0x0F + vpshufd ymm4, ymm8, 0x39 + vshufps ymm8, ymm6, ymm7, 250 + vpblendd ymm9, ymm9, ymm8, 0xAA + vpunpcklqdq ymm8, ymm7, ymm5 + vpblendd ymm8, ymm8, ymm6, 0x88 + vpshufd ymm8, ymm8, 0x78 + vpunpckhdq ymm5, ymm5, ymm7 + vpunpckldq ymm6, ymm6, ymm5 + vpshufd ymm7, ymm6, 0x1E + vmovdqa ymm5, ymm9 + vmovdqa ymm6, ymm8 + jmp 9b +9: + vpxor ymm0, ymm0, ymm2 + vpxor ymm1, ymm1, ymm3 + mov eax, r13d + cmp rdx, r15 + jne 2b + vmovdqu xmmword ptr [rbx], xmm0 + vmovdqu xmmword ptr [rbx+0x10], xmm1 + vextracti128 xmmword ptr [rbx+0x20], ymm0, 0x01 + vextracti128 xmmword ptr [rbx+0x30], ymm1, 0x01 + vmovaps ymm8, ymmword ptr [rsp+0x280] + vmovaps ymm0, ymmword ptr [rsp+0x240] + vmovups ymm1, ymmword ptr [rsp+0x248] + vmovaps ymm2, ymmword ptr [rsp+0x260] + vmovups ymm3, ymmword ptr [rsp+0x268] + vblendvps ymm0, ymm0, ymm1, ymm8 + vblendvps ymm2, ymm2, ymm3, ymm8 + vmovaps ymmword ptr [rsp+0x240], ymm0 + vmovaps ymmword ptr [rsp+0x260], ymm2 + add rbx, 64 + add rdi, 16 + sub rsi, 2 +3: + test rsi, 0x1 + je 4b + vmovdqu xmm0, xmmword ptr [rcx] + vmovdqu xmm1, xmmword ptr [rcx+0x10] + vmovd xmm3, dword ptr [rsp+0x240] + vpinsrd xmm3, xmm3, dword ptr [rsp+0x260], 1 + vpinsrd xmm13, xmm3, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + vmovdqa xmm14, xmmword ptr [ROT16+rip] + vmovdqa xmm15, xmmword ptr [ROT8+rip] + mov r8, qword ptr [rdi] + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +.p2align 5 +2: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + vmovdqa xmm2, xmmword ptr [BLAKE3_IV+rip] + vmovdqa xmm3, xmm13 + vpinsrd xmm3, xmm3, eax, 3 + vmovups xmm8, xmmword ptr [r8+rdx-0x40] + vmovups xmm9, xmmword ptr [r8+rdx-0x30] + vshufps xmm4, xmm8, xmm9, 136 + vshufps xmm5, xmm8, xmm9, 221 + vmovups xmm8, xmmword ptr [r8+rdx-0x20] + vmovups xmm9, xmmword ptr [r8+rdx-0x10] + vshufps xmm6, xmm8, xmm9, 136 + vshufps xmm7, xmm8, xmm9, 221 + vpshufd xmm6, xmm6, 0x93 + vpshufd xmm7, xmm7, 0x93 + mov al, 7 +9: + vpaddd xmm0, xmm0, xmm4 + vpaddd xmm0, xmm0, xmm1 + vpxor xmm3, xmm3, xmm0 + vpshufb xmm3, xmm3, xmm14 + vpaddd xmm2, xmm2, xmm3 + vpxor xmm1, xmm1, xmm2 + vpsrld xmm8, xmm1, 12 + vpslld xmm1, xmm1, 20 + vpor xmm1, xmm1, xmm8 + vpaddd xmm0, xmm0, xmm5 + vpaddd xmm0, xmm0, xmm1 + vpxor xmm3, xmm3, xmm0 + vpshufb xmm3, xmm3, xmm15 + vpaddd xmm2, xmm2, xmm3 + vpxor xmm1, xmm1, xmm2 + vpsrld xmm8, xmm1, 7 + vpslld xmm1, xmm1, 25 + vpor xmm1, xmm1, xmm8 + vpshufd xmm0, xmm0, 0x93 + vpshufd xmm3, xmm3, 0x4E + vpshufd xmm2, xmm2, 0x39 + vpaddd xmm0, xmm0, xmm6 + vpaddd xmm0, xmm0, xmm1 + vpxor xmm3, xmm3, xmm0 + vpshufb xmm3, xmm3, xmm14 + vpaddd xmm2, xmm2, xmm3 + vpxor xmm1, xmm1, xmm2 + vpsrld xmm8, xmm1, 12 + vpslld xmm1, xmm1, 20 + vpor xmm1, xmm1, xmm8 + vpaddd xmm0, xmm0, xmm7 + vpaddd xmm0, xmm0, xmm1 + vpxor xmm3, xmm3, xmm0 + vpshufb xmm3, xmm3, xmm15 + vpaddd xmm2, xmm2, xmm3 + vpxor xmm1, xmm1, xmm2 + vpsrld xmm8, xmm1, 7 + vpslld xmm1, xmm1, 25 + vpor xmm1, xmm1, xmm8 + vpshufd xmm0, xmm0, 0x39 + vpshufd xmm3, xmm3, 0x4E + vpshufd xmm2, xmm2, 0x93 + dec al + jz 9f + vshufps xmm8, xmm4, xmm5, 214 + vpshufd xmm9, xmm4, 0x0F + vpshufd xmm4, xmm8, 0x39 + vshufps xmm8, xmm6, xmm7, 250 + vpblendd xmm9, xmm9, xmm8, 0xAA + vpunpcklqdq xmm8, xmm7, xmm5 + vpblendd xmm8, xmm8, xmm6, 0x88 + vpshufd xmm8, xmm8, 0x78 + vpunpckhdq xmm5, xmm5, xmm7 + vpunpckldq xmm6, xmm6, xmm5 + vpshufd xmm7, xmm6, 0x1E + vmovdqa xmm5, xmm9 + vmovdqa xmm6, xmm8 + jmp 9b +9: + vpxor xmm0, xmm0, xmm2 + vpxor xmm1, xmm1, xmm3 + mov eax, r13d + cmp rdx, r15 + jne 2b + vmovdqu xmmword ptr [rbx], xmm0 + vmovdqu xmmword ptr [rbx+0x10], xmm1 + jmp 4b + + +#ifdef __APPLE__ +.static_data +#else +.section .rodata +#endif +.p2align 6 +ADD0: + .long 0, 1, 2, 3, 4, 5, 6, 7 +ADD1: + .long 8, 8, 8, 8, 8, 8, 8, 8 +BLAKE3_IV_0: + .long 0x6A09E667, 0x6A09E667, 0x6A09E667, 0x6A09E667 + .long 0x6A09E667, 0x6A09E667, 0x6A09E667, 0x6A09E667 +BLAKE3_IV_1: + .long 0xBB67AE85, 0xBB67AE85, 0xBB67AE85, 0xBB67AE85 + .long 0xBB67AE85, 0xBB67AE85, 0xBB67AE85, 0xBB67AE85 +BLAKE3_IV_2: + .long 0x3C6EF372, 0x3C6EF372, 0x3C6EF372, 0x3C6EF372 + .long 0x3C6EF372, 0x3C6EF372, 0x3C6EF372, 0x3C6EF372 +BLAKE3_IV_3: + .long 0xA54FF53A, 0xA54FF53A, 0xA54FF53A, 0xA54FF53A + .long 0xA54FF53A, 0xA54FF53A, 0xA54FF53A, 0xA54FF53A +BLAKE3_BLOCK_LEN: + .long 0x00000040, 0x00000040, 0x00000040, 0x00000040 + .long 0x00000040, 0x00000040, 0x00000040, 0x00000040 +ROT16: + .byte 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13 +ROT8: + .byte 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12 +CMP_MSB_MASK: + .long 0x80000000, 0x80000000, 0x80000000, 0x80000000 + .long 0x80000000, 0x80000000, 0x80000000, 0x80000000 +BLAKE3_IV: + .long 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A + +#endif // __x86_64__ diff --git a/src/b3/blake3_avx512.c b/src/b3/blake3_avx512.c index 77a5c385..00f6884f 100644 --- a/src/b3/blake3_avx512.c +++ b/src/b3/blake3_avx512.c @@ -1,1204 +1,1204 @@ -#include "blake3_impl.h" - -#include - -#define _mm_shuffle_ps2(a, b, c) \ - (_mm_castps_si128( \ - _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c)))) - -INLINE __m128i loadu_128(const uint8_t src[16]) { - return _mm_loadu_si128((const __m128i *)src); -} - -INLINE __m256i loadu_256(const uint8_t src[32]) { - return _mm256_loadu_si256((const __m256i *)src); -} - -INLINE __m512i loadu_512(const uint8_t src[64]) { - return _mm512_loadu_si512((const __m512i *)src); -} - -INLINE void storeu_128(__m128i src, uint8_t dest[16]) { - _mm_storeu_si128((__m128i *)dest, src); -} - -INLINE void storeu_256(__m256i src, uint8_t dest[16]) { - _mm256_storeu_si256((__m256i *)dest, src); -} - -INLINE __m128i add_128(__m128i a, __m128i b) { return _mm_add_epi32(a, b); } - -INLINE __m256i add_256(__m256i a, __m256i b) { return _mm256_add_epi32(a, b); } - -INLINE __m512i add_512(__m512i a, __m512i b) { return _mm512_add_epi32(a, b); } - -INLINE __m128i xor_128(__m128i a, __m128i b) { return _mm_xor_si128(a, b); } - -INLINE __m256i xor_256(__m256i a, __m256i b) { return _mm256_xor_si256(a, b); } - -INLINE __m512i xor_512(__m512i a, __m512i b) { return _mm512_xor_si512(a, b); } - -INLINE __m128i set1_128(uint32_t x) { return _mm_set1_epi32((int32_t)x); } - -INLINE __m256i set1_256(uint32_t x) { return _mm256_set1_epi32((int32_t)x); } - -INLINE __m512i set1_512(uint32_t x) { return _mm512_set1_epi32((int32_t)x); } - -INLINE __m128i set4(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { - return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d); -} - -INLINE __m128i rot16_128(__m128i x) { return _mm_ror_epi32(x, 16); } - -INLINE __m256i rot16_256(__m256i x) { return _mm256_ror_epi32(x, 16); } - -INLINE __m512i rot16_512(__m512i x) { return _mm512_ror_epi32(x, 16); } - -INLINE __m128i rot12_128(__m128i x) { return _mm_ror_epi32(x, 12); } - -INLINE __m256i rot12_256(__m256i x) { return _mm256_ror_epi32(x, 12); } - -INLINE __m512i rot12_512(__m512i x) { return _mm512_ror_epi32(x, 12); } - -INLINE __m128i rot8_128(__m128i x) { return _mm_ror_epi32(x, 8); } - -INLINE __m256i rot8_256(__m256i x) { return _mm256_ror_epi32(x, 8); } - -INLINE __m512i rot8_512(__m512i x) { return _mm512_ror_epi32(x, 8); } - -INLINE __m128i rot7_128(__m128i x) { return _mm_ror_epi32(x, 7); } - -INLINE __m256i rot7_256(__m256i x) { return _mm256_ror_epi32(x, 7); } - -INLINE __m512i rot7_512(__m512i x) { return _mm512_ror_epi32(x, 7); } - -/* - * ---------------------------------------------------------------------------- - * compress_avx512 - * ---------------------------------------------------------------------------- - */ - -INLINE void g1(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, - __m128i m) { - *row0 = add_128(add_128(*row0, m), *row1); - *row3 = xor_128(*row3, *row0); - *row3 = rot16_128(*row3); - *row2 = add_128(*row2, *row3); - *row1 = xor_128(*row1, *row2); - *row1 = rot12_128(*row1); -} - -INLINE void g2(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, - __m128i m) { - *row0 = add_128(add_128(*row0, m), *row1); - *row3 = xor_128(*row3, *row0); - *row3 = rot8_128(*row3); - *row2 = add_128(*row2, *row3); - *row1 = xor_128(*row1, *row2); - *row1 = rot7_128(*row1); -} - -// Note the optimization here of leaving row1 as the unrotated row, rather than -// row0. All the message loads below are adjusted to compensate for this. See -// discussion at https://github.com/sneves/blake2-avx2/pull/4 -INLINE void diagonalize(__m128i *row0, __m128i *row2, __m128i *row3) { - *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3)); - *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2)); - *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1)); -} - -INLINE void undiagonalize(__m128i *row0, __m128i *row2, __m128i *row3) { - *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1)); - *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2)); - *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3)); -} - -INLINE void compress_pre(__m128i rows[4], const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, uint8_t flags) { - rows[0] = loadu_128((uint8_t *)&cv[0]); - rows[1] = loadu_128((uint8_t *)&cv[4]); - rows[2] = set4(IV[0], IV[1], IV[2], IV[3]); - rows[3] = set4(counter_low(counter), counter_high(counter), - (uint32_t)block_len, (uint32_t)flags); - - __m128i m0 = loadu_128(&block[sizeof(__m128i) * 0]); - __m128i m1 = loadu_128(&block[sizeof(__m128i) * 1]); - __m128i m2 = loadu_128(&block[sizeof(__m128i) * 2]); - __m128i m3 = loadu_128(&block[sizeof(__m128i) * 3]); - - __m128i t0, t1, t2, t3, tt; - - // Round 1. The first round permutes the message words from the original - // input order, into the groups that get mixed in parallel. - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0)); // 6 4 2 0 - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1)); // 7 5 3 1 - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0)); // 14 12 10 8 - t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3)); // 12 10 8 14 - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1)); // 15 13 11 9 - t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3)); // 13 11 9 15 - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 2. This round and all following rounds apply a fixed permutation - // to the message words from the round before. - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 3 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 4 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 5 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 6 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 7 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); -} - -void blake3_compress_xof_avx512(const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags, uint8_t out[64]) { - __m128i rows[4]; - compress_pre(rows, cv, block, block_len, counter, flags); - storeu_128(xor_128(rows[0], rows[2]), &out[0]); - storeu_128(xor_128(rows[1], rows[3]), &out[16]); - storeu_128(xor_128(rows[2], loadu_128((uint8_t *)&cv[0])), &out[32]); - storeu_128(xor_128(rows[3], loadu_128((uint8_t *)&cv[4])), &out[48]); -} - -void blake3_compress_in_place_avx512(uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags) { - __m128i rows[4]; - compress_pre(rows, cv, block, block_len, counter, flags); - storeu_128(xor_128(rows[0], rows[2]), (uint8_t *)&cv[0]); - storeu_128(xor_128(rows[1], rows[3]), (uint8_t *)&cv[4]); -} - -/* - * ---------------------------------------------------------------------------- - * hash4_avx512 - * ---------------------------------------------------------------------------- - */ - -INLINE void round_fn4(__m128i v[16], __m128i m[16], size_t r) { - v[0] = add_128(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); - v[1] = add_128(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); - v[2] = add_128(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); - v[3] = add_128(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); - v[0] = add_128(v[0], v[4]); - v[1] = add_128(v[1], v[5]); - v[2] = add_128(v[2], v[6]); - v[3] = add_128(v[3], v[7]); - v[12] = xor_128(v[12], v[0]); - v[13] = xor_128(v[13], v[1]); - v[14] = xor_128(v[14], v[2]); - v[15] = xor_128(v[15], v[3]); - v[12] = rot16_128(v[12]); - v[13] = rot16_128(v[13]); - v[14] = rot16_128(v[14]); - v[15] = rot16_128(v[15]); - v[8] = add_128(v[8], v[12]); - v[9] = add_128(v[9], v[13]); - v[10] = add_128(v[10], v[14]); - v[11] = add_128(v[11], v[15]); - v[4] = xor_128(v[4], v[8]); - v[5] = xor_128(v[5], v[9]); - v[6] = xor_128(v[6], v[10]); - v[7] = xor_128(v[7], v[11]); - v[4] = rot12_128(v[4]); - v[5] = rot12_128(v[5]); - v[6] = rot12_128(v[6]); - v[7] = rot12_128(v[7]); - v[0] = add_128(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); - v[1] = add_128(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); - v[2] = add_128(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); - v[3] = add_128(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); - v[0] = add_128(v[0], v[4]); - v[1] = add_128(v[1], v[5]); - v[2] = add_128(v[2], v[6]); - v[3] = add_128(v[3], v[7]); - v[12] = xor_128(v[12], v[0]); - v[13] = xor_128(v[13], v[1]); - v[14] = xor_128(v[14], v[2]); - v[15] = xor_128(v[15], v[3]); - v[12] = rot8_128(v[12]); - v[13] = rot8_128(v[13]); - v[14] = rot8_128(v[14]); - v[15] = rot8_128(v[15]); - v[8] = add_128(v[8], v[12]); - v[9] = add_128(v[9], v[13]); - v[10] = add_128(v[10], v[14]); - v[11] = add_128(v[11], v[15]); - v[4] = xor_128(v[4], v[8]); - v[5] = xor_128(v[5], v[9]); - v[6] = xor_128(v[6], v[10]); - v[7] = xor_128(v[7], v[11]); - v[4] = rot7_128(v[4]); - v[5] = rot7_128(v[5]); - v[6] = rot7_128(v[6]); - v[7] = rot7_128(v[7]); - - v[0] = add_128(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); - v[1] = add_128(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); - v[2] = add_128(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); - v[3] = add_128(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); - v[0] = add_128(v[0], v[5]); - v[1] = add_128(v[1], v[6]); - v[2] = add_128(v[2], v[7]); - v[3] = add_128(v[3], v[4]); - v[15] = xor_128(v[15], v[0]); - v[12] = xor_128(v[12], v[1]); - v[13] = xor_128(v[13], v[2]); - v[14] = xor_128(v[14], v[3]); - v[15] = rot16_128(v[15]); - v[12] = rot16_128(v[12]); - v[13] = rot16_128(v[13]); - v[14] = rot16_128(v[14]); - v[10] = add_128(v[10], v[15]); - v[11] = add_128(v[11], v[12]); - v[8] = add_128(v[8], v[13]); - v[9] = add_128(v[9], v[14]); - v[5] = xor_128(v[5], v[10]); - v[6] = xor_128(v[6], v[11]); - v[7] = xor_128(v[7], v[8]); - v[4] = xor_128(v[4], v[9]); - v[5] = rot12_128(v[5]); - v[6] = rot12_128(v[6]); - v[7] = rot12_128(v[7]); - v[4] = rot12_128(v[4]); - v[0] = add_128(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); - v[1] = add_128(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); - v[2] = add_128(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); - v[3] = add_128(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); - v[0] = add_128(v[0], v[5]); - v[1] = add_128(v[1], v[6]); - v[2] = add_128(v[2], v[7]); - v[3] = add_128(v[3], v[4]); - v[15] = xor_128(v[15], v[0]); - v[12] = xor_128(v[12], v[1]); - v[13] = xor_128(v[13], v[2]); - v[14] = xor_128(v[14], v[3]); - v[15] = rot8_128(v[15]); - v[12] = rot8_128(v[12]); - v[13] = rot8_128(v[13]); - v[14] = rot8_128(v[14]); - v[10] = add_128(v[10], v[15]); - v[11] = add_128(v[11], v[12]); - v[8] = add_128(v[8], v[13]); - v[9] = add_128(v[9], v[14]); - v[5] = xor_128(v[5], v[10]); - v[6] = xor_128(v[6], v[11]); - v[7] = xor_128(v[7], v[8]); - v[4] = xor_128(v[4], v[9]); - v[5] = rot7_128(v[5]); - v[6] = rot7_128(v[6]); - v[7] = rot7_128(v[7]); - v[4] = rot7_128(v[4]); -} - -INLINE void transpose_vecs_128(__m128i vecs[4]) { - // Interleave 32-bit lates. The low unpack is lanes 00/11 and the high is - // 22/33. Note that this doesn't split the vector into two lanes, as the - // AVX2 counterparts do. - __m128i ab_01 = _mm_unpacklo_epi32(vecs[0], vecs[1]); - __m128i ab_23 = _mm_unpackhi_epi32(vecs[0], vecs[1]); - __m128i cd_01 = _mm_unpacklo_epi32(vecs[2], vecs[3]); - __m128i cd_23 = _mm_unpackhi_epi32(vecs[2], vecs[3]); - - // Interleave 64-bit lanes. - __m128i abcd_0 = _mm_unpacklo_epi64(ab_01, cd_01); - __m128i abcd_1 = _mm_unpackhi_epi64(ab_01, cd_01); - __m128i abcd_2 = _mm_unpacklo_epi64(ab_23, cd_23); - __m128i abcd_3 = _mm_unpackhi_epi64(ab_23, cd_23); - - vecs[0] = abcd_0; - vecs[1] = abcd_1; - vecs[2] = abcd_2; - vecs[3] = abcd_3; -} - -INLINE void transpose_msg_vecs4(const uint8_t *const *inputs, - size_t block_offset, __m128i out[16]) { - out[0] = loadu_128(&inputs[0][block_offset + 0 * sizeof(__m128i)]); - out[1] = loadu_128(&inputs[1][block_offset + 0 * sizeof(__m128i)]); - out[2] = loadu_128(&inputs[2][block_offset + 0 * sizeof(__m128i)]); - out[3] = loadu_128(&inputs[3][block_offset + 0 * sizeof(__m128i)]); - out[4] = loadu_128(&inputs[0][block_offset + 1 * sizeof(__m128i)]); - out[5] = loadu_128(&inputs[1][block_offset + 1 * sizeof(__m128i)]); - out[6] = loadu_128(&inputs[2][block_offset + 1 * sizeof(__m128i)]); - out[7] = loadu_128(&inputs[3][block_offset + 1 * sizeof(__m128i)]); - out[8] = loadu_128(&inputs[0][block_offset + 2 * sizeof(__m128i)]); - out[9] = loadu_128(&inputs[1][block_offset + 2 * sizeof(__m128i)]); - out[10] = loadu_128(&inputs[2][block_offset + 2 * sizeof(__m128i)]); - out[11] = loadu_128(&inputs[3][block_offset + 2 * sizeof(__m128i)]); - out[12] = loadu_128(&inputs[0][block_offset + 3 * sizeof(__m128i)]); - out[13] = loadu_128(&inputs[1][block_offset + 3 * sizeof(__m128i)]); - out[14] = loadu_128(&inputs[2][block_offset + 3 * sizeof(__m128i)]); - out[15] = loadu_128(&inputs[3][block_offset + 3 * sizeof(__m128i)]); - for (size_t i = 0; i < 4; ++i) { - _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); - } - transpose_vecs_128(&out[0]); - transpose_vecs_128(&out[4]); - transpose_vecs_128(&out[8]); - transpose_vecs_128(&out[12]); -} - -INLINE void load_counters4(uint64_t counter, bool increment_counter, - __m128i *out_lo, __m128i *out_hi) { - uint64_t mask = (increment_counter ? ~0 : 0); - __m256i mask_vec = _mm256_set1_epi64x(mask); - __m256i deltas = _mm256_setr_epi64x(0, 1, 2, 3); - deltas = _mm256_and_si256(mask_vec, deltas); - __m256i counters = - _mm256_add_epi64(_mm256_set1_epi64x((int64_t)counter), deltas); - *out_lo = _mm256_cvtepi64_epi32(counters); - *out_hi = _mm256_cvtepi64_epi32(_mm256_srli_epi64(counters, 32)); -} - -void blake3_hash4_avx512(const uint8_t *const *inputs, size_t blocks, - const uint32_t key[8], uint64_t counter, - bool increment_counter, uint8_t flags, - uint8_t flags_start, uint8_t flags_end, uint8_t *out) { - __m128i h_vecs[8] = { - set1_128(key[0]), set1_128(key[1]), set1_128(key[2]), set1_128(key[3]), - set1_128(key[4]), set1_128(key[5]), set1_128(key[6]), set1_128(key[7]), - }; - __m128i counter_low_vec, counter_high_vec; - load_counters4(counter, increment_counter, &counter_low_vec, - &counter_high_vec); - uint8_t block_flags = flags | flags_start; - - for (size_t block = 0; block < blocks; block++) { - if (block + 1 == blocks) { - block_flags |= flags_end; - } - __m128i block_len_vec = set1_128(BLAKE3_BLOCK_LEN); - __m128i block_flags_vec = set1_128(block_flags); - __m128i msg_vecs[16]; - transpose_msg_vecs4(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); - - __m128i v[16] = { - h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], - h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], - set1_128(IV[0]), set1_128(IV[1]), set1_128(IV[2]), set1_128(IV[3]), - counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, - }; - round_fn4(v, msg_vecs, 0); - round_fn4(v, msg_vecs, 1); - round_fn4(v, msg_vecs, 2); - round_fn4(v, msg_vecs, 3); - round_fn4(v, msg_vecs, 4); - round_fn4(v, msg_vecs, 5); - round_fn4(v, msg_vecs, 6); - h_vecs[0] = xor_128(v[0], v[8]); - h_vecs[1] = xor_128(v[1], v[9]); - h_vecs[2] = xor_128(v[2], v[10]); - h_vecs[3] = xor_128(v[3], v[11]); - h_vecs[4] = xor_128(v[4], v[12]); - h_vecs[5] = xor_128(v[5], v[13]); - h_vecs[6] = xor_128(v[6], v[14]); - h_vecs[7] = xor_128(v[7], v[15]); - - block_flags = flags; - } - - transpose_vecs_128(&h_vecs[0]); - transpose_vecs_128(&h_vecs[4]); - // The first four vecs now contain the first half of each output, and the - // second four vecs contain the second half of each output. - storeu_128(h_vecs[0], &out[0 * sizeof(__m128i)]); - storeu_128(h_vecs[4], &out[1 * sizeof(__m128i)]); - storeu_128(h_vecs[1], &out[2 * sizeof(__m128i)]); - storeu_128(h_vecs[5], &out[3 * sizeof(__m128i)]); - storeu_128(h_vecs[2], &out[4 * sizeof(__m128i)]); - storeu_128(h_vecs[6], &out[5 * sizeof(__m128i)]); - storeu_128(h_vecs[3], &out[6 * sizeof(__m128i)]); - storeu_128(h_vecs[7], &out[7 * sizeof(__m128i)]); -} - -/* - * ---------------------------------------------------------------------------- - * hash8_avx512 - * ---------------------------------------------------------------------------- - */ - -INLINE void round_fn8(__m256i v[16], __m256i m[16], size_t r) { - v[0] = add_256(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); - v[1] = add_256(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); - v[2] = add_256(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); - v[3] = add_256(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); - v[0] = add_256(v[0], v[4]); - v[1] = add_256(v[1], v[5]); - v[2] = add_256(v[2], v[6]); - v[3] = add_256(v[3], v[7]); - v[12] = xor_256(v[12], v[0]); - v[13] = xor_256(v[13], v[1]); - v[14] = xor_256(v[14], v[2]); - v[15] = xor_256(v[15], v[3]); - v[12] = rot16_256(v[12]); - v[13] = rot16_256(v[13]); - v[14] = rot16_256(v[14]); - v[15] = rot16_256(v[15]); - v[8] = add_256(v[8], v[12]); - v[9] = add_256(v[9], v[13]); - v[10] = add_256(v[10], v[14]); - v[11] = add_256(v[11], v[15]); - v[4] = xor_256(v[4], v[8]); - v[5] = xor_256(v[5], v[9]); - v[6] = xor_256(v[6], v[10]); - v[7] = xor_256(v[7], v[11]); - v[4] = rot12_256(v[4]); - v[5] = rot12_256(v[5]); - v[6] = rot12_256(v[6]); - v[7] = rot12_256(v[7]); - v[0] = add_256(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); - v[1] = add_256(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); - v[2] = add_256(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); - v[3] = add_256(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); - v[0] = add_256(v[0], v[4]); - v[1] = add_256(v[1], v[5]); - v[2] = add_256(v[2], v[6]); - v[3] = add_256(v[3], v[7]); - v[12] = xor_256(v[12], v[0]); - v[13] = xor_256(v[13], v[1]); - v[14] = xor_256(v[14], v[2]); - v[15] = xor_256(v[15], v[3]); - v[12] = rot8_256(v[12]); - v[13] = rot8_256(v[13]); - v[14] = rot8_256(v[14]); - v[15] = rot8_256(v[15]); - v[8] = add_256(v[8], v[12]); - v[9] = add_256(v[9], v[13]); - v[10] = add_256(v[10], v[14]); - v[11] = add_256(v[11], v[15]); - v[4] = xor_256(v[4], v[8]); - v[5] = xor_256(v[5], v[9]); - v[6] = xor_256(v[6], v[10]); - v[7] = xor_256(v[7], v[11]); - v[4] = rot7_256(v[4]); - v[5] = rot7_256(v[5]); - v[6] = rot7_256(v[6]); - v[7] = rot7_256(v[7]); - - v[0] = add_256(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); - v[1] = add_256(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); - v[2] = add_256(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); - v[3] = add_256(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); - v[0] = add_256(v[0], v[5]); - v[1] = add_256(v[1], v[6]); - v[2] = add_256(v[2], v[7]); - v[3] = add_256(v[3], v[4]); - v[15] = xor_256(v[15], v[0]); - v[12] = xor_256(v[12], v[1]); - v[13] = xor_256(v[13], v[2]); - v[14] = xor_256(v[14], v[3]); - v[15] = rot16_256(v[15]); - v[12] = rot16_256(v[12]); - v[13] = rot16_256(v[13]); - v[14] = rot16_256(v[14]); - v[10] = add_256(v[10], v[15]); - v[11] = add_256(v[11], v[12]); - v[8] = add_256(v[8], v[13]); - v[9] = add_256(v[9], v[14]); - v[5] = xor_256(v[5], v[10]); - v[6] = xor_256(v[6], v[11]); - v[7] = xor_256(v[7], v[8]); - v[4] = xor_256(v[4], v[9]); - v[5] = rot12_256(v[5]); - v[6] = rot12_256(v[6]); - v[7] = rot12_256(v[7]); - v[4] = rot12_256(v[4]); - v[0] = add_256(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); - v[1] = add_256(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); - v[2] = add_256(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); - v[3] = add_256(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); - v[0] = add_256(v[0], v[5]); - v[1] = add_256(v[1], v[6]); - v[2] = add_256(v[2], v[7]); - v[3] = add_256(v[3], v[4]); - v[15] = xor_256(v[15], v[0]); - v[12] = xor_256(v[12], v[1]); - v[13] = xor_256(v[13], v[2]); - v[14] = xor_256(v[14], v[3]); - v[15] = rot8_256(v[15]); - v[12] = rot8_256(v[12]); - v[13] = rot8_256(v[13]); - v[14] = rot8_256(v[14]); - v[10] = add_256(v[10], v[15]); - v[11] = add_256(v[11], v[12]); - v[8] = add_256(v[8], v[13]); - v[9] = add_256(v[9], v[14]); - v[5] = xor_256(v[5], v[10]); - v[6] = xor_256(v[6], v[11]); - v[7] = xor_256(v[7], v[8]); - v[4] = xor_256(v[4], v[9]); - v[5] = rot7_256(v[5]); - v[6] = rot7_256(v[6]); - v[7] = rot7_256(v[7]); - v[4] = rot7_256(v[4]); -} - -INLINE void transpose_vecs_256(__m256i vecs[8]) { - // Interleave 32-bit lanes. The low unpack is lanes 00/11/44/55, and the high - // is 22/33/66/77. - __m256i ab_0145 = _mm256_unpacklo_epi32(vecs[0], vecs[1]); - __m256i ab_2367 = _mm256_unpackhi_epi32(vecs[0], vecs[1]); - __m256i cd_0145 = _mm256_unpacklo_epi32(vecs[2], vecs[3]); - __m256i cd_2367 = _mm256_unpackhi_epi32(vecs[2], vecs[3]); - __m256i ef_0145 = _mm256_unpacklo_epi32(vecs[4], vecs[5]); - __m256i ef_2367 = _mm256_unpackhi_epi32(vecs[4], vecs[5]); - __m256i gh_0145 = _mm256_unpacklo_epi32(vecs[6], vecs[7]); - __m256i gh_2367 = _mm256_unpackhi_epi32(vecs[6], vecs[7]); - - // Interleave 64-bit lates. The low unpack is lanes 00/22 and the high is - // 11/33. - __m256i abcd_04 = _mm256_unpacklo_epi64(ab_0145, cd_0145); - __m256i abcd_15 = _mm256_unpackhi_epi64(ab_0145, cd_0145); - __m256i abcd_26 = _mm256_unpacklo_epi64(ab_2367, cd_2367); - __m256i abcd_37 = _mm256_unpackhi_epi64(ab_2367, cd_2367); - __m256i efgh_04 = _mm256_unpacklo_epi64(ef_0145, gh_0145); - __m256i efgh_15 = _mm256_unpackhi_epi64(ef_0145, gh_0145); - __m256i efgh_26 = _mm256_unpacklo_epi64(ef_2367, gh_2367); - __m256i efgh_37 = _mm256_unpackhi_epi64(ef_2367, gh_2367); - - // Interleave 128-bit lanes. - vecs[0] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x20); - vecs[1] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x20); - vecs[2] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x20); - vecs[3] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x20); - vecs[4] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x31); - vecs[5] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x31); - vecs[6] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x31); - vecs[7] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x31); -} - -INLINE void transpose_msg_vecs8(const uint8_t *const *inputs, - size_t block_offset, __m256i out[16]) { - out[0] = loadu_256(&inputs[0][block_offset + 0 * sizeof(__m256i)]); - out[1] = loadu_256(&inputs[1][block_offset + 0 * sizeof(__m256i)]); - out[2] = loadu_256(&inputs[2][block_offset + 0 * sizeof(__m256i)]); - out[3] = loadu_256(&inputs[3][block_offset + 0 * sizeof(__m256i)]); - out[4] = loadu_256(&inputs[4][block_offset + 0 * sizeof(__m256i)]); - out[5] = loadu_256(&inputs[5][block_offset + 0 * sizeof(__m256i)]); - out[6] = loadu_256(&inputs[6][block_offset + 0 * sizeof(__m256i)]); - out[7] = loadu_256(&inputs[7][block_offset + 0 * sizeof(__m256i)]); - out[8] = loadu_256(&inputs[0][block_offset + 1 * sizeof(__m256i)]); - out[9] = loadu_256(&inputs[1][block_offset + 1 * sizeof(__m256i)]); - out[10] = loadu_256(&inputs[2][block_offset + 1 * sizeof(__m256i)]); - out[11] = loadu_256(&inputs[3][block_offset + 1 * sizeof(__m256i)]); - out[12] = loadu_256(&inputs[4][block_offset + 1 * sizeof(__m256i)]); - out[13] = loadu_256(&inputs[5][block_offset + 1 * sizeof(__m256i)]); - out[14] = loadu_256(&inputs[6][block_offset + 1 * sizeof(__m256i)]); - out[15] = loadu_256(&inputs[7][block_offset + 1 * sizeof(__m256i)]); - for (size_t i = 0; i < 8; ++i) { - _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); - } - transpose_vecs_256(&out[0]); - transpose_vecs_256(&out[8]); -} - -INLINE void load_counters8(uint64_t counter, bool increment_counter, - __m256i *out_lo, __m256i *out_hi) { - uint64_t mask = (increment_counter ? ~0 : 0); - __m512i mask_vec = _mm512_set1_epi64(mask); - __m512i deltas = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); - deltas = _mm512_and_si512(mask_vec, deltas); - __m512i counters = - _mm512_add_epi64(_mm512_set1_epi64((int64_t)counter), deltas); - *out_lo = _mm512_cvtepi64_epi32(counters); - *out_hi = _mm512_cvtepi64_epi32(_mm512_srli_epi64(counters, 32)); -} - -void blake3_hash8_avx512(const uint8_t *const *inputs, size_t blocks, - const uint32_t key[8], uint64_t counter, - bool increment_counter, uint8_t flags, - uint8_t flags_start, uint8_t flags_end, uint8_t *out) { - __m256i h_vecs[8] = { - set1_256(key[0]), set1_256(key[1]), set1_256(key[2]), set1_256(key[3]), - set1_256(key[4]), set1_256(key[5]), set1_256(key[6]), set1_256(key[7]), - }; - __m256i counter_low_vec, counter_high_vec; - load_counters8(counter, increment_counter, &counter_low_vec, - &counter_high_vec); - uint8_t block_flags = flags | flags_start; - - for (size_t block = 0; block < blocks; block++) { - if (block + 1 == blocks) { - block_flags |= flags_end; - } - __m256i block_len_vec = set1_256(BLAKE3_BLOCK_LEN); - __m256i block_flags_vec = set1_256(block_flags); - __m256i msg_vecs[16]; - transpose_msg_vecs8(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); - - __m256i v[16] = { - h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], - h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], - set1_256(IV[0]), set1_256(IV[1]), set1_256(IV[2]), set1_256(IV[3]), - counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, - }; - round_fn8(v, msg_vecs, 0); - round_fn8(v, msg_vecs, 1); - round_fn8(v, msg_vecs, 2); - round_fn8(v, msg_vecs, 3); - round_fn8(v, msg_vecs, 4); - round_fn8(v, msg_vecs, 5); - round_fn8(v, msg_vecs, 6); - h_vecs[0] = xor_256(v[0], v[8]); - h_vecs[1] = xor_256(v[1], v[9]); - h_vecs[2] = xor_256(v[2], v[10]); - h_vecs[3] = xor_256(v[3], v[11]); - h_vecs[4] = xor_256(v[4], v[12]); - h_vecs[5] = xor_256(v[5], v[13]); - h_vecs[6] = xor_256(v[6], v[14]); - h_vecs[7] = xor_256(v[7], v[15]); - - block_flags = flags; - } - - transpose_vecs_256(h_vecs); - storeu_256(h_vecs[0], &out[0 * sizeof(__m256i)]); - storeu_256(h_vecs[1], &out[1 * sizeof(__m256i)]); - storeu_256(h_vecs[2], &out[2 * sizeof(__m256i)]); - storeu_256(h_vecs[3], &out[3 * sizeof(__m256i)]); - storeu_256(h_vecs[4], &out[4 * sizeof(__m256i)]); - storeu_256(h_vecs[5], &out[5 * sizeof(__m256i)]); - storeu_256(h_vecs[6], &out[6 * sizeof(__m256i)]); - storeu_256(h_vecs[7], &out[7 * sizeof(__m256i)]); -} - -/* - * ---------------------------------------------------------------------------- - * hash16_avx512 - * ---------------------------------------------------------------------------- - */ - -INLINE void round_fn16(__m512i v[16], __m512i m[16], size_t r) { - v[0] = add_512(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); - v[1] = add_512(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); - v[2] = add_512(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); - v[3] = add_512(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); - v[0] = add_512(v[0], v[4]); - v[1] = add_512(v[1], v[5]); - v[2] = add_512(v[2], v[6]); - v[3] = add_512(v[3], v[7]); - v[12] = xor_512(v[12], v[0]); - v[13] = xor_512(v[13], v[1]); - v[14] = xor_512(v[14], v[2]); - v[15] = xor_512(v[15], v[3]); - v[12] = rot16_512(v[12]); - v[13] = rot16_512(v[13]); - v[14] = rot16_512(v[14]); - v[15] = rot16_512(v[15]); - v[8] = add_512(v[8], v[12]); - v[9] = add_512(v[9], v[13]); - v[10] = add_512(v[10], v[14]); - v[11] = add_512(v[11], v[15]); - v[4] = xor_512(v[4], v[8]); - v[5] = xor_512(v[5], v[9]); - v[6] = xor_512(v[6], v[10]); - v[7] = xor_512(v[7], v[11]); - v[4] = rot12_512(v[4]); - v[5] = rot12_512(v[5]); - v[6] = rot12_512(v[6]); - v[7] = rot12_512(v[7]); - v[0] = add_512(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); - v[1] = add_512(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); - v[2] = add_512(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); - v[3] = add_512(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); - v[0] = add_512(v[0], v[4]); - v[1] = add_512(v[1], v[5]); - v[2] = add_512(v[2], v[6]); - v[3] = add_512(v[3], v[7]); - v[12] = xor_512(v[12], v[0]); - v[13] = xor_512(v[13], v[1]); - v[14] = xor_512(v[14], v[2]); - v[15] = xor_512(v[15], v[3]); - v[12] = rot8_512(v[12]); - v[13] = rot8_512(v[13]); - v[14] = rot8_512(v[14]); - v[15] = rot8_512(v[15]); - v[8] = add_512(v[8], v[12]); - v[9] = add_512(v[9], v[13]); - v[10] = add_512(v[10], v[14]); - v[11] = add_512(v[11], v[15]); - v[4] = xor_512(v[4], v[8]); - v[5] = xor_512(v[5], v[9]); - v[6] = xor_512(v[6], v[10]); - v[7] = xor_512(v[7], v[11]); - v[4] = rot7_512(v[4]); - v[5] = rot7_512(v[5]); - v[6] = rot7_512(v[6]); - v[7] = rot7_512(v[7]); - - v[0] = add_512(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); - v[1] = add_512(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); - v[2] = add_512(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); - v[3] = add_512(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); - v[0] = add_512(v[0], v[5]); - v[1] = add_512(v[1], v[6]); - v[2] = add_512(v[2], v[7]); - v[3] = add_512(v[3], v[4]); - v[15] = xor_512(v[15], v[0]); - v[12] = xor_512(v[12], v[1]); - v[13] = xor_512(v[13], v[2]); - v[14] = xor_512(v[14], v[3]); - v[15] = rot16_512(v[15]); - v[12] = rot16_512(v[12]); - v[13] = rot16_512(v[13]); - v[14] = rot16_512(v[14]); - v[10] = add_512(v[10], v[15]); - v[11] = add_512(v[11], v[12]); - v[8] = add_512(v[8], v[13]); - v[9] = add_512(v[9], v[14]); - v[5] = xor_512(v[5], v[10]); - v[6] = xor_512(v[6], v[11]); - v[7] = xor_512(v[7], v[8]); - v[4] = xor_512(v[4], v[9]); - v[5] = rot12_512(v[5]); - v[6] = rot12_512(v[6]); - v[7] = rot12_512(v[7]); - v[4] = rot12_512(v[4]); - v[0] = add_512(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); - v[1] = add_512(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); - v[2] = add_512(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); - v[3] = add_512(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); - v[0] = add_512(v[0], v[5]); - v[1] = add_512(v[1], v[6]); - v[2] = add_512(v[2], v[7]); - v[3] = add_512(v[3], v[4]); - v[15] = xor_512(v[15], v[0]); - v[12] = xor_512(v[12], v[1]); - v[13] = xor_512(v[13], v[2]); - v[14] = xor_512(v[14], v[3]); - v[15] = rot8_512(v[15]); - v[12] = rot8_512(v[12]); - v[13] = rot8_512(v[13]); - v[14] = rot8_512(v[14]); - v[10] = add_512(v[10], v[15]); - v[11] = add_512(v[11], v[12]); - v[8] = add_512(v[8], v[13]); - v[9] = add_512(v[9], v[14]); - v[5] = xor_512(v[5], v[10]); - v[6] = xor_512(v[6], v[11]); - v[7] = xor_512(v[7], v[8]); - v[4] = xor_512(v[4], v[9]); - v[5] = rot7_512(v[5]); - v[6] = rot7_512(v[6]); - v[7] = rot7_512(v[7]); - v[4] = rot7_512(v[4]); -} - -// 0b10001000, or lanes a0/a2/b0/b2 in little-endian order -#define LO_IMM8 0x88 - -INLINE __m512i unpack_lo_128(__m512i a, __m512i b) { - return _mm512_shuffle_i32x4(a, b, LO_IMM8); -} - -// 0b11011101, or lanes a1/a3/b1/b3 in little-endian order -#define HI_IMM8 0xdd - -INLINE __m512i unpack_hi_128(__m512i a, __m512i b) { - return _mm512_shuffle_i32x4(a, b, HI_IMM8); -} - -INLINE void transpose_vecs_512(__m512i vecs[16]) { - // Interleave 32-bit lanes. The _0 unpack is lanes - // 0/0/1/1/4/4/5/5/8/8/9/9/12/12/13/13, and the _2 unpack is lanes - // 2/2/3/3/6/6/7/7/10/10/11/11/14/14/15/15. - __m512i ab_0 = _mm512_unpacklo_epi32(vecs[0], vecs[1]); - __m512i ab_2 = _mm512_unpackhi_epi32(vecs[0], vecs[1]); - __m512i cd_0 = _mm512_unpacklo_epi32(vecs[2], vecs[3]); - __m512i cd_2 = _mm512_unpackhi_epi32(vecs[2], vecs[3]); - __m512i ef_0 = _mm512_unpacklo_epi32(vecs[4], vecs[5]); - __m512i ef_2 = _mm512_unpackhi_epi32(vecs[4], vecs[5]); - __m512i gh_0 = _mm512_unpacklo_epi32(vecs[6], vecs[7]); - __m512i gh_2 = _mm512_unpackhi_epi32(vecs[6], vecs[7]); - __m512i ij_0 = _mm512_unpacklo_epi32(vecs[8], vecs[9]); - __m512i ij_2 = _mm512_unpackhi_epi32(vecs[8], vecs[9]); - __m512i kl_0 = _mm512_unpacklo_epi32(vecs[10], vecs[11]); - __m512i kl_2 = _mm512_unpackhi_epi32(vecs[10], vecs[11]); - __m512i mn_0 = _mm512_unpacklo_epi32(vecs[12], vecs[13]); - __m512i mn_2 = _mm512_unpackhi_epi32(vecs[12], vecs[13]); - __m512i op_0 = _mm512_unpacklo_epi32(vecs[14], vecs[15]); - __m512i op_2 = _mm512_unpackhi_epi32(vecs[14], vecs[15]); - - // Interleave 64-bit lates. The _0 unpack is lanes - // 0/0/0/0/4/4/4/4/8/8/8/8/12/12/12/12, the _1 unpack is lanes - // 1/1/1/1/5/5/5/5/9/9/9/9/13/13/13/13, the _2 unpack is lanes - // 2/2/2/2/6/6/6/6/10/10/10/10/14/14/14/14, and the _3 unpack is lanes - // 3/3/3/3/7/7/7/7/11/11/11/11/15/15/15/15. - __m512i abcd_0 = _mm512_unpacklo_epi64(ab_0, cd_0); - __m512i abcd_1 = _mm512_unpackhi_epi64(ab_0, cd_0); - __m512i abcd_2 = _mm512_unpacklo_epi64(ab_2, cd_2); - __m512i abcd_3 = _mm512_unpackhi_epi64(ab_2, cd_2); - __m512i efgh_0 = _mm512_unpacklo_epi64(ef_0, gh_0); - __m512i efgh_1 = _mm512_unpackhi_epi64(ef_0, gh_0); - __m512i efgh_2 = _mm512_unpacklo_epi64(ef_2, gh_2); - __m512i efgh_3 = _mm512_unpackhi_epi64(ef_2, gh_2); - __m512i ijkl_0 = _mm512_unpacklo_epi64(ij_0, kl_0); - __m512i ijkl_1 = _mm512_unpackhi_epi64(ij_0, kl_0); - __m512i ijkl_2 = _mm512_unpacklo_epi64(ij_2, kl_2); - __m512i ijkl_3 = _mm512_unpackhi_epi64(ij_2, kl_2); - __m512i mnop_0 = _mm512_unpacklo_epi64(mn_0, op_0); - __m512i mnop_1 = _mm512_unpackhi_epi64(mn_0, op_0); - __m512i mnop_2 = _mm512_unpacklo_epi64(mn_2, op_2); - __m512i mnop_3 = _mm512_unpackhi_epi64(mn_2, op_2); - - // Interleave 128-bit lanes. The _0 unpack is - // 0/0/0/0/8/8/8/8/0/0/0/0/8/8/8/8, the _1 unpack is - // 1/1/1/1/9/9/9/9/1/1/1/1/9/9/9/9, and so on. - __m512i abcdefgh_0 = unpack_lo_128(abcd_0, efgh_0); - __m512i abcdefgh_1 = unpack_lo_128(abcd_1, efgh_1); - __m512i abcdefgh_2 = unpack_lo_128(abcd_2, efgh_2); - __m512i abcdefgh_3 = unpack_lo_128(abcd_3, efgh_3); - __m512i abcdefgh_4 = unpack_hi_128(abcd_0, efgh_0); - __m512i abcdefgh_5 = unpack_hi_128(abcd_1, efgh_1); - __m512i abcdefgh_6 = unpack_hi_128(abcd_2, efgh_2); - __m512i abcdefgh_7 = unpack_hi_128(abcd_3, efgh_3); - __m512i ijklmnop_0 = unpack_lo_128(ijkl_0, mnop_0); - __m512i ijklmnop_1 = unpack_lo_128(ijkl_1, mnop_1); - __m512i ijklmnop_2 = unpack_lo_128(ijkl_2, mnop_2); - __m512i ijklmnop_3 = unpack_lo_128(ijkl_3, mnop_3); - __m512i ijklmnop_4 = unpack_hi_128(ijkl_0, mnop_0); - __m512i ijklmnop_5 = unpack_hi_128(ijkl_1, mnop_1); - __m512i ijklmnop_6 = unpack_hi_128(ijkl_2, mnop_2); - __m512i ijklmnop_7 = unpack_hi_128(ijkl_3, mnop_3); - - // Interleave 128-bit lanes again for the final outputs. - vecs[0] = unpack_lo_128(abcdefgh_0, ijklmnop_0); - vecs[1] = unpack_lo_128(abcdefgh_1, ijklmnop_1); - vecs[2] = unpack_lo_128(abcdefgh_2, ijklmnop_2); - vecs[3] = unpack_lo_128(abcdefgh_3, ijklmnop_3); - vecs[4] = unpack_lo_128(abcdefgh_4, ijklmnop_4); - vecs[5] = unpack_lo_128(abcdefgh_5, ijklmnop_5); - vecs[6] = unpack_lo_128(abcdefgh_6, ijklmnop_6); - vecs[7] = unpack_lo_128(abcdefgh_7, ijklmnop_7); - vecs[8] = unpack_hi_128(abcdefgh_0, ijklmnop_0); - vecs[9] = unpack_hi_128(abcdefgh_1, ijklmnop_1); - vecs[10] = unpack_hi_128(abcdefgh_2, ijklmnop_2); - vecs[11] = unpack_hi_128(abcdefgh_3, ijklmnop_3); - vecs[12] = unpack_hi_128(abcdefgh_4, ijklmnop_4); - vecs[13] = unpack_hi_128(abcdefgh_5, ijklmnop_5); - vecs[14] = unpack_hi_128(abcdefgh_6, ijklmnop_6); - vecs[15] = unpack_hi_128(abcdefgh_7, ijklmnop_7); -} - -INLINE void transpose_msg_vecs16(const uint8_t *const *inputs, - size_t block_offset, __m512i out[16]) { - out[0] = loadu_512(&inputs[0][block_offset]); - out[1] = loadu_512(&inputs[1][block_offset]); - out[2] = loadu_512(&inputs[2][block_offset]); - out[3] = loadu_512(&inputs[3][block_offset]); - out[4] = loadu_512(&inputs[4][block_offset]); - out[5] = loadu_512(&inputs[5][block_offset]); - out[6] = loadu_512(&inputs[6][block_offset]); - out[7] = loadu_512(&inputs[7][block_offset]); - out[8] = loadu_512(&inputs[8][block_offset]); - out[9] = loadu_512(&inputs[9][block_offset]); - out[10] = loadu_512(&inputs[10][block_offset]); - out[11] = loadu_512(&inputs[11][block_offset]); - out[12] = loadu_512(&inputs[12][block_offset]); - out[13] = loadu_512(&inputs[13][block_offset]); - out[14] = loadu_512(&inputs[14][block_offset]); - out[15] = loadu_512(&inputs[15][block_offset]); - for (size_t i = 0; i < 16; ++i) { - _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); - } - transpose_vecs_512(out); -} - -INLINE void load_counters16(uint64_t counter, bool increment_counter, - __m512i *out_lo, __m512i *out_hi) { - const __m512i mask = _mm512_set1_epi32(-(int32_t)increment_counter); - const __m512i add0 = _mm512_set_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); - const __m512i add1 = _mm512_and_si512(mask, add0); - __m512i l = _mm512_add_epi32(_mm512_set1_epi32(counter), add1); - __mmask16 carry = _mm512_cmp_epu32_mask(l, add1, _MM_CMPINT_LT); - __m512i h = _mm512_mask_add_epi32(_mm512_set1_epi32(counter >> 32), carry, _mm512_set1_epi32(counter >> 32), _mm512_set1_epi32(1)); - *out_lo = l; - *out_hi = h; -} - -void blake3_hash16_avx512(const uint8_t *const *inputs, size_t blocks, - const uint32_t key[8], uint64_t counter, - bool increment_counter, uint8_t flags, - uint8_t flags_start, uint8_t flags_end, - uint8_t *out) { - __m512i h_vecs[8] = { - set1_512(key[0]), set1_512(key[1]), set1_512(key[2]), set1_512(key[3]), - set1_512(key[4]), set1_512(key[5]), set1_512(key[6]), set1_512(key[7]), - }; - __m512i counter_low_vec, counter_high_vec; - load_counters16(counter, increment_counter, &counter_low_vec, - &counter_high_vec); - uint8_t block_flags = flags | flags_start; - - for (size_t block = 0; block < blocks; block++) { - if (block + 1 == blocks) { - block_flags |= flags_end; - } - __m512i block_len_vec = set1_512(BLAKE3_BLOCK_LEN); - __m512i block_flags_vec = set1_512(block_flags); - __m512i msg_vecs[16]; - transpose_msg_vecs16(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); - - __m512i v[16] = { - h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], - h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], - set1_512(IV[0]), set1_512(IV[1]), set1_512(IV[2]), set1_512(IV[3]), - counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, - }; - round_fn16(v, msg_vecs, 0); - round_fn16(v, msg_vecs, 1); - round_fn16(v, msg_vecs, 2); - round_fn16(v, msg_vecs, 3); - round_fn16(v, msg_vecs, 4); - round_fn16(v, msg_vecs, 5); - round_fn16(v, msg_vecs, 6); - h_vecs[0] = xor_512(v[0], v[8]); - h_vecs[1] = xor_512(v[1], v[9]); - h_vecs[2] = xor_512(v[2], v[10]); - h_vecs[3] = xor_512(v[3], v[11]); - h_vecs[4] = xor_512(v[4], v[12]); - h_vecs[5] = xor_512(v[5], v[13]); - h_vecs[6] = xor_512(v[6], v[14]); - h_vecs[7] = xor_512(v[7], v[15]); - - block_flags = flags; - } - - // transpose_vecs_512 operates on a 16x16 matrix of words, but we only have 8 - // state vectors. Pad the matrix with zeros. After transposition, store the - // lower half of each vector. - __m512i padded[16] = { - h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], - h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], - set1_512(0), set1_512(0), set1_512(0), set1_512(0), - set1_512(0), set1_512(0), set1_512(0), set1_512(0), - }; - transpose_vecs_512(padded); - _mm256_mask_storeu_epi32(&out[0 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[0])); - _mm256_mask_storeu_epi32(&out[1 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[1])); - _mm256_mask_storeu_epi32(&out[2 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[2])); - _mm256_mask_storeu_epi32(&out[3 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[3])); - _mm256_mask_storeu_epi32(&out[4 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[4])); - _mm256_mask_storeu_epi32(&out[5 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[5])); - _mm256_mask_storeu_epi32(&out[6 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[6])); - _mm256_mask_storeu_epi32(&out[7 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[7])); - _mm256_mask_storeu_epi32(&out[8 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[8])); - _mm256_mask_storeu_epi32(&out[9 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[9])); - _mm256_mask_storeu_epi32(&out[10 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[10])); - _mm256_mask_storeu_epi32(&out[11 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[11])); - _mm256_mask_storeu_epi32(&out[12 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[12])); - _mm256_mask_storeu_epi32(&out[13 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[13])); - _mm256_mask_storeu_epi32(&out[14 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[14])); - _mm256_mask_storeu_epi32(&out[15 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[15])); -} - -/* - * ---------------------------------------------------------------------------- - * hash_many_avx512 - * ---------------------------------------------------------------------------- - */ - -INLINE void hash_one_avx512(const uint8_t *input, size_t blocks, - const uint32_t key[8], uint64_t counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t out[BLAKE3_OUT_LEN]) { - uint32_t cv[8]; - memcpy(cv, key, BLAKE3_KEY_LEN); - uint8_t block_flags = flags | flags_start; - while (blocks > 0) { - if (blocks == 1) { - block_flags |= flags_end; - } - blake3_compress_in_place_avx512(cv, input, BLAKE3_BLOCK_LEN, counter, - block_flags); - input = &input[BLAKE3_BLOCK_LEN]; - blocks -= 1; - block_flags = flags; - } - memcpy(out, cv, BLAKE3_OUT_LEN); -} - -void blake3_hash_many_avx512(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out) { - while (num_inputs >= 16) { - blake3_hash16_avx512(inputs, blocks, key, counter, increment_counter, flags, - flags_start, flags_end, out); - if (increment_counter) { - counter += 16; - } - inputs += 16; - num_inputs -= 16; - out = &out[16 * BLAKE3_OUT_LEN]; - } - while (num_inputs >= 8) { - blake3_hash8_avx512(inputs, blocks, key, counter, increment_counter, flags, - flags_start, flags_end, out); - if (increment_counter) { - counter += 8; - } - inputs += 8; - num_inputs -= 8; - out = &out[8 * BLAKE3_OUT_LEN]; - } - while (num_inputs >= 4) { - blake3_hash4_avx512(inputs, blocks, key, counter, increment_counter, flags, - flags_start, flags_end, out); - if (increment_counter) { - counter += 4; - } - inputs += 4; - num_inputs -= 4; - out = &out[4 * BLAKE3_OUT_LEN]; - } - while (num_inputs > 0) { - hash_one_avx512(inputs[0], blocks, key, counter, flags, flags_start, - flags_end, out); - if (increment_counter) { - counter += 1; - } - inputs += 1; - num_inputs -= 1; - out = &out[BLAKE3_OUT_LEN]; - } -} +#include "blake3_impl.h" + +#include + +#define _mm_shuffle_ps2(a, b, c) \ + (_mm_castps_si128( \ + _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c)))) + +INLINE __m128i loadu_128(const uint8_t src[16]) { + return _mm_loadu_si128((const __m128i *)src); +} + +INLINE __m256i loadu_256(const uint8_t src[32]) { + return _mm256_loadu_si256((const __m256i *)src); +} + +INLINE __m512i loadu_512(const uint8_t src[64]) { + return _mm512_loadu_si512((const __m512i *)src); +} + +INLINE void storeu_128(__m128i src, uint8_t dest[16]) { + _mm_storeu_si128((__m128i *)dest, src); +} + +INLINE void storeu_256(__m256i src, uint8_t dest[16]) { + _mm256_storeu_si256((__m256i *)dest, src); +} + +INLINE __m128i add_128(__m128i a, __m128i b) { return _mm_add_epi32(a, b); } + +INLINE __m256i add_256(__m256i a, __m256i b) { return _mm256_add_epi32(a, b); } + +INLINE __m512i add_512(__m512i a, __m512i b) { return _mm512_add_epi32(a, b); } + +INLINE __m128i xor_128(__m128i a, __m128i b) { return _mm_xor_si128(a, b); } + +INLINE __m256i xor_256(__m256i a, __m256i b) { return _mm256_xor_si256(a, b); } + +INLINE __m512i xor_512(__m512i a, __m512i b) { return _mm512_xor_si512(a, b); } + +INLINE __m128i set1_128(uint32_t x) { return _mm_set1_epi32((int32_t)x); } + +INLINE __m256i set1_256(uint32_t x) { return _mm256_set1_epi32((int32_t)x); } + +INLINE __m512i set1_512(uint32_t x) { return _mm512_set1_epi32((int32_t)x); } + +INLINE __m128i set4(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { + return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d); +} + +INLINE __m128i rot16_128(__m128i x) { return _mm_ror_epi32(x, 16); } + +INLINE __m256i rot16_256(__m256i x) { return _mm256_ror_epi32(x, 16); } + +INLINE __m512i rot16_512(__m512i x) { return _mm512_ror_epi32(x, 16); } + +INLINE __m128i rot12_128(__m128i x) { return _mm_ror_epi32(x, 12); } + +INLINE __m256i rot12_256(__m256i x) { return _mm256_ror_epi32(x, 12); } + +INLINE __m512i rot12_512(__m512i x) { return _mm512_ror_epi32(x, 12); } + +INLINE __m128i rot8_128(__m128i x) { return _mm_ror_epi32(x, 8); } + +INLINE __m256i rot8_256(__m256i x) { return _mm256_ror_epi32(x, 8); } + +INLINE __m512i rot8_512(__m512i x) { return _mm512_ror_epi32(x, 8); } + +INLINE __m128i rot7_128(__m128i x) { return _mm_ror_epi32(x, 7); } + +INLINE __m256i rot7_256(__m256i x) { return _mm256_ror_epi32(x, 7); } + +INLINE __m512i rot7_512(__m512i x) { return _mm512_ror_epi32(x, 7); } + +/* + * ---------------------------------------------------------------------------- + * compress_avx512 + * ---------------------------------------------------------------------------- + */ + +INLINE void g1(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, + __m128i m) { + *row0 = add_128(add_128(*row0, m), *row1); + *row3 = xor_128(*row3, *row0); + *row3 = rot16_128(*row3); + *row2 = add_128(*row2, *row3); + *row1 = xor_128(*row1, *row2); + *row1 = rot12_128(*row1); +} + +INLINE void g2(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, + __m128i m) { + *row0 = add_128(add_128(*row0, m), *row1); + *row3 = xor_128(*row3, *row0); + *row3 = rot8_128(*row3); + *row2 = add_128(*row2, *row3); + *row1 = xor_128(*row1, *row2); + *row1 = rot7_128(*row1); +} + +// Note the optimization here of leaving row1 as the unrotated row, rather than +// row0. All the message loads below are adjusted to compensate for this. See +// discussion at https://github.com/sneves/blake2-avx2/pull/4 +INLINE void diagonalize(__m128i *row0, __m128i *row2, __m128i *row3) { + *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3)); + *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2)); + *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1)); +} + +INLINE void undiagonalize(__m128i *row0, __m128i *row2, __m128i *row3) { + *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1)); + *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2)); + *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3)); +} + +INLINE void compress_pre(__m128i rows[4], const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, uint8_t flags) { + rows[0] = loadu_128((uint8_t *)&cv[0]); + rows[1] = loadu_128((uint8_t *)&cv[4]); + rows[2] = set4(IV[0], IV[1], IV[2], IV[3]); + rows[3] = set4(counter_low(counter), counter_high(counter), + (uint32_t)block_len, (uint32_t)flags); + + __m128i m0 = loadu_128(&block[sizeof(__m128i) * 0]); + __m128i m1 = loadu_128(&block[sizeof(__m128i) * 1]); + __m128i m2 = loadu_128(&block[sizeof(__m128i) * 2]); + __m128i m3 = loadu_128(&block[sizeof(__m128i) * 3]); + + __m128i t0, t1, t2, t3, tt; + + // Round 1. The first round permutes the message words from the original + // input order, into the groups that get mixed in parallel. + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0)); // 6 4 2 0 + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1)); // 7 5 3 1 + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0)); // 14 12 10 8 + t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3)); // 12 10 8 14 + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1)); // 15 13 11 9 + t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3)); // 13 11 9 15 + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 2. This round and all following rounds apply a fixed permutation + // to the message words from the round before. + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 3 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 4 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 5 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 6 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 7 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); +} + +void blake3_compress_xof_avx512(const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags, uint8_t out[64]) { + __m128i rows[4]; + compress_pre(rows, cv, block, block_len, counter, flags); + storeu_128(xor_128(rows[0], rows[2]), &out[0]); + storeu_128(xor_128(rows[1], rows[3]), &out[16]); + storeu_128(xor_128(rows[2], loadu_128((uint8_t *)&cv[0])), &out[32]); + storeu_128(xor_128(rows[3], loadu_128((uint8_t *)&cv[4])), &out[48]); +} + +void blake3_compress_in_place_avx512(uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags) { + __m128i rows[4]; + compress_pre(rows, cv, block, block_len, counter, flags); + storeu_128(xor_128(rows[0], rows[2]), (uint8_t *)&cv[0]); + storeu_128(xor_128(rows[1], rows[3]), (uint8_t *)&cv[4]); +} + +/* + * ---------------------------------------------------------------------------- + * hash4_avx512 + * ---------------------------------------------------------------------------- + */ + +INLINE void round_fn4(__m128i v[16], __m128i m[16], size_t r) { + v[0] = add_128(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); + v[1] = add_128(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); + v[2] = add_128(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); + v[3] = add_128(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); + v[0] = add_128(v[0], v[4]); + v[1] = add_128(v[1], v[5]); + v[2] = add_128(v[2], v[6]); + v[3] = add_128(v[3], v[7]); + v[12] = xor_128(v[12], v[0]); + v[13] = xor_128(v[13], v[1]); + v[14] = xor_128(v[14], v[2]); + v[15] = xor_128(v[15], v[3]); + v[12] = rot16_128(v[12]); + v[13] = rot16_128(v[13]); + v[14] = rot16_128(v[14]); + v[15] = rot16_128(v[15]); + v[8] = add_128(v[8], v[12]); + v[9] = add_128(v[9], v[13]); + v[10] = add_128(v[10], v[14]); + v[11] = add_128(v[11], v[15]); + v[4] = xor_128(v[4], v[8]); + v[5] = xor_128(v[5], v[9]); + v[6] = xor_128(v[6], v[10]); + v[7] = xor_128(v[7], v[11]); + v[4] = rot12_128(v[4]); + v[5] = rot12_128(v[5]); + v[6] = rot12_128(v[6]); + v[7] = rot12_128(v[7]); + v[0] = add_128(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); + v[1] = add_128(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); + v[2] = add_128(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); + v[3] = add_128(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); + v[0] = add_128(v[0], v[4]); + v[1] = add_128(v[1], v[5]); + v[2] = add_128(v[2], v[6]); + v[3] = add_128(v[3], v[7]); + v[12] = xor_128(v[12], v[0]); + v[13] = xor_128(v[13], v[1]); + v[14] = xor_128(v[14], v[2]); + v[15] = xor_128(v[15], v[3]); + v[12] = rot8_128(v[12]); + v[13] = rot8_128(v[13]); + v[14] = rot8_128(v[14]); + v[15] = rot8_128(v[15]); + v[8] = add_128(v[8], v[12]); + v[9] = add_128(v[9], v[13]); + v[10] = add_128(v[10], v[14]); + v[11] = add_128(v[11], v[15]); + v[4] = xor_128(v[4], v[8]); + v[5] = xor_128(v[5], v[9]); + v[6] = xor_128(v[6], v[10]); + v[7] = xor_128(v[7], v[11]); + v[4] = rot7_128(v[4]); + v[5] = rot7_128(v[5]); + v[6] = rot7_128(v[6]); + v[7] = rot7_128(v[7]); + + v[0] = add_128(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); + v[1] = add_128(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); + v[2] = add_128(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); + v[3] = add_128(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); + v[0] = add_128(v[0], v[5]); + v[1] = add_128(v[1], v[6]); + v[2] = add_128(v[2], v[7]); + v[3] = add_128(v[3], v[4]); + v[15] = xor_128(v[15], v[0]); + v[12] = xor_128(v[12], v[1]); + v[13] = xor_128(v[13], v[2]); + v[14] = xor_128(v[14], v[3]); + v[15] = rot16_128(v[15]); + v[12] = rot16_128(v[12]); + v[13] = rot16_128(v[13]); + v[14] = rot16_128(v[14]); + v[10] = add_128(v[10], v[15]); + v[11] = add_128(v[11], v[12]); + v[8] = add_128(v[8], v[13]); + v[9] = add_128(v[9], v[14]); + v[5] = xor_128(v[5], v[10]); + v[6] = xor_128(v[6], v[11]); + v[7] = xor_128(v[7], v[8]); + v[4] = xor_128(v[4], v[9]); + v[5] = rot12_128(v[5]); + v[6] = rot12_128(v[6]); + v[7] = rot12_128(v[7]); + v[4] = rot12_128(v[4]); + v[0] = add_128(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); + v[1] = add_128(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); + v[2] = add_128(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); + v[3] = add_128(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); + v[0] = add_128(v[0], v[5]); + v[1] = add_128(v[1], v[6]); + v[2] = add_128(v[2], v[7]); + v[3] = add_128(v[3], v[4]); + v[15] = xor_128(v[15], v[0]); + v[12] = xor_128(v[12], v[1]); + v[13] = xor_128(v[13], v[2]); + v[14] = xor_128(v[14], v[3]); + v[15] = rot8_128(v[15]); + v[12] = rot8_128(v[12]); + v[13] = rot8_128(v[13]); + v[14] = rot8_128(v[14]); + v[10] = add_128(v[10], v[15]); + v[11] = add_128(v[11], v[12]); + v[8] = add_128(v[8], v[13]); + v[9] = add_128(v[9], v[14]); + v[5] = xor_128(v[5], v[10]); + v[6] = xor_128(v[6], v[11]); + v[7] = xor_128(v[7], v[8]); + v[4] = xor_128(v[4], v[9]); + v[5] = rot7_128(v[5]); + v[6] = rot7_128(v[6]); + v[7] = rot7_128(v[7]); + v[4] = rot7_128(v[4]); +} + +INLINE void transpose_vecs_128(__m128i vecs[4]) { + // Interleave 32-bit lates. The low unpack is lanes 00/11 and the high is + // 22/33. Note that this doesn't split the vector into two lanes, as the + // AVX2 counterparts do. + __m128i ab_01 = _mm_unpacklo_epi32(vecs[0], vecs[1]); + __m128i ab_23 = _mm_unpackhi_epi32(vecs[0], vecs[1]); + __m128i cd_01 = _mm_unpacklo_epi32(vecs[2], vecs[3]); + __m128i cd_23 = _mm_unpackhi_epi32(vecs[2], vecs[3]); + + // Interleave 64-bit lanes. + __m128i abcd_0 = _mm_unpacklo_epi64(ab_01, cd_01); + __m128i abcd_1 = _mm_unpackhi_epi64(ab_01, cd_01); + __m128i abcd_2 = _mm_unpacklo_epi64(ab_23, cd_23); + __m128i abcd_3 = _mm_unpackhi_epi64(ab_23, cd_23); + + vecs[0] = abcd_0; + vecs[1] = abcd_1; + vecs[2] = abcd_2; + vecs[3] = abcd_3; +} + +INLINE void transpose_msg_vecs4(const uint8_t *const *inputs, + size_t block_offset, __m128i out[16]) { + out[0] = loadu_128(&inputs[0][block_offset + 0 * sizeof(__m128i)]); + out[1] = loadu_128(&inputs[1][block_offset + 0 * sizeof(__m128i)]); + out[2] = loadu_128(&inputs[2][block_offset + 0 * sizeof(__m128i)]); + out[3] = loadu_128(&inputs[3][block_offset + 0 * sizeof(__m128i)]); + out[4] = loadu_128(&inputs[0][block_offset + 1 * sizeof(__m128i)]); + out[5] = loadu_128(&inputs[1][block_offset + 1 * sizeof(__m128i)]); + out[6] = loadu_128(&inputs[2][block_offset + 1 * sizeof(__m128i)]); + out[7] = loadu_128(&inputs[3][block_offset + 1 * sizeof(__m128i)]); + out[8] = loadu_128(&inputs[0][block_offset + 2 * sizeof(__m128i)]); + out[9] = loadu_128(&inputs[1][block_offset + 2 * sizeof(__m128i)]); + out[10] = loadu_128(&inputs[2][block_offset + 2 * sizeof(__m128i)]); + out[11] = loadu_128(&inputs[3][block_offset + 2 * sizeof(__m128i)]); + out[12] = loadu_128(&inputs[0][block_offset + 3 * sizeof(__m128i)]); + out[13] = loadu_128(&inputs[1][block_offset + 3 * sizeof(__m128i)]); + out[14] = loadu_128(&inputs[2][block_offset + 3 * sizeof(__m128i)]); + out[15] = loadu_128(&inputs[3][block_offset + 3 * sizeof(__m128i)]); + for (size_t i = 0; i < 4; ++i) { + _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); + } + transpose_vecs_128(&out[0]); + transpose_vecs_128(&out[4]); + transpose_vecs_128(&out[8]); + transpose_vecs_128(&out[12]); +} + +INLINE void load_counters4(uint64_t counter, bool increment_counter, + __m128i *out_lo, __m128i *out_hi) { + uint64_t mask = (increment_counter ? ~0 : 0); + __m256i mask_vec = _mm256_set1_epi64x(mask); + __m256i deltas = _mm256_setr_epi64x(0, 1, 2, 3); + deltas = _mm256_and_si256(mask_vec, deltas); + __m256i counters = + _mm256_add_epi64(_mm256_set1_epi64x((int64_t)counter), deltas); + *out_lo = _mm256_cvtepi64_epi32(counters); + *out_hi = _mm256_cvtepi64_epi32(_mm256_srli_epi64(counters, 32)); +} + +void blake3_hash4_avx512(const uint8_t *const *inputs, size_t blocks, + const uint32_t key[8], uint64_t counter, + bool increment_counter, uint8_t flags, + uint8_t flags_start, uint8_t flags_end, uint8_t *out) { + __m128i h_vecs[8] = { + set1_128(key[0]), set1_128(key[1]), set1_128(key[2]), set1_128(key[3]), + set1_128(key[4]), set1_128(key[5]), set1_128(key[6]), set1_128(key[7]), + }; + __m128i counter_low_vec, counter_high_vec; + load_counters4(counter, increment_counter, &counter_low_vec, + &counter_high_vec); + uint8_t block_flags = flags | flags_start; + + for (size_t block = 0; block < blocks; block++) { + if (block + 1 == blocks) { + block_flags |= flags_end; + } + __m128i block_len_vec = set1_128(BLAKE3_BLOCK_LEN); + __m128i block_flags_vec = set1_128(block_flags); + __m128i msg_vecs[16]; + transpose_msg_vecs4(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); + + __m128i v[16] = { + h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], + h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], + set1_128(IV[0]), set1_128(IV[1]), set1_128(IV[2]), set1_128(IV[3]), + counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, + }; + round_fn4(v, msg_vecs, 0); + round_fn4(v, msg_vecs, 1); + round_fn4(v, msg_vecs, 2); + round_fn4(v, msg_vecs, 3); + round_fn4(v, msg_vecs, 4); + round_fn4(v, msg_vecs, 5); + round_fn4(v, msg_vecs, 6); + h_vecs[0] = xor_128(v[0], v[8]); + h_vecs[1] = xor_128(v[1], v[9]); + h_vecs[2] = xor_128(v[2], v[10]); + h_vecs[3] = xor_128(v[3], v[11]); + h_vecs[4] = xor_128(v[4], v[12]); + h_vecs[5] = xor_128(v[5], v[13]); + h_vecs[6] = xor_128(v[6], v[14]); + h_vecs[7] = xor_128(v[7], v[15]); + + block_flags = flags; + } + + transpose_vecs_128(&h_vecs[0]); + transpose_vecs_128(&h_vecs[4]); + // The first four vecs now contain the first half of each output, and the + // second four vecs contain the second half of each output. + storeu_128(h_vecs[0], &out[0 * sizeof(__m128i)]); + storeu_128(h_vecs[4], &out[1 * sizeof(__m128i)]); + storeu_128(h_vecs[1], &out[2 * sizeof(__m128i)]); + storeu_128(h_vecs[5], &out[3 * sizeof(__m128i)]); + storeu_128(h_vecs[2], &out[4 * sizeof(__m128i)]); + storeu_128(h_vecs[6], &out[5 * sizeof(__m128i)]); + storeu_128(h_vecs[3], &out[6 * sizeof(__m128i)]); + storeu_128(h_vecs[7], &out[7 * sizeof(__m128i)]); +} + +/* + * ---------------------------------------------------------------------------- + * hash8_avx512 + * ---------------------------------------------------------------------------- + */ + +INLINE void round_fn8(__m256i v[16], __m256i m[16], size_t r) { + v[0] = add_256(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); + v[1] = add_256(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); + v[2] = add_256(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); + v[3] = add_256(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); + v[0] = add_256(v[0], v[4]); + v[1] = add_256(v[1], v[5]); + v[2] = add_256(v[2], v[6]); + v[3] = add_256(v[3], v[7]); + v[12] = xor_256(v[12], v[0]); + v[13] = xor_256(v[13], v[1]); + v[14] = xor_256(v[14], v[2]); + v[15] = xor_256(v[15], v[3]); + v[12] = rot16_256(v[12]); + v[13] = rot16_256(v[13]); + v[14] = rot16_256(v[14]); + v[15] = rot16_256(v[15]); + v[8] = add_256(v[8], v[12]); + v[9] = add_256(v[9], v[13]); + v[10] = add_256(v[10], v[14]); + v[11] = add_256(v[11], v[15]); + v[4] = xor_256(v[4], v[8]); + v[5] = xor_256(v[5], v[9]); + v[6] = xor_256(v[6], v[10]); + v[7] = xor_256(v[7], v[11]); + v[4] = rot12_256(v[4]); + v[5] = rot12_256(v[5]); + v[6] = rot12_256(v[6]); + v[7] = rot12_256(v[7]); + v[0] = add_256(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); + v[1] = add_256(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); + v[2] = add_256(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); + v[3] = add_256(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); + v[0] = add_256(v[0], v[4]); + v[1] = add_256(v[1], v[5]); + v[2] = add_256(v[2], v[6]); + v[3] = add_256(v[3], v[7]); + v[12] = xor_256(v[12], v[0]); + v[13] = xor_256(v[13], v[1]); + v[14] = xor_256(v[14], v[2]); + v[15] = xor_256(v[15], v[3]); + v[12] = rot8_256(v[12]); + v[13] = rot8_256(v[13]); + v[14] = rot8_256(v[14]); + v[15] = rot8_256(v[15]); + v[8] = add_256(v[8], v[12]); + v[9] = add_256(v[9], v[13]); + v[10] = add_256(v[10], v[14]); + v[11] = add_256(v[11], v[15]); + v[4] = xor_256(v[4], v[8]); + v[5] = xor_256(v[5], v[9]); + v[6] = xor_256(v[6], v[10]); + v[7] = xor_256(v[7], v[11]); + v[4] = rot7_256(v[4]); + v[5] = rot7_256(v[5]); + v[6] = rot7_256(v[6]); + v[7] = rot7_256(v[7]); + + v[0] = add_256(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); + v[1] = add_256(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); + v[2] = add_256(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); + v[3] = add_256(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); + v[0] = add_256(v[0], v[5]); + v[1] = add_256(v[1], v[6]); + v[2] = add_256(v[2], v[7]); + v[3] = add_256(v[3], v[4]); + v[15] = xor_256(v[15], v[0]); + v[12] = xor_256(v[12], v[1]); + v[13] = xor_256(v[13], v[2]); + v[14] = xor_256(v[14], v[3]); + v[15] = rot16_256(v[15]); + v[12] = rot16_256(v[12]); + v[13] = rot16_256(v[13]); + v[14] = rot16_256(v[14]); + v[10] = add_256(v[10], v[15]); + v[11] = add_256(v[11], v[12]); + v[8] = add_256(v[8], v[13]); + v[9] = add_256(v[9], v[14]); + v[5] = xor_256(v[5], v[10]); + v[6] = xor_256(v[6], v[11]); + v[7] = xor_256(v[7], v[8]); + v[4] = xor_256(v[4], v[9]); + v[5] = rot12_256(v[5]); + v[6] = rot12_256(v[6]); + v[7] = rot12_256(v[7]); + v[4] = rot12_256(v[4]); + v[0] = add_256(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); + v[1] = add_256(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); + v[2] = add_256(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); + v[3] = add_256(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); + v[0] = add_256(v[0], v[5]); + v[1] = add_256(v[1], v[6]); + v[2] = add_256(v[2], v[7]); + v[3] = add_256(v[3], v[4]); + v[15] = xor_256(v[15], v[0]); + v[12] = xor_256(v[12], v[1]); + v[13] = xor_256(v[13], v[2]); + v[14] = xor_256(v[14], v[3]); + v[15] = rot8_256(v[15]); + v[12] = rot8_256(v[12]); + v[13] = rot8_256(v[13]); + v[14] = rot8_256(v[14]); + v[10] = add_256(v[10], v[15]); + v[11] = add_256(v[11], v[12]); + v[8] = add_256(v[8], v[13]); + v[9] = add_256(v[9], v[14]); + v[5] = xor_256(v[5], v[10]); + v[6] = xor_256(v[6], v[11]); + v[7] = xor_256(v[7], v[8]); + v[4] = xor_256(v[4], v[9]); + v[5] = rot7_256(v[5]); + v[6] = rot7_256(v[6]); + v[7] = rot7_256(v[7]); + v[4] = rot7_256(v[4]); +} + +INLINE void transpose_vecs_256(__m256i vecs[8]) { + // Interleave 32-bit lanes. The low unpack is lanes 00/11/44/55, and the high + // is 22/33/66/77. + __m256i ab_0145 = _mm256_unpacklo_epi32(vecs[0], vecs[1]); + __m256i ab_2367 = _mm256_unpackhi_epi32(vecs[0], vecs[1]); + __m256i cd_0145 = _mm256_unpacklo_epi32(vecs[2], vecs[3]); + __m256i cd_2367 = _mm256_unpackhi_epi32(vecs[2], vecs[3]); + __m256i ef_0145 = _mm256_unpacklo_epi32(vecs[4], vecs[5]); + __m256i ef_2367 = _mm256_unpackhi_epi32(vecs[4], vecs[5]); + __m256i gh_0145 = _mm256_unpacklo_epi32(vecs[6], vecs[7]); + __m256i gh_2367 = _mm256_unpackhi_epi32(vecs[6], vecs[7]); + + // Interleave 64-bit lates. The low unpack is lanes 00/22 and the high is + // 11/33. + __m256i abcd_04 = _mm256_unpacklo_epi64(ab_0145, cd_0145); + __m256i abcd_15 = _mm256_unpackhi_epi64(ab_0145, cd_0145); + __m256i abcd_26 = _mm256_unpacklo_epi64(ab_2367, cd_2367); + __m256i abcd_37 = _mm256_unpackhi_epi64(ab_2367, cd_2367); + __m256i efgh_04 = _mm256_unpacklo_epi64(ef_0145, gh_0145); + __m256i efgh_15 = _mm256_unpackhi_epi64(ef_0145, gh_0145); + __m256i efgh_26 = _mm256_unpacklo_epi64(ef_2367, gh_2367); + __m256i efgh_37 = _mm256_unpackhi_epi64(ef_2367, gh_2367); + + // Interleave 128-bit lanes. + vecs[0] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x20); + vecs[1] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x20); + vecs[2] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x20); + vecs[3] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x20); + vecs[4] = _mm256_permute2x128_si256(abcd_04, efgh_04, 0x31); + vecs[5] = _mm256_permute2x128_si256(abcd_15, efgh_15, 0x31); + vecs[6] = _mm256_permute2x128_si256(abcd_26, efgh_26, 0x31); + vecs[7] = _mm256_permute2x128_si256(abcd_37, efgh_37, 0x31); +} + +INLINE void transpose_msg_vecs8(const uint8_t *const *inputs, + size_t block_offset, __m256i out[16]) { + out[0] = loadu_256(&inputs[0][block_offset + 0 * sizeof(__m256i)]); + out[1] = loadu_256(&inputs[1][block_offset + 0 * sizeof(__m256i)]); + out[2] = loadu_256(&inputs[2][block_offset + 0 * sizeof(__m256i)]); + out[3] = loadu_256(&inputs[3][block_offset + 0 * sizeof(__m256i)]); + out[4] = loadu_256(&inputs[4][block_offset + 0 * sizeof(__m256i)]); + out[5] = loadu_256(&inputs[5][block_offset + 0 * sizeof(__m256i)]); + out[6] = loadu_256(&inputs[6][block_offset + 0 * sizeof(__m256i)]); + out[7] = loadu_256(&inputs[7][block_offset + 0 * sizeof(__m256i)]); + out[8] = loadu_256(&inputs[0][block_offset + 1 * sizeof(__m256i)]); + out[9] = loadu_256(&inputs[1][block_offset + 1 * sizeof(__m256i)]); + out[10] = loadu_256(&inputs[2][block_offset + 1 * sizeof(__m256i)]); + out[11] = loadu_256(&inputs[3][block_offset + 1 * sizeof(__m256i)]); + out[12] = loadu_256(&inputs[4][block_offset + 1 * sizeof(__m256i)]); + out[13] = loadu_256(&inputs[5][block_offset + 1 * sizeof(__m256i)]); + out[14] = loadu_256(&inputs[6][block_offset + 1 * sizeof(__m256i)]); + out[15] = loadu_256(&inputs[7][block_offset + 1 * sizeof(__m256i)]); + for (size_t i = 0; i < 8; ++i) { + _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); + } + transpose_vecs_256(&out[0]); + transpose_vecs_256(&out[8]); +} + +INLINE void load_counters8(uint64_t counter, bool increment_counter, + __m256i *out_lo, __m256i *out_hi) { + uint64_t mask = (increment_counter ? ~0 : 0); + __m512i mask_vec = _mm512_set1_epi64(mask); + __m512i deltas = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); + deltas = _mm512_and_si512(mask_vec, deltas); + __m512i counters = + _mm512_add_epi64(_mm512_set1_epi64((int64_t)counter), deltas); + *out_lo = _mm512_cvtepi64_epi32(counters); + *out_hi = _mm512_cvtepi64_epi32(_mm512_srli_epi64(counters, 32)); +} + +void blake3_hash8_avx512(const uint8_t *const *inputs, size_t blocks, + const uint32_t key[8], uint64_t counter, + bool increment_counter, uint8_t flags, + uint8_t flags_start, uint8_t flags_end, uint8_t *out) { + __m256i h_vecs[8] = { + set1_256(key[0]), set1_256(key[1]), set1_256(key[2]), set1_256(key[3]), + set1_256(key[4]), set1_256(key[5]), set1_256(key[6]), set1_256(key[7]), + }; + __m256i counter_low_vec, counter_high_vec; + load_counters8(counter, increment_counter, &counter_low_vec, + &counter_high_vec); + uint8_t block_flags = flags | flags_start; + + for (size_t block = 0; block < blocks; block++) { + if (block + 1 == blocks) { + block_flags |= flags_end; + } + __m256i block_len_vec = set1_256(BLAKE3_BLOCK_LEN); + __m256i block_flags_vec = set1_256(block_flags); + __m256i msg_vecs[16]; + transpose_msg_vecs8(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); + + __m256i v[16] = { + h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], + h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], + set1_256(IV[0]), set1_256(IV[1]), set1_256(IV[2]), set1_256(IV[3]), + counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, + }; + round_fn8(v, msg_vecs, 0); + round_fn8(v, msg_vecs, 1); + round_fn8(v, msg_vecs, 2); + round_fn8(v, msg_vecs, 3); + round_fn8(v, msg_vecs, 4); + round_fn8(v, msg_vecs, 5); + round_fn8(v, msg_vecs, 6); + h_vecs[0] = xor_256(v[0], v[8]); + h_vecs[1] = xor_256(v[1], v[9]); + h_vecs[2] = xor_256(v[2], v[10]); + h_vecs[3] = xor_256(v[3], v[11]); + h_vecs[4] = xor_256(v[4], v[12]); + h_vecs[5] = xor_256(v[5], v[13]); + h_vecs[6] = xor_256(v[6], v[14]); + h_vecs[7] = xor_256(v[7], v[15]); + + block_flags = flags; + } + + transpose_vecs_256(h_vecs); + storeu_256(h_vecs[0], &out[0 * sizeof(__m256i)]); + storeu_256(h_vecs[1], &out[1 * sizeof(__m256i)]); + storeu_256(h_vecs[2], &out[2 * sizeof(__m256i)]); + storeu_256(h_vecs[3], &out[3 * sizeof(__m256i)]); + storeu_256(h_vecs[4], &out[4 * sizeof(__m256i)]); + storeu_256(h_vecs[5], &out[5 * sizeof(__m256i)]); + storeu_256(h_vecs[6], &out[6 * sizeof(__m256i)]); + storeu_256(h_vecs[7], &out[7 * sizeof(__m256i)]); +} + +/* + * ---------------------------------------------------------------------------- + * hash16_avx512 + * ---------------------------------------------------------------------------- + */ + +INLINE void round_fn16(__m512i v[16], __m512i m[16], size_t r) { + v[0] = add_512(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); + v[1] = add_512(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); + v[2] = add_512(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); + v[3] = add_512(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); + v[0] = add_512(v[0], v[4]); + v[1] = add_512(v[1], v[5]); + v[2] = add_512(v[2], v[6]); + v[3] = add_512(v[3], v[7]); + v[12] = xor_512(v[12], v[0]); + v[13] = xor_512(v[13], v[1]); + v[14] = xor_512(v[14], v[2]); + v[15] = xor_512(v[15], v[3]); + v[12] = rot16_512(v[12]); + v[13] = rot16_512(v[13]); + v[14] = rot16_512(v[14]); + v[15] = rot16_512(v[15]); + v[8] = add_512(v[8], v[12]); + v[9] = add_512(v[9], v[13]); + v[10] = add_512(v[10], v[14]); + v[11] = add_512(v[11], v[15]); + v[4] = xor_512(v[4], v[8]); + v[5] = xor_512(v[5], v[9]); + v[6] = xor_512(v[6], v[10]); + v[7] = xor_512(v[7], v[11]); + v[4] = rot12_512(v[4]); + v[5] = rot12_512(v[5]); + v[6] = rot12_512(v[6]); + v[7] = rot12_512(v[7]); + v[0] = add_512(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); + v[1] = add_512(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); + v[2] = add_512(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); + v[3] = add_512(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); + v[0] = add_512(v[0], v[4]); + v[1] = add_512(v[1], v[5]); + v[2] = add_512(v[2], v[6]); + v[3] = add_512(v[3], v[7]); + v[12] = xor_512(v[12], v[0]); + v[13] = xor_512(v[13], v[1]); + v[14] = xor_512(v[14], v[2]); + v[15] = xor_512(v[15], v[3]); + v[12] = rot8_512(v[12]); + v[13] = rot8_512(v[13]); + v[14] = rot8_512(v[14]); + v[15] = rot8_512(v[15]); + v[8] = add_512(v[8], v[12]); + v[9] = add_512(v[9], v[13]); + v[10] = add_512(v[10], v[14]); + v[11] = add_512(v[11], v[15]); + v[4] = xor_512(v[4], v[8]); + v[5] = xor_512(v[5], v[9]); + v[6] = xor_512(v[6], v[10]); + v[7] = xor_512(v[7], v[11]); + v[4] = rot7_512(v[4]); + v[5] = rot7_512(v[5]); + v[6] = rot7_512(v[6]); + v[7] = rot7_512(v[7]); + + v[0] = add_512(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); + v[1] = add_512(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); + v[2] = add_512(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); + v[3] = add_512(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); + v[0] = add_512(v[0], v[5]); + v[1] = add_512(v[1], v[6]); + v[2] = add_512(v[2], v[7]); + v[3] = add_512(v[3], v[4]); + v[15] = xor_512(v[15], v[0]); + v[12] = xor_512(v[12], v[1]); + v[13] = xor_512(v[13], v[2]); + v[14] = xor_512(v[14], v[3]); + v[15] = rot16_512(v[15]); + v[12] = rot16_512(v[12]); + v[13] = rot16_512(v[13]); + v[14] = rot16_512(v[14]); + v[10] = add_512(v[10], v[15]); + v[11] = add_512(v[11], v[12]); + v[8] = add_512(v[8], v[13]); + v[9] = add_512(v[9], v[14]); + v[5] = xor_512(v[5], v[10]); + v[6] = xor_512(v[6], v[11]); + v[7] = xor_512(v[7], v[8]); + v[4] = xor_512(v[4], v[9]); + v[5] = rot12_512(v[5]); + v[6] = rot12_512(v[6]); + v[7] = rot12_512(v[7]); + v[4] = rot12_512(v[4]); + v[0] = add_512(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); + v[1] = add_512(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); + v[2] = add_512(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); + v[3] = add_512(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); + v[0] = add_512(v[0], v[5]); + v[1] = add_512(v[1], v[6]); + v[2] = add_512(v[2], v[7]); + v[3] = add_512(v[3], v[4]); + v[15] = xor_512(v[15], v[0]); + v[12] = xor_512(v[12], v[1]); + v[13] = xor_512(v[13], v[2]); + v[14] = xor_512(v[14], v[3]); + v[15] = rot8_512(v[15]); + v[12] = rot8_512(v[12]); + v[13] = rot8_512(v[13]); + v[14] = rot8_512(v[14]); + v[10] = add_512(v[10], v[15]); + v[11] = add_512(v[11], v[12]); + v[8] = add_512(v[8], v[13]); + v[9] = add_512(v[9], v[14]); + v[5] = xor_512(v[5], v[10]); + v[6] = xor_512(v[6], v[11]); + v[7] = xor_512(v[7], v[8]); + v[4] = xor_512(v[4], v[9]); + v[5] = rot7_512(v[5]); + v[6] = rot7_512(v[6]); + v[7] = rot7_512(v[7]); + v[4] = rot7_512(v[4]); +} + +// 0b10001000, or lanes a0/a2/b0/b2 in little-endian order +#define LO_IMM8 0x88 + +INLINE __m512i unpack_lo_128(__m512i a, __m512i b) { + return _mm512_shuffle_i32x4(a, b, LO_IMM8); +} + +// 0b11011101, or lanes a1/a3/b1/b3 in little-endian order +#define HI_IMM8 0xdd + +INLINE __m512i unpack_hi_128(__m512i a, __m512i b) { + return _mm512_shuffle_i32x4(a, b, HI_IMM8); +} + +INLINE void transpose_vecs_512(__m512i vecs[16]) { + // Interleave 32-bit lanes. The _0 unpack is lanes + // 0/0/1/1/4/4/5/5/8/8/9/9/12/12/13/13, and the _2 unpack is lanes + // 2/2/3/3/6/6/7/7/10/10/11/11/14/14/15/15. + __m512i ab_0 = _mm512_unpacklo_epi32(vecs[0], vecs[1]); + __m512i ab_2 = _mm512_unpackhi_epi32(vecs[0], vecs[1]); + __m512i cd_0 = _mm512_unpacklo_epi32(vecs[2], vecs[3]); + __m512i cd_2 = _mm512_unpackhi_epi32(vecs[2], vecs[3]); + __m512i ef_0 = _mm512_unpacklo_epi32(vecs[4], vecs[5]); + __m512i ef_2 = _mm512_unpackhi_epi32(vecs[4], vecs[5]); + __m512i gh_0 = _mm512_unpacklo_epi32(vecs[6], vecs[7]); + __m512i gh_2 = _mm512_unpackhi_epi32(vecs[6], vecs[7]); + __m512i ij_0 = _mm512_unpacklo_epi32(vecs[8], vecs[9]); + __m512i ij_2 = _mm512_unpackhi_epi32(vecs[8], vecs[9]); + __m512i kl_0 = _mm512_unpacklo_epi32(vecs[10], vecs[11]); + __m512i kl_2 = _mm512_unpackhi_epi32(vecs[10], vecs[11]); + __m512i mn_0 = _mm512_unpacklo_epi32(vecs[12], vecs[13]); + __m512i mn_2 = _mm512_unpackhi_epi32(vecs[12], vecs[13]); + __m512i op_0 = _mm512_unpacklo_epi32(vecs[14], vecs[15]); + __m512i op_2 = _mm512_unpackhi_epi32(vecs[14], vecs[15]); + + // Interleave 64-bit lates. The _0 unpack is lanes + // 0/0/0/0/4/4/4/4/8/8/8/8/12/12/12/12, the _1 unpack is lanes + // 1/1/1/1/5/5/5/5/9/9/9/9/13/13/13/13, the _2 unpack is lanes + // 2/2/2/2/6/6/6/6/10/10/10/10/14/14/14/14, and the _3 unpack is lanes + // 3/3/3/3/7/7/7/7/11/11/11/11/15/15/15/15. + __m512i abcd_0 = _mm512_unpacklo_epi64(ab_0, cd_0); + __m512i abcd_1 = _mm512_unpackhi_epi64(ab_0, cd_0); + __m512i abcd_2 = _mm512_unpacklo_epi64(ab_2, cd_2); + __m512i abcd_3 = _mm512_unpackhi_epi64(ab_2, cd_2); + __m512i efgh_0 = _mm512_unpacklo_epi64(ef_0, gh_0); + __m512i efgh_1 = _mm512_unpackhi_epi64(ef_0, gh_0); + __m512i efgh_2 = _mm512_unpacklo_epi64(ef_2, gh_2); + __m512i efgh_3 = _mm512_unpackhi_epi64(ef_2, gh_2); + __m512i ijkl_0 = _mm512_unpacklo_epi64(ij_0, kl_0); + __m512i ijkl_1 = _mm512_unpackhi_epi64(ij_0, kl_0); + __m512i ijkl_2 = _mm512_unpacklo_epi64(ij_2, kl_2); + __m512i ijkl_3 = _mm512_unpackhi_epi64(ij_2, kl_2); + __m512i mnop_0 = _mm512_unpacklo_epi64(mn_0, op_0); + __m512i mnop_1 = _mm512_unpackhi_epi64(mn_0, op_0); + __m512i mnop_2 = _mm512_unpacklo_epi64(mn_2, op_2); + __m512i mnop_3 = _mm512_unpackhi_epi64(mn_2, op_2); + + // Interleave 128-bit lanes. The _0 unpack is + // 0/0/0/0/8/8/8/8/0/0/0/0/8/8/8/8, the _1 unpack is + // 1/1/1/1/9/9/9/9/1/1/1/1/9/9/9/9, and so on. + __m512i abcdefgh_0 = unpack_lo_128(abcd_0, efgh_0); + __m512i abcdefgh_1 = unpack_lo_128(abcd_1, efgh_1); + __m512i abcdefgh_2 = unpack_lo_128(abcd_2, efgh_2); + __m512i abcdefgh_3 = unpack_lo_128(abcd_3, efgh_3); + __m512i abcdefgh_4 = unpack_hi_128(abcd_0, efgh_0); + __m512i abcdefgh_5 = unpack_hi_128(abcd_1, efgh_1); + __m512i abcdefgh_6 = unpack_hi_128(abcd_2, efgh_2); + __m512i abcdefgh_7 = unpack_hi_128(abcd_3, efgh_3); + __m512i ijklmnop_0 = unpack_lo_128(ijkl_0, mnop_0); + __m512i ijklmnop_1 = unpack_lo_128(ijkl_1, mnop_1); + __m512i ijklmnop_2 = unpack_lo_128(ijkl_2, mnop_2); + __m512i ijklmnop_3 = unpack_lo_128(ijkl_3, mnop_3); + __m512i ijklmnop_4 = unpack_hi_128(ijkl_0, mnop_0); + __m512i ijklmnop_5 = unpack_hi_128(ijkl_1, mnop_1); + __m512i ijklmnop_6 = unpack_hi_128(ijkl_2, mnop_2); + __m512i ijklmnop_7 = unpack_hi_128(ijkl_3, mnop_3); + + // Interleave 128-bit lanes again for the final outputs. + vecs[0] = unpack_lo_128(abcdefgh_0, ijklmnop_0); + vecs[1] = unpack_lo_128(abcdefgh_1, ijklmnop_1); + vecs[2] = unpack_lo_128(abcdefgh_2, ijklmnop_2); + vecs[3] = unpack_lo_128(abcdefgh_3, ijklmnop_3); + vecs[4] = unpack_lo_128(abcdefgh_4, ijklmnop_4); + vecs[5] = unpack_lo_128(abcdefgh_5, ijklmnop_5); + vecs[6] = unpack_lo_128(abcdefgh_6, ijklmnop_6); + vecs[7] = unpack_lo_128(abcdefgh_7, ijklmnop_7); + vecs[8] = unpack_hi_128(abcdefgh_0, ijklmnop_0); + vecs[9] = unpack_hi_128(abcdefgh_1, ijklmnop_1); + vecs[10] = unpack_hi_128(abcdefgh_2, ijklmnop_2); + vecs[11] = unpack_hi_128(abcdefgh_3, ijklmnop_3); + vecs[12] = unpack_hi_128(abcdefgh_4, ijklmnop_4); + vecs[13] = unpack_hi_128(abcdefgh_5, ijklmnop_5); + vecs[14] = unpack_hi_128(abcdefgh_6, ijklmnop_6); + vecs[15] = unpack_hi_128(abcdefgh_7, ijklmnop_7); +} + +INLINE void transpose_msg_vecs16(const uint8_t *const *inputs, + size_t block_offset, __m512i out[16]) { + out[0] = loadu_512(&inputs[0][block_offset]); + out[1] = loadu_512(&inputs[1][block_offset]); + out[2] = loadu_512(&inputs[2][block_offset]); + out[3] = loadu_512(&inputs[3][block_offset]); + out[4] = loadu_512(&inputs[4][block_offset]); + out[5] = loadu_512(&inputs[5][block_offset]); + out[6] = loadu_512(&inputs[6][block_offset]); + out[7] = loadu_512(&inputs[7][block_offset]); + out[8] = loadu_512(&inputs[8][block_offset]); + out[9] = loadu_512(&inputs[9][block_offset]); + out[10] = loadu_512(&inputs[10][block_offset]); + out[11] = loadu_512(&inputs[11][block_offset]); + out[12] = loadu_512(&inputs[12][block_offset]); + out[13] = loadu_512(&inputs[13][block_offset]); + out[14] = loadu_512(&inputs[14][block_offset]); + out[15] = loadu_512(&inputs[15][block_offset]); + for (size_t i = 0; i < 16; ++i) { + _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); + } + transpose_vecs_512(out); +} + +INLINE void load_counters16(uint64_t counter, bool increment_counter, + __m512i *out_lo, __m512i *out_hi) { + const __m512i mask = _mm512_set1_epi32(-(int32_t)increment_counter); + const __m512i add0 = _mm512_set_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); + const __m512i add1 = _mm512_and_si512(mask, add0); + __m512i l = _mm512_add_epi32(_mm512_set1_epi32(counter), add1); + __mmask16 carry = _mm512_cmp_epu32_mask(l, add1, _MM_CMPINT_LT); + __m512i h = _mm512_mask_add_epi32(_mm512_set1_epi32(counter >> 32), carry, _mm512_set1_epi32(counter >> 32), _mm512_set1_epi32(1)); + *out_lo = l; + *out_hi = h; +} + +void blake3_hash16_avx512(const uint8_t *const *inputs, size_t blocks, + const uint32_t key[8], uint64_t counter, + bool increment_counter, uint8_t flags, + uint8_t flags_start, uint8_t flags_end, + uint8_t *out) { + __m512i h_vecs[8] = { + set1_512(key[0]), set1_512(key[1]), set1_512(key[2]), set1_512(key[3]), + set1_512(key[4]), set1_512(key[5]), set1_512(key[6]), set1_512(key[7]), + }; + __m512i counter_low_vec, counter_high_vec; + load_counters16(counter, increment_counter, &counter_low_vec, + &counter_high_vec); + uint8_t block_flags = flags | flags_start; + + for (size_t block = 0; block < blocks; block++) { + if (block + 1 == blocks) { + block_flags |= flags_end; + } + __m512i block_len_vec = set1_512(BLAKE3_BLOCK_LEN); + __m512i block_flags_vec = set1_512(block_flags); + __m512i msg_vecs[16]; + transpose_msg_vecs16(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); + + __m512i v[16] = { + h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], + h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], + set1_512(IV[0]), set1_512(IV[1]), set1_512(IV[2]), set1_512(IV[3]), + counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, + }; + round_fn16(v, msg_vecs, 0); + round_fn16(v, msg_vecs, 1); + round_fn16(v, msg_vecs, 2); + round_fn16(v, msg_vecs, 3); + round_fn16(v, msg_vecs, 4); + round_fn16(v, msg_vecs, 5); + round_fn16(v, msg_vecs, 6); + h_vecs[0] = xor_512(v[0], v[8]); + h_vecs[1] = xor_512(v[1], v[9]); + h_vecs[2] = xor_512(v[2], v[10]); + h_vecs[3] = xor_512(v[3], v[11]); + h_vecs[4] = xor_512(v[4], v[12]); + h_vecs[5] = xor_512(v[5], v[13]); + h_vecs[6] = xor_512(v[6], v[14]); + h_vecs[7] = xor_512(v[7], v[15]); + + block_flags = flags; + } + + // transpose_vecs_512 operates on a 16x16 matrix of words, but we only have 8 + // state vectors. Pad the matrix with zeros. After transposition, store the + // lower half of each vector. + __m512i padded[16] = { + h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], + h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], + set1_512(0), set1_512(0), set1_512(0), set1_512(0), + set1_512(0), set1_512(0), set1_512(0), set1_512(0), + }; + transpose_vecs_512(padded); + _mm256_mask_storeu_epi32(&out[0 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[0])); + _mm256_mask_storeu_epi32(&out[1 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[1])); + _mm256_mask_storeu_epi32(&out[2 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[2])); + _mm256_mask_storeu_epi32(&out[3 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[3])); + _mm256_mask_storeu_epi32(&out[4 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[4])); + _mm256_mask_storeu_epi32(&out[5 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[5])); + _mm256_mask_storeu_epi32(&out[6 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[6])); + _mm256_mask_storeu_epi32(&out[7 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[7])); + _mm256_mask_storeu_epi32(&out[8 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[8])); + _mm256_mask_storeu_epi32(&out[9 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[9])); + _mm256_mask_storeu_epi32(&out[10 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[10])); + _mm256_mask_storeu_epi32(&out[11 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[11])); + _mm256_mask_storeu_epi32(&out[12 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[12])); + _mm256_mask_storeu_epi32(&out[13 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[13])); + _mm256_mask_storeu_epi32(&out[14 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[14])); + _mm256_mask_storeu_epi32(&out[15 * sizeof(__m256i)], (__mmask8)-1, _mm512_castsi512_si256(padded[15])); +} + +/* + * ---------------------------------------------------------------------------- + * hash_many_avx512 + * ---------------------------------------------------------------------------- + */ + +INLINE void hash_one_avx512(const uint8_t *input, size_t blocks, + const uint32_t key[8], uint64_t counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t out[BLAKE3_OUT_LEN]) { + uint32_t cv[8]; + memcpy(cv, key, BLAKE3_KEY_LEN); + uint8_t block_flags = flags | flags_start; + while (blocks > 0) { + if (blocks == 1) { + block_flags |= flags_end; + } + blake3_compress_in_place_avx512(cv, input, BLAKE3_BLOCK_LEN, counter, + block_flags); + input = &input[BLAKE3_BLOCK_LEN]; + blocks -= 1; + block_flags = flags; + } + memcpy(out, cv, BLAKE3_OUT_LEN); +} + +void blake3_hash_many_avx512(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out) { + while (num_inputs >= 16) { + blake3_hash16_avx512(inputs, blocks, key, counter, increment_counter, flags, + flags_start, flags_end, out); + if (increment_counter) { + counter += 16; + } + inputs += 16; + num_inputs -= 16; + out = &out[16 * BLAKE3_OUT_LEN]; + } + while (num_inputs >= 8) { + blake3_hash8_avx512(inputs, blocks, key, counter, increment_counter, flags, + flags_start, flags_end, out); + if (increment_counter) { + counter += 8; + } + inputs += 8; + num_inputs -= 8; + out = &out[8 * BLAKE3_OUT_LEN]; + } + while (num_inputs >= 4) { + blake3_hash4_avx512(inputs, blocks, key, counter, increment_counter, flags, + flags_start, flags_end, out); + if (increment_counter) { + counter += 4; + } + inputs += 4; + num_inputs -= 4; + out = &out[4 * BLAKE3_OUT_LEN]; + } + while (num_inputs > 0) { + hash_one_avx512(inputs[0], blocks, key, counter, flags, flags_start, + flags_end, out); + if (increment_counter) { + counter += 1; + } + inputs += 1; + num_inputs -= 1; + out = &out[BLAKE3_OUT_LEN]; + } +} diff --git a/src/b3/blake3_avx512_x86-64_unix.S b/src/b3/blake3_avx512_x86-64_unix.S index 621e1aa6..1fd5bae5 100644 --- a/src/b3/blake3_avx512_x86-64_unix.S +++ b/src/b3/blake3_avx512_x86-64_unix.S @@ -1,2572 +1,2572 @@ -#ifdef __x86_64__ -.intel_syntax noprefix - -.global _blake3_hash_many_avx512 -.global blake3_hash_many_avx512 -.global blake3_compress_in_place_avx512 -.global _blake3_compress_in_place_avx512 -.global blake3_compress_xof_avx512 -.global _blake3_compress_xof_avx512 - -#ifdef __APPLE__ -.text -#else -.section .text -#endif -.p2align 6 -_blake3_hash_many_avx512: -blake3_hash_many_avx512: - push r15 - push r14 - push r13 - push r12 - push rbx - push rbp - mov rbp, rsp - sub rsp, 144 - and rsp, 0xFFFFFFFFFFFFFFC0 - neg r9 - kmovw k1, r9d - vmovd xmm0, r8d - vpbroadcastd ymm0, xmm0 - shr r8, 32 - vmovd xmm1, r8d - vpbroadcastd ymm1, xmm1 - vmovdqa ymm4, ymm1 - vmovdqa ymm5, ymm1 - vpaddd ymm2, ymm0, ymmword ptr [ADD0+rip] - vpaddd ymm3, ymm0, ymmword ptr [ADD0+32+rip] - vpcmpltud k2, ymm2, ymm0 - vpcmpltud k3, ymm3, ymm0 - vpaddd ymm4 {k2}, ymm4, dword ptr [ADD1+rip] {1to8} - vpaddd ymm5 {k3}, ymm5, dword ptr [ADD1+rip] {1to8} - knotw k2, k1 - vmovdqa32 ymm2 {k2}, ymm0 - vmovdqa32 ymm3 {k2}, ymm0 - vmovdqa32 ymm4 {k2}, ymm1 - vmovdqa32 ymm5 {k2}, ymm1 - vmovdqa ymmword ptr [rsp], ymm2 - vmovdqa ymmword ptr [rsp+0x1*0x20], ymm3 - vmovdqa ymmword ptr [rsp+0x2*0x20], ymm4 - vmovdqa ymmword ptr [rsp+0x3*0x20], ymm5 - shl rdx, 6 - mov qword ptr [rsp+0x80], rdx - cmp rsi, 16 - jc 3f -2: - vpbroadcastd zmm0, dword ptr [rcx] - vpbroadcastd zmm1, dword ptr [rcx+0x1*0x4] - vpbroadcastd zmm2, dword ptr [rcx+0x2*0x4] - vpbroadcastd zmm3, dword ptr [rcx+0x3*0x4] - vpbroadcastd zmm4, dword ptr [rcx+0x4*0x4] - vpbroadcastd zmm5, dword ptr [rcx+0x5*0x4] - vpbroadcastd zmm6, dword ptr [rcx+0x6*0x4] - vpbroadcastd zmm7, dword ptr [rcx+0x7*0x4] - movzx eax, byte ptr [rbp+0x38] - movzx ebx, byte ptr [rbp+0x40] - or eax, ebx - xor edx, edx -.p2align 5 -9: - movzx ebx, byte ptr [rbp+0x48] - or ebx, eax - add rdx, 64 - cmp rdx, qword ptr [rsp+0x80] - cmove eax, ebx - mov dword ptr [rsp+0x88], eax - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - mov r10, qword ptr [rdi+0x10] - mov r11, qword ptr [rdi+0x18] - mov r12, qword ptr [rdi+0x40] - mov r13, qword ptr [rdi+0x48] - mov r14, qword ptr [rdi+0x50] - mov r15, qword ptr [rdi+0x58] - vmovdqu32 ymm16, ymmword ptr [rdx+r8-0x2*0x20] - vinserti64x4 zmm16, zmm16, ymmword ptr [rdx+r12-0x2*0x20], 0x01 - vmovdqu32 ymm17, ymmword ptr [rdx+r9-0x2*0x20] - vinserti64x4 zmm17, zmm17, ymmword ptr [rdx+r13-0x2*0x20], 0x01 - vpunpcklqdq zmm8, zmm16, zmm17 - vpunpckhqdq zmm9, zmm16, zmm17 - vmovdqu32 ymm18, ymmword ptr [rdx+r10-0x2*0x20] - vinserti64x4 zmm18, zmm18, ymmword ptr [rdx+r14-0x2*0x20], 0x01 - vmovdqu32 ymm19, ymmword ptr [rdx+r11-0x2*0x20] - vinserti64x4 zmm19, zmm19, ymmword ptr [rdx+r15-0x2*0x20], 0x01 - vpunpcklqdq zmm10, zmm18, zmm19 - vpunpckhqdq zmm11, zmm18, zmm19 - mov r8, qword ptr [rdi+0x20] - mov r9, qword ptr [rdi+0x28] - mov r10, qword ptr [rdi+0x30] - mov r11, qword ptr [rdi+0x38] - mov r12, qword ptr [rdi+0x60] - mov r13, qword ptr [rdi+0x68] - mov r14, qword ptr [rdi+0x70] - mov r15, qword ptr [rdi+0x78] - vmovdqu32 ymm16, ymmword ptr [rdx+r8-0x2*0x20] - vinserti64x4 zmm16, zmm16, ymmword ptr [rdx+r12-0x2*0x20], 0x01 - vmovdqu32 ymm17, ymmword ptr [rdx+r9-0x2*0x20] - vinserti64x4 zmm17, zmm17, ymmword ptr [rdx+r13-0x2*0x20], 0x01 - vpunpcklqdq zmm12, zmm16, zmm17 - vpunpckhqdq zmm13, zmm16, zmm17 - vmovdqu32 ymm18, ymmword ptr [rdx+r10-0x2*0x20] - vinserti64x4 zmm18, zmm18, ymmword ptr [rdx+r14-0x2*0x20], 0x01 - vmovdqu32 ymm19, ymmword ptr [rdx+r11-0x2*0x20] - vinserti64x4 zmm19, zmm19, ymmword ptr [rdx+r15-0x2*0x20], 0x01 - vpunpcklqdq zmm14, zmm18, zmm19 - vpunpckhqdq zmm15, zmm18, zmm19 - vmovdqa32 zmm27, zmmword ptr [INDEX0+rip] - vmovdqa32 zmm31, zmmword ptr [INDEX1+rip] - vshufps zmm16, zmm8, zmm10, 136 - vshufps zmm17, zmm12, zmm14, 136 - vmovdqa32 zmm20, zmm16 - vpermt2d zmm16, zmm27, zmm17 - vpermt2d zmm20, zmm31, zmm17 - vshufps zmm17, zmm8, zmm10, 221 - vshufps zmm30, zmm12, zmm14, 221 - vmovdqa32 zmm21, zmm17 - vpermt2d zmm17, zmm27, zmm30 - vpermt2d zmm21, zmm31, zmm30 - vshufps zmm18, zmm9, zmm11, 136 - vshufps zmm8, zmm13, zmm15, 136 - vmovdqa32 zmm22, zmm18 - vpermt2d zmm18, zmm27, zmm8 - vpermt2d zmm22, zmm31, zmm8 - vshufps zmm19, zmm9, zmm11, 221 - vshufps zmm8, zmm13, zmm15, 221 - vmovdqa32 zmm23, zmm19 - vpermt2d zmm19, zmm27, zmm8 - vpermt2d zmm23, zmm31, zmm8 - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - mov r10, qword ptr [rdi+0x10] - mov r11, qword ptr [rdi+0x18] - mov r12, qword ptr [rdi+0x40] - mov r13, qword ptr [rdi+0x48] - mov r14, qword ptr [rdi+0x50] - mov r15, qword ptr [rdi+0x58] - vmovdqu32 ymm24, ymmword ptr [r8+rdx-0x1*0x20] - vinserti64x4 zmm24, zmm24, ymmword ptr [r12+rdx-0x1*0x20], 0x01 - vmovdqu32 ymm25, ymmword ptr [r9+rdx-0x1*0x20] - vinserti64x4 zmm25, zmm25, ymmword ptr [r13+rdx-0x1*0x20], 0x01 - vpunpcklqdq zmm8, zmm24, zmm25 - vpunpckhqdq zmm9, zmm24, zmm25 - vmovdqu32 ymm24, ymmword ptr [r10+rdx-0x1*0x20] - vinserti64x4 zmm24, zmm24, ymmword ptr [r14+rdx-0x1*0x20], 0x01 - vmovdqu32 ymm25, ymmword ptr [r11+rdx-0x1*0x20] - vinserti64x4 zmm25, zmm25, ymmword ptr [r15+rdx-0x1*0x20], 0x01 - vpunpcklqdq zmm10, zmm24, zmm25 - vpunpckhqdq zmm11, zmm24, zmm25 - prefetcht0 [r8+rdx+0x80] - prefetcht0 [r12+rdx+0x80] - prefetcht0 [r9+rdx+0x80] - prefetcht0 [r13+rdx+0x80] - prefetcht0 [r10+rdx+0x80] - prefetcht0 [r14+rdx+0x80] - prefetcht0 [r11+rdx+0x80] - prefetcht0 [r15+rdx+0x80] - mov r8, qword ptr [rdi+0x20] - mov r9, qword ptr [rdi+0x28] - mov r10, qword ptr [rdi+0x30] - mov r11, qword ptr [rdi+0x38] - mov r12, qword ptr [rdi+0x60] - mov r13, qword ptr [rdi+0x68] - mov r14, qword ptr [rdi+0x70] - mov r15, qword ptr [rdi+0x78] - vmovdqu32 ymm24, ymmword ptr [r8+rdx-0x1*0x20] - vinserti64x4 zmm24, zmm24, ymmword ptr [r12+rdx-0x1*0x20], 0x01 - vmovdqu32 ymm25, ymmword ptr [r9+rdx-0x1*0x20] - vinserti64x4 zmm25, zmm25, ymmword ptr [r13+rdx-0x1*0x20], 0x01 - vpunpcklqdq zmm12, zmm24, zmm25 - vpunpckhqdq zmm13, zmm24, zmm25 - vmovdqu32 ymm24, ymmword ptr [r10+rdx-0x1*0x20] - vinserti64x4 zmm24, zmm24, ymmword ptr [r14+rdx-0x1*0x20], 0x01 - vmovdqu32 ymm25, ymmword ptr [r11+rdx-0x1*0x20] - vinserti64x4 zmm25, zmm25, ymmword ptr [r15+rdx-0x1*0x20], 0x01 - vpunpcklqdq zmm14, zmm24, zmm25 - vpunpckhqdq zmm15, zmm24, zmm25 - prefetcht0 [r8+rdx+0x80] - prefetcht0 [r12+rdx+0x80] - prefetcht0 [r9+rdx+0x80] - prefetcht0 [r13+rdx+0x80] - prefetcht0 [r10+rdx+0x80] - prefetcht0 [r14+rdx+0x80] - prefetcht0 [r11+rdx+0x80] - prefetcht0 [r15+rdx+0x80] - vshufps zmm24, zmm8, zmm10, 136 - vshufps zmm30, zmm12, zmm14, 136 - vmovdqa32 zmm28, zmm24 - vpermt2d zmm24, zmm27, zmm30 - vpermt2d zmm28, zmm31, zmm30 - vshufps zmm25, zmm8, zmm10, 221 - vshufps zmm30, zmm12, zmm14, 221 - vmovdqa32 zmm29, zmm25 - vpermt2d zmm25, zmm27, zmm30 - vpermt2d zmm29, zmm31, zmm30 - vshufps zmm26, zmm9, zmm11, 136 - vshufps zmm8, zmm13, zmm15, 136 - vmovdqa32 zmm30, zmm26 - vpermt2d zmm26, zmm27, zmm8 - vpermt2d zmm30, zmm31, zmm8 - vshufps zmm8, zmm9, zmm11, 221 - vshufps zmm10, zmm13, zmm15, 221 - vpermi2d zmm27, zmm8, zmm10 - vpermi2d zmm31, zmm8, zmm10 - vpbroadcastd zmm8, dword ptr [BLAKE3_IV_0+rip] - vpbroadcastd zmm9, dword ptr [BLAKE3_IV_1+rip] - vpbroadcastd zmm10, dword ptr [BLAKE3_IV_2+rip] - vpbroadcastd zmm11, dword ptr [BLAKE3_IV_3+rip] - vmovdqa32 zmm12, zmmword ptr [rsp] - vmovdqa32 zmm13, zmmword ptr [rsp+0x1*0x40] - vpbroadcastd zmm14, dword ptr [BLAKE3_BLOCK_LEN+rip] - vpbroadcastd zmm15, dword ptr [rsp+0x22*0x4] - vpaddd zmm0, zmm0, zmm16 - vpaddd zmm1, zmm1, zmm18 - vpaddd zmm2, zmm2, zmm20 - vpaddd zmm3, zmm3, zmm22 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vprord zmm15, zmm15, 16 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 12 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vpaddd zmm0, zmm0, zmm17 - vpaddd zmm1, zmm1, zmm19 - vpaddd zmm2, zmm2, zmm21 - vpaddd zmm3, zmm3, zmm23 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vprord zmm15, zmm15, 8 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 7 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vpaddd zmm0, zmm0, zmm24 - vpaddd zmm1, zmm1, zmm26 - vpaddd zmm2, zmm2, zmm28 - vpaddd zmm3, zmm3, zmm30 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 16 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vprord zmm4, zmm4, 12 - vpaddd zmm0, zmm0, zmm25 - vpaddd zmm1, zmm1, zmm27 - vpaddd zmm2, zmm2, zmm29 - vpaddd zmm3, zmm3, zmm31 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 8 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vprord zmm4, zmm4, 7 - vpaddd zmm0, zmm0, zmm18 - vpaddd zmm1, zmm1, zmm19 - vpaddd zmm2, zmm2, zmm23 - vpaddd zmm3, zmm3, zmm20 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vprord zmm15, zmm15, 16 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 12 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vpaddd zmm0, zmm0, zmm22 - vpaddd zmm1, zmm1, zmm26 - vpaddd zmm2, zmm2, zmm16 - vpaddd zmm3, zmm3, zmm29 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vprord zmm15, zmm15, 8 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 7 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vpaddd zmm0, zmm0, zmm17 - vpaddd zmm1, zmm1, zmm28 - vpaddd zmm2, zmm2, zmm25 - vpaddd zmm3, zmm3, zmm31 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 16 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vprord zmm4, zmm4, 12 - vpaddd zmm0, zmm0, zmm27 - vpaddd zmm1, zmm1, zmm21 - vpaddd zmm2, zmm2, zmm30 - vpaddd zmm3, zmm3, zmm24 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 8 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vprord zmm4, zmm4, 7 - vpaddd zmm0, zmm0, zmm19 - vpaddd zmm1, zmm1, zmm26 - vpaddd zmm2, zmm2, zmm29 - vpaddd zmm3, zmm3, zmm23 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vprord zmm15, zmm15, 16 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 12 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vpaddd zmm0, zmm0, zmm20 - vpaddd zmm1, zmm1, zmm28 - vpaddd zmm2, zmm2, zmm18 - vpaddd zmm3, zmm3, zmm30 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vprord zmm15, zmm15, 8 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 7 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vpaddd zmm0, zmm0, zmm22 - vpaddd zmm1, zmm1, zmm25 - vpaddd zmm2, zmm2, zmm27 - vpaddd zmm3, zmm3, zmm24 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 16 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vprord zmm4, zmm4, 12 - vpaddd zmm0, zmm0, zmm21 - vpaddd zmm1, zmm1, zmm16 - vpaddd zmm2, zmm2, zmm31 - vpaddd zmm3, zmm3, zmm17 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 8 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vprord zmm4, zmm4, 7 - vpaddd zmm0, zmm0, zmm26 - vpaddd zmm1, zmm1, zmm28 - vpaddd zmm2, zmm2, zmm30 - vpaddd zmm3, zmm3, zmm29 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vprord zmm15, zmm15, 16 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 12 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vpaddd zmm0, zmm0, zmm23 - vpaddd zmm1, zmm1, zmm25 - vpaddd zmm2, zmm2, zmm19 - vpaddd zmm3, zmm3, zmm31 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vprord zmm15, zmm15, 8 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 7 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vpaddd zmm0, zmm0, zmm20 - vpaddd zmm1, zmm1, zmm27 - vpaddd zmm2, zmm2, zmm21 - vpaddd zmm3, zmm3, zmm17 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 16 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vprord zmm4, zmm4, 12 - vpaddd zmm0, zmm0, zmm16 - vpaddd zmm1, zmm1, zmm18 - vpaddd zmm2, zmm2, zmm24 - vpaddd zmm3, zmm3, zmm22 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 8 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vprord zmm4, zmm4, 7 - vpaddd zmm0, zmm0, zmm28 - vpaddd zmm1, zmm1, zmm25 - vpaddd zmm2, zmm2, zmm31 - vpaddd zmm3, zmm3, zmm30 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vprord zmm15, zmm15, 16 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 12 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vpaddd zmm0, zmm0, zmm29 - vpaddd zmm1, zmm1, zmm27 - vpaddd zmm2, zmm2, zmm26 - vpaddd zmm3, zmm3, zmm24 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vprord zmm15, zmm15, 8 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 7 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vpaddd zmm0, zmm0, zmm23 - vpaddd zmm1, zmm1, zmm21 - vpaddd zmm2, zmm2, zmm16 - vpaddd zmm3, zmm3, zmm22 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 16 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vprord zmm4, zmm4, 12 - vpaddd zmm0, zmm0, zmm18 - vpaddd zmm1, zmm1, zmm19 - vpaddd zmm2, zmm2, zmm17 - vpaddd zmm3, zmm3, zmm20 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 8 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vprord zmm4, zmm4, 7 - vpaddd zmm0, zmm0, zmm25 - vpaddd zmm1, zmm1, zmm27 - vpaddd zmm2, zmm2, zmm24 - vpaddd zmm3, zmm3, zmm31 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vprord zmm15, zmm15, 16 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 12 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vpaddd zmm0, zmm0, zmm30 - vpaddd zmm1, zmm1, zmm21 - vpaddd zmm2, zmm2, zmm28 - vpaddd zmm3, zmm3, zmm17 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vprord zmm15, zmm15, 8 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 7 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vpaddd zmm0, zmm0, zmm29 - vpaddd zmm1, zmm1, zmm16 - vpaddd zmm2, zmm2, zmm18 - vpaddd zmm3, zmm3, zmm20 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 16 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vprord zmm4, zmm4, 12 - vpaddd zmm0, zmm0, zmm19 - vpaddd zmm1, zmm1, zmm26 - vpaddd zmm2, zmm2, zmm22 - vpaddd zmm3, zmm3, zmm23 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 8 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vprord zmm4, zmm4, 7 - vpaddd zmm0, zmm0, zmm27 - vpaddd zmm1, zmm1, zmm21 - vpaddd zmm2, zmm2, zmm17 - vpaddd zmm3, zmm3, zmm24 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vprord zmm15, zmm15, 16 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 12 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vpaddd zmm0, zmm0, zmm31 - vpaddd zmm1, zmm1, zmm16 - vpaddd zmm2, zmm2, zmm25 - vpaddd zmm3, zmm3, zmm22 - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm1, zmm1, zmm5 - vpaddd zmm2, zmm2, zmm6 - vpaddd zmm3, zmm3, zmm7 - vpxord zmm12, zmm12, zmm0 - vpxord zmm13, zmm13, zmm1 - vpxord zmm14, zmm14, zmm2 - vpxord zmm15, zmm15, zmm3 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vprord zmm15, zmm15, 8 - vpaddd zmm8, zmm8, zmm12 - vpaddd zmm9, zmm9, zmm13 - vpaddd zmm10, zmm10, zmm14 - vpaddd zmm11, zmm11, zmm15 - vpxord zmm4, zmm4, zmm8 - vpxord zmm5, zmm5, zmm9 - vpxord zmm6, zmm6, zmm10 - vpxord zmm7, zmm7, zmm11 - vprord zmm4, zmm4, 7 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vpaddd zmm0, zmm0, zmm30 - vpaddd zmm1, zmm1, zmm18 - vpaddd zmm2, zmm2, zmm19 - vpaddd zmm3, zmm3, zmm23 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 16 - vprord zmm12, zmm12, 16 - vprord zmm13, zmm13, 16 - vprord zmm14, zmm14, 16 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 12 - vprord zmm6, zmm6, 12 - vprord zmm7, zmm7, 12 - vprord zmm4, zmm4, 12 - vpaddd zmm0, zmm0, zmm26 - vpaddd zmm1, zmm1, zmm28 - vpaddd zmm2, zmm2, zmm20 - vpaddd zmm3, zmm3, zmm29 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm1, zmm1, zmm6 - vpaddd zmm2, zmm2, zmm7 - vpaddd zmm3, zmm3, zmm4 - vpxord zmm15, zmm15, zmm0 - vpxord zmm12, zmm12, zmm1 - vpxord zmm13, zmm13, zmm2 - vpxord zmm14, zmm14, zmm3 - vprord zmm15, zmm15, 8 - vprord zmm12, zmm12, 8 - vprord zmm13, zmm13, 8 - vprord zmm14, zmm14, 8 - vpaddd zmm10, zmm10, zmm15 - vpaddd zmm11, zmm11, zmm12 - vpaddd zmm8, zmm8, zmm13 - vpaddd zmm9, zmm9, zmm14 - vpxord zmm5, zmm5, zmm10 - vpxord zmm6, zmm6, zmm11 - vpxord zmm7, zmm7, zmm8 - vpxord zmm4, zmm4, zmm9 - vprord zmm5, zmm5, 7 - vprord zmm6, zmm6, 7 - vprord zmm7, zmm7, 7 - vprord zmm4, zmm4, 7 - vpxord zmm0, zmm0, zmm8 - vpxord zmm1, zmm1, zmm9 - vpxord zmm2, zmm2, zmm10 - vpxord zmm3, zmm3, zmm11 - vpxord zmm4, zmm4, zmm12 - vpxord zmm5, zmm5, zmm13 - vpxord zmm6, zmm6, zmm14 - vpxord zmm7, zmm7, zmm15 - movzx eax, byte ptr [rbp+0x38] - jne 9b - mov rbx, qword ptr [rbp+0x50] - vpunpckldq zmm16, zmm0, zmm1 - vpunpckhdq zmm17, zmm0, zmm1 - vpunpckldq zmm18, zmm2, zmm3 - vpunpckhdq zmm19, zmm2, zmm3 - vpunpckldq zmm20, zmm4, zmm5 - vpunpckhdq zmm21, zmm4, zmm5 - vpunpckldq zmm22, zmm6, zmm7 - vpunpckhdq zmm23, zmm6, zmm7 - vpunpcklqdq zmm0, zmm16, zmm18 - vpunpckhqdq zmm1, zmm16, zmm18 - vpunpcklqdq zmm2, zmm17, zmm19 - vpunpckhqdq zmm3, zmm17, zmm19 - vpunpcklqdq zmm4, zmm20, zmm22 - vpunpckhqdq zmm5, zmm20, zmm22 - vpunpcklqdq zmm6, zmm21, zmm23 - vpunpckhqdq zmm7, zmm21, zmm23 - vshufi32x4 zmm16, zmm0, zmm4, 0x88 - vshufi32x4 zmm17, zmm1, zmm5, 0x88 - vshufi32x4 zmm18, zmm2, zmm6, 0x88 - vshufi32x4 zmm19, zmm3, zmm7, 0x88 - vshufi32x4 zmm20, zmm0, zmm4, 0xDD - vshufi32x4 zmm21, zmm1, zmm5, 0xDD - vshufi32x4 zmm22, zmm2, zmm6, 0xDD - vshufi32x4 zmm23, zmm3, zmm7, 0xDD - vshufi32x4 zmm0, zmm16, zmm17, 0x88 - vshufi32x4 zmm1, zmm18, zmm19, 0x88 - vshufi32x4 zmm2, zmm20, zmm21, 0x88 - vshufi32x4 zmm3, zmm22, zmm23, 0x88 - vshufi32x4 zmm4, zmm16, zmm17, 0xDD - vshufi32x4 zmm5, zmm18, zmm19, 0xDD - vshufi32x4 zmm6, zmm20, zmm21, 0xDD - vshufi32x4 zmm7, zmm22, zmm23, 0xDD - vmovdqu32 zmmword ptr [rbx], zmm0 - vmovdqu32 zmmword ptr [rbx+0x1*0x40], zmm1 - vmovdqu32 zmmword ptr [rbx+0x2*0x40], zmm2 - vmovdqu32 zmmword ptr [rbx+0x3*0x40], zmm3 - vmovdqu32 zmmword ptr [rbx+0x4*0x40], zmm4 - vmovdqu32 zmmword ptr [rbx+0x5*0x40], zmm5 - vmovdqu32 zmmword ptr [rbx+0x6*0x40], zmm6 - vmovdqu32 zmmword ptr [rbx+0x7*0x40], zmm7 - vmovdqa32 zmm0, zmmword ptr [rsp] - vmovdqa32 zmm1, zmmword ptr [rsp+0x1*0x40] - vmovdqa32 zmm2, zmm0 - vpaddd zmm2{k1}, zmm0, dword ptr [ADD16+rip] {1to16} - vpcmpltud k2, zmm2, zmm0 - vpaddd zmm1 {k2}, zmm1, dword ptr [ADD1+rip] {1to16} - vmovdqa32 zmmword ptr [rsp], zmm2 - vmovdqa32 zmmword ptr [rsp+0x1*0x40], zmm1 - add rdi, 128 - add rbx, 512 - mov qword ptr [rbp+0x50], rbx - sub rsi, 16 - cmp rsi, 16 - jnc 2b - test rsi, rsi - jnz 3f -4: - vzeroupper - mov rsp, rbp - pop rbp - pop rbx - pop r12 - pop r13 - pop r14 - pop r15 - ret -.p2align 6 -3: - test esi, 0x8 - je 3f - vpbroadcastd ymm0, dword ptr [rcx] - vpbroadcastd ymm1, dword ptr [rcx+0x4] - vpbroadcastd ymm2, dword ptr [rcx+0x8] - vpbroadcastd ymm3, dword ptr [rcx+0xC] - vpbroadcastd ymm4, dword ptr [rcx+0x10] - vpbroadcastd ymm5, dword ptr [rcx+0x14] - vpbroadcastd ymm6, dword ptr [rcx+0x18] - vpbroadcastd ymm7, dword ptr [rcx+0x1C] - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - mov r10, qword ptr [rdi+0x10] - mov r11, qword ptr [rdi+0x18] - mov r12, qword ptr [rdi+0x20] - mov r13, qword ptr [rdi+0x28] - mov r14, qword ptr [rdi+0x30] - mov r15, qword ptr [rdi+0x38] - movzx eax, byte ptr [rbp+0x38] - movzx ebx, byte ptr [rbp+0x40] - or eax, ebx - xor edx, edx -2: - movzx ebx, byte ptr [rbp+0x48] - or ebx, eax - add rdx, 64 - cmp rdx, qword ptr [rsp+0x80] - cmove eax, ebx - mov dword ptr [rsp+0x88], eax - vmovups xmm8, xmmword ptr [r8+rdx-0x40] - vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x40], 0x01 - vmovups xmm9, xmmword ptr [r9+rdx-0x40] - vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x40], 0x01 - vunpcklpd ymm12, ymm8, ymm9 - vunpckhpd ymm13, ymm8, ymm9 - vmovups xmm10, xmmword ptr [r10+rdx-0x40] - vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x40], 0x01 - vmovups xmm11, xmmword ptr [r11+rdx-0x40] - vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x40], 0x01 - vunpcklpd ymm14, ymm10, ymm11 - vunpckhpd ymm15, ymm10, ymm11 - vshufps ymm16, ymm12, ymm14, 136 - vshufps ymm17, ymm12, ymm14, 221 - vshufps ymm18, ymm13, ymm15, 136 - vshufps ymm19, ymm13, ymm15, 221 - vmovups xmm8, xmmword ptr [r8+rdx-0x30] - vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x30], 0x01 - vmovups xmm9, xmmword ptr [r9+rdx-0x30] - vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x30], 0x01 - vunpcklpd ymm12, ymm8, ymm9 - vunpckhpd ymm13, ymm8, ymm9 - vmovups xmm10, xmmword ptr [r10+rdx-0x30] - vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x30], 0x01 - vmovups xmm11, xmmword ptr [r11+rdx-0x30] - vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x30], 0x01 - vunpcklpd ymm14, ymm10, ymm11 - vunpckhpd ymm15, ymm10, ymm11 - vshufps ymm20, ymm12, ymm14, 136 - vshufps ymm21, ymm12, ymm14, 221 - vshufps ymm22, ymm13, ymm15, 136 - vshufps ymm23, ymm13, ymm15, 221 - vmovups xmm8, xmmword ptr [r8+rdx-0x20] - vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x20], 0x01 - vmovups xmm9, xmmword ptr [r9+rdx-0x20] - vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x20], 0x01 - vunpcklpd ymm12, ymm8, ymm9 - vunpckhpd ymm13, ymm8, ymm9 - vmovups xmm10, xmmword ptr [r10+rdx-0x20] - vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x20], 0x01 - vmovups xmm11, xmmword ptr [r11+rdx-0x20] - vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x20], 0x01 - vunpcklpd ymm14, ymm10, ymm11 - vunpckhpd ymm15, ymm10, ymm11 - vshufps ymm24, ymm12, ymm14, 136 - vshufps ymm25, ymm12, ymm14, 221 - vshufps ymm26, ymm13, ymm15, 136 - vshufps ymm27, ymm13, ymm15, 221 - vmovups xmm8, xmmword ptr [r8+rdx-0x10] - vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x10], 0x01 - vmovups xmm9, xmmword ptr [r9+rdx-0x10] - vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x10], 0x01 - vunpcklpd ymm12, ymm8, ymm9 - vunpckhpd ymm13, ymm8, ymm9 - vmovups xmm10, xmmword ptr [r10+rdx-0x10] - vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x10], 0x01 - vmovups xmm11, xmmword ptr [r11+rdx-0x10] - vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x10], 0x01 - vunpcklpd ymm14, ymm10, ymm11 - vunpckhpd ymm15, ymm10, ymm11 - vshufps ymm28, ymm12, ymm14, 136 - vshufps ymm29, ymm12, ymm14, 221 - vshufps ymm30, ymm13, ymm15, 136 - vshufps ymm31, ymm13, ymm15, 221 - vpbroadcastd ymm8, dword ptr [BLAKE3_IV_0+rip] - vpbroadcastd ymm9, dword ptr [BLAKE3_IV_1+rip] - vpbroadcastd ymm10, dword ptr [BLAKE3_IV_2+rip] - vpbroadcastd ymm11, dword ptr [BLAKE3_IV_3+rip] - vmovdqa ymm12, ymmword ptr [rsp] - vmovdqa ymm13, ymmword ptr [rsp+0x40] - vpbroadcastd ymm14, dword ptr [BLAKE3_BLOCK_LEN+rip] - vpbroadcastd ymm15, dword ptr [rsp+0x88] - vpaddd ymm0, ymm0, ymm16 - vpaddd ymm1, ymm1, ymm18 - vpaddd ymm2, ymm2, ymm20 - vpaddd ymm3, ymm3, ymm22 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vprord ymm15, ymm15, 16 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 12 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vpaddd ymm0, ymm0, ymm17 - vpaddd ymm1, ymm1, ymm19 - vpaddd ymm2, ymm2, ymm21 - vpaddd ymm3, ymm3, ymm23 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vprord ymm15, ymm15, 8 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 7 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vpaddd ymm0, ymm0, ymm24 - vpaddd ymm1, ymm1, ymm26 - vpaddd ymm2, ymm2, ymm28 - vpaddd ymm3, ymm3, ymm30 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 16 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vprord ymm4, ymm4, 12 - vpaddd ymm0, ymm0, ymm25 - vpaddd ymm1, ymm1, ymm27 - vpaddd ymm2, ymm2, ymm29 - vpaddd ymm3, ymm3, ymm31 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 8 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vprord ymm4, ymm4, 7 - vpaddd ymm0, ymm0, ymm18 - vpaddd ymm1, ymm1, ymm19 - vpaddd ymm2, ymm2, ymm23 - vpaddd ymm3, ymm3, ymm20 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vprord ymm15, ymm15, 16 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 12 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vpaddd ymm0, ymm0, ymm22 - vpaddd ymm1, ymm1, ymm26 - vpaddd ymm2, ymm2, ymm16 - vpaddd ymm3, ymm3, ymm29 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vprord ymm15, ymm15, 8 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 7 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vpaddd ymm0, ymm0, ymm17 - vpaddd ymm1, ymm1, ymm28 - vpaddd ymm2, ymm2, ymm25 - vpaddd ymm3, ymm3, ymm31 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 16 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vprord ymm4, ymm4, 12 - vpaddd ymm0, ymm0, ymm27 - vpaddd ymm1, ymm1, ymm21 - vpaddd ymm2, ymm2, ymm30 - vpaddd ymm3, ymm3, ymm24 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 8 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vprord ymm4, ymm4, 7 - vpaddd ymm0, ymm0, ymm19 - vpaddd ymm1, ymm1, ymm26 - vpaddd ymm2, ymm2, ymm29 - vpaddd ymm3, ymm3, ymm23 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vprord ymm15, ymm15, 16 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 12 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vpaddd ymm0, ymm0, ymm20 - vpaddd ymm1, ymm1, ymm28 - vpaddd ymm2, ymm2, ymm18 - vpaddd ymm3, ymm3, ymm30 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vprord ymm15, ymm15, 8 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 7 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vpaddd ymm0, ymm0, ymm22 - vpaddd ymm1, ymm1, ymm25 - vpaddd ymm2, ymm2, ymm27 - vpaddd ymm3, ymm3, ymm24 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 16 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vprord ymm4, ymm4, 12 - vpaddd ymm0, ymm0, ymm21 - vpaddd ymm1, ymm1, ymm16 - vpaddd ymm2, ymm2, ymm31 - vpaddd ymm3, ymm3, ymm17 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 8 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vprord ymm4, ymm4, 7 - vpaddd ymm0, ymm0, ymm26 - vpaddd ymm1, ymm1, ymm28 - vpaddd ymm2, ymm2, ymm30 - vpaddd ymm3, ymm3, ymm29 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vprord ymm15, ymm15, 16 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 12 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vpaddd ymm0, ymm0, ymm23 - vpaddd ymm1, ymm1, ymm25 - vpaddd ymm2, ymm2, ymm19 - vpaddd ymm3, ymm3, ymm31 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vprord ymm15, ymm15, 8 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 7 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vpaddd ymm0, ymm0, ymm20 - vpaddd ymm1, ymm1, ymm27 - vpaddd ymm2, ymm2, ymm21 - vpaddd ymm3, ymm3, ymm17 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 16 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vprord ymm4, ymm4, 12 - vpaddd ymm0, ymm0, ymm16 - vpaddd ymm1, ymm1, ymm18 - vpaddd ymm2, ymm2, ymm24 - vpaddd ymm3, ymm3, ymm22 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 8 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vprord ymm4, ymm4, 7 - vpaddd ymm0, ymm0, ymm28 - vpaddd ymm1, ymm1, ymm25 - vpaddd ymm2, ymm2, ymm31 - vpaddd ymm3, ymm3, ymm30 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vprord ymm15, ymm15, 16 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 12 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vpaddd ymm0, ymm0, ymm29 - vpaddd ymm1, ymm1, ymm27 - vpaddd ymm2, ymm2, ymm26 - vpaddd ymm3, ymm3, ymm24 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vprord ymm15, ymm15, 8 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 7 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vpaddd ymm0, ymm0, ymm23 - vpaddd ymm1, ymm1, ymm21 - vpaddd ymm2, ymm2, ymm16 - vpaddd ymm3, ymm3, ymm22 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 16 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vprord ymm4, ymm4, 12 - vpaddd ymm0, ymm0, ymm18 - vpaddd ymm1, ymm1, ymm19 - vpaddd ymm2, ymm2, ymm17 - vpaddd ymm3, ymm3, ymm20 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 8 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vprord ymm4, ymm4, 7 - vpaddd ymm0, ymm0, ymm25 - vpaddd ymm1, ymm1, ymm27 - vpaddd ymm2, ymm2, ymm24 - vpaddd ymm3, ymm3, ymm31 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vprord ymm15, ymm15, 16 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 12 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vpaddd ymm0, ymm0, ymm30 - vpaddd ymm1, ymm1, ymm21 - vpaddd ymm2, ymm2, ymm28 - vpaddd ymm3, ymm3, ymm17 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vprord ymm15, ymm15, 8 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 7 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vpaddd ymm0, ymm0, ymm29 - vpaddd ymm1, ymm1, ymm16 - vpaddd ymm2, ymm2, ymm18 - vpaddd ymm3, ymm3, ymm20 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 16 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vprord ymm4, ymm4, 12 - vpaddd ymm0, ymm0, ymm19 - vpaddd ymm1, ymm1, ymm26 - vpaddd ymm2, ymm2, ymm22 - vpaddd ymm3, ymm3, ymm23 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 8 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vprord ymm4, ymm4, 7 - vpaddd ymm0, ymm0, ymm27 - vpaddd ymm1, ymm1, ymm21 - vpaddd ymm2, ymm2, ymm17 - vpaddd ymm3, ymm3, ymm24 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vprord ymm15, ymm15, 16 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 12 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vpaddd ymm0, ymm0, ymm31 - vpaddd ymm1, ymm1, ymm16 - vpaddd ymm2, ymm2, ymm25 - vpaddd ymm3, ymm3, ymm22 - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm1, ymm1, ymm5 - vpaddd ymm2, ymm2, ymm6 - vpaddd ymm3, ymm3, ymm7 - vpxord ymm12, ymm12, ymm0 - vpxord ymm13, ymm13, ymm1 - vpxord ymm14, ymm14, ymm2 - vpxord ymm15, ymm15, ymm3 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vprord ymm15, ymm15, 8 - vpaddd ymm8, ymm8, ymm12 - vpaddd ymm9, ymm9, ymm13 - vpaddd ymm10, ymm10, ymm14 - vpaddd ymm11, ymm11, ymm15 - vpxord ymm4, ymm4, ymm8 - vpxord ymm5, ymm5, ymm9 - vpxord ymm6, ymm6, ymm10 - vpxord ymm7, ymm7, ymm11 - vprord ymm4, ymm4, 7 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vpaddd ymm0, ymm0, ymm30 - vpaddd ymm1, ymm1, ymm18 - vpaddd ymm2, ymm2, ymm19 - vpaddd ymm3, ymm3, ymm23 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 16 - vprord ymm12, ymm12, 16 - vprord ymm13, ymm13, 16 - vprord ymm14, ymm14, 16 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 12 - vprord ymm6, ymm6, 12 - vprord ymm7, ymm7, 12 - vprord ymm4, ymm4, 12 - vpaddd ymm0, ymm0, ymm26 - vpaddd ymm1, ymm1, ymm28 - vpaddd ymm2, ymm2, ymm20 - vpaddd ymm3, ymm3, ymm29 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm1, ymm1, ymm6 - vpaddd ymm2, ymm2, ymm7 - vpaddd ymm3, ymm3, ymm4 - vpxord ymm15, ymm15, ymm0 - vpxord ymm12, ymm12, ymm1 - vpxord ymm13, ymm13, ymm2 - vpxord ymm14, ymm14, ymm3 - vprord ymm15, ymm15, 8 - vprord ymm12, ymm12, 8 - vprord ymm13, ymm13, 8 - vprord ymm14, ymm14, 8 - vpaddd ymm10, ymm10, ymm15 - vpaddd ymm11, ymm11, ymm12 - vpaddd ymm8, ymm8, ymm13 - vpaddd ymm9, ymm9, ymm14 - vpxord ymm5, ymm5, ymm10 - vpxord ymm6, ymm6, ymm11 - vpxord ymm7, ymm7, ymm8 - vpxord ymm4, ymm4, ymm9 - vprord ymm5, ymm5, 7 - vprord ymm6, ymm6, 7 - vprord ymm7, ymm7, 7 - vprord ymm4, ymm4, 7 - vpxor ymm0, ymm0, ymm8 - vpxor ymm1, ymm1, ymm9 - vpxor ymm2, ymm2, ymm10 - vpxor ymm3, ymm3, ymm11 - vpxor ymm4, ymm4, ymm12 - vpxor ymm5, ymm5, ymm13 - vpxor ymm6, ymm6, ymm14 - vpxor ymm7, ymm7, ymm15 - movzx eax, byte ptr [rbp+0x38] - jne 2b - mov rbx, qword ptr [rbp+0x50] - vunpcklps ymm8, ymm0, ymm1 - vunpcklps ymm9, ymm2, ymm3 - vunpckhps ymm10, ymm0, ymm1 - vunpcklps ymm11, ymm4, ymm5 - vunpcklps ymm0, ymm6, ymm7 - vshufps ymm12, ymm8, ymm9, 78 - vblendps ymm1, ymm8, ymm12, 0xCC - vshufps ymm8, ymm11, ymm0, 78 - vunpckhps ymm13, ymm2, ymm3 - vblendps ymm2, ymm11, ymm8, 0xCC - vblendps ymm3, ymm12, ymm9, 0xCC - vperm2f128 ymm12, ymm1, ymm2, 0x20 - vmovups ymmword ptr [rbx], ymm12 - vunpckhps ymm14, ymm4, ymm5 - vblendps ymm4, ymm8, ymm0, 0xCC - vunpckhps ymm15, ymm6, ymm7 - vperm2f128 ymm7, ymm3, ymm4, 0x20 - vmovups ymmword ptr [rbx+0x20], ymm7 - vshufps ymm5, ymm10, ymm13, 78 - vblendps ymm6, ymm5, ymm13, 0xCC - vshufps ymm13, ymm14, ymm15, 78 - vblendps ymm10, ymm10, ymm5, 0xCC - vblendps ymm14, ymm14, ymm13, 0xCC - vperm2f128 ymm8, ymm10, ymm14, 0x20 - vmovups ymmword ptr [rbx+0x40], ymm8 - vblendps ymm15, ymm13, ymm15, 0xCC - vperm2f128 ymm13, ymm6, ymm15, 0x20 - vmovups ymmword ptr [rbx+0x60], ymm13 - vperm2f128 ymm9, ymm1, ymm2, 0x31 - vperm2f128 ymm11, ymm3, ymm4, 0x31 - vmovups ymmword ptr [rbx+0x80], ymm9 - vperm2f128 ymm14, ymm10, ymm14, 0x31 - vperm2f128 ymm15, ymm6, ymm15, 0x31 - vmovups ymmword ptr [rbx+0xA0], ymm11 - vmovups ymmword ptr [rbx+0xC0], ymm14 - vmovups ymmword ptr [rbx+0xE0], ymm15 - vmovdqa ymm0, ymmword ptr [rsp] - vmovdqa ymm2, ymmword ptr [rsp+0x2*0x20] - vmovdqa32 ymm0 {k1}, ymmword ptr [rsp+0x1*0x20] - vmovdqa32 ymm2 {k1}, ymmword ptr [rsp+0x3*0x20] - vmovdqa ymmword ptr [rsp], ymm0 - vmovdqa ymmword ptr [rsp+0x2*0x20], ymm2 - add rbx, 256 - mov qword ptr [rbp+0x50], rbx - add rdi, 64 - sub rsi, 8 -3: - mov rbx, qword ptr [rbp+0x50] - mov r15, qword ptr [rsp+0x80] - movzx r13, byte ptr [rbp+0x38] - movzx r12, byte ptr [rbp+0x48] - test esi, 0x4 - je 3f - vbroadcasti32x4 zmm0, xmmword ptr [rcx] - vbroadcasti32x4 zmm1, xmmword ptr [rcx+0x1*0x10] - vmovdqa xmm12, xmmword ptr [rsp] - vmovdqa xmm13, xmmword ptr [rsp+0x4*0x10] - vpunpckldq xmm14, xmm12, xmm13 - vpunpckhdq xmm15, xmm12, xmm13 - vpermq ymm14, ymm14, 0xDC - vpermq ymm15, ymm15, 0xDC - vpbroadcastd zmm12, dword ptr [BLAKE3_BLOCK_LEN+rip] - vinserti64x4 zmm13, zmm14, ymm15, 0x01 - mov eax, 17476 - kmovw k2, eax - vpblendmd zmm13 {k2}, zmm13, zmm12 - vbroadcasti32x4 zmm15, xmmword ptr [BLAKE3_IV+rip] - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - mov r10, qword ptr [rdi+0x10] - mov r11, qword ptr [rdi+0x18] - mov eax, 43690 - kmovw k3, eax - mov eax, 34952 - kmovw k4, eax - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -.p2align 5 -2: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - mov dword ptr [rsp+0x88], eax - vmovdqa32 zmm2, zmm15 - vpbroadcastd zmm8, dword ptr [rsp+0x22*0x4] - vpblendmd zmm3 {k4}, zmm13, zmm8 - vmovups zmm8, zmmword ptr [r8+rdx-0x1*0x40] - vinserti32x4 zmm8, zmm8, xmmword ptr [r9+rdx-0x4*0x10], 0x01 - vinserti32x4 zmm8, zmm8, xmmword ptr [r10+rdx-0x4*0x10], 0x02 - vinserti32x4 zmm8, zmm8, xmmword ptr [r11+rdx-0x4*0x10], 0x03 - vmovups zmm9, zmmword ptr [r8+rdx-0x30] - vinserti32x4 zmm9, zmm9, xmmword ptr [r9+rdx-0x3*0x10], 0x01 - vinserti32x4 zmm9, zmm9, xmmword ptr [r10+rdx-0x3*0x10], 0x02 - vinserti32x4 zmm9, zmm9, xmmword ptr [r11+rdx-0x3*0x10], 0x03 - vshufps zmm4, zmm8, zmm9, 136 - vshufps zmm5, zmm8, zmm9, 221 - vmovups zmm8, zmmword ptr [r8+rdx-0x20] - vinserti32x4 zmm8, zmm8, xmmword ptr [r9+rdx-0x2*0x10], 0x01 - vinserti32x4 zmm8, zmm8, xmmword ptr [r10+rdx-0x2*0x10], 0x02 - vinserti32x4 zmm8, zmm8, xmmword ptr [r11+rdx-0x2*0x10], 0x03 - vmovups zmm9, zmmword ptr [r8+rdx-0x10] - vinserti32x4 zmm9, zmm9, xmmword ptr [r9+rdx-0x1*0x10], 0x01 - vinserti32x4 zmm9, zmm9, xmmword ptr [r10+rdx-0x1*0x10], 0x02 - vinserti32x4 zmm9, zmm9, xmmword ptr [r11+rdx-0x1*0x10], 0x03 - vshufps zmm6, zmm8, zmm9, 136 - vshufps zmm7, zmm8, zmm9, 221 - vpshufd zmm6, zmm6, 0x93 - vpshufd zmm7, zmm7, 0x93 - mov al, 7 -9: - vpaddd zmm0, zmm0, zmm4 - vpaddd zmm0, zmm0, zmm1 - vpxord zmm3, zmm3, zmm0 - vprord zmm3, zmm3, 16 - vpaddd zmm2, zmm2, zmm3 - vpxord zmm1, zmm1, zmm2 - vprord zmm1, zmm1, 12 - vpaddd zmm0, zmm0, zmm5 - vpaddd zmm0, zmm0, zmm1 - vpxord zmm3, zmm3, zmm0 - vprord zmm3, zmm3, 8 - vpaddd zmm2, zmm2, zmm3 - vpxord zmm1, zmm1, zmm2 - vprord zmm1, zmm1, 7 - vpshufd zmm0, zmm0, 0x93 - vpshufd zmm3, zmm3, 0x4E - vpshufd zmm2, zmm2, 0x39 - vpaddd zmm0, zmm0, zmm6 - vpaddd zmm0, zmm0, zmm1 - vpxord zmm3, zmm3, zmm0 - vprord zmm3, zmm3, 16 - vpaddd zmm2, zmm2, zmm3 - vpxord zmm1, zmm1, zmm2 - vprord zmm1, zmm1, 12 - vpaddd zmm0, zmm0, zmm7 - vpaddd zmm0, zmm0, zmm1 - vpxord zmm3, zmm3, zmm0 - vprord zmm3, zmm3, 8 - vpaddd zmm2, zmm2, zmm3 - vpxord zmm1, zmm1, zmm2 - vprord zmm1, zmm1, 7 - vpshufd zmm0, zmm0, 0x39 - vpshufd zmm3, zmm3, 0x4E - vpshufd zmm2, zmm2, 0x93 - dec al - jz 9f - vshufps zmm8, zmm4, zmm5, 214 - vpshufd zmm9, zmm4, 0x0F - vpshufd zmm4, zmm8, 0x39 - vshufps zmm8, zmm6, zmm7, 250 - vpblendmd zmm9 {k3}, zmm9, zmm8 - vpunpcklqdq zmm8, zmm7, zmm5 - vpblendmd zmm8 {k4}, zmm8, zmm6 - vpshufd zmm8, zmm8, 0x78 - vpunpckhdq zmm5, zmm5, zmm7 - vpunpckldq zmm6, zmm6, zmm5 - vpshufd zmm7, zmm6, 0x1E - vmovdqa32 zmm5, zmm9 - vmovdqa32 zmm6, zmm8 - jmp 9b -9: - vpxord zmm0, zmm0, zmm2 - vpxord zmm1, zmm1, zmm3 - mov eax, r13d - cmp rdx, r15 - jne 2b - vmovdqu xmmword ptr [rbx], xmm0 - vmovdqu xmmword ptr [rbx+0x10], xmm1 - vextracti128 xmmword ptr [rbx+0x20], ymm0, 0x01 - vextracti128 xmmword ptr [rbx+0x30], ymm1, 0x01 - vextracti32x4 xmmword ptr [rbx+0x4*0x10], zmm0, 0x02 - vextracti32x4 xmmword ptr [rbx+0x5*0x10], zmm1, 0x02 - vextracti32x4 xmmword ptr [rbx+0x6*0x10], zmm0, 0x03 - vextracti32x4 xmmword ptr [rbx+0x7*0x10], zmm1, 0x03 - vmovdqa xmm0, xmmword ptr [rsp] - vmovdqa xmm2, xmmword ptr [rsp+0x40] - vmovdqa32 xmm0 {k1}, xmmword ptr [rsp+0x1*0x10] - vmovdqa32 xmm2 {k1}, xmmword ptr [rsp+0x5*0x10] - vmovdqa xmmword ptr [rsp], xmm0 - vmovdqa xmmword ptr [rsp+0x40], xmm2 - add rbx, 128 - add rdi, 32 - sub rsi, 4 -3: - test esi, 0x2 - je 3f - vbroadcasti128 ymm0, xmmword ptr [rcx] - vbroadcasti128 ymm1, xmmword ptr [rcx+0x10] - vmovd xmm13, dword ptr [rsp] - vpinsrd xmm13, xmm13, dword ptr [rsp+0x40], 1 - vpinsrd xmm13, xmm13, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - vmovd xmm14, dword ptr [rsp+0x4] - vpinsrd xmm14, xmm14, dword ptr [rsp+0x44], 1 - vpinsrd xmm14, xmm14, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - vinserti128 ymm13, ymm13, xmm14, 0x01 - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -.p2align 5 -2: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - mov dword ptr [rsp+0x88], eax - vbroadcasti128 ymm2, xmmword ptr [BLAKE3_IV+rip] - vpbroadcastd ymm8, dword ptr [rsp+0x88] - vpblendd ymm3, ymm13, ymm8, 0x88 - vmovups ymm8, ymmword ptr [r8+rdx-0x40] - vinsertf128 ymm8, ymm8, xmmword ptr [r9+rdx-0x40], 0x01 - vmovups ymm9, ymmword ptr [r8+rdx-0x30] - vinsertf128 ymm9, ymm9, xmmword ptr [r9+rdx-0x30], 0x01 - vshufps ymm4, ymm8, ymm9, 136 - vshufps ymm5, ymm8, ymm9, 221 - vmovups ymm8, ymmword ptr [r8+rdx-0x20] - vinsertf128 ymm8, ymm8, xmmword ptr [r9+rdx-0x20], 0x01 - vmovups ymm9, ymmword ptr [r8+rdx-0x10] - vinsertf128 ymm9, ymm9, xmmword ptr [r9+rdx-0x10], 0x01 - vshufps ymm6, ymm8, ymm9, 136 - vshufps ymm7, ymm8, ymm9, 221 - vpshufd ymm6, ymm6, 0x93 - vpshufd ymm7, ymm7, 0x93 - mov al, 7 -9: - vpaddd ymm0, ymm0, ymm4 - vpaddd ymm0, ymm0, ymm1 - vpxord ymm3, ymm3, ymm0 - vprord ymm3, ymm3, 16 - vpaddd ymm2, ymm2, ymm3 - vpxord ymm1, ymm1, ymm2 - vprord ymm1, ymm1, 12 - vpaddd ymm0, ymm0, ymm5 - vpaddd ymm0, ymm0, ymm1 - vpxord ymm3, ymm3, ymm0 - vprord ymm3, ymm3, 8 - vpaddd ymm2, ymm2, ymm3 - vpxord ymm1, ymm1, ymm2 - vprord ymm1, ymm1, 7 - vpshufd ymm0, ymm0, 0x93 - vpshufd ymm3, ymm3, 0x4E - vpshufd ymm2, ymm2, 0x39 - vpaddd ymm0, ymm0, ymm6 - vpaddd ymm0, ymm0, ymm1 - vpxord ymm3, ymm3, ymm0 - vprord ymm3, ymm3, 16 - vpaddd ymm2, ymm2, ymm3 - vpxord ymm1, ymm1, ymm2 - vprord ymm1, ymm1, 12 - vpaddd ymm0, ymm0, ymm7 - vpaddd ymm0, ymm0, ymm1 - vpxord ymm3, ymm3, ymm0 - vprord ymm3, ymm3, 8 - vpaddd ymm2, ymm2, ymm3 - vpxord ymm1, ymm1, ymm2 - vprord ymm1, ymm1, 7 - vpshufd ymm0, ymm0, 0x39 - vpshufd ymm3, ymm3, 0x4E - vpshufd ymm2, ymm2, 0x93 - dec al - jz 9f - vshufps ymm8, ymm4, ymm5, 214 - vpshufd ymm9, ymm4, 0x0F - vpshufd ymm4, ymm8, 0x39 - vshufps ymm8, ymm6, ymm7, 250 - vpblendd ymm9, ymm9, ymm8, 0xAA - vpunpcklqdq ymm8, ymm7, ymm5 - vpblendd ymm8, ymm8, ymm6, 0x88 - vpshufd ymm8, ymm8, 0x78 - vpunpckhdq ymm5, ymm5, ymm7 - vpunpckldq ymm6, ymm6, ymm5 - vpshufd ymm7, ymm6, 0x1E - vmovdqa ymm5, ymm9 - vmovdqa ymm6, ymm8 - jmp 9b -9: - vpxor ymm0, ymm0, ymm2 - vpxor ymm1, ymm1, ymm3 - mov eax, r13d - cmp rdx, r15 - jne 2b - vmovdqu xmmword ptr [rbx], xmm0 - vmovdqu xmmword ptr [rbx+0x10], xmm1 - vextracti128 xmmword ptr [rbx+0x20], ymm0, 0x01 - vextracti128 xmmword ptr [rbx+0x30], ymm1, 0x01 - vmovdqa xmm0, xmmword ptr [rsp] - vmovdqa xmm2, xmmword ptr [rsp+0x4*0x10] - vmovdqu32 xmm0 {k1}, xmmword ptr [rsp+0x8] - vmovdqu32 xmm2 {k1}, xmmword ptr [rsp+0x48] - vmovdqa xmmword ptr [rsp], xmm0 - vmovdqa xmmword ptr [rsp+0x4*0x10], xmm2 - add rbx, 64 - add rdi, 16 - sub rsi, 2 -3: - test esi, 0x1 - je 4b - vmovdqu xmm0, xmmword ptr [rcx] - vmovdqu xmm1, xmmword ptr [rcx+0x10] - vmovd xmm14, dword ptr [rsp] - vpinsrd xmm14, xmm14, dword ptr [rsp+0x40], 1 - vpinsrd xmm14, xmm14, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - vmovdqa xmm15, xmmword ptr [BLAKE3_IV+rip] - mov r8, qword ptr [rdi] - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -.p2align 5 -2: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - vpinsrd xmm3, xmm14, eax, 3 - vmovdqa xmm2, xmm15 - vmovups xmm8, xmmword ptr [r8+rdx-0x40] - vmovups xmm9, xmmword ptr [r8+rdx-0x30] - vshufps xmm4, xmm8, xmm9, 136 - vshufps xmm5, xmm8, xmm9, 221 - vmovups xmm8, xmmword ptr [r8+rdx-0x20] - vmovups xmm9, xmmword ptr [r8+rdx-0x10] - vshufps xmm6, xmm8, xmm9, 136 - vshufps xmm7, xmm8, xmm9, 221 - vpshufd xmm6, xmm6, 0x93 - vpshufd xmm7, xmm7, 0x93 - mov al, 7 -9: - vpaddd xmm0, xmm0, xmm4 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 16 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 12 - vpaddd xmm0, xmm0, xmm5 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 8 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 7 - vpshufd xmm0, xmm0, 0x93 - vpshufd xmm3, xmm3, 0x4E - vpshufd xmm2, xmm2, 0x39 - vpaddd xmm0, xmm0, xmm6 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 16 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 12 - vpaddd xmm0, xmm0, xmm7 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 8 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 7 - vpshufd xmm0, xmm0, 0x39 - vpshufd xmm3, xmm3, 0x4E - vpshufd xmm2, xmm2, 0x93 - dec al - jz 9f - vshufps xmm8, xmm4, xmm5, 214 - vpshufd xmm9, xmm4, 0x0F - vpshufd xmm4, xmm8, 0x39 - vshufps xmm8, xmm6, xmm7, 250 - vpblendd xmm9, xmm9, xmm8, 0xAA - vpunpcklqdq xmm8, xmm7, xmm5 - vpblendd xmm8, xmm8, xmm6, 0x88 - vpshufd xmm8, xmm8, 0x78 - vpunpckhdq xmm5, xmm5, xmm7 - vpunpckldq xmm6, xmm6, xmm5 - vpshufd xmm7, xmm6, 0x1E - vmovdqa xmm5, xmm9 - vmovdqa xmm6, xmm8 - jmp 9b -9: - vpxor xmm0, xmm0, xmm2 - vpxor xmm1, xmm1, xmm3 - mov eax, r13d - cmp rdx, r15 - jne 2b - vmovdqu xmmword ptr [rbx], xmm0 - vmovdqu xmmword ptr [rbx+0x10], xmm1 - jmp 4b -.p2align 6 -_blake3_compress_in_place_avx512: -blake3_compress_in_place_avx512: - vmovdqu xmm0, xmmword ptr [rdi] - vmovdqu xmm1, xmmword ptr [rdi+0x10] - movzx eax, r8b - movzx edx, dl - shl rax, 32 - add rdx, rax - vmovq xmm3, rcx - vmovq xmm4, rdx - vpunpcklqdq xmm3, xmm3, xmm4 - vmovaps xmm2, xmmword ptr [BLAKE3_IV+rip] - vmovups xmm8, xmmword ptr [rsi] - vmovups xmm9, xmmword ptr [rsi+0x10] - vshufps xmm4, xmm8, xmm9, 136 - vshufps xmm5, xmm8, xmm9, 221 - vmovups xmm8, xmmword ptr [rsi+0x20] - vmovups xmm9, xmmword ptr [rsi+0x30] - vshufps xmm6, xmm8, xmm9, 136 - vshufps xmm7, xmm8, xmm9, 221 - vpshufd xmm6, xmm6, 0x93 - vpshufd xmm7, xmm7, 0x93 - mov al, 7 -9: - vpaddd xmm0, xmm0, xmm4 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 16 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 12 - vpaddd xmm0, xmm0, xmm5 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 8 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 7 - vpshufd xmm0, xmm0, 0x93 - vpshufd xmm3, xmm3, 0x4E - vpshufd xmm2, xmm2, 0x39 - vpaddd xmm0, xmm0, xmm6 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 16 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 12 - vpaddd xmm0, xmm0, xmm7 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 8 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 7 - vpshufd xmm0, xmm0, 0x39 - vpshufd xmm3, xmm3, 0x4E - vpshufd xmm2, xmm2, 0x93 - dec al - jz 9f - vshufps xmm8, xmm4, xmm5, 214 - vpshufd xmm9, xmm4, 0x0F - vpshufd xmm4, xmm8, 0x39 - vshufps xmm8, xmm6, xmm7, 250 - vpblendd xmm9, xmm9, xmm8, 0xAA - vpunpcklqdq xmm8, xmm7, xmm5 - vpblendd xmm8, xmm8, xmm6, 0x88 - vpshufd xmm8, xmm8, 0x78 - vpunpckhdq xmm5, xmm5, xmm7 - vpunpckldq xmm6, xmm6, xmm5 - vpshufd xmm7, xmm6, 0x1E - vmovdqa xmm5, xmm9 - vmovdqa xmm6, xmm8 - jmp 9b -9: - vpxor xmm0, xmm0, xmm2 - vpxor xmm1, xmm1, xmm3 - vmovdqu xmmword ptr [rdi], xmm0 - vmovdqu xmmword ptr [rdi+0x10], xmm1 - ret - -.p2align 6 -_blake3_compress_xof_avx512: -blake3_compress_xof_avx512: - vmovdqu xmm0, xmmword ptr [rdi] - vmovdqu xmm1, xmmword ptr [rdi+0x10] - movzx eax, r8b - movzx edx, dl - shl rax, 32 - add rdx, rax - vmovq xmm3, rcx - vmovq xmm4, rdx - vpunpcklqdq xmm3, xmm3, xmm4 - vmovaps xmm2, xmmword ptr [BLAKE3_IV+rip] - vmovups xmm8, xmmword ptr [rsi] - vmovups xmm9, xmmword ptr [rsi+0x10] - vshufps xmm4, xmm8, xmm9, 136 - vshufps xmm5, xmm8, xmm9, 221 - vmovups xmm8, xmmword ptr [rsi+0x20] - vmovups xmm9, xmmword ptr [rsi+0x30] - vshufps xmm6, xmm8, xmm9, 136 - vshufps xmm7, xmm8, xmm9, 221 - vpshufd xmm6, xmm6, 0x93 - vpshufd xmm7, xmm7, 0x93 - mov al, 7 -9: - vpaddd xmm0, xmm0, xmm4 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 16 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 12 - vpaddd xmm0, xmm0, xmm5 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 8 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 7 - vpshufd xmm0, xmm0, 0x93 - vpshufd xmm3, xmm3, 0x4E - vpshufd xmm2, xmm2, 0x39 - vpaddd xmm0, xmm0, xmm6 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 16 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 12 - vpaddd xmm0, xmm0, xmm7 - vpaddd xmm0, xmm0, xmm1 - vpxord xmm3, xmm3, xmm0 - vprord xmm3, xmm3, 8 - vpaddd xmm2, xmm2, xmm3 - vpxord xmm1, xmm1, xmm2 - vprord xmm1, xmm1, 7 - vpshufd xmm0, xmm0, 0x39 - vpshufd xmm3, xmm3, 0x4E - vpshufd xmm2, xmm2, 0x93 - dec al - jz 9f - vshufps xmm8, xmm4, xmm5, 214 - vpshufd xmm9, xmm4, 0x0F - vpshufd xmm4, xmm8, 0x39 - vshufps xmm8, xmm6, xmm7, 250 - vpblendd xmm9, xmm9, xmm8, 0xAA - vpunpcklqdq xmm8, xmm7, xmm5 - vpblendd xmm8, xmm8, xmm6, 0x88 - vpshufd xmm8, xmm8, 0x78 - vpunpckhdq xmm5, xmm5, xmm7 - vpunpckldq xmm6, xmm6, xmm5 - vpshufd xmm7, xmm6, 0x1E - vmovdqa xmm5, xmm9 - vmovdqa xmm6, xmm8 - jmp 9b -9: - vpxor xmm0, xmm0, xmm2 - vpxor xmm1, xmm1, xmm3 - vpxor xmm2, xmm2, [rdi] - vpxor xmm3, xmm3, [rdi+0x10] - vmovdqu xmmword ptr [r9], xmm0 - vmovdqu xmmword ptr [r9+0x10], xmm1 - vmovdqu xmmword ptr [r9+0x20], xmm2 - vmovdqu xmmword ptr [r9+0x30], xmm3 - ret - -#ifdef __APPLE__ -.static_data -#else -.section .rodata -#endif -.p2align 6 -INDEX0: - .long 0, 1, 2, 3, 16, 17, 18, 19 - .long 8, 9, 10, 11, 24, 25, 26, 27 -INDEX1: - .long 4, 5, 6, 7, 20, 21, 22, 23 - .long 12, 13, 14, 15, 28, 29, 30, 31 -ADD0: - .long 0, 1, 2, 3, 4, 5, 6, 7 - .long 8, 9, 10, 11, 12, 13, 14, 15 -ADD1: .long 1 - -ADD16: .long 16 -BLAKE3_BLOCK_LEN: - .long 64 -.p2align 6 -BLAKE3_IV: -BLAKE3_IV_0: - .long 0x6A09E667 -BLAKE3_IV_1: - .long 0xBB67AE85 -BLAKE3_IV_2: - .long 0x3C6EF372 -BLAKE3_IV_3: - .long 0xA54FF53A - -#endif // __x86_64__ +#ifdef __x86_64__ +.intel_syntax noprefix + +.global _blake3_hash_many_avx512 +.global blake3_hash_many_avx512 +.global blake3_compress_in_place_avx512 +.global _blake3_compress_in_place_avx512 +.global blake3_compress_xof_avx512 +.global _blake3_compress_xof_avx512 + +#ifdef __APPLE__ +.text +#else +.section .text +#endif +.p2align 6 +_blake3_hash_many_avx512: +blake3_hash_many_avx512: + push r15 + push r14 + push r13 + push r12 + push rbx + push rbp + mov rbp, rsp + sub rsp, 144 + and rsp, 0xFFFFFFFFFFFFFFC0 + neg r9 + kmovw k1, r9d + vmovd xmm0, r8d + vpbroadcastd ymm0, xmm0 + shr r8, 32 + vmovd xmm1, r8d + vpbroadcastd ymm1, xmm1 + vmovdqa ymm4, ymm1 + vmovdqa ymm5, ymm1 + vpaddd ymm2, ymm0, ymmword ptr [ADD0+rip] + vpaddd ymm3, ymm0, ymmword ptr [ADD0+32+rip] + vpcmpltud k2, ymm2, ymm0 + vpcmpltud k3, ymm3, ymm0 + vpaddd ymm4 {k2}, ymm4, dword ptr [ADD1+rip] {1to8} + vpaddd ymm5 {k3}, ymm5, dword ptr [ADD1+rip] {1to8} + knotw k2, k1 + vmovdqa32 ymm2 {k2}, ymm0 + vmovdqa32 ymm3 {k2}, ymm0 + vmovdqa32 ymm4 {k2}, ymm1 + vmovdqa32 ymm5 {k2}, ymm1 + vmovdqa ymmword ptr [rsp], ymm2 + vmovdqa ymmword ptr [rsp+0x1*0x20], ymm3 + vmovdqa ymmword ptr [rsp+0x2*0x20], ymm4 + vmovdqa ymmword ptr [rsp+0x3*0x20], ymm5 + shl rdx, 6 + mov qword ptr [rsp+0x80], rdx + cmp rsi, 16 + jc 3f +2: + vpbroadcastd zmm0, dword ptr [rcx] + vpbroadcastd zmm1, dword ptr [rcx+0x1*0x4] + vpbroadcastd zmm2, dword ptr [rcx+0x2*0x4] + vpbroadcastd zmm3, dword ptr [rcx+0x3*0x4] + vpbroadcastd zmm4, dword ptr [rcx+0x4*0x4] + vpbroadcastd zmm5, dword ptr [rcx+0x5*0x4] + vpbroadcastd zmm6, dword ptr [rcx+0x6*0x4] + vpbroadcastd zmm7, dword ptr [rcx+0x7*0x4] + movzx eax, byte ptr [rbp+0x38] + movzx ebx, byte ptr [rbp+0x40] + or eax, ebx + xor edx, edx +.p2align 5 +9: + movzx ebx, byte ptr [rbp+0x48] + or ebx, eax + add rdx, 64 + cmp rdx, qword ptr [rsp+0x80] + cmove eax, ebx + mov dword ptr [rsp+0x88], eax + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + mov r10, qword ptr [rdi+0x10] + mov r11, qword ptr [rdi+0x18] + mov r12, qword ptr [rdi+0x40] + mov r13, qword ptr [rdi+0x48] + mov r14, qword ptr [rdi+0x50] + mov r15, qword ptr [rdi+0x58] + vmovdqu32 ymm16, ymmword ptr [rdx+r8-0x2*0x20] + vinserti64x4 zmm16, zmm16, ymmword ptr [rdx+r12-0x2*0x20], 0x01 + vmovdqu32 ymm17, ymmword ptr [rdx+r9-0x2*0x20] + vinserti64x4 zmm17, zmm17, ymmword ptr [rdx+r13-0x2*0x20], 0x01 + vpunpcklqdq zmm8, zmm16, zmm17 + vpunpckhqdq zmm9, zmm16, zmm17 + vmovdqu32 ymm18, ymmword ptr [rdx+r10-0x2*0x20] + vinserti64x4 zmm18, zmm18, ymmword ptr [rdx+r14-0x2*0x20], 0x01 + vmovdqu32 ymm19, ymmword ptr [rdx+r11-0x2*0x20] + vinserti64x4 zmm19, zmm19, ymmword ptr [rdx+r15-0x2*0x20], 0x01 + vpunpcklqdq zmm10, zmm18, zmm19 + vpunpckhqdq zmm11, zmm18, zmm19 + mov r8, qword ptr [rdi+0x20] + mov r9, qword ptr [rdi+0x28] + mov r10, qword ptr [rdi+0x30] + mov r11, qword ptr [rdi+0x38] + mov r12, qword ptr [rdi+0x60] + mov r13, qword ptr [rdi+0x68] + mov r14, qword ptr [rdi+0x70] + mov r15, qword ptr [rdi+0x78] + vmovdqu32 ymm16, ymmword ptr [rdx+r8-0x2*0x20] + vinserti64x4 zmm16, zmm16, ymmword ptr [rdx+r12-0x2*0x20], 0x01 + vmovdqu32 ymm17, ymmword ptr [rdx+r9-0x2*0x20] + vinserti64x4 zmm17, zmm17, ymmword ptr [rdx+r13-0x2*0x20], 0x01 + vpunpcklqdq zmm12, zmm16, zmm17 + vpunpckhqdq zmm13, zmm16, zmm17 + vmovdqu32 ymm18, ymmword ptr [rdx+r10-0x2*0x20] + vinserti64x4 zmm18, zmm18, ymmword ptr [rdx+r14-0x2*0x20], 0x01 + vmovdqu32 ymm19, ymmword ptr [rdx+r11-0x2*0x20] + vinserti64x4 zmm19, zmm19, ymmword ptr [rdx+r15-0x2*0x20], 0x01 + vpunpcklqdq zmm14, zmm18, zmm19 + vpunpckhqdq zmm15, zmm18, zmm19 + vmovdqa32 zmm27, zmmword ptr [INDEX0+rip] + vmovdqa32 zmm31, zmmword ptr [INDEX1+rip] + vshufps zmm16, zmm8, zmm10, 136 + vshufps zmm17, zmm12, zmm14, 136 + vmovdqa32 zmm20, zmm16 + vpermt2d zmm16, zmm27, zmm17 + vpermt2d zmm20, zmm31, zmm17 + vshufps zmm17, zmm8, zmm10, 221 + vshufps zmm30, zmm12, zmm14, 221 + vmovdqa32 zmm21, zmm17 + vpermt2d zmm17, zmm27, zmm30 + vpermt2d zmm21, zmm31, zmm30 + vshufps zmm18, zmm9, zmm11, 136 + vshufps zmm8, zmm13, zmm15, 136 + vmovdqa32 zmm22, zmm18 + vpermt2d zmm18, zmm27, zmm8 + vpermt2d zmm22, zmm31, zmm8 + vshufps zmm19, zmm9, zmm11, 221 + vshufps zmm8, zmm13, zmm15, 221 + vmovdqa32 zmm23, zmm19 + vpermt2d zmm19, zmm27, zmm8 + vpermt2d zmm23, zmm31, zmm8 + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + mov r10, qword ptr [rdi+0x10] + mov r11, qword ptr [rdi+0x18] + mov r12, qword ptr [rdi+0x40] + mov r13, qword ptr [rdi+0x48] + mov r14, qword ptr [rdi+0x50] + mov r15, qword ptr [rdi+0x58] + vmovdqu32 ymm24, ymmword ptr [r8+rdx-0x1*0x20] + vinserti64x4 zmm24, zmm24, ymmword ptr [r12+rdx-0x1*0x20], 0x01 + vmovdqu32 ymm25, ymmword ptr [r9+rdx-0x1*0x20] + vinserti64x4 zmm25, zmm25, ymmword ptr [r13+rdx-0x1*0x20], 0x01 + vpunpcklqdq zmm8, zmm24, zmm25 + vpunpckhqdq zmm9, zmm24, zmm25 + vmovdqu32 ymm24, ymmword ptr [r10+rdx-0x1*0x20] + vinserti64x4 zmm24, zmm24, ymmword ptr [r14+rdx-0x1*0x20], 0x01 + vmovdqu32 ymm25, ymmword ptr [r11+rdx-0x1*0x20] + vinserti64x4 zmm25, zmm25, ymmword ptr [r15+rdx-0x1*0x20], 0x01 + vpunpcklqdq zmm10, zmm24, zmm25 + vpunpckhqdq zmm11, zmm24, zmm25 + prefetcht0 [r8+rdx+0x80] + prefetcht0 [r12+rdx+0x80] + prefetcht0 [r9+rdx+0x80] + prefetcht0 [r13+rdx+0x80] + prefetcht0 [r10+rdx+0x80] + prefetcht0 [r14+rdx+0x80] + prefetcht0 [r11+rdx+0x80] + prefetcht0 [r15+rdx+0x80] + mov r8, qword ptr [rdi+0x20] + mov r9, qword ptr [rdi+0x28] + mov r10, qword ptr [rdi+0x30] + mov r11, qword ptr [rdi+0x38] + mov r12, qword ptr [rdi+0x60] + mov r13, qword ptr [rdi+0x68] + mov r14, qword ptr [rdi+0x70] + mov r15, qword ptr [rdi+0x78] + vmovdqu32 ymm24, ymmword ptr [r8+rdx-0x1*0x20] + vinserti64x4 zmm24, zmm24, ymmword ptr [r12+rdx-0x1*0x20], 0x01 + vmovdqu32 ymm25, ymmword ptr [r9+rdx-0x1*0x20] + vinserti64x4 zmm25, zmm25, ymmword ptr [r13+rdx-0x1*0x20], 0x01 + vpunpcklqdq zmm12, zmm24, zmm25 + vpunpckhqdq zmm13, zmm24, zmm25 + vmovdqu32 ymm24, ymmword ptr [r10+rdx-0x1*0x20] + vinserti64x4 zmm24, zmm24, ymmword ptr [r14+rdx-0x1*0x20], 0x01 + vmovdqu32 ymm25, ymmword ptr [r11+rdx-0x1*0x20] + vinserti64x4 zmm25, zmm25, ymmword ptr [r15+rdx-0x1*0x20], 0x01 + vpunpcklqdq zmm14, zmm24, zmm25 + vpunpckhqdq zmm15, zmm24, zmm25 + prefetcht0 [r8+rdx+0x80] + prefetcht0 [r12+rdx+0x80] + prefetcht0 [r9+rdx+0x80] + prefetcht0 [r13+rdx+0x80] + prefetcht0 [r10+rdx+0x80] + prefetcht0 [r14+rdx+0x80] + prefetcht0 [r11+rdx+0x80] + prefetcht0 [r15+rdx+0x80] + vshufps zmm24, zmm8, zmm10, 136 + vshufps zmm30, zmm12, zmm14, 136 + vmovdqa32 zmm28, zmm24 + vpermt2d zmm24, zmm27, zmm30 + vpermt2d zmm28, zmm31, zmm30 + vshufps zmm25, zmm8, zmm10, 221 + vshufps zmm30, zmm12, zmm14, 221 + vmovdqa32 zmm29, zmm25 + vpermt2d zmm25, zmm27, zmm30 + vpermt2d zmm29, zmm31, zmm30 + vshufps zmm26, zmm9, zmm11, 136 + vshufps zmm8, zmm13, zmm15, 136 + vmovdqa32 zmm30, zmm26 + vpermt2d zmm26, zmm27, zmm8 + vpermt2d zmm30, zmm31, zmm8 + vshufps zmm8, zmm9, zmm11, 221 + vshufps zmm10, zmm13, zmm15, 221 + vpermi2d zmm27, zmm8, zmm10 + vpermi2d zmm31, zmm8, zmm10 + vpbroadcastd zmm8, dword ptr [BLAKE3_IV_0+rip] + vpbroadcastd zmm9, dword ptr [BLAKE3_IV_1+rip] + vpbroadcastd zmm10, dword ptr [BLAKE3_IV_2+rip] + vpbroadcastd zmm11, dword ptr [BLAKE3_IV_3+rip] + vmovdqa32 zmm12, zmmword ptr [rsp] + vmovdqa32 zmm13, zmmword ptr [rsp+0x1*0x40] + vpbroadcastd zmm14, dword ptr [BLAKE3_BLOCK_LEN+rip] + vpbroadcastd zmm15, dword ptr [rsp+0x22*0x4] + vpaddd zmm0, zmm0, zmm16 + vpaddd zmm1, zmm1, zmm18 + vpaddd zmm2, zmm2, zmm20 + vpaddd zmm3, zmm3, zmm22 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vprord zmm15, zmm15, 16 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 12 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vpaddd zmm0, zmm0, zmm17 + vpaddd zmm1, zmm1, zmm19 + vpaddd zmm2, zmm2, zmm21 + vpaddd zmm3, zmm3, zmm23 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vprord zmm15, zmm15, 8 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 7 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vpaddd zmm0, zmm0, zmm24 + vpaddd zmm1, zmm1, zmm26 + vpaddd zmm2, zmm2, zmm28 + vpaddd zmm3, zmm3, zmm30 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 16 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vprord zmm4, zmm4, 12 + vpaddd zmm0, zmm0, zmm25 + vpaddd zmm1, zmm1, zmm27 + vpaddd zmm2, zmm2, zmm29 + vpaddd zmm3, zmm3, zmm31 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 8 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vprord zmm4, zmm4, 7 + vpaddd zmm0, zmm0, zmm18 + vpaddd zmm1, zmm1, zmm19 + vpaddd zmm2, zmm2, zmm23 + vpaddd zmm3, zmm3, zmm20 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vprord zmm15, zmm15, 16 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 12 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vpaddd zmm0, zmm0, zmm22 + vpaddd zmm1, zmm1, zmm26 + vpaddd zmm2, zmm2, zmm16 + vpaddd zmm3, zmm3, zmm29 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vprord zmm15, zmm15, 8 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 7 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vpaddd zmm0, zmm0, zmm17 + vpaddd zmm1, zmm1, zmm28 + vpaddd zmm2, zmm2, zmm25 + vpaddd zmm3, zmm3, zmm31 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 16 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vprord zmm4, zmm4, 12 + vpaddd zmm0, zmm0, zmm27 + vpaddd zmm1, zmm1, zmm21 + vpaddd zmm2, zmm2, zmm30 + vpaddd zmm3, zmm3, zmm24 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 8 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vprord zmm4, zmm4, 7 + vpaddd zmm0, zmm0, zmm19 + vpaddd zmm1, zmm1, zmm26 + vpaddd zmm2, zmm2, zmm29 + vpaddd zmm3, zmm3, zmm23 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vprord zmm15, zmm15, 16 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 12 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vpaddd zmm0, zmm0, zmm20 + vpaddd zmm1, zmm1, zmm28 + vpaddd zmm2, zmm2, zmm18 + vpaddd zmm3, zmm3, zmm30 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vprord zmm15, zmm15, 8 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 7 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vpaddd zmm0, zmm0, zmm22 + vpaddd zmm1, zmm1, zmm25 + vpaddd zmm2, zmm2, zmm27 + vpaddd zmm3, zmm3, zmm24 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 16 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vprord zmm4, zmm4, 12 + vpaddd zmm0, zmm0, zmm21 + vpaddd zmm1, zmm1, zmm16 + vpaddd zmm2, zmm2, zmm31 + vpaddd zmm3, zmm3, zmm17 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 8 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vprord zmm4, zmm4, 7 + vpaddd zmm0, zmm0, zmm26 + vpaddd zmm1, zmm1, zmm28 + vpaddd zmm2, zmm2, zmm30 + vpaddd zmm3, zmm3, zmm29 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vprord zmm15, zmm15, 16 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 12 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vpaddd zmm0, zmm0, zmm23 + vpaddd zmm1, zmm1, zmm25 + vpaddd zmm2, zmm2, zmm19 + vpaddd zmm3, zmm3, zmm31 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vprord zmm15, zmm15, 8 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 7 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vpaddd zmm0, zmm0, zmm20 + vpaddd zmm1, zmm1, zmm27 + vpaddd zmm2, zmm2, zmm21 + vpaddd zmm3, zmm3, zmm17 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 16 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vprord zmm4, zmm4, 12 + vpaddd zmm0, zmm0, zmm16 + vpaddd zmm1, zmm1, zmm18 + vpaddd zmm2, zmm2, zmm24 + vpaddd zmm3, zmm3, zmm22 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 8 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vprord zmm4, zmm4, 7 + vpaddd zmm0, zmm0, zmm28 + vpaddd zmm1, zmm1, zmm25 + vpaddd zmm2, zmm2, zmm31 + vpaddd zmm3, zmm3, zmm30 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vprord zmm15, zmm15, 16 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 12 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vpaddd zmm0, zmm0, zmm29 + vpaddd zmm1, zmm1, zmm27 + vpaddd zmm2, zmm2, zmm26 + vpaddd zmm3, zmm3, zmm24 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vprord zmm15, zmm15, 8 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 7 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vpaddd zmm0, zmm0, zmm23 + vpaddd zmm1, zmm1, zmm21 + vpaddd zmm2, zmm2, zmm16 + vpaddd zmm3, zmm3, zmm22 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 16 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vprord zmm4, zmm4, 12 + vpaddd zmm0, zmm0, zmm18 + vpaddd zmm1, zmm1, zmm19 + vpaddd zmm2, zmm2, zmm17 + vpaddd zmm3, zmm3, zmm20 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 8 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vprord zmm4, zmm4, 7 + vpaddd zmm0, zmm0, zmm25 + vpaddd zmm1, zmm1, zmm27 + vpaddd zmm2, zmm2, zmm24 + vpaddd zmm3, zmm3, zmm31 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vprord zmm15, zmm15, 16 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 12 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vpaddd zmm0, zmm0, zmm30 + vpaddd zmm1, zmm1, zmm21 + vpaddd zmm2, zmm2, zmm28 + vpaddd zmm3, zmm3, zmm17 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vprord zmm15, zmm15, 8 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 7 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vpaddd zmm0, zmm0, zmm29 + vpaddd zmm1, zmm1, zmm16 + vpaddd zmm2, zmm2, zmm18 + vpaddd zmm3, zmm3, zmm20 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 16 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vprord zmm4, zmm4, 12 + vpaddd zmm0, zmm0, zmm19 + vpaddd zmm1, zmm1, zmm26 + vpaddd zmm2, zmm2, zmm22 + vpaddd zmm3, zmm3, zmm23 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 8 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vprord zmm4, zmm4, 7 + vpaddd zmm0, zmm0, zmm27 + vpaddd zmm1, zmm1, zmm21 + vpaddd zmm2, zmm2, zmm17 + vpaddd zmm3, zmm3, zmm24 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vprord zmm15, zmm15, 16 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 12 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vpaddd zmm0, zmm0, zmm31 + vpaddd zmm1, zmm1, zmm16 + vpaddd zmm2, zmm2, zmm25 + vpaddd zmm3, zmm3, zmm22 + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm1, zmm1, zmm5 + vpaddd zmm2, zmm2, zmm6 + vpaddd zmm3, zmm3, zmm7 + vpxord zmm12, zmm12, zmm0 + vpxord zmm13, zmm13, zmm1 + vpxord zmm14, zmm14, zmm2 + vpxord zmm15, zmm15, zmm3 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vprord zmm15, zmm15, 8 + vpaddd zmm8, zmm8, zmm12 + vpaddd zmm9, zmm9, zmm13 + vpaddd zmm10, zmm10, zmm14 + vpaddd zmm11, zmm11, zmm15 + vpxord zmm4, zmm4, zmm8 + vpxord zmm5, zmm5, zmm9 + vpxord zmm6, zmm6, zmm10 + vpxord zmm7, zmm7, zmm11 + vprord zmm4, zmm4, 7 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vpaddd zmm0, zmm0, zmm30 + vpaddd zmm1, zmm1, zmm18 + vpaddd zmm2, zmm2, zmm19 + vpaddd zmm3, zmm3, zmm23 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 16 + vprord zmm12, zmm12, 16 + vprord zmm13, zmm13, 16 + vprord zmm14, zmm14, 16 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 12 + vprord zmm6, zmm6, 12 + vprord zmm7, zmm7, 12 + vprord zmm4, zmm4, 12 + vpaddd zmm0, zmm0, zmm26 + vpaddd zmm1, zmm1, zmm28 + vpaddd zmm2, zmm2, zmm20 + vpaddd zmm3, zmm3, zmm29 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm1, zmm1, zmm6 + vpaddd zmm2, zmm2, zmm7 + vpaddd zmm3, zmm3, zmm4 + vpxord zmm15, zmm15, zmm0 + vpxord zmm12, zmm12, zmm1 + vpxord zmm13, zmm13, zmm2 + vpxord zmm14, zmm14, zmm3 + vprord zmm15, zmm15, 8 + vprord zmm12, zmm12, 8 + vprord zmm13, zmm13, 8 + vprord zmm14, zmm14, 8 + vpaddd zmm10, zmm10, zmm15 + vpaddd zmm11, zmm11, zmm12 + vpaddd zmm8, zmm8, zmm13 + vpaddd zmm9, zmm9, zmm14 + vpxord zmm5, zmm5, zmm10 + vpxord zmm6, zmm6, zmm11 + vpxord zmm7, zmm7, zmm8 + vpxord zmm4, zmm4, zmm9 + vprord zmm5, zmm5, 7 + vprord zmm6, zmm6, 7 + vprord zmm7, zmm7, 7 + vprord zmm4, zmm4, 7 + vpxord zmm0, zmm0, zmm8 + vpxord zmm1, zmm1, zmm9 + vpxord zmm2, zmm2, zmm10 + vpxord zmm3, zmm3, zmm11 + vpxord zmm4, zmm4, zmm12 + vpxord zmm5, zmm5, zmm13 + vpxord zmm6, zmm6, zmm14 + vpxord zmm7, zmm7, zmm15 + movzx eax, byte ptr [rbp+0x38] + jne 9b + mov rbx, qword ptr [rbp+0x50] + vpunpckldq zmm16, zmm0, zmm1 + vpunpckhdq zmm17, zmm0, zmm1 + vpunpckldq zmm18, zmm2, zmm3 + vpunpckhdq zmm19, zmm2, zmm3 + vpunpckldq zmm20, zmm4, zmm5 + vpunpckhdq zmm21, zmm4, zmm5 + vpunpckldq zmm22, zmm6, zmm7 + vpunpckhdq zmm23, zmm6, zmm7 + vpunpcklqdq zmm0, zmm16, zmm18 + vpunpckhqdq zmm1, zmm16, zmm18 + vpunpcklqdq zmm2, zmm17, zmm19 + vpunpckhqdq zmm3, zmm17, zmm19 + vpunpcklqdq zmm4, zmm20, zmm22 + vpunpckhqdq zmm5, zmm20, zmm22 + vpunpcklqdq zmm6, zmm21, zmm23 + vpunpckhqdq zmm7, zmm21, zmm23 + vshufi32x4 zmm16, zmm0, zmm4, 0x88 + vshufi32x4 zmm17, zmm1, zmm5, 0x88 + vshufi32x4 zmm18, zmm2, zmm6, 0x88 + vshufi32x4 zmm19, zmm3, zmm7, 0x88 + vshufi32x4 zmm20, zmm0, zmm4, 0xDD + vshufi32x4 zmm21, zmm1, zmm5, 0xDD + vshufi32x4 zmm22, zmm2, zmm6, 0xDD + vshufi32x4 zmm23, zmm3, zmm7, 0xDD + vshufi32x4 zmm0, zmm16, zmm17, 0x88 + vshufi32x4 zmm1, zmm18, zmm19, 0x88 + vshufi32x4 zmm2, zmm20, zmm21, 0x88 + vshufi32x4 zmm3, zmm22, zmm23, 0x88 + vshufi32x4 zmm4, zmm16, zmm17, 0xDD + vshufi32x4 zmm5, zmm18, zmm19, 0xDD + vshufi32x4 zmm6, zmm20, zmm21, 0xDD + vshufi32x4 zmm7, zmm22, zmm23, 0xDD + vmovdqu32 zmmword ptr [rbx], zmm0 + vmovdqu32 zmmword ptr [rbx+0x1*0x40], zmm1 + vmovdqu32 zmmword ptr [rbx+0x2*0x40], zmm2 + vmovdqu32 zmmword ptr [rbx+0x3*0x40], zmm3 + vmovdqu32 zmmword ptr [rbx+0x4*0x40], zmm4 + vmovdqu32 zmmword ptr [rbx+0x5*0x40], zmm5 + vmovdqu32 zmmword ptr [rbx+0x6*0x40], zmm6 + vmovdqu32 zmmword ptr [rbx+0x7*0x40], zmm7 + vmovdqa32 zmm0, zmmword ptr [rsp] + vmovdqa32 zmm1, zmmword ptr [rsp+0x1*0x40] + vmovdqa32 zmm2, zmm0 + vpaddd zmm2{k1}, zmm0, dword ptr [ADD16+rip] {1to16} + vpcmpltud k2, zmm2, zmm0 + vpaddd zmm1 {k2}, zmm1, dword ptr [ADD1+rip] {1to16} + vmovdqa32 zmmword ptr [rsp], zmm2 + vmovdqa32 zmmword ptr [rsp+0x1*0x40], zmm1 + add rdi, 128 + add rbx, 512 + mov qword ptr [rbp+0x50], rbx + sub rsi, 16 + cmp rsi, 16 + jnc 2b + test rsi, rsi + jnz 3f +4: + vzeroupper + mov rsp, rbp + pop rbp + pop rbx + pop r12 + pop r13 + pop r14 + pop r15 + ret +.p2align 6 +3: + test esi, 0x8 + je 3f + vpbroadcastd ymm0, dword ptr [rcx] + vpbroadcastd ymm1, dword ptr [rcx+0x4] + vpbroadcastd ymm2, dword ptr [rcx+0x8] + vpbroadcastd ymm3, dword ptr [rcx+0xC] + vpbroadcastd ymm4, dword ptr [rcx+0x10] + vpbroadcastd ymm5, dword ptr [rcx+0x14] + vpbroadcastd ymm6, dword ptr [rcx+0x18] + vpbroadcastd ymm7, dword ptr [rcx+0x1C] + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + mov r10, qword ptr [rdi+0x10] + mov r11, qword ptr [rdi+0x18] + mov r12, qword ptr [rdi+0x20] + mov r13, qword ptr [rdi+0x28] + mov r14, qword ptr [rdi+0x30] + mov r15, qword ptr [rdi+0x38] + movzx eax, byte ptr [rbp+0x38] + movzx ebx, byte ptr [rbp+0x40] + or eax, ebx + xor edx, edx +2: + movzx ebx, byte ptr [rbp+0x48] + or ebx, eax + add rdx, 64 + cmp rdx, qword ptr [rsp+0x80] + cmove eax, ebx + mov dword ptr [rsp+0x88], eax + vmovups xmm8, xmmword ptr [r8+rdx-0x40] + vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x40], 0x01 + vmovups xmm9, xmmword ptr [r9+rdx-0x40] + vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x40], 0x01 + vunpcklpd ymm12, ymm8, ymm9 + vunpckhpd ymm13, ymm8, ymm9 + vmovups xmm10, xmmword ptr [r10+rdx-0x40] + vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x40], 0x01 + vmovups xmm11, xmmword ptr [r11+rdx-0x40] + vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x40], 0x01 + vunpcklpd ymm14, ymm10, ymm11 + vunpckhpd ymm15, ymm10, ymm11 + vshufps ymm16, ymm12, ymm14, 136 + vshufps ymm17, ymm12, ymm14, 221 + vshufps ymm18, ymm13, ymm15, 136 + vshufps ymm19, ymm13, ymm15, 221 + vmovups xmm8, xmmword ptr [r8+rdx-0x30] + vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x30], 0x01 + vmovups xmm9, xmmword ptr [r9+rdx-0x30] + vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x30], 0x01 + vunpcklpd ymm12, ymm8, ymm9 + vunpckhpd ymm13, ymm8, ymm9 + vmovups xmm10, xmmword ptr [r10+rdx-0x30] + vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x30], 0x01 + vmovups xmm11, xmmword ptr [r11+rdx-0x30] + vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x30], 0x01 + vunpcklpd ymm14, ymm10, ymm11 + vunpckhpd ymm15, ymm10, ymm11 + vshufps ymm20, ymm12, ymm14, 136 + vshufps ymm21, ymm12, ymm14, 221 + vshufps ymm22, ymm13, ymm15, 136 + vshufps ymm23, ymm13, ymm15, 221 + vmovups xmm8, xmmword ptr [r8+rdx-0x20] + vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x20], 0x01 + vmovups xmm9, xmmword ptr [r9+rdx-0x20] + vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x20], 0x01 + vunpcklpd ymm12, ymm8, ymm9 + vunpckhpd ymm13, ymm8, ymm9 + vmovups xmm10, xmmword ptr [r10+rdx-0x20] + vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x20], 0x01 + vmovups xmm11, xmmword ptr [r11+rdx-0x20] + vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x20], 0x01 + vunpcklpd ymm14, ymm10, ymm11 + vunpckhpd ymm15, ymm10, ymm11 + vshufps ymm24, ymm12, ymm14, 136 + vshufps ymm25, ymm12, ymm14, 221 + vshufps ymm26, ymm13, ymm15, 136 + vshufps ymm27, ymm13, ymm15, 221 + vmovups xmm8, xmmword ptr [r8+rdx-0x10] + vinsertf128 ymm8, ymm8, xmmword ptr [r12+rdx-0x10], 0x01 + vmovups xmm9, xmmword ptr [r9+rdx-0x10] + vinsertf128 ymm9, ymm9, xmmword ptr [r13+rdx-0x10], 0x01 + vunpcklpd ymm12, ymm8, ymm9 + vunpckhpd ymm13, ymm8, ymm9 + vmovups xmm10, xmmword ptr [r10+rdx-0x10] + vinsertf128 ymm10, ymm10, xmmword ptr [r14+rdx-0x10], 0x01 + vmovups xmm11, xmmword ptr [r11+rdx-0x10] + vinsertf128 ymm11, ymm11, xmmword ptr [r15+rdx-0x10], 0x01 + vunpcklpd ymm14, ymm10, ymm11 + vunpckhpd ymm15, ymm10, ymm11 + vshufps ymm28, ymm12, ymm14, 136 + vshufps ymm29, ymm12, ymm14, 221 + vshufps ymm30, ymm13, ymm15, 136 + vshufps ymm31, ymm13, ymm15, 221 + vpbroadcastd ymm8, dword ptr [BLAKE3_IV_0+rip] + vpbroadcastd ymm9, dword ptr [BLAKE3_IV_1+rip] + vpbroadcastd ymm10, dword ptr [BLAKE3_IV_2+rip] + vpbroadcastd ymm11, dword ptr [BLAKE3_IV_3+rip] + vmovdqa ymm12, ymmword ptr [rsp] + vmovdqa ymm13, ymmword ptr [rsp+0x40] + vpbroadcastd ymm14, dword ptr [BLAKE3_BLOCK_LEN+rip] + vpbroadcastd ymm15, dword ptr [rsp+0x88] + vpaddd ymm0, ymm0, ymm16 + vpaddd ymm1, ymm1, ymm18 + vpaddd ymm2, ymm2, ymm20 + vpaddd ymm3, ymm3, ymm22 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vprord ymm15, ymm15, 16 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 12 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vpaddd ymm0, ymm0, ymm17 + vpaddd ymm1, ymm1, ymm19 + vpaddd ymm2, ymm2, ymm21 + vpaddd ymm3, ymm3, ymm23 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vprord ymm15, ymm15, 8 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 7 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vpaddd ymm0, ymm0, ymm24 + vpaddd ymm1, ymm1, ymm26 + vpaddd ymm2, ymm2, ymm28 + vpaddd ymm3, ymm3, ymm30 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 16 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vprord ymm4, ymm4, 12 + vpaddd ymm0, ymm0, ymm25 + vpaddd ymm1, ymm1, ymm27 + vpaddd ymm2, ymm2, ymm29 + vpaddd ymm3, ymm3, ymm31 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 8 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vprord ymm4, ymm4, 7 + vpaddd ymm0, ymm0, ymm18 + vpaddd ymm1, ymm1, ymm19 + vpaddd ymm2, ymm2, ymm23 + vpaddd ymm3, ymm3, ymm20 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vprord ymm15, ymm15, 16 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 12 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vpaddd ymm0, ymm0, ymm22 + vpaddd ymm1, ymm1, ymm26 + vpaddd ymm2, ymm2, ymm16 + vpaddd ymm3, ymm3, ymm29 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vprord ymm15, ymm15, 8 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 7 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vpaddd ymm0, ymm0, ymm17 + vpaddd ymm1, ymm1, ymm28 + vpaddd ymm2, ymm2, ymm25 + vpaddd ymm3, ymm3, ymm31 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 16 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vprord ymm4, ymm4, 12 + vpaddd ymm0, ymm0, ymm27 + vpaddd ymm1, ymm1, ymm21 + vpaddd ymm2, ymm2, ymm30 + vpaddd ymm3, ymm3, ymm24 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 8 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vprord ymm4, ymm4, 7 + vpaddd ymm0, ymm0, ymm19 + vpaddd ymm1, ymm1, ymm26 + vpaddd ymm2, ymm2, ymm29 + vpaddd ymm3, ymm3, ymm23 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vprord ymm15, ymm15, 16 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 12 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vpaddd ymm0, ymm0, ymm20 + vpaddd ymm1, ymm1, ymm28 + vpaddd ymm2, ymm2, ymm18 + vpaddd ymm3, ymm3, ymm30 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vprord ymm15, ymm15, 8 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 7 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vpaddd ymm0, ymm0, ymm22 + vpaddd ymm1, ymm1, ymm25 + vpaddd ymm2, ymm2, ymm27 + vpaddd ymm3, ymm3, ymm24 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 16 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vprord ymm4, ymm4, 12 + vpaddd ymm0, ymm0, ymm21 + vpaddd ymm1, ymm1, ymm16 + vpaddd ymm2, ymm2, ymm31 + vpaddd ymm3, ymm3, ymm17 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 8 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vprord ymm4, ymm4, 7 + vpaddd ymm0, ymm0, ymm26 + vpaddd ymm1, ymm1, ymm28 + vpaddd ymm2, ymm2, ymm30 + vpaddd ymm3, ymm3, ymm29 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vprord ymm15, ymm15, 16 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 12 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vpaddd ymm0, ymm0, ymm23 + vpaddd ymm1, ymm1, ymm25 + vpaddd ymm2, ymm2, ymm19 + vpaddd ymm3, ymm3, ymm31 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vprord ymm15, ymm15, 8 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 7 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vpaddd ymm0, ymm0, ymm20 + vpaddd ymm1, ymm1, ymm27 + vpaddd ymm2, ymm2, ymm21 + vpaddd ymm3, ymm3, ymm17 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 16 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vprord ymm4, ymm4, 12 + vpaddd ymm0, ymm0, ymm16 + vpaddd ymm1, ymm1, ymm18 + vpaddd ymm2, ymm2, ymm24 + vpaddd ymm3, ymm3, ymm22 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 8 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vprord ymm4, ymm4, 7 + vpaddd ymm0, ymm0, ymm28 + vpaddd ymm1, ymm1, ymm25 + vpaddd ymm2, ymm2, ymm31 + vpaddd ymm3, ymm3, ymm30 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vprord ymm15, ymm15, 16 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 12 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vpaddd ymm0, ymm0, ymm29 + vpaddd ymm1, ymm1, ymm27 + vpaddd ymm2, ymm2, ymm26 + vpaddd ymm3, ymm3, ymm24 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vprord ymm15, ymm15, 8 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 7 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vpaddd ymm0, ymm0, ymm23 + vpaddd ymm1, ymm1, ymm21 + vpaddd ymm2, ymm2, ymm16 + vpaddd ymm3, ymm3, ymm22 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 16 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vprord ymm4, ymm4, 12 + vpaddd ymm0, ymm0, ymm18 + vpaddd ymm1, ymm1, ymm19 + vpaddd ymm2, ymm2, ymm17 + vpaddd ymm3, ymm3, ymm20 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 8 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vprord ymm4, ymm4, 7 + vpaddd ymm0, ymm0, ymm25 + vpaddd ymm1, ymm1, ymm27 + vpaddd ymm2, ymm2, ymm24 + vpaddd ymm3, ymm3, ymm31 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vprord ymm15, ymm15, 16 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 12 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vpaddd ymm0, ymm0, ymm30 + vpaddd ymm1, ymm1, ymm21 + vpaddd ymm2, ymm2, ymm28 + vpaddd ymm3, ymm3, ymm17 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vprord ymm15, ymm15, 8 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 7 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vpaddd ymm0, ymm0, ymm29 + vpaddd ymm1, ymm1, ymm16 + vpaddd ymm2, ymm2, ymm18 + vpaddd ymm3, ymm3, ymm20 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 16 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vprord ymm4, ymm4, 12 + vpaddd ymm0, ymm0, ymm19 + vpaddd ymm1, ymm1, ymm26 + vpaddd ymm2, ymm2, ymm22 + vpaddd ymm3, ymm3, ymm23 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 8 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vprord ymm4, ymm4, 7 + vpaddd ymm0, ymm0, ymm27 + vpaddd ymm1, ymm1, ymm21 + vpaddd ymm2, ymm2, ymm17 + vpaddd ymm3, ymm3, ymm24 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vprord ymm15, ymm15, 16 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 12 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vpaddd ymm0, ymm0, ymm31 + vpaddd ymm1, ymm1, ymm16 + vpaddd ymm2, ymm2, ymm25 + vpaddd ymm3, ymm3, ymm22 + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm1, ymm1, ymm5 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 + vpxord ymm12, ymm12, ymm0 + vpxord ymm13, ymm13, ymm1 + vpxord ymm14, ymm14, ymm2 + vpxord ymm15, ymm15, ymm3 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vprord ymm15, ymm15, 8 + vpaddd ymm8, ymm8, ymm12 + vpaddd ymm9, ymm9, ymm13 + vpaddd ymm10, ymm10, ymm14 + vpaddd ymm11, ymm11, ymm15 + vpxord ymm4, ymm4, ymm8 + vpxord ymm5, ymm5, ymm9 + vpxord ymm6, ymm6, ymm10 + vpxord ymm7, ymm7, ymm11 + vprord ymm4, ymm4, 7 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vpaddd ymm0, ymm0, ymm30 + vpaddd ymm1, ymm1, ymm18 + vpaddd ymm2, ymm2, ymm19 + vpaddd ymm3, ymm3, ymm23 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 16 + vprord ymm12, ymm12, 16 + vprord ymm13, ymm13, 16 + vprord ymm14, ymm14, 16 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 12 + vprord ymm6, ymm6, 12 + vprord ymm7, ymm7, 12 + vprord ymm4, ymm4, 12 + vpaddd ymm0, ymm0, ymm26 + vpaddd ymm1, ymm1, ymm28 + vpaddd ymm2, ymm2, ymm20 + vpaddd ymm3, ymm3, ymm29 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm6 + vpaddd ymm2, ymm2, ymm7 + vpaddd ymm3, ymm3, ymm4 + vpxord ymm15, ymm15, ymm0 + vpxord ymm12, ymm12, ymm1 + vpxord ymm13, ymm13, ymm2 + vpxord ymm14, ymm14, ymm3 + vprord ymm15, ymm15, 8 + vprord ymm12, ymm12, 8 + vprord ymm13, ymm13, 8 + vprord ymm14, ymm14, 8 + vpaddd ymm10, ymm10, ymm15 + vpaddd ymm11, ymm11, ymm12 + vpaddd ymm8, ymm8, ymm13 + vpaddd ymm9, ymm9, ymm14 + vpxord ymm5, ymm5, ymm10 + vpxord ymm6, ymm6, ymm11 + vpxord ymm7, ymm7, ymm8 + vpxord ymm4, ymm4, ymm9 + vprord ymm5, ymm5, 7 + vprord ymm6, ymm6, 7 + vprord ymm7, ymm7, 7 + vprord ymm4, ymm4, 7 + vpxor ymm0, ymm0, ymm8 + vpxor ymm1, ymm1, ymm9 + vpxor ymm2, ymm2, ymm10 + vpxor ymm3, ymm3, ymm11 + vpxor ymm4, ymm4, ymm12 + vpxor ymm5, ymm5, ymm13 + vpxor ymm6, ymm6, ymm14 + vpxor ymm7, ymm7, ymm15 + movzx eax, byte ptr [rbp+0x38] + jne 2b + mov rbx, qword ptr [rbp+0x50] + vunpcklps ymm8, ymm0, ymm1 + vunpcklps ymm9, ymm2, ymm3 + vunpckhps ymm10, ymm0, ymm1 + vunpcklps ymm11, ymm4, ymm5 + vunpcklps ymm0, ymm6, ymm7 + vshufps ymm12, ymm8, ymm9, 78 + vblendps ymm1, ymm8, ymm12, 0xCC + vshufps ymm8, ymm11, ymm0, 78 + vunpckhps ymm13, ymm2, ymm3 + vblendps ymm2, ymm11, ymm8, 0xCC + vblendps ymm3, ymm12, ymm9, 0xCC + vperm2f128 ymm12, ymm1, ymm2, 0x20 + vmovups ymmword ptr [rbx], ymm12 + vunpckhps ymm14, ymm4, ymm5 + vblendps ymm4, ymm8, ymm0, 0xCC + vunpckhps ymm15, ymm6, ymm7 + vperm2f128 ymm7, ymm3, ymm4, 0x20 + vmovups ymmword ptr [rbx+0x20], ymm7 + vshufps ymm5, ymm10, ymm13, 78 + vblendps ymm6, ymm5, ymm13, 0xCC + vshufps ymm13, ymm14, ymm15, 78 + vblendps ymm10, ymm10, ymm5, 0xCC + vblendps ymm14, ymm14, ymm13, 0xCC + vperm2f128 ymm8, ymm10, ymm14, 0x20 + vmovups ymmword ptr [rbx+0x40], ymm8 + vblendps ymm15, ymm13, ymm15, 0xCC + vperm2f128 ymm13, ymm6, ymm15, 0x20 + vmovups ymmword ptr [rbx+0x60], ymm13 + vperm2f128 ymm9, ymm1, ymm2, 0x31 + vperm2f128 ymm11, ymm3, ymm4, 0x31 + vmovups ymmword ptr [rbx+0x80], ymm9 + vperm2f128 ymm14, ymm10, ymm14, 0x31 + vperm2f128 ymm15, ymm6, ymm15, 0x31 + vmovups ymmword ptr [rbx+0xA0], ymm11 + vmovups ymmword ptr [rbx+0xC0], ymm14 + vmovups ymmword ptr [rbx+0xE0], ymm15 + vmovdqa ymm0, ymmword ptr [rsp] + vmovdqa ymm2, ymmword ptr [rsp+0x2*0x20] + vmovdqa32 ymm0 {k1}, ymmword ptr [rsp+0x1*0x20] + vmovdqa32 ymm2 {k1}, ymmword ptr [rsp+0x3*0x20] + vmovdqa ymmword ptr [rsp], ymm0 + vmovdqa ymmword ptr [rsp+0x2*0x20], ymm2 + add rbx, 256 + mov qword ptr [rbp+0x50], rbx + add rdi, 64 + sub rsi, 8 +3: + mov rbx, qword ptr [rbp+0x50] + mov r15, qword ptr [rsp+0x80] + movzx r13, byte ptr [rbp+0x38] + movzx r12, byte ptr [rbp+0x48] + test esi, 0x4 + je 3f + vbroadcasti32x4 zmm0, xmmword ptr [rcx] + vbroadcasti32x4 zmm1, xmmword ptr [rcx+0x1*0x10] + vmovdqa xmm12, xmmword ptr [rsp] + vmovdqa xmm13, xmmword ptr [rsp+0x4*0x10] + vpunpckldq xmm14, xmm12, xmm13 + vpunpckhdq xmm15, xmm12, xmm13 + vpermq ymm14, ymm14, 0xDC + vpermq ymm15, ymm15, 0xDC + vpbroadcastd zmm12, dword ptr [BLAKE3_BLOCK_LEN+rip] + vinserti64x4 zmm13, zmm14, ymm15, 0x01 + mov eax, 17476 + kmovw k2, eax + vpblendmd zmm13 {k2}, zmm13, zmm12 + vbroadcasti32x4 zmm15, xmmword ptr [BLAKE3_IV+rip] + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + mov r10, qword ptr [rdi+0x10] + mov r11, qword ptr [rdi+0x18] + mov eax, 43690 + kmovw k3, eax + mov eax, 34952 + kmovw k4, eax + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +.p2align 5 +2: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + mov dword ptr [rsp+0x88], eax + vmovdqa32 zmm2, zmm15 + vpbroadcastd zmm8, dword ptr [rsp+0x22*0x4] + vpblendmd zmm3 {k4}, zmm13, zmm8 + vmovups zmm8, zmmword ptr [r8+rdx-0x1*0x40] + vinserti32x4 zmm8, zmm8, xmmword ptr [r9+rdx-0x4*0x10], 0x01 + vinserti32x4 zmm8, zmm8, xmmword ptr [r10+rdx-0x4*0x10], 0x02 + vinserti32x4 zmm8, zmm8, xmmword ptr [r11+rdx-0x4*0x10], 0x03 + vmovups zmm9, zmmword ptr [r8+rdx-0x30] + vinserti32x4 zmm9, zmm9, xmmword ptr [r9+rdx-0x3*0x10], 0x01 + vinserti32x4 zmm9, zmm9, xmmword ptr [r10+rdx-0x3*0x10], 0x02 + vinserti32x4 zmm9, zmm9, xmmword ptr [r11+rdx-0x3*0x10], 0x03 + vshufps zmm4, zmm8, zmm9, 136 + vshufps zmm5, zmm8, zmm9, 221 + vmovups zmm8, zmmword ptr [r8+rdx-0x20] + vinserti32x4 zmm8, zmm8, xmmword ptr [r9+rdx-0x2*0x10], 0x01 + vinserti32x4 zmm8, zmm8, xmmword ptr [r10+rdx-0x2*0x10], 0x02 + vinserti32x4 zmm8, zmm8, xmmword ptr [r11+rdx-0x2*0x10], 0x03 + vmovups zmm9, zmmword ptr [r8+rdx-0x10] + vinserti32x4 zmm9, zmm9, xmmword ptr [r9+rdx-0x1*0x10], 0x01 + vinserti32x4 zmm9, zmm9, xmmword ptr [r10+rdx-0x1*0x10], 0x02 + vinserti32x4 zmm9, zmm9, xmmword ptr [r11+rdx-0x1*0x10], 0x03 + vshufps zmm6, zmm8, zmm9, 136 + vshufps zmm7, zmm8, zmm9, 221 + vpshufd zmm6, zmm6, 0x93 + vpshufd zmm7, zmm7, 0x93 + mov al, 7 +9: + vpaddd zmm0, zmm0, zmm4 + vpaddd zmm0, zmm0, zmm1 + vpxord zmm3, zmm3, zmm0 + vprord zmm3, zmm3, 16 + vpaddd zmm2, zmm2, zmm3 + vpxord zmm1, zmm1, zmm2 + vprord zmm1, zmm1, 12 + vpaddd zmm0, zmm0, zmm5 + vpaddd zmm0, zmm0, zmm1 + vpxord zmm3, zmm3, zmm0 + vprord zmm3, zmm3, 8 + vpaddd zmm2, zmm2, zmm3 + vpxord zmm1, zmm1, zmm2 + vprord zmm1, zmm1, 7 + vpshufd zmm0, zmm0, 0x93 + vpshufd zmm3, zmm3, 0x4E + vpshufd zmm2, zmm2, 0x39 + vpaddd zmm0, zmm0, zmm6 + vpaddd zmm0, zmm0, zmm1 + vpxord zmm3, zmm3, zmm0 + vprord zmm3, zmm3, 16 + vpaddd zmm2, zmm2, zmm3 + vpxord zmm1, zmm1, zmm2 + vprord zmm1, zmm1, 12 + vpaddd zmm0, zmm0, zmm7 + vpaddd zmm0, zmm0, zmm1 + vpxord zmm3, zmm3, zmm0 + vprord zmm3, zmm3, 8 + vpaddd zmm2, zmm2, zmm3 + vpxord zmm1, zmm1, zmm2 + vprord zmm1, zmm1, 7 + vpshufd zmm0, zmm0, 0x39 + vpshufd zmm3, zmm3, 0x4E + vpshufd zmm2, zmm2, 0x93 + dec al + jz 9f + vshufps zmm8, zmm4, zmm5, 214 + vpshufd zmm9, zmm4, 0x0F + vpshufd zmm4, zmm8, 0x39 + vshufps zmm8, zmm6, zmm7, 250 + vpblendmd zmm9 {k3}, zmm9, zmm8 + vpunpcklqdq zmm8, zmm7, zmm5 + vpblendmd zmm8 {k4}, zmm8, zmm6 + vpshufd zmm8, zmm8, 0x78 + vpunpckhdq zmm5, zmm5, zmm7 + vpunpckldq zmm6, zmm6, zmm5 + vpshufd zmm7, zmm6, 0x1E + vmovdqa32 zmm5, zmm9 + vmovdqa32 zmm6, zmm8 + jmp 9b +9: + vpxord zmm0, zmm0, zmm2 + vpxord zmm1, zmm1, zmm3 + mov eax, r13d + cmp rdx, r15 + jne 2b + vmovdqu xmmword ptr [rbx], xmm0 + vmovdqu xmmword ptr [rbx+0x10], xmm1 + vextracti128 xmmword ptr [rbx+0x20], ymm0, 0x01 + vextracti128 xmmword ptr [rbx+0x30], ymm1, 0x01 + vextracti32x4 xmmword ptr [rbx+0x4*0x10], zmm0, 0x02 + vextracti32x4 xmmword ptr [rbx+0x5*0x10], zmm1, 0x02 + vextracti32x4 xmmword ptr [rbx+0x6*0x10], zmm0, 0x03 + vextracti32x4 xmmword ptr [rbx+0x7*0x10], zmm1, 0x03 + vmovdqa xmm0, xmmword ptr [rsp] + vmovdqa xmm2, xmmword ptr [rsp+0x40] + vmovdqa32 xmm0 {k1}, xmmword ptr [rsp+0x1*0x10] + vmovdqa32 xmm2 {k1}, xmmword ptr [rsp+0x5*0x10] + vmovdqa xmmword ptr [rsp], xmm0 + vmovdqa xmmword ptr [rsp+0x40], xmm2 + add rbx, 128 + add rdi, 32 + sub rsi, 4 +3: + test esi, 0x2 + je 3f + vbroadcasti128 ymm0, xmmword ptr [rcx] + vbroadcasti128 ymm1, xmmword ptr [rcx+0x10] + vmovd xmm13, dword ptr [rsp] + vpinsrd xmm13, xmm13, dword ptr [rsp+0x40], 1 + vpinsrd xmm13, xmm13, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + vmovd xmm14, dword ptr [rsp+0x4] + vpinsrd xmm14, xmm14, dword ptr [rsp+0x44], 1 + vpinsrd xmm14, xmm14, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + vinserti128 ymm13, ymm13, xmm14, 0x01 + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +.p2align 5 +2: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + mov dword ptr [rsp+0x88], eax + vbroadcasti128 ymm2, xmmword ptr [BLAKE3_IV+rip] + vpbroadcastd ymm8, dword ptr [rsp+0x88] + vpblendd ymm3, ymm13, ymm8, 0x88 + vmovups ymm8, ymmword ptr [r8+rdx-0x40] + vinsertf128 ymm8, ymm8, xmmword ptr [r9+rdx-0x40], 0x01 + vmovups ymm9, ymmword ptr [r8+rdx-0x30] + vinsertf128 ymm9, ymm9, xmmword ptr [r9+rdx-0x30], 0x01 + vshufps ymm4, ymm8, ymm9, 136 + vshufps ymm5, ymm8, ymm9, 221 + vmovups ymm8, ymmword ptr [r8+rdx-0x20] + vinsertf128 ymm8, ymm8, xmmword ptr [r9+rdx-0x20], 0x01 + vmovups ymm9, ymmword ptr [r8+rdx-0x10] + vinsertf128 ymm9, ymm9, xmmword ptr [r9+rdx-0x10], 0x01 + vshufps ymm6, ymm8, ymm9, 136 + vshufps ymm7, ymm8, ymm9, 221 + vpshufd ymm6, ymm6, 0x93 + vpshufd ymm7, ymm7, 0x93 + mov al, 7 +9: + vpaddd ymm0, ymm0, ymm4 + vpaddd ymm0, ymm0, ymm1 + vpxord ymm3, ymm3, ymm0 + vprord ymm3, ymm3, 16 + vpaddd ymm2, ymm2, ymm3 + vpxord ymm1, ymm1, ymm2 + vprord ymm1, ymm1, 12 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm0, ymm0, ymm1 + vpxord ymm3, ymm3, ymm0 + vprord ymm3, ymm3, 8 + vpaddd ymm2, ymm2, ymm3 + vpxord ymm1, ymm1, ymm2 + vprord ymm1, ymm1, 7 + vpshufd ymm0, ymm0, 0x93 + vpshufd ymm3, ymm3, 0x4E + vpshufd ymm2, ymm2, 0x39 + vpaddd ymm0, ymm0, ymm6 + vpaddd ymm0, ymm0, ymm1 + vpxord ymm3, ymm3, ymm0 + vprord ymm3, ymm3, 16 + vpaddd ymm2, ymm2, ymm3 + vpxord ymm1, ymm1, ymm2 + vprord ymm1, ymm1, 12 + vpaddd ymm0, ymm0, ymm7 + vpaddd ymm0, ymm0, ymm1 + vpxord ymm3, ymm3, ymm0 + vprord ymm3, ymm3, 8 + vpaddd ymm2, ymm2, ymm3 + vpxord ymm1, ymm1, ymm2 + vprord ymm1, ymm1, 7 + vpshufd ymm0, ymm0, 0x39 + vpshufd ymm3, ymm3, 0x4E + vpshufd ymm2, ymm2, 0x93 + dec al + jz 9f + vshufps ymm8, ymm4, ymm5, 214 + vpshufd ymm9, ymm4, 0x0F + vpshufd ymm4, ymm8, 0x39 + vshufps ymm8, ymm6, ymm7, 250 + vpblendd ymm9, ymm9, ymm8, 0xAA + vpunpcklqdq ymm8, ymm7, ymm5 + vpblendd ymm8, ymm8, ymm6, 0x88 + vpshufd ymm8, ymm8, 0x78 + vpunpckhdq ymm5, ymm5, ymm7 + vpunpckldq ymm6, ymm6, ymm5 + vpshufd ymm7, ymm6, 0x1E + vmovdqa ymm5, ymm9 + vmovdqa ymm6, ymm8 + jmp 9b +9: + vpxor ymm0, ymm0, ymm2 + vpxor ymm1, ymm1, ymm3 + mov eax, r13d + cmp rdx, r15 + jne 2b + vmovdqu xmmword ptr [rbx], xmm0 + vmovdqu xmmword ptr [rbx+0x10], xmm1 + vextracti128 xmmword ptr [rbx+0x20], ymm0, 0x01 + vextracti128 xmmword ptr [rbx+0x30], ymm1, 0x01 + vmovdqa xmm0, xmmword ptr [rsp] + vmovdqa xmm2, xmmword ptr [rsp+0x4*0x10] + vmovdqu32 xmm0 {k1}, xmmword ptr [rsp+0x8] + vmovdqu32 xmm2 {k1}, xmmword ptr [rsp+0x48] + vmovdqa xmmword ptr [rsp], xmm0 + vmovdqa xmmword ptr [rsp+0x4*0x10], xmm2 + add rbx, 64 + add rdi, 16 + sub rsi, 2 +3: + test esi, 0x1 + je 4b + vmovdqu xmm0, xmmword ptr [rcx] + vmovdqu xmm1, xmmword ptr [rcx+0x10] + vmovd xmm14, dword ptr [rsp] + vpinsrd xmm14, xmm14, dword ptr [rsp+0x40], 1 + vpinsrd xmm14, xmm14, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + vmovdqa xmm15, xmmword ptr [BLAKE3_IV+rip] + mov r8, qword ptr [rdi] + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +.p2align 5 +2: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + vpinsrd xmm3, xmm14, eax, 3 + vmovdqa xmm2, xmm15 + vmovups xmm8, xmmword ptr [r8+rdx-0x40] + vmovups xmm9, xmmword ptr [r8+rdx-0x30] + vshufps xmm4, xmm8, xmm9, 136 + vshufps xmm5, xmm8, xmm9, 221 + vmovups xmm8, xmmword ptr [r8+rdx-0x20] + vmovups xmm9, xmmword ptr [r8+rdx-0x10] + vshufps xmm6, xmm8, xmm9, 136 + vshufps xmm7, xmm8, xmm9, 221 + vpshufd xmm6, xmm6, 0x93 + vpshufd xmm7, xmm7, 0x93 + mov al, 7 +9: + vpaddd xmm0, xmm0, xmm4 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 16 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 12 + vpaddd xmm0, xmm0, xmm5 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 8 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 7 + vpshufd xmm0, xmm0, 0x93 + vpshufd xmm3, xmm3, 0x4E + vpshufd xmm2, xmm2, 0x39 + vpaddd xmm0, xmm0, xmm6 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 16 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 12 + vpaddd xmm0, xmm0, xmm7 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 8 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 7 + vpshufd xmm0, xmm0, 0x39 + vpshufd xmm3, xmm3, 0x4E + vpshufd xmm2, xmm2, 0x93 + dec al + jz 9f + vshufps xmm8, xmm4, xmm5, 214 + vpshufd xmm9, xmm4, 0x0F + vpshufd xmm4, xmm8, 0x39 + vshufps xmm8, xmm6, xmm7, 250 + vpblendd xmm9, xmm9, xmm8, 0xAA + vpunpcklqdq xmm8, xmm7, xmm5 + vpblendd xmm8, xmm8, xmm6, 0x88 + vpshufd xmm8, xmm8, 0x78 + vpunpckhdq xmm5, xmm5, xmm7 + vpunpckldq xmm6, xmm6, xmm5 + vpshufd xmm7, xmm6, 0x1E + vmovdqa xmm5, xmm9 + vmovdqa xmm6, xmm8 + jmp 9b +9: + vpxor xmm0, xmm0, xmm2 + vpxor xmm1, xmm1, xmm3 + mov eax, r13d + cmp rdx, r15 + jne 2b + vmovdqu xmmword ptr [rbx], xmm0 + vmovdqu xmmword ptr [rbx+0x10], xmm1 + jmp 4b +.p2align 6 +_blake3_compress_in_place_avx512: +blake3_compress_in_place_avx512: + vmovdqu xmm0, xmmword ptr [rdi] + vmovdqu xmm1, xmmword ptr [rdi+0x10] + movzx eax, r8b + movzx edx, dl + shl rax, 32 + add rdx, rax + vmovq xmm3, rcx + vmovq xmm4, rdx + vpunpcklqdq xmm3, xmm3, xmm4 + vmovaps xmm2, xmmword ptr [BLAKE3_IV+rip] + vmovups xmm8, xmmword ptr [rsi] + vmovups xmm9, xmmword ptr [rsi+0x10] + vshufps xmm4, xmm8, xmm9, 136 + vshufps xmm5, xmm8, xmm9, 221 + vmovups xmm8, xmmword ptr [rsi+0x20] + vmovups xmm9, xmmword ptr [rsi+0x30] + vshufps xmm6, xmm8, xmm9, 136 + vshufps xmm7, xmm8, xmm9, 221 + vpshufd xmm6, xmm6, 0x93 + vpshufd xmm7, xmm7, 0x93 + mov al, 7 +9: + vpaddd xmm0, xmm0, xmm4 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 16 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 12 + vpaddd xmm0, xmm0, xmm5 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 8 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 7 + vpshufd xmm0, xmm0, 0x93 + vpshufd xmm3, xmm3, 0x4E + vpshufd xmm2, xmm2, 0x39 + vpaddd xmm0, xmm0, xmm6 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 16 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 12 + vpaddd xmm0, xmm0, xmm7 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 8 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 7 + vpshufd xmm0, xmm0, 0x39 + vpshufd xmm3, xmm3, 0x4E + vpshufd xmm2, xmm2, 0x93 + dec al + jz 9f + vshufps xmm8, xmm4, xmm5, 214 + vpshufd xmm9, xmm4, 0x0F + vpshufd xmm4, xmm8, 0x39 + vshufps xmm8, xmm6, xmm7, 250 + vpblendd xmm9, xmm9, xmm8, 0xAA + vpunpcklqdq xmm8, xmm7, xmm5 + vpblendd xmm8, xmm8, xmm6, 0x88 + vpshufd xmm8, xmm8, 0x78 + vpunpckhdq xmm5, xmm5, xmm7 + vpunpckldq xmm6, xmm6, xmm5 + vpshufd xmm7, xmm6, 0x1E + vmovdqa xmm5, xmm9 + vmovdqa xmm6, xmm8 + jmp 9b +9: + vpxor xmm0, xmm0, xmm2 + vpxor xmm1, xmm1, xmm3 + vmovdqu xmmword ptr [rdi], xmm0 + vmovdqu xmmword ptr [rdi+0x10], xmm1 + ret + +.p2align 6 +_blake3_compress_xof_avx512: +blake3_compress_xof_avx512: + vmovdqu xmm0, xmmword ptr [rdi] + vmovdqu xmm1, xmmword ptr [rdi+0x10] + movzx eax, r8b + movzx edx, dl + shl rax, 32 + add rdx, rax + vmovq xmm3, rcx + vmovq xmm4, rdx + vpunpcklqdq xmm3, xmm3, xmm4 + vmovaps xmm2, xmmword ptr [BLAKE3_IV+rip] + vmovups xmm8, xmmword ptr [rsi] + vmovups xmm9, xmmword ptr [rsi+0x10] + vshufps xmm4, xmm8, xmm9, 136 + vshufps xmm5, xmm8, xmm9, 221 + vmovups xmm8, xmmword ptr [rsi+0x20] + vmovups xmm9, xmmword ptr [rsi+0x30] + vshufps xmm6, xmm8, xmm9, 136 + vshufps xmm7, xmm8, xmm9, 221 + vpshufd xmm6, xmm6, 0x93 + vpshufd xmm7, xmm7, 0x93 + mov al, 7 +9: + vpaddd xmm0, xmm0, xmm4 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 16 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 12 + vpaddd xmm0, xmm0, xmm5 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 8 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 7 + vpshufd xmm0, xmm0, 0x93 + vpshufd xmm3, xmm3, 0x4E + vpshufd xmm2, xmm2, 0x39 + vpaddd xmm0, xmm0, xmm6 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 16 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 12 + vpaddd xmm0, xmm0, xmm7 + vpaddd xmm0, xmm0, xmm1 + vpxord xmm3, xmm3, xmm0 + vprord xmm3, xmm3, 8 + vpaddd xmm2, xmm2, xmm3 + vpxord xmm1, xmm1, xmm2 + vprord xmm1, xmm1, 7 + vpshufd xmm0, xmm0, 0x39 + vpshufd xmm3, xmm3, 0x4E + vpshufd xmm2, xmm2, 0x93 + dec al + jz 9f + vshufps xmm8, xmm4, xmm5, 214 + vpshufd xmm9, xmm4, 0x0F + vpshufd xmm4, xmm8, 0x39 + vshufps xmm8, xmm6, xmm7, 250 + vpblendd xmm9, xmm9, xmm8, 0xAA + vpunpcklqdq xmm8, xmm7, xmm5 + vpblendd xmm8, xmm8, xmm6, 0x88 + vpshufd xmm8, xmm8, 0x78 + vpunpckhdq xmm5, xmm5, xmm7 + vpunpckldq xmm6, xmm6, xmm5 + vpshufd xmm7, xmm6, 0x1E + vmovdqa xmm5, xmm9 + vmovdqa xmm6, xmm8 + jmp 9b +9: + vpxor xmm0, xmm0, xmm2 + vpxor xmm1, xmm1, xmm3 + vpxor xmm2, xmm2, [rdi] + vpxor xmm3, xmm3, [rdi+0x10] + vmovdqu xmmword ptr [r9], xmm0 + vmovdqu xmmword ptr [r9+0x10], xmm1 + vmovdqu xmmword ptr [r9+0x20], xmm2 + vmovdqu xmmword ptr [r9+0x30], xmm3 + ret + +#ifdef __APPLE__ +.static_data +#else +.section .rodata +#endif +.p2align 6 +INDEX0: + .long 0, 1, 2, 3, 16, 17, 18, 19 + .long 8, 9, 10, 11, 24, 25, 26, 27 +INDEX1: + .long 4, 5, 6, 7, 20, 21, 22, 23 + .long 12, 13, 14, 15, 28, 29, 30, 31 +ADD0: + .long 0, 1, 2, 3, 4, 5, 6, 7 + .long 8, 9, 10, 11, 12, 13, 14, 15 +ADD1: .long 1 + +ADD16: .long 16 +BLAKE3_BLOCK_LEN: + .long 64 +.p2align 6 +BLAKE3_IV: +BLAKE3_IV_0: + .long 0x6A09E667 +BLAKE3_IV_1: + .long 0xBB67AE85 +BLAKE3_IV_2: + .long 0x3C6EF372 +BLAKE3_IV_3: + .long 0xA54FF53A + +#endif // __x86_64__ diff --git a/src/b3/blake3_dispatch.c b/src/b3/blake3_dispatch.c index 820b3dfe..26c78a2b 100644 --- a/src/b3/blake3_dispatch.c +++ b/src/b3/blake3_dispatch.c @@ -1,249 +1,249 @@ -#include -#include -#include - -#include "blake3_impl.h" - -#if defined(IS_X86) -#if defined(_MSC_VER) -#include -#elif defined(__GNUC__) -#include -#else -#error "Unimplemented!" -#endif -#endif - -#if defined(IS_X86) -static uint64_t xgetbv() { -#if defined(_MSC_VER) - return _xgetbv(0); -#else - uint32_t eax = 0, edx = 0; - __asm__ __volatile__("xgetbv\n" : "=a"(eax), "=d"(edx) : "c"(0)); - return ((uint64_t)edx << 32) | eax; -#endif -} - -static void cpuid(uint32_t out[4], uint32_t id) { -#if defined(_MSC_VER) - __cpuid((int *)out, id); -#elif defined(__i386__) || defined(_M_IX86) - __asm__ __volatile__("movl %%ebx, %1\n" - "cpuid\n" - "xchgl %1, %%ebx\n" - : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) - : "a"(id)); -#else - __asm__ __volatile__("cpuid\n" - : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) - : "a"(id)); -#endif -} - -static void cpuidex(uint32_t out[4], uint32_t id, uint32_t sid) { -#if defined(_MSC_VER) - __cpuidex((int *)out, id, sid); -#elif defined(__i386__) || defined(_M_IX86) - __asm__ __volatile__("movl %%ebx, %1\n" - "cpuid\n" - "xchgl %1, %%ebx\n" - : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) - : "a"(id), "c"(sid)); -#else - __asm__ __volatile__("cpuid\n" - : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) - : "a"(id), "c"(sid)); -#endif -} - -#endif - -enum cpu_feature { - SSE2 = 1 << 0, - SSSE3 = 1 << 1, - SSE41 = 1 << 2, - AVX = 1 << 3, - AVX2 = 1 << 4, - AVX512F = 1 << 5, - AVX512VL = 1 << 6, - /* ... */ - UNDEFINED = 1 << 30 -}; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" - -#if !defined(BLAKE3_TESTING) -static /* Allow the variable to be controlled manually for testing */ -#endif - enum cpu_feature g_cpu_features = UNDEFINED; - -#if !defined(BLAKE3_TESTING) -static -#endif - enum cpu_feature - get_cpu_features() { - - if (g_cpu_features != UNDEFINED) { - return g_cpu_features; - } else { -#if defined(IS_X86) - uint32_t regs[4] = {0}; - uint32_t *eax = ®s[0], *ebx = ®s[1], *ecx = ®s[2], *edx = ®s[3]; - (void)edx; - enum cpu_feature features = 0; - cpuid(regs, 0); - const int max_id = *eax; - cpuid(regs, 1); -#if defined(__amd64__) || defined(_M_X64) - features |= SSE2; -#else - if (*edx & (1UL << 26)) - features |= SSE2; -#endif - if (*ecx & (1UL << 0)) - features |= SSSE3; - if (*ecx & (1UL << 19)) - features |= SSE41; - - if (*ecx & (1UL << 27)) { // OSXSAVE - const uint64_t mask = xgetbv(); - if ((mask & 6) == 6) { // SSE and AVX states - if (*ecx & (1UL << 28)) - features |= AVX; - if (max_id >= 7) { - cpuidex(regs, 7, 0); - if (*ebx & (1UL << 5)) - features |= AVX2; - if ((mask & 224) == 224) { // Opmask, ZMM_Hi256, Hi16_Zmm - if (*ebx & (1UL << 31)) - features |= AVX512VL; - if (*ebx & (1UL << 16)) - features |= AVX512F; - } - } - } - } - g_cpu_features = features; - return features; -#else - /* How to detect NEON? */ - return 0; -#endif - } -} - -void blake3_compress_in_place(uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags) { -#if defined(IS_X86) - const enum cpu_feature features = get_cpu_features(); -#if !defined(BLAKE3_NO_AVX512) - if (features & AVX512VL) { - blake3_compress_in_place_avx512(cv, block, block_len, counter, flags); - return; - } -#endif -#if !defined(BLAKE3_NO_SSE41) - if (features & SSE41) { - blake3_compress_in_place_sse41(cv, block, block_len, counter, flags); - return; - } -#endif -#endif - blake3_compress_in_place_portable(cv, block, block_len, counter, flags); -} -#pragma GCC diagnostic pop - -void blake3_compress_xof(const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, uint8_t flags, - uint8_t out[64]) { -#if defined(IS_X86) - const enum cpu_feature features = get_cpu_features(); -#if !defined(BLAKE3_NO_AVX512) - if (features & AVX512VL) { - blake3_compress_xof_avx512(cv, block, block_len, counter, flags, out); - return; - } -#endif -#if !defined(BLAKE3_NO_SSE41) - if (features & SSE41) { - blake3_compress_xof_sse41(cv, block, block_len, counter, flags, out); - return; - } -#endif -#endif - blake3_compress_xof_portable(cv, block, block_len, counter, flags, out); -} - -void blake3_hash_many(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], uint64_t counter, - bool increment_counter, uint8_t flags, - uint8_t flags_start, uint8_t flags_end, uint8_t *out) { -#if defined(IS_X86) - const enum cpu_feature features = get_cpu_features(); -#if !defined(BLAKE3_NO_AVX512) - if ((features & (AVX512F|AVX512VL)) == (AVX512F|AVX512VL)) { - blake3_hash_many_avx512(inputs, num_inputs, blocks, key, counter, - increment_counter, flags, flags_start, flags_end, - out); - return; - } -#endif -#if !defined(BLAKE3_NO_AVX2) - if (features & AVX2) { - blake3_hash_many_avx2(inputs, num_inputs, blocks, key, counter, - increment_counter, flags, flags_start, flags_end, - out); - return; - } -#endif -#if !defined(BLAKE3_NO_SSE41) - if (features & SSE41) { - blake3_hash_many_sse41(inputs, num_inputs, blocks, key, counter, - increment_counter, flags, flags_start, flags_end, - out); - return; - } -#endif -#endif - -#if defined(BLAKE3_USE_NEON) - blake3_hash_many_neon(inputs, num_inputs, blocks, key, counter, - increment_counter, flags, flags_start, flags_end, out); - return; -#endif - - blake3_hash_many_portable(inputs, num_inputs, blocks, key, counter, - increment_counter, flags, flags_start, flags_end, - out); -} - -// The dynamically detected SIMD degree of the current platform. -size_t blake3_simd_degree(void) { -#if defined(IS_X86) - const enum cpu_feature features = get_cpu_features(); -#if !defined(BLAKE3_NO_AVX512) - if ((features & (AVX512F|AVX512VL)) == (AVX512F|AVX512VL)) { - return 16; - } -#endif -#if !defined(BLAKE3_NO_AVX2) - if (features & AVX2) { - return 8; - } -#endif -#if !defined(BLAKE3_NO_SSE41) - if (features & SSE41) { - return 4; - } -#endif -#endif -#if defined(BLAKE3_USE_NEON) - return 4; -#endif - return 1; -} +#include +#include +#include + +#include "blake3_impl.h" + +#if defined(IS_X86) +#if defined(_MSC_VER) +#include +#elif defined(__GNUC__) +#include +#else +#error "Unimplemented!" +#endif +#endif + +#if defined(IS_X86) +static uint64_t xgetbv() { +#if defined(_MSC_VER) + return _xgetbv(0); +#else + uint32_t eax = 0, edx = 0; + __asm__ __volatile__("xgetbv\n" : "=a"(eax), "=d"(edx) : "c"(0)); + return ((uint64_t)edx << 32) | eax; +#endif +} + +static void cpuid(uint32_t out[4], uint32_t id) { +#if defined(_MSC_VER) + __cpuid((int *)out, id); +#elif defined(__i386__) || defined(_M_IX86) + __asm__ __volatile__("movl %%ebx, %1\n" + "cpuid\n" + "xchgl %1, %%ebx\n" + : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) + : "a"(id)); +#else + __asm__ __volatile__("cpuid\n" + : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) + : "a"(id)); +#endif +} + +static void cpuidex(uint32_t out[4], uint32_t id, uint32_t sid) { +#if defined(_MSC_VER) + __cpuidex((int *)out, id, sid); +#elif defined(__i386__) || defined(_M_IX86) + __asm__ __volatile__("movl %%ebx, %1\n" + "cpuid\n" + "xchgl %1, %%ebx\n" + : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) + : "a"(id), "c"(sid)); +#else + __asm__ __volatile__("cpuid\n" + : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) + : "a"(id), "c"(sid)); +#endif +} + +#endif + +enum cpu_feature { + SSE2 = 1 << 0, + SSSE3 = 1 << 1, + SSE41 = 1 << 2, + AVX = 1 << 3, + AVX2 = 1 << 4, + AVX512F = 1 << 5, + AVX512VL = 1 << 6, + /* ... */ + UNDEFINED = 1 << 30 +}; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + +#if !defined(BLAKE3_TESTING) +static /* Allow the variable to be controlled manually for testing */ +#endif + enum cpu_feature g_cpu_features = UNDEFINED; + +#if !defined(BLAKE3_TESTING) +static +#endif + enum cpu_feature + get_cpu_features() { + + if (g_cpu_features != UNDEFINED) { + return g_cpu_features; + } else { +#if defined(IS_X86) + uint32_t regs[4] = {0}; + uint32_t *eax = ®s[0], *ebx = ®s[1], *ecx = ®s[2], *edx = ®s[3]; + (void)edx; + enum cpu_feature features = 0; + cpuid(regs, 0); + const int max_id = *eax; + cpuid(regs, 1); +#if defined(__amd64__) || defined(_M_X64) + features |= SSE2; +#else + if (*edx & (1UL << 26)) + features |= SSE2; +#endif + if (*ecx & (1UL << 0)) + features |= SSSE3; + if (*ecx & (1UL << 19)) + features |= SSE41; + + if (*ecx & (1UL << 27)) { // OSXSAVE + const uint64_t mask = xgetbv(); + if ((mask & 6) == 6) { // SSE and AVX states + if (*ecx & (1UL << 28)) + features |= AVX; + if (max_id >= 7) { + cpuidex(regs, 7, 0); + if (*ebx & (1UL << 5)) + features |= AVX2; + if ((mask & 224) == 224) { // Opmask, ZMM_Hi256, Hi16_Zmm + if (*ebx & (1UL << 31)) + features |= AVX512VL; + if (*ebx & (1UL << 16)) + features |= AVX512F; + } + } + } + } + g_cpu_features = features; + return features; +#else + /* How to detect NEON? */ + return 0; +#endif + } +} + +void blake3_compress_in_place(uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags) { +#if defined(IS_X86) + const enum cpu_feature features = get_cpu_features(); +#if !defined(BLAKE3_NO_AVX512) + if (features & AVX512VL) { + blake3_compress_in_place_avx512(cv, block, block_len, counter, flags); + return; + } +#endif +#if !defined(BLAKE3_NO_SSE41) + if (features & SSE41) { + blake3_compress_in_place_sse41(cv, block, block_len, counter, flags); + return; + } +#endif +#endif + blake3_compress_in_place_portable(cv, block, block_len, counter, flags); +} +#pragma GCC diagnostic pop + +void blake3_compress_xof(const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, uint8_t flags, + uint8_t out[64]) { +#if defined(IS_X86) + const enum cpu_feature features = get_cpu_features(); +#if !defined(BLAKE3_NO_AVX512) + if (features & AVX512VL) { + blake3_compress_xof_avx512(cv, block, block_len, counter, flags, out); + return; + } +#endif +#if !defined(BLAKE3_NO_SSE41) + if (features & SSE41) { + blake3_compress_xof_sse41(cv, block, block_len, counter, flags, out); + return; + } +#endif +#endif + blake3_compress_xof_portable(cv, block, block_len, counter, flags, out); +} + +void blake3_hash_many(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], uint64_t counter, + bool increment_counter, uint8_t flags, + uint8_t flags_start, uint8_t flags_end, uint8_t *out) { +#if defined(IS_X86) + const enum cpu_feature features = get_cpu_features(); +#if !defined(BLAKE3_NO_AVX512) + if ((features & (AVX512F|AVX512VL)) == (AVX512F|AVX512VL)) { + blake3_hash_many_avx512(inputs, num_inputs, blocks, key, counter, + increment_counter, flags, flags_start, flags_end, + out); + return; + } +#endif +#if !defined(BLAKE3_NO_AVX2) + if (features & AVX2) { + blake3_hash_many_avx2(inputs, num_inputs, blocks, key, counter, + increment_counter, flags, flags_start, flags_end, + out); + return; + } +#endif +#if !defined(BLAKE3_NO_SSE41) + if (features & SSE41) { + blake3_hash_many_sse41(inputs, num_inputs, blocks, key, counter, + increment_counter, flags, flags_start, flags_end, + out); + return; + } +#endif +#endif + +#if defined(BLAKE3_USE_NEON) + blake3_hash_many_neon(inputs, num_inputs, blocks, key, counter, + increment_counter, flags, flags_start, flags_end, out); + return; +#endif + + blake3_hash_many_portable(inputs, num_inputs, blocks, key, counter, + increment_counter, flags, flags_start, flags_end, + out); +} + +// The dynamically detected SIMD degree of the current platform. +size_t blake3_simd_degree(void) { +#if defined(IS_X86) + const enum cpu_feature features = get_cpu_features(); +#if !defined(BLAKE3_NO_AVX512) + if ((features & (AVX512F|AVX512VL)) == (AVX512F|AVX512VL)) { + return 16; + } +#endif +#if !defined(BLAKE3_NO_AVX2) + if (features & AVX2) { + return 8; + } +#endif +#if !defined(BLAKE3_NO_SSE41) + if (features & SSE41) { + return 4; + } +#endif +#endif +#if defined(BLAKE3_USE_NEON) + return 4; +#endif + return 1; +} diff --git a/src/b3/blake3_impl.h b/src/b3/blake3_impl.h index c384671f..1e58e7a8 100644 --- a/src/b3/blake3_impl.h +++ b/src/b3/blake3_impl.h @@ -1,235 +1,235 @@ -#ifndef BLAKE3_IMPL_H -#define BLAKE3_IMPL_H - -#include -#include -#include -#include -#include - -#include "blake3.h" - -// internal flags -enum blake3_flags { - CHUNK_START = 1 << 0, - CHUNK_END = 1 << 1, - PARENT = 1 << 2, - ROOT = 1 << 3, - KEYED_HASH = 1 << 4, - DERIVE_KEY_CONTEXT = 1 << 5, - DERIVE_KEY_MATERIAL = 1 << 6, -}; - -// This C implementation tries to support recent versions of GCC, Clang, and -// MSVC. -#if defined(_MSC_VER) -#define INLINE static __forceinline -#else -#define INLINE static inline __attribute__((always_inline)) -#endif - -#if defined(__x86_64__) || defined(_M_X64) -#define IS_X86 -#define IS_X86_64 -#endif - -#if defined(__i386__) || defined(_M_IX86) -#define IS_X86 -#define IS_X86_32 -#endif - -#if defined(IS_X86) -#if defined(_MSC_VER) -#include -#endif -#include -#endif - -#if defined(IS_X86) -#define MAX_SIMD_DEGREE 16 -#elif defined(BLAKE3_USE_NEON) -#define MAX_SIMD_DEGREE 4 -#else -#define MAX_SIMD_DEGREE 1 -#endif - -// There are some places where we want a static size that's equal to the -// MAX_SIMD_DEGREE, but also at least 2. -#define MAX_SIMD_DEGREE_OR_2 (MAX_SIMD_DEGREE > 2 ? MAX_SIMD_DEGREE : 2) - -static const uint32_t IV[8] = {0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, - 0xA54FF53AUL, 0x510E527FUL, 0x9B05688CUL, - 0x1F83D9ABUL, 0x5BE0CD19UL}; - -static const uint8_t MSG_SCHEDULE[7][16] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - {2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8}, - {3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1}, - {10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6}, - {12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4}, - {9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7}, - {11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13}, -}; - -/* Find index of the highest set bit */ -/* x is assumed to be nonzero. */ -static unsigned int highest_one(uint64_t x) { -#if defined(__GNUC__) || defined(__clang__) - return 63 ^ __builtin_clzll(x); -#elif defined(_MSC_VER) && defined(IS_X86_64) - unsigned long index; - _BitScanReverse64(&index, x); - return index; -#elif defined(_MSC_VER) && defined(IS_X86_32) - if(x >> 32) { - unsigned long index; - _BitScanReverse(&index, x >> 32); - return 32 + index; - } else { - unsigned long index; - _BitScanReverse(&index, x); - return index; - } -#else - unsigned int c = 0; - if(x & 0xffffffff00000000ULL) { x >>= 32; c += 32; } - if(x & 0x00000000ffff0000ULL) { x >>= 16; c += 16; } - if(x & 0x000000000000ff00ULL) { x >>= 8; c += 8; } - if(x & 0x00000000000000f0ULL) { x >>= 4; c += 4; } - if(x & 0x000000000000000cULL) { x >>= 2; c += 2; } - if(x & 0x0000000000000002ULL) { c += 1; } - return c; -#endif -} - -// Count the number of 1 bits. -INLINE unsigned int popcnt(uint64_t x) { -#if defined(__GNUC__) || defined(__clang__) - return __builtin_popcountll(x); -#else - unsigned int count = 0; - while (x != 0) { - count += 1; - x &= x - 1; - } - return count; -#endif -} - -// Largest power of two less than or equal to x. As a special case, returns 1 -// when x is 0. -INLINE uint64_t round_down_to_power_of_2(uint64_t x) { - return 1ULL << highest_one(x | 1); -} - -INLINE uint32_t counter_low(uint64_t counter) { return (uint32_t)counter; } - -INLINE uint32_t counter_high(uint64_t counter) { - return (uint32_t)(counter >> 32); -} - -INLINE uint32_t load32(const void *src) { - const uint8_t *p = (const uint8_t *)src; - return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) | - ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24); -} - -INLINE void load_key_words(const uint8_t key[BLAKE3_KEY_LEN], - uint32_t key_words[8]) { - key_words[0] = load32(&key[0 * 4]); - key_words[1] = load32(&key[1 * 4]); - key_words[2] = load32(&key[2 * 4]); - key_words[3] = load32(&key[3 * 4]); - key_words[4] = load32(&key[4 * 4]); - key_words[5] = load32(&key[5 * 4]); - key_words[6] = load32(&key[6 * 4]); - key_words[7] = load32(&key[7 * 4]); -} - -void blake3_compress_in_place(uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags); - -void blake3_compress_xof(const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, uint8_t flags, - uint8_t out[64]); - -void blake3_hash_many(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], uint64_t counter, - bool increment_counter, uint8_t flags, - uint8_t flags_start, uint8_t flags_end, uint8_t *out); - -size_t blake3_simd_degree(void); - - -// Declarations for implementation-specific functions. -void blake3_compress_in_place_portable(uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags); - -void blake3_compress_xof_portable(const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags, uint8_t out[64]); - -void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out); - -#if defined(IS_X86) -#if !defined(BLAKE3_NO_SSE41) -void blake3_compress_in_place_sse41(uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags); -void blake3_compress_xof_sse41(const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags, uint8_t out[64]); -void blake3_hash_many_sse41(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out); -#endif -#if !defined(BLAKE3_NO_AVX2) -void blake3_hash_many_avx2(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out); -#endif -#if !defined(BLAKE3_NO_AVX512) -void blake3_compress_in_place_avx512(uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags); - -void blake3_compress_xof_avx512(const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags, uint8_t out[64]); - -void blake3_hash_many_avx512(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out); -#endif -#endif - -#if defined(BLAKE3_USE_NEON) -void blake3_hash_many_neon(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out); -#endif - - -#endif /* BLAKE3_IMPL_H */ +#ifndef BLAKE3_IMPL_H +#define BLAKE3_IMPL_H + +#include +#include +#include +#include +#include + +#include "blake3.h" + +// internal flags +enum blake3_flags { + CHUNK_START = 1 << 0, + CHUNK_END = 1 << 1, + PARENT = 1 << 2, + ROOT = 1 << 3, + KEYED_HASH = 1 << 4, + DERIVE_KEY_CONTEXT = 1 << 5, + DERIVE_KEY_MATERIAL = 1 << 6, +}; + +// This C implementation tries to support recent versions of GCC, Clang, and +// MSVC. +#if defined(_MSC_VER) +#define INLINE static __forceinline +#else +#define INLINE static inline __attribute__((always_inline)) +#endif + +#if defined(__x86_64__) || defined(_M_X64) +#define IS_X86 +#define IS_X86_64 +#endif + +#if defined(__i386__) || defined(_M_IX86) +#define IS_X86 +#define IS_X86_32 +#endif + +#if defined(IS_X86) +#if defined(_MSC_VER) +#include +#endif +#include +#endif + +#if defined(IS_X86) +#define MAX_SIMD_DEGREE 16 +#elif defined(BLAKE3_USE_NEON) +#define MAX_SIMD_DEGREE 4 +#else +#define MAX_SIMD_DEGREE 1 +#endif + +// There are some places where we want a static size that's equal to the +// MAX_SIMD_DEGREE, but also at least 2. +#define MAX_SIMD_DEGREE_OR_2 (MAX_SIMD_DEGREE > 2 ? MAX_SIMD_DEGREE : 2) + +static const uint32_t IV[8] = {0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, + 0xA54FF53AUL, 0x510E527FUL, 0x9B05688CUL, + 0x1F83D9ABUL, 0x5BE0CD19UL}; + +static const uint8_t MSG_SCHEDULE[7][16] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8}, + {3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1}, + {10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6}, + {12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4}, + {9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7}, + {11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13}, +}; + +/* Find index of the highest set bit */ +/* x is assumed to be nonzero. */ +static unsigned int highest_one(uint64_t x) { +#if defined(__GNUC__) || defined(__clang__) + return 63 ^ __builtin_clzll(x); +#elif defined(_MSC_VER) && defined(IS_X86_64) + unsigned long index; + _BitScanReverse64(&index, x); + return index; +#elif defined(_MSC_VER) && defined(IS_X86_32) + if(x >> 32) { + unsigned long index; + _BitScanReverse(&index, x >> 32); + return 32 + index; + } else { + unsigned long index; + _BitScanReverse(&index, x); + return index; + } +#else + unsigned int c = 0; + if(x & 0xffffffff00000000ULL) { x >>= 32; c += 32; } + if(x & 0x00000000ffff0000ULL) { x >>= 16; c += 16; } + if(x & 0x000000000000ff00ULL) { x >>= 8; c += 8; } + if(x & 0x00000000000000f0ULL) { x >>= 4; c += 4; } + if(x & 0x000000000000000cULL) { x >>= 2; c += 2; } + if(x & 0x0000000000000002ULL) { c += 1; } + return c; +#endif +} + +// Count the number of 1 bits. +INLINE unsigned int popcnt(uint64_t x) { +#if defined(__GNUC__) || defined(__clang__) + return __builtin_popcountll(x); +#else + unsigned int count = 0; + while (x != 0) { + count += 1; + x &= x - 1; + } + return count; +#endif +} + +// Largest power of two less than or equal to x. As a special case, returns 1 +// when x is 0. +INLINE uint64_t round_down_to_power_of_2(uint64_t x) { + return 1ULL << highest_one(x | 1); +} + +INLINE uint32_t counter_low(uint64_t counter) { return (uint32_t)counter; } + +INLINE uint32_t counter_high(uint64_t counter) { + return (uint32_t)(counter >> 32); +} + +INLINE uint32_t load32(const void *src) { + const uint8_t *p = (const uint8_t *)src; + return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) | + ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24); +} + +INLINE void load_key_words(const uint8_t key[BLAKE3_KEY_LEN], + uint32_t key_words[8]) { + key_words[0] = load32(&key[0 * 4]); + key_words[1] = load32(&key[1 * 4]); + key_words[2] = load32(&key[2 * 4]); + key_words[3] = load32(&key[3 * 4]); + key_words[4] = load32(&key[4 * 4]); + key_words[5] = load32(&key[5 * 4]); + key_words[6] = load32(&key[6 * 4]); + key_words[7] = load32(&key[7 * 4]); +} + +void blake3_compress_in_place(uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags); + +void blake3_compress_xof(const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, uint8_t flags, + uint8_t out[64]); + +void blake3_hash_many(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], uint64_t counter, + bool increment_counter, uint8_t flags, + uint8_t flags_start, uint8_t flags_end, uint8_t *out); + +size_t blake3_simd_degree(void); + + +// Declarations for implementation-specific functions. +void blake3_compress_in_place_portable(uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags); + +void blake3_compress_xof_portable(const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags, uint8_t out[64]); + +void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out); + +#if defined(IS_X86) +#if !defined(BLAKE3_NO_SSE41) +void blake3_compress_in_place_sse41(uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags); +void blake3_compress_xof_sse41(const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags, uint8_t out[64]); +void blake3_hash_many_sse41(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out); +#endif +#if !defined(BLAKE3_NO_AVX2) +void blake3_hash_many_avx2(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out); +#endif +#if !defined(BLAKE3_NO_AVX512) +void blake3_compress_in_place_avx512(uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags); + +void blake3_compress_xof_avx512(const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags, uint8_t out[64]); + +void blake3_hash_many_avx512(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out); +#endif +#endif + +#if defined(BLAKE3_USE_NEON) +void blake3_hash_many_neon(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out); +#endif + + +#endif /* BLAKE3_IMPL_H */ diff --git a/src/b3/blake3_portable.c b/src/b3/blake3_portable.c index 9ee2f4a4..12ffdbfd 100644 --- a/src/b3/blake3_portable.c +++ b/src/b3/blake3_portable.c @@ -1,168 +1,168 @@ -#include "blake3_impl.h" -#include - -INLINE void store32(void *dst, uint32_t w) { - uint8_t *p = (uint8_t *)dst; - p[0] = (uint8_t)(w >> 0); - p[1] = (uint8_t)(w >> 8); - p[2] = (uint8_t)(w >> 16); - p[3] = (uint8_t)(w >> 24); -} - -INLINE uint32_t rotr32(uint32_t w, uint32_t c) { - return (w >> c) | (w << (32 - c)); -} - -INLINE void g(uint32_t *state, size_t a, size_t b, size_t c, size_t d, - uint32_t x, uint32_t y) { - state[a] = state[a] + state[b] + x; - state[d] = rotr32(state[d] ^ state[a], 16); - state[c] = state[c] + state[d]; - state[b] = rotr32(state[b] ^ state[c], 12); - state[a] = state[a] + state[b] + y; - state[d] = rotr32(state[d] ^ state[a], 8); - state[c] = state[c] + state[d]; - state[b] = rotr32(state[b] ^ state[c], 7); -} - -INLINE void round_fn(uint32_t state[16], const uint32_t *msg, size_t round) { - // Select the message schedule based on the round. - const uint8_t *schedule = MSG_SCHEDULE[round]; - - // Mix the columns. - g(state, 0, 4, 8, 12, msg[schedule[0]], msg[schedule[1]]); - g(state, 1, 5, 9, 13, msg[schedule[2]], msg[schedule[3]]); - g(state, 2, 6, 10, 14, msg[schedule[4]], msg[schedule[5]]); - g(state, 3, 7, 11, 15, msg[schedule[6]], msg[schedule[7]]); - - // Mix the rows. - g(state, 0, 5, 10, 15, msg[schedule[8]], msg[schedule[9]]); - g(state, 1, 6, 11, 12, msg[schedule[10]], msg[schedule[11]]); - g(state, 2, 7, 8, 13, msg[schedule[12]], msg[schedule[13]]); - g(state, 3, 4, 9, 14, msg[schedule[14]], msg[schedule[15]]); -} - -INLINE void compress_pre(uint32_t state[16], const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, uint8_t flags) { - uint32_t block_words[16]; - block_words[0] = load32(block + 4 * 0); - block_words[1] = load32(block + 4 * 1); - block_words[2] = load32(block + 4 * 2); - block_words[3] = load32(block + 4 * 3); - block_words[4] = load32(block + 4 * 4); - block_words[5] = load32(block + 4 * 5); - block_words[6] = load32(block + 4 * 6); - block_words[7] = load32(block + 4 * 7); - block_words[8] = load32(block + 4 * 8); - block_words[9] = load32(block + 4 * 9); - block_words[10] = load32(block + 4 * 10); - block_words[11] = load32(block + 4 * 11); - block_words[12] = load32(block + 4 * 12); - block_words[13] = load32(block + 4 * 13); - block_words[14] = load32(block + 4 * 14); - block_words[15] = load32(block + 4 * 15); - - state[0] = cv[0]; - state[1] = cv[1]; - state[2] = cv[2]; - state[3] = cv[3]; - state[4] = cv[4]; - state[5] = cv[5]; - state[6] = cv[6]; - state[7] = cv[7]; - state[8] = IV[0]; - state[9] = IV[1]; - state[10] = IV[2]; - state[11] = IV[3]; - state[12] = counter_low(counter); - state[13] = counter_high(counter); - state[14] = (uint32_t)block_len; - state[15] = (uint32_t)flags; - - round_fn(state, &block_words[0], 0); - round_fn(state, &block_words[0], 1); - round_fn(state, &block_words[0], 2); - round_fn(state, &block_words[0], 3); - round_fn(state, &block_words[0], 4); - round_fn(state, &block_words[0], 5); - round_fn(state, &block_words[0], 6); -} - -void blake3_compress_in_place_portable(uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags) { - uint32_t state[16]; - compress_pre(state, cv, block, block_len, counter, flags); - cv[0] = state[0] ^ state[8]; - cv[1] = state[1] ^ state[9]; - cv[2] = state[2] ^ state[10]; - cv[3] = state[3] ^ state[11]; - cv[4] = state[4] ^ state[12]; - cv[5] = state[5] ^ state[13]; - cv[6] = state[6] ^ state[14]; - cv[7] = state[7] ^ state[15]; -} - -void blake3_compress_xof_portable(const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags, uint8_t out[64]) { - uint32_t state[16]; - compress_pre(state, cv, block, block_len, counter, flags); - - store32(&out[0 * 4], state[0] ^ state[8]); - store32(&out[1 * 4], state[1] ^ state[9]); - store32(&out[2 * 4], state[2] ^ state[10]); - store32(&out[3 * 4], state[3] ^ state[11]); - store32(&out[4 * 4], state[4] ^ state[12]); - store32(&out[5 * 4], state[5] ^ state[13]); - store32(&out[6 * 4], state[6] ^ state[14]); - store32(&out[7 * 4], state[7] ^ state[15]); - store32(&out[8 * 4], state[8] ^ cv[0]); - store32(&out[9 * 4], state[9] ^ cv[1]); - store32(&out[10 * 4], state[10] ^ cv[2]); - store32(&out[11 * 4], state[11] ^ cv[3]); - store32(&out[12 * 4], state[12] ^ cv[4]); - store32(&out[13 * 4], state[13] ^ cv[5]); - store32(&out[14 * 4], state[14] ^ cv[6]); - store32(&out[15 * 4], state[15] ^ cv[7]); -} - -INLINE void hash_one_portable(const uint8_t *input, size_t blocks, - const uint32_t key[8], uint64_t counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t out[BLAKE3_OUT_LEN]) { - uint32_t cv[8]; - memcpy(cv, key, BLAKE3_KEY_LEN); - uint8_t block_flags = flags | flags_start; - while (blocks > 0) { - if (blocks == 1) { - block_flags |= flags_end; - } - blake3_compress_in_place_portable(cv, input, BLAKE3_BLOCK_LEN, counter, - block_flags); - input = &input[BLAKE3_BLOCK_LEN]; - blocks -= 1; - block_flags = flags; - } - memcpy(out, cv, 32); -} - -void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out) { - while (num_inputs > 0) { - hash_one_portable(inputs[0], blocks, key, counter, flags, flags_start, - flags_end, out); - if (increment_counter) { - counter += 1; - } - inputs += 1; - num_inputs -= 1; - out = &out[BLAKE3_OUT_LEN]; - } -} +#include "blake3_impl.h" +#include + +INLINE void store32(void *dst, uint32_t w) { + uint8_t *p = (uint8_t *)dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); +} + +INLINE uint32_t rotr32(uint32_t w, uint32_t c) { + return (w >> c) | (w << (32 - c)); +} + +INLINE void g(uint32_t *state, size_t a, size_t b, size_t c, size_t d, + uint32_t x, uint32_t y) { + state[a] = state[a] + state[b] + x; + state[d] = rotr32(state[d] ^ state[a], 16); + state[c] = state[c] + state[d]; + state[b] = rotr32(state[b] ^ state[c], 12); + state[a] = state[a] + state[b] + y; + state[d] = rotr32(state[d] ^ state[a], 8); + state[c] = state[c] + state[d]; + state[b] = rotr32(state[b] ^ state[c], 7); +} + +INLINE void round_fn(uint32_t state[16], const uint32_t *msg, size_t round) { + // Select the message schedule based on the round. + const uint8_t *schedule = MSG_SCHEDULE[round]; + + // Mix the columns. + g(state, 0, 4, 8, 12, msg[schedule[0]], msg[schedule[1]]); + g(state, 1, 5, 9, 13, msg[schedule[2]], msg[schedule[3]]); + g(state, 2, 6, 10, 14, msg[schedule[4]], msg[schedule[5]]); + g(state, 3, 7, 11, 15, msg[schedule[6]], msg[schedule[7]]); + + // Mix the rows. + g(state, 0, 5, 10, 15, msg[schedule[8]], msg[schedule[9]]); + g(state, 1, 6, 11, 12, msg[schedule[10]], msg[schedule[11]]); + g(state, 2, 7, 8, 13, msg[schedule[12]], msg[schedule[13]]); + g(state, 3, 4, 9, 14, msg[schedule[14]], msg[schedule[15]]); +} + +INLINE void compress_pre(uint32_t state[16], const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, uint8_t flags) { + uint32_t block_words[16]; + block_words[0] = load32(block + 4 * 0); + block_words[1] = load32(block + 4 * 1); + block_words[2] = load32(block + 4 * 2); + block_words[3] = load32(block + 4 * 3); + block_words[4] = load32(block + 4 * 4); + block_words[5] = load32(block + 4 * 5); + block_words[6] = load32(block + 4 * 6); + block_words[7] = load32(block + 4 * 7); + block_words[8] = load32(block + 4 * 8); + block_words[9] = load32(block + 4 * 9); + block_words[10] = load32(block + 4 * 10); + block_words[11] = load32(block + 4 * 11); + block_words[12] = load32(block + 4 * 12); + block_words[13] = load32(block + 4 * 13); + block_words[14] = load32(block + 4 * 14); + block_words[15] = load32(block + 4 * 15); + + state[0] = cv[0]; + state[1] = cv[1]; + state[2] = cv[2]; + state[3] = cv[3]; + state[4] = cv[4]; + state[5] = cv[5]; + state[6] = cv[6]; + state[7] = cv[7]; + state[8] = IV[0]; + state[9] = IV[1]; + state[10] = IV[2]; + state[11] = IV[3]; + state[12] = counter_low(counter); + state[13] = counter_high(counter); + state[14] = (uint32_t)block_len; + state[15] = (uint32_t)flags; + + round_fn(state, &block_words[0], 0); + round_fn(state, &block_words[0], 1); + round_fn(state, &block_words[0], 2); + round_fn(state, &block_words[0], 3); + round_fn(state, &block_words[0], 4); + round_fn(state, &block_words[0], 5); + round_fn(state, &block_words[0], 6); +} + +void blake3_compress_in_place_portable(uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags) { + uint32_t state[16]; + compress_pre(state, cv, block, block_len, counter, flags); + cv[0] = state[0] ^ state[8]; + cv[1] = state[1] ^ state[9]; + cv[2] = state[2] ^ state[10]; + cv[3] = state[3] ^ state[11]; + cv[4] = state[4] ^ state[12]; + cv[5] = state[5] ^ state[13]; + cv[6] = state[6] ^ state[14]; + cv[7] = state[7] ^ state[15]; +} + +void blake3_compress_xof_portable(const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags, uint8_t out[64]) { + uint32_t state[16]; + compress_pre(state, cv, block, block_len, counter, flags); + + store32(&out[0 * 4], state[0] ^ state[8]); + store32(&out[1 * 4], state[1] ^ state[9]); + store32(&out[2 * 4], state[2] ^ state[10]); + store32(&out[3 * 4], state[3] ^ state[11]); + store32(&out[4 * 4], state[4] ^ state[12]); + store32(&out[5 * 4], state[5] ^ state[13]); + store32(&out[6 * 4], state[6] ^ state[14]); + store32(&out[7 * 4], state[7] ^ state[15]); + store32(&out[8 * 4], state[8] ^ cv[0]); + store32(&out[9 * 4], state[9] ^ cv[1]); + store32(&out[10 * 4], state[10] ^ cv[2]); + store32(&out[11 * 4], state[11] ^ cv[3]); + store32(&out[12 * 4], state[12] ^ cv[4]); + store32(&out[13 * 4], state[13] ^ cv[5]); + store32(&out[14 * 4], state[14] ^ cv[6]); + store32(&out[15 * 4], state[15] ^ cv[7]); +} + +INLINE void hash_one_portable(const uint8_t *input, size_t blocks, + const uint32_t key[8], uint64_t counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t out[BLAKE3_OUT_LEN]) { + uint32_t cv[8]; + memcpy(cv, key, BLAKE3_KEY_LEN); + uint8_t block_flags = flags | flags_start; + while (blocks > 0) { + if (blocks == 1) { + block_flags |= flags_end; + } + blake3_compress_in_place_portable(cv, input, BLAKE3_BLOCK_LEN, counter, + block_flags); + input = &input[BLAKE3_BLOCK_LEN]; + blocks -= 1; + block_flags = flags; + } + memcpy(out, cv, 32); +} + +void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out) { + while (num_inputs > 0) { + hash_one_portable(inputs[0], blocks, key, counter, flags, flags_start, + flags_end, out); + if (increment_counter) { + counter += 1; + } + inputs += 1; + num_inputs -= 1; + out = &out[BLAKE3_OUT_LEN]; + } +} diff --git a/src/b3/blake3_sse41.c b/src/b3/blake3_sse41.c index b3112253..b5b4977a 100644 --- a/src/b3/blake3_sse41.c +++ b/src/b3/blake3_sse41.c @@ -1,559 +1,559 @@ -#include "blake3_impl.h" - -#include - -#define DEGREE 4 - -#define _mm_shuffle_ps2(a, b, c) \ - (_mm_castps_si128( \ - _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c)))) - -INLINE __m128i loadu(const uint8_t src[16]) { - return _mm_loadu_si128((const __m128i *)src); -} - -INLINE void storeu(__m128i src, uint8_t dest[16]) { - _mm_storeu_si128((__m128i *)dest, src); -} - -INLINE __m128i addv(__m128i a, __m128i b) { return _mm_add_epi32(a, b); } - -// Note that clang-format doesn't like the name "xor" for some reason. -INLINE __m128i xorv(__m128i a, __m128i b) { return _mm_xor_si128(a, b); } - -INLINE __m128i set1(uint32_t x) { return _mm_set1_epi32((int32_t)x); } - -INLINE __m128i set4(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { - return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d); -} - -INLINE __m128i rot16(__m128i x) { - return _mm_shuffle_epi8( - x, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2)); -} - -INLINE __m128i rot12(__m128i x) { - return xorv(_mm_srli_epi32(x, 12), _mm_slli_epi32(x, 32 - 12)); -} - -INLINE __m128i rot8(__m128i x) { - return _mm_shuffle_epi8( - x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1)); -} - -INLINE __m128i rot7(__m128i x) { - return xorv(_mm_srli_epi32(x, 7), _mm_slli_epi32(x, 32 - 7)); -} - -INLINE void g1(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, - __m128i m) { - *row0 = addv(addv(*row0, m), *row1); - *row3 = xorv(*row3, *row0); - *row3 = rot16(*row3); - *row2 = addv(*row2, *row3); - *row1 = xorv(*row1, *row2); - *row1 = rot12(*row1); -} - -INLINE void g2(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, - __m128i m) { - *row0 = addv(addv(*row0, m), *row1); - *row3 = xorv(*row3, *row0); - *row3 = rot8(*row3); - *row2 = addv(*row2, *row3); - *row1 = xorv(*row1, *row2); - *row1 = rot7(*row1); -} - -// Note the optimization here of leaving row1 as the unrotated row, rather than -// row0. All the message loads below are adjusted to compensate for this. See -// discussion at https://github.com/sneves/blake2-avx2/pull/4 -INLINE void diagonalize(__m128i *row0, __m128i *row2, __m128i *row3) { - *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3)); - *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2)); - *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1)); -} - -INLINE void undiagonalize(__m128i *row0, __m128i *row2, __m128i *row3) { - *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1)); - *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2)); - *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3)); -} - -INLINE void compress_pre(__m128i rows[4], const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, uint8_t flags) { - rows[0] = loadu((uint8_t *)&cv[0]); - rows[1] = loadu((uint8_t *)&cv[4]); - rows[2] = set4(IV[0], IV[1], IV[2], IV[3]); - rows[3] = set4(counter_low(counter), counter_high(counter), - (uint32_t)block_len, (uint32_t)flags); - - __m128i m0 = loadu(&block[sizeof(__m128i) * 0]); - __m128i m1 = loadu(&block[sizeof(__m128i) * 1]); - __m128i m2 = loadu(&block[sizeof(__m128i) * 2]); - __m128i m3 = loadu(&block[sizeof(__m128i) * 3]); - - __m128i t0, t1, t2, t3, tt; - - // Round 1. The first round permutes the message words from the original - // input order, into the groups that get mixed in parallel. - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0)); // 6 4 2 0 - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1)); // 7 5 3 1 - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0)); // 14 12 10 8 - t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3)); // 12 10 8 14 - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1)); // 15 13 11 9 - t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3)); // 13 11 9 15 - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 2. This round and all following rounds apply a fixed permutation - // to the message words from the round before. - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 3 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 4 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 5 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 6 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); - m0 = t0; - m1 = t1; - m2 = t2; - m3 = t3; - - // Round 7 - t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); - t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); - t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); - tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); - t1 = _mm_blend_epi16(tt, t1, 0xCC); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); - diagonalize(&rows[0], &rows[2], &rows[3]); - t2 = _mm_unpacklo_epi64(m3, m1); - tt = _mm_blend_epi16(t2, m2, 0xC0); - t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); - g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); - t3 = _mm_unpackhi_epi32(m1, m3); - tt = _mm_unpacklo_epi32(m2, t3); - t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); - g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); - undiagonalize(&rows[0], &rows[2], &rows[3]); -} - -void blake3_compress_in_place_sse41(uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags) { - __m128i rows[4]; - compress_pre(rows, cv, block, block_len, counter, flags); - storeu(xorv(rows[0], rows[2]), (uint8_t *)&cv[0]); - storeu(xorv(rows[1], rows[3]), (uint8_t *)&cv[4]); -} - -void blake3_compress_xof_sse41(const uint32_t cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, uint64_t counter, - uint8_t flags, uint8_t out[64]) { - __m128i rows[4]; - compress_pre(rows, cv, block, block_len, counter, flags); - storeu(xorv(rows[0], rows[2]), &out[0]); - storeu(xorv(rows[1], rows[3]), &out[16]); - storeu(xorv(rows[2], loadu((uint8_t *)&cv[0])), &out[32]); - storeu(xorv(rows[3], loadu((uint8_t *)&cv[4])), &out[48]); -} - -INLINE void round_fn(__m128i v[16], __m128i m[16], size_t r) { - v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); - v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); - v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); - v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); - v[0] = addv(v[0], v[4]); - v[1] = addv(v[1], v[5]); - v[2] = addv(v[2], v[6]); - v[3] = addv(v[3], v[7]); - v[12] = xorv(v[12], v[0]); - v[13] = xorv(v[13], v[1]); - v[14] = xorv(v[14], v[2]); - v[15] = xorv(v[15], v[3]); - v[12] = rot16(v[12]); - v[13] = rot16(v[13]); - v[14] = rot16(v[14]); - v[15] = rot16(v[15]); - v[8] = addv(v[8], v[12]); - v[9] = addv(v[9], v[13]); - v[10] = addv(v[10], v[14]); - v[11] = addv(v[11], v[15]); - v[4] = xorv(v[4], v[8]); - v[5] = xorv(v[5], v[9]); - v[6] = xorv(v[6], v[10]); - v[7] = xorv(v[7], v[11]); - v[4] = rot12(v[4]); - v[5] = rot12(v[5]); - v[6] = rot12(v[6]); - v[7] = rot12(v[7]); - v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); - v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); - v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); - v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); - v[0] = addv(v[0], v[4]); - v[1] = addv(v[1], v[5]); - v[2] = addv(v[2], v[6]); - v[3] = addv(v[3], v[7]); - v[12] = xorv(v[12], v[0]); - v[13] = xorv(v[13], v[1]); - v[14] = xorv(v[14], v[2]); - v[15] = xorv(v[15], v[3]); - v[12] = rot8(v[12]); - v[13] = rot8(v[13]); - v[14] = rot8(v[14]); - v[15] = rot8(v[15]); - v[8] = addv(v[8], v[12]); - v[9] = addv(v[9], v[13]); - v[10] = addv(v[10], v[14]); - v[11] = addv(v[11], v[15]); - v[4] = xorv(v[4], v[8]); - v[5] = xorv(v[5], v[9]); - v[6] = xorv(v[6], v[10]); - v[7] = xorv(v[7], v[11]); - v[4] = rot7(v[4]); - v[5] = rot7(v[5]); - v[6] = rot7(v[6]); - v[7] = rot7(v[7]); - - v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); - v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); - v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); - v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); - v[0] = addv(v[0], v[5]); - v[1] = addv(v[1], v[6]); - v[2] = addv(v[2], v[7]); - v[3] = addv(v[3], v[4]); - v[15] = xorv(v[15], v[0]); - v[12] = xorv(v[12], v[1]); - v[13] = xorv(v[13], v[2]); - v[14] = xorv(v[14], v[3]); - v[15] = rot16(v[15]); - v[12] = rot16(v[12]); - v[13] = rot16(v[13]); - v[14] = rot16(v[14]); - v[10] = addv(v[10], v[15]); - v[11] = addv(v[11], v[12]); - v[8] = addv(v[8], v[13]); - v[9] = addv(v[9], v[14]); - v[5] = xorv(v[5], v[10]); - v[6] = xorv(v[6], v[11]); - v[7] = xorv(v[7], v[8]); - v[4] = xorv(v[4], v[9]); - v[5] = rot12(v[5]); - v[6] = rot12(v[6]); - v[7] = rot12(v[7]); - v[4] = rot12(v[4]); - v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); - v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); - v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); - v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); - v[0] = addv(v[0], v[5]); - v[1] = addv(v[1], v[6]); - v[2] = addv(v[2], v[7]); - v[3] = addv(v[3], v[4]); - v[15] = xorv(v[15], v[0]); - v[12] = xorv(v[12], v[1]); - v[13] = xorv(v[13], v[2]); - v[14] = xorv(v[14], v[3]); - v[15] = rot8(v[15]); - v[12] = rot8(v[12]); - v[13] = rot8(v[13]); - v[14] = rot8(v[14]); - v[10] = addv(v[10], v[15]); - v[11] = addv(v[11], v[12]); - v[8] = addv(v[8], v[13]); - v[9] = addv(v[9], v[14]); - v[5] = xorv(v[5], v[10]); - v[6] = xorv(v[6], v[11]); - v[7] = xorv(v[7], v[8]); - v[4] = xorv(v[4], v[9]); - v[5] = rot7(v[5]); - v[6] = rot7(v[6]); - v[7] = rot7(v[7]); - v[4] = rot7(v[4]); -} - -INLINE void transpose_vecs(__m128i vecs[DEGREE]) { - // Interleave 32-bit lates. The low unpack is lanes 00/11 and the high is - // 22/33. Note that this doesn't split the vector into two lanes, as the - // AVX2 counterparts do. - __m128i ab_01 = _mm_unpacklo_epi32(vecs[0], vecs[1]); - __m128i ab_23 = _mm_unpackhi_epi32(vecs[0], vecs[1]); - __m128i cd_01 = _mm_unpacklo_epi32(vecs[2], vecs[3]); - __m128i cd_23 = _mm_unpackhi_epi32(vecs[2], vecs[3]); - - // Interleave 64-bit lanes. - __m128i abcd_0 = _mm_unpacklo_epi64(ab_01, cd_01); - __m128i abcd_1 = _mm_unpackhi_epi64(ab_01, cd_01); - __m128i abcd_2 = _mm_unpacklo_epi64(ab_23, cd_23); - __m128i abcd_3 = _mm_unpackhi_epi64(ab_23, cd_23); - - vecs[0] = abcd_0; - vecs[1] = abcd_1; - vecs[2] = abcd_2; - vecs[3] = abcd_3; -} - -INLINE void transpose_msg_vecs(const uint8_t *const *inputs, - size_t block_offset, __m128i out[16]) { - out[0] = loadu(&inputs[0][block_offset + 0 * sizeof(__m128i)]); - out[1] = loadu(&inputs[1][block_offset + 0 * sizeof(__m128i)]); - out[2] = loadu(&inputs[2][block_offset + 0 * sizeof(__m128i)]); - out[3] = loadu(&inputs[3][block_offset + 0 * sizeof(__m128i)]); - out[4] = loadu(&inputs[0][block_offset + 1 * sizeof(__m128i)]); - out[5] = loadu(&inputs[1][block_offset + 1 * sizeof(__m128i)]); - out[6] = loadu(&inputs[2][block_offset + 1 * sizeof(__m128i)]); - out[7] = loadu(&inputs[3][block_offset + 1 * sizeof(__m128i)]); - out[8] = loadu(&inputs[0][block_offset + 2 * sizeof(__m128i)]); - out[9] = loadu(&inputs[1][block_offset + 2 * sizeof(__m128i)]); - out[10] = loadu(&inputs[2][block_offset + 2 * sizeof(__m128i)]); - out[11] = loadu(&inputs[3][block_offset + 2 * sizeof(__m128i)]); - out[12] = loadu(&inputs[0][block_offset + 3 * sizeof(__m128i)]); - out[13] = loadu(&inputs[1][block_offset + 3 * sizeof(__m128i)]); - out[14] = loadu(&inputs[2][block_offset + 3 * sizeof(__m128i)]); - out[15] = loadu(&inputs[3][block_offset + 3 * sizeof(__m128i)]); - for (size_t i = 0; i < 4; ++i) { - _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); - } - transpose_vecs(&out[0]); - transpose_vecs(&out[4]); - transpose_vecs(&out[8]); - transpose_vecs(&out[12]); -} - -INLINE void load_counters(uint64_t counter, bool increment_counter, - __m128i *out_lo, __m128i *out_hi) { - const __m128i mask = _mm_set1_epi32(-(int32_t)increment_counter); - const __m128i add0 = _mm_set_epi32(3, 2, 1, 0); - const __m128i add1 = _mm_and_si128(mask, add0); - __m128i l = _mm_add_epi32(_mm_set1_epi32(counter), add1); - __m128i carry = _mm_cmpgt_epi32(_mm_xor_si128(add1, _mm_set1_epi32(0x80000000)), - _mm_xor_si128( l, _mm_set1_epi32(0x80000000))); - __m128i h = _mm_sub_epi32(_mm_set1_epi32(counter >> 32), carry); - *out_lo = l; - *out_hi = h; -} - -void blake3_hash4_sse41(const uint8_t *const *inputs, size_t blocks, - const uint32_t key[8], uint64_t counter, - bool increment_counter, uint8_t flags, - uint8_t flags_start, uint8_t flags_end, uint8_t *out) { - __m128i h_vecs[8] = { - set1(key[0]), set1(key[1]), set1(key[2]), set1(key[3]), - set1(key[4]), set1(key[5]), set1(key[6]), set1(key[7]), - }; - __m128i counter_low_vec, counter_high_vec; - load_counters(counter, increment_counter, &counter_low_vec, - &counter_high_vec); - uint8_t block_flags = flags | flags_start; - - for (size_t block = 0; block < blocks; block++) { - if (block + 1 == blocks) { - block_flags |= flags_end; - } - __m128i block_len_vec = set1(BLAKE3_BLOCK_LEN); - __m128i block_flags_vec = set1(block_flags); - __m128i msg_vecs[16]; - transpose_msg_vecs(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); - - __m128i v[16] = { - h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], - h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], - set1(IV[0]), set1(IV[1]), set1(IV[2]), set1(IV[3]), - counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, - }; - round_fn(v, msg_vecs, 0); - round_fn(v, msg_vecs, 1); - round_fn(v, msg_vecs, 2); - round_fn(v, msg_vecs, 3); - round_fn(v, msg_vecs, 4); - round_fn(v, msg_vecs, 5); - round_fn(v, msg_vecs, 6); - h_vecs[0] = xorv(v[0], v[8]); - h_vecs[1] = xorv(v[1], v[9]); - h_vecs[2] = xorv(v[2], v[10]); - h_vecs[3] = xorv(v[3], v[11]); - h_vecs[4] = xorv(v[4], v[12]); - h_vecs[5] = xorv(v[5], v[13]); - h_vecs[6] = xorv(v[6], v[14]); - h_vecs[7] = xorv(v[7], v[15]); - - block_flags = flags; - } - - transpose_vecs(&h_vecs[0]); - transpose_vecs(&h_vecs[4]); - // The first four vecs now contain the first half of each output, and the - // second four vecs contain the second half of each output. - storeu(h_vecs[0], &out[0 * sizeof(__m128i)]); - storeu(h_vecs[4], &out[1 * sizeof(__m128i)]); - storeu(h_vecs[1], &out[2 * sizeof(__m128i)]); - storeu(h_vecs[5], &out[3 * sizeof(__m128i)]); - storeu(h_vecs[2], &out[4 * sizeof(__m128i)]); - storeu(h_vecs[6], &out[5 * sizeof(__m128i)]); - storeu(h_vecs[3], &out[6 * sizeof(__m128i)]); - storeu(h_vecs[7], &out[7 * sizeof(__m128i)]); -} - -INLINE void hash_one_sse41(const uint8_t *input, size_t blocks, - const uint32_t key[8], uint64_t counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t out[BLAKE3_OUT_LEN]) { - uint32_t cv[8]; - memcpy(cv, key, BLAKE3_KEY_LEN); - uint8_t block_flags = flags | flags_start; - while (blocks > 0) { - if (blocks == 1) { - block_flags |= flags_end; - } - blake3_compress_in_place_sse41(cv, input, BLAKE3_BLOCK_LEN, counter, - block_flags); - input = &input[BLAKE3_BLOCK_LEN]; - blocks -= 1; - block_flags = flags; - } - memcpy(out, cv, BLAKE3_OUT_LEN); -} - -void blake3_hash_many_sse41(const uint8_t *const *inputs, size_t num_inputs, - size_t blocks, const uint32_t key[8], - uint64_t counter, bool increment_counter, - uint8_t flags, uint8_t flags_start, - uint8_t flags_end, uint8_t *out) { - while (num_inputs >= DEGREE) { - blake3_hash4_sse41(inputs, blocks, key, counter, increment_counter, flags, - flags_start, flags_end, out); - if (increment_counter) { - counter += DEGREE; - } - inputs += DEGREE; - num_inputs -= DEGREE; - out = &out[DEGREE * BLAKE3_OUT_LEN]; - } - while (num_inputs > 0) { - hash_one_sse41(inputs[0], blocks, key, counter, flags, flags_start, - flags_end, out); - if (increment_counter) { - counter += 1; - } - inputs += 1; - num_inputs -= 1; - out = &out[BLAKE3_OUT_LEN]; - } -} +#include "blake3_impl.h" + +#include + +#define DEGREE 4 + +#define _mm_shuffle_ps2(a, b, c) \ + (_mm_castps_si128( \ + _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), (c)))) + +INLINE __m128i loadu(const uint8_t src[16]) { + return _mm_loadu_si128((const __m128i *)src); +} + +INLINE void storeu(__m128i src, uint8_t dest[16]) { + _mm_storeu_si128((__m128i *)dest, src); +} + +INLINE __m128i addv(__m128i a, __m128i b) { return _mm_add_epi32(a, b); } + +// Note that clang-format doesn't like the name "xor" for some reason. +INLINE __m128i xorv(__m128i a, __m128i b) { return _mm_xor_si128(a, b); } + +INLINE __m128i set1(uint32_t x) { return _mm_set1_epi32((int32_t)x); } + +INLINE __m128i set4(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { + return _mm_setr_epi32((int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d); +} + +INLINE __m128i rot16(__m128i x) { + return _mm_shuffle_epi8( + x, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2)); +} + +INLINE __m128i rot12(__m128i x) { + return xorv(_mm_srli_epi32(x, 12), _mm_slli_epi32(x, 32 - 12)); +} + +INLINE __m128i rot8(__m128i x) { + return _mm_shuffle_epi8( + x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1)); +} + +INLINE __m128i rot7(__m128i x) { + return xorv(_mm_srli_epi32(x, 7), _mm_slli_epi32(x, 32 - 7)); +} + +INLINE void g1(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, + __m128i m) { + *row0 = addv(addv(*row0, m), *row1); + *row3 = xorv(*row3, *row0); + *row3 = rot16(*row3); + *row2 = addv(*row2, *row3); + *row1 = xorv(*row1, *row2); + *row1 = rot12(*row1); +} + +INLINE void g2(__m128i *row0, __m128i *row1, __m128i *row2, __m128i *row3, + __m128i m) { + *row0 = addv(addv(*row0, m), *row1); + *row3 = xorv(*row3, *row0); + *row3 = rot8(*row3); + *row2 = addv(*row2, *row3); + *row1 = xorv(*row1, *row2); + *row1 = rot7(*row1); +} + +// Note the optimization here of leaving row1 as the unrotated row, rather than +// row0. All the message loads below are adjusted to compensate for this. See +// discussion at https://github.com/sneves/blake2-avx2/pull/4 +INLINE void diagonalize(__m128i *row0, __m128i *row2, __m128i *row3) { + *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(2, 1, 0, 3)); + *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2)); + *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(0, 3, 2, 1)); +} + +INLINE void undiagonalize(__m128i *row0, __m128i *row2, __m128i *row3) { + *row0 = _mm_shuffle_epi32(*row0, _MM_SHUFFLE(0, 3, 2, 1)); + *row3 = _mm_shuffle_epi32(*row3, _MM_SHUFFLE(1, 0, 3, 2)); + *row2 = _mm_shuffle_epi32(*row2, _MM_SHUFFLE(2, 1, 0, 3)); +} + +INLINE void compress_pre(__m128i rows[4], const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, uint8_t flags) { + rows[0] = loadu((uint8_t *)&cv[0]); + rows[1] = loadu((uint8_t *)&cv[4]); + rows[2] = set4(IV[0], IV[1], IV[2], IV[3]); + rows[3] = set4(counter_low(counter), counter_high(counter), + (uint32_t)block_len, (uint32_t)flags); + + __m128i m0 = loadu(&block[sizeof(__m128i) * 0]); + __m128i m1 = loadu(&block[sizeof(__m128i) * 1]); + __m128i m2 = loadu(&block[sizeof(__m128i) * 2]); + __m128i m3 = loadu(&block[sizeof(__m128i) * 3]); + + __m128i t0, t1, t2, t3, tt; + + // Round 1. The first round permutes the message words from the original + // input order, into the groups that get mixed in parallel. + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(2, 0, 2, 0)); // 6 4 2 0 + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 3, 1)); // 7 5 3 1 + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(2, 0, 2, 0)); // 14 12 10 8 + t2 = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2, 1, 0, 3)); // 12 10 8 14 + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 1, 3, 1)); // 15 13 11 9 + t3 = _mm_shuffle_epi32(t3, _MM_SHUFFLE(2, 1, 0, 3)); // 13 11 9 15 + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 2. This round and all following rounds apply a fixed permutation + // to the message words from the round before. + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 3 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 4 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 5 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 6 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); + m0 = t0; + m1 = t1; + m2 = t2; + m3 = t3; + + // Round 7 + t0 = _mm_shuffle_ps2(m0, m1, _MM_SHUFFLE(3, 1, 1, 2)); + t0 = _mm_shuffle_epi32(t0, _MM_SHUFFLE(0, 3, 2, 1)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t0); + t1 = _mm_shuffle_ps2(m2, m3, _MM_SHUFFLE(3, 3, 2, 2)); + tt = _mm_shuffle_epi32(m0, _MM_SHUFFLE(0, 0, 3, 3)); + t1 = _mm_blend_epi16(tt, t1, 0xCC); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t1); + diagonalize(&rows[0], &rows[2], &rows[3]); + t2 = _mm_unpacklo_epi64(m3, m1); + tt = _mm_blend_epi16(t2, m2, 0xC0); + t2 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(1, 3, 2, 0)); + g1(&rows[0], &rows[1], &rows[2], &rows[3], t2); + t3 = _mm_unpackhi_epi32(m1, m3); + tt = _mm_unpacklo_epi32(m2, t3); + t3 = _mm_shuffle_epi32(tt, _MM_SHUFFLE(0, 1, 3, 2)); + g2(&rows[0], &rows[1], &rows[2], &rows[3], t3); + undiagonalize(&rows[0], &rows[2], &rows[3]); +} + +void blake3_compress_in_place_sse41(uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags) { + __m128i rows[4]; + compress_pre(rows, cv, block, block_len, counter, flags); + storeu(xorv(rows[0], rows[2]), (uint8_t *)&cv[0]); + storeu(xorv(rows[1], rows[3]), (uint8_t *)&cv[4]); +} + +void blake3_compress_xof_sse41(const uint32_t cv[8], + const uint8_t block[BLAKE3_BLOCK_LEN], + uint8_t block_len, uint64_t counter, + uint8_t flags, uint8_t out[64]) { + __m128i rows[4]; + compress_pre(rows, cv, block, block_len, counter, flags); + storeu(xorv(rows[0], rows[2]), &out[0]); + storeu(xorv(rows[1], rows[3]), &out[16]); + storeu(xorv(rows[2], loadu((uint8_t *)&cv[0])), &out[32]); + storeu(xorv(rows[3], loadu((uint8_t *)&cv[4])), &out[48]); +} + +INLINE void round_fn(__m128i v[16], __m128i m[16], size_t r) { + v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][0]]); + v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][2]]); + v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][4]]); + v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][6]]); + v[0] = addv(v[0], v[4]); + v[1] = addv(v[1], v[5]); + v[2] = addv(v[2], v[6]); + v[3] = addv(v[3], v[7]); + v[12] = xorv(v[12], v[0]); + v[13] = xorv(v[13], v[1]); + v[14] = xorv(v[14], v[2]); + v[15] = xorv(v[15], v[3]); + v[12] = rot16(v[12]); + v[13] = rot16(v[13]); + v[14] = rot16(v[14]); + v[15] = rot16(v[15]); + v[8] = addv(v[8], v[12]); + v[9] = addv(v[9], v[13]); + v[10] = addv(v[10], v[14]); + v[11] = addv(v[11], v[15]); + v[4] = xorv(v[4], v[8]); + v[5] = xorv(v[5], v[9]); + v[6] = xorv(v[6], v[10]); + v[7] = xorv(v[7], v[11]); + v[4] = rot12(v[4]); + v[5] = rot12(v[5]); + v[6] = rot12(v[6]); + v[7] = rot12(v[7]); + v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][1]]); + v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][3]]); + v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][5]]); + v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][7]]); + v[0] = addv(v[0], v[4]); + v[1] = addv(v[1], v[5]); + v[2] = addv(v[2], v[6]); + v[3] = addv(v[3], v[7]); + v[12] = xorv(v[12], v[0]); + v[13] = xorv(v[13], v[1]); + v[14] = xorv(v[14], v[2]); + v[15] = xorv(v[15], v[3]); + v[12] = rot8(v[12]); + v[13] = rot8(v[13]); + v[14] = rot8(v[14]); + v[15] = rot8(v[15]); + v[8] = addv(v[8], v[12]); + v[9] = addv(v[9], v[13]); + v[10] = addv(v[10], v[14]); + v[11] = addv(v[11], v[15]); + v[4] = xorv(v[4], v[8]); + v[5] = xorv(v[5], v[9]); + v[6] = xorv(v[6], v[10]); + v[7] = xorv(v[7], v[11]); + v[4] = rot7(v[4]); + v[5] = rot7(v[5]); + v[6] = rot7(v[6]); + v[7] = rot7(v[7]); + + v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][8]]); + v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][10]]); + v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][12]]); + v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][14]]); + v[0] = addv(v[0], v[5]); + v[1] = addv(v[1], v[6]); + v[2] = addv(v[2], v[7]); + v[3] = addv(v[3], v[4]); + v[15] = xorv(v[15], v[0]); + v[12] = xorv(v[12], v[1]); + v[13] = xorv(v[13], v[2]); + v[14] = xorv(v[14], v[3]); + v[15] = rot16(v[15]); + v[12] = rot16(v[12]); + v[13] = rot16(v[13]); + v[14] = rot16(v[14]); + v[10] = addv(v[10], v[15]); + v[11] = addv(v[11], v[12]); + v[8] = addv(v[8], v[13]); + v[9] = addv(v[9], v[14]); + v[5] = xorv(v[5], v[10]); + v[6] = xorv(v[6], v[11]); + v[7] = xorv(v[7], v[8]); + v[4] = xorv(v[4], v[9]); + v[5] = rot12(v[5]); + v[6] = rot12(v[6]); + v[7] = rot12(v[7]); + v[4] = rot12(v[4]); + v[0] = addv(v[0], m[(size_t)MSG_SCHEDULE[r][9]]); + v[1] = addv(v[1], m[(size_t)MSG_SCHEDULE[r][11]]); + v[2] = addv(v[2], m[(size_t)MSG_SCHEDULE[r][13]]); + v[3] = addv(v[3], m[(size_t)MSG_SCHEDULE[r][15]]); + v[0] = addv(v[0], v[5]); + v[1] = addv(v[1], v[6]); + v[2] = addv(v[2], v[7]); + v[3] = addv(v[3], v[4]); + v[15] = xorv(v[15], v[0]); + v[12] = xorv(v[12], v[1]); + v[13] = xorv(v[13], v[2]); + v[14] = xorv(v[14], v[3]); + v[15] = rot8(v[15]); + v[12] = rot8(v[12]); + v[13] = rot8(v[13]); + v[14] = rot8(v[14]); + v[10] = addv(v[10], v[15]); + v[11] = addv(v[11], v[12]); + v[8] = addv(v[8], v[13]); + v[9] = addv(v[9], v[14]); + v[5] = xorv(v[5], v[10]); + v[6] = xorv(v[6], v[11]); + v[7] = xorv(v[7], v[8]); + v[4] = xorv(v[4], v[9]); + v[5] = rot7(v[5]); + v[6] = rot7(v[6]); + v[7] = rot7(v[7]); + v[4] = rot7(v[4]); +} + +INLINE void transpose_vecs(__m128i vecs[DEGREE]) { + // Interleave 32-bit lates. The low unpack is lanes 00/11 and the high is + // 22/33. Note that this doesn't split the vector into two lanes, as the + // AVX2 counterparts do. + __m128i ab_01 = _mm_unpacklo_epi32(vecs[0], vecs[1]); + __m128i ab_23 = _mm_unpackhi_epi32(vecs[0], vecs[1]); + __m128i cd_01 = _mm_unpacklo_epi32(vecs[2], vecs[3]); + __m128i cd_23 = _mm_unpackhi_epi32(vecs[2], vecs[3]); + + // Interleave 64-bit lanes. + __m128i abcd_0 = _mm_unpacklo_epi64(ab_01, cd_01); + __m128i abcd_1 = _mm_unpackhi_epi64(ab_01, cd_01); + __m128i abcd_2 = _mm_unpacklo_epi64(ab_23, cd_23); + __m128i abcd_3 = _mm_unpackhi_epi64(ab_23, cd_23); + + vecs[0] = abcd_0; + vecs[1] = abcd_1; + vecs[2] = abcd_2; + vecs[3] = abcd_3; +} + +INLINE void transpose_msg_vecs(const uint8_t *const *inputs, + size_t block_offset, __m128i out[16]) { + out[0] = loadu(&inputs[0][block_offset + 0 * sizeof(__m128i)]); + out[1] = loadu(&inputs[1][block_offset + 0 * sizeof(__m128i)]); + out[2] = loadu(&inputs[2][block_offset + 0 * sizeof(__m128i)]); + out[3] = loadu(&inputs[3][block_offset + 0 * sizeof(__m128i)]); + out[4] = loadu(&inputs[0][block_offset + 1 * sizeof(__m128i)]); + out[5] = loadu(&inputs[1][block_offset + 1 * sizeof(__m128i)]); + out[6] = loadu(&inputs[2][block_offset + 1 * sizeof(__m128i)]); + out[7] = loadu(&inputs[3][block_offset + 1 * sizeof(__m128i)]); + out[8] = loadu(&inputs[0][block_offset + 2 * sizeof(__m128i)]); + out[9] = loadu(&inputs[1][block_offset + 2 * sizeof(__m128i)]); + out[10] = loadu(&inputs[2][block_offset + 2 * sizeof(__m128i)]); + out[11] = loadu(&inputs[3][block_offset + 2 * sizeof(__m128i)]); + out[12] = loadu(&inputs[0][block_offset + 3 * sizeof(__m128i)]); + out[13] = loadu(&inputs[1][block_offset + 3 * sizeof(__m128i)]); + out[14] = loadu(&inputs[2][block_offset + 3 * sizeof(__m128i)]); + out[15] = loadu(&inputs[3][block_offset + 3 * sizeof(__m128i)]); + for (size_t i = 0; i < 4; ++i) { + _mm_prefetch(&inputs[i][block_offset + 256], _MM_HINT_T0); + } + transpose_vecs(&out[0]); + transpose_vecs(&out[4]); + transpose_vecs(&out[8]); + transpose_vecs(&out[12]); +} + +INLINE void load_counters(uint64_t counter, bool increment_counter, + __m128i *out_lo, __m128i *out_hi) { + const __m128i mask = _mm_set1_epi32(-(int32_t)increment_counter); + const __m128i add0 = _mm_set_epi32(3, 2, 1, 0); + const __m128i add1 = _mm_and_si128(mask, add0); + __m128i l = _mm_add_epi32(_mm_set1_epi32(counter), add1); + __m128i carry = _mm_cmpgt_epi32(_mm_xor_si128(add1, _mm_set1_epi32(0x80000000)), + _mm_xor_si128( l, _mm_set1_epi32(0x80000000))); + __m128i h = _mm_sub_epi32(_mm_set1_epi32(counter >> 32), carry); + *out_lo = l; + *out_hi = h; +} + +void blake3_hash4_sse41(const uint8_t *const *inputs, size_t blocks, + const uint32_t key[8], uint64_t counter, + bool increment_counter, uint8_t flags, + uint8_t flags_start, uint8_t flags_end, uint8_t *out) { + __m128i h_vecs[8] = { + set1(key[0]), set1(key[1]), set1(key[2]), set1(key[3]), + set1(key[4]), set1(key[5]), set1(key[6]), set1(key[7]), + }; + __m128i counter_low_vec, counter_high_vec; + load_counters(counter, increment_counter, &counter_low_vec, + &counter_high_vec); + uint8_t block_flags = flags | flags_start; + + for (size_t block = 0; block < blocks; block++) { + if (block + 1 == blocks) { + block_flags |= flags_end; + } + __m128i block_len_vec = set1(BLAKE3_BLOCK_LEN); + __m128i block_flags_vec = set1(block_flags); + __m128i msg_vecs[16]; + transpose_msg_vecs(inputs, block * BLAKE3_BLOCK_LEN, msg_vecs); + + __m128i v[16] = { + h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], + h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], + set1(IV[0]), set1(IV[1]), set1(IV[2]), set1(IV[3]), + counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec, + }; + round_fn(v, msg_vecs, 0); + round_fn(v, msg_vecs, 1); + round_fn(v, msg_vecs, 2); + round_fn(v, msg_vecs, 3); + round_fn(v, msg_vecs, 4); + round_fn(v, msg_vecs, 5); + round_fn(v, msg_vecs, 6); + h_vecs[0] = xorv(v[0], v[8]); + h_vecs[1] = xorv(v[1], v[9]); + h_vecs[2] = xorv(v[2], v[10]); + h_vecs[3] = xorv(v[3], v[11]); + h_vecs[4] = xorv(v[4], v[12]); + h_vecs[5] = xorv(v[5], v[13]); + h_vecs[6] = xorv(v[6], v[14]); + h_vecs[7] = xorv(v[7], v[15]); + + block_flags = flags; + } + + transpose_vecs(&h_vecs[0]); + transpose_vecs(&h_vecs[4]); + // The first four vecs now contain the first half of each output, and the + // second four vecs contain the second half of each output. + storeu(h_vecs[0], &out[0 * sizeof(__m128i)]); + storeu(h_vecs[4], &out[1 * sizeof(__m128i)]); + storeu(h_vecs[1], &out[2 * sizeof(__m128i)]); + storeu(h_vecs[5], &out[3 * sizeof(__m128i)]); + storeu(h_vecs[2], &out[4 * sizeof(__m128i)]); + storeu(h_vecs[6], &out[5 * sizeof(__m128i)]); + storeu(h_vecs[3], &out[6 * sizeof(__m128i)]); + storeu(h_vecs[7], &out[7 * sizeof(__m128i)]); +} + +INLINE void hash_one_sse41(const uint8_t *input, size_t blocks, + const uint32_t key[8], uint64_t counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t out[BLAKE3_OUT_LEN]) { + uint32_t cv[8]; + memcpy(cv, key, BLAKE3_KEY_LEN); + uint8_t block_flags = flags | flags_start; + while (blocks > 0) { + if (blocks == 1) { + block_flags |= flags_end; + } + blake3_compress_in_place_sse41(cv, input, BLAKE3_BLOCK_LEN, counter, + block_flags); + input = &input[BLAKE3_BLOCK_LEN]; + blocks -= 1; + block_flags = flags; + } + memcpy(out, cv, BLAKE3_OUT_LEN); +} + +void blake3_hash_many_sse41(const uint8_t *const *inputs, size_t num_inputs, + size_t blocks, const uint32_t key[8], + uint64_t counter, bool increment_counter, + uint8_t flags, uint8_t flags_start, + uint8_t flags_end, uint8_t *out) { + while (num_inputs >= DEGREE) { + blake3_hash4_sse41(inputs, blocks, key, counter, increment_counter, flags, + flags_start, flags_end, out); + if (increment_counter) { + counter += DEGREE; + } + inputs += DEGREE; + num_inputs -= DEGREE; + out = &out[DEGREE * BLAKE3_OUT_LEN]; + } + while (num_inputs > 0) { + hash_one_sse41(inputs[0], blocks, key, counter, flags, flags_start, + flags_end, out); + if (increment_counter) { + counter += 1; + } + inputs += 1; + num_inputs -= 1; + out = &out[BLAKE3_OUT_LEN]; + } +} diff --git a/src/b3/blake3_sse41_x86-64_unix.S b/src/b3/blake3_sse41_x86-64_unix.S index 024a8290..320a89fa 100644 --- a/src/b3/blake3_sse41_x86-64_unix.S +++ b/src/b3/blake3_sse41_x86-64_unix.S @@ -1,2014 +1,2014 @@ -#ifdef __x86_64__ -.intel_syntax noprefix -.global blake3_hash_many_sse41 -.global _blake3_hash_many_sse41 -.global blake3_compress_in_place_sse41 -.global _blake3_compress_in_place_sse41 -.global blake3_compress_xof_sse41 -.global _blake3_compress_xof_sse41 -#ifdef __APPLE__ -.text -#else -.section .text -#endif - .p2align 6 -_blake3_hash_many_sse41: -blake3_hash_many_sse41: - push r15 - push r14 - push r13 - push r12 - push rbx - push rbp - mov rbp, rsp - sub rsp, 360 - and rsp, 0xFFFFFFFFFFFFFFC0 - neg r9d - movd xmm0, r9d - pshufd xmm0, xmm0, 0x00 - movdqa xmmword ptr [rsp+0x130], xmm0 - movdqa xmm1, xmm0 - pand xmm1, xmmword ptr [ADD0+rip] - pand xmm0, xmmword ptr [ADD1+rip] - movdqa xmmword ptr [rsp+0x150], xmm0 - movd xmm0, r8d - pshufd xmm0, xmm0, 0x00 - paddd xmm0, xmm1 - movdqa xmmword ptr [rsp+0x110], xmm0 - pxor xmm0, xmmword ptr [CMP_MSB_MASK+rip] - pxor xmm1, xmmword ptr [CMP_MSB_MASK+rip] - pcmpgtd xmm1, xmm0 - shr r8, 32 - movd xmm2, r8d - pshufd xmm2, xmm2, 0x00 - psubd xmm2, xmm1 - movdqa xmmword ptr [rsp+0x120], xmm2 - mov rbx, qword ptr [rbp+0x50] - mov r15, rdx - shl r15, 6 - movzx r13d, byte ptr [rbp+0x38] - movzx r12d, byte ptr [rbp+0x48] - cmp rsi, 4 - jc 3f -2: - movdqu xmm3, xmmword ptr [rcx] - pshufd xmm0, xmm3, 0x00 - pshufd xmm1, xmm3, 0x55 - pshufd xmm2, xmm3, 0xAA - pshufd xmm3, xmm3, 0xFF - movdqu xmm7, xmmword ptr [rcx+0x10] - pshufd xmm4, xmm7, 0x00 - pshufd xmm5, xmm7, 0x55 - pshufd xmm6, xmm7, 0xAA - pshufd xmm7, xmm7, 0xFF - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - mov r10, qword ptr [rdi+0x10] - mov r11, qword ptr [rdi+0x18] - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -9: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - movdqu xmm8, xmmword ptr [r8+rdx-0x40] - movdqu xmm9, xmmword ptr [r9+rdx-0x40] - movdqu xmm10, xmmword ptr [r10+rdx-0x40] - movdqu xmm11, xmmword ptr [r11+rdx-0x40] - movdqa xmm12, xmm8 - punpckldq xmm8, xmm9 - punpckhdq xmm12, xmm9 - movdqa xmm14, xmm10 - punpckldq xmm10, xmm11 - punpckhdq xmm14, xmm11 - movdqa xmm9, xmm8 - punpcklqdq xmm8, xmm10 - punpckhqdq xmm9, xmm10 - movdqa xmm13, xmm12 - punpcklqdq xmm12, xmm14 - punpckhqdq xmm13, xmm14 - movdqa xmmword ptr [rsp], xmm8 - movdqa xmmword ptr [rsp+0x10], xmm9 - movdqa xmmword ptr [rsp+0x20], xmm12 - movdqa xmmword ptr [rsp+0x30], xmm13 - movdqu xmm8, xmmword ptr [r8+rdx-0x30] - movdqu xmm9, xmmword ptr [r9+rdx-0x30] - movdqu xmm10, xmmword ptr [r10+rdx-0x30] - movdqu xmm11, xmmword ptr [r11+rdx-0x30] - movdqa xmm12, xmm8 - punpckldq xmm8, xmm9 - punpckhdq xmm12, xmm9 - movdqa xmm14, xmm10 - punpckldq xmm10, xmm11 - punpckhdq xmm14, xmm11 - movdqa xmm9, xmm8 - punpcklqdq xmm8, xmm10 - punpckhqdq xmm9, xmm10 - movdqa xmm13, xmm12 - punpcklqdq xmm12, xmm14 - punpckhqdq xmm13, xmm14 - movdqa xmmword ptr [rsp+0x40], xmm8 - movdqa xmmword ptr [rsp+0x50], xmm9 - movdqa xmmword ptr [rsp+0x60], xmm12 - movdqa xmmword ptr [rsp+0x70], xmm13 - movdqu xmm8, xmmword ptr [r8+rdx-0x20] - movdqu xmm9, xmmword ptr [r9+rdx-0x20] - movdqu xmm10, xmmword ptr [r10+rdx-0x20] - movdqu xmm11, xmmword ptr [r11+rdx-0x20] - movdqa xmm12, xmm8 - punpckldq xmm8, xmm9 - punpckhdq xmm12, xmm9 - movdqa xmm14, xmm10 - punpckldq xmm10, xmm11 - punpckhdq xmm14, xmm11 - movdqa xmm9, xmm8 - punpcklqdq xmm8, xmm10 - punpckhqdq xmm9, xmm10 - movdqa xmm13, xmm12 - punpcklqdq xmm12, xmm14 - punpckhqdq xmm13, xmm14 - movdqa xmmword ptr [rsp+0x80], xmm8 - movdqa xmmword ptr [rsp+0x90], xmm9 - movdqa xmmword ptr [rsp+0xA0], xmm12 - movdqa xmmword ptr [rsp+0xB0], xmm13 - movdqu xmm8, xmmword ptr [r8+rdx-0x10] - movdqu xmm9, xmmword ptr [r9+rdx-0x10] - movdqu xmm10, xmmword ptr [r10+rdx-0x10] - movdqu xmm11, xmmword ptr [r11+rdx-0x10] - movdqa xmm12, xmm8 - punpckldq xmm8, xmm9 - punpckhdq xmm12, xmm9 - movdqa xmm14, xmm10 - punpckldq xmm10, xmm11 - punpckhdq xmm14, xmm11 - movdqa xmm9, xmm8 - punpcklqdq xmm8, xmm10 - punpckhqdq xmm9, xmm10 - movdqa xmm13, xmm12 - punpcklqdq xmm12, xmm14 - punpckhqdq xmm13, xmm14 - movdqa xmmword ptr [rsp+0xC0], xmm8 - movdqa xmmword ptr [rsp+0xD0], xmm9 - movdqa xmmword ptr [rsp+0xE0], xmm12 - movdqa xmmword ptr [rsp+0xF0], xmm13 - movdqa xmm9, xmmword ptr [BLAKE3_IV_1+rip] - movdqa xmm10, xmmword ptr [BLAKE3_IV_2+rip] - movdqa xmm11, xmmword ptr [BLAKE3_IV_3+rip] - movdqa xmm12, xmmword ptr [rsp+0x110] - movdqa xmm13, xmmword ptr [rsp+0x120] - movdqa xmm14, xmmword ptr [BLAKE3_BLOCK_LEN+rip] - movd xmm15, eax - pshufd xmm15, xmm15, 0x00 - prefetcht0 [r8+rdx+0x80] - prefetcht0 [r9+rdx+0x80] - prefetcht0 [r10+rdx+0x80] - prefetcht0 [r11+rdx+0x80] - paddd xmm0, xmmword ptr [rsp] - paddd xmm1, xmmword ptr [rsp+0x20] - paddd xmm2, xmmword ptr [rsp+0x40] - paddd xmm3, xmmword ptr [rsp+0x60] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [BLAKE3_IV_0+rip] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x10] - paddd xmm1, xmmword ptr [rsp+0x30] - paddd xmm2, xmmword ptr [rsp+0x50] - paddd xmm3, xmmword ptr [rsp+0x70] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x80] - paddd xmm1, xmmword ptr [rsp+0xA0] - paddd xmm2, xmmword ptr [rsp+0xC0] - paddd xmm3, xmmword ptr [rsp+0xE0] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0x90] - paddd xmm1, xmmword ptr [rsp+0xB0] - paddd xmm2, xmmword ptr [rsp+0xD0] - paddd xmm3, xmmword ptr [rsp+0xF0] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0x20] - paddd xmm1, xmmword ptr [rsp+0x30] - paddd xmm2, xmmword ptr [rsp+0x70] - paddd xmm3, xmmword ptr [rsp+0x40] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x60] - paddd xmm1, xmmword ptr [rsp+0xA0] - paddd xmm2, xmmword ptr [rsp] - paddd xmm3, xmmword ptr [rsp+0xD0] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x10] - paddd xmm1, xmmword ptr [rsp+0xC0] - paddd xmm2, xmmword ptr [rsp+0x90] - paddd xmm3, xmmword ptr [rsp+0xF0] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0xB0] - paddd xmm1, xmmword ptr [rsp+0x50] - paddd xmm2, xmmword ptr [rsp+0xE0] - paddd xmm3, xmmword ptr [rsp+0x80] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0x30] - paddd xmm1, xmmword ptr [rsp+0xA0] - paddd xmm2, xmmword ptr [rsp+0xD0] - paddd xmm3, xmmword ptr [rsp+0x70] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x40] - paddd xmm1, xmmword ptr [rsp+0xC0] - paddd xmm2, xmmword ptr [rsp+0x20] - paddd xmm3, xmmword ptr [rsp+0xE0] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x60] - paddd xmm1, xmmword ptr [rsp+0x90] - paddd xmm2, xmmword ptr [rsp+0xB0] - paddd xmm3, xmmword ptr [rsp+0x80] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0x50] - paddd xmm1, xmmword ptr [rsp] - paddd xmm2, xmmword ptr [rsp+0xF0] - paddd xmm3, xmmword ptr [rsp+0x10] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0xA0] - paddd xmm1, xmmword ptr [rsp+0xC0] - paddd xmm2, xmmword ptr [rsp+0xE0] - paddd xmm3, xmmword ptr [rsp+0xD0] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x70] - paddd xmm1, xmmword ptr [rsp+0x90] - paddd xmm2, xmmword ptr [rsp+0x30] - paddd xmm3, xmmword ptr [rsp+0xF0] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x40] - paddd xmm1, xmmword ptr [rsp+0xB0] - paddd xmm2, xmmword ptr [rsp+0x50] - paddd xmm3, xmmword ptr [rsp+0x10] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp] - paddd xmm1, xmmword ptr [rsp+0x20] - paddd xmm2, xmmword ptr [rsp+0x80] - paddd xmm3, xmmword ptr [rsp+0x60] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0xC0] - paddd xmm1, xmmword ptr [rsp+0x90] - paddd xmm2, xmmword ptr [rsp+0xF0] - paddd xmm3, xmmword ptr [rsp+0xE0] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0xD0] - paddd xmm1, xmmword ptr [rsp+0xB0] - paddd xmm2, xmmword ptr [rsp+0xA0] - paddd xmm3, xmmword ptr [rsp+0x80] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0x70] - paddd xmm1, xmmword ptr [rsp+0x50] - paddd xmm2, xmmword ptr [rsp] - paddd xmm3, xmmword ptr [rsp+0x60] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0x20] - paddd xmm1, xmmword ptr [rsp+0x30] - paddd xmm2, xmmword ptr [rsp+0x10] - paddd xmm3, xmmword ptr [rsp+0x40] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0x90] - paddd xmm1, xmmword ptr [rsp+0xB0] - paddd xmm2, xmmword ptr [rsp+0x80] - paddd xmm3, xmmword ptr [rsp+0xF0] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0xE0] - paddd xmm1, xmmword ptr [rsp+0x50] - paddd xmm2, xmmword ptr [rsp+0xC0] - paddd xmm3, xmmword ptr [rsp+0x10] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0xD0] - paddd xmm1, xmmword ptr [rsp] - paddd xmm2, xmmword ptr [rsp+0x20] - paddd xmm3, xmmword ptr [rsp+0x40] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0x30] - paddd xmm1, xmmword ptr [rsp+0xA0] - paddd xmm2, xmmword ptr [rsp+0x60] - paddd xmm3, xmmword ptr [rsp+0x70] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0xB0] - paddd xmm1, xmmword ptr [rsp+0x50] - paddd xmm2, xmmword ptr [rsp+0x10] - paddd xmm3, xmmword ptr [rsp+0x80] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0xF0] - paddd xmm1, xmmword ptr [rsp] - paddd xmm2, xmmword ptr [rsp+0x90] - paddd xmm3, xmmword ptr [rsp+0x60] - paddd xmm0, xmm4 - paddd xmm1, xmm5 - paddd xmm2, xmm6 - paddd xmm3, xmm7 - pxor xmm12, xmm0 - pxor xmm13, xmm1 - pxor xmm14, xmm2 - pxor xmm15, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - pshufb xmm15, xmm8 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm12 - paddd xmm9, xmm13 - paddd xmm10, xmm14 - paddd xmm11, xmm15 - pxor xmm4, xmm8 - pxor xmm5, xmm9 - pxor xmm6, xmm10 - pxor xmm7, xmm11 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - paddd xmm0, xmmword ptr [rsp+0xE0] - paddd xmm1, xmmword ptr [rsp+0x20] - paddd xmm2, xmmword ptr [rsp+0x30] - paddd xmm3, xmmword ptr [rsp+0x70] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT16+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - movdqa xmmword ptr [rsp+0x100], xmm8 - movdqa xmm8, xmm5 - psrld xmm8, 12 - pslld xmm5, 20 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 12 - pslld xmm6, 20 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 12 - pslld xmm7, 20 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 12 - pslld xmm4, 20 - por xmm4, xmm8 - paddd xmm0, xmmword ptr [rsp+0xA0] - paddd xmm1, xmmword ptr [rsp+0xC0] - paddd xmm2, xmmword ptr [rsp+0x40] - paddd xmm3, xmmword ptr [rsp+0xD0] - paddd xmm0, xmm5 - paddd xmm1, xmm6 - paddd xmm2, xmm7 - paddd xmm3, xmm4 - pxor xmm15, xmm0 - pxor xmm12, xmm1 - pxor xmm13, xmm2 - pxor xmm14, xmm3 - movdqa xmm8, xmmword ptr [ROT8+rip] - pshufb xmm15, xmm8 - pshufb xmm12, xmm8 - pshufb xmm13, xmm8 - pshufb xmm14, xmm8 - paddd xmm10, xmm15 - paddd xmm11, xmm12 - movdqa xmm8, xmmword ptr [rsp+0x100] - paddd xmm8, xmm13 - paddd xmm9, xmm14 - pxor xmm5, xmm10 - pxor xmm6, xmm11 - pxor xmm7, xmm8 - pxor xmm4, xmm9 - pxor xmm0, xmm8 - pxor xmm1, xmm9 - pxor xmm2, xmm10 - pxor xmm3, xmm11 - movdqa xmm8, xmm5 - psrld xmm8, 7 - pslld xmm5, 25 - por xmm5, xmm8 - movdqa xmm8, xmm6 - psrld xmm8, 7 - pslld xmm6, 25 - por xmm6, xmm8 - movdqa xmm8, xmm7 - psrld xmm8, 7 - pslld xmm7, 25 - por xmm7, xmm8 - movdqa xmm8, xmm4 - psrld xmm8, 7 - pslld xmm4, 25 - por xmm4, xmm8 - pxor xmm4, xmm12 - pxor xmm5, xmm13 - pxor xmm6, xmm14 - pxor xmm7, xmm15 - mov eax, r13d - jne 9b - movdqa xmm9, xmm0 - punpckldq xmm0, xmm1 - punpckhdq xmm9, xmm1 - movdqa xmm11, xmm2 - punpckldq xmm2, xmm3 - punpckhdq xmm11, xmm3 - movdqa xmm1, xmm0 - punpcklqdq xmm0, xmm2 - punpckhqdq xmm1, xmm2 - movdqa xmm3, xmm9 - punpcklqdq xmm9, xmm11 - punpckhqdq xmm3, xmm11 - movdqu xmmword ptr [rbx], xmm0 - movdqu xmmword ptr [rbx+0x20], xmm1 - movdqu xmmword ptr [rbx+0x40], xmm9 - movdqu xmmword ptr [rbx+0x60], xmm3 - movdqa xmm9, xmm4 - punpckldq xmm4, xmm5 - punpckhdq xmm9, xmm5 - movdqa xmm11, xmm6 - punpckldq xmm6, xmm7 - punpckhdq xmm11, xmm7 - movdqa xmm5, xmm4 - punpcklqdq xmm4, xmm6 - punpckhqdq xmm5, xmm6 - movdqa xmm7, xmm9 - punpcklqdq xmm9, xmm11 - punpckhqdq xmm7, xmm11 - movdqu xmmword ptr [rbx+0x10], xmm4 - movdqu xmmword ptr [rbx+0x30], xmm5 - movdqu xmmword ptr [rbx+0x50], xmm9 - movdqu xmmword ptr [rbx+0x70], xmm7 - movdqa xmm1, xmmword ptr [rsp+0x110] - movdqa xmm0, xmm1 - paddd xmm1, xmmword ptr [rsp+0x150] - movdqa xmmword ptr [rsp+0x110], xmm1 - pxor xmm0, xmmword ptr [CMP_MSB_MASK+rip] - pxor xmm1, xmmword ptr [CMP_MSB_MASK+rip] - pcmpgtd xmm0, xmm1 - movdqa xmm1, xmmword ptr [rsp+0x120] - psubd xmm1, xmm0 - movdqa xmmword ptr [rsp+0x120], xmm1 - add rbx, 128 - add rdi, 32 - sub rsi, 4 - cmp rsi, 4 - jnc 2b - test rsi, rsi - jnz 3f -4: - mov rsp, rbp - pop rbp - pop rbx - pop r12 - pop r13 - pop r14 - pop r15 - ret -.p2align 5 -3: - test esi, 0x2 - je 3f - movups xmm0, xmmword ptr [rcx] - movups xmm1, xmmword ptr [rcx+0x10] - movaps xmm8, xmm0 - movaps xmm9, xmm1 - movd xmm13, dword ptr [rsp+0x110] - pinsrd xmm13, dword ptr [rsp+0x120], 1 - pinsrd xmm13, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - movaps xmmword ptr [rsp], xmm13 - movd xmm14, dword ptr [rsp+0x114] - pinsrd xmm14, dword ptr [rsp+0x124], 1 - pinsrd xmm14, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - movaps xmmword ptr [rsp+0x10], xmm14 - mov r8, qword ptr [rdi] - mov r9, qword ptr [rdi+0x8] - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -2: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - movaps xmm2, xmmword ptr [BLAKE3_IV+rip] - movaps xmm10, xmm2 - movups xmm4, xmmword ptr [r8+rdx-0x40] - movups xmm5, xmmword ptr [r8+rdx-0x30] - movaps xmm3, xmm4 - shufps xmm4, xmm5, 136 - shufps xmm3, xmm5, 221 - movaps xmm5, xmm3 - movups xmm6, xmmword ptr [r8+rdx-0x20] - movups xmm7, xmmword ptr [r8+rdx-0x10] - movaps xmm3, xmm6 - shufps xmm6, xmm7, 136 - pshufd xmm6, xmm6, 0x93 - shufps xmm3, xmm7, 221 - pshufd xmm7, xmm3, 0x93 - movups xmm12, xmmword ptr [r9+rdx-0x40] - movups xmm13, xmmword ptr [r9+rdx-0x30] - movaps xmm11, xmm12 - shufps xmm12, xmm13, 136 - shufps xmm11, xmm13, 221 - movaps xmm13, xmm11 - movups xmm14, xmmword ptr [r9+rdx-0x20] - movups xmm15, xmmword ptr [r9+rdx-0x10] - movaps xmm11, xmm14 - shufps xmm14, xmm15, 136 - pshufd xmm14, xmm14, 0x93 - shufps xmm11, xmm15, 221 - pshufd xmm15, xmm11, 0x93 - movaps xmm3, xmmword ptr [rsp] - movaps xmm11, xmmword ptr [rsp+0x10] - pinsrd xmm3, eax, 3 - pinsrd xmm11, eax, 3 - mov al, 7 -9: - paddd xmm0, xmm4 - paddd xmm8, xmm12 - movaps xmmword ptr [rsp+0x20], xmm4 - movaps xmmword ptr [rsp+0x30], xmm12 - paddd xmm0, xmm1 - paddd xmm8, xmm9 - pxor xmm3, xmm0 - pxor xmm11, xmm8 - movaps xmm12, xmmword ptr [ROT16+rip] - pshufb xmm3, xmm12 - pshufb xmm11, xmm12 - paddd xmm2, xmm3 - paddd xmm10, xmm11 - pxor xmm1, xmm2 - pxor xmm9, xmm10 - movdqa xmm4, xmm1 - pslld xmm1, 20 - psrld xmm4, 12 - por xmm1, xmm4 - movdqa xmm4, xmm9 - pslld xmm9, 20 - psrld xmm4, 12 - por xmm9, xmm4 - paddd xmm0, xmm5 - paddd xmm8, xmm13 - movaps xmmword ptr [rsp+0x40], xmm5 - movaps xmmword ptr [rsp+0x50], xmm13 - paddd xmm0, xmm1 - paddd xmm8, xmm9 - pxor xmm3, xmm0 - pxor xmm11, xmm8 - movaps xmm13, xmmword ptr [ROT8+rip] - pshufb xmm3, xmm13 - pshufb xmm11, xmm13 - paddd xmm2, xmm3 - paddd xmm10, xmm11 - pxor xmm1, xmm2 - pxor xmm9, xmm10 - movdqa xmm4, xmm1 - pslld xmm1, 25 - psrld xmm4, 7 - por xmm1, xmm4 - movdqa xmm4, xmm9 - pslld xmm9, 25 - psrld xmm4, 7 - por xmm9, xmm4 - pshufd xmm0, xmm0, 0x93 - pshufd xmm8, xmm8, 0x93 - pshufd xmm3, xmm3, 0x4E - pshufd xmm11, xmm11, 0x4E - pshufd xmm2, xmm2, 0x39 - pshufd xmm10, xmm10, 0x39 - paddd xmm0, xmm6 - paddd xmm8, xmm14 - paddd xmm0, xmm1 - paddd xmm8, xmm9 - pxor xmm3, xmm0 - pxor xmm11, xmm8 - pshufb xmm3, xmm12 - pshufb xmm11, xmm12 - paddd xmm2, xmm3 - paddd xmm10, xmm11 - pxor xmm1, xmm2 - pxor xmm9, xmm10 - movdqa xmm4, xmm1 - pslld xmm1, 20 - psrld xmm4, 12 - por xmm1, xmm4 - movdqa xmm4, xmm9 - pslld xmm9, 20 - psrld xmm4, 12 - por xmm9, xmm4 - paddd xmm0, xmm7 - paddd xmm8, xmm15 - paddd xmm0, xmm1 - paddd xmm8, xmm9 - pxor xmm3, xmm0 - pxor xmm11, xmm8 - pshufb xmm3, xmm13 - pshufb xmm11, xmm13 - paddd xmm2, xmm3 - paddd xmm10, xmm11 - pxor xmm1, xmm2 - pxor xmm9, xmm10 - movdqa xmm4, xmm1 - pslld xmm1, 25 - psrld xmm4, 7 - por xmm1, xmm4 - movdqa xmm4, xmm9 - pslld xmm9, 25 - psrld xmm4, 7 - por xmm9, xmm4 - pshufd xmm0, xmm0, 0x39 - pshufd xmm8, xmm8, 0x39 - pshufd xmm3, xmm3, 0x4E - pshufd xmm11, xmm11, 0x4E - pshufd xmm2, xmm2, 0x93 - pshufd xmm10, xmm10, 0x93 - dec al - je 9f - movdqa xmm12, xmmword ptr [rsp+0x20] - movdqa xmm5, xmmword ptr [rsp+0x40] - pshufd xmm13, xmm12, 0x0F - shufps xmm12, xmm5, 214 - pshufd xmm4, xmm12, 0x39 - movdqa xmm12, xmm6 - shufps xmm12, xmm7, 250 - pblendw xmm13, xmm12, 0xCC - movdqa xmm12, xmm7 - punpcklqdq xmm12, xmm5 - pblendw xmm12, xmm6, 0xC0 - pshufd xmm12, xmm12, 0x78 - punpckhdq xmm5, xmm7 - punpckldq xmm6, xmm5 - pshufd xmm7, xmm6, 0x1E - movdqa xmmword ptr [rsp+0x20], xmm13 - movdqa xmmword ptr [rsp+0x40], xmm12 - movdqa xmm5, xmmword ptr [rsp+0x30] - movdqa xmm13, xmmword ptr [rsp+0x50] - pshufd xmm6, xmm5, 0x0F - shufps xmm5, xmm13, 214 - pshufd xmm12, xmm5, 0x39 - movdqa xmm5, xmm14 - shufps xmm5, xmm15, 250 - pblendw xmm6, xmm5, 0xCC - movdqa xmm5, xmm15 - punpcklqdq xmm5, xmm13 - pblendw xmm5, xmm14, 0xC0 - pshufd xmm5, xmm5, 0x78 - punpckhdq xmm13, xmm15 - punpckldq xmm14, xmm13 - pshufd xmm15, xmm14, 0x1E - movdqa xmm13, xmm6 - movdqa xmm14, xmm5 - movdqa xmm5, xmmword ptr [rsp+0x20] - movdqa xmm6, xmmword ptr [rsp+0x40] - jmp 9b -9: - pxor xmm0, xmm2 - pxor xmm1, xmm3 - pxor xmm8, xmm10 - pxor xmm9, xmm11 - mov eax, r13d - cmp rdx, r15 - jne 2b - movups xmmword ptr [rbx], xmm0 - movups xmmword ptr [rbx+0x10], xmm1 - movups xmmword ptr [rbx+0x20], xmm8 - movups xmmword ptr [rbx+0x30], xmm9 - movdqa xmm0, xmmword ptr [rsp+0x130] - movdqa xmm1, xmmword ptr [rsp+0x110] - movdqa xmm2, xmmword ptr [rsp+0x120] - movdqu xmm3, xmmword ptr [rsp+0x118] - movdqu xmm4, xmmword ptr [rsp+0x128] - blendvps xmm1, xmm3, xmm0 - blendvps xmm2, xmm4, xmm0 - movdqa xmmword ptr [rsp+0x110], xmm1 - movdqa xmmword ptr [rsp+0x120], xmm2 - add rdi, 16 - add rbx, 64 - sub rsi, 2 -3: - test esi, 0x1 - je 4b - movups xmm0, xmmword ptr [rcx] - movups xmm1, xmmword ptr [rcx+0x10] - movd xmm13, dword ptr [rsp+0x110] - pinsrd xmm13, dword ptr [rsp+0x120], 1 - pinsrd xmm13, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 - movaps xmm14, xmmword ptr [ROT8+rip] - movaps xmm15, xmmword ptr [ROT16+rip] - mov r8, qword ptr [rdi] - movzx eax, byte ptr [rbp+0x40] - or eax, r13d - xor edx, edx -2: - mov r14d, eax - or eax, r12d - add rdx, 64 - cmp rdx, r15 - cmovne eax, r14d - movaps xmm2, xmmword ptr [BLAKE3_IV+rip] - movaps xmm3, xmm13 - pinsrd xmm3, eax, 3 - movups xmm4, xmmword ptr [r8+rdx-0x40] - movups xmm5, xmmword ptr [r8+rdx-0x30] - movaps xmm8, xmm4 - shufps xmm4, xmm5, 136 - shufps xmm8, xmm5, 221 - movaps xmm5, xmm8 - movups xmm6, xmmword ptr [r8+rdx-0x20] - movups xmm7, xmmword ptr [r8+rdx-0x10] - movaps xmm8, xmm6 - shufps xmm6, xmm7, 136 - pshufd xmm6, xmm6, 0x93 - shufps xmm8, xmm7, 221 - pshufd xmm7, xmm8, 0x93 - mov al, 7 -9: - paddd xmm0, xmm4 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm15 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 20 - psrld xmm11, 12 - por xmm1, xmm11 - paddd xmm0, xmm5 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm14 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 25 - psrld xmm11, 7 - por xmm1, xmm11 - pshufd xmm0, xmm0, 0x93 - pshufd xmm3, xmm3, 0x4E - pshufd xmm2, xmm2, 0x39 - paddd xmm0, xmm6 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm15 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 20 - psrld xmm11, 12 - por xmm1, xmm11 - paddd xmm0, xmm7 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm14 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 25 - psrld xmm11, 7 - por xmm1, xmm11 - pshufd xmm0, xmm0, 0x39 - pshufd xmm3, xmm3, 0x4E - pshufd xmm2, xmm2, 0x93 - dec al - jz 9f - movdqa xmm8, xmm4 - shufps xmm8, xmm5, 214 - pshufd xmm9, xmm4, 0x0F - pshufd xmm4, xmm8, 0x39 - movdqa xmm8, xmm6 - shufps xmm8, xmm7, 250 - pblendw xmm9, xmm8, 0xCC - movdqa xmm8, xmm7 - punpcklqdq xmm8, xmm5 - pblendw xmm8, xmm6, 0xC0 - pshufd xmm8, xmm8, 0x78 - punpckhdq xmm5, xmm7 - punpckldq xmm6, xmm5 - pshufd xmm7, xmm6, 0x1E - movdqa xmm5, xmm9 - movdqa xmm6, xmm8 - jmp 9b -9: - pxor xmm0, xmm2 - pxor xmm1, xmm3 - mov eax, r13d - cmp rdx, r15 - jne 2b - movups xmmword ptr [rbx], xmm0 - movups xmmword ptr [rbx+0x10], xmm1 - jmp 4b - -.p2align 6 -blake3_compress_in_place_sse41: -_blake3_compress_in_place_sse41: - movups xmm0, xmmword ptr [rdi] - movups xmm1, xmmword ptr [rdi+0x10] - movaps xmm2, xmmword ptr [BLAKE3_IV+rip] - shl r8, 32 - add rdx, r8 - movq xmm3, rcx - movq xmm4, rdx - punpcklqdq xmm3, xmm4 - movups xmm4, xmmword ptr [rsi] - movups xmm5, xmmword ptr [rsi+0x10] - movaps xmm8, xmm4 - shufps xmm4, xmm5, 136 - shufps xmm8, xmm5, 221 - movaps xmm5, xmm8 - movups xmm6, xmmword ptr [rsi+0x20] - movups xmm7, xmmword ptr [rsi+0x30] - movaps xmm8, xmm6 - shufps xmm6, xmm7, 136 - pshufd xmm6, xmm6, 0x93 - shufps xmm8, xmm7, 221 - pshufd xmm7, xmm8, 0x93 - movaps xmm14, xmmword ptr [ROT8+rip] - movaps xmm15, xmmword ptr [ROT16+rip] - mov al, 7 -9: - paddd xmm0, xmm4 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm15 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 20 - psrld xmm11, 12 - por xmm1, xmm11 - paddd xmm0, xmm5 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm14 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 25 - psrld xmm11, 7 - por xmm1, xmm11 - pshufd xmm0, xmm0, 0x93 - pshufd xmm3, xmm3, 0x4E - pshufd xmm2, xmm2, 0x39 - paddd xmm0, xmm6 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm15 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 20 - psrld xmm11, 12 - por xmm1, xmm11 - paddd xmm0, xmm7 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm14 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 25 - psrld xmm11, 7 - por xmm1, xmm11 - pshufd xmm0, xmm0, 0x39 - pshufd xmm3, xmm3, 0x4E - pshufd xmm2, xmm2, 0x93 - dec al - jz 9f - movdqa xmm8, xmm4 - shufps xmm8, xmm5, 214 - pshufd xmm9, xmm4, 0x0F - pshufd xmm4, xmm8, 0x39 - movdqa xmm8, xmm6 - shufps xmm8, xmm7, 250 - pblendw xmm9, xmm8, 0xCC - movdqa xmm8, xmm7 - punpcklqdq xmm8, xmm5 - pblendw xmm8, xmm6, 0xC0 - pshufd xmm8, xmm8, 0x78 - punpckhdq xmm5, xmm7 - punpckldq xmm6, xmm5 - pshufd xmm7, xmm6, 0x1E - movdqa xmm5, xmm9 - movdqa xmm6, xmm8 - jmp 9b -9: - pxor xmm0, xmm2 - pxor xmm1, xmm3 - movups xmmword ptr [rdi], xmm0 - movups xmmword ptr [rdi+0x10], xmm1 - ret - -.p2align 6 -blake3_compress_xof_sse41: -_blake3_compress_xof_sse41: - movups xmm0, xmmword ptr [rdi] - movups xmm1, xmmword ptr [rdi+0x10] - movaps xmm2, xmmword ptr [BLAKE3_IV+rip] - movzx eax, r8b - movzx edx, dl - shl rax, 32 - add rdx, rax - movq xmm3, rcx - movq xmm4, rdx - punpcklqdq xmm3, xmm4 - movups xmm4, xmmword ptr [rsi] - movups xmm5, xmmword ptr [rsi+0x10] - movaps xmm8, xmm4 - shufps xmm4, xmm5, 136 - shufps xmm8, xmm5, 221 - movaps xmm5, xmm8 - movups xmm6, xmmword ptr [rsi+0x20] - movups xmm7, xmmword ptr [rsi+0x30] - movaps xmm8, xmm6 - shufps xmm6, xmm7, 136 - pshufd xmm6, xmm6, 0x93 - shufps xmm8, xmm7, 221 - pshufd xmm7, xmm8, 0x93 - movaps xmm14, xmmword ptr [ROT8+rip] - movaps xmm15, xmmword ptr [ROT16+rip] - mov al, 7 -9: - paddd xmm0, xmm4 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm15 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 20 - psrld xmm11, 12 - por xmm1, xmm11 - paddd xmm0, xmm5 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm14 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 25 - psrld xmm11, 7 - por xmm1, xmm11 - pshufd xmm0, xmm0, 0x93 - pshufd xmm3, xmm3, 0x4E - pshufd xmm2, xmm2, 0x39 - paddd xmm0, xmm6 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm15 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 20 - psrld xmm11, 12 - por xmm1, xmm11 - paddd xmm0, xmm7 - paddd xmm0, xmm1 - pxor xmm3, xmm0 - pshufb xmm3, xmm14 - paddd xmm2, xmm3 - pxor xmm1, xmm2 - movdqa xmm11, xmm1 - pslld xmm1, 25 - psrld xmm11, 7 - por xmm1, xmm11 - pshufd xmm0, xmm0, 0x39 - pshufd xmm3, xmm3, 0x4E - pshufd xmm2, xmm2, 0x93 - dec al - jz 9f - movdqa xmm8, xmm4 - shufps xmm8, xmm5, 214 - pshufd xmm9, xmm4, 0x0F - pshufd xmm4, xmm8, 0x39 - movdqa xmm8, xmm6 - shufps xmm8, xmm7, 250 - pblendw xmm9, xmm8, 0xCC - movdqa xmm8, xmm7 - punpcklqdq xmm8, xmm5 - pblendw xmm8, xmm6, 0xC0 - pshufd xmm8, xmm8, 0x78 - punpckhdq xmm5, xmm7 - punpckldq xmm6, xmm5 - pshufd xmm7, xmm6, 0x1E - movdqa xmm5, xmm9 - movdqa xmm6, xmm8 - jmp 9b -9: - movdqu xmm4, xmmword ptr [rdi] - movdqu xmm5, xmmword ptr [rdi+0x10] - pxor xmm0, xmm2 - pxor xmm1, xmm3 - pxor xmm2, xmm4 - pxor xmm3, xmm5 - movups xmmword ptr [r9], xmm0 - movups xmmword ptr [r9+0x10], xmm1 - movups xmmword ptr [r9+0x20], xmm2 - movups xmmword ptr [r9+0x30], xmm3 - ret - - -#ifdef __APPLE__ -.static_data -#else -.section .rodata -#endif -.p2align 6 -BLAKE3_IV: - .long 0x6A09E667, 0xBB67AE85 - .long 0x3C6EF372, 0xA54FF53A -ROT16: - .byte 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13 -ROT8: - .byte 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12 -ADD0: - .long 0, 1, 2, 3 -ADD1: - .long 4, 4, 4, 4 -BLAKE3_IV_0: - .long 0x6A09E667, 0x6A09E667, 0x6A09E667, 0x6A09E667 -BLAKE3_IV_1: - .long 0xBB67AE85, 0xBB67AE85, 0xBB67AE85, 0xBB67AE85 -BLAKE3_IV_2: - .long 0x3C6EF372, 0x3C6EF372, 0x3C6EF372, 0x3C6EF372 -BLAKE3_IV_3: - .long 0xA54FF53A, 0xA54FF53A, 0xA54FF53A, 0xA54FF53A -BLAKE3_BLOCK_LEN: - .long 64, 64, 64, 64 -CMP_MSB_MASK: - .long 0x80000000, 0x80000000, 0x80000000, 0x80000000 - -#endif // __x86_64__ +#ifdef __x86_64__ +.intel_syntax noprefix +.global blake3_hash_many_sse41 +.global _blake3_hash_many_sse41 +.global blake3_compress_in_place_sse41 +.global _blake3_compress_in_place_sse41 +.global blake3_compress_xof_sse41 +.global _blake3_compress_xof_sse41 +#ifdef __APPLE__ +.text +#else +.section .text +#endif + .p2align 6 +_blake3_hash_many_sse41: +blake3_hash_many_sse41: + push r15 + push r14 + push r13 + push r12 + push rbx + push rbp + mov rbp, rsp + sub rsp, 360 + and rsp, 0xFFFFFFFFFFFFFFC0 + neg r9d + movd xmm0, r9d + pshufd xmm0, xmm0, 0x00 + movdqa xmmword ptr [rsp+0x130], xmm0 + movdqa xmm1, xmm0 + pand xmm1, xmmword ptr [ADD0+rip] + pand xmm0, xmmword ptr [ADD1+rip] + movdqa xmmword ptr [rsp+0x150], xmm0 + movd xmm0, r8d + pshufd xmm0, xmm0, 0x00 + paddd xmm0, xmm1 + movdqa xmmword ptr [rsp+0x110], xmm0 + pxor xmm0, xmmword ptr [CMP_MSB_MASK+rip] + pxor xmm1, xmmword ptr [CMP_MSB_MASK+rip] + pcmpgtd xmm1, xmm0 + shr r8, 32 + movd xmm2, r8d + pshufd xmm2, xmm2, 0x00 + psubd xmm2, xmm1 + movdqa xmmword ptr [rsp+0x120], xmm2 + mov rbx, qword ptr [rbp+0x50] + mov r15, rdx + shl r15, 6 + movzx r13d, byte ptr [rbp+0x38] + movzx r12d, byte ptr [rbp+0x48] + cmp rsi, 4 + jc 3f +2: + movdqu xmm3, xmmword ptr [rcx] + pshufd xmm0, xmm3, 0x00 + pshufd xmm1, xmm3, 0x55 + pshufd xmm2, xmm3, 0xAA + pshufd xmm3, xmm3, 0xFF + movdqu xmm7, xmmword ptr [rcx+0x10] + pshufd xmm4, xmm7, 0x00 + pshufd xmm5, xmm7, 0x55 + pshufd xmm6, xmm7, 0xAA + pshufd xmm7, xmm7, 0xFF + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + mov r10, qword ptr [rdi+0x10] + mov r11, qword ptr [rdi+0x18] + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +9: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + movdqu xmm8, xmmword ptr [r8+rdx-0x40] + movdqu xmm9, xmmword ptr [r9+rdx-0x40] + movdqu xmm10, xmmword ptr [r10+rdx-0x40] + movdqu xmm11, xmmword ptr [r11+rdx-0x40] + movdqa xmm12, xmm8 + punpckldq xmm8, xmm9 + punpckhdq xmm12, xmm9 + movdqa xmm14, xmm10 + punpckldq xmm10, xmm11 + punpckhdq xmm14, xmm11 + movdqa xmm9, xmm8 + punpcklqdq xmm8, xmm10 + punpckhqdq xmm9, xmm10 + movdqa xmm13, xmm12 + punpcklqdq xmm12, xmm14 + punpckhqdq xmm13, xmm14 + movdqa xmmword ptr [rsp], xmm8 + movdqa xmmword ptr [rsp+0x10], xmm9 + movdqa xmmword ptr [rsp+0x20], xmm12 + movdqa xmmword ptr [rsp+0x30], xmm13 + movdqu xmm8, xmmword ptr [r8+rdx-0x30] + movdqu xmm9, xmmword ptr [r9+rdx-0x30] + movdqu xmm10, xmmword ptr [r10+rdx-0x30] + movdqu xmm11, xmmword ptr [r11+rdx-0x30] + movdqa xmm12, xmm8 + punpckldq xmm8, xmm9 + punpckhdq xmm12, xmm9 + movdqa xmm14, xmm10 + punpckldq xmm10, xmm11 + punpckhdq xmm14, xmm11 + movdqa xmm9, xmm8 + punpcklqdq xmm8, xmm10 + punpckhqdq xmm9, xmm10 + movdqa xmm13, xmm12 + punpcklqdq xmm12, xmm14 + punpckhqdq xmm13, xmm14 + movdqa xmmword ptr [rsp+0x40], xmm8 + movdqa xmmword ptr [rsp+0x50], xmm9 + movdqa xmmword ptr [rsp+0x60], xmm12 + movdqa xmmword ptr [rsp+0x70], xmm13 + movdqu xmm8, xmmword ptr [r8+rdx-0x20] + movdqu xmm9, xmmword ptr [r9+rdx-0x20] + movdqu xmm10, xmmword ptr [r10+rdx-0x20] + movdqu xmm11, xmmword ptr [r11+rdx-0x20] + movdqa xmm12, xmm8 + punpckldq xmm8, xmm9 + punpckhdq xmm12, xmm9 + movdqa xmm14, xmm10 + punpckldq xmm10, xmm11 + punpckhdq xmm14, xmm11 + movdqa xmm9, xmm8 + punpcklqdq xmm8, xmm10 + punpckhqdq xmm9, xmm10 + movdqa xmm13, xmm12 + punpcklqdq xmm12, xmm14 + punpckhqdq xmm13, xmm14 + movdqa xmmword ptr [rsp+0x80], xmm8 + movdqa xmmword ptr [rsp+0x90], xmm9 + movdqa xmmword ptr [rsp+0xA0], xmm12 + movdqa xmmword ptr [rsp+0xB0], xmm13 + movdqu xmm8, xmmword ptr [r8+rdx-0x10] + movdqu xmm9, xmmword ptr [r9+rdx-0x10] + movdqu xmm10, xmmword ptr [r10+rdx-0x10] + movdqu xmm11, xmmword ptr [r11+rdx-0x10] + movdqa xmm12, xmm8 + punpckldq xmm8, xmm9 + punpckhdq xmm12, xmm9 + movdqa xmm14, xmm10 + punpckldq xmm10, xmm11 + punpckhdq xmm14, xmm11 + movdqa xmm9, xmm8 + punpcklqdq xmm8, xmm10 + punpckhqdq xmm9, xmm10 + movdqa xmm13, xmm12 + punpcklqdq xmm12, xmm14 + punpckhqdq xmm13, xmm14 + movdqa xmmword ptr [rsp+0xC0], xmm8 + movdqa xmmword ptr [rsp+0xD0], xmm9 + movdqa xmmword ptr [rsp+0xE0], xmm12 + movdqa xmmword ptr [rsp+0xF0], xmm13 + movdqa xmm9, xmmword ptr [BLAKE3_IV_1+rip] + movdqa xmm10, xmmword ptr [BLAKE3_IV_2+rip] + movdqa xmm11, xmmword ptr [BLAKE3_IV_3+rip] + movdqa xmm12, xmmword ptr [rsp+0x110] + movdqa xmm13, xmmword ptr [rsp+0x120] + movdqa xmm14, xmmword ptr [BLAKE3_BLOCK_LEN+rip] + movd xmm15, eax + pshufd xmm15, xmm15, 0x00 + prefetcht0 [r8+rdx+0x80] + prefetcht0 [r9+rdx+0x80] + prefetcht0 [r10+rdx+0x80] + prefetcht0 [r11+rdx+0x80] + paddd xmm0, xmmword ptr [rsp] + paddd xmm1, xmmword ptr [rsp+0x20] + paddd xmm2, xmmword ptr [rsp+0x40] + paddd xmm3, xmmword ptr [rsp+0x60] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [BLAKE3_IV_0+rip] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x10] + paddd xmm1, xmmword ptr [rsp+0x30] + paddd xmm2, xmmword ptr [rsp+0x50] + paddd xmm3, xmmword ptr [rsp+0x70] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x80] + paddd xmm1, xmmword ptr [rsp+0xA0] + paddd xmm2, xmmword ptr [rsp+0xC0] + paddd xmm3, xmmword ptr [rsp+0xE0] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0x90] + paddd xmm1, xmmword ptr [rsp+0xB0] + paddd xmm2, xmmword ptr [rsp+0xD0] + paddd xmm3, xmmword ptr [rsp+0xF0] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0x20] + paddd xmm1, xmmword ptr [rsp+0x30] + paddd xmm2, xmmword ptr [rsp+0x70] + paddd xmm3, xmmword ptr [rsp+0x40] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x60] + paddd xmm1, xmmword ptr [rsp+0xA0] + paddd xmm2, xmmword ptr [rsp] + paddd xmm3, xmmword ptr [rsp+0xD0] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x10] + paddd xmm1, xmmword ptr [rsp+0xC0] + paddd xmm2, xmmword ptr [rsp+0x90] + paddd xmm3, xmmword ptr [rsp+0xF0] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0xB0] + paddd xmm1, xmmword ptr [rsp+0x50] + paddd xmm2, xmmword ptr [rsp+0xE0] + paddd xmm3, xmmword ptr [rsp+0x80] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0x30] + paddd xmm1, xmmword ptr [rsp+0xA0] + paddd xmm2, xmmword ptr [rsp+0xD0] + paddd xmm3, xmmword ptr [rsp+0x70] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x40] + paddd xmm1, xmmword ptr [rsp+0xC0] + paddd xmm2, xmmword ptr [rsp+0x20] + paddd xmm3, xmmword ptr [rsp+0xE0] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x60] + paddd xmm1, xmmword ptr [rsp+0x90] + paddd xmm2, xmmword ptr [rsp+0xB0] + paddd xmm3, xmmword ptr [rsp+0x80] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0x50] + paddd xmm1, xmmword ptr [rsp] + paddd xmm2, xmmword ptr [rsp+0xF0] + paddd xmm3, xmmword ptr [rsp+0x10] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0xA0] + paddd xmm1, xmmword ptr [rsp+0xC0] + paddd xmm2, xmmword ptr [rsp+0xE0] + paddd xmm3, xmmword ptr [rsp+0xD0] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x70] + paddd xmm1, xmmword ptr [rsp+0x90] + paddd xmm2, xmmword ptr [rsp+0x30] + paddd xmm3, xmmword ptr [rsp+0xF0] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x40] + paddd xmm1, xmmword ptr [rsp+0xB0] + paddd xmm2, xmmword ptr [rsp+0x50] + paddd xmm3, xmmword ptr [rsp+0x10] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp] + paddd xmm1, xmmword ptr [rsp+0x20] + paddd xmm2, xmmword ptr [rsp+0x80] + paddd xmm3, xmmword ptr [rsp+0x60] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0xC0] + paddd xmm1, xmmword ptr [rsp+0x90] + paddd xmm2, xmmword ptr [rsp+0xF0] + paddd xmm3, xmmword ptr [rsp+0xE0] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0xD0] + paddd xmm1, xmmword ptr [rsp+0xB0] + paddd xmm2, xmmword ptr [rsp+0xA0] + paddd xmm3, xmmword ptr [rsp+0x80] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0x70] + paddd xmm1, xmmword ptr [rsp+0x50] + paddd xmm2, xmmword ptr [rsp] + paddd xmm3, xmmword ptr [rsp+0x60] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0x20] + paddd xmm1, xmmword ptr [rsp+0x30] + paddd xmm2, xmmword ptr [rsp+0x10] + paddd xmm3, xmmword ptr [rsp+0x40] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0x90] + paddd xmm1, xmmword ptr [rsp+0xB0] + paddd xmm2, xmmword ptr [rsp+0x80] + paddd xmm3, xmmword ptr [rsp+0xF0] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0xE0] + paddd xmm1, xmmword ptr [rsp+0x50] + paddd xmm2, xmmword ptr [rsp+0xC0] + paddd xmm3, xmmword ptr [rsp+0x10] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0xD0] + paddd xmm1, xmmword ptr [rsp] + paddd xmm2, xmmword ptr [rsp+0x20] + paddd xmm3, xmmword ptr [rsp+0x40] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0x30] + paddd xmm1, xmmword ptr [rsp+0xA0] + paddd xmm2, xmmword ptr [rsp+0x60] + paddd xmm3, xmmword ptr [rsp+0x70] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0xB0] + paddd xmm1, xmmword ptr [rsp+0x50] + paddd xmm2, xmmword ptr [rsp+0x10] + paddd xmm3, xmmword ptr [rsp+0x80] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0xF0] + paddd xmm1, xmmword ptr [rsp] + paddd xmm2, xmmword ptr [rsp+0x90] + paddd xmm3, xmmword ptr [rsp+0x60] + paddd xmm0, xmm4 + paddd xmm1, xmm5 + paddd xmm2, xmm6 + paddd xmm3, xmm7 + pxor xmm12, xmm0 + pxor xmm13, xmm1 + pxor xmm14, xmm2 + pxor xmm15, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + pshufb xmm15, xmm8 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm12 + paddd xmm9, xmm13 + paddd xmm10, xmm14 + paddd xmm11, xmm15 + pxor xmm4, xmm8 + pxor xmm5, xmm9 + pxor xmm6, xmm10 + pxor xmm7, xmm11 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + paddd xmm0, xmmword ptr [rsp+0xE0] + paddd xmm1, xmmword ptr [rsp+0x20] + paddd xmm2, xmmword ptr [rsp+0x30] + paddd xmm3, xmmword ptr [rsp+0x70] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT16+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + movdqa xmmword ptr [rsp+0x100], xmm8 + movdqa xmm8, xmm5 + psrld xmm8, 12 + pslld xmm5, 20 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 12 + pslld xmm6, 20 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 12 + pslld xmm7, 20 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 12 + pslld xmm4, 20 + por xmm4, xmm8 + paddd xmm0, xmmword ptr [rsp+0xA0] + paddd xmm1, xmmword ptr [rsp+0xC0] + paddd xmm2, xmmword ptr [rsp+0x40] + paddd xmm3, xmmword ptr [rsp+0xD0] + paddd xmm0, xmm5 + paddd xmm1, xmm6 + paddd xmm2, xmm7 + paddd xmm3, xmm4 + pxor xmm15, xmm0 + pxor xmm12, xmm1 + pxor xmm13, xmm2 + pxor xmm14, xmm3 + movdqa xmm8, xmmword ptr [ROT8+rip] + pshufb xmm15, xmm8 + pshufb xmm12, xmm8 + pshufb xmm13, xmm8 + pshufb xmm14, xmm8 + paddd xmm10, xmm15 + paddd xmm11, xmm12 + movdqa xmm8, xmmword ptr [rsp+0x100] + paddd xmm8, xmm13 + paddd xmm9, xmm14 + pxor xmm5, xmm10 + pxor xmm6, xmm11 + pxor xmm7, xmm8 + pxor xmm4, xmm9 + pxor xmm0, xmm8 + pxor xmm1, xmm9 + pxor xmm2, xmm10 + pxor xmm3, xmm11 + movdqa xmm8, xmm5 + psrld xmm8, 7 + pslld xmm5, 25 + por xmm5, xmm8 + movdqa xmm8, xmm6 + psrld xmm8, 7 + pslld xmm6, 25 + por xmm6, xmm8 + movdqa xmm8, xmm7 + psrld xmm8, 7 + pslld xmm7, 25 + por xmm7, xmm8 + movdqa xmm8, xmm4 + psrld xmm8, 7 + pslld xmm4, 25 + por xmm4, xmm8 + pxor xmm4, xmm12 + pxor xmm5, xmm13 + pxor xmm6, xmm14 + pxor xmm7, xmm15 + mov eax, r13d + jne 9b + movdqa xmm9, xmm0 + punpckldq xmm0, xmm1 + punpckhdq xmm9, xmm1 + movdqa xmm11, xmm2 + punpckldq xmm2, xmm3 + punpckhdq xmm11, xmm3 + movdqa xmm1, xmm0 + punpcklqdq xmm0, xmm2 + punpckhqdq xmm1, xmm2 + movdqa xmm3, xmm9 + punpcklqdq xmm9, xmm11 + punpckhqdq xmm3, xmm11 + movdqu xmmword ptr [rbx], xmm0 + movdqu xmmword ptr [rbx+0x20], xmm1 + movdqu xmmword ptr [rbx+0x40], xmm9 + movdqu xmmword ptr [rbx+0x60], xmm3 + movdqa xmm9, xmm4 + punpckldq xmm4, xmm5 + punpckhdq xmm9, xmm5 + movdqa xmm11, xmm6 + punpckldq xmm6, xmm7 + punpckhdq xmm11, xmm7 + movdqa xmm5, xmm4 + punpcklqdq xmm4, xmm6 + punpckhqdq xmm5, xmm6 + movdqa xmm7, xmm9 + punpcklqdq xmm9, xmm11 + punpckhqdq xmm7, xmm11 + movdqu xmmword ptr [rbx+0x10], xmm4 + movdqu xmmword ptr [rbx+0x30], xmm5 + movdqu xmmword ptr [rbx+0x50], xmm9 + movdqu xmmword ptr [rbx+0x70], xmm7 + movdqa xmm1, xmmword ptr [rsp+0x110] + movdqa xmm0, xmm1 + paddd xmm1, xmmword ptr [rsp+0x150] + movdqa xmmword ptr [rsp+0x110], xmm1 + pxor xmm0, xmmword ptr [CMP_MSB_MASK+rip] + pxor xmm1, xmmword ptr [CMP_MSB_MASK+rip] + pcmpgtd xmm0, xmm1 + movdqa xmm1, xmmword ptr [rsp+0x120] + psubd xmm1, xmm0 + movdqa xmmword ptr [rsp+0x120], xmm1 + add rbx, 128 + add rdi, 32 + sub rsi, 4 + cmp rsi, 4 + jnc 2b + test rsi, rsi + jnz 3f +4: + mov rsp, rbp + pop rbp + pop rbx + pop r12 + pop r13 + pop r14 + pop r15 + ret +.p2align 5 +3: + test esi, 0x2 + je 3f + movups xmm0, xmmword ptr [rcx] + movups xmm1, xmmword ptr [rcx+0x10] + movaps xmm8, xmm0 + movaps xmm9, xmm1 + movd xmm13, dword ptr [rsp+0x110] + pinsrd xmm13, dword ptr [rsp+0x120], 1 + pinsrd xmm13, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + movaps xmmword ptr [rsp], xmm13 + movd xmm14, dword ptr [rsp+0x114] + pinsrd xmm14, dword ptr [rsp+0x124], 1 + pinsrd xmm14, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + movaps xmmword ptr [rsp+0x10], xmm14 + mov r8, qword ptr [rdi] + mov r9, qword ptr [rdi+0x8] + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +2: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + movaps xmm2, xmmword ptr [BLAKE3_IV+rip] + movaps xmm10, xmm2 + movups xmm4, xmmword ptr [r8+rdx-0x40] + movups xmm5, xmmword ptr [r8+rdx-0x30] + movaps xmm3, xmm4 + shufps xmm4, xmm5, 136 + shufps xmm3, xmm5, 221 + movaps xmm5, xmm3 + movups xmm6, xmmword ptr [r8+rdx-0x20] + movups xmm7, xmmword ptr [r8+rdx-0x10] + movaps xmm3, xmm6 + shufps xmm6, xmm7, 136 + pshufd xmm6, xmm6, 0x93 + shufps xmm3, xmm7, 221 + pshufd xmm7, xmm3, 0x93 + movups xmm12, xmmword ptr [r9+rdx-0x40] + movups xmm13, xmmword ptr [r9+rdx-0x30] + movaps xmm11, xmm12 + shufps xmm12, xmm13, 136 + shufps xmm11, xmm13, 221 + movaps xmm13, xmm11 + movups xmm14, xmmword ptr [r9+rdx-0x20] + movups xmm15, xmmword ptr [r9+rdx-0x10] + movaps xmm11, xmm14 + shufps xmm14, xmm15, 136 + pshufd xmm14, xmm14, 0x93 + shufps xmm11, xmm15, 221 + pshufd xmm15, xmm11, 0x93 + movaps xmm3, xmmword ptr [rsp] + movaps xmm11, xmmword ptr [rsp+0x10] + pinsrd xmm3, eax, 3 + pinsrd xmm11, eax, 3 + mov al, 7 +9: + paddd xmm0, xmm4 + paddd xmm8, xmm12 + movaps xmmword ptr [rsp+0x20], xmm4 + movaps xmmword ptr [rsp+0x30], xmm12 + paddd xmm0, xmm1 + paddd xmm8, xmm9 + pxor xmm3, xmm0 + pxor xmm11, xmm8 + movaps xmm12, xmmword ptr [ROT16+rip] + pshufb xmm3, xmm12 + pshufb xmm11, xmm12 + paddd xmm2, xmm3 + paddd xmm10, xmm11 + pxor xmm1, xmm2 + pxor xmm9, xmm10 + movdqa xmm4, xmm1 + pslld xmm1, 20 + psrld xmm4, 12 + por xmm1, xmm4 + movdqa xmm4, xmm9 + pslld xmm9, 20 + psrld xmm4, 12 + por xmm9, xmm4 + paddd xmm0, xmm5 + paddd xmm8, xmm13 + movaps xmmword ptr [rsp+0x40], xmm5 + movaps xmmword ptr [rsp+0x50], xmm13 + paddd xmm0, xmm1 + paddd xmm8, xmm9 + pxor xmm3, xmm0 + pxor xmm11, xmm8 + movaps xmm13, xmmword ptr [ROT8+rip] + pshufb xmm3, xmm13 + pshufb xmm11, xmm13 + paddd xmm2, xmm3 + paddd xmm10, xmm11 + pxor xmm1, xmm2 + pxor xmm9, xmm10 + movdqa xmm4, xmm1 + pslld xmm1, 25 + psrld xmm4, 7 + por xmm1, xmm4 + movdqa xmm4, xmm9 + pslld xmm9, 25 + psrld xmm4, 7 + por xmm9, xmm4 + pshufd xmm0, xmm0, 0x93 + pshufd xmm8, xmm8, 0x93 + pshufd xmm3, xmm3, 0x4E + pshufd xmm11, xmm11, 0x4E + pshufd xmm2, xmm2, 0x39 + pshufd xmm10, xmm10, 0x39 + paddd xmm0, xmm6 + paddd xmm8, xmm14 + paddd xmm0, xmm1 + paddd xmm8, xmm9 + pxor xmm3, xmm0 + pxor xmm11, xmm8 + pshufb xmm3, xmm12 + pshufb xmm11, xmm12 + paddd xmm2, xmm3 + paddd xmm10, xmm11 + pxor xmm1, xmm2 + pxor xmm9, xmm10 + movdqa xmm4, xmm1 + pslld xmm1, 20 + psrld xmm4, 12 + por xmm1, xmm4 + movdqa xmm4, xmm9 + pslld xmm9, 20 + psrld xmm4, 12 + por xmm9, xmm4 + paddd xmm0, xmm7 + paddd xmm8, xmm15 + paddd xmm0, xmm1 + paddd xmm8, xmm9 + pxor xmm3, xmm0 + pxor xmm11, xmm8 + pshufb xmm3, xmm13 + pshufb xmm11, xmm13 + paddd xmm2, xmm3 + paddd xmm10, xmm11 + pxor xmm1, xmm2 + pxor xmm9, xmm10 + movdqa xmm4, xmm1 + pslld xmm1, 25 + psrld xmm4, 7 + por xmm1, xmm4 + movdqa xmm4, xmm9 + pslld xmm9, 25 + psrld xmm4, 7 + por xmm9, xmm4 + pshufd xmm0, xmm0, 0x39 + pshufd xmm8, xmm8, 0x39 + pshufd xmm3, xmm3, 0x4E + pshufd xmm11, xmm11, 0x4E + pshufd xmm2, xmm2, 0x93 + pshufd xmm10, xmm10, 0x93 + dec al + je 9f + movdqa xmm12, xmmword ptr [rsp+0x20] + movdqa xmm5, xmmword ptr [rsp+0x40] + pshufd xmm13, xmm12, 0x0F + shufps xmm12, xmm5, 214 + pshufd xmm4, xmm12, 0x39 + movdqa xmm12, xmm6 + shufps xmm12, xmm7, 250 + pblendw xmm13, xmm12, 0xCC + movdqa xmm12, xmm7 + punpcklqdq xmm12, xmm5 + pblendw xmm12, xmm6, 0xC0 + pshufd xmm12, xmm12, 0x78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, 0x1E + movdqa xmmword ptr [rsp+0x20], xmm13 + movdqa xmmword ptr [rsp+0x40], xmm12 + movdqa xmm5, xmmword ptr [rsp+0x30] + movdqa xmm13, xmmword ptr [rsp+0x50] + pshufd xmm6, xmm5, 0x0F + shufps xmm5, xmm13, 214 + pshufd xmm12, xmm5, 0x39 + movdqa xmm5, xmm14 + shufps xmm5, xmm15, 250 + pblendw xmm6, xmm5, 0xCC + movdqa xmm5, xmm15 + punpcklqdq xmm5, xmm13 + pblendw xmm5, xmm14, 0xC0 + pshufd xmm5, xmm5, 0x78 + punpckhdq xmm13, xmm15 + punpckldq xmm14, xmm13 + pshufd xmm15, xmm14, 0x1E + movdqa xmm13, xmm6 + movdqa xmm14, xmm5 + movdqa xmm5, xmmword ptr [rsp+0x20] + movdqa xmm6, xmmword ptr [rsp+0x40] + jmp 9b +9: + pxor xmm0, xmm2 + pxor xmm1, xmm3 + pxor xmm8, xmm10 + pxor xmm9, xmm11 + mov eax, r13d + cmp rdx, r15 + jne 2b + movups xmmword ptr [rbx], xmm0 + movups xmmword ptr [rbx+0x10], xmm1 + movups xmmword ptr [rbx+0x20], xmm8 + movups xmmword ptr [rbx+0x30], xmm9 + movdqa xmm0, xmmword ptr [rsp+0x130] + movdqa xmm1, xmmword ptr [rsp+0x110] + movdqa xmm2, xmmword ptr [rsp+0x120] + movdqu xmm3, xmmword ptr [rsp+0x118] + movdqu xmm4, xmmword ptr [rsp+0x128] + blendvps xmm1, xmm3, xmm0 + blendvps xmm2, xmm4, xmm0 + movdqa xmmword ptr [rsp+0x110], xmm1 + movdqa xmmword ptr [rsp+0x120], xmm2 + add rdi, 16 + add rbx, 64 + sub rsi, 2 +3: + test esi, 0x1 + je 4b + movups xmm0, xmmword ptr [rcx] + movups xmm1, xmmword ptr [rcx+0x10] + movd xmm13, dword ptr [rsp+0x110] + pinsrd xmm13, dword ptr [rsp+0x120], 1 + pinsrd xmm13, dword ptr [BLAKE3_BLOCK_LEN+rip], 2 + movaps xmm14, xmmword ptr [ROT8+rip] + movaps xmm15, xmmword ptr [ROT16+rip] + mov r8, qword ptr [rdi] + movzx eax, byte ptr [rbp+0x40] + or eax, r13d + xor edx, edx +2: + mov r14d, eax + or eax, r12d + add rdx, 64 + cmp rdx, r15 + cmovne eax, r14d + movaps xmm2, xmmword ptr [BLAKE3_IV+rip] + movaps xmm3, xmm13 + pinsrd xmm3, eax, 3 + movups xmm4, xmmword ptr [r8+rdx-0x40] + movups xmm5, xmmword ptr [r8+rdx-0x30] + movaps xmm8, xmm4 + shufps xmm4, xmm5, 136 + shufps xmm8, xmm5, 221 + movaps xmm5, xmm8 + movups xmm6, xmmword ptr [r8+rdx-0x20] + movups xmm7, xmmword ptr [r8+rdx-0x10] + movaps xmm8, xmm6 + shufps xmm6, xmm7, 136 + pshufd xmm6, xmm6, 0x93 + shufps xmm8, xmm7, 221 + pshufd xmm7, xmm8, 0x93 + mov al, 7 +9: + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm15 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm14 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + pshufd xmm0, xmm0, 0x93 + pshufd xmm3, xmm3, 0x4E + pshufd xmm2, xmm2, 0x39 + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm15 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm14 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + pshufd xmm0, xmm0, 0x39 + pshufd xmm3, xmm3, 0x4E + pshufd xmm2, xmm2, 0x93 + dec al + jz 9f + movdqa xmm8, xmm4 + shufps xmm8, xmm5, 214 + pshufd xmm9, xmm4, 0x0F + pshufd xmm4, xmm8, 0x39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, 250 + pblendw xmm9, xmm8, 0xCC + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + pblendw xmm8, xmm6, 0xC0 + pshufd xmm8, xmm8, 0x78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, 0x1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + jmp 9b +9: + pxor xmm0, xmm2 + pxor xmm1, xmm3 + mov eax, r13d + cmp rdx, r15 + jne 2b + movups xmmword ptr [rbx], xmm0 + movups xmmword ptr [rbx+0x10], xmm1 + jmp 4b + +.p2align 6 +blake3_compress_in_place_sse41: +_blake3_compress_in_place_sse41: + movups xmm0, xmmword ptr [rdi] + movups xmm1, xmmword ptr [rdi+0x10] + movaps xmm2, xmmword ptr [BLAKE3_IV+rip] + shl r8, 32 + add rdx, r8 + movq xmm3, rcx + movq xmm4, rdx + punpcklqdq xmm3, xmm4 + movups xmm4, xmmword ptr [rsi] + movups xmm5, xmmword ptr [rsi+0x10] + movaps xmm8, xmm4 + shufps xmm4, xmm5, 136 + shufps xmm8, xmm5, 221 + movaps xmm5, xmm8 + movups xmm6, xmmword ptr [rsi+0x20] + movups xmm7, xmmword ptr [rsi+0x30] + movaps xmm8, xmm6 + shufps xmm6, xmm7, 136 + pshufd xmm6, xmm6, 0x93 + shufps xmm8, xmm7, 221 + pshufd xmm7, xmm8, 0x93 + movaps xmm14, xmmword ptr [ROT8+rip] + movaps xmm15, xmmword ptr [ROT16+rip] + mov al, 7 +9: + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm15 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm14 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + pshufd xmm0, xmm0, 0x93 + pshufd xmm3, xmm3, 0x4E + pshufd xmm2, xmm2, 0x39 + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm15 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm14 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + pshufd xmm0, xmm0, 0x39 + pshufd xmm3, xmm3, 0x4E + pshufd xmm2, xmm2, 0x93 + dec al + jz 9f + movdqa xmm8, xmm4 + shufps xmm8, xmm5, 214 + pshufd xmm9, xmm4, 0x0F + pshufd xmm4, xmm8, 0x39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, 250 + pblendw xmm9, xmm8, 0xCC + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + pblendw xmm8, xmm6, 0xC0 + pshufd xmm8, xmm8, 0x78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, 0x1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + jmp 9b +9: + pxor xmm0, xmm2 + pxor xmm1, xmm3 + movups xmmword ptr [rdi], xmm0 + movups xmmword ptr [rdi+0x10], xmm1 + ret + +.p2align 6 +blake3_compress_xof_sse41: +_blake3_compress_xof_sse41: + movups xmm0, xmmword ptr [rdi] + movups xmm1, xmmword ptr [rdi+0x10] + movaps xmm2, xmmword ptr [BLAKE3_IV+rip] + movzx eax, r8b + movzx edx, dl + shl rax, 32 + add rdx, rax + movq xmm3, rcx + movq xmm4, rdx + punpcklqdq xmm3, xmm4 + movups xmm4, xmmword ptr [rsi] + movups xmm5, xmmword ptr [rsi+0x10] + movaps xmm8, xmm4 + shufps xmm4, xmm5, 136 + shufps xmm8, xmm5, 221 + movaps xmm5, xmm8 + movups xmm6, xmmword ptr [rsi+0x20] + movups xmm7, xmmword ptr [rsi+0x30] + movaps xmm8, xmm6 + shufps xmm6, xmm7, 136 + pshufd xmm6, xmm6, 0x93 + shufps xmm8, xmm7, 221 + pshufd xmm7, xmm8, 0x93 + movaps xmm14, xmmword ptr [ROT8+rip] + movaps xmm15, xmmword ptr [ROT16+rip] + mov al, 7 +9: + paddd xmm0, xmm4 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm15 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + paddd xmm0, xmm5 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm14 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + pshufd xmm0, xmm0, 0x93 + pshufd xmm3, xmm3, 0x4E + pshufd xmm2, xmm2, 0x39 + paddd xmm0, xmm6 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm15 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 20 + psrld xmm11, 12 + por xmm1, xmm11 + paddd xmm0, xmm7 + paddd xmm0, xmm1 + pxor xmm3, xmm0 + pshufb xmm3, xmm14 + paddd xmm2, xmm3 + pxor xmm1, xmm2 + movdqa xmm11, xmm1 + pslld xmm1, 25 + psrld xmm11, 7 + por xmm1, xmm11 + pshufd xmm0, xmm0, 0x39 + pshufd xmm3, xmm3, 0x4E + pshufd xmm2, xmm2, 0x93 + dec al + jz 9f + movdqa xmm8, xmm4 + shufps xmm8, xmm5, 214 + pshufd xmm9, xmm4, 0x0F + pshufd xmm4, xmm8, 0x39 + movdqa xmm8, xmm6 + shufps xmm8, xmm7, 250 + pblendw xmm9, xmm8, 0xCC + movdqa xmm8, xmm7 + punpcklqdq xmm8, xmm5 + pblendw xmm8, xmm6, 0xC0 + pshufd xmm8, xmm8, 0x78 + punpckhdq xmm5, xmm7 + punpckldq xmm6, xmm5 + pshufd xmm7, xmm6, 0x1E + movdqa xmm5, xmm9 + movdqa xmm6, xmm8 + jmp 9b +9: + movdqu xmm4, xmmword ptr [rdi] + movdqu xmm5, xmmword ptr [rdi+0x10] + pxor xmm0, xmm2 + pxor xmm1, xmm3 + pxor xmm2, xmm4 + pxor xmm3, xmm5 + movups xmmword ptr [r9], xmm0 + movups xmmword ptr [r9+0x10], xmm1 + movups xmmword ptr [r9+0x20], xmm2 + movups xmmword ptr [r9+0x30], xmm3 + ret + + +#ifdef __APPLE__ +.static_data +#else +.section .rodata +#endif +.p2align 6 +BLAKE3_IV: + .long 0x6A09E667, 0xBB67AE85 + .long 0x3C6EF372, 0xA54FF53A +ROT16: + .byte 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13 +ROT8: + .byte 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12 +ADD0: + .long 0, 1, 2, 3 +ADD1: + .long 4, 4, 4, 4 +BLAKE3_IV_0: + .long 0x6A09E667, 0x6A09E667, 0x6A09E667, 0x6A09E667 +BLAKE3_IV_1: + .long 0xBB67AE85, 0xBB67AE85, 0xBB67AE85, 0xBB67AE85 +BLAKE3_IV_2: + .long 0x3C6EF372, 0x3C6EF372, 0x3C6EF372, 0x3C6EF372 +BLAKE3_IV_3: + .long 0xA54FF53A, 0xA54FF53A, 0xA54FF53A, 0xA54FF53A +BLAKE3_BLOCK_LEN: + .long 64, 64, 64, 64 +CMP_MSB_MASK: + .long 0x80000000, 0x80000000, 0x80000000, 0x80000000 + +#endif // __x86_64__ diff --git a/src/bech32/segwit_addr.c b/src/bech32/segwit_addr.c index 7cd7c614..2a46e30f 100644 --- a/src/bech32/segwit_addr.c +++ b/src/bech32/segwit_addr.c @@ -1,215 +1,215 @@ -/* Copyright (c) 2017, 2021 Pieter Wuille - * - * 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 "segwit_addr.h" - -static uint32_t bech32_polymod_step(uint32_t pre) { - uint8_t b = pre >> 25; - return ((pre & 0x1FFFFFF) << 5) ^ - (-((b >> 0) & 1) & 0x3b6a57b2UL) ^ - (-((b >> 1) & 1) & 0x26508e6dUL) ^ - (-((b >> 2) & 1) & 0x1ea119faUL) ^ - (-((b >> 3) & 1) & 0x3d4233ddUL) ^ - (-((b >> 4) & 1) & 0x2a1462b3UL); -} - -#pragma warning( push ) -#pragma warning( disable : 4715 ) // Not all control paths retrn a value -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wreturn-type" -static uint32_t bech32_final_constant(bech32_encoding enc) { - if (enc == BECH32_ENCODING_BECH32) return 1; - if (enc == BECH32_ENCODING_BECH32M) return 0x2bc830a3; - assert(0); -} -#pragma GCC diagnostic pop -#pragma warning( pop ) - -static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; - -static const int8_t charset_rev[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, - -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, - 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, - -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, - 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 -}; - -int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len, bech32_encoding enc) { - uint32_t chk = 1; - size_t i = 0; - while (hrp[i] != 0) { - int ch = hrp[i]; - if (ch < 33 || ch > 126) { - return 0; - } - - if (ch >= 'A' && ch <= 'Z') return 0; - chk = bech32_polymod_step(chk) ^ (ch >> 5); - ++i; - } - if (i + 7 + data_len > 90) return 0; - chk = bech32_polymod_step(chk); - while (*hrp != 0) { - chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f); - *(output++) = *(hrp++); - } - *(output++) = '1'; - for (i = 0; i < data_len; ++i) { - if (*data >> 5) return 0; - chk = bech32_polymod_step(chk) ^ (*data); - *(output++) = charset[*(data++)]; - } - for (i = 0; i < 6; ++i) { - chk = bech32_polymod_step(chk); - } - chk ^= bech32_final_constant(enc); - for (i = 0; i < 6; ++i) { - *(output++) = charset[(chk >> ((5 - i) * 5)) & 0x1f]; - } - *output = 0; - return 1; -} - -bech32_encoding bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) { - uint32_t chk = 1; - size_t i; - size_t input_len = strlen(input); - size_t hrp_len; - int have_lower = 0, have_upper = 0; - if (input_len < 8 || input_len > 90) { - return BECH32_ENCODING_NONE; - } - *data_len = 0; - while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') { - ++(*data_len); - } - hrp_len = input_len - (1 + *data_len); - if (1 + *data_len >= input_len || *data_len < 6) { - return BECH32_ENCODING_NONE; - } - *(data_len) -= 6; - for (i = 0; i < hrp_len; ++i) { - int ch = input[i]; - if (ch < 33 || ch > 126) { - return BECH32_ENCODING_NONE; - } - if (ch >= 'a' && ch <= 'z') { - have_lower = 1; - } else if (ch >= 'A' && ch <= 'Z') { - have_upper = 1; - ch = (ch - 'A') + 'a'; - } - hrp[i] = ch; - chk = bech32_polymod_step(chk) ^ (ch >> 5); - } - hrp[i] = 0; - chk = bech32_polymod_step(chk); - for (i = 0; i < hrp_len; ++i) { - chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f); - } - ++i; - while (i < input_len) { - int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; - if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1; - if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; - if (v == -1) { - return BECH32_ENCODING_NONE; - } - chk = bech32_polymod_step(chk) ^ v; - if (i + 6 < input_len) { - data[i - (1 + hrp_len)] = v; - } - ++i; - } - if (have_lower && have_upper) { - return BECH32_ENCODING_NONE; - } - if (chk == bech32_final_constant(BECH32_ENCODING_BECH32)) { - return BECH32_ENCODING_BECH32; - } else if (chk == bech32_final_constant(BECH32_ENCODING_BECH32M)) { - return BECH32_ENCODING_BECH32M; - } else { - return BECH32_ENCODING_NONE; - } -} - -static int convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) { - uint32_t val = 0; - int bits = 0; - uint32_t maxv = (((uint32_t)1) << outbits) - 1; - while (inlen--) { - val = (val << inbits) | *(in++); - bits += inbits; - while (bits >= outbits) { - bits -= outbits; - out[(*outlen)++] = (val >> bits) & maxv; - } - } - if (pad) { - if (bits) { - out[(*outlen)++] = (val << (outbits - bits)) & maxv; - } - } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { - return 0; - } - return 1; -} - -int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) { - uint8_t data[65]; - size_t datalen = 0; - bech32_encoding enc = BECH32_ENCODING_BECH32; - if (witver > 16) return 0; - if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0; - if (witprog_len < 2 || witprog_len > 40) return 0; - if (witver > 0) enc = BECH32_ENCODING_BECH32M; - data[0] = witver; - convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1); - ++datalen; - return bech32_encode(output, hrp, data, datalen, enc); -} - -int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) { - uint8_t data[84]; - char hrp_actual[84]; - size_t data_len; - bech32_encoding enc = bech32_decode(hrp_actual, data, &data_len, addr); - if (enc == BECH32_ENCODING_NONE) return 0; - if (data_len == 0 || data_len > 65) return 0; - if (strncmp(hrp, hrp_actual, 84) != 0) return 0; - if (data[0] > 16) return 0; - if (data[0] == 0 && enc != BECH32_ENCODING_BECH32) return 0; - if (data[0] > 0 && enc != BECH32_ENCODING_BECH32M) return 0; - *witdata_len = 0; - if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0; - if (*witdata_len < 2 || *witdata_len > 40) return 0; - if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0; - *witver = data[0]; - return 1; -} +/* Copyright (c) 2017, 2021 Pieter Wuille + * + * 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 "segwit_addr.h" + +static uint32_t bech32_polymod_step(uint32_t pre) { + uint8_t b = pre >> 25; + return ((pre & 0x1FFFFFF) << 5) ^ + (-((b >> 0) & 1) & 0x3b6a57b2UL) ^ + (-((b >> 1) & 1) & 0x26508e6dUL) ^ + (-((b >> 2) & 1) & 0x1ea119faUL) ^ + (-((b >> 3) & 1) & 0x3d4233ddUL) ^ + (-((b >> 4) & 1) & 0x2a1462b3UL); +} + +#pragma warning( push ) +#pragma warning( disable : 4715 ) // Not all control paths retrn a value +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type" +static uint32_t bech32_final_constant(bech32_encoding enc) { + if (enc == BECH32_ENCODING_BECH32) return 1; + if (enc == BECH32_ENCODING_BECH32M) return 0x2bc830a3; + assert(0); +} +#pragma GCC diagnostic pop +#pragma warning( pop ) + +static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; + +static const int8_t charset_rev[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, + -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, + 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, + -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, + 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 +}; + +int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len, bech32_encoding enc) { + uint32_t chk = 1; + size_t i = 0; + while (hrp[i] != 0) { + int ch = hrp[i]; + if (ch < 33 || ch > 126) { + return 0; + } + + if (ch >= 'A' && ch <= 'Z') return 0; + chk = bech32_polymod_step(chk) ^ (ch >> 5); + ++i; + } + if (i + 7 + data_len > 90) return 0; + chk = bech32_polymod_step(chk); + while (*hrp != 0) { + chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f); + *(output++) = *(hrp++); + } + *(output++) = '1'; + for (i = 0; i < data_len; ++i) { + if (*data >> 5) return 0; + chk = bech32_polymod_step(chk) ^ (*data); + *(output++) = charset[*(data++)]; + } + for (i = 0; i < 6; ++i) { + chk = bech32_polymod_step(chk); + } + chk ^= bech32_final_constant(enc); + for (i = 0; i < 6; ++i) { + *(output++) = charset[(chk >> ((5 - i) * 5)) & 0x1f]; + } + *output = 0; + return 1; +} + +bech32_encoding bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) { + uint32_t chk = 1; + size_t i; + size_t input_len = strlen(input); + size_t hrp_len; + int have_lower = 0, have_upper = 0; + if (input_len < 8 || input_len > 90) { + return BECH32_ENCODING_NONE; + } + *data_len = 0; + while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') { + ++(*data_len); + } + hrp_len = input_len - (1 + *data_len); + if (1 + *data_len >= input_len || *data_len < 6) { + return BECH32_ENCODING_NONE; + } + *(data_len) -= 6; + for (i = 0; i < hrp_len; ++i) { + int ch = input[i]; + if (ch < 33 || ch > 126) { + return BECH32_ENCODING_NONE; + } + if (ch >= 'a' && ch <= 'z') { + have_lower = 1; + } else if (ch >= 'A' && ch <= 'Z') { + have_upper = 1; + ch = (ch - 'A') + 'a'; + } + hrp[i] = ch; + chk = bech32_polymod_step(chk) ^ (ch >> 5); + } + hrp[i] = 0; + chk = bech32_polymod_step(chk); + for (i = 0; i < hrp_len; ++i) { + chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f); + } + ++i; + while (i < input_len) { + int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; + if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1; + if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; + if (v == -1) { + return BECH32_ENCODING_NONE; + } + chk = bech32_polymod_step(chk) ^ v; + if (i + 6 < input_len) { + data[i - (1 + hrp_len)] = v; + } + ++i; + } + if (have_lower && have_upper) { + return BECH32_ENCODING_NONE; + } + if (chk == bech32_final_constant(BECH32_ENCODING_BECH32)) { + return BECH32_ENCODING_BECH32; + } else if (chk == bech32_final_constant(BECH32_ENCODING_BECH32M)) { + return BECH32_ENCODING_BECH32M; + } else { + return BECH32_ENCODING_NONE; + } +} + +int bech32_convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) { + uint32_t val = 0; + int bits = 0; + uint32_t maxv = (((uint32_t)1) << outbits) - 1; + while (inlen--) { + val = (val << inbits) | *(in++); + bits += inbits; + while (bits >= outbits) { + bits -= outbits; + out[(*outlen)++] = (val >> bits) & maxv; + } + } + if (pad) { + if (bits) { + out[(*outlen)++] = (val << (outbits - bits)) & maxv; + } + } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { + return 0; + } + return 1; +} + +int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) { + uint8_t data[65]; + size_t datalen = 0; + bech32_encoding enc = BECH32_ENCODING_BECH32; + if (witver > 16) return 0; + if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0; + if (witprog_len < 2 || witprog_len > 40) return 0; + if (witver > 0) enc = BECH32_ENCODING_BECH32M; + data[0] = witver; + bech32_convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1); + ++datalen; + return bech32_encode(output, hrp, data, datalen, enc); +} + +int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) { + uint8_t data[84]; + char hrp_actual[84]; + size_t data_len; + bech32_encoding enc = bech32_decode(hrp_actual, data, &data_len, addr); + if (enc == BECH32_ENCODING_NONE) return 0; + if (data_len == 0 || data_len > 65) return 0; + if (strncmp(hrp, hrp_actual, 84) != 0) return 0; + if (data[0] > 16) return 0; + if (data[0] == 0 && enc != BECH32_ENCODING_BECH32) return 0; + if (data[0] > 0 && enc != BECH32_ENCODING_BECH32M) return 0; + *witdata_len = 0; + if (!bech32_convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0; + if (*witdata_len < 2 || *witdata_len > 40) return 0; + if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0; + *witver = data[0]; + return 1; +} diff --git a/src/bech32/segwit_addr.h b/src/bech32/segwit_addr.h index 511970ab..31fb008f 100644 --- a/src/bech32/segwit_addr.h +++ b/src/bech32/segwit_addr.h @@ -1,113 +1,115 @@ -/* Copyright (c) 2017, 2021 Pieter Wuille - * - * 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 _SEGWIT_ADDR_H_ -#define _SEGWIT_ADDR_H_ 1 - -#include - - -/** Encode a SegWit address - * - * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be - * updated to contain the null-terminated address. - * In: hrp: Pointer to the null-terminated human readable part to use - * (chain/network specific). - * ver: Version of the witness program (between 0 and 16 inclusive). - * prog: Data bytes for the witness program (between 2 and 40 bytes). - * prog_len: Number of data bytes in prog. - * Returns 1 if successful. - */ -int segwit_addr_encode( - char *output, - const char *hrp, - int ver, - const uint8_t *prog, - size_t prog_len -); - -/** Decode a SegWit address - * - * Out: ver: Pointer to an int that will be updated to contain the witness - * program version (between 0 and 16 inclusive). - * prog: Pointer to a buffer of size 40 that will be updated to - * contain the witness program bytes. - * prog_len: Pointer to a size_t that will be updated to contain the length - * of bytes in prog. - * hrp: Pointer to the null-terminated human readable part that is - * expected (chain/network specific). - * addr: Pointer to the null-terminated address. - * Returns 1 if successful. - */ -int segwit_addr_decode( - int* ver, - uint8_t* prog, - size_t* prog_len, - const char* hrp, - const char* addr -); - -/** Supported encodings. */ -typedef enum { - BECH32_ENCODING_NONE, - BECH32_ENCODING_BECH32, - BECH32_ENCODING_BECH32M -} bech32_encoding; - -/** Encode a Bech32 or Bech32m string - * - * Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that - * will be updated to contain the null-terminated Bech32 string. - * In: hrp : Pointer to the null-terminated human readable part. - * data : Pointer to an array of 5-bit values. - * data_len: Length of the data array. - * enc: Which encoding to use (BECH32_ENCODING_BECH32{,M}). - * Returns 1 if successful. - */ -int bech32_encode( - char *output, - const char *hrp, - const uint8_t *data, - size_t data_len, - bech32_encoding enc -); - -/** Decode a Bech32 or Bech32m string - * - * Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be - * updated to contain the null-terminated human readable part. - * data: Pointer to a buffer of size strlen(input) - 8 that will - * hold the encoded 5-bit data values. - * data_len: Pointer to a size_t that will be updated to be the number - * of entries in data. - * In: input: Pointer to a null-terminated Bech32 string. - * Returns BECH32_ENCODING_BECH32{,M} to indicate decoding was successful - * with the specified encoding standard. BECH32_ENCODING_NONE is returned if - * decoding failed. - */ -bech32_encoding bech32_decode( - char *hrp, - uint8_t *data, - size_t *data_len, - const char *input -); - -#endif +/* Copyright (c) 2017, 2021 Pieter Wuille + * + * 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 _SEGWIT_ADDR_H_ +#define _SEGWIT_ADDR_H_ 1 + +#include + + +/** Encode a SegWit address + * + * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be + * updated to contain the null-terminated address. + * In: hrp: Pointer to the null-terminated human readable part to use + * (chain/network specific). + * ver: Version of the witness program (between 0 and 16 inclusive). + * prog: Data bytes for the witness program (between 2 and 40 bytes). + * prog_len: Number of data bytes in prog. + * Returns 1 if successful. + */ +int segwit_addr_encode( + char *output, + const char *hrp, + int ver, + const uint8_t *prog, + size_t prog_len +); + +/** Decode a SegWit address + * + * Out: ver: Pointer to an int that will be updated to contain the witness + * program version (between 0 and 16 inclusive). + * prog: Pointer to a buffer of size 40 that will be updated to + * contain the witness program bytes. + * prog_len: Pointer to a size_t that will be updated to contain the length + * of bytes in prog. + * hrp: Pointer to the null-terminated human readable part that is + * expected (chain/network specific). + * addr: Pointer to the null-terminated address. + * Returns 1 if successful. + */ +int segwit_addr_decode( + int* ver, + uint8_t* prog, + size_t* prog_len, + const char* hrp, + const char* addr +); + +/** Supported encodings. */ +typedef enum { + BECH32_ENCODING_NONE, + BECH32_ENCODING_BECH32, + BECH32_ENCODING_BECH32M +} bech32_encoding; + +/** Encode a Bech32 or Bech32m string + * + * Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that + * will be updated to contain the null-terminated Bech32 string. + * In: hrp : Pointer to the null-terminated human readable part. + * data : Pointer to an array of 5-bit values. + * data_len: Length of the data array. + * enc: Which encoding to use (BECH32_ENCODING_BECH32{,M}). + * Returns 1 if successful. + */ +int bech32_encode( + char *output, + const char *hrp, + const uint8_t *data, + size_t data_len, + bech32_encoding enc +); + +/** Decode a Bech32 or Bech32m string + * + * Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be + * updated to contain the null-terminated human readable part. + * data: Pointer to a buffer of size strlen(input) - 8 that will + * hold the encoded 5-bit data values. + * data_len: Pointer to a size_t that will be updated to be the number + * of entries in data. + * In: input: Pointer to a null-terminated Bech32 string. + * Returns BECH32_ENCODING_BECH32{,M} to indicate decoding was successful + * with the specified encoding standard. BECH32_ENCODING_NONE is returned if + * decoding failed. + */ +bech32_encoding bech32_decode( + char *hrp, + uint8_t *data, + size_t *data_len, + const char *input +); + +int bech32_convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad); + +#endif diff --git a/src/fse/LICENSE b/src/fse/LICENSE index b6942af4..536ad621 100644 --- a/src/fse/LICENSE +++ b/src/fse/LICENSE @@ -1,23 +1,23 @@ -Copyright (c) 2013, Yann Collet -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 +Copyright (c) 2013, Yann Collet +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. \ No newline at end of file diff --git a/src/fse/README.md b/src/fse/README.md index 5b18f20b..520b9a47 100644 --- a/src/fse/README.md +++ b/src/fse/README.md @@ -1,38 +1,38 @@ -New Generation Entropy library -============================== - -The __lib__ directory contains several files, but you don't necessarily want them all. -Here is a detailed list, to help you decide which one you need : - - -#### Compulsory files - -These files are required in all circumstances : -- __error_public.h__ : error list as enum -- __error_private.h__ : error management -- __mem.h__ : low level memory access routines -- __bitstream.h__ : generic read/write bitstream common to all entropy codecs -- __entropy_common.c__ : common functions needed for both compression and decompression - - -#### Finite State Entropy - -This is the base codec required by other ones. -It implements a tANS variant, similar to arithmetic in compression performance, but much faster. Compression and decompression can be compiled independently. -- __fse.h__ : exposes interfaces -- __fse_compress.c__ : implements compression codec -- __fse_decompress.c__ : implements decompression codec - - -#### FSE 16-bits symbols version - -This codec is able to encode alphabets of size > 256, using 2 bytes per symbol. It requires the base FSE codec to compile properly. Compression and decompression are merged in the same file. -- __fseU16.c__ implements the codec, while __fseU16.h__ exposes its interfaces. - - -#### Huffman codec - -This is the fast huffman codec. It requires the base FSE codec to compress its headers. Compression and decompression can be compiled independently. -- __huf.h__ : exposes interfaces. -- __huf_compress.c__ : implements compression codec -- __huf_decompress.c__ : implements decompression codec +New Generation Entropy library +============================== + +The __lib__ directory contains several files, but you don't necessarily want them all. +Here is a detailed list, to help you decide which one you need : + + +#### Compulsory files + +These files are required in all circumstances : +- __error_public.h__ : error list as enum +- __error_private.h__ : error management +- __mem.h__ : low level memory access routines +- __bitstream.h__ : generic read/write bitstream common to all entropy codecs +- __entropy_common.c__ : common functions needed for both compression and decompression + + +#### Finite State Entropy + +This is the base codec required by other ones. +It implements a tANS variant, similar to arithmetic in compression performance, but much faster. Compression and decompression can be compiled independently. +- __fse.h__ : exposes interfaces +- __fse_compress.c__ : implements compression codec +- __fse_decompress.c__ : implements decompression codec + + +#### FSE 16-bits symbols version + +This codec is able to encode alphabets of size > 256, using 2 bytes per symbol. It requires the base FSE codec to compile properly. Compression and decompression are merged in the same file. +- __fseU16.c__ implements the codec, while __fseU16.h__ exposes its interfaces. + + +#### Huffman codec + +This is the fast huffman codec. It requires the base FSE codec to compress its headers. Compression and decompression can be compiled independently. +- __huf.h__ : exposes interfaces. +- __huf_compress.c__ : implements compression codec +- __huf_decompress.c__ : implements decompression codec diff --git a/src/fse/bitstream.h b/src/fse/bitstream.h index 2f91460c..cfe3612d 100644 --- a/src/fse/bitstream.h +++ b/src/fse/bitstream.h @@ -1,458 +1,458 @@ -/* ****************************************************************** - bitstream - Part of FSE library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ -#ifndef BITSTREAM_H_MODULE -#define BITSTREAM_H_MODULE - -#if defined (__cplusplus) -extern "C" { -#endif - -/* -* This API consists of small unitary functions, which must be inlined for best performance. -* Since link-time-optimization is not available for all compilers, -* these functions are defined into a .h to be included. -*/ - -/*-**************************************** -* Dependencies -******************************************/ -#include "mem.h" /* unaligned access routines */ -#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */ -#include "error_private.h" /* error codes and messages */ - - -/*========================================= -* Target specific -=========================================*/ -#if defined(__BMI__) && defined(__GNUC__) -# include /* support for bextr (experimental) */ -#endif - -#define STREAM_ACCUMULATOR_MIN_32 25 -#define STREAM_ACCUMULATOR_MIN_64 57 -#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) - - -/*-****************************************** -* bitStream encoding API (write forward) -********************************************/ -/* bitStream can mix input from multiple sources. - * A critical property of these streams is that they encode and decode in **reverse** direction. - * So the first bit sequence you add will be the last to be read, like a LIFO stack. - */ -typedef struct { - size_t bitContainer; - unsigned bitPos; - char* startPtr; - char* ptr; - char* endPtr; -} BIT_CStream_t; - -MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); -MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits); -MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC); -MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); - -/* Start with initCStream, providing the size of buffer to write into. -* bitStream will never write outside of this buffer. -* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. -* -* bits are first added to a local register. -* Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems. -* Writing data into memory is an explicit operation, performed by the flushBits function. -* Hence keep track how many bits are potentially stored into local register to avoid register overflow. -* After a flushBits, a maximum of 7 bits might still be stored into local register. -* -* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers. -* -* Last operation is to close the bitStream. -* The function returns the final size of CStream in bytes. -* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) -*/ - - -/*-******************************************** -* bitStream decoding API (read backward) -**********************************************/ -typedef struct { - size_t bitContainer; - unsigned bitsConsumed; - const char* ptr; - const char* start; - const char* limitPtr; -} BIT_DStream_t; - -typedef enum { BIT_DStream_unfinished = 0, - BIT_DStream_endOfBuffer = 1, - BIT_DStream_completed = 2, - BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */ - /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ - -MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); -MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); -MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); -MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); - - -/* Start by invoking BIT_initDStream(). -* A chunk of the bitStream is then stored into a local register. -* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). -* You can then retrieve bitFields stored into the local register, **in reverse order**. -* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. -* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. -* Otherwise, it can be less than that, so proceed accordingly. -* Checking if DStream has reached its end can be performed with BIT_endOfDStream(). -*/ - - -/*-**************************************** -* unsafe API -******************************************/ -MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits); -/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ - -MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); -/* unsafe version; does not check buffer overflow */ - -MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); -/* faster, but works only if nbBits >= 1 */ - - - -/*-************************************************************** -* Internal functions -****************************************************************/ -MEM_STATIC unsigned BIT_highbit32 (U32 val) -{ - assert(val != 0); - { -# if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - _BitScanReverse ( &r, val ); - return (unsigned) r; -# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ - return 31 - __builtin_clz (val); -# else /* Software version */ - static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, - 11, 14, 16, 18, 22, 25, 3, 30, - 8, 12, 20, 28, 15, 17, 24, 7, - 19, 27, 23, 6, 26, 5, 4, 31 }; - U32 v = val; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; -# endif - } -} - -/*===== Local Constants =====*/ -static const unsigned BIT_mask[] = { - 0, 1, 3, 7, 0xF, 0x1F, - 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, - 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, - 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, - 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, - 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */ -#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0])) - -/*-************************************************************** -* bitStream encoding -****************************************************************/ -/*! BIT_initCStream() : - * `dstCapacity` must be > sizeof(size_t) - * @return : 0 if success, - * otherwise an error code (can be tested using ERR_isError()) */ -MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, - void* startPtr, size_t dstCapacity) -{ - bitC->bitContainer = 0; - bitC->bitPos = 0; - bitC->startPtr = (char*)startPtr; - bitC->ptr = bitC->startPtr; - bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer); - if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall); - return 0; -} - -/*! BIT_addBits() : - * can add up to 31 bits into `bitC`. - * Note : does not check for register overflow ! */ -MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, - size_t value, unsigned nbBits) -{ - MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32); - assert(nbBits < BIT_MASK_SIZE); - assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); - bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; - bitC->bitPos += nbBits; -} - -/*! BIT_addBitsFast() : - * works only if `value` is _clean_, - * meaning all high bits above nbBits are 0 */ -MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, - size_t value, unsigned nbBits) -{ - assert((value>>nbBits) == 0); - assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); - bitC->bitContainer |= value << bitC->bitPos; - bitC->bitPos += nbBits; -} - -/*! BIT_flushBitsFast() : - * assumption : bitContainer has not overflowed - * unsafe version; does not check buffer overflow */ -MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) -{ - size_t const nbBytes = bitC->bitPos >> 3; - assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); - MEM_writeLEST(bitC->ptr, bitC->bitContainer); - bitC->ptr += nbBytes; - assert(bitC->ptr <= bitC->endPtr); - bitC->bitPos &= 7; - bitC->bitContainer >>= nbBytes*8; -} - -/*! BIT_flushBits() : - * assumption : bitContainer has not overflowed - * safe version; check for buffer overflow, and prevents it. - * note : does not signal buffer overflow. - * overflow will be revealed later on using BIT_closeCStream() */ -MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) -{ - size_t const nbBytes = bitC->bitPos >> 3; - assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); - MEM_writeLEST(bitC->ptr, bitC->bitContainer); - bitC->ptr += nbBytes; - if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; - bitC->bitPos &= 7; - bitC->bitContainer >>= nbBytes*8; -} - -/*! BIT_closeCStream() : - * @return : size of CStream, in bytes, - * or 0 if it could not fit into dstBuffer */ -MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) -{ - BIT_addBitsFast(bitC, 1, 1); /* endMark */ - BIT_flushBits(bitC); - if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ - return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); -} - - -/*-******************************************************** -* bitStream decoding -**********************************************************/ -/*! BIT_initDStream() : - * Initialize a BIT_DStream_t. - * `bitD` : a pointer to an already allocated BIT_DStream_t structure. - * `srcSize` must be the *exact* size of the bitStream, in bytes. - * @return : size of stream (== srcSize), or an errorCode if a problem is detected - */ -MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) -{ - if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } - - bitD->start = (const char*)srcBuffer; - bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer); - - if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ - bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); - bitD->bitContainer = MEM_readLEST(bitD->ptr); - { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; - bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ - if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } - } else { - bitD->ptr = bitD->start; - bitD->bitContainer = *(const BYTE*)(bitD->start); - switch(srcSize) - { - case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); - /* fall-through */ - - case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); - /* fall-through */ - - case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); - /* fall-through */ - - case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; - /* fall-through */ - - case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; - /* fall-through */ - - case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; - /* fall-through */ - - default: break; - } - { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; - bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; - if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */ - } - bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; - } - - return srcSize; -} - -MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) -{ - return bitContainer >> start; -} - -MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) -{ -#if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */ -# if defined(__x86_64__) - if (sizeof(bitContainer)==8) - return _bextr_u64(bitContainer, start, nbBits); - else -# endif - return _bextr_u32(bitContainer, start, nbBits); -#else - assert(nbBits < BIT_MASK_SIZE); - return (bitContainer >> start) & BIT_mask[nbBits]; -#endif -} - -MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) -{ - assert(nbBits < BIT_MASK_SIZE); - return bitContainer & BIT_mask[nbBits]; -} - -/*! BIT_lookBits() : - * Provides next n bits from local register. - * local register is not modified. - * On 32-bits, maxNbBits==24. - * On 64-bits, maxNbBits==56. - * @return : value extracted */ -MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) -{ -#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */ - return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); -#else - U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; - return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask); -#endif -} - -/*! BIT_lookBitsFast() : - * unsafe version; only works if nbBits >= 1 */ -MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) -{ - U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; - assert(nbBits >= 1); - return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); -} - -MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) -{ - bitD->bitsConsumed += nbBits; -} - -/*! BIT_readBits() : - * Read (consume) next n bits from local register and update. - * Pay attention to not read more than nbBits contained into local register. - * @return : extracted value. */ -MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits) -{ - size_t const value = BIT_lookBits(bitD, nbBits); - BIT_skipBits(bitD, nbBits); - return value; -} - -/*! BIT_readBitsFast() : - * unsafe version; only works only if nbBits >= 1 */ -MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) -{ - size_t const value = BIT_lookBitsFast(bitD, nbBits); - assert(nbBits >= 1); - BIT_skipBits(bitD, nbBits); - return value; -} - -/*! BIT_reloadDStream() : - * Refill `bitD` from buffer previously set in BIT_initDStream() . - * This function is safe, it guarantees it will not read beyond src buffer. - * @return : status of `BIT_DStream_t` internal register. - * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ -MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) -{ - if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */ - return BIT_DStream_overflow; - - if (bitD->ptr >= bitD->limitPtr) { - bitD->ptr -= bitD->bitsConsumed >> 3; - bitD->bitsConsumed &= 7; - bitD->bitContainer = MEM_readLEST(bitD->ptr); - return BIT_DStream_unfinished; - } - if (bitD->ptr == bitD->start) { - if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; - return BIT_DStream_completed; - } - /* start < ptr < limitPtr */ - { U32 nbBytes = bitD->bitsConsumed >> 3; - BIT_DStream_status result = BIT_DStream_unfinished; - if (bitD->ptr - nbBytes < bitD->start) { - nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ - result = BIT_DStream_endOfBuffer; - } - bitD->ptr -= nbBytes; - bitD->bitsConsumed -= nbBytes*8; - bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */ - return result; - } -} - -/*! BIT_endOfDStream() : - * @return : 1 if DStream has _exactly_ reached its end (all bits consumed). - */ -MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) -{ - return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); -} - -#if defined (__cplusplus) -} -#endif - -#endif /* BITSTREAM_H_MODULE */ +/* ****************************************************************** + bitstream + Part of FSE library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ +#ifndef BITSTREAM_H_MODULE +#define BITSTREAM_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + +/* +* This API consists of small unitary functions, which must be inlined for best performance. +* Since link-time-optimization is not available for all compilers, +* these functions are defined into a .h to be included. +*/ + +/*-**************************************** +* Dependencies +******************************************/ +#include "mem.h" /* unaligned access routines */ +#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */ +#include "error_private.h" /* error codes and messages */ + + +/*========================================= +* Target specific +=========================================*/ +#if defined(__BMI__) && defined(__GNUC__) +# include /* support for bextr (experimental) */ +#endif + +#define STREAM_ACCUMULATOR_MIN_32 25 +#define STREAM_ACCUMULATOR_MIN_64 57 +#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) + + +/*-****************************************** +* bitStream encoding API (write forward) +********************************************/ +/* bitStream can mix input from multiple sources. + * A critical property of these streams is that they encode and decode in **reverse** direction. + * So the first bit sequence you add will be the last to be read, like a LIFO stack. + */ +typedef struct { + size_t bitContainer; + unsigned bitPos; + char* startPtr; + char* ptr; + char* endPtr; +} BIT_CStream_t; + +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits); +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC); +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); + +/* Start with initCStream, providing the size of buffer to write into. +* bitStream will never write outside of this buffer. +* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. +* +* bits are first added to a local register. +* Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems. +* Writing data into memory is an explicit operation, performed by the flushBits function. +* Hence keep track how many bits are potentially stored into local register to avoid register overflow. +* After a flushBits, a maximum of 7 bits might still be stored into local register. +* +* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers. +* +* Last operation is to close the bitStream. +* The function returns the final size of CStream in bytes. +* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) +*/ + + +/*-******************************************** +* bitStream decoding API (read backward) +**********************************************/ +typedef struct { + size_t bitContainer; + unsigned bitsConsumed; + const char* ptr; + const char* start; + const char* limitPtr; +} BIT_DStream_t; + +typedef enum { BIT_DStream_unfinished = 0, + BIT_DStream_endOfBuffer = 1, + BIT_DStream_completed = 2, + BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */ + /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ + +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); +MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); + + +/* Start by invoking BIT_initDStream(). +* A chunk of the bitStream is then stored into a local register. +* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). +* You can then retrieve bitFields stored into the local register, **in reverse order**. +* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. +* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. +* Otherwise, it can be less than that, so proceed accordingly. +* Checking if DStream has reached its end can be performed with BIT_endOfDStream(). +*/ + + +/*-**************************************** +* unsafe API +******************************************/ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits); +/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ + +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); +/* unsafe version; does not check buffer overflow */ + +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); +/* faster, but works only if nbBits >= 1 */ + + + +/*-************************************************************** +* Internal functions +****************************************************************/ +MEM_STATIC unsigned BIT_highbit32 (U32 val) +{ + assert(val != 0); + { +# if defined(_MSC_VER) /* Visual */ + unsigned long r=0; + _BitScanReverse ( &r, val ); + return (unsigned) r; +# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ + return 31 - __builtin_clz (val); +# else /* Software version */ + static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31 }; + U32 v = val; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; +# endif + } +} + +/*===== Local Constants =====*/ +static const unsigned BIT_mask[] = { + 0, 1, 3, 7, 0xF, 0x1F, + 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, + 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, + 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, + 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */ +#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0])) + +/*-************************************************************** +* bitStream encoding +****************************************************************/ +/*! BIT_initCStream() : + * `dstCapacity` must be > sizeof(size_t) + * @return : 0 if success, + * otherwise an error code (can be tested using ERR_isError()) */ +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, + void* startPtr, size_t dstCapacity) +{ + bitC->bitContainer = 0; + bitC->bitPos = 0; + bitC->startPtr = (char*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer); + if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall); + return 0; +} + +/*! BIT_addBits() : + * can add up to 31 bits into `bitC`. + * Note : does not check for register overflow ! */ +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, + size_t value, unsigned nbBits) +{ + MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32); + assert(nbBits < BIT_MASK_SIZE); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_addBitsFast() : + * works only if `value` is _clean_, + * meaning all high bits above nbBits are 0 */ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, + size_t value, unsigned nbBits) +{ + assert((value>>nbBits) == 0); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= value << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_flushBitsFast() : + * assumption : bitContainer has not overflowed + * unsafe version; does not check buffer overflow */ +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + assert(bitC->ptr <= bitC->endPtr); + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_flushBits() : + * assumption : bitContainer has not overflowed + * safe version; check for buffer overflow, and prevents it. + * note : does not signal buffer overflow. + * overflow will be revealed later on using BIT_closeCStream() */ +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_closeCStream() : + * @return : size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) +{ + BIT_addBitsFast(bitC, 1, 1); /* endMark */ + BIT_flushBits(bitC); + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); +} + + +/*-******************************************************** +* bitStream decoding +**********************************************************/ +/*! BIT_initDStream() : + * Initialize a BIT_DStream_t. + * `bitD` : a pointer to an already allocated BIT_DStream_t structure. + * `srcSize` must be the *exact* size of the bitStream, in bytes. + * @return : size of stream (== srcSize), or an errorCode if a problem is detected + */ +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) +{ + if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } + + bitD->start = (const char*)srcBuffer; + bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer); + + if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ + bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); + bitD->bitContainer = MEM_readLEST(bitD->ptr); + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ + if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } + } else { + bitD->ptr = bitD->start; + bitD->bitContainer = *(const BYTE*)(bitD->start); + switch(srcSize) + { + case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); + /* fall-through */ + + case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); + /* fall-through */ + + case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); + /* fall-through */ + + case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; + /* fall-through */ + + case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; + /* fall-through */ + + case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; + /* fall-through */ + + default: break; + } + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; + if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */ + } + bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; + } + + return srcSize; +} + +MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) +{ + return bitContainer >> start; +} + +MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) +{ +#if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */ +# if defined(__x86_64__) + if (sizeof(bitContainer)==8) + return _bextr_u64(bitContainer, start, nbBits); + else +# endif + return _bextr_u32(bitContainer, start, nbBits); +#else + assert(nbBits < BIT_MASK_SIZE); + return (bitContainer >> start) & BIT_mask[nbBits]; +#endif +} + +MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) +{ + assert(nbBits < BIT_MASK_SIZE); + return bitContainer & BIT_mask[nbBits]; +} + +/*! BIT_lookBits() : + * Provides next n bits from local register. + * local register is not modified. + * On 32-bits, maxNbBits==24. + * On 64-bits, maxNbBits==56. + * @return : value extracted */ +MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) +{ +#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */ + return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); +#else + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask); +#endif +} + +/*! BIT_lookBitsFast() : + * unsafe version; only works if nbBits >= 1 */ +MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) +{ + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + assert(nbBits >= 1); + return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); +} + +MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +{ + bitD->bitsConsumed += nbBits; +} + +/*! BIT_readBits() : + * Read (consume) next n bits from local register and update. + * Pay attention to not read more than nbBits contained into local register. + * @return : extracted value. */ +MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits) +{ + size_t const value = BIT_lookBits(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_readBitsFast() : + * unsafe version; only works only if nbBits >= 1 */ +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) +{ + size_t const value = BIT_lookBitsFast(bitD, nbBits); + assert(nbBits >= 1); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_reloadDStream() : + * Refill `bitD` from buffer previously set in BIT_initDStream() . + * This function is safe, it guarantees it will not read beyond src buffer. + * @return : status of `BIT_DStream_t` internal register. + * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) +{ + if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */ + return BIT_DStream_overflow; + + if (bitD->ptr >= bitD->limitPtr) { + bitD->ptr -= bitD->bitsConsumed >> 3; + bitD->bitsConsumed &= 7; + bitD->bitContainer = MEM_readLEST(bitD->ptr); + return BIT_DStream_unfinished; + } + if (bitD->ptr == bitD->start) { + if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; + return BIT_DStream_completed; + } + /* start < ptr < limitPtr */ + { U32 nbBytes = bitD->bitsConsumed >> 3; + BIT_DStream_status result = BIT_DStream_unfinished; + if (bitD->ptr - nbBytes < bitD->start) { + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ + result = BIT_DStream_endOfBuffer; + } + bitD->ptr -= nbBytes; + bitD->bitsConsumed -= nbBytes*8; + bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */ + return result; + } +} + +/*! BIT_endOfDStream() : + * @return : 1 if DStream has _exactly_ reached its end (all bits consumed). + */ +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) +{ + return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); +} + +#if defined (__cplusplus) +} +#endif + +#endif /* BITSTREAM_H_MODULE */ diff --git a/src/fse/compiler.h b/src/fse/compiler.h index 366ed2b4..8f50228e 100644 --- a/src/fse/compiler.h +++ b/src/fse/compiler.h @@ -1,111 +1,111 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -#ifndef ZSTD_COMPILER_H -#define ZSTD_COMPILER_H - -/*-******************************************************* -* Compiler specifics -*********************************************************/ -/* force inlining */ -#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# define INLINE_KEYWORD inline -#else -# define INLINE_KEYWORD -#endif - -#if defined(__GNUC__) -# define FORCE_INLINE_ATTR __attribute__((always_inline)) -#elif defined(_MSC_VER) -# define FORCE_INLINE_ATTR __forceinline -#else -# define FORCE_INLINE_ATTR -#endif - -/** - * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant - * parameters. They must be inlined for the compiler to elimininate the constant - * branches. - */ -#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR -/** - * HINT_INLINE is used to help the compiler generate better code. It is *not* - * used for "templates", so it can be tweaked based on the compilers - * performance. - * - * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the - * always_inline attribute. - * - * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline - * attribute. - */ -#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5 -# define HINT_INLINE static INLINE_KEYWORD -#else -# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR -#endif - -/* force no inlining */ -#ifdef _MSC_VER -# define FORCE_NOINLINE static __declspec(noinline) -#else -# ifdef __GNUC__ -# define FORCE_NOINLINE static __attribute__((__noinline__)) -# else -# define FORCE_NOINLINE static -# endif -#endif - -/* target attribute */ -#ifndef __has_attribute - #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif -#if defined(__GNUC__) -# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) -#else -# define TARGET_ATTRIBUTE(target) -#endif - -/* Enable runtime BMI2 dispatch based on the CPU. - * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. - */ -#ifndef DYNAMIC_BMI2 - #if ((defined(__clang__) && __has_attribute(__target__)) \ - || (defined(__GNUC__) \ - && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ - && (defined(__x86_64__) || defined(_M_X86)) \ - && !defined(__BMI2__) - # define DYNAMIC_BMI2 1 - #else - # define DYNAMIC_BMI2 0 - #endif -#endif - -/* prefetch */ -#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ -# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ -# define PREFETCH(ptr) _mm_prefetch((const char*)ptr, _MM_HINT_T0) -#elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) -# define PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0) -#else -# define PREFETCH(ptr) /* disabled */ -#endif - -/* disable warnings */ -#ifdef _MSC_VER /* Visual Studio */ -# include /* For Visual 2005 */ -# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */ -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ -# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ -# pragma warning(disable : 4324) /* disable: C4324: padded structure */ -#endif - -#endif /* ZSTD_COMPILER_H */ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPILER_H +#define ZSTD_COMPILER_H + +/*-******************************************************* +* Compiler specifics +*********************************************************/ +/* force inlining */ +#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# define INLINE_KEYWORD inline +#else +# define INLINE_KEYWORD +#endif + +#if defined(__GNUC__) +# define FORCE_INLINE_ATTR __attribute__((always_inline)) +#elif defined(_MSC_VER) +# define FORCE_INLINE_ATTR __forceinline +#else +# define FORCE_INLINE_ATTR +#endif + +/** + * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant + * parameters. They must be inlined for the compiler to elimininate the constant + * branches. + */ +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR +/** + * HINT_INLINE is used to help the compiler generate better code. It is *not* + * used for "templates", so it can be tweaked based on the compilers + * performance. + * + * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the + * always_inline attribute. + * + * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline + * attribute. + */ +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5 +# define HINT_INLINE static INLINE_KEYWORD +#else +# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR +#endif + +/* force no inlining */ +#ifdef _MSC_VER +# define FORCE_NOINLINE static __declspec(noinline) +#else +# ifdef __GNUC__ +# define FORCE_NOINLINE static __attribute__((__noinline__)) +# else +# define FORCE_NOINLINE static +# endif +#endif + +/* target attribute */ +#ifndef __has_attribute + #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif +#if defined(__GNUC__) +# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) +#else +# define TARGET_ATTRIBUTE(target) +#endif + +/* Enable runtime BMI2 dispatch based on the CPU. + * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. + */ +#ifndef DYNAMIC_BMI2 + #if ((defined(__clang__) && __has_attribute(__target__)) \ + || (defined(__GNUC__) \ + && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ + && (defined(__x86_64__) || defined(_M_X86)) \ + && !defined(__BMI2__) + # define DYNAMIC_BMI2 1 + #else + # define DYNAMIC_BMI2 0 + #endif +#endif + +/* prefetch */ +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define PREFETCH(ptr) _mm_prefetch((const char*)ptr, _MM_HINT_T0) +#elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0) +#else +# define PREFETCH(ptr) /* disabled */ +#endif + +/* disable warnings */ +#ifdef _MSC_VER /* Visual Studio */ +# include /* For Visual 2005 */ +# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ +# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ +# pragma warning(disable : 4324) /* disable: C4324: padded structure */ +#endif + +#endif /* ZSTD_COMPILER_H */ diff --git a/src/fse/debug.c b/src/fse/debug.c index 3ebdd1cb..66378e6d 100644 --- a/src/fse/debug.c +++ b/src/fse/debug.c @@ -1,44 +1,44 @@ -/* ****************************************************************** - debug - Part of FSE library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - - -/* - * This module only hosts one global variable - * which can be used to dynamically influence the verbosity of traces, - * such as DEBUGLOG and RAWLOG - */ - -#include "debug.h" - -int g_debuglevel = DEBUGLEVEL; +/* ****************************************************************** + debug + Part of FSE library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + + +/* + * This module only hosts one global variable + * which can be used to dynamically influence the verbosity of traces, + * such as DEBUGLOG and RAWLOG + */ + +#include "debug.h" + +int g_debuglevel = DEBUGLEVEL; diff --git a/src/fse/debug.h b/src/fse/debug.h index 95a3fcab..9ee536b4 100644 --- a/src/fse/debug.h +++ b/src/fse/debug.h @@ -1,121 +1,121 @@ -/* ****************************************************************** - debug - Part of FSE library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - - -/* - * The purpose of this header is to enable debug functions. - * They regroup assert(), DEBUGLOG() and RAWLOG(). - * - * By default, DEBUGLEVEL==0, which means debug is disabled. - * - * Level 1 enables assert() only. - * Starting level 2, traces can be generated and pushed to stderr. - * The higher the level, the more verbose the traces. - * - * It's possible to dynamically adjust level using variable g_debug_level, - * which is only declared if DEBUGLEVEL>=2, - * and is a global variable, not multi-thread protected (use with care) - */ - -#ifndef DEBUG_H_12987983217 -#define DEBUG_H_12987983217 - -#if defined (__cplusplus) -extern "C" { -#endif - - -/* static assert is triggered at compile time, leaving no runtime artefact, - * but can only work with compile-time constants */ -#define DEBUG_STATIC_ASSERT(c) { enum { DEBUG_static_assert = 1/(int)(!!(c)) }; } - - -/* DEBUGLEVEL is expected to be defined externally, - * typically through compiler command line. - * Value must be a number. */ -#ifndef DEBUGLEVEL -# define DEBUGLEVEL 0 -#endif - -/* recommended values for DEBUGLEVEL : - * 0 : no debug, all functions disabled (except DEBUG_STATIC_ASSERT) - * 1 : no display, enables assert() only - * 2 : reserved, for currently active debug path - * 3 : events once per object lifetime (CCtx, CDict, etc.) - * 4 : events once per frame - * 5 : events once per block - * 6 : events once per sequence (verbose) - * 7+: events at every position (*very* verbose) - * - * It's generally inconvenient to output traces > 5. - * In which case, it's possible to selectively enable higher verbosity levels - * by modifying g_debug_level. - */ - -#if (DEBUGLEVEL>=1) -# include -#else -# ifndef assert /* assert may be already defined, due to prior #include */ -# define assert(condition) ((void)0) /* disable assert (default) */ -# endif -#endif - -#if (DEBUGLEVEL>=2) -# include -extern int g_debuglevel; /* here, this variable is only declared, - it actually lives in debug.c, - and is shared by the whole process. - It's typically used to enable very verbose levels - on selective conditions (such as position in src) */ - -# define RAWLOG(l, ...) { \ - if (l<=g_debuglevel) { \ - fprintf(stderr, __VA_ARGS__); \ - } } -# define DEBUGLOG(l, ...) { \ - if (l<=g_debuglevel) { \ - fprintf(stderr, __FILE__ ": " __VA_ARGS__); \ - fprintf(stderr, " \n"); \ - } } -#else -# define RAWLOG(l, ...) {} /* disabled */ -# define DEBUGLOG(l, ...) {} /* disabled */ -#endif - - -#if defined (__cplusplus) -} -#endif - -#endif /* DEBUG_H_12987983217 */ +/* ****************************************************************** + debug + Part of FSE library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + + +/* + * The purpose of this header is to enable debug functions. + * They regroup assert(), DEBUGLOG() and RAWLOG(). + * + * By default, DEBUGLEVEL==0, which means debug is disabled. + * + * Level 1 enables assert() only. + * Starting level 2, traces can be generated and pushed to stderr. + * The higher the level, the more verbose the traces. + * + * It's possible to dynamically adjust level using variable g_debug_level, + * which is only declared if DEBUGLEVEL>=2, + * and is a global variable, not multi-thread protected (use with care) + */ + +#ifndef DEBUG_H_12987983217 +#define DEBUG_H_12987983217 + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* static assert is triggered at compile time, leaving no runtime artefact, + * but can only work with compile-time constants */ +#define DEBUG_STATIC_ASSERT(c) { enum { DEBUG_static_assert = 1/(int)(!!(c)) }; } + + +/* DEBUGLEVEL is expected to be defined externally, + * typically through compiler command line. + * Value must be a number. */ +#ifndef DEBUGLEVEL +# define DEBUGLEVEL 0 +#endif + +/* recommended values for DEBUGLEVEL : + * 0 : no debug, all functions disabled (except DEBUG_STATIC_ASSERT) + * 1 : no display, enables assert() only + * 2 : reserved, for currently active debug path + * 3 : events once per object lifetime (CCtx, CDict, etc.) + * 4 : events once per frame + * 5 : events once per block + * 6 : events once per sequence (verbose) + * 7+: events at every position (*very* verbose) + * + * It's generally inconvenient to output traces > 5. + * In which case, it's possible to selectively enable higher verbosity levels + * by modifying g_debug_level. + */ + +#if (DEBUGLEVEL>=1) +# include +#else +# ifndef assert /* assert may be already defined, due to prior #include */ +# define assert(condition) ((void)0) /* disable assert (default) */ +# endif +#endif + +#if (DEBUGLEVEL>=2) +# include +extern int g_debuglevel; /* here, this variable is only declared, + it actually lives in debug.c, + and is shared by the whole process. + It's typically used to enable very verbose levels + on selective conditions (such as position in src) */ + +# define RAWLOG(l, ...) { \ + if (l<=g_debuglevel) { \ + fprintf(stderr, __VA_ARGS__); \ + } } +# define DEBUGLOG(l, ...) { \ + if (l<=g_debuglevel) { \ + fprintf(stderr, __FILE__ ": " __VA_ARGS__); \ + fprintf(stderr, " \n"); \ + } } +#else +# define RAWLOG(l, ...) {} /* disabled */ +# define DEBUGLOG(l, ...) {} /* disabled */ +#endif + + +#if defined (__cplusplus) +} +#endif + +#endif /* DEBUG_H_12987983217 */ diff --git a/src/fse/entropy_common.c b/src/fse/entropy_common.c index 08d6e713..226ee05a 100644 --- a/src/fse/entropy_common.c +++ b/src/fse/entropy_common.c @@ -1,240 +1,240 @@ -/* - Common functions for Finite State Entropy project - Copyright (C) 2016-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy - - Public forum : https://groups.google.com/forum/#!forum/lz4c -*************************************************************************** */ - -/* ************************************* -* Dependencies -***************************************/ -#include "mem.h" -#include "error_private.h" /* ERR_*, ERROR */ -#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ -#include "fse.h" -#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */ -#include "huf.h" - - -/*=== Version ===*/ -unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } - - -/*=== Error Management ===*/ -unsigned FSE_isError(size_t code) { return ERR_isError(code); } -const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } - -unsigned HUF_isError(size_t code) { return ERR_isError(code); } -const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } - -/*-************************************************************** -* FSE NCount decoding -****************************************************************/ -size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, - const void* headerBuffer, size_t hbSize) -{ - const BYTE* const istart = (const BYTE*) headerBuffer; - const BYTE* const iend = istart + hbSize; - const BYTE* ip = istart; - int nbBits; - int remaining; - int threshold; - U32 bitStream; - int bitCount; - unsigned charnum = 0; - int previous0 = 0; - - DEBUGLOG(5, "FSE_readNCount"); - - if (hbSize < 4) { - /* This function only works when hbSize >= 4 */ - char buffer[4]; - memset(buffer, 0, sizeof(buffer)); - memcpy(buffer, headerBuffer, hbSize); - { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, - buffer, sizeof(buffer)); - if (FSE_isError(countSize)) return countSize; - if (countSize > hbSize) return ERROR(corruption_detected); - return countSize; - } } - assert(hbSize >= 4); - - bitStream = MEM_readLE32(ip); - nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ - if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); - bitStream >>= 4; - bitCount = 4; - *tableLogPtr = nbBits; - remaining = (1<1) & (charnum<=*maxSVPtr)) { - if (previous0) { - unsigned n0 = charnum; - while ((bitStream & 0xFFFF) == 0xFFFF) { - n0 += 24; - if (ip < iend-5) { - ip += 2; - bitStream = MEM_readLE32(ip) >> bitCount; - } else { - bitStream >>= 16; - bitCount += 16; - } } - while ((bitStream & 3) == 3) { - n0 += 3; - bitStream >>= 2; - bitCount += 2; - } - n0 += bitStream & 3; - bitCount += 2; - if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); - while (charnum < n0) normalizedCounter[charnum++] = 0; - if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { - assert((bitCount >> 3) <= 3); /* For first condition to work */ - ip += bitCount>>3; - bitCount &= 7; - bitStream = MEM_readLE32(ip) >> bitCount; - } else { - bitStream >>= 2; - } } - { int const max = (2*threshold-1) - remaining; - int count; - - if ((bitStream & (threshold-1)) < (U32)max) { - count = bitStream & (threshold-1); - bitCount += nbBits-1; - } else { - count = bitStream & (2*threshold-1); - if (count >= threshold) count -= max; - bitCount += nbBits; - } - - count--; /* extra accuracy */ - remaining -= count < 0 ? -count : count; /* -1 means +1 */ - normalizedCounter[charnum++] = (short)count; - previous0 = !count; - while (remaining < threshold) { - nbBits--; - threshold >>= 1; - } - - if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { - ip += bitCount>>3; - bitCount &= 7; - } else { - bitCount -= (int)(8 * (iend - 4 - ip)); - ip = iend - 4; - } - bitStream = MEM_readLE32(ip) >> (bitCount & 31); - } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */ - if (remaining != 1) return ERROR(corruption_detected); - if (bitCount > 32) return ERROR(corruption_detected); - /* zeroise the rest */ - { unsigned symbNb = charnum; - for (symbNb=charnum; symbNb <= *maxSVPtr; symbNb++) - normalizedCounter[symbNb] = 0; - } - *maxSVPtr = charnum-1; - - ip += (bitCount+7)>>3; - return ip-istart; -} - - -/*! HUF_readStats() : - Read compact Huffman tree, saved by HUF_writeCTable(). - `huffWeight` is destination buffer. - `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. - @return : size read from `src` , or an error Code . - Note : Needed by HUF_readCTable() and HUF_readDTableX?() . -*/ -size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, - U32* nbSymbolsPtr, U32* tableLogPtr, - const void* src, size_t srcSize) -{ - U32 weightTotal; - const BYTE* ip = (const BYTE*) src; - size_t iSize; - size_t oSize; - - if (!srcSize) return ERROR(srcSize_wrong); - iSize = ip[0]; - /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ - - if (iSize >= 128) { /* special header */ - oSize = iSize - 127; - iSize = ((oSize+1)/2); - if (iSize+1 > srcSize) return ERROR(srcSize_wrong); - if (oSize >= hwSize) return ERROR(corruption_detected); - ip += 1; - { U32 n; - for (n=0; n> 4; - huffWeight[n+1] = ip[n/2] & 15; - } } } - else { /* header compressed with FSE (normal case) */ - FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ - if (iSize+1 > srcSize) return ERROR(srcSize_wrong); - oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ - if (FSE_isError(oSize)) return oSize; - } - - /* collect weight stats */ - memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); - weightTotal = 0; - { U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected); - rankStats[huffWeight[n]]++; - weightTotal += (1 << huffWeight[n]) >> 1; - } } - if (weightTotal == 0) return ERROR(corruption_detected); - - /* get last non-null symbol weight (implied, total must be 2^n) */ - { U32 const tableLog = BIT_highbit32(weightTotal) + 1; - if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); - *tableLogPtr = tableLog; - /* determine last weight */ - { U32 const total = 1 << tableLog; - U32 const rest = total - weightTotal; - U32 const verif = 1 << BIT_highbit32(rest); - U32 const lastWeight = BIT_highbit32(rest) + 1; - if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ - huffWeight[oSize] = (BYTE)lastWeight; - rankStats[lastWeight]++; - } } - - /* check tree construction validity */ - if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ - - /* results */ - *nbSymbolsPtr = (U32)(oSize+1); - return iSize+1; -} +/* + Common functions for Finite State Entropy project + Copyright (C) 2016-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +*************************************************************************** */ + +/* ************************************* +* Dependencies +***************************************/ +#include "mem.h" +#include "error_private.h" /* ERR_*, ERROR */ +#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ +#include "fse.h" +#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */ +#include "huf.h" + + +/*=== Version ===*/ +unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } + + +/*=== Error Management ===*/ +unsigned FSE_isError(size_t code) { return ERR_isError(code); } +const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } + +unsigned HUF_isError(size_t code) { return ERR_isError(code); } +const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } + +/*-************************************************************** +* FSE NCount decoding +****************************************************************/ +size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + const BYTE* const istart = (const BYTE*) headerBuffer; + const BYTE* const iend = istart + hbSize; + const BYTE* ip = istart; + int nbBits; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + int previous0 = 0; + + DEBUGLOG(5, "FSE_readNCount"); + + if (hbSize < 4) { + /* This function only works when hbSize >= 4 */ + char buffer[4]; + memset(buffer, 0, sizeof(buffer)); + memcpy(buffer, headerBuffer, hbSize); + { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, + buffer, sizeof(buffer)); + if (FSE_isError(countSize)) return countSize; + if (countSize > hbSize) return ERROR(corruption_detected); + return countSize; + } } + assert(hbSize >= 4); + + bitStream = MEM_readLE32(ip); + nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ + if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); + bitStream >>= 4; + bitCount = 4; + *tableLogPtr = nbBits; + remaining = (1<1) & (charnum<=*maxSVPtr)) { + if (previous0) { + unsigned n0 = charnum; + while ((bitStream & 0xFFFF) == 0xFFFF) { + n0 += 24; + if (ip < iend-5) { + ip += 2; + bitStream = MEM_readLE32(ip) >> bitCount; + } else { + bitStream >>= 16; + bitCount += 16; + } } + while ((bitStream & 3) == 3) { + n0 += 3; + bitStream >>= 2; + bitCount += 2; + } + n0 += bitStream & 3; + bitCount += 2; + if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); + while (charnum < n0) normalizedCounter[charnum++] = 0; + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + assert((bitCount >> 3) <= 3); /* For first condition to work */ + ip += bitCount>>3; + bitCount &= 7; + bitStream = MEM_readLE32(ip) >> bitCount; + } else { + bitStream >>= 2; + } } + { int const max = (2*threshold-1) - remaining; + int count; + + if ((bitStream & (threshold-1)) < (U32)max) { + count = bitStream & (threshold-1); + bitCount += nbBits-1; + } else { + count = bitStream & (2*threshold-1); + if (count >= threshold) count -= max; + bitCount += nbBits; + } + + count--; /* extra accuracy */ + remaining -= count < 0 ? -count : count; /* -1 means +1 */ + normalizedCounter[charnum++] = (short)count; + previous0 = !count; + while (remaining < threshold) { + nbBits--; + threshold >>= 1; + } + + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> (bitCount & 31); + } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */ + if (remaining != 1) return ERROR(corruption_detected); + if (bitCount > 32) return ERROR(corruption_detected); + /* zeroise the rest */ + { unsigned symbNb = charnum; + for (symbNb=charnum; symbNb <= *maxSVPtr; symbNb++) + normalizedCounter[symbNb] = 0; + } + *maxSVPtr = charnum-1; + + ip += (bitCount+7)>>3; + return ip-istart; +} + + +/*! HUF_readStats() : + Read compact Huffman tree, saved by HUF_writeCTable(). + `huffWeight` is destination buffer. + `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableX?() . +*/ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize) +{ + U32 weightTotal; + const BYTE* ip = (const BYTE*) src; + size_t iSize; + size_t oSize; + + if (!srcSize) return ERROR(srcSize_wrong); + iSize = ip[0]; + /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ + + if (iSize >= 128) { /* special header */ + oSize = iSize - 127; + iSize = ((oSize+1)/2); + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + if (oSize >= hwSize) return ERROR(corruption_detected); + ip += 1; + { U32 n; + for (n=0; n> 4; + huffWeight[n+1] = ip[n/2] & 15; + } } } + else { /* header compressed with FSE (normal case) */ + FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ + if (FSE_isError(oSize)) return oSize; + } + + /* collect weight stats */ + memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); + weightTotal = 0; + { U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected); + rankStats[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } } + if (weightTotal == 0) return ERROR(corruption_detected); + + /* get last non-null symbol weight (implied, total must be 2^n) */ + { U32 const tableLog = BIT_highbit32(weightTotal) + 1; + if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); + *tableLogPtr = tableLog; + /* determine last weight */ + { U32 const total = 1 << tableLog; + U32 const rest = total - weightTotal; + U32 const verif = 1 << BIT_highbit32(rest); + U32 const lastWeight = BIT_highbit32(rest) + 1; + if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankStats[lastWeight]++; + } } + + /* check tree construction validity */ + if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ + + /* results */ + *nbSymbolsPtr = (U32)(oSize+1); + return iSize+1; +} diff --git a/src/fse/error_private.h b/src/fse/error_private.h index 9aac9ba3..5daa7ac0 100644 --- a/src/fse/error_private.h +++ b/src/fse/error_private.h @@ -1,116 +1,116 @@ -/* ****************************************************************** - Error codes and messages - Copyright (C) 2013-2016, Yann Collet - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - Homepage : http://www.zstd.net -****************************************************************** */ -/* Note : this module is expected to remain private, do not expose it */ - -#ifndef ERROR_H_MODULE -#define ERROR_H_MODULE - -#if defined (__cplusplus) -extern "C" { -#endif - - -/* **************************************** -* Dependencies -******************************************/ -#include /* size_t */ -#include "error_public.h" /* enum list */ - - -/* **************************************** -* Compiler-specific -******************************************/ -#if defined(__GNUC__) -# define ERR_STATIC static __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define ERR_STATIC static inline -#elif defined(_MSC_VER) -# define ERR_STATIC static __inline -#else -# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif - - -/*-**************************************** -* Customization (error_public.h) -******************************************/ -typedef FSE_ErrorCode ERR_enum; -#define PREFIX(name) FSE_error_##name - - -/*-**************************************** -* Error codes handling -******************************************/ -#ifdef ERROR -# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */ -#endif -#define ERROR(name) ((size_t)-PREFIX(name)) - -ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } - -ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); } - - -/*-**************************************** -* Error Strings -******************************************/ - -ERR_STATIC const char* ERR_getErrorString(ERR_enum code) -{ - static const char* notErrorCode = "Unspecified error code"; - switch( code ) - { - case PREFIX(no_error): return "No error detected"; - case PREFIX(GENERIC): return "Error (generic)"; - case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; - case PREFIX(srcSize_wrong): return "Src size is incorrect"; - case PREFIX(corruption_detected): return "Corrupted block detected"; - case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; - case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; - case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; - case PREFIX(workSpace_tooSmall): return "workspace buffer is too small"; - case PREFIX(maxCode): - default: return notErrorCode; - } -} - -ERR_STATIC const char* ERR_getErrorName(size_t code) -{ - return ERR_getErrorString(ERR_getErrorCode(code)); -} - -#if defined (__cplusplus) -} -#endif - -#endif /* ERROR_H_MODULE */ +/* ****************************************************************** + Error codes and messages + Copyright (C) 2013-2016, Yann Collet + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - Homepage : http://www.zstd.net +****************************************************************** */ +/* Note : this module is expected to remain private, do not expose it */ + +#ifndef ERROR_H_MODULE +#define ERROR_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* **************************************** +* Dependencies +******************************************/ +#include /* size_t */ +#include "error_public.h" /* enum list */ + + +/* **************************************** +* Compiler-specific +******************************************/ +#if defined(__GNUC__) +# define ERR_STATIC static __attribute__((unused)) +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define ERR_STATIC static inline +#elif defined(_MSC_VER) +# define ERR_STATIC static __inline +#else +# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif + + +/*-**************************************** +* Customization (error_public.h) +******************************************/ +typedef FSE_ErrorCode ERR_enum; +#define PREFIX(name) FSE_error_##name + + +/*-**************************************** +* Error codes handling +******************************************/ +#ifdef ERROR +# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */ +#endif +#define ERROR(name) ((size_t)-PREFIX(name)) + +ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } + +ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); } + + +/*-**************************************** +* Error Strings +******************************************/ + +ERR_STATIC const char* ERR_getErrorString(ERR_enum code) +{ + static const char* notErrorCode = "Unspecified error code"; + switch( code ) + { + case PREFIX(no_error): return "No error detected"; + case PREFIX(GENERIC): return "Error (generic)"; + case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; + case PREFIX(srcSize_wrong): return "Src size is incorrect"; + case PREFIX(corruption_detected): return "Corrupted block detected"; + case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; + case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; + case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; + case PREFIX(workSpace_tooSmall): return "workspace buffer is too small"; + case PREFIX(maxCode): + default: return notErrorCode; + } +} + +ERR_STATIC const char* ERR_getErrorName(size_t code) +{ + return ERR_getErrorString(ERR_getErrorCode(code)); +} + +#if defined (__cplusplus) +} +#endif + +#endif /* ERROR_H_MODULE */ diff --git a/src/fse/error_public.h b/src/fse/error_public.h index 88c8c052..dcd8bf78 100644 --- a/src/fse/error_public.h +++ b/src/fse/error_public.h @@ -1,65 +1,65 @@ -/* ****************************************************************** - Error codes list - Copyright (C) 2016, Yann Collet - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy - - Public forum : https://groups.google.com/forum/#!forum/lz4c -****************************************************************** */ -#ifndef ERROR_PUBLIC_H_MODULE -#define ERROR_PUBLIC_H_MODULE - -#if defined (__cplusplus) -extern "C" { -#endif - - -/* ***************************************** - * error codes list - ******************************************/ -typedef enum { - FSE_error_no_error, - FSE_error_GENERIC, - FSE_error_dstSize_tooSmall, - FSE_error_srcSize_wrong, - FSE_error_corruption_detected, - FSE_error_tableLog_tooLarge, - FSE_error_maxSymbolValue_tooLarge, - FSE_error_maxSymbolValue_tooSmall, - FSE_error_workSpace_tooSmall, - FSE_error_maxCode -} FSE_ErrorCode; - -/* note : compare with size_t function results using FSE_getError() */ - - -#if defined (__cplusplus) -} -#endif - -#endif /* ERROR_PUBLIC_H_MODULE */ +/* ****************************************************************** + Error codes list + Copyright (C) 2016, Yann Collet + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ +#ifndef ERROR_PUBLIC_H_MODULE +#define ERROR_PUBLIC_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* ***************************************** + * error codes list + ******************************************/ +typedef enum { + FSE_error_no_error, + FSE_error_GENERIC, + FSE_error_dstSize_tooSmall, + FSE_error_srcSize_wrong, + FSE_error_corruption_detected, + FSE_error_tableLog_tooLarge, + FSE_error_maxSymbolValue_tooLarge, + FSE_error_maxSymbolValue_tooSmall, + FSE_error_workSpace_tooSmall, + FSE_error_maxCode +} FSE_ErrorCode; + +/* note : compare with size_t function results using FSE_getError() */ + + +#if defined (__cplusplus) +} +#endif + +#endif /* ERROR_PUBLIC_H_MODULE */ diff --git a/src/fse/fse.h b/src/fse/fse.h index f28842c0..d4bd6eb2 100644 --- a/src/fse/fse.h +++ b/src/fse/fse.h @@ -1,708 +1,708 @@ -/* ****************************************************************** - FSE : Finite State Entropy codec - Public Prototypes declaration - Copyright (C) 2013-2016, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - -#if defined (__cplusplus) -extern "C" { -#endif - -#ifndef FSE_H -#define FSE_H - - -/*-***************************************** -* Dependencies -******************************************/ -#include /* size_t, ptrdiff_t */ - - -/*-***************************************** -* FSE_PUBLIC_API : control library symbols visibility -******************************************/ -#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) -# define FSE_PUBLIC_API __attribute__ ((visibility ("default"))) -#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ -# define FSE_PUBLIC_API __declspec(dllexport) -#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) -# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ -#else -# define FSE_PUBLIC_API -#endif - -/*------ Version ------*/ -#define FSE_VERSION_MAJOR 0 -#define FSE_VERSION_MINOR 9 -#define FSE_VERSION_RELEASE 0 - -#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE -#define FSE_QUOTE(str) #str -#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) -#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) - -#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) -FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ - - -/*-**************************************** -* FSE simple functions -******************************************/ -/*! FSE_compress() : - Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'. - 'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize). - @return : size of compressed data (<= dstCapacity). - Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! - if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead. - if FSE_isError(return), compression failed (more details using FSE_getErrorName()) -*/ -FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity, - const void* src, size_t srcSize); - -/*! FSE_decompress(): - Decompress FSE data from buffer 'cSrc', of size 'cSrcSize', - into already allocated destination buffer 'dst', of size 'dstCapacity'. - @return : size of regenerated data (<= maxDstSize), - or an error code, which can be tested using FSE_isError() . - - ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!! - Why ? : making this distinction requires a header. - Header management is intentionally delegated to the user layer, which can better manage special cases. -*/ -FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity, - const void* cSrc, size_t cSrcSize); - - -/*-***************************************** -* Tool functions -******************************************/ -FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ - -/* Error Management */ -FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ -FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ - - -/*-***************************************** -* FSE advanced functions -******************************************/ -/*! FSE_compress2() : - Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog' - Both parameters can be defined as '0' to mean : use default value - @return : size of compressed data - Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!! - if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression. - if FSE_isError(return), it's an error code. -*/ -FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); - - -/*-***************************************** -* FSE detailed API -******************************************/ -/*! -FSE_compress() does the following: -1. count symbol occurrence from source[] into table count[] (see hist.h) -2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog) -3. save normalized counters to memory buffer using writeNCount() -4. build encoding table 'CTable' from normalized counters -5. encode the data stream using encoding table 'CTable' - -FSE_decompress() does the following: -1. read normalized counters with readNCount() -2. build decoding table 'DTable' from normalized counters -3. decode the data stream using decoding table 'DTable' - -The following API allows targeting specific sub-functions for advanced tasks. -For example, it's possible to compress several blocks using the same 'CTable', -or to save and provide normalized distribution using external method. -*/ - -/* *** COMPRESSION *** */ - -/*! FSE_optimalTableLog(): - dynamically downsize 'tableLog' when conditions are met. - It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. - @return : recommended tableLog (necessarily <= 'maxTableLog') */ -FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); - -/*! FSE_normalizeCount(): - normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) - 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). - @return : tableLog, - or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, - const unsigned* count, size_t srcSize, unsigned maxSymbolValue); - -/*! FSE_NCountWriteBound(): - Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. - Typically useful for allocation purpose. */ -FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); - -/*! FSE_writeNCount(): - Compactly save 'normalizedCounter' into 'buffer'. - @return : size of the compressed table, - or an errorCode, which can be tested using FSE_isError(). */ -FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, - const short* normalizedCounter, - unsigned maxSymbolValue, unsigned tableLog); - -/*! Constructor and Destructor of FSE_CTable. - Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ -typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ -FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog); -FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct); - -/*! FSE_buildCTable(): - Builds `ct`, which must be already allocated, using FSE_createCTable(). - @return : 0, or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); - -/*! FSE_compress_usingCTable(): - Compress `src` using `ct` into `dst` which must be already allocated. - @return : size of compressed data (<= `dstCapacity`), - or 0 if compressed data could not fit into `dst`, - or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); - -/*! -Tutorial : ----------- -The first step is to count all symbols. FSE_count() does this job very fast. -Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells. -'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0] -maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value) -FSE_count() will return the number of occurrence of the most frequent symbol. -This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility. -If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). - -The next step is to normalize the frequencies. -FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'. -It also guarantees a minimum of 1 to any Symbol with frequency >= 1. -You can use 'tableLog'==0 to mean "use default tableLog value". -If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(), -which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default"). - -The result of FSE_normalizeCount() will be saved into a table, -called 'normalizedCounter', which is a table of signed short. -'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells. -The return value is tableLog if everything proceeded as expected. -It is 0 if there is a single symbol within distribution. -If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()). - -'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount(). -'buffer' must be already allocated. -For guaranteed success, buffer size must be at least FSE_headerBound(). -The result of the function is the number of bytes written into 'buffer'. -If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small). - -'normalizedCounter' can then be used to create the compression table 'CTable'. -The space required by 'CTable' must be already allocated, using FSE_createCTable(). -You can then use FSE_buildCTable() to fill 'CTable'. -If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()). - -'CTable' can then be used to compress 'src', with FSE_compress_usingCTable(). -Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize' -The function returns the size of compressed data (without header), necessarily <= `dstCapacity`. -If it returns '0', compressed data could not fit into 'dst'. -If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). -*/ - - -/* *** DECOMPRESSION *** */ - -/*! FSE_readNCount(): - Read compactly saved 'normalizedCounter' from 'rBuffer'. - @return : size read from 'rBuffer', - or an errorCode, which can be tested using FSE_isError(). - maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ -FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, - unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, - const void* rBuffer, size_t rBuffSize); - -/*! Constructor and Destructor of FSE_DTable. - Note that its size depends on 'tableLog' */ -typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ -FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog); -FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt); - -/*! FSE_buildDTable(): - Builds 'dt', which must be already allocated, using FSE_createDTable(). - return : 0, or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); - -/*! FSE_decompress_usingDTable(): - Decompress compressed source `cSrc` of size `cSrcSize` using `dt` - into `dst` which must be already allocated. - @return : size of regenerated data (necessarily <= `dstCapacity`), - or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt); - -/*! -Tutorial : ----------- -(Note : these functions only decompress FSE-compressed blocks. - If block is uncompressed, use memcpy() instead - If block is a single repeated byte, use memset() instead ) - -The first step is to obtain the normalized frequencies of symbols. -This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount(). -'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short. -In practice, that means it's necessary to know 'maxSymbolValue' beforehand, -or size the table to handle worst case situations (typically 256). -FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'. -The result of FSE_readNCount() is the number of bytes read from 'rBuffer'. -Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that. -If there is an error, the function will return an error code, which can be tested using FSE_isError(). - -The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'. -This is performed by the function FSE_buildDTable(). -The space required by 'FSE_DTable' must be already allocated using FSE_createDTable(). -If there is an error, the function will return an error code, which can be tested using FSE_isError(). - -`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable(). -`cSrcSize` must be strictly correct, otherwise decompression will fail. -FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`). -If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) -*/ - -#endif /* FSE_H */ - -#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) -#define FSE_H_FSE_STATIC_LINKING_ONLY - -/* *** Dependency *** */ -#include "bitstream.h" - - -/* ***************************************** -* Static allocation -*******************************************/ -/* FSE buffer bounds */ -#define FSE_NCOUNTBOUND 512 -#define FSE_BLOCKBOUND(size) (size + (size>>7)) -#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ - -/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ -#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2)) -#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1< 12) ? (1 << (maxTableLog - 2)) : 1024) ) -size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); - -size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits); -/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ - -size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); -/**< build a fake FSE_CTable, designed to compress always the same symbolValue */ - -/* FSE_buildCTable_wksp() : - * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). - * `wkspSize` must be >= `(1<= BIT_DStream_completed - -When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. -Checking if DStream has reached its end is performed by : - BIT_endOfDStream(&DStream); -Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. - FSE_endOfDState(&DState); -*/ - - -/* ***************************************** -* FSE unsafe API -*******************************************/ -static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); -/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ - - -/* ***************************************** -* Implementation of inlined functions -*******************************************/ -typedef struct { - int deltaFindState; - U32 deltaNbBits; -} FSE_symbolCompressionTransform; /* total 8 bytes */ - -MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) -{ - const void* ptr = ct; - const U16* u16ptr = (const U16*) ptr; - const U32 tableLog = MEM_read16(ptr); - statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2; - statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1)); - statePtr->stateLog = tableLog; -} - - -/*! FSE_initCState2() : -* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) -* uses the smallest state value possible, saving the cost of this symbol */ -MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol) -{ - FSE_initCState(statePtr, ct); - { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; - const U16* stateTable = (const U16*)(statePtr->stateTable); - U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16); - statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; - statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; - } -} - -MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol) -{ - FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; - const U16* const stateTable = (const U16*)(statePtr->stateTable); - U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); - BIT_addBits(bitC, statePtr->value, nbBitsOut); - statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; -} - -MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) -{ - BIT_addBits(bitC, statePtr->value, statePtr->stateLog); - BIT_flushBits(bitC); -} - - -/* FSE_getMaxNbBits() : - * Approximate maximum cost of a symbol, in bits. - * Fractional get rounded up (i.e : a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) - * note 1 : assume symbolValue is valid (<= maxSymbolValue) - * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ -MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue) -{ - const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; - return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16; -} - -/* FSE_bitCost() : - * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits) - * note 1 : assume symbolValue is valid (<= maxSymbolValue) - * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ -MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog) -{ - const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; - U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16; - U32 const threshold = (minNbBits+1) << 16; - assert(tableLog < 16); - assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */ - { U32 const tableSize = 1 << tableLog; - U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize); - U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */ - U32 const bitMultiplier = 1 << accuracyLog; - assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold); - assert(normalizedDeltaFromThreshold <= bitMultiplier); - return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold; - } -} - - -/* ====== Decompression ====== */ - -typedef struct { - U16 tableLog; - U16 fastMode; -} FSE_DTableHeader; /* sizeof U32 */ - -typedef struct -{ - unsigned short newState; - unsigned char symbol; - unsigned char nbBits; -} FSE_decode_t; /* size == U32 */ - -MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) -{ - const void* ptr = dt; - const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; - DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); - BIT_reloadDStream(bitD); - DStatePtr->table = dt + 1; -} - -MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr) -{ - FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; - return DInfo.symbol; -} - -MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) -{ - FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; - U32 const nbBits = DInfo.nbBits; - size_t const lowBits = BIT_readBits(bitD, nbBits); - DStatePtr->state = DInfo.newState + lowBits; -} - -MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) -{ - FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; - U32 const nbBits = DInfo.nbBits; - BYTE const symbol = DInfo.symbol; - size_t const lowBits = BIT_readBits(bitD, nbBits); - - DStatePtr->state = DInfo.newState + lowBits; - return symbol; -} - -/*! FSE_decodeSymbolFast() : - unsafe, only works if no symbol has a probability > 50% */ -MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) -{ - FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; - U32 const nbBits = DInfo.nbBits; - BYTE const symbol = DInfo.symbol; - size_t const lowBits = BIT_readBitsFast(bitD, nbBits); - - DStatePtr->state = DInfo.newState + lowBits; - return symbol; -} - -MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) -{ - return DStatePtr->state == 0; -} - - - -#ifndef FSE_COMMONDEFS_ONLY - -/* ************************************************************** -* Tuning parameters -****************************************************************/ -/*!MEMORY_USAGE : -* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) -* Increasing memory usage improves compression ratio -* Reduced memory usage can improve speed, due to cache effect -* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ -#ifndef FSE_MAX_MEMORY_USAGE -# define FSE_MAX_MEMORY_USAGE 16 -#endif -#ifndef FSE_DEFAULT_MEMORY_USAGE -# define FSE_DEFAULT_MEMORY_USAGE 16 -#endif - -/*!FSE_MAX_SYMBOL_VALUE : -* Maximum symbol value authorized. -* Required for proper stack allocation */ -#ifndef FSE_MAX_SYMBOL_VALUE -# define FSE_MAX_SYMBOL_VALUE 255 -#endif - -/* ************************************************************** -* template functions type & suffix -****************************************************************/ -#define FSE_FUNCTION_TYPE BYTE -#define FSE_FUNCTION_EXTENSION -#define FSE_DECODE_TYPE FSE_decode_t - - -#endif /* !FSE_COMMONDEFS_ONLY */ - - -/* *************************************************************** -* Constants -*****************************************************************/ -#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) -#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX -# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" -#endif - -#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3) - - -#endif /* FSE_STATIC_LINKING_ONLY */ - - -#if defined (__cplusplus) -} -#endif +/* ****************************************************************** + FSE : Finite State Entropy codec + Public Prototypes declaration + Copyright (C) 2013-2016, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef FSE_H +#define FSE_H + + +/*-***************************************** +* Dependencies +******************************************/ +#include /* size_t, ptrdiff_t */ + + +/*-***************************************** +* FSE_PUBLIC_API : control library symbols visibility +******************************************/ +#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) +# define FSE_PUBLIC_API __attribute__ ((visibility ("default"))) +#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ +# define FSE_PUBLIC_API __declspec(dllexport) +#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) +# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define FSE_PUBLIC_API +#endif + +/*------ Version ------*/ +#define FSE_VERSION_MAJOR 0 +#define FSE_VERSION_MINOR 9 +#define FSE_VERSION_RELEASE 0 + +#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE +#define FSE_QUOTE(str) #str +#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) +#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) + +#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) +FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ + + +/*-**************************************** +* FSE simple functions +******************************************/ +/*! FSE_compress() : + Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'. + 'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize). + @return : size of compressed data (<= dstCapacity). + Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! + if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead. + if FSE_isError(return), compression failed (more details using FSE_getErrorName()) +*/ +FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +/*! FSE_decompress(): + Decompress FSE data from buffer 'cSrc', of size 'cSrcSize', + into already allocated destination buffer 'dst', of size 'dstCapacity'. + @return : size of regenerated data (<= maxDstSize), + or an error code, which can be tested using FSE_isError() . + + ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!! + Why ? : making this distinction requires a header. + Header management is intentionally delegated to the user layer, which can better manage special cases. +*/ +FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity, + const void* cSrc, size_t cSrcSize); + + +/*-***************************************** +* Tool functions +******************************************/ +FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ + +/* Error Management */ +FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ +FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ + + +/*-***************************************** +* FSE advanced functions +******************************************/ +/*! FSE_compress2() : + Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog' + Both parameters can be defined as '0' to mean : use default value + @return : size of compressed data + Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!! + if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression. + if FSE_isError(return), it's an error code. +*/ +FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); + + +/*-***************************************** +* FSE detailed API +******************************************/ +/*! +FSE_compress() does the following: +1. count symbol occurrence from source[] into table count[] (see hist.h) +2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog) +3. save normalized counters to memory buffer using writeNCount() +4. build encoding table 'CTable' from normalized counters +5. encode the data stream using encoding table 'CTable' + +FSE_decompress() does the following: +1. read normalized counters with readNCount() +2. build decoding table 'DTable' from normalized counters +3. decode the data stream using decoding table 'DTable' + +The following API allows targeting specific sub-functions for advanced tasks. +For example, it's possible to compress several blocks using the same 'CTable', +or to save and provide normalized distribution using external method. +*/ + +/* *** COMPRESSION *** */ + +/*! FSE_optimalTableLog(): + dynamically downsize 'tableLog' when conditions are met. + It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. + @return : recommended tableLog (necessarily <= 'maxTableLog') */ +FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_normalizeCount(): + normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) + 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). + @return : tableLog, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_NCountWriteBound(): + Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. + Typically useful for allocation purpose. */ +FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_writeNCount(): + Compactly save 'normalizedCounter' into 'buffer'. + @return : size of the compressed table, + or an errorCode, which can be tested using FSE_isError(). */ +FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, + const short* normalizedCounter, + unsigned maxSymbolValue, unsigned tableLog); + +/*! Constructor and Destructor of FSE_CTable. + Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ +typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ +FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog); +FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct); + +/*! FSE_buildCTable(): + Builds `ct`, which must be already allocated, using FSE_createCTable(). + @return : 0, or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_compress_usingCTable(): + Compress `src` using `ct` into `dst` which must be already allocated. + @return : size of compressed data (<= `dstCapacity`), + or 0 if compressed data could not fit into `dst`, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); + +/*! +Tutorial : +---------- +The first step is to count all symbols. FSE_count() does this job very fast. +Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells. +'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0] +maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value) +FSE_count() will return the number of occurrence of the most frequent symbol. +This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). + +The next step is to normalize the frequencies. +FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'. +It also guarantees a minimum of 1 to any Symbol with frequency >= 1. +You can use 'tableLog'==0 to mean "use default tableLog value". +If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(), +which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default"). + +The result of FSE_normalizeCount() will be saved into a table, +called 'normalizedCounter', which is a table of signed short. +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells. +The return value is tableLog if everything proceeded as expected. +It is 0 if there is a single symbol within distribution. +If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()). + +'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount(). +'buffer' must be already allocated. +For guaranteed success, buffer size must be at least FSE_headerBound(). +The result of the function is the number of bytes written into 'buffer'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small). + +'normalizedCounter' can then be used to create the compression table 'CTable'. +The space required by 'CTable' must be already allocated, using FSE_createCTable(). +You can then use FSE_buildCTable() to fill 'CTable'. +If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()). + +'CTable' can then be used to compress 'src', with FSE_compress_usingCTable(). +Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize' +The function returns the size of compressed data (without header), necessarily <= `dstCapacity`. +If it returns '0', compressed data could not fit into 'dst'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). +*/ + + +/* *** DECOMPRESSION *** */ + +/*! FSE_readNCount(): + Read compactly saved 'normalizedCounter' from 'rBuffer'. + @return : size read from 'rBuffer', + or an errorCode, which can be tested using FSE_isError(). + maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ +FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize); + +/*! Constructor and Destructor of FSE_DTable. + Note that its size depends on 'tableLog' */ +typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ +FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog); +FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt); + +/*! FSE_buildDTable(): + Builds 'dt', which must be already allocated, using FSE_createDTable(). + return : 0, or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_decompress_usingDTable(): + Decompress compressed source `cSrc` of size `cSrcSize` using `dt` + into `dst` which must be already allocated. + @return : size of regenerated data (necessarily <= `dstCapacity`), + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt); + +/*! +Tutorial : +---------- +(Note : these functions only decompress FSE-compressed blocks. + If block is uncompressed, use memcpy() instead + If block is a single repeated byte, use memset() instead ) + +The first step is to obtain the normalized frequencies of symbols. +This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount(). +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short. +In practice, that means it's necessary to know 'maxSymbolValue' beforehand, +or size the table to handle worst case situations (typically 256). +FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'. +The result of FSE_readNCount() is the number of bytes read from 'rBuffer'. +Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that. +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'. +This is performed by the function FSE_buildDTable(). +The space required by 'FSE_DTable' must be already allocated using FSE_createDTable(). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable(). +`cSrcSize` must be strictly correct, otherwise decompression will fail. +FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) +*/ + +#endif /* FSE_H */ + +#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) +#define FSE_H_FSE_STATIC_LINKING_ONLY + +/* *** Dependency *** */ +#include "bitstream.h" + + +/* ***************************************** +* Static allocation +*******************************************/ +/* FSE buffer bounds */ +#define FSE_NCOUNTBOUND 512 +#define FSE_BLOCKBOUND(size) (size + (size>>7)) +#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ +#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2)) +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1< 12) ? (1 << (maxTableLog - 2)) : 1024) ) +size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); + +size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits); +/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ + +size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); +/**< build a fake FSE_CTable, designed to compress always the same symbolValue */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * `wkspSize` must be >= `(1<= BIT_DStream_completed + +When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. +Checking if DStream has reached its end is performed by : + BIT_endOfDStream(&DStream); +Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. + FSE_endOfDState(&DState); +*/ + + +/* ***************************************** +* FSE unsafe API +*******************************************/ +static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); +/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ + + +/* ***************************************** +* Implementation of inlined functions +*******************************************/ +typedef struct { + int deltaFindState; + U32 deltaNbBits; +} FSE_symbolCompressionTransform; /* total 8 bytes */ + +MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) +{ + const void* ptr = ct; + const U16* u16ptr = (const U16*) ptr; + const U32 tableLog = MEM_read16(ptr); + statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2; + statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1)); + statePtr->stateLog = tableLog; +} + + +/*! FSE_initCState2() : +* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) +* uses the smallest state value possible, saving the cost of this symbol */ +MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol) +{ + FSE_initCState(statePtr, ct); + { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* stateTable = (const U16*)(statePtr->stateTable); + U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16); + statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; + statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; + } +} + +MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol) +{ + FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* const stateTable = (const U16*)(statePtr->stateTable); + U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); + BIT_addBits(bitC, statePtr->value, nbBitsOut); + statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; +} + +MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) +{ + BIT_addBits(bitC, statePtr->value, statePtr->stateLog); + BIT_flushBits(bitC); +} + + +/* FSE_getMaxNbBits() : + * Approximate maximum cost of a symbol, in bits. + * Fractional get rounded up (i.e : a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16; +} + +/* FSE_bitCost() : + * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16; + U32 const threshold = (minNbBits+1) << 16; + assert(tableLog < 16); + assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */ + { U32 const tableSize = 1 << tableLog; + U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize); + U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */ + U32 const bitMultiplier = 1 << accuracyLog; + assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold); + assert(normalizedDeltaFromThreshold <= bitMultiplier); + return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold; + } +} + + +/* ====== Decompression ====== */ + +typedef struct { + U16 tableLog; + U16 fastMode; +} FSE_DTableHeader; /* sizeof U32 */ + +typedef struct +{ + unsigned short newState; + unsigned char symbol; + unsigned char nbBits; +} FSE_decode_t; /* size == U32 */ + +MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) +{ + const void* ptr = dt; + const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + return DInfo.symbol; +} + +MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = DInfo.newState + lowBits; +} + +MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBits(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +/*! FSE_decodeSymbolFast() : + unsafe, only works if no symbol has a probability > 50% */ +MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBitsFast(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) +{ + return DStatePtr->state == 0; +} + + + +#ifndef FSE_COMMONDEFS_ONLY + +/* ************************************************************** +* Tuning parameters +****************************************************************/ +/*!MEMORY_USAGE : +* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect +* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ +#ifndef FSE_MAX_MEMORY_USAGE +# define FSE_MAX_MEMORY_USAGE 16 +#endif +#ifndef FSE_DEFAULT_MEMORY_USAGE +# define FSE_DEFAULT_MEMORY_USAGE 16 +#endif + +/*!FSE_MAX_SYMBOL_VALUE : +* Maximum symbol value authorized. +* Required for proper stack allocation */ +#ifndef FSE_MAX_SYMBOL_VALUE +# define FSE_MAX_SYMBOL_VALUE 255 +#endif + +/* ************************************************************** +* template functions type & suffix +****************************************************************/ +#define FSE_FUNCTION_TYPE BYTE +#define FSE_FUNCTION_EXTENSION +#define FSE_DECODE_TYPE FSE_decode_t + + +#endif /* !FSE_COMMONDEFS_ONLY */ + + +/* *************************************************************** +* Constants +*****************************************************************/ +#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) +#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX +# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" +#endif + +#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3) + + +#endif /* FSE_STATIC_LINKING_ONLY */ + + +#if defined (__cplusplus) +} +#endif diff --git a/src/fse/fse_compress.c b/src/fse/fse_compress.c index 07b3ab89..96d68cae 100644 --- a/src/fse/fse_compress.c +++ b/src/fse/fse_compress.c @@ -1,714 +1,714 @@ -/* ****************************************************************** - FSE : Finite State Entropy encoder - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy - - Public forum : https://groups.google.com/forum/#!forum/lz4c -****************************************************************** */ - -/* ************************************************************** -* Includes -****************************************************************/ -#include /* malloc, free, qsort */ -#include /* memcpy, memset */ -#include "compiler.h" -#include "mem.h" /* U32, U16, etc. */ -#include "debug.h" /* assert, DEBUGLOG */ -#include "hist.h" /* HIST_count_wksp */ -#include "bitstream.h" -#define FSE_STATIC_LINKING_ONLY -#include "fse.h" -#include "error_private.h" - - -/* ************************************************************** -* Error Management -****************************************************************/ -#define FSE_isError ERR_isError - - -/* ************************************************************** -* Templates -****************************************************************/ -/* - designed to be included - for type-specific functions (template emulation in C) - Objective is to write these functions only once, for improved maintenance -*/ - -/* safety checks */ -#ifndef FSE_FUNCTION_EXTENSION -# error "FSE_FUNCTION_EXTENSION must be defined" -#endif -#ifndef FSE_FUNCTION_TYPE -# error "FSE_FUNCTION_TYPE must be defined" -#endif - -/* Function names */ -#define FSE_CAT(X,Y) X##Y -#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) -#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) - - -/* Function templates */ - -/* FSE_buildCTable_wksp() : - * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). - * wkspSize should be sized to handle worst case situation, which is `1<>1 : 1) ; - FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); - U32 const step = FSE_TABLESTEP(tableSize); - U32 cumul[FSE_MAX_SYMBOL_VALUE+2]; - - FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace; - U32 highThreshold = tableSize-1; - - /* CTable header */ - if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge); - tableU16[-2] = (U16) tableLog; - tableU16[-1] = (U16) maxSymbolValue; - assert(tableLog < 16); /* required for the threshold strategy to work */ - - /* For explanations on how to distribute symbol values over the table : - * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */ - - /* symbol start positions */ - { U32 u; - cumul[0] = 0; - for (u=1; u<=maxSymbolValue+1; u++) { - if (normalizedCounter[u-1]==-1) { /* Low proba symbol */ - cumul[u] = cumul[u-1] + 1; - tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1); - } else { - cumul[u] = cumul[u-1] + normalizedCounter[u-1]; - } } - cumul[maxSymbolValue+1] = tableSize+1; - } - - /* Spread symbols */ - { U32 position = 0; - U32 symbol; - for (symbol=0; symbol<=maxSymbolValue; symbol++) { - int nbOccurences; - for (nbOccurences=0; nbOccurences highThreshold) position = (position + step) & tableMask; /* Low proba area */ - } } - - if (position!=0) return ERROR(GENERIC); /* Must have gone through all positions */ - } - - /* Build table */ - { U32 u; for (u=0; u> 3) + 3; - return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ -} - -static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize, - const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, - unsigned writeIsSafe) -{ - BYTE* const ostart = (BYTE*) header; - BYTE* out = ostart; - BYTE* const oend = ostart + headerBufferSize; - int nbBits; - const int tableSize = 1 << tableLog; - int remaining; - int threshold; - U32 bitStream; - int bitCount; - unsigned charnum = 0; - int previous0 = 0; - - bitStream = 0; - bitCount = 0; - /* Table Size */ - bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount; - bitCount += 4; - - /* Init */ - remaining = tableSize+1; /* +1 for extra accuracy */ - threshold = tableSize; - nbBits = tableLog+1; - - while (remaining>1) { /* stops at 1 */ - if (previous0) { - unsigned start = charnum; - while (!normalizedCounter[charnum]) charnum++; - while (charnum >= start+24) { - start+=24; - bitStream += 0xFFFFU << bitCount; - if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ - out[0] = (BYTE) bitStream; - out[1] = (BYTE)(bitStream>>8); - out+=2; - bitStream>>=16; - } - while (charnum >= start+3) { - start+=3; - bitStream += 3 << bitCount; - bitCount += 2; - } - bitStream += (charnum-start) << bitCount; - bitCount += 2; - if (bitCount>16) { - if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ - out[0] = (BYTE)bitStream; - out[1] = (BYTE)(bitStream>>8); - out += 2; - bitStream >>= 16; - bitCount -= 16; - } } - { int count = normalizedCounter[charnum++]; - int const max = (2*threshold-1)-remaining; - remaining -= count < 0 ? -count : count; - count++; /* +1 for extra accuracy */ - if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ - bitStream += count << bitCount; - bitCount += nbBits; - bitCount -= (count>=1; } - } - if (bitCount>16) { - if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ - out[0] = (BYTE)bitStream; - out[1] = (BYTE)(bitStream>>8); - out += 2; - bitStream >>= 16; - bitCount -= 16; - } } - - /* flush remaining bitStream */ - if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ - out[0] = (BYTE)bitStream; - out[1] = (BYTE)(bitStream>>8); - out+= (bitCount+7) /8; - - if (charnum > maxSymbolValue + 1) return ERROR(GENERIC); - - return (out-ostart); -} - - -size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) -{ - if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */ - if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */ - - if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog)) - return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0); - - return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1); -} - - -/*-************************************************************** -* FSE Compression Code -****************************************************************/ -/*! FSE_sizeof_CTable() : - FSE_CTable is a variable size structure which contains : - `U16 tableLog;` - `U16 maxSymbolValue;` - `U16 nextStateNumber[1 << tableLog];` // This size is variable - `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];` // This size is variable -Allocation is manual (C standard does not support variable-size structures). -*/ -size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog) -{ - if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); - return FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32); -} - -FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog) -{ - size_t size; - if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; - size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32); - return (FSE_CTable*)malloc(size); -} - -void FSE_freeCTable (FSE_CTable* ct) { free(ct); } - -/* provides the minimum logSize to safely represent a distribution */ -static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) -{ - U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1; - U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2; - U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols; - assert(srcSize > 1); /* Not supported, RLE should be used instead */ - return minBits; -} - -unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus) -{ - U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus; - U32 tableLog = maxTableLog; - U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue); - assert(srcSize > 1); /* Not supported, RLE should be used instead */ - if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; - if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */ - if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */ - if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG; - if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG; - return tableLog; -} - -unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) -{ - return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2); -} - - -/* Secondary normalization method. - To be used when primary method fails. */ - -static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue) -{ - short const NOT_YET_ASSIGNED = -2; - U32 s; - U32 distributed = 0; - U32 ToDistribute; - - /* Init */ - U32 const lowThreshold = (U32)(total >> tableLog); - U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); - - for (s=0; s<=maxSymbolValue; s++) { - if (count[s] == 0) { - norm[s]=0; - continue; - } - if (count[s] <= lowThreshold) { - norm[s] = -1; - distributed++; - total -= count[s]; - continue; - } - if (count[s] <= lowOne) { - norm[s] = 1; - distributed++; - total -= count[s]; - continue; - } - - norm[s]=NOT_YET_ASSIGNED; - } - ToDistribute = (1 << tableLog) - distributed; - - if ((total / ToDistribute) > lowOne) { - /* risk of rounding to zero */ - lowOne = (U32)((total * 3) / (ToDistribute * 2)); - for (s=0; s<=maxSymbolValue; s++) { - if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) { - norm[s] = 1; - distributed++; - total -= count[s]; - continue; - } } - ToDistribute = (1 << tableLog) - distributed; - } - - if (distributed == maxSymbolValue+1) { - /* all values are pretty poor; - probably incompressible data (should have already been detected); - find max, then give all remaining points to max */ - U32 maxV = 0, maxC = 0; - for (s=0; s<=maxSymbolValue; s++) - if (count[s] > maxC) { maxV=s; maxC=count[s]; } - norm[maxV] += (short)ToDistribute; - return 0; - } - - if (total == 0) { - /* all of the symbols were low enough for the lowOne or lowThreshold */ - for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1)) - if (norm[s] > 0) { ToDistribute--; norm[s]++; } - return 0; - } - - { U64 const vStepLog = 62 - tableLog; - U64 const mid = (1ULL << (vStepLog-1)) - 1; - U64 const rStep = ((((U64)1<> vStepLog); - U32 const sEnd = (U32)(end >> vStepLog); - U32 const weight = sEnd - sStart; - if (weight < 1) - return ERROR(GENERIC); - norm[s] = (short)weight; - tmpTotal = end; - } } } - - return 0; -} - - -size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, - const unsigned* count, size_t total, - unsigned maxSymbolValue) -{ - /* Sanity checks */ - if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; - if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */ - if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */ - if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ - - { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 }; - U64 const scale = 62 - tableLog; - U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */ - U64 const vStep = 1ULL<<(scale-20); - int stillToDistribute = 1<> tableLog); - - for (s=0; s<=maxSymbolValue; s++) { - if (count[s] == total) return 0; /* rle special case */ - if (count[s] == 0) { normalizedCounter[s]=0; continue; } - if (count[s] <= lowThreshold) { - normalizedCounter[s] = -1; - stillToDistribute--; - } else { - short proba = (short)((count[s]*step) >> scale); - if (proba<8) { - U64 restToBeat = vStep * rtbTable[proba]; - proba += (count[s]*step) - ((U64)proba< restToBeat; - } - if (proba > largestP) { largestP=proba; largest=s; } - normalizedCounter[s] = proba; - stillToDistribute -= proba; - } } - if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { - /* corner case, need another normalization method */ - size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue); - if (FSE_isError(errorCode)) return errorCode; - } - else normalizedCounter[largest] += (short)stillToDistribute; - } - -#if 0 - { /* Print Table (debug) */ - U32 s; - U32 nTotal = 0; - for (s=0; s<=maxSymbolValue; s++) - RAWLOG(2, "%3i: %4i \n", s, normalizedCounter[s]); - for (s=0; s<=maxSymbolValue; s++) - nTotal += abs(normalizedCounter[s]); - if (nTotal != (1U<>1); /* assumption : tableLog >= 1 */ - FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); - unsigned s; - - /* Sanity checks */ - if (nbBits < 1) return ERROR(GENERIC); /* min size */ - - /* header */ - tableU16[-2] = (U16) nbBits; - tableU16[-1] = (U16) maxSymbolValue; - - /* Build table */ - for (s=0; s FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) { /* test bit 2 */ - FSE_encodeSymbol(&bitC, &CState2, *--ip); - FSE_encodeSymbol(&bitC, &CState1, *--ip); - FSE_FLUSHBITS(&bitC); - } - - /* 2 or 4 encoding per loop */ - while ( ip>istart ) { - - FSE_encodeSymbol(&bitC, &CState2, *--ip); - - if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */ - FSE_FLUSHBITS(&bitC); - - FSE_encodeSymbol(&bitC, &CState1, *--ip); - - if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) { /* this test must be static */ - FSE_encodeSymbol(&bitC, &CState2, *--ip); - FSE_encodeSymbol(&bitC, &CState1, *--ip); - } - - FSE_FLUSHBITS(&bitC); - } - - FSE_flushCState(&bitC, &CState2); - FSE_flushCState(&bitC, &CState1); - return BIT_closeCStream(&bitC); -} - -size_t FSE_compress_usingCTable (void* dst, size_t dstSize, - const void* src, size_t srcSize, - const FSE_CTable* ct) -{ - unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); - - if (fast) - return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1); - else - return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0); -} - - -size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } - -#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e -#define CHECK_F(f) { CHECK_V_F(_var_err__, f); } - -/* FSE_compress_wksp() : - * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). - * `wkspSize` size must be `(1< not compressible */ - if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */ - } - - tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); - CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) ); - - /* Write table description header */ - { CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); - op += nc_err; - } - - /* Compress */ - CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) ); - { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) ); - if (cSize == 0) return 0; /* not enough space for compressed data */ - op += cSize; - } - - /* check compressibility */ - if ( (size_t)(op-ostart) >= srcSize-1 ) return 0; - - return op-ostart; -} - -typedef struct { - FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)]; - BYTE scratchBuffer[1 << FSE_MAX_TABLELOG]; -} fseWkspMax_t; - -size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) -{ - fseWkspMax_t scratchBuffer; - DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */ - if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); - return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer)); -} - -size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) -{ - return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG); -} - - -#endif /* FSE_COMMONDEFS_ONLY */ +/* ****************************************************************** + FSE : Finite State Entropy encoder + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ + +/* ************************************************************** +* Includes +****************************************************************/ +#include /* malloc, free, qsort */ +#include /* memcpy, memset */ +#include "compiler.h" +#include "mem.h" /* U32, U16, etc. */ +#include "debug.h" /* assert, DEBUGLOG */ +#include "hist.h" /* HIST_count_wksp */ +#include "bitstream.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "error_private.h" + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + + +/* Function templates */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * wkspSize should be sized to handle worst case situation, which is `1<>1 : 1) ; + FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); + U32 const step = FSE_TABLESTEP(tableSize); + U32 cumul[FSE_MAX_SYMBOL_VALUE+2]; + + FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace; + U32 highThreshold = tableSize-1; + + /* CTable header */ + if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge); + tableU16[-2] = (U16) tableLog; + tableU16[-1] = (U16) maxSymbolValue; + assert(tableLog < 16); /* required for the threshold strategy to work */ + + /* For explanations on how to distribute symbol values over the table : + * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */ + + /* symbol start positions */ + { U32 u; + cumul[0] = 0; + for (u=1; u<=maxSymbolValue+1; u++) { + if (normalizedCounter[u-1]==-1) { /* Low proba symbol */ + cumul[u] = cumul[u-1] + 1; + tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1); + } else { + cumul[u] = cumul[u-1] + normalizedCounter[u-1]; + } } + cumul[maxSymbolValue+1] = tableSize+1; + } + + /* Spread symbols */ + { U32 position = 0; + U32 symbol; + for (symbol=0; symbol<=maxSymbolValue; symbol++) { + int nbOccurences; + for (nbOccurences=0; nbOccurences highThreshold) position = (position + step) & tableMask; /* Low proba area */ + } } + + if (position!=0) return ERROR(GENERIC); /* Must have gone through all positions */ + } + + /* Build table */ + { U32 u; for (u=0; u> 3) + 3; + return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ +} + +static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize, + const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, + unsigned writeIsSafe) +{ + BYTE* const ostart = (BYTE*) header; + BYTE* out = ostart; + BYTE* const oend = ostart + headerBufferSize; + int nbBits; + const int tableSize = 1 << tableLog; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + int previous0 = 0; + + bitStream = 0; + bitCount = 0; + /* Table Size */ + bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount; + bitCount += 4; + + /* Init */ + remaining = tableSize+1; /* +1 for extra accuracy */ + threshold = tableSize; + nbBits = tableLog+1; + + while (remaining>1) { /* stops at 1 */ + if (previous0) { + unsigned start = charnum; + while (!normalizedCounter[charnum]) charnum++; + while (charnum >= start+24) { + start+=24; + bitStream += 0xFFFFU << bitCount; + if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE) bitStream; + out[1] = (BYTE)(bitStream>>8); + out+=2; + bitStream>>=16; + } + while (charnum >= start+3) { + start+=3; + bitStream += 3 << bitCount; + bitCount += 2; + } + bitStream += (charnum-start) << bitCount; + bitCount += 2; + if (bitCount>16) { + if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } } + { int count = normalizedCounter[charnum++]; + int const max = (2*threshold-1)-remaining; + remaining -= count < 0 ? -count : count; + count++; /* +1 for extra accuracy */ + if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ + bitStream += count << bitCount; + bitCount += nbBits; + bitCount -= (count>=1; } + } + if (bitCount>16) { + if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } } + + /* flush remaining bitStream */ + if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out+= (bitCount+7) /8; + + if (charnum > maxSymbolValue + 1) return ERROR(GENERIC); + + return (out-ostart); +} + + +size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */ + if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */ + + if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog)) + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0); + + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1); +} + + +/*-************************************************************** +* FSE Compression Code +****************************************************************/ +/*! FSE_sizeof_CTable() : + FSE_CTable is a variable size structure which contains : + `U16 tableLog;` + `U16 maxSymbolValue;` + `U16 nextStateNumber[1 << tableLog];` // This size is variable + `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];` // This size is variable +Allocation is manual (C standard does not support variable-size structures). +*/ +size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog) +{ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + return FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32); +} + +FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog) +{ + size_t size; + if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; + size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32); + return (FSE_CTable*)malloc(size); +} + +void FSE_freeCTable (FSE_CTable* ct) { free(ct); } + +/* provides the minimum logSize to safely represent a distribution */ +static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) +{ + U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1; + U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2; + U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols; + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + return minBits; +} + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus) +{ + U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus; + U32 tableLog = maxTableLog; + U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue); + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; + if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */ + if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */ + if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG; + if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG; + return tableLog; +} + +unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) +{ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2); +} + + +/* Secondary normalization method. + To be used when primary method fails. */ + +static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue) +{ + short const NOT_YET_ASSIGNED = -2; + U32 s; + U32 distributed = 0; + U32 ToDistribute; + + /* Init */ + U32 const lowThreshold = (U32)(total >> tableLog); + U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); + + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == 0) { + norm[s]=0; + continue; + } + if (count[s] <= lowThreshold) { + norm[s] = -1; + distributed++; + total -= count[s]; + continue; + } + if (count[s] <= lowOne) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } + + norm[s]=NOT_YET_ASSIGNED; + } + ToDistribute = (1 << tableLog) - distributed; + + if ((total / ToDistribute) > lowOne) { + /* risk of rounding to zero */ + lowOne = (U32)((total * 3) / (ToDistribute * 2)); + for (s=0; s<=maxSymbolValue; s++) { + if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } } + ToDistribute = (1 << tableLog) - distributed; + } + + if (distributed == maxSymbolValue+1) { + /* all values are pretty poor; + probably incompressible data (should have already been detected); + find max, then give all remaining points to max */ + U32 maxV = 0, maxC = 0; + for (s=0; s<=maxSymbolValue; s++) + if (count[s] > maxC) { maxV=s; maxC=count[s]; } + norm[maxV] += (short)ToDistribute; + return 0; + } + + if (total == 0) { + /* all of the symbols were low enough for the lowOne or lowThreshold */ + for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1)) + if (norm[s] > 0) { ToDistribute--; norm[s]++; } + return 0; + } + + { U64 const vStepLog = 62 - tableLog; + U64 const mid = (1ULL << (vStepLog-1)) - 1; + U64 const rStep = ((((U64)1<> vStepLog); + U32 const sEnd = (U32)(end >> vStepLog); + U32 const weight = sEnd - sStart; + if (weight < 1) + return ERROR(GENERIC); + norm[s] = (short)weight; + tmpTotal = end; + } } } + + return 0; +} + + +size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t total, + unsigned maxSymbolValue) +{ + /* Sanity checks */ + if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; + if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */ + if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ + + { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 }; + U64 const scale = 62 - tableLog; + U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */ + U64 const vStep = 1ULL<<(scale-20); + int stillToDistribute = 1<> tableLog); + + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == total) return 0; /* rle special case */ + if (count[s] == 0) { normalizedCounter[s]=0; continue; } + if (count[s] <= lowThreshold) { + normalizedCounter[s] = -1; + stillToDistribute--; + } else { + short proba = (short)((count[s]*step) >> scale); + if (proba<8) { + U64 restToBeat = vStep * rtbTable[proba]; + proba += (count[s]*step) - ((U64)proba< restToBeat; + } + if (proba > largestP) { largestP=proba; largest=s; } + normalizedCounter[s] = proba; + stillToDistribute -= proba; + } } + if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { + /* corner case, need another normalization method */ + size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue); + if (FSE_isError(errorCode)) return errorCode; + } + else normalizedCounter[largest] += (short)stillToDistribute; + } + +#if 0 + { /* Print Table (debug) */ + U32 s; + U32 nTotal = 0; + for (s=0; s<=maxSymbolValue; s++) + RAWLOG(2, "%3i: %4i \n", s, normalizedCounter[s]); + for (s=0; s<=maxSymbolValue; s++) + nTotal += abs(normalizedCounter[s]); + if (nTotal != (1U<>1); /* assumption : tableLog >= 1 */ + FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); + unsigned s; + + /* Sanity checks */ + if (nbBits < 1) return ERROR(GENERIC); /* min size */ + + /* header */ + tableU16[-2] = (U16) nbBits; + tableU16[-1] = (U16) maxSymbolValue; + + /* Build table */ + for (s=0; s FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) { /* test bit 2 */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + FSE_FLUSHBITS(&bitC); + } + + /* 2 or 4 encoding per loop */ + while ( ip>istart ) { + + FSE_encodeSymbol(&bitC, &CState2, *--ip); + + if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */ + FSE_FLUSHBITS(&bitC); + + FSE_encodeSymbol(&bitC, &CState1, *--ip); + + if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) { /* this test must be static */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + } + + FSE_FLUSHBITS(&bitC); + } + + FSE_flushCState(&bitC, &CState2); + FSE_flushCState(&bitC, &CState1); + return BIT_closeCStream(&bitC); +} + +size_t FSE_compress_usingCTable (void* dst, size_t dstSize, + const void* src, size_t srcSize, + const FSE_CTable* ct) +{ + unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); + + if (fast) + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1); + else + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0); +} + + +size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } + +#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e +#define CHECK_F(f) { CHECK_V_F(_var_err__, f); } + +/* FSE_compress_wksp() : + * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). + * `wkspSize` size must be `(1< not compressible */ + if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */ + } + + tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); + CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) ); + + /* Write table description header */ + { CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); + op += nc_err; + } + + /* Compress */ + CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) ); + { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) ); + if (cSize == 0) return 0; /* not enough space for compressed data */ + op += cSize; + } + + /* check compressibility */ + if ( (size_t)(op-ostart) >= srcSize-1 ) return 0; + + return op-ostart; +} + +typedef struct { + FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)]; + BYTE scratchBuffer[1 << FSE_MAX_TABLELOG]; +} fseWkspMax_t; + +size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) +{ + fseWkspMax_t scratchBuffer; + DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer)); +} + +size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG); +} + + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/src/fse/fse_decompress.c b/src/fse/fse_decompress.c index 72bbead5..3963289b 100644 --- a/src/fse/fse_decompress.c +++ b/src/fse/fse_decompress.c @@ -1,309 +1,309 @@ -/* ****************************************************************** - FSE : Finite State Entropy decoder - Copyright (C) 2013-2015, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy - - Public forum : https://groups.google.com/forum/#!forum/lz4c -****************************************************************** */ - - -/* ************************************************************** -* Includes -****************************************************************/ -#include /* malloc, free, qsort */ -#include /* memcpy, memset */ -#include "bitstream.h" -#include "compiler.h" -#define FSE_STATIC_LINKING_ONLY -#include "fse.h" -#include "error_private.h" - - -/* ************************************************************** -* Error Management -****************************************************************/ -#define FSE_isError ERR_isError -#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ - -/* check and forward error code */ -#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; } - - -/* ************************************************************** -* Templates -****************************************************************/ -/* - designed to be included - for type-specific functions (template emulation in C) - Objective is to write these functions only once, for improved maintenance -*/ - -/* safety checks */ -#ifndef FSE_FUNCTION_EXTENSION -# error "FSE_FUNCTION_EXTENSION must be defined" -#endif -#ifndef FSE_FUNCTION_TYPE -# error "FSE_FUNCTION_TYPE must be defined" -#endif - -/* Function names */ -#define FSE_CAT(X,Y) X##Y -#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) -#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) - - -/* Function templates */ -FSE_DTable* FSE_createDTable (unsigned tableLog) -{ - if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; - return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); -} - -void FSE_freeDTable (FSE_DTable* dt) -{ - free(dt); -} - -size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) -{ - void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ - FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); - U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; - - U32 const maxSV1 = maxSymbolValue + 1; - U32 const tableSize = 1 << tableLog; - U32 highThreshold = tableSize-1; - - /* Sanity Checks */ - if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); - if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); - - /* Init, lay down lowprob symbols */ - { FSE_DTableHeader DTableH; - DTableH.tableLog = (U16)tableLog; - DTableH.fastMode = 1; - { S16 const largeLimit= (S16)(1 << (tableLog-1)); - U32 s; - for (s=0; s= largeLimit) DTableH.fastMode=0; - symbolNext[s] = normalizedCounter[s]; - } } } - memcpy(dt, &DTableH, sizeof(DTableH)); - } - - /* Spread symbols */ - { U32 const tableMask = tableSize-1; - U32 const step = FSE_TABLESTEP(tableSize); - U32 s, position = 0; - for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ - } } - if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ - } - - /* Build Decoding table */ - { U32 u; - for (u=0; utableLog = 0; - DTableH->fastMode = 0; - - cell->newState = 0; - cell->symbol = symbolValue; - cell->nbBits = 0; - - return 0; -} - - -size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) -{ - void* ptr = dt; - FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; - void* dPtr = dt + 1; - FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr; - const unsigned tableSize = 1 << nbBits; - const unsigned tableMask = tableSize - 1; - const unsigned maxSV1 = tableMask+1; - unsigned s; - - /* Sanity checks */ - if (nbBits < 1) return ERROR(GENERIC); /* min size */ - - /* Build Decoding Table */ - DTableH->tableLog = (U16)nbBits; - DTableH->fastMode = 1; - for (s=0; s sizeof(bitD.bitContainer)*8) /* This test must be static */ - BIT_reloadDStream(&bitD); - - op[1] = FSE_GETSYMBOL(&state2); - - if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ - { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } - - op[2] = FSE_GETSYMBOL(&state1); - - if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ - BIT_reloadDStream(&bitD); - - op[3] = FSE_GETSYMBOL(&state2); - } - - /* tail */ - /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ - while (1) { - if (op>(omax-2)) return ERROR(dstSize_tooSmall); - *op++ = FSE_GETSYMBOL(&state1); - if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { - *op++ = FSE_GETSYMBOL(&state2); - break; - } - - if (op>(omax-2)) return ERROR(dstSize_tooSmall); - *op++ = FSE_GETSYMBOL(&state2); - if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { - *op++ = FSE_GETSYMBOL(&state1); - break; - } } - - return op-ostart; -} - - -size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, - const void* cSrc, size_t cSrcSize, - const FSE_DTable* dt) -{ - const void* ptr = dt; - const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; - const U32 fastMode = DTableH->fastMode; - - /* select fast mode (static) */ - if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); - return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); -} - - -size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog) -{ - const BYTE* const istart = (const BYTE*)cSrc; - const BYTE* ip = istart; - short counting[FSE_MAX_SYMBOL_VALUE+1]; - unsigned tableLog; - unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; - - /* normal FSE decoding mode */ - size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); - if (FSE_isError(NCountLength)) return NCountLength; - //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ - if (tableLog > maxLog) return ERROR(tableLog_tooLarge); - ip += NCountLength; - cSrcSize -= NCountLength; - - CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) ); - - return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ -} - - -typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; - -size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) -{ - DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ - return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG); -} - - - -#endif /* FSE_COMMONDEFS_ONLY */ +/* ****************************************************************** + FSE : Finite State Entropy decoder + Copyright (C) 2013-2015, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ + + +/* ************************************************************** +* Includes +****************************************************************/ +#include /* malloc, free, qsort */ +#include /* memcpy, memset */ +#include "bitstream.h" +#include "compiler.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "error_private.h" + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError +#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ + +/* check and forward error code */ +#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; } + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + + +/* Function templates */ +FSE_DTable* FSE_createDTable (unsigned tableLog) +{ + if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; + return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); +} + +void FSE_freeDTable (FSE_DTable* dt) +{ + free(dt); +} + +size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ + FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); + U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; + + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + U32 highThreshold = tableSize-1; + + /* Sanity Checks */ + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + + /* Init, lay down lowprob symbols */ + { FSE_DTableHeader DTableH; + DTableH.tableLog = (U16)tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + symbolNext[s] = normalizedCounter[s]; + } } } + memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + { U32 const tableMask = tableSize-1; + U32 const step = FSE_TABLESTEP(tableSize); + U32 s, position = 0; + for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ + } } + if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { U32 u; + for (u=0; utableLog = 0; + DTableH->fastMode = 0; + + cell->newState = 0; + cell->symbol = symbolValue; + cell->nbBits = 0; + + return 0; +} + + +size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) +{ + void* ptr = dt; + FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; + void* dPtr = dt + 1; + FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr; + const unsigned tableSize = 1 << nbBits; + const unsigned tableMask = tableSize - 1; + const unsigned maxSV1 = tableMask+1; + unsigned s; + + /* Sanity checks */ + if (nbBits < 1) return ERROR(GENERIC); /* min size */ + + /* Build Decoding Table */ + DTableH->tableLog = (U16)nbBits; + DTableH->fastMode = 1; + for (s=0; s sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[1] = FSE_GETSYMBOL(&state2); + + if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } + + op[2] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[3] = FSE_GETSYMBOL(&state2); + } + + /* tail */ + /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ + while (1) { + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state1); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state2); + break; + } + + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state2); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state1); + break; + } } + + return op-ostart; +} + + +size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, + const void* cSrc, size_t cSrcSize, + const FSE_DTable* dt) +{ + const void* ptr = dt; + const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; + const U32 fastMode = DTableH->fastMode; + + /* select fast mode (static) */ + if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); + return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); +} + + +size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog) +{ + const BYTE* const istart = (const BYTE*)cSrc; + const BYTE* ip = istart; + short counting[FSE_MAX_SYMBOL_VALUE+1]; + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + + /* normal FSE decoding mode */ + size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + if (FSE_isError(NCountLength)) return NCountLength; + //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ + if (tableLog > maxLog) return ERROR(tableLog_tooLarge); + ip += NCountLength; + cSrcSize -= NCountLength; + + CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) ); + + return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ +} + + +typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; + +size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) +{ + DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ + return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG); +} + + + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/src/fse/hist.c b/src/fse/hist.c index 16524756..a5d83d89 100644 --- a/src/fse/hist.c +++ b/src/fse/hist.c @@ -1,195 +1,195 @@ -/* ****************************************************************** - hist : Histogram functions - part of Finite State Entropy project - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy - - Public forum : https://groups.google.com/forum/#!forum/lz4c -****************************************************************** */ - -/* --- dependencies --- */ -#include "mem.h" /* U32, BYTE, etc. */ -#include "debug.h" /* assert, DEBUGLOG */ -#include "error_private.h" /* ERROR */ -#include "hist.h" - - -/* --- Error management --- */ -unsigned HIST_isError(size_t code) { return ERR_isError(code); } - -/*-************************************************************** - * Histogram functions - ****************************************************************/ -unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, - const void* src, size_t srcSize) -{ - const BYTE* ip = (const BYTE*)src; - const BYTE* const end = ip + srcSize; - unsigned maxSymbolValue = *maxSymbolValuePtr; - unsigned largestCount=0; - - memset(count, 0, (maxSymbolValue+1) * sizeof(*count)); - if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; } - - while (ip largestCount) largestCount = count[s]; - } - - return largestCount; -} - - -/* HIST_count_parallel_wksp() : - * store histogram into 4 intermediate tables, recombined at the end. - * this design makes better use of OoO cpus, - * and is noticeably faster when some values are heavily repeated. - * But it needs some additional workspace for intermediate tables. - * `workSpace` size must be a table of size >= HIST_WKSP_SIZE_U32. - * @return : largest histogram frequency, - * or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */ -static size_t HIST_count_parallel_wksp( - unsigned* count, unsigned* maxSymbolValuePtr, - const void* source, size_t sourceSize, - unsigned checkMax, - unsigned* const workSpace) -{ - const BYTE* ip = (const BYTE*)source; - const BYTE* const iend = ip+sourceSize; - unsigned maxSymbolValue = *maxSymbolValuePtr; - unsigned max=0; - U32* const Counting1 = workSpace; - U32* const Counting2 = Counting1 + 256; - U32* const Counting3 = Counting2 + 256; - U32* const Counting4 = Counting3 + 256; - - memset(workSpace, 0, 4*256*sizeof(unsigned)); - - /* safety checks */ - if (!sourceSize) { - memset(count, 0, maxSymbolValue + 1); - *maxSymbolValuePtr = 0; - return 0; - } - if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */ - - /* by stripes of 16 bytes */ - { U32 cached = MEM_read32(ip); ip += 4; - while (ip < iend-15) { - U32 c = cached; cached = MEM_read32(ip); ip += 4; - Counting1[(BYTE) c ]++; - Counting2[(BYTE)(c>>8) ]++; - Counting3[(BYTE)(c>>16)]++; - Counting4[ c>>24 ]++; - c = cached; cached = MEM_read32(ip); ip += 4; - Counting1[(BYTE) c ]++; - Counting2[(BYTE)(c>>8) ]++; - Counting3[(BYTE)(c>>16)]++; - Counting4[ c>>24 ]++; - c = cached; cached = MEM_read32(ip); ip += 4; - Counting1[(BYTE) c ]++; - Counting2[(BYTE)(c>>8) ]++; - Counting3[(BYTE)(c>>16)]++; - Counting4[ c>>24 ]++; - c = cached; cached = MEM_read32(ip); ip += 4; - Counting1[(BYTE) c ]++; - Counting2[(BYTE)(c>>8) ]++; - Counting3[(BYTE)(c>>16)]++; - Counting4[ c>>24 ]++; - } - ip-=4; - } - - /* finish last symbols */ - while (ipmaxSymbolValue; s--) { - Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s]; - if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall); - } } - - { U32 s; - if (maxSymbolValue > 255) maxSymbolValue = 255; - for (s=0; s<=maxSymbolValue; s++) { - count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s]; - if (count[s] > max) max = count[s]; - } } - - while (!count[maxSymbolValue]) maxSymbolValue--; - *maxSymbolValuePtr = maxSymbolValue; - return (size_t)max; -} - -/* HIST_countFast_wksp() : - * Same as HIST_countFast(), but using an externally provided scratch buffer. - * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ -size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, - const void* source, size_t sourceSize, - unsigned* workSpace) -{ - if (sourceSize < 1500) /* heuristic threshold */ - return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize); - return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace); -} - -/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ -size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, - const void* source, size_t sourceSize) -{ - unsigned tmpCounters[HIST_WKSP_SIZE_U32]; - return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters); -} - -/* HIST_count_wksp() : - * Same as HIST_count(), but using an externally provided scratch buffer. - * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ -size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, - const void* source, size_t sourceSize, unsigned* workSpace) -{ - if (*maxSymbolValuePtr < 255) - return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace); - *maxSymbolValuePtr = 255; - return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace); -} - -size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, - const void* src, size_t srcSize) -{ - unsigned tmpCounters[HIST_WKSP_SIZE_U32]; - return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters); -} +/* ****************************************************************** + hist : Histogram functions + part of Finite State Entropy project + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ + +/* --- dependencies --- */ +#include "mem.h" /* U32, BYTE, etc. */ +#include "debug.h" /* assert, DEBUGLOG */ +#include "error_private.h" /* ERROR */ +#include "hist.h" + + +/* --- Error management --- */ +unsigned HIST_isError(size_t code) { return ERR_isError(code); } + +/*-************************************************************** + * Histogram functions + ****************************************************************/ +unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize) +{ + const BYTE* ip = (const BYTE*)src; + const BYTE* const end = ip + srcSize; + unsigned maxSymbolValue = *maxSymbolValuePtr; + unsigned largestCount=0; + + memset(count, 0, (maxSymbolValue+1) * sizeof(*count)); + if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; } + + while (ip largestCount) largestCount = count[s]; + } + + return largestCount; +} + + +/* HIST_count_parallel_wksp() : + * store histogram into 4 intermediate tables, recombined at the end. + * this design makes better use of OoO cpus, + * and is noticeably faster when some values are heavily repeated. + * But it needs some additional workspace for intermediate tables. + * `workSpace` size must be a table of size >= HIST_WKSP_SIZE_U32. + * @return : largest histogram frequency, + * or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */ +static size_t HIST_count_parallel_wksp( + unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + unsigned checkMax, + unsigned* const workSpace) +{ + const BYTE* ip = (const BYTE*)source; + const BYTE* const iend = ip+sourceSize; + unsigned maxSymbolValue = *maxSymbolValuePtr; + unsigned max=0; + U32* const Counting1 = workSpace; + U32* const Counting2 = Counting1 + 256; + U32* const Counting3 = Counting2 + 256; + U32* const Counting4 = Counting3 + 256; + + memset(workSpace, 0, 4*256*sizeof(unsigned)); + + /* safety checks */ + if (!sourceSize) { + memset(count, 0, maxSymbolValue + 1); + *maxSymbolValuePtr = 0; + return 0; + } + if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */ + + /* by stripes of 16 bytes */ + { U32 cached = MEM_read32(ip); ip += 4; + while (ip < iend-15) { + U32 c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + } + ip-=4; + } + + /* finish last symbols */ + while (ipmaxSymbolValue; s--) { + Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s]; + if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall); + } } + + { U32 s; + if (maxSymbolValue > 255) maxSymbolValue = 255; + for (s=0; s<=maxSymbolValue; s++) { + count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s]; + if (count[s] > max) max = count[s]; + } } + + while (!count[maxSymbolValue]) maxSymbolValue--; + *maxSymbolValuePtr = maxSymbolValue; + return (size_t)max; +} + +/* HIST_countFast_wksp() : + * Same as HIST_countFast(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ +size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + unsigned* workSpace) +{ + if (sourceSize < 1500) /* heuristic threshold */ + return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize); + return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace); +} + +/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters); +} + +/* HIST_count_wksp() : + * Same as HIST_count(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ +size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, unsigned* workSpace) +{ + if (*maxSymbolValuePtr < 255) + return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace); + *maxSymbolValuePtr = 255; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace); +} + +size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters); +} diff --git a/src/fse/hist.h b/src/fse/hist.h index 788470da..415bf2fc 100644 --- a/src/fse/hist.h +++ b/src/fse/hist.h @@ -1,92 +1,92 @@ -/* ****************************************************************** - hist : Histogram functions - part of Finite State Entropy project - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy - - Public forum : https://groups.google.com/forum/#!forum/lz4c -****************************************************************** */ - -/* --- dependencies --- */ -#include /* size_t */ - - -/* --- simple histogram functions --- */ - -/*! HIST_count(): - * Provides the precise count of each byte within a table 'count'. - * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1). - * Updates *maxSymbolValuePtr with actual largest symbol value detected. - * @return : count of the most frequent symbol (which isn't identified). - * or an error code, which can be tested using HIST_isError(). - * note : if return == srcSize, there is only one symbol. - */ -size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, - const void* src, size_t srcSize); - -unsigned HIST_isError(size_t code); /*< tells if a return value is an error code */ - - -/* --- advanced histogram functions --- */ - -#define HIST_WKSP_SIZE_U32 1024 -/** HIST_count_wksp() : - * Same as HIST_count(), but using an externally provided scratch buffer. - * Benefit is this function will use very little stack space. - * `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32 - */ -size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, - const void* src, size_t srcSize, - unsigned* workSpace); - -/** HIST_countFast() : - * same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr. - * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` - */ -size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, - const void* src, size_t srcSize); - -/** HIST_countFast_wksp() : - * Same as HIST_countFast(), but using an externally provided scratch buffer. - * `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32 - */ -size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, - const void* src, size_t srcSize, - unsigned* workSpace); - -/*! HIST_count_simple() : - * Same as HIST_countFast(), this function is unsafe, - * and will segfault if any value within `src` is `> *maxSymbolValuePtr`. - * It is also a bit slower for large inputs. - * However, it does not need any additional memory (not even on stack). - * @return : count of the most frequent symbol. - * Note this function doesn't produce any error (i.e. it must succeed). - */ -unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, - const void* src, size_t srcSize); +/* ****************************************************************** + hist : Histogram functions + part of Finite State Entropy project + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ + +/* --- dependencies --- */ +#include /* size_t */ + + +/* --- simple histogram functions --- */ + +/*! HIST_count(): + * Provides the precise count of each byte within a table 'count'. + * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1). + * Updates *maxSymbolValuePtr with actual largest symbol value detected. + * @return : count of the most frequent symbol (which isn't identified). + * or an error code, which can be tested using HIST_isError(). + * note : if return == srcSize, there is only one symbol. + */ +size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +unsigned HIST_isError(size_t code); /*< tells if a return value is an error code */ + + +/* --- advanced histogram functions --- */ + +#define HIST_WKSP_SIZE_U32 1024 +/** HIST_count_wksp() : + * Same as HIST_count(), but using an externally provided scratch buffer. + * Benefit is this function will use very little stack space. + * `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32 + */ +size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize, + unsigned* workSpace); + +/** HIST_countFast() : + * same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr. + * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` + */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +/** HIST_countFast_wksp() : + * Same as HIST_countFast(), but using an externally provided scratch buffer. + * `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32 + */ +size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize, + unsigned* workSpace); + +/*! HIST_count_simple() : + * Same as HIST_countFast(), this function is unsafe, + * and will segfault if any value within `src` is `> *maxSymbolValuePtr`. + * It is also a bit slower for large inputs. + * However, it does not need any additional memory (not even on stack). + * @return : count of the most frequent symbol. + * Note this function doesn't produce any error (i.e. it must succeed). + */ +unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); diff --git a/src/fse/huf.h b/src/fse/huf.h index de946411..a9e07d06 100644 --- a/src/fse/huf.h +++ b/src/fse/huf.h @@ -1,334 +1,334 @@ -/* ****************************************************************** - huff0 huffman codec, - part of Finite State Entropy library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - 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 - 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - -#if defined (__cplusplus) -extern "C" { -#endif - -#ifndef HUF_H_298734234 -#define HUF_H_298734234 - -/* *** Dependencies *** */ -#include /* size_t */ - - -/* *** library symbols visibility *** */ -/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual, - * HUF symbols remain "private" (internal symbols for library only). - * Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */ -#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) -# define HUF_PUBLIC_API __attribute__ ((visibility ("default"))) -#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ -# define HUF_PUBLIC_API __declspec(dllexport) -#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) -# define HUF_PUBLIC_API __declspec(dllimport) /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */ -#else -# define HUF_PUBLIC_API -#endif - - -/* ========================== */ -/* *** simple functions *** */ -/* ========================== */ - -/** HUF_compress() : - * Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'. - * 'dst' buffer must be already allocated. - * Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize). - * `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB. - * @return : size of compressed data (<= `dstCapacity`). - * Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! - * if HUF_isError(return), compression failed (more details using HUF_getErrorName()) - */ -HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity, - const void* src, size_t srcSize); - -/** HUF_decompress() : - * Decompress HUF data from buffer 'cSrc', of size 'cSrcSize', - * into already allocated buffer 'dst', of minimum size 'dstSize'. - * `originalSize` : **must** be the ***exact*** size of original (uncompressed) data. - * Note : in contrast with FSE, HUF_decompress can regenerate - * RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, - * because it knows size to regenerate (originalSize). - * @return : size of regenerated data (== originalSize), - * or an error code, which can be tested using HUF_isError() - */ -HUF_PUBLIC_API size_t HUF_decompress(void* dst, size_t originalSize, - const void* cSrc, size_t cSrcSize); - - -/* *** Tool functions *** */ -#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ -HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ - -/* Error Management */ -HUF_PUBLIC_API unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */ -HUF_PUBLIC_API const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */ - - -/* *** Advanced function *** */ - -/** HUF_compress2() : - * Same as HUF_compress(), but offers control over `maxSymbolValue` and `tableLog`. - * `maxSymbolValue` must be <= HUF_SYMBOLVALUE_MAX . - * `tableLog` must be `<= HUF_TABLELOG_MAX` . */ -HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned tableLog); - -/** HUF_compress4X_wksp() : - * Same as HUF_compress2(), but uses externally allocated `workSpace`. - * `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */ -#define HUF_WORKSPACE_SIZE (6 << 10) -#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) -HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned tableLog, - void* workSpace, size_t wkspSize); - -#endif /* HUF_H_298734234 */ - -/* ****************************************************************** - * WARNING !! - * The following section contains advanced and experimental definitions - * which shall never be used in the context of a dynamic library, - * because they are not guaranteed to remain stable in the future. - * Only consider them in association with static linking. - * *****************************************************************/ -#if defined(HUF_STATIC_LINKING_ONLY) && !defined(HUF_H_HUF_STATIC_LINKING_ONLY) -#define HUF_H_HUF_STATIC_LINKING_ONLY - -/* *** Dependencies *** */ -#include "mem.h" /* U32 */ - - -/* *** Constants *** */ -#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */ -#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ -#define HUF_SYMBOLVALUE_MAX 255 - -#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ -#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) -# error "HUF_TABLELOG_MAX is too large !" -#endif - - -/* **************************************** -* Static allocation -******************************************/ -/* HUF buffer bounds */ -#define HUF_CTABLEBOUND 129 -#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */ -#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ - -/* static allocation of HUF's Compression Table */ -#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */ -#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32)) -#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ - U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \ - void* name##hv = &(name##hb); \ - HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */ - -/* static allocation of HUF's DTable */ -typedef U32 HUF_DTable; -#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) -#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \ - HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } -#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ - HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } - - -/* **************************************** -* Advanced decompression functions -******************************************/ -size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ - -size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */ -size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */ -size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and uncompressed as errors */ -size_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ -size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ -size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ - - -/* **************************************** - * HUF detailed API - * ****************************************/ - -/*! HUF_compress() does the following: - * 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h") - * 2. (optional) refine tableLog using HUF_optimalTableLog() - * 3. build Huffman table from count using HUF_buildCTable() - * 4. save Huffman table to memory buffer using HUF_writeCTable() - * 5. encode the data stream using HUF_compress4X_usingCTable() - * - * The following API allows targeting specific sub-functions for advanced tasks. - * For example, it's possible to compress several blocks using the same 'CTable', - * or to save and regenerate 'CTable' using external methods. - */ -unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); -typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */ -size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */ -size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog); -size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); - -typedef enum { - HUF_repeat_none, /**< Cannot use the previous table */ - HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */ - HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */ - } HUF_repeat; -/** HUF_compress4X_repeat() : - * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. - * If it uses hufTable it does not modify hufTable or repeat. - * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. - * If preferRepeat then the old table will always be used if valid. */ -size_t HUF_compress4X_repeat(void* dst, size_t dstSize, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned tableLog, - void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ - HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); - -/** HUF_buildCTable_wksp() : - * Same as HUF_buildCTable(), but using externally allocated scratch buffer. - * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE. - */ -#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1) -#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned)) -size_t HUF_buildCTable_wksp (HUF_CElt* tree, - const U32* count, U32 maxSymbolValue, U32 maxNbBits, - void* workSpace, size_t wkspSize); - -/*! HUF_readStats() : - * Read compact Huffman tree, saved by HUF_writeCTable(). - * `huffWeight` is destination buffer. - * @return : size read from `src` , or an error Code . - * Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ -size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, - U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, - const void* src, size_t srcSize); - -/** HUF_readCTable() : - * Loading a CTable saved with HUF_writeCTable() */ -size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); - -/** HUF_getNbBits() : - * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX - * Note 1 : is not inlined, as HUF_CElt definition is private - * Note 2 : const void* used, so that it can provide a statically allocated table as argument (which uses type U32) */ -U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue); - -/* - * HUF_decompress() does the following: - * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics - * 2. build Huffman table from save, using HUF_readDTableX?() - * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable() - */ - -/** HUF_selectDecoder() : - * Tells which decoder is likely to decode faster, - * based on a set of pre-computed metrics. - * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . - * Assumption : 0 < dstSize <= 128 KB */ -U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize); - -/** - * The minimum workspace size for the `workSpace` used in - * HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp(). - * - * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when - * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. - * Buffer overflow errors may potentially occur if code modifications result in - * a required workspace size greater than that specified in the following - * macro. - */ -#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10) -#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) - -size_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize); -size_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); -size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize); -size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); - -size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); - - -/* ====================== */ -/* single stream variants */ -/* ====================== */ - -size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); -size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ -size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); -/** HUF_compress1X_repeat() : - * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. - * If it uses hufTable it does not modify hufTable or repeat. - * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. - * If preferRepeat then the old table will always be used if valid. */ -size_t HUF_compress1X_repeat(void* dst, size_t dstSize, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned tableLog, - void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ - HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); - -size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ -size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ - -size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); -size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); -size_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ -size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ -size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ - -size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ -size_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); - -/* BMI2 variants. - * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. - */ -size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); -size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); -size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); -size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); - -#endif /* HUF_STATIC_LINKING_ONLY */ - -#if defined (__cplusplus) -} -#endif +/* ****************************************************************** + huff0 huffman codec, + part of Finite State Entropy library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + 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 + 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. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef HUF_H_298734234 +#define HUF_H_298734234 + +/* *** Dependencies *** */ +#include /* size_t */ + + +/* *** library symbols visibility *** */ +/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual, + * HUF symbols remain "private" (internal symbols for library only). + * Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */ +#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) +# define HUF_PUBLIC_API __attribute__ ((visibility ("default"))) +#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ +# define HUF_PUBLIC_API __declspec(dllexport) +#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) +# define HUF_PUBLIC_API __declspec(dllimport) /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */ +#else +# define HUF_PUBLIC_API +#endif + + +/* ========================== */ +/* *** simple functions *** */ +/* ========================== */ + +/** HUF_compress() : + * Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'. + * 'dst' buffer must be already allocated. + * Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize). + * `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB. + * @return : size of compressed data (<= `dstCapacity`). + * Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! + * if HUF_isError(return), compression failed (more details using HUF_getErrorName()) + */ +HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +/** HUF_decompress() : + * Decompress HUF data from buffer 'cSrc', of size 'cSrcSize', + * into already allocated buffer 'dst', of minimum size 'dstSize'. + * `originalSize` : **must** be the ***exact*** size of original (uncompressed) data. + * Note : in contrast with FSE, HUF_decompress can regenerate + * RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, + * because it knows size to regenerate (originalSize). + * @return : size of regenerated data (== originalSize), + * or an error code, which can be tested using HUF_isError() + */ +HUF_PUBLIC_API size_t HUF_decompress(void* dst, size_t originalSize, + const void* cSrc, size_t cSrcSize); + + +/* *** Tool functions *** */ +#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ +HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ + +/* Error Management */ +HUF_PUBLIC_API unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */ +HUF_PUBLIC_API const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */ + + +/* *** Advanced function *** */ + +/** HUF_compress2() : + * Same as HUF_compress(), but offers control over `maxSymbolValue` and `tableLog`. + * `maxSymbolValue` must be <= HUF_SYMBOLVALUE_MAX . + * `tableLog` must be `<= HUF_TABLELOG_MAX` . */ +HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog); + +/** HUF_compress4X_wksp() : + * Same as HUF_compress2(), but uses externally allocated `workSpace`. + * `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */ +#define HUF_WORKSPACE_SIZE (6 << 10) +#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) +HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize); + +#endif /* HUF_H_298734234 */ + +/* ****************************************************************** + * WARNING !! + * The following section contains advanced and experimental definitions + * which shall never be used in the context of a dynamic library, + * because they are not guaranteed to remain stable in the future. + * Only consider them in association with static linking. + * *****************************************************************/ +#if defined(HUF_STATIC_LINKING_ONLY) && !defined(HUF_H_HUF_STATIC_LINKING_ONLY) +#define HUF_H_HUF_STATIC_LINKING_ONLY + +/* *** Dependencies *** */ +#include "mem.h" /* U32 */ + + +/* *** Constants *** */ +#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */ +#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ +#define HUF_SYMBOLVALUE_MAX 255 + +#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) +# error "HUF_TABLELOG_MAX is too large !" +#endif + + +/* **************************************** +* Static allocation +******************************************/ +/* HUF buffer bounds */ +#define HUF_CTABLEBOUND 129 +#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */ +#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* static allocation of HUF's Compression Table */ +#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */ +#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32)) +#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ + U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \ + void* name##hv = &(name##hb); \ + HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */ + +/* static allocation of HUF's DTable */ +typedef U32 HUF_DTable; +#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) +#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } +#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } + + +/* **************************************** +* Advanced decompression functions +******************************************/ +size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ + +size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */ +size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */ +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and uncompressed as errors */ +size_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ +size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ + + +/* **************************************** + * HUF detailed API + * ****************************************/ + +/*! HUF_compress() does the following: + * 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h") + * 2. (optional) refine tableLog using HUF_optimalTableLog() + * 3. build Huffman table from count using HUF_buildCTable() + * 4. save Huffman table to memory buffer using HUF_writeCTable() + * 5. encode the data stream using HUF_compress4X_usingCTable() + * + * The following API allows targeting specific sub-functions for advanced tasks. + * For example, it's possible to compress several blocks using the same 'CTable', + * or to save and regenerate 'CTable' using external methods. + */ +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); +typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */ +size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */ +size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog); +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); + +typedef enum { + HUF_repeat_none, /**< Cannot use the previous table */ + HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */ + HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */ + } HUF_repeat; +/** HUF_compress4X_repeat() : + * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. */ +size_t HUF_compress4X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE. + */ +#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1) +#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_buildCTable_wksp (HUF_CElt* tree, + const U32* count, U32 maxSymbolValue, U32 maxNbBits, + void* workSpace, size_t wkspSize); + +/*! HUF_readStats() : + * Read compact Huffman tree, saved by HUF_writeCTable(). + * `huffWeight` is destination buffer. + * @return : size read from `src` , or an error Code . + * Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize); + +/** HUF_readCTable() : + * Loading a CTable saved with HUF_writeCTable() */ +size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); + +/** HUF_getNbBits() : + * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX + * Note 1 : is not inlined, as HUF_CElt definition is private + * Note 2 : const void* used, so that it can provide a statically allocated table as argument (which uses type U32) */ +U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue); + +/* + * HUF_decompress() does the following: + * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics + * 2. build Huffman table from save, using HUF_readDTableX?() + * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable() + */ + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize); + +/** + * The minimum workspace size for the `workSpace` used in + * HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp(). + * + * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when + * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. + * Buffer overflow errors may potentially occur if code modifications result in + * a required workspace size greater than that specified in the following + * macro. + */ +#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10) +#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) + +size_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize); +size_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); +size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize); +size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); + +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); +size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); +size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); + + +/* ====================== */ +/* single stream variants */ +/* ====================== */ + +size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); +size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); +/** HUF_compress1X_repeat() : + * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. */ +size_t HUF_compress1X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); + +size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ +size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ + +size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); +size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); +size_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ +size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ + +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ +size_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); +size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); + +/* BMI2 variants. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); +size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); +size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); +size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); + +#endif /* HUF_STATIC_LINKING_ONLY */ + +#if defined (__cplusplus) +} +#endif diff --git a/src/fse/mem.h b/src/fse/mem.h index 47d23001..33b4a9ee 100644 --- a/src/fse/mem.h +++ b/src/fse/mem.h @@ -1,362 +1,362 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -#ifndef MEM_H_MODULE -#define MEM_H_MODULE - -#if defined (__cplusplus) -extern "C" { -#endif - -/*-**************************************** -* Dependencies -******************************************/ -#include /* size_t, ptrdiff_t */ -#include /* memcpy */ - - -/*-**************************************** -* Compiler specifics -******************************************/ -#if defined(_MSC_VER) /* Visual Studio */ -# include /* _byteswap_ulong */ -# include /* _byteswap_* */ -#endif -#if defined(__GNUC__) -# define MEM_STATIC static __inline __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define MEM_STATIC static inline -#elif defined(_MSC_VER) -# define MEM_STATIC static __inline -#else -# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif - -/* code only tested on 32 and 64 bits systems */ -#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; } -MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } - - -/*-************************************************************** -* Basic Types -*****************************************************************/ -#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef int16_t S16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; - typedef int64_t S64; -#else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef signed short S16; - typedef unsigned int U32; - typedef signed int S32; - typedef unsigned long long U64; - typedef signed long long S64; -#endif - - -/*-************************************************************** -* Memory I/O -*****************************************************************/ -/* MEM_FORCE_MEMORY_ACCESS : - * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. - * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. - * The below switch allow to select different access method for improved performance. - * Method 0 (default) : use `memcpy()`. Safe and portable. - * Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable). - * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. - * Method 2 : direct access. This method is portable but violate C standard. - * It can generate buggy code on targets depending on alignment. - * In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6) - * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. - * Prefer these methods in priority order (0 > 1 > 2) - */ -#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define MEM_FORCE_MEMORY_ACCESS 2 -# elif defined(__INTEL_COMPILER) || defined(__GNUC__) -# define MEM_FORCE_MEMORY_ACCESS 1 -# endif -#endif - -MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } -MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } - -MEM_STATIC unsigned MEM_isLittleEndian(void) -{ - const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ - return one.c[0]; -} - -#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) - -/* violates C standard, by lying on structure alignment. -Only use if no other choice to achieve best performance on target platform */ -MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } -MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } -MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } -MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; } - -MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } -MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } -MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } - -#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32)) - __pragma( pack(push, 1) ) - typedef struct { U16 v; } unalign16; - typedef struct { U32 v; } unalign32; - typedef struct { U64 v; } unalign64; - typedef struct { size_t v; } unalignArch; - __pragma( pack(pop) ) -#else - typedef struct { U16 v; } __attribute__((packed)) unalign16; - typedef struct { U32 v; } __attribute__((packed)) unalign32; - typedef struct { U64 v; } __attribute__((packed)) unalign64; - typedef struct { size_t v; } __attribute__((packed)) unalignArch; -#endif - -MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign16*)ptr)->v; } -MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign32*)ptr)->v; } -MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign64*)ptr)->v; } -MEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalignArch*)ptr)->v; } - -MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign16*)memPtr)->v = value; } -MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign32*)memPtr)->v = value; } -MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = value; } - -#else - -/* default method, safe and standard. - can sometimes prove slower */ - -MEM_STATIC U16 MEM_read16(const void* memPtr) -{ - U16 val; memcpy(&val, memPtr, sizeof(val)); return val; -} - -MEM_STATIC U32 MEM_read32(const void* memPtr) -{ - U32 val; memcpy(&val, memPtr, sizeof(val)); return val; -} - -MEM_STATIC U64 MEM_read64(const void* memPtr) -{ - U64 val; memcpy(&val, memPtr, sizeof(val)); return val; -} - -MEM_STATIC size_t MEM_readST(const void* memPtr) -{ - size_t val; memcpy(&val, memPtr, sizeof(val)); return val; -} - -MEM_STATIC void MEM_write16(void* memPtr, U16 value) -{ - memcpy(memPtr, &value, sizeof(value)); -} - -MEM_STATIC void MEM_write32(void* memPtr, U32 value) -{ - memcpy(memPtr, &value, sizeof(value)); -} - -MEM_STATIC void MEM_write64(void* memPtr, U64 value) -{ - memcpy(memPtr, &value, sizeof(value)); -} - -#endif /* MEM_FORCE_MEMORY_ACCESS */ - -MEM_STATIC U32 MEM_swap32(U32 in) -{ -#if defined(_MSC_VER) /* Visual Studio */ - return _byteswap_ulong(in); -#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) - return __builtin_bswap32(in); -#else - return ((in << 24) & 0xff000000 ) | - ((in << 8) & 0x00ff0000 ) | - ((in >> 8) & 0x0000ff00 ) | - ((in >> 24) & 0x000000ff ); -#endif -} - -MEM_STATIC U64 MEM_swap64(U64 in) -{ -#if defined(_MSC_VER) /* Visual Studio */ - return _byteswap_uint64(in); -#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) - return __builtin_bswap64(in); -#else - return ((in << 56) & 0xff00000000000000ULL) | - ((in << 40) & 0x00ff000000000000ULL) | - ((in << 24) & 0x0000ff0000000000ULL) | - ((in << 8) & 0x000000ff00000000ULL) | - ((in >> 8) & 0x00000000ff000000ULL) | - ((in >> 24) & 0x0000000000ff0000ULL) | - ((in >> 40) & 0x000000000000ff00ULL) | - ((in >> 56) & 0x00000000000000ffULL); -#endif -} - -MEM_STATIC size_t MEM_swapST(size_t in) -{ - if (MEM_32bits()) - return (size_t)MEM_swap32((U32)in); - else - return (size_t)MEM_swap64((U64)in); -} - -/*=== Little endian r/w ===*/ - -MEM_STATIC U16 MEM_readLE16(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_read16(memPtr); - else { - const BYTE* p = (const BYTE*)memPtr; - return (U16)(p[0] + (p[1]<<8)); - } -} - -MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) -{ - if (MEM_isLittleEndian()) { - MEM_write16(memPtr, val); - } else { - BYTE* p = (BYTE*)memPtr; - p[0] = (BYTE)val; - p[1] = (BYTE)(val>>8); - } -} - -MEM_STATIC U32 MEM_readLE24(const void* memPtr) -{ - return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16); -} - -MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val) -{ - MEM_writeLE16(memPtr, (U16)val); - ((BYTE*)memPtr)[2] = (BYTE)(val>>16); -} - -MEM_STATIC U32 MEM_readLE32(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_read32(memPtr); - else - return MEM_swap32(MEM_read32(memPtr)); -} - -MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32) -{ - if (MEM_isLittleEndian()) - MEM_write32(memPtr, val32); - else - MEM_write32(memPtr, MEM_swap32(val32)); -} - -MEM_STATIC U64 MEM_readLE64(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_read64(memPtr); - else - return MEM_swap64(MEM_read64(memPtr)); -} - -MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64) -{ - if (MEM_isLittleEndian()) - MEM_write64(memPtr, val64); - else - MEM_write64(memPtr, MEM_swap64(val64)); -} - -MEM_STATIC size_t MEM_readLEST(const void* memPtr) -{ - if (MEM_32bits()) - return (size_t)MEM_readLE32(memPtr); - else - return (size_t)MEM_readLE64(memPtr); -} - -MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val) -{ - if (MEM_32bits()) - MEM_writeLE32(memPtr, (U32)val); - else - MEM_writeLE64(memPtr, (U64)val); -} - -/*=== Big endian r/w ===*/ - -MEM_STATIC U32 MEM_readBE32(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_swap32(MEM_read32(memPtr)); - else - return MEM_read32(memPtr); -} - -MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32) -{ - if (MEM_isLittleEndian()) - MEM_write32(memPtr, MEM_swap32(val32)); - else - MEM_write32(memPtr, val32); -} - -MEM_STATIC U64 MEM_readBE64(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_swap64(MEM_read64(memPtr)); - else - return MEM_read64(memPtr); -} - -MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64) -{ - if (MEM_isLittleEndian()) - MEM_write64(memPtr, MEM_swap64(val64)); - else - MEM_write64(memPtr, val64); -} - -MEM_STATIC size_t MEM_readBEST(const void* memPtr) -{ - if (MEM_32bits()) - return (size_t)MEM_readBE32(memPtr); - else - return (size_t)MEM_readBE64(memPtr); -} - -MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) -{ - if (MEM_32bits()) - MEM_writeBE32(memPtr, (U32)val); - else - MEM_writeBE64(memPtr, (U64)val); -} - - -#if defined (__cplusplus) -} -#endif - -#endif /* MEM_H_MODULE */ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef MEM_H_MODULE +#define MEM_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + +/*-**************************************** +* Dependencies +******************************************/ +#include /* size_t, ptrdiff_t */ +#include /* memcpy */ + + +/*-**************************************** +* Compiler specifics +******************************************/ +#if defined(_MSC_VER) /* Visual Studio */ +# include /* _byteswap_ulong */ +# include /* _byteswap_* */ +#endif +#if defined(__GNUC__) +# define MEM_STATIC static __inline __attribute__((unused)) +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define MEM_STATIC static inline +#elif defined(_MSC_VER) +# define MEM_STATIC static __inline +#else +# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif + +/* code only tested on 32 and 64 bits systems */ +#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; } +MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } + + +/*-************************************************************** +* Basic Types +*****************************************************************/ +#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef int16_t S16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; + typedef int64_t S64; +#else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef signed short S16; + typedef unsigned int U32; + typedef signed int S32; + typedef unsigned long long U64; + typedef signed long long S64; +#endif + + +/*-************************************************************** +* Memory I/O +*****************************************************************/ +/* MEM_FORCE_MEMORY_ACCESS : + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets depending on alignment. + * In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6) + * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define MEM_FORCE_MEMORY_ACCESS 2 +# elif defined(__INTEL_COMPILER) || defined(__GNUC__) +# define MEM_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } +MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } + +MEM_STATIC unsigned MEM_isLittleEndian(void) +{ + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +} + +#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) + +/* violates C standard, by lying on structure alignment. +Only use if no other choice to achieve best performance on target platform */ +MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } +MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } +MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } +MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } + +#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32)) + __pragma( pack(push, 1) ) + typedef struct { U16 v; } unalign16; + typedef struct { U32 v; } unalign32; + typedef struct { U64 v; } unalign64; + typedef struct { size_t v; } unalignArch; + __pragma( pack(pop) ) +#else + typedef struct { U16 v; } __attribute__((packed)) unalign16; + typedef struct { U32 v; } __attribute__((packed)) unalign32; + typedef struct { U64 v; } __attribute__((packed)) unalign64; + typedef struct { size_t v; } __attribute__((packed)) unalignArch; +#endif + +MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign16*)ptr)->v; } +MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign32*)ptr)->v; } +MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign64*)ptr)->v; } +MEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalignArch*)ptr)->v; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign16*)memPtr)->v = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign32*)memPtr)->v = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = value; } + +#else + +/* default method, safe and standard. + can sometimes prove slower */ + +MEM_STATIC U16 MEM_read16(const void* memPtr) +{ + U16 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U32 MEM_read32(const void* memPtr) +{ + U32 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U64 MEM_read64(const void* memPtr) +{ + U64 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC size_t MEM_readST(const void* memPtr) +{ + size_t val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write32(void* memPtr, U32 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write64(void* memPtr, U64 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* MEM_FORCE_MEMORY_ACCESS */ + +MEM_STATIC U32 MEM_swap32(U32 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_ulong(in); +#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) + return __builtin_bswap32(in); +#else + return ((in << 24) & 0xff000000 ) | + ((in << 8) & 0x00ff0000 ) | + ((in >> 8) & 0x0000ff00 ) | + ((in >> 24) & 0x000000ff ); +#endif +} + +MEM_STATIC U64 MEM_swap64(U64 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_uint64(in); +#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) + return __builtin_bswap64(in); +#else + return ((in << 56) & 0xff00000000000000ULL) | + ((in << 40) & 0x00ff000000000000ULL) | + ((in << 24) & 0x0000ff0000000000ULL) | + ((in << 8) & 0x000000ff00000000ULL) | + ((in >> 8) & 0x00000000ff000000ULL) | + ((in >> 24) & 0x0000000000ff0000ULL) | + ((in >> 40) & 0x000000000000ff00ULL) | + ((in >> 56) & 0x00000000000000ffULL); +#endif +} + +MEM_STATIC size_t MEM_swapST(size_t in) +{ + if (MEM_32bits()) + return (size_t)MEM_swap32((U32)in); + else + return (size_t)MEM_swap64((U64)in); +} + +/*=== Little endian r/w ===*/ + +MEM_STATIC U16 MEM_readLE16(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read16(memPtr); + else { + const BYTE* p = (const BYTE*)memPtr; + return (U16)(p[0] + (p[1]<<8)); + } +} + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) +{ + if (MEM_isLittleEndian()) { + MEM_write16(memPtr, val); + } else { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE)val; + p[1] = (BYTE)(val>>8); + } +} + +MEM_STATIC U32 MEM_readLE24(const void* memPtr) +{ + return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16); +} + +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val) +{ + MEM_writeLE16(memPtr, (U16)val); + ((BYTE*)memPtr)[2] = (BYTE)(val>>16); +} + +MEM_STATIC U32 MEM_readLE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read32(memPtr); + else + return MEM_swap32(MEM_read32(memPtr)); +} + +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, val32); + else + MEM_write32(memPtr, MEM_swap32(val32)); +} + +MEM_STATIC U64 MEM_readLE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read64(memPtr); + else + return MEM_swap64(MEM_read64(memPtr)); +} + +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, val64); + else + MEM_write64(memPtr, MEM_swap64(val64)); +} + +MEM_STATIC size_t MEM_readLEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readLE32(memPtr); + else + return (size_t)MEM_readLE64(memPtr); +} + +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeLE32(memPtr, (U32)val); + else + MEM_writeLE64(memPtr, (U64)val); +} + +/*=== Big endian r/w ===*/ + +MEM_STATIC U32 MEM_readBE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap32(MEM_read32(memPtr)); + else + return MEM_read32(memPtr); +} + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, MEM_swap32(val32)); + else + MEM_write32(memPtr, val32); +} + +MEM_STATIC U64 MEM_readBE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap64(MEM_read64(memPtr)); + else + return MEM_read64(memPtr); +} + +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, MEM_swap64(val64)); + else + MEM_write64(memPtr, val64); +} + +MEM_STATIC size_t MEM_readBEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readBE32(memPtr); + else + return (size_t)MEM_readBE64(memPtr); +} + +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeBE32(memPtr, (U32)val); + else + MEM_writeBE64(memPtr, (U64)val); +} + + +#if defined (__cplusplus) +} +#endif + +#endif /* MEM_H_MODULE */ diff --git a/src/io/BucketStream.cpp b/src/io/BucketStream.cpp new file mode 100644 index 00000000..f6078c8a --- /dev/null +++ b/src/io/BucketStream.cpp @@ -0,0 +1,204 @@ +#include "BucketStream.h" +#include "util/Util.h" + + //----------------------------------------------------------- + BucketStream::BucketStream( IStream& baseStream, const size_t sliceSize, const uint32 numBuckets ) + : _baseStream ( baseStream ) + , _sequentialSlices ( bbcalloc( numBuckets ), numBuckets ) + , _interleavedSlices( bbcalloc( numBuckets ), numBuckets ) + , _sliceCapacity ( sliceSize ) + , _bucketCapacity ( sliceSize * numBuckets ) + , _numBuckets ( numBuckets ) +{ + const size_t sliceCount = numBuckets * (size_t)numBuckets; + + size_t* seqSliceBuffer = bbcalloc( sliceCount ); + size_t* intSliceBuffer = bbcalloc( sliceCount ); + ZeroMem( seqSliceBuffer, sliceCount ); + ZeroMem( intSliceBuffer, sliceCount ); + + for( uint32 i = 0; i < numBuckets; i++ ) + { + _sequentialSlices [i] = seqSliceBuffer; + _interleavedSlices[i] = intSliceBuffer; + + seqSliceBuffer += numBuckets; + intSliceBuffer += numBuckets; + } + } + + //----------------------------------------------------------- + BucketStream::~BucketStream() + { + free( _sequentialSlices [0] ); + free( _interleavedSlices[0] ); + free( _sequentialSlices .Ptr() ); + free( _interleavedSlices.Ptr() ); + } + + //----------------------------------------------------------- + void BucketStream::WriteBucketSlices( const void* slices, const uint32* sliceSizes ) + { + const byte* sliceBytes = (byte*)slices; + + IStream& stream = _baseStream; + + if( GetWriteMode() == Sequential ) + { + // Write slices across all buckets. That is, each bucket contains its own slices + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + const int64 offset = (int64)( bucket * _bucketCapacity + _writeSlice * _sliceCapacity ); //bucket * (int64)_bucketCapacity + (int64)_slices[i][0].size; + PanicIf( !stream.Seek( offset, SeekOrigin::Begin ), "Base stream failed to seek." ); + + const size_t size = sliceSizes[bucket]; + ASSERT( size <= _sliceCapacity ); + + // #TODO: Loop write, or use IOJob + PanicIf( stream.Write( sliceBytes, size ) != (ssize_t)size, "Failed to write slice to base stream." ); + + _sequentialSlices[bucket][_writeSlice] = size; + sliceBytes += size; + } + + _writeSlice++; + } + else + { + // Interleaved writes. This means that we will fill each bucket + // with slices that belong to all buckets, not just he bukcket's own slices. + // ie. Bucket 0 will have slices from bucket, 0, 1, 2... and so on. + + // #NOTE: We can't just write the whole bucket-full because we need to have each slice + // separated by its full slice capacity so that we don't overwrite any data + // during the next sequential write. + const size_t bucketOffset = _writeBucket * _bucketCapacity; + + for( uint32 slice = 0; slice < _numBuckets; slice++ ) + { + const int64 offset = (int64)( bucketOffset + slice * _sliceCapacity ); + PanicIf( !stream.Seek( offset, SeekOrigin::Begin ), "Base stream failed to seek." ); + + const size_t size = sliceSizes[slice]; + ASSERT( size <= _sliceCapacity ); + + // #TODO: Loop write, or use IOJob + PanicIf( stream.Write( sliceBytes, size ) != (ssize_t)size, "Failed to write slice to base stream." ); + _interleavedSlices[_writeBucket][slice] = size; + sliceBytes += size; + } + + _writeBucket++; + } + } + + //----------------------------------------------------------- + void BucketStream::ReadBucket( const size_t size, void* readBuffer ) + { + ASSERT( _readBucket < _numBuckets ); + ASSERT( size ); + ASSERT( readBuffer ); + // #TODO: Remove the read size... We don't need that here... + + byte* buffer = (byte*)readBuffer; + IStream& stream = _baseStream; + + if( GetReadMode() == Sequential ) + { + // Read all slices from the same bucket + const size_t _bucketStart = _readBucket * _bucketCapacity; + + for( uint32 slice = 0; slice < _numBuckets; slice++ ) + { + const int64 offset = (int64)(_bucketStart + slice * _sliceCapacity ); + PanicIf( !stream.Seek( offset, SeekOrigin::Begin ), "Failed to seek for reading." ); + + // #TODO: Loop read, or use IOJob + const size_t sliceSize = _sequentialSlices[_readBucket][slice]; + const ssize_t sizeRead = stream.Read( buffer, sliceSize ); + PanicIf( sizeRead != (ssize_t)sliceSize, "Failed to read slice %u of bucket %u.", slice, (uint32)_readBucket ); + + buffer += sliceSize; + } + + _readBucket++; + } + else + { + // Read a whole bucket's worth of bytes by reading slices spread across all buckets + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + const int64 offset = (int64)( bucket * _bucketCapacity + _readSlice * _sliceCapacity ); + PanicIf( !_baseStream.Seek( offset, SeekOrigin::Begin ), "Failed to seek for reading." ); + + // #TODO: Loop read, or use IOJob + const size_t sliceSize = _interleavedSlices[bucket][_readSlice]; + const ssize_t sizeRead = _baseStream.Read( buffer, sliceSize ); + PanicIf( sizeRead != (ssize_t)sliceSize, "Failed to read slice %u of bucket %u.", (uint32)_readSlice, bucket ); + + buffer += sliceSize; + } + + _readSlice++; + } + } + + //----------------------------------------------------------- + ssize_t BucketStream::Read( void* buffer, size_t size ) + { + ASSERT( 0 ); + return 0; // Can only read bucket + } + + //----------------------------------------------------------- + ssize_t BucketStream::Write( const void* buffer, size_t size ) + { + ASSERT( 0 ); + return 0; // Can only write bucket + } + + //----------------------------------------------------------- + bool BucketStream::Seek( int64 offset, SeekOrigin origin ) + { + if( origin == SeekOrigin::Begin && offset == 0 ) + { + _readBucket = 0; + _writeBucket = 0; + + SwitchMode(); + return true; + } + + return false; + } + + //----------------------------------------------------------- + bool BucketStream::Flush() + { + return false; + } + + //----------------------------------------------------------- + inline size_t BucketStream::BlockSize() const + { + return _baseStream.BlockSize(); + } + + //----------------------------------------------------------- + ssize_t BucketStream::Size() + { + return 0; + } + + //----------------------------------------------------------- + bool BucketStream::Truncate( const ssize_t length ) + { + return false; + } + + //----------------------------------------------------------- + int BucketStream::GetError() + { + return 0; + } + diff --git a/src/io/BucketStream.h b/src/io/BucketStream.h new file mode 100644 index 00000000..e17e8416 --- /dev/null +++ b/src/io/BucketStream.h @@ -0,0 +1,74 @@ +#include "IStream.h" + +class BucketStream : public IStream +{ +public: + enum Mode + { + Sequential = 0, + Interleaved + }; + + BucketStream( IStream& baseStream, const size_t sliceSize, const uint32 numBuckets ); + + virtual ~BucketStream(); + + ssize_t Read( void* buffer, size_t size ) override; + + ssize_t Write( const void* buffer, size_t size ) override; + + void WriteBucketSlices( const void* slices, const uint32* sliceSizes ); + + void ReadBucket( const size_t size, void* readBuffer ); + + bool Seek( int64 offset, SeekOrigin origin ) override; + + bool Flush() override; + + size_t BlockSize() const override; + + ssize_t Size() override; + + bool Truncate( const ssize_t length ) override; + + int GetError() override; + + inline Mode GetWriteMode() const { return _writeMode; } + inline Mode GetReadMode() const { return (Mode)(((uint32)_writeMode + 1) & 1); } + +private: + inline void SwitchMode() + { + _writeMode = (Mode)(((uint32)_writeMode + 1) & 1); // (mode + 1) % 2 + } + + struct Slice + { + uint32 position; + uint32 size; + }; +private: + IStream& _baseStream; // Backing stream where we actually write data + Span _sequentialSlices; // Info about each bucket slice + Span _interleavedSlices; // Info about each bucket slice + size_t _sliceCapacity; // Maximum size of a single bucket slice + size_t _bucketCapacity; // Maximum capacity of a single bucket + uint32 _numBuckets; + + // Keep track of current bucket or slice. These are + // opposite to each other depending on the current mode being used. + // In sequential mode you write in slices across all buckets, and read in buckets. + // In interleaved mode you write in buckets and read in slices across all buckets. + union { + uint16 _writeSlice = 0; + uint16 _writeBucket; + }; + + union { + uint16 _readSlice = 0; + uint16 _readBucket; + }; + + Mode _writeMode = Sequential; // Current write mode. The read mode is the opposite +}; + diff --git a/src/io/FileStream.cpp b/src/io/FileStream.cpp index 1cb7ae23..cbbf4c04 100644 --- a/src/io/FileStream.cpp +++ b/src/io/FileStream.cpp @@ -1,2 +1,2 @@ -#include "FileStream.h" - +#include "FileStream.h" + diff --git a/src/io/FileStream.h b/src/io/FileStream.h index a2d8fc72..eaaf9ab1 100644 --- a/src/io/FileStream.h +++ b/src/io/FileStream.h @@ -1,102 +1,106 @@ -#pragma once -#include "Platform.h" - -enum class FileAccess : uint16 -{ - None = 0, - Read = 1 << 0, - Write = 1 << 1, - ReadWrite = Read | Write -}; -ImplementFlagOps( FileAccess ); - -enum class FileMode : uint16 -{ - Open = 0, - Create = 1, - Append = 2 -}; - -enum class FileFlags : uint32 -{ - None = 0, - NoBuffering = 1 << 0, - LargeFile = 1 << 1, -}; -ImplementFlagOps( FileFlags ); - - -enum class SeekOrigin : int32 -{ - Begin = 0, - Current, - End -}; - -class FileStream -{ -public: - inline FileStream() {} - inline ~FileStream() - { - Close(); - } - - // Duplicate a file - // FileStream( const FileStream& src ); - - // void WriteAsync( byte* buffer, size_t size ); - - static bool Open( const char* path, FileStream& file, FileMode mode, FileAccess access, FileFlags flags = FileFlags::None ); - bool Open( const char* path, FileMode mode, FileAccess access, FileFlags flags = FileFlags::None ); - - ssize_t Read( void* buffer, size_t size ); - ssize_t Write( const void* buffer, size_t size ); - - bool Reserve( ssize_t size ); - - bool Seek( int64 offset, SeekOrigin origin ); - - bool Flush(); - - inline size_t BlockSize() - { - return _blockSize; - } - - void Close(); - - bool IsOpen() const; - static bool Exists( const char* path ); - - inline int GetError() - { - int err = _error; - _error = 0; - - return err; - } -private: - inline bool HasValidFD() const - { - #if PLATFORM_IS_UNIX - return _fd != -1; - #else - return _fd != INVALID_HANDLE_VALUE; - #endif - } - -private: - size_t _writePosition = 0; - size_t _readPosition = 0; - FileAccess _access = FileAccess::None; - FileFlags _flags = FileFlags::None; - int _error = 0; - size_t _blockSize = 0; // for O_DIRECT/FILE_FLAG_NO_BUFFERING - - #if PLATFORM_IS_UNIX - int _fd = -1; - #elif PLATFORM_IS_WINDOWS - HANDLE _fd = INVALID_HANDLE_VALUE; - #endif +#pragma once +#include "Platform.h" +#include "IStream.h" + +enum class FileAccess : uint16 +{ + None = 0, + Read = 1 << 0, + Write = 1 << 1, + ReadWrite = Read | Write +}; +ImplementFlagOps( FileAccess ); + +enum class FileMode : uint16 +{ + Open = 0 // Open existing (fails if it does not exist). + ,Create = 1 // Create new, or if it is existing, open and truncate. + ,OpenOrCreate = 2 // Open existing or create new. +}; + +enum class FileFlags : uint32 +{ + None = 0, + NoBuffering = 1 << 0, + LargeFile = 1 << 1, +}; +ImplementFlagOps( FileFlags ); + + +class FileStream : public IStream +{ +public: + inline FileStream() {} + inline ~FileStream() + { + Close(); + } + + // Duplicate a file + // FileStream( const FileStream& src ); + + // void WriteAsync( byte* buffer, size_t size ); + + static bool Open( const char* path, FileStream& file, FileMode mode, FileAccess access, FileFlags flags = FileFlags::None ); + bool Open( const char* path, FileMode mode, FileAccess access, FileFlags flags = FileFlags::None ); + + ssize_t Read( void* buffer, size_t size ) override; + ssize_t Write( const void* buffer, size_t size ) override; + + bool Reserve( ssize_t size ); + + bool Seek( int64 offset, SeekOrigin origin ) override; + + bool Flush() override; + + inline size_t BlockSize() const override + { + return _blockSize; + } + + ssize_t Size() override; + + bool Truncate( const ssize_t length ) override; + + void Close(); + + bool IsOpen() const; + static bool Exists( const char* path ); + + inline int GetError() override + { + int err = _error; + _error = 0; + + return err; + } + + inline FileAccess GetFileAccess() const { return _access; } + + inline FileFlags GetFlags() const { return _flags; } + + inline intptr_t Id() { return (intptr_t)_fd; } + +private: + inline bool HasValidFD() const + { + #if PLATFORM_IS_UNIX + return _fd != -1; + #else + return _fd != INVALID_WIN32_HANDLE; + #endif + } + +private: + size_t _position = 0; + FileAccess _access = FileAccess::None; + FileFlags _flags = FileFlags::None; + int _error = 0; + size_t _blockSize = 0; // for O_DIRECT/FILE_FLAG_NO_BUFFERING + + #if PLATFORM_IS_UNIX + int _fd = -1; + #elif PLATFORM_IS_WINDOWS + HANDLE _fd = INVALID_WIN32_HANDLE; + #endif }; \ No newline at end of file diff --git a/src/io/HybridStream.cpp b/src/io/HybridStream.cpp new file mode 100644 index 00000000..b6f4acb4 --- /dev/null +++ b/src/io/HybridStream.cpp @@ -0,0 +1,304 @@ +#include "HybridStream.h" +#include "util/Util.h" + +//----------------------------------------------------------- +bool HybridStream::Open( void* memory, ssize_t memorySize, const char* path, FileMode mode, FileAccess access, FileFlags flags ) +{ + ASSERT( memory ); + FatalIf( memorySize < 0, "Invalid memory size." ); + + // Open the backing file + if( !_file.Open( path, mode, access, flags ) ) + { + _error = _file.GetError(); + return false; + } + + _memory = (byte*)memory; + _memSize = (size_t)memorySize; + _position = 0; + _error = 0; + + return true; +} + +//----------------------------------------------------------- +void HybridStream::Close() +{ + if( !IsOpen() ) + return; + + _memory = nullptr; + _memSize = 0; + _position = 0; + _error = 0; + _file.Close(); +} +// //----------------------------------------------------------- +// bool HybridStream::Open( ssize_t memorySize, const char* path, FileMode mode, FileAccess access, FileFlags flags ) +// { +// +// } + +//----------------------------------------------------------- +ssize_t HybridStream::Read( void* buffer, size_t size ) +{ + if( size < 1 ) + return 0; + + ASSERT( buffer ); + if( !buffer ) + return -14; // EFAULT + + // #TODO: Check if write-only + + // #TODO: Prevent overflow ssize_t max + + // Bring down to our max read size + const size_t maxRead = (size_t)(std::numeric_limits::max() - Size() ); + size = std::min( size, maxRead ); + + // Check if we can read from memory + size_t read = 0; + if( _position < _memSize ) + { + read = std::min( _memSize - _position, size ); + + memcpy( buffer, _memory + _position, read ); + + _position += read; + size -= read; + buffer = ((byte*)buffer) + read; + } + + if( size ) + { + ssize_t diskRead = _file.Read( buffer, size ); + if( diskRead < 0 ) + { + _error = _file.GetError(); + return diskRead; + } + + _position += (size_t)diskRead; + read += (size_t)diskRead; + } + + return (ssize_t)read; +} + + +//----------------------------------------------------------- +ssize_t HybridStream::Write( const void* buffer, size_t size ) +{ + if( size < 1 ) + return 0; + + ASSERT( buffer ); + if( !buffer ) + { + _error = -14; // EFAULT + return _error; + } + + // #TODO: Check if read-only + + // Bring down to our max write size + const size_t maxWrite = (size_t)(std::numeric_limits::max() - _position ); + size = std::min( size, maxWrite ); + + // See if we can write to our memory region + size_t written = 0; + if( _position < _memSize ) + { + written = std::min( _memSize - _position, size ); + + memcpy( _memory + _position, buffer, written ); + + _position += written; + size -= written; + buffer = ((byte*)buffer) + written; + } + + // Write any remaining data to disk + if( size ) + { + ssize_t diskWritten = _file.Write( buffer, size ); + if( diskWritten < 0 ) + { + _error = _file.GetError(); + return diskWritten; + } + + _position += (size_t)diskWritten; + written += (size_t)diskWritten; + } + + return (ssize_t)written; +} + +//----------------------------------------------------------- +bool HybridStream::Seek( int64 offset, SeekOrigin origin ) +{ + switch( origin ) + { + case SeekOrigin::Begin: + if( offset < 0 ) + { + ASSERT( 0 ); + _error = -22; // EINVAL + return false; + } + _position = (size_t)offset; + break; + + case SeekOrigin::Current: + if( offset < 0 ) + { + const size_t subtrahend = (size_t)std::abs( offset ); + if( subtrahend > _position ) + { + ASSERT( 0 ); + _error = -22; // EINVAL + return false; + } + + _position -= subtrahend; + } + else + { + if( _position + (size_t)offset < _position ) + { + ASSERT( 0 ); + _error = -22; // EINVAL + return false; + } + + _position += (size_t)offset; + } + break; + + case SeekOrigin::End: + { + const size_t end = _memSize + (size_t)_file.Size(); + if( offset < 0 ) + { + const size_t subtrahend = (size_t)std::abs( offset ); + if( subtrahend > end ) + { + ASSERT( 0 ); + _error = -22; // EINVAL + return false; + } + + _position = end - (size_t)subtrahend; + } + else + { + if( _position + (ssize_t)offset > (size_t)std::numeric_limits::max() ) + { + ASSERT( 0 ); + _error = -22; // EINVAL + return false; + } + + // Go beyond the file end + if( !_file.Seek( (int64)offset, SeekOrigin::End ) ) + { + ASSERT( 0 ); + _error = _file.GetError(); + return false; + } + + _position = end + (ssize_t)offset; + return true; + } + } + break; + + default: + _error = -1; // EPERM + return false; + } + + ASSERT( _position <= (size_t)std::numeric_limits::max() ); + + // Seek file + if( _position < _memSize ) + { + if( !_file.Seek( 0, SeekOrigin::Begin ) ) + { + ASSERT( 0 ); + _error = _file.GetError(); + return false; + } + } + else + { + const size_t filePos = _position - _memSize; + + if( !_file.Seek( filePos, SeekOrigin::Begin ) ) + { + ASSERT( 0 ); + _error = _file.GetError(); + return false; + } + } + + return true; +} + +//----------------------------------------------------------- +bool HybridStream::Flush() +{ + return _file.Flush(); +} + +//----------------------------------------------------------- +size_t HybridStream::BlockSize() const +{ + return _file.BlockSize(); +} + +//----------------------------------------------------------- +ssize_t HybridStream::Size() +{ + // #TODO: Should track maximum written position, not based on the _memSize + return _memSize + _file.Size(); +} + +//----------------------------------------------------------- +bool HybridStream::Truncate( const ssize_t length ) +{ + if( length < 0 ) + { + ASSERT( 0 ); + return false; + } + + if( (size_t)length >= _memSize ) + { + // Need to truncate the backing file + const ssize_t fileLength = length - (ssize_t)_memSize; + if( !_file.Truncate( fileLength ) ) + { + _error = _file.GetError(); + return false; + } + } + + if( _position > (size_t)length ) + Seek( (int64)length, SeekOrigin::Begin ); + + return true; +} + +//----------------------------------------------------------- +int HybridStream::GetError() +{ + // #TODO: Do not clear error here. + // Only clear on successful operations. + int err = _error; + _error = 0; + return err; +} \ No newline at end of file diff --git a/src/io/HybridStream.h b/src/io/HybridStream.h new file mode 100644 index 00000000..a121184a --- /dev/null +++ b/src/io/HybridStream.h @@ -0,0 +1,41 @@ +#pragma once +#include "FileStream.h" + +class HybridStream : public IStream +{ + +public: + inline HybridStream() {} + inline ~HybridStream() {} + + bool Open( void* memory, ssize_t memorySize, const char* path, FileMode mode, FileAccess access, FileFlags flags = FileFlags::None ); + // bool Open( ssize_t memorySize, const char* path, FileMode mode, FileAccess access, FileFlags flags = FileFlags::None ); + void Close(); + + ssize_t Read( void* buffer, size_t size ) override; + + ssize_t Write( const void* buffer, size_t size ) override; + + bool Seek( int64 offset, SeekOrigin origin ) override; + + bool Flush() override; + + size_t BlockSize() const override; + + ssize_t Size() override; + + bool Truncate( const ssize_t length ) override; + + int GetError() override; + + inline bool IsOpen() const { return _file.IsOpen(); } + + FileStream& File() { return _file; } + +private: + FileStream _file; // Backing file + byte* _memory = nullptr; // Memory buffer + size_t _memSize = 0; + size_t _position = 0; + int _error = 0; +}; \ No newline at end of file diff --git a/src/io/IOUtil.cpp b/src/io/IOUtil.cpp new file mode 100644 index 00000000..f0d41bd7 --- /dev/null +++ b/src/io/IOUtil.cpp @@ -0,0 +1,4 @@ +#include "IOUtil.h" +#include "IStream.h" + + diff --git a/src/io/IOUtil.h b/src/io/IOUtil.h new file mode 100644 index 00000000..599c8852 --- /dev/null +++ b/src/io/IOUtil.h @@ -0,0 +1,9 @@ +#pragma once + +class IStream; + +class IOUtil +{ +public: + +}; \ No newline at end of file diff --git a/src/io/IStream.h b/src/io/IStream.h new file mode 100644 index 00000000..20c47673 --- /dev/null +++ b/src/io/IStream.h @@ -0,0 +1,33 @@ +#pragma once + +enum class SeekOrigin : int32 +{ + Begin = 0, + Current, + End +}; + + +// Stream Interface +class IStream +{ +public: + inline virtual ~IStream() {} + + virtual ssize_t Read( void* buffer, size_t size ) = 0; + + virtual ssize_t Write( const void* buffer, size_t size ) = 0; + + virtual bool Seek( int64 offset, SeekOrigin origin ) = 0; + + virtual bool Flush() = 0; + + virtual size_t BlockSize() const = 0; + + virtual ssize_t Size() = 0; + + virtual bool Truncate( const ssize_t length ) = 0; + + virtual int GetError() = 0; + +}; \ No newline at end of file diff --git a/src/io/MemoryStream.h b/src/io/MemoryStream.h new file mode 100644 index 00000000..828bd413 --- /dev/null +++ b/src/io/MemoryStream.h @@ -0,0 +1,21 @@ +#pragma once +#include "IStream.h" + +class MemoryStream : public IStream +{ +public: + + ssize_t Read( void* buffer, size_t size ) override; + + ssize_t Write( const void* buffer, size_t size ) override; + + bool Seek( int64 offset, SeekOrigin origin ) override; + + bool Flush() override; + + size_t BlockSize() const override; + + ssize_t Size() override; + + int GetError() override; +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f0c85a34..16acf242 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,383 +1,180 @@ -#include -#include -#include -#include - +#include "plotting/GlobalPlotConfig.h" +#include "util/CliParser.h" +#include "plotdisk/DiskPlotter.h" #include "Version.h" -#include "Util.h" -#include "util/Log.h" -#include "SysHost.h" -#include "memplot/MemPlotter.h" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wreturn-type" +#if PLATFORM_IS_UNIX + #include +#endif -#pragma warning( push ) +static void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ); +static void PrintUsage(); -extern "C" { - #include "bech32/segwit_addr.h" -} +// See IOTester.cpp +void IOTestMain( GlobalPlotConfig& gCfg, CliParser& cli ); +void IOTestPrintUsage(); -#pragma GCC diagnostic ignored "-Wsign-compare" -#pragma warning( disable : 6287 ) -#pragma warning( disable : 4267 ) -#pragma warning( disable : 26495 ) -#include "bls.hpp" -#include "elements.hpp" -#include "schemes.hpp" -#include "util.hpp" -#pragma GCC diagnostic pop -#pragma warning( pop ) - -#define PLOT_FILE_PREFIX_LEN (sizeof("plot-k32-2021-08-05-18-55-")-1) -#define PLOT_FILE_FMT_LEN (sizeof( "/plot-k32-2021-08-05-18-55-77a011fc20f0003c3adcc739b615041ae56351a22b690fd854ccb6726e5f43b7.plot.tmp" )) - -/// Internal Data Structures -struct Config -{ - uint threads = 0; - uint plotCount = 1; - bool warmStart = false; - bool disableNuma = false; - bool disableCpuAffinity = false; - - bls::G1Element farmerPublicKey; - bls::G1Element* poolPublicKey = nullptr; - - ByteSpan* contractPuzzleHash = nullptr; - const char* outputFolder = nullptr; +// MemTester.cpp +void MemTestMain( GlobalPlotConfig& gCfg, CliParser& cli ); +void MemTestPrintUsage(); - int maxFailCount = 100; +// PlotValidator.cpp +void PlotValidatorMain( GlobalPlotConfig& gCfg, CliParser& cli ); +void PlotValidatorPrintUsage(); - const char* plotId = nullptr; - const char* plotMemo = nullptr; - bool showMemo = false; -}; +// PlotComparer.cpp +void PlotCompareMain( GlobalPlotConfig& gCfg, CliParser& cli ); +void PlotCompareMainPrintUsage(); -/// Internal Functions -void ParseCommandLine( int argc, const char* argv[], Config& cfg ); -bool HexPKeyToG1Element( const char* hexKey, bls::G1Element& pkey ); -ByteSpan DecodePuzzleHash( const char* poolContractAddress ); -void GeneratePlotIdAndMemo( Config& cfg, byte plotId[32], byte plotMemo[48+48+32], uint16& outMemoSize ); -bls::PrivateKey MasterSkToLocalSK( bls::PrivateKey& sk ); -bls::G1Element GeneratePlotPublicKey( const bls::G1Element& localPk, bls::G1Element& farmerPk, const bool includeTaproot ); -std::vector BytesConcat( std::vector a, std::vector b, std::vector c ); +struct Plotter +{ + union { + void* _ptr; + DiskPlotter* disk; + }; +}; + +Plotter _plotter; -void PrintSysInfo(); -void GetPlotIdBytes( const std::string& plotId, byte outBytes[32] ); -void PrintUsage(); +//----------------------------------------------------------- +int main( int argc, const char* argv[] ) +{ + // Install a crash handler to dump our stack traces + SysHost::InstallCrashHandler(); #if _DEBUG - std::string HexToString( const byte* bytes, size_t length ); - std::vector HexStringToBytes( const char* hexStr ); - std::vector HexStringToBytes( const std::string& hexStr ); - void PrintPK( const bls::G1Element& key ); - void PrintSK( const bls::PrivateKey& key ); + Log::Line( "*** Warning: Debug mode is ENABLED ***" ); #endif -//----------------------------------------------------------- -const char* USAGE = "bladebit [] []\n" -R"( -: Output directory in which to output the plots. - This directory must exist. - -OPTIONS: - - -h, --help : Shows this message and exits. + ZeroMem( &_plotter ); - -t, --threads : Maximum number of threads to use. - For best performance, use all available threads (default behavior). - Values below 2 are not recommended. - - -n, --count : Number of plots to create. Default = 1. - - -f, --farmer-key : Farmer public key, specified in hexadecimal format. - *REQUIRED* - - -p, --pool-key : Pool public key, specified in hexadecimal format. - Either a pool public key or a pool contract address must be specified. - - -c, --pool-contract : Pool contract address, specified in hexadecimal format. - Address where the pool reward will be sent to. - Only used if pool public key is not specified. - - -w, --warm-start : Touch all pages of buffer allocations before starting to plot. - - -i, --plot-id : Specify a plot id for debugging. - - --memo : Specify a plot memo for debugging. - - --show-memo : Output the memo of the next plot the be plotted. - - -v, --verbose : Enable verbose output. + GlobalPlotConfig cfg; + ParseCommandLine( cfg, --argc, ++argv ); - -m, --no-numa : Disable automatic NUMA aware memory binding. - If you set this parameter in a NUMA system you - will likely get degraded performance. + FatalIf( !_plotter._ptr, "No command chosen." ); - --no-cpu-affinity : Disable assigning automatic thread affinity. - This is useful when running multiple simultaneous - instances of bladebit as you can manually - assign thread affinity yourself when launching bladebit. - - --memory : Display system memory available, in bytes, and the - required memory to run Bladebit, in bytes. - - --memory-json : Same as --memory, but formats the output as json. - --version : Display current version. -)"; + const int64 plotCount = cfg.plotCount > 0 ? (int64)cfg.plotCount : std::numeric_limits::max(); + // int64 failCount = 0; + byte plotId [BB_PLOT_ID_LEN]; + byte plotMemo[BB_PLOT_MEMO_MAX_SIZE]; + uint16 plotMemoSize = 0; -//----------------------------------------------------------- -int main( int argc, const char* argv[] ) -{ - // Install a crash handler to dump our stack traces - SysHost::InstallCrashHandler(); + char plotIdStr[BB_PLOT_ID_LEN*2+1]; - // Parse command line info - Config cfg; - ParseCommandLine( argc-1, argv+1, cfg ); - // Create the plot output path + // Prepare the output path size_t outputFolderLen = strlen( cfg.outputFolder ); - - char* plotOutPath = new char[outputFolderLen + PLOT_FILE_FMT_LEN]; + char* plotOutPath = new char[outputFolderLen + BB_PLOT_FILE_LEN_TMP + 2]; // + '/' + null terminator if( outputFolderLen ) { memcpy( plotOutPath, cfg.outputFolder, outputFolderLen ); // Add a trailing slash, if we need one. - if( plotOutPath[outputFolderLen-1] != '/' ) + if( plotOutPath[outputFolderLen-1] != '/' && plotOutPath[outputFolderLen-1] != '\\' ) plotOutPath[outputFolderLen++] = '/'; } - // Begin plotting - PlotRequest req; - ZeroMem( &req ); - - // #TODO: Don't let this config to permanently remain on the stack - MemPlotConfig plotCfg; - plotCfg.threadCount = cfg.threads; - plotCfg.noNUMA = cfg.disableNuma; - plotCfg.noCPUAffinity = cfg.disableCpuAffinity; - plotCfg.warmStart = cfg.warmStart; - - MemPlotter plotter( plotCfg ); - - byte plotId[32]; - byte memo [48+48+32]; - uint16 memoSize; - char plotIdStr[65] = { 0 }; - - int failCount = 0; - for( uint i = 0; i < cfg.plotCount; i++ ) + // Start plotting + for( int64 i = 0; i < plotCount; i++ ) { - // Generate a new plot id - GeneratePlotIdAndMemo( cfg, plotId, memo, memoSize ); + // Generate a plot id and memo + PlotTools::GeneratePlotIdAndMemo( plotId, plotMemo, plotMemoSize, + cfg.farmerPublicKey, cfg.poolPublicKey, cfg.poolContractPuzzleHash ); // Apply debug plot id and/or memo - if( cfg.plotId ) - HexStrToBytes( cfg.plotId, 64, plotId, 32 ); + if( cfg.plotIdStr ) + HexStrToBytes( cfg.plotIdStr, BB_PLOT_ID_LEN*2, plotId, BB_PLOT_ID_LEN ); - if( cfg.plotMemo ) + if( cfg.plotMemoStr ) { - const size_t memoLen = strlen( cfg.plotMemo ); - HexStrToBytes( cfg.plotMemo, memoLen, memo, memoLen/2 ); + const size_t memoLen = strlen( cfg.plotMemoStr ); + HexStrToBytes( cfg.plotMemoStr, memoLen, plotMemo, memoLen/2 ); } - - // Convert plot id to string - { - size_t numEncoded = 0; - BytesToHexStr( plotId, sizeof( plotId), plotIdStr, sizeof( plotIdStr ), numEncoded ); - ASSERT( numEncoded == 32 ); - plotIdStr[64] = 0; - } + // Convert plot id to string + PlotTools::PlotIdToString( plotId, plotIdStr ); - // Set the output path - { - time_t now = time( nullptr ); - struct tm* t = localtime( &now ); ASSERT( t ); - - const size_t r = strftime( plotOutPath + outputFolderLen, PLOT_FILE_FMT_LEN, "plot-k32-%Y-%m-%d-%H-%M-", t ); - if( r != PLOT_FILE_PREFIX_LEN ) - Fatal( "Failed to generate plot file." ); + // Set the plot file name + const char* plotFileName = plotOutPath + outputFolderLen; + PlotTools::GenPlotFileName( plotId, (char*)plotFileName ); - memcpy( plotOutPath + outputFolderLen + PLOT_FILE_PREFIX_LEN , plotIdStr, 64 ); - memcpy( plotOutPath + outputFolderLen + PLOT_FILE_PREFIX_LEN + 64, ".plot.tmp", sizeof( ".plot.tmp" ) ); - } + // Begin plot + if( cfg.plotCount == 0 ) + Log::Line( "Generating plot %lld: %s", i+1, plotIdStr ); + else + Log::Line( "Generating plot %lld / %u: %s", i+1, cfg.plotCount, plotIdStr ); - Log::Line( "Generating plot %d / %d: %s", i+1, cfg.plotCount, plotIdStr ); if( cfg.showMemo ) { - char memoStr[(48+48+32)*2 + 1]; + char plotMemoStr[BB_PLOT_MEMO_MAX_SIZE*2+1]; size_t numEncoded = 0; - BytesToHexStr( memo, memoSize, memoStr, sizeof( memoStr ) - 1, numEncoded ); - memoStr[numEncoded*2] = 0; + BytesToHexStr( plotMemo, plotMemoSize, plotMemoStr, sizeof( plotMemoStr ) - 1, numEncoded ); + plotMemoStr[numEncoded*2] = 0; - Log::Line( "Plot Memo: %s", memoStr ); + Log::Line( "Plot Memo: %s", plotMemoStr ); } Log::Line( "" ); - // Prepare the request - req.outPath = plotOutPath; - req.plotId = plotId; - req.memo = memo; - req.memoSize = memoSize; - req.IsFinalPlot = i+1 == cfg.plotCount; - - // Plot it - if( !plotter.Run( req ) ) + if( _plotter.disk ) { - Log::Error( "Error: Plot %s failed... Trying next plot.", plotIdStr ); - if( cfg.maxFailCount > 0 && ++failCount >= cfg.maxFailCount ) - { - // #TODO: Wait for pending plot writes to disk - Fatal( "Maximum number of plot failures reached. Exiting." ); - } + auto& plotter = *_plotter.disk; + + DiskPlotter::PlotRequest req; + req.plotId = plotId; + req.plotMemo = plotMemo; + req.plotMemoSize = plotMemoSize; + req.plotFileName = plotFileName; + plotter.Plot( req ); } - - Log::Line( "" ); } - - Log::Flush(); - return 0; } //----------------------------------------------------------- -void ParseCommandLine( int argc, const char* argv[], Config& cfg ) +void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ) { - #define check( a ) (strcmp( a, arg ) == 0) - int i; - const char* arg = nullptr; - - auto value = [&](){ - - if( ++i >= argc ) - Fatal( "Expected a value for parameter '%s'", arg ); - - return argv[i]; - }; - - auto ivalue = [&]() { - - const char* val = value(); - int64 v = 0; - - int r = sscanf( val, "%lld", &v ); - if( r != 1 ) - Fatal( "Invalid value for argument '%s'.", arg ); - - return v; - }; - - auto uvalue = [&]() { - - int64 v = ivalue(); - if( v < 0 || v > 0xFFFFFFFF ) - Fatal( "Invalid value for argument '%s'. Value '%ld' is out of range.", arg, v ); - - return (uint32)v; - }; + CliParser cli( argc, argv ); const char* farmerPublicKey = nullptr; const char* poolPublicKey = nullptr; const char* poolContractAddress = nullptr; - for( i = 0; i < argc; i++ ) + while( cli.HasArgs() ) { - arg = argv[i]; - - if( check( "-h" ) || check( "--help") ) - { - PrintUsage(); - exit( 0 ); - } - else if( check( "-t" ) || check( "--threads") ) - { - cfg.threads = uvalue(); - - if( cfg.threads == 1 ) - Log::Line( "Warning: Only 1 thread was specified. Sub-optimal performance expected." ); - } - else if( check( "-n" ) || check( "--count" ) ) - { - cfg.plotCount = uvalue(); - if( cfg.plotCount < 1 ) - { - Log::Line( "Warning: Invalid plot count specified. Setting it to 1." ); - cfg.plotCount = 1; - } - } - else if( check( "-f" ) || check( "--farmer-key" ) ) - { - farmerPublicKey = value(); - } - else if( check( "-p" ) || check( "--pool-key" ) ) - { - poolPublicKey = value(); - } - else if( check( "-c" ) || check( "--pool-contract" ) ) - { - poolContractAddress = value(); - } - else if( check( "-w" ) || check( "--warm-start" ) ) - { - cfg.warmStart = true; - } - else if( check( "-i" ) || check( "--plot-id" ) ) - { - cfg.plotId = value(); - - size_t len = strlen( cfg.plotId ); - if( len < 64 && len != 66 ) - Fatal( "Invalid plot id." ); - - if( len == 66 ) - { - if( cfg.plotId[0] == '0' && cfg.plotId[1] == 'x' ) - cfg.plotId += 2; - else - Fatal( "Invalid plot id." ); - } - } - else if( check( "--memo" ) ) - { - cfg.plotMemo = value(); - - size_t len = strlen( cfg.plotMemo ); - if( len > 2 && cfg.plotMemo[0] == '0' && cfg.plotMemo[1] == 'x' ) - { - cfg.plotMemo += 2; - len -= 2; - } - - if( len/2 != (48 + 48 + 32) && len != (32 + 48 + 32) ) - Fatal( "Invalid plot memo." ); - } - else if( check( "--show-memo" ) ) - { - cfg.showMemo = true; - } - else if( check( "-m" ) || check( "--no-numa" ) ) - { - cfg.disableNuma = true; - } - else if( check( "--no-cpu-affinity" ) ) - { - cfg.disableCpuAffinity = true; - } - else if( check( "-v" ) || check( "--verbose" ) ) + if( cli.ReadU32( cfg.threadCount, "-t", "--threads" ) ) + continue; + else if( cli.ReadU32( cfg.plotCount, "-n", "--count" ) ) + continue; + else if( cli.ReadStr( farmerPublicKey, "-f", "--farmer-key" ) ) + continue; + else if( cli.ReadStr( poolPublicKey, "-p", "--pool-key" ) ) + continue; + else if( cli.ReadStr( poolContractAddress, "-c", "--pool-contract" ) ) + continue; + else if( cli.ReadSwitch( cfg.warmStart, "-w", "--warm-start" ) ) + continue; + else if( cli.ReadStr( cfg.plotIdStr, "-i", "--plot-id" ) ) + continue; + else if( cli.ReadStr( cfg.plotMemoStr, "--memo" ) ) + continue; + else if( cli.ReadSwitch( cfg.showMemo, "--show-memo" ) ) + continue; + else if( cli.ReadSwitch( cfg.disableNuma, "-m", "--no-numa" ) ) + continue; + else if( cli.ReadSwitch( cfg.disableCpuAffinity, "--no-cpu-affinity" ) ) + continue; + else if( cli.ArgConsume( "-v", "--verbose" ) ) { Log::SetVerbose( true ); } - else if( check( "--memory" ) ) + else if( cli.ArgConsume( "--memory" ) ) { + // #TODO: We should move the required part to the memplot command // #TODO: Get this value from Memplotter const size_t requiredMem = 416ull GB; const size_t availableMem = SysHost::GetAvailableSystemMemory(); @@ -389,7 +186,7 @@ void ParseCommandLine( int argc, const char* argv[], Config& cfg ) exit( 0 ); } - else if( check( "--memory-json" ) ) + else if( cli.ArgConsume( "--memory-json" ) ) { // #TODO: Get this value from Memplotter const size_t requiredMem = 416ull GB; @@ -401,389 +198,274 @@ void ParseCommandLine( int argc, const char* argv[], Config& cfg ) exit( 0 ); } - else if( check( "--version" ) ) + else if( cli.ArgConsume( "--version" ) ) { Log::Line( BLADEBIT_VERSION_STR ); exit( 0 ); } - else + else if( cli.ArgConsume( "-h", "--help" ) ) { - if( i+1 < argc ) + PrintUsage(); + exit( 0 ); + } + else if( cli.ArgConsume( "--about" ) ) + { + Log::Line( "BladeBit Chia Plotter" ); + Log::Line( "Version : %s", BLADEBIT_VERSION_STR ); + Log::Line( "Git Commit : %s", BLADEBIT_GIT_COMMIT ); + Log::Line( "Compiled With: %s", BBGetCompilerVersion() ); + + exit( 0 ); + } + + // Commands + else if( cli.ArgConsume( "diskplot" ) ) + { + // Increase the file size limit on linux + #if PLATFORM_IS_UNIX + struct rlimit limit; + getrlimit( RLIMIT_NOFILE, &limit ); + + if( limit.rlim_cur < limit.rlim_max ) + { + Log::Line( "Increasing the file limit from %u to %u", limit.rlim_cur, limit.rlim_max ); + + limit.rlim_cur = limit.rlim_max; + if( setrlimit( RLIMIT_NOFILE, &limit ) != 0 ) + { + const int err = errno; + Log::Line( "*** Warning: Failed to increase file limit to with error %d (0x%02x). Plotting may fail ***", err, err ); + } + } + #endif + + DiskPlotter::Config diskCfg; + diskCfg.globalCfg = &cfg; + DiskPlotter::ParseCommandLine( cli, diskCfg ); + + _plotter.disk = new DiskPlotter( diskCfg ); + + break; + } + else if( cli.ArgConsume( "iotest" ) ) + { + IOTestMain( cfg, cli ); + exit( 0 ); + } + else if( cli.ArgConsume( "memtest" ) ) + { + MemTestMain( cfg, cli ); + exit( 0 ); + } + else if( cli.ArgConsume( "validate" ) ) + { + PlotValidatorMain( cfg, cli ); + exit( 0 ); + } + else if( cli.ArgConsume( "plotcmp" ) ) + { + PlotCompareMain( cfg, cli ); + exit( 0 ); + } + else if( cli.ArgConsume( "help" ) ) + { + if( cli.HasArgs() ) { - Fatal( "Unexpected argument '%s'.", arg ); - exit( 1 ); + if( cli.ArgMatch( "diskplot" ) ) + DiskPlotter::PrintUsage(); + if( cli.ArgMatch( "iotest" ) ) + IOTestPrintUsage(); + if( cli.ArgMatch( "memtest" ) ) + MemTestPrintUsage(); + if( cli.ArgMatch( "validate" ) ) + PlotValidatorPrintUsage(); + if( cli.ArgMatch( "plotcmp" ) ) + PlotCompareMainPrintUsage(); + else + Fatal( "Unknown command '%s'.", cli.Arg() ); + + exit( 0 ); } - cfg.outputFolder = arg; + Log::Line( "help []" ); + Log::Line( "Display help text for a command." ); + Log::Line( "" ); + PrintUsage(); + exit( 0 ); } - } - #undef check - + // else if( cli.ArgMatch( "memplot" ) ) + // { - if( farmerPublicKey ) - { - if( !HexPKeyToG1Element( farmerPublicKey, cfg.farmerPublicKey ) ) - Fatal( "Failed to parse farmer public key '%s'.", farmerPublicKey ); - - // Remove 0x prefix for printing - if( farmerPublicKey[0] == '0' && farmerPublicKey[1] == 'x' ) - farmerPublicKey += 2; + // } + else + { + Fatal( "Unexpected argument '%s'", cli.Arg() ); + } } - else - Fatal( "A farmer public key is required. Please specify a farmer public key." ); - if( poolPublicKey ) + // The remainder should be output folders + while( cli.HasArgs() ) { - if( poolContractAddress ) - Log::Write( "Warning: Pool contract address will not be used. A pool public key was specified." ); - - // cfg.poolPublicKey = new bls::G1Element() - bls::G1Element poolPubG1; - if( !HexPKeyToG1Element( poolPublicKey, poolPubG1 ) ) - Fatal( "Error: Failed to parse pool public key '%s'.", poolPublicKey ); + cfg.outputFolder = cli.Arg(); + cli.NextArg(); + } - cfg.poolPublicKey = new bls::G1Element( std::move( poolPubG1 ) ); + // Validation + FatalIf( farmerPublicKey == nullptr, "A farmer public key must be specified." ); + FatalIf( !KeyTools::HexPKeyToG1Element( farmerPublicKey, cfg.farmerPublicKey ), + "Invalid farmer public key '%s'", farmerPublicKey ); - // Remove 0x prefix for printing - if( poolPublicKey[0] == '0' && poolPublicKey[1] == 'x' ) - poolPublicKey += 2; + if( poolContractAddress ) + { + cfg.poolContractPuzzleHash = new PuzzleHash(); + FatalIf( !PuzzleHash::FromAddress( *cfg.poolContractPuzzleHash, poolContractAddress ), + "Invalid pool contract puzzle hash '%s'", poolContractAddress ); } - else if( poolContractAddress ) + else if( poolPublicKey ) { - cfg.contractPuzzleHash = new ByteSpan( std::move( DecodePuzzleHash( poolContractAddress ) ) ); + cfg.poolPublicKey = new bls::G1Element(); + FatalIf( !KeyTools::HexPKeyToG1Element( poolPublicKey, *cfg.poolPublicKey ), + "Invalid pool public key '%s'", poolPublicKey ); } else Fatal( "Error: Either a pool public key or a pool contract address must be specified." ); - const uint threadCount = SysHost::GetLogicalCPUCount(); - - if( cfg.threads == 0 ) - cfg.threads = threadCount; - else if( cfg.threads > threadCount ) + const uint maxThreads = SysHost::GetLogicalCPUCount(); + if( cfg.threadCount == 0 ) + cfg.threadCount = maxThreads; + else if( cfg.threadCount > maxThreads ) { - Log::Write( "Warning: Lowering thread count from %d to %d, the native maximum.", - cfg.threads, threadCount ); + Log::Write( "Warning: Lowering thread count from %u to %u, the native maximum.", + cfg.threadCount, maxThreads ); - cfg.threads = threadCount; + cfg.threadCount = maxThreads; } - - if( cfg.plotCount < 1 ) - cfg.plotCount = 1; - if( cfg.outputFolder == nullptr ) - { - Log::Line( "Warning: No output folder specified. Using current directory." ); - cfg.outputFolder = ""; - } + FatalIf( cfg.outputFolder == nullptr, "An output folder must be specified." ); - Log::Line( "Creating %d plots:", cfg.plotCount ); - - if( cfg.outputFolder ) - Log::Line( " Output path : %s", cfg.outputFolder ); - else - Log::Line( " Output path : Current directory." ); - - Log::Line( " Thread count : %d", cfg.threads ); - Log::Line( " Warm start enabled : %s", cfg.warmStart ? "true" : "false" ); - - - Log::Line( " Farmer public key : %s", farmerPublicKey ); - - if( poolPublicKey ) - Log::Line( " Pool public key : %s", poolPublicKey ); - else if( poolContractAddress ) - Log::Line( " Pool contract address : %s", poolContractAddress ); - - Log::Line( "" ); -} - -//----------------------------------------------------------- -void GeneratePlotIdAndMemo( Config& cfg, byte plotId[32], byte plotMemo[48+48+32], uint16& outMemoSize ) -{ - bls::G1Element& farmerPK = cfg.farmerPublicKey; - bls::G1Element* poolPK = cfg.poolPublicKey; - - // Generate random master secret key - byte seed[32]; - SysHost::Random( seed, sizeof( seed ) ); - - bls::PrivateKey sk = bls::AugSchemeMPL().KeyGen( bls::Bytes( seed, sizeof( seed ) ) ); - bls::G1Element localPk = std::move( MasterSkToLocalSK( sk ) ).GetG1Element(); - - // #See: chia-blockchain create_plots.py - // The plot public key is the combination of the harvester and farmer keys - // New plots will also include a taproot of the keys, for extensibility - const bool includeTaproot = cfg.contractPuzzleHash != nullptr; - - bls::G1Element plotPublicKey = std::move( GeneratePlotPublicKey( localPk, farmerPK, includeTaproot ) ); - - std::vector farmerPkBytes = farmerPK.Serialize(); - std::vector localSkBytes = sk.Serialize(); - // The plot id is based on the harvester, farmer, and pool keys - if( !includeTaproot ) + if( cfg.plotIdStr ) { - std::vector bytes = poolPK->Serialize(); + const size_t len = strlen( cfg.plotIdStr ); + if( len < 64 && len != 66 ) + Fatal( "Invalid plot id." ); - // Gen plot id - auto plotPkBytes = plotPublicKey.Serialize(); - bytes.insert( bytes.end(), plotPkBytes.begin(), plotPkBytes.end() ); - - bls::Util::Hash256( plotId, bytes.data(), bytes.size() ); - - // Gen memo - auto memoBytes = BytesConcat( poolPK->Serialize(), farmerPkBytes, localSkBytes ); - - const size_t poolMemoSize = 48 + 48 + 32; - ASSERT( memoBytes.size() == poolMemoSize ); - - memcpy( plotMemo, memoBytes.data(), poolMemoSize ); - outMemoSize = (uint16)poolMemoSize; + if( len == 66 ) + { + if( cfg.plotIdStr[0] == '0' && cfg.plotIdStr[1] == 'x' ) + cfg.plotIdStr += 2; + else + Fatal( "Invalid plot id." ); + } } - else + if( cfg.plotMemoStr ) { - // Create a pool plot with a contract puzzle hash - ASSERT( cfg.contractPuzzleHash ); - - const auto& ph = *cfg.contractPuzzleHash; - std::vector phBytes( (uint8_t*)ph.values, (uint8_t*)ph.values + ph.length ); + size_t len = strlen( cfg.plotMemoStr ); + if( len > 2 && cfg.plotMemoStr[0] == '0' && cfg.plotMemoStr[1] == 'x' ) + { + cfg.plotMemoStr += 2; + len -= 2; + } - // Gen plot id - std::vector plotIdBytes = phBytes; - auto plotPkBytes = plotPublicKey.Serialize(); - - plotIdBytes.insert( plotIdBytes.end(), plotPkBytes.begin(), plotPkBytes.end() ); - bls::Util::Hash256( plotId, plotIdBytes.data(), plotIdBytes.size() ); - - // Gen memo - auto memoBytes = BytesConcat( phBytes, farmerPkBytes, localSkBytes ); - - const size_t phMemoSize = 32 + 48 + 32; - ASSERT( memoBytes.size() == phMemoSize ); - - memcpy( plotMemo, memoBytes.data(), phMemoSize ); - outMemoSize = (uint16)phMemoSize; + if( len/2 != (48 + 48 + 32) && len != (32 + 48 + 32) ) + Fatal( "Invalid plot memo." ); } -} - -//----------------------------------------------------------- -bls::PrivateKey MasterSkToLocalSK( bls::PrivateKey& sk ) -{ - // #SEE: chia-blockchain: derive-keys.py - // EIP 2334 bls key derivation - // https://eips.ethereum.org/EIPS/eip-2334 - // 12381 = bls spec number - // 8444 = Chia blockchain number and port number - // 0, 1, 2, 3, 4, 5, 6 farmer, pool, wallet, local, backup key, singleton, pooling authentication key numbers - - const uint32 blsSpecNum = 12381; - const uint32 chiaBlockchainPort = 8444; - const uint32 localIdx = 3; - - bls::PrivateKey ssk = bls::AugSchemeMPL().DeriveChildSk( sk, blsSpecNum ); - ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, chiaBlockchainPort ); - ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, localIdx ); - ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, 0 ); - - return ssk; -} -//----------------------------------------------------------- -bls::G1Element GeneratePlotPublicKey( const bls::G1Element& localPk, bls::G1Element& farmerPk, const bool includeTaproot ) -{ - bls::G1Element plotPublicKey; - - if( includeTaproot ) - { - std::vector taprootMsg = (localPk + farmerPk).Serialize(); - taprootMsg = BytesConcat( taprootMsg, localPk.Serialize(), farmerPk.Serialize() ); - - byte tapRootHash[32]; - bls::Util::Hash256( tapRootHash, taprootMsg.data(), taprootMsg.size() ); - - bls::PrivateKey taprootSk = bls::AugSchemeMPL().KeyGen( bls::Bytes( tapRootHash, sizeof( tapRootHash ) ) ); - - plotPublicKey = localPk + farmerPk + taprootSk.GetG1Element(); - } + // Config Summary + Log::Line( "" ); + Log::Line( "[Global Plotting Config]" ); + if( cfg.plotCount == 0 ) + Log::Line( " Will create plots indefinitely." ); else - { - plotPublicKey = localPk + farmerPk; - } - - return plotPublicKey; -} + Log::Line( " Will create %u plots.", cfg.plotCount ); -//----------------------------------------------------------- -ByteSpan DecodePuzzleHash( const char* poolContractAddress ) -{ - ASSERT( poolContractAddress ); - - size_t length = strlen( poolContractAddress ); - - if( length < 9 ) - Fatal( "Error: Invalid pool contract address '%s'.", poolContractAddress ); - - char* hrp = (char*)malloc( length - 6 ); - byte* data = (byte*)malloc( length - 8 ); + Log::Line( " Thread count : %d", cfg.threadCount ); + Log::Line( " Warm start enabled : %s", cfg.warmStart ? "true" : "false" ); + Log::Line( " NUMA disabled : %s", cfg.disableNuma ? "true" : "false" ); + Log::Line( " CPU affinity disabled : %s", cfg.disableCpuAffinity ? "true" : "false" ); - size_t dataLength = 0; - bech32_encoding encoding = bech32_decode( hrp, data, &dataLength, poolContractAddress ); - if( encoding == BECH32_ENCODING_NONE ) - Fatal( "Error: Failed to decode contract address '%s'.", poolContractAddress ); + Log::Line( " Farmer public key : %s", farmerPublicKey ); + - ASSERT( dataLength > 0 ); - free( hrp ); + if( poolContractAddress ) + Log::Line( " Pool contract address : %s", poolContractAddress ); + else if( cfg.poolPublicKey ) + Log::Line( " Pool public key : %s", poolPublicKey ); - // See: convertbits in bech32m. py - // This extends fields from 5 bits to 8 bits - byte* decoded = (byte*)malloc( length - 8 ); + Log::Line( "" ); +} - const uint fromBits = 5; - const uint toBits = 8; - uint acc = 0; - uint bits = 0; - uint maxv = (1 << toBits) - 1; - uint maxAcc = (1 << (fromBits + toBits - 1)) - 1; - uint bitsLen = 0; +//----------------------------------------------------------- +static const char* USAGE = "bladebit [GLOBAL_OPTIONS] [COMMAND_OPTIONS]\n" +R"( +[COMMANDS] + diskplot : Create a plot by making use of a disk. + iotest : Perform a write and read test on a specified disk. + memtest : Perform a memory (RAM) copy test. + validate : Validates all entries in a plot to ensure they all evaluate to a valid proof. + help : Output this help message, or help for a specific command, if specified. + +[GLOBAL_OPTIONS]: + -h, --help : Shows this message and exits. - for( size_t i = 0; i < dataLength; i++ ) - { - uint value = data[i]; + -t, --threads : Maximum number of threads to use. + By default, this is set to the maximum number of logical cpus present. + + -n, --count : Number of plots to create. Default = 1. - if( value < 0 || (value >> fromBits) ) - Fatal( "Error: Invalid pool contract address '%s'. Could not decode bits.", poolContractAddress ); + -f, --farmer-key : Farmer public key, specified in hexadecimal format. + *REQUIRED* - acc = ((acc << fromBits) | value) & maxAcc; - bits += fromBits; - - while( bits >= toBits ) - { - ASSERT( bitsLen < length-8 ); - bits -= toBits; - decoded[bitsLen++] = (acc >> bits) & maxv; - } - } + -c, --pool-contract : Pool contract address. + Use this if you are creating pool plots. + *A pool contract address or a pool public key must be specified.* - if( bits >= fromBits || ((acc << (toBits - bits)) & maxv) ) - Fatal( "Error: Invalid pool contract addres bits '%s'.", poolContractAddress ); + -p, --pool-key : Pool public key, specified in hexadecimal format. + Use this if you are creating OG plots. + Only used if a pool contract address is not specified. - free( data ); + -w, --warm-start : Touch all pages of buffer allocations before starting to plot. - return ByteSpan( decoded, bitsLen ); -} + -i, --plot-id : Specify a plot id for debugging. -//----------------------------------------------------------- -bool HexPKeyToG1Element( const char* hexKey, bls::G1Element& pkey ) -{ - ASSERT( hexKey ); - - size_t length = strlen( hexKey ); + --memo : Specify a plot memo for debugging. - if( length < bls::G1Element::SIZE*2 ) - return false; + --show-memo : Output the memo of the next plot the be plotted. - if( hexKey[0] == '0' && hexKey[1] == 'x' ) - { - hexKey += 2; - length -= 2; - } + -v, --verbose : Enable verbose output. - if( length != bls::G1Element::SIZE*2 ) - return false; + -m, --no-numa : Disable automatic NUMA aware memory binding. + If you set this parameter in a NUMA system you + will likely get degraded performance. - byte g1Buffer[bls::G1Element::SIZE]; - HexStrToBytes( hexKey, length, g1Buffer, sizeof( g1Buffer ) ); + --no-cpu-affinity : Disable assigning automatic thread affinity. + This is useful when running multiple simultaneous + instances of Bladebit as you can manually + assign thread affinity yourself when launching Bladebit. + + --memory : Display system memory available, in bytes, and the + required memory to run Bladebit, in bytes. + + --memory-json : Same as --memory, but formats the output as json. - bls::Bytes g1Bytes( g1Buffer, sizeof( g1Buffer ) ); + --version : Display current version. - pkey = bls::G1Element::FromBytes( g1Bytes ); - - return pkey.IsValid(); -} -//----------------------------------------------------------- -void GetPlotIdBytes( const std::string& plotId, byte outBytes[32] ) -{ - const char* pId = plotId.c_str(); - if( plotId.length() == 66 ) - { - ASSERT( pId[0] == '0' && pId[1] == 'x' ); - pId += 2; - } +[EXAMPLES] +bladebit --help - HexStrToBytes( pId, 64, outBytes, 32 ); -} +bladebiy help diskplot +bladebit -t 24 -f ... -c ... diskplot --f1 256MB --fx 256MB -t /my/temporary/plot/dir + --f1-threads 3 --c-threads 8 --p2-threads 12 --p3-threads 8 /my/output/dir -//----------------------------------------------------------- -inline std::vector BytesConcat( std::vector a, std::vector b, std::vector c ) -{ - a.insert( a.end(), b.begin(), b.end() ); - a.insert( a.end(), c.begin(), c.end() ); - return a; -} +bladebit -t 8 -f ... -c ... diskplot --f1 64MB --fx 128MB -t /my/temporary/plot/dir /my/output/dir +)"; //----------------------------------------------------------- void PrintUsage() { - Log::Line( "bladebit v%s-%s\n", BLADEBIT_VERSION_STR, BLADEBIT_GIT_COMMIT ); - Log::Line( "Usage:" ); - fputs( USAGE, stdout ); - fflush( stdout ); -} - -#if _DEBUG - //----------------------------------------------------------- - std::string HexToString( const byte* bytes, size_t length ) - { - ASSERT( length ); - - const size_t slen = length * 2 + 1; - char* buffer = (char*)malloc( slen ); - memset( buffer, 0, slen ); - - size_t numEncoded; - BytesToHexStr( bytes, length, buffer, slen, numEncoded ); - - std::string str( buffer ); - free( buffer ); - - return str; - } - - //----------------------------------------------------------- - std::vector HexStringToBytes( const char* hexStr ) - { - const size_t len = strlen( hexStr ); - - byte* buffer = (byte*)malloc( len / 2 ); - - HexStrToBytes( hexStr, len, buffer, len / 2 ); - std::vector ret( buffer, buffer + len / 2 ); - - free( buffer ); - return ret; - } - - //----------------------------------------------------------- - std::vector HexStringToBytes( const std::string& hexStr ) - { - return HexStringToBytes( hexStr.c_str() ); - } - - //----------------------------------------------------------- - void PrintPK( const bls::G1Element& key ) - { - std::vector bytes = key.Serialize(); - Log::Line( "%s", HexToString( (byte*)bytes.data(), bytes.size() ).c_str() ); - } - - //----------------------------------------------------------- - void PrintSK( const bls::PrivateKey& key ) - { - std::vector bytes = key.Serialize(); - Log::Line( "%s", HexToString( (byte*)bytes.data(), bytes.size() ).c_str() ); - } -#endif + Log::Line( USAGE ); +} \ No newline at end of file diff --git a/src/main_old.h b/src/main_old.h new file mode 100644 index 00000000..d0d70ec8 --- /dev/null +++ b/src/main_old.h @@ -0,0 +1,786 @@ +#include +#include +#include + +#include "Version.h" +#include "util/Util.h" +#include "util/Log.h" +#include "SysHost.h" +#include "plotmem/MemPlotter.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type" + +#pragma warning( push ) + +extern "C" { + #include "bech32/segwit_addr.h" +} + +#pragma GCC diagnostic ignored "-Wsign-compare" +#pragma warning( disable : 6287 ) +#pragma warning( disable : 4267 ) +#pragma warning( disable : 26495 ) +#include "bls.hpp" +#include "elements.hpp" +#include "schemes.hpp" +#include "util.hpp" +#pragma GCC diagnostic pop +#pragma warning( pop ) + +#define PLOT_FILE_PREFIX_LEN (sizeof("plot-k32-2021-08-05-18-55-")-1) +#define PLOT_FILE_FMT_LEN (sizeof( "/plot-k32-2021-08-05-18-55-77a011fc20f0003c3adcc739b615041ae56351a22b690fd854ccb6726e5f43b7.plot.tmp" )) + +/// Internal Data Structures +struct Config +{ + uint threads = 0; + uint plotCount = 1; + bool warmStart = false; + bool disableNuma = false; + bool disableCpuAffinity = false; + + bls::G1Element farmerPublicKey; + bls::G1Element* poolPublicKey = nullptr; + + ByteSpan* contractPuzzleHash = nullptr; + const char* outputFolder = nullptr; + + int maxFailCount = 100; + + const char* plotId = nullptr; + const char* plotMemo = nullptr; + bool showMemo = false; +}; + +/// Internal Functions +void ParseCommandLine( int argc, const char* argv[], Config& cfg ); +bool HexPKeyToG1Element( const char* hexKey, bls::G1Element& pkey ); + +ByteSpan DecodePuzzleHash( const char* poolContractAddress ); +void GeneratePlotIdAndMemo( Config& cfg, byte plotId[32], byte plotMemo[48+48+32], uint16& outMemoSize ); +bls::PrivateKey MasterSkToLocalSK( bls::PrivateKey& sk ); +bls::G1Element GeneratePlotPublicKey( const bls::G1Element& localPk, bls::G1Element& farmerPk, const bool includeTaproot ); + +std::vector BytesConcat( std::vector a, std::vector b, std::vector c ); + +void PrintSysInfo(); +void GetPlotIdBytes( const std::string& plotId, byte outBytes[32] ); +void PrintUsage(); + +#if _DEBUG + std::string HexToString( const byte* bytes, size_t length ); + std::vector HexStringToBytes( const char* hexStr ); + std::vector HexStringToBytes( const std::string& hexStr ); + void PrintPK( const bls::G1Element& key ); + void PrintSK( const bls::PrivateKey& key ); +#endif + +//----------------------------------------------------------- +const char* USAGE = "bladebit [] []\n" +R"( +: Output directory in which to output the plots. + This directory must exist. + +OPTIONS: + + -h, --help : Shows this message and exits. + + -t, --threads : Maximum number of threads to use. + For best performance, use all available threads (default behavior). + Values below 2 are not recommended. + + -n, --count : Number of plots to create. Default = 1. + + -f, --farmer-key : Farmer public key, specified in hexadecimal format. + *REQUIRED* + + -p, --pool-key : Pool public key, specified in hexadecimal format. + Either a pool public key or a pool contract address must be specified. + + -c, --pool-contract : Pool contract address, specified in hexadecimal format. + Address where the pool reward will be sent to. + Only used if pool public key is not specified. + + -w, --warm-start : Touch all pages of buffer allocations before starting to plot. + + -i, --plot-id : Specify a plot id for debugging. + + --memo : Specify a plot memo for debugging. + + --show-memo : Output the memo of the next plot the be plotted. + + -v, --verbose : Enable verbose output. + + -m, --no-numa : Disable automatic NUMA aware memory binding. + If you set this parameter in a NUMA system you + will likely get degraded performance. + + --no-cpu-affinity : Disable assigning automatic thread affinity. + This is useful when running multiple simultaneous + instances of Bladebit as you can manually + assign thread affinity yourself when launching Bladebit. + + --memory : Display system memory available, in bytes, and the + required memory to run Bladebit, in bytes. + + --memory-json : Same as --memory, but formats the output as json. + + --version : Display current version. +)"; + + +//----------------------------------------------------------- +int main( int argc, const char* argv[] ) +{ + // Install a crash handler to dump our stack traces + SysHost::InstallCrashHandler(); + + // Parse command line info + Config cfg; + ParseCommandLine( argc-1, argv+1, cfg ); + + // Create the plot output path + size_t outputFolderLen = strlen( cfg.outputFolder ); + + char* plotOutPath = new char[outputFolderLen + PLOT_FILE_FMT_LEN]; + + if( outputFolderLen ) + { + memcpy( plotOutPath, cfg.outputFolder, outputFolderLen ); + + // Add a trailing slash, if we need one. + if( plotOutPath[outputFolderLen-1] != '/' ) + plotOutPath[outputFolderLen++] = '/'; + } + + // Begin plotting + PlotRequest req; + ZeroMem( &req ); + + // #TODO: Don't let this config to permanently remain on the stack + MemPlotConfig plotCfg; + plotCfg.threadCount = cfg.threads; + plotCfg.noNUMA = cfg.disableNuma; + plotCfg.noCPUAffinity = cfg.disableCpuAffinity; + plotCfg.warmStart = cfg.warmStart; + + MemPlotter plotter( plotCfg ); + + byte plotId[32]; + byte memo [48+48+32]; + uint16 memoSize; + char plotIdStr[65] = { 0 }; + + int failCount = 0; + for( uint i = 0; i < cfg.plotCount; i++ ) + { + // Generate a new plot id + GeneratePlotIdAndMemo( cfg, plotId, memo, memoSize ); + + // Apply debug plot id and/or memo + if( cfg.plotId ) + HexStrToBytes( cfg.plotId, 64, plotId, 32 ); + + if( cfg.plotMemo ) + { + const size_t memoLen = strlen( cfg.plotMemo ); + HexStrToBytes( cfg.plotMemo, memoLen, memo, memoLen/2 ); + } + + // Convert plot id to string + { + size_t numEncoded = 0; + BytesToHexStr( plotId, sizeof( plotId), plotIdStr, sizeof( plotIdStr ), numEncoded ); + + ASSERT( numEncoded == 32 ); + plotIdStr[64] = 0; + } + + // Set the output path + { + time_t now = time( nullptr ); + struct tm* t = localtime( &now ); ASSERT( t ); + + const size_t r = strftime( plotOutPath + outputFolderLen, PLOT_FILE_FMT_LEN, "plot-k32-%Y-%m-%d-%H-%M-", t ); + if( r != PLOT_FILE_PREFIX_LEN ) + Fatal( "Failed to generate plot file." ); + + memcpy( plotOutPath + outputFolderLen + PLOT_FILE_PREFIX_LEN , plotIdStr, 64 ); + memcpy( plotOutPath + outputFolderLen + PLOT_FILE_PREFIX_LEN + 64, ".plot.tmp", sizeof( ".plot.tmp" ) ); + } + + Log::Line( "Generating plot %d / %d: %s", i+1, cfg.plotCount, plotIdStr ); + if( cfg.showMemo ) + { + char memoStr[(48+48+32)*2 + 1]; + + size_t numEncoded = 0; + BytesToHexStr( memo, memoSize, memoStr, sizeof( memoStr ) - 1, numEncoded ); + memoStr[numEncoded*2] = 0; + + Log::Line( "Plot Memo: %s", memoStr ); + } + Log::Line( "" ); + + // Prepare the request + req.outPath = plotOutPath; + req.plotId = plotId; + req.memo = memo; + req.memoSize = memoSize; + req.IsFinalPlot = i+1 == cfg.plotCount; + + // Plot it + if( !plotter.Run( req ) ) + { + Log::Error( "Error: Plot %s failed... Trying next plot.", plotIdStr ); + if( cfg.maxFailCount > 0 && ++failCount >= cfg.maxFailCount ) + { + // #TODO: Wait for pending plot writes to disk + Fatal( "Maximum number of plot failures reached. Exiting." ); + } + } + + Log::Line( "" ); + } + + Log::Flush(); + return 0; +} + +//----------------------------------------------------------- +void ParseCommandLine( int argc, const char* argv[], Config& cfg ) +{ + #define check( a ) (strcmp( a, arg ) == 0) + int i; + const char* arg = nullptr; + + auto value = [&](){ + + if( ++i >= argc ) + Fatal( "Expected a value for parameter '%s'", arg ); + + return argv[i]; + }; + + auto ivalue = [&]() { + + const char* val = value(); + int64 v = 0; + + int r = sscanf( val, "%lld", &v ); + if( r != 1 ) + Fatal( "Invalid value for argument '%s'.", arg ); + + return v; + }; + + auto uvalue = [&]() { + + int64 v = ivalue(); + if( v < 0 || v > 0xFFFFFFFF ) + Fatal( "Invalid value for argument '%s'. Value '%ld' is out of range.", arg, v ); + + return (uint32)v; + }; + + const char* farmerPublicKey = nullptr; + const char* poolPublicKey = nullptr; + const char* poolContractAddress = nullptr; + + for( i = 0; i < argc; i++ ) + { + arg = argv[i]; + + if( check( "-h" ) || check( "--help") ) + { + PrintUsage(); + exit( 0 ); + } + else if( check( "-t" ) || check( "--threads") ) + { + cfg.threads = uvalue(); + + if( cfg.threads == 1 ) + Log::Line( "Warning: Only 1 thread was specified. Sub-optimal performance expected." ); + } + else if( check( "-n" ) || check( "--count" ) ) + { + cfg.plotCount = uvalue(); + if( cfg.plotCount < 1 ) + { + Log::Line( "Warning: Invalid plot count specified. Setting it to 1." ); + cfg.plotCount = 1; + } + } + else if( check( "-f" ) || check( "--farmer-key" ) ) + { + farmerPublicKey = value(); + } + else if( check( "-p" ) || check( "--pool-key" ) ) + { + poolPublicKey = value(); + } + else if( check( "-c" ) || check( "--pool-contract" ) ) + { + poolContractAddress = value(); + } + else if( check( "-w" ) || check( "--warm-start" ) ) + { + cfg.warmStart = true; + } + else if( check( "-i" ) || check( "--plot-id" ) ) + { + cfg.plotId = value(); + + size_t len = strlen( cfg.plotId ); + if( len < 64 && len != 66 ) + Fatal( "Invalid plot id." ); + + if( len == 66 ) + { + if( cfg.plotId[0] == '0' && cfg.plotId[1] == 'x' ) + cfg.plotId += 2; + else + Fatal( "Invalid plot id." ); + } + } + else if( check( "--memo" ) ) + { + cfg.plotMemo = value(); + + size_t len = strlen( cfg.plotMemo ); + if( len > 2 && cfg.plotMemo[0] == '0' && cfg.plotMemo[1] == 'x' ) + { + cfg.plotMemo += 2; + len -= 2; + } + + if( len/2 != (48 + 48 + 32) && len != (32 + 48 + 32) ) + Fatal( "Invalid plot memo." ); + } + else if( check( "--show-memo" ) ) + { + cfg.showMemo = true; + } + else if( check( "-m" ) || check( "--no-numa" ) ) + { + cfg.disableNuma = true; + } + else if( check( "--no-cpu-affinity" ) ) + { + cfg.disableCpuAffinity = true; + } + else if( check( "-v" ) || check( "--verbose" ) ) + { + Log::SetVerbose( true ); + } + else if( check( "--memory" ) ) + { + // #TODO: Get this value from Memplotter + const size_t requiredMem = 416ull GB; + const size_t availableMem = SysHost::GetAvailableSystemMemory(); + const size_t totalMem = SysHost::GetTotalSystemMemory(); + + Log::Line( "required : %llu", requiredMem ); + Log::Line( "total : %llu", totalMem ); + Log::Line( "available: %llu", availableMem ); + + exit( 0 ); + } + else if( check( "--memory-json" ) ) + { + // #TODO: Get this value from Memplotter + const size_t requiredMem = 416ull GB; + const size_t availableMem = SysHost::GetAvailableSystemMemory(); + const size_t totalMem = SysHost::GetTotalSystemMemory(); + + Log::Line( "{ \"required\": %llu, \"total\": %llu, \"available\": %llu }", + requiredMem, totalMem, availableMem ); + + exit( 0 ); + } + else if( check( "--version" ) ) + { + Log::Line( BLADEBIT_VERSION_STR ); + exit( 0 ); + } + else + { + if( i+1 < argc ) + { + Fatal( "Unexpected argument '%s'.", arg ); + exit( 1 ); + } + + cfg.outputFolder = arg; + } + } + #undef check + + + if( farmerPublicKey ) + { + if( !HexPKeyToG1Element( farmerPublicKey, cfg.farmerPublicKey ) ) + Fatal( "Failed to parse farmer public key '%s'.", farmerPublicKey ); + + // Remove 0x prefix for printing + if( farmerPublicKey[0] == '0' && farmerPublicKey[1] == 'x' ) + farmerPublicKey += 2; + } + else + Fatal( "A farmer public key is required. Please specify a farmer public key." ); + + if( poolPublicKey ) + { + if( poolContractAddress ) + Log::Write( "Warning: Pool contract address will not be used. A pool public key was specified." ); + + // cfg.poolPublicKey = new bls::G1Element() + bls::G1Element poolPubG1; + if( !HexPKeyToG1Element( poolPublicKey, poolPubG1 ) ) + Fatal( "Error: Failed to parse pool public key '%s'.", poolPublicKey ); + + cfg.poolPublicKey = new bls::G1Element( std::move( poolPubG1 ) ); + + // Remove 0x prefix for printing + if( poolPublicKey[0] == '0' && poolPublicKey[1] == 'x' ) + poolPublicKey += 2; + } + else if( poolContractAddress ) + { + cfg.contractPuzzleHash = new ByteSpan( std::move( DecodePuzzleHash( poolContractAddress ) ) ); + } + else + Fatal( "Error: Either a pool public key or a pool contract address must be specified." ); + + + const uint threadCount = SysHost::GetLogicalCPUCount(); + + if( cfg.threads == 0 ) + cfg.threads = threadCount; + else if( cfg.threads > threadCount ) + { + Log::Write( "Warning: Lowering thread count from %d to %d, the native maximum.", + cfg.threads, threadCount ); + + cfg.threads = threadCount; + } + + if( cfg.plotCount < 1 ) + cfg.plotCount = 1; + + if( cfg.outputFolder == nullptr ) + { + Log::Line( "Warning: No output folder specified. Using current directory." ); + cfg.outputFolder = ""; + } + + Log::Line( "Creating %d plots:", cfg.plotCount ); + + if( cfg.outputFolder ) + Log::Line( " Output path : %s", cfg.outputFolder ); + else + Log::Line( " Output path : Current directory." ); + + Log::Line( " Thread count : %d", cfg.threads ); + Log::Line( " Warm start enabled : %s", cfg.warmStart ? "true" : "false" ); + + + Log::Line( " Farmer public key : %s", farmerPublicKey ); + + if( poolPublicKey ) + Log::Line( " Pool public key : %s", poolPublicKey ); + else if( poolContractAddress ) + Log::Line( " Pool contract address : %s", poolContractAddress ); + + Log::Line( "" ); +} + +//----------------------------------------------------------- +void GeneratePlotIdAndMemo( Config& cfg, byte plotId[32], byte plotMemo[48+48+32], uint16& outMemoSize ) +{ + bls::G1Element& farmerPK = cfg.farmerPublicKey; + bls::G1Element* poolPK = cfg.poolPublicKey; + + // Generate random master secret key + byte seed[32]; + SysHost::Random( seed, sizeof( seed ) ); + + bls::PrivateKey sk = bls::AugSchemeMPL().KeyGen( bls::Bytes( seed, sizeof( seed ) ) ); + bls::G1Element localPk = std::move( MasterSkToLocalSK( sk ) ).GetG1Element(); + + // #See: chia-blockchain create_plots.py + // The plot public key is the combination of the harvester and farmer keys + // New plots will also include a taproot of the keys, for extensibility + const bool includeTaproot = cfg.contractPuzzleHash != nullptr; + + bls::G1Element plotPublicKey = std::move( GeneratePlotPublicKey( localPk, farmerPK, includeTaproot ) ); + + std::vector farmerPkBytes = farmerPK.Serialize(); + std::vector localSkBytes = sk.Serialize(); + + // The plot id is based on the harvester, farmer, and pool keys + if( !includeTaproot ) + { + std::vector bytes = poolPK->Serialize(); + + // Gen plot id + auto plotPkBytes = plotPublicKey.Serialize(); + bytes.insert( bytes.end(), plotPkBytes.begin(), plotPkBytes.end() ); + + bls::Util::Hash256( plotId, bytes.data(), bytes.size() ); + + // Gen memo + auto memoBytes = BytesConcat( poolPK->Serialize(), farmerPkBytes, localSkBytes ); + + const size_t poolMemoSize = 48 + 48 + 32; + ASSERT( memoBytes.size() == poolMemoSize ); + + memcpy( plotMemo, memoBytes.data(), poolMemoSize ); + outMemoSize = (uint16)poolMemoSize; + } + else + { + // Create a pool plot with a contract puzzle hash + ASSERT( cfg.contractPuzzleHash ); + + const auto& ph = *cfg.contractPuzzleHash; + std::vector phBytes( (uint8_t*)ph.values, (uint8_t*)ph.values + ph.length ); + + // Gen plot id + std::vector plotIdBytes = phBytes; + auto plotPkBytes = plotPublicKey.Serialize(); + + plotIdBytes.insert( plotIdBytes.end(), plotPkBytes.begin(), plotPkBytes.end() ); + bls::Util::Hash256( plotId, plotIdBytes.data(), plotIdBytes.size() ); + + // Gen memo + auto memoBytes = BytesConcat( phBytes, farmerPkBytes, localSkBytes ); + + const size_t phMemoSize = 32 + 48 + 32; + ASSERT( memoBytes.size() == phMemoSize ); + + memcpy( plotMemo, memoBytes.data(), phMemoSize ); + outMemoSize = (uint16)phMemoSize; + } +} + +//----------------------------------------------------------- +bls::PrivateKey MasterSkToLocalSK( bls::PrivateKey& sk ) +{ + // #SEE: chia-blockchain: derive-keys.py + // EIP 2334 bls key derivation + // https://eips.ethereum.org/EIPS/eip-2334 + // 12381 = bls spec number + // 8444 = Chia blockchain number and port number + // 0, 1, 2, 3, 4, 5, 6 farmer, pool, wallet, local, backup key, singleton, pooling authentication key numbers + + const uint32 blsSpecNum = 12381; + const uint32 chiaBlockchainPort = 8444; + const uint32 localIdx = 3; + + bls::PrivateKey ssk = bls::AugSchemeMPL().DeriveChildSk( sk, blsSpecNum ); + ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, chiaBlockchainPort ); + ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, localIdx ); + ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, 0 ); + + return ssk; +} + +//----------------------------------------------------------- +bls::G1Element GeneratePlotPublicKey( const bls::G1Element& localPk, bls::G1Element& farmerPk, const bool includeTaproot ) +{ + bls::G1Element plotPublicKey; + + if( includeTaproot ) + { + std::vector taprootMsg = (localPk + farmerPk).Serialize(); + taprootMsg = BytesConcat( taprootMsg, localPk.Serialize(), farmerPk.Serialize() ); + + byte tapRootHash[32]; + bls::Util::Hash256( tapRootHash, taprootMsg.data(), taprootMsg.size() ); + + bls::PrivateKey taprootSk = bls::AugSchemeMPL().KeyGen( bls::Bytes( tapRootHash, sizeof( tapRootHash ) ) ); + + plotPublicKey = localPk + farmerPk + taprootSk.GetG1Element(); + } + else + { + plotPublicKey = localPk + farmerPk; + } + + return plotPublicKey; +} + +//----------------------------------------------------------- +ByteSpan DecodePuzzleHash( const char* poolContractAddress ) +{ + ASSERT( poolContractAddress ); + + size_t length = strlen( poolContractAddress ); + + if( length < 9 ) + Fatal( "Error: Invalid pool contract address '%s'.", poolContractAddress ); + + char* hrp = (char*)malloc( length - 6 ); + byte* data = (byte*)malloc( length - 8 ); + + size_t dataLength = 0; + bech32_encoding encoding = bech32_decode( hrp, data, &dataLength, poolContractAddress ); + if( encoding == BECH32_ENCODING_NONE ) + Fatal( "Error: Failed to decode contract address '%s'.", poolContractAddress ); + + ASSERT( dataLength > 0 ); + free( hrp ); + + // See: convertbits in bech32m.py + // This extends fields from 5 bits to 8 bits + byte* decoded = (byte*)malloc( length - 8 ); + + const uint fromBits = 5; + const uint toBits = 8; + + uint acc = 0; + uint bits = 0; + uint maxv = (1 << toBits) - 1; + uint maxAcc = (1 << (fromBits + toBits - 1)) - 1; + uint bitsLen = 0; + + for( size_t i = 0; i < dataLength; i++ ) + { + uint value = data[i]; + + if( value < 0 || (value >> fromBits) ) + Fatal( "Error: Invalid pool contract address '%s'. Could not decode bits.", poolContractAddress ); + + acc = ((acc << fromBits) | value) & maxAcc; + bits += fromBits; + + while( bits >= toBits ) + { + ASSERT( bitsLen < length-8 ); + bits -= toBits; + decoded[bitsLen++] = (acc >> bits) & maxv; + } + } + + if( bits >= fromBits || ((acc << (toBits - bits)) & maxv) ) + Fatal( "Error: Invalid pool contract address bits '%s'.", poolContractAddress ); + + free( data ); + + return ByteSpan( decoded, bitsLen ); +} + +//----------------------------------------------------------- +bool HexPKeyToG1Element( const char* hexKey, bls::G1Element& pkey ) +{ + ASSERT( hexKey ); + + size_t length = strlen( hexKey ); + + if( length < bls::G1Element::SIZE*2 ) + return false; + + if( hexKey[0] == '0' && hexKey[1] == 'x' ) + { + hexKey += 2; + length -= 2; + } + + if( length != bls::G1Element::SIZE*2 ) + return false; + + byte g1Buffer[bls::G1Element::SIZE]; + HexStrToBytes( hexKey, length, g1Buffer, sizeof( g1Buffer ) ); + + bls::Bytes g1Bytes( g1Buffer, sizeof( g1Buffer ) ); + + pkey = bls::G1Element::FromBytes( g1Bytes ); + + return pkey.IsValid(); +} + +//----------------------------------------------------------- +void GetPlotIdBytes( const std::string& plotId, byte outBytes[32] ) +{ + const char* pId = plotId.c_str(); + if( plotId.length() == 66 ) + { + ASSERT( pId[0] == '0' && pId[1] == 'x' ); + pId += 2; + } + + HexStrToBytes( pId, 64, outBytes, 32 ); +} + + +//----------------------------------------------------------- +inline std::vector BytesConcat( std::vector a, std::vector b, std::vector c ) +{ + a.insert( a.end(), b.begin(), b.end() ); + a.insert( a.end(), c.begin(), c.end() ); + return a; +} + +//----------------------------------------------------------- +void PrintUsage() +{ + fputs( USAGE, stderr ); + fflush( stderr ); +} + +#if _DEBUG + //----------------------------------------------------------- + std::string HexToString( const byte* bytes, size_t length ) + { + ASSERT( length ); + + const size_t slen = length * 2 + 1; + char* buffer = (char*)malloc( slen ); + memset( buffer, 0, slen ); + + size_t numEncoded; + BytesToHexStr( bytes, length, buffer, slen, numEncoded ); + + std::string str( buffer ); + free( buffer ); + + return str; + } + + //----------------------------------------------------------- + std::vector HexStringToBytes( const char* hexStr ) + { + const size_t len = strlen( hexStr ); + + byte* buffer = (byte*)malloc( len / 2 ); + + HexStrToBytes( hexStr, len, buffer, len / 2 ); + std::vector ret( buffer, buffer + len / 2 ); + + free( buffer ); + return ret; + } + + //----------------------------------------------------------- + std::vector HexStringToBytes( const std::string& hexStr ) + { + return HexStringToBytes( hexStr.c_str() ); + } + + //----------------------------------------------------------- + void PrintPK( const bls::G1Element& key ) + { + std::vector bytes = key.Serialize(); + Log::Line( "%s", HexToString( (byte*)bytes.data(), bytes.size() ).c_str() ); + } + + //----------------------------------------------------------- + void PrintSK( const bls::PrivateKey& key ) + { + std::vector bytes = key.Serialize(); + Log::Line( "%s", HexToString( (byte*)bytes.data(), bytes.size() ).c_str() ); + } +#endif diff --git a/src/pch.cpp b/src/pch.cpp index 1d9f38c5..9e6b2e07 100644 --- a/src/pch.cpp +++ b/src/pch.cpp @@ -1 +1 @@ -#include "pch.h" +#include "pch.h" diff --git a/src/pch.h b/src/pch.h index 3b444d8a..44e56636 100644 --- a/src/pch.h +++ b/src/pch.h @@ -1,23 +1,33 @@ -#pragma once - -// Only for our own files, don't include in third party C files -#ifdef __cplusplus - -#include -#include -#include -#include -#include - -#if _DEBUG - #include - #define ASSERT( x ) assert( x ) -#else - #define ASSERT( x ) -#endif - -// Only include from C++ files -#include "Globals.h" -#include "Types.h" - -#endif // __cplusplus \ No newline at end of file +#pragma once + +// Only for our own files, don't include in third party C files +#ifdef __cplusplus + +#include +#include +#include +#include +#include +#include +#include +#include "Platform.h" + +// Defined in Util.cpp +bool AssertLog( int line, const char* file, const char* func ); + +#if _DEBUG + #include + #define ASSERT( condition ) \ + { if( !(condition) ) { AssertLog( __LINE__, __FILE__, __FUNCTION__ ); BBDebugBreak(); } } +// assert( x ) +#else + #define ASSERT( x ) +#endif + +// Only include from C++ files +#include "Globals.h" +#include "Types.h" +#include "Config.h" +#include "util/Span.h" + +#endif // __cplusplus diff --git a/src/platform/linux/SysHost_Linux.cpp b/src/platform/linux/SysHost_Linux.cpp index f9ef1e39..808b8ff8 100644 --- a/src/platform/linux/SysHost_Linux.cpp +++ b/src/platform/linux/SysHost_Linux.cpp @@ -1,402 +1,445 @@ -#include "SysHost.h" -#include "Platform.h" -#include "Util.h" - -#include -#include -#include -#include -#include -#include - -// #if _DEBUG - #include "util/Log.h" -// #endif - -std::atomic _crashed = false; - -//----------------------------------------------------------- -size_t SysHost::GetPageSize() -{ - return (size_t)getpagesize(); -} - -//----------------------------------------------------------- -size_t SysHost::GetTotalSystemMemory() -{ - const size_t pageSize = GetPageSize(); - return (size_t)get_phys_pages() * pageSize; -} - -//----------------------------------------------------------- -size_t SysHost::GetAvailableSystemMemory() -{ - const size_t pageSize = GetPageSize(); - return (size_t)get_avphys_pages() * pageSize; -} - -//----------------------------------------------------------- - uint SysHost::GetLogicalCPUCount() - { - return (uint)get_nprocs(); - } - -//----------------------------------------------------------- -void* SysHost::VirtualAlloc( size_t size, bool initialize ) -{ - // Align size to page boundary - const size_t pageSize = GetPageSize(); - - size = RoundUpToNextBoundary( size, (int)pageSize ); - - // #TODO: Don't use a whole page size. But provide a VirtualAllocAligned for the block-aligned allocations - // Add one page to store our size (yup a whole page for it...) - size += pageSize; - - void* ptr = mmap( NULL, size, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, - -1, 0 - ); - - if( ptr == MAP_FAILED ) - { - #if _DEBUG - const int err = errno; - Log::Line( "Error: mmap() returned %d (0x%x).", err, err ); - ASSERT( 0 ); - #endif - - return nullptr; - } - - if( initialize ) - { - byte* page = (byte*)ptr; - - const size_t pageCount = size / pageSize; - const byte* endPage = page + pageCount * pageSize; - - do - { - *page = 0; - page += pageSize; - } while( page < endPage ); - } - - *((size_t*)ptr) = size; - - return ((byte*)ptr)+pageSize; -} - -//----------------------------------------------------------- -void SysHost::VirtualFree( void* ptr ) -{ - ASSERT( ptr ); - if( !ptr ) - return; - - const size_t pageSize = GetPageSize(); - - byte* realPtr = ((byte*)ptr) - pageSize; - const size_t size = *((size_t*)realPtr); - - munmap( realPtr, size ); -} - -//----------------------------------------------------------- -bool SysHost::VirtualProtect( void* ptr, size_t size, VProtect flags ) -{ - ASSERT( ptr ); - - int prot = 0; - - if( IsFlagSet( flags, VProtect::NoAccess ) ) - { - prot = PROT_NONE; - } - else - { - if( IsFlagSet( flags, VProtect::Read ) ) - prot |= PROT_READ; - if( IsFlagSet( flags, VProtect::Write ) ) - prot |= PROT_WRITE; - } - - int r = mprotect( ptr, size, prot ); - ASSERT( !r ); - - return r == 0; -} - -//----------------------------------------------------------- -// uint64 SysHost::SetCurrentProcessAffinityMask( uint64 mask ) -// { -// return SetCurrentThreadAffinityMask( mask ); -// } - -// //----------------------------------------------------------- -// uint64 SysHost::SetCurrentThreadAffinityMask( uint64 mask ) -// { -// pthread_t thread = pthread_self(); - -// cpu_set_t cpuSet; -// CPU_ZERO( &cpuSet ); - -// if( mask == 0 ) -// CPU_SET( 1, &cpuSet ); -// else -// { -// for( uint i = 0; i < 64; i++ ) -// { -// if( mask & (1ull << i ) ) -// CPU_SET( i+1, &cpuSet ); -// } -// } - -// int r = pthread_setaffinity_np( thread, sizeof(cpu_set_t), &cpuSet ); -// if( r != 0 ) -// { -// ASSERT( 0 ); -// return 0; -// } - -// r = pthread_getaffinity_np( thread, sizeof(cpu_set_t), &cpuSet ); -// if( r != 0 ) -// { -// ASSERT( 0 ); -// return 0; -// } - -// return mask; -// } - -//----------------------------------------------------------- -bool SysHost::SetCurrentThreadAffinityCpuId( uint32 cpuId ) -{ - pthread_t thread = pthread_self(); - - cpu_set_t cpuSet; - CPU_ZERO( &cpuSet ); - CPU_SET( cpuId, &cpuSet ); - - int r = pthread_setaffinity_np( thread, sizeof(cpu_set_t), &cpuSet ); - return r == 0; -} - -//----------------------------------------------------------- -void CrashHandler( int signal ) -{ - // Only let the first thread handle the crash - bool crashed = false; - if( !_crashed.compare_exchange_strong( crashed, true, - std::memory_order_release, std::memory_order_relaxed ) ) - { - return; - } - - const size_t MAX_POINTERS = 256; - void* stackTrace[256] = { 0 }; - - fprintf( stderr, "*** Crashed! ***\n" ); - fflush( stderr ); - - int traceSize = backtrace( stackTrace, (int)MAX_POINTERS ); - backtrace_symbols_fd( stackTrace, traceSize, fileno( stderr ) ); - fflush( stderr ); - - exit( 1 ); -} - -//----------------------------------------------------------- -void SysHost::InstallCrashHandler() -{ - signal( SIGSEGV, CrashHandler ); -} - -//----------------------------------------------------------- -void SysHost::Random( byte* buffer, size_t size ) -{ - // See: https://man7.org/linux/man-pages/man2/getrandom.2.html - - ssize_t sizeRead; - byte* writer = buffer; - const byte* end = writer + size; - - const size_t BLOCK_SIZE = 256; - - while( writer < end ) - { - size_t readSize = (size_t)(end - writer); - if( readSize > BLOCK_SIZE ) - readSize = BLOCK_SIZE; - - sizeRead = getrandom( writer, readSize, 0 ); - - // Should never get EINTR, but docs say to check anyway. - if( sizeRead < 0 && errno != EINTR ) - Fatal( "getrandom syscall failed." ); - - writer += (size_t)sizeRead; - } -} - -// #NOTE: This is not thread-safe -//----------------------------------------------------------- -const NumaInfo* SysHost::GetNUMAInfo() -{ - if( numa_available() == -1 ) - return nullptr; - - static NumaInfo _info; - static NumaInfo* info = nullptr; - - // Initialize if not initialized - if( !info ) - { - memset( &_info, 0, sizeof( NumaInfo ) ); - - const uint nodeCount = (uint)numa_num_configured_nodes(); - - uint totalCpuCount = 0; - Span* cpuIds = (Span*)malloc( sizeof( uint* ) * nodeCount ); - - - for( uint i = 0; i < nodeCount; i++ ) - { - bitmask* cpuMask = numa_allocate_cpumask(); - if( !cpuMask ) - Fatal( "Failed to allocate NUMA CPU mask." ); - - int r = numa_node_to_cpus( i, cpuMask ); - - if( r ) - { - int err = errno; - Fatal( "Failed to get cpus from NUMA node %u with error: %d (0x%x)", i, err, err ); - } - - // Count how many CPUs in this node - uint cpuCount = 0; - for( uint64 j = 0; j < cpuMask->size; j++ ) - if( numa_bitmask_isbitset( cpuMask, (uint)j ) ) - cpuCount ++; - - // Allocate a buffer for this cpu - cpuIds[i].values = (uint*)malloc( sizeof( uint ) * cpuCount ); - cpuIds[i].length = cpuCount; - - // Assign CPUs - uint cpuI = 0; - for( uint64 j = 0; j < cpuMask->size; j++ ) - { - int s = numa_bitmask_isbitset( cpuMask, (uint)j ); - if( s ) - cpuIds[i].values[cpuI++] = (uint)j; - - ASSERT( cpuI <= cpuCount ); - } - - totalCpuCount += cpuCount; - - // #TODO BUG: This is a memory leak, - // but we're getting crashes releasing it or - // using it multiple times with numa_node_to_cpus on - // a signle allocations. - // Fix it. (Not fatal as it is a small allocation, and this has re-entry protection) - // numa_free_cpumask( cpuMask ); - } - - // Save instance - _info.nodeCount = nodeCount; - _info.cpuCount = totalCpuCount; - _info.cpuIds = cpuIds; - info = &_info; - } - - return info; -} - -//----------------------------------------------------------- -void SysHost::NumaAssignPages( void* ptr, size_t size, uint node ) -{ - numa_tonode_memory( ptr, size, (int)node ); -} - -//----------------------------------------------------------- -bool SysHost::NumaSetThreadInterleavedMode() -{ - const NumaInfo* numa = GetNUMAInfo(); - if( !numa ) - return false; - - const size_t MASK_SIZE = 128; - unsigned long mask[MASK_SIZE]; - memset( mask, 0xFF, sizeof( mask ) ); - - const int maxPossibleNodes = numa_num_possible_nodes(); - ASSERT( (MASK_SIZE * 64) >= (size_t)maxPossibleNodes ); - - long r = set_mempolicy( MPOL_INTERLEAVE, mask, maxPossibleNodes ); - - #if _DEBUG - if( r ) - { - int err = errno; - Log::Error( "Warning: set_mempolicy() failed with error %d (0x%x).", err, err ); - } - #endif - - return r == 0; -} - -//----------------------------------------------------------- -bool SysHost::NumaSetMemoryInterleavedMode( void* ptr, size_t size ) -{ - const NumaInfo* numa = GetNUMAInfo(); - if( !numa ) - return false; - - const size_t MASK_SIZE = 128; - unsigned long mask[MASK_SIZE]; - memset( mask, 0xFF, sizeof( mask ) ); - - const int maxPossibleNodes = numa_num_possible_nodes(); - ASSERT( (MASK_SIZE * 64) >= (size_t)maxPossibleNodes ); - - long r = mbind( ptr, size, MPOL_INTERLEAVE, mask, maxPossibleNodes, 0 ); - - #if _DEBUG - if( r ) - { - int err = errno; - Log::Error( "Warning: mbind() failed with error %d (0x%x).", err, err ); - } - #endif - - return r == 0; -} - -//----------------------------------------------------------- -int SysHost::NumaGetNodeFromPage( void* ptr ) -{ - const NumaInfo* numa = GetNUMAInfo(); - if( !numa ) - return -1; - - int node = -1; - int r = numa_move_pages( 0, 1, &ptr, nullptr, &node, 0 ); - - if( r ) - { - int err = errno; - Log::Error( "Warning: numa_move_pages() failed with error %d (0x%x).", err, err ); - } - else if( node < 0 ) - { - int err = std::abs( node ); - Log::Error( "Warning: numa_move_pages() node retrieval failed with error %d (0x%x).", err, err ); - } - - return node; -} \ No newline at end of file +#include "SysHost.h" +#include "Platform.h" +#include "util/Util.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #if _DEBUG + #include "util/Log.h" +// #endif + +std::atomic _crashed = false; + + +//----------------------------------------------------------- +size_t SysHost::GetPageSize() +{ + return (size_t)getpagesize(); +} + +//----------------------------------------------------------- +size_t SysHost::GetTotalSystemMemory() +{ + const size_t pageSize = GetPageSize(); + return (size_t)get_phys_pages() * pageSize; +} + +//----------------------------------------------------------- +size_t SysHost::GetAvailableSystemMemory() +{ + const size_t pageSize = GetPageSize(); + return (size_t)get_avphys_pages() * pageSize; +} + +//----------------------------------------------------------- + uint SysHost::GetLogicalCPUCount() + { + return (uint)get_nprocs(); + } + +//----------------------------------------------------------- +void* SysHost::VirtualAlloc( size_t size, bool initialize ) +{ + // Align size to page boundary + const size_t pageSize = GetPageSize(); + + size = RoundUpToNextBoundary( size, (int)pageSize ); + + // #TODO: Don't use a whole page size. But provide a VirtualAllocAligned for the block-aligned allocations + // Add one page to store our size (yup a whole page for it...) + size += pageSize; + + void* ptr = mmap( NULL, size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, + -1, 0 + ); + + if( ptr == MAP_FAILED ) + { + #if _DEBUG + const int err = errno; + Log::Line( "Error: mmap() returned %d (0x%x).", err, err ); + ASSERT( 0 ); + #endif + + return nullptr; + } + + if( initialize ) + { + byte* page = (byte*)ptr; + + const size_t pageCount = size / pageSize; + const byte* endPage = page + pageCount * pageSize; + + do + { + *page = 0; + page += pageSize; + } while( page < endPage ); + } + + *((size_t*)ptr) = size; + + return ((byte*)ptr)+pageSize; +} + +//----------------------------------------------------------- +void SysHost::VirtualFree( void* ptr ) +{ + ASSERT( ptr ); + if( !ptr ) + return; + + const size_t pageSize = GetPageSize(); + + byte* realPtr = ((byte*)ptr) - pageSize; + const size_t size = *((size_t*)realPtr); + + munmap( realPtr, size ); +} + +//----------------------------------------------------------- +bool SysHost::VirtualProtect( void* ptr, size_t size, VProtect flags ) +{ + ASSERT( ptr ); + + int prot = PROT_NONE; + + // if( IsFlagSet( flags, VProtect::NoAccess ) ) + // { + // prot = PROT_NONE; + // } + // else + // { + if( IsFlagSet( flags, VProtect::Read ) ) + prot |= PROT_READ; + if( IsFlagSet( flags, VProtect::Write ) ) + prot |= PROT_WRITE; + // } + + int r = mprotect( ptr, size, prot ); + ASSERT( !r ); + + return r == 0; +} + +//----------------------------------------------------------- +// uint64 SysHost::SetCurrentProcessAffinityMask( uint64 mask ) +// { +// return SetCurrentThreadAffinityMask( mask ); +// } + +// //----------------------------------------------------------- +// uint64 SysHost::SetCurrentThreadAffinityMask( uint64 mask ) +// { +// pthread_t thread = pthread_self(); + +// cpu_set_t cpuSet; +// CPU_ZERO( &cpuSet ); + +// if( mask == 0 ) +// CPU_SET( 1, &cpuSet ); +// else +// { +// for( uint i = 0; i < 64; i++ ) +// { +// if( mask & (1ull << i ) ) +// CPU_SET( i+1, &cpuSet ); +// } +// } + +// int r = pthread_setaffinity_np( thread, sizeof(cpu_set_t), &cpuSet ); +// if( r != 0 ) +// { +// ASSERT( 0 ); +// return 0; +// } + +// r = pthread_getaffinity_np( thread, sizeof(cpu_set_t), &cpuSet ); +// if( r != 0 ) +// { +// ASSERT( 0 ); +// return 0; +// } + +// return mask; +// } + +//----------------------------------------------------------- +bool SysHost::SetCurrentThreadAffinityCpuId( uint32 cpuId ) +{ + pthread_t thread = pthread_self(); + + cpu_set_t cpuSet; + CPU_ZERO( &cpuSet ); + CPU_SET( cpuId, &cpuSet ); + + int r = pthread_setaffinity_np( thread, sizeof(cpu_set_t), &cpuSet ); + return r == 0; +} + +//----------------------------------------------------------- +void CrashHandler( int signal ) +{ + // Only let the first thread handle the crash + bool crashed = false; + if( !_crashed.compare_exchange_strong( crashed, true, + std::memory_order_release, std::memory_order_relaxed ) ) + { + return; + } + + const size_t MAX_POINTERS = 256; + void* stackTrace[256] = { 0 }; + + fprintf( stderr, "*** Crashed! ***\n" ); + fflush( stderr ); + + int traceSize = backtrace( stackTrace, (int)MAX_POINTERS ); + backtrace_symbols_fd( stackTrace, traceSize, fileno( stderr ) ); + fflush( stderr ); + + FILE* crashFile = fopen( "crash.log", "w" ); + if( crashFile ) + { + fprintf( stderr, "Dumping crash to crash.log\n" ); + fflush( stderr ); + + backtrace_symbols_fd( stackTrace, traceSize, fileno( crashFile ) ); + fflush( crashFile ); + fclose( crashFile ); + } + + exit( 1 ); +} + +//----------------------------------------------------------- +void SysHost::InstallCrashHandler() +{ + signal( SIGSEGV, CrashHandler ); +} + +//----------------------------------------------------------- +void SysHost::DumpStackTrace() +{ + static std::mutex _lock; + _lock.lock(); + + const size_t MAX_POINTERS = 256; + void* stackTrace[256] = { 0 }; + + int traceSize = backtrace( stackTrace, (int)MAX_POINTERS ); + backtrace_symbols_fd( stackTrace, traceSize, fileno( stderr ) ); + fflush( stderr ); + + // FILE* crashFile = fopen( "stack.log", "w" ); + // if( crashFile ) + // { + // fprintf( stderr, "Dumping crash to crash.log\n" ); + // fflush( stderr ); + + // backtrace_symbols_fd( stackTrace, traceSize, fileno( crashFile ) ); + // fflush( crashFile ); + // fclose( crashFile ); + // } + + _lock.unlock(); +} + +//----------------------------------------------------------- +void SysHost::Random( byte* buffer, size_t size ) +{ + // See: https://man7.org/linux/man-pages/man2/getrandom.2.html + + ssize_t sizeRead; + byte* writer = buffer; + const byte* end = writer + size; + + const size_t BLOCK_SIZE = 256; + + while( writer < end ) + { + size_t readSize = (size_t)(end - writer); + if( readSize > BLOCK_SIZE ) + readSize = BLOCK_SIZE; + + sizeRead = getrandom( writer, readSize, 0 ); + + // Should never get EINTR, but docs say to check anyway. + int err = errno; + if( sizeRead < 0 && err != EINTR ) + Fatal( "getrandom syscall failed with error %d.", err ); + + writer += (size_t)sizeRead; + } +} + +// #NOTE: This is not thread-safe +//----------------------------------------------------------- +const NumaInfo* SysHost::GetNUMAInfo() +{ + if( numa_available() == -1 ) + return nullptr; + + static NumaInfo _info; + static NumaInfo* info = nullptr; + + // Initialize if not initialized + if( !info ) + { + memset( &_info, 0, sizeof( NumaInfo ) ); + + const uint nodeCount = (uint)numa_num_configured_nodes(); + + uint totalCpuCount = 0; + Span* cpuIds = (Span*)malloc( sizeof( uint* ) * nodeCount ); + + + for( uint i = 0; i < nodeCount; i++ ) + { + bitmask* cpuMask = numa_allocate_cpumask(); + if( !cpuMask ) + Fatal( "Failed to allocate NUMA CPU mask." ); + + int r = numa_node_to_cpus( i, cpuMask ); + + if( r ) + { + int err = errno; + Fatal( "Failed to get cpus from NUMA node %u with error: %d (0x%x)", i, err, err ); + } + + // Count how many CPUs in this node + uint cpuCount = 0; + for( uint64 j = 0; j < cpuMask->size; j++ ) + if( numa_bitmask_isbitset( cpuMask, (uint)j ) ) + cpuCount ++; + + // Allocate a buffer for this cpu + cpuIds[i].values = (uint*)malloc( sizeof( uint ) * cpuCount ); + cpuIds[i].length = cpuCount; + + // Assign CPUs + uint cpuI = 0; + for( uint64 j = 0; j < cpuMask->size; j++ ) + { + int s = numa_bitmask_isbitset( cpuMask, (uint)j ); + if( s ) + cpuIds[i].values[cpuI++] = (uint)j; + + ASSERT( cpuI <= cpuCount ); + } + + totalCpuCount += cpuCount; + + // #TODO BUG: This is a memory leak, + // but we're getting crashes releasing it or + // using it multiple times with numa_node_to_cpus on + // a signle allocations. + // Fix it. (Not fatal as it is a small allocation, and this has re-entry protection) + // numa_free_cpumask( cpuMask ); + } + + // Save instance + _info.nodeCount = nodeCount; + _info.cpuCount = totalCpuCount; + _info.cpuIds = cpuIds; + info = &_info; + } + + return info; +} + +//----------------------------------------------------------- +void SysHost::NumaAssignPages( void* ptr, size_t size, uint node ) +{ + numa_tonode_memory( ptr, size, (int)node ); +} + +//----------------------------------------------------------- +bool SysHost::NumaSetThreadInterleavedMode() +{ + const NumaInfo* numa = GetNUMAInfo(); + if( !numa ) + return false; + + const size_t MASK_SIZE = 128; + unsigned long mask[MASK_SIZE]; + memset( mask, 0xFF, sizeof( mask ) ); + + const int maxPossibleNodes = numa_num_possible_nodes(); + ASSERT( (MASK_SIZE * 64) >= (size_t)maxPossibleNodes ); + + long r = set_mempolicy( MPOL_INTERLEAVE, mask, maxPossibleNodes ); + + #if _DEBUG + if( r ) + { + int err = errno; + Log::Error( "Warning: set_mempolicy() failed with error %d (0x%x).", err, err ); + } + #endif + + return r == 0; +} + +//----------------------------------------------------------- +bool SysHost::NumaSetMemoryInterleavedMode( void* ptr, size_t size ) +{ + const NumaInfo* numa = GetNUMAInfo(); + if( !numa ) + return false; + + const size_t MASK_SIZE = 128; + unsigned long mask[MASK_SIZE]; + memset( mask, 0xFF, sizeof( mask ) ); + + const int maxPossibleNodes = numa_num_possible_nodes(); + ASSERT( (MASK_SIZE * 64) >= (size_t)maxPossibleNodes ); + + long r = mbind( ptr, size, MPOL_INTERLEAVE, mask, maxPossibleNodes, 0 ); + + #if _DEBUG + if( r ) + { + int err = errno; + Log::Error( "Warning: mbind() failed with error %d (0x%x).", err, err ); + } + #endif + + return r == 0; +} + +//----------------------------------------------------------- +int SysHost::NumaGetNodeFromPage( void* ptr ) +{ + const NumaInfo* numa = GetNUMAInfo(); + if( !numa ) + return -1; + + int node = -1; + int r = numa_move_pages( 0, 1, &ptr, nullptr, &node, 0 ); + + if( r ) + { + int err = errno; + Log::Error( "Warning: numa_move_pages() failed with error %d (0x%x).", err, err ); + } + else if( node < 0 ) + { + int err = std::abs( node ); + Log::Error( "Warning: numa_move_pages() node retrieval failed with error %d (0x%x).", err, err ); + } + + return node; +} diff --git a/src/platform/macos/SysHost_Macos.cpp b/src/platform/macos/SysHost_Macos.cpp index 52991e84..192d3de2 100644 --- a/src/platform/macos/SysHost_Macos.cpp +++ b/src/platform/macos/SysHost_Macos.cpp @@ -1,128 +1,271 @@ -#include "SysHost.h" -#include "Platform.h" -#include "Util.h" - -#if _DEBUG - #include "util/Log.h" -#endif - -//----------------------------------------------------------- -size_t SysHost::GetPageSize() -{ - // #TODO: Use host_page_size - return (size_t)getpagesize(); -} - -//----------------------------------------------------------- -size_t SysHost::GetTotalSystemMemory() -{ - uint count = HOST_VM_INFO64_COUNT; - vm_statistics64_t vmstat; - ZeroMem( &vmstat ); - - if( host_statistics64( mach_host_self(), HOST_VM_INFO, (host_info64_t)&vmstat, &count ) != KERN_SUCCESS ) - return 0; - - const size_t pageSize = GetPageSize(); - - return ( vmstat->free_count + - vmstat->active_count + - vmstat->inactive_count + - vmstat->wire_count ) * pageSize; -} - -//----------------------------------------------------------- -size_t SysHost::GetAvailableSystemMemory() -{ - uint count = HOST_VM_INFO64_COUNT; - vm_statistics64_t vmstat; - ZeroMem( &vmstat ); - - if( host_statistics64( mach_host_self(), HOST_VM_INFO, (host_info64_t)&vmstat, &count ) != KERN_SUCCESS ) - return 0; - - const size_t pageSize = GetPageSize(); - - return ( vmstat->free_count + - vmstat->inactive_count ) * pageSize; -} - -//----------------------------------------------------------- -void* SysHost::VirtualAlloc( size_t size, bool initialize ) -{ - // #TODO: Use vm_allocate - // #TODO: Consider initialize - - const size_t pageSize = (size_t)getpagesize(); - - // Align size to page boundary - size = RoundUpToNextBoundary( size, (int)pageSize ); - - void* ptr = mmap( NULL, size, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, - -1, 0 - ); - - if( ptr == MAP_FAILED ) - { - #if _DEBUG - const int err = errno; - Log::Line( "Error: mmap() returned %d (0x%x).", err, err ); - ASSERT( 0 ); - #endif - - return nullptr; - } - else if( initialize ) - { - // Initialize memory - // (since physical pages are not allocated until the actual pages are accessed) - - byte* page = (byte*)ptr; - - const size_t pageCount = size / pageSize; - const byte* endPage = page + pageCount * pageSize; - - do - { - *page = 0; - page += pageSize; - } while( page < endPage ); - } - - return ptr; -} - -//----------------------------------------------------------- -void SysHost::VirtualFree( void* ptr ) -{ - // #TODO: Implement -} - -//----------------------------------------------------------- -uint64 SysHost::SetCurrentProcessAffinityMask( uint64 mask ) -{ - return SetCurrentThreadAffinityMask( mask ); -} - -// #TODO: This should perhaps return bool. -//----------------------------------------------------------- -uint64 SysHost::SetCurrentThreadAffinityMask( uint64 mask ) -{ - thread_port_t thread = mach_thread_self(); - - // It seems macOS does not support 64 bit affinity masks. - // This may be since they have never had a processor with more than 32 cores. - thread_affinity_policy_data_t policy = { (integer_t)mask }; - - kern_return_t r = thread_policy_set( thread, THREAD_AFFINITY_POLICY, - (thread_policy_t)&policy, - THREAD_AFFINITY_POLICY_COUNT ); - - - if( r == KERN_SUCCESS ) - return (uint64)(integer_t)mask; - - return 0; -} \ No newline at end of file +#include "SysHost.h" +#include "Platform.h" +#include "util/Util.h" +#include "util/Log.h" +#include +#include +#include +#include +#include + +//----------------------------------------------------------- +size_t SysHost::GetPageSize() +{ + vm_size_t pageSize = 0; + kern_return_t r = host_page_size( mach_host_self(), & pageSize ); + PanicIf( r != 0, "host_page_size failed with error: %d.", (int32)r ); + + return (size_t)pageSize; +} + +//----------------------------------------------------------- +size_t SysHost::GetTotalSystemMemory() +{ + uint count = HOST_VM_INFO64_COUNT; + vm_statistics64_data_t vmstat; + ZeroMem( &vmstat ); + + if( host_statistics64( mach_host_self(), HOST_VM_INFO64, (host_info64_t)&vmstat, &count ) != KERN_SUCCESS ) + return 0; + + const size_t pageSize = GetPageSize(); + + return ( vmstat.free_count + + vmstat.active_count + + vmstat.inactive_count + + vmstat.wire_count ) * pageSize; +} + +//----------------------------------------------------------- +size_t SysHost::GetAvailableSystemMemory() +{ + uint count = HOST_VM_INFO64_COUNT; + vm_statistics64_data_t vmstat; + ZeroMem( &vmstat ); + + if( host_statistics64( mach_host_self(), HOST_VM_INFO, (host_info64_t)&vmstat, &count ) != KERN_SUCCESS ) + return 0; + + const size_t pageSize = GetPageSize(); + + return ( vmstat.free_count + + vmstat.inactive_count ) * pageSize; +} + +//----------------------------------------------------------- +uint SysHost::GetLogicalCPUCount() +{ + host_basic_info info; + ZeroMem( &info ); + + mach_msg_type_number_t host_info_count = (mach_msg_type_number_t)sizeof( info ); + host_info( mach_host_self(), HOST_BASIC_INFO, (host_info_t)&info, &host_info_count ); + + return (uint)info.avail_cpus; +} + +//----------------------------------------------------------- +void* SysHost::VirtualAlloc( size_t size, bool initialize ) +{ + // #TODO: Remove initialize + + const size_t pageSize = GetPageSize(); + const mach_port_t task = mach_task_self(); + + const vm_size_t allocSize = (vm_size_t)RoundUpToNextBoundary( size, (int)pageSize ) + pageSize; + vm_address_t ptr = 0; + kern_return_t r = vm_allocate( task,&ptr,allocSize, TRUE ); + + if( r != 0 ) + { + Log::Line( "Warning: vm_allocate() failed with error: %d .", (int32)r ); + return nullptr; + } + ASSERT( ptr ); + + // #TODO: Use a hinting system for this. + // Hit the memory to be accessed sequentially + r = vm_behavior_set( task, ptr, allocSize, VM_BEHAVIOR_SEQUENTIAL ); + if( r != 0 ) + { + Log::Line( "Warning: vm_behavior_set() failed with error: %d .", (int32)r ); + } + + // Try wiring it + r = vm_wire( mach_host_self(), task, ptr, allocSize, VM_PROT_READ | VM_PROT_WRITE ); + if( r != 0 ) + { + Log::Line( "Warning: vm_wire() failed with error: %d .", (int32)r ); + } + + // Store page size + // #TODO: Have the user specify an alignment instead so we don't have to store at page size boundaries. + (*(size_t*)ptr) = allocSize; + + return (void*)(uintptr_t)(ptr + pageSize); +// const size_t pageSize = (size_t)getpagesize(); +// +// // Align size to page boundary +// size = RoundUpToNextBoundary( size, (int)pageSize ); +// +// void* ptr = mmap( NULL, size, +// PROT_READ | PROT_WRITE, +// MAP_ANONYMOUS | MAP_PRIVATE, +// -1, 0 +// ); +// +// if( ptr == MAP_FAILED ) +// { +// #if _DEBUG +// const int err = errno; +// Log::Line( "Error: mmap() returned %d (0x%x).", err, err ); +// ASSERT( 0 ); +// #endif +// +// return nullptr; +// } +// else if( initialize ) +// { +// // Initialize memory +// // (since physical pages are not allocated until the actual pages are accessed) +// +// byte* page = (byte*)ptr; +// +// const size_t pageCount = size / pageSize; +// const byte* endPage = page + pageCount * pageSize; +// +// do +// { +// *page = 0; +// page += pageSize; +// } while( page < endPage ); +// } +// +// return ptr; +} + +//----------------------------------------------------------- +void SysHost::VirtualFree( void* ptr ) +{ + ASSERT( ptr ); + if( !ptr ) + return; + + // #TODO: Have user specify size instead, so we can store the size not at page alignment. + const size_t pageSize = GetPageSize(); + + byte* realPtr = ((byte*)ptr) - pageSize; + const size_t size = *((size_t*)realPtr); + +// munmap( realPtr, size ); + kern_return_t r = vm_deallocate( mach_task_self(), (vm_address_t)realPtr, (vm_size_t)size ); + if( r != 0 ) + Log::Line("Warning: vm_deallocate() failed with error %d.", (int32)r ); +} + +//----------------------------------------------------------- +bool SysHost::VirtualProtect( void* ptr, size_t size, VProtect flags ) +{ + ASSERT( ptr ); + ASSERT( size ); + + vm_prot_t prot = VM_PROT_NONE; + + // if( IsFlagSet( flags, VProtect::NoAccess ) ) + // { + // prot = PROT_NONE; + // } + // else + // { + if( IsFlagSet( flags, VProtect::Read ) ) + prot |= VM_PROT_READ; + if( IsFlagSet( flags, VProtect::Write ) ) + prot |= VM_PROT_WRITE; + // } + + const kern_return_t r = vm_protect( mach_task_self(), (vm_address_t)ptr, (vm_size_t)size, false, prot ); + ASSERT( !r ); + + return r == 0; +} + +//----------------------------------------------------------- +bool SysHost::SetCurrentThreadAffinityCpuId( uint32 cpuId ) +{ + // #NOTE: Thread affinity it not supported on macOS. + // These will always return "not implemented". +// ASSERT( cpuId < 32 ); +// +// thread_port_t thread = mach_thread_self(); +// +// // It seems macOS does not support 64 bit affinity masks +// thread_affinity_policy_data_t policy = { (integer_t)(1 << cpuId) }; +// +// kern_return_t r = thread_policy_set( thread, THREAD_AFFINITY_POLICY, +// (thread_policy_t)&policy, +// THREAD_AFFINITY_POLICY_COUNT ); +// +// if( r != KERN_SUCCESS ) +// { +// Log::Error( "thread_policy_set failed on cpu id %lld with error: %d.", cpuId, (int64)r ); +// return false; +// } + + return true; +} + +//----------------------------------------------------------- +void SysHost::InstallCrashHandler() +{ + // #TODO: Implement me +} + +//----------------------------------------------------------- +void SysHost::DumpStackTrace() +{ + // #TODO: Implement me +} + +//----------------------------------------------------------- +void SysHost::Random( byte* buffer, size_t size ) +{ + randombytes_buf( buffer, size ); +} + + +/// +/// NUMA (no support on macOS) +/// +//----------------------------------------------------------- +const NumaInfo* SysHost::GetNUMAInfo() +{ + // Not supported + return nullptr; +} + +//----------------------------------------------------------- +void SysHost::NumaAssignPages( void* ptr, size_t size, uint node ) +{ + // Not supported +} + +//----------------------------------------------------------- +bool SysHost::NumaSetThreadInterleavedMode() +{ + // Not supported + return false; +} + +//----------------------------------------------------------- +bool SysHost::NumaSetMemoryInterleavedMode( void* ptr, size_t size ) +{ + // Not supported + return false; +} + +//----------------------------------------------------------- +int SysHost::NumaGetNodeFromPage( void* ptr ) +{ + // Not supported + return 0; +} diff --git a/src/platform/unix/FileStream_Unix.cpp b/src/platform/unix/FileStream_Unix.cpp index 8a24c407..2e0bf9d2 100644 --- a/src/platform/unix/FileStream_Unix.cpp +++ b/src/platform/unix/FileStream_Unix.cpp @@ -1,251 +1,313 @@ -#include "io/FileStream.h" -#include "Util.h" -#include "util/Log.h" - -#include -#include -#include - -//---------------------------------------------------------- -bool FileStream::Open( const char* path, FileMode mode, FileAccess access, FileFlags flags ) -{ - return Open( path, *this, mode, access, flags ); -} - -//---------------------------------------------------------- -bool FileStream::Open( const char* path, FileStream& file, FileMode mode, FileAccess access, FileFlags flags ) -{ - if( path == nullptr ) - return false; - - if( file._fd >= 0 ) - return false; - - if( access == FileAccess::None ) - access = FileAccess::Read; - - mode_t fmode = 0; - - int fdFlags = access == FileAccess::Read ? O_RDONLY : - access == FileAccess::Write ? O_WRONLY : O_RDWR; - - fdFlags |= mode == FileMode::Create ? O_CREAT : - mode == FileMode::Append ? O_APPEND : 0; - - #if PLATFORM_IS_LINUX - if( IsFlagSet( flags, FileFlags::NoBuffering ) ) - fdFlags |= O_DIRECT | O_SYNC; - - if( IsFlagSet( flags, FileFlags::LargeFile ) ) - fdFlags |= O_LARGEFILE; - #endif - - if( mode == FileMode::Create ) - fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - - int fd = open( path, fdFlags, fmode ); - if( fd < 0 ) - return false; - - #if PLATFORM_IS_MACOS - if( IsFlagSet( flags, FileFlags::NoBuffering ) ) - { - int r = fcntl( fd, F_NOCACHE, 1 ); - if( r == -1 ) - { - file._error = errno; - close( fd ); - return false; - } - } - #endif - - // Get the block size (useful when using O_DIRECT) - int blockSize = 0; - { - struct stat fs; - int r = fstat( fd, &fs ); - - if( r == 0 ) - { - blockSize = (size_t)fs.st_blksize; - } - else - { - file._error = errno; - close( fd ); - - return false; - } - - ASSERT( blockSize > 0 ); - } - - file._fd = fd; - file._blockSize = (size_t)blockSize; - file._writePosition = 0; - file._readPosition = 0; - file._access = access; - file._flags = flags; - file._error = 0; - - return true; -} - -//----------------------------------------------------------- -void FileStream::Close() -{ - if( _fd <= 0 ) - return; - - #if _DEBUG - int r = - #endif - close( _fd ); - - ASSERT( !r ); - - _fd = -1; - _writePosition = 0; - _readPosition = 0; - _access = FileAccess::None; - _error = 0; - _blockSize = 0; -} - -//----------------------------------------------------------- -ssize_t FileStream::Read( void* buffer, size_t size ) -{ - ASSERT( buffer ); - - if( buffer == nullptr ) - return -1; - - if( ! IsFlagSet( _access, FileAccess::Read ) ) - return -1; - - if( _fd < 0 ) - return -1; - - if( size < 1 ) - return 0; - - const ssize_t sizeRead = read( _fd, buffer, size ); - if( sizeRead >= 0 ) - _readPosition += (size_t)sizeRead; - else - _error = errno; - - return sizeRead; -} - -//----------------------------------------------------------- -ssize_t FileStream::Write( const void* buffer, size_t size ) -{ - ASSERT( buffer ); - ASSERT( size ); - ASSERT( _fd ); - - if( buffer == nullptr ) - return -1; - - if( ! IsFlagSet( _access, FileAccess::Write ) ) - return -1; - - if( _fd < 0 ) - return -1; - - if( size < 1 ) - return 0; - - // Note that this can return less than size if size > SSIZE_MAX - ssize_t written = write( _fd, buffer, size ); - - if( written >= 0 ) - _writePosition += (size_t)written; - else - _error = errno; - - return written; -} - -//---------------------------------------------------------- -bool FileStream::Reserve( ssize_t size ) -{ - #if PLATFORM_IS_LINUX - int r = posix_fallocate( _fd, 0, (off_t)size ); - if( r != 0 ) - { - _error = errno; - return false; - } - #else - - // #TODO: Use F_PREALLOCATE on macOS - // #SEE: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html - return false; - #endif - return true; -} - -//---------------------------------------------------------- -bool FileStream::Seek( int64 offset, SeekOrigin origin ) -{ - if( !IsOpen() ) - return false; - - int whence; - switch( origin ) - { - case SeekOrigin::Begin : whence = SEEK_SET; break; - case SeekOrigin::Current: whence = SEEK_CUR; break; - case SeekOrigin::End : whence = SEEK_END; break; - default: return false; - } - - off_t r = lseek( _fd, (off_t)offset, whence ); - if( r == -1 ) - { - _error = errno; - return false; - } - - return true; -} - -//----------------------------------------------------------- -bool FileStream::Flush() -{ - if( !IsOpen() ) - return false; - - int r = fsync( _fd ); - - if( r ) - { - _error = errno; - return false; - } - - return true; -} - -//----------------------------------------------------------- -bool FileStream::IsOpen() const -{ - return _fd >= 0; -} - -//----------------------------------------------------------- -bool FileStream::Exists( const char* path ) -{ - struct stat fileStat; - if( lstat( path, &fileStat ) == 0 ) - { - // #TODO: Check if it is a folder... - - return true; - } - - return false; -} +#include "io/FileStream.h" +#include "util/Util.h" +#include "util/Log.h" + +#include +#include +#include + +//---------------------------------------------------------- +bool FileStream::Open( const char* path, FileMode mode, FileAccess access, FileFlags flags ) +{ + return Open( path, *this, mode, access, flags ); +} + +//---------------------------------------------------------- +bool FileStream::Open( const char* path, FileStream& file, FileMode mode, FileAccess access, FileFlags flags ) +{ + if( path == nullptr ) + return false; + + if( file._fd >= 0 ) + return false; + + if( access == FileAccess::None ) + access = FileAccess::Read; + + mode_t fmode = 0; + + int fdFlags = access == FileAccess::Read ? O_RDONLY : + access == FileAccess::Write ? O_WRONLY : O_RDWR; + + fdFlags |= mode == FileMode::Create ? O_CREAT | O_TRUNC : + mode == FileMode::OpenOrCreate ? O_CREAT : 0; + + #if PLATFORM_IS_LINUX + if( IsFlagSet( flags, FileFlags::NoBuffering ) ) + fdFlags |= O_DIRECT | O_SYNC; + + if( IsFlagSet( flags, FileFlags::LargeFile ) ) + fdFlags |= O_LARGEFILE; + #endif + + if( mode == FileMode::Create ) + fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + + int fd = open( path, fdFlags, fmode ); + if( fd < 0 ) + { + file._error = errno; + return false; + } + + #if PLATFORM_IS_MACOS + if( IsFlagSet( flags, FileFlags::NoBuffering ) ) + { + int r = fcntl( fd, F_NOCACHE, 1 ); + if( r == -1 ) + { + file._error = errno; + close( fd ); + return false; + } + } + #endif + + // Get the block size (useful when using O_DIRECT) + int blockSize = 0; + { + struct stat fs; + int r = fstat( fd, &fs ); + + if( r == 0 ) + { + blockSize = (size_t)fs.st_blksize; + } + else + { + file._error = errno; + close( fd ); + + return false; + } + + ASSERT( blockSize > 0 ); + } + + file._fd = fd; + file._blockSize = (size_t)blockSize; + file._position = 0; + file._access = access; + file._flags = flags; + file._error = 0; + + return true; +} + +//----------------------------------------------------------- +void FileStream::Close() +{ + if( _fd <= 0 ) + return; + + #if _DEBUG + int r = + #endif + close( _fd ); + + #if _DEBUG + ASSERT( !r ); + #endif + + _fd = -1; + _position = 0; + _access = FileAccess::None; + _error = 0; + _blockSize = 0; +} + +//----------------------------------------------------------- +ssize_t FileStream::Size() +{ + // #TODO: Cache size and only invalidate on write or seek + struct stat fs; + int r = fstat( _fd, &fs ); + + if( r == 0 ) + return (ssize_t)fs.st_size; + + _error = errno; + return -1; +} + +//----------------------------------------------------------- +bool FileStream::Truncate( const ssize_t length ) +{ + ASSERT( length >= 0 ); + static_assert( sizeof( off_t ) == sizeof( length ) ); + + const int r = ftruncate( _fd, (off_t)length ); + + if( r != 0 ) + { + _error = errno; + return false; + } + + if( _position > (size_t)length ) + _position = (size_t)length; + + return true; +} + +//----------------------------------------------------------- +ssize_t FileStream::Read( void* buffer, size_t size ) +{ + ASSERT( buffer ); + + if( buffer == nullptr ) + { + _error = -1; + return -1; + } + + if( ! IsFlagSet( _access, FileAccess::Read ) ) + { + _error = -1; + return -1; + } + + if( _fd < 0 ) + { + _error = -1; + return -1; + } + + if( size < 1 ) + return 0; + + const ssize_t sizeRead = read( _fd, buffer, size ); + if( sizeRead > 0 ) + _position += (size_t)sizeRead; + else + _error = errno; + + return sizeRead; +} + +//----------------------------------------------------------- +ssize_t FileStream::Write( const void* buffer, size_t size ) +{ + ASSERT( buffer ); + ASSERT( size ); + ASSERT( _fd ); + + if( buffer == nullptr ) + { + _error = -1; + return -1; + } + + if( ! IsFlagSet( _access, FileAccess::Write ) ) + { + _error = -1; + return -1; + } + + if( _fd < 0 ) + { + _error = -1; + return -1; + } + + if( size < 1 ) + return 0; + + // Note that this can return less than size if size > SSIZE_MAX + // On macOS, this seems to fail with EINVAL if we write anything above 2GiB. + // Although Apple's docs does not list this as an error condition for write(), + // it seems we can infer that the maximum value is signed 32-bit max, + // form the notes given on writev() here: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/write.2.html + // On Linux, the maximum is 0x7ffff000 anyway, so let's just cap to that: https://man7.org/linux/man-pages/man2/write.2.html + size = std::min( size, (size_t)0x7ffff000 ); + ssize_t written = write( _fd, buffer, size ); + + if( written >= 0 ) + _position += (size_t)written; + else + _error = errno; + + return written; +} + +//---------------------------------------------------------- +bool FileStream::Reserve( ssize_t size ) +{ + #if PLATFORM_IS_LINUX + int r = posix_fallocate( _fd, 0, (off_t)size ); + if( r != 0 ) + { + _error = errno; + return false; + } + #else + + // #TODO: Use F_PREALLOCATE on macOS + // #SEE: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html + return false; + #endif + return true; +} + +//---------------------------------------------------------- +bool FileStream::Seek( int64 offset, SeekOrigin origin ) +{ + if( !IsOpen() ) + return false; + + int whence; + switch( origin ) + { + case SeekOrigin::Begin : whence = SEEK_SET; break; + case SeekOrigin::Current: whence = SEEK_CUR; break; + case SeekOrigin::End : whence = SEEK_END; break; + default: return false; + } + + off_t r = lseek( _fd, (off_t)offset, whence ); + if( r == -1 ) + { + _error = errno; + return false; + } + + _position = (size_t)r; + return true; +} + +//----------------------------------------------------------- +bool FileStream::Flush() +{ + if( !IsOpen() ) + return false; + + int r = fsync( _fd ); + + if( r ) + { + _error = errno; + return false; + } + + return true; +} + +//----------------------------------------------------------- +bool FileStream::IsOpen() const +{ + return _fd >= 0; +} + +//----------------------------------------------------------- +bool FileStream::Exists( const char* path ) +{ + struct stat fileStat; + if( lstat( path, &fileStat ) == 0 ) + { + // #TODO: Check if it is a folder... + + return true; + } + + return false; +} diff --git a/src/platform/unix/Thread_Unix.cpp b/src/platform/unix/Thread_Unix.cpp index 6c7b6f04..25ddfaa1 100644 --- a/src/platform/unix/Thread_Unix.cpp +++ b/src/platform/unix/Thread_Unix.cpp @@ -1,232 +1,260 @@ -#include "../../threading/Thread.h" -#include "../../Util.h" -#include "../../Globals.h" -#include "SysHost.h" -#include "util/Log.h" - -typedef void* (*PthreadFunc)( void* param ); - -//----------------------------------------------------------- -Thread::Thread( size_t stackSize ) -{ - // Configure stack size - if( stackSize < 1024 * 4 ) - Fatal( "Thread stack size is too small." ); - - // Align to 8 bytes - stackSize = RoundUpToNextBoundary( stackSize, 8 ); - - _state.store( ThreadState::ReadyToRun, std::memory_order_release ); - -#if PLATFORM_IS_UNIX - - pthread_attr_t attr; - - int r = pthread_attr_init( &attr ); - if( r ) Fatal( "pthread_attr_init() failed." ); - - r = pthread_attr_setstacksize( &attr, stackSize ); - if( r ) Fatal( "pthread_attr_setstacksize() failed." ); - - // Initialize suspended mode signal - r = pthread_cond_init( &_launchCond, NULL ); - if( r ) Fatal( "pthread_cond_init() failed." ); - - r = pthread_mutex_init( &_launchMutex, NULL ); - if( r ) Fatal( "pthread_mutex_init() failed." ); - - r = pthread_create( &_threadId, &attr, (PthreadFunc)&Thread::ThreadStarterUnix, this ); - if( r ) Fatal( "pthread_create() failed." ); - - r = pthread_attr_destroy( &attr ); - if( r ) Fatal( "pthread_attr_destroy() failed." ); - -#elif PLATFORM_IS_WINDOWS - - -#else - #error Not implemented -#endif -} - -//----------------------------------------------------------- -Thread::Thread() : Thread( 8 MB ) -{ -} - -//----------------------------------------------------------- -Thread::~Thread() -{ - const bool didExit = _state.load( std::memory_order_relaxed ) == ThreadState::Exited; - - if( !didExit ) - { - // Thread should have exited already - #if PLATFORM_IS_UNIX - pthread_cancel( _threadId ); - - pthread_mutex_destroy( &_launchMutex ); - pthread_cond_destroy ( &_launchCond ); - - ZeroMem( &_launchMutex ); - ZeroMem( &_launchCond ); - #else - #error Unimplemented - #endif - } - - _threadId = 0; -} - -//----------------------------------------------------------- -// uint64 Thread::SetAffinity( uint64 affinity ) -// { -// return SysHost::SetCurrentThreadAffinityMask( affinity ); -// } - -//----------------------------------------------------------- -bool Thread::HasExited() const -{ - return _state.load( std::memory_order_relaxed ) == ThreadState::Exited; -} - -//----------------------------------------------------------- -void Thread::Run( ThreadRunner runner, void* param ) -{ - ASSERT( runner ); - const bool canRun = _state.load( std::memory_order_relaxed ) == ThreadState::ReadyToRun; - - ASSERT( canRun ); - if( !canRun ) - return; - - ThreadState expected = ThreadState::ReadyToRun; - if( !_state.compare_exchange_strong( expected, ThreadState::Running, - std::memory_order_release, - std::memory_order_relaxed ) ) - { - // Another thread ran us first. - return; - } - - _runner = runner; - _runParam = param; - - #if PLATFORM_IS_UNIX - // Signal thread to resume - int r = pthread_mutex_lock( &_launchMutex ); - if( r ) Fatal( "pthread_mutex_lock() failed." ); - - r = pthread_cond_signal( &_launchCond ); - if( r ) Fatal( "pthread_cond_signal() failed." ); - - r = pthread_mutex_unlock( &_launchMutex ); - if( r ) Fatal( "pthread_mutex_unlock() failed." ); - #endif -} - - -//----------------------------------------------------------- -void Thread::Sleep( long milliseconds ) -{ - #if PLATFORM_IS_UNIX - - long seconds = milliseconds / 1000; - milliseconds -= seconds * 1000; - - struct timespec req; - req.tv_sec = seconds; - req.tv_nsec = milliseconds * 1000000; - - #if _DEBUG - int r = - #endif - nanosleep( &req, NULL ); - ASSERT( !r ); - #else - #error Unimplemented - #endif -} - -//----------------------------------------------------------- -bool Thread::WaitForExit( long milliseconds ) -{ - ThreadState state = _state.load( std::memory_order_relaxed ); - if( state == ThreadState::Exited ) - return true; - - #if PLATFORM_IS_UNIX - - int r; - - if( milliseconds > 0 ) - { - // #TODO: Support on apple with a condition variable and mutex pair - #if __APPLE__ - return false; - #else - long seconds = milliseconds / 1000; - milliseconds -= seconds * 1000; - - struct timespec abstime; - - if( clock_gettime( CLOCK_REALTIME, &abstime ) == -1 ) - { - ASSERT( 0 ); - return false; - } - - abstime.tv_sec += seconds; - abstime.tv_nsec += milliseconds * 1000000; - - r = pthread_timedjoin_np( _threadId, NULL, &abstime ); - ASSERT( !r || r == ETIMEDOUT ); - #endif - } - else - { - r = pthread_join( _threadId, NULL ); - } - - return r == 0; - #else - #error Unimplemented - #endif -} - -// Starts up a thread. -//----------------------------------------------------------- -void* Thread::ThreadStarterUnix( Thread* t ) -{ - // On Linux, it suspends it until it is signaled to run. - int r = pthread_mutex_lock( &t->_launchMutex ); - if( r ) Fatal( "pthread_mutex_lock() failed." ); - - while( t->_state.load( std::memory_order_relaxed ) == ThreadState::ReadyToRun ) - { - r = pthread_cond_wait( &t->_launchCond, &t->_launchMutex ); - if( r ) Fatal( "pthread_cond_wait() failed." ); - break; - } - - r = pthread_mutex_unlock( &t->_launchMutex ); - if( r ) Fatal( "pthread_mutex_unlock() failed." ); - - pthread_mutex_destroy( &t->_launchMutex ); - pthread_cond_destroy ( &t->_launchCond ); - - ZeroMem( &t->_launchMutex ); - ZeroMem( &t->_launchCond ); - - // Run the thread function - t->_runner( t->_runParam ); - - // Thread has exited - t->_state.store( ThreadState::Exited, std::memory_order_release ); - - // TODO: Signal if waiting to be joined - pthread_exit( nullptr ); - - return nullptr; -} - +#include "threading/Thread.h" +#include "util/Util.h" +#include "Globals.h" +#include "SysHost.h" +#include "util/Log.h" + +typedef void* (*PthreadFunc)( void* param ); + +//----------------------------------------------------------- +Thread::Thread( size_t stackSize ) +{ + // Configure stack size + if( stackSize < 1024 * 4 ) + Fatal( "Thread stack size is too small." ); + + // Align to 8 bytes + stackSize = RoundUpToNextBoundary( stackSize, 8 ); + + _state.store( ThreadState::ReadyToRun, std::memory_order_release ); + +#if PLATFORM_IS_UNIX + + pthread_attr_t attr; + + int r = pthread_attr_init( &attr ); + if( r ) Fatal( "pthread_attr_init() failed." ); + + r = pthread_attr_setstacksize( &attr, stackSize ); + if( r ) Fatal( "pthread_attr_setstacksize() failed." ); + + // Initialize suspended mode signal + r = pthread_cond_init( &_launchCond, NULL ); + if( r ) Fatal( "pthread_cond_init() failed." ); + + r = pthread_mutex_init( &_launchMutex, NULL ); + if( r ) Fatal( "pthread_mutex_init() failed." ); + + r = pthread_create( &_threadId, &attr, (PthreadFunc)&Thread::ThreadStarterUnix, this ); + if( r ) Fatal( "pthread_create() failed." ); + + r = pthread_attr_destroy( &attr ); + if( r ) Fatal( "pthread_attr_destroy() failed." ); + +#elif PLATFORM_IS_WINDOWS + + +#else + #error Not implemented +#endif +} + +//----------------------------------------------------------- +Thread::Thread() : Thread( 8 MB ) +{ +} + +//----------------------------------------------------------- +Thread::~Thread() +{ + const bool didExit = _state.load( std::memory_order_relaxed ) == ThreadState::Exited; + + if( !didExit ) + { + // Thread should have exited already + #if PLATFORM_IS_UNIX + pthread_cancel( _threadId ); + + pthread_mutex_destroy( &_launchMutex ); + pthread_cond_destroy ( &_launchCond ); + + ZeroMem( &_launchMutex ); + ZeroMem( &_launchCond ); + #else + #error Unimplemented + #endif + } + + _threadId = 0; +} + +//----------------------------------------------------------- +// uint64 Thread::SetAffinity( uint64 affinity ) +// { +// return SysHost::SetCurrentThreadAffinityMask( affinity ); +// } + +//----------------------------------------------------------- +bool Thread::HasExited() const +{ + return _state.load( std::memory_order_relaxed ) == ThreadState::Exited; +} + +//----------------------------------------------------------- +void Thread::Run( ThreadRunner runner, void* param ) +{ + ASSERT( runner ); + const bool canRun = _state.load( std::memory_order_relaxed ) == ThreadState::ReadyToRun; + + ASSERT( canRun ); + if( !canRun ) + return; + + ThreadState expected = ThreadState::ReadyToRun; + if( !_state.compare_exchange_strong( expected, ThreadState::Running, + std::memory_order_release, + std::memory_order_relaxed ) ) + { + // Another thread ran us first. + return; + } + + _runner = runner; + _runParam = param; + + #if PLATFORM_IS_UNIX + // Signal thread to resume + int r = pthread_mutex_lock( &_launchMutex ); + if( r ) Fatal( "pthread_mutex_lock() failed." ); + + r = pthread_cond_signal( &_launchCond ); + if( r ) Fatal( "pthread_cond_signal() failed." ); + + r = pthread_mutex_unlock( &_launchMutex ); + if( r ) Fatal( "pthread_mutex_unlock() failed." ); + #endif +} + + +//----------------------------------------------------------- +void Thread::Sleep( long milliseconds ) +{ + #if PLATFORM_IS_UNIX + + long seconds = milliseconds / 1000; + milliseconds -= seconds * 1000; + + struct timespec req; + req.tv_sec = seconds; + req.tv_nsec = milliseconds * 1000000; + + #if _DEBUG + int r = + #endif + + nanosleep( &req, NULL ); + + #if _DEBUG + ASSERT( !r ); + #endif + + #else + #error Unimplemented + #endif +} + +//----------------------------------------------------------- +bool Thread::WaitForExit( long milliseconds ) +{ + ThreadState state = _state.load( std::memory_order_relaxed ); + if( state == ThreadState::Exited ) + return true; + + #if PLATFORM_IS_UNIX + + int r; + + if( milliseconds > 0 ) + { + // #TODO: Support on apple with a condition variable and mutex pair + #if __APPLE__ + return false; + #else + long seconds = milliseconds / 1000; + milliseconds -= seconds * 1000; + + struct timespec abstime; + + if( clock_gettime( CLOCK_REALTIME, &abstime ) == -1 ) + { + ASSERT( 0 ); + return false; + } + + abstime.tv_sec += seconds; + abstime.tv_nsec += milliseconds * 1000000; + + r = pthread_timedjoin_np( _threadId, NULL, &abstime ); + ASSERT( !r || r == ETIMEDOUT ); + #endif + } + else + { + r = pthread_join( _threadId, NULL ); + } + + return r == 0; + #else + #error Unimplemented + #endif +} + +// Starts up a thread. +//----------------------------------------------------------- +void* Thread::ThreadStarterUnix( Thread* t ) +{ + // On Linux, it suspends it until it is signaled to run. + int r = pthread_mutex_lock( &t->_launchMutex ); + if( r ) Fatal( "pthread_mutex_lock() failed." ); + + while( t->_state.load( std::memory_order_relaxed ) == ThreadState::ReadyToRun ) + { + r = pthread_cond_wait( &t->_launchCond, &t->_launchMutex ); + if( r ) Fatal( "pthread_cond_wait() failed." ); + break; + } + + r = pthread_mutex_unlock( &t->_launchMutex ); + if( r ) Fatal( "pthread_mutex_unlock() failed." ); + + pthread_mutex_destroy( &t->_launchMutex ); + pthread_cond_destroy ( &t->_launchCond ); + + ZeroMem( &t->_launchMutex ); + ZeroMem( &t->_launchCond ); + + // Run the thread function + t->_runner( t->_runParam ); + + // Thread has exited + t->_state.store( ThreadState::Exited, std::memory_order_release ); + + // TODO: Signal if waiting to be joined + pthread_exit( nullptr ); + + return nullptr; +} + +//----------------------------------------------------------- +bool Thread::SetPriority( const ThreadPriority priority ) +{ + // #TODO: Implement + // struct sched_param sched; + + switch( priority ) + { + // case ThreadPriority::Normal: + + // break; + + // case ThreadPriority::High: + + // break; + + + default: + ASSERT( 0 ); + return false; + } +} + diff --git a/src/platform/win32/FileStream_Win32.cpp b/src/platform/win32/FileStream_Win32.cpp index 3f86b243..402bb60d 100644 --- a/src/platform/win32/FileStream_Win32.cpp +++ b/src/platform/win32/FileStream_Win32.cpp @@ -1,416 +1,450 @@ -#include "io/FileStream.h" -#include "Util.h" -#include "util/Log.h" - -#include -#include -#pragma comment( lib, "Shlwapi.lib" ) - -const size_t BUF16_STACK_LEN = 1024; - -//bool GetFileClusterSize( wchar_t* filePath, size_t& outClusterSize ); -bool GetFileClusterSize( HANDLE hFile, size_t& outClusterSize ); - -wchar_t* Utf8ToUtf16( const char* utf8Str, wchar_t* stackBuffer16, const size_t stackBuf16Size ); - -//---------------------------------------------------------- -bool FileStream::Open( const char* path, FileMode mode, FileAccess access, FileFlags flags ) -{ - return Open( path, *this, mode, access, flags ); -} - -//---------------------------------------------------------- -bool FileStream::Open( const char* path, FileStream& file, FileMode mode, FileAccess access, FileFlags flags ) -{ - if( path == nullptr ) - return false; - - if( file.HasValidFD() ) - return false; - - - // Encode utf-8 path to wchar_t - wchar_t path16Stack[BUF16_STACK_LEN]; - - wchar_t* path16 = Utf8ToUtf16( path, path16Stack, BUF16_STACK_LEN ); - if( !path16 ) - return false; - - if( access == FileAccess::None ) - access = FileAccess::Read; - - const DWORD dwShareMode = 0; - const DWORD dwCreationDisposition = mode == FileMode::Create ? CREATE_ALWAYS : - mode == FileMode::Open ? OPEN_ALWAYS : - OPEN_EXISTING; - DWORD dwFlags = FILE_ATTRIBUTE_NORMAL; - DWORD dwAccess = 0; - - if( IsFlagSet( flags, FileFlags::NoBuffering ) ) - dwFlags = FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; - - if( IsFlagSet( access, FileAccess::Read ) ) - dwAccess = GENERIC_READ; - - if( IsFlagSet( access, FileAccess::Write ) ) - dwAccess |= GENERIC_WRITE; - - HANDLE fd = CreateFile( path16, dwAccess, dwShareMode, NULL, - dwCreationDisposition, dwFlags, NULL ); - - if( fd != INVALID_HANDLE_VALUE ) - { - // Get the block (cluster) size - size_t blockSize; - - if( !GetFileClusterSize( fd, blockSize ) ) - Log::Error( "Failed to obtain file block size. Defaulting to %llu, but writes may fail.", blockSize ); - - file._fd = fd; - file._blockSize = blockSize; - file._writePosition = 0; - file._readPosition = 0; - file._access = access; - file._flags = flags; - file._error = 0; - - // #TODO: Seek to end if appending? - } - else - { - // #TODO: Use GetLastError report error in utf8 - file._error = (int)GetLastError(); - } - - if( path16 != path16Stack ) - free( path16 ); - - return fd != INVALID_HANDLE_VALUE; -} - -//----------------------------------------------------------- -void FileStream::Close() -{ - if( !HasValidFD() ) - return; - - #if _DEBUG - BOOL r = - #endif - - CloseHandle( _fd ); - - #if _DEBUG - ASSERT( r ); - #endif - - _fd = INVALID_HANDLE_VALUE; - _writePosition = 0; - _readPosition = 0; - _access = FileAccess::None; - _error = 0; - _blockSize = 0; -} - -//----------------------------------------------------------- -ssize_t FileStream::Read( void* buffer, size_t size ) -{ - ASSERT( buffer ); - - if( buffer == nullptr ) - return -1; - - if( !IsFlagSet( _access, FileAccess::Read ) ) - return -1; - - if( !HasValidFD() ) - return -1; - - if( size < 1 ) - return 0; - - DWORD bytesToRead = size > std::numeric_limits::max() ? - std::numeric_limits::max() : - (DWORD)size; - - if( IsFlagSet( _flags, FileFlags::NoBuffering ) ) - { - // #NOTE: See comment on Write() about this. - bytesToRead = (DWORD)( bytesToRead / _blockSize * _blockSize ); - } - - DWORD bytesRead = 0; - - // Cap size to 32-bit range - const BOOL r = ReadFile( _fd, buffer, bytesToRead, &bytesRead, NULL ); - - if( r ) - _readPosition += (size_t)bytesRead; - else - { - _error = (int)GetLastError(); - return (ssize_t)-1; - } - - return (ssize_t)bytesRead; -} - -//----------------------------------------------------------- -ssize_t FileStream::Write( const void* buffer, size_t size ) -{ - ASSERT( buffer ); - ASSERT( size ); - ASSERT( _fd ); - - if( buffer == nullptr ) - return -1; - - if( !IsFlagSet( _access, FileAccess::Write ) ) - return -1; - - if( !HasValidFD() ) - return -1; - - if( size < 1 ) - return 0; - - DWORD bytesToWrite = size > std::numeric_limits::max() ? - std::numeric_limits::max() : - (DWORD)size; - - if( IsFlagSet( _flags, FileFlags::NoBuffering ) ) - { - // We can only write in block sizes. But since the user may have - // specified a size greater than DWORD, our clamping it to - // DWORD's max can cause it to become not bounded to block size, - // even if the user's original size was block-bound. - // So let's limit this to a block size. - bytesToWrite = (DWORD)(bytesToWrite / _blockSize * _blockSize); - } - - DWORD bytesWritten = 0; - BOOL r = WriteFile( _fd, buffer, bytesToWrite, &bytesWritten, NULL ); - - if( r ) - _writePosition += (size_t)bytesWritten; - else - { - _error = (int)GetLastError(); - return (ssize_t)-1; - } - - return (ssize_t)bytesWritten; -} - -//---------------------------------------------------------- -bool FileStream::Reserve( ssize_t size ) -{ - // #TODO: Use SetFileValidData()? - // #See: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfilevaliddata - - return false; -} - -//---------------------------------------------------------- -bool FileStream::Seek( int64 offset, SeekOrigin origin ) -{ - if( !IsOpen() || !HasValidFD() ) - return false; - - DWORD whence; - switch( origin ) - { - case SeekOrigin::Begin : whence = FILE_BEGIN ; break; - case SeekOrigin::Current: whence = FILE_CURRENT; break; - case SeekOrigin::End : whence = FILE_END ; break; - default: return false; - } - - LARGE_INTEGER distanceToMove, newPosition; - distanceToMove.QuadPart = offset; - - const BOOL r = ::SetFilePointerEx( _fd, distanceToMove, &newPosition, whence ); - - if( !r ) - _error = GetLastError(); - - _writePosition = (size_t)newPosition.QuadPart; - _readPosition = (size_t)newPosition.QuadPart; - - return (bool)r; -} - -//----------------------------------------------------------- -bool FileStream::Flush() -{ - if( !IsOpen() || !HasValidFD() ) - return false; - - const BOOL r = FlushFileBuffers( _fd ); - - if( !r ) - _error = GetLastError(); - - return (bool)r; -} - -//----------------------------------------------------------- -bool FileStream::IsOpen() const -{ - return HasValidFD(); -} - -//----------------------------------------------------------- -bool FileStream::Exists( const char* path ) -{ - ASSERT( path ); - if( !path || !*path ) - return false; - - wchar_t stackBuffer[BUF16_STACK_LEN]; - - wchar_t* path16 = Utf8ToUtf16( path, stackBuffer, BUF16_STACK_LEN ); - if( !path16 ) - { - Log::Error( "FileStream::Exists() Failed to convert path to utf16." ); - return false; - } - - bool exists = true; - - const DWORD r = GetFileAttributesW( path16 ); - - if( r == INVALID_FILE_ATTRIBUTES ) - exists = false; - - if( path16 != stackBuffer ) - free( path16 ); - - return exists; -} - -//----------------------------------------------------------- -wchar_t* Utf8ToUtf16( const char* utf8Str, wchar_t* stackBuffer16, const size_t stackBuf16Size ) -{ - const size_t length8 = strlen( utf8Str ); - - if( length8 < 1 ) - return nullptr; - - if( length8 > std::numeric_limits::max() ) - { - Log::Error( "File path is too long." ); - return nullptr; - } - - - const int requiredLen16 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, utf8Str, (int)length8, NULL, 0 ) + 1; - - if( requiredLen16 <= 1 ) - { - Log::Error( "Could not get encoded file path length." ); - return nullptr; - } - - wchar_t* str16 = nullptr; - - if( requiredLen16 <= stackBuf16Size ) - { - str16 = stackBuffer16; - } - else - { - str16 = (wchar_t*)malloc( sizeof( wchar_t ) * (size_t)requiredLen16 ); - if( !str16 ) - { - Log::Error( "Failed to allocate file path buffer." ); - return nullptr; - } - } - - const int numEncoded = MultiByteToWideChar( - CP_UTF8, MB_PRECOMPOSED, - utf8Str, (int)length8, - str16, requiredLen16 - ); - - ASSERT( numEncoded == requiredLen16-1 ); - - str16[numEncoded] = 0; - - return str16; -} - -//----------------------------------------------------------- -//bool GetFileClusterSize( wchar_t* filePath, size_t& outClusterSize ) -bool GetFileClusterSize( HANDLE hFile, size_t& outClusterSize ) -{ - outClusterSize = 4096; - - ASSERT( hFile != INVALID_HANDLE_VALUE ); - - FILE_STORAGE_INFO info = { 0 }; - const BOOL r = GetFileInformationByHandleEx( hFile, FileStorageInfo, &info, (DWORD)sizeof( info ) ); - - if( r ) - outClusterSize = info.PhysicalBytesPerSectorForPerformance; - - return (bool)r; - // - //ASSERT( filePath ); - - //// Get path to the device - //if (!PathStripToRootW( filePath ) ) - // return false; - // - //const size_t len = std::char_traits::length( filePath ); - - //// #TODO: Do this properly by copying to another buffer that we're sure has enough size - //memmove( filePath + 4, filePath, (len + 1) * sizeof( wchar_t ) ); - //filePath[0] = u'\\'; - //filePath[1] = u'\\'; - //filePath[2] = u'.' ; - //filePath[3] = u'\\'; - - //HANDLE hDevice = INVALID_HANDLE_VALUE; - - //// #See: https://docs.microsoft.com/en-us/windows/win32/devio/calling-deviceiocontrol - //hDevice = CreateFileW( filePath, // drive to open - // 0, // no access to the drive - // FILE_SHARE_READ | // share mode - // FILE_SHARE_WRITE, - // NULL, // default security attributes - // OPEN_EXISTING, // disposition - // 0, // file attributes - // NULL ); - - //if( hDevice == INVALID_HANDLE_VALUE ) - // return false; - - //STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR desc = { 0 }; - //DWORD bytesReturned; - - //STORAGE_PROPERTY_QUERY spq = { StorageAccessAlignmentProperty, PropertyStandardQuery }; - - //BOOL r = DeviceIoControl( - // hDevice, - // IOCTL_STORAGE_QUERY_PROPERTY, - // &spq, sizeof( spq ), - // &desc, sizeof( desc ), - // &bytesReturned, - // NULL ); - // - //// MS recommends the use the physical sector size - //// #See: https://docs.microsoft.com/en-us/windows/win32/fileio/file-buffering - //if( r ) - // outClusterSize = desc.BytesPerPhysicalSector; - //else - //{ - // const DWORD err = GetLastError(); - // Log::Error( "Error getting block size: %d (0x%x)", err ); - //} - - //CloseHandle( hDevice ); - - //return (bool)r; +#include "io/FileStream.h" +#include "util/Util.h" +#include "util/Log.h" +#include +//#include +//#include +//#pragma comment( lib, "Shlwapi.lib" ) + + +const size_t BUF16_STACK_LEN = 1024; + +//bool GetFileClusterSize( wchar_t* filePath, size_t& outClusterSize ); +bool GetFileClusterSize( HANDLE hFile, size_t& outClusterSize ); + +wchar_t* Utf8ToUtf16( const char* utf8Str, wchar_t* stackBuffer16, const size_t stackBuf16Size ); + +//---------------------------------------------------------- +bool FileStream::Open( const char* path, FileMode mode, FileAccess access, FileFlags flags ) +{ + return Open( path, *this, mode, access, flags ); +} + +//---------------------------------------------------------- +bool FileStream::Open( const char* path, FileStream& file, FileMode mode, FileAccess access, FileFlags flags ) +{ + if( path == nullptr ) + return false; + + if( file.HasValidFD() ) + return false; + + + // Encode utf-8 path to wchar_t + wchar_t path16Stack[BUF16_STACK_LEN]; + + wchar_t* path16 = Utf8ToUtf16( path, path16Stack, BUF16_STACK_LEN ); + if( !path16 ) + return false; + + if( access == FileAccess::None ) + access = FileAccess::Read; + + const DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; // #TODO: Specify this as flags, for now we need full share for MT I/O + const DWORD dwCreationDisposition = mode == FileMode::Create ? CREATE_ALWAYS : + mode == FileMode::Open ? OPEN_EXISTING : OPEN_ALWAYS; + + DWORD dwFlags = FILE_ATTRIBUTE_NORMAL; + DWORD dwAccess = 0; + + if( IsFlagSet( flags, FileFlags::NoBuffering ) ) + dwFlags = FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; + + if( IsFlagSet( access, FileAccess::Read ) ) + dwAccess = GENERIC_READ; + + if( IsFlagSet( access, FileAccess::Write ) ) + dwAccess |= GENERIC_WRITE; + + HANDLE fd = CreateFile( path16, dwAccess, dwShareMode, NULL, + dwCreationDisposition, dwFlags, NULL ); + + if( fd != INVALID_HANDLE_VALUE ) + { + // Clear error in case we're re-opening an existing file (it emits ERROR_ALREADY_EXISTS) + GetLastError(); + + // Get the block (cluster) size + size_t blockSize; + + if( !GetFileClusterSize( fd, blockSize ) ) + Log::Error( "Failed to obtain file block size. Defaulting to %llu, but writes may fail.", blockSize ); + + file._fd = fd; + file._blockSize = blockSize; + file._position = 0; + file._access = access; + file._flags = flags; + file._error = 0; + + // #TODO: Seek to end if appending? + } + else + { + // #TODO: Use GetLastError report error in utf8 + file._error = (int)GetLastError(); + } + + if( path16 != path16Stack ) + free( path16 ); + + return fd != INVALID_HANDLE_VALUE; +} + +//----------------------------------------------------------- +void FileStream::Close() +{ + if( !HasValidFD() ) + return; + + #if _DEBUG + BOOL r = + #endif + + CloseHandle( _fd ); + + #if _DEBUG + ASSERT( r ); + #endif + + _fd = INVALID_HANDLE_VALUE; + _position = 0; + _access = FileAccess::None; + _error = 0; + _blockSize = 0; +} + +//----------------------------------------------------------- +ssize_t FileStream::Read( void* buffer, size_t size ) +{ + ASSERT( buffer ); + + if( buffer == nullptr ) + return -1; + + if( !IsFlagSet( _access, FileAccess::Read ) ) + return -1; + + if( !HasValidFD() ) + return -1; + + if( size < 1 ) + return 0; + + DWORD bytesToRead = size > std::numeric_limits::max() ? + std::numeric_limits::max() : + (DWORD)size; + + if( IsFlagSet( _flags, FileFlags::NoBuffering ) ) + { + // #NOTE: See comment on Write() about this. + bytesToRead = (DWORD)( bytesToRead / _blockSize * _blockSize ); + } + + DWORD bytesRead = 0; + + // Cap size to 32-bit range + const BOOL r = ReadFile( _fd, buffer, bytesToRead, &bytesRead, NULL ); + + if( r ) + _position += (size_t)bytesRead; + else + { + _error = (int)GetLastError(); + bytesRead = -1; + } + + return (ssize_t)bytesRead; +} + +//----------------------------------------------------------- +ssize_t FileStream::Write( const void* buffer, size_t size ) +{ + ASSERT( buffer ); + ASSERT( size ); + ASSERT( _fd ); + + if( buffer == nullptr ) + return -1; + + if( !IsFlagSet( _access, FileAccess::Write ) ) + return -1; + + if( !HasValidFD() ) + return -1; + + if( size < 1 ) + return 0; + + DWORD bytesToWrite = size > std::numeric_limits::max() ? + std::numeric_limits::max() : + (DWORD)size; + + if( IsFlagSet( _flags, FileFlags::NoBuffering ) ) + { + // We can only write in block sizes. But since the user may have + // specified a size greater than DWORD, our clamping it to + // DWORD's max can cause it to become not bounded to block size, + // even if the user's original size was block-bound. + // So let's limit this to a block size. + bytesToWrite = (DWORD)(bytesToWrite / _blockSize * _blockSize); + } + + DWORD bytesWritten = 0; + BOOL r = WriteFile( _fd, buffer, bytesToWrite, &bytesWritten, NULL ); + + if( r ) + _position += (size_t)bytesWritten; + else + { + _error = (int)GetLastError(); + bytesWritten = -1; + } + + return bytesWritten; +} + +//---------------------------------------------------------- +bool FileStream::Reserve( ssize_t size ) +{ + // #TODO: Use SetFileValidData()? + // #See: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfilevaliddata + + return false; +} + +//---------------------------------------------------------- +bool FileStream::Seek( int64 offset, SeekOrigin origin ) +{ + if( !IsOpen() || !HasValidFD() ) + return false; + + DWORD whence; + switch( origin ) + { + case SeekOrigin::Begin : whence = FILE_BEGIN ; break; + case SeekOrigin::Current: whence = FILE_CURRENT; break; + case SeekOrigin::End : whence = FILE_END ; break; + default: return false; + } + + LARGE_INTEGER distanceToMove, newPosition; + distanceToMove.QuadPart = offset; + + const BOOL r = ::SetFilePointerEx( _fd, distanceToMove, &newPosition, whence ); + + if( !r ) + _error = GetLastError(); + + _position = (size_t)newPosition.QuadPart; + + return (bool)r; +} + +//----------------------------------------------------------- +bool FileStream::Flush() +{ + if( !IsOpen() || !HasValidFD() ) + return false; + + const BOOL r = FlushFileBuffers( _fd ); + + if( !r ) + _error = GetLastError(); + + return (bool)r; +} + +//----------------------------------------------------------- +bool FileStream::IsOpen() const +{ + return HasValidFD(); +} + +//----------------------------------------------------------- +ssize_t FileStream::Size() +{ + LARGE_INTEGER size; + const BOOL r = ::GetFileSizeEx( _fd, &size ); + + if( !r ) + { + _error = ::GetLastError(); + Log::Line( "Error: GetFileSizeEx() failed with error: %d", _error ); + return 0; + } + + return (ssize_t)size.QuadPart; +} + +//----------------------------------------------------------- +bool FileStream::Truncate( const ssize_t length ) +{ + if( !Seek( (int64)length, SeekOrigin::Begin ) ) + return false; + + const BOOL r = ::SetEndOfFile( _fd ); + if( !r ) + { + _error = ::GetLastError(); + Log::Line( "Error: SetEndOfFile() failed with error: %d", _error ); + return false; + } + + return true; +} + +//----------------------------------------------------------- +bool FileStream::Exists( const char* path ) +{ + ASSERT( path ); + if( !path || !*path ) + return false; + + wchar_t stackBuffer[BUF16_STACK_LEN]; + + wchar_t* path16 = Utf8ToUtf16( path, stackBuffer, BUF16_STACK_LEN ); + if( !path16 ) + { + Log::Error( "FileStream::Exists() Failed to convert path to utf16." ); + return false; + } + + bool exists = true; + + const DWORD r = GetFileAttributesW( path16 ); + + if( r == INVALID_FILE_ATTRIBUTES ) + exists = false; + + if( path16 != stackBuffer ) + free( path16 ); + + return exists; +} + +//----------------------------------------------------------- +wchar_t* Utf8ToUtf16( const char* utf8Str, wchar_t* stackBuffer16, const size_t stackBuf16Size ) +{ + const size_t length8 = strlen( utf8Str ); + + if( length8 < 1 ) + return nullptr; + + if( length8 > std::numeric_limits::max() ) + { + Log::Error( "File path is too long." ); + return nullptr; + } + + + const int requiredLen16 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, utf8Str, (int)length8, NULL, 0 ) + 1; + + if( requiredLen16 <= 1 ) + { + Log::Error( "Could not get encoded file path length." ); + return nullptr; + } + + wchar_t* str16 = nullptr; + + if( requiredLen16 <= stackBuf16Size ) + { + str16 = stackBuffer16; + } + else + { + str16 = (wchar_t*)malloc( sizeof( wchar_t ) * (size_t)requiredLen16 ); + if( !str16 ) + { + Log::Error( "Failed to allocate file path buffer." ); + return nullptr; + } + } + + const int numEncoded = MultiByteToWideChar( + CP_UTF8, MB_PRECOMPOSED, + utf8Str, (int)length8, + str16, requiredLen16 + ); + + ASSERT( numEncoded == requiredLen16-1 ); + + str16[numEncoded] = 0; + + return str16; +} + +//----------------------------------------------------------- +//bool GetFileClusterSize( wchar_t* filePath, size_t& outClusterSize ) +bool GetFileClusterSize( HANDLE hFile, size_t& outClusterSize ) +{ + outClusterSize = 4096; + + ASSERT( hFile != INVALID_HANDLE_VALUE ); + + FILE_STORAGE_INFO info = { 0 }; + const BOOL r = GetFileInformationByHandleEx( hFile, FileStorageInfo, &info, (DWORD)sizeof( info ) ); + + if( r ) + outClusterSize = info.PhysicalBytesPerSectorForPerformance; + + return (bool)r; + // + //ASSERT( filePath ); + + //// Get path to the device + //if (!PathStripToRootW( filePath ) ) + // return false; + // + //const size_t len = std::char_traits::length( filePath ); + + //// #TODO: Do this properly by copying to another buffer that we're sure has enough size + //memmove( filePath + 4, filePath, (len + 1) * sizeof( wchar_t ) ); + //filePath[0] = u'\\'; + //filePath[1] = u'\\'; + //filePath[2] = u'.' ; + //filePath[3] = u'\\'; + + //HANDLE hDevice = INVALID_HANDLE_VALUE; + + //// #See: https://docs.microsoft.com/en-us/windows/win32/devio/calling-deviceiocontrol + //hDevice = CreateFileW( filePath, // drive to open + // 0, // no access to the drive + // FILE_SHARE_READ | // share mode + // FILE_SHARE_WRITE, + // NULL, // default security attributes + // OPEN_EXISTING, // disposition + // 0, // file attributes + // NULL ); + + //if( hDevice == INVALID_HANDLE_VALUE ) + // return false; + + //STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR desc = { 0 }; + //DWORD bytesReturned; + + //STORAGE_PROPERTY_QUERY spq = { StorageAccessAlignmentProperty, PropertyStandardQuery }; + + //BOOL r = DeviceIoControl( + // hDevice, + // IOCTL_STORAGE_QUERY_PROPERTY, + // &spq, sizeof( spq ), + // &desc, sizeof( desc ), + // &bytesReturned, + // NULL ); + // + //// MS recommends the use the physical sector size + //// #See: https://docs.microsoft.com/en-us/windows/win32/fileio/file-buffering + //if( r ) + // outClusterSize = desc.BytesPerPhysicalSector; + //else + //{ + // const DWORD err = GetLastError(); + // Log::Error( "Error getting block size: %d (0x%x)", err ); + //} + + //CloseHandle( hDevice ); + + //return (bool)r; } \ No newline at end of file diff --git a/src/platform/win32/SysHost_Win32.cpp b/src/platform/win32/SysHost_Win32.cpp index d3ab683a..08ddd107 100644 --- a/src/platform/win32/SysHost_Win32.cpp +++ b/src/platform/win32/SysHost_Win32.cpp @@ -1,511 +1,606 @@ -#include "SysHost.h" -#include "Platform.h" -#include "Util.h" -#include "util//Log.h" - -#include -#include -#include - -/* -* Based on source from libSodium: ref: https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c -* ISC License -* Copyright( c ) 2013 - 2020 -* Frank Denis -*/ -#define RtlGenRandom SystemFunction036 -extern "C" BOOLEAN NTAPI RtlGenRandom( PVOID RandomBuffer, ULONG RandomBufferLength ); -#pragma comment( lib, "advapi32.lib" ) - -// Helper structs to help us iterate these variable-length structs -template -class PocessorInfoIter -{ - using ProcInfo = SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX; - - byte* _current; - const byte* _end ; - -public: - //----------------------------------------------------------- - inline PocessorInfoIter( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* info, DWORD size ) - : _current( (byte*)info ) - , _end ( ((byte*)info) + size ) - {} - - //----------------------------------------------------------- - inline bool HasNext() const - { - return _current < _end; - } - - //----------------------------------------------------------- - inline T& Next() - { - ASSERT( this->HasNext() ); - - ProcInfo* info = (ProcInfo*)_current; - - T& r = *(T*)&info->Processor; - - _current += info->Size; - return r; - } -}; - -static GROUP_RELATIONSHIP* _procGroupInfo = nullptr; - - -//----------------------------------------------------------- -size_t SysHost::GetPageSize() -{ - SYSTEM_INFO info; - ::GetSystemInfo( &info ); - - const size_t pageSize = (size_t)info.dwPageSize; - return pageSize; -} - -//----------------------------------------------------------- -size_t SysHost::GetTotalSystemMemory() -{ - MEMORYSTATUSEX statex; - statex.dwLength = sizeof( statex ); - - BOOL r = GlobalMemoryStatusEx( &statex ); - if( !r ) - return 0; - - // #TODO: Return total virtual... We will let the user use a page file. - return statex.ullTotalPhys; -} - -//----------------------------------------------------------- -size_t SysHost::GetAvailableSystemMemory() -{ - MEMORYSTATUSEX statex; - statex.dwLength = sizeof( statex ); - - BOOL r = GlobalMemoryStatusEx( &statex ); - if( !r ) - return 0; - - // #TODO: Return total virtual... We will let the user use a page file. - return statex.ullAvailPhys; -} - -//----------------------------------------------------------- -uint SysHost::GetLogicalCPUCount() -{ - return (uint)GetActiveProcessorCount( ALL_PROCESSOR_GROUPS ); -} - -//----------------------------------------------------------- -void* SysHost::VirtualAlloc( size_t size, bool initialize ) -{ - SYSTEM_INFO info; - ::GetSystemInfo( &info ); - - const size_t pageSize = (size_t)info.dwPageSize; - size = CeildDiv( size, pageSize ); - - void* ptr = ::VirtualAlloc( NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE ); - - if( ptr && initialize ) - { - // Fault memory pages - - byte* page = (byte*)ptr; - - const size_t pageCount = size / pageSize; - const byte* endPage = page + pageCount * pageSize; - - do - { - *page = 0; - page += pageSize; - } while( page < endPage ); - } - - return ptr; -} - -//----------------------------------------------------------- -void SysHost::VirtualFree( void* ptr ) -{ - ASSERT( ptr ); - if( !ptr ) - return; - - const BOOL r = ::VirtualFree( (LPVOID)ptr, 0, MEM_RELEASE ); - if( !r ) - { - const DWORD err = GetLastError(); - Log::Error( "VirtualFree() failed with error: %d", err ); - } -} - -//----------------------------------------------------------- -bool SysHost::VirtualProtect( void* ptr, size_t size, VProtect flags ) -{ - ASSERT( ptr ); - - // #TODO: Implement me - return true; -} - -//----------------------------------------------------------- -// uint64 SysHost::SetCurrentProcessAffinityMask( uint64 mask ) -// { -// HANDLE hProcess = ::GetCurrentProcess(); - -// BOOL r = ::SetProcessAffinityMask( hProcess, mask ); -// ASSERT( r ); - -// return r ? mask : 0; -// } - -// //----------------------------------------------------------- -// uint64 SysHost::SetCurrentThreadAffinityMask( uint64 mask ) -// { -// HANDLE hThread = ::GetCurrentThread(); -// -// const uint64 oldMask = ::SetThreadAffinityMask( hThread, mask ); -// -// if( oldMask == 0 ) -// return 0; -// -// return mask; -// } - -//----------------------------------------------------------- -bool SysHost::SetCurrentThreadAffinityCpuId( uint32 cpuId ) -{ - ASSERT( cpuId < (uint)GetActiveProcessorCount( ALL_PROCESSOR_GROUPS ) ); - - HANDLE hThread = ::GetCurrentThread(); - - // #TODO: We might have to check for single-node system with more than 64 threads. - // If in NUMA, we need to find the correct process group given a cpuId - const NumaInfo* numa = GetNUMAInfo(); - if( numa ) - { - ASSERT( _procGroupInfo ); - - WORD processGroupId = 0; - - // Shave-out any process groups below the requested one - for( WORD i = 0; i < _procGroupInfo->ActiveGroupCount; i++ ) - { - const uint groupProcCount = _procGroupInfo->GroupInfo[i].ActiveProcessorCount; - if( cpuId < groupProcCount ) - { - processGroupId = i; - break; - } - - cpuId -= groupProcCount; - } - - // Move this thread to the target process group - GROUP_AFFINITY grpAffinity, prevGprAffinity; - - ZeroMem( &grpAffinity ); - grpAffinity.Mask = 1ull << cpuId; - grpAffinity.Group = processGroupId; - if( !SetThreadGroupAffinity( hThread, &grpAffinity, &prevGprAffinity ) ) - { - const DWORD err = GetLastError(); - Log::Error( "Error: Failed to set thread group affinity with error: %d (0x%x).", err, err ); - return false; - } - } - - const uint64 mask = 1ull << cpuId; - const uint64 oldMask = (uint64)::SetThreadAffinityMask( hThread, mask ); - - if( oldMask == 0 ) - { - const DWORD err = GetLastError(); - Log::Error( "Error: Failed to set thread affinity with error: %d (0x%x).", err, err ); - } - - return oldMask != 0; -} - -//----------------------------------------------------------- -void SysHost::InstallCrashHandler() -{ - // #TODO: Implement me -} - -//----------------------------------------------------------- -void SysHost::Random( byte* buffer, size_t size ) -{ - if( !RtlGenRandom( (PVOID)buffer, (ULONG)size ) ) - { - Fatal( "System entropy gen failure." ); - } -} - -// #SEE: https://docs.microsoft.com/en-us/windows/win32/procthread/numa-support -// #SEE: https://docs.microsoft.com/en-us/windows/win32/procthread/processor-groups -// #NOTE: This is not thread-safe on the first time is called -//----------------------------------------------------------- -const NumaInfo* SysHost::GetNUMAInfo() -{ - // #TODO: Check _WIN32_WINNT >= 0x0601 - // Build 20348 - // and support new NUMA method/API. - - static NumaInfo _info; - static NumaInfo* _pInfo = nullptr; - - if( !_pInfo ) - { - uint nodeCount = 0; - - if( !GetNumaHighestNodeNumber( (PULONG)&nodeCount ) ) - { - const DWORD err = GetLastError(); - Log::Error( "Warning: Failed to get NUMA info with error %d (0x%x).", err, err ); - return nullptr; - } - - // The above returns the highest node index (0-based), we want the count. - nodeCount++; - - if( nodeCount < 2 ) - return nullptr; - - ZeroMem( &_info ); - - uint procGroupCount = 0; - uint totalCpuCount = 0; - - // Get number of processor groups in this system - procGroupCount = (uint)GetActiveProcessorGroupCount(); - if( procGroupCount == 0 ) - { - const DWORD err = GetLastError(); - Fatal( "GetActiveProcessorGroupCount() failed with error: %d (0x%x).", err, err ); - } - - // Get the total number of active CPUs - totalCpuCount = (uint)GetActiveProcessorCount( ALL_PROCESSOR_GROUPS ); - if( totalCpuCount == 0 ) - { - const DWORD err = GetLastError(); - Fatal( "GetActiveProcessorCount() failed with error: %d (0x%x).", err, err ); - } - - // Allocate required buffers - _info.cpuIds = ( Span* )malloc( sizeof( Span ) * nodeCount ); - FatalIf( !_info.cpuIds, "Failed to allocate NUMA node buffer." ); - memset( _info.cpuIds, 0, sizeof( Span ) * nodeCount ); - - uint* cpuIds = (uint*)malloc( sizeof( uint ) * totalCpuCount ); - FatalIf( !cpuIds, "Failed to allocate CPU id buffer." ); - memset( cpuIds, 0, sizeof( uint ) * totalCpuCount ); - - - // Get nodes & process group information - DWORD nodeInfoLength = 0, procInfoLength = 0; - DWORD result = 0; - - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* nodeInfo = nullptr, *procInfo = nullptr; - - // Get node info size - if( GetLogicalProcessorInformationEx( RelationNumaNode, nullptr, &nodeInfoLength ) ) - Fatal( "Unexpected result from GetLogicalProcessorInformationEx( RelationNumaNode )." ); - - result = GetLastError(); - if( result != ERROR_INSUFFICIENT_BUFFER ) - Fatal( "GetLogicalProcessorInformationEx( RelationNumaNode, null ) with error: %d (0x%x).", result, result ); - - ASSERT( nodeInfoLength >= ( sizeof( DWORD ) + sizeof( LOGICAL_PROCESSOR_RELATIONSHIP ) ) ); - - - // Get process info size - if( GetLogicalProcessorInformationEx( RelationGroup, nullptr, &procInfoLength ) ) - Fatal( "Unexpected result from GetLogicalProcessorInformationEx( RelationGroup )." ); - - result = GetLastError(); - if( result != ERROR_INSUFFICIENT_BUFFER ) - Fatal( "GetLogicalProcessorInformationEx( RelationGroup, null ) with error: %d (0x%x).", result, result ); - - ASSERT( procInfoLength >= ( sizeof( DWORD ) + sizeof( LOGICAL_PROCESSOR_RELATIONSHIP ) ) ); - - // Allocate the buffers and fetch the actual info now - nodeInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc( nodeInfoLength ); - procInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc( procInfoLength ); - - if( !nodeInfo ) - Fatal( "Failed to allocate node info buffer." ); - if( !procInfo ) - Fatal( "Failed to allocate processor info buffer." ); - - if( !GetLogicalProcessorInformationEx( RelationNumaNode, nodeInfo, &nodeInfoLength ) ) - { - const DWORD err = GetLastError(); - Fatal( "GetLogicalProcessorInformationEx( RelationNumaNode ) failed with error: %d (0x%x).", err, err ); - } - - if( !GetLogicalProcessorInformationEx( RelationGroup, procInfo, &procInfoLength ) ) - { - const DWORD err = GetLastError(); - Fatal( "GetLogicalProcessorInformationEx( RelationGroup ) failed with error: %d (0x%x).", err, err ); - } - - ASSERT( procInfo->Size == procInfoLength ); // Only expect a single instance here - - - // Save an instance of process group info as we need to refer to it when setting thread affinity - _procGroupInfo = &procInfo->Group; - - // Get info from each node - for( PocessorInfoIter numaIter( nodeInfo, nodeInfoLength ); numaIter.HasNext(); ) - { - const NUMA_NODE_RELATIONSHIP& node = numaIter.Next(); - ASSERT( node.NodeNumber < nodeCount ); - ASSERT( node.GroupMask.Group < procInfo->Group.ActiveGroupCount ); - - const WORD targetGroupId = node.GroupMask.Group; - const PROCESSOR_GROUP_INFO& targetGroup = procInfo->Group.GroupInfo[targetGroupId]; - - // Find the starting cpuId for this group by - // adding all the active processors on the groups before ours - uint cpuBase = 0; - for( WORD i = 0; i < targetGroupId; i++ ) - cpuBase += procInfo->Group.GroupInfo[i].ActiveProcessorCount; - - // Save CPUids for this node - uint* nodeCpus = cpuIds; - for( BYTE i = 0; i < targetGroup.MaximumProcessorCount; i++ ) - { - if( targetGroup.ActiveProcessorMask & ( 1ull << i ) ) - *nodeCpus++ = cpuBase + i; - } - - ASSERT( (intptr_t)( nodeCpus - cpuIds ) == (intptr_t)targetGroup.ActiveProcessorCount ); - - // Save node info - _info.cpuIds[node.NodeNumber].length = targetGroup.ActiveProcessorCount; - _info.cpuIds[node.NodeNumber].values = cpuIds; - - cpuIds += targetGroup.ActiveProcessorCount; - ASSERT( cpuIds == nodeCpus ); - } - - // All done - _info.nodeCount = nodeCount; - _info.cpuCount = totalCpuCount; - _pInfo = &_info; - } - - return _pInfo; -} - -//----------------------------------------------------------- -void SysHost::NumaAssignPages( void* ptr, size_t size, uint node ) -{ - // #TODO: Implement me -} - -//----------------------------------------------------------- -bool SysHost::NumaSetThreadInterleavedMode() -{ - // Not a thing on windows - // #TODO: Remove this function - return false; -} - -//----------------------------------------------------------- -bool SysHost::NumaSetMemoryInterleavedMode( void* ptr, size_t size ) -{ - ASSERT( ptr && size ); - - ULONG nodeCount = 0; - - if( !GetNumaHighestNodeNumber( (PULONG)&nodeCount ) ) - { - const DWORD err = GetLastError(); - Log::Error( "Failed to get NUMA nodes to interleave memory with error %d (0x%x).", err, err ); - return false; - } - - nodeCount++; - - const size_t pageSize = GetPageSize(); - const size_t pageCount = size / pageSize; - - const size_t blockStride = pageSize * nodeCount; - const size_t blockCount = pageCount / nodeCount; - - const byte* pages = (byte*)ptr; - const byte* endPage = pages + pageCount * pageSize; - const byte* endBlock = pages + blockCount * blockStride; - - HANDLE gProcess = GetCurrentProcess(); - - DWORD dwNodes = (DWORD)nodeCount; - - while( pages < endBlock ) - { - for( DWORD i = 0; i < nodeCount; i++ ) - { - LPVOID r = VirtualAllocExNuma( - gProcess, - (LPVOID)pages, pageSize, - MEM_COMMIT, - PAGE_READWRITE, - i ); - - pages += pageSize; - if( !r ) - { - const DWORD err = GetLastError(); - Log::Error( "Failed to assigned memory to NUMA node with error: %d (0x%x).", err, err ); - return false; - } - } - } - - DWORD node = 0; - while( pages < endPage ) - { - LPVOID r = VirtualAllocExNuma( - gProcess, - (LPVOID)pages, pageSize, - MEM_COMMIT, - PAGE_READWRITE, - node++ ); - - if( !r ) - { - const DWORD err = GetLastError(); - Log::Error( "Failed to assigned memory to NUMA node with error: %d (0x%x).", err, err ); - return false; - } - - pages += pageSize; - } - - return true; -} - -//----------------------------------------------------------- -int SysHost::NumaGetNodeFromPage( void* ptr ) -{ - // #TODO: Implement me - // PSAPI_WORKING_SET_EX_INFORMATION info; - - // BOOL r = QueryWorkingSetEx( GetCurrentProcess(), (PVOID)&info, (DWORD)GetPageSize() ); - // if( !r ) - // { - // const DWORD err = GetLastError(); - // Log::Error( "Failed to call QueryWorkingSetEx with error: %d (0x%x).", err, err ); - // } - - return -1; +#include "SysHost.h" +#include "Platform.h" +#include "util/Util.h" +#include "util//Log.h" + +#include +#include +#include +#include + + +static_assert( INVALID_HANDLE_VALUE == INVALID_WIN32_HANDLE ); + +/* +* Based on source from libSodium: ref: https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c +* ISC License +* Copyright( c ) 2013 - 2020 +* Frank Denis +*/ +#define RtlGenRandom SystemFunction036 +extern "C" BOOLEAN NTAPI RtlGenRandom( PVOID RandomBuffer, ULONG RandomBufferLength ); +#pragma comment( lib, "advapi32.lib" ) + +static bool EnableLockMemoryPrivilege(); + + +// Helper structs to help us iterate these variable-length structs +template +class PocessorInfoIter +{ + using ProcInfo = SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX; + + byte* _current; + const byte* _end ; + +public: + //----------------------------------------------------------- + inline PocessorInfoIter( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* info, DWORD size ) + : _current( (byte*)info ) + , _end ( ((byte*)info) + size ) + {} + + //----------------------------------------------------------- + inline bool HasNext() const + { + return _current < _end; + } + + //----------------------------------------------------------- + inline T& Next() + { + ASSERT( this->HasNext() ); + + ProcInfo* info = (ProcInfo*)_current; + + T& r = *(T*)&info->Processor; + + _current += info->Size; + return r; + } +}; + +static GROUP_RELATIONSHIP* _procGroupInfo = nullptr; + + +//----------------------------------------------------------- +size_t SysHost::GetPageSize() +{ + SYSTEM_INFO info; + ::GetSystemInfo( &info ); + + const size_t pageSize = (size_t)info.dwPageSize; + return pageSize; +} + +//----------------------------------------------------------- +size_t SysHost::GetTotalSystemMemory() +{ + MEMORYSTATUSEX statex; + statex.dwLength = sizeof( statex ); + + BOOL r = GlobalMemoryStatusEx( &statex ); + if( !r ) + return 0; + + // #TODO: Return total virtual... We will let the user use a page file. + return statex.ullTotalPhys; +} + +//----------------------------------------------------------- +size_t SysHost::GetAvailableSystemMemory() +{ + MEMORYSTATUSEX statex; + statex.dwLength = sizeof( statex ); + + BOOL r = GlobalMemoryStatusEx( &statex ); + if( !r ) + return 0; + + // #TODO: Return total virtual... We will let the user use a page file. + return statex.ullAvailPhys; +} + +//----------------------------------------------------------- +uint SysHost::GetLogicalCPUCount() +{ + return (uint)GetActiveProcessorCount( ALL_PROCESSOR_GROUPS ); +} + +//----------------------------------------------------------- +void* SysHost::VirtualAlloc( size_t size, bool initialize ) +{ + SYSTEM_INFO info; + ::GetSystemInfo( &info ); + + size_t pageSize = (size_t)info.dwPageSize; + DWORD allocType = MEM_RESERVE | MEM_COMMIT; + + // #TODO: Add a hint to see if we want to allocate large pages. + const bool useLargePages = false; //EnableLockMemoryPrivilege(); +// Log::Line( "Large page support: %s", useLargePages ? "true" : "false" ); +// if( useLargePages ) +// { +// pageSize = (size_t)::GetLargePageMinimum(); +// allocType |= MEM_LARGE_PAGES; +// } +// else +// Log::Line( "No large page support." ); + + // See if we can allocate large pages + size_t allocSize = RoundUpToNextBoundaryT( size, pageSize ); + + void* ptr = ::VirtualAlloc( NULL, allocSize, allocType, PAGE_READWRITE ); + + if( !ptr && useLargePages ) + { + const DWORD err = GetLastError(); + Log::Line( "Warning: Failed to allocate large pages with error: %d.", err ); + + // Try without large pages + allocSize = RoundUpToNextBoundaryT( size, (size_t)info.dwPageSize ); + ptr = ::VirtualAlloc( NULL, allocSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE ); + } + + // #TODO: Remove this + if( ptr && initialize ) + { + // Fault memory pages + byte* page = (byte*)ptr; + + const size_t pageCount = size / pageSize; + const byte* endPage = page + pageCount * pageSize; + + do + { + *page = 0; + page += pageSize; + } while( page < endPage ); + } + + return ptr; +} + +//----------------------------------------------------------- +void SysHost::VirtualFree( void* ptr ) +{ + ASSERT( ptr ); + if( !ptr ) + return; + + const BOOL r = ::VirtualFree( (LPVOID)ptr, 0, MEM_RELEASE ); + if( !r ) + { + const DWORD err = GetLastError(); + Log::Error( "VirtualFree() failed with error: %d", err ); + } +} + +//----------------------------------------------------------- +bool SysHost::VirtualProtect( void* ptr, size_t size, VProtect flags ) +{ + ASSERT( ptr ); + + // #TODO: Implement me + return true; +} + +//----------------------------------------------------------- +// uint64 SysHost::SetCurrentProcessAffinityMask( uint64 mask ) +// { +// HANDLE hProcess = ::GetCurrentProcess(); + +// BOOL r = ::SetProcessAffinityMask( hProcess, mask ); +// ASSERT( r ); + +// return r ? mask : 0; +// } + +// //----------------------------------------------------------- +// uint64 SysHost::SetCurrentThreadAffinityMask( uint64 mask ) +// { +// HANDLE hThread = ::GetCurrentThread(); +// +// const uint64 oldMask = ::SetThreadAffinityMask( hThread, mask ); +// +// if( oldMask == 0 ) +// return 0; +// +// return mask; +// } + +//----------------------------------------------------------- +bool SysHost::SetCurrentThreadAffinityCpuId( uint32 cpuId ) +{ + ASSERT( cpuId < (uint)GetActiveProcessorCount( ALL_PROCESSOR_GROUPS ) ); + + HANDLE hThread = ::GetCurrentThread(); + + // #TODO: We might have to check for single-node system with more than 64 threads. + // If in NUMA, we need to find the correct process group given a cpuId + const NumaInfo* numa = GetNUMAInfo(); + if( numa ) + { + ASSERT( _procGroupInfo ); + + WORD processGroupId = 0; + + // Shave-out any process groups below the requested one + for( WORD i = 0; i < _procGroupInfo->ActiveGroupCount; i++ ) + { + const uint groupProcCount = _procGroupInfo->GroupInfo[i].ActiveProcessorCount; + if( cpuId < groupProcCount ) + { + processGroupId = i; + break; + } + + cpuId -= groupProcCount; + } + + // Move this thread to the target process group + GROUP_AFFINITY grpAffinity, prevGprAffinity; + + ZeroMem( &grpAffinity ); + grpAffinity.Mask = 1ull << cpuId; + grpAffinity.Group = processGroupId; + if( !SetThreadGroupAffinity( hThread, &grpAffinity, &prevGprAffinity ) ) + { + const DWORD err = GetLastError(); + Log::Error( "Error: Failed to set thread group affinity with error: %d (0x%x).", err, err ); + return false; + } + } + + const uint64 mask = 1ull << cpuId; + const uint64 oldMask = (uint64)::SetThreadAffinityMask( hThread, mask ); + + if( oldMask == 0 ) + { + const DWORD err = GetLastError(); + Log::Error( "Error: Failed to set thread affinity with error: %d (0x%x).", err, err ); + } + + return oldMask != 0; +} + +//----------------------------------------------------------- +void SysHost::InstallCrashHandler() +{ + // #TODO: Implement me +} + +//----------------------------------------------------------- +void SysHost::DumpStackTrace() +{ + // #TODO: Implement me +} + +//----------------------------------------------------------- +void SysHost::Random( byte* buffer, size_t size ) +{ + if( !RtlGenRandom( (PVOID)buffer, (ULONG)size ) ) + { + Fatal( "System entropy gen failure." ); + } +} + +// #SEE: https://docs.microsoft.com/en-us/windows/win32/procthread/numa-support +// #SEE: https://docs.microsoft.com/en-us/windows/win32/procthread/processor-groups +// #NOTE: This is not thread-safe on the first time is called +//----------------------------------------------------------- +const NumaInfo* SysHost::GetNUMAInfo() +{ + // #TODO: Check _WIN32_WINNT >= 0x0601 + // Build 20348 + // and support new NUMA method/API. + + static NumaInfo _info; + static NumaInfo* _pInfo = nullptr; + + if( !_pInfo ) + { + uint nodeCount = 0; + + if( !GetNumaHighestNodeNumber( (PULONG)&nodeCount ) ) + { + const DWORD err = GetLastError(); + Log::Error( "Warning: Failed to get NUMA info with error %d (0x%x).", err, err ); + return nullptr; + } + + // The above returns the highest node index (0-based), we want the count. + nodeCount++; + + if( nodeCount < 2 ) + return nullptr; + + ZeroMem( &_info ); + + uint procGroupCount = 0; + uint totalCpuCount = 0; + + // Get number of processor groups in this system + procGroupCount = (uint)GetActiveProcessorGroupCount(); + if( procGroupCount == 0 ) + { + const DWORD err = GetLastError(); + Fatal( "GetActiveProcessorGroupCount() failed with error: %d (0x%x).", err, err ); + } + + // Get the total number of active CPUs + totalCpuCount = (uint)GetActiveProcessorCount( ALL_PROCESSOR_GROUPS ); + if( totalCpuCount == 0 ) + { + const DWORD err = GetLastError(); + Fatal( "GetActiveProcessorCount() failed with error: %d (0x%x).", err, err ); + } + + // Allocate required buffers + _info.cpuIds = ( Span* )malloc( sizeof( Span ) * nodeCount ); + FatalIf( !_info.cpuIds, "Failed to allocate NUMA node buffer." ); + memset( _info.cpuIds, 0, sizeof( Span ) * nodeCount ); + + uint* cpuIds = (uint*)malloc( sizeof( uint ) * totalCpuCount ); + FatalIf( !cpuIds, "Failed to allocate CPU id buffer." ); + memset( cpuIds, 0, sizeof( uint ) * totalCpuCount ); + + + // Get nodes & process group information + DWORD nodeInfoLength = 0, procInfoLength = 0; + DWORD result = 0; + + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* nodeInfo = nullptr, *procInfo = nullptr; + + // Get node info size + if( GetLogicalProcessorInformationEx( RelationNumaNode, nullptr, &nodeInfoLength ) ) + Fatal( "Unexpected result from GetLogicalProcessorInformationEx( RelationNumaNode )." ); + + result = GetLastError(); + if( result != ERROR_INSUFFICIENT_BUFFER ) + Fatal( "GetLogicalProcessorInformationEx( RelationNumaNode, null ) with error: %d (0x%x).", result, result ); + + ASSERT( nodeInfoLength >= ( sizeof( DWORD ) + sizeof( LOGICAL_PROCESSOR_RELATIONSHIP ) ) ); + + + // Get process info size + if( GetLogicalProcessorInformationEx( RelationGroup, nullptr, &procInfoLength ) ) + Fatal( "Unexpected result from GetLogicalProcessorInformationEx( RelationGroup )." ); + + result = GetLastError(); + if( result != ERROR_INSUFFICIENT_BUFFER ) + Fatal( "GetLogicalProcessorInformationEx( RelationGroup, null ) with error: %d (0x%x).", result, result ); + + ASSERT( procInfoLength >= ( sizeof( DWORD ) + sizeof( LOGICAL_PROCESSOR_RELATIONSHIP ) ) ); + + // Allocate the buffers and fetch the actual info now + nodeInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc( nodeInfoLength ); + procInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc( procInfoLength ); + + if( !nodeInfo ) + Fatal( "Failed to allocate node info buffer." ); + if( !procInfo ) + Fatal( "Failed to allocate processor info buffer." ); + + if( !GetLogicalProcessorInformationEx( RelationNumaNode, nodeInfo, &nodeInfoLength ) ) + { + const DWORD err = GetLastError(); + Fatal( "GetLogicalProcessorInformationEx( RelationNumaNode ) failed with error: %d (0x%x).", err, err ); + } + + if( !GetLogicalProcessorInformationEx( RelationGroup, procInfo, &procInfoLength ) ) + { + const DWORD err = GetLastError(); + Fatal( "GetLogicalProcessorInformationEx( RelationGroup ) failed with error: %d (0x%x).", err, err ); + } + + ASSERT( procInfo->Size == procInfoLength ); // Only expect a single instance here + + + // Save an instance of process group info as we need to refer to it when setting thread affinity + _procGroupInfo = &procInfo->Group; + + // Get info from each node + for( PocessorInfoIter numaIter( nodeInfo, nodeInfoLength ); numaIter.HasNext(); ) + { + const NUMA_NODE_RELATIONSHIP& node = numaIter.Next(); + ASSERT( node.NodeNumber < nodeCount ); + ASSERT( node.GroupMask.Group < procInfo->Group.ActiveGroupCount ); + + const WORD targetGroupId = node.GroupMask.Group; + const PROCESSOR_GROUP_INFO& targetGroup = procInfo->Group.GroupInfo[targetGroupId]; + + // Find the starting cpuId for this group by + // adding all the active processors on the groups before ours + uint cpuBase = 0; + for( WORD i = 0; i < targetGroupId; i++ ) + cpuBase += procInfo->Group.GroupInfo[i].ActiveProcessorCount; + + // Save CPUids for this node + uint* nodeCpus = cpuIds; + for( BYTE i = 0; i < targetGroup.MaximumProcessorCount; i++ ) + { + if( targetGroup.ActiveProcessorMask & ( 1ull << i ) ) + *nodeCpus++ = cpuBase + i; + } + + ASSERT( (intptr_t)( nodeCpus - cpuIds ) == (intptr_t)targetGroup.ActiveProcessorCount ); + + // Save node info + _info.cpuIds[node.NodeNumber].length = targetGroup.ActiveProcessorCount; + _info.cpuIds[node.NodeNumber].values = cpuIds; + + cpuIds += targetGroup.ActiveProcessorCount; + ASSERT( cpuIds == nodeCpus ); + } + + // All done + _info.nodeCount = nodeCount; + _info.cpuCount = totalCpuCount; + _pInfo = &_info; + } + + return _pInfo; +} + +//----------------------------------------------------------- +void SysHost::NumaAssignPages( void* ptr, size_t size, uint node ) +{ + // #TODO: Implement me +} + +//----------------------------------------------------------- +bool SysHost::NumaSetThreadInterleavedMode() +{ + // Not a thing on windows + // #TODO: Remove this function + return false; +} + +//----------------------------------------------------------- +bool SysHost::NumaSetMemoryInterleavedMode( void* ptr, size_t size ) +{ + ASSERT( ptr && size ); + + ULONG nodeCount = 0; + + if( !GetNumaHighestNodeNumber( (PULONG)&nodeCount ) ) + { + const DWORD err = GetLastError(); + Log::Error( "Failed to get NUMA nodes to interleave memory with error %d (0x%x).", err, err ); + return false; + } + + nodeCount++; + + const size_t pageSize = GetPageSize(); + const size_t pageCount = size / pageSize; + + const size_t blockStride = pageSize * nodeCount; + const size_t blockCount = pageCount / nodeCount; + + const byte* pages = (byte*)ptr; + const byte* endPage = pages + pageCount * pageSize; + const byte* endBlock = pages + blockCount * blockStride; + + HANDLE gProcess = GetCurrentProcess(); + + DWORD dwNodes = (DWORD)nodeCount; + + while( pages < endBlock ) + { + for( DWORD i = 0; i < nodeCount; i++ ) + { + LPVOID r = VirtualAllocExNuma( + gProcess, + (LPVOID)pages, pageSize, + MEM_COMMIT, + PAGE_READWRITE, + i ); + + pages += pageSize; + if( !r ) + { + const DWORD err = GetLastError(); + Log::Error( "Failed to assigned memory to NUMA node with error: %d (0x%x).", err, err ); + return false; + } + } + } + + DWORD node = 0; + while( pages < endPage ) + { + LPVOID r = VirtualAllocExNuma( + gProcess, + (LPVOID)pages, pageSize, + MEM_COMMIT, + PAGE_READWRITE, + node++ ); + + if( !r ) + { + const DWORD err = GetLastError(); + Log::Error( "Failed to assigned memory to NUMA node with error: %d (0x%x).", err, err ); + return false; + } + + pages += pageSize; + } + + return true; +} + +//----------------------------------------------------------- +int SysHost::NumaGetNodeFromPage( void* ptr ) +{ + // #TODO: Implement me + // PSAPI_WORKING_SET_EX_INFORMATION info; + + // BOOL r = QueryWorkingSetEx( GetCurrentProcess(), (PVOID)&info, (DWORD)GetPageSize() ); + // if( !r ) + // { + // const DWORD err = GetLastError(); + // Log::Error( "Failed to call QueryWorkingSetEx with error: %d (0x%x).", err, err ); + // } + + return -1; +} + +// #See: +// https://docs.microsoft.com/en-us/windows/win32/memory/large-page-support +// https://docs.microsoft.com/en-us/windows/win32/secauthz/enabling-and-disabling-privileges-in-c-- +// https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-adjusttokenprivileges +//----------------------------------------------------------- +bool EnableLockMemoryPrivilege() +{ + static int32 _enabledState = 0; // 0 = uninitialized, -1 = failed to enabled, 1 = enabled + if( _enabledState != 0 ) + return _enabledState == 1; + + HANDLE hProc, hToken; + hProc = GetCurrentProcess(); + + if( !OpenProcessToken( hProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) + return false; // Try again later + + TOKEN_PRIVILEGES tp; + LUID luid; + + if( !LookupPrivilegeValue( + NULL, // lookup privilege on local system + SE_LOCK_MEMORY_NAME, // privilege to lookup + &luid ) ) // receives LUID of privilege + { + goto Failed; + } + + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if( !AdjustTokenPrivileges( + hToken, + FALSE, + &tp, + sizeof( TOKEN_PRIVILEGES ), + (PTOKEN_PRIVILEGES)NULL, + (PDWORD)NULL ) ) + { + goto Failed; + } + + // Still have to check if it actually adjusted the privilege + // #See: https://devblogs.microsoft.com/oldnewthing/20211126-00/?p=105973 + DWORD r = ::GetLastError(); + if( r != ERROR_SUCCESS ) + goto Failed; + + _enabledState = 1; + return true; + +Failed: + ::CloseHandle( hToken ); + _enabledState = -1; + return false; } \ No newline at end of file diff --git a/src/platform/win32/Thread_Win32.cpp b/src/platform/win32/Thread_Win32.cpp index 3f1dde1c..82f72357 100644 --- a/src/platform/win32/Thread_Win32.cpp +++ b/src/platform/win32/Thread_Win32.cpp @@ -1,127 +1,129 @@ -#include "../../threading/Thread.h" -#include "../../Util.h" -#include "../../Globals.h" -#include "SysHost.h" -#include "util/Log.h" - -//----------------------------------------------------------- -Thread::Thread( size_t stackSize ) -{ - // Configure stack size - if( stackSize < 1024 * 4 ) - Fatal( "Thread stack size is too small." ); - - _state.store( ThreadState::ReadyToRun, std::memory_order_release ); - - _threadId = CreateThread( - NULL, - (SIZE_T)stackSize, - Thread::ThreadStarterWin, - (LPVOID)this, - CREATE_SUSPENDED, - nullptr ); - - if( _threadId == NULL ) - Fatal( "Failed to create thread." ); -} - -//----------------------------------------------------------- -Thread::Thread() : Thread( 8 MB ) {} - -//----------------------------------------------------------- -Thread::~Thread() -{ - const bool didExit = _state.load( std::memory_order_relaxed ) == ThreadState::Exited; - - if( !didExit ) - { - // Thread should have exited already, terminate it abruptly - Log::Error( "Warning: Thread did not exit properly." ); - TerminateThread( _threadId, 0 ); - } - - if( !CloseHandle( _threadId ) ) - Log::Error( "An error occurred when closing a thread." ); - - _threadId = NULL; -} - -//----------------------------------------------------------- -bool Thread::HasExited() const -{ - return _state.load( std::memory_order_relaxed ) == ThreadState::Exited; -} - -//----------------------------------------------------------- -void Thread::Run( ThreadRunner runner, void* param ) -{ - // Ensure we can actually start - ASSERT( runner ); - const bool canRun = _state.load( std::memory_order_relaxed ) == ThreadState::ReadyToRun; - - ASSERT( canRun ); - if( !canRun ) - return; - - // Change the thread state - ThreadState expected = ThreadState::ReadyToRun; - if( !_state.compare_exchange_strong( expected, ThreadState::Running, - std::memory_order_release, - std::memory_order_relaxed ) ) - { - // Another thread ran us first. - return; - } - - _runner = runner; - _runParam = param; - - // Start the thread - const DWORD r = ResumeThread( _threadId ); - if( r != 1 ) - Fatal( "Failed to resume thread %d.", _threadId ); -} - - -//----------------------------------------------------------- -void Thread::Sleep( long milliseconds ) -{ - ::Sleep( (DWORD)milliseconds ); -} - -//----------------------------------------------------------- -bool Thread::WaitForExit( long milliseconds ) -{ - ThreadState state = _state.load( std::memory_order_relaxed ); - if( state == ThreadState::Exited ) - return true; - - const DWORD r = WaitForSingleObject( _threadId, (DWORD)milliseconds ); - if( r != WAIT_TIMEOUT && r != WAIT_OBJECT_0 ) - { - Log::Error( "Thread %d wait for exit failed: %d", _threadId, GetLastError() ); - return false; - } - - return true; -} - -// Thread entry point -//----------------------------------------------------------- -DWORD Thread::ThreadStarterWin( LPVOID param ) -{ - ASSERT( param ); - - Thread* t = (Thread*)param; - ASSERT( t->_state == ThreadState::Running ); - - // Run the thread function - t->_runner( t->_runParam ); - - // Thread has exited - t->_state.store( ThreadState::Exited, std::memory_order_release ); - - // TODO: Signal if waiting to be joined - return 0; -} - +#include "threading/Thread.h" +#include "util/Util.h" +#include "Globals.h" +#include "SysHost.h" +#include "util/Log.h" +#include + + +//----------------------------------------------------------- +Thread::Thread( size_t stackSize ) +{ + // Configure stack size + if( stackSize < 1024 * 4 ) + Fatal( "Thread stack size is too small." ); + + _state.store( ThreadState::ReadyToRun, std::memory_order_release ); + + _threadId = CreateThread( + NULL, + (SIZE_T)stackSize, + (LPTHREAD_START_ROUTINE)(void*)Thread::ThreadStarterWin, + (LPVOID)this, + CREATE_SUSPENDED, + nullptr ); + + if( _threadId == NULL ) + Fatal( "Failed to create thread." ); +} + +//----------------------------------------------------------- +Thread::Thread() : Thread( 8 MB ) {} + +//----------------------------------------------------------- +Thread::~Thread() +{ + const bool didExit = _state.load( std::memory_order_relaxed ) == ThreadState::Exited; + + if( !didExit ) + { + // Thread should have exited already, terminate it abruptly + Log::Error( "Warning: Thread did not exit properly." ); + TerminateThread( _threadId, 0 ); + } + + if( !CloseHandle( _threadId ) ) + Log::Error( "An error occurred when closing a thread." ); + + _threadId = NULL; +} + +//----------------------------------------------------------- +bool Thread::HasExited() const +{ + return _state.load( std::memory_order_relaxed ) == ThreadState::Exited; +} + +//----------------------------------------------------------- +void Thread::Run( ThreadRunner runner, void* param ) +{ + // Ensure we can actually start + ASSERT( runner ); + const bool canRun = _state.load( std::memory_order_relaxed ) == ThreadState::ReadyToRun; + + ASSERT( canRun ); + if( !canRun ) + return; + + // Change the thread state + ThreadState expected = ThreadState::ReadyToRun; + if( !_state.compare_exchange_strong( expected, ThreadState::Running, + std::memory_order_release, + std::memory_order_relaxed ) ) + { + // Another thread ran us first. + return; + } + + _runner = runner; + _runParam = param; + + // Start the thread + const DWORD r = ResumeThread( _threadId ); + if( r != 1 ) + Fatal( "Failed to resume thread %d.", _threadId ); +} + + +//----------------------------------------------------------- +void Thread::Sleep( long milliseconds ) +{ + ::Sleep( (DWORD)milliseconds ); +} + +//----------------------------------------------------------- +bool Thread::WaitForExit( long milliseconds ) +{ + ThreadState state = _state.load( std::memory_order_relaxed ); + if( state == ThreadState::Exited ) + return true; + + const DWORD r = WaitForSingleObject( _threadId, (DWORD)milliseconds ); + if( r != WAIT_TIMEOUT && r != WAIT_OBJECT_0 ) + { + Log::Error( "Thread %d wait for exit failed: %d", _threadId, GetLastError() ); + return false; + } + + return true; +} + +// Thread entry point +//----------------------------------------------------------- +unsigned long Thread::ThreadStarterWin( intptr_t param ) +{ + ASSERT( param ); + + Thread* t = (Thread*)param; + ASSERT( t->_state == ThreadState::Running ); + + // Run the thread function + t->_runner( t->_runParam ); + + // Thread has exited + t->_state.store( ThreadState::Exited, std::memory_order_release ); + + // TODO: Signal if waiting to be joined + return 0; +} + diff --git a/src/plotdisk/BitBucketWriter.h b/src/plotdisk/BitBucketWriter.h new file mode 100644 index 00000000..19eec772 --- /dev/null +++ b/src/plotdisk/BitBucketWriter.h @@ -0,0 +1,185 @@ +#pragma once +#include "util/Util.h" +#include "util/BitView.h" + + +template +class BitBucketWriter +{ + struct BitBucket + { + size_t count; + byte* buffer; + }; + + DiskBufferQueue* _queue = nullptr; + uint64* _remainderFields [_numBuckets] = { nullptr }; // Left-over block buffers + uint64 _remainderBitCount[_numBuckets] = { 0 }; + BitBucket _buckets [_numBuckets] = { 0 }; + FileId _fileId = FileId::None; + +public: + + //----------------------------------------------------------- + inline BitBucketWriter() + {} + + //----------------------------------------------------------- + inline BitBucketWriter( DiskBufferQueue& queue, const FileId fileId, byte* blockBuffers ) + : _queue ( &queue ) + , _fileId ( fileId ) + { + SetBlockBuffers( blockBuffers ); + } + + //----------------------------------------------------------- + inline BitBucketWriter( const BitBucketWriter<_numBuckets>& other ) + { + memcpy( this, &other, sizeof( other ) ); + } + + //----------------------------------------------------------- + // inline BitBucketWriter( BitBucketWriter<_numBuckets>&& other ) + // { + // memcpy( this, &other, sizeof( other ) ); + // memset( *other, 0, sizeof( other )); + // } + + //----------------------------------------------------------- + inline void SetFileId( const FileId id ) { _fileId = id; } + + //----------------------------------------------------------- + inline void BeginWriteBuckets( const uint64 bucketBitSizes[_numBuckets] ) + { + const size_t fsBlockSize = _queue->BlockSize( _fileId ); + const size_t fsBlockSizeBits = fsBlockSize * 8; + ASSERT( fsBlockSize > 0 ); + + size_t allocSize = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + allocSize += CDivT( (size_t)bucketBitSizes[i] + (size_t)_remainderBitCount[i], fsBlockSizeBits ) * fsBlockSizeBits / 8; + + byte* bucketBuffers = _queue->GetBuffer( allocSize, fsBlockSize, true ); + + BeginWriteBuckets( bucketBitSizes, bucketBuffers ); + } + + //----------------------------------------------------------- + inline void BeginWriteBuckets( const uint64 bucketBitSizes[_numBuckets], byte* bucketBuffers ) + { + ASSERT( bucketBuffers ); + + const size_t fsBlockSizeBits = _queue->BlockSize( _fileId ) * 8; + ASSERT( fsBlockSizeBits > 0 ); + + // Initialize our BitWriters + byte* fields = bucketBuffers; + for( uint32 i = 0; i < _numBuckets; i++ ) + { + const uint64 leftOverBitCount = _remainderBitCount[i]; + const size_t totalBitCount = bucketBitSizes[i] + leftOverBitCount; + const size_t bufferBitCapacity = CDivT( totalBitCount, fsBlockSizeBits ) * fsBlockSizeBits; + ASSERT( bufferBitCapacity / 64 * 64 == bufferBitCapacity ); + + _buckets[i].count = totalBitCount; + _buckets[i].buffer = fields; + + if( leftOverBitCount > 0 ) + { + const uint64 nFields = CDiv( leftOverBitCount, 64 ); + memcpy( fields, _remainderFields[i], nFields * sizeof( uint64 ) ); + } + + fields += bufferBitCapacity / 8; + } + } + + //----------------------------------------------------------- + inline void Submit() + { + const size_t fsBlockSize = _queue->BlockSize( _fileId ); + const size_t fsBlockSizeBits = fsBlockSize * 8; + + // Save any overflow bits + for( uint32 i = 0; i < _numBuckets; i++ ) + { + BitBucket& bucket = _buckets[i]; + + const size_t bitCount = bucket.count; + const size_t bitsToWrite = bitCount / fsBlockSizeBits * fsBlockSizeBits; + const size_t remainderBits = bitCount - bitsToWrite; + + const size_t bytesToWrite = bitsToWrite / 8; + + ASSERT( bitsToWrite / fsBlockSizeBits * fsBlockSizeBits == bitsToWrite ); + + if( remainderBits ) + { + // Copy left-over fields + const size_t remainderFieldCount = CDiv( remainderBits, 64 ); + memcpy( _remainderFields[i], bucket.buffer + bytesToWrite, remainderFieldCount * sizeof( uint64 ) ); + } + + if( bytesToWrite ) + _queue->WriteFile( _fileId, i, bucket.buffer, bytesToWrite ); + + _remainderBitCount[i] = remainderBits; + } + _queue->CommitCommands(); + } + + //----------------------------------------------------------- + inline void SubmitAndRelease() + { + this->Submit(); + _queue->ReleaseBuffer( _buckets[0].buffer ); + _queue->CommitCommands(); + } + + //----------------------------------------------------------- + inline void SubmitLeftOvers() + { + const size_t fsBlockSize = _queue->BlockSize( _fileId ); + ASSERT( fsBlockSize ); + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + if( _remainderBitCount[i] > 0 ) + _queue->WriteFile( _fileId, i, _remainderFields[i], fsBlockSize ); + } + _queue->CommitCommands(); + } + + //----------------------------------------------------------- + inline BitWriter GetWriter( const uint32 bucket, const uint64 bitOffset ) + { + ASSERT( bucket < _numBuckets ); + + BitBucket& b = _buckets[bucket]; + return BitWriter( (uint64*)b.buffer, b.count, _remainderBitCount[bucket] + bitOffset ); + } + + //----------------------------------------------------------- + inline size_t RemainderBits( const uint32 bucket ) + { + ASSERT( bucket < _numBuckets ); + return _remainderBitCount[bucket]; + } + +private: + + //----------------------------------------------------------- + inline void SetBlockBuffers( byte* blockBuffers ) + { + const size_t fsBlockSize = _queue->BlockSize( _fileId ); + ASSERT( fsBlockSize > 0 ); + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + _remainderFields[i] = (uint64*)blockBuffers; + *_remainderFields[i] = 0; + blockBuffers += fsBlockSize; + } + } +}; diff --git a/src/plotdisk/BlockWriter.h b/src/plotdisk/BlockWriter.h new file mode 100644 index 00000000..0769ffc9 --- /dev/null +++ b/src/plotdisk/BlockWriter.h @@ -0,0 +1,91 @@ +#pragma once +#include "DiskBufferQueue.h" +#include "util/StackAllocator.h" + +template +class BlockWriter +{ +public: + //----------------------------------------------------------- + inline BlockWriter() {} + + //----------------------------------------------------------- + inline BlockWriter( IAllocator& allocator, const FileId fileId, Fence& fence, const size_t blockSize, const size_t elementCount ) + : _fileId( fileId ) + , _fence( &fence ) + { + static_assert( sizeof( T ) == 1 || ( sizeof( T ) & 1) == 0 ); + + const size_t allocSize = blockSize + RoundUpToNextBoundaryT( elementCount * sizeof( T ), blockSize ); + + // Sanity check, should never happen as block sizes are power of 2 and + // we don't expect to use this with non Po2 elements. + FatalIf( blockSize / sizeof( T ) * sizeof( T ) != blockSize, "Unexpected block size." ); + + _buffers[0] = allocator.AllocT( allocSize, blockSize ); + _buffers[1] = allocator.AllocT( allocSize, blockSize ); + + _remainder = allocator.AllocT( blockSize ); + } + + //----------------------------------------------------------- + inline T* GetNextBuffer( Duration& writeWaitTime ) + { + if( _bufferIdx > 1 ) + _fence->Wait( _bufferIdx - 2, writeWaitTime ); + + return _buffers[_bufferIdx & 1] + _remainderCount; + } + + //----------------------------------------------------------- + inline void SubmitBuffer( DiskBufferQueue& queue, const size_t elementCount ) + { + ASSERT( elementCount ); + + const size_t blockSize = queue.BlockSize( _fileId ); + const size_t elementsPerBlock = blockSize / sizeof( T ); + + T* buf = _buffers[_bufferIdx & 1]; + + if( _remainderCount ) + bbmemcpy_t( buf, _remainder, _remainderCount ); + + const size_t totalElements = _remainderCount + elementCount; + const size_t writeCount = totalElements / elementsPerBlock * elementsPerBlock; + _remainderCount = totalElements - writeCount; + + if( _remainderCount ) + bbmemcpy_t( _remainder, buf + writeCount, _remainderCount ); + + queue.WriteFile( _fileId, 0, buf, writeCount * sizeof( T ) ); + queue.SignalFence( *_fence, _bufferIdx++ ); + queue.CommitCommands(); + } + + //----------------------------------------------------------- + inline void SubmitFinalBlock( DiskBufferQueue& queue ) + { + if( _remainderCount ) + { + queue.WriteFile( _fileId, 0, _remainder, queue.BlockSize( _fileId ) ); + _remainderCount = 0; + } + + queue.SignalFence( *_fence, _bufferIdx ); + queue.CommitCommands(); + } + + //----------------------------------------------------------- + inline void WaitForFinalWrite() + { + _fence->Wait( _bufferIdx ); + } + +private: + FileId _fileId = FileId::None; + int32 _bufferIdx = 0; + T* _buffers[2] = { nullptr }; + T* _remainder = nullptr; + size_t _remainderCount = 0; // Number of elements saved in our remainder buffer + Fence* _fence = nullptr; +}; diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp new file mode 100644 index 00000000..d573ee4b --- /dev/null +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -0,0 +1,1071 @@ +#include "DiskBufferQueue.h" +#include "io/FileStream.h" +#include "io/HybridStream.h" +#include "plotdisk/DiskPlotConfig.h" +#include "plotdisk/IOTransforms.h" +#include "jobs/IOJob.h" +#include "util/Util.h" +#include "util/Log.h" + + +#define NULL_BUFFER -1 + +#ifdef _WIN32 + #define PATH_SEPA_STR "\\" + #define CheckPathSeparator( x ) ((x) == '\\' || (x) == '/') +#else + #define PATH_SEPA_STR "/" + #define CheckPathSeparator( x ) ((x) == '/') +#endif + +//----------------------------------------------------------- +DiskBufferQueue::DiskBufferQueue( + const char* workDir1, const char* workDir2, const char* plotDir, byte* workBuffer, + size_t workBufferSize, uint ioThreadCount, + int32 threadBindId +) + : _workDir1 ( workDir1 ) + , _workDir2 ( workDir2 ) + , _plotDir ( plotDir ) + , _workHeap ( workBufferSize, workBuffer ) + // , _threadPool ( ioThreadCount, ThreadPool::Mode::Fixed, true ) + , _dispatchThread() + , _deleterThread () + , _deleteSignal () + , _deleteQueue ( 128 ) + , _threadBindId ( threadBindId ) +{ + ASSERT( workDir1 ); + ASSERT( plotDir ); + + if( !workDir2 ) + workDir2 = workDir1; + + // Initialize path buffers + FatalIf( _workDir1.length() < 1, "Working directory path 1 is empty." ); + FatalIf( _workDir2.length() < 1, "Working directory path 2 is empty." ); + FatalIf( _plotDir.length() < 1, "Plot tmp directory is empty." ); + + // Add a trailing slash if we don't have one + if( !CheckPathSeparator( _workDir1.back() ) ) + _workDir1 += PATH_SEPA_STR; + if( !CheckPathSeparator( _workDir2.back() ) ) + _workDir2 += PATH_SEPA_STR; + if( !CheckPathSeparator( _plotDir.back() ) ) + _plotDir += PATH_SEPA_STR; + + const size_t workDirLen = std::max( _workDir1.length(), _workDir2.length() ); + + const size_t PLOT_FILE_LEN = sizeof( "/plot-k32-2021-08-05-18-55-77a011fc20f0003c3adcc739b615041ae56351a22b690fd854ccb6726e5f43b7.plot.tmp" ); + + _filePathBuffer = bbmalloc( workDirLen + PLOT_FILE_LEN ); // Should be enough for all our file names + _delFilePathBuffer = bbmalloc( workDirLen + PLOT_FILE_LEN ); + + // Initialize file deleter thread + _deleterThread.Run( DeleterThreadMain, this ); + + // Initialize I/O thread + _dispatchThread.Run( CommandThreadMain, this ); +} + +//----------------------------------------------------------- +DiskBufferQueue::~DiskBufferQueue() +{ + _deleterExit = true; + _deleteSignal.Signal(); + _deleterThread.WaitForExit(); + + // #TODO: Wait for command thread + + // #TODO: Delete our file sets + + free( _filePathBuffer ); + free( _delFilePathBuffer ); +} + +//----------------------------------------------------------- +size_t DiskBufferQueue::BlockSize( FileId fileId ) const +{ + ASSERT( _files[(int)fileId].files[0] ); + return _files[(int)fileId].files[0]->BlockSize(); +} + +//----------------------------------------------------------- +void DiskBufferQueue::ResetHeap( const size_t heapSize, void* heapBuffer ) +{ + _workHeap.ResetHeap( heapSize, heapBuffer ); +} + +//----------------------------------------------------------- +bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketCount ) +{ + return InitFileSet( fileId, name, bucketCount, FileSetOptions::None, nullptr ); +} + +//----------------------------------------------------------- +bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketCount, const FileSetOptions options, const FileSetInitData* optsData ) +{ + const bool isPlotFile = fileId == FileId::PLOT; + const bool useTmp2 = IsFlagSet( options, FileSetOptions::UseTemp2 ); + + const std::string& wokrDir = isPlotFile ? _plotDir : + useTmp2 ? _workDir2 : _workDir1; + memcpy( _filePathBuffer, wokrDir.c_str(), wokrDir.length() ); + + const char* pathBuffer = _filePathBuffer; + char* baseName = _filePathBuffer + wokrDir.length(); + + FileFlags flags = FileFlags::LargeFile; + if( IsFlagSet( options, FileSetOptions::DirectIO ) ) + flags |= FileFlags::NoBuffering; + + FileSet& fileSet = _files[(uint)fileId]; + ASSERT( !fileSet.files.values ); + + fileSet.name = name; + fileSet.files.values = new IStream*[bucketCount]; + fileSet.files.length = bucketCount; + fileSet.blockBuffer = nullptr; + fileSet.options = options; + + const bool isCachable = IsFlagSet( options, FileSetOptions::Cachable ) && optsData->cacheSize > 0; + ASSERT( !isCachable || optsData ); + + const size_t cacheSize = isCachable ? optsData->cacheSize / bucketCount : 0; + byte* cache = isCachable ? (byte*)optsData->cache : nullptr; + + // Ensure we don't flag it as a HybridStream if the cache happened to be 0 + if( !isCachable ) + UnSetFlag( fileSet.options, FileSetOptions::Cachable ); + + // #TODO: Try using a single file and opening multiple handles to that file as buckets... + for( uint i = 0; i < bucketCount; i++ ) + { + IStream* file = nullptr; + + if( isCachable ) + file = new HybridStream(); + else + file = new FileStream(); + + fileSet.files[i] = file; + + const FileMode fileMode = + #if _DEBUG && ( BB_DP_DBG_READ_EXISTING_F1 || BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) + !isPlotFile ? FileMode::OpenOrCreate : FileMode::Create; + #else + FileMode::Create; + #endif + + if( !isPlotFile ) + sprintf( baseName, "%s_%u.tmp", name, i ); + else + { + sprintf( baseName, "%s", name ); + + _plotFullName = pathBuffer; + _plotFullName.erase( _plotFullName.length() - 4 ); + } + + bool opened; + + if( isCachable ) + { + opened = static_cast( file )->Open( cache, cacheSize, pathBuffer, fileMode, FileAccess::ReadWrite, flags ); + cache += cacheSize; + + ASSERT( cacheSize / file->BlockSize() * file->BlockSize() == cacheSize ); + } + else + opened = static_cast( file )->Open( pathBuffer, fileMode, FileAccess::ReadWrite, flags ); + + if( !opened ) + { + // Allow plot file to fail opening + if( isPlotFile ) + { + Log::Line( "Failed to open plot file %s with error: %d.", pathBuffer, file->GetError() ); + return false; + } + + Fatal( "Failed to open temp work file @ %s with error: %d.", pathBuffer, file->GetError() ); + } + + if( i == 0 && IsFlagSet( options, FileSetOptions::DirectIO ) ) + { + // const size_t totalBlockSize = file->BlockSize() * bucketCount; + fileSet.blockBuffer = bbvirtalloc( file->BlockSize() ); + } + } + + return true; +} + +//----------------------------------------------------------- +void DiskBufferQueue::SetTransform( FileId fileId, IIOTransform& transform ) +{ + // _files[(int)fileId].transform = &transform; +} + +//----------------------------------------------------------- +void DiskBufferQueue::OpenPlotFile( const char* fileName, const byte* plotId, const byte* plotMemo, uint16 plotMemoSize ) +{ + // #TODO: fileName should not have .tmp here. + // Change that and then change InitFile to add the .tmp like the rest of the files. + ASSERT( fileName ); + ASSERT( plotId ); + ASSERT( plotMemo ); + ASSERT( plotMemoSize ); + ASSERT( _plotFullName.length() == 0 ); + + // #TODO: Retry multiple-times. + const bool didOpen = InitFileSet( FileId::PLOT, fileName, 1 ); + FatalIf( !didOpen, "Failed to open plot file." ); + + // Write plot header + const size_t headerSize = + ( sizeof( kPOSMagic ) - 1 ) + + 32 + // plot id + 1 + // k + 2 + // kFormatDescription length + ( sizeof( kFormatDescription ) - 1 ) + + 2 + // Memo length + plotMemoSize + // Memo + 80 // Table pointers + ; + + _plotHeaderSize = headerSize; + + // #TODO: Support block-aligned like in PlotWriter.cpp + if( !_plotHeaderbuffer ) + _plotHeaderbuffer = bbvirtalloc( headerSize ); + + byte* header = _plotHeaderbuffer; + + // Encode the headers + { + // Magic + byte* headerWriter = header; + memcpy( headerWriter, kPOSMagic, sizeof( kPOSMagic ) - 1 ); + headerWriter += sizeof( kPOSMagic ) - 1; + + // Plot Id + memcpy( headerWriter, plotId, 32 ); + headerWriter += 32; + + // K + *headerWriter++ = (byte)_K; + + // Format description + *((uint16*)headerWriter) = Swap16( (uint16)(sizeof( kFormatDescription ) - 1) ); + headerWriter += 2; + memcpy( headerWriter, kFormatDescription, sizeof( kFormatDescription ) - 1 ); + headerWriter += sizeof( kFormatDescription ) - 1; + + // Memo + *((uint16*)headerWriter) = Swap16( plotMemoSize ); + headerWriter += 2; + memcpy( headerWriter, plotMemo, plotMemoSize ); + headerWriter += plotMemoSize; + + // Tables will be copied at the end. + _plotTablesPointers = (uint64)(headerWriter - header); + + // Write the headers to disk + WriteFile( FileId::PLOT, 0, header, (size_t)headerSize ); + CommitCommands(); + } +} + +//----------------------------------------------------------- +void DiskBufferQueue::FinishPlot( Fence& fence ) +{ + SignalFence( fence ); + CommitCommands(); + + char* plotPath = _filePathBuffer; + char* baseName = plotPath + _plotDir.length(); + + const char* plotTmpName = _files[(int)FileId::PLOT].name; + + memcpy( plotPath, _plotDir.c_str(), _plotDir.length() ); + memcpy( baseName, plotTmpName, strlen( plotTmpName ) + 1 ); + + fence.Wait(); + CloseFileNow( FileId::PLOT, 0 ); + + const uint32 RETRY_COUNT = 10; + const long MS_WAIT_TIME = 1000; + + for( uint32 i = 0; i < RETRY_COUNT; i++ ) + { + int r = rename( plotPath, _plotFullName.c_str() ); + if( !r ) + break; + + Log::Line( "Error: Could not rename plot file with error: %d.", (int32)errno ); + + if( i+1 == RETRY_COUNT) + { + Log::Line( "Error:: Failed to to rename plot file after %u retries. Please rename manually." ); + break; + } + + Log::Line( "Retrying in %.2lf seconds...", MS_WAIT_TIME / 1000.0 ); + Thread::Sleep( MS_WAIT_TIME ); + } + + _plotFullName = ""; +} + +//----------------------------------------------------------- +void DiskBufferQueue::WriteBuckets( FileId id, const void* buckets, const uint* sizes ) +{ + Command* cmd = GetCommandObject( Command::WriteBuckets ); + cmd->buckets.sizes = sizes; + cmd->buckets.buffers = (byte*)buckets; + cmd->buckets.fileId = id; +} + +//----------------------------------------------------------- +void DiskBufferQueue::WriteBucketElements( const FileId id, const void* buckets, const size_t elementSize, const uint32* counts ) +{ + ASSERT( buckets ); + ASSERT( elementSize ); + ASSERT( counts ); + ASSERT( elementSize < std::numeric_limits::max() ); + + Command* cmd = GetCommandObject( Command::WriteBucketElements ); + cmd->bucketElements.counts = counts; + cmd->bucketElements.buffers = (byte*)buckets; + cmd->bucketElements.fileId = id; + cmd->bucketElements.elementSize = (uint32)elementSize; +} + +//----------------------------------------------------------- +void DiskBufferQueue::WriteFile( FileId id, uint bucket, const void* buffer, size_t size ) +{ + Command* cmd = GetCommandObject( Command::WriteFile ); + cmd->file.buffer = (byte*)buffer; + cmd->file.size = size; + cmd->file.fileId = id; + cmd->file.bucket = bucket; +} + +//----------------------------------------------------------- +void DiskBufferQueue::ReadFile( FileId id, uint bucket, void* dstBuffer, size_t readSize ) +{ + Command* cmd = GetCommandObject( Command::ReadFile ); + cmd->file.buffer = (byte*)dstBuffer; + cmd->file.size = readSize; + cmd->file.fileId = id; + cmd->file.bucket = bucket; +} + +//----------------------------------------------------------- +void DiskBufferQueue::SeekFile( FileId id, uint bucket, int64 offset, SeekOrigin origin ) +{ + Command* cmd = GetCommandObject( Command::SeekFile ); + cmd->seek.fileId = id; + cmd->seek.bucket = bucket; + cmd->seek.offset = offset; + cmd->seek.origin = origin; +} + +//----------------------------------------------------------- +void DiskBufferQueue::SeekBucket( FileId id, int64 offset, SeekOrigin origin ) +{ + Command* cmd = GetCommandObject( Command::SeekBucket ); + cmd->seek.fileId = id; + cmd->seek.offset = offset; + cmd->seek.origin = origin; +} + +//----------------------------------------------------------- +void DiskBufferQueue::ReleaseBuffer( void* buffer ) +{ + ASSERT( buffer ); + + Command* cmd = GetCommandObject( Command::ReleaseBuffer ); + cmd->releaseBuffer.buffer = (byte*)buffer; +} + +//----------------------------------------------------------- +void DiskBufferQueue::SignalFence( Fence& fence ) +{ + Command* cmd = GetCommandObject( Command::SignalFence ); + cmd->fence.signal = &fence; + cmd->fence.value = -1; +} + +//----------------------------------------------------------- +void DiskBufferQueue::SignalFence( Fence& fence, uint32 value ) +{ + Command* cmd = GetCommandObject( Command::SignalFence ); + cmd->fence.signal = &fence; + cmd->fence.value = (int64)value; +} + +//----------------------------------------------------------- +void DiskBufferQueue::WaitForFence( Fence& fence ) +{ + Command* cmd = GetCommandObject( Command::WaitForFence ); + cmd->fence.signal = &fence; + cmd->fence.value = -1; +} + +//----------------------------------------------------------- +void DiskBufferQueue::DeleteFile( FileId id, uint bucket ) +{ + // Log::Line( "DeleteFile( %u : %u )", id, bucket ); + Command* cmd = GetCommandObject( Command::DeleteFile ); + cmd->deleteFile.fileId = id; + cmd->deleteFile.bucket = bucket; +} + +//----------------------------------------------------------- +void DiskBufferQueue::DeleteBucket( FileId id ) +{ + // Log::Line( "DeleteBucket( %u )", id ); + // #TODO: This command must be run in another helper thread in order + // to not block while the kernel buffers are being + // cleared (when not using direct IO). Otherwise + // other commands will get blocked while a command + // we don't care about is executing. + Command* cmd = GetCommandObject( Command::DeleteBucket ); + cmd->deleteFile.fileId = id; +} + +//----------------------------------------------------------- +void DiskBufferQueue::TruncateBucket( FileId id, const ssize_t position ) +{ + Command* cmd = GetCommandObject( Command::TruncateBucket ); + cmd->truncateBucket.fileId = id; + cmd->truncateBucket.position = position; +} + +//----------------------------------------------------------- +void DiskBufferQueue::CompletePendingReleases() +{ + _workHeap.CompletePendingReleases(); +} + +//----------------------------------------------------------- +inline DiskBufferQueue::Command* DiskBufferQueue::GetCommandObject( Command::CommandType type ) +{ + Command* cmd; + while( !_commands.Write( cmd ) ) + { + Log::Line( "[DiskBufferQueue] Command buffer full. Waiting for commands." ); + auto waitTimer = TimerBegin(); + + // Block and wait until we have commands free in the buffer + _cmdConsumedSignal.Wait(); + + Log::Line( "[DiskBufferQueue] Waited %.6lf seconds for a Command to be available.", TimerEnd( waitTimer ) ); + } + + ZeroMem( cmd ); + cmd->type = type; + + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] > Snd: %s (%d)", DbgGetCommandName( type ), type ); + #endif + + return cmd; +} + +//----------------------------------------------------------- +void DiskBufferQueue::CommitCommands() +{ + //Log::Debug( "Committing %d commands.", _commands._pendingCount ); + _commands.Commit(); + _cmdReadySignal.Signal(); +} + +//----------------------------------------------------------- +void DiskBufferQueue::CommandThreadMain( DiskBufferQueue* self ) +{ + if( self->_threadBindId > -1 ) + { + const uint32 threadBindId = (uint32)self->_threadBindId; + ASSERT( threadBindId < SysHost::GetLogicalCPUCount() ); + SysHost::SetCurrentThreadAffinityCpuId( threadBindId ); + } + self->CommandMain(); +} + +//----------------------------------------------------------- +// byte* DiskBufferQueue::GetBufferForId( const FileId fileId, const uint32 bucket, const size_t size, bool blockUntilFreeBuffer ) +// { +// if( !IsFlagSet( _files[(int)fileId].options, FileSetOptions::DirectIO ) ) +// return GetBuffer( size, blockUntilFreeBuffer ); + +// const size_t blockOffset = _files[(int)fileId].blockOffsets[bucket]; +// const size_t blockSize = _files[(int)fileId].files[bucket]->BlockSize(); + +// size_t allocSize = RoundUpToNextBoundaryT( size, blockOffset ); +// if( blockOffset > 0 ) +// allocSize += blockSize; + +// byte* buffer = _workHeap.Alloc( allocSize, blockSize, blockUntilFreeBuffer, &_ioBufferWaitTime ); +// buffer += blockOffset; + +// return buffer; +// } + + +/// +/// Command Thread +/// + +//----------------------------------------------------------- +void DiskBufferQueue::CommandMain() +{ + const int CMD_BUF_SIZE = 64; + Command commands[CMD_BUF_SIZE]; + + for( ;; ) + { + _cmdReadySignal.Wait(); + + int cmdCount; + while( ( ( cmdCount = _commands.Dequeue( commands, CMD_BUF_SIZE ) ) ) ) + { + _cmdConsumedSignal.Signal(); + + for( int i = 0; i < cmdCount; i++ ) + ExecuteCommand( commands[i] ); + } + } +} + +//----------------------------------------------------------- +void DiskBufferQueue::ExecuteCommand( Command& cmd ) +{ + //#if DBG_LOG_ENABLE + // Log::Debug( "[DiskBufferQueue] ^ Cmd Execute: %s (%d)", DbgGetCommandName( cmd.type ), cmd.type ); + //#endif + + switch( cmd.type ) + { + case Command::WriteBuckets: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd WriteBuckets: (%u) addr:0x%p", cmd.buckets.fileId, cmd.buckets.buffers ); + #endif + CmdWriteBuckets( cmd ); + break; + + case Command::WriteFile: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd WriteFile: (%u) bucket:%u sz:%llu addr:0x%p", cmd.file.fileId, cmd.file.bucket, cmd.file.size, cmd.file.buffer ); + #endif + CndWriteFile( cmd ); + break; + + case Command::ReadFile: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd ReadFile: (%u) bucket:%u sz:%llu addr:0x%p", cmd.file.fileId, cmd.file.bucket, cmd.file.size, cmd.file.buffer ); + #endif + CmdReadFile( cmd ); + break; + + case Command::SeekFile: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd SeekFile: (%u) bucket:%u offset:%lld origin:%ld", cmd.seek.fileId, cmd.seek.bucket, cmd.seek.offset, (int)cmd.seek.origin ); + #endif + if( !_files[(uint)cmd.seek.fileId].files[cmd.seek.bucket]->Seek( cmd.seek.offset, cmd.seek.origin ) ) + { + int err = _files[(uint)cmd.seek.fileId].files[cmd.seek.bucket]->GetError(); + Fatal( "[DiskBufferQueue] Failed to seek file %s.%u with error %d (0x%x)", + _files[(uint)cmd.seek.fileId].name, cmd.seek.bucket, err, err ); + } + break; + + case Command::SeekBucket: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd SeekBucket: (%u) offset:%lld origin:%ld", cmd.seek.fileId, cmd.seek.offset, (int)cmd.seek.origin ); + #endif + + CmdSeekBucket( cmd ); + break; + + case Command::ReleaseBuffer: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd ReleaseBuffer: 0x%p", cmd.releaseBuffer.buffer ); + #endif + _workHeap.Release( cmd.releaseBuffer.buffer ); + break; + + case Command::SignalFence: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd MemoryFence" ); + #endif + ASSERT( cmd.fence.signal ); + if( cmd.fence.value < 0 ) + cmd.fence.signal->Signal(); + else + cmd.fence.signal->Signal( (uint32)cmd.fence.value ); + break; + + case Command::WaitForFence: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd WaitForFence" ); + #endif + ASSERT( cmd.fence.signal ); + cmd.fence.signal->Wait(); + break; + + case Command::DeleteFile: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd DeleteFile" ); + #endif + CmdDeleteFile( cmd ); // Dispatch to deleter thread + break; + + case Command::DeleteBucket: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd DeleteBucket" ); + #endif + CmdDeleteBucket( cmd ); // Dispatch to deleter thread + break; + + case Command::TruncateBucket: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd TruncateBucket" ); + #endif + CmdTruncateBucket( cmd ); + break; + + + default: + ASSERT( 0 ); + break; + } +} + +//----------------------------------------------------------- +void DiskBufferQueue::CmdWriteBuckets( const Command& cmd ) +{ + const FileId fileId = cmd.buckets.fileId; + const uint* sizes = cmd.buckets.sizes; + const byte* buffers = cmd.buckets.buffers; + + FileSet& fileSet = _files[(int)fileId]; + // ASSERT( IsFlagSet( fileBuckets.files[0]->GetFileAccess(), FileAccess::ReadWrite ) ); + + const uint32 bucketCount = (uint32)fileSet.files.length; + + Log::Debug( " >>> Write 0x%p", buffers ); + + // Single-threaded for now... We don't have file handles for all the threads yet! + #if _DEBUG + const size_t blockSize = _blockSize; + #endif + + const byte* buffer = buffers; + + // if( fileSet.transform ) + // { + // IIOTransform::TransformData data = { + // .buffer = (void*)buffers, + // .numBuckets = bucketCount, + // .bucketSizes = (uint32*)sizes + // }; + + // // #TODO: Profile time elapsed here + // fileSet.transform->Write( data ); + // } + + + for( uint i = 0; i < bucketCount; i++ ) + { + const size_t bufferSize = sizes[i]; + + // Only write up-to the block-aligned boundary. The caller is in charge of handling unlaigned data. + ASSERT( bufferSize == bufferSize / blockSize * blockSize ); + WriteToFile( *fileSet.files[i], bufferSize, buffer, (byte*)fileSet.blockBuffer, fileSet.name, i ); + + // ASSERT( IsFlagSet( fileBuckets.files[i].GetFileAccess(), FileAccess::ReadWrite ) ); + buffer += bufferSize; + } +} + +//----------------------------------------------------------- +void DiskBufferQueue::CndWriteFile( const Command& cmd ) +{ + FileSet& fileBuckets = _files[(int)cmd.file.fileId]; + WriteToFile( *fileBuckets.files[cmd.file.bucket], cmd.file.size, cmd.file.buffer, (byte*)fileBuckets.blockBuffer, fileBuckets.name, cmd.file.bucket ); +} + +//----------------------------------------------------------- +void DiskBufferQueue::CmdReadFile( const Command& cmd ) +{ + FileSet& fileSet = _files[(int)cmd.file.fileId]; + const bool directIO = IsFlagSet( fileSet.options, FileSetOptions::DirectIO ); + const size_t blockSize = fileSet.files[0]->BlockSize(); + + ReadFromFile( *fileSet.files[cmd.file.bucket], cmd.file.size, cmd.file.buffer, (byte*)fileSet.blockBuffer, blockSize, directIO, fileSet.name, cmd.file.bucket ); +} + +//----------------------------------------------------------- +void DiskBufferQueue::CmdSeekBucket( const Command& cmd ) +{ + FileSet& fileBuckets = _files[(int)cmd.seek.fileId]; + const uint bucketCount = (uint)fileBuckets.files.length; + + const int64 seekOffset = cmd.seek.offset; + const SeekOrigin seekOrigin = cmd.seek.origin; + + for( uint i = 0; i < bucketCount; i++ ) + { + if( !fileBuckets.files[i]->Seek( seekOffset, seekOrigin ) ) + { + int err = fileBuckets.files[i]->GetError(); + Fatal( "[DiskBufferQueue] Failed to seek file %s.%u with error %d (0x%x)", fileBuckets.name, i, err, err ); + } + } +} + +//----------------------------------------------------------- +inline void DiskBufferQueue::WriteToFile( IStream& file, size_t size, const byte* buffer, byte* blockBuffer, const char* fileName, uint bucket ) +{ + // if( !_useDirectIO ) + // { + #if BB_IO_METRICS_ON + _writeMetrics.size += size; + _writeMetrics.count++; + const auto timer = TimerBegin(); + #endif + + while( size ) + { + + ssize_t sizeWritten = file.Write( buffer, size ); + + + if( sizeWritten < 1 ) + { + const int err = file.GetError(); + Fatal( "Failed to write to '%s.%u' work file with error %d (0x%x).", fileName, bucket, err, err ); + } + + size -= (size_t)sizeWritten; + buffer += sizeWritten; + } + + #if BB_IO_METRICS_ON + _writeMetrics.time += TimerEndTicks( timer ); + #endif + // } + // else + // { + // ASSERT() + // const size_t blockSize = _blockSize; + // size_t sizeToWrite = size / blockSize * blockSize; + // const size_t remainder = size - sizeToWrite; + + // while( sizeToWrite ) + // { + // ssize_t sizeWritten = file.Write( buffer, sizeToWrite ); + // if( sizeWritten < 1 ) + // { + // const int err = file.GetError(); + // Fatal( "Failed to write to '%s.%u' work file with error %d (0x%x).", fileName, bucket, err, err ); + // } + + // ASSERT( sizeWritten <= (ssize_t)sizeToWrite ); + + // sizeToWrite -= (size_t)sizeWritten; + // buffer += sizeWritten; + // } + + // if( remainder ) + // { + // ASSERT( blockBuffer ); + + // // Unnecessary zeroing of memory, but might be useful for debugging + // memset( blockBuffer, 0, blockSize ); + // memcpy( blockBuffer, buffer, remainder ); + + // ssize_t sizeWritten = file.Write( blockBuffer, blockSize ); + + // if( sizeWritten < remainder ) + // { + // const int err = file.GetError(); + // Fatal( "Failed to write block to '%s.%u' work file with error %d (0x%x).", fileName, bucket, err, err ); + // } + // } + // } +} + +//----------------------------------------------------------- +inline void DiskBufferQueue::ReadFromFile( IStream& file, size_t size, byte* buffer, byte* blockBuffer, const size_t blockSize, const bool directIO, const char* fileName, const uint bucket ) +{ + #if BB_IO_METRICS_ON + _readMetrics.size += size; + _readMetrics.count++; + const auto timer = TimerBegin(); + #endif + + if( !directIO ) + { + while( size ) + { + const ssize_t sizeRead = file.Read( buffer, size ); + if( sizeRead < 1 ) + { + const int err = file.GetError(); + Fatal( "Failed to read from '%s_%u' work file with error %d (0x%x).", fileName, bucket, err, err ); + } + + size -= (size_t)sizeRead; + buffer += sizeRead; + } + } + else + { + int err; + FatalIf( !IOJob::ReadFromFile( file, buffer, size, blockBuffer, blockSize, err ), + "Failed to read from '%s_%u' work file with error %d (0x%x).", fileName, bucket, err, err ); + + + // const size_t blockSize = _blockSize; + + // /// #NOTE: All our buffers should be block aligned so we should be able to freely read all blocks to them... + // /// Only implement remainder block reading if we really need to. + // // size_t sizeToRead = size / blockSize * blockSize; + // // const size_t remainder = size - sizeToRead; + + // size_t sizeToRead = CDivT( size, blockSize ) * blockSize; + + // while( sizeToRead ) + // { + // ssize_t sizeRead = file.Read( buffer, sizeToRead ); + // if( sizeRead < 1 ) + // { + // const int err = file.GetError(); + // Fatal( "Failed to read from '%s_%u' work file with error %d (0x%x).", fileName, bucket, err, err ); + // } + + // ASSERT( sizeRead <= (ssize_t)sizeToRead ); + + // sizeToRead -= (size_t)sizeRead; + // buffer += sizeRead; + // } + } + + #if BB_IO_METRICS_ON + _readMetrics.time += TimerEndTicks( timer ); + #endif + +// if( remainder ) +// { +// ASSERT( blockBuffer ); +// +// file.read +// } +} + +//---------------------------------------------------------- +void DiskBufferQueue::CmdDeleteFile( const Command& cmd ) +{ + DeleteFileNow( cmd.deleteFile.fileId, cmd.deleteFile.bucket ); + + // FileDeleteCommand delCmd; + // delCmd.fileId = cmd.deleteFile.fileId; + // delCmd.bucket = (int64)cmd.deleteFile.bucket; + // while( !_deleteQueue.Enqueue( delCmd ) ); + + // _deleteSignal.Signal(); +} + +//---------------------------------------------------------- +void DiskBufferQueue::CmdDeleteBucket( const Command& cmd ) +{ + DeleteBucketNow( cmd.deleteFile.fileId ); + + // FileDeleteCommand delCmd; + // delCmd.fileId = cmd.deleteFile.fileId; + // delCmd.bucket = -1; + // while( !_deleteQueue.Enqueue( delCmd ) ); + + // _deleteSignal.Signal(); +} + +//----------------------------------------------------------- +void DiskBufferQueue::CmdTruncateBucket( const Command& cmd ) +{ + const auto& tcmd = cmd.truncateBucket; + + FileSet& files = _files[(int)tcmd.fileId]; + + for( size_t i = 0; i < files.files.Length(); i++ ) + { + const bool r = files.files[i]->Truncate( tcmd.position ); + if( !r ) + { + ASSERT( 0 ); + Log::Line( "Warning: Failed to truncate file %s:%llu", files.name, (uint64)i ); + } + } +} + +//----------------------------------------------------------- +inline const char* DiskBufferQueue::DbgGetCommandName( Command::CommandType type ) +{ + switch( type ) + { + case DiskBufferQueue::Command::WriteFile: + return "WriteFile"; + + case DiskBufferQueue::Command::WriteBuckets: + return "WriteBuckets"; + + case DiskBufferQueue::Command::ReadFile: + return "ReadFile"; + + case DiskBufferQueue::Command::ReleaseBuffer: + return "ReleaseBuffer"; + + case DiskBufferQueue::Command::SeekFile: + return "SeekFile"; + + case DiskBufferQueue::Command::SeekBucket: + return "SeekBucket"; + + case DiskBufferQueue::Command::SignalFence: + return "SignalFence"; + + case DiskBufferQueue::Command::WaitForFence: + return "WaitForFence"; + + case DiskBufferQueue::Command::DeleteFile: + return "DeleteFile"; + + case DiskBufferQueue::Command::DeleteBucket: + return "DeleteBucket"; + + case DiskBufferQueue::Command::TruncateBucket: + return "TruncateBucket"; + + default: + ASSERT( 0 ); + return nullptr; + } +} + + +/// +/// File-Deleter Thread +/// +//----------------------------------------------------------- +void DiskBufferQueue::DeleterThreadMain( DiskBufferQueue* self ) +{ + self->DeleterMain(); +} + +//----------------------------------------------------------- +void DiskBufferQueue::DeleterMain() +{ + const int BUFFER_SIZE = 1024; + FileDeleteCommand commands[BUFFER_SIZE]; + + for( ;; ) + { + _deleteSignal.Wait(); + + // Keep grabbing commands until there's none more + for( ;; ) + { + const int count = _deleteQueue.Dequeue( commands, BUFFER_SIZE ); + + if( count == 0 ) + { + if( _deleterExit ) + return; + + break; + } + + for( int i = 0; i < count; i++ ) + { + auto& cmd = commands[i]; + + if( cmd.bucket < 0 ) + DeleteBucketNow( cmd.fileId ); + else + DeleteFileNow( cmd.fileId, (uint32)cmd.bucket ); + } + } + } +} + +//----------------------------------------------------------- +inline void DiskBufferQueue::CloseFileNow( const FileId fileId, const uint32 bucket ) +{ + FileSet& fileSet = _files[(int)fileId]; + + // NOTE: Why are we doing it this way?? Just add Close() to IStream. + const bool isHybridFile = IsFlagSet( fileSet.options, FileSetOptions::Cachable ); + if( isHybridFile ) + { + auto* file = static_cast( fileSet.files[bucket] ); + file->Close(); + } + else + { + auto* file = static_cast( fileSet.files[bucket] ); + file->Close(); + } +} + +//----------------------------------------------------------- +void DiskBufferQueue::DeleteFileNow( const FileId fileId, const uint32 bucket ) +{ + FileSet& fileSet = _files[(int)fileId]; + + CloseFileNow( fileId, bucket ); + + const bool useTmp2 = IsFlagSet( fileSet.options, FileSetOptions::UseTemp2 ); + + const std::string& wokrDir = useTmp2 ? _workDir2 : _workDir1; + char* filePath = _delFilePathBuffer; + + memcpy( filePath, wokrDir.c_str(), wokrDir.length() ); + char* baseName = filePath + wokrDir.length(); + + sprintf( baseName, "%s_%u.tmp", fileSet.name, bucket ); + + const int r = remove( filePath ); + + if( r ) + Log::Error( "Error: Failed to delete file %s with errror %d (0x%x).", filePath, r, r ); +} + +//----------------------------------------------------------- +void DiskBufferQueue::DeleteBucketNow( const FileId fileId ) +{ + FileSet& fileSet = _files[(int)fileId]; + + const bool useTmp2 = IsFlagSet( fileSet.options, FileSetOptions::UseTemp2 ); + + const std::string& wokrDir = useTmp2 ? _workDir2 : _workDir1; + char* filePath = _delFilePathBuffer; + + memcpy( filePath, wokrDir.c_str(), wokrDir.length() ); + char* baseName = filePath + wokrDir.length(); + + for( size_t i = 0; i < fileSet.files.length; i++ ) + { + CloseFileNow( fileId, (uint32)i ); + + sprintf( baseName, "%s_%u.tmp", fileSet.name, (uint)i ); + + const int r = remove( filePath ); + + if( r ) + Log::Error( "Error: Failed to delete file %s with errror %d (0x%x).", filePath, r, r ); + } +} + diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h new file mode 100644 index 00000000..0ad4b587 --- /dev/null +++ b/src/plotdisk/DiskBufferQueue.h @@ -0,0 +1,357 @@ +#pragma once + +#include "io/IStream.h" +#include "threading/Fence.h" +#include "threading/ThreadPool.h" +#include "threading/MTJob.h" +#include "plotting/WorkHeap.h" +#include "plotting/Tables.h" +#include "FileId.h" + +class Thread; +class IIOTransform; + +enum FileSetOptions +{ + None = 0, + DirectIO = 1 << 0, // Use direct IO/unbuffered file IO + Cachable = 1 << 1, // Use a in-memory cache for the file + UseTemp2 = 1 << 2, // Open the file set the high-frequency temp directory + + Interleaved = 1 << 3, // Alternate bucket slices between interleaved and non-interleaved + BlockAlign = 1 << 4, // Only write in block-aligned segments. Keeping a block-sized buffer for left overs. + // The last write flushes the whole block. + // This can be very memory-costly on file systems with large block sizes + // as interleaved buckets will need many block buffers. + // This must be used with DirectIO. +}; +ImplementFlagOps( FileSetOptions ); + +struct FileSetInitData +{ + // Cachable + void* cache = nullptr; // Cache buffer + size_t cacheSize = 0; // Cache size in bytes + + // Interleaved + size_t sliceSize = 0; // Maximum size of a bucket slice +}; + +struct FileSet +{ + const char* name = nullptr; + Span files; + void* blockBuffer = nullptr; // For FileSetOptions::BlockAlign + size_t sliceCapacity = 0; // (in bytes) For FileSetOptions::Interleaved + FileSetOptions options = FileSetOptions::None; +}; + +class DiskBufferQueue +{ + struct Command + { + enum CommandType + { + Void = 0, + WriteFile, + WriteBuckets, + WriteBucketElements, + ReadFile, + SeekFile, + SeekBucket, + DeleteFile, + DeleteBucket, + ReleaseBuffer, + SignalFence, + WaitForFence, + TruncateBucket, + }; + + CommandType type; + + union + { + struct + { + byte* buffer; + size_t size; + FileId fileId; + uint bucket; + } file; + + struct + { + const uint* sizes; + const byte* buffers; + FileId fileId; + } buckets; + + // Same as buckets, but written with element sizes instead + struct + { + const uint* counts; + const byte* buffers; + FileId fileId; + uint32 elementSize; + } bucketElements; + + struct + { + FileId fileId; + uint bucket; + int64 offset; + SeekOrigin origin; + + } seek; + + struct + { + byte* buffer; + } releaseBuffer; + + struct + { + Fence* signal; + int64 value; + } fence; + + struct + { + FileId fileId; + uint bucket; + } deleteFile; + + struct + { + FileId fileId; + ssize_t position; + } truncateBucket; + }; + }; + + struct FileDeleteCommand + { + FileId fileId; + int64 bucket; // If < 0, delete all buckets + }; + +#if BB_IO_METRICS_ON +public: + struct IOMetric + { + size_t size; + Duration time; + size_t count; + }; +#endif + +public: + DiskBufferQueue( const char* workDir1, const char* workDir2, const char* plotDir, + byte* workBuffer, size_t workBufferSize, uint ioThreadCount, + int32 threadBindId = -1 ); + + ~DiskBufferQueue(); + + bool InitFileSet( FileId fileId, const char* name, uint bucketCount, const FileSetOptions options, const FileSetInitData* optsData ); + + bool InitFileSet( FileId fileId, const char* name, uint bucketCount ); + + void SetTransform( FileId fileId, IIOTransform& transform ); + + void OpenPlotFile( const char* fileName, const byte* plotId, const byte* plotMemo, uint16 plotMemoSize ); + +/// Commands + void FinishPlot( Fence& fence ); + + void ResetHeap( const size_t heapSize, void* heapBuffer ); + + void WriteBuckets( FileId id, const void* buckets, const uint* sizes ); + + void WriteBucketElements( const FileId id, const void* buckets, const size_t elementSize, const uint32* counts ); + + template + void WriteBucketElementsT( const FileId id, const T* buckets, const uint32* counts ); + + void WriteFile( FileId id, uint bucket, const void* buffer, size_t size ); + + void ReadFile( FileId id, uint bucket, void* dstBuffer, size_t readSize ); + + void SeekFile( FileId id, uint bucket, int64 offset, SeekOrigin origin ); + + void SeekBucket( FileId id, int64 offset, SeekOrigin origin ); + + void DeleteFile( FileId id, uint bucket ); + + void DeleteBucket( FileId id ); + + void TruncateBucket( FileId id, const ssize_t position ); + + // Add a memory fence into the command stream. + // The signal will be set once this command is reached. + // This ensures the caller that all commands before the + // fence have been processed. + void SignalFence( Fence& fence ); + + // Signal a fence with a specific value. + void SignalFence( Fence& fence, uint32 value ); + + // Instructs the command dispatch thread to wait until the specified fence has been signalled + void WaitForFence( Fence& fence ); + + void CommitCommands(); + +// Helpers + // Obtain a buffer allocated from the work heap. + // May block until there's a buffer available if there was none. + // This assumes a single consumer. + inline byte* GetBuffer( size_t size, bool blockUntilFreeBuffer = true ) + { + return _workHeap.Alloc( size, 1 /*_blockSize*/, blockUntilFreeBuffer, &_ioBufferWaitTime ); + } + + inline byte* GetBuffer( const size_t size, const size_t alignment, bool blockUntilFreeBuffer = true ) + { + return _workHeap.Alloc( size, alignment, blockUntilFreeBuffer, &_ioBufferWaitTime ); + } + + // byte* GetBufferForId( const FileId fileId, const uint32 bucket, const size_t size, bool blockUntilFreeBuffer = true ); + + // Release/return a chunk buffer that was in use, gotten by GetBuffer() + // These returns the buffer back to the queue so that it is in use. + // This command is serialized and should be added after + // any writing/reading has finished with said buffer + void ReleaseBuffer( void* buffer ); + + void CompletePendingReleases(); + + inline size_t BlockSize() const { return _blockSize; } + size_t BlockSize( FileId fileId ) const; + + inline const WorkHeap& Heap() const { return _workHeap; } + + inline size_t PlotHeaderSize() const { return _plotHeaderSize; } + + inline uint64 PlotTablePointersAddress() const { return _plotTablesPointers; } + + inline double IOBufferWaitTime() const { return TicksToSeconds( _ioBufferWaitTime ); } + inline void ResetIOBufferWaitCounter() { _ioBufferWaitTime = Duration::zero(); } + + + #if BB_IO_METRICS_ON + //----------------------------------------------------------- + inline const IOMetric& GetReadMetrics() const { return _readMetrics; } + inline const IOMetric& GetWriteMetrics() const { return _writeMetrics;} + + //----------------------------------------------------------- + inline double GetAverageReadThroughput() const + { + const double elapsed = TicksToSeconds( _readMetrics.time ) / (double)_readMetrics.count; + const double throughput = (double)_readMetrics.size / (double)_readMetrics.count / elapsed; + return throughput; + } + + //----------------------------------------------------------- + inline double GetAverageWriteThroughput() const + { + const double elapsed = TicksToSeconds( _writeMetrics.time ) / (double)_writeMetrics.count; + const double throughput = (double)_writeMetrics.size / (double)_writeMetrics.count / elapsed; + return throughput; + } + + //----------------------------------------------------------- + inline void ClearReadMetrics() + { + _readMetrics = {}; + } + + //----------------------------------------------------------- + inline void ClearWriteMetrics() + { + _writeMetrics = {}; + } + #endif + +private: + + Command* GetCommandObject( Command::CommandType type ); + + static void CommandThreadMain( DiskBufferQueue* self ); + void CommandMain(); + + static void DeleterThreadMain( DiskBufferQueue* self ); + void DeleterMain(); + + void ExecuteCommand( Command& cmd ); + + void CmdWriteBuckets( const Command& cmd ); + void CndWriteFile( const Command& cmd ); + void CmdReadFile( const Command& cmd ); + void CmdSeekBucket( const Command& cmd ); + + void WriteToFile( IStream& file, size_t size, const byte* buffer, byte* blockBuffer, const char* fileName, uint bucket ); + void ReadFromFile( IStream& file, size_t size, byte* buffer, byte* blockBuffer, const size_t blockSize, const bool directIO, const char* fileName, const uint bucket ); + + void CmdDeleteFile( const Command& cmd ); + void CmdDeleteBucket( const Command& cmd ); + + void CmdTruncateBucket( const Command& cmd ); + + void CloseFileNow( const FileId fileId, const uint32 bucket ); + void DeleteFileNow( const FileId fileId, const uint32 bucket ); + void DeleteBucketNow( const FileId fileId ); + + static const char* DbgGetCommandName( Command::CommandType type ); + + +private: + std::string _workDir1; // Temporary 1 directory in which we will store our long-lived temporary files + std::string _workDir2; // Temporary 2 directory in which we will store our short-live, high-req I/O temporary files + std::string _plotDir; // Temporary plot directory + std::string _plotFullName; // Full path of the plot file without '.tmp' + + WorkHeap _workHeap; // Reserved memory for performing plot work and I/O // #TODO: Remove this + + // Handles to all files needed to create a plot + FileSet _files[(size_t)FileId::_COUNT]; + size_t _blockSize = 0; + + char* _filePathBuffer = nullptr; // For creating file sets + + size_t _plotHeaderSize = 0; + byte* _plotHeaderbuffer = nullptr; + uint64 _plotTablesPointers = 0; // Offset in the plot file to the tables pointer table + + Duration _ioBufferWaitTime = Duration::zero(); // Total time spent waiting for IO buffers. + + // I/O thread stuff + Thread _dispatchThread; + + SPCQueue _commands; + + // ThreadPool _threadPool; + + AutoResetSignal _cmdReadySignal; + AutoResetSignal _cmdConsumedSignal; + + // File deleter thread + Thread _deleterThread; // For deleting files. + AutoResetSignal _deleteSignal; // We do this in a separate thread as to not + GrowableSPCQueue _deleteQueue; // block other commands when the kernel is clearing cached IO buffers for the files. + char* _delFilePathBuffer = nullptr; // For deleting file sets + bool _deleterExit = false; + int32 _threadBindId; + +#if BB_IO_METRICS_ON + IOMetric _readMetrics = {}; + IOMetric _writeMetrics = {}; +#endif +}; + + +//----------------------------------------------------------- +template +inline void DiskBufferQueue::WriteBucketElementsT( const FileId id, const T* buckets, const uint32* counts ) +{ + WriteBucketElements( id, (void*)buckets, sizeof( T ), counts ); +} + diff --git a/src/plotdisk/DiskF1.h b/src/plotdisk/DiskF1.h new file mode 100644 index 00000000..a63e81d1 --- /dev/null +++ b/src/plotdisk/DiskF1.h @@ -0,0 +1,229 @@ +#pragma once +#include "util/Util.h" +#include "plotdisk/DiskPlotInfo.h" +#include "plotdisk/DiskPlotContext.h" +#include "plotdisk/DiskPlotConfig.h" +#include "plotdisk/DiskBufferQueue.h" +#include "plotting/PlotTools.h" +#include "pos/chacha8.h" +#include "threading/MTJob.h" +#include "BitBucketWriter.h" +#include "util/StackAllocator.h" + +template +struct DiskF1 +{ + using Info = DiskPlotInfo; + + static constexpr uint32 _k = _K; + static constexpr int64 _entriesPerBucket = (int64)(( 1ull << _k ) / _numBuckets ); + + //----------------------------------------------------------- + inline DiskF1( DiskPlotContext& context, const FileId fileId ) + : _context( context ) + , _entriesPerThread( _entriesPerBucket / (int64)context.f1ThreadCount ) + { + DiskBufferQueue& ioQueue = *context.ioQueue; + + const uint32 threadCount = context.f1ThreadCount; + const uint32 entriesPerBlock = kF1BlockSizeBits / _k; + const uint64 blocksPerThread = CDiv( _entriesPerThread, entriesPerBlock ) + 1; // +1 because we might start at an entry which is not the first entry of a block + const size_t entryAllocCount = blocksPerThread * entriesPerBlock; + + // Alloc our data from the heap + byte* fxBlocks = nullptr; + + StackAllocator stack( context.heapBuffer, context.heapSize ); + fxBlocks = (byte*)stack.Alloc( _numBuckets * context.tmp2BlockSize, context.tmp2BlockSize ); + _blocks[0] = stack.CAlloc( entryAllocCount * threadCount ); + _entries = stack.CAlloc( entryAllocCount * threadCount ); + + for( uint32 i = 1; i < threadCount; i++ ) + _blocks[i] = _blocks[i-1] + entryAllocCount; + + _bitWriter = BitBucketWriter<_numBuckets>( *context.ioQueue, fileId, fxBlocks ); + + Log::Line( "F1 working heap @ %u buckets: %.2lf / %.2lf MiB", + _numBuckets, (double)stack.Size() BtoMB, (double)context.heapSize BtoMB ); + + // Must have at least n bits left + const size_t ioBitsPerBucket = RoundUpToNextBoundary( Info::EntrySizePackedBits * entryAllocCount * threadCount, 64u ); + const size_t ioBytesPerBucket = ioBitsPerBucket / 8; + + Log::Line( "Minimum IO buffer size required per bucket @ %u buckets: %.2lf MiB", + _numBuckets, (double)ioBytesPerBucket BtoMB ); + + Log::Line( "F1 IO size @ %u buckets: %.2lf MiB", + _numBuckets, (double)stack.Remainder() BtoMB ); + + FatalIf( stack.Remainder() < ioBitsPerBucket, "Not enough IO reserve size." ); + + ioQueue.ResetHeap( stack.Remainder(), stack.Top() ); + } + + //----------------------------------------------------------- + inline void GenF1() + { + using Job = AnonPrefixSumJob; + Job::Run( *_context.threadPool, _context.f1ThreadCount, [=]( Job* self ) { + + const uint32 threadCount = self->JobCount(); + const uint32 id = self->JobId(); + const uint32 kMinusKExtraBits = _k - kExtraBits; + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 bucketBitShift = _k - bucketBits; + const int32 entriesPerBlock = kF1BlockSizeBits / (int32)_k; + const size_t entrySizeBits = Info::YBitSize + _k; // y + x + + uint32* blocks = _blocks[id]; + uint64* entries = _entries; + + const int64 trailingEntries = ( 1ll << _k ) - _entriesPerBucket * _numBuckets; + + byte key[BB_PLOT_ID_LEN] = { 1 }; + memcpy( key + 1, _context.plotId, BB_PLOT_ID_LEN-1 ); + + chacha8_ctx chacha; + chacha8_keysetup( &chacha, key, 256, NULL ); + + auto& bitWriter = _bitWriter; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + int64 entriesPerThread = _entriesPerThread; + uint64 x = (uint64)_entriesPerBucket * bucket + (uint64)entriesPerThread * id; // Esure this is set before we update entriesPerThread on the last job + + // Last thread grabs trailing entries + if( self->IsLastThread() ) + { + entriesPerThread += _entriesPerBucket - entriesPerThread * (int64)threadCount; + + if( bucket + 1 == _numBuckets ) + { + // #TODO: Spread across threads instead + entriesPerThread += trailingEntries; + } + } + + const uint64 chachaBlock = x / entriesPerBlock; + const uint64 blockCount = ( x + entriesPerThread ) / entriesPerBlock - chachaBlock + 1; + + // ChaCha gen + chacha8_get_keystream( &chacha, chachaBlock, (uint32)blockCount, (byte*)blocks ); + + const uint32* yBlocks = blocks + (x - chachaBlock * entriesPerBlock); + + // Distribue to buckets + uint64 counts [_numBuckets]; + uint64 pfxSum [_numBuckets]; + uint64 totalCounts[_numBuckets]; + + memset( counts, 0, sizeof( counts ) ); + for( int64 i = 0; i < entriesPerThread; i++ ) + counts[Swap32( yBlocks[i] ) >> bucketBitShift] ++; + + self->CalculatePrefixSum( _numBuckets, counts, pfxSum, totalCounts ); + + if( self->IsControlThread() ) + { + self->LockThreads(); + + for( uint32 i = 0; i < _numBuckets; i++ ) + _context.bucketCounts[0][i] += (uint32)totalCounts[i]; + + // Convert counts to bit sizes + for( uint32 i = 0; i < _numBuckets; i++ ) + totalCounts[i] *= entrySizeBits; + + _sharedTotalCounts = totalCounts; + + bitWriter.BeginWriteBuckets( totalCounts ); + self->ReleaseThreads(); + } + else + { + self->WaitForRelease(); + } + + const uint32 yBits = Info::YBitSize; + const uint64 yMask = ( 1ull << yBits ) - 1; + + for( int64 i = 0; i < entriesPerThread; i++ ) + { + uint64 y = Swap32( yBlocks[i] ); + const uint64 dst = --pfxSum[y >> bucketBitShift]; + + const uint64 xi = ( x + (uint64)i ); // Store bit-compressed already + + y = ( ( y << kExtraBits ) | ( xi >> kMinusKExtraBits ) ) & yMask; + entries[dst] = ( xi << yBits ) | y; + } + + + // Bit-compress each bucket + uint64 bitsWritten = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + const uint64 offset = pfxSum[i]; + const uint64 bitOffset = offset * entrySizeBits - bitsWritten; + bitsWritten += _sharedTotalCounts[i]; + + ASSERT( bitOffset + counts[i] * entrySizeBits <= _sharedTotalCounts[i] ); + + BitWriter writer = bitWriter.GetWriter( i, bitOffset ); + + const uint64* entry = entries + offset; + const uint64* end = entry + counts[i]; + ASSERT( counts[i] >= 2 ); + + // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields + writer.Write( entry[0], entrySizeBits ); + writer.Write( entry[1], entrySizeBits ); + entry += 2; + + self->SyncThreads(); + + while( entry < end ) + { + writer.Write( *entry, entrySizeBits ); + entry++; + } + } + + // Write to disk + if( self->IsControlThread() ) + { + self->LockThreads(); + bitWriter.SubmitAndRelease(); + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + } + + if( self->IsControlThread() ) + bitWriter.SubmitLeftOvers(); + }); + + // Ensure the left-over finish writing + { + Fence fence; + _context.ioQueue->SignalFence( fence ); + _context.ioQueue->CommitCommands(); + fence.Wait(); + } + } + +private: + DiskPlotContext& _context; + int64 _entriesPerThread; + uint64 _blocksPerBucket; + uint64* _entries; // Work buffer for distributed bucket entries + uint32* _blocks[_numBuckets] = { 0 }; // Chacha block buffers for each thread + FileId _fileId; + BitBucketWriter<_numBuckets> _bitWriter; + + + const uint64* _sharedTotalCounts = nullptr; // Shared across threads +}; \ No newline at end of file diff --git a/src/plotdisk/DiskFp.h b/src/plotdisk/DiskFp.h new file mode 100644 index 00000000..d353d904 --- /dev/null +++ b/src/plotdisk/DiskFp.h @@ -0,0 +1,1243 @@ +#pragma once +#include "util/Util.h" +#include "plotdisk/DiskPlotConfig.h" +#include "plotdisk/DiskBufferQueue.h" +#include "plotdisk/DiskPlotContext.h" +#include "plotdisk/FpGroupMatcher.h" +#include "plotdisk/FpFxGen.h" +#include "DiskPlotInfo.h" +#include "BitBucketWriter.h" +#include "BlockWriter.h" +#include "util/StackAllocator.h" +#include "plotting/TableWriter.h" + +#if _DEBUG + #include "DiskPlotDebug.h" +#endif + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" + +template +struct FpMapType { using Type = uint64; }; + +template<> +struct FpMapType { using Type = uint32; }; + +template +class DiskFp +{ +public: + using InInfo = DiskPlotInfo; + using Info = DiskPlotInfo; + + static constexpr uint32 _k = Info::_k; + static constexpr uint64 MaxBucketEntries = Info::MaxBucketEntries; + static constexpr uint32 MapBucketCount = table == TableId::Table2 ? 1 : _numBuckets + 1; + + using Entry = FpEntry; + using EntryOut = FpEntry; + using TMetaIn = typename TableMetaType
::MetaIn; + using TMetaOut = typename TableMetaType
::MetaOut; + using TYOut = typename FpFxGen
::TYOut; + using TAddress = uint64; + +public: + + //----------------------------------------------------------- + inline DiskFp( DiskPlotContext& context, const FileId inFxId, const FileId outFxId ) + : _context( context ) + , _pool ( *context.threadPool ) + , _ioQueue( *context.ioQueue ) + , _inFxId ( inFxId ) + , _outFxId( outFxId ) + , _threadCount( context.fpThreadCount ) + { + _crossBucketInfo.maxBuckets = _numBuckets; + } + + //----------------------------------------------------------- + inline void Run() + { + _ioQueue.SeekBucket( _inFxId , 0, SeekOrigin::Begin ); + _ioQueue.SeekBucket( _outFxId, 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); + + StackAllocator alloc( _context.heapBuffer, _context.heapSize ); + AllocateBuffers( alloc, _context.tmp2BlockSize, _context.tmp1BlockSize ); + + FpTable(); + + _context.entryCounts[(int)table] = (uint64)_tableEntryCount; + + // #TODO: Pass in the fences and then wait before we start the next table... + // Wait for all writes to finish + _ioQueue.SignalFence( _writeFence, _numBuckets+1 ); + _ioQueue.CommitCommands(); + _writeFence.Wait( _numBuckets+1 ); + +#if _DEBUG + if( 0 && table == TableId::Table2 ) + { + Log::Line( "Validating Xs" ); + uint32* xRef = nullptr; + uint64 refCount = 0; + + FatalIf( !Debug::LoadRefTable( "/mnt/p5510a/reference/t1.x.tmp", xRef, refCount ), + "Failed to load ref table" ); + ASSERT( refCount == (1ull << _K) ); + + int err; + uint32* xs = (uint32*)IOJob::ReadAllBytesDirect( "/mnt/p5510a/disk_tmp/t1_0.tmp", err ); + FatalIf( !xs, "Failed to rad Xs with error: %d", err ); + + for( uint64 i = 0; i < refCount; i++ ) + { + if( xs[i] != xRef[i] ) + { + if( xs[i+1] == xRef[i] || xs[i] == xRef[i+1] ) + { + i++; + continue; + } + else + { + uint32 xA[3] = { xs[i], xs[i+1], xs[i+2] }; + uint32 xB[3] = { xRef[i], xRef[i+1], xRef[i+2] }; + + std::sort( xA, &xA[3] ); + std::sort( xB, &xB[3] ); + + if( memcmp( xA, xB, sizeof( xA ) ) == 0 ) + { + i+=2; + continue; + } + } + ASSERT( 0 ); + } + } + + bbvirtfree( xRef ); + bbvirtfree( xs ); + Log::Line( "All good!" ); + } +#endif + } + + //----------------------------------------------------------- + inline void RunF7() + { + _threadCount = _context.cThreadCount; + + _ioQueue.SeekBucket( _inFxId, 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); + + StackAllocator alloc( _context.heapBuffer, _context.heapSize ); + AllocateBuffers( alloc, _context.tmp2BlockSize, _context.tmp1BlockSize ); + + _mapBitWriter.SetFileId( FileId::MAP7 ); + WriteCTables(); + + // Wait for all writes to finish + _ioQueue.SignalFence( _writeFence, _numBuckets+1 ); + _ioQueue.CommitCommands(); + _writeFence.Wait( _numBuckets+1 ); + } + + //----------------------------------------------------------- + inline void AllocateBuffers( IAllocator& alloc, const size_t fxBlockSize, const size_t pairBlockSize, bool dryRun = false ) + { + using info = DiskPlotInfo; + + const size_t maxEntries = info::MaxBucketEntries; + const size_t maxSliceEntries = info::MaxBucketSliceEntries; + const size_t maxEntriesX = maxEntries + BB_DP_CROSS_BUCKET_MAX_ENTRIES; + + // Working buffers + _entries[0] = alloc.CAlloc( maxEntries ); + _entries[1] = alloc.CAlloc( maxEntries ); + + _y[0] = alloc.CAlloc( maxEntriesX ); + _y[1] = alloc.CAlloc( maxEntriesX ); + + _map[0] = alloc.CAlloc( maxEntriesX ); + + _meta[0] = (TMetaIn*)alloc.CAlloc( maxEntriesX ); + _meta[1] = (TMetaIn*)alloc.CAlloc( maxEntriesX ); + + _pair[0] = alloc.CAlloc( maxEntriesX ); + + // IO buffers + const uint32 bucketBits = bblog2( _numBuckets ); + const size_t entrySizeBits = info::EntrySizePackedBits; // Entries stored in fx file (tmp2) + const size_t pairBits = _k + 1 - bucketBits + 9; // Entries stored in table file (tmp1) + const size_t mapBits = _k + 1 - bucketBits + _k + 1; // Entries stored in map file (tmp1) + + // Because bitwriter needs each slice buffer to be rounded up + // to block-size, we need to account for that here when allocating. + const size_t entrySliceAlloc = (size_t)RoundUpToNextBoundaryT( CDiv( (uint128)maxSliceEntries * entrySizeBits, 8 ), (uint128)fxBlockSize ); + const size_t mapSliceAslloc = (size_t)RoundUpToNextBoundaryT( CDiv( (uint128)maxSliceEntries * mapBits , 8 ), (uint128)pairBlockSize ); + + const size_t genEntriesPerBucket = (size_t)( CDivT( maxEntries, (size_t)_numBuckets ) * BB_DP_XTRA_ENTRIES_PER_BUCKET ); + const size_t perBucketEntriesSize = RoundUpToNextBoundaryT( CDiv( entrySizeBits * genEntriesPerBucket, 8 ), fxBlockSize ) + + RoundUpToNextBoundaryT( CDiv( entrySizeBits * BB_DP_CROSS_BUCKET_MAX_ENTRIES, 8 ), fxBlockSize ); + + const size_t fxWriteSize = entrySliceAlloc * _numBuckets; //(size_t)_numBuckets * perBucketEntriesSize; + const size_t pairWriteSize = CDiv( ( maxEntriesX ) * pairBits, 8 ); + const size_t mapWriteSize = mapSliceAslloc * _numBuckets; //CDiv( ( maxEntriesX ) * mapBits , 8 ); // #TODO: Might need the cross bucket entries added here too... But maybe the multiplier covers it + + // #TODO: These need to have buffers rounded-up to block size per bucket I think... + // So we need to have this divided into bucket slices, then each sice rounded-up + // to the block size, finally, the sum of that is the allocation size. + _fxRead [0] = alloc.Alloc( fxWriteSize, fxBlockSize ); + _fxRead [1] = alloc.Alloc( fxWriteSize, fxBlockSize ); + _fxWrite[0] = alloc.Alloc( fxWriteSize, fxBlockSize ); + _fxWrite[1] = alloc.Alloc( fxWriteSize, fxBlockSize ); + + _pairWrite[0] = alloc.Alloc( pairWriteSize, pairBlockSize ); + _pairWrite[1] = alloc.Alloc( pairWriteSize, pairBlockSize ); + + _mapWrite[0] = alloc.Alloc( mapWriteSize, pairBlockSize ); + _mapWrite[1] = alloc.Alloc( mapWriteSize, pairBlockSize ); + + // Block bit buffers + byte* fxBlocks = (byte*)alloc.CAlloc( _numBuckets, fxBlockSize , fxBlockSize ); // Fx write + byte* pairBlocks = (byte*)alloc.CAlloc( 1 , pairBlockSize, pairBlockSize ); // Pair write + byte* mapBlocks = nullptr; + + // #TODO: Just re-use another buffer for x in T2. mapWriteSize will be already biffer than we need I think. + // Or do NOT allocate map write buffers in T2. Just allocate xWriter. + if( table == TableId::Table2 ) + _xWriter = BlockWriter( alloc, FileId::T1, _mapWriteFence, pairBlockSize, maxEntries ); + else + mapBlocks = (byte*)alloc.CAlloc( MapBucketCount, pairBlockSize, pairBlockSize ); // Map write + + if( !dryRun ) + { + const FileId mapWriterId = IsT7Out ? FileId::MAP7 : + table == TableId::Table2 ? FileId::T1 : FileId::MAP2 + (FileId)table-2; // Writes previous buffer's key as a map + + if( !IsT7Out ) + { + _fxBitWriter = BitBucketWriter<_numBuckets>( _ioQueue, _outFxId, (byte*)fxBlocks ); + _pairBitWriter = BitBucketWriter<1> ( _ioQueue, FileId::T1 + (FileId)table, (byte*)pairBlocks ); + } + + if( table > TableId::Table2 ) + _mapBitWriter = BitBucketWriter( _ioQueue, mapWriterId, (byte*)mapBlocks ); + } + } + + //----------------------------------------------------------- + inline static size_t GetRequiredHeapSize( const size_t fxBlockSize, const size_t pairBlockSize ) + { + DiskPlotContext cx = { 0 }; + DiskFp fp2( cx, FileId::None, FileId::None ); + DiskFp fp4( cx, FileId::None, FileId::None ); + + // #TODO: Revert checking both, use whichever is bigger after testing explicitly + DummyAllocator alloc2; + DummyAllocator alloc4; + fp2.AllocateBuffers( alloc2, fxBlockSize, pairBlockSize, true ); + fp4.AllocateBuffers( alloc4, fxBlockSize, pairBlockSize, true ); + + const size_t reqSize = std::max( alloc2.Size(), alloc4.Size() ); + return reqSize; + } + + //----------------------------------------------------------- + inline Duration IOWaitTime() const { return _ioWaitTime; } + +// private: + //----------------------------------------------------------- + inline void FpTable() + { + // Load initial bucket + LoadBucket( 0 ); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + // Load next bucket in the background + if( bucket + 1 < _numBuckets ) + LoadBucket( bucket + 1 ); + + _readFence.Wait( bucket + 1, _ioWaitTime ); + + FpBucket( bucket ); + } + + _fxBitWriter .SubmitLeftOvers(); + _pairBitWriter.SubmitLeftOvers(); + + if( table > TableId::Table2 ) + _mapBitWriter .SubmitLeftOvers(); + } + + //----------------------------------------------------------- + inline void FpBucket( const uint32 bucket ) + { + // Log::Verbose( " Bucket %u", bucket ); + const int64 inEntryCount = (int64)_context.bucketCounts[(int)table-1][bucket]; + // const bool isLastBucket = bucket + 1 == _numBuckets; + + const byte* packedEntries = GetReadBufferForBucket( bucket ); + + // The first part of the buffer is reserved for storing cross bucket entries. + uint64* y = _y [0] + BB_DP_CROSS_BUCKET_MAX_ENTRIES; + TMetaIn* meta = _meta[0] + BB_DP_CROSS_BUCKET_MAX_ENTRIES; + Pair* pairs = _pair[0] + BB_DP_CROSS_BUCKET_MAX_ENTRIES; + uint64* map = _map [0] + BB_DP_CROSS_BUCKET_MAX_ENTRIES; // Needs prefix offset because it is used as meta input in cross-bucket matches + + // Expand entries to be 64-bit aligned, sort them, then unpack them to individual components + ExpandEntries( packedEntries, 0, _entries[0], inEntryCount ); + SortEntries( _entries[0], _entries[1], inEntryCount ); + UnpackEntries( bucket, _entries[0], inEntryCount, y, map, meta ); + + WriteMap( bucket, inEntryCount, map, (uint64*)_meta[1] ); + + const TMetaIn* inMeta = ( table == TableId::Table2 ) ? (TMetaIn*)map : meta; + + TYOut* outY = (TYOut*)_y[1]; + TMetaOut* outMeta = (TMetaOut*)_meta[1]; + + // Match + const int64 outEntryCount = MatchEntries( bucket, inEntryCount, y, inMeta, pairs ); + + const int64 crossMatchCount = _crossBucketInfo.matchCount; + const int64 writeEntrtyCount = outEntryCount + crossMatchCount; + + if( bucket > 0 ) + { + ProcessCrossBucketEntries( bucket - 1, pairs - crossMatchCount, outY, outMeta ); + ASSERT( crossMatchCount <= std::numeric_limits::max() ); + + _context.ptrTableBucketCounts[(int)table][bucket-1] += (uint32)crossMatchCount; + } + + WritePairsToDisk( bucket, writeEntrtyCount, pairs - crossMatchCount ); + + FxGen( bucket, outEntryCount, pairs, y, inMeta, outY + crossMatchCount, outMeta + crossMatchCount ); + + WriteEntriesToDisk( bucket, writeEntrtyCount, outY, outMeta, (EntryOut*)_entries[0] ); + + // Save bucket length before y-sort since the pairs remain unsorted + _context.ptrTableBucketCounts[(int)table][bucket] += (uint32)outEntryCount; + + _tableEntryCount += writeEntrtyCount; + _mapOffset += (uint64)inEntryCount; + _crossBucketInfo.matchCount = 0; + } + + //----------------------------------------------------------- + void WriteMap( const uint32 bucket, const int64 entryCount, const uint64* map, uint64* outMap ) + { + ASSERT( entryCount < (1ll << _k) ); + + if constexpr ( table == TableId::Table2 ) + { + // #NOTE: We don't unpack xs directly into the write buffer because + // map is used as meta during matching, which needs a prefix zone + // to perfrom cross-bucket matches. + uint32* xBuffer = _xWriter.GetNextBuffer( _ioWaitTime ); + + AnonMTJob::Run( _pool, _threadCount, [=]( AnonMTJob* self ) { + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + if( count ) + memcpy( xBuffer + offset, ((uint32*)map) + offset, (size_t)count * sizeof( uint32 ) ); + }); + + _xWriter.SubmitBuffer( _ioQueue, (size_t)entryCount ); + + if( bucket == _numBuckets - 1 ) + _xWriter.SubmitFinalBlock( _ioQueue ); + + return; + } + + // Write the key as a map to the final entry location. + // We do this by writing into buckets to final sorted (current) location + // into its original bucket, with the offset in that bucket. + using Job = AnonPrefixSumJob; + + uint32 totalCounts [_numBuckets+1]; + uint64 totalBitCounts[_numBuckets+1]; + + Job::Run( _pool, _threadCount, [&]( Job* self ) { + + const uint32 bucketBits = Info::BucketBits; + const uint32 bucketShift = _k - bucketBits; + const uint32 bitSize = Info::MapBitSize + _k - bucketBits; + const uint32 encodeShift = Info::MapBitSize; + const uint32 numBuckets = _numBuckets + 1; + + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + uint32 counts[numBuckets] = { 0 }; + uint32 pfxSum[numBuckets]; + + const uint64* inIdx = map + offset; + const uint64* inIdxEnd = map + end; + + // Count buckets + do { + const uint64 b = *inIdx >> bucketShift; + ASSERT( b < numBuckets ); + counts[b]++; + } while( ++inIdx < inIdxEnd ); + + self->CalculatePrefixSum( numBuckets, counts, pfxSum, totalCounts ); + + // Convert map entries from source index to reverse map + const uint64 tableOffset = _mapOffset + (uint64)offset; + + const uint64* reverseMap = map + offset; + uint64* outMapBuckets = outMap; + + for( int64 i = 0; i < count; i++ ) + { + const uint64 origin = reverseMap[i]; + const uint64 b = origin >> bucketShift; + const uint32 dstIdx = --pfxSum[b]; + + const uint64 finalIdx = tableOffset + (uint64)i; + outMapBuckets[dstIdx] = (origin << encodeShift) | finalIdx; + + ASSERT( (int64)dstIdx < entryCount ); + ASSERT( finalIdx < ( 1ull << encodeShift ) ); + } + + auto& bitWriter = _mapBitWriter; + uint64* bitCounts = totalBitCounts; + + if( self->IsControlThread() ) + { + self->LockThreads(); + + // Convert counts to bit sizes + for( uint32 i = 0; i < numBuckets; i++ ) + bitCounts[i] = (uint64)totalCounts[i] * bitSize; + + byte* writeBuffer = GetMapWriteBuffer( bucket ); + + // Wait for the buffer to be available first + if( bucket > 1 ) + _mapWriteFence.Wait( bucket - 2, _ioWaitTime ); + + bitWriter.BeginWriteBuckets( bitCounts, writeBuffer ); + + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + + + // Bit-compress/pack each bucket entries (except the overflow bucket) + uint64 bitsWritten = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + if( counts[i] < 1 ) + { + self->SyncThreads(); + continue; + } + + + const uint64 writeOffset = pfxSum[i]; + const uint64 bitOffset = writeOffset * bitSize - bitsWritten; + bitsWritten += bitCounts[i]; + + ASSERT( bitOffset + counts[i] * bitSize <= bitCounts[i] ); + + BitWriter writer = bitWriter.GetWriter( i, bitOffset ); + + const uint64* mapToWrite = outMapBuckets + writeOffset; + const uint64* mapToWriteEnd = mapToWrite + counts[i]; + + // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields + const uint64* mapToWriteEndPass1 = mapToWrite + std::min( counts[i], 2u ); + ASSERT( counts[i] > 2 ); + + while( mapToWrite < mapToWriteEndPass1 ) + writer.Write( *mapToWrite++, bitSize ); + + self->SyncThreads(); + + while( mapToWrite < mapToWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } + + // Write the overflow bucket and then write to disk + self->SyncThreads(); + if( self->IsControlThread() ) + { + const uint32 overflowBucket = _numBuckets; + const uint64 overflowCount = totalCounts[overflowBucket]; + + if( overflowCount ) + { + const uint64 writeOffset = pfxSum[overflowBucket]; + ASSERT( writeOffset * bitSize - bitsWritten == 0 ); + + BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); + + const uint64* mapToWrite = outMapBuckets + writeOffset; + const uint64* mapWriteEnd = mapToWrite + overflowCount; + while( mapToWrite < mapWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } + + bitWriter.Submit(); + _ioQueue.SignalFence( _mapWriteFence, bucket ); + _ioQueue.CommitCommands(); + } + }); + } + + //----------------------------------------------------------- + inline int64 MatchEntries( const uint32 bucket, const int64 inEntryCount, const uint64* y, const TMetaIn* meta, Pair* pairs ) + { + _crossBucketInfo.bucket = bucket; + FpGroupMatcher matcher( _context, MaxBucketEntries, _y[1], (Pair*)_meta[1], pairs ); + const int64 entryCount = (int64)matcher.Match( inEntryCount, y, meta, &_crossBucketInfo ); + + return entryCount; + } + + //----------------------------------------------------------- + void ProcessCrossBucketEntries( const uint32 bucket, Pair* dstPairs, TYOut* outY, TMetaOut* outMeta ) + { + FpCrossBucketInfo& info = _crossBucketInfo; + // ASSERT( info.matchCount ); + + if( !info.matchCount ) + return; + + FpFxGen
::ComputeFx( (int64)info.matchCount, info.pair, info.y, (TMetaIn*)info.meta, outY, outMeta, 0 ); + + const uint32 matchOffset = (uint32)info.matchOffset[0]; // Grab the previous bucket's offset and apply it + const Pair * srcPairs = info.pair; + + for( uint64 i = 0; i < info.matchCount; i++ ) + { + auto& src = srcPairs[i]; + auto& dst = dstPairs[i]; + dst.left = src.left + matchOffset; + dst.right = src.right + matchOffset; + } + } + + //----------------------------------------------------------- + void FxGen( const uint32 bucket, const int64 entryCount, + const Pair* pairs, const uint64* inY, const TMetaIn* inMeta, + TYOut* outY, TMetaOut* outMeta ) + { + FpFxGen
fx( _pool, _threadCount ); + fx.ComputeFxMT( entryCount, pairs, inY, inMeta, outY, outMeta ); + } + + //----------------------------------------------------------- + inline void WritePairsToDisk( const uint32 bucket, const int64 entryCount, const Pair* pairs ) + { + uint64 bitBucketSizes = (uint64)entryCount * Info::PairBitSize; + byte* writeBuffer = GetPairWriteBuffer( bucket ); + + _pairWriteFence.Wait( bucket, _ioWaitTime ); + _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, writeBuffer ); + + AnonMTJob::Run( _pool, _threadCount, [=]( AnonMTJob* self ) { + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + const Pair* pair = pairs + offset; + + BitWriter writer = _pairBitWriter.GetWriter( 0, (uint64)offset * Info::PairBitSize ); + + ASSERT( count >= 2 ); + PackPairs( 2, pair, writer ); + self->SyncThreads(); + PackPairs( count-2, pair+2, writer ); + }); + + _pairBitWriter.Submit(); + _ioQueue.SignalFence( _pairWriteFence, bucket + 1 ); // #TODO: Don't signal here, signal on cross-bucket? + _ioQueue.CommitCommands(); + } + + //----------------------------------------------------------- + inline static void PackPairs( const int64 entryCount, const Pair* pair, BitWriter& writer ) + { + const uint32 entrySizeBits = Info::PairBitSize; + const uint32 shift = Info::PairBitSizeL; + const uint64 mask = ( 1ull << shift ) - 1; + + const Pair* end = pair + entryCount; + + while( pair < end ) + { + ASSERT( pair->right - pair->left < 512 ); + + writer.Write( ( (uint64)(pair->right - pair->left) << shift ) | ( pair->left & mask ), entrySizeBits ); + pair++; + } + } + + //----------------------------------------------------------- + inline void WriteEntriesToDisk( const uint32 bucket, const int64 entryCount, const TYOut* outY, const TMetaOut* outMeta, EntryOut* dstEntriesBuckets ) + { + using Job = AnonPrefixSumJob; + + Job::Run( _pool, _threadCount, [=]( Job* self ) { + + const uint32 yBits = Info::YBitSize; + const uint32 yShift = Info::BucketShift; + const uint64 yMask = ( 1ull << yBits ) - 1; + const size_t entrySizeBits = Info::EntrySizePackedBits; + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + // Count Y buckets + uint32 counts [_numBuckets] = { 0 }; + uint32 pfxSum [_numBuckets]; + uint32 totalCounts [_numBuckets]; + uint64 totalBitCounts[_numBuckets]; + + const TYOut* ySrc = outY + offset; + const TYOut* ySrcEnd = outY + end; + + do { + counts[(*ySrc) >> yShift]++; + } while( ++ySrc < ySrcEnd ); + + self->CalculatePrefixSum( _numBuckets, counts, pfxSum, totalCounts ); + + // Distribute to the appropriate buckets as an expanded entry + const int64 mapIdx = _tableEntryCount + offset; + const TMetaOut* metaSrc = outMeta + offset; + EntryOut* dstEntries = dstEntriesBuckets; + + ySrc = outY + offset; + + for( int64 i = 0; i < count; i++ ) + { + const uint64 y = ySrc[i]; + const uint32 dstIdx = --pfxSum[y >> yShift]; + ASSERT( (int64)dstIdx < entryCount ); + + EntryOut& e = dstEntries[dstIdx]; + e.ykey = ( (uint64)(mapIdx+i) << yBits ) | ( y & yMask ); // Write y and key/map as packed already + + if constexpr ( table < TableId::Table7 ) + e.meta = metaSrc[i]; + } + + // Prepare to pack entries + auto& bitWriter = _fxBitWriter; + + if( self->IsControlThread() ) + { + self->LockThreads(); + + for( uint32 i = 0; i < _numBuckets; i++ ) + _context.bucketCounts[(int)table][i] += totalCounts[i]; + + // Convert counts to bit sizes + for( uint32 i = 0; i < _numBuckets; i++ ) + totalBitCounts[i] = totalCounts[i] * entrySizeBits; + + byte* writeBuffer = GetWriteBuffer( bucket ); + + // Wait for the buffer to be available first + if( bucket > 1 ) + _writeFence.Wait( bucket - 2, _ioWaitTime ); + + bitWriter.BeginWriteBuckets( totalBitCounts, writeBuffer ); + + _sharedTotalBitCounts = totalBitCounts; + + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + + + // Bit-compress/pack each bucket entries + uint64* totalBucketBitCounts = _sharedTotalBitCounts; + uint64 bitsWritten = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + const uint64 writeOffset = pfxSum[i]; + const uint64 bitOffset = writeOffset * entrySizeBits - bitsWritten; + bitsWritten += totalBucketBitCounts[i]; + + ASSERT( bitOffset + counts[i] * entrySizeBits <= totalBucketBitCounts[i] ); + + BitWriter writer = bitWriter.GetWriter( i, bitOffset ); + + const EntryOut* entry = dstEntries + writeOffset; + ASSERT( counts[i] >= 2 ); + + // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields + PackEntries( entry, 2, writer ); + self->SyncThreads(); + PackEntries( entry + 2, (int64)counts[i]-2, writer ); + } + + // Write buckets to disk + if( self->IsControlThread() ) + { + self->LockThreads(); + bitWriter.Submit(); + _ioQueue.SignalFence( _writeFence, bucket ); + _ioQueue.CommitCommands(); + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + }); + } + + //----------------------------------------------------------- + void WriteCTables() + { + _readFence .Reset( 0 ); + _writeFence.Reset( 0 ); + + uint32 c1NextCheckpoint = 0; // How many C1 entries to skip until the next checkpoint. If there's any entries here, it means the last bucket wrote a + uint32 c2NextCheckpoint = 0; // checkpoint entry and still had entries which did not reach the next checkpoint. + // Ex. Last bucket had 10005 entries, so it wrote a checkpoint at 0 and 10000, then it counted 5 more entries, so + // the next checkpoint would be after 9995 entries. + + // These buffers are small enough on k32 (around 1.6MiB for C1, C2 is negligible), we keep the whole thing in memory, + // while we write C3 to the actual file + const uint32 c1Interval = kCheckpoint1Interval; + const uint32 c2Interval = kCheckpoint1Interval * kCheckpoint2Interval; + + const uint64 tableLength = _context.entryCounts[(int)TableId::Table7]; + const uint32 c1TotalEntries = (uint32)CDiv( tableLength, (int)c1Interval ) + 1; // +1 because chiapos adds an extra '0' entry at the end + const uint32 c2TotalEntries = (uint32)CDiv( tableLength, (int)c2Interval ) + 1; // +1 because we add a short-circuit entry to prevent C2 lookup overflows + // #TODO: Remove the extra c2 entry? + + const size_t c1TableSizeBytes = c1TotalEntries * sizeof( uint32 ); + const size_t c2TableSizeBytes = c2TotalEntries * sizeof( uint32 ); + + // Use meta1 for here, it's big enough to hold both at any bucket size + // meta1 is 64MiB on which is enough to c1 and c2 + uint32* c1Buffer = (uint32*)_meta[1]; + uint32* c2Buffer = c1Buffer + c1TotalEntries; + + uint32 c3ParkOverflowCount = 0; // Overflow entries from a bucket that did not make it into a C3 park this bucket. Saved for the next bucket. + uint32 c3ParkOverflow[kCheckpoint1Interval]; // They are then copied to a "prefix region" in the f7 buffer of the next park. + + size_t c3TableSizeBytes = 0; // Total size of the C3 table + + // Seek to the start of the C3 table instead of writing garbage data. + _ioQueue.SeekFile( FileId::PLOT, 0, (int64)(c1TableSizeBytes + c2TableSizeBytes), SeekOrigin::Current ); + _ioQueue.CommitCommands(); + + // Load initial bucket + LoadBucket( 0 ); + + uint32* c1Writer = c1Buffer; + uint32* c2Writer = c2Buffer; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + // Load next bucket in the background + if( bucket + 1 < _numBuckets ) + LoadBucket( bucket + 1 ); + + _readFence.Wait( bucket + 1, _ioWaitTime ); + + const uint32 bucketLength = (int64)_context.bucketCounts[(int)TableId::Table7][bucket]; + const byte* packedEntries = GetReadBufferForBucket( bucket ); + + uint32* f7 = ((uint32*)_y[0]) + kCheckpoint1Interval; + + using T7Entry = FpEntry; + static_assert( sizeof( T7Entry ) == sizeof( uint64 ) ); + + ExpandEntries( packedEntries, 0, (T7Entry*)_entries[0], (int64)bucketLength ); + // #if _DEBUG + // { + // UnpackEntries( bucket, (T7Entry*)_entries[0], (int64)bucketLength, f7, _map[0], nullptr ); + // RadixSort256::Sort( *_context.threadPool, f7, (uint32*)_map[0], bucketLength ); + // } + // #endif + SortEntries( (T7Entry*)_entries[0], (T7Entry*)_entries[1], (int64)bucketLength ); + + // Any bucket count above 128 will only require 3 iterations w/ k=32, so + // the sorted entries will be at the _entries[1] buffer in that case + auto* sortedEntries = (T7Entry*)( _numBuckets > 128 ? _entries[1] : _entries[0] ); + + UnpackEntries( bucket, sortedEntries, (int64)bucketLength, f7, _map[0], nullptr ); + WriteMap( bucket, (int64)bucketLength, _map[0], (uint64*)_meta[0] ); + + _mapOffset += (uint64)bucketLength; + + /// Now handle f7 and write them into C tables + /// We will set the addersses to these tables accordingly. + + // Write C1 + { + ASSERT( bucketLength > c1NextCheckpoint ); + + // #TODO: Do C1 multi-threaded? For now jsut single-thread it... + for( uint32 i = c1NextCheckpoint; i < bucketLength; i += c1Interval ) + *c1Writer++ = Swap32( f7[i] ); + + // Track how many entries we covered in the last checkpoint region + const uint32 c1Length = bucketLength - c1NextCheckpoint; + const uint32 c1CheckPointCount = CDiv( c1Length, (int)c1Interval ); + + c1NextCheckpoint = c1CheckPointCount * c1Interval - c1Length; + } + + // Write C2 + { + // C2 has so few entries on k=32 that there's no sense in doing it multi-threaded + static_assert( _K == 32 ); + + if( c2NextCheckpoint >= bucketLength ) + c2NextCheckpoint -= bucketLength; // No entries to write in this bucket + else + { + for( uint32 i = c2NextCheckpoint; i < bucketLength; i += c2Interval ) + *c2Writer++ = Swap32( f7[i] ); + + // Track how many entries we covered in the last checkpoint region + const uint32 c2Length = bucketLength - c2NextCheckpoint; + const uint32 c2CheckPointCount = CDiv( c2Length, (int)c2Interval ); + + c2NextCheckpoint = c2CheckPointCount * c2Interval - c2Length; + } + } + + // Write C3 + { + const bool isLastBucket = bucket == _numBuckets-1; + + uint32* c3F7 = f7; + uint32 c3BucketLength = bucketLength; + + if( c3ParkOverflowCount ) + { + // Copy our overflow to the prefix region of our f7 buffer + c3F7 -= c3ParkOverflowCount; + c3BucketLength += c3ParkOverflowCount; + + memcpy( c3F7, c3ParkOverflow, sizeof( uint32 ) * c3ParkOverflowCount ); + + c3ParkOverflowCount = 0; + } + + + #if _DEBUG + // #TODO: TEST: Remove this + // Dump f7's that have the value of 0xFFFFFFFF for now, + // this is just for compatibility with RAM bladebit + // for testing plots against it. + // if( isLastBucket ) + // { + // while( c3F7[c3BucketLength-1] == 0xFFFFFFFF ) + // c3BucketLength--; + // } + #endif + + // See TableWriter::GetC3ParkCount for details + uint32 parkCount = c3BucketLength / kCheckpoint1Interval; + uint32 overflowEntries = c3BucketLength - ( parkCount * kCheckpoint1Interval ); + + // Greater than 1 because the first entry is excluded as it is written in C1 instead. + if( isLastBucket && overflowEntries > 1 ) + { + overflowEntries = 0; + parkCount++; + } + else if( overflowEntries && !isLastBucket ) + { + // Save any entries that don't fill-up a full park for the next bucket + memcpy( c3ParkOverflow, c3F7 + c3BucketLength - overflowEntries, overflowEntries * sizeof( uint32 ) ); + + c3ParkOverflowCount = overflowEntries; + c3BucketLength -= overflowEntries; + } + + const size_t c3BufferSize = CalculateC3Size() * parkCount; + byte* c3Buffer = GetWriteBuffer( bucket ); + + if( bucket > 1 ) + _writeFence.Wait( bucket - 2, _ioWaitTime ); + + // #NOTE: This function uses re-writes our f7 buffer, so ensure it is done after + // that buffer is no longer needed. + const size_t sizeWritten = TableWriter::WriteC3Parallel( *_context.threadPool, + _threadCount, c3BucketLength, c3F7, c3Buffer ); + ASSERT( sizeWritten == c3BufferSize ); + + c3TableSizeBytes += sizeWritten; + + // Write the C3 table to the plot file directly + _ioQueue.WriteFile( FileId::PLOT, 0, c3Buffer, c3BufferSize ); + _ioQueue.SignalFence( _writeFence, bucket ); + _ioQueue.CommitCommands(); + } + } + + // Submit any left-over map bits + _mapBitWriter.SubmitLeftOvers(); + + // Seek back to the begining of the C1 table and + // write C1 and C2 buffers to file, then seek back to the end of the C3 table + + c1Buffer[c1TotalEntries-1] = 0; // Chiapos adds a trailing 0 + c2Buffer[c2TotalEntries-1] = 0xFFFFFFFF; // C2 overflow protection // #TODO: Remove? + + _readFence.Reset( 0 ); + + _ioQueue.SeekBucket( FileId::PLOT, -(int64)( c1TableSizeBytes + c2TableSizeBytes + c3TableSizeBytes ), SeekOrigin::Current ); + _ioQueue.WriteFile( FileId::PLOT, 0, c1Buffer, c1TableSizeBytes ); + _ioQueue.WriteFile( FileId::PLOT, 0, c2Buffer, c2TableSizeBytes ); + _ioQueue.SeekBucket( FileId::PLOT, (int64)c3TableSizeBytes, SeekOrigin::Current ); + + _ioQueue.SignalFence( _readFence, 1 ); + _ioQueue.CommitCommands(); + + // Save C table addresses into the plot context. + // And set the starting address for the table 1 to be written + const size_t headerSize = _ioQueue.PlotHeaderSize(); + + _context.plotTablePointers[7] = headerSize; // C1 + _context.plotTablePointers[8] = _context.plotTablePointers[7] + c1TableSizeBytes; // C2 + _context.plotTablePointers[9] = _context.plotTablePointers[8] + c2TableSizeBytes; // C3 + _context.plotTablePointers[0] = _context.plotTablePointers[9] + c3TableSizeBytes; // T1 + + // Save sizes + _context.plotTableSizes[7] = c1TableSizeBytes; + _context.plotTableSizes[8] = c2TableSizeBytes; + _context.plotTableSizes[9] = c3TableSizeBytes; + + // Wait for all commands to finish + _readFence.Wait( 1 ); + } + + //----------------------------------------------------------- + inline static void PackEntries( const EntryOut* entries, const int64 entryCount, BitWriter& writer ) + { + const uint32 yBits = Info::YBitSize; + const uint32 mapBits = Info::MapBitSize; + const uint32 ykeyBits = yBits + mapBits; + const size_t metaOutMulti = Info::MetaMultiplier; + const size_t entrySizeBits = Info::EntrySizePackedBits; + + static_assert( ykeyBits + metaOutMulti * _k == entrySizeBits ); + static_assert( metaOutMulti != 1 ); + + const EntryOut* entry = entries; + const EntryOut* end = entry + entryCount; + + while( entry < end ) + { + writer.Write( entry->ykey, ykeyBits ); + + if constexpr ( metaOutMulti == 2 ) + { + writer.Write( entry->meta, 64 ); + } + else if constexpr ( metaOutMulti == 3 ) + { + writer.Write( entry->meta.m0, 64 ); + writer.Write( entry->meta.m1, 32 ); + } + else if constexpr ( metaOutMulti == 4 ) + { + writer.Write( entry->meta.m0, 64 ); + writer.Write( entry->meta.m1, 64 ); + } + + entry++; + } + } + + //----------------------------------------------------------- + template + inline void UnpackEntries( const uint32 bucket, const TEntry* packedEntries, const int64 entryCount, TY* outY, uint64* outMap, TMetaIn* outMeta ) + { + using TMap = typename FpMapType
::Type; + + AnonMTJob::Run( _pool, _threadCount, [=]( AnonMTJob* self ) { + + constexpr uint32 metaMultipler = IsT7Out ? 0 : InInfo::MetaMultiplier; + + const uint32 yBits = IsT7Out ? Info::YBitSize : InInfo::YBitSize; + const uint64 yMask = 0xFFFFFFFFFFFFFFFFull >> (64-yBits); + + const uint64 bucketBits = ((uint64)bucket) << yBits; + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + TY* y = (TY*)outY; + TMap* map = (TMap*)outMap; + TMetaIn* meta = outMeta; + + const TEntry* entries = packedEntries; + + for( int64 i = offset; i < end; i++ ) + { + auto& e = entries[i]; + + const uint64 ykey = e.ykey; + y [i] = (TY)( bucketBits | ( ykey & yMask ) ); + map[i] = (TMap)( ykey >> yBits ); + ASSERT( map[i] <= ( 1ull << Info::MapBitSize ) - 1 ); + + // Can't be 1 (table 1 only), because in that case the metadata is x, + // which is stored as the map + if constexpr ( metaMultipler > 1 ) + meta[i] = e.meta; + } + }); + } + + //----------------------------------------------------------- + template + inline void SortEntries( TEntry* entries, TEntry* tmpEntries, const int64 entryCount ) + { + AnonPrefixSumJob::Run( _pool, _threadCount, [=]( AnonPrefixSumJob* self ) { + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + const uint32 remainderBits = _k - yBitSize; + EntrySort( self, count, offset, entries, tmpEntries ); + }); + } + + //----------------------------------------------------------- + template + inline static void EntrySort( PrefixSumJob* self, const int64 entryCount, const int64 offset, + T* entries, T* tmpEntries ) + { + ASSERT( self ); + ASSERT( entries ); + ASSERT( tmpEntries ); + ASSERT( entryCount > 0 ); + + constexpr uint Radix = 256; + + constexpr uint32 MaxIter = 4; + constexpr int32 iterations = MaxIter - remainderBits / 8; + constexpr uint32 shiftBase = 8; + + BucketT counts [Radix]; + BucketT pfxSum [Radix]; + BucketT totalCounts[Radix]; + + uint32 shift = 0; + T* input = entries; + T* output = tmpEntries; + + const uint32 lastByteRemainderBits = remainderBits & 7; // & 7 == % 8 + const uint32 lastByteMask = 0xFF >> lastByteRemainderBits; + uint32 masks[MaxIter] = { 0xFF, 0xFF, 0xFF, 0xFF }; + + masks[iterations-1] = lastByteMask; + + for( int32 iter = 0; iter < iterations ; iter++, shift += shiftBase ) + { + const uint32 mask = masks[iter]; + + // Zero-out the counts + memset( counts, 0, sizeof( BucketT ) * Radix ); + + T* src = input + offset; + const T* start = src; + const T* end = start + entryCount; + + do { + counts[(src->ykey >> shift) & mask]++; + } while( ++src < end ); + + self->CalculatePrefixSum( Radix, counts, pfxSum, totalCounts ); + + while( --src >= start ) + { + const T value = *src; + const uint64 bucket = (value.ykey >> shift) & mask; + + const BucketT dstIdx = --pfxSum[bucket]; + + output[dstIdx] = value; + } + + std::swap( input, output ); + self->SyncThreads(); + } + } + + //----------------------------------------------------------- + // Convert entries from packed bits into 64-bit aligned entries + //----------------------------------------------------------- + template + inline void ExpandEntries( const void* packedEntries, const uint64 inputBitOffset, TEntry* expendedEntries, const int64 entryCount ) + { + AnonMTJob::Run( _pool, _threadCount, [=]( AnonMTJob* self ) { + + constexpr uint32 packedEntrySize = IsT7Out ? Info::YBitSize + Info::MapBitSize : InInfo::EntrySizePackedBits; + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + const uint64 inputBitOffset = packedEntrySize * (uint64)offset; + const size_t bitCapacity = CDiv( packedEntrySize * (uint64)entryCount, 64 ) * 64; + + DiskFp::ExpandEntries( packedEntries, inputBitOffset, bitCapacity, expendedEntries + offset, count ); + }); + } + + //----------------------------------------------------------- + template + inline static void ExpandEntries( const void* packedEntries, const uint64 inputBitOffset, const size_t bitCapacity, + TEntry* expendedEntries, const int64 entryCount ) + { + constexpr uint32 yBits = IsT7Out? Info::YBitSize : InInfo::YBitSize; + constexpr uint32 mapBits = table == TableId::Table2 ? _k : InInfo::MapBitSize; + constexpr uint32 metaMultipler = IsT7Out ? 0 : InInfo::MetaMultiplier; + constexpr uint32 packedEntrySize = IsT7Out ? yBits + mapBits : InInfo::EntrySizePackedBits; + + BitReader reader( (uint64*)packedEntries, bitCapacity, inputBitOffset ); + + TEntry* out = expendedEntries; + const TEntry* end = out + entryCount; + + for( ; out < end; out++ ) + { + if constexpr ( table == TableId::Table2 || IsT7Out ) + { + out->ykey = reader.ReadBits64( packedEntrySize ); + } + else + { + // #TODO: Can still get ykey in a single step like above + const uint64 y = reader.ReadBits64( yBits ); + const uint64 map = reader.ReadBits64( mapBits ); + + out->ykey = y | ( map << yBits ); + + if constexpr ( metaMultipler == 2 ) + { + out->meta = reader.ReadBits64( 64 ); + } + else if constexpr ( metaMultipler == 3 ) + { + // #TODO: Try aligning entries to 32-bits instead. + out->meta.m0 = reader.ReadBits64( 64 ); + out->meta.m1 = reader.ReadBits64( 32 ); + } + else if constexpr ( metaMultipler == 4 ) + { + out->meta.m0 = reader.ReadBits64( 64 ); + out->meta.m1 = reader.ReadBits64( 64 ); + } + } + } + } + + //----------------------------------------------------------- + inline void LoadBucket( const uint32 bucket ) + { + const size_t entrySizeBits = IsT7Out ? Info::EntrySizePackedBits : InInfo::EntrySizePackedBits; + const int32 loadTable = IsT7Out ? (int)table : (int)table-1; + + const uint64 inBucketLength = _context.bucketCounts[loadTable][bucket]; + const size_t bucketSizeBytes = CDiv( entrySizeBits * (uint64)inBucketLength, 64 ) * 64 / 8; + + byte* readBuffer = GetReadBufferForBucket( bucket ); + ASSERT( (size_t)readBuffer / _ioQueue.BlockSize( _inFxId ) * _ioQueue.BlockSize( _inFxId ) == (size_t)readBuffer ); + + _ioQueue.SeekFile( _inFxId, bucket, 0, SeekOrigin::Begin ); + _ioQueue.ReadFile( _inFxId, bucket, readBuffer, bucketSizeBytes ); + _ioQueue.SignalFence( _readFence, bucket+1 ); + _ioQueue.CommitCommands(); + } + + //----------------------------------------------------------- + inline byte* GetReadBufferForBucket( const uint32 bucket ) + { + return (byte*)_fxRead[bucket % 2]; + } + + //----------------------------------------------------------- + inline byte* GetWriteBuffer( const uint32 bucket ) + { + return (byte*)_fxWrite[bucket % 2]; + } + + //----------------------------------------------------------- + inline byte* GetPairWriteBuffer( const uint32 bucket ) + { + return (byte*)_pairWrite[bucket % 2]; + } + + //----------------------------------------------------------- + inline byte* GetMapWriteBuffer( const uint32 bucket ) + { + return (byte*)_mapWrite[bucket % 2]; + } + +private: + DiskPlotContext& _context; + ThreadPool& _pool; + DiskBufferQueue& _ioQueue; + FileId _inFxId; + FileId _outFxId; + Fence _readFence; // #TODO: Pass these in, have them pre-created so that we don't re-create them per-table? + Fence _writeFence; + Fence _mapWriteFence; + Fence _pairWriteFence; + Fence _crossBucketFence; + + int64 _tableEntryCount = 0; // Current table entry count + uint64 _mapOffset = 0; // Offset for writing the map entries + + Duration _ioWaitTime = Duration::zero(); + + // Working buffers, all of them have enough to hold entries for a single bucket + cross bucket entries + Entry* _entries[2] = { 0 }; // Unpacked entries // #TODO: Create read buffers of unpacked size and then just use that as temp entries + uint64* _y [2] = { 0 }; + uint64* _map [1] = { 0 }; + TMetaIn* _meta[2] = { 0 }; + Pair* _pair[1] = { 0 }; + + void* _fxRead [2] = { 0 }; + void* _fxWrite[2] = { 0 }; + + void* _pairWrite[2] = { 0 }; + void* _mapWrite [2] = { 0 }; + + uint32 _threadCount; + uint64* _sharedTotalBitCounts = nullptr; // Total bucket bit sizes when writing Fx across all threads + + BitBucketWriter<_numBuckets> _fxBitWriter; + BitBucketWriter<1> _pairBitWriter; + + BlockWriter _xWriter; // Used for Table2 (there's no map, but just x.) + BitBucketWriter _mapBitWriter; // Used after Table2 + + FpCrossBucketInfo _crossBucketInfo; +}; + + +#pragma GCC diagnostic pop + diff --git a/src/plotdisk/DiskFxGen.h b/src/plotdisk/DiskFxGen.h new file mode 100644 index 00000000..325a6674 --- /dev/null +++ b/src/plotdisk/DiskFxGen.h @@ -0,0 +1,6 @@ +#pragma once + +struct DiskFxGen +{ + +}; \ No newline at end of file diff --git a/src/plotdisk/DiskPairReader.h b/src/plotdisk/DiskPairReader.h new file mode 100644 index 00000000..cc10d82f --- /dev/null +++ b/src/plotdisk/DiskPairReader.h @@ -0,0 +1,591 @@ +#pragma once +#include "plotdisk/DiskPlotInfo.h" +#include "plotdisk/DiskPlotContext.h" +#include "util/StackAllocator.h" +#include "util/BitView.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreorder" + +/// #NOTE: We actually have _numBuckets+1 because there's an +// implicit overflow bucket that may contain entries. +template +struct DiskMapReader +{ + static constexpr uint32 _k = _K; + static constexpr uint32 _savedBits = bblog2( _numBuckets ); + static constexpr uint32 _mapBits = _k - _savedBits + _finalIdxBits; // ( origin address | final address ) + + //----------------------------------------------------------- + DiskMapReader() {} + + //----------------------------------------------------------- + DiskMapReader( DiskPlotContext& context, const uint32 threadCount, const TableId table, const FileId fileId, IAllocator& allocator, const uint64* realBucketLengths = nullptr ) + : _context ( &context ) + , _table ( table ) + , _fileId ( fileId ) + , _threadCount( threadCount ) + { + const uint64 maxKEntries = ( 1ull << _k ); + const uint64 maxBucketEntries = maxKEntries / _numBuckets; + const size_t blockSize = context.ioQueue->BlockSize( fileId ); + const size_t bufferSize = CDivT( (size_t)maxBucketEntries * _mapBits, blockSize * 8 ) * blockSize; + + _loadBuffers[0] = allocator.Alloc( bufferSize, blockSize ); + _loadBuffers[1] = allocator.Alloc( bufferSize, blockSize ); + _loadBuffers[2] = allocator.Alloc( bufferSize, blockSize ); + _loadBuffers[3] = allocator.Alloc( bufferSize, blockSize ); + + _unpackdMaps[0] = allocator.CAlloc( maxBucketEntries ); + _unpackdMaps[1] = allocator.CAlloc( maxBucketEntries ); + + if( realBucketLengths ) + memcpy( _bucketLengths, realBucketLengths, sizeof( _bucketLengths ) ); + else + { + for( uint32 b = 0; b < _numBuckets-1; b++ ) + _bucketLengths[b] = maxBucketEntries; + + _bucketLengths[_numBuckets-1] = GetVirtualBucketLength( _numBuckets-1 ); + _bucketLengths[_numBuckets] = GetVirtualBucketLength( _numBuckets ); + } + + ASSERT( _numBuckets == context.numBuckets ); + } + + //----------------------------------------------------------- + void LoadNextEntries( const uint64 entryCount ) + { + if( _bucketsLoaded >= _numBuckets ) + return; + + DiskBufferQueue& ioQueue = *_context->ioQueue; + + const size_t blockSize = ioQueue.BlockSize( _fileId ); + const size_t blockSizeBits = blockSize * 8; + + uint64 bucketLength = GetVirtualBucketLength( _bucketsLoaded ); + ASSERT( bucketLength ); + + // Need to load current bucket? + if( _bucketEntryOffset == 0 ) + { + // Load length (actual bucket length) might be different than the virtual length + const size_t loadSize = CDivT( (size_t)_bucketLengths[_bucketsLoaded] * _mapBits, blockSizeBits ) * blockSize; + ioQueue.ReadFile( _fileId, _bucketsLoaded, GetBucketBuffer( _bucketsLoaded ), loadSize ); + // _fence.Signal( _bucketsLoaded + 1 ); + } + + _bucketEntryOffset += entryCount; + + // It is possible to cross 2 buckets, so we need to account for that. + // But we ought never have to load more than 2 buckets on one go. + while( _bucketEntryOffset > bucketLength ) + { + _bucketEntryOffset -= bucketLength; + _bucketsLoaded++; + ASSERT( _bucketsLoaded <= _numBuckets ); + + // Upade bucket length and load the new bucket + bucketLength = GetVirtualBucketLength( _bucketsLoaded ); + ASSERT( bucketLength ); + + const size_t loadSize = CDivT( (size_t)_bucketLengths[_bucketsLoaded] * _mapBits, blockSizeBits ) * blockSize; + ioQueue.ReadFile( _fileId, _bucketsLoaded, GetBucketBuffer( _bucketsLoaded ), loadSize ); + // _fence.Signal( _bucketsLoaded + 1 ); + } + } + + //----------------------------------------------------------- + void ReadEntries( const uint64 entryCount, TMap* outMap ) + { + ASSERT( _bucketsRead <= _numBuckets ); + + // #TODO: Check here if we have to unpack a bucket and then check our own fence. + AnonMTJob::Run( *_context->threadPool, _threadCount, [=]( AnonMTJob* self ) { + + uint64 entriesToRead = entryCount; + TMap* outWriter = outMap; + uint64 readBucketOffset = _bucketReadOffset; + uint32 bucketsRead = _bucketsRead; + + while( entriesToRead ) + { + // Unpack the whole bucket into it's destination indices + if( _bucketsUnpacked <= bucketsRead ) + { + #if _DEBUG + const uint64 virtBucketLength = GetVirtualBucketLength( _bucketsUnpacked ); + #endif + + const uint64 bucketLength = _bucketLengths[_bucketsUnpacked]; + + int64 count, offset, end; + GetThreadOffsets( self, (int64)bucketLength, count, offset, end ); + ASSERT( count > 0 ); + + TMap* unpackedMap = _unpackdMaps[_bucketsUnpacked & 1]; + BitReader reader( (uint64*)GetBucketBuffer( _bucketsUnpacked ), _mapBits * bucketLength, offset * _mapBits ); + + const uint32 idxShift = _finalIdxBits; + const uint64 finalIdxMask = ( 1ull << idxShift ) - 1; + + for( int64 i = offset; i < end; i++ ) + { + const uint64 packedMap = reader.ReadBits64( (uint32)_mapBits ); + const uint64 map = packedMap & finalIdxMask; + const uint64 dstIdx = packedMap >> idxShift; + + ASSERT( dstIdx < virtBucketLength ); + unpackedMap[dstIdx] = (TMap)map; + } + + if( self->IsControlThread() ) + { + self->LockThreads(); + _bucketsUnpacked++; + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + } + + const uint64 bucketLength = GetVirtualBucketLength( bucketsRead ); + const uint64 readCount = std::min( bucketLength - readBucketOffset, entriesToRead ); + + const TMap* readMap = _unpackdMaps[bucketsRead & 1] + readBucketOffset; + + // Simply copy the unpacked map to the destination buffer + int64 count, offset, end; + GetThreadOffsets( self, (int64)readCount, count, offset, end ); + + if( count ) + memcpy( outWriter + offset, readMap + offset, (size_t)count * sizeof( TMap ) ); + + // Update read entries + entriesToRead -= readCount; + outWriter += readCount; + + readBucketOffset += readCount; + if( readBucketOffset == bucketLength ) + { + readBucketOffset = 0; + bucketsRead++; + } + } + + if( self->IsControlThread() ) + { + self->LockThreads(); + _bucketReadOffset = readBucketOffset; + _bucketsRead = bucketsRead; + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + }); + } + + //----------------------------------------------------------- + inline uint64 GetVirtualBucketLength( const uint32 bucket ) + { + const uint64 maxKEntries = ( 1ull << _k ); + const uint64 maxBucketEntries = maxKEntries / _numBuckets; + + // All buckets before the last bucket (and before the overflow bucket) have the same entry count which is 2^k / numBuckets + if( bucket < _numBuckets - 1 ) + return maxBucketEntries; + + const uint64 tableEntryCount = _context->entryCounts[(int)_table]; + + // Last, non-overflow bucket? + if( bucket == _numBuckets - 1 ) + return tableEntryCount > maxKEntries ? + maxBucketEntries : + maxBucketEntries - ( maxKEntries - tableEntryCount ); + + // Last bucket + return tableEntryCount > maxKEntries ? tableEntryCount - maxKEntries : 0; + } + +private: + //----------------------------------------------------------- + inline void* GetBucketBuffer( const uint32 bucket ) + { + return _loadBuffers[bucket & 3]; + } + +private: + DiskPlotContext* _context = nullptr; + TableId _table = TableId::Table1; + FileId _fileId = FileId::None; + uint32 _threadCount = 0; + uint32 _bucketsLoaded = 0; + uint32 _bucketsRead = 0; + uint32 _bucketsUnpacked = 0; + uint64 _bucketEntryOffset = 0; + uint64 _bucketReadOffset = 0; // Entries that have actually bean read/unpacked in a bucket + + TMap* _unpackdMaps[2]; + void* _loadBuffers[4]; // We do double-buffering, but since a single load may go across bucket boundaries, we need 4. + uint64 _bucketLengths[_numBuckets+1]; // Real, non-virtual bucket lengths. This is only necessary for buckets that have been pruned (ex. in Phase 3) +}; + + +// Since pairs (back-pointers) and their corresponding +// maps, have assymetric bucket counts (or not synchronized with each other), +// as the maps have been sorted on y and written back to their original buckets, +// and pairs were never sorted on y. +template +struct DiskPairAndMapReader +{ + static constexpr uint32 _k = _K; + static constexpr uint32 _savedBits = bblog2( _numBuckets ); + static constexpr uint32 _pairBits = _k + 1 - _savedBits + 9; + + //----------------------------------------------------------- + DiskPairAndMapReader( DiskPlotContext& context, const uint32 threadCount, Fence& fence, const TableId table, IAllocator& allocator, bool noMap ) + : _context ( context ) + , _fence ( fence ) + , _table ( table ) + , _threadCount( threadCount ) + , _mapReader ( context, threadCount, table, FileId::MAP2 + (FileId)table - 1, allocator ) + , _noMap ( noMap ) + { + DiskBufferQueue& ioQueue = *_context.ioQueue; + + const uint64 maxBucketEntries = (uint64)DiskPlotInfo::MaxBucketEntries; + const size_t blockSize = ioQueue.BlockSize( FileId::T1 + (FileId)table ); + + const size_t bufferSize = blockSize + CDivT( (size_t)maxBucketEntries * _pairBits, blockSize * 8 ) * blockSize; + + _pairBuffers[0] = allocator.Alloc( bufferSize, blockSize ); + _pairBuffers[1] = allocator.Alloc( bufferSize, blockSize ); + + size_t prevOverflowBits = 0; + for( uint32 i = 0; i < _numBuckets; i++ ) + { + const size_t bucketLength = _context.ptrTableBucketCounts[(int)_table][i]; + const size_t bucketBitSize = bucketLength * _pairBits - prevOverflowBits; + const size_t bucketByteSize = CDiv( bucketBitSize, 8 ); + const size_t bucketBlockAlignedSize = CDivT( bucketByteSize, blockSize ) * blockSize; + + const size_t overflowBits = (bucketBlockAlignedSize * 8) - bucketBitSize; + ASSERT( overflowBits < blockSize * 8 ); + + _pairBucketLoadSize[i] = bucketBlockAlignedSize; + _pairOverflowBits [i] = (uint32)overflowBits; + + prevOverflowBits = overflowBits; + } + } + + //----------------------------------------------------------- + void LoadNextBucket() + { + if( _bucketsLoaded >= _numBuckets ) + return; + + ASSERT( _table > TableId::Table1 ); + + DiskBufferQueue& ioQueue = *_context.ioQueue; + + const FileId fileId = FileId::T1 + (FileId)_table; + const size_t blockSize = ioQueue.BlockSize( FileId::T1 + (FileId)_table); + + const uint32 bucket = _bucketsLoaded++; + const uint32 loadIdx = bucket & 1; // bucket & 1 == bucket % 2 + + // First block is for previous bucket's left-over bits + void* buffer = (byte*)_pairBuffers[loadIdx] + blockSize; + + ioQueue.ReadFile( fileId, 0, buffer, _pairBucketLoadSize[bucket] ); + + // Load accompanying map entries + if( !_noMap ) + _mapReader.LoadNextEntries( _context.ptrTableBucketCounts[(int)_table][bucket] ); + + ioQueue.SignalFence( _fence, bucket+1 ); + ioQueue.CommitCommands(); + } + + //----------------------------------------------------------- + uint64 UnpackBucket( const uint32 bucket, Pair* outPairs, uint64* outMap, Duration& ioWait ) + { + DiskBufferQueue& ioQueue = *_context.ioQueue; + + const uint32 loadIdx = bucket & 1; // Same as % 2 + const size_t blockSize = ioQueue.BlockSize( FileId::T1 + (FileId)_table ); + const size_t blockBitSize = blockSize * 8; + + _fence.Wait( bucket + 1, ioWait ); + + const byte* pairBuffer = (byte*)_pairBuffers[loadIdx]; + + // If we have overflow bits (bits that belong to the next bucket), + // copy the last block we loaded to the next bucket's buffer. + if( _pairOverflowBits[bucket] > 0 ) + { + const size_t bucketByteSize = _pairBucketLoadSize[bucket]; + const uint32 nextLoadIdx = ( loadIdx + 1 ) & 1; + + memcpy( _pairBuffers[nextLoadIdx], pairBuffer + bucketByteSize, blockSize ); + } + const uint32 startBit = bucket == 0 ? (uint32)blockBitSize : (uint32)(blockBitSize - _pairOverflowBits[bucket-1] ); + ASSERT( startBit <= blockSize*8 ); + + const size_t fullBitSize = _pairBucketLoadSize[bucket] * 8 + blockBitSize - startBit; + + const int64 bucketLength = (int64)_context.ptrTableBucketCounts[(int)_table][bucket]; + + AnonMTJob::Run( *_context.threadPool, _threadCount, [=]( AnonMTJob* self ) { + + + int64 count, offset, end; + GetThreadOffsets( self, bucketLength, count, offset, end ); + + const size_t bitOffset = startBit + (size_t)offset * _pairBits; + BitReader reader( (uint64*)pairBuffer, fullBitSize, bitOffset ); + + // const uint64 pairOffset = _entriesLoaded; + const uint32 lBits = _k - _savedBits + 1; + const uint32 rBits = 9; + + for( int64 i = offset; i < end; i++ ) + { + Pair pair; + pair.left = (uint32)reader.ReadBits64( lBits ); + pair.right = pair.left + (uint32)reader.ReadBits64( rBits ); + + outPairs[i] = pair; + } + }); + + // #TODO: Try not to start another threaded job, and instead do it in the same MT job? + if( !_noMap ) + _mapReader.ReadEntries( (uint64)bucketLength, outMap ); + + return (uint64)bucketLength; + } + +private: + DiskPlotContext& _context; + Fence& _fence; + + DiskMapReader _mapReader; + + void* _pairBuffers [2]; + uint32 _pairOverflowBits [_numBuckets]; + uint64 _pairBucketLoadSize[_numBuckets]; + + uint64 _entriesLoaded = 0; + uint32 _bucketsLoaded = 0; + uint32 _threadCount; + TableId _table; + bool _noMap; +}; + + +/// Reads T-sized elements with fs block size alignment. +/// Utility class used to hide block alignment stuff from the user. +/// Loads are double-buffered and meant to be used as if laoding a whole bucket. +/// After a maximum of 2 LoadEntries are called, +/// ReadEntries must be used afterwards/ to read that buffer and make it available again. +/// There's no check for this at runtime in release mode, so it must be used correctly by the user. +template +class BlockReader +{ +public: + + //----------------------------------------------------------- + BlockReader( const FileId fileId, DiskBufferQueue* ioQueue, const uint64 maxLength, + IAllocator& allocator, const size_t blockSize, const uint64 retainOffset ) + : _fileId( fileId ) + , _entriesPerBlock( blockSize / sizeof( T ) ) + , _ioQueue( ioQueue ) + { + // #TODO: Check that sizeof( T ) is power of 2 + ASSERT( _entriesPerBlock * sizeof( T ) == blockSize ); + + const size_t prefixZoneCount = RoundUpToNextBoundaryT( retainOffset, _entriesPerBlock ); + + // Add another retain offset here because we space for retained entries at the start and at the end + const size_t allocCount = prefixZoneCount + RoundUpToNextBoundaryT( _entriesPerBlock + maxLength + retainOffset, _entriesPerBlock ); + + _loadBuffer[0] = allocator.CAlloc( allocCount, blockSize ) + prefixZoneCount; + _loadBuffer[1] = allocator.CAlloc( allocCount, blockSize ) + prefixZoneCount; + } + + //----------------------------------------------------------- + BlockReader() + {} + + // #NOTE: User is responsible for using a Fence after this call + //----------------------------------------------------------- + void LoadEntries( uint64 count ) + { + ASSERT( _loadIdx >= _readIdx ); + ASSERT( _loadIdx - _readIdx <= 2 ); + ASSERT( count ); + + const uint32 loadIdx = _loadIdx & 1; // % 2 + const uint32 preloadIdx = _loadIdx & 3; // % 4 + + // Substract entries that are already pre-loaded + const uint64 numPreloaded = _preloadedEntries[preloadIdx]; + + if( numPreloaded ) + { + count -= std::min( count, numPreloaded ); + + if( count == 0 ) + { + // #TODO: Test this scenario, have not hit it during testing. + // <= than our preloaded entries were requested. + // Move any left-over preloaded entries to the next load + _preloadedEntries[(_loadIdx+1) & 3] = numPreloaded - count; + _copyCount[loadIdx] = numPreloaded - count; + _loadCount[loadIdx] = 0; + return; + } + } + + T* buffer = _loadBuffer[loadIdx] + _entriesPerBlock; + + const uint64 loadCount = RoundUpToNextBoundaryT( count, _entriesPerBlock ); + + _ioQueue->ReadFile( _fileId, 0, buffer, loadCount * sizeof( T ) ); + _ioQueue->CommitCommands(); + + const uint64 overflowCount = loadCount - count; + + _loadCount[loadIdx] = loadCount; + _copyCount[loadIdx] = overflowCount; + + // Save overflow as preloaded entries for the next load + _loadIdx++; + _preloadedEntries[_loadIdx & 3] = overflowCount; + } + + //----------------------------------------------------------- + T* ReadEntries() + { + const uint32 readIdx = _readIdx & 1; + + const uint64 copyCount = _copyCount[readIdx]; + const uint64 loadedCount = _loadCount[readIdx]; + const uint64 preloaded = GetPreloadedEntryCount(); + + T* buffer = _loadBuffer[readIdx] + _entriesPerBlock - preloaded; + + // Copy any overflow entries we may have loaded to the next buffer + if( copyCount ) + { + const uint64 entryCount = preloaded + loadedCount; + T* dst = _loadBuffer[(readIdx + 1) & 1] + _entriesPerBlock - copyCount; + memcpy( dst, buffer + entryCount - copyCount, copyCount * sizeof( T ) ); + } + + _readIdx++; + return buffer; + } + +private: + //----------------------------------------------------------- + inline uint64 GetPreloadedEntryCount() + { + return _preloadedEntries[_readIdx & 3]; // % 4 + } + +private: + FileId _fileId = FileId::None; + uint64 _entriesPerBlock = 0; + DiskBufferQueue* _ioQueue = nullptr; + T* _loadBuffer [2] = { nullptr }; + uint64 _loadCount [2] = { 0 }; // How many entries actually loaded from disk + uint64 _copyCount [2] = { 0 }; // Trailing entries to copy over to the next buffer + uint64 _preloadedEntries[4] = { 0 }; // Overflow entries already loaded by the previous load (due to alignment), kept for the next load + // We use 4-sized array for this so that each load can safely store the read count without overwrites. + uint32 _loadIdx = 0; + uint32 _readIdx = 0; +}; + +template +class IP3LMapReader +{ +public: + virtual void LoadNextBucket() = 0; + virtual T* ReadLoadedBucket() = 0; +}; + +/// Utility for reading maps for P3 where the left table buckets +/// have to load more entries than the bucket has in order to allow +/// the pairs to point correctly to cross-bucket entries. +/// The extra entries loaded from the next bucket have to be carried over +/// to the start of the bucket of the next load. +template +class SingleFileMapReader : public IP3LMapReader +{ +public: + //----------------------------------------------------------- + SingleFileMapReader() {} + + //----------------------------------------------------------- + SingleFileMapReader( const FileId fileId, DiskBufferQueue* ioQueue, IAllocator& allocator, + const uint64 maxLength, const size_t blockSize, + const uint32 bucketCounts[_numBuckets] ) + : _reader( fileId, ioQueue, maxLength, allocator, blockSize, _retainCount ) + { + memcpy( _bucketCounts, bucketCounts, sizeof( _bucketCounts ) ); + } + + //----------------------------------------------------------- + void LoadNextBucket() override + { + ASSERT( _bucketsLoaded < _numBuckets ); + + const uint64 bucketLength = _bucketCounts[_bucketsLoaded]; + const uint64 loadCount = _bucketsLoaded == 0 ? bucketLength + _retainCount : + _bucketsLoaded == _numBuckets - 1 ? bucketLength - _retainCount : + bucketLength; + + _reader.LoadEntries( loadCount ); + _bucketsLoaded++; + } + + //----------------------------------------------------------- + T* ReadLoadedBucket() override + { + T* entries = _reader.ReadEntries(); + T* dstEntries = entries; + + if( _bucketsRead > 0 ) + { + // Copy over the retained entries from the last buffer + dstEntries -= _retainCount; + memcpy( dstEntries, _retainedEntries, _retainCount * sizeof( uint32 ) ); + } + + if( _bucketsRead < _numBuckets - 1 ) + { + // Retain our last entries for the next buffer + const uint64 entryCount = _bucketCounts[_bucketsRead] + ( _bucketsRead == 0 ? _retainCount : 0 ); + + memcpy( _retainedEntries, entries + entryCount - _retainCount, _retainCount * sizeof( uint32 ) ); + } + + _bucketsRead++; + return dstEntries; + } + +private: + BlockReader _reader; + uint32 _bucketsLoaded = 0; + uint32 _bucketsRead = 0; + uint32 _bucketCounts [_numBuckets ]; + T _retainedEntries[_retainCount]; +}; + + +#pragma GCC diagnostic pop + diff --git a/src/plotdisk/DiskPlotBounded.cpp b/src/plotdisk/DiskPlotBounded.cpp new file mode 100644 index 00000000..9955bb58 --- /dev/null +++ b/src/plotdisk/DiskPlotBounded.cpp @@ -0,0 +1,202 @@ +#include "DiskPlotBounded.h" +#include "util/Util.h" +#include "util/StackAllocator.h" +#include "pos/chacha8.h" +#include "threading/MTJob.h" +#include "plotdisk/DiskPlotInfo.h" +#include "plotdisk/DiskPlotContext.h" +#include "plotdisk/DiskPlotConfig.h" +#include "plotdisk/DiskBufferQueue.h" +#include "plotting/PlotTools.h" + + +template +class K32BoundedF1 +{ + using Job = AnonPrefixSumJob; + + static constexpr uint32 _k = 32; + static constexpr uint64 _kEntryCount = 1ull << _k; + static constexpr uint32 _entriesPerBucket = (uint32)( _kEntryCount / _numBuckets ); + static constexpr uint32 _entriesPerBlock = kF1BlockSize / sizeof( uint32 ); + static constexpr uint32 _blocksPerBucket = _entriesPerBucket * sizeof( uint32 ) / kF1BlockSize; + +public: + //----------------------------------------------------------- + K32BoundedF1( DiskPlotContext& context, IAllocator& allocator ) + : _context( context ) + , _ioQueue( *context.ioQueue ) + , _writeFence( context.fencePool->RequireFence() ) + { + const uint32 threadCount = context.f1ThreadCount; + + // Get the maximum block count per thread + uint32 blockCount, _; + GetThreadOffsets( threadCount-1, threadCount, _blocksPerBucket, blockCount, _, _ ); + + const uint32 blockBufferSize = blockCount * threadCount * _entriesPerBlock; + _blockBuffer = allocator.CAllocSpan( blockBufferSize ); + + _yEntries[0] = allocator.CAlloc( _entriesPerBucket ); + _yEntries[1] = allocator.CAlloc( _entriesPerBucket ); + _xEntries[0] = allocator.CAlloc( _entriesPerBucket ); + _xEntries[1] = allocator.CAlloc( _entriesPerBucket ); + } + + //----------------------------------------------------------- + void Run() + { + Job::Run( *_context.threadPool, _context.f1ThreadCount, [=]( Job* self ) { + + byte key[BB_PLOT_ID_LEN] = { 1 }; + memcpy( key + 1, _context.plotId, BB_PLOT_ID_LEN-1 ); + + chacha8_ctx chacha; + chacha8_keysetup( &chacha, key, 256, nullptr ); + + uint32 blockCount, blockOffset, _; + GetThreadOffsets( self, _blocksPerBucket, blockCount, blockOffset, _ ); + + auto blocks = _blockBuffer.Slice( blockOffset * _entriesPerBlock, blockCount * _entriesPerBlock ); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + // Calculate f1 blocks + chacha8_get_keystream( &chacha, blockOffset, blockCount, (byte*)blocks.Ptr() ); + + // Write blocks to disk buckets + WriteToBuckets( self, blockCount, blockOffset * _entriesPerBlock ); + + blockOffset += _blocksPerBucket; // Offset to block start at next bucket + } + }); + } + +private: + //----------------------------------------------------------- + void WriteToBuckets( const uint32 bucket, Job* self, const uint32* blocks, const uint32 blockCount, const uint32 xStart ) + { + const uint32 entriesPerBlock = kF1BlockSize / sizeof( uint32 ); + const uint32 entryCount = blockCount * entriesPerBlock; + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 bucketBitShift = _k - bucketBits; + const uint32 kMinusKExtraBits = _k - kExtraBits; + + // Distribute to buckets + uint32 counts [_numBuckets] = { 0 }; + uint32 pfxSum [_numBuckets]; + uint32 totalCounts[_numBuckets]; + +// memset( counts, 0, sizeof( counts ) ); + + for( uint32 i = 0; i < entryCount; i++ ) + counts[Swap32( blocks[i] ) >> bucketBitShift]++; + + self->CalculatePrefixSum( _numBuckets, counts, pfxSum, totalCounts ); + + const uint32 yBits = _k + kExtraBits - bucketBits; + const uint32 yMask = (uint32)(( 1ull << yBits ) - 1); + + Span yEntries, xEntries, elementCounts; + GetNextBuffer( self, bucket, yEntries, xEntries, elementCounts ); + + // Distribute slices to buckets + for( uint32 i = 0; i < entryCount; i++ ) + { + uint32 y = Swap32( blocks[i] ); + const uint32 dst = --pfxSum[y >> bucketBitShift]; + const uint32 x = xStart + i; + + y = ( ( y << kExtraBits ) | ( x >> kMinusKExtraBits ) ) & yMask; + + yEntries[dst] = y; + xEntries[dst] = x; + } + + // Write to disk + if( self->BeginLockBlock() ) + { + memcpy( elementCounts.Ptr(), totalCounts, sizeof( totalCounts ) ); + + _ioQueue.WriteBucketElementsT( FileId::Y , yEntries.Ptr(), elementCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( FileId::META, xEntries.Ptr(), elementCounts.Ptr() ); + _ioQueue.SignalFence( _writeFence, bucket+1 ); + _ioQueue.CommitCommands(); + + for( uint32 i = 0; i < _numBuckets; i++ ) + _context.bucketCounts[(int)TableId::Table1][i] += totalCounts[i]; + } + self->EndLockBlock(); + } + + //----------------------------------------------------------- + void GetNextBuffer( Job* self, const uint32 bucket, Span& yEntries, Span& xEntries, Span& totalCounts ) + { + if( bucket >= 2 && _writeFence.Value() < bucket-1 ) + { + if( self->BeginLockBlock() ) + _writeFence.Wait( bucket - 1, _context.p1TableWaitTime[(int)TableId::Table1] ); + + self->EndLockBlock(); + } + + const uint32 entriesPerBucket = (uint32)( _kEntryCount / _numBuckets ); + yEntries = Span( _yEntries[bucket & 1], entriesPerBucket ); + xEntries = Span( _xEntries[bucket & 1], entriesPerBucket ); + totalCounts = Span( _elementCounts[bucket & 1], _numBuckets ); + } + +private: + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; + Fence& _writeFence; + Span _blockBuffer; + + // I/O buffers + uint32* _yEntries [2]; + uint32* _xEntries [2]; + uint32 _elementCounts[2][_numBuckets] = {}; +}; + +template +class K32BoundedPhase1 +{ + //----------------------------------------------------------- + K32BoundedPhase1( DiskPlotContext& context ) + : _context( context ) + , _ioQueue( _ioQueue ) + { + // Open files + FileSetOptions opts = FileSetOptions::None; + FileSetInitData data = {}; + + opts = FileSetOptions::UseTemp2; + _ioQueue.InitFileSet( FileId::Y , "y" , _numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::META, "meta", _numBuckets, opts, &data ); + } + + //----------------------------------------------------------- + void Run() + { + Log::Line( "Table 1: F1 generation" ); + + { + StackAllocator allocator( _context.heapBuffer, _context.heapSize ); + K32BoundedF1<_numBuckets> f1( _context, allocator ); + f1.Run(); + } + + Fx(); + } + + //----------------------------------------------------------- + void Fx() + { + + } + +private: + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; +}; + diff --git a/src/plotdisk/DiskPlotBounded.h b/src/plotdisk/DiskPlotBounded.h new file mode 100644 index 00000000..798e13d6 --- /dev/null +++ b/src/plotdisk/DiskPlotBounded.h @@ -0,0 +1,4 @@ +#pragma once + +// Bounded disk plotter + diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h new file mode 100644 index 00000000..8fa89c4a --- /dev/null +++ b/src/plotdisk/DiskPlotConfig.h @@ -0,0 +1,74 @@ +#pragma once +#include "ChiaConsts.h" + +#define BB_DP_MAX_JOBS 256u + +#define BB_DP_BUCKET_COUNT ( 1u << kExtraBits ) // 64 with kExtraBits == 6 // #TODO: Remove this and make buckets configurable + +#define BB_DP_MIN_BUCKET_COUNT 128 // Below 128 we can't fit y+map in a qword. +#define BB_DP_MAX_BUCKET_COUNT 1024 + +#define BB_DP_ENTRIES_PER_BUCKET ( ( 1ull << _K ) / BB_DP_BUCKET_COUNT ) +#define BB_DP_XTRA_ENTRIES_PER_BUCKET 1.1 + + +#define BB_DP_MAX_BC_GROUP_PER_BUCKET 300000 // There's around 284,190 groups per bucket (of bucket size 64) +#define BB_DP_MAX_BC_GROUP_PER_K_32 (BB_DP_MAX_BC_GROUP_PER_BUCKET * 64ull) +#define BB_DP_XTRA_MATCHES_PER_THREAD 1024 + +// How many extra entries to load from the next bucket to ensure we have enough to hold the 2 groups's +// worth of entries. This is so that we can besure that we can complete matches from groups from the previous +// bucket that continue on to the next bucket. There's around 280-320 entries per group on k32. This should be enough +#define BB_DP_CROSS_BUCKET_MAX_ENTRIES 768 + +// Pretty big right now, but when buckets == 1024 it is needed. +// Might change it to dynamic. +#define BB_DISK_QUEUE_MAX_CMDS (4096*8) //1024 + +// Use at 256 buckets for line points so that +// we can save 1 iteration when sorting it. +#define BB_DPP3_LP_BUCKET_COUNT 256 + + +/// +/// DEBUG +/// +// #define BB_DP_DBG_READ_EXISTING_F1 1 +// #define BB_DP_DBG_VALIDATE_F1 1 +// #define BB_DP_DBG_VALIDATE_FX 1 +// #define BB_DP_DBG_VALIDATE_META 1 +// #define BB_DP_DBG_PROTECT_FP_BUFFERS 1 + +// #define BB_DP_DBG_DONT_DELETE_TMP_FILES_PHASE 3 + +#define BB_DP_DBG_READ_BUCKET_COUNT_FNAME "bucket_count.tmp" +#define BB_DP_TABLE_COUNTS_FNAME "table_counts.tmp" +#define BB_DP_DBG_PTR_BUCKET_COUNT_FNAME "ptr_bucket_count.tmp" + +#define BB_DP_DBG_TEST_DIR "/mnt/p5510a/disk_dbg/" +#define BB_DP_DBG_REF_DIR "/mnt/p5510a/reference/" + +// #define BB_DP_DBG_SKIP_PHASE_1 1 +// #define BB_DP_DBG_SKIP_PHASE_2 1 + +// Skip all of Phase 1 except the C tables writing. +// #NOTE: BB_DP_DBG_SKIP_PHASE_1 Must be defined +// #define BB_DP_DBG_SKIP_TO_C_TABLES 1 + +// #define BB_DP_P1_SKIP_TO_TABLE 1 +// #define BB_DP_P1_START_TABLE TableId::Table7 + +// Tmp file deletion (useful to keep around when developing) +#if _DEBUG + // #define BB_DP_P1_KEEP_FILES 1 + // #define BB_DP_P3_KEEP_FILES 1 +#endif + + +#if _DEBUG + // Skip Phase 3 to the specific table (must have the files on disk ready) + // #define BB_DBG_SKIP_P3_S1 1 + // #define BB_DP_DBG_P3_START_TABLE Table7 + + // #define BB_DP_DBG_P3_KEEP_FILES 1 +#endif \ No newline at end of file diff --git a/src/plotdisk/DiskPlotContext.h b/src/plotdisk/DiskPlotContext.h new file mode 100644 index 00000000..c56a1d41 --- /dev/null +++ b/src/plotdisk/DiskPlotContext.h @@ -0,0 +1,90 @@ +#pragma once +#include "DiskPlotConfig.h" +#include "DiskBufferQueue.h" +#include "threading/ThreadPool.h" +#include "threading/MTJob.h" +#include "plotting/PlotTypes.h" +#include "plotting/Tables.h" +#include "ChiaConsts.h" + +struct GlobalPlotConfig; + +struct DiskPlotConfig +{ + GlobalPlotConfig* globalCfg = nullptr; + const char* tmpPath = nullptr; + const char* tmpPath2 = nullptr; + size_t expectedTmpDirBlockSize = 0; + uint32 numBuckets = 256; + uint32 ioThreadCount = 0; + uint32 ioBufferCount = 0; + size_t cacheSize = 0; + + bool noTmp1DirectIO = false; // Disable direct I/O on tmp 1 + bool noTmp2DirectIO = false; // Disable direct I/O on tmp 1 + + uint32 f1ThreadCount = 0; + uint32 fpThreadCount = 0; + uint32 cThreadCount = 0; + uint32 p2ThreadCount = 0; + uint32 p3ThreadCount = 0; +}; + +struct DiskPlotContext +{ + const DiskPlotConfig* cfg; + + const char* tmpPath; // Path in which to allocate temporary buffers + const char* tmpPath2; // Path to store fx files and other high R/W files. + + size_t tmp1BlockSize; + size_t tmp2BlockSize; + + ThreadPool* threadPool; + DiskBufferQueue* ioQueue; + FencePool* fencePool; + + size_t heapSize; // Size in bytes of our working heap. + byte* heapBuffer; // Buffer allocated for in-memory work + + size_t cacheSize; // Size of memory cache to reserve for IO (region in file that never gets written to disk). + byte* cache; + + uint32 numBuckets; // Divide entries into this many buckets + + uint32 ioThreadCount; // How many threads to use for the disk buffer writer/reader + uint32 f1ThreadCount; // How many threads to use for f1 generation + uint32 fpThreadCount; // How many threads to use for forward propagation + uint32 cThreadCount; // How many threads to use for C3 park writing and compression + uint32 p2ThreadCount; // How many threads to use for Phase 2 + uint32 p3ThreadCount; // How many threads to use for Phase 3 + + const byte* plotId; + const byte* plotMemo; + uint16 plotMemoSize; + + uint32 bucketCounts[(uint)TableId::_Count][BB_DP_MAX_BUCKET_COUNT+1]; + uint64 entryCounts [(uint)TableId::_Count]; + + // Since back pointer table entries are not sorted along with y, + // (instead we use a mapping table), and since their values are stored + // in local-to-bucket coordinates, we need to know how many entries + // were generated given an L table bucket. + // This stores how many R entries were generated given an L table bucket, + // including the cross-bucket entries. + uint32 ptrTableBucketCounts[(uint)TableId::_Count][BB_DP_MAX_BUCKET_COUNT]; + + // Pointers to tables in the plot file (byte offset to where it starts in the plot file) + // Where: + // 0-6 = Parked tables 1-7 + // 7-9 = C1-C3 tables + uint64 plotTablePointers[10]; + uint64 plotTableSizes [10]; + + Duration ioWaitTime; // Total Plot I/O wait time + Duration p1TableWaitTime[(uint)TableId::_Count]; // Phase 1 per-table I/O wait time + Duration p2TableWaitTime[(uint)TableId::_Count]; // Phase 2 per-table I/O wait time + Duration p3TableWaitTime[(uint)TableId::_Count]; // Phase 3 per-table I/O wait time + Duration cTableWaitTime; + Duration p7WaitTime; +}; diff --git a/src/plotdisk/DiskPlotDebug.cpp b/src/plotdisk/DiskPlotDebug.cpp new file mode 100644 index 00000000..19263132 --- /dev/null +++ b/src/plotdisk/DiskPlotDebug.cpp @@ -0,0 +1,622 @@ +#include "DiskPlotDebug.h" +#include "io/FileStream.h" +#include "threading/ThreadPool.h" +#include "threading/AutoResetSignal.h" +#include "algorithm/RadixSort.h" +#include "util/Util.h" +#include "util/Log.h" +#include "jobs/IOJob.h" +#include "DiskPlotContext.h" +#include "DiskBufferQueue.h" + +#define BB_DBG_WRITE_LP_BUCKET_COUNTS 1 + +// #define BB_DBG_READ_LP_BUCKET_COUNTS 1 + +//----------------------------------------------------------- +void Debug::ValidateYFileFromBuckets( FileId yFileId, ThreadPool& pool, DiskBufferQueue& queue, TableId table, + uint32 bucketCounts[BB_DP_BUCKET_COUNT] ) +{ + // const size_t bucketMaxCount = BB_DP_MAX_ENTRIES_PER_BUCKET; + + // uint64 refEntryCount = 0; + // uint64* refEntries = nullptr; + + // // Read the whole reference table into memory + // Log::Line( "Loading reference table..." ); + // { + // char path[1024]; + // sprintf( path, "%st%d.y.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); + + // FileStream refTable; + // FatalIf( !refTable.Open( path, FileMode::Open, FileAccess::Read, FileFlags::LargeFile | FileFlags::NoBuffering ), + // "Failed to open reference table file %s.", path ); + + // const size_t blockSize = refTable.BlockSize(); + // const uint64 maxEntries = 1ull << _K; + + // const size_t allocSize = (size_t)maxEntries * sizeof( uint64 ); + + // byte* block = bbvirtalloc( blockSize ); + // refEntries = bbvirtalloc( allocSize ); + + // // The first block contains the entry count + // FatalIf( !refTable.Read( refEntries, blockSize ), + // "Failed to read count from reference table file %s with error: %d.", path, refTable.GetError() ); + + // refEntryCount = *refEntries; + // if( table == TableId::Table1 ) + // ASSERT( refEntryCount == maxEntries ); + + // ASSERT( refEntryCount <= maxEntries ); + + // const size_t totalSize = RoundUpToNextBoundaryT( (size_t)refEntryCount * ( table == TableId::Table7 ? sizeof( uint32 ) : sizeof( uint64 ) ), blockSize ); + // const size_t blockSizeToRead = totalSize / blockSize * blockSize; + // const size_t remainder = totalSize - blockSizeToRead; + + // // Read blocks + // size_t sizeToRead = blockSizeToRead; + // byte* reader = (byte*)refEntries; + // while( sizeToRead ) + // { + // // The rest of the blocks are entries + // const ssize_t sizeRead = refTable.Read( reader, sizeToRead ); + // if( sizeRead < 1 ) + // { + // const int err = refTable.GetError(); + // Fatal( "Failed to read entries from reference table file %s with error: %d.", path, err ); + // } + + // sizeToRead -= (size_t)sizeRead; + // reader += sizeRead; + // } + + // if( remainder ) + // { + // if( refTable.Read( block, blockSize ) != (ssize_t)blockSize ) + // { + // const int err = refTable.GetError(); + // Fatal( "Failed to read entries from reference table file %s with error: %d.", path, err ); + // } + + // // ASSERT( blockSizeToRead / sizeof( uint64 ) + remainder / sizeof( uint64 ) == refEntryCount ); + // memcpy( reader, block, remainder ); + // } + + // SysHost::VirtualFree( block ); + // } + + + // // Alloc a buffer for our buckets + // const size_t bucketAllocSize = RoundUpToNextBoundaryT( sizeof( uint32 ) * (size_t)BB_DP_MAX_ENTRIES_PER_BUCKET, queue.BlockSize() ); + // uint32* bucketEntries = bbvirtalloc( bucketAllocSize ); + // uint32* bucketSortTmp = bbvirtalloc( bucketAllocSize ); + + // Fence fence; + + // // Load the first bucket + // queue.SeekBucket( yFileId, 0, SeekOrigin::Begin ); + // queue.ReadFile( yFileId, 0, bucketEntries, bucketCounts[0] * sizeof( uint32 ) ); + // queue.SignalFence( fence ); + // queue.CommitCommands(); + + // fence.Wait(); + // fence.Signal(); // Set as signaled initially since we wait for the next bucket in the loop + + // const uint64* refReader = refEntries; + // const uint32* f7Reader = (uint32*)refEntries; + + // for( uint bucket = 0; bucket < BB_DP_BUCKET_COUNT; bucket++ ) + // { + // Log::Line( "Bucket %u", bucket ); + + // // Wait for the next bucket to be loaded + // fence.Wait(); + + // const int64 entryCount = bucketCounts[bucket]; + + // // Sort the bucket + // // if( table < TableId::Table7 ) + // { + // Log::Line( " Sorting bucket..." ); + // RadixSort256::Sort( pool, bucketEntries, bucketSortTmp, (uint64)entryCount ); + // } + + // // Load the next bucket + // const uint nextBucket = bucket + 1; + + // if( nextBucket < BB_DP_BUCKET_COUNT ) + // { + // queue.ReadFile( yFileId, nextBucket, bucketSortTmp, bucketCounts[nextBucket] * sizeof( uint32 ) ); + // queue.SignalFence( fence ); + // queue.CommitCommands(); + // } + + // // Start validating + // Log::Line( " Validating entries..."); + // if( table < TableId::Table7 ) + // { + // const uint64 bucketMask = ((uint64)bucket) << 32; + // uint64 prevRef = 0; + + // for( int64 i = 0; i < entryCount; i++, refReader++ ) + // { + // const uint64 y = bucketMask | bucketEntries[i]; + // const uint64 yRef = *refReader; + + // // Test for now, since we're not getting all of the reference values in some tables... + // if( yRef < prevRef ) + // break; + // prevRef = yRef; + // // if( y == 112675641563 ) BBDebugBreak(); + + // // const uint32 y32 = bucketEntries[i]; + // // const uint32 y32Ref = (uint32)yRef; + + // FatalIf( y != yRef, + // "Failed to validate entry on table %d at bucket position %u:%lld | Global position: %lld.\n" + // " Expected %llu but got %llu", + // (int)table+1, bucket, i, (int64)( refReader - refEntries ), yRef, y ); + // } + // } + // else + // { + // const uint32* refEnd = f7Reader + refEntryCount; + + // for( int64 i = 0; i < entryCount && f7Reader < refEnd; i++, f7Reader++ ) + // { + // const uint32 y = bucketEntries[i]; + // const uint32 yRef = *f7Reader; + + // FatalIf( y != yRef, + // "Failed to validate entry on table %d at bucket position %u:%lld | Global position: %lld.\n" + // " Expected %lu but got %lu", + // (int)table+1, bucket, i, (int64)( refReader - refEntries ), yRef, y ); + // } + // } + + // Log::Line( " Bucket %u validated successfully!", bucket ); + + // // Swap bucket buffers + // std::swap( bucketEntries, bucketSortTmp ); + // } + + // Log::Line( "Table %d y values validated successfully.", (int)table+1 ); + + // // Restore files to their position, just in case + // queue.SeekBucket( yFileId, 0, SeekOrigin::Begin ); + // queue.SignalFence( fence ); + // queue.CommitCommands(); + // fence.Wait(); + + + // SysHost::VirtualFree( refEntries ); + // SysHost::VirtualFree( bucketEntries ); +} + +//----------------------------------------------------------- +void Debug::ValidateMetaFileFromBuckets( const uint64* metaABucket, const uint64* metaBBucket, + TableId table, uint32 entryCount, uint32 bucketIdx, + uint32 bucketCounts[BB_DP_BUCKET_COUNT] ) +{ + size_t refEntrySize = 0; + uint32 metaMultiplier = 0; + size_t refMetaTableSize = 0; + uint64 refEntryCount = 0; + uint64* refEntries = nullptr; + + Log::Line( "Validating metadata for table %d...", (int)table+1 ); + + switch( table ) + { + case TableId::Table2: metaMultiplier = TableMetaOut::Multiplier; break; + case TableId::Table3: metaMultiplier = TableMetaOut::Multiplier; break; + case TableId::Table4: metaMultiplier = TableMetaOut::Multiplier; break; + case TableId::Table5: metaMultiplier = TableMetaOut::Multiplier; break; + case TableId::Table6: metaMultiplier = TableMetaOut::Multiplier; break; + default: + Fatal( "Invalid table specified for metadata verification." ); + break; + } + + // Reference stores 3*4 multiplier as 4*4 + if( metaMultiplier == 3 ) + metaMultiplier = 4; + + refEntrySize = metaMultiplier * 4; + + // Read the whole reference table into memory + Log::Line( "Loading reference table..." ); + { + char path[1024]; + sprintf( path, BB_DP_DBG_REF_DIR "meta%d.tmp", (int)table+1 ); + + FileStream refTable; + FatalIf( !refTable.Open( path, FileMode::Open, FileAccess::Read, FileFlags::LargeFile | FileFlags::NoBuffering ), + "Failed to open reference meta table file %s.", path ); + + const uint64 maxEntries = 1ull << _K; + const size_t blockSize = refTable.BlockSize(); + const size_t allocSize = (size_t)maxEntries * refEntrySize; + + byte* block = bbvirtalloc( blockSize ); + refEntries = bbvirtalloc( allocSize ); + + // The first block contains the entry count + FatalIf( !refTable.Read( refEntries, blockSize ), + "Failed to read count from reference table file %s with error: %d.", path, refTable.GetError() ); + + refMetaTableSize = *refEntries; + refEntryCount = refMetaTableSize / refEntrySize; + + ASSERT( refMetaTableSize <= allocSize ); + ASSERT( refEntryCount <= maxEntries ); + + const size_t blockSizeToRead = refMetaTableSize / blockSize * blockSize; + const size_t remainder = refMetaTableSize - blockSizeToRead; + + // Read blocks + size_t sizeToRead = blockSizeToRead; + byte* reader = (byte*)refEntries; + while( sizeToRead ) + { + // The rest of the blocks are entries + const ssize_t sizeRead = refTable.Read( reader, sizeToRead ); + if( sizeRead < 1 ) + { + const int err = refTable.GetError(); + Fatal( "Failed to read entries from reference table file %s with error: %d.", path, err ); + } + + sizeToRead -= (size_t)sizeRead; + reader += sizeRead; + } + + if( remainder ) + { + if( refTable.Read( block, blockSize ) != (ssize_t)blockSize ) + { + const int err = refTable.GetError(); + Fatal( "Failed to read entries from reference table file %s with error: %d.", path, err ); + } + + memcpy( reader, block, remainder ); + } + + SysHost::VirtualFree( block ); + } + + + // Test + Log::Line( "Validating Bucket %u", bucketIdx ); + + if( metaMultiplier == 2 ) + { + const uint64* refReader = refEntries; + + // Get reader offset based on bucket + for( uint i = 0; i < bucketIdx; i++ ) + refReader += bucketCounts[i]; + + for( int64 i = 0; i < entryCount; i++, refReader++ ) + { + const uint64 metaA = metaABucket[i]; + const uint64 metaRef = *refReader; + + // FatalIf( metaA != metaRef, + // "Failed to validate entry on table %d at bucket position %u:%lld | Global position: %lld.\n" + // " Expected %llu but got %llu", + // (int)table+1, bucketIdx, i, (int64)( refReader - refEntries ), metaRef, metaA ); + if( metaA != metaRef ) + { + // Because the y that generated the meta might be repeated, when we sort + // we might get metadata that is not matching because it is out of order. + // We test for those cases here in the case that there's a 2-way mismatch. + // If the y repeates more than 2 times and we have a mismatch, we won't test for + // it and just consider it as an error for manual checking. + + if( metaABucket[i+1] == metaRef && + metaA == refReader[1] ) + { + // Mismatched pair, skip the next one. + // Skip the next + i++; + refReader++; + continue; + } + + Log::Line( "Failed to validate entry on table %d at bucket position %u:%lld | Global position: %lld.\n" + " Expected %llu but got %llu", + (int)table+1, bucketIdx, i, (int64)( refReader - refEntries ), metaRef, metaA ); + + } + } + } + else if( metaMultiplier == 4 ) + { + struct Meta4 { uint64 a, b; }; + + const Meta4* refReader = (Meta4*)refEntries; + + // Get reader offset based on bucket + for( uint i = 0; i < bucketIdx; i++ ) + refReader += bucketCounts[i]; + + for( int64 i = 0; i < entryCount; i++, refReader++ ) + { + const uint64 metaA = metaABucket[i]; + const uint64 metaB = metaBBucket[i]; + const uint64 metaARef = refReader->a; + const uint64 metaBRef = refReader->b; + + // FatalIf( metaA != metaRef, + // "Failed to validate entry on table %d at bucket position %u:%lld | Global position: %lld.\n" + // " Expected %llu but got %llu", + // (int)table+1, bucketIdx, i, (int64)( refReader - refEntries ), metaRef, metaA ); + if( metaA != metaARef || metaB != metaBRef ) + { + // Because the y that generated the meta might be repeated, when we sort + // we might get metadata that is not matching because it is out of order. + // We test for those cases here in the case that there's a 2-way mismatch. + // If the y repeates more than 2 times and we have a mismatch, we won't test for + // it and just consider it as an error for manual checking. + + if( metaABucket[i+1] == metaARef && metaA == refReader[1].a && + metaBBucket[i+1] == metaBRef && metaB == refReader[1].b ) + { + // Mismatched pair, skip the next one. + // Skip the next + i++; + refReader++; + continue; + } + + const intptr_t globalPos = ((intptr_t)refReader - (intptr_t)refEntries) / (intptr_t)sizeof( Meta4 ); + + Log::Line( "Failed to validate entry on table %d at bucket position %u:%lld | Global position: %lld.\n" + " Expected A:%llu but got A:%llu\n" + " Expected B:%llu but got B:%llu", + (int)table+1, bucketIdx, i, + globalPos, metaARef, metaA, metaBRef, metaB ); + + } + } + } + + Log::Line( "Table %d meta values validated successfully.", (int)table+1 ); + + SysHost::VirtualFree( refEntries ); +} + +// Ensure we have an ordered lookup index +//----------------------------------------------------------- +void Debug::ValidateLookupIndex( TableId table, ThreadPool& pool, DiskBufferQueue& queue, const uint32 bucketCounts[BB_DP_BUCKET_COUNT] ) +{ + uint64 totalEntries = 0; + for( uint32 i = 0; i < BB_DP_BUCKET_COUNT; i++ ) + totalEntries += bucketCounts[i]; + + // Lod buckets into a single contiguous bucket + uint32* indices = bbcvirtalloc( RoundUpToNextBoundary( totalEntries, (int)queue.BlockSize() ) * 2 ); + + Log::Line( "Loading table %d lookup indices...", (int)table ); + { + const FileId fileId = TableIdToSortKeyId( table ); + + uint32* readPtr = indices; + + queue.SeekBucket( fileId, 0, SeekOrigin::Begin ); + queue.CommitCommands(); + + for( uint32 bucket = 0; bucket < BB_DP_BUCKET_COUNT; bucket++ ) + { + queue.ReadFile( fileId, bucket, readPtr, bucketCounts[bucket] * sizeof( uint32 ) ); + readPtr += bucketCounts[bucket]; + } + + Fence fence; + queue.SignalFence( fence ); + queue.SeekBucket( fileId, 0, SeekOrigin::Begin ); + queue.CommitCommands(); + fence.Wait(); + } + + // Check counts per bucket, before sort + uint32 bcounts[BB_DP_BUCKET_COUNT]; + { + memset( bcounts, 0, sizeof( bcounts ) ); + + const uint32* reader = indices; + + for( uint32 bucket = 0; bucket < BB_DP_BUCKET_COUNT; bucket++ ) + { + const uint32 bucketEntryCount = bucketCounts[bucket]; + + for( uint32 i = 0; i < bucketEntryCount; i++ ) + { + const uint b = reader[i] >> ( 32 - kExtraBits ); + ASSERT( b < BB_DP_BUCKET_COUNT ); + bcounts[b]++; + } + + reader += bucketEntryCount; + } + } + + // Sort the entries + Log::Line( "Sorting indices..." ); + RadixSort256::Sort( pool, indices, indices + totalEntries, totalEntries ); + + // Ensure all indices are ordered + Log::Line( "Validating indices..." ); + for( uint64 i = 0; i < totalEntries; i++ ) + { + ASSERT( indices[i] == i ); + } + Log::Line( "** Validation success **" ); + + // Check distribution into buckets + uint32 counts[BB_DP_BUCKET_COUNT]; + memset( counts, 0, sizeof( counts ) ); + + for( uint64 i = 0; i < totalEntries; i++ ) + { + const uint bucket = indices[i] >> ( 32 - kExtraBits ); + ASSERT( bucket < BB_DP_BUCKET_COUNT ); + counts[bucket]++; + } + + // Cleanup + SysHost::VirtualFree( indices ); +} + +//----------------------------------------------------------- +void Debug::ValidateLinePoints( DiskPlotContext& context, TableId table, uint32 bucketCounts[BB_DPP3_LP_BUCKET_COUNT] ) +{ + // Log::Line( "Validating Line points for table %u", table+1 ); + + // // Load the reference table + // uint64 refLPCount = 0; + // uint64* refLinePoints = bbcvirtalloc( 1ull << _K ); + + // byte* blockBuffer = nullptr; + + // { + // Log::Line( " Loading reference values..." ); + // char path[1024]; + // sprintf( path, "%slp.t%u.tmp", BB_DP_DBG_REF_DIR, table ); + + // FileStream file; + // FatalIf( !file.Open( path, FileMode::Open, FileAccess::ReadWrite, FileFlags::NoBuffering | FileFlags::LargeFile ), + // "Failed to open reference LP table @ %s", path ); + + // blockBuffer = bbvirtalloc( file.BlockSize() ); + + // // Read entry count + // FatalIf( file.Read( blockBuffer, file.BlockSize() ) != (ssize_t)file.BlockSize(), + // "Failed to read reference LP table entry count @ %s", path ); + + // refLPCount = *(uint64*)blockBuffer; + // int err = 0; + // FatalIf( !IOJob::ReadFromFile( file, (byte*)refLinePoints, + // refLPCount * sizeof( uint64 ), blockBuffer, file.BlockSize(), err ), + // "Failed to read LP table with error: %d : %s", err, path ); + // } + + // bool readBuckets = false; + // #if BB_DBG_READ_LP_BUCKET_COUNTS + // { + // char path[1024]; + // sprintf( path, "%slp_t%u_bucket_counts.tmp", BB_DP_DBG_TEST_DIR, table+1 ); + + // FileStream file; + // if( file.Exists( path ) ) + // { + // FatalIf( !file.Open( path, FileMode::Open, FileAccess::Read, FileFlags::None ), + // "Failed to open file %s for reading.", path ); + + // const size_t readSize = sizeof( uint32 ) * BB_DPP3_LP_BUCKET_COUNT; + // FatalIf( (ssize_t)readSize != file.Read( bucketCounts, readSize ), + // "Failed to read bucket counts for LP table file %s with error: %d.", path, file.GetError() ); + + // readBuckets = true; + // } + // } + // #endif + // #if BB_DBG_WRITE_LP_BUCKET_COUNTS + // if( !readBuckets ) + // { + // // Write This table's LP bucket counts + // Log::Line( " Writing table %d LP bucket counts...", table ); + + // char path[1024]; + // sprintf( path, "%slp_t%u_bucket_counts.tmp", BB_DP_DBG_TEST_DIR, table+1 ); + + // FileStream file; + // FatalIf( !file.Open( path, FileMode::OpenOrCreate, FileAccess::Write, FileFlags::None ), + // "Failed to open file %s for writing.", path ); + + // const size_t writeSize = sizeof( uint32 ) * BB_DPP3_LP_BUCKET_COUNT; + // FatalIf( (ssize_t)writeSize != file.Write( bucketCounts, writeSize ), + // "Failed to write bucket counts for LP table file %s with error: %d.", path, file.GetError() ); + // } + // #endif + + + // const FileId fileId = TableIdToLinePointFileId( table ); + // DiskBufferQueue& ioQueue = *context.ioQueue; + // ioQueue.SeekBucket( fileId, 0, SeekOrigin::Begin ); + // ioQueue.CommitCommands(); + + // // Should be enough for an allocation size + // uint64 lpBucketSize = ( ( 1ull << _K ) / BB_DP_BUCKET_COUNT ) * 2; + // uint64* linePoints = bbcvirtalloc( lpBucketSize ); + // uint64* lpTemp = bbcvirtalloc( lpBucketSize ); + + // Fence readFence; + // readFence.Reset( 0 ); + + // const uint64* refLP = refLinePoints; + // uint64 totalCount = 0; + + // Log::Line( " Validating buckets..." ); + // for( uint32 bucket = 0; bucket < BB_DPP3_LP_BUCKET_COUNT; bucket++ ) + // { + // uint64 entryCount = bucketCounts[bucket]; + + // Log::Write( " Bucket %2u... ", bucket ); Log::Flush(); + + // ioQueue.ReadFile( fileId, bucket, linePoints, entryCount * sizeof( uint64 ) ); + // ioQueue.SignalFence( readFence ); + // ioQueue.CommitCommands(); + + // readFence.Wait(); + + // // Sort the bucket + // RadixSort256::Sort( *context.threadPool, linePoints, lpTemp, entryCount ); + + // // Cap the entry count if we're above the ref count + // // (bladebit ram is dropping 1 entry for table 7 for some reason, have to check why.) + // if( totalCount + entryCount > refLPCount ) + // entryCount -= ( ( totalCount + entryCount ) - refLPCount ); + + // ASSERT( totalCount + entryCount <= refLPCount ); + // ASSERT( entryCount <= lpBucketSize ); + + // // Compare values + // uint64* lpReader = lpTemp; + // for( int64 i = 0; i < (int64)entryCount; i++ ) + // { + // const uint64 ref = refLP [i]; + // const uint64 lp = lpReader[i]; + // ASSERT( lp == ref ); + // } + + // refLP += entryCount; + // totalCount += entryCount; + + // Log::Line( "OK" ); + // } + + // ASSERT( totalCount == refLPCount ); + // Log::Line( "Table %u validated successfully!", table+1 ); + + // ioQueue.SeekBucket( fileId, 0, SeekOrigin::Begin ); + // ioQueue.CommitCommands(); + + // SysHost::VirtualFree( refLinePoints ); + // SysHost::VirtualFree( blockBuffer ); + // SysHost::VirtualFree( linePoints ); + // SysHost::VirtualFree( lpTemp ); +} + +//----------------------------------------------------------- +// void ValidatePark7( DiskBufferQueue& ioQueue, uint64 park7Size ) + + + + + + + + diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h new file mode 100644 index 00000000..07596edd --- /dev/null +++ b/src/plotdisk/DiskPlotDebug.h @@ -0,0 +1,438 @@ +#pragma once + +#include "plotting/Tables.h" +#include "DiskPlotConfig.h" +#include "DiskBufferQueue.h" +#include "threading/ThreadPool.h" +#include "threading/MTJob.h" +#include "plotdisk/DiskPlotInfo.h" +#include "plotdisk/DiskPlotContext.h" +#include "plotdisk/jobs/IOJob.h" +#include "io/FileStream.h" +#include "util/BitView.h" +#include "algorithm/RadixSort.h" + +class ThreadPool; +struct DiskPlotContext; + +namespace Debug +{ + void ValidateYFileFromBuckets( FileId yFileId, ThreadPool& pool, DiskBufferQueue& queue, + TableId table, uint32 bucketCounts[BB_DP_BUCKET_COUNT] ); + + void ValidateMetaFileFromBuckets( const uint64* metaA, const uint64* metaB, + TableId table, uint32 entryCount, uint32 bucketIdx, + uint32 bucketCounts[BB_DP_BUCKET_COUNT] ); + + + void ValidateLookupIndex( TableId table, ThreadPool& pool, DiskBufferQueue& queue, const uint32 bucketCounts[BB_DP_BUCKET_COUNT] ); + + void ValidateLinePoints( DiskPlotContext& context, TableId table, uint32 bucketCounts[BB_DPP3_LP_BUCKET_COUNT] ); + + template + void ValidateYForTable( const FileId fileId, DiskBufferQueue& queue, ThreadPool& pool, uint32 bucketCounts[numBuckets] ); + + template + bool LoadRefTable( const char* path, T*& buffer, uint64& outEntryCount ); + + template + bool LoadRefTableByName( const char* fileName, T*& buffer, uint64& outEntryCount ); + + void LoadRefLinePointTable( const TableId table, uint64*& buffer, uint64& outEntryCount ); + + void LoadRefLPIndexTable( const TableId table, uint32*& buffer, uint64& outEntryCount ); + + template + void ValidatePairs( DiskPlotContext& context, const TableId table ); +} + +template +inline void Debug::ValidateYForTable( const FileId fileId, DiskBufferQueue& queue, ThreadPool& pool, uint32 bucketCounts[numBuckets] ) +{ + Log::Line( "Validating table %u", table+1 ); + + uint64 refEntryCount = 0; + TYOut* yReference = nullptr; + + // Load File + { + char path[1024]; + sprintf( path, "%st%d.y.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); + Log::Line( " Loading reference table '%s'.", path ); + + FileStream file; + FatalIf( !file.Open( path, FileMode::Open, FileAccess::Read, FileFlags::LargeFile | FileFlags::NoBuffering ), + "Failed to open reference table file '%s'.", path ); + + const size_t blockSize = file.BlockSize(); + uint64* blockBuffer = (uint64*)bbvirtalloc( blockSize ); + + FatalIf( file.Read( blockBuffer, blockSize ) != (ssize_t)blockSize, + "Failed to read entry count for reference table with error: %u.", file.GetError() ); + + refEntryCount = *blockBuffer; + yReference = bbcvirtalloc( refEntryCount ); + + int err; + FatalIf( !IOJob::ReadFromFile( file, yReference, sizeof( TYOut ) * refEntryCount, blockBuffer, blockSize, err ), + "Failed to read table file with error %u.", err ); + + bbvirtfree( blockBuffer ); + } + + queue.SeekBucket( fileId, 0, SeekOrigin::Begin ); + queue.CommitCommands(); + + const size_t blockSize = queue.BlockSize( fileId ); + + using Info = DiskPlotInfo; + const size_t maxBucketEntries = (size_t)Info::MaxBucketEntries; + const size_t entrySizeBits = Info::EntrySizePackedBits; + const size_t entrySize = CDiv( RoundUpToNextBoundary( entrySizeBits, 64 ), 8 ); + const size_t bucketAllocSize = RoundUpToNextBoundaryT( entrySize * maxBucketEntries, blockSize ); + + uint64* bucketBuffers[2] = { + bbvirtalloc( bucketAllocSize ), + bbvirtalloc( bucketAllocSize ) + }; + + TYOut* entries = bbcvirtalloc( maxBucketEntries ); + TYOut* tmp = bbcvirtalloc( maxBucketEntries ); + + Fence fence; + + auto LoadBucket = [&]( const uint32 bucket ) { + + void* buffer = bucketBuffers[bucket % 2]; + + ASSERT( bucketCounts[bucket] <= maxBucketEntries ); + const size_t size = CDivT( entrySizeBits * bucketCounts[bucket], blockSize * 8 ) * blockSize; + + queue.ReadFile( fileId, bucket, buffer, size ); + queue.SignalFence( fence, bucket + 1 ); + queue.CommitCommands(); + }; + + LoadBucket( 0 ); + + const TYOut* refReader = yReference; + uint64 entriesLoaded = 0; + + std::atomic failCount = 0; + + Log::Line( " Validating buckets." ); + for( uint32 b = 0; b < numBuckets; b++ ) + { + Log::Line( "Bucket %u", b ); + + if( b + 1 < numBuckets ) + LoadBucket( b+1 ); + + fence.Wait( b+1 ); + + const uint64 bucketEntryCount = bucketCounts[b]; + + AnonMTJob::Run( pool, [&]( AnonMTJob* self ) + { + + uint64 count, offset, end; + GetThreadOffsets( self, bucketEntryCount, count, offset, end ); + // count = bucketEntryCount; offset = 0; end = bucketEntryCount; + + // Unpack entries + { + const size_t yBits = Info::YBitSize; + const size_t bump = entrySizeBits - yBits; + ASSERT( yBits <= 32 ); + + BitReader reader( bucketBuffers[b % 2], bucketEntryCount * entrySizeBits, offset * entrySizeBits ); + uint32* writer = ((uint32*)tmp) + offset; + + for( uint64 i = 0; i < count; i++ ) + { + writer[i] = (uint32)reader.ReadBits64( yBits ); + reader.Bump( bump ); + } + } + } + ); + + // Sort + RadixSort256::Sort( pool, (uint32*)tmp, (uint32*)entries, bucketEntryCount ); + + AnonMTJob::Run( pool, [&]( AnonMTJob* self ) + { + uint64 count, offset, end; + GetThreadOffsets( self, bucketEntryCount, count, offset, end ); + // count = bucketEntryCount; offset = 0; end = bucketEntryCount; + + // Expand to full entry with bucket + { + const size_t yBits = Info::YBitSize; + const uint64 bucketMask = ((uint64)b) << yBits; + + const uint32* reader = ((uint32*)tmp) + offset; + TYOut* writer = entries + offset; + + for( uint64 i = 0; i < count; i++ ) + writer[i] = (TYOut)( bucketMask | (uint64)reader[i] ); + } + + // Compare entries + const TYOut* refs = refReader; + const TYOut* ys = entries; + + for( uint64 i = offset; i < end; i++ ) + { + const TYOut ref = refs[i]; + const TYOut y = ys[i]; + + if( y != ref ) + { + if( y != refs[i+1] && ys[i+1] != ref ) + { + Log::Line( " !Entry mismatch @ %llu : %llu != %llu.", + i + entriesLoaded, ref, y ); + + ASSERT( 0 ); + failCount++; + } + i++; + } + } + } + ); + + entriesLoaded += bucketCounts[b]; + refReader += bucketEntryCount; + ASSERT( refReader <= yReference + refEntryCount ); + } + + if( failCount == 0 ) + Log::Line( "*** Table validated successfully! ***" ); + else + Log::Line( "! Validation failed with %llu / %llu entries failing. !", failCount.load(), refEntryCount ); + + bbvirtfree( bucketBuffers[0] ); + bbvirtfree( bucketBuffers[1] ); + bbvirtfree( entries ); + bbvirtfree( tmp ); +} + + +//----------------------------------------------------------- +template +inline bool Debug::LoadRefTableByName( const char* fileName, T*& buffer, uint64& outEntryCount ) +{ + char path[1024]; + sprintf( path, "%s%s", BB_DP_DBG_REF_DIR, fileName ); + Log::Line( " Loading reference line point table '%s'.", path ); + return LoadRefTable( path, buffer, outEntryCount ); +} + +//----------------------------------------------------------- +template +inline bool Debug::LoadRefTable( const char* path, T*& buffer, uint64& outEntryCount ) +{ + FileStream file; + + if( !file.Open( path, FileMode::Open, FileAccess::Read, FileFlags::NoBuffering | FileFlags::LargeFile ) ) + return false; + + const size_t blockSize = file.BlockSize(); + + uint64* block = (uint64*)bbvirtalloc( blockSize ); + ASSERT( block ); + + bool success = false; + if( file.Read( block, blockSize ) ) + { + outEntryCount = *block; + + if( buffer == nullptr ) + buffer = bbvirtalloc( RoundUpToNextBoundary( outEntryCount * sizeof( T ), (int)blockSize ) ); + + int err = 0; + success = IOJob::ReadFromFile( file, buffer, sizeof( T ) * outEntryCount, block, blockSize, err ); + } + + bbvirtfree( block ); + return success; +} + +//----------------------------------------------------------- +inline void Debug::LoadRefLinePointTable( const TableId table, uint64*& buffer, uint64& outEntryCount ) +{ + ASSERT( table < TableId::Table7 ); + + char path[1024]; + sprintf( path, "%slp.t%d.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); + Log::Line( " Loading reference line point table '%s'.", path ); + + FatalIf( !Debug::LoadRefTable( path, buffer, outEntryCount ), "Failed to load reference line point table." ); +} + +//----------------------------------------------------------- +inline void Debug::LoadRefLPIndexTable( const TableId table, uint32*& buffer, uint64& outEntryCount ) +{ + ASSERT( table < TableId::Table7 ); + + char path[1024]; + sprintf( path, "%slpmap.t%d.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); + Log::Line( " Loading reference line point index table '%s'.", path ); + + FatalIf( !Debug::LoadRefTable( path, buffer, outEntryCount ), "Failed to load reference line index map table." ); +} + +//----------------------------------------------------------- +template +inline void Debug::ValidatePairs( DiskPlotContext& context, const TableId table ) +{ + uint64 refCount = 0; + Pair* refPairs = nullptr; + + + { + char path[1024]; + sprintf( path, "%sp1.t%d.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); + Log::Line( " Loading reference table '%s'.", path ); + + FatalIf( !Debug::LoadRefTable( path, refPairs, refCount ), "Failed to load table." ); + } + + ThreadPool& pool = *context.threadPool; + + const uint64 pairCount = context.entryCounts[(int)table]; + uint64* tmpPairs = bbcvirtalloc( std::max( refCount, pairCount ) ); + + // We need to unpack the entries in such a way that we can sort the pairs in increasing order again. + auto SwapPairs = [&]( Pair* pairs, const uint64 pairCount ) { + + AnonMTJob::Run( pool, [=]( AnonMTJob* self ) { + + uint64 count, offset, endIdx; + GetThreadOffsets( self, pairCount, count, offset, endIdx ); + + Pair* src = pairs + offset; + const Pair* end = pairs + endIdx; + + do { + if( src->left == 16778218 && src->right == 16778555 ) BBDebugBreak(); + std::swap( src->left, src->right ); + } while( ++src < end ); + }); + }; + + Log::Line( "Sorting reference pairs."); + SwapPairs( refPairs, refCount ); + RadixSort256::Sort( pool, (uint64*)refPairs, tmpPairs, refCount ); + SwapPairs( refPairs, refCount ); + + Log::Line( "Loading our pairs." ); + Pair* pairs = bbcvirtalloc( pairCount ); + + const uint32 savedBits = bblog2( _numBuckets ); + const uint32 pairBits = _K + 1 - savedBits + 9; + + { + const size_t blockSize = context.ioQueue->BlockSize( FileId::T1 ); + const size_t pairReadSize = (size_t)CDiv( pairCount * pairBits, (int)blockSize*8 ) * blockSize; + const FileId rTableId = FileId::T1 + (FileId)table; + + Fence fence; + + uint64* pairBitBuffer = bbcvirtalloc( pairReadSize ); + context.ioQueue->SeekBucket( rTableId, 0, SeekOrigin::Begin ); + context.ioQueue->ReadFile( rTableId, 0, pairBitBuffer, pairReadSize ); + context.ioQueue->SignalFence( fence ); + context.ioQueue->SeekBucket( rTableId, 0, SeekOrigin::Begin ); + context.ioQueue->CommitCommands(); + + fence.Wait(); + + AnonMTJob::Run( pool, [=]( AnonMTJob* self ) { + + uint64 count, offset, end; + GetThreadOffsets( self, pairCount, count, offset, end ); + + BitReader reader( pairBitBuffer, pairCount * pairBits, offset * pairBits ); + const uint32 lBits = _K - savedBits + 1; + const uint32 rBits = 9; + + for( uint64 i = offset; i < end; i++ ) + { + const uint32 left = (uint32)reader.ReadBits64( lBits ); + const uint32 right = left + (uint32)reader.ReadBits64( rBits ); + pairs[i] = { .left = left, .right = right }; + } + + // Now set them to global coords + // #TODO: This won't work for overflow entries, for now test like this + uint32 entryOffset = 0; + Pair* pairReader = pairs; + + for( uint32 b = 0; b < _numBuckets; b++ ) + { + self->SyncThreads(); + + const uint32 bucketCount = context.ptrTableBucketCounts[(int)table][b]; + + GetThreadOffsets( self, (uint64)bucketCount, count, offset, end ); + for( uint64 i = offset; i < end; i++ ) + { + pairReader[i].left += entryOffset; + pairReader[i].right += entryOffset; + } + + entryOffset += context.bucketCounts[(int)table-1][b]; + pairReader += bucketCount; + } + }); + + bbvirtfree( pairBitBuffer ); + } + + // Log::Line( "Sorting our pairs."); + SwapPairs( pairs, pairCount ); + RadixSort256::Sort( pool, (uint64*)pairs, tmpPairs, pairCount ); + SwapPairs( pairs, pairCount ); + + Log::Line( "Comparing pairs." ); + + // uint32 b = 0; + // uint64 bucketStart = 0; + // uint32 bucketEnd = context.ptrTableBucketCounts[(int)table][b]; + // uint64 lOffset = 0; + + ASSERT( refCount == pairCount ); + const uint64 entryCount = std::min( refCount, pairCount ); + + AnonMTJob::Run( pool, [=]( AnonMTJob* self ) { + + uint64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + for( uint64 i = offset; i < end; i++ ) + { + const Pair p = pairs [i]; + const Pair r = refPairs[i]; + + if( *(uint64*)&p != *(uint64*)&r ) + ASSERT( 0 ); + + // if( i == bucketEnd ) + // { + // lOffset += context.bucketCounts[(int)table][b]; + // bucketStart = bucketEnd; + // bucketEnd += context.ptrTableBucketCounts[(int)table][++b]; + // } + } + }); + + + Log::Line( "OK" ); + bbvirtfree( refPairs ); + bbvirtfree( pairs ); + bbvirtfree( tmpPairs ); +} + diff --git a/src/plotdisk/DiskPlotInfo.h b/src/plotdisk/DiskPlotInfo.h new file mode 100644 index 00000000..19d8bb2f --- /dev/null +++ b/src/plotdisk/DiskPlotInfo.h @@ -0,0 +1,64 @@ +#pragma once +#include "ChiaConsts.h" +#include "plotting/Tables.h" +#include "plotdisk/DiskPlotConfig.h" + +template +struct FpEntry {}; + +// Unpacked, 64-bit-aligned +template<> struct FpEntry { uint64 ykey; }; // x, y +template<> struct FpEntry { uint64 ykey; uint64 meta; }; // meta, key, y +template<> struct FpEntry { uint64 ykey; Meta4 meta; }; +template<> struct FpEntry { uint64 ykey; Meta4 meta; }; +template<> struct FpEntry { uint64 ykey; Meta3 meta; }; // It should be 20, but we use an extra 4 to round up to 64 bits. +template<> struct FpEntry { uint64 ykey; uint64 meta; }; +template<> struct FpEntry { uint64 ykey; }; + +typedef FpEntry T1Entry; +typedef FpEntry T2Entry; +typedef FpEntry T3Entry; +typedef FpEntry T4Entry; +typedef FpEntry T5Entry; +typedef FpEntry T6Entry; +typedef FpEntry T7Entry; + +static_assert( sizeof( T1Entry ) == 8 ); +static_assert( sizeof( T2Entry ) == 16 ); +static_assert( sizeof( T3Entry ) == 24 ); +static_assert( sizeof( T4Entry ) == 24 ); +static_assert( sizeof( T5Entry ) == 24 ); +static_assert( sizeof( T6Entry ) == 16 ); +static_assert( sizeof( T7Entry ) == 8 ); + +template +struct DiskPlotInfo +{ + static constexpr uint32 _k = _K; + + using Entry = FpEntry
; + using TMeta = typename TableMetaType
::MetaOut; + + using InputInfo = DiskPlotInfo; + + static constexpr int64 KEntryCount = static_cast( 1ull << _k ); + static constexpr int64 MaxBucketSliceEntries = (int64)bbconst_ceil( CDiv( CDiv( KEntryCount, (int) _numBuckets ), (int)_numBuckets ) * BB_DP_XTRA_ENTRIES_PER_BUCKET ); + static constexpr int64 MaxBucketEntries = MaxBucketSliceEntries * _numBuckets; //(int64)bbconst_ceil( ( static_cast( (1ull << _k) / _numBuckets ) * BB_DP_XTRA_ENTRIES_PER_BUCKET ) ); + + // Size of data outputted/generated by this table + static constexpr uint32 MetaMultiplier = static_cast( TableMetaOut
::Multiplier ); + + static constexpr uint32 BucketBits = bblog2( _numBuckets ); + static constexpr uint32 BucketShift = table < TableId::Table7 ? ( _k + kExtraBits) - BucketBits : _k - BucketBits; + + static constexpr uint32 YBitSize = table < TableId::Table7 ? _k - bblog2( _numBuckets ) + kExtraBits : _k - bblog2( _numBuckets ); + static constexpr uint32 MapBitSize = table == TableId::Table1 ? 0 : _k + 1; // This should be key bit size + + static constexpr uint32 PairBitSizeL = _k + 1 - BucketBits; + static constexpr uint32 PairBitSizeR = 9; + static constexpr uint32 PairBitSize = PairBitSizeL + PairBitSizeR; + + static constexpr uint32 EntrySizePackedBits = YBitSize + MapBitSize + ( MetaMultiplier * _k ); + static constexpr uint32 EntrySizeExpandedBits = CDiv( EntrySizePackedBits, 64 ) * 64; + +}; diff --git a/src/plotdisk/DiskPlotPhase1.cpp b/src/plotdisk/DiskPlotPhase1.cpp new file mode 100644 index 00000000..4a195d4a --- /dev/null +++ b/src/plotdisk/DiskPlotPhase1.cpp @@ -0,0 +1,452 @@ +#include "DiskPlotPhase1.h" +#include "util/Util.h" +#include "util/Log.h" +#include "b3/blake3.h" +#include "algorithm/RadixSort.h" +#include "plotting/GenSortKey.h" +#include "jobs/LookupMapJob.h" +#include "plotting/TableWriter.h" +#include "util/StackAllocator.h" +#include "DiskF1.h" +#include "DiskFp.h" + + +// Test +#if _DEBUG + #include "../plotmem/DbgHelper.h" + #include "plotdisk/DiskPlotDebug.h" +#endif + +//----------------------------------------------------------- +DiskPlotPhase1::DiskPlotPhase1( DiskPlotContext& cx ) + : _cx( cx ) + , _diskQueue( cx.ioQueue ) +{ + ASSERT( cx.tmpPath ); + + const FileSetOptions tmp1Options = cx.cfg->noTmp1DirectIO ? FileSetOptions::None : FileSetOptions::DirectIO; + + _diskQueue->InitFileSet( FileId::T1, "t1", 1, tmp1Options, nullptr ); // X (sorted on Y) + _diskQueue->InitFileSet( FileId::T2, "t2", 1, tmp1Options, nullptr ); // Back pointers + _diskQueue->InitFileSet( FileId::T3, "t3", 1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::T4, "t4", 1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::T5, "t5", 1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::T6, "t6", 1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::T7, "t7", 1, tmp1Options, nullptr ); + + _diskQueue->InitFileSet( FileId::MAP2, "map2", _cx.numBuckets+1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::MAP3, "map3", _cx.numBuckets+1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::MAP4, "map4", _cx.numBuckets+1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::MAP5, "map5", _cx.numBuckets+1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::MAP6, "map6", _cx.numBuckets+1, tmp1Options, nullptr ); + _diskQueue->InitFileSet( FileId::MAP7, "map7", _cx.numBuckets+1, tmp1Options, nullptr ); + + { + const size_t cacheSize = _cx.cacheSize / 2; + + FileSetOptions opts = FileSetOptions::UseTemp2; + + if( !_cx.cfg->noTmp2DirectIO ) + opts |= FileSetOptions::DirectIO; + + if( _cx.cache ) + opts |= FileSetOptions::Cachable; + + FileSetInitData fdata; + fdata.cache = _cx.cache; + fdata.cacheSize = cacheSize; + + _diskQueue->InitFileSet( FileId::FX0, "fx_0", _cx.numBuckets, opts, &fdata ); + + fdata.cache = ((byte*)fdata.cache) + cacheSize; + _diskQueue->InitFileSet( FileId::FX1, "fx_1", _cx.numBuckets, opts, &fdata ); + } +} + +//----------------------------------------------------------- +void DiskPlotPhase1::Run() +{ + #if _DEBUG && ( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) + { + FileStream bucketCounts, tableCounts, backPtrBucketCounts; + + if( bucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_READ_BUCKET_COUNT_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( bucketCounts.Read( _cx.bucketCounts, sizeof( _cx.bucketCounts ) ) != sizeof( _cx.bucketCounts ) ) + { + Log::Error( "Failed to read from bucket counts file." ); + goto CONTINUE; + } + } + else + { + Log::Error( "Failed to open bucket counts file." ); + goto CONTINUE; + } + + if( tableCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_TABLE_COUNTS_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( tableCounts.Read( _cx.entryCounts, sizeof( _cx.entryCounts ) ) != sizeof( _cx.entryCounts ) ) + { + Log::Error( "Failed to read from table counts file." ); + goto CONTINUE; + } + } + else + { + Log::Error( "Failed to open table counts file." ); + goto CONTINUE; + } + + if( backPtrBucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_PTR_BUCKET_COUNT_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( backPtrBucketCounts.Read( _cx.ptrTableBucketCounts, sizeof( _cx.ptrTableBucketCounts ) ) != sizeof( _cx.ptrTableBucketCounts ) ) + { + Fatal( "Failed to read from pointer bucket counts file." ); + } + } + else + { + Fatal( "Failed to open pointer bucket counts file." ); + } + + #if BB_DP_P1_SKIP_TO_TABLE + goto FP; + #endif + + #if BB_DP_DBG_SKIP_TO_C_TABLES + goto CTables; + #endif + + return; + + CONTINUE:; + } + #endif + + + +#if !BB_DP_DBG_READ_EXISTING_F1 + GenF1(); +#else + { + size_t pathLen = strlen( _cx.tmpPath ); + pathLen += sizeof( BB_DP_DBG_READ_BUCKET_COUNT_FNAME ); + + std::string bucketsPath = _cx.tmpPath; + if( bucketsPath[bucketsPath.length() - 1] != '/' && bucketsPath[bucketsPath.length() - 1] != '\\' ) + bucketsPath += "/"; + + bucketsPath += BB_DP_DBG_READ_BUCKET_COUNT_FNAME; + + const size_t bucketsCountSize = sizeof( uint32 ) * BB_DP_BUCKET_COUNT; + + FileStream fBucketCounts; + if( fBucketCounts.Open( bucketsPath.c_str(), FileMode::Open, FileAccess::Read ) ) + { + + size_t sizeRead = fBucketCounts.Read( _cx.bucketCounts[0], bucketsCountSize ); + FatalIf( sizeRead != bucketsCountSize, "Invalid bucket counts." ); + } + else + { + GenF1(); + + fBucketCounts.Close(); + FatalIf( !fBucketCounts.Open( bucketsPath.c_str(), FileMode::Create, FileAccess::Write ), "File to open bucket counts file" ); + FatalIf( fBucketCounts.Write( _cx.bucketCounts[0], bucketsCountSize ) != bucketsCountSize, "Failed to write bucket counts."); + } + } +#endif + + #if _DEBUG && BB_DP_DBG_VALIDATE_F1 + // if( 0 ) + { + const uint32* bucketCounts = _cx.bucketCounts[0]; + uint64 totalEntries = 0; + for( uint i = 0; i < BB_DP_BUCKET_COUNT; i++ ) + totalEntries += bucketCounts[i]; + + ASSERT( totalEntries == 1ull << _K ); + + Debug::ValidateYFileFromBuckets( FileId::Y0, *_cx.threadPool, *_diskQueue, TableId::Table1, _cx.bucketCounts[0] ); + } + #endif + +#if _DEBUG && BB_DP_P1_SKIP_TO_TABLE + FP: +#endif + + ForwardPropagate(); + + // Check all table counts + #if _DEBUG + for( int table = (int)TableId::Table1; table <= (int)TableId::Table7; table++ ) + { + uint64 entryCount = 0; + + for( int bucket = 0; bucket < (int)_cx.numBuckets; bucket++ ) + entryCount += _cx.bucketCounts[table][bucket]; + + ASSERT( entryCount == _cx.entryCounts[table] ); + } + #endif + + #if _DEBUG + { + // Write bucket counts + FileStream bucketCounts, tableCounts, backPtrBucketCounts; + + if( bucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_READ_BUCKET_COUNT_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( bucketCounts.Write( _cx.bucketCounts, sizeof( _cx.bucketCounts ) ) != sizeof( _cx.bucketCounts ) ) + Log::Error( "Failed to write to bucket counts file." ); + } + else + Log::Error( "Failed to open bucket counts file." ); + + if( tableCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_TABLE_COUNTS_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( tableCounts.Write( _cx.entryCounts, sizeof( _cx.entryCounts ) ) != sizeof( _cx.entryCounts ) ) + Log::Error( "Failed to write to table counts file." ); + } + else + Log::Error( "Failed to open table counts file." ); + + if( backPtrBucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_PTR_BUCKET_COUNT_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( backPtrBucketCounts.Write( _cx.ptrTableBucketCounts, sizeof( _cx.ptrTableBucketCounts ) ) != sizeof( _cx.ptrTableBucketCounts ) ) + Log::Error( "Failed to write to back pointer bucket counts file." ); + } + else + Log::Error( "Failed to open back pointer bucket counts file." ); + } + #endif + + Log::Line( " Phase 1 Total I/O wait time: %.2lf", TicksToSeconds( _cx.ioWaitTime ) + _cx.ioQueue->IOBufferWaitTime() ); + +#if BB_DP_DBG_SKIP_TO_C_TABLES + CTables: +#endif + WriteCTables(); + + #if !BB_DP_P1_KEEP_FILES + _cx.ioQueue->DeleteBucket( _fxIn ); + _cx.ioQueue->CommitCommands(); + #endif +} + +/// +/// F1 Generation +/// +//----------------------------------------------------------- +void DiskPlotPhase1::GenF1() +{ + Log::Line( "Generating f1..." ); + auto timer = TimerBegin(); + + switch( _cx.numBuckets ) + { + case 128 : GenF1Buckets<128 >(); break; + case 256 : GenF1Buckets<256 >(); break; + case 512 : GenF1Buckets<512 >(); break; + case 1024: GenF1Buckets<1024>(); break; + default: + ASSERT( 0 ); + break; + } + + _cx.entryCounts[0] = 1ull << _K; + + double elapsed = TimerEnd( timer ); + Log::Line( "Finished f1 generation in %.2lf seconds. ", elapsed ); + Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _cx.ioQueue->IOBufferWaitTime() ); + + #if BB_IO_METRICS_ON + const double writeThroughput = _cx.ioQueue->GetAverageWriteThroughput(); + const auto& writes = _cx.ioQueue->GetWriteMetrics(); + + Log::Line( " Table 1 I/O Metrics:" ); + Log::Line( " Average write throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + writeThroughput BtoMB, writeThroughput / 1000000.0, writeThroughput BtoGB, writeThroughput / 1000000000.0 ); + Log::Line( " Total size written: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + (double)writes.size BtoMB, (double)writes.size / 1000000.0, (double)writes.size BtoGB, (double)writes.size / 1000000000.0 ); + Log::Line( " Total write commands: %llu.", (llu)writes.count ); + Log::Line( "" ); + + _cx.ioQueue->ClearWriteMetrics(); + #endif +} + +//----------------------------------------------------------- +template +void DiskPlotPhase1::GenF1Buckets() +{ + DiskF1<_numBuckets> f1( _cx, FileId::FX0 ); + f1.GenF1(); +} + +//----------------------------------------------------------- +void DiskPlotPhase1::ForwardPropagate() +{ + TableId startTable = TableId::Table2; + + #if BB_DP_P1_SKIP_TO_TABLE + startTable = BB_DP_P1_START_TABLE; + if( (int)startTable ^ 1 ) + std::swap( _fxIn, _fxOut ); + #endif + + for( TableId table = startTable; table <= TableId::Table7; table++ ) + { + Log::Line( "Table %u", table+1 ); + auto timer = TimerBegin(); + + switch( table ) + { + case TableId::Table2: ForwardPropagateTable(); break; + case TableId::Table3: ForwardPropagateTable(); break; + case TableId::Table4: ForwardPropagateTable(); break; + case TableId::Table5: ForwardPropagateTable(); break; + case TableId::Table6: ForwardPropagateTable(); break; + case TableId::Table7: ForwardPropagateTable(); break; + + default: + Fatal( "Invalid table." ); + break; + } + Log::Line( "Completed table %u in %.2lf seconds with %.llu entries.", table+1, TimerEnd( timer ), _cx.entryCounts[(int)table] ); + Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( _tableIOWaitTime ) ); + + std::swap( _fxIn, _fxOut ); + + // No longer need fxout. Delete it + if( table == TableId::Table7 ) + { + #if !BB_DP_P1_KEEP_FILES + _cx.ioQueue->DeleteBucket( _fxOut ); + _cx.ioQueue->CommitCommands(); + #endif + } + + #if BB_IO_METRICS_ON + const double readThroughput = _cx.ioQueue->GetAverageReadThroughput(); + const auto& reads = _cx.ioQueue->GetReadMetrics(); + const double writeThroughput = _cx.ioQueue->GetAverageWriteThroughput(); + const auto& writes = _cx.ioQueue->GetWriteMetrics(); + + Log::Line( " Table %u I/O Metrics:", (uint32)table+1 ); + + Log::Line( " Average read throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + readThroughput BtoMB, readThroughput / 1000000.0, readThroughput BtoGB, readThroughput / 1000000000.0 ); + Log::Line( " Total size read: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + (double)reads.size BtoMB, (double)reads.size / 1000000.0, (double)reads.size BtoGB, (double)reads.size / 1000000000.0 ); + Log::Line( " Total read commands: %llu.", (llu)reads.count ); + + Log::Line( " Average write throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + writeThroughput BtoMB, writeThroughput / 1000000.0, writeThroughput BtoGB, writeThroughput / 1000000000.0 ); + Log::Line( " Total size written: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + (double)writes.size BtoMB, (double)writes.size / 1000000.0, (double)writes.size BtoGB, (double)writes.size / 1000000000.0 ); + Log::Line( " Total write commands: %llu.", (llu)writes.count ); + Log::Line( "" ); + + _cx.ioQueue->ClearReadMetrics(); + _cx.ioQueue->ClearWriteMetrics(); + #endif + } +} + +//----------------------------------------------------------- +template +void DiskPlotPhase1::ForwardPropagateTable() +{ + _tableIOWaitTime = Duration::zero(); + + // Above table 6 the metadata is < x4, let's truncate the output file + // so that we can recover some space from the x4 metadata from the previous tables + if( table >= TableId::Table6 ) + { + _cx.ioQueue->TruncateBucket( _fxOut, 0 ); + _cx.ioQueue->CommitCommands(); + } + + switch( _cx.numBuckets ) + { + case 128 : ForwardPropagateBuckets(); break; + case 256 : ForwardPropagateBuckets(); break; + case 512 : ForwardPropagateBuckets(); break; + case 1024: ForwardPropagateBuckets(); break; + + default: + Fatal( "Invalid bucket count." ); + break; + } +} + +//----------------------------------------------------------- +template +void DiskPlotPhase1::ForwardPropagateBuckets() +{ + DiskFp fp( _cx, _fxIn, _fxOut ); + fp.Run(); + + _tableIOWaitTime = fp.IOWaitTime(); + _cx.ioWaitTime += _tableIOWaitTime; + + #if BB_DP_DBG_VALIDATE_FX + #if !_DEBUG + Log::Line( "Warning: Table validation enabled in release mode." ); + #endif + + using TYOut = typename DiskFp::TYOut; + Debug::ValidateYForTable( _fxOut, *_cx.ioQueue, *_cx.threadPool, _cx.bucketCounts[(int)table] ); + Debug::ValidatePairs<256>( _cx, table ); + #endif +} + +//----------------------------------------------------------- +void DiskPlotPhase1::WriteCTables() +{ + switch( _cx.numBuckets ) + { + case 128 : WriteCTablesBuckets<128 >(); break; + case 256 : WriteCTablesBuckets<256 >(); break; + case 512 : WriteCTablesBuckets<512 >(); break; + case 1024: WriteCTablesBuckets<1024>(); break; + + default: + Fatal( "Invalid bucket count." ); + break; + } +} + +//----------------------------------------------------------- +template +void DiskPlotPhase1::WriteCTablesBuckets() +{ + #if BB_DP_DBG_SKIP_TO_C_TABLES + _fxIn = FileId::FX0; + _fxOut = FileId::FX1; + + #if BB_DP_DBG_VALIDATE_FX + #if !_DEBUG + Log::Line( "Warning: Table validation enabled in release mode." ); + #endif + + using TYOut = typename DiskFp::TYOut; + Debug::ValidateYForTable( _fxIn, *_cx.ioQueue, *_cx.threadPool, _cx.bucketCounts[(int)TableId::Table7] ); + #endif + #endif + + Log::Line( "Processing f7s and writing C tables to plot file." ); + + const auto timer = TimerBegin(); + + DiskFp fp( _cx, _fxIn, _fxOut ); + fp.RunF7(); + + const double elapsed = TimerEnd( timer ); + Log::Line( "Completed C processing tables in %.2lf seconds.", elapsed ); + Log::Line( "C Tables I/O wait time: %.2lf.", TicksToSeconds( fp.IOWaitTime() ) ); +} + diff --git a/src/plotdisk/DiskPlotPhase1.h b/src/plotdisk/DiskPlotPhase1.h new file mode 100644 index 00000000..350b5b57 --- /dev/null +++ b/src/plotdisk/DiskPlotPhase1.h @@ -0,0 +1,41 @@ +#pragma once +#include "DiskPlotContext.h" +#include "util/Log.h" +#include "ChiaConsts.h" + +class DiskPlotPhase1 +{ +public: + DiskPlotPhase1( DiskPlotContext& cx ); + void Run(); + +private: + void GenF1(); + + template + void GenF1Buckets(); + + // Run forward propagations portion + void ForwardPropagate(); + + template + void ForwardPropagateTable(); + + template + void ForwardPropagateBuckets(); + + // Write C tables + void WriteCTables(); + + template + void WriteCTablesBuckets(); + +private: + DiskPlotContext& _cx; + DiskBufferQueue* _diskQueue; + + Duration _tableIOWaitTime; + + FileId _fxIn = FileId::FX0; + FileId _fxOut = FileId::FX1; +}; diff --git a/src/plotdisk/DiskPlotPhase2.cpp b/src/plotdisk/DiskPlotPhase2.cpp new file mode 100644 index 00000000..987fdcf6 --- /dev/null +++ b/src/plotdisk/DiskPlotPhase2.cpp @@ -0,0 +1,537 @@ +#include "DiskPlotPhase2.h" +#include "util/BitField.h" +#include "algorithm/RadixSort.h" +#include "transforms/FxTransform.h" +#include "plotdisk/DiskPlotInfo.h" +#include "util/StackAllocator.h" +#include "DiskPlotInfo.h" +#include "plotdisk/DiskPairReader.h" + +// #DEBUG +#include "jobs/IOJob.h" +#include "io/FileStream.h" +#include "DiskPlotDebug.h" + +//----------------------------------------------------------- +template +inline void MarkTableEntries( int64 i, const int64 entryCount, BitField lTable, const BitField rTable, + uint64 lTableOffset, const Pair* pairs, const uint64* map ); + + +//----------------------------------------------------------- +DiskPlotPhase2::DiskPlotPhase2( DiskPlotContext& context ) + : _context( context ) +{ + DiskBufferQueue& ioQueue = *context.ioQueue; + + const FileSetOptions tmp1Opts = context.cfg->noTmp1DirectIO ? FileSetOptions::None : FileSetOptions::DirectIO; + + // #TODO: Give the cache to the marks? Probably not needed for sucha small write... + // Then we would need to re-distribute the cache on Phase 3. + // #TODO: We need to specify the temporary file location + ioQueue.InitFileSet( FileId::MARKED_ENTRIES_2, "table_2_marks", 1, tmp1Opts, nullptr ); + ioQueue.InitFileSet( FileId::MARKED_ENTRIES_3, "table_3_marks", 1, tmp1Opts, nullptr ); + ioQueue.InitFileSet( FileId::MARKED_ENTRIES_4, "table_4_marks", 1, tmp1Opts, nullptr ); + ioQueue.InitFileSet( FileId::MARKED_ENTRIES_5, "table_5_marks", 1, tmp1Opts, nullptr ); + ioQueue.InitFileSet( FileId::MARKED_ENTRIES_6, "table_6_marks", 1, tmp1Opts, nullptr ); + + ioQueue.SeekFile( FileId::T1, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T2, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T3, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T4, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T5, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T6, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T7, 0, 0, SeekOrigin::Begin ); + + ioQueue.SeekBucket( FileId::MAP2, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP3, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP4, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP5, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP6, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP7, 0, SeekOrigin::Begin ); + + ioQueue.CommitCommands(); +} + +//----------------------------------------------------------- +DiskPlotPhase2::~DiskPlotPhase2() {} + +//----------------------------------------------------------- +void DiskPlotPhase2::Run() +{ +#if BB_DP_DBG_SKIP_PHASE_2 + return; +#endif + + switch( _context.numBuckets ) + { + case 128 : RunWithBuckets<128 >(); break; + case 256 : RunWithBuckets<256 >(); break; + case 512 : RunWithBuckets<512 >(); break; + case 1024: RunWithBuckets<1024>(); break; + + default: + ASSERT( 0 ); + break; + } +} + +//----------------------------------------------------------- +template +void DiskPlotPhase2::RunWithBuckets() +{ + DiskPlotContext& context = _context; + DiskBufferQueue& queue = *context.ioQueue; + + Duration p2WaitTime = Duration::zero(); + + StackAllocator allocator( context.heapBuffer, context.heapSize ); + + Fence readFence; + Fence bitFieldFence; + + const uint64 maxBucketEntries = (uint64)DiskPlotInfo::MaxBucketEntries; + Pair* pairs = allocator.CAlloc ( maxBucketEntries ); + uint64* map = allocator.CAlloc( maxBucketEntries ); + + uint64 maxEntries = context.entryCounts[0]; + for( TableId table = TableId::Table2; table <= TableId::Table7; table++ ) + maxEntries = std::max( maxEntries, context.entryCounts[(int)table] ); + + const size_t blockSize = _context.tmp2BlockSize; + _markingTableSize = RoundUpToNextBoundaryT( maxEntries / 8, (uint64)blockSize ); + + // Prepare 2 marking bitfields for dual-buffering + uint64* bitFields[2]; + bitFields[0] = allocator.AllocT( _markingTableSize, blockSize ); + bitFields[1] = allocator.AllocT( _markingTableSize, blockSize ); + + #if _DEBUG && BB_DP_DBG_SKIP_PHASE_2 + return; + #endif + + + // Mark all tables + FileId lTableFileId = FileId::MARKED_ENTRIES_6; + + uint64* lMarkingTable = bitFields[0]; + uint64* rMarkingTable = bitFields[1]; + + for( TableId table = TableId::Table7; table > TableId::Table2; table = table-1 ) + { + readFence.Reset( 0 ); + + const auto timer = TimerBegin(); + + const size_t stackMarker = allocator.Size(); + DiskPairAndMapReader<_numBuckets> reader( context, context.p2ThreadCount, readFence, table, allocator, table == TableId::Table7 ); + + ASSERT( allocator.Size() < context.heapSize ); + + // Log::Line( "Allocated work heap of %.2lf GiB out of %.2lf GiB.", + // (double)(allocator.Size() + _markingTableSize*2 ) BtoGB, (double)context.heapSize BtoGB ); + + memset( lMarkingTable, 0, _markingTableSize ); + MarkTable<_numBuckets>( table, reader, pairs, map, BitField( lMarkingTable, context.entryCounts[(int)table-1] ), + BitField( rMarkingTable, context.entryCounts[(int)table] ) ); + + // + // #TEST + // + #if 0 + if( 0 ) + { + // Debug::ValidatePairs<_numBuckets>( _context, TableId::Table7 ); + + uint64* readbuffer = bbcvirtalloc( maxEntries*2 ); + Pair* pairBuf = bbcvirtalloc( maxEntries ); + byte* rMarkedBuffer = bbcvirtalloc( maxEntries ); + byte* lMarkedBuffer = bbcvirtalloc( maxEntries ); + + Pair* pairRef = bbcvirtalloc( 1ull << _K ); + Pair* pairRefTmp = bbcvirtalloc( 1ull << _K ); + + uint64* rMap = bbcvirtalloc( maxEntries ); + uint64* refMap = bbcvirtalloc( maxEntries ); + + // Load from the reader as a reference + if( 0 ) + { + Log::Line( "Loading with map reader..." ); + uint64 readCount = 0; + uint64* mapReader = refMap; + for( uint32 b = 0; b < _numBuckets; b++ ) + { + reader.LoadNextBucket(); + const uint64 readLength = reader.UnpackBucket( b, pairBuf, mapReader ); + mapReader += readLength; + readCount += readLength; + } + ASSERT( readCount == context.entryCounts[(int)TableId::Table7] ); + } + + for( TableId rTable = TableId::Table7; rTable > TableId::Table2; rTable = rTable-1 ) + { + const TableId lTable = rTable-1; + + const uint64 rEntryCount = context.entryCounts[(int)rTable]; + const uint64 lEntryCount = context.entryCounts[(int)lTable]; + + // BitField rMarkedEntries( (uint64*)rMarkedBuffer, rEntryCount ); + // BitField lMarkedEntries( (uint64*)lMarkedBuffer, lEntryCount ); + + Log::Line( "Reading R table %u...", rTable+1 ); + { + const uint32 savedBits = bblog2( _numBuckets ); + const uint32 pairBits = _K + 1 - savedBits + 9; + const size_t blockSize = queue.BlockSize( FileId::T1 ); + const size_t pairReadSize = (size_t)CDiv( rEntryCount * pairBits, (int)blockSize*8 ) * blockSize; + const FileId rTableId = FileId::T1 + (FileId)rTable; + + Fence fence; + queue.SeekFile( rTableId, 0, 0, SeekOrigin::Begin ); + queue.ReadFile( rTableId, 0, readbuffer, pairReadSize ); + queue.SignalFence( fence ); + queue.CommitCommands(); + fence.Wait(); + + AnonMTJob::Run( *_context.threadPool, [=]( AnonMTJob* self ) { + + uint64 count, offset, end; + GetThreadOffsets( self, rEntryCount, count, offset, end ); + + BitReader reader( readbuffer, rEntryCount * pairBits, offset * pairBits ); + const uint32 lBits = _K - savedBits + 1; + const uint32 rBits = 9; + for( uint64 i = offset; i < end; i++ ) + { + const uint32 left = (uint32)reader.ReadBits64( lBits ); + const uint32 right = left + (uint32)reader.ReadBits64( rBits ); + pairBuf[i] = { .left = left, .right = right }; + } + }); + } + + if( rTable < TableId::Table7 ) + { + Log::Line( "Reading R map" ); + const uint32 _k = _K; + const uint32 _savedBits = bblog2( _numBuckets ); + const uint32 _mapBits = _k + 1 + _k - _savedBits; + + const FileId mapId = FileId::MAP2 + (FileId)rTable - 1; + + const uint64 kEntryCount = ( 1ull << _K ); + const uint64 bucketLength = kEntryCount / _numBuckets; + + // Last, non-overflow bucket + const uint64 lastBucketLength = rEntryCount > kEntryCount ? + bucketLength : bucketLength - ( kEntryCount - rEntryCount ); + + // Overflow bucket + const uint64 overflowBucketLength = rEntryCount > kEntryCount ? rEntryCount - kEntryCount : 0; + + Fence fence; + queue.SeekBucket( mapId, 0, SeekOrigin::Begin ); + queue.CommitCommands(); + + uint64* mapReader = rMap; + for( uint32 b = 0; b <= _numBuckets; b++ ) + { + const uint64 length = b < _numBuckets - 1 ? bucketLength : + b < _numBuckets ? lastBucketLength : overflowBucketLength; + + if( length < 1 ) + break; + const size_t bucketReadSize = RoundUpToNextBoundary( length * _mapBits, (int)blockSize * 8 ) / 8; + + queue.ReadFile( mapId, b, readbuffer, bucketReadSize ); + queue.SignalFence( fence ); + queue.CommitCommands(); + fence.Wait(); + + AnonMTJob::Run( *_context.threadPool, [=]( AnonMTJob* self ) { + + int64 count, offset, end; + GetThreadOffsets( self, (int64)length, count, offset, end ); + ASSERT( count > 0 ); + + BitReader reader( (uint64*)readbuffer, _mapBits * length, offset * _mapBits ); + + const uint32 idxShift = _k+1; + const uint64 finalIdxMask = ( 1ull << idxShift ) - 1; + for( int64 i = offset; i < end; i++ ) + { + const uint64 packedMap = reader.ReadBits64( (uint32)_mapBits ); + const uint64 map = packedMap & finalIdxMask; + const uint32 dstIdx = (uint32)( packedMap >> idxShift ); + ASSERT( dstIdx < length ); + + mapReader[dstIdx] = map; + // mapReader[dstIdx] = dstIdx; + } + }); + // for( uint64 i = 1; i < length; i++ ) + // ASSERT( mapReader[i] == mapReader[i-1]+1 ); + + mapReader += length; + } + + // Test against ref + AnonMTJob::Run( *_context.threadPool, 1, [=]( AnonMTJob* self ) { + + uint64 count, offset, end; + GetThreadOffsets( self, rEntryCount, count, offset, end ); + + for( uint64 i = offset; i < end; i++ ) + ASSERT( rMap[i] == refMap[i] ); + }); + } + + // uint64 refEntryCount = 0; + // { + // char path[1024]; + // sprintf( path, "%sp1.t%d.tmp", BB_DP_DBG_REF_DIR, (int)rTable+1 ); + // Log::Line( " Loading reference pairs '%s'.", path ); + + // FatalIf( !Debug::LoadRefTable( path, pairRef, refEntryCount ), "Failed to load reference pairs." ); + + // ASSERT( refEntryCount == rEntryCount ); + // RadixSort256::Sort( *_context.threadPool, (uint64*)pairRef, (uint64*)pairRefTmp, refEntryCount ); + // } + // ASSERT( refEntryCount == rEntryCount ); + + Log::Line( "Marking entries..." ); + std::atomic prunedEntryCount = 0; + + AnonMTJob::Run( *context.threadPool, [&]( AnonMTJob* self ) { + + const Pair* pairPtr = pairBuf; + + uint64 lEntryOffset = 0; + uint64 rTableOffset = 0; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + const uint32 rBucketCount = context.ptrTableBucketCounts[(int)rTable][bucket]; + const uint32 lBucketCount = context.bucketCounts[(int)lTable][bucket]; + + uint32 count, offset, end; + GetThreadOffsets( self, rBucketCount, count, offset, end ); + + for( uint e = offset; e < end; e++ ) + { + if( rTable < TableId::Table7 ) + { + const uint64 rIdx = rMap[rTableOffset + e]; + if( !rMarkedBuffer[rIdx] ) + continue; + } + + uint64 l = (uint64)pairPtr[e].left + lEntryOffset; + uint64 r = (uint64)pairPtr[e].right + lEntryOffset; + + ASSERT( l < lEntryCount ); + ASSERT( r < lEntryCount ); + + lMarkedBuffer[l] = 1; + lMarkedBuffer[r] = 1; + } + + pairPtr += rBucketCount; + + lEntryOffset += lBucketCount; + rTableOffset += rBucketCount; + } + + self->SyncThreads(); + + + if( self->IsControlThread() ) + Log::Line( "Counting entries." ); + + uint64 count, offset, end; + GetThreadOffsets( self, lEntryCount, count, offset, end ); + for( uint64 e = offset; e < end; e++ ) + { + if( lMarkedBuffer[e] ) + prunedEntryCount++; + } + }); + + Log::Line( " %llu/%llu (%.2lf%%)", prunedEntryCount.load(), lEntryCount, + ((double)prunedEntryCount.load() / lEntryCount) * 100.0 ); + Log::Line(""); + + // Swap marking tables and zero-out the left one. + std::swap( lMarkedBuffer, rMarkedBuffer ); + memset( lMarkedBuffer, 0, 1ull << _K ); + } + } + #endif + + // Ensure the last table finished writing to the bitfield + _ioTableWaitTime = Duration::zero(); + + if( table < TableId::Table7 ) + bitFieldFence.Wait( _ioTableWaitTime ); + + // Submit l marking table for writing + queue.WriteFile( lTableFileId, 0, lMarkingTable, _markingTableSize ); + queue.SignalFence( bitFieldFence ); + queue.CommitCommands(); + + // Swap marking tables + std::swap( lMarkingTable, rMarkingTable ); + lTableFileId = (FileId)( (int)lTableFileId - 1 ); + + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished marking table %d in %.2lf seconds.", table, elapsed ); + Log::Line( "Table %d I/O wait time: %.2lf seconds.", table, TicksToSeconds( _ioTableWaitTime ) ); + p2WaitTime += _ioTableWaitTime; + + allocator.PopToMarker( stackMarker ); + ASSERT( allocator.Size() == stackMarker ); + + // Log::Line( " Table %u IO Aggregate Wait Time | READ: %.4lf | WRITE: %.4lf | BUFFERS: %.4lf", table, + // TicksToSeconds( context.readWaitTime ), TicksToSeconds( context.writeWaitTime ), context.ioQueue->IOBufferWaitTime() ); + + /// #TEST Marked entries + if( 0 ) + { + Log::Line( "Counting marked entries..." ); + std::atomic lTablePrunedEntries = 0; + + AnonMTJob::Run( *_context.threadPool, [&]( AnonMTJob* self ) { + BitField markedEntries( rMarkingTable, context.entryCounts[(int)table] ); + + const uint64 lTableEntries = context.entryCounts[(int)table-1]; + + uint64 count, offset, end; + GetThreadOffsets( self, lTableEntries, count, offset, end ); + + uint64 prunedCount = 0; + for( uint64 e = offset; e < end; ++e ) + { + if( markedEntries.Get( e ) ) + prunedCount++; + } + + lTablePrunedEntries += prunedCount; + }); + + const uint64 lTableEntries = context.entryCounts[(int)table-1]; + Log::Line( "Table %u entries: %llu/%llu (%.2lf%%)", table, + lTablePrunedEntries.load(), lTableEntries, ((double)lTablePrunedEntries.load() / lTableEntries ) * 100.0 ); + Log::Line( "" ); + } + } + + // Log::Line( " Phase 2 IO write wait time: %.2lf seconds.", TicksToSeconds( writeWaitTime ) ); + + // Wait for final write + queue.SignalFence( bitFieldFence, 0xFFFFFFFF ); + queue.CommitCommands(); + bitFieldFence.Wait( 0xFFFFFFFF ); + + Log::Line( " Phase 2 Total I/O wait time: %.2lf seconds.", TicksToSeconds( p2WaitTime ) ); + _context.ioWaitTime += p2WaitTime; + // TicksToSeconds( context.readWaitTime ), TicksToSeconds( context.writeWaitTime ), context.ioQueue->IOBufferWaitTime() ); +} + +//----------------------------------------------------------- +template +void DiskPlotPhase2::MarkTable( const TableId rTable, DiskPairAndMapReader<_numBuckets> reader, + Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ) +{ + switch( rTable ) + { + case TableId::Table7: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table6: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table5: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table4: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table3: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + + default: + ASSERT( 0 ); + break; + } +} + +//----------------------------------------------------------- +template +void DiskPlotPhase2::MarkTableBuckets( DiskPairAndMapReader<_numBuckets> reader, + Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ) +{ + // Load initial bucket + reader.LoadNextBucket(); + + uint64 lTableOffset = 0; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + reader.LoadNextBucket(); + reader.UnpackBucket( bucket, pairs, map, _ioTableWaitTime ); + + AnonMTJob::Run( *_context.threadPool, _context.p2ThreadCount, [=]( AnonMTJob* self ) { + + // if( bucket == 0 ) + // { + // // Zero-out l marking table + // size_t clearCount, clearOffset, _; + // GetThreadOffsets( self, _markingTableSize, clearCount, clearOffset, _ ); + + // if( clearCount ) + // memset( ((byte*)lTableMarks) + clearOffset, 0, clearCount ); + + // self->SyncThreads(); + // } + + const uint64 bucketEntryCount = _context.ptrTableBucketCounts[(int)rTable][bucket]; + + // Mark entries + int64 count, offset, _; + GetThreadOffsets( self, (int64)bucketEntryCount, count, offset, _ ); + + // We need to do 2 passes to ensure no 2 threads attempt to write to the same field at the same time + const int64 firstPassCount = count / 2; + + MarkTableEntries( offset, firstPassCount, lTableMarks, rTableMarks, lTableOffset, pairs, map ); + self->SyncThreads(); + MarkTableEntries( offset + firstPassCount, count - firstPassCount, lTableMarks, rTableMarks, lTableOffset, pairs, map ); + + }); + + lTableOffset += _context.bucketCounts[(int)rTable-1][bucket]; + } +} + +//----------------------------------------------------------- +template +inline void MarkTableEntries( int64 i, const int64 entryCount, BitField lTable, const BitField rTable, + uint64 lTableOffset, const Pair* pairs, const uint64* map ) +{ + for( const int64 end = i + entryCount ; i < end; i++ ) + { +#if _DEBUG + // if( table == TableId::Table3 && pairs[i].left == 4213663 && pairs[i].right == 4214002 ) BBDebugBreak(); + // if( table == TableId::Table3 && pairs[i].left + lTableOffset == 910154188 && pairs[i].right + lTableOffset == 910154527 ) BBDebugBreak(); +#endif + if constexpr ( table < TableId::Table7 ) + { + const uint64 rTableIdx = map[i]; + if( !rTable.Get( rTableIdx ) ) + continue; + } + + const Pair& pair = pairs[i]; + const uint64 left = lTableOffset + pair.left; + const uint64 right = lTableOffset + pair.right; + + // #TODO Test with atomic sets so that we can write into the + // mapped index, and not have to do mapped readings when + // reading from the R table here, or in Phase 3. + lTable.Set( left ); + lTable.Set( right ); + } +} diff --git a/src/plotdisk/DiskPlotPhase2.h b/src/plotdisk/DiskPlotPhase2.h new file mode 100644 index 00000000..e324cb10 --- /dev/null +++ b/src/plotdisk/DiskPlotPhase2.h @@ -0,0 +1,35 @@ +#pragma once + +#include "plotdisk/DiskPlotContext.h" +#include "util/BitField.h" + + +template +struct DiskPairAndMapReader; + +class DiskPlotPhase2 +{ +public: + DiskPlotPhase2( DiskPlotContext& context ); + ~DiskPlotPhase2(); + + void Run(); + +private: + + template + void RunWithBuckets(); + + template + void MarkTable( const TableId rTable, DiskPairAndMapReader<_numBuckets> reader, Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ); + + template + void MarkTableBuckets( DiskPairAndMapReader<_numBuckets> reader, Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ); + +private: + DiskPlotContext& _context; + Fence* _bucketReadFence; + Fence* _mapWriteFence; + size_t _markingTableSize = 0; + Duration _ioTableWaitTime = Duration::zero(); +}; \ No newline at end of file diff --git a/src/plotdisk/DiskPlotPhase3.cpp b/src/plotdisk/DiskPlotPhase3.cpp new file mode 100644 index 00000000..3d07b428 --- /dev/null +++ b/src/plotdisk/DiskPlotPhase3.cpp @@ -0,0 +1,1620 @@ +#include "DiskPlotPhase3.h" +#include "util/BitField.h" +#include "plotdisk/BitBucketWriter.h" +#include "plotmem/LPGen.h" +#include "algorithm/RadixSort.h" +#include "plotting/TableWriter.h" +#include "plotmem/ParkWriter.h" + +#if _DEBUG + #include "DiskPlotDebug.h" + #include "jobs/IOJob.h" + #include + + static void ValidateLinePoints( const TableId table, const DiskPlotContext& context, const uint32 bucket, const uint64* linePoints, const uint64 length ); + static void SavePrunedBucketCount( const TableId table, uint64* bucketCounts, bool read ); + static void UnpackPark7( const byte* srcBits, uint64* dstEntries ); + + // #define BB_DP_DBG_P3_SKIP_TO_TABLE + #define BB_DP_DBG_P3_START_TABLE TableId::Table7 + +#endif + +// Extra L entries to load per bucket to ensure we +// have cross bucket entries accounted for +#define P3_EXTRA_L_ENTRIES_TO_LOAD BB_DP_CROSS_BUCKET_MAX_ENTRIES + +// Because entries are pruned here, we will need bigger bucket sizes as the +// entries will be piled into the first buckets and not the latter ones. +// This is because the line points will be smaller given the L table indices +// are smaller as they were pruned. +#define P3_BUCKET_MULTIPLER 1.4 + +class EntrySort +{ +public: + //----------------------------------------------------------- + template + inline static void SortEntries( ThreadPool& pool, const uint32 threadCount, const int64 entryCount, + TEntry* entries, TEntry* tmpEntries, TKey* keys, TKey* tmpKeys ) + { + ASSERT( entries ); + ASSERT( tmpEntries ); + ASSERT( entryCount > 0 ); + ASSERT( keys ); + ASSERT( tmpKeys ); + + using Job = AnonPrefixSumJob; + + Job::Run( pool, threadCount, [=]( Job* self ) { + + const uint32 remainderBits = CDiv( entryBitSize, 8 ) * 8 - entryBitSize; + + int64 count, offset, endIdx; + GetThreadOffsets( self, entryCount, count, offset, endIdx ); + + constexpr uint Radix = 256; + constexpr uint32 MaxIter = CDiv( entryBitSize, 8 ); + constexpr int32 iterations = MaxIter - remainderBits / 8; + constexpr uint32 shiftBase = 8; + + BucketT counts [Radix]; + BucketT pfxSum [Radix]; + BucketT totalCounts[Radix]; + + const TEntry* input = entries; + TEntry* output = tmpEntries; + + const TKey* keyInput = keys; + TKey* keyOut = tmpKeys; + + uint32 shift = 0; + + const uint32 lastByteRemainderBits = remainderBits & 7; // & 7 == % 8 + const uint32 lastByteMask = 0xFF >> lastByteRemainderBits; + uint32 masks[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + masks[iterations-1] = lastByteMask; + + for( int32 iter = 0; iter < iterations ; iter++, shift += shiftBase ) + { + const uint32 mask = masks[iter]; + + // Zero-out the counts + memset( counts, 0, sizeof( BucketT ) * Radix ); + + const TEntry* src = input + offset; + const TEntry* end = input + endIdx; + const TKey* keySrc = keyInput + offset; + ASSERT( (int64)(intptr_t)(end - src) == count ); + + do { + counts[(*src >> shift) & mask]++; + } while( ++src < end ); + + self->CalculatePrefixSum( Radix, counts, pfxSum, totalCounts ); + + src = input + offset; + for( int64 i = count; i > 0; ) + { + const TEntry value = src[--i]; + const uint64 bucket = (value >> shift) & mask; + + const BucketT dstIdx = --pfxSum[bucket]; + ASSERT( dstIdx < entryCount ); + + output[dstIdx] = value; + keyOut[dstIdx] = keySrc[i]; + } + + std::swap( (TEntry*&)input , output ); + std::swap( (TKey*&)keyInput, keyOut ); + + self->SyncThreads(); + } + }); + } + +}; + +template +class MapWriter +{ +public: + static constexpr uint32 _k = _K; + static constexpr uint32 BucketBits = bblog2( _numBuckets ); + static constexpr uint32 AddressBitSize = _overflow ? _k + 1 : _k; + static constexpr uint32 EntryBitSize = _k - BucketBits + AddressBitSize; // ( origin address | final address ) ( k-log2(buckets) | 32 ) + +public: + + //----------------------------------------------------------- + MapWriter() {} + + //----------------------------------------------------------- + MapWriter( DiskBufferQueue& ioQueue, const FileId fileId, IAllocator& allocator, const uint64 maxEntries, const size_t blockSize, + Fence& writeFence, Duration& writeWaitTime ) + : _ioQueue ( &ioQueue ) + , _bucketWriter ( ioQueue, fileId, (byte*)allocator.CAlloc( _numBuckets+1, blockSize, blockSize ) ) + , _writeFence ( &writeFence ) + , _writeWaitTime( &writeWaitTime ) + { + const size_t writeBufferSize = RoundUpToNextBoundary( CDiv( maxEntries * EntryBitSize, 8 ), (int)blockSize ); + + _writebuffers[0] = allocator.AllocT( writeBufferSize, blockSize ); + _writebuffers[1] = allocator.AllocT( writeBufferSize, blockSize ); + } + + //----------------------------------------------------------- + void Write( ThreadPool& pool, const uint32 threadCount, + const uint32 bucket, const int64 entryCount, const uint64 mapOffset, + const uint64* map, uint64* outMap, uint64 outMapBucketCounts[_numBuckets+1] ) + { + // Write the key as a map to the final entry location. + // We do this by writing into buckets to final sorted (current) location + // into its original bucket, with the offset in that bucket. + using Job = AnonPrefixSumJob; + + uint32 _totalCounts [_numBuckets+1]; uint32* totalCounts = _totalCounts; + uint64 _totalBitCounts[_numBuckets+1]; uint64* totalBitCounts = _totalBitCounts; + + Job::Run( pool, threadCount, [=]( Job* self ) { + + const uint32 bucketBits = BucketBits; + const uint32 bucketShift = _k - bucketBits; + const uint32 bitSize = EntryBitSize; + const uint32 encodeShift = AddressBitSize; + const uint32 numBuckets = _numBuckets + 1; + + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + uint32 counts[numBuckets] = { 0 }; + uint32 pfxSum[numBuckets]; + + const uint64* inIdx = map + offset; + const uint64* inIdxEnd = map + end; + + // Count buckets + do { + const uint64 b = *inIdx >> bucketShift; + ASSERT( b < numBuckets ); + counts[b]++; + } while( ++inIdx < inIdxEnd ); + + self->CalculatePrefixSum( numBuckets, counts, pfxSum, totalCounts ); + + // Convert map entries from source index to reverse map + const uint64 tableOffset = mapOffset + (uint64)offset; + + const uint64* reverseMap = map + offset; + uint64* outMapBuckets = outMap; + + for( int64 i = 0; i < count; i++ ) + { + const uint64 origin = reverseMap[i]; ASSERT( origin < 0x100000000 + (1ull<<_k) / _numBuckets ); + const uint64 b = origin >> bucketShift; ASSERT( b <= _numBuckets ); + const uint32 dstIdx = --pfxSum[b]; ASSERT( (int64)dstIdx < entryCount ); + + const uint64 finalIdx = tableOffset + (uint64)i; + ASSERT( finalIdx < ( 1ull << encodeShift ) ); + + outMapBuckets[dstIdx] = (origin << encodeShift) | finalIdx; + } + + auto& bitWriter = _bucketWriter; + uint64* bitCounts = totalBitCounts; + + if( self->IsControlThread() ) + { + self->LockThreads(); + + // Convert counts to bit sizes + for( uint32 i = 0; i < numBuckets; i++ ) + bitCounts[i] = (uint64)totalCounts[i] * bitSize; + + byte* writeBuffer = GetWriteBuffer( bucket ); + + // Wait for the buffer to be available first + if( bucket > 1 ) + _writeFence->Wait( bucket - 2, *_writeWaitTime ); + + bitWriter.BeginWriteBuckets( bitCounts, writeBuffer ); + + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + + + // Bit-compress/pack each bucket entries (except the overflow bucket) + uint64 bitsWritten = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + if( counts[i] < 1 ) + { + self->SyncThreads(); + continue; + } + + const uint64 writeOffset = pfxSum[i]; + const uint64 bitOffset = writeOffset * bitSize - bitsWritten; + bitsWritten += bitCounts[i]; + + ASSERT( bitOffset + counts[i] * bitSize <= bitCounts[i] ); + + BitWriter writer = bitWriter.GetWriter( i, bitOffset ); + + const uint64* mapToWrite = outMapBuckets + writeOffset; + const uint64* mapToWriteEnd = mapToWrite + counts[i]; + + // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields + const uint64* mapToWriteEndPass1 = mapToWrite + std::min( counts[i], 2u ); + ASSERT( counts[i] > 2 ); + + while( mapToWrite < mapToWriteEndPass1 ) + writer.Write( *mapToWrite++, bitSize ); + + self->SyncThreads(); + + while( mapToWrite < mapToWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } + + // Write the overflow bucket and then write to disk + self->SyncThreads(); + if( self->IsControlThread() ) + { + const uint32 overflowBucket = _numBuckets; + const uint64 overflowCount = totalCounts[overflowBucket]; + + if( overflowCount ) + { + const uint64 writeOffset = pfxSum[overflowBucket]; + ASSERT( writeOffset * bitSize - bitsWritten == 0 ); + + BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); + + const uint64* mapToWrite = outMapBuckets + writeOffset; + const uint64* mapWriteEnd = mapToWrite + overflowCount; + while( mapToWrite < mapWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } + + bitWriter.Submit(); + _ioQueue->SignalFence( *_writeFence, bucket ); + _ioQueue->CommitCommands(); + } + }); + + for( int32 b = 0; b <= (int32)_numBuckets; b++ ) + outMapBucketCounts[b] += totalCounts[b]; + } + + //----------------------------------------------------------- + void SubmitFinalBits() + { + _bucketWriter.SubmitLeftOvers(); + _ioQueue->SignalFence( *_writeFence, _numBuckets ); + _ioQueue->CommitCommands(); + } + +private: + //----------------------------------------------------------- + inline byte* GetWriteBuffer( const uint32 bucket ) + { + return _writebuffers[bucket & 1]; + } + +private: + DiskBufferQueue* _ioQueue = nullptr; + BitBucketWriter<_numBuckets+1> _bucketWriter; + byte* _writebuffers[2] = { nullptr }; + Fence* _writeFence = nullptr; + Duration* _writeWaitTime = nullptr; +}; + +template +class P3StepOne +{ +public: + // #TODO: Move these to a shared object + static constexpr uint32 _k = _K; + static constexpr uint32 _bucketBits = bblog2( _numBuckets ); + static constexpr uint32 _lpBits = _k * 2 - ( _bucketBits + 1 ); // LPs have at most 2*k-1. Because we ommit the bucket bits, we substract those too. + static constexpr uint32 _idxBits = _k + 1; + static constexpr uint32 _entrySizeBits = _lpBits + _idxBits; // LP, origin index + +public: + //----------------------------------------------------------- + P3StepOne( DiskPlotContext& context, const FileId mapReadId, Fence& readFence, Fence& writeFence ) + : _context ( context ) + , _ioQueue ( *context.ioQueue ) + , _threadCount( context.p3ThreadCount ) + , _mapReadId ( mapReadId ) + , _readFence ( readFence ) + , _writeFence ( writeFence ) + { + _readFence .Reset(); + _writeFence.Reset(); + } + + //----------------------------------------------------------- + inline Duration GetIOWaitTime() const { return _ioWaitTime; } + + //----------------------------------------------------------- + uint64 Run( const uint64 inLMapBucketCounts[_numBuckets+1], uint64 outLPBucketCounts[_numBuckets+1] ) + { + DiskPlotContext& context = _context; + DiskBufferQueue& ioQueue = _ioQueue; + + ioQueue.SeekBucket( FileId::LP, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); + + const TableId lTable = rTable - 1; + const uint64 maxBucketEntries = (uint64)( ( (1ull << _k) / _numBuckets ) * P3_BUCKET_MULTIPLER ); + const size_t rMarksSize = RoundUpToNextBoundary( context.entryCounts[(int)rTable] / 8, (int)context.tmp1BlockSize ); + + // Allocate buffers + StackAllocator allocator( context.heapBuffer, context.heapSize ); + + void* rMarks = allocator.Alloc( rMarksSize, context.tmp1BlockSize ); + + DiskPairAndMapReader<_numBuckets> rTableReader( context, _threadCount, _readFence, rTable, allocator, false ); + + using L1Reader = SingleFileMapReader<_numBuckets, P3_EXTRA_L_ENTRIES_TO_LOAD, uint32>; + using LNReader = DiskMapReader; + + + IP3LMapReader* lReader = nullptr; + + L1Reader lTable1Reader; + LNReader lTableNReader; + uint32* lTableNEntries = nullptr; + + if constexpr ( lTable == TableId::Table1 ) + { + lTable1Reader = L1Reader( FileId::T1, &ioQueue, allocator, maxBucketEntries, context.tmp1BlockSize, context.bucketCounts[(int)TableId::Table1] ); + lReader = &lTable1Reader; + } + else + { + lTableNReader = LNReader( _context, _context.p3ThreadCount, lTable, _mapReadId, allocator, inLMapBucketCounts ); + lTableNEntries = allocator.CAlloc( maxBucketEntries + P3_EXTRA_L_ENTRIES_TO_LOAD ); + } + + { + const size_t perBucketWriteSize = CDiv( maxBucketEntries * _entrySizeBits / _numBuckets, (int)context.tmp2BlockSize * 8 ) * context.tmp2BlockSize; + const size_t writeBufferAllocSize = RoundUpToNextBoundary( perBucketWriteSize * _numBuckets, (int)context.tmp2BlockSize ); + + _lpWriteBuffer[0] = allocator.AllocT( writeBufferAllocSize, context.tmp2BlockSize ); + _lpWriteBuffer[1] = allocator.AllocT( writeBufferAllocSize, context.tmp2BlockSize ); + + byte* blockBuffers = (byte*)allocator.CAlloc( _numBuckets, context.tmp2BlockSize, context.tmp2BlockSize ); + _lpWriter = BitBucketWriter<_numBuckets>( ioQueue, FileId::LP, blockBuffers ); + } + + Pair* pairs = allocator.CAlloc ( maxBucketEntries ); + uint64* map = allocator.CAlloc( maxBucketEntries ); + + _rPrunedLinePoints = allocator.CAlloc( maxBucketEntries ); + _rPrunedMap = allocator.CAlloc( maxBucketEntries ); + + auto GetLLoadCount = [=]( const uint32 bucket ) { + + // Use the original (unpruned) bucket count + const uint64 lEntryCount = _context.bucketCounts[(int)lTable][bucket]; + const uint64 loadCount = bucket == 0 ? lEntryCount + P3_EXTRA_L_ENTRIES_TO_LOAD : + bucket == _numBuckets - 1 ? lEntryCount - P3_EXTRA_L_ENTRIES_TO_LOAD : + lEntryCount; + + return loadCount; + }; + + auto LoadBucket = [&]( const uint32 bucket ) { + + if( lTable == TableId::Table1 ) + lReader->LoadNextBucket(); + // lTable1Reader.LoadNextBucket(); + else + lTableNReader.LoadNextEntries( GetLLoadCount( bucket ) ); + + rTableReader.LoadNextBucket(); + }; + + + // Load initial bucket and the whole marking table + if( rTable < TableId::Table7 ) + ioQueue.ReadFile( FileId::MARKED_ENTRIES_2 + (FileId)rTable - 1, 0, rMarks, rMarksSize ); + + LoadBucket( 0 ); + + Log::Line( "Allocated %.2lf / %.2lf MiB", (double)allocator.Size() BtoMB, (double)allocator.Capacity() BtoMB ); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + // Load next bucket in the background + const bool isLastbucket = bucket + 1 == _numBuckets; + + if( !isLastbucket ) + LoadBucket( bucket + 1 ); + + // Wait for and unpack our current bucket + const uint64 bucketLength = rTableReader.UnpackBucket( bucket, pairs, map, _ioWaitTime ); // This will wait on the read fence + + uint32* lEntries; + + if constexpr ( lTable == TableId::Table1 ) + // lEntries = lTable1Reader.ReadLoadedBucket(); + lEntries = lReader->ReadLoadedBucket(); + else + { + lEntries = lTableNEntries; + + const uintptr_t offset = bucket == 0 ? 0 : P3_EXTRA_L_ENTRIES_TO_LOAD; + + lTableNReader.ReadEntries( GetLLoadCount( bucket ), lEntries + offset ); + } + + ASSERT( bucketLength <= maxBucketEntries ); + + // Convert to line points + uint64 prunedEntryCount = ConvertToLinePoints( bucket, bucketLength, lEntries, + BitField( (uint64*)rMarks, context.entryCounts[(int)rTable] ), pairs, map ); + ASSERT( prunedEntryCount <= bucketLength ); + + WriteLinePointsToBuckets( bucket, (int64)prunedEntryCount, _rPrunedLinePoints, _rPrunedMap, (uint64*)pairs, map, outLPBucketCounts ); + + // #TODO: Remove this after making our T2+ table reader an IP3LMapReader? Or just remove the IP3LMapReader thing? + if constexpr ( lTable > TableId::Table1 ) + { + // ASSERT( 0 ); + if( bucket < _numBuckets - 1 ) + memcpy( lTableNEntries, lTableNEntries + _context.bucketCounts[(int)lTable][bucket], P3_EXTRA_L_ENTRIES_TO_LOAD * sizeof( uint32 ) ); + } + + _prunedEntryCount += prunedEntryCount; + } + + // Submit trailing bits + _lpWriter.SubmitLeftOvers(); + + return _prunedEntryCount; + } + +private: + //----------------------------------------------------------- + uint64 ConvertToLinePoints( + const uint32 bucket, const int64 bucketLength, const uint32* leftEntries, + const BitField& rightMarkedEntries, const Pair* rightPairs, const uint64* rightMap ) + { + int64 __prunedEntryCount[BB_DP_MAX_JOBS]; + int64* _prunedEntryCount = __prunedEntryCount; + + AnonMTJob::Run( *_context.threadPool, _threadCount, [=]( AnonMTJob* self ) { + + int64 count, offset, end; + GetThreadOffsets( self, bucketLength, count, offset, end ); + + const uint32* lMap = leftEntries; + const Pair* pairs = rightPairs; + const uint64* rMap = rightMap; + const BitField markedEntries = rightMarkedEntries; + + // First, scan our entries in order to prune them + int64 prunedLength = 0; + int64* allPrunedLengths = (int64*)_prunedEntryCount; + + if constexpr ( rTable < TableId::Table7 ) + { + for( int64 i = offset; i < end; i++ ) + { + if( markedEntries.Get( rMap[i] ) ) + prunedLength ++; + } + } + else + { + prunedLength = count; + } + + allPrunedLengths[self->_jobId] = prunedLength; + self->SyncThreads(); + + + // Set our destination offset + // #NOTE: Not necesarry for T7, but let's avoid code duplication for now. + int64 dstOffset = 0; + + for( int32 i = 0; i < (int32)self->_jobId; i++ ) + dstOffset += allPrunedLengths[i]; + + // Copy pruned entries into a new, contiguous buffer + // #TODO: check if doing 1 pass per buffer performs better + static_assert( sizeof( Pair ) == sizeof( uint64 ) ); + + Pair* outPairsStart = (Pair*)(_rPrunedLinePoints + dstOffset); + Pair* outPairs = outPairsStart; + uint64* outRMap = _rPrunedMap + dstOffset; + uint64* mapWriter = outRMap; + + #if _DEBUG + int64 secondPassPruneCount = 0; + #endif + + for( int64 i = offset; i < end; i++ ) + { + const uint64 mapIdx = rMap[i]; + + if constexpr ( rTable < TableId::Table7 ) + { + if( !markedEntries.Get( mapIdx ) ) + continue; + } + + #if _DEBUG + secondPassPruneCount ++; + #endif + + *outPairs = pairs[i]; + *mapWriter = mapIdx; + + outPairs++; + mapWriter++; + } + ASSERT( secondPassPruneCount == prunedLength ); + ASSERT( (uintptr_t)outPairs == (uintptr_t)(_rPrunedLinePoints + dstOffset + prunedLength) ); + + + // Now we can convert our pruned pairs to line points + uint64* outLinePoints = _rPrunedLinePoints + dstOffset; + ASSERT( (uintptr_t)outLinePoints == (uintptr_t)outPairsStart); + { + const uint32* lTable = lMap; + + for( int64 i = 0; i < prunedLength; i++ ) + { + Pair p = outPairsStart[i]; + + const uint64 x = lTable[p.left ]; + const uint64 y = lTable[p.right]; + + ASSERT( x || y ); + outLinePoints[i] = SquareToLinePoint( x, y ); + } + } + }); + + int64 prunedEntryCount = 0; + for( int32 i = 0; i < (int32)_threadCount; i++ ) + prunedEntryCount += _prunedEntryCount[i]; + + return (uint64)prunedEntryCount; + } + + //----------------------------------------------------------- + void WriteLinePointsToBuckets( const uint32 bucket, const int64 entryCount, const uint64* linePoints, const uint64* indices, + uint64* tmpLPs, uint64* tmpIndices, uint64 outLPBucketCounts[_numBuckets+1] ) + { + using LPJob = AnonPrefixSumJob; + + uint32 __totalCounts[_numBuckets]; uint32* _totalCounts = __totalCounts; + uint64 _bitCounts [_numBuckets]; uint64* bitCounts = _bitCounts; + + LPJob::Run( *_context.threadPool, _threadCount, [=]( LPJob* self ) { + + const uint32 threadCount = self->JobCount(); + + const uint32 entrySizeBits = _entrySizeBits; + const uint32 bucketShift = _lpBits; + + const uint64* srcLinePoints = linePoints; + const uint64* srcIndices = indices; + + uint32* totalCounts = (uint32*)_totalCounts; + uint32 counts[_numBuckets]; + uint32 pfxSum[_numBuckets]; + + memset( counts, 0, sizeof( counts ) ); + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + /// Count entries per bucket + for( const uint64* lp = srcLinePoints + offset, *lpEnd = srcLinePoints + end; lp < lpEnd; lp++ ) + { + const uint64 b = (*lp) >> bucketShift; ASSERT( b < _numBuckets ); + counts[b]++; + } + + self->CalculatePrefixSum( _numBuckets, counts, pfxSum, (uint32*)totalCounts ); + + /// Distribute entries to their respective buckets + uint64* lpBuckets = tmpLPs; + uint64* idxBuckets = tmpIndices; + + for( int64 i = offset; i < end; i++ ) + { + const uint64 lp = srcLinePoints[i]; + const uint64 bucket = lp >> bucketShift; ASSERT( bucket < _numBuckets ); + const uint32 dstIndex = --pfxSum[bucket]; + + ASSERT( dstIndex < entryCount ); + + lpBuckets [dstIndex] = lp; + idxBuckets[dstIndex] = srcIndices[i]; + } + + /// Prepare to write to disk + auto& bucketWriter = _lpWriter; + uint64* totalBucketBitCounts = (uint64*)bitCounts; + + if( self->IsControlThread() ) + { + self->LockThreads(); + + for( uint32 i = 0; i < _numBuckets; i++ ) + totalBucketBitCounts[i] = totalCounts[i] * (uint64)entrySizeBits; + + bucketWriter.BeginWriteBuckets( totalBucketBitCounts, GetLPWriteBuffer( bucket ) ); + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + + /// Bit-pack entries and write to disk + uint64 bitsWritten = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + const uint64 writeOffset = pfxSum[i]; + const uint64 bitOffset = writeOffset * entrySizeBits - bitsWritten; + bitsWritten += totalBucketBitCounts[i]; + + ASSERT( bitOffset + counts[i] * entrySizeBits <= totalBucketBitCounts[i] ); + + BitWriter writer = bucketWriter.GetWriter( i, bitOffset ); + + const uint64* lp = lpBuckets + writeOffset; + const uint64* idx = idxBuckets + writeOffset; + + // If we have too few entries, just have a single thread pack them + if( totalCounts[i] <= threadCount*3 ) + { + if( self->_jobId == 0 && totalCounts[i] > 0 ) + PackEntries( totalCounts[i], writer, lp, idx, i ); + + self->SyncThreads(); + continue; + } + + // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields + const int64 firstWrite = (int64)std::min( 2u, counts[i] ); + const int64 secondWrite = (int64)counts[i] >= 2 ? counts[i] - 2 : 0; + ASSERT( counts[i] == 0 || counts[i] > 2 ); + + PackEntries( firstWrite, writer, lp, idx, i ); + self->SyncThreads(); + PackEntries( secondWrite, writer, lp+2, idx+2, i ); + } + + /// Write buckets to disk + if( self->IsControlThread() ) + { + self->LockThreads(); + bucketWriter.Submit(); + _ioQueue.SignalFence( _writeFence, bucket ); + _ioQueue.CommitCommands(); + self->ReleaseThreads(); + } + else + self->WaitForRelease(); // Don't go out of scope + }); + + for( int32 b = 0; b < (int32)_numBuckets; b++ ) + outLPBucketCounts[b] += _totalCounts[b]; + } + + //----------------------------------------------------------- + inline void PackEntries( const int64 count, BitWriter& writer, const uint64* lps, const uint64* indices, const uint32 bucket ) + { + BitReader reader( (uint64*)writer.Fields(), writer.Capacity(), writer.Position() ); + + for( int64 i = 0; i < count; i++ ) + { + writer.Write( lps [i], _lpBits ); + writer.Write( indices[i], _idxBits ); + + ASSERT( indices[i] < (1ull << _K) + ((1ull << _K) / _numBuckets) ); + } + } + + //----------------------------------------------------------- + byte* GetLPWriteBuffer( const uint32 bucket ) + { + if( bucket > 1 ) + _writeFence.Wait( bucket - 2, _ioWaitTime ); + + return _lpWriteBuffer[bucket & 1]; + } + +private: + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; + uint32 _threadCount; + FileId _mapReadId; + Fence& _readFence; + Fence& _writeFence; + Duration _ioWaitTime = Duration::zero(); + + // Temporary buffer for storing the pruned pairs/linePoints and map + uint64* _rPrunedLinePoints = nullptr; + uint64* _rPrunedMap = nullptr; + + BitBucketWriter<_numBuckets> _lpWriter; + byte* _lpWriteBuffer[2] = { nullptr }; + + uint64 _prunedEntryCount = 0; +}; + +template +class P3StepTwo +{ +public: + // #TODO: Move these to a shared object + static constexpr uint32 _k = _K; + static constexpr uint32 _bucketBits = bblog2( _numBuckets ); + static constexpr uint32 _lpBits = _k * 2 - ( _bucketBits + 1 ); // LPs have at most 2*k-1. Because we ommit the bucket bits, we substract those too. + static constexpr uint32 _idxBits = _k + 1; + static constexpr uint32 _entrySizeBits = _lpBits + _idxBits; // LP, origin index + +public: + //----------------------------------------------------------- + P3StepTwo( DiskPlotContext& context, Fence& readFence, Fence& writeFence, Fence& lpWriteFence, const FileId readId, const FileId writeId ) + : _context ( context ) + , _ioQueue ( *context.ioQueue ) + , _threadCount ( context.p3ThreadCount ) + , _readFence ( readFence ) + , _writeFence ( writeFence ) + , _lpWriteFence( lpWriteFence ) + , _readId ( readId ) + , _writeId ( writeId ) + { + _readFence .Reset(); + _writeFence .Reset(); + _lpWriteFence.Reset(); + } + + //----------------------------------------------------------- + inline Duration GetIOWaitTime() const { return _ioWaitTime; } + + //----------------------------------------------------------- + void Run( const uint64 inLPBucketCounts[_numBuckets+1], uint64 outLMapBucketCounts[_numBuckets+1] ) + { + constexpr bool _overflow = rTable == TableId::Table7; + + _ioQueue.SeekBucket( FileId::LP, 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); + + const TableId lTable = rTable - 1; + const uint64 maxBucketEntries = (uint64)( ( (1ull << _k) / _numBuckets ) * P3_BUCKET_MULTIPLER ); + + // Allocate buffers and needed structures + StackAllocator allocator( _context.heapBuffer, _context.heapSize ); + + const size_t readBufferSize = RoundUpToNextBoundary( CDiv( maxBucketEntries * _entrySizeBits, 8 ), (int)_context.tmp2BlockSize ); + byte* readBuffers[2] = { + allocator.AllocT( readBufferSize, _context.tmp2BlockSize ), + allocator.AllocT( readBufferSize, _context.tmp2BlockSize ), + }; + + uint64* linePoints = allocator.CAlloc( maxBucketEntries + kEntriesPerPark ); // Need to add kEntriesPerPark so we can copy + uint64* tmpLinePoints = allocator.CAlloc( maxBucketEntries + kEntriesPerPark ); // the park overflows from the previous bucket. + uint64* indices = allocator.CAlloc( maxBucketEntries ); + uint64* tmpIndices = allocator.CAlloc( maxBucketEntries ); + + MapWriter<_numBuckets, _overflow> mapWriter( _ioQueue, _writeId, allocator, maxBucketEntries, _context.tmp2BlockSize, _writeFence, _ioWaitTime ); + + const size_t parkSize = CalculateParkSize( lTable ); + _maxParkCount = maxBucketEntries / kEntriesPerPark; + _lpLeftOverBuffer = allocator.CAlloc( kEntriesPerPark ); + _parkBuffers[0] = allocator.AllocT( parkSize * _maxParkCount ); + _parkBuffers[1] = allocator.AllocT( parkSize * _maxParkCount ); + + Log::Line( "Step 2 using %.2lf / %.2lf GiB.", (double)allocator.Size() BtoGB, (double)allocator.Capacity() BtoGB ); + + // Start processing buckets + auto LoadBucket = [=]( uint32 bucket ) { + const size_t readSize = RoundUpToNextBoundary( CDiv( inLPBucketCounts[bucket] * _entrySizeBits, 8 ), (int)_context.tmp2BlockSize ); + + _ioQueue.ReadFile( FileId::LP, bucket, readBuffers[bucket & 1], readSize ); + _ioQueue.SignalFence( _readFence, bucket + 1 ); + _ioQueue.CommitCommands(); + }; + + LoadBucket( 0 ); + + uint64 mapOffset = 0; + + const uint32 endBucket = rTable == TableId::Table7 ? _numBuckets : _numBuckets-1; + for( uint32 bucket = 0; bucket <= endBucket; bucket++ ) + { + const bool isLastBucket = bucket == endBucket; + const bool nextBucketEmpty = !isLastBucket && inLPBucketCounts[bucket+1] == 0; + const bool hasNextBucket = !isLastBucket && !nextBucketEmpty; + + const int64 entryCount = (int64)inLPBucketCounts[bucket]; + if( entryCount < 1 ) + break; + + ASSERT( (uint64)entryCount <= maxBucketEntries ); + + if( hasNextBucket ) + LoadBucket( bucket + 1 ); + + _readFence.Wait( bucket + 1, _ioWaitTime ); + + + uint64* unpackedLinePoints = linePoints + kEntriesPerPark; + uint64* unpackedTmpLinePoints = tmpLinePoints + kEntriesPerPark; + + // Unpack bucket + const byte* packedEntries = readBuffers[bucket & 1]; + UnpackEntries( bucket, entryCount, packedEntries, unpackedLinePoints, indices ); + + // Sort on LP + EntrySort::SortEntries<_numBuckets, _lpBits>( *_context.threadPool, _threadCount, entryCount, unpackedLinePoints, unpackedTmpLinePoints, indices, tmpIndices ); + + uint64* sortedLinePoints = unpackedLinePoints; + uint64* sortedIndices = indices; + uint64* scratchIndices = tmpIndices; + + // If our iteration count is not even, it means the final + // output of the sort is saved in the tmp buffers. + constexpr int32 maxSortIter = (int)CDiv( 64 - _bucketBits, 8 ); + + if( ( maxSortIter & 1 ) != 0) + { + sortedLinePoints = unpackedTmpLinePoints; + std::swap( sortedIndices, scratchIndices ); + } + + #if _DEBUG + // ValidateLinePoints( lTable, _context, bucket, sortedLinePoints, (uint64)entryCount ); + #endif + + // Write reverse map to disk + mapWriter.Write( *_context.threadPool, _threadCount, bucket, entryCount, mapOffset, sortedIndices, scratchIndices, outLMapBucketCounts ); + + // Write LP's as parks into the plot file + if( _lpParkLeftOvers ) + { + sortedLinePoints -= _lpParkLeftOvers; + memcpy( sortedLinePoints, _lpLeftOverBuffer, _lpParkLeftOvers * sizeof( uint64 ) ); + } + + // #NOTE: sortedLinePoints get mutated here + WriteLinePointsToPlot( allocator, bucket, (uint64)entryCount, sortedLinePoints, hasNextBucket ); + + mapOffset += (uint64)entryCount; + } + + + mapWriter.SubmitFinalBits(); + + // Wait for all writes to finish + _ioQueue.SignalFence( _lpWriteFence, _numBuckets + 5 ); + _ioQueue.CommitCommands(); + _lpWriteFence.Wait( _numBuckets + 5 ); + } + +private: + + //----------------------------------------------------------- + void UnpackEntries( const uint32 bucket, const int64 entryCount, const byte* packedEntries, uint64* outLinePoints, uint64* outIndices ) + { + AnonMTJob::Run( *_context.threadPool, _threadCount, [=]( AnonMTJob* self ) { + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + BitReader reader( (uint64*)packedEntries, _entrySizeBits * (uint64)entryCount, (uint64)offset * _entrySizeBits ); + + uint64* linePoints = outLinePoints; + uint64* indices = outIndices; + ASSERT( indices + entryCount ) + + const uint64 bucketMask = ((uint64)bucket) << _lpBits; + for( int64 i = offset; i < end; i++ ) + { + const uint64 lp = reader.ReadBits64( _lpBits ) | bucketMask; + const uint64 idx = reader.ReadBits64( _idxBits ); + + ASSERT( idx < (1ull << _K) + ((1ull << _K) / _numBuckets) ); + + linePoints[i] = lp; + indices [i] = idx; + } + }); + } + + //----------------------------------------------------------- + void WriteLinePointsToPlot( IAllocator& allocator, const uint32 bucket, const uint64 entryCount, uint64* inLinePoints, const bool hasNextBucket ) + { + ASSERT( entryCount ); + ASSERT( inLinePoints ); + + DiskBufferQueue& ioQueue = *_context.ioQueue; + + const TableId lTable = rTable - 1; + const size_t parkSize = CalculateParkSize( lTable ); + + /// Encode into parks + byte* parkBuffer = GetLPWriteBuffer( bucket ); + + const uint64 entriesToEncode = entryCount + _lpParkLeftOvers; + const uint64 parkCount = entriesToEncode / kEntriesPerPark; ASSERT( parkCount <= _maxParkCount ); + const uint64 overflowEntries = entriesToEncode - parkCount * kEntriesPerPark; + + uint64* lpOverflowStart = inLinePoints + entriesToEncode - overflowEntries; + + // Copy overflow entries for the next bucket + _lpParkLeftOvers = overflowEntries; + + if( overflowEntries ) + memcpy( _lpLeftOverBuffer, lpOverflowStart, sizeof( uint64 ) * overflowEntries ); + + AnonMTJob::Run( *_context.threadPool, _context.p3ThreadCount, [=]( AnonMTJob* self ){ + + uint64 count, offset, end; + GetThreadOffsets( self, parkCount, count, offset, end ); + + const TableId lTable = rTable - 1; + const size_t parkSize = CalculateParkSize( lTable ); + + uint64* parkLinePoints = inLinePoints + offset * kEntriesPerPark; + byte* parkWriteBuffer = parkBuffer + offset * parkSize; + + for( uint64 i = 0; i < count; i++ ) + { + // #NOTE: This functions mutates inLinePoints + WritePark( parkSize, kEntriesPerPark, (uint64*)parkLinePoints, parkWriteBuffer, lTable ); + parkLinePoints += kEntriesPerPark; + parkWriteBuffer += parkSize; + } + }); + + const size_t sizeWritten = parkSize * parkCount; + _context.plotTableSizes[(int)lTable] += sizeWritten; + + ioQueue.WriteFile( FileId::PLOT, 0, parkBuffer, sizeWritten ); + ioQueue.SignalFence( _lpWriteFence, bucket ); + ioQueue.CommitCommands(); + + + // If it's the last bucket or the next bucket has no entries (might happen with the overflow bucket), + // then write an extra left-over park, if we have left-over entries. + if( !hasNextBucket ) + { + if( overflowEntries ) + { + // #NOTE: This functions mutates inLinePoints + byte* finalPark = allocator.AllocT( parkSize ); + WritePark( parkSize, overflowEntries, lpOverflowStart, finalPark, lTable ); + + _context.plotTableSizes[(int)lTable] += parkSize; + ioQueue.WriteFile( FileId::PLOT, 0, finalPark, parkSize ); + ioQueue.CommitCommands(); + } + + return; + } + } + + //----------------------------------------------------------- + byte* GetLPWriteBuffer( const uint32 bucket ) + { + if( bucket > 1 ) + _lpWriteFence.Wait( bucket - 2, _ioWaitTime ); + + return _parkBuffers[bucket & 1]; + } + +private: + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; + uint32 _threadCount; + Fence& _readFence; + Fence& _writeFence; + Fence& _lpWriteFence; + Duration _ioWaitTime = Duration::zero(); + FileId _readId; + FileId _writeId; + uint64* _lpLeftOverBuffer = nullptr; + uint64 _lpParkLeftOvers = 0; + uint64 _maxParkCount = 0; + byte* _parkBuffers[2] = { nullptr }; +}; + + +//----------------------------------------------------------- +DiskPlotPhase3::DiskPlotPhase3( DiskPlotContext& context ) + : _context( context ) + , _ioQueue( *context.ioQueue ) +{} + +//----------------------------------------------------------- +DiskPlotPhase3::~DiskPlotPhase3() {} + +//----------------------------------------------------------- +void DiskPlotPhase3::Run() +{ + DiskBufferQueue& ioQueue = *_context.ioQueue; + + ioQueue.SeekFile( FileId::T1, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T2, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T3, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T4, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T5, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T6, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::T7, 0, 0, SeekOrigin::Begin ); + + ioQueue.SeekBucket( FileId::MAP2, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP3, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP4, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP5, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP6, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::MAP7, 0, SeekOrigin::Begin ); + + ioQueue.SeekFile( FileId::MARKED_ENTRIES_2, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::MARKED_ENTRIES_3, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::MARKED_ENTRIES_4, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::MARKED_ENTRIES_5, 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile( FileId::MARKED_ENTRIES_6, 0, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); + + // Use up any cache for our line points and map + size_t lpCacheSize, mapCacheSize; + GetCacheSizes( lpCacheSize, mapCacheSize ); + + ASSERT( lpCacheSize / _context.tmp2BlockSize * _context.tmp2BlockSize == lpCacheSize ); + ASSERT( mapCacheSize / _context.tmp2BlockSize * _context.tmp2BlockSize == mapCacheSize ); + + byte* cache = _context.cache; + + FileSetOptions opts = FileSetOptions::UseTemp2; + + if( !_context.cfg->noTmp2DirectIO ) + opts |= FileSetOptions::DirectIO; + + if( _context.cache ) + opts |= FileSetOptions::Cachable; + + FileSetInitData fdata; + fdata.cache = cache; + fdata.cacheSize = lpCacheSize; + + ioQueue.InitFileSet( FileId::LP, "lp", _context.numBuckets, opts, &fdata ); // LP+origin idx buckets + + fdata.cache = (cache += lpCacheSize); + fdata.cacheSize = mapCacheSize; + + ioQueue.InitFileSet( FileId::LP_MAP_0, "lp_map_0", _context.numBuckets+1, opts, &fdata ); // Reverse map write/read + fdata.cache = (cache += mapCacheSize); + ioQueue.InitFileSet( FileId::LP_MAP_1, "lp_map_1", _context.numBuckets+1, opts, &fdata ); // Reverse map read/write + + switch( _context.numBuckets ) + { + case 128 : RunBuckets<128 >(); break; + case 256 : RunBuckets<256 >(); break; + case 512 : RunBuckets<512 >(); break; + case 1024: RunBuckets<1024>(); break; + + default: + ASSERT( 0 ); + break; + } + + // Delete remaining temporary files + #if !BB_DP_P3_KEEP_FILES + ioQueue.DeleteBucket( FileId::LP ); + ioQueue.DeleteBucket( FileId::LP_MAP_0 ); + ioQueue.DeleteBucket( FileId::LP_MAP_1 ); + ioQueue.SignalFence( _stepFence, 0xFFFFFFFF ); + ioQueue.CommitCommands(); + _stepFence.Wait( 0xFFFFFFFF ); + #endif +} + +//----------------------------------------------------------- +void DiskPlotPhase3::GetCacheSizes( size_t& outCacheSizeLP, size_t& outCacheSizeMap ) +{ + switch( _context.numBuckets ) + { + case 128 : GetCacheSizesForBuckets<128 >( outCacheSizeLP, outCacheSizeMap ); break; + case 256 : GetCacheSizesForBuckets<256 >( outCacheSizeLP, outCacheSizeMap ); break; + case 512 : GetCacheSizesForBuckets<512 >( outCacheSizeLP, outCacheSizeMap ); break; + case 1024: GetCacheSizesForBuckets<1024>( outCacheSizeLP, outCacheSizeMap ); break; + + default: + Fatal( "Invalid bucket count %u.", _context.numBuckets ); + break; + } +} + +//----------------------------------------------------------- +template +void DiskPlotPhase3::GetCacheSizesForBuckets( size_t& outCacheSizeLP, size_t& outCacheSizeMap ) +{ + const size_t lpEntrySize = P3StepOne::_entrySizeBits; + const size_t mapEntrySizeX2 = MapWriter<_numBuckets, true>::EntryBitSize * 2; + + static_assert( mapEntrySizeX2 >= lpEntrySize ); + + const size_t fullCache = _context.cacheSize; + const size_t blockSize = _context.tmp2BlockSize; + + double mapRatio = (double)mapEntrySizeX2 / ( mapEntrySizeX2 + lpEntrySize ); + + const uint32 mapBuckets = _numBuckets + 1; + + outCacheSizeMap = ((size_t)(fullCache * mapRatio) / 2 ) / mapBuckets / blockSize * mapBuckets * blockSize; + outCacheSizeLP = ( fullCache - outCacheSizeMap * 2 ) / _numBuckets / blockSize * _numBuckets * blockSize; + + ASSERT( outCacheSizeMap + outCacheSizeLP <= fullCache ); +} + +//----------------------------------------------------------- +template +void DiskPlotPhase3::RunBuckets() +{ + TableId startTable = TableId::Table2; + +#if _DEBUG && defined( BB_DP_DBG_P3_SKIP_TO_TABLE ) + startTable = BB_DP_DBG_P3_START_TABLE; + + if( ((int)startTable & 1) == 0 ) + std::swap( _mapReadId, _mapWriteId ); + + if( startTable > TableId::Table2 ) + SavePrunedBucketCount( startTable - 1, _lMapPrunedBucketCounts, true ); + + _context.plotTablePointers[(int)startTable-1] = _ioQueue.PlotTablePointersAddress(); +#endif + + for( TableId rTable = startTable; rTable <= TableId::Table7; rTable++ ) + { + Log::Line( "Compressing tables %u and %u.", rTable, rTable+1 ); + const auto timer = TimerBegin(); + switch( rTable ) + { + case TableId::Table2: ProcessTable(); break; + case TableId::Table3: ProcessTable(); break; + case TableId::Table4: ProcessTable(); break; + case TableId::Table5: ProcessTable(); break; + case TableId::Table6: ProcessTable(); break; + case TableId::Table7: ProcessTable(); break; + default: + ASSERT( 0 ); + break; + } + + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished compressing tables %u and %u in %.2lf seconds.", rTable, rTable+1, elapsed ); + + std::swap( _mapReadId, _mapWriteId ); + + _ioQueue.SeekBucket( _mapReadId , 0, SeekOrigin::Begin ); + _ioQueue.SeekBucket( _mapWriteId, 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); + + // Set the table offset for the next table + _context.plotTablePointers[(int)rTable] = _context.plotTablePointers[(int)rTable-1] + _context.plotTableSizes[(int)rTable-1]; + } + + // Finish up with table 7 which needs to be sorted on f7. We use its map for that + { + Log::Line( "Writing P7 parks." ); + const auto timer = TimerBegin(); + WritePark7<_numBuckets>( _lMapPrunedBucketCounts ); + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished writing P7 parks in %.2lf seconds.", elapsed ); + Log::Line( "P7 I/O wait time: %.2lf seconds", TicksToSeconds( _ioWaitTime ) ); + + _context.ioWaitTime += _ioWaitTime; + } +} + +//----------------------------------------------------------- +template +void DiskPlotPhase3::ProcessTable() +{ + uint64 prunedEntryCount; + + // Step 1: Converts pairs to line points whilst prunning the entries, + // then writes them to buckets, alog with their source index, + // for sorting in the second step. + { + memset( _lpPrunedBucketCounts, 0, sizeof( uint64 ) * (_numBuckets+1) ); + + P3StepOne stepOne( _context, _mapReadId, _readFence, _writeFence ); + prunedEntryCount = stepOne.Run( _lMapPrunedBucketCounts, _lpPrunedBucketCounts ); + + _ioWaitTime = stepOne.GetIOWaitTime(); + } + + _ioQueue.SignalFence( _stepFence ); + + // OK to delete input files now + #if !BB_DP_P3_KEEP_FILES + if( rTable == TableId::Table2 ) + _ioQueue.DeleteFile( FileId::T1, 0 ); + + _ioQueue.DeleteFile( FileId::T1 + (FileId)rTable, 0 ); + _ioQueue.DeleteBucket( FileId::MAP2 + (FileId)rTable-1 ); + + if( rTable < TableId::Table7 ) + _ioQueue.DeleteFile( FileId::MARKED_ENTRIES_2 + (FileId)rTable-1, 0 ); + #endif + + _ioQueue.CommitCommands(); + + + // Wait for all step 1 writes to complete + _stepFence.Wait( 0, _ioWaitTime ); // #TODO: Wait on Step1 instead? + + // Step 1: Loads line points & their source indices from buckets, + // sorts them on the line points and then writes the line points + // as parks into the plot file. The sorted indices are then written as + // a reverse map into their origin buckets. This reverse map serves + // as the L table input for the next table. + { + memset( _lMapPrunedBucketCounts, 0, sizeof( uint64 ) * (_numBuckets+1) ); + + P3StepTwo stepTwo( _context, _readFence, _writeFence, _plotFence, _mapReadId, _mapWriteId ); + stepTwo.Run( _lpPrunedBucketCounts, _lMapPrunedBucketCounts ); + + _ioWaitTime += stepTwo.GetIOWaitTime(); + } + + Log::Line( "Table %u now has %llu / %llu ( %.2lf%% ) entries.", + rTable, prunedEntryCount, _context.entryCounts[(int)rTable], + prunedEntryCount / (double)_context.entryCounts[(int)rTable] * 100 ); + + Log::Line( "Table %u I/O wait time: %.2lf seconds.", rTable, TicksToSeconds( _ioWaitTime ) ); + +#if _DEBUG + SavePrunedBucketCount( rTable, _lMapPrunedBucketCounts, false ); +#endif + + _context.ioWaitTime += _ioWaitTime; + _tablePrunedEntryCount[(int)rTable-1] = prunedEntryCount; +} + +//----------------------------------------------------------- +template +void DiskPlotPhase3::WritePark7( const uint64 inMapBucketCounts[_numBuckets+1] ) +{ + DiskPlotContext& context = _context; + DiskBufferQueue& ioQueue = *context.ioQueue; + ThreadPool& pool = *context.threadPool; + + Duration waitTime = Duration::zero(); + + _readFence .Reset(); + _writeFence.Reset(); + + const uint64 maxBucketEntries = inMapBucketCounts[0]; // All buckets are the same size at this point, except the last one which could be less + const uint64 maxParkCount = maxBucketEntries / kEntriesPerPark; + const size_t parkSize = CalculatePark7Size( _K ); + + const size_t plotBlockSize = ioQueue.BlockSize( FileId::PLOT ); + + StackAllocator allocator( context.heapBuffer, context.heapSize ); + + DiskMapReader mapReader( context, context.p3ThreadCount, TableId::Table7, _mapReadId, allocator, inMapBucketCounts ); + + // Allocate an extra park's worth of entries so that we can use it as a 'prefix zone' + // to copy left over entries from a bucket that did not fit into a park. + uint64* t6Indices = allocator.CAlloc( maxBucketEntries + kEntriesPerPark ); + + byte* parkBuffers[2] = { + allocator.AllocT( parkSize * maxParkCount, plotBlockSize ), + allocator.AllocT( parkSize * maxParkCount, plotBlockSize ) + }; + + /// Internal Funcs + auto GetParkBuffer = [&]( const uint32 bucket ) { + + if( bucket > 1 ) + _writeFence.Wait( bucket - 2, waitTime ); + + return parkBuffers[bucket & 1]; + }; + + auto LoadBucket = [&]( const uint32 bucket ) { + + const uint64 bucketLength = inMapBucketCounts[bucket];// mapReader.GetVirtualBucketLength( bucket ); + + if( bucketLength ) + mapReader.LoadNextEntries( bucketLength ); + + ioQueue.SignalFence( _readFence, bucket + 1 ); + ioQueue.CommitCommands(); + }; + +// #if _DEBUG +// uint32* refP7Entries = nullptr; + +// Log::Line( "Loading Reference P7"); +// { +// uint64 refEntryCount = 0; +// Debug::LoadRefTableByName( "plot_p7.tmp", refP7Entries, refEntryCount ); +// } +// const uint32* refP7Reader = refP7Entries; + +// uint64* allP7Entries = bbcvirtalloc( context.entryCounts[6] ); +// uint64* allP7EntriesTmp = bbcvirtalloc( context.entryCounts[6] ); +// uint64* p7Writer = allP7Entries; +// uint64 _parkIdx = 0; +// #endif + + /// Start writeing buckets to park 7 + uint64 leftOverEntryCount = 0; + + LoadBucket( 0 ); + + for( uint32 bucket = 0; bucket <= _numBuckets; bucket++ ) + { + const bool isLastBucket = bucket == _numBuckets; + const bool nextBucketEmpty = !isLastBucket && inMapBucketCounts[bucket+1] == 0; + const bool hasNextBucket = !isLastBucket && !nextBucketEmpty; + + if( hasNextBucket ) + LoadBucket( bucket + 1 ); + + /// Read bucket + const uint64 bucketLength = inMapBucketCounts[bucket]; ASSERT( bucketLength <= maxBucketEntries ); + + _readFence.Wait( bucket + 1, waitTime ); + mapReader.ReadEntries( bucketLength, t6Indices + leftOverEntryCount ); // Load entries to the buffer starting + // at the point after the left-over entries. + const uint64 entriesToEncode = bucketLength + leftOverEntryCount; + + /// Encode into parks + const uint64 parkCount = entriesToEncode / kEntriesPerPark; ASSERT( parkCount <= maxParkCount ); + const uint64 overflowEntries = entriesToEncode - parkCount * kEntriesPerPark; + + byte* parkBuffer = GetParkBuffer( bucket ); + + + AnonMTJob::Run( pool, context.p3ThreadCount, [=]( AnonMTJob* self ){ + + uint64 count, offset, end; + GetThreadOffsets( self, parkCount, count, offset, end ); + + const size_t parkSize = CalculatePark7Size( _K ); + const uint64* park7Entries = t6Indices + offset * kEntriesPerPark; + byte* parkWriteBuffer = parkBuffer + offset * parkSize; + + for( uint64 i = 0; i < count; i++ ) + { + TableWriter::WriteP7Entries( kEntriesPerPark, park7Entries, parkWriteBuffer, self->_jobId ); + park7Entries += kEntriesPerPark; + parkWriteBuffer += parkSize; + } + }); + + const size_t sizeWritten = parkSize * parkCount; + context.plotTableSizes[(int)TableId::Table7] += sizeWritten; + + ioQueue.WriteFile( FileId::PLOT, 0, parkBuffer, sizeWritten ); + ioQueue.SignalFence( _writeFence, bucket ); + ioQueue.CommitCommands(); + + + // If it's the last bucket or the next bucket has no entries (might happen with the overflow bucket), + // then write an extra left-over park, if we have left-over entries. + uint64* indexOverflowStart = t6Indices + entriesToEncode - overflowEntries; + + if( !hasNextBucket ) + { + if( overflowEntries ) + { + byte* finalPark = allocator.AllocT( parkSize ); + TableWriter::WriteP7Entries( overflowEntries, indexOverflowStart, finalPark, 0 ); + + context.plotTableSizes[(int)TableId::Table7] += parkSize; + ioQueue.WriteFile( FileId::PLOT, 0, finalPark, parkSize ); + ioQueue.CommitCommands(); + } + + break; + } + + /// Copy overflow entries for the next bucket + leftOverEntryCount = overflowEntries; + + if( overflowEntries ) + memcpy( t6Indices, indexOverflowStart, sizeof( uint64 ) * overflowEntries ); + } + + // Wait for all writes to finish + ioQueue.SignalFence( _writeFence, _numBuckets + 2 ); + ioQueue.CommitCommands(); + _writeFence.Wait( _numBuckets + 2 ); + + // Save IO wait times + _ioWaitTime = waitTime; +} + + +#if _DEBUG + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + +//----------------------------------------------------------- +void ValidateLinePoints( const TableId table, const DiskPlotContext& context, const uint32 bucket, const uint64* linePoints, const uint64 length ) +{ + static TableId _loadedTable = TableId::_Count; + static uint64* _refLPs = nullptr; + static uint64 _refEntryCount = 0; + static uint64 _refLPOffset = 0; + + if( _refLPs == nullptr ) + { + _refLPs = bbvirtallocbounded( sizeof( uint64 ) * context.entryCounts[(int)TableId::Table7] ); // T7 is the only one that won't be pruned. + // So all other tables should fit here. + } + + if( table != _loadedTable ) + { + // Time to load a new table and reset the reader to the beginning + _loadedTable = table; + + Debug::LoadRefLinePointTable( table, _refLPs, _refEntryCount ); + ASSERT( _refEntryCount <= context.entryCounts[(int)TableId::Table7] ); + + _refLPOffset = 0; + } + + ASSERT( _refLPOffset + length <= _refEntryCount ); + + AnonMTJob::Run( *context.threadPool, 1, [=]( AnonMTJob* self ) { + + uint64 count, offset, end; + GetThreadOffsets( self, length, count, offset, end ); + + const uint64* refLPReader = _refLPs + _refLPOffset + offset; + const uint64* lpReader = linePoints + offset; + + for( uint64 i = 0; i < count; i++ ) + { + // ASSERT( lpReader[i] == refLPReader[i] ); + // To skip the extra entry for now, lets test like this: + if( lpReader[i] != refLPReader[i] ) + { + ASSERT( 0 ); + if( lpReader[i+1] == refLPReader[i] ) + { + lpReader++; + continue; + } + ASSERT( 0 ); + } + } + + _refLPOffset += length; + }); + + if( bucket == context.numBuckets - 1 ) + Log::Line( "LinePoints Validated Successfully!" ); +} + +//----------------------------------------------------------- +void SavePrunedBucketCount( const TableId table, uint64* bucketCounts, bool read ) +{ + FileStream file; + + char path[1024]; + sprintf( path, "%sp3.t%d.buckets.tmp", BB_DP_DBG_TEST_DIR, (int)table+1 ); + + const size_t fileSize = sizeof( uint64 ) * ( BB_DP_MAX_BUCKET_COUNT+1 ); + + if( file.Open(path, read ? FileMode::Open : FileMode::Create, read ? FileAccess::Read : FileAccess::Write ) ) + { + if( read ) + { + if( file.Read( bucketCounts, fileSize ) != fileSize ) + Log::Error( "Failed to read from bucket counts file." ); + } + else + { + if( file.Write( bucketCounts, fileSize ) != fileSize ) + Log::Error( "Failed to write to bucket counts file." ); + } + } + else + Log::Error( "Failed to open bucket counts file." ); +} + +// Unpack a single park 7 +//----------------------------------------------------------- +void UnpackPark7( const byte* srcBits, uint64* dstEntries ) +{ + const uint32 _k = _K; + + const uint32 bitsPerEntry = _k + 1; + CPBitReader reader( (byte*)srcBits, CalculatePark7Size( _k ) * 8, 0 ); + + for( int32 i = 0; i < kEntriesPerPark; i++ ) + { + dstEntries[i] = reader.Read64( bitsPerEntry ); + } + + // BitReader reader( srcBits, CalculatePark7Size( _k ) * bitsPerEntry, 0 ); + + // const uint32 fieldShift = 64 - bitsPerEntry; + // const uint32 dFieldsPerPark = kEntriesPerPark * bitsPerEntry / 64; + // const uint64 mask = 0xFFFFFFFFFFFFFFFF >> ( 64 - bitsPerEntry ); + + // ASSERT( dFieldsPerPark * 64 / bitsPerEntry == kEntriesPerPark ); + + // uint64 sField = 0; // Source field + // uint64 dField = 0; // Destination field + + // uint32 dBits = 0; + + // #if _DEBUG + // uint64 didx = 0; + // #endif + + // for( uint i = 0; i < dFieldsPerPark; i++ ) + // { + // sField = Swap64( srcBits[i] ); + + // const uint32 shift = ( fieldShift + dBits ) & 63; + + // #if _DEBUG + // didx++; + // #endif + // // New S field, so we're sure we have a enough to fill a full D field + // dField |= sField >> shift; + // *dstEntries++ = dField & mask; + + // sField <<= 64 - shift; // Clear out unpacked entries from S field + // dField = sField >> fieldShift; // Place what remains of S field on a new D fIeld (always guaranteed to have a remainder) + + + // // Still have bits to unpack? + // const uint32 sUsed = ( bitsPerEntry - dBits ) + bitsPerEntry; + // if( sUsed < 64 ) + // { + // #if _DEBUG + // didx++; + // #endif + // // S field still has bits, we can begin to fill one more D field + // *dstEntries++ = dField & mask; + + // sField <<= 64 - fieldShift; // Use up the S bits we just unpacked + // dField = sField >> fieldShift; // Add final S remainders to new D field + + // dBits = 64 - sUsed; + // } + // else + // { + // // S field used-up completely, D field not yet filled + // dBits = shift; + // } + // } +} + + +#endif + + +#pragma GCC diagnostic pop + diff --git a/src/plotdisk/DiskPlotPhase3.cpp.disabled b/src/plotdisk/DiskPlotPhase3.cpp.disabled new file mode 100644 index 00000000..4515b5cc --- /dev/null +++ b/src/plotdisk/DiskPlotPhase3.cpp.disabled @@ -0,0 +1,1434 @@ +#include "DiskPlotPhase3.h" +#include "util/BitField.h" +#include "algorithm/RadixSort.h" +#include "DiskPlotDebug.h" +#include "plotmem/LPGen.h" +#include "plotmem/ParkWriter.h" +#include "jobs/UnpackMapJob.h" +#include "plotting/TableWriter.h" + +#define P3_EXTRA_L_ENTRIES_TO_LOAD 1024 // Extra L entries to load per bucket to ensure we + // have cross bucket entries accounted for + + +/** + * Algorithm: + * + * Let rTable be a table in a set {table2, table3, ..., table7} + * Let lTable be rTable - 1. Such that if rTable is table2, then lTable is table1 + * + * For each rTable perform 2 passes: + * + * Pass 1. Process each bucket as follows]: + * - Load L/R back pointers for rTable. + * - Load y index map for rTable. + * - Load marked entries from Phase 2 for rTable. + * - Load lTable, which for rTable==1 is the x buckets, otherwise it is the output of map of + * the previous iteration's rTable. + * - If rTable > table2: + * - Sort the lTable map on its origin (y) index, and then discard the origin index, + * keeping only the destination index (final position of an entry after LP sort). + * - Sort the rTable map on its origin index. + * - Generate LinePoints (LPs) from the rTable pointers and the lTable x or map values, + * while excluding each entry that is not marked in the marked entries table. + * - Distribute the LPs to their respective buckets along with the rTable (y) map + * and write them to disk. + * (The r table (y) map represents the origin index before sorting.) + * + * Pass 2. Process each LP bucket as follows: + * - Load the rTable LP output and map. + * - Sort the LP bucket and map on LP. + * - Compress the LP bucket and write it to disk. + * - Convert the sorted map into a reverse lookup by extending them with its origin index (its current value) + * and its destination index (its current index after sort). Then distribute + * them to buckets given its origin value. Write the buckets to disk. + * + * Go to next table. + */ +struct P3FenceId +{ + enum + { + Start = 0, + + RTableLoaded, + RMapLoaded, + + FENCE_COUNT + }; +}; + +struct Step2FenceId +{ + enum + { + Start = 0, + + LPLoaded, + MapLoaded, + + FENCE_COUNT + }; +}; + + +struct ConvertToLPJob : public PrefixSumJob +{ + DiskPlotContext* context; + TableId rTable; + + uint64 rTableOffset; + uint32 bucketEntryCount; + const uint64* markedEntries; + const uint32* lMap; + const uint32* rMap; + Pairs rTablePairs; + + uint64* linePoints; // Buffer for line points/pruned pairs + uint32* rMapPruned; // Where we store our pruned R map + + int64 prunedEntryCount; // Pruned entry count per thread. + int64 totalPrunedEntryCount; // Pruned entry count accross all threads + + void Run() override; + + template + void RunForTable(); + + // For distributing + uint32* bucketCounts; // Total count of entries per bucket (used by first thread) + uint64* lpOutBuffer; + uint32* keyOutBuffer; + + void DistributeToBuckets( const int64 enytryCount, const uint64* linePoints, const uint32* map ); +}; + + +//----------------------------------------------------------- +DiskPlotPhase3::DiskPlotPhase3( DiskPlotContext& context, const Phase3Data& phase3Data ) + : _context ( context ) + , _phase3Data( phase3Data ) +{ + memset( _tablePrunedEntryCount, 0, sizeof( _tablePrunedEntryCount ) ); + + DiskBufferQueue& ioQueue = *context.ioQueue; + + // Open required files + ioQueue.InitFileSet( FileId::LP_2, "lp_2", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_3, "lp_3", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_4, "lp_4", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_5, "lp_5", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_6, "lp_6", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_7, "lp_7", BB_DPP3_LP_BUCKET_COUNT ); + + ioQueue.InitFileSet( FileId::LP_KEY_2, "lp_key_2", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_KEY_3, "lp_key_3", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_KEY_4, "lp_key_4", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_KEY_5, "lp_key_5", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_KEY_6, "lp_key_6", BB_DPP3_LP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_KEY_7, "lp_key_7", BB_DPP3_LP_BUCKET_COUNT ); + + ioQueue.InitFileSet( FileId::LP_MAP_2, "lp_map_2", BB_DP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_MAP_3, "lp_map_3", BB_DP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_MAP_4, "lp_map_4", BB_DP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_MAP_5, "lp_map_5", BB_DP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_MAP_6, "lp_map_6", BB_DP_BUCKET_COUNT ); + ioQueue.InitFileSet( FileId::LP_MAP_7, "lp_map_7", BB_DP_BUCKET_COUNT ); + + // Find largest bucket size accross all tables + uint32 maxBucketLength = 0; + for( TableId table = TableId::Table1; table <= TableId::Table7; table = table +1 ) + { + if( table < TableId::Table2 ) + { + for( uint32 i = 0; i < BB_DP_BUCKET_COUNT; i++ ) + maxBucketLength = std::max( context.bucketCounts[(int)table][i], maxBucketLength ); + } + else + { + for( uint32 i = 0; i < BB_DP_BUCKET_COUNT; i++ ) + { + maxBucketLength = std::max( context.bucketCounts[(int)table][i], + std::max( context.ptrTableBucketCounts[(int)table][i], maxBucketLength ) ); + } + } + } + + maxBucketLength += P3_EXTRA_L_ENTRIES_TO_LOAD; + + // Init our buffers + // #TODO: Remove this as we're moving alignment on to the ioQueue to handle? + const size_t fileBlockSize = ioQueue.BlockSize(); + + // #TODO: Only have marking table, lp bucket and pruned r map buckets as + // fixed buffers, the rest we can just grab from the heap. + const size_t markedEntriesSize = phase3Data.bitFieldSize; + const size_t rTableMapBucketSize = RoundUpToNextBoundary( maxBucketLength * sizeof( uint32 ), fileBlockSize ); + const size_t rTableLPtrBucketSize = RoundUpToNextBoundary( maxBucketLength * sizeof( uint32 ), fileBlockSize ); + const size_t rTableRPtrBucketSize = RoundUpToNextBoundary( maxBucketLength * sizeof( uint16 ), fileBlockSize ); + + const size_t lTableBucketSize = RoundUpToNextBoundary( maxBucketLength * sizeof( uint32 ), fileBlockSize ); + const size_t lpBucketSize = RoundUpToNextBoundary( maxBucketLength * sizeof( uint64 ), fileBlockSize ); + + byte* heap = context.heapBuffer; + + _markedEntries = (uint64*)heap; + heap += markedEntriesSize; + + _rMap[0] = (uint32*)heap; heap += rTableMapBucketSize; + _rMap[1] = (uint32*)heap; heap += rTableMapBucketSize; + + _rTablePairs[0].left = (uint32*)heap; heap += rTableLPtrBucketSize; + _rTablePairs[1].left = (uint32*)heap; heap += rTableLPtrBucketSize; + + _rTablePairs[0].right = (uint16*)heap; heap += rTableRPtrBucketSize; + _rTablePairs[1].right = (uint16*)heap; heap += rTableRPtrBucketSize; + + _lMap[0] = (uint32*)heap; heap += lTableBucketSize; + _lMap[1] = (uint32*)heap; heap += lTableBucketSize; + + _rPrunedMap = (uint32*)heap; heap += rTableMapBucketSize; + _linePoints = (uint64*)heap; heap += lpBucketSize; + + size_t totalSize = + markedEntriesSize + + rTableMapBucketSize * 2 + + rTableLPtrBucketSize * 2 + + rTableRPtrBucketSize * 2 + + lTableBucketSize * 2 + + rTableMapBucketSize + + lpBucketSize; + + ASSERT( (size_t)(heap - context.heapBuffer) == totalSize ); + + // Reset our heap to the remainder of what we're not using + const size_t fullHeapSize = context.heapSize + context.ioHeapSize; + const size_t heapRemainder = fullHeapSize - totalSize; + ASSERT( context.heapBuffer + fullHeapSize == heap + heapRemainder ); + + ioQueue.ResetHeap( heapRemainder, heap ); +} + +//----------------------------------------------------------- +DiskPlotPhase3::~DiskPlotPhase3() +{} + +//----------------------------------------------------------- +void DiskPlotPhase3::Run() +{ + TableId startTable = TableId::Table2; + #ifdef BB_DP_DBG_P3_START_TABLE + startTable = TableId::BB_DP_DBG_P3_START_TABLE; + #endif + + for( TableId rTable = startTable; rTable <= TableId::Table7; rTable++ ) + { + Log::Line( "Compressing Tables %u and %u...", rTable, rTable+1 ); + const auto timer = TimerBegin(); + + ProcessTable( rTable ); + + const auto elapsed = TimerEnd( timer ); + Log::Line( "Finished compression in %.2lf seconds.", elapsed ); + } + + Log::Line( "Phase3 Total IO Aggregate Wait Time | READ: %.4lf | WRITE: %.4lf | BUFFERS: %.4lf", + TicksToSeconds( _context.readWaitTime ), TicksToSeconds( _context.writeWaitTime ), _context.ioQueue->IOBufferWaitTime() ); +} + +//----------------------------------------------------------- +void DiskPlotPhase3::ProcessTable( const TableId rTable ) +{ + DiskPlotContext& context = _context; + // DiskBufferQueue& ioQueue = *context.ioQueue; + + // Reset table counts + _prunedEntryCount = 0; + memset( _lpBucketCounts , 0, sizeof( _lpBucketCounts ) ); + memset( _lMapBucketCounts, 0, sizeof( _lMapBucketCounts ) ); + + // Reset Fence + _readFence.Reset( P3FenceId::Start ); + + #if _DEBUG && BB_DBG_SKIP_P3_S1 + + // Skip first step + // if( 0 ) + #endif + // Prune the R table pairs and key, + // convert pairs to LPs, then distribute + // the LPs to buckets, along with the key. + TableFirstStep( rTable ); + Log::Line( " Step 1 IO Aggregate Wait Time | READ: %.4lf | WRITE: %.4lf | BUFFERS: %.4lf", + TicksToSeconds( context.readWaitTime ), TicksToSeconds( context.writeWaitTime ), context.ioQueue->IOBufferWaitTime() ); + + // Validate linePoints + // #if _DEBUG + // if( rTable > TableId::Table2 ) + // Debug::ValidateLinePoints( context, rTable, _lpBucketCounts ); + // #endif + + // Load LP buckets and key, sort them, + // write a reverse lookup map given the sorted key, + // then compress and write the rTable to disk. + TableSecondStep( rTable ); + Log::Line( " Step 2 IO Aggregate Wait Time | READ: %.4lf | WRITE: %.4lf | BUFFERS: %.4lf", + TicksToSeconds( context.readWaitTime ), TicksToSeconds( context.writeWaitTime ), context.ioQueue->IOBufferWaitTime() ); + + // Unpack map to be used as the L table for the next table iteration + TableThirdStep( rTable ); + + // Update to our new bucket count and table entry count + const uint64 oldEntryCount = context.entryCounts[(int)rTable]; + Log::Line( " Table %u now has %llu / %llu ( %.2lf%% ) entries.", rTable, + _prunedEntryCount, oldEntryCount, (double)_prunedEntryCount / oldEntryCount * 100 ); + + Log::Line( " Table %u IO Aggregate Wait Time | READ: %.4lf | WRITE: %.4lf | BUFFERS: %.4lf", rTable, + TicksToSeconds( context.readWaitTime ), TicksToSeconds( context.writeWaitTime ), context.ioQueue->IOBufferWaitTime() ); + + // context.entryCounts[(int)rTable] = _prunedEntryCount; + _tablePrunedEntryCount[(int)rTable] = _prunedEntryCount; +} + + +/// +/// First Step +/// +//----------------------------------------------------------- +void DiskPlotPhase3::TableFirstStep( const TableId rTable ) +{ + Log::Line( " Step 1" ); + + DiskPlotContext& context = _context; + DiskBufferQueue& ioQueue = *context.ioQueue; + Fence& readFence = _readFence; + + const TableId lTable = rTable - 1; + const uint64 maxEntries = 1ull << _K; + const uint64 lTableEntryCount = context.entryCounts[(int)lTable]; + const uint64 rTableEntryCount = context.entryCounts[(int)rTable]; + + const FileId markedEntriesFileId = rTable < TableId::Table7 ? TableIdToMarkedEntriesFileId( rTable ) : FileId::None; + const FileId lMapId = rTable == TableId::Table2 ? FileId::X : TableIdToLinePointMapFileId( lTable ); + const FileId rMapId = TableIdToMapFileId( rTable ); + const FileId rPtrsRId = TableIdToBackPointerFileId( rTable ); + const FileId rPtrsLId = rPtrsRId + 1; + + // Prepare our files for reading + if( rTable < TableId::Table7 ) + ioQueue.SeekBucket( markedEntriesFileId, 0, SeekOrigin::Begin ); + + ioQueue.SeekFile ( lMapId , 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile ( rMapId , 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile ( rPtrsRId , 0, 0, SeekOrigin::Begin ); + ioQueue.SeekFile ( rPtrsLId , 0, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); + + uint64 lEntriesLoaded = 0; + + // Read first bucket + { + const uint32 lBucketLength = context.bucketCounts[(int)lTable][0] + P3_EXTRA_L_ENTRIES_TO_LOAD; + const uint32 rBucketLength = context.ptrTableBucketCounts[(int)rTable][0]; + + lEntriesLoaded += lBucketLength; + + // Read L Table 1st bucket + ioQueue.ReadFile( lMapId, 0, _lMap[0], lBucketLength * sizeof( uint32 ) ); + + // Read R Table marks + if( rTable < TableId::Table7 ) + { + ioQueue.ReadFile( markedEntriesFileId, 0, _markedEntries, _phase3Data.bitFieldSize ); + DeleteFile( markedEntriesFileId, 0 ); + } + + // Read R Table 1st bucket + ioQueue.ReadFile( rPtrsRId, 0, _rTablePairs[0].left , rBucketLength * sizeof( uint32 ) ); + ioQueue.ReadFile( rPtrsLId, 0, _rTablePairs[0].right, rBucketLength * sizeof( uint16 ) ); + + ioQueue.ReadFile( rMapId, 0, _rMap[0], rBucketLength * sizeof( int32 ) ); + ioQueue.SignalFence( readFence, 1 ); + + ioQueue.CommitCommands(); + } + + // Reset offsets + _rTableOffset = 0; + + // Start processing buckets + for( uint bucket = 0; bucket < BB_DP_BUCKET_COUNT; bucket++ ) + { + const bool isCurrentBucketLastBucket = bucket == BB_DP_BUCKET_COUNT - 1; + + if( !isCurrentBucketLastBucket ) + { + // Load the next bucket on the background + const uint32 nextBucket = bucket + 1; + const bool nextBucketIsLastBucket = nextBucket == BB_DP_BUCKET_COUNT - 1; + + uint32 lBucketLength = context.bucketCounts[(int)lTable][nextBucket]; + uint32 rBucketLength = context.ptrTableBucketCounts[(int)rTable][nextBucket]; + + // ASSERT( !nextBucketIsLastBucket || lEntriesLoaded+lBucketLength == context.entryCounts[(int)lTable] ); + if( nextBucketIsLastBucket ) + lBucketLength = (uint32)( context.entryCounts[(int)lTable] - lEntriesLoaded ); + + lEntriesLoaded += lBucketLength; + + // Load L Table + ioQueue.ReadFile( lMapId, 0, _lMap[1] + P3_EXTRA_L_ENTRIES_TO_LOAD, lBucketLength * sizeof( uint32 ) ); + + // Load R Table + ioQueue.ReadFile( rPtrsRId, 0, _rTablePairs[1].left , rBucketLength * sizeof( uint32 ) ); + ioQueue.ReadFile( rPtrsLId, 0, _rTablePairs[1].right, rBucketLength * sizeof( uint16 ) ); + + ioQueue.ReadFile( rMapId, 0, _rMap[1], rBucketLength * sizeof( uint32 ) ); + ioQueue.SignalFence( readFence, nextBucket + 1 ); + + ioQueue.CommitCommands(); + } + + // Process the bucket + BucketFirstStep( rTable, bucket ); + + // Copy last L entries from current bucket to next bucket's first entries + memcpy( _lMap[1], _lMap[0] + context.bucketCounts[(int)lTable][bucket], P3_EXTRA_L_ENTRIES_TO_LOAD * sizeof( uint32 ) ); + + // Swap buffers + std::swap( _lMap[0] , _lMap[1] ); + std::swap( _rMap[0] , _rMap[1] ); + std::swap( _rTablePairs[0], _rTablePairs[1] ); + } + + DeleteFile( lMapId , 0 ); + DeleteFile( rPtrsRId, 0 ); + DeleteFile( rPtrsLId, 0 ); + DeleteFile( rMapId , 0 ); +} + +//----------------------------------------------------------- +void DiskPlotPhase3::BucketFirstStep( const TableId rTable, const uint32 bucket ) +{ + DiskPlotContext& context = _context; + DiskBufferQueue& ioQueue = *context.ioQueue; + ThreadPool& threadPool = *context.threadPool; + Fence& readFence = _readFence; + + const TableId lTable = rTable - 1; + const bool isLastBucket = bucket == BB_DP_BUCKET_COUNT - 1; + const uint32 bucketEntryCountR = context.ptrTableBucketCounts[(int)rTable][bucket]; + + // Wait for the bucket to be loaded + readFence.Wait( bucket + 1, context.readWaitTime ); + + #if _DEBUG + { + const uint32 r = _rTablePairs[0].left[bucketEntryCountR-1] + _rTablePairs[0].right[bucketEntryCountR-1]; + const uint32 lTableBucketLength = _context.bucketCounts[(int)lTable][bucket] + P3_EXTRA_L_ENTRIES_TO_LOAD; + ASSERT( r < lTableBucketLength ); + } + #endif + + // Convert to line points + const uint32 prunedEntryCount = + PointersToLinePoints( + rTable, _rTableOffset, + bucketEntryCountR, _markedEntries, + _lMap[0], + _rTablePairs[0], _rMap[0], + _rPrunedMap, _linePoints ); + + _prunedEntryCount += prunedEntryCount; + + // Update our offset for the next bucket + _rTableOffset += bucketEntryCountR; +} + +//----------------------------------------------------------- +uint32 DiskPlotPhase3::PointersToLinePoints( + TableId rTable, uint64 entryOffset, + const uint32 entryCount, const uint64* markedEntries, + const uint32* lTable, + const Pairs pairs, const uint32* rMapIn, + uint32* rMapOut, uint64* outLinePoints ) +{ + const uint32 threadCount = _context.p3ThreadCount; + + uint32 bucketCounts[BB_DPP3_LP_BUCKET_COUNT]; + + MTJobRunner jobs( *_context.threadPool ); + + for( uint32 i = 0; i < threadCount; i++ ) + { + ConvertToLPJob& job = jobs[i]; + + job.context = &_context; + job.rTable = rTable; + + job.rTableOffset = entryOffset; + job.bucketEntryCount = entryCount; + job.markedEntries = markedEntries; + job.lMap = lTable; + job.rTablePairs = pairs; + job.rMap = rMapIn; + job.linePoints = outLinePoints; + job.rMapPruned = rMapOut; + + job.bucketCounts = bucketCounts; + } + + jobs.Run( threadCount ); + + for( uint32 i = 0; i < BB_DPP3_LP_BUCKET_COUNT; i++ ) + _lpBucketCounts[i] += bucketCounts[i]; + + uint32 prunedEntryCount = (uint32)jobs[0].totalPrunedEntryCount; + return prunedEntryCount; +} + +//----------------------------------------------------------- +void ConvertToLPJob::Run() +{ + switch( this->rTable ) + { + case TableId::Table2: this->RunForTable(); break; + case TableId::Table3: this->RunForTable(); break; + case TableId::Table4: this->RunForTable(); break; + case TableId::Table5: this->RunForTable(); break; + case TableId::Table6: this->RunForTable(); break; + case TableId::Table7: this->RunForTable(); break; + + default: + ASSERT( 0 ); + break; + } +} + +//----------------------------------------------------------- +template +void ConvertToLPJob::RunForTable() +{ + DiskPlotContext& context = *this->context; + + const int32 threadCount = (int32)this->JobCount(); + int64 entryCount = (int64)( this->bucketEntryCount / threadCount ); + + const int64 bucketOffset = entryCount * (int32)this->JobId(); // Offset in the bucket + const int64 rTableOffset = (int64)this->rTableOffset; // Offset in the table overall (used for checking marks) + const int64 marksOffset = rTableOffset + bucketOffset; + + if( this->IsLastThread() ) + entryCount += (int64)this->bucketEntryCount - entryCount * threadCount; + + const int64 end = bucketOffset + entryCount; + + const BitField markedEntries( (uint64*)this->markedEntries ); + + const uint32* rMap = this->rMap; + const Pairs pairs = this->rTablePairs; + + // First, scan our entries in order to prune them + int64 prunedLength = 0; + + if constexpr ( rTable < TableId::Table7 ) + { + for( int64 i = bucketOffset; i < end; i++) + { + // #TODO: Try changing Phase 2 to write atomically to see + // (if we don't get a huge performance hit), + // if we can do reads without the rMap + if( markedEntries.Get( rMap[i] ) ) + prunedLength ++; + } + } + else + { + prunedLength = entryCount; + } + + this->prunedEntryCount = prunedLength; + this->SyncThreads(); + + // #NOTE: Not necesarry for T7, but let's avoid code duplication for now. + // Set our destination offset + int64 dstOffset = 0; + + for( int32 i = 0; i < (int32)this->JobId(); i++ ) + dstOffset += GetJob( i ).prunedEntryCount; + + // Copy pruned entries into new buffer and expend R pointers to absolute address + // #TODO: check if doing 1 pass per buffer performs better + struct Pair + { + uint32 left; + uint32 right; + }; + + Pair* outPairsStart = (Pair*)(this->linePoints + dstOffset); + Pair* outPairs = outPairsStart; + uint32* outRMap = this->rMapPruned + dstOffset; + uint32* mapWriter = outRMap; + + for( int64 i = bucketOffset; i < end; i++ ) + { + const uint32 mapIdx = rMap[i]; + + if constexpr ( rTable < TableId::Table7 ) + { + if( !markedEntries.Get( mapIdx ) ) + continue; + } + + outPairs->left = pairs.left[i]; + outPairs->right = outPairs->left + pairs.right[i]; + + *mapWriter = mapIdx; + + outPairs++; + mapWriter++; + } + + // Now we can convert our pruned pairs to line points + uint64* outLinePoints = this->linePoints + dstOffset; + { + const uint32* lTable = this->lMap; + + for( int64 i = 0; i < prunedLength; i++ ) + { + Pair p = outPairsStart[i]; + const uint64 x = lTable[p.left ]; + const uint64 y = lTable[p.right]; + + outLinePoints[i] = SquareToLinePoint( x, y ); + + // TEST + #if _DEBUG + // if( rTable == TableId::Table7 && outLinePoints[i] == 6866525082325270466 ) BBDebugBreak(); + #endif + } + + // const uint64* lpEnd = outLinePoints + prunedLength; + // do + // { + // Pair p = *((Pair*)outLinePoints); + // const uint64 x = lTable[p.left ]; + // const uint64 y = lTable[p.right]; + + // *outLinePoints = SquareToLinePoint( x, y ); + + // } while( ++outLinePoints < lpEnd ); + } + + this->DistributeToBuckets( prunedLength, outLinePoints, outRMap ); +} + +//----------------------------------------------------------- +void ConvertToLPJob::DistributeToBuckets( const int64 entryCount, const uint64* linePoints, const uint32* key ) +{ + uint32 counts[BB_DPP3_LP_BUCKET_COUNT]; + uint32 pfxSum[BB_DPP3_LP_BUCKET_COUNT]; + + memset( counts, 0, sizeof( counts ) ); + + // Count entries per bucket + for( const uint64* lp = linePoints, *end = lp + entryCount; lp < end; lp++ ) + { + const uint64 bucket = (*lp) >> 56; ASSERT( bucket < BB_DPP3_LP_BUCKET_COUNT ); + counts[bucket]++; + } + + this->CalculatePrefixSum( BB_DPP3_LP_BUCKET_COUNT, counts, pfxSum, this->bucketCounts ); + + uint64* lpOutBuffer = nullptr; + uint32* keyOutBuffer = nullptr; + + // Grab write buffers for distribution + if( this->IsControlThread() ) + { + this->LockThreads(); + + DiskBufferQueue& ioQueue = *context->ioQueue; + + const int64 threadCount = (int64)this->JobCount(); + int64 totalEntryCountPruned = entryCount; + + for( int64 i = 1; i < threadCount; i++ ) + totalEntryCountPruned += this->GetJob( (int)i ).prunedEntryCount; + + this->totalPrunedEntryCount = totalEntryCountPruned; + + const size_t sizeLPs = (size_t)totalEntryCountPruned * sizeof( uint64 ); + const size_t sizeKey = (size_t)totalEntryCountPruned * sizeof( uint32 ); + + lpOutBuffer = (uint64*)ioQueue.GetBuffer( sizeLPs, true ); + keyOutBuffer = (uint32*)ioQueue.GetBuffer( sizeKey, true ); + + this->lpOutBuffer = lpOutBuffer; + this->keyOutBuffer = keyOutBuffer; + + this->ReleaseThreads(); + } + else + { + this->WaitForRelease(); + lpOutBuffer = GetJob( 0 ).lpOutBuffer ; + keyOutBuffer = GetJob( 0 ).keyOutBuffer; + } + + // Distribute entries to their respective buckets + for( int64 i = 0; i < entryCount; i++ ) + { + const uint64 lp = linePoints[i]; + const uint64 bucket = lp >> 56; ASSERT( bucket < BB_DPP3_LP_BUCKET_COUNT ); + const uint32 dstIndex = --pfxSum[bucket]; + + ASSERT( dstIndex < this->bucketEntryCount ); + + lpOutBuffer [dstIndex] = lp; + keyOutBuffer[dstIndex] = key[i]; + } + + if( this->IsControlThread() ) + { + DiskBufferQueue& ioQueue = *context->ioQueue; + + uint32* lpSizes = (uint32*)ioQueue.GetBuffer( BB_DPP3_LP_BUCKET_COUNT * sizeof( uint32 ) ); + uint32* keySizes = (uint32*)ioQueue.GetBuffer( BB_DPP3_LP_BUCKET_COUNT * sizeof( uint32 ) ); + + const uint32* bucketCounts = this->bucketCounts; + + for( int64 i = 0; i < (int)BB_DPP3_LP_BUCKET_COUNT; i++ ) + lpSizes[i] = bucketCounts[i] * sizeof( uint64 ); + + for( int64 i = 0; i < (int)BB_DPP3_LP_BUCKET_COUNT; i++ ) + keySizes[i] = bucketCounts[i] * sizeof( uint32 ); + + const FileId lpFileId = TableIdToLinePointFileId ( this->rTable ); + const FileId lpKeyFilId = TableIdToLinePointKeyFileId( this->rTable ); + + // Wait for all threads to finish writing + this->LockThreads(); + + ioQueue.WriteBuckets( lpFileId, lpOutBuffer, lpSizes ); + ioQueue.ReleaseBuffer( lpOutBuffer ); + ioQueue.ReleaseBuffer( lpSizes ); + + ioQueue.WriteBuckets( lpKeyFilId, keyOutBuffer, keySizes ); + ioQueue.ReleaseBuffer( keyOutBuffer ); + ioQueue.ReleaseBuffer( keySizes ); + + ioQueue.CommitCommands(); + + this->ReleaseThreads(); + } + else + this->WaitForRelease(); + + // #NOTE: If we move the write from here, we still need to sync the + // threads before existing to ensure the counts[] buffer + // doesn't go out of scope. +} + + + +/// +/// Seconds Step +/// +//----------------------------------------------------------- +void DiskPlotPhase3::TableSecondStep( const TableId rTable ) +{ + Log::Line( " Step 2" ); + + // #TODO: Organize buckets for a single bucket step here so that we can avoid waiting for buffers + // as much as we can. + + auto& context = _context; + auto& ioQueue = *context.ioQueue; + + const FileId lpId = TableIdToLinePointFileId ( rTable ); + const FileId keyId = TableIdToLinePointKeyFileId( rTable ); + + Fence& readFence = _readFence; + readFence.Reset( Step2FenceId::Start ); + + ioQueue.SeekBucket( lpId , 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( keyId, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); + + struct BucketBuffers + { + uint64* linePoints; + uint32* key; + }; + + // Clear per-bucket park left over LPs for parks + _bucketParkLeftOversCount = 0; + + uint64 entryOffset = 0; + uint32 bucketsLoaded = 0; + BucketBuffers buffers[BB_DPP3_LP_BUCKET_COUNT]; + + // #TODO: Check this to optimize better + // Since with BB_DPP3_LP_BUCKET_COUNT = 256, we get a lot of empty buckets, + // we need to determine which is the last bucket with entries to let the + // park writer know when to write the final partial park. + uint32 lastBucketWithEntries = 0; + + for( uint32 bucket = 0; bucket < BB_DPP3_LP_BUCKET_COUNT; bucket++ ) + { + if( _lpBucketCounts[bucket] ) + lastBucketWithEntries = bucket; + } + ASSERT( lastBucketWithEntries > 0 ); + + // Use a capture lambda for now, but change this to a non-capturing one later maybe + auto LoadBucket = [&]( uint32 bucket, bool forceLoad ) -> BucketBuffers + { + const uint32 bucketLength = _lpBucketCounts[bucket]; + if( bucketLength < 1 ) + { + return { nullptr, nullptr }; + } + + const size_t lpBucketSize = sizeof( uint64 ) * bucketLength; + const size_t mapBucketSize = sizeof( uint32 ) * bucketLength; + + uint64* linePoints = (uint64*)ioQueue.GetBuffer( lpBucketSize , forceLoad ); + uint32* key = (uint32*)ioQueue.GetBuffer( mapBucketSize, forceLoad ); + + const uint32 fenceIdx = bucket * Step2FenceId::FENCE_COUNT; + + ioQueue.ReadFile( lpId , bucket, linePoints, lpBucketSize ); + DeleteFile( lpId, bucket ); + ioQueue.SignalFence( readFence, Step2FenceId::LPLoaded + fenceIdx ); + + ioQueue.ReadFile( keyId, bucket, key, mapBucketSize ); + DeleteFile( keyId, bucket ); + ioQueue.SignalFence( readFence, Step2FenceId::MapLoaded + fenceIdx ); + + ioQueue.CommitCommands(); + + return { + .linePoints = linePoints, + .key = key + }; + }; + + buffers[0] = LoadBucket( 0, true ); + bucketsLoaded++; + + for( uint32 bucket = 0; bucket <= lastBucketWithEntries; bucket++ ) + { + const bool isLastBucket = bucket == lastBucketWithEntries; + + if( !isLastBucket ) + { + const uint32 nextBucket = bucket + 1; + // #TODO: Make background loading optional if we have no buffers available, + // then force-load if we don't have the current bucket pre-loaded. + buffers[nextBucket] = LoadBucket( nextBucket, true ); + bucketsLoaded++; + } + + const uint32 bucketLength = _lpBucketCounts[bucket]; + if( bucketLength > 0 ) + { + const uint32 fenceIdx = bucket * Step2FenceId::FENCE_COUNT; + readFence.Wait( Step2FenceId::MapLoaded + fenceIdx, context.readWaitTime ); + + uint64* linePoints = buffers[bucket].linePoints; + uint32* key = buffers[bucket].key; + + uint64* sortedLinePoints = _linePoints; + uint32* sortedKey = _rPrunedMap; + + // Sort line point w/ the key + // Since we're skipping an iteration, the output will be + // stored in the temp buffers, instead on the input ones. + RadixSort256::SortWithKey( + *context.threadPool, linePoints, sortedLinePoints, + key, sortedKey, bucketLength ); + + ioQueue.ReleaseBuffer( linePoints ); linePoints = nullptr; + ioQueue.ReleaseBuffer( key ); key = nullptr; + ioQueue.CommitCommands(); + + // Write the map back to disk as a reverse lookup map + WriteLPReverseLookup( rTable, sortedKey, bucket, bucketLength, entryOffset ); + + // Deltafy, compress and write bucket to a park into the plot file + WriteLinePointsToPark( rTable, isLastBucket, sortedLinePoints, bucketLength ); + } + + entryOffset += bucketLength; + } + + // Delete the reset of the buckets + for( uint32 bucket = lastBucketWithEntries; bucket < BB_DPP3_LP_BUCKET_COUNT; bucket++ ) + { + ioQueue.DeleteFile( lpId , bucket ); + ioQueue.DeleteFile( keyId, bucket ); + } + ioQueue.CommitCommands(); + + // Set the table offset for the next table + context.plotTablePointers[(int)rTable] = context.plotTablePointers[(int)rTable-1] + context.plotTableSizes[(int)rTable-1]; +} + +struct WriteLPMapJob : PrefixSumJob +{ + uint32 bucket; + uint32 entryCount; + uint64 entryOffset; + + const uint32* inKey; + uint64* outMap; + + uint32* bucketCounts; + + void Run() override; +}; + +//----------------------------------------------------------- +void DiskPlotPhase3::WriteLPReverseLookup( + const TableId rTable, const uint32* key, + const uint32 bucket , const uint32 entryCount, + const uint64 entryOffset ) +{ + constexpr uint32 BucketSize = BB_DP_BUCKET_COUNT; + + // Pack entries to a reverse lookup map and sort them + // into their buckets of origin (before sorted to line point) + ASSERT( entryOffset + entryCount <= 0xFFFFFFFFull ); + + if( entryCount < 1 ) + return; + + auto& ioQueue = *_context.ioQueue; + + const size_t bufferSize = sizeof( uint64 ) * entryCount; + + uint64* outMap = (uint64*)ioQueue.GetBuffer( bufferSize ); + uint32* bucketCounts = (uint32*)ioQueue.GetBuffer( sizeof( uint32 ) * BucketSize ); + + const uint32 threadCount = _context.p3ThreadCount; + + MTJobRunner jobs( *_context.threadPool ); + + for( uint32 i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job.bucket = bucket; + job.entryCount = entryCount; + job.entryOffset = entryOffset; + + job.inKey = key; + job.outMap = outMap; + job.bucketCounts = nullptr; + } + + jobs[0].bucketCounts = bucketCounts; + jobs.Run( threadCount ); + + // Append to our overall bucket count + for( uint32 i = 0; i < BucketSize; i++ ) + _lMapBucketCounts[i] += bucketCounts[i]; + + #if _DEBUG + // #TEST + // // if( 0 ) + // { + // uint32 totalCount = 0; + // for( uint32 i = 0; i < BucketSize; i++ ) + // totalCount += bucketCounts[i]; + + // ASSERT( totalCount == entryCount ) + + // const uint64* map = outMap; + // for( uint32 b = 0; b < BucketSize; b++ ) + // { + // const uint32 count = bucketCounts[b]; + + // for( uint32 i = 0; i < count; i++ ) + // { + // const uint64 e = map[i]; + // const uint32 idx = (uint32)e; + // ASSERT( ( idx >> 26 ) == b ); + // } + + // map += count; + // } + // } + #endif + + // Update count to sizes + for( uint32 i = 0; i < BucketSize; i++ ) + bucketCounts[i] *= sizeof( uint64 ); + + // Write to disk + const FileId mapId = TableIdToLinePointMapFileId( rTable ); + + ioQueue.WriteBuckets( mapId, outMap, bucketCounts ); + ioQueue.ReleaseBuffer( outMap ); + ioQueue.ReleaseBuffer( bucketCounts ); + ioQueue.CommitCommands(); +} + +//----------------------------------------------------------- +void WriteLPMapJob::Run() +{ + const int32 threadCount = (int32)this->JobCount(); + + int64 entriesPerThread = (int64)this->entryCount / threadCount; + + int64 offset = entriesPerThread * this->JobId(); + + if( this->IsLastThread() ) + entriesPerThread += (int64)this->entryCount - entriesPerThread * threadCount; + + // Count how many entries we have per bucket + // #TODO: Use arbirary bucket count here too (from 64-512) and bit-pack entries tightly + // then we can save at least 6 bits per entry, since we can infer it from its bucket. + const uint32 bitShift = 32 - kExtraBits; + constexpr uint32 BucketSize = BB_DP_BUCKET_COUNT; + + const uint32* inKey = this->inKey + offset; + uint64* outMap = this->outMap; + + uint32 counts[BucketSize]; + uint32 pfxSum[BucketSize]; + + memset( counts, 0, sizeof( counts ) ); + + for( const uint32* key = inKey, *end = key + entriesPerThread; key < end; key++ ) + { + const uint32 bucket = *key >> bitShift; + counts[bucket]++; + } + + this->CalculatePrefixSum( BucketSize, counts, pfxSum, this->bucketCounts ); + + // Write into our buckets + const uint64 entryOffset = (uint64)this->entryOffset + (uint64)offset; + + for( int64 i = 0; i < entriesPerThread; i++ ) + { + const uint32 key = inKey[i]; + const uint32 bucket = key >> bitShift; + + const uint32 writeIdx = --pfxSum[bucket]; + ASSERT( writeIdx < this->entryCount ); + + uint64 map = (entryOffset + (uint64)i) << 32; + + // TEST + #if _DEBUG + // if( key == 2 ) BBDebugBreak(); + #endif + + outMap[writeIdx] = map | key; + } + + // Wait for other thread sp that counts doesn't go out of scope + this->SyncThreads(); +} + +//----------------------------------------------------------- +void DiskPlotPhase3::WriteLinePointsToPark( TableId rTable, bool isLastBucketWithEntries, const uint64* linePoints, uint32 bucketLength ) +{ + ASSERT( bucketLength ); + + DiskPlotContext& context = _context; + DiskBufferQueue& ioQueue = *context.ioQueue; + + const TableId lTable = rTable - 1; + const size_t parkSize = CalculateParkSize( lTable ); + + if( _bucketParkLeftOversCount ) + { + ASSERT( _bucketParkLeftOversCount < kEntriesPerPark ); + + const uint32 requiredEntriesToCompletePark = kEntriesPerPark - _bucketParkLeftOversCount; + const uint32 entriesToCopy = std::min( requiredEntriesToCompletePark, bucketLength ); + + // Write cross-bucket park + byte* xBucketPark = (byte*)ioQueue.GetBuffer( parkSize ); + + memcpy( _bucketParkLeftOvers + _bucketParkLeftOversCount, linePoints, entriesToCopy * sizeof( uint64 ) ); + _bucketParkLeftOversCount += entriesToCopy; + + // Don't write unless we filled the whole park, or it is the last bucket (non-filled park is allowed then) + if( entriesToCopy < requiredEntriesToCompletePark ) + { + ASSERT( bucketLength < requiredEntriesToCompletePark ); + return; + } + + ASSERT( _bucketParkLeftOversCount == kEntriesPerPark ); + WritePark( parkSize, kEntriesPerPark, _bucketParkLeftOvers, xBucketPark, lTable ); + + ioQueue.WriteFile( FileId::PLOT, 0, xBucketPark, parkSize ); + ioQueue.ReleaseBuffer( xBucketPark ); + ioQueue.CommitCommands(); + + context.plotTableSizes[(int)rTable-1] += parkSize; + + // Offset our current bucket to account for the entries we just used + linePoints += entriesToCopy; + bucketLength -= entriesToCopy; + + // Clear the left-overs + _bucketParkLeftOversCount = 0; + + if( bucketLength < 1 ) + return; + } + + uint32 parkCount = bucketLength / kEntriesPerPark; + uint32 leftOverEntries = bucketLength - parkCount * kEntriesPerPark; + + if( isLastBucketWithEntries && leftOverEntries ) + { + leftOverEntries = 0; + parkCount++; + } + else if( leftOverEntries ) + { + // Save any entries that don't fill-up a full park for the next bucket + memcpy( _bucketParkLeftOvers, linePoints + bucketLength - leftOverEntries, leftOverEntries * sizeof( uint64 ) ); + + _bucketParkLeftOversCount = leftOverEntries; + bucketLength -= leftOverEntries; + } + + ASSERT( isLastBucketWithEntries || bucketLength / kEntriesPerPark * kEntriesPerPark == bucketLength ); + + byte* parkBuffer = (byte*)ioQueue.GetBuffer( parkSize * parkCount ); + + const size_t sizeWritten = WriteParks( *context.threadPool, bucketLength, (uint64*)linePoints, parkBuffer, lTable ); + ASSERT( sizeWritten <= parkSize * parkCount ); + + ioQueue.WriteFile( FileId::PLOT, 0, parkBuffer, sizeWritten ); + ioQueue.ReleaseBuffer( parkBuffer ); + ioQueue.CommitCommands(); + + context.plotTableSizes[(int)rTable-1] += sizeWritten; +} + + +/// +/// Third Step +/// +struct LPUnpackMapJob : MTJob +{ + uint32 bucket; + uint32 entryCount; + const uint64* mapSrc; + uint32* mapDst; + + //----------------------------------------------------------- + static void RunJob( ThreadPool& pool, const uint32 threadCount, const uint32 bucket, + const uint32 entryCount, const uint64* mapSrc, uint32* mapDst ) + { + MTJobRunner jobs( pool ); + + for( uint32 i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + job.bucket = bucket; + job.entryCount = entryCount; + job.mapSrc = mapSrc; + job.mapDst = mapDst; + } + + jobs.Run( threadCount ); + } + + //----------------------------------------------------------- + void Run() override + { + const uint64 maxEntries = 1ull << _K ; + const uint32 fixedBucketLength = (uint32)( maxEntries / BB_DP_BUCKET_COUNT ); + const uint32 bucketOffset = fixedBucketLength * this->bucket; + + const uint32 threadCount = this->JobCount(); + uint32 entriesPerThread = this->entryCount / threadCount; + + const uint32 offset = entriesPerThread * this->JobId(); + + if( this->IsLastThread() ) + entriesPerThread += this->entryCount - entriesPerThread * threadCount; + + const uint64* mapSrc = this->mapSrc + offset; + uint32* mapDst = this->mapDst; + + // Unpack with the bucket id + for( uint32 i = 0; i < entriesPerThread; i++ ) + { + const uint64 m = mapSrc[i]; + const uint32 idx = (uint32)m - bucketOffset; + + // #TODO: No need to keep track of bucketOffset, can just + // mask out the bucket portion... + ASSERT( idx < fixedBucketLength ); + + mapDst[idx] = (uint32)(m >> 32); + } + } +}; + +//----------------------------------------------------------- +void DiskPlotPhase3::TableThirdStep( const TableId rTable ) +{ + Log::Line( " Step 3" ); + + // Read back the packed map buffer from the current R table, then + // write them back to disk as a single, contiguous file + + DiskPlotContext& context = _context; + DiskBufferQueue& ioQueue = *context.ioQueue; + + constexpr uint32 BucketCount = BB_DP_BUCKET_COUNT; + + const FileId mapId = TableIdToLinePointMapFileId( rTable ); + + const uint64 tableEntryCount = context.entryCounts[(int)rTable]; + + const uint64 maxEntries = 1ull << _K; + const uint32 fixedBucketSize = (uint32)( maxEntries / BucketCount ); + const uint32 lastBucketSize = (uint32)( tableEntryCount - fixedBucketSize * ( BucketCount - 1 ) ); + + Fence& readFence = _readFence; + readFence.Reset( 0 ); + + ioQueue.SeekBucket( mapId, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); + + + uint64* buffers[BucketCount] = { 0 }; + uint32 bucketsLoaded = 0; + + auto LoadBucket = [&]( const bool forceLoad ) -> void + { + const uint32 bucket = bucketsLoaded; + + const uint32 entryCount = _lMapBucketCounts[bucket]; + if( entryCount < 1 ) + { + buffers[bucketsLoaded++] = nullptr; + return; + } + + // const size_t bucketSize = RoundUpToNextBoundaryT( entryCount * sizeof( uint64 ), 4096ul ); + const size_t bucketSize = entryCount * sizeof( uint64 ); + + auto* buffer = (uint64*)ioQueue.GetBuffer( bucketSize, forceLoad ); + if( !buffer ) + return; + + ioQueue.ReadFile( mapId, bucket, buffer, bucketSize ); + ioQueue.SignalFence( readFence, bucket + 1 ); + ioQueue.CommitCommands(); + + if( bucket == 0 && rTable < TableId::Table7 ) + ioQueue.SeekFile( mapId, 0, 0, SeekOrigin::Begin ); // Seek to the start to re-use this file for writing the unpacked map + else + ioQueue.DeleteFile( mapId, bucket ); + + ioQueue.CommitCommands(); + + buffers[bucketsLoaded++] = buffer; + }; + + LoadBucket( true ); + + const uint32 maxBucketsToLoadPerIter = 2; + + for( uint32 bucket = 0; bucket < BucketCount; bucket++ ) + { + const uint32 nextBucket = bucket + 1; + const bool isLastBucket = nextBucket == BucketCount; + + // Reserve a buffer for writing + const uint32 entryCount = _lMapBucketCounts[bucket]; + + const uint32 writeEntryCount = isLastBucket ? lastBucketSize : fixedBucketSize; + const size_t writeSize = writeEntryCount * sizeof( uint32 ); + + uint32* writeBuffer = nullptr; + if( entryCount > 0 ) + writeBuffer = (uint32*)ioQueue.GetBuffer( writeSize, true ); + + // Load next bucket + if( !isLastBucket && bucketsLoaded < BucketCount ) + { + uint32 maxBucketsToLoad = std::min( maxBucketsToLoadPerIter, BucketCount - bucketsLoaded ); + + for( uint32 i = 0; i < maxBucketsToLoad; i++ ) + { + const bool needNextBucket = bucketsLoaded == nextBucket; + LoadBucket( needNextBucket ); + } + } + + if( entryCount < 1 ) + continue; + + readFence.Wait( nextBucket, context.readWaitTime ); + + // Unpack the map + const uint64* inMap = buffers[bucket]; + + // TEST + #if _DEBUG + // if( 0 ) + // { + // const uint64 maxEntries = 1ull << _K ; + // const uint32 fixedBucketLength = (uint32)( maxEntries / BB_DP_BUCKET_COUNT ); + // const uint32 bucketOffset = fixedBucketLength * bucket; + + // for( int64 i = 0; i < (int64)entryCount; i++ ) + // { + // const uint32 idx = ((uint32)inMap[i]); + // ASSERT( idx - bucketOffset < fixedBucketLength ); + // ASSERT( ( idx >> 26 ) == bucket ); + // } + // } + + // memset( writeBuffer, 0, 67108864 * sizeof( uint32 ) ); + #endif + + LPUnpackMapJob::RunJob( + *context.threadPool, context.p3ThreadCount, + bucket, entryCount, inMap, writeBuffer ); + + ioQueue.ReleaseBuffer( (void*)inMap ); + ioQueue.CommitCommands(); + + if( rTable < TableId::Table7 ) + { + // Write the unpacked map back to disk + ioQueue.WriteFile( mapId, 0, writeBuffer, writeSize ); + } + else + { + // For table 7 we just write the parks to disk + WritePark7( bucket, writeBuffer, writeEntryCount ); + } + + ioQueue.ReleaseBuffer( writeBuffer ); + ioQueue.CommitCommands(); + } +} + +// Write the entries for table 7 as indices into +// table 6 into a park in the plot file +//----------------------------------------------------------- +void DiskPlotPhase3::WritePark7( uint32 bucket, uint32* t6Indices, uint32 bucketLength ) +{ + ASSERT( bucketLength ); + + DiskPlotContext& context = _context; + DiskBufferQueue& ioQueue = *context.ioQueue; + + const size_t parkSize = CDiv( (_K + 1) * kEntriesPerPark, 8 ); // #TODO: Move this to its own function + + if( _park7LeftOversCount ) + { + ASSERT( _park7LeftOversCount < kEntriesPerPark ); + + const uint32 requiredEntriesToCompletePark = kEntriesPerPark - _park7LeftOversCount; + const uint32 entriesToCopy = std::min( requiredEntriesToCompletePark, bucketLength ); + + // Write cross-bucket park + byte* xBucketPark = (byte*)ioQueue.GetBuffer( parkSize ); + + memcpy( _park7LeftOvers + _park7LeftOversCount, t6Indices, entriesToCopy * sizeof( uint32 ) ); + _park7LeftOversCount += entriesToCopy; + + // Don't write unless we filled the whole park, or it is the last bucket (non-filled park is allowed then) + if( entriesToCopy < requiredEntriesToCompletePark ) + { + ASSERT( bucketLength < requiredEntriesToCompletePark ); + return; + } + + // #TODO: Have to zero-out any entries remaining (in case of the last park) + + ASSERT( _park7LeftOversCount == kEntriesPerPark ); + TableWriter::WriteP7Entries( kEntriesPerPark, _park7LeftOvers, xBucketPark ); + context.plotTableSizes[(int)TableId::Table7] += parkSize; + + ioQueue.WriteFile( FileId::PLOT, 0, xBucketPark, parkSize ); + ioQueue.ReleaseBuffer( xBucketPark ); + ioQueue.CommitCommands(); + + // Offset our current bucket to account for the entries we just used + t6Indices += entriesToCopy; + bucketLength -= entriesToCopy; + + // Clear the overflow entries + _park7LeftOversCount = 0; + + if( bucketLength < 1 ) + return; + } + + const uint32 BucketCount = BB_DP_BUCKET_COUNT; + const bool isLastBucket = bucket + 1 == BucketCount; + + uint32 parkCount = bucketLength / kEntriesPerPark; + uint32 overflowEntries = bucketLength - parkCount * kEntriesPerPark; + + if( isLastBucket && overflowEntries ) + { + overflowEntries = 0; + parkCount++; + } + else if( overflowEntries ) + { + // Save any entries that don't fill-up a full park for the next bucket + memcpy( _park7LeftOvers, t6Indices + bucketLength - overflowEntries, overflowEntries * sizeof( uint32 ) ); + + _bucketParkLeftOversCount = overflowEntries; + bucketLength -= overflowEntries; + } + + ASSERT( isLastBucket || bucketLength / kEntriesPerPark * kEntriesPerPark == bucketLength ); + + byte* parkBuffer = (byte*)ioQueue.GetBuffer( parkSize * parkCount ); + + const size_t sizeWritten = TableWriter::WriteP7( *context.threadPool, + context.p3ThreadCount, bucketLength, t6Indices, parkBuffer ); + ASSERT( sizeWritten <= parkSize * parkCount ); + + ioQueue.WriteFile( FileId::PLOT, 0, parkBuffer, sizeWritten ); + ioQueue.ReleaseBuffer( parkBuffer ); + ioQueue.CommitCommands(); + + context.plotTableSizes[(int)TableId::Table7] += sizeWritten; +} + +//----------------------------------------------------------- +void DiskPlotPhase3::DeleteFile( FileId fileId, uint32 bucket ) +{ +#if BB_DP_DBG_P3_KEEP_FILES + return; +#endif + + _context.ioQueue->DeleteFile( fileId, bucket ); +} + +//----------------------------------------------------------- +void DiskPlotPhase3::DeleteBucket( FileId fileId ) +{ +#if BB_DP_DBG_P3_KEEP_FILES + return; +#endif + + _context.ioQueue->DeleteBucket( fileId ); +} + + diff --git a/src/plotdisk/DiskPlotPhase3.h b/src/plotdisk/DiskPlotPhase3.h new file mode 100644 index 00000000..43f5dc06 --- /dev/null +++ b/src/plotdisk/DiskPlotPhase3.h @@ -0,0 +1,128 @@ +#pragma once + +#include "DiskPlotContext.h" +#include "plotdisk/BitBucketWriter.h" +#include "plotdisk/DiskPairReader.h" + +class DiskPlotPhase3 +{ +public: + DiskPlotPhase3( DiskPlotContext& context ); + ~DiskPlotPhase3(); + + void Run(); + +private: + + template + void RunBuckets(); + + template + void ProcessTable(); + + template + void TableFirstStep(); + + template + void TableSecondStep(); + + template + void ConvertToLinePoints( + const uint32 bucket, const int64 bucketLength, const uint32* leftEntries, + const void* rightMarkedEntries, const Pair* rightPairs, const uint64* rightMap ); + + template + void WriteLinePointsToBuckets( const uint32 bucket,const int64 entryCount, const uint64* linePoints, const uint32* key ); + + template + void WritePark7( const uint64 inMapBucketCounts[_numBuckets+1] ); + + // template + // void WritePark7(); + + // void TableFirstStep( const TableId rTable ); + // void BucketFirstStep( const TableId rTable, const uint32 bucket ); + + // uint32 PointersToLinePoints( TableId rTable, const uint64 entryOffset, + // const uint32 entryCount, const uint64* markedEntries, + // const uint32* lTable, const Pairs pairs, + // const uint32* rMapIn, uint32* rMapOut, + // uint64* outLinePoints ); + + + + // void TableSecondStep( const TableId rTable ); + + // void WriteLPReverseLookup( const TableId rTable, const uint32* key, + // const uint32 bucket, const uint32 entryCount, + // const uint64 entryOffset ); + + // void WriteLinePointsToPark( TableId rTable, bool isLastBucket, const uint64* linePoints, uint32 bucketLength ); + + + // void TableThirdStep( const TableId rTable ); + + // void WritePark7( uint32 bucket, uint32* t6Indices, uint32 entryCount ); + + // void DeleteFile( FileId fileId, uint32 bucket ); + // void DeleteBucket( FileId fileId ); + + void GetCacheSizes( size_t& outCacheSizeLP, size_t& outCacheSizeMap ); + + template + void GetCacheSizesForBuckets( size_t& outCacheSizeLP, size_t& outCacheSizeMap ); + +private: + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; + + Fence _readFence; + Fence _writeFence; + Fence _stepFence; + Fence _plotFence; + + Duration _ioWaitTime = Duration::zero(); + + FileId _mapReadId = FileId::LP_MAP_0; + FileId _mapWriteId = FileId::LP_MAP_1; + + // Read buffers + // Pair* _pairRead[2]; + // uint64* _rMapRead[2]; + // uint32* _lMapRead[2]; + + // uint32* _lMapBuffers[2]; // Only used for table 1. The rest use a map reader. + // IP3LMapReader* _lMap = nullptr; + // uint32* _rMap[2]; + + // uint64 _lEntriesLoaded = 0; + + // Unpacked working buffers + // Pair* _rPrunedPairs; // Temporary buffer for storing the pruned pairs and map + // uint64* _rPrunedMap; + // uint64* _linePoints; // Used to convert to line points/tmp buffer + + // uint64 _rTableOffset; // + + // BitBucketWriter _lpWriter; + // BitBucketWriter _mapWriter; + // uint64* _lpWriteBuffer [2]; + // uint32* _mapWriteBuffer[2]; + + + // Entry count for the current R table after it has been pruned + // uint64 _prunedEntryCount; + + uint64 _tablePrunedEntryCount [7] = { 0 }; // Count of each table, after prunning + uint64 _lpPrunedBucketCounts [BB_DP_MAX_BUCKET_COUNT+1]; // Entry count per bucket of our current R table after it has been converted to buckets. + uint64 _lMapPrunedBucketCounts[BB_DP_MAX_BUCKET_COUNT+1]; // Entry count per bucket for the lMap table after it has been pruned by the previous table compression. + + // // Left over entries in a bucket (which is not the last bucket) + // // that did not fit into a full park, these need to be included in + // // the first park of the next bucket + // uint64 _bucketParkLeftOvers[kEntriesPerPark] = { 0 }; + // uint32 _bucketParkLeftOversCount = 0; + + // uint32 _park7LeftOvers[kEntriesPerPark] = { 0 }; + // uint32 _park7LeftOversCount = 0; +}; diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp new file mode 100644 index 00000000..d95be160 --- /dev/null +++ b/src/plotdisk/DiskPlotter.cpp @@ -0,0 +1,566 @@ +#include "DiskPlotter.h" +#include "util/Log.h" +#include "util/Util.h" +#include "util/CliParser.h" +#include "util/jobs/MemJobs.h" +#include "io/FileStream.h" + +#include "DiskFp.h" +#include "DiskPlotPhase1.h" +#include "DiskPlotPhase2.h" +#include "DiskPlotPhase3.h" +#include "SysHost.h" + + +size_t ValidateTmpPathAndGetBlockSize( DiskPlotter::Config& cfg ); + + +//----------------------------------------------------------- +// DiskPlotter::DiskPlotter() +// { +// } + +//----------------------------------------------------------- +DiskPlotter::DiskPlotter( const Config& cfg ) +{ + ASSERT( cfg.tmpPath ); + ASSERT( cfg.tmpPath2 ); + + // Initialize tables for matching + LoadLTargets(); + + GlobalPlotConfig& gCfg = *cfg.globalCfg; + + ZeroMem( &_cx ); + + FatalIf( !GetTmpPathsBlockSizes( cfg.tmpPath, cfg.tmpPath2, _cx.tmp1BlockSize, _cx.tmp2BlockSize ), + "Failed to obtain temp paths block size from t1: '%s' or %s t2: '%s'.", cfg.tmpPath, cfg.tmpPath2 ); + + FatalIf( _cx.tmp1BlockSize < 8 || _cx.tmp2BlockSize < 8,"File system block size is too small.." ); + + const size_t heapSize = GetRequiredSizeForBuckets( cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize ); + + _cfg = cfg; + _cx.cfg = &_cfg; + _cx.tmpPath = cfg.tmpPath; + _cx.tmpPath2 = cfg.tmpPath2; + _cx.numBuckets = cfg.numBuckets; + _cx.heapSize = heapSize; + _cx.cacheSize = cfg.cacheSize; + + const uint sysLogicalCoreCount = SysHost::GetLogicalCPUCount(); + const auto* numa = SysHost::GetNUMAInfo(); + + // _cx.threadCount = gCfg.threadCount; + _cx.ioThreadCount = cfg.ioThreadCount; + _cx.f1ThreadCount = cfg.f1ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.f1ThreadCount, sysLogicalCoreCount ); + _cx.fpThreadCount = cfg.fpThreadCount == 0 ? gCfg.threadCount : std::min( cfg.fpThreadCount, sysLogicalCoreCount ); + _cx.cThreadCount = cfg.cThreadCount == 0 ? gCfg.threadCount : std::min( cfg.cThreadCount , sysLogicalCoreCount ); + _cx.p2ThreadCount = cfg.p2ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.p2ThreadCount, sysLogicalCoreCount ); + _cx.p3ThreadCount = cfg.p3ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.p3ThreadCount, sysLogicalCoreCount ); + + Log::Line( "[Bladebit Disk Plotter]" ); + Log::Line( " Heap size : %.2lf GiB ( %.2lf MiB )", (double)_cx.heapSize BtoGB, (double)_cx.heapSize BtoMB ); + Log::Line( " Cache size : %.2lf GiB ( %.2lf MiB )", (double)_cx.cacheSize BtoGB, (double)_cx.cacheSize BtoMB ); + Log::Line( " Bucket count : %u" , _cx.numBuckets ); + Log::Line( " F1 threads : %u" , _cx.f1ThreadCount ); + Log::Line( " FP threads : %u" , _cx.fpThreadCount ); + Log::Line( " C threads : %u" , _cx.cThreadCount ); + Log::Line( " P2 threads : %u" , _cx.p2ThreadCount ); + Log::Line( " P3 threads : %u" , _cx.p3ThreadCount ); + Log::Line( " I/O threads : %u" , _cx.ioThreadCount ); + Log::Line( " Temp1 block sz : %u" , _cx.tmp1BlockSize ); + Log::Line( " Temp2 block sz : %u" , _cx.tmp2BlockSize ); +#if BB_IO_METRICS_ON + Log::Line( " I/O metrices enabled." ); +#endif + + Log::Line( " Allocating memory" ); + _cx.heapBuffer = bbvirtalloc( _cx.heapSize ); + if( numa && !gCfg.disableNuma ) + { + if( !SysHost::NumaSetMemoryInterleavedMode( _cx.heapBuffer, _cx.heapSize ) ) + Log::Error( "WARNING: Failed to bind NUMA memory on the heap." ); + } + + if( _cx.cacheSize ) + { + // We need to align the cache size to the block size of the temp2 dir + const size_t cachePerBucket = _cx.cacheSize / _cx.numBuckets; + const size_t cachePerBucketAligned = CDivT( cachePerBucket, _cx.tmp2BlockSize ) * _cx.tmp2BlockSize; + const size_t alignedCacheSize = cachePerBucketAligned * _cx.numBuckets; + + if( alignedCacheSize != _cx.cacheSize ) + { + Log::Line( "WARNING: Cache size has been adjusted from %.2lf to %.2lf MiB to make it block-aligned.", + (double)_cx.cacheSize BtoMB, (double)alignedCacheSize BtoMB ); + _cx.cacheSize = alignedCacheSize; + } + + _cx.cache = bbvirtallocnuma( _cx.cacheSize ); + if( numa && !gCfg.disableNuma ) + { + if( !SysHost::NumaSetMemoryInterleavedMode( _cx.cache, _cx.cacheSize ) ) + Log::Error( "WARNING: Failed to bind NUMA memory on the cache." ); + } + } + + // Initialize our Thread Pool and IO Queue + const int32 ioThreadId = -1; // Force unbounded IO thread for now. We should bind it to the last used thread, of the max threads used... + _cx.threadPool = new ThreadPool( sysLogicalCoreCount, ThreadPool::Mode::Fixed, gCfg.disableCpuAffinity ); + _cx.ioQueue = new DiskBufferQueue( _cx.tmpPath, _cx.tmpPath2, gCfg.outputFolder, _cx.heapBuffer, _cx.heapSize, _cx.ioThreadCount, ioThreadId ); + + // if( cfg.globalCfg->warmStart ) + // #TODO: IMPORTANT: Remove this after testing + Log::Line( "WARNING: Forcing warm start for testing." ); + { + Log::Line( "Warm start: Pre-faulting memory pages..." ); + + const uint32 threadCount = cfg.globalCfg->threadCount == 0 ? sysLogicalCoreCount : + std::min( cfg.globalCfg->threadCount, sysLogicalCoreCount ); + + FaultMemoryPages::RunJob( *_cx.threadPool, threadCount, _cx.heapBuffer, _cx.heapSize ); + + if( _cx.cacheSize ) + FaultMemoryPages::RunJob( *_cx.threadPool, threadCount, _cx.cache, _cx.cacheSize ); + + Log::Line( "Memory initialized." ); + } +} + +//----------------------------------------------------------- +void DiskPlotter::Plot( const PlotRequest& req ) +{ + // Reset state + memset( _cx.plotTablePointers , 0, sizeof( _cx.plotTablePointers ) ); + memset( _cx.plotTableSizes , 0, sizeof( _cx.plotTableSizes ) ); + memset( _cx.bucketCounts , 0, sizeof( _cx.bucketCounts ) ); + memset( _cx.entryCounts , 0, sizeof( _cx.entryCounts ) ); + memset( _cx.ptrTableBucketCounts, 0, sizeof( _cx.ptrTableBucketCounts ) ); + // #TODO: Reset the rest of the state, including the heap & the ioQueue + + + Log::Line( "Started plot." ); + auto plotTimer = TimerBegin(); + + _cx.plotId = req.plotId; + _cx.plotMemo = req.plotMemo; + _cx.plotMemoSize = req.plotMemoSize; + + _cx.ioQueue->OpenPlotFile( req.plotFileName, req.plotId, req.plotMemo, req.plotMemoSize ); + + { + Log::Line( "Running Phase 1" ); + const auto timer = TimerBegin(); + + DiskPlotPhase1 phase1( _cx ); + phase1.Run(); + + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 1 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } + + { + Log::Line( "Running Phase 2" ); + const auto timer = TimerBegin(); + + DiskPlotPhase2 phase2( _cx ); + phase2.Run(); + + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 2 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } + + { + Log::Line( "Running Phase 3" ); + const auto timer = TimerBegin(); + + DiskPlotPhase3 phase3( _cx ); + phase3.Run(); + + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 3 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } + Log::Line("Total plot I/O wait time: %.2lf seconds.", TicksToSeconds( _cx.ioWaitTime ) ); + + + { + // Now we need to update the table sizes on the file + Log::Line( "Waiting for plot file to complete pending writes..." ); + const auto timer = TimerBegin(); + + // Update the table pointers location + DiskBufferQueue& ioQueue = *_cx.ioQueue; + ASSERT( sizeof( _cx.plotTablePointers ) == sizeof( uint64 ) * 10 ); + + // Convert them to big endian + for( int i = 0; i < 10; i++ ) + _cx.plotTablePointers[i] = Swap64( _cx.plotTablePointers[i] ); + + const int64 tablePtrsStart = (int64)ioQueue.PlotTablePointersAddress(); + ioQueue.SeekFile( FileId::PLOT, 0, tablePtrsStart, SeekOrigin::Begin ); + ioQueue.WriteFile( FileId::PLOT, 0, _cx.plotTablePointers, sizeof( _cx.plotTablePointers ) ); + + // Wait for all IO commands to finish + Fence fence; + ioQueue.SignalFence( fence ); + ioQueue.CommitCommands(); + fence.Wait(); + + const double elapsed = TimerEnd( timer ); + Log::Line( "Completed pending writes in %.2lf seconds.", elapsed ); + Log::Line( "Finished writing plot %s.", req.plotFileName ); + Log::Line( "Final plot table pointers: " ); + + for( int i = 0; i < 10; i++ ) + { + const uint64 addy = Swap64( _cx.plotTablePointers[i] ); + + if( i < 7 ) + Log::Line( " Table %d: %16lu ( 0x%016lx )", i+1, addy, addy ); + else + Log::Line( " C %d : %16lu ( 0x%016lx )", i-6, addy, addy ); + } + Log::Line( "" ); + + double plotElapsed = TimerEnd( plotTimer ); + Log::Line( "Finished plotting in %.2lf seconds ( %.1lf minutes ).", plotElapsed, plotElapsed / 60 ); + + // Rename plot file + ioQueue.FinishPlot( fence ); + } +} + +//----------------------------------------------------------- +void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) +{ + while( cli.HasArgs() ) + { + if( cli.ReadU32( cfg.numBuckets, "-b", "--buckets" ) ) + continue; + if( cli.ReadStr( cfg.tmpPath, "-t1", "--temp1" ) ) + continue; + if( cli.ReadStr( cfg.tmpPath2, "-t2", "--temp2" ) ) + continue; + if( cli.ReadSwitch( cfg.noTmp1DirectIO, "--no-t1-direct" ) ) + continue; + if( cli.ReadSwitch( cfg.noTmp2DirectIO, "--no-t2-direct" ) ) + continue; + if( cli.ReadSize( cfg.cacheSize, "--cache" ) ) + continue; + if( cli.ReadU32( cfg.f1ThreadCount, "--f1-threads" ) ) + continue; + if( cli.ReadU32( cfg.fpThreadCount, "--fp-threads" ) ) + continue; + if( cli.ReadU32( cfg.cThreadCount, "--c-threads" ) ) + continue; + if( cli.ReadU32( cfg.p2ThreadCount, "--p2-threads" ) ) + continue; + if( cli.ReadU32( cfg.p3ThreadCount, "--p3-threads" ) ) + continue; + if( cli.ArgConsume( "-s", "--sizes" ) ) + { + FatalIf( cfg.numBuckets < BB_DP_MIN_BUCKET_COUNT || cfg.numBuckets > BB_DP_MAX_BUCKET_COUNT, + "Buckets must be between %u and %u, inclusive.", (uint)BB_DP_MIN_BUCKET_COUNT, (uint)BB_DP_MAX_BUCKET_COUNT ); + FatalIf( ( cfg.numBuckets & ( cfg.numBuckets - 1 ) ) != 0, "Buckets must be power of 2." ); + + size_t heapSize = 0; + if( cfg.tmpPath ) + { + cfg.tmpPath2 = cfg.tmpPath2 ? cfg.tmpPath2 : cfg.tmpPath; + heapSize = GetRequiredSizeForBuckets( cfg.numBuckets, cfg.tmpPath2, cfg.tmpPath ); + } + else + heapSize = GetRequiredSizeForBuckets( cfg.numBuckets, 1, 1 ); + + Log::Line( "Buckets: %u | Heap Sizes: %.2lf GiB", cfg.numBuckets, (double)heapSize BtoGB ); + exit( 0 ); + } + if( cli.ArgConsume( "-h", "--help" ) ) + { + PrintUsage(); + exit( 0 ); + } + else if( cli.Arg()[0] == '-' ) + { + Fatal( "Unexpected argument '%s'.", cli.Arg() ); + } + else + { + cfg.globalCfg->outputFolder = cli.ArgConsume(); + + FatalIf( strlen( cfg.globalCfg->outputFolder ) == 0, "Invalid plot output directory." ); + FatalIf( cli.HasArgs(), "Unexpected argument '%s'.", cli.Arg() ); + break; + } + } + + /// + /// Validate some parameters + /// + FatalIf( cfg.tmpPath == nullptr, "At least 1 temporary path (--temp) must be specified." ); + if( cfg.tmpPath2 == nullptr ) + cfg.tmpPath2 = cfg.tmpPath; + + FatalIf( cfg.numBuckets < BB_DP_MIN_BUCKET_COUNT || cfg.numBuckets > BB_DP_MAX_BUCKET_COUNT, + "Buckets must be between %u and %u, inclusive.", (uint)BB_DP_MIN_BUCKET_COUNT, (uint)BB_DP_MAX_BUCKET_COUNT ); + + FatalIf( ( cfg.numBuckets & ( cfg.numBuckets - 1 ) ) != 0, "Buckets must be power of 2." ); + + const uint32 sysLogicalCoreCount = SysHost::GetLogicalCPUCount(); + + if( cfg.ioThreadCount == 0 ) + cfg.ioThreadCount = 1; // #TODO: figure out a reasonable default. Probably 1 or 2 for current consumer NVMes running on PCIe3... + else if( cfg.ioThreadCount > sysLogicalCoreCount ) + { + Log::Line( "Warning: Limiting disk queue threads to %u, which is the system's logical CPU count.", sysLogicalCoreCount ); + cfg.ioThreadCount = sysLogicalCoreCount; + } + + const uint32 defaultThreads = cfg.globalCfg->threadCount == 0 ? sysLogicalCoreCount : + std::min( sysLogicalCoreCount, cfg.globalCfg->threadCount ); + + auto validateThreads = [&]( uint32& targetValue ) { + targetValue = targetValue == 0 ? defaultThreads : std::min( sysLogicalCoreCount, targetValue ); + }; + + validateThreads( cfg.f1ThreadCount ); + validateThreads( cfg.fpThreadCount ); + validateThreads( cfg.cThreadCount ); + validateThreads( cfg.p2ThreadCount ); + validateThreads( cfg.p3ThreadCount ); +} + +//----------------------------------------------------------- +bool DiskPlotter::GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPath2, size_t& tmpPath1Size, size_t& tmpPath2Size ) +{ + ASSERT( tmpPath1 ); + ASSERT( tmpPath2 ); + + bool success = false; + + const char* paths[2] = { tmpPath1, tmpPath2 }; + const size_t lengths[2] = { + strlen( tmpPath1 ), + strlen( tmpPath2 ), + }; + + const size_t RAND_PART = 16; + const size_t RAND_FILE_SIZE = RAND_PART + 4; // 5 = '.' + ".tmp" + const size_t MAX_LENGTH = 1024 + RAND_FILE_SIZE + 1; + char stackPath[MAX_LENGTH+1]; + + const size_t pathLength = std::max( lengths[0], lengths[1] ) + RAND_FILE_SIZE + 1; + + char* path = nullptr; + if( pathLength > MAX_LENGTH ) + path = bbmalloc( pathLength + RAND_FILE_SIZE + 2 ); // +2 = '/' + '\0' + else + path = stackPath; + + size_t blockSizes[2] = { 0 }; + + for( int32 i = 0; i < 2; i++ ) + { + size_t len = lengths[i]; + memcpy( path, paths[i], len ); + + if( path[len-1] != '/' && path[len-1] != '\\' ) + path[len++] = '/'; + + path[len++] = '.'; + + byte filename[RAND_PART/2]; + SysHost::Random( filename, sizeof( filename ) ); + + size_t encoded; + if( BytesToHexStr( filename, sizeof( filename ), path+len, RAND_PART, encoded ) != 0 ) + { + Log::Error( "GetTmpPathsBlockSizes: Hex conversion failed." ); + goto EXIT; + } + + len += RAND_PART; + memcpy( path+len, ".tmp", sizeof( ".tmp" ) ); + + #if _DEBUG + if( path == stackPath ) + ASSERT( path+len+ sizeof( ".tmp" ) <= stackPath + sizeof( stackPath ) ); + #endif + + FileStream file; + if( !file.Open( path, FileMode::Create, FileAccess::ReadWrite ) ) + { + Log::Error( "GetTmpPathsBlockSizes: Failed to open temp file '%s'.", path ); + goto EXIT; + } + + blockSizes[i] = file.BlockSize(); + file.Close(); + + remove( path ); + } + + tmpPath1Size = blockSizes[0]; + tmpPath2Size = blockSizes[1]; + success = true; + +EXIT: + if( path && path != stackPath ) + free( path ); + + return success; +} + +//----------------------------------------------------------- +size_t DiskPlotter::GetRequiredSizeForBuckets( const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2 ) +{ + size_t blockSizes[2] = { 0 }; + + if( !GetTmpPathsBlockSizes( tmpPath1, tmpPath2, blockSizes[0], blockSizes[1] ) ) + return 0; + + return GetRequiredSizeForBuckets( numBuckets, blockSizes[0], blockSizes[1] ); +} + +//----------------------------------------------------------- +size_t DiskPlotter::GetRequiredSizeForBuckets( const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize ) +{ + switch( numBuckets ) + { + case 128 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); + case 256 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); + case 512 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); + case 1024: + // We need to add a bit more here (at least 1GiB) to have enough space for P2, which keeps + // 2 marking table bitfields in-memory: k^32 / 8 = 0.5GiB + return 1032ull MB + DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); + + default: + Fatal( "Invalid bucket size: %u.", numBuckets ); + break; + } + + return 0; +} + + +//----------------------------------------------------------- +size_t ValidateTmpPathAndGetBlockSize( DiskPlotter::Config& cfg ) +{ + FatalIf( cfg.tmpPath == nullptr, "No temporary path specified." ); + + size_t pathLen = strlen( cfg.tmpPath ); + FatalIf( pathLen < 1, "Invalid temporary path." ); + + char* tmpPath = bbmalloc( pathLen + 2 ); + memcpy( tmpPath, cfg.tmpPath, pathLen ); + + if( cfg.tmpPath[pathLen - 1] != '/' + #ifdef _WIN32 + && cfg.tmpPath[pathLen - 1] != '\\' + #endif + ) + { + tmpPath[pathLen++] = '/'; + } + + tmpPath[pathLen] = (char)0; + cfg.tmpPath = tmpPath; + + // Open a file in the temp dir to obtain the block size + uint64 randNum = 0; + SysHost::Random( (byte*)&randNum, sizeof( randNum ) ); + + char* randFileName = bbmalloc( pathLen + 32 ); + + int r = snprintf( randFileName, pathLen + 32, "%s.%llx.blk", tmpPath, (llu)randNum ); + FatalIf( r < 1, "Unexpected error validating temp directory." ); + + FileStream tmpFile; + + if( !tmpFile.Open( randFileName, FileMode::Create, FileAccess::ReadWrite ) ) + { + int err = tmpFile.GetError(); + Fatal( "Failed to open a file in the temp directory with error %d (0x%x).", err, err ); + } + + + cfg.expectedTmpDirBlockSize = tmpFile.BlockSize(); + + remove( randFileName ); + free( randFileName ); + + return cfg.expectedTmpDirBlockSize; +} + + +static const char* USAGE = R"(diskplot [OPTIONS] + +Creates plots by making use of a disk to temporarily store and read values. + + : The output directory where the plot will be copied to after completion. + +[OPTIONS] + -b, --buckets : The number of buckets to use. The default is 256. + You may specify one of: 128, 256, 512, 1024. + + -t1, --temp1 : The temporary directory to use when plotting. + *REQUIRED* + + -t2, --temp2 : Specify a secondary temporary directory, which will be used for data + that needs to be read/written from constantly. + If nothing is specified, --temp will be used instead. + + --no-t1-direct : Disable direct I/O on the temp 1 directory. + + --no-t2-direct : Disable direct I/O on the temp 2 directory. + + -s, --sizes : Output the memory requirements for a specific bucket count. + To change the bucket count from the default, pass a value to -b + before using this argument. You may also pass a value to --temp and --temp2 + to get file system block-aligned values when using direct IO. + + --cache : Size of cache to reserve for I/O. This is memory + reserved for files that incur frequent I/O. + You need about 192GiB(+|-) for high-frequency I/O Phase 1 calculations + to be completely in-memory. + + --f1-threads : Override the thread count for F1 generation. + + --fp-threads : Override the thread count for forward propagation. + + --c-threads : Override the thread count for C table processing. + (Equivalent to Phase 4 in chiapos, but performed + at the end of Phase 1.) + +--p2-threads : Override the thread count for Phase 2. + +--p3-threads : Override the thread count for Phase 3. + +-h, --help : Print this help text and exit. + + +[NOTES] +If you don't specify any thread count overrides, the default thread count +specified in the global options will be used. + +Phases 2 and 3 are typically more I/O bound than Phase 1 as these +phases perform less computational work than Phase 1 and thus the CPU +finishes the currently loaded workload quicker and will proceed to +grab another buffer from disk with a shorter frequency. Because of this +you would typically lower the thread count for these phases if you are +incurring I/O waits. + +[EXAMPLES] +bladebit -t 24 -f ... -c ... diskplot --b 128 --cache 32G -t1 /my/temporary/plot/dir + --f1-threads 3 --fp-threads 16 --c-threads 8 --p2-threads 12 --p3-threads 8 /my/output/dir + +bladebit -t 8 -f ... -c ... diskplot -t2 /my/temporary/plot/dir -t2 /my/other/tmp/dir /my/output/dir +)"; + +//----------------------------------------------------------- +void DiskPlotter::PrintUsage() +{ + Log::Line( USAGE ); +} \ No newline at end of file diff --git a/src/plotdisk/DiskPlotter.h b/src/plotdisk/DiskPlotter.h new file mode 100644 index 00000000..2a1a1483 --- /dev/null +++ b/src/plotdisk/DiskPlotter.h @@ -0,0 +1,39 @@ +#pragma once + +#include "DiskPlotContext.h" +#include "plotting/GlobalPlotConfig.h" +class CliParser; + +class DiskPlotter +{ +public: + using Config = DiskPlotConfig; + + struct PlotRequest + { + const byte* plotId; + const byte* plotMemo; + uint16 plotMemoSize; + const char* plotFileName; + }; + +public: + // DiskPlotter(); + DiskPlotter( const Config& cfg ); + + void Plot( const PlotRequest& req ); + + static bool GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPath2, size_t& tmpPath1Size, size_t& tmpPath2Size ); + static size_t GetRequiredSizeForBuckets( const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2 ); + static size_t GetRequiredSizeForBuckets( const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize ); + + static void ParseCommandLine( CliParser& cli, Config& cfg ); + + static void PrintUsage(); + + +private: + DiskPlotContext _cx; + Config _cfg; +}; + diff --git a/src/plotdisk/FileId.h b/src/plotdisk/FileId.h new file mode 100644 index 00000000..817b15bb --- /dev/null +++ b/src/plotdisk/FileId.h @@ -0,0 +1,134 @@ +#pragma once + + +enum class FileId +{ + None = 0, + + // Bounded Phase 1: + Y, + META, + + // Phase 1 fx, key, metadata + FX0, FX1, + + // Table 7 fx values + F7, + + // Back pointers + T1, // 1 : X values + T2, // 2-7: Back pointers + T3, + T4, + T5, + T6, + T7, + + // Maps from match order to y-sorted order + MAP2, + MAP3, + MAP4, + MAP5, + MAP6, + MAP7, + + // Marked entries for prunning + MARKED_ENTRIES_2, + MARKED_ENTRIES_3, + MARKED_ENTRIES_4, + MARKED_ENTRIES_5, + MARKED_ENTRIES_6, + + // Line points + LP, + LP_MAP_0, + LP_MAP_1, + + PLOT + + ,_COUNT +}; ImplementArithmeticOps( FileId ); + + +//----------------------------------------------------------- +inline FileId TableIdToSortKeyId( const TableId table ) +{ + // switch( table ) + // { + // case TableId::Table2: return FileId::SORT_KEY2; + // case TableId::Table3: return FileId::SORT_KEY3; + // case TableId::Table4: return FileId::SORT_KEY4; + // case TableId::Table5: return FileId::SORT_KEY5; + // case TableId::Table6: return FileId::SORT_KEY6; + // case TableId::Table7: return FileId::SORT_KEY7; + + // default: + // ASSERT( 0 ); + // break; + // } + + ASSERT( 0 ); + return FileId::None; +} + +//----------------------------------------------------------- +inline FileId TableIdToBackPointerFileId( const TableId table ) +{ + switch( table ) + { + case TableId::Table2: return FileId::T2; + case TableId::Table3: return FileId::T3; + case TableId::Table4: return FileId::T4; + case TableId::Table5: return FileId::T5; + case TableId::Table6: return FileId::T6; + case TableId::Table7: return FileId::T7; + + default: + ASSERT( 0 ); + break; + } + + ASSERT( 0 ); + return FileId::None; +} + +//----------------------------------------------------------- +inline FileId TableIdToMapFileId( const TableId table ) +{ + switch( table ) + { + case TableId::Table2: return FileId::MAP2; + case TableId::Table3: return FileId::MAP3; + case TableId::Table4: return FileId::MAP4; + case TableId::Table5: return FileId::MAP5; + case TableId::Table6: return FileId::MAP6; + case TableId::Table7: return FileId::MAP7; + + default: + ASSERT( 0 ); + break; + } + + ASSERT( 0 ); + return FileId::None; +} + +//----------------------------------------------------------- +inline FileId TableIdToMarkedEntriesFileId( const TableId table ) +{ + switch( table ) + { + case TableId::Table2: return FileId::MARKED_ENTRIES_2; + case TableId::Table3: return FileId::MARKED_ENTRIES_3; + case TableId::Table4: return FileId::MARKED_ENTRIES_4; + case TableId::Table5: return FileId::MARKED_ENTRIES_5; + case TableId::Table6: return FileId::MARKED_ENTRIES_6; + + default: + ASSERT( 0 ); + break; + } + + ASSERT( 0 ); + return FileId::None; +} diff --git a/src/plotdisk/FpFxGen.h b/src/plotdisk/FpFxGen.h new file mode 100644 index 00000000..63ac567e --- /dev/null +++ b/src/plotdisk/FpFxGen.h @@ -0,0 +1,189 @@ +#pragma once +#include "plotting/Tables.h" +#include "threading/ThreadPool.h" +#include "plotdisk/DiskPlotInfo.h" +#include "b3/blake3.h" + +template +struct FpYType { using Type = uint64; }; + +template<> +struct FpYType { using Type = uint32; }; + + +template +struct FpFxGen +{ + using TMetaIn = typename TableMetaType
::MetaIn; + using TMetaOut = typename TableMetaType
::MetaOut; + using TYOut = typename FpYType
::Type; + + static constexpr size_t MetaInMulti = TableMetaIn
::Multiplier; + static constexpr size_t MetaOutMulti = TableMetaOut
::Multiplier; + + static constexpr uint32 _k = _K; + + //----------------------------------------------------------- + inline FpFxGen( ThreadPool& pool, const uint32 threadCount ) + : _pool ( pool ) + , _threadCount( threadCount ) + {} + + //----------------------------------------------------------- + inline void ComputeFxMT( const int64 entryCount, const Pair* pairs, const uint64* yIn, const TMetaIn* metaIn, + TYOut* yOut, TMetaOut* metaOut ) + { + AnonMTJob::Run( _pool, _threadCount, [=]( AnonMTJob* self ) { + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + ComputeFx( count, pairs+offset, yIn, metaIn, yOut+offset, metaOut+offset, self->_jobId ); + }); + } + + //----------------------------------------------------------- + static inline void ComputeFx( const int64 entryCount, const Pair* pairs, const uint64* yIn, const TMetaIn* metaIn, + TYOut* yOut, TMetaOut* metaOut, const uint32 id ) + { + static_assert( MetaInMulti != 0, "Invalid metaKMultiplier" ); + + // Helper consts + const uint32 shiftBits = MetaOutMulti == 0 ? 0 : kExtraBits; // Table 7 (identified by 0 metadata output) we don't have k + kExtraBits sized y's. + // so we need to shift by 32 bits, instead of 26. + const uint32 ySize = _k + kExtraBits; // = 38 + const uint32 yShift = 64 - (_k + shiftBits); // = 26 or 32 + const size_t metaSize = _k * MetaInMulti; + const size_t metaSizeLR = metaSize * 2; + + const size_t bufferSize = CDiv( ySize + metaSizeLR, 8 ); + + // Hashing + uint64 input [5]; // y + L + R + uint64 output[4]; // blake3 hashed output + + blake3_hasher hasher; + + static_assert( bufferSize <= sizeof( input ), "Invalid fx input buffer size." ); + + #if _DEBUG + uint64 prevY = yIn[pairs[0].left]; + uint64 prevLeft = 0; + #endif + + for( int64 i = 0; i < entryCount; i++ ) + { + const auto& pair = pairs[i]; + const uint32 left = pair.left; + const uint32 right = pair.right; + ASSERT( left < right ); + + const uint64 y = yIn[left]; + + #if _DEBUG + ASSERT( y >= prevY ); + ASSERT( left >= prevLeft ); + prevY = y; + prevLeft = left; + #endif + + // Extract metadata + auto& mOut = metaOut[i]; + + if constexpr( MetaInMulti == 1 ) + { + const uint64 l = metaIn[left ]; + const uint64 r = metaIn[right]; + + input[0] = Swap64( y << 26 | l >> 6 ); + input[1] = Swap64( l << 58 | r << 26 ); + + // Metadata is just L + R of 8 bytes + if constexpr( MetaOutMulti == 2 ) + mOut = l << 32 | r; + } + else if constexpr( MetaInMulti == 2 ) + { + const uint64 l = metaIn[left ]; + const uint64 r = metaIn[right]; + + input[0] = Swap64( y << 26 | l >> 38 ); + input[1] = Swap64( l << 26 | r >> 38 ); + input[2] = Swap64( r << 26 ); + + // Metadata is just L + R again of 16 bytes + if constexpr( MetaOutMulti == 4 ) + { + mOut.m0 = l; + mOut.m1 = r; + } + } + else if constexpr( MetaInMulti == 3 ) + { + const uint64 l0 = metaIn[left ].m0; + const uint64 l1 = metaIn[left ].m1 & 0xFFFFFFFF; + const uint64 r0 = metaIn[right].m0; + const uint64 r1 = metaIn[right].m1 & 0xFFFFFFFF; + + input[0] = Swap64( y << 26 | l0 >> 38 ); + input[1] = Swap64( l0 << 26 | l1 >> 6 ); + input[2] = Swap64( l1 << 58 | r0 >> 6 ); + input[3] = Swap64( r0 << 58 | r1 << 26 ); + } + else if constexpr( MetaInMulti == 4 ) + { + // const uint64 l0 = metaInA[left ]; + // const uint64 l1 = metaInB[left ]; + // const uint64 r0 = metaInA[right]; + // const uint64 r1 = metaInB[right]; + const Meta4 l = metaIn[left]; + const Meta4 r = metaIn[right]; + + input[0] = Swap64( y << 26 | l.m0 >> 38 ); + input[1] = Swap64( l.m0 << 26 | l.m1 >> 38 ); + input[2] = Swap64( l.m1 << 26 | r.m0 >> 38 ); + input[3] = Swap64( r.m0 << 26 | r.m1 >> 38 ); + input[4] = Swap64( r.m1 << 26 ); + } + + // Hash the input + blake3_hasher_init( &hasher ); + blake3_hasher_update( &hasher, input, bufferSize ); + blake3_hasher_finalize( &hasher, (uint8_t*)output, sizeof( output ) ); + + const uint64 f = Swap64( *output ) >> yShift; + yOut[i] = (TYOut)f; + + if constexpr ( MetaOutMulti == 2 && MetaInMulti == 3 ) + { + const uint64 h0 = Swap64( output[0] ); + const uint64 h1 = Swap64( output[1] ); + + mOut = h0 << ySize | h1 >> 26; + } + else if constexpr ( MetaOutMulti == 3 ) + { + const uint64 h0 = Swap64( output[0] ); + const uint64 h1 = Swap64( output[1] ); + const uint64 h2 = Swap64( output[2] ); + + mOut.m0 = h0 << ySize | h1 >> 26; + mOut.m1 = ((h1 << 6) & 0xFFFFFFC0) | h2 >> 58; + } + else if constexpr ( MetaOutMulti == 4 && MetaInMulti != 2 ) // In = 2 is calculated above with L + R + { + const uint64 h0 = Swap64( output[0] ); + const uint64 h1 = Swap64( output[1] ); + const uint64 h2 = Swap64( output[2] ); + + mOut.m0 = h0 << ySize | h1 >> 26; + mOut.m1 = h1 << 38 | h2 >> 26; + } + } + } + + +private: + ThreadPool& _pool; + uint32 _threadCount; +}; \ No newline at end of file diff --git a/src/plotdisk/FpGroupMatcher.h b/src/plotdisk/FpGroupMatcher.h new file mode 100644 index 00000000..223a5c7a --- /dev/null +++ b/src/plotdisk/FpGroupMatcher.h @@ -0,0 +1,303 @@ +#pragma once +#include "DiskPlotContext.h" +#include "DiskPlotInfo.h" +#include "threading/ThreadPool.h" + +struct FpCrossBucketInfo +{ + uint32 groupCount[2]; + + uint64 savedY [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + Meta4 savedMeta[BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + Pair pair [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + + uint64* y = nullptr; + Meta4* meta = nullptr; + uint64 matchCount = 0; + uint64 matchOffset[2] = { 0 }; // 0 = prev bucket, 1 = cur bucket + uint32 bucket; + uint32 maxBuckets; + + inline bool IsLastBucket() const { return bucket == maxBuckets-1; } + inline bool IsFirstBucket() const { return bucket == 0; } + inline uint64 EntryCount() const { return (uint64)groupCount[0] + groupCount[1]; } +}; + +struct FpGroupMatcher +{ + DiskPlotContext& _context; + uint64 _maxMatches; + const uint64* _startPositions[BB_DP_MAX_JOBS];// = { 0 }; + uint64 _matchCounts [BB_DP_MAX_JOBS];// = { 0 }; + uint64* _groupIndices [BB_DP_MAX_JOBS]; + Pair* _pairs [BB_DP_MAX_JOBS]; + Pair* _outPairs; + + //----------------------------------------------------------- + inline FpGroupMatcher( DiskPlotContext& context, const uint64 maxEntries, + uint64* groupBoundaries, Pair* pairs, Pair* outPairs ) + : _context( context ) + , _maxMatches( maxEntries / context.fpThreadCount ) + , _outPairs( outPairs ) + { + for( uint32 i = 0; i < context.fpThreadCount; i++ ) + { + _groupIndices[i] = groupBoundaries + _maxMatches * i; + _pairs [i] = pairs + _maxMatches * i; + } + } + + //----------------------------------------------------------- + template + inline uint64 Match( const int64 entryCount, const uint64* yEntries, const TMeta* meta, FpCrossBucketInfo* crossBucketInfo ) + { + const uint32 threadCount = _context.fpThreadCount; + + AnonMTJob::Run( *_context.threadPool, threadCount, [=]( AnonMTJob* self ) { + + const uint32 id = self->_jobId; + + int64 _, offset; + GetThreadOffsets( self, entryCount, _, offset, _ ); + + const uint64* start = yEntries; + const uint64* entries = start + offset; + + // Find base start position + uint64 curGroup = *entries / kBC; + while( entries > start ) + { + if( entries[-1] / kBC != curGroup ) + break; + --entries; + } + + const uint64 startIndex = (uint64)(uintptr_t)(entries - start); + + _startPositions[id] = entries; + self->SyncThreads(); + + const uint64* end = self->IsLastThread() ? yEntries + entryCount : _startPositions[id+1]; + + // Now scan for all groups + uint64* groupIndices = _groupIndices[id]; + uint64 groupCount = 0; + while( ++entries < end ) + { + const uint64 g = *entries / kBC; + if( g != curGroup ) + { + ASSERT( groupCount < _maxMatches ); + groupIndices[groupCount++] = (uint64)(uintptr_t)(entries - start); + + ASSERT( g - curGroup > 1 || groupCount == 1 || groupIndices[groupCount-1] - groupIndices[groupCount-2] <= 350 ); + curGroup = g; + } + } + + self->SyncThreads(); + + // Add the end location of the last R group + if( self->IsLastThread() ) + { + ASSERT( groupCount < _maxMatches ); + groupIndices[groupCount] = (uint64)entryCount; + } + else + { + ASSERT( groupCount+1 < _maxMatches ); + groupIndices[groupCount++] = (uint64)(uintptr_t)(_startPositions[id+1] - start); + groupIndices[groupCount ] = _groupIndices[id+1][0]; + } + + // Cross-bucket matching + // Perform cross-bucket matches with the previous bucket + if( self->IsControlThread() && !crossBucketInfo->IsFirstBucket() ) + this->CrossBucketMatch( *crossBucketInfo, yEntries, meta, groupIndices ); + + // Now perform matches + _matchCounts[id] = MatchGroups( startIndex, groupCount, groupIndices, yEntries, _pairs[id], _maxMatches, id ); + + // Copy to contiguous pair buffer + self->SyncThreads(); + + size_t copyOffset = 0; + + uint64* allMatches = _matchCounts; + for( uint32 i = 0; i < id; i++ ) + copyOffset += allMatches[i]; + + memcpy( _outPairs + copyOffset, _pairs[id], sizeof( Pair ) * _matchCounts[id] ); + + // Save the last 2 groups for cross-bucket matching + if( self->IsLastThread() ) + SaveCrossBucketInfo( *crossBucketInfo, groupIndices + groupCount - 2, yEntries, meta ); + }); + + const uint64* allMatches = _matchCounts; + uint64 matchCount = 0; + for( uint32 i = 0; i < threadCount; i++ ) + matchCount += allMatches[i]; + + return matchCount; + } + + //----------------------------------------------------------- + template + inline static uint64 MatchGroups( + const uint64 startIndex, const int64 groupCount, + const uint64* groupBoundaries, const uint64* yBuffer, + Pair* pairs, const uint64 maxPairs, const uint32 id = 0 ) + { + uint64 pairCount = 0; + + uint8 rMapCounts [kBC]; + uint16 rMapIndices[kBC]; + + uint64 groupLStart = startIndex; + uint64 groupL = yBuffer[groupLStart] / kBC; + + for( uint32 i = 0; i < groupCount; i++ ) + { + const uint64 groupRStart = groupBoundaries[i]; + const uint64 groupR = yBuffer[groupRStart] / kBC; + + const uint64 groupLEnd = IdIsLGroupEnd ? id : groupRStart; + + if( groupR - groupL == 1 ) + { + // Groups are adjacent, calculate matches + const uint16 parity = groupL & 1; + const uint64 groupREnd = groupBoundaries[i+1]; + + const uint64 groupLRangeStart = groupL * kBC; + const uint64 groupRRangeStart = groupR * kBC; + + ASSERT( groupREnd - groupRStart <= 350 ); + ASSERT( groupLRangeStart == groupRRangeStart - kBC ); + + // Prepare a map of range kBC to store which indices from groupR are used + // For now just iterate our bGroup to find the pairs + + // #NOTE: memset(0) works faster on average than keeping a separate a clearing buffer + memset( rMapCounts, 0, sizeof( rMapCounts ) ); + + for( uint64 iR = groupRStart; iR < groupREnd; iR++ ) + { + uint64 localRY = yBuffer[iR] - groupRRangeStart; + ASSERT( yBuffer[iR] / kBC == groupR ); + + if( rMapCounts[localRY] == 0 ) + rMapIndices[localRY] = (uint16)( iR - groupRStart ); + + rMapCounts[localRY] ++; + } + + // For each group L entry + for( uint64 iL = groupLStart; iL < groupLEnd; iL++ ) + { + const uint64 yL = yBuffer[iL]; + const uint64 localL = yL - groupLRangeStart; + + // Iterate kExtraBitsPow = 1 << kExtraBits = 1 << 6 == 64 + // So iterate 64 times for each L entry. + for( int iK = 0; iK < kExtraBitsPow; iK++ ) + { + const uint64 targetR = L_targets[parity][localL][iK]; + + for( uint j = 0; j < rMapCounts[targetR]; j++ ) + { + const uint64 iR = groupRStart + rMapIndices[targetR] + j; + ASSERT( iL < iR ); + + // Add a new pair + Pair& pair = pairs[pairCount++]; + pair.left = (uint32)iL; + pair.right = (uint32)iR; + + ASSERT( pairCount <= maxPairs ); + if( pairCount == maxPairs ) + return pairCount; + } + } + } + } + // Else: Not an adjacent group, skip to next one. + + // Go to next group + groupL = groupR; + groupLStart = groupRStart; + } + + return pairCount; + } + +private: + //----------------------------------------------------------- + template + inline void CrossBucketMatch( FpCrossBucketInfo& info, const uint64* yEntries, const TMeta* meta, const uint64 curBucketIndices[2] ) + { + const uint64 prevGroupsEntryCount = info.EntryCount(); + + uint64 groupBoundaries[3] = { + prevGroupsEntryCount, + curBucketIndices[0] + prevGroupsEntryCount, + curBucketIndices[1] + prevGroupsEntryCount + }; + + // Copy to the area before our working buffer starts. It is reserved for cross-bucket entries + info.y = (uint64*)( yEntries - prevGroupsEntryCount ); + info.meta = (Meta4*)( meta - prevGroupsEntryCount ); + + memcpy( info.y , info.savedY , sizeof( uint64 ) * prevGroupsEntryCount ); + memcpy( info.meta, info.savedMeta, sizeof( TMeta ) * prevGroupsEntryCount ); + + const uint64* yStart = info.y; + uint64 matches = 0; + + uint32 lastGrpMatchIndx = 1; + + // If the first entry group is the same from the prev's bucket last group, + // then we can perform matches with the penultimate bucket + if( yEntries[0] / kBC == yEntries[-1] / kBC ) + { + matches = MatchGroups( 0, 1, groupBoundaries, yStart, info.pair, + BB_DP_CROSS_BUCKET_MAX_ENTRIES, (uint32)info.groupCount[0] ); + } + else + { + // We have different groups at the bucket boundary, so update the boundaries for the next match accordingly + lastGrpMatchIndx = 0; + } + + matches += MatchGroups( info.groupCount[0], 1, &groupBoundaries[lastGrpMatchIndx], yStart, &info.pair[matches], + BB_DP_CROSS_BUCKET_MAX_ENTRIES-matches, (uint32)prevGroupsEntryCount ); + + info.matchCount = matches; + } + + //----------------------------------------------------------- + template + inline void SaveCrossBucketInfo( FpCrossBucketInfo& info, const uint64 groupIndices[3], const uint64* y, const TMeta* meta ) + { + info.matchOffset[0] = info.matchOffset[1]; + info.matchOffset[1] = groupIndices[0]; + + if( info.IsLastBucket() ) + return; + + info.groupCount[0] = (uint32)( groupIndices[1] - groupIndices[0] ); + info.groupCount[1] = (uint32)( groupIndices[2] - groupIndices[1] ); + + const size_t copyCount = info.groupCount[0] + info.groupCount[1]; + ASSERT( copyCount <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + + memcpy( info.savedY , y + groupIndices[0], copyCount * sizeof( uint64 ) ); + memcpy( info.savedMeta, meta + groupIndices[0], copyCount * sizeof( TMeta ) ); + + ASSERT( info.savedY[0] / kBC == info.savedY[info.groupCount[0]-1] / kBC ); + ASSERT( info.savedY[info.groupCount[0]] / kBC == info.savedY[info.groupCount[0]+info.groupCount[1]-1] / kBC ); + } +}; + + diff --git a/src/plotdisk/IOTransforms.h b/src/plotdisk/IOTransforms.h new file mode 100644 index 00000000..1c32b175 --- /dev/null +++ b/src/plotdisk/IOTransforms.h @@ -0,0 +1,24 @@ +#pragma once + +class IIOTransform +{ +public: + struct TransformData + { + void* buffer; + uint32 numBuckets; + uint32* bucketSizes; + + // void* output; + // size_t inputSize; + // void* userData; + }; + +public: + inline virtual ~IIOTransform() {} + // virtual void ReadTransform( TransformData& data ) = 0; + // virtual void WriteTransform( TransformData& data ) = 0; + + inline virtual void Read( TransformData& data ) {} + inline virtual void Write( TransformData& data ) {} +}; diff --git a/src/plotdisk/jobs/IOJob.cpp b/src/plotdisk/jobs/IOJob.cpp new file mode 100644 index 00000000..b6557da1 --- /dev/null +++ b/src/plotdisk/jobs/IOJob.cpp @@ -0,0 +1,257 @@ +#include "IOJob.h" +#include "threading/ThreadPool.h" +#include "threading/MTJob.h" +#include "util/Util.h" +#include "io/IStream.h" +#include "io/FileStream.h" + +//----------------------------------------------------------- +bool IOJob::MTWrite( ThreadPool& pool, uint32 threadCount, + IStream** files, + const void* bufferToWrite, const size_t sizeToWrite, + void** blockBuffers, const size_t blockSize, + int& error ) +{ + return RunIOJob( true, pool, threadCount, files, (byte*)bufferToWrite, sizeToWrite, + (byte**)blockBuffers, blockSize, error ); +} + +//----------------------------------------------------------- +bool IOJob::MTRead( ThreadPool& pool, uint32 threadCount, + IStream** files, + void* dstBuffer, const size_t sizeToRead, + void** blockBuffers, const size_t blockSize, + int& error ) +{ + + return RunIOJob( false, pool, threadCount, files, (byte*)dstBuffer, sizeToRead, + (byte**)blockBuffers, blockSize, error ); +} + +//----------------------------------------------------------- +bool IOJob::RunIOJob( bool write, + ThreadPool& pool, + uint32 threadCount, + IStream** files, + byte* ioBuffer, const size_t size, + byte** blockBuffers, const size_t blockSize, + int& error ) +{ + ASSERT( files ); + ASSERT( threadCount <= pool.ThreadCount() ); + ASSERT( ioBuffer ); + ASSERT( blockBuffers ); + ASSERT( size ); + ASSERT( blockSize ); + + + error = 0; + threadCount = std::max( 1u, std::min( threadCount, pool.ThreadCount() ) ); + + // For small writes use a single thread + const size_t minWrite = std::max( blockSize, (size_t)16 MB ); + + if( size <= minWrite || threadCount == 1 ) + { + if( write ) + return WriteToFile( **files, ioBuffer, size, blockBuffers[0], blockSize, error ); + else + return ReadFromFile( **files, ioBuffer, size, blockBuffers[0], blockSize, error ); + } + + + MTJobRunner jobs( pool ); + + // Size per thread, aligned to block size + const size_t sizePerThread = size / threadCount / blockSize * blockSize; + size_t sizeRemainder = size - sizePerThread * threadCount; + + + size_t fileOffset = 0; + + for( uint32 i = 0; i < threadCount; i++ ) + { + ASSERT( blockBuffers[i] ); + + auto& job = jobs[i]; + + job._file = files[i]; + job._blockSize = blockSize; + job._size = sizePerThread; + job._buffer = ioBuffer + fileOffset; + job._blockBuffer = (byte*)blockBuffers[i]; + job._offset = (int64)fileOffset; + job._error = 0; + job._isWrite = write; + + if( fileOffset > 0 ) + { + if( !job._file->Seek( fileOffset, SeekOrigin::Current ) ) + { + error = job._file->GetError(); + return false; + } + } + + if( sizeRemainder >= blockSize ) + { + job._size += blockSize; + sizeRemainder -= blockSize; + } + + fileOffset += job._size; + } + + jobs[threadCount-1]._size += sizeRemainder; + jobs.Run( threadCount ); + + // Find the first job with an error + for( uint32 i = 0; i < threadCount; i++ ) + { + if( jobs[i]._error != 0 ) + { + error = jobs[i]._error; + return false; + } + } + + return true; +} + +//----------------------------------------------------------- +void IOJob::Run() +{ + if( _isWrite ) + WriteToFile( *_file, _buffer, _size, _blockBuffer, _blockSize, _error ); + else + ReadFromFile( *_file, _buffer, _size, _blockBuffer, _blockSize, _error ); +} + +//----------------------------------------------------------- +bool IOJob::WriteToFile( IStream& file, const void* writeBuffer, const size_t size, + void* fileBlockBuffer, const size_t blockSize, int& error ) +{ + error = 0; + + const byte* buffer = (byte*)writeBuffer; + byte* blockBuffer = (byte*)fileBlockBuffer; + + size_t sizeToWrite = size / blockSize * blockSize; + const size_t remainder = size - sizeToWrite; + + while( sizeToWrite ) + { + ssize_t sizeWritten = file.Write( buffer, sizeToWrite ); + if( sizeWritten < 1 ) + { + error = file.GetError(); + return false; + } + + ASSERT( sizeWritten <= (ssize_t)sizeToWrite ); + + sizeToWrite -= (size_t)sizeWritten; + buffer += sizeWritten; + } + + if( remainder ) + { + ASSERT( blockBuffer ); + + // Unnecessary zeroing of memory, but might be useful for debugging + memset( blockBuffer, 0, blockSize ); + memcpy( blockBuffer, buffer, remainder ); + + ssize_t sizeWritten = file.Write( blockBuffer, blockSize ); + + if( sizeWritten < 1 ) + { + error = file.GetError(); + return false; + } + } + + return true; +} + +//----------------------------------------------------------- +void* IOJob::ReadAllBytesDirect( const char* path, int& error ) +{ + FileStream file; + if( !file.Open( path, FileMode::Open, FileAccess::Read, FileFlags::NoBuffering ) ) + return nullptr; + + const size_t blockSize = file.BlockSize(); + const size_t readSize = file.Size(); + const size_t allocSize = RoundUpToNextBoundaryT( readSize, blockSize ); + + void* block = bbvirtalloc( blockSize ); + void* buffer = bbvirtalloc( allocSize ); + + const bool r = ReadFromFile( file, buffer, readSize, block, blockSize, error ); + + bbvirtfree( block ); + if( !r ) + { + bbvirtfree( buffer ); + return nullptr; + } + + return buffer; +} + +//----------------------------------------------------------- +bool IOJob::ReadFromFile( const char* path, void* buffer, const size_t size, + void* blockBuffer, const size_t blockSize, int& error ) +{ + FileStream file; + if( !file.Open( path, FileMode::Open, FileAccess::Read ) ) + return false; + + return ReadFromFile( file, buffer, size, blockBuffer, blockSize, error ); +} + +//----------------------------------------------------------- +bool IOJob::ReadFromFile( IStream& file, void* readBuffer, const size_t size, + void* fileBlockBuffer, const size_t blockSize, int& error ) +{ + error = 0; + + byte* buffer = (byte*)readBuffer; + byte* blockBuffer = (byte*)fileBlockBuffer; + + size_t sizeToRead = size / blockSize * blockSize; + const size_t remainder = size - sizeToRead; + + // size_t sizeToRead = CDivT( size, blockSize ) * blockSize; + + while( sizeToRead ) + { + ssize_t sizeRead = file.Read( buffer, sizeToRead ); + if( sizeRead < 1 ) + { + error = file.GetError(); + return false; + } + + ASSERT( sizeRead <= (ssize_t)sizeToRead ); + + sizeToRead -= (size_t)sizeRead; + buffer += sizeRead; + } + + if( remainder ) + { + ssize_t sizeRead = file.Read( blockBuffer, blockSize ); + + if( sizeRead < (ssize_t)remainder ) + { + error = file.GetError(); + return false; + } + + memcpy( buffer, blockBuffer, remainder ); + } + + return true; +} diff --git a/src/plotdisk/jobs/IOJob.h b/src/plotdisk/jobs/IOJob.h new file mode 100644 index 00000000..f90437eb --- /dev/null +++ b/src/plotdisk/jobs/IOJob.h @@ -0,0 +1,52 @@ +#pragma once + +#include "threading/MTJob.h" + +class IStream; +class ThreadPool; + +struct IOJob : MTJob +{ + IStream* _file; + size_t _blockSize; + size_t _size; + byte* _buffer; + byte* _blockBuffer; + int64 _offset; // If not zero, the file will be seeked to this relative offset before writing. + int _error; + bool _isWrite; // True if the job is a write job + + static bool WriteTest( const char* testPath, size_t testSize, uint threadCount ); + + static bool MTWrite( ThreadPool& pool, uint32 threadCount, + IStream** files, + const void* bufferToWrite, const size_t sizeToWrite, + void** blockBuffers, const size_t blockSize, + int& error ); + + static bool MTRead( ThreadPool& pool, uint32 const threadCount, + IStream** files, + void* dstBuffer, const size_t sizeToRead, + void** blockBuffers, const size_t blockSize, + int& error ); + + void Run() override; + + static bool WriteToFile( IStream& file, const void* writeBuffer, const size_t size, + void* fileBlockBuffer, const size_t blockSize, int& error ); + + static bool ReadFromFile( IStream& file, void* buffer, const size_t size, + void* blockBuffer, const size_t blockSize, int& error ); + + static bool ReadFromFile( const char* path, void* buffer, const size_t size, + void* blockBuffer, const size_t blockSize, int& error ); + + static void* ReadAllBytesDirect( const char* path, int& error ); + +private: + static bool RunIOJob( bool write, ThreadPool& pool, uint32 threadCount, + IStream** files, + byte* ioBuffer, const size_t size, + byte** blockBuffers, const size_t blockSize, + int& error ); +}; \ No newline at end of file diff --git a/src/plotdisk/jobs/JobShared.h b/src/plotdisk/jobs/JobShared.h new file mode 100644 index 00000000..7472454c --- /dev/null +++ b/src/plotdisk/jobs/JobShared.h @@ -0,0 +1,18 @@ +#pragma once + +#include "plotdisk/DiskPlotConfig.h" +#include "threading/MTJob.h" + +// template +// struct BucketJob : MTJob +// { +// const uint32* counts; // Each thread's entry count per bucket +// uint32* totalBucketCounts; // Total counts per for all buckets. Used by the control thread + +// // DiskBufferQueue* diskQueue; +// // uint32 chunkCount; + +// void CalculatePrefixSum( const uint32 counts [BB_DP_BUCKET_COUNT], +// uint32 pfxSum [BB_DP_BUCKET_COUNT], +// uint32 bucketCounts[BB_DP_BUCKET_COUNT] ); +// }; diff --git a/src/plotdisk/jobs/LookupMapJob.h b/src/plotdisk/jobs/LookupMapJob.h new file mode 100644 index 00000000..7d119244 --- /dev/null +++ b/src/plotdisk/jobs/LookupMapJob.h @@ -0,0 +1,181 @@ +#pragma once +#include "plotdisk/DiskPlotContext.h" +#include "threading/MTJob.h" +#include "threading/Fence.h" + +template +struct ReverseMapJob : MTJob> +{ + DiskBufferQueue* ioQueue; + uint32 entryCount; + uint32 sortedIndexOffset; // Offset of the index at which each sorted source index is stored + const uint32* sortedSourceIndices; // Read-only sorted final (absolute) position of the origin indices + uint64* mappedIndices; // Write to position for the buckets + + uint32* bucketCounts; + + // For internal use: + const uint32* counts; + + void Run() override; + + void CalculatePrefixSum( + uint32 counts [BucketCount], + uint32 pfxSum [BucketCount], + uint32 bucketCounts[BucketCount], + const size_t fileBlockSize ); +}; + +//----------------------------------------------------------- +template +inline void ReverseMapJob::Run() +{ + // #TODO: Determine bits needed bucket count statically. + // For now hard coded to 64 buckets. + const uint32 bitShift = 32 - kExtraBits; + + const uint32 entryCount = this->entryCount; + const uint32* sortedOriginIndices = this->sortedSourceIndices; + const uint32* end = sortedOriginIndices + entryCount; + + uint64* map = this->mappedIndices; + + uint32 counts[BucketCount]; + uint32 pfxSum[BucketCount]; + + memset( counts, 0, sizeof( counts ) ); + + // Count how many entries we have per bucket + { + const uint32* index = sortedOriginIndices; + + while( index < end ) + { + const uint bucket = (*index) >> bitShift; + counts[bucket]++; + index++; + } + } + + // Calculate prefix sum + // #TODO: Allow block-aligned prefix sum here + this->CalculatePrefixSum( counts, pfxSum, this->bucketCounts, 0 ); + + // Now distribute to the respective buckets + const uint32 entriesPerThread = this->GetJob( 0 ).entryCount; + const uint32 sortedIndexOffset = this->sortedIndexOffset + this->JobId() * entriesPerThread; + + for( uint32 i = 0; i < entryCount; i++ ) + { + const uint32 originIndex = sortedOriginIndices[i]; // Original index of this entry before y sort + const uint64 sortedIndex = i + sortedIndexOffset; // Index where this entry was placed after y sort + const uint32 bucket = (uint32)(originIndex >> bitShift); + + const uint32 dstIndex = --pfxSum[bucket]; + + map[dstIndex] = ( sortedIndex << 32 ) | originIndex; + } + + // Ensure all threads end at the same time (so that counts doesn't go out of scope) + this->SyncThreads(); +} + +// #TODO: Avoud code duplication here +//----------------------------------------------------------- +template +inline void ReverseMapJob::CalculatePrefixSum( + uint32 counts [BucketCount], + uint32 pfxSum [BucketCount], + uint32 bucketCounts[BucketCount], + const size_t fileBlockSize ) +{ + const uint32 jobId = this->JobId(); + const uint32 jobCount = this->JobCount(); + + // This holds the count of extra entries added per-bucket + // to align each bucket starting address to disk block size. + // Only used when fileBlockSize > 0 + uint32 entryPadding[BB_DP_BUCKET_COUNT]; + + this->counts = counts; + this->SyncThreads(); + + // Add up all of the jobs counts + memset( pfxSum, 0, sizeof( uint32 ) * BB_DP_BUCKET_COUNT ); + + for( uint i = 0; i < jobCount; i++ ) + { + const uint* tCounts = this->GetJob( i ).counts; + + for( uint j = 0; j < BB_DP_BUCKET_COUNT; j++ ) + pfxSum[j] += tCounts[j]; + } + + // If we're the control thread, retain the total bucket count + if( this->IsControlThread() ) + { + memcpy( bucketCounts, pfxSum, sizeof( uint32 ) * BB_DP_BUCKET_COUNT ); + } + + // Only do this if using Direct IO + // We need to align our bucket totals to the file block size boundary + // so that each block buffer is properly aligned for direct io. + if( fileBlockSize ) + { + #if _DEBUG + size_t bucketAddress = 0; + #endif + + for( uint i = 0; i < BB_DP_BUCKET_COUNT-1; i++ ) + { + const uint32 count = pfxSum[i]; + + pfxSum[i] = RoundUpToNextBoundary( count * sizeof( uint32 ), (int)fileBlockSize ) / sizeof( uint32 ); + entryPadding[i] = pfxSum[i] - count; + + #if _DEBUG + bucketAddress += pfxSum[i] * sizeof( uint32 ); + ASSERT( bucketAddress / fileBlockSize * fileBlockSize == bucketAddress ); + #endif + } + + #if _DEBUG + // if( this->IsControlThread() ) + // { + // size_t totalSize = 0; + // for( uint i = 0; i < BB_DP_BUCKET_COUNT; i++ ) + // totalSize += pfxSum[i]; + + // totalSize *= sizeof( uint32 ); + // Log::Line( "Total Size: %llu", totalSize ); + // } + #endif + } + + // Calculate the prefix sum + for( uint i = 1; i < BB_DP_BUCKET_COUNT; i++ ) + pfxSum[i] += pfxSum[i-1]; + + // Subtract the count from all threads after ours + // to get the correct prefix sum for this thread + for( uint t = jobId+1; t < jobCount; t++ ) + { + const uint* tCounts = this->GetJob( t ).counts; + + for( uint i = 0; i < BB_DP_BUCKET_COUNT; i++ ) + pfxSum[i] -= tCounts[i]; + } + + if( fileBlockSize ) + { + // Now that we have the starting addresses of the buckets + // at a block-aligned position, we need to substract + // the padding that we added to align them, so that + // the entries actually get writting to the starting + // point of the address + + for( uint i = 0; i < BB_DP_BUCKET_COUNT-1; i++ ) + pfxSum[i] -= entryPadding[i]; + } +} + diff --git a/src/plotdisk/jobs/UnpackMapJob.cpp b/src/plotdisk/jobs/UnpackMapJob.cpp new file mode 100644 index 00000000..25c66880 --- /dev/null +++ b/src/plotdisk/jobs/UnpackMapJob.cpp @@ -0,0 +1,52 @@ +#include "UnpackMapJob.h" + +// //----------------------------------------------------------- +// void UnpackMapJob::RunJob( +// ThreadPool& pool, const uint32 threadCount, +// const uint32 bucket, const uint32 bucketCount, +// const uint32 entryCount, const uint64* mapSrc, uint32* mapDst ) +// { +// MTJobRunner jobs( pool ); + +// for( uint32 i = 0; i < threadCount; i++ ) +// { +// auto& job = jobs[i]; +// // job.bucketCount = bucketCount; +// job.bucket = bucket; +// job.entryCount = entryCount; +// job.mapSrc = mapSrc; +// job.mapDst = mapDst; +// } + +// jobs.Run( threadCount ); +// } + +// //----------------------------------------------------------- +// void UnpackMapJob::Run() +// { +// const uint64 maxEntries = 1ull << _K ; +// const uint32 fixedBucketLength = (uint32)( maxEntries / BB_DP_BUCKET_COUNT );// this->bucketCount ); +// const uint32 bucketOffset = fixedBucketLength * this->bucket; + +// const uint32 threadCount = this->JobCount(); +// uint32 entriesPerThread = this->entryCount / threadCount; + +// const uint32 offset = entriesPerThread * this->JobId(); + +// if( this->IsLastThread() ) +// entriesPerThread += this->entryCount - entriesPerThread * threadCount; + +// const uint64* mapSrc = this->mapSrc + offset; +// uint32* mapDst = this->mapDst; + +// // Unpack with the bucket id +// for( uint32 i = 0; i < entriesPerThread; i++ ) +// { +// const uint64 m = mapSrc[i]; +// const uint32 idx = (uint32)m - bucketOffset; + +// ASSERT( idx < this->entryCount ); + +// mapDst[idx] = (uint32)(m >> 32); +// } +// } diff --git a/src/plotdisk/jobs/UnpackMapJob.h b/src/plotdisk/jobs/UnpackMapJob.h new file mode 100644 index 00000000..7a5aa145 --- /dev/null +++ b/src/plotdisk/jobs/UnpackMapJob.h @@ -0,0 +1,78 @@ +#pragma once + +#include "plotdisk/DiskPlotContext.h" + +// struct UnpackMapJob : MTJob +// { +// // uint32 bucketCount; +// uint32 bucket; +// uint32 entryCount; +// const uint64* mapSrc; +// uint32* mapDst; + +// static void RunJob( ThreadPool& pool, const uint32 threadCount, +// const uint32 bucket, const uint32 bucketCount, +// const uint32 entryCount, const uint64* mapSrc, uint32* mapDst ); + +// void Run() override; +// }; + + + +struct UnpackMapJob : MTJob +{ + uint32 bucket; + uint32 entryCount; + const uint64* mapSrc; + uint32* mapDst; + + //----------------------------------------------------------- + static void RunJob( ThreadPool& pool, const uint32 threadCount, const uint32 bucket, + const uint32 entryCount, const uint64* mapSrc, uint32* mapDst ) + { + MTJobRunner jobs( pool ); + + for( uint32 i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + job.bucket = bucket; + job.entryCount = entryCount; + job.mapSrc = mapSrc; + job.mapDst = mapDst; + } + + jobs.Run( threadCount ); + } + + //----------------------------------------------------------- + void Run() override + { + const uint64 maxEntries = 1ull << _K ; + const uint32 fixedBucketLength = (uint32)( maxEntries / BB_DP_BUCKET_COUNT ); + const uint32 bucketOffset = fixedBucketLength * this->bucket; + + + const uint32 threadCount = this->JobCount(); + uint32 entriesPerThread = this->entryCount / threadCount; + + const uint32 offset = entriesPerThread * this->JobId(); + + if( this->IsLastThread() ) + entriesPerThread += this->entryCount - entriesPerThread * threadCount; + + const uint64* mapSrc = this->mapSrc + offset; + uint32* mapDst = this->mapDst; + + // Unpack with the bucket id + for( uint32 i = 0; i < entriesPerThread; i++ ) + { + const uint64 m = mapSrc[i]; + const uint32 idx = (uint32)m - bucketOffset; + + ASSERT( idx >> 26 == bucket ); + ASSERT( idx < this->entryCount ); + + mapDst[idx] = (uint32)(m >> 32); + } + } +}; diff --git a/src/plotdisk/main_diskplot.h b/src/plotdisk/main_diskplot.h new file mode 100644 index 00000000..0653f48a --- /dev/null +++ b/src/plotdisk/main_diskplot.h @@ -0,0 +1,493 @@ +#include +#include "DiskPlotter.h" +#include "SysHost.h" +#include "io/FileStream.h" +#include "util/Log.h" +#include "plotting/PlotTools.h" + +// TEST +#include "plotdisk/jobs/IOJob.h" +#include "threading/ThreadPool.h" +#include + +// TEST: +void TestDiskBackPointers(); +void TestLookupMaps(); + +struct GlobalConfig +{ + +}; + + +//----------------------------------------------------------- +void ParseConfig( int argc, const char* argv[], GlobalConfig& gConfig, DiskPlotter::Config& cfg ); + +size_t ParseSize( const char* arg, const char* sizeText ); +size_t ValidateTmpPathAndGetBlockSize( DiskPlotter::Config& cfg ); + +//----------------------------------------------------------- +int WriteTest( int argc, const char* argv[] ) +{ + uint threadCount = 4; + const size_t bufferSize = 64ull GB; + // const uint bufferCount = 4; + const char* filePath = "/mnt/p5510a/test.tmp"; + + // if( argc > 0 ) + // { + // int r = sscanf( argv[0], "%lu", &threadCount ); + // FatalIf( r != 1, "Invalid value for threadCount" ); + // } + + Log::Line( "Threads : %u", threadCount ); + Log::Line( "Buffer Size: %llu GiB", bufferSize BtoGB ); + + ThreadPool pool( threadCount ); + FileStream* files = new FileStream[threadCount]; + byte** blockBuffers = new byte*[threadCount]; + + for( uint i = 0; i < threadCount; i++ ) + { + FatalIf( !files[i].Open( filePath, FileMode::OpenOrCreate, FileAccess::ReadWrite, + FileFlags::LargeFile | FileFlags::NoBuffering ), "Failed to open file." ); + + blockBuffers[i] = (byte*)SysHost::VirtualAlloc( files[i].BlockSize() ); + } + Log::Line( "Allocating buffer..." ); + byte* buffer = (byte*)SysHost::VirtualAlloc( bufferSize, true ); + + Log::Line( "Writing..." ); + int error = 0; + double elapsed = IOJob::WriteWithThreads( + threadCount, pool, files, buffer, bufferSize, blockBuffers, files[0].BlockSize(), error ); + + if( error ) + Fatal( "Error when writing: %d (0x%x)", error, error ); + + const double writeRate = bufferSize / elapsed; + + Log::Line( "Wrote %.2lf GiB in %.4lf seconds: %.2lf MiB/s (%.2lf MB/s)", + (double)bufferSize BtoGB, elapsed, writeRate BtoMB, writeRate / 1000 / 1000 ); + + FatalIf( !files[0].Seek( 0, SeekOrigin::Begin ), + "Failed to seek file with error %d.", files[0].GetError() ); + + Log::Line( "Reading..." ); + auto readTimer = TimerBegin(); + IOJob::ReadFromFile( files[0], buffer, bufferSize, blockBuffers[0], files[0].BlockSize(), error ); + elapsed = TimerEnd( readTimer ); + + FatalIf( error, "Error reading: %d, (0x%x)", error, error ); + + const double readRate = bufferSize / elapsed; + Log::Line( "Read %.2lf GiB in %.4lf seconds: %.2lf MiB/s (%.2lf MB/s)", + (double)bufferSize BtoGB, elapsed, readRate BtoMB, readRate / 1000 / 1000 ); + + return 0; +} + +//----------------------------------------------------------- +int main( int argc, const char* argv[] ) +{ + // Install a crash handler to dump our stack traces + SysHost::InstallCrashHandler(); + + struct rlimit limit; + getrlimit( RLIMIT_NOFILE, &limit ); + Log::Line( "%u / %u", limit.rlim_cur, limit.rlim_max ); + + limit.rlim_cur = limit.rlim_max; + setrlimit( RLIMIT_NOFILE, &limit ); + + #if _DEBUG + Log::Line( "DEBUG: ON" ); + #else + Log::Line( "DEBUG: OFF" ); + #endif + + #if _NDEBUG + Log::Line( "NDEBUG: ON" ); + #else + Log::Line( "NDEBUG: OFF" ); + #endif + + // TestDiskBackPointers(); return 0; + // TestLookupMaps(); return 0; + + argc--; + argv++; + // return WriteTest( argc, argv ); + + DiskPlotter::Config plotCfg; + GlobalConfig gCfg; + + ParseConfig( argc, argv, gCfg, plotCfg ); + + DiskPlotter plotter( plotCfg ); + + byte* plotId = new byte[BB_PLOT_ID_LEN]; + byte* plotMemo = new byte[BB_PLOT_MEMO_MAX_SIZE]; + char* plotFileName = new char[BB_PLOT_FILE_LEN_TMP]; + uint16 plotMemoSize = 0; + + DiskPlotter::PlotRequest req; + req.plotFileName = plotFileName; + req.plotId = plotId; + req.plotMemo = plotMemo; + // #TODO: Generate plot id & memo + + + // TEST + // #TODO: Remove + { + const char refPlotId [] = "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835"; + const char refPlotMemo[] = "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef01b7bf8a22a9ac82a003e07b551c851ea683839f3e1beb8ac9ede57d2c020669"; + + memset( plotId , 0, BB_PLOT_ID_LEN ); + memset( plotMemo, 0, BB_PLOT_MEMO_MAX_SIZE ); + + HexStrToBytes( refPlotId , sizeof( refPlotId )-1, plotId , BB_PLOT_ID_LEN ); + HexStrToBytes( refPlotMemo, sizeof( refPlotMemo )-1, plotMemo, BB_PLOT_MEMO_MAX_SIZE ); + + req.plotMemoSize = 128; + } + + PlotTools::GenPlotFileName( plotId, plotFileName ); + plotter.Plot( req ); + + exit( 0 ); +} + +//----------------------------------------------------------- +void ParseConfig( int argc, const char* argv[], GlobalConfig& gConfig, DiskPlotter::Config& cfg ) +{ + #define check( a ) (strcmp( a, arg ) == 0) + int i; + const char* arg = nullptr; + + auto value = [&](){ + + FatalIf( ++i >= argc, "Expected a value for parameter '%s'", arg ); + return argv[i]; + }; + + auto ivalue = [&]() { + + const char* val = value(); + int64 v = 0; + + int r = sscanf( val, "%lld", &v ); + FatalIf( r != 1, "Invalid int64 value for argument '%s'.", arg ); + + return v; + }; + + auto uvalue = [&]() { + + const char* val = value(); + uint64 v = 0; + + int r = sscanf( val, "%llu", &v ); + FatalIf( r != 1, "Invalid uint64 value for argument '%s'.", arg ); + + return v; + }; + + + // Set defaults + const size_t f1DefaultWriteInterval = 128ull MB; + size_t fxDefaultWriteInterval = 64ull MB; + size_t matchDefaultWriteInterval = 64ull MB; + const uint minBufferCount = 3; + + // Parse fx and match per-table + auto checkFx = [&]( const char* a ) { + + const size_t minSize = sizeof( "--fx" ) - 1; + const size_t len = strlen( a ); + + if( len >= minSize && memcmp( "--fx", a, minSize ) == 0 ) + { + if( len == minSize ) + { + // Set the default value + fxDefaultWriteInterval = ParseSize( "--fx", value() ); + return true; + } + else + { + // Set the value for a table (--fx2, --fx4...) + const char intChar = a[minSize]; + + // Expect an integer from 2-7 (inclusive) to come immediately after --fx + if( intChar >= '2' && intChar <= '7' ) + { + const int tableId = (int)intChar - '0'; + cfg.writeIntervals[tableId].fxGen = ParseSize( "--fn", value() ); + + return true; + } + } + } + + return false; + }; + + auto checkMatch = [&]( const char* a ) { + + const size_t minSize = sizeof( "--match" ) - 1; + const size_t len = strlen( a ); + + if( len >= minSize && memcmp( "--match", a, minSize ) == 0 ) + { + if( len == minSize ) + { + // Set the default value + matchDefaultWriteInterval = uvalue(); + return true; + } + else + { + // Set the value for a table (--fx2, --fx4...) + const char intChar = a[minSize]; + + // Expect an integer from 2-7 (inclusive) to come immediately after --fx + if( intChar >= '2' && intChar <= '7' ) + { + const int tableId = (int)intChar - '0'; + cfg.writeIntervals[tableId].matching = uvalue(); + + return true; + } + } + } + + return false; + }; + + // Set some defaults + ZeroMem( &cfg ); + cfg.workHeapSize = BB_DP_MIN_RAM_SIZE; // #TODO: I don't think we need this anymore. + // We only need a variable size for the write intervals. + // This size will be fixed. + + cfg.ioBufferCount = minBufferCount; + + + // Start parsing + for( i = 0; i < argc; i++ ) + { + arg = argv[i]; + + if( check( "--f1" ) ) + { + cfg.writeIntervals[0].fxGen = ParseSize( arg, value() ); + } + else if( checkFx( arg ) || checkMatch( arg ) ) + { + continue; + } + else if( check( "-t" ) || check( "--threads" ) ) + { + cfg.workThreadCount = (uint)uvalue(); + } + else if( check( "-b" ) || check( "--buffer-count" ) ) + { + cfg.ioBufferCount = (uint)uvalue(); + } + // else if( check( "-d" ) || check( "--direct-io" ) ) + // { + // cfg.enableDirectIO = true; + // } + // else if( check( "--io-threads" ) ) + // { + // cfg.ioThreadCount = (uint)uvalue(); + // } + // else if( check( "-h" ) || check( "--heap" ) ) + // { + // ParseSize( arg, value() ); + // } + else if( check( "--temp" ) ) + { + cfg.tmpPath = value(); + } + else if( i == argc - 1 ) + { + cfg.tmpPath = arg; + } + else + { + Fatal( "Error: Unexpected argument '%s'.", arg ); + } + } + + + // Validate some parameters + const size_t diskBlockSize = ValidateTmpPathAndGetBlockSize( cfg ); + + const size_t minBucketSize = BB_DP_MAX_ENTRIES_PER_BUCKET * sizeof( uint32 ); + + size_t maxWriteInterval = 0; + + for( TableId table = TableId::Table1; table < TableId::_Count; table++ ) + { + auto& writeInterval = cfg.writeIntervals[(int)table]; + + if( writeInterval.fxGen == 0 ) + writeInterval.fxGen = table == TableId::Table1 ? f1DefaultWriteInterval : fxDefaultWriteInterval; + + if( writeInterval.matching == 0 ) + writeInterval.matching = matchDefaultWriteInterval; + + // Ensure the intervals are <= than the minimum write size of a bucket (table 7) + // and >= disk block size of the temporary directory. + FatalIf( writeInterval.fxGen > minBucketSize, "f%d write interval must be less or equal than %llu bytes.", (int)table+1, minBucketSize ); + FatalIf( writeInterval.matching > minBucketSize, "Table %d match write interval must be less or equal than %llu bytes.", (int)table+1, minBucketSize ); + FatalIf( writeInterval.fxGen < diskBlockSize, "f%d write interval must be greater or equal than the tmp directory block size of %llu bytes.", (int)table+1, diskBlockSize ); + FatalIf( writeInterval.matching < diskBlockSize, "Table %d match write interval must be greater or equal than the tmp directory block size of %llu bytes.", (int)table + 1, minBucketSize ); + + // Round up the size to the block size + writeInterval.fxGen = RoundUpToNextBoundaryT( writeInterval.fxGen , diskBlockSize ); + writeInterval.matching = RoundUpToNextBoundaryT( writeInterval.matching, diskBlockSize ); + + maxWriteInterval = std::max( maxWriteInterval, writeInterval.fxGen ); + maxWriteInterval = std::max( maxWriteInterval, writeInterval.matching ); + } + + cfg.ioBufferSize = maxWriteInterval; + + FatalIf( cfg.ioBufferCount < 3, "IO buffer (write interval buffers) cont must be 3 or more." ); + + + const uint sysLogicalCoreCount = SysHost::GetLogicalCPUCount(); + + if( cfg.workThreadCount == 0 ) + cfg.workThreadCount = sysLogicalCoreCount; + else if( cfg.workThreadCount > sysLogicalCoreCount ) + { + Log::Line( "Warning: Limiting work threads to %u, which is the system's logical CPU count.", sysLogicalCoreCount ); + cfg.workThreadCount = sysLogicalCoreCount; + } + + if( cfg.ioThreadCount == 0 ) + cfg.ioThreadCount = 1; // #TODO: figure out a reasonable default. Probably 1 or 2 for current consumer NVMes running on PCIe3... + else if( cfg.ioThreadCount > sysLogicalCoreCount ) + { + Log::Line( "Warning: Limiting disk queue threads to %u, which is the system's logical CPU count.", sysLogicalCoreCount ); + cfg.ioThreadCount = sysLogicalCoreCount; + } +} + +//----------------------------------------------------------- +size_t ParseSize( const char* arg, const char* sizeText ) +{ + const size_t len = strlen( sizeText ); + const char* end = sizeText + len; + + const char* suffix = sizeText; + +#ifdef _WIN32 + #define StriCmp _stricmp +#else + #define StriCmp strcasecmp +#endif + + // Try to find a suffix: + // Find the first character that's not a digit + do + { + const char c = *suffix; + if( c < '0' || c > '9' ) + break; + } + while( ++suffix < end ); + + // Apply multiplier depending on the suffix + size_t multiplier = 1; + + const size_t suffixLength = end - suffix; + if( suffixLength > 0 ) + { + if( StriCmp( "GB", suffix ) == 0 || StriCmp( "G", suffix ) == 0 ) + multiplier = 1ull GB; + else if( StriCmp( "MB", suffix ) == 0 || StriCmp( "M", suffix ) == 0 ) + multiplier = 1ull MB; + else if( StriCmp( "KB", suffix ) == 0 || StriCmp( "K", suffix ) == 0 ) + multiplier = 1ull KB; + else + Fatal( "Invalid suffix '%s' for argument '%s'", suffix, arg ); + } + + const size_t MAX_DIGITS = 19; + char digits[MAX_DIGITS + 1]; + + const size_t digitsLength = suffix - sizeText; + FatalIf( digitsLength < 1 || digitsLength > MAX_DIGITS, "Invalid parameters value for argument '%s'.", arg ); + + // Read digits + size_t size = 0; + + memcpy( digits, sizeText, digitsLength ); + digits[digitsLength] = 0; + + FatalIf( sscanf( digits, "%llu", &size ) != 1, + "Invalid parameters value for argument '%s'.", arg ); + + const size_t resolvedSize = size * multiplier; + + // Check for overflow + FatalIf( resolvedSize < size, "Size overflowed for argument '%s'.", arg );; + + return resolvedSize; +} + +//----------------------------------------------------------- +size_t ValidateTmpPathAndGetBlockSize( DiskPlotter::Config& cfg ) +{ + FatalIf( cfg.tmpPath == nullptr, "No temporary path specified." ); + + size_t pathLen = strlen( cfg.tmpPath ); + FatalIf( pathLen < 1, "Invalid temporary path." ); + + char* tmpPath = bbmalloc( pathLen + 2 ); + memcpy( tmpPath, cfg.tmpPath, pathLen ); + + if( cfg.tmpPath[pathLen - 1] != '/' + #ifdef _WIN32 + && cfg.tmpPath[pathLen - 1] != '\\' + #endif + ) + { + tmpPath[pathLen++] = '/'; + } + + tmpPath[pathLen] = (char)0; + cfg.tmpPath = tmpPath; + + // Open a file in the temp dir to obtain the block size + uint64 randNum = 0; + SysHost::Random( (byte*)&randNum, sizeof( randNum ) ); + + char* randFileName = bbmalloc( pathLen + 32 ); + + int r = snprintf( randFileName, pathLen + 32, "%s.%llx.blk", tmpPath, randNum ); + FatalIf( r < 1, "Unexpected error validating temp directory." ); + + FileStream tmpFile; + + if( !tmpFile.Open( randFileName, FileMode::Create, FileAccess::ReadWrite ) ) + { + int err = tmpFile.GetError(); + Fatal( "Failed to open a file in the temp directory with error %d (0x%x).", err, err ); + } + + + cfg.expectedTmpDirBlockSize = tmpFile.BlockSize(); + + remove( randFileName ); + free( randFileName ); + + return cfg.expectedTmpDirBlockSize; +} + diff --git a/src/plotdisk/transforms/FxTransform.h b/src/plotdisk/transforms/FxTransform.h new file mode 100644 index 00000000..177cb530 --- /dev/null +++ b/src/plotdisk/transforms/FxTransform.h @@ -0,0 +1,38 @@ +#include "plotdisk/IOTransforms.h" +#include "util/BitView.h" + +// class FxTransform : public IIOTransform +// { +// public: +// //----------------------------------------------------------- +// inline void ReadTransform( TransformData& data ) override +// { +// // uint32* +// uint32* y; +// uint64* meta; +// } + +// //----------------------------------------------------------- +// inline void WriteTransform( TransformData& data ) override +// { + +// } + +// private: + +// //----------------------------------------------------------- +// template +// inline void PackFx( void* outBuffer, size_t outBufferSize, +// const uint32* y, const TMeta* meta, const TAddress* key, +// const int64 entryCount, const uint32 k, const uint32 keyBits, const uint32 metaBits ) +// { +// BitWriter writer( (uint64*)outBuffer, outBufferSize * 8 ); + +// for( int64 i = 0; i < entryCount; i++ ) +// { +// writer.Write( y [i], k ); +// writer.Write( key [i], keyBits ); +// writer.Write( meta[i], metaBits ); +// } +// } +// }; diff --git a/src/memplot/DbgHelper.cpp b/src/plotmem/DbgHelper.cpp similarity index 98% rename from src/memplot/DbgHelper.cpp rename to src/plotmem/DbgHelper.cpp index cb86d53a..0e29fef9 100644 --- a/src/memplot/DbgHelper.cpp +++ b/src/plotmem/DbgHelper.cpp @@ -106,7 +106,7 @@ void PrintHash( FILE* file, uint64 index, const void* input, size_t inputSize ) blake3_hasher_update( &hasher, input, inputSize ); blake3_hasher_finalize( &hasher, (uint8_t*)hash, sizeof( hash ) ); - fprintf( file, "[%-12llu] 0x", index ); + fprintf( file, "[%-12llu] 0x", (llu)index ); for( uint64 i = 0; i < sizeof( hash ); i+=16 ) { fprintf( file, diff --git a/src/memplot/DbgHelper.h b/src/plotmem/DbgHelper.h similarity index 96% rename from src/memplot/DbgHelper.h rename to src/plotmem/DbgHelper.h index 230fdbcd..67955977 100644 --- a/src/memplot/DbgHelper.h +++ b/src/plotmem/DbgHelper.h @@ -455,3 +455,25 @@ inline bool DbgVerifySorted( const uint64 entryCount, const T* entries ) } +//----------------------------------------------------------- +template +inline bool DbgVerifyGreater( const uint64 entryCount, const T* entries ) +{ + ASSERT( entryCount ); + + T last = entries[0]; + for( uint64 i = 1; i < entryCount; i++ ) + { + const T e = entries[i]; + + if( last > e ) + { + ASSERT(0); + return false; + } + last = e; + } + + return true; +} + diff --git a/src/memplot/FxSort.h b/src/plotmem/FxSort.h similarity index 100% rename from src/memplot/FxSort.h rename to src/plotmem/FxSort.h diff --git a/src/memplot/LPGen.h b/src/plotmem/LPGen.h similarity index 75% rename from src/memplot/LPGen.h rename to src/plotmem/LPGen.h index 3238358b..9e1e9bb9 100644 --- a/src/memplot/LPGen.h +++ b/src/plotmem/LPGen.h @@ -33,6 +33,11 @@ struct LPJob : public SyncedJob uint32* map; }; +struct BackPtr +{ + uint64 x, y; +}; + template void ProcessTableThread( LPJob* job ); @@ -43,7 +48,10 @@ void WriteLookupTableThread( LPJob* job ); // Calculates x * (x-1) / 2. Division is done before multiplication. inline uint64 GetXEnc( uint64 x ); inline uint64 SquareToLinePoint( uint64 x, uint64 y ); +inline uint128 GetXEnc128( uint64 x ); +inline BackPtr LinePointToSquare( uint128 index ); +inline BackPtr LinePointToSquare64( uint64 index ); #pragma GCC diagnostic push @@ -53,6 +61,7 @@ inline uint64 SquareToLinePoint( uint64 x, uint64 y ); //----------------------------------------------------------- FORCE_INLINE uint64 GetXEnc( uint64 x ) { + ASSERT( x ); uint64 a = x, b = x - 1; // if( a % 2 == 0 ) @@ -67,6 +76,24 @@ FORCE_INLINE uint64 GetXEnc( uint64 x ) return r; } +//----------------------------------------------------------- +FORCE_INLINE uint128 GetXEnc128( uint64 x ) +{ + ASSERT( x ); + uint64 a = x, b = x - 1; + + // if( a % 2 == 0 ) + if( (a & 1) == 0 ) + a >>= 1; // a /= 2; + else + b >>= 1; // b /= 2; + + const uint128 r = (uint128)a * b; + ASSERT( r >= a && r >= b ); + + return r; +} + /// #NOTE: From chiapos: // Encodes two max k bit values into one max 2k bit value. This can be thought of // mapping points in a two dimensional space into a one dimensional space. The benefits @@ -84,6 +111,37 @@ FORCE_INLINE uint64 SquareToLinePoint( uint64 x, uint64 y ) return GetXEnc( x ) + y; } + +FORCE_INLINE BackPtr LinePointToSquare( uint128 index ) +{ + // Performs a square root, without the use of doubles, + // to use the precision of the uint128_t. + uint64 x = 0; + for( int i = 63; i >= 0; i-- ) + { + uint64 new_x = x + ((uint64)1 << i); + if( GetXEnc128( new_x ) <= index ) + x = new_x; + } + + return { x, (uint64)(uint64_t)( index - GetXEnc128( x ) ) }; +} + +FORCE_INLINE BackPtr LinePointToSquare64( uint64 index ) +{ + // Performs a square root, without the use of doubles, + // to use the precision of the uint128_t. + uint64 x = 0; + for( int i = 63; i >= 0; i-- ) + { + uint64 new_x = x + ((uint64)1 << i); + if( GetXEnc( new_x ) <= index ) + x = new_x; + } + + return { x, ( index - GetXEnc( x ) ) }; +} + #pragma GCC diagnostic pop diff --git a/src/memplot/MemPhase1.cpp b/src/plotmem/MemPhase1.cpp similarity index 99% rename from src/memplot/MemPhase1.cpp rename to src/plotmem/MemPhase1.cpp index b2686b66..36ec940a 100644 --- a/src/memplot/MemPhase1.cpp +++ b/src/plotmem/MemPhase1.cpp @@ -1,7 +1,7 @@ #include "MemPhase1.h" #include "b3/blake3.h" #include "pos/chacha8.h" -#include "Util.h" +#include "util/Util.h" #include "util/Log.h" #include "FxSort.h" #include "algorithm/YSort.h" diff --git a/src/memplot/MemPhase1.h b/src/plotmem/MemPhase1.h similarity index 51% rename from src/memplot/MemPhase1.h rename to src/plotmem/MemPhase1.h index 57f10d02..40134e28 100644 --- a/src/memplot/MemPhase1.h +++ b/src/plotmem/MemPhase1.h @@ -1,6 +1,7 @@ #pragma once #include "PlotContext.h" + struct kBCJob; template @@ -25,36 +26,6 @@ struct ReadWriteBuffer }; -/// -/// Helpers for working with metadata -/// -struct Meta3 { uint64 m0, m1; }; // Used for when the metadata multiplier == 3 -struct Meta4 : Meta3 {}; // Used for when the metadata multiplier == 4 -struct NoMeta {}; // Used for when the metadata multiplier == 0 - -template -struct SizeForMeta; - -template<> struct SizeForMeta { static constexpr size_t Value = 1; }; -template<> struct SizeForMeta { static constexpr size_t Value = 2; }; -template<> struct SizeForMeta { static constexpr size_t Value = 3; }; -template<> struct SizeForMeta { static constexpr size_t Value = 4; }; -template<> struct SizeForMeta { static constexpr size_t Value = 0; }; - -template -struct TableMetaType; - -template<> struct TableMetaType { using MetaIn = uint32; using MetaOut = uint64; }; -template<> struct TableMetaType { using MetaIn = uint64; using MetaOut = Meta4; }; -template<> struct TableMetaType { using MetaIn = Meta4; using MetaOut = Meta4; }; -template<> struct TableMetaType { using MetaIn = Meta4; using MetaOut = Meta3; }; -template<> struct TableMetaType { using MetaIn = Meta3; using MetaOut = uint64; }; -template<> struct TableMetaType { using MetaIn = uint64; using MetaOut = NoMeta; }; - - -/// Helper for obtaining the correct fx (y) output type per table -template struct YOut { using Type = uint64; }; -template<> struct YOut { using Type = uint32; }; diff --git a/src/memplot/MemPhase2.cpp b/src/plotmem/MemPhase2.cpp similarity index 100% rename from src/memplot/MemPhase2.cpp rename to src/plotmem/MemPhase2.cpp diff --git a/src/memplot/MemPhase2.h b/src/plotmem/MemPhase2.h similarity index 100% rename from src/memplot/MemPhase2.h rename to src/plotmem/MemPhase2.h diff --git a/src/memplot/MemPhase3.cpp b/src/plotmem/MemPhase3.cpp similarity index 99% rename from src/memplot/MemPhase3.cpp rename to src/plotmem/MemPhase3.cpp index 3f247ab2..bc7cf634 100644 --- a/src/memplot/MemPhase3.cpp +++ b/src/plotmem/MemPhase3.cpp @@ -1,5 +1,5 @@ #include "MemPhase3.h" -#include "Util.h" +#include "util/Util.h" #include "util/Log.h" #include "algorithm/RadixSort.h" #include "LPGen.h" @@ -254,7 +254,7 @@ void PruneAndMapThread( LPJob* job ) // Scan entries { uint64 newLength = 0; - + for( uint64 i = srcOffset; i < end; i++ ) { if( markedEntries[i] ) @@ -272,7 +272,7 @@ void PruneAndMapThread( LPJob* job ) /// /// Prune to new buffer /// - + // Get our new offset uint64 dstOffset = 0; diff --git a/src/memplot/MemPhase3.h b/src/plotmem/MemPhase3.h similarity index 100% rename from src/memplot/MemPhase3.h rename to src/plotmem/MemPhase3.h diff --git a/src/memplot/MemPhase4.cpp b/src/plotmem/MemPhase4.cpp similarity index 99% rename from src/memplot/MemPhase4.cpp rename to src/plotmem/MemPhase4.cpp index 901a5edd..a0e076c3 100644 --- a/src/memplot/MemPhase4.cpp +++ b/src/plotmem/MemPhase4.cpp @@ -1,5 +1,5 @@ #include "MemPhase4.h" -#include "CTables.h" +#include "plotting/CTables.h" #include "util/Log.h" //----------------------------------------------------------- diff --git a/src/memplot/MemPhase4.h b/src/plotmem/MemPhase4.h similarity index 98% rename from src/memplot/MemPhase4.h rename to src/plotmem/MemPhase4.h index f547c144..65ce2c27 100644 --- a/src/memplot/MemPhase4.h +++ b/src/plotmem/MemPhase4.h @@ -1,6 +1,6 @@ #pragma once #include "PlotContext.h" -#include "CTables.h" +#include "plotting/CTables.h" class MemPhase4 { @@ -435,10 +435,10 @@ inline void WriteC3Park( const uint64 length, uint32* f7Entries, byte* parkBuffe // Store size in the first 2 bytes *((uint16*)parkBuffer) = Swap16( (uint16)compressedSize ); - // Zero-out remainder (not necessarry, though...) + // Zero-out remainder (not necessary, though...) const size_t remainder = c3Size - (compressedSize + 2); if( remainder ) - memset( deltaWriter + compressedSize + 2, 0, remainder ); + memset( parkBuffer + compressedSize + 2, 0, remainder ); } diff --git a/src/memplot/MemPlotter.cpp b/src/plotmem/MemPlotter.cpp similarity index 99% rename from src/memplot/MemPlotter.cpp rename to src/plotmem/MemPlotter.cpp index 25b80907..0d64b3fd 100644 --- a/src/memplot/MemPlotter.cpp +++ b/src/plotmem/MemPlotter.cpp @@ -1,6 +1,6 @@ #include "MemPlotter.h" #include "threading/ThreadPool.h" -#include "Util.h" +#include "util/Util.h" #include "util/Log.h" #include "SysHost.h" @@ -270,7 +270,7 @@ void MemPlotter::WaitPlotWriter() for( uint i = 7; i < 10; i++ ) { const uint64 ptr = Swap64( tablePointers[i] ); - Log::Line( " C%u table pointer : %16lu ( 0x%016lx )", i+1-7, ptr, ptr); + Log::Line( " C%u table pointer : %16lu ( 0x%016lx )", i+1-7, ptr, ptr ); } Log::Line( "" ); // } diff --git a/src/memplot/MemPlotter.h b/src/plotmem/MemPlotter.h similarity index 100% rename from src/memplot/MemPlotter.h rename to src/plotmem/MemPlotter.h diff --git a/src/memplot/ParkWriter.h b/src/plotmem/ParkWriter.h similarity index 99% rename from src/memplot/ParkWriter.h rename to src/plotmem/ParkWriter.h index 8cf4d2c0..cb56261a 100644 --- a/src/memplot/ParkWriter.h +++ b/src/plotmem/ParkWriter.h @@ -1,5 +1,5 @@ #pragma once -#include "memplot/CTables.h" +#include "plotting/CTables.h" #include "ChiaConsts.h" #include "threading/ThreadPool.h" @@ -31,7 +31,7 @@ inline size_t WriteParks( ThreadPool& pool, const uint64 length, uint64* linePoi const size_t parkSize = CalculateParkSize( tableId ); const uint64 parkCount = length / kEntriesPerPark; const uint64 parksPerThread = parkCount / threadCount; - + uint64 trailingParks = parkCount - ( parksPerThread * threadCount ); ASSERT( trailingParks < threadCount ); @@ -40,7 +40,7 @@ inline size_t WriteParks( ThreadPool& pool, const uint64 length, uint64* linePoi ASSERT( trailingEntries <= kEntriesPerPark ); WriteParkJob jobs[MaxJobs]; - + uint64* threadLinePoints = linePoints; byte* threadParkBuffer = parkBuffer; @@ -71,8 +71,8 @@ inline size_t WriteParks( ThreadPool& pool, const uint64 length, uint64* linePoi // Write trailing entries if any if( trailingEntries ) WritePark( parkSize, trailingEntries, threadLinePoints, threadParkBuffer, tableId ); - - + + const size_t sizeWritten = parkSize * ( parkCount + (trailingEntries ? 1 : 0) ); return sizeWritten; diff --git a/src/memplot/CTables.h b/src/plotting/CTables.h similarity index 100% rename from src/memplot/CTables.h rename to src/plotting/CTables.h diff --git a/src/plotting/DTables.h b/src/plotting/DTables.h new file mode 100644 index 00000000..1420372c --- /dev/null +++ b/src/plotting/DTables.h @@ -0,0 +1,14376 @@ +#pragma once +#include "fse/fse.h" + +const byte DTable_0[65540] = { + 0x0e, 0x00, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x10, 0x1e, 0x00, 0x04, 0x20, 0x1e, 0x00, 0x04, 0xd8, 0x17, 0x01, 0x03, 0xe0, 0x17, 0x01, 0x03, 0xe8, 0x17, 0x01, 0x03, 0xf0, 0x17, 0x01, 0x03, + 0x08, 0x07, 0x02, 0x03, 0x10, 0x07, 0x02, 0x03, 0x18, 0x07, 0x02, 0x03, 0xd0, 0x32, 0x03, 0x04, 0xe0, 0x32, 0x03, 0x04, 0xf0, 0x32, 0x03, 0x04, 0xd0, 0x1c, 0x04, 0x04, 0xe0, 0x1c, 0x04, 0x04, + 0x00, 0x0b, 0x05, 0x04, 0x10, 0x0b, 0x05, 0x04, 0x40, 0x39, 0x06, 0x05, 0x00, 0x22, 0x07, 0x05, 0x20, 0x22, 0x07, 0x05, 0x40, 0x0f, 0x08, 0x05, 0x80, 0x27, 0x0a, 0x06, 0xc0, 0x03, 0x0c, 0x06, + 0x80, 0x07, 0x0f, 0x07, 0x30, 0x1e, 0x00, 0x04, 0x40, 0x1e, 0x00, 0x04, 0x50, 0x1e, 0x00, 0x04, 0xf8, 0x17, 0x01, 0x03, 0x00, 0x18, 0x01, 0x03, 0x08, 0x18, 0x01, 0x03, 0x10, 0x18, 0x01, 0x03, + 0x20, 0x07, 0x02, 0x03, 0x28, 0x07, 0x02, 0x03, 0x30, 0x07, 0x02, 0x03, 0x00, 0x33, 0x03, 0x04, 0x10, 0x33, 0x03, 0x04, 0x20, 0x33, 0x03, 0x04, 0xf0, 0x1c, 0x04, 0x04, 0x00, 0x1d, 0x04, 0x04, + 0x20, 0x0b, 0x05, 0x04, 0x30, 0x0b, 0x05, 0x04, 0x60, 0x39, 0x06, 0x05, 0x40, 0x22, 0x07, 0x05, 0x60, 0x22, 0x07, 0x05, 0x60, 0x0f, 0x08, 0x05, 0xc0, 0x27, 0x0a, 0x06, 0x00, 0x04, 0x0c, 0x06, + 0x00, 0x08, 0x0f, 0x07, 0x60, 0x1e, 0x00, 0x04, 0x70, 0x1e, 0x00, 0x04, 0x80, 0x1e, 0x00, 0x04, 0x18, 0x18, 0x01, 0x03, 0x20, 0x18, 0x01, 0x03, 0x28, 0x18, 0x01, 0x03, 0x30, 0x18, 0x01, 0x03, + 0x38, 0x07, 0x02, 0x03, 0x40, 0x07, 0x02, 0x03, 0x48, 0x07, 0x02, 0x03, 0x30, 0x33, 0x03, 0x04, 0x40, 0x33, 0x03, 0x04, 0x50, 0x33, 0x03, 0x04, 0x10, 0x1d, 0x04, 0x04, 0x20, 0x1d, 0x04, 0x04, + 0x40, 0x0b, 0x05, 0x04, 0x50, 0x0b, 0x05, 0x04, 0x80, 0x39, 0x06, 0x05, 0x80, 0x22, 0x07, 0x05, 0xa0, 0x22, 0x07, 0x05, 0x80, 0x0f, 0x08, 0x05, 0x00, 0x28, 0x0a, 0x06, 0x40, 0x04, 0x0c, 0x06, + 0x80, 0x08, 0x0f, 0x07, 0x90, 0x1e, 0x00, 0x04, 0xa0, 0x1e, 0x00, 0x04, 0xb0, 0x1e, 0x00, 0x04, 0x38, 0x18, 0x01, 0x03, 0x40, 0x18, 0x01, 0x03, 0x48, 0x18, 0x01, 0x03, 0x50, 0x18, 0x01, 0x03, + 0x50, 0x07, 0x02, 0x03, 0x58, 0x07, 0x02, 0x03, 0x60, 0x07, 0x02, 0x03, 0x60, 0x33, 0x03, 0x04, 0x70, 0x33, 0x03, 0x04, 0x80, 0x33, 0x03, 0x04, 0x30, 0x1d, 0x04, 0x04, 0x40, 0x1d, 0x04, 0x04, + 0x60, 0x0b, 0x05, 0x04, 0x70, 0x0b, 0x05, 0x04, 0xa0, 0x39, 0x06, 0x05, 0xc0, 0x22, 0x07, 0x05, 0xe0, 0x22, 0x07, 0x05, 0x00, 0x00, 0x09, 0x05, 0x40, 0x28, 0x0a, 0x06, 0x80, 0x04, 0x0c, 0x06, + 0x00, 0x09, 0x0f, 0x07, 0xc0, 0x1e, 0x00, 0x04, 0xd0, 0x1e, 0x00, 0x04, 0xe0, 0x1e, 0x00, 0x04, 0x58, 0x18, 0x01, 0x03, 0x60, 0x18, 0x01, 0x03, 0x68, 0x18, 0x01, 0x03, 0x70, 0x18, 0x01, 0x03, + 0x68, 0x07, 0x02, 0x03, 0x70, 0x07, 0x02, 0x03, 0x78, 0x07, 0x02, 0x03, 0x90, 0x33, 0x03, 0x04, 0xa0, 0x33, 0x03, 0x04, 0xb0, 0x33, 0x03, 0x04, 0x50, 0x1d, 0x04, 0x04, 0x60, 0x1d, 0x04, 0x04, + 0x80, 0x0b, 0x05, 0x04, 0x90, 0x0b, 0x05, 0x04, 0xc0, 0x39, 0x06, 0x05, 0x00, 0x23, 0x07, 0x05, 0x20, 0x23, 0x07, 0x05, 0x20, 0x00, 0x09, 0x05, 0x80, 0x28, 0x0a, 0x06, 0xc0, 0x04, 0x0c, 0x06, + 0x80, 0x09, 0x0f, 0x07, 0xf0, 0x1e, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x10, 0x1f, 0x00, 0x04, 0x78, 0x18, 0x01, 0x03, 0x80, 0x18, 0x01, 0x03, 0x88, 0x18, 0x01, 0x03, 0x90, 0x18, 0x01, 0x03, + 0x80, 0x07, 0x02, 0x03, 0x88, 0x07, 0x02, 0x03, 0x90, 0x07, 0x02, 0x03, 0xc0, 0x33, 0x03, 0x04, 0xd0, 0x33, 0x03, 0x04, 0xe0, 0x33, 0x03, 0x04, 0x70, 0x1d, 0x04, 0x04, 0x80, 0x1d, 0x04, 0x04, + 0xa0, 0x0b, 0x05, 0x04, 0xb0, 0x0b, 0x05, 0x04, 0xe0, 0x39, 0x06, 0x05, 0x40, 0x23, 0x07, 0x05, 0x60, 0x23, 0x07, 0x05, 0x40, 0x00, 0x09, 0x05, 0xc0, 0x28, 0x0a, 0x06, 0x00, 0x05, 0x0c, 0x06, + 0x00, 0x0a, 0x0f, 0x07, 0x20, 0x1f, 0x00, 0x04, 0x30, 0x1f, 0x00, 0x04, 0x40, 0x1f, 0x00, 0x04, 0x98, 0x18, 0x01, 0x03, 0xa0, 0x18, 0x01, 0x03, 0xa8, 0x18, 0x01, 0x03, 0xb0, 0x18, 0x01, 0x03, + 0x98, 0x07, 0x02, 0x03, 0xa0, 0x07, 0x02, 0x03, 0xa8, 0x07, 0x02, 0x03, 0xf0, 0x33, 0x03, 0x04, 0x00, 0x34, 0x03, 0x04, 0x10, 0x34, 0x03, 0x04, 0x90, 0x1d, 0x04, 0x04, 0xa0, 0x1d, 0x04, 0x04, + 0xc0, 0x0b, 0x05, 0x04, 0xd0, 0x0b, 0x05, 0x04, 0x00, 0x3a, 0x06, 0x05, 0x80, 0x23, 0x07, 0x05, 0xa0, 0x23, 0x07, 0x05, 0x60, 0x00, 0x09, 0x05, 0x00, 0x29, 0x0a, 0x06, 0x40, 0x05, 0x0c, 0x06, + 0x80, 0x0a, 0x0f, 0x07, 0x50, 0x1f, 0x00, 0x04, 0x60, 0x1f, 0x00, 0x04, 0x70, 0x1f, 0x00, 0x04, 0xb8, 0x18, 0x01, 0x03, 0xc0, 0x18, 0x01, 0x03, 0xc8, 0x18, 0x01, 0x03, 0xd0, 0x18, 0x01, 0x03, + 0xb0, 0x07, 0x02, 0x03, 0xb8, 0x07, 0x02, 0x03, 0xc0, 0x07, 0x02, 0x03, 0x20, 0x34, 0x03, 0x04, 0x30, 0x34, 0x03, 0x04, 0x40, 0x34, 0x03, 0x04, 0xb0, 0x1d, 0x04, 0x04, 0xc0, 0x1d, 0x04, 0x04, + 0xe0, 0x0b, 0x05, 0x04, 0xf0, 0x0b, 0x05, 0x04, 0x20, 0x3a, 0x06, 0x05, 0xc0, 0x23, 0x07, 0x05, 0xe0, 0x23, 0x07, 0x05, 0x80, 0x00, 0x09, 0x05, 0x40, 0x29, 0x0a, 0x06, 0x80, 0x05, 0x0c, 0x06, + 0x00, 0x0b, 0x0f, 0x07, 0x80, 0x1f, 0x00, 0x04, 0x90, 0x1f, 0x00, 0x04, 0xa0, 0x1f, 0x00, 0x04, 0xd8, 0x18, 0x01, 0x03, 0xe0, 0x18, 0x01, 0x03, 0xe8, 0x18, 0x01, 0x03, 0xf0, 0x18, 0x01, 0x03, + 0xc8, 0x07, 0x02, 0x03, 0xd0, 0x07, 0x02, 0x03, 0xd8, 0x07, 0x02, 0x03, 0x50, 0x34, 0x03, 0x04, 0x60, 0x34, 0x03, 0x04, 0x70, 0x34, 0x03, 0x04, 0xd0, 0x1d, 0x04, 0x04, 0xe0, 0x1d, 0x04, 0x04, + 0x00, 0x0c, 0x05, 0x04, 0x10, 0x0c, 0x05, 0x04, 0x40, 0x3a, 0x06, 0x05, 0x00, 0x24, 0x07, 0x05, 0xa0, 0x0f, 0x08, 0x05, 0xa0, 0x00, 0x09, 0x05, 0x80, 0x29, 0x0a, 0x06, 0xc0, 0x05, 0x0c, 0x06, + 0x80, 0x0b, 0x0f, 0x07, 0xb0, 0x1f, 0x00, 0x04, 0xc0, 0x1f, 0x00, 0x04, 0xd0, 0x1f, 0x00, 0x04, 0xf8, 0x18, 0x01, 0x03, 0x00, 0x19, 0x01, 0x03, 0x08, 0x19, 0x01, 0x03, 0x10, 0x19, 0x01, 0x03, + 0xe0, 0x07, 0x02, 0x03, 0xe8, 0x07, 0x02, 0x03, 0xf0, 0x07, 0x02, 0x03, 0x80, 0x34, 0x03, 0x04, 0x90, 0x34, 0x03, 0x04, 0xa0, 0x34, 0x03, 0x04, 0xf0, 0x1d, 0x04, 0x04, 0x00, 0x1e, 0x04, 0x04, + 0x20, 0x0c, 0x05, 0x04, 0x30, 0x0c, 0x05, 0x04, 0x60, 0x3a, 0x06, 0x05, 0x20, 0x24, 0x07, 0x05, 0xc0, 0x0f, 0x08, 0x05, 0xc0, 0x00, 0x09, 0x05, 0xc0, 0x29, 0x0a, 0x06, 0x00, 0x06, 0x0c, 0x06, + 0x00, 0x34, 0x10, 0x08, 0xe0, 0x1f, 0x00, 0x04, 0xf0, 0x1f, 0x00, 0x04, 0x00, 0x20, 0x00, 0x04, 0x18, 0x19, 0x01, 0x03, 0x20, 0x19, 0x01, 0x03, 0x28, 0x19, 0x01, 0x03, 0x30, 0x19, 0x01, 0x03, + 0xf8, 0x07, 0x02, 0x03, 0x00, 0x08, 0x02, 0x03, 0x08, 0x08, 0x02, 0x03, 0xb0, 0x34, 0x03, 0x04, 0xc0, 0x34, 0x03, 0x04, 0xd0, 0x34, 0x03, 0x04, 0x10, 0x1e, 0x04, 0x04, 0x20, 0x1e, 0x04, 0x04, + 0x40, 0x0c, 0x05, 0x04, 0x50, 0x0c, 0x05, 0x04, 0x80, 0x3a, 0x06, 0x05, 0x40, 0x24, 0x07, 0x05, 0xe0, 0x0f, 0x08, 0x05, 0xe0, 0x00, 0x09, 0x05, 0x00, 0x2a, 0x0a, 0x06, 0x40, 0x06, 0x0c, 0x06, + 0x00, 0x35, 0x10, 0x08, 0x10, 0x20, 0x00, 0x04, 0x20, 0x20, 0x00, 0x04, 0x30, 0x20, 0x00, 0x04, 0x38, 0x19, 0x01, 0x03, 0x40, 0x19, 0x01, 0x03, 0x48, 0x19, 0x01, 0x03, 0x50, 0x19, 0x01, 0x03, + 0x10, 0x08, 0x02, 0x03, 0x18, 0x08, 0x02, 0x03, 0x20, 0x08, 0x02, 0x03, 0xe0, 0x34, 0x03, 0x04, 0xf0, 0x34, 0x03, 0x04, 0x00, 0x35, 0x03, 0x04, 0x30, 0x1e, 0x04, 0x04, 0x40, 0x1e, 0x04, 0x04, + 0x60, 0x0c, 0x05, 0x04, 0x70, 0x0c, 0x05, 0x04, 0xa0, 0x3a, 0x06, 0x05, 0x60, 0x24, 0x07, 0x05, 0x00, 0x10, 0x08, 0x05, 0x00, 0x01, 0x09, 0x05, 0x40, 0x2a, 0x0a, 0x06, 0x80, 0x06, 0x0c, 0x06, + 0x00, 0x36, 0x10, 0x08, 0x40, 0x20, 0x00, 0x04, 0x50, 0x20, 0x00, 0x04, 0x60, 0x20, 0x00, 0x04, 0x58, 0x19, 0x01, 0x03, 0x60, 0x19, 0x01, 0x03, 0x68, 0x19, 0x01, 0x03, 0x70, 0x19, 0x01, 0x03, + 0x28, 0x08, 0x02, 0x03, 0x30, 0x08, 0x02, 0x03, 0x38, 0x08, 0x02, 0x03, 0x10, 0x35, 0x03, 0x04, 0x20, 0x35, 0x03, 0x04, 0x30, 0x35, 0x03, 0x04, 0x50, 0x1e, 0x04, 0x04, 0x60, 0x1e, 0x04, 0x04, + 0x80, 0x0c, 0x05, 0x04, 0x90, 0x0c, 0x05, 0x04, 0xc0, 0x3a, 0x06, 0x05, 0x80, 0x24, 0x07, 0x05, 0x20, 0x10, 0x08, 0x05, 0x20, 0x01, 0x09, 0x05, 0x80, 0x2a, 0x0a, 0x06, 0xc0, 0x06, 0x0c, 0x06, + 0x00, 0x37, 0x10, 0x08, 0x70, 0x20, 0x00, 0x04, 0x80, 0x20, 0x00, 0x04, 0x90, 0x20, 0x00, 0x04, 0x78, 0x19, 0x01, 0x03, 0x80, 0x19, 0x01, 0x03, 0x88, 0x19, 0x01, 0x03, 0x90, 0x19, 0x01, 0x03, + 0x40, 0x08, 0x02, 0x03, 0x48, 0x08, 0x02, 0x03, 0x50, 0x08, 0x02, 0x03, 0x40, 0x35, 0x03, 0x04, 0x50, 0x35, 0x03, 0x04, 0x60, 0x35, 0x03, 0x04, 0x70, 0x1e, 0x04, 0x04, 0x80, 0x1e, 0x04, 0x04, + 0xa0, 0x0c, 0x05, 0x04, 0xb0, 0x0c, 0x05, 0x04, 0xe0, 0x3a, 0x06, 0x05, 0xa0, 0x24, 0x07, 0x05, 0x40, 0x10, 0x08, 0x05, 0x40, 0x01, 0x09, 0x05, 0xc0, 0x2a, 0x0a, 0x06, 0x00, 0x07, 0x0c, 0x06, + 0x00, 0x38, 0x10, 0x08, 0xa0, 0x20, 0x00, 0x04, 0xb0, 0x20, 0x00, 0x04, 0xc0, 0x20, 0x00, 0x04, 0x98, 0x19, 0x01, 0x03, 0xa0, 0x19, 0x01, 0x03, 0xa8, 0x19, 0x01, 0x03, 0xb0, 0x19, 0x01, 0x03, + 0x58, 0x08, 0x02, 0x03, 0x60, 0x08, 0x02, 0x03, 0x68, 0x08, 0x02, 0x03, 0x70, 0x35, 0x03, 0x04, 0x80, 0x35, 0x03, 0x04, 0x90, 0x35, 0x03, 0x04, 0x90, 0x1e, 0x04, 0x04, 0xa0, 0x1e, 0x04, 0x04, + 0xc0, 0x0c, 0x05, 0x04, 0xd0, 0x0c, 0x05, 0x04, 0x00, 0x3b, 0x06, 0x05, 0xc0, 0x24, 0x07, 0x05, 0x60, 0x10, 0x08, 0x05, 0x60, 0x01, 0x09, 0x05, 0x00, 0x2b, 0x0a, 0x06, 0x40, 0x07, 0x0c, 0x06, + 0x00, 0x39, 0x10, 0x08, 0xd0, 0x20, 0x00, 0x04, 0xe0, 0x20, 0x00, 0x04, 0xf0, 0x20, 0x00, 0x04, 0xb8, 0x19, 0x01, 0x03, 0xc0, 0x19, 0x01, 0x03, 0xc8, 0x19, 0x01, 0x03, 0xd0, 0x19, 0x01, 0x03, + 0x70, 0x08, 0x02, 0x03, 0x78, 0x08, 0x02, 0x03, 0x80, 0x08, 0x02, 0x03, 0xa0, 0x35, 0x03, 0x04, 0xb0, 0x35, 0x03, 0x04, 0xc0, 0x35, 0x03, 0x04, 0xb0, 0x1e, 0x04, 0x04, 0xc0, 0x1e, 0x04, 0x04, + 0xe0, 0x0c, 0x05, 0x04, 0xf0, 0x0c, 0x05, 0x04, 0x20, 0x3b, 0x06, 0x05, 0xe0, 0x24, 0x07, 0x05, 0x80, 0x10, 0x08, 0x05, 0x80, 0x01, 0x09, 0x05, 0x40, 0x2b, 0x0a, 0x06, 0x80, 0x07, 0x0c, 0x06, + 0x00, 0x3a, 0x10, 0x08, 0x00, 0x21, 0x00, 0x04, 0x10, 0x21, 0x00, 0x04, 0x20, 0x21, 0x00, 0x04, 0xd8, 0x19, 0x01, 0x03, 0xe0, 0x19, 0x01, 0x03, 0xe8, 0x19, 0x01, 0x03, 0xf0, 0x19, 0x01, 0x03, + 0x88, 0x08, 0x02, 0x03, 0x90, 0x08, 0x02, 0x03, 0x98, 0x08, 0x02, 0x03, 0xd0, 0x35, 0x03, 0x04, 0xe0, 0x35, 0x03, 0x04, 0xf0, 0x35, 0x03, 0x04, 0xd0, 0x1e, 0x04, 0x04, 0xe0, 0x1e, 0x04, 0x04, + 0x00, 0x0d, 0x05, 0x04, 0x10, 0x0d, 0x05, 0x04, 0x40, 0x3b, 0x06, 0x05, 0x00, 0x25, 0x07, 0x05, 0xa0, 0x10, 0x08, 0x05, 0xa0, 0x01, 0x09, 0x05, 0x80, 0x2b, 0x0a, 0x06, 0xc0, 0x07, 0x0c, 0x06, + 0x00, 0x3b, 0x10, 0x08, 0x30, 0x21, 0x00, 0x04, 0x40, 0x21, 0x00, 0x04, 0x50, 0x21, 0x00, 0x04, 0xf8, 0x19, 0x01, 0x03, 0x00, 0x1a, 0x01, 0x03, 0x08, 0x1a, 0x01, 0x03, 0x10, 0x1a, 0x01, 0x03, + 0xa0, 0x08, 0x02, 0x03, 0xa8, 0x08, 0x02, 0x03, 0xb0, 0x08, 0x02, 0x03, 0x00, 0x36, 0x03, 0x04, 0x10, 0x36, 0x03, 0x04, 0x20, 0x36, 0x03, 0x04, 0xf0, 0x1e, 0x04, 0x04, 0x00, 0x1f, 0x04, 0x04, + 0x20, 0x0d, 0x05, 0x04, 0x30, 0x0d, 0x05, 0x04, 0x60, 0x3b, 0x06, 0x05, 0x20, 0x25, 0x07, 0x05, 0xc0, 0x10, 0x08, 0x05, 0xc0, 0x01, 0x09, 0x05, 0xc0, 0x2b, 0x0a, 0x06, 0x00, 0x08, 0x0c, 0x06, + 0x00, 0x3c, 0x10, 0x08, 0x60, 0x21, 0x00, 0x04, 0x70, 0x21, 0x00, 0x04, 0x80, 0x21, 0x00, 0x04, 0x18, 0x1a, 0x01, 0x03, 0x20, 0x1a, 0x01, 0x03, 0x28, 0x1a, 0x01, 0x03, 0x30, 0x1a, 0x01, 0x03, + 0xb8, 0x08, 0x02, 0x03, 0xc0, 0x08, 0x02, 0x03, 0xc8, 0x08, 0x02, 0x03, 0x30, 0x36, 0x03, 0x04, 0x40, 0x36, 0x03, 0x04, 0x50, 0x36, 0x03, 0x04, 0x10, 0x1f, 0x04, 0x04, 0x20, 0x1f, 0x04, 0x04, + 0x40, 0x0d, 0x05, 0x04, 0x50, 0x0d, 0x05, 0x04, 0x80, 0x3b, 0x06, 0x05, 0x40, 0x25, 0x07, 0x05, 0xe0, 0x10, 0x08, 0x05, 0xe0, 0x01, 0x09, 0x05, 0x00, 0x2c, 0x0a, 0x06, 0x40, 0x08, 0x0c, 0x06, + 0x00, 0x3d, 0x10, 0x08, 0x90, 0x21, 0x00, 0x04, 0xa0, 0x21, 0x00, 0x04, 0xb0, 0x21, 0x00, 0x04, 0x38, 0x1a, 0x01, 0x03, 0x40, 0x1a, 0x01, 0x03, 0x48, 0x1a, 0x01, 0x03, 0x50, 0x1a, 0x01, 0x03, + 0xd0, 0x08, 0x02, 0x03, 0xd8, 0x08, 0x02, 0x03, 0xe0, 0x08, 0x02, 0x03, 0x60, 0x36, 0x03, 0x04, 0x70, 0x36, 0x03, 0x04, 0x80, 0x36, 0x03, 0x04, 0x30, 0x1f, 0x04, 0x04, 0x40, 0x1f, 0x04, 0x04, + 0x60, 0x0d, 0x05, 0x04, 0x70, 0x0d, 0x05, 0x04, 0xa0, 0x3b, 0x06, 0x05, 0x60, 0x25, 0x07, 0x05, 0x00, 0x11, 0x08, 0x05, 0x00, 0x02, 0x09, 0x05, 0x40, 0x2c, 0x0a, 0x06, 0x80, 0x08, 0x0c, 0x06, + 0x00, 0x3e, 0x10, 0x08, 0xc0, 0x21, 0x00, 0x04, 0xd0, 0x21, 0x00, 0x04, 0x58, 0x1a, 0x01, 0x03, 0x60, 0x1a, 0x01, 0x03, 0x68, 0x1a, 0x01, 0x03, 0x70, 0x1a, 0x01, 0x03, 0x78, 0x1a, 0x01, 0x03, + 0xe8, 0x08, 0x02, 0x03, 0xf0, 0x08, 0x02, 0x03, 0xf8, 0x08, 0x02, 0x03, 0x90, 0x36, 0x03, 0x04, 0xa0, 0x36, 0x03, 0x04, 0xb0, 0x36, 0x03, 0x04, 0x50, 0x1f, 0x04, 0x04, 0x60, 0x1f, 0x04, 0x04, + 0x80, 0x0d, 0x05, 0x04, 0x90, 0x0d, 0x05, 0x04, 0xc0, 0x3b, 0x06, 0x05, 0x80, 0x25, 0x07, 0x05, 0x20, 0x11, 0x08, 0x05, 0x20, 0x02, 0x09, 0x05, 0x80, 0x2c, 0x0a, 0x06, 0xc0, 0x08, 0x0c, 0x06, + 0x00, 0x3f, 0x10, 0x08, 0xe0, 0x21, 0x00, 0x04, 0xf0, 0x21, 0x00, 0x04, 0x80, 0x1a, 0x01, 0x03, 0x88, 0x1a, 0x01, 0x03, 0x90, 0x1a, 0x01, 0x03, 0x98, 0x1a, 0x01, 0x03, 0xa0, 0x1a, 0x01, 0x03, + 0x00, 0x09, 0x02, 0x03, 0x08, 0x09, 0x02, 0x03, 0x10, 0x09, 0x02, 0x03, 0xc0, 0x36, 0x03, 0x04, 0xd0, 0x36, 0x03, 0x04, 0xe0, 0x36, 0x03, 0x04, 0x70, 0x1f, 0x04, 0x04, 0x80, 0x1f, 0x04, 0x04, + 0xa0, 0x0d, 0x05, 0x04, 0xb0, 0x0d, 0x05, 0x04, 0xe0, 0x3b, 0x06, 0x05, 0xa0, 0x25, 0x07, 0x05, 0x40, 0x11, 0x08, 0x05, 0x40, 0x02, 0x09, 0x05, 0xc0, 0x2c, 0x0a, 0x06, 0x00, 0x09, 0x0c, 0x06, + 0x00, 0x00, 0x10, 0x07, 0x00, 0x22, 0x00, 0x04, 0x10, 0x22, 0x00, 0x04, 0xa8, 0x1a, 0x01, 0x03, 0xb0, 0x1a, 0x01, 0x03, 0xb8, 0x1a, 0x01, 0x03, 0xc0, 0x1a, 0x01, 0x03, 0xc8, 0x1a, 0x01, 0x03, + 0x18, 0x09, 0x02, 0x03, 0x20, 0x09, 0x02, 0x03, 0x28, 0x09, 0x02, 0x03, 0xf0, 0x36, 0x03, 0x04, 0x00, 0x37, 0x03, 0x04, 0x10, 0x37, 0x03, 0x04, 0x90, 0x1f, 0x04, 0x04, 0xa0, 0x1f, 0x04, 0x04, + 0xc0, 0x0d, 0x05, 0x04, 0xd0, 0x0d, 0x05, 0x04, 0x00, 0x3c, 0x06, 0x05, 0xc0, 0x25, 0x07, 0x05, 0x60, 0x11, 0x08, 0x05, 0x60, 0x02, 0x09, 0x05, 0x00, 0x2d, 0x0a, 0x06, 0x40, 0x09, 0x0c, 0x06, + 0x80, 0x00, 0x10, 0x07, 0x20, 0x22, 0x00, 0x04, 0x30, 0x22, 0x00, 0x04, 0xd0, 0x1a, 0x01, 0x03, 0xd8, 0x1a, 0x01, 0x03, 0xe0, 0x1a, 0x01, 0x03, 0xe8, 0x1a, 0x01, 0x03, 0xf0, 0x1a, 0x01, 0x03, + 0x30, 0x09, 0x02, 0x03, 0x38, 0x09, 0x02, 0x03, 0x40, 0x09, 0x02, 0x03, 0x20, 0x37, 0x03, 0x04, 0x30, 0x37, 0x03, 0x04, 0x40, 0x37, 0x03, 0x04, 0xb0, 0x1f, 0x04, 0x04, 0xc0, 0x1f, 0x04, 0x04, + 0xe0, 0x0d, 0x05, 0x04, 0xf0, 0x0d, 0x05, 0x04, 0x20, 0x3c, 0x06, 0x05, 0xe0, 0x25, 0x07, 0x05, 0x80, 0x11, 0x08, 0x05, 0x80, 0x02, 0x09, 0x05, 0x40, 0x2d, 0x0a, 0x06, 0x80, 0x09, 0x0c, 0x06, + 0x00, 0x01, 0x10, 0x07, 0x40, 0x22, 0x00, 0x04, 0x50, 0x22, 0x00, 0x04, 0xf8, 0x1a, 0x01, 0x03, 0x00, 0x1b, 0x01, 0x03, 0x08, 0x1b, 0x01, 0x03, 0x10, 0x1b, 0x01, 0x03, 0x18, 0x1b, 0x01, 0x03, + 0x48, 0x09, 0x02, 0x03, 0x50, 0x09, 0x02, 0x03, 0x58, 0x09, 0x02, 0x03, 0x50, 0x37, 0x03, 0x04, 0x60, 0x37, 0x03, 0x04, 0x70, 0x37, 0x03, 0x04, 0xd0, 0x1f, 0x04, 0x04, 0xe0, 0x1f, 0x04, 0x04, + 0x00, 0x0e, 0x05, 0x04, 0x10, 0x0e, 0x05, 0x04, 0x40, 0x3c, 0x06, 0x05, 0x00, 0x26, 0x07, 0x05, 0xa0, 0x11, 0x08, 0x05, 0xa0, 0x02, 0x09, 0x05, 0x80, 0x2d, 0x0a, 0x06, 0xc0, 0x09, 0x0c, 0x06, + 0x00, 0x1d, 0x11, 0x08, 0x60, 0x22, 0x00, 0x04, 0x70, 0x22, 0x00, 0x04, 0x20, 0x1b, 0x01, 0x03, 0x28, 0x1b, 0x01, 0x03, 0x30, 0x1b, 0x01, 0x03, 0x38, 0x1b, 0x01, 0x03, 0x40, 0x1b, 0x01, 0x03, + 0x60, 0x09, 0x02, 0x03, 0x68, 0x09, 0x02, 0x03, 0x70, 0x09, 0x02, 0x03, 0x80, 0x37, 0x03, 0x04, 0x90, 0x37, 0x03, 0x04, 0xa0, 0x37, 0x03, 0x04, 0xf0, 0x1f, 0x04, 0x04, 0x00, 0x20, 0x04, 0x04, + 0x20, 0x0e, 0x05, 0x04, 0x30, 0x0e, 0x05, 0x04, 0x60, 0x3c, 0x06, 0x05, 0x20, 0x26, 0x07, 0x05, 0xc0, 0x11, 0x08, 0x05, 0xc0, 0x02, 0x09, 0x05, 0xc0, 0x2d, 0x0a, 0x06, 0x00, 0x0a, 0x0c, 0x06, + 0x00, 0x1e, 0x11, 0x08, 0x80, 0x22, 0x00, 0x04, 0x90, 0x22, 0x00, 0x04, 0x48, 0x1b, 0x01, 0x03, 0x50, 0x1b, 0x01, 0x03, 0x58, 0x1b, 0x01, 0x03, 0x60, 0x1b, 0x01, 0x03, 0x68, 0x1b, 0x01, 0x03, + 0x78, 0x09, 0x02, 0x03, 0x80, 0x09, 0x02, 0x03, 0x88, 0x09, 0x02, 0x03, 0xb0, 0x37, 0x03, 0x04, 0xc0, 0x37, 0x03, 0x04, 0xd0, 0x37, 0x03, 0x04, 0x10, 0x20, 0x04, 0x04, 0x20, 0x20, 0x04, 0x04, + 0x40, 0x0e, 0x05, 0x04, 0x50, 0x0e, 0x05, 0x04, 0x80, 0x3c, 0x06, 0x05, 0x40, 0x26, 0x07, 0x05, 0xe0, 0x11, 0x08, 0x05, 0xe0, 0x02, 0x09, 0x05, 0x00, 0x2e, 0x0a, 0x06, 0x80, 0x2d, 0x0d, 0x07, + 0x00, 0x1f, 0x11, 0x08, 0xa0, 0x22, 0x00, 0x04, 0xb0, 0x22, 0x00, 0x04, 0x70, 0x1b, 0x01, 0x03, 0x78, 0x1b, 0x01, 0x03, 0x80, 0x1b, 0x01, 0x03, 0x88, 0x1b, 0x01, 0x03, 0x90, 0x1b, 0x01, 0x03, + 0x90, 0x09, 0x02, 0x03, 0x98, 0x09, 0x02, 0x03, 0xa0, 0x09, 0x02, 0x03, 0xe0, 0x37, 0x03, 0x04, 0xf0, 0x37, 0x03, 0x04, 0x00, 0x38, 0x03, 0x04, 0x30, 0x20, 0x04, 0x04, 0x40, 0x20, 0x04, 0x04, + 0x60, 0x0e, 0x05, 0x04, 0x70, 0x0e, 0x05, 0x04, 0xa0, 0x3c, 0x06, 0x05, 0x60, 0x26, 0x07, 0x05, 0x00, 0x12, 0x08, 0x05, 0x00, 0x03, 0x09, 0x05, 0x40, 0x2e, 0x0a, 0x06, 0x00, 0x2e, 0x0d, 0x07, + 0x00, 0x20, 0x11, 0x08, 0xc0, 0x22, 0x00, 0x04, 0xd0, 0x22, 0x00, 0x04, 0x98, 0x1b, 0x01, 0x03, 0xa0, 0x1b, 0x01, 0x03, 0xa8, 0x1b, 0x01, 0x03, 0xb0, 0x1b, 0x01, 0x03, 0xb8, 0x1b, 0x01, 0x03, + 0xa8, 0x09, 0x02, 0x03, 0xb0, 0x09, 0x02, 0x03, 0xb8, 0x09, 0x02, 0x03, 0x10, 0x38, 0x03, 0x04, 0x20, 0x38, 0x03, 0x04, 0x30, 0x38, 0x03, 0x04, 0x50, 0x20, 0x04, 0x04, 0x60, 0x20, 0x04, 0x04, + 0x80, 0x0e, 0x05, 0x04, 0x90, 0x0e, 0x05, 0x04, 0xc0, 0x3c, 0x06, 0x05, 0x80, 0x26, 0x07, 0x05, 0x20, 0x12, 0x08, 0x05, 0x20, 0x03, 0x09, 0x05, 0x80, 0x2e, 0x0a, 0x06, 0x80, 0x2e, 0x0d, 0x07, + 0x00, 0x21, 0x11, 0x08, 0xe0, 0x22, 0x00, 0x04, 0xf0, 0x22, 0x00, 0x04, 0xc0, 0x1b, 0x01, 0x03, 0xc8, 0x1b, 0x01, 0x03, 0xd0, 0x1b, 0x01, 0x03, 0xd8, 0x1b, 0x01, 0x03, 0xe0, 0x1b, 0x01, 0x03, + 0xc0, 0x09, 0x02, 0x03, 0xc8, 0x09, 0x02, 0x03, 0xd0, 0x09, 0x02, 0x03, 0x40, 0x38, 0x03, 0x04, 0x50, 0x38, 0x03, 0x04, 0x60, 0x38, 0x03, 0x04, 0x70, 0x20, 0x04, 0x04, 0x80, 0x20, 0x04, 0x04, + 0xa0, 0x0e, 0x05, 0x04, 0xb0, 0x0e, 0x05, 0x04, 0xe0, 0x3c, 0x06, 0x05, 0xa0, 0x26, 0x07, 0x05, 0x40, 0x12, 0x08, 0x05, 0x40, 0x03, 0x09, 0x05, 0xc0, 0x2e, 0x0a, 0x06, 0x00, 0x2f, 0x0d, 0x07, + 0x00, 0x22, 0x11, 0x08, 0x00, 0x23, 0x00, 0x04, 0x10, 0x23, 0x00, 0x04, 0xe8, 0x1b, 0x01, 0x03, 0xf0, 0x1b, 0x01, 0x03, 0xf8, 0x1b, 0x01, 0x03, 0x00, 0x1c, 0x01, 0x03, 0x08, 0x1c, 0x01, 0x03, + 0xd8, 0x09, 0x02, 0x03, 0xe0, 0x09, 0x02, 0x03, 0xe8, 0x09, 0x02, 0x03, 0x70, 0x38, 0x03, 0x04, 0x80, 0x38, 0x03, 0x04, 0x90, 0x38, 0x03, 0x04, 0x90, 0x20, 0x04, 0x04, 0xa0, 0x20, 0x04, 0x04, + 0xc0, 0x0e, 0x05, 0x04, 0xd0, 0x0e, 0x05, 0x04, 0x00, 0x3d, 0x06, 0x05, 0xc0, 0x26, 0x07, 0x05, 0x60, 0x12, 0x08, 0x05, 0x60, 0x03, 0x09, 0x05, 0x00, 0x2f, 0x0a, 0x06, 0x80, 0x2f, 0x0d, 0x07, + 0x00, 0x23, 0x11, 0x08, 0x20, 0x23, 0x00, 0x04, 0x30, 0x23, 0x00, 0x04, 0x10, 0x1c, 0x01, 0x03, 0x18, 0x1c, 0x01, 0x03, 0x20, 0x1c, 0x01, 0x03, 0x28, 0x1c, 0x01, 0x03, 0x30, 0x1c, 0x01, 0x03, + 0xf0, 0x09, 0x02, 0x03, 0xf8, 0x09, 0x02, 0x03, 0x00, 0x0a, 0x02, 0x03, 0xa0, 0x38, 0x03, 0x04, 0xb0, 0x38, 0x03, 0x04, 0xc0, 0x38, 0x03, 0x04, 0xb0, 0x20, 0x04, 0x04, 0xc0, 0x20, 0x04, 0x04, + 0xe0, 0x0e, 0x05, 0x04, 0xf0, 0x0e, 0x05, 0x04, 0x20, 0x3d, 0x06, 0x05, 0xe0, 0x26, 0x07, 0x05, 0x80, 0x12, 0x08, 0x05, 0x80, 0x03, 0x09, 0x05, 0x40, 0x2f, 0x0a, 0x06, 0x00, 0x30, 0x0d, 0x07, + 0x00, 0x24, 0x11, 0x08, 0x40, 0x23, 0x00, 0x04, 0x50, 0x23, 0x00, 0x04, 0x38, 0x1c, 0x01, 0x03, 0x40, 0x1c, 0x01, 0x03, 0x48, 0x1c, 0x01, 0x03, 0x50, 0x1c, 0x01, 0x03, 0x58, 0x1c, 0x01, 0x03, + 0x08, 0x0a, 0x02, 0x03, 0x10, 0x0a, 0x02, 0x03, 0x18, 0x0a, 0x02, 0x03, 0xd0, 0x38, 0x03, 0x04, 0xe0, 0x38, 0x03, 0x04, 0xf0, 0x38, 0x03, 0x04, 0xd0, 0x20, 0x04, 0x04, 0xe0, 0x20, 0x04, 0x04, + 0x00, 0x0f, 0x05, 0x04, 0x10, 0x0f, 0x05, 0x04, 0x40, 0x3d, 0x06, 0x05, 0x00, 0x27, 0x07, 0x05, 0xa0, 0x12, 0x08, 0x05, 0xa0, 0x03, 0x09, 0x05, 0x80, 0x2f, 0x0a, 0x06, 0x80, 0x30, 0x0d, 0x07, + 0x00, 0x25, 0x11, 0x08, 0x60, 0x23, 0x00, 0x04, 0x70, 0x23, 0x00, 0x04, 0x60, 0x1c, 0x01, 0x03, 0x68, 0x1c, 0x01, 0x03, 0x70, 0x1c, 0x01, 0x03, 0x78, 0x1c, 0x01, 0x03, 0x80, 0x1c, 0x01, 0x03, + 0x20, 0x0a, 0x02, 0x03, 0x28, 0x0a, 0x02, 0x03, 0x30, 0x0a, 0x02, 0x03, 0x00, 0x39, 0x03, 0x04, 0x10, 0x39, 0x03, 0x04, 0x20, 0x39, 0x03, 0x04, 0xf0, 0x20, 0x04, 0x04, 0x00, 0x21, 0x04, 0x04, + 0x20, 0x0f, 0x05, 0x04, 0x30, 0x0f, 0x05, 0x04, 0x60, 0x3d, 0x06, 0x05, 0x20, 0x27, 0x07, 0x05, 0xc0, 0x12, 0x08, 0x05, 0xc0, 0x03, 0x09, 0x05, 0xc0, 0x2f, 0x0a, 0x06, 0x00, 0x31, 0x0d, 0x07, + 0x00, 0x26, 0x11, 0x08, 0x80, 0x23, 0x00, 0x04, 0x90, 0x23, 0x00, 0x04, 0x88, 0x1c, 0x01, 0x03, 0x90, 0x1c, 0x01, 0x03, 0x98, 0x1c, 0x01, 0x03, 0xa0, 0x1c, 0x01, 0x03, 0x38, 0x0a, 0x02, 0x03, + 0x40, 0x0a, 0x02, 0x03, 0x48, 0x0a, 0x02, 0x03, 0x50, 0x0a, 0x02, 0x03, 0x30, 0x39, 0x03, 0x04, 0x40, 0x39, 0x03, 0x04, 0x50, 0x39, 0x03, 0x04, 0x10, 0x21, 0x04, 0x04, 0x20, 0x21, 0x04, 0x04, + 0x40, 0x0f, 0x05, 0x04, 0x50, 0x0f, 0x05, 0x04, 0x80, 0x3d, 0x06, 0x05, 0x40, 0x27, 0x07, 0x05, 0xe0, 0x12, 0x08, 0x05, 0xe0, 0x03, 0x09, 0x05, 0xc0, 0x13, 0x0b, 0x06, 0x80, 0x31, 0x0d, 0x07, + 0x00, 0x27, 0x11, 0x08, 0xa0, 0x23, 0x00, 0x04, 0xb0, 0x23, 0x00, 0x04, 0xa8, 0x1c, 0x01, 0x03, 0xb0, 0x1c, 0x01, 0x03, 0xb8, 0x1c, 0x01, 0x03, 0xc0, 0x1c, 0x01, 0x03, 0x58, 0x0a, 0x02, 0x03, + 0x60, 0x0a, 0x02, 0x03, 0x68, 0x0a, 0x02, 0x03, 0x70, 0x0a, 0x02, 0x03, 0x60, 0x39, 0x03, 0x04, 0x70, 0x39, 0x03, 0x04, 0x80, 0x39, 0x03, 0x04, 0x30, 0x21, 0x04, 0x04, 0x40, 0x21, 0x04, 0x04, + 0x60, 0x0f, 0x05, 0x04, 0x70, 0x0f, 0x05, 0x04, 0xa0, 0x3d, 0x06, 0x05, 0x60, 0x27, 0x07, 0x05, 0x00, 0x13, 0x08, 0x05, 0x00, 0x04, 0x09, 0x05, 0x00, 0x14, 0x0b, 0x06, 0x00, 0x32, 0x0d, 0x07, + 0x00, 0x0c, 0x12, 0x08, 0xc0, 0x23, 0x00, 0x04, 0xd0, 0x23, 0x00, 0x04, 0xc8, 0x1c, 0x01, 0x03, 0xd0, 0x1c, 0x01, 0x03, 0xd8, 0x1c, 0x01, 0x03, 0xe0, 0x1c, 0x01, 0x03, 0x78, 0x0a, 0x02, 0x03, + 0x80, 0x0a, 0x02, 0x03, 0x88, 0x0a, 0x02, 0x03, 0x90, 0x0a, 0x02, 0x03, 0x90, 0x39, 0x03, 0x04, 0xa0, 0x39, 0x03, 0x04, 0xb0, 0x39, 0x03, 0x04, 0x50, 0x21, 0x04, 0x04, 0x60, 0x21, 0x04, 0x04, + 0x80, 0x0f, 0x05, 0x04, 0x90, 0x0f, 0x05, 0x04, 0xc0, 0x3d, 0x06, 0x05, 0x80, 0x27, 0x07, 0x05, 0x20, 0x13, 0x08, 0x05, 0x20, 0x04, 0x09, 0x05, 0x40, 0x14, 0x0b, 0x06, 0x80, 0x32, 0x0d, 0x07, + 0x00, 0x0d, 0x12, 0x08, 0xe0, 0x23, 0x00, 0x04, 0xf0, 0x23, 0x00, 0x04, 0xe8, 0x1c, 0x01, 0x03, 0xf0, 0x1c, 0x01, 0x03, 0xf8, 0x1c, 0x01, 0x03, 0x00, 0x1d, 0x01, 0x03, 0x98, 0x0a, 0x02, 0x03, + 0xa0, 0x0a, 0x02, 0x03, 0xa8, 0x0a, 0x02, 0x03, 0xb0, 0x0a, 0x02, 0x03, 0xc0, 0x39, 0x03, 0x04, 0xd0, 0x39, 0x03, 0x04, 0xe0, 0x39, 0x03, 0x04, 0x70, 0x21, 0x04, 0x04, 0x80, 0x21, 0x04, 0x04, + 0xa0, 0x0f, 0x05, 0x04, 0xb0, 0x0f, 0x05, 0x04, 0xe0, 0x3d, 0x06, 0x05, 0xa0, 0x27, 0x07, 0x05, 0x40, 0x13, 0x08, 0x05, 0x40, 0x04, 0x09, 0x05, 0x80, 0x14, 0x0b, 0x06, 0x00, 0x33, 0x0d, 0x07, + 0x00, 0x0e, 0x12, 0x08, 0x00, 0x24, 0x00, 0x04, 0x10, 0x24, 0x00, 0x04, 0x08, 0x1d, 0x01, 0x03, 0x10, 0x1d, 0x01, 0x03, 0x18, 0x1d, 0x01, 0x03, 0x20, 0x1d, 0x01, 0x03, 0xb8, 0x0a, 0x02, 0x03, + 0xc0, 0x0a, 0x02, 0x03, 0xc8, 0x0a, 0x02, 0x03, 0xd0, 0x0a, 0x02, 0x03, 0xf0, 0x39, 0x03, 0x04, 0x00, 0x3a, 0x03, 0x04, 0x10, 0x3a, 0x03, 0x04, 0x90, 0x21, 0x04, 0x04, 0xa0, 0x21, 0x04, 0x04, + 0xc0, 0x0f, 0x05, 0x04, 0xd0, 0x0f, 0x05, 0x04, 0x00, 0x3e, 0x06, 0x05, 0xc0, 0x27, 0x07, 0x05, 0x60, 0x13, 0x08, 0x05, 0x60, 0x04, 0x09, 0x05, 0xc0, 0x14, 0x0b, 0x06, 0x80, 0x33, 0x0d, 0x07, + 0x00, 0x0f, 0x12, 0x08, 0x20, 0x24, 0x00, 0x04, 0x30, 0x24, 0x00, 0x04, 0x28, 0x1d, 0x01, 0x03, 0x30, 0x1d, 0x01, 0x03, 0x38, 0x1d, 0x01, 0x03, 0x40, 0x1d, 0x01, 0x03, 0xd8, 0x0a, 0x02, 0x03, + 0xe0, 0x0a, 0x02, 0x03, 0xe8, 0x0a, 0x02, 0x03, 0xf0, 0x0a, 0x02, 0x03, 0x20, 0x3a, 0x03, 0x04, 0x30, 0x3a, 0x03, 0x04, 0x40, 0x3a, 0x03, 0x04, 0xb0, 0x21, 0x04, 0x04, 0xc0, 0x21, 0x04, 0x04, + 0xe0, 0x0f, 0x05, 0x04, 0xf0, 0x0f, 0x05, 0x04, 0x20, 0x3e, 0x06, 0x05, 0xe0, 0x27, 0x07, 0x05, 0x80, 0x13, 0x08, 0x05, 0x80, 0x04, 0x09, 0x05, 0x00, 0x15, 0x0b, 0x06, 0x00, 0x34, 0x0d, 0x07, + 0x00, 0x10, 0x12, 0x08, 0x40, 0x24, 0x00, 0x04, 0x50, 0x24, 0x00, 0x04, 0x48, 0x1d, 0x01, 0x03, 0x50, 0x1d, 0x01, 0x03, 0x58, 0x1d, 0x01, 0x03, 0x60, 0x1d, 0x01, 0x03, 0xf8, 0x0a, 0x02, 0x03, + 0x00, 0x0b, 0x02, 0x03, 0x08, 0x0b, 0x02, 0x03, 0x10, 0x0b, 0x02, 0x03, 0x50, 0x3a, 0x03, 0x04, 0x60, 0x3a, 0x03, 0x04, 0x70, 0x3a, 0x03, 0x04, 0xd0, 0x21, 0x04, 0x04, 0xe0, 0x21, 0x04, 0x04, + 0x00, 0x10, 0x05, 0x04, 0x10, 0x10, 0x05, 0x04, 0x40, 0x3e, 0x06, 0x05, 0x00, 0x28, 0x07, 0x05, 0xa0, 0x13, 0x08, 0x05, 0xa0, 0x04, 0x09, 0x05, 0x40, 0x15, 0x0b, 0x06, 0x80, 0x34, 0x0d, 0x07, + 0x00, 0x11, 0x12, 0x08, 0x60, 0x24, 0x00, 0x04, 0x70, 0x24, 0x00, 0x04, 0x68, 0x1d, 0x01, 0x03, 0x70, 0x1d, 0x01, 0x03, 0x78, 0x1d, 0x01, 0x03, 0x80, 0x1d, 0x01, 0x03, 0x18, 0x0b, 0x02, 0x03, + 0x20, 0x0b, 0x02, 0x03, 0x28, 0x0b, 0x02, 0x03, 0x30, 0x0b, 0x02, 0x03, 0x80, 0x3a, 0x03, 0x04, 0x90, 0x3a, 0x03, 0x04, 0xa0, 0x3a, 0x03, 0x04, 0xf0, 0x21, 0x04, 0x04, 0x00, 0x22, 0x04, 0x04, + 0x20, 0x10, 0x05, 0x04, 0x60, 0x3e, 0x06, 0x05, 0x80, 0x3e, 0x06, 0x05, 0x20, 0x28, 0x07, 0x05, 0xc0, 0x13, 0x08, 0x05, 0xc0, 0x04, 0x09, 0x05, 0x80, 0x15, 0x0b, 0x06, 0x00, 0x35, 0x0d, 0x07, + 0x00, 0x12, 0x12, 0x08, 0x80, 0x24, 0x00, 0x04, 0x90, 0x24, 0x00, 0x04, 0x88, 0x1d, 0x01, 0x03, 0x90, 0x1d, 0x01, 0x03, 0x98, 0x1d, 0x01, 0x03, 0xa0, 0x1d, 0x01, 0x03, 0x38, 0x0b, 0x02, 0x03, + 0x40, 0x0b, 0x02, 0x03, 0x48, 0x0b, 0x02, 0x03, 0x50, 0x0b, 0x02, 0x03, 0xb0, 0x3a, 0x03, 0x04, 0xc0, 0x3a, 0x03, 0x04, 0xd0, 0x3a, 0x03, 0x04, 0x10, 0x22, 0x04, 0x04, 0x20, 0x22, 0x04, 0x04, + 0x30, 0x10, 0x05, 0x04, 0xa0, 0x3e, 0x06, 0x05, 0xc0, 0x3e, 0x06, 0x05, 0x40, 0x28, 0x07, 0x05, 0xe0, 0x13, 0x08, 0x05, 0xe0, 0x04, 0x09, 0x05, 0xc0, 0x15, 0x0b, 0x06, 0x80, 0x35, 0x0d, 0x07, + 0x00, 0x13, 0x12, 0x08, 0xa0, 0x24, 0x00, 0x04, 0xb0, 0x24, 0x00, 0x04, 0xa8, 0x1d, 0x01, 0x03, 0xb0, 0x1d, 0x01, 0x03, 0xb8, 0x1d, 0x01, 0x03, 0xc0, 0x1d, 0x01, 0x03, 0x58, 0x0b, 0x02, 0x03, + 0x60, 0x0b, 0x02, 0x03, 0x68, 0x0b, 0x02, 0x03, 0x70, 0x0b, 0x02, 0x03, 0xe0, 0x3a, 0x03, 0x04, 0xf0, 0x3a, 0x03, 0x04, 0x30, 0x22, 0x04, 0x04, 0x40, 0x22, 0x04, 0x04, 0x50, 0x22, 0x04, 0x04, + 0x40, 0x10, 0x05, 0x04, 0xe0, 0x3e, 0x06, 0x05, 0x00, 0x3f, 0x06, 0x05, 0x60, 0x28, 0x07, 0x05, 0x00, 0x14, 0x08, 0x05, 0x00, 0x05, 0x09, 0x05, 0x00, 0x16, 0x0b, 0x06, 0x00, 0x36, 0x0d, 0x07, + 0x00, 0x14, 0x12, 0x08, 0xc0, 0x24, 0x00, 0x04, 0xd0, 0x24, 0x00, 0x04, 0xc8, 0x1d, 0x01, 0x03, 0xd0, 0x1d, 0x01, 0x03, 0xd8, 0x1d, 0x01, 0x03, 0xe0, 0x1d, 0x01, 0x03, 0x78, 0x0b, 0x02, 0x03, + 0x80, 0x0b, 0x02, 0x03, 0x88, 0x0b, 0x02, 0x03, 0x90, 0x0b, 0x02, 0x03, 0x00, 0x3b, 0x03, 0x04, 0x10, 0x3b, 0x03, 0x04, 0x60, 0x22, 0x04, 0x04, 0x70, 0x22, 0x04, 0x04, 0x80, 0x22, 0x04, 0x04, + 0x50, 0x10, 0x05, 0x04, 0x20, 0x3f, 0x06, 0x05, 0x40, 0x3f, 0x06, 0x05, 0x80, 0x28, 0x07, 0x05, 0x20, 0x14, 0x08, 0x05, 0x20, 0x05, 0x09, 0x05, 0x40, 0x16, 0x0b, 0x06, 0x80, 0x36, 0x0d, 0x07, + 0x00, 0x15, 0x12, 0x08, 0xe0, 0x24, 0x00, 0x04, 0xf0, 0x24, 0x00, 0x04, 0xe8, 0x1d, 0x01, 0x03, 0xf0, 0x1d, 0x01, 0x03, 0xf8, 0x1d, 0x01, 0x03, 0x00, 0x1e, 0x01, 0x03, 0x98, 0x0b, 0x02, 0x03, + 0xa0, 0x0b, 0x02, 0x03, 0xa8, 0x0b, 0x02, 0x03, 0xb0, 0x0b, 0x02, 0x03, 0x20, 0x3b, 0x03, 0x04, 0x30, 0x3b, 0x03, 0x04, 0x90, 0x22, 0x04, 0x04, 0xa0, 0x22, 0x04, 0x04, 0xb0, 0x22, 0x04, 0x04, + 0x60, 0x10, 0x05, 0x04, 0x60, 0x3f, 0x06, 0x05, 0x80, 0x3f, 0x06, 0x05, 0xa0, 0x28, 0x07, 0x05, 0x40, 0x14, 0x08, 0x05, 0x40, 0x05, 0x09, 0x05, 0x80, 0x16, 0x0b, 0x06, 0x00, 0x37, 0x0d, 0x07, + 0x00, 0x3a, 0x13, 0x09, 0x00, 0x25, 0x00, 0x04, 0x10, 0x25, 0x00, 0x04, 0x08, 0x1e, 0x01, 0x03, 0x10, 0x1e, 0x01, 0x03, 0x18, 0x1e, 0x01, 0x03, 0x20, 0x1e, 0x01, 0x03, 0xb8, 0x0b, 0x02, 0x03, + 0xc0, 0x0b, 0x02, 0x03, 0xc8, 0x0b, 0x02, 0x03, 0xd0, 0x0b, 0x02, 0x03, 0x40, 0x3b, 0x03, 0x04, 0x50, 0x3b, 0x03, 0x04, 0xc0, 0x22, 0x04, 0x04, 0xd0, 0x22, 0x04, 0x04, 0xe0, 0x22, 0x04, 0x04, + 0x70, 0x10, 0x05, 0x04, 0xa0, 0x3f, 0x06, 0x05, 0xc0, 0x3f, 0x06, 0x05, 0xc0, 0x28, 0x07, 0x05, 0x60, 0x14, 0x08, 0x05, 0x60, 0x05, 0x09, 0x05, 0xc0, 0x16, 0x0b, 0x06, 0x80, 0x37, 0x0d, 0x07, + 0x00, 0x3c, 0x13, 0x09, 0x20, 0x25, 0x00, 0x04, 0x30, 0x25, 0x00, 0x04, 0x28, 0x1e, 0x01, 0x03, 0x30, 0x1e, 0x01, 0x03, 0x38, 0x1e, 0x01, 0x03, 0x40, 0x1e, 0x01, 0x03, 0xd8, 0x0b, 0x02, 0x03, + 0xe0, 0x0b, 0x02, 0x03, 0xe8, 0x0b, 0x02, 0x03, 0xf0, 0x0b, 0x02, 0x03, 0x60, 0x3b, 0x03, 0x04, 0x70, 0x3b, 0x03, 0x04, 0xf0, 0x22, 0x04, 0x04, 0x00, 0x23, 0x04, 0x04, 0x10, 0x23, 0x04, 0x04, + 0x80, 0x10, 0x05, 0x04, 0xe0, 0x3f, 0x06, 0x05, 0x00, 0x00, 0x06, 0x04, 0xe0, 0x28, 0x07, 0x05, 0x80, 0x14, 0x08, 0x05, 0x80, 0x05, 0x09, 0x05, 0x00, 0x17, 0x0b, 0x06, 0x00, 0x38, 0x0d, 0x07, + 0x00, 0x3e, 0x13, 0x09, 0x40, 0x25, 0x00, 0x04, 0x50, 0x25, 0x00, 0x04, 0x48, 0x1e, 0x01, 0x03, 0x50, 0x1e, 0x01, 0x03, 0x58, 0x1e, 0x01, 0x03, 0x60, 0x1e, 0x01, 0x03, 0xf8, 0x0b, 0x02, 0x03, + 0x00, 0x0c, 0x02, 0x03, 0x08, 0x0c, 0x02, 0x03, 0x10, 0x0c, 0x02, 0x03, 0x80, 0x3b, 0x03, 0x04, 0x90, 0x3b, 0x03, 0x04, 0x20, 0x23, 0x04, 0x04, 0x30, 0x23, 0x04, 0x04, 0x40, 0x23, 0x04, 0x04, + 0x90, 0x10, 0x05, 0x04, 0x10, 0x00, 0x06, 0x04, 0x20, 0x00, 0x06, 0x04, 0x00, 0x29, 0x07, 0x05, 0xa0, 0x14, 0x08, 0x05, 0xa0, 0x05, 0x09, 0x05, 0x40, 0x17, 0x0b, 0x06, 0x80, 0x38, 0x0d, 0x07, + 0x00, 0x00, 0x13, 0x08, 0x60, 0x25, 0x00, 0x04, 0x70, 0x25, 0x00, 0x04, 0x68, 0x1e, 0x01, 0x03, 0x70, 0x1e, 0x01, 0x03, 0x78, 0x1e, 0x01, 0x03, 0x80, 0x1e, 0x01, 0x03, 0x18, 0x0c, 0x02, 0x03, + 0x20, 0x0c, 0x02, 0x03, 0x28, 0x0c, 0x02, 0x03, 0x30, 0x0c, 0x02, 0x03, 0xa0, 0x3b, 0x03, 0x04, 0xb0, 0x3b, 0x03, 0x04, 0x50, 0x23, 0x04, 0x04, 0x60, 0x23, 0x04, 0x04, 0x70, 0x23, 0x04, 0x04, + 0xa0, 0x10, 0x05, 0x04, 0x30, 0x00, 0x06, 0x04, 0x40, 0x00, 0x06, 0x04, 0x20, 0x29, 0x07, 0x05, 0xc0, 0x14, 0x08, 0x05, 0xc0, 0x05, 0x09, 0x05, 0x80, 0x17, 0x0b, 0x06, 0x00, 0x39, 0x0d, 0x07, + 0x00, 0x01, 0x13, 0x08, 0x80, 0x25, 0x00, 0x04, 0x90, 0x25, 0x00, 0x04, 0x88, 0x1e, 0x01, 0x03, 0x90, 0x1e, 0x01, 0x03, 0x98, 0x1e, 0x01, 0x03, 0xa0, 0x1e, 0x01, 0x03, 0x38, 0x0c, 0x02, 0x03, + 0x40, 0x0c, 0x02, 0x03, 0x48, 0x0c, 0x02, 0x03, 0x50, 0x0c, 0x02, 0x03, 0xc0, 0x3b, 0x03, 0x04, 0xd0, 0x3b, 0x03, 0x04, 0x80, 0x23, 0x04, 0x04, 0x90, 0x23, 0x04, 0x04, 0xa0, 0x23, 0x04, 0x04, + 0xb0, 0x10, 0x05, 0x04, 0x50, 0x00, 0x06, 0x04, 0x60, 0x00, 0x06, 0x04, 0x40, 0x29, 0x07, 0x05, 0xe0, 0x14, 0x08, 0x05, 0xe0, 0x05, 0x09, 0x05, 0xc0, 0x17, 0x0b, 0x06, 0x80, 0x39, 0x0d, 0x07, + 0x00, 0x02, 0x13, 0x08, 0xa0, 0x25, 0x00, 0x04, 0xb0, 0x25, 0x00, 0x04, 0xa8, 0x1e, 0x01, 0x03, 0xb0, 0x1e, 0x01, 0x03, 0xb8, 0x1e, 0x01, 0x03, 0xc0, 0x1e, 0x01, 0x03, 0x58, 0x0c, 0x02, 0x03, + 0x60, 0x0c, 0x02, 0x03, 0x68, 0x0c, 0x02, 0x03, 0x70, 0x0c, 0x02, 0x03, 0xe0, 0x3b, 0x03, 0x04, 0xf0, 0x3b, 0x03, 0x04, 0xb0, 0x23, 0x04, 0x04, 0xc0, 0x23, 0x04, 0x04, 0xd0, 0x23, 0x04, 0x04, + 0xc0, 0x10, 0x05, 0x04, 0x70, 0x00, 0x06, 0x04, 0x80, 0x00, 0x06, 0x04, 0x60, 0x29, 0x07, 0x05, 0x00, 0x15, 0x08, 0x05, 0x00, 0x06, 0x09, 0x05, 0x00, 0x18, 0x0b, 0x06, 0x00, 0x3a, 0x0d, 0x07, + 0x00, 0x03, 0x13, 0x08, 0xc0, 0x25, 0x00, 0x04, 0xd0, 0x25, 0x00, 0x04, 0xc8, 0x1e, 0x01, 0x03, 0xd0, 0x1e, 0x01, 0x03, 0xd8, 0x1e, 0x01, 0x03, 0xe0, 0x1e, 0x01, 0x03, 0x78, 0x0c, 0x02, 0x03, + 0x80, 0x0c, 0x02, 0x03, 0x88, 0x0c, 0x02, 0x03, 0x90, 0x0c, 0x02, 0x03, 0x00, 0x3c, 0x03, 0x04, 0x10, 0x3c, 0x03, 0x04, 0xe0, 0x23, 0x04, 0x04, 0xf0, 0x23, 0x04, 0x04, 0x00, 0x24, 0x04, 0x04, + 0xd0, 0x10, 0x05, 0x04, 0x90, 0x00, 0x06, 0x04, 0xa0, 0x00, 0x06, 0x04, 0x80, 0x29, 0x07, 0x05, 0x20, 0x15, 0x08, 0x05, 0x20, 0x06, 0x09, 0x05, 0x40, 0x18, 0x0b, 0x06, 0x80, 0x3a, 0x0d, 0x07, + 0x00, 0x22, 0x14, 0x09, 0xe0, 0x25, 0x00, 0x04, 0xf0, 0x25, 0x00, 0x04, 0xe8, 0x1e, 0x01, 0x03, 0xf0, 0x1e, 0x01, 0x03, 0xf8, 0x1e, 0x01, 0x03, 0x00, 0x1f, 0x01, 0x03, 0x98, 0x0c, 0x02, 0x03, + 0xa0, 0x0c, 0x02, 0x03, 0xa8, 0x0c, 0x02, 0x03, 0xb0, 0x0c, 0x02, 0x03, 0x20, 0x3c, 0x03, 0x04, 0x30, 0x3c, 0x03, 0x04, 0x10, 0x24, 0x04, 0x04, 0x20, 0x24, 0x04, 0x04, 0x30, 0x24, 0x04, 0x04, + 0xe0, 0x10, 0x05, 0x04, 0xb0, 0x00, 0x06, 0x04, 0xc0, 0x00, 0x06, 0x04, 0xa0, 0x29, 0x07, 0x05, 0x40, 0x15, 0x08, 0x05, 0x40, 0x06, 0x09, 0x05, 0x80, 0x18, 0x0b, 0x06, 0x80, 0x18, 0x0e, 0x07, + 0x00, 0x24, 0x14, 0x09, 0x00, 0x26, 0x00, 0x04, 0x10, 0x26, 0x00, 0x04, 0x08, 0x1f, 0x01, 0x03, 0x10, 0x1f, 0x01, 0x03, 0x18, 0x1f, 0x01, 0x03, 0x20, 0x1f, 0x01, 0x03, 0xb8, 0x0c, 0x02, 0x03, + 0xc0, 0x0c, 0x02, 0x03, 0xc8, 0x0c, 0x02, 0x03, 0xd0, 0x0c, 0x02, 0x03, 0x40, 0x3c, 0x03, 0x04, 0x50, 0x3c, 0x03, 0x04, 0x40, 0x24, 0x04, 0x04, 0x50, 0x24, 0x04, 0x04, 0x60, 0x24, 0x04, 0x04, + 0xf0, 0x10, 0x05, 0x04, 0xd0, 0x00, 0x06, 0x04, 0xe0, 0x00, 0x06, 0x04, 0xc0, 0x29, 0x07, 0x05, 0x60, 0x15, 0x08, 0x05, 0x60, 0x06, 0x09, 0x05, 0xc0, 0x18, 0x0b, 0x06, 0x00, 0x19, 0x0e, 0x07, + 0x00, 0x26, 0x14, 0x09, 0x20, 0x26, 0x00, 0x04, 0x30, 0x26, 0x00, 0x04, 0x28, 0x1f, 0x01, 0x03, 0x30, 0x1f, 0x01, 0x03, 0x38, 0x1f, 0x01, 0x03, 0x40, 0x1f, 0x01, 0x03, 0xd8, 0x0c, 0x02, 0x03, + 0xe0, 0x0c, 0x02, 0x03, 0xe8, 0x0c, 0x02, 0x03, 0xf0, 0x0c, 0x02, 0x03, 0x60, 0x3c, 0x03, 0x04, 0x70, 0x3c, 0x03, 0x04, 0x70, 0x24, 0x04, 0x04, 0x80, 0x24, 0x04, 0x04, 0x90, 0x24, 0x04, 0x04, + 0x00, 0x11, 0x05, 0x04, 0xf0, 0x00, 0x06, 0x04, 0x00, 0x01, 0x06, 0x04, 0xe0, 0x29, 0x07, 0x05, 0x80, 0x15, 0x08, 0x05, 0x80, 0x06, 0x09, 0x05, 0x00, 0x19, 0x0b, 0x06, 0x80, 0x19, 0x0e, 0x07, + 0x00, 0x28, 0x14, 0x09, 0x40, 0x26, 0x00, 0x04, 0x50, 0x26, 0x00, 0x04, 0x48, 0x1f, 0x01, 0x03, 0x50, 0x1f, 0x01, 0x03, 0x58, 0x1f, 0x01, 0x03, 0x60, 0x1f, 0x01, 0x03, 0xf8, 0x0c, 0x02, 0x03, + 0x00, 0x0d, 0x02, 0x03, 0x08, 0x0d, 0x02, 0x03, 0x10, 0x0d, 0x02, 0x03, 0x80, 0x3c, 0x03, 0x04, 0x90, 0x3c, 0x03, 0x04, 0xa0, 0x24, 0x04, 0x04, 0xb0, 0x24, 0x04, 0x04, 0xc0, 0x24, 0x04, 0x04, + 0x10, 0x11, 0x05, 0x04, 0x10, 0x01, 0x06, 0x04, 0x20, 0x01, 0x06, 0x04, 0x00, 0x2a, 0x07, 0x05, 0xa0, 0x15, 0x08, 0x05, 0xa0, 0x06, 0x09, 0x05, 0x40, 0x19, 0x0b, 0x06, 0x00, 0x1a, 0x0e, 0x07, + 0x00, 0x2a, 0x14, 0x09, 0x60, 0x26, 0x00, 0x04, 0x70, 0x26, 0x00, 0x04, 0x68, 0x1f, 0x01, 0x03, 0x70, 0x1f, 0x01, 0x03, 0x78, 0x1f, 0x01, 0x03, 0x80, 0x1f, 0x01, 0x03, 0x18, 0x0d, 0x02, 0x03, + 0x20, 0x0d, 0x02, 0x03, 0x28, 0x0d, 0x02, 0x03, 0x30, 0x0d, 0x02, 0x03, 0xa0, 0x3c, 0x03, 0x04, 0xb0, 0x3c, 0x03, 0x04, 0xd0, 0x24, 0x04, 0x04, 0xe0, 0x24, 0x04, 0x04, 0xf0, 0x24, 0x04, 0x04, + 0x20, 0x11, 0x05, 0x04, 0x30, 0x01, 0x06, 0x04, 0x40, 0x01, 0x06, 0x04, 0x20, 0x2a, 0x07, 0x05, 0xc0, 0x15, 0x08, 0x05, 0xc0, 0x06, 0x09, 0x05, 0x80, 0x19, 0x0b, 0x06, 0x80, 0x1a, 0x0e, 0x07, + 0x00, 0x2c, 0x14, 0x09, 0x80, 0x26, 0x00, 0x04, 0x90, 0x26, 0x00, 0x04, 0x88, 0x1f, 0x01, 0x03, 0x90, 0x1f, 0x01, 0x03, 0x98, 0x1f, 0x01, 0x03, 0xa0, 0x1f, 0x01, 0x03, 0x38, 0x0d, 0x02, 0x03, + 0x40, 0x0d, 0x02, 0x03, 0x48, 0x0d, 0x02, 0x03, 0x50, 0x0d, 0x02, 0x03, 0xc0, 0x3c, 0x03, 0x04, 0xd0, 0x3c, 0x03, 0x04, 0x00, 0x25, 0x04, 0x04, 0x10, 0x25, 0x04, 0x04, 0x20, 0x25, 0x04, 0x04, + 0x30, 0x11, 0x05, 0x04, 0x50, 0x01, 0x06, 0x04, 0x60, 0x01, 0x06, 0x04, 0x40, 0x2a, 0x07, 0x05, 0xe0, 0x15, 0x08, 0x05, 0xe0, 0x06, 0x09, 0x05, 0xc0, 0x19, 0x0b, 0x06, 0x00, 0x1b, 0x0e, 0x07, + 0x00, 0x10, 0x15, 0x09, 0xa0, 0x26, 0x00, 0x04, 0xb0, 0x26, 0x00, 0x04, 0xa8, 0x1f, 0x01, 0x03, 0xb0, 0x1f, 0x01, 0x03, 0xb8, 0x1f, 0x01, 0x03, 0xc0, 0x1f, 0x01, 0x03, 0x58, 0x0d, 0x02, 0x03, + 0x60, 0x0d, 0x02, 0x03, 0x68, 0x0d, 0x02, 0x03, 0x70, 0x0d, 0x02, 0x03, 0xe0, 0x3c, 0x03, 0x04, 0xf0, 0x3c, 0x03, 0x04, 0x30, 0x25, 0x04, 0x04, 0x40, 0x25, 0x04, 0x04, 0x50, 0x25, 0x04, 0x04, + 0x40, 0x11, 0x05, 0x04, 0x70, 0x01, 0x06, 0x04, 0x80, 0x01, 0x06, 0x04, 0x60, 0x2a, 0x07, 0x05, 0x00, 0x16, 0x08, 0x05, 0x00, 0x07, 0x09, 0x05, 0x00, 0x1a, 0x0b, 0x06, 0x80, 0x1b, 0x0e, 0x07, + 0x00, 0x12, 0x15, 0x09, 0xc0, 0x26, 0x00, 0x04, 0xd0, 0x26, 0x00, 0x04, 0xc8, 0x1f, 0x01, 0x03, 0xd0, 0x1f, 0x01, 0x03, 0xd8, 0x1f, 0x01, 0x03, 0xe0, 0x1f, 0x01, 0x03, 0x78, 0x0d, 0x02, 0x03, + 0x80, 0x0d, 0x02, 0x03, 0x88, 0x0d, 0x02, 0x03, 0x90, 0x0d, 0x02, 0x03, 0x00, 0x3d, 0x03, 0x04, 0x10, 0x3d, 0x03, 0x04, 0x60, 0x25, 0x04, 0x04, 0x70, 0x25, 0x04, 0x04, 0x50, 0x11, 0x05, 0x04, + 0x60, 0x11, 0x05, 0x04, 0x90, 0x01, 0x06, 0x04, 0xa0, 0x01, 0x06, 0x04, 0x80, 0x2a, 0x07, 0x05, 0x20, 0x16, 0x08, 0x05, 0x20, 0x07, 0x09, 0x05, 0x40, 0x1a, 0x0b, 0x06, 0x00, 0x1c, 0x0e, 0x07, + 0x00, 0x14, 0x15, 0x09, 0xe0, 0x26, 0x00, 0x04, 0xf0, 0x26, 0x00, 0x04, 0xe8, 0x1f, 0x01, 0x03, 0xf0, 0x1f, 0x01, 0x03, 0xf8, 0x1f, 0x01, 0x03, 0x00, 0x20, 0x01, 0x03, 0x98, 0x0d, 0x02, 0x03, + 0xa0, 0x0d, 0x02, 0x03, 0xa8, 0x0d, 0x02, 0x03, 0xb0, 0x0d, 0x02, 0x03, 0x20, 0x3d, 0x03, 0x04, 0x30, 0x3d, 0x03, 0x04, 0x80, 0x25, 0x04, 0x04, 0x90, 0x25, 0x04, 0x04, 0x70, 0x11, 0x05, 0x04, + 0x80, 0x11, 0x05, 0x04, 0xb0, 0x01, 0x06, 0x04, 0xc0, 0x01, 0x06, 0x04, 0xa0, 0x2a, 0x07, 0x05, 0x40, 0x16, 0x08, 0x05, 0x40, 0x07, 0x09, 0x05, 0x80, 0x1a, 0x0b, 0x06, 0x80, 0x1c, 0x0e, 0x07, + 0x00, 0x16, 0x15, 0x09, 0x00, 0x27, 0x00, 0x04, 0x10, 0x27, 0x00, 0x04, 0x08, 0x20, 0x01, 0x03, 0x10, 0x20, 0x01, 0x03, 0x18, 0x20, 0x01, 0x03, 0x20, 0x20, 0x01, 0x03, 0xb8, 0x0d, 0x02, 0x03, + 0xc0, 0x0d, 0x02, 0x03, 0xc8, 0x0d, 0x02, 0x03, 0xd0, 0x0d, 0x02, 0x03, 0x40, 0x3d, 0x03, 0x04, 0x50, 0x3d, 0x03, 0x04, 0xa0, 0x25, 0x04, 0x04, 0xb0, 0x25, 0x04, 0x04, 0x90, 0x11, 0x05, 0x04, + 0xa0, 0x11, 0x05, 0x04, 0xd0, 0x01, 0x06, 0x04, 0xe0, 0x01, 0x06, 0x04, 0xc0, 0x2a, 0x07, 0x05, 0x60, 0x16, 0x08, 0x05, 0x60, 0x07, 0x09, 0x05, 0xc0, 0x1a, 0x0b, 0x06, 0x00, 0x1d, 0x0e, 0x07, + 0x00, 0x18, 0x15, 0x09, 0x20, 0x27, 0x00, 0x04, 0x30, 0x27, 0x00, 0x04, 0x28, 0x20, 0x01, 0x03, 0x30, 0x20, 0x01, 0x03, 0x38, 0x20, 0x01, 0x03, 0x40, 0x20, 0x01, 0x03, 0xd8, 0x0d, 0x02, 0x03, + 0xe0, 0x0d, 0x02, 0x03, 0xe8, 0x0d, 0x02, 0x03, 0xf0, 0x0d, 0x02, 0x03, 0x60, 0x3d, 0x03, 0x04, 0x70, 0x3d, 0x03, 0x04, 0xc0, 0x25, 0x04, 0x04, 0xd0, 0x25, 0x04, 0x04, 0xb0, 0x11, 0x05, 0x04, + 0xc0, 0x11, 0x05, 0x04, 0xf0, 0x01, 0x06, 0x04, 0x00, 0x02, 0x06, 0x04, 0xe0, 0x2a, 0x07, 0x05, 0x80, 0x16, 0x08, 0x05, 0x80, 0x07, 0x09, 0x05, 0x00, 0x1b, 0x0b, 0x06, 0x80, 0x1d, 0x0e, 0x07, + 0x00, 0x00, 0x16, 0x09, 0x40, 0x27, 0x00, 0x04, 0x50, 0x27, 0x00, 0x04, 0x48, 0x20, 0x01, 0x03, 0x50, 0x20, 0x01, 0x03, 0x58, 0x20, 0x01, 0x03, 0x60, 0x20, 0x01, 0x03, 0xf8, 0x0d, 0x02, 0x03, + 0x00, 0x0e, 0x02, 0x03, 0x08, 0x0e, 0x02, 0x03, 0x10, 0x0e, 0x02, 0x03, 0x80, 0x3d, 0x03, 0x04, 0x90, 0x3d, 0x03, 0x04, 0xe0, 0x25, 0x04, 0x04, 0xf0, 0x25, 0x04, 0x04, 0xd0, 0x11, 0x05, 0x04, + 0xe0, 0x11, 0x05, 0x04, 0x10, 0x02, 0x06, 0x04, 0x20, 0x02, 0x06, 0x04, 0x00, 0x2b, 0x07, 0x05, 0xa0, 0x16, 0x08, 0x05, 0xa0, 0x07, 0x09, 0x05, 0x40, 0x1b, 0x0b, 0x06, 0x00, 0x1e, 0x0e, 0x07, + 0x00, 0x02, 0x16, 0x09, 0x60, 0x27, 0x00, 0x04, 0x70, 0x27, 0x00, 0x04, 0x68, 0x20, 0x01, 0x03, 0x70, 0x20, 0x01, 0x03, 0x78, 0x20, 0x01, 0x03, 0x80, 0x20, 0x01, 0x03, 0x18, 0x0e, 0x02, 0x03, + 0x20, 0x0e, 0x02, 0x03, 0x28, 0x0e, 0x02, 0x03, 0x30, 0x0e, 0x02, 0x03, 0xa0, 0x3d, 0x03, 0x04, 0xb0, 0x3d, 0x03, 0x04, 0x00, 0x26, 0x04, 0x04, 0x10, 0x26, 0x04, 0x04, 0xf0, 0x11, 0x05, 0x04, + 0x00, 0x12, 0x05, 0x04, 0x30, 0x02, 0x06, 0x04, 0x40, 0x02, 0x06, 0x04, 0x20, 0x2b, 0x07, 0x05, 0xc0, 0x16, 0x08, 0x05, 0xc0, 0x07, 0x09, 0x05, 0x80, 0x1b, 0x0b, 0x06, 0x80, 0x1e, 0x0e, 0x07, + 0x00, 0x04, 0x16, 0x09, 0x80, 0x27, 0x00, 0x04, 0x90, 0x27, 0x00, 0x04, 0x88, 0x20, 0x01, 0x03, 0x90, 0x20, 0x01, 0x03, 0x98, 0x20, 0x01, 0x03, 0xa0, 0x20, 0x01, 0x03, 0x38, 0x0e, 0x02, 0x03, + 0x40, 0x0e, 0x02, 0x03, 0x48, 0x0e, 0x02, 0x03, 0xc0, 0x3d, 0x03, 0x04, 0xd0, 0x3d, 0x03, 0x04, 0xe0, 0x3d, 0x03, 0x04, 0x20, 0x26, 0x04, 0x04, 0x30, 0x26, 0x04, 0x04, 0x10, 0x12, 0x05, 0x04, + 0x20, 0x12, 0x05, 0x04, 0x50, 0x02, 0x06, 0x04, 0x60, 0x02, 0x06, 0x04, 0x40, 0x2b, 0x07, 0x05, 0xe0, 0x16, 0x08, 0x05, 0xe0, 0x07, 0x09, 0x05, 0xc0, 0x1b, 0x0b, 0x06, 0x00, 0x1f, 0x0e, 0x07, + 0x00, 0x06, 0x16, 0x09, 0xa0, 0x27, 0x00, 0x04, 0xb0, 0x27, 0x00, 0x04, 0xa8, 0x20, 0x01, 0x03, 0xb0, 0x20, 0x01, 0x03, 0xb8, 0x20, 0x01, 0x03, 0xc0, 0x20, 0x01, 0x03, 0x50, 0x0e, 0x02, 0x03, + 0x58, 0x0e, 0x02, 0x03, 0x60, 0x0e, 0x02, 0x03, 0xf0, 0x3d, 0x03, 0x04, 0x00, 0x3e, 0x03, 0x04, 0x10, 0x3e, 0x03, 0x04, 0x40, 0x26, 0x04, 0x04, 0x50, 0x26, 0x04, 0x04, 0x30, 0x12, 0x05, 0x04, + 0x40, 0x12, 0x05, 0x04, 0x70, 0x02, 0x06, 0x04, 0x80, 0x02, 0x06, 0x04, 0x60, 0x2b, 0x07, 0x05, 0x00, 0x17, 0x08, 0x05, 0x00, 0x30, 0x0a, 0x06, 0x00, 0x1c, 0x0b, 0x06, 0x80, 0x1f, 0x0e, 0x07, + 0x00, 0x28, 0x17, 0x0a, 0xc0, 0x27, 0x00, 0x04, 0xd0, 0x27, 0x00, 0x04, 0xc8, 0x20, 0x01, 0x03, 0xd0, 0x20, 0x01, 0x03, 0xd8, 0x20, 0x01, 0x03, 0xe0, 0x20, 0x01, 0x03, 0x68, 0x0e, 0x02, 0x03, + 0x70, 0x0e, 0x02, 0x03, 0x78, 0x0e, 0x02, 0x03, 0x20, 0x3e, 0x03, 0x04, 0x30, 0x3e, 0x03, 0x04, 0x40, 0x3e, 0x03, 0x04, 0x60, 0x26, 0x04, 0x04, 0x70, 0x26, 0x04, 0x04, 0x50, 0x12, 0x05, 0x04, + 0x60, 0x12, 0x05, 0x04, 0x90, 0x02, 0x06, 0x04, 0xa0, 0x02, 0x06, 0x04, 0x80, 0x2b, 0x07, 0x05, 0x20, 0x17, 0x08, 0x05, 0x40, 0x30, 0x0a, 0x06, 0x40, 0x1c, 0x0b, 0x06, 0x00, 0x20, 0x0e, 0x07, + 0x00, 0x2c, 0x17, 0x0a, 0xe0, 0x27, 0x00, 0x04, 0xf0, 0x27, 0x00, 0x04, 0xe8, 0x20, 0x01, 0x03, 0xf0, 0x20, 0x01, 0x03, 0xf8, 0x20, 0x01, 0x03, 0x00, 0x21, 0x01, 0x03, 0x80, 0x0e, 0x02, 0x03, + 0x88, 0x0e, 0x02, 0x03, 0x90, 0x0e, 0x02, 0x03, 0x50, 0x3e, 0x03, 0x04, 0x60, 0x3e, 0x03, 0x04, 0x70, 0x3e, 0x03, 0x04, 0x80, 0x26, 0x04, 0x04, 0x90, 0x26, 0x04, 0x04, 0x70, 0x12, 0x05, 0x04, + 0x80, 0x12, 0x05, 0x04, 0xb0, 0x02, 0x06, 0x04, 0xc0, 0x02, 0x06, 0x04, 0xa0, 0x2b, 0x07, 0x05, 0x40, 0x17, 0x08, 0x05, 0x80, 0x30, 0x0a, 0x06, 0x80, 0x1c, 0x0b, 0x06, 0x80, 0x20, 0x0e, 0x07, + 0x00, 0x30, 0x17, 0x0a, 0x00, 0x28, 0x00, 0x04, 0x10, 0x28, 0x00, 0x04, 0x08, 0x21, 0x01, 0x03, 0x10, 0x21, 0x01, 0x03, 0x18, 0x21, 0x01, 0x03, 0x20, 0x21, 0x01, 0x03, 0x98, 0x0e, 0x02, 0x03, + 0xa0, 0x0e, 0x02, 0x03, 0xa8, 0x0e, 0x02, 0x03, 0x80, 0x3e, 0x03, 0x04, 0x90, 0x3e, 0x03, 0x04, 0xa0, 0x3e, 0x03, 0x04, 0xa0, 0x26, 0x04, 0x04, 0xb0, 0x26, 0x04, 0x04, 0x90, 0x12, 0x05, 0x04, + 0xa0, 0x12, 0x05, 0x04, 0xd0, 0x02, 0x06, 0x04, 0xe0, 0x02, 0x06, 0x04, 0xc0, 0x2b, 0x07, 0x05, 0x60, 0x17, 0x08, 0x05, 0xc0, 0x30, 0x0a, 0x06, 0xc0, 0x1c, 0x0b, 0x06, 0x00, 0x21, 0x0e, 0x07, + 0x00, 0x34, 0x17, 0x0a, 0x20, 0x28, 0x00, 0x04, 0x30, 0x28, 0x00, 0x04, 0x28, 0x21, 0x01, 0x03, 0x30, 0x21, 0x01, 0x03, 0x38, 0x21, 0x01, 0x03, 0x40, 0x21, 0x01, 0x03, 0xb0, 0x0e, 0x02, 0x03, + 0xb8, 0x0e, 0x02, 0x03, 0xc0, 0x0e, 0x02, 0x03, 0xb0, 0x3e, 0x03, 0x04, 0xc0, 0x3e, 0x03, 0x04, 0xd0, 0x3e, 0x03, 0x04, 0xc0, 0x26, 0x04, 0x04, 0xd0, 0x26, 0x04, 0x04, 0xb0, 0x12, 0x05, 0x04, + 0xc0, 0x12, 0x05, 0x04, 0xf0, 0x02, 0x06, 0x04, 0x00, 0x03, 0x06, 0x04, 0xe0, 0x2b, 0x07, 0x05, 0x80, 0x17, 0x08, 0x05, 0x00, 0x31, 0x0a, 0x06, 0x00, 0x1d, 0x0b, 0x06, 0x80, 0x21, 0x0e, 0x07, + 0x00, 0x14, 0x18, 0x0a, 0x40, 0x28, 0x00, 0x04, 0x50, 0x28, 0x00, 0x04, 0x48, 0x21, 0x01, 0x03, 0x50, 0x21, 0x01, 0x03, 0x58, 0x21, 0x01, 0x03, 0x60, 0x21, 0x01, 0x03, 0xc8, 0x0e, 0x02, 0x03, + 0xd0, 0x0e, 0x02, 0x03, 0xd8, 0x0e, 0x02, 0x03, 0xe0, 0x3e, 0x03, 0x04, 0xf0, 0x3e, 0x03, 0x04, 0x00, 0x3f, 0x03, 0x04, 0xe0, 0x26, 0x04, 0x04, 0xf0, 0x26, 0x04, 0x04, 0xd0, 0x12, 0x05, 0x04, + 0xe0, 0x12, 0x05, 0x04, 0x10, 0x03, 0x06, 0x04, 0x20, 0x03, 0x06, 0x04, 0x00, 0x2c, 0x07, 0x05, 0xa0, 0x17, 0x08, 0x05, 0x40, 0x31, 0x0a, 0x06, 0x40, 0x1d, 0x0b, 0x06, 0x00, 0x22, 0x0e, 0x07, + 0x00, 0x18, 0x18, 0x0a, 0x60, 0x28, 0x00, 0x04, 0x70, 0x28, 0x00, 0x04, 0x68, 0x21, 0x01, 0x03, 0x70, 0x21, 0x01, 0x03, 0x78, 0x21, 0x01, 0x03, 0x80, 0x21, 0x01, 0x03, 0xe0, 0x0e, 0x02, 0x03, + 0xe8, 0x0e, 0x02, 0x03, 0xf0, 0x0e, 0x02, 0x03, 0x10, 0x3f, 0x03, 0x04, 0x20, 0x3f, 0x03, 0x04, 0x30, 0x3f, 0x03, 0x04, 0x00, 0x27, 0x04, 0x04, 0x10, 0x27, 0x04, 0x04, 0xf0, 0x12, 0x05, 0x04, + 0x00, 0x13, 0x05, 0x04, 0x30, 0x03, 0x06, 0x04, 0x40, 0x03, 0x06, 0x04, 0x20, 0x2c, 0x07, 0x05, 0xc0, 0x17, 0x08, 0x05, 0x80, 0x31, 0x0a, 0x06, 0x80, 0x1d, 0x0b, 0x06, 0x80, 0x22, 0x0e, 0x07, + 0x00, 0x04, 0x19, 0x0a, 0x80, 0x28, 0x00, 0x04, 0x90, 0x28, 0x00, 0x04, 0x88, 0x21, 0x01, 0x03, 0x90, 0x21, 0x01, 0x03, 0x98, 0x21, 0x01, 0x03, 0xa0, 0x21, 0x01, 0x03, 0xf8, 0x0e, 0x02, 0x03, + 0x00, 0x0f, 0x02, 0x03, 0x08, 0x0f, 0x02, 0x03, 0x40, 0x3f, 0x03, 0x04, 0x50, 0x3f, 0x03, 0x04, 0x60, 0x3f, 0x03, 0x04, 0x20, 0x27, 0x04, 0x04, 0x30, 0x27, 0x04, 0x04, 0x10, 0x13, 0x05, 0x04, + 0x20, 0x13, 0x05, 0x04, 0x50, 0x03, 0x06, 0x04, 0x60, 0x03, 0x06, 0x04, 0x40, 0x2c, 0x07, 0x05, 0xe0, 0x17, 0x08, 0x05, 0xc0, 0x31, 0x0a, 0x06, 0xc0, 0x1d, 0x0b, 0x06, 0x00, 0x23, 0x0e, 0x07, + 0x00, 0x08, 0x19, 0x0a, 0xa0, 0x28, 0x00, 0x04, 0xb0, 0x28, 0x00, 0x04, 0xa8, 0x21, 0x01, 0x03, 0xb0, 0x21, 0x01, 0x03, 0xb8, 0x21, 0x01, 0x03, 0xc0, 0x21, 0x01, 0x03, 0x10, 0x0f, 0x02, 0x03, + 0x18, 0x0f, 0x02, 0x03, 0x20, 0x0f, 0x02, 0x03, 0x70, 0x3f, 0x03, 0x04, 0x80, 0x3f, 0x03, 0x04, 0x90, 0x3f, 0x03, 0x04, 0x40, 0x27, 0x04, 0x04, 0x50, 0x27, 0x04, 0x04, 0x30, 0x13, 0x05, 0x04, + 0x40, 0x13, 0x05, 0x04, 0x70, 0x03, 0x06, 0x04, 0x80, 0x03, 0x06, 0x04, 0x60, 0x2c, 0x07, 0x05, 0x00, 0x18, 0x08, 0x05, 0x00, 0x32, 0x0a, 0x06, 0x00, 0x1e, 0x0b, 0x06, 0x00, 0x0c, 0x0f, 0x07, + 0x00, 0x30, 0x1a, 0x0b, 0xc0, 0x28, 0x00, 0x04, 0xd0, 0x28, 0x00, 0x04, 0xc8, 0x21, 0x01, 0x03, 0xd0, 0x21, 0x01, 0x03, 0xd8, 0x21, 0x01, 0x03, 0xe0, 0x21, 0x01, 0x03, 0x28, 0x0f, 0x02, 0x03, + 0x30, 0x0f, 0x02, 0x03, 0x38, 0x0f, 0x02, 0x03, 0xa0, 0x3f, 0x03, 0x04, 0xb0, 0x3f, 0x03, 0x04, 0xc0, 0x3f, 0x03, 0x04, 0x60, 0x27, 0x04, 0x04, 0x70, 0x27, 0x04, 0x04, 0x50, 0x13, 0x05, 0x04, + 0x60, 0x13, 0x05, 0x04, 0x90, 0x03, 0x06, 0x04, 0xa0, 0x03, 0x06, 0x04, 0x80, 0x2c, 0x07, 0x05, 0x20, 0x18, 0x08, 0x05, 0x40, 0x32, 0x0a, 0x06, 0x40, 0x0a, 0x0c, 0x06, 0x80, 0x0c, 0x0f, 0x07, + 0x00, 0x38, 0x1a, 0x0b, 0xe0, 0x28, 0x00, 0x04, 0xf0, 0x28, 0x00, 0x04, 0xe8, 0x21, 0x01, 0x03, 0xf0, 0x21, 0x01, 0x03, 0xf8, 0x21, 0x01, 0x03, 0x00, 0x22, 0x01, 0x03, 0x40, 0x0f, 0x02, 0x03, + 0x48, 0x0f, 0x02, 0x03, 0x50, 0x0f, 0x02, 0x03, 0xd0, 0x3f, 0x03, 0x04, 0xe0, 0x3f, 0x03, 0x04, 0xf0, 0x3f, 0x03, 0x04, 0x80, 0x27, 0x04, 0x04, 0x90, 0x27, 0x04, 0x04, 0x70, 0x13, 0x05, 0x04, + 0x80, 0x13, 0x05, 0x04, 0xb0, 0x03, 0x06, 0x04, 0xc0, 0x03, 0x06, 0x04, 0xa0, 0x2c, 0x07, 0x05, 0x40, 0x18, 0x08, 0x05, 0x80, 0x32, 0x0a, 0x06, 0x80, 0x0a, 0x0c, 0x06, 0x00, 0x0d, 0x0f, 0x07, + 0x00, 0x18, 0x1b, 0x0b, 0x00, 0x29, 0x00, 0x04, 0x10, 0x29, 0x00, 0x04, 0x08, 0x22, 0x01, 0x03, 0x10, 0x22, 0x01, 0x03, 0x18, 0x22, 0x01, 0x03, 0x20, 0x22, 0x01, 0x03, 0x58, 0x0f, 0x02, 0x03, + 0x60, 0x0f, 0x02, 0x03, 0x68, 0x0f, 0x02, 0x03, 0x00, 0x00, 0x03, 0x03, 0x08, 0x00, 0x03, 0x03, 0x10, 0x00, 0x03, 0x03, 0xa0, 0x27, 0x04, 0x04, 0xb0, 0x27, 0x04, 0x04, 0x90, 0x13, 0x05, 0x04, + 0xa0, 0x13, 0x05, 0x04, 0xd0, 0x03, 0x06, 0x04, 0xc0, 0x2c, 0x07, 0x05, 0xe0, 0x2c, 0x07, 0x05, 0x60, 0x18, 0x08, 0x05, 0xc0, 0x32, 0x0a, 0x06, 0xc0, 0x0a, 0x0c, 0x06, 0x80, 0x0d, 0x0f, 0x07, + 0x00, 0x20, 0x1b, 0x0b, 0x20, 0x29, 0x00, 0x04, 0x30, 0x29, 0x00, 0x04, 0x28, 0x22, 0x01, 0x03, 0x30, 0x22, 0x01, 0x03, 0x38, 0x22, 0x01, 0x03, 0x40, 0x22, 0x01, 0x03, 0x70, 0x0f, 0x02, 0x03, + 0x78, 0x0f, 0x02, 0x03, 0x80, 0x0f, 0x02, 0x03, 0x18, 0x00, 0x03, 0x03, 0x20, 0x00, 0x03, 0x03, 0x28, 0x00, 0x03, 0x03, 0xc0, 0x27, 0x04, 0x04, 0xd0, 0x27, 0x04, 0x04, 0xb0, 0x13, 0x05, 0x04, + 0xc0, 0x13, 0x05, 0x04, 0xe0, 0x03, 0x06, 0x04, 0x00, 0x2d, 0x07, 0x05, 0x20, 0x2d, 0x07, 0x05, 0x80, 0x18, 0x08, 0x05, 0x00, 0x33, 0x0a, 0x06, 0x00, 0x0b, 0x0c, 0x06, 0x00, 0x0e, 0x0f, 0x07, + 0x00, 0x08, 0x1c, 0x0b, 0x40, 0x29, 0x00, 0x04, 0x50, 0x29, 0x00, 0x04, 0x48, 0x22, 0x01, 0x03, 0x50, 0x22, 0x01, 0x03, 0x58, 0x22, 0x01, 0x03, 0x60, 0x22, 0x01, 0x03, 0x88, 0x0f, 0x02, 0x03, + 0x90, 0x0f, 0x02, 0x03, 0x98, 0x0f, 0x02, 0x03, 0x30, 0x00, 0x03, 0x03, 0x38, 0x00, 0x03, 0x03, 0x40, 0x00, 0x03, 0x03, 0xe0, 0x27, 0x04, 0x04, 0xf0, 0x27, 0x04, 0x04, 0xd0, 0x13, 0x05, 0x04, + 0xe0, 0x13, 0x05, 0x04, 0xf0, 0x03, 0x06, 0x04, 0x40, 0x2d, 0x07, 0x05, 0x60, 0x2d, 0x07, 0x05, 0xa0, 0x18, 0x08, 0x05, 0x40, 0x33, 0x0a, 0x06, 0x40, 0x0b, 0x0c, 0x06, 0x80, 0x0e, 0x0f, 0x07, + 0x00, 0x30, 0x1d, 0x0c, 0x60, 0x29, 0x00, 0x04, 0x70, 0x29, 0x00, 0x04, 0x68, 0x22, 0x01, 0x03, 0x70, 0x22, 0x01, 0x03, 0x78, 0x22, 0x01, 0x03, 0x80, 0x22, 0x01, 0x03, 0xa0, 0x0f, 0x02, 0x03, + 0xa8, 0x0f, 0x02, 0x03, 0xb0, 0x0f, 0x02, 0x03, 0x48, 0x00, 0x03, 0x03, 0x50, 0x00, 0x03, 0x03, 0x58, 0x00, 0x03, 0x03, 0x00, 0x28, 0x04, 0x04, 0x10, 0x28, 0x04, 0x04, 0xf0, 0x13, 0x05, 0x04, + 0x00, 0x14, 0x05, 0x04, 0x00, 0x04, 0x06, 0x04, 0x80, 0x2d, 0x07, 0x05, 0xa0, 0x2d, 0x07, 0x05, 0xc0, 0x18, 0x08, 0x05, 0x80, 0x33, 0x0a, 0x06, 0x80, 0x0b, 0x0c, 0x06, 0x00, 0x0f, 0x0f, 0x07, + 0x00, 0x20, 0x1e, 0x0c, 0x80, 0x29, 0x00, 0x04, 0x90, 0x29, 0x00, 0x04, 0x88, 0x22, 0x01, 0x03, 0x90, 0x22, 0x01, 0x03, 0x98, 0x22, 0x01, 0x03, 0xa0, 0x22, 0x01, 0x03, 0xb8, 0x0f, 0x02, 0x03, + 0xc0, 0x0f, 0x02, 0x03, 0xc8, 0x0f, 0x02, 0x03, 0x60, 0x00, 0x03, 0x03, 0x68, 0x00, 0x03, 0x03, 0x70, 0x00, 0x03, 0x03, 0x20, 0x28, 0x04, 0x04, 0x30, 0x28, 0x04, 0x04, 0x10, 0x14, 0x05, 0x04, + 0x20, 0x14, 0x05, 0x04, 0x10, 0x04, 0x06, 0x04, 0xc0, 0x2d, 0x07, 0x05, 0xe0, 0x2d, 0x07, 0x05, 0xe0, 0x18, 0x08, 0x05, 0xc0, 0x33, 0x0a, 0x06, 0xc0, 0x0b, 0x0c, 0x06, 0x80, 0x0f, 0x0f, 0x07, + 0x00, 0x10, 0x1f, 0x0c, 0xa0, 0x29, 0x00, 0x04, 0xb0, 0x29, 0x00, 0x04, 0xa8, 0x22, 0x01, 0x03, 0xb0, 0x22, 0x01, 0x03, 0xb8, 0x22, 0x01, 0x03, 0xc0, 0x22, 0x01, 0x03, 0xd0, 0x0f, 0x02, 0x03, + 0xd8, 0x0f, 0x02, 0x03, 0xe0, 0x0f, 0x02, 0x03, 0x78, 0x00, 0x03, 0x03, 0x80, 0x00, 0x03, 0x03, 0x88, 0x00, 0x03, 0x03, 0x40, 0x28, 0x04, 0x04, 0x50, 0x28, 0x04, 0x04, 0x30, 0x14, 0x05, 0x04, + 0x40, 0x14, 0x05, 0x04, 0x20, 0x04, 0x06, 0x04, 0x00, 0x2e, 0x07, 0x05, 0x20, 0x2e, 0x07, 0x05, 0x00, 0x19, 0x08, 0x05, 0x00, 0x34, 0x0a, 0x06, 0x00, 0x0c, 0x0c, 0x06, 0x00, 0x10, 0x0f, 0x07, + 0x00, 0x20, 0x21, 0x0d, 0xc0, 0x29, 0x00, 0x04, 0xd0, 0x29, 0x00, 0x04, 0xc8, 0x22, 0x01, 0x03, 0xd0, 0x22, 0x01, 0x03, 0xd8, 0x22, 0x01, 0x03, 0xe0, 0x22, 0x01, 0x03, 0xe8, 0x0f, 0x02, 0x03, + 0xf0, 0x0f, 0x02, 0x03, 0xf8, 0x0f, 0x02, 0x03, 0x90, 0x00, 0x03, 0x03, 0x98, 0x00, 0x03, 0x03, 0xa0, 0x00, 0x03, 0x03, 0x60, 0x28, 0x04, 0x04, 0x70, 0x28, 0x04, 0x04, 0x50, 0x14, 0x05, 0x04, + 0x60, 0x14, 0x05, 0x04, 0x30, 0x04, 0x06, 0x04, 0x40, 0x2e, 0x07, 0x05, 0x60, 0x2e, 0x07, 0x05, 0x20, 0x19, 0x08, 0x05, 0x40, 0x34, 0x0a, 0x06, 0x40, 0x0c, 0x0c, 0x06, 0x80, 0x10, 0x0f, 0x07, + 0x00, 0x00, 0x23, 0x0d, 0xe0, 0x29, 0x00, 0x04, 0xf0, 0x29, 0x00, 0x04, 0xe8, 0x22, 0x01, 0x03, 0xf0, 0x22, 0x01, 0x03, 0xf8, 0x22, 0x01, 0x03, 0x00, 0x23, 0x01, 0x03, 0x00, 0x10, 0x02, 0x03, + 0x08, 0x10, 0x02, 0x03, 0x10, 0x10, 0x02, 0x03, 0xa8, 0x00, 0x03, 0x03, 0xb0, 0x00, 0x03, 0x03, 0xb8, 0x00, 0x03, 0x03, 0x80, 0x28, 0x04, 0x04, 0x90, 0x28, 0x04, 0x04, 0x70, 0x14, 0x05, 0x04, + 0x80, 0x14, 0x05, 0x04, 0x40, 0x04, 0x06, 0x04, 0x80, 0x2e, 0x07, 0x05, 0xa0, 0x2e, 0x07, 0x05, 0x40, 0x19, 0x08, 0x05, 0x80, 0x34, 0x0a, 0x06, 0x80, 0x0c, 0x0c, 0x06, 0x00, 0x11, 0x0f, 0x07, + 0x00, 0x2a, 0x00, 0x04, 0x10, 0x2a, 0x00, 0x04, 0x20, 0x2a, 0x00, 0x04, 0x08, 0x23, 0x01, 0x03, 0x10, 0x23, 0x01, 0x03, 0x18, 0x23, 0x01, 0x03, 0x20, 0x23, 0x01, 0x03, 0x18, 0x10, 0x02, 0x03, + 0x20, 0x10, 0x02, 0x03, 0x28, 0x10, 0x02, 0x03, 0xc0, 0x00, 0x03, 0x03, 0xc8, 0x00, 0x03, 0x03, 0xd0, 0x00, 0x03, 0x03, 0xa0, 0x28, 0x04, 0x04, 0xb0, 0x28, 0x04, 0x04, 0x90, 0x14, 0x05, 0x04, + 0xa0, 0x14, 0x05, 0x04, 0x50, 0x04, 0x06, 0x04, 0xc0, 0x2e, 0x07, 0x05, 0xe0, 0x2e, 0x07, 0x05, 0x60, 0x19, 0x08, 0x05, 0xc0, 0x34, 0x0a, 0x06, 0xc0, 0x0c, 0x0c, 0x06, 0x80, 0x11, 0x0f, 0x07, + 0x30, 0x2a, 0x00, 0x04, 0x40, 0x2a, 0x00, 0x04, 0x50, 0x2a, 0x00, 0x04, 0x28, 0x23, 0x01, 0x03, 0x30, 0x23, 0x01, 0x03, 0x38, 0x23, 0x01, 0x03, 0x40, 0x23, 0x01, 0x03, 0x30, 0x10, 0x02, 0x03, + 0x38, 0x10, 0x02, 0x03, 0x40, 0x10, 0x02, 0x03, 0xd8, 0x00, 0x03, 0x03, 0xe0, 0x00, 0x03, 0x03, 0xe8, 0x00, 0x03, 0x03, 0xc0, 0x28, 0x04, 0x04, 0xd0, 0x28, 0x04, 0x04, 0xb0, 0x14, 0x05, 0x04, + 0xc0, 0x14, 0x05, 0x04, 0x60, 0x04, 0x06, 0x04, 0x00, 0x2f, 0x07, 0x05, 0x20, 0x2f, 0x07, 0x05, 0x80, 0x19, 0x08, 0x05, 0x00, 0x35, 0x0a, 0x06, 0x00, 0x0d, 0x0c, 0x06, 0x00, 0x12, 0x0f, 0x07, + 0x60, 0x2a, 0x00, 0x04, 0x70, 0x2a, 0x00, 0x04, 0x80, 0x2a, 0x00, 0x04, 0x48, 0x23, 0x01, 0x03, 0x50, 0x23, 0x01, 0x03, 0x58, 0x23, 0x01, 0x03, 0x60, 0x23, 0x01, 0x03, 0x48, 0x10, 0x02, 0x03, + 0x50, 0x10, 0x02, 0x03, 0x58, 0x10, 0x02, 0x03, 0xf0, 0x00, 0x03, 0x03, 0xf8, 0x00, 0x03, 0x03, 0x00, 0x01, 0x03, 0x03, 0xe0, 0x28, 0x04, 0x04, 0xf0, 0x28, 0x04, 0x04, 0xd0, 0x14, 0x05, 0x04, + 0xe0, 0x14, 0x05, 0x04, 0x70, 0x04, 0x06, 0x04, 0x40, 0x2f, 0x07, 0x05, 0x60, 0x2f, 0x07, 0x05, 0x00, 0x08, 0x09, 0x05, 0x40, 0x35, 0x0a, 0x06, 0x40, 0x0d, 0x0c, 0x06, 0x80, 0x12, 0x0f, 0x07, + 0x90, 0x2a, 0x00, 0x04, 0xa0, 0x2a, 0x00, 0x04, 0xb0, 0x2a, 0x00, 0x04, 0x68, 0x23, 0x01, 0x03, 0x70, 0x23, 0x01, 0x03, 0x78, 0x23, 0x01, 0x03, 0x80, 0x23, 0x01, 0x03, 0x60, 0x10, 0x02, 0x03, + 0x68, 0x10, 0x02, 0x03, 0x70, 0x10, 0x02, 0x03, 0x08, 0x01, 0x03, 0x03, 0x10, 0x01, 0x03, 0x03, 0x18, 0x01, 0x03, 0x03, 0x00, 0x29, 0x04, 0x04, 0x10, 0x29, 0x04, 0x04, 0xf0, 0x14, 0x05, 0x04, + 0x00, 0x15, 0x05, 0x04, 0x80, 0x04, 0x06, 0x04, 0x80, 0x2f, 0x07, 0x05, 0xa0, 0x2f, 0x07, 0x05, 0x20, 0x08, 0x09, 0x05, 0x80, 0x35, 0x0a, 0x06, 0x80, 0x0d, 0x0c, 0x06, 0x00, 0x13, 0x0f, 0x07, + 0xc0, 0x2a, 0x00, 0x04, 0xd0, 0x2a, 0x00, 0x04, 0xe0, 0x2a, 0x00, 0x04, 0x88, 0x23, 0x01, 0x03, 0x90, 0x23, 0x01, 0x03, 0x98, 0x23, 0x01, 0x03, 0xa0, 0x23, 0x01, 0x03, 0x78, 0x10, 0x02, 0x03, + 0x80, 0x10, 0x02, 0x03, 0x88, 0x10, 0x02, 0x03, 0x20, 0x01, 0x03, 0x03, 0x28, 0x01, 0x03, 0x03, 0x30, 0x01, 0x03, 0x03, 0x20, 0x29, 0x04, 0x04, 0x30, 0x29, 0x04, 0x04, 0x10, 0x15, 0x05, 0x04, + 0x20, 0x15, 0x05, 0x04, 0x90, 0x04, 0x06, 0x04, 0xc0, 0x2f, 0x07, 0x05, 0xe0, 0x2f, 0x07, 0x05, 0x40, 0x08, 0x09, 0x05, 0xc0, 0x35, 0x0a, 0x06, 0xc0, 0x0d, 0x0c, 0x06, 0x80, 0x13, 0x0f, 0x07, + 0xf0, 0x2a, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x04, 0x10, 0x2b, 0x00, 0x04, 0xa8, 0x23, 0x01, 0x03, 0xb0, 0x23, 0x01, 0x03, 0xb8, 0x23, 0x01, 0x03, 0xc0, 0x23, 0x01, 0x03, 0x90, 0x10, 0x02, 0x03, + 0x98, 0x10, 0x02, 0x03, 0xa0, 0x10, 0x02, 0x03, 0x38, 0x01, 0x03, 0x03, 0x40, 0x01, 0x03, 0x03, 0x48, 0x01, 0x03, 0x03, 0x40, 0x29, 0x04, 0x04, 0x50, 0x29, 0x04, 0x04, 0x30, 0x15, 0x05, 0x04, + 0x40, 0x15, 0x05, 0x04, 0xa0, 0x04, 0x06, 0x04, 0x00, 0x30, 0x07, 0x05, 0x20, 0x30, 0x07, 0x05, 0x60, 0x08, 0x09, 0x05, 0x00, 0x36, 0x0a, 0x06, 0x00, 0x0e, 0x0c, 0x06, 0x00, 0x14, 0x0f, 0x07, + 0x20, 0x2b, 0x00, 0x04, 0x30, 0x2b, 0x00, 0x04, 0x40, 0x2b, 0x00, 0x04, 0xc8, 0x23, 0x01, 0x03, 0xd0, 0x23, 0x01, 0x03, 0xd8, 0x23, 0x01, 0x03, 0xe0, 0x23, 0x01, 0x03, 0xa8, 0x10, 0x02, 0x03, + 0xb0, 0x10, 0x02, 0x03, 0xb8, 0x10, 0x02, 0x03, 0x50, 0x01, 0x03, 0x03, 0x58, 0x01, 0x03, 0x03, 0x60, 0x01, 0x03, 0x03, 0x60, 0x29, 0x04, 0x04, 0x70, 0x29, 0x04, 0x04, 0x50, 0x15, 0x05, 0x04, + 0x60, 0x15, 0x05, 0x04, 0xb0, 0x04, 0x06, 0x04, 0x40, 0x30, 0x07, 0x05, 0x60, 0x30, 0x07, 0x05, 0x80, 0x08, 0x09, 0x05, 0x40, 0x36, 0x0a, 0x06, 0x40, 0x0e, 0x0c, 0x06, 0x80, 0x14, 0x0f, 0x07, + 0x50, 0x2b, 0x00, 0x04, 0x60, 0x2b, 0x00, 0x04, 0x70, 0x2b, 0x00, 0x04, 0xe8, 0x23, 0x01, 0x03, 0xf0, 0x23, 0x01, 0x03, 0xf8, 0x23, 0x01, 0x03, 0x00, 0x24, 0x01, 0x03, 0xc0, 0x10, 0x02, 0x03, + 0xc8, 0x10, 0x02, 0x03, 0xd0, 0x10, 0x02, 0x03, 0x68, 0x01, 0x03, 0x03, 0x70, 0x01, 0x03, 0x03, 0x78, 0x01, 0x03, 0x03, 0x80, 0x29, 0x04, 0x04, 0x90, 0x29, 0x04, 0x04, 0x70, 0x15, 0x05, 0x04, + 0x80, 0x15, 0x05, 0x04, 0xc0, 0x04, 0x06, 0x04, 0x80, 0x30, 0x07, 0x05, 0xa0, 0x19, 0x08, 0x05, 0xa0, 0x08, 0x09, 0x05, 0x80, 0x36, 0x0a, 0x06, 0x80, 0x0e, 0x0c, 0x06, 0x00, 0x15, 0x0f, 0x07, + 0x80, 0x2b, 0x00, 0x04, 0x90, 0x2b, 0x00, 0x04, 0xa0, 0x2b, 0x00, 0x04, 0x08, 0x24, 0x01, 0x03, 0x10, 0x24, 0x01, 0x03, 0x18, 0x24, 0x01, 0x03, 0x20, 0x24, 0x01, 0x03, 0xd8, 0x10, 0x02, 0x03, + 0xe0, 0x10, 0x02, 0x03, 0xe8, 0x10, 0x02, 0x03, 0x80, 0x01, 0x03, 0x03, 0x88, 0x01, 0x03, 0x03, 0x90, 0x01, 0x03, 0x03, 0xa0, 0x29, 0x04, 0x04, 0xb0, 0x29, 0x04, 0x04, 0x90, 0x15, 0x05, 0x04, + 0xa0, 0x15, 0x05, 0x04, 0xd0, 0x04, 0x06, 0x04, 0xa0, 0x30, 0x07, 0x05, 0xc0, 0x19, 0x08, 0x05, 0xc0, 0x08, 0x09, 0x05, 0xc0, 0x36, 0x0a, 0x06, 0xc0, 0x0e, 0x0c, 0x06, 0x80, 0x01, 0x10, 0x07, + 0xb0, 0x2b, 0x00, 0x04, 0xc0, 0x2b, 0x00, 0x04, 0xd0, 0x2b, 0x00, 0x04, 0x28, 0x24, 0x01, 0x03, 0x30, 0x24, 0x01, 0x03, 0x38, 0x24, 0x01, 0x03, 0x40, 0x24, 0x01, 0x03, 0xf0, 0x10, 0x02, 0x03, + 0xf8, 0x10, 0x02, 0x03, 0x00, 0x11, 0x02, 0x03, 0x98, 0x01, 0x03, 0x03, 0xa0, 0x01, 0x03, 0x03, 0xa8, 0x01, 0x03, 0x03, 0xc0, 0x29, 0x04, 0x04, 0xd0, 0x29, 0x04, 0x04, 0xb0, 0x15, 0x05, 0x04, + 0xc0, 0x15, 0x05, 0x04, 0xe0, 0x04, 0x06, 0x04, 0xc0, 0x30, 0x07, 0x05, 0xe0, 0x19, 0x08, 0x05, 0xe0, 0x08, 0x09, 0x05, 0x00, 0x37, 0x0a, 0x06, 0x00, 0x0f, 0x0c, 0x06, 0x00, 0x02, 0x10, 0x07, + 0xe0, 0x2b, 0x00, 0x04, 0xf0, 0x2b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x04, 0x48, 0x24, 0x01, 0x03, 0x50, 0x24, 0x01, 0x03, 0x58, 0x24, 0x01, 0x03, 0x60, 0x24, 0x01, 0x03, 0x08, 0x11, 0x02, 0x03, + 0x10, 0x11, 0x02, 0x03, 0x18, 0x11, 0x02, 0x03, 0xb0, 0x01, 0x03, 0x03, 0xb8, 0x01, 0x03, 0x03, 0xc0, 0x01, 0x03, 0x03, 0xe0, 0x29, 0x04, 0x04, 0xf0, 0x29, 0x04, 0x04, 0xd0, 0x15, 0x05, 0x04, + 0xe0, 0x15, 0x05, 0x04, 0xf0, 0x04, 0x06, 0x04, 0xe0, 0x30, 0x07, 0x05, 0x00, 0x1a, 0x08, 0x05, 0x00, 0x09, 0x09, 0x05, 0x40, 0x37, 0x0a, 0x06, 0x40, 0x0f, 0x0c, 0x06, 0x80, 0x02, 0x10, 0x07, + 0x10, 0x2c, 0x00, 0x04, 0x20, 0x2c, 0x00, 0x04, 0x30, 0x2c, 0x00, 0x04, 0x68, 0x24, 0x01, 0x03, 0x70, 0x24, 0x01, 0x03, 0x78, 0x24, 0x01, 0x03, 0x80, 0x24, 0x01, 0x03, 0x20, 0x11, 0x02, 0x03, + 0x28, 0x11, 0x02, 0x03, 0x30, 0x11, 0x02, 0x03, 0xc8, 0x01, 0x03, 0x03, 0xd0, 0x01, 0x03, 0x03, 0xd8, 0x01, 0x03, 0x03, 0x00, 0x2a, 0x04, 0x04, 0x10, 0x2a, 0x04, 0x04, 0xf0, 0x15, 0x05, 0x04, + 0x00, 0x16, 0x05, 0x04, 0x00, 0x05, 0x06, 0x04, 0x00, 0x31, 0x07, 0x05, 0x20, 0x1a, 0x08, 0x05, 0x20, 0x09, 0x09, 0x05, 0x80, 0x37, 0x0a, 0x06, 0x80, 0x0f, 0x0c, 0x06, 0x00, 0x03, 0x10, 0x07, + 0x40, 0x2c, 0x00, 0x04, 0x50, 0x2c, 0x00, 0x04, 0x60, 0x2c, 0x00, 0x04, 0x88, 0x24, 0x01, 0x03, 0x90, 0x24, 0x01, 0x03, 0x98, 0x24, 0x01, 0x03, 0xa0, 0x24, 0x01, 0x03, 0x38, 0x11, 0x02, 0x03, + 0x40, 0x11, 0x02, 0x03, 0x48, 0x11, 0x02, 0x03, 0xe0, 0x01, 0x03, 0x03, 0xe8, 0x01, 0x03, 0x03, 0xf0, 0x01, 0x03, 0x03, 0x20, 0x2a, 0x04, 0x04, 0x30, 0x2a, 0x04, 0x04, 0x10, 0x16, 0x05, 0x04, + 0x20, 0x16, 0x05, 0x04, 0x10, 0x05, 0x06, 0x04, 0x20, 0x31, 0x07, 0x05, 0x40, 0x1a, 0x08, 0x05, 0x40, 0x09, 0x09, 0x05, 0xc0, 0x37, 0x0a, 0x06, 0xc0, 0x0f, 0x0c, 0x06, 0x80, 0x03, 0x10, 0x07, + 0x70, 0x2c, 0x00, 0x04, 0x80, 0x2c, 0x00, 0x04, 0x90, 0x2c, 0x00, 0x04, 0xa8, 0x24, 0x01, 0x03, 0xb0, 0x24, 0x01, 0x03, 0xb8, 0x24, 0x01, 0x03, 0xc0, 0x24, 0x01, 0x03, 0x50, 0x11, 0x02, 0x03, + 0x58, 0x11, 0x02, 0x03, 0x60, 0x11, 0x02, 0x03, 0xf8, 0x01, 0x03, 0x03, 0x00, 0x02, 0x03, 0x03, 0x08, 0x02, 0x03, 0x03, 0x40, 0x2a, 0x04, 0x04, 0x50, 0x2a, 0x04, 0x04, 0x30, 0x16, 0x05, 0x04, + 0x40, 0x16, 0x05, 0x04, 0x20, 0x05, 0x06, 0x04, 0x40, 0x31, 0x07, 0x05, 0x60, 0x1a, 0x08, 0x05, 0x60, 0x09, 0x09, 0x05, 0x00, 0x38, 0x0a, 0x06, 0x00, 0x10, 0x0c, 0x06, 0x00, 0x04, 0x10, 0x07, + 0xa0, 0x2c, 0x00, 0x04, 0xb0, 0x2c, 0x00, 0x04, 0xc0, 0x2c, 0x00, 0x04, 0xc8, 0x24, 0x01, 0x03, 0xd0, 0x24, 0x01, 0x03, 0xd8, 0x24, 0x01, 0x03, 0xe0, 0x24, 0x01, 0x03, 0x68, 0x11, 0x02, 0x03, + 0x70, 0x11, 0x02, 0x03, 0x78, 0x11, 0x02, 0x03, 0x10, 0x02, 0x03, 0x03, 0x18, 0x02, 0x03, 0x03, 0x20, 0x02, 0x03, 0x03, 0x60, 0x2a, 0x04, 0x04, 0x70, 0x2a, 0x04, 0x04, 0x50, 0x16, 0x05, 0x04, + 0x60, 0x16, 0x05, 0x04, 0x30, 0x05, 0x06, 0x04, 0x60, 0x31, 0x07, 0x05, 0x80, 0x1a, 0x08, 0x05, 0x80, 0x09, 0x09, 0x05, 0x40, 0x38, 0x0a, 0x06, 0x40, 0x10, 0x0c, 0x06, 0x80, 0x04, 0x10, 0x07, + 0xd0, 0x2c, 0x00, 0x04, 0xe0, 0x2c, 0x00, 0x04, 0xf0, 0x2c, 0x00, 0x04, 0xe8, 0x24, 0x01, 0x03, 0xf0, 0x24, 0x01, 0x03, 0xf8, 0x24, 0x01, 0x03, 0x00, 0x25, 0x01, 0x03, 0x80, 0x11, 0x02, 0x03, + 0x88, 0x11, 0x02, 0x03, 0x90, 0x11, 0x02, 0x03, 0x28, 0x02, 0x03, 0x03, 0x30, 0x02, 0x03, 0x03, 0x38, 0x02, 0x03, 0x03, 0x80, 0x2a, 0x04, 0x04, 0x90, 0x2a, 0x04, 0x04, 0x70, 0x16, 0x05, 0x04, + 0x80, 0x16, 0x05, 0x04, 0x40, 0x05, 0x06, 0x04, 0x80, 0x31, 0x07, 0x05, 0xa0, 0x1a, 0x08, 0x05, 0xa0, 0x09, 0x09, 0x05, 0x80, 0x38, 0x0a, 0x06, 0x80, 0x10, 0x0c, 0x06, 0x00, 0x05, 0x10, 0x07, + 0x00, 0x2d, 0x00, 0x04, 0x10, 0x2d, 0x00, 0x04, 0x20, 0x2d, 0x00, 0x04, 0x08, 0x25, 0x01, 0x03, 0x10, 0x25, 0x01, 0x03, 0x18, 0x25, 0x01, 0x03, 0x20, 0x25, 0x01, 0x03, 0x98, 0x11, 0x02, 0x03, + 0xa0, 0x11, 0x02, 0x03, 0xa8, 0x11, 0x02, 0x03, 0x40, 0x02, 0x03, 0x03, 0x48, 0x02, 0x03, 0x03, 0x50, 0x02, 0x03, 0x03, 0xa0, 0x2a, 0x04, 0x04, 0xb0, 0x2a, 0x04, 0x04, 0x90, 0x16, 0x05, 0x04, + 0xa0, 0x16, 0x05, 0x04, 0x50, 0x05, 0x06, 0x04, 0xa0, 0x31, 0x07, 0x05, 0xc0, 0x1a, 0x08, 0x05, 0xc0, 0x09, 0x09, 0x05, 0xc0, 0x38, 0x0a, 0x06, 0xc0, 0x10, 0x0c, 0x06, 0x80, 0x05, 0x10, 0x07, + 0x30, 0x2d, 0x00, 0x04, 0x40, 0x2d, 0x00, 0x04, 0x50, 0x2d, 0x00, 0x04, 0x28, 0x25, 0x01, 0x03, 0x30, 0x25, 0x01, 0x03, 0x38, 0x25, 0x01, 0x03, 0x40, 0x25, 0x01, 0x03, 0xb0, 0x11, 0x02, 0x03, + 0xb8, 0x11, 0x02, 0x03, 0xc0, 0x11, 0x02, 0x03, 0x58, 0x02, 0x03, 0x03, 0x60, 0x02, 0x03, 0x03, 0x68, 0x02, 0x03, 0x03, 0xc0, 0x2a, 0x04, 0x04, 0xd0, 0x2a, 0x04, 0x04, 0xb0, 0x16, 0x05, 0x04, + 0xc0, 0x16, 0x05, 0x04, 0x60, 0x05, 0x06, 0x04, 0xc0, 0x31, 0x07, 0x05, 0xe0, 0x1a, 0x08, 0x05, 0xe0, 0x09, 0x09, 0x05, 0x00, 0x39, 0x0a, 0x06, 0x00, 0x11, 0x0c, 0x06, 0x00, 0x06, 0x10, 0x07, + 0x60, 0x2d, 0x00, 0x04, 0x70, 0x2d, 0x00, 0x04, 0x80, 0x2d, 0x00, 0x04, 0x48, 0x25, 0x01, 0x03, 0x50, 0x25, 0x01, 0x03, 0x58, 0x25, 0x01, 0x03, 0x60, 0x25, 0x01, 0x03, 0xc8, 0x11, 0x02, 0x03, + 0xd0, 0x11, 0x02, 0x03, 0xd8, 0x11, 0x02, 0x03, 0x70, 0x02, 0x03, 0x03, 0x78, 0x02, 0x03, 0x03, 0x80, 0x02, 0x03, 0x03, 0xe0, 0x2a, 0x04, 0x04, 0xf0, 0x2a, 0x04, 0x04, 0xd0, 0x16, 0x05, 0x04, + 0xe0, 0x16, 0x05, 0x04, 0x70, 0x05, 0x06, 0x04, 0xe0, 0x31, 0x07, 0x05, 0x00, 0x1b, 0x08, 0x05, 0x00, 0x0a, 0x09, 0x05, 0x40, 0x39, 0x0a, 0x06, 0x40, 0x11, 0x0c, 0x06, 0x80, 0x06, 0x10, 0x07, + 0x90, 0x2d, 0x00, 0x04, 0xa0, 0x2d, 0x00, 0x04, 0x68, 0x25, 0x01, 0x03, 0x70, 0x25, 0x01, 0x03, 0x78, 0x25, 0x01, 0x03, 0x80, 0x25, 0x01, 0x03, 0x88, 0x25, 0x01, 0x03, 0xe0, 0x11, 0x02, 0x03, + 0xe8, 0x11, 0x02, 0x03, 0xf0, 0x11, 0x02, 0x03, 0x88, 0x02, 0x03, 0x03, 0x90, 0x02, 0x03, 0x03, 0x98, 0x02, 0x03, 0x03, 0x00, 0x2b, 0x04, 0x04, 0x10, 0x2b, 0x04, 0x04, 0xf0, 0x16, 0x05, 0x04, + 0x00, 0x17, 0x05, 0x04, 0x80, 0x05, 0x06, 0x04, 0x00, 0x32, 0x07, 0x05, 0x20, 0x1b, 0x08, 0x05, 0x20, 0x0a, 0x09, 0x05, 0x80, 0x39, 0x0a, 0x06, 0x80, 0x11, 0x0c, 0x06, 0x00, 0x07, 0x10, 0x07, + 0xb0, 0x2d, 0x00, 0x04, 0xc0, 0x2d, 0x00, 0x04, 0x90, 0x25, 0x01, 0x03, 0x98, 0x25, 0x01, 0x03, 0xa0, 0x25, 0x01, 0x03, 0xa8, 0x25, 0x01, 0x03, 0xb0, 0x25, 0x01, 0x03, 0xf8, 0x11, 0x02, 0x03, + 0x00, 0x12, 0x02, 0x03, 0x08, 0x12, 0x02, 0x03, 0xa0, 0x02, 0x03, 0x03, 0xa8, 0x02, 0x03, 0x03, 0xb0, 0x02, 0x03, 0x03, 0x20, 0x2b, 0x04, 0x04, 0x30, 0x2b, 0x04, 0x04, 0x10, 0x17, 0x05, 0x04, + 0x20, 0x17, 0x05, 0x04, 0x90, 0x05, 0x06, 0x04, 0x20, 0x32, 0x07, 0x05, 0x40, 0x1b, 0x08, 0x05, 0x40, 0x0a, 0x09, 0x05, 0xc0, 0x39, 0x0a, 0x06, 0xc0, 0x11, 0x0c, 0x06, 0x80, 0x07, 0x10, 0x07, + 0xd0, 0x2d, 0x00, 0x04, 0xe0, 0x2d, 0x00, 0x04, 0xb8, 0x25, 0x01, 0x03, 0xc0, 0x25, 0x01, 0x03, 0xc8, 0x25, 0x01, 0x03, 0xd0, 0x25, 0x01, 0x03, 0xd8, 0x25, 0x01, 0x03, 0x10, 0x12, 0x02, 0x03, + 0x18, 0x12, 0x02, 0x03, 0x20, 0x12, 0x02, 0x03, 0xb8, 0x02, 0x03, 0x03, 0xc0, 0x02, 0x03, 0x03, 0xc8, 0x02, 0x03, 0x03, 0x40, 0x2b, 0x04, 0x04, 0x50, 0x2b, 0x04, 0x04, 0x30, 0x17, 0x05, 0x04, + 0x40, 0x17, 0x05, 0x04, 0xa0, 0x05, 0x06, 0x04, 0x40, 0x32, 0x07, 0x05, 0x60, 0x1b, 0x08, 0x05, 0x60, 0x0a, 0x09, 0x05, 0x00, 0x3a, 0x0a, 0x06, 0x00, 0x12, 0x0c, 0x06, 0x00, 0x08, 0x10, 0x07, + 0xf0, 0x2d, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x04, 0xe0, 0x25, 0x01, 0x03, 0xe8, 0x25, 0x01, 0x03, 0xf0, 0x25, 0x01, 0x03, 0xf8, 0x25, 0x01, 0x03, 0x00, 0x26, 0x01, 0x03, 0x28, 0x12, 0x02, 0x03, + 0x30, 0x12, 0x02, 0x03, 0x38, 0x12, 0x02, 0x03, 0xd0, 0x02, 0x03, 0x03, 0xd8, 0x02, 0x03, 0x03, 0xe0, 0x02, 0x03, 0x03, 0x60, 0x2b, 0x04, 0x04, 0x70, 0x2b, 0x04, 0x04, 0x50, 0x17, 0x05, 0x04, + 0x60, 0x17, 0x05, 0x04, 0xb0, 0x05, 0x06, 0x04, 0x60, 0x32, 0x07, 0x05, 0x80, 0x1b, 0x08, 0x05, 0x80, 0x0a, 0x09, 0x05, 0x40, 0x3a, 0x0a, 0x06, 0x40, 0x12, 0x0c, 0x06, 0x80, 0x08, 0x10, 0x07, + 0x10, 0x2e, 0x00, 0x04, 0x20, 0x2e, 0x00, 0x04, 0x08, 0x26, 0x01, 0x03, 0x10, 0x26, 0x01, 0x03, 0x18, 0x26, 0x01, 0x03, 0x20, 0x26, 0x01, 0x03, 0x28, 0x26, 0x01, 0x03, 0x40, 0x12, 0x02, 0x03, + 0x48, 0x12, 0x02, 0x03, 0x50, 0x12, 0x02, 0x03, 0xe8, 0x02, 0x03, 0x03, 0xf0, 0x02, 0x03, 0x03, 0xf8, 0x02, 0x03, 0x03, 0x80, 0x2b, 0x04, 0x04, 0x90, 0x2b, 0x04, 0x04, 0x70, 0x17, 0x05, 0x04, + 0x80, 0x17, 0x05, 0x04, 0xc0, 0x05, 0x06, 0x04, 0x80, 0x32, 0x07, 0x05, 0xa0, 0x1b, 0x08, 0x05, 0xa0, 0x0a, 0x09, 0x05, 0x80, 0x3a, 0x0a, 0x06, 0x80, 0x12, 0x0c, 0x06, 0x00, 0x28, 0x11, 0x08, + 0x30, 0x2e, 0x00, 0x04, 0x40, 0x2e, 0x00, 0x04, 0x30, 0x26, 0x01, 0x03, 0x38, 0x26, 0x01, 0x03, 0x40, 0x26, 0x01, 0x03, 0x48, 0x26, 0x01, 0x03, 0x50, 0x26, 0x01, 0x03, 0x58, 0x12, 0x02, 0x03, + 0x60, 0x12, 0x02, 0x03, 0x68, 0x12, 0x02, 0x03, 0x00, 0x03, 0x03, 0x03, 0x08, 0x03, 0x03, 0x03, 0x10, 0x03, 0x03, 0x03, 0xa0, 0x2b, 0x04, 0x04, 0xb0, 0x2b, 0x04, 0x04, 0x90, 0x17, 0x05, 0x04, + 0xa0, 0x17, 0x05, 0x04, 0xd0, 0x05, 0x06, 0x04, 0xa0, 0x32, 0x07, 0x05, 0xc0, 0x1b, 0x08, 0x05, 0xc0, 0x0a, 0x09, 0x05, 0xc0, 0x3a, 0x0a, 0x06, 0xc0, 0x12, 0x0c, 0x06, 0x00, 0x29, 0x11, 0x08, + 0x50, 0x2e, 0x00, 0x04, 0x60, 0x2e, 0x00, 0x04, 0x58, 0x26, 0x01, 0x03, 0x60, 0x26, 0x01, 0x03, 0x68, 0x26, 0x01, 0x03, 0x70, 0x26, 0x01, 0x03, 0x78, 0x26, 0x01, 0x03, 0x70, 0x12, 0x02, 0x03, + 0x78, 0x12, 0x02, 0x03, 0x80, 0x12, 0x02, 0x03, 0x18, 0x03, 0x03, 0x03, 0x20, 0x03, 0x03, 0x03, 0x28, 0x03, 0x03, 0x03, 0xc0, 0x2b, 0x04, 0x04, 0xd0, 0x2b, 0x04, 0x04, 0xb0, 0x17, 0x05, 0x04, + 0xc0, 0x17, 0x05, 0x04, 0xe0, 0x05, 0x06, 0x04, 0xc0, 0x32, 0x07, 0x05, 0xe0, 0x1b, 0x08, 0x05, 0xe0, 0x0a, 0x09, 0x05, 0x00, 0x3b, 0x0a, 0x06, 0x00, 0x3b, 0x0d, 0x07, 0x00, 0x2a, 0x11, 0x08, + 0x70, 0x2e, 0x00, 0x04, 0x80, 0x2e, 0x00, 0x04, 0x80, 0x26, 0x01, 0x03, 0x88, 0x26, 0x01, 0x03, 0x90, 0x26, 0x01, 0x03, 0x98, 0x26, 0x01, 0x03, 0xa0, 0x26, 0x01, 0x03, 0x88, 0x12, 0x02, 0x03, + 0x90, 0x12, 0x02, 0x03, 0x98, 0x12, 0x02, 0x03, 0x30, 0x03, 0x03, 0x03, 0x38, 0x03, 0x03, 0x03, 0x40, 0x03, 0x03, 0x03, 0xe0, 0x2b, 0x04, 0x04, 0xf0, 0x2b, 0x04, 0x04, 0xd0, 0x17, 0x05, 0x04, + 0xe0, 0x17, 0x05, 0x04, 0xf0, 0x05, 0x06, 0x04, 0xe0, 0x32, 0x07, 0x05, 0x00, 0x1c, 0x08, 0x05, 0x00, 0x0b, 0x09, 0x05, 0x40, 0x3b, 0x0a, 0x06, 0x80, 0x3b, 0x0d, 0x07, 0x00, 0x2b, 0x11, 0x08, + 0x90, 0x2e, 0x00, 0x04, 0xa0, 0x2e, 0x00, 0x04, 0xa8, 0x26, 0x01, 0x03, 0xb0, 0x26, 0x01, 0x03, 0xb8, 0x26, 0x01, 0x03, 0xc0, 0x26, 0x01, 0x03, 0xc8, 0x26, 0x01, 0x03, 0xa0, 0x12, 0x02, 0x03, + 0xa8, 0x12, 0x02, 0x03, 0xb0, 0x12, 0x02, 0x03, 0x48, 0x03, 0x03, 0x03, 0x50, 0x03, 0x03, 0x03, 0x58, 0x03, 0x03, 0x03, 0x00, 0x2c, 0x04, 0x04, 0x10, 0x2c, 0x04, 0x04, 0xf0, 0x17, 0x05, 0x04, + 0x00, 0x18, 0x05, 0x04, 0x00, 0x06, 0x06, 0x04, 0x00, 0x33, 0x07, 0x05, 0x20, 0x1c, 0x08, 0x05, 0x20, 0x0b, 0x09, 0x05, 0x80, 0x3b, 0x0a, 0x06, 0x00, 0x3c, 0x0d, 0x07, 0x00, 0x2c, 0x11, 0x08, + 0xb0, 0x2e, 0x00, 0x04, 0xc0, 0x2e, 0x00, 0x04, 0xd0, 0x26, 0x01, 0x03, 0xd8, 0x26, 0x01, 0x03, 0xe0, 0x26, 0x01, 0x03, 0xe8, 0x26, 0x01, 0x03, 0xf0, 0x26, 0x01, 0x03, 0xb8, 0x12, 0x02, 0x03, + 0xc0, 0x12, 0x02, 0x03, 0xc8, 0x12, 0x02, 0x03, 0x60, 0x03, 0x03, 0x03, 0x68, 0x03, 0x03, 0x03, 0x70, 0x03, 0x03, 0x03, 0x20, 0x2c, 0x04, 0x04, 0x30, 0x2c, 0x04, 0x04, 0x10, 0x18, 0x05, 0x04, + 0x20, 0x18, 0x05, 0x04, 0x10, 0x06, 0x06, 0x04, 0x20, 0x33, 0x07, 0x05, 0x40, 0x1c, 0x08, 0x05, 0x40, 0x0b, 0x09, 0x05, 0xc0, 0x3b, 0x0a, 0x06, 0x80, 0x3c, 0x0d, 0x07, 0x00, 0x2d, 0x11, 0x08, + 0xd0, 0x2e, 0x00, 0x04, 0xe0, 0x2e, 0x00, 0x04, 0xf8, 0x26, 0x01, 0x03, 0x00, 0x27, 0x01, 0x03, 0x08, 0x27, 0x01, 0x03, 0x10, 0x27, 0x01, 0x03, 0x18, 0x27, 0x01, 0x03, 0xd0, 0x12, 0x02, 0x03, + 0xd8, 0x12, 0x02, 0x03, 0xe0, 0x12, 0x02, 0x03, 0x78, 0x03, 0x03, 0x03, 0x80, 0x03, 0x03, 0x03, 0x88, 0x03, 0x03, 0x03, 0x40, 0x2c, 0x04, 0x04, 0x50, 0x2c, 0x04, 0x04, 0x30, 0x18, 0x05, 0x04, + 0x40, 0x18, 0x05, 0x04, 0x20, 0x06, 0x06, 0x04, 0x40, 0x33, 0x07, 0x05, 0x60, 0x1c, 0x08, 0x05, 0x60, 0x0b, 0x09, 0x05, 0x00, 0x3c, 0x0a, 0x06, 0x00, 0x3d, 0x0d, 0x07, 0x00, 0x2e, 0x11, 0x08, + 0xf0, 0x2e, 0x00, 0x04, 0x00, 0x2f, 0x00, 0x04, 0x20, 0x27, 0x01, 0x03, 0x28, 0x27, 0x01, 0x03, 0x30, 0x27, 0x01, 0x03, 0x38, 0x27, 0x01, 0x03, 0x40, 0x27, 0x01, 0x03, 0xe8, 0x12, 0x02, 0x03, + 0xf0, 0x12, 0x02, 0x03, 0xf8, 0x12, 0x02, 0x03, 0x90, 0x03, 0x03, 0x03, 0x98, 0x03, 0x03, 0x03, 0xa0, 0x03, 0x03, 0x03, 0x60, 0x2c, 0x04, 0x04, 0x70, 0x2c, 0x04, 0x04, 0x50, 0x18, 0x05, 0x04, + 0x60, 0x18, 0x05, 0x04, 0x30, 0x06, 0x06, 0x04, 0x60, 0x33, 0x07, 0x05, 0x80, 0x1c, 0x08, 0x05, 0x80, 0x0b, 0x09, 0x05, 0x40, 0x3c, 0x0a, 0x06, 0x80, 0x3d, 0x0d, 0x07, 0x00, 0x2f, 0x11, 0x08, + 0x10, 0x2f, 0x00, 0x04, 0x20, 0x2f, 0x00, 0x04, 0x48, 0x27, 0x01, 0x03, 0x50, 0x27, 0x01, 0x03, 0x58, 0x27, 0x01, 0x03, 0x60, 0x27, 0x01, 0x03, 0x68, 0x27, 0x01, 0x03, 0x00, 0x13, 0x02, 0x03, + 0x08, 0x13, 0x02, 0x03, 0x10, 0x13, 0x02, 0x03, 0xa8, 0x03, 0x03, 0x03, 0xb0, 0x03, 0x03, 0x03, 0xb8, 0x03, 0x03, 0x03, 0x80, 0x2c, 0x04, 0x04, 0x90, 0x2c, 0x04, 0x04, 0x70, 0x18, 0x05, 0x04, + 0x80, 0x18, 0x05, 0x04, 0x40, 0x06, 0x06, 0x04, 0x80, 0x33, 0x07, 0x05, 0xa0, 0x1c, 0x08, 0x05, 0xa0, 0x0b, 0x09, 0x05, 0x80, 0x3c, 0x0a, 0x06, 0x00, 0x3e, 0x0d, 0x07, 0x00, 0x30, 0x11, 0x08, + 0x30, 0x2f, 0x00, 0x04, 0x40, 0x2f, 0x00, 0x04, 0x70, 0x27, 0x01, 0x03, 0x78, 0x27, 0x01, 0x03, 0x80, 0x27, 0x01, 0x03, 0x88, 0x27, 0x01, 0x03, 0x90, 0x27, 0x01, 0x03, 0x18, 0x13, 0x02, 0x03, + 0x20, 0x13, 0x02, 0x03, 0x28, 0x13, 0x02, 0x03, 0xc0, 0x03, 0x03, 0x03, 0xc8, 0x03, 0x03, 0x03, 0xd0, 0x03, 0x03, 0x03, 0xa0, 0x2c, 0x04, 0x04, 0xb0, 0x2c, 0x04, 0x04, 0x90, 0x18, 0x05, 0x04, + 0xa0, 0x18, 0x05, 0x04, 0x50, 0x06, 0x06, 0x04, 0xa0, 0x33, 0x07, 0x05, 0xc0, 0x1c, 0x08, 0x05, 0xc0, 0x0b, 0x09, 0x05, 0xc0, 0x3c, 0x0a, 0x06, 0x80, 0x3e, 0x0d, 0x07, 0x00, 0x31, 0x11, 0x08, + 0x50, 0x2f, 0x00, 0x04, 0x60, 0x2f, 0x00, 0x04, 0x98, 0x27, 0x01, 0x03, 0xa0, 0x27, 0x01, 0x03, 0xa8, 0x27, 0x01, 0x03, 0xb0, 0x27, 0x01, 0x03, 0xb8, 0x27, 0x01, 0x03, 0x30, 0x13, 0x02, 0x03, + 0x38, 0x13, 0x02, 0x03, 0x40, 0x13, 0x02, 0x03, 0xd8, 0x03, 0x03, 0x03, 0xe0, 0x03, 0x03, 0x03, 0xe8, 0x03, 0x03, 0x03, 0xc0, 0x2c, 0x04, 0x04, 0xd0, 0x2c, 0x04, 0x04, 0xb0, 0x18, 0x05, 0x04, + 0xc0, 0x18, 0x05, 0x04, 0x60, 0x06, 0x06, 0x04, 0xc0, 0x33, 0x07, 0x05, 0xe0, 0x1c, 0x08, 0x05, 0xe0, 0x0b, 0x09, 0x05, 0x00, 0x3d, 0x0a, 0x06, 0x00, 0x3f, 0x0d, 0x07, 0x00, 0x32, 0x11, 0x08, + 0x70, 0x2f, 0x00, 0x04, 0x80, 0x2f, 0x00, 0x04, 0xc0, 0x27, 0x01, 0x03, 0xc8, 0x27, 0x01, 0x03, 0xd0, 0x27, 0x01, 0x03, 0xd8, 0x27, 0x01, 0x03, 0x48, 0x13, 0x02, 0x03, 0x50, 0x13, 0x02, 0x03, + 0x58, 0x13, 0x02, 0x03, 0x60, 0x13, 0x02, 0x03, 0xf0, 0x03, 0x03, 0x03, 0xf8, 0x03, 0x03, 0x03, 0x00, 0x04, 0x03, 0x03, 0xe0, 0x2c, 0x04, 0x04, 0xf0, 0x2c, 0x04, 0x04, 0xd0, 0x18, 0x05, 0x04, + 0xe0, 0x18, 0x05, 0x04, 0x70, 0x06, 0x06, 0x04, 0xe0, 0x33, 0x07, 0x05, 0x00, 0x1d, 0x08, 0x05, 0x00, 0x0c, 0x09, 0x05, 0x40, 0x1e, 0x0b, 0x06, 0x80, 0x3f, 0x0d, 0x07, 0x00, 0x33, 0x11, 0x08, + 0x90, 0x2f, 0x00, 0x04, 0xa0, 0x2f, 0x00, 0x04, 0xe0, 0x27, 0x01, 0x03, 0xe8, 0x27, 0x01, 0x03, 0xf0, 0x27, 0x01, 0x03, 0xf8, 0x27, 0x01, 0x03, 0x68, 0x13, 0x02, 0x03, 0x70, 0x13, 0x02, 0x03, + 0x78, 0x13, 0x02, 0x03, 0x80, 0x13, 0x02, 0x03, 0x08, 0x04, 0x03, 0x03, 0x10, 0x04, 0x03, 0x03, 0x18, 0x04, 0x03, 0x03, 0x00, 0x2d, 0x04, 0x04, 0x10, 0x2d, 0x04, 0x04, 0xf0, 0x18, 0x05, 0x04, + 0x00, 0x19, 0x05, 0x04, 0x80, 0x06, 0x06, 0x04, 0x00, 0x34, 0x07, 0x05, 0x20, 0x1d, 0x08, 0x05, 0x20, 0x0c, 0x09, 0x05, 0x80, 0x1e, 0x0b, 0x06, 0x00, 0x00, 0x0d, 0x06, 0x00, 0x16, 0x12, 0x08, + 0xb0, 0x2f, 0x00, 0x04, 0xc0, 0x2f, 0x00, 0x04, 0x00, 0x28, 0x01, 0x03, 0x08, 0x28, 0x01, 0x03, 0x10, 0x28, 0x01, 0x03, 0x18, 0x28, 0x01, 0x03, 0x88, 0x13, 0x02, 0x03, 0x90, 0x13, 0x02, 0x03, + 0x98, 0x13, 0x02, 0x03, 0xa0, 0x13, 0x02, 0x03, 0x20, 0x04, 0x03, 0x03, 0x28, 0x04, 0x03, 0x03, 0x30, 0x04, 0x03, 0x03, 0x20, 0x2d, 0x04, 0x04, 0x30, 0x2d, 0x04, 0x04, 0x10, 0x19, 0x05, 0x04, + 0x20, 0x19, 0x05, 0x04, 0x90, 0x06, 0x06, 0x04, 0x20, 0x34, 0x07, 0x05, 0x40, 0x1d, 0x08, 0x05, 0x40, 0x0c, 0x09, 0x05, 0xc0, 0x1e, 0x0b, 0x06, 0x40, 0x00, 0x0d, 0x06, 0x00, 0x17, 0x12, 0x08, + 0xd0, 0x2f, 0x00, 0x04, 0xe0, 0x2f, 0x00, 0x04, 0x20, 0x28, 0x01, 0x03, 0x28, 0x28, 0x01, 0x03, 0x30, 0x28, 0x01, 0x03, 0x38, 0x28, 0x01, 0x03, 0xa8, 0x13, 0x02, 0x03, 0xb0, 0x13, 0x02, 0x03, + 0xb8, 0x13, 0x02, 0x03, 0xc0, 0x13, 0x02, 0x03, 0x38, 0x04, 0x03, 0x03, 0x40, 0x04, 0x03, 0x03, 0x48, 0x04, 0x03, 0x03, 0x40, 0x2d, 0x04, 0x04, 0x50, 0x2d, 0x04, 0x04, 0x30, 0x19, 0x05, 0x04, + 0x40, 0x19, 0x05, 0x04, 0xa0, 0x06, 0x06, 0x04, 0x40, 0x34, 0x07, 0x05, 0x60, 0x1d, 0x08, 0x05, 0x60, 0x0c, 0x09, 0x05, 0x00, 0x1f, 0x0b, 0x06, 0x80, 0x00, 0x0d, 0x06, 0x00, 0x18, 0x12, 0x08, + 0xf0, 0x2f, 0x00, 0x04, 0x00, 0x30, 0x00, 0x04, 0x40, 0x28, 0x01, 0x03, 0x48, 0x28, 0x01, 0x03, 0x50, 0x28, 0x01, 0x03, 0x58, 0x28, 0x01, 0x03, 0xc8, 0x13, 0x02, 0x03, 0xd0, 0x13, 0x02, 0x03, + 0xd8, 0x13, 0x02, 0x03, 0xe0, 0x13, 0x02, 0x03, 0x50, 0x04, 0x03, 0x03, 0x58, 0x04, 0x03, 0x03, 0x60, 0x04, 0x03, 0x03, 0x60, 0x2d, 0x04, 0x04, 0x70, 0x2d, 0x04, 0x04, 0x50, 0x19, 0x05, 0x04, + 0x60, 0x19, 0x05, 0x04, 0xb0, 0x06, 0x06, 0x04, 0x60, 0x34, 0x07, 0x05, 0x80, 0x1d, 0x08, 0x05, 0x80, 0x0c, 0x09, 0x05, 0x40, 0x1f, 0x0b, 0x06, 0xc0, 0x00, 0x0d, 0x06, 0x00, 0x19, 0x12, 0x08, + 0x10, 0x30, 0x00, 0x04, 0x20, 0x30, 0x00, 0x04, 0x60, 0x28, 0x01, 0x03, 0x68, 0x28, 0x01, 0x03, 0x70, 0x28, 0x01, 0x03, 0x78, 0x28, 0x01, 0x03, 0xe8, 0x13, 0x02, 0x03, 0xf0, 0x13, 0x02, 0x03, + 0xf8, 0x13, 0x02, 0x03, 0x00, 0x14, 0x02, 0x03, 0x68, 0x04, 0x03, 0x03, 0x70, 0x04, 0x03, 0x03, 0x78, 0x04, 0x03, 0x03, 0x80, 0x2d, 0x04, 0x04, 0x90, 0x2d, 0x04, 0x04, 0x70, 0x19, 0x05, 0x04, + 0x80, 0x19, 0x05, 0x04, 0xc0, 0x06, 0x06, 0x04, 0x80, 0x34, 0x07, 0x05, 0xa0, 0x1d, 0x08, 0x05, 0xa0, 0x0c, 0x09, 0x05, 0x80, 0x1f, 0x0b, 0x06, 0x00, 0x01, 0x0d, 0x06, 0x00, 0x1a, 0x12, 0x08, + 0x30, 0x30, 0x00, 0x04, 0x40, 0x30, 0x00, 0x04, 0x80, 0x28, 0x01, 0x03, 0x88, 0x28, 0x01, 0x03, 0x90, 0x28, 0x01, 0x03, 0x98, 0x28, 0x01, 0x03, 0x08, 0x14, 0x02, 0x03, 0x10, 0x14, 0x02, 0x03, + 0x18, 0x14, 0x02, 0x03, 0x20, 0x14, 0x02, 0x03, 0x80, 0x04, 0x03, 0x03, 0x88, 0x04, 0x03, 0x03, 0x90, 0x04, 0x03, 0x03, 0xa0, 0x2d, 0x04, 0x04, 0xb0, 0x2d, 0x04, 0x04, 0x90, 0x19, 0x05, 0x04, + 0xa0, 0x19, 0x05, 0x04, 0xd0, 0x06, 0x06, 0x04, 0xa0, 0x34, 0x07, 0x05, 0xc0, 0x1d, 0x08, 0x05, 0xc0, 0x0c, 0x09, 0x05, 0xc0, 0x1f, 0x0b, 0x06, 0x40, 0x01, 0x0d, 0x06, 0x00, 0x1b, 0x12, 0x08, + 0x50, 0x30, 0x00, 0x04, 0x60, 0x30, 0x00, 0x04, 0xa0, 0x28, 0x01, 0x03, 0xa8, 0x28, 0x01, 0x03, 0xb0, 0x28, 0x01, 0x03, 0xb8, 0x28, 0x01, 0x03, 0x28, 0x14, 0x02, 0x03, 0x30, 0x14, 0x02, 0x03, + 0x38, 0x14, 0x02, 0x03, 0x40, 0x14, 0x02, 0x03, 0x98, 0x04, 0x03, 0x03, 0xa0, 0x04, 0x03, 0x03, 0xa8, 0x04, 0x03, 0x03, 0xc0, 0x2d, 0x04, 0x04, 0xd0, 0x2d, 0x04, 0x04, 0xb0, 0x19, 0x05, 0x04, + 0xe0, 0x06, 0x06, 0x04, 0xf0, 0x06, 0x06, 0x04, 0xc0, 0x34, 0x07, 0x05, 0xe0, 0x1d, 0x08, 0x05, 0xe0, 0x0c, 0x09, 0x05, 0x00, 0x20, 0x0b, 0x06, 0x80, 0x01, 0x0d, 0x06, 0x00, 0x1c, 0x12, 0x08, + 0x70, 0x30, 0x00, 0x04, 0x80, 0x30, 0x00, 0x04, 0xc0, 0x28, 0x01, 0x03, 0xc8, 0x28, 0x01, 0x03, 0xd0, 0x28, 0x01, 0x03, 0xd8, 0x28, 0x01, 0x03, 0x48, 0x14, 0x02, 0x03, 0x50, 0x14, 0x02, 0x03, + 0x58, 0x14, 0x02, 0x03, 0x60, 0x14, 0x02, 0x03, 0xb0, 0x04, 0x03, 0x03, 0xb8, 0x04, 0x03, 0x03, 0xe0, 0x2d, 0x04, 0x04, 0xf0, 0x2d, 0x04, 0x04, 0x00, 0x2e, 0x04, 0x04, 0xc0, 0x19, 0x05, 0x04, + 0x00, 0x07, 0x06, 0x04, 0x10, 0x07, 0x06, 0x04, 0xe0, 0x34, 0x07, 0x05, 0x00, 0x1e, 0x08, 0x05, 0x00, 0x0d, 0x09, 0x05, 0x40, 0x20, 0x0b, 0x06, 0xc0, 0x01, 0x0d, 0x06, 0x00, 0x1d, 0x12, 0x08, + 0x90, 0x30, 0x00, 0x04, 0xa0, 0x30, 0x00, 0x04, 0xe0, 0x28, 0x01, 0x03, 0xe8, 0x28, 0x01, 0x03, 0xf0, 0x28, 0x01, 0x03, 0xf8, 0x28, 0x01, 0x03, 0x68, 0x14, 0x02, 0x03, 0x70, 0x14, 0x02, 0x03, + 0x78, 0x14, 0x02, 0x03, 0x80, 0x14, 0x02, 0x03, 0xc0, 0x04, 0x03, 0x03, 0xc8, 0x04, 0x03, 0x03, 0x10, 0x2e, 0x04, 0x04, 0x20, 0x2e, 0x04, 0x04, 0x30, 0x2e, 0x04, 0x04, 0xd0, 0x19, 0x05, 0x04, + 0x20, 0x07, 0x06, 0x04, 0x30, 0x07, 0x06, 0x04, 0x00, 0x35, 0x07, 0x05, 0x20, 0x1e, 0x08, 0x05, 0x20, 0x0d, 0x09, 0x05, 0x80, 0x20, 0x0b, 0x06, 0x00, 0x02, 0x0d, 0x06, 0x00, 0x1e, 0x12, 0x08, + 0xb0, 0x30, 0x00, 0x04, 0xc0, 0x30, 0x00, 0x04, 0x00, 0x29, 0x01, 0x03, 0x08, 0x29, 0x01, 0x03, 0x10, 0x29, 0x01, 0x03, 0x18, 0x29, 0x01, 0x03, 0x88, 0x14, 0x02, 0x03, 0x90, 0x14, 0x02, 0x03, + 0x98, 0x14, 0x02, 0x03, 0xa0, 0x14, 0x02, 0x03, 0xd0, 0x04, 0x03, 0x03, 0xd8, 0x04, 0x03, 0x03, 0x40, 0x2e, 0x04, 0x04, 0x50, 0x2e, 0x04, 0x04, 0x60, 0x2e, 0x04, 0x04, 0xe0, 0x19, 0x05, 0x04, + 0x40, 0x07, 0x06, 0x04, 0x50, 0x07, 0x06, 0x04, 0x20, 0x35, 0x07, 0x05, 0x40, 0x1e, 0x08, 0x05, 0x40, 0x0d, 0x09, 0x05, 0xc0, 0x20, 0x0b, 0x06, 0x40, 0x02, 0x0d, 0x06, 0x00, 0x04, 0x13, 0x08, + 0xd0, 0x30, 0x00, 0x04, 0xe0, 0x30, 0x00, 0x04, 0x20, 0x29, 0x01, 0x03, 0x28, 0x29, 0x01, 0x03, 0x30, 0x29, 0x01, 0x03, 0x38, 0x29, 0x01, 0x03, 0xa8, 0x14, 0x02, 0x03, 0xb0, 0x14, 0x02, 0x03, + 0xb8, 0x14, 0x02, 0x03, 0xc0, 0x14, 0x02, 0x03, 0xe0, 0x04, 0x03, 0x03, 0xe8, 0x04, 0x03, 0x03, 0x70, 0x2e, 0x04, 0x04, 0x80, 0x2e, 0x04, 0x04, 0x90, 0x2e, 0x04, 0x04, 0xf0, 0x19, 0x05, 0x04, + 0x60, 0x07, 0x06, 0x04, 0x70, 0x07, 0x06, 0x04, 0x40, 0x35, 0x07, 0x05, 0x60, 0x1e, 0x08, 0x05, 0x60, 0x0d, 0x09, 0x05, 0x00, 0x21, 0x0b, 0x06, 0x80, 0x02, 0x0d, 0x06, 0x00, 0x05, 0x13, 0x08, + 0xf0, 0x30, 0x00, 0x04, 0x00, 0x31, 0x00, 0x04, 0x40, 0x29, 0x01, 0x03, 0x48, 0x29, 0x01, 0x03, 0x50, 0x29, 0x01, 0x03, 0x58, 0x29, 0x01, 0x03, 0xc8, 0x14, 0x02, 0x03, 0xd0, 0x14, 0x02, 0x03, + 0xd8, 0x14, 0x02, 0x03, 0xe0, 0x14, 0x02, 0x03, 0xf0, 0x04, 0x03, 0x03, 0xf8, 0x04, 0x03, 0x03, 0xa0, 0x2e, 0x04, 0x04, 0xb0, 0x2e, 0x04, 0x04, 0xc0, 0x2e, 0x04, 0x04, 0x00, 0x1a, 0x05, 0x04, + 0x80, 0x07, 0x06, 0x04, 0x90, 0x07, 0x06, 0x04, 0x60, 0x35, 0x07, 0x05, 0x80, 0x1e, 0x08, 0x05, 0x80, 0x0d, 0x09, 0x05, 0x40, 0x21, 0x0b, 0x06, 0xc0, 0x02, 0x0d, 0x06, 0x00, 0x06, 0x13, 0x08, + 0x10, 0x31, 0x00, 0x04, 0x20, 0x31, 0x00, 0x04, 0x60, 0x29, 0x01, 0x03, 0x68, 0x29, 0x01, 0x03, 0x70, 0x29, 0x01, 0x03, 0x78, 0x29, 0x01, 0x03, 0xe8, 0x14, 0x02, 0x03, 0xf0, 0x14, 0x02, 0x03, + 0xf8, 0x14, 0x02, 0x03, 0x00, 0x15, 0x02, 0x03, 0x00, 0x05, 0x03, 0x03, 0x08, 0x05, 0x03, 0x03, 0xd0, 0x2e, 0x04, 0x04, 0xe0, 0x2e, 0x04, 0x04, 0xf0, 0x2e, 0x04, 0x04, 0x10, 0x1a, 0x05, 0x04, + 0xa0, 0x07, 0x06, 0x04, 0xb0, 0x07, 0x06, 0x04, 0x80, 0x35, 0x07, 0x05, 0xa0, 0x1e, 0x08, 0x05, 0xa0, 0x0d, 0x09, 0x05, 0x80, 0x21, 0x0b, 0x06, 0x00, 0x03, 0x0d, 0x06, 0x00, 0x07, 0x13, 0x08, + 0x30, 0x31, 0x00, 0x04, 0x40, 0x31, 0x00, 0x04, 0x80, 0x29, 0x01, 0x03, 0x88, 0x29, 0x01, 0x03, 0x90, 0x29, 0x01, 0x03, 0x98, 0x29, 0x01, 0x03, 0x08, 0x15, 0x02, 0x03, 0x10, 0x15, 0x02, 0x03, + 0x18, 0x15, 0x02, 0x03, 0x20, 0x15, 0x02, 0x03, 0x10, 0x05, 0x03, 0x03, 0x18, 0x05, 0x03, 0x03, 0x00, 0x2f, 0x04, 0x04, 0x10, 0x2f, 0x04, 0x04, 0x20, 0x2f, 0x04, 0x04, 0x20, 0x1a, 0x05, 0x04, + 0xc0, 0x07, 0x06, 0x04, 0xd0, 0x07, 0x06, 0x04, 0xa0, 0x35, 0x07, 0x05, 0xc0, 0x1e, 0x08, 0x05, 0xc0, 0x0d, 0x09, 0x05, 0xc0, 0x21, 0x0b, 0x06, 0x40, 0x03, 0x0d, 0x06, 0x00, 0x08, 0x13, 0x08, + 0x50, 0x31, 0x00, 0x04, 0x60, 0x31, 0x00, 0x04, 0xa0, 0x29, 0x01, 0x03, 0xa8, 0x29, 0x01, 0x03, 0xb0, 0x29, 0x01, 0x03, 0xb8, 0x29, 0x01, 0x03, 0x28, 0x15, 0x02, 0x03, 0x30, 0x15, 0x02, 0x03, + 0x38, 0x15, 0x02, 0x03, 0x40, 0x15, 0x02, 0x03, 0x20, 0x05, 0x03, 0x03, 0x28, 0x05, 0x03, 0x03, 0x30, 0x2f, 0x04, 0x04, 0x40, 0x2f, 0x04, 0x04, 0x50, 0x2f, 0x04, 0x04, 0x30, 0x1a, 0x05, 0x04, + 0xe0, 0x07, 0x06, 0x04, 0xf0, 0x07, 0x06, 0x04, 0xc0, 0x35, 0x07, 0x05, 0xe0, 0x1e, 0x08, 0x05, 0xe0, 0x0d, 0x09, 0x05, 0x00, 0x22, 0x0b, 0x06, 0x80, 0x03, 0x0d, 0x06, 0x00, 0x09, 0x13, 0x08, + 0x70, 0x31, 0x00, 0x04, 0x80, 0x31, 0x00, 0x04, 0xc0, 0x29, 0x01, 0x03, 0xc8, 0x29, 0x01, 0x03, 0xd0, 0x29, 0x01, 0x03, 0xd8, 0x29, 0x01, 0x03, 0x48, 0x15, 0x02, 0x03, 0x50, 0x15, 0x02, 0x03, + 0x58, 0x15, 0x02, 0x03, 0x60, 0x15, 0x02, 0x03, 0x30, 0x05, 0x03, 0x03, 0x38, 0x05, 0x03, 0x03, 0x60, 0x2f, 0x04, 0x04, 0x70, 0x2f, 0x04, 0x04, 0x80, 0x2f, 0x04, 0x04, 0x40, 0x1a, 0x05, 0x04, + 0x00, 0x08, 0x06, 0x04, 0x10, 0x08, 0x06, 0x04, 0xe0, 0x35, 0x07, 0x05, 0x00, 0x1f, 0x08, 0x05, 0x00, 0x0e, 0x09, 0x05, 0x40, 0x22, 0x0b, 0x06, 0xc0, 0x03, 0x0d, 0x06, 0x00, 0x0a, 0x13, 0x08, + 0x90, 0x31, 0x00, 0x04, 0xa0, 0x31, 0x00, 0x04, 0xe0, 0x29, 0x01, 0x03, 0xe8, 0x29, 0x01, 0x03, 0xf0, 0x29, 0x01, 0x03, 0xf8, 0x29, 0x01, 0x03, 0x68, 0x15, 0x02, 0x03, 0x70, 0x15, 0x02, 0x03, + 0x78, 0x15, 0x02, 0x03, 0x80, 0x15, 0x02, 0x03, 0x40, 0x05, 0x03, 0x03, 0x48, 0x05, 0x03, 0x03, 0x90, 0x2f, 0x04, 0x04, 0xa0, 0x2f, 0x04, 0x04, 0xb0, 0x2f, 0x04, 0x04, 0x50, 0x1a, 0x05, 0x04, + 0x20, 0x08, 0x06, 0x04, 0x30, 0x08, 0x06, 0x04, 0x00, 0x36, 0x07, 0x05, 0x20, 0x1f, 0x08, 0x05, 0x20, 0x0e, 0x09, 0x05, 0x80, 0x22, 0x0b, 0x06, 0x00, 0x04, 0x0d, 0x06, 0x00, 0x0b, 0x13, 0x08, + 0xb0, 0x31, 0x00, 0x04, 0xc0, 0x31, 0x00, 0x04, 0x00, 0x2a, 0x01, 0x03, 0x08, 0x2a, 0x01, 0x03, 0x10, 0x2a, 0x01, 0x03, 0x18, 0x2a, 0x01, 0x03, 0x88, 0x15, 0x02, 0x03, 0x90, 0x15, 0x02, 0x03, + 0x98, 0x15, 0x02, 0x03, 0xa0, 0x15, 0x02, 0x03, 0x50, 0x05, 0x03, 0x03, 0x58, 0x05, 0x03, 0x03, 0xc0, 0x2f, 0x04, 0x04, 0xd0, 0x2f, 0x04, 0x04, 0xe0, 0x2f, 0x04, 0x04, 0x60, 0x1a, 0x05, 0x04, + 0x40, 0x08, 0x06, 0x04, 0x50, 0x08, 0x06, 0x04, 0x20, 0x36, 0x07, 0x05, 0x40, 0x1f, 0x08, 0x05, 0x40, 0x0e, 0x09, 0x05, 0xc0, 0x22, 0x0b, 0x06, 0x40, 0x04, 0x0d, 0x06, 0x00, 0x2e, 0x14, 0x09, + 0xd0, 0x31, 0x00, 0x04, 0xe0, 0x31, 0x00, 0x04, 0x20, 0x2a, 0x01, 0x03, 0x28, 0x2a, 0x01, 0x03, 0x30, 0x2a, 0x01, 0x03, 0x38, 0x2a, 0x01, 0x03, 0xa8, 0x15, 0x02, 0x03, 0xb0, 0x15, 0x02, 0x03, + 0xb8, 0x15, 0x02, 0x03, 0xc0, 0x15, 0x02, 0x03, 0x60, 0x05, 0x03, 0x03, 0x68, 0x05, 0x03, 0x03, 0xf0, 0x2f, 0x04, 0x04, 0x00, 0x30, 0x04, 0x04, 0x10, 0x30, 0x04, 0x04, 0x70, 0x1a, 0x05, 0x04, + 0x60, 0x08, 0x06, 0x04, 0x70, 0x08, 0x06, 0x04, 0x40, 0x36, 0x07, 0x05, 0x60, 0x1f, 0x08, 0x05, 0x60, 0x0e, 0x09, 0x05, 0x00, 0x23, 0x0b, 0x06, 0x80, 0x23, 0x0e, 0x07, 0x00, 0x30, 0x14, 0x09, + 0xf0, 0x31, 0x00, 0x04, 0x00, 0x32, 0x00, 0x04, 0x40, 0x2a, 0x01, 0x03, 0x48, 0x2a, 0x01, 0x03, 0x50, 0x2a, 0x01, 0x03, 0x58, 0x2a, 0x01, 0x03, 0xc8, 0x15, 0x02, 0x03, 0xd0, 0x15, 0x02, 0x03, + 0xd8, 0x15, 0x02, 0x03, 0xe0, 0x15, 0x02, 0x03, 0x70, 0x05, 0x03, 0x03, 0x78, 0x05, 0x03, 0x03, 0x20, 0x30, 0x04, 0x04, 0x30, 0x30, 0x04, 0x04, 0x40, 0x30, 0x04, 0x04, 0x80, 0x1a, 0x05, 0x04, + 0x80, 0x08, 0x06, 0x04, 0x90, 0x08, 0x06, 0x04, 0x60, 0x36, 0x07, 0x05, 0x80, 0x1f, 0x08, 0x05, 0x80, 0x0e, 0x09, 0x05, 0x40, 0x23, 0x0b, 0x06, 0x00, 0x24, 0x0e, 0x07, 0x00, 0x32, 0x14, 0x09, + 0x10, 0x32, 0x00, 0x04, 0x20, 0x32, 0x00, 0x04, 0x60, 0x2a, 0x01, 0x03, 0x68, 0x2a, 0x01, 0x03, 0x70, 0x2a, 0x01, 0x03, 0x78, 0x2a, 0x01, 0x03, 0xe8, 0x15, 0x02, 0x03, 0xf0, 0x15, 0x02, 0x03, + 0xf8, 0x15, 0x02, 0x03, 0x00, 0x16, 0x02, 0x03, 0x80, 0x05, 0x03, 0x03, 0x88, 0x05, 0x03, 0x03, 0x50, 0x30, 0x04, 0x04, 0x60, 0x30, 0x04, 0x04, 0x70, 0x30, 0x04, 0x04, 0x90, 0x1a, 0x05, 0x04, + 0xa0, 0x08, 0x06, 0x04, 0xb0, 0x08, 0x06, 0x04, 0x80, 0x36, 0x07, 0x05, 0xa0, 0x1f, 0x08, 0x05, 0xa0, 0x0e, 0x09, 0x05, 0x80, 0x23, 0x0b, 0x06, 0x80, 0x24, 0x0e, 0x07, 0x00, 0x34, 0x14, 0x09, + 0x30, 0x32, 0x00, 0x04, 0x40, 0x32, 0x00, 0x04, 0x80, 0x2a, 0x01, 0x03, 0x88, 0x2a, 0x01, 0x03, 0x90, 0x2a, 0x01, 0x03, 0x98, 0x2a, 0x01, 0x03, 0x08, 0x16, 0x02, 0x03, 0x10, 0x16, 0x02, 0x03, + 0x18, 0x16, 0x02, 0x03, 0x20, 0x16, 0x02, 0x03, 0x90, 0x05, 0x03, 0x03, 0x98, 0x05, 0x03, 0x03, 0x80, 0x30, 0x04, 0x04, 0x90, 0x30, 0x04, 0x04, 0xa0, 0x30, 0x04, 0x04, 0xa0, 0x1a, 0x05, 0x04, + 0xc0, 0x08, 0x06, 0x04, 0xd0, 0x08, 0x06, 0x04, 0xa0, 0x36, 0x07, 0x05, 0xc0, 0x1f, 0x08, 0x05, 0xc0, 0x0e, 0x09, 0x05, 0xc0, 0x23, 0x0b, 0x06, 0x00, 0x25, 0x0e, 0x07, 0x00, 0x36, 0x14, 0x09, + 0x50, 0x32, 0x00, 0x04, 0x60, 0x32, 0x00, 0x04, 0xa0, 0x2a, 0x01, 0x03, 0xa8, 0x2a, 0x01, 0x03, 0xb0, 0x2a, 0x01, 0x03, 0xb8, 0x2a, 0x01, 0x03, 0x28, 0x16, 0x02, 0x03, 0x30, 0x16, 0x02, 0x03, + 0x38, 0x16, 0x02, 0x03, 0x40, 0x16, 0x02, 0x03, 0xa0, 0x05, 0x03, 0x03, 0xa8, 0x05, 0x03, 0x03, 0xb0, 0x30, 0x04, 0x04, 0xc0, 0x30, 0x04, 0x04, 0xd0, 0x30, 0x04, 0x04, 0xb0, 0x1a, 0x05, 0x04, + 0xe0, 0x08, 0x06, 0x04, 0xf0, 0x08, 0x06, 0x04, 0xc0, 0x36, 0x07, 0x05, 0xe0, 0x1f, 0x08, 0x05, 0xe0, 0x0e, 0x09, 0x05, 0x00, 0x24, 0x0b, 0x06, 0x80, 0x25, 0x0e, 0x07, 0x00, 0x38, 0x14, 0x09, + 0x70, 0x32, 0x00, 0x04, 0x80, 0x32, 0x00, 0x04, 0xc0, 0x2a, 0x01, 0x03, 0xc8, 0x2a, 0x01, 0x03, 0xd0, 0x2a, 0x01, 0x03, 0xd8, 0x2a, 0x01, 0x03, 0x48, 0x16, 0x02, 0x03, 0x50, 0x16, 0x02, 0x03, + 0x58, 0x16, 0x02, 0x03, 0x60, 0x16, 0x02, 0x03, 0xb0, 0x05, 0x03, 0x03, 0xb8, 0x05, 0x03, 0x03, 0xe0, 0x30, 0x04, 0x04, 0xf0, 0x30, 0x04, 0x04, 0x00, 0x31, 0x04, 0x04, 0xc0, 0x1a, 0x05, 0x04, + 0x00, 0x09, 0x06, 0x04, 0x10, 0x09, 0x06, 0x04, 0xe0, 0x36, 0x07, 0x05, 0x00, 0x20, 0x08, 0x05, 0x00, 0x0f, 0x09, 0x05, 0x40, 0x24, 0x0b, 0x06, 0x00, 0x26, 0x0e, 0x07, 0x00, 0x1a, 0x15, 0x09, + 0x90, 0x32, 0x00, 0x04, 0xa0, 0x32, 0x00, 0x04, 0xe0, 0x2a, 0x01, 0x03, 0xe8, 0x2a, 0x01, 0x03, 0xf0, 0x2a, 0x01, 0x03, 0xf8, 0x2a, 0x01, 0x03, 0x68, 0x16, 0x02, 0x03, 0x70, 0x16, 0x02, 0x03, + 0x78, 0x16, 0x02, 0x03, 0x80, 0x16, 0x02, 0x03, 0xc0, 0x05, 0x03, 0x03, 0xc8, 0x05, 0x03, 0x03, 0x10, 0x31, 0x04, 0x04, 0x20, 0x31, 0x04, 0x04, 0xd0, 0x1a, 0x05, 0x04, 0xe0, 0x1a, 0x05, 0x04, + 0x20, 0x09, 0x06, 0x04, 0x30, 0x09, 0x06, 0x04, 0x00, 0x37, 0x07, 0x05, 0x20, 0x20, 0x08, 0x05, 0x20, 0x0f, 0x09, 0x05, 0x80, 0x24, 0x0b, 0x06, 0x80, 0x26, 0x0e, 0x07, 0x00, 0x1c, 0x15, 0x09, + 0xb0, 0x32, 0x00, 0x04, 0xc0, 0x32, 0x00, 0x04, 0x00, 0x2b, 0x01, 0x03, 0x08, 0x2b, 0x01, 0x03, 0x10, 0x2b, 0x01, 0x03, 0x18, 0x2b, 0x01, 0x03, 0x88, 0x16, 0x02, 0x03, 0x90, 0x16, 0x02, 0x03, + 0x98, 0x16, 0x02, 0x03, 0xa0, 0x16, 0x02, 0x03, 0xd0, 0x05, 0x03, 0x03, 0xd8, 0x05, 0x03, 0x03, 0x30, 0x31, 0x04, 0x04, 0x40, 0x31, 0x04, 0x04, 0xf0, 0x1a, 0x05, 0x04, 0x00, 0x1b, 0x05, 0x04, + 0x40, 0x09, 0x06, 0x04, 0x50, 0x09, 0x06, 0x04, 0x20, 0x37, 0x07, 0x05, 0x40, 0x20, 0x08, 0x05, 0x40, 0x0f, 0x09, 0x05, 0xc0, 0x24, 0x0b, 0x06, 0x00, 0x27, 0x0e, 0x07, 0x00, 0x1e, 0x15, 0x09, + 0xd0, 0x32, 0x00, 0x04, 0xe0, 0x32, 0x00, 0x04, 0x20, 0x2b, 0x01, 0x03, 0x28, 0x2b, 0x01, 0x03, 0x30, 0x2b, 0x01, 0x03, 0x38, 0x2b, 0x01, 0x03, 0xa8, 0x16, 0x02, 0x03, 0xb0, 0x16, 0x02, 0x03, + 0xb8, 0x16, 0x02, 0x03, 0xc0, 0x16, 0x02, 0x03, 0xe0, 0x05, 0x03, 0x03, 0xe8, 0x05, 0x03, 0x03, 0x50, 0x31, 0x04, 0x04, 0x60, 0x31, 0x04, 0x04, 0x10, 0x1b, 0x05, 0x04, 0x20, 0x1b, 0x05, 0x04, + 0x60, 0x09, 0x06, 0x04, 0x70, 0x09, 0x06, 0x04, 0x40, 0x37, 0x07, 0x05, 0x60, 0x20, 0x08, 0x05, 0x60, 0x0f, 0x09, 0x05, 0x00, 0x25, 0x0b, 0x06, 0x80, 0x27, 0x0e, 0x07, 0x00, 0x20, 0x15, 0x09, + 0xf0, 0x32, 0x00, 0x04, 0x00, 0x33, 0x00, 0x04, 0x40, 0x2b, 0x01, 0x03, 0x48, 0x2b, 0x01, 0x03, 0x50, 0x2b, 0x01, 0x03, 0x58, 0x2b, 0x01, 0x03, 0xc8, 0x16, 0x02, 0x03, 0xd0, 0x16, 0x02, 0x03, + 0xd8, 0x16, 0x02, 0x03, 0xe0, 0x16, 0x02, 0x03, 0xf0, 0x05, 0x03, 0x03, 0xf8, 0x05, 0x03, 0x03, 0x70, 0x31, 0x04, 0x04, 0x80, 0x31, 0x04, 0x04, 0x30, 0x1b, 0x05, 0x04, 0x40, 0x1b, 0x05, 0x04, + 0x80, 0x09, 0x06, 0x04, 0x90, 0x09, 0x06, 0x04, 0x60, 0x37, 0x07, 0x05, 0x80, 0x20, 0x08, 0x05, 0x80, 0x0f, 0x09, 0x05, 0x40, 0x25, 0x0b, 0x06, 0x00, 0x28, 0x0e, 0x07, 0x00, 0x22, 0x15, 0x09, + 0x10, 0x33, 0x00, 0x04, 0x20, 0x33, 0x00, 0x04, 0x60, 0x2b, 0x01, 0x03, 0x68, 0x2b, 0x01, 0x03, 0x70, 0x2b, 0x01, 0x03, 0x78, 0x2b, 0x01, 0x03, 0xe8, 0x16, 0x02, 0x03, 0xf0, 0x16, 0x02, 0x03, + 0xf8, 0x16, 0x02, 0x03, 0x00, 0x17, 0x02, 0x03, 0x00, 0x06, 0x03, 0x03, 0x08, 0x06, 0x03, 0x03, 0x90, 0x31, 0x04, 0x04, 0xa0, 0x31, 0x04, 0x04, 0x50, 0x1b, 0x05, 0x04, 0x60, 0x1b, 0x05, 0x04, + 0xa0, 0x09, 0x06, 0x04, 0xb0, 0x09, 0x06, 0x04, 0x80, 0x37, 0x07, 0x05, 0xa0, 0x20, 0x08, 0x05, 0xa0, 0x0f, 0x09, 0x05, 0x80, 0x25, 0x0b, 0x06, 0x80, 0x28, 0x0e, 0x07, 0x00, 0x08, 0x16, 0x09, + 0x30, 0x33, 0x00, 0x04, 0x40, 0x33, 0x00, 0x04, 0x80, 0x2b, 0x01, 0x03, 0x88, 0x2b, 0x01, 0x03, 0x90, 0x2b, 0x01, 0x03, 0x98, 0x2b, 0x01, 0x03, 0x08, 0x17, 0x02, 0x03, 0x10, 0x17, 0x02, 0x03, + 0x18, 0x17, 0x02, 0x03, 0x20, 0x17, 0x02, 0x03, 0x10, 0x06, 0x03, 0x03, 0x18, 0x06, 0x03, 0x03, 0xb0, 0x31, 0x04, 0x04, 0xc0, 0x31, 0x04, 0x04, 0x70, 0x1b, 0x05, 0x04, 0x80, 0x1b, 0x05, 0x04, + 0xc0, 0x09, 0x06, 0x04, 0xd0, 0x09, 0x06, 0x04, 0xa0, 0x37, 0x07, 0x05, 0xc0, 0x20, 0x08, 0x05, 0xc0, 0x0f, 0x09, 0x05, 0xc0, 0x25, 0x0b, 0x06, 0x00, 0x29, 0x0e, 0x07, 0x00, 0x0a, 0x16, 0x09, + 0x50, 0x33, 0x00, 0x04, 0x60, 0x33, 0x00, 0x04, 0xa0, 0x2b, 0x01, 0x03, 0xa8, 0x2b, 0x01, 0x03, 0xb0, 0x2b, 0x01, 0x03, 0xb8, 0x2b, 0x01, 0x03, 0x28, 0x17, 0x02, 0x03, 0x30, 0x17, 0x02, 0x03, + 0x38, 0x17, 0x02, 0x03, 0x20, 0x06, 0x03, 0x03, 0x28, 0x06, 0x03, 0x03, 0x30, 0x06, 0x03, 0x03, 0xd0, 0x31, 0x04, 0x04, 0xe0, 0x31, 0x04, 0x04, 0x90, 0x1b, 0x05, 0x04, 0xa0, 0x1b, 0x05, 0x04, + 0xe0, 0x09, 0x06, 0x04, 0xf0, 0x09, 0x06, 0x04, 0xc0, 0x37, 0x07, 0x05, 0xe0, 0x20, 0x08, 0x05, 0xe0, 0x0f, 0x09, 0x05, 0x00, 0x26, 0x0b, 0x06, 0x80, 0x29, 0x0e, 0x07, 0x00, 0x0c, 0x16, 0x09, + 0x70, 0x33, 0x00, 0x04, 0x80, 0x33, 0x00, 0x04, 0xc0, 0x2b, 0x01, 0x03, 0xc8, 0x2b, 0x01, 0x03, 0xd0, 0x2b, 0x01, 0x03, 0xd8, 0x2b, 0x01, 0x03, 0x40, 0x17, 0x02, 0x03, 0x48, 0x17, 0x02, 0x03, + 0x50, 0x17, 0x02, 0x03, 0x38, 0x06, 0x03, 0x03, 0x40, 0x06, 0x03, 0x03, 0x48, 0x06, 0x03, 0x03, 0xf0, 0x31, 0x04, 0x04, 0x00, 0x32, 0x04, 0x04, 0xb0, 0x1b, 0x05, 0x04, 0xc0, 0x1b, 0x05, 0x04, + 0x00, 0x0a, 0x06, 0x04, 0x10, 0x0a, 0x06, 0x04, 0xe0, 0x37, 0x07, 0x05, 0x00, 0x21, 0x08, 0x05, 0x40, 0x3d, 0x0a, 0x06, 0x40, 0x26, 0x0b, 0x06, 0x00, 0x2a, 0x0e, 0x07, 0x00, 0x0e, 0x16, 0x09, + 0x90, 0x33, 0x00, 0x04, 0xa0, 0x33, 0x00, 0x04, 0xe0, 0x2b, 0x01, 0x03, 0xe8, 0x2b, 0x01, 0x03, 0xf0, 0x2b, 0x01, 0x03, 0xf8, 0x2b, 0x01, 0x03, 0x58, 0x17, 0x02, 0x03, 0x60, 0x17, 0x02, 0x03, + 0x68, 0x17, 0x02, 0x03, 0x50, 0x06, 0x03, 0x03, 0x58, 0x06, 0x03, 0x03, 0x60, 0x06, 0x03, 0x03, 0x10, 0x32, 0x04, 0x04, 0x20, 0x32, 0x04, 0x04, 0xd0, 0x1b, 0x05, 0x04, 0xe0, 0x1b, 0x05, 0x04, + 0x20, 0x0a, 0x06, 0x04, 0x30, 0x0a, 0x06, 0x04, 0x00, 0x38, 0x07, 0x05, 0x20, 0x21, 0x08, 0x05, 0x80, 0x3d, 0x0a, 0x06, 0x80, 0x26, 0x0b, 0x06, 0x80, 0x2a, 0x0e, 0x07, 0x00, 0x38, 0x17, 0x0a, + 0xb0, 0x33, 0x00, 0x04, 0xc0, 0x33, 0x00, 0x04, 0x00, 0x2c, 0x01, 0x03, 0x08, 0x2c, 0x01, 0x03, 0x10, 0x2c, 0x01, 0x03, 0x18, 0x2c, 0x01, 0x03, 0x70, 0x17, 0x02, 0x03, 0x78, 0x17, 0x02, 0x03, + 0x80, 0x17, 0x02, 0x03, 0x68, 0x06, 0x03, 0x03, 0x70, 0x06, 0x03, 0x03, 0x78, 0x06, 0x03, 0x03, 0x30, 0x32, 0x04, 0x04, 0x40, 0x32, 0x04, 0x04, 0xf0, 0x1b, 0x05, 0x04, 0x00, 0x1c, 0x05, 0x04, + 0x40, 0x0a, 0x06, 0x04, 0x50, 0x0a, 0x06, 0x04, 0x20, 0x38, 0x07, 0x05, 0x40, 0x21, 0x08, 0x05, 0xc0, 0x3d, 0x0a, 0x06, 0xc0, 0x26, 0x0b, 0x06, 0x00, 0x2b, 0x0e, 0x07, 0x00, 0x3c, 0x17, 0x0a, + 0xd0, 0x33, 0x00, 0x04, 0xe0, 0x33, 0x00, 0x04, 0x20, 0x2c, 0x01, 0x03, 0x28, 0x2c, 0x01, 0x03, 0x30, 0x2c, 0x01, 0x03, 0x38, 0x2c, 0x01, 0x03, 0x88, 0x17, 0x02, 0x03, 0x90, 0x17, 0x02, 0x03, + 0x98, 0x17, 0x02, 0x03, 0x80, 0x06, 0x03, 0x03, 0x88, 0x06, 0x03, 0x03, 0x90, 0x06, 0x03, 0x03, 0x50, 0x32, 0x04, 0x04, 0x60, 0x32, 0x04, 0x04, 0x10, 0x1c, 0x05, 0x04, 0x20, 0x1c, 0x05, 0x04, + 0x60, 0x0a, 0x06, 0x04, 0x70, 0x0a, 0x06, 0x04, 0x40, 0x38, 0x07, 0x05, 0x60, 0x21, 0x08, 0x05, 0x00, 0x3e, 0x0a, 0x06, 0x00, 0x27, 0x0b, 0x06, 0x80, 0x2b, 0x0e, 0x07, 0x00, 0x00, 0x17, 0x09, + 0xf0, 0x33, 0x00, 0x04, 0x00, 0x34, 0x00, 0x04, 0x40, 0x2c, 0x01, 0x03, 0x48, 0x2c, 0x01, 0x03, 0x50, 0x2c, 0x01, 0x03, 0x58, 0x2c, 0x01, 0x03, 0xa0, 0x17, 0x02, 0x03, 0xa8, 0x17, 0x02, 0x03, + 0xb0, 0x17, 0x02, 0x03, 0x98, 0x06, 0x03, 0x03, 0xa0, 0x06, 0x03, 0x03, 0xa8, 0x06, 0x03, 0x03, 0x70, 0x32, 0x04, 0x04, 0x80, 0x32, 0x04, 0x04, 0x30, 0x1c, 0x05, 0x04, 0x40, 0x1c, 0x05, 0x04, + 0x80, 0x0a, 0x06, 0x04, 0x90, 0x0a, 0x06, 0x04, 0x60, 0x38, 0x07, 0x05, 0x80, 0x21, 0x08, 0x05, 0x40, 0x3e, 0x0a, 0x06, 0x40, 0x27, 0x0b, 0x06, 0x00, 0x2c, 0x0e, 0x07, 0x00, 0x1c, 0x18, 0x0a, + 0x10, 0x34, 0x00, 0x04, 0x20, 0x34, 0x00, 0x04, 0x60, 0x2c, 0x01, 0x03, 0x68, 0x2c, 0x01, 0x03, 0x70, 0x2c, 0x01, 0x03, 0x78, 0x2c, 0x01, 0x03, 0xb8, 0x17, 0x02, 0x03, 0xc0, 0x17, 0x02, 0x03, + 0xc8, 0x17, 0x02, 0x03, 0xb0, 0x06, 0x03, 0x03, 0xb8, 0x06, 0x03, 0x03, 0xc0, 0x06, 0x03, 0x03, 0x90, 0x32, 0x04, 0x04, 0xa0, 0x32, 0x04, 0x04, 0x50, 0x1c, 0x05, 0x04, 0x60, 0x1c, 0x05, 0x04, + 0xa0, 0x0a, 0x06, 0x04, 0xb0, 0x0a, 0x06, 0x04, 0x80, 0x38, 0x07, 0x05, 0xa0, 0x21, 0x08, 0x05, 0x80, 0x3e, 0x0a, 0x06, 0x80, 0x27, 0x0b, 0x06, 0x80, 0x2c, 0x0e, 0x07, 0x00, 0x20, 0x18, 0x0a, + 0x30, 0x34, 0x00, 0x04, 0x40, 0x34, 0x00, 0x04, 0x80, 0x2c, 0x01, 0x03, 0x88, 0x2c, 0x01, 0x03, 0x90, 0x2c, 0x01, 0x03, 0x98, 0x2c, 0x01, 0x03, 0xd0, 0x17, 0x02, 0x03, 0xd8, 0x17, 0x02, 0x03, + 0xe0, 0x17, 0x02, 0x03, 0xc8, 0x06, 0x03, 0x03, 0xd0, 0x06, 0x03, 0x03, 0xd8, 0x06, 0x03, 0x03, 0xb0, 0x32, 0x04, 0x04, 0xc0, 0x32, 0x04, 0x04, 0x70, 0x1c, 0x05, 0x04, 0x80, 0x1c, 0x05, 0x04, + 0xc0, 0x0a, 0x06, 0x04, 0xd0, 0x0a, 0x06, 0x04, 0xa0, 0x38, 0x07, 0x05, 0xc0, 0x21, 0x08, 0x05, 0xc0, 0x3e, 0x0a, 0x06, 0xc0, 0x27, 0x0b, 0x06, 0x00, 0x2d, 0x0e, 0x07, 0x00, 0x24, 0x18, 0x0a, + 0x50, 0x34, 0x00, 0x04, 0x60, 0x34, 0x00, 0x04, 0xa0, 0x2c, 0x01, 0x03, 0xa8, 0x2c, 0x01, 0x03, 0xb0, 0x2c, 0x01, 0x03, 0xb8, 0x2c, 0x01, 0x03, 0xe8, 0x17, 0x02, 0x03, 0xf0, 0x17, 0x02, 0x03, + 0xf8, 0x17, 0x02, 0x03, 0xe0, 0x06, 0x03, 0x03, 0xe8, 0x06, 0x03, 0x03, 0xf0, 0x06, 0x03, 0x03, 0xd0, 0x32, 0x04, 0x04, 0xe0, 0x32, 0x04, 0x04, 0x90, 0x1c, 0x05, 0x04, 0xa0, 0x1c, 0x05, 0x04, + 0xe0, 0x0a, 0x06, 0x04, 0xf0, 0x0a, 0x06, 0x04, 0xc0, 0x38, 0x07, 0x05, 0xe0, 0x21, 0x08, 0x05, 0x00, 0x3f, 0x0a, 0x06, 0x00, 0x28, 0x0b, 0x06, 0x80, 0x2d, 0x0e, 0x07, 0x00, 0x0c, 0x19, 0x0a, + 0x70, 0x34, 0x00, 0x04, 0x80, 0x34, 0x00, 0x04, 0xc0, 0x2c, 0x01, 0x03, 0xc8, 0x2c, 0x01, 0x03, 0xd0, 0x2c, 0x01, 0x03, 0xd8, 0x2c, 0x01, 0x03, 0x00, 0x18, 0x02, 0x03, 0x08, 0x18, 0x02, 0x03, + 0x10, 0x18, 0x02, 0x03, 0xf8, 0x06, 0x03, 0x03, 0x00, 0x07, 0x03, 0x03, 0x08, 0x07, 0x03, 0x03, 0xf0, 0x32, 0x04, 0x04, 0x00, 0x33, 0x04, 0x04, 0xb0, 0x1c, 0x05, 0x04, 0xc0, 0x1c, 0x05, 0x04, + 0x00, 0x0b, 0x06, 0x04, 0x10, 0x0b, 0x06, 0x04, 0xe0, 0x38, 0x07, 0x05, 0x00, 0x22, 0x08, 0x05, 0x40, 0x3f, 0x0a, 0x06, 0x40, 0x28, 0x0b, 0x06, 0x00, 0x2e, 0x0e, 0x07, 0x00, 0x10, 0x19, 0x0a, + 0x90, 0x34, 0x00, 0x04, 0xa0, 0x34, 0x00, 0x04, 0xe0, 0x2c, 0x01, 0x03, 0xe8, 0x2c, 0x01, 0x03, 0xf0, 0x2c, 0x01, 0x03, 0xf8, 0x2c, 0x01, 0x03, 0x18, 0x18, 0x02, 0x03, 0x20, 0x18, 0x02, 0x03, + 0x28, 0x18, 0x02, 0x03, 0x10, 0x07, 0x03, 0x03, 0x18, 0x07, 0x03, 0x03, 0x20, 0x07, 0x03, 0x03, 0x10, 0x33, 0x04, 0x04, 0x20, 0x33, 0x04, 0x04, 0xd0, 0x1c, 0x05, 0x04, 0xe0, 0x1c, 0x05, 0x04, + 0x20, 0x0b, 0x06, 0x04, 0x30, 0x0b, 0x06, 0x04, 0x00, 0x39, 0x07, 0x05, 0x20, 0x22, 0x08, 0x05, 0x80, 0x3f, 0x0a, 0x06, 0x80, 0x28, 0x0b, 0x06, 0x80, 0x15, 0x0f, 0x07, 0x00, 0x00, 0x1a, 0x0a, + 0xb0, 0x34, 0x00, 0x04, 0xc0, 0x34, 0x00, 0x04, 0x00, 0x2d, 0x01, 0x03, 0x08, 0x2d, 0x01, 0x03, 0x10, 0x2d, 0x01, 0x03, 0x18, 0x2d, 0x01, 0x03, 0x30, 0x18, 0x02, 0x03, 0x38, 0x18, 0x02, 0x03, + 0x40, 0x18, 0x02, 0x03, 0x28, 0x07, 0x03, 0x03, 0x30, 0x07, 0x03, 0x03, 0x38, 0x07, 0x03, 0x03, 0x30, 0x33, 0x04, 0x04, 0x40, 0x33, 0x04, 0x04, 0xf0, 0x1c, 0x05, 0x04, 0x00, 0x1d, 0x05, 0x04, + 0x40, 0x0b, 0x06, 0x04, 0x50, 0x0b, 0x06, 0x04, 0x20, 0x39, 0x07, 0x05, 0x40, 0x22, 0x08, 0x05, 0xc0, 0x3f, 0x0a, 0x06, 0x00, 0x13, 0x0c, 0x06, 0x00, 0x16, 0x0f, 0x07, 0x00, 0x04, 0x1a, 0x0a, + 0xd0, 0x34, 0x00, 0x04, 0xe0, 0x34, 0x00, 0x04, 0x20, 0x2d, 0x01, 0x03, 0x28, 0x2d, 0x01, 0x03, 0x30, 0x2d, 0x01, 0x03, 0x38, 0x2d, 0x01, 0x03, 0x48, 0x18, 0x02, 0x03, 0x50, 0x18, 0x02, 0x03, + 0x58, 0x18, 0x02, 0x03, 0x40, 0x07, 0x03, 0x03, 0x48, 0x07, 0x03, 0x03, 0x50, 0x07, 0x03, 0x03, 0x50, 0x33, 0x04, 0x04, 0x60, 0x33, 0x04, 0x04, 0x10, 0x1d, 0x05, 0x04, 0x20, 0x1d, 0x05, 0x04, + 0x60, 0x0b, 0x06, 0x04, 0x70, 0x0b, 0x06, 0x04, 0x40, 0x39, 0x07, 0x05, 0x60, 0x22, 0x08, 0x05, 0x00, 0x00, 0x0a, 0x05, 0x40, 0x13, 0x0c, 0x06, 0x80, 0x16, 0x0f, 0x07, 0x00, 0x28, 0x1b, 0x0b, + 0xf0, 0x34, 0x00, 0x04, 0x00, 0x35, 0x00, 0x04, 0x40, 0x2d, 0x01, 0x03, 0x48, 0x2d, 0x01, 0x03, 0x50, 0x2d, 0x01, 0x03, 0x58, 0x2d, 0x01, 0x03, 0x60, 0x18, 0x02, 0x03, 0x68, 0x18, 0x02, 0x03, + 0x70, 0x18, 0x02, 0x03, 0x58, 0x07, 0x03, 0x03, 0x60, 0x07, 0x03, 0x03, 0x68, 0x07, 0x03, 0x03, 0x70, 0x33, 0x04, 0x04, 0x80, 0x33, 0x04, 0x04, 0x30, 0x1d, 0x05, 0x04, 0x40, 0x1d, 0x05, 0x04, + 0x80, 0x0b, 0x06, 0x04, 0x60, 0x39, 0x07, 0x05, 0x80, 0x39, 0x07, 0x05, 0x80, 0x22, 0x08, 0x05, 0x20, 0x00, 0x0a, 0x05, 0x80, 0x13, 0x0c, 0x06, 0x00, 0x17, 0x0f, 0x07, 0x00, 0x10, 0x1c, 0x0b, + 0x10, 0x35, 0x00, 0x04, 0x20, 0x35, 0x00, 0x04, 0x60, 0x2d, 0x01, 0x03, 0x68, 0x2d, 0x01, 0x03, 0x70, 0x2d, 0x01, 0x03, 0x78, 0x2d, 0x01, 0x03, 0x78, 0x18, 0x02, 0x03, 0x80, 0x18, 0x02, 0x03, + 0x88, 0x18, 0x02, 0x03, 0x70, 0x07, 0x03, 0x03, 0x78, 0x07, 0x03, 0x03, 0x80, 0x07, 0x03, 0x03, 0x90, 0x33, 0x04, 0x04, 0xa0, 0x33, 0x04, 0x04, 0x50, 0x1d, 0x05, 0x04, 0x60, 0x1d, 0x05, 0x04, + 0x90, 0x0b, 0x06, 0x04, 0xa0, 0x39, 0x07, 0x05, 0xc0, 0x39, 0x07, 0x05, 0xa0, 0x22, 0x08, 0x05, 0x40, 0x00, 0x0a, 0x05, 0xc0, 0x13, 0x0c, 0x06, 0x80, 0x17, 0x0f, 0x07, 0x00, 0x18, 0x1c, 0x0b, + 0x30, 0x35, 0x00, 0x04, 0x40, 0x35, 0x00, 0x04, 0x80, 0x2d, 0x01, 0x03, 0x88, 0x2d, 0x01, 0x03, 0x90, 0x2d, 0x01, 0x03, 0x98, 0x2d, 0x01, 0x03, 0x90, 0x18, 0x02, 0x03, 0x98, 0x18, 0x02, 0x03, + 0xa0, 0x18, 0x02, 0x03, 0x88, 0x07, 0x03, 0x03, 0x90, 0x07, 0x03, 0x03, 0x98, 0x07, 0x03, 0x03, 0xb0, 0x33, 0x04, 0x04, 0xc0, 0x33, 0x04, 0x04, 0x70, 0x1d, 0x05, 0x04, 0x80, 0x1d, 0x05, 0x04, + 0xa0, 0x0b, 0x06, 0x04, 0xe0, 0x39, 0x07, 0x05, 0x00, 0x3a, 0x07, 0x05, 0xc0, 0x22, 0x08, 0x05, 0x60, 0x00, 0x0a, 0x05, 0x00, 0x14, 0x0c, 0x06, 0x00, 0x18, 0x0f, 0x07, 0x00, 0x00, 0x1d, 0x0b, + 0x50, 0x35, 0x00, 0x04, 0x60, 0x35, 0x00, 0x04, 0xa0, 0x2d, 0x01, 0x03, 0xa8, 0x2d, 0x01, 0x03, 0xb0, 0x2d, 0x01, 0x03, 0xb8, 0x2d, 0x01, 0x03, 0xa8, 0x18, 0x02, 0x03, 0xb0, 0x18, 0x02, 0x03, + 0xb8, 0x18, 0x02, 0x03, 0xa0, 0x07, 0x03, 0x03, 0xa8, 0x07, 0x03, 0x03, 0xb0, 0x07, 0x03, 0x03, 0xd0, 0x33, 0x04, 0x04, 0xe0, 0x33, 0x04, 0x04, 0x90, 0x1d, 0x05, 0x04, 0xa0, 0x1d, 0x05, 0x04, + 0xb0, 0x0b, 0x06, 0x04, 0x20, 0x3a, 0x07, 0x05, 0x40, 0x3a, 0x07, 0x05, 0xe0, 0x22, 0x08, 0x05, 0x80, 0x00, 0x0a, 0x05, 0x40, 0x14, 0x0c, 0x06, 0x80, 0x18, 0x0f, 0x07, 0x00, 0x30, 0x1e, 0x0c, + 0x70, 0x35, 0x00, 0x04, 0x80, 0x35, 0x00, 0x04, 0xc0, 0x2d, 0x01, 0x03, 0xc8, 0x2d, 0x01, 0x03, 0xd0, 0x2d, 0x01, 0x03, 0xd8, 0x2d, 0x01, 0x03, 0xc0, 0x18, 0x02, 0x03, 0xc8, 0x18, 0x02, 0x03, + 0xd0, 0x18, 0x02, 0x03, 0xb8, 0x07, 0x03, 0x03, 0xc0, 0x07, 0x03, 0x03, 0xc8, 0x07, 0x03, 0x03, 0xf0, 0x33, 0x04, 0x04, 0x00, 0x34, 0x04, 0x04, 0xb0, 0x1d, 0x05, 0x04, 0xc0, 0x1d, 0x05, 0x04, + 0xc0, 0x0b, 0x06, 0x04, 0x60, 0x3a, 0x07, 0x05, 0x80, 0x3a, 0x07, 0x05, 0x00, 0x23, 0x08, 0x05, 0xa0, 0x00, 0x0a, 0x05, 0x80, 0x14, 0x0c, 0x06, 0x00, 0x19, 0x0f, 0x07, 0x00, 0x00, 0x20, 0x0c, + 0x90, 0x35, 0x00, 0x04, 0xa0, 0x35, 0x00, 0x04, 0xe0, 0x2d, 0x01, 0x03, 0xe8, 0x2d, 0x01, 0x03, 0xf0, 0x2d, 0x01, 0x03, 0xf8, 0x2d, 0x01, 0x03, 0xd8, 0x18, 0x02, 0x03, 0xe0, 0x18, 0x02, 0x03, + 0xe8, 0x18, 0x02, 0x03, 0xd0, 0x07, 0x03, 0x03, 0xd8, 0x07, 0x03, 0x03, 0xe0, 0x07, 0x03, 0x03, 0x10, 0x34, 0x04, 0x04, 0x20, 0x34, 0x04, 0x04, 0xd0, 0x1d, 0x05, 0x04, 0xe0, 0x1d, 0x05, 0x04, + 0xd0, 0x0b, 0x06, 0x04, 0xa0, 0x3a, 0x07, 0x05, 0xc0, 0x3a, 0x07, 0x05, 0x20, 0x23, 0x08, 0x05, 0xc0, 0x00, 0x0a, 0x05, 0xc0, 0x14, 0x0c, 0x06, 0x80, 0x19, 0x0f, 0x07, 0x00, 0x20, 0x22, 0x0d, + 0xb0, 0x35, 0x00, 0x04, 0xc0, 0x35, 0x00, 0x04, 0x00, 0x2e, 0x01, 0x03, 0x08, 0x2e, 0x01, 0x03, 0x10, 0x2e, 0x01, 0x03, 0x18, 0x2e, 0x01, 0x03, 0xf0, 0x18, 0x02, 0x03, 0xf8, 0x18, 0x02, 0x03, + 0x00, 0x19, 0x02, 0x03, 0xe8, 0x07, 0x03, 0x03, 0xf0, 0x07, 0x03, 0x03, 0xf8, 0x07, 0x03, 0x03, 0x30, 0x34, 0x04, 0x04, 0x40, 0x34, 0x04, 0x04, 0xf0, 0x1d, 0x05, 0x04, 0x00, 0x1e, 0x05, 0x04, + 0xe0, 0x0b, 0x06, 0x04, 0xe0, 0x3a, 0x07, 0x05, 0x00, 0x3b, 0x07, 0x05, 0x40, 0x23, 0x08, 0x05, 0xe0, 0x00, 0x0a, 0x05, 0x00, 0x15, 0x0c, 0x06, 0x00, 0x1a, 0x0f, 0x07, 0xd0, 0x35, 0x00, 0x04, + 0xe0, 0x35, 0x00, 0x04, 0xf0, 0x35, 0x00, 0x04, 0x20, 0x2e, 0x01, 0x03, 0x28, 0x2e, 0x01, 0x03, 0x30, 0x2e, 0x01, 0x03, 0x38, 0x2e, 0x01, 0x03, 0x08, 0x19, 0x02, 0x03, 0x10, 0x19, 0x02, 0x03, + 0x18, 0x19, 0x02, 0x03, 0x00, 0x08, 0x03, 0x03, 0x08, 0x08, 0x03, 0x03, 0x10, 0x08, 0x03, 0x03, 0x50, 0x34, 0x04, 0x04, 0x60, 0x34, 0x04, 0x04, 0x10, 0x1e, 0x05, 0x04, 0x20, 0x1e, 0x05, 0x04, + 0xf0, 0x0b, 0x06, 0x04, 0x20, 0x3b, 0x07, 0x05, 0x40, 0x3b, 0x07, 0x05, 0x60, 0x23, 0x08, 0x05, 0x00, 0x01, 0x0a, 0x05, 0x40, 0x15, 0x0c, 0x06, 0x80, 0x1a, 0x0f, 0x07, 0x00, 0x36, 0x00, 0x04, + 0x10, 0x36, 0x00, 0x04, 0x20, 0x36, 0x00, 0x04, 0x40, 0x2e, 0x01, 0x03, 0x48, 0x2e, 0x01, 0x03, 0x50, 0x2e, 0x01, 0x03, 0x58, 0x2e, 0x01, 0x03, 0x20, 0x19, 0x02, 0x03, 0x28, 0x19, 0x02, 0x03, + 0x30, 0x19, 0x02, 0x03, 0x18, 0x08, 0x03, 0x03, 0x20, 0x08, 0x03, 0x03, 0x28, 0x08, 0x03, 0x03, 0x70, 0x34, 0x04, 0x04, 0x80, 0x34, 0x04, 0x04, 0x30, 0x1e, 0x05, 0x04, 0x40, 0x1e, 0x05, 0x04, + 0x00, 0x0c, 0x06, 0x04, 0x60, 0x3b, 0x07, 0x05, 0x80, 0x3b, 0x07, 0x05, 0x80, 0x23, 0x08, 0x05, 0x20, 0x01, 0x0a, 0x05, 0x80, 0x15, 0x0c, 0x06, 0x00, 0x1b, 0x0f, 0x07, 0x30, 0x36, 0x00, 0x04, + 0x40, 0x36, 0x00, 0x04, 0x50, 0x36, 0x00, 0x04, 0x60, 0x2e, 0x01, 0x03, 0x68, 0x2e, 0x01, 0x03, 0x70, 0x2e, 0x01, 0x03, 0x78, 0x2e, 0x01, 0x03, 0x38, 0x19, 0x02, 0x03, 0x40, 0x19, 0x02, 0x03, + 0x48, 0x19, 0x02, 0x03, 0x30, 0x08, 0x03, 0x03, 0x38, 0x08, 0x03, 0x03, 0x40, 0x08, 0x03, 0x03, 0x90, 0x34, 0x04, 0x04, 0xa0, 0x34, 0x04, 0x04, 0x50, 0x1e, 0x05, 0x04, 0x60, 0x1e, 0x05, 0x04, + 0x10, 0x0c, 0x06, 0x04, 0xa0, 0x3b, 0x07, 0x05, 0xc0, 0x3b, 0x07, 0x05, 0x00, 0x10, 0x09, 0x05, 0x40, 0x01, 0x0a, 0x05, 0xc0, 0x15, 0x0c, 0x06, 0x80, 0x1b, 0x0f, 0x07, 0x60, 0x36, 0x00, 0x04, + 0x70, 0x36, 0x00, 0x04, 0x80, 0x36, 0x00, 0x04, 0x80, 0x2e, 0x01, 0x03, 0x88, 0x2e, 0x01, 0x03, 0x90, 0x2e, 0x01, 0x03, 0x98, 0x2e, 0x01, 0x03, 0x50, 0x19, 0x02, 0x03, 0x58, 0x19, 0x02, 0x03, + 0x60, 0x19, 0x02, 0x03, 0x48, 0x08, 0x03, 0x03, 0x50, 0x08, 0x03, 0x03, 0x58, 0x08, 0x03, 0x03, 0xb0, 0x34, 0x04, 0x04, 0xc0, 0x34, 0x04, 0x04, 0x70, 0x1e, 0x05, 0x04, 0x80, 0x1e, 0x05, 0x04, + 0x20, 0x0c, 0x06, 0x04, 0xe0, 0x3b, 0x07, 0x05, 0x00, 0x3c, 0x07, 0x05, 0x20, 0x10, 0x09, 0x05, 0x60, 0x01, 0x0a, 0x05, 0x00, 0x16, 0x0c, 0x06, 0x00, 0x1c, 0x0f, 0x07, 0x90, 0x36, 0x00, 0x04, + 0xa0, 0x36, 0x00, 0x04, 0xb0, 0x36, 0x00, 0x04, 0xa0, 0x2e, 0x01, 0x03, 0xa8, 0x2e, 0x01, 0x03, 0xb0, 0x2e, 0x01, 0x03, 0xb8, 0x2e, 0x01, 0x03, 0x68, 0x19, 0x02, 0x03, 0x70, 0x19, 0x02, 0x03, + 0x78, 0x19, 0x02, 0x03, 0x60, 0x08, 0x03, 0x03, 0x68, 0x08, 0x03, 0x03, 0x70, 0x08, 0x03, 0x03, 0xd0, 0x34, 0x04, 0x04, 0xe0, 0x34, 0x04, 0x04, 0x90, 0x1e, 0x05, 0x04, 0xa0, 0x1e, 0x05, 0x04, + 0x30, 0x0c, 0x06, 0x04, 0x20, 0x3c, 0x07, 0x05, 0x40, 0x3c, 0x07, 0x05, 0x40, 0x10, 0x09, 0x05, 0x80, 0x01, 0x0a, 0x05, 0x40, 0x16, 0x0c, 0x06, 0x80, 0x1c, 0x0f, 0x07, 0xc0, 0x36, 0x00, 0x04, + 0xd0, 0x36, 0x00, 0x04, 0xe0, 0x36, 0x00, 0x04, 0xc0, 0x2e, 0x01, 0x03, 0xc8, 0x2e, 0x01, 0x03, 0xd0, 0x2e, 0x01, 0x03, 0xd8, 0x2e, 0x01, 0x03, 0x80, 0x19, 0x02, 0x03, 0x88, 0x19, 0x02, 0x03, + 0x90, 0x19, 0x02, 0x03, 0x78, 0x08, 0x03, 0x03, 0x80, 0x08, 0x03, 0x03, 0x88, 0x08, 0x03, 0x03, 0xf0, 0x34, 0x04, 0x04, 0x00, 0x35, 0x04, 0x04, 0xb0, 0x1e, 0x05, 0x04, 0xc0, 0x1e, 0x05, 0x04, + 0x40, 0x0c, 0x06, 0x04, 0x60, 0x3c, 0x07, 0x05, 0x80, 0x3c, 0x07, 0x05, 0x60, 0x10, 0x09, 0x05, 0xa0, 0x01, 0x0a, 0x05, 0x80, 0x16, 0x0c, 0x06, 0x00, 0x1d, 0x0f, 0x07, 0xf0, 0x36, 0x00, 0x04, + 0x00, 0x37, 0x00, 0x04, 0x10, 0x37, 0x00, 0x04, 0xe0, 0x2e, 0x01, 0x03, 0xe8, 0x2e, 0x01, 0x03, 0xf0, 0x2e, 0x01, 0x03, 0xf8, 0x2e, 0x01, 0x03, 0x98, 0x19, 0x02, 0x03, 0xa0, 0x19, 0x02, 0x03, + 0xa8, 0x19, 0x02, 0x03, 0x90, 0x08, 0x03, 0x03, 0x98, 0x08, 0x03, 0x03, 0xa0, 0x08, 0x03, 0x03, 0x10, 0x35, 0x04, 0x04, 0x20, 0x35, 0x04, 0x04, 0xd0, 0x1e, 0x05, 0x04, 0xe0, 0x1e, 0x05, 0x04, + 0x50, 0x0c, 0x06, 0x04, 0xa0, 0x3c, 0x07, 0x05, 0xc0, 0x3c, 0x07, 0x05, 0x80, 0x10, 0x09, 0x05, 0xc0, 0x01, 0x0a, 0x05, 0xc0, 0x16, 0x0c, 0x06, 0x80, 0x1d, 0x0f, 0x07, 0x20, 0x37, 0x00, 0x04, + 0x30, 0x37, 0x00, 0x04, 0x40, 0x37, 0x00, 0x04, 0x00, 0x2f, 0x01, 0x03, 0x08, 0x2f, 0x01, 0x03, 0x10, 0x2f, 0x01, 0x03, 0x18, 0x2f, 0x01, 0x03, 0xb0, 0x19, 0x02, 0x03, 0xb8, 0x19, 0x02, 0x03, + 0xc0, 0x19, 0x02, 0x03, 0xa8, 0x08, 0x03, 0x03, 0xb0, 0x08, 0x03, 0x03, 0xb8, 0x08, 0x03, 0x03, 0x30, 0x35, 0x04, 0x04, 0x40, 0x35, 0x04, 0x04, 0xf0, 0x1e, 0x05, 0x04, 0x00, 0x1f, 0x05, 0x04, + 0x60, 0x0c, 0x06, 0x04, 0xe0, 0x3c, 0x07, 0x05, 0xa0, 0x23, 0x08, 0x05, 0xa0, 0x10, 0x09, 0x05, 0xe0, 0x01, 0x0a, 0x05, 0x00, 0x17, 0x0c, 0x06, 0x00, 0x1e, 0x0f, 0x07, 0x50, 0x37, 0x00, 0x04, + 0x60, 0x37, 0x00, 0x04, 0x70, 0x37, 0x00, 0x04, 0x20, 0x2f, 0x01, 0x03, 0x28, 0x2f, 0x01, 0x03, 0x30, 0x2f, 0x01, 0x03, 0x38, 0x2f, 0x01, 0x03, 0xc8, 0x19, 0x02, 0x03, 0xd0, 0x19, 0x02, 0x03, + 0xd8, 0x19, 0x02, 0x03, 0xc0, 0x08, 0x03, 0x03, 0xc8, 0x08, 0x03, 0x03, 0xd0, 0x08, 0x03, 0x03, 0x50, 0x35, 0x04, 0x04, 0x60, 0x35, 0x04, 0x04, 0x10, 0x1f, 0x05, 0x04, 0x20, 0x1f, 0x05, 0x04, + 0x70, 0x0c, 0x06, 0x04, 0x00, 0x3d, 0x07, 0x05, 0xc0, 0x23, 0x08, 0x05, 0xc0, 0x10, 0x09, 0x05, 0x00, 0x02, 0x0a, 0x05, 0x40, 0x17, 0x0c, 0x06, 0x80, 0x1e, 0x0f, 0x07, 0x80, 0x37, 0x00, 0x04, + 0x90, 0x37, 0x00, 0x04, 0xa0, 0x37, 0x00, 0x04, 0x40, 0x2f, 0x01, 0x03, 0x48, 0x2f, 0x01, 0x03, 0x50, 0x2f, 0x01, 0x03, 0x58, 0x2f, 0x01, 0x03, 0xe0, 0x19, 0x02, 0x03, 0xe8, 0x19, 0x02, 0x03, + 0xf0, 0x19, 0x02, 0x03, 0xd8, 0x08, 0x03, 0x03, 0xe0, 0x08, 0x03, 0x03, 0xe8, 0x08, 0x03, 0x03, 0x70, 0x35, 0x04, 0x04, 0x80, 0x35, 0x04, 0x04, 0x30, 0x1f, 0x05, 0x04, 0x40, 0x1f, 0x05, 0x04, + 0x80, 0x0c, 0x06, 0x04, 0x20, 0x3d, 0x07, 0x05, 0xe0, 0x23, 0x08, 0x05, 0xe0, 0x10, 0x09, 0x05, 0x20, 0x02, 0x0a, 0x05, 0x80, 0x17, 0x0c, 0x06, 0x00, 0x09, 0x10, 0x07, 0xb0, 0x37, 0x00, 0x04, + 0xc0, 0x37, 0x00, 0x04, 0xd0, 0x37, 0x00, 0x04, 0x60, 0x2f, 0x01, 0x03, 0x68, 0x2f, 0x01, 0x03, 0x70, 0x2f, 0x01, 0x03, 0x78, 0x2f, 0x01, 0x03, 0xf8, 0x19, 0x02, 0x03, 0x00, 0x1a, 0x02, 0x03, + 0x08, 0x1a, 0x02, 0x03, 0xf0, 0x08, 0x03, 0x03, 0xf8, 0x08, 0x03, 0x03, 0x00, 0x09, 0x03, 0x03, 0x90, 0x35, 0x04, 0x04, 0xa0, 0x35, 0x04, 0x04, 0x50, 0x1f, 0x05, 0x04, 0x60, 0x1f, 0x05, 0x04, + 0x90, 0x0c, 0x06, 0x04, 0x40, 0x3d, 0x07, 0x05, 0x00, 0x24, 0x08, 0x05, 0x00, 0x11, 0x09, 0x05, 0x40, 0x02, 0x0a, 0x05, 0xc0, 0x17, 0x0c, 0x06, 0x80, 0x09, 0x10, 0x07, 0xe0, 0x37, 0x00, 0x04, + 0xf0, 0x37, 0x00, 0x04, 0x00, 0x38, 0x00, 0x04, 0x80, 0x2f, 0x01, 0x03, 0x88, 0x2f, 0x01, 0x03, 0x90, 0x2f, 0x01, 0x03, 0x98, 0x2f, 0x01, 0x03, 0x10, 0x1a, 0x02, 0x03, 0x18, 0x1a, 0x02, 0x03, + 0x20, 0x1a, 0x02, 0x03, 0x08, 0x09, 0x03, 0x03, 0x10, 0x09, 0x03, 0x03, 0x18, 0x09, 0x03, 0x03, 0xb0, 0x35, 0x04, 0x04, 0xc0, 0x35, 0x04, 0x04, 0x70, 0x1f, 0x05, 0x04, 0x80, 0x1f, 0x05, 0x04, + 0xa0, 0x0c, 0x06, 0x04, 0x60, 0x3d, 0x07, 0x05, 0x20, 0x24, 0x08, 0x05, 0x20, 0x11, 0x09, 0x05, 0x60, 0x02, 0x0a, 0x05, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x0a, 0x10, 0x07, 0x10, 0x38, 0x00, 0x04, + 0x20, 0x38, 0x00, 0x04, 0x30, 0x38, 0x00, 0x04, 0xa0, 0x2f, 0x01, 0x03, 0xa8, 0x2f, 0x01, 0x03, 0xb0, 0x2f, 0x01, 0x03, 0xb8, 0x2f, 0x01, 0x03, 0x28, 0x1a, 0x02, 0x03, 0x30, 0x1a, 0x02, 0x03, + 0x38, 0x1a, 0x02, 0x03, 0x20, 0x09, 0x03, 0x03, 0x28, 0x09, 0x03, 0x03, 0x30, 0x09, 0x03, 0x03, 0xd0, 0x35, 0x04, 0x04, 0xe0, 0x35, 0x04, 0x04, 0x90, 0x1f, 0x05, 0x04, 0xa0, 0x1f, 0x05, 0x04, + 0xb0, 0x0c, 0x06, 0x04, 0x80, 0x3d, 0x07, 0x05, 0x40, 0x24, 0x08, 0x05, 0x40, 0x11, 0x09, 0x05, 0x80, 0x02, 0x0a, 0x05, 0x40, 0x18, 0x0c, 0x06, 0x80, 0x0a, 0x10, 0x07, 0x40, 0x38, 0x00, 0x04, + 0x50, 0x38, 0x00, 0x04, 0x60, 0x38, 0x00, 0x04, 0xc0, 0x2f, 0x01, 0x03, 0xc8, 0x2f, 0x01, 0x03, 0xd0, 0x2f, 0x01, 0x03, 0xd8, 0x2f, 0x01, 0x03, 0x40, 0x1a, 0x02, 0x03, 0x48, 0x1a, 0x02, 0x03, + 0x50, 0x1a, 0x02, 0x03, 0x38, 0x09, 0x03, 0x03, 0x40, 0x09, 0x03, 0x03, 0x48, 0x09, 0x03, 0x03, 0xf0, 0x35, 0x04, 0x04, 0x00, 0x36, 0x04, 0x04, 0xb0, 0x1f, 0x05, 0x04, 0xc0, 0x1f, 0x05, 0x04, + 0xc0, 0x0c, 0x06, 0x04, 0xa0, 0x3d, 0x07, 0x05, 0x60, 0x24, 0x08, 0x05, 0x60, 0x11, 0x09, 0x05, 0xa0, 0x02, 0x0a, 0x05, 0x80, 0x18, 0x0c, 0x06, 0x00, 0x0b, 0x10, 0x07, 0x70, 0x38, 0x00, 0x04, + 0x80, 0x38, 0x00, 0x04, 0x90, 0x38, 0x00, 0x04, 0xe0, 0x2f, 0x01, 0x03, 0xe8, 0x2f, 0x01, 0x03, 0xf0, 0x2f, 0x01, 0x03, 0xf8, 0x2f, 0x01, 0x03, 0x58, 0x1a, 0x02, 0x03, 0x60, 0x1a, 0x02, 0x03, + 0x68, 0x1a, 0x02, 0x03, 0x50, 0x09, 0x03, 0x03, 0x58, 0x09, 0x03, 0x03, 0x60, 0x09, 0x03, 0x03, 0x10, 0x36, 0x04, 0x04, 0x20, 0x36, 0x04, 0x04, 0xd0, 0x1f, 0x05, 0x04, 0xe0, 0x1f, 0x05, 0x04, + 0xd0, 0x0c, 0x06, 0x04, 0xc0, 0x3d, 0x07, 0x05, 0x80, 0x24, 0x08, 0x05, 0x80, 0x11, 0x09, 0x05, 0xc0, 0x02, 0x0a, 0x05, 0xc0, 0x18, 0x0c, 0x06, 0x80, 0x0b, 0x10, 0x07, 0xa0, 0x38, 0x00, 0x04, + 0xb0, 0x38, 0x00, 0x04, 0xc0, 0x38, 0x00, 0x04, 0x00, 0x30, 0x01, 0x03, 0x08, 0x30, 0x01, 0x03, 0x10, 0x30, 0x01, 0x03, 0x18, 0x30, 0x01, 0x03, 0x70, 0x1a, 0x02, 0x03, 0x78, 0x1a, 0x02, 0x03, + 0x80, 0x1a, 0x02, 0x03, 0x68, 0x09, 0x03, 0x03, 0x70, 0x09, 0x03, 0x03, 0x78, 0x09, 0x03, 0x03, 0x30, 0x36, 0x04, 0x04, 0x40, 0x36, 0x04, 0x04, 0xf0, 0x1f, 0x05, 0x04, 0x00, 0x20, 0x05, 0x04, + 0xe0, 0x0c, 0x06, 0x04, 0xe0, 0x3d, 0x07, 0x05, 0xa0, 0x24, 0x08, 0x05, 0xa0, 0x11, 0x09, 0x05, 0xe0, 0x02, 0x0a, 0x05, 0x00, 0x19, 0x0c, 0x06, 0x00, 0x0c, 0x10, 0x07, 0xd0, 0x38, 0x00, 0x04, + 0xe0, 0x38, 0x00, 0x04, 0xf0, 0x38, 0x00, 0x04, 0x20, 0x30, 0x01, 0x03, 0x28, 0x30, 0x01, 0x03, 0x30, 0x30, 0x01, 0x03, 0x38, 0x30, 0x01, 0x03, 0x88, 0x1a, 0x02, 0x03, 0x90, 0x1a, 0x02, 0x03, + 0x98, 0x1a, 0x02, 0x03, 0x80, 0x09, 0x03, 0x03, 0x88, 0x09, 0x03, 0x03, 0x90, 0x09, 0x03, 0x03, 0x50, 0x36, 0x04, 0x04, 0x60, 0x36, 0x04, 0x04, 0x10, 0x20, 0x05, 0x04, 0x20, 0x20, 0x05, 0x04, + 0xf0, 0x0c, 0x06, 0x04, 0x00, 0x3e, 0x07, 0x05, 0xc0, 0x24, 0x08, 0x05, 0xc0, 0x11, 0x09, 0x05, 0x00, 0x03, 0x0a, 0x05, 0x40, 0x19, 0x0c, 0x06, 0x80, 0x0c, 0x10, 0x07, 0x00, 0x39, 0x00, 0x04, + 0x10, 0x39, 0x00, 0x04, 0x20, 0x39, 0x00, 0x04, 0x40, 0x30, 0x01, 0x03, 0x48, 0x30, 0x01, 0x03, 0x50, 0x30, 0x01, 0x03, 0x58, 0x30, 0x01, 0x03, 0xa0, 0x1a, 0x02, 0x03, 0xa8, 0x1a, 0x02, 0x03, + 0xb0, 0x1a, 0x02, 0x03, 0x98, 0x09, 0x03, 0x03, 0xa0, 0x09, 0x03, 0x03, 0xa8, 0x09, 0x03, 0x03, 0x70, 0x36, 0x04, 0x04, 0x80, 0x36, 0x04, 0x04, 0x30, 0x20, 0x05, 0x04, 0x40, 0x20, 0x05, 0x04, + 0x00, 0x0d, 0x06, 0x04, 0x20, 0x3e, 0x07, 0x05, 0xe0, 0x24, 0x08, 0x05, 0xe0, 0x11, 0x09, 0x05, 0x20, 0x03, 0x0a, 0x05, 0x80, 0x19, 0x0c, 0x06, 0x00, 0x0d, 0x10, 0x07, 0x30, 0x39, 0x00, 0x04, + 0x40, 0x39, 0x00, 0x04, 0x50, 0x39, 0x00, 0x04, 0x60, 0x30, 0x01, 0x03, 0x68, 0x30, 0x01, 0x03, 0x70, 0x30, 0x01, 0x03, 0x78, 0x30, 0x01, 0x03, 0xb8, 0x1a, 0x02, 0x03, 0xc0, 0x1a, 0x02, 0x03, + 0xc8, 0x1a, 0x02, 0x03, 0xb0, 0x09, 0x03, 0x03, 0xb8, 0x09, 0x03, 0x03, 0xc0, 0x09, 0x03, 0x03, 0x90, 0x36, 0x04, 0x04, 0xa0, 0x36, 0x04, 0x04, 0x50, 0x20, 0x05, 0x04, 0x60, 0x20, 0x05, 0x04, + 0x10, 0x0d, 0x06, 0x04, 0x40, 0x3e, 0x07, 0x05, 0x00, 0x25, 0x08, 0x05, 0x00, 0x12, 0x09, 0x05, 0x40, 0x03, 0x0a, 0x05, 0xc0, 0x19, 0x0c, 0x06, 0x80, 0x0d, 0x10, 0x07, 0x60, 0x39, 0x00, 0x04, + 0x70, 0x39, 0x00, 0x04, 0x80, 0x39, 0x00, 0x04, 0x80, 0x30, 0x01, 0x03, 0x88, 0x30, 0x01, 0x03, 0x90, 0x30, 0x01, 0x03, 0x98, 0x30, 0x01, 0x03, 0xd0, 0x1a, 0x02, 0x03, 0xd8, 0x1a, 0x02, 0x03, + 0xe0, 0x1a, 0x02, 0x03, 0xc8, 0x09, 0x03, 0x03, 0xd0, 0x09, 0x03, 0x03, 0xd8, 0x09, 0x03, 0x03, 0xb0, 0x36, 0x04, 0x04, 0xc0, 0x36, 0x04, 0x04, 0x70, 0x20, 0x05, 0x04, 0x80, 0x20, 0x05, 0x04, + 0x20, 0x0d, 0x06, 0x04, 0x60, 0x3e, 0x07, 0x05, 0x20, 0x25, 0x08, 0x05, 0x20, 0x12, 0x09, 0x05, 0x60, 0x03, 0x0a, 0x05, 0x00, 0x1a, 0x0c, 0x06, 0x00, 0x0e, 0x10, 0x07, 0x90, 0x39, 0x00, 0x04, + 0xa0, 0x39, 0x00, 0x04, 0xa0, 0x30, 0x01, 0x03, 0xa8, 0x30, 0x01, 0x03, 0xb0, 0x30, 0x01, 0x03, 0xb8, 0x30, 0x01, 0x03, 0xc0, 0x30, 0x01, 0x03, 0xe8, 0x1a, 0x02, 0x03, 0xf0, 0x1a, 0x02, 0x03, + 0xf8, 0x1a, 0x02, 0x03, 0xe0, 0x09, 0x03, 0x03, 0xe8, 0x09, 0x03, 0x03, 0xf0, 0x09, 0x03, 0x03, 0xd0, 0x36, 0x04, 0x04, 0xe0, 0x36, 0x04, 0x04, 0x90, 0x20, 0x05, 0x04, 0xa0, 0x20, 0x05, 0x04, + 0x30, 0x0d, 0x06, 0x04, 0x80, 0x3e, 0x07, 0x05, 0x40, 0x25, 0x08, 0x05, 0x40, 0x12, 0x09, 0x05, 0x80, 0x03, 0x0a, 0x05, 0x40, 0x1a, 0x0c, 0x06, 0x80, 0x0e, 0x10, 0x07, 0xb0, 0x39, 0x00, 0x04, + 0xc0, 0x39, 0x00, 0x04, 0xc8, 0x30, 0x01, 0x03, 0xd0, 0x30, 0x01, 0x03, 0xd8, 0x30, 0x01, 0x03, 0xe0, 0x30, 0x01, 0x03, 0xe8, 0x30, 0x01, 0x03, 0x00, 0x1b, 0x02, 0x03, 0x08, 0x1b, 0x02, 0x03, + 0x10, 0x1b, 0x02, 0x03, 0xf8, 0x09, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x03, 0x08, 0x0a, 0x03, 0x03, 0xf0, 0x36, 0x04, 0x04, 0x00, 0x37, 0x04, 0x04, 0xb0, 0x20, 0x05, 0x04, 0xc0, 0x20, 0x05, 0x04, + 0x40, 0x0d, 0x06, 0x04, 0xa0, 0x3e, 0x07, 0x05, 0x60, 0x25, 0x08, 0x05, 0x60, 0x12, 0x09, 0x05, 0xa0, 0x03, 0x0a, 0x05, 0x80, 0x1a, 0x0c, 0x06, 0x00, 0x0f, 0x10, 0x07, 0xd0, 0x39, 0x00, 0x04, + 0xe0, 0x39, 0x00, 0x04, 0xf0, 0x30, 0x01, 0x03, 0xf8, 0x30, 0x01, 0x03, 0x00, 0x31, 0x01, 0x03, 0x08, 0x31, 0x01, 0x03, 0x10, 0x31, 0x01, 0x03, 0x18, 0x1b, 0x02, 0x03, 0x20, 0x1b, 0x02, 0x03, + 0x28, 0x1b, 0x02, 0x03, 0x10, 0x0a, 0x03, 0x03, 0x18, 0x0a, 0x03, 0x03, 0x20, 0x0a, 0x03, 0x03, 0x10, 0x37, 0x04, 0x04, 0x20, 0x37, 0x04, 0x04, 0xd0, 0x20, 0x05, 0x04, 0xe0, 0x20, 0x05, 0x04, + 0x50, 0x0d, 0x06, 0x04, 0xc0, 0x3e, 0x07, 0x05, 0x80, 0x25, 0x08, 0x05, 0x80, 0x12, 0x09, 0x05, 0xc0, 0x03, 0x0a, 0x05, 0xc0, 0x1a, 0x0c, 0x06, 0x80, 0x0f, 0x10, 0x07, 0xf0, 0x39, 0x00, 0x04, + 0x00, 0x3a, 0x00, 0x04, 0x18, 0x31, 0x01, 0x03, 0x20, 0x31, 0x01, 0x03, 0x28, 0x31, 0x01, 0x03, 0x30, 0x31, 0x01, 0x03, 0x38, 0x31, 0x01, 0x03, 0x30, 0x1b, 0x02, 0x03, 0x38, 0x1b, 0x02, 0x03, + 0x40, 0x1b, 0x02, 0x03, 0x28, 0x0a, 0x03, 0x03, 0x30, 0x0a, 0x03, 0x03, 0x38, 0x0a, 0x03, 0x03, 0x30, 0x37, 0x04, 0x04, 0x40, 0x37, 0x04, 0x04, 0xf0, 0x20, 0x05, 0x04, 0x00, 0x21, 0x05, 0x04, + 0x60, 0x0d, 0x06, 0x04, 0xe0, 0x3e, 0x07, 0x05, 0xa0, 0x25, 0x08, 0x05, 0xa0, 0x12, 0x09, 0x05, 0xe0, 0x03, 0x0a, 0x05, 0x00, 0x1b, 0x0c, 0x06, 0x00, 0x34, 0x11, 0x08, 0x10, 0x3a, 0x00, 0x04, + 0x20, 0x3a, 0x00, 0x04, 0x40, 0x31, 0x01, 0x03, 0x48, 0x31, 0x01, 0x03, 0x50, 0x31, 0x01, 0x03, 0x58, 0x31, 0x01, 0x03, 0x60, 0x31, 0x01, 0x03, 0x48, 0x1b, 0x02, 0x03, 0x50, 0x1b, 0x02, 0x03, + 0x58, 0x1b, 0x02, 0x03, 0x40, 0x0a, 0x03, 0x03, 0x48, 0x0a, 0x03, 0x03, 0x50, 0x0a, 0x03, 0x03, 0x50, 0x37, 0x04, 0x04, 0x60, 0x37, 0x04, 0x04, 0x10, 0x21, 0x05, 0x04, 0x20, 0x21, 0x05, 0x04, + 0x70, 0x0d, 0x06, 0x04, 0x00, 0x3f, 0x07, 0x05, 0xc0, 0x25, 0x08, 0x05, 0xc0, 0x12, 0x09, 0x05, 0x00, 0x04, 0x0a, 0x05, 0x40, 0x1b, 0x0c, 0x06, 0x00, 0x35, 0x11, 0x08, 0x30, 0x3a, 0x00, 0x04, + 0x40, 0x3a, 0x00, 0x04, 0x68, 0x31, 0x01, 0x03, 0x70, 0x31, 0x01, 0x03, 0x78, 0x31, 0x01, 0x03, 0x80, 0x31, 0x01, 0x03, 0x88, 0x31, 0x01, 0x03, 0x60, 0x1b, 0x02, 0x03, 0x68, 0x1b, 0x02, 0x03, + 0x70, 0x1b, 0x02, 0x03, 0x58, 0x0a, 0x03, 0x03, 0x60, 0x0a, 0x03, 0x03, 0x68, 0x0a, 0x03, 0x03, 0x70, 0x37, 0x04, 0x04, 0x80, 0x37, 0x04, 0x04, 0x30, 0x21, 0x05, 0x04, 0x40, 0x21, 0x05, 0x04, + 0x80, 0x0d, 0x06, 0x04, 0x20, 0x3f, 0x07, 0x05, 0xe0, 0x25, 0x08, 0x05, 0xe0, 0x12, 0x09, 0x05, 0x20, 0x04, 0x0a, 0x05, 0x80, 0x1b, 0x0c, 0x06, 0x00, 0x36, 0x11, 0x08, 0x50, 0x3a, 0x00, 0x04, + 0x60, 0x3a, 0x00, 0x04, 0x90, 0x31, 0x01, 0x03, 0x98, 0x31, 0x01, 0x03, 0xa0, 0x31, 0x01, 0x03, 0xa8, 0x31, 0x01, 0x03, 0xb0, 0x31, 0x01, 0x03, 0x78, 0x1b, 0x02, 0x03, 0x80, 0x1b, 0x02, 0x03, + 0x88, 0x1b, 0x02, 0x03, 0x70, 0x0a, 0x03, 0x03, 0x78, 0x0a, 0x03, 0x03, 0x80, 0x0a, 0x03, 0x03, 0x90, 0x37, 0x04, 0x04, 0xa0, 0x37, 0x04, 0x04, 0x50, 0x21, 0x05, 0x04, 0x60, 0x21, 0x05, 0x04, + 0x90, 0x0d, 0x06, 0x04, 0x40, 0x3f, 0x07, 0x05, 0x00, 0x26, 0x08, 0x05, 0x00, 0x13, 0x09, 0x05, 0x40, 0x04, 0x0a, 0x05, 0x80, 0x04, 0x0d, 0x06, 0x00, 0x37, 0x11, 0x08, 0x70, 0x3a, 0x00, 0x04, + 0x80, 0x3a, 0x00, 0x04, 0xb8, 0x31, 0x01, 0x03, 0xc0, 0x31, 0x01, 0x03, 0xc8, 0x31, 0x01, 0x03, 0xd0, 0x31, 0x01, 0x03, 0xd8, 0x31, 0x01, 0x03, 0x90, 0x1b, 0x02, 0x03, 0x98, 0x1b, 0x02, 0x03, + 0xa0, 0x1b, 0x02, 0x03, 0x88, 0x0a, 0x03, 0x03, 0x90, 0x0a, 0x03, 0x03, 0x98, 0x0a, 0x03, 0x03, 0xb0, 0x37, 0x04, 0x04, 0xc0, 0x37, 0x04, 0x04, 0x70, 0x21, 0x05, 0x04, 0x80, 0x21, 0x05, 0x04, + 0xa0, 0x0d, 0x06, 0x04, 0x60, 0x3f, 0x07, 0x05, 0x20, 0x26, 0x08, 0x05, 0x20, 0x13, 0x09, 0x05, 0x60, 0x04, 0x0a, 0x05, 0xc0, 0x04, 0x0d, 0x06, 0x00, 0x38, 0x11, 0x08, 0x90, 0x3a, 0x00, 0x04, + 0xa0, 0x3a, 0x00, 0x04, 0xe0, 0x31, 0x01, 0x03, 0xe8, 0x31, 0x01, 0x03, 0xf0, 0x31, 0x01, 0x03, 0xf8, 0x31, 0x01, 0x03, 0x00, 0x32, 0x01, 0x03, 0xa8, 0x1b, 0x02, 0x03, 0xb0, 0x1b, 0x02, 0x03, + 0xb8, 0x1b, 0x02, 0x03, 0xa0, 0x0a, 0x03, 0x03, 0xa8, 0x0a, 0x03, 0x03, 0xb0, 0x0a, 0x03, 0x03, 0xd0, 0x37, 0x04, 0x04, 0xe0, 0x37, 0x04, 0x04, 0x90, 0x21, 0x05, 0x04, 0xa0, 0x21, 0x05, 0x04, + 0xb0, 0x0d, 0x06, 0x04, 0x80, 0x3f, 0x07, 0x05, 0x40, 0x26, 0x08, 0x05, 0x40, 0x13, 0x09, 0x05, 0x80, 0x04, 0x0a, 0x05, 0x00, 0x05, 0x0d, 0x06, 0x00, 0x39, 0x11, 0x08, 0xb0, 0x3a, 0x00, 0x04, + 0xc0, 0x3a, 0x00, 0x04, 0x08, 0x32, 0x01, 0x03, 0x10, 0x32, 0x01, 0x03, 0x18, 0x32, 0x01, 0x03, 0x20, 0x32, 0x01, 0x03, 0x28, 0x32, 0x01, 0x03, 0xc0, 0x1b, 0x02, 0x03, 0xc8, 0x1b, 0x02, 0x03, + 0xd0, 0x1b, 0x02, 0x03, 0xb8, 0x0a, 0x03, 0x03, 0xc0, 0x0a, 0x03, 0x03, 0xc8, 0x0a, 0x03, 0x03, 0xf0, 0x37, 0x04, 0x04, 0x00, 0x38, 0x04, 0x04, 0xb0, 0x21, 0x05, 0x04, 0xc0, 0x21, 0x05, 0x04, + 0xc0, 0x0d, 0x06, 0x04, 0xa0, 0x3f, 0x07, 0x05, 0x60, 0x26, 0x08, 0x05, 0x60, 0x13, 0x09, 0x05, 0xa0, 0x04, 0x0a, 0x05, 0x40, 0x05, 0x0d, 0x06, 0x00, 0x3a, 0x11, 0x08, 0xd0, 0x3a, 0x00, 0x04, + 0xe0, 0x3a, 0x00, 0x04, 0x30, 0x32, 0x01, 0x03, 0x38, 0x32, 0x01, 0x03, 0x40, 0x32, 0x01, 0x03, 0x48, 0x32, 0x01, 0x03, 0x50, 0x32, 0x01, 0x03, 0xd8, 0x1b, 0x02, 0x03, 0xe0, 0x1b, 0x02, 0x03, + 0xe8, 0x1b, 0x02, 0x03, 0xd0, 0x0a, 0x03, 0x03, 0xd8, 0x0a, 0x03, 0x03, 0xe0, 0x0a, 0x03, 0x03, 0x10, 0x38, 0x04, 0x04, 0x20, 0x38, 0x04, 0x04, 0xd0, 0x21, 0x05, 0x04, 0xe0, 0x21, 0x05, 0x04, + 0xd0, 0x0d, 0x06, 0x04, 0xc0, 0x3f, 0x07, 0x05, 0x80, 0x26, 0x08, 0x05, 0x80, 0x13, 0x09, 0x05, 0xc0, 0x04, 0x0a, 0x05, 0x80, 0x05, 0x0d, 0x06, 0x00, 0x3b, 0x11, 0x08, 0xf0, 0x3a, 0x00, 0x04, + 0x00, 0x3b, 0x00, 0x04, 0x58, 0x32, 0x01, 0x03, 0x60, 0x32, 0x01, 0x03, 0x68, 0x32, 0x01, 0x03, 0x70, 0x32, 0x01, 0x03, 0x78, 0x32, 0x01, 0x03, 0xf0, 0x1b, 0x02, 0x03, 0xf8, 0x1b, 0x02, 0x03, + 0x00, 0x1c, 0x02, 0x03, 0xe8, 0x0a, 0x03, 0x03, 0xf0, 0x0a, 0x03, 0x03, 0xf8, 0x0a, 0x03, 0x03, 0x30, 0x38, 0x04, 0x04, 0x40, 0x38, 0x04, 0x04, 0xf0, 0x21, 0x05, 0x04, 0x00, 0x22, 0x05, 0x04, + 0xe0, 0x0d, 0x06, 0x04, 0xe0, 0x3f, 0x07, 0x05, 0xa0, 0x26, 0x08, 0x05, 0xa0, 0x13, 0x09, 0x05, 0xe0, 0x04, 0x0a, 0x05, 0xc0, 0x05, 0x0d, 0x06, 0x00, 0x3c, 0x11, 0x08, 0x10, 0x3b, 0x00, 0x04, + 0x20, 0x3b, 0x00, 0x04, 0x80, 0x32, 0x01, 0x03, 0x88, 0x32, 0x01, 0x03, 0x90, 0x32, 0x01, 0x03, 0x98, 0x32, 0x01, 0x03, 0xa0, 0x32, 0x01, 0x03, 0x08, 0x1c, 0x02, 0x03, 0x10, 0x1c, 0x02, 0x03, + 0x18, 0x1c, 0x02, 0x03, 0x00, 0x0b, 0x03, 0x03, 0x08, 0x0b, 0x03, 0x03, 0x10, 0x0b, 0x03, 0x03, 0x50, 0x38, 0x04, 0x04, 0x60, 0x38, 0x04, 0x04, 0x10, 0x22, 0x05, 0x04, 0x20, 0x22, 0x05, 0x04, + 0xf0, 0x0d, 0x06, 0x04, 0x00, 0x00, 0x07, 0x04, 0xc0, 0x26, 0x08, 0x05, 0xc0, 0x13, 0x09, 0x05, 0x00, 0x05, 0x0a, 0x05, 0x00, 0x06, 0x0d, 0x06, 0x00, 0x3d, 0x11, 0x08, 0x30, 0x3b, 0x00, 0x04, + 0x40, 0x3b, 0x00, 0x04, 0xa8, 0x32, 0x01, 0x03, 0xb0, 0x32, 0x01, 0x03, 0xb8, 0x32, 0x01, 0x03, 0xc0, 0x32, 0x01, 0x03, 0xc8, 0x32, 0x01, 0x03, 0x20, 0x1c, 0x02, 0x03, 0x28, 0x1c, 0x02, 0x03, + 0x30, 0x1c, 0x02, 0x03, 0x18, 0x0b, 0x03, 0x03, 0x20, 0x0b, 0x03, 0x03, 0x28, 0x0b, 0x03, 0x03, 0x70, 0x38, 0x04, 0x04, 0x80, 0x38, 0x04, 0x04, 0x30, 0x22, 0x05, 0x04, 0x40, 0x22, 0x05, 0x04, + 0x00, 0x0e, 0x06, 0x04, 0x10, 0x00, 0x07, 0x04, 0xe0, 0x26, 0x08, 0x05, 0xe0, 0x13, 0x09, 0x05, 0x20, 0x05, 0x0a, 0x05, 0x40, 0x06, 0x0d, 0x06, 0x00, 0x3e, 0x11, 0x08, 0x50, 0x3b, 0x00, 0x04, + 0x60, 0x3b, 0x00, 0x04, 0xd0, 0x32, 0x01, 0x03, 0xd8, 0x32, 0x01, 0x03, 0xe0, 0x32, 0x01, 0x03, 0xe8, 0x32, 0x01, 0x03, 0x38, 0x1c, 0x02, 0x03, 0x40, 0x1c, 0x02, 0x03, 0x48, 0x1c, 0x02, 0x03, + 0x50, 0x1c, 0x02, 0x03, 0x30, 0x0b, 0x03, 0x03, 0x38, 0x0b, 0x03, 0x03, 0x40, 0x0b, 0x03, 0x03, 0x90, 0x38, 0x04, 0x04, 0xa0, 0x38, 0x04, 0x04, 0x50, 0x22, 0x05, 0x04, 0x60, 0x22, 0x05, 0x04, + 0x10, 0x0e, 0x06, 0x04, 0x20, 0x00, 0x07, 0x04, 0x00, 0x27, 0x08, 0x05, 0x00, 0x14, 0x09, 0x05, 0xc0, 0x28, 0x0b, 0x06, 0x80, 0x06, 0x0d, 0x06, 0x00, 0x3f, 0x11, 0x08, 0x70, 0x3b, 0x00, 0x04, + 0x80, 0x3b, 0x00, 0x04, 0xf0, 0x32, 0x01, 0x03, 0xf8, 0x32, 0x01, 0x03, 0x00, 0x33, 0x01, 0x03, 0x08, 0x33, 0x01, 0x03, 0x58, 0x1c, 0x02, 0x03, 0x60, 0x1c, 0x02, 0x03, 0x68, 0x1c, 0x02, 0x03, + 0x70, 0x1c, 0x02, 0x03, 0x48, 0x0b, 0x03, 0x03, 0x50, 0x0b, 0x03, 0x03, 0x58, 0x0b, 0x03, 0x03, 0xb0, 0x38, 0x04, 0x04, 0xc0, 0x38, 0x04, 0x04, 0x70, 0x22, 0x05, 0x04, 0x80, 0x22, 0x05, 0x04, + 0x20, 0x0e, 0x06, 0x04, 0x30, 0x00, 0x07, 0x04, 0x20, 0x27, 0x08, 0x05, 0x20, 0x14, 0x09, 0x05, 0x00, 0x29, 0x0b, 0x06, 0xc0, 0x06, 0x0d, 0x06, 0x00, 0x1f, 0x12, 0x08, 0x90, 0x3b, 0x00, 0x04, + 0xa0, 0x3b, 0x00, 0x04, 0x10, 0x33, 0x01, 0x03, 0x18, 0x33, 0x01, 0x03, 0x20, 0x33, 0x01, 0x03, 0x28, 0x33, 0x01, 0x03, 0x78, 0x1c, 0x02, 0x03, 0x80, 0x1c, 0x02, 0x03, 0x88, 0x1c, 0x02, 0x03, + 0x90, 0x1c, 0x02, 0x03, 0x60, 0x0b, 0x03, 0x03, 0x68, 0x0b, 0x03, 0x03, 0x70, 0x0b, 0x03, 0x03, 0xd0, 0x38, 0x04, 0x04, 0xe0, 0x38, 0x04, 0x04, 0x90, 0x22, 0x05, 0x04, 0xa0, 0x22, 0x05, 0x04, + 0x30, 0x0e, 0x06, 0x04, 0x40, 0x00, 0x07, 0x04, 0x40, 0x27, 0x08, 0x05, 0x40, 0x14, 0x09, 0x05, 0x40, 0x29, 0x0b, 0x06, 0x00, 0x07, 0x0d, 0x06, 0x00, 0x20, 0x12, 0x08, 0xb0, 0x3b, 0x00, 0x04, + 0xc0, 0x3b, 0x00, 0x04, 0x30, 0x33, 0x01, 0x03, 0x38, 0x33, 0x01, 0x03, 0x40, 0x33, 0x01, 0x03, 0x48, 0x33, 0x01, 0x03, 0x98, 0x1c, 0x02, 0x03, 0xa0, 0x1c, 0x02, 0x03, 0xa8, 0x1c, 0x02, 0x03, + 0xb0, 0x1c, 0x02, 0x03, 0x78, 0x0b, 0x03, 0x03, 0x80, 0x0b, 0x03, 0x03, 0x88, 0x0b, 0x03, 0x03, 0xf0, 0x38, 0x04, 0x04, 0x00, 0x39, 0x04, 0x04, 0xb0, 0x22, 0x05, 0x04, 0xc0, 0x22, 0x05, 0x04, + 0x40, 0x0e, 0x06, 0x04, 0x50, 0x00, 0x07, 0x04, 0x60, 0x27, 0x08, 0x05, 0x60, 0x14, 0x09, 0x05, 0x80, 0x29, 0x0b, 0x06, 0x40, 0x07, 0x0d, 0x06, 0x00, 0x21, 0x12, 0x08, 0xd0, 0x3b, 0x00, 0x04, + 0xe0, 0x3b, 0x00, 0x04, 0x50, 0x33, 0x01, 0x03, 0x58, 0x33, 0x01, 0x03, 0x60, 0x33, 0x01, 0x03, 0x68, 0x33, 0x01, 0x03, 0xb8, 0x1c, 0x02, 0x03, 0xc0, 0x1c, 0x02, 0x03, 0xc8, 0x1c, 0x02, 0x03, + 0xd0, 0x1c, 0x02, 0x03, 0x90, 0x0b, 0x03, 0x03, 0x98, 0x0b, 0x03, 0x03, 0xa0, 0x0b, 0x03, 0x03, 0x10, 0x39, 0x04, 0x04, 0x20, 0x39, 0x04, 0x04, 0xd0, 0x22, 0x05, 0x04, 0xe0, 0x22, 0x05, 0x04, + 0x50, 0x0e, 0x06, 0x04, 0x60, 0x00, 0x07, 0x04, 0x80, 0x27, 0x08, 0x05, 0x80, 0x14, 0x09, 0x05, 0xc0, 0x29, 0x0b, 0x06, 0x80, 0x07, 0x0d, 0x06, 0x00, 0x22, 0x12, 0x08, 0xf0, 0x3b, 0x00, 0x04, + 0x00, 0x3c, 0x00, 0x04, 0x70, 0x33, 0x01, 0x03, 0x78, 0x33, 0x01, 0x03, 0x80, 0x33, 0x01, 0x03, 0x88, 0x33, 0x01, 0x03, 0xd8, 0x1c, 0x02, 0x03, 0xe0, 0x1c, 0x02, 0x03, 0xe8, 0x1c, 0x02, 0x03, + 0xf0, 0x1c, 0x02, 0x03, 0xa8, 0x0b, 0x03, 0x03, 0xb0, 0x0b, 0x03, 0x03, 0xb8, 0x0b, 0x03, 0x03, 0x30, 0x39, 0x04, 0x04, 0x40, 0x39, 0x04, 0x04, 0xf0, 0x22, 0x05, 0x04, 0x00, 0x23, 0x05, 0x04, + 0x60, 0x0e, 0x06, 0x04, 0x70, 0x00, 0x07, 0x04, 0xa0, 0x27, 0x08, 0x05, 0xa0, 0x14, 0x09, 0x05, 0x00, 0x2a, 0x0b, 0x06, 0xc0, 0x07, 0x0d, 0x06, 0x00, 0x23, 0x12, 0x08, 0x10, 0x3c, 0x00, 0x04, + 0x20, 0x3c, 0x00, 0x04, 0x90, 0x33, 0x01, 0x03, 0x98, 0x33, 0x01, 0x03, 0xa0, 0x33, 0x01, 0x03, 0xa8, 0x33, 0x01, 0x03, 0xf8, 0x1c, 0x02, 0x03, 0x00, 0x1d, 0x02, 0x03, 0x08, 0x1d, 0x02, 0x03, + 0x10, 0x1d, 0x02, 0x03, 0xc0, 0x0b, 0x03, 0x03, 0xc8, 0x0b, 0x03, 0x03, 0xd0, 0x0b, 0x03, 0x03, 0x50, 0x39, 0x04, 0x04, 0x60, 0x39, 0x04, 0x04, 0x10, 0x23, 0x05, 0x04, 0x20, 0x23, 0x05, 0x04, + 0x70, 0x0e, 0x06, 0x04, 0x80, 0x00, 0x07, 0x04, 0xc0, 0x27, 0x08, 0x05, 0xc0, 0x14, 0x09, 0x05, 0x40, 0x2a, 0x0b, 0x06, 0x00, 0x08, 0x0d, 0x06, 0x00, 0x24, 0x12, 0x08, 0x30, 0x3c, 0x00, 0x04, + 0x40, 0x3c, 0x00, 0x04, 0xb0, 0x33, 0x01, 0x03, 0xb8, 0x33, 0x01, 0x03, 0xc0, 0x33, 0x01, 0x03, 0xc8, 0x33, 0x01, 0x03, 0x18, 0x1d, 0x02, 0x03, 0x20, 0x1d, 0x02, 0x03, 0x28, 0x1d, 0x02, 0x03, + 0x30, 0x1d, 0x02, 0x03, 0xd8, 0x0b, 0x03, 0x03, 0xe0, 0x0b, 0x03, 0x03, 0xe8, 0x0b, 0x03, 0x03, 0x70, 0x39, 0x04, 0x04, 0x80, 0x39, 0x04, 0x04, 0x30, 0x23, 0x05, 0x04, 0x80, 0x0e, 0x06, 0x04, + 0x90, 0x0e, 0x06, 0x04, 0x90, 0x00, 0x07, 0x04, 0xe0, 0x27, 0x08, 0x05, 0xe0, 0x14, 0x09, 0x05, 0x80, 0x2a, 0x0b, 0x06, 0x40, 0x08, 0x0d, 0x06, 0x00, 0x25, 0x12, 0x08, 0x50, 0x3c, 0x00, 0x04, + 0x60, 0x3c, 0x00, 0x04, 0xd0, 0x33, 0x01, 0x03, 0xd8, 0x33, 0x01, 0x03, 0xe0, 0x33, 0x01, 0x03, 0xe8, 0x33, 0x01, 0x03, 0x38, 0x1d, 0x02, 0x03, 0x40, 0x1d, 0x02, 0x03, 0x48, 0x1d, 0x02, 0x03, + 0x50, 0x1d, 0x02, 0x03, 0xf0, 0x0b, 0x03, 0x03, 0xf8, 0x0b, 0x03, 0x03, 0x90, 0x39, 0x04, 0x04, 0xa0, 0x39, 0x04, 0x04, 0xb0, 0x39, 0x04, 0x04, 0x40, 0x23, 0x05, 0x04, 0xa0, 0x0e, 0x06, 0x04, + 0xb0, 0x0e, 0x06, 0x04, 0xa0, 0x00, 0x07, 0x04, 0x00, 0x28, 0x08, 0x05, 0x00, 0x15, 0x09, 0x05, 0xc0, 0x2a, 0x0b, 0x06, 0x80, 0x08, 0x0d, 0x06, 0x00, 0x26, 0x12, 0x08, 0x70, 0x3c, 0x00, 0x04, + 0x80, 0x3c, 0x00, 0x04, 0xf0, 0x33, 0x01, 0x03, 0xf8, 0x33, 0x01, 0x03, 0x00, 0x34, 0x01, 0x03, 0x08, 0x34, 0x01, 0x03, 0x58, 0x1d, 0x02, 0x03, 0x60, 0x1d, 0x02, 0x03, 0x68, 0x1d, 0x02, 0x03, + 0x70, 0x1d, 0x02, 0x03, 0x00, 0x0c, 0x03, 0x03, 0x08, 0x0c, 0x03, 0x03, 0xc0, 0x39, 0x04, 0x04, 0xd0, 0x39, 0x04, 0x04, 0xe0, 0x39, 0x04, 0x04, 0x50, 0x23, 0x05, 0x04, 0xc0, 0x0e, 0x06, 0x04, + 0xd0, 0x0e, 0x06, 0x04, 0xb0, 0x00, 0x07, 0x04, 0x20, 0x28, 0x08, 0x05, 0x20, 0x15, 0x09, 0x05, 0x00, 0x2b, 0x0b, 0x06, 0xc0, 0x08, 0x0d, 0x06, 0x00, 0x27, 0x12, 0x08, 0x90, 0x3c, 0x00, 0x04, + 0xa0, 0x3c, 0x00, 0x04, 0x10, 0x34, 0x01, 0x03, 0x18, 0x34, 0x01, 0x03, 0x20, 0x34, 0x01, 0x03, 0x28, 0x34, 0x01, 0x03, 0x78, 0x1d, 0x02, 0x03, 0x80, 0x1d, 0x02, 0x03, 0x88, 0x1d, 0x02, 0x03, + 0x90, 0x1d, 0x02, 0x03, 0x10, 0x0c, 0x03, 0x03, 0x18, 0x0c, 0x03, 0x03, 0xf0, 0x39, 0x04, 0x04, 0x00, 0x3a, 0x04, 0x04, 0x10, 0x3a, 0x04, 0x04, 0x60, 0x23, 0x05, 0x04, 0xe0, 0x0e, 0x06, 0x04, + 0xf0, 0x0e, 0x06, 0x04, 0xc0, 0x00, 0x07, 0x04, 0x40, 0x28, 0x08, 0x05, 0x40, 0x15, 0x09, 0x05, 0x40, 0x2b, 0x0b, 0x06, 0x00, 0x09, 0x0d, 0x06, 0x00, 0x0c, 0x13, 0x08, 0xb0, 0x3c, 0x00, 0x04, + 0xc0, 0x3c, 0x00, 0x04, 0x30, 0x34, 0x01, 0x03, 0x38, 0x34, 0x01, 0x03, 0x40, 0x34, 0x01, 0x03, 0x48, 0x34, 0x01, 0x03, 0x98, 0x1d, 0x02, 0x03, 0xa0, 0x1d, 0x02, 0x03, 0xa8, 0x1d, 0x02, 0x03, + 0xb0, 0x1d, 0x02, 0x03, 0x20, 0x0c, 0x03, 0x03, 0x28, 0x0c, 0x03, 0x03, 0x20, 0x3a, 0x04, 0x04, 0x30, 0x3a, 0x04, 0x04, 0x40, 0x3a, 0x04, 0x04, 0x70, 0x23, 0x05, 0x04, 0x00, 0x0f, 0x06, 0x04, + 0x10, 0x0f, 0x06, 0x04, 0xd0, 0x00, 0x07, 0x04, 0x60, 0x28, 0x08, 0x05, 0x60, 0x15, 0x09, 0x05, 0x80, 0x2b, 0x0b, 0x06, 0x40, 0x09, 0x0d, 0x06, 0x00, 0x0d, 0x13, 0x08, 0xd0, 0x3c, 0x00, 0x04, + 0xe0, 0x3c, 0x00, 0x04, 0x50, 0x34, 0x01, 0x03, 0x58, 0x34, 0x01, 0x03, 0x60, 0x34, 0x01, 0x03, 0x68, 0x34, 0x01, 0x03, 0xb8, 0x1d, 0x02, 0x03, 0xc0, 0x1d, 0x02, 0x03, 0xc8, 0x1d, 0x02, 0x03, + 0xd0, 0x1d, 0x02, 0x03, 0x30, 0x0c, 0x03, 0x03, 0x38, 0x0c, 0x03, 0x03, 0x50, 0x3a, 0x04, 0x04, 0x60, 0x3a, 0x04, 0x04, 0x70, 0x3a, 0x04, 0x04, 0x80, 0x23, 0x05, 0x04, 0x20, 0x0f, 0x06, 0x04, + 0x30, 0x0f, 0x06, 0x04, 0xe0, 0x00, 0x07, 0x04, 0x80, 0x28, 0x08, 0x05, 0x80, 0x15, 0x09, 0x05, 0xc0, 0x2b, 0x0b, 0x06, 0x80, 0x09, 0x0d, 0x06, 0x00, 0x0e, 0x13, 0x08, 0xf0, 0x3c, 0x00, 0x04, + 0x00, 0x3d, 0x00, 0x04, 0x70, 0x34, 0x01, 0x03, 0x78, 0x34, 0x01, 0x03, 0x80, 0x34, 0x01, 0x03, 0x88, 0x34, 0x01, 0x03, 0xd8, 0x1d, 0x02, 0x03, 0xe0, 0x1d, 0x02, 0x03, 0xe8, 0x1d, 0x02, 0x03, + 0xf0, 0x1d, 0x02, 0x03, 0x40, 0x0c, 0x03, 0x03, 0x48, 0x0c, 0x03, 0x03, 0x80, 0x3a, 0x04, 0x04, 0x90, 0x3a, 0x04, 0x04, 0xa0, 0x3a, 0x04, 0x04, 0x90, 0x23, 0x05, 0x04, 0x40, 0x0f, 0x06, 0x04, + 0x50, 0x0f, 0x06, 0x04, 0xf0, 0x00, 0x07, 0x04, 0xa0, 0x28, 0x08, 0x05, 0xa0, 0x15, 0x09, 0x05, 0x00, 0x2c, 0x0b, 0x06, 0xc0, 0x09, 0x0d, 0x06, 0x00, 0x0f, 0x13, 0x08, 0x10, 0x3d, 0x00, 0x04, + 0x20, 0x3d, 0x00, 0x04, 0x90, 0x34, 0x01, 0x03, 0x98, 0x34, 0x01, 0x03, 0xa0, 0x34, 0x01, 0x03, 0xa8, 0x34, 0x01, 0x03, 0xf8, 0x1d, 0x02, 0x03, 0x00, 0x1e, 0x02, 0x03, 0x08, 0x1e, 0x02, 0x03, + 0x10, 0x1e, 0x02, 0x03, 0x50, 0x0c, 0x03, 0x03, 0x58, 0x0c, 0x03, 0x03, 0xb0, 0x3a, 0x04, 0x04, 0xc0, 0x3a, 0x04, 0x04, 0xd0, 0x3a, 0x04, 0x04, 0xa0, 0x23, 0x05, 0x04, 0x60, 0x0f, 0x06, 0x04, + 0x70, 0x0f, 0x06, 0x04, 0x00, 0x01, 0x07, 0x04, 0xc0, 0x28, 0x08, 0x05, 0xc0, 0x15, 0x09, 0x05, 0x40, 0x2c, 0x0b, 0x06, 0x00, 0x0a, 0x0d, 0x06, 0x00, 0x10, 0x13, 0x08, 0x30, 0x3d, 0x00, 0x04, + 0x40, 0x3d, 0x00, 0x04, 0xb0, 0x34, 0x01, 0x03, 0xb8, 0x34, 0x01, 0x03, 0xc0, 0x34, 0x01, 0x03, 0xc8, 0x34, 0x01, 0x03, 0x18, 0x1e, 0x02, 0x03, 0x20, 0x1e, 0x02, 0x03, 0x28, 0x1e, 0x02, 0x03, + 0x30, 0x1e, 0x02, 0x03, 0x60, 0x0c, 0x03, 0x03, 0x68, 0x0c, 0x03, 0x03, 0xe0, 0x3a, 0x04, 0x04, 0xf0, 0x3a, 0x04, 0x04, 0x00, 0x3b, 0x04, 0x04, 0xb0, 0x23, 0x05, 0x04, 0x80, 0x0f, 0x06, 0x04, + 0x90, 0x0f, 0x06, 0x04, 0x10, 0x01, 0x07, 0x04, 0xe0, 0x28, 0x08, 0x05, 0xe0, 0x15, 0x09, 0x05, 0x80, 0x2c, 0x0b, 0x06, 0x40, 0x0a, 0x0d, 0x06, 0x00, 0x11, 0x13, 0x08, 0x50, 0x3d, 0x00, 0x04, + 0x60, 0x3d, 0x00, 0x04, 0xd0, 0x34, 0x01, 0x03, 0xd8, 0x34, 0x01, 0x03, 0xe0, 0x34, 0x01, 0x03, 0xe8, 0x34, 0x01, 0x03, 0x38, 0x1e, 0x02, 0x03, 0x40, 0x1e, 0x02, 0x03, 0x48, 0x1e, 0x02, 0x03, + 0x50, 0x1e, 0x02, 0x03, 0x70, 0x0c, 0x03, 0x03, 0x78, 0x0c, 0x03, 0x03, 0x10, 0x3b, 0x04, 0x04, 0x20, 0x3b, 0x04, 0x04, 0x30, 0x3b, 0x04, 0x04, 0xc0, 0x23, 0x05, 0x04, 0xa0, 0x0f, 0x06, 0x04, + 0xb0, 0x0f, 0x06, 0x04, 0x20, 0x01, 0x07, 0x04, 0x00, 0x29, 0x08, 0x05, 0x00, 0x16, 0x09, 0x05, 0xc0, 0x2c, 0x0b, 0x06, 0x80, 0x0a, 0x0d, 0x06, 0x00, 0x12, 0x13, 0x08, 0x70, 0x3d, 0x00, 0x04, + 0x80, 0x3d, 0x00, 0x04, 0xf0, 0x34, 0x01, 0x03, 0xf8, 0x34, 0x01, 0x03, 0x00, 0x35, 0x01, 0x03, 0x08, 0x35, 0x01, 0x03, 0x58, 0x1e, 0x02, 0x03, 0x60, 0x1e, 0x02, 0x03, 0x68, 0x1e, 0x02, 0x03, + 0x70, 0x1e, 0x02, 0x03, 0x80, 0x0c, 0x03, 0x03, 0x88, 0x0c, 0x03, 0x03, 0x40, 0x3b, 0x04, 0x04, 0x50, 0x3b, 0x04, 0x04, 0x60, 0x3b, 0x04, 0x04, 0xd0, 0x23, 0x05, 0x04, 0xc0, 0x0f, 0x06, 0x04, + 0xd0, 0x0f, 0x06, 0x04, 0x30, 0x01, 0x07, 0x04, 0x20, 0x29, 0x08, 0x05, 0x20, 0x16, 0x09, 0x05, 0x00, 0x2d, 0x0b, 0x06, 0xc0, 0x0a, 0x0d, 0x06, 0x00, 0x13, 0x13, 0x08, 0x90, 0x3d, 0x00, 0x04, + 0xa0, 0x3d, 0x00, 0x04, 0x10, 0x35, 0x01, 0x03, 0x18, 0x35, 0x01, 0x03, 0x20, 0x35, 0x01, 0x03, 0x28, 0x35, 0x01, 0x03, 0x78, 0x1e, 0x02, 0x03, 0x80, 0x1e, 0x02, 0x03, 0x88, 0x1e, 0x02, 0x03, + 0x90, 0x1e, 0x02, 0x03, 0x90, 0x0c, 0x03, 0x03, 0x98, 0x0c, 0x03, 0x03, 0x70, 0x3b, 0x04, 0x04, 0x80, 0x3b, 0x04, 0x04, 0x90, 0x3b, 0x04, 0x04, 0xe0, 0x23, 0x05, 0x04, 0xe0, 0x0f, 0x06, 0x04, + 0xf0, 0x0f, 0x06, 0x04, 0x40, 0x01, 0x07, 0x04, 0x40, 0x29, 0x08, 0x05, 0x40, 0x16, 0x09, 0x05, 0x40, 0x2d, 0x0b, 0x06, 0x00, 0x0b, 0x0d, 0x06, 0x00, 0x3a, 0x14, 0x09, 0xb0, 0x3d, 0x00, 0x04, + 0xc0, 0x3d, 0x00, 0x04, 0x30, 0x35, 0x01, 0x03, 0x38, 0x35, 0x01, 0x03, 0x40, 0x35, 0x01, 0x03, 0x48, 0x35, 0x01, 0x03, 0x98, 0x1e, 0x02, 0x03, 0xa0, 0x1e, 0x02, 0x03, 0xa8, 0x1e, 0x02, 0x03, + 0xb0, 0x1e, 0x02, 0x03, 0xa0, 0x0c, 0x03, 0x03, 0xa8, 0x0c, 0x03, 0x03, 0xa0, 0x3b, 0x04, 0x04, 0xb0, 0x3b, 0x04, 0x04, 0xc0, 0x3b, 0x04, 0x04, 0xf0, 0x23, 0x05, 0x04, 0x00, 0x10, 0x06, 0x04, + 0x10, 0x10, 0x06, 0x04, 0x50, 0x01, 0x07, 0x04, 0x60, 0x29, 0x08, 0x05, 0x60, 0x16, 0x09, 0x05, 0x80, 0x2d, 0x0b, 0x06, 0x80, 0x2e, 0x0e, 0x07, 0x00, 0x3c, 0x14, 0x09, 0xd0, 0x3d, 0x00, 0x04, + 0xe0, 0x3d, 0x00, 0x04, 0x50, 0x35, 0x01, 0x03, 0x58, 0x35, 0x01, 0x03, 0x60, 0x35, 0x01, 0x03, 0x68, 0x35, 0x01, 0x03, 0xb8, 0x1e, 0x02, 0x03, 0xc0, 0x1e, 0x02, 0x03, 0xc8, 0x1e, 0x02, 0x03, + 0xd0, 0x1e, 0x02, 0x03, 0xb0, 0x0c, 0x03, 0x03, 0xb8, 0x0c, 0x03, 0x03, 0xd0, 0x3b, 0x04, 0x04, 0xe0, 0x3b, 0x04, 0x04, 0xf0, 0x3b, 0x04, 0x04, 0x00, 0x24, 0x05, 0x04, 0x20, 0x10, 0x06, 0x04, + 0x30, 0x10, 0x06, 0x04, 0x60, 0x01, 0x07, 0x04, 0x80, 0x29, 0x08, 0x05, 0x80, 0x16, 0x09, 0x05, 0xc0, 0x2d, 0x0b, 0x06, 0x00, 0x2f, 0x0e, 0x07, 0x00, 0x3e, 0x14, 0x09, 0xf0, 0x3d, 0x00, 0x04, + 0x00, 0x3e, 0x00, 0x04, 0x70, 0x35, 0x01, 0x03, 0x78, 0x35, 0x01, 0x03, 0x80, 0x35, 0x01, 0x03, 0x88, 0x35, 0x01, 0x03, 0xd8, 0x1e, 0x02, 0x03, 0xe0, 0x1e, 0x02, 0x03, 0xe8, 0x1e, 0x02, 0x03, + 0xf0, 0x1e, 0x02, 0x03, 0xc0, 0x0c, 0x03, 0x03, 0xc8, 0x0c, 0x03, 0x03, 0x00, 0x3c, 0x04, 0x04, 0x10, 0x3c, 0x04, 0x04, 0x20, 0x3c, 0x04, 0x04, 0x10, 0x24, 0x05, 0x04, 0x40, 0x10, 0x06, 0x04, + 0x50, 0x10, 0x06, 0x04, 0x70, 0x01, 0x07, 0x04, 0xa0, 0x29, 0x08, 0x05, 0xa0, 0x16, 0x09, 0x05, 0x00, 0x2e, 0x0b, 0x06, 0x80, 0x2f, 0x0e, 0x07, 0x00, 0x00, 0x14, 0x08, 0x10, 0x3e, 0x00, 0x04, + 0x20, 0x3e, 0x00, 0x04, 0x90, 0x35, 0x01, 0x03, 0x98, 0x35, 0x01, 0x03, 0xa0, 0x35, 0x01, 0x03, 0xa8, 0x35, 0x01, 0x03, 0xf8, 0x1e, 0x02, 0x03, 0x00, 0x1f, 0x02, 0x03, 0x08, 0x1f, 0x02, 0x03, + 0x10, 0x1f, 0x02, 0x03, 0xd0, 0x0c, 0x03, 0x03, 0xd8, 0x0c, 0x03, 0x03, 0x30, 0x3c, 0x04, 0x04, 0x40, 0x3c, 0x04, 0x04, 0x50, 0x3c, 0x04, 0x04, 0x20, 0x24, 0x05, 0x04, 0x60, 0x10, 0x06, 0x04, + 0x70, 0x10, 0x06, 0x04, 0x80, 0x01, 0x07, 0x04, 0xc0, 0x29, 0x08, 0x05, 0xc0, 0x16, 0x09, 0x05, 0x40, 0x2e, 0x0b, 0x06, 0x00, 0x30, 0x0e, 0x07, 0x00, 0x01, 0x14, 0x08, 0x30, 0x3e, 0x00, 0x04, + 0x40, 0x3e, 0x00, 0x04, 0xb0, 0x35, 0x01, 0x03, 0xb8, 0x35, 0x01, 0x03, 0xc0, 0x35, 0x01, 0x03, 0xc8, 0x35, 0x01, 0x03, 0x18, 0x1f, 0x02, 0x03, 0x20, 0x1f, 0x02, 0x03, 0x28, 0x1f, 0x02, 0x03, + 0x30, 0x1f, 0x02, 0x03, 0xe0, 0x0c, 0x03, 0x03, 0xe8, 0x0c, 0x03, 0x03, 0x60, 0x3c, 0x04, 0x04, 0x70, 0x3c, 0x04, 0x04, 0x80, 0x3c, 0x04, 0x04, 0x30, 0x24, 0x05, 0x04, 0x80, 0x10, 0x06, 0x04, + 0x90, 0x10, 0x06, 0x04, 0x90, 0x01, 0x07, 0x04, 0xe0, 0x29, 0x08, 0x05, 0xe0, 0x16, 0x09, 0x05, 0x80, 0x2e, 0x0b, 0x06, 0x80, 0x30, 0x0e, 0x07, 0x00, 0x02, 0x14, 0x08, 0x50, 0x3e, 0x00, 0x04, + 0x60, 0x3e, 0x00, 0x04, 0xd0, 0x35, 0x01, 0x03, 0xd8, 0x35, 0x01, 0x03, 0xe0, 0x35, 0x01, 0x03, 0xe8, 0x35, 0x01, 0x03, 0x38, 0x1f, 0x02, 0x03, 0x40, 0x1f, 0x02, 0x03, 0x48, 0x1f, 0x02, 0x03, + 0x50, 0x1f, 0x02, 0x03, 0xf0, 0x0c, 0x03, 0x03, 0xf8, 0x0c, 0x03, 0x03, 0x90, 0x3c, 0x04, 0x04, 0xa0, 0x3c, 0x04, 0x04, 0xb0, 0x3c, 0x04, 0x04, 0x40, 0x24, 0x05, 0x04, 0xa0, 0x10, 0x06, 0x04, + 0xb0, 0x10, 0x06, 0x04, 0xa0, 0x01, 0x07, 0x04, 0x00, 0x2a, 0x08, 0x05, 0x00, 0x17, 0x09, 0x05, 0xc0, 0x2e, 0x0b, 0x06, 0x00, 0x31, 0x0e, 0x07, 0x00, 0x24, 0x15, 0x09, 0x70, 0x3e, 0x00, 0x04, + 0x80, 0x3e, 0x00, 0x04, 0xf0, 0x35, 0x01, 0x03, 0xf8, 0x35, 0x01, 0x03, 0x00, 0x36, 0x01, 0x03, 0x08, 0x36, 0x01, 0x03, 0x58, 0x1f, 0x02, 0x03, 0x60, 0x1f, 0x02, 0x03, 0x68, 0x1f, 0x02, 0x03, + 0x70, 0x1f, 0x02, 0x03, 0x00, 0x0d, 0x03, 0x03, 0x08, 0x0d, 0x03, 0x03, 0xc0, 0x3c, 0x04, 0x04, 0xd0, 0x3c, 0x04, 0x04, 0x50, 0x24, 0x05, 0x04, 0x60, 0x24, 0x05, 0x04, 0xc0, 0x10, 0x06, 0x04, + 0xd0, 0x10, 0x06, 0x04, 0xb0, 0x01, 0x07, 0x04, 0x20, 0x2a, 0x08, 0x05, 0x20, 0x17, 0x09, 0x05, 0x00, 0x2f, 0x0b, 0x06, 0x80, 0x31, 0x0e, 0x07, 0x00, 0x26, 0x15, 0x09, 0x90, 0x3e, 0x00, 0x04, + 0xa0, 0x3e, 0x00, 0x04, 0x10, 0x36, 0x01, 0x03, 0x18, 0x36, 0x01, 0x03, 0x20, 0x36, 0x01, 0x03, 0x28, 0x36, 0x01, 0x03, 0x78, 0x1f, 0x02, 0x03, 0x80, 0x1f, 0x02, 0x03, 0x88, 0x1f, 0x02, 0x03, + 0x90, 0x1f, 0x02, 0x03, 0x10, 0x0d, 0x03, 0x03, 0x18, 0x0d, 0x03, 0x03, 0xe0, 0x3c, 0x04, 0x04, 0xf0, 0x3c, 0x04, 0x04, 0x70, 0x24, 0x05, 0x04, 0x80, 0x24, 0x05, 0x04, 0xe0, 0x10, 0x06, 0x04, + 0xf0, 0x10, 0x06, 0x04, 0xc0, 0x01, 0x07, 0x04, 0x40, 0x2a, 0x08, 0x05, 0x40, 0x17, 0x09, 0x05, 0x40, 0x2f, 0x0b, 0x06, 0x00, 0x32, 0x0e, 0x07, 0x00, 0x28, 0x15, 0x09, 0xb0, 0x3e, 0x00, 0x04, + 0xc0, 0x3e, 0x00, 0x04, 0x30, 0x36, 0x01, 0x03, 0x38, 0x36, 0x01, 0x03, 0x40, 0x36, 0x01, 0x03, 0x48, 0x36, 0x01, 0x03, 0x98, 0x1f, 0x02, 0x03, 0xa0, 0x1f, 0x02, 0x03, 0xa8, 0x1f, 0x02, 0x03, + 0xb0, 0x1f, 0x02, 0x03, 0x20, 0x0d, 0x03, 0x03, 0x28, 0x0d, 0x03, 0x03, 0x00, 0x3d, 0x04, 0x04, 0x10, 0x3d, 0x04, 0x04, 0x90, 0x24, 0x05, 0x04, 0xa0, 0x24, 0x05, 0x04, 0x00, 0x11, 0x06, 0x04, + 0x10, 0x11, 0x06, 0x04, 0xd0, 0x01, 0x07, 0x04, 0x60, 0x2a, 0x08, 0x05, 0x60, 0x17, 0x09, 0x05, 0x80, 0x2f, 0x0b, 0x06, 0x80, 0x32, 0x0e, 0x07, 0x00, 0x2a, 0x15, 0x09, 0xd0, 0x3e, 0x00, 0x04, + 0xe0, 0x3e, 0x00, 0x04, 0x50, 0x36, 0x01, 0x03, 0x58, 0x36, 0x01, 0x03, 0x60, 0x36, 0x01, 0x03, 0x68, 0x36, 0x01, 0x03, 0xb8, 0x1f, 0x02, 0x03, 0xc0, 0x1f, 0x02, 0x03, 0xc8, 0x1f, 0x02, 0x03, + 0xd0, 0x1f, 0x02, 0x03, 0x30, 0x0d, 0x03, 0x03, 0x38, 0x0d, 0x03, 0x03, 0x20, 0x3d, 0x04, 0x04, 0x30, 0x3d, 0x04, 0x04, 0xb0, 0x24, 0x05, 0x04, 0xc0, 0x24, 0x05, 0x04, 0x20, 0x11, 0x06, 0x04, + 0x30, 0x11, 0x06, 0x04, 0xe0, 0x01, 0x07, 0x04, 0x80, 0x2a, 0x08, 0x05, 0x80, 0x17, 0x09, 0x05, 0xc0, 0x2f, 0x0b, 0x06, 0x00, 0x33, 0x0e, 0x07, 0x00, 0x2c, 0x15, 0x09, 0xf0, 0x3e, 0x00, 0x04, + 0x00, 0x3f, 0x00, 0x04, 0x70, 0x36, 0x01, 0x03, 0x78, 0x36, 0x01, 0x03, 0x80, 0x36, 0x01, 0x03, 0x88, 0x36, 0x01, 0x03, 0xd8, 0x1f, 0x02, 0x03, 0xe0, 0x1f, 0x02, 0x03, 0xe8, 0x1f, 0x02, 0x03, + 0xf0, 0x1f, 0x02, 0x03, 0x40, 0x0d, 0x03, 0x03, 0x48, 0x0d, 0x03, 0x03, 0x40, 0x3d, 0x04, 0x04, 0x50, 0x3d, 0x04, 0x04, 0xd0, 0x24, 0x05, 0x04, 0xe0, 0x24, 0x05, 0x04, 0x40, 0x11, 0x06, 0x04, + 0x50, 0x11, 0x06, 0x04, 0xf0, 0x01, 0x07, 0x04, 0xa0, 0x2a, 0x08, 0x05, 0xa0, 0x17, 0x09, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x80, 0x33, 0x0e, 0x07, 0x00, 0x10, 0x16, 0x09, 0x10, 0x3f, 0x00, 0x04, + 0x20, 0x3f, 0x00, 0x04, 0x90, 0x36, 0x01, 0x03, 0x98, 0x36, 0x01, 0x03, 0xa0, 0x36, 0x01, 0x03, 0xa8, 0x36, 0x01, 0x03, 0xf8, 0x1f, 0x02, 0x03, 0x00, 0x20, 0x02, 0x03, 0x08, 0x20, 0x02, 0x03, + 0x10, 0x20, 0x02, 0x03, 0x50, 0x0d, 0x03, 0x03, 0x58, 0x0d, 0x03, 0x03, 0x60, 0x3d, 0x04, 0x04, 0x70, 0x3d, 0x04, 0x04, 0xf0, 0x24, 0x05, 0x04, 0x00, 0x25, 0x05, 0x04, 0x60, 0x11, 0x06, 0x04, + 0x70, 0x11, 0x06, 0x04, 0x00, 0x02, 0x07, 0x04, 0xc0, 0x2a, 0x08, 0x05, 0xc0, 0x17, 0x09, 0x05, 0x40, 0x30, 0x0b, 0x06, 0x00, 0x34, 0x0e, 0x07, 0x00, 0x12, 0x16, 0x09, 0x30, 0x3f, 0x00, 0x04, + 0x40, 0x3f, 0x00, 0x04, 0xb0, 0x36, 0x01, 0x03, 0xb8, 0x36, 0x01, 0x03, 0xc0, 0x36, 0x01, 0x03, 0xc8, 0x36, 0x01, 0x03, 0x18, 0x20, 0x02, 0x03, 0x20, 0x20, 0x02, 0x03, 0x28, 0x20, 0x02, 0x03, + 0x60, 0x0d, 0x03, 0x03, 0x68, 0x0d, 0x03, 0x03, 0x70, 0x0d, 0x03, 0x03, 0x80, 0x3d, 0x04, 0x04, 0x90, 0x3d, 0x04, 0x04, 0x10, 0x25, 0x05, 0x04, 0x20, 0x25, 0x05, 0x04, 0x80, 0x11, 0x06, 0x04, + 0x90, 0x11, 0x06, 0x04, 0x10, 0x02, 0x07, 0x04, 0xe0, 0x2a, 0x08, 0x05, 0xe0, 0x17, 0x09, 0x05, 0x80, 0x30, 0x0b, 0x06, 0x80, 0x34, 0x0e, 0x07, 0x00, 0x14, 0x16, 0x09, 0x50, 0x3f, 0x00, 0x04, + 0x60, 0x3f, 0x00, 0x04, 0xd0, 0x36, 0x01, 0x03, 0xd8, 0x36, 0x01, 0x03, 0xe0, 0x36, 0x01, 0x03, 0xe8, 0x36, 0x01, 0x03, 0x30, 0x20, 0x02, 0x03, 0x38, 0x20, 0x02, 0x03, 0x40, 0x20, 0x02, 0x03, + 0x78, 0x0d, 0x03, 0x03, 0x80, 0x0d, 0x03, 0x03, 0x88, 0x0d, 0x03, 0x03, 0xa0, 0x3d, 0x04, 0x04, 0xb0, 0x3d, 0x04, 0x04, 0x30, 0x25, 0x05, 0x04, 0x40, 0x25, 0x05, 0x04, 0xa0, 0x11, 0x06, 0x04, + 0xb0, 0x11, 0x06, 0x04, 0x20, 0x02, 0x07, 0x04, 0x00, 0x2b, 0x08, 0x05, 0x40, 0x05, 0x0a, 0x05, 0xc0, 0x30, 0x0b, 0x06, 0x00, 0x35, 0x0e, 0x07, 0x00, 0x16, 0x16, 0x09, 0x70, 0x3f, 0x00, 0x04, + 0x80, 0x3f, 0x00, 0x04, 0xf0, 0x36, 0x01, 0x03, 0xf8, 0x36, 0x01, 0x03, 0x00, 0x37, 0x01, 0x03, 0x08, 0x37, 0x01, 0x03, 0x48, 0x20, 0x02, 0x03, 0x50, 0x20, 0x02, 0x03, 0x58, 0x20, 0x02, 0x03, + 0x90, 0x0d, 0x03, 0x03, 0x98, 0x0d, 0x03, 0x03, 0xa0, 0x0d, 0x03, 0x03, 0xc0, 0x3d, 0x04, 0x04, 0xd0, 0x3d, 0x04, 0x04, 0x50, 0x25, 0x05, 0x04, 0x60, 0x25, 0x05, 0x04, 0xc0, 0x11, 0x06, 0x04, + 0xd0, 0x11, 0x06, 0x04, 0x30, 0x02, 0x07, 0x04, 0x20, 0x2b, 0x08, 0x05, 0x60, 0x05, 0x0a, 0x05, 0x00, 0x31, 0x0b, 0x06, 0x80, 0x35, 0x0e, 0x07, 0x00, 0x02, 0x17, 0x09, 0x90, 0x3f, 0x00, 0x04, + 0xa0, 0x3f, 0x00, 0x04, 0x10, 0x37, 0x01, 0x03, 0x18, 0x37, 0x01, 0x03, 0x20, 0x37, 0x01, 0x03, 0x28, 0x37, 0x01, 0x03, 0x60, 0x20, 0x02, 0x03, 0x68, 0x20, 0x02, 0x03, 0x70, 0x20, 0x02, 0x03, + 0xa8, 0x0d, 0x03, 0x03, 0xb0, 0x0d, 0x03, 0x03, 0xb8, 0x0d, 0x03, 0x03, 0xe0, 0x3d, 0x04, 0x04, 0xf0, 0x3d, 0x04, 0x04, 0x70, 0x25, 0x05, 0x04, 0x80, 0x25, 0x05, 0x04, 0xe0, 0x11, 0x06, 0x04, + 0xf0, 0x11, 0x06, 0x04, 0x40, 0x02, 0x07, 0x04, 0x40, 0x2b, 0x08, 0x05, 0x80, 0x05, 0x0a, 0x05, 0x40, 0x31, 0x0b, 0x06, 0x00, 0x36, 0x0e, 0x07, 0x00, 0x04, 0x17, 0x09, 0xb0, 0x3f, 0x00, 0x04, + 0xc0, 0x3f, 0x00, 0x04, 0x30, 0x37, 0x01, 0x03, 0x38, 0x37, 0x01, 0x03, 0x40, 0x37, 0x01, 0x03, 0x48, 0x37, 0x01, 0x03, 0x78, 0x20, 0x02, 0x03, 0x80, 0x20, 0x02, 0x03, 0x88, 0x20, 0x02, 0x03, + 0xc0, 0x0d, 0x03, 0x03, 0xc8, 0x0d, 0x03, 0x03, 0xd0, 0x0d, 0x03, 0x03, 0x00, 0x3e, 0x04, 0x04, 0x10, 0x3e, 0x04, 0x04, 0x90, 0x25, 0x05, 0x04, 0xa0, 0x25, 0x05, 0x04, 0x00, 0x12, 0x06, 0x04, + 0x10, 0x12, 0x06, 0x04, 0x50, 0x02, 0x07, 0x04, 0x60, 0x2b, 0x08, 0x05, 0xa0, 0x05, 0x0a, 0x05, 0x80, 0x31, 0x0b, 0x06, 0x80, 0x36, 0x0e, 0x07, 0x00, 0x06, 0x17, 0x09, 0xd0, 0x3f, 0x00, 0x04, + 0xe0, 0x3f, 0x00, 0x04, 0x50, 0x37, 0x01, 0x03, 0x58, 0x37, 0x01, 0x03, 0x60, 0x37, 0x01, 0x03, 0x68, 0x37, 0x01, 0x03, 0x90, 0x20, 0x02, 0x03, 0x98, 0x20, 0x02, 0x03, 0xa0, 0x20, 0x02, 0x03, + 0xd8, 0x0d, 0x03, 0x03, 0xe0, 0x0d, 0x03, 0x03, 0xe8, 0x0d, 0x03, 0x03, 0x20, 0x3e, 0x04, 0x04, 0x30, 0x3e, 0x04, 0x04, 0xb0, 0x25, 0x05, 0x04, 0xc0, 0x25, 0x05, 0x04, 0x20, 0x12, 0x06, 0x04, + 0x30, 0x12, 0x06, 0x04, 0x60, 0x02, 0x07, 0x04, 0x80, 0x2b, 0x08, 0x05, 0xc0, 0x05, 0x0a, 0x05, 0xc0, 0x31, 0x0b, 0x06, 0x00, 0x37, 0x0e, 0x07, 0x00, 0x28, 0x18, 0x0a, 0xf0, 0x3f, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x03, 0x70, 0x37, 0x01, 0x03, 0x78, 0x37, 0x01, 0x03, 0x80, 0x37, 0x01, 0x03, 0x88, 0x37, 0x01, 0x03, 0xa8, 0x20, 0x02, 0x03, 0xb0, 0x20, 0x02, 0x03, 0xb8, 0x20, 0x02, 0x03, + 0xf0, 0x0d, 0x03, 0x03, 0xf8, 0x0d, 0x03, 0x03, 0x00, 0x0e, 0x03, 0x03, 0x40, 0x3e, 0x04, 0x04, 0x50, 0x3e, 0x04, 0x04, 0xd0, 0x25, 0x05, 0x04, 0xe0, 0x25, 0x05, 0x04, 0x40, 0x12, 0x06, 0x04, + 0x50, 0x12, 0x06, 0x04, 0x70, 0x02, 0x07, 0x04, 0xa0, 0x2b, 0x08, 0x05, 0xe0, 0x05, 0x0a, 0x05, 0x00, 0x32, 0x0b, 0x06, 0x80, 0x37, 0x0e, 0x07, 0x00, 0x2c, 0x18, 0x0a, 0x08, 0x00, 0x00, 0x03, + 0x10, 0x00, 0x00, 0x03, 0x90, 0x37, 0x01, 0x03, 0x98, 0x37, 0x01, 0x03, 0xa0, 0x37, 0x01, 0x03, 0xa8, 0x37, 0x01, 0x03, 0xc0, 0x20, 0x02, 0x03, 0xc8, 0x20, 0x02, 0x03, 0xd0, 0x20, 0x02, 0x03, + 0x08, 0x0e, 0x03, 0x03, 0x10, 0x0e, 0x03, 0x03, 0x18, 0x0e, 0x03, 0x03, 0x60, 0x3e, 0x04, 0x04, 0x70, 0x3e, 0x04, 0x04, 0xf0, 0x25, 0x05, 0x04, 0x00, 0x26, 0x05, 0x04, 0x60, 0x12, 0x06, 0x04, + 0x70, 0x12, 0x06, 0x04, 0x80, 0x02, 0x07, 0x04, 0xc0, 0x2b, 0x08, 0x05, 0x00, 0x06, 0x0a, 0x05, 0x40, 0x32, 0x0b, 0x06, 0x00, 0x38, 0x0e, 0x07, 0x00, 0x30, 0x18, 0x0a, 0x18, 0x00, 0x00, 0x03, + 0x20, 0x00, 0x00, 0x03, 0xb0, 0x37, 0x01, 0x03, 0xb8, 0x37, 0x01, 0x03, 0xc0, 0x37, 0x01, 0x03, 0xc8, 0x37, 0x01, 0x03, 0xd8, 0x20, 0x02, 0x03, 0xe0, 0x20, 0x02, 0x03, 0xe8, 0x20, 0x02, 0x03, + 0x20, 0x0e, 0x03, 0x03, 0x28, 0x0e, 0x03, 0x03, 0x30, 0x0e, 0x03, 0x03, 0x80, 0x3e, 0x04, 0x04, 0x90, 0x3e, 0x04, 0x04, 0x10, 0x26, 0x05, 0x04, 0x20, 0x26, 0x05, 0x04, 0x80, 0x12, 0x06, 0x04, + 0x90, 0x12, 0x06, 0x04, 0x90, 0x02, 0x07, 0x04, 0xe0, 0x2b, 0x08, 0x05, 0x20, 0x06, 0x0a, 0x05, 0x80, 0x32, 0x0b, 0x06, 0x80, 0x38, 0x0e, 0x07, 0x00, 0x14, 0x19, 0x0a, 0x28, 0x00, 0x00, 0x03, + 0x30, 0x00, 0x00, 0x03, 0xd0, 0x37, 0x01, 0x03, 0xd8, 0x37, 0x01, 0x03, 0xe0, 0x37, 0x01, 0x03, 0xe8, 0x37, 0x01, 0x03, 0xf0, 0x20, 0x02, 0x03, 0xf8, 0x20, 0x02, 0x03, 0x00, 0x21, 0x02, 0x03, + 0x38, 0x0e, 0x03, 0x03, 0x40, 0x0e, 0x03, 0x03, 0x48, 0x0e, 0x03, 0x03, 0xa0, 0x3e, 0x04, 0x04, 0xb0, 0x3e, 0x04, 0x04, 0x30, 0x26, 0x05, 0x04, 0x40, 0x26, 0x05, 0x04, 0xa0, 0x12, 0x06, 0x04, + 0xb0, 0x12, 0x06, 0x04, 0xa0, 0x02, 0x07, 0x04, 0x00, 0x2c, 0x08, 0x05, 0x40, 0x06, 0x0a, 0x05, 0xc0, 0x32, 0x0b, 0x06, 0x00, 0x39, 0x0e, 0x07, 0x00, 0x18, 0x19, 0x0a, 0x38, 0x00, 0x00, 0x03, + 0x40, 0x00, 0x00, 0x03, 0xf0, 0x37, 0x01, 0x03, 0xf8, 0x37, 0x01, 0x03, 0x00, 0x38, 0x01, 0x03, 0x08, 0x38, 0x01, 0x03, 0x08, 0x21, 0x02, 0x03, 0x10, 0x21, 0x02, 0x03, 0x18, 0x21, 0x02, 0x03, + 0x50, 0x0e, 0x03, 0x03, 0x58, 0x0e, 0x03, 0x03, 0x60, 0x0e, 0x03, 0x03, 0xc0, 0x3e, 0x04, 0x04, 0xd0, 0x3e, 0x04, 0x04, 0x50, 0x26, 0x05, 0x04, 0x60, 0x26, 0x05, 0x04, 0xc0, 0x12, 0x06, 0x04, + 0xd0, 0x12, 0x06, 0x04, 0xb0, 0x02, 0x07, 0x04, 0x20, 0x2c, 0x08, 0x05, 0x60, 0x06, 0x0a, 0x05, 0x00, 0x33, 0x0b, 0x06, 0x00, 0x1f, 0x0f, 0x07, 0x00, 0x08, 0x1a, 0x0a, 0x48, 0x00, 0x00, 0x03, + 0x50, 0x00, 0x00, 0x03, 0x10, 0x38, 0x01, 0x03, 0x18, 0x38, 0x01, 0x03, 0x20, 0x38, 0x01, 0x03, 0x28, 0x38, 0x01, 0x03, 0x20, 0x21, 0x02, 0x03, 0x28, 0x21, 0x02, 0x03, 0x30, 0x21, 0x02, 0x03, + 0x68, 0x0e, 0x03, 0x03, 0x70, 0x0e, 0x03, 0x03, 0x78, 0x0e, 0x03, 0x03, 0xe0, 0x3e, 0x04, 0x04, 0xf0, 0x3e, 0x04, 0x04, 0x70, 0x26, 0x05, 0x04, 0x80, 0x26, 0x05, 0x04, 0xe0, 0x12, 0x06, 0x04, + 0xf0, 0x12, 0x06, 0x04, 0xc0, 0x02, 0x07, 0x04, 0x40, 0x2c, 0x08, 0x05, 0x80, 0x06, 0x0a, 0x05, 0xc0, 0x1b, 0x0c, 0x06, 0x80, 0x1f, 0x0f, 0x07, 0x00, 0x0c, 0x1a, 0x0a, 0x58, 0x00, 0x00, 0x03, + 0x60, 0x00, 0x00, 0x03, 0x30, 0x38, 0x01, 0x03, 0x38, 0x38, 0x01, 0x03, 0x40, 0x38, 0x01, 0x03, 0x48, 0x38, 0x01, 0x03, 0x38, 0x21, 0x02, 0x03, 0x40, 0x21, 0x02, 0x03, 0x48, 0x21, 0x02, 0x03, + 0x80, 0x0e, 0x03, 0x03, 0x88, 0x0e, 0x03, 0x03, 0x90, 0x0e, 0x03, 0x03, 0x00, 0x3f, 0x04, 0x04, 0x10, 0x3f, 0x04, 0x04, 0x90, 0x26, 0x05, 0x04, 0xa0, 0x26, 0x05, 0x04, 0x00, 0x13, 0x06, 0x04, + 0x10, 0x13, 0x06, 0x04, 0xd0, 0x02, 0x07, 0x04, 0x60, 0x2c, 0x08, 0x05, 0xa0, 0x06, 0x0a, 0x05, 0x00, 0x1c, 0x0c, 0x06, 0x00, 0x20, 0x0f, 0x07, 0x00, 0x30, 0x1b, 0x0b, 0x68, 0x00, 0x00, 0x03, + 0x70, 0x00, 0x00, 0x03, 0x50, 0x38, 0x01, 0x03, 0x58, 0x38, 0x01, 0x03, 0x60, 0x38, 0x01, 0x03, 0x68, 0x38, 0x01, 0x03, 0x50, 0x21, 0x02, 0x03, 0x58, 0x21, 0x02, 0x03, 0x60, 0x21, 0x02, 0x03, + 0x98, 0x0e, 0x03, 0x03, 0xa0, 0x0e, 0x03, 0x03, 0xa8, 0x0e, 0x03, 0x03, 0x20, 0x3f, 0x04, 0x04, 0x30, 0x3f, 0x04, 0x04, 0xb0, 0x26, 0x05, 0x04, 0xc0, 0x26, 0x05, 0x04, 0x20, 0x13, 0x06, 0x04, + 0xe0, 0x02, 0x07, 0x04, 0xf0, 0x02, 0x07, 0x04, 0x80, 0x2c, 0x08, 0x05, 0xc0, 0x06, 0x0a, 0x05, 0x40, 0x1c, 0x0c, 0x06, 0x80, 0x20, 0x0f, 0x07, 0x00, 0x38, 0x1b, 0x0b, 0x78, 0x00, 0x00, 0x03, + 0x80, 0x00, 0x00, 0x03, 0x70, 0x38, 0x01, 0x03, 0x78, 0x38, 0x01, 0x03, 0x80, 0x38, 0x01, 0x03, 0x88, 0x38, 0x01, 0x03, 0x68, 0x21, 0x02, 0x03, 0x70, 0x21, 0x02, 0x03, 0x78, 0x21, 0x02, 0x03, + 0xb0, 0x0e, 0x03, 0x03, 0xb8, 0x0e, 0x03, 0x03, 0xc0, 0x0e, 0x03, 0x03, 0x40, 0x3f, 0x04, 0x04, 0x50, 0x3f, 0x04, 0x04, 0xd0, 0x26, 0x05, 0x04, 0xe0, 0x26, 0x05, 0x04, 0x30, 0x13, 0x06, 0x04, + 0x00, 0x03, 0x07, 0x04, 0x10, 0x03, 0x07, 0x04, 0xa0, 0x2c, 0x08, 0x05, 0xe0, 0x06, 0x0a, 0x05, 0x80, 0x1c, 0x0c, 0x06, 0x00, 0x21, 0x0f, 0x07, 0x00, 0x20, 0x1c, 0x0b, 0x88, 0x00, 0x00, 0x03, + 0x90, 0x00, 0x00, 0x03, 0x90, 0x38, 0x01, 0x03, 0x98, 0x38, 0x01, 0x03, 0xa0, 0x38, 0x01, 0x03, 0xa8, 0x38, 0x01, 0x03, 0x80, 0x21, 0x02, 0x03, 0x88, 0x21, 0x02, 0x03, 0x90, 0x21, 0x02, 0x03, + 0xc8, 0x0e, 0x03, 0x03, 0xd0, 0x0e, 0x03, 0x03, 0xd8, 0x0e, 0x03, 0x03, 0x60, 0x3f, 0x04, 0x04, 0x70, 0x3f, 0x04, 0x04, 0xf0, 0x26, 0x05, 0x04, 0x00, 0x27, 0x05, 0x04, 0x40, 0x13, 0x06, 0x04, + 0x20, 0x03, 0x07, 0x04, 0x30, 0x03, 0x07, 0x04, 0xc0, 0x2c, 0x08, 0x05, 0x00, 0x07, 0x0a, 0x05, 0xc0, 0x1c, 0x0c, 0x06, 0x80, 0x21, 0x0f, 0x07, 0x00, 0x08, 0x1d, 0x0b, 0x98, 0x00, 0x00, 0x03, + 0xa0, 0x00, 0x00, 0x03, 0xb0, 0x38, 0x01, 0x03, 0xb8, 0x38, 0x01, 0x03, 0xc0, 0x38, 0x01, 0x03, 0xc8, 0x38, 0x01, 0x03, 0x98, 0x21, 0x02, 0x03, 0xa0, 0x21, 0x02, 0x03, 0xa8, 0x21, 0x02, 0x03, + 0xe0, 0x0e, 0x03, 0x03, 0xe8, 0x0e, 0x03, 0x03, 0xf0, 0x0e, 0x03, 0x03, 0x80, 0x3f, 0x04, 0x04, 0x90, 0x3f, 0x04, 0x04, 0x10, 0x27, 0x05, 0x04, 0x20, 0x27, 0x05, 0x04, 0x50, 0x13, 0x06, 0x04, + 0x40, 0x03, 0x07, 0x04, 0x50, 0x03, 0x07, 0x04, 0xe0, 0x2c, 0x08, 0x05, 0x20, 0x07, 0x0a, 0x05, 0x00, 0x1d, 0x0c, 0x06, 0x00, 0x22, 0x0f, 0x07, 0x00, 0x00, 0x1e, 0x0b, 0xa8, 0x00, 0x00, 0x03, + 0xb0, 0x00, 0x00, 0x03, 0xd0, 0x38, 0x01, 0x03, 0xd8, 0x38, 0x01, 0x03, 0xe0, 0x38, 0x01, 0x03, 0xe8, 0x38, 0x01, 0x03, 0xb0, 0x21, 0x02, 0x03, 0xb8, 0x21, 0x02, 0x03, 0xc0, 0x21, 0x02, 0x03, + 0xf8, 0x0e, 0x03, 0x03, 0x00, 0x0f, 0x03, 0x03, 0x08, 0x0f, 0x03, 0x03, 0xa0, 0x3f, 0x04, 0x04, 0xb0, 0x3f, 0x04, 0x04, 0x30, 0x27, 0x05, 0x04, 0x40, 0x27, 0x05, 0x04, 0x60, 0x13, 0x06, 0x04, + 0x60, 0x03, 0x07, 0x04, 0x70, 0x03, 0x07, 0x04, 0x00, 0x2d, 0x08, 0x05, 0x40, 0x07, 0x0a, 0x05, 0x40, 0x1d, 0x0c, 0x06, 0x80, 0x22, 0x0f, 0x07, 0x00, 0x20, 0x1f, 0x0c, 0xb8, 0x00, 0x00, 0x03, + 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x38, 0x01, 0x03, 0xf8, 0x38, 0x01, 0x03, 0x00, 0x39, 0x01, 0x03, 0x08, 0x39, 0x01, 0x03, 0xc8, 0x21, 0x02, 0x03, 0xd0, 0x21, 0x02, 0x03, 0xd8, 0x21, 0x02, 0x03, + 0x10, 0x0f, 0x03, 0x03, 0x18, 0x0f, 0x03, 0x03, 0x20, 0x0f, 0x03, 0x03, 0xc0, 0x3f, 0x04, 0x04, 0xd0, 0x3f, 0x04, 0x04, 0x50, 0x27, 0x05, 0x04, 0x60, 0x27, 0x05, 0x04, 0x70, 0x13, 0x06, 0x04, + 0x80, 0x03, 0x07, 0x04, 0x90, 0x03, 0x07, 0x04, 0x20, 0x2d, 0x08, 0x05, 0x60, 0x07, 0x0a, 0x05, 0x80, 0x1d, 0x0c, 0x06, 0x00, 0x23, 0x0f, 0x07, 0x00, 0x00, 0x21, 0x0c, 0xc8, 0x00, 0x00, 0x03, + 0xd0, 0x00, 0x00, 0x03, 0x10, 0x39, 0x01, 0x03, 0x18, 0x39, 0x01, 0x03, 0x20, 0x39, 0x01, 0x03, 0x28, 0x39, 0x01, 0x03, 0xe0, 0x21, 0x02, 0x03, 0xe8, 0x21, 0x02, 0x03, 0xf0, 0x21, 0x02, 0x03, + 0x28, 0x0f, 0x03, 0x03, 0x30, 0x0f, 0x03, 0x03, 0x38, 0x0f, 0x03, 0x03, 0xe0, 0x3f, 0x04, 0x04, 0xf0, 0x3f, 0x04, 0x04, 0x70, 0x27, 0x05, 0x04, 0x80, 0x27, 0x05, 0x04, 0x80, 0x13, 0x06, 0x04, + 0xa0, 0x03, 0x07, 0x04, 0xb0, 0x03, 0x07, 0x04, 0x40, 0x2d, 0x08, 0x05, 0x80, 0x07, 0x0a, 0x05, 0xc0, 0x1d, 0x0c, 0x06, 0x80, 0x23, 0x0f, 0x07, 0x00, 0x00, 0x24, 0x0d, 0xd8, 0x00, 0x00, 0x03, + 0xe0, 0x00, 0x00, 0x03, 0x30, 0x39, 0x01, 0x03, 0x38, 0x39, 0x01, 0x03, 0x40, 0x39, 0x01, 0x03, 0x48, 0x39, 0x01, 0x03, 0xf8, 0x21, 0x02, 0x03, 0x00, 0x22, 0x02, 0x03, 0x08, 0x22, 0x02, 0x03, + 0x40, 0x0f, 0x03, 0x03, 0x48, 0x0f, 0x03, 0x03, 0x50, 0x0f, 0x03, 0x03, 0x00, 0x00, 0x04, 0x03, 0x08, 0x00, 0x04, 0x03, 0x90, 0x27, 0x05, 0x04, 0xa0, 0x27, 0x05, 0x04, 0x90, 0x13, 0x06, 0x04, + 0xc0, 0x03, 0x07, 0x04, 0xd0, 0x03, 0x07, 0x04, 0x60, 0x2d, 0x08, 0x05, 0xa0, 0x07, 0x0a, 0x05, 0x00, 0x1e, 0x0c, 0x06, 0x00, 0x24, 0x0f, 0x07, 0xe8, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x03, + 0xf8, 0x00, 0x00, 0x03, 0x50, 0x39, 0x01, 0x03, 0x58, 0x39, 0x01, 0x03, 0x60, 0x39, 0x01, 0x03, 0x68, 0x39, 0x01, 0x03, 0x10, 0x22, 0x02, 0x03, 0x18, 0x22, 0x02, 0x03, 0x20, 0x22, 0x02, 0x03, + 0x58, 0x0f, 0x03, 0x03, 0x60, 0x0f, 0x03, 0x03, 0x68, 0x0f, 0x03, 0x03, 0x10, 0x00, 0x04, 0x03, 0x18, 0x00, 0x04, 0x03, 0xb0, 0x27, 0x05, 0x04, 0xc0, 0x27, 0x05, 0x04, 0xa0, 0x13, 0x06, 0x04, + 0xe0, 0x03, 0x07, 0x04, 0xf0, 0x03, 0x07, 0x04, 0x80, 0x2d, 0x08, 0x05, 0xc0, 0x07, 0x0a, 0x05, 0x40, 0x1e, 0x0c, 0x06, 0x80, 0x24, 0x0f, 0x07, 0x00, 0x01, 0x00, 0x03, 0x08, 0x01, 0x00, 0x03, + 0x10, 0x01, 0x00, 0x03, 0x70, 0x39, 0x01, 0x03, 0x78, 0x39, 0x01, 0x03, 0x80, 0x39, 0x01, 0x03, 0x88, 0x39, 0x01, 0x03, 0x28, 0x22, 0x02, 0x03, 0x30, 0x22, 0x02, 0x03, 0x38, 0x22, 0x02, 0x03, + 0x70, 0x0f, 0x03, 0x03, 0x78, 0x0f, 0x03, 0x03, 0x80, 0x0f, 0x03, 0x03, 0x20, 0x00, 0x04, 0x03, 0x28, 0x00, 0x04, 0x03, 0xd0, 0x27, 0x05, 0x04, 0xe0, 0x27, 0x05, 0x04, 0xb0, 0x13, 0x06, 0x04, + 0x00, 0x04, 0x07, 0x04, 0x10, 0x04, 0x07, 0x04, 0xa0, 0x2d, 0x08, 0x05, 0xe0, 0x07, 0x0a, 0x05, 0x80, 0x1e, 0x0c, 0x06, 0x00, 0x25, 0x0f, 0x07, 0x18, 0x01, 0x00, 0x03, 0x20, 0x01, 0x00, 0x03, + 0x28, 0x01, 0x00, 0x03, 0x90, 0x39, 0x01, 0x03, 0x98, 0x39, 0x01, 0x03, 0xa0, 0x39, 0x01, 0x03, 0xa8, 0x39, 0x01, 0x03, 0x40, 0x22, 0x02, 0x03, 0x48, 0x22, 0x02, 0x03, 0x50, 0x22, 0x02, 0x03, + 0x88, 0x0f, 0x03, 0x03, 0x90, 0x0f, 0x03, 0x03, 0x98, 0x0f, 0x03, 0x03, 0x30, 0x00, 0x04, 0x03, 0x38, 0x00, 0x04, 0x03, 0xf0, 0x27, 0x05, 0x04, 0x00, 0x28, 0x05, 0x04, 0xc0, 0x13, 0x06, 0x04, + 0x20, 0x04, 0x07, 0x04, 0x30, 0x04, 0x07, 0x04, 0x00, 0x18, 0x09, 0x05, 0x00, 0x08, 0x0a, 0x05, 0xc0, 0x1e, 0x0c, 0x06, 0x80, 0x25, 0x0f, 0x07, 0x30, 0x01, 0x00, 0x03, 0x38, 0x01, 0x00, 0x03, + 0x40, 0x01, 0x00, 0x03, 0xb0, 0x39, 0x01, 0x03, 0xb8, 0x39, 0x01, 0x03, 0xc0, 0x39, 0x01, 0x03, 0xc8, 0x39, 0x01, 0x03, 0x58, 0x22, 0x02, 0x03, 0x60, 0x22, 0x02, 0x03, 0x68, 0x22, 0x02, 0x03, + 0xa0, 0x0f, 0x03, 0x03, 0xa8, 0x0f, 0x03, 0x03, 0xb0, 0x0f, 0x03, 0x03, 0x40, 0x00, 0x04, 0x03, 0x48, 0x00, 0x04, 0x03, 0x10, 0x28, 0x05, 0x04, 0x20, 0x28, 0x05, 0x04, 0xd0, 0x13, 0x06, 0x04, + 0x40, 0x04, 0x07, 0x04, 0x50, 0x04, 0x07, 0x04, 0x20, 0x18, 0x09, 0x05, 0x20, 0x08, 0x0a, 0x05, 0x00, 0x1f, 0x0c, 0x06, 0x00, 0x26, 0x0f, 0x07, 0x48, 0x01, 0x00, 0x03, 0x50, 0x01, 0x00, 0x03, + 0x58, 0x01, 0x00, 0x03, 0xd0, 0x39, 0x01, 0x03, 0xd8, 0x39, 0x01, 0x03, 0xe0, 0x39, 0x01, 0x03, 0xe8, 0x39, 0x01, 0x03, 0x70, 0x22, 0x02, 0x03, 0x78, 0x22, 0x02, 0x03, 0x80, 0x22, 0x02, 0x03, + 0xb8, 0x0f, 0x03, 0x03, 0xc0, 0x0f, 0x03, 0x03, 0xc8, 0x0f, 0x03, 0x03, 0x50, 0x00, 0x04, 0x03, 0x58, 0x00, 0x04, 0x03, 0x30, 0x28, 0x05, 0x04, 0x40, 0x28, 0x05, 0x04, 0xe0, 0x13, 0x06, 0x04, + 0x60, 0x04, 0x07, 0x04, 0x70, 0x04, 0x07, 0x04, 0x40, 0x18, 0x09, 0x05, 0x40, 0x08, 0x0a, 0x05, 0x40, 0x1f, 0x0c, 0x06, 0x80, 0x26, 0x0f, 0x07, 0x60, 0x01, 0x00, 0x03, 0x68, 0x01, 0x00, 0x03, + 0x70, 0x01, 0x00, 0x03, 0xf0, 0x39, 0x01, 0x03, 0xf8, 0x39, 0x01, 0x03, 0x00, 0x3a, 0x01, 0x03, 0x08, 0x3a, 0x01, 0x03, 0x88, 0x22, 0x02, 0x03, 0x90, 0x22, 0x02, 0x03, 0x98, 0x22, 0x02, 0x03, + 0xd0, 0x0f, 0x03, 0x03, 0xd8, 0x0f, 0x03, 0x03, 0xe0, 0x0f, 0x03, 0x03, 0x60, 0x00, 0x04, 0x03, 0x68, 0x00, 0x04, 0x03, 0x50, 0x28, 0x05, 0x04, 0x60, 0x28, 0x05, 0x04, 0xf0, 0x13, 0x06, 0x04, + 0x80, 0x04, 0x07, 0x04, 0x90, 0x04, 0x07, 0x04, 0x60, 0x18, 0x09, 0x05, 0x60, 0x08, 0x0a, 0x05, 0x80, 0x1f, 0x0c, 0x06, 0x00, 0x27, 0x0f, 0x07, 0x78, 0x01, 0x00, 0x03, 0x80, 0x01, 0x00, 0x03, + 0x88, 0x01, 0x00, 0x03, 0x10, 0x3a, 0x01, 0x03, 0x18, 0x3a, 0x01, 0x03, 0x20, 0x3a, 0x01, 0x03, 0x28, 0x3a, 0x01, 0x03, 0xa0, 0x22, 0x02, 0x03, 0xa8, 0x22, 0x02, 0x03, 0xb0, 0x22, 0x02, 0x03, + 0xe8, 0x0f, 0x03, 0x03, 0xf0, 0x0f, 0x03, 0x03, 0xf8, 0x0f, 0x03, 0x03, 0x70, 0x00, 0x04, 0x03, 0x78, 0x00, 0x04, 0x03, 0x70, 0x28, 0x05, 0x04, 0x80, 0x28, 0x05, 0x04, 0x00, 0x14, 0x06, 0x04, + 0xa0, 0x04, 0x07, 0x04, 0xb0, 0x04, 0x07, 0x04, 0x80, 0x18, 0x09, 0x05, 0x80, 0x08, 0x0a, 0x05, 0xc0, 0x1f, 0x0c, 0x06, 0x80, 0x27, 0x0f, 0x07, 0x90, 0x01, 0x00, 0x03, 0x98, 0x01, 0x00, 0x03, + 0xa0, 0x01, 0x00, 0x03, 0x30, 0x3a, 0x01, 0x03, 0x38, 0x3a, 0x01, 0x03, 0x40, 0x3a, 0x01, 0x03, 0x48, 0x3a, 0x01, 0x03, 0xb8, 0x22, 0x02, 0x03, 0xc0, 0x22, 0x02, 0x03, 0xc8, 0x22, 0x02, 0x03, + 0x00, 0x10, 0x03, 0x03, 0x08, 0x10, 0x03, 0x03, 0x10, 0x10, 0x03, 0x03, 0x80, 0x00, 0x04, 0x03, 0x88, 0x00, 0x04, 0x03, 0x90, 0x28, 0x05, 0x04, 0xa0, 0x28, 0x05, 0x04, 0x10, 0x14, 0x06, 0x04, + 0xc0, 0x04, 0x07, 0x04, 0xc0, 0x2d, 0x08, 0x05, 0xa0, 0x18, 0x09, 0x05, 0xa0, 0x08, 0x0a, 0x05, 0x00, 0x20, 0x0c, 0x06, 0x00, 0x28, 0x0f, 0x07, 0xa8, 0x01, 0x00, 0x03, 0xb0, 0x01, 0x00, 0x03, + 0xb8, 0x01, 0x00, 0x03, 0x50, 0x3a, 0x01, 0x03, 0x58, 0x3a, 0x01, 0x03, 0x60, 0x3a, 0x01, 0x03, 0x68, 0x3a, 0x01, 0x03, 0xd0, 0x22, 0x02, 0x03, 0xd8, 0x22, 0x02, 0x03, 0xe0, 0x22, 0x02, 0x03, + 0x18, 0x10, 0x03, 0x03, 0x20, 0x10, 0x03, 0x03, 0x28, 0x10, 0x03, 0x03, 0x90, 0x00, 0x04, 0x03, 0x98, 0x00, 0x04, 0x03, 0xb0, 0x28, 0x05, 0x04, 0xc0, 0x28, 0x05, 0x04, 0x20, 0x14, 0x06, 0x04, + 0xd0, 0x04, 0x07, 0x04, 0xe0, 0x2d, 0x08, 0x05, 0xc0, 0x18, 0x09, 0x05, 0xc0, 0x08, 0x0a, 0x05, 0x40, 0x20, 0x0c, 0x06, 0x00, 0x10, 0x10, 0x07, 0xc0, 0x01, 0x00, 0x03, 0xc8, 0x01, 0x00, 0x03, + 0xd0, 0x01, 0x00, 0x03, 0x70, 0x3a, 0x01, 0x03, 0x78, 0x3a, 0x01, 0x03, 0x80, 0x3a, 0x01, 0x03, 0x88, 0x3a, 0x01, 0x03, 0xe8, 0x22, 0x02, 0x03, 0xf0, 0x22, 0x02, 0x03, 0xf8, 0x22, 0x02, 0x03, + 0x30, 0x10, 0x03, 0x03, 0x38, 0x10, 0x03, 0x03, 0x40, 0x10, 0x03, 0x03, 0xa0, 0x00, 0x04, 0x03, 0xa8, 0x00, 0x04, 0x03, 0xd0, 0x28, 0x05, 0x04, 0xe0, 0x28, 0x05, 0x04, 0x30, 0x14, 0x06, 0x04, + 0xe0, 0x04, 0x07, 0x04, 0x00, 0x2e, 0x08, 0x05, 0xe0, 0x18, 0x09, 0x05, 0xe0, 0x08, 0x0a, 0x05, 0x80, 0x20, 0x0c, 0x06, 0x80, 0x10, 0x10, 0x07, 0xd8, 0x01, 0x00, 0x03, 0xe0, 0x01, 0x00, 0x03, + 0xe8, 0x01, 0x00, 0x03, 0x90, 0x3a, 0x01, 0x03, 0x98, 0x3a, 0x01, 0x03, 0xa0, 0x3a, 0x01, 0x03, 0xa8, 0x3a, 0x01, 0x03, 0x00, 0x23, 0x02, 0x03, 0x08, 0x23, 0x02, 0x03, 0x10, 0x23, 0x02, 0x03, + 0x48, 0x10, 0x03, 0x03, 0x50, 0x10, 0x03, 0x03, 0x58, 0x10, 0x03, 0x03, 0xb0, 0x00, 0x04, 0x03, 0xb8, 0x00, 0x04, 0x03, 0xf0, 0x28, 0x05, 0x04, 0x00, 0x29, 0x05, 0x04, 0x40, 0x14, 0x06, 0x04, + 0xf0, 0x04, 0x07, 0x04, 0x20, 0x2e, 0x08, 0x05, 0x00, 0x19, 0x09, 0x05, 0x00, 0x09, 0x0a, 0x05, 0xc0, 0x20, 0x0c, 0x06, 0x00, 0x11, 0x10, 0x07, 0xf0, 0x01, 0x00, 0x03, 0xf8, 0x01, 0x00, 0x03, + 0x00, 0x02, 0x00, 0x03, 0xb0, 0x3a, 0x01, 0x03, 0xb8, 0x3a, 0x01, 0x03, 0xc0, 0x3a, 0x01, 0x03, 0xc8, 0x3a, 0x01, 0x03, 0x18, 0x23, 0x02, 0x03, 0x20, 0x23, 0x02, 0x03, 0x28, 0x23, 0x02, 0x03, + 0x60, 0x10, 0x03, 0x03, 0x68, 0x10, 0x03, 0x03, 0x70, 0x10, 0x03, 0x03, 0xc0, 0x00, 0x04, 0x03, 0xc8, 0x00, 0x04, 0x03, 0x10, 0x29, 0x05, 0x04, 0x20, 0x29, 0x05, 0x04, 0x50, 0x14, 0x06, 0x04, + 0x00, 0x05, 0x07, 0x04, 0x40, 0x2e, 0x08, 0x05, 0x20, 0x19, 0x09, 0x05, 0x20, 0x09, 0x0a, 0x05, 0x00, 0x21, 0x0c, 0x06, 0x80, 0x11, 0x10, 0x07, 0x08, 0x02, 0x00, 0x03, 0x10, 0x02, 0x00, 0x03, + 0x18, 0x02, 0x00, 0x03, 0xd0, 0x3a, 0x01, 0x03, 0xd8, 0x3a, 0x01, 0x03, 0xe0, 0x3a, 0x01, 0x03, 0xe8, 0x3a, 0x01, 0x03, 0x30, 0x23, 0x02, 0x03, 0x38, 0x23, 0x02, 0x03, 0x40, 0x23, 0x02, 0x03, + 0x78, 0x10, 0x03, 0x03, 0x80, 0x10, 0x03, 0x03, 0x88, 0x10, 0x03, 0x03, 0xd0, 0x00, 0x04, 0x03, 0xd8, 0x00, 0x04, 0x03, 0x30, 0x29, 0x05, 0x04, 0x40, 0x29, 0x05, 0x04, 0x60, 0x14, 0x06, 0x04, + 0x10, 0x05, 0x07, 0x04, 0x60, 0x2e, 0x08, 0x05, 0x40, 0x19, 0x09, 0x05, 0x40, 0x09, 0x0a, 0x05, 0x40, 0x21, 0x0c, 0x06, 0x00, 0x12, 0x10, 0x07, 0x20, 0x02, 0x00, 0x03, 0x28, 0x02, 0x00, 0x03, + 0x30, 0x02, 0x00, 0x03, 0xf0, 0x3a, 0x01, 0x03, 0xf8, 0x3a, 0x01, 0x03, 0x00, 0x3b, 0x01, 0x03, 0x08, 0x3b, 0x01, 0x03, 0x48, 0x23, 0x02, 0x03, 0x50, 0x23, 0x02, 0x03, 0x58, 0x23, 0x02, 0x03, + 0x90, 0x10, 0x03, 0x03, 0x98, 0x10, 0x03, 0x03, 0xa0, 0x10, 0x03, 0x03, 0xe0, 0x00, 0x04, 0x03, 0xe8, 0x00, 0x04, 0x03, 0x50, 0x29, 0x05, 0x04, 0x60, 0x29, 0x05, 0x04, 0x70, 0x14, 0x06, 0x04, + 0x20, 0x05, 0x07, 0x04, 0x80, 0x2e, 0x08, 0x05, 0x60, 0x19, 0x09, 0x05, 0x60, 0x09, 0x0a, 0x05, 0x80, 0x21, 0x0c, 0x06, 0x80, 0x12, 0x10, 0x07, 0x38, 0x02, 0x00, 0x03, 0x40, 0x02, 0x00, 0x03, + 0x48, 0x02, 0x00, 0x03, 0x10, 0x3b, 0x01, 0x03, 0x18, 0x3b, 0x01, 0x03, 0x20, 0x3b, 0x01, 0x03, 0x28, 0x3b, 0x01, 0x03, 0x60, 0x23, 0x02, 0x03, 0x68, 0x23, 0x02, 0x03, 0x70, 0x23, 0x02, 0x03, + 0xa8, 0x10, 0x03, 0x03, 0xb0, 0x10, 0x03, 0x03, 0xb8, 0x10, 0x03, 0x03, 0xf0, 0x00, 0x04, 0x03, 0xf8, 0x00, 0x04, 0x03, 0x70, 0x29, 0x05, 0x04, 0x80, 0x29, 0x05, 0x04, 0x80, 0x14, 0x06, 0x04, + 0x30, 0x05, 0x07, 0x04, 0xa0, 0x2e, 0x08, 0x05, 0x80, 0x19, 0x09, 0x05, 0x80, 0x09, 0x0a, 0x05, 0xc0, 0x21, 0x0c, 0x06, 0x00, 0x13, 0x10, 0x07, 0x50, 0x02, 0x00, 0x03, 0x58, 0x02, 0x00, 0x03, + 0x60, 0x02, 0x00, 0x03, 0x30, 0x3b, 0x01, 0x03, 0x38, 0x3b, 0x01, 0x03, 0x40, 0x3b, 0x01, 0x03, 0x48, 0x3b, 0x01, 0x03, 0x78, 0x23, 0x02, 0x03, 0x80, 0x23, 0x02, 0x03, 0x88, 0x23, 0x02, 0x03, + 0xc0, 0x10, 0x03, 0x03, 0xc8, 0x10, 0x03, 0x03, 0xd0, 0x10, 0x03, 0x03, 0x00, 0x01, 0x04, 0x03, 0x08, 0x01, 0x04, 0x03, 0x90, 0x29, 0x05, 0x04, 0xa0, 0x29, 0x05, 0x04, 0x90, 0x14, 0x06, 0x04, + 0x40, 0x05, 0x07, 0x04, 0xc0, 0x2e, 0x08, 0x05, 0xa0, 0x19, 0x09, 0x05, 0xa0, 0x09, 0x0a, 0x05, 0x00, 0x22, 0x0c, 0x06, 0x80, 0x13, 0x10, 0x07, 0x68, 0x02, 0x00, 0x03, 0x70, 0x02, 0x00, 0x03, + 0x78, 0x02, 0x00, 0x03, 0x50, 0x3b, 0x01, 0x03, 0x58, 0x3b, 0x01, 0x03, 0x60, 0x3b, 0x01, 0x03, 0x68, 0x3b, 0x01, 0x03, 0x90, 0x23, 0x02, 0x03, 0x98, 0x23, 0x02, 0x03, 0xa0, 0x23, 0x02, 0x03, + 0xd8, 0x10, 0x03, 0x03, 0xe0, 0x10, 0x03, 0x03, 0xe8, 0x10, 0x03, 0x03, 0x10, 0x01, 0x04, 0x03, 0x18, 0x01, 0x04, 0x03, 0xb0, 0x29, 0x05, 0x04, 0xc0, 0x29, 0x05, 0x04, 0xa0, 0x14, 0x06, 0x04, + 0x50, 0x05, 0x07, 0x04, 0xe0, 0x2e, 0x08, 0x05, 0xc0, 0x19, 0x09, 0x05, 0xc0, 0x09, 0x0a, 0x05, 0x40, 0x22, 0x0c, 0x06, 0x00, 0x14, 0x10, 0x07, 0x80, 0x02, 0x00, 0x03, 0x88, 0x02, 0x00, 0x03, + 0x90, 0x02, 0x00, 0x03, 0x70, 0x3b, 0x01, 0x03, 0x78, 0x3b, 0x01, 0x03, 0x80, 0x3b, 0x01, 0x03, 0x88, 0x3b, 0x01, 0x03, 0xa8, 0x23, 0x02, 0x03, 0xb0, 0x23, 0x02, 0x03, 0xb8, 0x23, 0x02, 0x03, + 0xf0, 0x10, 0x03, 0x03, 0xf8, 0x10, 0x03, 0x03, 0x00, 0x11, 0x03, 0x03, 0x20, 0x01, 0x04, 0x03, 0x28, 0x01, 0x04, 0x03, 0xd0, 0x29, 0x05, 0x04, 0xe0, 0x29, 0x05, 0x04, 0xb0, 0x14, 0x06, 0x04, + 0x60, 0x05, 0x07, 0x04, 0x00, 0x2f, 0x08, 0x05, 0xe0, 0x19, 0x09, 0x05, 0xe0, 0x09, 0x0a, 0x05, 0x80, 0x22, 0x0c, 0x06, 0x80, 0x14, 0x10, 0x07, 0x98, 0x02, 0x00, 0x03, 0xa0, 0x02, 0x00, 0x03, + 0xa8, 0x02, 0x00, 0x03, 0x90, 0x3b, 0x01, 0x03, 0x98, 0x3b, 0x01, 0x03, 0xa0, 0x3b, 0x01, 0x03, 0xa8, 0x3b, 0x01, 0x03, 0xc0, 0x23, 0x02, 0x03, 0xc8, 0x23, 0x02, 0x03, 0xd0, 0x23, 0x02, 0x03, + 0x08, 0x11, 0x03, 0x03, 0x10, 0x11, 0x03, 0x03, 0x18, 0x11, 0x03, 0x03, 0x30, 0x01, 0x04, 0x03, 0x38, 0x01, 0x04, 0x03, 0xf0, 0x29, 0x05, 0x04, 0x00, 0x2a, 0x05, 0x04, 0xc0, 0x14, 0x06, 0x04, + 0x70, 0x05, 0x07, 0x04, 0x20, 0x2f, 0x08, 0x05, 0x00, 0x1a, 0x09, 0x05, 0x00, 0x0a, 0x0a, 0x05, 0xc0, 0x22, 0x0c, 0x06, 0x00, 0x15, 0x10, 0x07, 0xb0, 0x02, 0x00, 0x03, 0xb8, 0x02, 0x00, 0x03, + 0xb0, 0x3b, 0x01, 0x03, 0xb8, 0x3b, 0x01, 0x03, 0xc0, 0x3b, 0x01, 0x03, 0xc8, 0x3b, 0x01, 0x03, 0xd0, 0x3b, 0x01, 0x03, 0xd8, 0x23, 0x02, 0x03, 0xe0, 0x23, 0x02, 0x03, 0xe8, 0x23, 0x02, 0x03, + 0x20, 0x11, 0x03, 0x03, 0x28, 0x11, 0x03, 0x03, 0x30, 0x11, 0x03, 0x03, 0x40, 0x01, 0x04, 0x03, 0x48, 0x01, 0x04, 0x03, 0x10, 0x2a, 0x05, 0x04, 0x20, 0x2a, 0x05, 0x04, 0xd0, 0x14, 0x06, 0x04, + 0x80, 0x05, 0x07, 0x04, 0x40, 0x2f, 0x08, 0x05, 0x20, 0x1a, 0x09, 0x05, 0x20, 0x0a, 0x0a, 0x05, 0x00, 0x23, 0x0c, 0x06, 0x80, 0x15, 0x10, 0x07, 0xc0, 0x02, 0x00, 0x03, 0xc8, 0x02, 0x00, 0x03, + 0xd8, 0x3b, 0x01, 0x03, 0xe0, 0x3b, 0x01, 0x03, 0xe8, 0x3b, 0x01, 0x03, 0xf0, 0x3b, 0x01, 0x03, 0xf8, 0x3b, 0x01, 0x03, 0xf0, 0x23, 0x02, 0x03, 0xf8, 0x23, 0x02, 0x03, 0x00, 0x24, 0x02, 0x03, + 0x38, 0x11, 0x03, 0x03, 0x40, 0x11, 0x03, 0x03, 0x48, 0x11, 0x03, 0x03, 0x50, 0x01, 0x04, 0x03, 0x58, 0x01, 0x04, 0x03, 0x30, 0x2a, 0x05, 0x04, 0x40, 0x2a, 0x05, 0x04, 0xe0, 0x14, 0x06, 0x04, + 0x90, 0x05, 0x07, 0x04, 0x60, 0x2f, 0x08, 0x05, 0x40, 0x1a, 0x09, 0x05, 0x40, 0x0a, 0x0a, 0x05, 0x40, 0x23, 0x0c, 0x06, 0x00, 0x16, 0x10, 0x07, 0xd0, 0x02, 0x00, 0x03, 0xd8, 0x02, 0x00, 0x03, + 0x00, 0x3c, 0x01, 0x03, 0x08, 0x3c, 0x01, 0x03, 0x10, 0x3c, 0x01, 0x03, 0x18, 0x3c, 0x01, 0x03, 0x20, 0x3c, 0x01, 0x03, 0x08, 0x24, 0x02, 0x03, 0x10, 0x24, 0x02, 0x03, 0x18, 0x24, 0x02, 0x03, + 0x50, 0x11, 0x03, 0x03, 0x58, 0x11, 0x03, 0x03, 0x60, 0x11, 0x03, 0x03, 0x60, 0x01, 0x04, 0x03, 0x68, 0x01, 0x04, 0x03, 0x50, 0x2a, 0x05, 0x04, 0x60, 0x2a, 0x05, 0x04, 0xf0, 0x14, 0x06, 0x04, + 0xa0, 0x05, 0x07, 0x04, 0x80, 0x2f, 0x08, 0x05, 0x60, 0x1a, 0x09, 0x05, 0x60, 0x0a, 0x0a, 0x05, 0x80, 0x23, 0x0c, 0x06, 0x80, 0x16, 0x10, 0x07, 0xe0, 0x02, 0x00, 0x03, 0xe8, 0x02, 0x00, 0x03, + 0x28, 0x3c, 0x01, 0x03, 0x30, 0x3c, 0x01, 0x03, 0x38, 0x3c, 0x01, 0x03, 0x40, 0x3c, 0x01, 0x03, 0x48, 0x3c, 0x01, 0x03, 0x20, 0x24, 0x02, 0x03, 0x28, 0x24, 0x02, 0x03, 0x30, 0x24, 0x02, 0x03, + 0x68, 0x11, 0x03, 0x03, 0x70, 0x11, 0x03, 0x03, 0x78, 0x11, 0x03, 0x03, 0x70, 0x01, 0x04, 0x03, 0x78, 0x01, 0x04, 0x03, 0x70, 0x2a, 0x05, 0x04, 0x80, 0x2a, 0x05, 0x04, 0x00, 0x15, 0x06, 0x04, + 0xb0, 0x05, 0x07, 0x04, 0xa0, 0x2f, 0x08, 0x05, 0x80, 0x1a, 0x09, 0x05, 0x80, 0x0a, 0x0a, 0x05, 0xc0, 0x23, 0x0c, 0x06, 0x00, 0x17, 0x10, 0x07, 0xf0, 0x02, 0x00, 0x03, 0xf8, 0x02, 0x00, 0x03, + 0x50, 0x3c, 0x01, 0x03, 0x58, 0x3c, 0x01, 0x03, 0x60, 0x3c, 0x01, 0x03, 0x68, 0x3c, 0x01, 0x03, 0x70, 0x3c, 0x01, 0x03, 0x38, 0x24, 0x02, 0x03, 0x40, 0x24, 0x02, 0x03, 0x48, 0x24, 0x02, 0x03, + 0x80, 0x11, 0x03, 0x03, 0x88, 0x11, 0x03, 0x03, 0x90, 0x11, 0x03, 0x03, 0x80, 0x01, 0x04, 0x03, 0x88, 0x01, 0x04, 0x03, 0x90, 0x2a, 0x05, 0x04, 0xa0, 0x2a, 0x05, 0x04, 0x10, 0x15, 0x06, 0x04, + 0xc0, 0x05, 0x07, 0x04, 0xc0, 0x2f, 0x08, 0x05, 0xa0, 0x1a, 0x09, 0x05, 0xa0, 0x0a, 0x0a, 0x05, 0x00, 0x24, 0x0c, 0x06, 0x00, 0x00, 0x11, 0x07, 0x00, 0x03, 0x00, 0x03, 0x08, 0x03, 0x00, 0x03, + 0x78, 0x3c, 0x01, 0x03, 0x80, 0x3c, 0x01, 0x03, 0x88, 0x3c, 0x01, 0x03, 0x90, 0x3c, 0x01, 0x03, 0x98, 0x3c, 0x01, 0x03, 0x50, 0x24, 0x02, 0x03, 0x58, 0x24, 0x02, 0x03, 0x60, 0x24, 0x02, 0x03, + 0x98, 0x11, 0x03, 0x03, 0xa0, 0x11, 0x03, 0x03, 0xa8, 0x11, 0x03, 0x03, 0x90, 0x01, 0x04, 0x03, 0x98, 0x01, 0x04, 0x03, 0xb0, 0x2a, 0x05, 0x04, 0xc0, 0x2a, 0x05, 0x04, 0x20, 0x15, 0x06, 0x04, + 0xd0, 0x05, 0x07, 0x04, 0xe0, 0x2f, 0x08, 0x05, 0xc0, 0x1a, 0x09, 0x05, 0xc0, 0x0a, 0x0a, 0x05, 0x40, 0x24, 0x0c, 0x06, 0x80, 0x00, 0x11, 0x07, 0x10, 0x03, 0x00, 0x03, 0x18, 0x03, 0x00, 0x03, + 0xa0, 0x3c, 0x01, 0x03, 0xa8, 0x3c, 0x01, 0x03, 0xb0, 0x3c, 0x01, 0x03, 0xb8, 0x3c, 0x01, 0x03, 0xc0, 0x3c, 0x01, 0x03, 0x68, 0x24, 0x02, 0x03, 0x70, 0x24, 0x02, 0x03, 0x78, 0x24, 0x02, 0x03, + 0xb0, 0x11, 0x03, 0x03, 0xb8, 0x11, 0x03, 0x03, 0xc0, 0x11, 0x03, 0x03, 0xa0, 0x01, 0x04, 0x03, 0xa8, 0x01, 0x04, 0x03, 0xd0, 0x2a, 0x05, 0x04, 0xe0, 0x2a, 0x05, 0x04, 0x30, 0x15, 0x06, 0x04, + 0xe0, 0x05, 0x07, 0x04, 0x00, 0x30, 0x08, 0x05, 0xe0, 0x1a, 0x09, 0x05, 0xe0, 0x0a, 0x0a, 0x05, 0x40, 0x0b, 0x0d, 0x06, 0x00, 0x01, 0x11, 0x07, 0x20, 0x03, 0x00, 0x03, 0x28, 0x03, 0x00, 0x03, + 0xc8, 0x3c, 0x01, 0x03, 0xd0, 0x3c, 0x01, 0x03, 0xd8, 0x3c, 0x01, 0x03, 0xe0, 0x3c, 0x01, 0x03, 0xe8, 0x3c, 0x01, 0x03, 0x80, 0x24, 0x02, 0x03, 0x88, 0x24, 0x02, 0x03, 0x90, 0x24, 0x02, 0x03, + 0xc8, 0x11, 0x03, 0x03, 0xd0, 0x11, 0x03, 0x03, 0xd8, 0x11, 0x03, 0x03, 0xb0, 0x01, 0x04, 0x03, 0xb8, 0x01, 0x04, 0x03, 0xf0, 0x2a, 0x05, 0x04, 0x00, 0x2b, 0x05, 0x04, 0x40, 0x15, 0x06, 0x04, + 0xf0, 0x05, 0x07, 0x04, 0x20, 0x30, 0x08, 0x05, 0x00, 0x1b, 0x09, 0x05, 0x00, 0x0b, 0x0a, 0x05, 0x80, 0x0b, 0x0d, 0x06, 0x80, 0x01, 0x11, 0x07, 0x30, 0x03, 0x00, 0x03, 0x38, 0x03, 0x00, 0x03, + 0xf0, 0x3c, 0x01, 0x03, 0xf8, 0x3c, 0x01, 0x03, 0x00, 0x3d, 0x01, 0x03, 0x08, 0x3d, 0x01, 0x03, 0x10, 0x3d, 0x01, 0x03, 0x98, 0x24, 0x02, 0x03, 0xa0, 0x24, 0x02, 0x03, 0xa8, 0x24, 0x02, 0x03, + 0xe0, 0x11, 0x03, 0x03, 0xe8, 0x11, 0x03, 0x03, 0xf0, 0x11, 0x03, 0x03, 0xc0, 0x01, 0x04, 0x03, 0xc8, 0x01, 0x04, 0x03, 0x10, 0x2b, 0x05, 0x04, 0x20, 0x2b, 0x05, 0x04, 0x50, 0x15, 0x06, 0x04, + 0x00, 0x06, 0x07, 0x04, 0x40, 0x30, 0x08, 0x05, 0x20, 0x1b, 0x09, 0x05, 0x20, 0x0b, 0x0a, 0x05, 0xc0, 0x0b, 0x0d, 0x06, 0x00, 0x02, 0x11, 0x07, 0x40, 0x03, 0x00, 0x03, 0x48, 0x03, 0x00, 0x03, + 0x18, 0x3d, 0x01, 0x03, 0x20, 0x3d, 0x01, 0x03, 0x28, 0x3d, 0x01, 0x03, 0x30, 0x3d, 0x01, 0x03, 0x38, 0x3d, 0x01, 0x03, 0xb0, 0x24, 0x02, 0x03, 0xb8, 0x24, 0x02, 0x03, 0xc0, 0x24, 0x02, 0x03, + 0xf8, 0x11, 0x03, 0x03, 0x00, 0x12, 0x03, 0x03, 0x08, 0x12, 0x03, 0x03, 0xd0, 0x01, 0x04, 0x03, 0xd8, 0x01, 0x04, 0x03, 0x30, 0x2b, 0x05, 0x04, 0x40, 0x2b, 0x05, 0x04, 0x60, 0x15, 0x06, 0x04, + 0x10, 0x06, 0x07, 0x04, 0x60, 0x30, 0x08, 0x05, 0x40, 0x1b, 0x09, 0x05, 0x40, 0x0b, 0x0a, 0x05, 0x00, 0x0c, 0x0d, 0x06, 0x80, 0x02, 0x11, 0x07, 0x50, 0x03, 0x00, 0x03, 0x58, 0x03, 0x00, 0x03, + 0x40, 0x3d, 0x01, 0x03, 0x48, 0x3d, 0x01, 0x03, 0x50, 0x3d, 0x01, 0x03, 0x58, 0x3d, 0x01, 0x03, 0x60, 0x3d, 0x01, 0x03, 0xc8, 0x24, 0x02, 0x03, 0xd0, 0x24, 0x02, 0x03, 0xd8, 0x24, 0x02, 0x03, + 0x10, 0x12, 0x03, 0x03, 0x18, 0x12, 0x03, 0x03, 0x20, 0x12, 0x03, 0x03, 0xe0, 0x01, 0x04, 0x03, 0xe8, 0x01, 0x04, 0x03, 0x50, 0x2b, 0x05, 0x04, 0x60, 0x2b, 0x05, 0x04, 0x70, 0x15, 0x06, 0x04, + 0x20, 0x06, 0x07, 0x04, 0x80, 0x30, 0x08, 0x05, 0x60, 0x1b, 0x09, 0x05, 0x60, 0x0b, 0x0a, 0x05, 0x40, 0x0c, 0x0d, 0x06, 0x00, 0x03, 0x11, 0x07, 0x60, 0x03, 0x00, 0x03, 0x68, 0x03, 0x00, 0x03, + 0x68, 0x3d, 0x01, 0x03, 0x70, 0x3d, 0x01, 0x03, 0x78, 0x3d, 0x01, 0x03, 0x80, 0x3d, 0x01, 0x03, 0x88, 0x3d, 0x01, 0x03, 0xe0, 0x24, 0x02, 0x03, 0xe8, 0x24, 0x02, 0x03, 0xf0, 0x24, 0x02, 0x03, + 0x28, 0x12, 0x03, 0x03, 0x30, 0x12, 0x03, 0x03, 0x38, 0x12, 0x03, 0x03, 0xf0, 0x01, 0x04, 0x03, 0xf8, 0x01, 0x04, 0x03, 0x70, 0x2b, 0x05, 0x04, 0x80, 0x2b, 0x05, 0x04, 0x80, 0x15, 0x06, 0x04, + 0x30, 0x06, 0x07, 0x04, 0xa0, 0x30, 0x08, 0x05, 0x80, 0x1b, 0x09, 0x05, 0x80, 0x0b, 0x0a, 0x05, 0x80, 0x0c, 0x0d, 0x06, 0x80, 0x03, 0x11, 0x07, 0x70, 0x03, 0x00, 0x03, 0x78, 0x03, 0x00, 0x03, + 0x90, 0x3d, 0x01, 0x03, 0x98, 0x3d, 0x01, 0x03, 0xa0, 0x3d, 0x01, 0x03, 0xa8, 0x3d, 0x01, 0x03, 0xb0, 0x3d, 0x01, 0x03, 0xf8, 0x24, 0x02, 0x03, 0x00, 0x25, 0x02, 0x03, 0x08, 0x25, 0x02, 0x03, + 0x40, 0x12, 0x03, 0x03, 0x48, 0x12, 0x03, 0x03, 0x50, 0x12, 0x03, 0x03, 0x00, 0x02, 0x04, 0x03, 0x08, 0x02, 0x04, 0x03, 0x90, 0x2b, 0x05, 0x04, 0xa0, 0x2b, 0x05, 0x04, 0x90, 0x15, 0x06, 0x04, + 0x40, 0x06, 0x07, 0x04, 0xc0, 0x30, 0x08, 0x05, 0xa0, 0x1b, 0x09, 0x05, 0xa0, 0x0b, 0x0a, 0x05, 0xc0, 0x0c, 0x0d, 0x06, 0x00, 0x04, 0x11, 0x07, 0x80, 0x03, 0x00, 0x03, 0x88, 0x03, 0x00, 0x03, + 0xb8, 0x3d, 0x01, 0x03, 0xc0, 0x3d, 0x01, 0x03, 0xc8, 0x3d, 0x01, 0x03, 0xd0, 0x3d, 0x01, 0x03, 0xd8, 0x3d, 0x01, 0x03, 0x10, 0x25, 0x02, 0x03, 0x18, 0x25, 0x02, 0x03, 0x20, 0x25, 0x02, 0x03, + 0x58, 0x12, 0x03, 0x03, 0x60, 0x12, 0x03, 0x03, 0x68, 0x12, 0x03, 0x03, 0x10, 0x02, 0x04, 0x03, 0x18, 0x02, 0x04, 0x03, 0xb0, 0x2b, 0x05, 0x04, 0xc0, 0x2b, 0x05, 0x04, 0xa0, 0x15, 0x06, 0x04, + 0x50, 0x06, 0x07, 0x04, 0xe0, 0x30, 0x08, 0x05, 0xc0, 0x1b, 0x09, 0x05, 0xc0, 0x0b, 0x0a, 0x05, 0x00, 0x0d, 0x0d, 0x06, 0x80, 0x04, 0x11, 0x07, 0x90, 0x03, 0x00, 0x03, 0x98, 0x03, 0x00, 0x03, + 0xe0, 0x3d, 0x01, 0x03, 0xe8, 0x3d, 0x01, 0x03, 0xf0, 0x3d, 0x01, 0x03, 0xf8, 0x3d, 0x01, 0x03, 0x28, 0x25, 0x02, 0x03, 0x30, 0x25, 0x02, 0x03, 0x38, 0x25, 0x02, 0x03, 0x40, 0x25, 0x02, 0x03, + 0x70, 0x12, 0x03, 0x03, 0x78, 0x12, 0x03, 0x03, 0x80, 0x12, 0x03, 0x03, 0x20, 0x02, 0x04, 0x03, 0x28, 0x02, 0x04, 0x03, 0xd0, 0x2b, 0x05, 0x04, 0xe0, 0x2b, 0x05, 0x04, 0xb0, 0x15, 0x06, 0x04, + 0x60, 0x06, 0x07, 0x04, 0x00, 0x31, 0x08, 0x05, 0xe0, 0x1b, 0x09, 0x05, 0x40, 0x33, 0x0b, 0x06, 0x40, 0x0d, 0x0d, 0x06, 0x00, 0x05, 0x11, 0x07, 0xa0, 0x03, 0x00, 0x03, 0xa8, 0x03, 0x00, 0x03, + 0x00, 0x3e, 0x01, 0x03, 0x08, 0x3e, 0x01, 0x03, 0x10, 0x3e, 0x01, 0x03, 0x18, 0x3e, 0x01, 0x03, 0x48, 0x25, 0x02, 0x03, 0x50, 0x25, 0x02, 0x03, 0x58, 0x25, 0x02, 0x03, 0x60, 0x25, 0x02, 0x03, + 0x88, 0x12, 0x03, 0x03, 0x90, 0x12, 0x03, 0x03, 0x98, 0x12, 0x03, 0x03, 0x30, 0x02, 0x04, 0x03, 0x38, 0x02, 0x04, 0x03, 0xf0, 0x2b, 0x05, 0x04, 0x00, 0x2c, 0x05, 0x04, 0xc0, 0x15, 0x06, 0x04, + 0x70, 0x06, 0x07, 0x04, 0x20, 0x31, 0x08, 0x05, 0x00, 0x1c, 0x09, 0x05, 0x80, 0x33, 0x0b, 0x06, 0x80, 0x0d, 0x0d, 0x06, 0x00, 0x28, 0x12, 0x08, 0xb0, 0x03, 0x00, 0x03, 0xb8, 0x03, 0x00, 0x03, + 0x20, 0x3e, 0x01, 0x03, 0x28, 0x3e, 0x01, 0x03, 0x30, 0x3e, 0x01, 0x03, 0x38, 0x3e, 0x01, 0x03, 0x68, 0x25, 0x02, 0x03, 0x70, 0x25, 0x02, 0x03, 0x78, 0x25, 0x02, 0x03, 0x80, 0x25, 0x02, 0x03, + 0xa0, 0x12, 0x03, 0x03, 0xa8, 0x12, 0x03, 0x03, 0xb0, 0x12, 0x03, 0x03, 0x40, 0x02, 0x04, 0x03, 0x48, 0x02, 0x04, 0x03, 0x10, 0x2c, 0x05, 0x04, 0x20, 0x2c, 0x05, 0x04, 0xd0, 0x15, 0x06, 0x04, + 0x80, 0x06, 0x07, 0x04, 0x40, 0x31, 0x08, 0x05, 0x20, 0x1c, 0x09, 0x05, 0xc0, 0x33, 0x0b, 0x06, 0xc0, 0x0d, 0x0d, 0x06, 0x00, 0x29, 0x12, 0x08, 0xc0, 0x03, 0x00, 0x03, 0xc8, 0x03, 0x00, 0x03, + 0x40, 0x3e, 0x01, 0x03, 0x48, 0x3e, 0x01, 0x03, 0x50, 0x3e, 0x01, 0x03, 0x58, 0x3e, 0x01, 0x03, 0x88, 0x25, 0x02, 0x03, 0x90, 0x25, 0x02, 0x03, 0x98, 0x25, 0x02, 0x03, 0xa0, 0x25, 0x02, 0x03, + 0xb8, 0x12, 0x03, 0x03, 0xc0, 0x12, 0x03, 0x03, 0xc8, 0x12, 0x03, 0x03, 0x50, 0x02, 0x04, 0x03, 0x58, 0x02, 0x04, 0x03, 0x30, 0x2c, 0x05, 0x04, 0x40, 0x2c, 0x05, 0x04, 0xe0, 0x15, 0x06, 0x04, + 0x90, 0x06, 0x07, 0x04, 0x60, 0x31, 0x08, 0x05, 0x40, 0x1c, 0x09, 0x05, 0x00, 0x34, 0x0b, 0x06, 0x00, 0x0e, 0x0d, 0x06, 0x00, 0x2a, 0x12, 0x08, 0xd0, 0x03, 0x00, 0x03, 0xd8, 0x03, 0x00, 0x03, + 0x60, 0x3e, 0x01, 0x03, 0x68, 0x3e, 0x01, 0x03, 0x70, 0x3e, 0x01, 0x03, 0x78, 0x3e, 0x01, 0x03, 0xa8, 0x25, 0x02, 0x03, 0xb0, 0x25, 0x02, 0x03, 0xb8, 0x25, 0x02, 0x03, 0xc0, 0x25, 0x02, 0x03, + 0xd0, 0x12, 0x03, 0x03, 0xd8, 0x12, 0x03, 0x03, 0xe0, 0x12, 0x03, 0x03, 0x60, 0x02, 0x04, 0x03, 0x68, 0x02, 0x04, 0x03, 0x50, 0x2c, 0x05, 0x04, 0x60, 0x2c, 0x05, 0x04, 0xf0, 0x15, 0x06, 0x04, + 0xa0, 0x06, 0x07, 0x04, 0x80, 0x31, 0x08, 0x05, 0x60, 0x1c, 0x09, 0x05, 0x40, 0x34, 0x0b, 0x06, 0x40, 0x0e, 0x0d, 0x06, 0x00, 0x2b, 0x12, 0x08, 0xe0, 0x03, 0x00, 0x03, 0xe8, 0x03, 0x00, 0x03, + 0x80, 0x3e, 0x01, 0x03, 0x88, 0x3e, 0x01, 0x03, 0x90, 0x3e, 0x01, 0x03, 0x98, 0x3e, 0x01, 0x03, 0xc8, 0x25, 0x02, 0x03, 0xd0, 0x25, 0x02, 0x03, 0xd8, 0x25, 0x02, 0x03, 0xe0, 0x25, 0x02, 0x03, + 0xe8, 0x12, 0x03, 0x03, 0xf0, 0x12, 0x03, 0x03, 0xf8, 0x12, 0x03, 0x03, 0x70, 0x02, 0x04, 0x03, 0x78, 0x02, 0x04, 0x03, 0x70, 0x2c, 0x05, 0x04, 0x80, 0x2c, 0x05, 0x04, 0x00, 0x16, 0x06, 0x04, + 0xb0, 0x06, 0x07, 0x04, 0xa0, 0x31, 0x08, 0x05, 0x80, 0x1c, 0x09, 0x05, 0x80, 0x34, 0x0b, 0x06, 0x80, 0x0e, 0x0d, 0x06, 0x00, 0x2c, 0x12, 0x08, 0xf0, 0x03, 0x00, 0x03, 0xf8, 0x03, 0x00, 0x03, + 0xa0, 0x3e, 0x01, 0x03, 0xa8, 0x3e, 0x01, 0x03, 0xb0, 0x3e, 0x01, 0x03, 0xb8, 0x3e, 0x01, 0x03, 0xe8, 0x25, 0x02, 0x03, 0xf0, 0x25, 0x02, 0x03, 0xf8, 0x25, 0x02, 0x03, 0x00, 0x26, 0x02, 0x03, + 0x00, 0x13, 0x03, 0x03, 0x08, 0x13, 0x03, 0x03, 0x10, 0x13, 0x03, 0x03, 0x80, 0x02, 0x04, 0x03, 0x88, 0x02, 0x04, 0x03, 0x90, 0x2c, 0x05, 0x04, 0xa0, 0x2c, 0x05, 0x04, 0x10, 0x16, 0x06, 0x04, + 0xc0, 0x06, 0x07, 0x04, 0xc0, 0x31, 0x08, 0x05, 0xa0, 0x1c, 0x09, 0x05, 0xc0, 0x34, 0x0b, 0x06, 0xc0, 0x0e, 0x0d, 0x06, 0x00, 0x2d, 0x12, 0x08, 0x00, 0x04, 0x00, 0x03, 0x08, 0x04, 0x00, 0x03, + 0xc0, 0x3e, 0x01, 0x03, 0xc8, 0x3e, 0x01, 0x03, 0xd0, 0x3e, 0x01, 0x03, 0xd8, 0x3e, 0x01, 0x03, 0x08, 0x26, 0x02, 0x03, 0x10, 0x26, 0x02, 0x03, 0x18, 0x26, 0x02, 0x03, 0x20, 0x26, 0x02, 0x03, + 0x18, 0x13, 0x03, 0x03, 0x20, 0x13, 0x03, 0x03, 0x28, 0x13, 0x03, 0x03, 0x90, 0x02, 0x04, 0x03, 0x98, 0x02, 0x04, 0x03, 0xb0, 0x2c, 0x05, 0x04, 0x20, 0x16, 0x06, 0x04, 0x30, 0x16, 0x06, 0x04, + 0xd0, 0x06, 0x07, 0x04, 0xe0, 0x31, 0x08, 0x05, 0xc0, 0x1c, 0x09, 0x05, 0x00, 0x35, 0x0b, 0x06, 0x00, 0x0f, 0x0d, 0x06, 0x00, 0x2e, 0x12, 0x08, 0x10, 0x04, 0x00, 0x03, 0x18, 0x04, 0x00, 0x03, + 0xe0, 0x3e, 0x01, 0x03, 0xe8, 0x3e, 0x01, 0x03, 0xf0, 0x3e, 0x01, 0x03, 0xf8, 0x3e, 0x01, 0x03, 0x28, 0x26, 0x02, 0x03, 0x30, 0x26, 0x02, 0x03, 0x38, 0x26, 0x02, 0x03, 0x40, 0x26, 0x02, 0x03, + 0x30, 0x13, 0x03, 0x03, 0x38, 0x13, 0x03, 0x03, 0x40, 0x13, 0x03, 0x03, 0xa0, 0x02, 0x04, 0x03, 0xa8, 0x02, 0x04, 0x03, 0xc0, 0x2c, 0x05, 0x04, 0x40, 0x16, 0x06, 0x04, 0x50, 0x16, 0x06, 0x04, + 0xe0, 0x06, 0x07, 0x04, 0x00, 0x32, 0x08, 0x05, 0xe0, 0x1c, 0x09, 0x05, 0x40, 0x35, 0x0b, 0x06, 0x40, 0x0f, 0x0d, 0x06, 0x00, 0x2f, 0x12, 0x08, 0x20, 0x04, 0x00, 0x03, 0x28, 0x04, 0x00, 0x03, + 0x00, 0x3f, 0x01, 0x03, 0x08, 0x3f, 0x01, 0x03, 0x10, 0x3f, 0x01, 0x03, 0x18, 0x3f, 0x01, 0x03, 0x48, 0x26, 0x02, 0x03, 0x50, 0x26, 0x02, 0x03, 0x58, 0x26, 0x02, 0x03, 0x60, 0x26, 0x02, 0x03, + 0x48, 0x13, 0x03, 0x03, 0x50, 0x13, 0x03, 0x03, 0xb0, 0x02, 0x04, 0x03, 0xb8, 0x02, 0x04, 0x03, 0xc0, 0x02, 0x04, 0x03, 0xd0, 0x2c, 0x05, 0x04, 0x60, 0x16, 0x06, 0x04, 0x70, 0x16, 0x06, 0x04, + 0xf0, 0x06, 0x07, 0x04, 0x20, 0x32, 0x08, 0x05, 0x00, 0x1d, 0x09, 0x05, 0x80, 0x35, 0x0b, 0x06, 0x80, 0x0f, 0x0d, 0x06, 0x00, 0x30, 0x12, 0x08, 0x30, 0x04, 0x00, 0x03, 0x38, 0x04, 0x00, 0x03, + 0x20, 0x3f, 0x01, 0x03, 0x28, 0x3f, 0x01, 0x03, 0x30, 0x3f, 0x01, 0x03, 0x38, 0x3f, 0x01, 0x03, 0x68, 0x26, 0x02, 0x03, 0x70, 0x26, 0x02, 0x03, 0x78, 0x26, 0x02, 0x03, 0x80, 0x26, 0x02, 0x03, + 0x58, 0x13, 0x03, 0x03, 0x60, 0x13, 0x03, 0x03, 0xc8, 0x02, 0x04, 0x03, 0xd0, 0x02, 0x04, 0x03, 0xd8, 0x02, 0x04, 0x03, 0xe0, 0x2c, 0x05, 0x04, 0x80, 0x16, 0x06, 0x04, 0x90, 0x16, 0x06, 0x04, + 0x00, 0x07, 0x07, 0x04, 0x40, 0x32, 0x08, 0x05, 0x20, 0x1d, 0x09, 0x05, 0xc0, 0x35, 0x0b, 0x06, 0xc0, 0x0f, 0x0d, 0x06, 0x00, 0x31, 0x12, 0x08, 0x40, 0x04, 0x00, 0x03, 0x48, 0x04, 0x00, 0x03, + 0x40, 0x3f, 0x01, 0x03, 0x48, 0x3f, 0x01, 0x03, 0x50, 0x3f, 0x01, 0x03, 0x58, 0x3f, 0x01, 0x03, 0x88, 0x26, 0x02, 0x03, 0x90, 0x26, 0x02, 0x03, 0x98, 0x26, 0x02, 0x03, 0xa0, 0x26, 0x02, 0x03, + 0x68, 0x13, 0x03, 0x03, 0x70, 0x13, 0x03, 0x03, 0xe0, 0x02, 0x04, 0x03, 0xe8, 0x02, 0x04, 0x03, 0xf0, 0x02, 0x04, 0x03, 0xf0, 0x2c, 0x05, 0x04, 0xa0, 0x16, 0x06, 0x04, 0xb0, 0x16, 0x06, 0x04, + 0x10, 0x07, 0x07, 0x04, 0x60, 0x32, 0x08, 0x05, 0x40, 0x1d, 0x09, 0x05, 0x00, 0x36, 0x0b, 0x06, 0x00, 0x10, 0x0d, 0x06, 0x00, 0x14, 0x13, 0x08, 0x50, 0x04, 0x00, 0x03, 0x58, 0x04, 0x00, 0x03, + 0x60, 0x3f, 0x01, 0x03, 0x68, 0x3f, 0x01, 0x03, 0x70, 0x3f, 0x01, 0x03, 0x78, 0x3f, 0x01, 0x03, 0xa8, 0x26, 0x02, 0x03, 0xb0, 0x26, 0x02, 0x03, 0xb8, 0x26, 0x02, 0x03, 0xc0, 0x26, 0x02, 0x03, + 0x78, 0x13, 0x03, 0x03, 0x80, 0x13, 0x03, 0x03, 0xf8, 0x02, 0x04, 0x03, 0x00, 0x03, 0x04, 0x03, 0x08, 0x03, 0x04, 0x03, 0x00, 0x2d, 0x05, 0x04, 0xc0, 0x16, 0x06, 0x04, 0xd0, 0x16, 0x06, 0x04, + 0x20, 0x07, 0x07, 0x04, 0x80, 0x32, 0x08, 0x05, 0x60, 0x1d, 0x09, 0x05, 0x40, 0x36, 0x0b, 0x06, 0x40, 0x10, 0x0d, 0x06, 0x00, 0x15, 0x13, 0x08, 0x60, 0x04, 0x00, 0x03, 0x68, 0x04, 0x00, 0x03, + 0x80, 0x3f, 0x01, 0x03, 0x88, 0x3f, 0x01, 0x03, 0x90, 0x3f, 0x01, 0x03, 0x98, 0x3f, 0x01, 0x03, 0xc8, 0x26, 0x02, 0x03, 0xd0, 0x26, 0x02, 0x03, 0xd8, 0x26, 0x02, 0x03, 0xe0, 0x26, 0x02, 0x03, + 0x88, 0x13, 0x03, 0x03, 0x90, 0x13, 0x03, 0x03, 0x10, 0x03, 0x04, 0x03, 0x18, 0x03, 0x04, 0x03, 0x20, 0x03, 0x04, 0x03, 0x10, 0x2d, 0x05, 0x04, 0xe0, 0x16, 0x06, 0x04, 0xf0, 0x16, 0x06, 0x04, + 0x30, 0x07, 0x07, 0x04, 0xa0, 0x32, 0x08, 0x05, 0x80, 0x1d, 0x09, 0x05, 0x80, 0x36, 0x0b, 0x06, 0x80, 0x10, 0x0d, 0x06, 0x00, 0x16, 0x13, 0x08, 0x70, 0x04, 0x00, 0x03, 0x78, 0x04, 0x00, 0x03, + 0xa0, 0x3f, 0x01, 0x03, 0xa8, 0x3f, 0x01, 0x03, 0xb0, 0x3f, 0x01, 0x03, 0xb8, 0x3f, 0x01, 0x03, 0xe8, 0x26, 0x02, 0x03, 0xf0, 0x26, 0x02, 0x03, 0xf8, 0x26, 0x02, 0x03, 0x00, 0x27, 0x02, 0x03, + 0x98, 0x13, 0x03, 0x03, 0xa0, 0x13, 0x03, 0x03, 0x28, 0x03, 0x04, 0x03, 0x30, 0x03, 0x04, 0x03, 0x38, 0x03, 0x04, 0x03, 0x20, 0x2d, 0x05, 0x04, 0x00, 0x17, 0x06, 0x04, 0x10, 0x17, 0x06, 0x04, + 0x40, 0x07, 0x07, 0x04, 0xc0, 0x32, 0x08, 0x05, 0xa0, 0x1d, 0x09, 0x05, 0xc0, 0x36, 0x0b, 0x06, 0xc0, 0x10, 0x0d, 0x06, 0x00, 0x17, 0x13, 0x08, 0x80, 0x04, 0x00, 0x03, 0x88, 0x04, 0x00, 0x03, + 0xc0, 0x3f, 0x01, 0x03, 0xc8, 0x3f, 0x01, 0x03, 0xd0, 0x3f, 0x01, 0x03, 0xd8, 0x3f, 0x01, 0x03, 0x08, 0x27, 0x02, 0x03, 0x10, 0x27, 0x02, 0x03, 0x18, 0x27, 0x02, 0x03, 0x20, 0x27, 0x02, 0x03, + 0xa8, 0x13, 0x03, 0x03, 0xb0, 0x13, 0x03, 0x03, 0x40, 0x03, 0x04, 0x03, 0x48, 0x03, 0x04, 0x03, 0x50, 0x03, 0x04, 0x03, 0x30, 0x2d, 0x05, 0x04, 0x20, 0x17, 0x06, 0x04, 0x30, 0x17, 0x06, 0x04, + 0x50, 0x07, 0x07, 0x04, 0xe0, 0x32, 0x08, 0x05, 0xc0, 0x1d, 0x09, 0x05, 0x00, 0x37, 0x0b, 0x06, 0x00, 0x11, 0x0d, 0x06, 0x00, 0x18, 0x13, 0x08, 0x90, 0x04, 0x00, 0x03, 0x98, 0x04, 0x00, 0x03, + 0xe0, 0x3f, 0x01, 0x03, 0xe8, 0x3f, 0x01, 0x03, 0xf0, 0x3f, 0x01, 0x03, 0xf8, 0x3f, 0x01, 0x03, 0x28, 0x27, 0x02, 0x03, 0x30, 0x27, 0x02, 0x03, 0x38, 0x27, 0x02, 0x03, 0x40, 0x27, 0x02, 0x03, + 0xb8, 0x13, 0x03, 0x03, 0xc0, 0x13, 0x03, 0x03, 0x58, 0x03, 0x04, 0x03, 0x60, 0x03, 0x04, 0x03, 0x68, 0x03, 0x04, 0x03, 0x40, 0x2d, 0x05, 0x04, 0x40, 0x17, 0x06, 0x04, 0x50, 0x17, 0x06, 0x04, + 0x60, 0x07, 0x07, 0x04, 0x00, 0x33, 0x08, 0x05, 0xe0, 0x1d, 0x09, 0x05, 0x40, 0x37, 0x0b, 0x06, 0x40, 0x11, 0x0d, 0x06, 0x00, 0x19, 0x13, 0x08, 0xa0, 0x04, 0x00, 0x03, 0xa8, 0x04, 0x00, 0x03, + 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x01, 0x02, 0x08, 0x00, 0x01, 0x02, 0x0c, 0x00, 0x01, 0x02, 0x48, 0x27, 0x02, 0x03, 0x50, 0x27, 0x02, 0x03, 0x58, 0x27, 0x02, 0x03, 0x60, 0x27, 0x02, 0x03, + 0xc8, 0x13, 0x03, 0x03, 0xd0, 0x13, 0x03, 0x03, 0x70, 0x03, 0x04, 0x03, 0x78, 0x03, 0x04, 0x03, 0x80, 0x03, 0x04, 0x03, 0x50, 0x2d, 0x05, 0x04, 0x60, 0x17, 0x06, 0x04, 0x70, 0x17, 0x06, 0x04, + 0x70, 0x07, 0x07, 0x04, 0x20, 0x33, 0x08, 0x05, 0x00, 0x1e, 0x09, 0x05, 0x80, 0x37, 0x0b, 0x06, 0x80, 0x11, 0x0d, 0x06, 0x00, 0x1a, 0x13, 0x08, 0xb0, 0x04, 0x00, 0x03, 0xb8, 0x04, 0x00, 0x03, + 0x10, 0x00, 0x01, 0x02, 0x14, 0x00, 0x01, 0x02, 0x18, 0x00, 0x01, 0x02, 0x1c, 0x00, 0x01, 0x02, 0x68, 0x27, 0x02, 0x03, 0x70, 0x27, 0x02, 0x03, 0x78, 0x27, 0x02, 0x03, 0x80, 0x27, 0x02, 0x03, + 0xd8, 0x13, 0x03, 0x03, 0xe0, 0x13, 0x03, 0x03, 0x88, 0x03, 0x04, 0x03, 0x90, 0x03, 0x04, 0x03, 0x98, 0x03, 0x04, 0x03, 0x60, 0x2d, 0x05, 0x04, 0x80, 0x17, 0x06, 0x04, 0x90, 0x17, 0x06, 0x04, + 0x80, 0x07, 0x07, 0x04, 0x40, 0x33, 0x08, 0x05, 0x20, 0x1e, 0x09, 0x05, 0xc0, 0x37, 0x0b, 0x06, 0xc0, 0x11, 0x0d, 0x06, 0x00, 0x03, 0x14, 0x08, 0xc0, 0x04, 0x00, 0x03, 0xc8, 0x04, 0x00, 0x03, + 0x20, 0x00, 0x01, 0x02, 0x24, 0x00, 0x01, 0x02, 0x28, 0x00, 0x01, 0x02, 0x2c, 0x00, 0x01, 0x02, 0x88, 0x27, 0x02, 0x03, 0x90, 0x27, 0x02, 0x03, 0x98, 0x27, 0x02, 0x03, 0xa0, 0x27, 0x02, 0x03, + 0xe8, 0x13, 0x03, 0x03, 0xf0, 0x13, 0x03, 0x03, 0xa0, 0x03, 0x04, 0x03, 0xa8, 0x03, 0x04, 0x03, 0xb0, 0x03, 0x04, 0x03, 0x70, 0x2d, 0x05, 0x04, 0xa0, 0x17, 0x06, 0x04, 0xb0, 0x17, 0x06, 0x04, + 0x90, 0x07, 0x07, 0x04, 0x60, 0x33, 0x08, 0x05, 0x40, 0x1e, 0x09, 0x05, 0x00, 0x38, 0x0b, 0x06, 0x80, 0x39, 0x0e, 0x07, 0x00, 0x04, 0x14, 0x08, 0xd0, 0x04, 0x00, 0x03, 0xd8, 0x04, 0x00, 0x03, + 0x30, 0x00, 0x01, 0x02, 0x34, 0x00, 0x01, 0x02, 0x38, 0x00, 0x01, 0x02, 0x3c, 0x00, 0x01, 0x02, 0xa8, 0x27, 0x02, 0x03, 0xb0, 0x27, 0x02, 0x03, 0xb8, 0x27, 0x02, 0x03, 0xc0, 0x27, 0x02, 0x03, + 0xf8, 0x13, 0x03, 0x03, 0x00, 0x14, 0x03, 0x03, 0xb8, 0x03, 0x04, 0x03, 0xc0, 0x03, 0x04, 0x03, 0xc8, 0x03, 0x04, 0x03, 0x80, 0x2d, 0x05, 0x04, 0xc0, 0x17, 0x06, 0x04, 0xd0, 0x17, 0x06, 0x04, + 0xa0, 0x07, 0x07, 0x04, 0x80, 0x33, 0x08, 0x05, 0x60, 0x1e, 0x09, 0x05, 0x40, 0x38, 0x0b, 0x06, 0x00, 0x3a, 0x0e, 0x07, 0x00, 0x05, 0x14, 0x08, 0xe0, 0x04, 0x00, 0x03, 0xe8, 0x04, 0x00, 0x03, + 0x40, 0x00, 0x01, 0x02, 0x44, 0x00, 0x01, 0x02, 0x48, 0x00, 0x01, 0x02, 0x4c, 0x00, 0x01, 0x02, 0xc8, 0x27, 0x02, 0x03, 0xd0, 0x27, 0x02, 0x03, 0xd8, 0x27, 0x02, 0x03, 0xe0, 0x27, 0x02, 0x03, + 0x08, 0x14, 0x03, 0x03, 0x10, 0x14, 0x03, 0x03, 0xd0, 0x03, 0x04, 0x03, 0xd8, 0x03, 0x04, 0x03, 0xe0, 0x03, 0x04, 0x03, 0x90, 0x2d, 0x05, 0x04, 0xe0, 0x17, 0x06, 0x04, 0xf0, 0x17, 0x06, 0x04, + 0xb0, 0x07, 0x07, 0x04, 0xa0, 0x33, 0x08, 0x05, 0x80, 0x1e, 0x09, 0x05, 0x80, 0x38, 0x0b, 0x06, 0x80, 0x3a, 0x0e, 0x07, 0x00, 0x06, 0x14, 0x08, 0xf0, 0x04, 0x00, 0x03, 0xf8, 0x04, 0x00, 0x03, + 0x50, 0x00, 0x01, 0x02, 0x54, 0x00, 0x01, 0x02, 0x58, 0x00, 0x01, 0x02, 0x5c, 0x00, 0x01, 0x02, 0xe8, 0x27, 0x02, 0x03, 0xf0, 0x27, 0x02, 0x03, 0xf8, 0x27, 0x02, 0x03, 0x00, 0x28, 0x02, 0x03, + 0x18, 0x14, 0x03, 0x03, 0x20, 0x14, 0x03, 0x03, 0xe8, 0x03, 0x04, 0x03, 0xf0, 0x03, 0x04, 0x03, 0xf8, 0x03, 0x04, 0x03, 0xa0, 0x2d, 0x05, 0x04, 0x00, 0x18, 0x06, 0x04, 0x10, 0x18, 0x06, 0x04, + 0xc0, 0x07, 0x07, 0x04, 0xc0, 0x33, 0x08, 0x05, 0xa0, 0x1e, 0x09, 0x05, 0xc0, 0x38, 0x0b, 0x06, 0x00, 0x3b, 0x0e, 0x07, 0x00, 0x07, 0x14, 0x08, 0x00, 0x05, 0x00, 0x03, 0x08, 0x05, 0x00, 0x03, + 0x60, 0x00, 0x01, 0x02, 0x64, 0x00, 0x01, 0x02, 0x68, 0x00, 0x01, 0x02, 0x6c, 0x00, 0x01, 0x02, 0x08, 0x28, 0x02, 0x03, 0x10, 0x28, 0x02, 0x03, 0x18, 0x28, 0x02, 0x03, 0x20, 0x28, 0x02, 0x03, + 0x28, 0x14, 0x03, 0x03, 0x30, 0x14, 0x03, 0x03, 0x00, 0x04, 0x04, 0x03, 0x08, 0x04, 0x04, 0x03, 0x10, 0x04, 0x04, 0x03, 0xb0, 0x2d, 0x05, 0x04, 0x20, 0x18, 0x06, 0x04, 0x30, 0x18, 0x06, 0x04, + 0xd0, 0x07, 0x07, 0x04, 0xe0, 0x33, 0x08, 0x05, 0xc0, 0x1e, 0x09, 0x05, 0x00, 0x39, 0x0b, 0x06, 0x80, 0x3b, 0x0e, 0x07, 0x00, 0x08, 0x14, 0x08, 0x10, 0x05, 0x00, 0x03, 0x18, 0x05, 0x00, 0x03, + 0x70, 0x00, 0x01, 0x02, 0x74, 0x00, 0x01, 0x02, 0x78, 0x00, 0x01, 0x02, 0x7c, 0x00, 0x01, 0x02, 0x28, 0x28, 0x02, 0x03, 0x30, 0x28, 0x02, 0x03, 0x38, 0x28, 0x02, 0x03, 0x40, 0x28, 0x02, 0x03, + 0x38, 0x14, 0x03, 0x03, 0x40, 0x14, 0x03, 0x03, 0x18, 0x04, 0x04, 0x03, 0x20, 0x04, 0x04, 0x03, 0x28, 0x04, 0x04, 0x03, 0xc0, 0x2d, 0x05, 0x04, 0x40, 0x18, 0x06, 0x04, 0x50, 0x18, 0x06, 0x04, + 0xe0, 0x07, 0x07, 0x04, 0x00, 0x34, 0x08, 0x05, 0xe0, 0x1e, 0x09, 0x05, 0x40, 0x39, 0x0b, 0x06, 0x00, 0x3c, 0x0e, 0x07, 0x00, 0x09, 0x14, 0x08, 0x20, 0x05, 0x00, 0x03, 0x28, 0x05, 0x00, 0x03, + 0x80, 0x00, 0x01, 0x02, 0x84, 0x00, 0x01, 0x02, 0x88, 0x00, 0x01, 0x02, 0x8c, 0x00, 0x01, 0x02, 0x48, 0x28, 0x02, 0x03, 0x50, 0x28, 0x02, 0x03, 0x58, 0x28, 0x02, 0x03, 0x60, 0x28, 0x02, 0x03, + 0x48, 0x14, 0x03, 0x03, 0x50, 0x14, 0x03, 0x03, 0x30, 0x04, 0x04, 0x03, 0x38, 0x04, 0x04, 0x03, 0x40, 0x04, 0x04, 0x03, 0xd0, 0x2d, 0x05, 0x04, 0x60, 0x18, 0x06, 0x04, 0x70, 0x18, 0x06, 0x04, + 0xf0, 0x07, 0x07, 0x04, 0x20, 0x34, 0x08, 0x05, 0x00, 0x1f, 0x09, 0x05, 0x80, 0x39, 0x0b, 0x06, 0x80, 0x3c, 0x0e, 0x07, 0x00, 0x2e, 0x15, 0x09, 0x30, 0x05, 0x00, 0x03, 0x38, 0x05, 0x00, 0x03, + 0x90, 0x00, 0x01, 0x02, 0x94, 0x00, 0x01, 0x02, 0x98, 0x00, 0x01, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, 0x28, 0x02, 0x03, 0x70, 0x28, 0x02, 0x03, 0x78, 0x28, 0x02, 0x03, 0x80, 0x28, 0x02, 0x03, + 0x58, 0x14, 0x03, 0x03, 0x60, 0x14, 0x03, 0x03, 0x48, 0x04, 0x04, 0x03, 0x50, 0x04, 0x04, 0x03, 0xe0, 0x2d, 0x05, 0x04, 0xf0, 0x2d, 0x05, 0x04, 0x80, 0x18, 0x06, 0x04, 0x90, 0x18, 0x06, 0x04, + 0x00, 0x08, 0x07, 0x04, 0x40, 0x34, 0x08, 0x05, 0x20, 0x1f, 0x09, 0x05, 0xc0, 0x39, 0x0b, 0x06, 0x00, 0x3d, 0x0e, 0x07, 0x00, 0x30, 0x15, 0x09, 0x40, 0x05, 0x00, 0x03, 0x48, 0x05, 0x00, 0x03, + 0xa0, 0x00, 0x01, 0x02, 0xa4, 0x00, 0x01, 0x02, 0xa8, 0x00, 0x01, 0x02, 0xac, 0x00, 0x01, 0x02, 0x88, 0x28, 0x02, 0x03, 0x90, 0x28, 0x02, 0x03, 0x98, 0x28, 0x02, 0x03, 0xa0, 0x28, 0x02, 0x03, + 0x68, 0x14, 0x03, 0x03, 0x70, 0x14, 0x03, 0x03, 0x58, 0x04, 0x04, 0x03, 0x60, 0x04, 0x04, 0x03, 0x00, 0x2e, 0x05, 0x04, 0x10, 0x2e, 0x05, 0x04, 0xa0, 0x18, 0x06, 0x04, 0xb0, 0x18, 0x06, 0x04, + 0x10, 0x08, 0x07, 0x04, 0x60, 0x34, 0x08, 0x05, 0x40, 0x1f, 0x09, 0x05, 0x00, 0x3a, 0x0b, 0x06, 0x80, 0x3d, 0x0e, 0x07, 0x00, 0x32, 0x15, 0x09, 0x50, 0x05, 0x00, 0x03, 0x58, 0x05, 0x00, 0x03, + 0xb0, 0x00, 0x01, 0x02, 0xb4, 0x00, 0x01, 0x02, 0xb8, 0x00, 0x01, 0x02, 0xbc, 0x00, 0x01, 0x02, 0xa8, 0x28, 0x02, 0x03, 0xb0, 0x28, 0x02, 0x03, 0xb8, 0x28, 0x02, 0x03, 0xc0, 0x28, 0x02, 0x03, + 0x78, 0x14, 0x03, 0x03, 0x80, 0x14, 0x03, 0x03, 0x68, 0x04, 0x04, 0x03, 0x70, 0x04, 0x04, 0x03, 0x20, 0x2e, 0x05, 0x04, 0x30, 0x2e, 0x05, 0x04, 0xc0, 0x18, 0x06, 0x04, 0xd0, 0x18, 0x06, 0x04, + 0x20, 0x08, 0x07, 0x04, 0x80, 0x34, 0x08, 0x05, 0x60, 0x1f, 0x09, 0x05, 0x40, 0x3a, 0x0b, 0x06, 0x00, 0x3e, 0x0e, 0x07, 0x00, 0x34, 0x15, 0x09, 0x60, 0x05, 0x00, 0x03, 0x68, 0x05, 0x00, 0x03, + 0xc0, 0x00, 0x01, 0x02, 0xc4, 0x00, 0x01, 0x02, 0xc8, 0x00, 0x01, 0x02, 0xcc, 0x00, 0x01, 0x02, 0xc8, 0x28, 0x02, 0x03, 0xd0, 0x28, 0x02, 0x03, 0xd8, 0x28, 0x02, 0x03, 0xe0, 0x28, 0x02, 0x03, + 0x88, 0x14, 0x03, 0x03, 0x90, 0x14, 0x03, 0x03, 0x78, 0x04, 0x04, 0x03, 0x80, 0x04, 0x04, 0x03, 0x40, 0x2e, 0x05, 0x04, 0x50, 0x2e, 0x05, 0x04, 0xe0, 0x18, 0x06, 0x04, 0xf0, 0x18, 0x06, 0x04, + 0x30, 0x08, 0x07, 0x04, 0xa0, 0x34, 0x08, 0x05, 0x80, 0x1f, 0x09, 0x05, 0x80, 0x3a, 0x0b, 0x06, 0x80, 0x3e, 0x0e, 0x07, 0x00, 0x36, 0x15, 0x09, 0x70, 0x05, 0x00, 0x03, 0x78, 0x05, 0x00, 0x03, + 0xd0, 0x00, 0x01, 0x02, 0xd4, 0x00, 0x01, 0x02, 0xd8, 0x00, 0x01, 0x02, 0xdc, 0x00, 0x01, 0x02, 0xe8, 0x28, 0x02, 0x03, 0xf0, 0x28, 0x02, 0x03, 0xf8, 0x28, 0x02, 0x03, 0x00, 0x29, 0x02, 0x03, + 0x98, 0x14, 0x03, 0x03, 0xa0, 0x14, 0x03, 0x03, 0x88, 0x04, 0x04, 0x03, 0x90, 0x04, 0x04, 0x03, 0x60, 0x2e, 0x05, 0x04, 0x70, 0x2e, 0x05, 0x04, 0x00, 0x19, 0x06, 0x04, 0x10, 0x19, 0x06, 0x04, + 0x40, 0x08, 0x07, 0x04, 0xc0, 0x34, 0x08, 0x05, 0xa0, 0x1f, 0x09, 0x05, 0xc0, 0x3a, 0x0b, 0x06, 0x00, 0x3f, 0x0e, 0x07, 0x00, 0x18, 0x16, 0x09, 0x80, 0x05, 0x00, 0x03, 0x88, 0x05, 0x00, 0x03, + 0xe0, 0x00, 0x01, 0x02, 0xe4, 0x00, 0x01, 0x02, 0xe8, 0x00, 0x01, 0x02, 0xec, 0x00, 0x01, 0x02, 0x08, 0x29, 0x02, 0x03, 0x10, 0x29, 0x02, 0x03, 0x18, 0x29, 0x02, 0x03, 0x20, 0x29, 0x02, 0x03, + 0xa8, 0x14, 0x03, 0x03, 0xb0, 0x14, 0x03, 0x03, 0x98, 0x04, 0x04, 0x03, 0xa0, 0x04, 0x04, 0x03, 0x80, 0x2e, 0x05, 0x04, 0x90, 0x2e, 0x05, 0x04, 0x20, 0x19, 0x06, 0x04, 0x30, 0x19, 0x06, 0x04, + 0x50, 0x08, 0x07, 0x04, 0xe0, 0x34, 0x08, 0x05, 0xc0, 0x1f, 0x09, 0x05, 0x00, 0x3b, 0x0b, 0x06, 0x80, 0x3f, 0x0e, 0x07, 0x00, 0x1a, 0x16, 0x09, 0x90, 0x05, 0x00, 0x03, 0x98, 0x05, 0x00, 0x03, + 0xf0, 0x00, 0x01, 0x02, 0xf4, 0x00, 0x01, 0x02, 0xf8, 0x00, 0x01, 0x02, 0xfc, 0x00, 0x01, 0x02, 0x28, 0x29, 0x02, 0x03, 0x30, 0x29, 0x02, 0x03, 0x38, 0x29, 0x02, 0x03, 0xb8, 0x14, 0x03, 0x03, + 0xc0, 0x14, 0x03, 0x03, 0xc8, 0x14, 0x03, 0x03, 0xa8, 0x04, 0x04, 0x03, 0xb0, 0x04, 0x04, 0x03, 0xa0, 0x2e, 0x05, 0x04, 0xb0, 0x2e, 0x05, 0x04, 0x40, 0x19, 0x06, 0x04, 0x50, 0x19, 0x06, 0x04, + 0x60, 0x08, 0x07, 0x04, 0x00, 0x35, 0x08, 0x05, 0xe0, 0x1f, 0x09, 0x05, 0x40, 0x3b, 0x0b, 0x06, 0x00, 0x00, 0x0e, 0x06, 0x00, 0x1c, 0x16, 0x09, 0xa0, 0x05, 0x00, 0x03, 0xa8, 0x05, 0x00, 0x03, + 0x00, 0x01, 0x01, 0x02, 0x04, 0x01, 0x01, 0x02, 0x08, 0x01, 0x01, 0x02, 0x0c, 0x01, 0x01, 0x02, 0x40, 0x29, 0x02, 0x03, 0x48, 0x29, 0x02, 0x03, 0x50, 0x29, 0x02, 0x03, 0xd0, 0x14, 0x03, 0x03, + 0xd8, 0x14, 0x03, 0x03, 0xe0, 0x14, 0x03, 0x03, 0xb8, 0x04, 0x04, 0x03, 0xc0, 0x04, 0x04, 0x03, 0xc0, 0x2e, 0x05, 0x04, 0xd0, 0x2e, 0x05, 0x04, 0x60, 0x19, 0x06, 0x04, 0x70, 0x19, 0x06, 0x04, + 0x70, 0x08, 0x07, 0x04, 0x20, 0x35, 0x08, 0x05, 0xe0, 0x0b, 0x0a, 0x05, 0x80, 0x3b, 0x0b, 0x06, 0x40, 0x00, 0x0e, 0x06, 0x00, 0x1e, 0x16, 0x09, 0xb0, 0x05, 0x00, 0x03, 0xb8, 0x05, 0x00, 0x03, + 0x10, 0x01, 0x01, 0x02, 0x14, 0x01, 0x01, 0x02, 0x18, 0x01, 0x01, 0x02, 0x1c, 0x01, 0x01, 0x02, 0x58, 0x29, 0x02, 0x03, 0x60, 0x29, 0x02, 0x03, 0x68, 0x29, 0x02, 0x03, 0xe8, 0x14, 0x03, 0x03, + 0xf0, 0x14, 0x03, 0x03, 0xf8, 0x14, 0x03, 0x03, 0xc8, 0x04, 0x04, 0x03, 0xd0, 0x04, 0x04, 0x03, 0xe0, 0x2e, 0x05, 0x04, 0xf0, 0x2e, 0x05, 0x04, 0x80, 0x19, 0x06, 0x04, 0x90, 0x19, 0x06, 0x04, + 0x80, 0x08, 0x07, 0x04, 0x40, 0x35, 0x08, 0x05, 0x00, 0x0c, 0x0a, 0x05, 0xc0, 0x3b, 0x0b, 0x06, 0x80, 0x00, 0x0e, 0x06, 0x00, 0x08, 0x17, 0x09, 0xc0, 0x05, 0x00, 0x03, 0xc8, 0x05, 0x00, 0x03, + 0x20, 0x01, 0x01, 0x02, 0x24, 0x01, 0x01, 0x02, 0x28, 0x01, 0x01, 0x02, 0x2c, 0x01, 0x01, 0x02, 0x70, 0x29, 0x02, 0x03, 0x78, 0x29, 0x02, 0x03, 0x80, 0x29, 0x02, 0x03, 0x00, 0x15, 0x03, 0x03, + 0x08, 0x15, 0x03, 0x03, 0x10, 0x15, 0x03, 0x03, 0xd8, 0x04, 0x04, 0x03, 0xe0, 0x04, 0x04, 0x03, 0x00, 0x2f, 0x05, 0x04, 0x10, 0x2f, 0x05, 0x04, 0xa0, 0x19, 0x06, 0x04, 0xb0, 0x19, 0x06, 0x04, + 0x90, 0x08, 0x07, 0x04, 0x60, 0x35, 0x08, 0x05, 0x20, 0x0c, 0x0a, 0x05, 0x00, 0x3c, 0x0b, 0x06, 0xc0, 0x00, 0x0e, 0x06, 0x00, 0x0a, 0x17, 0x09, 0xd0, 0x05, 0x00, 0x03, 0xd8, 0x05, 0x00, 0x03, + 0x30, 0x01, 0x01, 0x02, 0x34, 0x01, 0x01, 0x02, 0x38, 0x01, 0x01, 0x02, 0x3c, 0x01, 0x01, 0x02, 0x88, 0x29, 0x02, 0x03, 0x90, 0x29, 0x02, 0x03, 0x98, 0x29, 0x02, 0x03, 0x18, 0x15, 0x03, 0x03, + 0x20, 0x15, 0x03, 0x03, 0x28, 0x15, 0x03, 0x03, 0xe8, 0x04, 0x04, 0x03, 0xf0, 0x04, 0x04, 0x03, 0x20, 0x2f, 0x05, 0x04, 0x30, 0x2f, 0x05, 0x04, 0xc0, 0x19, 0x06, 0x04, 0xd0, 0x19, 0x06, 0x04, + 0xa0, 0x08, 0x07, 0x04, 0x80, 0x35, 0x08, 0x05, 0x40, 0x0c, 0x0a, 0x05, 0x40, 0x3c, 0x0b, 0x06, 0x00, 0x01, 0x0e, 0x06, 0x00, 0x0c, 0x17, 0x09, 0xe0, 0x05, 0x00, 0x03, 0xe8, 0x05, 0x00, 0x03, + 0x40, 0x01, 0x01, 0x02, 0x44, 0x01, 0x01, 0x02, 0x48, 0x01, 0x01, 0x02, 0x4c, 0x01, 0x01, 0x02, 0xa0, 0x29, 0x02, 0x03, 0xa8, 0x29, 0x02, 0x03, 0xb0, 0x29, 0x02, 0x03, 0x30, 0x15, 0x03, 0x03, + 0x38, 0x15, 0x03, 0x03, 0x40, 0x15, 0x03, 0x03, 0xf8, 0x04, 0x04, 0x03, 0x00, 0x05, 0x04, 0x03, 0x40, 0x2f, 0x05, 0x04, 0x50, 0x2f, 0x05, 0x04, 0xe0, 0x19, 0x06, 0x04, 0xf0, 0x19, 0x06, 0x04, + 0xb0, 0x08, 0x07, 0x04, 0xa0, 0x35, 0x08, 0x05, 0x60, 0x0c, 0x0a, 0x05, 0x80, 0x3c, 0x0b, 0x06, 0x40, 0x01, 0x0e, 0x06, 0x00, 0x34, 0x18, 0x0a, 0xf0, 0x05, 0x00, 0x03, 0xf8, 0x05, 0x00, 0x03, + 0x50, 0x01, 0x01, 0x02, 0x54, 0x01, 0x01, 0x02, 0x58, 0x01, 0x01, 0x02, 0x5c, 0x01, 0x01, 0x02, 0xb8, 0x29, 0x02, 0x03, 0xc0, 0x29, 0x02, 0x03, 0xc8, 0x29, 0x02, 0x03, 0x48, 0x15, 0x03, 0x03, + 0x50, 0x15, 0x03, 0x03, 0x58, 0x15, 0x03, 0x03, 0x08, 0x05, 0x04, 0x03, 0x10, 0x05, 0x04, 0x03, 0x60, 0x2f, 0x05, 0x04, 0x70, 0x2f, 0x05, 0x04, 0x00, 0x1a, 0x06, 0x04, 0x10, 0x1a, 0x06, 0x04, + 0xc0, 0x08, 0x07, 0x04, 0xc0, 0x35, 0x08, 0x05, 0x80, 0x0c, 0x0a, 0x05, 0xc0, 0x3c, 0x0b, 0x06, 0x80, 0x01, 0x0e, 0x06, 0x00, 0x38, 0x18, 0x0a, 0x00, 0x06, 0x00, 0x03, 0x08, 0x06, 0x00, 0x03, + 0x60, 0x01, 0x01, 0x02, 0x64, 0x01, 0x01, 0x02, 0x68, 0x01, 0x01, 0x02, 0x6c, 0x01, 0x01, 0x02, 0xd0, 0x29, 0x02, 0x03, 0xd8, 0x29, 0x02, 0x03, 0xe0, 0x29, 0x02, 0x03, 0x60, 0x15, 0x03, 0x03, + 0x68, 0x15, 0x03, 0x03, 0x70, 0x15, 0x03, 0x03, 0x18, 0x05, 0x04, 0x03, 0x20, 0x05, 0x04, 0x03, 0x80, 0x2f, 0x05, 0x04, 0x90, 0x2f, 0x05, 0x04, 0x20, 0x1a, 0x06, 0x04, 0x30, 0x1a, 0x06, 0x04, + 0xd0, 0x08, 0x07, 0x04, 0xe0, 0x35, 0x08, 0x05, 0xa0, 0x0c, 0x0a, 0x05, 0x00, 0x3d, 0x0b, 0x06, 0xc0, 0x01, 0x0e, 0x06, 0x00, 0x1c, 0x19, 0x0a, 0x10, 0x06, 0x00, 0x03, 0x18, 0x06, 0x00, 0x03, + 0x70, 0x01, 0x01, 0x02, 0x74, 0x01, 0x01, 0x02, 0x78, 0x01, 0x01, 0x02, 0x7c, 0x01, 0x01, 0x02, 0xe8, 0x29, 0x02, 0x03, 0xf0, 0x29, 0x02, 0x03, 0xf8, 0x29, 0x02, 0x03, 0x78, 0x15, 0x03, 0x03, + 0x80, 0x15, 0x03, 0x03, 0x88, 0x15, 0x03, 0x03, 0x28, 0x05, 0x04, 0x03, 0x30, 0x05, 0x04, 0x03, 0xa0, 0x2f, 0x05, 0x04, 0xb0, 0x2f, 0x05, 0x04, 0x40, 0x1a, 0x06, 0x04, 0x50, 0x1a, 0x06, 0x04, + 0xe0, 0x08, 0x07, 0x04, 0x00, 0x36, 0x08, 0x05, 0xc0, 0x0c, 0x0a, 0x05, 0x40, 0x3d, 0x0b, 0x06, 0x00, 0x02, 0x0e, 0x06, 0x00, 0x20, 0x19, 0x0a, 0x20, 0x06, 0x00, 0x03, 0x28, 0x06, 0x00, 0x03, + 0x80, 0x01, 0x01, 0x02, 0x84, 0x01, 0x01, 0x02, 0x88, 0x01, 0x01, 0x02, 0x8c, 0x01, 0x01, 0x02, 0x00, 0x2a, 0x02, 0x03, 0x08, 0x2a, 0x02, 0x03, 0x10, 0x2a, 0x02, 0x03, 0x90, 0x15, 0x03, 0x03, + 0x98, 0x15, 0x03, 0x03, 0xa0, 0x15, 0x03, 0x03, 0x38, 0x05, 0x04, 0x03, 0x40, 0x05, 0x04, 0x03, 0xc0, 0x2f, 0x05, 0x04, 0xd0, 0x2f, 0x05, 0x04, 0x60, 0x1a, 0x06, 0x04, 0x70, 0x1a, 0x06, 0x04, + 0xf0, 0x08, 0x07, 0x04, 0x20, 0x36, 0x08, 0x05, 0xe0, 0x0c, 0x0a, 0x05, 0x80, 0x3d, 0x0b, 0x06, 0x80, 0x28, 0x0f, 0x07, 0x00, 0x24, 0x19, 0x0a, 0x30, 0x06, 0x00, 0x03, 0x38, 0x06, 0x00, 0x03, + 0x90, 0x01, 0x01, 0x02, 0x94, 0x01, 0x01, 0x02, 0x98, 0x01, 0x01, 0x02, 0x9c, 0x01, 0x01, 0x02, 0x18, 0x2a, 0x02, 0x03, 0x20, 0x2a, 0x02, 0x03, 0x28, 0x2a, 0x02, 0x03, 0xa8, 0x15, 0x03, 0x03, + 0xb0, 0x15, 0x03, 0x03, 0xb8, 0x15, 0x03, 0x03, 0x48, 0x05, 0x04, 0x03, 0x50, 0x05, 0x04, 0x03, 0xe0, 0x2f, 0x05, 0x04, 0xf0, 0x2f, 0x05, 0x04, 0x80, 0x1a, 0x06, 0x04, 0x90, 0x1a, 0x06, 0x04, + 0x00, 0x09, 0x07, 0x04, 0x40, 0x36, 0x08, 0x05, 0x00, 0x0d, 0x0a, 0x05, 0x80, 0x24, 0x0c, 0x06, 0x00, 0x29, 0x0f, 0x07, 0x00, 0x10, 0x1a, 0x0a, 0x40, 0x06, 0x00, 0x03, 0x48, 0x06, 0x00, 0x03, + 0xa0, 0x01, 0x01, 0x02, 0xa4, 0x01, 0x01, 0x02, 0xa8, 0x01, 0x01, 0x02, 0xac, 0x01, 0x01, 0x02, 0x30, 0x2a, 0x02, 0x03, 0x38, 0x2a, 0x02, 0x03, 0x40, 0x2a, 0x02, 0x03, 0xc0, 0x15, 0x03, 0x03, + 0xc8, 0x15, 0x03, 0x03, 0xd0, 0x15, 0x03, 0x03, 0x58, 0x05, 0x04, 0x03, 0x60, 0x05, 0x04, 0x03, 0x00, 0x30, 0x05, 0x04, 0x10, 0x30, 0x05, 0x04, 0xa0, 0x1a, 0x06, 0x04, 0xb0, 0x1a, 0x06, 0x04, + 0x10, 0x09, 0x07, 0x04, 0x60, 0x36, 0x08, 0x05, 0x20, 0x0d, 0x0a, 0x05, 0xc0, 0x24, 0x0c, 0x06, 0x80, 0x29, 0x0f, 0x07, 0x00, 0x14, 0x1a, 0x0a, 0x50, 0x06, 0x00, 0x03, 0x58, 0x06, 0x00, 0x03, + 0xb0, 0x01, 0x01, 0x02, 0xb4, 0x01, 0x01, 0x02, 0xb8, 0x01, 0x01, 0x02, 0xbc, 0x01, 0x01, 0x02, 0x48, 0x2a, 0x02, 0x03, 0x50, 0x2a, 0x02, 0x03, 0x58, 0x2a, 0x02, 0x03, 0xd8, 0x15, 0x03, 0x03, + 0xe0, 0x15, 0x03, 0x03, 0xe8, 0x15, 0x03, 0x03, 0x68, 0x05, 0x04, 0x03, 0x70, 0x05, 0x04, 0x03, 0x20, 0x30, 0x05, 0x04, 0x30, 0x30, 0x05, 0x04, 0xc0, 0x1a, 0x06, 0x04, 0xd0, 0x1a, 0x06, 0x04, + 0x20, 0x09, 0x07, 0x04, 0x80, 0x36, 0x08, 0x05, 0x40, 0x0d, 0x0a, 0x05, 0x00, 0x25, 0x0c, 0x06, 0x00, 0x2a, 0x0f, 0x07, 0x00, 0x00, 0x1b, 0x0a, 0x60, 0x06, 0x00, 0x03, 0x68, 0x06, 0x00, 0x03, + 0xc0, 0x01, 0x01, 0x02, 0xc4, 0x01, 0x01, 0x02, 0xc8, 0x01, 0x01, 0x02, 0xcc, 0x01, 0x01, 0x02, 0x60, 0x2a, 0x02, 0x03, 0x68, 0x2a, 0x02, 0x03, 0x70, 0x2a, 0x02, 0x03, 0xf0, 0x15, 0x03, 0x03, + 0xf8, 0x15, 0x03, 0x03, 0x00, 0x16, 0x03, 0x03, 0x78, 0x05, 0x04, 0x03, 0x80, 0x05, 0x04, 0x03, 0x40, 0x30, 0x05, 0x04, 0x50, 0x30, 0x05, 0x04, 0xe0, 0x1a, 0x06, 0x04, 0x30, 0x09, 0x07, 0x04, + 0x40, 0x09, 0x07, 0x04, 0xa0, 0x36, 0x08, 0x05, 0x60, 0x0d, 0x0a, 0x05, 0x40, 0x25, 0x0c, 0x06, 0x80, 0x2a, 0x0f, 0x07, 0x00, 0x28, 0x1c, 0x0b, 0x70, 0x06, 0x00, 0x03, 0x78, 0x06, 0x00, 0x03, + 0xd0, 0x01, 0x01, 0x02, 0xd4, 0x01, 0x01, 0x02, 0xd8, 0x01, 0x01, 0x02, 0xdc, 0x01, 0x01, 0x02, 0x78, 0x2a, 0x02, 0x03, 0x80, 0x2a, 0x02, 0x03, 0x88, 0x2a, 0x02, 0x03, 0x08, 0x16, 0x03, 0x03, + 0x10, 0x16, 0x03, 0x03, 0x18, 0x16, 0x03, 0x03, 0x88, 0x05, 0x04, 0x03, 0x90, 0x05, 0x04, 0x03, 0x60, 0x30, 0x05, 0x04, 0x70, 0x30, 0x05, 0x04, 0xf0, 0x1a, 0x06, 0x04, 0x50, 0x09, 0x07, 0x04, + 0x60, 0x09, 0x07, 0x04, 0xc0, 0x36, 0x08, 0x05, 0x80, 0x0d, 0x0a, 0x05, 0x80, 0x25, 0x0c, 0x06, 0x00, 0x2b, 0x0f, 0x07, 0x00, 0x10, 0x1d, 0x0b, 0x80, 0x06, 0x00, 0x03, 0x88, 0x06, 0x00, 0x03, + 0xe0, 0x01, 0x01, 0x02, 0xe4, 0x01, 0x01, 0x02, 0xe8, 0x01, 0x01, 0x02, 0xec, 0x01, 0x01, 0x02, 0x90, 0x2a, 0x02, 0x03, 0x98, 0x2a, 0x02, 0x03, 0xa0, 0x2a, 0x02, 0x03, 0x20, 0x16, 0x03, 0x03, + 0x28, 0x16, 0x03, 0x03, 0x30, 0x16, 0x03, 0x03, 0x98, 0x05, 0x04, 0x03, 0xa0, 0x05, 0x04, 0x03, 0x80, 0x30, 0x05, 0x04, 0x90, 0x30, 0x05, 0x04, 0x00, 0x1b, 0x06, 0x04, 0x70, 0x09, 0x07, 0x04, + 0x80, 0x09, 0x07, 0x04, 0xe0, 0x36, 0x08, 0x05, 0xa0, 0x0d, 0x0a, 0x05, 0xc0, 0x25, 0x0c, 0x06, 0x80, 0x2b, 0x0f, 0x07, 0x00, 0x08, 0x1e, 0x0b, 0x90, 0x06, 0x00, 0x03, 0x98, 0x06, 0x00, 0x03, + 0xf0, 0x01, 0x01, 0x02, 0xf4, 0x01, 0x01, 0x02, 0xf8, 0x01, 0x01, 0x02, 0xfc, 0x01, 0x01, 0x02, 0xa8, 0x2a, 0x02, 0x03, 0xb0, 0x2a, 0x02, 0x03, 0xb8, 0x2a, 0x02, 0x03, 0x38, 0x16, 0x03, 0x03, + 0x40, 0x16, 0x03, 0x03, 0x48, 0x16, 0x03, 0x03, 0xa8, 0x05, 0x04, 0x03, 0xb0, 0x05, 0x04, 0x03, 0xa0, 0x30, 0x05, 0x04, 0xb0, 0x30, 0x05, 0x04, 0x10, 0x1b, 0x06, 0x04, 0x90, 0x09, 0x07, 0x04, + 0xa0, 0x09, 0x07, 0x04, 0x00, 0x37, 0x08, 0x05, 0xc0, 0x0d, 0x0a, 0x05, 0x00, 0x26, 0x0c, 0x06, 0x00, 0x2c, 0x0f, 0x07, 0x00, 0x30, 0x1f, 0x0c, 0xa0, 0x06, 0x00, 0x03, 0xa8, 0x06, 0x00, 0x03, + 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02, 0x08, 0x02, 0x01, 0x02, 0x0c, 0x02, 0x01, 0x02, 0xc0, 0x2a, 0x02, 0x03, 0xc8, 0x2a, 0x02, 0x03, 0xd0, 0x2a, 0x02, 0x03, 0x50, 0x16, 0x03, 0x03, + 0x58, 0x16, 0x03, 0x03, 0x60, 0x16, 0x03, 0x03, 0xb8, 0x05, 0x04, 0x03, 0xc0, 0x05, 0x04, 0x03, 0xc0, 0x30, 0x05, 0x04, 0xd0, 0x30, 0x05, 0x04, 0x20, 0x1b, 0x06, 0x04, 0xb0, 0x09, 0x07, 0x04, + 0xc0, 0x09, 0x07, 0x04, 0x20, 0x37, 0x08, 0x05, 0xe0, 0x0d, 0x0a, 0x05, 0x40, 0x26, 0x0c, 0x06, 0x80, 0x2c, 0x0f, 0x07, 0x00, 0x10, 0x20, 0x0c, 0xb0, 0x06, 0x00, 0x03, 0xb8, 0x06, 0x00, 0x03, + 0x10, 0x02, 0x01, 0x02, 0x14, 0x02, 0x01, 0x02, 0x18, 0x02, 0x01, 0x02, 0x1c, 0x02, 0x01, 0x02, 0xd8, 0x2a, 0x02, 0x03, 0xe0, 0x2a, 0x02, 0x03, 0xe8, 0x2a, 0x02, 0x03, 0x68, 0x16, 0x03, 0x03, + 0x70, 0x16, 0x03, 0x03, 0x78, 0x16, 0x03, 0x03, 0xc8, 0x05, 0x04, 0x03, 0xd0, 0x05, 0x04, 0x03, 0xe0, 0x30, 0x05, 0x04, 0xf0, 0x30, 0x05, 0x04, 0x30, 0x1b, 0x06, 0x04, 0xd0, 0x09, 0x07, 0x04, + 0xe0, 0x09, 0x07, 0x04, 0x40, 0x37, 0x08, 0x05, 0x00, 0x0e, 0x0a, 0x05, 0x80, 0x26, 0x0c, 0x06, 0x00, 0x2d, 0x0f, 0x07, 0x00, 0x20, 0x23, 0x0d, 0xc0, 0x06, 0x00, 0x03, 0xc8, 0x06, 0x00, 0x03, + 0x20, 0x02, 0x01, 0x02, 0x24, 0x02, 0x01, 0x02, 0x28, 0x02, 0x01, 0x02, 0x2c, 0x02, 0x01, 0x02, 0xf0, 0x2a, 0x02, 0x03, 0xf8, 0x2a, 0x02, 0x03, 0x00, 0x2b, 0x02, 0x03, 0x80, 0x16, 0x03, 0x03, + 0x88, 0x16, 0x03, 0x03, 0x90, 0x16, 0x03, 0x03, 0xd8, 0x05, 0x04, 0x03, 0xe0, 0x05, 0x04, 0x03, 0x00, 0x31, 0x05, 0x04, 0x10, 0x31, 0x05, 0x04, 0x40, 0x1b, 0x06, 0x04, 0xf0, 0x09, 0x07, 0x04, + 0x00, 0x0a, 0x07, 0x04, 0x60, 0x37, 0x08, 0x05, 0x20, 0x0e, 0x0a, 0x05, 0xc0, 0x26, 0x0c, 0x06, 0x80, 0x2d, 0x0f, 0x07, 0xd0, 0x06, 0x00, 0x03, 0xd8, 0x06, 0x00, 0x03, 0xe0, 0x06, 0x00, 0x03, + 0x30, 0x02, 0x01, 0x02, 0x34, 0x02, 0x01, 0x02, 0x38, 0x02, 0x01, 0x02, 0x3c, 0x02, 0x01, 0x02, 0x08, 0x2b, 0x02, 0x03, 0x10, 0x2b, 0x02, 0x03, 0x18, 0x2b, 0x02, 0x03, 0x98, 0x16, 0x03, 0x03, + 0xa0, 0x16, 0x03, 0x03, 0xa8, 0x16, 0x03, 0x03, 0xe8, 0x05, 0x04, 0x03, 0xf0, 0x05, 0x04, 0x03, 0x20, 0x31, 0x05, 0x04, 0x30, 0x31, 0x05, 0x04, 0x50, 0x1b, 0x06, 0x04, 0x10, 0x0a, 0x07, 0x04, + 0x20, 0x0a, 0x07, 0x04, 0x80, 0x37, 0x08, 0x05, 0x40, 0x0e, 0x0a, 0x05, 0x00, 0x27, 0x0c, 0x06, 0x00, 0x2e, 0x0f, 0x07, 0xe8, 0x06, 0x00, 0x03, 0xf0, 0x06, 0x00, 0x03, 0xf8, 0x06, 0x00, 0x03, + 0x40, 0x02, 0x01, 0x02, 0x44, 0x02, 0x01, 0x02, 0x48, 0x02, 0x01, 0x02, 0x4c, 0x02, 0x01, 0x02, 0x20, 0x2b, 0x02, 0x03, 0x28, 0x2b, 0x02, 0x03, 0x30, 0x2b, 0x02, 0x03, 0xb0, 0x16, 0x03, 0x03, + 0xb8, 0x16, 0x03, 0x03, 0xc0, 0x16, 0x03, 0x03, 0xf8, 0x05, 0x04, 0x03, 0x00, 0x06, 0x04, 0x03, 0x40, 0x31, 0x05, 0x04, 0x50, 0x31, 0x05, 0x04, 0x60, 0x1b, 0x06, 0x04, 0x30, 0x0a, 0x07, 0x04, + 0x40, 0x0a, 0x07, 0x04, 0xa0, 0x37, 0x08, 0x05, 0x60, 0x0e, 0x0a, 0x05, 0x40, 0x27, 0x0c, 0x06, 0x80, 0x2e, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x03, 0x08, 0x07, 0x00, 0x03, 0x10, 0x07, 0x00, 0x03, + 0x50, 0x02, 0x01, 0x02, 0x54, 0x02, 0x01, 0x02, 0x58, 0x02, 0x01, 0x02, 0x5c, 0x02, 0x01, 0x02, 0x38, 0x2b, 0x02, 0x03, 0x40, 0x2b, 0x02, 0x03, 0x48, 0x2b, 0x02, 0x03, 0xc8, 0x16, 0x03, 0x03, + 0xd0, 0x16, 0x03, 0x03, 0xd8, 0x16, 0x03, 0x03, 0x08, 0x06, 0x04, 0x03, 0x10, 0x06, 0x04, 0x03, 0x60, 0x31, 0x05, 0x04, 0x70, 0x31, 0x05, 0x04, 0x70, 0x1b, 0x06, 0x04, 0x50, 0x0a, 0x07, 0x04, + 0x60, 0x0a, 0x07, 0x04, 0x00, 0x20, 0x09, 0x05, 0x80, 0x0e, 0x0a, 0x05, 0x80, 0x27, 0x0c, 0x06, 0x00, 0x2f, 0x0f, 0x07, 0x18, 0x07, 0x00, 0x03, 0x20, 0x07, 0x00, 0x03, 0x28, 0x07, 0x00, 0x03, + 0x60, 0x02, 0x01, 0x02, 0x64, 0x02, 0x01, 0x02, 0x68, 0x02, 0x01, 0x02, 0x6c, 0x02, 0x01, 0x02, 0x50, 0x2b, 0x02, 0x03, 0x58, 0x2b, 0x02, 0x03, 0x60, 0x2b, 0x02, 0x03, 0xe0, 0x16, 0x03, 0x03, + 0xe8, 0x16, 0x03, 0x03, 0xf0, 0x16, 0x03, 0x03, 0x18, 0x06, 0x04, 0x03, 0x20, 0x06, 0x04, 0x03, 0x80, 0x31, 0x05, 0x04, 0x90, 0x31, 0x05, 0x04, 0x80, 0x1b, 0x06, 0x04, 0x70, 0x0a, 0x07, 0x04, + 0x80, 0x0a, 0x07, 0x04, 0x20, 0x20, 0x09, 0x05, 0xa0, 0x0e, 0x0a, 0x05, 0xc0, 0x27, 0x0c, 0x06, 0x80, 0x2f, 0x0f, 0x07, 0x30, 0x07, 0x00, 0x03, 0x38, 0x07, 0x00, 0x03, 0x40, 0x07, 0x00, 0x03, + 0x70, 0x02, 0x01, 0x02, 0x74, 0x02, 0x01, 0x02, 0x78, 0x02, 0x01, 0x02, 0x7c, 0x02, 0x01, 0x02, 0x68, 0x2b, 0x02, 0x03, 0x70, 0x2b, 0x02, 0x03, 0x78, 0x2b, 0x02, 0x03, 0xf8, 0x16, 0x03, 0x03, + 0x00, 0x17, 0x03, 0x03, 0x08, 0x17, 0x03, 0x03, 0x28, 0x06, 0x04, 0x03, 0x30, 0x06, 0x04, 0x03, 0xa0, 0x31, 0x05, 0x04, 0xb0, 0x31, 0x05, 0x04, 0x90, 0x1b, 0x06, 0x04, 0x90, 0x0a, 0x07, 0x04, + 0xa0, 0x0a, 0x07, 0x04, 0x40, 0x20, 0x09, 0x05, 0xc0, 0x0e, 0x0a, 0x05, 0x00, 0x28, 0x0c, 0x06, 0x00, 0x30, 0x0f, 0x07, 0x48, 0x07, 0x00, 0x03, 0x50, 0x07, 0x00, 0x03, 0x58, 0x07, 0x00, 0x03, + 0x80, 0x02, 0x01, 0x02, 0x84, 0x02, 0x01, 0x02, 0x88, 0x02, 0x01, 0x02, 0x8c, 0x02, 0x01, 0x02, 0x80, 0x2b, 0x02, 0x03, 0x88, 0x2b, 0x02, 0x03, 0x90, 0x2b, 0x02, 0x03, 0x10, 0x17, 0x03, 0x03, + 0x18, 0x17, 0x03, 0x03, 0x20, 0x17, 0x03, 0x03, 0x38, 0x06, 0x04, 0x03, 0x40, 0x06, 0x04, 0x03, 0xc0, 0x31, 0x05, 0x04, 0xd0, 0x31, 0x05, 0x04, 0xa0, 0x1b, 0x06, 0x04, 0xb0, 0x0a, 0x07, 0x04, + 0xc0, 0x0a, 0x07, 0x04, 0x60, 0x20, 0x09, 0x05, 0xe0, 0x0e, 0x0a, 0x05, 0x40, 0x28, 0x0c, 0x06, 0x80, 0x30, 0x0f, 0x07, 0x60, 0x07, 0x00, 0x03, 0x68, 0x07, 0x00, 0x03, 0x70, 0x07, 0x00, 0x03, + 0x90, 0x02, 0x01, 0x02, 0x94, 0x02, 0x01, 0x02, 0x98, 0x02, 0x01, 0x02, 0x9c, 0x02, 0x01, 0x02, 0x98, 0x2b, 0x02, 0x03, 0xa0, 0x2b, 0x02, 0x03, 0xa8, 0x2b, 0x02, 0x03, 0x28, 0x17, 0x03, 0x03, + 0x30, 0x17, 0x03, 0x03, 0x38, 0x17, 0x03, 0x03, 0x48, 0x06, 0x04, 0x03, 0x50, 0x06, 0x04, 0x03, 0xe0, 0x31, 0x05, 0x04, 0xf0, 0x31, 0x05, 0x04, 0xb0, 0x1b, 0x06, 0x04, 0xd0, 0x0a, 0x07, 0x04, + 0xe0, 0x0a, 0x07, 0x04, 0x80, 0x20, 0x09, 0x05, 0x00, 0x0f, 0x0a, 0x05, 0x80, 0x28, 0x0c, 0x06, 0x00, 0x31, 0x0f, 0x07, 0x78, 0x07, 0x00, 0x03, 0x80, 0x07, 0x00, 0x03, 0x88, 0x07, 0x00, 0x03, + 0xa0, 0x02, 0x01, 0x02, 0xa4, 0x02, 0x01, 0x02, 0xa8, 0x02, 0x01, 0x02, 0xac, 0x02, 0x01, 0x02, 0xb0, 0x2b, 0x02, 0x03, 0xb8, 0x2b, 0x02, 0x03, 0xc0, 0x2b, 0x02, 0x03, 0x40, 0x17, 0x03, 0x03, + 0x48, 0x17, 0x03, 0x03, 0x50, 0x17, 0x03, 0x03, 0x58, 0x06, 0x04, 0x03, 0x60, 0x06, 0x04, 0x03, 0x00, 0x32, 0x05, 0x04, 0x10, 0x32, 0x05, 0x04, 0xc0, 0x1b, 0x06, 0x04, 0xf0, 0x0a, 0x07, 0x04, + 0xc0, 0x37, 0x08, 0x05, 0xa0, 0x20, 0x09, 0x05, 0x20, 0x0f, 0x0a, 0x05, 0xc0, 0x28, 0x0c, 0x06, 0x80, 0x31, 0x0f, 0x07, 0x90, 0x07, 0x00, 0x03, 0x98, 0x07, 0x00, 0x03, 0xa0, 0x07, 0x00, 0x03, + 0xb0, 0x02, 0x01, 0x02, 0xb4, 0x02, 0x01, 0x02, 0xb8, 0x02, 0x01, 0x02, 0xbc, 0x02, 0x01, 0x02, 0xc8, 0x2b, 0x02, 0x03, 0xd0, 0x2b, 0x02, 0x03, 0xd8, 0x2b, 0x02, 0x03, 0x58, 0x17, 0x03, 0x03, + 0x60, 0x17, 0x03, 0x03, 0x68, 0x17, 0x03, 0x03, 0x68, 0x06, 0x04, 0x03, 0x70, 0x06, 0x04, 0x03, 0x20, 0x32, 0x05, 0x04, 0x30, 0x32, 0x05, 0x04, 0xd0, 0x1b, 0x06, 0x04, 0x00, 0x0b, 0x07, 0x04, + 0xe0, 0x37, 0x08, 0x05, 0xc0, 0x20, 0x09, 0x05, 0x40, 0x0f, 0x0a, 0x05, 0x00, 0x29, 0x0c, 0x06, 0x00, 0x32, 0x0f, 0x07, 0xa8, 0x07, 0x00, 0x03, 0xb0, 0x07, 0x00, 0x03, 0xb8, 0x07, 0x00, 0x03, + 0xc0, 0x02, 0x01, 0x02, 0xc4, 0x02, 0x01, 0x02, 0xc8, 0x02, 0x01, 0x02, 0xcc, 0x02, 0x01, 0x02, 0xe0, 0x2b, 0x02, 0x03, 0xe8, 0x2b, 0x02, 0x03, 0xf0, 0x2b, 0x02, 0x03, 0x70, 0x17, 0x03, 0x03, + 0x78, 0x17, 0x03, 0x03, 0x80, 0x17, 0x03, 0x03, 0x78, 0x06, 0x04, 0x03, 0x80, 0x06, 0x04, 0x03, 0x40, 0x32, 0x05, 0x04, 0x50, 0x32, 0x05, 0x04, 0xe0, 0x1b, 0x06, 0x04, 0x10, 0x0b, 0x07, 0x04, + 0x00, 0x38, 0x08, 0x05, 0xe0, 0x20, 0x09, 0x05, 0x60, 0x0f, 0x0a, 0x05, 0x40, 0x29, 0x0c, 0x06, 0x80, 0x17, 0x10, 0x07, 0xc0, 0x07, 0x00, 0x03, 0xc8, 0x07, 0x00, 0x03, 0xd0, 0x07, 0x00, 0x03, + 0xd0, 0x02, 0x01, 0x02, 0xd4, 0x02, 0x01, 0x02, 0xd8, 0x02, 0x01, 0x02, 0xdc, 0x02, 0x01, 0x02, 0xf8, 0x2b, 0x02, 0x03, 0x00, 0x2c, 0x02, 0x03, 0x08, 0x2c, 0x02, 0x03, 0x88, 0x17, 0x03, 0x03, + 0x90, 0x17, 0x03, 0x03, 0x98, 0x17, 0x03, 0x03, 0x88, 0x06, 0x04, 0x03, 0x90, 0x06, 0x04, 0x03, 0x60, 0x32, 0x05, 0x04, 0x70, 0x32, 0x05, 0x04, 0xf0, 0x1b, 0x06, 0x04, 0x20, 0x0b, 0x07, 0x04, + 0x20, 0x38, 0x08, 0x05, 0x00, 0x21, 0x09, 0x05, 0x80, 0x0f, 0x0a, 0x05, 0x80, 0x29, 0x0c, 0x06, 0x00, 0x18, 0x10, 0x07, 0xd8, 0x07, 0x00, 0x03, 0xe0, 0x07, 0x00, 0x03, 0xe8, 0x07, 0x00, 0x03, + 0xe0, 0x02, 0x01, 0x02, 0xe4, 0x02, 0x01, 0x02, 0xe8, 0x02, 0x01, 0x02, 0xec, 0x02, 0x01, 0x02, 0x10, 0x2c, 0x02, 0x03, 0x18, 0x2c, 0x02, 0x03, 0x20, 0x2c, 0x02, 0x03, 0xa0, 0x17, 0x03, 0x03, + 0xa8, 0x17, 0x03, 0x03, 0xb0, 0x17, 0x03, 0x03, 0x98, 0x06, 0x04, 0x03, 0xa0, 0x06, 0x04, 0x03, 0x80, 0x32, 0x05, 0x04, 0x90, 0x32, 0x05, 0x04, 0x00, 0x1c, 0x06, 0x04, 0x30, 0x0b, 0x07, 0x04, + 0x40, 0x38, 0x08, 0x05, 0x20, 0x21, 0x09, 0x05, 0xa0, 0x0f, 0x0a, 0x05, 0xc0, 0x29, 0x0c, 0x06, 0x80, 0x18, 0x10, 0x07, 0xf0, 0x07, 0x00, 0x03, 0xf8, 0x07, 0x00, 0x03, 0x00, 0x08, 0x00, 0x03, + 0xf0, 0x02, 0x01, 0x02, 0xf4, 0x02, 0x01, 0x02, 0xf8, 0x02, 0x01, 0x02, 0xfc, 0x02, 0x01, 0x02, 0x28, 0x2c, 0x02, 0x03, 0x30, 0x2c, 0x02, 0x03, 0x38, 0x2c, 0x02, 0x03, 0xb8, 0x17, 0x03, 0x03, + 0xc0, 0x17, 0x03, 0x03, 0xc8, 0x17, 0x03, 0x03, 0xa8, 0x06, 0x04, 0x03, 0xb0, 0x06, 0x04, 0x03, 0xa0, 0x32, 0x05, 0x04, 0xb0, 0x32, 0x05, 0x04, 0x10, 0x1c, 0x06, 0x04, 0x40, 0x0b, 0x07, 0x04, + 0x60, 0x38, 0x08, 0x05, 0x40, 0x21, 0x09, 0x05, 0xc0, 0x0f, 0x0a, 0x05, 0x00, 0x2a, 0x0c, 0x06, 0x00, 0x19, 0x10, 0x07, 0x08, 0x08, 0x00, 0x03, 0x10, 0x08, 0x00, 0x03, 0x18, 0x08, 0x00, 0x03, + 0x00, 0x03, 0x01, 0x02, 0x04, 0x03, 0x01, 0x02, 0x08, 0x03, 0x01, 0x02, 0x0c, 0x03, 0x01, 0x02, 0x40, 0x2c, 0x02, 0x03, 0x48, 0x2c, 0x02, 0x03, 0x50, 0x2c, 0x02, 0x03, 0xd0, 0x17, 0x03, 0x03, + 0xd8, 0x17, 0x03, 0x03, 0xe0, 0x17, 0x03, 0x03, 0xb8, 0x06, 0x04, 0x03, 0xc0, 0x06, 0x04, 0x03, 0xc0, 0x32, 0x05, 0x04, 0xd0, 0x32, 0x05, 0x04, 0x20, 0x1c, 0x06, 0x04, 0x50, 0x0b, 0x07, 0x04, + 0x80, 0x38, 0x08, 0x05, 0x60, 0x21, 0x09, 0x05, 0xe0, 0x0f, 0x0a, 0x05, 0x40, 0x2a, 0x0c, 0x06, 0x80, 0x19, 0x10, 0x07, 0x20, 0x08, 0x00, 0x03, 0x28, 0x08, 0x00, 0x03, 0x30, 0x08, 0x00, 0x03, + 0x10, 0x03, 0x01, 0x02, 0x14, 0x03, 0x01, 0x02, 0x18, 0x03, 0x01, 0x02, 0x1c, 0x03, 0x01, 0x02, 0x58, 0x2c, 0x02, 0x03, 0x60, 0x2c, 0x02, 0x03, 0x68, 0x2c, 0x02, 0x03, 0xe8, 0x17, 0x03, 0x03, + 0xf0, 0x17, 0x03, 0x03, 0xf8, 0x17, 0x03, 0x03, 0xc8, 0x06, 0x04, 0x03, 0xd0, 0x06, 0x04, 0x03, 0xe0, 0x32, 0x05, 0x04, 0xf0, 0x32, 0x05, 0x04, 0x30, 0x1c, 0x06, 0x04, 0x60, 0x0b, 0x07, 0x04, + 0xa0, 0x38, 0x08, 0x05, 0x80, 0x21, 0x09, 0x05, 0x00, 0x10, 0x0a, 0x05, 0x80, 0x2a, 0x0c, 0x06, 0x00, 0x1a, 0x10, 0x07, 0x38, 0x08, 0x00, 0x03, 0x40, 0x08, 0x00, 0x03, 0x48, 0x08, 0x00, 0x03, + 0x20, 0x03, 0x01, 0x02, 0x24, 0x03, 0x01, 0x02, 0x28, 0x03, 0x01, 0x02, 0x2c, 0x03, 0x01, 0x02, 0x70, 0x2c, 0x02, 0x03, 0x78, 0x2c, 0x02, 0x03, 0x80, 0x2c, 0x02, 0x03, 0x00, 0x18, 0x03, 0x03, + 0x08, 0x18, 0x03, 0x03, 0x10, 0x18, 0x03, 0x03, 0xd8, 0x06, 0x04, 0x03, 0xe0, 0x06, 0x04, 0x03, 0x00, 0x33, 0x05, 0x04, 0x10, 0x33, 0x05, 0x04, 0x40, 0x1c, 0x06, 0x04, 0x70, 0x0b, 0x07, 0x04, + 0xc0, 0x38, 0x08, 0x05, 0xa0, 0x21, 0x09, 0x05, 0x20, 0x10, 0x0a, 0x05, 0xc0, 0x2a, 0x0c, 0x06, 0x80, 0x1a, 0x10, 0x07, 0x50, 0x08, 0x00, 0x03, 0x58, 0x08, 0x00, 0x03, 0x60, 0x08, 0x00, 0x03, + 0x30, 0x03, 0x01, 0x02, 0x34, 0x03, 0x01, 0x02, 0x38, 0x03, 0x01, 0x02, 0x3c, 0x03, 0x01, 0x02, 0x88, 0x2c, 0x02, 0x03, 0x90, 0x2c, 0x02, 0x03, 0x98, 0x2c, 0x02, 0x03, 0x18, 0x18, 0x03, 0x03, + 0x20, 0x18, 0x03, 0x03, 0x28, 0x18, 0x03, 0x03, 0xe8, 0x06, 0x04, 0x03, 0xf0, 0x06, 0x04, 0x03, 0x20, 0x33, 0x05, 0x04, 0x30, 0x33, 0x05, 0x04, 0x50, 0x1c, 0x06, 0x04, 0x80, 0x0b, 0x07, 0x04, + 0xe0, 0x38, 0x08, 0x05, 0xc0, 0x21, 0x09, 0x05, 0x40, 0x10, 0x0a, 0x05, 0x00, 0x2b, 0x0c, 0x06, 0x00, 0x1b, 0x10, 0x07, 0x68, 0x08, 0x00, 0x03, 0x70, 0x08, 0x00, 0x03, 0x78, 0x08, 0x00, 0x03, + 0x40, 0x03, 0x01, 0x02, 0x44, 0x03, 0x01, 0x02, 0x48, 0x03, 0x01, 0x02, 0x4c, 0x03, 0x01, 0x02, 0xa0, 0x2c, 0x02, 0x03, 0xa8, 0x2c, 0x02, 0x03, 0xb0, 0x2c, 0x02, 0x03, 0x30, 0x18, 0x03, 0x03, + 0x38, 0x18, 0x03, 0x03, 0x40, 0x18, 0x03, 0x03, 0xf8, 0x06, 0x04, 0x03, 0x00, 0x07, 0x04, 0x03, 0x40, 0x33, 0x05, 0x04, 0x50, 0x33, 0x05, 0x04, 0x60, 0x1c, 0x06, 0x04, 0x90, 0x0b, 0x07, 0x04, + 0x00, 0x39, 0x08, 0x05, 0xe0, 0x21, 0x09, 0x05, 0x60, 0x10, 0x0a, 0x05, 0x40, 0x2b, 0x0c, 0x06, 0x80, 0x1b, 0x10, 0x07, 0x80, 0x08, 0x00, 0x03, 0x88, 0x08, 0x00, 0x03, 0x90, 0x08, 0x00, 0x03, + 0x50, 0x03, 0x01, 0x02, 0x54, 0x03, 0x01, 0x02, 0x58, 0x03, 0x01, 0x02, 0x5c, 0x03, 0x01, 0x02, 0xb8, 0x2c, 0x02, 0x03, 0xc0, 0x2c, 0x02, 0x03, 0xc8, 0x2c, 0x02, 0x03, 0x48, 0x18, 0x03, 0x03, + 0x50, 0x18, 0x03, 0x03, 0x58, 0x18, 0x03, 0x03, 0x08, 0x07, 0x04, 0x03, 0x10, 0x07, 0x04, 0x03, 0x60, 0x33, 0x05, 0x04, 0x70, 0x33, 0x05, 0x04, 0x70, 0x1c, 0x06, 0x04, 0xa0, 0x0b, 0x07, 0x04, + 0x20, 0x39, 0x08, 0x05, 0x00, 0x22, 0x09, 0x05, 0x80, 0x10, 0x0a, 0x05, 0x80, 0x2b, 0x0c, 0x06, 0x00, 0x1c, 0x10, 0x07, 0x98, 0x08, 0x00, 0x03, 0xa0, 0x08, 0x00, 0x03, 0x60, 0x03, 0x01, 0x02, + 0x64, 0x03, 0x01, 0x02, 0x68, 0x03, 0x01, 0x02, 0x6c, 0x03, 0x01, 0x02, 0x70, 0x03, 0x01, 0x02, 0xd0, 0x2c, 0x02, 0x03, 0xd8, 0x2c, 0x02, 0x03, 0xe0, 0x2c, 0x02, 0x03, 0x60, 0x18, 0x03, 0x03, + 0x68, 0x18, 0x03, 0x03, 0x70, 0x18, 0x03, 0x03, 0x18, 0x07, 0x04, 0x03, 0x20, 0x07, 0x04, 0x03, 0x80, 0x33, 0x05, 0x04, 0x90, 0x33, 0x05, 0x04, 0x80, 0x1c, 0x06, 0x04, 0xb0, 0x0b, 0x07, 0x04, + 0x40, 0x39, 0x08, 0x05, 0x20, 0x22, 0x09, 0x05, 0xa0, 0x10, 0x0a, 0x05, 0xc0, 0x2b, 0x0c, 0x06, 0x80, 0x1c, 0x10, 0x07, 0xa8, 0x08, 0x00, 0x03, 0xb0, 0x08, 0x00, 0x03, 0x74, 0x03, 0x01, 0x02, + 0x78, 0x03, 0x01, 0x02, 0x7c, 0x03, 0x01, 0x02, 0x80, 0x03, 0x01, 0x02, 0x84, 0x03, 0x01, 0x02, 0xe8, 0x2c, 0x02, 0x03, 0xf0, 0x2c, 0x02, 0x03, 0xf8, 0x2c, 0x02, 0x03, 0x78, 0x18, 0x03, 0x03, + 0x80, 0x18, 0x03, 0x03, 0x88, 0x18, 0x03, 0x03, 0x28, 0x07, 0x04, 0x03, 0x30, 0x07, 0x04, 0x03, 0xa0, 0x33, 0x05, 0x04, 0xb0, 0x33, 0x05, 0x04, 0x90, 0x1c, 0x06, 0x04, 0xc0, 0x0b, 0x07, 0x04, + 0x60, 0x39, 0x08, 0x05, 0x40, 0x22, 0x09, 0x05, 0xc0, 0x10, 0x0a, 0x05, 0x00, 0x2c, 0x0c, 0x06, 0x00, 0x1d, 0x10, 0x07, 0xb8, 0x08, 0x00, 0x03, 0xc0, 0x08, 0x00, 0x03, 0x88, 0x03, 0x01, 0x02, + 0x8c, 0x03, 0x01, 0x02, 0x90, 0x03, 0x01, 0x02, 0x94, 0x03, 0x01, 0x02, 0x98, 0x03, 0x01, 0x02, 0x00, 0x2d, 0x02, 0x03, 0x08, 0x2d, 0x02, 0x03, 0x10, 0x2d, 0x02, 0x03, 0x90, 0x18, 0x03, 0x03, + 0x98, 0x18, 0x03, 0x03, 0xa0, 0x18, 0x03, 0x03, 0x38, 0x07, 0x04, 0x03, 0x40, 0x07, 0x04, 0x03, 0xc0, 0x33, 0x05, 0x04, 0xd0, 0x33, 0x05, 0x04, 0xa0, 0x1c, 0x06, 0x04, 0xd0, 0x0b, 0x07, 0x04, + 0x80, 0x39, 0x08, 0x05, 0x60, 0x22, 0x09, 0x05, 0xe0, 0x10, 0x0a, 0x05, 0x40, 0x2c, 0x0c, 0x06, 0x80, 0x1d, 0x10, 0x07, 0xc8, 0x08, 0x00, 0x03, 0xd0, 0x08, 0x00, 0x03, 0x9c, 0x03, 0x01, 0x02, + 0xa0, 0x03, 0x01, 0x02, 0xa4, 0x03, 0x01, 0x02, 0xa8, 0x03, 0x01, 0x02, 0xac, 0x03, 0x01, 0x02, 0x18, 0x2d, 0x02, 0x03, 0x20, 0x2d, 0x02, 0x03, 0x28, 0x2d, 0x02, 0x03, 0xa8, 0x18, 0x03, 0x03, + 0xb0, 0x18, 0x03, 0x03, 0xb8, 0x18, 0x03, 0x03, 0x48, 0x07, 0x04, 0x03, 0x50, 0x07, 0x04, 0x03, 0xe0, 0x33, 0x05, 0x04, 0xf0, 0x33, 0x05, 0x04, 0xb0, 0x1c, 0x06, 0x04, 0xe0, 0x0b, 0x07, 0x04, + 0xa0, 0x39, 0x08, 0x05, 0x80, 0x22, 0x09, 0x05, 0x00, 0x11, 0x0a, 0x05, 0x80, 0x2c, 0x0c, 0x06, 0x00, 0x1e, 0x10, 0x07, 0xd8, 0x08, 0x00, 0x03, 0xe0, 0x08, 0x00, 0x03, 0xb0, 0x03, 0x01, 0x02, + 0xb4, 0x03, 0x01, 0x02, 0xb8, 0x03, 0x01, 0x02, 0xbc, 0x03, 0x01, 0x02, 0xc0, 0x03, 0x01, 0x02, 0x30, 0x2d, 0x02, 0x03, 0x38, 0x2d, 0x02, 0x03, 0x40, 0x2d, 0x02, 0x03, 0xc0, 0x18, 0x03, 0x03, + 0xc8, 0x18, 0x03, 0x03, 0xd0, 0x18, 0x03, 0x03, 0x58, 0x07, 0x04, 0x03, 0x60, 0x07, 0x04, 0x03, 0x00, 0x34, 0x05, 0x04, 0x10, 0x34, 0x05, 0x04, 0xc0, 0x1c, 0x06, 0x04, 0xf0, 0x0b, 0x07, 0x04, + 0xc0, 0x39, 0x08, 0x05, 0xa0, 0x22, 0x09, 0x05, 0x20, 0x11, 0x0a, 0x05, 0xc0, 0x2c, 0x0c, 0x06, 0x80, 0x05, 0x11, 0x07, 0xe8, 0x08, 0x00, 0x03, 0xf0, 0x08, 0x00, 0x03, 0xc4, 0x03, 0x01, 0x02, + 0xc8, 0x03, 0x01, 0x02, 0xcc, 0x03, 0x01, 0x02, 0xd0, 0x03, 0x01, 0x02, 0xd4, 0x03, 0x01, 0x02, 0x48, 0x2d, 0x02, 0x03, 0x50, 0x2d, 0x02, 0x03, 0x58, 0x2d, 0x02, 0x03, 0xd8, 0x18, 0x03, 0x03, + 0xe0, 0x18, 0x03, 0x03, 0xe8, 0x18, 0x03, 0x03, 0x68, 0x07, 0x04, 0x03, 0x70, 0x07, 0x04, 0x03, 0x20, 0x34, 0x05, 0x04, 0x30, 0x34, 0x05, 0x04, 0xd0, 0x1c, 0x06, 0x04, 0x00, 0x0c, 0x07, 0x04, + 0xe0, 0x39, 0x08, 0x05, 0xc0, 0x22, 0x09, 0x05, 0x40, 0x11, 0x0a, 0x05, 0x00, 0x2d, 0x0c, 0x06, 0x00, 0x06, 0x11, 0x07, 0xf8, 0x08, 0x00, 0x03, 0x00, 0x09, 0x00, 0x03, 0xd8, 0x03, 0x01, 0x02, + 0xdc, 0x03, 0x01, 0x02, 0xe0, 0x03, 0x01, 0x02, 0xe4, 0x03, 0x01, 0x02, 0xe8, 0x03, 0x01, 0x02, 0x60, 0x2d, 0x02, 0x03, 0x68, 0x2d, 0x02, 0x03, 0x70, 0x2d, 0x02, 0x03, 0xf0, 0x18, 0x03, 0x03, + 0xf8, 0x18, 0x03, 0x03, 0x00, 0x19, 0x03, 0x03, 0x78, 0x07, 0x04, 0x03, 0x80, 0x07, 0x04, 0x03, 0x40, 0x34, 0x05, 0x04, 0x50, 0x34, 0x05, 0x04, 0xe0, 0x1c, 0x06, 0x04, 0x10, 0x0c, 0x07, 0x04, + 0x00, 0x3a, 0x08, 0x05, 0xe0, 0x22, 0x09, 0x05, 0x60, 0x11, 0x0a, 0x05, 0x00, 0x12, 0x0d, 0x06, 0x80, 0x06, 0x11, 0x07, 0x08, 0x09, 0x00, 0x03, 0x10, 0x09, 0x00, 0x03, 0xec, 0x03, 0x01, 0x02, + 0xf0, 0x03, 0x01, 0x02, 0xf4, 0x03, 0x01, 0x02, 0xf8, 0x03, 0x01, 0x02, 0xfc, 0x03, 0x01, 0x02, 0x78, 0x2d, 0x02, 0x03, 0x80, 0x2d, 0x02, 0x03, 0x88, 0x2d, 0x02, 0x03, 0x08, 0x19, 0x03, 0x03, + 0x10, 0x19, 0x03, 0x03, 0x18, 0x19, 0x03, 0x03, 0x88, 0x07, 0x04, 0x03, 0x90, 0x07, 0x04, 0x03, 0x60, 0x34, 0x05, 0x04, 0x70, 0x34, 0x05, 0x04, 0xf0, 0x1c, 0x06, 0x04, 0x20, 0x0c, 0x07, 0x04, + 0x20, 0x3a, 0x08, 0x05, 0x00, 0x23, 0x09, 0x05, 0x80, 0x11, 0x0a, 0x05, 0x40, 0x12, 0x0d, 0x06, 0x00, 0x07, 0x11, 0x07, 0x18, 0x09, 0x00, 0x03, 0x20, 0x09, 0x00, 0x03, 0x00, 0x04, 0x01, 0x02, + 0x04, 0x04, 0x01, 0x02, 0x08, 0x04, 0x01, 0x02, 0x0c, 0x04, 0x01, 0x02, 0x10, 0x04, 0x01, 0x02, 0x90, 0x2d, 0x02, 0x03, 0x98, 0x2d, 0x02, 0x03, 0xa0, 0x2d, 0x02, 0x03, 0x20, 0x19, 0x03, 0x03, + 0x28, 0x19, 0x03, 0x03, 0x30, 0x19, 0x03, 0x03, 0x98, 0x07, 0x04, 0x03, 0xa0, 0x07, 0x04, 0x03, 0x80, 0x34, 0x05, 0x04, 0x90, 0x34, 0x05, 0x04, 0x00, 0x1d, 0x06, 0x04, 0x30, 0x0c, 0x07, 0x04, + 0x40, 0x3a, 0x08, 0x05, 0x20, 0x23, 0x09, 0x05, 0xa0, 0x11, 0x0a, 0x05, 0x80, 0x12, 0x0d, 0x06, 0x80, 0x07, 0x11, 0x07, 0x28, 0x09, 0x00, 0x03, 0x30, 0x09, 0x00, 0x03, 0x14, 0x04, 0x01, 0x02, + 0x18, 0x04, 0x01, 0x02, 0x1c, 0x04, 0x01, 0x02, 0x20, 0x04, 0x01, 0x02, 0x24, 0x04, 0x01, 0x02, 0xa8, 0x2d, 0x02, 0x03, 0xb0, 0x2d, 0x02, 0x03, 0xb8, 0x2d, 0x02, 0x03, 0x38, 0x19, 0x03, 0x03, + 0x40, 0x19, 0x03, 0x03, 0x48, 0x19, 0x03, 0x03, 0xa8, 0x07, 0x04, 0x03, 0xb0, 0x07, 0x04, 0x03, 0xa0, 0x34, 0x05, 0x04, 0xb0, 0x34, 0x05, 0x04, 0x10, 0x1d, 0x06, 0x04, 0x40, 0x0c, 0x07, 0x04, + 0x60, 0x3a, 0x08, 0x05, 0x40, 0x23, 0x09, 0x05, 0xc0, 0x11, 0x0a, 0x05, 0xc0, 0x12, 0x0d, 0x06, 0x00, 0x08, 0x11, 0x07, 0x38, 0x09, 0x00, 0x03, 0x40, 0x09, 0x00, 0x03, 0x28, 0x04, 0x01, 0x02, + 0x2c, 0x04, 0x01, 0x02, 0x30, 0x04, 0x01, 0x02, 0x34, 0x04, 0x01, 0x02, 0x38, 0x04, 0x01, 0x02, 0xc0, 0x2d, 0x02, 0x03, 0xc8, 0x2d, 0x02, 0x03, 0xd0, 0x2d, 0x02, 0x03, 0x50, 0x19, 0x03, 0x03, + 0x58, 0x19, 0x03, 0x03, 0x60, 0x19, 0x03, 0x03, 0xb8, 0x07, 0x04, 0x03, 0xc0, 0x07, 0x04, 0x03, 0xc0, 0x34, 0x05, 0x04, 0xd0, 0x34, 0x05, 0x04, 0x20, 0x1d, 0x06, 0x04, 0x50, 0x0c, 0x07, 0x04, + 0x80, 0x3a, 0x08, 0x05, 0x60, 0x23, 0x09, 0x05, 0xe0, 0x11, 0x0a, 0x05, 0x00, 0x13, 0x0d, 0x06, 0x80, 0x08, 0x11, 0x07, 0x48, 0x09, 0x00, 0x03, 0x50, 0x09, 0x00, 0x03, 0x3c, 0x04, 0x01, 0x02, + 0x40, 0x04, 0x01, 0x02, 0x44, 0x04, 0x01, 0x02, 0x48, 0x04, 0x01, 0x02, 0x4c, 0x04, 0x01, 0x02, 0xd8, 0x2d, 0x02, 0x03, 0xe0, 0x2d, 0x02, 0x03, 0xe8, 0x2d, 0x02, 0x03, 0x68, 0x19, 0x03, 0x03, + 0x70, 0x19, 0x03, 0x03, 0x78, 0x19, 0x03, 0x03, 0xc8, 0x07, 0x04, 0x03, 0xd0, 0x07, 0x04, 0x03, 0xe0, 0x34, 0x05, 0x04, 0xf0, 0x34, 0x05, 0x04, 0x30, 0x1d, 0x06, 0x04, 0x60, 0x0c, 0x07, 0x04, + 0xa0, 0x3a, 0x08, 0x05, 0x80, 0x23, 0x09, 0x05, 0x00, 0x12, 0x0a, 0x05, 0x40, 0x13, 0x0d, 0x06, 0x00, 0x09, 0x11, 0x07, 0x58, 0x09, 0x00, 0x03, 0x60, 0x09, 0x00, 0x03, 0x50, 0x04, 0x01, 0x02, + 0x54, 0x04, 0x01, 0x02, 0x58, 0x04, 0x01, 0x02, 0x5c, 0x04, 0x01, 0x02, 0x60, 0x04, 0x01, 0x02, 0xf0, 0x2d, 0x02, 0x03, 0xf8, 0x2d, 0x02, 0x03, 0x00, 0x2e, 0x02, 0x03, 0x80, 0x19, 0x03, 0x03, + 0x88, 0x19, 0x03, 0x03, 0x90, 0x19, 0x03, 0x03, 0xd8, 0x07, 0x04, 0x03, 0xe0, 0x07, 0x04, 0x03, 0x00, 0x35, 0x05, 0x04, 0x10, 0x35, 0x05, 0x04, 0x40, 0x1d, 0x06, 0x04, 0x70, 0x0c, 0x07, 0x04, + 0xc0, 0x3a, 0x08, 0x05, 0xa0, 0x23, 0x09, 0x05, 0x20, 0x12, 0x0a, 0x05, 0x80, 0x13, 0x0d, 0x06, 0x80, 0x09, 0x11, 0x07, 0x68, 0x09, 0x00, 0x03, 0x70, 0x09, 0x00, 0x03, 0x64, 0x04, 0x01, 0x02, + 0x68, 0x04, 0x01, 0x02, 0x6c, 0x04, 0x01, 0x02, 0x70, 0x04, 0x01, 0x02, 0x74, 0x04, 0x01, 0x02, 0x08, 0x2e, 0x02, 0x03, 0x10, 0x2e, 0x02, 0x03, 0x18, 0x2e, 0x02, 0x03, 0x98, 0x19, 0x03, 0x03, + 0xa0, 0x19, 0x03, 0x03, 0xa8, 0x19, 0x03, 0x03, 0xe8, 0x07, 0x04, 0x03, 0xf0, 0x07, 0x04, 0x03, 0x20, 0x35, 0x05, 0x04, 0x30, 0x35, 0x05, 0x04, 0x50, 0x1d, 0x06, 0x04, 0x80, 0x0c, 0x07, 0x04, + 0xe0, 0x3a, 0x08, 0x05, 0xc0, 0x23, 0x09, 0x05, 0x40, 0x12, 0x0a, 0x05, 0xc0, 0x13, 0x0d, 0x06, 0x00, 0x0a, 0x11, 0x07, 0x78, 0x09, 0x00, 0x03, 0x80, 0x09, 0x00, 0x03, 0x78, 0x04, 0x01, 0x02, + 0x7c, 0x04, 0x01, 0x02, 0x80, 0x04, 0x01, 0x02, 0x84, 0x04, 0x01, 0x02, 0x88, 0x04, 0x01, 0x02, 0x20, 0x2e, 0x02, 0x03, 0x28, 0x2e, 0x02, 0x03, 0x30, 0x2e, 0x02, 0x03, 0xb0, 0x19, 0x03, 0x03, + 0xb8, 0x19, 0x03, 0x03, 0xc0, 0x19, 0x03, 0x03, 0xf8, 0x07, 0x04, 0x03, 0x00, 0x08, 0x04, 0x03, 0x40, 0x35, 0x05, 0x04, 0x50, 0x35, 0x05, 0x04, 0x60, 0x1d, 0x06, 0x04, 0x90, 0x0c, 0x07, 0x04, + 0x00, 0x3b, 0x08, 0x05, 0xe0, 0x23, 0x09, 0x05, 0x60, 0x12, 0x0a, 0x05, 0x00, 0x14, 0x0d, 0x06, 0x80, 0x0a, 0x11, 0x07, 0x88, 0x09, 0x00, 0x03, 0x90, 0x09, 0x00, 0x03, 0x8c, 0x04, 0x01, 0x02, + 0x90, 0x04, 0x01, 0x02, 0x94, 0x04, 0x01, 0x02, 0x98, 0x04, 0x01, 0x02, 0x38, 0x2e, 0x02, 0x03, 0x40, 0x2e, 0x02, 0x03, 0x48, 0x2e, 0x02, 0x03, 0x50, 0x2e, 0x02, 0x03, 0xc8, 0x19, 0x03, 0x03, + 0xd0, 0x19, 0x03, 0x03, 0xd8, 0x19, 0x03, 0x03, 0x08, 0x08, 0x04, 0x03, 0x10, 0x08, 0x04, 0x03, 0x60, 0x35, 0x05, 0x04, 0x70, 0x35, 0x05, 0x04, 0x70, 0x1d, 0x06, 0x04, 0xa0, 0x0c, 0x07, 0x04, + 0x20, 0x3b, 0x08, 0x05, 0x00, 0x24, 0x09, 0x05, 0xc0, 0x3d, 0x0b, 0x06, 0x40, 0x14, 0x0d, 0x06, 0x00, 0x0b, 0x11, 0x07, 0x98, 0x09, 0x00, 0x03, 0xa0, 0x09, 0x00, 0x03, 0x9c, 0x04, 0x01, 0x02, + 0xa0, 0x04, 0x01, 0x02, 0xa4, 0x04, 0x01, 0x02, 0xa8, 0x04, 0x01, 0x02, 0x58, 0x2e, 0x02, 0x03, 0x60, 0x2e, 0x02, 0x03, 0x68, 0x2e, 0x02, 0x03, 0x70, 0x2e, 0x02, 0x03, 0xe0, 0x19, 0x03, 0x03, + 0xe8, 0x19, 0x03, 0x03, 0xf0, 0x19, 0x03, 0x03, 0x18, 0x08, 0x04, 0x03, 0x20, 0x08, 0x04, 0x03, 0x80, 0x35, 0x05, 0x04, 0x90, 0x35, 0x05, 0x04, 0x80, 0x1d, 0x06, 0x04, 0xb0, 0x0c, 0x07, 0x04, + 0x40, 0x3b, 0x08, 0x05, 0x20, 0x24, 0x09, 0x05, 0x00, 0x3e, 0x0b, 0x06, 0x80, 0x14, 0x0d, 0x06, 0x00, 0x32, 0x12, 0x08, 0xa8, 0x09, 0x00, 0x03, 0xb0, 0x09, 0x00, 0x03, 0xac, 0x04, 0x01, 0x02, + 0xb0, 0x04, 0x01, 0x02, 0xb4, 0x04, 0x01, 0x02, 0xb8, 0x04, 0x01, 0x02, 0x78, 0x2e, 0x02, 0x03, 0x80, 0x2e, 0x02, 0x03, 0x88, 0x2e, 0x02, 0x03, 0x90, 0x2e, 0x02, 0x03, 0xf8, 0x19, 0x03, 0x03, + 0x00, 0x1a, 0x03, 0x03, 0x08, 0x1a, 0x03, 0x03, 0x28, 0x08, 0x04, 0x03, 0x30, 0x08, 0x04, 0x03, 0xa0, 0x35, 0x05, 0x04, 0xb0, 0x35, 0x05, 0x04, 0x90, 0x1d, 0x06, 0x04, 0xc0, 0x0c, 0x07, 0x04, + 0x60, 0x3b, 0x08, 0x05, 0x40, 0x24, 0x09, 0x05, 0x40, 0x3e, 0x0b, 0x06, 0xc0, 0x14, 0x0d, 0x06, 0x00, 0x33, 0x12, 0x08, 0xb8, 0x09, 0x00, 0x03, 0xc0, 0x09, 0x00, 0x03, 0xbc, 0x04, 0x01, 0x02, + 0xc0, 0x04, 0x01, 0x02, 0xc4, 0x04, 0x01, 0x02, 0xc8, 0x04, 0x01, 0x02, 0x98, 0x2e, 0x02, 0x03, 0xa0, 0x2e, 0x02, 0x03, 0xa8, 0x2e, 0x02, 0x03, 0xb0, 0x2e, 0x02, 0x03, 0x10, 0x1a, 0x03, 0x03, + 0x18, 0x1a, 0x03, 0x03, 0x20, 0x1a, 0x03, 0x03, 0x38, 0x08, 0x04, 0x03, 0x40, 0x08, 0x04, 0x03, 0xc0, 0x35, 0x05, 0x04, 0xd0, 0x35, 0x05, 0x04, 0xa0, 0x1d, 0x06, 0x04, 0xd0, 0x0c, 0x07, 0x04, + 0x80, 0x3b, 0x08, 0x05, 0x60, 0x24, 0x09, 0x05, 0x80, 0x3e, 0x0b, 0x06, 0x00, 0x15, 0x0d, 0x06, 0x00, 0x34, 0x12, 0x08, 0xc8, 0x09, 0x00, 0x03, 0xd0, 0x09, 0x00, 0x03, 0xcc, 0x04, 0x01, 0x02, + 0xd0, 0x04, 0x01, 0x02, 0xd4, 0x04, 0x01, 0x02, 0xd8, 0x04, 0x01, 0x02, 0xb8, 0x2e, 0x02, 0x03, 0xc0, 0x2e, 0x02, 0x03, 0xc8, 0x2e, 0x02, 0x03, 0xd0, 0x2e, 0x02, 0x03, 0x28, 0x1a, 0x03, 0x03, + 0x30, 0x1a, 0x03, 0x03, 0x38, 0x1a, 0x03, 0x03, 0x48, 0x08, 0x04, 0x03, 0x50, 0x08, 0x04, 0x03, 0xe0, 0x35, 0x05, 0x04, 0xf0, 0x35, 0x05, 0x04, 0xb0, 0x1d, 0x06, 0x04, 0xe0, 0x0c, 0x07, 0x04, + 0xa0, 0x3b, 0x08, 0x05, 0x80, 0x24, 0x09, 0x05, 0xc0, 0x3e, 0x0b, 0x06, 0x40, 0x15, 0x0d, 0x06, 0x00, 0x35, 0x12, 0x08, 0xd8, 0x09, 0x00, 0x03, 0xe0, 0x09, 0x00, 0x03, 0xdc, 0x04, 0x01, 0x02, + 0xe0, 0x04, 0x01, 0x02, 0xe4, 0x04, 0x01, 0x02, 0xe8, 0x04, 0x01, 0x02, 0xd8, 0x2e, 0x02, 0x03, 0xe0, 0x2e, 0x02, 0x03, 0xe8, 0x2e, 0x02, 0x03, 0xf0, 0x2e, 0x02, 0x03, 0x40, 0x1a, 0x03, 0x03, + 0x48, 0x1a, 0x03, 0x03, 0x50, 0x1a, 0x03, 0x03, 0x58, 0x08, 0x04, 0x03, 0x60, 0x08, 0x04, 0x03, 0x00, 0x36, 0x05, 0x04, 0x10, 0x36, 0x05, 0x04, 0xc0, 0x1d, 0x06, 0x04, 0xf0, 0x0c, 0x07, 0x04, + 0xc0, 0x3b, 0x08, 0x05, 0xa0, 0x24, 0x09, 0x05, 0x00, 0x3f, 0x0b, 0x06, 0x80, 0x15, 0x0d, 0x06, 0x00, 0x36, 0x12, 0x08, 0xe8, 0x09, 0x00, 0x03, 0xf0, 0x09, 0x00, 0x03, 0xec, 0x04, 0x01, 0x02, + 0xf0, 0x04, 0x01, 0x02, 0xf4, 0x04, 0x01, 0x02, 0xf8, 0x04, 0x01, 0x02, 0xf8, 0x2e, 0x02, 0x03, 0x00, 0x2f, 0x02, 0x03, 0x08, 0x2f, 0x02, 0x03, 0x10, 0x2f, 0x02, 0x03, 0x58, 0x1a, 0x03, 0x03, + 0x60, 0x1a, 0x03, 0x03, 0x68, 0x1a, 0x03, 0x03, 0x68, 0x08, 0x04, 0x03, 0x70, 0x08, 0x04, 0x03, 0x20, 0x36, 0x05, 0x04, 0x30, 0x36, 0x05, 0x04, 0xd0, 0x1d, 0x06, 0x04, 0x00, 0x0d, 0x07, 0x04, + 0xe0, 0x3b, 0x08, 0x05, 0xc0, 0x24, 0x09, 0x05, 0x40, 0x3f, 0x0b, 0x06, 0xc0, 0x15, 0x0d, 0x06, 0x00, 0x37, 0x12, 0x08, 0xf8, 0x09, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x03, 0xfc, 0x04, 0x01, 0x02, + 0x00, 0x05, 0x01, 0x02, 0x04, 0x05, 0x01, 0x02, 0x08, 0x05, 0x01, 0x02, 0x18, 0x2f, 0x02, 0x03, 0x20, 0x2f, 0x02, 0x03, 0x28, 0x2f, 0x02, 0x03, 0x30, 0x2f, 0x02, 0x03, 0x70, 0x1a, 0x03, 0x03, + 0x78, 0x1a, 0x03, 0x03, 0x80, 0x1a, 0x03, 0x03, 0x78, 0x08, 0x04, 0x03, 0x80, 0x08, 0x04, 0x03, 0x40, 0x36, 0x05, 0x04, 0xe0, 0x1d, 0x06, 0x04, 0xf0, 0x1d, 0x06, 0x04, 0x10, 0x0d, 0x07, 0x04, + 0x00, 0x3c, 0x08, 0x05, 0xe0, 0x24, 0x09, 0x05, 0x80, 0x3f, 0x0b, 0x06, 0x00, 0x16, 0x0d, 0x06, 0x00, 0x38, 0x12, 0x08, 0x08, 0x0a, 0x00, 0x03, 0x10, 0x0a, 0x00, 0x03, 0x0c, 0x05, 0x01, 0x02, + 0x10, 0x05, 0x01, 0x02, 0x14, 0x05, 0x01, 0x02, 0x18, 0x05, 0x01, 0x02, 0x38, 0x2f, 0x02, 0x03, 0x40, 0x2f, 0x02, 0x03, 0x48, 0x2f, 0x02, 0x03, 0x50, 0x2f, 0x02, 0x03, 0x88, 0x1a, 0x03, 0x03, + 0x90, 0x1a, 0x03, 0x03, 0x88, 0x08, 0x04, 0x03, 0x90, 0x08, 0x04, 0x03, 0x98, 0x08, 0x04, 0x03, 0x50, 0x36, 0x05, 0x04, 0x00, 0x1e, 0x06, 0x04, 0x10, 0x1e, 0x06, 0x04, 0x20, 0x0d, 0x07, 0x04, + 0x20, 0x3c, 0x08, 0x05, 0x00, 0x25, 0x09, 0x05, 0xc0, 0x3f, 0x0b, 0x06, 0x40, 0x16, 0x0d, 0x06, 0x00, 0x39, 0x12, 0x08, 0x18, 0x0a, 0x00, 0x03, 0x20, 0x0a, 0x00, 0x03, 0x1c, 0x05, 0x01, 0x02, + 0x20, 0x05, 0x01, 0x02, 0x24, 0x05, 0x01, 0x02, 0x28, 0x05, 0x01, 0x02, 0x58, 0x2f, 0x02, 0x03, 0x60, 0x2f, 0x02, 0x03, 0x68, 0x2f, 0x02, 0x03, 0x70, 0x2f, 0x02, 0x03, 0x98, 0x1a, 0x03, 0x03, + 0xa0, 0x1a, 0x03, 0x03, 0xa0, 0x08, 0x04, 0x03, 0xa8, 0x08, 0x04, 0x03, 0xb0, 0x08, 0x04, 0x03, 0x60, 0x36, 0x05, 0x04, 0x20, 0x1e, 0x06, 0x04, 0x30, 0x1e, 0x06, 0x04, 0x30, 0x0d, 0x07, 0x04, + 0x40, 0x3c, 0x08, 0x05, 0x20, 0x25, 0x09, 0x05, 0x00, 0x00, 0x0b, 0x05, 0x80, 0x16, 0x0d, 0x06, 0x00, 0x3a, 0x12, 0x08, 0x28, 0x0a, 0x00, 0x03, 0x30, 0x0a, 0x00, 0x03, 0x2c, 0x05, 0x01, 0x02, + 0x30, 0x05, 0x01, 0x02, 0x34, 0x05, 0x01, 0x02, 0x38, 0x05, 0x01, 0x02, 0x78, 0x2f, 0x02, 0x03, 0x80, 0x2f, 0x02, 0x03, 0x88, 0x2f, 0x02, 0x03, 0x90, 0x2f, 0x02, 0x03, 0xa8, 0x1a, 0x03, 0x03, + 0xb0, 0x1a, 0x03, 0x03, 0xb8, 0x08, 0x04, 0x03, 0xc0, 0x08, 0x04, 0x03, 0xc8, 0x08, 0x04, 0x03, 0x70, 0x36, 0x05, 0x04, 0x40, 0x1e, 0x06, 0x04, 0x50, 0x1e, 0x06, 0x04, 0x40, 0x0d, 0x07, 0x04, + 0x60, 0x3c, 0x08, 0x05, 0x40, 0x25, 0x09, 0x05, 0x20, 0x00, 0x0b, 0x05, 0xc0, 0x16, 0x0d, 0x06, 0x00, 0x1b, 0x13, 0x08, 0x38, 0x0a, 0x00, 0x03, 0x40, 0x0a, 0x00, 0x03, 0x3c, 0x05, 0x01, 0x02, + 0x40, 0x05, 0x01, 0x02, 0x44, 0x05, 0x01, 0x02, 0x48, 0x05, 0x01, 0x02, 0x98, 0x2f, 0x02, 0x03, 0xa0, 0x2f, 0x02, 0x03, 0xa8, 0x2f, 0x02, 0x03, 0xb0, 0x2f, 0x02, 0x03, 0xb8, 0x1a, 0x03, 0x03, + 0xc0, 0x1a, 0x03, 0x03, 0xd0, 0x08, 0x04, 0x03, 0xd8, 0x08, 0x04, 0x03, 0xe0, 0x08, 0x04, 0x03, 0x80, 0x36, 0x05, 0x04, 0x60, 0x1e, 0x06, 0x04, 0x70, 0x1e, 0x06, 0x04, 0x50, 0x0d, 0x07, 0x04, + 0x80, 0x3c, 0x08, 0x05, 0x60, 0x25, 0x09, 0x05, 0x40, 0x00, 0x0b, 0x05, 0x00, 0x17, 0x0d, 0x06, 0x00, 0x1c, 0x13, 0x08, 0x48, 0x0a, 0x00, 0x03, 0x50, 0x0a, 0x00, 0x03, 0x4c, 0x05, 0x01, 0x02, + 0x50, 0x05, 0x01, 0x02, 0x54, 0x05, 0x01, 0x02, 0x58, 0x05, 0x01, 0x02, 0xb8, 0x2f, 0x02, 0x03, 0xc0, 0x2f, 0x02, 0x03, 0xc8, 0x2f, 0x02, 0x03, 0xd0, 0x2f, 0x02, 0x03, 0xc8, 0x1a, 0x03, 0x03, + 0xd0, 0x1a, 0x03, 0x03, 0xe8, 0x08, 0x04, 0x03, 0xf0, 0x08, 0x04, 0x03, 0xf8, 0x08, 0x04, 0x03, 0x90, 0x36, 0x05, 0x04, 0x80, 0x1e, 0x06, 0x04, 0x90, 0x1e, 0x06, 0x04, 0x60, 0x0d, 0x07, 0x04, + 0xa0, 0x3c, 0x08, 0x05, 0x80, 0x25, 0x09, 0x05, 0x60, 0x00, 0x0b, 0x05, 0x40, 0x17, 0x0d, 0x06, 0x00, 0x1d, 0x13, 0x08, 0x58, 0x0a, 0x00, 0x03, 0x60, 0x0a, 0x00, 0x03, 0x5c, 0x05, 0x01, 0x02, + 0x60, 0x05, 0x01, 0x02, 0x64, 0x05, 0x01, 0x02, 0x68, 0x05, 0x01, 0x02, 0xd8, 0x2f, 0x02, 0x03, 0xe0, 0x2f, 0x02, 0x03, 0xe8, 0x2f, 0x02, 0x03, 0xf0, 0x2f, 0x02, 0x03, 0xd8, 0x1a, 0x03, 0x03, + 0xe0, 0x1a, 0x03, 0x03, 0x00, 0x09, 0x04, 0x03, 0x08, 0x09, 0x04, 0x03, 0x10, 0x09, 0x04, 0x03, 0xa0, 0x36, 0x05, 0x04, 0xa0, 0x1e, 0x06, 0x04, 0xb0, 0x1e, 0x06, 0x04, 0x70, 0x0d, 0x07, 0x04, + 0xc0, 0x3c, 0x08, 0x05, 0xa0, 0x25, 0x09, 0x05, 0x80, 0x00, 0x0b, 0x05, 0x80, 0x17, 0x0d, 0x06, 0x00, 0x1e, 0x13, 0x08, 0x68, 0x0a, 0x00, 0x03, 0x70, 0x0a, 0x00, 0x03, 0x6c, 0x05, 0x01, 0x02, + 0x70, 0x05, 0x01, 0x02, 0x74, 0x05, 0x01, 0x02, 0x78, 0x05, 0x01, 0x02, 0xf8, 0x2f, 0x02, 0x03, 0x00, 0x30, 0x02, 0x03, 0x08, 0x30, 0x02, 0x03, 0x10, 0x30, 0x02, 0x03, 0xe8, 0x1a, 0x03, 0x03, + 0xf0, 0x1a, 0x03, 0x03, 0x18, 0x09, 0x04, 0x03, 0x20, 0x09, 0x04, 0x03, 0x28, 0x09, 0x04, 0x03, 0xb0, 0x36, 0x05, 0x04, 0xc0, 0x1e, 0x06, 0x04, 0xd0, 0x1e, 0x06, 0x04, 0x80, 0x0d, 0x07, 0x04, + 0xe0, 0x3c, 0x08, 0x05, 0xc0, 0x25, 0x09, 0x05, 0xa0, 0x00, 0x0b, 0x05, 0xc0, 0x17, 0x0d, 0x06, 0x00, 0x1f, 0x13, 0x08, 0x78, 0x0a, 0x00, 0x03, 0x80, 0x0a, 0x00, 0x03, 0x7c, 0x05, 0x01, 0x02, + 0x80, 0x05, 0x01, 0x02, 0x84, 0x05, 0x01, 0x02, 0x88, 0x05, 0x01, 0x02, 0x18, 0x30, 0x02, 0x03, 0x20, 0x30, 0x02, 0x03, 0x28, 0x30, 0x02, 0x03, 0x30, 0x30, 0x02, 0x03, 0xf8, 0x1a, 0x03, 0x03, + 0x00, 0x1b, 0x03, 0x03, 0x30, 0x09, 0x04, 0x03, 0x38, 0x09, 0x04, 0x03, 0x40, 0x09, 0x04, 0x03, 0xc0, 0x36, 0x05, 0x04, 0xe0, 0x1e, 0x06, 0x04, 0xf0, 0x1e, 0x06, 0x04, 0x90, 0x0d, 0x07, 0x04, + 0x00, 0x3d, 0x08, 0x05, 0xe0, 0x25, 0x09, 0x05, 0xc0, 0x00, 0x0b, 0x05, 0x00, 0x18, 0x0d, 0x06, 0x00, 0x20, 0x13, 0x08, 0x88, 0x0a, 0x00, 0x03, 0x90, 0x0a, 0x00, 0x03, 0x8c, 0x05, 0x01, 0x02, + 0x90, 0x05, 0x01, 0x02, 0x94, 0x05, 0x01, 0x02, 0x98, 0x05, 0x01, 0x02, 0x38, 0x30, 0x02, 0x03, 0x40, 0x30, 0x02, 0x03, 0x48, 0x30, 0x02, 0x03, 0x50, 0x30, 0x02, 0x03, 0x08, 0x1b, 0x03, 0x03, + 0x10, 0x1b, 0x03, 0x03, 0x48, 0x09, 0x04, 0x03, 0x50, 0x09, 0x04, 0x03, 0x58, 0x09, 0x04, 0x03, 0xd0, 0x36, 0x05, 0x04, 0x00, 0x1f, 0x06, 0x04, 0x10, 0x1f, 0x06, 0x04, 0xa0, 0x0d, 0x07, 0x04, + 0x20, 0x3d, 0x08, 0x05, 0x00, 0x26, 0x09, 0x05, 0xe0, 0x00, 0x0b, 0x05, 0x40, 0x18, 0x0d, 0x06, 0x00, 0x21, 0x13, 0x08, 0x98, 0x0a, 0x00, 0x03, 0xa0, 0x0a, 0x00, 0x03, 0x9c, 0x05, 0x01, 0x02, + 0xa0, 0x05, 0x01, 0x02, 0xa4, 0x05, 0x01, 0x02, 0xa8, 0x05, 0x01, 0x02, 0x58, 0x30, 0x02, 0x03, 0x60, 0x30, 0x02, 0x03, 0x68, 0x30, 0x02, 0x03, 0x70, 0x30, 0x02, 0x03, 0x18, 0x1b, 0x03, 0x03, + 0x20, 0x1b, 0x03, 0x03, 0x60, 0x09, 0x04, 0x03, 0x68, 0x09, 0x04, 0x03, 0x70, 0x09, 0x04, 0x03, 0xe0, 0x36, 0x05, 0x04, 0x20, 0x1f, 0x06, 0x04, 0x30, 0x1f, 0x06, 0x04, 0xb0, 0x0d, 0x07, 0x04, + 0x40, 0x3d, 0x08, 0x05, 0x20, 0x26, 0x09, 0x05, 0x00, 0x01, 0x0b, 0x05, 0x80, 0x18, 0x0d, 0x06, 0x00, 0x22, 0x13, 0x08, 0xa8, 0x0a, 0x00, 0x03, 0xb0, 0x0a, 0x00, 0x03, 0xac, 0x05, 0x01, 0x02, + 0xb0, 0x05, 0x01, 0x02, 0xb4, 0x05, 0x01, 0x02, 0xb8, 0x05, 0x01, 0x02, 0x78, 0x30, 0x02, 0x03, 0x80, 0x30, 0x02, 0x03, 0x88, 0x30, 0x02, 0x03, 0x90, 0x30, 0x02, 0x03, 0x28, 0x1b, 0x03, 0x03, + 0x30, 0x1b, 0x03, 0x03, 0x78, 0x09, 0x04, 0x03, 0x80, 0x09, 0x04, 0x03, 0x88, 0x09, 0x04, 0x03, 0xf0, 0x36, 0x05, 0x04, 0x40, 0x1f, 0x06, 0x04, 0x50, 0x1f, 0x06, 0x04, 0xc0, 0x0d, 0x07, 0x04, + 0x60, 0x3d, 0x08, 0x05, 0x40, 0x26, 0x09, 0x05, 0x20, 0x01, 0x0b, 0x05, 0xc0, 0x18, 0x0d, 0x06, 0x00, 0x0a, 0x14, 0x08, 0xb8, 0x0a, 0x00, 0x03, 0xc0, 0x0a, 0x00, 0x03, 0xbc, 0x05, 0x01, 0x02, + 0xc0, 0x05, 0x01, 0x02, 0xc4, 0x05, 0x01, 0x02, 0xc8, 0x05, 0x01, 0x02, 0x98, 0x30, 0x02, 0x03, 0xa0, 0x30, 0x02, 0x03, 0xa8, 0x30, 0x02, 0x03, 0xb0, 0x30, 0x02, 0x03, 0x38, 0x1b, 0x03, 0x03, + 0x40, 0x1b, 0x03, 0x03, 0x90, 0x09, 0x04, 0x03, 0x98, 0x09, 0x04, 0x03, 0xa0, 0x09, 0x04, 0x03, 0x00, 0x37, 0x05, 0x04, 0x60, 0x1f, 0x06, 0x04, 0x70, 0x1f, 0x06, 0x04, 0xd0, 0x0d, 0x07, 0x04, + 0x80, 0x3d, 0x08, 0x05, 0x60, 0x26, 0x09, 0x05, 0x40, 0x01, 0x0b, 0x05, 0x40, 0x02, 0x0e, 0x06, 0x00, 0x0b, 0x14, 0x08, 0xc8, 0x0a, 0x00, 0x03, 0xd0, 0x0a, 0x00, 0x03, 0xcc, 0x05, 0x01, 0x02, + 0xd0, 0x05, 0x01, 0x02, 0xd4, 0x05, 0x01, 0x02, 0xd8, 0x05, 0x01, 0x02, 0xb8, 0x30, 0x02, 0x03, 0xc0, 0x30, 0x02, 0x03, 0xc8, 0x30, 0x02, 0x03, 0xd0, 0x30, 0x02, 0x03, 0x48, 0x1b, 0x03, 0x03, + 0x50, 0x1b, 0x03, 0x03, 0xa8, 0x09, 0x04, 0x03, 0xb0, 0x09, 0x04, 0x03, 0xb8, 0x09, 0x04, 0x03, 0x10, 0x37, 0x05, 0x04, 0x80, 0x1f, 0x06, 0x04, 0x90, 0x1f, 0x06, 0x04, 0xe0, 0x0d, 0x07, 0x04, + 0xa0, 0x3d, 0x08, 0x05, 0x80, 0x26, 0x09, 0x05, 0x60, 0x01, 0x0b, 0x05, 0x80, 0x02, 0x0e, 0x06, 0x00, 0x0c, 0x14, 0x08, 0xd8, 0x0a, 0x00, 0x03, 0xe0, 0x0a, 0x00, 0x03, 0xdc, 0x05, 0x01, 0x02, + 0xe0, 0x05, 0x01, 0x02, 0xe4, 0x05, 0x01, 0x02, 0xe8, 0x05, 0x01, 0x02, 0xd8, 0x30, 0x02, 0x03, 0xe0, 0x30, 0x02, 0x03, 0xe8, 0x30, 0x02, 0x03, 0xf0, 0x30, 0x02, 0x03, 0x58, 0x1b, 0x03, 0x03, + 0x60, 0x1b, 0x03, 0x03, 0xc0, 0x09, 0x04, 0x03, 0xc8, 0x09, 0x04, 0x03, 0xd0, 0x09, 0x04, 0x03, 0x20, 0x37, 0x05, 0x04, 0xa0, 0x1f, 0x06, 0x04, 0xb0, 0x1f, 0x06, 0x04, 0xf0, 0x0d, 0x07, 0x04, + 0xc0, 0x3d, 0x08, 0x05, 0xa0, 0x26, 0x09, 0x05, 0x80, 0x01, 0x0b, 0x05, 0xc0, 0x02, 0x0e, 0x06, 0x00, 0x0d, 0x14, 0x08, 0xe8, 0x0a, 0x00, 0x03, 0xf0, 0x0a, 0x00, 0x03, 0xec, 0x05, 0x01, 0x02, + 0xf0, 0x05, 0x01, 0x02, 0xf4, 0x05, 0x01, 0x02, 0xf8, 0x05, 0x01, 0x02, 0xf8, 0x30, 0x02, 0x03, 0x00, 0x31, 0x02, 0x03, 0x08, 0x31, 0x02, 0x03, 0x10, 0x31, 0x02, 0x03, 0x68, 0x1b, 0x03, 0x03, + 0x70, 0x1b, 0x03, 0x03, 0xd8, 0x09, 0x04, 0x03, 0xe0, 0x09, 0x04, 0x03, 0xe8, 0x09, 0x04, 0x03, 0x30, 0x37, 0x05, 0x04, 0xc0, 0x1f, 0x06, 0x04, 0xd0, 0x1f, 0x06, 0x04, 0x00, 0x0e, 0x07, 0x04, + 0xe0, 0x3d, 0x08, 0x05, 0xc0, 0x26, 0x09, 0x05, 0xa0, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x0e, 0x06, 0x00, 0x0e, 0x14, 0x08, 0xf8, 0x0a, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x03, 0xfc, 0x05, 0x01, 0x02, + 0x00, 0x06, 0x01, 0x02, 0x04, 0x06, 0x01, 0x02, 0x08, 0x06, 0x01, 0x02, 0x18, 0x31, 0x02, 0x03, 0x20, 0x31, 0x02, 0x03, 0x28, 0x31, 0x02, 0x03, 0x30, 0x31, 0x02, 0x03, 0x78, 0x1b, 0x03, 0x03, + 0x80, 0x1b, 0x03, 0x03, 0xf0, 0x09, 0x04, 0x03, 0xf8, 0x09, 0x04, 0x03, 0x00, 0x0a, 0x04, 0x03, 0x40, 0x37, 0x05, 0x04, 0xe0, 0x1f, 0x06, 0x04, 0xf0, 0x1f, 0x06, 0x04, 0x10, 0x0e, 0x07, 0x04, + 0x00, 0x3e, 0x08, 0x05, 0xe0, 0x26, 0x09, 0x05, 0xc0, 0x01, 0x0b, 0x05, 0x40, 0x03, 0x0e, 0x06, 0x00, 0x0f, 0x14, 0x08, 0x08, 0x0b, 0x00, 0x03, 0x10, 0x0b, 0x00, 0x03, 0x0c, 0x06, 0x01, 0x02, + 0x10, 0x06, 0x01, 0x02, 0x14, 0x06, 0x01, 0x02, 0x18, 0x06, 0x01, 0x02, 0x38, 0x31, 0x02, 0x03, 0x40, 0x31, 0x02, 0x03, 0x48, 0x31, 0x02, 0x03, 0x50, 0x31, 0x02, 0x03, 0x88, 0x1b, 0x03, 0x03, + 0x90, 0x1b, 0x03, 0x03, 0x08, 0x0a, 0x04, 0x03, 0x10, 0x0a, 0x04, 0x03, 0x18, 0x0a, 0x04, 0x03, 0x50, 0x37, 0x05, 0x04, 0x00, 0x20, 0x06, 0x04, 0x10, 0x20, 0x06, 0x04, 0x20, 0x0e, 0x07, 0x04, + 0x20, 0x3e, 0x08, 0x05, 0x00, 0x27, 0x09, 0x05, 0xe0, 0x01, 0x0b, 0x05, 0x80, 0x03, 0x0e, 0x06, 0x00, 0x38, 0x15, 0x09, 0x18, 0x0b, 0x00, 0x03, 0x20, 0x0b, 0x00, 0x03, 0x1c, 0x06, 0x01, 0x02, + 0x20, 0x06, 0x01, 0x02, 0x24, 0x06, 0x01, 0x02, 0x28, 0x06, 0x01, 0x02, 0x58, 0x31, 0x02, 0x03, 0x60, 0x31, 0x02, 0x03, 0x68, 0x31, 0x02, 0x03, 0x70, 0x31, 0x02, 0x03, 0x98, 0x1b, 0x03, 0x03, + 0xa0, 0x1b, 0x03, 0x03, 0x20, 0x0a, 0x04, 0x03, 0x28, 0x0a, 0x04, 0x03, 0x60, 0x37, 0x05, 0x04, 0x70, 0x37, 0x05, 0x04, 0x20, 0x20, 0x06, 0x04, 0x30, 0x20, 0x06, 0x04, 0x30, 0x0e, 0x07, 0x04, + 0x40, 0x3e, 0x08, 0x05, 0x20, 0x27, 0x09, 0x05, 0x00, 0x02, 0x0b, 0x05, 0xc0, 0x03, 0x0e, 0x06, 0x00, 0x3a, 0x15, 0x09, 0x28, 0x0b, 0x00, 0x03, 0x30, 0x0b, 0x00, 0x03, 0x2c, 0x06, 0x01, 0x02, + 0x30, 0x06, 0x01, 0x02, 0x34, 0x06, 0x01, 0x02, 0x38, 0x06, 0x01, 0x02, 0x78, 0x31, 0x02, 0x03, 0x80, 0x31, 0x02, 0x03, 0x88, 0x31, 0x02, 0x03, 0x90, 0x31, 0x02, 0x03, 0xa8, 0x1b, 0x03, 0x03, + 0xb0, 0x1b, 0x03, 0x03, 0x30, 0x0a, 0x04, 0x03, 0x38, 0x0a, 0x04, 0x03, 0x80, 0x37, 0x05, 0x04, 0x90, 0x37, 0x05, 0x04, 0x40, 0x20, 0x06, 0x04, 0x50, 0x20, 0x06, 0x04, 0x40, 0x0e, 0x07, 0x04, + 0x60, 0x3e, 0x08, 0x05, 0x40, 0x27, 0x09, 0x05, 0x20, 0x02, 0x0b, 0x05, 0x00, 0x04, 0x0e, 0x06, 0x00, 0x3c, 0x15, 0x09, 0x38, 0x0b, 0x00, 0x03, 0x40, 0x0b, 0x00, 0x03, 0x3c, 0x06, 0x01, 0x02, + 0x40, 0x06, 0x01, 0x02, 0x44, 0x06, 0x01, 0x02, 0x48, 0x06, 0x01, 0x02, 0x98, 0x31, 0x02, 0x03, 0xa0, 0x31, 0x02, 0x03, 0xa8, 0x31, 0x02, 0x03, 0xb0, 0x31, 0x02, 0x03, 0xb8, 0x1b, 0x03, 0x03, + 0xc0, 0x1b, 0x03, 0x03, 0x40, 0x0a, 0x04, 0x03, 0x48, 0x0a, 0x04, 0x03, 0xa0, 0x37, 0x05, 0x04, 0xb0, 0x37, 0x05, 0x04, 0x60, 0x20, 0x06, 0x04, 0x70, 0x20, 0x06, 0x04, 0x50, 0x0e, 0x07, 0x04, + 0x80, 0x3e, 0x08, 0x05, 0x60, 0x27, 0x09, 0x05, 0x40, 0x02, 0x0b, 0x05, 0x40, 0x04, 0x0e, 0x06, 0x00, 0x3e, 0x15, 0x09, 0x48, 0x0b, 0x00, 0x03, 0x50, 0x0b, 0x00, 0x03, 0x4c, 0x06, 0x01, 0x02, + 0x50, 0x06, 0x01, 0x02, 0x54, 0x06, 0x01, 0x02, 0x58, 0x06, 0x01, 0x02, 0xb8, 0x31, 0x02, 0x03, 0xc0, 0x31, 0x02, 0x03, 0xc8, 0x31, 0x02, 0x03, 0xd0, 0x31, 0x02, 0x03, 0xc8, 0x1b, 0x03, 0x03, + 0xd0, 0x1b, 0x03, 0x03, 0x50, 0x0a, 0x04, 0x03, 0x58, 0x0a, 0x04, 0x03, 0xc0, 0x37, 0x05, 0x04, 0xd0, 0x37, 0x05, 0x04, 0x80, 0x20, 0x06, 0x04, 0x90, 0x20, 0x06, 0x04, 0x60, 0x0e, 0x07, 0x04, + 0xa0, 0x3e, 0x08, 0x05, 0x80, 0x27, 0x09, 0x05, 0x60, 0x02, 0x0b, 0x05, 0x80, 0x04, 0x0e, 0x06, 0x00, 0x00, 0x15, 0x08, 0x58, 0x0b, 0x00, 0x03, 0x60, 0x0b, 0x00, 0x03, 0x5c, 0x06, 0x01, 0x02, + 0x60, 0x06, 0x01, 0x02, 0x64, 0x06, 0x01, 0x02, 0x68, 0x06, 0x01, 0x02, 0xd8, 0x31, 0x02, 0x03, 0xe0, 0x31, 0x02, 0x03, 0xe8, 0x31, 0x02, 0x03, 0xf0, 0x31, 0x02, 0x03, 0xd8, 0x1b, 0x03, 0x03, + 0xe0, 0x1b, 0x03, 0x03, 0x60, 0x0a, 0x04, 0x03, 0x68, 0x0a, 0x04, 0x03, 0xe0, 0x37, 0x05, 0x04, 0xf0, 0x37, 0x05, 0x04, 0xa0, 0x20, 0x06, 0x04, 0xb0, 0x20, 0x06, 0x04, 0x70, 0x0e, 0x07, 0x04, + 0xc0, 0x3e, 0x08, 0x05, 0xa0, 0x27, 0x09, 0x05, 0x80, 0x02, 0x0b, 0x05, 0xc0, 0x04, 0x0e, 0x06, 0x00, 0x20, 0x16, 0x09, 0x68, 0x0b, 0x00, 0x03, 0x70, 0x0b, 0x00, 0x03, 0x6c, 0x06, 0x01, 0x02, + 0x70, 0x06, 0x01, 0x02, 0x74, 0x06, 0x01, 0x02, 0x78, 0x06, 0x01, 0x02, 0xf8, 0x31, 0x02, 0x03, 0x00, 0x32, 0x02, 0x03, 0x08, 0x32, 0x02, 0x03, 0x10, 0x32, 0x02, 0x03, 0xe8, 0x1b, 0x03, 0x03, + 0xf0, 0x1b, 0x03, 0x03, 0x70, 0x0a, 0x04, 0x03, 0x78, 0x0a, 0x04, 0x03, 0x00, 0x38, 0x05, 0x04, 0x10, 0x38, 0x05, 0x04, 0xc0, 0x20, 0x06, 0x04, 0xd0, 0x20, 0x06, 0x04, 0x80, 0x0e, 0x07, 0x04, + 0xe0, 0x3e, 0x08, 0x05, 0xc0, 0x27, 0x09, 0x05, 0xa0, 0x02, 0x0b, 0x05, 0x00, 0x05, 0x0e, 0x06, 0x00, 0x22, 0x16, 0x09, 0x78, 0x0b, 0x00, 0x03, 0x80, 0x0b, 0x00, 0x03, 0x7c, 0x06, 0x01, 0x02, + 0x80, 0x06, 0x01, 0x02, 0x84, 0x06, 0x01, 0x02, 0x88, 0x06, 0x01, 0x02, 0x18, 0x32, 0x02, 0x03, 0x20, 0x32, 0x02, 0x03, 0x28, 0x32, 0x02, 0x03, 0xf8, 0x1b, 0x03, 0x03, 0x00, 0x1c, 0x03, 0x03, + 0x08, 0x1c, 0x03, 0x03, 0x80, 0x0a, 0x04, 0x03, 0x88, 0x0a, 0x04, 0x03, 0x20, 0x38, 0x05, 0x04, 0x30, 0x38, 0x05, 0x04, 0xe0, 0x20, 0x06, 0x04, 0xf0, 0x20, 0x06, 0x04, 0x90, 0x0e, 0x07, 0x04, + 0x00, 0x3f, 0x08, 0x05, 0xe0, 0x27, 0x09, 0x05, 0xc0, 0x02, 0x0b, 0x05, 0x40, 0x05, 0x0e, 0x06, 0x00, 0x24, 0x16, 0x09, 0x88, 0x0b, 0x00, 0x03, 0x90, 0x0b, 0x00, 0x03, 0x8c, 0x06, 0x01, 0x02, + 0x90, 0x06, 0x01, 0x02, 0x94, 0x06, 0x01, 0x02, 0x98, 0x06, 0x01, 0x02, 0x30, 0x32, 0x02, 0x03, 0x38, 0x32, 0x02, 0x03, 0x40, 0x32, 0x02, 0x03, 0x10, 0x1c, 0x03, 0x03, 0x18, 0x1c, 0x03, 0x03, + 0x20, 0x1c, 0x03, 0x03, 0x90, 0x0a, 0x04, 0x03, 0x98, 0x0a, 0x04, 0x03, 0x40, 0x38, 0x05, 0x04, 0x50, 0x38, 0x05, 0x04, 0x00, 0x21, 0x06, 0x04, 0x10, 0x21, 0x06, 0x04, 0xa0, 0x0e, 0x07, 0x04, + 0x20, 0x3f, 0x08, 0x05, 0x80, 0x12, 0x0a, 0x05, 0xe0, 0x02, 0x0b, 0x05, 0x80, 0x05, 0x0e, 0x06, 0x00, 0x26, 0x16, 0x09, 0x98, 0x0b, 0x00, 0x03, 0xa0, 0x0b, 0x00, 0x03, 0x9c, 0x06, 0x01, 0x02, + 0xa0, 0x06, 0x01, 0x02, 0xa4, 0x06, 0x01, 0x02, 0xa8, 0x06, 0x01, 0x02, 0x48, 0x32, 0x02, 0x03, 0x50, 0x32, 0x02, 0x03, 0x58, 0x32, 0x02, 0x03, 0x28, 0x1c, 0x03, 0x03, 0x30, 0x1c, 0x03, 0x03, + 0x38, 0x1c, 0x03, 0x03, 0xa0, 0x0a, 0x04, 0x03, 0xa8, 0x0a, 0x04, 0x03, 0x60, 0x38, 0x05, 0x04, 0x70, 0x38, 0x05, 0x04, 0x20, 0x21, 0x06, 0x04, 0x30, 0x21, 0x06, 0x04, 0xb0, 0x0e, 0x07, 0x04, + 0x40, 0x3f, 0x08, 0x05, 0xa0, 0x12, 0x0a, 0x05, 0x00, 0x03, 0x0b, 0x05, 0xc0, 0x05, 0x0e, 0x06, 0x00, 0x0e, 0x17, 0x09, 0xa8, 0x0b, 0x00, 0x03, 0xb0, 0x0b, 0x00, 0x03, 0xac, 0x06, 0x01, 0x02, + 0xb0, 0x06, 0x01, 0x02, 0xb4, 0x06, 0x01, 0x02, 0xb8, 0x06, 0x01, 0x02, 0x60, 0x32, 0x02, 0x03, 0x68, 0x32, 0x02, 0x03, 0x70, 0x32, 0x02, 0x03, 0x40, 0x1c, 0x03, 0x03, 0x48, 0x1c, 0x03, 0x03, + 0x50, 0x1c, 0x03, 0x03, 0xb0, 0x0a, 0x04, 0x03, 0xb8, 0x0a, 0x04, 0x03, 0x80, 0x38, 0x05, 0x04, 0x90, 0x38, 0x05, 0x04, 0x40, 0x21, 0x06, 0x04, 0x50, 0x21, 0x06, 0x04, 0xc0, 0x0e, 0x07, 0x04, + 0x60, 0x3f, 0x08, 0x05, 0xc0, 0x12, 0x0a, 0x05, 0x20, 0x03, 0x0b, 0x05, 0x00, 0x06, 0x0e, 0x06, 0x00, 0x10, 0x17, 0x09, 0xb8, 0x0b, 0x00, 0x03, 0xc0, 0x0b, 0x00, 0x03, 0xbc, 0x06, 0x01, 0x02, + 0xc0, 0x06, 0x01, 0x02, 0xc4, 0x06, 0x01, 0x02, 0xc8, 0x06, 0x01, 0x02, 0x78, 0x32, 0x02, 0x03, 0x80, 0x32, 0x02, 0x03, 0x88, 0x32, 0x02, 0x03, 0x58, 0x1c, 0x03, 0x03, 0x60, 0x1c, 0x03, 0x03, + 0x68, 0x1c, 0x03, 0x03, 0xc0, 0x0a, 0x04, 0x03, 0xc8, 0x0a, 0x04, 0x03, 0xa0, 0x38, 0x05, 0x04, 0xb0, 0x38, 0x05, 0x04, 0x60, 0x21, 0x06, 0x04, 0x70, 0x21, 0x06, 0x04, 0xd0, 0x0e, 0x07, 0x04, + 0x80, 0x3f, 0x08, 0x05, 0xe0, 0x12, 0x0a, 0x05, 0x40, 0x03, 0x0b, 0x05, 0x40, 0x06, 0x0e, 0x06, 0x00, 0x12, 0x17, 0x09, 0xc8, 0x0b, 0x00, 0x03, 0xd0, 0x0b, 0x00, 0x03, 0xcc, 0x06, 0x01, 0x02, + 0xd0, 0x06, 0x01, 0x02, 0xd4, 0x06, 0x01, 0x02, 0xd8, 0x06, 0x01, 0x02, 0x90, 0x32, 0x02, 0x03, 0x98, 0x32, 0x02, 0x03, 0xa0, 0x32, 0x02, 0x03, 0x70, 0x1c, 0x03, 0x03, 0x78, 0x1c, 0x03, 0x03, + 0x80, 0x1c, 0x03, 0x03, 0xd0, 0x0a, 0x04, 0x03, 0xd8, 0x0a, 0x04, 0x03, 0xc0, 0x38, 0x05, 0x04, 0xd0, 0x38, 0x05, 0x04, 0x80, 0x21, 0x06, 0x04, 0x90, 0x21, 0x06, 0x04, 0xe0, 0x0e, 0x07, 0x04, + 0xa0, 0x3f, 0x08, 0x05, 0x00, 0x13, 0x0a, 0x05, 0x60, 0x03, 0x0b, 0x05, 0x80, 0x06, 0x0e, 0x06, 0x00, 0x3c, 0x18, 0x0a, 0xd8, 0x0b, 0x00, 0x03, 0xe0, 0x0b, 0x00, 0x03, 0xdc, 0x06, 0x01, 0x02, + 0xe0, 0x06, 0x01, 0x02, 0xe4, 0x06, 0x01, 0x02, 0xe8, 0x06, 0x01, 0x02, 0xa8, 0x32, 0x02, 0x03, 0xb0, 0x32, 0x02, 0x03, 0xb8, 0x32, 0x02, 0x03, 0x88, 0x1c, 0x03, 0x03, 0x90, 0x1c, 0x03, 0x03, + 0x98, 0x1c, 0x03, 0x03, 0xe0, 0x0a, 0x04, 0x03, 0xe8, 0x0a, 0x04, 0x03, 0xe0, 0x38, 0x05, 0x04, 0xf0, 0x38, 0x05, 0x04, 0xa0, 0x21, 0x06, 0x04, 0xb0, 0x21, 0x06, 0x04, 0xf0, 0x0e, 0x07, 0x04, + 0xc0, 0x3f, 0x08, 0x05, 0x20, 0x13, 0x0a, 0x05, 0x80, 0x03, 0x0b, 0x05, 0xc0, 0x06, 0x0e, 0x06, 0x00, 0x00, 0x18, 0x09, 0xe8, 0x0b, 0x00, 0x03, 0xf0, 0x0b, 0x00, 0x03, 0xec, 0x06, 0x01, 0x02, + 0xf0, 0x06, 0x01, 0x02, 0xf4, 0x06, 0x01, 0x02, 0xf8, 0x06, 0x01, 0x02, 0xc0, 0x32, 0x02, 0x03, 0xc8, 0x32, 0x02, 0x03, 0xd0, 0x32, 0x02, 0x03, 0xa0, 0x1c, 0x03, 0x03, 0xa8, 0x1c, 0x03, 0x03, + 0xb0, 0x1c, 0x03, 0x03, 0xf0, 0x0a, 0x04, 0x03, 0xf8, 0x0a, 0x04, 0x03, 0x00, 0x39, 0x05, 0x04, 0x10, 0x39, 0x05, 0x04, 0xc0, 0x21, 0x06, 0x04, 0xd0, 0x21, 0x06, 0x04, 0x00, 0x0f, 0x07, 0x04, + 0xe0, 0x3f, 0x08, 0x05, 0x40, 0x13, 0x0a, 0x05, 0xa0, 0x03, 0x0b, 0x05, 0x00, 0x07, 0x0e, 0x06, 0x00, 0x02, 0x18, 0x09, 0xf8, 0x0b, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x03, 0xfc, 0x06, 0x01, 0x02, + 0x00, 0x07, 0x01, 0x02, 0x04, 0x07, 0x01, 0x02, 0x08, 0x07, 0x01, 0x02, 0xd8, 0x32, 0x02, 0x03, 0xe0, 0x32, 0x02, 0x03, 0xe8, 0x32, 0x02, 0x03, 0xb8, 0x1c, 0x03, 0x03, 0xc0, 0x1c, 0x03, 0x03, + 0xc8, 0x1c, 0x03, 0x03, 0x00, 0x0b, 0x04, 0x03, 0x08, 0x0b, 0x04, 0x03, 0x20, 0x39, 0x05, 0x04, 0x30, 0x39, 0x05, 0x04, 0xe0, 0x21, 0x06, 0x04, 0xf0, 0x21, 0x06, 0x04, 0x10, 0x0f, 0x07, 0x04, + 0x00, 0x00, 0x08, 0x04, 0x60, 0x13, 0x0a, 0x05, 0xc0, 0x03, 0x0b, 0x05, 0x40, 0x07, 0x0e, 0x06, 0x00, 0x28, 0x19, 0x0a, 0x08, 0x0c, 0x00, 0x03, 0x10, 0x0c, 0x00, 0x03, 0x0c, 0x07, 0x01, 0x02, + 0x10, 0x07, 0x01, 0x02, 0x14, 0x07, 0x01, 0x02, 0x18, 0x07, 0x01, 0x02, 0xf0, 0x32, 0x02, 0x03, 0xf8, 0x32, 0x02, 0x03, 0x00, 0x33, 0x02, 0x03, 0xd0, 0x1c, 0x03, 0x03, 0xd8, 0x1c, 0x03, 0x03, + 0xe0, 0x1c, 0x03, 0x03, 0x10, 0x0b, 0x04, 0x03, 0x18, 0x0b, 0x04, 0x03, 0x40, 0x39, 0x05, 0x04, 0x50, 0x39, 0x05, 0x04, 0x00, 0x22, 0x06, 0x04, 0x10, 0x22, 0x06, 0x04, 0x20, 0x0f, 0x07, 0x04, + 0x10, 0x00, 0x08, 0x04, 0x80, 0x13, 0x0a, 0x05, 0xe0, 0x03, 0x0b, 0x05, 0x80, 0x07, 0x0e, 0x06, 0x00, 0x2c, 0x19, 0x0a, 0x18, 0x0c, 0x00, 0x03, 0x20, 0x0c, 0x00, 0x03, 0x1c, 0x07, 0x01, 0x02, + 0x20, 0x07, 0x01, 0x02, 0x24, 0x07, 0x01, 0x02, 0x28, 0x07, 0x01, 0x02, 0x08, 0x33, 0x02, 0x03, 0x10, 0x33, 0x02, 0x03, 0x18, 0x33, 0x02, 0x03, 0xe8, 0x1c, 0x03, 0x03, 0xf0, 0x1c, 0x03, 0x03, + 0xf8, 0x1c, 0x03, 0x03, 0x20, 0x0b, 0x04, 0x03, 0x28, 0x0b, 0x04, 0x03, 0x60, 0x39, 0x05, 0x04, 0x70, 0x39, 0x05, 0x04, 0x20, 0x22, 0x06, 0x04, 0x30, 0x22, 0x06, 0x04, 0x30, 0x0f, 0x07, 0x04, + 0x20, 0x00, 0x08, 0x04, 0xa0, 0x13, 0x0a, 0x05, 0x00, 0x04, 0x0b, 0x05, 0x80, 0x32, 0x0f, 0x07, 0x00, 0x18, 0x1a, 0x0a, 0x28, 0x0c, 0x00, 0x03, 0x30, 0x0c, 0x00, 0x03, 0x2c, 0x07, 0x01, 0x02, + 0x30, 0x07, 0x01, 0x02, 0x34, 0x07, 0x01, 0x02, 0x38, 0x07, 0x01, 0x02, 0x20, 0x33, 0x02, 0x03, 0x28, 0x33, 0x02, 0x03, 0x30, 0x33, 0x02, 0x03, 0x00, 0x1d, 0x03, 0x03, 0x08, 0x1d, 0x03, 0x03, + 0x10, 0x1d, 0x03, 0x03, 0x30, 0x0b, 0x04, 0x03, 0x38, 0x0b, 0x04, 0x03, 0x80, 0x39, 0x05, 0x04, 0x90, 0x39, 0x05, 0x04, 0x40, 0x22, 0x06, 0x04, 0x50, 0x22, 0x06, 0x04, 0x40, 0x0f, 0x07, 0x04, + 0x30, 0x00, 0x08, 0x04, 0xc0, 0x13, 0x0a, 0x05, 0x40, 0x2d, 0x0c, 0x06, 0x00, 0x33, 0x0f, 0x07, 0x00, 0x1c, 0x1a, 0x0a, 0x38, 0x0c, 0x00, 0x03, 0x40, 0x0c, 0x00, 0x03, 0x3c, 0x07, 0x01, 0x02, + 0x40, 0x07, 0x01, 0x02, 0x44, 0x07, 0x01, 0x02, 0x48, 0x07, 0x01, 0x02, 0x38, 0x33, 0x02, 0x03, 0x40, 0x33, 0x02, 0x03, 0x48, 0x33, 0x02, 0x03, 0x18, 0x1d, 0x03, 0x03, 0x20, 0x1d, 0x03, 0x03, + 0x28, 0x1d, 0x03, 0x03, 0x40, 0x0b, 0x04, 0x03, 0x48, 0x0b, 0x04, 0x03, 0xa0, 0x39, 0x05, 0x04, 0xb0, 0x39, 0x05, 0x04, 0x60, 0x22, 0x06, 0x04, 0x70, 0x22, 0x06, 0x04, 0x50, 0x0f, 0x07, 0x04, + 0x40, 0x00, 0x08, 0x04, 0xe0, 0x13, 0x0a, 0x05, 0x80, 0x2d, 0x0c, 0x06, 0x80, 0x33, 0x0f, 0x07, 0x00, 0x04, 0x1b, 0x0a, 0x48, 0x0c, 0x00, 0x03, 0x50, 0x0c, 0x00, 0x03, 0x4c, 0x07, 0x01, 0x02, + 0x50, 0x07, 0x01, 0x02, 0x54, 0x07, 0x01, 0x02, 0x58, 0x07, 0x01, 0x02, 0x50, 0x33, 0x02, 0x03, 0x58, 0x33, 0x02, 0x03, 0x60, 0x33, 0x02, 0x03, 0x30, 0x1d, 0x03, 0x03, 0x38, 0x1d, 0x03, 0x03, + 0x40, 0x1d, 0x03, 0x03, 0x50, 0x0b, 0x04, 0x03, 0x58, 0x0b, 0x04, 0x03, 0xc0, 0x39, 0x05, 0x04, 0xd0, 0x39, 0x05, 0x04, 0x80, 0x22, 0x06, 0x04, 0x60, 0x0f, 0x07, 0x04, 0x70, 0x0f, 0x07, 0x04, + 0x50, 0x00, 0x08, 0x04, 0x00, 0x14, 0x0a, 0x05, 0xc0, 0x2d, 0x0c, 0x06, 0x00, 0x34, 0x0f, 0x07, 0x00, 0x08, 0x1b, 0x0a, 0x58, 0x0c, 0x00, 0x03, 0x60, 0x0c, 0x00, 0x03, 0x5c, 0x07, 0x01, 0x02, + 0x60, 0x07, 0x01, 0x02, 0x64, 0x07, 0x01, 0x02, 0x68, 0x07, 0x01, 0x02, 0x68, 0x33, 0x02, 0x03, 0x70, 0x33, 0x02, 0x03, 0x78, 0x33, 0x02, 0x03, 0x48, 0x1d, 0x03, 0x03, 0x50, 0x1d, 0x03, 0x03, + 0x58, 0x1d, 0x03, 0x03, 0x60, 0x0b, 0x04, 0x03, 0x68, 0x0b, 0x04, 0x03, 0xe0, 0x39, 0x05, 0x04, 0xf0, 0x39, 0x05, 0x04, 0x90, 0x22, 0x06, 0x04, 0x80, 0x0f, 0x07, 0x04, 0x90, 0x0f, 0x07, 0x04, + 0x60, 0x00, 0x08, 0x04, 0x20, 0x14, 0x0a, 0x05, 0x00, 0x2e, 0x0c, 0x06, 0x80, 0x34, 0x0f, 0x07, 0x00, 0x30, 0x1c, 0x0b, 0x68, 0x0c, 0x00, 0x03, 0x70, 0x0c, 0x00, 0x03, 0x6c, 0x07, 0x01, 0x02, + 0x70, 0x07, 0x01, 0x02, 0x74, 0x07, 0x01, 0x02, 0x78, 0x07, 0x01, 0x02, 0x80, 0x33, 0x02, 0x03, 0x88, 0x33, 0x02, 0x03, 0x90, 0x33, 0x02, 0x03, 0x60, 0x1d, 0x03, 0x03, 0x68, 0x1d, 0x03, 0x03, + 0x70, 0x1d, 0x03, 0x03, 0x70, 0x0b, 0x04, 0x03, 0x78, 0x0b, 0x04, 0x03, 0x00, 0x3a, 0x05, 0x04, 0x10, 0x3a, 0x05, 0x04, 0xa0, 0x22, 0x06, 0x04, 0xa0, 0x0f, 0x07, 0x04, 0xb0, 0x0f, 0x07, 0x04, + 0x70, 0x00, 0x08, 0x04, 0x40, 0x14, 0x0a, 0x05, 0x40, 0x2e, 0x0c, 0x06, 0x00, 0x35, 0x0f, 0x07, 0x00, 0x18, 0x1d, 0x0b, 0x78, 0x0c, 0x00, 0x03, 0x80, 0x0c, 0x00, 0x03, 0x7c, 0x07, 0x01, 0x02, + 0x80, 0x07, 0x01, 0x02, 0x84, 0x07, 0x01, 0x02, 0x88, 0x07, 0x01, 0x02, 0x98, 0x33, 0x02, 0x03, 0xa0, 0x33, 0x02, 0x03, 0xa8, 0x33, 0x02, 0x03, 0x78, 0x1d, 0x03, 0x03, 0x80, 0x1d, 0x03, 0x03, + 0x88, 0x1d, 0x03, 0x03, 0x80, 0x0b, 0x04, 0x03, 0x88, 0x0b, 0x04, 0x03, 0x20, 0x3a, 0x05, 0x04, 0x30, 0x3a, 0x05, 0x04, 0xb0, 0x22, 0x06, 0x04, 0xc0, 0x0f, 0x07, 0x04, 0xd0, 0x0f, 0x07, 0x04, + 0x80, 0x00, 0x08, 0x04, 0x60, 0x14, 0x0a, 0x05, 0x80, 0x2e, 0x0c, 0x06, 0x80, 0x35, 0x0f, 0x07, 0x00, 0x10, 0x1e, 0x0b, 0x88, 0x0c, 0x00, 0x03, 0x90, 0x0c, 0x00, 0x03, 0x8c, 0x07, 0x01, 0x02, + 0x90, 0x07, 0x01, 0x02, 0x94, 0x07, 0x01, 0x02, 0x98, 0x07, 0x01, 0x02, 0xb0, 0x33, 0x02, 0x03, 0xb8, 0x33, 0x02, 0x03, 0xc0, 0x33, 0x02, 0x03, 0x90, 0x1d, 0x03, 0x03, 0x98, 0x1d, 0x03, 0x03, + 0xa0, 0x1d, 0x03, 0x03, 0x90, 0x0b, 0x04, 0x03, 0x98, 0x0b, 0x04, 0x03, 0x40, 0x3a, 0x05, 0x04, 0x50, 0x3a, 0x05, 0x04, 0xc0, 0x22, 0x06, 0x04, 0xe0, 0x0f, 0x07, 0x04, 0xf0, 0x0f, 0x07, 0x04, + 0x90, 0x00, 0x08, 0x04, 0x80, 0x14, 0x0a, 0x05, 0xc0, 0x2e, 0x0c, 0x06, 0x00, 0x36, 0x0f, 0x07, 0x00, 0x20, 0x20, 0x0c, 0x98, 0x0c, 0x00, 0x03, 0xa0, 0x0c, 0x00, 0x03, 0x9c, 0x07, 0x01, 0x02, + 0xa0, 0x07, 0x01, 0x02, 0xa4, 0x07, 0x01, 0x02, 0xa8, 0x07, 0x01, 0x02, 0xc8, 0x33, 0x02, 0x03, 0xd0, 0x33, 0x02, 0x03, 0xd8, 0x33, 0x02, 0x03, 0xa8, 0x1d, 0x03, 0x03, 0xb0, 0x1d, 0x03, 0x03, + 0xb8, 0x1d, 0x03, 0x03, 0xa0, 0x0b, 0x04, 0x03, 0xa8, 0x0b, 0x04, 0x03, 0x60, 0x3a, 0x05, 0x04, 0x70, 0x3a, 0x05, 0x04, 0xd0, 0x22, 0x06, 0x04, 0x00, 0x10, 0x07, 0x04, 0x10, 0x10, 0x07, 0x04, + 0xa0, 0x00, 0x08, 0x04, 0xa0, 0x14, 0x0a, 0x05, 0x00, 0x2f, 0x0c, 0x06, 0x80, 0x36, 0x0f, 0x07, 0x00, 0x00, 0x22, 0x0c, 0xa8, 0x0c, 0x00, 0x03, 0xb0, 0x0c, 0x00, 0x03, 0xac, 0x07, 0x01, 0x02, + 0xb0, 0x07, 0x01, 0x02, 0xb4, 0x07, 0x01, 0x02, 0xb8, 0x07, 0x01, 0x02, 0xe0, 0x33, 0x02, 0x03, 0xe8, 0x33, 0x02, 0x03, 0xf0, 0x33, 0x02, 0x03, 0xc0, 0x1d, 0x03, 0x03, 0xc8, 0x1d, 0x03, 0x03, + 0xd0, 0x1d, 0x03, 0x03, 0xb0, 0x0b, 0x04, 0x03, 0xb8, 0x0b, 0x04, 0x03, 0x80, 0x3a, 0x05, 0x04, 0x90, 0x3a, 0x05, 0x04, 0xe0, 0x22, 0x06, 0x04, 0x20, 0x10, 0x07, 0x04, 0x30, 0x10, 0x07, 0x04, + 0xb0, 0x00, 0x08, 0x04, 0xc0, 0x14, 0x0a, 0x05, 0x40, 0x2f, 0x0c, 0x06, 0x00, 0x37, 0x0f, 0x07, 0xb8, 0x0c, 0x00, 0x03, 0xc0, 0x0c, 0x00, 0x03, 0xc8, 0x0c, 0x00, 0x03, 0xbc, 0x07, 0x01, 0x02, + 0xc0, 0x07, 0x01, 0x02, 0xc4, 0x07, 0x01, 0x02, 0xc8, 0x07, 0x01, 0x02, 0xf8, 0x33, 0x02, 0x03, 0x00, 0x34, 0x02, 0x03, 0x08, 0x34, 0x02, 0x03, 0xd8, 0x1d, 0x03, 0x03, 0xe0, 0x1d, 0x03, 0x03, + 0xe8, 0x1d, 0x03, 0x03, 0xc0, 0x0b, 0x04, 0x03, 0xc8, 0x0b, 0x04, 0x03, 0xa0, 0x3a, 0x05, 0x04, 0xb0, 0x3a, 0x05, 0x04, 0xf0, 0x22, 0x06, 0x04, 0x40, 0x10, 0x07, 0x04, 0x50, 0x10, 0x07, 0x04, + 0xc0, 0x00, 0x08, 0x04, 0xe0, 0x14, 0x0a, 0x05, 0x80, 0x2f, 0x0c, 0x06, 0x80, 0x37, 0x0f, 0x07, 0xd0, 0x0c, 0x00, 0x03, 0xd8, 0x0c, 0x00, 0x03, 0xe0, 0x0c, 0x00, 0x03, 0xcc, 0x07, 0x01, 0x02, + 0xd0, 0x07, 0x01, 0x02, 0xd4, 0x07, 0x01, 0x02, 0xd8, 0x07, 0x01, 0x02, 0x10, 0x34, 0x02, 0x03, 0x18, 0x34, 0x02, 0x03, 0x20, 0x34, 0x02, 0x03, 0xf0, 0x1d, 0x03, 0x03, 0xf8, 0x1d, 0x03, 0x03, + 0x00, 0x1e, 0x03, 0x03, 0xd0, 0x0b, 0x04, 0x03, 0xd8, 0x0b, 0x04, 0x03, 0xc0, 0x3a, 0x05, 0x04, 0xd0, 0x3a, 0x05, 0x04, 0x00, 0x23, 0x06, 0x04, 0x60, 0x10, 0x07, 0x04, 0x70, 0x10, 0x07, 0x04, + 0xd0, 0x00, 0x08, 0x04, 0x00, 0x15, 0x0a, 0x05, 0xc0, 0x2f, 0x0c, 0x06, 0x00, 0x38, 0x0f, 0x07, 0xe8, 0x0c, 0x00, 0x03, 0xf0, 0x0c, 0x00, 0x03, 0xf8, 0x0c, 0x00, 0x03, 0xdc, 0x07, 0x01, 0x02, + 0xe0, 0x07, 0x01, 0x02, 0xe4, 0x07, 0x01, 0x02, 0xe8, 0x07, 0x01, 0x02, 0x28, 0x34, 0x02, 0x03, 0x30, 0x34, 0x02, 0x03, 0x38, 0x34, 0x02, 0x03, 0x08, 0x1e, 0x03, 0x03, 0x10, 0x1e, 0x03, 0x03, + 0x18, 0x1e, 0x03, 0x03, 0xe0, 0x0b, 0x04, 0x03, 0xe8, 0x0b, 0x04, 0x03, 0xe0, 0x3a, 0x05, 0x04, 0xf0, 0x3a, 0x05, 0x04, 0x10, 0x23, 0x06, 0x04, 0x80, 0x10, 0x07, 0x04, 0x90, 0x10, 0x07, 0x04, + 0xe0, 0x00, 0x08, 0x04, 0x20, 0x15, 0x0a, 0x05, 0x00, 0x30, 0x0c, 0x06, 0x80, 0x38, 0x0f, 0x07, 0x00, 0x0d, 0x00, 0x03, 0x08, 0x0d, 0x00, 0x03, 0x10, 0x0d, 0x00, 0x03, 0xec, 0x07, 0x01, 0x02, + 0xf0, 0x07, 0x01, 0x02, 0xf4, 0x07, 0x01, 0x02, 0xf8, 0x07, 0x01, 0x02, 0x40, 0x34, 0x02, 0x03, 0x48, 0x34, 0x02, 0x03, 0x50, 0x34, 0x02, 0x03, 0x20, 0x1e, 0x03, 0x03, 0x28, 0x1e, 0x03, 0x03, + 0x30, 0x1e, 0x03, 0x03, 0xf0, 0x0b, 0x04, 0x03, 0xf8, 0x0b, 0x04, 0x03, 0x00, 0x3b, 0x05, 0x04, 0x10, 0x3b, 0x05, 0x04, 0x20, 0x23, 0x06, 0x04, 0xa0, 0x10, 0x07, 0x04, 0xb0, 0x10, 0x07, 0x04, + 0x00, 0x28, 0x09, 0x05, 0x40, 0x15, 0x0a, 0x05, 0x40, 0x30, 0x0c, 0x06, 0x00, 0x39, 0x0f, 0x07, 0x18, 0x0d, 0x00, 0x03, 0x20, 0x0d, 0x00, 0x03, 0x28, 0x0d, 0x00, 0x03, 0xfc, 0x07, 0x01, 0x02, + 0x00, 0x08, 0x01, 0x02, 0x04, 0x08, 0x01, 0x02, 0x08, 0x08, 0x01, 0x02, 0x58, 0x34, 0x02, 0x03, 0x60, 0x34, 0x02, 0x03, 0x68, 0x34, 0x02, 0x03, 0x38, 0x1e, 0x03, 0x03, 0x40, 0x1e, 0x03, 0x03, + 0x48, 0x1e, 0x03, 0x03, 0x00, 0x0c, 0x04, 0x03, 0x08, 0x0c, 0x04, 0x03, 0x20, 0x3b, 0x05, 0x04, 0x30, 0x3b, 0x05, 0x04, 0x30, 0x23, 0x06, 0x04, 0xc0, 0x10, 0x07, 0x04, 0xd0, 0x10, 0x07, 0x04, + 0x20, 0x28, 0x09, 0x05, 0x60, 0x15, 0x0a, 0x05, 0x80, 0x30, 0x0c, 0x06, 0x80, 0x39, 0x0f, 0x07, 0x30, 0x0d, 0x00, 0x03, 0x38, 0x0d, 0x00, 0x03, 0x40, 0x0d, 0x00, 0x03, 0x0c, 0x08, 0x01, 0x02, + 0x10, 0x08, 0x01, 0x02, 0x14, 0x08, 0x01, 0x02, 0x18, 0x08, 0x01, 0x02, 0x70, 0x34, 0x02, 0x03, 0x78, 0x34, 0x02, 0x03, 0x80, 0x34, 0x02, 0x03, 0x50, 0x1e, 0x03, 0x03, 0x58, 0x1e, 0x03, 0x03, + 0x60, 0x1e, 0x03, 0x03, 0x10, 0x0c, 0x04, 0x03, 0x18, 0x0c, 0x04, 0x03, 0x40, 0x3b, 0x05, 0x04, 0x50, 0x3b, 0x05, 0x04, 0x40, 0x23, 0x06, 0x04, 0xe0, 0x10, 0x07, 0x04, 0xf0, 0x10, 0x07, 0x04, + 0x40, 0x28, 0x09, 0x05, 0x80, 0x15, 0x0a, 0x05, 0xc0, 0x30, 0x0c, 0x06, 0x00, 0x3a, 0x0f, 0x07, 0x48, 0x0d, 0x00, 0x03, 0x50, 0x0d, 0x00, 0x03, 0x58, 0x0d, 0x00, 0x03, 0x1c, 0x08, 0x01, 0x02, + 0x20, 0x08, 0x01, 0x02, 0x24, 0x08, 0x01, 0x02, 0x28, 0x08, 0x01, 0x02, 0x88, 0x34, 0x02, 0x03, 0x90, 0x34, 0x02, 0x03, 0x98, 0x34, 0x02, 0x03, 0x68, 0x1e, 0x03, 0x03, 0x70, 0x1e, 0x03, 0x03, + 0x78, 0x1e, 0x03, 0x03, 0x20, 0x0c, 0x04, 0x03, 0x28, 0x0c, 0x04, 0x03, 0x60, 0x3b, 0x05, 0x04, 0x70, 0x3b, 0x05, 0x04, 0x50, 0x23, 0x06, 0x04, 0x00, 0x11, 0x07, 0x04, 0x10, 0x11, 0x07, 0x04, + 0x60, 0x28, 0x09, 0x05, 0xa0, 0x15, 0x0a, 0x05, 0x00, 0x31, 0x0c, 0x06, 0x80, 0x3a, 0x0f, 0x07, 0x60, 0x0d, 0x00, 0x03, 0x68, 0x0d, 0x00, 0x03, 0x70, 0x0d, 0x00, 0x03, 0x2c, 0x08, 0x01, 0x02, + 0x30, 0x08, 0x01, 0x02, 0x34, 0x08, 0x01, 0x02, 0x38, 0x08, 0x01, 0x02, 0xa0, 0x34, 0x02, 0x03, 0xa8, 0x34, 0x02, 0x03, 0xb0, 0x34, 0x02, 0x03, 0x80, 0x1e, 0x03, 0x03, 0x88, 0x1e, 0x03, 0x03, + 0x90, 0x1e, 0x03, 0x03, 0x30, 0x0c, 0x04, 0x03, 0x38, 0x0c, 0x04, 0x03, 0x80, 0x3b, 0x05, 0x04, 0x90, 0x3b, 0x05, 0x04, 0x60, 0x23, 0x06, 0x04, 0x20, 0x11, 0x07, 0x04, 0x30, 0x11, 0x07, 0x04, + 0x80, 0x28, 0x09, 0x05, 0xc0, 0x15, 0x0a, 0x05, 0x40, 0x31, 0x0c, 0x06, 0x00, 0x3b, 0x0f, 0x07, 0x78, 0x0d, 0x00, 0x03, 0x80, 0x0d, 0x00, 0x03, 0x88, 0x0d, 0x00, 0x03, 0x3c, 0x08, 0x01, 0x02, + 0x40, 0x08, 0x01, 0x02, 0x44, 0x08, 0x01, 0x02, 0x48, 0x08, 0x01, 0x02, 0xb8, 0x34, 0x02, 0x03, 0xc0, 0x34, 0x02, 0x03, 0xc8, 0x34, 0x02, 0x03, 0x98, 0x1e, 0x03, 0x03, 0xa0, 0x1e, 0x03, 0x03, + 0xa8, 0x1e, 0x03, 0x03, 0x40, 0x0c, 0x04, 0x03, 0x48, 0x0c, 0x04, 0x03, 0xa0, 0x3b, 0x05, 0x04, 0xb0, 0x3b, 0x05, 0x04, 0x70, 0x23, 0x06, 0x04, 0x40, 0x11, 0x07, 0x04, 0xf0, 0x00, 0x08, 0x04, + 0xa0, 0x28, 0x09, 0x05, 0xe0, 0x15, 0x0a, 0x05, 0x80, 0x31, 0x0c, 0x06, 0x80, 0x3b, 0x0f, 0x07, 0x90, 0x0d, 0x00, 0x03, 0x98, 0x0d, 0x00, 0x03, 0xa0, 0x0d, 0x00, 0x03, 0x4c, 0x08, 0x01, 0x02, + 0x50, 0x08, 0x01, 0x02, 0x54, 0x08, 0x01, 0x02, 0x58, 0x08, 0x01, 0x02, 0xd0, 0x34, 0x02, 0x03, 0xd8, 0x34, 0x02, 0x03, 0xe0, 0x34, 0x02, 0x03, 0xb0, 0x1e, 0x03, 0x03, 0xb8, 0x1e, 0x03, 0x03, + 0xc0, 0x1e, 0x03, 0x03, 0x50, 0x0c, 0x04, 0x03, 0x58, 0x0c, 0x04, 0x03, 0xc0, 0x3b, 0x05, 0x04, 0xd0, 0x3b, 0x05, 0x04, 0x80, 0x23, 0x06, 0x04, 0x50, 0x11, 0x07, 0x04, 0x00, 0x01, 0x08, 0x04, + 0xc0, 0x28, 0x09, 0x05, 0x00, 0x16, 0x0a, 0x05, 0xc0, 0x31, 0x0c, 0x06, 0x80, 0x1e, 0x10, 0x07, 0xa8, 0x0d, 0x00, 0x03, 0xb0, 0x0d, 0x00, 0x03, 0xb8, 0x0d, 0x00, 0x03, 0x5c, 0x08, 0x01, 0x02, + 0x60, 0x08, 0x01, 0x02, 0x64, 0x08, 0x01, 0x02, 0x68, 0x08, 0x01, 0x02, 0xe8, 0x34, 0x02, 0x03, 0xf0, 0x34, 0x02, 0x03, 0xf8, 0x34, 0x02, 0x03, 0xc8, 0x1e, 0x03, 0x03, 0xd0, 0x1e, 0x03, 0x03, + 0xd8, 0x1e, 0x03, 0x03, 0x60, 0x0c, 0x04, 0x03, 0x68, 0x0c, 0x04, 0x03, 0xe0, 0x3b, 0x05, 0x04, 0xf0, 0x3b, 0x05, 0x04, 0x90, 0x23, 0x06, 0x04, 0x60, 0x11, 0x07, 0x04, 0x10, 0x01, 0x08, 0x04, + 0xe0, 0x28, 0x09, 0x05, 0x20, 0x16, 0x0a, 0x05, 0x00, 0x32, 0x0c, 0x06, 0x00, 0x1f, 0x10, 0x07, 0xc0, 0x0d, 0x00, 0x03, 0xc8, 0x0d, 0x00, 0x03, 0xd0, 0x0d, 0x00, 0x03, 0x6c, 0x08, 0x01, 0x02, + 0x70, 0x08, 0x01, 0x02, 0x74, 0x08, 0x01, 0x02, 0x78, 0x08, 0x01, 0x02, 0x00, 0x35, 0x02, 0x03, 0x08, 0x35, 0x02, 0x03, 0x10, 0x35, 0x02, 0x03, 0xe0, 0x1e, 0x03, 0x03, 0xe8, 0x1e, 0x03, 0x03, + 0xf0, 0x1e, 0x03, 0x03, 0x70, 0x0c, 0x04, 0x03, 0x78, 0x0c, 0x04, 0x03, 0x00, 0x3c, 0x05, 0x04, 0x10, 0x3c, 0x05, 0x04, 0xa0, 0x23, 0x06, 0x04, 0x70, 0x11, 0x07, 0x04, 0x20, 0x01, 0x08, 0x04, + 0x00, 0x29, 0x09, 0x05, 0x40, 0x16, 0x0a, 0x05, 0x40, 0x32, 0x0c, 0x06, 0x80, 0x1f, 0x10, 0x07, 0xd8, 0x0d, 0x00, 0x03, 0xe0, 0x0d, 0x00, 0x03, 0xe8, 0x0d, 0x00, 0x03, 0x7c, 0x08, 0x01, 0x02, + 0x80, 0x08, 0x01, 0x02, 0x84, 0x08, 0x01, 0x02, 0x88, 0x08, 0x01, 0x02, 0x18, 0x35, 0x02, 0x03, 0x20, 0x35, 0x02, 0x03, 0x28, 0x35, 0x02, 0x03, 0xf8, 0x1e, 0x03, 0x03, 0x00, 0x1f, 0x03, 0x03, + 0x08, 0x1f, 0x03, 0x03, 0x80, 0x0c, 0x04, 0x03, 0x88, 0x0c, 0x04, 0x03, 0x20, 0x3c, 0x05, 0x04, 0x30, 0x3c, 0x05, 0x04, 0xb0, 0x23, 0x06, 0x04, 0x80, 0x11, 0x07, 0x04, 0x30, 0x01, 0x08, 0x04, + 0x20, 0x29, 0x09, 0x05, 0x60, 0x16, 0x0a, 0x05, 0x80, 0x32, 0x0c, 0x06, 0x00, 0x20, 0x10, 0x07, 0xf0, 0x0d, 0x00, 0x03, 0xf8, 0x0d, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x03, 0x8c, 0x08, 0x01, 0x02, + 0x90, 0x08, 0x01, 0x02, 0x94, 0x08, 0x01, 0x02, 0x98, 0x08, 0x01, 0x02, 0x30, 0x35, 0x02, 0x03, 0x38, 0x35, 0x02, 0x03, 0x40, 0x35, 0x02, 0x03, 0x10, 0x1f, 0x03, 0x03, 0x18, 0x1f, 0x03, 0x03, + 0x20, 0x1f, 0x03, 0x03, 0x90, 0x0c, 0x04, 0x03, 0x98, 0x0c, 0x04, 0x03, 0x40, 0x3c, 0x05, 0x04, 0x50, 0x3c, 0x05, 0x04, 0xc0, 0x23, 0x06, 0x04, 0x90, 0x11, 0x07, 0x04, 0x40, 0x01, 0x08, 0x04, + 0x40, 0x29, 0x09, 0x05, 0x80, 0x16, 0x0a, 0x05, 0xc0, 0x32, 0x0c, 0x06, 0x80, 0x20, 0x10, 0x07, 0x08, 0x0e, 0x00, 0x03, 0x10, 0x0e, 0x00, 0x03, 0x18, 0x0e, 0x00, 0x03, 0x9c, 0x08, 0x01, 0x02, + 0xa0, 0x08, 0x01, 0x02, 0xa4, 0x08, 0x01, 0x02, 0xa8, 0x08, 0x01, 0x02, 0x48, 0x35, 0x02, 0x03, 0x50, 0x35, 0x02, 0x03, 0x58, 0x35, 0x02, 0x03, 0x28, 0x1f, 0x03, 0x03, 0x30, 0x1f, 0x03, 0x03, + 0x38, 0x1f, 0x03, 0x03, 0xa0, 0x0c, 0x04, 0x03, 0xa8, 0x0c, 0x04, 0x03, 0x60, 0x3c, 0x05, 0x04, 0x70, 0x3c, 0x05, 0x04, 0xd0, 0x23, 0x06, 0x04, 0xa0, 0x11, 0x07, 0x04, 0x50, 0x01, 0x08, 0x04, + 0x60, 0x29, 0x09, 0x05, 0xa0, 0x16, 0x0a, 0x05, 0x00, 0x33, 0x0c, 0x06, 0x00, 0x21, 0x10, 0x07, 0x20, 0x0e, 0x00, 0x03, 0x28, 0x0e, 0x00, 0x03, 0x30, 0x0e, 0x00, 0x03, 0xac, 0x08, 0x01, 0x02, + 0xb0, 0x08, 0x01, 0x02, 0xb4, 0x08, 0x01, 0x02, 0xb8, 0x08, 0x01, 0x02, 0x60, 0x35, 0x02, 0x03, 0x68, 0x35, 0x02, 0x03, 0x70, 0x35, 0x02, 0x03, 0x40, 0x1f, 0x03, 0x03, 0x48, 0x1f, 0x03, 0x03, + 0x50, 0x1f, 0x03, 0x03, 0xb0, 0x0c, 0x04, 0x03, 0xb8, 0x0c, 0x04, 0x03, 0x80, 0x3c, 0x05, 0x04, 0x90, 0x3c, 0x05, 0x04, 0xe0, 0x23, 0x06, 0x04, 0xb0, 0x11, 0x07, 0x04, 0x60, 0x01, 0x08, 0x04, + 0x80, 0x29, 0x09, 0x05, 0xc0, 0x16, 0x0a, 0x05, 0x40, 0x33, 0x0c, 0x06, 0x80, 0x21, 0x10, 0x07, 0x38, 0x0e, 0x00, 0x03, 0x40, 0x0e, 0x00, 0x03, 0x48, 0x0e, 0x00, 0x03, 0xbc, 0x08, 0x01, 0x02, + 0xc0, 0x08, 0x01, 0x02, 0xc4, 0x08, 0x01, 0x02, 0xc8, 0x08, 0x01, 0x02, 0x78, 0x35, 0x02, 0x03, 0x80, 0x35, 0x02, 0x03, 0x88, 0x35, 0x02, 0x03, 0x58, 0x1f, 0x03, 0x03, 0x60, 0x1f, 0x03, 0x03, + 0x68, 0x1f, 0x03, 0x03, 0xc0, 0x0c, 0x04, 0x03, 0xc8, 0x0c, 0x04, 0x03, 0xa0, 0x3c, 0x05, 0x04, 0xb0, 0x3c, 0x05, 0x04, 0xf0, 0x23, 0x06, 0x04, 0xc0, 0x11, 0x07, 0x04, 0x70, 0x01, 0x08, 0x04, + 0xa0, 0x29, 0x09, 0x05, 0xe0, 0x16, 0x0a, 0x05, 0x80, 0x33, 0x0c, 0x06, 0x00, 0x22, 0x10, 0x07, 0x50, 0x0e, 0x00, 0x03, 0x58, 0x0e, 0x00, 0x03, 0x60, 0x0e, 0x00, 0x03, 0xcc, 0x08, 0x01, 0x02, + 0xd0, 0x08, 0x01, 0x02, 0xd4, 0x08, 0x01, 0x02, 0xd8, 0x08, 0x01, 0x02, 0x90, 0x35, 0x02, 0x03, 0x98, 0x35, 0x02, 0x03, 0xa0, 0x35, 0x02, 0x03, 0x70, 0x1f, 0x03, 0x03, 0x78, 0x1f, 0x03, 0x03, + 0x80, 0x1f, 0x03, 0x03, 0xd0, 0x0c, 0x04, 0x03, 0xd8, 0x0c, 0x04, 0x03, 0xc0, 0x3c, 0x05, 0x04, 0xd0, 0x3c, 0x05, 0x04, 0x00, 0x24, 0x06, 0x04, 0xd0, 0x11, 0x07, 0x04, 0x80, 0x01, 0x08, 0x04, + 0xc0, 0x29, 0x09, 0x05, 0x00, 0x17, 0x0a, 0x05, 0xc0, 0x33, 0x0c, 0x06, 0x80, 0x22, 0x10, 0x07, 0x68, 0x0e, 0x00, 0x03, 0x70, 0x0e, 0x00, 0x03, 0x78, 0x0e, 0x00, 0x03, 0xdc, 0x08, 0x01, 0x02, + 0xe0, 0x08, 0x01, 0x02, 0xe4, 0x08, 0x01, 0x02, 0xe8, 0x08, 0x01, 0x02, 0xa8, 0x35, 0x02, 0x03, 0xb0, 0x35, 0x02, 0x03, 0xb8, 0x35, 0x02, 0x03, 0x88, 0x1f, 0x03, 0x03, 0x90, 0x1f, 0x03, 0x03, + 0x98, 0x1f, 0x03, 0x03, 0xe0, 0x0c, 0x04, 0x03, 0xe8, 0x0c, 0x04, 0x03, 0xe0, 0x3c, 0x05, 0x04, 0xf0, 0x3c, 0x05, 0x04, 0x10, 0x24, 0x06, 0x04, 0xe0, 0x11, 0x07, 0x04, 0x90, 0x01, 0x08, 0x04, + 0xe0, 0x29, 0x09, 0x05, 0x20, 0x17, 0x0a, 0x05, 0x00, 0x34, 0x0c, 0x06, 0x00, 0x23, 0x10, 0x07, 0x80, 0x0e, 0x00, 0x03, 0x88, 0x0e, 0x00, 0x03, 0x90, 0x0e, 0x00, 0x03, 0xec, 0x08, 0x01, 0x02, + 0xf0, 0x08, 0x01, 0x02, 0xf4, 0x08, 0x01, 0x02, 0xf8, 0x08, 0x01, 0x02, 0xc0, 0x35, 0x02, 0x03, 0xc8, 0x35, 0x02, 0x03, 0xd0, 0x35, 0x02, 0x03, 0xa0, 0x1f, 0x03, 0x03, 0xa8, 0x1f, 0x03, 0x03, + 0xb0, 0x1f, 0x03, 0x03, 0xf0, 0x0c, 0x04, 0x03, 0xf8, 0x0c, 0x04, 0x03, 0x00, 0x3d, 0x05, 0x04, 0x10, 0x3d, 0x05, 0x04, 0x20, 0x24, 0x06, 0x04, 0xf0, 0x11, 0x07, 0x04, 0xa0, 0x01, 0x08, 0x04, + 0x00, 0x2a, 0x09, 0x05, 0x40, 0x17, 0x0a, 0x05, 0x40, 0x34, 0x0c, 0x06, 0x80, 0x23, 0x10, 0x07, 0x98, 0x0e, 0x00, 0x03, 0xa0, 0x0e, 0x00, 0x03, 0xfc, 0x08, 0x01, 0x02, 0x00, 0x09, 0x01, 0x02, + 0x04, 0x09, 0x01, 0x02, 0x08, 0x09, 0x01, 0x02, 0x0c, 0x09, 0x01, 0x02, 0xd8, 0x35, 0x02, 0x03, 0xe0, 0x35, 0x02, 0x03, 0xe8, 0x35, 0x02, 0x03, 0xb8, 0x1f, 0x03, 0x03, 0xc0, 0x1f, 0x03, 0x03, + 0xc8, 0x1f, 0x03, 0x03, 0x00, 0x0d, 0x04, 0x03, 0x08, 0x0d, 0x04, 0x03, 0x20, 0x3d, 0x05, 0x04, 0x30, 0x3d, 0x05, 0x04, 0x30, 0x24, 0x06, 0x04, 0x00, 0x12, 0x07, 0x04, 0xb0, 0x01, 0x08, 0x04, + 0x20, 0x2a, 0x09, 0x05, 0x60, 0x17, 0x0a, 0x05, 0x80, 0x34, 0x0c, 0x06, 0x00, 0x24, 0x10, 0x07, 0xa8, 0x0e, 0x00, 0x03, 0xb0, 0x0e, 0x00, 0x03, 0x10, 0x09, 0x01, 0x02, 0x14, 0x09, 0x01, 0x02, + 0x18, 0x09, 0x01, 0x02, 0x1c, 0x09, 0x01, 0x02, 0x20, 0x09, 0x01, 0x02, 0xf0, 0x35, 0x02, 0x03, 0xf8, 0x35, 0x02, 0x03, 0x00, 0x36, 0x02, 0x03, 0xd0, 0x1f, 0x03, 0x03, 0xd8, 0x1f, 0x03, 0x03, + 0xe0, 0x1f, 0x03, 0x03, 0x10, 0x0d, 0x04, 0x03, 0x18, 0x0d, 0x04, 0x03, 0x40, 0x3d, 0x05, 0x04, 0x50, 0x3d, 0x05, 0x04, 0x40, 0x24, 0x06, 0x04, 0x10, 0x12, 0x07, 0x04, 0xc0, 0x01, 0x08, 0x04, + 0x40, 0x2a, 0x09, 0x05, 0x80, 0x17, 0x0a, 0x05, 0xc0, 0x34, 0x0c, 0x06, 0x80, 0x24, 0x10, 0x07, 0xb8, 0x0e, 0x00, 0x03, 0xc0, 0x0e, 0x00, 0x03, 0x24, 0x09, 0x01, 0x02, 0x28, 0x09, 0x01, 0x02, + 0x2c, 0x09, 0x01, 0x02, 0x30, 0x09, 0x01, 0x02, 0x34, 0x09, 0x01, 0x02, 0x08, 0x36, 0x02, 0x03, 0x10, 0x36, 0x02, 0x03, 0x18, 0x36, 0x02, 0x03, 0xe8, 0x1f, 0x03, 0x03, 0xf0, 0x1f, 0x03, 0x03, + 0xf8, 0x1f, 0x03, 0x03, 0x20, 0x0d, 0x04, 0x03, 0x28, 0x0d, 0x04, 0x03, 0x60, 0x3d, 0x05, 0x04, 0x70, 0x3d, 0x05, 0x04, 0x50, 0x24, 0x06, 0x04, 0x20, 0x12, 0x07, 0x04, 0xd0, 0x01, 0x08, 0x04, + 0x60, 0x2a, 0x09, 0x05, 0xa0, 0x17, 0x0a, 0x05, 0x00, 0x35, 0x0c, 0x06, 0x00, 0x25, 0x10, 0x07, 0xc8, 0x0e, 0x00, 0x03, 0xd0, 0x0e, 0x00, 0x03, 0x38, 0x09, 0x01, 0x02, 0x3c, 0x09, 0x01, 0x02, + 0x40, 0x09, 0x01, 0x02, 0x44, 0x09, 0x01, 0x02, 0x48, 0x09, 0x01, 0x02, 0x20, 0x36, 0x02, 0x03, 0x28, 0x36, 0x02, 0x03, 0x30, 0x36, 0x02, 0x03, 0x00, 0x20, 0x03, 0x03, 0x08, 0x20, 0x03, 0x03, + 0x10, 0x20, 0x03, 0x03, 0x30, 0x0d, 0x04, 0x03, 0x38, 0x0d, 0x04, 0x03, 0x80, 0x3d, 0x05, 0x04, 0x90, 0x3d, 0x05, 0x04, 0x60, 0x24, 0x06, 0x04, 0x30, 0x12, 0x07, 0x04, 0xe0, 0x01, 0x08, 0x04, + 0x80, 0x2a, 0x09, 0x05, 0xc0, 0x17, 0x0a, 0x05, 0x40, 0x35, 0x0c, 0x06, 0x80, 0x0b, 0x11, 0x07, 0xd8, 0x0e, 0x00, 0x03, 0xe0, 0x0e, 0x00, 0x03, 0x4c, 0x09, 0x01, 0x02, 0x50, 0x09, 0x01, 0x02, + 0x54, 0x09, 0x01, 0x02, 0x58, 0x09, 0x01, 0x02, 0x5c, 0x09, 0x01, 0x02, 0x38, 0x36, 0x02, 0x03, 0x40, 0x36, 0x02, 0x03, 0x48, 0x36, 0x02, 0x03, 0x18, 0x20, 0x03, 0x03, 0x20, 0x20, 0x03, 0x03, + 0x28, 0x20, 0x03, 0x03, 0x40, 0x0d, 0x04, 0x03, 0x48, 0x0d, 0x04, 0x03, 0xa0, 0x3d, 0x05, 0x04, 0xb0, 0x3d, 0x05, 0x04, 0x70, 0x24, 0x06, 0x04, 0x40, 0x12, 0x07, 0x04, 0xf0, 0x01, 0x08, 0x04, + 0xa0, 0x2a, 0x09, 0x05, 0xe0, 0x17, 0x0a, 0x05, 0x80, 0x35, 0x0c, 0x06, 0x00, 0x0c, 0x11, 0x07, 0xe8, 0x0e, 0x00, 0x03, 0xf0, 0x0e, 0x00, 0x03, 0x60, 0x09, 0x01, 0x02, 0x64, 0x09, 0x01, 0x02, + 0x68, 0x09, 0x01, 0x02, 0x6c, 0x09, 0x01, 0x02, 0x70, 0x09, 0x01, 0x02, 0x50, 0x36, 0x02, 0x03, 0x58, 0x36, 0x02, 0x03, 0x60, 0x36, 0x02, 0x03, 0x30, 0x20, 0x03, 0x03, 0x38, 0x20, 0x03, 0x03, + 0x40, 0x20, 0x03, 0x03, 0x50, 0x0d, 0x04, 0x03, 0x58, 0x0d, 0x04, 0x03, 0xc0, 0x3d, 0x05, 0x04, 0xd0, 0x3d, 0x05, 0x04, 0x80, 0x24, 0x06, 0x04, 0x50, 0x12, 0x07, 0x04, 0x00, 0x02, 0x08, 0x04, + 0xc0, 0x2a, 0x09, 0x05, 0x00, 0x18, 0x0a, 0x05, 0xc0, 0x35, 0x0c, 0x06, 0x80, 0x0c, 0x11, 0x07, 0xf8, 0x0e, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x74, 0x09, 0x01, 0x02, 0x78, 0x09, 0x01, 0x02, + 0x7c, 0x09, 0x01, 0x02, 0x80, 0x09, 0x01, 0x02, 0x84, 0x09, 0x01, 0x02, 0x68, 0x36, 0x02, 0x03, 0x70, 0x36, 0x02, 0x03, 0x78, 0x36, 0x02, 0x03, 0x48, 0x20, 0x03, 0x03, 0x50, 0x20, 0x03, 0x03, + 0x58, 0x20, 0x03, 0x03, 0x60, 0x0d, 0x04, 0x03, 0x68, 0x0d, 0x04, 0x03, 0xe0, 0x3d, 0x05, 0x04, 0xf0, 0x3d, 0x05, 0x04, 0x90, 0x24, 0x06, 0x04, 0x60, 0x12, 0x07, 0x04, 0x10, 0x02, 0x08, 0x04, + 0xe0, 0x2a, 0x09, 0x05, 0x20, 0x18, 0x0a, 0x05, 0x00, 0x19, 0x0d, 0x06, 0x00, 0x0d, 0x11, 0x07, 0x08, 0x0f, 0x00, 0x03, 0x10, 0x0f, 0x00, 0x03, 0x88, 0x09, 0x01, 0x02, 0x8c, 0x09, 0x01, 0x02, + 0x90, 0x09, 0x01, 0x02, 0x94, 0x09, 0x01, 0x02, 0x98, 0x09, 0x01, 0x02, 0x80, 0x36, 0x02, 0x03, 0x88, 0x36, 0x02, 0x03, 0x90, 0x36, 0x02, 0x03, 0x60, 0x20, 0x03, 0x03, 0x68, 0x20, 0x03, 0x03, + 0x70, 0x20, 0x03, 0x03, 0x70, 0x0d, 0x04, 0x03, 0x78, 0x0d, 0x04, 0x03, 0x00, 0x3e, 0x05, 0x04, 0x10, 0x3e, 0x05, 0x04, 0xa0, 0x24, 0x06, 0x04, 0x70, 0x12, 0x07, 0x04, 0x20, 0x02, 0x08, 0x04, + 0x00, 0x2b, 0x09, 0x05, 0x40, 0x18, 0x0a, 0x05, 0x40, 0x19, 0x0d, 0x06, 0x80, 0x0d, 0x11, 0x07, 0x18, 0x0f, 0x00, 0x03, 0x20, 0x0f, 0x00, 0x03, 0x9c, 0x09, 0x01, 0x02, 0xa0, 0x09, 0x01, 0x02, + 0xa4, 0x09, 0x01, 0x02, 0xa8, 0x09, 0x01, 0x02, 0xac, 0x09, 0x01, 0x02, 0x98, 0x36, 0x02, 0x03, 0xa0, 0x36, 0x02, 0x03, 0xa8, 0x36, 0x02, 0x03, 0x78, 0x20, 0x03, 0x03, 0x80, 0x20, 0x03, 0x03, + 0x88, 0x20, 0x03, 0x03, 0x80, 0x0d, 0x04, 0x03, 0x88, 0x0d, 0x04, 0x03, 0x20, 0x3e, 0x05, 0x04, 0x30, 0x3e, 0x05, 0x04, 0xb0, 0x24, 0x06, 0x04, 0x80, 0x12, 0x07, 0x04, 0x30, 0x02, 0x08, 0x04, + 0x20, 0x2b, 0x09, 0x05, 0x60, 0x18, 0x0a, 0x05, 0x80, 0x19, 0x0d, 0x06, 0x00, 0x0e, 0x11, 0x07, 0x28, 0x0f, 0x00, 0x03, 0x30, 0x0f, 0x00, 0x03, 0xb0, 0x09, 0x01, 0x02, 0xb4, 0x09, 0x01, 0x02, + 0xb8, 0x09, 0x01, 0x02, 0xbc, 0x09, 0x01, 0x02, 0xc0, 0x09, 0x01, 0x02, 0xb0, 0x36, 0x02, 0x03, 0xb8, 0x36, 0x02, 0x03, 0xc0, 0x36, 0x02, 0x03, 0x90, 0x20, 0x03, 0x03, 0x98, 0x20, 0x03, 0x03, + 0xa0, 0x20, 0x03, 0x03, 0x90, 0x0d, 0x04, 0x03, 0x98, 0x0d, 0x04, 0x03, 0x40, 0x3e, 0x05, 0x04, 0x50, 0x3e, 0x05, 0x04, 0xc0, 0x24, 0x06, 0x04, 0x90, 0x12, 0x07, 0x04, 0x40, 0x02, 0x08, 0x04, + 0x40, 0x2b, 0x09, 0x05, 0x80, 0x18, 0x0a, 0x05, 0xc0, 0x19, 0x0d, 0x06, 0x80, 0x0e, 0x11, 0x07, 0x38, 0x0f, 0x00, 0x03, 0x40, 0x0f, 0x00, 0x03, 0xc4, 0x09, 0x01, 0x02, 0xc8, 0x09, 0x01, 0x02, + 0xcc, 0x09, 0x01, 0x02, 0xd0, 0x09, 0x01, 0x02, 0xd4, 0x09, 0x01, 0x02, 0xc8, 0x36, 0x02, 0x03, 0xd0, 0x36, 0x02, 0x03, 0xd8, 0x36, 0x02, 0x03, 0xa8, 0x20, 0x03, 0x03, 0xb0, 0x20, 0x03, 0x03, + 0xb8, 0x20, 0x03, 0x03, 0xa0, 0x0d, 0x04, 0x03, 0xa8, 0x0d, 0x04, 0x03, 0x60, 0x3e, 0x05, 0x04, 0x70, 0x3e, 0x05, 0x04, 0xd0, 0x24, 0x06, 0x04, 0xa0, 0x12, 0x07, 0x04, 0x50, 0x02, 0x08, 0x04, + 0x60, 0x2b, 0x09, 0x05, 0xa0, 0x18, 0x0a, 0x05, 0x00, 0x1a, 0x0d, 0x06, 0x00, 0x0f, 0x11, 0x07, 0x48, 0x0f, 0x00, 0x03, 0x50, 0x0f, 0x00, 0x03, 0xd8, 0x09, 0x01, 0x02, 0xdc, 0x09, 0x01, 0x02, + 0xe0, 0x09, 0x01, 0x02, 0xe4, 0x09, 0x01, 0x02, 0xe8, 0x09, 0x01, 0x02, 0xe0, 0x36, 0x02, 0x03, 0xe8, 0x36, 0x02, 0x03, 0xf0, 0x36, 0x02, 0x03, 0xc0, 0x20, 0x03, 0x03, 0xc8, 0x20, 0x03, 0x03, + 0xd0, 0x20, 0x03, 0x03, 0xb0, 0x0d, 0x04, 0x03, 0xb8, 0x0d, 0x04, 0x03, 0x80, 0x3e, 0x05, 0x04, 0x90, 0x3e, 0x05, 0x04, 0xe0, 0x24, 0x06, 0x04, 0xb0, 0x12, 0x07, 0x04, 0x60, 0x02, 0x08, 0x04, + 0x80, 0x2b, 0x09, 0x05, 0xc0, 0x18, 0x0a, 0x05, 0x40, 0x1a, 0x0d, 0x06, 0x80, 0x0f, 0x11, 0x07, 0x58, 0x0f, 0x00, 0x03, 0x60, 0x0f, 0x00, 0x03, 0xec, 0x09, 0x01, 0x02, 0xf0, 0x09, 0x01, 0x02, + 0xf4, 0x09, 0x01, 0x02, 0xf8, 0x09, 0x01, 0x02, 0xfc, 0x09, 0x01, 0x02, 0xf8, 0x36, 0x02, 0x03, 0x00, 0x37, 0x02, 0x03, 0x08, 0x37, 0x02, 0x03, 0xd8, 0x20, 0x03, 0x03, 0xe0, 0x20, 0x03, 0x03, + 0xe8, 0x20, 0x03, 0x03, 0xc0, 0x0d, 0x04, 0x03, 0xc8, 0x0d, 0x04, 0x03, 0xa0, 0x3e, 0x05, 0x04, 0xb0, 0x3e, 0x05, 0x04, 0xf0, 0x24, 0x06, 0x04, 0xc0, 0x12, 0x07, 0x04, 0x70, 0x02, 0x08, 0x04, + 0xa0, 0x2b, 0x09, 0x05, 0xe0, 0x18, 0x0a, 0x05, 0x80, 0x1a, 0x0d, 0x06, 0x00, 0x10, 0x11, 0x07, 0x68, 0x0f, 0x00, 0x03, 0x70, 0x0f, 0x00, 0x03, 0x00, 0x0a, 0x01, 0x02, 0x04, 0x0a, 0x01, 0x02, + 0x08, 0x0a, 0x01, 0x02, 0x0c, 0x0a, 0x01, 0x02, 0x10, 0x0a, 0x01, 0x02, 0x10, 0x37, 0x02, 0x03, 0x18, 0x37, 0x02, 0x03, 0x20, 0x37, 0x02, 0x03, 0xf0, 0x20, 0x03, 0x03, 0xf8, 0x20, 0x03, 0x03, + 0x00, 0x21, 0x03, 0x03, 0xd0, 0x0d, 0x04, 0x03, 0xd8, 0x0d, 0x04, 0x03, 0xc0, 0x3e, 0x05, 0x04, 0xd0, 0x3e, 0x05, 0x04, 0x00, 0x25, 0x06, 0x04, 0xd0, 0x12, 0x07, 0x04, 0x80, 0x02, 0x08, 0x04, + 0xc0, 0x2b, 0x09, 0x05, 0x00, 0x19, 0x0a, 0x05, 0xc0, 0x1a, 0x0d, 0x06, 0x80, 0x10, 0x11, 0x07, 0x78, 0x0f, 0x00, 0x03, 0x80, 0x0f, 0x00, 0x03, 0x14, 0x0a, 0x01, 0x02, 0x18, 0x0a, 0x01, 0x02, + 0x1c, 0x0a, 0x01, 0x02, 0x20, 0x0a, 0x01, 0x02, 0x28, 0x37, 0x02, 0x03, 0x30, 0x37, 0x02, 0x03, 0x38, 0x37, 0x02, 0x03, 0x40, 0x37, 0x02, 0x03, 0x08, 0x21, 0x03, 0x03, 0x10, 0x21, 0x03, 0x03, + 0x18, 0x21, 0x03, 0x03, 0xe0, 0x0d, 0x04, 0x03, 0xe8, 0x0d, 0x04, 0x03, 0xe0, 0x3e, 0x05, 0x04, 0xf0, 0x3e, 0x05, 0x04, 0x10, 0x25, 0x06, 0x04, 0xe0, 0x12, 0x07, 0x04, 0x90, 0x02, 0x08, 0x04, + 0xe0, 0x2b, 0x09, 0x05, 0x20, 0x04, 0x0b, 0x05, 0x00, 0x1b, 0x0d, 0x06, 0x00, 0x11, 0x11, 0x07, 0x88, 0x0f, 0x00, 0x03, 0x90, 0x0f, 0x00, 0x03, 0x24, 0x0a, 0x01, 0x02, 0x28, 0x0a, 0x01, 0x02, + 0x2c, 0x0a, 0x01, 0x02, 0x30, 0x0a, 0x01, 0x02, 0x48, 0x37, 0x02, 0x03, 0x50, 0x37, 0x02, 0x03, 0x58, 0x37, 0x02, 0x03, 0x60, 0x37, 0x02, 0x03, 0x20, 0x21, 0x03, 0x03, 0x28, 0x21, 0x03, 0x03, + 0x30, 0x21, 0x03, 0x03, 0xf0, 0x0d, 0x04, 0x03, 0xf8, 0x0d, 0x04, 0x03, 0x00, 0x3f, 0x05, 0x04, 0x10, 0x3f, 0x05, 0x04, 0x20, 0x25, 0x06, 0x04, 0xf0, 0x12, 0x07, 0x04, 0xa0, 0x02, 0x08, 0x04, + 0x00, 0x2c, 0x09, 0x05, 0x40, 0x04, 0x0b, 0x05, 0x40, 0x1b, 0x0d, 0x06, 0x00, 0x3b, 0x12, 0x08, 0x98, 0x0f, 0x00, 0x03, 0xa0, 0x0f, 0x00, 0x03, 0x34, 0x0a, 0x01, 0x02, 0x38, 0x0a, 0x01, 0x02, + 0x3c, 0x0a, 0x01, 0x02, 0x40, 0x0a, 0x01, 0x02, 0x68, 0x37, 0x02, 0x03, 0x70, 0x37, 0x02, 0x03, 0x78, 0x37, 0x02, 0x03, 0x80, 0x37, 0x02, 0x03, 0x38, 0x21, 0x03, 0x03, 0x40, 0x21, 0x03, 0x03, + 0x48, 0x21, 0x03, 0x03, 0x00, 0x0e, 0x04, 0x03, 0x08, 0x0e, 0x04, 0x03, 0x20, 0x3f, 0x05, 0x04, 0x30, 0x3f, 0x05, 0x04, 0x30, 0x25, 0x06, 0x04, 0x00, 0x13, 0x07, 0x04, 0xb0, 0x02, 0x08, 0x04, + 0x20, 0x2c, 0x09, 0x05, 0x60, 0x04, 0x0b, 0x05, 0x80, 0x1b, 0x0d, 0x06, 0x00, 0x3c, 0x12, 0x08, 0xa8, 0x0f, 0x00, 0x03, 0xb0, 0x0f, 0x00, 0x03, 0x44, 0x0a, 0x01, 0x02, 0x48, 0x0a, 0x01, 0x02, + 0x4c, 0x0a, 0x01, 0x02, 0x50, 0x0a, 0x01, 0x02, 0x88, 0x37, 0x02, 0x03, 0x90, 0x37, 0x02, 0x03, 0x98, 0x37, 0x02, 0x03, 0xa0, 0x37, 0x02, 0x03, 0x50, 0x21, 0x03, 0x03, 0x58, 0x21, 0x03, 0x03, + 0x60, 0x21, 0x03, 0x03, 0x10, 0x0e, 0x04, 0x03, 0x18, 0x0e, 0x04, 0x03, 0x40, 0x3f, 0x05, 0x04, 0x50, 0x3f, 0x05, 0x04, 0x40, 0x25, 0x06, 0x04, 0x10, 0x13, 0x07, 0x04, 0xc0, 0x02, 0x08, 0x04, + 0x40, 0x2c, 0x09, 0x05, 0x80, 0x04, 0x0b, 0x05, 0xc0, 0x1b, 0x0d, 0x06, 0x00, 0x3d, 0x12, 0x08, 0xb8, 0x0f, 0x00, 0x03, 0xc0, 0x0f, 0x00, 0x03, 0x54, 0x0a, 0x01, 0x02, 0x58, 0x0a, 0x01, 0x02, + 0x5c, 0x0a, 0x01, 0x02, 0x60, 0x0a, 0x01, 0x02, 0xa8, 0x37, 0x02, 0x03, 0xb0, 0x37, 0x02, 0x03, 0xb8, 0x37, 0x02, 0x03, 0xc0, 0x37, 0x02, 0x03, 0x68, 0x21, 0x03, 0x03, 0x70, 0x21, 0x03, 0x03, + 0x78, 0x21, 0x03, 0x03, 0x20, 0x0e, 0x04, 0x03, 0x28, 0x0e, 0x04, 0x03, 0x60, 0x3f, 0x05, 0x04, 0x70, 0x3f, 0x05, 0x04, 0x50, 0x25, 0x06, 0x04, 0x20, 0x13, 0x07, 0x04, 0xd0, 0x02, 0x08, 0x04, + 0x60, 0x2c, 0x09, 0x05, 0xa0, 0x04, 0x0b, 0x05, 0x00, 0x1c, 0x0d, 0x06, 0x00, 0x3e, 0x12, 0x08, 0xc8, 0x0f, 0x00, 0x03, 0xd0, 0x0f, 0x00, 0x03, 0x64, 0x0a, 0x01, 0x02, 0x68, 0x0a, 0x01, 0x02, + 0x6c, 0x0a, 0x01, 0x02, 0x70, 0x0a, 0x01, 0x02, 0xc8, 0x37, 0x02, 0x03, 0xd0, 0x37, 0x02, 0x03, 0xd8, 0x37, 0x02, 0x03, 0xe0, 0x37, 0x02, 0x03, 0x80, 0x21, 0x03, 0x03, 0x88, 0x21, 0x03, 0x03, + 0x90, 0x21, 0x03, 0x03, 0x30, 0x0e, 0x04, 0x03, 0x38, 0x0e, 0x04, 0x03, 0x80, 0x3f, 0x05, 0x04, 0x90, 0x3f, 0x05, 0x04, 0x60, 0x25, 0x06, 0x04, 0x30, 0x13, 0x07, 0x04, 0xe0, 0x02, 0x08, 0x04, + 0x80, 0x2c, 0x09, 0x05, 0xc0, 0x04, 0x0b, 0x05, 0x40, 0x1c, 0x0d, 0x06, 0x00, 0x3f, 0x12, 0x08, 0xd8, 0x0f, 0x00, 0x03, 0xe0, 0x0f, 0x00, 0x03, 0x74, 0x0a, 0x01, 0x02, 0x78, 0x0a, 0x01, 0x02, + 0x7c, 0x0a, 0x01, 0x02, 0x80, 0x0a, 0x01, 0x02, 0xe8, 0x37, 0x02, 0x03, 0xf0, 0x37, 0x02, 0x03, 0xf8, 0x37, 0x02, 0x03, 0x00, 0x38, 0x02, 0x03, 0x98, 0x21, 0x03, 0x03, 0xa0, 0x21, 0x03, 0x03, + 0xa8, 0x21, 0x03, 0x03, 0x40, 0x0e, 0x04, 0x03, 0x48, 0x0e, 0x04, 0x03, 0xa0, 0x3f, 0x05, 0x04, 0xb0, 0x3f, 0x05, 0x04, 0x70, 0x25, 0x06, 0x04, 0x40, 0x13, 0x07, 0x04, 0xf0, 0x02, 0x08, 0x04, + 0xa0, 0x2c, 0x09, 0x05, 0xe0, 0x04, 0x0b, 0x05, 0x80, 0x1c, 0x0d, 0x06, 0x00, 0x00, 0x12, 0x07, 0xe8, 0x0f, 0x00, 0x03, 0xf0, 0x0f, 0x00, 0x03, 0x84, 0x0a, 0x01, 0x02, 0x88, 0x0a, 0x01, 0x02, + 0x8c, 0x0a, 0x01, 0x02, 0x90, 0x0a, 0x01, 0x02, 0x08, 0x38, 0x02, 0x03, 0x10, 0x38, 0x02, 0x03, 0x18, 0x38, 0x02, 0x03, 0x20, 0x38, 0x02, 0x03, 0xb0, 0x21, 0x03, 0x03, 0xb8, 0x21, 0x03, 0x03, + 0xc0, 0x21, 0x03, 0x03, 0x50, 0x0e, 0x04, 0x03, 0x58, 0x0e, 0x04, 0x03, 0xc0, 0x3f, 0x05, 0x04, 0x80, 0x25, 0x06, 0x04, 0x90, 0x25, 0x06, 0x04, 0x50, 0x13, 0x07, 0x04, 0x00, 0x03, 0x08, 0x04, + 0xc0, 0x2c, 0x09, 0x05, 0x00, 0x05, 0x0b, 0x05, 0xc0, 0x1c, 0x0d, 0x06, 0x80, 0x00, 0x12, 0x07, 0xf8, 0x0f, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x94, 0x0a, 0x01, 0x02, 0x98, 0x0a, 0x01, 0x02, + 0x9c, 0x0a, 0x01, 0x02, 0xa0, 0x0a, 0x01, 0x02, 0x28, 0x38, 0x02, 0x03, 0x30, 0x38, 0x02, 0x03, 0x38, 0x38, 0x02, 0x03, 0x40, 0x38, 0x02, 0x03, 0xc8, 0x21, 0x03, 0x03, 0xd0, 0x21, 0x03, 0x03, + 0x60, 0x0e, 0x04, 0x03, 0x68, 0x0e, 0x04, 0x03, 0x70, 0x0e, 0x04, 0x03, 0xd0, 0x3f, 0x05, 0x04, 0xa0, 0x25, 0x06, 0x04, 0xb0, 0x25, 0x06, 0x04, 0x60, 0x13, 0x07, 0x04, 0x10, 0x03, 0x08, 0x04, + 0xe0, 0x2c, 0x09, 0x05, 0x20, 0x05, 0x0b, 0x05, 0x00, 0x1d, 0x0d, 0x06, 0x00, 0x01, 0x12, 0x07, 0x08, 0x10, 0x00, 0x03, 0x10, 0x10, 0x00, 0x03, 0xa4, 0x0a, 0x01, 0x02, 0xa8, 0x0a, 0x01, 0x02, + 0xac, 0x0a, 0x01, 0x02, 0xb0, 0x0a, 0x01, 0x02, 0x48, 0x38, 0x02, 0x03, 0x50, 0x38, 0x02, 0x03, 0x58, 0x38, 0x02, 0x03, 0x60, 0x38, 0x02, 0x03, 0xd8, 0x21, 0x03, 0x03, 0xe0, 0x21, 0x03, 0x03, + 0x78, 0x0e, 0x04, 0x03, 0x80, 0x0e, 0x04, 0x03, 0x88, 0x0e, 0x04, 0x03, 0xe0, 0x3f, 0x05, 0x04, 0xc0, 0x25, 0x06, 0x04, 0xd0, 0x25, 0x06, 0x04, 0x70, 0x13, 0x07, 0x04, 0x20, 0x03, 0x08, 0x04, + 0x00, 0x2d, 0x09, 0x05, 0x40, 0x05, 0x0b, 0x05, 0x40, 0x1d, 0x0d, 0x06, 0x80, 0x01, 0x12, 0x07, 0x18, 0x10, 0x00, 0x03, 0x20, 0x10, 0x00, 0x03, 0xb4, 0x0a, 0x01, 0x02, 0xb8, 0x0a, 0x01, 0x02, + 0xbc, 0x0a, 0x01, 0x02, 0xc0, 0x0a, 0x01, 0x02, 0x68, 0x38, 0x02, 0x03, 0x70, 0x38, 0x02, 0x03, 0x78, 0x38, 0x02, 0x03, 0x80, 0x38, 0x02, 0x03, 0xe8, 0x21, 0x03, 0x03, 0xf0, 0x21, 0x03, 0x03, + 0x90, 0x0e, 0x04, 0x03, 0x98, 0x0e, 0x04, 0x03, 0xa0, 0x0e, 0x04, 0x03, 0xf0, 0x3f, 0x05, 0x04, 0xe0, 0x25, 0x06, 0x04, 0xf0, 0x25, 0x06, 0x04, 0x80, 0x13, 0x07, 0x04, 0x30, 0x03, 0x08, 0x04, + 0x20, 0x2d, 0x09, 0x05, 0x60, 0x05, 0x0b, 0x05, 0x80, 0x1d, 0x0d, 0x06, 0x00, 0x02, 0x12, 0x07, 0x28, 0x10, 0x00, 0x03, 0x30, 0x10, 0x00, 0x03, 0xc4, 0x0a, 0x01, 0x02, 0xc8, 0x0a, 0x01, 0x02, + 0xcc, 0x0a, 0x01, 0x02, 0xd0, 0x0a, 0x01, 0x02, 0x88, 0x38, 0x02, 0x03, 0x90, 0x38, 0x02, 0x03, 0x98, 0x38, 0x02, 0x03, 0xa0, 0x38, 0x02, 0x03, 0xf8, 0x21, 0x03, 0x03, 0x00, 0x22, 0x03, 0x03, + 0xa8, 0x0e, 0x04, 0x03, 0xb0, 0x0e, 0x04, 0x03, 0xb8, 0x0e, 0x04, 0x03, 0x00, 0x00, 0x05, 0x03, 0x00, 0x26, 0x06, 0x04, 0x10, 0x26, 0x06, 0x04, 0x90, 0x13, 0x07, 0x04, 0x40, 0x03, 0x08, 0x04, + 0x40, 0x2d, 0x09, 0x05, 0x80, 0x05, 0x0b, 0x05, 0xc0, 0x1d, 0x0d, 0x06, 0x00, 0x23, 0x13, 0x08, 0x38, 0x10, 0x00, 0x03, 0x40, 0x10, 0x00, 0x03, 0xd4, 0x0a, 0x01, 0x02, 0xd8, 0x0a, 0x01, 0x02, + 0xdc, 0x0a, 0x01, 0x02, 0xe0, 0x0a, 0x01, 0x02, 0xa8, 0x38, 0x02, 0x03, 0xb0, 0x38, 0x02, 0x03, 0xb8, 0x38, 0x02, 0x03, 0xc0, 0x38, 0x02, 0x03, 0x08, 0x22, 0x03, 0x03, 0x10, 0x22, 0x03, 0x03, + 0xc0, 0x0e, 0x04, 0x03, 0xc8, 0x0e, 0x04, 0x03, 0xd0, 0x0e, 0x04, 0x03, 0x08, 0x00, 0x05, 0x03, 0x20, 0x26, 0x06, 0x04, 0x30, 0x26, 0x06, 0x04, 0xa0, 0x13, 0x07, 0x04, 0x50, 0x03, 0x08, 0x04, + 0x60, 0x2d, 0x09, 0x05, 0xa0, 0x05, 0x0b, 0x05, 0x00, 0x1e, 0x0d, 0x06, 0x00, 0x24, 0x13, 0x08, 0x48, 0x10, 0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0xe4, 0x0a, 0x01, 0x02, 0xe8, 0x0a, 0x01, 0x02, + 0xec, 0x0a, 0x01, 0x02, 0xf0, 0x0a, 0x01, 0x02, 0xc8, 0x38, 0x02, 0x03, 0xd0, 0x38, 0x02, 0x03, 0xd8, 0x38, 0x02, 0x03, 0xe0, 0x38, 0x02, 0x03, 0x18, 0x22, 0x03, 0x03, 0x20, 0x22, 0x03, 0x03, + 0xd8, 0x0e, 0x04, 0x03, 0xe0, 0x0e, 0x04, 0x03, 0xe8, 0x0e, 0x04, 0x03, 0x10, 0x00, 0x05, 0x03, 0x40, 0x26, 0x06, 0x04, 0x50, 0x26, 0x06, 0x04, 0xb0, 0x13, 0x07, 0x04, 0x60, 0x03, 0x08, 0x04, + 0x80, 0x2d, 0x09, 0x05, 0xc0, 0x05, 0x0b, 0x05, 0x40, 0x1e, 0x0d, 0x06, 0x00, 0x25, 0x13, 0x08, 0x58, 0x10, 0x00, 0x03, 0x60, 0x10, 0x00, 0x03, 0xf4, 0x0a, 0x01, 0x02, 0xf8, 0x0a, 0x01, 0x02, + 0xfc, 0x0a, 0x01, 0x02, 0x00, 0x0b, 0x01, 0x02, 0xe8, 0x38, 0x02, 0x03, 0xf0, 0x38, 0x02, 0x03, 0xf8, 0x38, 0x02, 0x03, 0x00, 0x39, 0x02, 0x03, 0x28, 0x22, 0x03, 0x03, 0x30, 0x22, 0x03, 0x03, + 0xf0, 0x0e, 0x04, 0x03, 0xf8, 0x0e, 0x04, 0x03, 0x00, 0x0f, 0x04, 0x03, 0x18, 0x00, 0x05, 0x03, 0x60, 0x26, 0x06, 0x04, 0x70, 0x26, 0x06, 0x04, 0xc0, 0x13, 0x07, 0x04, 0x70, 0x03, 0x08, 0x04, + 0xa0, 0x2d, 0x09, 0x05, 0xe0, 0x05, 0x0b, 0x05, 0x80, 0x1e, 0x0d, 0x06, 0x00, 0x26, 0x13, 0x08, 0x68, 0x10, 0x00, 0x03, 0x70, 0x10, 0x00, 0x03, 0x04, 0x0b, 0x01, 0x02, 0x08, 0x0b, 0x01, 0x02, + 0x0c, 0x0b, 0x01, 0x02, 0x10, 0x0b, 0x01, 0x02, 0x08, 0x39, 0x02, 0x03, 0x10, 0x39, 0x02, 0x03, 0x18, 0x39, 0x02, 0x03, 0x20, 0x39, 0x02, 0x03, 0x38, 0x22, 0x03, 0x03, 0x40, 0x22, 0x03, 0x03, + 0x08, 0x0f, 0x04, 0x03, 0x10, 0x0f, 0x04, 0x03, 0x18, 0x0f, 0x04, 0x03, 0x20, 0x00, 0x05, 0x03, 0x80, 0x26, 0x06, 0x04, 0x90, 0x26, 0x06, 0x04, 0xd0, 0x13, 0x07, 0x04, 0x80, 0x03, 0x08, 0x04, + 0xc0, 0x2d, 0x09, 0x05, 0x00, 0x06, 0x0b, 0x05, 0xc0, 0x1e, 0x0d, 0x06, 0x00, 0x27, 0x13, 0x08, 0x78, 0x10, 0x00, 0x03, 0x80, 0x10, 0x00, 0x03, 0x14, 0x0b, 0x01, 0x02, 0x18, 0x0b, 0x01, 0x02, + 0x1c, 0x0b, 0x01, 0x02, 0x20, 0x0b, 0x01, 0x02, 0x28, 0x39, 0x02, 0x03, 0x30, 0x39, 0x02, 0x03, 0x38, 0x39, 0x02, 0x03, 0x40, 0x39, 0x02, 0x03, 0x48, 0x22, 0x03, 0x03, 0x50, 0x22, 0x03, 0x03, + 0x20, 0x0f, 0x04, 0x03, 0x28, 0x0f, 0x04, 0x03, 0x30, 0x0f, 0x04, 0x03, 0x28, 0x00, 0x05, 0x03, 0xa0, 0x26, 0x06, 0x04, 0xb0, 0x26, 0x06, 0x04, 0xe0, 0x13, 0x07, 0x04, 0x90, 0x03, 0x08, 0x04, + 0xe0, 0x2d, 0x09, 0x05, 0x20, 0x06, 0x0b, 0x05, 0x00, 0x1f, 0x0d, 0x06, 0x00, 0x28, 0x13, 0x08, 0x88, 0x10, 0x00, 0x03, 0x90, 0x10, 0x00, 0x03, 0x24, 0x0b, 0x01, 0x02, 0x28, 0x0b, 0x01, 0x02, + 0x2c, 0x0b, 0x01, 0x02, 0x30, 0x0b, 0x01, 0x02, 0x48, 0x39, 0x02, 0x03, 0x50, 0x39, 0x02, 0x03, 0x58, 0x39, 0x02, 0x03, 0x60, 0x39, 0x02, 0x03, 0x58, 0x22, 0x03, 0x03, 0x60, 0x22, 0x03, 0x03, + 0x38, 0x0f, 0x04, 0x03, 0x40, 0x0f, 0x04, 0x03, 0x48, 0x0f, 0x04, 0x03, 0x30, 0x00, 0x05, 0x03, 0xc0, 0x26, 0x06, 0x04, 0xd0, 0x26, 0x06, 0x04, 0xf0, 0x13, 0x07, 0x04, 0xa0, 0x03, 0x08, 0x04, + 0x00, 0x2e, 0x09, 0x05, 0x40, 0x06, 0x0b, 0x05, 0x40, 0x1f, 0x0d, 0x06, 0x00, 0x29, 0x13, 0x08, 0x98, 0x10, 0x00, 0x03, 0xa0, 0x10, 0x00, 0x03, 0x34, 0x0b, 0x01, 0x02, 0x38, 0x0b, 0x01, 0x02, + 0x3c, 0x0b, 0x01, 0x02, 0x40, 0x0b, 0x01, 0x02, 0x68, 0x39, 0x02, 0x03, 0x70, 0x39, 0x02, 0x03, 0x78, 0x39, 0x02, 0x03, 0x80, 0x39, 0x02, 0x03, 0x68, 0x22, 0x03, 0x03, 0x70, 0x22, 0x03, 0x03, + 0x50, 0x0f, 0x04, 0x03, 0x58, 0x0f, 0x04, 0x03, 0x60, 0x0f, 0x04, 0x03, 0x38, 0x00, 0x05, 0x03, 0xe0, 0x26, 0x06, 0x04, 0xf0, 0x26, 0x06, 0x04, 0x00, 0x14, 0x07, 0x04, 0xb0, 0x03, 0x08, 0x04, + 0x20, 0x2e, 0x09, 0x05, 0x60, 0x06, 0x0b, 0x05, 0x80, 0x1f, 0x0d, 0x06, 0x00, 0x10, 0x14, 0x08, 0xa8, 0x10, 0x00, 0x03, 0xb0, 0x10, 0x00, 0x03, 0x44, 0x0b, 0x01, 0x02, 0x48, 0x0b, 0x01, 0x02, + 0x4c, 0x0b, 0x01, 0x02, 0x50, 0x0b, 0x01, 0x02, 0x88, 0x39, 0x02, 0x03, 0x90, 0x39, 0x02, 0x03, 0x98, 0x39, 0x02, 0x03, 0xa0, 0x39, 0x02, 0x03, 0x78, 0x22, 0x03, 0x03, 0x80, 0x22, 0x03, 0x03, + 0x68, 0x0f, 0x04, 0x03, 0x70, 0x0f, 0x04, 0x03, 0x78, 0x0f, 0x04, 0x03, 0x40, 0x00, 0x05, 0x03, 0x00, 0x27, 0x06, 0x04, 0x10, 0x27, 0x06, 0x04, 0x10, 0x14, 0x07, 0x04, 0xc0, 0x03, 0x08, 0x04, + 0x40, 0x2e, 0x09, 0x05, 0x80, 0x06, 0x0b, 0x05, 0xc0, 0x07, 0x0e, 0x06, 0x00, 0x11, 0x14, 0x08, 0xb8, 0x10, 0x00, 0x03, 0xc0, 0x10, 0x00, 0x03, 0x54, 0x0b, 0x01, 0x02, 0x58, 0x0b, 0x01, 0x02, + 0x5c, 0x0b, 0x01, 0x02, 0x60, 0x0b, 0x01, 0x02, 0xa8, 0x39, 0x02, 0x03, 0xb0, 0x39, 0x02, 0x03, 0xb8, 0x39, 0x02, 0x03, 0xc0, 0x39, 0x02, 0x03, 0x88, 0x22, 0x03, 0x03, 0x90, 0x22, 0x03, 0x03, + 0x80, 0x0f, 0x04, 0x03, 0x88, 0x0f, 0x04, 0x03, 0x90, 0x0f, 0x04, 0x03, 0x48, 0x00, 0x05, 0x03, 0x20, 0x27, 0x06, 0x04, 0x30, 0x27, 0x06, 0x04, 0x20, 0x14, 0x07, 0x04, 0xd0, 0x03, 0x08, 0x04, + 0x60, 0x2e, 0x09, 0x05, 0xa0, 0x06, 0x0b, 0x05, 0x00, 0x08, 0x0e, 0x06, 0x00, 0x12, 0x14, 0x08, 0xc8, 0x10, 0x00, 0x03, 0xd0, 0x10, 0x00, 0x03, 0x64, 0x0b, 0x01, 0x02, 0x68, 0x0b, 0x01, 0x02, + 0x6c, 0x0b, 0x01, 0x02, 0x70, 0x0b, 0x01, 0x02, 0xc8, 0x39, 0x02, 0x03, 0xd0, 0x39, 0x02, 0x03, 0xd8, 0x39, 0x02, 0x03, 0xe0, 0x39, 0x02, 0x03, 0x98, 0x22, 0x03, 0x03, 0xa0, 0x22, 0x03, 0x03, + 0x98, 0x0f, 0x04, 0x03, 0xa0, 0x0f, 0x04, 0x03, 0xa8, 0x0f, 0x04, 0x03, 0x50, 0x00, 0x05, 0x03, 0x40, 0x27, 0x06, 0x04, 0x50, 0x27, 0x06, 0x04, 0x30, 0x14, 0x07, 0x04, 0xe0, 0x03, 0x08, 0x04, + 0x80, 0x2e, 0x09, 0x05, 0xc0, 0x06, 0x0b, 0x05, 0x40, 0x08, 0x0e, 0x06, 0x00, 0x13, 0x14, 0x08, 0xd8, 0x10, 0x00, 0x03, 0xe0, 0x10, 0x00, 0x03, 0x74, 0x0b, 0x01, 0x02, 0x78, 0x0b, 0x01, 0x02, + 0x7c, 0x0b, 0x01, 0x02, 0x80, 0x0b, 0x01, 0x02, 0xe8, 0x39, 0x02, 0x03, 0xf0, 0x39, 0x02, 0x03, 0xf8, 0x39, 0x02, 0x03, 0x00, 0x3a, 0x02, 0x03, 0xa8, 0x22, 0x03, 0x03, 0xb0, 0x22, 0x03, 0x03, + 0xb0, 0x0f, 0x04, 0x03, 0xb8, 0x0f, 0x04, 0x03, 0xc0, 0x0f, 0x04, 0x03, 0x58, 0x00, 0x05, 0x03, 0x60, 0x27, 0x06, 0x04, 0x70, 0x27, 0x06, 0x04, 0x40, 0x14, 0x07, 0x04, 0xf0, 0x03, 0x08, 0x04, + 0xa0, 0x2e, 0x09, 0x05, 0xe0, 0x06, 0x0b, 0x05, 0x80, 0x08, 0x0e, 0x06, 0x00, 0x14, 0x14, 0x08, 0xe8, 0x10, 0x00, 0x03, 0xf0, 0x10, 0x00, 0x03, 0x84, 0x0b, 0x01, 0x02, 0x88, 0x0b, 0x01, 0x02, + 0x8c, 0x0b, 0x01, 0x02, 0x90, 0x0b, 0x01, 0x02, 0x08, 0x3a, 0x02, 0x03, 0x10, 0x3a, 0x02, 0x03, 0x18, 0x3a, 0x02, 0x03, 0x20, 0x3a, 0x02, 0x03, 0xb8, 0x22, 0x03, 0x03, 0xc0, 0x22, 0x03, 0x03, + 0xc8, 0x0f, 0x04, 0x03, 0xd0, 0x0f, 0x04, 0x03, 0xd8, 0x0f, 0x04, 0x03, 0x60, 0x00, 0x05, 0x03, 0x80, 0x27, 0x06, 0x04, 0x90, 0x27, 0x06, 0x04, 0x50, 0x14, 0x07, 0x04, 0x00, 0x04, 0x08, 0x04, + 0xc0, 0x2e, 0x09, 0x05, 0x00, 0x07, 0x0b, 0x05, 0xc0, 0x08, 0x0e, 0x06, 0x00, 0x15, 0x14, 0x08, 0xf8, 0x10, 0x00, 0x03, 0x00, 0x11, 0x00, 0x03, 0x94, 0x0b, 0x01, 0x02, 0x98, 0x0b, 0x01, 0x02, + 0x9c, 0x0b, 0x01, 0x02, 0xa0, 0x0b, 0x01, 0x02, 0x28, 0x3a, 0x02, 0x03, 0x30, 0x3a, 0x02, 0x03, 0x38, 0x3a, 0x02, 0x03, 0x40, 0x3a, 0x02, 0x03, 0xc8, 0x22, 0x03, 0x03, 0xd0, 0x22, 0x03, 0x03, + 0xe0, 0x0f, 0x04, 0x03, 0xe8, 0x0f, 0x04, 0x03, 0xf0, 0x0f, 0x04, 0x03, 0x68, 0x00, 0x05, 0x03, 0xa0, 0x27, 0x06, 0x04, 0xb0, 0x27, 0x06, 0x04, 0x60, 0x14, 0x07, 0x04, 0x10, 0x04, 0x08, 0x04, + 0xe0, 0x2e, 0x09, 0x05, 0x20, 0x07, 0x0b, 0x05, 0x00, 0x09, 0x0e, 0x06, 0x00, 0x01, 0x15, 0x08, 0x08, 0x11, 0x00, 0x03, 0x10, 0x11, 0x00, 0x03, 0xa4, 0x0b, 0x01, 0x02, 0xa8, 0x0b, 0x01, 0x02, + 0xac, 0x0b, 0x01, 0x02, 0xb0, 0x0b, 0x01, 0x02, 0x48, 0x3a, 0x02, 0x03, 0x50, 0x3a, 0x02, 0x03, 0x58, 0x3a, 0x02, 0x03, 0x60, 0x3a, 0x02, 0x03, 0xd8, 0x22, 0x03, 0x03, 0xe0, 0x22, 0x03, 0x03, + 0xf8, 0x0f, 0x04, 0x03, 0x00, 0x10, 0x04, 0x03, 0x08, 0x10, 0x04, 0x03, 0x70, 0x00, 0x05, 0x03, 0xc0, 0x27, 0x06, 0x04, 0xd0, 0x27, 0x06, 0x04, 0x70, 0x14, 0x07, 0x04, 0x20, 0x04, 0x08, 0x04, + 0x00, 0x2f, 0x09, 0x05, 0x40, 0x07, 0x0b, 0x05, 0x40, 0x09, 0x0e, 0x06, 0x00, 0x02, 0x15, 0x08, 0x18, 0x11, 0x00, 0x03, 0x20, 0x11, 0x00, 0x03, 0xb4, 0x0b, 0x01, 0x02, 0xb8, 0x0b, 0x01, 0x02, + 0xbc, 0x0b, 0x01, 0x02, 0xc0, 0x0b, 0x01, 0x02, 0x68, 0x3a, 0x02, 0x03, 0x70, 0x3a, 0x02, 0x03, 0x78, 0x3a, 0x02, 0x03, 0x80, 0x3a, 0x02, 0x03, 0xe8, 0x22, 0x03, 0x03, 0xf0, 0x22, 0x03, 0x03, + 0x10, 0x10, 0x04, 0x03, 0x18, 0x10, 0x04, 0x03, 0x78, 0x00, 0x05, 0x03, 0x80, 0x00, 0x05, 0x03, 0xe0, 0x27, 0x06, 0x04, 0xf0, 0x27, 0x06, 0x04, 0x80, 0x14, 0x07, 0x04, 0x30, 0x04, 0x08, 0x04, + 0x20, 0x2f, 0x09, 0x05, 0x60, 0x07, 0x0b, 0x05, 0x80, 0x09, 0x0e, 0x06, 0x00, 0x03, 0x15, 0x08, 0x28, 0x11, 0x00, 0x03, 0x30, 0x11, 0x00, 0x03, 0xc4, 0x0b, 0x01, 0x02, 0xc8, 0x0b, 0x01, 0x02, + 0xcc, 0x0b, 0x01, 0x02, 0xd0, 0x0b, 0x01, 0x02, 0x88, 0x3a, 0x02, 0x03, 0x90, 0x3a, 0x02, 0x03, 0x98, 0x3a, 0x02, 0x03, 0xa0, 0x3a, 0x02, 0x03, 0xf8, 0x22, 0x03, 0x03, 0x00, 0x23, 0x03, 0x03, + 0x20, 0x10, 0x04, 0x03, 0x28, 0x10, 0x04, 0x03, 0x88, 0x00, 0x05, 0x03, 0x90, 0x00, 0x05, 0x03, 0x00, 0x28, 0x06, 0x04, 0x10, 0x28, 0x06, 0x04, 0x90, 0x14, 0x07, 0x04, 0x40, 0x04, 0x08, 0x04, + 0x40, 0x2f, 0x09, 0x05, 0x80, 0x07, 0x0b, 0x05, 0xc0, 0x09, 0x0e, 0x06, 0x00, 0x04, 0x15, 0x08, 0x38, 0x11, 0x00, 0x03, 0x40, 0x11, 0x00, 0x03, 0xd4, 0x0b, 0x01, 0x02, 0xd8, 0x0b, 0x01, 0x02, + 0xdc, 0x0b, 0x01, 0x02, 0xe0, 0x0b, 0x01, 0x02, 0xa8, 0x3a, 0x02, 0x03, 0xb0, 0x3a, 0x02, 0x03, 0xb8, 0x3a, 0x02, 0x03, 0xc0, 0x3a, 0x02, 0x03, 0x08, 0x23, 0x03, 0x03, 0x10, 0x23, 0x03, 0x03, + 0x30, 0x10, 0x04, 0x03, 0x38, 0x10, 0x04, 0x03, 0x98, 0x00, 0x05, 0x03, 0xa0, 0x00, 0x05, 0x03, 0x20, 0x28, 0x06, 0x04, 0x30, 0x28, 0x06, 0x04, 0xa0, 0x14, 0x07, 0x04, 0x50, 0x04, 0x08, 0x04, + 0x60, 0x2f, 0x09, 0x05, 0xa0, 0x07, 0x0b, 0x05, 0x00, 0x0a, 0x0e, 0x06, 0x00, 0x05, 0x15, 0x08, 0x48, 0x11, 0x00, 0x03, 0x50, 0x11, 0x00, 0x03, 0xe4, 0x0b, 0x01, 0x02, 0xe8, 0x0b, 0x01, 0x02, + 0xec, 0x0b, 0x01, 0x02, 0xf0, 0x0b, 0x01, 0x02, 0xc8, 0x3a, 0x02, 0x03, 0xd0, 0x3a, 0x02, 0x03, 0xd8, 0x3a, 0x02, 0x03, 0xe0, 0x3a, 0x02, 0x03, 0x18, 0x23, 0x03, 0x03, 0x20, 0x23, 0x03, 0x03, + 0x40, 0x10, 0x04, 0x03, 0x48, 0x10, 0x04, 0x03, 0xa8, 0x00, 0x05, 0x03, 0xb0, 0x00, 0x05, 0x03, 0x40, 0x28, 0x06, 0x04, 0x50, 0x28, 0x06, 0x04, 0xb0, 0x14, 0x07, 0x04, 0x60, 0x04, 0x08, 0x04, + 0x80, 0x2f, 0x09, 0x05, 0xc0, 0x07, 0x0b, 0x05, 0x40, 0x0a, 0x0e, 0x06, 0x00, 0x28, 0x16, 0x09, 0x58, 0x11, 0x00, 0x03, 0x60, 0x11, 0x00, 0x03, 0xf4, 0x0b, 0x01, 0x02, 0xf8, 0x0b, 0x01, 0x02, + 0xfc, 0x0b, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0xe8, 0x3a, 0x02, 0x03, 0xf0, 0x3a, 0x02, 0x03, 0xf8, 0x3a, 0x02, 0x03, 0x00, 0x3b, 0x02, 0x03, 0x28, 0x23, 0x03, 0x03, 0x30, 0x23, 0x03, 0x03, + 0x50, 0x10, 0x04, 0x03, 0x58, 0x10, 0x04, 0x03, 0xb8, 0x00, 0x05, 0x03, 0xc0, 0x00, 0x05, 0x03, 0x60, 0x28, 0x06, 0x04, 0x70, 0x28, 0x06, 0x04, 0xc0, 0x14, 0x07, 0x04, 0x70, 0x04, 0x08, 0x04, + 0xa0, 0x2f, 0x09, 0x05, 0xe0, 0x07, 0x0b, 0x05, 0x80, 0x0a, 0x0e, 0x06, 0x00, 0x2a, 0x16, 0x09, 0x68, 0x11, 0x00, 0x03, 0x70, 0x11, 0x00, 0x03, 0x04, 0x0c, 0x01, 0x02, 0x08, 0x0c, 0x01, 0x02, + 0x0c, 0x0c, 0x01, 0x02, 0x10, 0x0c, 0x01, 0x02, 0x08, 0x3b, 0x02, 0x03, 0x10, 0x3b, 0x02, 0x03, 0x18, 0x3b, 0x02, 0x03, 0x20, 0x3b, 0x02, 0x03, 0x38, 0x23, 0x03, 0x03, 0x40, 0x23, 0x03, 0x03, + 0x60, 0x10, 0x04, 0x03, 0x68, 0x10, 0x04, 0x03, 0xc8, 0x00, 0x05, 0x03, 0xd0, 0x00, 0x05, 0x03, 0x80, 0x28, 0x06, 0x04, 0x90, 0x28, 0x06, 0x04, 0xd0, 0x14, 0x07, 0x04, 0x80, 0x04, 0x08, 0x04, + 0xc0, 0x2f, 0x09, 0x05, 0x00, 0x08, 0x0b, 0x05, 0xc0, 0x0a, 0x0e, 0x06, 0x00, 0x2c, 0x16, 0x09, 0x78, 0x11, 0x00, 0x03, 0x80, 0x11, 0x00, 0x03, 0x14, 0x0c, 0x01, 0x02, 0x18, 0x0c, 0x01, 0x02, + 0x1c, 0x0c, 0x01, 0x02, 0x20, 0x0c, 0x01, 0x02, 0x28, 0x3b, 0x02, 0x03, 0x30, 0x3b, 0x02, 0x03, 0x38, 0x3b, 0x02, 0x03, 0x48, 0x23, 0x03, 0x03, 0x50, 0x23, 0x03, 0x03, 0x58, 0x23, 0x03, 0x03, + 0x70, 0x10, 0x04, 0x03, 0x78, 0x10, 0x04, 0x03, 0xd8, 0x00, 0x05, 0x03, 0xe0, 0x00, 0x05, 0x03, 0xa0, 0x28, 0x06, 0x04, 0xb0, 0x28, 0x06, 0x04, 0xe0, 0x14, 0x07, 0x04, 0x90, 0x04, 0x08, 0x04, + 0xe0, 0x2f, 0x09, 0x05, 0x20, 0x08, 0x0b, 0x05, 0x00, 0x0b, 0x0e, 0x06, 0x00, 0x2e, 0x16, 0x09, 0x88, 0x11, 0x00, 0x03, 0x90, 0x11, 0x00, 0x03, 0x24, 0x0c, 0x01, 0x02, 0x28, 0x0c, 0x01, 0x02, + 0x2c, 0x0c, 0x01, 0x02, 0x30, 0x0c, 0x01, 0x02, 0x40, 0x3b, 0x02, 0x03, 0x48, 0x3b, 0x02, 0x03, 0x50, 0x3b, 0x02, 0x03, 0x60, 0x23, 0x03, 0x03, 0x68, 0x23, 0x03, 0x03, 0x70, 0x23, 0x03, 0x03, + 0x80, 0x10, 0x04, 0x03, 0x88, 0x10, 0x04, 0x03, 0xe8, 0x00, 0x05, 0x03, 0xf0, 0x00, 0x05, 0x03, 0xc0, 0x28, 0x06, 0x04, 0xd0, 0x28, 0x06, 0x04, 0xf0, 0x14, 0x07, 0x04, 0xa0, 0x04, 0x08, 0x04, + 0x20, 0x19, 0x0a, 0x05, 0x40, 0x08, 0x0b, 0x05, 0x40, 0x0b, 0x0e, 0x06, 0x00, 0x14, 0x17, 0x09, 0x98, 0x11, 0x00, 0x03, 0xa0, 0x11, 0x00, 0x03, 0x34, 0x0c, 0x01, 0x02, 0x38, 0x0c, 0x01, 0x02, + 0x3c, 0x0c, 0x01, 0x02, 0x40, 0x0c, 0x01, 0x02, 0x58, 0x3b, 0x02, 0x03, 0x60, 0x3b, 0x02, 0x03, 0x68, 0x3b, 0x02, 0x03, 0x78, 0x23, 0x03, 0x03, 0x80, 0x23, 0x03, 0x03, 0x88, 0x23, 0x03, 0x03, + 0x90, 0x10, 0x04, 0x03, 0x98, 0x10, 0x04, 0x03, 0xf8, 0x00, 0x05, 0x03, 0x00, 0x01, 0x05, 0x03, 0xe0, 0x28, 0x06, 0x04, 0xf0, 0x28, 0x06, 0x04, 0x00, 0x15, 0x07, 0x04, 0xb0, 0x04, 0x08, 0x04, + 0x40, 0x19, 0x0a, 0x05, 0x60, 0x08, 0x0b, 0x05, 0x80, 0x0b, 0x0e, 0x06, 0x00, 0x16, 0x17, 0x09, 0xa8, 0x11, 0x00, 0x03, 0xb0, 0x11, 0x00, 0x03, 0x44, 0x0c, 0x01, 0x02, 0x48, 0x0c, 0x01, 0x02, + 0x4c, 0x0c, 0x01, 0x02, 0x50, 0x0c, 0x01, 0x02, 0x70, 0x3b, 0x02, 0x03, 0x78, 0x3b, 0x02, 0x03, 0x80, 0x3b, 0x02, 0x03, 0x90, 0x23, 0x03, 0x03, 0x98, 0x23, 0x03, 0x03, 0xa0, 0x23, 0x03, 0x03, + 0xa0, 0x10, 0x04, 0x03, 0xa8, 0x10, 0x04, 0x03, 0x08, 0x01, 0x05, 0x03, 0x10, 0x01, 0x05, 0x03, 0x00, 0x29, 0x06, 0x04, 0x10, 0x29, 0x06, 0x04, 0x10, 0x15, 0x07, 0x04, 0xc0, 0x04, 0x08, 0x04, + 0x60, 0x19, 0x0a, 0x05, 0x80, 0x08, 0x0b, 0x05, 0xc0, 0x0b, 0x0e, 0x06, 0x00, 0x18, 0x17, 0x09, 0xb8, 0x11, 0x00, 0x03, 0xc0, 0x11, 0x00, 0x03, 0x54, 0x0c, 0x01, 0x02, 0x58, 0x0c, 0x01, 0x02, + 0x5c, 0x0c, 0x01, 0x02, 0x60, 0x0c, 0x01, 0x02, 0x88, 0x3b, 0x02, 0x03, 0x90, 0x3b, 0x02, 0x03, 0x98, 0x3b, 0x02, 0x03, 0xa8, 0x23, 0x03, 0x03, 0xb0, 0x23, 0x03, 0x03, 0xb8, 0x23, 0x03, 0x03, + 0xb0, 0x10, 0x04, 0x03, 0xb8, 0x10, 0x04, 0x03, 0x18, 0x01, 0x05, 0x03, 0x20, 0x01, 0x05, 0x03, 0x20, 0x29, 0x06, 0x04, 0x30, 0x29, 0x06, 0x04, 0x20, 0x15, 0x07, 0x04, 0xd0, 0x04, 0x08, 0x04, + 0x80, 0x19, 0x0a, 0x05, 0xa0, 0x08, 0x0b, 0x05, 0x00, 0x0c, 0x0e, 0x06, 0x00, 0x1a, 0x17, 0x09, 0xc8, 0x11, 0x00, 0x03, 0xd0, 0x11, 0x00, 0x03, 0x64, 0x0c, 0x01, 0x02, 0x68, 0x0c, 0x01, 0x02, + 0x6c, 0x0c, 0x01, 0x02, 0x70, 0x0c, 0x01, 0x02, 0xa0, 0x3b, 0x02, 0x03, 0xa8, 0x3b, 0x02, 0x03, 0xb0, 0x3b, 0x02, 0x03, 0xc0, 0x23, 0x03, 0x03, 0xc8, 0x23, 0x03, 0x03, 0xd0, 0x23, 0x03, 0x03, + 0xc0, 0x10, 0x04, 0x03, 0xc8, 0x10, 0x04, 0x03, 0x28, 0x01, 0x05, 0x03, 0x30, 0x01, 0x05, 0x03, 0x40, 0x29, 0x06, 0x04, 0x50, 0x29, 0x06, 0x04, 0x30, 0x15, 0x07, 0x04, 0xe0, 0x04, 0x08, 0x04, + 0xa0, 0x19, 0x0a, 0x05, 0xc0, 0x08, 0x0b, 0x05, 0x40, 0x0c, 0x0e, 0x06, 0x00, 0x04, 0x18, 0x09, 0xd8, 0x11, 0x00, 0x03, 0xe0, 0x11, 0x00, 0x03, 0x74, 0x0c, 0x01, 0x02, 0x78, 0x0c, 0x01, 0x02, + 0x7c, 0x0c, 0x01, 0x02, 0x80, 0x0c, 0x01, 0x02, 0xb8, 0x3b, 0x02, 0x03, 0xc0, 0x3b, 0x02, 0x03, 0xc8, 0x3b, 0x02, 0x03, 0xd8, 0x23, 0x03, 0x03, 0xe0, 0x23, 0x03, 0x03, 0xe8, 0x23, 0x03, 0x03, + 0xd0, 0x10, 0x04, 0x03, 0xd8, 0x10, 0x04, 0x03, 0x38, 0x01, 0x05, 0x03, 0x40, 0x01, 0x05, 0x03, 0x60, 0x29, 0x06, 0x04, 0x70, 0x29, 0x06, 0x04, 0x40, 0x15, 0x07, 0x04, 0xf0, 0x04, 0x08, 0x04, + 0xc0, 0x19, 0x0a, 0x05, 0xe0, 0x08, 0x0b, 0x05, 0x80, 0x0c, 0x0e, 0x06, 0x00, 0x06, 0x18, 0x09, 0xe8, 0x11, 0x00, 0x03, 0xf0, 0x11, 0x00, 0x03, 0x84, 0x0c, 0x01, 0x02, 0x88, 0x0c, 0x01, 0x02, + 0x8c, 0x0c, 0x01, 0x02, 0x90, 0x0c, 0x01, 0x02, 0xd0, 0x3b, 0x02, 0x03, 0xd8, 0x3b, 0x02, 0x03, 0xe0, 0x3b, 0x02, 0x03, 0xf0, 0x23, 0x03, 0x03, 0xf8, 0x23, 0x03, 0x03, 0x00, 0x24, 0x03, 0x03, + 0xe0, 0x10, 0x04, 0x03, 0xe8, 0x10, 0x04, 0x03, 0x48, 0x01, 0x05, 0x03, 0x50, 0x01, 0x05, 0x03, 0x80, 0x29, 0x06, 0x04, 0x90, 0x29, 0x06, 0x04, 0x50, 0x15, 0x07, 0x04, 0x00, 0x05, 0x08, 0x04, + 0xe0, 0x19, 0x0a, 0x05, 0x00, 0x09, 0x0b, 0x05, 0xc0, 0x0c, 0x0e, 0x06, 0x00, 0x30, 0x19, 0x0a, 0xf8, 0x11, 0x00, 0x03, 0x00, 0x12, 0x00, 0x03, 0x94, 0x0c, 0x01, 0x02, 0x98, 0x0c, 0x01, 0x02, + 0x9c, 0x0c, 0x01, 0x02, 0xa0, 0x0c, 0x01, 0x02, 0xe8, 0x3b, 0x02, 0x03, 0xf0, 0x3b, 0x02, 0x03, 0xf8, 0x3b, 0x02, 0x03, 0x08, 0x24, 0x03, 0x03, 0x10, 0x24, 0x03, 0x03, 0x18, 0x24, 0x03, 0x03, + 0xf0, 0x10, 0x04, 0x03, 0xf8, 0x10, 0x04, 0x03, 0x58, 0x01, 0x05, 0x03, 0x60, 0x01, 0x05, 0x03, 0xa0, 0x29, 0x06, 0x04, 0xb0, 0x29, 0x06, 0x04, 0x60, 0x15, 0x07, 0x04, 0x10, 0x05, 0x08, 0x04, + 0x00, 0x1a, 0x0a, 0x05, 0x20, 0x09, 0x0b, 0x05, 0x00, 0x0d, 0x0e, 0x06, 0x00, 0x34, 0x19, 0x0a, 0x08, 0x12, 0x00, 0x03, 0x10, 0x12, 0x00, 0x03, 0xa4, 0x0c, 0x01, 0x02, 0xa8, 0x0c, 0x01, 0x02, + 0xac, 0x0c, 0x01, 0x02, 0xb0, 0x0c, 0x01, 0x02, 0x00, 0x3c, 0x02, 0x03, 0x08, 0x3c, 0x02, 0x03, 0x10, 0x3c, 0x02, 0x03, 0x20, 0x24, 0x03, 0x03, 0x28, 0x24, 0x03, 0x03, 0x30, 0x24, 0x03, 0x03, + 0x00, 0x11, 0x04, 0x03, 0x08, 0x11, 0x04, 0x03, 0x68, 0x01, 0x05, 0x03, 0x70, 0x01, 0x05, 0x03, 0xc0, 0x29, 0x06, 0x04, 0xd0, 0x29, 0x06, 0x04, 0x70, 0x15, 0x07, 0x04, 0x20, 0x05, 0x08, 0x04, + 0x20, 0x1a, 0x0a, 0x05, 0x40, 0x09, 0x0b, 0x05, 0x00, 0x3c, 0x0f, 0x07, 0x00, 0x20, 0x1a, 0x0a, 0x18, 0x12, 0x00, 0x03, 0x20, 0x12, 0x00, 0x03, 0xb4, 0x0c, 0x01, 0x02, 0xb8, 0x0c, 0x01, 0x02, + 0xbc, 0x0c, 0x01, 0x02, 0xc0, 0x0c, 0x01, 0x02, 0x18, 0x3c, 0x02, 0x03, 0x20, 0x3c, 0x02, 0x03, 0x28, 0x3c, 0x02, 0x03, 0x38, 0x24, 0x03, 0x03, 0x40, 0x24, 0x03, 0x03, 0x48, 0x24, 0x03, 0x03, + 0x10, 0x11, 0x04, 0x03, 0x18, 0x11, 0x04, 0x03, 0x78, 0x01, 0x05, 0x03, 0x80, 0x01, 0x05, 0x03, 0xe0, 0x29, 0x06, 0x04, 0xf0, 0x29, 0x06, 0x04, 0x80, 0x15, 0x07, 0x04, 0x30, 0x05, 0x08, 0x04, + 0x40, 0x1a, 0x0a, 0x05, 0x00, 0x36, 0x0c, 0x06, 0x80, 0x3c, 0x0f, 0x07, 0x00, 0x24, 0x1a, 0x0a, 0x28, 0x12, 0x00, 0x03, 0x30, 0x12, 0x00, 0x03, 0xc4, 0x0c, 0x01, 0x02, 0xc8, 0x0c, 0x01, 0x02, + 0xcc, 0x0c, 0x01, 0x02, 0xd0, 0x0c, 0x01, 0x02, 0x30, 0x3c, 0x02, 0x03, 0x38, 0x3c, 0x02, 0x03, 0x40, 0x3c, 0x02, 0x03, 0x50, 0x24, 0x03, 0x03, 0x58, 0x24, 0x03, 0x03, 0x60, 0x24, 0x03, 0x03, + 0x20, 0x11, 0x04, 0x03, 0x28, 0x11, 0x04, 0x03, 0x88, 0x01, 0x05, 0x03, 0x90, 0x01, 0x05, 0x03, 0x00, 0x2a, 0x06, 0x04, 0x10, 0x2a, 0x06, 0x04, 0x90, 0x15, 0x07, 0x04, 0x40, 0x05, 0x08, 0x04, + 0x60, 0x1a, 0x0a, 0x05, 0x40, 0x36, 0x0c, 0x06, 0x00, 0x3d, 0x0f, 0x07, 0x00, 0x0c, 0x1b, 0x0a, 0x38, 0x12, 0x00, 0x03, 0x40, 0x12, 0x00, 0x03, 0xd4, 0x0c, 0x01, 0x02, 0xd8, 0x0c, 0x01, 0x02, + 0xdc, 0x0c, 0x01, 0x02, 0xe0, 0x0c, 0x01, 0x02, 0x48, 0x3c, 0x02, 0x03, 0x50, 0x3c, 0x02, 0x03, 0x58, 0x3c, 0x02, 0x03, 0x68, 0x24, 0x03, 0x03, 0x70, 0x24, 0x03, 0x03, 0x78, 0x24, 0x03, 0x03, + 0x30, 0x11, 0x04, 0x03, 0x38, 0x11, 0x04, 0x03, 0x98, 0x01, 0x05, 0x03, 0xa0, 0x01, 0x05, 0x03, 0x20, 0x2a, 0x06, 0x04, 0xa0, 0x15, 0x07, 0x04, 0xb0, 0x15, 0x07, 0x04, 0x50, 0x05, 0x08, 0x04, + 0x80, 0x1a, 0x0a, 0x05, 0x80, 0x36, 0x0c, 0x06, 0x80, 0x3d, 0x0f, 0x07, 0x00, 0x10, 0x1b, 0x0a, 0x48, 0x12, 0x00, 0x03, 0x50, 0x12, 0x00, 0x03, 0xe4, 0x0c, 0x01, 0x02, 0xe8, 0x0c, 0x01, 0x02, + 0xec, 0x0c, 0x01, 0x02, 0xf0, 0x0c, 0x01, 0x02, 0x60, 0x3c, 0x02, 0x03, 0x68, 0x3c, 0x02, 0x03, 0x70, 0x3c, 0x02, 0x03, 0x80, 0x24, 0x03, 0x03, 0x88, 0x24, 0x03, 0x03, 0x90, 0x24, 0x03, 0x03, + 0x40, 0x11, 0x04, 0x03, 0x48, 0x11, 0x04, 0x03, 0xa8, 0x01, 0x05, 0x03, 0xb0, 0x01, 0x05, 0x03, 0x30, 0x2a, 0x06, 0x04, 0xc0, 0x15, 0x07, 0x04, 0xd0, 0x15, 0x07, 0x04, 0x60, 0x05, 0x08, 0x04, + 0xa0, 0x1a, 0x0a, 0x05, 0xc0, 0x36, 0x0c, 0x06, 0x00, 0x3e, 0x0f, 0x07, 0x00, 0x38, 0x1c, 0x0b, 0x58, 0x12, 0x00, 0x03, 0x60, 0x12, 0x00, 0x03, 0xf4, 0x0c, 0x01, 0x02, 0xf8, 0x0c, 0x01, 0x02, + 0xfc, 0x0c, 0x01, 0x02, 0x00, 0x0d, 0x01, 0x02, 0x78, 0x3c, 0x02, 0x03, 0x80, 0x3c, 0x02, 0x03, 0x88, 0x3c, 0x02, 0x03, 0x98, 0x24, 0x03, 0x03, 0xa0, 0x24, 0x03, 0x03, 0xa8, 0x24, 0x03, 0x03, + 0x50, 0x11, 0x04, 0x03, 0x58, 0x11, 0x04, 0x03, 0xb8, 0x01, 0x05, 0x03, 0xc0, 0x01, 0x05, 0x03, 0x40, 0x2a, 0x06, 0x04, 0xe0, 0x15, 0x07, 0x04, 0xf0, 0x15, 0x07, 0x04, 0x70, 0x05, 0x08, 0x04, + 0xc0, 0x1a, 0x0a, 0x05, 0x00, 0x37, 0x0c, 0x06, 0x80, 0x3e, 0x0f, 0x07, 0x00, 0x20, 0x1d, 0x0b, 0x68, 0x12, 0x00, 0x03, 0x70, 0x12, 0x00, 0x03, 0x04, 0x0d, 0x01, 0x02, 0x08, 0x0d, 0x01, 0x02, + 0x0c, 0x0d, 0x01, 0x02, 0x10, 0x0d, 0x01, 0x02, 0x90, 0x3c, 0x02, 0x03, 0x98, 0x3c, 0x02, 0x03, 0xa0, 0x3c, 0x02, 0x03, 0xb0, 0x24, 0x03, 0x03, 0xb8, 0x24, 0x03, 0x03, 0xc0, 0x24, 0x03, 0x03, + 0x60, 0x11, 0x04, 0x03, 0x68, 0x11, 0x04, 0x03, 0xc8, 0x01, 0x05, 0x03, 0xd0, 0x01, 0x05, 0x03, 0x50, 0x2a, 0x06, 0x04, 0x00, 0x16, 0x07, 0x04, 0x10, 0x16, 0x07, 0x04, 0x80, 0x05, 0x08, 0x04, + 0xe0, 0x1a, 0x0a, 0x05, 0x40, 0x37, 0x0c, 0x06, 0x00, 0x3f, 0x0f, 0x07, 0x00, 0x18, 0x1e, 0x0b, 0x78, 0x12, 0x00, 0x03, 0x80, 0x12, 0x00, 0x03, 0x14, 0x0d, 0x01, 0x02, 0x18, 0x0d, 0x01, 0x02, + 0x1c, 0x0d, 0x01, 0x02, 0x20, 0x0d, 0x01, 0x02, 0xa8, 0x3c, 0x02, 0x03, 0xb0, 0x3c, 0x02, 0x03, 0xb8, 0x3c, 0x02, 0x03, 0xc8, 0x24, 0x03, 0x03, 0xd0, 0x24, 0x03, 0x03, 0xd8, 0x24, 0x03, 0x03, + 0x70, 0x11, 0x04, 0x03, 0x78, 0x11, 0x04, 0x03, 0xd8, 0x01, 0x05, 0x03, 0xe0, 0x01, 0x05, 0x03, 0x60, 0x2a, 0x06, 0x04, 0x20, 0x16, 0x07, 0x04, 0x30, 0x16, 0x07, 0x04, 0x90, 0x05, 0x08, 0x04, + 0x00, 0x1b, 0x0a, 0x05, 0x80, 0x37, 0x0c, 0x06, 0x80, 0x3f, 0x0f, 0x07, 0x00, 0x00, 0x1f, 0x0b, 0x88, 0x12, 0x00, 0x03, 0x90, 0x12, 0x00, 0x03, 0x24, 0x0d, 0x01, 0x02, 0x28, 0x0d, 0x01, 0x02, + 0x2c, 0x0d, 0x01, 0x02, 0x30, 0x0d, 0x01, 0x02, 0xc0, 0x3c, 0x02, 0x03, 0xc8, 0x3c, 0x02, 0x03, 0xd0, 0x3c, 0x02, 0x03, 0xe0, 0x24, 0x03, 0x03, 0xe8, 0x24, 0x03, 0x03, 0xf0, 0x24, 0x03, 0x03, + 0x80, 0x11, 0x04, 0x03, 0x88, 0x11, 0x04, 0x03, 0xe8, 0x01, 0x05, 0x03, 0xf0, 0x01, 0x05, 0x03, 0x70, 0x2a, 0x06, 0x04, 0x40, 0x16, 0x07, 0x04, 0x50, 0x16, 0x07, 0x04, 0xa0, 0x05, 0x08, 0x04, + 0x20, 0x1b, 0x0a, 0x05, 0xc0, 0x37, 0x0c, 0x06, 0x00, 0x00, 0x0f, 0x06, 0x00, 0x10, 0x21, 0x0c, 0x98, 0x12, 0x00, 0x03, 0xa0, 0x12, 0x00, 0x03, 0x34, 0x0d, 0x01, 0x02, 0x38, 0x0d, 0x01, 0x02, + 0x3c, 0x0d, 0x01, 0x02, 0x40, 0x0d, 0x01, 0x02, 0xd8, 0x3c, 0x02, 0x03, 0xe0, 0x3c, 0x02, 0x03, 0xe8, 0x3c, 0x02, 0x03, 0xf8, 0x24, 0x03, 0x03, 0x00, 0x25, 0x03, 0x03, 0x08, 0x25, 0x03, 0x03, + 0x90, 0x11, 0x04, 0x03, 0x98, 0x11, 0x04, 0x03, 0xf8, 0x01, 0x05, 0x03, 0x00, 0x02, 0x05, 0x03, 0x80, 0x2a, 0x06, 0x04, 0x60, 0x16, 0x07, 0x04, 0x70, 0x16, 0x07, 0x04, 0xb0, 0x05, 0x08, 0x04, + 0x40, 0x1b, 0x0a, 0x05, 0x00, 0x38, 0x0c, 0x06, 0x40, 0x00, 0x0f, 0x06, 0x00, 0x20, 0x24, 0x0d, 0xa8, 0x12, 0x00, 0x03, 0xb0, 0x12, 0x00, 0x03, 0x44, 0x0d, 0x01, 0x02, 0x48, 0x0d, 0x01, 0x02, + 0x4c, 0x0d, 0x01, 0x02, 0x50, 0x0d, 0x01, 0x02, 0xf0, 0x3c, 0x02, 0x03, 0xf8, 0x3c, 0x02, 0x03, 0x00, 0x3d, 0x02, 0x03, 0x10, 0x25, 0x03, 0x03, 0x18, 0x25, 0x03, 0x03, 0x20, 0x25, 0x03, 0x03, + 0xa0, 0x11, 0x04, 0x03, 0xa8, 0x11, 0x04, 0x03, 0x08, 0x02, 0x05, 0x03, 0x10, 0x02, 0x05, 0x03, 0x90, 0x2a, 0x06, 0x04, 0x80, 0x16, 0x07, 0x04, 0x90, 0x16, 0x07, 0x04, 0xc0, 0x05, 0x08, 0x04, + 0x60, 0x1b, 0x0a, 0x05, 0x40, 0x38, 0x0c, 0x06, 0x80, 0x00, 0x0f, 0x06, 0xb8, 0x12, 0x00, 0x03, 0xc0, 0x12, 0x00, 0x03, 0xc8, 0x12, 0x00, 0x03, 0x54, 0x0d, 0x01, 0x02, 0x58, 0x0d, 0x01, 0x02, + 0x5c, 0x0d, 0x01, 0x02, 0x60, 0x0d, 0x01, 0x02, 0x08, 0x3d, 0x02, 0x03, 0x10, 0x3d, 0x02, 0x03, 0x18, 0x3d, 0x02, 0x03, 0x28, 0x25, 0x03, 0x03, 0x30, 0x25, 0x03, 0x03, 0x38, 0x25, 0x03, 0x03, + 0xb0, 0x11, 0x04, 0x03, 0xb8, 0x11, 0x04, 0x03, 0x18, 0x02, 0x05, 0x03, 0x20, 0x02, 0x05, 0x03, 0xa0, 0x2a, 0x06, 0x04, 0xa0, 0x16, 0x07, 0x04, 0xb0, 0x16, 0x07, 0x04, 0xd0, 0x05, 0x08, 0x04, + 0x80, 0x1b, 0x0a, 0x05, 0x80, 0x38, 0x0c, 0x06, 0xc0, 0x00, 0x0f, 0x06, 0xd0, 0x12, 0x00, 0x03, 0xd8, 0x12, 0x00, 0x03, 0xe0, 0x12, 0x00, 0x03, 0x64, 0x0d, 0x01, 0x02, 0x68, 0x0d, 0x01, 0x02, + 0x6c, 0x0d, 0x01, 0x02, 0x70, 0x0d, 0x01, 0x02, 0x20, 0x3d, 0x02, 0x03, 0x28, 0x3d, 0x02, 0x03, 0x30, 0x3d, 0x02, 0x03, 0x40, 0x25, 0x03, 0x03, 0x48, 0x25, 0x03, 0x03, 0x50, 0x25, 0x03, 0x03, + 0xc0, 0x11, 0x04, 0x03, 0xc8, 0x11, 0x04, 0x03, 0x28, 0x02, 0x05, 0x03, 0x30, 0x02, 0x05, 0x03, 0xb0, 0x2a, 0x06, 0x04, 0xc0, 0x16, 0x07, 0x04, 0xd0, 0x16, 0x07, 0x04, 0xe0, 0x05, 0x08, 0x04, + 0xa0, 0x1b, 0x0a, 0x05, 0xc0, 0x38, 0x0c, 0x06, 0x00, 0x01, 0x0f, 0x06, 0xe8, 0x12, 0x00, 0x03, 0xf0, 0x12, 0x00, 0x03, 0xf8, 0x12, 0x00, 0x03, 0x74, 0x0d, 0x01, 0x02, 0x78, 0x0d, 0x01, 0x02, + 0x7c, 0x0d, 0x01, 0x02, 0x80, 0x0d, 0x01, 0x02, 0x38, 0x3d, 0x02, 0x03, 0x40, 0x3d, 0x02, 0x03, 0x48, 0x3d, 0x02, 0x03, 0x58, 0x25, 0x03, 0x03, 0x60, 0x25, 0x03, 0x03, 0x68, 0x25, 0x03, 0x03, + 0xd0, 0x11, 0x04, 0x03, 0xd8, 0x11, 0x04, 0x03, 0x38, 0x02, 0x05, 0x03, 0x40, 0x02, 0x05, 0x03, 0xc0, 0x2a, 0x06, 0x04, 0xe0, 0x16, 0x07, 0x04, 0xf0, 0x16, 0x07, 0x04, 0x00, 0x30, 0x09, 0x05, + 0xc0, 0x1b, 0x0a, 0x05, 0x00, 0x39, 0x0c, 0x06, 0x40, 0x01, 0x0f, 0x06, 0x00, 0x13, 0x00, 0x03, 0x08, 0x13, 0x00, 0x03, 0x10, 0x13, 0x00, 0x03, 0x84, 0x0d, 0x01, 0x02, 0x88, 0x0d, 0x01, 0x02, + 0x8c, 0x0d, 0x01, 0x02, 0x90, 0x0d, 0x01, 0x02, 0x50, 0x3d, 0x02, 0x03, 0x58, 0x3d, 0x02, 0x03, 0x60, 0x3d, 0x02, 0x03, 0x70, 0x25, 0x03, 0x03, 0x78, 0x25, 0x03, 0x03, 0x80, 0x25, 0x03, 0x03, + 0xe0, 0x11, 0x04, 0x03, 0xe8, 0x11, 0x04, 0x03, 0x48, 0x02, 0x05, 0x03, 0x50, 0x02, 0x05, 0x03, 0xd0, 0x2a, 0x06, 0x04, 0x00, 0x17, 0x07, 0x04, 0x10, 0x17, 0x07, 0x04, 0x20, 0x30, 0x09, 0x05, + 0xe0, 0x1b, 0x0a, 0x05, 0x40, 0x39, 0x0c, 0x06, 0x80, 0x01, 0x0f, 0x06, 0x18, 0x13, 0x00, 0x03, 0x20, 0x13, 0x00, 0x03, 0x28, 0x13, 0x00, 0x03, 0x94, 0x0d, 0x01, 0x02, 0x98, 0x0d, 0x01, 0x02, + 0x9c, 0x0d, 0x01, 0x02, 0xa0, 0x0d, 0x01, 0x02, 0x68, 0x3d, 0x02, 0x03, 0x70, 0x3d, 0x02, 0x03, 0x78, 0x3d, 0x02, 0x03, 0x88, 0x25, 0x03, 0x03, 0x90, 0x25, 0x03, 0x03, 0x98, 0x25, 0x03, 0x03, + 0xf0, 0x11, 0x04, 0x03, 0xf8, 0x11, 0x04, 0x03, 0x58, 0x02, 0x05, 0x03, 0x60, 0x02, 0x05, 0x03, 0xe0, 0x2a, 0x06, 0x04, 0x20, 0x17, 0x07, 0x04, 0x30, 0x17, 0x07, 0x04, 0x40, 0x30, 0x09, 0x05, + 0x00, 0x1c, 0x0a, 0x05, 0x80, 0x39, 0x0c, 0x06, 0xc0, 0x01, 0x0f, 0x06, 0x30, 0x13, 0x00, 0x03, 0x38, 0x13, 0x00, 0x03, 0x40, 0x13, 0x00, 0x03, 0xa4, 0x0d, 0x01, 0x02, 0xa8, 0x0d, 0x01, 0x02, + 0xac, 0x0d, 0x01, 0x02, 0xb0, 0x0d, 0x01, 0x02, 0x80, 0x3d, 0x02, 0x03, 0x88, 0x3d, 0x02, 0x03, 0x90, 0x3d, 0x02, 0x03, 0xa0, 0x25, 0x03, 0x03, 0xa8, 0x25, 0x03, 0x03, 0xb0, 0x25, 0x03, 0x03, + 0x00, 0x12, 0x04, 0x03, 0x08, 0x12, 0x04, 0x03, 0x68, 0x02, 0x05, 0x03, 0x70, 0x02, 0x05, 0x03, 0xf0, 0x2a, 0x06, 0x04, 0x40, 0x17, 0x07, 0x04, 0x50, 0x17, 0x07, 0x04, 0x60, 0x30, 0x09, 0x05, + 0x20, 0x1c, 0x0a, 0x05, 0xc0, 0x39, 0x0c, 0x06, 0x00, 0x02, 0x0f, 0x06, 0x48, 0x13, 0x00, 0x03, 0x50, 0x13, 0x00, 0x03, 0x58, 0x13, 0x00, 0x03, 0xb4, 0x0d, 0x01, 0x02, 0xb8, 0x0d, 0x01, 0x02, + 0xbc, 0x0d, 0x01, 0x02, 0xc0, 0x0d, 0x01, 0x02, 0x98, 0x3d, 0x02, 0x03, 0xa0, 0x3d, 0x02, 0x03, 0xa8, 0x3d, 0x02, 0x03, 0xb8, 0x25, 0x03, 0x03, 0xc0, 0x25, 0x03, 0x03, 0xc8, 0x25, 0x03, 0x03, + 0x10, 0x12, 0x04, 0x03, 0x18, 0x12, 0x04, 0x03, 0x78, 0x02, 0x05, 0x03, 0x80, 0x02, 0x05, 0x03, 0x00, 0x2b, 0x06, 0x04, 0x60, 0x17, 0x07, 0x04, 0x70, 0x17, 0x07, 0x04, 0x80, 0x30, 0x09, 0x05, + 0x40, 0x1c, 0x0a, 0x05, 0x00, 0x3a, 0x0c, 0x06, 0x40, 0x02, 0x0f, 0x06, 0x60, 0x13, 0x00, 0x03, 0x68, 0x13, 0x00, 0x03, 0x70, 0x13, 0x00, 0x03, 0xc4, 0x0d, 0x01, 0x02, 0xc8, 0x0d, 0x01, 0x02, + 0xcc, 0x0d, 0x01, 0x02, 0xd0, 0x0d, 0x01, 0x02, 0xb0, 0x3d, 0x02, 0x03, 0xb8, 0x3d, 0x02, 0x03, 0xc0, 0x3d, 0x02, 0x03, 0xd0, 0x25, 0x03, 0x03, 0xd8, 0x25, 0x03, 0x03, 0xe0, 0x25, 0x03, 0x03, + 0x20, 0x12, 0x04, 0x03, 0x28, 0x12, 0x04, 0x03, 0x88, 0x02, 0x05, 0x03, 0x90, 0x02, 0x05, 0x03, 0x10, 0x2b, 0x06, 0x04, 0x80, 0x17, 0x07, 0x04, 0xf0, 0x05, 0x08, 0x04, 0xa0, 0x30, 0x09, 0x05, + 0x60, 0x1c, 0x0a, 0x05, 0x40, 0x3a, 0x0c, 0x06, 0x80, 0x02, 0x0f, 0x06, 0x78, 0x13, 0x00, 0x03, 0x80, 0x13, 0x00, 0x03, 0x88, 0x13, 0x00, 0x03, 0xd4, 0x0d, 0x01, 0x02, 0xd8, 0x0d, 0x01, 0x02, + 0xdc, 0x0d, 0x01, 0x02, 0xe0, 0x0d, 0x01, 0x02, 0xc8, 0x3d, 0x02, 0x03, 0xd0, 0x3d, 0x02, 0x03, 0xd8, 0x3d, 0x02, 0x03, 0xe8, 0x25, 0x03, 0x03, 0xf0, 0x25, 0x03, 0x03, 0xf8, 0x25, 0x03, 0x03, + 0x30, 0x12, 0x04, 0x03, 0x38, 0x12, 0x04, 0x03, 0x98, 0x02, 0x05, 0x03, 0xa0, 0x02, 0x05, 0x03, 0x20, 0x2b, 0x06, 0x04, 0x90, 0x17, 0x07, 0x04, 0x00, 0x06, 0x08, 0x04, 0xc0, 0x30, 0x09, 0x05, + 0x80, 0x1c, 0x0a, 0x05, 0x80, 0x3a, 0x0c, 0x06, 0x80, 0x25, 0x10, 0x07, 0x90, 0x13, 0x00, 0x03, 0x98, 0x13, 0x00, 0x03, 0xa0, 0x13, 0x00, 0x03, 0xe4, 0x0d, 0x01, 0x02, 0xe8, 0x0d, 0x01, 0x02, + 0xec, 0x0d, 0x01, 0x02, 0xf0, 0x0d, 0x01, 0x02, 0xe0, 0x3d, 0x02, 0x03, 0xe8, 0x3d, 0x02, 0x03, 0xf0, 0x3d, 0x02, 0x03, 0x00, 0x26, 0x03, 0x03, 0x08, 0x26, 0x03, 0x03, 0x10, 0x26, 0x03, 0x03, + 0x40, 0x12, 0x04, 0x03, 0x48, 0x12, 0x04, 0x03, 0xa8, 0x02, 0x05, 0x03, 0xb0, 0x02, 0x05, 0x03, 0x30, 0x2b, 0x06, 0x04, 0xa0, 0x17, 0x07, 0x04, 0x10, 0x06, 0x08, 0x04, 0xe0, 0x30, 0x09, 0x05, + 0xa0, 0x1c, 0x0a, 0x05, 0xc0, 0x3a, 0x0c, 0x06, 0x00, 0x26, 0x10, 0x07, 0xa8, 0x13, 0x00, 0x03, 0xb0, 0x13, 0x00, 0x03, 0xb8, 0x13, 0x00, 0x03, 0xf4, 0x0d, 0x01, 0x02, 0xf8, 0x0d, 0x01, 0x02, + 0xfc, 0x0d, 0x01, 0x02, 0x00, 0x0e, 0x01, 0x02, 0xf8, 0x3d, 0x02, 0x03, 0x00, 0x3e, 0x02, 0x03, 0x08, 0x3e, 0x02, 0x03, 0x18, 0x26, 0x03, 0x03, 0x20, 0x26, 0x03, 0x03, 0x28, 0x26, 0x03, 0x03, + 0x50, 0x12, 0x04, 0x03, 0x58, 0x12, 0x04, 0x03, 0xb8, 0x02, 0x05, 0x03, 0xc0, 0x02, 0x05, 0x03, 0x40, 0x2b, 0x06, 0x04, 0xb0, 0x17, 0x07, 0x04, 0x20, 0x06, 0x08, 0x04, 0x00, 0x31, 0x09, 0x05, + 0xc0, 0x1c, 0x0a, 0x05, 0x00, 0x3b, 0x0c, 0x06, 0x80, 0x26, 0x10, 0x07, 0xc0, 0x13, 0x00, 0x03, 0xc8, 0x13, 0x00, 0x03, 0xd0, 0x13, 0x00, 0x03, 0x04, 0x0e, 0x01, 0x02, 0x08, 0x0e, 0x01, 0x02, + 0x0c, 0x0e, 0x01, 0x02, 0x10, 0x0e, 0x01, 0x02, 0x10, 0x3e, 0x02, 0x03, 0x18, 0x3e, 0x02, 0x03, 0x20, 0x3e, 0x02, 0x03, 0x30, 0x26, 0x03, 0x03, 0x38, 0x26, 0x03, 0x03, 0x40, 0x26, 0x03, 0x03, + 0x60, 0x12, 0x04, 0x03, 0x68, 0x12, 0x04, 0x03, 0xc8, 0x02, 0x05, 0x03, 0xd0, 0x02, 0x05, 0x03, 0x50, 0x2b, 0x06, 0x04, 0xc0, 0x17, 0x07, 0x04, 0x30, 0x06, 0x08, 0x04, 0x20, 0x31, 0x09, 0x05, + 0xe0, 0x1c, 0x0a, 0x05, 0x40, 0x3b, 0x0c, 0x06, 0x00, 0x27, 0x10, 0x07, 0xd8, 0x13, 0x00, 0x03, 0xe0, 0x13, 0x00, 0x03, 0xe8, 0x13, 0x00, 0x03, 0x14, 0x0e, 0x01, 0x02, 0x18, 0x0e, 0x01, 0x02, + 0x1c, 0x0e, 0x01, 0x02, 0x20, 0x0e, 0x01, 0x02, 0x28, 0x3e, 0x02, 0x03, 0x30, 0x3e, 0x02, 0x03, 0x38, 0x3e, 0x02, 0x03, 0x48, 0x26, 0x03, 0x03, 0x50, 0x26, 0x03, 0x03, 0x58, 0x26, 0x03, 0x03, + 0x70, 0x12, 0x04, 0x03, 0x78, 0x12, 0x04, 0x03, 0xd8, 0x02, 0x05, 0x03, 0xe0, 0x02, 0x05, 0x03, 0x60, 0x2b, 0x06, 0x04, 0xd0, 0x17, 0x07, 0x04, 0x40, 0x06, 0x08, 0x04, 0x40, 0x31, 0x09, 0x05, + 0x00, 0x1d, 0x0a, 0x05, 0x80, 0x3b, 0x0c, 0x06, 0x80, 0x27, 0x10, 0x07, 0xf0, 0x13, 0x00, 0x03, 0xf8, 0x13, 0x00, 0x03, 0x00, 0x14, 0x00, 0x03, 0x24, 0x0e, 0x01, 0x02, 0x28, 0x0e, 0x01, 0x02, + 0x2c, 0x0e, 0x01, 0x02, 0x30, 0x0e, 0x01, 0x02, 0x40, 0x3e, 0x02, 0x03, 0x48, 0x3e, 0x02, 0x03, 0x50, 0x3e, 0x02, 0x03, 0x60, 0x26, 0x03, 0x03, 0x68, 0x26, 0x03, 0x03, 0x70, 0x26, 0x03, 0x03, + 0x80, 0x12, 0x04, 0x03, 0x88, 0x12, 0x04, 0x03, 0xe8, 0x02, 0x05, 0x03, 0xf0, 0x02, 0x05, 0x03, 0x70, 0x2b, 0x06, 0x04, 0xe0, 0x17, 0x07, 0x04, 0x50, 0x06, 0x08, 0x04, 0x60, 0x31, 0x09, 0x05, + 0x20, 0x1d, 0x0a, 0x05, 0xc0, 0x3b, 0x0c, 0x06, 0x00, 0x28, 0x10, 0x07, 0x08, 0x14, 0x00, 0x03, 0x10, 0x14, 0x00, 0x03, 0x18, 0x14, 0x00, 0x03, 0x34, 0x0e, 0x01, 0x02, 0x38, 0x0e, 0x01, 0x02, + 0x3c, 0x0e, 0x01, 0x02, 0x40, 0x0e, 0x01, 0x02, 0x58, 0x3e, 0x02, 0x03, 0x60, 0x3e, 0x02, 0x03, 0x68, 0x3e, 0x02, 0x03, 0x78, 0x26, 0x03, 0x03, 0x80, 0x26, 0x03, 0x03, 0x88, 0x26, 0x03, 0x03, + 0x90, 0x12, 0x04, 0x03, 0x98, 0x12, 0x04, 0x03, 0xf8, 0x02, 0x05, 0x03, 0x00, 0x03, 0x05, 0x03, 0x80, 0x2b, 0x06, 0x04, 0xf0, 0x17, 0x07, 0x04, 0x60, 0x06, 0x08, 0x04, 0x80, 0x31, 0x09, 0x05, + 0x40, 0x1d, 0x0a, 0x05, 0x00, 0x3c, 0x0c, 0x06, 0x80, 0x28, 0x10, 0x07, 0x20, 0x14, 0x00, 0x03, 0x28, 0x14, 0x00, 0x03, 0x30, 0x14, 0x00, 0x03, 0x44, 0x0e, 0x01, 0x02, 0x48, 0x0e, 0x01, 0x02, + 0x4c, 0x0e, 0x01, 0x02, 0x50, 0x0e, 0x01, 0x02, 0x70, 0x3e, 0x02, 0x03, 0x78, 0x3e, 0x02, 0x03, 0x80, 0x3e, 0x02, 0x03, 0x90, 0x26, 0x03, 0x03, 0x98, 0x26, 0x03, 0x03, 0xa0, 0x26, 0x03, 0x03, + 0xa0, 0x12, 0x04, 0x03, 0xa8, 0x12, 0x04, 0x03, 0x08, 0x03, 0x05, 0x03, 0x10, 0x03, 0x05, 0x03, 0x90, 0x2b, 0x06, 0x04, 0x00, 0x18, 0x07, 0x04, 0x70, 0x06, 0x08, 0x04, 0xa0, 0x31, 0x09, 0x05, + 0x60, 0x1d, 0x0a, 0x05, 0x40, 0x3c, 0x0c, 0x06, 0x00, 0x29, 0x10, 0x07, 0x38, 0x14, 0x00, 0x03, 0x40, 0x14, 0x00, 0x03, 0x48, 0x14, 0x00, 0x03, 0x54, 0x0e, 0x01, 0x02, 0x58, 0x0e, 0x01, 0x02, + 0x5c, 0x0e, 0x01, 0x02, 0x60, 0x0e, 0x01, 0x02, 0x88, 0x3e, 0x02, 0x03, 0x90, 0x3e, 0x02, 0x03, 0x98, 0x3e, 0x02, 0x03, 0xa8, 0x26, 0x03, 0x03, 0xb0, 0x26, 0x03, 0x03, 0xb8, 0x26, 0x03, 0x03, + 0xb0, 0x12, 0x04, 0x03, 0xb8, 0x12, 0x04, 0x03, 0x18, 0x03, 0x05, 0x03, 0x20, 0x03, 0x05, 0x03, 0xa0, 0x2b, 0x06, 0x04, 0x10, 0x18, 0x07, 0x04, 0x80, 0x06, 0x08, 0x04, 0xc0, 0x31, 0x09, 0x05, + 0x80, 0x1d, 0x0a, 0x05, 0x80, 0x3c, 0x0c, 0x06, 0x80, 0x29, 0x10, 0x07, 0x50, 0x14, 0x00, 0x03, 0x58, 0x14, 0x00, 0x03, 0x60, 0x14, 0x00, 0x03, 0x64, 0x0e, 0x01, 0x02, 0x68, 0x0e, 0x01, 0x02, + 0x6c, 0x0e, 0x01, 0x02, 0x70, 0x0e, 0x01, 0x02, 0xa0, 0x3e, 0x02, 0x03, 0xa8, 0x3e, 0x02, 0x03, 0xb0, 0x3e, 0x02, 0x03, 0xc0, 0x26, 0x03, 0x03, 0xc8, 0x26, 0x03, 0x03, 0xd0, 0x26, 0x03, 0x03, + 0xc0, 0x12, 0x04, 0x03, 0xc8, 0x12, 0x04, 0x03, 0x28, 0x03, 0x05, 0x03, 0x30, 0x03, 0x05, 0x03, 0xb0, 0x2b, 0x06, 0x04, 0x20, 0x18, 0x07, 0x04, 0x90, 0x06, 0x08, 0x04, 0xe0, 0x31, 0x09, 0x05, + 0xa0, 0x1d, 0x0a, 0x05, 0xc0, 0x3c, 0x0c, 0x06, 0x00, 0x2a, 0x10, 0x07, 0x68, 0x14, 0x00, 0x03, 0x70, 0x14, 0x00, 0x03, 0x78, 0x14, 0x00, 0x03, 0x74, 0x0e, 0x01, 0x02, 0x78, 0x0e, 0x01, 0x02, + 0x7c, 0x0e, 0x01, 0x02, 0x80, 0x0e, 0x01, 0x02, 0xb8, 0x3e, 0x02, 0x03, 0xc0, 0x3e, 0x02, 0x03, 0xc8, 0x3e, 0x02, 0x03, 0xd8, 0x26, 0x03, 0x03, 0xe0, 0x26, 0x03, 0x03, 0xe8, 0x26, 0x03, 0x03, + 0xd0, 0x12, 0x04, 0x03, 0xd8, 0x12, 0x04, 0x03, 0x38, 0x03, 0x05, 0x03, 0x40, 0x03, 0x05, 0x03, 0xc0, 0x2b, 0x06, 0x04, 0x30, 0x18, 0x07, 0x04, 0xa0, 0x06, 0x08, 0x04, 0x00, 0x32, 0x09, 0x05, + 0xc0, 0x1d, 0x0a, 0x05, 0x00, 0x3d, 0x0c, 0x06, 0x80, 0x2a, 0x10, 0x07, 0x80, 0x14, 0x00, 0x03, 0x88, 0x14, 0x00, 0x03, 0x84, 0x0e, 0x01, 0x02, 0x88, 0x0e, 0x01, 0x02, 0x8c, 0x0e, 0x01, 0x02, + 0x90, 0x0e, 0x01, 0x02, 0x94, 0x0e, 0x01, 0x02, 0xd0, 0x3e, 0x02, 0x03, 0xd8, 0x3e, 0x02, 0x03, 0xe0, 0x3e, 0x02, 0x03, 0xf0, 0x26, 0x03, 0x03, 0xf8, 0x26, 0x03, 0x03, 0x00, 0x27, 0x03, 0x03, + 0xe0, 0x12, 0x04, 0x03, 0xe8, 0x12, 0x04, 0x03, 0x48, 0x03, 0x05, 0x03, 0x50, 0x03, 0x05, 0x03, 0xd0, 0x2b, 0x06, 0x04, 0x40, 0x18, 0x07, 0x04, 0xb0, 0x06, 0x08, 0x04, 0x20, 0x32, 0x09, 0x05, + 0xe0, 0x1d, 0x0a, 0x05, 0x40, 0x3d, 0x0c, 0x06, 0x00, 0x2b, 0x10, 0x07, 0x90, 0x14, 0x00, 0x03, 0x98, 0x14, 0x00, 0x03, 0x98, 0x0e, 0x01, 0x02, 0x9c, 0x0e, 0x01, 0x02, 0xa0, 0x0e, 0x01, 0x02, + 0xa4, 0x0e, 0x01, 0x02, 0xa8, 0x0e, 0x01, 0x02, 0xe8, 0x3e, 0x02, 0x03, 0xf0, 0x3e, 0x02, 0x03, 0xf8, 0x3e, 0x02, 0x03, 0x08, 0x27, 0x03, 0x03, 0x10, 0x27, 0x03, 0x03, 0x18, 0x27, 0x03, 0x03, + 0xf0, 0x12, 0x04, 0x03, 0xf8, 0x12, 0x04, 0x03, 0x58, 0x03, 0x05, 0x03, 0x60, 0x03, 0x05, 0x03, 0xe0, 0x2b, 0x06, 0x04, 0x50, 0x18, 0x07, 0x04, 0xc0, 0x06, 0x08, 0x04, 0x40, 0x32, 0x09, 0x05, + 0x00, 0x1e, 0x0a, 0x05, 0x80, 0x3d, 0x0c, 0x06, 0x80, 0x2b, 0x10, 0x07, 0xa0, 0x14, 0x00, 0x03, 0xa8, 0x14, 0x00, 0x03, 0xac, 0x0e, 0x01, 0x02, 0xb0, 0x0e, 0x01, 0x02, 0xb4, 0x0e, 0x01, 0x02, + 0xb8, 0x0e, 0x01, 0x02, 0xbc, 0x0e, 0x01, 0x02, 0x00, 0x3f, 0x02, 0x03, 0x08, 0x3f, 0x02, 0x03, 0x10, 0x3f, 0x02, 0x03, 0x20, 0x27, 0x03, 0x03, 0x28, 0x27, 0x03, 0x03, 0x30, 0x27, 0x03, 0x03, + 0x00, 0x13, 0x04, 0x03, 0x08, 0x13, 0x04, 0x03, 0x68, 0x03, 0x05, 0x03, 0x70, 0x03, 0x05, 0x03, 0xf0, 0x2b, 0x06, 0x04, 0x60, 0x18, 0x07, 0x04, 0xd0, 0x06, 0x08, 0x04, 0x60, 0x32, 0x09, 0x05, + 0x20, 0x1e, 0x0a, 0x05, 0xc0, 0x3d, 0x0c, 0x06, 0x00, 0x2c, 0x10, 0x07, 0xb0, 0x14, 0x00, 0x03, 0xb8, 0x14, 0x00, 0x03, 0xc0, 0x0e, 0x01, 0x02, 0xc4, 0x0e, 0x01, 0x02, 0xc8, 0x0e, 0x01, 0x02, + 0xcc, 0x0e, 0x01, 0x02, 0xd0, 0x0e, 0x01, 0x02, 0x18, 0x3f, 0x02, 0x03, 0x20, 0x3f, 0x02, 0x03, 0x28, 0x3f, 0x02, 0x03, 0x38, 0x27, 0x03, 0x03, 0x40, 0x27, 0x03, 0x03, 0x48, 0x27, 0x03, 0x03, + 0x10, 0x13, 0x04, 0x03, 0x18, 0x13, 0x04, 0x03, 0x78, 0x03, 0x05, 0x03, 0x80, 0x03, 0x05, 0x03, 0x00, 0x2c, 0x06, 0x04, 0x70, 0x18, 0x07, 0x04, 0xe0, 0x06, 0x08, 0x04, 0x80, 0x32, 0x09, 0x05, + 0x40, 0x1e, 0x0a, 0x05, 0x00, 0x3e, 0x0c, 0x06, 0x80, 0x2c, 0x10, 0x07, 0xc0, 0x14, 0x00, 0x03, 0xc8, 0x14, 0x00, 0x03, 0xd4, 0x0e, 0x01, 0x02, 0xd8, 0x0e, 0x01, 0x02, 0xdc, 0x0e, 0x01, 0x02, + 0xe0, 0x0e, 0x01, 0x02, 0xe4, 0x0e, 0x01, 0x02, 0x30, 0x3f, 0x02, 0x03, 0x38, 0x3f, 0x02, 0x03, 0x40, 0x3f, 0x02, 0x03, 0x50, 0x27, 0x03, 0x03, 0x58, 0x27, 0x03, 0x03, 0x60, 0x27, 0x03, 0x03, + 0x20, 0x13, 0x04, 0x03, 0x28, 0x13, 0x04, 0x03, 0x88, 0x03, 0x05, 0x03, 0x90, 0x03, 0x05, 0x03, 0x10, 0x2c, 0x06, 0x04, 0x80, 0x18, 0x07, 0x04, 0xf0, 0x06, 0x08, 0x04, 0xa0, 0x32, 0x09, 0x05, + 0x60, 0x1e, 0x0a, 0x05, 0x40, 0x3e, 0x0c, 0x06, 0x80, 0x11, 0x11, 0x07, 0xd0, 0x14, 0x00, 0x03, 0xd8, 0x14, 0x00, 0x03, 0xe8, 0x0e, 0x01, 0x02, 0xec, 0x0e, 0x01, 0x02, 0xf0, 0x0e, 0x01, 0x02, + 0xf4, 0x0e, 0x01, 0x02, 0xf8, 0x0e, 0x01, 0x02, 0x48, 0x3f, 0x02, 0x03, 0x50, 0x3f, 0x02, 0x03, 0x58, 0x3f, 0x02, 0x03, 0x68, 0x27, 0x03, 0x03, 0x70, 0x27, 0x03, 0x03, 0x78, 0x27, 0x03, 0x03, + 0x30, 0x13, 0x04, 0x03, 0x38, 0x13, 0x04, 0x03, 0x98, 0x03, 0x05, 0x03, 0xa0, 0x03, 0x05, 0x03, 0x20, 0x2c, 0x06, 0x04, 0x90, 0x18, 0x07, 0x04, 0x00, 0x07, 0x08, 0x04, 0xc0, 0x32, 0x09, 0x05, + 0x80, 0x1e, 0x0a, 0x05, 0x80, 0x3e, 0x0c, 0x06, 0x00, 0x12, 0x11, 0x07, 0xe0, 0x14, 0x00, 0x03, 0xe8, 0x14, 0x00, 0x03, 0xfc, 0x0e, 0x01, 0x02, 0x00, 0x0f, 0x01, 0x02, 0x04, 0x0f, 0x01, 0x02, + 0x08, 0x0f, 0x01, 0x02, 0x0c, 0x0f, 0x01, 0x02, 0x60, 0x3f, 0x02, 0x03, 0x68, 0x3f, 0x02, 0x03, 0x70, 0x3f, 0x02, 0x03, 0x80, 0x27, 0x03, 0x03, 0x88, 0x27, 0x03, 0x03, 0x90, 0x27, 0x03, 0x03, + 0x40, 0x13, 0x04, 0x03, 0x48, 0x13, 0x04, 0x03, 0xa8, 0x03, 0x05, 0x03, 0xb0, 0x03, 0x05, 0x03, 0x30, 0x2c, 0x06, 0x04, 0xa0, 0x18, 0x07, 0x04, 0x10, 0x07, 0x08, 0x04, 0xe0, 0x32, 0x09, 0x05, + 0xa0, 0x1e, 0x0a, 0x05, 0xc0, 0x1f, 0x0d, 0x06, 0x80, 0x12, 0x11, 0x07, 0xf0, 0x14, 0x00, 0x03, 0xf8, 0x14, 0x00, 0x03, 0x10, 0x0f, 0x01, 0x02, 0x14, 0x0f, 0x01, 0x02, 0x18, 0x0f, 0x01, 0x02, + 0x1c, 0x0f, 0x01, 0x02, 0x20, 0x0f, 0x01, 0x02, 0x78, 0x3f, 0x02, 0x03, 0x80, 0x3f, 0x02, 0x03, 0x88, 0x3f, 0x02, 0x03, 0x98, 0x27, 0x03, 0x03, 0xa0, 0x27, 0x03, 0x03, 0xa8, 0x27, 0x03, 0x03, + 0x50, 0x13, 0x04, 0x03, 0x58, 0x13, 0x04, 0x03, 0xb8, 0x03, 0x05, 0x03, 0xc0, 0x03, 0x05, 0x03, 0x40, 0x2c, 0x06, 0x04, 0xb0, 0x18, 0x07, 0x04, 0x20, 0x07, 0x08, 0x04, 0x00, 0x33, 0x09, 0x05, + 0xc0, 0x1e, 0x0a, 0x05, 0x00, 0x20, 0x0d, 0x06, 0x00, 0x13, 0x11, 0x07, 0x00, 0x15, 0x00, 0x03, 0x08, 0x15, 0x00, 0x03, 0x24, 0x0f, 0x01, 0x02, 0x28, 0x0f, 0x01, 0x02, 0x2c, 0x0f, 0x01, 0x02, + 0x30, 0x0f, 0x01, 0x02, 0x34, 0x0f, 0x01, 0x02, 0x90, 0x3f, 0x02, 0x03, 0x98, 0x3f, 0x02, 0x03, 0xa0, 0x3f, 0x02, 0x03, 0xb0, 0x27, 0x03, 0x03, 0xb8, 0x27, 0x03, 0x03, 0xc0, 0x27, 0x03, 0x03, + 0x60, 0x13, 0x04, 0x03, 0x68, 0x13, 0x04, 0x03, 0xc8, 0x03, 0x05, 0x03, 0xd0, 0x03, 0x05, 0x03, 0x50, 0x2c, 0x06, 0x04, 0xc0, 0x18, 0x07, 0x04, 0x30, 0x07, 0x08, 0x04, 0x20, 0x33, 0x09, 0x05, + 0xe0, 0x1e, 0x0a, 0x05, 0x40, 0x20, 0x0d, 0x06, 0x80, 0x13, 0x11, 0x07, 0x10, 0x15, 0x00, 0x03, 0x18, 0x15, 0x00, 0x03, 0x38, 0x0f, 0x01, 0x02, 0x3c, 0x0f, 0x01, 0x02, 0x40, 0x0f, 0x01, 0x02, + 0x44, 0x0f, 0x01, 0x02, 0x48, 0x0f, 0x01, 0x02, 0xa8, 0x3f, 0x02, 0x03, 0xb0, 0x3f, 0x02, 0x03, 0xb8, 0x3f, 0x02, 0x03, 0xc8, 0x27, 0x03, 0x03, 0xd0, 0x27, 0x03, 0x03, 0xd8, 0x27, 0x03, 0x03, + 0x70, 0x13, 0x04, 0x03, 0x78, 0x13, 0x04, 0x03, 0xd8, 0x03, 0x05, 0x03, 0xe0, 0x03, 0x05, 0x03, 0x60, 0x2c, 0x06, 0x04, 0xd0, 0x18, 0x07, 0x04, 0x40, 0x07, 0x08, 0x04, 0x40, 0x33, 0x09, 0x05, + 0x00, 0x1f, 0x0a, 0x05, 0x80, 0x20, 0x0d, 0x06, 0x00, 0x14, 0x11, 0x07, 0x20, 0x15, 0x00, 0x03, 0x28, 0x15, 0x00, 0x03, 0x4c, 0x0f, 0x01, 0x02, 0x50, 0x0f, 0x01, 0x02, 0x54, 0x0f, 0x01, 0x02, + 0x58, 0x0f, 0x01, 0x02, 0x5c, 0x0f, 0x01, 0x02, 0xc0, 0x3f, 0x02, 0x03, 0xc8, 0x3f, 0x02, 0x03, 0xd0, 0x3f, 0x02, 0x03, 0xe0, 0x27, 0x03, 0x03, 0xe8, 0x27, 0x03, 0x03, 0xf0, 0x27, 0x03, 0x03, + 0x80, 0x13, 0x04, 0x03, 0x88, 0x13, 0x04, 0x03, 0xe8, 0x03, 0x05, 0x03, 0xf0, 0x03, 0x05, 0x03, 0x70, 0x2c, 0x06, 0x04, 0xe0, 0x18, 0x07, 0x04, 0x50, 0x07, 0x08, 0x04, 0x60, 0x33, 0x09, 0x05, + 0x20, 0x1f, 0x0a, 0x05, 0xc0, 0x20, 0x0d, 0x06, 0x80, 0x14, 0x11, 0x07, 0x30, 0x15, 0x00, 0x03, 0x38, 0x15, 0x00, 0x03, 0x60, 0x0f, 0x01, 0x02, 0x64, 0x0f, 0x01, 0x02, 0x68, 0x0f, 0x01, 0x02, + 0x6c, 0x0f, 0x01, 0x02, 0x70, 0x0f, 0x01, 0x02, 0xd8, 0x3f, 0x02, 0x03, 0xe0, 0x3f, 0x02, 0x03, 0xe8, 0x3f, 0x02, 0x03, 0xf8, 0x27, 0x03, 0x03, 0x00, 0x28, 0x03, 0x03, 0x08, 0x28, 0x03, 0x03, + 0x90, 0x13, 0x04, 0x03, 0x98, 0x13, 0x04, 0x03, 0xf8, 0x03, 0x05, 0x03, 0x00, 0x04, 0x05, 0x03, 0x80, 0x2c, 0x06, 0x04, 0xf0, 0x18, 0x07, 0x04, 0x60, 0x07, 0x08, 0x04, 0x80, 0x33, 0x09, 0x05, + 0x40, 0x1f, 0x0a, 0x05, 0x00, 0x21, 0x0d, 0x06, 0x00, 0x15, 0x11, 0x07, 0x40, 0x15, 0x00, 0x03, 0x48, 0x15, 0x00, 0x03, 0x74, 0x0f, 0x01, 0x02, 0x78, 0x0f, 0x01, 0x02, 0x7c, 0x0f, 0x01, 0x02, + 0x80, 0x0f, 0x01, 0x02, 0x84, 0x0f, 0x01, 0x02, 0xf0, 0x3f, 0x02, 0x03, 0xf8, 0x3f, 0x02, 0x03, 0x00, 0x00, 0x02, 0x02, 0x10, 0x28, 0x03, 0x03, 0x18, 0x28, 0x03, 0x03, 0x20, 0x28, 0x03, 0x03, + 0xa0, 0x13, 0x04, 0x03, 0xa8, 0x13, 0x04, 0x03, 0x08, 0x04, 0x05, 0x03, 0x10, 0x04, 0x05, 0x03, 0x90, 0x2c, 0x06, 0x04, 0x00, 0x19, 0x07, 0x04, 0x70, 0x07, 0x08, 0x04, 0xa0, 0x33, 0x09, 0x05, + 0x60, 0x1f, 0x0a, 0x05, 0x40, 0x21, 0x0d, 0x06, 0x80, 0x15, 0x11, 0x07, 0x50, 0x15, 0x00, 0x03, 0x58, 0x15, 0x00, 0x03, 0x88, 0x0f, 0x01, 0x02, 0x8c, 0x0f, 0x01, 0x02, 0x90, 0x0f, 0x01, 0x02, + 0x94, 0x0f, 0x01, 0x02, 0x98, 0x0f, 0x01, 0x02, 0x04, 0x00, 0x02, 0x02, 0x08, 0x00, 0x02, 0x02, 0x0c, 0x00, 0x02, 0x02, 0x28, 0x28, 0x03, 0x03, 0x30, 0x28, 0x03, 0x03, 0x38, 0x28, 0x03, 0x03, + 0xb0, 0x13, 0x04, 0x03, 0xb8, 0x13, 0x04, 0x03, 0x18, 0x04, 0x05, 0x03, 0x20, 0x04, 0x05, 0x03, 0xa0, 0x2c, 0x06, 0x04, 0x10, 0x19, 0x07, 0x04, 0x80, 0x07, 0x08, 0x04, 0xc0, 0x33, 0x09, 0x05, + 0x80, 0x1f, 0x0a, 0x05, 0x80, 0x21, 0x0d, 0x06, 0x00, 0x16, 0x11, 0x07, 0x60, 0x15, 0x00, 0x03, 0x68, 0x15, 0x00, 0x03, 0x9c, 0x0f, 0x01, 0x02, 0xa0, 0x0f, 0x01, 0x02, 0xa4, 0x0f, 0x01, 0x02, + 0xa8, 0x0f, 0x01, 0x02, 0xac, 0x0f, 0x01, 0x02, 0x10, 0x00, 0x02, 0x02, 0x14, 0x00, 0x02, 0x02, 0x18, 0x00, 0x02, 0x02, 0x40, 0x28, 0x03, 0x03, 0x48, 0x28, 0x03, 0x03, 0x50, 0x28, 0x03, 0x03, + 0xc0, 0x13, 0x04, 0x03, 0xc8, 0x13, 0x04, 0x03, 0x28, 0x04, 0x05, 0x03, 0x30, 0x04, 0x05, 0x03, 0xb0, 0x2c, 0x06, 0x04, 0x20, 0x19, 0x07, 0x04, 0x90, 0x07, 0x08, 0x04, 0xe0, 0x33, 0x09, 0x05, + 0x60, 0x09, 0x0b, 0x05, 0xc0, 0x21, 0x0d, 0x06, 0x80, 0x16, 0x11, 0x07, 0x70, 0x15, 0x00, 0x03, 0x78, 0x15, 0x00, 0x03, 0xb0, 0x0f, 0x01, 0x02, 0xb4, 0x0f, 0x01, 0x02, 0xb8, 0x0f, 0x01, 0x02, + 0xbc, 0x0f, 0x01, 0x02, 0x1c, 0x00, 0x02, 0x02, 0x20, 0x00, 0x02, 0x02, 0x24, 0x00, 0x02, 0x02, 0x28, 0x00, 0x02, 0x02, 0x58, 0x28, 0x03, 0x03, 0x60, 0x28, 0x03, 0x03, 0x68, 0x28, 0x03, 0x03, + 0xd0, 0x13, 0x04, 0x03, 0xd8, 0x13, 0x04, 0x03, 0x38, 0x04, 0x05, 0x03, 0x40, 0x04, 0x05, 0x03, 0xc0, 0x2c, 0x06, 0x04, 0x30, 0x19, 0x07, 0x04, 0xa0, 0x07, 0x08, 0x04, 0x00, 0x34, 0x09, 0x05, + 0x80, 0x09, 0x0b, 0x05, 0x00, 0x22, 0x0d, 0x06, 0x80, 0x02, 0x12, 0x07, 0x80, 0x15, 0x00, 0x03, 0x88, 0x15, 0x00, 0x03, 0xc0, 0x0f, 0x01, 0x02, 0xc4, 0x0f, 0x01, 0x02, 0xc8, 0x0f, 0x01, 0x02, + 0xcc, 0x0f, 0x01, 0x02, 0x2c, 0x00, 0x02, 0x02, 0x30, 0x00, 0x02, 0x02, 0x34, 0x00, 0x02, 0x02, 0x38, 0x00, 0x02, 0x02, 0x70, 0x28, 0x03, 0x03, 0x78, 0x28, 0x03, 0x03, 0x80, 0x28, 0x03, 0x03, + 0xe0, 0x13, 0x04, 0x03, 0xe8, 0x13, 0x04, 0x03, 0x48, 0x04, 0x05, 0x03, 0x50, 0x04, 0x05, 0x03, 0xd0, 0x2c, 0x06, 0x04, 0x40, 0x19, 0x07, 0x04, 0xb0, 0x07, 0x08, 0x04, 0x20, 0x34, 0x09, 0x05, + 0xa0, 0x09, 0x0b, 0x05, 0x40, 0x22, 0x0d, 0x06, 0x00, 0x03, 0x12, 0x07, 0x90, 0x15, 0x00, 0x03, 0x98, 0x15, 0x00, 0x03, 0xd0, 0x0f, 0x01, 0x02, 0xd4, 0x0f, 0x01, 0x02, 0xd8, 0x0f, 0x01, 0x02, + 0xdc, 0x0f, 0x01, 0x02, 0x3c, 0x00, 0x02, 0x02, 0x40, 0x00, 0x02, 0x02, 0x44, 0x00, 0x02, 0x02, 0x48, 0x00, 0x02, 0x02, 0x88, 0x28, 0x03, 0x03, 0x90, 0x28, 0x03, 0x03, 0x98, 0x28, 0x03, 0x03, + 0xf0, 0x13, 0x04, 0x03, 0xf8, 0x13, 0x04, 0x03, 0x58, 0x04, 0x05, 0x03, 0x60, 0x04, 0x05, 0x03, 0xe0, 0x2c, 0x06, 0x04, 0x50, 0x19, 0x07, 0x04, 0xc0, 0x07, 0x08, 0x04, 0x40, 0x34, 0x09, 0x05, + 0xc0, 0x09, 0x0b, 0x05, 0x80, 0x22, 0x0d, 0x06, 0x80, 0x03, 0x12, 0x07, 0xa0, 0x15, 0x00, 0x03, 0xa8, 0x15, 0x00, 0x03, 0xe0, 0x0f, 0x01, 0x02, 0xe4, 0x0f, 0x01, 0x02, 0xe8, 0x0f, 0x01, 0x02, + 0xec, 0x0f, 0x01, 0x02, 0x4c, 0x00, 0x02, 0x02, 0x50, 0x00, 0x02, 0x02, 0x54, 0x00, 0x02, 0x02, 0x58, 0x00, 0x02, 0x02, 0xa0, 0x28, 0x03, 0x03, 0xa8, 0x28, 0x03, 0x03, 0xb0, 0x28, 0x03, 0x03, + 0x00, 0x14, 0x04, 0x03, 0x08, 0x14, 0x04, 0x03, 0x68, 0x04, 0x05, 0x03, 0x70, 0x04, 0x05, 0x03, 0xf0, 0x2c, 0x06, 0x04, 0x60, 0x19, 0x07, 0x04, 0xd0, 0x07, 0x08, 0x04, 0x60, 0x34, 0x09, 0x05, + 0xe0, 0x09, 0x0b, 0x05, 0xc0, 0x22, 0x0d, 0x06, 0x00, 0x04, 0x12, 0x07, 0xb0, 0x15, 0x00, 0x03, 0xb8, 0x15, 0x00, 0x03, 0xf0, 0x0f, 0x01, 0x02, 0xf4, 0x0f, 0x01, 0x02, 0xf8, 0x0f, 0x01, 0x02, + 0xfc, 0x0f, 0x01, 0x02, 0x5c, 0x00, 0x02, 0x02, 0x60, 0x00, 0x02, 0x02, 0x64, 0x00, 0x02, 0x02, 0x68, 0x00, 0x02, 0x02, 0xb8, 0x28, 0x03, 0x03, 0xc0, 0x28, 0x03, 0x03, 0xc8, 0x28, 0x03, 0x03, + 0x10, 0x14, 0x04, 0x03, 0x18, 0x14, 0x04, 0x03, 0x78, 0x04, 0x05, 0x03, 0x80, 0x04, 0x05, 0x03, 0x00, 0x2d, 0x06, 0x04, 0x70, 0x19, 0x07, 0x04, 0xe0, 0x07, 0x08, 0x04, 0x80, 0x34, 0x09, 0x05, + 0x00, 0x0a, 0x0b, 0x05, 0x00, 0x23, 0x0d, 0x06, 0x80, 0x04, 0x12, 0x07, 0xc0, 0x15, 0x00, 0x03, 0xc8, 0x15, 0x00, 0x03, 0x00, 0x10, 0x01, 0x02, 0x04, 0x10, 0x01, 0x02, 0x08, 0x10, 0x01, 0x02, + 0x0c, 0x10, 0x01, 0x02, 0x6c, 0x00, 0x02, 0x02, 0x70, 0x00, 0x02, 0x02, 0x74, 0x00, 0x02, 0x02, 0x78, 0x00, 0x02, 0x02, 0xd0, 0x28, 0x03, 0x03, 0xd8, 0x28, 0x03, 0x03, 0xe0, 0x28, 0x03, 0x03, + 0x20, 0x14, 0x04, 0x03, 0x28, 0x14, 0x04, 0x03, 0x88, 0x04, 0x05, 0x03, 0x90, 0x04, 0x05, 0x03, 0x10, 0x2d, 0x06, 0x04, 0x80, 0x19, 0x07, 0x04, 0xf0, 0x07, 0x08, 0x04, 0xa0, 0x34, 0x09, 0x05, + 0x20, 0x0a, 0x0b, 0x05, 0x40, 0x23, 0x0d, 0x06, 0x00, 0x05, 0x12, 0x07, 0xd0, 0x15, 0x00, 0x03, 0xd8, 0x15, 0x00, 0x03, 0x10, 0x10, 0x01, 0x02, 0x14, 0x10, 0x01, 0x02, 0x18, 0x10, 0x01, 0x02, + 0x1c, 0x10, 0x01, 0x02, 0x7c, 0x00, 0x02, 0x02, 0x80, 0x00, 0x02, 0x02, 0x84, 0x00, 0x02, 0x02, 0x88, 0x00, 0x02, 0x02, 0xe8, 0x28, 0x03, 0x03, 0xf0, 0x28, 0x03, 0x03, 0xf8, 0x28, 0x03, 0x03, + 0x30, 0x14, 0x04, 0x03, 0x38, 0x14, 0x04, 0x03, 0x98, 0x04, 0x05, 0x03, 0x20, 0x2d, 0x06, 0x04, 0x30, 0x2d, 0x06, 0x04, 0x90, 0x19, 0x07, 0x04, 0x00, 0x08, 0x08, 0x04, 0xc0, 0x34, 0x09, 0x05, + 0x40, 0x0a, 0x0b, 0x05, 0x80, 0x23, 0x0d, 0x06, 0x80, 0x05, 0x12, 0x07, 0xe0, 0x15, 0x00, 0x03, 0xe8, 0x15, 0x00, 0x03, 0x20, 0x10, 0x01, 0x02, 0x24, 0x10, 0x01, 0x02, 0x28, 0x10, 0x01, 0x02, + 0x2c, 0x10, 0x01, 0x02, 0x8c, 0x00, 0x02, 0x02, 0x90, 0x00, 0x02, 0x02, 0x94, 0x00, 0x02, 0x02, 0x98, 0x00, 0x02, 0x02, 0x00, 0x29, 0x03, 0x03, 0x08, 0x29, 0x03, 0x03, 0x10, 0x29, 0x03, 0x03, + 0x40, 0x14, 0x04, 0x03, 0x48, 0x14, 0x04, 0x03, 0xa0, 0x04, 0x05, 0x03, 0x40, 0x2d, 0x06, 0x04, 0x50, 0x2d, 0x06, 0x04, 0xa0, 0x19, 0x07, 0x04, 0x10, 0x08, 0x08, 0x04, 0xe0, 0x34, 0x09, 0x05, + 0x60, 0x0a, 0x0b, 0x05, 0xc0, 0x23, 0x0d, 0x06, 0x00, 0x06, 0x12, 0x07, 0xf0, 0x15, 0x00, 0x03, 0xf8, 0x15, 0x00, 0x03, 0x30, 0x10, 0x01, 0x02, 0x34, 0x10, 0x01, 0x02, 0x38, 0x10, 0x01, 0x02, + 0x3c, 0x10, 0x01, 0x02, 0x9c, 0x00, 0x02, 0x02, 0xa0, 0x00, 0x02, 0x02, 0xa4, 0x00, 0x02, 0x02, 0xa8, 0x00, 0x02, 0x02, 0x18, 0x29, 0x03, 0x03, 0x20, 0x29, 0x03, 0x03, 0x50, 0x14, 0x04, 0x03, + 0x58, 0x14, 0x04, 0x03, 0x60, 0x14, 0x04, 0x03, 0xa8, 0x04, 0x05, 0x03, 0x60, 0x2d, 0x06, 0x04, 0x70, 0x2d, 0x06, 0x04, 0xb0, 0x19, 0x07, 0x04, 0x20, 0x08, 0x08, 0x04, 0x00, 0x35, 0x09, 0x05, + 0x80, 0x0a, 0x0b, 0x05, 0x00, 0x24, 0x0d, 0x06, 0x80, 0x06, 0x12, 0x07, 0x00, 0x16, 0x00, 0x03, 0x08, 0x16, 0x00, 0x03, 0x40, 0x10, 0x01, 0x02, 0x44, 0x10, 0x01, 0x02, 0x48, 0x10, 0x01, 0x02, + 0x4c, 0x10, 0x01, 0x02, 0xac, 0x00, 0x02, 0x02, 0xb0, 0x00, 0x02, 0x02, 0xb4, 0x00, 0x02, 0x02, 0xb8, 0x00, 0x02, 0x02, 0x28, 0x29, 0x03, 0x03, 0x30, 0x29, 0x03, 0x03, 0x68, 0x14, 0x04, 0x03, + 0x70, 0x14, 0x04, 0x03, 0x78, 0x14, 0x04, 0x03, 0xb0, 0x04, 0x05, 0x03, 0x80, 0x2d, 0x06, 0x04, 0x90, 0x2d, 0x06, 0x04, 0xc0, 0x19, 0x07, 0x04, 0x30, 0x08, 0x08, 0x04, 0x20, 0x35, 0x09, 0x05, + 0xa0, 0x0a, 0x0b, 0x05, 0x40, 0x24, 0x0d, 0x06, 0x00, 0x07, 0x12, 0x07, 0x10, 0x16, 0x00, 0x03, 0x18, 0x16, 0x00, 0x03, 0x50, 0x10, 0x01, 0x02, 0x54, 0x10, 0x01, 0x02, 0x58, 0x10, 0x01, 0x02, + 0x5c, 0x10, 0x01, 0x02, 0xbc, 0x00, 0x02, 0x02, 0xc0, 0x00, 0x02, 0x02, 0xc4, 0x00, 0x02, 0x02, 0xc8, 0x00, 0x02, 0x02, 0x38, 0x29, 0x03, 0x03, 0x40, 0x29, 0x03, 0x03, 0x80, 0x14, 0x04, 0x03, + 0x88, 0x14, 0x04, 0x03, 0x90, 0x14, 0x04, 0x03, 0xb8, 0x04, 0x05, 0x03, 0xa0, 0x2d, 0x06, 0x04, 0xb0, 0x2d, 0x06, 0x04, 0xd0, 0x19, 0x07, 0x04, 0x40, 0x08, 0x08, 0x04, 0x40, 0x35, 0x09, 0x05, + 0xc0, 0x0a, 0x0b, 0x05, 0x80, 0x24, 0x0d, 0x06, 0x00, 0x2a, 0x13, 0x08, 0x20, 0x16, 0x00, 0x03, 0x28, 0x16, 0x00, 0x03, 0x60, 0x10, 0x01, 0x02, 0x64, 0x10, 0x01, 0x02, 0x68, 0x10, 0x01, 0x02, + 0x6c, 0x10, 0x01, 0x02, 0xcc, 0x00, 0x02, 0x02, 0xd0, 0x00, 0x02, 0x02, 0xd4, 0x00, 0x02, 0x02, 0xd8, 0x00, 0x02, 0x02, 0x48, 0x29, 0x03, 0x03, 0x50, 0x29, 0x03, 0x03, 0x98, 0x14, 0x04, 0x03, + 0xa0, 0x14, 0x04, 0x03, 0xa8, 0x14, 0x04, 0x03, 0xc0, 0x04, 0x05, 0x03, 0xc0, 0x2d, 0x06, 0x04, 0xd0, 0x2d, 0x06, 0x04, 0xe0, 0x19, 0x07, 0x04, 0x50, 0x08, 0x08, 0x04, 0x60, 0x35, 0x09, 0x05, + 0xe0, 0x0a, 0x0b, 0x05, 0xc0, 0x24, 0x0d, 0x06, 0x00, 0x2b, 0x13, 0x08, 0x30, 0x16, 0x00, 0x03, 0x38, 0x16, 0x00, 0x03, 0x70, 0x10, 0x01, 0x02, 0x74, 0x10, 0x01, 0x02, 0x78, 0x10, 0x01, 0x02, + 0x7c, 0x10, 0x01, 0x02, 0xdc, 0x00, 0x02, 0x02, 0xe0, 0x00, 0x02, 0x02, 0xe4, 0x00, 0x02, 0x02, 0xe8, 0x00, 0x02, 0x02, 0x58, 0x29, 0x03, 0x03, 0x60, 0x29, 0x03, 0x03, 0xb0, 0x14, 0x04, 0x03, + 0xb8, 0x14, 0x04, 0x03, 0xc0, 0x14, 0x04, 0x03, 0xc8, 0x04, 0x05, 0x03, 0xe0, 0x2d, 0x06, 0x04, 0xf0, 0x2d, 0x06, 0x04, 0xf0, 0x19, 0x07, 0x04, 0x60, 0x08, 0x08, 0x04, 0x80, 0x35, 0x09, 0x05, + 0x00, 0x0b, 0x0b, 0x05, 0x00, 0x25, 0x0d, 0x06, 0x00, 0x2c, 0x13, 0x08, 0x40, 0x16, 0x00, 0x03, 0x48, 0x16, 0x00, 0x03, 0x80, 0x10, 0x01, 0x02, 0x84, 0x10, 0x01, 0x02, 0x88, 0x10, 0x01, 0x02, + 0x8c, 0x10, 0x01, 0x02, 0xec, 0x00, 0x02, 0x02, 0xf0, 0x00, 0x02, 0x02, 0xf4, 0x00, 0x02, 0x02, 0xf8, 0x00, 0x02, 0x02, 0x68, 0x29, 0x03, 0x03, 0x70, 0x29, 0x03, 0x03, 0xc8, 0x14, 0x04, 0x03, + 0xd0, 0x14, 0x04, 0x03, 0xd8, 0x14, 0x04, 0x03, 0xd0, 0x04, 0x05, 0x03, 0x00, 0x2e, 0x06, 0x04, 0x10, 0x2e, 0x06, 0x04, 0x00, 0x1a, 0x07, 0x04, 0x70, 0x08, 0x08, 0x04, 0xa0, 0x35, 0x09, 0x05, + 0x20, 0x0b, 0x0b, 0x05, 0x40, 0x25, 0x0d, 0x06, 0x00, 0x2d, 0x13, 0x08, 0x50, 0x16, 0x00, 0x03, 0x58, 0x16, 0x00, 0x03, 0x90, 0x10, 0x01, 0x02, 0x94, 0x10, 0x01, 0x02, 0x98, 0x10, 0x01, 0x02, + 0x9c, 0x10, 0x01, 0x02, 0xfc, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x04, 0x01, 0x02, 0x02, 0x08, 0x01, 0x02, 0x02, 0x78, 0x29, 0x03, 0x03, 0x80, 0x29, 0x03, 0x03, 0xe0, 0x14, 0x04, 0x03, + 0xe8, 0x14, 0x04, 0x03, 0xf0, 0x14, 0x04, 0x03, 0xd8, 0x04, 0x05, 0x03, 0x20, 0x2e, 0x06, 0x04, 0x30, 0x2e, 0x06, 0x04, 0x10, 0x1a, 0x07, 0x04, 0x80, 0x08, 0x08, 0x04, 0xc0, 0x35, 0x09, 0x05, + 0x40, 0x0b, 0x0b, 0x05, 0x80, 0x25, 0x0d, 0x06, 0x00, 0x2e, 0x13, 0x08, 0x60, 0x16, 0x00, 0x03, 0x68, 0x16, 0x00, 0x03, 0xa0, 0x10, 0x01, 0x02, 0xa4, 0x10, 0x01, 0x02, 0xa8, 0x10, 0x01, 0x02, + 0xac, 0x10, 0x01, 0x02, 0x0c, 0x01, 0x02, 0x02, 0x10, 0x01, 0x02, 0x02, 0x14, 0x01, 0x02, 0x02, 0x18, 0x01, 0x02, 0x02, 0x88, 0x29, 0x03, 0x03, 0x90, 0x29, 0x03, 0x03, 0xf8, 0x14, 0x04, 0x03, + 0x00, 0x15, 0x04, 0x03, 0x08, 0x15, 0x04, 0x03, 0xe0, 0x04, 0x05, 0x03, 0x40, 0x2e, 0x06, 0x04, 0x50, 0x2e, 0x06, 0x04, 0x20, 0x1a, 0x07, 0x04, 0x90, 0x08, 0x08, 0x04, 0xe0, 0x35, 0x09, 0x05, + 0x60, 0x0b, 0x0b, 0x05, 0xc0, 0x25, 0x0d, 0x06, 0x00, 0x2f, 0x13, 0x08, 0x70, 0x16, 0x00, 0x03, 0x78, 0x16, 0x00, 0x03, 0xb0, 0x10, 0x01, 0x02, 0xb4, 0x10, 0x01, 0x02, 0xb8, 0x10, 0x01, 0x02, + 0xbc, 0x10, 0x01, 0x02, 0x1c, 0x01, 0x02, 0x02, 0x20, 0x01, 0x02, 0x02, 0x24, 0x01, 0x02, 0x02, 0x28, 0x01, 0x02, 0x02, 0x98, 0x29, 0x03, 0x03, 0xa0, 0x29, 0x03, 0x03, 0x10, 0x15, 0x04, 0x03, + 0x18, 0x15, 0x04, 0x03, 0x20, 0x15, 0x04, 0x03, 0xe8, 0x04, 0x05, 0x03, 0x60, 0x2e, 0x06, 0x04, 0x70, 0x2e, 0x06, 0x04, 0x30, 0x1a, 0x07, 0x04, 0xa0, 0x08, 0x08, 0x04, 0x00, 0x36, 0x09, 0x05, + 0x80, 0x0b, 0x0b, 0x05, 0x00, 0x26, 0x0d, 0x06, 0x00, 0x30, 0x13, 0x08, 0x80, 0x16, 0x00, 0x03, 0x88, 0x16, 0x00, 0x03, 0xc0, 0x10, 0x01, 0x02, 0xc4, 0x10, 0x01, 0x02, 0xc8, 0x10, 0x01, 0x02, + 0xcc, 0x10, 0x01, 0x02, 0x2c, 0x01, 0x02, 0x02, 0x30, 0x01, 0x02, 0x02, 0x34, 0x01, 0x02, 0x02, 0x38, 0x01, 0x02, 0x02, 0xa8, 0x29, 0x03, 0x03, 0xb0, 0x29, 0x03, 0x03, 0x28, 0x15, 0x04, 0x03, + 0x30, 0x15, 0x04, 0x03, 0x38, 0x15, 0x04, 0x03, 0xf0, 0x04, 0x05, 0x03, 0x80, 0x2e, 0x06, 0x04, 0x90, 0x2e, 0x06, 0x04, 0x40, 0x1a, 0x07, 0x04, 0xb0, 0x08, 0x08, 0x04, 0x20, 0x36, 0x09, 0x05, + 0xa0, 0x0b, 0x0b, 0x05, 0x40, 0x26, 0x0d, 0x06, 0x00, 0x31, 0x13, 0x08, 0x90, 0x16, 0x00, 0x03, 0x98, 0x16, 0x00, 0x03, 0xd0, 0x10, 0x01, 0x02, 0xd4, 0x10, 0x01, 0x02, 0xd8, 0x10, 0x01, 0x02, + 0xdc, 0x10, 0x01, 0x02, 0x3c, 0x01, 0x02, 0x02, 0x40, 0x01, 0x02, 0x02, 0x44, 0x01, 0x02, 0x02, 0x48, 0x01, 0x02, 0x02, 0xb8, 0x29, 0x03, 0x03, 0xc0, 0x29, 0x03, 0x03, 0x40, 0x15, 0x04, 0x03, + 0x48, 0x15, 0x04, 0x03, 0x50, 0x15, 0x04, 0x03, 0xf8, 0x04, 0x05, 0x03, 0xa0, 0x2e, 0x06, 0x04, 0xb0, 0x2e, 0x06, 0x04, 0x50, 0x1a, 0x07, 0x04, 0xc0, 0x08, 0x08, 0x04, 0x40, 0x36, 0x09, 0x05, + 0xc0, 0x0b, 0x0b, 0x05, 0x40, 0x0d, 0x0e, 0x06, 0x00, 0x16, 0x14, 0x08, 0xa0, 0x16, 0x00, 0x03, 0xa8, 0x16, 0x00, 0x03, 0xe0, 0x10, 0x01, 0x02, 0xe4, 0x10, 0x01, 0x02, 0xe8, 0x10, 0x01, 0x02, + 0xec, 0x10, 0x01, 0x02, 0x4c, 0x01, 0x02, 0x02, 0x50, 0x01, 0x02, 0x02, 0x54, 0x01, 0x02, 0x02, 0x58, 0x01, 0x02, 0x02, 0xc8, 0x29, 0x03, 0x03, 0xd0, 0x29, 0x03, 0x03, 0x58, 0x15, 0x04, 0x03, + 0x60, 0x15, 0x04, 0x03, 0x68, 0x15, 0x04, 0x03, 0x00, 0x05, 0x05, 0x03, 0xc0, 0x2e, 0x06, 0x04, 0xd0, 0x2e, 0x06, 0x04, 0x60, 0x1a, 0x07, 0x04, 0xd0, 0x08, 0x08, 0x04, 0x60, 0x36, 0x09, 0x05, + 0xe0, 0x0b, 0x0b, 0x05, 0x80, 0x0d, 0x0e, 0x06, 0x00, 0x17, 0x14, 0x08, 0xb0, 0x16, 0x00, 0x03, 0xb8, 0x16, 0x00, 0x03, 0xf0, 0x10, 0x01, 0x02, 0xf4, 0x10, 0x01, 0x02, 0xf8, 0x10, 0x01, 0x02, + 0xfc, 0x10, 0x01, 0x02, 0x5c, 0x01, 0x02, 0x02, 0x60, 0x01, 0x02, 0x02, 0x64, 0x01, 0x02, 0x02, 0x68, 0x01, 0x02, 0x02, 0xd8, 0x29, 0x03, 0x03, 0xe0, 0x29, 0x03, 0x03, 0x70, 0x15, 0x04, 0x03, + 0x78, 0x15, 0x04, 0x03, 0x80, 0x15, 0x04, 0x03, 0x08, 0x05, 0x05, 0x03, 0xe0, 0x2e, 0x06, 0x04, 0xf0, 0x2e, 0x06, 0x04, 0x70, 0x1a, 0x07, 0x04, 0xe0, 0x08, 0x08, 0x04, 0x80, 0x36, 0x09, 0x05, + 0x00, 0x0c, 0x0b, 0x05, 0xc0, 0x0d, 0x0e, 0x06, 0x00, 0x18, 0x14, 0x08, 0xc0, 0x16, 0x00, 0x03, 0xc8, 0x16, 0x00, 0x03, 0x00, 0x11, 0x01, 0x02, 0x04, 0x11, 0x01, 0x02, 0x08, 0x11, 0x01, 0x02, + 0x0c, 0x11, 0x01, 0x02, 0x6c, 0x01, 0x02, 0x02, 0x70, 0x01, 0x02, 0x02, 0x74, 0x01, 0x02, 0x02, 0x78, 0x01, 0x02, 0x02, 0xe8, 0x29, 0x03, 0x03, 0xf0, 0x29, 0x03, 0x03, 0x88, 0x15, 0x04, 0x03, + 0x90, 0x15, 0x04, 0x03, 0x98, 0x15, 0x04, 0x03, 0x10, 0x05, 0x05, 0x03, 0x00, 0x2f, 0x06, 0x04, 0x10, 0x2f, 0x06, 0x04, 0x80, 0x1a, 0x07, 0x04, 0xf0, 0x08, 0x08, 0x04, 0xa0, 0x36, 0x09, 0x05, + 0x20, 0x0c, 0x0b, 0x05, 0x00, 0x0e, 0x0e, 0x06, 0x00, 0x19, 0x14, 0x08, 0xd0, 0x16, 0x00, 0x03, 0xd8, 0x16, 0x00, 0x03, 0x10, 0x11, 0x01, 0x02, 0x14, 0x11, 0x01, 0x02, 0x18, 0x11, 0x01, 0x02, + 0x1c, 0x11, 0x01, 0x02, 0x7c, 0x01, 0x02, 0x02, 0x80, 0x01, 0x02, 0x02, 0x84, 0x01, 0x02, 0x02, 0x88, 0x01, 0x02, 0x02, 0xf8, 0x29, 0x03, 0x03, 0x00, 0x2a, 0x03, 0x03, 0xa0, 0x15, 0x04, 0x03, + 0xa8, 0x15, 0x04, 0x03, 0xb0, 0x15, 0x04, 0x03, 0x18, 0x05, 0x05, 0x03, 0x20, 0x2f, 0x06, 0x04, 0x30, 0x2f, 0x06, 0x04, 0x90, 0x1a, 0x07, 0x04, 0x00, 0x09, 0x08, 0x04, 0xc0, 0x36, 0x09, 0x05, + 0x40, 0x0c, 0x0b, 0x05, 0x40, 0x0e, 0x0e, 0x06, 0x00, 0x1a, 0x14, 0x08, 0xe0, 0x16, 0x00, 0x03, 0xe8, 0x16, 0x00, 0x03, 0x20, 0x11, 0x01, 0x02, 0x24, 0x11, 0x01, 0x02, 0x28, 0x11, 0x01, 0x02, + 0x2c, 0x11, 0x01, 0x02, 0x8c, 0x01, 0x02, 0x02, 0x90, 0x01, 0x02, 0x02, 0x94, 0x01, 0x02, 0x02, 0x98, 0x01, 0x02, 0x02, 0x08, 0x2a, 0x03, 0x03, 0x10, 0x2a, 0x03, 0x03, 0xb8, 0x15, 0x04, 0x03, + 0xc0, 0x15, 0x04, 0x03, 0xc8, 0x15, 0x04, 0x03, 0x20, 0x05, 0x05, 0x03, 0x40, 0x2f, 0x06, 0x04, 0x50, 0x2f, 0x06, 0x04, 0xa0, 0x1a, 0x07, 0x04, 0x10, 0x09, 0x08, 0x04, 0xe0, 0x36, 0x09, 0x05, + 0x60, 0x0c, 0x0b, 0x05, 0x80, 0x0e, 0x0e, 0x06, 0x00, 0x1b, 0x14, 0x08, 0xf0, 0x16, 0x00, 0x03, 0xf8, 0x16, 0x00, 0x03, 0x30, 0x11, 0x01, 0x02, 0x34, 0x11, 0x01, 0x02, 0x38, 0x11, 0x01, 0x02, + 0x3c, 0x11, 0x01, 0x02, 0x9c, 0x01, 0x02, 0x02, 0xa0, 0x01, 0x02, 0x02, 0xa4, 0x01, 0x02, 0x02, 0xa8, 0x01, 0x02, 0x02, 0x18, 0x2a, 0x03, 0x03, 0x20, 0x2a, 0x03, 0x03, 0xd0, 0x15, 0x04, 0x03, + 0xd8, 0x15, 0x04, 0x03, 0xe0, 0x15, 0x04, 0x03, 0x28, 0x05, 0x05, 0x03, 0x60, 0x2f, 0x06, 0x04, 0x70, 0x2f, 0x06, 0x04, 0xb0, 0x1a, 0x07, 0x04, 0x20, 0x09, 0x08, 0x04, 0x00, 0x37, 0x09, 0x05, + 0x80, 0x0c, 0x0b, 0x05, 0xc0, 0x0e, 0x0e, 0x06, 0x00, 0x06, 0x15, 0x08, 0x00, 0x17, 0x00, 0x03, 0x08, 0x17, 0x00, 0x03, 0x40, 0x11, 0x01, 0x02, 0x44, 0x11, 0x01, 0x02, 0x48, 0x11, 0x01, 0x02, + 0x4c, 0x11, 0x01, 0x02, 0xac, 0x01, 0x02, 0x02, 0xb0, 0x01, 0x02, 0x02, 0xb4, 0x01, 0x02, 0x02, 0xb8, 0x01, 0x02, 0x02, 0x28, 0x2a, 0x03, 0x03, 0x30, 0x2a, 0x03, 0x03, 0xe8, 0x15, 0x04, 0x03, + 0xf0, 0x15, 0x04, 0x03, 0x30, 0x05, 0x05, 0x03, 0x38, 0x05, 0x05, 0x03, 0x80, 0x2f, 0x06, 0x04, 0x90, 0x2f, 0x06, 0x04, 0xc0, 0x1a, 0x07, 0x04, 0x30, 0x09, 0x08, 0x04, 0x20, 0x37, 0x09, 0x05, + 0xa0, 0x0c, 0x0b, 0x05, 0x00, 0x0f, 0x0e, 0x06, 0x00, 0x07, 0x15, 0x08, 0x10, 0x17, 0x00, 0x03, 0x18, 0x17, 0x00, 0x03, 0x50, 0x11, 0x01, 0x02, 0x54, 0x11, 0x01, 0x02, 0x58, 0x11, 0x01, 0x02, + 0x5c, 0x11, 0x01, 0x02, 0xbc, 0x01, 0x02, 0x02, 0xc0, 0x01, 0x02, 0x02, 0xc4, 0x01, 0x02, 0x02, 0xc8, 0x01, 0x02, 0x02, 0x38, 0x2a, 0x03, 0x03, 0x40, 0x2a, 0x03, 0x03, 0xf8, 0x15, 0x04, 0x03, + 0x00, 0x16, 0x04, 0x03, 0x40, 0x05, 0x05, 0x03, 0x48, 0x05, 0x05, 0x03, 0xa0, 0x2f, 0x06, 0x04, 0xb0, 0x2f, 0x06, 0x04, 0xd0, 0x1a, 0x07, 0x04, 0x40, 0x09, 0x08, 0x04, 0x40, 0x37, 0x09, 0x05, + 0xc0, 0x0c, 0x0b, 0x05, 0x40, 0x0f, 0x0e, 0x06, 0x00, 0x08, 0x15, 0x08, 0x20, 0x17, 0x00, 0x03, 0x28, 0x17, 0x00, 0x03, 0x60, 0x11, 0x01, 0x02, 0x64, 0x11, 0x01, 0x02, 0x68, 0x11, 0x01, 0x02, + 0x6c, 0x11, 0x01, 0x02, 0xcc, 0x01, 0x02, 0x02, 0xd0, 0x01, 0x02, 0x02, 0xd4, 0x01, 0x02, 0x02, 0xd8, 0x01, 0x02, 0x02, 0x48, 0x2a, 0x03, 0x03, 0x50, 0x2a, 0x03, 0x03, 0x08, 0x16, 0x04, 0x03, + 0x10, 0x16, 0x04, 0x03, 0x50, 0x05, 0x05, 0x03, 0x58, 0x05, 0x05, 0x03, 0xc0, 0x2f, 0x06, 0x04, 0xd0, 0x2f, 0x06, 0x04, 0xe0, 0x1a, 0x07, 0x04, 0x50, 0x09, 0x08, 0x04, 0x60, 0x37, 0x09, 0x05, + 0xe0, 0x0c, 0x0b, 0x05, 0x80, 0x0f, 0x0e, 0x06, 0x00, 0x09, 0x15, 0x08, 0x30, 0x17, 0x00, 0x03, 0x38, 0x17, 0x00, 0x03, 0x70, 0x11, 0x01, 0x02, 0x74, 0x11, 0x01, 0x02, 0x78, 0x11, 0x01, 0x02, + 0x7c, 0x11, 0x01, 0x02, 0xdc, 0x01, 0x02, 0x02, 0xe0, 0x01, 0x02, 0x02, 0xe4, 0x01, 0x02, 0x02, 0xe8, 0x01, 0x02, 0x02, 0x58, 0x2a, 0x03, 0x03, 0x60, 0x2a, 0x03, 0x03, 0x18, 0x16, 0x04, 0x03, + 0x20, 0x16, 0x04, 0x03, 0x60, 0x05, 0x05, 0x03, 0x68, 0x05, 0x05, 0x03, 0xe0, 0x2f, 0x06, 0x04, 0xf0, 0x2f, 0x06, 0x04, 0xf0, 0x1a, 0x07, 0x04, 0x60, 0x09, 0x08, 0x04, 0x80, 0x37, 0x09, 0x05, + 0x00, 0x0d, 0x0b, 0x05, 0xc0, 0x0f, 0x0e, 0x06, 0x00, 0x0a, 0x15, 0x08, 0x40, 0x17, 0x00, 0x03, 0x48, 0x17, 0x00, 0x03, 0x80, 0x11, 0x01, 0x02, 0x84, 0x11, 0x01, 0x02, 0x88, 0x11, 0x01, 0x02, + 0x8c, 0x11, 0x01, 0x02, 0xec, 0x01, 0x02, 0x02, 0xf0, 0x01, 0x02, 0x02, 0xf4, 0x01, 0x02, 0x02, 0xf8, 0x01, 0x02, 0x02, 0x68, 0x2a, 0x03, 0x03, 0x70, 0x2a, 0x03, 0x03, 0x28, 0x16, 0x04, 0x03, + 0x30, 0x16, 0x04, 0x03, 0x70, 0x05, 0x05, 0x03, 0x78, 0x05, 0x05, 0x03, 0x00, 0x30, 0x06, 0x04, 0x10, 0x30, 0x06, 0x04, 0x00, 0x1b, 0x07, 0x04, 0x70, 0x09, 0x08, 0x04, 0xa0, 0x37, 0x09, 0x05, + 0x20, 0x0d, 0x0b, 0x05, 0x00, 0x10, 0x0e, 0x06, 0x00, 0x30, 0x16, 0x09, 0x50, 0x17, 0x00, 0x03, 0x58, 0x17, 0x00, 0x03, 0x90, 0x11, 0x01, 0x02, 0x94, 0x11, 0x01, 0x02, 0x98, 0x11, 0x01, 0x02, + 0x9c, 0x11, 0x01, 0x02, 0xfc, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x08, 0x02, 0x02, 0x02, 0x78, 0x2a, 0x03, 0x03, 0x80, 0x2a, 0x03, 0x03, 0x38, 0x16, 0x04, 0x03, + 0x40, 0x16, 0x04, 0x03, 0x80, 0x05, 0x05, 0x03, 0x88, 0x05, 0x05, 0x03, 0x20, 0x30, 0x06, 0x04, 0x30, 0x30, 0x06, 0x04, 0x10, 0x1b, 0x07, 0x04, 0x80, 0x09, 0x08, 0x04, 0xc0, 0x37, 0x09, 0x05, + 0x40, 0x0d, 0x0b, 0x05, 0x40, 0x10, 0x0e, 0x06, 0x00, 0x32, 0x16, 0x09, 0x60, 0x17, 0x00, 0x03, 0x68, 0x17, 0x00, 0x03, 0xa0, 0x11, 0x01, 0x02, 0xa4, 0x11, 0x01, 0x02, 0xa8, 0x11, 0x01, 0x02, + 0xac, 0x11, 0x01, 0x02, 0x0c, 0x02, 0x02, 0x02, 0x10, 0x02, 0x02, 0x02, 0x14, 0x02, 0x02, 0x02, 0x88, 0x2a, 0x03, 0x03, 0x90, 0x2a, 0x03, 0x03, 0x98, 0x2a, 0x03, 0x03, 0x48, 0x16, 0x04, 0x03, + 0x50, 0x16, 0x04, 0x03, 0x90, 0x05, 0x05, 0x03, 0x98, 0x05, 0x05, 0x03, 0x40, 0x30, 0x06, 0x04, 0x50, 0x30, 0x06, 0x04, 0x20, 0x1b, 0x07, 0x04, 0x90, 0x09, 0x08, 0x04, 0xe0, 0x37, 0x09, 0x05, + 0x60, 0x0d, 0x0b, 0x05, 0x80, 0x10, 0x0e, 0x06, 0x00, 0x34, 0x16, 0x09, 0x70, 0x17, 0x00, 0x03, 0x78, 0x17, 0x00, 0x03, 0xb0, 0x11, 0x01, 0x02, 0xb4, 0x11, 0x01, 0x02, 0xb8, 0x11, 0x01, 0x02, + 0xbc, 0x11, 0x01, 0x02, 0x18, 0x02, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0x20, 0x02, 0x02, 0x02, 0xa0, 0x2a, 0x03, 0x03, 0xa8, 0x2a, 0x03, 0x03, 0xb0, 0x2a, 0x03, 0x03, 0x58, 0x16, 0x04, 0x03, + 0x60, 0x16, 0x04, 0x03, 0xa0, 0x05, 0x05, 0x03, 0xa8, 0x05, 0x05, 0x03, 0x60, 0x30, 0x06, 0x04, 0x70, 0x30, 0x06, 0x04, 0x30, 0x1b, 0x07, 0x04, 0xa0, 0x09, 0x08, 0x04, 0xa0, 0x1f, 0x0a, 0x05, + 0x80, 0x0d, 0x0b, 0x05, 0xc0, 0x10, 0x0e, 0x06, 0x00, 0x36, 0x16, 0x09, 0x80, 0x17, 0x00, 0x03, 0x88, 0x17, 0x00, 0x03, 0xc0, 0x11, 0x01, 0x02, 0xc4, 0x11, 0x01, 0x02, 0xc8, 0x11, 0x01, 0x02, + 0xcc, 0x11, 0x01, 0x02, 0x24, 0x02, 0x02, 0x02, 0x28, 0x02, 0x02, 0x02, 0x2c, 0x02, 0x02, 0x02, 0xb8, 0x2a, 0x03, 0x03, 0xc0, 0x2a, 0x03, 0x03, 0xc8, 0x2a, 0x03, 0x03, 0x68, 0x16, 0x04, 0x03, + 0x70, 0x16, 0x04, 0x03, 0xb0, 0x05, 0x05, 0x03, 0xb8, 0x05, 0x05, 0x03, 0x80, 0x30, 0x06, 0x04, 0x90, 0x30, 0x06, 0x04, 0x40, 0x1b, 0x07, 0x04, 0xb0, 0x09, 0x08, 0x04, 0xc0, 0x1f, 0x0a, 0x05, + 0xa0, 0x0d, 0x0b, 0x05, 0x00, 0x11, 0x0e, 0x06, 0x00, 0x1c, 0x17, 0x09, 0x90, 0x17, 0x00, 0x03, 0x98, 0x17, 0x00, 0x03, 0xd0, 0x11, 0x01, 0x02, 0xd4, 0x11, 0x01, 0x02, 0xd8, 0x11, 0x01, 0x02, + 0xdc, 0x11, 0x01, 0x02, 0x30, 0x02, 0x02, 0x02, 0x34, 0x02, 0x02, 0x02, 0x38, 0x02, 0x02, 0x02, 0xd0, 0x2a, 0x03, 0x03, 0xd8, 0x2a, 0x03, 0x03, 0xe0, 0x2a, 0x03, 0x03, 0x78, 0x16, 0x04, 0x03, + 0x80, 0x16, 0x04, 0x03, 0xc0, 0x05, 0x05, 0x03, 0xc8, 0x05, 0x05, 0x03, 0xa0, 0x30, 0x06, 0x04, 0xb0, 0x30, 0x06, 0x04, 0x50, 0x1b, 0x07, 0x04, 0xc0, 0x09, 0x08, 0x04, 0xe0, 0x1f, 0x0a, 0x05, + 0xc0, 0x0d, 0x0b, 0x05, 0x40, 0x11, 0x0e, 0x06, 0x00, 0x1e, 0x17, 0x09, 0xa0, 0x17, 0x00, 0x03, 0xa8, 0x17, 0x00, 0x03, 0xe0, 0x11, 0x01, 0x02, 0xe4, 0x11, 0x01, 0x02, 0xe8, 0x11, 0x01, 0x02, + 0xec, 0x11, 0x01, 0x02, 0x3c, 0x02, 0x02, 0x02, 0x40, 0x02, 0x02, 0x02, 0x44, 0x02, 0x02, 0x02, 0xe8, 0x2a, 0x03, 0x03, 0xf0, 0x2a, 0x03, 0x03, 0xf8, 0x2a, 0x03, 0x03, 0x88, 0x16, 0x04, 0x03, + 0x90, 0x16, 0x04, 0x03, 0xd0, 0x05, 0x05, 0x03, 0xd8, 0x05, 0x05, 0x03, 0xc0, 0x30, 0x06, 0x04, 0xd0, 0x30, 0x06, 0x04, 0x60, 0x1b, 0x07, 0x04, 0xd0, 0x09, 0x08, 0x04, 0x00, 0x20, 0x0a, 0x05, + 0xe0, 0x0d, 0x0b, 0x05, 0x80, 0x11, 0x0e, 0x06, 0x00, 0x20, 0x17, 0x09, 0xb0, 0x17, 0x00, 0x03, 0xb8, 0x17, 0x00, 0x03, 0xf0, 0x11, 0x01, 0x02, 0xf4, 0x11, 0x01, 0x02, 0xf8, 0x11, 0x01, 0x02, + 0xfc, 0x11, 0x01, 0x02, 0x48, 0x02, 0x02, 0x02, 0x4c, 0x02, 0x02, 0x02, 0x50, 0x02, 0x02, 0x02, 0x00, 0x2b, 0x03, 0x03, 0x08, 0x2b, 0x03, 0x03, 0x10, 0x2b, 0x03, 0x03, 0x98, 0x16, 0x04, 0x03, + 0xa0, 0x16, 0x04, 0x03, 0xe0, 0x05, 0x05, 0x03, 0xe8, 0x05, 0x05, 0x03, 0xe0, 0x30, 0x06, 0x04, 0xf0, 0x30, 0x06, 0x04, 0x70, 0x1b, 0x07, 0x04, 0xe0, 0x09, 0x08, 0x04, 0x20, 0x20, 0x0a, 0x05, + 0x00, 0x0e, 0x0b, 0x05, 0xc0, 0x11, 0x0e, 0x06, 0x00, 0x08, 0x18, 0x09, 0xc0, 0x17, 0x00, 0x03, 0xc8, 0x17, 0x00, 0x03, 0x00, 0x12, 0x01, 0x02, 0x04, 0x12, 0x01, 0x02, 0x08, 0x12, 0x01, 0x02, + 0x0c, 0x12, 0x01, 0x02, 0x54, 0x02, 0x02, 0x02, 0x58, 0x02, 0x02, 0x02, 0x5c, 0x02, 0x02, 0x02, 0x18, 0x2b, 0x03, 0x03, 0x20, 0x2b, 0x03, 0x03, 0x28, 0x2b, 0x03, 0x03, 0xa8, 0x16, 0x04, 0x03, + 0xb0, 0x16, 0x04, 0x03, 0xf0, 0x05, 0x05, 0x03, 0xf8, 0x05, 0x05, 0x03, 0x00, 0x31, 0x06, 0x04, 0x10, 0x31, 0x06, 0x04, 0x80, 0x1b, 0x07, 0x04, 0xf0, 0x09, 0x08, 0x04, 0x40, 0x20, 0x0a, 0x05, + 0x20, 0x0e, 0x0b, 0x05, 0x00, 0x12, 0x0e, 0x06, 0x00, 0x0a, 0x18, 0x09, 0xd0, 0x17, 0x00, 0x03, 0xd8, 0x17, 0x00, 0x03, 0x10, 0x12, 0x01, 0x02, 0x14, 0x12, 0x01, 0x02, 0x18, 0x12, 0x01, 0x02, + 0x1c, 0x12, 0x01, 0x02, 0x60, 0x02, 0x02, 0x02, 0x64, 0x02, 0x02, 0x02, 0x68, 0x02, 0x02, 0x02, 0x30, 0x2b, 0x03, 0x03, 0x38, 0x2b, 0x03, 0x03, 0x40, 0x2b, 0x03, 0x03, 0xb8, 0x16, 0x04, 0x03, + 0xc0, 0x16, 0x04, 0x03, 0x00, 0x06, 0x05, 0x03, 0x08, 0x06, 0x05, 0x03, 0x20, 0x31, 0x06, 0x04, 0x30, 0x31, 0x06, 0x04, 0x90, 0x1b, 0x07, 0x04, 0x00, 0x0a, 0x08, 0x04, 0x60, 0x20, 0x0a, 0x05, + 0x40, 0x0e, 0x0b, 0x05, 0x40, 0x12, 0x0e, 0x06, 0x00, 0x0c, 0x18, 0x09, 0xe0, 0x17, 0x00, 0x03, 0xe8, 0x17, 0x00, 0x03, 0x20, 0x12, 0x01, 0x02, 0x24, 0x12, 0x01, 0x02, 0x28, 0x12, 0x01, 0x02, + 0x2c, 0x12, 0x01, 0x02, 0x6c, 0x02, 0x02, 0x02, 0x70, 0x02, 0x02, 0x02, 0x74, 0x02, 0x02, 0x02, 0x48, 0x2b, 0x03, 0x03, 0x50, 0x2b, 0x03, 0x03, 0x58, 0x2b, 0x03, 0x03, 0xc8, 0x16, 0x04, 0x03, + 0xd0, 0x16, 0x04, 0x03, 0x10, 0x06, 0x05, 0x03, 0x18, 0x06, 0x05, 0x03, 0x40, 0x31, 0x06, 0x04, 0x50, 0x31, 0x06, 0x04, 0xa0, 0x1b, 0x07, 0x04, 0x10, 0x0a, 0x08, 0x04, 0x80, 0x20, 0x0a, 0x05, + 0x60, 0x0e, 0x0b, 0x05, 0x80, 0x12, 0x0e, 0x06, 0x00, 0x38, 0x19, 0x0a, 0xf0, 0x17, 0x00, 0x03, 0xf8, 0x17, 0x00, 0x03, 0x30, 0x12, 0x01, 0x02, 0x34, 0x12, 0x01, 0x02, 0x38, 0x12, 0x01, 0x02, + 0x3c, 0x12, 0x01, 0x02, 0x78, 0x02, 0x02, 0x02, 0x7c, 0x02, 0x02, 0x02, 0x80, 0x02, 0x02, 0x02, 0x60, 0x2b, 0x03, 0x03, 0x68, 0x2b, 0x03, 0x03, 0x70, 0x2b, 0x03, 0x03, 0xd8, 0x16, 0x04, 0x03, + 0xe0, 0x16, 0x04, 0x03, 0x20, 0x06, 0x05, 0x03, 0x28, 0x06, 0x05, 0x03, 0x60, 0x31, 0x06, 0x04, 0x70, 0x31, 0x06, 0x04, 0xb0, 0x1b, 0x07, 0x04, 0x20, 0x0a, 0x08, 0x04, 0xa0, 0x20, 0x0a, 0x05, + 0x80, 0x0e, 0x0b, 0x05, 0xc0, 0x12, 0x0e, 0x06, 0x00, 0x3c, 0x19, 0x0a, 0x00, 0x18, 0x00, 0x03, 0x08, 0x18, 0x00, 0x03, 0x40, 0x12, 0x01, 0x02, 0x44, 0x12, 0x01, 0x02, 0x48, 0x12, 0x01, 0x02, + 0x4c, 0x12, 0x01, 0x02, 0x84, 0x02, 0x02, 0x02, 0x88, 0x02, 0x02, 0x02, 0x8c, 0x02, 0x02, 0x02, 0x78, 0x2b, 0x03, 0x03, 0x80, 0x2b, 0x03, 0x03, 0x88, 0x2b, 0x03, 0x03, 0xe8, 0x16, 0x04, 0x03, + 0xf0, 0x16, 0x04, 0x03, 0x30, 0x06, 0x05, 0x03, 0x38, 0x06, 0x05, 0x03, 0x80, 0x31, 0x06, 0x04, 0x90, 0x31, 0x06, 0x04, 0xc0, 0x1b, 0x07, 0x04, 0x30, 0x0a, 0x08, 0x04, 0xc0, 0x20, 0x0a, 0x05, + 0xc0, 0x3e, 0x0c, 0x06, 0xc0, 0x02, 0x0f, 0x06, 0x00, 0x28, 0x1a, 0x0a, 0x10, 0x18, 0x00, 0x03, 0x18, 0x18, 0x00, 0x03, 0x50, 0x12, 0x01, 0x02, 0x54, 0x12, 0x01, 0x02, 0x58, 0x12, 0x01, 0x02, + 0x5c, 0x12, 0x01, 0x02, 0x90, 0x02, 0x02, 0x02, 0x94, 0x02, 0x02, 0x02, 0x98, 0x02, 0x02, 0x02, 0x90, 0x2b, 0x03, 0x03, 0x98, 0x2b, 0x03, 0x03, 0xa0, 0x2b, 0x03, 0x03, 0xf8, 0x16, 0x04, 0x03, + 0x00, 0x17, 0x04, 0x03, 0x40, 0x06, 0x05, 0x03, 0x48, 0x06, 0x05, 0x03, 0xa0, 0x31, 0x06, 0x04, 0xb0, 0x31, 0x06, 0x04, 0xd0, 0x1b, 0x07, 0x04, 0x40, 0x0a, 0x08, 0x04, 0xe0, 0x20, 0x0a, 0x05, + 0x00, 0x3f, 0x0c, 0x06, 0x00, 0x03, 0x0f, 0x06, 0x00, 0x2c, 0x1a, 0x0a, 0x20, 0x18, 0x00, 0x03, 0x28, 0x18, 0x00, 0x03, 0x60, 0x12, 0x01, 0x02, 0x64, 0x12, 0x01, 0x02, 0x68, 0x12, 0x01, 0x02, + 0x6c, 0x12, 0x01, 0x02, 0x9c, 0x02, 0x02, 0x02, 0xa0, 0x02, 0x02, 0x02, 0xa4, 0x02, 0x02, 0x02, 0xa8, 0x2b, 0x03, 0x03, 0xb0, 0x2b, 0x03, 0x03, 0xb8, 0x2b, 0x03, 0x03, 0x08, 0x17, 0x04, 0x03, + 0x10, 0x17, 0x04, 0x03, 0x50, 0x06, 0x05, 0x03, 0x58, 0x06, 0x05, 0x03, 0xc0, 0x31, 0x06, 0x04, 0xd0, 0x31, 0x06, 0x04, 0xe0, 0x1b, 0x07, 0x04, 0x50, 0x0a, 0x08, 0x04, 0x00, 0x21, 0x0a, 0x05, + 0x40, 0x3f, 0x0c, 0x06, 0x40, 0x03, 0x0f, 0x06, 0x00, 0x14, 0x1b, 0x0a, 0x30, 0x18, 0x00, 0x03, 0x38, 0x18, 0x00, 0x03, 0x70, 0x12, 0x01, 0x02, 0x74, 0x12, 0x01, 0x02, 0x78, 0x12, 0x01, 0x02, + 0x7c, 0x12, 0x01, 0x02, 0xa8, 0x02, 0x02, 0x02, 0xac, 0x02, 0x02, 0x02, 0xb0, 0x02, 0x02, 0x02, 0xc0, 0x2b, 0x03, 0x03, 0xc8, 0x2b, 0x03, 0x03, 0xd0, 0x2b, 0x03, 0x03, 0x18, 0x17, 0x04, 0x03, + 0x20, 0x17, 0x04, 0x03, 0x60, 0x06, 0x05, 0x03, 0x68, 0x06, 0x05, 0x03, 0xe0, 0x31, 0x06, 0x04, 0xf0, 0x1b, 0x07, 0x04, 0x00, 0x1c, 0x07, 0x04, 0x60, 0x0a, 0x08, 0x04, 0x20, 0x21, 0x0a, 0x05, + 0x80, 0x3f, 0x0c, 0x06, 0x80, 0x03, 0x0f, 0x06, 0x00, 0x00, 0x1c, 0x0a, 0x40, 0x18, 0x00, 0x03, 0x48, 0x18, 0x00, 0x03, 0x80, 0x12, 0x01, 0x02, 0x84, 0x12, 0x01, 0x02, 0x88, 0x12, 0x01, 0x02, + 0x8c, 0x12, 0x01, 0x02, 0xb4, 0x02, 0x02, 0x02, 0xb8, 0x02, 0x02, 0x02, 0xbc, 0x02, 0x02, 0x02, 0xd8, 0x2b, 0x03, 0x03, 0xe0, 0x2b, 0x03, 0x03, 0xe8, 0x2b, 0x03, 0x03, 0x28, 0x17, 0x04, 0x03, + 0x30, 0x17, 0x04, 0x03, 0x70, 0x06, 0x05, 0x03, 0x78, 0x06, 0x05, 0x03, 0xf0, 0x31, 0x06, 0x04, 0x10, 0x1c, 0x07, 0x04, 0x20, 0x1c, 0x07, 0x04, 0x70, 0x0a, 0x08, 0x04, 0x40, 0x21, 0x0a, 0x05, + 0xc0, 0x3f, 0x0c, 0x06, 0xc0, 0x03, 0x0f, 0x06, 0x00, 0x04, 0x1c, 0x0a, 0x50, 0x18, 0x00, 0x03, 0x58, 0x18, 0x00, 0x03, 0x90, 0x12, 0x01, 0x02, 0x94, 0x12, 0x01, 0x02, 0x98, 0x12, 0x01, 0x02, + 0x9c, 0x12, 0x01, 0x02, 0xc0, 0x02, 0x02, 0x02, 0xc4, 0x02, 0x02, 0x02, 0xc8, 0x02, 0x02, 0x02, 0xf0, 0x2b, 0x03, 0x03, 0xf8, 0x2b, 0x03, 0x03, 0x00, 0x2c, 0x03, 0x03, 0x38, 0x17, 0x04, 0x03, + 0x40, 0x17, 0x04, 0x03, 0x80, 0x06, 0x05, 0x03, 0x88, 0x06, 0x05, 0x03, 0x00, 0x32, 0x06, 0x04, 0x30, 0x1c, 0x07, 0x04, 0x40, 0x1c, 0x07, 0x04, 0x80, 0x0a, 0x08, 0x04, 0x60, 0x21, 0x0a, 0x05, + 0x00, 0x00, 0x0c, 0x05, 0x00, 0x04, 0x0f, 0x06, 0x00, 0x28, 0x1d, 0x0b, 0x60, 0x18, 0x00, 0x03, 0x68, 0x18, 0x00, 0x03, 0xa0, 0x12, 0x01, 0x02, 0xa4, 0x12, 0x01, 0x02, 0xa8, 0x12, 0x01, 0x02, + 0xac, 0x12, 0x01, 0x02, 0xcc, 0x02, 0x02, 0x02, 0xd0, 0x02, 0x02, 0x02, 0xd4, 0x02, 0x02, 0x02, 0x08, 0x2c, 0x03, 0x03, 0x10, 0x2c, 0x03, 0x03, 0x18, 0x2c, 0x03, 0x03, 0x48, 0x17, 0x04, 0x03, + 0x50, 0x17, 0x04, 0x03, 0x90, 0x06, 0x05, 0x03, 0x98, 0x06, 0x05, 0x03, 0x10, 0x32, 0x06, 0x04, 0x50, 0x1c, 0x07, 0x04, 0x60, 0x1c, 0x07, 0x04, 0x90, 0x0a, 0x08, 0x04, 0x80, 0x21, 0x0a, 0x05, + 0x20, 0x00, 0x0c, 0x05, 0x40, 0x04, 0x0f, 0x06, 0x00, 0x08, 0x1f, 0x0b, 0x70, 0x18, 0x00, 0x03, 0x78, 0x18, 0x00, 0x03, 0xb0, 0x12, 0x01, 0x02, 0xb4, 0x12, 0x01, 0x02, 0xb8, 0x12, 0x01, 0x02, + 0xbc, 0x12, 0x01, 0x02, 0xd8, 0x02, 0x02, 0x02, 0xdc, 0x02, 0x02, 0x02, 0xe0, 0x02, 0x02, 0x02, 0x20, 0x2c, 0x03, 0x03, 0x28, 0x2c, 0x03, 0x03, 0x30, 0x2c, 0x03, 0x03, 0x58, 0x17, 0x04, 0x03, + 0x60, 0x17, 0x04, 0x03, 0xa0, 0x06, 0x05, 0x03, 0xa8, 0x06, 0x05, 0x03, 0x20, 0x32, 0x06, 0x04, 0x70, 0x1c, 0x07, 0x04, 0x80, 0x1c, 0x07, 0x04, 0xa0, 0x0a, 0x08, 0x04, 0xa0, 0x21, 0x0a, 0x05, + 0x40, 0x00, 0x0c, 0x05, 0x80, 0x04, 0x0f, 0x06, 0x00, 0x30, 0x20, 0x0c, 0x80, 0x18, 0x00, 0x03, 0x88, 0x18, 0x00, 0x03, 0xc0, 0x12, 0x01, 0x02, 0xc4, 0x12, 0x01, 0x02, 0xc8, 0x12, 0x01, 0x02, + 0xcc, 0x12, 0x01, 0x02, 0xe4, 0x02, 0x02, 0x02, 0xe8, 0x02, 0x02, 0x02, 0xec, 0x02, 0x02, 0x02, 0x38, 0x2c, 0x03, 0x03, 0x40, 0x2c, 0x03, 0x03, 0x48, 0x2c, 0x03, 0x03, 0x68, 0x17, 0x04, 0x03, + 0x70, 0x17, 0x04, 0x03, 0xb0, 0x06, 0x05, 0x03, 0xb8, 0x06, 0x05, 0x03, 0x30, 0x32, 0x06, 0x04, 0x90, 0x1c, 0x07, 0x04, 0xa0, 0x1c, 0x07, 0x04, 0xb0, 0x0a, 0x08, 0x04, 0xc0, 0x21, 0x0a, 0x05, + 0x60, 0x00, 0x0c, 0x05, 0xc0, 0x04, 0x0f, 0x06, 0x00, 0x10, 0x22, 0x0c, 0x90, 0x18, 0x00, 0x03, 0x98, 0x18, 0x00, 0x03, 0xd0, 0x12, 0x01, 0x02, 0xd4, 0x12, 0x01, 0x02, 0xd8, 0x12, 0x01, 0x02, + 0xdc, 0x12, 0x01, 0x02, 0xf0, 0x02, 0x02, 0x02, 0xf4, 0x02, 0x02, 0x02, 0xf8, 0x02, 0x02, 0x02, 0x50, 0x2c, 0x03, 0x03, 0x58, 0x2c, 0x03, 0x03, 0x60, 0x2c, 0x03, 0x03, 0x78, 0x17, 0x04, 0x03, + 0x80, 0x17, 0x04, 0x03, 0xc0, 0x06, 0x05, 0x03, 0xc8, 0x06, 0x05, 0x03, 0x40, 0x32, 0x06, 0x04, 0xb0, 0x1c, 0x07, 0x04, 0xc0, 0x1c, 0x07, 0x04, 0xc0, 0x0a, 0x08, 0x04, 0xe0, 0x21, 0x0a, 0x05, + 0x80, 0x00, 0x0c, 0x05, 0x00, 0x05, 0x0f, 0x06, 0xa0, 0x18, 0x00, 0x03, 0xa8, 0x18, 0x00, 0x03, 0xb0, 0x18, 0x00, 0x03, 0xe0, 0x12, 0x01, 0x02, 0xe4, 0x12, 0x01, 0x02, 0xe8, 0x12, 0x01, 0x02, + 0xec, 0x12, 0x01, 0x02, 0xfc, 0x02, 0x02, 0x02, 0x00, 0x03, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x68, 0x2c, 0x03, 0x03, 0x70, 0x2c, 0x03, 0x03, 0x78, 0x2c, 0x03, 0x03, 0x88, 0x17, 0x04, 0x03, + 0x90, 0x17, 0x04, 0x03, 0xd0, 0x06, 0x05, 0x03, 0xd8, 0x06, 0x05, 0x03, 0x50, 0x32, 0x06, 0x04, 0xd0, 0x1c, 0x07, 0x04, 0xe0, 0x1c, 0x07, 0x04, 0xd0, 0x0a, 0x08, 0x04, 0x00, 0x22, 0x0a, 0x05, + 0xa0, 0x00, 0x0c, 0x05, 0x40, 0x05, 0x0f, 0x06, 0xb8, 0x18, 0x00, 0x03, 0xc0, 0x18, 0x00, 0x03, 0xc8, 0x18, 0x00, 0x03, 0xf0, 0x12, 0x01, 0x02, 0xf4, 0x12, 0x01, 0x02, 0xf8, 0x12, 0x01, 0x02, + 0xfc, 0x12, 0x01, 0x02, 0x08, 0x03, 0x02, 0x02, 0x0c, 0x03, 0x02, 0x02, 0x10, 0x03, 0x02, 0x02, 0x80, 0x2c, 0x03, 0x03, 0x88, 0x2c, 0x03, 0x03, 0x90, 0x2c, 0x03, 0x03, 0x98, 0x17, 0x04, 0x03, + 0xa0, 0x17, 0x04, 0x03, 0xe0, 0x06, 0x05, 0x03, 0xe8, 0x06, 0x05, 0x03, 0x60, 0x32, 0x06, 0x04, 0xf0, 0x1c, 0x07, 0x04, 0x00, 0x1d, 0x07, 0x04, 0xe0, 0x0a, 0x08, 0x04, 0x20, 0x22, 0x0a, 0x05, + 0xc0, 0x00, 0x0c, 0x05, 0x80, 0x05, 0x0f, 0x06, 0xd0, 0x18, 0x00, 0x03, 0xd8, 0x18, 0x00, 0x03, 0xe0, 0x18, 0x00, 0x03, 0x00, 0x13, 0x01, 0x02, 0x04, 0x13, 0x01, 0x02, 0x08, 0x13, 0x01, 0x02, + 0x0c, 0x13, 0x01, 0x02, 0x14, 0x03, 0x02, 0x02, 0x18, 0x03, 0x02, 0x02, 0x1c, 0x03, 0x02, 0x02, 0x98, 0x2c, 0x03, 0x03, 0xa0, 0x2c, 0x03, 0x03, 0xa8, 0x2c, 0x03, 0x03, 0xa8, 0x17, 0x04, 0x03, + 0xb0, 0x17, 0x04, 0x03, 0xf0, 0x06, 0x05, 0x03, 0xf8, 0x06, 0x05, 0x03, 0x70, 0x32, 0x06, 0x04, 0x10, 0x1d, 0x07, 0x04, 0x20, 0x1d, 0x07, 0x04, 0x00, 0x38, 0x09, 0x05, 0x40, 0x22, 0x0a, 0x05, + 0xe0, 0x00, 0x0c, 0x05, 0xc0, 0x05, 0x0f, 0x06, 0xe8, 0x18, 0x00, 0x03, 0xf0, 0x18, 0x00, 0x03, 0xf8, 0x18, 0x00, 0x03, 0x10, 0x13, 0x01, 0x02, 0x14, 0x13, 0x01, 0x02, 0x18, 0x13, 0x01, 0x02, + 0x1c, 0x13, 0x01, 0x02, 0x20, 0x03, 0x02, 0x02, 0x24, 0x03, 0x02, 0x02, 0x28, 0x03, 0x02, 0x02, 0xb0, 0x2c, 0x03, 0x03, 0xb8, 0x2c, 0x03, 0x03, 0xc0, 0x2c, 0x03, 0x03, 0xb8, 0x17, 0x04, 0x03, + 0xc0, 0x17, 0x04, 0x03, 0x00, 0x07, 0x05, 0x03, 0x08, 0x07, 0x05, 0x03, 0x80, 0x32, 0x06, 0x04, 0x30, 0x1d, 0x07, 0x04, 0x40, 0x1d, 0x07, 0x04, 0x20, 0x38, 0x09, 0x05, 0x60, 0x22, 0x0a, 0x05, + 0x00, 0x01, 0x0c, 0x05, 0x00, 0x06, 0x0f, 0x06, 0x00, 0x19, 0x00, 0x03, 0x08, 0x19, 0x00, 0x03, 0x10, 0x19, 0x00, 0x03, 0x20, 0x13, 0x01, 0x02, 0x24, 0x13, 0x01, 0x02, 0x28, 0x13, 0x01, 0x02, + 0x2c, 0x13, 0x01, 0x02, 0x2c, 0x03, 0x02, 0x02, 0x30, 0x03, 0x02, 0x02, 0x34, 0x03, 0x02, 0x02, 0xc8, 0x2c, 0x03, 0x03, 0xd0, 0x2c, 0x03, 0x03, 0xd8, 0x2c, 0x03, 0x03, 0xc8, 0x17, 0x04, 0x03, + 0xd0, 0x17, 0x04, 0x03, 0x10, 0x07, 0x05, 0x03, 0x18, 0x07, 0x05, 0x03, 0x90, 0x32, 0x06, 0x04, 0x50, 0x1d, 0x07, 0x04, 0x60, 0x1d, 0x07, 0x04, 0x40, 0x38, 0x09, 0x05, 0x80, 0x22, 0x0a, 0x05, + 0x20, 0x01, 0x0c, 0x05, 0x40, 0x06, 0x0f, 0x06, 0x18, 0x19, 0x00, 0x03, 0x20, 0x19, 0x00, 0x03, 0x28, 0x19, 0x00, 0x03, 0x30, 0x13, 0x01, 0x02, 0x34, 0x13, 0x01, 0x02, 0x38, 0x13, 0x01, 0x02, + 0x3c, 0x13, 0x01, 0x02, 0x38, 0x03, 0x02, 0x02, 0x3c, 0x03, 0x02, 0x02, 0x40, 0x03, 0x02, 0x02, 0xe0, 0x2c, 0x03, 0x03, 0xe8, 0x2c, 0x03, 0x03, 0xf0, 0x2c, 0x03, 0x03, 0xd8, 0x17, 0x04, 0x03, + 0xe0, 0x17, 0x04, 0x03, 0x20, 0x07, 0x05, 0x03, 0x28, 0x07, 0x05, 0x03, 0xa0, 0x32, 0x06, 0x04, 0x70, 0x1d, 0x07, 0x04, 0x80, 0x1d, 0x07, 0x04, 0x60, 0x38, 0x09, 0x05, 0xa0, 0x22, 0x0a, 0x05, + 0x40, 0x01, 0x0c, 0x05, 0x80, 0x06, 0x0f, 0x06, 0x30, 0x19, 0x00, 0x03, 0x38, 0x19, 0x00, 0x03, 0x40, 0x19, 0x00, 0x03, 0x40, 0x13, 0x01, 0x02, 0x44, 0x13, 0x01, 0x02, 0x48, 0x13, 0x01, 0x02, + 0x4c, 0x13, 0x01, 0x02, 0x44, 0x03, 0x02, 0x02, 0x48, 0x03, 0x02, 0x02, 0x4c, 0x03, 0x02, 0x02, 0xf8, 0x2c, 0x03, 0x03, 0x00, 0x2d, 0x03, 0x03, 0x08, 0x2d, 0x03, 0x03, 0xe8, 0x17, 0x04, 0x03, + 0xf0, 0x17, 0x04, 0x03, 0x30, 0x07, 0x05, 0x03, 0x38, 0x07, 0x05, 0x03, 0xb0, 0x32, 0x06, 0x04, 0x90, 0x1d, 0x07, 0x04, 0xa0, 0x1d, 0x07, 0x04, 0x80, 0x38, 0x09, 0x05, 0xc0, 0x22, 0x0a, 0x05, + 0x60, 0x01, 0x0c, 0x05, 0xc0, 0x06, 0x0f, 0x06, 0x48, 0x19, 0x00, 0x03, 0x50, 0x19, 0x00, 0x03, 0x58, 0x19, 0x00, 0x03, 0x50, 0x13, 0x01, 0x02, 0x54, 0x13, 0x01, 0x02, 0x58, 0x13, 0x01, 0x02, + 0x5c, 0x13, 0x01, 0x02, 0x50, 0x03, 0x02, 0x02, 0x54, 0x03, 0x02, 0x02, 0x58, 0x03, 0x02, 0x02, 0x10, 0x2d, 0x03, 0x03, 0x18, 0x2d, 0x03, 0x03, 0x20, 0x2d, 0x03, 0x03, 0xf8, 0x17, 0x04, 0x03, + 0x00, 0x18, 0x04, 0x03, 0x40, 0x07, 0x05, 0x03, 0x48, 0x07, 0x05, 0x03, 0xc0, 0x32, 0x06, 0x04, 0xb0, 0x1d, 0x07, 0x04, 0xf0, 0x0a, 0x08, 0x04, 0xa0, 0x38, 0x09, 0x05, 0xe0, 0x22, 0x0a, 0x05, + 0x80, 0x01, 0x0c, 0x05, 0x00, 0x07, 0x0f, 0x06, 0x60, 0x19, 0x00, 0x03, 0x68, 0x19, 0x00, 0x03, 0x70, 0x19, 0x00, 0x03, 0x60, 0x13, 0x01, 0x02, 0x64, 0x13, 0x01, 0x02, 0x68, 0x13, 0x01, 0x02, + 0x6c, 0x13, 0x01, 0x02, 0x5c, 0x03, 0x02, 0x02, 0x60, 0x03, 0x02, 0x02, 0x64, 0x03, 0x02, 0x02, 0x28, 0x2d, 0x03, 0x03, 0x30, 0x2d, 0x03, 0x03, 0x38, 0x2d, 0x03, 0x03, 0x08, 0x18, 0x04, 0x03, + 0x10, 0x18, 0x04, 0x03, 0x50, 0x07, 0x05, 0x03, 0x58, 0x07, 0x05, 0x03, 0xd0, 0x32, 0x06, 0x04, 0xc0, 0x1d, 0x07, 0x04, 0x00, 0x0b, 0x08, 0x04, 0xc0, 0x38, 0x09, 0x05, 0x00, 0x23, 0x0a, 0x05, + 0xa0, 0x01, 0x0c, 0x05, 0x40, 0x07, 0x0f, 0x06, 0x78, 0x19, 0x00, 0x03, 0x80, 0x19, 0x00, 0x03, 0x88, 0x19, 0x00, 0x03, 0x70, 0x13, 0x01, 0x02, 0x74, 0x13, 0x01, 0x02, 0x78, 0x13, 0x01, 0x02, + 0x7c, 0x13, 0x01, 0x02, 0x68, 0x03, 0x02, 0x02, 0x6c, 0x03, 0x02, 0x02, 0x70, 0x03, 0x02, 0x02, 0x40, 0x2d, 0x03, 0x03, 0x48, 0x2d, 0x03, 0x03, 0x50, 0x2d, 0x03, 0x03, 0x18, 0x18, 0x04, 0x03, + 0x20, 0x18, 0x04, 0x03, 0x60, 0x07, 0x05, 0x03, 0x68, 0x07, 0x05, 0x03, 0xe0, 0x32, 0x06, 0x04, 0xd0, 0x1d, 0x07, 0x04, 0x10, 0x0b, 0x08, 0x04, 0xe0, 0x38, 0x09, 0x05, 0x20, 0x23, 0x0a, 0x05, + 0xc0, 0x01, 0x0c, 0x05, 0x00, 0x2d, 0x10, 0x07, 0x90, 0x19, 0x00, 0x03, 0x98, 0x19, 0x00, 0x03, 0xa0, 0x19, 0x00, 0x03, 0x80, 0x13, 0x01, 0x02, 0x84, 0x13, 0x01, 0x02, 0x88, 0x13, 0x01, 0x02, + 0x8c, 0x13, 0x01, 0x02, 0x74, 0x03, 0x02, 0x02, 0x78, 0x03, 0x02, 0x02, 0x7c, 0x03, 0x02, 0x02, 0x58, 0x2d, 0x03, 0x03, 0x60, 0x2d, 0x03, 0x03, 0x68, 0x2d, 0x03, 0x03, 0x28, 0x18, 0x04, 0x03, + 0x30, 0x18, 0x04, 0x03, 0x70, 0x07, 0x05, 0x03, 0x78, 0x07, 0x05, 0x03, 0xf0, 0x32, 0x06, 0x04, 0xe0, 0x1d, 0x07, 0x04, 0x20, 0x0b, 0x08, 0x04, 0x00, 0x39, 0x09, 0x05, 0x40, 0x23, 0x0a, 0x05, + 0xe0, 0x01, 0x0c, 0x05, 0x80, 0x2d, 0x10, 0x07, 0xa8, 0x19, 0x00, 0x03, 0xb0, 0x19, 0x00, 0x03, 0xb8, 0x19, 0x00, 0x03, 0x90, 0x13, 0x01, 0x02, 0x94, 0x13, 0x01, 0x02, 0x98, 0x13, 0x01, 0x02, + 0x9c, 0x13, 0x01, 0x02, 0x80, 0x03, 0x02, 0x02, 0x84, 0x03, 0x02, 0x02, 0x88, 0x03, 0x02, 0x02, 0x70, 0x2d, 0x03, 0x03, 0x78, 0x2d, 0x03, 0x03, 0x80, 0x2d, 0x03, 0x03, 0x38, 0x18, 0x04, 0x03, + 0x40, 0x18, 0x04, 0x03, 0x80, 0x07, 0x05, 0x03, 0x88, 0x07, 0x05, 0x03, 0x00, 0x33, 0x06, 0x04, 0xf0, 0x1d, 0x07, 0x04, 0x30, 0x0b, 0x08, 0x04, 0x20, 0x39, 0x09, 0x05, 0x60, 0x23, 0x0a, 0x05, + 0x00, 0x02, 0x0c, 0x05, 0x00, 0x2e, 0x10, 0x07, 0xc0, 0x19, 0x00, 0x03, 0xc8, 0x19, 0x00, 0x03, 0xd0, 0x19, 0x00, 0x03, 0xa0, 0x13, 0x01, 0x02, 0xa4, 0x13, 0x01, 0x02, 0xa8, 0x13, 0x01, 0x02, + 0xac, 0x13, 0x01, 0x02, 0x8c, 0x03, 0x02, 0x02, 0x90, 0x03, 0x02, 0x02, 0x94, 0x03, 0x02, 0x02, 0x88, 0x2d, 0x03, 0x03, 0x90, 0x2d, 0x03, 0x03, 0x98, 0x2d, 0x03, 0x03, 0x48, 0x18, 0x04, 0x03, + 0x50, 0x18, 0x04, 0x03, 0x90, 0x07, 0x05, 0x03, 0x98, 0x07, 0x05, 0x03, 0x10, 0x33, 0x06, 0x04, 0x00, 0x1e, 0x07, 0x04, 0x40, 0x0b, 0x08, 0x04, 0x40, 0x39, 0x09, 0x05, 0x80, 0x23, 0x0a, 0x05, + 0x20, 0x02, 0x0c, 0x05, 0x80, 0x2e, 0x10, 0x07, 0xd8, 0x19, 0x00, 0x03, 0xe0, 0x19, 0x00, 0x03, 0xe8, 0x19, 0x00, 0x03, 0xb0, 0x13, 0x01, 0x02, 0xb4, 0x13, 0x01, 0x02, 0xb8, 0x13, 0x01, 0x02, + 0xbc, 0x13, 0x01, 0x02, 0x98, 0x03, 0x02, 0x02, 0x9c, 0x03, 0x02, 0x02, 0xa0, 0x03, 0x02, 0x02, 0xa0, 0x2d, 0x03, 0x03, 0xa8, 0x2d, 0x03, 0x03, 0xb0, 0x2d, 0x03, 0x03, 0x58, 0x18, 0x04, 0x03, + 0x60, 0x18, 0x04, 0x03, 0xa0, 0x07, 0x05, 0x03, 0xa8, 0x07, 0x05, 0x03, 0x20, 0x33, 0x06, 0x04, 0x10, 0x1e, 0x07, 0x04, 0x50, 0x0b, 0x08, 0x04, 0x60, 0x39, 0x09, 0x05, 0xa0, 0x23, 0x0a, 0x05, + 0x40, 0x02, 0x0c, 0x05, 0x00, 0x2f, 0x10, 0x07, 0xf0, 0x19, 0x00, 0x03, 0xf8, 0x19, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x03, 0xc0, 0x13, 0x01, 0x02, 0xc4, 0x13, 0x01, 0x02, 0xc8, 0x13, 0x01, 0x02, + 0xcc, 0x13, 0x01, 0x02, 0xa4, 0x03, 0x02, 0x02, 0xa8, 0x03, 0x02, 0x02, 0xac, 0x03, 0x02, 0x02, 0xb8, 0x2d, 0x03, 0x03, 0xc0, 0x2d, 0x03, 0x03, 0xc8, 0x2d, 0x03, 0x03, 0x68, 0x18, 0x04, 0x03, + 0x70, 0x18, 0x04, 0x03, 0xb0, 0x07, 0x05, 0x03, 0xb8, 0x07, 0x05, 0x03, 0x30, 0x33, 0x06, 0x04, 0x20, 0x1e, 0x07, 0x04, 0x60, 0x0b, 0x08, 0x04, 0x80, 0x39, 0x09, 0x05, 0xc0, 0x23, 0x0a, 0x05, + 0x60, 0x02, 0x0c, 0x05, 0x80, 0x2f, 0x10, 0x07, 0x08, 0x1a, 0x00, 0x03, 0x10, 0x1a, 0x00, 0x03, 0x18, 0x1a, 0x00, 0x03, 0xd0, 0x13, 0x01, 0x02, 0xd4, 0x13, 0x01, 0x02, 0xd8, 0x13, 0x01, 0x02, + 0xdc, 0x13, 0x01, 0x02, 0xb0, 0x03, 0x02, 0x02, 0xb4, 0x03, 0x02, 0x02, 0xb8, 0x03, 0x02, 0x02, 0xd0, 0x2d, 0x03, 0x03, 0xd8, 0x2d, 0x03, 0x03, 0xe0, 0x2d, 0x03, 0x03, 0x78, 0x18, 0x04, 0x03, + 0x80, 0x18, 0x04, 0x03, 0xc0, 0x07, 0x05, 0x03, 0xc8, 0x07, 0x05, 0x03, 0x40, 0x33, 0x06, 0x04, 0x30, 0x1e, 0x07, 0x04, 0x70, 0x0b, 0x08, 0x04, 0xa0, 0x39, 0x09, 0x05, 0xe0, 0x23, 0x0a, 0x05, + 0x80, 0x02, 0x0c, 0x05, 0x00, 0x30, 0x10, 0x07, 0x20, 0x1a, 0x00, 0x03, 0x28, 0x1a, 0x00, 0x03, 0x30, 0x1a, 0x00, 0x03, 0xe0, 0x13, 0x01, 0x02, 0xe4, 0x13, 0x01, 0x02, 0xe8, 0x13, 0x01, 0x02, + 0xec, 0x13, 0x01, 0x02, 0xbc, 0x03, 0x02, 0x02, 0xc0, 0x03, 0x02, 0x02, 0xc4, 0x03, 0x02, 0x02, 0xe8, 0x2d, 0x03, 0x03, 0xf0, 0x2d, 0x03, 0x03, 0xf8, 0x2d, 0x03, 0x03, 0x88, 0x18, 0x04, 0x03, + 0x90, 0x18, 0x04, 0x03, 0xd0, 0x07, 0x05, 0x03, 0xd8, 0x07, 0x05, 0x03, 0x50, 0x33, 0x06, 0x04, 0x40, 0x1e, 0x07, 0x04, 0x80, 0x0b, 0x08, 0x04, 0xc0, 0x39, 0x09, 0x05, 0x00, 0x24, 0x0a, 0x05, + 0xa0, 0x02, 0x0c, 0x05, 0x80, 0x30, 0x10, 0x07, 0x38, 0x1a, 0x00, 0x03, 0x40, 0x1a, 0x00, 0x03, 0x48, 0x1a, 0x00, 0x03, 0xf0, 0x13, 0x01, 0x02, 0xf4, 0x13, 0x01, 0x02, 0xf8, 0x13, 0x01, 0x02, + 0xfc, 0x13, 0x01, 0x02, 0xc8, 0x03, 0x02, 0x02, 0xcc, 0x03, 0x02, 0x02, 0xd0, 0x03, 0x02, 0x02, 0x00, 0x2e, 0x03, 0x03, 0x08, 0x2e, 0x03, 0x03, 0x10, 0x2e, 0x03, 0x03, 0x98, 0x18, 0x04, 0x03, + 0xa0, 0x18, 0x04, 0x03, 0xe0, 0x07, 0x05, 0x03, 0xe8, 0x07, 0x05, 0x03, 0x60, 0x33, 0x06, 0x04, 0x50, 0x1e, 0x07, 0x04, 0x90, 0x0b, 0x08, 0x04, 0xe0, 0x39, 0x09, 0x05, 0x20, 0x24, 0x0a, 0x05, + 0xc0, 0x02, 0x0c, 0x05, 0x00, 0x31, 0x10, 0x07, 0x50, 0x1a, 0x00, 0x03, 0x58, 0x1a, 0x00, 0x03, 0x60, 0x1a, 0x00, 0x03, 0x00, 0x14, 0x01, 0x02, 0x04, 0x14, 0x01, 0x02, 0x08, 0x14, 0x01, 0x02, + 0x0c, 0x14, 0x01, 0x02, 0xd4, 0x03, 0x02, 0x02, 0xd8, 0x03, 0x02, 0x02, 0xdc, 0x03, 0x02, 0x02, 0x18, 0x2e, 0x03, 0x03, 0x20, 0x2e, 0x03, 0x03, 0x28, 0x2e, 0x03, 0x03, 0xa8, 0x18, 0x04, 0x03, + 0xb0, 0x18, 0x04, 0x03, 0xf0, 0x07, 0x05, 0x03, 0xf8, 0x07, 0x05, 0x03, 0x70, 0x33, 0x06, 0x04, 0x60, 0x1e, 0x07, 0x04, 0xa0, 0x0b, 0x08, 0x04, 0x00, 0x3a, 0x09, 0x05, 0x40, 0x24, 0x0a, 0x05, + 0xe0, 0x02, 0x0c, 0x05, 0x80, 0x31, 0x10, 0x07, 0x68, 0x1a, 0x00, 0x03, 0x70, 0x1a, 0x00, 0x03, 0x78, 0x1a, 0x00, 0x03, 0x10, 0x14, 0x01, 0x02, 0x14, 0x14, 0x01, 0x02, 0x18, 0x14, 0x01, 0x02, + 0x1c, 0x14, 0x01, 0x02, 0xe0, 0x03, 0x02, 0x02, 0xe4, 0x03, 0x02, 0x02, 0xe8, 0x03, 0x02, 0x02, 0x30, 0x2e, 0x03, 0x03, 0x38, 0x2e, 0x03, 0x03, 0x40, 0x2e, 0x03, 0x03, 0xb8, 0x18, 0x04, 0x03, + 0xc0, 0x18, 0x04, 0x03, 0x00, 0x08, 0x05, 0x03, 0x08, 0x08, 0x05, 0x03, 0x80, 0x33, 0x06, 0x04, 0x70, 0x1e, 0x07, 0x04, 0xb0, 0x0b, 0x08, 0x04, 0x20, 0x3a, 0x09, 0x05, 0x60, 0x24, 0x0a, 0x05, + 0x00, 0x03, 0x0c, 0x05, 0x00, 0x32, 0x10, 0x07, 0x80, 0x1a, 0x00, 0x03, 0x88, 0x1a, 0x00, 0x03, 0x20, 0x14, 0x01, 0x02, 0x24, 0x14, 0x01, 0x02, 0x28, 0x14, 0x01, 0x02, 0x2c, 0x14, 0x01, 0x02, + 0x30, 0x14, 0x01, 0x02, 0xec, 0x03, 0x02, 0x02, 0xf0, 0x03, 0x02, 0x02, 0xf4, 0x03, 0x02, 0x02, 0x48, 0x2e, 0x03, 0x03, 0x50, 0x2e, 0x03, 0x03, 0x58, 0x2e, 0x03, 0x03, 0xc8, 0x18, 0x04, 0x03, + 0xd0, 0x18, 0x04, 0x03, 0x10, 0x08, 0x05, 0x03, 0x18, 0x08, 0x05, 0x03, 0x90, 0x33, 0x06, 0x04, 0x80, 0x1e, 0x07, 0x04, 0xc0, 0x0b, 0x08, 0x04, 0x40, 0x3a, 0x09, 0x05, 0x80, 0x24, 0x0a, 0x05, + 0x20, 0x03, 0x0c, 0x05, 0x80, 0x32, 0x10, 0x07, 0x90, 0x1a, 0x00, 0x03, 0x98, 0x1a, 0x00, 0x03, 0x34, 0x14, 0x01, 0x02, 0x38, 0x14, 0x01, 0x02, 0x3c, 0x14, 0x01, 0x02, 0x40, 0x14, 0x01, 0x02, + 0x44, 0x14, 0x01, 0x02, 0xf8, 0x03, 0x02, 0x02, 0xfc, 0x03, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x60, 0x2e, 0x03, 0x03, 0x68, 0x2e, 0x03, 0x03, 0x70, 0x2e, 0x03, 0x03, 0xd8, 0x18, 0x04, 0x03, + 0xe0, 0x18, 0x04, 0x03, 0x20, 0x08, 0x05, 0x03, 0x28, 0x08, 0x05, 0x03, 0xa0, 0x33, 0x06, 0x04, 0x90, 0x1e, 0x07, 0x04, 0xd0, 0x0b, 0x08, 0x04, 0x60, 0x3a, 0x09, 0x05, 0xa0, 0x24, 0x0a, 0x05, + 0x40, 0x03, 0x0c, 0x05, 0x00, 0x33, 0x10, 0x07, 0xa0, 0x1a, 0x00, 0x03, 0xa8, 0x1a, 0x00, 0x03, 0x48, 0x14, 0x01, 0x02, 0x4c, 0x14, 0x01, 0x02, 0x50, 0x14, 0x01, 0x02, 0x54, 0x14, 0x01, 0x02, + 0x58, 0x14, 0x01, 0x02, 0x04, 0x04, 0x02, 0x02, 0x08, 0x04, 0x02, 0x02, 0x0c, 0x04, 0x02, 0x02, 0x78, 0x2e, 0x03, 0x03, 0x80, 0x2e, 0x03, 0x03, 0x88, 0x2e, 0x03, 0x03, 0xe8, 0x18, 0x04, 0x03, + 0xf0, 0x18, 0x04, 0x03, 0x30, 0x08, 0x05, 0x03, 0x38, 0x08, 0x05, 0x03, 0xb0, 0x33, 0x06, 0x04, 0xa0, 0x1e, 0x07, 0x04, 0xe0, 0x0b, 0x08, 0x04, 0x80, 0x3a, 0x09, 0x05, 0xc0, 0x24, 0x0a, 0x05, + 0x60, 0x03, 0x0c, 0x05, 0x80, 0x33, 0x10, 0x07, 0xb0, 0x1a, 0x00, 0x03, 0xb8, 0x1a, 0x00, 0x03, 0x5c, 0x14, 0x01, 0x02, 0x60, 0x14, 0x01, 0x02, 0x64, 0x14, 0x01, 0x02, 0x68, 0x14, 0x01, 0x02, + 0x6c, 0x14, 0x01, 0x02, 0x10, 0x04, 0x02, 0x02, 0x14, 0x04, 0x02, 0x02, 0x18, 0x04, 0x02, 0x02, 0x90, 0x2e, 0x03, 0x03, 0x98, 0x2e, 0x03, 0x03, 0xa0, 0x2e, 0x03, 0x03, 0xf8, 0x18, 0x04, 0x03, + 0x00, 0x19, 0x04, 0x03, 0x40, 0x08, 0x05, 0x03, 0x48, 0x08, 0x05, 0x03, 0xc0, 0x33, 0x06, 0x04, 0xb0, 0x1e, 0x07, 0x04, 0xf0, 0x0b, 0x08, 0x04, 0xa0, 0x3a, 0x09, 0x05, 0xe0, 0x24, 0x0a, 0x05, + 0x80, 0x03, 0x0c, 0x05, 0x00, 0x17, 0x11, 0x07, 0xc0, 0x1a, 0x00, 0x03, 0xc8, 0x1a, 0x00, 0x03, 0x70, 0x14, 0x01, 0x02, 0x74, 0x14, 0x01, 0x02, 0x78, 0x14, 0x01, 0x02, 0x7c, 0x14, 0x01, 0x02, + 0x80, 0x14, 0x01, 0x02, 0x1c, 0x04, 0x02, 0x02, 0x20, 0x04, 0x02, 0x02, 0x24, 0x04, 0x02, 0x02, 0xa8, 0x2e, 0x03, 0x03, 0xb0, 0x2e, 0x03, 0x03, 0xb8, 0x2e, 0x03, 0x03, 0x08, 0x19, 0x04, 0x03, + 0x10, 0x19, 0x04, 0x03, 0x50, 0x08, 0x05, 0x03, 0x58, 0x08, 0x05, 0x03, 0xd0, 0x33, 0x06, 0x04, 0xc0, 0x1e, 0x07, 0x04, 0x00, 0x0c, 0x08, 0x04, 0xc0, 0x3a, 0x09, 0x05, 0x00, 0x25, 0x0a, 0x05, + 0xa0, 0x03, 0x0c, 0x05, 0x80, 0x17, 0x11, 0x07, 0xd0, 0x1a, 0x00, 0x03, 0xd8, 0x1a, 0x00, 0x03, 0x84, 0x14, 0x01, 0x02, 0x88, 0x14, 0x01, 0x02, 0x8c, 0x14, 0x01, 0x02, 0x90, 0x14, 0x01, 0x02, + 0x94, 0x14, 0x01, 0x02, 0x28, 0x04, 0x02, 0x02, 0x2c, 0x04, 0x02, 0x02, 0x30, 0x04, 0x02, 0x02, 0xc0, 0x2e, 0x03, 0x03, 0xc8, 0x2e, 0x03, 0x03, 0xd0, 0x2e, 0x03, 0x03, 0x18, 0x19, 0x04, 0x03, + 0x20, 0x19, 0x04, 0x03, 0x60, 0x08, 0x05, 0x03, 0x68, 0x08, 0x05, 0x03, 0xe0, 0x33, 0x06, 0x04, 0xd0, 0x1e, 0x07, 0x04, 0x10, 0x0c, 0x08, 0x04, 0xe0, 0x3a, 0x09, 0x05, 0x20, 0x25, 0x0a, 0x05, + 0x80, 0x26, 0x0d, 0x06, 0x00, 0x18, 0x11, 0x07, 0xe0, 0x1a, 0x00, 0x03, 0xe8, 0x1a, 0x00, 0x03, 0x98, 0x14, 0x01, 0x02, 0x9c, 0x14, 0x01, 0x02, 0xa0, 0x14, 0x01, 0x02, 0xa4, 0x14, 0x01, 0x02, + 0xa8, 0x14, 0x01, 0x02, 0x34, 0x04, 0x02, 0x02, 0x38, 0x04, 0x02, 0x02, 0x3c, 0x04, 0x02, 0x02, 0xd8, 0x2e, 0x03, 0x03, 0xe0, 0x2e, 0x03, 0x03, 0xe8, 0x2e, 0x03, 0x03, 0x28, 0x19, 0x04, 0x03, + 0x30, 0x19, 0x04, 0x03, 0x70, 0x08, 0x05, 0x03, 0x78, 0x08, 0x05, 0x03, 0xf0, 0x33, 0x06, 0x04, 0xe0, 0x1e, 0x07, 0x04, 0x20, 0x0c, 0x08, 0x04, 0x00, 0x3b, 0x09, 0x05, 0x40, 0x25, 0x0a, 0x05, + 0xc0, 0x26, 0x0d, 0x06, 0x80, 0x18, 0x11, 0x07, 0xf0, 0x1a, 0x00, 0x03, 0xf8, 0x1a, 0x00, 0x03, 0xac, 0x14, 0x01, 0x02, 0xb0, 0x14, 0x01, 0x02, 0xb4, 0x14, 0x01, 0x02, 0xb8, 0x14, 0x01, 0x02, + 0xbc, 0x14, 0x01, 0x02, 0x40, 0x04, 0x02, 0x02, 0x44, 0x04, 0x02, 0x02, 0x48, 0x04, 0x02, 0x02, 0xf0, 0x2e, 0x03, 0x03, 0xf8, 0x2e, 0x03, 0x03, 0x00, 0x2f, 0x03, 0x03, 0x38, 0x19, 0x04, 0x03, + 0x40, 0x19, 0x04, 0x03, 0x80, 0x08, 0x05, 0x03, 0x88, 0x08, 0x05, 0x03, 0x00, 0x34, 0x06, 0x04, 0xf0, 0x1e, 0x07, 0x04, 0x30, 0x0c, 0x08, 0x04, 0x20, 0x3b, 0x09, 0x05, 0x60, 0x25, 0x0a, 0x05, + 0x00, 0x27, 0x0d, 0x06, 0x00, 0x19, 0x11, 0x07, 0x00, 0x1b, 0x00, 0x03, 0x08, 0x1b, 0x00, 0x03, 0xc0, 0x14, 0x01, 0x02, 0xc4, 0x14, 0x01, 0x02, 0xc8, 0x14, 0x01, 0x02, 0xcc, 0x14, 0x01, 0x02, + 0xd0, 0x14, 0x01, 0x02, 0x4c, 0x04, 0x02, 0x02, 0x50, 0x04, 0x02, 0x02, 0x54, 0x04, 0x02, 0x02, 0x08, 0x2f, 0x03, 0x03, 0x10, 0x2f, 0x03, 0x03, 0x18, 0x2f, 0x03, 0x03, 0x48, 0x19, 0x04, 0x03, + 0x50, 0x19, 0x04, 0x03, 0x90, 0x08, 0x05, 0x03, 0x98, 0x08, 0x05, 0x03, 0x10, 0x34, 0x06, 0x04, 0x00, 0x1f, 0x07, 0x04, 0x40, 0x0c, 0x08, 0x04, 0x40, 0x3b, 0x09, 0x05, 0x80, 0x25, 0x0a, 0x05, + 0x40, 0x27, 0x0d, 0x06, 0x80, 0x19, 0x11, 0x07, 0x10, 0x1b, 0x00, 0x03, 0x18, 0x1b, 0x00, 0x03, 0xd4, 0x14, 0x01, 0x02, 0xd8, 0x14, 0x01, 0x02, 0xdc, 0x14, 0x01, 0x02, 0xe0, 0x14, 0x01, 0x02, + 0xe4, 0x14, 0x01, 0x02, 0x58, 0x04, 0x02, 0x02, 0x5c, 0x04, 0x02, 0x02, 0x60, 0x04, 0x02, 0x02, 0x20, 0x2f, 0x03, 0x03, 0x28, 0x2f, 0x03, 0x03, 0x30, 0x2f, 0x03, 0x03, 0x58, 0x19, 0x04, 0x03, + 0x60, 0x19, 0x04, 0x03, 0xa0, 0x08, 0x05, 0x03, 0xa8, 0x08, 0x05, 0x03, 0x20, 0x34, 0x06, 0x04, 0x10, 0x1f, 0x07, 0x04, 0x50, 0x0c, 0x08, 0x04, 0x60, 0x3b, 0x09, 0x05, 0xa0, 0x25, 0x0a, 0x05, + 0x80, 0x27, 0x0d, 0x06, 0x00, 0x1a, 0x11, 0x07, 0x20, 0x1b, 0x00, 0x03, 0x28, 0x1b, 0x00, 0x03, 0xe8, 0x14, 0x01, 0x02, 0xec, 0x14, 0x01, 0x02, 0xf0, 0x14, 0x01, 0x02, 0xf4, 0x14, 0x01, 0x02, + 0xf8, 0x14, 0x01, 0x02, 0x64, 0x04, 0x02, 0x02, 0x68, 0x04, 0x02, 0x02, 0x6c, 0x04, 0x02, 0x02, 0x38, 0x2f, 0x03, 0x03, 0x40, 0x2f, 0x03, 0x03, 0x48, 0x2f, 0x03, 0x03, 0x68, 0x19, 0x04, 0x03, + 0x70, 0x19, 0x04, 0x03, 0xb0, 0x08, 0x05, 0x03, 0xb8, 0x08, 0x05, 0x03, 0x30, 0x34, 0x06, 0x04, 0x20, 0x1f, 0x07, 0x04, 0x60, 0x0c, 0x08, 0x04, 0x80, 0x3b, 0x09, 0x05, 0xc0, 0x25, 0x0a, 0x05, + 0xc0, 0x27, 0x0d, 0x06, 0x80, 0x1a, 0x11, 0x07, 0x30, 0x1b, 0x00, 0x03, 0x38, 0x1b, 0x00, 0x03, 0xfc, 0x14, 0x01, 0x02, 0x00, 0x15, 0x01, 0x02, 0x04, 0x15, 0x01, 0x02, 0x08, 0x15, 0x01, 0x02, + 0x0c, 0x15, 0x01, 0x02, 0x70, 0x04, 0x02, 0x02, 0x74, 0x04, 0x02, 0x02, 0x78, 0x04, 0x02, 0x02, 0x50, 0x2f, 0x03, 0x03, 0x58, 0x2f, 0x03, 0x03, 0x60, 0x2f, 0x03, 0x03, 0x78, 0x19, 0x04, 0x03, + 0x80, 0x19, 0x04, 0x03, 0xc0, 0x08, 0x05, 0x03, 0xc8, 0x08, 0x05, 0x03, 0x40, 0x34, 0x06, 0x04, 0x30, 0x1f, 0x07, 0x04, 0x70, 0x0c, 0x08, 0x04, 0xa0, 0x3b, 0x09, 0x05, 0xe0, 0x25, 0x0a, 0x05, + 0x00, 0x28, 0x0d, 0x06, 0x00, 0x1b, 0x11, 0x07, 0x40, 0x1b, 0x00, 0x03, 0x48, 0x1b, 0x00, 0x03, 0x10, 0x15, 0x01, 0x02, 0x14, 0x15, 0x01, 0x02, 0x18, 0x15, 0x01, 0x02, 0x1c, 0x15, 0x01, 0x02, + 0x20, 0x15, 0x01, 0x02, 0x7c, 0x04, 0x02, 0x02, 0x80, 0x04, 0x02, 0x02, 0x84, 0x04, 0x02, 0x02, 0x68, 0x2f, 0x03, 0x03, 0x70, 0x2f, 0x03, 0x03, 0x78, 0x2f, 0x03, 0x03, 0x88, 0x19, 0x04, 0x03, + 0x90, 0x19, 0x04, 0x03, 0xd0, 0x08, 0x05, 0x03, 0xd8, 0x08, 0x05, 0x03, 0x50, 0x34, 0x06, 0x04, 0x40, 0x1f, 0x07, 0x04, 0x80, 0x0c, 0x08, 0x04, 0xc0, 0x3b, 0x09, 0x05, 0x00, 0x26, 0x0a, 0x05, + 0x40, 0x28, 0x0d, 0x06, 0x80, 0x1b, 0x11, 0x07, 0x50, 0x1b, 0x00, 0x03, 0x58, 0x1b, 0x00, 0x03, 0x24, 0x15, 0x01, 0x02, 0x28, 0x15, 0x01, 0x02, 0x2c, 0x15, 0x01, 0x02, 0x30, 0x15, 0x01, 0x02, + 0x34, 0x15, 0x01, 0x02, 0x88, 0x04, 0x02, 0x02, 0x8c, 0x04, 0x02, 0x02, 0x90, 0x04, 0x02, 0x02, 0x80, 0x2f, 0x03, 0x03, 0x88, 0x2f, 0x03, 0x03, 0x90, 0x2f, 0x03, 0x03, 0x98, 0x19, 0x04, 0x03, + 0xa0, 0x19, 0x04, 0x03, 0xe0, 0x08, 0x05, 0x03, 0xe8, 0x08, 0x05, 0x03, 0x60, 0x34, 0x06, 0x04, 0x50, 0x1f, 0x07, 0x04, 0x90, 0x0c, 0x08, 0x04, 0xe0, 0x3b, 0x09, 0x05, 0x20, 0x26, 0x0a, 0x05, + 0x80, 0x28, 0x0d, 0x06, 0x00, 0x1c, 0x11, 0x07, 0x60, 0x1b, 0x00, 0x03, 0x68, 0x1b, 0x00, 0x03, 0x38, 0x15, 0x01, 0x02, 0x3c, 0x15, 0x01, 0x02, 0x40, 0x15, 0x01, 0x02, 0x44, 0x15, 0x01, 0x02, + 0x94, 0x04, 0x02, 0x02, 0x98, 0x04, 0x02, 0x02, 0x9c, 0x04, 0x02, 0x02, 0xa0, 0x04, 0x02, 0x02, 0x98, 0x2f, 0x03, 0x03, 0xa0, 0x2f, 0x03, 0x03, 0xa8, 0x2f, 0x03, 0x03, 0xa8, 0x19, 0x04, 0x03, + 0xb0, 0x19, 0x04, 0x03, 0xf0, 0x08, 0x05, 0x03, 0xf8, 0x08, 0x05, 0x03, 0x70, 0x34, 0x06, 0x04, 0x60, 0x1f, 0x07, 0x04, 0xa0, 0x0c, 0x08, 0x04, 0x00, 0x3c, 0x09, 0x05, 0xa0, 0x0e, 0x0b, 0x05, + 0xc0, 0x28, 0x0d, 0x06, 0x80, 0x1c, 0x11, 0x07, 0x70, 0x1b, 0x00, 0x03, 0x78, 0x1b, 0x00, 0x03, 0x48, 0x15, 0x01, 0x02, 0x4c, 0x15, 0x01, 0x02, 0x50, 0x15, 0x01, 0x02, 0x54, 0x15, 0x01, 0x02, + 0xa4, 0x04, 0x02, 0x02, 0xa8, 0x04, 0x02, 0x02, 0xac, 0x04, 0x02, 0x02, 0xb0, 0x04, 0x02, 0x02, 0xb0, 0x2f, 0x03, 0x03, 0xb8, 0x2f, 0x03, 0x03, 0xc0, 0x2f, 0x03, 0x03, 0xb8, 0x19, 0x04, 0x03, + 0xc0, 0x19, 0x04, 0x03, 0x00, 0x09, 0x05, 0x03, 0x08, 0x09, 0x05, 0x03, 0x80, 0x34, 0x06, 0x04, 0x70, 0x1f, 0x07, 0x04, 0xb0, 0x0c, 0x08, 0x04, 0x20, 0x3c, 0x09, 0x05, 0xc0, 0x0e, 0x0b, 0x05, + 0x00, 0x29, 0x0d, 0x06, 0x80, 0x07, 0x12, 0x07, 0x80, 0x1b, 0x00, 0x03, 0x88, 0x1b, 0x00, 0x03, 0x58, 0x15, 0x01, 0x02, 0x5c, 0x15, 0x01, 0x02, 0x60, 0x15, 0x01, 0x02, 0x64, 0x15, 0x01, 0x02, + 0xb4, 0x04, 0x02, 0x02, 0xb8, 0x04, 0x02, 0x02, 0xbc, 0x04, 0x02, 0x02, 0xc0, 0x04, 0x02, 0x02, 0xc8, 0x2f, 0x03, 0x03, 0xd0, 0x2f, 0x03, 0x03, 0xd8, 0x2f, 0x03, 0x03, 0xc8, 0x19, 0x04, 0x03, + 0xd0, 0x19, 0x04, 0x03, 0x10, 0x09, 0x05, 0x03, 0x18, 0x09, 0x05, 0x03, 0x90, 0x34, 0x06, 0x04, 0x80, 0x1f, 0x07, 0x04, 0xc0, 0x0c, 0x08, 0x04, 0x40, 0x3c, 0x09, 0x05, 0xe0, 0x0e, 0x0b, 0x05, + 0x40, 0x29, 0x0d, 0x06, 0x00, 0x08, 0x12, 0x07, 0x90, 0x1b, 0x00, 0x03, 0x98, 0x1b, 0x00, 0x03, 0x68, 0x15, 0x01, 0x02, 0x6c, 0x15, 0x01, 0x02, 0x70, 0x15, 0x01, 0x02, 0x74, 0x15, 0x01, 0x02, + 0xc4, 0x04, 0x02, 0x02, 0xc8, 0x04, 0x02, 0x02, 0xcc, 0x04, 0x02, 0x02, 0xd0, 0x04, 0x02, 0x02, 0xe0, 0x2f, 0x03, 0x03, 0xe8, 0x2f, 0x03, 0x03, 0xf0, 0x2f, 0x03, 0x03, 0xd8, 0x19, 0x04, 0x03, + 0xe0, 0x19, 0x04, 0x03, 0x20, 0x09, 0x05, 0x03, 0x28, 0x09, 0x05, 0x03, 0xa0, 0x34, 0x06, 0x04, 0x90, 0x1f, 0x07, 0x04, 0xd0, 0x0c, 0x08, 0x04, 0x60, 0x3c, 0x09, 0x05, 0x00, 0x0f, 0x0b, 0x05, + 0x80, 0x29, 0x0d, 0x06, 0x80, 0x08, 0x12, 0x07, 0xa0, 0x1b, 0x00, 0x03, 0xa8, 0x1b, 0x00, 0x03, 0x78, 0x15, 0x01, 0x02, 0x7c, 0x15, 0x01, 0x02, 0x80, 0x15, 0x01, 0x02, 0x84, 0x15, 0x01, 0x02, + 0xd4, 0x04, 0x02, 0x02, 0xd8, 0x04, 0x02, 0x02, 0xdc, 0x04, 0x02, 0x02, 0xe0, 0x04, 0x02, 0x02, 0xf8, 0x2f, 0x03, 0x03, 0x00, 0x30, 0x03, 0x03, 0x08, 0x30, 0x03, 0x03, 0xe8, 0x19, 0x04, 0x03, + 0xf0, 0x19, 0x04, 0x03, 0x30, 0x09, 0x05, 0x03, 0x38, 0x09, 0x05, 0x03, 0xb0, 0x34, 0x06, 0x04, 0xa0, 0x1f, 0x07, 0x04, 0xe0, 0x0c, 0x08, 0x04, 0x80, 0x3c, 0x09, 0x05, 0x20, 0x0f, 0x0b, 0x05, + 0xc0, 0x29, 0x0d, 0x06, 0x00, 0x09, 0x12, 0x07, 0xb0, 0x1b, 0x00, 0x03, 0xb8, 0x1b, 0x00, 0x03, 0x88, 0x15, 0x01, 0x02, 0x8c, 0x15, 0x01, 0x02, 0x90, 0x15, 0x01, 0x02, 0x94, 0x15, 0x01, 0x02, + 0xe4, 0x04, 0x02, 0x02, 0xe8, 0x04, 0x02, 0x02, 0xec, 0x04, 0x02, 0x02, 0xf0, 0x04, 0x02, 0x02, 0x10, 0x30, 0x03, 0x03, 0x18, 0x30, 0x03, 0x03, 0x20, 0x30, 0x03, 0x03, 0xf8, 0x19, 0x04, 0x03, + 0x00, 0x1a, 0x04, 0x03, 0x40, 0x09, 0x05, 0x03, 0x48, 0x09, 0x05, 0x03, 0xc0, 0x34, 0x06, 0x04, 0xb0, 0x1f, 0x07, 0x04, 0xf0, 0x0c, 0x08, 0x04, 0xa0, 0x3c, 0x09, 0x05, 0x40, 0x0f, 0x0b, 0x05, + 0x00, 0x2a, 0x0d, 0x06, 0x80, 0x09, 0x12, 0x07, 0xc0, 0x1b, 0x00, 0x03, 0xc8, 0x1b, 0x00, 0x03, 0x98, 0x15, 0x01, 0x02, 0x9c, 0x15, 0x01, 0x02, 0xa0, 0x15, 0x01, 0x02, 0xa4, 0x15, 0x01, 0x02, + 0xf4, 0x04, 0x02, 0x02, 0xf8, 0x04, 0x02, 0x02, 0xfc, 0x04, 0x02, 0x02, 0x00, 0x05, 0x02, 0x02, 0x28, 0x30, 0x03, 0x03, 0x30, 0x30, 0x03, 0x03, 0x38, 0x30, 0x03, 0x03, 0x08, 0x1a, 0x04, 0x03, + 0x10, 0x1a, 0x04, 0x03, 0x50, 0x09, 0x05, 0x03, 0x58, 0x09, 0x05, 0x03, 0xd0, 0x34, 0x06, 0x04, 0xc0, 0x1f, 0x07, 0x04, 0x00, 0x0d, 0x08, 0x04, 0xc0, 0x3c, 0x09, 0x05, 0x60, 0x0f, 0x0b, 0x05, + 0x40, 0x2a, 0x0d, 0x06, 0x00, 0x0a, 0x12, 0x07, 0xd0, 0x1b, 0x00, 0x03, 0xd8, 0x1b, 0x00, 0x03, 0xa8, 0x15, 0x01, 0x02, 0xac, 0x15, 0x01, 0x02, 0xb0, 0x15, 0x01, 0x02, 0xb4, 0x15, 0x01, 0x02, + 0x04, 0x05, 0x02, 0x02, 0x08, 0x05, 0x02, 0x02, 0x0c, 0x05, 0x02, 0x02, 0x10, 0x05, 0x02, 0x02, 0x40, 0x30, 0x03, 0x03, 0x48, 0x30, 0x03, 0x03, 0x50, 0x30, 0x03, 0x03, 0x18, 0x1a, 0x04, 0x03, + 0x20, 0x1a, 0x04, 0x03, 0x60, 0x09, 0x05, 0x03, 0xe0, 0x34, 0x06, 0x04, 0xf0, 0x34, 0x06, 0x04, 0xd0, 0x1f, 0x07, 0x04, 0x10, 0x0d, 0x08, 0x04, 0xe0, 0x3c, 0x09, 0x05, 0x80, 0x0f, 0x0b, 0x05, + 0x80, 0x2a, 0x0d, 0x06, 0x80, 0x0a, 0x12, 0x07, 0xe0, 0x1b, 0x00, 0x03, 0xe8, 0x1b, 0x00, 0x03, 0xb8, 0x15, 0x01, 0x02, 0xbc, 0x15, 0x01, 0x02, 0xc0, 0x15, 0x01, 0x02, 0xc4, 0x15, 0x01, 0x02, + 0x14, 0x05, 0x02, 0x02, 0x18, 0x05, 0x02, 0x02, 0x1c, 0x05, 0x02, 0x02, 0x20, 0x05, 0x02, 0x02, 0x58, 0x30, 0x03, 0x03, 0x60, 0x30, 0x03, 0x03, 0x28, 0x1a, 0x04, 0x03, 0x30, 0x1a, 0x04, 0x03, + 0x38, 0x1a, 0x04, 0x03, 0x68, 0x09, 0x05, 0x03, 0x00, 0x35, 0x06, 0x04, 0x10, 0x35, 0x06, 0x04, 0xe0, 0x1f, 0x07, 0x04, 0x20, 0x0d, 0x08, 0x04, 0x00, 0x3d, 0x09, 0x05, 0xa0, 0x0f, 0x0b, 0x05, + 0xc0, 0x2a, 0x0d, 0x06, 0x00, 0x0b, 0x12, 0x07, 0xf0, 0x1b, 0x00, 0x03, 0xf8, 0x1b, 0x00, 0x03, 0xc8, 0x15, 0x01, 0x02, 0xcc, 0x15, 0x01, 0x02, 0xd0, 0x15, 0x01, 0x02, 0xd4, 0x15, 0x01, 0x02, + 0x24, 0x05, 0x02, 0x02, 0x28, 0x05, 0x02, 0x02, 0x2c, 0x05, 0x02, 0x02, 0x30, 0x05, 0x02, 0x02, 0x68, 0x30, 0x03, 0x03, 0x70, 0x30, 0x03, 0x03, 0x40, 0x1a, 0x04, 0x03, 0x48, 0x1a, 0x04, 0x03, + 0x50, 0x1a, 0x04, 0x03, 0x70, 0x09, 0x05, 0x03, 0x20, 0x35, 0x06, 0x04, 0x30, 0x35, 0x06, 0x04, 0xf0, 0x1f, 0x07, 0x04, 0x30, 0x0d, 0x08, 0x04, 0x20, 0x3d, 0x09, 0x05, 0xc0, 0x0f, 0x0b, 0x05, + 0x00, 0x2b, 0x0d, 0x06, 0x80, 0x0b, 0x12, 0x07, 0x00, 0x1c, 0x00, 0x03, 0x08, 0x1c, 0x00, 0x03, 0xd8, 0x15, 0x01, 0x02, 0xdc, 0x15, 0x01, 0x02, 0xe0, 0x15, 0x01, 0x02, 0xe4, 0x15, 0x01, 0x02, + 0x34, 0x05, 0x02, 0x02, 0x38, 0x05, 0x02, 0x02, 0x3c, 0x05, 0x02, 0x02, 0x40, 0x05, 0x02, 0x02, 0x78, 0x30, 0x03, 0x03, 0x80, 0x30, 0x03, 0x03, 0x58, 0x1a, 0x04, 0x03, 0x60, 0x1a, 0x04, 0x03, + 0x68, 0x1a, 0x04, 0x03, 0x78, 0x09, 0x05, 0x03, 0x40, 0x35, 0x06, 0x04, 0x50, 0x35, 0x06, 0x04, 0x00, 0x20, 0x07, 0x04, 0x40, 0x0d, 0x08, 0x04, 0x40, 0x3d, 0x09, 0x05, 0xe0, 0x0f, 0x0b, 0x05, + 0x40, 0x2b, 0x0d, 0x06, 0x00, 0x32, 0x13, 0x08, 0x10, 0x1c, 0x00, 0x03, 0x18, 0x1c, 0x00, 0x03, 0xe8, 0x15, 0x01, 0x02, 0xec, 0x15, 0x01, 0x02, 0xf0, 0x15, 0x01, 0x02, 0xf4, 0x15, 0x01, 0x02, + 0x44, 0x05, 0x02, 0x02, 0x48, 0x05, 0x02, 0x02, 0x4c, 0x05, 0x02, 0x02, 0x50, 0x05, 0x02, 0x02, 0x88, 0x30, 0x03, 0x03, 0x90, 0x30, 0x03, 0x03, 0x70, 0x1a, 0x04, 0x03, 0x78, 0x1a, 0x04, 0x03, + 0x80, 0x1a, 0x04, 0x03, 0x80, 0x09, 0x05, 0x03, 0x60, 0x35, 0x06, 0x04, 0x70, 0x35, 0x06, 0x04, 0x10, 0x20, 0x07, 0x04, 0x50, 0x0d, 0x08, 0x04, 0x60, 0x3d, 0x09, 0x05, 0x00, 0x10, 0x0b, 0x05, + 0x80, 0x2b, 0x0d, 0x06, 0x00, 0x33, 0x13, 0x08, 0x20, 0x1c, 0x00, 0x03, 0x28, 0x1c, 0x00, 0x03, 0xf8, 0x15, 0x01, 0x02, 0xfc, 0x15, 0x01, 0x02, 0x00, 0x16, 0x01, 0x02, 0x04, 0x16, 0x01, 0x02, + 0x54, 0x05, 0x02, 0x02, 0x58, 0x05, 0x02, 0x02, 0x5c, 0x05, 0x02, 0x02, 0x60, 0x05, 0x02, 0x02, 0x98, 0x30, 0x03, 0x03, 0xa0, 0x30, 0x03, 0x03, 0x88, 0x1a, 0x04, 0x03, 0x90, 0x1a, 0x04, 0x03, + 0x98, 0x1a, 0x04, 0x03, 0x88, 0x09, 0x05, 0x03, 0x80, 0x35, 0x06, 0x04, 0x90, 0x35, 0x06, 0x04, 0x20, 0x20, 0x07, 0x04, 0x60, 0x0d, 0x08, 0x04, 0x80, 0x3d, 0x09, 0x05, 0x20, 0x10, 0x0b, 0x05, + 0xc0, 0x2b, 0x0d, 0x06, 0x00, 0x34, 0x13, 0x08, 0x30, 0x1c, 0x00, 0x03, 0x38, 0x1c, 0x00, 0x03, 0x08, 0x16, 0x01, 0x02, 0x0c, 0x16, 0x01, 0x02, 0x10, 0x16, 0x01, 0x02, 0x14, 0x16, 0x01, 0x02, + 0x64, 0x05, 0x02, 0x02, 0x68, 0x05, 0x02, 0x02, 0x6c, 0x05, 0x02, 0x02, 0x70, 0x05, 0x02, 0x02, 0xa8, 0x30, 0x03, 0x03, 0xb0, 0x30, 0x03, 0x03, 0xa0, 0x1a, 0x04, 0x03, 0xa8, 0x1a, 0x04, 0x03, + 0xb0, 0x1a, 0x04, 0x03, 0x90, 0x09, 0x05, 0x03, 0xa0, 0x35, 0x06, 0x04, 0xb0, 0x35, 0x06, 0x04, 0x30, 0x20, 0x07, 0x04, 0x70, 0x0d, 0x08, 0x04, 0xa0, 0x3d, 0x09, 0x05, 0x40, 0x10, 0x0b, 0x05, + 0x00, 0x2c, 0x0d, 0x06, 0x00, 0x35, 0x13, 0x08, 0x40, 0x1c, 0x00, 0x03, 0x48, 0x1c, 0x00, 0x03, 0x18, 0x16, 0x01, 0x02, 0x1c, 0x16, 0x01, 0x02, 0x20, 0x16, 0x01, 0x02, 0x24, 0x16, 0x01, 0x02, + 0x74, 0x05, 0x02, 0x02, 0x78, 0x05, 0x02, 0x02, 0x7c, 0x05, 0x02, 0x02, 0x80, 0x05, 0x02, 0x02, 0xb8, 0x30, 0x03, 0x03, 0xc0, 0x30, 0x03, 0x03, 0xb8, 0x1a, 0x04, 0x03, 0xc0, 0x1a, 0x04, 0x03, + 0xc8, 0x1a, 0x04, 0x03, 0x98, 0x09, 0x05, 0x03, 0xc0, 0x35, 0x06, 0x04, 0xd0, 0x35, 0x06, 0x04, 0x40, 0x20, 0x07, 0x04, 0x80, 0x0d, 0x08, 0x04, 0xc0, 0x3d, 0x09, 0x05, 0x60, 0x10, 0x0b, 0x05, + 0x40, 0x2c, 0x0d, 0x06, 0x00, 0x36, 0x13, 0x08, 0x50, 0x1c, 0x00, 0x03, 0x58, 0x1c, 0x00, 0x03, 0x28, 0x16, 0x01, 0x02, 0x2c, 0x16, 0x01, 0x02, 0x30, 0x16, 0x01, 0x02, 0x34, 0x16, 0x01, 0x02, + 0x84, 0x05, 0x02, 0x02, 0x88, 0x05, 0x02, 0x02, 0x8c, 0x05, 0x02, 0x02, 0x90, 0x05, 0x02, 0x02, 0xc8, 0x30, 0x03, 0x03, 0xd0, 0x30, 0x03, 0x03, 0xd0, 0x1a, 0x04, 0x03, 0xd8, 0x1a, 0x04, 0x03, + 0xe0, 0x1a, 0x04, 0x03, 0xa0, 0x09, 0x05, 0x03, 0xe0, 0x35, 0x06, 0x04, 0xf0, 0x35, 0x06, 0x04, 0x50, 0x20, 0x07, 0x04, 0x90, 0x0d, 0x08, 0x04, 0xe0, 0x3d, 0x09, 0x05, 0x80, 0x10, 0x0b, 0x05, + 0x80, 0x2c, 0x0d, 0x06, 0x00, 0x37, 0x13, 0x08, 0x60, 0x1c, 0x00, 0x03, 0x68, 0x1c, 0x00, 0x03, 0x38, 0x16, 0x01, 0x02, 0x3c, 0x16, 0x01, 0x02, 0x40, 0x16, 0x01, 0x02, 0x44, 0x16, 0x01, 0x02, + 0x94, 0x05, 0x02, 0x02, 0x98, 0x05, 0x02, 0x02, 0x9c, 0x05, 0x02, 0x02, 0xa0, 0x05, 0x02, 0x02, 0xd8, 0x30, 0x03, 0x03, 0xe0, 0x30, 0x03, 0x03, 0xe8, 0x1a, 0x04, 0x03, 0xf0, 0x1a, 0x04, 0x03, + 0xf8, 0x1a, 0x04, 0x03, 0xa8, 0x09, 0x05, 0x03, 0x00, 0x36, 0x06, 0x04, 0x10, 0x36, 0x06, 0x04, 0x60, 0x20, 0x07, 0x04, 0xa0, 0x0d, 0x08, 0x04, 0x00, 0x3e, 0x09, 0x05, 0xa0, 0x10, 0x0b, 0x05, + 0xc0, 0x2c, 0x0d, 0x06, 0x00, 0x38, 0x13, 0x08, 0x70, 0x1c, 0x00, 0x03, 0x78, 0x1c, 0x00, 0x03, 0x48, 0x16, 0x01, 0x02, 0x4c, 0x16, 0x01, 0x02, 0x50, 0x16, 0x01, 0x02, 0x54, 0x16, 0x01, 0x02, + 0xa4, 0x05, 0x02, 0x02, 0xa8, 0x05, 0x02, 0x02, 0xac, 0x05, 0x02, 0x02, 0xb0, 0x05, 0x02, 0x02, 0xe8, 0x30, 0x03, 0x03, 0xf0, 0x30, 0x03, 0x03, 0x00, 0x1b, 0x04, 0x03, 0x08, 0x1b, 0x04, 0x03, + 0x10, 0x1b, 0x04, 0x03, 0xb0, 0x09, 0x05, 0x03, 0x20, 0x36, 0x06, 0x04, 0x30, 0x36, 0x06, 0x04, 0x70, 0x20, 0x07, 0x04, 0xb0, 0x0d, 0x08, 0x04, 0x20, 0x3e, 0x09, 0x05, 0xc0, 0x10, 0x0b, 0x05, + 0x00, 0x2d, 0x0d, 0x06, 0x00, 0x39, 0x13, 0x08, 0x80, 0x1c, 0x00, 0x03, 0x88, 0x1c, 0x00, 0x03, 0x58, 0x16, 0x01, 0x02, 0x5c, 0x16, 0x01, 0x02, 0x60, 0x16, 0x01, 0x02, 0x64, 0x16, 0x01, 0x02, + 0xb4, 0x05, 0x02, 0x02, 0xb8, 0x05, 0x02, 0x02, 0xbc, 0x05, 0x02, 0x02, 0xc0, 0x05, 0x02, 0x02, 0xf8, 0x30, 0x03, 0x03, 0x00, 0x31, 0x03, 0x03, 0x18, 0x1b, 0x04, 0x03, 0x20, 0x1b, 0x04, 0x03, + 0x28, 0x1b, 0x04, 0x03, 0xb8, 0x09, 0x05, 0x03, 0x40, 0x36, 0x06, 0x04, 0x50, 0x36, 0x06, 0x04, 0x80, 0x20, 0x07, 0x04, 0xc0, 0x0d, 0x08, 0x04, 0x40, 0x3e, 0x09, 0x05, 0xe0, 0x10, 0x0b, 0x05, + 0x40, 0x2d, 0x0d, 0x06, 0x00, 0x1c, 0x14, 0x08, 0x90, 0x1c, 0x00, 0x03, 0x98, 0x1c, 0x00, 0x03, 0x68, 0x16, 0x01, 0x02, 0x6c, 0x16, 0x01, 0x02, 0x70, 0x16, 0x01, 0x02, 0x74, 0x16, 0x01, 0x02, + 0xc4, 0x05, 0x02, 0x02, 0xc8, 0x05, 0x02, 0x02, 0xcc, 0x05, 0x02, 0x02, 0xd0, 0x05, 0x02, 0x02, 0x08, 0x31, 0x03, 0x03, 0x10, 0x31, 0x03, 0x03, 0x30, 0x1b, 0x04, 0x03, 0x38, 0x1b, 0x04, 0x03, + 0x40, 0x1b, 0x04, 0x03, 0xc0, 0x09, 0x05, 0x03, 0x60, 0x36, 0x06, 0x04, 0x70, 0x36, 0x06, 0x04, 0x90, 0x20, 0x07, 0x04, 0xd0, 0x0d, 0x08, 0x04, 0x60, 0x3e, 0x09, 0x05, 0x00, 0x11, 0x0b, 0x05, + 0x00, 0x13, 0x0e, 0x06, 0x00, 0x1d, 0x14, 0x08, 0xa0, 0x1c, 0x00, 0x03, 0xa8, 0x1c, 0x00, 0x03, 0x78, 0x16, 0x01, 0x02, 0x7c, 0x16, 0x01, 0x02, 0x80, 0x16, 0x01, 0x02, 0x84, 0x16, 0x01, 0x02, + 0xd4, 0x05, 0x02, 0x02, 0xd8, 0x05, 0x02, 0x02, 0xdc, 0x05, 0x02, 0x02, 0xe0, 0x05, 0x02, 0x02, 0x18, 0x31, 0x03, 0x03, 0x20, 0x31, 0x03, 0x03, 0x48, 0x1b, 0x04, 0x03, 0x50, 0x1b, 0x04, 0x03, + 0x58, 0x1b, 0x04, 0x03, 0xc8, 0x09, 0x05, 0x03, 0x80, 0x36, 0x06, 0x04, 0x90, 0x36, 0x06, 0x04, 0xa0, 0x20, 0x07, 0x04, 0xe0, 0x0d, 0x08, 0x04, 0x80, 0x3e, 0x09, 0x05, 0x20, 0x11, 0x0b, 0x05, + 0x40, 0x13, 0x0e, 0x06, 0x00, 0x1e, 0x14, 0x08, 0xb0, 0x1c, 0x00, 0x03, 0xb8, 0x1c, 0x00, 0x03, 0x88, 0x16, 0x01, 0x02, 0x8c, 0x16, 0x01, 0x02, 0x90, 0x16, 0x01, 0x02, 0x94, 0x16, 0x01, 0x02, + 0xe4, 0x05, 0x02, 0x02, 0xe8, 0x05, 0x02, 0x02, 0xec, 0x05, 0x02, 0x02, 0xf0, 0x05, 0x02, 0x02, 0x28, 0x31, 0x03, 0x03, 0x30, 0x31, 0x03, 0x03, 0x60, 0x1b, 0x04, 0x03, 0x68, 0x1b, 0x04, 0x03, + 0x70, 0x1b, 0x04, 0x03, 0xd0, 0x09, 0x05, 0x03, 0xa0, 0x36, 0x06, 0x04, 0xb0, 0x36, 0x06, 0x04, 0xb0, 0x20, 0x07, 0x04, 0xf0, 0x0d, 0x08, 0x04, 0xa0, 0x3e, 0x09, 0x05, 0x40, 0x11, 0x0b, 0x05, + 0x80, 0x13, 0x0e, 0x06, 0x00, 0x1f, 0x14, 0x08, 0xc0, 0x1c, 0x00, 0x03, 0xc8, 0x1c, 0x00, 0x03, 0x98, 0x16, 0x01, 0x02, 0x9c, 0x16, 0x01, 0x02, 0xa0, 0x16, 0x01, 0x02, 0xa4, 0x16, 0x01, 0x02, + 0xf4, 0x05, 0x02, 0x02, 0xf8, 0x05, 0x02, 0x02, 0xfc, 0x05, 0x02, 0x02, 0x00, 0x06, 0x02, 0x02, 0x38, 0x31, 0x03, 0x03, 0x40, 0x31, 0x03, 0x03, 0x78, 0x1b, 0x04, 0x03, 0x80, 0x1b, 0x04, 0x03, + 0x88, 0x1b, 0x04, 0x03, 0xd8, 0x09, 0x05, 0x03, 0xc0, 0x36, 0x06, 0x04, 0xd0, 0x36, 0x06, 0x04, 0xc0, 0x20, 0x07, 0x04, 0x00, 0x0e, 0x08, 0x04, 0xc0, 0x3e, 0x09, 0x05, 0x60, 0x11, 0x0b, 0x05, + 0xc0, 0x13, 0x0e, 0x06, 0x00, 0x20, 0x14, 0x08, 0xd0, 0x1c, 0x00, 0x03, 0xd8, 0x1c, 0x00, 0x03, 0xa8, 0x16, 0x01, 0x02, 0xac, 0x16, 0x01, 0x02, 0xb0, 0x16, 0x01, 0x02, 0xb4, 0x16, 0x01, 0x02, + 0x04, 0x06, 0x02, 0x02, 0x08, 0x06, 0x02, 0x02, 0x0c, 0x06, 0x02, 0x02, 0x10, 0x06, 0x02, 0x02, 0x48, 0x31, 0x03, 0x03, 0x50, 0x31, 0x03, 0x03, 0x90, 0x1b, 0x04, 0x03, 0x98, 0x1b, 0x04, 0x03, + 0xa0, 0x1b, 0x04, 0x03, 0xe0, 0x09, 0x05, 0x03, 0xe0, 0x36, 0x06, 0x04, 0xf0, 0x36, 0x06, 0x04, 0xd0, 0x20, 0x07, 0x04, 0x10, 0x0e, 0x08, 0x04, 0xe0, 0x3e, 0x09, 0x05, 0x80, 0x11, 0x0b, 0x05, + 0x00, 0x14, 0x0e, 0x06, 0x00, 0x21, 0x14, 0x08, 0xe0, 0x1c, 0x00, 0x03, 0xe8, 0x1c, 0x00, 0x03, 0xb8, 0x16, 0x01, 0x02, 0xbc, 0x16, 0x01, 0x02, 0xc0, 0x16, 0x01, 0x02, 0xc4, 0x16, 0x01, 0x02, + 0x14, 0x06, 0x02, 0x02, 0x18, 0x06, 0x02, 0x02, 0x1c, 0x06, 0x02, 0x02, 0x20, 0x06, 0x02, 0x02, 0x58, 0x31, 0x03, 0x03, 0x60, 0x31, 0x03, 0x03, 0xa8, 0x1b, 0x04, 0x03, 0xb0, 0x1b, 0x04, 0x03, + 0xb8, 0x1b, 0x04, 0x03, 0xe8, 0x09, 0x05, 0x03, 0x00, 0x37, 0x06, 0x04, 0x10, 0x37, 0x06, 0x04, 0xe0, 0x20, 0x07, 0x04, 0x20, 0x0e, 0x08, 0x04, 0x00, 0x3f, 0x09, 0x05, 0xa0, 0x11, 0x0b, 0x05, + 0x40, 0x14, 0x0e, 0x06, 0x00, 0x0b, 0x15, 0x08, 0xf0, 0x1c, 0x00, 0x03, 0xf8, 0x1c, 0x00, 0x03, 0xc8, 0x16, 0x01, 0x02, 0xcc, 0x16, 0x01, 0x02, 0xd0, 0x16, 0x01, 0x02, 0xd4, 0x16, 0x01, 0x02, + 0x24, 0x06, 0x02, 0x02, 0x28, 0x06, 0x02, 0x02, 0x2c, 0x06, 0x02, 0x02, 0x30, 0x06, 0x02, 0x02, 0x68, 0x31, 0x03, 0x03, 0x70, 0x31, 0x03, 0x03, 0xc0, 0x1b, 0x04, 0x03, 0xc8, 0x1b, 0x04, 0x03, + 0xf0, 0x09, 0x05, 0x03, 0xf8, 0x09, 0x05, 0x03, 0x20, 0x37, 0x06, 0x04, 0x30, 0x37, 0x06, 0x04, 0xf0, 0x20, 0x07, 0x04, 0x30, 0x0e, 0x08, 0x04, 0x20, 0x3f, 0x09, 0x05, 0xc0, 0x11, 0x0b, 0x05, + 0x80, 0x14, 0x0e, 0x06, 0x00, 0x0c, 0x15, 0x08, 0x00, 0x1d, 0x00, 0x03, 0x08, 0x1d, 0x00, 0x03, 0xd8, 0x16, 0x01, 0x02, 0xdc, 0x16, 0x01, 0x02, 0xe0, 0x16, 0x01, 0x02, 0xe4, 0x16, 0x01, 0x02, + 0x34, 0x06, 0x02, 0x02, 0x38, 0x06, 0x02, 0x02, 0x3c, 0x06, 0x02, 0x02, 0x40, 0x06, 0x02, 0x02, 0x78, 0x31, 0x03, 0x03, 0x80, 0x31, 0x03, 0x03, 0xd0, 0x1b, 0x04, 0x03, 0xd8, 0x1b, 0x04, 0x03, + 0x00, 0x0a, 0x05, 0x03, 0x08, 0x0a, 0x05, 0x03, 0x40, 0x37, 0x06, 0x04, 0x50, 0x37, 0x06, 0x04, 0x00, 0x21, 0x07, 0x04, 0x40, 0x0e, 0x08, 0x04, 0x40, 0x3f, 0x09, 0x05, 0xe0, 0x11, 0x0b, 0x05, + 0xc0, 0x14, 0x0e, 0x06, 0x00, 0x0d, 0x15, 0x08, 0x10, 0x1d, 0x00, 0x03, 0x18, 0x1d, 0x00, 0x03, 0xe8, 0x16, 0x01, 0x02, 0xec, 0x16, 0x01, 0x02, 0xf0, 0x16, 0x01, 0x02, 0xf4, 0x16, 0x01, 0x02, + 0x44, 0x06, 0x02, 0x02, 0x48, 0x06, 0x02, 0x02, 0x4c, 0x06, 0x02, 0x02, 0x50, 0x06, 0x02, 0x02, 0x88, 0x31, 0x03, 0x03, 0x90, 0x31, 0x03, 0x03, 0xe0, 0x1b, 0x04, 0x03, 0xe8, 0x1b, 0x04, 0x03, + 0x10, 0x0a, 0x05, 0x03, 0x18, 0x0a, 0x05, 0x03, 0x60, 0x37, 0x06, 0x04, 0x70, 0x37, 0x06, 0x04, 0x10, 0x21, 0x07, 0x04, 0x50, 0x0e, 0x08, 0x04, 0x60, 0x3f, 0x09, 0x05, 0x00, 0x12, 0x0b, 0x05, + 0x00, 0x15, 0x0e, 0x06, 0x00, 0x0e, 0x15, 0x08, 0x20, 0x1d, 0x00, 0x03, 0x28, 0x1d, 0x00, 0x03, 0xf8, 0x16, 0x01, 0x02, 0xfc, 0x16, 0x01, 0x02, 0x00, 0x17, 0x01, 0x02, 0x04, 0x17, 0x01, 0x02, + 0x54, 0x06, 0x02, 0x02, 0x58, 0x06, 0x02, 0x02, 0x5c, 0x06, 0x02, 0x02, 0x60, 0x06, 0x02, 0x02, 0x98, 0x31, 0x03, 0x03, 0xa0, 0x31, 0x03, 0x03, 0xf0, 0x1b, 0x04, 0x03, 0xf8, 0x1b, 0x04, 0x03, + 0x20, 0x0a, 0x05, 0x03, 0x28, 0x0a, 0x05, 0x03, 0x80, 0x37, 0x06, 0x04, 0x90, 0x37, 0x06, 0x04, 0x20, 0x21, 0x07, 0x04, 0x60, 0x0e, 0x08, 0x04, 0x80, 0x3f, 0x09, 0x05, 0x20, 0x12, 0x0b, 0x05, + 0x40, 0x15, 0x0e, 0x06, 0x00, 0x0f, 0x15, 0x08, 0x30, 0x1d, 0x00, 0x03, 0x38, 0x1d, 0x00, 0x03, 0x08, 0x17, 0x01, 0x02, 0x0c, 0x17, 0x01, 0x02, 0x10, 0x17, 0x01, 0x02, 0x14, 0x17, 0x01, 0x02, + 0x64, 0x06, 0x02, 0x02, 0x68, 0x06, 0x02, 0x02, 0x6c, 0x06, 0x02, 0x02, 0x70, 0x06, 0x02, 0x02, 0xa8, 0x31, 0x03, 0x03, 0xb0, 0x31, 0x03, 0x03, 0x00, 0x1c, 0x04, 0x03, 0x08, 0x1c, 0x04, 0x03, + 0x30, 0x0a, 0x05, 0x03, 0x38, 0x0a, 0x05, 0x03, 0xa0, 0x37, 0x06, 0x04, 0xb0, 0x37, 0x06, 0x04, 0x30, 0x21, 0x07, 0x04, 0x70, 0x0e, 0x08, 0x04, 0xa0, 0x3f, 0x09, 0x05, 0x40, 0x12, 0x0b, 0x05, + 0x80, 0x15, 0x0e, 0x06, 0x00, 0x38, 0x16, 0x09, 0x40, 0x1d, 0x00, 0x03, 0x48, 0x1d, 0x00, 0x03, 0x18, 0x17, 0x01, 0x02, 0x1c, 0x17, 0x01, 0x02, 0x20, 0x17, 0x01, 0x02, 0x24, 0x17, 0x01, 0x02, + 0x74, 0x06, 0x02, 0x02, 0x78, 0x06, 0x02, 0x02, 0x7c, 0x06, 0x02, 0x02, 0x80, 0x06, 0x02, 0x02, 0xb8, 0x31, 0x03, 0x03, 0xc0, 0x31, 0x03, 0x03, 0x10, 0x1c, 0x04, 0x03, 0x18, 0x1c, 0x04, 0x03, + 0x40, 0x0a, 0x05, 0x03, 0x48, 0x0a, 0x05, 0x03, 0xc0, 0x37, 0x06, 0x04, 0xd0, 0x37, 0x06, 0x04, 0x40, 0x21, 0x07, 0x04, 0x80, 0x0e, 0x08, 0x04, 0xc0, 0x3f, 0x09, 0x05, 0x60, 0x12, 0x0b, 0x05, + 0xc0, 0x15, 0x0e, 0x06, 0x00, 0x3a, 0x16, 0x09, 0x50, 0x1d, 0x00, 0x03, 0x58, 0x1d, 0x00, 0x03, 0x28, 0x17, 0x01, 0x02, 0x2c, 0x17, 0x01, 0x02, 0x30, 0x17, 0x01, 0x02, 0x34, 0x17, 0x01, 0x02, + 0x84, 0x06, 0x02, 0x02, 0x88, 0x06, 0x02, 0x02, 0x8c, 0x06, 0x02, 0x02, 0xc8, 0x31, 0x03, 0x03, 0xd0, 0x31, 0x03, 0x03, 0xd8, 0x31, 0x03, 0x03, 0x20, 0x1c, 0x04, 0x03, 0x28, 0x1c, 0x04, 0x03, + 0x50, 0x0a, 0x05, 0x03, 0x58, 0x0a, 0x05, 0x03, 0xe0, 0x37, 0x06, 0x04, 0xf0, 0x37, 0x06, 0x04, 0x50, 0x21, 0x07, 0x04, 0x90, 0x0e, 0x08, 0x04, 0xe0, 0x3f, 0x09, 0x05, 0x80, 0x12, 0x0b, 0x05, + 0x00, 0x16, 0x0e, 0x06, 0x00, 0x3c, 0x16, 0x09, 0x60, 0x1d, 0x00, 0x03, 0x68, 0x1d, 0x00, 0x03, 0x38, 0x17, 0x01, 0x02, 0x3c, 0x17, 0x01, 0x02, 0x40, 0x17, 0x01, 0x02, 0x44, 0x17, 0x01, 0x02, + 0x90, 0x06, 0x02, 0x02, 0x94, 0x06, 0x02, 0x02, 0x98, 0x06, 0x02, 0x02, 0xe0, 0x31, 0x03, 0x03, 0xe8, 0x31, 0x03, 0x03, 0xf0, 0x31, 0x03, 0x03, 0x30, 0x1c, 0x04, 0x03, 0x38, 0x1c, 0x04, 0x03, + 0x60, 0x0a, 0x05, 0x03, 0x68, 0x0a, 0x05, 0x03, 0x00, 0x38, 0x06, 0x04, 0x10, 0x38, 0x06, 0x04, 0x60, 0x21, 0x07, 0x04, 0xa0, 0x0e, 0x08, 0x04, 0x40, 0x26, 0x0a, 0x05, 0xa0, 0x12, 0x0b, 0x05, + 0x40, 0x16, 0x0e, 0x06, 0x00, 0x3e, 0x16, 0x09, 0x70, 0x1d, 0x00, 0x03, 0x78, 0x1d, 0x00, 0x03, 0x48, 0x17, 0x01, 0x02, 0x4c, 0x17, 0x01, 0x02, 0x50, 0x17, 0x01, 0x02, 0x54, 0x17, 0x01, 0x02, + 0x9c, 0x06, 0x02, 0x02, 0xa0, 0x06, 0x02, 0x02, 0xa4, 0x06, 0x02, 0x02, 0xf8, 0x31, 0x03, 0x03, 0x00, 0x32, 0x03, 0x03, 0x08, 0x32, 0x03, 0x03, 0x40, 0x1c, 0x04, 0x03, 0x48, 0x1c, 0x04, 0x03, + 0x70, 0x0a, 0x05, 0x03, 0x78, 0x0a, 0x05, 0x03, 0x20, 0x38, 0x06, 0x04, 0x30, 0x38, 0x06, 0x04, 0x70, 0x21, 0x07, 0x04, 0xb0, 0x0e, 0x08, 0x04, 0x60, 0x26, 0x0a, 0x05, 0xc0, 0x12, 0x0b, 0x05, + 0x80, 0x16, 0x0e, 0x06, 0x00, 0x22, 0x17, 0x09, 0x80, 0x1d, 0x00, 0x03, 0x88, 0x1d, 0x00, 0x03, 0x58, 0x17, 0x01, 0x02, 0x5c, 0x17, 0x01, 0x02, 0x60, 0x17, 0x01, 0x02, 0x64, 0x17, 0x01, 0x02, + 0xa8, 0x06, 0x02, 0x02, 0xac, 0x06, 0x02, 0x02, 0xb0, 0x06, 0x02, 0x02, 0x10, 0x32, 0x03, 0x03, 0x18, 0x32, 0x03, 0x03, 0x20, 0x32, 0x03, 0x03, 0x50, 0x1c, 0x04, 0x03, 0x58, 0x1c, 0x04, 0x03, + 0x80, 0x0a, 0x05, 0x03, 0x88, 0x0a, 0x05, 0x03, 0x40, 0x38, 0x06, 0x04, 0x50, 0x38, 0x06, 0x04, 0x80, 0x21, 0x07, 0x04, 0xc0, 0x0e, 0x08, 0x04, 0x80, 0x26, 0x0a, 0x05, 0xe0, 0x12, 0x0b, 0x05, + 0xc0, 0x16, 0x0e, 0x06, 0x00, 0x24, 0x17, 0x09, 0x90, 0x1d, 0x00, 0x03, 0x98, 0x1d, 0x00, 0x03, 0x68, 0x17, 0x01, 0x02, 0x6c, 0x17, 0x01, 0x02, 0x70, 0x17, 0x01, 0x02, 0x74, 0x17, 0x01, 0x02, + 0xb4, 0x06, 0x02, 0x02, 0xb8, 0x06, 0x02, 0x02, 0xbc, 0x06, 0x02, 0x02, 0x28, 0x32, 0x03, 0x03, 0x30, 0x32, 0x03, 0x03, 0x38, 0x32, 0x03, 0x03, 0x60, 0x1c, 0x04, 0x03, 0x68, 0x1c, 0x04, 0x03, + 0x90, 0x0a, 0x05, 0x03, 0x98, 0x0a, 0x05, 0x03, 0x60, 0x38, 0x06, 0x04, 0x70, 0x38, 0x06, 0x04, 0x90, 0x21, 0x07, 0x04, 0xd0, 0x0e, 0x08, 0x04, 0xa0, 0x26, 0x0a, 0x05, 0x00, 0x13, 0x0b, 0x05, + 0x00, 0x17, 0x0e, 0x06, 0x00, 0x26, 0x17, 0x09, 0xa0, 0x1d, 0x00, 0x03, 0xa8, 0x1d, 0x00, 0x03, 0x78, 0x17, 0x01, 0x02, 0x7c, 0x17, 0x01, 0x02, 0x80, 0x17, 0x01, 0x02, 0x84, 0x17, 0x01, 0x02, + 0xc0, 0x06, 0x02, 0x02, 0xc4, 0x06, 0x02, 0x02, 0xc8, 0x06, 0x02, 0x02, 0x40, 0x32, 0x03, 0x03, 0x48, 0x32, 0x03, 0x03, 0x50, 0x32, 0x03, 0x03, 0x70, 0x1c, 0x04, 0x03, 0x78, 0x1c, 0x04, 0x03, + 0xa0, 0x0a, 0x05, 0x03, 0xa8, 0x0a, 0x05, 0x03, 0x80, 0x38, 0x06, 0x04, 0x90, 0x38, 0x06, 0x04, 0xa0, 0x21, 0x07, 0x04, 0xe0, 0x0e, 0x08, 0x04, 0xc0, 0x26, 0x0a, 0x05, 0x20, 0x13, 0x0b, 0x05, + 0x40, 0x17, 0x0e, 0x06, 0x00, 0x0e, 0x18, 0x09, 0xb0, 0x1d, 0x00, 0x03, 0xb8, 0x1d, 0x00, 0x03, 0x88, 0x17, 0x01, 0x02, 0x8c, 0x17, 0x01, 0x02, 0x90, 0x17, 0x01, 0x02, 0x94, 0x17, 0x01, 0x02, + 0xcc, 0x06, 0x02, 0x02, 0xd0, 0x06, 0x02, 0x02, 0xd4, 0x06, 0x02, 0x02, 0x58, 0x32, 0x03, 0x03, 0x60, 0x32, 0x03, 0x03, 0x68, 0x32, 0x03, 0x03, 0x80, 0x1c, 0x04, 0x03, 0x88, 0x1c, 0x04, 0x03, + 0xb0, 0x0a, 0x05, 0x03, 0xb8, 0x0a, 0x05, 0x03, 0xa0, 0x38, 0x06, 0x04, 0xb0, 0x38, 0x06, 0x04, 0xb0, 0x21, 0x07, 0x04, 0xf0, 0x0e, 0x08, 0x04, 0xe0, 0x26, 0x0a, 0x05, 0x40, 0x13, 0x0b, 0x05, + 0x80, 0x17, 0x0e, 0x06, 0x00, 0x10, 0x18, 0x09, 0xc0, 0x1d, 0x00, 0x03, 0xc8, 0x1d, 0x00, 0x03, 0x98, 0x17, 0x01, 0x02, 0x9c, 0x17, 0x01, 0x02, 0xa0, 0x17, 0x01, 0x02, 0xa4, 0x17, 0x01, 0x02, + 0xd8, 0x06, 0x02, 0x02, 0xdc, 0x06, 0x02, 0x02, 0xe0, 0x06, 0x02, 0x02, 0x70, 0x32, 0x03, 0x03, 0x78, 0x32, 0x03, 0x03, 0x80, 0x32, 0x03, 0x03, 0x90, 0x1c, 0x04, 0x03, 0x98, 0x1c, 0x04, 0x03, + 0xc0, 0x0a, 0x05, 0x03, 0xc8, 0x0a, 0x05, 0x03, 0xc0, 0x38, 0x06, 0x04, 0xd0, 0x38, 0x06, 0x04, 0xc0, 0x21, 0x07, 0x04, 0x00, 0x0f, 0x08, 0x04, 0x00, 0x27, 0x0a, 0x05, 0x60, 0x13, 0x0b, 0x05, + 0xc0, 0x17, 0x0e, 0x06, 0x00, 0x12, 0x18, 0x09, 0xd0, 0x1d, 0x00, 0x03, 0xd8, 0x1d, 0x00, 0x03, 0xa8, 0x17, 0x01, 0x02, 0xac, 0x17, 0x01, 0x02, 0xb0, 0x17, 0x01, 0x02, 0xb4, 0x17, 0x01, 0x02, + 0xe4, 0x06, 0x02, 0x02, 0xe8, 0x06, 0x02, 0x02, 0xec, 0x06, 0x02, 0x02, 0x88, 0x32, 0x03, 0x03, 0x90, 0x32, 0x03, 0x03, 0x98, 0x32, 0x03, 0x03, 0xa0, 0x1c, 0x04, 0x03, 0xa8, 0x1c, 0x04, 0x03, + 0xd0, 0x0a, 0x05, 0x03, 0xd8, 0x0a, 0x05, 0x03, 0xe0, 0x38, 0x06, 0x04, 0xf0, 0x38, 0x06, 0x04, 0xd0, 0x21, 0x07, 0x04, 0x10, 0x0f, 0x08, 0x04, 0x20, 0x27, 0x0a, 0x05, 0x80, 0x13, 0x0b, 0x05, + 0x00, 0x18, 0x0e, 0x06, 0x00, 0x00, 0x19, 0x09, 0xe0, 0x1d, 0x00, 0x03, 0xe8, 0x1d, 0x00, 0x03, 0xb8, 0x17, 0x01, 0x02, 0xbc, 0x17, 0x01, 0x02, 0xc0, 0x17, 0x01, 0x02, 0xc4, 0x17, 0x01, 0x02, + 0xf0, 0x06, 0x02, 0x02, 0xf4, 0x06, 0x02, 0x02, 0xf8, 0x06, 0x02, 0x02, 0xa0, 0x32, 0x03, 0x03, 0xa8, 0x32, 0x03, 0x03, 0xb0, 0x32, 0x03, 0x03, 0xb0, 0x1c, 0x04, 0x03, 0xb8, 0x1c, 0x04, 0x03, + 0xe0, 0x0a, 0x05, 0x03, 0xe8, 0x0a, 0x05, 0x03, 0x00, 0x39, 0x06, 0x04, 0x10, 0x39, 0x06, 0x04, 0xe0, 0x21, 0x07, 0x04, 0x20, 0x0f, 0x08, 0x04, 0x40, 0x27, 0x0a, 0x05, 0xa0, 0x13, 0x0b, 0x05, + 0x40, 0x18, 0x0e, 0x06, 0x00, 0x02, 0x19, 0x09, 0xf0, 0x1d, 0x00, 0x03, 0xf8, 0x1d, 0x00, 0x03, 0xc8, 0x17, 0x01, 0x02, 0xcc, 0x17, 0x01, 0x02, 0xd0, 0x17, 0x01, 0x02, 0xd4, 0x17, 0x01, 0x02, + 0xfc, 0x06, 0x02, 0x02, 0x00, 0x07, 0x02, 0x02, 0x04, 0x07, 0x02, 0x02, 0xb8, 0x32, 0x03, 0x03, 0xc0, 0x32, 0x03, 0x03, 0xc8, 0x32, 0x03, 0x03, 0xc0, 0x1c, 0x04, 0x03, 0xc8, 0x1c, 0x04, 0x03, + 0xf0, 0x0a, 0x05, 0x03, 0xf8, 0x0a, 0x05, 0x03, 0x20, 0x39, 0x06, 0x04, 0x30, 0x39, 0x06, 0x04, 0xf0, 0x21, 0x07, 0x04, 0x30, 0x0f, 0x08, 0x04, 0x60, 0x27, 0x0a, 0x05, 0x00, 0x00, 0xfe, 0x0e, + 0x00, 0x00, 0xfd, 0x0e, 0x00, 0x00, 0xfc, 0x0e, 0x00, 0x00, 0xfb, 0x0e, 0x00, 0x00, 0xfa, 0x0e, 0x00, 0x00, 0xf9, 0x0e, 0x00, 0x00, 0xf8, 0x0e, 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0xf6, 0x0e, + 0x00, 0x00, 0xf5, 0x0e, 0x00, 0x00, 0xf4, 0x0e, 0x00, 0x00, 0xf3, 0x0e, 0x00, 0x00, 0xf2, 0x0e, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0xef, 0x0e, 0x00, 0x00, 0xee, 0x0e, + 0x00, 0x00, 0xed, 0x0e, 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xeb, 0x0e, 0x00, 0x00, 0xea, 0x0e, 0x00, 0x00, 0xe9, 0x0e, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x00, 0xe7, 0x0e, 0x00, 0x00, 0xe6, 0x0e, + 0x00, 0x00, 0xe5, 0x0e, 0x00, 0x00, 0xe4, 0x0e, 0x00, 0x00, 0xe3, 0x0e, 0x00, 0x00, 0xe2, 0x0e, 0x00, 0x00, 0xe1, 0x0e, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0xdf, 0x0e, 0x00, 0x00, 0xde, 0x0e, + 0x00, 0x00, 0xdd, 0x0e, 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0xdb, 0x0e, 0x00, 0x00, 0xda, 0x0e, 0x00, 0x00, 0xd9, 0x0e, 0x00, 0x00, 0xd8, 0x0e, 0x00, 0x00, 0xd7, 0x0e, 0x00, 0x00, 0xd6, 0x0e, + 0x00, 0x00, 0xd5, 0x0e, 0x00, 0x00, 0xd4, 0x0e, 0x00, 0x00, 0xd3, 0x0e, 0x00, 0x00, 0xd2, 0x0e, 0x00, 0x00, 0xd1, 0x0e, 0x00, 0x00, 0xd0, 0x0e, 0x00, 0x00, 0xcf, 0x0e, 0x00, 0x00, 0xce, 0x0e, + 0x00, 0x00, 0xcd, 0x0e, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x00, 0xcb, 0x0e, 0x00, 0x00, 0xca, 0x0e, 0x00, 0x00, 0xc9, 0x0e, 0x00, 0x00, 0xc8, 0x0e, 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0xc6, 0x0e, + 0x00, 0x00, 0xc5, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc3, 0x0e, 0x00, 0x00, 0xc2, 0x0e, 0x00, 0x00, 0xc1, 0x0e, 0x00, 0x00, 0xc0, 0x0e, 0x00, 0x00, 0xbf, 0x0e, 0x00, 0x00, 0xbe, 0x0e, + 0x00, 0x00, 0xbd, 0x0e, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x00, 0xbb, 0x0e, 0x00, 0x00, 0xba, 0x0e, 0x00, 0x00, 0xb9, 0x0e, 0x00, 0x00, 0xb8, 0x0e, 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x00, 0xb6, 0x0e, + 0x00, 0x00, 0xb5, 0x0e, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x00, 0xb3, 0x0e, 0x00, 0x00, 0xb2, 0x0e, 0x00, 0x00, 0xb1, 0x0e, 0x00, 0x00, 0xb0, 0x0e, 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0xae, 0x0e, + 0x00, 0x00, 0xad, 0x0e, 0x00, 0x00, 0xac, 0x0e, 0x00, 0x00, 0xab, 0x0e, 0x00, 0x00, 0xaa, 0x0e, 0x00, 0x00, 0xa9, 0x0e, 0x00, 0x00, 0xa8, 0x0e, 0x00, 0x00, 0xa7, 0x0e, 0x00, 0x00, 0xa6, 0x0e, + 0x00, 0x00, 0xa5, 0x0e, 0x00, 0x00, 0xa4, 0x0e, 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0xa2, 0x0e, 0x00, 0x00, 0xa1, 0x0e, 0x00, 0x00, 0xa0, 0x0e, 0x00, 0x00, 0x9f, 0x0e, 0x00, 0x00, 0x9e, 0x0e, + 0x00, 0x00, 0x9d, 0x0e, 0x00, 0x00, 0x9c, 0x0e, 0x00, 0x00, 0x9b, 0x0e, 0x00, 0x00, 0x9a, 0x0e, 0x00, 0x00, 0x99, 0x0e, 0x00, 0x00, 0x98, 0x0e, 0x00, 0x00, 0x97, 0x0e, 0x00, 0x00, 0x96, 0x0e, + 0x00, 0x00, 0x95, 0x0e, 0x00, 0x00, 0x94, 0x0e, 0x00, 0x00, 0x93, 0x0e, 0x00, 0x00, 0x92, 0x0e, 0x00, 0x00, 0x91, 0x0e, 0x00, 0x00, 0x90, 0x0e, 0x00, 0x00, 0x8f, 0x0e, 0x00, 0x00, 0x8e, 0x0e, + 0x00, 0x00, 0x8d, 0x0e, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x00, 0x8b, 0x0e, 0x00, 0x00, 0x8a, 0x0e, 0x00, 0x00, 0x89, 0x0e, 0x00, 0x00, 0x88, 0x0e, 0x00, 0x00, 0x87, 0x0e, 0x00, 0x00, 0x86, 0x0e, + 0x00, 0x00, 0x85, 0x0e, 0x00, 0x00, 0x84, 0x0e, 0x00, 0x00, 0x83, 0x0e, 0x00, 0x00, 0x82, 0x0e, 0x00, 0x00, 0x81, 0x0e, 0x00, 0x00, 0x80, 0x0e, 0x00, 0x00, 0x7f, 0x0e, 0x00, 0x00, 0x7e, 0x0e, + 0x00, 0x00, 0x7d, 0x0e, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x00, 0x7b, 0x0e, 0x00, 0x00, 0x7a, 0x0e, 0x00, 0x00, 0x79, 0x0e, 0x00, 0x00, 0x78, 0x0e, 0x00, 0x00, 0x77, 0x0e, 0x00, 0x00, 0x76, 0x0e, + 0x00, 0x00, 0x75, 0x0e, 0x00, 0x00, 0x74, 0x0e, 0x00, 0x00, 0x73, 0x0e, 0x00, 0x00, 0x72, 0x0e, 0x00, 0x00, 0x71, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x6f, 0x0e, 0x00, 0x00, 0x6e, 0x0e, + 0x00, 0x00, 0x6d, 0x0e, 0x00, 0x00, 0x6c, 0x0e, 0x00, 0x00, 0x6b, 0x0e, 0x00, 0x00, 0x6a, 0x0e, 0x00, 0x00, 0x69, 0x0e, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x00, 0x67, 0x0e, 0x00, 0x00, 0x66, 0x0e, + 0x00, 0x00, 0x65, 0x0e, 0x00, 0x00, 0x64, 0x0e, 0x00, 0x00, 0x63, 0x0e, 0x00, 0x00, 0x62, 0x0e, 0x00, 0x00, 0x61, 0x0e, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x00, 0x5f, 0x0e, 0x00, 0x00, 0x5e, 0x0e, + 0x00, 0x00, 0x5d, 0x0e, 0x00, 0x00, 0x5c, 0x0e, 0x00, 0x00, 0x5b, 0x0e, 0x00, 0x00, 0x5a, 0x0e, 0x00, 0x00, 0x59, 0x0e, 0x00, 0x00, 0x58, 0x0e, 0x00, 0x00, 0x57, 0x0e, 0x00, 0x00, 0x56, 0x0e, + 0x00, 0x00, 0x55, 0x0e, 0x00, 0x00, 0x54, 0x0e, 0x00, 0x00, 0x53, 0x0e, 0x00, 0x00, 0x52, 0x0e, 0x00, 0x00, 0x51, 0x0e, 0x00, 0x00, 0x50, 0x0e, 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x4e, 0x0e, + 0x00, 0x00, 0x4d, 0x0e, 0x00, 0x00, 0x4c, 0x0e, 0x00, 0x00, 0x4b, 0x0e, 0x00, 0x00, 0x4a, 0x0e, 0x00, 0x00, 0x49, 0x0e, 0x00, 0x00, 0x48, 0x0e, 0x00, 0x00, 0x47, 0x0e, 0x00, 0x00, 0x46, 0x0e, + 0x00, 0x00, 0x45, 0x0e, 0x00, 0x00, 0x44, 0x0e, 0x00, 0x00, 0x43, 0x0e, 0x00, 0x00, 0x42, 0x0e, 0x00, 0x00, 0x41, 0x0e, 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x3f, 0x0e, 0x00, 0x00, 0x3e, 0x0e, + 0x00, 0x00, 0x3d, 0x0e, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x3a, 0x0e, 0x00, 0x00, 0x39, 0x0e, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 0x37, 0x0e, 0x00, 0x00, 0x36, 0x0e, + 0x00, 0x00, 0x35, 0x0e, 0x00, 0x00, 0x34, 0x0e, 0x00, 0x00, 0x33, 0x0e, 0x00, 0x00, 0x32, 0x0e, 0x00, 0x00, 0x31, 0x0e, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x2e, 0x0e, + 0x00, 0x00, 0x2d, 0x0e, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00, 0x2b, 0x0e, 0x00, 0x00, 0x2a, 0x0e, 0x00, 0x00, 0x29, 0x0e, 0x00, 0x00, 0x28, 0x0e, 0x00, 0x00, 0x27, 0x0e, 0x00, 0x00, 0x26, 0x0e, + 0x00, 0x00, 0x25, 0x0e +}; + +const byte DTable_1[65540] = { + 0x0e, 0x00, 0x01, 0x00, 0x90, 0x0d, 0x00, 0x03, 0x98, 0x0d, 0x00, 0x03, 0xa0, 0x0d, 0x00, 0x03, 0xa8, 0x0d, 0x00, 0x03, 0x24, 0x01, 0x01, 0x02, 0x28, 0x01, 0x01, 0x02, 0x2c, 0x01, 0x01, 0x02, + 0x30, 0x01, 0x01, 0x02, 0x34, 0x01, 0x01, 0x02, 0x38, 0x01, 0x01, 0x02, 0x90, 0x1a, 0x02, 0x03, 0x98, 0x1a, 0x02, 0x03, 0xa0, 0x1a, 0x02, 0x03, 0xa8, 0x1a, 0x02, 0x03, 0xb0, 0x1a, 0x02, 0x03, + 0xf0, 0x3d, 0x03, 0x04, 0x00, 0x3e, 0x03, 0x04, 0x10, 0x3e, 0x03, 0x04, 0x80, 0x17, 0x04, 0x04, 0x90, 0x17, 0x04, 0x04, 0xa0, 0x39, 0x05, 0x05, 0xa0, 0x14, 0x06, 0x05, 0x80, 0x35, 0x07, 0x06, + 0x80, 0x31, 0x09, 0x07, 0xb0, 0x0d, 0x00, 0x03, 0xb8, 0x0d, 0x00, 0x03, 0xc0, 0x0d, 0x00, 0x03, 0xc8, 0x0d, 0x00, 0x03, 0x3c, 0x01, 0x01, 0x02, 0x40, 0x01, 0x01, 0x02, 0x44, 0x01, 0x01, 0x02, + 0x48, 0x01, 0x01, 0x02, 0x4c, 0x01, 0x01, 0x02, 0x50, 0x01, 0x01, 0x02, 0xb8, 0x1a, 0x02, 0x03, 0xc0, 0x1a, 0x02, 0x03, 0xc8, 0x1a, 0x02, 0x03, 0xd0, 0x1a, 0x02, 0x03, 0xd8, 0x1a, 0x02, 0x03, + 0x20, 0x3e, 0x03, 0x04, 0x30, 0x3e, 0x03, 0x04, 0x40, 0x3e, 0x03, 0x04, 0xa0, 0x17, 0x04, 0x04, 0xb0, 0x17, 0x04, 0x04, 0xc0, 0x39, 0x05, 0x05, 0xc0, 0x14, 0x06, 0x05, 0xc0, 0x35, 0x07, 0x06, + 0x00, 0x32, 0x09, 0x07, 0xd0, 0x0d, 0x00, 0x03, 0xd8, 0x0d, 0x00, 0x03, 0xe0, 0x0d, 0x00, 0x03, 0xe8, 0x0d, 0x00, 0x03, 0x54, 0x01, 0x01, 0x02, 0x58, 0x01, 0x01, 0x02, 0x5c, 0x01, 0x01, 0x02, + 0x60, 0x01, 0x01, 0x02, 0x64, 0x01, 0x01, 0x02, 0x68, 0x01, 0x01, 0x02, 0xe0, 0x1a, 0x02, 0x03, 0xe8, 0x1a, 0x02, 0x03, 0xf0, 0x1a, 0x02, 0x03, 0xf8, 0x1a, 0x02, 0x03, 0x00, 0x1b, 0x02, 0x03, + 0x50, 0x3e, 0x03, 0x04, 0x60, 0x3e, 0x03, 0x04, 0x70, 0x3e, 0x03, 0x04, 0xc0, 0x17, 0x04, 0x04, 0xd0, 0x17, 0x04, 0x04, 0xe0, 0x39, 0x05, 0x05, 0xe0, 0x14, 0x06, 0x05, 0x00, 0x36, 0x07, 0x06, + 0x80, 0x32, 0x09, 0x07, 0xf0, 0x0d, 0x00, 0x03, 0xf8, 0x0d, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x03, 0x08, 0x0e, 0x00, 0x03, 0x6c, 0x01, 0x01, 0x02, 0x70, 0x01, 0x01, 0x02, 0x74, 0x01, 0x01, 0x02, + 0x78, 0x01, 0x01, 0x02, 0x7c, 0x01, 0x01, 0x02, 0x80, 0x01, 0x01, 0x02, 0x08, 0x1b, 0x02, 0x03, 0x10, 0x1b, 0x02, 0x03, 0x18, 0x1b, 0x02, 0x03, 0x20, 0x1b, 0x02, 0x03, 0x28, 0x1b, 0x02, 0x03, + 0x80, 0x3e, 0x03, 0x04, 0x90, 0x3e, 0x03, 0x04, 0xa0, 0x3e, 0x03, 0x04, 0xe0, 0x17, 0x04, 0x04, 0xf0, 0x17, 0x04, 0x04, 0x00, 0x3a, 0x05, 0x05, 0x00, 0x15, 0x06, 0x05, 0x40, 0x36, 0x07, 0x06, + 0x00, 0x33, 0x09, 0x07, 0x10, 0x0e, 0x00, 0x03, 0x18, 0x0e, 0x00, 0x03, 0x20, 0x0e, 0x00, 0x03, 0x28, 0x0e, 0x00, 0x03, 0x84, 0x01, 0x01, 0x02, 0x88, 0x01, 0x01, 0x02, 0x8c, 0x01, 0x01, 0x02, + 0x90, 0x01, 0x01, 0x02, 0x94, 0x01, 0x01, 0x02, 0x98, 0x01, 0x01, 0x02, 0x30, 0x1b, 0x02, 0x03, 0x38, 0x1b, 0x02, 0x03, 0x40, 0x1b, 0x02, 0x03, 0x48, 0x1b, 0x02, 0x03, 0x50, 0x1b, 0x02, 0x03, + 0xb0, 0x3e, 0x03, 0x04, 0xc0, 0x3e, 0x03, 0x04, 0xd0, 0x3e, 0x03, 0x04, 0x00, 0x18, 0x04, 0x04, 0x10, 0x18, 0x04, 0x04, 0x20, 0x3a, 0x05, 0x05, 0x20, 0x15, 0x06, 0x05, 0x80, 0x36, 0x07, 0x06, + 0x80, 0x33, 0x09, 0x07, 0x30, 0x0e, 0x00, 0x03, 0x38, 0x0e, 0x00, 0x03, 0x40, 0x0e, 0x00, 0x03, 0x48, 0x0e, 0x00, 0x03, 0x9c, 0x01, 0x01, 0x02, 0xa0, 0x01, 0x01, 0x02, 0xa4, 0x01, 0x01, 0x02, + 0xa8, 0x01, 0x01, 0x02, 0xac, 0x01, 0x01, 0x02, 0xb0, 0x01, 0x01, 0x02, 0x58, 0x1b, 0x02, 0x03, 0x60, 0x1b, 0x02, 0x03, 0x68, 0x1b, 0x02, 0x03, 0x70, 0x1b, 0x02, 0x03, 0x78, 0x1b, 0x02, 0x03, + 0xe0, 0x3e, 0x03, 0x04, 0xf0, 0x3e, 0x03, 0x04, 0x00, 0x3f, 0x03, 0x04, 0x20, 0x18, 0x04, 0x04, 0x30, 0x18, 0x04, 0x04, 0x40, 0x3a, 0x05, 0x05, 0x40, 0x15, 0x06, 0x05, 0xc0, 0x36, 0x07, 0x06, + 0x00, 0x34, 0x09, 0x07, 0x50, 0x0e, 0x00, 0x03, 0x58, 0x0e, 0x00, 0x03, 0x60, 0x0e, 0x00, 0x03, 0x68, 0x0e, 0x00, 0x03, 0xb4, 0x01, 0x01, 0x02, 0xb8, 0x01, 0x01, 0x02, 0xbc, 0x01, 0x01, 0x02, + 0xc0, 0x01, 0x01, 0x02, 0xc4, 0x01, 0x01, 0x02, 0xc8, 0x01, 0x01, 0x02, 0x80, 0x1b, 0x02, 0x03, 0x88, 0x1b, 0x02, 0x03, 0x90, 0x1b, 0x02, 0x03, 0x98, 0x1b, 0x02, 0x03, 0xa0, 0x1b, 0x02, 0x03, + 0x10, 0x3f, 0x03, 0x04, 0x20, 0x3f, 0x03, 0x04, 0x30, 0x3f, 0x03, 0x04, 0x40, 0x18, 0x04, 0x04, 0x50, 0x18, 0x04, 0x04, 0x60, 0x3a, 0x05, 0x05, 0x60, 0x15, 0x06, 0x05, 0x00, 0x37, 0x07, 0x06, + 0x80, 0x34, 0x09, 0x07, 0x70, 0x0e, 0x00, 0x03, 0x78, 0x0e, 0x00, 0x03, 0x80, 0x0e, 0x00, 0x03, 0x88, 0x0e, 0x00, 0x03, 0xcc, 0x01, 0x01, 0x02, 0xd0, 0x01, 0x01, 0x02, 0xd4, 0x01, 0x01, 0x02, + 0xd8, 0x01, 0x01, 0x02, 0xdc, 0x01, 0x01, 0x02, 0xe0, 0x01, 0x01, 0x02, 0xa8, 0x1b, 0x02, 0x03, 0xb0, 0x1b, 0x02, 0x03, 0xb8, 0x1b, 0x02, 0x03, 0xc0, 0x1b, 0x02, 0x03, 0xc8, 0x1b, 0x02, 0x03, + 0x40, 0x3f, 0x03, 0x04, 0x50, 0x3f, 0x03, 0x04, 0x60, 0x3f, 0x03, 0x04, 0x60, 0x18, 0x04, 0x04, 0x70, 0x18, 0x04, 0x04, 0x80, 0x3a, 0x05, 0x05, 0x80, 0x15, 0x06, 0x05, 0x40, 0x37, 0x07, 0x06, + 0x00, 0x35, 0x09, 0x07, 0x90, 0x0e, 0x00, 0x03, 0x98, 0x0e, 0x00, 0x03, 0xa0, 0x0e, 0x00, 0x03, 0xa8, 0x0e, 0x00, 0x03, 0xe4, 0x01, 0x01, 0x02, 0xe8, 0x01, 0x01, 0x02, 0xec, 0x01, 0x01, 0x02, + 0xf0, 0x01, 0x01, 0x02, 0xf4, 0x01, 0x01, 0x02, 0xf8, 0x01, 0x01, 0x02, 0xd0, 0x1b, 0x02, 0x03, 0xd8, 0x1b, 0x02, 0x03, 0xe0, 0x1b, 0x02, 0x03, 0xe8, 0x1b, 0x02, 0x03, 0xf0, 0x1b, 0x02, 0x03, + 0x70, 0x3f, 0x03, 0x04, 0x80, 0x3f, 0x03, 0x04, 0x90, 0x3f, 0x03, 0x04, 0x80, 0x18, 0x04, 0x04, 0x90, 0x18, 0x04, 0x04, 0xa0, 0x3a, 0x05, 0x05, 0xa0, 0x15, 0x06, 0x05, 0x80, 0x37, 0x07, 0x06, + 0x80, 0x35, 0x09, 0x07, 0xb0, 0x0e, 0x00, 0x03, 0xb8, 0x0e, 0x00, 0x03, 0xc0, 0x0e, 0x00, 0x03, 0xc8, 0x0e, 0x00, 0x03, 0xfc, 0x01, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02, + 0x08, 0x02, 0x01, 0x02, 0x0c, 0x02, 0x01, 0x02, 0x10, 0x02, 0x01, 0x02, 0xf8, 0x1b, 0x02, 0x03, 0x00, 0x1c, 0x02, 0x03, 0x08, 0x1c, 0x02, 0x03, 0x10, 0x1c, 0x02, 0x03, 0x18, 0x1c, 0x02, 0x03, + 0xa0, 0x3f, 0x03, 0x04, 0xb0, 0x3f, 0x03, 0x04, 0xc0, 0x3f, 0x03, 0x04, 0xa0, 0x18, 0x04, 0x04, 0xb0, 0x18, 0x04, 0x04, 0xc0, 0x3a, 0x05, 0x05, 0xc0, 0x15, 0x06, 0x05, 0xc0, 0x37, 0x07, 0x06, + 0x00, 0x36, 0x09, 0x07, 0xd0, 0x0e, 0x00, 0x03, 0xd8, 0x0e, 0x00, 0x03, 0xe0, 0x0e, 0x00, 0x03, 0xe8, 0x0e, 0x00, 0x03, 0x14, 0x02, 0x01, 0x02, 0x18, 0x02, 0x01, 0x02, 0x1c, 0x02, 0x01, 0x02, + 0x20, 0x02, 0x01, 0x02, 0x24, 0x02, 0x01, 0x02, 0x28, 0x02, 0x01, 0x02, 0x20, 0x1c, 0x02, 0x03, 0x28, 0x1c, 0x02, 0x03, 0x30, 0x1c, 0x02, 0x03, 0x38, 0x1c, 0x02, 0x03, 0x40, 0x1c, 0x02, 0x03, + 0xd0, 0x3f, 0x03, 0x04, 0xe0, 0x3f, 0x03, 0x04, 0xf0, 0x3f, 0x03, 0x04, 0xc0, 0x18, 0x04, 0x04, 0xd0, 0x18, 0x04, 0x04, 0xe0, 0x3a, 0x05, 0x05, 0xe0, 0x15, 0x06, 0x05, 0x00, 0x38, 0x07, 0x06, + 0x80, 0x36, 0x09, 0x07, 0xf0, 0x0e, 0x00, 0x03, 0xf8, 0x0e, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x08, 0x0f, 0x00, 0x03, 0x2c, 0x02, 0x01, 0x02, 0x30, 0x02, 0x01, 0x02, 0x34, 0x02, 0x01, 0x02, + 0x38, 0x02, 0x01, 0x02, 0x3c, 0x02, 0x01, 0x02, 0x40, 0x02, 0x01, 0x02, 0x48, 0x1c, 0x02, 0x03, 0x50, 0x1c, 0x02, 0x03, 0x58, 0x1c, 0x02, 0x03, 0x60, 0x1c, 0x02, 0x03, 0x68, 0x1c, 0x02, 0x03, + 0x00, 0x00, 0x03, 0x03, 0x08, 0x00, 0x03, 0x03, 0x10, 0x00, 0x03, 0x03, 0xe0, 0x18, 0x04, 0x04, 0xf0, 0x18, 0x04, 0x04, 0x00, 0x3b, 0x05, 0x05, 0x00, 0x16, 0x06, 0x05, 0x40, 0x38, 0x07, 0x06, + 0x00, 0x37, 0x09, 0x07, 0x10, 0x0f, 0x00, 0x03, 0x18, 0x0f, 0x00, 0x03, 0x20, 0x0f, 0x00, 0x03, 0x28, 0x0f, 0x00, 0x03, 0x44, 0x02, 0x01, 0x02, 0x48, 0x02, 0x01, 0x02, 0x4c, 0x02, 0x01, 0x02, + 0x50, 0x02, 0x01, 0x02, 0x54, 0x02, 0x01, 0x02, 0x58, 0x02, 0x01, 0x02, 0x70, 0x1c, 0x02, 0x03, 0x78, 0x1c, 0x02, 0x03, 0x80, 0x1c, 0x02, 0x03, 0x88, 0x1c, 0x02, 0x03, 0x90, 0x1c, 0x02, 0x03, + 0x18, 0x00, 0x03, 0x03, 0x20, 0x00, 0x03, 0x03, 0x28, 0x00, 0x03, 0x03, 0x00, 0x19, 0x04, 0x04, 0x10, 0x19, 0x04, 0x04, 0x20, 0x3b, 0x05, 0x05, 0x20, 0x16, 0x06, 0x05, 0x80, 0x38, 0x07, 0x06, + 0x80, 0x37, 0x09, 0x07, 0x30, 0x0f, 0x00, 0x03, 0x38, 0x0f, 0x00, 0x03, 0x40, 0x0f, 0x00, 0x03, 0x48, 0x0f, 0x00, 0x03, 0x5c, 0x02, 0x01, 0x02, 0x60, 0x02, 0x01, 0x02, 0x64, 0x02, 0x01, 0x02, + 0x68, 0x02, 0x01, 0x02, 0x6c, 0x02, 0x01, 0x02, 0x70, 0x02, 0x01, 0x02, 0x98, 0x1c, 0x02, 0x03, 0xa0, 0x1c, 0x02, 0x03, 0xa8, 0x1c, 0x02, 0x03, 0xb0, 0x1c, 0x02, 0x03, 0xb8, 0x1c, 0x02, 0x03, + 0x30, 0x00, 0x03, 0x03, 0x38, 0x00, 0x03, 0x03, 0x40, 0x00, 0x03, 0x03, 0x20, 0x19, 0x04, 0x04, 0x30, 0x19, 0x04, 0x04, 0x40, 0x3b, 0x05, 0x05, 0x40, 0x16, 0x06, 0x05, 0xc0, 0x38, 0x07, 0x06, + 0x00, 0x38, 0x09, 0x07, 0x50, 0x0f, 0x00, 0x03, 0x58, 0x0f, 0x00, 0x03, 0x60, 0x0f, 0x00, 0x03, 0x68, 0x0f, 0x00, 0x03, 0x74, 0x02, 0x01, 0x02, 0x78, 0x02, 0x01, 0x02, 0x7c, 0x02, 0x01, 0x02, + 0x80, 0x02, 0x01, 0x02, 0x84, 0x02, 0x01, 0x02, 0x88, 0x02, 0x01, 0x02, 0xc0, 0x1c, 0x02, 0x03, 0xc8, 0x1c, 0x02, 0x03, 0xd0, 0x1c, 0x02, 0x03, 0xd8, 0x1c, 0x02, 0x03, 0xe0, 0x1c, 0x02, 0x03, + 0x48, 0x00, 0x03, 0x03, 0x50, 0x00, 0x03, 0x03, 0x58, 0x00, 0x03, 0x03, 0x40, 0x19, 0x04, 0x04, 0x50, 0x19, 0x04, 0x04, 0x60, 0x3b, 0x05, 0x05, 0x60, 0x16, 0x06, 0x05, 0x00, 0x39, 0x07, 0x06, + 0x80, 0x38, 0x09, 0x07, 0x70, 0x0f, 0x00, 0x03, 0x78, 0x0f, 0x00, 0x03, 0x80, 0x0f, 0x00, 0x03, 0x88, 0x0f, 0x00, 0x03, 0x8c, 0x02, 0x01, 0x02, 0x90, 0x02, 0x01, 0x02, 0x94, 0x02, 0x01, 0x02, + 0x98, 0x02, 0x01, 0x02, 0x9c, 0x02, 0x01, 0x02, 0xa0, 0x02, 0x01, 0x02, 0xe8, 0x1c, 0x02, 0x03, 0xf0, 0x1c, 0x02, 0x03, 0xf8, 0x1c, 0x02, 0x03, 0x00, 0x1d, 0x02, 0x03, 0x60, 0x00, 0x03, 0x03, + 0x68, 0x00, 0x03, 0x03, 0x70, 0x00, 0x03, 0x03, 0x60, 0x19, 0x04, 0x04, 0x70, 0x19, 0x04, 0x04, 0x80, 0x19, 0x04, 0x04, 0x80, 0x3b, 0x05, 0x05, 0x80, 0x16, 0x06, 0x05, 0x40, 0x39, 0x07, 0x06, + 0x00, 0x39, 0x09, 0x07, 0x90, 0x0f, 0x00, 0x03, 0x98, 0x0f, 0x00, 0x03, 0xa0, 0x0f, 0x00, 0x03, 0xa8, 0x0f, 0x00, 0x03, 0xa4, 0x02, 0x01, 0x02, 0xa8, 0x02, 0x01, 0x02, 0xac, 0x02, 0x01, 0x02, + 0xb0, 0x02, 0x01, 0x02, 0xb4, 0x02, 0x01, 0x02, 0xb8, 0x02, 0x01, 0x02, 0x08, 0x1d, 0x02, 0x03, 0x10, 0x1d, 0x02, 0x03, 0x18, 0x1d, 0x02, 0x03, 0x20, 0x1d, 0x02, 0x03, 0x78, 0x00, 0x03, 0x03, + 0x80, 0x00, 0x03, 0x03, 0x88, 0x00, 0x03, 0x03, 0x90, 0x19, 0x04, 0x04, 0xa0, 0x19, 0x04, 0x04, 0xb0, 0x19, 0x04, 0x04, 0xa0, 0x3b, 0x05, 0x05, 0xa0, 0x16, 0x06, 0x05, 0x80, 0x39, 0x07, 0x06, + 0x80, 0x39, 0x09, 0x07, 0xb0, 0x0f, 0x00, 0x03, 0xb8, 0x0f, 0x00, 0x03, 0xc0, 0x0f, 0x00, 0x03, 0xc8, 0x0f, 0x00, 0x03, 0xbc, 0x02, 0x01, 0x02, 0xc0, 0x02, 0x01, 0x02, 0xc4, 0x02, 0x01, 0x02, + 0xc8, 0x02, 0x01, 0x02, 0xcc, 0x02, 0x01, 0x02, 0xd0, 0x02, 0x01, 0x02, 0x28, 0x1d, 0x02, 0x03, 0x30, 0x1d, 0x02, 0x03, 0x38, 0x1d, 0x02, 0x03, 0x40, 0x1d, 0x02, 0x03, 0x90, 0x00, 0x03, 0x03, + 0x98, 0x00, 0x03, 0x03, 0xa0, 0x00, 0x03, 0x03, 0xc0, 0x19, 0x04, 0x04, 0xd0, 0x19, 0x04, 0x04, 0xe0, 0x19, 0x04, 0x04, 0xc0, 0x3b, 0x05, 0x05, 0xc0, 0x16, 0x06, 0x05, 0xc0, 0x39, 0x07, 0x06, + 0x00, 0x3a, 0x09, 0x07, 0xd0, 0x0f, 0x00, 0x03, 0xd8, 0x0f, 0x00, 0x03, 0xe0, 0x0f, 0x00, 0x03, 0xe8, 0x0f, 0x00, 0x03, 0xd4, 0x02, 0x01, 0x02, 0xd8, 0x02, 0x01, 0x02, 0xdc, 0x02, 0x01, 0x02, + 0xe0, 0x02, 0x01, 0x02, 0xe4, 0x02, 0x01, 0x02, 0xe8, 0x02, 0x01, 0x02, 0x48, 0x1d, 0x02, 0x03, 0x50, 0x1d, 0x02, 0x03, 0x58, 0x1d, 0x02, 0x03, 0x60, 0x1d, 0x02, 0x03, 0xa8, 0x00, 0x03, 0x03, + 0xb0, 0x00, 0x03, 0x03, 0xb8, 0x00, 0x03, 0x03, 0xf0, 0x19, 0x04, 0x04, 0x00, 0x1a, 0x04, 0x04, 0x10, 0x1a, 0x04, 0x04, 0xe0, 0x3b, 0x05, 0x05, 0xe0, 0x16, 0x06, 0x05, 0x00, 0x3a, 0x07, 0x06, + 0x80, 0x3a, 0x09, 0x07, 0xf0, 0x0f, 0x00, 0x03, 0xf8, 0x0f, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x08, 0x10, 0x00, 0x03, 0xec, 0x02, 0x01, 0x02, 0xf0, 0x02, 0x01, 0x02, 0xf4, 0x02, 0x01, 0x02, + 0xf8, 0x02, 0x01, 0x02, 0xfc, 0x02, 0x01, 0x02, 0x00, 0x03, 0x01, 0x02, 0x68, 0x1d, 0x02, 0x03, 0x70, 0x1d, 0x02, 0x03, 0x78, 0x1d, 0x02, 0x03, 0x80, 0x1d, 0x02, 0x03, 0xc0, 0x00, 0x03, 0x03, + 0xc8, 0x00, 0x03, 0x03, 0xd0, 0x00, 0x03, 0x03, 0x20, 0x1a, 0x04, 0x04, 0x30, 0x1a, 0x04, 0x04, 0x40, 0x1a, 0x04, 0x04, 0x00, 0x3c, 0x05, 0x05, 0x00, 0x17, 0x06, 0x05, 0x40, 0x3a, 0x07, 0x06, + 0x00, 0x0f, 0x0a, 0x07, 0x10, 0x10, 0x00, 0x03, 0x18, 0x10, 0x00, 0x03, 0x20, 0x10, 0x00, 0x03, 0x28, 0x10, 0x00, 0x03, 0x04, 0x03, 0x01, 0x02, 0x08, 0x03, 0x01, 0x02, 0x0c, 0x03, 0x01, 0x02, + 0x10, 0x03, 0x01, 0x02, 0x14, 0x03, 0x01, 0x02, 0x18, 0x03, 0x01, 0x02, 0x88, 0x1d, 0x02, 0x03, 0x90, 0x1d, 0x02, 0x03, 0x98, 0x1d, 0x02, 0x03, 0xa0, 0x1d, 0x02, 0x03, 0xd8, 0x00, 0x03, 0x03, + 0xe0, 0x00, 0x03, 0x03, 0xe8, 0x00, 0x03, 0x03, 0x50, 0x1a, 0x04, 0x04, 0x60, 0x1a, 0x04, 0x04, 0x70, 0x1a, 0x04, 0x04, 0x20, 0x3c, 0x05, 0x05, 0x20, 0x17, 0x06, 0x05, 0x80, 0x3a, 0x07, 0x06, + 0x80, 0x0f, 0x0a, 0x07, 0x30, 0x10, 0x00, 0x03, 0x38, 0x10, 0x00, 0x03, 0x40, 0x10, 0x00, 0x03, 0x48, 0x10, 0x00, 0x03, 0x1c, 0x03, 0x01, 0x02, 0x20, 0x03, 0x01, 0x02, 0x24, 0x03, 0x01, 0x02, + 0x28, 0x03, 0x01, 0x02, 0x2c, 0x03, 0x01, 0x02, 0x30, 0x03, 0x01, 0x02, 0xa8, 0x1d, 0x02, 0x03, 0xb0, 0x1d, 0x02, 0x03, 0xb8, 0x1d, 0x02, 0x03, 0xc0, 0x1d, 0x02, 0x03, 0xf0, 0x00, 0x03, 0x03, + 0xf8, 0x00, 0x03, 0x03, 0x00, 0x01, 0x03, 0x03, 0x80, 0x1a, 0x04, 0x04, 0x90, 0x1a, 0x04, 0x04, 0xa0, 0x1a, 0x04, 0x04, 0x40, 0x3c, 0x05, 0x05, 0x40, 0x17, 0x06, 0x05, 0xc0, 0x3a, 0x07, 0x06, + 0x00, 0x10, 0x0a, 0x07, 0x50, 0x10, 0x00, 0x03, 0x58, 0x10, 0x00, 0x03, 0x60, 0x10, 0x00, 0x03, 0x68, 0x10, 0x00, 0x03, 0x34, 0x03, 0x01, 0x02, 0x38, 0x03, 0x01, 0x02, 0x3c, 0x03, 0x01, 0x02, + 0x40, 0x03, 0x01, 0x02, 0x44, 0x03, 0x01, 0x02, 0x48, 0x03, 0x01, 0x02, 0xc8, 0x1d, 0x02, 0x03, 0xd0, 0x1d, 0x02, 0x03, 0xd8, 0x1d, 0x02, 0x03, 0xe0, 0x1d, 0x02, 0x03, 0x08, 0x01, 0x03, 0x03, + 0x10, 0x01, 0x03, 0x03, 0x18, 0x01, 0x03, 0x03, 0xb0, 0x1a, 0x04, 0x04, 0xc0, 0x1a, 0x04, 0x04, 0x60, 0x3c, 0x05, 0x05, 0x80, 0x3c, 0x05, 0x05, 0x60, 0x17, 0x06, 0x05, 0x00, 0x3b, 0x07, 0x06, + 0x80, 0x10, 0x0a, 0x07, 0x70, 0x10, 0x00, 0x03, 0x78, 0x10, 0x00, 0x03, 0x80, 0x10, 0x00, 0x03, 0x88, 0x10, 0x00, 0x03, 0x4c, 0x03, 0x01, 0x02, 0x50, 0x03, 0x01, 0x02, 0x54, 0x03, 0x01, 0x02, + 0x58, 0x03, 0x01, 0x02, 0x5c, 0x03, 0x01, 0x02, 0x60, 0x03, 0x01, 0x02, 0xe8, 0x1d, 0x02, 0x03, 0xf0, 0x1d, 0x02, 0x03, 0xf8, 0x1d, 0x02, 0x03, 0x00, 0x1e, 0x02, 0x03, 0x20, 0x01, 0x03, 0x03, + 0x28, 0x01, 0x03, 0x03, 0x30, 0x01, 0x03, 0x03, 0xd0, 0x1a, 0x04, 0x04, 0xe0, 0x1a, 0x04, 0x04, 0xa0, 0x3c, 0x05, 0x05, 0xc0, 0x3c, 0x05, 0x05, 0x80, 0x17, 0x06, 0x05, 0x40, 0x3b, 0x07, 0x06, + 0x00, 0x11, 0x0a, 0x07, 0x90, 0x10, 0x00, 0x03, 0x98, 0x10, 0x00, 0x03, 0xa0, 0x10, 0x00, 0x03, 0xa8, 0x10, 0x00, 0x03, 0x64, 0x03, 0x01, 0x02, 0x68, 0x03, 0x01, 0x02, 0x6c, 0x03, 0x01, 0x02, + 0x70, 0x03, 0x01, 0x02, 0x74, 0x03, 0x01, 0x02, 0x78, 0x03, 0x01, 0x02, 0x08, 0x1e, 0x02, 0x03, 0x10, 0x1e, 0x02, 0x03, 0x18, 0x1e, 0x02, 0x03, 0x20, 0x1e, 0x02, 0x03, 0x38, 0x01, 0x03, 0x03, + 0x40, 0x01, 0x03, 0x03, 0x48, 0x01, 0x03, 0x03, 0xf0, 0x1a, 0x04, 0x04, 0x00, 0x1b, 0x04, 0x04, 0xe0, 0x3c, 0x05, 0x05, 0x00, 0x3d, 0x05, 0x05, 0xa0, 0x17, 0x06, 0x05, 0x80, 0x3b, 0x07, 0x06, + 0x80, 0x11, 0x0a, 0x07, 0xb0, 0x10, 0x00, 0x03, 0xb8, 0x10, 0x00, 0x03, 0xc0, 0x10, 0x00, 0x03, 0xc8, 0x10, 0x00, 0x03, 0x7c, 0x03, 0x01, 0x02, 0x80, 0x03, 0x01, 0x02, 0x84, 0x03, 0x01, 0x02, + 0x88, 0x03, 0x01, 0x02, 0x8c, 0x03, 0x01, 0x02, 0x90, 0x03, 0x01, 0x02, 0x28, 0x1e, 0x02, 0x03, 0x30, 0x1e, 0x02, 0x03, 0x38, 0x1e, 0x02, 0x03, 0x40, 0x1e, 0x02, 0x03, 0x50, 0x01, 0x03, 0x03, + 0x58, 0x01, 0x03, 0x03, 0x60, 0x01, 0x03, 0x03, 0x10, 0x1b, 0x04, 0x04, 0x20, 0x1b, 0x04, 0x04, 0x20, 0x3d, 0x05, 0x05, 0x40, 0x3d, 0x05, 0x05, 0xc0, 0x17, 0x06, 0x05, 0xc0, 0x3b, 0x07, 0x06, + 0x00, 0x12, 0x0a, 0x07, 0xd0, 0x10, 0x00, 0x03, 0xd8, 0x10, 0x00, 0x03, 0xe0, 0x10, 0x00, 0x03, 0xe8, 0x10, 0x00, 0x03, 0x94, 0x03, 0x01, 0x02, 0x98, 0x03, 0x01, 0x02, 0x9c, 0x03, 0x01, 0x02, + 0xa0, 0x03, 0x01, 0x02, 0xa4, 0x03, 0x01, 0x02, 0xa8, 0x03, 0x01, 0x02, 0x48, 0x1e, 0x02, 0x03, 0x50, 0x1e, 0x02, 0x03, 0x58, 0x1e, 0x02, 0x03, 0x60, 0x1e, 0x02, 0x03, 0x68, 0x01, 0x03, 0x03, + 0x70, 0x01, 0x03, 0x03, 0x78, 0x01, 0x03, 0x03, 0x30, 0x1b, 0x04, 0x04, 0x40, 0x1b, 0x04, 0x04, 0x60, 0x3d, 0x05, 0x05, 0x80, 0x3d, 0x05, 0x05, 0xe0, 0x17, 0x06, 0x05, 0x00, 0x3c, 0x07, 0x06, + 0x80, 0x12, 0x0a, 0x07, 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x10, 0x00, 0x03, 0x00, 0x11, 0x00, 0x03, 0x08, 0x11, 0x00, 0x03, 0xac, 0x03, 0x01, 0x02, 0xb0, 0x03, 0x01, 0x02, 0xb4, 0x03, 0x01, 0x02, + 0xb8, 0x03, 0x01, 0x02, 0xbc, 0x03, 0x01, 0x02, 0xc0, 0x03, 0x01, 0x02, 0x68, 0x1e, 0x02, 0x03, 0x70, 0x1e, 0x02, 0x03, 0x78, 0x1e, 0x02, 0x03, 0x80, 0x1e, 0x02, 0x03, 0x80, 0x01, 0x03, 0x03, + 0x88, 0x01, 0x03, 0x03, 0x90, 0x01, 0x03, 0x03, 0x50, 0x1b, 0x04, 0x04, 0x60, 0x1b, 0x04, 0x04, 0xa0, 0x3d, 0x05, 0x05, 0xc0, 0x3d, 0x05, 0x05, 0x00, 0x18, 0x06, 0x05, 0x40, 0x3c, 0x07, 0x06, + 0x00, 0x13, 0x0a, 0x07, 0x10, 0x11, 0x00, 0x03, 0x18, 0x11, 0x00, 0x03, 0x20, 0x11, 0x00, 0x03, 0x28, 0x11, 0x00, 0x03, 0xc4, 0x03, 0x01, 0x02, 0xc8, 0x03, 0x01, 0x02, 0xcc, 0x03, 0x01, 0x02, + 0xd0, 0x03, 0x01, 0x02, 0xd4, 0x03, 0x01, 0x02, 0xd8, 0x03, 0x01, 0x02, 0x88, 0x1e, 0x02, 0x03, 0x90, 0x1e, 0x02, 0x03, 0x98, 0x1e, 0x02, 0x03, 0xa0, 0x1e, 0x02, 0x03, 0x98, 0x01, 0x03, 0x03, + 0xa0, 0x01, 0x03, 0x03, 0xa8, 0x01, 0x03, 0x03, 0x70, 0x1b, 0x04, 0x04, 0x80, 0x1b, 0x04, 0x04, 0xe0, 0x3d, 0x05, 0x05, 0x00, 0x3e, 0x05, 0x05, 0x20, 0x18, 0x06, 0x05, 0x80, 0x3c, 0x07, 0x06, + 0x80, 0x13, 0x0a, 0x07, 0x30, 0x11, 0x00, 0x03, 0x38, 0x11, 0x00, 0x03, 0x40, 0x11, 0x00, 0x03, 0x48, 0x11, 0x00, 0x03, 0xdc, 0x03, 0x01, 0x02, 0xe0, 0x03, 0x01, 0x02, 0xe4, 0x03, 0x01, 0x02, + 0xe8, 0x03, 0x01, 0x02, 0xec, 0x03, 0x01, 0x02, 0xf0, 0x03, 0x01, 0x02, 0xa8, 0x1e, 0x02, 0x03, 0xb0, 0x1e, 0x02, 0x03, 0xb8, 0x1e, 0x02, 0x03, 0xc0, 0x1e, 0x02, 0x03, 0xb0, 0x01, 0x03, 0x03, + 0xb8, 0x01, 0x03, 0x03, 0xc0, 0x01, 0x03, 0x03, 0x90, 0x1b, 0x04, 0x04, 0xa0, 0x1b, 0x04, 0x04, 0x20, 0x3e, 0x05, 0x05, 0x40, 0x3e, 0x05, 0x05, 0x40, 0x18, 0x06, 0x05, 0xc0, 0x3c, 0x07, 0x06, + 0x00, 0x14, 0x0a, 0x07, 0x50, 0x11, 0x00, 0x03, 0x58, 0x11, 0x00, 0x03, 0x60, 0x11, 0x00, 0x03, 0x68, 0x11, 0x00, 0x03, 0xf4, 0x03, 0x01, 0x02, 0xf8, 0x03, 0x01, 0x02, 0xfc, 0x03, 0x01, 0x02, + 0x00, 0x04, 0x01, 0x02, 0x04, 0x04, 0x01, 0x02, 0x08, 0x04, 0x01, 0x02, 0xc8, 0x1e, 0x02, 0x03, 0xd0, 0x1e, 0x02, 0x03, 0xd8, 0x1e, 0x02, 0x03, 0xe0, 0x1e, 0x02, 0x03, 0xc8, 0x01, 0x03, 0x03, + 0xd0, 0x01, 0x03, 0x03, 0xd8, 0x01, 0x03, 0x03, 0xb0, 0x1b, 0x04, 0x04, 0xc0, 0x1b, 0x04, 0x04, 0x60, 0x3e, 0x05, 0x05, 0x80, 0x3e, 0x05, 0x05, 0x60, 0x18, 0x06, 0x05, 0x00, 0x3d, 0x07, 0x06, + 0x80, 0x14, 0x0a, 0x07, 0x70, 0x11, 0x00, 0x03, 0x78, 0x11, 0x00, 0x03, 0x80, 0x11, 0x00, 0x03, 0x88, 0x11, 0x00, 0x03, 0x0c, 0x04, 0x01, 0x02, 0x10, 0x04, 0x01, 0x02, 0x14, 0x04, 0x01, 0x02, + 0x18, 0x04, 0x01, 0x02, 0x1c, 0x04, 0x01, 0x02, 0x20, 0x04, 0x01, 0x02, 0xe8, 0x1e, 0x02, 0x03, 0xf0, 0x1e, 0x02, 0x03, 0xf8, 0x1e, 0x02, 0x03, 0x00, 0x1f, 0x02, 0x03, 0xe0, 0x01, 0x03, 0x03, + 0xe8, 0x01, 0x03, 0x03, 0xf0, 0x01, 0x03, 0x03, 0xd0, 0x1b, 0x04, 0x04, 0xe0, 0x1b, 0x04, 0x04, 0xa0, 0x3e, 0x05, 0x05, 0xc0, 0x3e, 0x05, 0x05, 0x80, 0x18, 0x06, 0x05, 0x40, 0x3d, 0x07, 0x06, + 0x00, 0x15, 0x0a, 0x07, 0x90, 0x11, 0x00, 0x03, 0x98, 0x11, 0x00, 0x03, 0xa0, 0x11, 0x00, 0x03, 0xa8, 0x11, 0x00, 0x03, 0x24, 0x04, 0x01, 0x02, 0x28, 0x04, 0x01, 0x02, 0x2c, 0x04, 0x01, 0x02, + 0x30, 0x04, 0x01, 0x02, 0x34, 0x04, 0x01, 0x02, 0x38, 0x04, 0x01, 0x02, 0x08, 0x1f, 0x02, 0x03, 0x10, 0x1f, 0x02, 0x03, 0x18, 0x1f, 0x02, 0x03, 0x20, 0x1f, 0x02, 0x03, 0xf8, 0x01, 0x03, 0x03, + 0x00, 0x02, 0x03, 0x03, 0x08, 0x02, 0x03, 0x03, 0xf0, 0x1b, 0x04, 0x04, 0x00, 0x1c, 0x04, 0x04, 0xe0, 0x3e, 0x05, 0x05, 0x00, 0x3f, 0x05, 0x05, 0xa0, 0x18, 0x06, 0x05, 0x80, 0x3d, 0x07, 0x06, + 0x80, 0x15, 0x0a, 0x07, 0xb0, 0x11, 0x00, 0x03, 0xb8, 0x11, 0x00, 0x03, 0xc0, 0x11, 0x00, 0x03, 0xc8, 0x11, 0x00, 0x03, 0x3c, 0x04, 0x01, 0x02, 0x40, 0x04, 0x01, 0x02, 0x44, 0x04, 0x01, 0x02, + 0x48, 0x04, 0x01, 0x02, 0x4c, 0x04, 0x01, 0x02, 0x50, 0x04, 0x01, 0x02, 0x28, 0x1f, 0x02, 0x03, 0x30, 0x1f, 0x02, 0x03, 0x38, 0x1f, 0x02, 0x03, 0x40, 0x1f, 0x02, 0x03, 0x10, 0x02, 0x03, 0x03, + 0x18, 0x02, 0x03, 0x03, 0x20, 0x02, 0x03, 0x03, 0x10, 0x1c, 0x04, 0x04, 0x20, 0x1c, 0x04, 0x04, 0x20, 0x3f, 0x05, 0x05, 0x40, 0x3f, 0x05, 0x05, 0xc0, 0x18, 0x06, 0x05, 0xc0, 0x3d, 0x07, 0x06, + 0x00, 0x16, 0x0a, 0x07, 0xd0, 0x11, 0x00, 0x03, 0xd8, 0x11, 0x00, 0x03, 0xe0, 0x11, 0x00, 0x03, 0xe8, 0x11, 0x00, 0x03, 0x54, 0x04, 0x01, 0x02, 0x58, 0x04, 0x01, 0x02, 0x5c, 0x04, 0x01, 0x02, + 0x60, 0x04, 0x01, 0x02, 0x64, 0x04, 0x01, 0x02, 0x68, 0x04, 0x01, 0x02, 0x48, 0x1f, 0x02, 0x03, 0x50, 0x1f, 0x02, 0x03, 0x58, 0x1f, 0x02, 0x03, 0x60, 0x1f, 0x02, 0x03, 0x28, 0x02, 0x03, 0x03, + 0x30, 0x02, 0x03, 0x03, 0x38, 0x02, 0x03, 0x03, 0x30, 0x1c, 0x04, 0x04, 0x40, 0x1c, 0x04, 0x04, 0x60, 0x3f, 0x05, 0x05, 0x80, 0x3f, 0x05, 0x05, 0xe0, 0x18, 0x06, 0x05, 0xc0, 0x11, 0x08, 0x06, + 0x80, 0x16, 0x0a, 0x07, 0xf0, 0x11, 0x00, 0x03, 0xf8, 0x11, 0x00, 0x03, 0x00, 0x12, 0x00, 0x03, 0x08, 0x12, 0x00, 0x03, 0x6c, 0x04, 0x01, 0x02, 0x70, 0x04, 0x01, 0x02, 0x74, 0x04, 0x01, 0x02, + 0x78, 0x04, 0x01, 0x02, 0x7c, 0x04, 0x01, 0x02, 0x80, 0x04, 0x01, 0x02, 0x68, 0x1f, 0x02, 0x03, 0x70, 0x1f, 0x02, 0x03, 0x78, 0x1f, 0x02, 0x03, 0x80, 0x1f, 0x02, 0x03, 0x40, 0x02, 0x03, 0x03, + 0x48, 0x02, 0x03, 0x03, 0x50, 0x02, 0x03, 0x03, 0x50, 0x1c, 0x04, 0x04, 0x60, 0x1c, 0x04, 0x04, 0xa0, 0x3f, 0x05, 0x05, 0xc0, 0x3f, 0x05, 0x05, 0x00, 0x19, 0x06, 0x05, 0x00, 0x12, 0x08, 0x06, + 0x00, 0x17, 0x0a, 0x07, 0x10, 0x12, 0x00, 0x03, 0x18, 0x12, 0x00, 0x03, 0x20, 0x12, 0x00, 0x03, 0x28, 0x12, 0x00, 0x03, 0x84, 0x04, 0x01, 0x02, 0x88, 0x04, 0x01, 0x02, 0x8c, 0x04, 0x01, 0x02, + 0x90, 0x04, 0x01, 0x02, 0x94, 0x04, 0x01, 0x02, 0x98, 0x04, 0x01, 0x02, 0x88, 0x1f, 0x02, 0x03, 0x90, 0x1f, 0x02, 0x03, 0x98, 0x1f, 0x02, 0x03, 0xa0, 0x1f, 0x02, 0x03, 0x58, 0x02, 0x03, 0x03, + 0x60, 0x02, 0x03, 0x03, 0x68, 0x02, 0x03, 0x03, 0x70, 0x1c, 0x04, 0x04, 0x80, 0x1c, 0x04, 0x04, 0xe0, 0x3f, 0x05, 0x05, 0x00, 0x00, 0x05, 0x04, 0x20, 0x19, 0x06, 0x05, 0x40, 0x12, 0x08, 0x06, + 0x80, 0x17, 0x0a, 0x07, 0x30, 0x12, 0x00, 0x03, 0x38, 0x12, 0x00, 0x03, 0x40, 0x12, 0x00, 0x03, 0x48, 0x12, 0x00, 0x03, 0x9c, 0x04, 0x01, 0x02, 0xa0, 0x04, 0x01, 0x02, 0xa4, 0x04, 0x01, 0x02, + 0xa8, 0x04, 0x01, 0x02, 0xac, 0x04, 0x01, 0x02, 0xb0, 0x04, 0x01, 0x02, 0xa8, 0x1f, 0x02, 0x03, 0xb0, 0x1f, 0x02, 0x03, 0xb8, 0x1f, 0x02, 0x03, 0xc0, 0x1f, 0x02, 0x03, 0x70, 0x02, 0x03, 0x03, + 0x78, 0x02, 0x03, 0x03, 0x80, 0x02, 0x03, 0x03, 0x90, 0x1c, 0x04, 0x04, 0xa0, 0x1c, 0x04, 0x04, 0x10, 0x00, 0x05, 0x04, 0x20, 0x00, 0x05, 0x04, 0x40, 0x19, 0x06, 0x05, 0x80, 0x12, 0x08, 0x06, + 0x00, 0x18, 0x0a, 0x07, 0x50, 0x12, 0x00, 0x03, 0x58, 0x12, 0x00, 0x03, 0x60, 0x12, 0x00, 0x03, 0x68, 0x12, 0x00, 0x03, 0xb4, 0x04, 0x01, 0x02, 0xb8, 0x04, 0x01, 0x02, 0xbc, 0x04, 0x01, 0x02, + 0xc0, 0x04, 0x01, 0x02, 0xc4, 0x04, 0x01, 0x02, 0xc8, 0x04, 0x01, 0x02, 0xc8, 0x1f, 0x02, 0x03, 0xd0, 0x1f, 0x02, 0x03, 0xd8, 0x1f, 0x02, 0x03, 0xe0, 0x1f, 0x02, 0x03, 0x88, 0x02, 0x03, 0x03, + 0x90, 0x02, 0x03, 0x03, 0x98, 0x02, 0x03, 0x03, 0xb0, 0x1c, 0x04, 0x04, 0xc0, 0x1c, 0x04, 0x04, 0x30, 0x00, 0x05, 0x04, 0x40, 0x00, 0x05, 0x04, 0x60, 0x19, 0x06, 0x05, 0xc0, 0x12, 0x08, 0x06, + 0x80, 0x18, 0x0a, 0x07, 0x70, 0x12, 0x00, 0x03, 0x78, 0x12, 0x00, 0x03, 0x80, 0x12, 0x00, 0x03, 0x88, 0x12, 0x00, 0x03, 0xcc, 0x04, 0x01, 0x02, 0xd0, 0x04, 0x01, 0x02, 0xd4, 0x04, 0x01, 0x02, + 0xd8, 0x04, 0x01, 0x02, 0xdc, 0x04, 0x01, 0x02, 0xe0, 0x04, 0x01, 0x02, 0xe8, 0x1f, 0x02, 0x03, 0xf0, 0x1f, 0x02, 0x03, 0xf8, 0x1f, 0x02, 0x03, 0x00, 0x20, 0x02, 0x03, 0xa0, 0x02, 0x03, 0x03, + 0xa8, 0x02, 0x03, 0x03, 0xb0, 0x02, 0x03, 0x03, 0xd0, 0x1c, 0x04, 0x04, 0xe0, 0x1c, 0x04, 0x04, 0x50, 0x00, 0x05, 0x04, 0x60, 0x00, 0x05, 0x04, 0x80, 0x19, 0x06, 0x05, 0x00, 0x13, 0x08, 0x06, + 0x00, 0x2e, 0x0b, 0x08, 0x90, 0x12, 0x00, 0x03, 0x98, 0x12, 0x00, 0x03, 0xa0, 0x12, 0x00, 0x03, 0xa8, 0x12, 0x00, 0x03, 0xe4, 0x04, 0x01, 0x02, 0xe8, 0x04, 0x01, 0x02, 0xec, 0x04, 0x01, 0x02, + 0xf0, 0x04, 0x01, 0x02, 0xf4, 0x04, 0x01, 0x02, 0xf8, 0x04, 0x01, 0x02, 0x08, 0x20, 0x02, 0x03, 0x10, 0x20, 0x02, 0x03, 0x18, 0x20, 0x02, 0x03, 0x20, 0x20, 0x02, 0x03, 0xb8, 0x02, 0x03, 0x03, + 0xc0, 0x02, 0x03, 0x03, 0xc8, 0x02, 0x03, 0x03, 0xf0, 0x1c, 0x04, 0x04, 0x00, 0x1d, 0x04, 0x04, 0x70, 0x00, 0x05, 0x04, 0x80, 0x00, 0x05, 0x04, 0xa0, 0x19, 0x06, 0x05, 0x40, 0x13, 0x08, 0x06, + 0x00, 0x2f, 0x0b, 0x08, 0xb0, 0x12, 0x00, 0x03, 0xb8, 0x12, 0x00, 0x03, 0xc0, 0x12, 0x00, 0x03, 0xc8, 0x12, 0x00, 0x03, 0xfc, 0x04, 0x01, 0x02, 0x00, 0x05, 0x01, 0x02, 0x04, 0x05, 0x01, 0x02, + 0x08, 0x05, 0x01, 0x02, 0x0c, 0x05, 0x01, 0x02, 0x10, 0x05, 0x01, 0x02, 0x28, 0x20, 0x02, 0x03, 0x30, 0x20, 0x02, 0x03, 0x38, 0x20, 0x02, 0x03, 0x40, 0x20, 0x02, 0x03, 0xd0, 0x02, 0x03, 0x03, + 0xd8, 0x02, 0x03, 0x03, 0xe0, 0x02, 0x03, 0x03, 0x10, 0x1d, 0x04, 0x04, 0x20, 0x1d, 0x04, 0x04, 0x90, 0x00, 0x05, 0x04, 0xa0, 0x00, 0x05, 0x04, 0xc0, 0x19, 0x06, 0x05, 0x80, 0x13, 0x08, 0x06, + 0x00, 0x30, 0x0b, 0x08, 0xd0, 0x12, 0x00, 0x03, 0xd8, 0x12, 0x00, 0x03, 0xe0, 0x12, 0x00, 0x03, 0xe8, 0x12, 0x00, 0x03, 0x14, 0x05, 0x01, 0x02, 0x18, 0x05, 0x01, 0x02, 0x1c, 0x05, 0x01, 0x02, + 0x20, 0x05, 0x01, 0x02, 0x24, 0x05, 0x01, 0x02, 0x28, 0x05, 0x01, 0x02, 0x48, 0x20, 0x02, 0x03, 0x50, 0x20, 0x02, 0x03, 0x58, 0x20, 0x02, 0x03, 0x60, 0x20, 0x02, 0x03, 0xe8, 0x02, 0x03, 0x03, + 0xf0, 0x02, 0x03, 0x03, 0xf8, 0x02, 0x03, 0x03, 0x30, 0x1d, 0x04, 0x04, 0x40, 0x1d, 0x04, 0x04, 0xb0, 0x00, 0x05, 0x04, 0xc0, 0x00, 0x05, 0x04, 0xe0, 0x19, 0x06, 0x05, 0xc0, 0x13, 0x08, 0x06, + 0x00, 0x31, 0x0b, 0x08, 0xf0, 0x12, 0x00, 0x03, 0xf8, 0x12, 0x00, 0x03, 0x00, 0x13, 0x00, 0x03, 0x08, 0x13, 0x00, 0x03, 0x2c, 0x05, 0x01, 0x02, 0x30, 0x05, 0x01, 0x02, 0x34, 0x05, 0x01, 0x02, + 0x38, 0x05, 0x01, 0x02, 0x3c, 0x05, 0x01, 0x02, 0x40, 0x05, 0x01, 0x02, 0x68, 0x20, 0x02, 0x03, 0x70, 0x20, 0x02, 0x03, 0x78, 0x20, 0x02, 0x03, 0x80, 0x20, 0x02, 0x03, 0x00, 0x03, 0x03, 0x03, + 0x08, 0x03, 0x03, 0x03, 0x10, 0x03, 0x03, 0x03, 0x50, 0x1d, 0x04, 0x04, 0x60, 0x1d, 0x04, 0x04, 0xd0, 0x00, 0x05, 0x04, 0xe0, 0x00, 0x05, 0x04, 0x00, 0x1a, 0x06, 0x05, 0x00, 0x14, 0x08, 0x06, + 0x00, 0x32, 0x0b, 0x08, 0x10, 0x13, 0x00, 0x03, 0x18, 0x13, 0x00, 0x03, 0x20, 0x13, 0x00, 0x03, 0x28, 0x13, 0x00, 0x03, 0x44, 0x05, 0x01, 0x02, 0x48, 0x05, 0x01, 0x02, 0x4c, 0x05, 0x01, 0x02, + 0x50, 0x05, 0x01, 0x02, 0x54, 0x05, 0x01, 0x02, 0x58, 0x05, 0x01, 0x02, 0x88, 0x20, 0x02, 0x03, 0x90, 0x20, 0x02, 0x03, 0x98, 0x20, 0x02, 0x03, 0xa0, 0x20, 0x02, 0x03, 0x18, 0x03, 0x03, 0x03, + 0x20, 0x03, 0x03, 0x03, 0x28, 0x03, 0x03, 0x03, 0x70, 0x1d, 0x04, 0x04, 0x80, 0x1d, 0x04, 0x04, 0xf0, 0x00, 0x05, 0x04, 0x00, 0x01, 0x05, 0x04, 0x20, 0x1a, 0x06, 0x05, 0x40, 0x14, 0x08, 0x06, + 0x00, 0x33, 0x0b, 0x08, 0x30, 0x13, 0x00, 0x03, 0x38, 0x13, 0x00, 0x03, 0x40, 0x13, 0x00, 0x03, 0x48, 0x13, 0x00, 0x03, 0x5c, 0x05, 0x01, 0x02, 0x60, 0x05, 0x01, 0x02, 0x64, 0x05, 0x01, 0x02, + 0x68, 0x05, 0x01, 0x02, 0x6c, 0x05, 0x01, 0x02, 0x70, 0x05, 0x01, 0x02, 0xa8, 0x20, 0x02, 0x03, 0xb0, 0x20, 0x02, 0x03, 0xb8, 0x20, 0x02, 0x03, 0xc0, 0x20, 0x02, 0x03, 0x30, 0x03, 0x03, 0x03, + 0x38, 0x03, 0x03, 0x03, 0x40, 0x03, 0x03, 0x03, 0x90, 0x1d, 0x04, 0x04, 0xa0, 0x1d, 0x04, 0x04, 0x10, 0x01, 0x05, 0x04, 0x20, 0x01, 0x05, 0x04, 0x40, 0x1a, 0x06, 0x05, 0x80, 0x14, 0x08, 0x06, + 0x00, 0x34, 0x0b, 0x08, 0x50, 0x13, 0x00, 0x03, 0x58, 0x13, 0x00, 0x03, 0x60, 0x13, 0x00, 0x03, 0x68, 0x13, 0x00, 0x03, 0x74, 0x05, 0x01, 0x02, 0x78, 0x05, 0x01, 0x02, 0x7c, 0x05, 0x01, 0x02, + 0x80, 0x05, 0x01, 0x02, 0x84, 0x05, 0x01, 0x02, 0x88, 0x05, 0x01, 0x02, 0xc8, 0x20, 0x02, 0x03, 0xd0, 0x20, 0x02, 0x03, 0xd8, 0x20, 0x02, 0x03, 0xe0, 0x20, 0x02, 0x03, 0x48, 0x03, 0x03, 0x03, + 0x50, 0x03, 0x03, 0x03, 0x58, 0x03, 0x03, 0x03, 0xb0, 0x1d, 0x04, 0x04, 0xc0, 0x1d, 0x04, 0x04, 0x30, 0x01, 0x05, 0x04, 0x40, 0x01, 0x05, 0x04, 0x60, 0x1a, 0x06, 0x05, 0xc0, 0x14, 0x08, 0x06, + 0x00, 0x35, 0x0b, 0x08, 0x70, 0x13, 0x00, 0x03, 0x78, 0x13, 0x00, 0x03, 0x80, 0x13, 0x00, 0x03, 0x88, 0x13, 0x00, 0x03, 0x8c, 0x05, 0x01, 0x02, 0x90, 0x05, 0x01, 0x02, 0x94, 0x05, 0x01, 0x02, + 0x98, 0x05, 0x01, 0x02, 0x9c, 0x05, 0x01, 0x02, 0xa0, 0x05, 0x01, 0x02, 0xe8, 0x20, 0x02, 0x03, 0xf0, 0x20, 0x02, 0x03, 0xf8, 0x20, 0x02, 0x03, 0x00, 0x21, 0x02, 0x03, 0x60, 0x03, 0x03, 0x03, + 0x68, 0x03, 0x03, 0x03, 0x70, 0x03, 0x03, 0x03, 0xd0, 0x1d, 0x04, 0x04, 0xe0, 0x1d, 0x04, 0x04, 0x50, 0x01, 0x05, 0x04, 0x60, 0x01, 0x05, 0x04, 0x80, 0x1a, 0x06, 0x05, 0x00, 0x15, 0x08, 0x06, + 0x00, 0x36, 0x0b, 0x08, 0x90, 0x13, 0x00, 0x03, 0x98, 0x13, 0x00, 0x03, 0xa0, 0x13, 0x00, 0x03, 0xa8, 0x13, 0x00, 0x03, 0xa4, 0x05, 0x01, 0x02, 0xa8, 0x05, 0x01, 0x02, 0xac, 0x05, 0x01, 0x02, + 0xb0, 0x05, 0x01, 0x02, 0xb4, 0x05, 0x01, 0x02, 0xb8, 0x05, 0x01, 0x02, 0x08, 0x21, 0x02, 0x03, 0x10, 0x21, 0x02, 0x03, 0x18, 0x21, 0x02, 0x03, 0x20, 0x21, 0x02, 0x03, 0x78, 0x03, 0x03, 0x03, + 0x80, 0x03, 0x03, 0x03, 0x88, 0x03, 0x03, 0x03, 0xf0, 0x1d, 0x04, 0x04, 0x00, 0x1e, 0x04, 0x04, 0x70, 0x01, 0x05, 0x04, 0x80, 0x01, 0x05, 0x04, 0xa0, 0x1a, 0x06, 0x05, 0x40, 0x15, 0x08, 0x06, + 0x00, 0x37, 0x0b, 0x08, 0xb0, 0x13, 0x00, 0x03, 0xb8, 0x13, 0x00, 0x03, 0xc0, 0x13, 0x00, 0x03, 0xc8, 0x13, 0x00, 0x03, 0xbc, 0x05, 0x01, 0x02, 0xc0, 0x05, 0x01, 0x02, 0xc4, 0x05, 0x01, 0x02, + 0xc8, 0x05, 0x01, 0x02, 0xcc, 0x05, 0x01, 0x02, 0xd0, 0x05, 0x01, 0x02, 0x28, 0x21, 0x02, 0x03, 0x30, 0x21, 0x02, 0x03, 0x38, 0x21, 0x02, 0x03, 0x40, 0x21, 0x02, 0x03, 0x90, 0x03, 0x03, 0x03, + 0x98, 0x03, 0x03, 0x03, 0xa0, 0x03, 0x03, 0x03, 0x10, 0x1e, 0x04, 0x04, 0x20, 0x1e, 0x04, 0x04, 0x90, 0x01, 0x05, 0x04, 0xa0, 0x01, 0x05, 0x04, 0xc0, 0x1a, 0x06, 0x05, 0x80, 0x15, 0x08, 0x06, + 0x00, 0x38, 0x0b, 0x08, 0xd0, 0x13, 0x00, 0x03, 0xd8, 0x13, 0x00, 0x03, 0xe0, 0x13, 0x00, 0x03, 0xe8, 0x13, 0x00, 0x03, 0xd4, 0x05, 0x01, 0x02, 0xd8, 0x05, 0x01, 0x02, 0xdc, 0x05, 0x01, 0x02, + 0xe0, 0x05, 0x01, 0x02, 0xe4, 0x05, 0x01, 0x02, 0xe8, 0x05, 0x01, 0x02, 0x48, 0x21, 0x02, 0x03, 0x50, 0x21, 0x02, 0x03, 0x58, 0x21, 0x02, 0x03, 0x60, 0x21, 0x02, 0x03, 0xa8, 0x03, 0x03, 0x03, + 0xb0, 0x03, 0x03, 0x03, 0xb8, 0x03, 0x03, 0x03, 0x30, 0x1e, 0x04, 0x04, 0x40, 0x1e, 0x04, 0x04, 0xb0, 0x01, 0x05, 0x04, 0xc0, 0x01, 0x05, 0x04, 0xe0, 0x1a, 0x06, 0x05, 0xc0, 0x15, 0x08, 0x06, + 0x00, 0x39, 0x0b, 0x08, 0xf0, 0x13, 0x00, 0x03, 0xf8, 0x13, 0x00, 0x03, 0x00, 0x14, 0x00, 0x03, 0x08, 0x14, 0x00, 0x03, 0xec, 0x05, 0x01, 0x02, 0xf0, 0x05, 0x01, 0x02, 0xf4, 0x05, 0x01, 0x02, + 0xf8, 0x05, 0x01, 0x02, 0xfc, 0x05, 0x01, 0x02, 0x00, 0x06, 0x01, 0x02, 0x68, 0x21, 0x02, 0x03, 0x70, 0x21, 0x02, 0x03, 0x78, 0x21, 0x02, 0x03, 0x80, 0x21, 0x02, 0x03, 0xc0, 0x03, 0x03, 0x03, + 0xc8, 0x03, 0x03, 0x03, 0xd0, 0x03, 0x03, 0x03, 0x50, 0x1e, 0x04, 0x04, 0x60, 0x1e, 0x04, 0x04, 0xd0, 0x01, 0x05, 0x04, 0xe0, 0x01, 0x05, 0x04, 0x00, 0x1b, 0x06, 0x05, 0x00, 0x16, 0x08, 0x06, + 0x00, 0x3a, 0x0b, 0x08, 0x10, 0x14, 0x00, 0x03, 0x18, 0x14, 0x00, 0x03, 0x20, 0x14, 0x00, 0x03, 0x28, 0x14, 0x00, 0x03, 0x04, 0x06, 0x01, 0x02, 0x08, 0x06, 0x01, 0x02, 0x0c, 0x06, 0x01, 0x02, + 0x10, 0x06, 0x01, 0x02, 0x14, 0x06, 0x01, 0x02, 0x18, 0x06, 0x01, 0x02, 0x88, 0x21, 0x02, 0x03, 0x90, 0x21, 0x02, 0x03, 0x98, 0x21, 0x02, 0x03, 0xa0, 0x21, 0x02, 0x03, 0xd8, 0x03, 0x03, 0x03, + 0xe0, 0x03, 0x03, 0x03, 0xe8, 0x03, 0x03, 0x03, 0x70, 0x1e, 0x04, 0x04, 0x80, 0x1e, 0x04, 0x04, 0xf0, 0x01, 0x05, 0x04, 0x00, 0x02, 0x05, 0x04, 0x20, 0x1b, 0x06, 0x05, 0x40, 0x16, 0x08, 0x06, + 0x00, 0x3b, 0x0b, 0x08, 0x30, 0x14, 0x00, 0x03, 0x38, 0x14, 0x00, 0x03, 0x40, 0x14, 0x00, 0x03, 0x48, 0x14, 0x00, 0x03, 0x1c, 0x06, 0x01, 0x02, 0x20, 0x06, 0x01, 0x02, 0x24, 0x06, 0x01, 0x02, + 0x28, 0x06, 0x01, 0x02, 0x2c, 0x06, 0x01, 0x02, 0x30, 0x06, 0x01, 0x02, 0xa8, 0x21, 0x02, 0x03, 0xb0, 0x21, 0x02, 0x03, 0xb8, 0x21, 0x02, 0x03, 0xc0, 0x21, 0x02, 0x03, 0xf0, 0x03, 0x03, 0x03, + 0xf8, 0x03, 0x03, 0x03, 0x00, 0x04, 0x03, 0x03, 0x90, 0x1e, 0x04, 0x04, 0xa0, 0x1e, 0x04, 0x04, 0x10, 0x02, 0x05, 0x04, 0x20, 0x02, 0x05, 0x04, 0x40, 0x1b, 0x06, 0x05, 0x80, 0x16, 0x08, 0x06, + 0x00, 0x0c, 0x0c, 0x08, 0x50, 0x14, 0x00, 0x03, 0x58, 0x14, 0x00, 0x03, 0x60, 0x14, 0x00, 0x03, 0x68, 0x14, 0x00, 0x03, 0x34, 0x06, 0x01, 0x02, 0x38, 0x06, 0x01, 0x02, 0x3c, 0x06, 0x01, 0x02, + 0x40, 0x06, 0x01, 0x02, 0x44, 0x06, 0x01, 0x02, 0x48, 0x06, 0x01, 0x02, 0xc8, 0x21, 0x02, 0x03, 0xd0, 0x21, 0x02, 0x03, 0xd8, 0x21, 0x02, 0x03, 0xe0, 0x21, 0x02, 0x03, 0x08, 0x04, 0x03, 0x03, + 0x10, 0x04, 0x03, 0x03, 0x18, 0x04, 0x03, 0x03, 0xb0, 0x1e, 0x04, 0x04, 0xc0, 0x1e, 0x04, 0x04, 0x30, 0x02, 0x05, 0x04, 0x40, 0x02, 0x05, 0x04, 0x60, 0x1b, 0x06, 0x05, 0xc0, 0x16, 0x08, 0x06, + 0x00, 0x0d, 0x0c, 0x08, 0x70, 0x14, 0x00, 0x03, 0x78, 0x14, 0x00, 0x03, 0x80, 0x14, 0x00, 0x03, 0x88, 0x14, 0x00, 0x03, 0x4c, 0x06, 0x01, 0x02, 0x50, 0x06, 0x01, 0x02, 0x54, 0x06, 0x01, 0x02, + 0x58, 0x06, 0x01, 0x02, 0x5c, 0x06, 0x01, 0x02, 0x60, 0x06, 0x01, 0x02, 0xe8, 0x21, 0x02, 0x03, 0xf0, 0x21, 0x02, 0x03, 0xf8, 0x21, 0x02, 0x03, 0x00, 0x22, 0x02, 0x03, 0x20, 0x04, 0x03, 0x03, + 0x28, 0x04, 0x03, 0x03, 0x30, 0x04, 0x03, 0x03, 0xd0, 0x1e, 0x04, 0x04, 0xe0, 0x1e, 0x04, 0x04, 0x50, 0x02, 0x05, 0x04, 0x60, 0x02, 0x05, 0x04, 0x80, 0x1b, 0x06, 0x05, 0x00, 0x17, 0x08, 0x06, + 0x00, 0x0e, 0x0c, 0x08, 0x90, 0x14, 0x00, 0x03, 0x98, 0x14, 0x00, 0x03, 0xa0, 0x14, 0x00, 0x03, 0xa8, 0x14, 0x00, 0x03, 0x64, 0x06, 0x01, 0x02, 0x68, 0x06, 0x01, 0x02, 0x6c, 0x06, 0x01, 0x02, + 0x70, 0x06, 0x01, 0x02, 0x74, 0x06, 0x01, 0x02, 0x78, 0x06, 0x01, 0x02, 0x08, 0x22, 0x02, 0x03, 0x10, 0x22, 0x02, 0x03, 0x18, 0x22, 0x02, 0x03, 0x20, 0x22, 0x02, 0x03, 0x38, 0x04, 0x03, 0x03, + 0x40, 0x04, 0x03, 0x03, 0x48, 0x04, 0x03, 0x03, 0xf0, 0x1e, 0x04, 0x04, 0x00, 0x1f, 0x04, 0x04, 0x70, 0x02, 0x05, 0x04, 0x80, 0x02, 0x05, 0x04, 0xa0, 0x1b, 0x06, 0x05, 0x40, 0x17, 0x08, 0x06, + 0x00, 0x0f, 0x0c, 0x08, 0xb0, 0x14, 0x00, 0x03, 0xb8, 0x14, 0x00, 0x03, 0xc0, 0x14, 0x00, 0x03, 0xc8, 0x14, 0x00, 0x03, 0x7c, 0x06, 0x01, 0x02, 0x80, 0x06, 0x01, 0x02, 0x84, 0x06, 0x01, 0x02, + 0x88, 0x06, 0x01, 0x02, 0x8c, 0x06, 0x01, 0x02, 0x90, 0x06, 0x01, 0x02, 0x28, 0x22, 0x02, 0x03, 0x30, 0x22, 0x02, 0x03, 0x38, 0x22, 0x02, 0x03, 0x40, 0x22, 0x02, 0x03, 0x50, 0x04, 0x03, 0x03, + 0x58, 0x04, 0x03, 0x03, 0x60, 0x04, 0x03, 0x03, 0x10, 0x1f, 0x04, 0x04, 0x20, 0x1f, 0x04, 0x04, 0x90, 0x02, 0x05, 0x04, 0xa0, 0x02, 0x05, 0x04, 0xc0, 0x1b, 0x06, 0x05, 0x80, 0x17, 0x08, 0x06, + 0x00, 0x10, 0x0c, 0x08, 0xd0, 0x14, 0x00, 0x03, 0xd8, 0x14, 0x00, 0x03, 0xe0, 0x14, 0x00, 0x03, 0x94, 0x06, 0x01, 0x02, 0x98, 0x06, 0x01, 0x02, 0x9c, 0x06, 0x01, 0x02, 0xa0, 0x06, 0x01, 0x02, + 0xa4, 0x06, 0x01, 0x02, 0xa8, 0x06, 0x01, 0x02, 0xac, 0x06, 0x01, 0x02, 0x48, 0x22, 0x02, 0x03, 0x50, 0x22, 0x02, 0x03, 0x58, 0x22, 0x02, 0x03, 0x60, 0x22, 0x02, 0x03, 0x68, 0x04, 0x03, 0x03, + 0x70, 0x04, 0x03, 0x03, 0x78, 0x04, 0x03, 0x03, 0x30, 0x1f, 0x04, 0x04, 0x40, 0x1f, 0x04, 0x04, 0xb0, 0x02, 0x05, 0x04, 0xc0, 0x02, 0x05, 0x04, 0xe0, 0x1b, 0x06, 0x05, 0xc0, 0x17, 0x08, 0x06, + 0x00, 0x11, 0x0c, 0x08, 0xe8, 0x14, 0x00, 0x03, 0xf0, 0x14, 0x00, 0x03, 0xf8, 0x14, 0x00, 0x03, 0xb0, 0x06, 0x01, 0x02, 0xb4, 0x06, 0x01, 0x02, 0xb8, 0x06, 0x01, 0x02, 0xbc, 0x06, 0x01, 0x02, + 0xc0, 0x06, 0x01, 0x02, 0xc4, 0x06, 0x01, 0x02, 0xc8, 0x06, 0x01, 0x02, 0x68, 0x22, 0x02, 0x03, 0x70, 0x22, 0x02, 0x03, 0x78, 0x22, 0x02, 0x03, 0x80, 0x22, 0x02, 0x03, 0x80, 0x04, 0x03, 0x03, + 0x88, 0x04, 0x03, 0x03, 0x90, 0x04, 0x03, 0x03, 0x50, 0x1f, 0x04, 0x04, 0x60, 0x1f, 0x04, 0x04, 0xd0, 0x02, 0x05, 0x04, 0x00, 0x1c, 0x06, 0x05, 0x20, 0x1c, 0x06, 0x05, 0x00, 0x18, 0x08, 0x06, + 0x00, 0x12, 0x0c, 0x08, 0x00, 0x15, 0x00, 0x03, 0x08, 0x15, 0x00, 0x03, 0x10, 0x15, 0x00, 0x03, 0xcc, 0x06, 0x01, 0x02, 0xd0, 0x06, 0x01, 0x02, 0xd4, 0x06, 0x01, 0x02, 0xd8, 0x06, 0x01, 0x02, + 0xdc, 0x06, 0x01, 0x02, 0xe0, 0x06, 0x01, 0x02, 0xe4, 0x06, 0x01, 0x02, 0x88, 0x22, 0x02, 0x03, 0x90, 0x22, 0x02, 0x03, 0x98, 0x22, 0x02, 0x03, 0xa0, 0x22, 0x02, 0x03, 0x98, 0x04, 0x03, 0x03, + 0xa0, 0x04, 0x03, 0x03, 0xa8, 0x04, 0x03, 0x03, 0x70, 0x1f, 0x04, 0x04, 0x80, 0x1f, 0x04, 0x04, 0xe0, 0x02, 0x05, 0x04, 0x40, 0x1c, 0x06, 0x05, 0x00, 0x3e, 0x07, 0x06, 0x40, 0x18, 0x08, 0x06, + 0x00, 0x13, 0x0c, 0x08, 0x18, 0x15, 0x00, 0x03, 0x20, 0x15, 0x00, 0x03, 0x28, 0x15, 0x00, 0x03, 0xe8, 0x06, 0x01, 0x02, 0xec, 0x06, 0x01, 0x02, 0xf0, 0x06, 0x01, 0x02, 0xf4, 0x06, 0x01, 0x02, + 0xf8, 0x06, 0x01, 0x02, 0xfc, 0x06, 0x01, 0x02, 0x00, 0x07, 0x01, 0x02, 0xa8, 0x22, 0x02, 0x03, 0xb0, 0x22, 0x02, 0x03, 0xb8, 0x22, 0x02, 0x03, 0xc0, 0x22, 0x02, 0x03, 0xb0, 0x04, 0x03, 0x03, + 0xb8, 0x04, 0x03, 0x03, 0xc0, 0x04, 0x03, 0x03, 0x90, 0x1f, 0x04, 0x04, 0xa0, 0x1f, 0x04, 0x04, 0xf0, 0x02, 0x05, 0x04, 0x60, 0x1c, 0x06, 0x05, 0x40, 0x3e, 0x07, 0x06, 0x80, 0x18, 0x08, 0x06, + 0x00, 0x14, 0x0c, 0x08, 0x30, 0x15, 0x00, 0x03, 0x38, 0x15, 0x00, 0x03, 0x40, 0x15, 0x00, 0x03, 0x04, 0x07, 0x01, 0x02, 0x08, 0x07, 0x01, 0x02, 0x0c, 0x07, 0x01, 0x02, 0x10, 0x07, 0x01, 0x02, + 0x14, 0x07, 0x01, 0x02, 0x18, 0x07, 0x01, 0x02, 0x1c, 0x07, 0x01, 0x02, 0xc8, 0x22, 0x02, 0x03, 0xd0, 0x22, 0x02, 0x03, 0xd8, 0x22, 0x02, 0x03, 0xe0, 0x22, 0x02, 0x03, 0xc8, 0x04, 0x03, 0x03, + 0xd0, 0x04, 0x03, 0x03, 0xd8, 0x04, 0x03, 0x03, 0xb0, 0x1f, 0x04, 0x04, 0xc0, 0x1f, 0x04, 0x04, 0x00, 0x03, 0x05, 0x04, 0x80, 0x1c, 0x06, 0x05, 0x80, 0x3e, 0x07, 0x06, 0xc0, 0x18, 0x08, 0x06, + 0x00, 0x2a, 0x0d, 0x09, 0x48, 0x15, 0x00, 0x03, 0x50, 0x15, 0x00, 0x03, 0x58, 0x15, 0x00, 0x03, 0x20, 0x07, 0x01, 0x02, 0x24, 0x07, 0x01, 0x02, 0x28, 0x07, 0x01, 0x02, 0x2c, 0x07, 0x01, 0x02, + 0x30, 0x07, 0x01, 0x02, 0x34, 0x07, 0x01, 0x02, 0x38, 0x07, 0x01, 0x02, 0xe8, 0x22, 0x02, 0x03, 0xf0, 0x22, 0x02, 0x03, 0xf8, 0x22, 0x02, 0x03, 0x00, 0x23, 0x02, 0x03, 0xe0, 0x04, 0x03, 0x03, + 0xe8, 0x04, 0x03, 0x03, 0xf0, 0x04, 0x03, 0x03, 0xd0, 0x1f, 0x04, 0x04, 0xe0, 0x1f, 0x04, 0x04, 0x10, 0x03, 0x05, 0x04, 0xa0, 0x1c, 0x06, 0x05, 0xc0, 0x3e, 0x07, 0x06, 0x00, 0x19, 0x08, 0x06, + 0x00, 0x2c, 0x0d, 0x09, 0x60, 0x15, 0x00, 0x03, 0x68, 0x15, 0x00, 0x03, 0x70, 0x15, 0x00, 0x03, 0x3c, 0x07, 0x01, 0x02, 0x40, 0x07, 0x01, 0x02, 0x44, 0x07, 0x01, 0x02, 0x48, 0x07, 0x01, 0x02, + 0x4c, 0x07, 0x01, 0x02, 0x50, 0x07, 0x01, 0x02, 0x54, 0x07, 0x01, 0x02, 0x08, 0x23, 0x02, 0x03, 0x10, 0x23, 0x02, 0x03, 0x18, 0x23, 0x02, 0x03, 0x20, 0x23, 0x02, 0x03, 0xf8, 0x04, 0x03, 0x03, + 0x00, 0x05, 0x03, 0x03, 0x08, 0x05, 0x03, 0x03, 0xf0, 0x1f, 0x04, 0x04, 0x00, 0x20, 0x04, 0x04, 0x20, 0x03, 0x05, 0x04, 0xc0, 0x1c, 0x06, 0x05, 0x00, 0x3f, 0x07, 0x06, 0x40, 0x19, 0x08, 0x06, + 0x00, 0x2e, 0x0d, 0x09, 0x78, 0x15, 0x00, 0x03, 0x80, 0x15, 0x00, 0x03, 0x88, 0x15, 0x00, 0x03, 0x58, 0x07, 0x01, 0x02, 0x5c, 0x07, 0x01, 0x02, 0x60, 0x07, 0x01, 0x02, 0x64, 0x07, 0x01, 0x02, + 0x68, 0x07, 0x01, 0x02, 0x6c, 0x07, 0x01, 0x02, 0x70, 0x07, 0x01, 0x02, 0x28, 0x23, 0x02, 0x03, 0x30, 0x23, 0x02, 0x03, 0x38, 0x23, 0x02, 0x03, 0x40, 0x23, 0x02, 0x03, 0x10, 0x05, 0x03, 0x03, + 0x18, 0x05, 0x03, 0x03, 0x20, 0x05, 0x03, 0x03, 0x10, 0x20, 0x04, 0x04, 0x20, 0x20, 0x04, 0x04, 0x30, 0x03, 0x05, 0x04, 0xe0, 0x1c, 0x06, 0x05, 0x40, 0x3f, 0x07, 0x06, 0x80, 0x19, 0x08, 0x06, + 0x00, 0x30, 0x0d, 0x09, 0x90, 0x15, 0x00, 0x03, 0x98, 0x15, 0x00, 0x03, 0xa0, 0x15, 0x00, 0x03, 0x74, 0x07, 0x01, 0x02, 0x78, 0x07, 0x01, 0x02, 0x7c, 0x07, 0x01, 0x02, 0x80, 0x07, 0x01, 0x02, + 0x84, 0x07, 0x01, 0x02, 0x88, 0x07, 0x01, 0x02, 0x8c, 0x07, 0x01, 0x02, 0x48, 0x23, 0x02, 0x03, 0x50, 0x23, 0x02, 0x03, 0x58, 0x23, 0x02, 0x03, 0x60, 0x23, 0x02, 0x03, 0x28, 0x05, 0x03, 0x03, + 0x30, 0x05, 0x03, 0x03, 0x38, 0x05, 0x03, 0x03, 0x30, 0x20, 0x04, 0x04, 0x40, 0x20, 0x04, 0x04, 0x40, 0x03, 0x05, 0x04, 0x00, 0x1d, 0x06, 0x05, 0x80, 0x3f, 0x07, 0x06, 0xc0, 0x19, 0x08, 0x06, + 0x00, 0x32, 0x0d, 0x09, 0xa8, 0x15, 0x00, 0x03, 0xb0, 0x15, 0x00, 0x03, 0xb8, 0x15, 0x00, 0x03, 0x90, 0x07, 0x01, 0x02, 0x94, 0x07, 0x01, 0x02, 0x98, 0x07, 0x01, 0x02, 0x9c, 0x07, 0x01, 0x02, + 0xa0, 0x07, 0x01, 0x02, 0xa4, 0x07, 0x01, 0x02, 0xa8, 0x07, 0x01, 0x02, 0x68, 0x23, 0x02, 0x03, 0x70, 0x23, 0x02, 0x03, 0x78, 0x23, 0x02, 0x03, 0x80, 0x23, 0x02, 0x03, 0x40, 0x05, 0x03, 0x03, + 0x48, 0x05, 0x03, 0x03, 0x50, 0x05, 0x03, 0x03, 0x50, 0x20, 0x04, 0x04, 0x60, 0x20, 0x04, 0x04, 0x50, 0x03, 0x05, 0x04, 0x20, 0x1d, 0x06, 0x05, 0xc0, 0x3f, 0x07, 0x06, 0x00, 0x1a, 0x08, 0x06, + 0x00, 0x34, 0x0d, 0x09, 0xc0, 0x15, 0x00, 0x03, 0xc8, 0x15, 0x00, 0x03, 0xd0, 0x15, 0x00, 0x03, 0xac, 0x07, 0x01, 0x02, 0xb0, 0x07, 0x01, 0x02, 0xb4, 0x07, 0x01, 0x02, 0xb8, 0x07, 0x01, 0x02, + 0xbc, 0x07, 0x01, 0x02, 0xc0, 0x07, 0x01, 0x02, 0xc4, 0x07, 0x01, 0x02, 0x88, 0x23, 0x02, 0x03, 0x90, 0x23, 0x02, 0x03, 0x98, 0x23, 0x02, 0x03, 0xa0, 0x23, 0x02, 0x03, 0x58, 0x05, 0x03, 0x03, + 0x60, 0x05, 0x03, 0x03, 0x68, 0x05, 0x03, 0x03, 0x70, 0x20, 0x04, 0x04, 0x80, 0x20, 0x04, 0x04, 0x60, 0x03, 0x05, 0x04, 0x40, 0x1d, 0x06, 0x05, 0x00, 0x00, 0x07, 0x05, 0x40, 0x1a, 0x08, 0x06, + 0x00, 0x36, 0x0d, 0x09, 0xd8, 0x15, 0x00, 0x03, 0xe0, 0x15, 0x00, 0x03, 0xe8, 0x15, 0x00, 0x03, 0xc8, 0x07, 0x01, 0x02, 0xcc, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd4, 0x07, 0x01, 0x02, + 0xd8, 0x07, 0x01, 0x02, 0xdc, 0x07, 0x01, 0x02, 0xe0, 0x07, 0x01, 0x02, 0xa8, 0x23, 0x02, 0x03, 0xb0, 0x23, 0x02, 0x03, 0xb8, 0x23, 0x02, 0x03, 0xc0, 0x23, 0x02, 0x03, 0x70, 0x05, 0x03, 0x03, + 0x78, 0x05, 0x03, 0x03, 0x80, 0x05, 0x03, 0x03, 0x90, 0x20, 0x04, 0x04, 0xa0, 0x20, 0x04, 0x04, 0x70, 0x03, 0x05, 0x04, 0x60, 0x1d, 0x06, 0x05, 0x20, 0x00, 0x07, 0x05, 0x80, 0x1a, 0x08, 0x06, + 0x00, 0x0a, 0x0e, 0x09, 0xf0, 0x15, 0x00, 0x03, 0xf8, 0x15, 0x00, 0x03, 0x00, 0x16, 0x00, 0x03, 0xe4, 0x07, 0x01, 0x02, 0xe8, 0x07, 0x01, 0x02, 0xec, 0x07, 0x01, 0x02, 0xf0, 0x07, 0x01, 0x02, + 0xf4, 0x07, 0x01, 0x02, 0xf8, 0x07, 0x01, 0x02, 0xfc, 0x07, 0x01, 0x02, 0xc8, 0x23, 0x02, 0x03, 0xd0, 0x23, 0x02, 0x03, 0xd8, 0x23, 0x02, 0x03, 0xe0, 0x23, 0x02, 0x03, 0x88, 0x05, 0x03, 0x03, + 0x90, 0x05, 0x03, 0x03, 0x98, 0x05, 0x03, 0x03, 0xb0, 0x20, 0x04, 0x04, 0xc0, 0x20, 0x04, 0x04, 0x80, 0x03, 0x05, 0x04, 0x80, 0x1d, 0x06, 0x05, 0x40, 0x00, 0x07, 0x05, 0xc0, 0x1a, 0x08, 0x06, + 0x00, 0x0c, 0x0e, 0x09, 0x08, 0x16, 0x00, 0x03, 0x10, 0x16, 0x00, 0x03, 0x18, 0x16, 0x00, 0x03, 0x00, 0x08, 0x01, 0x02, 0x04, 0x08, 0x01, 0x02, 0x08, 0x08, 0x01, 0x02, 0x0c, 0x08, 0x01, 0x02, + 0x10, 0x08, 0x01, 0x02, 0x14, 0x08, 0x01, 0x02, 0x18, 0x08, 0x01, 0x02, 0xe8, 0x23, 0x02, 0x03, 0xf0, 0x23, 0x02, 0x03, 0xf8, 0x23, 0x02, 0x03, 0x00, 0x24, 0x02, 0x03, 0xa0, 0x05, 0x03, 0x03, + 0xa8, 0x05, 0x03, 0x03, 0xb0, 0x05, 0x03, 0x03, 0xd0, 0x20, 0x04, 0x04, 0xe0, 0x20, 0x04, 0x04, 0x90, 0x03, 0x05, 0x04, 0xa0, 0x1d, 0x06, 0x05, 0x60, 0x00, 0x07, 0x05, 0x00, 0x1b, 0x08, 0x06, + 0x00, 0x0e, 0x0e, 0x09, 0x20, 0x16, 0x00, 0x03, 0x28, 0x16, 0x00, 0x03, 0x30, 0x16, 0x00, 0x03, 0x1c, 0x08, 0x01, 0x02, 0x20, 0x08, 0x01, 0x02, 0x24, 0x08, 0x01, 0x02, 0x28, 0x08, 0x01, 0x02, + 0x2c, 0x08, 0x01, 0x02, 0x30, 0x08, 0x01, 0x02, 0x34, 0x08, 0x01, 0x02, 0x08, 0x24, 0x02, 0x03, 0x10, 0x24, 0x02, 0x03, 0x18, 0x24, 0x02, 0x03, 0x20, 0x24, 0x02, 0x03, 0xb8, 0x05, 0x03, 0x03, + 0xc0, 0x05, 0x03, 0x03, 0xc8, 0x05, 0x03, 0x03, 0xf0, 0x20, 0x04, 0x04, 0x00, 0x21, 0x04, 0x04, 0xa0, 0x03, 0x05, 0x04, 0xc0, 0x1d, 0x06, 0x05, 0x80, 0x00, 0x07, 0x05, 0x40, 0x1b, 0x08, 0x06, + 0x00, 0x10, 0x0e, 0x09, 0x38, 0x16, 0x00, 0x03, 0x40, 0x16, 0x00, 0x03, 0x48, 0x16, 0x00, 0x03, 0x38, 0x08, 0x01, 0x02, 0x3c, 0x08, 0x01, 0x02, 0x40, 0x08, 0x01, 0x02, 0x44, 0x08, 0x01, 0x02, + 0x48, 0x08, 0x01, 0x02, 0x4c, 0x08, 0x01, 0x02, 0x50, 0x08, 0x01, 0x02, 0x28, 0x24, 0x02, 0x03, 0x30, 0x24, 0x02, 0x03, 0x38, 0x24, 0x02, 0x03, 0x40, 0x24, 0x02, 0x03, 0xd0, 0x05, 0x03, 0x03, + 0xd8, 0x05, 0x03, 0x03, 0xe0, 0x05, 0x03, 0x03, 0x10, 0x21, 0x04, 0x04, 0x20, 0x21, 0x04, 0x04, 0xb0, 0x03, 0x05, 0x04, 0xe0, 0x1d, 0x06, 0x05, 0xa0, 0x00, 0x07, 0x05, 0x80, 0x1b, 0x08, 0x06, + 0x00, 0x12, 0x0e, 0x09, 0x50, 0x16, 0x00, 0x03, 0x58, 0x16, 0x00, 0x03, 0x60, 0x16, 0x00, 0x03, 0x54, 0x08, 0x01, 0x02, 0x58, 0x08, 0x01, 0x02, 0x5c, 0x08, 0x01, 0x02, 0x60, 0x08, 0x01, 0x02, + 0x64, 0x08, 0x01, 0x02, 0x68, 0x08, 0x01, 0x02, 0x48, 0x24, 0x02, 0x03, 0x50, 0x24, 0x02, 0x03, 0x58, 0x24, 0x02, 0x03, 0x60, 0x24, 0x02, 0x03, 0x68, 0x24, 0x02, 0x03, 0xe8, 0x05, 0x03, 0x03, + 0xf0, 0x05, 0x03, 0x03, 0xf8, 0x05, 0x03, 0x03, 0x30, 0x21, 0x04, 0x04, 0x40, 0x21, 0x04, 0x04, 0xc0, 0x03, 0x05, 0x04, 0x00, 0x1e, 0x06, 0x05, 0xc0, 0x00, 0x07, 0x05, 0xc0, 0x1b, 0x08, 0x06, + 0x00, 0x28, 0x0f, 0x0a, 0x68, 0x16, 0x00, 0x03, 0x70, 0x16, 0x00, 0x03, 0x78, 0x16, 0x00, 0x03, 0x6c, 0x08, 0x01, 0x02, 0x70, 0x08, 0x01, 0x02, 0x74, 0x08, 0x01, 0x02, 0x78, 0x08, 0x01, 0x02, + 0x7c, 0x08, 0x01, 0x02, 0x80, 0x08, 0x01, 0x02, 0x70, 0x24, 0x02, 0x03, 0x78, 0x24, 0x02, 0x03, 0x80, 0x24, 0x02, 0x03, 0x88, 0x24, 0x02, 0x03, 0x90, 0x24, 0x02, 0x03, 0x00, 0x06, 0x03, 0x03, + 0x08, 0x06, 0x03, 0x03, 0x10, 0x06, 0x03, 0x03, 0x50, 0x21, 0x04, 0x04, 0x60, 0x21, 0x04, 0x04, 0xd0, 0x03, 0x05, 0x04, 0x20, 0x1e, 0x06, 0x05, 0xe0, 0x00, 0x07, 0x05, 0x00, 0x3b, 0x09, 0x07, + 0x00, 0x2c, 0x0f, 0x0a, 0x80, 0x16, 0x00, 0x03, 0x88, 0x16, 0x00, 0x03, 0x90, 0x16, 0x00, 0x03, 0x84, 0x08, 0x01, 0x02, 0x88, 0x08, 0x01, 0x02, 0x8c, 0x08, 0x01, 0x02, 0x90, 0x08, 0x01, 0x02, + 0x94, 0x08, 0x01, 0x02, 0x98, 0x08, 0x01, 0x02, 0x98, 0x24, 0x02, 0x03, 0xa0, 0x24, 0x02, 0x03, 0xa8, 0x24, 0x02, 0x03, 0xb0, 0x24, 0x02, 0x03, 0xb8, 0x24, 0x02, 0x03, 0x18, 0x06, 0x03, 0x03, + 0x20, 0x06, 0x03, 0x03, 0x28, 0x06, 0x03, 0x03, 0x70, 0x21, 0x04, 0x04, 0x80, 0x21, 0x04, 0x04, 0xe0, 0x03, 0x05, 0x04, 0x40, 0x1e, 0x06, 0x05, 0x00, 0x01, 0x07, 0x05, 0x80, 0x3b, 0x09, 0x07, + 0x00, 0x30, 0x0f, 0x0a, 0x98, 0x16, 0x00, 0x03, 0xa0, 0x16, 0x00, 0x03, 0xa8, 0x16, 0x00, 0x03, 0x9c, 0x08, 0x01, 0x02, 0xa0, 0x08, 0x01, 0x02, 0xa4, 0x08, 0x01, 0x02, 0xa8, 0x08, 0x01, 0x02, + 0xac, 0x08, 0x01, 0x02, 0xb0, 0x08, 0x01, 0x02, 0xc0, 0x24, 0x02, 0x03, 0xc8, 0x24, 0x02, 0x03, 0xd0, 0x24, 0x02, 0x03, 0xd8, 0x24, 0x02, 0x03, 0xe0, 0x24, 0x02, 0x03, 0x30, 0x06, 0x03, 0x03, + 0x38, 0x06, 0x03, 0x03, 0x40, 0x06, 0x03, 0x03, 0x90, 0x21, 0x04, 0x04, 0xa0, 0x21, 0x04, 0x04, 0xf0, 0x03, 0x05, 0x04, 0x60, 0x1e, 0x06, 0x05, 0x20, 0x01, 0x07, 0x05, 0x00, 0x3c, 0x09, 0x07, + 0x00, 0x08, 0x10, 0x0a, 0xb0, 0x16, 0x00, 0x03, 0xb8, 0x16, 0x00, 0x03, 0xc0, 0x16, 0x00, 0x03, 0xb4, 0x08, 0x01, 0x02, 0xb8, 0x08, 0x01, 0x02, 0xbc, 0x08, 0x01, 0x02, 0xc0, 0x08, 0x01, 0x02, + 0xc4, 0x08, 0x01, 0x02, 0xc8, 0x08, 0x01, 0x02, 0xe8, 0x24, 0x02, 0x03, 0xf0, 0x24, 0x02, 0x03, 0xf8, 0x24, 0x02, 0x03, 0x00, 0x25, 0x02, 0x03, 0x08, 0x25, 0x02, 0x03, 0x48, 0x06, 0x03, 0x03, + 0x50, 0x06, 0x03, 0x03, 0x58, 0x06, 0x03, 0x03, 0xb0, 0x21, 0x04, 0x04, 0xc0, 0x21, 0x04, 0x04, 0x00, 0x04, 0x05, 0x04, 0x80, 0x1e, 0x06, 0x05, 0x40, 0x01, 0x07, 0x05, 0x80, 0x3c, 0x09, 0x07, + 0x00, 0x0c, 0x10, 0x0a, 0xc8, 0x16, 0x00, 0x03, 0xd0, 0x16, 0x00, 0x03, 0xd8, 0x16, 0x00, 0x03, 0xcc, 0x08, 0x01, 0x02, 0xd0, 0x08, 0x01, 0x02, 0xd4, 0x08, 0x01, 0x02, 0xd8, 0x08, 0x01, 0x02, + 0xdc, 0x08, 0x01, 0x02, 0xe0, 0x08, 0x01, 0x02, 0x10, 0x25, 0x02, 0x03, 0x18, 0x25, 0x02, 0x03, 0x20, 0x25, 0x02, 0x03, 0x28, 0x25, 0x02, 0x03, 0x30, 0x25, 0x02, 0x03, 0x60, 0x06, 0x03, 0x03, + 0x68, 0x06, 0x03, 0x03, 0x70, 0x06, 0x03, 0x03, 0xd0, 0x21, 0x04, 0x04, 0xe0, 0x21, 0x04, 0x04, 0x10, 0x04, 0x05, 0x04, 0xa0, 0x1e, 0x06, 0x05, 0x60, 0x01, 0x07, 0x05, 0x00, 0x3d, 0x09, 0x07, + 0x00, 0x10, 0x10, 0x0a, 0xe0, 0x16, 0x00, 0x03, 0xe8, 0x16, 0x00, 0x03, 0xf0, 0x16, 0x00, 0x03, 0xe4, 0x08, 0x01, 0x02, 0xe8, 0x08, 0x01, 0x02, 0xec, 0x08, 0x01, 0x02, 0xf0, 0x08, 0x01, 0x02, + 0xf4, 0x08, 0x01, 0x02, 0xf8, 0x08, 0x01, 0x02, 0x38, 0x25, 0x02, 0x03, 0x40, 0x25, 0x02, 0x03, 0x48, 0x25, 0x02, 0x03, 0x50, 0x25, 0x02, 0x03, 0x58, 0x25, 0x02, 0x03, 0x78, 0x06, 0x03, 0x03, + 0x80, 0x06, 0x03, 0x03, 0x88, 0x06, 0x03, 0x03, 0xf0, 0x21, 0x04, 0x04, 0x00, 0x22, 0x04, 0x04, 0x20, 0x04, 0x05, 0x04, 0xc0, 0x1e, 0x06, 0x05, 0x80, 0x01, 0x07, 0x05, 0x80, 0x3d, 0x09, 0x07, + 0x00, 0x20, 0x11, 0x0b, 0xf8, 0x16, 0x00, 0x03, 0x00, 0x17, 0x00, 0x03, 0x08, 0x17, 0x00, 0x03, 0xfc, 0x08, 0x01, 0x02, 0x00, 0x09, 0x01, 0x02, 0x04, 0x09, 0x01, 0x02, 0x08, 0x09, 0x01, 0x02, + 0x0c, 0x09, 0x01, 0x02, 0x10, 0x09, 0x01, 0x02, 0x60, 0x25, 0x02, 0x03, 0x68, 0x25, 0x02, 0x03, 0x70, 0x25, 0x02, 0x03, 0x78, 0x25, 0x02, 0x03, 0x80, 0x25, 0x02, 0x03, 0x90, 0x06, 0x03, 0x03, + 0x98, 0x06, 0x03, 0x03, 0xa0, 0x06, 0x03, 0x03, 0x10, 0x22, 0x04, 0x04, 0x20, 0x22, 0x04, 0x04, 0x30, 0x04, 0x05, 0x04, 0xe0, 0x1e, 0x06, 0x05, 0xa0, 0x01, 0x07, 0x05, 0x00, 0x3e, 0x09, 0x07, + 0x00, 0x08, 0x12, 0x0b, 0x10, 0x17, 0x00, 0x03, 0x18, 0x17, 0x00, 0x03, 0x20, 0x17, 0x00, 0x03, 0x14, 0x09, 0x01, 0x02, 0x18, 0x09, 0x01, 0x02, 0x1c, 0x09, 0x01, 0x02, 0x20, 0x09, 0x01, 0x02, + 0x24, 0x09, 0x01, 0x02, 0x28, 0x09, 0x01, 0x02, 0x88, 0x25, 0x02, 0x03, 0x90, 0x25, 0x02, 0x03, 0x98, 0x25, 0x02, 0x03, 0xa0, 0x25, 0x02, 0x03, 0xa8, 0x25, 0x02, 0x03, 0xa8, 0x06, 0x03, 0x03, + 0xb0, 0x06, 0x03, 0x03, 0xb8, 0x06, 0x03, 0x03, 0x30, 0x22, 0x04, 0x04, 0x40, 0x22, 0x04, 0x04, 0x40, 0x04, 0x05, 0x04, 0x00, 0x1f, 0x06, 0x05, 0xc0, 0x01, 0x07, 0x05, 0x80, 0x3e, 0x09, 0x07, + 0x00, 0x10, 0x12, 0x0b, 0x28, 0x17, 0x00, 0x03, 0x30, 0x17, 0x00, 0x03, 0x38, 0x17, 0x00, 0x03, 0x2c, 0x09, 0x01, 0x02, 0x30, 0x09, 0x01, 0x02, 0x34, 0x09, 0x01, 0x02, 0x38, 0x09, 0x01, 0x02, + 0x3c, 0x09, 0x01, 0x02, 0x40, 0x09, 0x01, 0x02, 0xb0, 0x25, 0x02, 0x03, 0xb8, 0x25, 0x02, 0x03, 0xc0, 0x25, 0x02, 0x03, 0xc8, 0x25, 0x02, 0x03, 0xd0, 0x25, 0x02, 0x03, 0xc0, 0x06, 0x03, 0x03, + 0xc8, 0x06, 0x03, 0x03, 0xd0, 0x06, 0x03, 0x03, 0x50, 0x22, 0x04, 0x04, 0x60, 0x22, 0x04, 0x04, 0x50, 0x04, 0x05, 0x04, 0x20, 0x1f, 0x06, 0x05, 0xe0, 0x01, 0x07, 0x05, 0x00, 0x3f, 0x09, 0x07, + 0x00, 0x20, 0x13, 0x0c, 0x40, 0x17, 0x00, 0x03, 0x48, 0x17, 0x00, 0x03, 0x50, 0x17, 0x00, 0x03, 0x44, 0x09, 0x01, 0x02, 0x48, 0x09, 0x01, 0x02, 0x4c, 0x09, 0x01, 0x02, 0x50, 0x09, 0x01, 0x02, + 0x54, 0x09, 0x01, 0x02, 0x58, 0x09, 0x01, 0x02, 0xd8, 0x25, 0x02, 0x03, 0xe0, 0x25, 0x02, 0x03, 0xe8, 0x25, 0x02, 0x03, 0xf0, 0x25, 0x02, 0x03, 0xf8, 0x25, 0x02, 0x03, 0xd8, 0x06, 0x03, 0x03, + 0xe0, 0x06, 0x03, 0x03, 0xe8, 0x06, 0x03, 0x03, 0x70, 0x22, 0x04, 0x04, 0x80, 0x22, 0x04, 0x04, 0x60, 0x04, 0x05, 0x04, 0x40, 0x1f, 0x06, 0x05, 0x00, 0x02, 0x07, 0x05, 0x80, 0x3f, 0x09, 0x07, + 0x00, 0x20, 0x15, 0x0d, 0x58, 0x17, 0x00, 0x03, 0x60, 0x17, 0x00, 0x03, 0x68, 0x17, 0x00, 0x03, 0x5c, 0x09, 0x01, 0x02, 0x60, 0x09, 0x01, 0x02, 0x64, 0x09, 0x01, 0x02, 0x68, 0x09, 0x01, 0x02, + 0x6c, 0x09, 0x01, 0x02, 0x70, 0x09, 0x01, 0x02, 0x00, 0x26, 0x02, 0x03, 0x08, 0x26, 0x02, 0x03, 0x10, 0x26, 0x02, 0x03, 0x18, 0x26, 0x02, 0x03, 0x20, 0x26, 0x02, 0x03, 0xf0, 0x06, 0x03, 0x03, + 0xf8, 0x06, 0x03, 0x03, 0x00, 0x07, 0x03, 0x03, 0x90, 0x22, 0x04, 0x04, 0xa0, 0x22, 0x04, 0x04, 0x70, 0x04, 0x05, 0x04, 0x60, 0x1f, 0x06, 0x05, 0x20, 0x02, 0x07, 0x05, 0x00, 0x00, 0x09, 0x06, + 0x70, 0x17, 0x00, 0x03, 0x78, 0x17, 0x00, 0x03, 0x80, 0x17, 0x00, 0x03, 0x88, 0x17, 0x00, 0x03, 0x74, 0x09, 0x01, 0x02, 0x78, 0x09, 0x01, 0x02, 0x7c, 0x09, 0x01, 0x02, 0x80, 0x09, 0x01, 0x02, + 0x84, 0x09, 0x01, 0x02, 0x88, 0x09, 0x01, 0x02, 0x28, 0x26, 0x02, 0x03, 0x30, 0x26, 0x02, 0x03, 0x38, 0x26, 0x02, 0x03, 0x40, 0x26, 0x02, 0x03, 0x48, 0x26, 0x02, 0x03, 0x08, 0x07, 0x03, 0x03, + 0x10, 0x07, 0x03, 0x03, 0x18, 0x07, 0x03, 0x03, 0xb0, 0x22, 0x04, 0x04, 0xc0, 0x22, 0x04, 0x04, 0x80, 0x04, 0x05, 0x04, 0x80, 0x1f, 0x06, 0x05, 0x40, 0x02, 0x07, 0x05, 0x40, 0x00, 0x09, 0x06, + 0x90, 0x17, 0x00, 0x03, 0x98, 0x17, 0x00, 0x03, 0xa0, 0x17, 0x00, 0x03, 0xa8, 0x17, 0x00, 0x03, 0x8c, 0x09, 0x01, 0x02, 0x90, 0x09, 0x01, 0x02, 0x94, 0x09, 0x01, 0x02, 0x98, 0x09, 0x01, 0x02, + 0x9c, 0x09, 0x01, 0x02, 0xa0, 0x09, 0x01, 0x02, 0x50, 0x26, 0x02, 0x03, 0x58, 0x26, 0x02, 0x03, 0x60, 0x26, 0x02, 0x03, 0x68, 0x26, 0x02, 0x03, 0x70, 0x26, 0x02, 0x03, 0x20, 0x07, 0x03, 0x03, + 0x28, 0x07, 0x03, 0x03, 0x30, 0x07, 0x03, 0x03, 0xd0, 0x22, 0x04, 0x04, 0xe0, 0x22, 0x04, 0x04, 0x90, 0x04, 0x05, 0x04, 0xa0, 0x1f, 0x06, 0x05, 0x60, 0x02, 0x07, 0x05, 0x80, 0x00, 0x09, 0x06, + 0xb0, 0x17, 0x00, 0x03, 0xb8, 0x17, 0x00, 0x03, 0xc0, 0x17, 0x00, 0x03, 0xc8, 0x17, 0x00, 0x03, 0xa4, 0x09, 0x01, 0x02, 0xa8, 0x09, 0x01, 0x02, 0xac, 0x09, 0x01, 0x02, 0xb0, 0x09, 0x01, 0x02, + 0xb4, 0x09, 0x01, 0x02, 0xb8, 0x09, 0x01, 0x02, 0x78, 0x26, 0x02, 0x03, 0x80, 0x26, 0x02, 0x03, 0x88, 0x26, 0x02, 0x03, 0x90, 0x26, 0x02, 0x03, 0x98, 0x26, 0x02, 0x03, 0x38, 0x07, 0x03, 0x03, + 0x40, 0x07, 0x03, 0x03, 0x48, 0x07, 0x03, 0x03, 0xf0, 0x22, 0x04, 0x04, 0x00, 0x23, 0x04, 0x04, 0xa0, 0x04, 0x05, 0x04, 0xc0, 0x1f, 0x06, 0x05, 0x80, 0x02, 0x07, 0x05, 0xc0, 0x00, 0x09, 0x06, + 0xd0, 0x17, 0x00, 0x03, 0xd8, 0x17, 0x00, 0x03, 0xe0, 0x17, 0x00, 0x03, 0xe8, 0x17, 0x00, 0x03, 0xbc, 0x09, 0x01, 0x02, 0xc0, 0x09, 0x01, 0x02, 0xc4, 0x09, 0x01, 0x02, 0xc8, 0x09, 0x01, 0x02, + 0xcc, 0x09, 0x01, 0x02, 0xd0, 0x09, 0x01, 0x02, 0xa0, 0x26, 0x02, 0x03, 0xa8, 0x26, 0x02, 0x03, 0xb0, 0x26, 0x02, 0x03, 0xb8, 0x26, 0x02, 0x03, 0xc0, 0x26, 0x02, 0x03, 0x50, 0x07, 0x03, 0x03, + 0x58, 0x07, 0x03, 0x03, 0x60, 0x07, 0x03, 0x03, 0x10, 0x23, 0x04, 0x04, 0x20, 0x23, 0x04, 0x04, 0xb0, 0x04, 0x05, 0x04, 0xe0, 0x1f, 0x06, 0x05, 0xa0, 0x02, 0x07, 0x05, 0x00, 0x01, 0x09, 0x06, + 0xf0, 0x17, 0x00, 0x03, 0xf8, 0x17, 0x00, 0x03, 0x00, 0x18, 0x00, 0x03, 0x08, 0x18, 0x00, 0x03, 0xd4, 0x09, 0x01, 0x02, 0xd8, 0x09, 0x01, 0x02, 0xdc, 0x09, 0x01, 0x02, 0xe0, 0x09, 0x01, 0x02, + 0xe4, 0x09, 0x01, 0x02, 0xe8, 0x09, 0x01, 0x02, 0xc8, 0x26, 0x02, 0x03, 0xd0, 0x26, 0x02, 0x03, 0xd8, 0x26, 0x02, 0x03, 0xe0, 0x26, 0x02, 0x03, 0xe8, 0x26, 0x02, 0x03, 0x68, 0x07, 0x03, 0x03, + 0x70, 0x07, 0x03, 0x03, 0x78, 0x07, 0x03, 0x03, 0x30, 0x23, 0x04, 0x04, 0x40, 0x23, 0x04, 0x04, 0xc0, 0x04, 0x05, 0x04, 0x00, 0x20, 0x06, 0x05, 0xc0, 0x02, 0x07, 0x05, 0x40, 0x01, 0x09, 0x06, + 0x10, 0x18, 0x00, 0x03, 0x18, 0x18, 0x00, 0x03, 0x20, 0x18, 0x00, 0x03, 0x28, 0x18, 0x00, 0x03, 0xec, 0x09, 0x01, 0x02, 0xf0, 0x09, 0x01, 0x02, 0xf4, 0x09, 0x01, 0x02, 0xf8, 0x09, 0x01, 0x02, + 0xfc, 0x09, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0xf0, 0x26, 0x02, 0x03, 0xf8, 0x26, 0x02, 0x03, 0x00, 0x27, 0x02, 0x03, 0x08, 0x27, 0x02, 0x03, 0x10, 0x27, 0x02, 0x03, 0x80, 0x07, 0x03, 0x03, + 0x88, 0x07, 0x03, 0x03, 0x90, 0x07, 0x03, 0x03, 0x50, 0x23, 0x04, 0x04, 0x60, 0x23, 0x04, 0x04, 0xd0, 0x04, 0x05, 0x04, 0x20, 0x20, 0x06, 0x05, 0xe0, 0x02, 0x07, 0x05, 0x80, 0x01, 0x09, 0x06, + 0x30, 0x18, 0x00, 0x03, 0x38, 0x18, 0x00, 0x03, 0x40, 0x18, 0x00, 0x03, 0x48, 0x18, 0x00, 0x03, 0x04, 0x0a, 0x01, 0x02, 0x08, 0x0a, 0x01, 0x02, 0x0c, 0x0a, 0x01, 0x02, 0x10, 0x0a, 0x01, 0x02, + 0x14, 0x0a, 0x01, 0x02, 0x18, 0x0a, 0x01, 0x02, 0x18, 0x27, 0x02, 0x03, 0x20, 0x27, 0x02, 0x03, 0x28, 0x27, 0x02, 0x03, 0x30, 0x27, 0x02, 0x03, 0x38, 0x27, 0x02, 0x03, 0x98, 0x07, 0x03, 0x03, + 0xa0, 0x07, 0x03, 0x03, 0xa8, 0x07, 0x03, 0x03, 0x70, 0x23, 0x04, 0x04, 0x80, 0x23, 0x04, 0x04, 0xe0, 0x04, 0x05, 0x04, 0x40, 0x20, 0x06, 0x05, 0x00, 0x03, 0x07, 0x05, 0xc0, 0x01, 0x09, 0x06, + 0x50, 0x18, 0x00, 0x03, 0x58, 0x18, 0x00, 0x03, 0x60, 0x18, 0x00, 0x03, 0x68, 0x18, 0x00, 0x03, 0x1c, 0x0a, 0x01, 0x02, 0x20, 0x0a, 0x01, 0x02, 0x24, 0x0a, 0x01, 0x02, 0x28, 0x0a, 0x01, 0x02, + 0x2c, 0x0a, 0x01, 0x02, 0x30, 0x0a, 0x01, 0x02, 0x40, 0x27, 0x02, 0x03, 0x48, 0x27, 0x02, 0x03, 0x50, 0x27, 0x02, 0x03, 0x58, 0x27, 0x02, 0x03, 0x60, 0x27, 0x02, 0x03, 0xb0, 0x07, 0x03, 0x03, + 0xb8, 0x07, 0x03, 0x03, 0xc0, 0x07, 0x03, 0x03, 0x90, 0x23, 0x04, 0x04, 0xa0, 0x23, 0x04, 0x04, 0xf0, 0x04, 0x05, 0x04, 0x60, 0x20, 0x06, 0x05, 0x20, 0x03, 0x07, 0x05, 0x00, 0x02, 0x09, 0x06, + 0x70, 0x18, 0x00, 0x03, 0x78, 0x18, 0x00, 0x03, 0x80, 0x18, 0x00, 0x03, 0x88, 0x18, 0x00, 0x03, 0x34, 0x0a, 0x01, 0x02, 0x38, 0x0a, 0x01, 0x02, 0x3c, 0x0a, 0x01, 0x02, 0x40, 0x0a, 0x01, 0x02, + 0x44, 0x0a, 0x01, 0x02, 0x48, 0x0a, 0x01, 0x02, 0x68, 0x27, 0x02, 0x03, 0x70, 0x27, 0x02, 0x03, 0x78, 0x27, 0x02, 0x03, 0x80, 0x27, 0x02, 0x03, 0x88, 0x27, 0x02, 0x03, 0xc8, 0x07, 0x03, 0x03, + 0xd0, 0x07, 0x03, 0x03, 0xd8, 0x07, 0x03, 0x03, 0xb0, 0x23, 0x04, 0x04, 0xc0, 0x23, 0x04, 0x04, 0x00, 0x05, 0x05, 0x04, 0x80, 0x20, 0x06, 0x05, 0x40, 0x03, 0x07, 0x05, 0x40, 0x02, 0x09, 0x06, + 0x90, 0x18, 0x00, 0x03, 0x98, 0x18, 0x00, 0x03, 0xa0, 0x18, 0x00, 0x03, 0xa8, 0x18, 0x00, 0x03, 0x4c, 0x0a, 0x01, 0x02, 0x50, 0x0a, 0x01, 0x02, 0x54, 0x0a, 0x01, 0x02, 0x58, 0x0a, 0x01, 0x02, + 0x5c, 0x0a, 0x01, 0x02, 0x60, 0x0a, 0x01, 0x02, 0x90, 0x27, 0x02, 0x03, 0x98, 0x27, 0x02, 0x03, 0xa0, 0x27, 0x02, 0x03, 0xa8, 0x27, 0x02, 0x03, 0xb0, 0x27, 0x02, 0x03, 0xe0, 0x07, 0x03, 0x03, + 0xe8, 0x07, 0x03, 0x03, 0xf0, 0x07, 0x03, 0x03, 0xd0, 0x23, 0x04, 0x04, 0xe0, 0x23, 0x04, 0x04, 0x10, 0x05, 0x05, 0x04, 0xa0, 0x20, 0x06, 0x05, 0x60, 0x03, 0x07, 0x05, 0x80, 0x02, 0x09, 0x06, + 0xb0, 0x18, 0x00, 0x03, 0xb8, 0x18, 0x00, 0x03, 0xc0, 0x18, 0x00, 0x03, 0xc8, 0x18, 0x00, 0x03, 0x64, 0x0a, 0x01, 0x02, 0x68, 0x0a, 0x01, 0x02, 0x6c, 0x0a, 0x01, 0x02, 0x70, 0x0a, 0x01, 0x02, + 0x74, 0x0a, 0x01, 0x02, 0x78, 0x0a, 0x01, 0x02, 0xb8, 0x27, 0x02, 0x03, 0xc0, 0x27, 0x02, 0x03, 0xc8, 0x27, 0x02, 0x03, 0xd0, 0x27, 0x02, 0x03, 0xd8, 0x27, 0x02, 0x03, 0xf8, 0x07, 0x03, 0x03, + 0x00, 0x08, 0x03, 0x03, 0x08, 0x08, 0x03, 0x03, 0xf0, 0x23, 0x04, 0x04, 0x00, 0x24, 0x04, 0x04, 0x20, 0x05, 0x05, 0x04, 0xc0, 0x20, 0x06, 0x05, 0x80, 0x03, 0x07, 0x05, 0xc0, 0x02, 0x09, 0x06, + 0xd0, 0x18, 0x00, 0x03, 0xd8, 0x18, 0x00, 0x03, 0xe0, 0x18, 0x00, 0x03, 0xe8, 0x18, 0x00, 0x03, 0x7c, 0x0a, 0x01, 0x02, 0x80, 0x0a, 0x01, 0x02, 0x84, 0x0a, 0x01, 0x02, 0x88, 0x0a, 0x01, 0x02, + 0x8c, 0x0a, 0x01, 0x02, 0x90, 0x0a, 0x01, 0x02, 0xe0, 0x27, 0x02, 0x03, 0xe8, 0x27, 0x02, 0x03, 0xf0, 0x27, 0x02, 0x03, 0xf8, 0x27, 0x02, 0x03, 0x00, 0x28, 0x02, 0x03, 0x10, 0x08, 0x03, 0x03, + 0x18, 0x08, 0x03, 0x03, 0x20, 0x08, 0x03, 0x03, 0x10, 0x24, 0x04, 0x04, 0x20, 0x24, 0x04, 0x04, 0x30, 0x05, 0x05, 0x04, 0xe0, 0x20, 0x06, 0x05, 0xa0, 0x03, 0x07, 0x05, 0x00, 0x03, 0x09, 0x06, + 0xf0, 0x18, 0x00, 0x03, 0xf8, 0x18, 0x00, 0x03, 0x00, 0x19, 0x00, 0x03, 0x08, 0x19, 0x00, 0x03, 0x94, 0x0a, 0x01, 0x02, 0x98, 0x0a, 0x01, 0x02, 0x9c, 0x0a, 0x01, 0x02, 0xa0, 0x0a, 0x01, 0x02, + 0xa4, 0x0a, 0x01, 0x02, 0xa8, 0x0a, 0x01, 0x02, 0x08, 0x28, 0x02, 0x03, 0x10, 0x28, 0x02, 0x03, 0x18, 0x28, 0x02, 0x03, 0x20, 0x28, 0x02, 0x03, 0x28, 0x28, 0x02, 0x03, 0x28, 0x08, 0x03, 0x03, + 0x30, 0x08, 0x03, 0x03, 0x38, 0x08, 0x03, 0x03, 0x30, 0x24, 0x04, 0x04, 0x40, 0x24, 0x04, 0x04, 0x40, 0x05, 0x05, 0x04, 0x00, 0x21, 0x06, 0x05, 0xc0, 0x03, 0x07, 0x05, 0x40, 0x03, 0x09, 0x06, + 0x10, 0x19, 0x00, 0x03, 0x18, 0x19, 0x00, 0x03, 0x20, 0x19, 0x00, 0x03, 0x28, 0x19, 0x00, 0x03, 0xac, 0x0a, 0x01, 0x02, 0xb0, 0x0a, 0x01, 0x02, 0xb4, 0x0a, 0x01, 0x02, 0xb8, 0x0a, 0x01, 0x02, + 0xbc, 0x0a, 0x01, 0x02, 0xc0, 0x0a, 0x01, 0x02, 0x30, 0x28, 0x02, 0x03, 0x38, 0x28, 0x02, 0x03, 0x40, 0x28, 0x02, 0x03, 0x48, 0x28, 0x02, 0x03, 0x50, 0x28, 0x02, 0x03, 0x40, 0x08, 0x03, 0x03, + 0x48, 0x08, 0x03, 0x03, 0x50, 0x08, 0x03, 0x03, 0x50, 0x24, 0x04, 0x04, 0x60, 0x24, 0x04, 0x04, 0x50, 0x05, 0x05, 0x04, 0x20, 0x21, 0x06, 0x05, 0xe0, 0x03, 0x07, 0x05, 0x80, 0x03, 0x09, 0x06, + 0x30, 0x19, 0x00, 0x03, 0x38, 0x19, 0x00, 0x03, 0x40, 0x19, 0x00, 0x03, 0x48, 0x19, 0x00, 0x03, 0xc4, 0x0a, 0x01, 0x02, 0xc8, 0x0a, 0x01, 0x02, 0xcc, 0x0a, 0x01, 0x02, 0xd0, 0x0a, 0x01, 0x02, + 0xd4, 0x0a, 0x01, 0x02, 0xd8, 0x0a, 0x01, 0x02, 0x58, 0x28, 0x02, 0x03, 0x60, 0x28, 0x02, 0x03, 0x68, 0x28, 0x02, 0x03, 0x70, 0x28, 0x02, 0x03, 0x78, 0x28, 0x02, 0x03, 0x58, 0x08, 0x03, 0x03, + 0x60, 0x08, 0x03, 0x03, 0x70, 0x24, 0x04, 0x04, 0x80, 0x24, 0x04, 0x04, 0x90, 0x24, 0x04, 0x04, 0x60, 0x05, 0x05, 0x04, 0x40, 0x21, 0x06, 0x05, 0x00, 0x04, 0x07, 0x05, 0xc0, 0x03, 0x09, 0x06, + 0x50, 0x19, 0x00, 0x03, 0x58, 0x19, 0x00, 0x03, 0x60, 0x19, 0x00, 0x03, 0x68, 0x19, 0x00, 0x03, 0xdc, 0x0a, 0x01, 0x02, 0xe0, 0x0a, 0x01, 0x02, 0xe4, 0x0a, 0x01, 0x02, 0xe8, 0x0a, 0x01, 0x02, + 0xec, 0x0a, 0x01, 0x02, 0xf0, 0x0a, 0x01, 0x02, 0x80, 0x28, 0x02, 0x03, 0x88, 0x28, 0x02, 0x03, 0x90, 0x28, 0x02, 0x03, 0x98, 0x28, 0x02, 0x03, 0x68, 0x08, 0x03, 0x03, 0x70, 0x08, 0x03, 0x03, + 0x78, 0x08, 0x03, 0x03, 0xa0, 0x24, 0x04, 0x04, 0xb0, 0x24, 0x04, 0x04, 0xc0, 0x24, 0x04, 0x04, 0x70, 0x05, 0x05, 0x04, 0x60, 0x21, 0x06, 0x05, 0x20, 0x04, 0x07, 0x05, 0x00, 0x04, 0x09, 0x06, + 0x70, 0x19, 0x00, 0x03, 0x78, 0x19, 0x00, 0x03, 0x80, 0x19, 0x00, 0x03, 0x88, 0x19, 0x00, 0x03, 0xf4, 0x0a, 0x01, 0x02, 0xf8, 0x0a, 0x01, 0x02, 0xfc, 0x0a, 0x01, 0x02, 0x00, 0x0b, 0x01, 0x02, + 0x04, 0x0b, 0x01, 0x02, 0x08, 0x0b, 0x01, 0x02, 0xa0, 0x28, 0x02, 0x03, 0xa8, 0x28, 0x02, 0x03, 0xb0, 0x28, 0x02, 0x03, 0xb8, 0x28, 0x02, 0x03, 0x80, 0x08, 0x03, 0x03, 0x88, 0x08, 0x03, 0x03, + 0x90, 0x08, 0x03, 0x03, 0xd0, 0x24, 0x04, 0x04, 0xe0, 0x24, 0x04, 0x04, 0xf0, 0x24, 0x04, 0x04, 0x80, 0x05, 0x05, 0x04, 0x80, 0x21, 0x06, 0x05, 0x40, 0x04, 0x07, 0x05, 0x40, 0x04, 0x09, 0x06, + 0x90, 0x19, 0x00, 0x03, 0x98, 0x19, 0x00, 0x03, 0xa0, 0x19, 0x00, 0x03, 0xa8, 0x19, 0x00, 0x03, 0x0c, 0x0b, 0x01, 0x02, 0x10, 0x0b, 0x01, 0x02, 0x14, 0x0b, 0x01, 0x02, 0x18, 0x0b, 0x01, 0x02, + 0x1c, 0x0b, 0x01, 0x02, 0x20, 0x0b, 0x01, 0x02, 0xc0, 0x28, 0x02, 0x03, 0xc8, 0x28, 0x02, 0x03, 0xd0, 0x28, 0x02, 0x03, 0xd8, 0x28, 0x02, 0x03, 0x98, 0x08, 0x03, 0x03, 0xa0, 0x08, 0x03, 0x03, + 0xa8, 0x08, 0x03, 0x03, 0x00, 0x25, 0x04, 0x04, 0x10, 0x25, 0x04, 0x04, 0x20, 0x25, 0x04, 0x04, 0x90, 0x05, 0x05, 0x04, 0xa0, 0x21, 0x06, 0x05, 0x60, 0x04, 0x07, 0x05, 0x80, 0x04, 0x09, 0x06, + 0xb0, 0x19, 0x00, 0x03, 0xb8, 0x19, 0x00, 0x03, 0xc0, 0x19, 0x00, 0x03, 0xc8, 0x19, 0x00, 0x03, 0x24, 0x0b, 0x01, 0x02, 0x28, 0x0b, 0x01, 0x02, 0x2c, 0x0b, 0x01, 0x02, 0x30, 0x0b, 0x01, 0x02, + 0x34, 0x0b, 0x01, 0x02, 0x38, 0x0b, 0x01, 0x02, 0xe0, 0x28, 0x02, 0x03, 0xe8, 0x28, 0x02, 0x03, 0xf0, 0x28, 0x02, 0x03, 0xf8, 0x28, 0x02, 0x03, 0xb0, 0x08, 0x03, 0x03, 0xb8, 0x08, 0x03, 0x03, + 0xc0, 0x08, 0x03, 0x03, 0x30, 0x25, 0x04, 0x04, 0x40, 0x25, 0x04, 0x04, 0x50, 0x25, 0x04, 0x04, 0xa0, 0x05, 0x05, 0x04, 0xc0, 0x21, 0x06, 0x05, 0x80, 0x04, 0x07, 0x05, 0xc0, 0x04, 0x09, 0x06, + 0xd0, 0x19, 0x00, 0x03, 0xd8, 0x19, 0x00, 0x03, 0xe0, 0x19, 0x00, 0x03, 0xe8, 0x19, 0x00, 0x03, 0x3c, 0x0b, 0x01, 0x02, 0x40, 0x0b, 0x01, 0x02, 0x44, 0x0b, 0x01, 0x02, 0x48, 0x0b, 0x01, 0x02, + 0x4c, 0x0b, 0x01, 0x02, 0x50, 0x0b, 0x01, 0x02, 0x00, 0x29, 0x02, 0x03, 0x08, 0x29, 0x02, 0x03, 0x10, 0x29, 0x02, 0x03, 0x18, 0x29, 0x02, 0x03, 0xc8, 0x08, 0x03, 0x03, 0xd0, 0x08, 0x03, 0x03, + 0xd8, 0x08, 0x03, 0x03, 0x60, 0x25, 0x04, 0x04, 0x70, 0x25, 0x04, 0x04, 0x80, 0x25, 0x04, 0x04, 0xb0, 0x05, 0x05, 0x04, 0xe0, 0x21, 0x06, 0x05, 0xa0, 0x04, 0x07, 0x05, 0x00, 0x19, 0x0a, 0x07, + 0xf0, 0x19, 0x00, 0x03, 0xf8, 0x19, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x03, 0x08, 0x1a, 0x00, 0x03, 0x54, 0x0b, 0x01, 0x02, 0x58, 0x0b, 0x01, 0x02, 0x5c, 0x0b, 0x01, 0x02, 0x60, 0x0b, 0x01, 0x02, + 0x64, 0x0b, 0x01, 0x02, 0x68, 0x0b, 0x01, 0x02, 0x20, 0x29, 0x02, 0x03, 0x28, 0x29, 0x02, 0x03, 0x30, 0x29, 0x02, 0x03, 0x38, 0x29, 0x02, 0x03, 0xe0, 0x08, 0x03, 0x03, 0xe8, 0x08, 0x03, 0x03, + 0xf0, 0x08, 0x03, 0x03, 0x90, 0x25, 0x04, 0x04, 0xa0, 0x25, 0x04, 0x04, 0xb0, 0x25, 0x04, 0x04, 0xc0, 0x05, 0x05, 0x04, 0x00, 0x22, 0x06, 0x05, 0xc0, 0x04, 0x07, 0x05, 0x80, 0x19, 0x0a, 0x07, + 0x10, 0x1a, 0x00, 0x03, 0x18, 0x1a, 0x00, 0x03, 0x20, 0x1a, 0x00, 0x03, 0x28, 0x1a, 0x00, 0x03, 0x6c, 0x0b, 0x01, 0x02, 0x70, 0x0b, 0x01, 0x02, 0x74, 0x0b, 0x01, 0x02, 0x78, 0x0b, 0x01, 0x02, + 0x7c, 0x0b, 0x01, 0x02, 0x80, 0x0b, 0x01, 0x02, 0x40, 0x29, 0x02, 0x03, 0x48, 0x29, 0x02, 0x03, 0x50, 0x29, 0x02, 0x03, 0x58, 0x29, 0x02, 0x03, 0xf8, 0x08, 0x03, 0x03, 0x00, 0x09, 0x03, 0x03, + 0x08, 0x09, 0x03, 0x03, 0xc0, 0x25, 0x04, 0x04, 0xd0, 0x25, 0x04, 0x04, 0xd0, 0x05, 0x05, 0x04, 0xe0, 0x05, 0x05, 0x04, 0x20, 0x22, 0x06, 0x05, 0xe0, 0x04, 0x07, 0x05, 0x00, 0x1a, 0x0a, 0x07, + 0x30, 0x1a, 0x00, 0x03, 0x38, 0x1a, 0x00, 0x03, 0x40, 0x1a, 0x00, 0x03, 0x48, 0x1a, 0x00, 0x03, 0x84, 0x0b, 0x01, 0x02, 0x88, 0x0b, 0x01, 0x02, 0x8c, 0x0b, 0x01, 0x02, 0x90, 0x0b, 0x01, 0x02, + 0x94, 0x0b, 0x01, 0x02, 0x98, 0x0b, 0x01, 0x02, 0x60, 0x29, 0x02, 0x03, 0x68, 0x29, 0x02, 0x03, 0x70, 0x29, 0x02, 0x03, 0x78, 0x29, 0x02, 0x03, 0x10, 0x09, 0x03, 0x03, 0x18, 0x09, 0x03, 0x03, + 0x20, 0x09, 0x03, 0x03, 0xe0, 0x25, 0x04, 0x04, 0xf0, 0x25, 0x04, 0x04, 0xf0, 0x05, 0x05, 0x04, 0x00, 0x06, 0x05, 0x04, 0x40, 0x22, 0x06, 0x05, 0x00, 0x05, 0x07, 0x05, 0x80, 0x1a, 0x0a, 0x07, + 0x50, 0x1a, 0x00, 0x03, 0x58, 0x1a, 0x00, 0x03, 0x60, 0x1a, 0x00, 0x03, 0x68, 0x1a, 0x00, 0x03, 0x9c, 0x0b, 0x01, 0x02, 0xa0, 0x0b, 0x01, 0x02, 0xa4, 0x0b, 0x01, 0x02, 0xa8, 0x0b, 0x01, 0x02, + 0xac, 0x0b, 0x01, 0x02, 0xb0, 0x0b, 0x01, 0x02, 0x80, 0x29, 0x02, 0x03, 0x88, 0x29, 0x02, 0x03, 0x90, 0x29, 0x02, 0x03, 0x98, 0x29, 0x02, 0x03, 0x28, 0x09, 0x03, 0x03, 0x30, 0x09, 0x03, 0x03, + 0x38, 0x09, 0x03, 0x03, 0x00, 0x26, 0x04, 0x04, 0x10, 0x26, 0x04, 0x04, 0x10, 0x06, 0x05, 0x04, 0x20, 0x06, 0x05, 0x04, 0x60, 0x22, 0x06, 0x05, 0x20, 0x05, 0x07, 0x05, 0x00, 0x1b, 0x0a, 0x07, + 0x70, 0x1a, 0x00, 0x03, 0x78, 0x1a, 0x00, 0x03, 0x80, 0x1a, 0x00, 0x03, 0x88, 0x1a, 0x00, 0x03, 0xb4, 0x0b, 0x01, 0x02, 0xb8, 0x0b, 0x01, 0x02, 0xbc, 0x0b, 0x01, 0x02, 0xc0, 0x0b, 0x01, 0x02, + 0xc4, 0x0b, 0x01, 0x02, 0xc8, 0x0b, 0x01, 0x02, 0xa0, 0x29, 0x02, 0x03, 0xa8, 0x29, 0x02, 0x03, 0xb0, 0x29, 0x02, 0x03, 0xb8, 0x29, 0x02, 0x03, 0x40, 0x09, 0x03, 0x03, 0x48, 0x09, 0x03, 0x03, + 0x50, 0x09, 0x03, 0x03, 0x20, 0x26, 0x04, 0x04, 0x30, 0x26, 0x04, 0x04, 0x30, 0x06, 0x05, 0x04, 0x40, 0x06, 0x05, 0x04, 0x80, 0x22, 0x06, 0x05, 0x40, 0x05, 0x07, 0x05, 0x80, 0x1b, 0x0a, 0x07, + 0x90, 0x1a, 0x00, 0x03, 0x98, 0x1a, 0x00, 0x03, 0xa0, 0x1a, 0x00, 0x03, 0xa8, 0x1a, 0x00, 0x03, 0xcc, 0x0b, 0x01, 0x02, 0xd0, 0x0b, 0x01, 0x02, 0xd4, 0x0b, 0x01, 0x02, 0xd8, 0x0b, 0x01, 0x02, + 0xdc, 0x0b, 0x01, 0x02, 0xe0, 0x0b, 0x01, 0x02, 0xc0, 0x29, 0x02, 0x03, 0xc8, 0x29, 0x02, 0x03, 0xd0, 0x29, 0x02, 0x03, 0xd8, 0x29, 0x02, 0x03, 0x58, 0x09, 0x03, 0x03, 0x60, 0x09, 0x03, 0x03, + 0x68, 0x09, 0x03, 0x03, 0x40, 0x26, 0x04, 0x04, 0x50, 0x26, 0x04, 0x04, 0x50, 0x06, 0x05, 0x04, 0x60, 0x06, 0x05, 0x04, 0xa0, 0x22, 0x06, 0x05, 0x60, 0x05, 0x07, 0x05, 0x00, 0x1c, 0x0a, 0x07, + 0xb0, 0x1a, 0x00, 0x03, 0xb8, 0x1a, 0x00, 0x03, 0xc0, 0x1a, 0x00, 0x03, 0xc8, 0x1a, 0x00, 0x03, 0xe4, 0x0b, 0x01, 0x02, 0xe8, 0x0b, 0x01, 0x02, 0xec, 0x0b, 0x01, 0x02, 0xf0, 0x0b, 0x01, 0x02, + 0xf4, 0x0b, 0x01, 0x02, 0xf8, 0x0b, 0x01, 0x02, 0xe0, 0x29, 0x02, 0x03, 0xe8, 0x29, 0x02, 0x03, 0xf0, 0x29, 0x02, 0x03, 0xf8, 0x29, 0x02, 0x03, 0x70, 0x09, 0x03, 0x03, 0x78, 0x09, 0x03, 0x03, + 0x80, 0x09, 0x03, 0x03, 0x60, 0x26, 0x04, 0x04, 0x70, 0x26, 0x04, 0x04, 0x70, 0x06, 0x05, 0x04, 0x80, 0x06, 0x05, 0x04, 0xc0, 0x22, 0x06, 0x05, 0x80, 0x05, 0x07, 0x05, 0x80, 0x1c, 0x0a, 0x07, + 0xd0, 0x1a, 0x00, 0x03, 0xd8, 0x1a, 0x00, 0x03, 0xe0, 0x1a, 0x00, 0x03, 0xe8, 0x1a, 0x00, 0x03, 0xfc, 0x0b, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x04, 0x0c, 0x01, 0x02, 0x08, 0x0c, 0x01, 0x02, + 0x0c, 0x0c, 0x01, 0x02, 0x10, 0x0c, 0x01, 0x02, 0x00, 0x2a, 0x02, 0x03, 0x08, 0x2a, 0x02, 0x03, 0x10, 0x2a, 0x02, 0x03, 0x18, 0x2a, 0x02, 0x03, 0x88, 0x09, 0x03, 0x03, 0x90, 0x09, 0x03, 0x03, + 0x98, 0x09, 0x03, 0x03, 0x80, 0x26, 0x04, 0x04, 0x90, 0x26, 0x04, 0x04, 0x90, 0x06, 0x05, 0x04, 0xa0, 0x06, 0x05, 0x04, 0xe0, 0x22, 0x06, 0x05, 0xa0, 0x05, 0x07, 0x05, 0x00, 0x1d, 0x0a, 0x07, + 0xf0, 0x1a, 0x00, 0x03, 0xf8, 0x1a, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x03, 0x08, 0x1b, 0x00, 0x03, 0x14, 0x0c, 0x01, 0x02, 0x18, 0x0c, 0x01, 0x02, 0x1c, 0x0c, 0x01, 0x02, 0x20, 0x0c, 0x01, 0x02, + 0x24, 0x0c, 0x01, 0x02, 0x28, 0x0c, 0x01, 0x02, 0x20, 0x2a, 0x02, 0x03, 0x28, 0x2a, 0x02, 0x03, 0x30, 0x2a, 0x02, 0x03, 0x38, 0x2a, 0x02, 0x03, 0xa0, 0x09, 0x03, 0x03, 0xa8, 0x09, 0x03, 0x03, + 0xb0, 0x09, 0x03, 0x03, 0xa0, 0x26, 0x04, 0x04, 0xb0, 0x26, 0x04, 0x04, 0xb0, 0x06, 0x05, 0x04, 0xc0, 0x06, 0x05, 0x04, 0x00, 0x23, 0x06, 0x05, 0xc0, 0x05, 0x07, 0x05, 0x80, 0x1d, 0x0a, 0x07, + 0x10, 0x1b, 0x00, 0x03, 0x18, 0x1b, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x03, 0x28, 0x1b, 0x00, 0x03, 0x2c, 0x0c, 0x01, 0x02, 0x30, 0x0c, 0x01, 0x02, 0x34, 0x0c, 0x01, 0x02, 0x38, 0x0c, 0x01, 0x02, + 0x3c, 0x0c, 0x01, 0x02, 0x40, 0x0c, 0x01, 0x02, 0x40, 0x2a, 0x02, 0x03, 0x48, 0x2a, 0x02, 0x03, 0x50, 0x2a, 0x02, 0x03, 0x58, 0x2a, 0x02, 0x03, 0xb8, 0x09, 0x03, 0x03, 0xc0, 0x09, 0x03, 0x03, + 0xc8, 0x09, 0x03, 0x03, 0xc0, 0x26, 0x04, 0x04, 0xd0, 0x26, 0x04, 0x04, 0xd0, 0x06, 0x05, 0x04, 0xe0, 0x06, 0x05, 0x04, 0x20, 0x23, 0x06, 0x05, 0xe0, 0x05, 0x07, 0x05, 0x00, 0x1e, 0x0a, 0x07, + 0x30, 0x1b, 0x00, 0x03, 0x38, 0x1b, 0x00, 0x03, 0x40, 0x1b, 0x00, 0x03, 0x48, 0x1b, 0x00, 0x03, 0x44, 0x0c, 0x01, 0x02, 0x48, 0x0c, 0x01, 0x02, 0x4c, 0x0c, 0x01, 0x02, 0x50, 0x0c, 0x01, 0x02, + 0x54, 0x0c, 0x01, 0x02, 0x58, 0x0c, 0x01, 0x02, 0x60, 0x2a, 0x02, 0x03, 0x68, 0x2a, 0x02, 0x03, 0x70, 0x2a, 0x02, 0x03, 0x78, 0x2a, 0x02, 0x03, 0xd0, 0x09, 0x03, 0x03, 0xd8, 0x09, 0x03, 0x03, + 0xe0, 0x09, 0x03, 0x03, 0xe0, 0x26, 0x04, 0x04, 0xf0, 0x26, 0x04, 0x04, 0xf0, 0x06, 0x05, 0x04, 0x00, 0x07, 0x05, 0x04, 0x40, 0x23, 0x06, 0x05, 0x00, 0x06, 0x07, 0x05, 0x80, 0x1e, 0x0a, 0x07, + 0x50, 0x1b, 0x00, 0x03, 0x58, 0x1b, 0x00, 0x03, 0x60, 0x1b, 0x00, 0x03, 0x68, 0x1b, 0x00, 0x03, 0x5c, 0x0c, 0x01, 0x02, 0x60, 0x0c, 0x01, 0x02, 0x64, 0x0c, 0x01, 0x02, 0x68, 0x0c, 0x01, 0x02, + 0x6c, 0x0c, 0x01, 0x02, 0x70, 0x0c, 0x01, 0x02, 0x80, 0x2a, 0x02, 0x03, 0x88, 0x2a, 0x02, 0x03, 0x90, 0x2a, 0x02, 0x03, 0x98, 0x2a, 0x02, 0x03, 0xe8, 0x09, 0x03, 0x03, 0xf0, 0x09, 0x03, 0x03, + 0xf8, 0x09, 0x03, 0x03, 0x00, 0x27, 0x04, 0x04, 0x10, 0x27, 0x04, 0x04, 0x10, 0x07, 0x05, 0x04, 0x20, 0x07, 0x05, 0x04, 0x60, 0x23, 0x06, 0x05, 0x20, 0x06, 0x07, 0x05, 0x00, 0x1f, 0x0a, 0x07, + 0x70, 0x1b, 0x00, 0x03, 0x78, 0x1b, 0x00, 0x03, 0x80, 0x1b, 0x00, 0x03, 0x88, 0x1b, 0x00, 0x03, 0x74, 0x0c, 0x01, 0x02, 0x78, 0x0c, 0x01, 0x02, 0x7c, 0x0c, 0x01, 0x02, 0x80, 0x0c, 0x01, 0x02, + 0x84, 0x0c, 0x01, 0x02, 0x88, 0x0c, 0x01, 0x02, 0xa0, 0x2a, 0x02, 0x03, 0xa8, 0x2a, 0x02, 0x03, 0xb0, 0x2a, 0x02, 0x03, 0xb8, 0x2a, 0x02, 0x03, 0x00, 0x0a, 0x03, 0x03, 0x08, 0x0a, 0x03, 0x03, + 0x10, 0x0a, 0x03, 0x03, 0x20, 0x27, 0x04, 0x04, 0x30, 0x27, 0x04, 0x04, 0x30, 0x07, 0x05, 0x04, 0x40, 0x07, 0x05, 0x04, 0x80, 0x23, 0x06, 0x05, 0x40, 0x06, 0x07, 0x05, 0x80, 0x1f, 0x0a, 0x07, + 0x90, 0x1b, 0x00, 0x03, 0x98, 0x1b, 0x00, 0x03, 0xa0, 0x1b, 0x00, 0x03, 0xa8, 0x1b, 0x00, 0x03, 0x8c, 0x0c, 0x01, 0x02, 0x90, 0x0c, 0x01, 0x02, 0x94, 0x0c, 0x01, 0x02, 0x98, 0x0c, 0x01, 0x02, + 0x9c, 0x0c, 0x01, 0x02, 0xa0, 0x0c, 0x01, 0x02, 0xc0, 0x2a, 0x02, 0x03, 0xc8, 0x2a, 0x02, 0x03, 0xd0, 0x2a, 0x02, 0x03, 0xd8, 0x2a, 0x02, 0x03, 0x18, 0x0a, 0x03, 0x03, 0x20, 0x0a, 0x03, 0x03, + 0x28, 0x0a, 0x03, 0x03, 0x40, 0x27, 0x04, 0x04, 0x50, 0x27, 0x04, 0x04, 0x50, 0x07, 0x05, 0x04, 0x60, 0x07, 0x05, 0x04, 0xa0, 0x23, 0x06, 0x05, 0x60, 0x06, 0x07, 0x05, 0x00, 0x20, 0x0a, 0x07, + 0xb0, 0x1b, 0x00, 0x03, 0xb8, 0x1b, 0x00, 0x03, 0xc0, 0x1b, 0x00, 0x03, 0xc8, 0x1b, 0x00, 0x03, 0xa4, 0x0c, 0x01, 0x02, 0xa8, 0x0c, 0x01, 0x02, 0xac, 0x0c, 0x01, 0x02, 0xb0, 0x0c, 0x01, 0x02, + 0xb4, 0x0c, 0x01, 0x02, 0xb8, 0x0c, 0x01, 0x02, 0xe0, 0x2a, 0x02, 0x03, 0xe8, 0x2a, 0x02, 0x03, 0xf0, 0x2a, 0x02, 0x03, 0xf8, 0x2a, 0x02, 0x03, 0x30, 0x0a, 0x03, 0x03, 0x38, 0x0a, 0x03, 0x03, + 0x40, 0x0a, 0x03, 0x03, 0x60, 0x27, 0x04, 0x04, 0x70, 0x27, 0x04, 0x04, 0x70, 0x07, 0x05, 0x04, 0x80, 0x07, 0x05, 0x04, 0xc0, 0x23, 0x06, 0x05, 0x00, 0x1c, 0x08, 0x06, 0x80, 0x20, 0x0a, 0x07, + 0xd0, 0x1b, 0x00, 0x03, 0xd8, 0x1b, 0x00, 0x03, 0xe0, 0x1b, 0x00, 0x03, 0xe8, 0x1b, 0x00, 0x03, 0xbc, 0x0c, 0x01, 0x02, 0xc0, 0x0c, 0x01, 0x02, 0xc4, 0x0c, 0x01, 0x02, 0xc8, 0x0c, 0x01, 0x02, + 0xcc, 0x0c, 0x01, 0x02, 0xd0, 0x0c, 0x01, 0x02, 0x00, 0x2b, 0x02, 0x03, 0x08, 0x2b, 0x02, 0x03, 0x10, 0x2b, 0x02, 0x03, 0x18, 0x2b, 0x02, 0x03, 0x48, 0x0a, 0x03, 0x03, 0x50, 0x0a, 0x03, 0x03, + 0x58, 0x0a, 0x03, 0x03, 0x80, 0x27, 0x04, 0x04, 0x90, 0x27, 0x04, 0x04, 0x90, 0x07, 0x05, 0x04, 0xa0, 0x07, 0x05, 0x04, 0xe0, 0x23, 0x06, 0x05, 0x40, 0x1c, 0x08, 0x06, 0x00, 0x21, 0x0a, 0x07, + 0xf0, 0x1b, 0x00, 0x03, 0xf8, 0x1b, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x03, 0x08, 0x1c, 0x00, 0x03, 0xd4, 0x0c, 0x01, 0x02, 0xd8, 0x0c, 0x01, 0x02, 0xdc, 0x0c, 0x01, 0x02, 0xe0, 0x0c, 0x01, 0x02, + 0xe4, 0x0c, 0x01, 0x02, 0xe8, 0x0c, 0x01, 0x02, 0x20, 0x2b, 0x02, 0x03, 0x28, 0x2b, 0x02, 0x03, 0x30, 0x2b, 0x02, 0x03, 0x38, 0x2b, 0x02, 0x03, 0x60, 0x0a, 0x03, 0x03, 0x68, 0x0a, 0x03, 0x03, + 0x70, 0x0a, 0x03, 0x03, 0xa0, 0x27, 0x04, 0x04, 0xb0, 0x27, 0x04, 0x04, 0xb0, 0x07, 0x05, 0x04, 0xc0, 0x07, 0x05, 0x04, 0x00, 0x24, 0x06, 0x05, 0x80, 0x1c, 0x08, 0x06, 0x80, 0x21, 0x0a, 0x07, + 0x10, 0x1c, 0x00, 0x03, 0x18, 0x1c, 0x00, 0x03, 0x20, 0x1c, 0x00, 0x03, 0x28, 0x1c, 0x00, 0x03, 0xec, 0x0c, 0x01, 0x02, 0xf0, 0x0c, 0x01, 0x02, 0xf4, 0x0c, 0x01, 0x02, 0xf8, 0x0c, 0x01, 0x02, + 0xfc, 0x0c, 0x01, 0x02, 0x00, 0x0d, 0x01, 0x02, 0x40, 0x2b, 0x02, 0x03, 0x48, 0x2b, 0x02, 0x03, 0x50, 0x2b, 0x02, 0x03, 0x58, 0x2b, 0x02, 0x03, 0x78, 0x0a, 0x03, 0x03, 0x80, 0x0a, 0x03, 0x03, + 0x88, 0x0a, 0x03, 0x03, 0xc0, 0x27, 0x04, 0x04, 0xd0, 0x27, 0x04, 0x04, 0xd0, 0x07, 0x05, 0x04, 0xe0, 0x07, 0x05, 0x04, 0x20, 0x24, 0x06, 0x05, 0xc0, 0x1c, 0x08, 0x06, 0x00, 0x22, 0x0a, 0x07, + 0x30, 0x1c, 0x00, 0x03, 0x38, 0x1c, 0x00, 0x03, 0x40, 0x1c, 0x00, 0x03, 0x48, 0x1c, 0x00, 0x03, 0x04, 0x0d, 0x01, 0x02, 0x08, 0x0d, 0x01, 0x02, 0x0c, 0x0d, 0x01, 0x02, 0x10, 0x0d, 0x01, 0x02, + 0x14, 0x0d, 0x01, 0x02, 0x18, 0x0d, 0x01, 0x02, 0x60, 0x2b, 0x02, 0x03, 0x68, 0x2b, 0x02, 0x03, 0x70, 0x2b, 0x02, 0x03, 0x78, 0x2b, 0x02, 0x03, 0x90, 0x0a, 0x03, 0x03, 0x98, 0x0a, 0x03, 0x03, + 0xa0, 0x0a, 0x03, 0x03, 0xe0, 0x27, 0x04, 0x04, 0xf0, 0x27, 0x04, 0x04, 0xf0, 0x07, 0x05, 0x04, 0x00, 0x08, 0x05, 0x04, 0x40, 0x24, 0x06, 0x05, 0x00, 0x1d, 0x08, 0x06, 0x80, 0x22, 0x0a, 0x07, + 0x50, 0x1c, 0x00, 0x03, 0x58, 0x1c, 0x00, 0x03, 0x60, 0x1c, 0x00, 0x03, 0x68, 0x1c, 0x00, 0x03, 0x1c, 0x0d, 0x01, 0x02, 0x20, 0x0d, 0x01, 0x02, 0x24, 0x0d, 0x01, 0x02, 0x28, 0x0d, 0x01, 0x02, + 0x2c, 0x0d, 0x01, 0x02, 0x30, 0x0d, 0x01, 0x02, 0x80, 0x2b, 0x02, 0x03, 0x88, 0x2b, 0x02, 0x03, 0x90, 0x2b, 0x02, 0x03, 0x98, 0x2b, 0x02, 0x03, 0xa8, 0x0a, 0x03, 0x03, 0xb0, 0x0a, 0x03, 0x03, + 0xb8, 0x0a, 0x03, 0x03, 0x00, 0x28, 0x04, 0x04, 0x10, 0x28, 0x04, 0x04, 0x10, 0x08, 0x05, 0x04, 0x20, 0x08, 0x05, 0x04, 0x60, 0x24, 0x06, 0x05, 0x40, 0x1d, 0x08, 0x06, 0x00, 0x3c, 0x0b, 0x08, + 0x70, 0x1c, 0x00, 0x03, 0x78, 0x1c, 0x00, 0x03, 0x80, 0x1c, 0x00, 0x03, 0x88, 0x1c, 0x00, 0x03, 0x34, 0x0d, 0x01, 0x02, 0x38, 0x0d, 0x01, 0x02, 0x3c, 0x0d, 0x01, 0x02, 0x40, 0x0d, 0x01, 0x02, + 0x44, 0x0d, 0x01, 0x02, 0x48, 0x0d, 0x01, 0x02, 0xa0, 0x2b, 0x02, 0x03, 0xa8, 0x2b, 0x02, 0x03, 0xb0, 0x2b, 0x02, 0x03, 0xb8, 0x2b, 0x02, 0x03, 0xc0, 0x0a, 0x03, 0x03, 0xc8, 0x0a, 0x03, 0x03, + 0xd0, 0x0a, 0x03, 0x03, 0x20, 0x28, 0x04, 0x04, 0x30, 0x28, 0x04, 0x04, 0x30, 0x08, 0x05, 0x04, 0x40, 0x08, 0x05, 0x04, 0x80, 0x24, 0x06, 0x05, 0x80, 0x1d, 0x08, 0x06, 0x00, 0x3d, 0x0b, 0x08, + 0x90, 0x1c, 0x00, 0x03, 0x98, 0x1c, 0x00, 0x03, 0xa0, 0x1c, 0x00, 0x03, 0xa8, 0x1c, 0x00, 0x03, 0x4c, 0x0d, 0x01, 0x02, 0x50, 0x0d, 0x01, 0x02, 0x54, 0x0d, 0x01, 0x02, 0x58, 0x0d, 0x01, 0x02, + 0x5c, 0x0d, 0x01, 0x02, 0x60, 0x0d, 0x01, 0x02, 0xc0, 0x2b, 0x02, 0x03, 0xc8, 0x2b, 0x02, 0x03, 0xd0, 0x2b, 0x02, 0x03, 0xd8, 0x2b, 0x02, 0x03, 0xd8, 0x0a, 0x03, 0x03, 0xe0, 0x0a, 0x03, 0x03, + 0xe8, 0x0a, 0x03, 0x03, 0x40, 0x28, 0x04, 0x04, 0x50, 0x28, 0x04, 0x04, 0x50, 0x08, 0x05, 0x04, 0x60, 0x08, 0x05, 0x04, 0xa0, 0x24, 0x06, 0x05, 0xc0, 0x1d, 0x08, 0x06, 0x00, 0x3e, 0x0b, 0x08, + 0xb0, 0x1c, 0x00, 0x03, 0xb8, 0x1c, 0x00, 0x03, 0xc0, 0x1c, 0x00, 0x03, 0xc8, 0x1c, 0x00, 0x03, 0x64, 0x0d, 0x01, 0x02, 0x68, 0x0d, 0x01, 0x02, 0x6c, 0x0d, 0x01, 0x02, 0x70, 0x0d, 0x01, 0x02, + 0x74, 0x0d, 0x01, 0x02, 0x78, 0x0d, 0x01, 0x02, 0xe0, 0x2b, 0x02, 0x03, 0xe8, 0x2b, 0x02, 0x03, 0xf0, 0x2b, 0x02, 0x03, 0xf8, 0x2b, 0x02, 0x03, 0xf0, 0x0a, 0x03, 0x03, 0xf8, 0x0a, 0x03, 0x03, + 0x00, 0x0b, 0x03, 0x03, 0x60, 0x28, 0x04, 0x04, 0x70, 0x28, 0x04, 0x04, 0x70, 0x08, 0x05, 0x04, 0x80, 0x08, 0x05, 0x04, 0xc0, 0x24, 0x06, 0x05, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x3f, 0x0b, 0x08, + 0xd0, 0x1c, 0x00, 0x03, 0xd8, 0x1c, 0x00, 0x03, 0xe0, 0x1c, 0x00, 0x03, 0xe8, 0x1c, 0x00, 0x03, 0x7c, 0x0d, 0x01, 0x02, 0x80, 0x0d, 0x01, 0x02, 0x84, 0x0d, 0x01, 0x02, 0x88, 0x0d, 0x01, 0x02, + 0x8c, 0x0d, 0x01, 0x02, 0x90, 0x0d, 0x01, 0x02, 0x00, 0x2c, 0x02, 0x03, 0x08, 0x2c, 0x02, 0x03, 0x10, 0x2c, 0x02, 0x03, 0x18, 0x2c, 0x02, 0x03, 0x08, 0x0b, 0x03, 0x03, 0x10, 0x0b, 0x03, 0x03, + 0x18, 0x0b, 0x03, 0x03, 0x80, 0x28, 0x04, 0x04, 0x90, 0x28, 0x04, 0x04, 0x90, 0x08, 0x05, 0x04, 0xa0, 0x08, 0x05, 0x04, 0xe0, 0x24, 0x06, 0x05, 0x40, 0x1e, 0x08, 0x06, 0x00, 0x00, 0x0b, 0x07, + 0xf0, 0x1c, 0x00, 0x03, 0xf8, 0x1c, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x03, 0x08, 0x1d, 0x00, 0x03, 0x94, 0x0d, 0x01, 0x02, 0x98, 0x0d, 0x01, 0x02, 0x9c, 0x0d, 0x01, 0x02, 0xa0, 0x0d, 0x01, 0x02, + 0xa4, 0x0d, 0x01, 0x02, 0xa8, 0x0d, 0x01, 0x02, 0x20, 0x2c, 0x02, 0x03, 0x28, 0x2c, 0x02, 0x03, 0x30, 0x2c, 0x02, 0x03, 0x38, 0x2c, 0x02, 0x03, 0x20, 0x0b, 0x03, 0x03, 0x28, 0x0b, 0x03, 0x03, + 0x30, 0x0b, 0x03, 0x03, 0xa0, 0x28, 0x04, 0x04, 0xb0, 0x28, 0x04, 0x04, 0xb0, 0x08, 0x05, 0x04, 0xc0, 0x08, 0x05, 0x04, 0x00, 0x25, 0x06, 0x05, 0x80, 0x1e, 0x08, 0x06, 0x80, 0x00, 0x0b, 0x07, + 0x10, 0x1d, 0x00, 0x03, 0x18, 0x1d, 0x00, 0x03, 0x20, 0x1d, 0x00, 0x03, 0x28, 0x1d, 0x00, 0x03, 0xac, 0x0d, 0x01, 0x02, 0xb0, 0x0d, 0x01, 0x02, 0xb4, 0x0d, 0x01, 0x02, 0xb8, 0x0d, 0x01, 0x02, + 0xbc, 0x0d, 0x01, 0x02, 0xc0, 0x0d, 0x01, 0x02, 0x40, 0x2c, 0x02, 0x03, 0x48, 0x2c, 0x02, 0x03, 0x50, 0x2c, 0x02, 0x03, 0x58, 0x2c, 0x02, 0x03, 0x38, 0x0b, 0x03, 0x03, 0x40, 0x0b, 0x03, 0x03, + 0x48, 0x0b, 0x03, 0x03, 0xc0, 0x28, 0x04, 0x04, 0xd0, 0x28, 0x04, 0x04, 0xd0, 0x08, 0x05, 0x04, 0xe0, 0x08, 0x05, 0x04, 0x20, 0x25, 0x06, 0x05, 0xc0, 0x1e, 0x08, 0x06, 0x00, 0x01, 0x0b, 0x07, + 0x30, 0x1d, 0x00, 0x03, 0x38, 0x1d, 0x00, 0x03, 0x40, 0x1d, 0x00, 0x03, 0x48, 0x1d, 0x00, 0x03, 0xc4, 0x0d, 0x01, 0x02, 0xc8, 0x0d, 0x01, 0x02, 0xcc, 0x0d, 0x01, 0x02, 0xd0, 0x0d, 0x01, 0x02, + 0xd4, 0x0d, 0x01, 0x02, 0xd8, 0x0d, 0x01, 0x02, 0x60, 0x2c, 0x02, 0x03, 0x68, 0x2c, 0x02, 0x03, 0x70, 0x2c, 0x02, 0x03, 0x78, 0x2c, 0x02, 0x03, 0x50, 0x0b, 0x03, 0x03, 0x58, 0x0b, 0x03, 0x03, + 0x60, 0x0b, 0x03, 0x03, 0xe0, 0x28, 0x04, 0x04, 0xf0, 0x28, 0x04, 0x04, 0xf0, 0x08, 0x05, 0x04, 0x00, 0x09, 0x05, 0x04, 0x40, 0x25, 0x06, 0x05, 0x00, 0x1f, 0x08, 0x06, 0x80, 0x01, 0x0b, 0x07, + 0x50, 0x1d, 0x00, 0x03, 0x58, 0x1d, 0x00, 0x03, 0x60, 0x1d, 0x00, 0x03, 0x68, 0x1d, 0x00, 0x03, 0xdc, 0x0d, 0x01, 0x02, 0xe0, 0x0d, 0x01, 0x02, 0xe4, 0x0d, 0x01, 0x02, 0xe8, 0x0d, 0x01, 0x02, + 0xec, 0x0d, 0x01, 0x02, 0xf0, 0x0d, 0x01, 0x02, 0x80, 0x2c, 0x02, 0x03, 0x88, 0x2c, 0x02, 0x03, 0x90, 0x2c, 0x02, 0x03, 0x98, 0x2c, 0x02, 0x03, 0x68, 0x0b, 0x03, 0x03, 0x70, 0x0b, 0x03, 0x03, + 0x78, 0x0b, 0x03, 0x03, 0x00, 0x29, 0x04, 0x04, 0x10, 0x29, 0x04, 0x04, 0x10, 0x09, 0x05, 0x04, 0x20, 0x09, 0x05, 0x04, 0x60, 0x25, 0x06, 0x05, 0x40, 0x1f, 0x08, 0x06, 0x00, 0x02, 0x0b, 0x07, + 0x70, 0x1d, 0x00, 0x03, 0x78, 0x1d, 0x00, 0x03, 0x80, 0x1d, 0x00, 0x03, 0x88, 0x1d, 0x00, 0x03, 0xf4, 0x0d, 0x01, 0x02, 0xf8, 0x0d, 0x01, 0x02, 0xfc, 0x0d, 0x01, 0x02, 0x00, 0x0e, 0x01, 0x02, + 0x04, 0x0e, 0x01, 0x02, 0x08, 0x0e, 0x01, 0x02, 0xa0, 0x2c, 0x02, 0x03, 0xa8, 0x2c, 0x02, 0x03, 0xb0, 0x2c, 0x02, 0x03, 0xb8, 0x2c, 0x02, 0x03, 0x80, 0x0b, 0x03, 0x03, 0x88, 0x0b, 0x03, 0x03, + 0x90, 0x0b, 0x03, 0x03, 0x20, 0x29, 0x04, 0x04, 0x30, 0x29, 0x04, 0x04, 0x30, 0x09, 0x05, 0x04, 0x40, 0x09, 0x05, 0x04, 0x80, 0x25, 0x06, 0x05, 0x80, 0x1f, 0x08, 0x06, 0x80, 0x02, 0x0b, 0x07, + 0x90, 0x1d, 0x00, 0x03, 0x98, 0x1d, 0x00, 0x03, 0xa0, 0x1d, 0x00, 0x03, 0xa8, 0x1d, 0x00, 0x03, 0x0c, 0x0e, 0x01, 0x02, 0x10, 0x0e, 0x01, 0x02, 0x14, 0x0e, 0x01, 0x02, 0x18, 0x0e, 0x01, 0x02, + 0x1c, 0x0e, 0x01, 0x02, 0x20, 0x0e, 0x01, 0x02, 0xc0, 0x2c, 0x02, 0x03, 0xc8, 0x2c, 0x02, 0x03, 0xd0, 0x2c, 0x02, 0x03, 0xd8, 0x2c, 0x02, 0x03, 0x98, 0x0b, 0x03, 0x03, 0xa0, 0x0b, 0x03, 0x03, + 0xa8, 0x0b, 0x03, 0x03, 0x40, 0x29, 0x04, 0x04, 0x50, 0x29, 0x04, 0x04, 0x50, 0x09, 0x05, 0x04, 0x60, 0x09, 0x05, 0x04, 0xa0, 0x25, 0x06, 0x05, 0xc0, 0x1f, 0x08, 0x06, 0x00, 0x03, 0x0b, 0x07, + 0xb0, 0x1d, 0x00, 0x03, 0xb8, 0x1d, 0x00, 0x03, 0xc0, 0x1d, 0x00, 0x03, 0xc8, 0x1d, 0x00, 0x03, 0x24, 0x0e, 0x01, 0x02, 0x28, 0x0e, 0x01, 0x02, 0x2c, 0x0e, 0x01, 0x02, 0x30, 0x0e, 0x01, 0x02, + 0x34, 0x0e, 0x01, 0x02, 0x38, 0x0e, 0x01, 0x02, 0xe0, 0x2c, 0x02, 0x03, 0xe8, 0x2c, 0x02, 0x03, 0xf0, 0x2c, 0x02, 0x03, 0xf8, 0x2c, 0x02, 0x03, 0xb0, 0x0b, 0x03, 0x03, 0xb8, 0x0b, 0x03, 0x03, + 0xc0, 0x0b, 0x03, 0x03, 0x60, 0x29, 0x04, 0x04, 0x70, 0x29, 0x04, 0x04, 0x70, 0x09, 0x05, 0x04, 0x80, 0x09, 0x05, 0x04, 0xc0, 0x25, 0x06, 0x05, 0x00, 0x20, 0x08, 0x06, 0x80, 0x03, 0x0b, 0x07, + 0xd0, 0x1d, 0x00, 0x03, 0xd8, 0x1d, 0x00, 0x03, 0xe0, 0x1d, 0x00, 0x03, 0xe8, 0x1d, 0x00, 0x03, 0x3c, 0x0e, 0x01, 0x02, 0x40, 0x0e, 0x01, 0x02, 0x44, 0x0e, 0x01, 0x02, 0x48, 0x0e, 0x01, 0x02, + 0x4c, 0x0e, 0x01, 0x02, 0x50, 0x0e, 0x01, 0x02, 0x00, 0x2d, 0x02, 0x03, 0x08, 0x2d, 0x02, 0x03, 0x10, 0x2d, 0x02, 0x03, 0x18, 0x2d, 0x02, 0x03, 0xc8, 0x0b, 0x03, 0x03, 0xd0, 0x0b, 0x03, 0x03, + 0xd8, 0x0b, 0x03, 0x03, 0x80, 0x29, 0x04, 0x04, 0x90, 0x29, 0x04, 0x04, 0x90, 0x09, 0x05, 0x04, 0xa0, 0x09, 0x05, 0x04, 0xe0, 0x25, 0x06, 0x05, 0x40, 0x20, 0x08, 0x06, 0x00, 0x04, 0x0b, 0x07, + 0xf0, 0x1d, 0x00, 0x03, 0xf8, 0x1d, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x03, 0x08, 0x1e, 0x00, 0x03, 0x54, 0x0e, 0x01, 0x02, 0x58, 0x0e, 0x01, 0x02, 0x5c, 0x0e, 0x01, 0x02, 0x60, 0x0e, 0x01, 0x02, + 0x64, 0x0e, 0x01, 0x02, 0x68, 0x0e, 0x01, 0x02, 0x20, 0x2d, 0x02, 0x03, 0x28, 0x2d, 0x02, 0x03, 0x30, 0x2d, 0x02, 0x03, 0x38, 0x2d, 0x02, 0x03, 0xe0, 0x0b, 0x03, 0x03, 0xe8, 0x0b, 0x03, 0x03, + 0xf0, 0x0b, 0x03, 0x03, 0xa0, 0x29, 0x04, 0x04, 0xb0, 0x29, 0x04, 0x04, 0xb0, 0x09, 0x05, 0x04, 0xc0, 0x09, 0x05, 0x04, 0x00, 0x26, 0x06, 0x05, 0x80, 0x20, 0x08, 0x06, 0x00, 0x15, 0x0c, 0x08, + 0x10, 0x1e, 0x00, 0x03, 0x18, 0x1e, 0x00, 0x03, 0x20, 0x1e, 0x00, 0x03, 0x28, 0x1e, 0x00, 0x03, 0x6c, 0x0e, 0x01, 0x02, 0x70, 0x0e, 0x01, 0x02, 0x74, 0x0e, 0x01, 0x02, 0x78, 0x0e, 0x01, 0x02, + 0x7c, 0x0e, 0x01, 0x02, 0x80, 0x0e, 0x01, 0x02, 0x40, 0x2d, 0x02, 0x03, 0x48, 0x2d, 0x02, 0x03, 0x50, 0x2d, 0x02, 0x03, 0x58, 0x2d, 0x02, 0x03, 0xf8, 0x0b, 0x03, 0x03, 0x00, 0x0c, 0x03, 0x03, + 0x08, 0x0c, 0x03, 0x03, 0xc0, 0x29, 0x04, 0x04, 0xd0, 0x29, 0x04, 0x04, 0xd0, 0x09, 0x05, 0x04, 0xe0, 0x09, 0x05, 0x04, 0x20, 0x26, 0x06, 0x05, 0xc0, 0x20, 0x08, 0x06, 0x00, 0x16, 0x0c, 0x08, + 0x30, 0x1e, 0x00, 0x03, 0x38, 0x1e, 0x00, 0x03, 0x40, 0x1e, 0x00, 0x03, 0x48, 0x1e, 0x00, 0x03, 0x84, 0x0e, 0x01, 0x02, 0x88, 0x0e, 0x01, 0x02, 0x8c, 0x0e, 0x01, 0x02, 0x90, 0x0e, 0x01, 0x02, + 0x94, 0x0e, 0x01, 0x02, 0x98, 0x0e, 0x01, 0x02, 0x60, 0x2d, 0x02, 0x03, 0x68, 0x2d, 0x02, 0x03, 0x70, 0x2d, 0x02, 0x03, 0x78, 0x2d, 0x02, 0x03, 0x10, 0x0c, 0x03, 0x03, 0x18, 0x0c, 0x03, 0x03, + 0x20, 0x0c, 0x03, 0x03, 0xe0, 0x29, 0x04, 0x04, 0xf0, 0x29, 0x04, 0x04, 0xf0, 0x09, 0x05, 0x04, 0x00, 0x0a, 0x05, 0x04, 0x40, 0x26, 0x06, 0x05, 0x00, 0x21, 0x08, 0x06, 0x00, 0x17, 0x0c, 0x08, + 0x50, 0x1e, 0x00, 0x03, 0x58, 0x1e, 0x00, 0x03, 0x60, 0x1e, 0x00, 0x03, 0x68, 0x1e, 0x00, 0x03, 0x9c, 0x0e, 0x01, 0x02, 0xa0, 0x0e, 0x01, 0x02, 0xa4, 0x0e, 0x01, 0x02, 0xa8, 0x0e, 0x01, 0x02, + 0xac, 0x0e, 0x01, 0x02, 0xb0, 0x0e, 0x01, 0x02, 0x80, 0x2d, 0x02, 0x03, 0x88, 0x2d, 0x02, 0x03, 0x90, 0x2d, 0x02, 0x03, 0x98, 0x2d, 0x02, 0x03, 0x28, 0x0c, 0x03, 0x03, 0x30, 0x0c, 0x03, 0x03, + 0x38, 0x0c, 0x03, 0x03, 0x00, 0x2a, 0x04, 0x04, 0x10, 0x2a, 0x04, 0x04, 0x10, 0x0a, 0x05, 0x04, 0x20, 0x0a, 0x05, 0x04, 0x60, 0x26, 0x06, 0x05, 0x40, 0x21, 0x08, 0x06, 0x00, 0x18, 0x0c, 0x08, + 0x70, 0x1e, 0x00, 0x03, 0x78, 0x1e, 0x00, 0x03, 0x80, 0x1e, 0x00, 0x03, 0x88, 0x1e, 0x00, 0x03, 0xb4, 0x0e, 0x01, 0x02, 0xb8, 0x0e, 0x01, 0x02, 0xbc, 0x0e, 0x01, 0x02, 0xc0, 0x0e, 0x01, 0x02, + 0xc4, 0x0e, 0x01, 0x02, 0xc8, 0x0e, 0x01, 0x02, 0xa0, 0x2d, 0x02, 0x03, 0xa8, 0x2d, 0x02, 0x03, 0xb0, 0x2d, 0x02, 0x03, 0xb8, 0x2d, 0x02, 0x03, 0x40, 0x0c, 0x03, 0x03, 0x48, 0x0c, 0x03, 0x03, + 0x50, 0x0c, 0x03, 0x03, 0x20, 0x2a, 0x04, 0x04, 0x30, 0x2a, 0x04, 0x04, 0x30, 0x0a, 0x05, 0x04, 0x40, 0x0a, 0x05, 0x04, 0x80, 0x26, 0x06, 0x05, 0x80, 0x21, 0x08, 0x06, 0x00, 0x19, 0x0c, 0x08, + 0x90, 0x1e, 0x00, 0x03, 0x98, 0x1e, 0x00, 0x03, 0xa0, 0x1e, 0x00, 0x03, 0xcc, 0x0e, 0x01, 0x02, 0xd0, 0x0e, 0x01, 0x02, 0xd4, 0x0e, 0x01, 0x02, 0xd8, 0x0e, 0x01, 0x02, 0xdc, 0x0e, 0x01, 0x02, + 0xe0, 0x0e, 0x01, 0x02, 0xe4, 0x0e, 0x01, 0x02, 0xc0, 0x2d, 0x02, 0x03, 0xc8, 0x2d, 0x02, 0x03, 0xd0, 0x2d, 0x02, 0x03, 0xd8, 0x2d, 0x02, 0x03, 0x58, 0x0c, 0x03, 0x03, 0x60, 0x0c, 0x03, 0x03, + 0x68, 0x0c, 0x03, 0x03, 0x40, 0x2a, 0x04, 0x04, 0x50, 0x2a, 0x04, 0x04, 0x50, 0x0a, 0x05, 0x04, 0x60, 0x0a, 0x05, 0x04, 0xa0, 0x26, 0x06, 0x05, 0xc0, 0x21, 0x08, 0x06, 0x00, 0x1a, 0x0c, 0x08, + 0xa8, 0x1e, 0x00, 0x03, 0xb0, 0x1e, 0x00, 0x03, 0xb8, 0x1e, 0x00, 0x03, 0xe8, 0x0e, 0x01, 0x02, 0xec, 0x0e, 0x01, 0x02, 0xf0, 0x0e, 0x01, 0x02, 0xf4, 0x0e, 0x01, 0x02, 0xf8, 0x0e, 0x01, 0x02, + 0xfc, 0x0e, 0x01, 0x02, 0x00, 0x0f, 0x01, 0x02, 0xe0, 0x2d, 0x02, 0x03, 0xe8, 0x2d, 0x02, 0x03, 0xf0, 0x2d, 0x02, 0x03, 0xf8, 0x2d, 0x02, 0x03, 0x70, 0x0c, 0x03, 0x03, 0x78, 0x0c, 0x03, 0x03, + 0x80, 0x0c, 0x03, 0x03, 0x60, 0x2a, 0x04, 0x04, 0x70, 0x2a, 0x04, 0x04, 0x70, 0x0a, 0x05, 0x04, 0x80, 0x0a, 0x05, 0x04, 0xc0, 0x26, 0x06, 0x05, 0x00, 0x22, 0x08, 0x06, 0x00, 0x1b, 0x0c, 0x08, + 0xc0, 0x1e, 0x00, 0x03, 0xc8, 0x1e, 0x00, 0x03, 0xd0, 0x1e, 0x00, 0x03, 0x04, 0x0f, 0x01, 0x02, 0x08, 0x0f, 0x01, 0x02, 0x0c, 0x0f, 0x01, 0x02, 0x10, 0x0f, 0x01, 0x02, 0x14, 0x0f, 0x01, 0x02, + 0x18, 0x0f, 0x01, 0x02, 0x1c, 0x0f, 0x01, 0x02, 0x00, 0x2e, 0x02, 0x03, 0x08, 0x2e, 0x02, 0x03, 0x10, 0x2e, 0x02, 0x03, 0x18, 0x2e, 0x02, 0x03, 0x88, 0x0c, 0x03, 0x03, 0x90, 0x0c, 0x03, 0x03, + 0x98, 0x0c, 0x03, 0x03, 0x80, 0x2a, 0x04, 0x04, 0x90, 0x2a, 0x04, 0x04, 0x90, 0x0a, 0x05, 0x04, 0xe0, 0x26, 0x06, 0x05, 0x80, 0x06, 0x07, 0x05, 0x40, 0x22, 0x08, 0x06, 0x00, 0x1c, 0x0c, 0x08, + 0xd8, 0x1e, 0x00, 0x03, 0xe0, 0x1e, 0x00, 0x03, 0xe8, 0x1e, 0x00, 0x03, 0x20, 0x0f, 0x01, 0x02, 0x24, 0x0f, 0x01, 0x02, 0x28, 0x0f, 0x01, 0x02, 0x2c, 0x0f, 0x01, 0x02, 0x30, 0x0f, 0x01, 0x02, + 0x34, 0x0f, 0x01, 0x02, 0x38, 0x0f, 0x01, 0x02, 0x20, 0x2e, 0x02, 0x03, 0x28, 0x2e, 0x02, 0x03, 0x30, 0x2e, 0x02, 0x03, 0x38, 0x2e, 0x02, 0x03, 0xa0, 0x0c, 0x03, 0x03, 0xa8, 0x0c, 0x03, 0x03, + 0xb0, 0x0c, 0x03, 0x03, 0xa0, 0x2a, 0x04, 0x04, 0xb0, 0x2a, 0x04, 0x04, 0xa0, 0x0a, 0x05, 0x04, 0x00, 0x27, 0x06, 0x05, 0xa0, 0x06, 0x07, 0x05, 0x80, 0x22, 0x08, 0x06, 0x00, 0x1d, 0x0c, 0x08, + 0xf0, 0x1e, 0x00, 0x03, 0xf8, 0x1e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x03, 0x3c, 0x0f, 0x01, 0x02, 0x40, 0x0f, 0x01, 0x02, 0x44, 0x0f, 0x01, 0x02, 0x48, 0x0f, 0x01, 0x02, 0x4c, 0x0f, 0x01, 0x02, + 0x50, 0x0f, 0x01, 0x02, 0x54, 0x0f, 0x01, 0x02, 0x40, 0x2e, 0x02, 0x03, 0x48, 0x2e, 0x02, 0x03, 0x50, 0x2e, 0x02, 0x03, 0x58, 0x2e, 0x02, 0x03, 0xb8, 0x0c, 0x03, 0x03, 0xc0, 0x0c, 0x03, 0x03, + 0xc8, 0x0c, 0x03, 0x03, 0xc0, 0x2a, 0x04, 0x04, 0xd0, 0x2a, 0x04, 0x04, 0xb0, 0x0a, 0x05, 0x04, 0x20, 0x27, 0x06, 0x05, 0xc0, 0x06, 0x07, 0x05, 0xc0, 0x22, 0x08, 0x06, 0x00, 0x1e, 0x0c, 0x08, + 0x08, 0x1f, 0x00, 0x03, 0x10, 0x1f, 0x00, 0x03, 0x18, 0x1f, 0x00, 0x03, 0x58, 0x0f, 0x01, 0x02, 0x5c, 0x0f, 0x01, 0x02, 0x60, 0x0f, 0x01, 0x02, 0x64, 0x0f, 0x01, 0x02, 0x68, 0x0f, 0x01, 0x02, + 0x6c, 0x0f, 0x01, 0x02, 0x70, 0x0f, 0x01, 0x02, 0x60, 0x2e, 0x02, 0x03, 0x68, 0x2e, 0x02, 0x03, 0x70, 0x2e, 0x02, 0x03, 0x78, 0x2e, 0x02, 0x03, 0xd0, 0x0c, 0x03, 0x03, 0xd8, 0x0c, 0x03, 0x03, + 0xe0, 0x0c, 0x03, 0x03, 0xe0, 0x2a, 0x04, 0x04, 0xf0, 0x2a, 0x04, 0x04, 0xc0, 0x0a, 0x05, 0x04, 0x40, 0x27, 0x06, 0x05, 0xe0, 0x06, 0x07, 0x05, 0x00, 0x23, 0x08, 0x06, 0x00, 0x38, 0x0d, 0x09, + 0x20, 0x1f, 0x00, 0x03, 0x28, 0x1f, 0x00, 0x03, 0x30, 0x1f, 0x00, 0x03, 0x74, 0x0f, 0x01, 0x02, 0x78, 0x0f, 0x01, 0x02, 0x7c, 0x0f, 0x01, 0x02, 0x80, 0x0f, 0x01, 0x02, 0x84, 0x0f, 0x01, 0x02, + 0x88, 0x0f, 0x01, 0x02, 0x8c, 0x0f, 0x01, 0x02, 0x80, 0x2e, 0x02, 0x03, 0x88, 0x2e, 0x02, 0x03, 0x90, 0x2e, 0x02, 0x03, 0x98, 0x2e, 0x02, 0x03, 0xe8, 0x0c, 0x03, 0x03, 0xf0, 0x0c, 0x03, 0x03, + 0xf8, 0x0c, 0x03, 0x03, 0x00, 0x2b, 0x04, 0x04, 0x10, 0x2b, 0x04, 0x04, 0xd0, 0x0a, 0x05, 0x04, 0x60, 0x27, 0x06, 0x05, 0x00, 0x07, 0x07, 0x05, 0x40, 0x23, 0x08, 0x06, 0x00, 0x3a, 0x0d, 0x09, + 0x38, 0x1f, 0x00, 0x03, 0x40, 0x1f, 0x00, 0x03, 0x48, 0x1f, 0x00, 0x03, 0x90, 0x0f, 0x01, 0x02, 0x94, 0x0f, 0x01, 0x02, 0x98, 0x0f, 0x01, 0x02, 0x9c, 0x0f, 0x01, 0x02, 0xa0, 0x0f, 0x01, 0x02, + 0xa4, 0x0f, 0x01, 0x02, 0xa8, 0x0f, 0x01, 0x02, 0xa0, 0x2e, 0x02, 0x03, 0xa8, 0x2e, 0x02, 0x03, 0xb0, 0x2e, 0x02, 0x03, 0xb8, 0x2e, 0x02, 0x03, 0x00, 0x0d, 0x03, 0x03, 0x08, 0x0d, 0x03, 0x03, + 0x10, 0x0d, 0x03, 0x03, 0x20, 0x2b, 0x04, 0x04, 0x30, 0x2b, 0x04, 0x04, 0xe0, 0x0a, 0x05, 0x04, 0x80, 0x27, 0x06, 0x05, 0x20, 0x07, 0x07, 0x05, 0x80, 0x23, 0x08, 0x06, 0x00, 0x3c, 0x0d, 0x09, + 0x50, 0x1f, 0x00, 0x03, 0x58, 0x1f, 0x00, 0x03, 0x60, 0x1f, 0x00, 0x03, 0xac, 0x0f, 0x01, 0x02, 0xb0, 0x0f, 0x01, 0x02, 0xb4, 0x0f, 0x01, 0x02, 0xb8, 0x0f, 0x01, 0x02, 0xbc, 0x0f, 0x01, 0x02, + 0xc0, 0x0f, 0x01, 0x02, 0xc4, 0x0f, 0x01, 0x02, 0xc0, 0x2e, 0x02, 0x03, 0xc8, 0x2e, 0x02, 0x03, 0xd0, 0x2e, 0x02, 0x03, 0xd8, 0x2e, 0x02, 0x03, 0x18, 0x0d, 0x03, 0x03, 0x20, 0x0d, 0x03, 0x03, + 0x28, 0x0d, 0x03, 0x03, 0x40, 0x2b, 0x04, 0x04, 0x50, 0x2b, 0x04, 0x04, 0xf0, 0x0a, 0x05, 0x04, 0xa0, 0x27, 0x06, 0x05, 0x40, 0x07, 0x07, 0x05, 0xc0, 0x23, 0x08, 0x06, 0x00, 0x3e, 0x0d, 0x09, + 0x68, 0x1f, 0x00, 0x03, 0x70, 0x1f, 0x00, 0x03, 0x78, 0x1f, 0x00, 0x03, 0xc8, 0x0f, 0x01, 0x02, 0xcc, 0x0f, 0x01, 0x02, 0xd0, 0x0f, 0x01, 0x02, 0xd4, 0x0f, 0x01, 0x02, 0xd8, 0x0f, 0x01, 0x02, + 0xdc, 0x0f, 0x01, 0x02, 0xe0, 0x0f, 0x01, 0x02, 0xe0, 0x2e, 0x02, 0x03, 0xe8, 0x2e, 0x02, 0x03, 0xf0, 0x2e, 0x02, 0x03, 0xf8, 0x2e, 0x02, 0x03, 0x30, 0x0d, 0x03, 0x03, 0x38, 0x0d, 0x03, 0x03, + 0x40, 0x0d, 0x03, 0x03, 0x60, 0x2b, 0x04, 0x04, 0x70, 0x2b, 0x04, 0x04, 0x00, 0x0b, 0x05, 0x04, 0xc0, 0x27, 0x06, 0x05, 0x60, 0x07, 0x07, 0x05, 0x00, 0x24, 0x08, 0x06, 0x00, 0x00, 0x0d, 0x08, + 0x80, 0x1f, 0x00, 0x03, 0x88, 0x1f, 0x00, 0x03, 0x90, 0x1f, 0x00, 0x03, 0xe4, 0x0f, 0x01, 0x02, 0xe8, 0x0f, 0x01, 0x02, 0xec, 0x0f, 0x01, 0x02, 0xf0, 0x0f, 0x01, 0x02, 0xf4, 0x0f, 0x01, 0x02, + 0xf8, 0x0f, 0x01, 0x02, 0xfc, 0x0f, 0x01, 0x02, 0x00, 0x2f, 0x02, 0x03, 0x08, 0x2f, 0x02, 0x03, 0x10, 0x2f, 0x02, 0x03, 0x18, 0x2f, 0x02, 0x03, 0x48, 0x0d, 0x03, 0x03, 0x50, 0x0d, 0x03, 0x03, + 0x58, 0x0d, 0x03, 0x03, 0x80, 0x2b, 0x04, 0x04, 0x90, 0x2b, 0x04, 0x04, 0x10, 0x0b, 0x05, 0x04, 0xe0, 0x27, 0x06, 0x05, 0x80, 0x07, 0x07, 0x05, 0x40, 0x24, 0x08, 0x06, 0x00, 0x01, 0x0d, 0x08, + 0x98, 0x1f, 0x00, 0x03, 0xa0, 0x1f, 0x00, 0x03, 0xa8, 0x1f, 0x00, 0x03, 0x00, 0x10, 0x01, 0x02, 0x04, 0x10, 0x01, 0x02, 0x08, 0x10, 0x01, 0x02, 0x0c, 0x10, 0x01, 0x02, 0x10, 0x10, 0x01, 0x02, + 0x14, 0x10, 0x01, 0x02, 0x18, 0x10, 0x01, 0x02, 0x20, 0x2f, 0x02, 0x03, 0x28, 0x2f, 0x02, 0x03, 0x30, 0x2f, 0x02, 0x03, 0x38, 0x2f, 0x02, 0x03, 0x60, 0x0d, 0x03, 0x03, 0x68, 0x0d, 0x03, 0x03, + 0x70, 0x0d, 0x03, 0x03, 0xa0, 0x2b, 0x04, 0x04, 0xb0, 0x2b, 0x04, 0x04, 0x20, 0x0b, 0x05, 0x04, 0x00, 0x28, 0x06, 0x05, 0xa0, 0x07, 0x07, 0x05, 0x80, 0x24, 0x08, 0x06, 0x00, 0x14, 0x0e, 0x09, + 0xb0, 0x1f, 0x00, 0x03, 0xb8, 0x1f, 0x00, 0x03, 0xc0, 0x1f, 0x00, 0x03, 0x1c, 0x10, 0x01, 0x02, 0x20, 0x10, 0x01, 0x02, 0x24, 0x10, 0x01, 0x02, 0x28, 0x10, 0x01, 0x02, 0x2c, 0x10, 0x01, 0x02, + 0x30, 0x10, 0x01, 0x02, 0x34, 0x10, 0x01, 0x02, 0x40, 0x2f, 0x02, 0x03, 0x48, 0x2f, 0x02, 0x03, 0x50, 0x2f, 0x02, 0x03, 0x58, 0x2f, 0x02, 0x03, 0x78, 0x0d, 0x03, 0x03, 0x80, 0x0d, 0x03, 0x03, + 0x88, 0x0d, 0x03, 0x03, 0xc0, 0x2b, 0x04, 0x04, 0xd0, 0x2b, 0x04, 0x04, 0x30, 0x0b, 0x05, 0x04, 0x20, 0x28, 0x06, 0x05, 0xc0, 0x07, 0x07, 0x05, 0xc0, 0x24, 0x08, 0x06, 0x00, 0x16, 0x0e, 0x09, + 0xc8, 0x1f, 0x00, 0x03, 0xd0, 0x1f, 0x00, 0x03, 0xd8, 0x1f, 0x00, 0x03, 0x38, 0x10, 0x01, 0x02, 0x3c, 0x10, 0x01, 0x02, 0x40, 0x10, 0x01, 0x02, 0x44, 0x10, 0x01, 0x02, 0x48, 0x10, 0x01, 0x02, + 0x4c, 0x10, 0x01, 0x02, 0x50, 0x10, 0x01, 0x02, 0x60, 0x2f, 0x02, 0x03, 0x68, 0x2f, 0x02, 0x03, 0x70, 0x2f, 0x02, 0x03, 0x78, 0x2f, 0x02, 0x03, 0x90, 0x0d, 0x03, 0x03, 0x98, 0x0d, 0x03, 0x03, + 0xa0, 0x0d, 0x03, 0x03, 0xe0, 0x2b, 0x04, 0x04, 0xf0, 0x2b, 0x04, 0x04, 0x40, 0x0b, 0x05, 0x04, 0x40, 0x28, 0x06, 0x05, 0xe0, 0x07, 0x07, 0x05, 0x00, 0x25, 0x08, 0x06, 0x00, 0x18, 0x0e, 0x09, + 0xe0, 0x1f, 0x00, 0x03, 0xe8, 0x1f, 0x00, 0x03, 0xf0, 0x1f, 0x00, 0x03, 0x54, 0x10, 0x01, 0x02, 0x58, 0x10, 0x01, 0x02, 0x5c, 0x10, 0x01, 0x02, 0x60, 0x10, 0x01, 0x02, 0x64, 0x10, 0x01, 0x02, + 0x68, 0x10, 0x01, 0x02, 0x6c, 0x10, 0x01, 0x02, 0x80, 0x2f, 0x02, 0x03, 0x88, 0x2f, 0x02, 0x03, 0x90, 0x2f, 0x02, 0x03, 0x98, 0x2f, 0x02, 0x03, 0xa8, 0x0d, 0x03, 0x03, 0xb0, 0x0d, 0x03, 0x03, + 0xb8, 0x0d, 0x03, 0x03, 0x00, 0x2c, 0x04, 0x04, 0x10, 0x2c, 0x04, 0x04, 0x50, 0x0b, 0x05, 0x04, 0x60, 0x28, 0x06, 0x05, 0x00, 0x08, 0x07, 0x05, 0x40, 0x25, 0x08, 0x06, 0x00, 0x1a, 0x0e, 0x09, + 0xf8, 0x1f, 0x00, 0x03, 0x00, 0x20, 0x00, 0x03, 0x08, 0x20, 0x00, 0x03, 0x70, 0x10, 0x01, 0x02, 0x74, 0x10, 0x01, 0x02, 0x78, 0x10, 0x01, 0x02, 0x7c, 0x10, 0x01, 0x02, 0x80, 0x10, 0x01, 0x02, + 0x84, 0x10, 0x01, 0x02, 0x88, 0x10, 0x01, 0x02, 0xa0, 0x2f, 0x02, 0x03, 0xa8, 0x2f, 0x02, 0x03, 0xb0, 0x2f, 0x02, 0x03, 0xb8, 0x2f, 0x02, 0x03, 0xc0, 0x0d, 0x03, 0x03, 0xc8, 0x0d, 0x03, 0x03, + 0xd0, 0x0d, 0x03, 0x03, 0x20, 0x2c, 0x04, 0x04, 0x30, 0x2c, 0x04, 0x04, 0x60, 0x0b, 0x05, 0x04, 0x80, 0x28, 0x06, 0x05, 0x20, 0x08, 0x07, 0x05, 0x80, 0x25, 0x08, 0x06, 0x00, 0x1c, 0x0e, 0x09, + 0x10, 0x20, 0x00, 0x03, 0x18, 0x20, 0x00, 0x03, 0x20, 0x20, 0x00, 0x03, 0x8c, 0x10, 0x01, 0x02, 0x90, 0x10, 0x01, 0x02, 0x94, 0x10, 0x01, 0x02, 0x98, 0x10, 0x01, 0x02, 0x9c, 0x10, 0x01, 0x02, + 0xa0, 0x10, 0x01, 0x02, 0xc0, 0x2f, 0x02, 0x03, 0xc8, 0x2f, 0x02, 0x03, 0xd0, 0x2f, 0x02, 0x03, 0xd8, 0x2f, 0x02, 0x03, 0xe0, 0x2f, 0x02, 0x03, 0xd8, 0x0d, 0x03, 0x03, 0xe0, 0x0d, 0x03, 0x03, + 0xe8, 0x0d, 0x03, 0x03, 0x40, 0x2c, 0x04, 0x04, 0x50, 0x2c, 0x04, 0x04, 0x70, 0x0b, 0x05, 0x04, 0xa0, 0x28, 0x06, 0x05, 0x40, 0x08, 0x07, 0x05, 0xc0, 0x25, 0x08, 0x06, 0x00, 0x34, 0x0f, 0x0a, + 0x28, 0x20, 0x00, 0x03, 0x30, 0x20, 0x00, 0x03, 0x38, 0x20, 0x00, 0x03, 0xa4, 0x10, 0x01, 0x02, 0xa8, 0x10, 0x01, 0x02, 0xac, 0x10, 0x01, 0x02, 0xb0, 0x10, 0x01, 0x02, 0xb4, 0x10, 0x01, 0x02, + 0xb8, 0x10, 0x01, 0x02, 0xe8, 0x2f, 0x02, 0x03, 0xf0, 0x2f, 0x02, 0x03, 0xf8, 0x2f, 0x02, 0x03, 0x00, 0x30, 0x02, 0x03, 0x08, 0x30, 0x02, 0x03, 0xf0, 0x0d, 0x03, 0x03, 0xf8, 0x0d, 0x03, 0x03, + 0x00, 0x0e, 0x03, 0x03, 0x60, 0x2c, 0x04, 0x04, 0x70, 0x2c, 0x04, 0x04, 0x80, 0x0b, 0x05, 0x04, 0xc0, 0x28, 0x06, 0x05, 0x60, 0x08, 0x07, 0x05, 0x00, 0x26, 0x08, 0x06, 0x00, 0x38, 0x0f, 0x0a, + 0x40, 0x20, 0x00, 0x03, 0x48, 0x20, 0x00, 0x03, 0x50, 0x20, 0x00, 0x03, 0xbc, 0x10, 0x01, 0x02, 0xc0, 0x10, 0x01, 0x02, 0xc4, 0x10, 0x01, 0x02, 0xc8, 0x10, 0x01, 0x02, 0xcc, 0x10, 0x01, 0x02, + 0xd0, 0x10, 0x01, 0x02, 0x10, 0x30, 0x02, 0x03, 0x18, 0x30, 0x02, 0x03, 0x20, 0x30, 0x02, 0x03, 0x28, 0x30, 0x02, 0x03, 0x30, 0x30, 0x02, 0x03, 0x08, 0x0e, 0x03, 0x03, 0x10, 0x0e, 0x03, 0x03, + 0x18, 0x0e, 0x03, 0x03, 0x80, 0x2c, 0x04, 0x04, 0x90, 0x2c, 0x04, 0x04, 0x90, 0x0b, 0x05, 0x04, 0xe0, 0x28, 0x06, 0x05, 0x80, 0x08, 0x07, 0x05, 0x00, 0x05, 0x09, 0x06, 0x00, 0x3c, 0x0f, 0x0a, + 0x58, 0x20, 0x00, 0x03, 0x60, 0x20, 0x00, 0x03, 0x68, 0x20, 0x00, 0x03, 0xd4, 0x10, 0x01, 0x02, 0xd8, 0x10, 0x01, 0x02, 0xdc, 0x10, 0x01, 0x02, 0xe0, 0x10, 0x01, 0x02, 0xe4, 0x10, 0x01, 0x02, + 0xe8, 0x10, 0x01, 0x02, 0x38, 0x30, 0x02, 0x03, 0x40, 0x30, 0x02, 0x03, 0x48, 0x30, 0x02, 0x03, 0x50, 0x30, 0x02, 0x03, 0x58, 0x30, 0x02, 0x03, 0x20, 0x0e, 0x03, 0x03, 0x28, 0x0e, 0x03, 0x03, + 0x30, 0x0e, 0x03, 0x03, 0xa0, 0x2c, 0x04, 0x04, 0xb0, 0x2c, 0x04, 0x04, 0xa0, 0x0b, 0x05, 0x04, 0x00, 0x29, 0x06, 0x05, 0xa0, 0x08, 0x07, 0x05, 0x40, 0x05, 0x09, 0x06, 0x00, 0x00, 0x0f, 0x09, + 0x70, 0x20, 0x00, 0x03, 0x78, 0x20, 0x00, 0x03, 0x80, 0x20, 0x00, 0x03, 0xec, 0x10, 0x01, 0x02, 0xf0, 0x10, 0x01, 0x02, 0xf4, 0x10, 0x01, 0x02, 0xf8, 0x10, 0x01, 0x02, 0xfc, 0x10, 0x01, 0x02, + 0x00, 0x11, 0x01, 0x02, 0x60, 0x30, 0x02, 0x03, 0x68, 0x30, 0x02, 0x03, 0x70, 0x30, 0x02, 0x03, 0x78, 0x30, 0x02, 0x03, 0x80, 0x30, 0x02, 0x03, 0x38, 0x0e, 0x03, 0x03, 0x40, 0x0e, 0x03, 0x03, + 0x48, 0x0e, 0x03, 0x03, 0xc0, 0x2c, 0x04, 0x04, 0xd0, 0x2c, 0x04, 0x04, 0xb0, 0x0b, 0x05, 0x04, 0x20, 0x29, 0x06, 0x05, 0xc0, 0x08, 0x07, 0x05, 0x80, 0x05, 0x09, 0x06, 0x00, 0x14, 0x10, 0x0a, + 0x88, 0x20, 0x00, 0x03, 0x90, 0x20, 0x00, 0x03, 0x98, 0x20, 0x00, 0x03, 0x04, 0x11, 0x01, 0x02, 0x08, 0x11, 0x01, 0x02, 0x0c, 0x11, 0x01, 0x02, 0x10, 0x11, 0x01, 0x02, 0x14, 0x11, 0x01, 0x02, + 0x18, 0x11, 0x01, 0x02, 0x88, 0x30, 0x02, 0x03, 0x90, 0x30, 0x02, 0x03, 0x98, 0x30, 0x02, 0x03, 0xa0, 0x30, 0x02, 0x03, 0xa8, 0x30, 0x02, 0x03, 0x50, 0x0e, 0x03, 0x03, 0x58, 0x0e, 0x03, 0x03, + 0x60, 0x0e, 0x03, 0x03, 0xe0, 0x2c, 0x04, 0x04, 0xf0, 0x2c, 0x04, 0x04, 0xc0, 0x0b, 0x05, 0x04, 0x40, 0x29, 0x06, 0x05, 0xe0, 0x08, 0x07, 0x05, 0xc0, 0x05, 0x09, 0x06, 0x00, 0x18, 0x10, 0x0a, + 0xa0, 0x20, 0x00, 0x03, 0xa8, 0x20, 0x00, 0x03, 0xb0, 0x20, 0x00, 0x03, 0x1c, 0x11, 0x01, 0x02, 0x20, 0x11, 0x01, 0x02, 0x24, 0x11, 0x01, 0x02, 0x28, 0x11, 0x01, 0x02, 0x2c, 0x11, 0x01, 0x02, + 0x30, 0x11, 0x01, 0x02, 0xb0, 0x30, 0x02, 0x03, 0xb8, 0x30, 0x02, 0x03, 0xc0, 0x30, 0x02, 0x03, 0xc8, 0x30, 0x02, 0x03, 0xd0, 0x30, 0x02, 0x03, 0x68, 0x0e, 0x03, 0x03, 0x70, 0x0e, 0x03, 0x03, + 0x78, 0x0e, 0x03, 0x03, 0x00, 0x2d, 0x04, 0x04, 0x10, 0x2d, 0x04, 0x04, 0xd0, 0x0b, 0x05, 0x04, 0x60, 0x29, 0x06, 0x05, 0x00, 0x09, 0x07, 0x05, 0x00, 0x06, 0x09, 0x06, 0x00, 0x28, 0x11, 0x0b, + 0xb8, 0x20, 0x00, 0x03, 0xc0, 0x20, 0x00, 0x03, 0xc8, 0x20, 0x00, 0x03, 0x34, 0x11, 0x01, 0x02, 0x38, 0x11, 0x01, 0x02, 0x3c, 0x11, 0x01, 0x02, 0x40, 0x11, 0x01, 0x02, 0x44, 0x11, 0x01, 0x02, + 0x48, 0x11, 0x01, 0x02, 0xd8, 0x30, 0x02, 0x03, 0xe0, 0x30, 0x02, 0x03, 0xe8, 0x30, 0x02, 0x03, 0xf0, 0x30, 0x02, 0x03, 0xf8, 0x30, 0x02, 0x03, 0x80, 0x0e, 0x03, 0x03, 0x88, 0x0e, 0x03, 0x03, + 0x90, 0x0e, 0x03, 0x03, 0x20, 0x2d, 0x04, 0x04, 0x30, 0x2d, 0x04, 0x04, 0xe0, 0x0b, 0x05, 0x04, 0x80, 0x29, 0x06, 0x05, 0x20, 0x09, 0x07, 0x05, 0x40, 0x06, 0x09, 0x06, 0x00, 0x30, 0x11, 0x0b, + 0xd0, 0x20, 0x00, 0x03, 0xd8, 0x20, 0x00, 0x03, 0xe0, 0x20, 0x00, 0x03, 0x4c, 0x11, 0x01, 0x02, 0x50, 0x11, 0x01, 0x02, 0x54, 0x11, 0x01, 0x02, 0x58, 0x11, 0x01, 0x02, 0x5c, 0x11, 0x01, 0x02, + 0x60, 0x11, 0x01, 0x02, 0x00, 0x31, 0x02, 0x03, 0x08, 0x31, 0x02, 0x03, 0x10, 0x31, 0x02, 0x03, 0x18, 0x31, 0x02, 0x03, 0x20, 0x31, 0x02, 0x03, 0x98, 0x0e, 0x03, 0x03, 0xa0, 0x0e, 0x03, 0x03, + 0xa8, 0x0e, 0x03, 0x03, 0x40, 0x2d, 0x04, 0x04, 0x50, 0x2d, 0x04, 0x04, 0xf0, 0x0b, 0x05, 0x04, 0xa0, 0x29, 0x06, 0x05, 0x40, 0x09, 0x07, 0x05, 0x80, 0x06, 0x09, 0x06, 0x00, 0x18, 0x12, 0x0b, + 0xe8, 0x20, 0x00, 0x03, 0xf0, 0x20, 0x00, 0x03, 0xf8, 0x20, 0x00, 0x03, 0x64, 0x11, 0x01, 0x02, 0x68, 0x11, 0x01, 0x02, 0x6c, 0x11, 0x01, 0x02, 0x70, 0x11, 0x01, 0x02, 0x74, 0x11, 0x01, 0x02, + 0x78, 0x11, 0x01, 0x02, 0x28, 0x31, 0x02, 0x03, 0x30, 0x31, 0x02, 0x03, 0x38, 0x31, 0x02, 0x03, 0x40, 0x31, 0x02, 0x03, 0x48, 0x31, 0x02, 0x03, 0xb0, 0x0e, 0x03, 0x03, 0xb8, 0x0e, 0x03, 0x03, + 0xc0, 0x0e, 0x03, 0x03, 0x60, 0x2d, 0x04, 0x04, 0x70, 0x2d, 0x04, 0x04, 0x00, 0x0c, 0x05, 0x04, 0xc0, 0x29, 0x06, 0x05, 0x60, 0x09, 0x07, 0x05, 0xc0, 0x06, 0x09, 0x06, 0x00, 0x30, 0x13, 0x0c, + 0x00, 0x21, 0x00, 0x03, 0x08, 0x21, 0x00, 0x03, 0x10, 0x21, 0x00, 0x03, 0x7c, 0x11, 0x01, 0x02, 0x80, 0x11, 0x01, 0x02, 0x84, 0x11, 0x01, 0x02, 0x88, 0x11, 0x01, 0x02, 0x8c, 0x11, 0x01, 0x02, + 0x90, 0x11, 0x01, 0x02, 0x50, 0x31, 0x02, 0x03, 0x58, 0x31, 0x02, 0x03, 0x60, 0x31, 0x02, 0x03, 0x68, 0x31, 0x02, 0x03, 0x70, 0x31, 0x02, 0x03, 0xc8, 0x0e, 0x03, 0x03, 0xd0, 0x0e, 0x03, 0x03, + 0xd8, 0x0e, 0x03, 0x03, 0x80, 0x2d, 0x04, 0x04, 0x90, 0x2d, 0x04, 0x04, 0x10, 0x0c, 0x05, 0x04, 0xe0, 0x29, 0x06, 0x05, 0x80, 0x09, 0x07, 0x05, 0x00, 0x07, 0x09, 0x06, 0x00, 0x00, 0x14, 0x0c, + 0x18, 0x21, 0x00, 0x03, 0x20, 0x21, 0x00, 0x03, 0x28, 0x21, 0x00, 0x03, 0x94, 0x11, 0x01, 0x02, 0x98, 0x11, 0x01, 0x02, 0x9c, 0x11, 0x01, 0x02, 0xa0, 0x11, 0x01, 0x02, 0xa4, 0x11, 0x01, 0x02, + 0xa8, 0x11, 0x01, 0x02, 0x78, 0x31, 0x02, 0x03, 0x80, 0x31, 0x02, 0x03, 0x88, 0x31, 0x02, 0x03, 0x90, 0x31, 0x02, 0x03, 0x98, 0x31, 0x02, 0x03, 0xe0, 0x0e, 0x03, 0x03, 0xe8, 0x0e, 0x03, 0x03, + 0xf0, 0x0e, 0x03, 0x03, 0xa0, 0x2d, 0x04, 0x04, 0xb0, 0x2d, 0x04, 0x04, 0x20, 0x0c, 0x05, 0x04, 0x00, 0x2a, 0x06, 0x05, 0xa0, 0x09, 0x07, 0x05, 0x40, 0x07, 0x09, 0x06, 0x30, 0x21, 0x00, 0x03, + 0x38, 0x21, 0x00, 0x03, 0x40, 0x21, 0x00, 0x03, 0x48, 0x21, 0x00, 0x03, 0xac, 0x11, 0x01, 0x02, 0xb0, 0x11, 0x01, 0x02, 0xb4, 0x11, 0x01, 0x02, 0xb8, 0x11, 0x01, 0x02, 0xbc, 0x11, 0x01, 0x02, + 0xc0, 0x11, 0x01, 0x02, 0xa0, 0x31, 0x02, 0x03, 0xa8, 0x31, 0x02, 0x03, 0xb0, 0x31, 0x02, 0x03, 0xb8, 0x31, 0x02, 0x03, 0xc0, 0x31, 0x02, 0x03, 0xf8, 0x0e, 0x03, 0x03, 0x00, 0x0f, 0x03, 0x03, + 0x08, 0x0f, 0x03, 0x03, 0xc0, 0x2d, 0x04, 0x04, 0xd0, 0x2d, 0x04, 0x04, 0x30, 0x0c, 0x05, 0x04, 0x20, 0x2a, 0x06, 0x05, 0xc0, 0x09, 0x07, 0x05, 0x80, 0x07, 0x09, 0x06, 0x50, 0x21, 0x00, 0x03, + 0x58, 0x21, 0x00, 0x03, 0x60, 0x21, 0x00, 0x03, 0x68, 0x21, 0x00, 0x03, 0xc4, 0x11, 0x01, 0x02, 0xc8, 0x11, 0x01, 0x02, 0xcc, 0x11, 0x01, 0x02, 0xd0, 0x11, 0x01, 0x02, 0xd4, 0x11, 0x01, 0x02, + 0xd8, 0x11, 0x01, 0x02, 0xc8, 0x31, 0x02, 0x03, 0xd0, 0x31, 0x02, 0x03, 0xd8, 0x31, 0x02, 0x03, 0xe0, 0x31, 0x02, 0x03, 0xe8, 0x31, 0x02, 0x03, 0x10, 0x0f, 0x03, 0x03, 0x18, 0x0f, 0x03, 0x03, + 0x20, 0x0f, 0x03, 0x03, 0xe0, 0x2d, 0x04, 0x04, 0xf0, 0x2d, 0x04, 0x04, 0x40, 0x0c, 0x05, 0x04, 0x40, 0x2a, 0x06, 0x05, 0xe0, 0x09, 0x07, 0x05, 0xc0, 0x07, 0x09, 0x06, 0x70, 0x21, 0x00, 0x03, + 0x78, 0x21, 0x00, 0x03, 0x80, 0x21, 0x00, 0x03, 0x88, 0x21, 0x00, 0x03, 0xdc, 0x11, 0x01, 0x02, 0xe0, 0x11, 0x01, 0x02, 0xe4, 0x11, 0x01, 0x02, 0xe8, 0x11, 0x01, 0x02, 0xec, 0x11, 0x01, 0x02, + 0xf0, 0x11, 0x01, 0x02, 0xf0, 0x31, 0x02, 0x03, 0xf8, 0x31, 0x02, 0x03, 0x00, 0x32, 0x02, 0x03, 0x08, 0x32, 0x02, 0x03, 0x10, 0x32, 0x02, 0x03, 0x28, 0x0f, 0x03, 0x03, 0x30, 0x0f, 0x03, 0x03, + 0x38, 0x0f, 0x03, 0x03, 0x00, 0x2e, 0x04, 0x04, 0x10, 0x2e, 0x04, 0x04, 0x50, 0x0c, 0x05, 0x04, 0x60, 0x2a, 0x06, 0x05, 0x00, 0x0a, 0x07, 0x05, 0x00, 0x08, 0x09, 0x06, 0x90, 0x21, 0x00, 0x03, + 0x98, 0x21, 0x00, 0x03, 0xa0, 0x21, 0x00, 0x03, 0xa8, 0x21, 0x00, 0x03, 0xf4, 0x11, 0x01, 0x02, 0xf8, 0x11, 0x01, 0x02, 0xfc, 0x11, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x04, 0x12, 0x01, 0x02, + 0x08, 0x12, 0x01, 0x02, 0x18, 0x32, 0x02, 0x03, 0x20, 0x32, 0x02, 0x03, 0x28, 0x32, 0x02, 0x03, 0x30, 0x32, 0x02, 0x03, 0x38, 0x32, 0x02, 0x03, 0x40, 0x0f, 0x03, 0x03, 0x48, 0x0f, 0x03, 0x03, + 0x50, 0x0f, 0x03, 0x03, 0x20, 0x2e, 0x04, 0x04, 0x30, 0x2e, 0x04, 0x04, 0x60, 0x0c, 0x05, 0x04, 0x80, 0x2a, 0x06, 0x05, 0x20, 0x0a, 0x07, 0x05, 0x40, 0x08, 0x09, 0x06, 0xb0, 0x21, 0x00, 0x03, + 0xb8, 0x21, 0x00, 0x03, 0xc0, 0x21, 0x00, 0x03, 0xc8, 0x21, 0x00, 0x03, 0x0c, 0x12, 0x01, 0x02, 0x10, 0x12, 0x01, 0x02, 0x14, 0x12, 0x01, 0x02, 0x18, 0x12, 0x01, 0x02, 0x1c, 0x12, 0x01, 0x02, + 0x20, 0x12, 0x01, 0x02, 0x40, 0x32, 0x02, 0x03, 0x48, 0x32, 0x02, 0x03, 0x50, 0x32, 0x02, 0x03, 0x58, 0x32, 0x02, 0x03, 0x60, 0x32, 0x02, 0x03, 0x58, 0x0f, 0x03, 0x03, 0x60, 0x0f, 0x03, 0x03, + 0x68, 0x0f, 0x03, 0x03, 0x40, 0x2e, 0x04, 0x04, 0x50, 0x2e, 0x04, 0x04, 0x70, 0x0c, 0x05, 0x04, 0xa0, 0x2a, 0x06, 0x05, 0x40, 0x0a, 0x07, 0x05, 0x80, 0x08, 0x09, 0x06, 0xd0, 0x21, 0x00, 0x03, + 0xd8, 0x21, 0x00, 0x03, 0xe0, 0x21, 0x00, 0x03, 0xe8, 0x21, 0x00, 0x03, 0x24, 0x12, 0x01, 0x02, 0x28, 0x12, 0x01, 0x02, 0x2c, 0x12, 0x01, 0x02, 0x30, 0x12, 0x01, 0x02, 0x34, 0x12, 0x01, 0x02, + 0x38, 0x12, 0x01, 0x02, 0x68, 0x32, 0x02, 0x03, 0x70, 0x32, 0x02, 0x03, 0x78, 0x32, 0x02, 0x03, 0x80, 0x32, 0x02, 0x03, 0x88, 0x32, 0x02, 0x03, 0x70, 0x0f, 0x03, 0x03, 0x78, 0x0f, 0x03, 0x03, + 0x80, 0x0f, 0x03, 0x03, 0x60, 0x2e, 0x04, 0x04, 0x70, 0x2e, 0x04, 0x04, 0x80, 0x0c, 0x05, 0x04, 0xc0, 0x2a, 0x06, 0x05, 0x60, 0x0a, 0x07, 0x05, 0xc0, 0x08, 0x09, 0x06, 0xf0, 0x21, 0x00, 0x03, + 0xf8, 0x21, 0x00, 0x03, 0x00, 0x22, 0x00, 0x03, 0x08, 0x22, 0x00, 0x03, 0x3c, 0x12, 0x01, 0x02, 0x40, 0x12, 0x01, 0x02, 0x44, 0x12, 0x01, 0x02, 0x48, 0x12, 0x01, 0x02, 0x4c, 0x12, 0x01, 0x02, + 0x50, 0x12, 0x01, 0x02, 0x90, 0x32, 0x02, 0x03, 0x98, 0x32, 0x02, 0x03, 0xa0, 0x32, 0x02, 0x03, 0xa8, 0x32, 0x02, 0x03, 0xb0, 0x32, 0x02, 0x03, 0x88, 0x0f, 0x03, 0x03, 0x90, 0x0f, 0x03, 0x03, + 0x98, 0x0f, 0x03, 0x03, 0x80, 0x2e, 0x04, 0x04, 0x90, 0x2e, 0x04, 0x04, 0x90, 0x0c, 0x05, 0x04, 0xe0, 0x2a, 0x06, 0x05, 0x80, 0x0a, 0x07, 0x05, 0x00, 0x09, 0x09, 0x06, 0x10, 0x22, 0x00, 0x03, + 0x18, 0x22, 0x00, 0x03, 0x20, 0x22, 0x00, 0x03, 0x28, 0x22, 0x00, 0x03, 0x54, 0x12, 0x01, 0x02, 0x58, 0x12, 0x01, 0x02, 0x5c, 0x12, 0x01, 0x02, 0x60, 0x12, 0x01, 0x02, 0x64, 0x12, 0x01, 0x02, + 0x68, 0x12, 0x01, 0x02, 0xb8, 0x32, 0x02, 0x03, 0xc0, 0x32, 0x02, 0x03, 0xc8, 0x32, 0x02, 0x03, 0xd0, 0x32, 0x02, 0x03, 0xd8, 0x32, 0x02, 0x03, 0xa0, 0x0f, 0x03, 0x03, 0xa8, 0x0f, 0x03, 0x03, + 0xb0, 0x0f, 0x03, 0x03, 0xa0, 0x2e, 0x04, 0x04, 0xb0, 0x2e, 0x04, 0x04, 0xa0, 0x0c, 0x05, 0x04, 0x00, 0x2b, 0x06, 0x05, 0xa0, 0x0a, 0x07, 0x05, 0x40, 0x09, 0x09, 0x06, 0x30, 0x22, 0x00, 0x03, + 0x38, 0x22, 0x00, 0x03, 0x40, 0x22, 0x00, 0x03, 0x48, 0x22, 0x00, 0x03, 0x6c, 0x12, 0x01, 0x02, 0x70, 0x12, 0x01, 0x02, 0x74, 0x12, 0x01, 0x02, 0x78, 0x12, 0x01, 0x02, 0x7c, 0x12, 0x01, 0x02, + 0x80, 0x12, 0x01, 0x02, 0xe0, 0x32, 0x02, 0x03, 0xe8, 0x32, 0x02, 0x03, 0xf0, 0x32, 0x02, 0x03, 0xf8, 0x32, 0x02, 0x03, 0x00, 0x33, 0x02, 0x03, 0xb8, 0x0f, 0x03, 0x03, 0xc0, 0x0f, 0x03, 0x03, + 0xc8, 0x0f, 0x03, 0x03, 0xc0, 0x2e, 0x04, 0x04, 0xd0, 0x2e, 0x04, 0x04, 0xb0, 0x0c, 0x05, 0x04, 0x20, 0x2b, 0x06, 0x05, 0xc0, 0x0a, 0x07, 0x05, 0x80, 0x09, 0x09, 0x06, 0x50, 0x22, 0x00, 0x03, + 0x58, 0x22, 0x00, 0x03, 0x60, 0x22, 0x00, 0x03, 0x68, 0x22, 0x00, 0x03, 0x84, 0x12, 0x01, 0x02, 0x88, 0x12, 0x01, 0x02, 0x8c, 0x12, 0x01, 0x02, 0x90, 0x12, 0x01, 0x02, 0x94, 0x12, 0x01, 0x02, + 0x98, 0x12, 0x01, 0x02, 0x08, 0x33, 0x02, 0x03, 0x10, 0x33, 0x02, 0x03, 0x18, 0x33, 0x02, 0x03, 0x20, 0x33, 0x02, 0x03, 0x28, 0x33, 0x02, 0x03, 0xd0, 0x0f, 0x03, 0x03, 0xd8, 0x0f, 0x03, 0x03, + 0xe0, 0x0f, 0x03, 0x03, 0xe0, 0x2e, 0x04, 0x04, 0xf0, 0x2e, 0x04, 0x04, 0xc0, 0x0c, 0x05, 0x04, 0x40, 0x2b, 0x06, 0x05, 0xe0, 0x0a, 0x07, 0x05, 0xc0, 0x09, 0x09, 0x06, 0x70, 0x22, 0x00, 0x03, + 0x78, 0x22, 0x00, 0x03, 0x80, 0x22, 0x00, 0x03, 0x88, 0x22, 0x00, 0x03, 0x9c, 0x12, 0x01, 0x02, 0xa0, 0x12, 0x01, 0x02, 0xa4, 0x12, 0x01, 0x02, 0xa8, 0x12, 0x01, 0x02, 0xac, 0x12, 0x01, 0x02, + 0xb0, 0x12, 0x01, 0x02, 0x30, 0x33, 0x02, 0x03, 0x38, 0x33, 0x02, 0x03, 0x40, 0x33, 0x02, 0x03, 0x48, 0x33, 0x02, 0x03, 0x50, 0x33, 0x02, 0x03, 0xe8, 0x0f, 0x03, 0x03, 0xf0, 0x0f, 0x03, 0x03, + 0xf8, 0x0f, 0x03, 0x03, 0x00, 0x2f, 0x04, 0x04, 0x10, 0x2f, 0x04, 0x04, 0xd0, 0x0c, 0x05, 0x04, 0x60, 0x2b, 0x06, 0x05, 0x00, 0x0b, 0x07, 0x05, 0x00, 0x0a, 0x09, 0x06, 0x90, 0x22, 0x00, 0x03, + 0x98, 0x22, 0x00, 0x03, 0xa0, 0x22, 0x00, 0x03, 0xa8, 0x22, 0x00, 0x03, 0xb4, 0x12, 0x01, 0x02, 0xb8, 0x12, 0x01, 0x02, 0xbc, 0x12, 0x01, 0x02, 0xc0, 0x12, 0x01, 0x02, 0xc4, 0x12, 0x01, 0x02, + 0xc8, 0x12, 0x01, 0x02, 0x58, 0x33, 0x02, 0x03, 0x60, 0x33, 0x02, 0x03, 0x68, 0x33, 0x02, 0x03, 0x70, 0x33, 0x02, 0x03, 0x78, 0x33, 0x02, 0x03, 0x00, 0x10, 0x03, 0x03, 0x08, 0x10, 0x03, 0x03, + 0x10, 0x10, 0x03, 0x03, 0x20, 0x2f, 0x04, 0x04, 0x30, 0x2f, 0x04, 0x04, 0xe0, 0x0c, 0x05, 0x04, 0x80, 0x2b, 0x06, 0x05, 0x20, 0x0b, 0x07, 0x05, 0x40, 0x0a, 0x09, 0x06, 0xb0, 0x22, 0x00, 0x03, + 0xb8, 0x22, 0x00, 0x03, 0xc0, 0x22, 0x00, 0x03, 0xc8, 0x22, 0x00, 0x03, 0xcc, 0x12, 0x01, 0x02, 0xd0, 0x12, 0x01, 0x02, 0xd4, 0x12, 0x01, 0x02, 0xd8, 0x12, 0x01, 0x02, 0xdc, 0x12, 0x01, 0x02, + 0xe0, 0x12, 0x01, 0x02, 0x80, 0x33, 0x02, 0x03, 0x88, 0x33, 0x02, 0x03, 0x90, 0x33, 0x02, 0x03, 0x98, 0x33, 0x02, 0x03, 0xa0, 0x33, 0x02, 0x03, 0x18, 0x10, 0x03, 0x03, 0x20, 0x10, 0x03, 0x03, + 0x28, 0x10, 0x03, 0x03, 0x40, 0x2f, 0x04, 0x04, 0x50, 0x2f, 0x04, 0x04, 0xf0, 0x0c, 0x05, 0x04, 0xa0, 0x2b, 0x06, 0x05, 0x40, 0x0b, 0x07, 0x05, 0x80, 0x0a, 0x09, 0x06, 0xd0, 0x22, 0x00, 0x03, + 0xd8, 0x22, 0x00, 0x03, 0xe0, 0x22, 0x00, 0x03, 0xe8, 0x22, 0x00, 0x03, 0xe4, 0x12, 0x01, 0x02, 0xe8, 0x12, 0x01, 0x02, 0xec, 0x12, 0x01, 0x02, 0xf0, 0x12, 0x01, 0x02, 0xf4, 0x12, 0x01, 0x02, + 0xf8, 0x12, 0x01, 0x02, 0xa8, 0x33, 0x02, 0x03, 0xb0, 0x33, 0x02, 0x03, 0xb8, 0x33, 0x02, 0x03, 0xc0, 0x33, 0x02, 0x03, 0xc8, 0x33, 0x02, 0x03, 0x30, 0x10, 0x03, 0x03, 0x38, 0x10, 0x03, 0x03, + 0x40, 0x10, 0x03, 0x03, 0x60, 0x2f, 0x04, 0x04, 0x70, 0x2f, 0x04, 0x04, 0x00, 0x0d, 0x05, 0x04, 0xc0, 0x2b, 0x06, 0x05, 0x60, 0x0b, 0x07, 0x05, 0xc0, 0x0a, 0x09, 0x06, 0xf0, 0x22, 0x00, 0x03, + 0xf8, 0x22, 0x00, 0x03, 0x00, 0x23, 0x00, 0x03, 0x08, 0x23, 0x00, 0x03, 0xfc, 0x12, 0x01, 0x02, 0x00, 0x13, 0x01, 0x02, 0x04, 0x13, 0x01, 0x02, 0x08, 0x13, 0x01, 0x02, 0x0c, 0x13, 0x01, 0x02, + 0x10, 0x13, 0x01, 0x02, 0xd0, 0x33, 0x02, 0x03, 0xd8, 0x33, 0x02, 0x03, 0xe0, 0x33, 0x02, 0x03, 0xe8, 0x33, 0x02, 0x03, 0xf0, 0x33, 0x02, 0x03, 0x48, 0x10, 0x03, 0x03, 0x50, 0x10, 0x03, 0x03, + 0x58, 0x10, 0x03, 0x03, 0x80, 0x2f, 0x04, 0x04, 0x90, 0x2f, 0x04, 0x04, 0x10, 0x0d, 0x05, 0x04, 0xe0, 0x2b, 0x06, 0x05, 0x80, 0x0b, 0x07, 0x05, 0x00, 0x0b, 0x09, 0x06, 0x10, 0x23, 0x00, 0x03, + 0x18, 0x23, 0x00, 0x03, 0x20, 0x23, 0x00, 0x03, 0x28, 0x23, 0x00, 0x03, 0x14, 0x13, 0x01, 0x02, 0x18, 0x13, 0x01, 0x02, 0x1c, 0x13, 0x01, 0x02, 0x20, 0x13, 0x01, 0x02, 0x24, 0x13, 0x01, 0x02, + 0x28, 0x13, 0x01, 0x02, 0xf8, 0x33, 0x02, 0x03, 0x00, 0x34, 0x02, 0x03, 0x08, 0x34, 0x02, 0x03, 0x10, 0x34, 0x02, 0x03, 0x60, 0x10, 0x03, 0x03, 0x68, 0x10, 0x03, 0x03, 0x70, 0x10, 0x03, 0x03, + 0xa0, 0x2f, 0x04, 0x04, 0xb0, 0x2f, 0x04, 0x04, 0xc0, 0x2f, 0x04, 0x04, 0x20, 0x0d, 0x05, 0x04, 0x00, 0x2c, 0x06, 0x05, 0xa0, 0x0b, 0x07, 0x05, 0x40, 0x0b, 0x09, 0x06, 0x30, 0x23, 0x00, 0x03, + 0x38, 0x23, 0x00, 0x03, 0x40, 0x23, 0x00, 0x03, 0x48, 0x23, 0x00, 0x03, 0x2c, 0x13, 0x01, 0x02, 0x30, 0x13, 0x01, 0x02, 0x34, 0x13, 0x01, 0x02, 0x38, 0x13, 0x01, 0x02, 0x3c, 0x13, 0x01, 0x02, + 0x40, 0x13, 0x01, 0x02, 0x18, 0x34, 0x02, 0x03, 0x20, 0x34, 0x02, 0x03, 0x28, 0x34, 0x02, 0x03, 0x30, 0x34, 0x02, 0x03, 0x78, 0x10, 0x03, 0x03, 0x80, 0x10, 0x03, 0x03, 0x88, 0x10, 0x03, 0x03, + 0xd0, 0x2f, 0x04, 0x04, 0xe0, 0x2f, 0x04, 0x04, 0xf0, 0x2f, 0x04, 0x04, 0x30, 0x0d, 0x05, 0x04, 0x20, 0x2c, 0x06, 0x05, 0xc0, 0x0b, 0x07, 0x05, 0x80, 0x0b, 0x09, 0x06, 0x50, 0x23, 0x00, 0x03, + 0x58, 0x23, 0x00, 0x03, 0x60, 0x23, 0x00, 0x03, 0x68, 0x23, 0x00, 0x03, 0x44, 0x13, 0x01, 0x02, 0x48, 0x13, 0x01, 0x02, 0x4c, 0x13, 0x01, 0x02, 0x50, 0x13, 0x01, 0x02, 0x54, 0x13, 0x01, 0x02, + 0x58, 0x13, 0x01, 0x02, 0x38, 0x34, 0x02, 0x03, 0x40, 0x34, 0x02, 0x03, 0x48, 0x34, 0x02, 0x03, 0x50, 0x34, 0x02, 0x03, 0x90, 0x10, 0x03, 0x03, 0x98, 0x10, 0x03, 0x03, 0xa0, 0x10, 0x03, 0x03, + 0x00, 0x30, 0x04, 0x04, 0x10, 0x30, 0x04, 0x04, 0x20, 0x30, 0x04, 0x04, 0x40, 0x0d, 0x05, 0x04, 0x40, 0x2c, 0x06, 0x05, 0xe0, 0x0b, 0x07, 0x05, 0xc0, 0x0b, 0x09, 0x06, 0x70, 0x23, 0x00, 0x03, + 0x78, 0x23, 0x00, 0x03, 0x80, 0x23, 0x00, 0x03, 0x88, 0x23, 0x00, 0x03, 0x5c, 0x13, 0x01, 0x02, 0x60, 0x13, 0x01, 0x02, 0x64, 0x13, 0x01, 0x02, 0x68, 0x13, 0x01, 0x02, 0x6c, 0x13, 0x01, 0x02, + 0x70, 0x13, 0x01, 0x02, 0x58, 0x34, 0x02, 0x03, 0x60, 0x34, 0x02, 0x03, 0x68, 0x34, 0x02, 0x03, 0x70, 0x34, 0x02, 0x03, 0xa8, 0x10, 0x03, 0x03, 0xb0, 0x10, 0x03, 0x03, 0xb8, 0x10, 0x03, 0x03, + 0x30, 0x30, 0x04, 0x04, 0x40, 0x30, 0x04, 0x04, 0x50, 0x30, 0x04, 0x04, 0x50, 0x0d, 0x05, 0x04, 0x60, 0x2c, 0x06, 0x05, 0x00, 0x0c, 0x07, 0x05, 0x00, 0x0c, 0x09, 0x06, 0x90, 0x23, 0x00, 0x03, + 0x98, 0x23, 0x00, 0x03, 0xa0, 0x23, 0x00, 0x03, 0xa8, 0x23, 0x00, 0x03, 0x74, 0x13, 0x01, 0x02, 0x78, 0x13, 0x01, 0x02, 0x7c, 0x13, 0x01, 0x02, 0x80, 0x13, 0x01, 0x02, 0x84, 0x13, 0x01, 0x02, + 0x88, 0x13, 0x01, 0x02, 0x78, 0x34, 0x02, 0x03, 0x80, 0x34, 0x02, 0x03, 0x88, 0x34, 0x02, 0x03, 0x90, 0x34, 0x02, 0x03, 0xc0, 0x10, 0x03, 0x03, 0xc8, 0x10, 0x03, 0x03, 0xd0, 0x10, 0x03, 0x03, + 0x60, 0x30, 0x04, 0x04, 0x70, 0x30, 0x04, 0x04, 0x80, 0x30, 0x04, 0x04, 0x60, 0x0d, 0x05, 0x04, 0x80, 0x2c, 0x06, 0x05, 0x20, 0x0c, 0x07, 0x05, 0x00, 0x23, 0x0a, 0x07, 0xb0, 0x23, 0x00, 0x03, + 0xb8, 0x23, 0x00, 0x03, 0xc0, 0x23, 0x00, 0x03, 0xc8, 0x23, 0x00, 0x03, 0x8c, 0x13, 0x01, 0x02, 0x90, 0x13, 0x01, 0x02, 0x94, 0x13, 0x01, 0x02, 0x98, 0x13, 0x01, 0x02, 0x9c, 0x13, 0x01, 0x02, + 0xa0, 0x13, 0x01, 0x02, 0x98, 0x34, 0x02, 0x03, 0xa0, 0x34, 0x02, 0x03, 0xa8, 0x34, 0x02, 0x03, 0xb0, 0x34, 0x02, 0x03, 0xd8, 0x10, 0x03, 0x03, 0xe0, 0x10, 0x03, 0x03, 0xe8, 0x10, 0x03, 0x03, + 0x90, 0x30, 0x04, 0x04, 0xa0, 0x30, 0x04, 0x04, 0xb0, 0x30, 0x04, 0x04, 0x70, 0x0d, 0x05, 0x04, 0xa0, 0x2c, 0x06, 0x05, 0x40, 0x0c, 0x07, 0x05, 0x80, 0x23, 0x0a, 0x07, 0xd0, 0x23, 0x00, 0x03, + 0xd8, 0x23, 0x00, 0x03, 0xe0, 0x23, 0x00, 0x03, 0xe8, 0x23, 0x00, 0x03, 0xa4, 0x13, 0x01, 0x02, 0xa8, 0x13, 0x01, 0x02, 0xac, 0x13, 0x01, 0x02, 0xb0, 0x13, 0x01, 0x02, 0xb4, 0x13, 0x01, 0x02, + 0xb8, 0x13, 0x01, 0x02, 0xb8, 0x34, 0x02, 0x03, 0xc0, 0x34, 0x02, 0x03, 0xc8, 0x34, 0x02, 0x03, 0xd0, 0x34, 0x02, 0x03, 0xf0, 0x10, 0x03, 0x03, 0xf8, 0x10, 0x03, 0x03, 0x00, 0x11, 0x03, 0x03, + 0xc0, 0x30, 0x04, 0x04, 0xd0, 0x30, 0x04, 0x04, 0x80, 0x0d, 0x05, 0x04, 0x90, 0x0d, 0x05, 0x04, 0xc0, 0x2c, 0x06, 0x05, 0x60, 0x0c, 0x07, 0x05, 0x00, 0x24, 0x0a, 0x07, 0xf0, 0x23, 0x00, 0x03, + 0xf8, 0x23, 0x00, 0x03, 0x00, 0x24, 0x00, 0x03, 0x08, 0x24, 0x00, 0x03, 0xbc, 0x13, 0x01, 0x02, 0xc0, 0x13, 0x01, 0x02, 0xc4, 0x13, 0x01, 0x02, 0xc8, 0x13, 0x01, 0x02, 0xcc, 0x13, 0x01, 0x02, + 0xd0, 0x13, 0x01, 0x02, 0xd8, 0x34, 0x02, 0x03, 0xe0, 0x34, 0x02, 0x03, 0xe8, 0x34, 0x02, 0x03, 0xf0, 0x34, 0x02, 0x03, 0x08, 0x11, 0x03, 0x03, 0x10, 0x11, 0x03, 0x03, 0x18, 0x11, 0x03, 0x03, + 0xe0, 0x30, 0x04, 0x04, 0xf0, 0x30, 0x04, 0x04, 0xa0, 0x0d, 0x05, 0x04, 0xb0, 0x0d, 0x05, 0x04, 0xe0, 0x2c, 0x06, 0x05, 0x80, 0x0c, 0x07, 0x05, 0x80, 0x24, 0x0a, 0x07, 0x10, 0x24, 0x00, 0x03, + 0x18, 0x24, 0x00, 0x03, 0x20, 0x24, 0x00, 0x03, 0x28, 0x24, 0x00, 0x03, 0xd4, 0x13, 0x01, 0x02, 0xd8, 0x13, 0x01, 0x02, 0xdc, 0x13, 0x01, 0x02, 0xe0, 0x13, 0x01, 0x02, 0xe4, 0x13, 0x01, 0x02, + 0xe8, 0x13, 0x01, 0x02, 0xf8, 0x34, 0x02, 0x03, 0x00, 0x35, 0x02, 0x03, 0x08, 0x35, 0x02, 0x03, 0x10, 0x35, 0x02, 0x03, 0x20, 0x11, 0x03, 0x03, 0x28, 0x11, 0x03, 0x03, 0x30, 0x11, 0x03, 0x03, + 0x00, 0x31, 0x04, 0x04, 0x10, 0x31, 0x04, 0x04, 0xc0, 0x0d, 0x05, 0x04, 0xd0, 0x0d, 0x05, 0x04, 0x00, 0x2d, 0x06, 0x05, 0xa0, 0x0c, 0x07, 0x05, 0x00, 0x25, 0x0a, 0x07, 0x30, 0x24, 0x00, 0x03, + 0x38, 0x24, 0x00, 0x03, 0x40, 0x24, 0x00, 0x03, 0x48, 0x24, 0x00, 0x03, 0xec, 0x13, 0x01, 0x02, 0xf0, 0x13, 0x01, 0x02, 0xf4, 0x13, 0x01, 0x02, 0xf8, 0x13, 0x01, 0x02, 0xfc, 0x13, 0x01, 0x02, + 0x00, 0x14, 0x01, 0x02, 0x18, 0x35, 0x02, 0x03, 0x20, 0x35, 0x02, 0x03, 0x28, 0x35, 0x02, 0x03, 0x30, 0x35, 0x02, 0x03, 0x38, 0x11, 0x03, 0x03, 0x40, 0x11, 0x03, 0x03, 0x48, 0x11, 0x03, 0x03, + 0x20, 0x31, 0x04, 0x04, 0x30, 0x31, 0x04, 0x04, 0xe0, 0x0d, 0x05, 0x04, 0xf0, 0x0d, 0x05, 0x04, 0x20, 0x2d, 0x06, 0x05, 0xc0, 0x0c, 0x07, 0x05, 0x80, 0x25, 0x0a, 0x07, 0x50, 0x24, 0x00, 0x03, + 0x58, 0x24, 0x00, 0x03, 0x60, 0x24, 0x00, 0x03, 0x68, 0x24, 0x00, 0x03, 0x04, 0x14, 0x01, 0x02, 0x08, 0x14, 0x01, 0x02, 0x0c, 0x14, 0x01, 0x02, 0x10, 0x14, 0x01, 0x02, 0x14, 0x14, 0x01, 0x02, + 0x18, 0x14, 0x01, 0x02, 0x38, 0x35, 0x02, 0x03, 0x40, 0x35, 0x02, 0x03, 0x48, 0x35, 0x02, 0x03, 0x50, 0x35, 0x02, 0x03, 0x50, 0x11, 0x03, 0x03, 0x58, 0x11, 0x03, 0x03, 0x60, 0x11, 0x03, 0x03, + 0x40, 0x31, 0x04, 0x04, 0x50, 0x31, 0x04, 0x04, 0x00, 0x0e, 0x05, 0x04, 0x10, 0x0e, 0x05, 0x04, 0x40, 0x2d, 0x06, 0x05, 0xe0, 0x0c, 0x07, 0x05, 0x00, 0x26, 0x0a, 0x07, 0x70, 0x24, 0x00, 0x03, + 0x78, 0x24, 0x00, 0x03, 0x80, 0x24, 0x00, 0x03, 0x88, 0x24, 0x00, 0x03, 0x1c, 0x14, 0x01, 0x02, 0x20, 0x14, 0x01, 0x02, 0x24, 0x14, 0x01, 0x02, 0x28, 0x14, 0x01, 0x02, 0x2c, 0x14, 0x01, 0x02, + 0x30, 0x14, 0x01, 0x02, 0x58, 0x35, 0x02, 0x03, 0x60, 0x35, 0x02, 0x03, 0x68, 0x35, 0x02, 0x03, 0x70, 0x35, 0x02, 0x03, 0x68, 0x11, 0x03, 0x03, 0x70, 0x11, 0x03, 0x03, 0x78, 0x11, 0x03, 0x03, + 0x60, 0x31, 0x04, 0x04, 0x70, 0x31, 0x04, 0x04, 0x20, 0x0e, 0x05, 0x04, 0x30, 0x0e, 0x05, 0x04, 0x60, 0x2d, 0x06, 0x05, 0x00, 0x0d, 0x07, 0x05, 0x80, 0x26, 0x0a, 0x07, 0x90, 0x24, 0x00, 0x03, + 0x98, 0x24, 0x00, 0x03, 0xa0, 0x24, 0x00, 0x03, 0xa8, 0x24, 0x00, 0x03, 0x34, 0x14, 0x01, 0x02, 0x38, 0x14, 0x01, 0x02, 0x3c, 0x14, 0x01, 0x02, 0x40, 0x14, 0x01, 0x02, 0x44, 0x14, 0x01, 0x02, + 0x48, 0x14, 0x01, 0x02, 0x78, 0x35, 0x02, 0x03, 0x80, 0x35, 0x02, 0x03, 0x88, 0x35, 0x02, 0x03, 0x90, 0x35, 0x02, 0x03, 0x80, 0x11, 0x03, 0x03, 0x88, 0x11, 0x03, 0x03, 0x90, 0x11, 0x03, 0x03, + 0x80, 0x31, 0x04, 0x04, 0x90, 0x31, 0x04, 0x04, 0x40, 0x0e, 0x05, 0x04, 0x50, 0x0e, 0x05, 0x04, 0x80, 0x2d, 0x06, 0x05, 0x20, 0x0d, 0x07, 0x05, 0x00, 0x27, 0x0a, 0x07, 0xb0, 0x24, 0x00, 0x03, + 0xb8, 0x24, 0x00, 0x03, 0xc0, 0x24, 0x00, 0x03, 0xc8, 0x24, 0x00, 0x03, 0x4c, 0x14, 0x01, 0x02, 0x50, 0x14, 0x01, 0x02, 0x54, 0x14, 0x01, 0x02, 0x58, 0x14, 0x01, 0x02, 0x5c, 0x14, 0x01, 0x02, + 0x60, 0x14, 0x01, 0x02, 0x98, 0x35, 0x02, 0x03, 0xa0, 0x35, 0x02, 0x03, 0xa8, 0x35, 0x02, 0x03, 0xb0, 0x35, 0x02, 0x03, 0x98, 0x11, 0x03, 0x03, 0xa0, 0x11, 0x03, 0x03, 0xa8, 0x11, 0x03, 0x03, + 0xa0, 0x31, 0x04, 0x04, 0xb0, 0x31, 0x04, 0x04, 0x60, 0x0e, 0x05, 0x04, 0x70, 0x0e, 0x05, 0x04, 0xa0, 0x2d, 0x06, 0x05, 0x40, 0x0d, 0x07, 0x05, 0x80, 0x27, 0x0a, 0x07, 0xd0, 0x24, 0x00, 0x03, + 0xd8, 0x24, 0x00, 0x03, 0xe0, 0x24, 0x00, 0x03, 0xe8, 0x24, 0x00, 0x03, 0x64, 0x14, 0x01, 0x02, 0x68, 0x14, 0x01, 0x02, 0x6c, 0x14, 0x01, 0x02, 0x70, 0x14, 0x01, 0x02, 0x74, 0x14, 0x01, 0x02, + 0x78, 0x14, 0x01, 0x02, 0xb8, 0x35, 0x02, 0x03, 0xc0, 0x35, 0x02, 0x03, 0xc8, 0x35, 0x02, 0x03, 0xd0, 0x35, 0x02, 0x03, 0xb0, 0x11, 0x03, 0x03, 0xb8, 0x11, 0x03, 0x03, 0xc0, 0x11, 0x03, 0x03, + 0xc0, 0x31, 0x04, 0x04, 0xd0, 0x31, 0x04, 0x04, 0x80, 0x0e, 0x05, 0x04, 0x90, 0x0e, 0x05, 0x04, 0xc0, 0x2d, 0x06, 0x05, 0x60, 0x0d, 0x07, 0x05, 0x00, 0x28, 0x0a, 0x07, 0xf0, 0x24, 0x00, 0x03, + 0xf8, 0x24, 0x00, 0x03, 0x00, 0x25, 0x00, 0x03, 0x08, 0x25, 0x00, 0x03, 0x7c, 0x14, 0x01, 0x02, 0x80, 0x14, 0x01, 0x02, 0x84, 0x14, 0x01, 0x02, 0x88, 0x14, 0x01, 0x02, 0x8c, 0x14, 0x01, 0x02, + 0x90, 0x14, 0x01, 0x02, 0xd8, 0x35, 0x02, 0x03, 0xe0, 0x35, 0x02, 0x03, 0xe8, 0x35, 0x02, 0x03, 0xf0, 0x35, 0x02, 0x03, 0xc8, 0x11, 0x03, 0x03, 0xd0, 0x11, 0x03, 0x03, 0xd8, 0x11, 0x03, 0x03, + 0xe0, 0x31, 0x04, 0x04, 0xf0, 0x31, 0x04, 0x04, 0xa0, 0x0e, 0x05, 0x04, 0xb0, 0x0e, 0x05, 0x04, 0xe0, 0x2d, 0x06, 0x05, 0x80, 0x0d, 0x07, 0x05, 0x80, 0x28, 0x0a, 0x07, 0x10, 0x25, 0x00, 0x03, + 0x18, 0x25, 0x00, 0x03, 0x20, 0x25, 0x00, 0x03, 0x28, 0x25, 0x00, 0x03, 0x94, 0x14, 0x01, 0x02, 0x98, 0x14, 0x01, 0x02, 0x9c, 0x14, 0x01, 0x02, 0xa0, 0x14, 0x01, 0x02, 0xa4, 0x14, 0x01, 0x02, + 0xa8, 0x14, 0x01, 0x02, 0xf8, 0x35, 0x02, 0x03, 0x00, 0x36, 0x02, 0x03, 0x08, 0x36, 0x02, 0x03, 0x10, 0x36, 0x02, 0x03, 0xe0, 0x11, 0x03, 0x03, 0xe8, 0x11, 0x03, 0x03, 0xf0, 0x11, 0x03, 0x03, + 0x00, 0x32, 0x04, 0x04, 0x10, 0x32, 0x04, 0x04, 0xc0, 0x0e, 0x05, 0x04, 0xd0, 0x0e, 0x05, 0x04, 0x00, 0x2e, 0x06, 0x05, 0xa0, 0x0d, 0x07, 0x05, 0x00, 0x29, 0x0a, 0x07, 0x30, 0x25, 0x00, 0x03, + 0x38, 0x25, 0x00, 0x03, 0x40, 0x25, 0x00, 0x03, 0x48, 0x25, 0x00, 0x03, 0xac, 0x14, 0x01, 0x02, 0xb0, 0x14, 0x01, 0x02, 0xb4, 0x14, 0x01, 0x02, 0xb8, 0x14, 0x01, 0x02, 0xbc, 0x14, 0x01, 0x02, + 0xc0, 0x14, 0x01, 0x02, 0x18, 0x36, 0x02, 0x03, 0x20, 0x36, 0x02, 0x03, 0x28, 0x36, 0x02, 0x03, 0x30, 0x36, 0x02, 0x03, 0xf8, 0x11, 0x03, 0x03, 0x00, 0x12, 0x03, 0x03, 0x08, 0x12, 0x03, 0x03, + 0x20, 0x32, 0x04, 0x04, 0x30, 0x32, 0x04, 0x04, 0xe0, 0x0e, 0x05, 0x04, 0xf0, 0x0e, 0x05, 0x04, 0x20, 0x2e, 0x06, 0x05, 0xc0, 0x0d, 0x07, 0x05, 0x80, 0x29, 0x0a, 0x07, 0x50, 0x25, 0x00, 0x03, + 0x58, 0x25, 0x00, 0x03, 0x60, 0x25, 0x00, 0x03, 0x68, 0x25, 0x00, 0x03, 0xc4, 0x14, 0x01, 0x02, 0xc8, 0x14, 0x01, 0x02, 0xcc, 0x14, 0x01, 0x02, 0xd0, 0x14, 0x01, 0x02, 0xd4, 0x14, 0x01, 0x02, + 0xd8, 0x14, 0x01, 0x02, 0x38, 0x36, 0x02, 0x03, 0x40, 0x36, 0x02, 0x03, 0x48, 0x36, 0x02, 0x03, 0x50, 0x36, 0x02, 0x03, 0x10, 0x12, 0x03, 0x03, 0x18, 0x12, 0x03, 0x03, 0x20, 0x12, 0x03, 0x03, + 0x40, 0x32, 0x04, 0x04, 0x50, 0x32, 0x04, 0x04, 0x00, 0x0f, 0x05, 0x04, 0x10, 0x0f, 0x05, 0x04, 0x40, 0x2e, 0x06, 0x05, 0xe0, 0x0d, 0x07, 0x05, 0x00, 0x2a, 0x0a, 0x07, 0x70, 0x25, 0x00, 0x03, + 0x78, 0x25, 0x00, 0x03, 0x80, 0x25, 0x00, 0x03, 0x88, 0x25, 0x00, 0x03, 0xdc, 0x14, 0x01, 0x02, 0xe0, 0x14, 0x01, 0x02, 0xe4, 0x14, 0x01, 0x02, 0xe8, 0x14, 0x01, 0x02, 0xec, 0x14, 0x01, 0x02, + 0xf0, 0x14, 0x01, 0x02, 0x58, 0x36, 0x02, 0x03, 0x60, 0x36, 0x02, 0x03, 0x68, 0x36, 0x02, 0x03, 0x70, 0x36, 0x02, 0x03, 0x28, 0x12, 0x03, 0x03, 0x30, 0x12, 0x03, 0x03, 0x38, 0x12, 0x03, 0x03, + 0x60, 0x32, 0x04, 0x04, 0x70, 0x32, 0x04, 0x04, 0x20, 0x0f, 0x05, 0x04, 0x30, 0x0f, 0x05, 0x04, 0x60, 0x2e, 0x06, 0x05, 0x40, 0x26, 0x08, 0x06, 0x80, 0x2a, 0x0a, 0x07, 0x90, 0x25, 0x00, 0x03, + 0x98, 0x25, 0x00, 0x03, 0xa0, 0x25, 0x00, 0x03, 0xa8, 0x25, 0x00, 0x03, 0xf4, 0x14, 0x01, 0x02, 0xf8, 0x14, 0x01, 0x02, 0xfc, 0x14, 0x01, 0x02, 0x00, 0x15, 0x01, 0x02, 0x04, 0x15, 0x01, 0x02, + 0x08, 0x15, 0x01, 0x02, 0x78, 0x36, 0x02, 0x03, 0x80, 0x36, 0x02, 0x03, 0x88, 0x36, 0x02, 0x03, 0x90, 0x36, 0x02, 0x03, 0x40, 0x12, 0x03, 0x03, 0x48, 0x12, 0x03, 0x03, 0x50, 0x12, 0x03, 0x03, + 0x80, 0x32, 0x04, 0x04, 0x90, 0x32, 0x04, 0x04, 0x40, 0x0f, 0x05, 0x04, 0x50, 0x0f, 0x05, 0x04, 0x80, 0x2e, 0x06, 0x05, 0x80, 0x26, 0x08, 0x06, 0x00, 0x2b, 0x0a, 0x07, 0xb0, 0x25, 0x00, 0x03, + 0xb8, 0x25, 0x00, 0x03, 0xc0, 0x25, 0x00, 0x03, 0xc8, 0x25, 0x00, 0x03, 0x0c, 0x15, 0x01, 0x02, 0x10, 0x15, 0x01, 0x02, 0x14, 0x15, 0x01, 0x02, 0x18, 0x15, 0x01, 0x02, 0x1c, 0x15, 0x01, 0x02, + 0x20, 0x15, 0x01, 0x02, 0x98, 0x36, 0x02, 0x03, 0xa0, 0x36, 0x02, 0x03, 0xa8, 0x36, 0x02, 0x03, 0xb0, 0x36, 0x02, 0x03, 0x58, 0x12, 0x03, 0x03, 0x60, 0x12, 0x03, 0x03, 0x68, 0x12, 0x03, 0x03, + 0xa0, 0x32, 0x04, 0x04, 0xb0, 0x32, 0x04, 0x04, 0x60, 0x0f, 0x05, 0x04, 0x70, 0x0f, 0x05, 0x04, 0xa0, 0x2e, 0x06, 0x05, 0xc0, 0x26, 0x08, 0x06, 0x80, 0x2b, 0x0a, 0x07, 0xd0, 0x25, 0x00, 0x03, + 0xd8, 0x25, 0x00, 0x03, 0xe0, 0x25, 0x00, 0x03, 0xe8, 0x25, 0x00, 0x03, 0x24, 0x15, 0x01, 0x02, 0x28, 0x15, 0x01, 0x02, 0x2c, 0x15, 0x01, 0x02, 0x30, 0x15, 0x01, 0x02, 0x34, 0x15, 0x01, 0x02, + 0x38, 0x15, 0x01, 0x02, 0xb8, 0x36, 0x02, 0x03, 0xc0, 0x36, 0x02, 0x03, 0xc8, 0x36, 0x02, 0x03, 0xd0, 0x36, 0x02, 0x03, 0x70, 0x12, 0x03, 0x03, 0x78, 0x12, 0x03, 0x03, 0x80, 0x12, 0x03, 0x03, + 0xc0, 0x32, 0x04, 0x04, 0xd0, 0x32, 0x04, 0x04, 0x80, 0x0f, 0x05, 0x04, 0x90, 0x0f, 0x05, 0x04, 0xc0, 0x2e, 0x06, 0x05, 0x00, 0x27, 0x08, 0x06, 0x00, 0x2c, 0x0a, 0x07, 0xf0, 0x25, 0x00, 0x03, + 0xf8, 0x25, 0x00, 0x03, 0x00, 0x26, 0x00, 0x03, 0x08, 0x26, 0x00, 0x03, 0x3c, 0x15, 0x01, 0x02, 0x40, 0x15, 0x01, 0x02, 0x44, 0x15, 0x01, 0x02, 0x48, 0x15, 0x01, 0x02, 0x4c, 0x15, 0x01, 0x02, + 0x50, 0x15, 0x01, 0x02, 0xd8, 0x36, 0x02, 0x03, 0xe0, 0x36, 0x02, 0x03, 0xe8, 0x36, 0x02, 0x03, 0xf0, 0x36, 0x02, 0x03, 0x88, 0x12, 0x03, 0x03, 0x90, 0x12, 0x03, 0x03, 0x98, 0x12, 0x03, 0x03, + 0xe0, 0x32, 0x04, 0x04, 0xf0, 0x32, 0x04, 0x04, 0xa0, 0x0f, 0x05, 0x04, 0xb0, 0x0f, 0x05, 0x04, 0xe0, 0x2e, 0x06, 0x05, 0x40, 0x27, 0x08, 0x06, 0x80, 0x2c, 0x0a, 0x07, 0x10, 0x26, 0x00, 0x03, + 0x18, 0x26, 0x00, 0x03, 0x20, 0x26, 0x00, 0x03, 0x28, 0x26, 0x00, 0x03, 0x54, 0x15, 0x01, 0x02, 0x58, 0x15, 0x01, 0x02, 0x5c, 0x15, 0x01, 0x02, 0x60, 0x15, 0x01, 0x02, 0x64, 0x15, 0x01, 0x02, + 0x68, 0x15, 0x01, 0x02, 0xf8, 0x36, 0x02, 0x03, 0x00, 0x37, 0x02, 0x03, 0x08, 0x37, 0x02, 0x03, 0x10, 0x37, 0x02, 0x03, 0xa0, 0x12, 0x03, 0x03, 0xa8, 0x12, 0x03, 0x03, 0xb0, 0x12, 0x03, 0x03, + 0x00, 0x33, 0x04, 0x04, 0x10, 0x33, 0x04, 0x04, 0xc0, 0x0f, 0x05, 0x04, 0xd0, 0x0f, 0x05, 0x04, 0x00, 0x2f, 0x06, 0x05, 0x80, 0x27, 0x08, 0x06, 0x80, 0x04, 0x0b, 0x07, 0x30, 0x26, 0x00, 0x03, + 0x38, 0x26, 0x00, 0x03, 0x40, 0x26, 0x00, 0x03, 0x48, 0x26, 0x00, 0x03, 0x6c, 0x15, 0x01, 0x02, 0x70, 0x15, 0x01, 0x02, 0x74, 0x15, 0x01, 0x02, 0x78, 0x15, 0x01, 0x02, 0x7c, 0x15, 0x01, 0x02, + 0x80, 0x15, 0x01, 0x02, 0x18, 0x37, 0x02, 0x03, 0x20, 0x37, 0x02, 0x03, 0x28, 0x37, 0x02, 0x03, 0x30, 0x37, 0x02, 0x03, 0xb8, 0x12, 0x03, 0x03, 0xc0, 0x12, 0x03, 0x03, 0xc8, 0x12, 0x03, 0x03, + 0x20, 0x33, 0x04, 0x04, 0x30, 0x33, 0x04, 0x04, 0xe0, 0x0f, 0x05, 0x04, 0xf0, 0x0f, 0x05, 0x04, 0x20, 0x2f, 0x06, 0x05, 0xc0, 0x27, 0x08, 0x06, 0x00, 0x05, 0x0b, 0x07, 0x50, 0x26, 0x00, 0x03, + 0x58, 0x26, 0x00, 0x03, 0x60, 0x26, 0x00, 0x03, 0x68, 0x26, 0x00, 0x03, 0x84, 0x15, 0x01, 0x02, 0x88, 0x15, 0x01, 0x02, 0x8c, 0x15, 0x01, 0x02, 0x90, 0x15, 0x01, 0x02, 0x94, 0x15, 0x01, 0x02, + 0x98, 0x15, 0x01, 0x02, 0x38, 0x37, 0x02, 0x03, 0x40, 0x37, 0x02, 0x03, 0x48, 0x37, 0x02, 0x03, 0x50, 0x37, 0x02, 0x03, 0xd0, 0x12, 0x03, 0x03, 0xd8, 0x12, 0x03, 0x03, 0xe0, 0x12, 0x03, 0x03, + 0x40, 0x33, 0x04, 0x04, 0x50, 0x33, 0x04, 0x04, 0x00, 0x10, 0x05, 0x04, 0x10, 0x10, 0x05, 0x04, 0x40, 0x2f, 0x06, 0x05, 0x00, 0x28, 0x08, 0x06, 0x80, 0x05, 0x0b, 0x07, 0x70, 0x26, 0x00, 0x03, + 0x78, 0x26, 0x00, 0x03, 0x80, 0x26, 0x00, 0x03, 0x88, 0x26, 0x00, 0x03, 0x9c, 0x15, 0x01, 0x02, 0xa0, 0x15, 0x01, 0x02, 0xa4, 0x15, 0x01, 0x02, 0xa8, 0x15, 0x01, 0x02, 0xac, 0x15, 0x01, 0x02, + 0xb0, 0x15, 0x01, 0x02, 0x58, 0x37, 0x02, 0x03, 0x60, 0x37, 0x02, 0x03, 0x68, 0x37, 0x02, 0x03, 0x70, 0x37, 0x02, 0x03, 0xe8, 0x12, 0x03, 0x03, 0xf0, 0x12, 0x03, 0x03, 0xf8, 0x12, 0x03, 0x03, + 0x60, 0x33, 0x04, 0x04, 0x70, 0x33, 0x04, 0x04, 0x20, 0x10, 0x05, 0x04, 0x30, 0x10, 0x05, 0x04, 0x60, 0x2f, 0x06, 0x05, 0x40, 0x28, 0x08, 0x06, 0x00, 0x06, 0x0b, 0x07, 0x90, 0x26, 0x00, 0x03, + 0x98, 0x26, 0x00, 0x03, 0xa0, 0x26, 0x00, 0x03, 0xa8, 0x26, 0x00, 0x03, 0xb4, 0x15, 0x01, 0x02, 0xb8, 0x15, 0x01, 0x02, 0xbc, 0x15, 0x01, 0x02, 0xc0, 0x15, 0x01, 0x02, 0xc4, 0x15, 0x01, 0x02, + 0xc8, 0x15, 0x01, 0x02, 0x78, 0x37, 0x02, 0x03, 0x80, 0x37, 0x02, 0x03, 0x88, 0x37, 0x02, 0x03, 0x90, 0x37, 0x02, 0x03, 0x00, 0x13, 0x03, 0x03, 0x08, 0x13, 0x03, 0x03, 0x10, 0x13, 0x03, 0x03, + 0x80, 0x33, 0x04, 0x04, 0x90, 0x33, 0x04, 0x04, 0x40, 0x10, 0x05, 0x04, 0x50, 0x10, 0x05, 0x04, 0x80, 0x2f, 0x06, 0x05, 0x80, 0x28, 0x08, 0x06, 0x80, 0x06, 0x0b, 0x07, 0xb0, 0x26, 0x00, 0x03, + 0xb8, 0x26, 0x00, 0x03, 0xc0, 0x26, 0x00, 0x03, 0xc8, 0x26, 0x00, 0x03, 0xcc, 0x15, 0x01, 0x02, 0xd0, 0x15, 0x01, 0x02, 0xd4, 0x15, 0x01, 0x02, 0xd8, 0x15, 0x01, 0x02, 0xdc, 0x15, 0x01, 0x02, + 0xe0, 0x15, 0x01, 0x02, 0x98, 0x37, 0x02, 0x03, 0xa0, 0x37, 0x02, 0x03, 0xa8, 0x37, 0x02, 0x03, 0xb0, 0x37, 0x02, 0x03, 0x18, 0x13, 0x03, 0x03, 0x20, 0x13, 0x03, 0x03, 0x28, 0x13, 0x03, 0x03, + 0xa0, 0x33, 0x04, 0x04, 0xb0, 0x33, 0x04, 0x04, 0x60, 0x10, 0x05, 0x04, 0x70, 0x10, 0x05, 0x04, 0xa0, 0x2f, 0x06, 0x05, 0xc0, 0x28, 0x08, 0x06, 0x00, 0x07, 0x0b, 0x07, 0xd0, 0x26, 0x00, 0x03, + 0xd8, 0x26, 0x00, 0x03, 0xe0, 0x26, 0x00, 0x03, 0xe8, 0x26, 0x00, 0x03, 0xe4, 0x15, 0x01, 0x02, 0xe8, 0x15, 0x01, 0x02, 0xec, 0x15, 0x01, 0x02, 0xf0, 0x15, 0x01, 0x02, 0xf4, 0x15, 0x01, 0x02, + 0xf8, 0x15, 0x01, 0x02, 0xb8, 0x37, 0x02, 0x03, 0xc0, 0x37, 0x02, 0x03, 0xc8, 0x37, 0x02, 0x03, 0xd0, 0x37, 0x02, 0x03, 0x30, 0x13, 0x03, 0x03, 0x38, 0x13, 0x03, 0x03, 0x40, 0x13, 0x03, 0x03, + 0xc0, 0x33, 0x04, 0x04, 0xd0, 0x33, 0x04, 0x04, 0x80, 0x10, 0x05, 0x04, 0x90, 0x10, 0x05, 0x04, 0xc0, 0x2f, 0x06, 0x05, 0x00, 0x29, 0x08, 0x06, 0x80, 0x07, 0x0b, 0x07, 0xf0, 0x26, 0x00, 0x03, + 0xf8, 0x26, 0x00, 0x03, 0x00, 0x27, 0x00, 0x03, 0x08, 0x27, 0x00, 0x03, 0xfc, 0x15, 0x01, 0x02, 0x00, 0x16, 0x01, 0x02, 0x04, 0x16, 0x01, 0x02, 0x08, 0x16, 0x01, 0x02, 0x0c, 0x16, 0x01, 0x02, + 0x10, 0x16, 0x01, 0x02, 0xd8, 0x37, 0x02, 0x03, 0xe0, 0x37, 0x02, 0x03, 0xe8, 0x37, 0x02, 0x03, 0xf0, 0x37, 0x02, 0x03, 0x48, 0x13, 0x03, 0x03, 0x50, 0x13, 0x03, 0x03, 0x58, 0x13, 0x03, 0x03, + 0xe0, 0x33, 0x04, 0x04, 0xf0, 0x33, 0x04, 0x04, 0xa0, 0x10, 0x05, 0x04, 0xb0, 0x10, 0x05, 0x04, 0xe0, 0x2f, 0x06, 0x05, 0x40, 0x29, 0x08, 0x06, 0x00, 0x08, 0x0b, 0x07, 0x10, 0x27, 0x00, 0x03, + 0x18, 0x27, 0x00, 0x03, 0x20, 0x27, 0x00, 0x03, 0x28, 0x27, 0x00, 0x03, 0x14, 0x16, 0x01, 0x02, 0x18, 0x16, 0x01, 0x02, 0x1c, 0x16, 0x01, 0x02, 0x20, 0x16, 0x01, 0x02, 0x24, 0x16, 0x01, 0x02, + 0x28, 0x16, 0x01, 0x02, 0xf8, 0x37, 0x02, 0x03, 0x00, 0x38, 0x02, 0x03, 0x08, 0x38, 0x02, 0x03, 0x10, 0x38, 0x02, 0x03, 0x60, 0x13, 0x03, 0x03, 0x68, 0x13, 0x03, 0x03, 0x70, 0x13, 0x03, 0x03, + 0x00, 0x34, 0x04, 0x04, 0x10, 0x34, 0x04, 0x04, 0xc0, 0x10, 0x05, 0x04, 0xd0, 0x10, 0x05, 0x04, 0x00, 0x30, 0x06, 0x05, 0x80, 0x29, 0x08, 0x06, 0x80, 0x08, 0x0b, 0x07, 0x30, 0x27, 0x00, 0x03, + 0x38, 0x27, 0x00, 0x03, 0x40, 0x27, 0x00, 0x03, 0x48, 0x27, 0x00, 0x03, 0x2c, 0x16, 0x01, 0x02, 0x30, 0x16, 0x01, 0x02, 0x34, 0x16, 0x01, 0x02, 0x38, 0x16, 0x01, 0x02, 0x3c, 0x16, 0x01, 0x02, + 0x40, 0x16, 0x01, 0x02, 0x18, 0x38, 0x02, 0x03, 0x20, 0x38, 0x02, 0x03, 0x28, 0x38, 0x02, 0x03, 0x30, 0x38, 0x02, 0x03, 0x78, 0x13, 0x03, 0x03, 0x80, 0x13, 0x03, 0x03, 0x88, 0x13, 0x03, 0x03, + 0x20, 0x34, 0x04, 0x04, 0x30, 0x34, 0x04, 0x04, 0xe0, 0x10, 0x05, 0x04, 0xf0, 0x10, 0x05, 0x04, 0x20, 0x30, 0x06, 0x05, 0xc0, 0x29, 0x08, 0x06, 0x00, 0x09, 0x0b, 0x07, 0x50, 0x27, 0x00, 0x03, + 0x58, 0x27, 0x00, 0x03, 0x60, 0x27, 0x00, 0x03, 0x68, 0x27, 0x00, 0x03, 0x44, 0x16, 0x01, 0x02, 0x48, 0x16, 0x01, 0x02, 0x4c, 0x16, 0x01, 0x02, 0x50, 0x16, 0x01, 0x02, 0x54, 0x16, 0x01, 0x02, + 0x58, 0x16, 0x01, 0x02, 0x38, 0x38, 0x02, 0x03, 0x40, 0x38, 0x02, 0x03, 0x48, 0x38, 0x02, 0x03, 0x50, 0x38, 0x02, 0x03, 0x90, 0x13, 0x03, 0x03, 0x98, 0x13, 0x03, 0x03, 0xa0, 0x13, 0x03, 0x03, + 0x40, 0x34, 0x04, 0x04, 0x50, 0x34, 0x04, 0x04, 0x00, 0x11, 0x05, 0x04, 0x10, 0x11, 0x05, 0x04, 0x40, 0x30, 0x06, 0x05, 0x00, 0x2a, 0x08, 0x06, 0x80, 0x09, 0x0b, 0x07, 0x70, 0x27, 0x00, 0x03, + 0x78, 0x27, 0x00, 0x03, 0x80, 0x27, 0x00, 0x03, 0x88, 0x27, 0x00, 0x03, 0x5c, 0x16, 0x01, 0x02, 0x60, 0x16, 0x01, 0x02, 0x64, 0x16, 0x01, 0x02, 0x68, 0x16, 0x01, 0x02, 0x6c, 0x16, 0x01, 0x02, + 0x70, 0x16, 0x01, 0x02, 0x58, 0x38, 0x02, 0x03, 0x60, 0x38, 0x02, 0x03, 0x68, 0x38, 0x02, 0x03, 0x70, 0x38, 0x02, 0x03, 0xa8, 0x13, 0x03, 0x03, 0xb0, 0x13, 0x03, 0x03, 0xb8, 0x13, 0x03, 0x03, + 0x60, 0x34, 0x04, 0x04, 0x70, 0x34, 0x04, 0x04, 0x20, 0x11, 0x05, 0x04, 0x30, 0x11, 0x05, 0x04, 0x60, 0x30, 0x06, 0x05, 0x40, 0x2a, 0x08, 0x06, 0x00, 0x0a, 0x0b, 0x07, 0x90, 0x27, 0x00, 0x03, + 0x98, 0x27, 0x00, 0x03, 0xa0, 0x27, 0x00, 0x03, 0xa8, 0x27, 0x00, 0x03, 0x74, 0x16, 0x01, 0x02, 0x78, 0x16, 0x01, 0x02, 0x7c, 0x16, 0x01, 0x02, 0x80, 0x16, 0x01, 0x02, 0x84, 0x16, 0x01, 0x02, + 0x88, 0x16, 0x01, 0x02, 0x78, 0x38, 0x02, 0x03, 0x80, 0x38, 0x02, 0x03, 0x88, 0x38, 0x02, 0x03, 0x90, 0x38, 0x02, 0x03, 0xc0, 0x13, 0x03, 0x03, 0xc8, 0x13, 0x03, 0x03, 0xd0, 0x13, 0x03, 0x03, + 0x80, 0x34, 0x04, 0x04, 0x90, 0x34, 0x04, 0x04, 0x40, 0x11, 0x05, 0x04, 0x50, 0x11, 0x05, 0x04, 0x80, 0x30, 0x06, 0x05, 0x80, 0x2a, 0x08, 0x06, 0x80, 0x0a, 0x0b, 0x07, 0xb0, 0x27, 0x00, 0x03, + 0xb8, 0x27, 0x00, 0x03, 0xc0, 0x27, 0x00, 0x03, 0xc8, 0x27, 0x00, 0x03, 0x8c, 0x16, 0x01, 0x02, 0x90, 0x16, 0x01, 0x02, 0x94, 0x16, 0x01, 0x02, 0x98, 0x16, 0x01, 0x02, 0x9c, 0x16, 0x01, 0x02, + 0xa0, 0x16, 0x01, 0x02, 0x98, 0x38, 0x02, 0x03, 0xa0, 0x38, 0x02, 0x03, 0xa8, 0x38, 0x02, 0x03, 0xb0, 0x38, 0x02, 0x03, 0xd8, 0x13, 0x03, 0x03, 0xe0, 0x13, 0x03, 0x03, 0xe8, 0x13, 0x03, 0x03, + 0xa0, 0x34, 0x04, 0x04, 0xb0, 0x34, 0x04, 0x04, 0x60, 0x11, 0x05, 0x04, 0x70, 0x11, 0x05, 0x04, 0xa0, 0x30, 0x06, 0x05, 0xc0, 0x2a, 0x08, 0x06, 0x00, 0x0b, 0x0b, 0x07, 0xd0, 0x27, 0x00, 0x03, + 0xd8, 0x27, 0x00, 0x03, 0xe0, 0x27, 0x00, 0x03, 0xe8, 0x27, 0x00, 0x03, 0xa4, 0x16, 0x01, 0x02, 0xa8, 0x16, 0x01, 0x02, 0xac, 0x16, 0x01, 0x02, 0xb0, 0x16, 0x01, 0x02, 0xb4, 0x16, 0x01, 0x02, + 0xb8, 0x16, 0x01, 0x02, 0xb8, 0x38, 0x02, 0x03, 0xc0, 0x38, 0x02, 0x03, 0xc8, 0x38, 0x02, 0x03, 0xd0, 0x38, 0x02, 0x03, 0xf0, 0x13, 0x03, 0x03, 0xf8, 0x13, 0x03, 0x03, 0x00, 0x14, 0x03, 0x03, + 0xc0, 0x34, 0x04, 0x04, 0xd0, 0x34, 0x04, 0x04, 0x80, 0x11, 0x05, 0x04, 0x90, 0x11, 0x05, 0x04, 0xc0, 0x30, 0x06, 0x05, 0x00, 0x2b, 0x08, 0x06, 0x00, 0x1f, 0x0c, 0x08, 0xf0, 0x27, 0x00, 0x03, + 0xf8, 0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x03, 0x08, 0x28, 0x00, 0x03, 0xbc, 0x16, 0x01, 0x02, 0xc0, 0x16, 0x01, 0x02, 0xc4, 0x16, 0x01, 0x02, 0xc8, 0x16, 0x01, 0x02, 0xcc, 0x16, 0x01, 0x02, + 0xd0, 0x16, 0x01, 0x02, 0xd8, 0x38, 0x02, 0x03, 0xe0, 0x38, 0x02, 0x03, 0xe8, 0x38, 0x02, 0x03, 0xf0, 0x38, 0x02, 0x03, 0x08, 0x14, 0x03, 0x03, 0x10, 0x14, 0x03, 0x03, 0x18, 0x14, 0x03, 0x03, + 0xe0, 0x34, 0x04, 0x04, 0xf0, 0x34, 0x04, 0x04, 0xa0, 0x11, 0x05, 0x04, 0xb0, 0x11, 0x05, 0x04, 0xe0, 0x30, 0x06, 0x05, 0x40, 0x2b, 0x08, 0x06, 0x00, 0x20, 0x0c, 0x08, 0x10, 0x28, 0x00, 0x03, + 0x18, 0x28, 0x00, 0x03, 0x20, 0x28, 0x00, 0x03, 0x28, 0x28, 0x00, 0x03, 0xd4, 0x16, 0x01, 0x02, 0xd8, 0x16, 0x01, 0x02, 0xdc, 0x16, 0x01, 0x02, 0xe0, 0x16, 0x01, 0x02, 0xe4, 0x16, 0x01, 0x02, + 0xe8, 0x16, 0x01, 0x02, 0xf8, 0x38, 0x02, 0x03, 0x00, 0x39, 0x02, 0x03, 0x08, 0x39, 0x02, 0x03, 0x10, 0x39, 0x02, 0x03, 0x20, 0x14, 0x03, 0x03, 0x28, 0x14, 0x03, 0x03, 0x30, 0x14, 0x03, 0x03, + 0x00, 0x35, 0x04, 0x04, 0x10, 0x35, 0x04, 0x04, 0xc0, 0x11, 0x05, 0x04, 0xd0, 0x11, 0x05, 0x04, 0x00, 0x31, 0x06, 0x05, 0x80, 0x2b, 0x08, 0x06, 0x00, 0x21, 0x0c, 0x08, 0x30, 0x28, 0x00, 0x03, + 0x38, 0x28, 0x00, 0x03, 0x40, 0x28, 0x00, 0x03, 0x48, 0x28, 0x00, 0x03, 0xec, 0x16, 0x01, 0x02, 0xf0, 0x16, 0x01, 0x02, 0xf4, 0x16, 0x01, 0x02, 0xf8, 0x16, 0x01, 0x02, 0xfc, 0x16, 0x01, 0x02, + 0x00, 0x17, 0x01, 0x02, 0x18, 0x39, 0x02, 0x03, 0x20, 0x39, 0x02, 0x03, 0x28, 0x39, 0x02, 0x03, 0x30, 0x39, 0x02, 0x03, 0x38, 0x14, 0x03, 0x03, 0x40, 0x14, 0x03, 0x03, 0x48, 0x14, 0x03, 0x03, + 0x20, 0x35, 0x04, 0x04, 0x30, 0x35, 0x04, 0x04, 0xe0, 0x11, 0x05, 0x04, 0xf0, 0x11, 0x05, 0x04, 0x20, 0x31, 0x06, 0x05, 0xc0, 0x2b, 0x08, 0x06, 0x00, 0x22, 0x0c, 0x08, 0x50, 0x28, 0x00, 0x03, + 0x58, 0x28, 0x00, 0x03, 0x60, 0x28, 0x00, 0x03, 0x68, 0x28, 0x00, 0x03, 0x04, 0x17, 0x01, 0x02, 0x08, 0x17, 0x01, 0x02, 0x0c, 0x17, 0x01, 0x02, 0x10, 0x17, 0x01, 0x02, 0x14, 0x17, 0x01, 0x02, + 0x18, 0x17, 0x01, 0x02, 0x38, 0x39, 0x02, 0x03, 0x40, 0x39, 0x02, 0x03, 0x48, 0x39, 0x02, 0x03, 0x50, 0x39, 0x02, 0x03, 0x50, 0x14, 0x03, 0x03, 0x58, 0x14, 0x03, 0x03, 0x60, 0x14, 0x03, 0x03, + 0x40, 0x35, 0x04, 0x04, 0x50, 0x35, 0x04, 0x04, 0x00, 0x12, 0x05, 0x04, 0x10, 0x12, 0x05, 0x04, 0x40, 0x31, 0x06, 0x05, 0x00, 0x2c, 0x08, 0x06, 0x00, 0x23, 0x0c, 0x08, 0x70, 0x28, 0x00, 0x03, + 0x78, 0x28, 0x00, 0x03, 0x80, 0x28, 0x00, 0x03, 0x1c, 0x17, 0x01, 0x02, 0x20, 0x17, 0x01, 0x02, 0x24, 0x17, 0x01, 0x02, 0x28, 0x17, 0x01, 0x02, 0x2c, 0x17, 0x01, 0x02, 0x30, 0x17, 0x01, 0x02, + 0x34, 0x17, 0x01, 0x02, 0x58, 0x39, 0x02, 0x03, 0x60, 0x39, 0x02, 0x03, 0x68, 0x39, 0x02, 0x03, 0x70, 0x39, 0x02, 0x03, 0x68, 0x14, 0x03, 0x03, 0x70, 0x14, 0x03, 0x03, 0x78, 0x14, 0x03, 0x03, + 0x60, 0x35, 0x04, 0x04, 0x70, 0x35, 0x04, 0x04, 0x20, 0x12, 0x05, 0x04, 0x30, 0x12, 0x05, 0x04, 0x60, 0x31, 0x06, 0x05, 0x40, 0x2c, 0x08, 0x06, 0x00, 0x24, 0x0c, 0x08, 0x88, 0x28, 0x00, 0x03, + 0x90, 0x28, 0x00, 0x03, 0x98, 0x28, 0x00, 0x03, 0x38, 0x17, 0x01, 0x02, 0x3c, 0x17, 0x01, 0x02, 0x40, 0x17, 0x01, 0x02, 0x44, 0x17, 0x01, 0x02, 0x48, 0x17, 0x01, 0x02, 0x4c, 0x17, 0x01, 0x02, + 0x50, 0x17, 0x01, 0x02, 0x78, 0x39, 0x02, 0x03, 0x80, 0x39, 0x02, 0x03, 0x88, 0x39, 0x02, 0x03, 0x90, 0x39, 0x02, 0x03, 0x80, 0x14, 0x03, 0x03, 0x88, 0x14, 0x03, 0x03, 0x90, 0x14, 0x03, 0x03, + 0x80, 0x35, 0x04, 0x04, 0x90, 0x35, 0x04, 0x04, 0x40, 0x12, 0x05, 0x04, 0x80, 0x31, 0x06, 0x05, 0x00, 0x0e, 0x07, 0x05, 0x80, 0x2c, 0x08, 0x06, 0x00, 0x25, 0x0c, 0x08, 0xa0, 0x28, 0x00, 0x03, + 0xa8, 0x28, 0x00, 0x03, 0xb0, 0x28, 0x00, 0x03, 0x54, 0x17, 0x01, 0x02, 0x58, 0x17, 0x01, 0x02, 0x5c, 0x17, 0x01, 0x02, 0x60, 0x17, 0x01, 0x02, 0x64, 0x17, 0x01, 0x02, 0x68, 0x17, 0x01, 0x02, + 0x6c, 0x17, 0x01, 0x02, 0x98, 0x39, 0x02, 0x03, 0xa0, 0x39, 0x02, 0x03, 0xa8, 0x39, 0x02, 0x03, 0xb0, 0x39, 0x02, 0x03, 0x98, 0x14, 0x03, 0x03, 0xa0, 0x14, 0x03, 0x03, 0xa8, 0x14, 0x03, 0x03, + 0xa0, 0x35, 0x04, 0x04, 0xb0, 0x35, 0x04, 0x04, 0x50, 0x12, 0x05, 0x04, 0xa0, 0x31, 0x06, 0x05, 0x20, 0x0e, 0x07, 0x05, 0xc0, 0x2c, 0x08, 0x06, 0x00, 0x26, 0x0c, 0x08, 0xb8, 0x28, 0x00, 0x03, + 0xc0, 0x28, 0x00, 0x03, 0xc8, 0x28, 0x00, 0x03, 0x70, 0x17, 0x01, 0x02, 0x74, 0x17, 0x01, 0x02, 0x78, 0x17, 0x01, 0x02, 0x7c, 0x17, 0x01, 0x02, 0x80, 0x17, 0x01, 0x02, 0x84, 0x17, 0x01, 0x02, + 0x88, 0x17, 0x01, 0x02, 0xb8, 0x39, 0x02, 0x03, 0xc0, 0x39, 0x02, 0x03, 0xc8, 0x39, 0x02, 0x03, 0xd0, 0x39, 0x02, 0x03, 0xb0, 0x14, 0x03, 0x03, 0xb8, 0x14, 0x03, 0x03, 0xc0, 0x14, 0x03, 0x03, + 0xc0, 0x35, 0x04, 0x04, 0xd0, 0x35, 0x04, 0x04, 0x60, 0x12, 0x05, 0x04, 0xc0, 0x31, 0x06, 0x05, 0x40, 0x0e, 0x07, 0x05, 0x00, 0x2d, 0x08, 0x06, 0x00, 0x27, 0x0c, 0x08, 0xd0, 0x28, 0x00, 0x03, + 0xd8, 0x28, 0x00, 0x03, 0xe0, 0x28, 0x00, 0x03, 0x8c, 0x17, 0x01, 0x02, 0x90, 0x17, 0x01, 0x02, 0x94, 0x17, 0x01, 0x02, 0x98, 0x17, 0x01, 0x02, 0x9c, 0x17, 0x01, 0x02, 0xa0, 0x17, 0x01, 0x02, + 0xa4, 0x17, 0x01, 0x02, 0xd8, 0x39, 0x02, 0x03, 0xe0, 0x39, 0x02, 0x03, 0xe8, 0x39, 0x02, 0x03, 0xf0, 0x39, 0x02, 0x03, 0xc8, 0x14, 0x03, 0x03, 0xd0, 0x14, 0x03, 0x03, 0xd8, 0x14, 0x03, 0x03, + 0xe0, 0x35, 0x04, 0x04, 0xf0, 0x35, 0x04, 0x04, 0x70, 0x12, 0x05, 0x04, 0xe0, 0x31, 0x06, 0x05, 0x60, 0x0e, 0x07, 0x05, 0x40, 0x2d, 0x08, 0x06, 0x00, 0x02, 0x0d, 0x08, 0xe8, 0x28, 0x00, 0x03, + 0xf0, 0x28, 0x00, 0x03, 0xf8, 0x28, 0x00, 0x03, 0xa8, 0x17, 0x01, 0x02, 0xac, 0x17, 0x01, 0x02, 0xb0, 0x17, 0x01, 0x02, 0xb4, 0x17, 0x01, 0x02, 0xb8, 0x17, 0x01, 0x02, 0xbc, 0x17, 0x01, 0x02, + 0xc0, 0x17, 0x01, 0x02, 0xf8, 0x39, 0x02, 0x03, 0x00, 0x3a, 0x02, 0x03, 0x08, 0x3a, 0x02, 0x03, 0x10, 0x3a, 0x02, 0x03, 0xe0, 0x14, 0x03, 0x03, 0xe8, 0x14, 0x03, 0x03, 0xf0, 0x14, 0x03, 0x03, + 0x00, 0x36, 0x04, 0x04, 0x10, 0x36, 0x04, 0x04, 0x80, 0x12, 0x05, 0x04, 0x00, 0x32, 0x06, 0x05, 0x80, 0x0e, 0x07, 0x05, 0x80, 0x2d, 0x08, 0x06, 0x00, 0x03, 0x0d, 0x08, 0x00, 0x29, 0x00, 0x03, + 0x08, 0x29, 0x00, 0x03, 0x10, 0x29, 0x00, 0x03, 0xc4, 0x17, 0x01, 0x02, 0xc8, 0x17, 0x01, 0x02, 0xcc, 0x17, 0x01, 0x02, 0xd0, 0x17, 0x01, 0x02, 0xd4, 0x17, 0x01, 0x02, 0xd8, 0x17, 0x01, 0x02, + 0xdc, 0x17, 0x01, 0x02, 0x18, 0x3a, 0x02, 0x03, 0x20, 0x3a, 0x02, 0x03, 0x28, 0x3a, 0x02, 0x03, 0x30, 0x3a, 0x02, 0x03, 0xf8, 0x14, 0x03, 0x03, 0x00, 0x15, 0x03, 0x03, 0x08, 0x15, 0x03, 0x03, + 0x20, 0x36, 0x04, 0x04, 0x30, 0x36, 0x04, 0x04, 0x90, 0x12, 0x05, 0x04, 0x20, 0x32, 0x06, 0x05, 0xa0, 0x0e, 0x07, 0x05, 0xc0, 0x2d, 0x08, 0x06, 0x00, 0x04, 0x0d, 0x08, 0x18, 0x29, 0x00, 0x03, + 0x20, 0x29, 0x00, 0x03, 0x28, 0x29, 0x00, 0x03, 0xe0, 0x17, 0x01, 0x02, 0xe4, 0x17, 0x01, 0x02, 0xe8, 0x17, 0x01, 0x02, 0xec, 0x17, 0x01, 0x02, 0xf0, 0x17, 0x01, 0x02, 0xf4, 0x17, 0x01, 0x02, + 0xf8, 0x17, 0x01, 0x02, 0x38, 0x3a, 0x02, 0x03, 0x40, 0x3a, 0x02, 0x03, 0x48, 0x3a, 0x02, 0x03, 0x50, 0x3a, 0x02, 0x03, 0x10, 0x15, 0x03, 0x03, 0x18, 0x15, 0x03, 0x03, 0x20, 0x15, 0x03, 0x03, + 0x40, 0x36, 0x04, 0x04, 0x50, 0x36, 0x04, 0x04, 0xa0, 0x12, 0x05, 0x04, 0x40, 0x32, 0x06, 0x05, 0xc0, 0x0e, 0x07, 0x05, 0x00, 0x2e, 0x08, 0x06, 0x00, 0x05, 0x0d, 0x08, 0x30, 0x29, 0x00, 0x03, + 0x38, 0x29, 0x00, 0x03, 0x40, 0x29, 0x00, 0x03, 0xfc, 0x17, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x04, 0x18, 0x01, 0x02, 0x08, 0x18, 0x01, 0x02, 0x0c, 0x18, 0x01, 0x02, 0x10, 0x18, 0x01, 0x02, + 0x14, 0x18, 0x01, 0x02, 0x58, 0x3a, 0x02, 0x03, 0x60, 0x3a, 0x02, 0x03, 0x68, 0x3a, 0x02, 0x03, 0x70, 0x3a, 0x02, 0x03, 0x28, 0x15, 0x03, 0x03, 0x30, 0x15, 0x03, 0x03, 0x38, 0x15, 0x03, 0x03, + 0x60, 0x36, 0x04, 0x04, 0x70, 0x36, 0x04, 0x04, 0xb0, 0x12, 0x05, 0x04, 0x60, 0x32, 0x06, 0x05, 0xe0, 0x0e, 0x07, 0x05, 0x40, 0x2e, 0x08, 0x06, 0x00, 0x06, 0x0d, 0x08, 0x48, 0x29, 0x00, 0x03, + 0x50, 0x29, 0x00, 0x03, 0x58, 0x29, 0x00, 0x03, 0x18, 0x18, 0x01, 0x02, 0x1c, 0x18, 0x01, 0x02, 0x20, 0x18, 0x01, 0x02, 0x24, 0x18, 0x01, 0x02, 0x28, 0x18, 0x01, 0x02, 0x2c, 0x18, 0x01, 0x02, + 0x30, 0x18, 0x01, 0x02, 0x78, 0x3a, 0x02, 0x03, 0x80, 0x3a, 0x02, 0x03, 0x88, 0x3a, 0x02, 0x03, 0x90, 0x3a, 0x02, 0x03, 0x40, 0x15, 0x03, 0x03, 0x48, 0x15, 0x03, 0x03, 0x50, 0x15, 0x03, 0x03, + 0x80, 0x36, 0x04, 0x04, 0x90, 0x36, 0x04, 0x04, 0xc0, 0x12, 0x05, 0x04, 0x80, 0x32, 0x06, 0x05, 0x00, 0x0f, 0x07, 0x05, 0x80, 0x2e, 0x08, 0x06, 0x00, 0x07, 0x0d, 0x08, 0x60, 0x29, 0x00, 0x03, + 0x68, 0x29, 0x00, 0x03, 0x70, 0x29, 0x00, 0x03, 0x34, 0x18, 0x01, 0x02, 0x38, 0x18, 0x01, 0x02, 0x3c, 0x18, 0x01, 0x02, 0x40, 0x18, 0x01, 0x02, 0x44, 0x18, 0x01, 0x02, 0x48, 0x18, 0x01, 0x02, + 0x4c, 0x18, 0x01, 0x02, 0x98, 0x3a, 0x02, 0x03, 0xa0, 0x3a, 0x02, 0x03, 0xa8, 0x3a, 0x02, 0x03, 0xb0, 0x3a, 0x02, 0x03, 0x58, 0x15, 0x03, 0x03, 0x60, 0x15, 0x03, 0x03, 0x68, 0x15, 0x03, 0x03, + 0xa0, 0x36, 0x04, 0x04, 0xb0, 0x36, 0x04, 0x04, 0xd0, 0x12, 0x05, 0x04, 0xa0, 0x32, 0x06, 0x05, 0x20, 0x0f, 0x07, 0x05, 0xc0, 0x2e, 0x08, 0x06, 0x00, 0x08, 0x0d, 0x08, 0x78, 0x29, 0x00, 0x03, + 0x80, 0x29, 0x00, 0x03, 0x88, 0x29, 0x00, 0x03, 0x50, 0x18, 0x01, 0x02, 0x54, 0x18, 0x01, 0x02, 0x58, 0x18, 0x01, 0x02, 0x5c, 0x18, 0x01, 0x02, 0x60, 0x18, 0x01, 0x02, 0x64, 0x18, 0x01, 0x02, + 0x68, 0x18, 0x01, 0x02, 0xb8, 0x3a, 0x02, 0x03, 0xc0, 0x3a, 0x02, 0x03, 0xc8, 0x3a, 0x02, 0x03, 0xd0, 0x3a, 0x02, 0x03, 0x70, 0x15, 0x03, 0x03, 0x78, 0x15, 0x03, 0x03, 0x80, 0x15, 0x03, 0x03, + 0xc0, 0x36, 0x04, 0x04, 0xd0, 0x36, 0x04, 0x04, 0xe0, 0x12, 0x05, 0x04, 0xc0, 0x32, 0x06, 0x05, 0x40, 0x0f, 0x07, 0x05, 0x00, 0x2f, 0x08, 0x06, 0x00, 0x1e, 0x0e, 0x09, 0x90, 0x29, 0x00, 0x03, + 0x98, 0x29, 0x00, 0x03, 0xa0, 0x29, 0x00, 0x03, 0x6c, 0x18, 0x01, 0x02, 0x70, 0x18, 0x01, 0x02, 0x74, 0x18, 0x01, 0x02, 0x78, 0x18, 0x01, 0x02, 0x7c, 0x18, 0x01, 0x02, 0x80, 0x18, 0x01, 0x02, + 0x84, 0x18, 0x01, 0x02, 0xd8, 0x3a, 0x02, 0x03, 0xe0, 0x3a, 0x02, 0x03, 0xe8, 0x3a, 0x02, 0x03, 0xf0, 0x3a, 0x02, 0x03, 0x88, 0x15, 0x03, 0x03, 0x90, 0x15, 0x03, 0x03, 0x98, 0x15, 0x03, 0x03, + 0xe0, 0x36, 0x04, 0x04, 0xf0, 0x36, 0x04, 0x04, 0xf0, 0x12, 0x05, 0x04, 0xe0, 0x32, 0x06, 0x05, 0x60, 0x0f, 0x07, 0x05, 0x40, 0x2f, 0x08, 0x06, 0x00, 0x20, 0x0e, 0x09, 0xa8, 0x29, 0x00, 0x03, + 0xb0, 0x29, 0x00, 0x03, 0xb8, 0x29, 0x00, 0x03, 0x88, 0x18, 0x01, 0x02, 0x8c, 0x18, 0x01, 0x02, 0x90, 0x18, 0x01, 0x02, 0x94, 0x18, 0x01, 0x02, 0x98, 0x18, 0x01, 0x02, 0x9c, 0x18, 0x01, 0x02, + 0xa0, 0x18, 0x01, 0x02, 0xf8, 0x3a, 0x02, 0x03, 0x00, 0x3b, 0x02, 0x03, 0x08, 0x3b, 0x02, 0x03, 0x10, 0x3b, 0x02, 0x03, 0xa0, 0x15, 0x03, 0x03, 0xa8, 0x15, 0x03, 0x03, 0xb0, 0x15, 0x03, 0x03, + 0x00, 0x37, 0x04, 0x04, 0x10, 0x37, 0x04, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x33, 0x06, 0x05, 0x80, 0x0f, 0x07, 0x05, 0x80, 0x2f, 0x08, 0x06, 0x00, 0x22, 0x0e, 0x09, 0xc0, 0x29, 0x00, 0x03, + 0xc8, 0x29, 0x00, 0x03, 0xd0, 0x29, 0x00, 0x03, 0xa4, 0x18, 0x01, 0x02, 0xa8, 0x18, 0x01, 0x02, 0xac, 0x18, 0x01, 0x02, 0xb0, 0x18, 0x01, 0x02, 0xb4, 0x18, 0x01, 0x02, 0xb8, 0x18, 0x01, 0x02, + 0xbc, 0x18, 0x01, 0x02, 0x18, 0x3b, 0x02, 0x03, 0x20, 0x3b, 0x02, 0x03, 0x28, 0x3b, 0x02, 0x03, 0x30, 0x3b, 0x02, 0x03, 0xb8, 0x15, 0x03, 0x03, 0xc0, 0x15, 0x03, 0x03, 0xc8, 0x15, 0x03, 0x03, + 0x20, 0x37, 0x04, 0x04, 0x30, 0x37, 0x04, 0x04, 0x10, 0x13, 0x05, 0x04, 0x20, 0x33, 0x06, 0x05, 0xa0, 0x0f, 0x07, 0x05, 0xc0, 0x2f, 0x08, 0x06, 0x00, 0x24, 0x0e, 0x09, 0xd8, 0x29, 0x00, 0x03, + 0xe0, 0x29, 0x00, 0x03, 0xe8, 0x29, 0x00, 0x03, 0xc0, 0x18, 0x01, 0x02, 0xc4, 0x18, 0x01, 0x02, 0xc8, 0x18, 0x01, 0x02, 0xcc, 0x18, 0x01, 0x02, 0xd0, 0x18, 0x01, 0x02, 0xd4, 0x18, 0x01, 0x02, + 0xd8, 0x18, 0x01, 0x02, 0x38, 0x3b, 0x02, 0x03, 0x40, 0x3b, 0x02, 0x03, 0x48, 0x3b, 0x02, 0x03, 0x50, 0x3b, 0x02, 0x03, 0xd0, 0x15, 0x03, 0x03, 0xd8, 0x15, 0x03, 0x03, 0xe0, 0x15, 0x03, 0x03, + 0x40, 0x37, 0x04, 0x04, 0x50, 0x37, 0x04, 0x04, 0x20, 0x13, 0x05, 0x04, 0x40, 0x33, 0x06, 0x05, 0xc0, 0x0f, 0x07, 0x05, 0x00, 0x30, 0x08, 0x06, 0x00, 0x02, 0x0f, 0x09, 0xf0, 0x29, 0x00, 0x03, + 0xf8, 0x29, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x03, 0xdc, 0x18, 0x01, 0x02, 0xe0, 0x18, 0x01, 0x02, 0xe4, 0x18, 0x01, 0x02, 0xe8, 0x18, 0x01, 0x02, 0xec, 0x18, 0x01, 0x02, 0xf0, 0x18, 0x01, 0x02, + 0x58, 0x3b, 0x02, 0x03, 0x60, 0x3b, 0x02, 0x03, 0x68, 0x3b, 0x02, 0x03, 0x70, 0x3b, 0x02, 0x03, 0x78, 0x3b, 0x02, 0x03, 0xe8, 0x15, 0x03, 0x03, 0xf0, 0x15, 0x03, 0x03, 0xf8, 0x15, 0x03, 0x03, + 0x60, 0x37, 0x04, 0x04, 0x70, 0x37, 0x04, 0x04, 0x30, 0x13, 0x05, 0x04, 0x60, 0x33, 0x06, 0x05, 0xe0, 0x0f, 0x07, 0x05, 0x40, 0x30, 0x08, 0x06, 0x00, 0x04, 0x0f, 0x09, 0x08, 0x2a, 0x00, 0x03, + 0x10, 0x2a, 0x00, 0x03, 0x18, 0x2a, 0x00, 0x03, 0xf4, 0x18, 0x01, 0x02, 0xf8, 0x18, 0x01, 0x02, 0xfc, 0x18, 0x01, 0x02, 0x00, 0x19, 0x01, 0x02, 0x04, 0x19, 0x01, 0x02, 0x08, 0x19, 0x01, 0x02, + 0x80, 0x3b, 0x02, 0x03, 0x88, 0x3b, 0x02, 0x03, 0x90, 0x3b, 0x02, 0x03, 0x98, 0x3b, 0x02, 0x03, 0xa0, 0x3b, 0x02, 0x03, 0x00, 0x16, 0x03, 0x03, 0x08, 0x16, 0x03, 0x03, 0x10, 0x16, 0x03, 0x03, + 0x80, 0x37, 0x04, 0x04, 0x90, 0x37, 0x04, 0x04, 0x40, 0x13, 0x05, 0x04, 0x80, 0x33, 0x06, 0x05, 0x00, 0x10, 0x07, 0x05, 0x40, 0x0c, 0x09, 0x06, 0x00, 0x06, 0x0f, 0x09, 0x20, 0x2a, 0x00, 0x03, + 0x28, 0x2a, 0x00, 0x03, 0x30, 0x2a, 0x00, 0x03, 0x0c, 0x19, 0x01, 0x02, 0x10, 0x19, 0x01, 0x02, 0x14, 0x19, 0x01, 0x02, 0x18, 0x19, 0x01, 0x02, 0x1c, 0x19, 0x01, 0x02, 0x20, 0x19, 0x01, 0x02, + 0xa8, 0x3b, 0x02, 0x03, 0xb0, 0x3b, 0x02, 0x03, 0xb8, 0x3b, 0x02, 0x03, 0xc0, 0x3b, 0x02, 0x03, 0xc8, 0x3b, 0x02, 0x03, 0x18, 0x16, 0x03, 0x03, 0x20, 0x16, 0x03, 0x03, 0x28, 0x16, 0x03, 0x03, + 0xa0, 0x37, 0x04, 0x04, 0xb0, 0x37, 0x04, 0x04, 0x50, 0x13, 0x05, 0x04, 0xa0, 0x33, 0x06, 0x05, 0x20, 0x10, 0x07, 0x05, 0x80, 0x0c, 0x09, 0x06, 0x00, 0x08, 0x0f, 0x09, 0x38, 0x2a, 0x00, 0x03, + 0x40, 0x2a, 0x00, 0x03, 0x48, 0x2a, 0x00, 0x03, 0x24, 0x19, 0x01, 0x02, 0x28, 0x19, 0x01, 0x02, 0x2c, 0x19, 0x01, 0x02, 0x30, 0x19, 0x01, 0x02, 0x34, 0x19, 0x01, 0x02, 0x38, 0x19, 0x01, 0x02, + 0xd0, 0x3b, 0x02, 0x03, 0xd8, 0x3b, 0x02, 0x03, 0xe0, 0x3b, 0x02, 0x03, 0xe8, 0x3b, 0x02, 0x03, 0xf0, 0x3b, 0x02, 0x03, 0x30, 0x16, 0x03, 0x03, 0x38, 0x16, 0x03, 0x03, 0x40, 0x16, 0x03, 0x03, + 0xc0, 0x37, 0x04, 0x04, 0xd0, 0x37, 0x04, 0x04, 0x60, 0x13, 0x05, 0x04, 0xc0, 0x33, 0x06, 0x05, 0x40, 0x10, 0x07, 0x05, 0xc0, 0x0c, 0x09, 0x06, 0x00, 0x1c, 0x10, 0x0a, 0x50, 0x2a, 0x00, 0x03, + 0x58, 0x2a, 0x00, 0x03, 0x60, 0x2a, 0x00, 0x03, 0x3c, 0x19, 0x01, 0x02, 0x40, 0x19, 0x01, 0x02, 0x44, 0x19, 0x01, 0x02, 0x48, 0x19, 0x01, 0x02, 0x4c, 0x19, 0x01, 0x02, 0x50, 0x19, 0x01, 0x02, + 0xf8, 0x3b, 0x02, 0x03, 0x00, 0x3c, 0x02, 0x03, 0x08, 0x3c, 0x02, 0x03, 0x10, 0x3c, 0x02, 0x03, 0x18, 0x3c, 0x02, 0x03, 0x48, 0x16, 0x03, 0x03, 0x50, 0x16, 0x03, 0x03, 0x58, 0x16, 0x03, 0x03, + 0xe0, 0x37, 0x04, 0x04, 0xf0, 0x37, 0x04, 0x04, 0x70, 0x13, 0x05, 0x04, 0xe0, 0x33, 0x06, 0x05, 0x60, 0x10, 0x07, 0x05, 0x00, 0x0d, 0x09, 0x06, 0x00, 0x20, 0x10, 0x0a, 0x68, 0x2a, 0x00, 0x03, + 0x70, 0x2a, 0x00, 0x03, 0x78, 0x2a, 0x00, 0x03, 0x54, 0x19, 0x01, 0x02, 0x58, 0x19, 0x01, 0x02, 0x5c, 0x19, 0x01, 0x02, 0x60, 0x19, 0x01, 0x02, 0x64, 0x19, 0x01, 0x02, 0x68, 0x19, 0x01, 0x02, + 0x20, 0x3c, 0x02, 0x03, 0x28, 0x3c, 0x02, 0x03, 0x30, 0x3c, 0x02, 0x03, 0x38, 0x3c, 0x02, 0x03, 0x40, 0x3c, 0x02, 0x03, 0x60, 0x16, 0x03, 0x03, 0x68, 0x16, 0x03, 0x03, 0x70, 0x16, 0x03, 0x03, + 0x00, 0x38, 0x04, 0x04, 0x10, 0x38, 0x04, 0x04, 0x80, 0x13, 0x05, 0x04, 0x00, 0x34, 0x06, 0x05, 0x80, 0x10, 0x07, 0x05, 0x40, 0x0d, 0x09, 0x06, 0x00, 0x38, 0x11, 0x0b, 0x80, 0x2a, 0x00, 0x03, + 0x88, 0x2a, 0x00, 0x03, 0x90, 0x2a, 0x00, 0x03, 0x6c, 0x19, 0x01, 0x02, 0x70, 0x19, 0x01, 0x02, 0x74, 0x19, 0x01, 0x02, 0x78, 0x19, 0x01, 0x02, 0x7c, 0x19, 0x01, 0x02, 0x80, 0x19, 0x01, 0x02, + 0x48, 0x3c, 0x02, 0x03, 0x50, 0x3c, 0x02, 0x03, 0x58, 0x3c, 0x02, 0x03, 0x60, 0x3c, 0x02, 0x03, 0x68, 0x3c, 0x02, 0x03, 0x78, 0x16, 0x03, 0x03, 0x80, 0x16, 0x03, 0x03, 0x88, 0x16, 0x03, 0x03, + 0x20, 0x38, 0x04, 0x04, 0x30, 0x38, 0x04, 0x04, 0x90, 0x13, 0x05, 0x04, 0x20, 0x34, 0x06, 0x05, 0xa0, 0x10, 0x07, 0x05, 0x80, 0x0d, 0x09, 0x06, 0x00, 0x00, 0x11, 0x0a, 0x98, 0x2a, 0x00, 0x03, + 0xa0, 0x2a, 0x00, 0x03, 0xa8, 0x2a, 0x00, 0x03, 0x84, 0x19, 0x01, 0x02, 0x88, 0x19, 0x01, 0x02, 0x8c, 0x19, 0x01, 0x02, 0x90, 0x19, 0x01, 0x02, 0x94, 0x19, 0x01, 0x02, 0x98, 0x19, 0x01, 0x02, + 0x70, 0x3c, 0x02, 0x03, 0x78, 0x3c, 0x02, 0x03, 0x80, 0x3c, 0x02, 0x03, 0x88, 0x3c, 0x02, 0x03, 0x90, 0x3c, 0x02, 0x03, 0x90, 0x16, 0x03, 0x03, 0x98, 0x16, 0x03, 0x03, 0xa0, 0x16, 0x03, 0x03, + 0x40, 0x38, 0x04, 0x04, 0x50, 0x38, 0x04, 0x04, 0xa0, 0x13, 0x05, 0x04, 0x40, 0x34, 0x06, 0x05, 0xc0, 0x10, 0x07, 0x05, 0xc0, 0x0d, 0x09, 0x06, 0x00, 0x20, 0x12, 0x0b, 0xb0, 0x2a, 0x00, 0x03, + 0xb8, 0x2a, 0x00, 0x03, 0xc0, 0x2a, 0x00, 0x03, 0x9c, 0x19, 0x01, 0x02, 0xa0, 0x19, 0x01, 0x02, 0xa4, 0x19, 0x01, 0x02, 0xa8, 0x19, 0x01, 0x02, 0xac, 0x19, 0x01, 0x02, 0xb0, 0x19, 0x01, 0x02, + 0x98, 0x3c, 0x02, 0x03, 0xa0, 0x3c, 0x02, 0x03, 0xa8, 0x3c, 0x02, 0x03, 0xb0, 0x3c, 0x02, 0x03, 0xb8, 0x3c, 0x02, 0x03, 0xa8, 0x16, 0x03, 0x03, 0xb0, 0x16, 0x03, 0x03, 0xb8, 0x16, 0x03, 0x03, + 0x60, 0x38, 0x04, 0x04, 0x70, 0x38, 0x04, 0x04, 0xb0, 0x13, 0x05, 0x04, 0x60, 0x34, 0x06, 0x05, 0xe0, 0x10, 0x07, 0x05, 0x00, 0x0e, 0x09, 0x06, 0x00, 0x00, 0x13, 0x0b, 0xc8, 0x2a, 0x00, 0x03, + 0xd0, 0x2a, 0x00, 0x03, 0xd8, 0x2a, 0x00, 0x03, 0xb4, 0x19, 0x01, 0x02, 0xb8, 0x19, 0x01, 0x02, 0xbc, 0x19, 0x01, 0x02, 0xc0, 0x19, 0x01, 0x02, 0xc4, 0x19, 0x01, 0x02, 0xc8, 0x19, 0x01, 0x02, + 0xc0, 0x3c, 0x02, 0x03, 0xc8, 0x3c, 0x02, 0x03, 0xd0, 0x3c, 0x02, 0x03, 0xd8, 0x3c, 0x02, 0x03, 0xe0, 0x3c, 0x02, 0x03, 0xc0, 0x16, 0x03, 0x03, 0xc8, 0x16, 0x03, 0x03, 0xd0, 0x16, 0x03, 0x03, + 0x80, 0x38, 0x04, 0x04, 0x90, 0x38, 0x04, 0x04, 0xc0, 0x13, 0x05, 0x04, 0x80, 0x34, 0x06, 0x05, 0x00, 0x11, 0x07, 0x05, 0x40, 0x0e, 0x09, 0x06, 0x00, 0x10, 0x14, 0x0c, 0xe0, 0x2a, 0x00, 0x03, + 0xe8, 0x2a, 0x00, 0x03, 0xf0, 0x2a, 0x00, 0x03, 0xcc, 0x19, 0x01, 0x02, 0xd0, 0x19, 0x01, 0x02, 0xd4, 0x19, 0x01, 0x02, 0xd8, 0x19, 0x01, 0x02, 0xdc, 0x19, 0x01, 0x02, 0xe0, 0x19, 0x01, 0x02, + 0xe8, 0x3c, 0x02, 0x03, 0xf0, 0x3c, 0x02, 0x03, 0xf8, 0x3c, 0x02, 0x03, 0x00, 0x3d, 0x02, 0x03, 0x08, 0x3d, 0x02, 0x03, 0xd8, 0x16, 0x03, 0x03, 0xe0, 0x16, 0x03, 0x03, 0xe8, 0x16, 0x03, 0x03, + 0xa0, 0x38, 0x04, 0x04, 0xb0, 0x38, 0x04, 0x04, 0xd0, 0x13, 0x05, 0x04, 0xa0, 0x34, 0x06, 0x05, 0x20, 0x11, 0x07, 0x05, 0x80, 0x0e, 0x09, 0x06, 0x00, 0x00, 0x16, 0x0d, 0xf8, 0x2a, 0x00, 0x03, + 0x00, 0x2b, 0x00, 0x03, 0x08, 0x2b, 0x00, 0x03, 0xe4, 0x19, 0x01, 0x02, 0xe8, 0x19, 0x01, 0x02, 0xec, 0x19, 0x01, 0x02, 0xf0, 0x19, 0x01, 0x02, 0xf4, 0x19, 0x01, 0x02, 0xf8, 0x19, 0x01, 0x02, + 0x10, 0x3d, 0x02, 0x03, 0x18, 0x3d, 0x02, 0x03, 0x20, 0x3d, 0x02, 0x03, 0x28, 0x3d, 0x02, 0x03, 0x30, 0x3d, 0x02, 0x03, 0xf0, 0x16, 0x03, 0x03, 0xf8, 0x16, 0x03, 0x03, 0x00, 0x17, 0x03, 0x03, + 0xc0, 0x38, 0x04, 0x04, 0xd0, 0x38, 0x04, 0x04, 0xe0, 0x13, 0x05, 0x04, 0xc0, 0x34, 0x06, 0x05, 0x40, 0x11, 0x07, 0x05, 0xc0, 0x0e, 0x09, 0x06, 0x10, 0x2b, 0x00, 0x03, 0x18, 0x2b, 0x00, 0x03, + 0x20, 0x2b, 0x00, 0x03, 0x28, 0x2b, 0x00, 0x03, 0xfc, 0x19, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x04, 0x1a, 0x01, 0x02, 0x08, 0x1a, 0x01, 0x02, 0x0c, 0x1a, 0x01, 0x02, 0x10, 0x1a, 0x01, 0x02, + 0x38, 0x3d, 0x02, 0x03, 0x40, 0x3d, 0x02, 0x03, 0x48, 0x3d, 0x02, 0x03, 0x50, 0x3d, 0x02, 0x03, 0x58, 0x3d, 0x02, 0x03, 0x08, 0x17, 0x03, 0x03, 0x10, 0x17, 0x03, 0x03, 0x18, 0x17, 0x03, 0x03, + 0xe0, 0x38, 0x04, 0x04, 0xf0, 0x38, 0x04, 0x04, 0xf0, 0x13, 0x05, 0x04, 0xe0, 0x34, 0x06, 0x05, 0x60, 0x11, 0x07, 0x05, 0x00, 0x0f, 0x09, 0x06, 0x30, 0x2b, 0x00, 0x03, 0x38, 0x2b, 0x00, 0x03, + 0x40, 0x2b, 0x00, 0x03, 0x48, 0x2b, 0x00, 0x03, 0x14, 0x1a, 0x01, 0x02, 0x18, 0x1a, 0x01, 0x02, 0x1c, 0x1a, 0x01, 0x02, 0x20, 0x1a, 0x01, 0x02, 0x24, 0x1a, 0x01, 0x02, 0x28, 0x1a, 0x01, 0x02, + 0x60, 0x3d, 0x02, 0x03, 0x68, 0x3d, 0x02, 0x03, 0x70, 0x3d, 0x02, 0x03, 0x78, 0x3d, 0x02, 0x03, 0x80, 0x3d, 0x02, 0x03, 0x20, 0x17, 0x03, 0x03, 0x28, 0x17, 0x03, 0x03, 0x30, 0x17, 0x03, 0x03, + 0x00, 0x39, 0x04, 0x04, 0x10, 0x39, 0x04, 0x04, 0x00, 0x14, 0x05, 0x04, 0x00, 0x35, 0x06, 0x05, 0x80, 0x11, 0x07, 0x05, 0x40, 0x0f, 0x09, 0x06, 0x50, 0x2b, 0x00, 0x03, 0x58, 0x2b, 0x00, 0x03, + 0x60, 0x2b, 0x00, 0x03, 0x68, 0x2b, 0x00, 0x03, 0x2c, 0x1a, 0x01, 0x02, 0x30, 0x1a, 0x01, 0x02, 0x34, 0x1a, 0x01, 0x02, 0x38, 0x1a, 0x01, 0x02, 0x3c, 0x1a, 0x01, 0x02, 0x40, 0x1a, 0x01, 0x02, + 0x88, 0x3d, 0x02, 0x03, 0x90, 0x3d, 0x02, 0x03, 0x98, 0x3d, 0x02, 0x03, 0xa0, 0x3d, 0x02, 0x03, 0xa8, 0x3d, 0x02, 0x03, 0x38, 0x17, 0x03, 0x03, 0x40, 0x17, 0x03, 0x03, 0x48, 0x17, 0x03, 0x03, + 0x20, 0x39, 0x04, 0x04, 0x30, 0x39, 0x04, 0x04, 0x10, 0x14, 0x05, 0x04, 0x20, 0x35, 0x06, 0x05, 0xa0, 0x11, 0x07, 0x05, 0x80, 0x0f, 0x09, 0x06, 0x70, 0x2b, 0x00, 0x03, 0x78, 0x2b, 0x00, 0x03, + 0x80, 0x2b, 0x00, 0x03, 0x88, 0x2b, 0x00, 0x03, 0x44, 0x1a, 0x01, 0x02, 0x48, 0x1a, 0x01, 0x02, 0x4c, 0x1a, 0x01, 0x02, 0x50, 0x1a, 0x01, 0x02, 0x54, 0x1a, 0x01, 0x02, 0x58, 0x1a, 0x01, 0x02, + 0xb0, 0x3d, 0x02, 0x03, 0xb8, 0x3d, 0x02, 0x03, 0xc0, 0x3d, 0x02, 0x03, 0xc8, 0x3d, 0x02, 0x03, 0xd0, 0x3d, 0x02, 0x03, 0x50, 0x17, 0x03, 0x03, 0x58, 0x17, 0x03, 0x03, 0x60, 0x17, 0x03, 0x03, + 0x40, 0x39, 0x04, 0x04, 0x50, 0x39, 0x04, 0x04, 0x20, 0x14, 0x05, 0x04, 0x40, 0x35, 0x06, 0x05, 0xc0, 0x11, 0x07, 0x05, 0xc0, 0x0f, 0x09, 0x06, 0x90, 0x2b, 0x00, 0x03, 0x98, 0x2b, 0x00, 0x03, + 0xa0, 0x2b, 0x00, 0x03, 0xa8, 0x2b, 0x00, 0x03, 0x5c, 0x1a, 0x01, 0x02, 0x60, 0x1a, 0x01, 0x02, 0x64, 0x1a, 0x01, 0x02, 0x68, 0x1a, 0x01, 0x02, 0x6c, 0x1a, 0x01, 0x02, 0x70, 0x1a, 0x01, 0x02, + 0xd8, 0x3d, 0x02, 0x03, 0xe0, 0x3d, 0x02, 0x03, 0xe8, 0x3d, 0x02, 0x03, 0xf0, 0x3d, 0x02, 0x03, 0xf8, 0x3d, 0x02, 0x03, 0x68, 0x17, 0x03, 0x03, 0x70, 0x17, 0x03, 0x03, 0x78, 0x17, 0x03, 0x03, + 0x60, 0x39, 0x04, 0x04, 0x70, 0x39, 0x04, 0x04, 0x30, 0x14, 0x05, 0x04, 0x60, 0x35, 0x06, 0x05, 0xe0, 0x11, 0x07, 0x05, 0x00, 0x10, 0x09, 0x06, 0xb0, 0x2b, 0x00, 0x03, 0xb8, 0x2b, 0x00, 0x03, + 0xc0, 0x2b, 0x00, 0x03, 0xc8, 0x2b, 0x00, 0x03, 0x74, 0x1a, 0x01, 0x02, 0x78, 0x1a, 0x01, 0x02, 0x7c, 0x1a, 0x01, 0x02, 0x80, 0x1a, 0x01, 0x02, 0x84, 0x1a, 0x01, 0x02, 0x88, 0x1a, 0x01, 0x02, + 0x00, 0x3e, 0x02, 0x03, 0x08, 0x3e, 0x02, 0x03, 0x10, 0x3e, 0x02, 0x03, 0x18, 0x3e, 0x02, 0x03, 0x20, 0x3e, 0x02, 0x03, 0x80, 0x17, 0x03, 0x03, 0x88, 0x17, 0x03, 0x03, 0x90, 0x17, 0x03, 0x03, + 0x80, 0x39, 0x04, 0x04, 0x90, 0x39, 0x04, 0x04, 0x40, 0x14, 0x05, 0x04, 0x80, 0x35, 0x06, 0x05, 0x00, 0x12, 0x07, 0x05, 0x40, 0x10, 0x09, 0x06, 0xd0, 0x2b, 0x00, 0x03, 0xd8, 0x2b, 0x00, 0x03, + 0xe0, 0x2b, 0x00, 0x03, 0xe8, 0x2b, 0x00, 0x03, 0x8c, 0x1a, 0x01, 0x02, 0x90, 0x1a, 0x01, 0x02, 0x94, 0x1a, 0x01, 0x02, 0x98, 0x1a, 0x01, 0x02, 0x9c, 0x1a, 0x01, 0x02, 0xa0, 0x1a, 0x01, 0x02, + 0x28, 0x3e, 0x02, 0x03, 0x30, 0x3e, 0x02, 0x03, 0x38, 0x3e, 0x02, 0x03, 0x40, 0x3e, 0x02, 0x03, 0x48, 0x3e, 0x02, 0x03, 0x98, 0x17, 0x03, 0x03, 0xa0, 0x17, 0x03, 0x03, 0xa8, 0x17, 0x03, 0x03, + 0xa0, 0x39, 0x04, 0x04, 0xb0, 0x39, 0x04, 0x04, 0x50, 0x14, 0x05, 0x04, 0xa0, 0x35, 0x06, 0x05, 0x20, 0x12, 0x07, 0x05, 0x80, 0x10, 0x09, 0x06, 0xf0, 0x2b, 0x00, 0x03, 0xf8, 0x2b, 0x00, 0x03, + 0x00, 0x2c, 0x00, 0x03, 0x08, 0x2c, 0x00, 0x03, 0xa4, 0x1a, 0x01, 0x02, 0xa8, 0x1a, 0x01, 0x02, 0xac, 0x1a, 0x01, 0x02, 0xb0, 0x1a, 0x01, 0x02, 0xb4, 0x1a, 0x01, 0x02, 0xb8, 0x1a, 0x01, 0x02, + 0x50, 0x3e, 0x02, 0x03, 0x58, 0x3e, 0x02, 0x03, 0x60, 0x3e, 0x02, 0x03, 0x68, 0x3e, 0x02, 0x03, 0x70, 0x3e, 0x02, 0x03, 0xb0, 0x17, 0x03, 0x03, 0xb8, 0x17, 0x03, 0x03, 0xc0, 0x17, 0x03, 0x03, + 0xc0, 0x39, 0x04, 0x04, 0xd0, 0x39, 0x04, 0x04, 0x60, 0x14, 0x05, 0x04, 0xc0, 0x35, 0x06, 0x05, 0x40, 0x12, 0x07, 0x05, 0xc0, 0x10, 0x09, 0x06, 0x10, 0x2c, 0x00, 0x03, 0x18, 0x2c, 0x00, 0x03, + 0x20, 0x2c, 0x00, 0x03, 0x28, 0x2c, 0x00, 0x03, 0xbc, 0x1a, 0x01, 0x02, 0xc0, 0x1a, 0x01, 0x02, 0xc4, 0x1a, 0x01, 0x02, 0xc8, 0x1a, 0x01, 0x02, 0xcc, 0x1a, 0x01, 0x02, 0xd0, 0x1a, 0x01, 0x02, + 0x78, 0x3e, 0x02, 0x03, 0x80, 0x3e, 0x02, 0x03, 0x88, 0x3e, 0x02, 0x03, 0x90, 0x3e, 0x02, 0x03, 0x98, 0x3e, 0x02, 0x03, 0xc8, 0x17, 0x03, 0x03, 0xd0, 0x17, 0x03, 0x03, 0xd8, 0x17, 0x03, 0x03, + 0xe0, 0x39, 0x04, 0x04, 0xf0, 0x39, 0x04, 0x04, 0x70, 0x14, 0x05, 0x04, 0xe0, 0x35, 0x06, 0x05, 0x60, 0x12, 0x07, 0x05, 0x00, 0x11, 0x09, 0x06, 0x30, 0x2c, 0x00, 0x03, 0x38, 0x2c, 0x00, 0x03, + 0x40, 0x2c, 0x00, 0x03, 0x48, 0x2c, 0x00, 0x03, 0xd4, 0x1a, 0x01, 0x02, 0xd8, 0x1a, 0x01, 0x02, 0xdc, 0x1a, 0x01, 0x02, 0xe0, 0x1a, 0x01, 0x02, 0xe4, 0x1a, 0x01, 0x02, 0xe8, 0x1a, 0x01, 0x02, + 0xa0, 0x3e, 0x02, 0x03, 0xa8, 0x3e, 0x02, 0x03, 0xb0, 0x3e, 0x02, 0x03, 0xb8, 0x3e, 0x02, 0x03, 0xc0, 0x3e, 0x02, 0x03, 0xe0, 0x17, 0x03, 0x03, 0xe8, 0x17, 0x03, 0x03, 0xf0, 0x17, 0x03, 0x03, + 0x00, 0x3a, 0x04, 0x04, 0x10, 0x3a, 0x04, 0x04, 0x80, 0x14, 0x05, 0x04, 0x00, 0x36, 0x06, 0x05, 0x80, 0x12, 0x07, 0x05, 0x40, 0x11, 0x09, 0x06, 0x50, 0x2c, 0x00, 0x03, 0x58, 0x2c, 0x00, 0x03, + 0x60, 0x2c, 0x00, 0x03, 0x68, 0x2c, 0x00, 0x03, 0xec, 0x1a, 0x01, 0x02, 0xf0, 0x1a, 0x01, 0x02, 0xf4, 0x1a, 0x01, 0x02, 0xf8, 0x1a, 0x01, 0x02, 0xfc, 0x1a, 0x01, 0x02, 0x00, 0x1b, 0x01, 0x02, + 0xc8, 0x3e, 0x02, 0x03, 0xd0, 0x3e, 0x02, 0x03, 0xd8, 0x3e, 0x02, 0x03, 0xe0, 0x3e, 0x02, 0x03, 0xe8, 0x3e, 0x02, 0x03, 0xf8, 0x17, 0x03, 0x03, 0x00, 0x18, 0x03, 0x03, 0x08, 0x18, 0x03, 0x03, + 0x20, 0x3a, 0x04, 0x04, 0x30, 0x3a, 0x04, 0x04, 0x90, 0x14, 0x05, 0x04, 0x20, 0x36, 0x06, 0x05, 0xa0, 0x12, 0x07, 0x05, 0x80, 0x11, 0x09, 0x06, 0x70, 0x2c, 0x00, 0x03, 0x78, 0x2c, 0x00, 0x03, + 0x80, 0x2c, 0x00, 0x03, 0x88, 0x2c, 0x00, 0x03, 0x04, 0x1b, 0x01, 0x02, 0x08, 0x1b, 0x01, 0x02, 0x0c, 0x1b, 0x01, 0x02, 0x10, 0x1b, 0x01, 0x02, 0x14, 0x1b, 0x01, 0x02, 0x18, 0x1b, 0x01, 0x02, + 0xf0, 0x3e, 0x02, 0x03, 0xf8, 0x3e, 0x02, 0x03, 0x00, 0x3f, 0x02, 0x03, 0x08, 0x3f, 0x02, 0x03, 0x10, 0x3f, 0x02, 0x03, 0x10, 0x18, 0x03, 0x03, 0x18, 0x18, 0x03, 0x03, 0x20, 0x18, 0x03, 0x03, + 0x40, 0x3a, 0x04, 0x04, 0x50, 0x3a, 0x04, 0x04, 0xa0, 0x14, 0x05, 0x04, 0x40, 0x36, 0x06, 0x05, 0xc0, 0x12, 0x07, 0x05, 0xc0, 0x11, 0x09, 0x06, 0x90, 0x2c, 0x00, 0x03, 0x98, 0x2c, 0x00, 0x03, + 0xa0, 0x2c, 0x00, 0x03, 0xa8, 0x2c, 0x00, 0x03, 0x1c, 0x1b, 0x01, 0x02, 0x20, 0x1b, 0x01, 0x02, 0x24, 0x1b, 0x01, 0x02, 0x28, 0x1b, 0x01, 0x02, 0x2c, 0x1b, 0x01, 0x02, 0x30, 0x1b, 0x01, 0x02, + 0x18, 0x3f, 0x02, 0x03, 0x20, 0x3f, 0x02, 0x03, 0x28, 0x3f, 0x02, 0x03, 0x30, 0x3f, 0x02, 0x03, 0x38, 0x3f, 0x02, 0x03, 0x28, 0x18, 0x03, 0x03, 0x30, 0x18, 0x03, 0x03, 0x38, 0x18, 0x03, 0x03, + 0x60, 0x3a, 0x04, 0x04, 0x70, 0x3a, 0x04, 0x04, 0xb0, 0x14, 0x05, 0x04, 0x60, 0x36, 0x06, 0x05, 0xe0, 0x12, 0x07, 0x05, 0x00, 0x12, 0x09, 0x06, 0xb0, 0x2c, 0x00, 0x03, 0xb8, 0x2c, 0x00, 0x03, + 0xc0, 0x2c, 0x00, 0x03, 0xc8, 0x2c, 0x00, 0x03, 0x34, 0x1b, 0x01, 0x02, 0x38, 0x1b, 0x01, 0x02, 0x3c, 0x1b, 0x01, 0x02, 0x40, 0x1b, 0x01, 0x02, 0x44, 0x1b, 0x01, 0x02, 0x48, 0x1b, 0x01, 0x02, + 0x40, 0x3f, 0x02, 0x03, 0x48, 0x3f, 0x02, 0x03, 0x50, 0x3f, 0x02, 0x03, 0x58, 0x3f, 0x02, 0x03, 0x60, 0x3f, 0x02, 0x03, 0x40, 0x18, 0x03, 0x03, 0x48, 0x18, 0x03, 0x03, 0x50, 0x18, 0x03, 0x03, + 0x80, 0x3a, 0x04, 0x04, 0x90, 0x3a, 0x04, 0x04, 0xc0, 0x14, 0x05, 0x04, 0x80, 0x36, 0x06, 0x05, 0x00, 0x13, 0x07, 0x05, 0x40, 0x12, 0x09, 0x06, 0xd0, 0x2c, 0x00, 0x03, 0xd8, 0x2c, 0x00, 0x03, + 0xe0, 0x2c, 0x00, 0x03, 0xe8, 0x2c, 0x00, 0x03, 0x4c, 0x1b, 0x01, 0x02, 0x50, 0x1b, 0x01, 0x02, 0x54, 0x1b, 0x01, 0x02, 0x58, 0x1b, 0x01, 0x02, 0x5c, 0x1b, 0x01, 0x02, 0x60, 0x1b, 0x01, 0x02, + 0x68, 0x3f, 0x02, 0x03, 0x70, 0x3f, 0x02, 0x03, 0x78, 0x3f, 0x02, 0x03, 0x80, 0x3f, 0x02, 0x03, 0x88, 0x3f, 0x02, 0x03, 0x58, 0x18, 0x03, 0x03, 0x60, 0x18, 0x03, 0x03, 0xa0, 0x3a, 0x04, 0x04, + 0xb0, 0x3a, 0x04, 0x04, 0xc0, 0x3a, 0x04, 0x04, 0xd0, 0x14, 0x05, 0x04, 0xa0, 0x36, 0x06, 0x05, 0x20, 0x13, 0x07, 0x05, 0x80, 0x12, 0x09, 0x06, 0xf0, 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x03, + 0x00, 0x2d, 0x00, 0x03, 0x08, 0x2d, 0x00, 0x03, 0x64, 0x1b, 0x01, 0x02, 0x68, 0x1b, 0x01, 0x02, 0x6c, 0x1b, 0x01, 0x02, 0x70, 0x1b, 0x01, 0x02, 0x74, 0x1b, 0x01, 0x02, 0x78, 0x1b, 0x01, 0x02, + 0x90, 0x3f, 0x02, 0x03, 0x98, 0x3f, 0x02, 0x03, 0xa0, 0x3f, 0x02, 0x03, 0xa8, 0x3f, 0x02, 0x03, 0x68, 0x18, 0x03, 0x03, 0x70, 0x18, 0x03, 0x03, 0x78, 0x18, 0x03, 0x03, 0xd0, 0x3a, 0x04, 0x04, + 0xe0, 0x3a, 0x04, 0x04, 0xf0, 0x3a, 0x04, 0x04, 0xe0, 0x14, 0x05, 0x04, 0xc0, 0x36, 0x06, 0x05, 0x40, 0x13, 0x07, 0x05, 0xc0, 0x12, 0x09, 0x06, 0x10, 0x2d, 0x00, 0x03, 0x18, 0x2d, 0x00, 0x03, + 0x20, 0x2d, 0x00, 0x03, 0x28, 0x2d, 0x00, 0x03, 0x7c, 0x1b, 0x01, 0x02, 0x80, 0x1b, 0x01, 0x02, 0x84, 0x1b, 0x01, 0x02, 0x88, 0x1b, 0x01, 0x02, 0x8c, 0x1b, 0x01, 0x02, 0x90, 0x1b, 0x01, 0x02, + 0xb0, 0x3f, 0x02, 0x03, 0xb8, 0x3f, 0x02, 0x03, 0xc0, 0x3f, 0x02, 0x03, 0xc8, 0x3f, 0x02, 0x03, 0x80, 0x18, 0x03, 0x03, 0x88, 0x18, 0x03, 0x03, 0x90, 0x18, 0x03, 0x03, 0x00, 0x3b, 0x04, 0x04, + 0x10, 0x3b, 0x04, 0x04, 0x20, 0x3b, 0x04, 0x04, 0xf0, 0x14, 0x05, 0x04, 0xe0, 0x36, 0x06, 0x05, 0x60, 0x13, 0x07, 0x05, 0x00, 0x13, 0x09, 0x06, 0x30, 0x2d, 0x00, 0x03, 0x38, 0x2d, 0x00, 0x03, + 0x40, 0x2d, 0x00, 0x03, 0x48, 0x2d, 0x00, 0x03, 0x94, 0x1b, 0x01, 0x02, 0x98, 0x1b, 0x01, 0x02, 0x9c, 0x1b, 0x01, 0x02, 0xa0, 0x1b, 0x01, 0x02, 0xa4, 0x1b, 0x01, 0x02, 0xa8, 0x1b, 0x01, 0x02, + 0xd0, 0x3f, 0x02, 0x03, 0xd8, 0x3f, 0x02, 0x03, 0xe0, 0x3f, 0x02, 0x03, 0xe8, 0x3f, 0x02, 0x03, 0x98, 0x18, 0x03, 0x03, 0xa0, 0x18, 0x03, 0x03, 0xa8, 0x18, 0x03, 0x03, 0x30, 0x3b, 0x04, 0x04, + 0x40, 0x3b, 0x04, 0x04, 0x50, 0x3b, 0x04, 0x04, 0x00, 0x15, 0x05, 0x04, 0x00, 0x37, 0x06, 0x05, 0x80, 0x13, 0x07, 0x05, 0x40, 0x13, 0x09, 0x06, 0x50, 0x2d, 0x00, 0x03, 0x58, 0x2d, 0x00, 0x03, + 0x60, 0x2d, 0x00, 0x03, 0x68, 0x2d, 0x00, 0x03, 0xac, 0x1b, 0x01, 0x02, 0xb0, 0x1b, 0x01, 0x02, 0xb4, 0x1b, 0x01, 0x02, 0xb8, 0x1b, 0x01, 0x02, 0xbc, 0x1b, 0x01, 0x02, 0xc0, 0x1b, 0x01, 0x02, + 0xf0, 0x3f, 0x02, 0x03, 0xf8, 0x3f, 0x02, 0x03, 0x00, 0x00, 0x02, 0x02, 0x04, 0x00, 0x02, 0x02, 0xb0, 0x18, 0x03, 0x03, 0xb8, 0x18, 0x03, 0x03, 0xc0, 0x18, 0x03, 0x03, 0x60, 0x3b, 0x04, 0x04, + 0x70, 0x3b, 0x04, 0x04, 0x80, 0x3b, 0x04, 0x04, 0x10, 0x15, 0x05, 0x04, 0x20, 0x37, 0x06, 0x05, 0xa0, 0x13, 0x07, 0x05, 0x80, 0x13, 0x09, 0x06, 0x70, 0x2d, 0x00, 0x03, 0x78, 0x2d, 0x00, 0x03, + 0x80, 0x2d, 0x00, 0x03, 0x88, 0x2d, 0x00, 0x03, 0xc4, 0x1b, 0x01, 0x02, 0xc8, 0x1b, 0x01, 0x02, 0xcc, 0x1b, 0x01, 0x02, 0xd0, 0x1b, 0x01, 0x02, 0xd4, 0x1b, 0x01, 0x02, 0xd8, 0x1b, 0x01, 0x02, + 0x08, 0x00, 0x02, 0x02, 0x0c, 0x00, 0x02, 0x02, 0x10, 0x00, 0x02, 0x02, 0x14, 0x00, 0x02, 0x02, 0xc8, 0x18, 0x03, 0x03, 0xd0, 0x18, 0x03, 0x03, 0xd8, 0x18, 0x03, 0x03, 0x90, 0x3b, 0x04, 0x04, + 0xa0, 0x3b, 0x04, 0x04, 0xb0, 0x3b, 0x04, 0x04, 0x20, 0x15, 0x05, 0x04, 0x40, 0x37, 0x06, 0x05, 0xc0, 0x13, 0x07, 0x05, 0x00, 0x2d, 0x0a, 0x07, 0x90, 0x2d, 0x00, 0x03, 0x98, 0x2d, 0x00, 0x03, + 0xa0, 0x2d, 0x00, 0x03, 0xa8, 0x2d, 0x00, 0x03, 0xdc, 0x1b, 0x01, 0x02, 0xe0, 0x1b, 0x01, 0x02, 0xe4, 0x1b, 0x01, 0x02, 0xe8, 0x1b, 0x01, 0x02, 0xec, 0x1b, 0x01, 0x02, 0xf0, 0x1b, 0x01, 0x02, + 0x18, 0x00, 0x02, 0x02, 0x1c, 0x00, 0x02, 0x02, 0x20, 0x00, 0x02, 0x02, 0x24, 0x00, 0x02, 0x02, 0xe0, 0x18, 0x03, 0x03, 0xe8, 0x18, 0x03, 0x03, 0xf0, 0x18, 0x03, 0x03, 0xc0, 0x3b, 0x04, 0x04, + 0xd0, 0x3b, 0x04, 0x04, 0xe0, 0x3b, 0x04, 0x04, 0x30, 0x15, 0x05, 0x04, 0x60, 0x37, 0x06, 0x05, 0xe0, 0x13, 0x07, 0x05, 0x80, 0x2d, 0x0a, 0x07, 0xb0, 0x2d, 0x00, 0x03, 0xb8, 0x2d, 0x00, 0x03, + 0xc0, 0x2d, 0x00, 0x03, 0xc8, 0x2d, 0x00, 0x03, 0xf4, 0x1b, 0x01, 0x02, 0xf8, 0x1b, 0x01, 0x02, 0xfc, 0x1b, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x04, 0x1c, 0x01, 0x02, 0x08, 0x1c, 0x01, 0x02, + 0x28, 0x00, 0x02, 0x02, 0x2c, 0x00, 0x02, 0x02, 0x30, 0x00, 0x02, 0x02, 0x34, 0x00, 0x02, 0x02, 0xf8, 0x18, 0x03, 0x03, 0x00, 0x19, 0x03, 0x03, 0x08, 0x19, 0x03, 0x03, 0xf0, 0x3b, 0x04, 0x04, + 0x00, 0x3c, 0x04, 0x04, 0x40, 0x15, 0x05, 0x04, 0x50, 0x15, 0x05, 0x04, 0x80, 0x37, 0x06, 0x05, 0x00, 0x14, 0x07, 0x05, 0x00, 0x2e, 0x0a, 0x07, 0xd0, 0x2d, 0x00, 0x03, 0xd8, 0x2d, 0x00, 0x03, + 0xe0, 0x2d, 0x00, 0x03, 0xe8, 0x2d, 0x00, 0x03, 0x0c, 0x1c, 0x01, 0x02, 0x10, 0x1c, 0x01, 0x02, 0x14, 0x1c, 0x01, 0x02, 0x18, 0x1c, 0x01, 0x02, 0x1c, 0x1c, 0x01, 0x02, 0x20, 0x1c, 0x01, 0x02, + 0x38, 0x00, 0x02, 0x02, 0x3c, 0x00, 0x02, 0x02, 0x40, 0x00, 0x02, 0x02, 0x44, 0x00, 0x02, 0x02, 0x10, 0x19, 0x03, 0x03, 0x18, 0x19, 0x03, 0x03, 0x20, 0x19, 0x03, 0x03, 0x10, 0x3c, 0x04, 0x04, + 0x20, 0x3c, 0x04, 0x04, 0x60, 0x15, 0x05, 0x04, 0x70, 0x15, 0x05, 0x04, 0xa0, 0x37, 0x06, 0x05, 0x20, 0x14, 0x07, 0x05, 0x80, 0x2e, 0x0a, 0x07, 0xf0, 0x2d, 0x00, 0x03, 0xf8, 0x2d, 0x00, 0x03, + 0x00, 0x2e, 0x00, 0x03, 0x08, 0x2e, 0x00, 0x03, 0x24, 0x1c, 0x01, 0x02, 0x28, 0x1c, 0x01, 0x02, 0x2c, 0x1c, 0x01, 0x02, 0x30, 0x1c, 0x01, 0x02, 0x34, 0x1c, 0x01, 0x02, 0x38, 0x1c, 0x01, 0x02, + 0x48, 0x00, 0x02, 0x02, 0x4c, 0x00, 0x02, 0x02, 0x50, 0x00, 0x02, 0x02, 0x54, 0x00, 0x02, 0x02, 0x28, 0x19, 0x03, 0x03, 0x30, 0x19, 0x03, 0x03, 0x38, 0x19, 0x03, 0x03, 0x30, 0x3c, 0x04, 0x04, + 0x40, 0x3c, 0x04, 0x04, 0x80, 0x15, 0x05, 0x04, 0x90, 0x15, 0x05, 0x04, 0xc0, 0x37, 0x06, 0x05, 0x40, 0x14, 0x07, 0x05, 0x00, 0x2f, 0x0a, 0x07, 0x10, 0x2e, 0x00, 0x03, 0x18, 0x2e, 0x00, 0x03, + 0x20, 0x2e, 0x00, 0x03, 0x28, 0x2e, 0x00, 0x03, 0x3c, 0x1c, 0x01, 0x02, 0x40, 0x1c, 0x01, 0x02, 0x44, 0x1c, 0x01, 0x02, 0x48, 0x1c, 0x01, 0x02, 0x4c, 0x1c, 0x01, 0x02, 0x50, 0x1c, 0x01, 0x02, + 0x58, 0x00, 0x02, 0x02, 0x5c, 0x00, 0x02, 0x02, 0x60, 0x00, 0x02, 0x02, 0x64, 0x00, 0x02, 0x02, 0x40, 0x19, 0x03, 0x03, 0x48, 0x19, 0x03, 0x03, 0x50, 0x19, 0x03, 0x03, 0x50, 0x3c, 0x04, 0x04, + 0x60, 0x3c, 0x04, 0x04, 0xa0, 0x15, 0x05, 0x04, 0xb0, 0x15, 0x05, 0x04, 0xe0, 0x37, 0x06, 0x05, 0x60, 0x14, 0x07, 0x05, 0x80, 0x2f, 0x0a, 0x07, 0x30, 0x2e, 0x00, 0x03, 0x38, 0x2e, 0x00, 0x03, + 0x40, 0x2e, 0x00, 0x03, 0x48, 0x2e, 0x00, 0x03, 0x54, 0x1c, 0x01, 0x02, 0x58, 0x1c, 0x01, 0x02, 0x5c, 0x1c, 0x01, 0x02, 0x60, 0x1c, 0x01, 0x02, 0x64, 0x1c, 0x01, 0x02, 0x68, 0x1c, 0x01, 0x02, + 0x68, 0x00, 0x02, 0x02, 0x6c, 0x00, 0x02, 0x02, 0x70, 0x00, 0x02, 0x02, 0x74, 0x00, 0x02, 0x02, 0x58, 0x19, 0x03, 0x03, 0x60, 0x19, 0x03, 0x03, 0x68, 0x19, 0x03, 0x03, 0x70, 0x3c, 0x04, 0x04, + 0x80, 0x3c, 0x04, 0x04, 0xc0, 0x15, 0x05, 0x04, 0xd0, 0x15, 0x05, 0x04, 0x00, 0x38, 0x06, 0x05, 0x80, 0x14, 0x07, 0x05, 0x00, 0x30, 0x0a, 0x07, 0x50, 0x2e, 0x00, 0x03, 0x58, 0x2e, 0x00, 0x03, + 0x60, 0x2e, 0x00, 0x03, 0x68, 0x2e, 0x00, 0x03, 0x6c, 0x1c, 0x01, 0x02, 0x70, 0x1c, 0x01, 0x02, 0x74, 0x1c, 0x01, 0x02, 0x78, 0x1c, 0x01, 0x02, 0x7c, 0x1c, 0x01, 0x02, 0x80, 0x1c, 0x01, 0x02, + 0x78, 0x00, 0x02, 0x02, 0x7c, 0x00, 0x02, 0x02, 0x80, 0x00, 0x02, 0x02, 0x84, 0x00, 0x02, 0x02, 0x70, 0x19, 0x03, 0x03, 0x78, 0x19, 0x03, 0x03, 0x80, 0x19, 0x03, 0x03, 0x90, 0x3c, 0x04, 0x04, + 0xa0, 0x3c, 0x04, 0x04, 0xe0, 0x15, 0x05, 0x04, 0xf0, 0x15, 0x05, 0x04, 0x20, 0x38, 0x06, 0x05, 0xa0, 0x14, 0x07, 0x05, 0x80, 0x30, 0x0a, 0x07, 0x70, 0x2e, 0x00, 0x03, 0x78, 0x2e, 0x00, 0x03, + 0x80, 0x2e, 0x00, 0x03, 0x88, 0x2e, 0x00, 0x03, 0x84, 0x1c, 0x01, 0x02, 0x88, 0x1c, 0x01, 0x02, 0x8c, 0x1c, 0x01, 0x02, 0x90, 0x1c, 0x01, 0x02, 0x94, 0x1c, 0x01, 0x02, 0x98, 0x1c, 0x01, 0x02, + 0x88, 0x00, 0x02, 0x02, 0x8c, 0x00, 0x02, 0x02, 0x90, 0x00, 0x02, 0x02, 0x94, 0x00, 0x02, 0x02, 0x88, 0x19, 0x03, 0x03, 0x90, 0x19, 0x03, 0x03, 0x98, 0x19, 0x03, 0x03, 0xb0, 0x3c, 0x04, 0x04, + 0xc0, 0x3c, 0x04, 0x04, 0x00, 0x16, 0x05, 0x04, 0x10, 0x16, 0x05, 0x04, 0x40, 0x38, 0x06, 0x05, 0xc0, 0x14, 0x07, 0x05, 0x00, 0x31, 0x0a, 0x07, 0x90, 0x2e, 0x00, 0x03, 0x98, 0x2e, 0x00, 0x03, + 0xa0, 0x2e, 0x00, 0x03, 0xa8, 0x2e, 0x00, 0x03, 0x9c, 0x1c, 0x01, 0x02, 0xa0, 0x1c, 0x01, 0x02, 0xa4, 0x1c, 0x01, 0x02, 0xa8, 0x1c, 0x01, 0x02, 0xac, 0x1c, 0x01, 0x02, 0xb0, 0x1c, 0x01, 0x02, + 0x98, 0x00, 0x02, 0x02, 0x9c, 0x00, 0x02, 0x02, 0xa0, 0x00, 0x02, 0x02, 0xa4, 0x00, 0x02, 0x02, 0xa0, 0x19, 0x03, 0x03, 0xa8, 0x19, 0x03, 0x03, 0xb0, 0x19, 0x03, 0x03, 0xd0, 0x3c, 0x04, 0x04, + 0xe0, 0x3c, 0x04, 0x04, 0x20, 0x16, 0x05, 0x04, 0x30, 0x16, 0x05, 0x04, 0x60, 0x38, 0x06, 0x05, 0xe0, 0x14, 0x07, 0x05, 0x80, 0x31, 0x0a, 0x07, 0xb0, 0x2e, 0x00, 0x03, 0xb8, 0x2e, 0x00, 0x03, + 0xc0, 0x2e, 0x00, 0x03, 0xc8, 0x2e, 0x00, 0x03, 0xb4, 0x1c, 0x01, 0x02, 0xb8, 0x1c, 0x01, 0x02, 0xbc, 0x1c, 0x01, 0x02, 0xc0, 0x1c, 0x01, 0x02, 0xc4, 0x1c, 0x01, 0x02, 0xc8, 0x1c, 0x01, 0x02, + 0xa8, 0x00, 0x02, 0x02, 0xac, 0x00, 0x02, 0x02, 0xb0, 0x00, 0x02, 0x02, 0xb4, 0x00, 0x02, 0x02, 0xb8, 0x19, 0x03, 0x03, 0xc0, 0x19, 0x03, 0x03, 0xc8, 0x19, 0x03, 0x03, 0xf0, 0x3c, 0x04, 0x04, + 0x00, 0x3d, 0x04, 0x04, 0x40, 0x16, 0x05, 0x04, 0x50, 0x16, 0x05, 0x04, 0x80, 0x38, 0x06, 0x05, 0x00, 0x15, 0x07, 0x05, 0x00, 0x32, 0x0a, 0x07, 0xd0, 0x2e, 0x00, 0x03, 0xd8, 0x2e, 0x00, 0x03, + 0xe0, 0x2e, 0x00, 0x03, 0xe8, 0x2e, 0x00, 0x03, 0xcc, 0x1c, 0x01, 0x02, 0xd0, 0x1c, 0x01, 0x02, 0xd4, 0x1c, 0x01, 0x02, 0xd8, 0x1c, 0x01, 0x02, 0xdc, 0x1c, 0x01, 0x02, 0xe0, 0x1c, 0x01, 0x02, + 0xb8, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x02, 0x02, 0xc0, 0x00, 0x02, 0x02, 0xc4, 0x00, 0x02, 0x02, 0xd0, 0x19, 0x03, 0x03, 0xd8, 0x19, 0x03, 0x03, 0xe0, 0x19, 0x03, 0x03, 0x10, 0x3d, 0x04, 0x04, + 0x20, 0x3d, 0x04, 0x04, 0x60, 0x16, 0x05, 0x04, 0x70, 0x16, 0x05, 0x04, 0xa0, 0x38, 0x06, 0x05, 0x20, 0x15, 0x07, 0x05, 0x80, 0x32, 0x0a, 0x07, 0xf0, 0x2e, 0x00, 0x03, 0xf8, 0x2e, 0x00, 0x03, + 0x00, 0x2f, 0x00, 0x03, 0x08, 0x2f, 0x00, 0x03, 0xe4, 0x1c, 0x01, 0x02, 0xe8, 0x1c, 0x01, 0x02, 0xec, 0x1c, 0x01, 0x02, 0xf0, 0x1c, 0x01, 0x02, 0xf4, 0x1c, 0x01, 0x02, 0xf8, 0x1c, 0x01, 0x02, + 0xc8, 0x00, 0x02, 0x02, 0xcc, 0x00, 0x02, 0x02, 0xd0, 0x00, 0x02, 0x02, 0xd4, 0x00, 0x02, 0x02, 0xe8, 0x19, 0x03, 0x03, 0xf0, 0x19, 0x03, 0x03, 0xf8, 0x19, 0x03, 0x03, 0x30, 0x3d, 0x04, 0x04, + 0x40, 0x3d, 0x04, 0x04, 0x80, 0x16, 0x05, 0x04, 0x90, 0x16, 0x05, 0x04, 0xc0, 0x38, 0x06, 0x05, 0x40, 0x15, 0x07, 0x05, 0x00, 0x33, 0x0a, 0x07, 0x10, 0x2f, 0x00, 0x03, 0x18, 0x2f, 0x00, 0x03, + 0x20, 0x2f, 0x00, 0x03, 0x28, 0x2f, 0x00, 0x03, 0xfc, 0x1c, 0x01, 0x02, 0x00, 0x1d, 0x01, 0x02, 0x04, 0x1d, 0x01, 0x02, 0x08, 0x1d, 0x01, 0x02, 0x0c, 0x1d, 0x01, 0x02, 0x10, 0x1d, 0x01, 0x02, + 0xd8, 0x00, 0x02, 0x02, 0xdc, 0x00, 0x02, 0x02, 0xe0, 0x00, 0x02, 0x02, 0xe4, 0x00, 0x02, 0x02, 0x00, 0x1a, 0x03, 0x03, 0x08, 0x1a, 0x03, 0x03, 0x10, 0x1a, 0x03, 0x03, 0x50, 0x3d, 0x04, 0x04, + 0x60, 0x3d, 0x04, 0x04, 0xa0, 0x16, 0x05, 0x04, 0xb0, 0x16, 0x05, 0x04, 0xe0, 0x38, 0x06, 0x05, 0x60, 0x15, 0x07, 0x05, 0x80, 0x33, 0x0a, 0x07, 0x30, 0x2f, 0x00, 0x03, 0x38, 0x2f, 0x00, 0x03, + 0x40, 0x2f, 0x00, 0x03, 0x48, 0x2f, 0x00, 0x03, 0x14, 0x1d, 0x01, 0x02, 0x18, 0x1d, 0x01, 0x02, 0x1c, 0x1d, 0x01, 0x02, 0x20, 0x1d, 0x01, 0x02, 0x24, 0x1d, 0x01, 0x02, 0x28, 0x1d, 0x01, 0x02, + 0xe8, 0x00, 0x02, 0x02, 0xec, 0x00, 0x02, 0x02, 0xf0, 0x00, 0x02, 0x02, 0xf4, 0x00, 0x02, 0x02, 0x18, 0x1a, 0x03, 0x03, 0x20, 0x1a, 0x03, 0x03, 0x28, 0x1a, 0x03, 0x03, 0x70, 0x3d, 0x04, 0x04, + 0x80, 0x3d, 0x04, 0x04, 0xc0, 0x16, 0x05, 0x04, 0xd0, 0x16, 0x05, 0x04, 0x00, 0x39, 0x06, 0x05, 0x80, 0x30, 0x08, 0x06, 0x00, 0x34, 0x0a, 0x07, 0x50, 0x2f, 0x00, 0x03, 0x58, 0x2f, 0x00, 0x03, + 0x60, 0x2f, 0x00, 0x03, 0x68, 0x2f, 0x00, 0x03, 0x2c, 0x1d, 0x01, 0x02, 0x30, 0x1d, 0x01, 0x02, 0x34, 0x1d, 0x01, 0x02, 0x38, 0x1d, 0x01, 0x02, 0x3c, 0x1d, 0x01, 0x02, 0x40, 0x1d, 0x01, 0x02, + 0xf8, 0x00, 0x02, 0x02, 0xfc, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x04, 0x01, 0x02, 0x02, 0x30, 0x1a, 0x03, 0x03, 0x38, 0x1a, 0x03, 0x03, 0x40, 0x1a, 0x03, 0x03, 0x90, 0x3d, 0x04, 0x04, + 0xa0, 0x3d, 0x04, 0x04, 0xe0, 0x16, 0x05, 0x04, 0xf0, 0x16, 0x05, 0x04, 0x20, 0x39, 0x06, 0x05, 0xc0, 0x30, 0x08, 0x06, 0x80, 0x34, 0x0a, 0x07, 0x70, 0x2f, 0x00, 0x03, 0x78, 0x2f, 0x00, 0x03, + 0x80, 0x2f, 0x00, 0x03, 0x88, 0x2f, 0x00, 0x03, 0x44, 0x1d, 0x01, 0x02, 0x48, 0x1d, 0x01, 0x02, 0x4c, 0x1d, 0x01, 0x02, 0x50, 0x1d, 0x01, 0x02, 0x54, 0x1d, 0x01, 0x02, 0x58, 0x1d, 0x01, 0x02, + 0x08, 0x01, 0x02, 0x02, 0x0c, 0x01, 0x02, 0x02, 0x10, 0x01, 0x02, 0x02, 0x14, 0x01, 0x02, 0x02, 0x48, 0x1a, 0x03, 0x03, 0x50, 0x1a, 0x03, 0x03, 0x58, 0x1a, 0x03, 0x03, 0xb0, 0x3d, 0x04, 0x04, + 0xc0, 0x3d, 0x04, 0x04, 0x00, 0x17, 0x05, 0x04, 0x10, 0x17, 0x05, 0x04, 0x40, 0x39, 0x06, 0x05, 0x00, 0x31, 0x08, 0x06, 0x00, 0x35, 0x0a, 0x07, 0x90, 0x2f, 0x00, 0x03, 0x98, 0x2f, 0x00, 0x03, + 0xa0, 0x2f, 0x00, 0x03, 0xa8, 0x2f, 0x00, 0x03, 0x5c, 0x1d, 0x01, 0x02, 0x60, 0x1d, 0x01, 0x02, 0x64, 0x1d, 0x01, 0x02, 0x68, 0x1d, 0x01, 0x02, 0x6c, 0x1d, 0x01, 0x02, 0x70, 0x1d, 0x01, 0x02, + 0x18, 0x01, 0x02, 0x02, 0x1c, 0x01, 0x02, 0x02, 0x20, 0x01, 0x02, 0x02, 0x24, 0x01, 0x02, 0x02, 0x60, 0x1a, 0x03, 0x03, 0x68, 0x1a, 0x03, 0x03, 0x70, 0x1a, 0x03, 0x03, 0xd0, 0x3d, 0x04, 0x04, + 0xe0, 0x3d, 0x04, 0x04, 0x20, 0x17, 0x05, 0x04, 0x30, 0x17, 0x05, 0x04, 0x60, 0x39, 0x06, 0x05, 0x40, 0x31, 0x08, 0x06, 0x80, 0x35, 0x0a, 0x07, 0xb0, 0x2f, 0x00, 0x03, 0xb8, 0x2f, 0x00, 0x03, + 0xc0, 0x2f, 0x00, 0x03, 0xc8, 0x2f, 0x00, 0x03, 0x74, 0x1d, 0x01, 0x02, 0x78, 0x1d, 0x01, 0x02, 0x7c, 0x1d, 0x01, 0x02, 0x80, 0x1d, 0x01, 0x02, 0x84, 0x1d, 0x01, 0x02, 0x88, 0x1d, 0x01, 0x02, + 0x28, 0x01, 0x02, 0x02, 0x2c, 0x01, 0x02, 0x02, 0x30, 0x01, 0x02, 0x02, 0x34, 0x01, 0x02, 0x02, 0x78, 0x1a, 0x03, 0x03, 0x80, 0x1a, 0x03, 0x03, 0x88, 0x1a, 0x03, 0x03, 0xf0, 0x3d, 0x04, 0x04, + 0x00, 0x3e, 0x04, 0x04, 0x40, 0x17, 0x05, 0x04, 0x50, 0x17, 0x05, 0x04, 0x80, 0x39, 0x06, 0x05, 0x80, 0x31, 0x08, 0x06, 0x00, 0x36, 0x0a, 0x07, 0xd0, 0x2f, 0x00, 0x03, 0xd8, 0x2f, 0x00, 0x03, + 0xe0, 0x2f, 0x00, 0x03, 0xe8, 0x2f, 0x00, 0x03, 0x8c, 0x1d, 0x01, 0x02, 0x90, 0x1d, 0x01, 0x02, 0x94, 0x1d, 0x01, 0x02, 0x98, 0x1d, 0x01, 0x02, 0x9c, 0x1d, 0x01, 0x02, 0xa0, 0x1d, 0x01, 0x02, + 0x38, 0x01, 0x02, 0x02, 0x3c, 0x01, 0x02, 0x02, 0x40, 0x01, 0x02, 0x02, 0x44, 0x01, 0x02, 0x02, 0x90, 0x1a, 0x03, 0x03, 0x98, 0x1a, 0x03, 0x03, 0xa0, 0x1a, 0x03, 0x03, 0x10, 0x3e, 0x04, 0x04, + 0x20, 0x3e, 0x04, 0x04, 0x60, 0x17, 0x05, 0x04, 0x70, 0x17, 0x05, 0x04, 0xa0, 0x39, 0x06, 0x05, 0xc0, 0x31, 0x08, 0x06, 0x80, 0x0b, 0x0b, 0x07, 0xf0, 0x2f, 0x00, 0x03, 0xf8, 0x2f, 0x00, 0x03, + 0x00, 0x30, 0x00, 0x03, 0x08, 0x30, 0x00, 0x03, 0xa4, 0x1d, 0x01, 0x02, 0xa8, 0x1d, 0x01, 0x02, 0xac, 0x1d, 0x01, 0x02, 0xb0, 0x1d, 0x01, 0x02, 0xb4, 0x1d, 0x01, 0x02, 0xb8, 0x1d, 0x01, 0x02, + 0x48, 0x01, 0x02, 0x02, 0x4c, 0x01, 0x02, 0x02, 0x50, 0x01, 0x02, 0x02, 0x54, 0x01, 0x02, 0x02, 0xa8, 0x1a, 0x03, 0x03, 0xb0, 0x1a, 0x03, 0x03, 0xb8, 0x1a, 0x03, 0x03, 0x30, 0x3e, 0x04, 0x04, + 0x40, 0x3e, 0x04, 0x04, 0x80, 0x17, 0x05, 0x04, 0x90, 0x17, 0x05, 0x04, 0xc0, 0x39, 0x06, 0x05, 0x00, 0x32, 0x08, 0x06, 0x00, 0x0c, 0x0b, 0x07, 0x10, 0x30, 0x00, 0x03, 0x18, 0x30, 0x00, 0x03, + 0x20, 0x30, 0x00, 0x03, 0x28, 0x30, 0x00, 0x03, 0xbc, 0x1d, 0x01, 0x02, 0xc0, 0x1d, 0x01, 0x02, 0xc4, 0x1d, 0x01, 0x02, 0xc8, 0x1d, 0x01, 0x02, 0xcc, 0x1d, 0x01, 0x02, 0xd0, 0x1d, 0x01, 0x02, + 0x58, 0x01, 0x02, 0x02, 0x5c, 0x01, 0x02, 0x02, 0x60, 0x01, 0x02, 0x02, 0x64, 0x01, 0x02, 0x02, 0xc0, 0x1a, 0x03, 0x03, 0xc8, 0x1a, 0x03, 0x03, 0xd0, 0x1a, 0x03, 0x03, 0x50, 0x3e, 0x04, 0x04, + 0x60, 0x3e, 0x04, 0x04, 0xa0, 0x17, 0x05, 0x04, 0xb0, 0x17, 0x05, 0x04, 0xe0, 0x39, 0x06, 0x05, 0x40, 0x32, 0x08, 0x06, 0x80, 0x0c, 0x0b, 0x07, 0x30, 0x30, 0x00, 0x03, 0x38, 0x30, 0x00, 0x03, + 0x40, 0x30, 0x00, 0x03, 0x48, 0x30, 0x00, 0x03, 0xd4, 0x1d, 0x01, 0x02, 0xd8, 0x1d, 0x01, 0x02, 0xdc, 0x1d, 0x01, 0x02, 0xe0, 0x1d, 0x01, 0x02, 0xe4, 0x1d, 0x01, 0x02, 0xe8, 0x1d, 0x01, 0x02, + 0x68, 0x01, 0x02, 0x02, 0x6c, 0x01, 0x02, 0x02, 0x70, 0x01, 0x02, 0x02, 0x74, 0x01, 0x02, 0x02, 0xd8, 0x1a, 0x03, 0x03, 0xe0, 0x1a, 0x03, 0x03, 0xe8, 0x1a, 0x03, 0x03, 0x70, 0x3e, 0x04, 0x04, + 0x80, 0x3e, 0x04, 0x04, 0xc0, 0x17, 0x05, 0x04, 0xd0, 0x17, 0x05, 0x04, 0x00, 0x3a, 0x06, 0x05, 0x80, 0x32, 0x08, 0x06, 0x00, 0x0d, 0x0b, 0x07, 0x50, 0x30, 0x00, 0x03, 0x58, 0x30, 0x00, 0x03, + 0x60, 0x30, 0x00, 0x03, 0x68, 0x30, 0x00, 0x03, 0xec, 0x1d, 0x01, 0x02, 0xf0, 0x1d, 0x01, 0x02, 0xf4, 0x1d, 0x01, 0x02, 0xf8, 0x1d, 0x01, 0x02, 0xfc, 0x1d, 0x01, 0x02, 0x00, 0x1e, 0x01, 0x02, + 0x78, 0x01, 0x02, 0x02, 0x7c, 0x01, 0x02, 0x02, 0x80, 0x01, 0x02, 0x02, 0x84, 0x01, 0x02, 0x02, 0xf0, 0x1a, 0x03, 0x03, 0xf8, 0x1a, 0x03, 0x03, 0x00, 0x1b, 0x03, 0x03, 0x90, 0x3e, 0x04, 0x04, + 0xa0, 0x3e, 0x04, 0x04, 0xe0, 0x17, 0x05, 0x04, 0xf0, 0x17, 0x05, 0x04, 0x20, 0x3a, 0x06, 0x05, 0xc0, 0x32, 0x08, 0x06, 0x80, 0x0d, 0x0b, 0x07, 0x70, 0x30, 0x00, 0x03, 0x78, 0x30, 0x00, 0x03, + 0x80, 0x30, 0x00, 0x03, 0x88, 0x30, 0x00, 0x03, 0x04, 0x1e, 0x01, 0x02, 0x08, 0x1e, 0x01, 0x02, 0x0c, 0x1e, 0x01, 0x02, 0x10, 0x1e, 0x01, 0x02, 0x14, 0x1e, 0x01, 0x02, 0x18, 0x1e, 0x01, 0x02, + 0x88, 0x01, 0x02, 0x02, 0x8c, 0x01, 0x02, 0x02, 0x90, 0x01, 0x02, 0x02, 0x94, 0x01, 0x02, 0x02, 0x08, 0x1b, 0x03, 0x03, 0x10, 0x1b, 0x03, 0x03, 0x18, 0x1b, 0x03, 0x03, 0xb0, 0x3e, 0x04, 0x04, + 0xc0, 0x3e, 0x04, 0x04, 0x00, 0x18, 0x05, 0x04, 0x10, 0x18, 0x05, 0x04, 0x40, 0x3a, 0x06, 0x05, 0x00, 0x33, 0x08, 0x06, 0x00, 0x0e, 0x0b, 0x07, 0x90, 0x30, 0x00, 0x03, 0x98, 0x30, 0x00, 0x03, + 0xa0, 0x30, 0x00, 0x03, 0xa8, 0x30, 0x00, 0x03, 0x1c, 0x1e, 0x01, 0x02, 0x20, 0x1e, 0x01, 0x02, 0x24, 0x1e, 0x01, 0x02, 0x28, 0x1e, 0x01, 0x02, 0x2c, 0x1e, 0x01, 0x02, 0x30, 0x1e, 0x01, 0x02, + 0x98, 0x01, 0x02, 0x02, 0x9c, 0x01, 0x02, 0x02, 0xa0, 0x01, 0x02, 0x02, 0xa4, 0x01, 0x02, 0x02, 0x20, 0x1b, 0x03, 0x03, 0x28, 0x1b, 0x03, 0x03, 0x30, 0x1b, 0x03, 0x03, 0xd0, 0x3e, 0x04, 0x04, + 0xe0, 0x3e, 0x04, 0x04, 0x20, 0x18, 0x05, 0x04, 0x30, 0x18, 0x05, 0x04, 0x60, 0x3a, 0x06, 0x05, 0x40, 0x33, 0x08, 0x06, 0x80, 0x0e, 0x0b, 0x07, 0xb0, 0x30, 0x00, 0x03, 0xb8, 0x30, 0x00, 0x03, + 0xc0, 0x30, 0x00, 0x03, 0xc8, 0x30, 0x00, 0x03, 0x34, 0x1e, 0x01, 0x02, 0x38, 0x1e, 0x01, 0x02, 0x3c, 0x1e, 0x01, 0x02, 0x40, 0x1e, 0x01, 0x02, 0x44, 0x1e, 0x01, 0x02, 0x48, 0x1e, 0x01, 0x02, + 0xa8, 0x01, 0x02, 0x02, 0xac, 0x01, 0x02, 0x02, 0xb0, 0x01, 0x02, 0x02, 0xb4, 0x01, 0x02, 0x02, 0x38, 0x1b, 0x03, 0x03, 0x40, 0x1b, 0x03, 0x03, 0x48, 0x1b, 0x03, 0x03, 0xf0, 0x3e, 0x04, 0x04, + 0x00, 0x3f, 0x04, 0x04, 0x40, 0x18, 0x05, 0x04, 0x50, 0x18, 0x05, 0x04, 0x80, 0x3a, 0x06, 0x05, 0x80, 0x33, 0x08, 0x06, 0x00, 0x0f, 0x0b, 0x07, 0xd0, 0x30, 0x00, 0x03, 0xd8, 0x30, 0x00, 0x03, + 0xe0, 0x30, 0x00, 0x03, 0xe8, 0x30, 0x00, 0x03, 0x4c, 0x1e, 0x01, 0x02, 0x50, 0x1e, 0x01, 0x02, 0x54, 0x1e, 0x01, 0x02, 0x58, 0x1e, 0x01, 0x02, 0x5c, 0x1e, 0x01, 0x02, 0x60, 0x1e, 0x01, 0x02, + 0xb8, 0x01, 0x02, 0x02, 0xbc, 0x01, 0x02, 0x02, 0xc0, 0x01, 0x02, 0x02, 0xc4, 0x01, 0x02, 0x02, 0x50, 0x1b, 0x03, 0x03, 0x58, 0x1b, 0x03, 0x03, 0x60, 0x1b, 0x03, 0x03, 0x10, 0x3f, 0x04, 0x04, + 0x20, 0x3f, 0x04, 0x04, 0x60, 0x18, 0x05, 0x04, 0x70, 0x18, 0x05, 0x04, 0xa0, 0x3a, 0x06, 0x05, 0xc0, 0x33, 0x08, 0x06, 0x80, 0x0f, 0x0b, 0x07, 0xf0, 0x30, 0x00, 0x03, 0xf8, 0x30, 0x00, 0x03, + 0x00, 0x31, 0x00, 0x03, 0x08, 0x31, 0x00, 0x03, 0x64, 0x1e, 0x01, 0x02, 0x68, 0x1e, 0x01, 0x02, 0x6c, 0x1e, 0x01, 0x02, 0x70, 0x1e, 0x01, 0x02, 0x74, 0x1e, 0x01, 0x02, 0x78, 0x1e, 0x01, 0x02, + 0xc8, 0x01, 0x02, 0x02, 0xcc, 0x01, 0x02, 0x02, 0xd0, 0x01, 0x02, 0x02, 0xd4, 0x01, 0x02, 0x02, 0x68, 0x1b, 0x03, 0x03, 0x70, 0x1b, 0x03, 0x03, 0x78, 0x1b, 0x03, 0x03, 0x30, 0x3f, 0x04, 0x04, + 0x40, 0x3f, 0x04, 0x04, 0x80, 0x18, 0x05, 0x04, 0x90, 0x18, 0x05, 0x04, 0xc0, 0x3a, 0x06, 0x05, 0x00, 0x34, 0x08, 0x06, 0x00, 0x10, 0x0b, 0x07, 0x10, 0x31, 0x00, 0x03, 0x18, 0x31, 0x00, 0x03, + 0x20, 0x31, 0x00, 0x03, 0x28, 0x31, 0x00, 0x03, 0x7c, 0x1e, 0x01, 0x02, 0x80, 0x1e, 0x01, 0x02, 0x84, 0x1e, 0x01, 0x02, 0x88, 0x1e, 0x01, 0x02, 0x8c, 0x1e, 0x01, 0x02, 0x90, 0x1e, 0x01, 0x02, + 0xd8, 0x01, 0x02, 0x02, 0xdc, 0x01, 0x02, 0x02, 0xe0, 0x01, 0x02, 0x02, 0xe4, 0x01, 0x02, 0x02, 0x80, 0x1b, 0x03, 0x03, 0x88, 0x1b, 0x03, 0x03, 0x90, 0x1b, 0x03, 0x03, 0x50, 0x3f, 0x04, 0x04, + 0x60, 0x3f, 0x04, 0x04, 0xa0, 0x18, 0x05, 0x04, 0xb0, 0x18, 0x05, 0x04, 0xe0, 0x3a, 0x06, 0x05, 0x40, 0x34, 0x08, 0x06, 0x80, 0x10, 0x0b, 0x07, 0x30, 0x31, 0x00, 0x03, 0x38, 0x31, 0x00, 0x03, + 0x40, 0x31, 0x00, 0x03, 0x48, 0x31, 0x00, 0x03, 0x94, 0x1e, 0x01, 0x02, 0x98, 0x1e, 0x01, 0x02, 0x9c, 0x1e, 0x01, 0x02, 0xa0, 0x1e, 0x01, 0x02, 0xa4, 0x1e, 0x01, 0x02, 0xa8, 0x1e, 0x01, 0x02, + 0xe8, 0x01, 0x02, 0x02, 0xec, 0x01, 0x02, 0x02, 0xf0, 0x01, 0x02, 0x02, 0xf4, 0x01, 0x02, 0x02, 0x98, 0x1b, 0x03, 0x03, 0xa0, 0x1b, 0x03, 0x03, 0xa8, 0x1b, 0x03, 0x03, 0x70, 0x3f, 0x04, 0x04, + 0x80, 0x3f, 0x04, 0x04, 0xc0, 0x18, 0x05, 0x04, 0xd0, 0x18, 0x05, 0x04, 0x00, 0x3b, 0x06, 0x05, 0x80, 0x34, 0x08, 0x06, 0x00, 0x11, 0x0b, 0x07, 0x50, 0x31, 0x00, 0x03, 0x58, 0x31, 0x00, 0x03, + 0x60, 0x31, 0x00, 0x03, 0x68, 0x31, 0x00, 0x03, 0xac, 0x1e, 0x01, 0x02, 0xb0, 0x1e, 0x01, 0x02, 0xb4, 0x1e, 0x01, 0x02, 0xb8, 0x1e, 0x01, 0x02, 0xbc, 0x1e, 0x01, 0x02, 0xc0, 0x1e, 0x01, 0x02, + 0xf8, 0x01, 0x02, 0x02, 0xfc, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0xb0, 0x1b, 0x03, 0x03, 0xb8, 0x1b, 0x03, 0x03, 0xc0, 0x1b, 0x03, 0x03, 0x90, 0x3f, 0x04, 0x04, + 0xa0, 0x3f, 0x04, 0x04, 0xe0, 0x18, 0x05, 0x04, 0xf0, 0x18, 0x05, 0x04, 0x20, 0x3b, 0x06, 0x05, 0xc0, 0x34, 0x08, 0x06, 0x80, 0x11, 0x0b, 0x07, 0x70, 0x31, 0x00, 0x03, 0x78, 0x31, 0x00, 0x03, + 0x80, 0x31, 0x00, 0x03, 0x88, 0x31, 0x00, 0x03, 0xc4, 0x1e, 0x01, 0x02, 0xc8, 0x1e, 0x01, 0x02, 0xcc, 0x1e, 0x01, 0x02, 0xd0, 0x1e, 0x01, 0x02, 0xd4, 0x1e, 0x01, 0x02, 0xd8, 0x1e, 0x01, 0x02, + 0x08, 0x02, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x02, 0x10, 0x02, 0x02, 0x02, 0x14, 0x02, 0x02, 0x02, 0xc8, 0x1b, 0x03, 0x03, 0xd0, 0x1b, 0x03, 0x03, 0xd8, 0x1b, 0x03, 0x03, 0xb0, 0x3f, 0x04, 0x04, + 0xc0, 0x3f, 0x04, 0x04, 0x00, 0x19, 0x05, 0x04, 0x10, 0x19, 0x05, 0x04, 0x40, 0x3b, 0x06, 0x05, 0x00, 0x35, 0x08, 0x06, 0x00, 0x12, 0x0b, 0x07, 0x90, 0x31, 0x00, 0x03, 0x98, 0x31, 0x00, 0x03, + 0xa0, 0x31, 0x00, 0x03, 0xa8, 0x31, 0x00, 0x03, 0xdc, 0x1e, 0x01, 0x02, 0xe0, 0x1e, 0x01, 0x02, 0xe4, 0x1e, 0x01, 0x02, 0xe8, 0x1e, 0x01, 0x02, 0xec, 0x1e, 0x01, 0x02, 0xf0, 0x1e, 0x01, 0x02, + 0x18, 0x02, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0x20, 0x02, 0x02, 0x02, 0x24, 0x02, 0x02, 0x02, 0xe0, 0x1b, 0x03, 0x03, 0xe8, 0x1b, 0x03, 0x03, 0xf0, 0x1b, 0x03, 0x03, 0xd0, 0x3f, 0x04, 0x04, + 0xe0, 0x3f, 0x04, 0x04, 0x20, 0x19, 0x05, 0x04, 0x30, 0x19, 0x05, 0x04, 0x60, 0x3b, 0x06, 0x05, 0x40, 0x35, 0x08, 0x06, 0x00, 0x28, 0x0c, 0x08, 0xb0, 0x31, 0x00, 0x03, 0xb8, 0x31, 0x00, 0x03, + 0xc0, 0x31, 0x00, 0x03, 0xc8, 0x31, 0x00, 0x03, 0xf4, 0x1e, 0x01, 0x02, 0xf8, 0x1e, 0x01, 0x02, 0xfc, 0x1e, 0x01, 0x02, 0x00, 0x1f, 0x01, 0x02, 0x04, 0x1f, 0x01, 0x02, 0x08, 0x1f, 0x01, 0x02, + 0x28, 0x02, 0x02, 0x02, 0x2c, 0x02, 0x02, 0x02, 0x30, 0x02, 0x02, 0x02, 0x34, 0x02, 0x02, 0x02, 0xf8, 0x1b, 0x03, 0x03, 0x00, 0x1c, 0x03, 0x03, 0x08, 0x1c, 0x03, 0x03, 0xf0, 0x3f, 0x04, 0x04, + 0x00, 0x00, 0x04, 0x03, 0x40, 0x19, 0x05, 0x04, 0x50, 0x19, 0x05, 0x04, 0x80, 0x3b, 0x06, 0x05, 0x80, 0x35, 0x08, 0x06, 0x00, 0x29, 0x0c, 0x08, 0xd0, 0x31, 0x00, 0x03, 0xd8, 0x31, 0x00, 0x03, + 0xe0, 0x31, 0x00, 0x03, 0xe8, 0x31, 0x00, 0x03, 0x0c, 0x1f, 0x01, 0x02, 0x10, 0x1f, 0x01, 0x02, 0x14, 0x1f, 0x01, 0x02, 0x18, 0x1f, 0x01, 0x02, 0x1c, 0x1f, 0x01, 0x02, 0x20, 0x1f, 0x01, 0x02, + 0x38, 0x02, 0x02, 0x02, 0x3c, 0x02, 0x02, 0x02, 0x40, 0x02, 0x02, 0x02, 0x44, 0x02, 0x02, 0x02, 0x10, 0x1c, 0x03, 0x03, 0x18, 0x1c, 0x03, 0x03, 0x20, 0x1c, 0x03, 0x03, 0x08, 0x00, 0x04, 0x03, + 0x10, 0x00, 0x04, 0x03, 0x60, 0x19, 0x05, 0x04, 0x70, 0x19, 0x05, 0x04, 0xa0, 0x3b, 0x06, 0x05, 0xc0, 0x35, 0x08, 0x06, 0x00, 0x2a, 0x0c, 0x08, 0xf0, 0x31, 0x00, 0x03, 0xf8, 0x31, 0x00, 0x03, + 0x00, 0x32, 0x00, 0x03, 0x08, 0x32, 0x00, 0x03, 0x24, 0x1f, 0x01, 0x02, 0x28, 0x1f, 0x01, 0x02, 0x2c, 0x1f, 0x01, 0x02, 0x30, 0x1f, 0x01, 0x02, 0x34, 0x1f, 0x01, 0x02, 0x38, 0x1f, 0x01, 0x02, + 0x48, 0x02, 0x02, 0x02, 0x4c, 0x02, 0x02, 0x02, 0x50, 0x02, 0x02, 0x02, 0x54, 0x02, 0x02, 0x02, 0x28, 0x1c, 0x03, 0x03, 0x30, 0x1c, 0x03, 0x03, 0x38, 0x1c, 0x03, 0x03, 0x18, 0x00, 0x04, 0x03, + 0x20, 0x00, 0x04, 0x03, 0x80, 0x19, 0x05, 0x04, 0x90, 0x19, 0x05, 0x04, 0xc0, 0x3b, 0x06, 0x05, 0x00, 0x36, 0x08, 0x06, 0x00, 0x2b, 0x0c, 0x08, 0x10, 0x32, 0x00, 0x03, 0x18, 0x32, 0x00, 0x03, + 0x20, 0x32, 0x00, 0x03, 0x28, 0x32, 0x00, 0x03, 0x3c, 0x1f, 0x01, 0x02, 0x40, 0x1f, 0x01, 0x02, 0x44, 0x1f, 0x01, 0x02, 0x48, 0x1f, 0x01, 0x02, 0x4c, 0x1f, 0x01, 0x02, 0x50, 0x1f, 0x01, 0x02, + 0x58, 0x02, 0x02, 0x02, 0x5c, 0x02, 0x02, 0x02, 0x60, 0x02, 0x02, 0x02, 0x64, 0x02, 0x02, 0x02, 0x40, 0x1c, 0x03, 0x03, 0x48, 0x1c, 0x03, 0x03, 0x50, 0x1c, 0x03, 0x03, 0x28, 0x00, 0x04, 0x03, + 0x30, 0x00, 0x04, 0x03, 0xa0, 0x19, 0x05, 0x04, 0xb0, 0x19, 0x05, 0x04, 0xe0, 0x3b, 0x06, 0x05, 0x40, 0x36, 0x08, 0x06, 0x00, 0x2c, 0x0c, 0x08, 0x30, 0x32, 0x00, 0x03, 0x38, 0x32, 0x00, 0x03, + 0x40, 0x32, 0x00, 0x03, 0x54, 0x1f, 0x01, 0x02, 0x58, 0x1f, 0x01, 0x02, 0x5c, 0x1f, 0x01, 0x02, 0x60, 0x1f, 0x01, 0x02, 0x64, 0x1f, 0x01, 0x02, 0x68, 0x1f, 0x01, 0x02, 0x6c, 0x1f, 0x01, 0x02, + 0x68, 0x02, 0x02, 0x02, 0x6c, 0x02, 0x02, 0x02, 0x70, 0x02, 0x02, 0x02, 0x74, 0x02, 0x02, 0x02, 0x58, 0x1c, 0x03, 0x03, 0x60, 0x1c, 0x03, 0x03, 0x68, 0x1c, 0x03, 0x03, 0x38, 0x00, 0x04, 0x03, + 0x40, 0x00, 0x04, 0x03, 0xc0, 0x19, 0x05, 0x04, 0xd0, 0x19, 0x05, 0x04, 0x00, 0x3c, 0x06, 0x05, 0x80, 0x36, 0x08, 0x06, 0x00, 0x2d, 0x0c, 0x08, 0x48, 0x32, 0x00, 0x03, 0x50, 0x32, 0x00, 0x03, + 0x58, 0x32, 0x00, 0x03, 0x70, 0x1f, 0x01, 0x02, 0x74, 0x1f, 0x01, 0x02, 0x78, 0x1f, 0x01, 0x02, 0x7c, 0x1f, 0x01, 0x02, 0x80, 0x1f, 0x01, 0x02, 0x84, 0x1f, 0x01, 0x02, 0x88, 0x1f, 0x01, 0x02, + 0x78, 0x02, 0x02, 0x02, 0x7c, 0x02, 0x02, 0x02, 0x80, 0x02, 0x02, 0x02, 0x84, 0x02, 0x02, 0x02, 0x70, 0x1c, 0x03, 0x03, 0x78, 0x1c, 0x03, 0x03, 0x80, 0x1c, 0x03, 0x03, 0x48, 0x00, 0x04, 0x03, + 0x50, 0x00, 0x04, 0x03, 0xe0, 0x19, 0x05, 0x04, 0x20, 0x3c, 0x06, 0x05, 0x40, 0x3c, 0x06, 0x05, 0xc0, 0x36, 0x08, 0x06, 0x00, 0x2e, 0x0c, 0x08, 0x60, 0x32, 0x00, 0x03, 0x68, 0x32, 0x00, 0x03, + 0x70, 0x32, 0x00, 0x03, 0x8c, 0x1f, 0x01, 0x02, 0x90, 0x1f, 0x01, 0x02, 0x94, 0x1f, 0x01, 0x02, 0x98, 0x1f, 0x01, 0x02, 0x9c, 0x1f, 0x01, 0x02, 0xa0, 0x1f, 0x01, 0x02, 0xa4, 0x1f, 0x01, 0x02, + 0x88, 0x02, 0x02, 0x02, 0x8c, 0x02, 0x02, 0x02, 0x90, 0x02, 0x02, 0x02, 0x94, 0x02, 0x02, 0x02, 0x88, 0x1c, 0x03, 0x03, 0x90, 0x1c, 0x03, 0x03, 0x98, 0x1c, 0x03, 0x03, 0x58, 0x00, 0x04, 0x03, + 0x60, 0x00, 0x04, 0x03, 0xf0, 0x19, 0x05, 0x04, 0x60, 0x3c, 0x06, 0x05, 0x80, 0x15, 0x07, 0x05, 0x00, 0x37, 0x08, 0x06, 0x00, 0x2f, 0x0c, 0x08, 0x78, 0x32, 0x00, 0x03, 0x80, 0x32, 0x00, 0x03, + 0x88, 0x32, 0x00, 0x03, 0xa8, 0x1f, 0x01, 0x02, 0xac, 0x1f, 0x01, 0x02, 0xb0, 0x1f, 0x01, 0x02, 0xb4, 0x1f, 0x01, 0x02, 0xb8, 0x1f, 0x01, 0x02, 0xbc, 0x1f, 0x01, 0x02, 0xc0, 0x1f, 0x01, 0x02, + 0x98, 0x02, 0x02, 0x02, 0x9c, 0x02, 0x02, 0x02, 0xa0, 0x02, 0x02, 0x02, 0xa4, 0x02, 0x02, 0x02, 0xa0, 0x1c, 0x03, 0x03, 0xa8, 0x1c, 0x03, 0x03, 0xb0, 0x1c, 0x03, 0x03, 0x68, 0x00, 0x04, 0x03, + 0x70, 0x00, 0x04, 0x03, 0x00, 0x1a, 0x05, 0x04, 0x80, 0x3c, 0x06, 0x05, 0xa0, 0x15, 0x07, 0x05, 0x40, 0x37, 0x08, 0x06, 0x00, 0x30, 0x0c, 0x08, 0x90, 0x32, 0x00, 0x03, 0x98, 0x32, 0x00, 0x03, + 0xa0, 0x32, 0x00, 0x03, 0xc4, 0x1f, 0x01, 0x02, 0xc8, 0x1f, 0x01, 0x02, 0xcc, 0x1f, 0x01, 0x02, 0xd0, 0x1f, 0x01, 0x02, 0xd4, 0x1f, 0x01, 0x02, 0xd8, 0x1f, 0x01, 0x02, 0xdc, 0x1f, 0x01, 0x02, + 0xa8, 0x02, 0x02, 0x02, 0xac, 0x02, 0x02, 0x02, 0xb0, 0x02, 0x02, 0x02, 0xb4, 0x02, 0x02, 0x02, 0xb8, 0x1c, 0x03, 0x03, 0xc0, 0x1c, 0x03, 0x03, 0xc8, 0x1c, 0x03, 0x03, 0x78, 0x00, 0x04, 0x03, + 0x80, 0x00, 0x04, 0x03, 0x10, 0x1a, 0x05, 0x04, 0xa0, 0x3c, 0x06, 0x05, 0xc0, 0x15, 0x07, 0x05, 0x80, 0x37, 0x08, 0x06, 0x00, 0x31, 0x0c, 0x08, 0xa8, 0x32, 0x00, 0x03, 0xb0, 0x32, 0x00, 0x03, + 0xb8, 0x32, 0x00, 0x03, 0xe0, 0x1f, 0x01, 0x02, 0xe4, 0x1f, 0x01, 0x02, 0xe8, 0x1f, 0x01, 0x02, 0xec, 0x1f, 0x01, 0x02, 0xf0, 0x1f, 0x01, 0x02, 0xf4, 0x1f, 0x01, 0x02, 0xf8, 0x1f, 0x01, 0x02, + 0xb8, 0x02, 0x02, 0x02, 0xbc, 0x02, 0x02, 0x02, 0xc0, 0x02, 0x02, 0x02, 0xc4, 0x02, 0x02, 0x02, 0xd0, 0x1c, 0x03, 0x03, 0xd8, 0x1c, 0x03, 0x03, 0xe0, 0x1c, 0x03, 0x03, 0x88, 0x00, 0x04, 0x03, + 0x90, 0x00, 0x04, 0x03, 0x20, 0x1a, 0x05, 0x04, 0xc0, 0x3c, 0x06, 0x05, 0xe0, 0x15, 0x07, 0x05, 0xc0, 0x37, 0x08, 0x06, 0x00, 0x09, 0x0d, 0x08, 0xc0, 0x32, 0x00, 0x03, 0xc8, 0x32, 0x00, 0x03, + 0xd0, 0x32, 0x00, 0x03, 0xfc, 0x1f, 0x01, 0x02, 0x00, 0x20, 0x01, 0x02, 0x04, 0x20, 0x01, 0x02, 0x08, 0x20, 0x01, 0x02, 0x0c, 0x20, 0x01, 0x02, 0x10, 0x20, 0x01, 0x02, 0x14, 0x20, 0x01, 0x02, + 0xc8, 0x02, 0x02, 0x02, 0xcc, 0x02, 0x02, 0x02, 0xd0, 0x02, 0x02, 0x02, 0xd4, 0x02, 0x02, 0x02, 0xe8, 0x1c, 0x03, 0x03, 0xf0, 0x1c, 0x03, 0x03, 0xf8, 0x1c, 0x03, 0x03, 0x98, 0x00, 0x04, 0x03, + 0xa0, 0x00, 0x04, 0x03, 0x30, 0x1a, 0x05, 0x04, 0xe0, 0x3c, 0x06, 0x05, 0x00, 0x16, 0x07, 0x05, 0x00, 0x38, 0x08, 0x06, 0x00, 0x0a, 0x0d, 0x08, 0xd8, 0x32, 0x00, 0x03, 0xe0, 0x32, 0x00, 0x03, + 0xe8, 0x32, 0x00, 0x03, 0x18, 0x20, 0x01, 0x02, 0x1c, 0x20, 0x01, 0x02, 0x20, 0x20, 0x01, 0x02, 0x24, 0x20, 0x01, 0x02, 0x28, 0x20, 0x01, 0x02, 0x2c, 0x20, 0x01, 0x02, 0x30, 0x20, 0x01, 0x02, + 0xd8, 0x02, 0x02, 0x02, 0xdc, 0x02, 0x02, 0x02, 0xe0, 0x02, 0x02, 0x02, 0xe4, 0x02, 0x02, 0x02, 0x00, 0x1d, 0x03, 0x03, 0x08, 0x1d, 0x03, 0x03, 0x10, 0x1d, 0x03, 0x03, 0xa8, 0x00, 0x04, 0x03, + 0xb0, 0x00, 0x04, 0x03, 0x40, 0x1a, 0x05, 0x04, 0x00, 0x3d, 0x06, 0x05, 0x20, 0x16, 0x07, 0x05, 0x40, 0x38, 0x08, 0x06, 0x00, 0x0b, 0x0d, 0x08, 0xf0, 0x32, 0x00, 0x03, 0xf8, 0x32, 0x00, 0x03, + 0x00, 0x33, 0x00, 0x03, 0x34, 0x20, 0x01, 0x02, 0x38, 0x20, 0x01, 0x02, 0x3c, 0x20, 0x01, 0x02, 0x40, 0x20, 0x01, 0x02, 0x44, 0x20, 0x01, 0x02, 0x48, 0x20, 0x01, 0x02, 0x4c, 0x20, 0x01, 0x02, + 0xe8, 0x02, 0x02, 0x02, 0xec, 0x02, 0x02, 0x02, 0xf0, 0x02, 0x02, 0x02, 0xf4, 0x02, 0x02, 0x02, 0x18, 0x1d, 0x03, 0x03, 0x20, 0x1d, 0x03, 0x03, 0x28, 0x1d, 0x03, 0x03, 0xb8, 0x00, 0x04, 0x03, + 0xc0, 0x00, 0x04, 0x03, 0x50, 0x1a, 0x05, 0x04, 0x20, 0x3d, 0x06, 0x05, 0x40, 0x16, 0x07, 0x05, 0x80, 0x38, 0x08, 0x06, 0x00, 0x0c, 0x0d, 0x08, 0x08, 0x33, 0x00, 0x03, 0x10, 0x33, 0x00, 0x03, + 0x18, 0x33, 0x00, 0x03, 0x50, 0x20, 0x01, 0x02, 0x54, 0x20, 0x01, 0x02, 0x58, 0x20, 0x01, 0x02, 0x5c, 0x20, 0x01, 0x02, 0x60, 0x20, 0x01, 0x02, 0x64, 0x20, 0x01, 0x02, 0x68, 0x20, 0x01, 0x02, + 0xf8, 0x02, 0x02, 0x02, 0xfc, 0x02, 0x02, 0x02, 0x00, 0x03, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x30, 0x1d, 0x03, 0x03, 0x38, 0x1d, 0x03, 0x03, 0x40, 0x1d, 0x03, 0x03, 0xc8, 0x00, 0x04, 0x03, + 0xd0, 0x00, 0x04, 0x03, 0x60, 0x1a, 0x05, 0x04, 0x40, 0x3d, 0x06, 0x05, 0x60, 0x16, 0x07, 0x05, 0xc0, 0x38, 0x08, 0x06, 0x00, 0x0d, 0x0d, 0x08, 0x20, 0x33, 0x00, 0x03, 0x28, 0x33, 0x00, 0x03, + 0x30, 0x33, 0x00, 0x03, 0x6c, 0x20, 0x01, 0x02, 0x70, 0x20, 0x01, 0x02, 0x74, 0x20, 0x01, 0x02, 0x78, 0x20, 0x01, 0x02, 0x7c, 0x20, 0x01, 0x02, 0x80, 0x20, 0x01, 0x02, 0x84, 0x20, 0x01, 0x02, + 0x08, 0x03, 0x02, 0x02, 0x0c, 0x03, 0x02, 0x02, 0x10, 0x03, 0x02, 0x02, 0x14, 0x03, 0x02, 0x02, 0x48, 0x1d, 0x03, 0x03, 0x50, 0x1d, 0x03, 0x03, 0x58, 0x1d, 0x03, 0x03, 0xd8, 0x00, 0x04, 0x03, + 0xe0, 0x00, 0x04, 0x03, 0x70, 0x1a, 0x05, 0x04, 0x60, 0x3d, 0x06, 0x05, 0x80, 0x16, 0x07, 0x05, 0x00, 0x39, 0x08, 0x06, 0x00, 0x0e, 0x0d, 0x08, 0x38, 0x33, 0x00, 0x03, 0x40, 0x33, 0x00, 0x03, + 0x48, 0x33, 0x00, 0x03, 0x88, 0x20, 0x01, 0x02, 0x8c, 0x20, 0x01, 0x02, 0x90, 0x20, 0x01, 0x02, 0x94, 0x20, 0x01, 0x02, 0x98, 0x20, 0x01, 0x02, 0x9c, 0x20, 0x01, 0x02, 0xa0, 0x20, 0x01, 0x02, + 0x18, 0x03, 0x02, 0x02, 0x1c, 0x03, 0x02, 0x02, 0x20, 0x03, 0x02, 0x02, 0x24, 0x03, 0x02, 0x02, 0x60, 0x1d, 0x03, 0x03, 0x68, 0x1d, 0x03, 0x03, 0x70, 0x1d, 0x03, 0x03, 0xe8, 0x00, 0x04, 0x03, + 0xf0, 0x00, 0x04, 0x03, 0x80, 0x1a, 0x05, 0x04, 0x80, 0x3d, 0x06, 0x05, 0xa0, 0x16, 0x07, 0x05, 0x40, 0x39, 0x08, 0x06, 0x00, 0x26, 0x0e, 0x09, 0x50, 0x33, 0x00, 0x03, 0x58, 0x33, 0x00, 0x03, + 0x60, 0x33, 0x00, 0x03, 0xa4, 0x20, 0x01, 0x02, 0xa8, 0x20, 0x01, 0x02, 0xac, 0x20, 0x01, 0x02, 0xb0, 0x20, 0x01, 0x02, 0xb4, 0x20, 0x01, 0x02, 0xb8, 0x20, 0x01, 0x02, 0xbc, 0x20, 0x01, 0x02, + 0x28, 0x03, 0x02, 0x02, 0x2c, 0x03, 0x02, 0x02, 0x30, 0x03, 0x02, 0x02, 0x34, 0x03, 0x02, 0x02, 0x78, 0x1d, 0x03, 0x03, 0x80, 0x1d, 0x03, 0x03, 0x88, 0x1d, 0x03, 0x03, 0xf8, 0x00, 0x04, 0x03, + 0x00, 0x01, 0x04, 0x03, 0x90, 0x1a, 0x05, 0x04, 0xa0, 0x3d, 0x06, 0x05, 0xc0, 0x16, 0x07, 0x05, 0x80, 0x39, 0x08, 0x06, 0x00, 0x28, 0x0e, 0x09, 0x68, 0x33, 0x00, 0x03, 0x70, 0x33, 0x00, 0x03, + 0x78, 0x33, 0x00, 0x03, 0xc0, 0x20, 0x01, 0x02, 0xc4, 0x20, 0x01, 0x02, 0xc8, 0x20, 0x01, 0x02, 0xcc, 0x20, 0x01, 0x02, 0xd0, 0x20, 0x01, 0x02, 0xd4, 0x20, 0x01, 0x02, 0xd8, 0x20, 0x01, 0x02, + 0x38, 0x03, 0x02, 0x02, 0x3c, 0x03, 0x02, 0x02, 0x40, 0x03, 0x02, 0x02, 0x44, 0x03, 0x02, 0x02, 0x90, 0x1d, 0x03, 0x03, 0x98, 0x1d, 0x03, 0x03, 0xa0, 0x1d, 0x03, 0x03, 0x08, 0x01, 0x04, 0x03, + 0x10, 0x01, 0x04, 0x03, 0xa0, 0x1a, 0x05, 0x04, 0xc0, 0x3d, 0x06, 0x05, 0xe0, 0x16, 0x07, 0x05, 0xc0, 0x39, 0x08, 0x06, 0x00, 0x2a, 0x0e, 0x09, 0x80, 0x33, 0x00, 0x03, 0x88, 0x33, 0x00, 0x03, + 0x90, 0x33, 0x00, 0x03, 0xdc, 0x20, 0x01, 0x02, 0xe0, 0x20, 0x01, 0x02, 0xe4, 0x20, 0x01, 0x02, 0xe8, 0x20, 0x01, 0x02, 0xec, 0x20, 0x01, 0x02, 0xf0, 0x20, 0x01, 0x02, 0xf4, 0x20, 0x01, 0x02, + 0x48, 0x03, 0x02, 0x02, 0x4c, 0x03, 0x02, 0x02, 0x50, 0x03, 0x02, 0x02, 0x54, 0x03, 0x02, 0x02, 0xa8, 0x1d, 0x03, 0x03, 0xb0, 0x1d, 0x03, 0x03, 0xb8, 0x1d, 0x03, 0x03, 0x18, 0x01, 0x04, 0x03, + 0x20, 0x01, 0x04, 0x03, 0xb0, 0x1a, 0x05, 0x04, 0xe0, 0x3d, 0x06, 0x05, 0x00, 0x17, 0x07, 0x05, 0x00, 0x3a, 0x08, 0x06, 0x00, 0x2c, 0x0e, 0x09, 0x98, 0x33, 0x00, 0x03, 0xa0, 0x33, 0x00, 0x03, + 0xa8, 0x33, 0x00, 0x03, 0xf8, 0x20, 0x01, 0x02, 0xfc, 0x20, 0x01, 0x02, 0x00, 0x21, 0x01, 0x02, 0x04, 0x21, 0x01, 0x02, 0x08, 0x21, 0x01, 0x02, 0x0c, 0x21, 0x01, 0x02, 0x10, 0x21, 0x01, 0x02, + 0x58, 0x03, 0x02, 0x02, 0x5c, 0x03, 0x02, 0x02, 0x60, 0x03, 0x02, 0x02, 0x64, 0x03, 0x02, 0x02, 0xc0, 0x1d, 0x03, 0x03, 0xc8, 0x1d, 0x03, 0x03, 0xd0, 0x1d, 0x03, 0x03, 0x28, 0x01, 0x04, 0x03, + 0x30, 0x01, 0x04, 0x03, 0xc0, 0x1a, 0x05, 0x04, 0x00, 0x3e, 0x06, 0x05, 0x20, 0x17, 0x07, 0x05, 0x40, 0x3a, 0x08, 0x06, 0x00, 0x2e, 0x0e, 0x09, 0xb0, 0x33, 0x00, 0x03, 0xb8, 0x33, 0x00, 0x03, + 0xc0, 0x33, 0x00, 0x03, 0x14, 0x21, 0x01, 0x02, 0x18, 0x21, 0x01, 0x02, 0x1c, 0x21, 0x01, 0x02, 0x20, 0x21, 0x01, 0x02, 0x24, 0x21, 0x01, 0x02, 0x28, 0x21, 0x01, 0x02, 0x68, 0x03, 0x02, 0x02, + 0x6c, 0x03, 0x02, 0x02, 0x70, 0x03, 0x02, 0x02, 0x74, 0x03, 0x02, 0x02, 0x78, 0x03, 0x02, 0x02, 0xd8, 0x1d, 0x03, 0x03, 0xe0, 0x1d, 0x03, 0x03, 0xe8, 0x1d, 0x03, 0x03, 0x38, 0x01, 0x04, 0x03, + 0x40, 0x01, 0x04, 0x03, 0xd0, 0x1a, 0x05, 0x04, 0x20, 0x3e, 0x06, 0x05, 0x40, 0x17, 0x07, 0x05, 0x80, 0x3a, 0x08, 0x06, 0x00, 0x0a, 0x0f, 0x09, 0xc8, 0x33, 0x00, 0x03, 0xd0, 0x33, 0x00, 0x03, + 0xd8, 0x33, 0x00, 0x03, 0x2c, 0x21, 0x01, 0x02, 0x30, 0x21, 0x01, 0x02, 0x34, 0x21, 0x01, 0x02, 0x38, 0x21, 0x01, 0x02, 0x3c, 0x21, 0x01, 0x02, 0x40, 0x21, 0x01, 0x02, 0x7c, 0x03, 0x02, 0x02, + 0x80, 0x03, 0x02, 0x02, 0x84, 0x03, 0x02, 0x02, 0x88, 0x03, 0x02, 0x02, 0x8c, 0x03, 0x02, 0x02, 0xf0, 0x1d, 0x03, 0x03, 0xf8, 0x1d, 0x03, 0x03, 0x00, 0x1e, 0x03, 0x03, 0x48, 0x01, 0x04, 0x03, + 0x50, 0x01, 0x04, 0x03, 0xe0, 0x1a, 0x05, 0x04, 0x40, 0x3e, 0x06, 0x05, 0x60, 0x17, 0x07, 0x05, 0xc0, 0x13, 0x09, 0x06, 0x00, 0x0c, 0x0f, 0x09, 0xe0, 0x33, 0x00, 0x03, 0xe8, 0x33, 0x00, 0x03, + 0xf0, 0x33, 0x00, 0x03, 0x44, 0x21, 0x01, 0x02, 0x48, 0x21, 0x01, 0x02, 0x4c, 0x21, 0x01, 0x02, 0x50, 0x21, 0x01, 0x02, 0x54, 0x21, 0x01, 0x02, 0x58, 0x21, 0x01, 0x02, 0x90, 0x03, 0x02, 0x02, + 0x94, 0x03, 0x02, 0x02, 0x98, 0x03, 0x02, 0x02, 0x9c, 0x03, 0x02, 0x02, 0xa0, 0x03, 0x02, 0x02, 0x08, 0x1e, 0x03, 0x03, 0x10, 0x1e, 0x03, 0x03, 0x18, 0x1e, 0x03, 0x03, 0x58, 0x01, 0x04, 0x03, + 0x60, 0x01, 0x04, 0x03, 0xf0, 0x1a, 0x05, 0x04, 0x60, 0x3e, 0x06, 0x05, 0x80, 0x17, 0x07, 0x05, 0x00, 0x14, 0x09, 0x06, 0x00, 0x0e, 0x0f, 0x09, 0xf8, 0x33, 0x00, 0x03, 0x00, 0x34, 0x00, 0x03, + 0x08, 0x34, 0x00, 0x03, 0x5c, 0x21, 0x01, 0x02, 0x60, 0x21, 0x01, 0x02, 0x64, 0x21, 0x01, 0x02, 0x68, 0x21, 0x01, 0x02, 0x6c, 0x21, 0x01, 0x02, 0x70, 0x21, 0x01, 0x02, 0xa4, 0x03, 0x02, 0x02, + 0xa8, 0x03, 0x02, 0x02, 0xac, 0x03, 0x02, 0x02, 0xb0, 0x03, 0x02, 0x02, 0xb4, 0x03, 0x02, 0x02, 0x20, 0x1e, 0x03, 0x03, 0x28, 0x1e, 0x03, 0x03, 0x30, 0x1e, 0x03, 0x03, 0x68, 0x01, 0x04, 0x03, + 0x70, 0x01, 0x04, 0x03, 0x00, 0x1b, 0x05, 0x04, 0x80, 0x3e, 0x06, 0x05, 0xa0, 0x17, 0x07, 0x05, 0x40, 0x14, 0x09, 0x06, 0x00, 0x24, 0x10, 0x0a, 0x10, 0x34, 0x00, 0x03, 0x18, 0x34, 0x00, 0x03, + 0x20, 0x34, 0x00, 0x03, 0x74, 0x21, 0x01, 0x02, 0x78, 0x21, 0x01, 0x02, 0x7c, 0x21, 0x01, 0x02, 0x80, 0x21, 0x01, 0x02, 0x84, 0x21, 0x01, 0x02, 0x88, 0x21, 0x01, 0x02, 0xb8, 0x03, 0x02, 0x02, + 0xbc, 0x03, 0x02, 0x02, 0xc0, 0x03, 0x02, 0x02, 0xc4, 0x03, 0x02, 0x02, 0xc8, 0x03, 0x02, 0x02, 0x38, 0x1e, 0x03, 0x03, 0x40, 0x1e, 0x03, 0x03, 0x48, 0x1e, 0x03, 0x03, 0x78, 0x01, 0x04, 0x03, + 0x80, 0x01, 0x04, 0x03, 0x10, 0x1b, 0x05, 0x04, 0xa0, 0x3e, 0x06, 0x05, 0xc0, 0x17, 0x07, 0x05, 0x80, 0x14, 0x09, 0x06, 0x00, 0x28, 0x10, 0x0a, 0x28, 0x34, 0x00, 0x03, 0x30, 0x34, 0x00, 0x03, + 0x38, 0x34, 0x00, 0x03, 0x8c, 0x21, 0x01, 0x02, 0x90, 0x21, 0x01, 0x02, 0x94, 0x21, 0x01, 0x02, 0x98, 0x21, 0x01, 0x02, 0x9c, 0x21, 0x01, 0x02, 0xa0, 0x21, 0x01, 0x02, 0xcc, 0x03, 0x02, 0x02, + 0xd0, 0x03, 0x02, 0x02, 0xd4, 0x03, 0x02, 0x02, 0xd8, 0x03, 0x02, 0x02, 0xdc, 0x03, 0x02, 0x02, 0x50, 0x1e, 0x03, 0x03, 0x58, 0x1e, 0x03, 0x03, 0x60, 0x1e, 0x03, 0x03, 0x88, 0x01, 0x04, 0x03, + 0x90, 0x01, 0x04, 0x03, 0x20, 0x1b, 0x05, 0x04, 0xc0, 0x3e, 0x06, 0x05, 0xe0, 0x17, 0x07, 0x05, 0xc0, 0x14, 0x09, 0x06, 0x00, 0x2c, 0x10, 0x0a, 0x40, 0x34, 0x00, 0x03, 0x48, 0x34, 0x00, 0x03, + 0x50, 0x34, 0x00, 0x03, 0xa4, 0x21, 0x01, 0x02, 0xa8, 0x21, 0x01, 0x02, 0xac, 0x21, 0x01, 0x02, 0xb0, 0x21, 0x01, 0x02, 0xb4, 0x21, 0x01, 0x02, 0xb8, 0x21, 0x01, 0x02, 0xe0, 0x03, 0x02, 0x02, + 0xe4, 0x03, 0x02, 0x02, 0xe8, 0x03, 0x02, 0x02, 0xec, 0x03, 0x02, 0x02, 0xf0, 0x03, 0x02, 0x02, 0x68, 0x1e, 0x03, 0x03, 0x70, 0x1e, 0x03, 0x03, 0x78, 0x1e, 0x03, 0x03, 0x98, 0x01, 0x04, 0x03, + 0xa0, 0x01, 0x04, 0x03, 0x30, 0x1b, 0x05, 0x04, 0xe0, 0x3e, 0x06, 0x05, 0x00, 0x18, 0x07, 0x05, 0x00, 0x15, 0x09, 0x06, 0x00, 0x04, 0x11, 0x0a, 0x58, 0x34, 0x00, 0x03, 0x60, 0x34, 0x00, 0x03, + 0x68, 0x34, 0x00, 0x03, 0xbc, 0x21, 0x01, 0x02, 0xc0, 0x21, 0x01, 0x02, 0xc4, 0x21, 0x01, 0x02, 0xc8, 0x21, 0x01, 0x02, 0xcc, 0x21, 0x01, 0x02, 0xd0, 0x21, 0x01, 0x02, 0xf4, 0x03, 0x02, 0x02, + 0xf8, 0x03, 0x02, 0x02, 0xfc, 0x03, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x80, 0x1e, 0x03, 0x03, 0x88, 0x1e, 0x03, 0x03, 0x90, 0x1e, 0x03, 0x03, 0xa8, 0x01, 0x04, 0x03, + 0xb0, 0x01, 0x04, 0x03, 0x40, 0x1b, 0x05, 0x04, 0x00, 0x3f, 0x06, 0x05, 0x20, 0x18, 0x07, 0x05, 0x40, 0x15, 0x09, 0x06, 0x00, 0x08, 0x11, 0x0a, 0x70, 0x34, 0x00, 0x03, 0x78, 0x34, 0x00, 0x03, + 0x80, 0x34, 0x00, 0x03, 0xd4, 0x21, 0x01, 0x02, 0xd8, 0x21, 0x01, 0x02, 0xdc, 0x21, 0x01, 0x02, 0xe0, 0x21, 0x01, 0x02, 0xe4, 0x21, 0x01, 0x02, 0xe8, 0x21, 0x01, 0x02, 0x08, 0x04, 0x02, 0x02, + 0x0c, 0x04, 0x02, 0x02, 0x10, 0x04, 0x02, 0x02, 0x14, 0x04, 0x02, 0x02, 0x18, 0x04, 0x02, 0x02, 0x98, 0x1e, 0x03, 0x03, 0xa0, 0x1e, 0x03, 0x03, 0xa8, 0x1e, 0x03, 0x03, 0xb8, 0x01, 0x04, 0x03, + 0xc0, 0x01, 0x04, 0x03, 0x50, 0x1b, 0x05, 0x04, 0x20, 0x3f, 0x06, 0x05, 0x40, 0x18, 0x07, 0x05, 0x80, 0x15, 0x09, 0x06, 0x00, 0x28, 0x12, 0x0b, 0x88, 0x34, 0x00, 0x03, 0x90, 0x34, 0x00, 0x03, + 0x98, 0x34, 0x00, 0x03, 0xec, 0x21, 0x01, 0x02, 0xf0, 0x21, 0x01, 0x02, 0xf4, 0x21, 0x01, 0x02, 0xf8, 0x21, 0x01, 0x02, 0xfc, 0x21, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x1c, 0x04, 0x02, 0x02, + 0x20, 0x04, 0x02, 0x02, 0x24, 0x04, 0x02, 0x02, 0x28, 0x04, 0x02, 0x02, 0x2c, 0x04, 0x02, 0x02, 0xb0, 0x1e, 0x03, 0x03, 0xb8, 0x1e, 0x03, 0x03, 0xc0, 0x1e, 0x03, 0x03, 0xc8, 0x01, 0x04, 0x03, + 0xd0, 0x01, 0x04, 0x03, 0x60, 0x1b, 0x05, 0x04, 0x40, 0x3f, 0x06, 0x05, 0x60, 0x18, 0x07, 0x05, 0xc0, 0x15, 0x09, 0x06, 0x00, 0x08, 0x13, 0x0b, 0xa0, 0x34, 0x00, 0x03, 0xa8, 0x34, 0x00, 0x03, + 0xb0, 0x34, 0x00, 0x03, 0x04, 0x22, 0x01, 0x02, 0x08, 0x22, 0x01, 0x02, 0x0c, 0x22, 0x01, 0x02, 0x10, 0x22, 0x01, 0x02, 0x14, 0x22, 0x01, 0x02, 0x18, 0x22, 0x01, 0x02, 0x30, 0x04, 0x02, 0x02, + 0x34, 0x04, 0x02, 0x02, 0x38, 0x04, 0x02, 0x02, 0x3c, 0x04, 0x02, 0x02, 0x40, 0x04, 0x02, 0x02, 0xc8, 0x1e, 0x03, 0x03, 0xd0, 0x1e, 0x03, 0x03, 0xd8, 0x1e, 0x03, 0x03, 0xd8, 0x01, 0x04, 0x03, + 0xe0, 0x01, 0x04, 0x03, 0x70, 0x1b, 0x05, 0x04, 0x60, 0x3f, 0x06, 0x05, 0x80, 0x18, 0x07, 0x05, 0x00, 0x16, 0x09, 0x06, 0x00, 0x00, 0x15, 0x0c, 0xb8, 0x34, 0x00, 0x03, 0xc0, 0x34, 0x00, 0x03, + 0xc8, 0x34, 0x00, 0x03, 0x1c, 0x22, 0x01, 0x02, 0x20, 0x22, 0x01, 0x02, 0x24, 0x22, 0x01, 0x02, 0x28, 0x22, 0x01, 0x02, 0x2c, 0x22, 0x01, 0x02, 0x30, 0x22, 0x01, 0x02, 0x44, 0x04, 0x02, 0x02, + 0x48, 0x04, 0x02, 0x02, 0x4c, 0x04, 0x02, 0x02, 0x50, 0x04, 0x02, 0x02, 0x54, 0x04, 0x02, 0x02, 0xe0, 0x1e, 0x03, 0x03, 0xe8, 0x1e, 0x03, 0x03, 0xf0, 0x1e, 0x03, 0x03, 0xe8, 0x01, 0x04, 0x03, + 0xf0, 0x01, 0x04, 0x03, 0x80, 0x1b, 0x05, 0x04, 0x80, 0x3f, 0x06, 0x05, 0xa0, 0x18, 0x07, 0x05, 0x40, 0x16, 0x09, 0x06, 0xd0, 0x34, 0x00, 0x03, 0xd8, 0x34, 0x00, 0x03, 0xe0, 0x34, 0x00, 0x03, + 0xe8, 0x34, 0x00, 0x03, 0x34, 0x22, 0x01, 0x02, 0x38, 0x22, 0x01, 0x02, 0x3c, 0x22, 0x01, 0x02, 0x40, 0x22, 0x01, 0x02, 0x44, 0x22, 0x01, 0x02, 0x48, 0x22, 0x01, 0x02, 0x58, 0x04, 0x02, 0x02, + 0x5c, 0x04, 0x02, 0x02, 0x60, 0x04, 0x02, 0x02, 0x64, 0x04, 0x02, 0x02, 0x68, 0x04, 0x02, 0x02, 0xf8, 0x1e, 0x03, 0x03, 0x00, 0x1f, 0x03, 0x03, 0x08, 0x1f, 0x03, 0x03, 0xf8, 0x01, 0x04, 0x03, + 0x00, 0x02, 0x04, 0x03, 0x90, 0x1b, 0x05, 0x04, 0xa0, 0x3f, 0x06, 0x05, 0xc0, 0x18, 0x07, 0x05, 0x80, 0x16, 0x09, 0x06, 0xf0, 0x34, 0x00, 0x03, 0xf8, 0x34, 0x00, 0x03, 0x00, 0x35, 0x00, 0x03, + 0x08, 0x35, 0x00, 0x03, 0x4c, 0x22, 0x01, 0x02, 0x50, 0x22, 0x01, 0x02, 0x54, 0x22, 0x01, 0x02, 0x58, 0x22, 0x01, 0x02, 0x5c, 0x22, 0x01, 0x02, 0x60, 0x22, 0x01, 0x02, 0x6c, 0x04, 0x02, 0x02, + 0x70, 0x04, 0x02, 0x02, 0x74, 0x04, 0x02, 0x02, 0x78, 0x04, 0x02, 0x02, 0x7c, 0x04, 0x02, 0x02, 0x10, 0x1f, 0x03, 0x03, 0x18, 0x1f, 0x03, 0x03, 0x20, 0x1f, 0x03, 0x03, 0x08, 0x02, 0x04, 0x03, + 0x10, 0x02, 0x04, 0x03, 0xa0, 0x1b, 0x05, 0x04, 0xc0, 0x3f, 0x06, 0x05, 0xe0, 0x18, 0x07, 0x05, 0xc0, 0x16, 0x09, 0x06, 0x10, 0x35, 0x00, 0x03, 0x18, 0x35, 0x00, 0x03, 0x20, 0x35, 0x00, 0x03, + 0x28, 0x35, 0x00, 0x03, 0x64, 0x22, 0x01, 0x02, 0x68, 0x22, 0x01, 0x02, 0x6c, 0x22, 0x01, 0x02, 0x70, 0x22, 0x01, 0x02, 0x74, 0x22, 0x01, 0x02, 0x78, 0x22, 0x01, 0x02, 0x80, 0x04, 0x02, 0x02, + 0x84, 0x04, 0x02, 0x02, 0x88, 0x04, 0x02, 0x02, 0x8c, 0x04, 0x02, 0x02, 0x90, 0x04, 0x02, 0x02, 0x28, 0x1f, 0x03, 0x03, 0x30, 0x1f, 0x03, 0x03, 0x38, 0x1f, 0x03, 0x03, 0x18, 0x02, 0x04, 0x03, + 0x20, 0x02, 0x04, 0x03, 0xb0, 0x1b, 0x05, 0x04, 0xe0, 0x3f, 0x06, 0x05, 0x00, 0x19, 0x07, 0x05, 0x00, 0x17, 0x09, 0x06, 0x30, 0x35, 0x00, 0x03, 0x38, 0x35, 0x00, 0x03, 0x40, 0x35, 0x00, 0x03, + 0x48, 0x35, 0x00, 0x03, 0x7c, 0x22, 0x01, 0x02, 0x80, 0x22, 0x01, 0x02, 0x84, 0x22, 0x01, 0x02, 0x88, 0x22, 0x01, 0x02, 0x8c, 0x22, 0x01, 0x02, 0x90, 0x22, 0x01, 0x02, 0x94, 0x04, 0x02, 0x02, + 0x98, 0x04, 0x02, 0x02, 0x9c, 0x04, 0x02, 0x02, 0xa0, 0x04, 0x02, 0x02, 0xa4, 0x04, 0x02, 0x02, 0x40, 0x1f, 0x03, 0x03, 0x48, 0x1f, 0x03, 0x03, 0x50, 0x1f, 0x03, 0x03, 0x28, 0x02, 0x04, 0x03, + 0x30, 0x02, 0x04, 0x03, 0xc0, 0x1b, 0x05, 0x04, 0x00, 0x00, 0x06, 0x04, 0x20, 0x19, 0x07, 0x05, 0x40, 0x17, 0x09, 0x06, 0x50, 0x35, 0x00, 0x03, 0x58, 0x35, 0x00, 0x03, 0x60, 0x35, 0x00, 0x03, + 0x68, 0x35, 0x00, 0x03, 0x94, 0x22, 0x01, 0x02, 0x98, 0x22, 0x01, 0x02, 0x9c, 0x22, 0x01, 0x02, 0xa0, 0x22, 0x01, 0x02, 0xa4, 0x22, 0x01, 0x02, 0xa8, 0x22, 0x01, 0x02, 0xa8, 0x04, 0x02, 0x02, + 0xac, 0x04, 0x02, 0x02, 0xb0, 0x04, 0x02, 0x02, 0xb4, 0x04, 0x02, 0x02, 0xb8, 0x04, 0x02, 0x02, 0x58, 0x1f, 0x03, 0x03, 0x60, 0x1f, 0x03, 0x03, 0x68, 0x1f, 0x03, 0x03, 0x38, 0x02, 0x04, 0x03, + 0x40, 0x02, 0x04, 0x03, 0xd0, 0x1b, 0x05, 0x04, 0x10, 0x00, 0x06, 0x04, 0x40, 0x19, 0x07, 0x05, 0x80, 0x17, 0x09, 0x06, 0x70, 0x35, 0x00, 0x03, 0x78, 0x35, 0x00, 0x03, 0x80, 0x35, 0x00, 0x03, + 0x88, 0x35, 0x00, 0x03, 0xac, 0x22, 0x01, 0x02, 0xb0, 0x22, 0x01, 0x02, 0xb4, 0x22, 0x01, 0x02, 0xb8, 0x22, 0x01, 0x02, 0xbc, 0x22, 0x01, 0x02, 0xc0, 0x22, 0x01, 0x02, 0xbc, 0x04, 0x02, 0x02, + 0xc0, 0x04, 0x02, 0x02, 0xc4, 0x04, 0x02, 0x02, 0xc8, 0x04, 0x02, 0x02, 0xcc, 0x04, 0x02, 0x02, 0x70, 0x1f, 0x03, 0x03, 0x78, 0x1f, 0x03, 0x03, 0x80, 0x1f, 0x03, 0x03, 0x48, 0x02, 0x04, 0x03, + 0x50, 0x02, 0x04, 0x03, 0xe0, 0x1b, 0x05, 0x04, 0x20, 0x00, 0x06, 0x04, 0x60, 0x19, 0x07, 0x05, 0xc0, 0x17, 0x09, 0x06, 0x90, 0x35, 0x00, 0x03, 0x98, 0x35, 0x00, 0x03, 0xa0, 0x35, 0x00, 0x03, + 0xa8, 0x35, 0x00, 0x03, 0xc4, 0x22, 0x01, 0x02, 0xc8, 0x22, 0x01, 0x02, 0xcc, 0x22, 0x01, 0x02, 0xd0, 0x22, 0x01, 0x02, 0xd4, 0x22, 0x01, 0x02, 0xd8, 0x22, 0x01, 0x02, 0xd0, 0x04, 0x02, 0x02, + 0xd4, 0x04, 0x02, 0x02, 0xd8, 0x04, 0x02, 0x02, 0xdc, 0x04, 0x02, 0x02, 0xe0, 0x04, 0x02, 0x02, 0x88, 0x1f, 0x03, 0x03, 0x90, 0x1f, 0x03, 0x03, 0x98, 0x1f, 0x03, 0x03, 0x58, 0x02, 0x04, 0x03, + 0x60, 0x02, 0x04, 0x03, 0xf0, 0x1b, 0x05, 0x04, 0x30, 0x00, 0x06, 0x04, 0x80, 0x19, 0x07, 0x05, 0x00, 0x18, 0x09, 0x06, 0xb0, 0x35, 0x00, 0x03, 0xb8, 0x35, 0x00, 0x03, 0xc0, 0x35, 0x00, 0x03, + 0xc8, 0x35, 0x00, 0x03, 0xdc, 0x22, 0x01, 0x02, 0xe0, 0x22, 0x01, 0x02, 0xe4, 0x22, 0x01, 0x02, 0xe8, 0x22, 0x01, 0x02, 0xec, 0x22, 0x01, 0x02, 0xf0, 0x22, 0x01, 0x02, 0xe4, 0x04, 0x02, 0x02, + 0xe8, 0x04, 0x02, 0x02, 0xec, 0x04, 0x02, 0x02, 0xf0, 0x04, 0x02, 0x02, 0xf4, 0x04, 0x02, 0x02, 0xa0, 0x1f, 0x03, 0x03, 0xa8, 0x1f, 0x03, 0x03, 0xb0, 0x1f, 0x03, 0x03, 0x68, 0x02, 0x04, 0x03, + 0x70, 0x02, 0x04, 0x03, 0x00, 0x1c, 0x05, 0x04, 0x40, 0x00, 0x06, 0x04, 0xa0, 0x19, 0x07, 0x05, 0x40, 0x18, 0x09, 0x06, 0xd0, 0x35, 0x00, 0x03, 0xd8, 0x35, 0x00, 0x03, 0xe0, 0x35, 0x00, 0x03, + 0xe8, 0x35, 0x00, 0x03, 0xf4, 0x22, 0x01, 0x02, 0xf8, 0x22, 0x01, 0x02, 0xfc, 0x22, 0x01, 0x02, 0x00, 0x23, 0x01, 0x02, 0x04, 0x23, 0x01, 0x02, 0x08, 0x23, 0x01, 0x02, 0xf8, 0x04, 0x02, 0x02, + 0xfc, 0x04, 0x02, 0x02, 0x00, 0x05, 0x02, 0x02, 0x04, 0x05, 0x02, 0x02, 0x08, 0x05, 0x02, 0x02, 0xb8, 0x1f, 0x03, 0x03, 0xc0, 0x1f, 0x03, 0x03, 0xc8, 0x1f, 0x03, 0x03, 0x78, 0x02, 0x04, 0x03, + 0x80, 0x02, 0x04, 0x03, 0x10, 0x1c, 0x05, 0x04, 0x50, 0x00, 0x06, 0x04, 0xc0, 0x19, 0x07, 0x05, 0x80, 0x18, 0x09, 0x06, 0xf0, 0x35, 0x00, 0x03, 0xf8, 0x35, 0x00, 0x03, 0x00, 0x36, 0x00, 0x03, + 0x08, 0x36, 0x00, 0x03, 0x0c, 0x23, 0x01, 0x02, 0x10, 0x23, 0x01, 0x02, 0x14, 0x23, 0x01, 0x02, 0x18, 0x23, 0x01, 0x02, 0x1c, 0x23, 0x01, 0x02, 0x20, 0x23, 0x01, 0x02, 0x0c, 0x05, 0x02, 0x02, + 0x10, 0x05, 0x02, 0x02, 0x14, 0x05, 0x02, 0x02, 0x18, 0x05, 0x02, 0x02, 0x1c, 0x05, 0x02, 0x02, 0xd0, 0x1f, 0x03, 0x03, 0xd8, 0x1f, 0x03, 0x03, 0xe0, 0x1f, 0x03, 0x03, 0x88, 0x02, 0x04, 0x03, + 0x90, 0x02, 0x04, 0x03, 0x20, 0x1c, 0x05, 0x04, 0x60, 0x00, 0x06, 0x04, 0xe0, 0x19, 0x07, 0x05, 0xc0, 0x18, 0x09, 0x06, 0x10, 0x36, 0x00, 0x03, 0x18, 0x36, 0x00, 0x03, 0x20, 0x36, 0x00, 0x03, + 0x28, 0x36, 0x00, 0x03, 0x24, 0x23, 0x01, 0x02, 0x28, 0x23, 0x01, 0x02, 0x2c, 0x23, 0x01, 0x02, 0x30, 0x23, 0x01, 0x02, 0x34, 0x23, 0x01, 0x02, 0x38, 0x23, 0x01, 0x02, 0x20, 0x05, 0x02, 0x02, + 0x24, 0x05, 0x02, 0x02, 0x28, 0x05, 0x02, 0x02, 0x2c, 0x05, 0x02, 0x02, 0x30, 0x05, 0x02, 0x02, 0xe8, 0x1f, 0x03, 0x03, 0xf0, 0x1f, 0x03, 0x03, 0xf8, 0x1f, 0x03, 0x03, 0x98, 0x02, 0x04, 0x03, + 0xa0, 0x02, 0x04, 0x03, 0x30, 0x1c, 0x05, 0x04, 0x70, 0x00, 0x06, 0x04, 0x00, 0x1a, 0x07, 0x05, 0x00, 0x19, 0x09, 0x06, 0x30, 0x36, 0x00, 0x03, 0x38, 0x36, 0x00, 0x03, 0x40, 0x36, 0x00, 0x03, + 0x48, 0x36, 0x00, 0x03, 0x3c, 0x23, 0x01, 0x02, 0x40, 0x23, 0x01, 0x02, 0x44, 0x23, 0x01, 0x02, 0x48, 0x23, 0x01, 0x02, 0x4c, 0x23, 0x01, 0x02, 0x50, 0x23, 0x01, 0x02, 0x34, 0x05, 0x02, 0x02, + 0x38, 0x05, 0x02, 0x02, 0x3c, 0x05, 0x02, 0x02, 0x40, 0x05, 0x02, 0x02, 0x44, 0x05, 0x02, 0x02, 0x00, 0x20, 0x03, 0x03, 0x08, 0x20, 0x03, 0x03, 0x10, 0x20, 0x03, 0x03, 0xa8, 0x02, 0x04, 0x03, + 0xb0, 0x02, 0x04, 0x03, 0x40, 0x1c, 0x05, 0x04, 0x80, 0x00, 0x06, 0x04, 0x20, 0x1a, 0x07, 0x05, 0x40, 0x19, 0x09, 0x06, 0x50, 0x36, 0x00, 0x03, 0x58, 0x36, 0x00, 0x03, 0x60, 0x36, 0x00, 0x03, + 0x68, 0x36, 0x00, 0x03, 0x54, 0x23, 0x01, 0x02, 0x58, 0x23, 0x01, 0x02, 0x5c, 0x23, 0x01, 0x02, 0x60, 0x23, 0x01, 0x02, 0x64, 0x23, 0x01, 0x02, 0x68, 0x23, 0x01, 0x02, 0x48, 0x05, 0x02, 0x02, + 0x4c, 0x05, 0x02, 0x02, 0x50, 0x05, 0x02, 0x02, 0x54, 0x05, 0x02, 0x02, 0x58, 0x05, 0x02, 0x02, 0x18, 0x20, 0x03, 0x03, 0x20, 0x20, 0x03, 0x03, 0x28, 0x20, 0x03, 0x03, 0xb8, 0x02, 0x04, 0x03, + 0xc0, 0x02, 0x04, 0x03, 0x50, 0x1c, 0x05, 0x04, 0x90, 0x00, 0x06, 0x04, 0x40, 0x1a, 0x07, 0x05, 0x80, 0x19, 0x09, 0x06, 0x70, 0x36, 0x00, 0x03, 0x78, 0x36, 0x00, 0x03, 0x80, 0x36, 0x00, 0x03, + 0x88, 0x36, 0x00, 0x03, 0x6c, 0x23, 0x01, 0x02, 0x70, 0x23, 0x01, 0x02, 0x74, 0x23, 0x01, 0x02, 0x78, 0x23, 0x01, 0x02, 0x7c, 0x23, 0x01, 0x02, 0x80, 0x23, 0x01, 0x02, 0x5c, 0x05, 0x02, 0x02, + 0x60, 0x05, 0x02, 0x02, 0x64, 0x05, 0x02, 0x02, 0x68, 0x05, 0x02, 0x02, 0x6c, 0x05, 0x02, 0x02, 0x30, 0x20, 0x03, 0x03, 0x38, 0x20, 0x03, 0x03, 0x40, 0x20, 0x03, 0x03, 0xc8, 0x02, 0x04, 0x03, + 0xd0, 0x02, 0x04, 0x03, 0x60, 0x1c, 0x05, 0x04, 0xa0, 0x00, 0x06, 0x04, 0x60, 0x1a, 0x07, 0x05, 0xc0, 0x19, 0x09, 0x06, 0x90, 0x36, 0x00, 0x03, 0x98, 0x36, 0x00, 0x03, 0xa0, 0x36, 0x00, 0x03, + 0xa8, 0x36, 0x00, 0x03, 0x84, 0x23, 0x01, 0x02, 0x88, 0x23, 0x01, 0x02, 0x8c, 0x23, 0x01, 0x02, 0x90, 0x23, 0x01, 0x02, 0x94, 0x23, 0x01, 0x02, 0x98, 0x23, 0x01, 0x02, 0x70, 0x05, 0x02, 0x02, + 0x74, 0x05, 0x02, 0x02, 0x78, 0x05, 0x02, 0x02, 0x7c, 0x05, 0x02, 0x02, 0x80, 0x05, 0x02, 0x02, 0x48, 0x20, 0x03, 0x03, 0x50, 0x20, 0x03, 0x03, 0xd8, 0x02, 0x04, 0x03, 0xe0, 0x02, 0x04, 0x03, + 0xe8, 0x02, 0x04, 0x03, 0x70, 0x1c, 0x05, 0x04, 0xb0, 0x00, 0x06, 0x04, 0x80, 0x1a, 0x07, 0x05, 0x00, 0x1a, 0x09, 0x06, 0xb0, 0x36, 0x00, 0x03, 0xb8, 0x36, 0x00, 0x03, 0xc0, 0x36, 0x00, 0x03, + 0xc8, 0x36, 0x00, 0x03, 0x9c, 0x23, 0x01, 0x02, 0xa0, 0x23, 0x01, 0x02, 0xa4, 0x23, 0x01, 0x02, 0xa8, 0x23, 0x01, 0x02, 0xac, 0x23, 0x01, 0x02, 0xb0, 0x23, 0x01, 0x02, 0x84, 0x05, 0x02, 0x02, + 0x88, 0x05, 0x02, 0x02, 0x8c, 0x05, 0x02, 0x02, 0x90, 0x05, 0x02, 0x02, 0x58, 0x20, 0x03, 0x03, 0x60, 0x20, 0x03, 0x03, 0x68, 0x20, 0x03, 0x03, 0xf0, 0x02, 0x04, 0x03, 0xf8, 0x02, 0x04, 0x03, + 0x00, 0x03, 0x04, 0x03, 0x80, 0x1c, 0x05, 0x04, 0xc0, 0x00, 0x06, 0x04, 0xa0, 0x1a, 0x07, 0x05, 0x40, 0x1a, 0x09, 0x06, 0xd0, 0x36, 0x00, 0x03, 0xd8, 0x36, 0x00, 0x03, 0xe0, 0x36, 0x00, 0x03, + 0xe8, 0x36, 0x00, 0x03, 0xb4, 0x23, 0x01, 0x02, 0xb8, 0x23, 0x01, 0x02, 0xbc, 0x23, 0x01, 0x02, 0xc0, 0x23, 0x01, 0x02, 0xc4, 0x23, 0x01, 0x02, 0xc8, 0x23, 0x01, 0x02, 0x94, 0x05, 0x02, 0x02, + 0x98, 0x05, 0x02, 0x02, 0x9c, 0x05, 0x02, 0x02, 0xa0, 0x05, 0x02, 0x02, 0x70, 0x20, 0x03, 0x03, 0x78, 0x20, 0x03, 0x03, 0x80, 0x20, 0x03, 0x03, 0x08, 0x03, 0x04, 0x03, 0x10, 0x03, 0x04, 0x03, + 0x18, 0x03, 0x04, 0x03, 0x90, 0x1c, 0x05, 0x04, 0xd0, 0x00, 0x06, 0x04, 0xc0, 0x1a, 0x07, 0x05, 0x80, 0x1a, 0x09, 0x06, 0xf0, 0x36, 0x00, 0x03, 0xf8, 0x36, 0x00, 0x03, 0x00, 0x37, 0x00, 0x03, + 0x08, 0x37, 0x00, 0x03, 0xcc, 0x23, 0x01, 0x02, 0xd0, 0x23, 0x01, 0x02, 0xd4, 0x23, 0x01, 0x02, 0xd8, 0x23, 0x01, 0x02, 0xdc, 0x23, 0x01, 0x02, 0xe0, 0x23, 0x01, 0x02, 0xa4, 0x05, 0x02, 0x02, + 0xa8, 0x05, 0x02, 0x02, 0xac, 0x05, 0x02, 0x02, 0xb0, 0x05, 0x02, 0x02, 0x88, 0x20, 0x03, 0x03, 0x90, 0x20, 0x03, 0x03, 0x98, 0x20, 0x03, 0x03, 0x20, 0x03, 0x04, 0x03, 0x28, 0x03, 0x04, 0x03, + 0x30, 0x03, 0x04, 0x03, 0xa0, 0x1c, 0x05, 0x04, 0xe0, 0x00, 0x06, 0x04, 0xe0, 0x1a, 0x07, 0x05, 0xc0, 0x1a, 0x09, 0x06, 0x10, 0x37, 0x00, 0x03, 0x18, 0x37, 0x00, 0x03, 0x20, 0x37, 0x00, 0x03, + 0x28, 0x37, 0x00, 0x03, 0xe4, 0x23, 0x01, 0x02, 0xe8, 0x23, 0x01, 0x02, 0xec, 0x23, 0x01, 0x02, 0xf0, 0x23, 0x01, 0x02, 0xf4, 0x23, 0x01, 0x02, 0xf8, 0x23, 0x01, 0x02, 0xb4, 0x05, 0x02, 0x02, + 0xb8, 0x05, 0x02, 0x02, 0xbc, 0x05, 0x02, 0x02, 0xc0, 0x05, 0x02, 0x02, 0xa0, 0x20, 0x03, 0x03, 0xa8, 0x20, 0x03, 0x03, 0xb0, 0x20, 0x03, 0x03, 0x38, 0x03, 0x04, 0x03, 0x40, 0x03, 0x04, 0x03, + 0x48, 0x03, 0x04, 0x03, 0xb0, 0x1c, 0x05, 0x04, 0xf0, 0x00, 0x06, 0x04, 0x00, 0x1b, 0x07, 0x05, 0x00, 0x1b, 0x09, 0x06, 0x30, 0x37, 0x00, 0x03, 0x38, 0x37, 0x00, 0x03, 0x40, 0x37, 0x00, 0x03, + 0x48, 0x37, 0x00, 0x03, 0xfc, 0x23, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x04, 0x24, 0x01, 0x02, 0x08, 0x24, 0x01, 0x02, 0x0c, 0x24, 0x01, 0x02, 0x10, 0x24, 0x01, 0x02, 0xc4, 0x05, 0x02, 0x02, + 0xc8, 0x05, 0x02, 0x02, 0xcc, 0x05, 0x02, 0x02, 0xd0, 0x05, 0x02, 0x02, 0xb8, 0x20, 0x03, 0x03, 0xc0, 0x20, 0x03, 0x03, 0xc8, 0x20, 0x03, 0x03, 0x50, 0x03, 0x04, 0x03, 0x58, 0x03, 0x04, 0x03, + 0x60, 0x03, 0x04, 0x03, 0xc0, 0x1c, 0x05, 0x04, 0x00, 0x01, 0x06, 0x04, 0x20, 0x1b, 0x07, 0x05, 0x80, 0x36, 0x0a, 0x07, 0x50, 0x37, 0x00, 0x03, 0x58, 0x37, 0x00, 0x03, 0x60, 0x37, 0x00, 0x03, + 0x68, 0x37, 0x00, 0x03, 0x14, 0x24, 0x01, 0x02, 0x18, 0x24, 0x01, 0x02, 0x1c, 0x24, 0x01, 0x02, 0x20, 0x24, 0x01, 0x02, 0x24, 0x24, 0x01, 0x02, 0x28, 0x24, 0x01, 0x02, 0xd4, 0x05, 0x02, 0x02, + 0xd8, 0x05, 0x02, 0x02, 0xdc, 0x05, 0x02, 0x02, 0xe0, 0x05, 0x02, 0x02, 0xd0, 0x20, 0x03, 0x03, 0xd8, 0x20, 0x03, 0x03, 0xe0, 0x20, 0x03, 0x03, 0x68, 0x03, 0x04, 0x03, 0x70, 0x03, 0x04, 0x03, + 0x78, 0x03, 0x04, 0x03, 0xd0, 0x1c, 0x05, 0x04, 0x10, 0x01, 0x06, 0x04, 0x40, 0x1b, 0x07, 0x05, 0x00, 0x37, 0x0a, 0x07, 0x70, 0x37, 0x00, 0x03, 0x78, 0x37, 0x00, 0x03, 0x80, 0x37, 0x00, 0x03, + 0x88, 0x37, 0x00, 0x03, 0x2c, 0x24, 0x01, 0x02, 0x30, 0x24, 0x01, 0x02, 0x34, 0x24, 0x01, 0x02, 0x38, 0x24, 0x01, 0x02, 0x3c, 0x24, 0x01, 0x02, 0x40, 0x24, 0x01, 0x02, 0xe4, 0x05, 0x02, 0x02, + 0xe8, 0x05, 0x02, 0x02, 0xec, 0x05, 0x02, 0x02, 0xf0, 0x05, 0x02, 0x02, 0xe8, 0x20, 0x03, 0x03, 0xf0, 0x20, 0x03, 0x03, 0xf8, 0x20, 0x03, 0x03, 0x80, 0x03, 0x04, 0x03, 0x88, 0x03, 0x04, 0x03, + 0xe0, 0x1c, 0x05, 0x04, 0xf0, 0x1c, 0x05, 0x04, 0x20, 0x01, 0x06, 0x04, 0x60, 0x1b, 0x07, 0x05, 0x80, 0x37, 0x0a, 0x07, 0x90, 0x37, 0x00, 0x03, 0x98, 0x37, 0x00, 0x03, 0xa0, 0x37, 0x00, 0x03, + 0xa8, 0x37, 0x00, 0x03, 0x44, 0x24, 0x01, 0x02, 0x48, 0x24, 0x01, 0x02, 0x4c, 0x24, 0x01, 0x02, 0x50, 0x24, 0x01, 0x02, 0x54, 0x24, 0x01, 0x02, 0x58, 0x24, 0x01, 0x02, 0xf4, 0x05, 0x02, 0x02, + 0xf8, 0x05, 0x02, 0x02, 0xfc, 0x05, 0x02, 0x02, 0x00, 0x06, 0x02, 0x02, 0x00, 0x21, 0x03, 0x03, 0x08, 0x21, 0x03, 0x03, 0x10, 0x21, 0x03, 0x03, 0x90, 0x03, 0x04, 0x03, 0x98, 0x03, 0x04, 0x03, + 0x00, 0x1d, 0x05, 0x04, 0x10, 0x1d, 0x05, 0x04, 0x30, 0x01, 0x06, 0x04, 0x80, 0x1b, 0x07, 0x05, 0x00, 0x38, 0x0a, 0x07, 0xb0, 0x37, 0x00, 0x03, 0xb8, 0x37, 0x00, 0x03, 0xc0, 0x37, 0x00, 0x03, + 0xc8, 0x37, 0x00, 0x03, 0x5c, 0x24, 0x01, 0x02, 0x60, 0x24, 0x01, 0x02, 0x64, 0x24, 0x01, 0x02, 0x68, 0x24, 0x01, 0x02, 0x6c, 0x24, 0x01, 0x02, 0x70, 0x24, 0x01, 0x02, 0x04, 0x06, 0x02, 0x02, + 0x08, 0x06, 0x02, 0x02, 0x0c, 0x06, 0x02, 0x02, 0x10, 0x06, 0x02, 0x02, 0x18, 0x21, 0x03, 0x03, 0x20, 0x21, 0x03, 0x03, 0x28, 0x21, 0x03, 0x03, 0xa0, 0x03, 0x04, 0x03, 0xa8, 0x03, 0x04, 0x03, + 0x20, 0x1d, 0x05, 0x04, 0x30, 0x1d, 0x05, 0x04, 0x40, 0x01, 0x06, 0x04, 0xa0, 0x1b, 0x07, 0x05, 0x80, 0x38, 0x0a, 0x07, 0xd0, 0x37, 0x00, 0x03, 0xd8, 0x37, 0x00, 0x03, 0xe0, 0x37, 0x00, 0x03, + 0xe8, 0x37, 0x00, 0x03, 0x74, 0x24, 0x01, 0x02, 0x78, 0x24, 0x01, 0x02, 0x7c, 0x24, 0x01, 0x02, 0x80, 0x24, 0x01, 0x02, 0x84, 0x24, 0x01, 0x02, 0x88, 0x24, 0x01, 0x02, 0x14, 0x06, 0x02, 0x02, + 0x18, 0x06, 0x02, 0x02, 0x1c, 0x06, 0x02, 0x02, 0x20, 0x06, 0x02, 0x02, 0x30, 0x21, 0x03, 0x03, 0x38, 0x21, 0x03, 0x03, 0x40, 0x21, 0x03, 0x03, 0xb0, 0x03, 0x04, 0x03, 0xb8, 0x03, 0x04, 0x03, + 0x40, 0x1d, 0x05, 0x04, 0x50, 0x1d, 0x05, 0x04, 0x50, 0x01, 0x06, 0x04, 0xc0, 0x1b, 0x07, 0x05, 0x00, 0x39, 0x0a, 0x07, 0xf0, 0x37, 0x00, 0x03, 0xf8, 0x37, 0x00, 0x03, 0x00, 0x38, 0x00, 0x03, + 0x08, 0x38, 0x00, 0x03, 0x8c, 0x24, 0x01, 0x02, 0x90, 0x24, 0x01, 0x02, 0x94, 0x24, 0x01, 0x02, 0x98, 0x24, 0x01, 0x02, 0x9c, 0x24, 0x01, 0x02, 0xa0, 0x24, 0x01, 0x02, 0x24, 0x06, 0x02, 0x02, + 0x28, 0x06, 0x02, 0x02, 0x2c, 0x06, 0x02, 0x02, 0x30, 0x06, 0x02, 0x02, 0x48, 0x21, 0x03, 0x03, 0x50, 0x21, 0x03, 0x03, 0x58, 0x21, 0x03, 0x03, 0xc0, 0x03, 0x04, 0x03, 0xc8, 0x03, 0x04, 0x03, + 0x60, 0x1d, 0x05, 0x04, 0x70, 0x1d, 0x05, 0x04, 0x60, 0x01, 0x06, 0x04, 0xe0, 0x1b, 0x07, 0x05, 0x80, 0x39, 0x0a, 0x07, 0x10, 0x38, 0x00, 0x03, 0x18, 0x38, 0x00, 0x03, 0x20, 0x38, 0x00, 0x03, + 0x28, 0x38, 0x00, 0x03, 0xa4, 0x24, 0x01, 0x02, 0xa8, 0x24, 0x01, 0x02, 0xac, 0x24, 0x01, 0x02, 0xb0, 0x24, 0x01, 0x02, 0xb4, 0x24, 0x01, 0x02, 0xb8, 0x24, 0x01, 0x02, 0x34, 0x06, 0x02, 0x02, + 0x38, 0x06, 0x02, 0x02, 0x3c, 0x06, 0x02, 0x02, 0x40, 0x06, 0x02, 0x02, 0x60, 0x21, 0x03, 0x03, 0x68, 0x21, 0x03, 0x03, 0x70, 0x21, 0x03, 0x03, 0xd0, 0x03, 0x04, 0x03, 0xd8, 0x03, 0x04, 0x03, + 0x80, 0x1d, 0x05, 0x04, 0x90, 0x1d, 0x05, 0x04, 0x70, 0x01, 0x06, 0x04, 0x00, 0x1c, 0x07, 0x05, 0x00, 0x3a, 0x0a, 0x07, 0x30, 0x38, 0x00, 0x03, 0x38, 0x38, 0x00, 0x03, 0x40, 0x38, 0x00, 0x03, + 0x48, 0x38, 0x00, 0x03, 0xbc, 0x24, 0x01, 0x02, 0xc0, 0x24, 0x01, 0x02, 0xc4, 0x24, 0x01, 0x02, 0xc8, 0x24, 0x01, 0x02, 0xcc, 0x24, 0x01, 0x02, 0xd0, 0x24, 0x01, 0x02, 0x44, 0x06, 0x02, 0x02, + 0x48, 0x06, 0x02, 0x02, 0x4c, 0x06, 0x02, 0x02, 0x50, 0x06, 0x02, 0x02, 0x78, 0x21, 0x03, 0x03, 0x80, 0x21, 0x03, 0x03, 0x88, 0x21, 0x03, 0x03, 0xe0, 0x03, 0x04, 0x03, 0xe8, 0x03, 0x04, 0x03, + 0xa0, 0x1d, 0x05, 0x04, 0xb0, 0x1d, 0x05, 0x04, 0x80, 0x01, 0x06, 0x04, 0x20, 0x1c, 0x07, 0x05, 0x80, 0x3a, 0x0a, 0x07, 0x50, 0x38, 0x00, 0x03, 0x58, 0x38, 0x00, 0x03, 0x60, 0x38, 0x00, 0x03, + 0x68, 0x38, 0x00, 0x03, 0xd4, 0x24, 0x01, 0x02, 0xd8, 0x24, 0x01, 0x02, 0xdc, 0x24, 0x01, 0x02, 0xe0, 0x24, 0x01, 0x02, 0xe4, 0x24, 0x01, 0x02, 0xe8, 0x24, 0x01, 0x02, 0x54, 0x06, 0x02, 0x02, + 0x58, 0x06, 0x02, 0x02, 0x5c, 0x06, 0x02, 0x02, 0x60, 0x06, 0x02, 0x02, 0x90, 0x21, 0x03, 0x03, 0x98, 0x21, 0x03, 0x03, 0xa0, 0x21, 0x03, 0x03, 0xf0, 0x03, 0x04, 0x03, 0xf8, 0x03, 0x04, 0x03, + 0xc0, 0x1d, 0x05, 0x04, 0xd0, 0x1d, 0x05, 0x04, 0x90, 0x01, 0x06, 0x04, 0x40, 0x1c, 0x07, 0x05, 0x00, 0x3b, 0x0a, 0x07, 0x70, 0x38, 0x00, 0x03, 0x78, 0x38, 0x00, 0x03, 0x80, 0x38, 0x00, 0x03, + 0x88, 0x38, 0x00, 0x03, 0xec, 0x24, 0x01, 0x02, 0xf0, 0x24, 0x01, 0x02, 0xf4, 0x24, 0x01, 0x02, 0xf8, 0x24, 0x01, 0x02, 0xfc, 0x24, 0x01, 0x02, 0x00, 0x25, 0x01, 0x02, 0x64, 0x06, 0x02, 0x02, + 0x68, 0x06, 0x02, 0x02, 0x6c, 0x06, 0x02, 0x02, 0x70, 0x06, 0x02, 0x02, 0xa8, 0x21, 0x03, 0x03, 0xb0, 0x21, 0x03, 0x03, 0xb8, 0x21, 0x03, 0x03, 0x00, 0x04, 0x04, 0x03, 0x08, 0x04, 0x04, 0x03, + 0xe0, 0x1d, 0x05, 0x04, 0xf0, 0x1d, 0x05, 0x04, 0xa0, 0x01, 0x06, 0x04, 0x60, 0x1c, 0x07, 0x05, 0x80, 0x3b, 0x0a, 0x07, 0x90, 0x38, 0x00, 0x03, 0x98, 0x38, 0x00, 0x03, 0xa0, 0x38, 0x00, 0x03, + 0xa8, 0x38, 0x00, 0x03, 0x04, 0x25, 0x01, 0x02, 0x08, 0x25, 0x01, 0x02, 0x0c, 0x25, 0x01, 0x02, 0x10, 0x25, 0x01, 0x02, 0x14, 0x25, 0x01, 0x02, 0x18, 0x25, 0x01, 0x02, 0x74, 0x06, 0x02, 0x02, + 0x78, 0x06, 0x02, 0x02, 0x7c, 0x06, 0x02, 0x02, 0x80, 0x06, 0x02, 0x02, 0xc0, 0x21, 0x03, 0x03, 0xc8, 0x21, 0x03, 0x03, 0xd0, 0x21, 0x03, 0x03, 0x10, 0x04, 0x04, 0x03, 0x18, 0x04, 0x04, 0x03, + 0x00, 0x1e, 0x05, 0x04, 0x10, 0x1e, 0x05, 0x04, 0xb0, 0x01, 0x06, 0x04, 0x80, 0x1c, 0x07, 0x05, 0x00, 0x3c, 0x0a, 0x07, 0xb0, 0x38, 0x00, 0x03, 0xb8, 0x38, 0x00, 0x03, 0xc0, 0x38, 0x00, 0x03, + 0xc8, 0x38, 0x00, 0x03, 0x1c, 0x25, 0x01, 0x02, 0x20, 0x25, 0x01, 0x02, 0x24, 0x25, 0x01, 0x02, 0x28, 0x25, 0x01, 0x02, 0x2c, 0x25, 0x01, 0x02, 0x30, 0x25, 0x01, 0x02, 0x84, 0x06, 0x02, 0x02, + 0x88, 0x06, 0x02, 0x02, 0x8c, 0x06, 0x02, 0x02, 0x90, 0x06, 0x02, 0x02, 0xd8, 0x21, 0x03, 0x03, 0xe0, 0x21, 0x03, 0x03, 0xe8, 0x21, 0x03, 0x03, 0x20, 0x04, 0x04, 0x03, 0x28, 0x04, 0x04, 0x03, + 0x20, 0x1e, 0x05, 0x04, 0x30, 0x1e, 0x05, 0x04, 0xc0, 0x01, 0x06, 0x04, 0xa0, 0x1c, 0x07, 0x05, 0x80, 0x3c, 0x0a, 0x07, 0xd0, 0x38, 0x00, 0x03, 0xd8, 0x38, 0x00, 0x03, 0xe0, 0x38, 0x00, 0x03, + 0xe8, 0x38, 0x00, 0x03, 0x34, 0x25, 0x01, 0x02, 0x38, 0x25, 0x01, 0x02, 0x3c, 0x25, 0x01, 0x02, 0x40, 0x25, 0x01, 0x02, 0x44, 0x25, 0x01, 0x02, 0x48, 0x25, 0x01, 0x02, 0x94, 0x06, 0x02, 0x02, + 0x98, 0x06, 0x02, 0x02, 0x9c, 0x06, 0x02, 0x02, 0xa0, 0x06, 0x02, 0x02, 0xf0, 0x21, 0x03, 0x03, 0xf8, 0x21, 0x03, 0x03, 0x00, 0x22, 0x03, 0x03, 0x30, 0x04, 0x04, 0x03, 0x38, 0x04, 0x04, 0x03, + 0x40, 0x1e, 0x05, 0x04, 0x50, 0x1e, 0x05, 0x04, 0xd0, 0x01, 0x06, 0x04, 0xc0, 0x1c, 0x07, 0x05, 0x00, 0x3d, 0x0a, 0x07, 0xf0, 0x38, 0x00, 0x03, 0xf8, 0x38, 0x00, 0x03, 0x00, 0x39, 0x00, 0x03, + 0x08, 0x39, 0x00, 0x03, 0x4c, 0x25, 0x01, 0x02, 0x50, 0x25, 0x01, 0x02, 0x54, 0x25, 0x01, 0x02, 0x58, 0x25, 0x01, 0x02, 0x5c, 0x25, 0x01, 0x02, 0x60, 0x25, 0x01, 0x02, 0xa4, 0x06, 0x02, 0x02, + 0xa8, 0x06, 0x02, 0x02, 0xac, 0x06, 0x02, 0x02, 0xb0, 0x06, 0x02, 0x02, 0x08, 0x22, 0x03, 0x03, 0x10, 0x22, 0x03, 0x03, 0x18, 0x22, 0x03, 0x03, 0x40, 0x04, 0x04, 0x03, 0x48, 0x04, 0x04, 0x03, + 0x60, 0x1e, 0x05, 0x04, 0x70, 0x1e, 0x05, 0x04, 0xe0, 0x01, 0x06, 0x04, 0xe0, 0x1c, 0x07, 0x05, 0x80, 0x3d, 0x0a, 0x07, 0x10, 0x39, 0x00, 0x03, 0x18, 0x39, 0x00, 0x03, 0x20, 0x39, 0x00, 0x03, + 0x28, 0x39, 0x00, 0x03, 0x64, 0x25, 0x01, 0x02, 0x68, 0x25, 0x01, 0x02, 0x6c, 0x25, 0x01, 0x02, 0x70, 0x25, 0x01, 0x02, 0x74, 0x25, 0x01, 0x02, 0x78, 0x25, 0x01, 0x02, 0xb4, 0x06, 0x02, 0x02, + 0xb8, 0x06, 0x02, 0x02, 0xbc, 0x06, 0x02, 0x02, 0xc0, 0x06, 0x02, 0x02, 0x20, 0x22, 0x03, 0x03, 0x28, 0x22, 0x03, 0x03, 0x30, 0x22, 0x03, 0x03, 0x50, 0x04, 0x04, 0x03, 0x58, 0x04, 0x04, 0x03, + 0x80, 0x1e, 0x05, 0x04, 0x90, 0x1e, 0x05, 0x04, 0xf0, 0x01, 0x06, 0x04, 0xc0, 0x3a, 0x08, 0x06, 0x00, 0x3e, 0x0a, 0x07, 0x30, 0x39, 0x00, 0x03, 0x38, 0x39, 0x00, 0x03, 0x40, 0x39, 0x00, 0x03, + 0x48, 0x39, 0x00, 0x03, 0x7c, 0x25, 0x01, 0x02, 0x80, 0x25, 0x01, 0x02, 0x84, 0x25, 0x01, 0x02, 0x88, 0x25, 0x01, 0x02, 0x8c, 0x25, 0x01, 0x02, 0x90, 0x25, 0x01, 0x02, 0xc4, 0x06, 0x02, 0x02, + 0xc8, 0x06, 0x02, 0x02, 0xcc, 0x06, 0x02, 0x02, 0xd0, 0x06, 0x02, 0x02, 0x38, 0x22, 0x03, 0x03, 0x40, 0x22, 0x03, 0x03, 0x48, 0x22, 0x03, 0x03, 0x60, 0x04, 0x04, 0x03, 0x68, 0x04, 0x04, 0x03, + 0xa0, 0x1e, 0x05, 0x04, 0xb0, 0x1e, 0x05, 0x04, 0x00, 0x02, 0x06, 0x04, 0x00, 0x3b, 0x08, 0x06, 0x80, 0x3e, 0x0a, 0x07, 0x50, 0x39, 0x00, 0x03, 0x58, 0x39, 0x00, 0x03, 0x60, 0x39, 0x00, 0x03, + 0x68, 0x39, 0x00, 0x03, 0x94, 0x25, 0x01, 0x02, 0x98, 0x25, 0x01, 0x02, 0x9c, 0x25, 0x01, 0x02, 0xa0, 0x25, 0x01, 0x02, 0xa4, 0x25, 0x01, 0x02, 0xa8, 0x25, 0x01, 0x02, 0xd4, 0x06, 0x02, 0x02, + 0xd8, 0x06, 0x02, 0x02, 0xdc, 0x06, 0x02, 0x02, 0xe0, 0x06, 0x02, 0x02, 0x50, 0x22, 0x03, 0x03, 0x58, 0x22, 0x03, 0x03, 0x60, 0x22, 0x03, 0x03, 0x70, 0x04, 0x04, 0x03, 0x78, 0x04, 0x04, 0x03, + 0xc0, 0x1e, 0x05, 0x04, 0xd0, 0x1e, 0x05, 0x04, 0x10, 0x02, 0x06, 0x04, 0x40, 0x3b, 0x08, 0x06, 0x00, 0x3f, 0x0a, 0x07, 0x70, 0x39, 0x00, 0x03, 0x78, 0x39, 0x00, 0x03, 0x80, 0x39, 0x00, 0x03, + 0x88, 0x39, 0x00, 0x03, 0xac, 0x25, 0x01, 0x02, 0xb0, 0x25, 0x01, 0x02, 0xb4, 0x25, 0x01, 0x02, 0xb8, 0x25, 0x01, 0x02, 0xbc, 0x25, 0x01, 0x02, 0xc0, 0x25, 0x01, 0x02, 0xe4, 0x06, 0x02, 0x02, + 0xe8, 0x06, 0x02, 0x02, 0xec, 0x06, 0x02, 0x02, 0xf0, 0x06, 0x02, 0x02, 0x68, 0x22, 0x03, 0x03, 0x70, 0x22, 0x03, 0x03, 0x78, 0x22, 0x03, 0x03, 0x80, 0x04, 0x04, 0x03, 0x88, 0x04, 0x04, 0x03, + 0xe0, 0x1e, 0x05, 0x04, 0xf0, 0x1e, 0x05, 0x04, 0x20, 0x02, 0x06, 0x04, 0x80, 0x3b, 0x08, 0x06, 0x80, 0x3f, 0x0a, 0x07, 0x90, 0x39, 0x00, 0x03, 0x98, 0x39, 0x00, 0x03, 0xa0, 0x39, 0x00, 0x03, + 0xa8, 0x39, 0x00, 0x03, 0xc4, 0x25, 0x01, 0x02, 0xc8, 0x25, 0x01, 0x02, 0xcc, 0x25, 0x01, 0x02, 0xd0, 0x25, 0x01, 0x02, 0xd4, 0x25, 0x01, 0x02, 0xd8, 0x25, 0x01, 0x02, 0xf4, 0x06, 0x02, 0x02, + 0xf8, 0x06, 0x02, 0x02, 0xfc, 0x06, 0x02, 0x02, 0x00, 0x07, 0x02, 0x02, 0x80, 0x22, 0x03, 0x03, 0x88, 0x22, 0x03, 0x03, 0x90, 0x22, 0x03, 0x03, 0x90, 0x04, 0x04, 0x03, 0x98, 0x04, 0x04, 0x03, + 0x00, 0x1f, 0x05, 0x04, 0x10, 0x1f, 0x05, 0x04, 0x30, 0x02, 0x06, 0x04, 0xc0, 0x3b, 0x08, 0x06, 0x00, 0x00, 0x0a, 0x06, 0xb0, 0x39, 0x00, 0x03, 0xb8, 0x39, 0x00, 0x03, 0xc0, 0x39, 0x00, 0x03, + 0xc8, 0x39, 0x00, 0x03, 0xdc, 0x25, 0x01, 0x02, 0xe0, 0x25, 0x01, 0x02, 0xe4, 0x25, 0x01, 0x02, 0xe8, 0x25, 0x01, 0x02, 0xec, 0x25, 0x01, 0x02, 0xf0, 0x25, 0x01, 0x02, 0x04, 0x07, 0x02, 0x02, + 0x08, 0x07, 0x02, 0x02, 0x0c, 0x07, 0x02, 0x02, 0x10, 0x07, 0x02, 0x02, 0x98, 0x22, 0x03, 0x03, 0xa0, 0x22, 0x03, 0x03, 0xa8, 0x22, 0x03, 0x03, 0xa0, 0x04, 0x04, 0x03, 0xa8, 0x04, 0x04, 0x03, + 0x20, 0x1f, 0x05, 0x04, 0x30, 0x1f, 0x05, 0x04, 0x40, 0x02, 0x06, 0x04, 0x00, 0x3c, 0x08, 0x06, 0x80, 0x12, 0x0b, 0x07, 0xd0, 0x39, 0x00, 0x03, 0xd8, 0x39, 0x00, 0x03, 0xe0, 0x39, 0x00, 0x03, + 0xe8, 0x39, 0x00, 0x03, 0xf4, 0x25, 0x01, 0x02, 0xf8, 0x25, 0x01, 0x02, 0xfc, 0x25, 0x01, 0x02, 0x00, 0x26, 0x01, 0x02, 0x04, 0x26, 0x01, 0x02, 0x08, 0x26, 0x01, 0x02, 0x14, 0x07, 0x02, 0x02, + 0x18, 0x07, 0x02, 0x02, 0x1c, 0x07, 0x02, 0x02, 0x20, 0x07, 0x02, 0x02, 0xb0, 0x22, 0x03, 0x03, 0xb8, 0x22, 0x03, 0x03, 0xc0, 0x22, 0x03, 0x03, 0xb0, 0x04, 0x04, 0x03, 0xb8, 0x04, 0x04, 0x03, + 0x40, 0x1f, 0x05, 0x04, 0x50, 0x1f, 0x05, 0x04, 0x50, 0x02, 0x06, 0x04, 0x40, 0x3c, 0x08, 0x06, 0x00, 0x13, 0x0b, 0x07, 0xf0, 0x39, 0x00, 0x03, 0xf8, 0x39, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x03, + 0x08, 0x3a, 0x00, 0x03, 0x0c, 0x26, 0x01, 0x02, 0x10, 0x26, 0x01, 0x02, 0x14, 0x26, 0x01, 0x02, 0x18, 0x26, 0x01, 0x02, 0x1c, 0x26, 0x01, 0x02, 0x20, 0x26, 0x01, 0x02, 0x24, 0x07, 0x02, 0x02, + 0x28, 0x07, 0x02, 0x02, 0x2c, 0x07, 0x02, 0x02, 0x30, 0x07, 0x02, 0x02, 0xc8, 0x22, 0x03, 0x03, 0xd0, 0x22, 0x03, 0x03, 0xd8, 0x22, 0x03, 0x03, 0xc0, 0x04, 0x04, 0x03, 0xc8, 0x04, 0x04, 0x03, + 0x60, 0x1f, 0x05, 0x04, 0x70, 0x1f, 0x05, 0x04, 0x60, 0x02, 0x06, 0x04, 0x80, 0x3c, 0x08, 0x06, 0x80, 0x13, 0x0b, 0x07, 0x10, 0x3a, 0x00, 0x03, 0x18, 0x3a, 0x00, 0x03, 0x20, 0x3a, 0x00, 0x03, + 0x28, 0x3a, 0x00, 0x03, 0x24, 0x26, 0x01, 0x02, 0x28, 0x26, 0x01, 0x02, 0x2c, 0x26, 0x01, 0x02, 0x30, 0x26, 0x01, 0x02, 0x34, 0x26, 0x01, 0x02, 0x38, 0x26, 0x01, 0x02, 0x34, 0x07, 0x02, 0x02, + 0x38, 0x07, 0x02, 0x02, 0x3c, 0x07, 0x02, 0x02, 0x40, 0x07, 0x02, 0x02, 0xe0, 0x22, 0x03, 0x03, 0xe8, 0x22, 0x03, 0x03, 0xf0, 0x22, 0x03, 0x03, 0xd0, 0x04, 0x04, 0x03, 0xd8, 0x04, 0x04, 0x03, + 0x80, 0x1f, 0x05, 0x04, 0x90, 0x1f, 0x05, 0x04, 0x70, 0x02, 0x06, 0x04, 0xc0, 0x3c, 0x08, 0x06, 0x00, 0x14, 0x0b, 0x07, 0x30, 0x3a, 0x00, 0x03, 0x38, 0x3a, 0x00, 0x03, 0x40, 0x3a, 0x00, 0x03, + 0x48, 0x3a, 0x00, 0x03, 0x3c, 0x26, 0x01, 0x02, 0x40, 0x26, 0x01, 0x02, 0x44, 0x26, 0x01, 0x02, 0x48, 0x26, 0x01, 0x02, 0x4c, 0x26, 0x01, 0x02, 0x50, 0x26, 0x01, 0x02, 0x44, 0x07, 0x02, 0x02, + 0x48, 0x07, 0x02, 0x02, 0x4c, 0x07, 0x02, 0x02, 0x50, 0x07, 0x02, 0x02, 0xf8, 0x22, 0x03, 0x03, 0x00, 0x23, 0x03, 0x03, 0x08, 0x23, 0x03, 0x03, 0xe0, 0x04, 0x04, 0x03, 0xe8, 0x04, 0x04, 0x03, + 0xa0, 0x1f, 0x05, 0x04, 0xb0, 0x1f, 0x05, 0x04, 0x80, 0x02, 0x06, 0x04, 0x00, 0x3d, 0x08, 0x06, 0x80, 0x14, 0x0b, 0x07, 0x50, 0x3a, 0x00, 0x03, 0x58, 0x3a, 0x00, 0x03, 0x60, 0x3a, 0x00, 0x03, + 0x68, 0x3a, 0x00, 0x03, 0x54, 0x26, 0x01, 0x02, 0x58, 0x26, 0x01, 0x02, 0x5c, 0x26, 0x01, 0x02, 0x60, 0x26, 0x01, 0x02, 0x64, 0x26, 0x01, 0x02, 0x68, 0x26, 0x01, 0x02, 0x54, 0x07, 0x02, 0x02, + 0x58, 0x07, 0x02, 0x02, 0x5c, 0x07, 0x02, 0x02, 0x60, 0x07, 0x02, 0x02, 0x10, 0x23, 0x03, 0x03, 0x18, 0x23, 0x03, 0x03, 0x20, 0x23, 0x03, 0x03, 0xf0, 0x04, 0x04, 0x03, 0xf8, 0x04, 0x04, 0x03, + 0xc0, 0x1f, 0x05, 0x04, 0xd0, 0x1f, 0x05, 0x04, 0x90, 0x02, 0x06, 0x04, 0x40, 0x3d, 0x08, 0x06, 0x00, 0x15, 0x0b, 0x07, 0x70, 0x3a, 0x00, 0x03, 0x78, 0x3a, 0x00, 0x03, 0x80, 0x3a, 0x00, 0x03, + 0x88, 0x3a, 0x00, 0x03, 0x6c, 0x26, 0x01, 0x02, 0x70, 0x26, 0x01, 0x02, 0x74, 0x26, 0x01, 0x02, 0x78, 0x26, 0x01, 0x02, 0x7c, 0x26, 0x01, 0x02, 0x80, 0x26, 0x01, 0x02, 0x64, 0x07, 0x02, 0x02, + 0x68, 0x07, 0x02, 0x02, 0x6c, 0x07, 0x02, 0x02, 0x70, 0x07, 0x02, 0x02, 0x28, 0x23, 0x03, 0x03, 0x30, 0x23, 0x03, 0x03, 0x38, 0x23, 0x03, 0x03, 0x00, 0x05, 0x04, 0x03, 0x08, 0x05, 0x04, 0x03, + 0xe0, 0x1f, 0x05, 0x04, 0xf0, 0x1f, 0x05, 0x04, 0xa0, 0x02, 0x06, 0x04, 0x80, 0x3d, 0x08, 0x06, 0x80, 0x15, 0x0b, 0x07, 0x90, 0x3a, 0x00, 0x03, 0x98, 0x3a, 0x00, 0x03, 0xa0, 0x3a, 0x00, 0x03, + 0xa8, 0x3a, 0x00, 0x03, 0x84, 0x26, 0x01, 0x02, 0x88, 0x26, 0x01, 0x02, 0x8c, 0x26, 0x01, 0x02, 0x90, 0x26, 0x01, 0x02, 0x94, 0x26, 0x01, 0x02, 0x98, 0x26, 0x01, 0x02, 0x74, 0x07, 0x02, 0x02, + 0x78, 0x07, 0x02, 0x02, 0x7c, 0x07, 0x02, 0x02, 0x80, 0x07, 0x02, 0x02, 0x40, 0x23, 0x03, 0x03, 0x48, 0x23, 0x03, 0x03, 0x50, 0x23, 0x03, 0x03, 0x10, 0x05, 0x04, 0x03, 0x18, 0x05, 0x04, 0x03, + 0x00, 0x20, 0x05, 0x04, 0x10, 0x20, 0x05, 0x04, 0xb0, 0x02, 0x06, 0x04, 0xc0, 0x3d, 0x08, 0x06, 0x00, 0x16, 0x0b, 0x07, 0xb0, 0x3a, 0x00, 0x03, 0xb8, 0x3a, 0x00, 0x03, 0xc0, 0x3a, 0x00, 0x03, + 0xc8, 0x3a, 0x00, 0x03, 0x9c, 0x26, 0x01, 0x02, 0xa0, 0x26, 0x01, 0x02, 0xa4, 0x26, 0x01, 0x02, 0xa8, 0x26, 0x01, 0x02, 0xac, 0x26, 0x01, 0x02, 0xb0, 0x26, 0x01, 0x02, 0x84, 0x07, 0x02, 0x02, + 0x88, 0x07, 0x02, 0x02, 0x8c, 0x07, 0x02, 0x02, 0x90, 0x07, 0x02, 0x02, 0x58, 0x23, 0x03, 0x03, 0x60, 0x23, 0x03, 0x03, 0x68, 0x23, 0x03, 0x03, 0x20, 0x05, 0x04, 0x03, 0x28, 0x05, 0x04, 0x03, + 0x20, 0x20, 0x05, 0x04, 0x30, 0x20, 0x05, 0x04, 0xc0, 0x02, 0x06, 0x04, 0x00, 0x3e, 0x08, 0x06, 0x80, 0x16, 0x0b, 0x07, 0xd0, 0x3a, 0x00, 0x03, 0xd8, 0x3a, 0x00, 0x03, 0xe0, 0x3a, 0x00, 0x03, + 0xe8, 0x3a, 0x00, 0x03, 0xb4, 0x26, 0x01, 0x02, 0xb8, 0x26, 0x01, 0x02, 0xbc, 0x26, 0x01, 0x02, 0xc0, 0x26, 0x01, 0x02, 0xc4, 0x26, 0x01, 0x02, 0xc8, 0x26, 0x01, 0x02, 0x94, 0x07, 0x02, 0x02, + 0x98, 0x07, 0x02, 0x02, 0x9c, 0x07, 0x02, 0x02, 0xa0, 0x07, 0x02, 0x02, 0x70, 0x23, 0x03, 0x03, 0x78, 0x23, 0x03, 0x03, 0x80, 0x23, 0x03, 0x03, 0x30, 0x05, 0x04, 0x03, 0x38, 0x05, 0x04, 0x03, + 0x40, 0x20, 0x05, 0x04, 0x50, 0x20, 0x05, 0x04, 0xd0, 0x02, 0x06, 0x04, 0x40, 0x3e, 0x08, 0x06, 0x00, 0x17, 0x0b, 0x07, 0xf0, 0x3a, 0x00, 0x03, 0xf8, 0x3a, 0x00, 0x03, 0x00, 0x3b, 0x00, 0x03, + 0x08, 0x3b, 0x00, 0x03, 0xcc, 0x26, 0x01, 0x02, 0xd0, 0x26, 0x01, 0x02, 0xd4, 0x26, 0x01, 0x02, 0xd8, 0x26, 0x01, 0x02, 0xdc, 0x26, 0x01, 0x02, 0xe0, 0x26, 0x01, 0x02, 0xa4, 0x07, 0x02, 0x02, + 0xa8, 0x07, 0x02, 0x02, 0xac, 0x07, 0x02, 0x02, 0xb0, 0x07, 0x02, 0x02, 0x88, 0x23, 0x03, 0x03, 0x90, 0x23, 0x03, 0x03, 0x98, 0x23, 0x03, 0x03, 0x40, 0x05, 0x04, 0x03, 0x48, 0x05, 0x04, 0x03, + 0x60, 0x20, 0x05, 0x04, 0x70, 0x20, 0x05, 0x04, 0xe0, 0x02, 0x06, 0x04, 0x80, 0x3e, 0x08, 0x06, 0x80, 0x17, 0x0b, 0x07, 0x10, 0x3b, 0x00, 0x03, 0x18, 0x3b, 0x00, 0x03, 0x20, 0x3b, 0x00, 0x03, + 0x28, 0x3b, 0x00, 0x03, 0xe4, 0x26, 0x01, 0x02, 0xe8, 0x26, 0x01, 0x02, 0xec, 0x26, 0x01, 0x02, 0xf0, 0x26, 0x01, 0x02, 0xf4, 0x26, 0x01, 0x02, 0xf8, 0x26, 0x01, 0x02, 0xb4, 0x07, 0x02, 0x02, + 0xb8, 0x07, 0x02, 0x02, 0xbc, 0x07, 0x02, 0x02, 0xc0, 0x07, 0x02, 0x02, 0xa0, 0x23, 0x03, 0x03, 0xa8, 0x23, 0x03, 0x03, 0xb0, 0x23, 0x03, 0x03, 0x50, 0x05, 0x04, 0x03, 0x58, 0x05, 0x04, 0x03, + 0x80, 0x20, 0x05, 0x04, 0x90, 0x20, 0x05, 0x04, 0xf0, 0x02, 0x06, 0x04, 0xc0, 0x3e, 0x08, 0x06, 0x00, 0x18, 0x0b, 0x07, 0x30, 0x3b, 0x00, 0x03, 0x38, 0x3b, 0x00, 0x03, 0x40, 0x3b, 0x00, 0x03, + 0x48, 0x3b, 0x00, 0x03, 0xfc, 0x26, 0x01, 0x02, 0x00, 0x27, 0x01, 0x02, 0x04, 0x27, 0x01, 0x02, 0x08, 0x27, 0x01, 0x02, 0x0c, 0x27, 0x01, 0x02, 0x10, 0x27, 0x01, 0x02, 0xc4, 0x07, 0x02, 0x02, + 0xc8, 0x07, 0x02, 0x02, 0xcc, 0x07, 0x02, 0x02, 0xd0, 0x07, 0x02, 0x02, 0xb8, 0x23, 0x03, 0x03, 0xc0, 0x23, 0x03, 0x03, 0xc8, 0x23, 0x03, 0x03, 0x60, 0x05, 0x04, 0x03, 0x68, 0x05, 0x04, 0x03, + 0xa0, 0x20, 0x05, 0x04, 0xb0, 0x20, 0x05, 0x04, 0x00, 0x03, 0x06, 0x04, 0x00, 0x3f, 0x08, 0x06, 0x80, 0x18, 0x0b, 0x07, 0x50, 0x3b, 0x00, 0x03, 0x58, 0x3b, 0x00, 0x03, 0x60, 0x3b, 0x00, 0x03, + 0x68, 0x3b, 0x00, 0x03, 0x14, 0x27, 0x01, 0x02, 0x18, 0x27, 0x01, 0x02, 0x1c, 0x27, 0x01, 0x02, 0x20, 0x27, 0x01, 0x02, 0x24, 0x27, 0x01, 0x02, 0x28, 0x27, 0x01, 0x02, 0xd4, 0x07, 0x02, 0x02, + 0xd8, 0x07, 0x02, 0x02, 0xdc, 0x07, 0x02, 0x02, 0xe0, 0x07, 0x02, 0x02, 0xd0, 0x23, 0x03, 0x03, 0xd8, 0x23, 0x03, 0x03, 0xe0, 0x23, 0x03, 0x03, 0x70, 0x05, 0x04, 0x03, 0x78, 0x05, 0x04, 0x03, + 0xc0, 0x20, 0x05, 0x04, 0xd0, 0x20, 0x05, 0x04, 0x10, 0x03, 0x06, 0x04, 0x40, 0x3f, 0x08, 0x06, 0x00, 0x32, 0x0c, 0x08, 0x70, 0x3b, 0x00, 0x03, 0x78, 0x3b, 0x00, 0x03, 0x80, 0x3b, 0x00, 0x03, + 0x88, 0x3b, 0x00, 0x03, 0x2c, 0x27, 0x01, 0x02, 0x30, 0x27, 0x01, 0x02, 0x34, 0x27, 0x01, 0x02, 0x38, 0x27, 0x01, 0x02, 0x3c, 0x27, 0x01, 0x02, 0x40, 0x27, 0x01, 0x02, 0xe4, 0x07, 0x02, 0x02, + 0xe8, 0x07, 0x02, 0x02, 0xec, 0x07, 0x02, 0x02, 0xf0, 0x07, 0x02, 0x02, 0xe8, 0x23, 0x03, 0x03, 0xf0, 0x23, 0x03, 0x03, 0xf8, 0x23, 0x03, 0x03, 0x80, 0x05, 0x04, 0x03, 0x88, 0x05, 0x04, 0x03, + 0xe0, 0x20, 0x05, 0x04, 0xf0, 0x20, 0x05, 0x04, 0x20, 0x03, 0x06, 0x04, 0x80, 0x3f, 0x08, 0x06, 0x00, 0x33, 0x0c, 0x08, 0x90, 0x3b, 0x00, 0x03, 0x98, 0x3b, 0x00, 0x03, 0xa0, 0x3b, 0x00, 0x03, + 0xa8, 0x3b, 0x00, 0x03, 0x44, 0x27, 0x01, 0x02, 0x48, 0x27, 0x01, 0x02, 0x4c, 0x27, 0x01, 0x02, 0x50, 0x27, 0x01, 0x02, 0x54, 0x27, 0x01, 0x02, 0x58, 0x27, 0x01, 0x02, 0xf4, 0x07, 0x02, 0x02, + 0xf8, 0x07, 0x02, 0x02, 0xfc, 0x07, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x00, 0x24, 0x03, 0x03, 0x08, 0x24, 0x03, 0x03, 0x10, 0x24, 0x03, 0x03, 0x90, 0x05, 0x04, 0x03, 0x98, 0x05, 0x04, 0x03, + 0x00, 0x21, 0x05, 0x04, 0x10, 0x21, 0x05, 0x04, 0x30, 0x03, 0x06, 0x04, 0xc0, 0x3f, 0x08, 0x06, 0x00, 0x34, 0x0c, 0x08, 0xb0, 0x3b, 0x00, 0x03, 0xb8, 0x3b, 0x00, 0x03, 0xc0, 0x3b, 0x00, 0x03, + 0xc8, 0x3b, 0x00, 0x03, 0x5c, 0x27, 0x01, 0x02, 0x60, 0x27, 0x01, 0x02, 0x64, 0x27, 0x01, 0x02, 0x68, 0x27, 0x01, 0x02, 0x6c, 0x27, 0x01, 0x02, 0x70, 0x27, 0x01, 0x02, 0x04, 0x08, 0x02, 0x02, + 0x08, 0x08, 0x02, 0x02, 0x0c, 0x08, 0x02, 0x02, 0x10, 0x08, 0x02, 0x02, 0x18, 0x24, 0x03, 0x03, 0x20, 0x24, 0x03, 0x03, 0x28, 0x24, 0x03, 0x03, 0xa0, 0x05, 0x04, 0x03, 0xa8, 0x05, 0x04, 0x03, + 0x20, 0x21, 0x05, 0x04, 0x30, 0x21, 0x05, 0x04, 0x40, 0x03, 0x06, 0x04, 0x00, 0x00, 0x08, 0x05, 0x00, 0x35, 0x0c, 0x08, 0xd0, 0x3b, 0x00, 0x03, 0xd8, 0x3b, 0x00, 0x03, 0xe0, 0x3b, 0x00, 0x03, + 0xe8, 0x3b, 0x00, 0x03, 0x74, 0x27, 0x01, 0x02, 0x78, 0x27, 0x01, 0x02, 0x7c, 0x27, 0x01, 0x02, 0x80, 0x27, 0x01, 0x02, 0x84, 0x27, 0x01, 0x02, 0x88, 0x27, 0x01, 0x02, 0x14, 0x08, 0x02, 0x02, + 0x18, 0x08, 0x02, 0x02, 0x1c, 0x08, 0x02, 0x02, 0x20, 0x08, 0x02, 0x02, 0x30, 0x24, 0x03, 0x03, 0x38, 0x24, 0x03, 0x03, 0x40, 0x24, 0x03, 0x03, 0xb0, 0x05, 0x04, 0x03, 0xb8, 0x05, 0x04, 0x03, + 0x40, 0x21, 0x05, 0x04, 0x50, 0x21, 0x05, 0x04, 0x50, 0x03, 0x06, 0x04, 0x20, 0x00, 0x08, 0x05, 0x00, 0x36, 0x0c, 0x08, 0xf0, 0x3b, 0x00, 0x03, 0xf8, 0x3b, 0x00, 0x03, 0x00, 0x3c, 0x00, 0x03, + 0x8c, 0x27, 0x01, 0x02, 0x90, 0x27, 0x01, 0x02, 0x94, 0x27, 0x01, 0x02, 0x98, 0x27, 0x01, 0x02, 0x9c, 0x27, 0x01, 0x02, 0xa0, 0x27, 0x01, 0x02, 0xa4, 0x27, 0x01, 0x02, 0x24, 0x08, 0x02, 0x02, + 0x28, 0x08, 0x02, 0x02, 0x2c, 0x08, 0x02, 0x02, 0x30, 0x08, 0x02, 0x02, 0x48, 0x24, 0x03, 0x03, 0x50, 0x24, 0x03, 0x03, 0x58, 0x24, 0x03, 0x03, 0xc0, 0x05, 0x04, 0x03, 0xc8, 0x05, 0x04, 0x03, + 0x60, 0x21, 0x05, 0x04, 0x70, 0x21, 0x05, 0x04, 0x60, 0x03, 0x06, 0x04, 0x40, 0x00, 0x08, 0x05, 0x00, 0x37, 0x0c, 0x08, 0x08, 0x3c, 0x00, 0x03, 0x10, 0x3c, 0x00, 0x03, 0x18, 0x3c, 0x00, 0x03, + 0xa8, 0x27, 0x01, 0x02, 0xac, 0x27, 0x01, 0x02, 0xb0, 0x27, 0x01, 0x02, 0xb4, 0x27, 0x01, 0x02, 0xb8, 0x27, 0x01, 0x02, 0xbc, 0x27, 0x01, 0x02, 0xc0, 0x27, 0x01, 0x02, 0x34, 0x08, 0x02, 0x02, + 0x38, 0x08, 0x02, 0x02, 0x3c, 0x08, 0x02, 0x02, 0x40, 0x08, 0x02, 0x02, 0x60, 0x24, 0x03, 0x03, 0x68, 0x24, 0x03, 0x03, 0x70, 0x24, 0x03, 0x03, 0xd0, 0x05, 0x04, 0x03, 0xd8, 0x05, 0x04, 0x03, + 0x80, 0x21, 0x05, 0x04, 0x90, 0x21, 0x05, 0x04, 0x70, 0x03, 0x06, 0x04, 0x60, 0x00, 0x08, 0x05, 0x00, 0x38, 0x0c, 0x08, 0x20, 0x3c, 0x00, 0x03, 0x28, 0x3c, 0x00, 0x03, 0x30, 0x3c, 0x00, 0x03, + 0xc4, 0x27, 0x01, 0x02, 0xc8, 0x27, 0x01, 0x02, 0xcc, 0x27, 0x01, 0x02, 0xd0, 0x27, 0x01, 0x02, 0xd4, 0x27, 0x01, 0x02, 0xd8, 0x27, 0x01, 0x02, 0xdc, 0x27, 0x01, 0x02, 0x44, 0x08, 0x02, 0x02, + 0x48, 0x08, 0x02, 0x02, 0x4c, 0x08, 0x02, 0x02, 0x50, 0x08, 0x02, 0x02, 0x78, 0x24, 0x03, 0x03, 0x80, 0x24, 0x03, 0x03, 0x88, 0x24, 0x03, 0x03, 0xe0, 0x05, 0x04, 0x03, 0xe8, 0x05, 0x04, 0x03, + 0xa0, 0x21, 0x05, 0x04, 0x80, 0x03, 0x06, 0x04, 0x00, 0x1d, 0x07, 0x05, 0x80, 0x00, 0x08, 0x05, 0x00, 0x39, 0x0c, 0x08, 0x38, 0x3c, 0x00, 0x03, 0x40, 0x3c, 0x00, 0x03, 0x48, 0x3c, 0x00, 0x03, + 0xe0, 0x27, 0x01, 0x02, 0xe4, 0x27, 0x01, 0x02, 0xe8, 0x27, 0x01, 0x02, 0xec, 0x27, 0x01, 0x02, 0xf0, 0x27, 0x01, 0x02, 0xf4, 0x27, 0x01, 0x02, 0xf8, 0x27, 0x01, 0x02, 0x54, 0x08, 0x02, 0x02, + 0x58, 0x08, 0x02, 0x02, 0x5c, 0x08, 0x02, 0x02, 0x60, 0x08, 0x02, 0x02, 0x90, 0x24, 0x03, 0x03, 0x98, 0x24, 0x03, 0x03, 0xa0, 0x24, 0x03, 0x03, 0xf0, 0x05, 0x04, 0x03, 0xf8, 0x05, 0x04, 0x03, + 0xb0, 0x21, 0x05, 0x04, 0x90, 0x03, 0x06, 0x04, 0x20, 0x1d, 0x07, 0x05, 0xa0, 0x00, 0x08, 0x05, 0x00, 0x3a, 0x0c, 0x08, 0x50, 0x3c, 0x00, 0x03, 0x58, 0x3c, 0x00, 0x03, 0x60, 0x3c, 0x00, 0x03, + 0xfc, 0x27, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x04, 0x28, 0x01, 0x02, 0x08, 0x28, 0x01, 0x02, 0x0c, 0x28, 0x01, 0x02, 0x10, 0x28, 0x01, 0x02, 0x14, 0x28, 0x01, 0x02, 0x64, 0x08, 0x02, 0x02, + 0x68, 0x08, 0x02, 0x02, 0x6c, 0x08, 0x02, 0x02, 0x70, 0x08, 0x02, 0x02, 0xa8, 0x24, 0x03, 0x03, 0xb0, 0x24, 0x03, 0x03, 0xb8, 0x24, 0x03, 0x03, 0x00, 0x06, 0x04, 0x03, 0x08, 0x06, 0x04, 0x03, + 0xc0, 0x21, 0x05, 0x04, 0xa0, 0x03, 0x06, 0x04, 0x40, 0x1d, 0x07, 0x05, 0xc0, 0x00, 0x08, 0x05, 0x00, 0x3b, 0x0c, 0x08, 0x68, 0x3c, 0x00, 0x03, 0x70, 0x3c, 0x00, 0x03, 0x78, 0x3c, 0x00, 0x03, + 0x18, 0x28, 0x01, 0x02, 0x1c, 0x28, 0x01, 0x02, 0x20, 0x28, 0x01, 0x02, 0x24, 0x28, 0x01, 0x02, 0x28, 0x28, 0x01, 0x02, 0x2c, 0x28, 0x01, 0x02, 0x30, 0x28, 0x01, 0x02, 0x74, 0x08, 0x02, 0x02, + 0x78, 0x08, 0x02, 0x02, 0x7c, 0x08, 0x02, 0x02, 0x80, 0x08, 0x02, 0x02, 0xc0, 0x24, 0x03, 0x03, 0xc8, 0x24, 0x03, 0x03, 0xd0, 0x24, 0x03, 0x03, 0x10, 0x06, 0x04, 0x03, 0x18, 0x06, 0x04, 0x03, + 0xd0, 0x21, 0x05, 0x04, 0xb0, 0x03, 0x06, 0x04, 0x60, 0x1d, 0x07, 0x05, 0xe0, 0x00, 0x08, 0x05, 0x00, 0x0f, 0x0d, 0x08, 0x80, 0x3c, 0x00, 0x03, 0x88, 0x3c, 0x00, 0x03, 0x90, 0x3c, 0x00, 0x03, + 0x34, 0x28, 0x01, 0x02, 0x38, 0x28, 0x01, 0x02, 0x3c, 0x28, 0x01, 0x02, 0x40, 0x28, 0x01, 0x02, 0x44, 0x28, 0x01, 0x02, 0x48, 0x28, 0x01, 0x02, 0x4c, 0x28, 0x01, 0x02, 0x84, 0x08, 0x02, 0x02, + 0x88, 0x08, 0x02, 0x02, 0x8c, 0x08, 0x02, 0x02, 0x90, 0x08, 0x02, 0x02, 0xd8, 0x24, 0x03, 0x03, 0xe0, 0x24, 0x03, 0x03, 0xe8, 0x24, 0x03, 0x03, 0x20, 0x06, 0x04, 0x03, 0x28, 0x06, 0x04, 0x03, + 0xe0, 0x21, 0x05, 0x04, 0xc0, 0x03, 0x06, 0x04, 0x80, 0x1d, 0x07, 0x05, 0x00, 0x01, 0x08, 0x05, 0x00, 0x10, 0x0d, 0x08, 0x98, 0x3c, 0x00, 0x03, 0xa0, 0x3c, 0x00, 0x03, 0xa8, 0x3c, 0x00, 0x03, + 0x50, 0x28, 0x01, 0x02, 0x54, 0x28, 0x01, 0x02, 0x58, 0x28, 0x01, 0x02, 0x5c, 0x28, 0x01, 0x02, 0x60, 0x28, 0x01, 0x02, 0x64, 0x28, 0x01, 0x02, 0x68, 0x28, 0x01, 0x02, 0x94, 0x08, 0x02, 0x02, + 0x98, 0x08, 0x02, 0x02, 0x9c, 0x08, 0x02, 0x02, 0xa0, 0x08, 0x02, 0x02, 0xf0, 0x24, 0x03, 0x03, 0xf8, 0x24, 0x03, 0x03, 0x00, 0x25, 0x03, 0x03, 0x30, 0x06, 0x04, 0x03, 0x38, 0x06, 0x04, 0x03, + 0xf0, 0x21, 0x05, 0x04, 0xd0, 0x03, 0x06, 0x04, 0xa0, 0x1d, 0x07, 0x05, 0x20, 0x01, 0x08, 0x05, 0x00, 0x11, 0x0d, 0x08, 0xb0, 0x3c, 0x00, 0x03, 0xb8, 0x3c, 0x00, 0x03, 0xc0, 0x3c, 0x00, 0x03, + 0x6c, 0x28, 0x01, 0x02, 0x70, 0x28, 0x01, 0x02, 0x74, 0x28, 0x01, 0x02, 0x78, 0x28, 0x01, 0x02, 0x7c, 0x28, 0x01, 0x02, 0x80, 0x28, 0x01, 0x02, 0x84, 0x28, 0x01, 0x02, 0xa4, 0x08, 0x02, 0x02, + 0xa8, 0x08, 0x02, 0x02, 0xac, 0x08, 0x02, 0x02, 0xb0, 0x08, 0x02, 0x02, 0x08, 0x25, 0x03, 0x03, 0x10, 0x25, 0x03, 0x03, 0x18, 0x25, 0x03, 0x03, 0x40, 0x06, 0x04, 0x03, 0x48, 0x06, 0x04, 0x03, + 0x00, 0x22, 0x05, 0x04, 0xe0, 0x03, 0x06, 0x04, 0xc0, 0x1d, 0x07, 0x05, 0x40, 0x01, 0x08, 0x05, 0x00, 0x12, 0x0d, 0x08, 0xc8, 0x3c, 0x00, 0x03, 0xd0, 0x3c, 0x00, 0x03, 0xd8, 0x3c, 0x00, 0x03, + 0x88, 0x28, 0x01, 0x02, 0x8c, 0x28, 0x01, 0x02, 0x90, 0x28, 0x01, 0x02, 0x94, 0x28, 0x01, 0x02, 0x98, 0x28, 0x01, 0x02, 0x9c, 0x28, 0x01, 0x02, 0xa0, 0x28, 0x01, 0x02, 0xb4, 0x08, 0x02, 0x02, + 0xb8, 0x08, 0x02, 0x02, 0xbc, 0x08, 0x02, 0x02, 0xc0, 0x08, 0x02, 0x02, 0x20, 0x25, 0x03, 0x03, 0x28, 0x25, 0x03, 0x03, 0x30, 0x25, 0x03, 0x03, 0x50, 0x06, 0x04, 0x03, 0x58, 0x06, 0x04, 0x03, + 0x10, 0x22, 0x05, 0x04, 0xf0, 0x03, 0x06, 0x04, 0xe0, 0x1d, 0x07, 0x05, 0x60, 0x01, 0x08, 0x05, 0x00, 0x13, 0x0d, 0x08, 0xe0, 0x3c, 0x00, 0x03, 0xe8, 0x3c, 0x00, 0x03, 0xf0, 0x3c, 0x00, 0x03, + 0xa4, 0x28, 0x01, 0x02, 0xa8, 0x28, 0x01, 0x02, 0xac, 0x28, 0x01, 0x02, 0xb0, 0x28, 0x01, 0x02, 0xb4, 0x28, 0x01, 0x02, 0xb8, 0x28, 0x01, 0x02, 0xbc, 0x28, 0x01, 0x02, 0xc4, 0x08, 0x02, 0x02, + 0xc8, 0x08, 0x02, 0x02, 0xcc, 0x08, 0x02, 0x02, 0xd0, 0x08, 0x02, 0x02, 0x38, 0x25, 0x03, 0x03, 0x40, 0x25, 0x03, 0x03, 0x48, 0x25, 0x03, 0x03, 0x60, 0x06, 0x04, 0x03, 0x68, 0x06, 0x04, 0x03, + 0x20, 0x22, 0x05, 0x04, 0x00, 0x04, 0x06, 0x04, 0x00, 0x1e, 0x07, 0x05, 0x80, 0x01, 0x08, 0x05, 0x00, 0x14, 0x0d, 0x08, 0xf8, 0x3c, 0x00, 0x03, 0x00, 0x3d, 0x00, 0x03, 0x08, 0x3d, 0x00, 0x03, + 0xc0, 0x28, 0x01, 0x02, 0xc4, 0x28, 0x01, 0x02, 0xc8, 0x28, 0x01, 0x02, 0xcc, 0x28, 0x01, 0x02, 0xd0, 0x28, 0x01, 0x02, 0xd4, 0x28, 0x01, 0x02, 0xd8, 0x28, 0x01, 0x02, 0xd4, 0x08, 0x02, 0x02, + 0xd8, 0x08, 0x02, 0x02, 0xdc, 0x08, 0x02, 0x02, 0xe0, 0x08, 0x02, 0x02, 0x50, 0x25, 0x03, 0x03, 0x58, 0x25, 0x03, 0x03, 0x60, 0x25, 0x03, 0x03, 0x70, 0x06, 0x04, 0x03, 0x78, 0x06, 0x04, 0x03, + 0x30, 0x22, 0x05, 0x04, 0x10, 0x04, 0x06, 0x04, 0x20, 0x1e, 0x07, 0x05, 0xa0, 0x01, 0x08, 0x05, 0x00, 0x15, 0x0d, 0x08, 0x10, 0x3d, 0x00, 0x03, 0x18, 0x3d, 0x00, 0x03, 0x20, 0x3d, 0x00, 0x03, + 0xdc, 0x28, 0x01, 0x02, 0xe0, 0x28, 0x01, 0x02, 0xe4, 0x28, 0x01, 0x02, 0xe8, 0x28, 0x01, 0x02, 0xec, 0x28, 0x01, 0x02, 0xf0, 0x28, 0x01, 0x02, 0xf4, 0x28, 0x01, 0x02, 0xe4, 0x08, 0x02, 0x02, + 0xe8, 0x08, 0x02, 0x02, 0xec, 0x08, 0x02, 0x02, 0xf0, 0x08, 0x02, 0x02, 0x68, 0x25, 0x03, 0x03, 0x70, 0x25, 0x03, 0x03, 0x78, 0x25, 0x03, 0x03, 0x80, 0x06, 0x04, 0x03, 0x88, 0x06, 0x04, 0x03, + 0x40, 0x22, 0x05, 0x04, 0x20, 0x04, 0x06, 0x04, 0x40, 0x1e, 0x07, 0x05, 0xc0, 0x01, 0x08, 0x05, 0x00, 0x30, 0x0e, 0x09, 0x28, 0x3d, 0x00, 0x03, 0x30, 0x3d, 0x00, 0x03, 0x38, 0x3d, 0x00, 0x03, + 0xf8, 0x28, 0x01, 0x02, 0xfc, 0x28, 0x01, 0x02, 0x00, 0x29, 0x01, 0x02, 0x04, 0x29, 0x01, 0x02, 0x08, 0x29, 0x01, 0x02, 0x0c, 0x29, 0x01, 0x02, 0x10, 0x29, 0x01, 0x02, 0xf4, 0x08, 0x02, 0x02, + 0xf8, 0x08, 0x02, 0x02, 0xfc, 0x08, 0x02, 0x02, 0x00, 0x09, 0x02, 0x02, 0x80, 0x25, 0x03, 0x03, 0x88, 0x25, 0x03, 0x03, 0x90, 0x25, 0x03, 0x03, 0x90, 0x06, 0x04, 0x03, 0x98, 0x06, 0x04, 0x03, + 0x50, 0x22, 0x05, 0x04, 0x30, 0x04, 0x06, 0x04, 0x60, 0x1e, 0x07, 0x05, 0xe0, 0x01, 0x08, 0x05, 0x00, 0x32, 0x0e, 0x09, 0x40, 0x3d, 0x00, 0x03, 0x48, 0x3d, 0x00, 0x03, 0x50, 0x3d, 0x00, 0x03, + 0x14, 0x29, 0x01, 0x02, 0x18, 0x29, 0x01, 0x02, 0x1c, 0x29, 0x01, 0x02, 0x20, 0x29, 0x01, 0x02, 0x24, 0x29, 0x01, 0x02, 0x28, 0x29, 0x01, 0x02, 0x2c, 0x29, 0x01, 0x02, 0x04, 0x09, 0x02, 0x02, + 0x08, 0x09, 0x02, 0x02, 0x0c, 0x09, 0x02, 0x02, 0x10, 0x09, 0x02, 0x02, 0x98, 0x25, 0x03, 0x03, 0xa0, 0x25, 0x03, 0x03, 0xa8, 0x25, 0x03, 0x03, 0xa0, 0x06, 0x04, 0x03, 0xa8, 0x06, 0x04, 0x03, + 0x60, 0x22, 0x05, 0x04, 0x40, 0x04, 0x06, 0x04, 0x80, 0x1e, 0x07, 0x05, 0x00, 0x02, 0x08, 0x05, 0x00, 0x34, 0x0e, 0x09, 0x58, 0x3d, 0x00, 0x03, 0x60, 0x3d, 0x00, 0x03, 0x68, 0x3d, 0x00, 0x03, + 0x30, 0x29, 0x01, 0x02, 0x34, 0x29, 0x01, 0x02, 0x38, 0x29, 0x01, 0x02, 0x3c, 0x29, 0x01, 0x02, 0x40, 0x29, 0x01, 0x02, 0x44, 0x29, 0x01, 0x02, 0x48, 0x29, 0x01, 0x02, 0x14, 0x09, 0x02, 0x02, + 0x18, 0x09, 0x02, 0x02, 0x1c, 0x09, 0x02, 0x02, 0x20, 0x09, 0x02, 0x02, 0xb0, 0x25, 0x03, 0x03, 0xb8, 0x25, 0x03, 0x03, 0xc0, 0x25, 0x03, 0x03, 0xb0, 0x06, 0x04, 0x03, 0xb8, 0x06, 0x04, 0x03, + 0x70, 0x22, 0x05, 0x04, 0x50, 0x04, 0x06, 0x04, 0xa0, 0x1e, 0x07, 0x05, 0x20, 0x02, 0x08, 0x05, 0x00, 0x36, 0x0e, 0x09, 0x70, 0x3d, 0x00, 0x03, 0x78, 0x3d, 0x00, 0x03, 0x80, 0x3d, 0x00, 0x03, + 0x4c, 0x29, 0x01, 0x02, 0x50, 0x29, 0x01, 0x02, 0x54, 0x29, 0x01, 0x02, 0x58, 0x29, 0x01, 0x02, 0x5c, 0x29, 0x01, 0x02, 0x60, 0x29, 0x01, 0x02, 0x24, 0x09, 0x02, 0x02, 0x28, 0x09, 0x02, 0x02, + 0x2c, 0x09, 0x02, 0x02, 0x30, 0x09, 0x02, 0x02, 0x34, 0x09, 0x02, 0x02, 0xc8, 0x25, 0x03, 0x03, 0xd0, 0x25, 0x03, 0x03, 0xd8, 0x25, 0x03, 0x03, 0xc0, 0x06, 0x04, 0x03, 0xc8, 0x06, 0x04, 0x03, + 0x80, 0x22, 0x05, 0x04, 0x60, 0x04, 0x06, 0x04, 0xc0, 0x1e, 0x07, 0x05, 0x40, 0x02, 0x08, 0x05, 0x00, 0x10, 0x0f, 0x09, 0x88, 0x3d, 0x00, 0x03, 0x90, 0x3d, 0x00, 0x03, 0x98, 0x3d, 0x00, 0x03, + 0x64, 0x29, 0x01, 0x02, 0x68, 0x29, 0x01, 0x02, 0x6c, 0x29, 0x01, 0x02, 0x70, 0x29, 0x01, 0x02, 0x74, 0x29, 0x01, 0x02, 0x78, 0x29, 0x01, 0x02, 0x38, 0x09, 0x02, 0x02, 0x3c, 0x09, 0x02, 0x02, + 0x40, 0x09, 0x02, 0x02, 0x44, 0x09, 0x02, 0x02, 0x48, 0x09, 0x02, 0x02, 0xe0, 0x25, 0x03, 0x03, 0xe8, 0x25, 0x03, 0x03, 0xf0, 0x25, 0x03, 0x03, 0xd0, 0x06, 0x04, 0x03, 0xd8, 0x06, 0x04, 0x03, + 0x90, 0x22, 0x05, 0x04, 0x70, 0x04, 0x06, 0x04, 0xe0, 0x1e, 0x07, 0x05, 0x60, 0x02, 0x08, 0x05, 0x00, 0x12, 0x0f, 0x09, 0xa0, 0x3d, 0x00, 0x03, 0xa8, 0x3d, 0x00, 0x03, 0xb0, 0x3d, 0x00, 0x03, + 0x7c, 0x29, 0x01, 0x02, 0x80, 0x29, 0x01, 0x02, 0x84, 0x29, 0x01, 0x02, 0x88, 0x29, 0x01, 0x02, 0x8c, 0x29, 0x01, 0x02, 0x90, 0x29, 0x01, 0x02, 0x4c, 0x09, 0x02, 0x02, 0x50, 0x09, 0x02, 0x02, + 0x54, 0x09, 0x02, 0x02, 0x58, 0x09, 0x02, 0x02, 0x5c, 0x09, 0x02, 0x02, 0xf8, 0x25, 0x03, 0x03, 0x00, 0x26, 0x03, 0x03, 0x08, 0x26, 0x03, 0x03, 0xe0, 0x06, 0x04, 0x03, 0xe8, 0x06, 0x04, 0x03, + 0xa0, 0x22, 0x05, 0x04, 0x80, 0x04, 0x06, 0x04, 0x00, 0x1f, 0x07, 0x05, 0x40, 0x1b, 0x09, 0x06, 0x00, 0x14, 0x0f, 0x09, 0xb8, 0x3d, 0x00, 0x03, 0xc0, 0x3d, 0x00, 0x03, 0xc8, 0x3d, 0x00, 0x03, + 0x94, 0x29, 0x01, 0x02, 0x98, 0x29, 0x01, 0x02, 0x9c, 0x29, 0x01, 0x02, 0xa0, 0x29, 0x01, 0x02, 0xa4, 0x29, 0x01, 0x02, 0xa8, 0x29, 0x01, 0x02, 0x60, 0x09, 0x02, 0x02, 0x64, 0x09, 0x02, 0x02, + 0x68, 0x09, 0x02, 0x02, 0x6c, 0x09, 0x02, 0x02, 0x70, 0x09, 0x02, 0x02, 0x10, 0x26, 0x03, 0x03, 0x18, 0x26, 0x03, 0x03, 0x20, 0x26, 0x03, 0x03, 0xf0, 0x06, 0x04, 0x03, 0xf8, 0x06, 0x04, 0x03, + 0xb0, 0x22, 0x05, 0x04, 0x90, 0x04, 0x06, 0x04, 0x20, 0x1f, 0x07, 0x05, 0x80, 0x1b, 0x09, 0x06, 0x00, 0x16, 0x0f, 0x09, 0xd0, 0x3d, 0x00, 0x03, 0xd8, 0x3d, 0x00, 0x03, 0xe0, 0x3d, 0x00, 0x03, + 0xac, 0x29, 0x01, 0x02, 0xb0, 0x29, 0x01, 0x02, 0xb4, 0x29, 0x01, 0x02, 0xb8, 0x29, 0x01, 0x02, 0xbc, 0x29, 0x01, 0x02, 0xc0, 0x29, 0x01, 0x02, 0x74, 0x09, 0x02, 0x02, 0x78, 0x09, 0x02, 0x02, + 0x7c, 0x09, 0x02, 0x02, 0x80, 0x09, 0x02, 0x02, 0x84, 0x09, 0x02, 0x02, 0x28, 0x26, 0x03, 0x03, 0x30, 0x26, 0x03, 0x03, 0x38, 0x26, 0x03, 0x03, 0x00, 0x07, 0x04, 0x03, 0x08, 0x07, 0x04, 0x03, + 0xc0, 0x22, 0x05, 0x04, 0xa0, 0x04, 0x06, 0x04, 0x40, 0x1f, 0x07, 0x05, 0xc0, 0x1b, 0x09, 0x06, 0x00, 0x30, 0x10, 0x0a, 0xe8, 0x3d, 0x00, 0x03, 0xf0, 0x3d, 0x00, 0x03, 0xf8, 0x3d, 0x00, 0x03, + 0xc4, 0x29, 0x01, 0x02, 0xc8, 0x29, 0x01, 0x02, 0xcc, 0x29, 0x01, 0x02, 0xd0, 0x29, 0x01, 0x02, 0xd4, 0x29, 0x01, 0x02, 0xd8, 0x29, 0x01, 0x02, 0x88, 0x09, 0x02, 0x02, 0x8c, 0x09, 0x02, 0x02, + 0x90, 0x09, 0x02, 0x02, 0x94, 0x09, 0x02, 0x02, 0x98, 0x09, 0x02, 0x02, 0x40, 0x26, 0x03, 0x03, 0x48, 0x26, 0x03, 0x03, 0x50, 0x26, 0x03, 0x03, 0x10, 0x07, 0x04, 0x03, 0x18, 0x07, 0x04, 0x03, + 0xd0, 0x22, 0x05, 0x04, 0xb0, 0x04, 0x06, 0x04, 0x60, 0x1f, 0x07, 0x05, 0x00, 0x1c, 0x09, 0x06, 0x00, 0x34, 0x10, 0x0a, 0x00, 0x3e, 0x00, 0x03, 0x08, 0x3e, 0x00, 0x03, 0x10, 0x3e, 0x00, 0x03, + 0xdc, 0x29, 0x01, 0x02, 0xe0, 0x29, 0x01, 0x02, 0xe4, 0x29, 0x01, 0x02, 0xe8, 0x29, 0x01, 0x02, 0xec, 0x29, 0x01, 0x02, 0xf0, 0x29, 0x01, 0x02, 0x9c, 0x09, 0x02, 0x02, 0xa0, 0x09, 0x02, 0x02, + 0xa4, 0x09, 0x02, 0x02, 0xa8, 0x09, 0x02, 0x02, 0xac, 0x09, 0x02, 0x02, 0x58, 0x26, 0x03, 0x03, 0x60, 0x26, 0x03, 0x03, 0x68, 0x26, 0x03, 0x03, 0x20, 0x07, 0x04, 0x03, 0x28, 0x07, 0x04, 0x03, + 0xe0, 0x22, 0x05, 0x04, 0xc0, 0x04, 0x06, 0x04, 0x80, 0x1f, 0x07, 0x05, 0x40, 0x1c, 0x09, 0x06, 0x00, 0x0c, 0x11, 0x0a, 0x18, 0x3e, 0x00, 0x03, 0x20, 0x3e, 0x00, 0x03, 0x28, 0x3e, 0x00, 0x03, + 0xf4, 0x29, 0x01, 0x02, 0xf8, 0x29, 0x01, 0x02, 0xfc, 0x29, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x04, 0x2a, 0x01, 0x02, 0x08, 0x2a, 0x01, 0x02, 0xb0, 0x09, 0x02, 0x02, 0xb4, 0x09, 0x02, 0x02, + 0xb8, 0x09, 0x02, 0x02, 0xbc, 0x09, 0x02, 0x02, 0xc0, 0x09, 0x02, 0x02, 0x70, 0x26, 0x03, 0x03, 0x78, 0x26, 0x03, 0x03, 0x80, 0x26, 0x03, 0x03, 0x30, 0x07, 0x04, 0x03, 0x38, 0x07, 0x04, 0x03, + 0xf0, 0x22, 0x05, 0x04, 0xd0, 0x04, 0x06, 0x04, 0xa0, 0x1f, 0x07, 0x05, 0x80, 0x1c, 0x09, 0x06, 0x00, 0x10, 0x11, 0x0a, 0x30, 0x3e, 0x00, 0x03, 0x38, 0x3e, 0x00, 0x03, 0x40, 0x3e, 0x00, 0x03, + 0x0c, 0x2a, 0x01, 0x02, 0x10, 0x2a, 0x01, 0x02, 0x14, 0x2a, 0x01, 0x02, 0x18, 0x2a, 0x01, 0x02, 0x1c, 0x2a, 0x01, 0x02, 0x20, 0x2a, 0x01, 0x02, 0xc4, 0x09, 0x02, 0x02, 0xc8, 0x09, 0x02, 0x02, + 0xcc, 0x09, 0x02, 0x02, 0xd0, 0x09, 0x02, 0x02, 0xd4, 0x09, 0x02, 0x02, 0x88, 0x26, 0x03, 0x03, 0x90, 0x26, 0x03, 0x03, 0x98, 0x26, 0x03, 0x03, 0x40, 0x07, 0x04, 0x03, 0x48, 0x07, 0x04, 0x03, + 0x00, 0x23, 0x05, 0x04, 0xe0, 0x04, 0x06, 0x04, 0xc0, 0x1f, 0x07, 0x05, 0xc0, 0x1c, 0x09, 0x06, 0x00, 0x30, 0x12, 0x0b, 0x48, 0x3e, 0x00, 0x03, 0x50, 0x3e, 0x00, 0x03, 0x58, 0x3e, 0x00, 0x03, + 0x24, 0x2a, 0x01, 0x02, 0x28, 0x2a, 0x01, 0x02, 0x2c, 0x2a, 0x01, 0x02, 0x30, 0x2a, 0x01, 0x02, 0x34, 0x2a, 0x01, 0x02, 0x38, 0x2a, 0x01, 0x02, 0xd8, 0x09, 0x02, 0x02, 0xdc, 0x09, 0x02, 0x02, + 0xe0, 0x09, 0x02, 0x02, 0xe4, 0x09, 0x02, 0x02, 0xe8, 0x09, 0x02, 0x02, 0xa0, 0x26, 0x03, 0x03, 0xa8, 0x26, 0x03, 0x03, 0xb0, 0x26, 0x03, 0x03, 0x50, 0x07, 0x04, 0x03, 0x58, 0x07, 0x04, 0x03, + 0x10, 0x23, 0x05, 0x04, 0xf0, 0x04, 0x06, 0x04, 0xe0, 0x1f, 0x07, 0x05, 0x00, 0x1d, 0x09, 0x06, 0x00, 0x10, 0x13, 0x0b, 0x60, 0x3e, 0x00, 0x03, 0x68, 0x3e, 0x00, 0x03, 0x70, 0x3e, 0x00, 0x03, + 0x3c, 0x2a, 0x01, 0x02, 0x40, 0x2a, 0x01, 0x02, 0x44, 0x2a, 0x01, 0x02, 0x48, 0x2a, 0x01, 0x02, 0x4c, 0x2a, 0x01, 0x02, 0x50, 0x2a, 0x01, 0x02, 0xec, 0x09, 0x02, 0x02, 0xf0, 0x09, 0x02, 0x02, + 0xf4, 0x09, 0x02, 0x02, 0xf8, 0x09, 0x02, 0x02, 0xfc, 0x09, 0x02, 0x02, 0xb8, 0x26, 0x03, 0x03, 0xc0, 0x26, 0x03, 0x03, 0xc8, 0x26, 0x03, 0x03, 0x60, 0x07, 0x04, 0x03, 0x68, 0x07, 0x04, 0x03, + 0x20, 0x23, 0x05, 0x04, 0x00, 0x05, 0x06, 0x04, 0x00, 0x20, 0x07, 0x05, 0x40, 0x1d, 0x09, 0x06, 0x00, 0x20, 0x14, 0x0c, 0x78, 0x3e, 0x00, 0x03, 0x80, 0x3e, 0x00, 0x03, 0x88, 0x3e, 0x00, 0x03, + 0x54, 0x2a, 0x01, 0x02, 0x58, 0x2a, 0x01, 0x02, 0x5c, 0x2a, 0x01, 0x02, 0x60, 0x2a, 0x01, 0x02, 0x64, 0x2a, 0x01, 0x02, 0x68, 0x2a, 0x01, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x04, 0x0a, 0x02, 0x02, + 0x08, 0x0a, 0x02, 0x02, 0x0c, 0x0a, 0x02, 0x02, 0x10, 0x0a, 0x02, 0x02, 0xd0, 0x26, 0x03, 0x03, 0xd8, 0x26, 0x03, 0x03, 0xe0, 0x26, 0x03, 0x03, 0x70, 0x07, 0x04, 0x03, 0x78, 0x07, 0x04, 0x03, + 0x30, 0x23, 0x05, 0x04, 0x10, 0x05, 0x06, 0x04, 0x20, 0x20, 0x07, 0x05, 0x80, 0x1d, 0x09, 0x06, 0x90, 0x3e, 0x00, 0x03, 0x98, 0x3e, 0x00, 0x03, 0xa0, 0x3e, 0x00, 0x03, 0xa8, 0x3e, 0x00, 0x03, + 0x6c, 0x2a, 0x01, 0x02, 0x70, 0x2a, 0x01, 0x02, 0x74, 0x2a, 0x01, 0x02, 0x78, 0x2a, 0x01, 0x02, 0x7c, 0x2a, 0x01, 0x02, 0x80, 0x2a, 0x01, 0x02, 0x14, 0x0a, 0x02, 0x02, 0x18, 0x0a, 0x02, 0x02, + 0x1c, 0x0a, 0x02, 0x02, 0x20, 0x0a, 0x02, 0x02, 0x24, 0x0a, 0x02, 0x02, 0xe8, 0x26, 0x03, 0x03, 0xf0, 0x26, 0x03, 0x03, 0xf8, 0x26, 0x03, 0x03, 0x80, 0x07, 0x04, 0x03, 0x88, 0x07, 0x04, 0x03, + 0x40, 0x23, 0x05, 0x04, 0x20, 0x05, 0x06, 0x04, 0x40, 0x20, 0x07, 0x05, 0xc0, 0x1d, 0x09, 0x06, 0xb0, 0x3e, 0x00, 0x03, 0xb8, 0x3e, 0x00, 0x03, 0xc0, 0x3e, 0x00, 0x03, 0xc8, 0x3e, 0x00, 0x03, + 0x84, 0x2a, 0x01, 0x02, 0x88, 0x2a, 0x01, 0x02, 0x8c, 0x2a, 0x01, 0x02, 0x90, 0x2a, 0x01, 0x02, 0x94, 0x2a, 0x01, 0x02, 0x98, 0x2a, 0x01, 0x02, 0x28, 0x0a, 0x02, 0x02, 0x2c, 0x0a, 0x02, 0x02, + 0x30, 0x0a, 0x02, 0x02, 0x34, 0x0a, 0x02, 0x02, 0x38, 0x0a, 0x02, 0x02, 0x00, 0x27, 0x03, 0x03, 0x08, 0x27, 0x03, 0x03, 0x10, 0x27, 0x03, 0x03, 0x90, 0x07, 0x04, 0x03, 0x98, 0x07, 0x04, 0x03, + 0x50, 0x23, 0x05, 0x04, 0x30, 0x05, 0x06, 0x04, 0x60, 0x20, 0x07, 0x05, 0x00, 0x1e, 0x09, 0x06, 0xd0, 0x3e, 0x00, 0x03, 0xd8, 0x3e, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x03, 0xe8, 0x3e, 0x00, 0x03, + 0x9c, 0x2a, 0x01, 0x02, 0xa0, 0x2a, 0x01, 0x02, 0xa4, 0x2a, 0x01, 0x02, 0xa8, 0x2a, 0x01, 0x02, 0xac, 0x2a, 0x01, 0x02, 0xb0, 0x2a, 0x01, 0x02, 0x3c, 0x0a, 0x02, 0x02, 0x40, 0x0a, 0x02, 0x02, + 0x44, 0x0a, 0x02, 0x02, 0x48, 0x0a, 0x02, 0x02, 0x4c, 0x0a, 0x02, 0x02, 0x18, 0x27, 0x03, 0x03, 0x20, 0x27, 0x03, 0x03, 0x28, 0x27, 0x03, 0x03, 0xa0, 0x07, 0x04, 0x03, 0xa8, 0x07, 0x04, 0x03, + 0x60, 0x23, 0x05, 0x04, 0x40, 0x05, 0x06, 0x04, 0x80, 0x20, 0x07, 0x05, 0x40, 0x1e, 0x09, 0x06, 0xf0, 0x3e, 0x00, 0x03, 0xf8, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x03, 0x08, 0x3f, 0x00, 0x03, + 0xb4, 0x2a, 0x01, 0x02, 0xb8, 0x2a, 0x01, 0x02, 0xbc, 0x2a, 0x01, 0x02, 0xc0, 0x2a, 0x01, 0x02, 0xc4, 0x2a, 0x01, 0x02, 0xc8, 0x2a, 0x01, 0x02, 0x50, 0x0a, 0x02, 0x02, 0x54, 0x0a, 0x02, 0x02, + 0x58, 0x0a, 0x02, 0x02, 0x5c, 0x0a, 0x02, 0x02, 0x60, 0x0a, 0x02, 0x02, 0x30, 0x27, 0x03, 0x03, 0x38, 0x27, 0x03, 0x03, 0x40, 0x27, 0x03, 0x03, 0xb0, 0x07, 0x04, 0x03, 0xb8, 0x07, 0x04, 0x03, + 0x70, 0x23, 0x05, 0x04, 0x50, 0x05, 0x06, 0x04, 0xa0, 0x20, 0x07, 0x05, 0x80, 0x1e, 0x09, 0x06, 0x10, 0x3f, 0x00, 0x03, 0x18, 0x3f, 0x00, 0x03, 0x20, 0x3f, 0x00, 0x03, 0x28, 0x3f, 0x00, 0x03, + 0xcc, 0x2a, 0x01, 0x02, 0xd0, 0x2a, 0x01, 0x02, 0xd4, 0x2a, 0x01, 0x02, 0xd8, 0x2a, 0x01, 0x02, 0xdc, 0x2a, 0x01, 0x02, 0xe0, 0x2a, 0x01, 0x02, 0x64, 0x0a, 0x02, 0x02, 0x68, 0x0a, 0x02, 0x02, + 0x6c, 0x0a, 0x02, 0x02, 0x70, 0x0a, 0x02, 0x02, 0x74, 0x0a, 0x02, 0x02, 0x48, 0x27, 0x03, 0x03, 0x50, 0x27, 0x03, 0x03, 0x58, 0x27, 0x03, 0x03, 0xc0, 0x07, 0x04, 0x03, 0xc8, 0x07, 0x04, 0x03, + 0x80, 0x23, 0x05, 0x04, 0x60, 0x05, 0x06, 0x04, 0xc0, 0x20, 0x07, 0x05, 0xc0, 0x1e, 0x09, 0x06, 0x30, 0x3f, 0x00, 0x03, 0x38, 0x3f, 0x00, 0x03, 0x40, 0x3f, 0x00, 0x03, 0x48, 0x3f, 0x00, 0x03, + 0xe4, 0x2a, 0x01, 0x02, 0xe8, 0x2a, 0x01, 0x02, 0xec, 0x2a, 0x01, 0x02, 0xf0, 0x2a, 0x01, 0x02, 0xf4, 0x2a, 0x01, 0x02, 0xf8, 0x2a, 0x01, 0x02, 0x78, 0x0a, 0x02, 0x02, 0x7c, 0x0a, 0x02, 0x02, + 0x80, 0x0a, 0x02, 0x02, 0x84, 0x0a, 0x02, 0x02, 0x88, 0x0a, 0x02, 0x02, 0x60, 0x27, 0x03, 0x03, 0x68, 0x27, 0x03, 0x03, 0x70, 0x27, 0x03, 0x03, 0xd0, 0x07, 0x04, 0x03, 0xd8, 0x07, 0x04, 0x03, + 0x90, 0x23, 0x05, 0x04, 0x70, 0x05, 0x06, 0x04, 0xe0, 0x20, 0x07, 0x05, 0x00, 0x1f, 0x09, 0x06, 0x50, 0x3f, 0x00, 0x03, 0x58, 0x3f, 0x00, 0x03, 0x60, 0x3f, 0x00, 0x03, 0x68, 0x3f, 0x00, 0x03, + 0xfc, 0x2a, 0x01, 0x02, 0x00, 0x2b, 0x01, 0x02, 0x04, 0x2b, 0x01, 0x02, 0x08, 0x2b, 0x01, 0x02, 0x0c, 0x2b, 0x01, 0x02, 0x10, 0x2b, 0x01, 0x02, 0x8c, 0x0a, 0x02, 0x02, 0x90, 0x0a, 0x02, 0x02, + 0x94, 0x0a, 0x02, 0x02, 0x98, 0x0a, 0x02, 0x02, 0x9c, 0x0a, 0x02, 0x02, 0x78, 0x27, 0x03, 0x03, 0x80, 0x27, 0x03, 0x03, 0x88, 0x27, 0x03, 0x03, 0xe0, 0x07, 0x04, 0x03, 0xe8, 0x07, 0x04, 0x03, + 0xa0, 0x23, 0x05, 0x04, 0x80, 0x05, 0x06, 0x04, 0x00, 0x21, 0x07, 0x05, 0x40, 0x1f, 0x09, 0x06, 0x70, 0x3f, 0x00, 0x03, 0x78, 0x3f, 0x00, 0x03, 0x80, 0x3f, 0x00, 0x03, 0x88, 0x3f, 0x00, 0x03, + 0x14, 0x2b, 0x01, 0x02, 0x18, 0x2b, 0x01, 0x02, 0x1c, 0x2b, 0x01, 0x02, 0x20, 0x2b, 0x01, 0x02, 0x24, 0x2b, 0x01, 0x02, 0x28, 0x2b, 0x01, 0x02, 0xa0, 0x0a, 0x02, 0x02, 0xa4, 0x0a, 0x02, 0x02, + 0xa8, 0x0a, 0x02, 0x02, 0xac, 0x0a, 0x02, 0x02, 0xb0, 0x0a, 0x02, 0x02, 0x90, 0x27, 0x03, 0x03, 0x98, 0x27, 0x03, 0x03, 0xa0, 0x27, 0x03, 0x03, 0xf0, 0x07, 0x04, 0x03, 0xf8, 0x07, 0x04, 0x03, + 0xb0, 0x23, 0x05, 0x04, 0x90, 0x05, 0x06, 0x04, 0x20, 0x21, 0x07, 0x05, 0x80, 0x1f, 0x09, 0x06, 0x90, 0x3f, 0x00, 0x03, 0x98, 0x3f, 0x00, 0x03, 0xa0, 0x3f, 0x00, 0x03, 0xa8, 0x3f, 0x00, 0x03, + 0x2c, 0x2b, 0x01, 0x02, 0x30, 0x2b, 0x01, 0x02, 0x34, 0x2b, 0x01, 0x02, 0x38, 0x2b, 0x01, 0x02, 0x3c, 0x2b, 0x01, 0x02, 0x40, 0x2b, 0x01, 0x02, 0xb4, 0x0a, 0x02, 0x02, 0xb8, 0x0a, 0x02, 0x02, + 0xbc, 0x0a, 0x02, 0x02, 0xc0, 0x0a, 0x02, 0x02, 0xc4, 0x0a, 0x02, 0x02, 0xa8, 0x27, 0x03, 0x03, 0xb0, 0x27, 0x03, 0x03, 0xb8, 0x27, 0x03, 0x03, 0x00, 0x08, 0x04, 0x03, 0x08, 0x08, 0x04, 0x03, + 0xc0, 0x23, 0x05, 0x04, 0xa0, 0x05, 0x06, 0x04, 0x40, 0x21, 0x07, 0x05, 0xc0, 0x1f, 0x09, 0x06, 0xb0, 0x3f, 0x00, 0x03, 0xb8, 0x3f, 0x00, 0x03, 0xc0, 0x3f, 0x00, 0x03, 0xc8, 0x3f, 0x00, 0x03, + 0x44, 0x2b, 0x01, 0x02, 0x48, 0x2b, 0x01, 0x02, 0x4c, 0x2b, 0x01, 0x02, 0x50, 0x2b, 0x01, 0x02, 0x54, 0x2b, 0x01, 0x02, 0x58, 0x2b, 0x01, 0x02, 0xc8, 0x0a, 0x02, 0x02, 0xcc, 0x0a, 0x02, 0x02, + 0xd0, 0x0a, 0x02, 0x02, 0xd4, 0x0a, 0x02, 0x02, 0xd8, 0x0a, 0x02, 0x02, 0xc0, 0x27, 0x03, 0x03, 0xc8, 0x27, 0x03, 0x03, 0xd0, 0x27, 0x03, 0x03, 0x10, 0x08, 0x04, 0x03, 0x18, 0x08, 0x04, 0x03, + 0xd0, 0x23, 0x05, 0x04, 0xb0, 0x05, 0x06, 0x04, 0x60, 0x21, 0x07, 0x05, 0x00, 0x20, 0x09, 0x06, 0xd0, 0x3f, 0x00, 0x03, 0xd8, 0x3f, 0x00, 0x03, 0xe0, 0x3f, 0x00, 0x03, 0xe8, 0x3f, 0x00, 0x03, + 0x5c, 0x2b, 0x01, 0x02, 0x60, 0x2b, 0x01, 0x02, 0x64, 0x2b, 0x01, 0x02, 0x68, 0x2b, 0x01, 0x02, 0x6c, 0x2b, 0x01, 0x02, 0x70, 0x2b, 0x01, 0x02, 0xdc, 0x0a, 0x02, 0x02, 0xe0, 0x0a, 0x02, 0x02, + 0xe4, 0x0a, 0x02, 0x02, 0xe8, 0x0a, 0x02, 0x02, 0xec, 0x0a, 0x02, 0x02, 0xd8, 0x27, 0x03, 0x03, 0xe0, 0x27, 0x03, 0x03, 0xe8, 0x27, 0x03, 0x03, 0x20, 0x08, 0x04, 0x03, 0x28, 0x08, 0x04, 0x03, + 0xe0, 0x23, 0x05, 0x04, 0xc0, 0x05, 0x06, 0x04, 0x80, 0x21, 0x07, 0x05, 0x40, 0x20, 0x09, 0x06, 0xf0, 0x3f, 0x00, 0x03, 0xf8, 0x3f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, + 0x74, 0x2b, 0x01, 0x02, 0x78, 0x2b, 0x01, 0x02, 0x7c, 0x2b, 0x01, 0x02, 0x80, 0x2b, 0x01, 0x02, 0x84, 0x2b, 0x01, 0x02, 0x88, 0x2b, 0x01, 0x02, 0xf0, 0x0a, 0x02, 0x02, 0xf4, 0x0a, 0x02, 0x02, + 0xf8, 0x0a, 0x02, 0x02, 0xfc, 0x0a, 0x02, 0x02, 0x00, 0x0b, 0x02, 0x02, 0xf0, 0x27, 0x03, 0x03, 0xf8, 0x27, 0x03, 0x03, 0x00, 0x28, 0x03, 0x03, 0x30, 0x08, 0x04, 0x03, 0x38, 0x08, 0x04, 0x03, + 0xf0, 0x23, 0x05, 0x04, 0xd0, 0x05, 0x06, 0x04, 0xa0, 0x21, 0x07, 0x05, 0x80, 0x20, 0x09, 0x06, 0x08, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x02, + 0x8c, 0x2b, 0x01, 0x02, 0x90, 0x2b, 0x01, 0x02, 0x94, 0x2b, 0x01, 0x02, 0x98, 0x2b, 0x01, 0x02, 0x9c, 0x2b, 0x01, 0x02, 0xa0, 0x2b, 0x01, 0x02, 0x04, 0x0b, 0x02, 0x02, 0x08, 0x0b, 0x02, 0x02, + 0x0c, 0x0b, 0x02, 0x02, 0x10, 0x0b, 0x02, 0x02, 0x14, 0x0b, 0x02, 0x02, 0x08, 0x28, 0x03, 0x03, 0x10, 0x28, 0x03, 0x03, 0x18, 0x28, 0x03, 0x03, 0x40, 0x08, 0x04, 0x03, 0x48, 0x08, 0x04, 0x03, + 0x00, 0x24, 0x05, 0x04, 0xe0, 0x05, 0x06, 0x04, 0xc0, 0x21, 0x07, 0x05, 0xc0, 0x20, 0x09, 0x06, 0x18, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x02, + 0xa4, 0x2b, 0x01, 0x02, 0xa8, 0x2b, 0x01, 0x02, 0xac, 0x2b, 0x01, 0x02, 0xb0, 0x2b, 0x01, 0x02, 0xb4, 0x2b, 0x01, 0x02, 0xb8, 0x2b, 0x01, 0x02, 0x18, 0x0b, 0x02, 0x02, 0x1c, 0x0b, 0x02, 0x02, + 0x20, 0x0b, 0x02, 0x02, 0x24, 0x0b, 0x02, 0x02, 0x28, 0x0b, 0x02, 0x02, 0x20, 0x28, 0x03, 0x03, 0x28, 0x28, 0x03, 0x03, 0x30, 0x28, 0x03, 0x03, 0x50, 0x08, 0x04, 0x03, 0x58, 0x08, 0x04, 0x03, + 0x10, 0x24, 0x05, 0x04, 0xf0, 0x05, 0x06, 0x04, 0xe0, 0x21, 0x07, 0x05, 0x00, 0x21, 0x09, 0x06, 0x28, 0x00, 0x00, 0x02, 0x2c, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x02, 0x34, 0x00, 0x00, 0x02, + 0xbc, 0x2b, 0x01, 0x02, 0xc0, 0x2b, 0x01, 0x02, 0xc4, 0x2b, 0x01, 0x02, 0xc8, 0x2b, 0x01, 0x02, 0xcc, 0x2b, 0x01, 0x02, 0xd0, 0x2b, 0x01, 0x02, 0x2c, 0x0b, 0x02, 0x02, 0x30, 0x0b, 0x02, 0x02, + 0x34, 0x0b, 0x02, 0x02, 0x38, 0x0b, 0x02, 0x02, 0x3c, 0x0b, 0x02, 0x02, 0x38, 0x28, 0x03, 0x03, 0x40, 0x28, 0x03, 0x03, 0x48, 0x28, 0x03, 0x03, 0x60, 0x08, 0x04, 0x03, 0x68, 0x08, 0x04, 0x03, + 0x20, 0x24, 0x05, 0x04, 0x00, 0x06, 0x06, 0x04, 0x00, 0x22, 0x07, 0x05, 0x40, 0x21, 0x09, 0x06, 0x38, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x44, 0x00, 0x00, 0x02, + 0xd4, 0x2b, 0x01, 0x02, 0xd8, 0x2b, 0x01, 0x02, 0xdc, 0x2b, 0x01, 0x02, 0xe0, 0x2b, 0x01, 0x02, 0xe4, 0x2b, 0x01, 0x02, 0xe8, 0x2b, 0x01, 0x02, 0x40, 0x0b, 0x02, 0x02, 0x44, 0x0b, 0x02, 0x02, + 0x48, 0x0b, 0x02, 0x02, 0x4c, 0x0b, 0x02, 0x02, 0x50, 0x28, 0x03, 0x03, 0x58, 0x28, 0x03, 0x03, 0x60, 0x28, 0x03, 0x03, 0x70, 0x08, 0x04, 0x03, 0x78, 0x08, 0x04, 0x03, 0x80, 0x08, 0x04, 0x03, + 0x30, 0x24, 0x05, 0x04, 0x10, 0x06, 0x06, 0x04, 0x20, 0x22, 0x07, 0x05, 0x80, 0x21, 0x09, 0x06, 0x48, 0x00, 0x00, 0x02, 0x4c, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x02, + 0xec, 0x2b, 0x01, 0x02, 0xf0, 0x2b, 0x01, 0x02, 0xf4, 0x2b, 0x01, 0x02, 0xf8, 0x2b, 0x01, 0x02, 0xfc, 0x2b, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x50, 0x0b, 0x02, 0x02, 0x54, 0x0b, 0x02, 0x02, + 0x58, 0x0b, 0x02, 0x02, 0x5c, 0x0b, 0x02, 0x02, 0x68, 0x28, 0x03, 0x03, 0x70, 0x28, 0x03, 0x03, 0x78, 0x28, 0x03, 0x03, 0x88, 0x08, 0x04, 0x03, 0x90, 0x08, 0x04, 0x03, 0x98, 0x08, 0x04, 0x03, + 0x40, 0x24, 0x05, 0x04, 0x20, 0x06, 0x06, 0x04, 0x40, 0x22, 0x07, 0x05, 0xc0, 0x21, 0x09, 0x06, 0x58, 0x00, 0x00, 0x02, 0x5c, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x02, 0x64, 0x00, 0x00, 0x02, + 0x04, 0x2c, 0x01, 0x02, 0x08, 0x2c, 0x01, 0x02, 0x0c, 0x2c, 0x01, 0x02, 0x10, 0x2c, 0x01, 0x02, 0x14, 0x2c, 0x01, 0x02, 0x18, 0x2c, 0x01, 0x02, 0x60, 0x0b, 0x02, 0x02, 0x64, 0x0b, 0x02, 0x02, + 0x68, 0x0b, 0x02, 0x02, 0x6c, 0x0b, 0x02, 0x02, 0x80, 0x28, 0x03, 0x03, 0x88, 0x28, 0x03, 0x03, 0x90, 0x28, 0x03, 0x03, 0xa0, 0x08, 0x04, 0x03, 0xa8, 0x08, 0x04, 0x03, 0xb0, 0x08, 0x04, 0x03, + 0x50, 0x24, 0x05, 0x04, 0x30, 0x06, 0x06, 0x04, 0x60, 0x22, 0x07, 0x05, 0x00, 0x22, 0x09, 0x06, 0x68, 0x00, 0x00, 0x02, 0x6c, 0x00, 0x00, 0x02, 0x70, 0x00, 0x00, 0x02, 0x74, 0x00, 0x00, 0x02, + 0x1c, 0x2c, 0x01, 0x02, 0x20, 0x2c, 0x01, 0x02, 0x24, 0x2c, 0x01, 0x02, 0x28, 0x2c, 0x01, 0x02, 0x2c, 0x2c, 0x01, 0x02, 0x30, 0x2c, 0x01, 0x02, 0x70, 0x0b, 0x02, 0x02, 0x74, 0x0b, 0x02, 0x02, + 0x78, 0x0b, 0x02, 0x02, 0x7c, 0x0b, 0x02, 0x02, 0x98, 0x28, 0x03, 0x03, 0xa0, 0x28, 0x03, 0x03, 0xa8, 0x28, 0x03, 0x03, 0xb8, 0x08, 0x04, 0x03, 0xc0, 0x08, 0x04, 0x03, 0xc8, 0x08, 0x04, 0x03, + 0x60, 0x24, 0x05, 0x04, 0x40, 0x06, 0x06, 0x04, 0x80, 0x22, 0x07, 0x05, 0x40, 0x22, 0x09, 0x06, 0x78, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x02, 0x84, 0x00, 0x00, 0x02, + 0x34, 0x2c, 0x01, 0x02, 0x38, 0x2c, 0x01, 0x02, 0x3c, 0x2c, 0x01, 0x02, 0x40, 0x2c, 0x01, 0x02, 0x44, 0x2c, 0x01, 0x02, 0x48, 0x2c, 0x01, 0x02, 0x80, 0x0b, 0x02, 0x02, 0x84, 0x0b, 0x02, 0x02, + 0x88, 0x0b, 0x02, 0x02, 0x8c, 0x0b, 0x02, 0x02, 0xb0, 0x28, 0x03, 0x03, 0xb8, 0x28, 0x03, 0x03, 0xc0, 0x28, 0x03, 0x03, 0xd0, 0x08, 0x04, 0x03, 0xd8, 0x08, 0x04, 0x03, 0xe0, 0x08, 0x04, 0x03, + 0x70, 0x24, 0x05, 0x04, 0x50, 0x06, 0x06, 0x04, 0xa0, 0x22, 0x07, 0x05, 0x40, 0x00, 0x0a, 0x06, 0x88, 0x00, 0x00, 0x02, 0x8c, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, 0x94, 0x00, 0x00, 0x02, + 0x4c, 0x2c, 0x01, 0x02, 0x50, 0x2c, 0x01, 0x02, 0x54, 0x2c, 0x01, 0x02, 0x58, 0x2c, 0x01, 0x02, 0x5c, 0x2c, 0x01, 0x02, 0x60, 0x2c, 0x01, 0x02, 0x90, 0x0b, 0x02, 0x02, 0x94, 0x0b, 0x02, 0x02, + 0x98, 0x0b, 0x02, 0x02, 0x9c, 0x0b, 0x02, 0x02, 0xc8, 0x28, 0x03, 0x03, 0xd0, 0x28, 0x03, 0x03, 0xd8, 0x28, 0x03, 0x03, 0xe8, 0x08, 0x04, 0x03, 0xf0, 0x08, 0x04, 0x03, 0xf8, 0x08, 0x04, 0x03, + 0x80, 0x24, 0x05, 0x04, 0x60, 0x06, 0x06, 0x04, 0xc0, 0x22, 0x07, 0x05, 0x80, 0x00, 0x0a, 0x06, 0x98, 0x00, 0x00, 0x02, 0x9c, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x02, 0xa4, 0x00, 0x00, 0x02, + 0x64, 0x2c, 0x01, 0x02, 0x68, 0x2c, 0x01, 0x02, 0x6c, 0x2c, 0x01, 0x02, 0x70, 0x2c, 0x01, 0x02, 0x74, 0x2c, 0x01, 0x02, 0x78, 0x2c, 0x01, 0x02, 0xa0, 0x0b, 0x02, 0x02, 0xa4, 0x0b, 0x02, 0x02, + 0xa8, 0x0b, 0x02, 0x02, 0xac, 0x0b, 0x02, 0x02, 0xe0, 0x28, 0x03, 0x03, 0xe8, 0x28, 0x03, 0x03, 0xf0, 0x28, 0x03, 0x03, 0x00, 0x09, 0x04, 0x03, 0x08, 0x09, 0x04, 0x03, 0x10, 0x09, 0x04, 0x03, + 0x90, 0x24, 0x05, 0x04, 0x70, 0x06, 0x06, 0x04, 0xe0, 0x22, 0x07, 0x05, 0xc0, 0x00, 0x0a, 0x06, 0xa8, 0x00, 0x00, 0x02, 0xac, 0x00, 0x00, 0x02, 0xb0, 0x00, 0x00, 0x02, 0xb4, 0x00, 0x00, 0x02, + 0x7c, 0x2c, 0x01, 0x02, 0x80, 0x2c, 0x01, 0x02, 0x84, 0x2c, 0x01, 0x02, 0x88, 0x2c, 0x01, 0x02, 0x8c, 0x2c, 0x01, 0x02, 0x90, 0x2c, 0x01, 0x02, 0xb0, 0x0b, 0x02, 0x02, 0xb4, 0x0b, 0x02, 0x02, + 0xb8, 0x0b, 0x02, 0x02, 0xbc, 0x0b, 0x02, 0x02, 0xf8, 0x28, 0x03, 0x03, 0x00, 0x29, 0x03, 0x03, 0x08, 0x29, 0x03, 0x03, 0x18, 0x09, 0x04, 0x03, 0x20, 0x09, 0x04, 0x03, 0xa0, 0x24, 0x05, 0x04, + 0xb0, 0x24, 0x05, 0x04, 0x80, 0x06, 0x06, 0x04, 0x00, 0x23, 0x07, 0x05, 0x00, 0x01, 0x0a, 0x06, 0xb8, 0x00, 0x00, 0x02, 0xbc, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x02, + 0x94, 0x2c, 0x01, 0x02, 0x98, 0x2c, 0x01, 0x02, 0x9c, 0x2c, 0x01, 0x02, 0xa0, 0x2c, 0x01, 0x02, 0xa4, 0x2c, 0x01, 0x02, 0xa8, 0x2c, 0x01, 0x02, 0xc0, 0x0b, 0x02, 0x02, 0xc4, 0x0b, 0x02, 0x02, + 0xc8, 0x0b, 0x02, 0x02, 0xcc, 0x0b, 0x02, 0x02, 0x10, 0x29, 0x03, 0x03, 0x18, 0x29, 0x03, 0x03, 0x20, 0x29, 0x03, 0x03, 0x28, 0x09, 0x04, 0x03, 0x30, 0x09, 0x04, 0x03, 0xc0, 0x24, 0x05, 0x04, + 0xd0, 0x24, 0x05, 0x04, 0x90, 0x06, 0x06, 0x04, 0x20, 0x23, 0x07, 0x05, 0x40, 0x01, 0x0a, 0x06, 0xc8, 0x00, 0x00, 0x02, 0xcc, 0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x02, 0xd4, 0x00, 0x00, 0x02, + 0xac, 0x2c, 0x01, 0x02, 0xb0, 0x2c, 0x01, 0x02, 0xb4, 0x2c, 0x01, 0x02, 0xb8, 0x2c, 0x01, 0x02, 0xbc, 0x2c, 0x01, 0x02, 0xc0, 0x2c, 0x01, 0x02, 0xd0, 0x0b, 0x02, 0x02, 0xd4, 0x0b, 0x02, 0x02, + 0xd8, 0x0b, 0x02, 0x02, 0xdc, 0x0b, 0x02, 0x02, 0x28, 0x29, 0x03, 0x03, 0x30, 0x29, 0x03, 0x03, 0x38, 0x29, 0x03, 0x03, 0x38, 0x09, 0x04, 0x03, 0x40, 0x09, 0x04, 0x03, 0xe0, 0x24, 0x05, 0x04, + 0xf0, 0x24, 0x05, 0x04, 0xa0, 0x06, 0x06, 0x04, 0x40, 0x23, 0x07, 0x05, 0x80, 0x01, 0x0a, 0x06, 0xd8, 0x00, 0x00, 0x02, 0xdc, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, 0xe4, 0x00, 0x00, 0x02, + 0xc4, 0x2c, 0x01, 0x02, 0xc8, 0x2c, 0x01, 0x02, 0xcc, 0x2c, 0x01, 0x02, 0xd0, 0x2c, 0x01, 0x02, 0xd4, 0x2c, 0x01, 0x02, 0xd8, 0x2c, 0x01, 0x02, 0xe0, 0x0b, 0x02, 0x02, 0xe4, 0x0b, 0x02, 0x02, + 0xe8, 0x0b, 0x02, 0x02, 0xec, 0x0b, 0x02, 0x02, 0x40, 0x29, 0x03, 0x03, 0x48, 0x29, 0x03, 0x03, 0x50, 0x29, 0x03, 0x03, 0x48, 0x09, 0x04, 0x03, 0x50, 0x09, 0x04, 0x03, 0x00, 0x25, 0x05, 0x04, + 0x10, 0x25, 0x05, 0x04, 0xb0, 0x06, 0x06, 0x04, 0x60, 0x23, 0x07, 0x05, 0xc0, 0x01, 0x0a, 0x06, 0xe8, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x02, 0xf0, 0x00, 0x00, 0x02, 0xf4, 0x00, 0x00, 0x02, + 0xdc, 0x2c, 0x01, 0x02, 0xe0, 0x2c, 0x01, 0x02, 0xe4, 0x2c, 0x01, 0x02, 0xe8, 0x2c, 0x01, 0x02, 0xec, 0x2c, 0x01, 0x02, 0xf0, 0x2c, 0x01, 0x02, 0xf0, 0x0b, 0x02, 0x02, 0xf4, 0x0b, 0x02, 0x02, + 0xf8, 0x0b, 0x02, 0x02, 0xfc, 0x0b, 0x02, 0x02, 0x58, 0x29, 0x03, 0x03, 0x60, 0x29, 0x03, 0x03, 0x68, 0x29, 0x03, 0x03, 0x58, 0x09, 0x04, 0x03, 0x60, 0x09, 0x04, 0x03, 0x20, 0x25, 0x05, 0x04, + 0x30, 0x25, 0x05, 0x04, 0xc0, 0x06, 0x06, 0x04, 0x80, 0x23, 0x07, 0x05, 0x00, 0x02, 0x0a, 0x06, 0xf8, 0x00, 0x00, 0x02, 0xfc, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02, + 0xf4, 0x2c, 0x01, 0x02, 0xf8, 0x2c, 0x01, 0x02, 0xfc, 0x2c, 0x01, 0x02, 0x00, 0x2d, 0x01, 0x02, 0x04, 0x2d, 0x01, 0x02, 0x08, 0x2d, 0x01, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x04, 0x0c, 0x02, 0x02, + 0x08, 0x0c, 0x02, 0x02, 0x0c, 0x0c, 0x02, 0x02, 0x70, 0x29, 0x03, 0x03, 0x78, 0x29, 0x03, 0x03, 0x80, 0x29, 0x03, 0x03, 0x68, 0x09, 0x04, 0x03, 0x70, 0x09, 0x04, 0x03, 0x40, 0x25, 0x05, 0x04, + 0x50, 0x25, 0x05, 0x04, 0xd0, 0x06, 0x06, 0x04, 0xa0, 0x23, 0x07, 0x05, 0x40, 0x02, 0x0a, 0x06, 0x08, 0x01, 0x00, 0x02, 0x0c, 0x01, 0x00, 0x02, 0x10, 0x01, 0x00, 0x02, 0x14, 0x01, 0x00, 0x02, + 0x0c, 0x2d, 0x01, 0x02, 0x10, 0x2d, 0x01, 0x02, 0x14, 0x2d, 0x01, 0x02, 0x18, 0x2d, 0x01, 0x02, 0x1c, 0x2d, 0x01, 0x02, 0x20, 0x2d, 0x01, 0x02, 0x10, 0x0c, 0x02, 0x02, 0x14, 0x0c, 0x02, 0x02, + 0x18, 0x0c, 0x02, 0x02, 0x1c, 0x0c, 0x02, 0x02, 0x88, 0x29, 0x03, 0x03, 0x90, 0x29, 0x03, 0x03, 0x98, 0x29, 0x03, 0x03, 0x78, 0x09, 0x04, 0x03, 0x80, 0x09, 0x04, 0x03, 0x60, 0x25, 0x05, 0x04, + 0x70, 0x25, 0x05, 0x04, 0xe0, 0x06, 0x06, 0x04, 0xc0, 0x23, 0x07, 0x05, 0x80, 0x02, 0x0a, 0x06, 0x18, 0x01, 0x00, 0x02, 0x1c, 0x01, 0x00, 0x02, 0x20, 0x01, 0x00, 0x02, 0x24, 0x01, 0x00, 0x02, + 0x24, 0x2d, 0x01, 0x02, 0x28, 0x2d, 0x01, 0x02, 0x2c, 0x2d, 0x01, 0x02, 0x30, 0x2d, 0x01, 0x02, 0x34, 0x2d, 0x01, 0x02, 0x38, 0x2d, 0x01, 0x02, 0x20, 0x0c, 0x02, 0x02, 0x24, 0x0c, 0x02, 0x02, + 0x28, 0x0c, 0x02, 0x02, 0x2c, 0x0c, 0x02, 0x02, 0xa0, 0x29, 0x03, 0x03, 0xa8, 0x29, 0x03, 0x03, 0xb0, 0x29, 0x03, 0x03, 0x88, 0x09, 0x04, 0x03, 0x90, 0x09, 0x04, 0x03, 0x80, 0x25, 0x05, 0x04, + 0x90, 0x25, 0x05, 0x04, 0xf0, 0x06, 0x06, 0x04, 0xe0, 0x23, 0x07, 0x05, 0xc0, 0x02, 0x0a, 0x06, 0x28, 0x01, 0x00, 0x02, 0x2c, 0x01, 0x00, 0x02, 0x30, 0x01, 0x00, 0x02, 0x34, 0x01, 0x00, 0x02, + 0x3c, 0x2d, 0x01, 0x02, 0x40, 0x2d, 0x01, 0x02, 0x44, 0x2d, 0x01, 0x02, 0x48, 0x2d, 0x01, 0x02, 0x4c, 0x2d, 0x01, 0x02, 0x50, 0x2d, 0x01, 0x02, 0x30, 0x0c, 0x02, 0x02, 0x34, 0x0c, 0x02, 0x02, + 0x38, 0x0c, 0x02, 0x02, 0x3c, 0x0c, 0x02, 0x02, 0xb8, 0x29, 0x03, 0x03, 0xc0, 0x29, 0x03, 0x03, 0xc8, 0x29, 0x03, 0x03, 0x98, 0x09, 0x04, 0x03, 0xa0, 0x09, 0x04, 0x03, 0xa0, 0x25, 0x05, 0x04, + 0xb0, 0x25, 0x05, 0x04, 0x00, 0x07, 0x06, 0x04, 0x00, 0x24, 0x07, 0x05, 0x00, 0x03, 0x0a, 0x06, 0x38, 0x01, 0x00, 0x02, 0x3c, 0x01, 0x00, 0x02, 0x40, 0x01, 0x00, 0x02, 0x44, 0x01, 0x00, 0x02, + 0x54, 0x2d, 0x01, 0x02, 0x58, 0x2d, 0x01, 0x02, 0x5c, 0x2d, 0x01, 0x02, 0x60, 0x2d, 0x01, 0x02, 0x64, 0x2d, 0x01, 0x02, 0x68, 0x2d, 0x01, 0x02, 0x40, 0x0c, 0x02, 0x02, 0x44, 0x0c, 0x02, 0x02, + 0x48, 0x0c, 0x02, 0x02, 0x4c, 0x0c, 0x02, 0x02, 0xd0, 0x29, 0x03, 0x03, 0xd8, 0x29, 0x03, 0x03, 0xe0, 0x29, 0x03, 0x03, 0xa8, 0x09, 0x04, 0x03, 0xb0, 0x09, 0x04, 0x03, 0xc0, 0x25, 0x05, 0x04, + 0xd0, 0x25, 0x05, 0x04, 0x10, 0x07, 0x06, 0x04, 0x20, 0x24, 0x07, 0x05, 0x40, 0x03, 0x0a, 0x06, 0x48, 0x01, 0x00, 0x02, 0x4c, 0x01, 0x00, 0x02, 0x50, 0x01, 0x00, 0x02, 0x54, 0x01, 0x00, 0x02, + 0x6c, 0x2d, 0x01, 0x02, 0x70, 0x2d, 0x01, 0x02, 0x74, 0x2d, 0x01, 0x02, 0x78, 0x2d, 0x01, 0x02, 0x7c, 0x2d, 0x01, 0x02, 0x80, 0x2d, 0x01, 0x02, 0x50, 0x0c, 0x02, 0x02, 0x54, 0x0c, 0x02, 0x02, + 0x58, 0x0c, 0x02, 0x02, 0x5c, 0x0c, 0x02, 0x02, 0xe8, 0x29, 0x03, 0x03, 0xf0, 0x29, 0x03, 0x03, 0xf8, 0x29, 0x03, 0x03, 0xb8, 0x09, 0x04, 0x03, 0xc0, 0x09, 0x04, 0x03, 0xe0, 0x25, 0x05, 0x04, + 0xf0, 0x25, 0x05, 0x04, 0x20, 0x07, 0x06, 0x04, 0x40, 0x24, 0x07, 0x05, 0x80, 0x03, 0x0a, 0x06, 0x58, 0x01, 0x00, 0x02, 0x5c, 0x01, 0x00, 0x02, 0x60, 0x01, 0x00, 0x02, 0x64, 0x01, 0x00, 0x02, + 0x84, 0x2d, 0x01, 0x02, 0x88, 0x2d, 0x01, 0x02, 0x8c, 0x2d, 0x01, 0x02, 0x90, 0x2d, 0x01, 0x02, 0x94, 0x2d, 0x01, 0x02, 0x98, 0x2d, 0x01, 0x02, 0x60, 0x0c, 0x02, 0x02, 0x64, 0x0c, 0x02, 0x02, + 0x68, 0x0c, 0x02, 0x02, 0x6c, 0x0c, 0x02, 0x02, 0x00, 0x2a, 0x03, 0x03, 0x08, 0x2a, 0x03, 0x03, 0x10, 0x2a, 0x03, 0x03, 0xc8, 0x09, 0x04, 0x03, 0xd0, 0x09, 0x04, 0x03, 0x00, 0x26, 0x05, 0x04, + 0x10, 0x26, 0x05, 0x04, 0x30, 0x07, 0x06, 0x04, 0x60, 0x24, 0x07, 0x05, 0xc0, 0x03, 0x0a, 0x06, 0x68, 0x01, 0x00, 0x02, 0x6c, 0x01, 0x00, 0x02, 0x70, 0x01, 0x00, 0x02, 0x74, 0x01, 0x00, 0x02, + 0x9c, 0x2d, 0x01, 0x02, 0xa0, 0x2d, 0x01, 0x02, 0xa4, 0x2d, 0x01, 0x02, 0xa8, 0x2d, 0x01, 0x02, 0xac, 0x2d, 0x01, 0x02, 0xb0, 0x2d, 0x01, 0x02, 0x70, 0x0c, 0x02, 0x02, 0x74, 0x0c, 0x02, 0x02, + 0x78, 0x0c, 0x02, 0x02, 0x7c, 0x0c, 0x02, 0x02, 0x18, 0x2a, 0x03, 0x03, 0x20, 0x2a, 0x03, 0x03, 0x28, 0x2a, 0x03, 0x03, 0xd8, 0x09, 0x04, 0x03, 0xe0, 0x09, 0x04, 0x03, 0x20, 0x26, 0x05, 0x04, + 0x30, 0x26, 0x05, 0x04, 0x40, 0x07, 0x06, 0x04, 0x80, 0x02, 0x08, 0x05, 0x00, 0x04, 0x0a, 0x06, 0x78, 0x01, 0x00, 0x02, 0x7c, 0x01, 0x00, 0x02, 0x80, 0x01, 0x00, 0x02, 0x84, 0x01, 0x00, 0x02, + 0xb4, 0x2d, 0x01, 0x02, 0xb8, 0x2d, 0x01, 0x02, 0xbc, 0x2d, 0x01, 0x02, 0xc0, 0x2d, 0x01, 0x02, 0xc4, 0x2d, 0x01, 0x02, 0xc8, 0x2d, 0x01, 0x02, 0x80, 0x0c, 0x02, 0x02, 0x84, 0x0c, 0x02, 0x02, + 0x88, 0x0c, 0x02, 0x02, 0x8c, 0x0c, 0x02, 0x02, 0x30, 0x2a, 0x03, 0x03, 0x38, 0x2a, 0x03, 0x03, 0x40, 0x2a, 0x03, 0x03, 0xe8, 0x09, 0x04, 0x03, 0xf0, 0x09, 0x04, 0x03, 0x40, 0x26, 0x05, 0x04, + 0x50, 0x26, 0x05, 0x04, 0x50, 0x07, 0x06, 0x04, 0xa0, 0x02, 0x08, 0x05, 0x40, 0x04, 0x0a, 0x06, 0x88, 0x01, 0x00, 0x02, 0x8c, 0x01, 0x00, 0x02, 0x90, 0x01, 0x00, 0x02, 0x94, 0x01, 0x00, 0x02, + 0xcc, 0x2d, 0x01, 0x02, 0xd0, 0x2d, 0x01, 0x02, 0xd4, 0x2d, 0x01, 0x02, 0xd8, 0x2d, 0x01, 0x02, 0xdc, 0x2d, 0x01, 0x02, 0xe0, 0x2d, 0x01, 0x02, 0x90, 0x0c, 0x02, 0x02, 0x94, 0x0c, 0x02, 0x02, + 0x98, 0x0c, 0x02, 0x02, 0x9c, 0x0c, 0x02, 0x02, 0x48, 0x2a, 0x03, 0x03, 0x50, 0x2a, 0x03, 0x03, 0x58, 0x2a, 0x03, 0x03, 0xf8, 0x09, 0x04, 0x03, 0x00, 0x0a, 0x04, 0x03, 0x60, 0x26, 0x05, 0x04, + 0x70, 0x26, 0x05, 0x04, 0x60, 0x07, 0x06, 0x04, 0xc0, 0x02, 0x08, 0x05, 0x80, 0x04, 0x0a, 0x06, 0x98, 0x01, 0x00, 0x02, 0x9c, 0x01, 0x00, 0x02, 0xa0, 0x01, 0x00, 0x02, 0xa4, 0x01, 0x00, 0x02, + 0xe4, 0x2d, 0x01, 0x02, 0xe8, 0x2d, 0x01, 0x02, 0xec, 0x2d, 0x01, 0x02, 0xf0, 0x2d, 0x01, 0x02, 0xf4, 0x2d, 0x01, 0x02, 0xf8, 0x2d, 0x01, 0x02, 0xa0, 0x0c, 0x02, 0x02, 0xa4, 0x0c, 0x02, 0x02, + 0xa8, 0x0c, 0x02, 0x02, 0xac, 0x0c, 0x02, 0x02, 0x60, 0x2a, 0x03, 0x03, 0x68, 0x2a, 0x03, 0x03, 0x70, 0x2a, 0x03, 0x03, 0x08, 0x0a, 0x04, 0x03, 0x10, 0x0a, 0x04, 0x03, 0x80, 0x26, 0x05, 0x04, + 0x90, 0x26, 0x05, 0x04, 0x70, 0x07, 0x06, 0x04, 0xe0, 0x02, 0x08, 0x05, 0xc0, 0x04, 0x0a, 0x06, 0xa8, 0x01, 0x00, 0x02, 0xac, 0x01, 0x00, 0x02, 0xb0, 0x01, 0x00, 0x02, 0xb4, 0x01, 0x00, 0x02, + 0xfc, 0x2d, 0x01, 0x02, 0x00, 0x2e, 0x01, 0x02, 0x04, 0x2e, 0x01, 0x02, 0x08, 0x2e, 0x01, 0x02, 0x0c, 0x2e, 0x01, 0x02, 0x10, 0x2e, 0x01, 0x02, 0xb0, 0x0c, 0x02, 0x02, 0xb4, 0x0c, 0x02, 0x02, + 0xb8, 0x0c, 0x02, 0x02, 0xbc, 0x0c, 0x02, 0x02, 0x78, 0x2a, 0x03, 0x03, 0x80, 0x2a, 0x03, 0x03, 0x88, 0x2a, 0x03, 0x03, 0x18, 0x0a, 0x04, 0x03, 0x20, 0x0a, 0x04, 0x03, 0xa0, 0x26, 0x05, 0x04, + 0xb0, 0x26, 0x05, 0x04, 0x80, 0x07, 0x06, 0x04, 0x00, 0x03, 0x08, 0x05, 0x00, 0x05, 0x0a, 0x06, 0xb8, 0x01, 0x00, 0x02, 0xbc, 0x01, 0x00, 0x02, 0xc0, 0x01, 0x00, 0x02, 0xc4, 0x01, 0x00, 0x02, + 0x14, 0x2e, 0x01, 0x02, 0x18, 0x2e, 0x01, 0x02, 0x1c, 0x2e, 0x01, 0x02, 0x20, 0x2e, 0x01, 0x02, 0x24, 0x2e, 0x01, 0x02, 0x28, 0x2e, 0x01, 0x02, 0xc0, 0x0c, 0x02, 0x02, 0xc4, 0x0c, 0x02, 0x02, + 0xc8, 0x0c, 0x02, 0x02, 0xcc, 0x0c, 0x02, 0x02, 0x90, 0x2a, 0x03, 0x03, 0x98, 0x2a, 0x03, 0x03, 0xa0, 0x2a, 0x03, 0x03, 0x28, 0x0a, 0x04, 0x03, 0x30, 0x0a, 0x04, 0x03, 0xc0, 0x26, 0x05, 0x04, + 0xd0, 0x26, 0x05, 0x04, 0x90, 0x07, 0x06, 0x04, 0x20, 0x03, 0x08, 0x05, 0x00, 0x19, 0x0b, 0x07, 0xc8, 0x01, 0x00, 0x02, 0xcc, 0x01, 0x00, 0x02, 0xd0, 0x01, 0x00, 0x02, 0xd4, 0x01, 0x00, 0x02, + 0x2c, 0x2e, 0x01, 0x02, 0x30, 0x2e, 0x01, 0x02, 0x34, 0x2e, 0x01, 0x02, 0x38, 0x2e, 0x01, 0x02, 0x3c, 0x2e, 0x01, 0x02, 0x40, 0x2e, 0x01, 0x02, 0xd0, 0x0c, 0x02, 0x02, 0xd4, 0x0c, 0x02, 0x02, + 0xd8, 0x0c, 0x02, 0x02, 0xdc, 0x0c, 0x02, 0x02, 0xa8, 0x2a, 0x03, 0x03, 0xb0, 0x2a, 0x03, 0x03, 0xb8, 0x2a, 0x03, 0x03, 0x38, 0x0a, 0x04, 0x03, 0x40, 0x0a, 0x04, 0x03, 0xe0, 0x26, 0x05, 0x04, + 0xf0, 0x26, 0x05, 0x04, 0xa0, 0x07, 0x06, 0x04, 0x40, 0x03, 0x08, 0x05, 0x80, 0x19, 0x0b, 0x07, 0xd8, 0x01, 0x00, 0x02, 0xdc, 0x01, 0x00, 0x02, 0xe0, 0x01, 0x00, 0x02, 0xe4, 0x01, 0x00, 0x02, + 0x44, 0x2e, 0x01, 0x02, 0x48, 0x2e, 0x01, 0x02, 0x4c, 0x2e, 0x01, 0x02, 0x50, 0x2e, 0x01, 0x02, 0x54, 0x2e, 0x01, 0x02, 0x58, 0x2e, 0x01, 0x02, 0xe0, 0x0c, 0x02, 0x02, 0xe4, 0x0c, 0x02, 0x02, + 0xe8, 0x0c, 0x02, 0x02, 0xec, 0x0c, 0x02, 0x02, 0xc0, 0x2a, 0x03, 0x03, 0xc8, 0x2a, 0x03, 0x03, 0xd0, 0x2a, 0x03, 0x03, 0x48, 0x0a, 0x04, 0x03, 0x50, 0x0a, 0x04, 0x03, 0x00, 0x27, 0x05, 0x04, + 0x10, 0x27, 0x05, 0x04, 0xb0, 0x07, 0x06, 0x04, 0x60, 0x03, 0x08, 0x05, 0x00, 0x1a, 0x0b, 0x07, 0xe8, 0x01, 0x00, 0x02, 0xec, 0x01, 0x00, 0x02, 0xf0, 0x01, 0x00, 0x02, 0xf4, 0x01, 0x00, 0x02, + 0x5c, 0x2e, 0x01, 0x02, 0x60, 0x2e, 0x01, 0x02, 0x64, 0x2e, 0x01, 0x02, 0x68, 0x2e, 0x01, 0x02, 0x6c, 0x2e, 0x01, 0x02, 0x70, 0x2e, 0x01, 0x02, 0xf0, 0x0c, 0x02, 0x02, 0xf4, 0x0c, 0x02, 0x02, + 0xf8, 0x0c, 0x02, 0x02, 0xfc, 0x0c, 0x02, 0x02, 0xd8, 0x2a, 0x03, 0x03, 0xe0, 0x2a, 0x03, 0x03, 0xe8, 0x2a, 0x03, 0x03, 0x58, 0x0a, 0x04, 0x03, 0x60, 0x0a, 0x04, 0x03, 0x20, 0x27, 0x05, 0x04, + 0x30, 0x27, 0x05, 0x04, 0xc0, 0x07, 0x06, 0x04, 0x80, 0x03, 0x08, 0x05, 0x80, 0x1a, 0x0b, 0x07, 0xf8, 0x01, 0x00, 0x02, 0xfc, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x04, 0x02, 0x00, 0x02, + 0x74, 0x2e, 0x01, 0x02, 0x78, 0x2e, 0x01, 0x02, 0x7c, 0x2e, 0x01, 0x02, 0x80, 0x2e, 0x01, 0x02, 0x84, 0x2e, 0x01, 0x02, 0x88, 0x2e, 0x01, 0x02, 0x00, 0x0d, 0x02, 0x02, 0x04, 0x0d, 0x02, 0x02, + 0x08, 0x0d, 0x02, 0x02, 0x0c, 0x0d, 0x02, 0x02, 0xf0, 0x2a, 0x03, 0x03, 0xf8, 0x2a, 0x03, 0x03, 0x00, 0x2b, 0x03, 0x03, 0x68, 0x0a, 0x04, 0x03, 0x70, 0x0a, 0x04, 0x03, 0x40, 0x27, 0x05, 0x04, + 0x50, 0x27, 0x05, 0x04, 0xd0, 0x07, 0x06, 0x04, 0xa0, 0x03, 0x08, 0x05, 0x00, 0x1b, 0x0b, 0x07, 0x08, 0x02, 0x00, 0x02, 0x0c, 0x02, 0x00, 0x02, 0x10, 0x02, 0x00, 0x02, 0x14, 0x02, 0x00, 0x02, + 0x8c, 0x2e, 0x01, 0x02, 0x90, 0x2e, 0x01, 0x02, 0x94, 0x2e, 0x01, 0x02, 0x98, 0x2e, 0x01, 0x02, 0x9c, 0x2e, 0x01, 0x02, 0xa0, 0x2e, 0x01, 0x02, 0x10, 0x0d, 0x02, 0x02, 0x14, 0x0d, 0x02, 0x02, + 0x18, 0x0d, 0x02, 0x02, 0x1c, 0x0d, 0x02, 0x02, 0x08, 0x2b, 0x03, 0x03, 0x10, 0x2b, 0x03, 0x03, 0x18, 0x2b, 0x03, 0x03, 0x78, 0x0a, 0x04, 0x03, 0x80, 0x0a, 0x04, 0x03, 0x60, 0x27, 0x05, 0x04, + 0x70, 0x27, 0x05, 0x04, 0xe0, 0x07, 0x06, 0x04, 0xc0, 0x03, 0x08, 0x05, 0x80, 0x1b, 0x0b, 0x07, 0x18, 0x02, 0x00, 0x02, 0x1c, 0x02, 0x00, 0x02, 0x20, 0x02, 0x00, 0x02, 0x24, 0x02, 0x00, 0x02, + 0xa4, 0x2e, 0x01, 0x02, 0xa8, 0x2e, 0x01, 0x02, 0xac, 0x2e, 0x01, 0x02, 0xb0, 0x2e, 0x01, 0x02, 0xb4, 0x2e, 0x01, 0x02, 0xb8, 0x2e, 0x01, 0x02, 0x20, 0x0d, 0x02, 0x02, 0x24, 0x0d, 0x02, 0x02, + 0x28, 0x0d, 0x02, 0x02, 0x2c, 0x0d, 0x02, 0x02, 0x20, 0x2b, 0x03, 0x03, 0x28, 0x2b, 0x03, 0x03, 0x30, 0x2b, 0x03, 0x03, 0x88, 0x0a, 0x04, 0x03, 0x90, 0x0a, 0x04, 0x03, 0x80, 0x27, 0x05, 0x04, + 0x90, 0x27, 0x05, 0x04, 0xf0, 0x07, 0x06, 0x04, 0xe0, 0x03, 0x08, 0x05, 0x00, 0x1c, 0x0b, 0x07, 0x28, 0x02, 0x00, 0x02, 0x2c, 0x02, 0x00, 0x02, 0x30, 0x02, 0x00, 0x02, 0x34, 0x02, 0x00, 0x02, + 0xbc, 0x2e, 0x01, 0x02, 0xc0, 0x2e, 0x01, 0x02, 0xc4, 0x2e, 0x01, 0x02, 0xc8, 0x2e, 0x01, 0x02, 0xcc, 0x2e, 0x01, 0x02, 0xd0, 0x2e, 0x01, 0x02, 0x30, 0x0d, 0x02, 0x02, 0x34, 0x0d, 0x02, 0x02, + 0x38, 0x0d, 0x02, 0x02, 0x3c, 0x0d, 0x02, 0x02, 0x38, 0x2b, 0x03, 0x03, 0x40, 0x2b, 0x03, 0x03, 0x48, 0x2b, 0x03, 0x03, 0x98, 0x0a, 0x04, 0x03, 0xa0, 0x0a, 0x04, 0x03, 0xa0, 0x27, 0x05, 0x04, + 0xb0, 0x27, 0x05, 0x04, 0x00, 0x08, 0x06, 0x04, 0x00, 0x04, 0x08, 0x05, 0x80, 0x1c, 0x0b, 0x07, 0x38, 0x02, 0x00, 0x02, 0x3c, 0x02, 0x00, 0x02, 0x40, 0x02, 0x00, 0x02, 0x44, 0x02, 0x00, 0x02, + 0xd4, 0x2e, 0x01, 0x02, 0xd8, 0x2e, 0x01, 0x02, 0xdc, 0x2e, 0x01, 0x02, 0xe0, 0x2e, 0x01, 0x02, 0xe4, 0x2e, 0x01, 0x02, 0xe8, 0x2e, 0x01, 0x02, 0x40, 0x0d, 0x02, 0x02, 0x44, 0x0d, 0x02, 0x02, + 0x48, 0x0d, 0x02, 0x02, 0x4c, 0x0d, 0x02, 0x02, 0x50, 0x2b, 0x03, 0x03, 0x58, 0x2b, 0x03, 0x03, 0x60, 0x2b, 0x03, 0x03, 0xa8, 0x0a, 0x04, 0x03, 0xb0, 0x0a, 0x04, 0x03, 0xc0, 0x27, 0x05, 0x04, + 0xd0, 0x27, 0x05, 0x04, 0x10, 0x08, 0x06, 0x04, 0x20, 0x04, 0x08, 0x05, 0x00, 0x1d, 0x0b, 0x07, 0x48, 0x02, 0x00, 0x02, 0x4c, 0x02, 0x00, 0x02, 0x50, 0x02, 0x00, 0x02, 0x54, 0x02, 0x00, 0x02, + 0xec, 0x2e, 0x01, 0x02, 0xf0, 0x2e, 0x01, 0x02, 0xf4, 0x2e, 0x01, 0x02, 0xf8, 0x2e, 0x01, 0x02, 0xfc, 0x2e, 0x01, 0x02, 0x00, 0x2f, 0x01, 0x02, 0x50, 0x0d, 0x02, 0x02, 0x54, 0x0d, 0x02, 0x02, + 0x58, 0x0d, 0x02, 0x02, 0x5c, 0x0d, 0x02, 0x02, 0x68, 0x2b, 0x03, 0x03, 0x70, 0x2b, 0x03, 0x03, 0x78, 0x2b, 0x03, 0x03, 0xb8, 0x0a, 0x04, 0x03, 0xc0, 0x0a, 0x04, 0x03, 0xe0, 0x27, 0x05, 0x04, + 0xf0, 0x27, 0x05, 0x04, 0x20, 0x08, 0x06, 0x04, 0x40, 0x04, 0x08, 0x05, 0x80, 0x1d, 0x0b, 0x07, 0x58, 0x02, 0x00, 0x02, 0x5c, 0x02, 0x00, 0x02, 0x60, 0x02, 0x00, 0x02, 0x64, 0x02, 0x00, 0x02, + 0x04, 0x2f, 0x01, 0x02, 0x08, 0x2f, 0x01, 0x02, 0x0c, 0x2f, 0x01, 0x02, 0x10, 0x2f, 0x01, 0x02, 0x14, 0x2f, 0x01, 0x02, 0x18, 0x2f, 0x01, 0x02, 0x60, 0x0d, 0x02, 0x02, 0x64, 0x0d, 0x02, 0x02, + 0x68, 0x0d, 0x02, 0x02, 0x6c, 0x0d, 0x02, 0x02, 0x80, 0x2b, 0x03, 0x03, 0x88, 0x2b, 0x03, 0x03, 0x90, 0x2b, 0x03, 0x03, 0xc8, 0x0a, 0x04, 0x03, 0xd0, 0x0a, 0x04, 0x03, 0x00, 0x28, 0x05, 0x04, + 0x10, 0x28, 0x05, 0x04, 0x30, 0x08, 0x06, 0x04, 0x60, 0x04, 0x08, 0x05, 0x00, 0x1e, 0x0b, 0x07, 0x68, 0x02, 0x00, 0x02, 0x6c, 0x02, 0x00, 0x02, 0x70, 0x02, 0x00, 0x02, 0x74, 0x02, 0x00, 0x02, + 0x1c, 0x2f, 0x01, 0x02, 0x20, 0x2f, 0x01, 0x02, 0x24, 0x2f, 0x01, 0x02, 0x28, 0x2f, 0x01, 0x02, 0x2c, 0x2f, 0x01, 0x02, 0x30, 0x2f, 0x01, 0x02, 0x70, 0x0d, 0x02, 0x02, 0x74, 0x0d, 0x02, 0x02, + 0x78, 0x0d, 0x02, 0x02, 0x7c, 0x0d, 0x02, 0x02, 0x98, 0x2b, 0x03, 0x03, 0xa0, 0x2b, 0x03, 0x03, 0xa8, 0x2b, 0x03, 0x03, 0xd8, 0x0a, 0x04, 0x03, 0xe0, 0x0a, 0x04, 0x03, 0x20, 0x28, 0x05, 0x04, + 0x30, 0x28, 0x05, 0x04, 0x40, 0x08, 0x06, 0x04, 0x80, 0x04, 0x08, 0x05, 0x80, 0x1e, 0x0b, 0x07, 0x78, 0x02, 0x00, 0x02, 0x7c, 0x02, 0x00, 0x02, 0x80, 0x02, 0x00, 0x02, 0x84, 0x02, 0x00, 0x02, + 0x34, 0x2f, 0x01, 0x02, 0x38, 0x2f, 0x01, 0x02, 0x3c, 0x2f, 0x01, 0x02, 0x40, 0x2f, 0x01, 0x02, 0x44, 0x2f, 0x01, 0x02, 0x48, 0x2f, 0x01, 0x02, 0x80, 0x0d, 0x02, 0x02, 0x84, 0x0d, 0x02, 0x02, + 0x88, 0x0d, 0x02, 0x02, 0x8c, 0x0d, 0x02, 0x02, 0xb0, 0x2b, 0x03, 0x03, 0xb8, 0x2b, 0x03, 0x03, 0xc0, 0x2b, 0x03, 0x03, 0xe8, 0x0a, 0x04, 0x03, 0xf0, 0x0a, 0x04, 0x03, 0x40, 0x28, 0x05, 0x04, + 0x50, 0x28, 0x05, 0x04, 0x50, 0x08, 0x06, 0x04, 0xa0, 0x04, 0x08, 0x05, 0x00, 0x1f, 0x0b, 0x07, 0x88, 0x02, 0x00, 0x02, 0x8c, 0x02, 0x00, 0x02, 0x90, 0x02, 0x00, 0x02, 0x94, 0x02, 0x00, 0x02, + 0x4c, 0x2f, 0x01, 0x02, 0x50, 0x2f, 0x01, 0x02, 0x54, 0x2f, 0x01, 0x02, 0x58, 0x2f, 0x01, 0x02, 0x5c, 0x2f, 0x01, 0x02, 0x60, 0x2f, 0x01, 0x02, 0x90, 0x0d, 0x02, 0x02, 0x94, 0x0d, 0x02, 0x02, + 0x98, 0x0d, 0x02, 0x02, 0x9c, 0x0d, 0x02, 0x02, 0xc8, 0x2b, 0x03, 0x03, 0xd0, 0x2b, 0x03, 0x03, 0xd8, 0x2b, 0x03, 0x03, 0xf8, 0x0a, 0x04, 0x03, 0x00, 0x0b, 0x04, 0x03, 0x60, 0x28, 0x05, 0x04, + 0x70, 0x28, 0x05, 0x04, 0x60, 0x08, 0x06, 0x04, 0xc0, 0x04, 0x08, 0x05, 0x80, 0x1f, 0x0b, 0x07, 0x98, 0x02, 0x00, 0x02, 0x9c, 0x02, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x02, 0xa4, 0x02, 0x00, 0x02, + 0x64, 0x2f, 0x01, 0x02, 0x68, 0x2f, 0x01, 0x02, 0x6c, 0x2f, 0x01, 0x02, 0x70, 0x2f, 0x01, 0x02, 0x74, 0x2f, 0x01, 0x02, 0x78, 0x2f, 0x01, 0x02, 0xa0, 0x0d, 0x02, 0x02, 0xa4, 0x0d, 0x02, 0x02, + 0xa8, 0x0d, 0x02, 0x02, 0xac, 0x0d, 0x02, 0x02, 0xe0, 0x2b, 0x03, 0x03, 0xe8, 0x2b, 0x03, 0x03, 0xf0, 0x2b, 0x03, 0x03, 0x08, 0x0b, 0x04, 0x03, 0x10, 0x0b, 0x04, 0x03, 0x80, 0x28, 0x05, 0x04, + 0x90, 0x28, 0x05, 0x04, 0x70, 0x08, 0x06, 0x04, 0xe0, 0x04, 0x08, 0x05, 0x00, 0x3c, 0x0c, 0x08, 0xa8, 0x02, 0x00, 0x02, 0xac, 0x02, 0x00, 0x02, 0xb0, 0x02, 0x00, 0x02, 0xb4, 0x02, 0x00, 0x02, + 0x7c, 0x2f, 0x01, 0x02, 0x80, 0x2f, 0x01, 0x02, 0x84, 0x2f, 0x01, 0x02, 0x88, 0x2f, 0x01, 0x02, 0x8c, 0x2f, 0x01, 0x02, 0x90, 0x2f, 0x01, 0x02, 0xb0, 0x0d, 0x02, 0x02, 0xb4, 0x0d, 0x02, 0x02, + 0xb8, 0x0d, 0x02, 0x02, 0xbc, 0x0d, 0x02, 0x02, 0xf8, 0x2b, 0x03, 0x03, 0x00, 0x2c, 0x03, 0x03, 0x08, 0x2c, 0x03, 0x03, 0x18, 0x0b, 0x04, 0x03, 0x20, 0x0b, 0x04, 0x03, 0xa0, 0x28, 0x05, 0x04, + 0xb0, 0x28, 0x05, 0x04, 0x80, 0x08, 0x06, 0x04, 0x00, 0x05, 0x08, 0x05, 0x00, 0x3d, 0x0c, 0x08, 0xb8, 0x02, 0x00, 0x02, 0xbc, 0x02, 0x00, 0x02, 0xc0, 0x02, 0x00, 0x02, 0xc4, 0x02, 0x00, 0x02, + 0x94, 0x2f, 0x01, 0x02, 0x98, 0x2f, 0x01, 0x02, 0x9c, 0x2f, 0x01, 0x02, 0xa0, 0x2f, 0x01, 0x02, 0xa4, 0x2f, 0x01, 0x02, 0xa8, 0x2f, 0x01, 0x02, 0xc0, 0x0d, 0x02, 0x02, 0xc4, 0x0d, 0x02, 0x02, + 0xc8, 0x0d, 0x02, 0x02, 0xcc, 0x0d, 0x02, 0x02, 0x10, 0x2c, 0x03, 0x03, 0x18, 0x2c, 0x03, 0x03, 0x20, 0x2c, 0x03, 0x03, 0x28, 0x0b, 0x04, 0x03, 0x30, 0x0b, 0x04, 0x03, 0xc0, 0x28, 0x05, 0x04, + 0xd0, 0x28, 0x05, 0x04, 0x90, 0x08, 0x06, 0x04, 0x20, 0x05, 0x08, 0x05, 0x00, 0x3e, 0x0c, 0x08, 0xc8, 0x02, 0x00, 0x02, 0xcc, 0x02, 0x00, 0x02, 0xd0, 0x02, 0x00, 0x02, 0xd4, 0x02, 0x00, 0x02, + 0xac, 0x2f, 0x01, 0x02, 0xb0, 0x2f, 0x01, 0x02, 0xb4, 0x2f, 0x01, 0x02, 0xb8, 0x2f, 0x01, 0x02, 0xbc, 0x2f, 0x01, 0x02, 0xc0, 0x2f, 0x01, 0x02, 0xd0, 0x0d, 0x02, 0x02, 0xd4, 0x0d, 0x02, 0x02, + 0xd8, 0x0d, 0x02, 0x02, 0xdc, 0x0d, 0x02, 0x02, 0x28, 0x2c, 0x03, 0x03, 0x30, 0x2c, 0x03, 0x03, 0x38, 0x2c, 0x03, 0x03, 0x38, 0x0b, 0x04, 0x03, 0x40, 0x0b, 0x04, 0x03, 0xe0, 0x28, 0x05, 0x04, + 0xf0, 0x28, 0x05, 0x04, 0xa0, 0x08, 0x06, 0x04, 0x40, 0x05, 0x08, 0x05, 0x00, 0x3f, 0x0c, 0x08, 0xd8, 0x02, 0x00, 0x02, 0xdc, 0x02, 0x00, 0x02, 0xe0, 0x02, 0x00, 0x02, 0xe4, 0x02, 0x00, 0x02, + 0xc4, 0x2f, 0x01, 0x02, 0xc8, 0x2f, 0x01, 0x02, 0xcc, 0x2f, 0x01, 0x02, 0xd0, 0x2f, 0x01, 0x02, 0xd4, 0x2f, 0x01, 0x02, 0xd8, 0x2f, 0x01, 0x02, 0xe0, 0x0d, 0x02, 0x02, 0xe4, 0x0d, 0x02, 0x02, + 0xe8, 0x0d, 0x02, 0x02, 0xec, 0x0d, 0x02, 0x02, 0x40, 0x2c, 0x03, 0x03, 0x48, 0x2c, 0x03, 0x03, 0x50, 0x2c, 0x03, 0x03, 0x48, 0x0b, 0x04, 0x03, 0x50, 0x0b, 0x04, 0x03, 0x00, 0x29, 0x05, 0x04, + 0x10, 0x29, 0x05, 0x04, 0xb0, 0x08, 0x06, 0x04, 0x60, 0x05, 0x08, 0x05, 0x00, 0x00, 0x0c, 0x07, 0xe8, 0x02, 0x00, 0x02, 0xec, 0x02, 0x00, 0x02, 0xf0, 0x02, 0x00, 0x02, 0xdc, 0x2f, 0x01, 0x02, + 0xe0, 0x2f, 0x01, 0x02, 0xe4, 0x2f, 0x01, 0x02, 0xe8, 0x2f, 0x01, 0x02, 0xec, 0x2f, 0x01, 0x02, 0xf0, 0x2f, 0x01, 0x02, 0xf4, 0x2f, 0x01, 0x02, 0xf0, 0x0d, 0x02, 0x02, 0xf4, 0x0d, 0x02, 0x02, + 0xf8, 0x0d, 0x02, 0x02, 0xfc, 0x0d, 0x02, 0x02, 0x58, 0x2c, 0x03, 0x03, 0x60, 0x2c, 0x03, 0x03, 0x68, 0x2c, 0x03, 0x03, 0x58, 0x0b, 0x04, 0x03, 0x60, 0x0b, 0x04, 0x03, 0x20, 0x29, 0x05, 0x04, + 0x30, 0x29, 0x05, 0x04, 0xc0, 0x08, 0x06, 0x04, 0x80, 0x05, 0x08, 0x05, 0x80, 0x00, 0x0c, 0x07, 0xf4, 0x02, 0x00, 0x02, 0xf8, 0x02, 0x00, 0x02, 0xfc, 0x02, 0x00, 0x02, 0xf8, 0x2f, 0x01, 0x02, + 0xfc, 0x2f, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x04, 0x30, 0x01, 0x02, 0x08, 0x30, 0x01, 0x02, 0x0c, 0x30, 0x01, 0x02, 0x10, 0x30, 0x01, 0x02, 0x00, 0x0e, 0x02, 0x02, 0x04, 0x0e, 0x02, 0x02, + 0x08, 0x0e, 0x02, 0x02, 0x0c, 0x0e, 0x02, 0x02, 0x70, 0x2c, 0x03, 0x03, 0x78, 0x2c, 0x03, 0x03, 0x80, 0x2c, 0x03, 0x03, 0x68, 0x0b, 0x04, 0x03, 0x70, 0x0b, 0x04, 0x03, 0x40, 0x29, 0x05, 0x04, + 0xd0, 0x08, 0x06, 0x04, 0xe0, 0x08, 0x06, 0x04, 0xa0, 0x05, 0x08, 0x05, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x03, 0x00, 0x02, 0x04, 0x03, 0x00, 0x02, 0x08, 0x03, 0x00, 0x02, 0x14, 0x30, 0x01, 0x02, + 0x18, 0x30, 0x01, 0x02, 0x1c, 0x30, 0x01, 0x02, 0x20, 0x30, 0x01, 0x02, 0x24, 0x30, 0x01, 0x02, 0x28, 0x30, 0x01, 0x02, 0x2c, 0x30, 0x01, 0x02, 0x10, 0x0e, 0x02, 0x02, 0x14, 0x0e, 0x02, 0x02, + 0x18, 0x0e, 0x02, 0x02, 0x1c, 0x0e, 0x02, 0x02, 0x88, 0x2c, 0x03, 0x03, 0x90, 0x2c, 0x03, 0x03, 0x98, 0x2c, 0x03, 0x03, 0x78, 0x0b, 0x04, 0x03, 0x80, 0x0b, 0x04, 0x03, 0x50, 0x29, 0x05, 0x04, + 0xf0, 0x08, 0x06, 0x04, 0x80, 0x24, 0x07, 0x05, 0xc0, 0x05, 0x08, 0x05, 0x80, 0x01, 0x0c, 0x07, 0x0c, 0x03, 0x00, 0x02, 0x10, 0x03, 0x00, 0x02, 0x14, 0x03, 0x00, 0x02, 0x30, 0x30, 0x01, 0x02, + 0x34, 0x30, 0x01, 0x02, 0x38, 0x30, 0x01, 0x02, 0x3c, 0x30, 0x01, 0x02, 0x40, 0x30, 0x01, 0x02, 0x44, 0x30, 0x01, 0x02, 0x48, 0x30, 0x01, 0x02, 0x20, 0x0e, 0x02, 0x02, 0x24, 0x0e, 0x02, 0x02, + 0x28, 0x0e, 0x02, 0x02, 0x2c, 0x0e, 0x02, 0x02, 0xa0, 0x2c, 0x03, 0x03, 0xa8, 0x2c, 0x03, 0x03, 0xb0, 0x2c, 0x03, 0x03, 0x88, 0x0b, 0x04, 0x03, 0x90, 0x0b, 0x04, 0x03, 0x60, 0x29, 0x05, 0x04, + 0x00, 0x09, 0x06, 0x04, 0xa0, 0x24, 0x07, 0x05, 0xe0, 0x05, 0x08, 0x05, 0x00, 0x02, 0x0c, 0x07, 0x18, 0x03, 0x00, 0x02, 0x1c, 0x03, 0x00, 0x02, 0x20, 0x03, 0x00, 0x02, 0x4c, 0x30, 0x01, 0x02, + 0x50, 0x30, 0x01, 0x02, 0x54, 0x30, 0x01, 0x02, 0x58, 0x30, 0x01, 0x02, 0x5c, 0x30, 0x01, 0x02, 0x60, 0x30, 0x01, 0x02, 0x64, 0x30, 0x01, 0x02, 0x30, 0x0e, 0x02, 0x02, 0x34, 0x0e, 0x02, 0x02, + 0x38, 0x0e, 0x02, 0x02, 0x3c, 0x0e, 0x02, 0x02, 0xb8, 0x2c, 0x03, 0x03, 0xc0, 0x2c, 0x03, 0x03, 0xc8, 0x2c, 0x03, 0x03, 0x98, 0x0b, 0x04, 0x03, 0xa0, 0x0b, 0x04, 0x03, 0x70, 0x29, 0x05, 0x04, + 0x10, 0x09, 0x06, 0x04, 0xc0, 0x24, 0x07, 0x05, 0x00, 0x06, 0x08, 0x05, 0x00, 0x16, 0x0d, 0x08, 0x24, 0x03, 0x00, 0x02, 0x28, 0x03, 0x00, 0x02, 0x2c, 0x03, 0x00, 0x02, 0x68, 0x30, 0x01, 0x02, + 0x6c, 0x30, 0x01, 0x02, 0x70, 0x30, 0x01, 0x02, 0x74, 0x30, 0x01, 0x02, 0x78, 0x30, 0x01, 0x02, 0x7c, 0x30, 0x01, 0x02, 0x80, 0x30, 0x01, 0x02, 0x40, 0x0e, 0x02, 0x02, 0x44, 0x0e, 0x02, 0x02, + 0x48, 0x0e, 0x02, 0x02, 0x4c, 0x0e, 0x02, 0x02, 0xd0, 0x2c, 0x03, 0x03, 0xd8, 0x2c, 0x03, 0x03, 0xe0, 0x2c, 0x03, 0x03, 0xa8, 0x0b, 0x04, 0x03, 0xb0, 0x0b, 0x04, 0x03, 0x80, 0x29, 0x05, 0x04, + 0x20, 0x09, 0x06, 0x04, 0xe0, 0x24, 0x07, 0x05, 0x20, 0x06, 0x08, 0x05, 0x00, 0x17, 0x0d, 0x08, 0x30, 0x03, 0x00, 0x02, 0x34, 0x03, 0x00, 0x02, 0x38, 0x03, 0x00, 0x02, 0x84, 0x30, 0x01, 0x02, + 0x88, 0x30, 0x01, 0x02, 0x8c, 0x30, 0x01, 0x02, 0x90, 0x30, 0x01, 0x02, 0x94, 0x30, 0x01, 0x02, 0x98, 0x30, 0x01, 0x02, 0x9c, 0x30, 0x01, 0x02, 0x50, 0x0e, 0x02, 0x02, 0x54, 0x0e, 0x02, 0x02, + 0x58, 0x0e, 0x02, 0x02, 0x5c, 0x0e, 0x02, 0x02, 0xe8, 0x2c, 0x03, 0x03, 0xf0, 0x2c, 0x03, 0x03, 0xf8, 0x2c, 0x03, 0x03, 0xb8, 0x0b, 0x04, 0x03, 0xc0, 0x0b, 0x04, 0x03, 0x90, 0x29, 0x05, 0x04, + 0x30, 0x09, 0x06, 0x04, 0x00, 0x25, 0x07, 0x05, 0x40, 0x06, 0x08, 0x05, 0x00, 0x18, 0x0d, 0x08, 0x3c, 0x03, 0x00, 0x02, 0x40, 0x03, 0x00, 0x02, 0x44, 0x03, 0x00, 0x02, 0xa0, 0x30, 0x01, 0x02, + 0xa4, 0x30, 0x01, 0x02, 0xa8, 0x30, 0x01, 0x02, 0xac, 0x30, 0x01, 0x02, 0xb0, 0x30, 0x01, 0x02, 0xb4, 0x30, 0x01, 0x02, 0xb8, 0x30, 0x01, 0x02, 0x60, 0x0e, 0x02, 0x02, 0x64, 0x0e, 0x02, 0x02, + 0x68, 0x0e, 0x02, 0x02, 0x6c, 0x0e, 0x02, 0x02, 0x00, 0x2d, 0x03, 0x03, 0x08, 0x2d, 0x03, 0x03, 0x10, 0x2d, 0x03, 0x03, 0xc8, 0x0b, 0x04, 0x03, 0xd0, 0x0b, 0x04, 0x03, 0xa0, 0x29, 0x05, 0x04, + 0x40, 0x09, 0x06, 0x04, 0x20, 0x25, 0x07, 0x05, 0x60, 0x06, 0x08, 0x05, 0x00, 0x19, 0x0d, 0x08, 0x48, 0x03, 0x00, 0x02, 0x4c, 0x03, 0x00, 0x02, 0x50, 0x03, 0x00, 0x02, 0xbc, 0x30, 0x01, 0x02, + 0xc0, 0x30, 0x01, 0x02, 0xc4, 0x30, 0x01, 0x02, 0xc8, 0x30, 0x01, 0x02, 0xcc, 0x30, 0x01, 0x02, 0xd0, 0x30, 0x01, 0x02, 0xd4, 0x30, 0x01, 0x02, 0x70, 0x0e, 0x02, 0x02, 0x74, 0x0e, 0x02, 0x02, + 0x78, 0x0e, 0x02, 0x02, 0x7c, 0x0e, 0x02, 0x02, 0x18, 0x2d, 0x03, 0x03, 0x20, 0x2d, 0x03, 0x03, 0x28, 0x2d, 0x03, 0x03, 0xd8, 0x0b, 0x04, 0x03, 0xe0, 0x0b, 0x04, 0x03, 0xb0, 0x29, 0x05, 0x04, + 0x50, 0x09, 0x06, 0x04, 0x40, 0x25, 0x07, 0x05, 0x80, 0x06, 0x08, 0x05, 0x00, 0x1a, 0x0d, 0x08, 0x54, 0x03, 0x00, 0x02, 0x58, 0x03, 0x00, 0x02, 0x5c, 0x03, 0x00, 0x02, 0xd8, 0x30, 0x01, 0x02, + 0xdc, 0x30, 0x01, 0x02, 0xe0, 0x30, 0x01, 0x02, 0xe4, 0x30, 0x01, 0x02, 0xe8, 0x30, 0x01, 0x02, 0xec, 0x30, 0x01, 0x02, 0xf0, 0x30, 0x01, 0x02, 0x80, 0x0e, 0x02, 0x02, 0x84, 0x0e, 0x02, 0x02, + 0x88, 0x0e, 0x02, 0x02, 0x8c, 0x0e, 0x02, 0x02, 0x30, 0x2d, 0x03, 0x03, 0x38, 0x2d, 0x03, 0x03, 0x40, 0x2d, 0x03, 0x03, 0xe8, 0x0b, 0x04, 0x03, 0xf0, 0x0b, 0x04, 0x03, 0xc0, 0x29, 0x05, 0x04, + 0x60, 0x09, 0x06, 0x04, 0x60, 0x25, 0x07, 0x05, 0xa0, 0x06, 0x08, 0x05, 0x00, 0x1b, 0x0d, 0x08, 0x60, 0x03, 0x00, 0x02, 0x64, 0x03, 0x00, 0x02, 0x68, 0x03, 0x00, 0x02, 0xf4, 0x30, 0x01, 0x02, + 0xf8, 0x30, 0x01, 0x02, 0xfc, 0x30, 0x01, 0x02, 0x00, 0x31, 0x01, 0x02, 0x04, 0x31, 0x01, 0x02, 0x08, 0x31, 0x01, 0x02, 0x0c, 0x31, 0x01, 0x02, 0x90, 0x0e, 0x02, 0x02, 0x94, 0x0e, 0x02, 0x02, + 0x98, 0x0e, 0x02, 0x02, 0x9c, 0x0e, 0x02, 0x02, 0x48, 0x2d, 0x03, 0x03, 0x50, 0x2d, 0x03, 0x03, 0x58, 0x2d, 0x03, 0x03, 0xf8, 0x0b, 0x04, 0x03, 0x00, 0x0c, 0x04, 0x03, 0xd0, 0x29, 0x05, 0x04, + 0x70, 0x09, 0x06, 0x04, 0x80, 0x25, 0x07, 0x05, 0xc0, 0x06, 0x08, 0x05, 0x00, 0x1c, 0x0d, 0x08, 0x6c, 0x03, 0x00, 0x02, 0x70, 0x03, 0x00, 0x02, 0x74, 0x03, 0x00, 0x02, 0x10, 0x31, 0x01, 0x02, + 0x14, 0x31, 0x01, 0x02, 0x18, 0x31, 0x01, 0x02, 0x1c, 0x31, 0x01, 0x02, 0x20, 0x31, 0x01, 0x02, 0x24, 0x31, 0x01, 0x02, 0x28, 0x31, 0x01, 0x02, 0xa0, 0x0e, 0x02, 0x02, 0xa4, 0x0e, 0x02, 0x02, + 0xa8, 0x0e, 0x02, 0x02, 0xac, 0x0e, 0x02, 0x02, 0x60, 0x2d, 0x03, 0x03, 0x68, 0x2d, 0x03, 0x03, 0x70, 0x2d, 0x03, 0x03, 0x08, 0x0c, 0x04, 0x03, 0x10, 0x0c, 0x04, 0x03, 0xe0, 0x29, 0x05, 0x04, + 0x80, 0x09, 0x06, 0x04, 0xa0, 0x25, 0x07, 0x05, 0xe0, 0x06, 0x08, 0x05, 0x00, 0x38, 0x0e, 0x09, 0x78, 0x03, 0x00, 0x02, 0x7c, 0x03, 0x00, 0x02, 0x80, 0x03, 0x00, 0x02, 0x2c, 0x31, 0x01, 0x02, + 0x30, 0x31, 0x01, 0x02, 0x34, 0x31, 0x01, 0x02, 0x38, 0x31, 0x01, 0x02, 0x3c, 0x31, 0x01, 0x02, 0x40, 0x31, 0x01, 0x02, 0x44, 0x31, 0x01, 0x02, 0xb0, 0x0e, 0x02, 0x02, 0xb4, 0x0e, 0x02, 0x02, + 0xb8, 0x0e, 0x02, 0x02, 0xbc, 0x0e, 0x02, 0x02, 0x78, 0x2d, 0x03, 0x03, 0x80, 0x2d, 0x03, 0x03, 0x88, 0x2d, 0x03, 0x03, 0x18, 0x0c, 0x04, 0x03, 0x20, 0x0c, 0x04, 0x03, 0xf0, 0x29, 0x05, 0x04, + 0x90, 0x09, 0x06, 0x04, 0xc0, 0x25, 0x07, 0x05, 0x00, 0x07, 0x08, 0x05, 0x00, 0x3a, 0x0e, 0x09, 0x84, 0x03, 0x00, 0x02, 0x88, 0x03, 0x00, 0x02, 0x8c, 0x03, 0x00, 0x02, 0x48, 0x31, 0x01, 0x02, + 0x4c, 0x31, 0x01, 0x02, 0x50, 0x31, 0x01, 0x02, 0x54, 0x31, 0x01, 0x02, 0x58, 0x31, 0x01, 0x02, 0x5c, 0x31, 0x01, 0x02, 0x60, 0x31, 0x01, 0x02, 0xc0, 0x0e, 0x02, 0x02, 0xc4, 0x0e, 0x02, 0x02, + 0xc8, 0x0e, 0x02, 0x02, 0xcc, 0x0e, 0x02, 0x02, 0x90, 0x2d, 0x03, 0x03, 0x98, 0x2d, 0x03, 0x03, 0xa0, 0x2d, 0x03, 0x03, 0x28, 0x0c, 0x04, 0x03, 0x30, 0x0c, 0x04, 0x03, 0x00, 0x2a, 0x05, 0x04, + 0xa0, 0x09, 0x06, 0x04, 0xe0, 0x25, 0x07, 0x05, 0x20, 0x07, 0x08, 0x05, 0x00, 0x3c, 0x0e, 0x09, 0x90, 0x03, 0x00, 0x02, 0x94, 0x03, 0x00, 0x02, 0x98, 0x03, 0x00, 0x02, 0x64, 0x31, 0x01, 0x02, + 0x68, 0x31, 0x01, 0x02, 0x6c, 0x31, 0x01, 0x02, 0x70, 0x31, 0x01, 0x02, 0x74, 0x31, 0x01, 0x02, 0x78, 0x31, 0x01, 0x02, 0x7c, 0x31, 0x01, 0x02, 0xd0, 0x0e, 0x02, 0x02, 0xd4, 0x0e, 0x02, 0x02, + 0xd8, 0x0e, 0x02, 0x02, 0xdc, 0x0e, 0x02, 0x02, 0xa8, 0x2d, 0x03, 0x03, 0xb0, 0x2d, 0x03, 0x03, 0xb8, 0x2d, 0x03, 0x03, 0x38, 0x0c, 0x04, 0x03, 0x40, 0x0c, 0x04, 0x03, 0x10, 0x2a, 0x05, 0x04, + 0xb0, 0x09, 0x06, 0x04, 0x00, 0x26, 0x07, 0x05, 0x40, 0x07, 0x08, 0x05, 0x00, 0x3e, 0x0e, 0x09, 0x9c, 0x03, 0x00, 0x02, 0xa0, 0x03, 0x00, 0x02, 0xa4, 0x03, 0x00, 0x02, 0x80, 0x31, 0x01, 0x02, + 0x84, 0x31, 0x01, 0x02, 0x88, 0x31, 0x01, 0x02, 0x8c, 0x31, 0x01, 0x02, 0x90, 0x31, 0x01, 0x02, 0x94, 0x31, 0x01, 0x02, 0x98, 0x31, 0x01, 0x02, 0xe0, 0x0e, 0x02, 0x02, 0xe4, 0x0e, 0x02, 0x02, + 0xe8, 0x0e, 0x02, 0x02, 0xec, 0x0e, 0x02, 0x02, 0xc0, 0x2d, 0x03, 0x03, 0xc8, 0x2d, 0x03, 0x03, 0xd0, 0x2d, 0x03, 0x03, 0x48, 0x0c, 0x04, 0x03, 0x50, 0x0c, 0x04, 0x03, 0x20, 0x2a, 0x05, 0x04, + 0xc0, 0x09, 0x06, 0x04, 0x20, 0x26, 0x07, 0x05, 0x60, 0x07, 0x08, 0x05, 0x00, 0x00, 0x0e, 0x08, 0xa8, 0x03, 0x00, 0x02, 0xac, 0x03, 0x00, 0x02, 0xb0, 0x03, 0x00, 0x02, 0x9c, 0x31, 0x01, 0x02, + 0xa0, 0x31, 0x01, 0x02, 0xa4, 0x31, 0x01, 0x02, 0xa8, 0x31, 0x01, 0x02, 0xac, 0x31, 0x01, 0x02, 0xb0, 0x31, 0x01, 0x02, 0xf0, 0x0e, 0x02, 0x02, 0xf4, 0x0e, 0x02, 0x02, 0xf8, 0x0e, 0x02, 0x02, + 0xfc, 0x0e, 0x02, 0x02, 0x00, 0x0f, 0x02, 0x02, 0xd8, 0x2d, 0x03, 0x03, 0xe0, 0x2d, 0x03, 0x03, 0xe8, 0x2d, 0x03, 0x03, 0x58, 0x0c, 0x04, 0x03, 0x60, 0x0c, 0x04, 0x03, 0x30, 0x2a, 0x05, 0x04, + 0xd0, 0x09, 0x06, 0x04, 0x40, 0x26, 0x07, 0x05, 0x80, 0x07, 0x08, 0x05, 0x00, 0x18, 0x0f, 0x09, 0xb4, 0x03, 0x00, 0x02, 0xb8, 0x03, 0x00, 0x02, 0xbc, 0x03, 0x00, 0x02, 0xb4, 0x31, 0x01, 0x02, + 0xb8, 0x31, 0x01, 0x02, 0xbc, 0x31, 0x01, 0x02, 0xc0, 0x31, 0x01, 0x02, 0xc4, 0x31, 0x01, 0x02, 0xc8, 0x31, 0x01, 0x02, 0x04, 0x0f, 0x02, 0x02, 0x08, 0x0f, 0x02, 0x02, 0x0c, 0x0f, 0x02, 0x02, + 0x10, 0x0f, 0x02, 0x02, 0x14, 0x0f, 0x02, 0x02, 0xf0, 0x2d, 0x03, 0x03, 0xf8, 0x2d, 0x03, 0x03, 0x00, 0x2e, 0x03, 0x03, 0x68, 0x0c, 0x04, 0x03, 0x70, 0x0c, 0x04, 0x03, 0x40, 0x2a, 0x05, 0x04, + 0xe0, 0x09, 0x06, 0x04, 0x60, 0x26, 0x07, 0x05, 0x80, 0x22, 0x09, 0x06, 0x00, 0x1a, 0x0f, 0x09, 0xc0, 0x03, 0x00, 0x02, 0xc4, 0x03, 0x00, 0x02, 0xc8, 0x03, 0x00, 0x02, 0xcc, 0x31, 0x01, 0x02, + 0xd0, 0x31, 0x01, 0x02, 0xd4, 0x31, 0x01, 0x02, 0xd8, 0x31, 0x01, 0x02, 0xdc, 0x31, 0x01, 0x02, 0xe0, 0x31, 0x01, 0x02, 0x18, 0x0f, 0x02, 0x02, 0x1c, 0x0f, 0x02, 0x02, 0x20, 0x0f, 0x02, 0x02, + 0x24, 0x0f, 0x02, 0x02, 0x28, 0x0f, 0x02, 0x02, 0x08, 0x2e, 0x03, 0x03, 0x10, 0x2e, 0x03, 0x03, 0x18, 0x2e, 0x03, 0x03, 0x78, 0x0c, 0x04, 0x03, 0x80, 0x0c, 0x04, 0x03, 0x50, 0x2a, 0x05, 0x04, + 0xf0, 0x09, 0x06, 0x04, 0x80, 0x26, 0x07, 0x05, 0xc0, 0x22, 0x09, 0x06, 0x00, 0x1c, 0x0f, 0x09, 0xcc, 0x03, 0x00, 0x02, 0xd0, 0x03, 0x00, 0x02, 0xd4, 0x03, 0x00, 0x02, 0xe4, 0x31, 0x01, 0x02, + 0xe8, 0x31, 0x01, 0x02, 0xec, 0x31, 0x01, 0x02, 0xf0, 0x31, 0x01, 0x02, 0xf4, 0x31, 0x01, 0x02, 0xf8, 0x31, 0x01, 0x02, 0x2c, 0x0f, 0x02, 0x02, 0x30, 0x0f, 0x02, 0x02, 0x34, 0x0f, 0x02, 0x02, + 0x38, 0x0f, 0x02, 0x02, 0x3c, 0x0f, 0x02, 0x02, 0x20, 0x2e, 0x03, 0x03, 0x28, 0x2e, 0x03, 0x03, 0x30, 0x2e, 0x03, 0x03, 0x88, 0x0c, 0x04, 0x03, 0x90, 0x0c, 0x04, 0x03, 0x60, 0x2a, 0x05, 0x04, + 0x00, 0x0a, 0x06, 0x04, 0xa0, 0x26, 0x07, 0x05, 0x00, 0x23, 0x09, 0x06, 0x00, 0x38, 0x10, 0x0a, 0xd8, 0x03, 0x00, 0x02, 0xdc, 0x03, 0x00, 0x02, 0xe0, 0x03, 0x00, 0x02, 0xfc, 0x31, 0x01, 0x02, + 0x00, 0x32, 0x01, 0x02, 0x04, 0x32, 0x01, 0x02, 0x08, 0x32, 0x01, 0x02, 0x0c, 0x32, 0x01, 0x02, 0x10, 0x32, 0x01, 0x02, 0x40, 0x0f, 0x02, 0x02, 0x44, 0x0f, 0x02, 0x02, 0x48, 0x0f, 0x02, 0x02, + 0x4c, 0x0f, 0x02, 0x02, 0x50, 0x0f, 0x02, 0x02, 0x38, 0x2e, 0x03, 0x03, 0x40, 0x2e, 0x03, 0x03, 0x48, 0x2e, 0x03, 0x03, 0x98, 0x0c, 0x04, 0x03, 0xa0, 0x0c, 0x04, 0x03, 0x70, 0x2a, 0x05, 0x04, + 0x10, 0x0a, 0x06, 0x04, 0xc0, 0x26, 0x07, 0x05, 0x40, 0x23, 0x09, 0x06, 0x00, 0x3c, 0x10, 0x0a, 0xe4, 0x03, 0x00, 0x02, 0xe8, 0x03, 0x00, 0x02, 0xec, 0x03, 0x00, 0x02, 0x14, 0x32, 0x01, 0x02, + 0x18, 0x32, 0x01, 0x02, 0x1c, 0x32, 0x01, 0x02, 0x20, 0x32, 0x01, 0x02, 0x24, 0x32, 0x01, 0x02, 0x28, 0x32, 0x01, 0x02, 0x54, 0x0f, 0x02, 0x02, 0x58, 0x0f, 0x02, 0x02, 0x5c, 0x0f, 0x02, 0x02, + 0x60, 0x0f, 0x02, 0x02, 0x64, 0x0f, 0x02, 0x02, 0x50, 0x2e, 0x03, 0x03, 0x58, 0x2e, 0x03, 0x03, 0x60, 0x2e, 0x03, 0x03, 0xa8, 0x0c, 0x04, 0x03, 0xb0, 0x0c, 0x04, 0x03, 0x80, 0x2a, 0x05, 0x04, + 0x20, 0x0a, 0x06, 0x04, 0xe0, 0x26, 0x07, 0x05, 0x80, 0x23, 0x09, 0x06, 0x00, 0x00, 0x10, 0x09, 0xf0, 0x03, 0x00, 0x02, 0xf4, 0x03, 0x00, 0x02, 0xf8, 0x03, 0x00, 0x02, 0x2c, 0x32, 0x01, 0x02, + 0x30, 0x32, 0x01, 0x02, 0x34, 0x32, 0x01, 0x02, 0x38, 0x32, 0x01, 0x02, 0x3c, 0x32, 0x01, 0x02, 0x40, 0x32, 0x01, 0x02, 0x68, 0x0f, 0x02, 0x02, 0x6c, 0x0f, 0x02, 0x02, 0x70, 0x0f, 0x02, 0x02, + 0x74, 0x0f, 0x02, 0x02, 0x78, 0x0f, 0x02, 0x02, 0x68, 0x2e, 0x03, 0x03, 0x70, 0x2e, 0x03, 0x03, 0x78, 0x2e, 0x03, 0x03, 0xb8, 0x0c, 0x04, 0x03, 0xc0, 0x0c, 0x04, 0x03, 0x90, 0x2a, 0x05, 0x04, + 0x30, 0x0a, 0x06, 0x04, 0x00, 0x27, 0x07, 0x05, 0xc0, 0x23, 0x09, 0x06, 0x00, 0x14, 0x11, 0x0a, 0xfc, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x04, 0x04, 0x00, 0x02, 0x44, 0x32, 0x01, 0x02, + 0x48, 0x32, 0x01, 0x02, 0x4c, 0x32, 0x01, 0x02, 0x50, 0x32, 0x01, 0x02, 0x54, 0x32, 0x01, 0x02, 0x58, 0x32, 0x01, 0x02, 0x7c, 0x0f, 0x02, 0x02, 0x80, 0x0f, 0x02, 0x02, 0x84, 0x0f, 0x02, 0x02, + 0x88, 0x0f, 0x02, 0x02, 0x8c, 0x0f, 0x02, 0x02, 0x80, 0x2e, 0x03, 0x03, 0x88, 0x2e, 0x03, 0x03, 0x90, 0x2e, 0x03, 0x03, 0xc8, 0x0c, 0x04, 0x03, 0xd0, 0x0c, 0x04, 0x03, 0xa0, 0x2a, 0x05, 0x04, + 0x40, 0x0a, 0x06, 0x04, 0x20, 0x27, 0x07, 0x05, 0x00, 0x24, 0x09, 0x06, 0x00, 0x38, 0x12, 0x0b, 0x08, 0x04, 0x00, 0x02, 0x0c, 0x04, 0x00, 0x02, 0x10, 0x04, 0x00, 0x02, 0x5c, 0x32, 0x01, 0x02, + 0x60, 0x32, 0x01, 0x02, 0x64, 0x32, 0x01, 0x02, 0x68, 0x32, 0x01, 0x02, 0x6c, 0x32, 0x01, 0x02, 0x70, 0x32, 0x01, 0x02, 0x90, 0x0f, 0x02, 0x02, 0x94, 0x0f, 0x02, 0x02, 0x98, 0x0f, 0x02, 0x02, + 0x9c, 0x0f, 0x02, 0x02, 0xa0, 0x0f, 0x02, 0x02, 0x98, 0x2e, 0x03, 0x03, 0xa0, 0x2e, 0x03, 0x03, 0xa8, 0x2e, 0x03, 0x03, 0xd8, 0x0c, 0x04, 0x03, 0xe0, 0x0c, 0x04, 0x03, 0xb0, 0x2a, 0x05, 0x04, + 0x50, 0x0a, 0x06, 0x04, 0x40, 0x27, 0x07, 0x05, 0x40, 0x24, 0x09, 0x06, 0x00, 0x00, 0x12, 0x0a, 0x14, 0x04, 0x00, 0x02, 0x18, 0x04, 0x00, 0x02, 0x1c, 0x04, 0x00, 0x02, 0x74, 0x32, 0x01, 0x02, + 0x78, 0x32, 0x01, 0x02, 0x7c, 0x32, 0x01, 0x02, 0x80, 0x32, 0x01, 0x02, 0x84, 0x32, 0x01, 0x02, 0x88, 0x32, 0x01, 0x02, 0xa4, 0x0f, 0x02, 0x02, 0xa8, 0x0f, 0x02, 0x02, 0xac, 0x0f, 0x02, 0x02, + 0xb0, 0x0f, 0x02, 0x02, 0xb4, 0x0f, 0x02, 0x02, 0xb0, 0x2e, 0x03, 0x03, 0xb8, 0x2e, 0x03, 0x03, 0xc0, 0x2e, 0x03, 0x03, 0xe8, 0x0c, 0x04, 0x03, 0xf0, 0x0c, 0x04, 0x03, 0xc0, 0x2a, 0x05, 0x04, + 0x60, 0x0a, 0x06, 0x04, 0x60, 0x27, 0x07, 0x05, 0x80, 0x24, 0x09, 0x06, 0x00, 0x30, 0x14, 0x0c, 0x20, 0x04, 0x00, 0x02, 0x24, 0x04, 0x00, 0x02, 0x28, 0x04, 0x00, 0x02, 0x8c, 0x32, 0x01, 0x02, + 0x90, 0x32, 0x01, 0x02, 0x94, 0x32, 0x01, 0x02, 0x98, 0x32, 0x01, 0x02, 0x9c, 0x32, 0x01, 0x02, 0xa0, 0x32, 0x01, 0x02, 0xb8, 0x0f, 0x02, 0x02, 0xbc, 0x0f, 0x02, 0x02, 0xc0, 0x0f, 0x02, 0x02, + 0xc4, 0x0f, 0x02, 0x02, 0xc8, 0x0f, 0x02, 0x02, 0xc8, 0x2e, 0x03, 0x03, 0xd0, 0x2e, 0x03, 0x03, 0xd8, 0x2e, 0x03, 0x03, 0xf8, 0x0c, 0x04, 0x03, 0x00, 0x0d, 0x04, 0x03, 0xd0, 0x2a, 0x05, 0x04, + 0x70, 0x0a, 0x06, 0x04, 0x80, 0x27, 0x07, 0x05, 0xc0, 0x24, 0x09, 0x06, 0x00, 0x20, 0x16, 0x0d, 0x2c, 0x04, 0x00, 0x02, 0x30, 0x04, 0x00, 0x02, 0x34, 0x04, 0x00, 0x02, 0xa4, 0x32, 0x01, 0x02, + 0xa8, 0x32, 0x01, 0x02, 0xac, 0x32, 0x01, 0x02, 0xb0, 0x32, 0x01, 0x02, 0xb4, 0x32, 0x01, 0x02, 0xb8, 0x32, 0x01, 0x02, 0xcc, 0x0f, 0x02, 0x02, 0xd0, 0x0f, 0x02, 0x02, 0xd4, 0x0f, 0x02, 0x02, + 0xd8, 0x0f, 0x02, 0x02, 0xdc, 0x0f, 0x02, 0x02, 0xe0, 0x2e, 0x03, 0x03, 0xe8, 0x2e, 0x03, 0x03, 0xf0, 0x2e, 0x03, 0x03, 0x08, 0x0d, 0x04, 0x03, 0x10, 0x0d, 0x04, 0x03, 0xe0, 0x2a, 0x05, 0x04, + 0x80, 0x0a, 0x06, 0x04, 0xa0, 0x27, 0x07, 0x05, 0x00, 0x25, 0x09, 0x06, 0x38, 0x04, 0x00, 0x02, 0x3c, 0x04, 0x00, 0x02, 0x40, 0x04, 0x00, 0x02, 0x44, 0x04, 0x00, 0x02, 0xbc, 0x32, 0x01, 0x02, + 0xc0, 0x32, 0x01, 0x02, 0xc4, 0x32, 0x01, 0x02, 0xc8, 0x32, 0x01, 0x02, 0xcc, 0x32, 0x01, 0x02, 0xd0, 0x32, 0x01, 0x02, 0xe0, 0x0f, 0x02, 0x02, 0xe4, 0x0f, 0x02, 0x02, 0xe8, 0x0f, 0x02, 0x02, + 0xec, 0x0f, 0x02, 0x02, 0xf0, 0x0f, 0x02, 0x02, 0xf8, 0x2e, 0x03, 0x03, 0x00, 0x2f, 0x03, 0x03, 0x08, 0x2f, 0x03, 0x03, 0x18, 0x0d, 0x04, 0x03, 0x20, 0x0d, 0x04, 0x03, 0xf0, 0x2a, 0x05, 0x04, + 0x90, 0x0a, 0x06, 0x04, 0xc0, 0x27, 0x07, 0x05, 0x40, 0x25, 0x09, 0x06, 0x48, 0x04, 0x00, 0x02, 0x4c, 0x04, 0x00, 0x02, 0x50, 0x04, 0x00, 0x02, 0x54, 0x04, 0x00, 0x02, 0xd4, 0x32, 0x01, 0x02, + 0xd8, 0x32, 0x01, 0x02, 0xdc, 0x32, 0x01, 0x02, 0xe0, 0x32, 0x01, 0x02, 0xe4, 0x32, 0x01, 0x02, 0xe8, 0x32, 0x01, 0x02, 0xf4, 0x0f, 0x02, 0x02, 0xf8, 0x0f, 0x02, 0x02, 0xfc, 0x0f, 0x02, 0x02, + 0x00, 0x10, 0x02, 0x02, 0x04, 0x10, 0x02, 0x02, 0x10, 0x2f, 0x03, 0x03, 0x18, 0x2f, 0x03, 0x03, 0x20, 0x2f, 0x03, 0x03, 0x28, 0x0d, 0x04, 0x03, 0x30, 0x0d, 0x04, 0x03, 0x00, 0x2b, 0x05, 0x04, + 0xa0, 0x0a, 0x06, 0x04, 0xe0, 0x27, 0x07, 0x05, 0x80, 0x25, 0x09, 0x06, 0x58, 0x04, 0x00, 0x02, 0x5c, 0x04, 0x00, 0x02, 0x60, 0x04, 0x00, 0x02, 0x64, 0x04, 0x00, 0x02, 0xec, 0x32, 0x01, 0x02, + 0xf0, 0x32, 0x01, 0x02, 0xf4, 0x32, 0x01, 0x02, 0xf8, 0x32, 0x01, 0x02, 0xfc, 0x32, 0x01, 0x02, 0x00, 0x33, 0x01, 0x02, 0x08, 0x10, 0x02, 0x02, 0x0c, 0x10, 0x02, 0x02, 0x10, 0x10, 0x02, 0x02, + 0x14, 0x10, 0x02, 0x02, 0x18, 0x10, 0x02, 0x02, 0x28, 0x2f, 0x03, 0x03, 0x30, 0x2f, 0x03, 0x03, 0x38, 0x2f, 0x03, 0x03, 0x38, 0x0d, 0x04, 0x03, 0x40, 0x0d, 0x04, 0x03, 0x10, 0x2b, 0x05, 0x04, + 0xb0, 0x0a, 0x06, 0x04, 0x00, 0x28, 0x07, 0x05, 0xc0, 0x25, 0x09, 0x06, 0x68, 0x04, 0x00, 0x02, 0x6c, 0x04, 0x00, 0x02, 0x70, 0x04, 0x00, 0x02, 0x74, 0x04, 0x00, 0x02, 0x04, 0x33, 0x01, 0x02, + 0x08, 0x33, 0x01, 0x02, 0x0c, 0x33, 0x01, 0x02, 0x10, 0x33, 0x01, 0x02, 0x14, 0x33, 0x01, 0x02, 0x18, 0x33, 0x01, 0x02, 0x1c, 0x10, 0x02, 0x02, 0x20, 0x10, 0x02, 0x02, 0x24, 0x10, 0x02, 0x02, + 0x28, 0x10, 0x02, 0x02, 0x2c, 0x10, 0x02, 0x02, 0x40, 0x2f, 0x03, 0x03, 0x48, 0x2f, 0x03, 0x03, 0x50, 0x2f, 0x03, 0x03, 0x48, 0x0d, 0x04, 0x03, 0x50, 0x0d, 0x04, 0x03, 0x20, 0x2b, 0x05, 0x04, + 0xc0, 0x0a, 0x06, 0x04, 0x20, 0x28, 0x07, 0x05, 0x00, 0x26, 0x09, 0x06, 0x78, 0x04, 0x00, 0x02, 0x7c, 0x04, 0x00, 0x02, 0x80, 0x04, 0x00, 0x02, 0x84, 0x04, 0x00, 0x02, 0x1c, 0x33, 0x01, 0x02, + 0x20, 0x33, 0x01, 0x02, 0x24, 0x33, 0x01, 0x02, 0x28, 0x33, 0x01, 0x02, 0x2c, 0x33, 0x01, 0x02, 0x30, 0x33, 0x01, 0x02, 0x30, 0x10, 0x02, 0x02, 0x34, 0x10, 0x02, 0x02, 0x38, 0x10, 0x02, 0x02, + 0x3c, 0x10, 0x02, 0x02, 0x40, 0x10, 0x02, 0x02, 0x58, 0x2f, 0x03, 0x03, 0x60, 0x2f, 0x03, 0x03, 0x68, 0x2f, 0x03, 0x03, 0x58, 0x0d, 0x04, 0x03, 0x60, 0x0d, 0x04, 0x03, 0x30, 0x2b, 0x05, 0x04, + 0xd0, 0x0a, 0x06, 0x04, 0x40, 0x28, 0x07, 0x05, 0x40, 0x26, 0x09, 0x06, 0x88, 0x04, 0x00, 0x02, 0x8c, 0x04, 0x00, 0x02, 0x90, 0x04, 0x00, 0x02, 0x94, 0x04, 0x00, 0x02, 0x34, 0x33, 0x01, 0x02, + 0x38, 0x33, 0x01, 0x02, 0x3c, 0x33, 0x01, 0x02, 0x40, 0x33, 0x01, 0x02, 0x44, 0x33, 0x01, 0x02, 0x48, 0x33, 0x01, 0x02, 0x44, 0x10, 0x02, 0x02, 0x48, 0x10, 0x02, 0x02, 0x4c, 0x10, 0x02, 0x02, + 0x50, 0x10, 0x02, 0x02, 0x54, 0x10, 0x02, 0x02, 0x70, 0x2f, 0x03, 0x03, 0x78, 0x2f, 0x03, 0x03, 0x80, 0x2f, 0x03, 0x03, 0x68, 0x0d, 0x04, 0x03, 0x70, 0x0d, 0x04, 0x03, 0x40, 0x2b, 0x05, 0x04, + 0xe0, 0x0a, 0x06, 0x04, 0x60, 0x28, 0x07, 0x05, 0x80, 0x26, 0x09, 0x06, 0x98, 0x04, 0x00, 0x02, 0x9c, 0x04, 0x00, 0x02, 0xa0, 0x04, 0x00, 0x02, 0xa4, 0x04, 0x00, 0x02, 0x4c, 0x33, 0x01, 0x02, + 0x50, 0x33, 0x01, 0x02, 0x54, 0x33, 0x01, 0x02, 0x58, 0x33, 0x01, 0x02, 0x5c, 0x33, 0x01, 0x02, 0x60, 0x33, 0x01, 0x02, 0x58, 0x10, 0x02, 0x02, 0x5c, 0x10, 0x02, 0x02, 0x60, 0x10, 0x02, 0x02, + 0x64, 0x10, 0x02, 0x02, 0x68, 0x10, 0x02, 0x02, 0x88, 0x2f, 0x03, 0x03, 0x90, 0x2f, 0x03, 0x03, 0x98, 0x2f, 0x03, 0x03, 0x78, 0x0d, 0x04, 0x03, 0x80, 0x0d, 0x04, 0x03, 0x50, 0x2b, 0x05, 0x04, + 0xf0, 0x0a, 0x06, 0x04, 0x80, 0x28, 0x07, 0x05, 0xc0, 0x26, 0x09, 0x06, 0xa8, 0x04, 0x00, 0x02, 0xac, 0x04, 0x00, 0x02, 0xb0, 0x04, 0x00, 0x02, 0xb4, 0x04, 0x00, 0x02, 0x64, 0x33, 0x01, 0x02, + 0x68, 0x33, 0x01, 0x02, 0x6c, 0x33, 0x01, 0x02, 0x70, 0x33, 0x01, 0x02, 0x74, 0x33, 0x01, 0x02, 0x78, 0x33, 0x01, 0x02, 0x6c, 0x10, 0x02, 0x02, 0x70, 0x10, 0x02, 0x02, 0x74, 0x10, 0x02, 0x02, + 0x78, 0x10, 0x02, 0x02, 0x7c, 0x10, 0x02, 0x02, 0xa0, 0x2f, 0x03, 0x03, 0xa8, 0x2f, 0x03, 0x03, 0xb0, 0x2f, 0x03, 0x03, 0x88, 0x0d, 0x04, 0x03, 0x90, 0x0d, 0x04, 0x03, 0x60, 0x2b, 0x05, 0x04, + 0x00, 0x0b, 0x06, 0x04, 0xa0, 0x28, 0x07, 0x05, 0x00, 0x27, 0x09, 0x06, 0xb8, 0x04, 0x00, 0x02, 0xbc, 0x04, 0x00, 0x02, 0xc0, 0x04, 0x00, 0x02, 0xc4, 0x04, 0x00, 0x02, 0x7c, 0x33, 0x01, 0x02, + 0x80, 0x33, 0x01, 0x02, 0x84, 0x33, 0x01, 0x02, 0x88, 0x33, 0x01, 0x02, 0x8c, 0x33, 0x01, 0x02, 0x90, 0x33, 0x01, 0x02, 0x80, 0x10, 0x02, 0x02, 0x84, 0x10, 0x02, 0x02, 0x88, 0x10, 0x02, 0x02, + 0x8c, 0x10, 0x02, 0x02, 0x90, 0x10, 0x02, 0x02, 0xb8, 0x2f, 0x03, 0x03, 0xc0, 0x2f, 0x03, 0x03, 0xc8, 0x2f, 0x03, 0x03, 0x98, 0x0d, 0x04, 0x03, 0xa0, 0x0d, 0x04, 0x03, 0x70, 0x2b, 0x05, 0x04, + 0x10, 0x0b, 0x06, 0x04, 0xc0, 0x28, 0x07, 0x05, 0x40, 0x27, 0x09, 0x06, 0xc8, 0x04, 0x00, 0x02, 0xcc, 0x04, 0x00, 0x02, 0xd0, 0x04, 0x00, 0x02, 0xd4, 0x04, 0x00, 0x02, 0x94, 0x33, 0x01, 0x02, + 0x98, 0x33, 0x01, 0x02, 0x9c, 0x33, 0x01, 0x02, 0xa0, 0x33, 0x01, 0x02, 0xa4, 0x33, 0x01, 0x02, 0xa8, 0x33, 0x01, 0x02, 0x94, 0x10, 0x02, 0x02, 0x98, 0x10, 0x02, 0x02, 0x9c, 0x10, 0x02, 0x02, + 0xa0, 0x10, 0x02, 0x02, 0xa4, 0x10, 0x02, 0x02, 0xd0, 0x2f, 0x03, 0x03, 0xd8, 0x2f, 0x03, 0x03, 0xe0, 0x2f, 0x03, 0x03, 0xa8, 0x0d, 0x04, 0x03, 0xb0, 0x0d, 0x04, 0x03, 0x80, 0x2b, 0x05, 0x04, + 0x20, 0x0b, 0x06, 0x04, 0xe0, 0x28, 0x07, 0x05, 0x80, 0x27, 0x09, 0x06, 0xd8, 0x04, 0x00, 0x02, 0xdc, 0x04, 0x00, 0x02, 0xe0, 0x04, 0x00, 0x02, 0xe4, 0x04, 0x00, 0x02, 0xac, 0x33, 0x01, 0x02, + 0xb0, 0x33, 0x01, 0x02, 0xb4, 0x33, 0x01, 0x02, 0xb8, 0x33, 0x01, 0x02, 0xbc, 0x33, 0x01, 0x02, 0xc0, 0x33, 0x01, 0x02, 0xa8, 0x10, 0x02, 0x02, 0xac, 0x10, 0x02, 0x02, 0xb0, 0x10, 0x02, 0x02, + 0xb4, 0x10, 0x02, 0x02, 0xb8, 0x10, 0x02, 0x02, 0xe8, 0x2f, 0x03, 0x03, 0xf0, 0x2f, 0x03, 0x03, 0xf8, 0x2f, 0x03, 0x03, 0xb8, 0x0d, 0x04, 0x03, 0xc0, 0x0d, 0x04, 0x03, 0x90, 0x2b, 0x05, 0x04, + 0x30, 0x0b, 0x06, 0x04, 0x00, 0x29, 0x07, 0x05, 0xc0, 0x27, 0x09, 0x06, 0xe8, 0x04, 0x00, 0x02, 0xec, 0x04, 0x00, 0x02, 0xf0, 0x04, 0x00, 0x02, 0xf4, 0x04, 0x00, 0x02, 0xc4, 0x33, 0x01, 0x02, + 0xc8, 0x33, 0x01, 0x02, 0xcc, 0x33, 0x01, 0x02, 0xd0, 0x33, 0x01, 0x02, 0xd4, 0x33, 0x01, 0x02, 0xd8, 0x33, 0x01, 0x02, 0xbc, 0x10, 0x02, 0x02, 0xc0, 0x10, 0x02, 0x02, 0xc4, 0x10, 0x02, 0x02, + 0xc8, 0x10, 0x02, 0x02, 0xcc, 0x10, 0x02, 0x02, 0x00, 0x30, 0x03, 0x03, 0x08, 0x30, 0x03, 0x03, 0x10, 0x30, 0x03, 0x03, 0xc8, 0x0d, 0x04, 0x03, 0xd0, 0x0d, 0x04, 0x03, 0xa0, 0x2b, 0x05, 0x04, + 0x40, 0x0b, 0x06, 0x04, 0x20, 0x29, 0x07, 0x05, 0x00, 0x28, 0x09, 0x06, 0xf8, 0x04, 0x00, 0x02, 0xfc, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x04, 0x05, 0x00, 0x02, 0xdc, 0x33, 0x01, 0x02, + 0xe0, 0x33, 0x01, 0x02, 0xe4, 0x33, 0x01, 0x02, 0xe8, 0x33, 0x01, 0x02, 0xec, 0x33, 0x01, 0x02, 0xf0, 0x33, 0x01, 0x02, 0xd0, 0x10, 0x02, 0x02, 0xd4, 0x10, 0x02, 0x02, 0xd8, 0x10, 0x02, 0x02, + 0xdc, 0x10, 0x02, 0x02, 0xe0, 0x10, 0x02, 0x02, 0x18, 0x30, 0x03, 0x03, 0x20, 0x30, 0x03, 0x03, 0x28, 0x30, 0x03, 0x03, 0xd8, 0x0d, 0x04, 0x03, 0xe0, 0x0d, 0x04, 0x03, 0xb0, 0x2b, 0x05, 0x04, + 0x50, 0x0b, 0x06, 0x04, 0x40, 0x29, 0x07, 0x05, 0x40, 0x28, 0x09, 0x06, 0x08, 0x05, 0x00, 0x02, 0x0c, 0x05, 0x00, 0x02, 0x10, 0x05, 0x00, 0x02, 0x14, 0x05, 0x00, 0x02, 0xf4, 0x33, 0x01, 0x02, + 0xf8, 0x33, 0x01, 0x02, 0xfc, 0x33, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x04, 0x34, 0x01, 0x02, 0x08, 0x34, 0x01, 0x02, 0xe4, 0x10, 0x02, 0x02, 0xe8, 0x10, 0x02, 0x02, 0xec, 0x10, 0x02, 0x02, + 0xf0, 0x10, 0x02, 0x02, 0xf4, 0x10, 0x02, 0x02, 0x30, 0x30, 0x03, 0x03, 0x38, 0x30, 0x03, 0x03, 0x40, 0x30, 0x03, 0x03, 0xe8, 0x0d, 0x04, 0x03, 0xf0, 0x0d, 0x04, 0x03, 0xc0, 0x2b, 0x05, 0x04, + 0x60, 0x0b, 0x06, 0x04, 0x60, 0x29, 0x07, 0x05, 0x80, 0x28, 0x09, 0x06, 0x18, 0x05, 0x00, 0x02, 0x1c, 0x05, 0x00, 0x02, 0x20, 0x05, 0x00, 0x02, 0x24, 0x05, 0x00, 0x02, 0x0c, 0x34, 0x01, 0x02, + 0x10, 0x34, 0x01, 0x02, 0x14, 0x34, 0x01, 0x02, 0x18, 0x34, 0x01, 0x02, 0x1c, 0x34, 0x01, 0x02, 0x20, 0x34, 0x01, 0x02, 0xf8, 0x10, 0x02, 0x02, 0xfc, 0x10, 0x02, 0x02, 0x00, 0x11, 0x02, 0x02, + 0x04, 0x11, 0x02, 0x02, 0x08, 0x11, 0x02, 0x02, 0x48, 0x30, 0x03, 0x03, 0x50, 0x30, 0x03, 0x03, 0xf8, 0x0d, 0x04, 0x03, 0x00, 0x0e, 0x04, 0x03, 0x08, 0x0e, 0x04, 0x03, 0xd0, 0x2b, 0x05, 0x04, + 0x70, 0x0b, 0x06, 0x04, 0x80, 0x29, 0x07, 0x05, 0xc0, 0x28, 0x09, 0x06, 0x28, 0x05, 0x00, 0x02, 0x2c, 0x05, 0x00, 0x02, 0x30, 0x05, 0x00, 0x02, 0x34, 0x05, 0x00, 0x02, 0x24, 0x34, 0x01, 0x02, + 0x28, 0x34, 0x01, 0x02, 0x2c, 0x34, 0x01, 0x02, 0x30, 0x34, 0x01, 0x02, 0x34, 0x34, 0x01, 0x02, 0x38, 0x34, 0x01, 0x02, 0x0c, 0x11, 0x02, 0x02, 0x10, 0x11, 0x02, 0x02, 0x14, 0x11, 0x02, 0x02, + 0x18, 0x11, 0x02, 0x02, 0x58, 0x30, 0x03, 0x03, 0x60, 0x30, 0x03, 0x03, 0x68, 0x30, 0x03, 0x03, 0x10, 0x0e, 0x04, 0x03, 0x18, 0x0e, 0x04, 0x03, 0x20, 0x0e, 0x04, 0x03, 0xe0, 0x2b, 0x05, 0x04, + 0x80, 0x0b, 0x06, 0x04, 0xa0, 0x29, 0x07, 0x05, 0x00, 0x29, 0x09, 0x06, 0x38, 0x05, 0x00, 0x02, 0x3c, 0x05, 0x00, 0x02, 0x40, 0x05, 0x00, 0x02, 0x44, 0x05, 0x00, 0x02, 0x3c, 0x34, 0x01, 0x02, + 0x40, 0x34, 0x01, 0x02, 0x44, 0x34, 0x01, 0x02, 0x48, 0x34, 0x01, 0x02, 0x4c, 0x34, 0x01, 0x02, 0x50, 0x34, 0x01, 0x02, 0x1c, 0x11, 0x02, 0x02, 0x20, 0x11, 0x02, 0x02, 0x24, 0x11, 0x02, 0x02, + 0x28, 0x11, 0x02, 0x02, 0x70, 0x30, 0x03, 0x03, 0x78, 0x30, 0x03, 0x03, 0x80, 0x30, 0x03, 0x03, 0x28, 0x0e, 0x04, 0x03, 0x30, 0x0e, 0x04, 0x03, 0x38, 0x0e, 0x04, 0x03, 0xf0, 0x2b, 0x05, 0x04, + 0x90, 0x0b, 0x06, 0x04, 0xc0, 0x29, 0x07, 0x05, 0x40, 0x29, 0x09, 0x06, 0x48, 0x05, 0x00, 0x02, 0x4c, 0x05, 0x00, 0x02, 0x50, 0x05, 0x00, 0x02, 0x54, 0x05, 0x00, 0x02, 0x54, 0x34, 0x01, 0x02, + 0x58, 0x34, 0x01, 0x02, 0x5c, 0x34, 0x01, 0x02, 0x60, 0x34, 0x01, 0x02, 0x64, 0x34, 0x01, 0x02, 0x68, 0x34, 0x01, 0x02, 0x2c, 0x11, 0x02, 0x02, 0x30, 0x11, 0x02, 0x02, 0x34, 0x11, 0x02, 0x02, + 0x38, 0x11, 0x02, 0x02, 0x88, 0x30, 0x03, 0x03, 0x90, 0x30, 0x03, 0x03, 0x98, 0x30, 0x03, 0x03, 0x40, 0x0e, 0x04, 0x03, 0x48, 0x0e, 0x04, 0x03, 0x50, 0x0e, 0x04, 0x03, 0x00, 0x2c, 0x05, 0x04, + 0xa0, 0x0b, 0x06, 0x04, 0xe0, 0x29, 0x07, 0x05, 0x80, 0x29, 0x09, 0x06, 0x58, 0x05, 0x00, 0x02, 0x5c, 0x05, 0x00, 0x02, 0x60, 0x05, 0x00, 0x02, 0x64, 0x05, 0x00, 0x02, 0x6c, 0x34, 0x01, 0x02, + 0x70, 0x34, 0x01, 0x02, 0x74, 0x34, 0x01, 0x02, 0x78, 0x34, 0x01, 0x02, 0x7c, 0x34, 0x01, 0x02, 0x80, 0x34, 0x01, 0x02, 0x3c, 0x11, 0x02, 0x02, 0x40, 0x11, 0x02, 0x02, 0x44, 0x11, 0x02, 0x02, + 0x48, 0x11, 0x02, 0x02, 0xa0, 0x30, 0x03, 0x03, 0xa8, 0x30, 0x03, 0x03, 0xb0, 0x30, 0x03, 0x03, 0x58, 0x0e, 0x04, 0x03, 0x60, 0x0e, 0x04, 0x03, 0x68, 0x0e, 0x04, 0x03, 0x10, 0x2c, 0x05, 0x04, + 0xb0, 0x0b, 0x06, 0x04, 0x00, 0x2a, 0x07, 0x05, 0xc0, 0x29, 0x09, 0x06, 0x68, 0x05, 0x00, 0x02, 0x6c, 0x05, 0x00, 0x02, 0x70, 0x05, 0x00, 0x02, 0x74, 0x05, 0x00, 0x02, 0x84, 0x34, 0x01, 0x02, + 0x88, 0x34, 0x01, 0x02, 0x8c, 0x34, 0x01, 0x02, 0x90, 0x34, 0x01, 0x02, 0x94, 0x34, 0x01, 0x02, 0x98, 0x34, 0x01, 0x02, 0x4c, 0x11, 0x02, 0x02, 0x50, 0x11, 0x02, 0x02, 0x54, 0x11, 0x02, 0x02, + 0x58, 0x11, 0x02, 0x02, 0xb8, 0x30, 0x03, 0x03, 0xc0, 0x30, 0x03, 0x03, 0xc8, 0x30, 0x03, 0x03, 0x70, 0x0e, 0x04, 0x03, 0x78, 0x0e, 0x04, 0x03, 0x80, 0x0e, 0x04, 0x03, 0x20, 0x2c, 0x05, 0x04, + 0xc0, 0x0b, 0x06, 0x04, 0x20, 0x2a, 0x07, 0x05, 0x40, 0x05, 0x0a, 0x06, 0x78, 0x05, 0x00, 0x02, 0x7c, 0x05, 0x00, 0x02, 0x80, 0x05, 0x00, 0x02, 0x84, 0x05, 0x00, 0x02, 0x9c, 0x34, 0x01, 0x02, + 0xa0, 0x34, 0x01, 0x02, 0xa4, 0x34, 0x01, 0x02, 0xa8, 0x34, 0x01, 0x02, 0xac, 0x34, 0x01, 0x02, 0xb0, 0x34, 0x01, 0x02, 0x5c, 0x11, 0x02, 0x02, 0x60, 0x11, 0x02, 0x02, 0x64, 0x11, 0x02, 0x02, + 0x68, 0x11, 0x02, 0x02, 0xd0, 0x30, 0x03, 0x03, 0xd8, 0x30, 0x03, 0x03, 0xe0, 0x30, 0x03, 0x03, 0x88, 0x0e, 0x04, 0x03, 0x90, 0x0e, 0x04, 0x03, 0x98, 0x0e, 0x04, 0x03, 0x30, 0x2c, 0x05, 0x04, + 0xd0, 0x0b, 0x06, 0x04, 0x40, 0x2a, 0x07, 0x05, 0x80, 0x05, 0x0a, 0x06, 0x88, 0x05, 0x00, 0x02, 0x8c, 0x05, 0x00, 0x02, 0x90, 0x05, 0x00, 0x02, 0x94, 0x05, 0x00, 0x02, 0xb4, 0x34, 0x01, 0x02, + 0xb8, 0x34, 0x01, 0x02, 0xbc, 0x34, 0x01, 0x02, 0xc0, 0x34, 0x01, 0x02, 0xc4, 0x34, 0x01, 0x02, 0xc8, 0x34, 0x01, 0x02, 0x6c, 0x11, 0x02, 0x02, 0x70, 0x11, 0x02, 0x02, 0x74, 0x11, 0x02, 0x02, + 0x78, 0x11, 0x02, 0x02, 0xe8, 0x30, 0x03, 0x03, 0xf0, 0x30, 0x03, 0x03, 0xf8, 0x30, 0x03, 0x03, 0xa0, 0x0e, 0x04, 0x03, 0xa8, 0x0e, 0x04, 0x03, 0x40, 0x2c, 0x05, 0x04, 0x50, 0x2c, 0x05, 0x04, + 0xe0, 0x0b, 0x06, 0x04, 0x60, 0x2a, 0x07, 0x05, 0xc0, 0x05, 0x0a, 0x06, 0x98, 0x05, 0x00, 0x02, 0x9c, 0x05, 0x00, 0x02, 0xa0, 0x05, 0x00, 0x02, 0xa4, 0x05, 0x00, 0x02, 0xcc, 0x34, 0x01, 0x02, + 0xd0, 0x34, 0x01, 0x02, 0xd4, 0x34, 0x01, 0x02, 0xd8, 0x34, 0x01, 0x02, 0xdc, 0x34, 0x01, 0x02, 0xe0, 0x34, 0x01, 0x02, 0x7c, 0x11, 0x02, 0x02, 0x80, 0x11, 0x02, 0x02, 0x84, 0x11, 0x02, 0x02, + 0x88, 0x11, 0x02, 0x02, 0x00, 0x31, 0x03, 0x03, 0x08, 0x31, 0x03, 0x03, 0x10, 0x31, 0x03, 0x03, 0xb0, 0x0e, 0x04, 0x03, 0xb8, 0x0e, 0x04, 0x03, 0x60, 0x2c, 0x05, 0x04, 0x70, 0x2c, 0x05, 0x04, + 0xf0, 0x0b, 0x06, 0x04, 0x80, 0x2a, 0x07, 0x05, 0x00, 0x06, 0x0a, 0x06, 0xa8, 0x05, 0x00, 0x02, 0xac, 0x05, 0x00, 0x02, 0xb0, 0x05, 0x00, 0x02, 0xb4, 0x05, 0x00, 0x02, 0xe4, 0x34, 0x01, 0x02, + 0xe8, 0x34, 0x01, 0x02, 0xec, 0x34, 0x01, 0x02, 0xf0, 0x34, 0x01, 0x02, 0xf4, 0x34, 0x01, 0x02, 0xf8, 0x34, 0x01, 0x02, 0x8c, 0x11, 0x02, 0x02, 0x90, 0x11, 0x02, 0x02, 0x94, 0x11, 0x02, 0x02, + 0x98, 0x11, 0x02, 0x02, 0x18, 0x31, 0x03, 0x03, 0x20, 0x31, 0x03, 0x03, 0x28, 0x31, 0x03, 0x03, 0xc0, 0x0e, 0x04, 0x03, 0xc8, 0x0e, 0x04, 0x03, 0x80, 0x2c, 0x05, 0x04, 0x90, 0x2c, 0x05, 0x04, + 0x00, 0x0c, 0x06, 0x04, 0xa0, 0x2a, 0x07, 0x05, 0x40, 0x06, 0x0a, 0x06, 0xb8, 0x05, 0x00, 0x02, 0xbc, 0x05, 0x00, 0x02, 0xc0, 0x05, 0x00, 0x02, 0xc4, 0x05, 0x00, 0x02, 0xfc, 0x34, 0x01, 0x02, + 0x00, 0x35, 0x01, 0x02, 0x04, 0x35, 0x01, 0x02, 0x08, 0x35, 0x01, 0x02, 0x0c, 0x35, 0x01, 0x02, 0x10, 0x35, 0x01, 0x02, 0x9c, 0x11, 0x02, 0x02, 0xa0, 0x11, 0x02, 0x02, 0xa4, 0x11, 0x02, 0x02, + 0xa8, 0x11, 0x02, 0x02, 0x30, 0x31, 0x03, 0x03, 0x38, 0x31, 0x03, 0x03, 0x40, 0x31, 0x03, 0x03, 0xd0, 0x0e, 0x04, 0x03, 0xd8, 0x0e, 0x04, 0x03, 0xa0, 0x2c, 0x05, 0x04, 0xb0, 0x2c, 0x05, 0x04, + 0x10, 0x0c, 0x06, 0x04, 0xc0, 0x2a, 0x07, 0x05, 0x80, 0x06, 0x0a, 0x06, 0xc8, 0x05, 0x00, 0x02, 0xcc, 0x05, 0x00, 0x02, 0xd0, 0x05, 0x00, 0x02, 0xd4, 0x05, 0x00, 0x02, 0x14, 0x35, 0x01, 0x02, + 0x18, 0x35, 0x01, 0x02, 0x1c, 0x35, 0x01, 0x02, 0x20, 0x35, 0x01, 0x02, 0x24, 0x35, 0x01, 0x02, 0x28, 0x35, 0x01, 0x02, 0xac, 0x11, 0x02, 0x02, 0xb0, 0x11, 0x02, 0x02, 0xb4, 0x11, 0x02, 0x02, + 0xb8, 0x11, 0x02, 0x02, 0x48, 0x31, 0x03, 0x03, 0x50, 0x31, 0x03, 0x03, 0x58, 0x31, 0x03, 0x03, 0xe0, 0x0e, 0x04, 0x03, 0xe8, 0x0e, 0x04, 0x03, 0xc0, 0x2c, 0x05, 0x04, 0xd0, 0x2c, 0x05, 0x04, + 0x20, 0x0c, 0x06, 0x04, 0xe0, 0x2a, 0x07, 0x05, 0xc0, 0x06, 0x0a, 0x06, 0xd8, 0x05, 0x00, 0x02, 0xdc, 0x05, 0x00, 0x02, 0xe0, 0x05, 0x00, 0x02, 0xe4, 0x05, 0x00, 0x02, 0x2c, 0x35, 0x01, 0x02, + 0x30, 0x35, 0x01, 0x02, 0x34, 0x35, 0x01, 0x02, 0x38, 0x35, 0x01, 0x02, 0x3c, 0x35, 0x01, 0x02, 0x40, 0x35, 0x01, 0x02, 0xbc, 0x11, 0x02, 0x02, 0xc0, 0x11, 0x02, 0x02, 0xc4, 0x11, 0x02, 0x02, + 0xc8, 0x11, 0x02, 0x02, 0x60, 0x31, 0x03, 0x03, 0x68, 0x31, 0x03, 0x03, 0x70, 0x31, 0x03, 0x03, 0xf0, 0x0e, 0x04, 0x03, 0xf8, 0x0e, 0x04, 0x03, 0xe0, 0x2c, 0x05, 0x04, 0xf0, 0x2c, 0x05, 0x04, + 0x30, 0x0c, 0x06, 0x04, 0x00, 0x2b, 0x07, 0x05, 0x00, 0x07, 0x0a, 0x06, 0xe8, 0x05, 0x00, 0x02, 0xec, 0x05, 0x00, 0x02, 0xf0, 0x05, 0x00, 0x02, 0xf4, 0x05, 0x00, 0x02, 0x44, 0x35, 0x01, 0x02, + 0x48, 0x35, 0x01, 0x02, 0x4c, 0x35, 0x01, 0x02, 0x50, 0x35, 0x01, 0x02, 0x54, 0x35, 0x01, 0x02, 0x58, 0x35, 0x01, 0x02, 0xcc, 0x11, 0x02, 0x02, 0xd0, 0x11, 0x02, 0x02, 0xd4, 0x11, 0x02, 0x02, + 0xd8, 0x11, 0x02, 0x02, 0x78, 0x31, 0x03, 0x03, 0x80, 0x31, 0x03, 0x03, 0x88, 0x31, 0x03, 0x03, 0x00, 0x0f, 0x04, 0x03, 0x08, 0x0f, 0x04, 0x03, 0x00, 0x2d, 0x05, 0x04, 0x10, 0x2d, 0x05, 0x04, + 0x40, 0x0c, 0x06, 0x04, 0x20, 0x2b, 0x07, 0x05, 0x40, 0x07, 0x0a, 0x06, 0xf8, 0x05, 0x00, 0x02, 0xfc, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x04, 0x06, 0x00, 0x02, 0x5c, 0x35, 0x01, 0x02, + 0x60, 0x35, 0x01, 0x02, 0x64, 0x35, 0x01, 0x02, 0x68, 0x35, 0x01, 0x02, 0x6c, 0x35, 0x01, 0x02, 0x70, 0x35, 0x01, 0x02, 0xdc, 0x11, 0x02, 0x02, 0xe0, 0x11, 0x02, 0x02, 0xe4, 0x11, 0x02, 0x02, + 0xe8, 0x11, 0x02, 0x02, 0x90, 0x31, 0x03, 0x03, 0x98, 0x31, 0x03, 0x03, 0xa0, 0x31, 0x03, 0x03, 0x10, 0x0f, 0x04, 0x03, 0x18, 0x0f, 0x04, 0x03, 0x20, 0x2d, 0x05, 0x04, 0x30, 0x2d, 0x05, 0x04, + 0x50, 0x0c, 0x06, 0x04, 0x40, 0x2b, 0x07, 0x05, 0x80, 0x07, 0x0a, 0x06, 0x08, 0x06, 0x00, 0x02, 0x0c, 0x06, 0x00, 0x02, 0x10, 0x06, 0x00, 0x02, 0x14, 0x06, 0x00, 0x02, 0x74, 0x35, 0x01, 0x02, + 0x78, 0x35, 0x01, 0x02, 0x7c, 0x35, 0x01, 0x02, 0x80, 0x35, 0x01, 0x02, 0x84, 0x35, 0x01, 0x02, 0x88, 0x35, 0x01, 0x02, 0xec, 0x11, 0x02, 0x02, 0xf0, 0x11, 0x02, 0x02, 0xf4, 0x11, 0x02, 0x02, + 0xf8, 0x11, 0x02, 0x02, 0xa8, 0x31, 0x03, 0x03, 0xb0, 0x31, 0x03, 0x03, 0xb8, 0x31, 0x03, 0x03, 0x20, 0x0f, 0x04, 0x03, 0x28, 0x0f, 0x04, 0x03, 0x40, 0x2d, 0x05, 0x04, 0x50, 0x2d, 0x05, 0x04, + 0x60, 0x0c, 0x06, 0x04, 0x60, 0x2b, 0x07, 0x05, 0xc0, 0x07, 0x0a, 0x06, 0x18, 0x06, 0x00, 0x02, 0x1c, 0x06, 0x00, 0x02, 0x20, 0x06, 0x00, 0x02, 0x24, 0x06, 0x00, 0x02, 0x8c, 0x35, 0x01, 0x02, + 0x90, 0x35, 0x01, 0x02, 0x94, 0x35, 0x01, 0x02, 0x98, 0x35, 0x01, 0x02, 0x9c, 0x35, 0x01, 0x02, 0xa0, 0x35, 0x01, 0x02, 0xfc, 0x11, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x04, 0x12, 0x02, 0x02, + 0x08, 0x12, 0x02, 0x02, 0xc0, 0x31, 0x03, 0x03, 0xc8, 0x31, 0x03, 0x03, 0xd0, 0x31, 0x03, 0x03, 0x30, 0x0f, 0x04, 0x03, 0x38, 0x0f, 0x04, 0x03, 0x60, 0x2d, 0x05, 0x04, 0x70, 0x2d, 0x05, 0x04, + 0x70, 0x0c, 0x06, 0x04, 0x80, 0x2b, 0x07, 0x05, 0x00, 0x08, 0x0a, 0x06, 0x28, 0x06, 0x00, 0x02, 0x2c, 0x06, 0x00, 0x02, 0x30, 0x06, 0x00, 0x02, 0x34, 0x06, 0x00, 0x02, 0xa4, 0x35, 0x01, 0x02, + 0xa8, 0x35, 0x01, 0x02, 0xac, 0x35, 0x01, 0x02, 0xb0, 0x35, 0x01, 0x02, 0xb4, 0x35, 0x01, 0x02, 0xb8, 0x35, 0x01, 0x02, 0x0c, 0x12, 0x02, 0x02, 0x10, 0x12, 0x02, 0x02, 0x14, 0x12, 0x02, 0x02, + 0x18, 0x12, 0x02, 0x02, 0xd8, 0x31, 0x03, 0x03, 0xe0, 0x31, 0x03, 0x03, 0xe8, 0x31, 0x03, 0x03, 0x40, 0x0f, 0x04, 0x03, 0x48, 0x0f, 0x04, 0x03, 0x80, 0x2d, 0x05, 0x04, 0x90, 0x2d, 0x05, 0x04, + 0x80, 0x0c, 0x06, 0x04, 0xa0, 0x2b, 0x07, 0x05, 0x40, 0x08, 0x0a, 0x06, 0x38, 0x06, 0x00, 0x02, 0x3c, 0x06, 0x00, 0x02, 0x40, 0x06, 0x00, 0x02, 0x44, 0x06, 0x00, 0x02, 0xbc, 0x35, 0x01, 0x02, + 0xc0, 0x35, 0x01, 0x02, 0xc4, 0x35, 0x01, 0x02, 0xc8, 0x35, 0x01, 0x02, 0xcc, 0x35, 0x01, 0x02, 0xd0, 0x35, 0x01, 0x02, 0x1c, 0x12, 0x02, 0x02, 0x20, 0x12, 0x02, 0x02, 0x24, 0x12, 0x02, 0x02, + 0x28, 0x12, 0x02, 0x02, 0xf0, 0x31, 0x03, 0x03, 0xf8, 0x31, 0x03, 0x03, 0x00, 0x32, 0x03, 0x03, 0x50, 0x0f, 0x04, 0x03, 0x58, 0x0f, 0x04, 0x03, 0xa0, 0x2d, 0x05, 0x04, 0xb0, 0x2d, 0x05, 0x04, + 0x90, 0x0c, 0x06, 0x04, 0xc0, 0x2b, 0x07, 0x05, 0x80, 0x08, 0x0a, 0x06, 0x48, 0x06, 0x00, 0x02, 0x4c, 0x06, 0x00, 0x02, 0x50, 0x06, 0x00, 0x02, 0x54, 0x06, 0x00, 0x02, 0xd4, 0x35, 0x01, 0x02, + 0xd8, 0x35, 0x01, 0x02, 0xdc, 0x35, 0x01, 0x02, 0xe0, 0x35, 0x01, 0x02, 0xe4, 0x35, 0x01, 0x02, 0xe8, 0x35, 0x01, 0x02, 0x2c, 0x12, 0x02, 0x02, 0x30, 0x12, 0x02, 0x02, 0x34, 0x12, 0x02, 0x02, + 0x38, 0x12, 0x02, 0x02, 0x08, 0x32, 0x03, 0x03, 0x10, 0x32, 0x03, 0x03, 0x18, 0x32, 0x03, 0x03, 0x60, 0x0f, 0x04, 0x03, 0x68, 0x0f, 0x04, 0x03, 0xc0, 0x2d, 0x05, 0x04, 0xd0, 0x2d, 0x05, 0x04, + 0xa0, 0x0c, 0x06, 0x04, 0xe0, 0x2b, 0x07, 0x05, 0xc0, 0x08, 0x0a, 0x06, 0x58, 0x06, 0x00, 0x02, 0x5c, 0x06, 0x00, 0x02, 0x60, 0x06, 0x00, 0x02, 0x64, 0x06, 0x00, 0x02, 0xec, 0x35, 0x01, 0x02, + 0xf0, 0x35, 0x01, 0x02, 0xf4, 0x35, 0x01, 0x02, 0xf8, 0x35, 0x01, 0x02, 0xfc, 0x35, 0x01, 0x02, 0x00, 0x36, 0x01, 0x02, 0x3c, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x02, 0x44, 0x12, 0x02, 0x02, + 0x48, 0x12, 0x02, 0x02, 0x20, 0x32, 0x03, 0x03, 0x28, 0x32, 0x03, 0x03, 0x30, 0x32, 0x03, 0x03, 0x70, 0x0f, 0x04, 0x03, 0x78, 0x0f, 0x04, 0x03, 0xe0, 0x2d, 0x05, 0x04, 0xf0, 0x2d, 0x05, 0x04, + 0xb0, 0x0c, 0x06, 0x04, 0xa0, 0x07, 0x08, 0x05, 0x00, 0x09, 0x0a, 0x06, 0x68, 0x06, 0x00, 0x02, 0x6c, 0x06, 0x00, 0x02, 0x70, 0x06, 0x00, 0x02, 0x74, 0x06, 0x00, 0x02, 0x04, 0x36, 0x01, 0x02, + 0x08, 0x36, 0x01, 0x02, 0x0c, 0x36, 0x01, 0x02, 0x10, 0x36, 0x01, 0x02, 0x14, 0x36, 0x01, 0x02, 0x18, 0x36, 0x01, 0x02, 0x4c, 0x12, 0x02, 0x02, 0x50, 0x12, 0x02, 0x02, 0x54, 0x12, 0x02, 0x02, + 0x58, 0x12, 0x02, 0x02, 0x38, 0x32, 0x03, 0x03, 0x40, 0x32, 0x03, 0x03, 0x48, 0x32, 0x03, 0x03, 0x80, 0x0f, 0x04, 0x03, 0x88, 0x0f, 0x04, 0x03, 0x00, 0x2e, 0x05, 0x04, 0x10, 0x2e, 0x05, 0x04, + 0xc0, 0x0c, 0x06, 0x04, 0xc0, 0x07, 0x08, 0x05, 0x40, 0x09, 0x0a, 0x06, 0x78, 0x06, 0x00, 0x02, 0x7c, 0x06, 0x00, 0x02, 0x80, 0x06, 0x00, 0x02, 0x84, 0x06, 0x00, 0x02, 0x1c, 0x36, 0x01, 0x02, + 0x20, 0x36, 0x01, 0x02, 0x24, 0x36, 0x01, 0x02, 0x28, 0x36, 0x01, 0x02, 0x2c, 0x36, 0x01, 0x02, 0x30, 0x36, 0x01, 0x02, 0x5c, 0x12, 0x02, 0x02, 0x60, 0x12, 0x02, 0x02, 0x64, 0x12, 0x02, 0x02, + 0x68, 0x12, 0x02, 0x02, 0x50, 0x32, 0x03, 0x03, 0x58, 0x32, 0x03, 0x03, 0x60, 0x32, 0x03, 0x03, 0x90, 0x0f, 0x04, 0x03, 0x98, 0x0f, 0x04, 0x03, 0x20, 0x2e, 0x05, 0x04, 0x30, 0x2e, 0x05, 0x04, + 0xd0, 0x0c, 0x06, 0x04, 0xe0, 0x07, 0x08, 0x05, 0x80, 0x09, 0x0a, 0x06, 0x88, 0x06, 0x00, 0x02, 0x8c, 0x06, 0x00, 0x02, 0x90, 0x06, 0x00, 0x02, 0x94, 0x06, 0x00, 0x02, 0x34, 0x36, 0x01, 0x02, + 0x38, 0x36, 0x01, 0x02, 0x3c, 0x36, 0x01, 0x02, 0x40, 0x36, 0x01, 0x02, 0x44, 0x36, 0x01, 0x02, 0x48, 0x36, 0x01, 0x02, 0x6c, 0x12, 0x02, 0x02, 0x70, 0x12, 0x02, 0x02, 0x74, 0x12, 0x02, 0x02, + 0x78, 0x12, 0x02, 0x02, 0x68, 0x32, 0x03, 0x03, 0x70, 0x32, 0x03, 0x03, 0x78, 0x32, 0x03, 0x03, 0xa0, 0x0f, 0x04, 0x03, 0xa8, 0x0f, 0x04, 0x03, 0x40, 0x2e, 0x05, 0x04, 0x50, 0x2e, 0x05, 0x04, + 0xe0, 0x0c, 0x06, 0x04, 0x00, 0x08, 0x08, 0x05, 0xc0, 0x09, 0x0a, 0x06, 0x98, 0x06, 0x00, 0x02, 0x9c, 0x06, 0x00, 0x02, 0xa0, 0x06, 0x00, 0x02, 0xa4, 0x06, 0x00, 0x02, 0x4c, 0x36, 0x01, 0x02, + 0x50, 0x36, 0x01, 0x02, 0x54, 0x36, 0x01, 0x02, 0x58, 0x36, 0x01, 0x02, 0x5c, 0x36, 0x01, 0x02, 0x60, 0x36, 0x01, 0x02, 0x7c, 0x12, 0x02, 0x02, 0x80, 0x12, 0x02, 0x02, 0x84, 0x12, 0x02, 0x02, + 0x88, 0x12, 0x02, 0x02, 0x80, 0x32, 0x03, 0x03, 0x88, 0x32, 0x03, 0x03, 0x90, 0x32, 0x03, 0x03, 0xb0, 0x0f, 0x04, 0x03, 0xb8, 0x0f, 0x04, 0x03, 0x60, 0x2e, 0x05, 0x04, 0x70, 0x2e, 0x05, 0x04, + 0xf0, 0x0c, 0x06, 0x04, 0x20, 0x08, 0x08, 0x05, 0x00, 0x20, 0x0b, 0x07, 0xa8, 0x06, 0x00, 0x02, 0xac, 0x06, 0x00, 0x02, 0xb0, 0x06, 0x00, 0x02, 0xb4, 0x06, 0x00, 0x02, 0x64, 0x36, 0x01, 0x02, + 0x68, 0x36, 0x01, 0x02, 0x6c, 0x36, 0x01, 0x02, 0x70, 0x36, 0x01, 0x02, 0x74, 0x36, 0x01, 0x02, 0x78, 0x36, 0x01, 0x02, 0x8c, 0x12, 0x02, 0x02, 0x90, 0x12, 0x02, 0x02, 0x94, 0x12, 0x02, 0x02, + 0x98, 0x12, 0x02, 0x02, 0x98, 0x32, 0x03, 0x03, 0xa0, 0x32, 0x03, 0x03, 0xa8, 0x32, 0x03, 0x03, 0xc0, 0x0f, 0x04, 0x03, 0xc8, 0x0f, 0x04, 0x03, 0x80, 0x2e, 0x05, 0x04, 0x90, 0x2e, 0x05, 0x04, + 0x00, 0x0d, 0x06, 0x04, 0x40, 0x08, 0x08, 0x05, 0x80, 0x20, 0x0b, 0x07, 0xb8, 0x06, 0x00, 0x02, 0xbc, 0x06, 0x00, 0x02, 0xc0, 0x06, 0x00, 0x02, 0xc4, 0x06, 0x00, 0x02, 0x7c, 0x36, 0x01, 0x02, + 0x80, 0x36, 0x01, 0x02, 0x84, 0x36, 0x01, 0x02, 0x88, 0x36, 0x01, 0x02, 0x8c, 0x36, 0x01, 0x02, 0x90, 0x36, 0x01, 0x02, 0x9c, 0x12, 0x02, 0x02, 0xa0, 0x12, 0x02, 0x02, 0xa4, 0x12, 0x02, 0x02, + 0xa8, 0x12, 0x02, 0x02, 0xb0, 0x32, 0x03, 0x03, 0xb8, 0x32, 0x03, 0x03, 0xc0, 0x32, 0x03, 0x03, 0xd0, 0x0f, 0x04, 0x03, 0xd8, 0x0f, 0x04, 0x03, 0xa0, 0x2e, 0x05, 0x04, 0xb0, 0x2e, 0x05, 0x04, + 0x10, 0x0d, 0x06, 0x04, 0x60, 0x08, 0x08, 0x05, 0x00, 0x21, 0x0b, 0x07, 0xc8, 0x06, 0x00, 0x02, 0xcc, 0x06, 0x00, 0x02, 0xd0, 0x06, 0x00, 0x02, 0xd4, 0x06, 0x00, 0x02, 0x94, 0x36, 0x01, 0x02, + 0x98, 0x36, 0x01, 0x02, 0x9c, 0x36, 0x01, 0x02, 0xa0, 0x36, 0x01, 0x02, 0xa4, 0x36, 0x01, 0x02, 0xa8, 0x36, 0x01, 0x02, 0xac, 0x12, 0x02, 0x02, 0xb0, 0x12, 0x02, 0x02, 0xb4, 0x12, 0x02, 0x02, + 0xb8, 0x12, 0x02, 0x02, 0xc8, 0x32, 0x03, 0x03, 0xd0, 0x32, 0x03, 0x03, 0xd8, 0x32, 0x03, 0x03, 0xe0, 0x0f, 0x04, 0x03, 0xe8, 0x0f, 0x04, 0x03, 0xc0, 0x2e, 0x05, 0x04, 0xd0, 0x2e, 0x05, 0x04, + 0x20, 0x0d, 0x06, 0x04, 0x80, 0x08, 0x08, 0x05, 0x80, 0x21, 0x0b, 0x07, 0xd8, 0x06, 0x00, 0x02, 0xdc, 0x06, 0x00, 0x02, 0xe0, 0x06, 0x00, 0x02, 0xe4, 0x06, 0x00, 0x02, 0xac, 0x36, 0x01, 0x02, + 0xb0, 0x36, 0x01, 0x02, 0xb4, 0x36, 0x01, 0x02, 0xb8, 0x36, 0x01, 0x02, 0xbc, 0x36, 0x01, 0x02, 0xc0, 0x36, 0x01, 0x02, 0xbc, 0x12, 0x02, 0x02, 0xc0, 0x12, 0x02, 0x02, 0xc4, 0x12, 0x02, 0x02, + 0xc8, 0x12, 0x02, 0x02, 0xe0, 0x32, 0x03, 0x03, 0xe8, 0x32, 0x03, 0x03, 0xf0, 0x32, 0x03, 0x03, 0xf0, 0x0f, 0x04, 0x03, 0xf8, 0x0f, 0x04, 0x03, 0xe0, 0x2e, 0x05, 0x04, 0xf0, 0x2e, 0x05, 0x04, + 0x30, 0x0d, 0x06, 0x04, 0xa0, 0x08, 0x08, 0x05, 0x00, 0x22, 0x0b, 0x07, 0xe8, 0x06, 0x00, 0x02, 0xec, 0x06, 0x00, 0x02, 0xf0, 0x06, 0x00, 0x02, 0xf4, 0x06, 0x00, 0x02, 0xc4, 0x36, 0x01, 0x02, + 0xc8, 0x36, 0x01, 0x02, 0xcc, 0x36, 0x01, 0x02, 0xd0, 0x36, 0x01, 0x02, 0xd4, 0x36, 0x01, 0x02, 0xd8, 0x36, 0x01, 0x02, 0xcc, 0x12, 0x02, 0x02, 0xd0, 0x12, 0x02, 0x02, 0xd4, 0x12, 0x02, 0x02, + 0xd8, 0x12, 0x02, 0x02, 0xf8, 0x32, 0x03, 0x03, 0x00, 0x33, 0x03, 0x03, 0x08, 0x33, 0x03, 0x03, 0x00, 0x10, 0x04, 0x03, 0x08, 0x10, 0x04, 0x03, 0x00, 0x2f, 0x05, 0x04, 0x10, 0x2f, 0x05, 0x04, + 0x40, 0x0d, 0x06, 0x04, 0xc0, 0x08, 0x08, 0x05, 0x80, 0x22, 0x0b, 0x07, 0xf8, 0x06, 0x00, 0x02, 0xfc, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x04, 0x07, 0x00, 0x02, 0xdc, 0x36, 0x01, 0x02, + 0xe0, 0x36, 0x01, 0x02, 0xe4, 0x36, 0x01, 0x02, 0xe8, 0x36, 0x01, 0x02, 0xec, 0x36, 0x01, 0x02, 0xf0, 0x36, 0x01, 0x02, 0xdc, 0x12, 0x02, 0x02, 0xe0, 0x12, 0x02, 0x02, 0xe4, 0x12, 0x02, 0x02, + 0xe8, 0x12, 0x02, 0x02, 0x10, 0x33, 0x03, 0x03, 0x18, 0x33, 0x03, 0x03, 0x20, 0x33, 0x03, 0x03, 0x10, 0x10, 0x04, 0x03, 0x18, 0x10, 0x04, 0x03, 0x20, 0x2f, 0x05, 0x04, 0x30, 0x2f, 0x05, 0x04, + 0x50, 0x0d, 0x06, 0x04, 0xe0, 0x08, 0x08, 0x05, 0x00, 0x23, 0x0b, 0x07, 0x08, 0x07, 0x00, 0x02, 0x0c, 0x07, 0x00, 0x02, 0x10, 0x07, 0x00, 0x02, 0x14, 0x07, 0x00, 0x02, 0xf4, 0x36, 0x01, 0x02, + 0xf8, 0x36, 0x01, 0x02, 0xfc, 0x36, 0x01, 0x02, 0x00, 0x37, 0x01, 0x02, 0x04, 0x37, 0x01, 0x02, 0x08, 0x37, 0x01, 0x02, 0xec, 0x12, 0x02, 0x02, 0xf0, 0x12, 0x02, 0x02, 0xf4, 0x12, 0x02, 0x02, + 0xf8, 0x12, 0x02, 0x02, 0x28, 0x33, 0x03, 0x03, 0x30, 0x33, 0x03, 0x03, 0x38, 0x33, 0x03, 0x03, 0x20, 0x10, 0x04, 0x03, 0x28, 0x10, 0x04, 0x03, 0x40, 0x2f, 0x05, 0x04, 0x50, 0x2f, 0x05, 0x04, + 0x60, 0x0d, 0x06, 0x04, 0x00, 0x09, 0x08, 0x05, 0x80, 0x23, 0x0b, 0x07, 0x18, 0x07, 0x00, 0x02, 0x1c, 0x07, 0x00, 0x02, 0x20, 0x07, 0x00, 0x02, 0x24, 0x07, 0x00, 0x02, 0x0c, 0x37, 0x01, 0x02, + 0x10, 0x37, 0x01, 0x02, 0x14, 0x37, 0x01, 0x02, 0x18, 0x37, 0x01, 0x02, 0x1c, 0x37, 0x01, 0x02, 0x20, 0x37, 0x01, 0x02, 0xfc, 0x12, 0x02, 0x02, 0x00, 0x13, 0x02, 0x02, 0x04, 0x13, 0x02, 0x02, + 0x08, 0x13, 0x02, 0x02, 0x40, 0x33, 0x03, 0x03, 0x48, 0x33, 0x03, 0x03, 0x50, 0x33, 0x03, 0x03, 0x30, 0x10, 0x04, 0x03, 0x38, 0x10, 0x04, 0x03, 0x60, 0x2f, 0x05, 0x04, 0x70, 0x2f, 0x05, 0x04, + 0x70, 0x0d, 0x06, 0x04, 0x20, 0x09, 0x08, 0x05, 0x00, 0x24, 0x0b, 0x07, 0x28, 0x07, 0x00, 0x02, 0x2c, 0x07, 0x00, 0x02, 0x30, 0x07, 0x00, 0x02, 0x34, 0x07, 0x00, 0x02, 0x24, 0x37, 0x01, 0x02, + 0x28, 0x37, 0x01, 0x02, 0x2c, 0x37, 0x01, 0x02, 0x30, 0x37, 0x01, 0x02, 0x34, 0x37, 0x01, 0x02, 0x38, 0x37, 0x01, 0x02, 0x0c, 0x13, 0x02, 0x02, 0x10, 0x13, 0x02, 0x02, 0x14, 0x13, 0x02, 0x02, + 0x18, 0x13, 0x02, 0x02, 0x58, 0x33, 0x03, 0x03, 0x60, 0x33, 0x03, 0x03, 0x68, 0x33, 0x03, 0x03, 0x40, 0x10, 0x04, 0x03, 0x48, 0x10, 0x04, 0x03, 0x80, 0x2f, 0x05, 0x04, 0x90, 0x2f, 0x05, 0x04, + 0x80, 0x0d, 0x06, 0x04, 0x40, 0x09, 0x08, 0x05, 0x80, 0x24, 0x0b, 0x07, 0x38, 0x07, 0x00, 0x02, 0x3c, 0x07, 0x00, 0x02, 0x40, 0x07, 0x00, 0x02, 0x44, 0x07, 0x00, 0x02, 0x3c, 0x37, 0x01, 0x02, + 0x40, 0x37, 0x01, 0x02, 0x44, 0x37, 0x01, 0x02, 0x48, 0x37, 0x01, 0x02, 0x4c, 0x37, 0x01, 0x02, 0x50, 0x37, 0x01, 0x02, 0x1c, 0x13, 0x02, 0x02, 0x20, 0x13, 0x02, 0x02, 0x24, 0x13, 0x02, 0x02, + 0x28, 0x13, 0x02, 0x02, 0x70, 0x33, 0x03, 0x03, 0x78, 0x33, 0x03, 0x03, 0x80, 0x33, 0x03, 0x03, 0x50, 0x10, 0x04, 0x03, 0x58, 0x10, 0x04, 0x03, 0xa0, 0x2f, 0x05, 0x04, 0xb0, 0x2f, 0x05, 0x04, + 0x90, 0x0d, 0x06, 0x04, 0x60, 0x09, 0x08, 0x05, 0x00, 0x25, 0x0b, 0x07, 0x48, 0x07, 0x00, 0x02, 0x4c, 0x07, 0x00, 0x02, 0x50, 0x07, 0x00, 0x02, 0x54, 0x07, 0x00, 0x02, 0x54, 0x37, 0x01, 0x02, + 0x58, 0x37, 0x01, 0x02, 0x5c, 0x37, 0x01, 0x02, 0x60, 0x37, 0x01, 0x02, 0x64, 0x37, 0x01, 0x02, 0x68, 0x37, 0x01, 0x02, 0x2c, 0x13, 0x02, 0x02, 0x30, 0x13, 0x02, 0x02, 0x34, 0x13, 0x02, 0x02, + 0x38, 0x13, 0x02, 0x02, 0x88, 0x33, 0x03, 0x03, 0x90, 0x33, 0x03, 0x03, 0x98, 0x33, 0x03, 0x03, 0x60, 0x10, 0x04, 0x03, 0x68, 0x10, 0x04, 0x03, 0xc0, 0x2f, 0x05, 0x04, 0xd0, 0x2f, 0x05, 0x04, + 0xa0, 0x0d, 0x06, 0x04, 0x80, 0x09, 0x08, 0x05, 0x80, 0x25, 0x0b, 0x07, 0x58, 0x07, 0x00, 0x02, 0x5c, 0x07, 0x00, 0x02, 0x60, 0x07, 0x00, 0x02, 0x64, 0x07, 0x00, 0x02, 0x6c, 0x37, 0x01, 0x02, + 0x70, 0x37, 0x01, 0x02, 0x74, 0x37, 0x01, 0x02, 0x78, 0x37, 0x01, 0x02, 0x7c, 0x37, 0x01, 0x02, 0x80, 0x37, 0x01, 0x02, 0x3c, 0x13, 0x02, 0x02, 0x40, 0x13, 0x02, 0x02, 0x44, 0x13, 0x02, 0x02, + 0x48, 0x13, 0x02, 0x02, 0xa0, 0x33, 0x03, 0x03, 0xa8, 0x33, 0x03, 0x03, 0xb0, 0x33, 0x03, 0x03, 0x70, 0x10, 0x04, 0x03, 0x78, 0x10, 0x04, 0x03, 0xe0, 0x2f, 0x05, 0x04, 0xf0, 0x2f, 0x05, 0x04, + 0xb0, 0x0d, 0x06, 0x04, 0xa0, 0x09, 0x08, 0x05, 0x00, 0x26, 0x0b, 0x07, 0x68, 0x07, 0x00, 0x02, 0x6c, 0x07, 0x00, 0x02, 0x70, 0x07, 0x00, 0x02, 0x74, 0x07, 0x00, 0x02, 0x84, 0x37, 0x01, 0x02, + 0x88, 0x37, 0x01, 0x02, 0x8c, 0x37, 0x01, 0x02, 0x90, 0x37, 0x01, 0x02, 0x94, 0x37, 0x01, 0x02, 0x98, 0x37, 0x01, 0x02, 0x4c, 0x13, 0x02, 0x02, 0x50, 0x13, 0x02, 0x02, 0x54, 0x13, 0x02, 0x02, + 0x58, 0x13, 0x02, 0x02, 0xb8, 0x33, 0x03, 0x03, 0xc0, 0x33, 0x03, 0x03, 0xc8, 0x33, 0x03, 0x03, 0x80, 0x10, 0x04, 0x03, 0x88, 0x10, 0x04, 0x03, 0x00, 0x30, 0x05, 0x04, 0x10, 0x30, 0x05, 0x04, + 0xc0, 0x0d, 0x06, 0x04, 0xc0, 0x09, 0x08, 0x05, 0x80, 0x26, 0x0b, 0x07, 0x78, 0x07, 0x00, 0x02, 0x7c, 0x07, 0x00, 0x02, 0x80, 0x07, 0x00, 0x02, 0x84, 0x07, 0x00, 0x02, 0x9c, 0x37, 0x01, 0x02, + 0xa0, 0x37, 0x01, 0x02, 0xa4, 0x37, 0x01, 0x02, 0xa8, 0x37, 0x01, 0x02, 0xac, 0x37, 0x01, 0x02, 0xb0, 0x37, 0x01, 0x02, 0x5c, 0x13, 0x02, 0x02, 0x60, 0x13, 0x02, 0x02, 0x64, 0x13, 0x02, 0x02, + 0x68, 0x13, 0x02, 0x02, 0xd0, 0x33, 0x03, 0x03, 0xd8, 0x33, 0x03, 0x03, 0xe0, 0x33, 0x03, 0x03, 0x90, 0x10, 0x04, 0x03, 0x98, 0x10, 0x04, 0x03, 0x20, 0x30, 0x05, 0x04, 0x30, 0x30, 0x05, 0x04, + 0xd0, 0x0d, 0x06, 0x04, 0xe0, 0x09, 0x08, 0x05, 0x80, 0x02, 0x0c, 0x07, 0x88, 0x07, 0x00, 0x02, 0x8c, 0x07, 0x00, 0x02, 0x90, 0x07, 0x00, 0x02, 0x94, 0x07, 0x00, 0x02, 0xb4, 0x37, 0x01, 0x02, + 0xb8, 0x37, 0x01, 0x02, 0xbc, 0x37, 0x01, 0x02, 0xc0, 0x37, 0x01, 0x02, 0xc4, 0x37, 0x01, 0x02, 0xc8, 0x37, 0x01, 0x02, 0x6c, 0x13, 0x02, 0x02, 0x70, 0x13, 0x02, 0x02, 0x74, 0x13, 0x02, 0x02, + 0x78, 0x13, 0x02, 0x02, 0xe8, 0x33, 0x03, 0x03, 0xf0, 0x33, 0x03, 0x03, 0xf8, 0x33, 0x03, 0x03, 0xa0, 0x10, 0x04, 0x03, 0xa8, 0x10, 0x04, 0x03, 0x40, 0x30, 0x05, 0x04, 0x50, 0x30, 0x05, 0x04, + 0xe0, 0x0d, 0x06, 0x04, 0x00, 0x0a, 0x08, 0x05, 0x00, 0x03, 0x0c, 0x07, 0x98, 0x07, 0x00, 0x02, 0x9c, 0x07, 0x00, 0x02, 0xa0, 0x07, 0x00, 0x02, 0xa4, 0x07, 0x00, 0x02, 0xcc, 0x37, 0x01, 0x02, + 0xd0, 0x37, 0x01, 0x02, 0xd4, 0x37, 0x01, 0x02, 0xd8, 0x37, 0x01, 0x02, 0xdc, 0x37, 0x01, 0x02, 0xe0, 0x37, 0x01, 0x02, 0x7c, 0x13, 0x02, 0x02, 0x80, 0x13, 0x02, 0x02, 0x84, 0x13, 0x02, 0x02, + 0x88, 0x13, 0x02, 0x02, 0x00, 0x34, 0x03, 0x03, 0x08, 0x34, 0x03, 0x03, 0x10, 0x34, 0x03, 0x03, 0xb0, 0x10, 0x04, 0x03, 0xb8, 0x10, 0x04, 0x03, 0x60, 0x30, 0x05, 0x04, 0x70, 0x30, 0x05, 0x04, + 0xf0, 0x0d, 0x06, 0x04, 0x20, 0x0a, 0x08, 0x05, 0x80, 0x03, 0x0c, 0x07, 0xa8, 0x07, 0x00, 0x02, 0xac, 0x07, 0x00, 0x02, 0xb0, 0x07, 0x00, 0x02, 0xb4, 0x07, 0x00, 0x02, 0xe4, 0x37, 0x01, 0x02, + 0xe8, 0x37, 0x01, 0x02, 0xec, 0x37, 0x01, 0x02, 0xf0, 0x37, 0x01, 0x02, 0xf4, 0x37, 0x01, 0x02, 0xf8, 0x37, 0x01, 0x02, 0x8c, 0x13, 0x02, 0x02, 0x90, 0x13, 0x02, 0x02, 0x94, 0x13, 0x02, 0x02, + 0x98, 0x13, 0x02, 0x02, 0x18, 0x34, 0x03, 0x03, 0x20, 0x34, 0x03, 0x03, 0x28, 0x34, 0x03, 0x03, 0xc0, 0x10, 0x04, 0x03, 0xc8, 0x10, 0x04, 0x03, 0x80, 0x30, 0x05, 0x04, 0x90, 0x30, 0x05, 0x04, + 0x00, 0x0e, 0x06, 0x04, 0x40, 0x0a, 0x08, 0x05, 0x00, 0x04, 0x0c, 0x07, 0xb8, 0x07, 0x00, 0x02, 0xbc, 0x07, 0x00, 0x02, 0xc0, 0x07, 0x00, 0x02, 0xc4, 0x07, 0x00, 0x02, 0xfc, 0x37, 0x01, 0x02, + 0x00, 0x38, 0x01, 0x02, 0x04, 0x38, 0x01, 0x02, 0x08, 0x38, 0x01, 0x02, 0x0c, 0x38, 0x01, 0x02, 0x10, 0x38, 0x01, 0x02, 0x9c, 0x13, 0x02, 0x02, 0xa0, 0x13, 0x02, 0x02, 0xa4, 0x13, 0x02, 0x02, + 0xa8, 0x13, 0x02, 0x02, 0x30, 0x34, 0x03, 0x03, 0x38, 0x34, 0x03, 0x03, 0x40, 0x34, 0x03, 0x03, 0xd0, 0x10, 0x04, 0x03, 0xd8, 0x10, 0x04, 0x03, 0xa0, 0x30, 0x05, 0x04, 0xb0, 0x30, 0x05, 0x04, + 0x10, 0x0e, 0x06, 0x04, 0x60, 0x0a, 0x08, 0x05, 0x80, 0x04, 0x0c, 0x07, 0xc8, 0x07, 0x00, 0x02, 0xcc, 0x07, 0x00, 0x02, 0xd0, 0x07, 0x00, 0x02, 0x14, 0x38, 0x01, 0x02, 0x18, 0x38, 0x01, 0x02, + 0x1c, 0x38, 0x01, 0x02, 0x20, 0x38, 0x01, 0x02, 0x24, 0x38, 0x01, 0x02, 0x28, 0x38, 0x01, 0x02, 0x2c, 0x38, 0x01, 0x02, 0xac, 0x13, 0x02, 0x02, 0xb0, 0x13, 0x02, 0x02, 0xb4, 0x13, 0x02, 0x02, + 0xb8, 0x13, 0x02, 0x02, 0x48, 0x34, 0x03, 0x03, 0x50, 0x34, 0x03, 0x03, 0x58, 0x34, 0x03, 0x03, 0xe0, 0x10, 0x04, 0x03, 0xe8, 0x10, 0x04, 0x03, 0xc0, 0x30, 0x05, 0x04, 0xd0, 0x30, 0x05, 0x04, + 0x20, 0x0e, 0x06, 0x04, 0x80, 0x0a, 0x08, 0x05, 0x00, 0x05, 0x0c, 0x07, 0xd4, 0x07, 0x00, 0x02, 0xd8, 0x07, 0x00, 0x02, 0xdc, 0x07, 0x00, 0x02, 0x30, 0x38, 0x01, 0x02, 0x34, 0x38, 0x01, 0x02, + 0x38, 0x38, 0x01, 0x02, 0x3c, 0x38, 0x01, 0x02, 0x40, 0x38, 0x01, 0x02, 0x44, 0x38, 0x01, 0x02, 0x48, 0x38, 0x01, 0x02, 0xbc, 0x13, 0x02, 0x02, 0xc0, 0x13, 0x02, 0x02, 0xc4, 0x13, 0x02, 0x02, + 0xc8, 0x13, 0x02, 0x02, 0x60, 0x34, 0x03, 0x03, 0x68, 0x34, 0x03, 0x03, 0x70, 0x34, 0x03, 0x03, 0xf0, 0x10, 0x04, 0x03, 0xf8, 0x10, 0x04, 0x03, 0xe0, 0x30, 0x05, 0x04, 0x30, 0x0e, 0x06, 0x04, + 0x40, 0x0e, 0x06, 0x04, 0xa0, 0x0a, 0x08, 0x05, 0x80, 0x05, 0x0c, 0x07, 0xe0, 0x07, 0x00, 0x02, 0xe4, 0x07, 0x00, 0x02, 0xe8, 0x07, 0x00, 0x02, 0x4c, 0x38, 0x01, 0x02, 0x50, 0x38, 0x01, 0x02, + 0x54, 0x38, 0x01, 0x02, 0x58, 0x38, 0x01, 0x02, 0x5c, 0x38, 0x01, 0x02, 0x60, 0x38, 0x01, 0x02, 0x64, 0x38, 0x01, 0x02, 0xcc, 0x13, 0x02, 0x02, 0xd0, 0x13, 0x02, 0x02, 0xd4, 0x13, 0x02, 0x02, + 0xd8, 0x13, 0x02, 0x02, 0x78, 0x34, 0x03, 0x03, 0x80, 0x34, 0x03, 0x03, 0x88, 0x34, 0x03, 0x03, 0x00, 0x11, 0x04, 0x03, 0x08, 0x11, 0x04, 0x03, 0xf0, 0x30, 0x05, 0x04, 0x50, 0x0e, 0x06, 0x04, + 0x00, 0x2c, 0x07, 0x05, 0xc0, 0x0a, 0x08, 0x05, 0x00, 0x06, 0x0c, 0x07, 0xec, 0x07, 0x00, 0x02, 0xf0, 0x07, 0x00, 0x02, 0xf4, 0x07, 0x00, 0x02, 0x68, 0x38, 0x01, 0x02, 0x6c, 0x38, 0x01, 0x02, + 0x70, 0x38, 0x01, 0x02, 0x74, 0x38, 0x01, 0x02, 0x78, 0x38, 0x01, 0x02, 0x7c, 0x38, 0x01, 0x02, 0x80, 0x38, 0x01, 0x02, 0xdc, 0x13, 0x02, 0x02, 0xe0, 0x13, 0x02, 0x02, 0xe4, 0x13, 0x02, 0x02, + 0xe8, 0x13, 0x02, 0x02, 0x90, 0x34, 0x03, 0x03, 0x98, 0x34, 0x03, 0x03, 0xa0, 0x34, 0x03, 0x03, 0x10, 0x11, 0x04, 0x03, 0x18, 0x11, 0x04, 0x03, 0x00, 0x31, 0x05, 0x04, 0x60, 0x0e, 0x06, 0x04, + 0x20, 0x2c, 0x07, 0x05, 0xe0, 0x0a, 0x08, 0x05, 0x80, 0x06, 0x0c, 0x07, 0xf8, 0x07, 0x00, 0x02, 0xfc, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x84, 0x38, 0x01, 0x02, 0x88, 0x38, 0x01, 0x02, + 0x8c, 0x38, 0x01, 0x02, 0x90, 0x38, 0x01, 0x02, 0x94, 0x38, 0x01, 0x02, 0x98, 0x38, 0x01, 0x02, 0x9c, 0x38, 0x01, 0x02, 0xec, 0x13, 0x02, 0x02, 0xf0, 0x13, 0x02, 0x02, 0xf4, 0x13, 0x02, 0x02, + 0xf8, 0x13, 0x02, 0x02, 0xa8, 0x34, 0x03, 0x03, 0xb0, 0x34, 0x03, 0x03, 0xb8, 0x34, 0x03, 0x03, 0x20, 0x11, 0x04, 0x03, 0x28, 0x11, 0x04, 0x03, 0x10, 0x31, 0x05, 0x04, 0x70, 0x0e, 0x06, 0x04, + 0x40, 0x2c, 0x07, 0x05, 0x00, 0x0b, 0x08, 0x05, 0x00, 0x07, 0x0c, 0x07, 0x04, 0x08, 0x00, 0x02, 0x08, 0x08, 0x00, 0x02, 0x0c, 0x08, 0x00, 0x02, 0xa0, 0x38, 0x01, 0x02, 0xa4, 0x38, 0x01, 0x02, + 0xa8, 0x38, 0x01, 0x02, 0xac, 0x38, 0x01, 0x02, 0xb0, 0x38, 0x01, 0x02, 0xb4, 0x38, 0x01, 0x02, 0xb8, 0x38, 0x01, 0x02, 0xfc, 0x13, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x04, 0x14, 0x02, 0x02, + 0x08, 0x14, 0x02, 0x02, 0xc0, 0x34, 0x03, 0x03, 0xc8, 0x34, 0x03, 0x03, 0xd0, 0x34, 0x03, 0x03, 0x30, 0x11, 0x04, 0x03, 0x38, 0x11, 0x04, 0x03, 0x20, 0x31, 0x05, 0x04, 0x80, 0x0e, 0x06, 0x04, + 0x60, 0x2c, 0x07, 0x05, 0x20, 0x0b, 0x08, 0x05, 0x00, 0x1d, 0x0d, 0x08, 0x10, 0x08, 0x00, 0x02, 0x14, 0x08, 0x00, 0x02, 0x18, 0x08, 0x00, 0x02, 0xbc, 0x38, 0x01, 0x02, 0xc0, 0x38, 0x01, 0x02, + 0xc4, 0x38, 0x01, 0x02, 0xc8, 0x38, 0x01, 0x02, 0xcc, 0x38, 0x01, 0x02, 0xd0, 0x38, 0x01, 0x02, 0xd4, 0x38, 0x01, 0x02, 0x0c, 0x14, 0x02, 0x02, 0x10, 0x14, 0x02, 0x02, 0x14, 0x14, 0x02, 0x02, + 0x18, 0x14, 0x02, 0x02, 0xd8, 0x34, 0x03, 0x03, 0xe0, 0x34, 0x03, 0x03, 0xe8, 0x34, 0x03, 0x03, 0x40, 0x11, 0x04, 0x03, 0x48, 0x11, 0x04, 0x03, 0x30, 0x31, 0x05, 0x04, 0x90, 0x0e, 0x06, 0x04, + 0x80, 0x2c, 0x07, 0x05, 0x40, 0x0b, 0x08, 0x05, 0x00, 0x1e, 0x0d, 0x08, 0x1c, 0x08, 0x00, 0x02, 0x20, 0x08, 0x00, 0x02, 0x24, 0x08, 0x00, 0x02, 0xd8, 0x38, 0x01, 0x02, 0xdc, 0x38, 0x01, 0x02, + 0xe0, 0x38, 0x01, 0x02, 0xe4, 0x38, 0x01, 0x02, 0xe8, 0x38, 0x01, 0x02, 0xec, 0x38, 0x01, 0x02, 0xf0, 0x38, 0x01, 0x02, 0x1c, 0x14, 0x02, 0x02, 0x20, 0x14, 0x02, 0x02, 0x24, 0x14, 0x02, 0x02, + 0x28, 0x14, 0x02, 0x02, 0xf0, 0x34, 0x03, 0x03, 0xf8, 0x34, 0x03, 0x03, 0x00, 0x35, 0x03, 0x03, 0x50, 0x11, 0x04, 0x03, 0x58, 0x11, 0x04, 0x03, 0x40, 0x31, 0x05, 0x04, 0xa0, 0x0e, 0x06, 0x04, + 0xa0, 0x2c, 0x07, 0x05, 0x60, 0x0b, 0x08, 0x05, 0x00, 0x1f, 0x0d, 0x08, 0x28, 0x08, 0x00, 0x02, 0x2c, 0x08, 0x00, 0x02, 0x30, 0x08, 0x00, 0x02, 0xf4, 0x38, 0x01, 0x02, 0xf8, 0x38, 0x01, 0x02, + 0xfc, 0x38, 0x01, 0x02, 0x00, 0x39, 0x01, 0x02, 0x04, 0x39, 0x01, 0x02, 0x08, 0x39, 0x01, 0x02, 0x0c, 0x39, 0x01, 0x02, 0x2c, 0x14, 0x02, 0x02, 0x30, 0x14, 0x02, 0x02, 0x34, 0x14, 0x02, 0x02, + 0x38, 0x14, 0x02, 0x02, 0x08, 0x35, 0x03, 0x03, 0x10, 0x35, 0x03, 0x03, 0x18, 0x35, 0x03, 0x03, 0x60, 0x11, 0x04, 0x03, 0x68, 0x11, 0x04, 0x03, 0x50, 0x31, 0x05, 0x04, 0xb0, 0x0e, 0x06, 0x04, + 0xc0, 0x2c, 0x07, 0x05, 0x80, 0x0b, 0x08, 0x05, 0x00, 0x20, 0x0d, 0x08, 0x34, 0x08, 0x00, 0x02, 0x38, 0x08, 0x00, 0x02, 0x3c, 0x08, 0x00, 0x02, 0x10, 0x39, 0x01, 0x02, 0x14, 0x39, 0x01, 0x02, + 0x18, 0x39, 0x01, 0x02, 0x1c, 0x39, 0x01, 0x02, 0x20, 0x39, 0x01, 0x02, 0x24, 0x39, 0x01, 0x02, 0x28, 0x39, 0x01, 0x02, 0x3c, 0x14, 0x02, 0x02, 0x40, 0x14, 0x02, 0x02, 0x44, 0x14, 0x02, 0x02, + 0x48, 0x14, 0x02, 0x02, 0x20, 0x35, 0x03, 0x03, 0x28, 0x35, 0x03, 0x03, 0x30, 0x35, 0x03, 0x03, 0x70, 0x11, 0x04, 0x03, 0x78, 0x11, 0x04, 0x03, 0x60, 0x31, 0x05, 0x04, 0xc0, 0x0e, 0x06, 0x04, + 0xe0, 0x2c, 0x07, 0x05, 0xa0, 0x0b, 0x08, 0x05, 0x00, 0x21, 0x0d, 0x08, 0x40, 0x08, 0x00, 0x02, 0x44, 0x08, 0x00, 0x02, 0x48, 0x08, 0x00, 0x02, 0x2c, 0x39, 0x01, 0x02, 0x30, 0x39, 0x01, 0x02, + 0x34, 0x39, 0x01, 0x02, 0x38, 0x39, 0x01, 0x02, 0x3c, 0x39, 0x01, 0x02, 0x40, 0x39, 0x01, 0x02, 0x44, 0x39, 0x01, 0x02, 0x4c, 0x14, 0x02, 0x02, 0x50, 0x14, 0x02, 0x02, 0x54, 0x14, 0x02, 0x02, + 0x58, 0x14, 0x02, 0x02, 0x38, 0x35, 0x03, 0x03, 0x40, 0x35, 0x03, 0x03, 0x48, 0x35, 0x03, 0x03, 0x80, 0x11, 0x04, 0x03, 0x88, 0x11, 0x04, 0x03, 0x70, 0x31, 0x05, 0x04, 0xd0, 0x0e, 0x06, 0x04, + 0x00, 0x2d, 0x07, 0x05, 0xc0, 0x0b, 0x08, 0x05, 0x00, 0x22, 0x0d, 0x08, 0x4c, 0x08, 0x00, 0x02, 0x50, 0x08, 0x00, 0x02, 0x54, 0x08, 0x00, 0x02, 0x48, 0x39, 0x01, 0x02, 0x4c, 0x39, 0x01, 0x02, + 0x50, 0x39, 0x01, 0x02, 0x54, 0x39, 0x01, 0x02, 0x58, 0x39, 0x01, 0x02, 0x5c, 0x39, 0x01, 0x02, 0x60, 0x39, 0x01, 0x02, 0x5c, 0x14, 0x02, 0x02, 0x60, 0x14, 0x02, 0x02, 0x64, 0x14, 0x02, 0x02, + 0x68, 0x14, 0x02, 0x02, 0x50, 0x35, 0x03, 0x03, 0x58, 0x35, 0x03, 0x03, 0x60, 0x35, 0x03, 0x03, 0x90, 0x11, 0x04, 0x03, 0x98, 0x11, 0x04, 0x03, 0x80, 0x31, 0x05, 0x04, 0xe0, 0x0e, 0x06, 0x04, + 0x20, 0x2d, 0x07, 0x05, 0xe0, 0x0b, 0x08, 0x05, 0x00, 0x01, 0x0e, 0x08, 0x58, 0x08, 0x00, 0x02, 0x5c, 0x08, 0x00, 0x02, 0x60, 0x08, 0x00, 0x02, 0x64, 0x39, 0x01, 0x02, 0x68, 0x39, 0x01, 0x02, + 0x6c, 0x39, 0x01, 0x02, 0x70, 0x39, 0x01, 0x02, 0x74, 0x39, 0x01, 0x02, 0x78, 0x39, 0x01, 0x02, 0x7c, 0x39, 0x01, 0x02, 0x6c, 0x14, 0x02, 0x02, 0x70, 0x14, 0x02, 0x02, 0x74, 0x14, 0x02, 0x02, + 0x78, 0x14, 0x02, 0x02, 0x68, 0x35, 0x03, 0x03, 0x70, 0x35, 0x03, 0x03, 0x78, 0x35, 0x03, 0x03, 0xa0, 0x11, 0x04, 0x03, 0xa8, 0x11, 0x04, 0x03, 0x90, 0x31, 0x05, 0x04, 0xf0, 0x0e, 0x06, 0x04, + 0x40, 0x2d, 0x07, 0x05, 0x00, 0x0c, 0x08, 0x05, 0x00, 0x02, 0x0e, 0x08, 0x64, 0x08, 0x00, 0x02, 0x68, 0x08, 0x00, 0x02, 0x6c, 0x08, 0x00, 0x02, 0x80, 0x39, 0x01, 0x02, 0x84, 0x39, 0x01, 0x02, + 0x88, 0x39, 0x01, 0x02, 0x8c, 0x39, 0x01, 0x02, 0x90, 0x39, 0x01, 0x02, 0x94, 0x39, 0x01, 0x02, 0x98, 0x39, 0x01, 0x02, 0x7c, 0x14, 0x02, 0x02, 0x80, 0x14, 0x02, 0x02, 0x84, 0x14, 0x02, 0x02, + 0x88, 0x14, 0x02, 0x02, 0x80, 0x35, 0x03, 0x03, 0x88, 0x35, 0x03, 0x03, 0x90, 0x35, 0x03, 0x03, 0xb0, 0x11, 0x04, 0x03, 0xb8, 0x11, 0x04, 0x03, 0xa0, 0x31, 0x05, 0x04, 0x00, 0x0f, 0x06, 0x04, + 0x60, 0x2d, 0x07, 0x05, 0x20, 0x0c, 0x08, 0x05, 0x00, 0x03, 0x0e, 0x08, 0x70, 0x08, 0x00, 0x02, 0x74, 0x08, 0x00, 0x02, 0x78, 0x08, 0x00, 0x02, 0x9c, 0x39, 0x01, 0x02, 0xa0, 0x39, 0x01, 0x02, + 0xa4, 0x39, 0x01, 0x02, 0xa8, 0x39, 0x01, 0x02, 0xac, 0x39, 0x01, 0x02, 0xb0, 0x39, 0x01, 0x02, 0xb4, 0x39, 0x01, 0x02, 0x8c, 0x14, 0x02, 0x02, 0x90, 0x14, 0x02, 0x02, 0x94, 0x14, 0x02, 0x02, + 0x98, 0x14, 0x02, 0x02, 0x98, 0x35, 0x03, 0x03, 0xa0, 0x35, 0x03, 0x03, 0xa8, 0x35, 0x03, 0x03, 0xc0, 0x11, 0x04, 0x03, 0xc8, 0x11, 0x04, 0x03, 0xb0, 0x31, 0x05, 0x04, 0x10, 0x0f, 0x06, 0x04, + 0x80, 0x2d, 0x07, 0x05, 0x40, 0x0c, 0x08, 0x05, 0x00, 0x04, 0x0e, 0x08, 0x7c, 0x08, 0x00, 0x02, 0x80, 0x08, 0x00, 0x02, 0x84, 0x08, 0x00, 0x02, 0xb8, 0x39, 0x01, 0x02, 0xbc, 0x39, 0x01, 0x02, + 0xc0, 0x39, 0x01, 0x02, 0xc4, 0x39, 0x01, 0x02, 0xc8, 0x39, 0x01, 0x02, 0xcc, 0x39, 0x01, 0x02, 0xd0, 0x39, 0x01, 0x02, 0x9c, 0x14, 0x02, 0x02, 0xa0, 0x14, 0x02, 0x02, 0xa4, 0x14, 0x02, 0x02, + 0xa8, 0x14, 0x02, 0x02, 0xb0, 0x35, 0x03, 0x03, 0xb8, 0x35, 0x03, 0x03, 0xc0, 0x35, 0x03, 0x03, 0xd0, 0x11, 0x04, 0x03, 0xd8, 0x11, 0x04, 0x03, 0xc0, 0x31, 0x05, 0x04, 0x20, 0x0f, 0x06, 0x04, + 0xa0, 0x2d, 0x07, 0x05, 0x60, 0x0c, 0x08, 0x05, 0x00, 0x05, 0x0e, 0x08, 0x88, 0x08, 0x00, 0x02, 0x8c, 0x08, 0x00, 0x02, 0x90, 0x08, 0x00, 0x02, 0xd4, 0x39, 0x01, 0x02, 0xd8, 0x39, 0x01, 0x02, + 0xdc, 0x39, 0x01, 0x02, 0xe0, 0x39, 0x01, 0x02, 0xe4, 0x39, 0x01, 0x02, 0xe8, 0x39, 0x01, 0x02, 0xac, 0x14, 0x02, 0x02, 0xb0, 0x14, 0x02, 0x02, 0xb4, 0x14, 0x02, 0x02, 0xb8, 0x14, 0x02, 0x02, + 0xbc, 0x14, 0x02, 0x02, 0xc8, 0x35, 0x03, 0x03, 0xd0, 0x35, 0x03, 0x03, 0xd8, 0x35, 0x03, 0x03, 0xe0, 0x11, 0x04, 0x03, 0xe8, 0x11, 0x04, 0x03, 0xd0, 0x31, 0x05, 0x04, 0x30, 0x0f, 0x06, 0x04, + 0xc0, 0x2d, 0x07, 0x05, 0x80, 0x0c, 0x08, 0x05, 0x00, 0x1e, 0x0f, 0x09, 0x94, 0x08, 0x00, 0x02, 0x98, 0x08, 0x00, 0x02, 0x9c, 0x08, 0x00, 0x02, 0xec, 0x39, 0x01, 0x02, 0xf0, 0x39, 0x01, 0x02, + 0xf4, 0x39, 0x01, 0x02, 0xf8, 0x39, 0x01, 0x02, 0xfc, 0x39, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0xc0, 0x14, 0x02, 0x02, 0xc4, 0x14, 0x02, 0x02, 0xc8, 0x14, 0x02, 0x02, 0xcc, 0x14, 0x02, 0x02, + 0xd0, 0x14, 0x02, 0x02, 0xe0, 0x35, 0x03, 0x03, 0xe8, 0x35, 0x03, 0x03, 0xf0, 0x35, 0x03, 0x03, 0xf0, 0x11, 0x04, 0x03, 0xf8, 0x11, 0x04, 0x03, 0xe0, 0x31, 0x05, 0x04, 0x40, 0x0f, 0x06, 0x04, + 0xe0, 0x2d, 0x07, 0x05, 0x00, 0x2a, 0x09, 0x06, 0x00, 0x20, 0x0f, 0x09, 0xa0, 0x08, 0x00, 0x02, 0xa4, 0x08, 0x00, 0x02, 0xa8, 0x08, 0x00, 0x02, 0x04, 0x3a, 0x01, 0x02, 0x08, 0x3a, 0x01, 0x02, + 0x0c, 0x3a, 0x01, 0x02, 0x10, 0x3a, 0x01, 0x02, 0x14, 0x3a, 0x01, 0x02, 0x18, 0x3a, 0x01, 0x02, 0xd4, 0x14, 0x02, 0x02, 0xd8, 0x14, 0x02, 0x02, 0xdc, 0x14, 0x02, 0x02, 0xe0, 0x14, 0x02, 0x02, + 0xe4, 0x14, 0x02, 0x02, 0xf8, 0x35, 0x03, 0x03, 0x00, 0x36, 0x03, 0x03, 0x08, 0x36, 0x03, 0x03, 0x00, 0x12, 0x04, 0x03, 0x08, 0x12, 0x04, 0x03, 0xf0, 0x31, 0x05, 0x04, 0x50, 0x0f, 0x06, 0x04, + 0x00, 0x2e, 0x07, 0x05, 0x40, 0x2a, 0x09, 0x06, 0x00, 0x22, 0x0f, 0x09, 0xac, 0x08, 0x00, 0x02, 0xb0, 0x08, 0x00, 0x02, 0xb4, 0x08, 0x00, 0x02, 0x1c, 0x3a, 0x01, 0x02, 0x20, 0x3a, 0x01, 0x02, + 0x24, 0x3a, 0x01, 0x02, 0x28, 0x3a, 0x01, 0x02, 0x2c, 0x3a, 0x01, 0x02, 0x30, 0x3a, 0x01, 0x02, 0xe8, 0x14, 0x02, 0x02, 0xec, 0x14, 0x02, 0x02, 0xf0, 0x14, 0x02, 0x02, 0xf4, 0x14, 0x02, 0x02, + 0xf8, 0x14, 0x02, 0x02, 0x10, 0x36, 0x03, 0x03, 0x18, 0x36, 0x03, 0x03, 0x20, 0x36, 0x03, 0x03, 0x10, 0x12, 0x04, 0x03, 0x18, 0x12, 0x04, 0x03, 0x00, 0x32, 0x05, 0x04, 0x60, 0x0f, 0x06, 0x04, + 0x20, 0x2e, 0x07, 0x05, 0x80, 0x2a, 0x09, 0x06, 0x00, 0x02, 0x10, 0x09, 0xb8, 0x08, 0x00, 0x02, 0xbc, 0x08, 0x00, 0x02, 0xc0, 0x08, 0x00, 0x02, 0x34, 0x3a, 0x01, 0x02, 0x38, 0x3a, 0x01, 0x02, + 0x3c, 0x3a, 0x01, 0x02, 0x40, 0x3a, 0x01, 0x02, 0x44, 0x3a, 0x01, 0x02, 0x48, 0x3a, 0x01, 0x02, 0xfc, 0x14, 0x02, 0x02, 0x00, 0x15, 0x02, 0x02, 0x04, 0x15, 0x02, 0x02, 0x08, 0x15, 0x02, 0x02, + 0x0c, 0x15, 0x02, 0x02, 0x28, 0x36, 0x03, 0x03, 0x30, 0x36, 0x03, 0x03, 0x38, 0x36, 0x03, 0x03, 0x20, 0x12, 0x04, 0x03, 0x28, 0x12, 0x04, 0x03, 0x10, 0x32, 0x05, 0x04, 0x70, 0x0f, 0x06, 0x04, + 0x40, 0x2e, 0x07, 0x05, 0xc0, 0x2a, 0x09, 0x06, 0x00, 0x04, 0x10, 0x09, 0xc4, 0x08, 0x00, 0x02, 0xc8, 0x08, 0x00, 0x02, 0xcc, 0x08, 0x00, 0x02, 0x4c, 0x3a, 0x01, 0x02, 0x50, 0x3a, 0x01, 0x02, + 0x54, 0x3a, 0x01, 0x02, 0x58, 0x3a, 0x01, 0x02, 0x5c, 0x3a, 0x01, 0x02, 0x60, 0x3a, 0x01, 0x02, 0x10, 0x15, 0x02, 0x02, 0x14, 0x15, 0x02, 0x02, 0x18, 0x15, 0x02, 0x02, 0x1c, 0x15, 0x02, 0x02, + 0x20, 0x15, 0x02, 0x02, 0x40, 0x36, 0x03, 0x03, 0x48, 0x36, 0x03, 0x03, 0x50, 0x36, 0x03, 0x03, 0x30, 0x12, 0x04, 0x03, 0x38, 0x12, 0x04, 0x03, 0x20, 0x32, 0x05, 0x04, 0x80, 0x0f, 0x06, 0x04, + 0x60, 0x2e, 0x07, 0x05, 0x00, 0x2b, 0x09, 0x06, 0x00, 0x06, 0x10, 0x09, 0xd0, 0x08, 0x00, 0x02, 0xd4, 0x08, 0x00, 0x02, 0xd8, 0x08, 0x00, 0x02, 0x64, 0x3a, 0x01, 0x02, 0x68, 0x3a, 0x01, 0x02, + 0x6c, 0x3a, 0x01, 0x02, 0x70, 0x3a, 0x01, 0x02, 0x74, 0x3a, 0x01, 0x02, 0x78, 0x3a, 0x01, 0x02, 0x24, 0x15, 0x02, 0x02, 0x28, 0x15, 0x02, 0x02, 0x2c, 0x15, 0x02, 0x02, 0x30, 0x15, 0x02, 0x02, + 0x34, 0x15, 0x02, 0x02, 0x58, 0x36, 0x03, 0x03, 0x60, 0x36, 0x03, 0x03, 0x68, 0x36, 0x03, 0x03, 0x40, 0x12, 0x04, 0x03, 0x48, 0x12, 0x04, 0x03, 0x30, 0x32, 0x05, 0x04, 0x90, 0x0f, 0x06, 0x04, + 0x80, 0x2e, 0x07, 0x05, 0x40, 0x2b, 0x09, 0x06, 0x00, 0x18, 0x11, 0x0a, 0xdc, 0x08, 0x00, 0x02, 0xe0, 0x08, 0x00, 0x02, 0xe4, 0x08, 0x00, 0x02, 0x7c, 0x3a, 0x01, 0x02, 0x80, 0x3a, 0x01, 0x02, + 0x84, 0x3a, 0x01, 0x02, 0x88, 0x3a, 0x01, 0x02, 0x8c, 0x3a, 0x01, 0x02, 0x90, 0x3a, 0x01, 0x02, 0x38, 0x15, 0x02, 0x02, 0x3c, 0x15, 0x02, 0x02, 0x40, 0x15, 0x02, 0x02, 0x44, 0x15, 0x02, 0x02, + 0x48, 0x15, 0x02, 0x02, 0x70, 0x36, 0x03, 0x03, 0x78, 0x36, 0x03, 0x03, 0x80, 0x36, 0x03, 0x03, 0x50, 0x12, 0x04, 0x03, 0x58, 0x12, 0x04, 0x03, 0x40, 0x32, 0x05, 0x04, 0xa0, 0x0f, 0x06, 0x04, + 0xa0, 0x2e, 0x07, 0x05, 0x80, 0x2b, 0x09, 0x06, 0x00, 0x1c, 0x11, 0x0a, 0xe8, 0x08, 0x00, 0x02, 0xec, 0x08, 0x00, 0x02, 0xf0, 0x08, 0x00, 0x02, 0x94, 0x3a, 0x01, 0x02, 0x98, 0x3a, 0x01, 0x02, + 0x9c, 0x3a, 0x01, 0x02, 0xa0, 0x3a, 0x01, 0x02, 0xa4, 0x3a, 0x01, 0x02, 0xa8, 0x3a, 0x01, 0x02, 0x4c, 0x15, 0x02, 0x02, 0x50, 0x15, 0x02, 0x02, 0x54, 0x15, 0x02, 0x02, 0x58, 0x15, 0x02, 0x02, + 0x5c, 0x15, 0x02, 0x02, 0x88, 0x36, 0x03, 0x03, 0x90, 0x36, 0x03, 0x03, 0x98, 0x36, 0x03, 0x03, 0x60, 0x12, 0x04, 0x03, 0x68, 0x12, 0x04, 0x03, 0x50, 0x32, 0x05, 0x04, 0xb0, 0x0f, 0x06, 0x04, + 0xc0, 0x2e, 0x07, 0x05, 0xc0, 0x2b, 0x09, 0x06, 0x00, 0x04, 0x12, 0x0a, 0xf4, 0x08, 0x00, 0x02, 0xf8, 0x08, 0x00, 0x02, 0xfc, 0x08, 0x00, 0x02, 0xac, 0x3a, 0x01, 0x02, 0xb0, 0x3a, 0x01, 0x02, + 0xb4, 0x3a, 0x01, 0x02, 0xb8, 0x3a, 0x01, 0x02, 0xbc, 0x3a, 0x01, 0x02, 0xc0, 0x3a, 0x01, 0x02, 0x60, 0x15, 0x02, 0x02, 0x64, 0x15, 0x02, 0x02, 0x68, 0x15, 0x02, 0x02, 0x6c, 0x15, 0x02, 0x02, + 0x70, 0x15, 0x02, 0x02, 0xa0, 0x36, 0x03, 0x03, 0xa8, 0x36, 0x03, 0x03, 0xb0, 0x36, 0x03, 0x03, 0x70, 0x12, 0x04, 0x03, 0x78, 0x12, 0x04, 0x03, 0x60, 0x32, 0x05, 0x04, 0xc0, 0x0f, 0x06, 0x04, + 0xe0, 0x2e, 0x07, 0x05, 0x00, 0x2c, 0x09, 0x06, 0x00, 0x18, 0x13, 0x0b, 0x00, 0x09, 0x00, 0x02, 0x04, 0x09, 0x00, 0x02, 0x08, 0x09, 0x00, 0x02, 0xc4, 0x3a, 0x01, 0x02, 0xc8, 0x3a, 0x01, 0x02, + 0xcc, 0x3a, 0x01, 0x02, 0xd0, 0x3a, 0x01, 0x02, 0xd4, 0x3a, 0x01, 0x02, 0xd8, 0x3a, 0x01, 0x02, 0x74, 0x15, 0x02, 0x02, 0x78, 0x15, 0x02, 0x02, 0x7c, 0x15, 0x02, 0x02, 0x80, 0x15, 0x02, 0x02, + 0x84, 0x15, 0x02, 0x02, 0xb8, 0x36, 0x03, 0x03, 0xc0, 0x36, 0x03, 0x03, 0xc8, 0x36, 0x03, 0x03, 0x80, 0x12, 0x04, 0x03, 0x88, 0x12, 0x04, 0x03, 0x70, 0x32, 0x05, 0x04, 0xd0, 0x0f, 0x06, 0x04, + 0x00, 0x2f, 0x07, 0x05, 0x40, 0x2c, 0x09, 0x06, 0x00, 0x10, 0x15, 0x0c, 0x0c, 0x09, 0x00, 0x02, 0x10, 0x09, 0x00, 0x02, 0x14, 0x09, 0x00, 0x02, 0xdc, 0x3a, 0x01, 0x02, 0xe0, 0x3a, 0x01, 0x02, + 0xe4, 0x3a, 0x01, 0x02, 0xe8, 0x3a, 0x01, 0x02, 0xec, 0x3a, 0x01, 0x02, 0xf0, 0x3a, 0x01, 0x02, 0x88, 0x15, 0x02, 0x02, 0x8c, 0x15, 0x02, 0x02, 0x90, 0x15, 0x02, 0x02, 0x94, 0x15, 0x02, 0x02, + 0x98, 0x15, 0x02, 0x02, 0xd0, 0x36, 0x03, 0x03, 0xd8, 0x36, 0x03, 0x03, 0xe0, 0x36, 0x03, 0x03, 0x90, 0x12, 0x04, 0x03, 0x98, 0x12, 0x04, 0x03, 0x80, 0x32, 0x05, 0x04, 0xe0, 0x0f, 0x06, 0x04, + 0x20, 0x2f, 0x07, 0x05, 0x80, 0x2c, 0x09, 0x06, 0x18, 0x09, 0x00, 0x02, 0x1c, 0x09, 0x00, 0x02, 0x20, 0x09, 0x00, 0x02, 0x24, 0x09, 0x00, 0x02, 0xf4, 0x3a, 0x01, 0x02, 0xf8, 0x3a, 0x01, 0x02, + 0xfc, 0x3a, 0x01, 0x02, 0x00, 0x3b, 0x01, 0x02, 0x04, 0x3b, 0x01, 0x02, 0x08, 0x3b, 0x01, 0x02, 0x9c, 0x15, 0x02, 0x02, 0xa0, 0x15, 0x02, 0x02, 0xa4, 0x15, 0x02, 0x02, 0xa8, 0x15, 0x02, 0x02, + 0xac, 0x15, 0x02, 0x02, 0xe8, 0x36, 0x03, 0x03, 0xf0, 0x36, 0x03, 0x03, 0xf8, 0x36, 0x03, 0x03, 0xa0, 0x12, 0x04, 0x03, 0xa8, 0x12, 0x04, 0x03, 0x90, 0x32, 0x05, 0x04, 0xf0, 0x0f, 0x06, 0x04, + 0x40, 0x2f, 0x07, 0x05, 0xc0, 0x2c, 0x09, 0x06, 0x28, 0x09, 0x00, 0x02, 0x2c, 0x09, 0x00, 0x02, 0x30, 0x09, 0x00, 0x02, 0x34, 0x09, 0x00, 0x02, 0x0c, 0x3b, 0x01, 0x02, 0x10, 0x3b, 0x01, 0x02, + 0x14, 0x3b, 0x01, 0x02, 0x18, 0x3b, 0x01, 0x02, 0x1c, 0x3b, 0x01, 0x02, 0x20, 0x3b, 0x01, 0x02, 0xb0, 0x15, 0x02, 0x02, 0xb4, 0x15, 0x02, 0x02, 0xb8, 0x15, 0x02, 0x02, 0xbc, 0x15, 0x02, 0x02, + 0xc0, 0x15, 0x02, 0x02, 0x00, 0x37, 0x03, 0x03, 0x08, 0x37, 0x03, 0x03, 0x10, 0x37, 0x03, 0x03, 0xb0, 0x12, 0x04, 0x03, 0xb8, 0x12, 0x04, 0x03, 0xa0, 0x32, 0x05, 0x04, 0x00, 0x10, 0x06, 0x04, + 0x60, 0x2f, 0x07, 0x05, 0x00, 0x2d, 0x09, 0x06, 0x38, 0x09, 0x00, 0x02, 0x3c, 0x09, 0x00, 0x02, 0x40, 0x09, 0x00, 0x02, 0x44, 0x09, 0x00, 0x02, 0x24, 0x3b, 0x01, 0x02, 0x28, 0x3b, 0x01, 0x02, + 0x2c, 0x3b, 0x01, 0x02, 0x30, 0x3b, 0x01, 0x02, 0x34, 0x3b, 0x01, 0x02, 0x38, 0x3b, 0x01, 0x02, 0xc4, 0x15, 0x02, 0x02, 0xc8, 0x15, 0x02, 0x02, 0xcc, 0x15, 0x02, 0x02, 0xd0, 0x15, 0x02, 0x02, + 0xd4, 0x15, 0x02, 0x02, 0x18, 0x37, 0x03, 0x03, 0x20, 0x37, 0x03, 0x03, 0x28, 0x37, 0x03, 0x03, 0xc0, 0x12, 0x04, 0x03, 0xc8, 0x12, 0x04, 0x03, 0xb0, 0x32, 0x05, 0x04, 0x10, 0x10, 0x06, 0x04, + 0x80, 0x2f, 0x07, 0x05, 0x40, 0x2d, 0x09, 0x06, 0x48, 0x09, 0x00, 0x02, 0x4c, 0x09, 0x00, 0x02, 0x50, 0x09, 0x00, 0x02, 0x54, 0x09, 0x00, 0x02, 0x3c, 0x3b, 0x01, 0x02, 0x40, 0x3b, 0x01, 0x02, + 0x44, 0x3b, 0x01, 0x02, 0x48, 0x3b, 0x01, 0x02, 0x4c, 0x3b, 0x01, 0x02, 0x50, 0x3b, 0x01, 0x02, 0xd8, 0x15, 0x02, 0x02, 0xdc, 0x15, 0x02, 0x02, 0xe0, 0x15, 0x02, 0x02, 0xe4, 0x15, 0x02, 0x02, + 0xe8, 0x15, 0x02, 0x02, 0x30, 0x37, 0x03, 0x03, 0x38, 0x37, 0x03, 0x03, 0x40, 0x37, 0x03, 0x03, 0xd0, 0x12, 0x04, 0x03, 0xd8, 0x12, 0x04, 0x03, 0xc0, 0x32, 0x05, 0x04, 0x20, 0x10, 0x06, 0x04, + 0xa0, 0x2f, 0x07, 0x05, 0x80, 0x2d, 0x09, 0x06, 0x58, 0x09, 0x00, 0x02, 0x5c, 0x09, 0x00, 0x02, 0x60, 0x09, 0x00, 0x02, 0x64, 0x09, 0x00, 0x02, 0x54, 0x3b, 0x01, 0x02, 0x58, 0x3b, 0x01, 0x02, + 0x5c, 0x3b, 0x01, 0x02, 0x60, 0x3b, 0x01, 0x02, 0x64, 0x3b, 0x01, 0x02, 0x68, 0x3b, 0x01, 0x02, 0xec, 0x15, 0x02, 0x02, 0xf0, 0x15, 0x02, 0x02, 0xf4, 0x15, 0x02, 0x02, 0xf8, 0x15, 0x02, 0x02, + 0xfc, 0x15, 0x02, 0x02, 0x48, 0x37, 0x03, 0x03, 0x50, 0x37, 0x03, 0x03, 0x58, 0x37, 0x03, 0x03, 0xe0, 0x12, 0x04, 0x03, 0xe8, 0x12, 0x04, 0x03, 0xd0, 0x32, 0x05, 0x04, 0x30, 0x10, 0x06, 0x04, + 0xc0, 0x2f, 0x07, 0x05, 0xc0, 0x2d, 0x09, 0x06, 0x68, 0x09, 0x00, 0x02, 0x6c, 0x09, 0x00, 0x02, 0x70, 0x09, 0x00, 0x02, 0x74, 0x09, 0x00, 0x02, 0x6c, 0x3b, 0x01, 0x02, 0x70, 0x3b, 0x01, 0x02, + 0x74, 0x3b, 0x01, 0x02, 0x78, 0x3b, 0x01, 0x02, 0x7c, 0x3b, 0x01, 0x02, 0x80, 0x3b, 0x01, 0x02, 0x00, 0x16, 0x02, 0x02, 0x04, 0x16, 0x02, 0x02, 0x08, 0x16, 0x02, 0x02, 0x0c, 0x16, 0x02, 0x02, + 0x10, 0x16, 0x02, 0x02, 0x60, 0x37, 0x03, 0x03, 0x68, 0x37, 0x03, 0x03, 0x70, 0x37, 0x03, 0x03, 0xf0, 0x12, 0x04, 0x03, 0xf8, 0x12, 0x04, 0x03, 0xe0, 0x32, 0x05, 0x04, 0x40, 0x10, 0x06, 0x04, + 0xe0, 0x2f, 0x07, 0x05, 0x00, 0x2e, 0x09, 0x06, 0x78, 0x09, 0x00, 0x02, 0x7c, 0x09, 0x00, 0x02, 0x80, 0x09, 0x00, 0x02, 0x84, 0x09, 0x00, 0x02, 0x84, 0x3b, 0x01, 0x02, 0x88, 0x3b, 0x01, 0x02, + 0x8c, 0x3b, 0x01, 0x02, 0x90, 0x3b, 0x01, 0x02, 0x94, 0x3b, 0x01, 0x02, 0x98, 0x3b, 0x01, 0x02, 0x14, 0x16, 0x02, 0x02, 0x18, 0x16, 0x02, 0x02, 0x1c, 0x16, 0x02, 0x02, 0x20, 0x16, 0x02, 0x02, + 0x24, 0x16, 0x02, 0x02, 0x78, 0x37, 0x03, 0x03, 0x80, 0x37, 0x03, 0x03, 0x88, 0x37, 0x03, 0x03, 0x00, 0x13, 0x04, 0x03, 0x08, 0x13, 0x04, 0x03, 0xf0, 0x32, 0x05, 0x04, 0x50, 0x10, 0x06, 0x04, + 0x00, 0x30, 0x07, 0x05, 0x40, 0x2e, 0x09, 0x06, 0x88, 0x09, 0x00, 0x02, 0x8c, 0x09, 0x00, 0x02, 0x90, 0x09, 0x00, 0x02, 0x94, 0x09, 0x00, 0x02, 0x9c, 0x3b, 0x01, 0x02, 0xa0, 0x3b, 0x01, 0x02, + 0xa4, 0x3b, 0x01, 0x02, 0xa8, 0x3b, 0x01, 0x02, 0xac, 0x3b, 0x01, 0x02, 0xb0, 0x3b, 0x01, 0x02, 0x28, 0x16, 0x02, 0x02, 0x2c, 0x16, 0x02, 0x02, 0x30, 0x16, 0x02, 0x02, 0x34, 0x16, 0x02, 0x02, + 0x38, 0x16, 0x02, 0x02, 0x90, 0x37, 0x03, 0x03, 0x98, 0x37, 0x03, 0x03, 0xa0, 0x37, 0x03, 0x03, 0x10, 0x13, 0x04, 0x03, 0x18, 0x13, 0x04, 0x03, 0x00, 0x33, 0x05, 0x04, 0x60, 0x10, 0x06, 0x04, + 0x20, 0x30, 0x07, 0x05, 0x80, 0x2e, 0x09, 0x06, 0x98, 0x09, 0x00, 0x02, 0x9c, 0x09, 0x00, 0x02, 0xa0, 0x09, 0x00, 0x02, 0xa4, 0x09, 0x00, 0x02, 0xb4, 0x3b, 0x01, 0x02, 0xb8, 0x3b, 0x01, 0x02, + 0xbc, 0x3b, 0x01, 0x02, 0xc0, 0x3b, 0x01, 0x02, 0xc4, 0x3b, 0x01, 0x02, 0xc8, 0x3b, 0x01, 0x02, 0x3c, 0x16, 0x02, 0x02, 0x40, 0x16, 0x02, 0x02, 0x44, 0x16, 0x02, 0x02, 0x48, 0x16, 0x02, 0x02, + 0x4c, 0x16, 0x02, 0x02, 0xa8, 0x37, 0x03, 0x03, 0xb0, 0x37, 0x03, 0x03, 0xb8, 0x37, 0x03, 0x03, 0x20, 0x13, 0x04, 0x03, 0x28, 0x13, 0x04, 0x03, 0x10, 0x33, 0x05, 0x04, 0x70, 0x10, 0x06, 0x04, + 0x40, 0x30, 0x07, 0x05, 0xc0, 0x2e, 0x09, 0x06, 0xa8, 0x09, 0x00, 0x02, 0xac, 0x09, 0x00, 0x02, 0xb0, 0x09, 0x00, 0x02, 0xb4, 0x09, 0x00, 0x02, 0xcc, 0x3b, 0x01, 0x02, 0xd0, 0x3b, 0x01, 0x02, + 0xd4, 0x3b, 0x01, 0x02, 0xd8, 0x3b, 0x01, 0x02, 0xdc, 0x3b, 0x01, 0x02, 0xe0, 0x3b, 0x01, 0x02, 0x50, 0x16, 0x02, 0x02, 0x54, 0x16, 0x02, 0x02, 0x58, 0x16, 0x02, 0x02, 0x5c, 0x16, 0x02, 0x02, + 0x60, 0x16, 0x02, 0x02, 0xc0, 0x37, 0x03, 0x03, 0xc8, 0x37, 0x03, 0x03, 0xd0, 0x37, 0x03, 0x03, 0x30, 0x13, 0x04, 0x03, 0x38, 0x13, 0x04, 0x03, 0x20, 0x33, 0x05, 0x04, 0x80, 0x10, 0x06, 0x04, + 0x60, 0x30, 0x07, 0x05, 0x00, 0x2f, 0x09, 0x06, 0xb8, 0x09, 0x00, 0x02, 0xbc, 0x09, 0x00, 0x02, 0xc0, 0x09, 0x00, 0x02, 0xc4, 0x09, 0x00, 0x02, 0xe4, 0x3b, 0x01, 0x02, 0xe8, 0x3b, 0x01, 0x02, + 0xec, 0x3b, 0x01, 0x02, 0xf0, 0x3b, 0x01, 0x02, 0xf4, 0x3b, 0x01, 0x02, 0xf8, 0x3b, 0x01, 0x02, 0x64, 0x16, 0x02, 0x02, 0x68, 0x16, 0x02, 0x02, 0x6c, 0x16, 0x02, 0x02, 0x70, 0x16, 0x02, 0x02, + 0x74, 0x16, 0x02, 0x02, 0xd8, 0x37, 0x03, 0x03, 0xe0, 0x37, 0x03, 0x03, 0xe8, 0x37, 0x03, 0x03, 0x40, 0x13, 0x04, 0x03, 0x48, 0x13, 0x04, 0x03, 0x30, 0x33, 0x05, 0x04, 0x90, 0x10, 0x06, 0x04, + 0x80, 0x30, 0x07, 0x05, 0x40, 0x2f, 0x09, 0x06, 0xc8, 0x09, 0x00, 0x02, 0xcc, 0x09, 0x00, 0x02, 0xd0, 0x09, 0x00, 0x02, 0xd4, 0x09, 0x00, 0x02, 0xfc, 0x3b, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, + 0x04, 0x3c, 0x01, 0x02, 0x08, 0x3c, 0x01, 0x02, 0x0c, 0x3c, 0x01, 0x02, 0x10, 0x3c, 0x01, 0x02, 0x78, 0x16, 0x02, 0x02, 0x7c, 0x16, 0x02, 0x02, 0x80, 0x16, 0x02, 0x02, 0x84, 0x16, 0x02, 0x02, + 0x88, 0x16, 0x02, 0x02, 0xf0, 0x37, 0x03, 0x03, 0xf8, 0x37, 0x03, 0x03, 0x00, 0x38, 0x03, 0x03, 0x50, 0x13, 0x04, 0x03, 0x58, 0x13, 0x04, 0x03, 0x40, 0x33, 0x05, 0x04, 0xa0, 0x10, 0x06, 0x04, + 0xa0, 0x30, 0x07, 0x05, 0x80, 0x2f, 0x09, 0x06, 0xd8, 0x09, 0x00, 0x02, 0xdc, 0x09, 0x00, 0x02, 0xe0, 0x09, 0x00, 0x02, 0xe4, 0x09, 0x00, 0x02, 0x14, 0x3c, 0x01, 0x02, 0x18, 0x3c, 0x01, 0x02, + 0x1c, 0x3c, 0x01, 0x02, 0x20, 0x3c, 0x01, 0x02, 0x24, 0x3c, 0x01, 0x02, 0x28, 0x3c, 0x01, 0x02, 0x8c, 0x16, 0x02, 0x02, 0x90, 0x16, 0x02, 0x02, 0x94, 0x16, 0x02, 0x02, 0x98, 0x16, 0x02, 0x02, + 0x9c, 0x16, 0x02, 0x02, 0x08, 0x38, 0x03, 0x03, 0x10, 0x38, 0x03, 0x03, 0x18, 0x38, 0x03, 0x03, 0x60, 0x13, 0x04, 0x03, 0x68, 0x13, 0x04, 0x03, 0x50, 0x33, 0x05, 0x04, 0xb0, 0x10, 0x06, 0x04, + 0xc0, 0x30, 0x07, 0x05, 0xc0, 0x2f, 0x09, 0x06, 0xe8, 0x09, 0x00, 0x02, 0xec, 0x09, 0x00, 0x02, 0xf0, 0x09, 0x00, 0x02, 0xf4, 0x09, 0x00, 0x02, 0x2c, 0x3c, 0x01, 0x02, 0x30, 0x3c, 0x01, 0x02, + 0x34, 0x3c, 0x01, 0x02, 0x38, 0x3c, 0x01, 0x02, 0x3c, 0x3c, 0x01, 0x02, 0x40, 0x3c, 0x01, 0x02, 0xa0, 0x16, 0x02, 0x02, 0xa4, 0x16, 0x02, 0x02, 0xa8, 0x16, 0x02, 0x02, 0xac, 0x16, 0x02, 0x02, + 0xb0, 0x16, 0x02, 0x02, 0x20, 0x38, 0x03, 0x03, 0x28, 0x38, 0x03, 0x03, 0x30, 0x38, 0x03, 0x03, 0x70, 0x13, 0x04, 0x03, 0x78, 0x13, 0x04, 0x03, 0x60, 0x33, 0x05, 0x04, 0xc0, 0x10, 0x06, 0x04, + 0xe0, 0x30, 0x07, 0x05, 0x00, 0x30, 0x09, 0x06, 0xf8, 0x09, 0x00, 0x02, 0xfc, 0x09, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x04, 0x0a, 0x00, 0x02, 0x44, 0x3c, 0x01, 0x02, 0x48, 0x3c, 0x01, 0x02, + 0x4c, 0x3c, 0x01, 0x02, 0x50, 0x3c, 0x01, 0x02, 0x54, 0x3c, 0x01, 0x02, 0x58, 0x3c, 0x01, 0x02, 0xb4, 0x16, 0x02, 0x02, 0xb8, 0x16, 0x02, 0x02, 0xbc, 0x16, 0x02, 0x02, 0xc0, 0x16, 0x02, 0x02, + 0xc4, 0x16, 0x02, 0x02, 0x38, 0x38, 0x03, 0x03, 0x40, 0x38, 0x03, 0x03, 0x48, 0x38, 0x03, 0x03, 0x80, 0x13, 0x04, 0x03, 0x88, 0x13, 0x04, 0x03, 0x70, 0x33, 0x05, 0x04, 0xd0, 0x10, 0x06, 0x04, + 0x00, 0x31, 0x07, 0x05, 0x40, 0x30, 0x09, 0x06, 0x08, 0x0a, 0x00, 0x02, 0x0c, 0x0a, 0x00, 0x02, 0x10, 0x0a, 0x00, 0x02, 0x14, 0x0a, 0x00, 0x02, 0x5c, 0x3c, 0x01, 0x02, 0x60, 0x3c, 0x01, 0x02, + 0x64, 0x3c, 0x01, 0x02, 0x68, 0x3c, 0x01, 0x02, 0x6c, 0x3c, 0x01, 0x02, 0x70, 0x3c, 0x01, 0x02, 0xc8, 0x16, 0x02, 0x02, 0xcc, 0x16, 0x02, 0x02, 0xd0, 0x16, 0x02, 0x02, 0xd4, 0x16, 0x02, 0x02, + 0x50, 0x38, 0x03, 0x03, 0x58, 0x38, 0x03, 0x03, 0x60, 0x38, 0x03, 0x03, 0x90, 0x13, 0x04, 0x03, 0x98, 0x13, 0x04, 0x03, 0xa0, 0x13, 0x04, 0x03, 0x80, 0x33, 0x05, 0x04, 0xe0, 0x10, 0x06, 0x04, + 0x20, 0x31, 0x07, 0x05, 0x80, 0x30, 0x09, 0x06, 0x18, 0x0a, 0x00, 0x02, 0x1c, 0x0a, 0x00, 0x02, 0x20, 0x0a, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x02, 0x74, 0x3c, 0x01, 0x02, 0x78, 0x3c, 0x01, 0x02, + 0x7c, 0x3c, 0x01, 0x02, 0x80, 0x3c, 0x01, 0x02, 0x84, 0x3c, 0x01, 0x02, 0x88, 0x3c, 0x01, 0x02, 0xd8, 0x16, 0x02, 0x02, 0xdc, 0x16, 0x02, 0x02, 0xe0, 0x16, 0x02, 0x02, 0xe4, 0x16, 0x02, 0x02, + 0x68, 0x38, 0x03, 0x03, 0x70, 0x38, 0x03, 0x03, 0x78, 0x38, 0x03, 0x03, 0xa8, 0x13, 0x04, 0x03, 0xb0, 0x13, 0x04, 0x03, 0xb8, 0x13, 0x04, 0x03, 0x90, 0x33, 0x05, 0x04, 0xf0, 0x10, 0x06, 0x04, + 0x40, 0x31, 0x07, 0x05, 0xc0, 0x30, 0x09, 0x06, 0x28, 0x0a, 0x00, 0x02, 0x2c, 0x0a, 0x00, 0x02, 0x30, 0x0a, 0x00, 0x02, 0x34, 0x0a, 0x00, 0x02, 0x8c, 0x3c, 0x01, 0x02, 0x90, 0x3c, 0x01, 0x02, + 0x94, 0x3c, 0x01, 0x02, 0x98, 0x3c, 0x01, 0x02, 0x9c, 0x3c, 0x01, 0x02, 0xa0, 0x3c, 0x01, 0x02, 0xe8, 0x16, 0x02, 0x02, 0xec, 0x16, 0x02, 0x02, 0xf0, 0x16, 0x02, 0x02, 0xf4, 0x16, 0x02, 0x02, + 0x80, 0x38, 0x03, 0x03, 0x88, 0x38, 0x03, 0x03, 0x90, 0x38, 0x03, 0x03, 0xc0, 0x13, 0x04, 0x03, 0xc8, 0x13, 0x04, 0x03, 0xd0, 0x13, 0x04, 0x03, 0xa0, 0x33, 0x05, 0x04, 0x00, 0x11, 0x06, 0x04, + 0x60, 0x31, 0x07, 0x05, 0x00, 0x31, 0x09, 0x06, 0x38, 0x0a, 0x00, 0x02, 0x3c, 0x0a, 0x00, 0x02, 0x40, 0x0a, 0x00, 0x02, 0x44, 0x0a, 0x00, 0x02, 0xa4, 0x3c, 0x01, 0x02, 0xa8, 0x3c, 0x01, 0x02, + 0xac, 0x3c, 0x01, 0x02, 0xb0, 0x3c, 0x01, 0x02, 0xb4, 0x3c, 0x01, 0x02, 0xb8, 0x3c, 0x01, 0x02, 0xf8, 0x16, 0x02, 0x02, 0xfc, 0x16, 0x02, 0x02, 0x00, 0x17, 0x02, 0x02, 0x04, 0x17, 0x02, 0x02, + 0x98, 0x38, 0x03, 0x03, 0xa0, 0x38, 0x03, 0x03, 0xa8, 0x38, 0x03, 0x03, 0xd8, 0x13, 0x04, 0x03, 0xe0, 0x13, 0x04, 0x03, 0xe8, 0x13, 0x04, 0x03, 0xb0, 0x33, 0x05, 0x04, 0x10, 0x11, 0x06, 0x04, + 0x80, 0x31, 0x07, 0x05, 0x40, 0x31, 0x09, 0x06, 0x48, 0x0a, 0x00, 0x02, 0x4c, 0x0a, 0x00, 0x02, 0x50, 0x0a, 0x00, 0x02, 0x54, 0x0a, 0x00, 0x02, 0xbc, 0x3c, 0x01, 0x02, 0xc0, 0x3c, 0x01, 0x02, + 0xc4, 0x3c, 0x01, 0x02, 0xc8, 0x3c, 0x01, 0x02, 0xcc, 0x3c, 0x01, 0x02, 0xd0, 0x3c, 0x01, 0x02, 0x08, 0x17, 0x02, 0x02, 0x0c, 0x17, 0x02, 0x02, 0x10, 0x17, 0x02, 0x02, 0x14, 0x17, 0x02, 0x02, + 0xb0, 0x38, 0x03, 0x03, 0xb8, 0x38, 0x03, 0x03, 0xc0, 0x38, 0x03, 0x03, 0xf0, 0x13, 0x04, 0x03, 0xf8, 0x13, 0x04, 0x03, 0x00, 0x14, 0x04, 0x03, 0xc0, 0x33, 0x05, 0x04, 0x20, 0x11, 0x06, 0x04, + 0xa0, 0x31, 0x07, 0x05, 0x00, 0x0a, 0x0a, 0x06, 0x58, 0x0a, 0x00, 0x02, 0x5c, 0x0a, 0x00, 0x02, 0x60, 0x0a, 0x00, 0x02, 0x64, 0x0a, 0x00, 0x02, 0xd4, 0x3c, 0x01, 0x02, 0xd8, 0x3c, 0x01, 0x02, + 0xdc, 0x3c, 0x01, 0x02, 0xe0, 0x3c, 0x01, 0x02, 0xe4, 0x3c, 0x01, 0x02, 0xe8, 0x3c, 0x01, 0x02, 0x18, 0x17, 0x02, 0x02, 0x1c, 0x17, 0x02, 0x02, 0x20, 0x17, 0x02, 0x02, 0x24, 0x17, 0x02, 0x02, + 0xc8, 0x38, 0x03, 0x03, 0xd0, 0x38, 0x03, 0x03, 0xd8, 0x38, 0x03, 0x03, 0x08, 0x14, 0x04, 0x03, 0x10, 0x14, 0x04, 0x03, 0x18, 0x14, 0x04, 0x03, 0xd0, 0x33, 0x05, 0x04, 0x30, 0x11, 0x06, 0x04, + 0xc0, 0x31, 0x07, 0x05, 0x40, 0x0a, 0x0a, 0x06, 0x68, 0x0a, 0x00, 0x02, 0x6c, 0x0a, 0x00, 0x02, 0x70, 0x0a, 0x00, 0x02, 0x74, 0x0a, 0x00, 0x02, 0xec, 0x3c, 0x01, 0x02, 0xf0, 0x3c, 0x01, 0x02, + 0xf4, 0x3c, 0x01, 0x02, 0xf8, 0x3c, 0x01, 0x02, 0xfc, 0x3c, 0x01, 0x02, 0x00, 0x3d, 0x01, 0x02, 0x28, 0x17, 0x02, 0x02, 0x2c, 0x17, 0x02, 0x02, 0x30, 0x17, 0x02, 0x02, 0x34, 0x17, 0x02, 0x02, + 0xe0, 0x38, 0x03, 0x03, 0xe8, 0x38, 0x03, 0x03, 0xf0, 0x38, 0x03, 0x03, 0x20, 0x14, 0x04, 0x03, 0x28, 0x14, 0x04, 0x03, 0xe0, 0x33, 0x05, 0x04, 0xf0, 0x33, 0x05, 0x04, 0x40, 0x11, 0x06, 0x04, + 0xe0, 0x31, 0x07, 0x05, 0x80, 0x0a, 0x0a, 0x06, 0x78, 0x0a, 0x00, 0x02, 0x7c, 0x0a, 0x00, 0x02, 0x80, 0x0a, 0x00, 0x02, 0x84, 0x0a, 0x00, 0x02, 0x04, 0x3d, 0x01, 0x02, 0x08, 0x3d, 0x01, 0x02, + 0x0c, 0x3d, 0x01, 0x02, 0x10, 0x3d, 0x01, 0x02, 0x14, 0x3d, 0x01, 0x02, 0x18, 0x3d, 0x01, 0x02, 0x38, 0x17, 0x02, 0x02, 0x3c, 0x17, 0x02, 0x02, 0x40, 0x17, 0x02, 0x02, 0x44, 0x17, 0x02, 0x02, + 0xf8, 0x38, 0x03, 0x03, 0x00, 0x39, 0x03, 0x03, 0x08, 0x39, 0x03, 0x03, 0x30, 0x14, 0x04, 0x03, 0x38, 0x14, 0x04, 0x03, 0x00, 0x34, 0x05, 0x04, 0x10, 0x34, 0x05, 0x04, 0x50, 0x11, 0x06, 0x04, + 0x00, 0x32, 0x07, 0x05, 0xc0, 0x0a, 0x0a, 0x06, 0x88, 0x0a, 0x00, 0x02, 0x8c, 0x0a, 0x00, 0x02, 0x90, 0x0a, 0x00, 0x02, 0x94, 0x0a, 0x00, 0x02, 0x1c, 0x3d, 0x01, 0x02, 0x20, 0x3d, 0x01, 0x02, + 0x24, 0x3d, 0x01, 0x02, 0x28, 0x3d, 0x01, 0x02, 0x2c, 0x3d, 0x01, 0x02, 0x30, 0x3d, 0x01, 0x02, 0x48, 0x17, 0x02, 0x02, 0x4c, 0x17, 0x02, 0x02, 0x50, 0x17, 0x02, 0x02, 0x54, 0x17, 0x02, 0x02, + 0x10, 0x39, 0x03, 0x03, 0x18, 0x39, 0x03, 0x03, 0x20, 0x39, 0x03, 0x03, 0x40, 0x14, 0x04, 0x03, 0x48, 0x14, 0x04, 0x03, 0x20, 0x34, 0x05, 0x04, 0x30, 0x34, 0x05, 0x04, 0x60, 0x11, 0x06, 0x04, + 0x20, 0x32, 0x07, 0x05, 0x00, 0x0b, 0x0a, 0x06, 0x98, 0x0a, 0x00, 0x02, 0x9c, 0x0a, 0x00, 0x02, 0xa0, 0x0a, 0x00, 0x02, 0xa4, 0x0a, 0x00, 0x02, 0x34, 0x3d, 0x01, 0x02, 0x38, 0x3d, 0x01, 0x02, + 0x3c, 0x3d, 0x01, 0x02, 0x40, 0x3d, 0x01, 0x02, 0x44, 0x3d, 0x01, 0x02, 0x48, 0x3d, 0x01, 0x02, 0x58, 0x17, 0x02, 0x02, 0x5c, 0x17, 0x02, 0x02, 0x60, 0x17, 0x02, 0x02, 0x64, 0x17, 0x02, 0x02, + 0x28, 0x39, 0x03, 0x03, 0x30, 0x39, 0x03, 0x03, 0x38, 0x39, 0x03, 0x03, 0x50, 0x14, 0x04, 0x03, 0x58, 0x14, 0x04, 0x03, 0x40, 0x34, 0x05, 0x04, 0x50, 0x34, 0x05, 0x04, 0x70, 0x11, 0x06, 0x04, + 0x40, 0x32, 0x07, 0x05, 0x40, 0x0b, 0x0a, 0x06, 0xa8, 0x0a, 0x00, 0x02, 0xac, 0x0a, 0x00, 0x02, 0xb0, 0x0a, 0x00, 0x02, 0xb4, 0x0a, 0x00, 0x02, 0x4c, 0x3d, 0x01, 0x02, 0x50, 0x3d, 0x01, 0x02, + 0x54, 0x3d, 0x01, 0x02, 0x58, 0x3d, 0x01, 0x02, 0x5c, 0x3d, 0x01, 0x02, 0x60, 0x3d, 0x01, 0x02, 0x68, 0x17, 0x02, 0x02, 0x6c, 0x17, 0x02, 0x02, 0x70, 0x17, 0x02, 0x02, 0x74, 0x17, 0x02, 0x02, + 0x40, 0x39, 0x03, 0x03, 0x48, 0x39, 0x03, 0x03, 0x50, 0x39, 0x03, 0x03, 0x60, 0x14, 0x04, 0x03, 0x68, 0x14, 0x04, 0x03, 0x60, 0x34, 0x05, 0x04, 0x70, 0x34, 0x05, 0x04, 0x80, 0x11, 0x06, 0x04, + 0x60, 0x32, 0x07, 0x05, 0x80, 0x0b, 0x0a, 0x06, 0xb8, 0x0a, 0x00, 0x02, 0xbc, 0x0a, 0x00, 0x02, 0xc0, 0x0a, 0x00, 0x02, 0xc4, 0x0a, 0x00, 0x02, 0x64, 0x3d, 0x01, 0x02, 0x68, 0x3d, 0x01, 0x02, + 0x6c, 0x3d, 0x01, 0x02, 0x70, 0x3d, 0x01, 0x02, 0x74, 0x3d, 0x01, 0x02, 0x78, 0x3d, 0x01, 0x02, 0x78, 0x17, 0x02, 0x02, 0x7c, 0x17, 0x02, 0x02, 0x80, 0x17, 0x02, 0x02, 0x84, 0x17, 0x02, 0x02, + 0x58, 0x39, 0x03, 0x03, 0x60, 0x39, 0x03, 0x03, 0x68, 0x39, 0x03, 0x03, 0x70, 0x14, 0x04, 0x03, 0x78, 0x14, 0x04, 0x03, 0x80, 0x34, 0x05, 0x04, 0x90, 0x34, 0x05, 0x04, 0x90, 0x11, 0x06, 0x04, + 0x80, 0x32, 0x07, 0x05, 0xc0, 0x0b, 0x0a, 0x06, 0xc8, 0x0a, 0x00, 0x02, 0xcc, 0x0a, 0x00, 0x02, 0xd0, 0x0a, 0x00, 0x02, 0xd4, 0x0a, 0x00, 0x02, 0x7c, 0x3d, 0x01, 0x02, 0x80, 0x3d, 0x01, 0x02, + 0x84, 0x3d, 0x01, 0x02, 0x88, 0x3d, 0x01, 0x02, 0x8c, 0x3d, 0x01, 0x02, 0x90, 0x3d, 0x01, 0x02, 0x88, 0x17, 0x02, 0x02, 0x8c, 0x17, 0x02, 0x02, 0x90, 0x17, 0x02, 0x02, 0x94, 0x17, 0x02, 0x02, + 0x70, 0x39, 0x03, 0x03, 0x78, 0x39, 0x03, 0x03, 0x80, 0x39, 0x03, 0x03, 0x80, 0x14, 0x04, 0x03, 0x88, 0x14, 0x04, 0x03, 0xa0, 0x34, 0x05, 0x04, 0xb0, 0x34, 0x05, 0x04, 0xa0, 0x11, 0x06, 0x04, + 0xa0, 0x32, 0x07, 0x05, 0x00, 0x0c, 0x0a, 0x06, 0xd8, 0x0a, 0x00, 0x02, 0xdc, 0x0a, 0x00, 0x02, 0xe0, 0x0a, 0x00, 0x02, 0xe4, 0x0a, 0x00, 0x02, 0x94, 0x3d, 0x01, 0x02, 0x98, 0x3d, 0x01, 0x02, + 0x9c, 0x3d, 0x01, 0x02, 0xa0, 0x3d, 0x01, 0x02, 0xa4, 0x3d, 0x01, 0x02, 0xa8, 0x3d, 0x01, 0x02, 0x98, 0x17, 0x02, 0x02, 0x9c, 0x17, 0x02, 0x02, 0xa0, 0x17, 0x02, 0x02, 0xa4, 0x17, 0x02, 0x02, + 0x88, 0x39, 0x03, 0x03, 0x90, 0x39, 0x03, 0x03, 0x98, 0x39, 0x03, 0x03, 0x90, 0x14, 0x04, 0x03, 0x98, 0x14, 0x04, 0x03, 0xc0, 0x34, 0x05, 0x04, 0xd0, 0x34, 0x05, 0x04, 0xb0, 0x11, 0x06, 0x04, + 0xc0, 0x32, 0x07, 0x05, 0x40, 0x0c, 0x0a, 0x06, 0xe8, 0x0a, 0x00, 0x02, 0xec, 0x0a, 0x00, 0x02, 0xf0, 0x0a, 0x00, 0x02, 0xf4, 0x0a, 0x00, 0x02, 0xac, 0x3d, 0x01, 0x02, 0xb0, 0x3d, 0x01, 0x02, + 0xb4, 0x3d, 0x01, 0x02, 0xb8, 0x3d, 0x01, 0x02, 0xbc, 0x3d, 0x01, 0x02, 0xc0, 0x3d, 0x01, 0x02, 0xa8, 0x17, 0x02, 0x02, 0xac, 0x17, 0x02, 0x02, 0xb0, 0x17, 0x02, 0x02, 0xb4, 0x17, 0x02, 0x02, + 0xa0, 0x39, 0x03, 0x03, 0xa8, 0x39, 0x03, 0x03, 0xb0, 0x39, 0x03, 0x03, 0xa0, 0x14, 0x04, 0x03, 0xa8, 0x14, 0x04, 0x03, 0xe0, 0x34, 0x05, 0x04, 0xf0, 0x34, 0x05, 0x04, 0xc0, 0x11, 0x06, 0x04, + 0xe0, 0x32, 0x07, 0x05, 0x80, 0x0c, 0x0a, 0x06, 0xf8, 0x0a, 0x00, 0x02, 0xfc, 0x0a, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x04, 0x0b, 0x00, 0x02, 0xc4, 0x3d, 0x01, 0x02, 0xc8, 0x3d, 0x01, 0x02, + 0xcc, 0x3d, 0x01, 0x02, 0xd0, 0x3d, 0x01, 0x02, 0xd4, 0x3d, 0x01, 0x02, 0xd8, 0x3d, 0x01, 0x02, 0xb8, 0x17, 0x02, 0x02, 0xbc, 0x17, 0x02, 0x02, 0xc0, 0x17, 0x02, 0x02, 0xc4, 0x17, 0x02, 0x02, + 0xb8, 0x39, 0x03, 0x03, 0xc0, 0x39, 0x03, 0x03, 0xc8, 0x39, 0x03, 0x03, 0xb0, 0x14, 0x04, 0x03, 0xb8, 0x14, 0x04, 0x03, 0x00, 0x35, 0x05, 0x04, 0x10, 0x35, 0x05, 0x04, 0xd0, 0x11, 0x06, 0x04, + 0x00, 0x33, 0x07, 0x05, 0xc0, 0x0c, 0x0a, 0x06, 0x08, 0x0b, 0x00, 0x02, 0x0c, 0x0b, 0x00, 0x02, 0x10, 0x0b, 0x00, 0x02, 0x14, 0x0b, 0x00, 0x02, 0xdc, 0x3d, 0x01, 0x02, 0xe0, 0x3d, 0x01, 0x02, + 0xe4, 0x3d, 0x01, 0x02, 0xe8, 0x3d, 0x01, 0x02, 0xec, 0x3d, 0x01, 0x02, 0xf0, 0x3d, 0x01, 0x02, 0xc8, 0x17, 0x02, 0x02, 0xcc, 0x17, 0x02, 0x02, 0xd0, 0x17, 0x02, 0x02, 0xd4, 0x17, 0x02, 0x02, + 0xd0, 0x39, 0x03, 0x03, 0xd8, 0x39, 0x03, 0x03, 0xe0, 0x39, 0x03, 0x03, 0xc0, 0x14, 0x04, 0x03, 0xc8, 0x14, 0x04, 0x03, 0x20, 0x35, 0x05, 0x04, 0x30, 0x35, 0x05, 0x04, 0xe0, 0x11, 0x06, 0x04, + 0x20, 0x33, 0x07, 0x05, 0x00, 0x0d, 0x0a, 0x06, 0x18, 0x0b, 0x00, 0x02, 0x1c, 0x0b, 0x00, 0x02, 0x20, 0x0b, 0x00, 0x02, 0x24, 0x0b, 0x00, 0x02, 0xf4, 0x3d, 0x01, 0x02, 0xf8, 0x3d, 0x01, 0x02, + 0xfc, 0x3d, 0x01, 0x02, 0x00, 0x3e, 0x01, 0x02, 0x04, 0x3e, 0x01, 0x02, 0x08, 0x3e, 0x01, 0x02, 0xd8, 0x17, 0x02, 0x02, 0xdc, 0x17, 0x02, 0x02, 0xe0, 0x17, 0x02, 0x02, 0xe4, 0x17, 0x02, 0x02, + 0xe8, 0x39, 0x03, 0x03, 0xf0, 0x39, 0x03, 0x03, 0xf8, 0x39, 0x03, 0x03, 0xd0, 0x14, 0x04, 0x03, 0xd8, 0x14, 0x04, 0x03, 0x40, 0x35, 0x05, 0x04, 0x50, 0x35, 0x05, 0x04, 0xf0, 0x11, 0x06, 0x04, + 0x40, 0x33, 0x07, 0x05, 0x40, 0x0d, 0x0a, 0x06, 0x28, 0x0b, 0x00, 0x02, 0x2c, 0x0b, 0x00, 0x02, 0x30, 0x0b, 0x00, 0x02, 0x34, 0x0b, 0x00, 0x02, 0x0c, 0x3e, 0x01, 0x02, 0x10, 0x3e, 0x01, 0x02, + 0x14, 0x3e, 0x01, 0x02, 0x18, 0x3e, 0x01, 0x02, 0x1c, 0x3e, 0x01, 0x02, 0x20, 0x3e, 0x01, 0x02, 0xe8, 0x17, 0x02, 0x02, 0xec, 0x17, 0x02, 0x02, 0xf0, 0x17, 0x02, 0x02, 0xf4, 0x17, 0x02, 0x02, + 0x00, 0x3a, 0x03, 0x03, 0x08, 0x3a, 0x03, 0x03, 0x10, 0x3a, 0x03, 0x03, 0xe0, 0x14, 0x04, 0x03, 0xe8, 0x14, 0x04, 0x03, 0x60, 0x35, 0x05, 0x04, 0x70, 0x35, 0x05, 0x04, 0x00, 0x12, 0x06, 0x04, + 0x60, 0x33, 0x07, 0x05, 0x80, 0x0d, 0x0a, 0x06, 0x38, 0x0b, 0x00, 0x02, 0x3c, 0x0b, 0x00, 0x02, 0x40, 0x0b, 0x00, 0x02, 0x44, 0x0b, 0x00, 0x02, 0x24, 0x3e, 0x01, 0x02, 0x28, 0x3e, 0x01, 0x02, + 0x2c, 0x3e, 0x01, 0x02, 0x30, 0x3e, 0x01, 0x02, 0x34, 0x3e, 0x01, 0x02, 0x38, 0x3e, 0x01, 0x02, 0xf8, 0x17, 0x02, 0x02, 0xfc, 0x17, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, 0x04, 0x18, 0x02, 0x02, + 0x18, 0x3a, 0x03, 0x03, 0x20, 0x3a, 0x03, 0x03, 0x28, 0x3a, 0x03, 0x03, 0xf0, 0x14, 0x04, 0x03, 0xf8, 0x14, 0x04, 0x03, 0x80, 0x35, 0x05, 0x04, 0x90, 0x35, 0x05, 0x04, 0x10, 0x12, 0x06, 0x04, + 0xa0, 0x0c, 0x08, 0x05, 0xc0, 0x0d, 0x0a, 0x06, 0x48, 0x0b, 0x00, 0x02, 0x4c, 0x0b, 0x00, 0x02, 0x50, 0x0b, 0x00, 0x02, 0x54, 0x0b, 0x00, 0x02, 0x3c, 0x3e, 0x01, 0x02, 0x40, 0x3e, 0x01, 0x02, + 0x44, 0x3e, 0x01, 0x02, 0x48, 0x3e, 0x01, 0x02, 0x4c, 0x3e, 0x01, 0x02, 0x50, 0x3e, 0x01, 0x02, 0x08, 0x18, 0x02, 0x02, 0x0c, 0x18, 0x02, 0x02, 0x10, 0x18, 0x02, 0x02, 0x14, 0x18, 0x02, 0x02, + 0x30, 0x3a, 0x03, 0x03, 0x38, 0x3a, 0x03, 0x03, 0x40, 0x3a, 0x03, 0x03, 0x00, 0x15, 0x04, 0x03, 0x08, 0x15, 0x04, 0x03, 0xa0, 0x35, 0x05, 0x04, 0xb0, 0x35, 0x05, 0x04, 0x20, 0x12, 0x06, 0x04, + 0xc0, 0x0c, 0x08, 0x05, 0x00, 0x0e, 0x0a, 0x06, 0x58, 0x0b, 0x00, 0x02, 0x5c, 0x0b, 0x00, 0x02, 0x60, 0x0b, 0x00, 0x02, 0x64, 0x0b, 0x00, 0x02, 0x54, 0x3e, 0x01, 0x02, 0x58, 0x3e, 0x01, 0x02, + 0x5c, 0x3e, 0x01, 0x02, 0x60, 0x3e, 0x01, 0x02, 0x64, 0x3e, 0x01, 0x02, 0x68, 0x3e, 0x01, 0x02, 0x18, 0x18, 0x02, 0x02, 0x1c, 0x18, 0x02, 0x02, 0x20, 0x18, 0x02, 0x02, 0x24, 0x18, 0x02, 0x02, + 0x48, 0x3a, 0x03, 0x03, 0x50, 0x3a, 0x03, 0x03, 0x58, 0x3a, 0x03, 0x03, 0x10, 0x15, 0x04, 0x03, 0x18, 0x15, 0x04, 0x03, 0xc0, 0x35, 0x05, 0x04, 0xd0, 0x35, 0x05, 0x04, 0x30, 0x12, 0x06, 0x04, + 0xe0, 0x0c, 0x08, 0x05, 0x40, 0x0e, 0x0a, 0x06, 0x68, 0x0b, 0x00, 0x02, 0x6c, 0x0b, 0x00, 0x02, 0x70, 0x0b, 0x00, 0x02, 0x74, 0x0b, 0x00, 0x02, 0x6c, 0x3e, 0x01, 0x02, 0x70, 0x3e, 0x01, 0x02, + 0x74, 0x3e, 0x01, 0x02, 0x78, 0x3e, 0x01, 0x02, 0x7c, 0x3e, 0x01, 0x02, 0x80, 0x3e, 0x01, 0x02, 0x28, 0x18, 0x02, 0x02, 0x2c, 0x18, 0x02, 0x02, 0x30, 0x18, 0x02, 0x02, 0x34, 0x18, 0x02, 0x02, + 0x60, 0x3a, 0x03, 0x03, 0x68, 0x3a, 0x03, 0x03, 0x70, 0x3a, 0x03, 0x03, 0x20, 0x15, 0x04, 0x03, 0x28, 0x15, 0x04, 0x03, 0xe0, 0x35, 0x05, 0x04, 0xf0, 0x35, 0x05, 0x04, 0x40, 0x12, 0x06, 0x04, + 0x00, 0x0d, 0x08, 0x05, 0x80, 0x0e, 0x0a, 0x06, 0x78, 0x0b, 0x00, 0x02, 0x7c, 0x0b, 0x00, 0x02, 0x80, 0x0b, 0x00, 0x02, 0x84, 0x0b, 0x00, 0x02, 0x84, 0x3e, 0x01, 0x02, 0x88, 0x3e, 0x01, 0x02, + 0x8c, 0x3e, 0x01, 0x02, 0x90, 0x3e, 0x01, 0x02, 0x94, 0x3e, 0x01, 0x02, 0x98, 0x3e, 0x01, 0x02, 0x38, 0x18, 0x02, 0x02, 0x3c, 0x18, 0x02, 0x02, 0x40, 0x18, 0x02, 0x02, 0x44, 0x18, 0x02, 0x02, + 0x78, 0x3a, 0x03, 0x03, 0x80, 0x3a, 0x03, 0x03, 0x88, 0x3a, 0x03, 0x03, 0x30, 0x15, 0x04, 0x03, 0x38, 0x15, 0x04, 0x03, 0x00, 0x36, 0x05, 0x04, 0x10, 0x36, 0x05, 0x04, 0x50, 0x12, 0x06, 0x04, + 0x20, 0x0d, 0x08, 0x05, 0xc0, 0x0e, 0x0a, 0x06, 0x88, 0x0b, 0x00, 0x02, 0x8c, 0x0b, 0x00, 0x02, 0x90, 0x0b, 0x00, 0x02, 0x94, 0x0b, 0x00, 0x02, 0x9c, 0x3e, 0x01, 0x02, 0xa0, 0x3e, 0x01, 0x02, + 0xa4, 0x3e, 0x01, 0x02, 0xa8, 0x3e, 0x01, 0x02, 0xac, 0x3e, 0x01, 0x02, 0xb0, 0x3e, 0x01, 0x02, 0x48, 0x18, 0x02, 0x02, 0x4c, 0x18, 0x02, 0x02, 0x50, 0x18, 0x02, 0x02, 0x54, 0x18, 0x02, 0x02, + 0x90, 0x3a, 0x03, 0x03, 0x98, 0x3a, 0x03, 0x03, 0xa0, 0x3a, 0x03, 0x03, 0x40, 0x15, 0x04, 0x03, 0x48, 0x15, 0x04, 0x03, 0x20, 0x36, 0x05, 0x04, 0x30, 0x36, 0x05, 0x04, 0x60, 0x12, 0x06, 0x04, + 0x40, 0x0d, 0x08, 0x05, 0x00, 0x27, 0x0b, 0x07, 0x98, 0x0b, 0x00, 0x02, 0x9c, 0x0b, 0x00, 0x02, 0xa0, 0x0b, 0x00, 0x02, 0xa4, 0x0b, 0x00, 0x02, 0xb4, 0x3e, 0x01, 0x02, 0xb8, 0x3e, 0x01, 0x02, + 0xbc, 0x3e, 0x01, 0x02, 0xc0, 0x3e, 0x01, 0x02, 0xc4, 0x3e, 0x01, 0x02, 0xc8, 0x3e, 0x01, 0x02, 0x58, 0x18, 0x02, 0x02, 0x5c, 0x18, 0x02, 0x02, 0x60, 0x18, 0x02, 0x02, 0x64, 0x18, 0x02, 0x02, + 0xa8, 0x3a, 0x03, 0x03, 0xb0, 0x3a, 0x03, 0x03, 0xb8, 0x3a, 0x03, 0x03, 0x50, 0x15, 0x04, 0x03, 0x58, 0x15, 0x04, 0x03, 0x40, 0x36, 0x05, 0x04, 0x50, 0x36, 0x05, 0x04, 0x70, 0x12, 0x06, 0x04, + 0x60, 0x0d, 0x08, 0x05, 0x80, 0x27, 0x0b, 0x07, 0xa8, 0x0b, 0x00, 0x02, 0xac, 0x0b, 0x00, 0x02, 0xb0, 0x0b, 0x00, 0x02, 0xb4, 0x0b, 0x00, 0x02, 0xcc, 0x3e, 0x01, 0x02, 0xd0, 0x3e, 0x01, 0x02, + 0xd4, 0x3e, 0x01, 0x02, 0xd8, 0x3e, 0x01, 0x02, 0xdc, 0x3e, 0x01, 0x02, 0xe0, 0x3e, 0x01, 0x02, 0x68, 0x18, 0x02, 0x02, 0x6c, 0x18, 0x02, 0x02, 0x70, 0x18, 0x02, 0x02, 0x74, 0x18, 0x02, 0x02, + 0xc0, 0x3a, 0x03, 0x03, 0xc8, 0x3a, 0x03, 0x03, 0xd0, 0x3a, 0x03, 0x03, 0x60, 0x15, 0x04, 0x03, 0x68, 0x15, 0x04, 0x03, 0x60, 0x36, 0x05, 0x04, 0x70, 0x36, 0x05, 0x04, 0x80, 0x12, 0x06, 0x04, + 0x80, 0x0d, 0x08, 0x05, 0x00, 0x28, 0x0b, 0x07, 0xb8, 0x0b, 0x00, 0x02, 0xbc, 0x0b, 0x00, 0x02, 0xc0, 0x0b, 0x00, 0x02, 0xc4, 0x0b, 0x00, 0x02, 0xe4, 0x3e, 0x01, 0x02, 0xe8, 0x3e, 0x01, 0x02, + 0xec, 0x3e, 0x01, 0x02, 0xf0, 0x3e, 0x01, 0x02, 0xf4, 0x3e, 0x01, 0x02, 0xf8, 0x3e, 0x01, 0x02, 0x78, 0x18, 0x02, 0x02, 0x7c, 0x18, 0x02, 0x02, 0x80, 0x18, 0x02, 0x02, 0x84, 0x18, 0x02, 0x02, + 0xd8, 0x3a, 0x03, 0x03, 0xe0, 0x3a, 0x03, 0x03, 0xe8, 0x3a, 0x03, 0x03, 0x70, 0x15, 0x04, 0x03, 0x78, 0x15, 0x04, 0x03, 0x80, 0x36, 0x05, 0x04, 0x90, 0x36, 0x05, 0x04, 0x90, 0x12, 0x06, 0x04, + 0xa0, 0x0d, 0x08, 0x05, 0x80, 0x28, 0x0b, 0x07, 0xc8, 0x0b, 0x00, 0x02, 0xcc, 0x0b, 0x00, 0x02, 0xd0, 0x0b, 0x00, 0x02, 0xd4, 0x0b, 0x00, 0x02, 0xfc, 0x3e, 0x01, 0x02, 0x00, 0x3f, 0x01, 0x02, + 0x04, 0x3f, 0x01, 0x02, 0x08, 0x3f, 0x01, 0x02, 0x0c, 0x3f, 0x01, 0x02, 0x10, 0x3f, 0x01, 0x02, 0x88, 0x18, 0x02, 0x02, 0x8c, 0x18, 0x02, 0x02, 0x90, 0x18, 0x02, 0x02, 0x94, 0x18, 0x02, 0x02, + 0xf0, 0x3a, 0x03, 0x03, 0xf8, 0x3a, 0x03, 0x03, 0x00, 0x3b, 0x03, 0x03, 0x80, 0x15, 0x04, 0x03, 0x88, 0x15, 0x04, 0x03, 0xa0, 0x36, 0x05, 0x04, 0xb0, 0x36, 0x05, 0x04, 0xa0, 0x12, 0x06, 0x04, + 0xc0, 0x0d, 0x08, 0x05, 0x00, 0x29, 0x0b, 0x07, 0xd8, 0x0b, 0x00, 0x02, 0xdc, 0x0b, 0x00, 0x02, 0xe0, 0x0b, 0x00, 0x02, 0xe4, 0x0b, 0x00, 0x02, 0x14, 0x3f, 0x01, 0x02, 0x18, 0x3f, 0x01, 0x02, + 0x1c, 0x3f, 0x01, 0x02, 0x20, 0x3f, 0x01, 0x02, 0x24, 0x3f, 0x01, 0x02, 0x28, 0x3f, 0x01, 0x02, 0x98, 0x18, 0x02, 0x02, 0x9c, 0x18, 0x02, 0x02, 0xa0, 0x18, 0x02, 0x02, 0xa4, 0x18, 0x02, 0x02, + 0x08, 0x3b, 0x03, 0x03, 0x10, 0x3b, 0x03, 0x03, 0x18, 0x3b, 0x03, 0x03, 0x90, 0x15, 0x04, 0x03, 0x98, 0x15, 0x04, 0x03, 0xc0, 0x36, 0x05, 0x04, 0xd0, 0x36, 0x05, 0x04, 0xb0, 0x12, 0x06, 0x04, + 0xe0, 0x0d, 0x08, 0x05, 0x80, 0x29, 0x0b, 0x07, 0xe8, 0x0b, 0x00, 0x02, 0xec, 0x0b, 0x00, 0x02, 0xf0, 0x0b, 0x00, 0x02, 0xf4, 0x0b, 0x00, 0x02, 0x2c, 0x3f, 0x01, 0x02, 0x30, 0x3f, 0x01, 0x02, + 0x34, 0x3f, 0x01, 0x02, 0x38, 0x3f, 0x01, 0x02, 0x3c, 0x3f, 0x01, 0x02, 0x40, 0x3f, 0x01, 0x02, 0xa8, 0x18, 0x02, 0x02, 0xac, 0x18, 0x02, 0x02, 0xb0, 0x18, 0x02, 0x02, 0xb4, 0x18, 0x02, 0x02, + 0x20, 0x3b, 0x03, 0x03, 0x28, 0x3b, 0x03, 0x03, 0x30, 0x3b, 0x03, 0x03, 0xa0, 0x15, 0x04, 0x03, 0xa8, 0x15, 0x04, 0x03, 0xe0, 0x36, 0x05, 0x04, 0xf0, 0x36, 0x05, 0x04, 0xc0, 0x12, 0x06, 0x04, + 0x00, 0x0e, 0x08, 0x05, 0x00, 0x2a, 0x0b, 0x07, 0xf8, 0x0b, 0x00, 0x02, 0xfc, 0x0b, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x04, 0x0c, 0x00, 0x02, 0x44, 0x3f, 0x01, 0x02, 0x48, 0x3f, 0x01, 0x02, + 0x4c, 0x3f, 0x01, 0x02, 0x50, 0x3f, 0x01, 0x02, 0x54, 0x3f, 0x01, 0x02, 0x58, 0x3f, 0x01, 0x02, 0xb8, 0x18, 0x02, 0x02, 0xbc, 0x18, 0x02, 0x02, 0xc0, 0x18, 0x02, 0x02, 0xc4, 0x18, 0x02, 0x02, + 0x38, 0x3b, 0x03, 0x03, 0x40, 0x3b, 0x03, 0x03, 0x48, 0x3b, 0x03, 0x03, 0xb0, 0x15, 0x04, 0x03, 0xb8, 0x15, 0x04, 0x03, 0x00, 0x37, 0x05, 0x04, 0x10, 0x37, 0x05, 0x04, 0xd0, 0x12, 0x06, 0x04, + 0x20, 0x0e, 0x08, 0x05, 0x80, 0x2a, 0x0b, 0x07, 0x08, 0x0c, 0x00, 0x02, 0x0c, 0x0c, 0x00, 0x02, 0x10, 0x0c, 0x00, 0x02, 0x14, 0x0c, 0x00, 0x02, 0x5c, 0x3f, 0x01, 0x02, 0x60, 0x3f, 0x01, 0x02, + 0x64, 0x3f, 0x01, 0x02, 0x68, 0x3f, 0x01, 0x02, 0x6c, 0x3f, 0x01, 0x02, 0x70, 0x3f, 0x01, 0x02, 0xc8, 0x18, 0x02, 0x02, 0xcc, 0x18, 0x02, 0x02, 0xd0, 0x18, 0x02, 0x02, 0xd4, 0x18, 0x02, 0x02, + 0x50, 0x3b, 0x03, 0x03, 0x58, 0x3b, 0x03, 0x03, 0x60, 0x3b, 0x03, 0x03, 0xc0, 0x15, 0x04, 0x03, 0xc8, 0x15, 0x04, 0x03, 0x20, 0x37, 0x05, 0x04, 0x30, 0x37, 0x05, 0x04, 0xe0, 0x12, 0x06, 0x04, + 0x40, 0x0e, 0x08, 0x05, 0x00, 0x2b, 0x0b, 0x07, 0x18, 0x0c, 0x00, 0x02, 0x1c, 0x0c, 0x00, 0x02, 0x20, 0x0c, 0x00, 0x02, 0x24, 0x0c, 0x00, 0x02, 0x74, 0x3f, 0x01, 0x02, 0x78, 0x3f, 0x01, 0x02, + 0x7c, 0x3f, 0x01, 0x02, 0x80, 0x3f, 0x01, 0x02, 0x84, 0x3f, 0x01, 0x02, 0x88, 0x3f, 0x01, 0x02, 0xd8, 0x18, 0x02, 0x02, 0xdc, 0x18, 0x02, 0x02, 0xe0, 0x18, 0x02, 0x02, 0xe4, 0x18, 0x02, 0x02, + 0x68, 0x3b, 0x03, 0x03, 0x70, 0x3b, 0x03, 0x03, 0x78, 0x3b, 0x03, 0x03, 0xd0, 0x15, 0x04, 0x03, 0xd8, 0x15, 0x04, 0x03, 0x40, 0x37, 0x05, 0x04, 0x50, 0x37, 0x05, 0x04, 0xf0, 0x12, 0x06, 0x04, + 0x60, 0x0e, 0x08, 0x05, 0x80, 0x2b, 0x0b, 0x07, 0x28, 0x0c, 0x00, 0x02, 0x2c, 0x0c, 0x00, 0x02, 0x30, 0x0c, 0x00, 0x02, 0x34, 0x0c, 0x00, 0x02, 0x8c, 0x3f, 0x01, 0x02, 0x90, 0x3f, 0x01, 0x02, + 0x94, 0x3f, 0x01, 0x02, 0x98, 0x3f, 0x01, 0x02, 0x9c, 0x3f, 0x01, 0x02, 0xa0, 0x3f, 0x01, 0x02, 0xe8, 0x18, 0x02, 0x02, 0xec, 0x18, 0x02, 0x02, 0xf0, 0x18, 0x02, 0x02, 0xf4, 0x18, 0x02, 0x02, + 0x80, 0x3b, 0x03, 0x03, 0x88, 0x3b, 0x03, 0x03, 0x90, 0x3b, 0x03, 0x03, 0xe0, 0x15, 0x04, 0x03, 0xe8, 0x15, 0x04, 0x03, 0x60, 0x37, 0x05, 0x04, 0x70, 0x37, 0x05, 0x04, 0x00, 0x13, 0x06, 0x04, + 0x80, 0x0e, 0x08, 0x05, 0x00, 0x2c, 0x0b, 0x07, 0x38, 0x0c, 0x00, 0x02, 0x3c, 0x0c, 0x00, 0x02, 0x40, 0x0c, 0x00, 0x02, 0x44, 0x0c, 0x00, 0x02, 0xa4, 0x3f, 0x01, 0x02, 0xa8, 0x3f, 0x01, 0x02, + 0xac, 0x3f, 0x01, 0x02, 0xb0, 0x3f, 0x01, 0x02, 0xb4, 0x3f, 0x01, 0x02, 0xb8, 0x3f, 0x01, 0x02, 0xf8, 0x18, 0x02, 0x02, 0xfc, 0x18, 0x02, 0x02, 0x00, 0x19, 0x02, 0x02, 0x04, 0x19, 0x02, 0x02, + 0x98, 0x3b, 0x03, 0x03, 0xa0, 0x3b, 0x03, 0x03, 0xa8, 0x3b, 0x03, 0x03, 0xf0, 0x15, 0x04, 0x03, 0xf8, 0x15, 0x04, 0x03, 0x80, 0x37, 0x05, 0x04, 0x90, 0x37, 0x05, 0x04, 0x10, 0x13, 0x06, 0x04, + 0xa0, 0x0e, 0x08, 0x05, 0x80, 0x2c, 0x0b, 0x07, 0x48, 0x0c, 0x00, 0x02, 0x4c, 0x0c, 0x00, 0x02, 0x50, 0x0c, 0x00, 0x02, 0x54, 0x0c, 0x00, 0x02, 0xbc, 0x3f, 0x01, 0x02, 0xc0, 0x3f, 0x01, 0x02, + 0xc4, 0x3f, 0x01, 0x02, 0xc8, 0x3f, 0x01, 0x02, 0xcc, 0x3f, 0x01, 0x02, 0xd0, 0x3f, 0x01, 0x02, 0x08, 0x19, 0x02, 0x02, 0x0c, 0x19, 0x02, 0x02, 0x10, 0x19, 0x02, 0x02, 0x14, 0x19, 0x02, 0x02, + 0xb0, 0x3b, 0x03, 0x03, 0xb8, 0x3b, 0x03, 0x03, 0xc0, 0x3b, 0x03, 0x03, 0x00, 0x16, 0x04, 0x03, 0x08, 0x16, 0x04, 0x03, 0xa0, 0x37, 0x05, 0x04, 0xb0, 0x37, 0x05, 0x04, 0x20, 0x13, 0x06, 0x04, + 0xc0, 0x0e, 0x08, 0x05, 0x00, 0x2d, 0x0b, 0x07, 0x58, 0x0c, 0x00, 0x02, 0x5c, 0x0c, 0x00, 0x02, 0x60, 0x0c, 0x00, 0x02, 0x64, 0x0c, 0x00, 0x02, 0xd4, 0x3f, 0x01, 0x02, 0xd8, 0x3f, 0x01, 0x02, + 0xdc, 0x3f, 0x01, 0x02, 0xe0, 0x3f, 0x01, 0x02, 0xe4, 0x3f, 0x01, 0x02, 0xe8, 0x3f, 0x01, 0x02, 0x18, 0x19, 0x02, 0x02, 0x1c, 0x19, 0x02, 0x02, 0x20, 0x19, 0x02, 0x02, 0x24, 0x19, 0x02, 0x02, + 0xc8, 0x3b, 0x03, 0x03, 0xd0, 0x3b, 0x03, 0x03, 0xd8, 0x3b, 0x03, 0x03, 0x10, 0x16, 0x04, 0x03, 0x18, 0x16, 0x04, 0x03, 0xc0, 0x37, 0x05, 0x04, 0xd0, 0x37, 0x05, 0x04, 0x30, 0x13, 0x06, 0x04, + 0xe0, 0x0e, 0x08, 0x05, 0x80, 0x2d, 0x0b, 0x07, 0x68, 0x0c, 0x00, 0x02, 0x6c, 0x0c, 0x00, 0x02, 0x70, 0x0c, 0x00, 0x02, 0x74, 0x0c, 0x00, 0x02, 0xec, 0x3f, 0x01, 0x02, 0xf0, 0x3f, 0x01, 0x02, + 0xf4, 0x3f, 0x01, 0x02, 0xf8, 0x3f, 0x01, 0x02, 0xfc, 0x3f, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x28, 0x19, 0x02, 0x02, 0x2c, 0x19, 0x02, 0x02, 0x30, 0x19, 0x02, 0x02, 0x34, 0x19, 0x02, 0x02, + 0xe0, 0x3b, 0x03, 0x03, 0xe8, 0x3b, 0x03, 0x03, 0xf0, 0x3b, 0x03, 0x03, 0x20, 0x16, 0x04, 0x03, 0x28, 0x16, 0x04, 0x03, 0xe0, 0x37, 0x05, 0x04, 0xf0, 0x37, 0x05, 0x04, 0x40, 0x13, 0x06, 0x04, + 0x00, 0x0f, 0x08, 0x05, 0x80, 0x07, 0x0c, 0x07, 0x78, 0x0c, 0x00, 0x02, 0x7c, 0x0c, 0x00, 0x02, 0x80, 0x0c, 0x00, 0x02, 0x84, 0x0c, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x01, + 0x06, 0x00, 0x01, 0x01, 0x08, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x01, 0x0c, 0x00, 0x01, 0x01, 0x38, 0x19, 0x02, 0x02, 0x3c, 0x19, 0x02, 0x02, 0x40, 0x19, 0x02, 0x02, 0x44, 0x19, 0x02, 0x02, + 0xf8, 0x3b, 0x03, 0x03, 0x00, 0x3c, 0x03, 0x03, 0x08, 0x3c, 0x03, 0x03, 0x30, 0x16, 0x04, 0x03, 0x38, 0x16, 0x04, 0x03, 0x00, 0x38, 0x05, 0x04, 0x10, 0x38, 0x05, 0x04, 0x50, 0x13, 0x06, 0x04, + 0x20, 0x0f, 0x08, 0x05, 0x00, 0x08, 0x0c, 0x07, 0x88, 0x0c, 0x00, 0x02, 0x8c, 0x0c, 0x00, 0x02, 0x90, 0x0c, 0x00, 0x02, 0x94, 0x0c, 0x00, 0x02, 0x0e, 0x00, 0x01, 0x01, 0x10, 0x00, 0x01, 0x01, + 0x12, 0x00, 0x01, 0x01, 0x14, 0x00, 0x01, 0x01, 0x16, 0x00, 0x01, 0x01, 0x18, 0x00, 0x01, 0x01, 0x48, 0x19, 0x02, 0x02, 0x4c, 0x19, 0x02, 0x02, 0x50, 0x19, 0x02, 0x02, 0x54, 0x19, 0x02, 0x02, + 0x10, 0x3c, 0x03, 0x03, 0x18, 0x3c, 0x03, 0x03, 0x20, 0x3c, 0x03, 0x03, 0x40, 0x16, 0x04, 0x03, 0x48, 0x16, 0x04, 0x03, 0x20, 0x38, 0x05, 0x04, 0x30, 0x38, 0x05, 0x04, 0x60, 0x13, 0x06, 0x04, + 0x40, 0x0f, 0x08, 0x05, 0x80, 0x08, 0x0c, 0x07, 0x98, 0x0c, 0x00, 0x02, 0x9c, 0x0c, 0x00, 0x02, 0xa0, 0x0c, 0x00, 0x02, 0xa4, 0x0c, 0x00, 0x02, 0x1a, 0x00, 0x01, 0x01, 0x1c, 0x00, 0x01, 0x01, + 0x1e, 0x00, 0x01, 0x01, 0x20, 0x00, 0x01, 0x01, 0x22, 0x00, 0x01, 0x01, 0x24, 0x00, 0x01, 0x01, 0x58, 0x19, 0x02, 0x02, 0x5c, 0x19, 0x02, 0x02, 0x60, 0x19, 0x02, 0x02, 0x64, 0x19, 0x02, 0x02, + 0x28, 0x3c, 0x03, 0x03, 0x30, 0x3c, 0x03, 0x03, 0x38, 0x3c, 0x03, 0x03, 0x50, 0x16, 0x04, 0x03, 0x58, 0x16, 0x04, 0x03, 0x40, 0x38, 0x05, 0x04, 0x50, 0x38, 0x05, 0x04, 0x70, 0x13, 0x06, 0x04, + 0x60, 0x0f, 0x08, 0x05, 0x00, 0x09, 0x0c, 0x07, 0xa8, 0x0c, 0x00, 0x02, 0xac, 0x0c, 0x00, 0x02, 0xb0, 0x0c, 0x00, 0x02, 0xb4, 0x0c, 0x00, 0x02, 0x26, 0x00, 0x01, 0x01, 0x28, 0x00, 0x01, 0x01, + 0x2a, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x01, 0x01, 0x2e, 0x00, 0x01, 0x01, 0x30, 0x00, 0x01, 0x01, 0x68, 0x19, 0x02, 0x02, 0x6c, 0x19, 0x02, 0x02, 0x70, 0x19, 0x02, 0x02, 0x74, 0x19, 0x02, 0x02, + 0x40, 0x3c, 0x03, 0x03, 0x48, 0x3c, 0x03, 0x03, 0x50, 0x3c, 0x03, 0x03, 0x60, 0x16, 0x04, 0x03, 0x68, 0x16, 0x04, 0x03, 0x60, 0x38, 0x05, 0x04, 0x70, 0x38, 0x05, 0x04, 0x80, 0x13, 0x06, 0x04, + 0x80, 0x0f, 0x08, 0x05, 0x80, 0x09, 0x0c, 0x07, 0xb8, 0x0c, 0x00, 0x02, 0xbc, 0x0c, 0x00, 0x02, 0xc0, 0x0c, 0x00, 0x02, 0x32, 0x00, 0x01, 0x01, 0x34, 0x00, 0x01, 0x01, 0x36, 0x00, 0x01, 0x01, + 0x38, 0x00, 0x01, 0x01, 0x3a, 0x00, 0x01, 0x01, 0x3c, 0x00, 0x01, 0x01, 0x3e, 0x00, 0x01, 0x01, 0x78, 0x19, 0x02, 0x02, 0x7c, 0x19, 0x02, 0x02, 0x80, 0x19, 0x02, 0x02, 0x84, 0x19, 0x02, 0x02, + 0x58, 0x3c, 0x03, 0x03, 0x60, 0x3c, 0x03, 0x03, 0x68, 0x3c, 0x03, 0x03, 0x70, 0x16, 0x04, 0x03, 0x78, 0x16, 0x04, 0x03, 0x80, 0x38, 0x05, 0x04, 0x90, 0x38, 0x05, 0x04, 0x90, 0x13, 0x06, 0x04, + 0xa0, 0x0f, 0x08, 0x05, 0x00, 0x0a, 0x0c, 0x07, 0xc4, 0x0c, 0x00, 0x02, 0xc8, 0x0c, 0x00, 0x02, 0xcc, 0x0c, 0x00, 0x02, 0x40, 0x00, 0x01, 0x01, 0x42, 0x00, 0x01, 0x01, 0x44, 0x00, 0x01, 0x01, + 0x46, 0x00, 0x01, 0x01, 0x48, 0x00, 0x01, 0x01, 0x4a, 0x00, 0x01, 0x01, 0x4c, 0x00, 0x01, 0x01, 0x88, 0x19, 0x02, 0x02, 0x8c, 0x19, 0x02, 0x02, 0x90, 0x19, 0x02, 0x02, 0x94, 0x19, 0x02, 0x02, + 0x70, 0x3c, 0x03, 0x03, 0x78, 0x3c, 0x03, 0x03, 0x80, 0x3c, 0x03, 0x03, 0x80, 0x16, 0x04, 0x03, 0x88, 0x16, 0x04, 0x03, 0xa0, 0x38, 0x05, 0x04, 0xa0, 0x13, 0x06, 0x04, 0x80, 0x33, 0x07, 0x05, + 0xc0, 0x0f, 0x08, 0x05, 0x80, 0x0a, 0x0c, 0x07, 0xd0, 0x0c, 0x00, 0x02, 0xd4, 0x0c, 0x00, 0x02, 0xd8, 0x0c, 0x00, 0x02, 0x4e, 0x00, 0x01, 0x01, 0x50, 0x00, 0x01, 0x01, 0x52, 0x00, 0x01, 0x01, + 0x54, 0x00, 0x01, 0x01, 0x56, 0x00, 0x01, 0x01, 0x58, 0x00, 0x01, 0x01, 0x5a, 0x00, 0x01, 0x01, 0x98, 0x19, 0x02, 0x02, 0x9c, 0x19, 0x02, 0x02, 0xa0, 0x19, 0x02, 0x02, 0xa4, 0x19, 0x02, 0x02, + 0x88, 0x3c, 0x03, 0x03, 0x90, 0x3c, 0x03, 0x03, 0x98, 0x3c, 0x03, 0x03, 0x90, 0x16, 0x04, 0x03, 0x98, 0x16, 0x04, 0x03, 0xb0, 0x38, 0x05, 0x04, 0xb0, 0x13, 0x06, 0x04, 0xa0, 0x33, 0x07, 0x05, + 0xe0, 0x0f, 0x08, 0x05, 0x00, 0x0b, 0x0c, 0x07, 0xdc, 0x0c, 0x00, 0x02, 0xe0, 0x0c, 0x00, 0x02, 0xe4, 0x0c, 0x00, 0x02, 0x5c, 0x00, 0x01, 0x01, 0x5e, 0x00, 0x01, 0x01, 0x60, 0x00, 0x01, 0x01, + 0x62, 0x00, 0x01, 0x01, 0x64, 0x00, 0x01, 0x01, 0x66, 0x00, 0x01, 0x01, 0x68, 0x00, 0x01, 0x01, 0xa8, 0x19, 0x02, 0x02, 0xac, 0x19, 0x02, 0x02, 0xb0, 0x19, 0x02, 0x02, 0xb4, 0x19, 0x02, 0x02, + 0xa0, 0x3c, 0x03, 0x03, 0xa8, 0x3c, 0x03, 0x03, 0xb0, 0x3c, 0x03, 0x03, 0xa0, 0x16, 0x04, 0x03, 0xa8, 0x16, 0x04, 0x03, 0xc0, 0x38, 0x05, 0x04, 0xc0, 0x13, 0x06, 0x04, 0xc0, 0x33, 0x07, 0x05, + 0x00, 0x10, 0x08, 0x05, 0x80, 0x0b, 0x0c, 0x07, 0xe8, 0x0c, 0x00, 0x02, 0xec, 0x0c, 0x00, 0x02, 0xf0, 0x0c, 0x00, 0x02, 0x6a, 0x00, 0x01, 0x01, 0x6c, 0x00, 0x01, 0x01, 0x6e, 0x00, 0x01, 0x01, + 0x70, 0x00, 0x01, 0x01, 0x72, 0x00, 0x01, 0x01, 0x74, 0x00, 0x01, 0x01, 0x76, 0x00, 0x01, 0x01, 0xb8, 0x19, 0x02, 0x02, 0xbc, 0x19, 0x02, 0x02, 0xc0, 0x19, 0x02, 0x02, 0xc4, 0x19, 0x02, 0x02, + 0xb8, 0x3c, 0x03, 0x03, 0xc0, 0x3c, 0x03, 0x03, 0xc8, 0x3c, 0x03, 0x03, 0xb0, 0x16, 0x04, 0x03, 0xb8, 0x16, 0x04, 0x03, 0xd0, 0x38, 0x05, 0x04, 0xd0, 0x13, 0x06, 0x04, 0xe0, 0x33, 0x07, 0x05, + 0x20, 0x10, 0x08, 0x05, 0x00, 0x23, 0x0d, 0x08, 0xf4, 0x0c, 0x00, 0x02, 0xf8, 0x0c, 0x00, 0x02, 0xfc, 0x0c, 0x00, 0x02, 0x78, 0x00, 0x01, 0x01, 0x7a, 0x00, 0x01, 0x01, 0x7c, 0x00, 0x01, 0x01, + 0x7e, 0x00, 0x01, 0x01, 0x80, 0x00, 0x01, 0x01, 0x82, 0x00, 0x01, 0x01, 0x84, 0x00, 0x01, 0x01, 0xc8, 0x19, 0x02, 0x02, 0xcc, 0x19, 0x02, 0x02, 0xd0, 0x19, 0x02, 0x02, 0xd4, 0x19, 0x02, 0x02, + 0xd0, 0x3c, 0x03, 0x03, 0xd8, 0x3c, 0x03, 0x03, 0xe0, 0x3c, 0x03, 0x03, 0xc0, 0x16, 0x04, 0x03, 0xc8, 0x16, 0x04, 0x03, 0xe0, 0x38, 0x05, 0x04, 0xe0, 0x13, 0x06, 0x04, 0x00, 0x34, 0x07, 0x05, + 0x40, 0x10, 0x08, 0x05, 0x00, 0x24, 0x0d, 0x08, 0x00, 0x0d, 0x00, 0x02, 0x04, 0x0d, 0x00, 0x02, 0x08, 0x0d, 0x00, 0x02, 0x86, 0x00, 0x01, 0x01, 0x88, 0x00, 0x01, 0x01, 0x8a, 0x00, 0x01, 0x01, + 0x8c, 0x00, 0x01, 0x01, 0x8e, 0x00, 0x01, 0x01, 0x90, 0x00, 0x01, 0x01, 0x92, 0x00, 0x01, 0x01, 0xd8, 0x19, 0x02, 0x02, 0xdc, 0x19, 0x02, 0x02, 0xe0, 0x19, 0x02, 0x02, 0xe4, 0x19, 0x02, 0x02, + 0xe8, 0x3c, 0x03, 0x03, 0xf0, 0x3c, 0x03, 0x03, 0xf8, 0x3c, 0x03, 0x03, 0xd0, 0x16, 0x04, 0x03, 0xd8, 0x16, 0x04, 0x03, 0xf0, 0x38, 0x05, 0x04, 0xf0, 0x13, 0x06, 0x04, 0x20, 0x34, 0x07, 0x05, + 0x60, 0x10, 0x08, 0x05, 0x00, 0x25, 0x0d, 0x08, 0x0c, 0x0d, 0x00, 0x02, 0x10, 0x0d, 0x00, 0x02, 0x14, 0x0d, 0x00, 0x02, 0x94, 0x00, 0x01, 0x01, 0x96, 0x00, 0x01, 0x01, 0x98, 0x00, 0x01, 0x01, + 0x9a, 0x00, 0x01, 0x01, 0x9c, 0x00, 0x01, 0x01, 0x9e, 0x00, 0x01, 0x01, 0xa0, 0x00, 0x01, 0x01, 0xe8, 0x19, 0x02, 0x02, 0xec, 0x19, 0x02, 0x02, 0xf0, 0x19, 0x02, 0x02, 0xf4, 0x19, 0x02, 0x02, + 0x00, 0x3d, 0x03, 0x03, 0x08, 0x3d, 0x03, 0x03, 0x10, 0x3d, 0x03, 0x03, 0xe0, 0x16, 0x04, 0x03, 0xe8, 0x16, 0x04, 0x03, 0x00, 0x39, 0x05, 0x04, 0x00, 0x14, 0x06, 0x04, 0x40, 0x34, 0x07, 0x05, + 0x80, 0x10, 0x08, 0x05, 0x00, 0x26, 0x0d, 0x08, 0x18, 0x0d, 0x00, 0x02, 0x1c, 0x0d, 0x00, 0x02, 0x20, 0x0d, 0x00, 0x02, 0xa2, 0x00, 0x01, 0x01, 0xa4, 0x00, 0x01, 0x01, 0xa6, 0x00, 0x01, 0x01, + 0xa8, 0x00, 0x01, 0x01, 0xaa, 0x00, 0x01, 0x01, 0xac, 0x00, 0x01, 0x01, 0xae, 0x00, 0x01, 0x01, 0xf8, 0x19, 0x02, 0x02, 0xfc, 0x19, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x04, 0x1a, 0x02, 0x02, + 0x18, 0x3d, 0x03, 0x03, 0x20, 0x3d, 0x03, 0x03, 0x28, 0x3d, 0x03, 0x03, 0xf0, 0x16, 0x04, 0x03, 0xf8, 0x16, 0x04, 0x03, 0x10, 0x39, 0x05, 0x04, 0x10, 0x14, 0x06, 0x04, 0x60, 0x34, 0x07, 0x05, + 0xa0, 0x10, 0x08, 0x05, 0x00, 0x27, 0x0d, 0x08, 0x24, 0x0d, 0x00, 0x02, 0x28, 0x0d, 0x00, 0x02, 0x2c, 0x0d, 0x00, 0x02, 0xb0, 0x00, 0x01, 0x01, 0xb2, 0x00, 0x01, 0x01, 0xb4, 0x00, 0x01, 0x01, + 0xb6, 0x00, 0x01, 0x01, 0xb8, 0x00, 0x01, 0x01, 0xba, 0x00, 0x01, 0x01, 0xbc, 0x00, 0x01, 0x01, 0x08, 0x1a, 0x02, 0x02, 0x0c, 0x1a, 0x02, 0x02, 0x10, 0x1a, 0x02, 0x02, 0x14, 0x1a, 0x02, 0x02, + 0x30, 0x3d, 0x03, 0x03, 0x38, 0x3d, 0x03, 0x03, 0x40, 0x3d, 0x03, 0x03, 0x00, 0x17, 0x04, 0x03, 0x08, 0x17, 0x04, 0x03, 0x20, 0x39, 0x05, 0x04, 0x20, 0x14, 0x06, 0x04, 0x80, 0x34, 0x07, 0x05, + 0xc0, 0x10, 0x08, 0x05, 0x00, 0x28, 0x0d, 0x08, 0x30, 0x0d, 0x00, 0x02, 0x34, 0x0d, 0x00, 0x02, 0x38, 0x0d, 0x00, 0x02, 0xbe, 0x00, 0x01, 0x01, 0xc0, 0x00, 0x01, 0x01, 0xc2, 0x00, 0x01, 0x01, + 0xc4, 0x00, 0x01, 0x01, 0xc6, 0x00, 0x01, 0x01, 0xc8, 0x00, 0x01, 0x01, 0xca, 0x00, 0x01, 0x01, 0x18, 0x1a, 0x02, 0x02, 0x1c, 0x1a, 0x02, 0x02, 0x20, 0x1a, 0x02, 0x02, 0x24, 0x1a, 0x02, 0x02, + 0x48, 0x3d, 0x03, 0x03, 0x50, 0x3d, 0x03, 0x03, 0x58, 0x3d, 0x03, 0x03, 0x10, 0x17, 0x04, 0x03, 0x18, 0x17, 0x04, 0x03, 0x30, 0x39, 0x05, 0x04, 0x30, 0x14, 0x06, 0x04, 0xa0, 0x34, 0x07, 0x05, + 0xe0, 0x10, 0x08, 0x05, 0x00, 0x29, 0x0d, 0x08, 0x3c, 0x0d, 0x00, 0x02, 0x40, 0x0d, 0x00, 0x02, 0x44, 0x0d, 0x00, 0x02, 0xcc, 0x00, 0x01, 0x01, 0xce, 0x00, 0x01, 0x01, 0xd0, 0x00, 0x01, 0x01, + 0xd2, 0x00, 0x01, 0x01, 0xd4, 0x00, 0x01, 0x01, 0xd6, 0x00, 0x01, 0x01, 0xd8, 0x00, 0x01, 0x01, 0x28, 0x1a, 0x02, 0x02, 0x2c, 0x1a, 0x02, 0x02, 0x30, 0x1a, 0x02, 0x02, 0x34, 0x1a, 0x02, 0x02, + 0x60, 0x3d, 0x03, 0x03, 0x68, 0x3d, 0x03, 0x03, 0x70, 0x3d, 0x03, 0x03, 0x20, 0x17, 0x04, 0x03, 0x28, 0x17, 0x04, 0x03, 0x40, 0x39, 0x05, 0x04, 0x40, 0x14, 0x06, 0x04, 0xc0, 0x34, 0x07, 0x05, + 0x00, 0x11, 0x08, 0x05, 0x00, 0x06, 0x0e, 0x08, 0x48, 0x0d, 0x00, 0x02, 0x4c, 0x0d, 0x00, 0x02, 0x50, 0x0d, 0x00, 0x02, 0xda, 0x00, 0x01, 0x01, 0xdc, 0x00, 0x01, 0x01, 0xde, 0x00, 0x01, 0x01, + 0xe0, 0x00, 0x01, 0x01, 0xe2, 0x00, 0x01, 0x01, 0xe4, 0x00, 0x01, 0x01, 0xe6, 0x00, 0x01, 0x01, 0x38, 0x1a, 0x02, 0x02, 0x3c, 0x1a, 0x02, 0x02, 0x40, 0x1a, 0x02, 0x02, 0x44, 0x1a, 0x02, 0x02, + 0x78, 0x3d, 0x03, 0x03, 0x80, 0x3d, 0x03, 0x03, 0x88, 0x3d, 0x03, 0x03, 0x30, 0x17, 0x04, 0x03, 0x38, 0x17, 0x04, 0x03, 0x50, 0x39, 0x05, 0x04, 0x50, 0x14, 0x06, 0x04, 0xe0, 0x34, 0x07, 0x05, + 0x20, 0x11, 0x08, 0x05, 0x00, 0x07, 0x0e, 0x08, 0x54, 0x0d, 0x00, 0x02, 0x58, 0x0d, 0x00, 0x02, 0x5c, 0x0d, 0x00, 0x02, 0xe8, 0x00, 0x01, 0x01, 0xea, 0x00, 0x01, 0x01, 0xec, 0x00, 0x01, 0x01, + 0xee, 0x00, 0x01, 0x01, 0xf0, 0x00, 0x01, 0x01, 0xf2, 0x00, 0x01, 0x01, 0xf4, 0x00, 0x01, 0x01, 0x48, 0x1a, 0x02, 0x02, 0x4c, 0x1a, 0x02, 0x02, 0x50, 0x1a, 0x02, 0x02, 0x54, 0x1a, 0x02, 0x02, + 0x90, 0x3d, 0x03, 0x03, 0x98, 0x3d, 0x03, 0x03, 0xa0, 0x3d, 0x03, 0x03, 0x40, 0x17, 0x04, 0x03, 0x48, 0x17, 0x04, 0x03, 0x60, 0x39, 0x05, 0x04, 0x60, 0x14, 0x06, 0x04, 0x00, 0x35, 0x07, 0x05, + 0x40, 0x11, 0x08, 0x05, 0x00, 0x08, 0x0e, 0x08, 0x60, 0x0d, 0x00, 0x02, 0x64, 0x0d, 0x00, 0x02, 0x68, 0x0d, 0x00, 0x02, 0xf6, 0x00, 0x01, 0x01, 0xf8, 0x00, 0x01, 0x01, 0xfa, 0x00, 0x01, 0x01, + 0xfc, 0x00, 0x01, 0x01, 0xfe, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x58, 0x1a, 0x02, 0x02, 0x5c, 0x1a, 0x02, 0x02, 0x60, 0x1a, 0x02, 0x02, 0x64, 0x1a, 0x02, 0x02, + 0xa8, 0x3d, 0x03, 0x03, 0xb0, 0x3d, 0x03, 0x03, 0xb8, 0x3d, 0x03, 0x03, 0x50, 0x17, 0x04, 0x03, 0x58, 0x17, 0x04, 0x03, 0x70, 0x39, 0x05, 0x04, 0x70, 0x14, 0x06, 0x04, 0x20, 0x35, 0x07, 0x05, + 0x60, 0x11, 0x08, 0x05, 0x00, 0x09, 0x0e, 0x08, 0x6c, 0x0d, 0x00, 0x02, 0x70, 0x0d, 0x00, 0x02, 0x74, 0x0d, 0x00, 0x02, 0x04, 0x01, 0x01, 0x01, 0x06, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, + 0x0a, 0x01, 0x01, 0x01, 0x0c, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x01, 0x68, 0x1a, 0x02, 0x02, 0x6c, 0x1a, 0x02, 0x02, 0x70, 0x1a, 0x02, 0x02, 0x74, 0x1a, 0x02, 0x02, 0x78, 0x1a, 0x02, 0x02, + 0xc0, 0x3d, 0x03, 0x03, 0xc8, 0x3d, 0x03, 0x03, 0xd0, 0x3d, 0x03, 0x03, 0x60, 0x17, 0x04, 0x03, 0x68, 0x17, 0x04, 0x03, 0x80, 0x39, 0x05, 0x04, 0x80, 0x14, 0x06, 0x04, 0x40, 0x35, 0x07, 0x05, + 0x80, 0x11, 0x08, 0x05, 0x00, 0x24, 0x0f, 0x09, 0x78, 0x0d, 0x00, 0x02, 0x7c, 0x0d, 0x00, 0x02, 0x80, 0x0d, 0x00, 0x02, 0x10, 0x01, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x14, 0x01, 0x01, 0x01, + 0x16, 0x01, 0x01, 0x01, 0x18, 0x01, 0x01, 0x01, 0x1a, 0x01, 0x01, 0x01, 0x7c, 0x1a, 0x02, 0x02, 0x80, 0x1a, 0x02, 0x02, 0x84, 0x1a, 0x02, 0x02, 0x88, 0x1a, 0x02, 0x02, 0x8c, 0x1a, 0x02, 0x02, + 0xd8, 0x3d, 0x03, 0x03, 0xe0, 0x3d, 0x03, 0x03, 0xe8, 0x3d, 0x03, 0x03, 0x70, 0x17, 0x04, 0x03, 0x78, 0x17, 0x04, 0x03, 0x90, 0x39, 0x05, 0x04, 0x90, 0x14, 0x06, 0x04, 0x60, 0x35, 0x07, 0x05, + 0xa0, 0x11, 0x08, 0x05, 0x00, 0x26, 0x0f, 0x09, 0x84, 0x0d, 0x00, 0x02, 0x88, 0x0d, 0x00, 0x02, 0x8c, 0x0d, 0x00, 0x02, 0x1c, 0x01, 0x01, 0x01, 0x1e, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, + 0x22, 0x01, 0x01, 0x01, 0x00, 0x00, 0xfe, 0x0e, 0x00, 0x00, 0xfd, 0x0e, 0x00, 0x00, 0xfc, 0x0e, 0x00, 0x00, 0xfb, 0x0e, 0x00, 0x00, 0xfa, 0x0e, 0x00, 0x00, 0xf9, 0x0e, 0x00, 0x00, 0xf8, 0x0e, + 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0xf6, 0x0e, 0x00, 0x00, 0xf5, 0x0e, 0x00, 0x00, 0xf4, 0x0e, 0x00, 0x00, 0xf3, 0x0e, 0x00, 0x00, 0xf2, 0x0e, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0x00, 0xf0, 0x0e, + 0x00, 0x00, 0xef, 0x0e, 0x00, 0x00, 0xee, 0x0e, 0x00, 0x00, 0xed, 0x0e, 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xeb, 0x0e, 0x00, 0x00, 0xea, 0x0e, 0x00, 0x00, 0xe9, 0x0e, 0x00, 0x00, 0xe8, 0x0e, + 0x00, 0x00, 0xe7, 0x0e, 0x00, 0x00, 0xe6, 0x0e, 0x00, 0x00, 0xe5, 0x0e, 0x00, 0x00, 0xe4, 0x0e, 0x00, 0x00, 0xe3, 0x0e, 0x00, 0x00, 0xe2, 0x0e, 0x00, 0x00, 0xe1, 0x0e, 0x00, 0x00, 0xe0, 0x0e, + 0x00, 0x00, 0xdf, 0x0e, 0x00, 0x00, 0xde, 0x0e, 0x00, 0x00, 0xdd, 0x0e, 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0xdb, 0x0e, 0x00, 0x00, 0xda, 0x0e, 0x00, 0x00, 0xd9, 0x0e, 0x00, 0x00, 0xd8, 0x0e, + 0x00, 0x00, 0xd7, 0x0e, 0x00, 0x00, 0xd6, 0x0e, 0x00, 0x00, 0xd5, 0x0e, 0x00, 0x00, 0xd4, 0x0e, 0x00, 0x00, 0xd3, 0x0e, 0x00, 0x00, 0xd2, 0x0e, 0x00, 0x00, 0xd1, 0x0e, 0x00, 0x00, 0xd0, 0x0e, + 0x00, 0x00, 0xcf, 0x0e, 0x00, 0x00, 0xce, 0x0e, 0x00, 0x00, 0xcd, 0x0e, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x00, 0xcb, 0x0e, 0x00, 0x00, 0xca, 0x0e, 0x00, 0x00, 0xc9, 0x0e, 0x00, 0x00, 0xc8, 0x0e, + 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0xc5, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc3, 0x0e, 0x00, 0x00, 0xc2, 0x0e, 0x00, 0x00, 0xc1, 0x0e, 0x00, 0x00, 0xc0, 0x0e, + 0x00, 0x00, 0xbf, 0x0e, 0x00, 0x00, 0xbe, 0x0e, 0x00, 0x00, 0xbd, 0x0e, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x00, 0xbb, 0x0e, 0x00, 0x00, 0xba, 0x0e, 0x00, 0x00, 0xb9, 0x0e, 0x00, 0x00, 0xb8, 0x0e, + 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x00, 0xb6, 0x0e, 0x00, 0x00, 0xb5, 0x0e, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x00, 0xb3, 0x0e, 0x00, 0x00, 0xb2, 0x0e, 0x00, 0x00, 0xb1, 0x0e, 0x00, 0x00, 0xb0, 0x0e, + 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0xae, 0x0e, 0x00, 0x00, 0xad, 0x0e, 0x00, 0x00, 0xac, 0x0e, 0x00, 0x00, 0xab, 0x0e, 0x00, 0x00, 0xaa, 0x0e, 0x00, 0x00, 0xa9, 0x0e, 0x00, 0x00, 0xa8, 0x0e, + 0x00, 0x00, 0xa7, 0x0e, 0x00, 0x00, 0xa6, 0x0e, 0x00, 0x00, 0xa5, 0x0e, 0x00, 0x00, 0xa4, 0x0e, 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0xa2, 0x0e, 0x00, 0x00, 0xa1, 0x0e, 0x00, 0x00, 0xa0, 0x0e, + 0x00, 0x00, 0x9f, 0x0e, 0x00, 0x00, 0x9e, 0x0e, 0x00, 0x00, 0x9d, 0x0e, 0x00, 0x00, 0x9c, 0x0e, 0x00, 0x00, 0x9b, 0x0e, 0x00, 0x00, 0x9a, 0x0e, 0x00, 0x00, 0x99, 0x0e, 0x00, 0x00, 0x98, 0x0e, + 0x00, 0x00, 0x97, 0x0e, 0x00, 0x00, 0x96, 0x0e, 0x00, 0x00, 0x95, 0x0e, 0x00, 0x00, 0x94, 0x0e, 0x00, 0x00, 0x93, 0x0e, 0x00, 0x00, 0x92, 0x0e, 0x00, 0x00, 0x91, 0x0e, 0x00, 0x00, 0x90, 0x0e, + 0x00, 0x00, 0x8f, 0x0e, 0x00, 0x00, 0x8e, 0x0e, 0x00, 0x00, 0x8d, 0x0e, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x00, 0x8b, 0x0e, 0x00, 0x00, 0x8a, 0x0e, 0x00, 0x00, 0x89, 0x0e, 0x00, 0x00, 0x88, 0x0e, + 0x00, 0x00, 0x87, 0x0e, 0x00, 0x00, 0x86, 0x0e, 0x00, 0x00, 0x85, 0x0e, 0x00, 0x00, 0x84, 0x0e, 0x00, 0x00, 0x83, 0x0e, 0x00, 0x00, 0x82, 0x0e, 0x00, 0x00, 0x81, 0x0e, 0x00, 0x00, 0x80, 0x0e, + 0x00, 0x00, 0x7f, 0x0e, 0x00, 0x00, 0x7e, 0x0e, 0x00, 0x00, 0x7d, 0x0e, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x00, 0x7b, 0x0e, 0x00, 0x00, 0x7a, 0x0e, 0x00, 0x00, 0x79, 0x0e, 0x00, 0x00, 0x78, 0x0e, + 0x00, 0x00, 0x77, 0x0e, 0x00, 0x00, 0x76, 0x0e, 0x00, 0x00, 0x75, 0x0e, 0x00, 0x00, 0x74, 0x0e, 0x00, 0x00, 0x73, 0x0e, 0x00, 0x00, 0x72, 0x0e, 0x00, 0x00, 0x71, 0x0e, 0x00, 0x00, 0x70, 0x0e, + 0x00, 0x00, 0x6f, 0x0e, 0x00, 0x00, 0x6e, 0x0e, 0x00, 0x00, 0x6d, 0x0e, 0x00, 0x00, 0x6c, 0x0e, 0x00, 0x00, 0x6b, 0x0e, 0x00, 0x00, 0x6a, 0x0e, 0x00, 0x00, 0x69, 0x0e, 0x00, 0x00, 0x68, 0x0e, + 0x00, 0x00, 0x67, 0x0e, 0x00, 0x00, 0x66, 0x0e, 0x00, 0x00, 0x65, 0x0e, 0x00, 0x00, 0x64, 0x0e, 0x00, 0x00, 0x63, 0x0e, 0x00, 0x00, 0x62, 0x0e, 0x00, 0x00, 0x61, 0x0e, 0x00, 0x00, 0x60, 0x0e, + 0x00, 0x00, 0x5f, 0x0e, 0x00, 0x00, 0x5e, 0x0e, 0x00, 0x00, 0x5d, 0x0e, 0x00, 0x00, 0x5c, 0x0e, 0x00, 0x00, 0x5b, 0x0e, 0x00, 0x00, 0x5a, 0x0e, 0x00, 0x00, 0x59, 0x0e, 0x00, 0x00, 0x58, 0x0e, + 0x00, 0x00, 0x57, 0x0e, 0x00, 0x00, 0x56, 0x0e, 0x00, 0x00, 0x55, 0x0e, 0x00, 0x00, 0x54, 0x0e, 0x00, 0x00, 0x53, 0x0e, 0x00, 0x00, 0x52, 0x0e, 0x00, 0x00, 0x51, 0x0e, 0x00, 0x00, 0x50, 0x0e, + 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x4e, 0x0e, 0x00, 0x00, 0x4d, 0x0e, 0x00, 0x00, 0x4c, 0x0e, 0x00, 0x00, 0x4b, 0x0e, 0x00, 0x00, 0x4a, 0x0e, 0x00, 0x00, 0x49, 0x0e, 0x00, 0x00, 0x48, 0x0e, + 0x00, 0x00, 0x47, 0x0e, 0x00, 0x00, 0x46, 0x0e, 0x00, 0x00, 0x45, 0x0e, 0x00, 0x00, 0x44, 0x0e, 0x00, 0x00, 0x43, 0x0e, 0x00, 0x00, 0x42, 0x0e, 0x00, 0x00, 0x41, 0x0e, 0x00, 0x00, 0x40, 0x0e, + 0x00, 0x00, 0x3f, 0x0e, 0x00, 0x00, 0x3e, 0x0e, 0x00, 0x00, 0x3d, 0x0e, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x3a, 0x0e, 0x00, 0x00, 0x39, 0x0e, 0x00, 0x00, 0x38, 0x0e, + 0x00, 0x00, 0x37, 0x0e, 0x00, 0x00, 0x36, 0x0e, 0x00, 0x00, 0x35, 0x0e, 0x00, 0x00, 0x34, 0x0e, 0x00, 0x00, 0x33, 0x0e, 0x00, 0x00, 0x32, 0x0e, 0x00, 0x00, 0x31, 0x0e, 0x00, 0x00, 0x30, 0x0e, + 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x2e, 0x0e, 0x00, 0x00, 0x2d, 0x0e, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00, 0x2b, 0x0e, 0x00, 0x00, 0x2a, 0x0e, 0x00, 0x00, 0x29, 0x0e, 0x00, 0x00, 0x28, 0x0e, + 0x00, 0x00, 0x27, 0x0e, 0x00, 0x00, 0x26, 0x0e, 0x00, 0x00, 0x25, 0x0e, 0x00, 0x00, 0x24, 0x0e, 0x00, 0x00, 0x23, 0x0e, 0x00, 0x00, 0x22, 0x0e, 0x00, 0x00, 0x21, 0x0e, 0x00, 0x00, 0x20, 0x0e, + 0x00, 0x00, 0x1f, 0x0e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x1d, 0x0e, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0x1b, 0x0e, 0x00, 0x00, 0x1a, 0x0e, 0x00, 0x00, 0x19, 0x0e, 0x00, 0x00, 0x18, 0x0e, + 0x00, 0x00, 0x17, 0x0e +}; + +const byte DTable_2[65540] = { + 0x0e, 0x00, 0x01, 0x00, 0x90, 0x0d, 0x00, 0x03, 0x98, 0x0d, 0x00, 0x03, 0xa0, 0x0d, 0x00, 0x03, 0xa8, 0x0d, 0x00, 0x03, 0x24, 0x01, 0x01, 0x02, 0x28, 0x01, 0x01, 0x02, 0x2c, 0x01, 0x01, 0x02, + 0x30, 0x01, 0x01, 0x02, 0x34, 0x01, 0x01, 0x02, 0x38, 0x01, 0x01, 0x02, 0x90, 0x1a, 0x02, 0x03, 0x98, 0x1a, 0x02, 0x03, 0xa0, 0x1a, 0x02, 0x03, 0xa8, 0x1a, 0x02, 0x03, 0xb0, 0x1a, 0x02, 0x03, + 0xf0, 0x3d, 0x03, 0x04, 0x00, 0x3e, 0x03, 0x04, 0x10, 0x3e, 0x03, 0x04, 0x80, 0x17, 0x04, 0x04, 0x90, 0x17, 0x04, 0x04, 0xa0, 0x39, 0x05, 0x05, 0xa0, 0x14, 0x06, 0x05, 0x80, 0x35, 0x07, 0x06, + 0x80, 0x31, 0x09, 0x07, 0xb0, 0x0d, 0x00, 0x03, 0xb8, 0x0d, 0x00, 0x03, 0xc0, 0x0d, 0x00, 0x03, 0xc8, 0x0d, 0x00, 0x03, 0x3c, 0x01, 0x01, 0x02, 0x40, 0x01, 0x01, 0x02, 0x44, 0x01, 0x01, 0x02, + 0x48, 0x01, 0x01, 0x02, 0x4c, 0x01, 0x01, 0x02, 0x50, 0x01, 0x01, 0x02, 0xb8, 0x1a, 0x02, 0x03, 0xc0, 0x1a, 0x02, 0x03, 0xc8, 0x1a, 0x02, 0x03, 0xd0, 0x1a, 0x02, 0x03, 0xd8, 0x1a, 0x02, 0x03, + 0x20, 0x3e, 0x03, 0x04, 0x30, 0x3e, 0x03, 0x04, 0x40, 0x3e, 0x03, 0x04, 0xa0, 0x17, 0x04, 0x04, 0xb0, 0x17, 0x04, 0x04, 0xc0, 0x39, 0x05, 0x05, 0xc0, 0x14, 0x06, 0x05, 0xc0, 0x35, 0x07, 0x06, + 0x00, 0x32, 0x09, 0x07, 0xd0, 0x0d, 0x00, 0x03, 0xd8, 0x0d, 0x00, 0x03, 0xe0, 0x0d, 0x00, 0x03, 0xe8, 0x0d, 0x00, 0x03, 0x54, 0x01, 0x01, 0x02, 0x58, 0x01, 0x01, 0x02, 0x5c, 0x01, 0x01, 0x02, + 0x60, 0x01, 0x01, 0x02, 0x64, 0x01, 0x01, 0x02, 0x68, 0x01, 0x01, 0x02, 0xe0, 0x1a, 0x02, 0x03, 0xe8, 0x1a, 0x02, 0x03, 0xf0, 0x1a, 0x02, 0x03, 0xf8, 0x1a, 0x02, 0x03, 0x00, 0x1b, 0x02, 0x03, + 0x50, 0x3e, 0x03, 0x04, 0x60, 0x3e, 0x03, 0x04, 0x70, 0x3e, 0x03, 0x04, 0xc0, 0x17, 0x04, 0x04, 0xd0, 0x17, 0x04, 0x04, 0xe0, 0x39, 0x05, 0x05, 0xe0, 0x14, 0x06, 0x05, 0x00, 0x36, 0x07, 0x06, + 0x80, 0x32, 0x09, 0x07, 0xf0, 0x0d, 0x00, 0x03, 0xf8, 0x0d, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x03, 0x08, 0x0e, 0x00, 0x03, 0x6c, 0x01, 0x01, 0x02, 0x70, 0x01, 0x01, 0x02, 0x74, 0x01, 0x01, 0x02, + 0x78, 0x01, 0x01, 0x02, 0x7c, 0x01, 0x01, 0x02, 0x80, 0x01, 0x01, 0x02, 0x08, 0x1b, 0x02, 0x03, 0x10, 0x1b, 0x02, 0x03, 0x18, 0x1b, 0x02, 0x03, 0x20, 0x1b, 0x02, 0x03, 0x28, 0x1b, 0x02, 0x03, + 0x80, 0x3e, 0x03, 0x04, 0x90, 0x3e, 0x03, 0x04, 0xa0, 0x3e, 0x03, 0x04, 0xe0, 0x17, 0x04, 0x04, 0xf0, 0x17, 0x04, 0x04, 0x00, 0x3a, 0x05, 0x05, 0x00, 0x15, 0x06, 0x05, 0x40, 0x36, 0x07, 0x06, + 0x00, 0x33, 0x09, 0x07, 0x10, 0x0e, 0x00, 0x03, 0x18, 0x0e, 0x00, 0x03, 0x20, 0x0e, 0x00, 0x03, 0x28, 0x0e, 0x00, 0x03, 0x84, 0x01, 0x01, 0x02, 0x88, 0x01, 0x01, 0x02, 0x8c, 0x01, 0x01, 0x02, + 0x90, 0x01, 0x01, 0x02, 0x94, 0x01, 0x01, 0x02, 0x98, 0x01, 0x01, 0x02, 0x30, 0x1b, 0x02, 0x03, 0x38, 0x1b, 0x02, 0x03, 0x40, 0x1b, 0x02, 0x03, 0x48, 0x1b, 0x02, 0x03, 0x50, 0x1b, 0x02, 0x03, + 0xb0, 0x3e, 0x03, 0x04, 0xc0, 0x3e, 0x03, 0x04, 0xd0, 0x3e, 0x03, 0x04, 0x00, 0x18, 0x04, 0x04, 0x10, 0x18, 0x04, 0x04, 0x20, 0x3a, 0x05, 0x05, 0x20, 0x15, 0x06, 0x05, 0x80, 0x36, 0x07, 0x06, + 0x80, 0x33, 0x09, 0x07, 0x30, 0x0e, 0x00, 0x03, 0x38, 0x0e, 0x00, 0x03, 0x40, 0x0e, 0x00, 0x03, 0x48, 0x0e, 0x00, 0x03, 0x9c, 0x01, 0x01, 0x02, 0xa0, 0x01, 0x01, 0x02, 0xa4, 0x01, 0x01, 0x02, + 0xa8, 0x01, 0x01, 0x02, 0xac, 0x01, 0x01, 0x02, 0xb0, 0x01, 0x01, 0x02, 0x58, 0x1b, 0x02, 0x03, 0x60, 0x1b, 0x02, 0x03, 0x68, 0x1b, 0x02, 0x03, 0x70, 0x1b, 0x02, 0x03, 0x78, 0x1b, 0x02, 0x03, + 0xe0, 0x3e, 0x03, 0x04, 0xf0, 0x3e, 0x03, 0x04, 0x00, 0x3f, 0x03, 0x04, 0x20, 0x18, 0x04, 0x04, 0x30, 0x18, 0x04, 0x04, 0x40, 0x3a, 0x05, 0x05, 0x40, 0x15, 0x06, 0x05, 0xc0, 0x36, 0x07, 0x06, + 0x00, 0x34, 0x09, 0x07, 0x50, 0x0e, 0x00, 0x03, 0x58, 0x0e, 0x00, 0x03, 0x60, 0x0e, 0x00, 0x03, 0x68, 0x0e, 0x00, 0x03, 0xb4, 0x01, 0x01, 0x02, 0xb8, 0x01, 0x01, 0x02, 0xbc, 0x01, 0x01, 0x02, + 0xc0, 0x01, 0x01, 0x02, 0xc4, 0x01, 0x01, 0x02, 0xc8, 0x01, 0x01, 0x02, 0x80, 0x1b, 0x02, 0x03, 0x88, 0x1b, 0x02, 0x03, 0x90, 0x1b, 0x02, 0x03, 0x98, 0x1b, 0x02, 0x03, 0xa0, 0x1b, 0x02, 0x03, + 0x10, 0x3f, 0x03, 0x04, 0x20, 0x3f, 0x03, 0x04, 0x30, 0x3f, 0x03, 0x04, 0x40, 0x18, 0x04, 0x04, 0x50, 0x18, 0x04, 0x04, 0x60, 0x3a, 0x05, 0x05, 0x60, 0x15, 0x06, 0x05, 0x00, 0x37, 0x07, 0x06, + 0x80, 0x34, 0x09, 0x07, 0x70, 0x0e, 0x00, 0x03, 0x78, 0x0e, 0x00, 0x03, 0x80, 0x0e, 0x00, 0x03, 0x88, 0x0e, 0x00, 0x03, 0xcc, 0x01, 0x01, 0x02, 0xd0, 0x01, 0x01, 0x02, 0xd4, 0x01, 0x01, 0x02, + 0xd8, 0x01, 0x01, 0x02, 0xdc, 0x01, 0x01, 0x02, 0xe0, 0x01, 0x01, 0x02, 0xa8, 0x1b, 0x02, 0x03, 0xb0, 0x1b, 0x02, 0x03, 0xb8, 0x1b, 0x02, 0x03, 0xc0, 0x1b, 0x02, 0x03, 0xc8, 0x1b, 0x02, 0x03, + 0x40, 0x3f, 0x03, 0x04, 0x50, 0x3f, 0x03, 0x04, 0x60, 0x3f, 0x03, 0x04, 0x60, 0x18, 0x04, 0x04, 0x70, 0x18, 0x04, 0x04, 0x80, 0x3a, 0x05, 0x05, 0x80, 0x15, 0x06, 0x05, 0x40, 0x37, 0x07, 0x06, + 0x00, 0x35, 0x09, 0x07, 0x90, 0x0e, 0x00, 0x03, 0x98, 0x0e, 0x00, 0x03, 0xa0, 0x0e, 0x00, 0x03, 0xa8, 0x0e, 0x00, 0x03, 0xe4, 0x01, 0x01, 0x02, 0xe8, 0x01, 0x01, 0x02, 0xec, 0x01, 0x01, 0x02, + 0xf0, 0x01, 0x01, 0x02, 0xf4, 0x01, 0x01, 0x02, 0xf8, 0x01, 0x01, 0x02, 0xd0, 0x1b, 0x02, 0x03, 0xd8, 0x1b, 0x02, 0x03, 0xe0, 0x1b, 0x02, 0x03, 0xe8, 0x1b, 0x02, 0x03, 0xf0, 0x1b, 0x02, 0x03, + 0x70, 0x3f, 0x03, 0x04, 0x80, 0x3f, 0x03, 0x04, 0x90, 0x3f, 0x03, 0x04, 0x80, 0x18, 0x04, 0x04, 0x90, 0x18, 0x04, 0x04, 0xa0, 0x3a, 0x05, 0x05, 0xa0, 0x15, 0x06, 0x05, 0x80, 0x37, 0x07, 0x06, + 0x80, 0x35, 0x09, 0x07, 0xb0, 0x0e, 0x00, 0x03, 0xb8, 0x0e, 0x00, 0x03, 0xc0, 0x0e, 0x00, 0x03, 0xc8, 0x0e, 0x00, 0x03, 0xfc, 0x01, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02, + 0x08, 0x02, 0x01, 0x02, 0x0c, 0x02, 0x01, 0x02, 0x10, 0x02, 0x01, 0x02, 0xf8, 0x1b, 0x02, 0x03, 0x00, 0x1c, 0x02, 0x03, 0x08, 0x1c, 0x02, 0x03, 0x10, 0x1c, 0x02, 0x03, 0x18, 0x1c, 0x02, 0x03, + 0xa0, 0x3f, 0x03, 0x04, 0xb0, 0x3f, 0x03, 0x04, 0xc0, 0x3f, 0x03, 0x04, 0xa0, 0x18, 0x04, 0x04, 0xb0, 0x18, 0x04, 0x04, 0xc0, 0x3a, 0x05, 0x05, 0xc0, 0x15, 0x06, 0x05, 0xc0, 0x37, 0x07, 0x06, + 0x00, 0x36, 0x09, 0x07, 0xd0, 0x0e, 0x00, 0x03, 0xd8, 0x0e, 0x00, 0x03, 0xe0, 0x0e, 0x00, 0x03, 0xe8, 0x0e, 0x00, 0x03, 0x14, 0x02, 0x01, 0x02, 0x18, 0x02, 0x01, 0x02, 0x1c, 0x02, 0x01, 0x02, + 0x20, 0x02, 0x01, 0x02, 0x24, 0x02, 0x01, 0x02, 0x28, 0x02, 0x01, 0x02, 0x20, 0x1c, 0x02, 0x03, 0x28, 0x1c, 0x02, 0x03, 0x30, 0x1c, 0x02, 0x03, 0x38, 0x1c, 0x02, 0x03, 0x40, 0x1c, 0x02, 0x03, + 0xd0, 0x3f, 0x03, 0x04, 0xe0, 0x3f, 0x03, 0x04, 0xf0, 0x3f, 0x03, 0x04, 0xc0, 0x18, 0x04, 0x04, 0xd0, 0x18, 0x04, 0x04, 0xe0, 0x3a, 0x05, 0x05, 0xe0, 0x15, 0x06, 0x05, 0x00, 0x38, 0x07, 0x06, + 0x80, 0x36, 0x09, 0x07, 0xf0, 0x0e, 0x00, 0x03, 0xf8, 0x0e, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x08, 0x0f, 0x00, 0x03, 0x2c, 0x02, 0x01, 0x02, 0x30, 0x02, 0x01, 0x02, 0x34, 0x02, 0x01, 0x02, + 0x38, 0x02, 0x01, 0x02, 0x3c, 0x02, 0x01, 0x02, 0x40, 0x02, 0x01, 0x02, 0x48, 0x1c, 0x02, 0x03, 0x50, 0x1c, 0x02, 0x03, 0x58, 0x1c, 0x02, 0x03, 0x60, 0x1c, 0x02, 0x03, 0x68, 0x1c, 0x02, 0x03, + 0x00, 0x00, 0x03, 0x03, 0x08, 0x00, 0x03, 0x03, 0x10, 0x00, 0x03, 0x03, 0xe0, 0x18, 0x04, 0x04, 0xf0, 0x18, 0x04, 0x04, 0x00, 0x3b, 0x05, 0x05, 0x00, 0x16, 0x06, 0x05, 0x40, 0x38, 0x07, 0x06, + 0x00, 0x37, 0x09, 0x07, 0x10, 0x0f, 0x00, 0x03, 0x18, 0x0f, 0x00, 0x03, 0x20, 0x0f, 0x00, 0x03, 0x28, 0x0f, 0x00, 0x03, 0x44, 0x02, 0x01, 0x02, 0x48, 0x02, 0x01, 0x02, 0x4c, 0x02, 0x01, 0x02, + 0x50, 0x02, 0x01, 0x02, 0x54, 0x02, 0x01, 0x02, 0x58, 0x02, 0x01, 0x02, 0x70, 0x1c, 0x02, 0x03, 0x78, 0x1c, 0x02, 0x03, 0x80, 0x1c, 0x02, 0x03, 0x88, 0x1c, 0x02, 0x03, 0x90, 0x1c, 0x02, 0x03, + 0x18, 0x00, 0x03, 0x03, 0x20, 0x00, 0x03, 0x03, 0x28, 0x00, 0x03, 0x03, 0x00, 0x19, 0x04, 0x04, 0x10, 0x19, 0x04, 0x04, 0x20, 0x3b, 0x05, 0x05, 0x20, 0x16, 0x06, 0x05, 0x80, 0x38, 0x07, 0x06, + 0x80, 0x37, 0x09, 0x07, 0x30, 0x0f, 0x00, 0x03, 0x38, 0x0f, 0x00, 0x03, 0x40, 0x0f, 0x00, 0x03, 0x48, 0x0f, 0x00, 0x03, 0x5c, 0x02, 0x01, 0x02, 0x60, 0x02, 0x01, 0x02, 0x64, 0x02, 0x01, 0x02, + 0x68, 0x02, 0x01, 0x02, 0x6c, 0x02, 0x01, 0x02, 0x70, 0x02, 0x01, 0x02, 0x98, 0x1c, 0x02, 0x03, 0xa0, 0x1c, 0x02, 0x03, 0xa8, 0x1c, 0x02, 0x03, 0xb0, 0x1c, 0x02, 0x03, 0xb8, 0x1c, 0x02, 0x03, + 0x30, 0x00, 0x03, 0x03, 0x38, 0x00, 0x03, 0x03, 0x40, 0x00, 0x03, 0x03, 0x20, 0x19, 0x04, 0x04, 0x30, 0x19, 0x04, 0x04, 0x40, 0x3b, 0x05, 0x05, 0x40, 0x16, 0x06, 0x05, 0xc0, 0x38, 0x07, 0x06, + 0x00, 0x38, 0x09, 0x07, 0x50, 0x0f, 0x00, 0x03, 0x58, 0x0f, 0x00, 0x03, 0x60, 0x0f, 0x00, 0x03, 0x68, 0x0f, 0x00, 0x03, 0x74, 0x02, 0x01, 0x02, 0x78, 0x02, 0x01, 0x02, 0x7c, 0x02, 0x01, 0x02, + 0x80, 0x02, 0x01, 0x02, 0x84, 0x02, 0x01, 0x02, 0x88, 0x02, 0x01, 0x02, 0xc0, 0x1c, 0x02, 0x03, 0xc8, 0x1c, 0x02, 0x03, 0xd0, 0x1c, 0x02, 0x03, 0xd8, 0x1c, 0x02, 0x03, 0xe0, 0x1c, 0x02, 0x03, + 0x48, 0x00, 0x03, 0x03, 0x50, 0x00, 0x03, 0x03, 0x58, 0x00, 0x03, 0x03, 0x40, 0x19, 0x04, 0x04, 0x50, 0x19, 0x04, 0x04, 0x60, 0x3b, 0x05, 0x05, 0x60, 0x16, 0x06, 0x05, 0x00, 0x39, 0x07, 0x06, + 0x80, 0x38, 0x09, 0x07, 0x70, 0x0f, 0x00, 0x03, 0x78, 0x0f, 0x00, 0x03, 0x80, 0x0f, 0x00, 0x03, 0x88, 0x0f, 0x00, 0x03, 0x8c, 0x02, 0x01, 0x02, 0x90, 0x02, 0x01, 0x02, 0x94, 0x02, 0x01, 0x02, + 0x98, 0x02, 0x01, 0x02, 0x9c, 0x02, 0x01, 0x02, 0xa0, 0x02, 0x01, 0x02, 0xe8, 0x1c, 0x02, 0x03, 0xf0, 0x1c, 0x02, 0x03, 0xf8, 0x1c, 0x02, 0x03, 0x00, 0x1d, 0x02, 0x03, 0x60, 0x00, 0x03, 0x03, + 0x68, 0x00, 0x03, 0x03, 0x70, 0x00, 0x03, 0x03, 0x60, 0x19, 0x04, 0x04, 0x70, 0x19, 0x04, 0x04, 0x80, 0x19, 0x04, 0x04, 0x80, 0x3b, 0x05, 0x05, 0x80, 0x16, 0x06, 0x05, 0x40, 0x39, 0x07, 0x06, + 0x00, 0x39, 0x09, 0x07, 0x90, 0x0f, 0x00, 0x03, 0x98, 0x0f, 0x00, 0x03, 0xa0, 0x0f, 0x00, 0x03, 0xa8, 0x0f, 0x00, 0x03, 0xa4, 0x02, 0x01, 0x02, 0xa8, 0x02, 0x01, 0x02, 0xac, 0x02, 0x01, 0x02, + 0xb0, 0x02, 0x01, 0x02, 0xb4, 0x02, 0x01, 0x02, 0xb8, 0x02, 0x01, 0x02, 0x08, 0x1d, 0x02, 0x03, 0x10, 0x1d, 0x02, 0x03, 0x18, 0x1d, 0x02, 0x03, 0x20, 0x1d, 0x02, 0x03, 0x78, 0x00, 0x03, 0x03, + 0x80, 0x00, 0x03, 0x03, 0x88, 0x00, 0x03, 0x03, 0x90, 0x19, 0x04, 0x04, 0xa0, 0x19, 0x04, 0x04, 0xb0, 0x19, 0x04, 0x04, 0xa0, 0x3b, 0x05, 0x05, 0xa0, 0x16, 0x06, 0x05, 0x80, 0x39, 0x07, 0x06, + 0x80, 0x39, 0x09, 0x07, 0xb0, 0x0f, 0x00, 0x03, 0xb8, 0x0f, 0x00, 0x03, 0xc0, 0x0f, 0x00, 0x03, 0xc8, 0x0f, 0x00, 0x03, 0xbc, 0x02, 0x01, 0x02, 0xc0, 0x02, 0x01, 0x02, 0xc4, 0x02, 0x01, 0x02, + 0xc8, 0x02, 0x01, 0x02, 0xcc, 0x02, 0x01, 0x02, 0xd0, 0x02, 0x01, 0x02, 0x28, 0x1d, 0x02, 0x03, 0x30, 0x1d, 0x02, 0x03, 0x38, 0x1d, 0x02, 0x03, 0x40, 0x1d, 0x02, 0x03, 0x90, 0x00, 0x03, 0x03, + 0x98, 0x00, 0x03, 0x03, 0xa0, 0x00, 0x03, 0x03, 0xc0, 0x19, 0x04, 0x04, 0xd0, 0x19, 0x04, 0x04, 0xe0, 0x19, 0x04, 0x04, 0xc0, 0x3b, 0x05, 0x05, 0xc0, 0x16, 0x06, 0x05, 0xc0, 0x39, 0x07, 0x06, + 0x00, 0x3a, 0x09, 0x07, 0xd0, 0x0f, 0x00, 0x03, 0xd8, 0x0f, 0x00, 0x03, 0xe0, 0x0f, 0x00, 0x03, 0xe8, 0x0f, 0x00, 0x03, 0xd4, 0x02, 0x01, 0x02, 0xd8, 0x02, 0x01, 0x02, 0xdc, 0x02, 0x01, 0x02, + 0xe0, 0x02, 0x01, 0x02, 0xe4, 0x02, 0x01, 0x02, 0xe8, 0x02, 0x01, 0x02, 0x48, 0x1d, 0x02, 0x03, 0x50, 0x1d, 0x02, 0x03, 0x58, 0x1d, 0x02, 0x03, 0x60, 0x1d, 0x02, 0x03, 0xa8, 0x00, 0x03, 0x03, + 0xb0, 0x00, 0x03, 0x03, 0xb8, 0x00, 0x03, 0x03, 0xf0, 0x19, 0x04, 0x04, 0x00, 0x1a, 0x04, 0x04, 0x10, 0x1a, 0x04, 0x04, 0xe0, 0x3b, 0x05, 0x05, 0xe0, 0x16, 0x06, 0x05, 0x00, 0x3a, 0x07, 0x06, + 0x80, 0x3a, 0x09, 0x07, 0xf0, 0x0f, 0x00, 0x03, 0xf8, 0x0f, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x08, 0x10, 0x00, 0x03, 0xec, 0x02, 0x01, 0x02, 0xf0, 0x02, 0x01, 0x02, 0xf4, 0x02, 0x01, 0x02, + 0xf8, 0x02, 0x01, 0x02, 0xfc, 0x02, 0x01, 0x02, 0x00, 0x03, 0x01, 0x02, 0x68, 0x1d, 0x02, 0x03, 0x70, 0x1d, 0x02, 0x03, 0x78, 0x1d, 0x02, 0x03, 0x80, 0x1d, 0x02, 0x03, 0xc0, 0x00, 0x03, 0x03, + 0xc8, 0x00, 0x03, 0x03, 0xd0, 0x00, 0x03, 0x03, 0x20, 0x1a, 0x04, 0x04, 0x30, 0x1a, 0x04, 0x04, 0x40, 0x1a, 0x04, 0x04, 0x00, 0x3c, 0x05, 0x05, 0x00, 0x17, 0x06, 0x05, 0x40, 0x3a, 0x07, 0x06, + 0x00, 0x0f, 0x0a, 0x07, 0x10, 0x10, 0x00, 0x03, 0x18, 0x10, 0x00, 0x03, 0x20, 0x10, 0x00, 0x03, 0x28, 0x10, 0x00, 0x03, 0x04, 0x03, 0x01, 0x02, 0x08, 0x03, 0x01, 0x02, 0x0c, 0x03, 0x01, 0x02, + 0x10, 0x03, 0x01, 0x02, 0x14, 0x03, 0x01, 0x02, 0x18, 0x03, 0x01, 0x02, 0x88, 0x1d, 0x02, 0x03, 0x90, 0x1d, 0x02, 0x03, 0x98, 0x1d, 0x02, 0x03, 0xa0, 0x1d, 0x02, 0x03, 0xd8, 0x00, 0x03, 0x03, + 0xe0, 0x00, 0x03, 0x03, 0xe8, 0x00, 0x03, 0x03, 0x50, 0x1a, 0x04, 0x04, 0x60, 0x1a, 0x04, 0x04, 0x70, 0x1a, 0x04, 0x04, 0x20, 0x3c, 0x05, 0x05, 0x20, 0x17, 0x06, 0x05, 0x80, 0x3a, 0x07, 0x06, + 0x80, 0x0f, 0x0a, 0x07, 0x30, 0x10, 0x00, 0x03, 0x38, 0x10, 0x00, 0x03, 0x40, 0x10, 0x00, 0x03, 0x48, 0x10, 0x00, 0x03, 0x1c, 0x03, 0x01, 0x02, 0x20, 0x03, 0x01, 0x02, 0x24, 0x03, 0x01, 0x02, + 0x28, 0x03, 0x01, 0x02, 0x2c, 0x03, 0x01, 0x02, 0x30, 0x03, 0x01, 0x02, 0xa8, 0x1d, 0x02, 0x03, 0xb0, 0x1d, 0x02, 0x03, 0xb8, 0x1d, 0x02, 0x03, 0xc0, 0x1d, 0x02, 0x03, 0xf0, 0x00, 0x03, 0x03, + 0xf8, 0x00, 0x03, 0x03, 0x00, 0x01, 0x03, 0x03, 0x80, 0x1a, 0x04, 0x04, 0x90, 0x1a, 0x04, 0x04, 0xa0, 0x1a, 0x04, 0x04, 0x40, 0x3c, 0x05, 0x05, 0x40, 0x17, 0x06, 0x05, 0xc0, 0x3a, 0x07, 0x06, + 0x00, 0x10, 0x0a, 0x07, 0x50, 0x10, 0x00, 0x03, 0x58, 0x10, 0x00, 0x03, 0x60, 0x10, 0x00, 0x03, 0x68, 0x10, 0x00, 0x03, 0x34, 0x03, 0x01, 0x02, 0x38, 0x03, 0x01, 0x02, 0x3c, 0x03, 0x01, 0x02, + 0x40, 0x03, 0x01, 0x02, 0x44, 0x03, 0x01, 0x02, 0x48, 0x03, 0x01, 0x02, 0xc8, 0x1d, 0x02, 0x03, 0xd0, 0x1d, 0x02, 0x03, 0xd8, 0x1d, 0x02, 0x03, 0xe0, 0x1d, 0x02, 0x03, 0x08, 0x01, 0x03, 0x03, + 0x10, 0x01, 0x03, 0x03, 0x18, 0x01, 0x03, 0x03, 0xb0, 0x1a, 0x04, 0x04, 0xc0, 0x1a, 0x04, 0x04, 0x60, 0x3c, 0x05, 0x05, 0x80, 0x3c, 0x05, 0x05, 0x60, 0x17, 0x06, 0x05, 0x00, 0x3b, 0x07, 0x06, + 0x80, 0x10, 0x0a, 0x07, 0x70, 0x10, 0x00, 0x03, 0x78, 0x10, 0x00, 0x03, 0x80, 0x10, 0x00, 0x03, 0x88, 0x10, 0x00, 0x03, 0x4c, 0x03, 0x01, 0x02, 0x50, 0x03, 0x01, 0x02, 0x54, 0x03, 0x01, 0x02, + 0x58, 0x03, 0x01, 0x02, 0x5c, 0x03, 0x01, 0x02, 0x60, 0x03, 0x01, 0x02, 0xe8, 0x1d, 0x02, 0x03, 0xf0, 0x1d, 0x02, 0x03, 0xf8, 0x1d, 0x02, 0x03, 0x00, 0x1e, 0x02, 0x03, 0x20, 0x01, 0x03, 0x03, + 0x28, 0x01, 0x03, 0x03, 0x30, 0x01, 0x03, 0x03, 0xd0, 0x1a, 0x04, 0x04, 0xe0, 0x1a, 0x04, 0x04, 0xa0, 0x3c, 0x05, 0x05, 0xc0, 0x3c, 0x05, 0x05, 0x80, 0x17, 0x06, 0x05, 0x40, 0x3b, 0x07, 0x06, + 0x00, 0x11, 0x0a, 0x07, 0x90, 0x10, 0x00, 0x03, 0x98, 0x10, 0x00, 0x03, 0xa0, 0x10, 0x00, 0x03, 0xa8, 0x10, 0x00, 0x03, 0x64, 0x03, 0x01, 0x02, 0x68, 0x03, 0x01, 0x02, 0x6c, 0x03, 0x01, 0x02, + 0x70, 0x03, 0x01, 0x02, 0x74, 0x03, 0x01, 0x02, 0x78, 0x03, 0x01, 0x02, 0x08, 0x1e, 0x02, 0x03, 0x10, 0x1e, 0x02, 0x03, 0x18, 0x1e, 0x02, 0x03, 0x20, 0x1e, 0x02, 0x03, 0x38, 0x01, 0x03, 0x03, + 0x40, 0x01, 0x03, 0x03, 0x48, 0x01, 0x03, 0x03, 0xf0, 0x1a, 0x04, 0x04, 0x00, 0x1b, 0x04, 0x04, 0xe0, 0x3c, 0x05, 0x05, 0x00, 0x3d, 0x05, 0x05, 0xa0, 0x17, 0x06, 0x05, 0x80, 0x3b, 0x07, 0x06, + 0x80, 0x11, 0x0a, 0x07, 0xb0, 0x10, 0x00, 0x03, 0xb8, 0x10, 0x00, 0x03, 0xc0, 0x10, 0x00, 0x03, 0xc8, 0x10, 0x00, 0x03, 0x7c, 0x03, 0x01, 0x02, 0x80, 0x03, 0x01, 0x02, 0x84, 0x03, 0x01, 0x02, + 0x88, 0x03, 0x01, 0x02, 0x8c, 0x03, 0x01, 0x02, 0x90, 0x03, 0x01, 0x02, 0x28, 0x1e, 0x02, 0x03, 0x30, 0x1e, 0x02, 0x03, 0x38, 0x1e, 0x02, 0x03, 0x40, 0x1e, 0x02, 0x03, 0x50, 0x01, 0x03, 0x03, + 0x58, 0x01, 0x03, 0x03, 0x60, 0x01, 0x03, 0x03, 0x10, 0x1b, 0x04, 0x04, 0x20, 0x1b, 0x04, 0x04, 0x20, 0x3d, 0x05, 0x05, 0x40, 0x3d, 0x05, 0x05, 0xc0, 0x17, 0x06, 0x05, 0xc0, 0x3b, 0x07, 0x06, + 0x00, 0x12, 0x0a, 0x07, 0xd0, 0x10, 0x00, 0x03, 0xd8, 0x10, 0x00, 0x03, 0xe0, 0x10, 0x00, 0x03, 0xe8, 0x10, 0x00, 0x03, 0x94, 0x03, 0x01, 0x02, 0x98, 0x03, 0x01, 0x02, 0x9c, 0x03, 0x01, 0x02, + 0xa0, 0x03, 0x01, 0x02, 0xa4, 0x03, 0x01, 0x02, 0xa8, 0x03, 0x01, 0x02, 0x48, 0x1e, 0x02, 0x03, 0x50, 0x1e, 0x02, 0x03, 0x58, 0x1e, 0x02, 0x03, 0x60, 0x1e, 0x02, 0x03, 0x68, 0x01, 0x03, 0x03, + 0x70, 0x01, 0x03, 0x03, 0x78, 0x01, 0x03, 0x03, 0x30, 0x1b, 0x04, 0x04, 0x40, 0x1b, 0x04, 0x04, 0x60, 0x3d, 0x05, 0x05, 0x80, 0x3d, 0x05, 0x05, 0xe0, 0x17, 0x06, 0x05, 0x00, 0x3c, 0x07, 0x06, + 0x80, 0x12, 0x0a, 0x07, 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x10, 0x00, 0x03, 0x00, 0x11, 0x00, 0x03, 0x08, 0x11, 0x00, 0x03, 0xac, 0x03, 0x01, 0x02, 0xb0, 0x03, 0x01, 0x02, 0xb4, 0x03, 0x01, 0x02, + 0xb8, 0x03, 0x01, 0x02, 0xbc, 0x03, 0x01, 0x02, 0xc0, 0x03, 0x01, 0x02, 0x68, 0x1e, 0x02, 0x03, 0x70, 0x1e, 0x02, 0x03, 0x78, 0x1e, 0x02, 0x03, 0x80, 0x1e, 0x02, 0x03, 0x80, 0x01, 0x03, 0x03, + 0x88, 0x01, 0x03, 0x03, 0x90, 0x01, 0x03, 0x03, 0x50, 0x1b, 0x04, 0x04, 0x60, 0x1b, 0x04, 0x04, 0xa0, 0x3d, 0x05, 0x05, 0xc0, 0x3d, 0x05, 0x05, 0x00, 0x18, 0x06, 0x05, 0x40, 0x3c, 0x07, 0x06, + 0x00, 0x13, 0x0a, 0x07, 0x10, 0x11, 0x00, 0x03, 0x18, 0x11, 0x00, 0x03, 0x20, 0x11, 0x00, 0x03, 0x28, 0x11, 0x00, 0x03, 0xc4, 0x03, 0x01, 0x02, 0xc8, 0x03, 0x01, 0x02, 0xcc, 0x03, 0x01, 0x02, + 0xd0, 0x03, 0x01, 0x02, 0xd4, 0x03, 0x01, 0x02, 0xd8, 0x03, 0x01, 0x02, 0x88, 0x1e, 0x02, 0x03, 0x90, 0x1e, 0x02, 0x03, 0x98, 0x1e, 0x02, 0x03, 0xa0, 0x1e, 0x02, 0x03, 0x98, 0x01, 0x03, 0x03, + 0xa0, 0x01, 0x03, 0x03, 0xa8, 0x01, 0x03, 0x03, 0x70, 0x1b, 0x04, 0x04, 0x80, 0x1b, 0x04, 0x04, 0xe0, 0x3d, 0x05, 0x05, 0x00, 0x3e, 0x05, 0x05, 0x20, 0x18, 0x06, 0x05, 0x80, 0x3c, 0x07, 0x06, + 0x80, 0x13, 0x0a, 0x07, 0x30, 0x11, 0x00, 0x03, 0x38, 0x11, 0x00, 0x03, 0x40, 0x11, 0x00, 0x03, 0x48, 0x11, 0x00, 0x03, 0xdc, 0x03, 0x01, 0x02, 0xe0, 0x03, 0x01, 0x02, 0xe4, 0x03, 0x01, 0x02, + 0xe8, 0x03, 0x01, 0x02, 0xec, 0x03, 0x01, 0x02, 0xf0, 0x03, 0x01, 0x02, 0xa8, 0x1e, 0x02, 0x03, 0xb0, 0x1e, 0x02, 0x03, 0xb8, 0x1e, 0x02, 0x03, 0xc0, 0x1e, 0x02, 0x03, 0xb0, 0x01, 0x03, 0x03, + 0xb8, 0x01, 0x03, 0x03, 0xc0, 0x01, 0x03, 0x03, 0x90, 0x1b, 0x04, 0x04, 0xa0, 0x1b, 0x04, 0x04, 0x20, 0x3e, 0x05, 0x05, 0x40, 0x3e, 0x05, 0x05, 0x40, 0x18, 0x06, 0x05, 0xc0, 0x3c, 0x07, 0x06, + 0x00, 0x14, 0x0a, 0x07, 0x50, 0x11, 0x00, 0x03, 0x58, 0x11, 0x00, 0x03, 0x60, 0x11, 0x00, 0x03, 0x68, 0x11, 0x00, 0x03, 0xf4, 0x03, 0x01, 0x02, 0xf8, 0x03, 0x01, 0x02, 0xfc, 0x03, 0x01, 0x02, + 0x00, 0x04, 0x01, 0x02, 0x04, 0x04, 0x01, 0x02, 0x08, 0x04, 0x01, 0x02, 0xc8, 0x1e, 0x02, 0x03, 0xd0, 0x1e, 0x02, 0x03, 0xd8, 0x1e, 0x02, 0x03, 0xe0, 0x1e, 0x02, 0x03, 0xc8, 0x01, 0x03, 0x03, + 0xd0, 0x01, 0x03, 0x03, 0xd8, 0x01, 0x03, 0x03, 0xb0, 0x1b, 0x04, 0x04, 0xc0, 0x1b, 0x04, 0x04, 0x60, 0x3e, 0x05, 0x05, 0x80, 0x3e, 0x05, 0x05, 0x60, 0x18, 0x06, 0x05, 0x00, 0x3d, 0x07, 0x06, + 0x80, 0x14, 0x0a, 0x07, 0x70, 0x11, 0x00, 0x03, 0x78, 0x11, 0x00, 0x03, 0x80, 0x11, 0x00, 0x03, 0x88, 0x11, 0x00, 0x03, 0x0c, 0x04, 0x01, 0x02, 0x10, 0x04, 0x01, 0x02, 0x14, 0x04, 0x01, 0x02, + 0x18, 0x04, 0x01, 0x02, 0x1c, 0x04, 0x01, 0x02, 0x20, 0x04, 0x01, 0x02, 0xe8, 0x1e, 0x02, 0x03, 0xf0, 0x1e, 0x02, 0x03, 0xf8, 0x1e, 0x02, 0x03, 0x00, 0x1f, 0x02, 0x03, 0xe0, 0x01, 0x03, 0x03, + 0xe8, 0x01, 0x03, 0x03, 0xf0, 0x01, 0x03, 0x03, 0xd0, 0x1b, 0x04, 0x04, 0xe0, 0x1b, 0x04, 0x04, 0xa0, 0x3e, 0x05, 0x05, 0xc0, 0x3e, 0x05, 0x05, 0x80, 0x18, 0x06, 0x05, 0x40, 0x3d, 0x07, 0x06, + 0x00, 0x15, 0x0a, 0x07, 0x90, 0x11, 0x00, 0x03, 0x98, 0x11, 0x00, 0x03, 0xa0, 0x11, 0x00, 0x03, 0xa8, 0x11, 0x00, 0x03, 0x24, 0x04, 0x01, 0x02, 0x28, 0x04, 0x01, 0x02, 0x2c, 0x04, 0x01, 0x02, + 0x30, 0x04, 0x01, 0x02, 0x34, 0x04, 0x01, 0x02, 0x38, 0x04, 0x01, 0x02, 0x08, 0x1f, 0x02, 0x03, 0x10, 0x1f, 0x02, 0x03, 0x18, 0x1f, 0x02, 0x03, 0x20, 0x1f, 0x02, 0x03, 0xf8, 0x01, 0x03, 0x03, + 0x00, 0x02, 0x03, 0x03, 0x08, 0x02, 0x03, 0x03, 0xf0, 0x1b, 0x04, 0x04, 0x00, 0x1c, 0x04, 0x04, 0xe0, 0x3e, 0x05, 0x05, 0x00, 0x3f, 0x05, 0x05, 0xa0, 0x18, 0x06, 0x05, 0x80, 0x3d, 0x07, 0x06, + 0x80, 0x15, 0x0a, 0x07, 0xb0, 0x11, 0x00, 0x03, 0xb8, 0x11, 0x00, 0x03, 0xc0, 0x11, 0x00, 0x03, 0xc8, 0x11, 0x00, 0x03, 0x3c, 0x04, 0x01, 0x02, 0x40, 0x04, 0x01, 0x02, 0x44, 0x04, 0x01, 0x02, + 0x48, 0x04, 0x01, 0x02, 0x4c, 0x04, 0x01, 0x02, 0x50, 0x04, 0x01, 0x02, 0x28, 0x1f, 0x02, 0x03, 0x30, 0x1f, 0x02, 0x03, 0x38, 0x1f, 0x02, 0x03, 0x40, 0x1f, 0x02, 0x03, 0x10, 0x02, 0x03, 0x03, + 0x18, 0x02, 0x03, 0x03, 0x20, 0x02, 0x03, 0x03, 0x10, 0x1c, 0x04, 0x04, 0x20, 0x1c, 0x04, 0x04, 0x20, 0x3f, 0x05, 0x05, 0x40, 0x3f, 0x05, 0x05, 0xc0, 0x18, 0x06, 0x05, 0xc0, 0x3d, 0x07, 0x06, + 0x00, 0x16, 0x0a, 0x07, 0xd0, 0x11, 0x00, 0x03, 0xd8, 0x11, 0x00, 0x03, 0xe0, 0x11, 0x00, 0x03, 0xe8, 0x11, 0x00, 0x03, 0x54, 0x04, 0x01, 0x02, 0x58, 0x04, 0x01, 0x02, 0x5c, 0x04, 0x01, 0x02, + 0x60, 0x04, 0x01, 0x02, 0x64, 0x04, 0x01, 0x02, 0x68, 0x04, 0x01, 0x02, 0x48, 0x1f, 0x02, 0x03, 0x50, 0x1f, 0x02, 0x03, 0x58, 0x1f, 0x02, 0x03, 0x60, 0x1f, 0x02, 0x03, 0x28, 0x02, 0x03, 0x03, + 0x30, 0x02, 0x03, 0x03, 0x38, 0x02, 0x03, 0x03, 0x30, 0x1c, 0x04, 0x04, 0x40, 0x1c, 0x04, 0x04, 0x60, 0x3f, 0x05, 0x05, 0x80, 0x3f, 0x05, 0x05, 0xe0, 0x18, 0x06, 0x05, 0xc0, 0x11, 0x08, 0x06, + 0x80, 0x16, 0x0a, 0x07, 0xf0, 0x11, 0x00, 0x03, 0xf8, 0x11, 0x00, 0x03, 0x00, 0x12, 0x00, 0x03, 0x08, 0x12, 0x00, 0x03, 0x6c, 0x04, 0x01, 0x02, 0x70, 0x04, 0x01, 0x02, 0x74, 0x04, 0x01, 0x02, + 0x78, 0x04, 0x01, 0x02, 0x7c, 0x04, 0x01, 0x02, 0x80, 0x04, 0x01, 0x02, 0x68, 0x1f, 0x02, 0x03, 0x70, 0x1f, 0x02, 0x03, 0x78, 0x1f, 0x02, 0x03, 0x80, 0x1f, 0x02, 0x03, 0x40, 0x02, 0x03, 0x03, + 0x48, 0x02, 0x03, 0x03, 0x50, 0x02, 0x03, 0x03, 0x50, 0x1c, 0x04, 0x04, 0x60, 0x1c, 0x04, 0x04, 0xa0, 0x3f, 0x05, 0x05, 0xc0, 0x3f, 0x05, 0x05, 0x00, 0x19, 0x06, 0x05, 0x00, 0x12, 0x08, 0x06, + 0x00, 0x17, 0x0a, 0x07, 0x10, 0x12, 0x00, 0x03, 0x18, 0x12, 0x00, 0x03, 0x20, 0x12, 0x00, 0x03, 0x28, 0x12, 0x00, 0x03, 0x84, 0x04, 0x01, 0x02, 0x88, 0x04, 0x01, 0x02, 0x8c, 0x04, 0x01, 0x02, + 0x90, 0x04, 0x01, 0x02, 0x94, 0x04, 0x01, 0x02, 0x98, 0x04, 0x01, 0x02, 0x88, 0x1f, 0x02, 0x03, 0x90, 0x1f, 0x02, 0x03, 0x98, 0x1f, 0x02, 0x03, 0xa0, 0x1f, 0x02, 0x03, 0x58, 0x02, 0x03, 0x03, + 0x60, 0x02, 0x03, 0x03, 0x68, 0x02, 0x03, 0x03, 0x70, 0x1c, 0x04, 0x04, 0x80, 0x1c, 0x04, 0x04, 0xe0, 0x3f, 0x05, 0x05, 0x00, 0x00, 0x05, 0x04, 0x20, 0x19, 0x06, 0x05, 0x40, 0x12, 0x08, 0x06, + 0x80, 0x17, 0x0a, 0x07, 0x30, 0x12, 0x00, 0x03, 0x38, 0x12, 0x00, 0x03, 0x40, 0x12, 0x00, 0x03, 0x48, 0x12, 0x00, 0x03, 0x9c, 0x04, 0x01, 0x02, 0xa0, 0x04, 0x01, 0x02, 0xa4, 0x04, 0x01, 0x02, + 0xa8, 0x04, 0x01, 0x02, 0xac, 0x04, 0x01, 0x02, 0xb0, 0x04, 0x01, 0x02, 0xa8, 0x1f, 0x02, 0x03, 0xb0, 0x1f, 0x02, 0x03, 0xb8, 0x1f, 0x02, 0x03, 0xc0, 0x1f, 0x02, 0x03, 0x70, 0x02, 0x03, 0x03, + 0x78, 0x02, 0x03, 0x03, 0x80, 0x02, 0x03, 0x03, 0x90, 0x1c, 0x04, 0x04, 0xa0, 0x1c, 0x04, 0x04, 0x10, 0x00, 0x05, 0x04, 0x20, 0x00, 0x05, 0x04, 0x40, 0x19, 0x06, 0x05, 0x80, 0x12, 0x08, 0x06, + 0x00, 0x18, 0x0a, 0x07, 0x50, 0x12, 0x00, 0x03, 0x58, 0x12, 0x00, 0x03, 0x60, 0x12, 0x00, 0x03, 0x68, 0x12, 0x00, 0x03, 0xb4, 0x04, 0x01, 0x02, 0xb8, 0x04, 0x01, 0x02, 0xbc, 0x04, 0x01, 0x02, + 0xc0, 0x04, 0x01, 0x02, 0xc4, 0x04, 0x01, 0x02, 0xc8, 0x04, 0x01, 0x02, 0xc8, 0x1f, 0x02, 0x03, 0xd0, 0x1f, 0x02, 0x03, 0xd8, 0x1f, 0x02, 0x03, 0xe0, 0x1f, 0x02, 0x03, 0x88, 0x02, 0x03, 0x03, + 0x90, 0x02, 0x03, 0x03, 0x98, 0x02, 0x03, 0x03, 0xb0, 0x1c, 0x04, 0x04, 0xc0, 0x1c, 0x04, 0x04, 0x30, 0x00, 0x05, 0x04, 0x40, 0x00, 0x05, 0x04, 0x60, 0x19, 0x06, 0x05, 0xc0, 0x12, 0x08, 0x06, + 0x80, 0x18, 0x0a, 0x07, 0x70, 0x12, 0x00, 0x03, 0x78, 0x12, 0x00, 0x03, 0x80, 0x12, 0x00, 0x03, 0x88, 0x12, 0x00, 0x03, 0xcc, 0x04, 0x01, 0x02, 0xd0, 0x04, 0x01, 0x02, 0xd4, 0x04, 0x01, 0x02, + 0xd8, 0x04, 0x01, 0x02, 0xdc, 0x04, 0x01, 0x02, 0xe0, 0x04, 0x01, 0x02, 0xe8, 0x1f, 0x02, 0x03, 0xf0, 0x1f, 0x02, 0x03, 0xf8, 0x1f, 0x02, 0x03, 0x00, 0x20, 0x02, 0x03, 0xa0, 0x02, 0x03, 0x03, + 0xa8, 0x02, 0x03, 0x03, 0xb0, 0x02, 0x03, 0x03, 0xd0, 0x1c, 0x04, 0x04, 0xe0, 0x1c, 0x04, 0x04, 0x50, 0x00, 0x05, 0x04, 0x60, 0x00, 0x05, 0x04, 0x80, 0x19, 0x06, 0x05, 0x00, 0x13, 0x08, 0x06, + 0x00, 0x2e, 0x0b, 0x08, 0x90, 0x12, 0x00, 0x03, 0x98, 0x12, 0x00, 0x03, 0xa0, 0x12, 0x00, 0x03, 0xa8, 0x12, 0x00, 0x03, 0xe4, 0x04, 0x01, 0x02, 0xe8, 0x04, 0x01, 0x02, 0xec, 0x04, 0x01, 0x02, + 0xf0, 0x04, 0x01, 0x02, 0xf4, 0x04, 0x01, 0x02, 0xf8, 0x04, 0x01, 0x02, 0x08, 0x20, 0x02, 0x03, 0x10, 0x20, 0x02, 0x03, 0x18, 0x20, 0x02, 0x03, 0x20, 0x20, 0x02, 0x03, 0xb8, 0x02, 0x03, 0x03, + 0xc0, 0x02, 0x03, 0x03, 0xc8, 0x02, 0x03, 0x03, 0xf0, 0x1c, 0x04, 0x04, 0x00, 0x1d, 0x04, 0x04, 0x70, 0x00, 0x05, 0x04, 0x80, 0x00, 0x05, 0x04, 0xa0, 0x19, 0x06, 0x05, 0x40, 0x13, 0x08, 0x06, + 0x00, 0x2f, 0x0b, 0x08, 0xb0, 0x12, 0x00, 0x03, 0xb8, 0x12, 0x00, 0x03, 0xc0, 0x12, 0x00, 0x03, 0xc8, 0x12, 0x00, 0x03, 0xfc, 0x04, 0x01, 0x02, 0x00, 0x05, 0x01, 0x02, 0x04, 0x05, 0x01, 0x02, + 0x08, 0x05, 0x01, 0x02, 0x0c, 0x05, 0x01, 0x02, 0x10, 0x05, 0x01, 0x02, 0x28, 0x20, 0x02, 0x03, 0x30, 0x20, 0x02, 0x03, 0x38, 0x20, 0x02, 0x03, 0x40, 0x20, 0x02, 0x03, 0xd0, 0x02, 0x03, 0x03, + 0xd8, 0x02, 0x03, 0x03, 0xe0, 0x02, 0x03, 0x03, 0x10, 0x1d, 0x04, 0x04, 0x20, 0x1d, 0x04, 0x04, 0x90, 0x00, 0x05, 0x04, 0xa0, 0x00, 0x05, 0x04, 0xc0, 0x19, 0x06, 0x05, 0x80, 0x13, 0x08, 0x06, + 0x00, 0x30, 0x0b, 0x08, 0xd0, 0x12, 0x00, 0x03, 0xd8, 0x12, 0x00, 0x03, 0xe0, 0x12, 0x00, 0x03, 0xe8, 0x12, 0x00, 0x03, 0x14, 0x05, 0x01, 0x02, 0x18, 0x05, 0x01, 0x02, 0x1c, 0x05, 0x01, 0x02, + 0x20, 0x05, 0x01, 0x02, 0x24, 0x05, 0x01, 0x02, 0x28, 0x05, 0x01, 0x02, 0x48, 0x20, 0x02, 0x03, 0x50, 0x20, 0x02, 0x03, 0x58, 0x20, 0x02, 0x03, 0x60, 0x20, 0x02, 0x03, 0xe8, 0x02, 0x03, 0x03, + 0xf0, 0x02, 0x03, 0x03, 0xf8, 0x02, 0x03, 0x03, 0x30, 0x1d, 0x04, 0x04, 0x40, 0x1d, 0x04, 0x04, 0xb0, 0x00, 0x05, 0x04, 0xc0, 0x00, 0x05, 0x04, 0xe0, 0x19, 0x06, 0x05, 0xc0, 0x13, 0x08, 0x06, + 0x00, 0x31, 0x0b, 0x08, 0xf0, 0x12, 0x00, 0x03, 0xf8, 0x12, 0x00, 0x03, 0x00, 0x13, 0x00, 0x03, 0x08, 0x13, 0x00, 0x03, 0x2c, 0x05, 0x01, 0x02, 0x30, 0x05, 0x01, 0x02, 0x34, 0x05, 0x01, 0x02, + 0x38, 0x05, 0x01, 0x02, 0x3c, 0x05, 0x01, 0x02, 0x40, 0x05, 0x01, 0x02, 0x68, 0x20, 0x02, 0x03, 0x70, 0x20, 0x02, 0x03, 0x78, 0x20, 0x02, 0x03, 0x80, 0x20, 0x02, 0x03, 0x00, 0x03, 0x03, 0x03, + 0x08, 0x03, 0x03, 0x03, 0x10, 0x03, 0x03, 0x03, 0x50, 0x1d, 0x04, 0x04, 0x60, 0x1d, 0x04, 0x04, 0xd0, 0x00, 0x05, 0x04, 0xe0, 0x00, 0x05, 0x04, 0x00, 0x1a, 0x06, 0x05, 0x00, 0x14, 0x08, 0x06, + 0x00, 0x32, 0x0b, 0x08, 0x10, 0x13, 0x00, 0x03, 0x18, 0x13, 0x00, 0x03, 0x20, 0x13, 0x00, 0x03, 0x28, 0x13, 0x00, 0x03, 0x44, 0x05, 0x01, 0x02, 0x48, 0x05, 0x01, 0x02, 0x4c, 0x05, 0x01, 0x02, + 0x50, 0x05, 0x01, 0x02, 0x54, 0x05, 0x01, 0x02, 0x58, 0x05, 0x01, 0x02, 0x88, 0x20, 0x02, 0x03, 0x90, 0x20, 0x02, 0x03, 0x98, 0x20, 0x02, 0x03, 0xa0, 0x20, 0x02, 0x03, 0x18, 0x03, 0x03, 0x03, + 0x20, 0x03, 0x03, 0x03, 0x28, 0x03, 0x03, 0x03, 0x70, 0x1d, 0x04, 0x04, 0x80, 0x1d, 0x04, 0x04, 0xf0, 0x00, 0x05, 0x04, 0x00, 0x01, 0x05, 0x04, 0x20, 0x1a, 0x06, 0x05, 0x40, 0x14, 0x08, 0x06, + 0x00, 0x33, 0x0b, 0x08, 0x30, 0x13, 0x00, 0x03, 0x38, 0x13, 0x00, 0x03, 0x40, 0x13, 0x00, 0x03, 0x48, 0x13, 0x00, 0x03, 0x5c, 0x05, 0x01, 0x02, 0x60, 0x05, 0x01, 0x02, 0x64, 0x05, 0x01, 0x02, + 0x68, 0x05, 0x01, 0x02, 0x6c, 0x05, 0x01, 0x02, 0x70, 0x05, 0x01, 0x02, 0xa8, 0x20, 0x02, 0x03, 0xb0, 0x20, 0x02, 0x03, 0xb8, 0x20, 0x02, 0x03, 0xc0, 0x20, 0x02, 0x03, 0x30, 0x03, 0x03, 0x03, + 0x38, 0x03, 0x03, 0x03, 0x40, 0x03, 0x03, 0x03, 0x90, 0x1d, 0x04, 0x04, 0xa0, 0x1d, 0x04, 0x04, 0x10, 0x01, 0x05, 0x04, 0x20, 0x01, 0x05, 0x04, 0x40, 0x1a, 0x06, 0x05, 0x80, 0x14, 0x08, 0x06, + 0x00, 0x34, 0x0b, 0x08, 0x50, 0x13, 0x00, 0x03, 0x58, 0x13, 0x00, 0x03, 0x60, 0x13, 0x00, 0x03, 0x68, 0x13, 0x00, 0x03, 0x74, 0x05, 0x01, 0x02, 0x78, 0x05, 0x01, 0x02, 0x7c, 0x05, 0x01, 0x02, + 0x80, 0x05, 0x01, 0x02, 0x84, 0x05, 0x01, 0x02, 0x88, 0x05, 0x01, 0x02, 0xc8, 0x20, 0x02, 0x03, 0xd0, 0x20, 0x02, 0x03, 0xd8, 0x20, 0x02, 0x03, 0xe0, 0x20, 0x02, 0x03, 0x48, 0x03, 0x03, 0x03, + 0x50, 0x03, 0x03, 0x03, 0x58, 0x03, 0x03, 0x03, 0xb0, 0x1d, 0x04, 0x04, 0xc0, 0x1d, 0x04, 0x04, 0x30, 0x01, 0x05, 0x04, 0x40, 0x01, 0x05, 0x04, 0x60, 0x1a, 0x06, 0x05, 0xc0, 0x14, 0x08, 0x06, + 0x00, 0x35, 0x0b, 0x08, 0x70, 0x13, 0x00, 0x03, 0x78, 0x13, 0x00, 0x03, 0x80, 0x13, 0x00, 0x03, 0x88, 0x13, 0x00, 0x03, 0x8c, 0x05, 0x01, 0x02, 0x90, 0x05, 0x01, 0x02, 0x94, 0x05, 0x01, 0x02, + 0x98, 0x05, 0x01, 0x02, 0x9c, 0x05, 0x01, 0x02, 0xa0, 0x05, 0x01, 0x02, 0xe8, 0x20, 0x02, 0x03, 0xf0, 0x20, 0x02, 0x03, 0xf8, 0x20, 0x02, 0x03, 0x00, 0x21, 0x02, 0x03, 0x60, 0x03, 0x03, 0x03, + 0x68, 0x03, 0x03, 0x03, 0x70, 0x03, 0x03, 0x03, 0xd0, 0x1d, 0x04, 0x04, 0xe0, 0x1d, 0x04, 0x04, 0x50, 0x01, 0x05, 0x04, 0x60, 0x01, 0x05, 0x04, 0x80, 0x1a, 0x06, 0x05, 0x00, 0x15, 0x08, 0x06, + 0x00, 0x36, 0x0b, 0x08, 0x90, 0x13, 0x00, 0x03, 0x98, 0x13, 0x00, 0x03, 0xa0, 0x13, 0x00, 0x03, 0xa8, 0x13, 0x00, 0x03, 0xa4, 0x05, 0x01, 0x02, 0xa8, 0x05, 0x01, 0x02, 0xac, 0x05, 0x01, 0x02, + 0xb0, 0x05, 0x01, 0x02, 0xb4, 0x05, 0x01, 0x02, 0xb8, 0x05, 0x01, 0x02, 0x08, 0x21, 0x02, 0x03, 0x10, 0x21, 0x02, 0x03, 0x18, 0x21, 0x02, 0x03, 0x20, 0x21, 0x02, 0x03, 0x78, 0x03, 0x03, 0x03, + 0x80, 0x03, 0x03, 0x03, 0x88, 0x03, 0x03, 0x03, 0xf0, 0x1d, 0x04, 0x04, 0x00, 0x1e, 0x04, 0x04, 0x70, 0x01, 0x05, 0x04, 0x80, 0x01, 0x05, 0x04, 0xa0, 0x1a, 0x06, 0x05, 0x40, 0x15, 0x08, 0x06, + 0x00, 0x37, 0x0b, 0x08, 0xb0, 0x13, 0x00, 0x03, 0xb8, 0x13, 0x00, 0x03, 0xc0, 0x13, 0x00, 0x03, 0xc8, 0x13, 0x00, 0x03, 0xbc, 0x05, 0x01, 0x02, 0xc0, 0x05, 0x01, 0x02, 0xc4, 0x05, 0x01, 0x02, + 0xc8, 0x05, 0x01, 0x02, 0xcc, 0x05, 0x01, 0x02, 0xd0, 0x05, 0x01, 0x02, 0x28, 0x21, 0x02, 0x03, 0x30, 0x21, 0x02, 0x03, 0x38, 0x21, 0x02, 0x03, 0x40, 0x21, 0x02, 0x03, 0x90, 0x03, 0x03, 0x03, + 0x98, 0x03, 0x03, 0x03, 0xa0, 0x03, 0x03, 0x03, 0x10, 0x1e, 0x04, 0x04, 0x20, 0x1e, 0x04, 0x04, 0x90, 0x01, 0x05, 0x04, 0xa0, 0x01, 0x05, 0x04, 0xc0, 0x1a, 0x06, 0x05, 0x80, 0x15, 0x08, 0x06, + 0x00, 0x38, 0x0b, 0x08, 0xd0, 0x13, 0x00, 0x03, 0xd8, 0x13, 0x00, 0x03, 0xe0, 0x13, 0x00, 0x03, 0xe8, 0x13, 0x00, 0x03, 0xd4, 0x05, 0x01, 0x02, 0xd8, 0x05, 0x01, 0x02, 0xdc, 0x05, 0x01, 0x02, + 0xe0, 0x05, 0x01, 0x02, 0xe4, 0x05, 0x01, 0x02, 0xe8, 0x05, 0x01, 0x02, 0x48, 0x21, 0x02, 0x03, 0x50, 0x21, 0x02, 0x03, 0x58, 0x21, 0x02, 0x03, 0x60, 0x21, 0x02, 0x03, 0xa8, 0x03, 0x03, 0x03, + 0xb0, 0x03, 0x03, 0x03, 0xb8, 0x03, 0x03, 0x03, 0x30, 0x1e, 0x04, 0x04, 0x40, 0x1e, 0x04, 0x04, 0xb0, 0x01, 0x05, 0x04, 0xc0, 0x01, 0x05, 0x04, 0xe0, 0x1a, 0x06, 0x05, 0xc0, 0x15, 0x08, 0x06, + 0x00, 0x39, 0x0b, 0x08, 0xf0, 0x13, 0x00, 0x03, 0xf8, 0x13, 0x00, 0x03, 0x00, 0x14, 0x00, 0x03, 0x08, 0x14, 0x00, 0x03, 0xec, 0x05, 0x01, 0x02, 0xf0, 0x05, 0x01, 0x02, 0xf4, 0x05, 0x01, 0x02, + 0xf8, 0x05, 0x01, 0x02, 0xfc, 0x05, 0x01, 0x02, 0x00, 0x06, 0x01, 0x02, 0x68, 0x21, 0x02, 0x03, 0x70, 0x21, 0x02, 0x03, 0x78, 0x21, 0x02, 0x03, 0x80, 0x21, 0x02, 0x03, 0xc0, 0x03, 0x03, 0x03, + 0xc8, 0x03, 0x03, 0x03, 0xd0, 0x03, 0x03, 0x03, 0x50, 0x1e, 0x04, 0x04, 0x60, 0x1e, 0x04, 0x04, 0xd0, 0x01, 0x05, 0x04, 0xe0, 0x01, 0x05, 0x04, 0x00, 0x1b, 0x06, 0x05, 0x00, 0x16, 0x08, 0x06, + 0x00, 0x3a, 0x0b, 0x08, 0x10, 0x14, 0x00, 0x03, 0x18, 0x14, 0x00, 0x03, 0x20, 0x14, 0x00, 0x03, 0x28, 0x14, 0x00, 0x03, 0x04, 0x06, 0x01, 0x02, 0x08, 0x06, 0x01, 0x02, 0x0c, 0x06, 0x01, 0x02, + 0x10, 0x06, 0x01, 0x02, 0x14, 0x06, 0x01, 0x02, 0x18, 0x06, 0x01, 0x02, 0x88, 0x21, 0x02, 0x03, 0x90, 0x21, 0x02, 0x03, 0x98, 0x21, 0x02, 0x03, 0xa0, 0x21, 0x02, 0x03, 0xd8, 0x03, 0x03, 0x03, + 0xe0, 0x03, 0x03, 0x03, 0xe8, 0x03, 0x03, 0x03, 0x70, 0x1e, 0x04, 0x04, 0x80, 0x1e, 0x04, 0x04, 0xf0, 0x01, 0x05, 0x04, 0x00, 0x02, 0x05, 0x04, 0x20, 0x1b, 0x06, 0x05, 0x40, 0x16, 0x08, 0x06, + 0x00, 0x3b, 0x0b, 0x08, 0x30, 0x14, 0x00, 0x03, 0x38, 0x14, 0x00, 0x03, 0x40, 0x14, 0x00, 0x03, 0x48, 0x14, 0x00, 0x03, 0x1c, 0x06, 0x01, 0x02, 0x20, 0x06, 0x01, 0x02, 0x24, 0x06, 0x01, 0x02, + 0x28, 0x06, 0x01, 0x02, 0x2c, 0x06, 0x01, 0x02, 0x30, 0x06, 0x01, 0x02, 0xa8, 0x21, 0x02, 0x03, 0xb0, 0x21, 0x02, 0x03, 0xb8, 0x21, 0x02, 0x03, 0xc0, 0x21, 0x02, 0x03, 0xf0, 0x03, 0x03, 0x03, + 0xf8, 0x03, 0x03, 0x03, 0x00, 0x04, 0x03, 0x03, 0x90, 0x1e, 0x04, 0x04, 0xa0, 0x1e, 0x04, 0x04, 0x10, 0x02, 0x05, 0x04, 0x20, 0x02, 0x05, 0x04, 0x40, 0x1b, 0x06, 0x05, 0x80, 0x16, 0x08, 0x06, + 0x00, 0x0c, 0x0c, 0x08, 0x50, 0x14, 0x00, 0x03, 0x58, 0x14, 0x00, 0x03, 0x60, 0x14, 0x00, 0x03, 0x68, 0x14, 0x00, 0x03, 0x34, 0x06, 0x01, 0x02, 0x38, 0x06, 0x01, 0x02, 0x3c, 0x06, 0x01, 0x02, + 0x40, 0x06, 0x01, 0x02, 0x44, 0x06, 0x01, 0x02, 0x48, 0x06, 0x01, 0x02, 0xc8, 0x21, 0x02, 0x03, 0xd0, 0x21, 0x02, 0x03, 0xd8, 0x21, 0x02, 0x03, 0xe0, 0x21, 0x02, 0x03, 0x08, 0x04, 0x03, 0x03, + 0x10, 0x04, 0x03, 0x03, 0x18, 0x04, 0x03, 0x03, 0xb0, 0x1e, 0x04, 0x04, 0xc0, 0x1e, 0x04, 0x04, 0x30, 0x02, 0x05, 0x04, 0x40, 0x02, 0x05, 0x04, 0x60, 0x1b, 0x06, 0x05, 0xc0, 0x16, 0x08, 0x06, + 0x00, 0x0d, 0x0c, 0x08, 0x70, 0x14, 0x00, 0x03, 0x78, 0x14, 0x00, 0x03, 0x80, 0x14, 0x00, 0x03, 0x88, 0x14, 0x00, 0x03, 0x4c, 0x06, 0x01, 0x02, 0x50, 0x06, 0x01, 0x02, 0x54, 0x06, 0x01, 0x02, + 0x58, 0x06, 0x01, 0x02, 0x5c, 0x06, 0x01, 0x02, 0x60, 0x06, 0x01, 0x02, 0xe8, 0x21, 0x02, 0x03, 0xf0, 0x21, 0x02, 0x03, 0xf8, 0x21, 0x02, 0x03, 0x00, 0x22, 0x02, 0x03, 0x20, 0x04, 0x03, 0x03, + 0x28, 0x04, 0x03, 0x03, 0x30, 0x04, 0x03, 0x03, 0xd0, 0x1e, 0x04, 0x04, 0xe0, 0x1e, 0x04, 0x04, 0x50, 0x02, 0x05, 0x04, 0x60, 0x02, 0x05, 0x04, 0x80, 0x1b, 0x06, 0x05, 0x00, 0x17, 0x08, 0x06, + 0x00, 0x0e, 0x0c, 0x08, 0x90, 0x14, 0x00, 0x03, 0x98, 0x14, 0x00, 0x03, 0xa0, 0x14, 0x00, 0x03, 0xa8, 0x14, 0x00, 0x03, 0x64, 0x06, 0x01, 0x02, 0x68, 0x06, 0x01, 0x02, 0x6c, 0x06, 0x01, 0x02, + 0x70, 0x06, 0x01, 0x02, 0x74, 0x06, 0x01, 0x02, 0x78, 0x06, 0x01, 0x02, 0x08, 0x22, 0x02, 0x03, 0x10, 0x22, 0x02, 0x03, 0x18, 0x22, 0x02, 0x03, 0x20, 0x22, 0x02, 0x03, 0x38, 0x04, 0x03, 0x03, + 0x40, 0x04, 0x03, 0x03, 0x48, 0x04, 0x03, 0x03, 0xf0, 0x1e, 0x04, 0x04, 0x00, 0x1f, 0x04, 0x04, 0x70, 0x02, 0x05, 0x04, 0x80, 0x02, 0x05, 0x04, 0xa0, 0x1b, 0x06, 0x05, 0x40, 0x17, 0x08, 0x06, + 0x00, 0x0f, 0x0c, 0x08, 0xb0, 0x14, 0x00, 0x03, 0xb8, 0x14, 0x00, 0x03, 0xc0, 0x14, 0x00, 0x03, 0xc8, 0x14, 0x00, 0x03, 0x7c, 0x06, 0x01, 0x02, 0x80, 0x06, 0x01, 0x02, 0x84, 0x06, 0x01, 0x02, + 0x88, 0x06, 0x01, 0x02, 0x8c, 0x06, 0x01, 0x02, 0x90, 0x06, 0x01, 0x02, 0x28, 0x22, 0x02, 0x03, 0x30, 0x22, 0x02, 0x03, 0x38, 0x22, 0x02, 0x03, 0x40, 0x22, 0x02, 0x03, 0x50, 0x04, 0x03, 0x03, + 0x58, 0x04, 0x03, 0x03, 0x60, 0x04, 0x03, 0x03, 0x10, 0x1f, 0x04, 0x04, 0x20, 0x1f, 0x04, 0x04, 0x90, 0x02, 0x05, 0x04, 0xa0, 0x02, 0x05, 0x04, 0xc0, 0x1b, 0x06, 0x05, 0x80, 0x17, 0x08, 0x06, + 0x00, 0x10, 0x0c, 0x08, 0xd0, 0x14, 0x00, 0x03, 0xd8, 0x14, 0x00, 0x03, 0xe0, 0x14, 0x00, 0x03, 0x94, 0x06, 0x01, 0x02, 0x98, 0x06, 0x01, 0x02, 0x9c, 0x06, 0x01, 0x02, 0xa0, 0x06, 0x01, 0x02, + 0xa4, 0x06, 0x01, 0x02, 0xa8, 0x06, 0x01, 0x02, 0xac, 0x06, 0x01, 0x02, 0x48, 0x22, 0x02, 0x03, 0x50, 0x22, 0x02, 0x03, 0x58, 0x22, 0x02, 0x03, 0x60, 0x22, 0x02, 0x03, 0x68, 0x04, 0x03, 0x03, + 0x70, 0x04, 0x03, 0x03, 0x78, 0x04, 0x03, 0x03, 0x30, 0x1f, 0x04, 0x04, 0x40, 0x1f, 0x04, 0x04, 0xb0, 0x02, 0x05, 0x04, 0xc0, 0x02, 0x05, 0x04, 0xe0, 0x1b, 0x06, 0x05, 0xc0, 0x17, 0x08, 0x06, + 0x00, 0x11, 0x0c, 0x08, 0xe8, 0x14, 0x00, 0x03, 0xf0, 0x14, 0x00, 0x03, 0xf8, 0x14, 0x00, 0x03, 0xb0, 0x06, 0x01, 0x02, 0xb4, 0x06, 0x01, 0x02, 0xb8, 0x06, 0x01, 0x02, 0xbc, 0x06, 0x01, 0x02, + 0xc0, 0x06, 0x01, 0x02, 0xc4, 0x06, 0x01, 0x02, 0xc8, 0x06, 0x01, 0x02, 0x68, 0x22, 0x02, 0x03, 0x70, 0x22, 0x02, 0x03, 0x78, 0x22, 0x02, 0x03, 0x80, 0x22, 0x02, 0x03, 0x80, 0x04, 0x03, 0x03, + 0x88, 0x04, 0x03, 0x03, 0x90, 0x04, 0x03, 0x03, 0x50, 0x1f, 0x04, 0x04, 0x60, 0x1f, 0x04, 0x04, 0xd0, 0x02, 0x05, 0x04, 0x00, 0x1c, 0x06, 0x05, 0x20, 0x1c, 0x06, 0x05, 0x00, 0x18, 0x08, 0x06, + 0x00, 0x12, 0x0c, 0x08, 0x00, 0x15, 0x00, 0x03, 0x08, 0x15, 0x00, 0x03, 0x10, 0x15, 0x00, 0x03, 0xcc, 0x06, 0x01, 0x02, 0xd0, 0x06, 0x01, 0x02, 0xd4, 0x06, 0x01, 0x02, 0xd8, 0x06, 0x01, 0x02, + 0xdc, 0x06, 0x01, 0x02, 0xe0, 0x06, 0x01, 0x02, 0xe4, 0x06, 0x01, 0x02, 0x88, 0x22, 0x02, 0x03, 0x90, 0x22, 0x02, 0x03, 0x98, 0x22, 0x02, 0x03, 0xa0, 0x22, 0x02, 0x03, 0x98, 0x04, 0x03, 0x03, + 0xa0, 0x04, 0x03, 0x03, 0xa8, 0x04, 0x03, 0x03, 0x70, 0x1f, 0x04, 0x04, 0x80, 0x1f, 0x04, 0x04, 0xe0, 0x02, 0x05, 0x04, 0x40, 0x1c, 0x06, 0x05, 0x00, 0x3e, 0x07, 0x06, 0x40, 0x18, 0x08, 0x06, + 0x00, 0x13, 0x0c, 0x08, 0x18, 0x15, 0x00, 0x03, 0x20, 0x15, 0x00, 0x03, 0x28, 0x15, 0x00, 0x03, 0xe8, 0x06, 0x01, 0x02, 0xec, 0x06, 0x01, 0x02, 0xf0, 0x06, 0x01, 0x02, 0xf4, 0x06, 0x01, 0x02, + 0xf8, 0x06, 0x01, 0x02, 0xfc, 0x06, 0x01, 0x02, 0x00, 0x07, 0x01, 0x02, 0xa8, 0x22, 0x02, 0x03, 0xb0, 0x22, 0x02, 0x03, 0xb8, 0x22, 0x02, 0x03, 0xc0, 0x22, 0x02, 0x03, 0xb0, 0x04, 0x03, 0x03, + 0xb8, 0x04, 0x03, 0x03, 0xc0, 0x04, 0x03, 0x03, 0x90, 0x1f, 0x04, 0x04, 0xa0, 0x1f, 0x04, 0x04, 0xf0, 0x02, 0x05, 0x04, 0x60, 0x1c, 0x06, 0x05, 0x40, 0x3e, 0x07, 0x06, 0x80, 0x18, 0x08, 0x06, + 0x00, 0x14, 0x0c, 0x08, 0x30, 0x15, 0x00, 0x03, 0x38, 0x15, 0x00, 0x03, 0x40, 0x15, 0x00, 0x03, 0x04, 0x07, 0x01, 0x02, 0x08, 0x07, 0x01, 0x02, 0x0c, 0x07, 0x01, 0x02, 0x10, 0x07, 0x01, 0x02, + 0x14, 0x07, 0x01, 0x02, 0x18, 0x07, 0x01, 0x02, 0x1c, 0x07, 0x01, 0x02, 0xc8, 0x22, 0x02, 0x03, 0xd0, 0x22, 0x02, 0x03, 0xd8, 0x22, 0x02, 0x03, 0xe0, 0x22, 0x02, 0x03, 0xc8, 0x04, 0x03, 0x03, + 0xd0, 0x04, 0x03, 0x03, 0xd8, 0x04, 0x03, 0x03, 0xb0, 0x1f, 0x04, 0x04, 0xc0, 0x1f, 0x04, 0x04, 0x00, 0x03, 0x05, 0x04, 0x80, 0x1c, 0x06, 0x05, 0x80, 0x3e, 0x07, 0x06, 0xc0, 0x18, 0x08, 0x06, + 0x00, 0x2a, 0x0d, 0x09, 0x48, 0x15, 0x00, 0x03, 0x50, 0x15, 0x00, 0x03, 0x58, 0x15, 0x00, 0x03, 0x20, 0x07, 0x01, 0x02, 0x24, 0x07, 0x01, 0x02, 0x28, 0x07, 0x01, 0x02, 0x2c, 0x07, 0x01, 0x02, + 0x30, 0x07, 0x01, 0x02, 0x34, 0x07, 0x01, 0x02, 0x38, 0x07, 0x01, 0x02, 0xe8, 0x22, 0x02, 0x03, 0xf0, 0x22, 0x02, 0x03, 0xf8, 0x22, 0x02, 0x03, 0x00, 0x23, 0x02, 0x03, 0xe0, 0x04, 0x03, 0x03, + 0xe8, 0x04, 0x03, 0x03, 0xf0, 0x04, 0x03, 0x03, 0xd0, 0x1f, 0x04, 0x04, 0xe0, 0x1f, 0x04, 0x04, 0x10, 0x03, 0x05, 0x04, 0xa0, 0x1c, 0x06, 0x05, 0xc0, 0x3e, 0x07, 0x06, 0x00, 0x19, 0x08, 0x06, + 0x00, 0x2c, 0x0d, 0x09, 0x60, 0x15, 0x00, 0x03, 0x68, 0x15, 0x00, 0x03, 0x70, 0x15, 0x00, 0x03, 0x3c, 0x07, 0x01, 0x02, 0x40, 0x07, 0x01, 0x02, 0x44, 0x07, 0x01, 0x02, 0x48, 0x07, 0x01, 0x02, + 0x4c, 0x07, 0x01, 0x02, 0x50, 0x07, 0x01, 0x02, 0x54, 0x07, 0x01, 0x02, 0x08, 0x23, 0x02, 0x03, 0x10, 0x23, 0x02, 0x03, 0x18, 0x23, 0x02, 0x03, 0x20, 0x23, 0x02, 0x03, 0xf8, 0x04, 0x03, 0x03, + 0x00, 0x05, 0x03, 0x03, 0x08, 0x05, 0x03, 0x03, 0xf0, 0x1f, 0x04, 0x04, 0x00, 0x20, 0x04, 0x04, 0x20, 0x03, 0x05, 0x04, 0xc0, 0x1c, 0x06, 0x05, 0x00, 0x3f, 0x07, 0x06, 0x40, 0x19, 0x08, 0x06, + 0x00, 0x2e, 0x0d, 0x09, 0x78, 0x15, 0x00, 0x03, 0x80, 0x15, 0x00, 0x03, 0x88, 0x15, 0x00, 0x03, 0x58, 0x07, 0x01, 0x02, 0x5c, 0x07, 0x01, 0x02, 0x60, 0x07, 0x01, 0x02, 0x64, 0x07, 0x01, 0x02, + 0x68, 0x07, 0x01, 0x02, 0x6c, 0x07, 0x01, 0x02, 0x70, 0x07, 0x01, 0x02, 0x28, 0x23, 0x02, 0x03, 0x30, 0x23, 0x02, 0x03, 0x38, 0x23, 0x02, 0x03, 0x40, 0x23, 0x02, 0x03, 0x10, 0x05, 0x03, 0x03, + 0x18, 0x05, 0x03, 0x03, 0x20, 0x05, 0x03, 0x03, 0x10, 0x20, 0x04, 0x04, 0x20, 0x20, 0x04, 0x04, 0x30, 0x03, 0x05, 0x04, 0xe0, 0x1c, 0x06, 0x05, 0x40, 0x3f, 0x07, 0x06, 0x80, 0x19, 0x08, 0x06, + 0x00, 0x30, 0x0d, 0x09, 0x90, 0x15, 0x00, 0x03, 0x98, 0x15, 0x00, 0x03, 0xa0, 0x15, 0x00, 0x03, 0x74, 0x07, 0x01, 0x02, 0x78, 0x07, 0x01, 0x02, 0x7c, 0x07, 0x01, 0x02, 0x80, 0x07, 0x01, 0x02, + 0x84, 0x07, 0x01, 0x02, 0x88, 0x07, 0x01, 0x02, 0x8c, 0x07, 0x01, 0x02, 0x48, 0x23, 0x02, 0x03, 0x50, 0x23, 0x02, 0x03, 0x58, 0x23, 0x02, 0x03, 0x60, 0x23, 0x02, 0x03, 0x28, 0x05, 0x03, 0x03, + 0x30, 0x05, 0x03, 0x03, 0x38, 0x05, 0x03, 0x03, 0x30, 0x20, 0x04, 0x04, 0x40, 0x20, 0x04, 0x04, 0x40, 0x03, 0x05, 0x04, 0x00, 0x1d, 0x06, 0x05, 0x80, 0x3f, 0x07, 0x06, 0xc0, 0x19, 0x08, 0x06, + 0x00, 0x32, 0x0d, 0x09, 0xa8, 0x15, 0x00, 0x03, 0xb0, 0x15, 0x00, 0x03, 0xb8, 0x15, 0x00, 0x03, 0x90, 0x07, 0x01, 0x02, 0x94, 0x07, 0x01, 0x02, 0x98, 0x07, 0x01, 0x02, 0x9c, 0x07, 0x01, 0x02, + 0xa0, 0x07, 0x01, 0x02, 0xa4, 0x07, 0x01, 0x02, 0xa8, 0x07, 0x01, 0x02, 0x68, 0x23, 0x02, 0x03, 0x70, 0x23, 0x02, 0x03, 0x78, 0x23, 0x02, 0x03, 0x80, 0x23, 0x02, 0x03, 0x40, 0x05, 0x03, 0x03, + 0x48, 0x05, 0x03, 0x03, 0x50, 0x05, 0x03, 0x03, 0x50, 0x20, 0x04, 0x04, 0x60, 0x20, 0x04, 0x04, 0x50, 0x03, 0x05, 0x04, 0x20, 0x1d, 0x06, 0x05, 0xc0, 0x3f, 0x07, 0x06, 0x00, 0x1a, 0x08, 0x06, + 0x00, 0x34, 0x0d, 0x09, 0xc0, 0x15, 0x00, 0x03, 0xc8, 0x15, 0x00, 0x03, 0xd0, 0x15, 0x00, 0x03, 0xac, 0x07, 0x01, 0x02, 0xb0, 0x07, 0x01, 0x02, 0xb4, 0x07, 0x01, 0x02, 0xb8, 0x07, 0x01, 0x02, + 0xbc, 0x07, 0x01, 0x02, 0xc0, 0x07, 0x01, 0x02, 0xc4, 0x07, 0x01, 0x02, 0x88, 0x23, 0x02, 0x03, 0x90, 0x23, 0x02, 0x03, 0x98, 0x23, 0x02, 0x03, 0xa0, 0x23, 0x02, 0x03, 0x58, 0x05, 0x03, 0x03, + 0x60, 0x05, 0x03, 0x03, 0x68, 0x05, 0x03, 0x03, 0x70, 0x20, 0x04, 0x04, 0x80, 0x20, 0x04, 0x04, 0x60, 0x03, 0x05, 0x04, 0x40, 0x1d, 0x06, 0x05, 0x00, 0x00, 0x07, 0x05, 0x40, 0x1a, 0x08, 0x06, + 0x00, 0x36, 0x0d, 0x09, 0xd8, 0x15, 0x00, 0x03, 0xe0, 0x15, 0x00, 0x03, 0xe8, 0x15, 0x00, 0x03, 0xc8, 0x07, 0x01, 0x02, 0xcc, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd4, 0x07, 0x01, 0x02, + 0xd8, 0x07, 0x01, 0x02, 0xdc, 0x07, 0x01, 0x02, 0xe0, 0x07, 0x01, 0x02, 0xa8, 0x23, 0x02, 0x03, 0xb0, 0x23, 0x02, 0x03, 0xb8, 0x23, 0x02, 0x03, 0xc0, 0x23, 0x02, 0x03, 0x70, 0x05, 0x03, 0x03, + 0x78, 0x05, 0x03, 0x03, 0x80, 0x05, 0x03, 0x03, 0x90, 0x20, 0x04, 0x04, 0xa0, 0x20, 0x04, 0x04, 0x70, 0x03, 0x05, 0x04, 0x60, 0x1d, 0x06, 0x05, 0x20, 0x00, 0x07, 0x05, 0x80, 0x1a, 0x08, 0x06, + 0x00, 0x0a, 0x0e, 0x09, 0xf0, 0x15, 0x00, 0x03, 0xf8, 0x15, 0x00, 0x03, 0x00, 0x16, 0x00, 0x03, 0xe4, 0x07, 0x01, 0x02, 0xe8, 0x07, 0x01, 0x02, 0xec, 0x07, 0x01, 0x02, 0xf0, 0x07, 0x01, 0x02, + 0xf4, 0x07, 0x01, 0x02, 0xf8, 0x07, 0x01, 0x02, 0xfc, 0x07, 0x01, 0x02, 0xc8, 0x23, 0x02, 0x03, 0xd0, 0x23, 0x02, 0x03, 0xd8, 0x23, 0x02, 0x03, 0xe0, 0x23, 0x02, 0x03, 0x88, 0x05, 0x03, 0x03, + 0x90, 0x05, 0x03, 0x03, 0x98, 0x05, 0x03, 0x03, 0xb0, 0x20, 0x04, 0x04, 0xc0, 0x20, 0x04, 0x04, 0x80, 0x03, 0x05, 0x04, 0x80, 0x1d, 0x06, 0x05, 0x40, 0x00, 0x07, 0x05, 0xc0, 0x1a, 0x08, 0x06, + 0x00, 0x0c, 0x0e, 0x09, 0x08, 0x16, 0x00, 0x03, 0x10, 0x16, 0x00, 0x03, 0x18, 0x16, 0x00, 0x03, 0x00, 0x08, 0x01, 0x02, 0x04, 0x08, 0x01, 0x02, 0x08, 0x08, 0x01, 0x02, 0x0c, 0x08, 0x01, 0x02, + 0x10, 0x08, 0x01, 0x02, 0x14, 0x08, 0x01, 0x02, 0x18, 0x08, 0x01, 0x02, 0xe8, 0x23, 0x02, 0x03, 0xf0, 0x23, 0x02, 0x03, 0xf8, 0x23, 0x02, 0x03, 0x00, 0x24, 0x02, 0x03, 0xa0, 0x05, 0x03, 0x03, + 0xa8, 0x05, 0x03, 0x03, 0xb0, 0x05, 0x03, 0x03, 0xd0, 0x20, 0x04, 0x04, 0xe0, 0x20, 0x04, 0x04, 0x90, 0x03, 0x05, 0x04, 0xa0, 0x1d, 0x06, 0x05, 0x60, 0x00, 0x07, 0x05, 0x00, 0x1b, 0x08, 0x06, + 0x00, 0x0e, 0x0e, 0x09, 0x20, 0x16, 0x00, 0x03, 0x28, 0x16, 0x00, 0x03, 0x30, 0x16, 0x00, 0x03, 0x1c, 0x08, 0x01, 0x02, 0x20, 0x08, 0x01, 0x02, 0x24, 0x08, 0x01, 0x02, 0x28, 0x08, 0x01, 0x02, + 0x2c, 0x08, 0x01, 0x02, 0x30, 0x08, 0x01, 0x02, 0x34, 0x08, 0x01, 0x02, 0x08, 0x24, 0x02, 0x03, 0x10, 0x24, 0x02, 0x03, 0x18, 0x24, 0x02, 0x03, 0x20, 0x24, 0x02, 0x03, 0xb8, 0x05, 0x03, 0x03, + 0xc0, 0x05, 0x03, 0x03, 0xc8, 0x05, 0x03, 0x03, 0xf0, 0x20, 0x04, 0x04, 0x00, 0x21, 0x04, 0x04, 0xa0, 0x03, 0x05, 0x04, 0xc0, 0x1d, 0x06, 0x05, 0x80, 0x00, 0x07, 0x05, 0x40, 0x1b, 0x08, 0x06, + 0x00, 0x10, 0x0e, 0x09, 0x38, 0x16, 0x00, 0x03, 0x40, 0x16, 0x00, 0x03, 0x48, 0x16, 0x00, 0x03, 0x38, 0x08, 0x01, 0x02, 0x3c, 0x08, 0x01, 0x02, 0x40, 0x08, 0x01, 0x02, 0x44, 0x08, 0x01, 0x02, + 0x48, 0x08, 0x01, 0x02, 0x4c, 0x08, 0x01, 0x02, 0x50, 0x08, 0x01, 0x02, 0x28, 0x24, 0x02, 0x03, 0x30, 0x24, 0x02, 0x03, 0x38, 0x24, 0x02, 0x03, 0x40, 0x24, 0x02, 0x03, 0xd0, 0x05, 0x03, 0x03, + 0xd8, 0x05, 0x03, 0x03, 0xe0, 0x05, 0x03, 0x03, 0x10, 0x21, 0x04, 0x04, 0x20, 0x21, 0x04, 0x04, 0xb0, 0x03, 0x05, 0x04, 0xe0, 0x1d, 0x06, 0x05, 0xa0, 0x00, 0x07, 0x05, 0x80, 0x1b, 0x08, 0x06, + 0x00, 0x12, 0x0e, 0x09, 0x50, 0x16, 0x00, 0x03, 0x58, 0x16, 0x00, 0x03, 0x60, 0x16, 0x00, 0x03, 0x54, 0x08, 0x01, 0x02, 0x58, 0x08, 0x01, 0x02, 0x5c, 0x08, 0x01, 0x02, 0x60, 0x08, 0x01, 0x02, + 0x64, 0x08, 0x01, 0x02, 0x68, 0x08, 0x01, 0x02, 0x48, 0x24, 0x02, 0x03, 0x50, 0x24, 0x02, 0x03, 0x58, 0x24, 0x02, 0x03, 0x60, 0x24, 0x02, 0x03, 0x68, 0x24, 0x02, 0x03, 0xe8, 0x05, 0x03, 0x03, + 0xf0, 0x05, 0x03, 0x03, 0xf8, 0x05, 0x03, 0x03, 0x30, 0x21, 0x04, 0x04, 0x40, 0x21, 0x04, 0x04, 0xc0, 0x03, 0x05, 0x04, 0x00, 0x1e, 0x06, 0x05, 0xc0, 0x00, 0x07, 0x05, 0xc0, 0x1b, 0x08, 0x06, + 0x00, 0x28, 0x0f, 0x0a, 0x68, 0x16, 0x00, 0x03, 0x70, 0x16, 0x00, 0x03, 0x78, 0x16, 0x00, 0x03, 0x6c, 0x08, 0x01, 0x02, 0x70, 0x08, 0x01, 0x02, 0x74, 0x08, 0x01, 0x02, 0x78, 0x08, 0x01, 0x02, + 0x7c, 0x08, 0x01, 0x02, 0x80, 0x08, 0x01, 0x02, 0x70, 0x24, 0x02, 0x03, 0x78, 0x24, 0x02, 0x03, 0x80, 0x24, 0x02, 0x03, 0x88, 0x24, 0x02, 0x03, 0x90, 0x24, 0x02, 0x03, 0x00, 0x06, 0x03, 0x03, + 0x08, 0x06, 0x03, 0x03, 0x10, 0x06, 0x03, 0x03, 0x50, 0x21, 0x04, 0x04, 0x60, 0x21, 0x04, 0x04, 0xd0, 0x03, 0x05, 0x04, 0x20, 0x1e, 0x06, 0x05, 0xe0, 0x00, 0x07, 0x05, 0x00, 0x3b, 0x09, 0x07, + 0x00, 0x2c, 0x0f, 0x0a, 0x80, 0x16, 0x00, 0x03, 0x88, 0x16, 0x00, 0x03, 0x90, 0x16, 0x00, 0x03, 0x84, 0x08, 0x01, 0x02, 0x88, 0x08, 0x01, 0x02, 0x8c, 0x08, 0x01, 0x02, 0x90, 0x08, 0x01, 0x02, + 0x94, 0x08, 0x01, 0x02, 0x98, 0x08, 0x01, 0x02, 0x98, 0x24, 0x02, 0x03, 0xa0, 0x24, 0x02, 0x03, 0xa8, 0x24, 0x02, 0x03, 0xb0, 0x24, 0x02, 0x03, 0xb8, 0x24, 0x02, 0x03, 0x18, 0x06, 0x03, 0x03, + 0x20, 0x06, 0x03, 0x03, 0x28, 0x06, 0x03, 0x03, 0x70, 0x21, 0x04, 0x04, 0x80, 0x21, 0x04, 0x04, 0xe0, 0x03, 0x05, 0x04, 0x40, 0x1e, 0x06, 0x05, 0x00, 0x01, 0x07, 0x05, 0x80, 0x3b, 0x09, 0x07, + 0x00, 0x30, 0x0f, 0x0a, 0x98, 0x16, 0x00, 0x03, 0xa0, 0x16, 0x00, 0x03, 0xa8, 0x16, 0x00, 0x03, 0x9c, 0x08, 0x01, 0x02, 0xa0, 0x08, 0x01, 0x02, 0xa4, 0x08, 0x01, 0x02, 0xa8, 0x08, 0x01, 0x02, + 0xac, 0x08, 0x01, 0x02, 0xb0, 0x08, 0x01, 0x02, 0xc0, 0x24, 0x02, 0x03, 0xc8, 0x24, 0x02, 0x03, 0xd0, 0x24, 0x02, 0x03, 0xd8, 0x24, 0x02, 0x03, 0xe0, 0x24, 0x02, 0x03, 0x30, 0x06, 0x03, 0x03, + 0x38, 0x06, 0x03, 0x03, 0x40, 0x06, 0x03, 0x03, 0x90, 0x21, 0x04, 0x04, 0xa0, 0x21, 0x04, 0x04, 0xf0, 0x03, 0x05, 0x04, 0x60, 0x1e, 0x06, 0x05, 0x20, 0x01, 0x07, 0x05, 0x00, 0x3c, 0x09, 0x07, + 0x00, 0x08, 0x10, 0x0a, 0xb0, 0x16, 0x00, 0x03, 0xb8, 0x16, 0x00, 0x03, 0xc0, 0x16, 0x00, 0x03, 0xb4, 0x08, 0x01, 0x02, 0xb8, 0x08, 0x01, 0x02, 0xbc, 0x08, 0x01, 0x02, 0xc0, 0x08, 0x01, 0x02, + 0xc4, 0x08, 0x01, 0x02, 0xc8, 0x08, 0x01, 0x02, 0xe8, 0x24, 0x02, 0x03, 0xf0, 0x24, 0x02, 0x03, 0xf8, 0x24, 0x02, 0x03, 0x00, 0x25, 0x02, 0x03, 0x08, 0x25, 0x02, 0x03, 0x48, 0x06, 0x03, 0x03, + 0x50, 0x06, 0x03, 0x03, 0x58, 0x06, 0x03, 0x03, 0xb0, 0x21, 0x04, 0x04, 0xc0, 0x21, 0x04, 0x04, 0x00, 0x04, 0x05, 0x04, 0x80, 0x1e, 0x06, 0x05, 0x40, 0x01, 0x07, 0x05, 0x80, 0x3c, 0x09, 0x07, + 0x00, 0x0c, 0x10, 0x0a, 0xc8, 0x16, 0x00, 0x03, 0xd0, 0x16, 0x00, 0x03, 0xd8, 0x16, 0x00, 0x03, 0xcc, 0x08, 0x01, 0x02, 0xd0, 0x08, 0x01, 0x02, 0xd4, 0x08, 0x01, 0x02, 0xd8, 0x08, 0x01, 0x02, + 0xdc, 0x08, 0x01, 0x02, 0xe0, 0x08, 0x01, 0x02, 0x10, 0x25, 0x02, 0x03, 0x18, 0x25, 0x02, 0x03, 0x20, 0x25, 0x02, 0x03, 0x28, 0x25, 0x02, 0x03, 0x30, 0x25, 0x02, 0x03, 0x60, 0x06, 0x03, 0x03, + 0x68, 0x06, 0x03, 0x03, 0x70, 0x06, 0x03, 0x03, 0xd0, 0x21, 0x04, 0x04, 0xe0, 0x21, 0x04, 0x04, 0x10, 0x04, 0x05, 0x04, 0xa0, 0x1e, 0x06, 0x05, 0x60, 0x01, 0x07, 0x05, 0x00, 0x3d, 0x09, 0x07, + 0x00, 0x10, 0x10, 0x0a, 0xe0, 0x16, 0x00, 0x03, 0xe8, 0x16, 0x00, 0x03, 0xf0, 0x16, 0x00, 0x03, 0xe4, 0x08, 0x01, 0x02, 0xe8, 0x08, 0x01, 0x02, 0xec, 0x08, 0x01, 0x02, 0xf0, 0x08, 0x01, 0x02, + 0xf4, 0x08, 0x01, 0x02, 0xf8, 0x08, 0x01, 0x02, 0x38, 0x25, 0x02, 0x03, 0x40, 0x25, 0x02, 0x03, 0x48, 0x25, 0x02, 0x03, 0x50, 0x25, 0x02, 0x03, 0x58, 0x25, 0x02, 0x03, 0x78, 0x06, 0x03, 0x03, + 0x80, 0x06, 0x03, 0x03, 0x88, 0x06, 0x03, 0x03, 0xf0, 0x21, 0x04, 0x04, 0x00, 0x22, 0x04, 0x04, 0x20, 0x04, 0x05, 0x04, 0xc0, 0x1e, 0x06, 0x05, 0x80, 0x01, 0x07, 0x05, 0x80, 0x3d, 0x09, 0x07, + 0x00, 0x20, 0x11, 0x0b, 0xf8, 0x16, 0x00, 0x03, 0x00, 0x17, 0x00, 0x03, 0x08, 0x17, 0x00, 0x03, 0xfc, 0x08, 0x01, 0x02, 0x00, 0x09, 0x01, 0x02, 0x04, 0x09, 0x01, 0x02, 0x08, 0x09, 0x01, 0x02, + 0x0c, 0x09, 0x01, 0x02, 0x10, 0x09, 0x01, 0x02, 0x60, 0x25, 0x02, 0x03, 0x68, 0x25, 0x02, 0x03, 0x70, 0x25, 0x02, 0x03, 0x78, 0x25, 0x02, 0x03, 0x80, 0x25, 0x02, 0x03, 0x90, 0x06, 0x03, 0x03, + 0x98, 0x06, 0x03, 0x03, 0xa0, 0x06, 0x03, 0x03, 0x10, 0x22, 0x04, 0x04, 0x20, 0x22, 0x04, 0x04, 0x30, 0x04, 0x05, 0x04, 0xe0, 0x1e, 0x06, 0x05, 0xa0, 0x01, 0x07, 0x05, 0x00, 0x3e, 0x09, 0x07, + 0x00, 0x08, 0x12, 0x0b, 0x10, 0x17, 0x00, 0x03, 0x18, 0x17, 0x00, 0x03, 0x20, 0x17, 0x00, 0x03, 0x14, 0x09, 0x01, 0x02, 0x18, 0x09, 0x01, 0x02, 0x1c, 0x09, 0x01, 0x02, 0x20, 0x09, 0x01, 0x02, + 0x24, 0x09, 0x01, 0x02, 0x28, 0x09, 0x01, 0x02, 0x88, 0x25, 0x02, 0x03, 0x90, 0x25, 0x02, 0x03, 0x98, 0x25, 0x02, 0x03, 0xa0, 0x25, 0x02, 0x03, 0xa8, 0x25, 0x02, 0x03, 0xa8, 0x06, 0x03, 0x03, + 0xb0, 0x06, 0x03, 0x03, 0xb8, 0x06, 0x03, 0x03, 0x30, 0x22, 0x04, 0x04, 0x40, 0x22, 0x04, 0x04, 0x40, 0x04, 0x05, 0x04, 0x00, 0x1f, 0x06, 0x05, 0xc0, 0x01, 0x07, 0x05, 0x80, 0x3e, 0x09, 0x07, + 0x00, 0x10, 0x12, 0x0b, 0x28, 0x17, 0x00, 0x03, 0x30, 0x17, 0x00, 0x03, 0x38, 0x17, 0x00, 0x03, 0x2c, 0x09, 0x01, 0x02, 0x30, 0x09, 0x01, 0x02, 0x34, 0x09, 0x01, 0x02, 0x38, 0x09, 0x01, 0x02, + 0x3c, 0x09, 0x01, 0x02, 0x40, 0x09, 0x01, 0x02, 0xb0, 0x25, 0x02, 0x03, 0xb8, 0x25, 0x02, 0x03, 0xc0, 0x25, 0x02, 0x03, 0xc8, 0x25, 0x02, 0x03, 0xd0, 0x25, 0x02, 0x03, 0xc0, 0x06, 0x03, 0x03, + 0xc8, 0x06, 0x03, 0x03, 0xd0, 0x06, 0x03, 0x03, 0x50, 0x22, 0x04, 0x04, 0x60, 0x22, 0x04, 0x04, 0x50, 0x04, 0x05, 0x04, 0x20, 0x1f, 0x06, 0x05, 0xe0, 0x01, 0x07, 0x05, 0x00, 0x3f, 0x09, 0x07, + 0x00, 0x20, 0x13, 0x0c, 0x40, 0x17, 0x00, 0x03, 0x48, 0x17, 0x00, 0x03, 0x50, 0x17, 0x00, 0x03, 0x44, 0x09, 0x01, 0x02, 0x48, 0x09, 0x01, 0x02, 0x4c, 0x09, 0x01, 0x02, 0x50, 0x09, 0x01, 0x02, + 0x54, 0x09, 0x01, 0x02, 0x58, 0x09, 0x01, 0x02, 0xd8, 0x25, 0x02, 0x03, 0xe0, 0x25, 0x02, 0x03, 0xe8, 0x25, 0x02, 0x03, 0xf0, 0x25, 0x02, 0x03, 0xf8, 0x25, 0x02, 0x03, 0xd8, 0x06, 0x03, 0x03, + 0xe0, 0x06, 0x03, 0x03, 0xe8, 0x06, 0x03, 0x03, 0x70, 0x22, 0x04, 0x04, 0x80, 0x22, 0x04, 0x04, 0x60, 0x04, 0x05, 0x04, 0x40, 0x1f, 0x06, 0x05, 0x00, 0x02, 0x07, 0x05, 0x80, 0x3f, 0x09, 0x07, + 0x00, 0x20, 0x15, 0x0d, 0x58, 0x17, 0x00, 0x03, 0x60, 0x17, 0x00, 0x03, 0x68, 0x17, 0x00, 0x03, 0x5c, 0x09, 0x01, 0x02, 0x60, 0x09, 0x01, 0x02, 0x64, 0x09, 0x01, 0x02, 0x68, 0x09, 0x01, 0x02, + 0x6c, 0x09, 0x01, 0x02, 0x70, 0x09, 0x01, 0x02, 0x00, 0x26, 0x02, 0x03, 0x08, 0x26, 0x02, 0x03, 0x10, 0x26, 0x02, 0x03, 0x18, 0x26, 0x02, 0x03, 0x20, 0x26, 0x02, 0x03, 0xf0, 0x06, 0x03, 0x03, + 0xf8, 0x06, 0x03, 0x03, 0x00, 0x07, 0x03, 0x03, 0x90, 0x22, 0x04, 0x04, 0xa0, 0x22, 0x04, 0x04, 0x70, 0x04, 0x05, 0x04, 0x60, 0x1f, 0x06, 0x05, 0x20, 0x02, 0x07, 0x05, 0x00, 0x00, 0x09, 0x06, + 0x70, 0x17, 0x00, 0x03, 0x78, 0x17, 0x00, 0x03, 0x80, 0x17, 0x00, 0x03, 0x88, 0x17, 0x00, 0x03, 0x74, 0x09, 0x01, 0x02, 0x78, 0x09, 0x01, 0x02, 0x7c, 0x09, 0x01, 0x02, 0x80, 0x09, 0x01, 0x02, + 0x84, 0x09, 0x01, 0x02, 0x88, 0x09, 0x01, 0x02, 0x28, 0x26, 0x02, 0x03, 0x30, 0x26, 0x02, 0x03, 0x38, 0x26, 0x02, 0x03, 0x40, 0x26, 0x02, 0x03, 0x48, 0x26, 0x02, 0x03, 0x08, 0x07, 0x03, 0x03, + 0x10, 0x07, 0x03, 0x03, 0x18, 0x07, 0x03, 0x03, 0xb0, 0x22, 0x04, 0x04, 0xc0, 0x22, 0x04, 0x04, 0x80, 0x04, 0x05, 0x04, 0x80, 0x1f, 0x06, 0x05, 0x40, 0x02, 0x07, 0x05, 0x40, 0x00, 0x09, 0x06, + 0x90, 0x17, 0x00, 0x03, 0x98, 0x17, 0x00, 0x03, 0xa0, 0x17, 0x00, 0x03, 0xa8, 0x17, 0x00, 0x03, 0x8c, 0x09, 0x01, 0x02, 0x90, 0x09, 0x01, 0x02, 0x94, 0x09, 0x01, 0x02, 0x98, 0x09, 0x01, 0x02, + 0x9c, 0x09, 0x01, 0x02, 0xa0, 0x09, 0x01, 0x02, 0x50, 0x26, 0x02, 0x03, 0x58, 0x26, 0x02, 0x03, 0x60, 0x26, 0x02, 0x03, 0x68, 0x26, 0x02, 0x03, 0x70, 0x26, 0x02, 0x03, 0x20, 0x07, 0x03, 0x03, + 0x28, 0x07, 0x03, 0x03, 0x30, 0x07, 0x03, 0x03, 0xd0, 0x22, 0x04, 0x04, 0xe0, 0x22, 0x04, 0x04, 0x90, 0x04, 0x05, 0x04, 0xa0, 0x1f, 0x06, 0x05, 0x60, 0x02, 0x07, 0x05, 0x80, 0x00, 0x09, 0x06, + 0xb0, 0x17, 0x00, 0x03, 0xb8, 0x17, 0x00, 0x03, 0xc0, 0x17, 0x00, 0x03, 0xc8, 0x17, 0x00, 0x03, 0xa4, 0x09, 0x01, 0x02, 0xa8, 0x09, 0x01, 0x02, 0xac, 0x09, 0x01, 0x02, 0xb0, 0x09, 0x01, 0x02, + 0xb4, 0x09, 0x01, 0x02, 0xb8, 0x09, 0x01, 0x02, 0x78, 0x26, 0x02, 0x03, 0x80, 0x26, 0x02, 0x03, 0x88, 0x26, 0x02, 0x03, 0x90, 0x26, 0x02, 0x03, 0x98, 0x26, 0x02, 0x03, 0x38, 0x07, 0x03, 0x03, + 0x40, 0x07, 0x03, 0x03, 0x48, 0x07, 0x03, 0x03, 0xf0, 0x22, 0x04, 0x04, 0x00, 0x23, 0x04, 0x04, 0xa0, 0x04, 0x05, 0x04, 0xc0, 0x1f, 0x06, 0x05, 0x80, 0x02, 0x07, 0x05, 0xc0, 0x00, 0x09, 0x06, + 0xd0, 0x17, 0x00, 0x03, 0xd8, 0x17, 0x00, 0x03, 0xe0, 0x17, 0x00, 0x03, 0xe8, 0x17, 0x00, 0x03, 0xbc, 0x09, 0x01, 0x02, 0xc0, 0x09, 0x01, 0x02, 0xc4, 0x09, 0x01, 0x02, 0xc8, 0x09, 0x01, 0x02, + 0xcc, 0x09, 0x01, 0x02, 0xd0, 0x09, 0x01, 0x02, 0xa0, 0x26, 0x02, 0x03, 0xa8, 0x26, 0x02, 0x03, 0xb0, 0x26, 0x02, 0x03, 0xb8, 0x26, 0x02, 0x03, 0xc0, 0x26, 0x02, 0x03, 0x50, 0x07, 0x03, 0x03, + 0x58, 0x07, 0x03, 0x03, 0x60, 0x07, 0x03, 0x03, 0x10, 0x23, 0x04, 0x04, 0x20, 0x23, 0x04, 0x04, 0xb0, 0x04, 0x05, 0x04, 0xe0, 0x1f, 0x06, 0x05, 0xa0, 0x02, 0x07, 0x05, 0x00, 0x01, 0x09, 0x06, + 0xf0, 0x17, 0x00, 0x03, 0xf8, 0x17, 0x00, 0x03, 0x00, 0x18, 0x00, 0x03, 0x08, 0x18, 0x00, 0x03, 0xd4, 0x09, 0x01, 0x02, 0xd8, 0x09, 0x01, 0x02, 0xdc, 0x09, 0x01, 0x02, 0xe0, 0x09, 0x01, 0x02, + 0xe4, 0x09, 0x01, 0x02, 0xe8, 0x09, 0x01, 0x02, 0xc8, 0x26, 0x02, 0x03, 0xd0, 0x26, 0x02, 0x03, 0xd8, 0x26, 0x02, 0x03, 0xe0, 0x26, 0x02, 0x03, 0xe8, 0x26, 0x02, 0x03, 0x68, 0x07, 0x03, 0x03, + 0x70, 0x07, 0x03, 0x03, 0x78, 0x07, 0x03, 0x03, 0x30, 0x23, 0x04, 0x04, 0x40, 0x23, 0x04, 0x04, 0xc0, 0x04, 0x05, 0x04, 0x00, 0x20, 0x06, 0x05, 0xc0, 0x02, 0x07, 0x05, 0x40, 0x01, 0x09, 0x06, + 0x10, 0x18, 0x00, 0x03, 0x18, 0x18, 0x00, 0x03, 0x20, 0x18, 0x00, 0x03, 0x28, 0x18, 0x00, 0x03, 0xec, 0x09, 0x01, 0x02, 0xf0, 0x09, 0x01, 0x02, 0xf4, 0x09, 0x01, 0x02, 0xf8, 0x09, 0x01, 0x02, + 0xfc, 0x09, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0xf0, 0x26, 0x02, 0x03, 0xf8, 0x26, 0x02, 0x03, 0x00, 0x27, 0x02, 0x03, 0x08, 0x27, 0x02, 0x03, 0x10, 0x27, 0x02, 0x03, 0x80, 0x07, 0x03, 0x03, + 0x88, 0x07, 0x03, 0x03, 0x90, 0x07, 0x03, 0x03, 0x50, 0x23, 0x04, 0x04, 0x60, 0x23, 0x04, 0x04, 0xd0, 0x04, 0x05, 0x04, 0x20, 0x20, 0x06, 0x05, 0xe0, 0x02, 0x07, 0x05, 0x80, 0x01, 0x09, 0x06, + 0x30, 0x18, 0x00, 0x03, 0x38, 0x18, 0x00, 0x03, 0x40, 0x18, 0x00, 0x03, 0x48, 0x18, 0x00, 0x03, 0x04, 0x0a, 0x01, 0x02, 0x08, 0x0a, 0x01, 0x02, 0x0c, 0x0a, 0x01, 0x02, 0x10, 0x0a, 0x01, 0x02, + 0x14, 0x0a, 0x01, 0x02, 0x18, 0x0a, 0x01, 0x02, 0x18, 0x27, 0x02, 0x03, 0x20, 0x27, 0x02, 0x03, 0x28, 0x27, 0x02, 0x03, 0x30, 0x27, 0x02, 0x03, 0x38, 0x27, 0x02, 0x03, 0x98, 0x07, 0x03, 0x03, + 0xa0, 0x07, 0x03, 0x03, 0xa8, 0x07, 0x03, 0x03, 0x70, 0x23, 0x04, 0x04, 0x80, 0x23, 0x04, 0x04, 0xe0, 0x04, 0x05, 0x04, 0x40, 0x20, 0x06, 0x05, 0x00, 0x03, 0x07, 0x05, 0xc0, 0x01, 0x09, 0x06, + 0x50, 0x18, 0x00, 0x03, 0x58, 0x18, 0x00, 0x03, 0x60, 0x18, 0x00, 0x03, 0x68, 0x18, 0x00, 0x03, 0x1c, 0x0a, 0x01, 0x02, 0x20, 0x0a, 0x01, 0x02, 0x24, 0x0a, 0x01, 0x02, 0x28, 0x0a, 0x01, 0x02, + 0x2c, 0x0a, 0x01, 0x02, 0x30, 0x0a, 0x01, 0x02, 0x40, 0x27, 0x02, 0x03, 0x48, 0x27, 0x02, 0x03, 0x50, 0x27, 0x02, 0x03, 0x58, 0x27, 0x02, 0x03, 0x60, 0x27, 0x02, 0x03, 0xb0, 0x07, 0x03, 0x03, + 0xb8, 0x07, 0x03, 0x03, 0xc0, 0x07, 0x03, 0x03, 0x90, 0x23, 0x04, 0x04, 0xa0, 0x23, 0x04, 0x04, 0xf0, 0x04, 0x05, 0x04, 0x60, 0x20, 0x06, 0x05, 0x20, 0x03, 0x07, 0x05, 0x00, 0x02, 0x09, 0x06, + 0x70, 0x18, 0x00, 0x03, 0x78, 0x18, 0x00, 0x03, 0x80, 0x18, 0x00, 0x03, 0x88, 0x18, 0x00, 0x03, 0x34, 0x0a, 0x01, 0x02, 0x38, 0x0a, 0x01, 0x02, 0x3c, 0x0a, 0x01, 0x02, 0x40, 0x0a, 0x01, 0x02, + 0x44, 0x0a, 0x01, 0x02, 0x48, 0x0a, 0x01, 0x02, 0x68, 0x27, 0x02, 0x03, 0x70, 0x27, 0x02, 0x03, 0x78, 0x27, 0x02, 0x03, 0x80, 0x27, 0x02, 0x03, 0x88, 0x27, 0x02, 0x03, 0xc8, 0x07, 0x03, 0x03, + 0xd0, 0x07, 0x03, 0x03, 0xd8, 0x07, 0x03, 0x03, 0xb0, 0x23, 0x04, 0x04, 0xc0, 0x23, 0x04, 0x04, 0x00, 0x05, 0x05, 0x04, 0x80, 0x20, 0x06, 0x05, 0x40, 0x03, 0x07, 0x05, 0x40, 0x02, 0x09, 0x06, + 0x90, 0x18, 0x00, 0x03, 0x98, 0x18, 0x00, 0x03, 0xa0, 0x18, 0x00, 0x03, 0xa8, 0x18, 0x00, 0x03, 0x4c, 0x0a, 0x01, 0x02, 0x50, 0x0a, 0x01, 0x02, 0x54, 0x0a, 0x01, 0x02, 0x58, 0x0a, 0x01, 0x02, + 0x5c, 0x0a, 0x01, 0x02, 0x60, 0x0a, 0x01, 0x02, 0x90, 0x27, 0x02, 0x03, 0x98, 0x27, 0x02, 0x03, 0xa0, 0x27, 0x02, 0x03, 0xa8, 0x27, 0x02, 0x03, 0xb0, 0x27, 0x02, 0x03, 0xe0, 0x07, 0x03, 0x03, + 0xe8, 0x07, 0x03, 0x03, 0xf0, 0x07, 0x03, 0x03, 0xd0, 0x23, 0x04, 0x04, 0xe0, 0x23, 0x04, 0x04, 0x10, 0x05, 0x05, 0x04, 0xa0, 0x20, 0x06, 0x05, 0x60, 0x03, 0x07, 0x05, 0x80, 0x02, 0x09, 0x06, + 0xb0, 0x18, 0x00, 0x03, 0xb8, 0x18, 0x00, 0x03, 0xc0, 0x18, 0x00, 0x03, 0xc8, 0x18, 0x00, 0x03, 0x64, 0x0a, 0x01, 0x02, 0x68, 0x0a, 0x01, 0x02, 0x6c, 0x0a, 0x01, 0x02, 0x70, 0x0a, 0x01, 0x02, + 0x74, 0x0a, 0x01, 0x02, 0x78, 0x0a, 0x01, 0x02, 0xb8, 0x27, 0x02, 0x03, 0xc0, 0x27, 0x02, 0x03, 0xc8, 0x27, 0x02, 0x03, 0xd0, 0x27, 0x02, 0x03, 0xd8, 0x27, 0x02, 0x03, 0xf8, 0x07, 0x03, 0x03, + 0x00, 0x08, 0x03, 0x03, 0x08, 0x08, 0x03, 0x03, 0xf0, 0x23, 0x04, 0x04, 0x00, 0x24, 0x04, 0x04, 0x20, 0x05, 0x05, 0x04, 0xc0, 0x20, 0x06, 0x05, 0x80, 0x03, 0x07, 0x05, 0xc0, 0x02, 0x09, 0x06, + 0xd0, 0x18, 0x00, 0x03, 0xd8, 0x18, 0x00, 0x03, 0xe0, 0x18, 0x00, 0x03, 0xe8, 0x18, 0x00, 0x03, 0x7c, 0x0a, 0x01, 0x02, 0x80, 0x0a, 0x01, 0x02, 0x84, 0x0a, 0x01, 0x02, 0x88, 0x0a, 0x01, 0x02, + 0x8c, 0x0a, 0x01, 0x02, 0x90, 0x0a, 0x01, 0x02, 0xe0, 0x27, 0x02, 0x03, 0xe8, 0x27, 0x02, 0x03, 0xf0, 0x27, 0x02, 0x03, 0xf8, 0x27, 0x02, 0x03, 0x00, 0x28, 0x02, 0x03, 0x10, 0x08, 0x03, 0x03, + 0x18, 0x08, 0x03, 0x03, 0x20, 0x08, 0x03, 0x03, 0x10, 0x24, 0x04, 0x04, 0x20, 0x24, 0x04, 0x04, 0x30, 0x05, 0x05, 0x04, 0xe0, 0x20, 0x06, 0x05, 0xa0, 0x03, 0x07, 0x05, 0x00, 0x03, 0x09, 0x06, + 0xf0, 0x18, 0x00, 0x03, 0xf8, 0x18, 0x00, 0x03, 0x00, 0x19, 0x00, 0x03, 0x08, 0x19, 0x00, 0x03, 0x94, 0x0a, 0x01, 0x02, 0x98, 0x0a, 0x01, 0x02, 0x9c, 0x0a, 0x01, 0x02, 0xa0, 0x0a, 0x01, 0x02, + 0xa4, 0x0a, 0x01, 0x02, 0xa8, 0x0a, 0x01, 0x02, 0x08, 0x28, 0x02, 0x03, 0x10, 0x28, 0x02, 0x03, 0x18, 0x28, 0x02, 0x03, 0x20, 0x28, 0x02, 0x03, 0x28, 0x28, 0x02, 0x03, 0x28, 0x08, 0x03, 0x03, + 0x30, 0x08, 0x03, 0x03, 0x38, 0x08, 0x03, 0x03, 0x30, 0x24, 0x04, 0x04, 0x40, 0x24, 0x04, 0x04, 0x40, 0x05, 0x05, 0x04, 0x00, 0x21, 0x06, 0x05, 0xc0, 0x03, 0x07, 0x05, 0x40, 0x03, 0x09, 0x06, + 0x10, 0x19, 0x00, 0x03, 0x18, 0x19, 0x00, 0x03, 0x20, 0x19, 0x00, 0x03, 0x28, 0x19, 0x00, 0x03, 0xac, 0x0a, 0x01, 0x02, 0xb0, 0x0a, 0x01, 0x02, 0xb4, 0x0a, 0x01, 0x02, 0xb8, 0x0a, 0x01, 0x02, + 0xbc, 0x0a, 0x01, 0x02, 0xc0, 0x0a, 0x01, 0x02, 0x30, 0x28, 0x02, 0x03, 0x38, 0x28, 0x02, 0x03, 0x40, 0x28, 0x02, 0x03, 0x48, 0x28, 0x02, 0x03, 0x50, 0x28, 0x02, 0x03, 0x40, 0x08, 0x03, 0x03, + 0x48, 0x08, 0x03, 0x03, 0x50, 0x08, 0x03, 0x03, 0x50, 0x24, 0x04, 0x04, 0x60, 0x24, 0x04, 0x04, 0x50, 0x05, 0x05, 0x04, 0x20, 0x21, 0x06, 0x05, 0xe0, 0x03, 0x07, 0x05, 0x80, 0x03, 0x09, 0x06, + 0x30, 0x19, 0x00, 0x03, 0x38, 0x19, 0x00, 0x03, 0x40, 0x19, 0x00, 0x03, 0x48, 0x19, 0x00, 0x03, 0xc4, 0x0a, 0x01, 0x02, 0xc8, 0x0a, 0x01, 0x02, 0xcc, 0x0a, 0x01, 0x02, 0xd0, 0x0a, 0x01, 0x02, + 0xd4, 0x0a, 0x01, 0x02, 0xd8, 0x0a, 0x01, 0x02, 0x58, 0x28, 0x02, 0x03, 0x60, 0x28, 0x02, 0x03, 0x68, 0x28, 0x02, 0x03, 0x70, 0x28, 0x02, 0x03, 0x78, 0x28, 0x02, 0x03, 0x58, 0x08, 0x03, 0x03, + 0x60, 0x08, 0x03, 0x03, 0x70, 0x24, 0x04, 0x04, 0x80, 0x24, 0x04, 0x04, 0x90, 0x24, 0x04, 0x04, 0x60, 0x05, 0x05, 0x04, 0x40, 0x21, 0x06, 0x05, 0x00, 0x04, 0x07, 0x05, 0xc0, 0x03, 0x09, 0x06, + 0x50, 0x19, 0x00, 0x03, 0x58, 0x19, 0x00, 0x03, 0x60, 0x19, 0x00, 0x03, 0x68, 0x19, 0x00, 0x03, 0xdc, 0x0a, 0x01, 0x02, 0xe0, 0x0a, 0x01, 0x02, 0xe4, 0x0a, 0x01, 0x02, 0xe8, 0x0a, 0x01, 0x02, + 0xec, 0x0a, 0x01, 0x02, 0xf0, 0x0a, 0x01, 0x02, 0x80, 0x28, 0x02, 0x03, 0x88, 0x28, 0x02, 0x03, 0x90, 0x28, 0x02, 0x03, 0x98, 0x28, 0x02, 0x03, 0x68, 0x08, 0x03, 0x03, 0x70, 0x08, 0x03, 0x03, + 0x78, 0x08, 0x03, 0x03, 0xa0, 0x24, 0x04, 0x04, 0xb0, 0x24, 0x04, 0x04, 0xc0, 0x24, 0x04, 0x04, 0x70, 0x05, 0x05, 0x04, 0x60, 0x21, 0x06, 0x05, 0x20, 0x04, 0x07, 0x05, 0x00, 0x04, 0x09, 0x06, + 0x70, 0x19, 0x00, 0x03, 0x78, 0x19, 0x00, 0x03, 0x80, 0x19, 0x00, 0x03, 0x88, 0x19, 0x00, 0x03, 0xf4, 0x0a, 0x01, 0x02, 0xf8, 0x0a, 0x01, 0x02, 0xfc, 0x0a, 0x01, 0x02, 0x00, 0x0b, 0x01, 0x02, + 0x04, 0x0b, 0x01, 0x02, 0x08, 0x0b, 0x01, 0x02, 0xa0, 0x28, 0x02, 0x03, 0xa8, 0x28, 0x02, 0x03, 0xb0, 0x28, 0x02, 0x03, 0xb8, 0x28, 0x02, 0x03, 0x80, 0x08, 0x03, 0x03, 0x88, 0x08, 0x03, 0x03, + 0x90, 0x08, 0x03, 0x03, 0xd0, 0x24, 0x04, 0x04, 0xe0, 0x24, 0x04, 0x04, 0xf0, 0x24, 0x04, 0x04, 0x80, 0x05, 0x05, 0x04, 0x80, 0x21, 0x06, 0x05, 0x40, 0x04, 0x07, 0x05, 0x40, 0x04, 0x09, 0x06, + 0x90, 0x19, 0x00, 0x03, 0x98, 0x19, 0x00, 0x03, 0xa0, 0x19, 0x00, 0x03, 0xa8, 0x19, 0x00, 0x03, 0x0c, 0x0b, 0x01, 0x02, 0x10, 0x0b, 0x01, 0x02, 0x14, 0x0b, 0x01, 0x02, 0x18, 0x0b, 0x01, 0x02, + 0x1c, 0x0b, 0x01, 0x02, 0x20, 0x0b, 0x01, 0x02, 0xc0, 0x28, 0x02, 0x03, 0xc8, 0x28, 0x02, 0x03, 0xd0, 0x28, 0x02, 0x03, 0xd8, 0x28, 0x02, 0x03, 0x98, 0x08, 0x03, 0x03, 0xa0, 0x08, 0x03, 0x03, + 0xa8, 0x08, 0x03, 0x03, 0x00, 0x25, 0x04, 0x04, 0x10, 0x25, 0x04, 0x04, 0x20, 0x25, 0x04, 0x04, 0x90, 0x05, 0x05, 0x04, 0xa0, 0x21, 0x06, 0x05, 0x60, 0x04, 0x07, 0x05, 0x80, 0x04, 0x09, 0x06, + 0xb0, 0x19, 0x00, 0x03, 0xb8, 0x19, 0x00, 0x03, 0xc0, 0x19, 0x00, 0x03, 0xc8, 0x19, 0x00, 0x03, 0x24, 0x0b, 0x01, 0x02, 0x28, 0x0b, 0x01, 0x02, 0x2c, 0x0b, 0x01, 0x02, 0x30, 0x0b, 0x01, 0x02, + 0x34, 0x0b, 0x01, 0x02, 0x38, 0x0b, 0x01, 0x02, 0xe0, 0x28, 0x02, 0x03, 0xe8, 0x28, 0x02, 0x03, 0xf0, 0x28, 0x02, 0x03, 0xf8, 0x28, 0x02, 0x03, 0xb0, 0x08, 0x03, 0x03, 0xb8, 0x08, 0x03, 0x03, + 0xc0, 0x08, 0x03, 0x03, 0x30, 0x25, 0x04, 0x04, 0x40, 0x25, 0x04, 0x04, 0x50, 0x25, 0x04, 0x04, 0xa0, 0x05, 0x05, 0x04, 0xc0, 0x21, 0x06, 0x05, 0x80, 0x04, 0x07, 0x05, 0xc0, 0x04, 0x09, 0x06, + 0xd0, 0x19, 0x00, 0x03, 0xd8, 0x19, 0x00, 0x03, 0xe0, 0x19, 0x00, 0x03, 0xe8, 0x19, 0x00, 0x03, 0x3c, 0x0b, 0x01, 0x02, 0x40, 0x0b, 0x01, 0x02, 0x44, 0x0b, 0x01, 0x02, 0x48, 0x0b, 0x01, 0x02, + 0x4c, 0x0b, 0x01, 0x02, 0x50, 0x0b, 0x01, 0x02, 0x00, 0x29, 0x02, 0x03, 0x08, 0x29, 0x02, 0x03, 0x10, 0x29, 0x02, 0x03, 0x18, 0x29, 0x02, 0x03, 0xc8, 0x08, 0x03, 0x03, 0xd0, 0x08, 0x03, 0x03, + 0xd8, 0x08, 0x03, 0x03, 0x60, 0x25, 0x04, 0x04, 0x70, 0x25, 0x04, 0x04, 0x80, 0x25, 0x04, 0x04, 0xb0, 0x05, 0x05, 0x04, 0xe0, 0x21, 0x06, 0x05, 0xa0, 0x04, 0x07, 0x05, 0x00, 0x19, 0x0a, 0x07, + 0xf0, 0x19, 0x00, 0x03, 0xf8, 0x19, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x03, 0x08, 0x1a, 0x00, 0x03, 0x54, 0x0b, 0x01, 0x02, 0x58, 0x0b, 0x01, 0x02, 0x5c, 0x0b, 0x01, 0x02, 0x60, 0x0b, 0x01, 0x02, + 0x64, 0x0b, 0x01, 0x02, 0x68, 0x0b, 0x01, 0x02, 0x20, 0x29, 0x02, 0x03, 0x28, 0x29, 0x02, 0x03, 0x30, 0x29, 0x02, 0x03, 0x38, 0x29, 0x02, 0x03, 0xe0, 0x08, 0x03, 0x03, 0xe8, 0x08, 0x03, 0x03, + 0xf0, 0x08, 0x03, 0x03, 0x90, 0x25, 0x04, 0x04, 0xa0, 0x25, 0x04, 0x04, 0xb0, 0x25, 0x04, 0x04, 0xc0, 0x05, 0x05, 0x04, 0x00, 0x22, 0x06, 0x05, 0xc0, 0x04, 0x07, 0x05, 0x80, 0x19, 0x0a, 0x07, + 0x10, 0x1a, 0x00, 0x03, 0x18, 0x1a, 0x00, 0x03, 0x20, 0x1a, 0x00, 0x03, 0x28, 0x1a, 0x00, 0x03, 0x6c, 0x0b, 0x01, 0x02, 0x70, 0x0b, 0x01, 0x02, 0x74, 0x0b, 0x01, 0x02, 0x78, 0x0b, 0x01, 0x02, + 0x7c, 0x0b, 0x01, 0x02, 0x80, 0x0b, 0x01, 0x02, 0x40, 0x29, 0x02, 0x03, 0x48, 0x29, 0x02, 0x03, 0x50, 0x29, 0x02, 0x03, 0x58, 0x29, 0x02, 0x03, 0xf8, 0x08, 0x03, 0x03, 0x00, 0x09, 0x03, 0x03, + 0x08, 0x09, 0x03, 0x03, 0xc0, 0x25, 0x04, 0x04, 0xd0, 0x25, 0x04, 0x04, 0xd0, 0x05, 0x05, 0x04, 0xe0, 0x05, 0x05, 0x04, 0x20, 0x22, 0x06, 0x05, 0xe0, 0x04, 0x07, 0x05, 0x00, 0x1a, 0x0a, 0x07, + 0x30, 0x1a, 0x00, 0x03, 0x38, 0x1a, 0x00, 0x03, 0x40, 0x1a, 0x00, 0x03, 0x48, 0x1a, 0x00, 0x03, 0x84, 0x0b, 0x01, 0x02, 0x88, 0x0b, 0x01, 0x02, 0x8c, 0x0b, 0x01, 0x02, 0x90, 0x0b, 0x01, 0x02, + 0x94, 0x0b, 0x01, 0x02, 0x98, 0x0b, 0x01, 0x02, 0x60, 0x29, 0x02, 0x03, 0x68, 0x29, 0x02, 0x03, 0x70, 0x29, 0x02, 0x03, 0x78, 0x29, 0x02, 0x03, 0x10, 0x09, 0x03, 0x03, 0x18, 0x09, 0x03, 0x03, + 0x20, 0x09, 0x03, 0x03, 0xe0, 0x25, 0x04, 0x04, 0xf0, 0x25, 0x04, 0x04, 0xf0, 0x05, 0x05, 0x04, 0x00, 0x06, 0x05, 0x04, 0x40, 0x22, 0x06, 0x05, 0x00, 0x05, 0x07, 0x05, 0x80, 0x1a, 0x0a, 0x07, + 0x50, 0x1a, 0x00, 0x03, 0x58, 0x1a, 0x00, 0x03, 0x60, 0x1a, 0x00, 0x03, 0x68, 0x1a, 0x00, 0x03, 0x9c, 0x0b, 0x01, 0x02, 0xa0, 0x0b, 0x01, 0x02, 0xa4, 0x0b, 0x01, 0x02, 0xa8, 0x0b, 0x01, 0x02, + 0xac, 0x0b, 0x01, 0x02, 0xb0, 0x0b, 0x01, 0x02, 0x80, 0x29, 0x02, 0x03, 0x88, 0x29, 0x02, 0x03, 0x90, 0x29, 0x02, 0x03, 0x98, 0x29, 0x02, 0x03, 0x28, 0x09, 0x03, 0x03, 0x30, 0x09, 0x03, 0x03, + 0x38, 0x09, 0x03, 0x03, 0x00, 0x26, 0x04, 0x04, 0x10, 0x26, 0x04, 0x04, 0x10, 0x06, 0x05, 0x04, 0x20, 0x06, 0x05, 0x04, 0x60, 0x22, 0x06, 0x05, 0x20, 0x05, 0x07, 0x05, 0x00, 0x1b, 0x0a, 0x07, + 0x70, 0x1a, 0x00, 0x03, 0x78, 0x1a, 0x00, 0x03, 0x80, 0x1a, 0x00, 0x03, 0x88, 0x1a, 0x00, 0x03, 0xb4, 0x0b, 0x01, 0x02, 0xb8, 0x0b, 0x01, 0x02, 0xbc, 0x0b, 0x01, 0x02, 0xc0, 0x0b, 0x01, 0x02, + 0xc4, 0x0b, 0x01, 0x02, 0xc8, 0x0b, 0x01, 0x02, 0xa0, 0x29, 0x02, 0x03, 0xa8, 0x29, 0x02, 0x03, 0xb0, 0x29, 0x02, 0x03, 0xb8, 0x29, 0x02, 0x03, 0x40, 0x09, 0x03, 0x03, 0x48, 0x09, 0x03, 0x03, + 0x50, 0x09, 0x03, 0x03, 0x20, 0x26, 0x04, 0x04, 0x30, 0x26, 0x04, 0x04, 0x30, 0x06, 0x05, 0x04, 0x40, 0x06, 0x05, 0x04, 0x80, 0x22, 0x06, 0x05, 0x40, 0x05, 0x07, 0x05, 0x80, 0x1b, 0x0a, 0x07, + 0x90, 0x1a, 0x00, 0x03, 0x98, 0x1a, 0x00, 0x03, 0xa0, 0x1a, 0x00, 0x03, 0xa8, 0x1a, 0x00, 0x03, 0xcc, 0x0b, 0x01, 0x02, 0xd0, 0x0b, 0x01, 0x02, 0xd4, 0x0b, 0x01, 0x02, 0xd8, 0x0b, 0x01, 0x02, + 0xdc, 0x0b, 0x01, 0x02, 0xe0, 0x0b, 0x01, 0x02, 0xc0, 0x29, 0x02, 0x03, 0xc8, 0x29, 0x02, 0x03, 0xd0, 0x29, 0x02, 0x03, 0xd8, 0x29, 0x02, 0x03, 0x58, 0x09, 0x03, 0x03, 0x60, 0x09, 0x03, 0x03, + 0x68, 0x09, 0x03, 0x03, 0x40, 0x26, 0x04, 0x04, 0x50, 0x26, 0x04, 0x04, 0x50, 0x06, 0x05, 0x04, 0x60, 0x06, 0x05, 0x04, 0xa0, 0x22, 0x06, 0x05, 0x60, 0x05, 0x07, 0x05, 0x00, 0x1c, 0x0a, 0x07, + 0xb0, 0x1a, 0x00, 0x03, 0xb8, 0x1a, 0x00, 0x03, 0xc0, 0x1a, 0x00, 0x03, 0xc8, 0x1a, 0x00, 0x03, 0xe4, 0x0b, 0x01, 0x02, 0xe8, 0x0b, 0x01, 0x02, 0xec, 0x0b, 0x01, 0x02, 0xf0, 0x0b, 0x01, 0x02, + 0xf4, 0x0b, 0x01, 0x02, 0xf8, 0x0b, 0x01, 0x02, 0xe0, 0x29, 0x02, 0x03, 0xe8, 0x29, 0x02, 0x03, 0xf0, 0x29, 0x02, 0x03, 0xf8, 0x29, 0x02, 0x03, 0x70, 0x09, 0x03, 0x03, 0x78, 0x09, 0x03, 0x03, + 0x80, 0x09, 0x03, 0x03, 0x60, 0x26, 0x04, 0x04, 0x70, 0x26, 0x04, 0x04, 0x70, 0x06, 0x05, 0x04, 0x80, 0x06, 0x05, 0x04, 0xc0, 0x22, 0x06, 0x05, 0x80, 0x05, 0x07, 0x05, 0x80, 0x1c, 0x0a, 0x07, + 0xd0, 0x1a, 0x00, 0x03, 0xd8, 0x1a, 0x00, 0x03, 0xe0, 0x1a, 0x00, 0x03, 0xe8, 0x1a, 0x00, 0x03, 0xfc, 0x0b, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x04, 0x0c, 0x01, 0x02, 0x08, 0x0c, 0x01, 0x02, + 0x0c, 0x0c, 0x01, 0x02, 0x10, 0x0c, 0x01, 0x02, 0x00, 0x2a, 0x02, 0x03, 0x08, 0x2a, 0x02, 0x03, 0x10, 0x2a, 0x02, 0x03, 0x18, 0x2a, 0x02, 0x03, 0x88, 0x09, 0x03, 0x03, 0x90, 0x09, 0x03, 0x03, + 0x98, 0x09, 0x03, 0x03, 0x80, 0x26, 0x04, 0x04, 0x90, 0x26, 0x04, 0x04, 0x90, 0x06, 0x05, 0x04, 0xa0, 0x06, 0x05, 0x04, 0xe0, 0x22, 0x06, 0x05, 0xa0, 0x05, 0x07, 0x05, 0x00, 0x1d, 0x0a, 0x07, + 0xf0, 0x1a, 0x00, 0x03, 0xf8, 0x1a, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x03, 0x08, 0x1b, 0x00, 0x03, 0x14, 0x0c, 0x01, 0x02, 0x18, 0x0c, 0x01, 0x02, 0x1c, 0x0c, 0x01, 0x02, 0x20, 0x0c, 0x01, 0x02, + 0x24, 0x0c, 0x01, 0x02, 0x28, 0x0c, 0x01, 0x02, 0x20, 0x2a, 0x02, 0x03, 0x28, 0x2a, 0x02, 0x03, 0x30, 0x2a, 0x02, 0x03, 0x38, 0x2a, 0x02, 0x03, 0xa0, 0x09, 0x03, 0x03, 0xa8, 0x09, 0x03, 0x03, + 0xb0, 0x09, 0x03, 0x03, 0xa0, 0x26, 0x04, 0x04, 0xb0, 0x26, 0x04, 0x04, 0xb0, 0x06, 0x05, 0x04, 0xc0, 0x06, 0x05, 0x04, 0x00, 0x23, 0x06, 0x05, 0xc0, 0x05, 0x07, 0x05, 0x80, 0x1d, 0x0a, 0x07, + 0x10, 0x1b, 0x00, 0x03, 0x18, 0x1b, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x03, 0x28, 0x1b, 0x00, 0x03, 0x2c, 0x0c, 0x01, 0x02, 0x30, 0x0c, 0x01, 0x02, 0x34, 0x0c, 0x01, 0x02, 0x38, 0x0c, 0x01, 0x02, + 0x3c, 0x0c, 0x01, 0x02, 0x40, 0x0c, 0x01, 0x02, 0x40, 0x2a, 0x02, 0x03, 0x48, 0x2a, 0x02, 0x03, 0x50, 0x2a, 0x02, 0x03, 0x58, 0x2a, 0x02, 0x03, 0xb8, 0x09, 0x03, 0x03, 0xc0, 0x09, 0x03, 0x03, + 0xc8, 0x09, 0x03, 0x03, 0xc0, 0x26, 0x04, 0x04, 0xd0, 0x26, 0x04, 0x04, 0xd0, 0x06, 0x05, 0x04, 0xe0, 0x06, 0x05, 0x04, 0x20, 0x23, 0x06, 0x05, 0xe0, 0x05, 0x07, 0x05, 0x00, 0x1e, 0x0a, 0x07, + 0x30, 0x1b, 0x00, 0x03, 0x38, 0x1b, 0x00, 0x03, 0x40, 0x1b, 0x00, 0x03, 0x48, 0x1b, 0x00, 0x03, 0x44, 0x0c, 0x01, 0x02, 0x48, 0x0c, 0x01, 0x02, 0x4c, 0x0c, 0x01, 0x02, 0x50, 0x0c, 0x01, 0x02, + 0x54, 0x0c, 0x01, 0x02, 0x58, 0x0c, 0x01, 0x02, 0x60, 0x2a, 0x02, 0x03, 0x68, 0x2a, 0x02, 0x03, 0x70, 0x2a, 0x02, 0x03, 0x78, 0x2a, 0x02, 0x03, 0xd0, 0x09, 0x03, 0x03, 0xd8, 0x09, 0x03, 0x03, + 0xe0, 0x09, 0x03, 0x03, 0xe0, 0x26, 0x04, 0x04, 0xf0, 0x26, 0x04, 0x04, 0xf0, 0x06, 0x05, 0x04, 0x00, 0x07, 0x05, 0x04, 0x40, 0x23, 0x06, 0x05, 0x00, 0x06, 0x07, 0x05, 0x80, 0x1e, 0x0a, 0x07, + 0x50, 0x1b, 0x00, 0x03, 0x58, 0x1b, 0x00, 0x03, 0x60, 0x1b, 0x00, 0x03, 0x68, 0x1b, 0x00, 0x03, 0x5c, 0x0c, 0x01, 0x02, 0x60, 0x0c, 0x01, 0x02, 0x64, 0x0c, 0x01, 0x02, 0x68, 0x0c, 0x01, 0x02, + 0x6c, 0x0c, 0x01, 0x02, 0x70, 0x0c, 0x01, 0x02, 0x80, 0x2a, 0x02, 0x03, 0x88, 0x2a, 0x02, 0x03, 0x90, 0x2a, 0x02, 0x03, 0x98, 0x2a, 0x02, 0x03, 0xe8, 0x09, 0x03, 0x03, 0xf0, 0x09, 0x03, 0x03, + 0xf8, 0x09, 0x03, 0x03, 0x00, 0x27, 0x04, 0x04, 0x10, 0x27, 0x04, 0x04, 0x10, 0x07, 0x05, 0x04, 0x20, 0x07, 0x05, 0x04, 0x60, 0x23, 0x06, 0x05, 0x20, 0x06, 0x07, 0x05, 0x00, 0x1f, 0x0a, 0x07, + 0x70, 0x1b, 0x00, 0x03, 0x78, 0x1b, 0x00, 0x03, 0x80, 0x1b, 0x00, 0x03, 0x88, 0x1b, 0x00, 0x03, 0x74, 0x0c, 0x01, 0x02, 0x78, 0x0c, 0x01, 0x02, 0x7c, 0x0c, 0x01, 0x02, 0x80, 0x0c, 0x01, 0x02, + 0x84, 0x0c, 0x01, 0x02, 0x88, 0x0c, 0x01, 0x02, 0xa0, 0x2a, 0x02, 0x03, 0xa8, 0x2a, 0x02, 0x03, 0xb0, 0x2a, 0x02, 0x03, 0xb8, 0x2a, 0x02, 0x03, 0x00, 0x0a, 0x03, 0x03, 0x08, 0x0a, 0x03, 0x03, + 0x10, 0x0a, 0x03, 0x03, 0x20, 0x27, 0x04, 0x04, 0x30, 0x27, 0x04, 0x04, 0x30, 0x07, 0x05, 0x04, 0x40, 0x07, 0x05, 0x04, 0x80, 0x23, 0x06, 0x05, 0x40, 0x06, 0x07, 0x05, 0x80, 0x1f, 0x0a, 0x07, + 0x90, 0x1b, 0x00, 0x03, 0x98, 0x1b, 0x00, 0x03, 0xa0, 0x1b, 0x00, 0x03, 0xa8, 0x1b, 0x00, 0x03, 0x8c, 0x0c, 0x01, 0x02, 0x90, 0x0c, 0x01, 0x02, 0x94, 0x0c, 0x01, 0x02, 0x98, 0x0c, 0x01, 0x02, + 0x9c, 0x0c, 0x01, 0x02, 0xa0, 0x0c, 0x01, 0x02, 0xc0, 0x2a, 0x02, 0x03, 0xc8, 0x2a, 0x02, 0x03, 0xd0, 0x2a, 0x02, 0x03, 0xd8, 0x2a, 0x02, 0x03, 0x18, 0x0a, 0x03, 0x03, 0x20, 0x0a, 0x03, 0x03, + 0x28, 0x0a, 0x03, 0x03, 0x40, 0x27, 0x04, 0x04, 0x50, 0x27, 0x04, 0x04, 0x50, 0x07, 0x05, 0x04, 0x60, 0x07, 0x05, 0x04, 0xa0, 0x23, 0x06, 0x05, 0x60, 0x06, 0x07, 0x05, 0x00, 0x20, 0x0a, 0x07, + 0xb0, 0x1b, 0x00, 0x03, 0xb8, 0x1b, 0x00, 0x03, 0xc0, 0x1b, 0x00, 0x03, 0xc8, 0x1b, 0x00, 0x03, 0xa4, 0x0c, 0x01, 0x02, 0xa8, 0x0c, 0x01, 0x02, 0xac, 0x0c, 0x01, 0x02, 0xb0, 0x0c, 0x01, 0x02, + 0xb4, 0x0c, 0x01, 0x02, 0xb8, 0x0c, 0x01, 0x02, 0xe0, 0x2a, 0x02, 0x03, 0xe8, 0x2a, 0x02, 0x03, 0xf0, 0x2a, 0x02, 0x03, 0xf8, 0x2a, 0x02, 0x03, 0x30, 0x0a, 0x03, 0x03, 0x38, 0x0a, 0x03, 0x03, + 0x40, 0x0a, 0x03, 0x03, 0x60, 0x27, 0x04, 0x04, 0x70, 0x27, 0x04, 0x04, 0x70, 0x07, 0x05, 0x04, 0x80, 0x07, 0x05, 0x04, 0xc0, 0x23, 0x06, 0x05, 0x00, 0x1c, 0x08, 0x06, 0x80, 0x20, 0x0a, 0x07, + 0xd0, 0x1b, 0x00, 0x03, 0xd8, 0x1b, 0x00, 0x03, 0xe0, 0x1b, 0x00, 0x03, 0xe8, 0x1b, 0x00, 0x03, 0xbc, 0x0c, 0x01, 0x02, 0xc0, 0x0c, 0x01, 0x02, 0xc4, 0x0c, 0x01, 0x02, 0xc8, 0x0c, 0x01, 0x02, + 0xcc, 0x0c, 0x01, 0x02, 0xd0, 0x0c, 0x01, 0x02, 0x00, 0x2b, 0x02, 0x03, 0x08, 0x2b, 0x02, 0x03, 0x10, 0x2b, 0x02, 0x03, 0x18, 0x2b, 0x02, 0x03, 0x48, 0x0a, 0x03, 0x03, 0x50, 0x0a, 0x03, 0x03, + 0x58, 0x0a, 0x03, 0x03, 0x80, 0x27, 0x04, 0x04, 0x90, 0x27, 0x04, 0x04, 0x90, 0x07, 0x05, 0x04, 0xa0, 0x07, 0x05, 0x04, 0xe0, 0x23, 0x06, 0x05, 0x40, 0x1c, 0x08, 0x06, 0x00, 0x21, 0x0a, 0x07, + 0xf0, 0x1b, 0x00, 0x03, 0xf8, 0x1b, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x03, 0x08, 0x1c, 0x00, 0x03, 0xd4, 0x0c, 0x01, 0x02, 0xd8, 0x0c, 0x01, 0x02, 0xdc, 0x0c, 0x01, 0x02, 0xe0, 0x0c, 0x01, 0x02, + 0xe4, 0x0c, 0x01, 0x02, 0xe8, 0x0c, 0x01, 0x02, 0x20, 0x2b, 0x02, 0x03, 0x28, 0x2b, 0x02, 0x03, 0x30, 0x2b, 0x02, 0x03, 0x38, 0x2b, 0x02, 0x03, 0x60, 0x0a, 0x03, 0x03, 0x68, 0x0a, 0x03, 0x03, + 0x70, 0x0a, 0x03, 0x03, 0xa0, 0x27, 0x04, 0x04, 0xb0, 0x27, 0x04, 0x04, 0xb0, 0x07, 0x05, 0x04, 0xc0, 0x07, 0x05, 0x04, 0x00, 0x24, 0x06, 0x05, 0x80, 0x1c, 0x08, 0x06, 0x80, 0x21, 0x0a, 0x07, + 0x10, 0x1c, 0x00, 0x03, 0x18, 0x1c, 0x00, 0x03, 0x20, 0x1c, 0x00, 0x03, 0x28, 0x1c, 0x00, 0x03, 0xec, 0x0c, 0x01, 0x02, 0xf0, 0x0c, 0x01, 0x02, 0xf4, 0x0c, 0x01, 0x02, 0xf8, 0x0c, 0x01, 0x02, + 0xfc, 0x0c, 0x01, 0x02, 0x00, 0x0d, 0x01, 0x02, 0x40, 0x2b, 0x02, 0x03, 0x48, 0x2b, 0x02, 0x03, 0x50, 0x2b, 0x02, 0x03, 0x58, 0x2b, 0x02, 0x03, 0x78, 0x0a, 0x03, 0x03, 0x80, 0x0a, 0x03, 0x03, + 0x88, 0x0a, 0x03, 0x03, 0xc0, 0x27, 0x04, 0x04, 0xd0, 0x27, 0x04, 0x04, 0xd0, 0x07, 0x05, 0x04, 0xe0, 0x07, 0x05, 0x04, 0x20, 0x24, 0x06, 0x05, 0xc0, 0x1c, 0x08, 0x06, 0x00, 0x22, 0x0a, 0x07, + 0x30, 0x1c, 0x00, 0x03, 0x38, 0x1c, 0x00, 0x03, 0x40, 0x1c, 0x00, 0x03, 0x48, 0x1c, 0x00, 0x03, 0x04, 0x0d, 0x01, 0x02, 0x08, 0x0d, 0x01, 0x02, 0x0c, 0x0d, 0x01, 0x02, 0x10, 0x0d, 0x01, 0x02, + 0x14, 0x0d, 0x01, 0x02, 0x18, 0x0d, 0x01, 0x02, 0x60, 0x2b, 0x02, 0x03, 0x68, 0x2b, 0x02, 0x03, 0x70, 0x2b, 0x02, 0x03, 0x78, 0x2b, 0x02, 0x03, 0x90, 0x0a, 0x03, 0x03, 0x98, 0x0a, 0x03, 0x03, + 0xa0, 0x0a, 0x03, 0x03, 0xe0, 0x27, 0x04, 0x04, 0xf0, 0x27, 0x04, 0x04, 0xf0, 0x07, 0x05, 0x04, 0x00, 0x08, 0x05, 0x04, 0x40, 0x24, 0x06, 0x05, 0x00, 0x1d, 0x08, 0x06, 0x80, 0x22, 0x0a, 0x07, + 0x50, 0x1c, 0x00, 0x03, 0x58, 0x1c, 0x00, 0x03, 0x60, 0x1c, 0x00, 0x03, 0x68, 0x1c, 0x00, 0x03, 0x1c, 0x0d, 0x01, 0x02, 0x20, 0x0d, 0x01, 0x02, 0x24, 0x0d, 0x01, 0x02, 0x28, 0x0d, 0x01, 0x02, + 0x2c, 0x0d, 0x01, 0x02, 0x30, 0x0d, 0x01, 0x02, 0x80, 0x2b, 0x02, 0x03, 0x88, 0x2b, 0x02, 0x03, 0x90, 0x2b, 0x02, 0x03, 0x98, 0x2b, 0x02, 0x03, 0xa8, 0x0a, 0x03, 0x03, 0xb0, 0x0a, 0x03, 0x03, + 0xb8, 0x0a, 0x03, 0x03, 0x00, 0x28, 0x04, 0x04, 0x10, 0x28, 0x04, 0x04, 0x10, 0x08, 0x05, 0x04, 0x20, 0x08, 0x05, 0x04, 0x60, 0x24, 0x06, 0x05, 0x40, 0x1d, 0x08, 0x06, 0x00, 0x3c, 0x0b, 0x08, + 0x70, 0x1c, 0x00, 0x03, 0x78, 0x1c, 0x00, 0x03, 0x80, 0x1c, 0x00, 0x03, 0x88, 0x1c, 0x00, 0x03, 0x34, 0x0d, 0x01, 0x02, 0x38, 0x0d, 0x01, 0x02, 0x3c, 0x0d, 0x01, 0x02, 0x40, 0x0d, 0x01, 0x02, + 0x44, 0x0d, 0x01, 0x02, 0x48, 0x0d, 0x01, 0x02, 0xa0, 0x2b, 0x02, 0x03, 0xa8, 0x2b, 0x02, 0x03, 0xb0, 0x2b, 0x02, 0x03, 0xb8, 0x2b, 0x02, 0x03, 0xc0, 0x0a, 0x03, 0x03, 0xc8, 0x0a, 0x03, 0x03, + 0xd0, 0x0a, 0x03, 0x03, 0x20, 0x28, 0x04, 0x04, 0x30, 0x28, 0x04, 0x04, 0x30, 0x08, 0x05, 0x04, 0x40, 0x08, 0x05, 0x04, 0x80, 0x24, 0x06, 0x05, 0x80, 0x1d, 0x08, 0x06, 0x00, 0x3d, 0x0b, 0x08, + 0x90, 0x1c, 0x00, 0x03, 0x98, 0x1c, 0x00, 0x03, 0xa0, 0x1c, 0x00, 0x03, 0xa8, 0x1c, 0x00, 0x03, 0x4c, 0x0d, 0x01, 0x02, 0x50, 0x0d, 0x01, 0x02, 0x54, 0x0d, 0x01, 0x02, 0x58, 0x0d, 0x01, 0x02, + 0x5c, 0x0d, 0x01, 0x02, 0x60, 0x0d, 0x01, 0x02, 0xc0, 0x2b, 0x02, 0x03, 0xc8, 0x2b, 0x02, 0x03, 0xd0, 0x2b, 0x02, 0x03, 0xd8, 0x2b, 0x02, 0x03, 0xd8, 0x0a, 0x03, 0x03, 0xe0, 0x0a, 0x03, 0x03, + 0xe8, 0x0a, 0x03, 0x03, 0x40, 0x28, 0x04, 0x04, 0x50, 0x28, 0x04, 0x04, 0x50, 0x08, 0x05, 0x04, 0x60, 0x08, 0x05, 0x04, 0xa0, 0x24, 0x06, 0x05, 0xc0, 0x1d, 0x08, 0x06, 0x00, 0x3e, 0x0b, 0x08, + 0xb0, 0x1c, 0x00, 0x03, 0xb8, 0x1c, 0x00, 0x03, 0xc0, 0x1c, 0x00, 0x03, 0xc8, 0x1c, 0x00, 0x03, 0x64, 0x0d, 0x01, 0x02, 0x68, 0x0d, 0x01, 0x02, 0x6c, 0x0d, 0x01, 0x02, 0x70, 0x0d, 0x01, 0x02, + 0x74, 0x0d, 0x01, 0x02, 0x78, 0x0d, 0x01, 0x02, 0xe0, 0x2b, 0x02, 0x03, 0xe8, 0x2b, 0x02, 0x03, 0xf0, 0x2b, 0x02, 0x03, 0xf8, 0x2b, 0x02, 0x03, 0xf0, 0x0a, 0x03, 0x03, 0xf8, 0x0a, 0x03, 0x03, + 0x00, 0x0b, 0x03, 0x03, 0x60, 0x28, 0x04, 0x04, 0x70, 0x28, 0x04, 0x04, 0x70, 0x08, 0x05, 0x04, 0x80, 0x08, 0x05, 0x04, 0xc0, 0x24, 0x06, 0x05, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x3f, 0x0b, 0x08, + 0xd0, 0x1c, 0x00, 0x03, 0xd8, 0x1c, 0x00, 0x03, 0xe0, 0x1c, 0x00, 0x03, 0xe8, 0x1c, 0x00, 0x03, 0x7c, 0x0d, 0x01, 0x02, 0x80, 0x0d, 0x01, 0x02, 0x84, 0x0d, 0x01, 0x02, 0x88, 0x0d, 0x01, 0x02, + 0x8c, 0x0d, 0x01, 0x02, 0x90, 0x0d, 0x01, 0x02, 0x00, 0x2c, 0x02, 0x03, 0x08, 0x2c, 0x02, 0x03, 0x10, 0x2c, 0x02, 0x03, 0x18, 0x2c, 0x02, 0x03, 0x08, 0x0b, 0x03, 0x03, 0x10, 0x0b, 0x03, 0x03, + 0x18, 0x0b, 0x03, 0x03, 0x80, 0x28, 0x04, 0x04, 0x90, 0x28, 0x04, 0x04, 0x90, 0x08, 0x05, 0x04, 0xa0, 0x08, 0x05, 0x04, 0xe0, 0x24, 0x06, 0x05, 0x40, 0x1e, 0x08, 0x06, 0x00, 0x00, 0x0b, 0x07, + 0xf0, 0x1c, 0x00, 0x03, 0xf8, 0x1c, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x03, 0x08, 0x1d, 0x00, 0x03, 0x94, 0x0d, 0x01, 0x02, 0x98, 0x0d, 0x01, 0x02, 0x9c, 0x0d, 0x01, 0x02, 0xa0, 0x0d, 0x01, 0x02, + 0xa4, 0x0d, 0x01, 0x02, 0xa8, 0x0d, 0x01, 0x02, 0x20, 0x2c, 0x02, 0x03, 0x28, 0x2c, 0x02, 0x03, 0x30, 0x2c, 0x02, 0x03, 0x38, 0x2c, 0x02, 0x03, 0x20, 0x0b, 0x03, 0x03, 0x28, 0x0b, 0x03, 0x03, + 0x30, 0x0b, 0x03, 0x03, 0xa0, 0x28, 0x04, 0x04, 0xb0, 0x28, 0x04, 0x04, 0xb0, 0x08, 0x05, 0x04, 0xc0, 0x08, 0x05, 0x04, 0x00, 0x25, 0x06, 0x05, 0x80, 0x1e, 0x08, 0x06, 0x80, 0x00, 0x0b, 0x07, + 0x10, 0x1d, 0x00, 0x03, 0x18, 0x1d, 0x00, 0x03, 0x20, 0x1d, 0x00, 0x03, 0x28, 0x1d, 0x00, 0x03, 0xac, 0x0d, 0x01, 0x02, 0xb0, 0x0d, 0x01, 0x02, 0xb4, 0x0d, 0x01, 0x02, 0xb8, 0x0d, 0x01, 0x02, + 0xbc, 0x0d, 0x01, 0x02, 0xc0, 0x0d, 0x01, 0x02, 0x40, 0x2c, 0x02, 0x03, 0x48, 0x2c, 0x02, 0x03, 0x50, 0x2c, 0x02, 0x03, 0x58, 0x2c, 0x02, 0x03, 0x38, 0x0b, 0x03, 0x03, 0x40, 0x0b, 0x03, 0x03, + 0x48, 0x0b, 0x03, 0x03, 0xc0, 0x28, 0x04, 0x04, 0xd0, 0x28, 0x04, 0x04, 0xd0, 0x08, 0x05, 0x04, 0xe0, 0x08, 0x05, 0x04, 0x20, 0x25, 0x06, 0x05, 0xc0, 0x1e, 0x08, 0x06, 0x00, 0x01, 0x0b, 0x07, + 0x30, 0x1d, 0x00, 0x03, 0x38, 0x1d, 0x00, 0x03, 0x40, 0x1d, 0x00, 0x03, 0x48, 0x1d, 0x00, 0x03, 0xc4, 0x0d, 0x01, 0x02, 0xc8, 0x0d, 0x01, 0x02, 0xcc, 0x0d, 0x01, 0x02, 0xd0, 0x0d, 0x01, 0x02, + 0xd4, 0x0d, 0x01, 0x02, 0xd8, 0x0d, 0x01, 0x02, 0x60, 0x2c, 0x02, 0x03, 0x68, 0x2c, 0x02, 0x03, 0x70, 0x2c, 0x02, 0x03, 0x78, 0x2c, 0x02, 0x03, 0x50, 0x0b, 0x03, 0x03, 0x58, 0x0b, 0x03, 0x03, + 0x60, 0x0b, 0x03, 0x03, 0xe0, 0x28, 0x04, 0x04, 0xf0, 0x28, 0x04, 0x04, 0xf0, 0x08, 0x05, 0x04, 0x00, 0x09, 0x05, 0x04, 0x40, 0x25, 0x06, 0x05, 0x00, 0x1f, 0x08, 0x06, 0x80, 0x01, 0x0b, 0x07, + 0x50, 0x1d, 0x00, 0x03, 0x58, 0x1d, 0x00, 0x03, 0x60, 0x1d, 0x00, 0x03, 0x68, 0x1d, 0x00, 0x03, 0xdc, 0x0d, 0x01, 0x02, 0xe0, 0x0d, 0x01, 0x02, 0xe4, 0x0d, 0x01, 0x02, 0xe8, 0x0d, 0x01, 0x02, + 0xec, 0x0d, 0x01, 0x02, 0xf0, 0x0d, 0x01, 0x02, 0x80, 0x2c, 0x02, 0x03, 0x88, 0x2c, 0x02, 0x03, 0x90, 0x2c, 0x02, 0x03, 0x98, 0x2c, 0x02, 0x03, 0x68, 0x0b, 0x03, 0x03, 0x70, 0x0b, 0x03, 0x03, + 0x78, 0x0b, 0x03, 0x03, 0x00, 0x29, 0x04, 0x04, 0x10, 0x29, 0x04, 0x04, 0x10, 0x09, 0x05, 0x04, 0x20, 0x09, 0x05, 0x04, 0x60, 0x25, 0x06, 0x05, 0x40, 0x1f, 0x08, 0x06, 0x00, 0x02, 0x0b, 0x07, + 0x70, 0x1d, 0x00, 0x03, 0x78, 0x1d, 0x00, 0x03, 0x80, 0x1d, 0x00, 0x03, 0x88, 0x1d, 0x00, 0x03, 0xf4, 0x0d, 0x01, 0x02, 0xf8, 0x0d, 0x01, 0x02, 0xfc, 0x0d, 0x01, 0x02, 0x00, 0x0e, 0x01, 0x02, + 0x04, 0x0e, 0x01, 0x02, 0x08, 0x0e, 0x01, 0x02, 0xa0, 0x2c, 0x02, 0x03, 0xa8, 0x2c, 0x02, 0x03, 0xb0, 0x2c, 0x02, 0x03, 0xb8, 0x2c, 0x02, 0x03, 0x80, 0x0b, 0x03, 0x03, 0x88, 0x0b, 0x03, 0x03, + 0x90, 0x0b, 0x03, 0x03, 0x20, 0x29, 0x04, 0x04, 0x30, 0x29, 0x04, 0x04, 0x30, 0x09, 0x05, 0x04, 0x40, 0x09, 0x05, 0x04, 0x80, 0x25, 0x06, 0x05, 0x80, 0x1f, 0x08, 0x06, 0x80, 0x02, 0x0b, 0x07, + 0x90, 0x1d, 0x00, 0x03, 0x98, 0x1d, 0x00, 0x03, 0xa0, 0x1d, 0x00, 0x03, 0xa8, 0x1d, 0x00, 0x03, 0x0c, 0x0e, 0x01, 0x02, 0x10, 0x0e, 0x01, 0x02, 0x14, 0x0e, 0x01, 0x02, 0x18, 0x0e, 0x01, 0x02, + 0x1c, 0x0e, 0x01, 0x02, 0x20, 0x0e, 0x01, 0x02, 0xc0, 0x2c, 0x02, 0x03, 0xc8, 0x2c, 0x02, 0x03, 0xd0, 0x2c, 0x02, 0x03, 0xd8, 0x2c, 0x02, 0x03, 0x98, 0x0b, 0x03, 0x03, 0xa0, 0x0b, 0x03, 0x03, + 0xa8, 0x0b, 0x03, 0x03, 0x40, 0x29, 0x04, 0x04, 0x50, 0x29, 0x04, 0x04, 0x50, 0x09, 0x05, 0x04, 0x60, 0x09, 0x05, 0x04, 0xa0, 0x25, 0x06, 0x05, 0xc0, 0x1f, 0x08, 0x06, 0x00, 0x03, 0x0b, 0x07, + 0xb0, 0x1d, 0x00, 0x03, 0xb8, 0x1d, 0x00, 0x03, 0xc0, 0x1d, 0x00, 0x03, 0xc8, 0x1d, 0x00, 0x03, 0x24, 0x0e, 0x01, 0x02, 0x28, 0x0e, 0x01, 0x02, 0x2c, 0x0e, 0x01, 0x02, 0x30, 0x0e, 0x01, 0x02, + 0x34, 0x0e, 0x01, 0x02, 0x38, 0x0e, 0x01, 0x02, 0xe0, 0x2c, 0x02, 0x03, 0xe8, 0x2c, 0x02, 0x03, 0xf0, 0x2c, 0x02, 0x03, 0xf8, 0x2c, 0x02, 0x03, 0xb0, 0x0b, 0x03, 0x03, 0xb8, 0x0b, 0x03, 0x03, + 0xc0, 0x0b, 0x03, 0x03, 0x60, 0x29, 0x04, 0x04, 0x70, 0x29, 0x04, 0x04, 0x70, 0x09, 0x05, 0x04, 0x80, 0x09, 0x05, 0x04, 0xc0, 0x25, 0x06, 0x05, 0x00, 0x20, 0x08, 0x06, 0x80, 0x03, 0x0b, 0x07, + 0xd0, 0x1d, 0x00, 0x03, 0xd8, 0x1d, 0x00, 0x03, 0xe0, 0x1d, 0x00, 0x03, 0xe8, 0x1d, 0x00, 0x03, 0x3c, 0x0e, 0x01, 0x02, 0x40, 0x0e, 0x01, 0x02, 0x44, 0x0e, 0x01, 0x02, 0x48, 0x0e, 0x01, 0x02, + 0x4c, 0x0e, 0x01, 0x02, 0x50, 0x0e, 0x01, 0x02, 0x00, 0x2d, 0x02, 0x03, 0x08, 0x2d, 0x02, 0x03, 0x10, 0x2d, 0x02, 0x03, 0x18, 0x2d, 0x02, 0x03, 0xc8, 0x0b, 0x03, 0x03, 0xd0, 0x0b, 0x03, 0x03, + 0xd8, 0x0b, 0x03, 0x03, 0x80, 0x29, 0x04, 0x04, 0x90, 0x29, 0x04, 0x04, 0x90, 0x09, 0x05, 0x04, 0xa0, 0x09, 0x05, 0x04, 0xe0, 0x25, 0x06, 0x05, 0x40, 0x20, 0x08, 0x06, 0x00, 0x04, 0x0b, 0x07, + 0xf0, 0x1d, 0x00, 0x03, 0xf8, 0x1d, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x03, 0x08, 0x1e, 0x00, 0x03, 0x54, 0x0e, 0x01, 0x02, 0x58, 0x0e, 0x01, 0x02, 0x5c, 0x0e, 0x01, 0x02, 0x60, 0x0e, 0x01, 0x02, + 0x64, 0x0e, 0x01, 0x02, 0x68, 0x0e, 0x01, 0x02, 0x20, 0x2d, 0x02, 0x03, 0x28, 0x2d, 0x02, 0x03, 0x30, 0x2d, 0x02, 0x03, 0x38, 0x2d, 0x02, 0x03, 0xe0, 0x0b, 0x03, 0x03, 0xe8, 0x0b, 0x03, 0x03, + 0xf0, 0x0b, 0x03, 0x03, 0xa0, 0x29, 0x04, 0x04, 0xb0, 0x29, 0x04, 0x04, 0xb0, 0x09, 0x05, 0x04, 0xc0, 0x09, 0x05, 0x04, 0x00, 0x26, 0x06, 0x05, 0x80, 0x20, 0x08, 0x06, 0x00, 0x15, 0x0c, 0x08, + 0x10, 0x1e, 0x00, 0x03, 0x18, 0x1e, 0x00, 0x03, 0x20, 0x1e, 0x00, 0x03, 0x28, 0x1e, 0x00, 0x03, 0x6c, 0x0e, 0x01, 0x02, 0x70, 0x0e, 0x01, 0x02, 0x74, 0x0e, 0x01, 0x02, 0x78, 0x0e, 0x01, 0x02, + 0x7c, 0x0e, 0x01, 0x02, 0x80, 0x0e, 0x01, 0x02, 0x40, 0x2d, 0x02, 0x03, 0x48, 0x2d, 0x02, 0x03, 0x50, 0x2d, 0x02, 0x03, 0x58, 0x2d, 0x02, 0x03, 0xf8, 0x0b, 0x03, 0x03, 0x00, 0x0c, 0x03, 0x03, + 0x08, 0x0c, 0x03, 0x03, 0xc0, 0x29, 0x04, 0x04, 0xd0, 0x29, 0x04, 0x04, 0xd0, 0x09, 0x05, 0x04, 0xe0, 0x09, 0x05, 0x04, 0x20, 0x26, 0x06, 0x05, 0xc0, 0x20, 0x08, 0x06, 0x00, 0x16, 0x0c, 0x08, + 0x30, 0x1e, 0x00, 0x03, 0x38, 0x1e, 0x00, 0x03, 0x40, 0x1e, 0x00, 0x03, 0x48, 0x1e, 0x00, 0x03, 0x84, 0x0e, 0x01, 0x02, 0x88, 0x0e, 0x01, 0x02, 0x8c, 0x0e, 0x01, 0x02, 0x90, 0x0e, 0x01, 0x02, + 0x94, 0x0e, 0x01, 0x02, 0x98, 0x0e, 0x01, 0x02, 0x60, 0x2d, 0x02, 0x03, 0x68, 0x2d, 0x02, 0x03, 0x70, 0x2d, 0x02, 0x03, 0x78, 0x2d, 0x02, 0x03, 0x10, 0x0c, 0x03, 0x03, 0x18, 0x0c, 0x03, 0x03, + 0x20, 0x0c, 0x03, 0x03, 0xe0, 0x29, 0x04, 0x04, 0xf0, 0x29, 0x04, 0x04, 0xf0, 0x09, 0x05, 0x04, 0x00, 0x0a, 0x05, 0x04, 0x40, 0x26, 0x06, 0x05, 0x00, 0x21, 0x08, 0x06, 0x00, 0x17, 0x0c, 0x08, + 0x50, 0x1e, 0x00, 0x03, 0x58, 0x1e, 0x00, 0x03, 0x60, 0x1e, 0x00, 0x03, 0x68, 0x1e, 0x00, 0x03, 0x9c, 0x0e, 0x01, 0x02, 0xa0, 0x0e, 0x01, 0x02, 0xa4, 0x0e, 0x01, 0x02, 0xa8, 0x0e, 0x01, 0x02, + 0xac, 0x0e, 0x01, 0x02, 0xb0, 0x0e, 0x01, 0x02, 0x80, 0x2d, 0x02, 0x03, 0x88, 0x2d, 0x02, 0x03, 0x90, 0x2d, 0x02, 0x03, 0x98, 0x2d, 0x02, 0x03, 0x28, 0x0c, 0x03, 0x03, 0x30, 0x0c, 0x03, 0x03, + 0x38, 0x0c, 0x03, 0x03, 0x00, 0x2a, 0x04, 0x04, 0x10, 0x2a, 0x04, 0x04, 0x10, 0x0a, 0x05, 0x04, 0x20, 0x0a, 0x05, 0x04, 0x60, 0x26, 0x06, 0x05, 0x40, 0x21, 0x08, 0x06, 0x00, 0x18, 0x0c, 0x08, + 0x70, 0x1e, 0x00, 0x03, 0x78, 0x1e, 0x00, 0x03, 0x80, 0x1e, 0x00, 0x03, 0x88, 0x1e, 0x00, 0x03, 0xb4, 0x0e, 0x01, 0x02, 0xb8, 0x0e, 0x01, 0x02, 0xbc, 0x0e, 0x01, 0x02, 0xc0, 0x0e, 0x01, 0x02, + 0xc4, 0x0e, 0x01, 0x02, 0xc8, 0x0e, 0x01, 0x02, 0xa0, 0x2d, 0x02, 0x03, 0xa8, 0x2d, 0x02, 0x03, 0xb0, 0x2d, 0x02, 0x03, 0xb8, 0x2d, 0x02, 0x03, 0x40, 0x0c, 0x03, 0x03, 0x48, 0x0c, 0x03, 0x03, + 0x50, 0x0c, 0x03, 0x03, 0x20, 0x2a, 0x04, 0x04, 0x30, 0x2a, 0x04, 0x04, 0x30, 0x0a, 0x05, 0x04, 0x40, 0x0a, 0x05, 0x04, 0x80, 0x26, 0x06, 0x05, 0x80, 0x21, 0x08, 0x06, 0x00, 0x19, 0x0c, 0x08, + 0x90, 0x1e, 0x00, 0x03, 0x98, 0x1e, 0x00, 0x03, 0xa0, 0x1e, 0x00, 0x03, 0xcc, 0x0e, 0x01, 0x02, 0xd0, 0x0e, 0x01, 0x02, 0xd4, 0x0e, 0x01, 0x02, 0xd8, 0x0e, 0x01, 0x02, 0xdc, 0x0e, 0x01, 0x02, + 0xe0, 0x0e, 0x01, 0x02, 0xe4, 0x0e, 0x01, 0x02, 0xc0, 0x2d, 0x02, 0x03, 0xc8, 0x2d, 0x02, 0x03, 0xd0, 0x2d, 0x02, 0x03, 0xd8, 0x2d, 0x02, 0x03, 0x58, 0x0c, 0x03, 0x03, 0x60, 0x0c, 0x03, 0x03, + 0x68, 0x0c, 0x03, 0x03, 0x40, 0x2a, 0x04, 0x04, 0x50, 0x2a, 0x04, 0x04, 0x50, 0x0a, 0x05, 0x04, 0x60, 0x0a, 0x05, 0x04, 0xa0, 0x26, 0x06, 0x05, 0xc0, 0x21, 0x08, 0x06, 0x00, 0x1a, 0x0c, 0x08, + 0xa8, 0x1e, 0x00, 0x03, 0xb0, 0x1e, 0x00, 0x03, 0xb8, 0x1e, 0x00, 0x03, 0xe8, 0x0e, 0x01, 0x02, 0xec, 0x0e, 0x01, 0x02, 0xf0, 0x0e, 0x01, 0x02, 0xf4, 0x0e, 0x01, 0x02, 0xf8, 0x0e, 0x01, 0x02, + 0xfc, 0x0e, 0x01, 0x02, 0x00, 0x0f, 0x01, 0x02, 0xe0, 0x2d, 0x02, 0x03, 0xe8, 0x2d, 0x02, 0x03, 0xf0, 0x2d, 0x02, 0x03, 0xf8, 0x2d, 0x02, 0x03, 0x70, 0x0c, 0x03, 0x03, 0x78, 0x0c, 0x03, 0x03, + 0x80, 0x0c, 0x03, 0x03, 0x60, 0x2a, 0x04, 0x04, 0x70, 0x2a, 0x04, 0x04, 0x70, 0x0a, 0x05, 0x04, 0x80, 0x0a, 0x05, 0x04, 0xc0, 0x26, 0x06, 0x05, 0x00, 0x22, 0x08, 0x06, 0x00, 0x1b, 0x0c, 0x08, + 0xc0, 0x1e, 0x00, 0x03, 0xc8, 0x1e, 0x00, 0x03, 0xd0, 0x1e, 0x00, 0x03, 0x04, 0x0f, 0x01, 0x02, 0x08, 0x0f, 0x01, 0x02, 0x0c, 0x0f, 0x01, 0x02, 0x10, 0x0f, 0x01, 0x02, 0x14, 0x0f, 0x01, 0x02, + 0x18, 0x0f, 0x01, 0x02, 0x1c, 0x0f, 0x01, 0x02, 0x00, 0x2e, 0x02, 0x03, 0x08, 0x2e, 0x02, 0x03, 0x10, 0x2e, 0x02, 0x03, 0x18, 0x2e, 0x02, 0x03, 0x88, 0x0c, 0x03, 0x03, 0x90, 0x0c, 0x03, 0x03, + 0x98, 0x0c, 0x03, 0x03, 0x80, 0x2a, 0x04, 0x04, 0x90, 0x2a, 0x04, 0x04, 0x90, 0x0a, 0x05, 0x04, 0xe0, 0x26, 0x06, 0x05, 0x80, 0x06, 0x07, 0x05, 0x40, 0x22, 0x08, 0x06, 0x00, 0x1c, 0x0c, 0x08, + 0xd8, 0x1e, 0x00, 0x03, 0xe0, 0x1e, 0x00, 0x03, 0xe8, 0x1e, 0x00, 0x03, 0x20, 0x0f, 0x01, 0x02, 0x24, 0x0f, 0x01, 0x02, 0x28, 0x0f, 0x01, 0x02, 0x2c, 0x0f, 0x01, 0x02, 0x30, 0x0f, 0x01, 0x02, + 0x34, 0x0f, 0x01, 0x02, 0x38, 0x0f, 0x01, 0x02, 0x20, 0x2e, 0x02, 0x03, 0x28, 0x2e, 0x02, 0x03, 0x30, 0x2e, 0x02, 0x03, 0x38, 0x2e, 0x02, 0x03, 0xa0, 0x0c, 0x03, 0x03, 0xa8, 0x0c, 0x03, 0x03, + 0xb0, 0x0c, 0x03, 0x03, 0xa0, 0x2a, 0x04, 0x04, 0xb0, 0x2a, 0x04, 0x04, 0xa0, 0x0a, 0x05, 0x04, 0x00, 0x27, 0x06, 0x05, 0xa0, 0x06, 0x07, 0x05, 0x80, 0x22, 0x08, 0x06, 0x00, 0x1d, 0x0c, 0x08, + 0xf0, 0x1e, 0x00, 0x03, 0xf8, 0x1e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x03, 0x3c, 0x0f, 0x01, 0x02, 0x40, 0x0f, 0x01, 0x02, 0x44, 0x0f, 0x01, 0x02, 0x48, 0x0f, 0x01, 0x02, 0x4c, 0x0f, 0x01, 0x02, + 0x50, 0x0f, 0x01, 0x02, 0x54, 0x0f, 0x01, 0x02, 0x40, 0x2e, 0x02, 0x03, 0x48, 0x2e, 0x02, 0x03, 0x50, 0x2e, 0x02, 0x03, 0x58, 0x2e, 0x02, 0x03, 0xb8, 0x0c, 0x03, 0x03, 0xc0, 0x0c, 0x03, 0x03, + 0xc8, 0x0c, 0x03, 0x03, 0xc0, 0x2a, 0x04, 0x04, 0xd0, 0x2a, 0x04, 0x04, 0xb0, 0x0a, 0x05, 0x04, 0x20, 0x27, 0x06, 0x05, 0xc0, 0x06, 0x07, 0x05, 0xc0, 0x22, 0x08, 0x06, 0x00, 0x1e, 0x0c, 0x08, + 0x08, 0x1f, 0x00, 0x03, 0x10, 0x1f, 0x00, 0x03, 0x18, 0x1f, 0x00, 0x03, 0x58, 0x0f, 0x01, 0x02, 0x5c, 0x0f, 0x01, 0x02, 0x60, 0x0f, 0x01, 0x02, 0x64, 0x0f, 0x01, 0x02, 0x68, 0x0f, 0x01, 0x02, + 0x6c, 0x0f, 0x01, 0x02, 0x70, 0x0f, 0x01, 0x02, 0x60, 0x2e, 0x02, 0x03, 0x68, 0x2e, 0x02, 0x03, 0x70, 0x2e, 0x02, 0x03, 0x78, 0x2e, 0x02, 0x03, 0xd0, 0x0c, 0x03, 0x03, 0xd8, 0x0c, 0x03, 0x03, + 0xe0, 0x0c, 0x03, 0x03, 0xe0, 0x2a, 0x04, 0x04, 0xf0, 0x2a, 0x04, 0x04, 0xc0, 0x0a, 0x05, 0x04, 0x40, 0x27, 0x06, 0x05, 0xe0, 0x06, 0x07, 0x05, 0x00, 0x23, 0x08, 0x06, 0x00, 0x38, 0x0d, 0x09, + 0x20, 0x1f, 0x00, 0x03, 0x28, 0x1f, 0x00, 0x03, 0x30, 0x1f, 0x00, 0x03, 0x74, 0x0f, 0x01, 0x02, 0x78, 0x0f, 0x01, 0x02, 0x7c, 0x0f, 0x01, 0x02, 0x80, 0x0f, 0x01, 0x02, 0x84, 0x0f, 0x01, 0x02, + 0x88, 0x0f, 0x01, 0x02, 0x8c, 0x0f, 0x01, 0x02, 0x80, 0x2e, 0x02, 0x03, 0x88, 0x2e, 0x02, 0x03, 0x90, 0x2e, 0x02, 0x03, 0x98, 0x2e, 0x02, 0x03, 0xe8, 0x0c, 0x03, 0x03, 0xf0, 0x0c, 0x03, 0x03, + 0xf8, 0x0c, 0x03, 0x03, 0x00, 0x2b, 0x04, 0x04, 0x10, 0x2b, 0x04, 0x04, 0xd0, 0x0a, 0x05, 0x04, 0x60, 0x27, 0x06, 0x05, 0x00, 0x07, 0x07, 0x05, 0x40, 0x23, 0x08, 0x06, 0x00, 0x3a, 0x0d, 0x09, + 0x38, 0x1f, 0x00, 0x03, 0x40, 0x1f, 0x00, 0x03, 0x48, 0x1f, 0x00, 0x03, 0x90, 0x0f, 0x01, 0x02, 0x94, 0x0f, 0x01, 0x02, 0x98, 0x0f, 0x01, 0x02, 0x9c, 0x0f, 0x01, 0x02, 0xa0, 0x0f, 0x01, 0x02, + 0xa4, 0x0f, 0x01, 0x02, 0xa8, 0x0f, 0x01, 0x02, 0xa0, 0x2e, 0x02, 0x03, 0xa8, 0x2e, 0x02, 0x03, 0xb0, 0x2e, 0x02, 0x03, 0xb8, 0x2e, 0x02, 0x03, 0x00, 0x0d, 0x03, 0x03, 0x08, 0x0d, 0x03, 0x03, + 0x10, 0x0d, 0x03, 0x03, 0x20, 0x2b, 0x04, 0x04, 0x30, 0x2b, 0x04, 0x04, 0xe0, 0x0a, 0x05, 0x04, 0x80, 0x27, 0x06, 0x05, 0x20, 0x07, 0x07, 0x05, 0x80, 0x23, 0x08, 0x06, 0x00, 0x3c, 0x0d, 0x09, + 0x50, 0x1f, 0x00, 0x03, 0x58, 0x1f, 0x00, 0x03, 0x60, 0x1f, 0x00, 0x03, 0xac, 0x0f, 0x01, 0x02, 0xb0, 0x0f, 0x01, 0x02, 0xb4, 0x0f, 0x01, 0x02, 0xb8, 0x0f, 0x01, 0x02, 0xbc, 0x0f, 0x01, 0x02, + 0xc0, 0x0f, 0x01, 0x02, 0xc4, 0x0f, 0x01, 0x02, 0xc0, 0x2e, 0x02, 0x03, 0xc8, 0x2e, 0x02, 0x03, 0xd0, 0x2e, 0x02, 0x03, 0xd8, 0x2e, 0x02, 0x03, 0x18, 0x0d, 0x03, 0x03, 0x20, 0x0d, 0x03, 0x03, + 0x28, 0x0d, 0x03, 0x03, 0x40, 0x2b, 0x04, 0x04, 0x50, 0x2b, 0x04, 0x04, 0xf0, 0x0a, 0x05, 0x04, 0xa0, 0x27, 0x06, 0x05, 0x40, 0x07, 0x07, 0x05, 0xc0, 0x23, 0x08, 0x06, 0x00, 0x3e, 0x0d, 0x09, + 0x68, 0x1f, 0x00, 0x03, 0x70, 0x1f, 0x00, 0x03, 0x78, 0x1f, 0x00, 0x03, 0xc8, 0x0f, 0x01, 0x02, 0xcc, 0x0f, 0x01, 0x02, 0xd0, 0x0f, 0x01, 0x02, 0xd4, 0x0f, 0x01, 0x02, 0xd8, 0x0f, 0x01, 0x02, + 0xdc, 0x0f, 0x01, 0x02, 0xe0, 0x0f, 0x01, 0x02, 0xe0, 0x2e, 0x02, 0x03, 0xe8, 0x2e, 0x02, 0x03, 0xf0, 0x2e, 0x02, 0x03, 0xf8, 0x2e, 0x02, 0x03, 0x30, 0x0d, 0x03, 0x03, 0x38, 0x0d, 0x03, 0x03, + 0x40, 0x0d, 0x03, 0x03, 0x60, 0x2b, 0x04, 0x04, 0x70, 0x2b, 0x04, 0x04, 0x00, 0x0b, 0x05, 0x04, 0xc0, 0x27, 0x06, 0x05, 0x60, 0x07, 0x07, 0x05, 0x00, 0x24, 0x08, 0x06, 0x00, 0x00, 0x0d, 0x08, + 0x80, 0x1f, 0x00, 0x03, 0x88, 0x1f, 0x00, 0x03, 0x90, 0x1f, 0x00, 0x03, 0xe4, 0x0f, 0x01, 0x02, 0xe8, 0x0f, 0x01, 0x02, 0xec, 0x0f, 0x01, 0x02, 0xf0, 0x0f, 0x01, 0x02, 0xf4, 0x0f, 0x01, 0x02, + 0xf8, 0x0f, 0x01, 0x02, 0xfc, 0x0f, 0x01, 0x02, 0x00, 0x2f, 0x02, 0x03, 0x08, 0x2f, 0x02, 0x03, 0x10, 0x2f, 0x02, 0x03, 0x18, 0x2f, 0x02, 0x03, 0x48, 0x0d, 0x03, 0x03, 0x50, 0x0d, 0x03, 0x03, + 0x58, 0x0d, 0x03, 0x03, 0x80, 0x2b, 0x04, 0x04, 0x90, 0x2b, 0x04, 0x04, 0x10, 0x0b, 0x05, 0x04, 0xe0, 0x27, 0x06, 0x05, 0x80, 0x07, 0x07, 0x05, 0x40, 0x24, 0x08, 0x06, 0x00, 0x01, 0x0d, 0x08, + 0x98, 0x1f, 0x00, 0x03, 0xa0, 0x1f, 0x00, 0x03, 0xa8, 0x1f, 0x00, 0x03, 0x00, 0x10, 0x01, 0x02, 0x04, 0x10, 0x01, 0x02, 0x08, 0x10, 0x01, 0x02, 0x0c, 0x10, 0x01, 0x02, 0x10, 0x10, 0x01, 0x02, + 0x14, 0x10, 0x01, 0x02, 0x18, 0x10, 0x01, 0x02, 0x20, 0x2f, 0x02, 0x03, 0x28, 0x2f, 0x02, 0x03, 0x30, 0x2f, 0x02, 0x03, 0x38, 0x2f, 0x02, 0x03, 0x60, 0x0d, 0x03, 0x03, 0x68, 0x0d, 0x03, 0x03, + 0x70, 0x0d, 0x03, 0x03, 0xa0, 0x2b, 0x04, 0x04, 0xb0, 0x2b, 0x04, 0x04, 0x20, 0x0b, 0x05, 0x04, 0x00, 0x28, 0x06, 0x05, 0xa0, 0x07, 0x07, 0x05, 0x80, 0x24, 0x08, 0x06, 0x00, 0x14, 0x0e, 0x09, + 0xb0, 0x1f, 0x00, 0x03, 0xb8, 0x1f, 0x00, 0x03, 0xc0, 0x1f, 0x00, 0x03, 0x1c, 0x10, 0x01, 0x02, 0x20, 0x10, 0x01, 0x02, 0x24, 0x10, 0x01, 0x02, 0x28, 0x10, 0x01, 0x02, 0x2c, 0x10, 0x01, 0x02, + 0x30, 0x10, 0x01, 0x02, 0x34, 0x10, 0x01, 0x02, 0x40, 0x2f, 0x02, 0x03, 0x48, 0x2f, 0x02, 0x03, 0x50, 0x2f, 0x02, 0x03, 0x58, 0x2f, 0x02, 0x03, 0x78, 0x0d, 0x03, 0x03, 0x80, 0x0d, 0x03, 0x03, + 0x88, 0x0d, 0x03, 0x03, 0xc0, 0x2b, 0x04, 0x04, 0xd0, 0x2b, 0x04, 0x04, 0x30, 0x0b, 0x05, 0x04, 0x20, 0x28, 0x06, 0x05, 0xc0, 0x07, 0x07, 0x05, 0xc0, 0x24, 0x08, 0x06, 0x00, 0x16, 0x0e, 0x09, + 0xc8, 0x1f, 0x00, 0x03, 0xd0, 0x1f, 0x00, 0x03, 0xd8, 0x1f, 0x00, 0x03, 0x38, 0x10, 0x01, 0x02, 0x3c, 0x10, 0x01, 0x02, 0x40, 0x10, 0x01, 0x02, 0x44, 0x10, 0x01, 0x02, 0x48, 0x10, 0x01, 0x02, + 0x4c, 0x10, 0x01, 0x02, 0x50, 0x10, 0x01, 0x02, 0x60, 0x2f, 0x02, 0x03, 0x68, 0x2f, 0x02, 0x03, 0x70, 0x2f, 0x02, 0x03, 0x78, 0x2f, 0x02, 0x03, 0x90, 0x0d, 0x03, 0x03, 0x98, 0x0d, 0x03, 0x03, + 0xa0, 0x0d, 0x03, 0x03, 0xe0, 0x2b, 0x04, 0x04, 0xf0, 0x2b, 0x04, 0x04, 0x40, 0x0b, 0x05, 0x04, 0x40, 0x28, 0x06, 0x05, 0xe0, 0x07, 0x07, 0x05, 0x00, 0x25, 0x08, 0x06, 0x00, 0x18, 0x0e, 0x09, + 0xe0, 0x1f, 0x00, 0x03, 0xe8, 0x1f, 0x00, 0x03, 0xf0, 0x1f, 0x00, 0x03, 0x54, 0x10, 0x01, 0x02, 0x58, 0x10, 0x01, 0x02, 0x5c, 0x10, 0x01, 0x02, 0x60, 0x10, 0x01, 0x02, 0x64, 0x10, 0x01, 0x02, + 0x68, 0x10, 0x01, 0x02, 0x6c, 0x10, 0x01, 0x02, 0x80, 0x2f, 0x02, 0x03, 0x88, 0x2f, 0x02, 0x03, 0x90, 0x2f, 0x02, 0x03, 0x98, 0x2f, 0x02, 0x03, 0xa8, 0x0d, 0x03, 0x03, 0xb0, 0x0d, 0x03, 0x03, + 0xb8, 0x0d, 0x03, 0x03, 0x00, 0x2c, 0x04, 0x04, 0x10, 0x2c, 0x04, 0x04, 0x50, 0x0b, 0x05, 0x04, 0x60, 0x28, 0x06, 0x05, 0x00, 0x08, 0x07, 0x05, 0x40, 0x25, 0x08, 0x06, 0x00, 0x1a, 0x0e, 0x09, + 0xf8, 0x1f, 0x00, 0x03, 0x00, 0x20, 0x00, 0x03, 0x08, 0x20, 0x00, 0x03, 0x70, 0x10, 0x01, 0x02, 0x74, 0x10, 0x01, 0x02, 0x78, 0x10, 0x01, 0x02, 0x7c, 0x10, 0x01, 0x02, 0x80, 0x10, 0x01, 0x02, + 0x84, 0x10, 0x01, 0x02, 0x88, 0x10, 0x01, 0x02, 0xa0, 0x2f, 0x02, 0x03, 0xa8, 0x2f, 0x02, 0x03, 0xb0, 0x2f, 0x02, 0x03, 0xb8, 0x2f, 0x02, 0x03, 0xc0, 0x0d, 0x03, 0x03, 0xc8, 0x0d, 0x03, 0x03, + 0xd0, 0x0d, 0x03, 0x03, 0x20, 0x2c, 0x04, 0x04, 0x30, 0x2c, 0x04, 0x04, 0x60, 0x0b, 0x05, 0x04, 0x80, 0x28, 0x06, 0x05, 0x20, 0x08, 0x07, 0x05, 0x80, 0x25, 0x08, 0x06, 0x00, 0x1c, 0x0e, 0x09, + 0x10, 0x20, 0x00, 0x03, 0x18, 0x20, 0x00, 0x03, 0x20, 0x20, 0x00, 0x03, 0x8c, 0x10, 0x01, 0x02, 0x90, 0x10, 0x01, 0x02, 0x94, 0x10, 0x01, 0x02, 0x98, 0x10, 0x01, 0x02, 0x9c, 0x10, 0x01, 0x02, + 0xa0, 0x10, 0x01, 0x02, 0xc0, 0x2f, 0x02, 0x03, 0xc8, 0x2f, 0x02, 0x03, 0xd0, 0x2f, 0x02, 0x03, 0xd8, 0x2f, 0x02, 0x03, 0xe0, 0x2f, 0x02, 0x03, 0xd8, 0x0d, 0x03, 0x03, 0xe0, 0x0d, 0x03, 0x03, + 0xe8, 0x0d, 0x03, 0x03, 0x40, 0x2c, 0x04, 0x04, 0x50, 0x2c, 0x04, 0x04, 0x70, 0x0b, 0x05, 0x04, 0xa0, 0x28, 0x06, 0x05, 0x40, 0x08, 0x07, 0x05, 0xc0, 0x25, 0x08, 0x06, 0x00, 0x34, 0x0f, 0x0a, + 0x28, 0x20, 0x00, 0x03, 0x30, 0x20, 0x00, 0x03, 0x38, 0x20, 0x00, 0x03, 0xa4, 0x10, 0x01, 0x02, 0xa8, 0x10, 0x01, 0x02, 0xac, 0x10, 0x01, 0x02, 0xb0, 0x10, 0x01, 0x02, 0xb4, 0x10, 0x01, 0x02, + 0xb8, 0x10, 0x01, 0x02, 0xe8, 0x2f, 0x02, 0x03, 0xf0, 0x2f, 0x02, 0x03, 0xf8, 0x2f, 0x02, 0x03, 0x00, 0x30, 0x02, 0x03, 0x08, 0x30, 0x02, 0x03, 0xf0, 0x0d, 0x03, 0x03, 0xf8, 0x0d, 0x03, 0x03, + 0x00, 0x0e, 0x03, 0x03, 0x60, 0x2c, 0x04, 0x04, 0x70, 0x2c, 0x04, 0x04, 0x80, 0x0b, 0x05, 0x04, 0xc0, 0x28, 0x06, 0x05, 0x60, 0x08, 0x07, 0x05, 0x00, 0x26, 0x08, 0x06, 0x00, 0x38, 0x0f, 0x0a, + 0x40, 0x20, 0x00, 0x03, 0x48, 0x20, 0x00, 0x03, 0x50, 0x20, 0x00, 0x03, 0xbc, 0x10, 0x01, 0x02, 0xc0, 0x10, 0x01, 0x02, 0xc4, 0x10, 0x01, 0x02, 0xc8, 0x10, 0x01, 0x02, 0xcc, 0x10, 0x01, 0x02, + 0xd0, 0x10, 0x01, 0x02, 0x10, 0x30, 0x02, 0x03, 0x18, 0x30, 0x02, 0x03, 0x20, 0x30, 0x02, 0x03, 0x28, 0x30, 0x02, 0x03, 0x30, 0x30, 0x02, 0x03, 0x08, 0x0e, 0x03, 0x03, 0x10, 0x0e, 0x03, 0x03, + 0x18, 0x0e, 0x03, 0x03, 0x80, 0x2c, 0x04, 0x04, 0x90, 0x2c, 0x04, 0x04, 0x90, 0x0b, 0x05, 0x04, 0xe0, 0x28, 0x06, 0x05, 0x80, 0x08, 0x07, 0x05, 0x00, 0x05, 0x09, 0x06, 0x00, 0x3c, 0x0f, 0x0a, + 0x58, 0x20, 0x00, 0x03, 0x60, 0x20, 0x00, 0x03, 0x68, 0x20, 0x00, 0x03, 0xd4, 0x10, 0x01, 0x02, 0xd8, 0x10, 0x01, 0x02, 0xdc, 0x10, 0x01, 0x02, 0xe0, 0x10, 0x01, 0x02, 0xe4, 0x10, 0x01, 0x02, + 0xe8, 0x10, 0x01, 0x02, 0x38, 0x30, 0x02, 0x03, 0x40, 0x30, 0x02, 0x03, 0x48, 0x30, 0x02, 0x03, 0x50, 0x30, 0x02, 0x03, 0x58, 0x30, 0x02, 0x03, 0x20, 0x0e, 0x03, 0x03, 0x28, 0x0e, 0x03, 0x03, + 0x30, 0x0e, 0x03, 0x03, 0xa0, 0x2c, 0x04, 0x04, 0xb0, 0x2c, 0x04, 0x04, 0xa0, 0x0b, 0x05, 0x04, 0x00, 0x29, 0x06, 0x05, 0xa0, 0x08, 0x07, 0x05, 0x40, 0x05, 0x09, 0x06, 0x00, 0x00, 0x0f, 0x09, + 0x70, 0x20, 0x00, 0x03, 0x78, 0x20, 0x00, 0x03, 0x80, 0x20, 0x00, 0x03, 0xec, 0x10, 0x01, 0x02, 0xf0, 0x10, 0x01, 0x02, 0xf4, 0x10, 0x01, 0x02, 0xf8, 0x10, 0x01, 0x02, 0xfc, 0x10, 0x01, 0x02, + 0x00, 0x11, 0x01, 0x02, 0x60, 0x30, 0x02, 0x03, 0x68, 0x30, 0x02, 0x03, 0x70, 0x30, 0x02, 0x03, 0x78, 0x30, 0x02, 0x03, 0x80, 0x30, 0x02, 0x03, 0x38, 0x0e, 0x03, 0x03, 0x40, 0x0e, 0x03, 0x03, + 0x48, 0x0e, 0x03, 0x03, 0xc0, 0x2c, 0x04, 0x04, 0xd0, 0x2c, 0x04, 0x04, 0xb0, 0x0b, 0x05, 0x04, 0x20, 0x29, 0x06, 0x05, 0xc0, 0x08, 0x07, 0x05, 0x80, 0x05, 0x09, 0x06, 0x00, 0x14, 0x10, 0x0a, + 0x88, 0x20, 0x00, 0x03, 0x90, 0x20, 0x00, 0x03, 0x98, 0x20, 0x00, 0x03, 0x04, 0x11, 0x01, 0x02, 0x08, 0x11, 0x01, 0x02, 0x0c, 0x11, 0x01, 0x02, 0x10, 0x11, 0x01, 0x02, 0x14, 0x11, 0x01, 0x02, + 0x18, 0x11, 0x01, 0x02, 0x88, 0x30, 0x02, 0x03, 0x90, 0x30, 0x02, 0x03, 0x98, 0x30, 0x02, 0x03, 0xa0, 0x30, 0x02, 0x03, 0xa8, 0x30, 0x02, 0x03, 0x50, 0x0e, 0x03, 0x03, 0x58, 0x0e, 0x03, 0x03, + 0x60, 0x0e, 0x03, 0x03, 0xe0, 0x2c, 0x04, 0x04, 0xf0, 0x2c, 0x04, 0x04, 0xc0, 0x0b, 0x05, 0x04, 0x40, 0x29, 0x06, 0x05, 0xe0, 0x08, 0x07, 0x05, 0xc0, 0x05, 0x09, 0x06, 0x00, 0x18, 0x10, 0x0a, + 0xa0, 0x20, 0x00, 0x03, 0xa8, 0x20, 0x00, 0x03, 0xb0, 0x20, 0x00, 0x03, 0x1c, 0x11, 0x01, 0x02, 0x20, 0x11, 0x01, 0x02, 0x24, 0x11, 0x01, 0x02, 0x28, 0x11, 0x01, 0x02, 0x2c, 0x11, 0x01, 0x02, + 0x30, 0x11, 0x01, 0x02, 0xb0, 0x30, 0x02, 0x03, 0xb8, 0x30, 0x02, 0x03, 0xc0, 0x30, 0x02, 0x03, 0xc8, 0x30, 0x02, 0x03, 0xd0, 0x30, 0x02, 0x03, 0x68, 0x0e, 0x03, 0x03, 0x70, 0x0e, 0x03, 0x03, + 0x78, 0x0e, 0x03, 0x03, 0x00, 0x2d, 0x04, 0x04, 0x10, 0x2d, 0x04, 0x04, 0xd0, 0x0b, 0x05, 0x04, 0x60, 0x29, 0x06, 0x05, 0x00, 0x09, 0x07, 0x05, 0x00, 0x06, 0x09, 0x06, 0x00, 0x28, 0x11, 0x0b, + 0xb8, 0x20, 0x00, 0x03, 0xc0, 0x20, 0x00, 0x03, 0xc8, 0x20, 0x00, 0x03, 0x34, 0x11, 0x01, 0x02, 0x38, 0x11, 0x01, 0x02, 0x3c, 0x11, 0x01, 0x02, 0x40, 0x11, 0x01, 0x02, 0x44, 0x11, 0x01, 0x02, + 0x48, 0x11, 0x01, 0x02, 0xd8, 0x30, 0x02, 0x03, 0xe0, 0x30, 0x02, 0x03, 0xe8, 0x30, 0x02, 0x03, 0xf0, 0x30, 0x02, 0x03, 0xf8, 0x30, 0x02, 0x03, 0x80, 0x0e, 0x03, 0x03, 0x88, 0x0e, 0x03, 0x03, + 0x90, 0x0e, 0x03, 0x03, 0x20, 0x2d, 0x04, 0x04, 0x30, 0x2d, 0x04, 0x04, 0xe0, 0x0b, 0x05, 0x04, 0x80, 0x29, 0x06, 0x05, 0x20, 0x09, 0x07, 0x05, 0x40, 0x06, 0x09, 0x06, 0x00, 0x30, 0x11, 0x0b, + 0xd0, 0x20, 0x00, 0x03, 0xd8, 0x20, 0x00, 0x03, 0xe0, 0x20, 0x00, 0x03, 0x4c, 0x11, 0x01, 0x02, 0x50, 0x11, 0x01, 0x02, 0x54, 0x11, 0x01, 0x02, 0x58, 0x11, 0x01, 0x02, 0x5c, 0x11, 0x01, 0x02, + 0x60, 0x11, 0x01, 0x02, 0x00, 0x31, 0x02, 0x03, 0x08, 0x31, 0x02, 0x03, 0x10, 0x31, 0x02, 0x03, 0x18, 0x31, 0x02, 0x03, 0x20, 0x31, 0x02, 0x03, 0x98, 0x0e, 0x03, 0x03, 0xa0, 0x0e, 0x03, 0x03, + 0xa8, 0x0e, 0x03, 0x03, 0x40, 0x2d, 0x04, 0x04, 0x50, 0x2d, 0x04, 0x04, 0xf0, 0x0b, 0x05, 0x04, 0xa0, 0x29, 0x06, 0x05, 0x40, 0x09, 0x07, 0x05, 0x80, 0x06, 0x09, 0x06, 0x00, 0x18, 0x12, 0x0b, + 0xe8, 0x20, 0x00, 0x03, 0xf0, 0x20, 0x00, 0x03, 0xf8, 0x20, 0x00, 0x03, 0x64, 0x11, 0x01, 0x02, 0x68, 0x11, 0x01, 0x02, 0x6c, 0x11, 0x01, 0x02, 0x70, 0x11, 0x01, 0x02, 0x74, 0x11, 0x01, 0x02, + 0x78, 0x11, 0x01, 0x02, 0x28, 0x31, 0x02, 0x03, 0x30, 0x31, 0x02, 0x03, 0x38, 0x31, 0x02, 0x03, 0x40, 0x31, 0x02, 0x03, 0x48, 0x31, 0x02, 0x03, 0xb0, 0x0e, 0x03, 0x03, 0xb8, 0x0e, 0x03, 0x03, + 0xc0, 0x0e, 0x03, 0x03, 0x60, 0x2d, 0x04, 0x04, 0x70, 0x2d, 0x04, 0x04, 0x00, 0x0c, 0x05, 0x04, 0xc0, 0x29, 0x06, 0x05, 0x60, 0x09, 0x07, 0x05, 0xc0, 0x06, 0x09, 0x06, 0x00, 0x30, 0x13, 0x0c, + 0x00, 0x21, 0x00, 0x03, 0x08, 0x21, 0x00, 0x03, 0x10, 0x21, 0x00, 0x03, 0x7c, 0x11, 0x01, 0x02, 0x80, 0x11, 0x01, 0x02, 0x84, 0x11, 0x01, 0x02, 0x88, 0x11, 0x01, 0x02, 0x8c, 0x11, 0x01, 0x02, + 0x90, 0x11, 0x01, 0x02, 0x50, 0x31, 0x02, 0x03, 0x58, 0x31, 0x02, 0x03, 0x60, 0x31, 0x02, 0x03, 0x68, 0x31, 0x02, 0x03, 0x70, 0x31, 0x02, 0x03, 0xc8, 0x0e, 0x03, 0x03, 0xd0, 0x0e, 0x03, 0x03, + 0xd8, 0x0e, 0x03, 0x03, 0x80, 0x2d, 0x04, 0x04, 0x90, 0x2d, 0x04, 0x04, 0x10, 0x0c, 0x05, 0x04, 0xe0, 0x29, 0x06, 0x05, 0x80, 0x09, 0x07, 0x05, 0x00, 0x07, 0x09, 0x06, 0x00, 0x00, 0x14, 0x0c, + 0x18, 0x21, 0x00, 0x03, 0x20, 0x21, 0x00, 0x03, 0x28, 0x21, 0x00, 0x03, 0x94, 0x11, 0x01, 0x02, 0x98, 0x11, 0x01, 0x02, 0x9c, 0x11, 0x01, 0x02, 0xa0, 0x11, 0x01, 0x02, 0xa4, 0x11, 0x01, 0x02, + 0xa8, 0x11, 0x01, 0x02, 0x78, 0x31, 0x02, 0x03, 0x80, 0x31, 0x02, 0x03, 0x88, 0x31, 0x02, 0x03, 0x90, 0x31, 0x02, 0x03, 0x98, 0x31, 0x02, 0x03, 0xe0, 0x0e, 0x03, 0x03, 0xe8, 0x0e, 0x03, 0x03, + 0xf0, 0x0e, 0x03, 0x03, 0xa0, 0x2d, 0x04, 0x04, 0xb0, 0x2d, 0x04, 0x04, 0x20, 0x0c, 0x05, 0x04, 0x00, 0x2a, 0x06, 0x05, 0xa0, 0x09, 0x07, 0x05, 0x40, 0x07, 0x09, 0x06, 0x30, 0x21, 0x00, 0x03, + 0x38, 0x21, 0x00, 0x03, 0x40, 0x21, 0x00, 0x03, 0x48, 0x21, 0x00, 0x03, 0xac, 0x11, 0x01, 0x02, 0xb0, 0x11, 0x01, 0x02, 0xb4, 0x11, 0x01, 0x02, 0xb8, 0x11, 0x01, 0x02, 0xbc, 0x11, 0x01, 0x02, + 0xc0, 0x11, 0x01, 0x02, 0xa0, 0x31, 0x02, 0x03, 0xa8, 0x31, 0x02, 0x03, 0xb0, 0x31, 0x02, 0x03, 0xb8, 0x31, 0x02, 0x03, 0xc0, 0x31, 0x02, 0x03, 0xf8, 0x0e, 0x03, 0x03, 0x00, 0x0f, 0x03, 0x03, + 0x08, 0x0f, 0x03, 0x03, 0xc0, 0x2d, 0x04, 0x04, 0xd0, 0x2d, 0x04, 0x04, 0x30, 0x0c, 0x05, 0x04, 0x20, 0x2a, 0x06, 0x05, 0xc0, 0x09, 0x07, 0x05, 0x80, 0x07, 0x09, 0x06, 0x50, 0x21, 0x00, 0x03, + 0x58, 0x21, 0x00, 0x03, 0x60, 0x21, 0x00, 0x03, 0x68, 0x21, 0x00, 0x03, 0xc4, 0x11, 0x01, 0x02, 0xc8, 0x11, 0x01, 0x02, 0xcc, 0x11, 0x01, 0x02, 0xd0, 0x11, 0x01, 0x02, 0xd4, 0x11, 0x01, 0x02, + 0xd8, 0x11, 0x01, 0x02, 0xc8, 0x31, 0x02, 0x03, 0xd0, 0x31, 0x02, 0x03, 0xd8, 0x31, 0x02, 0x03, 0xe0, 0x31, 0x02, 0x03, 0xe8, 0x31, 0x02, 0x03, 0x10, 0x0f, 0x03, 0x03, 0x18, 0x0f, 0x03, 0x03, + 0x20, 0x0f, 0x03, 0x03, 0xe0, 0x2d, 0x04, 0x04, 0xf0, 0x2d, 0x04, 0x04, 0x40, 0x0c, 0x05, 0x04, 0x40, 0x2a, 0x06, 0x05, 0xe0, 0x09, 0x07, 0x05, 0xc0, 0x07, 0x09, 0x06, 0x70, 0x21, 0x00, 0x03, + 0x78, 0x21, 0x00, 0x03, 0x80, 0x21, 0x00, 0x03, 0x88, 0x21, 0x00, 0x03, 0xdc, 0x11, 0x01, 0x02, 0xe0, 0x11, 0x01, 0x02, 0xe4, 0x11, 0x01, 0x02, 0xe8, 0x11, 0x01, 0x02, 0xec, 0x11, 0x01, 0x02, + 0xf0, 0x11, 0x01, 0x02, 0xf0, 0x31, 0x02, 0x03, 0xf8, 0x31, 0x02, 0x03, 0x00, 0x32, 0x02, 0x03, 0x08, 0x32, 0x02, 0x03, 0x10, 0x32, 0x02, 0x03, 0x28, 0x0f, 0x03, 0x03, 0x30, 0x0f, 0x03, 0x03, + 0x38, 0x0f, 0x03, 0x03, 0x00, 0x2e, 0x04, 0x04, 0x10, 0x2e, 0x04, 0x04, 0x50, 0x0c, 0x05, 0x04, 0x60, 0x2a, 0x06, 0x05, 0x00, 0x0a, 0x07, 0x05, 0x00, 0x08, 0x09, 0x06, 0x90, 0x21, 0x00, 0x03, + 0x98, 0x21, 0x00, 0x03, 0xa0, 0x21, 0x00, 0x03, 0xa8, 0x21, 0x00, 0x03, 0xf4, 0x11, 0x01, 0x02, 0xf8, 0x11, 0x01, 0x02, 0xfc, 0x11, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x04, 0x12, 0x01, 0x02, + 0x08, 0x12, 0x01, 0x02, 0x18, 0x32, 0x02, 0x03, 0x20, 0x32, 0x02, 0x03, 0x28, 0x32, 0x02, 0x03, 0x30, 0x32, 0x02, 0x03, 0x38, 0x32, 0x02, 0x03, 0x40, 0x0f, 0x03, 0x03, 0x48, 0x0f, 0x03, 0x03, + 0x50, 0x0f, 0x03, 0x03, 0x20, 0x2e, 0x04, 0x04, 0x30, 0x2e, 0x04, 0x04, 0x60, 0x0c, 0x05, 0x04, 0x80, 0x2a, 0x06, 0x05, 0x20, 0x0a, 0x07, 0x05, 0x40, 0x08, 0x09, 0x06, 0xb0, 0x21, 0x00, 0x03, + 0xb8, 0x21, 0x00, 0x03, 0xc0, 0x21, 0x00, 0x03, 0xc8, 0x21, 0x00, 0x03, 0x0c, 0x12, 0x01, 0x02, 0x10, 0x12, 0x01, 0x02, 0x14, 0x12, 0x01, 0x02, 0x18, 0x12, 0x01, 0x02, 0x1c, 0x12, 0x01, 0x02, + 0x20, 0x12, 0x01, 0x02, 0x40, 0x32, 0x02, 0x03, 0x48, 0x32, 0x02, 0x03, 0x50, 0x32, 0x02, 0x03, 0x58, 0x32, 0x02, 0x03, 0x60, 0x32, 0x02, 0x03, 0x58, 0x0f, 0x03, 0x03, 0x60, 0x0f, 0x03, 0x03, + 0x68, 0x0f, 0x03, 0x03, 0x40, 0x2e, 0x04, 0x04, 0x50, 0x2e, 0x04, 0x04, 0x70, 0x0c, 0x05, 0x04, 0xa0, 0x2a, 0x06, 0x05, 0x40, 0x0a, 0x07, 0x05, 0x80, 0x08, 0x09, 0x06, 0xd0, 0x21, 0x00, 0x03, + 0xd8, 0x21, 0x00, 0x03, 0xe0, 0x21, 0x00, 0x03, 0xe8, 0x21, 0x00, 0x03, 0x24, 0x12, 0x01, 0x02, 0x28, 0x12, 0x01, 0x02, 0x2c, 0x12, 0x01, 0x02, 0x30, 0x12, 0x01, 0x02, 0x34, 0x12, 0x01, 0x02, + 0x38, 0x12, 0x01, 0x02, 0x68, 0x32, 0x02, 0x03, 0x70, 0x32, 0x02, 0x03, 0x78, 0x32, 0x02, 0x03, 0x80, 0x32, 0x02, 0x03, 0x88, 0x32, 0x02, 0x03, 0x70, 0x0f, 0x03, 0x03, 0x78, 0x0f, 0x03, 0x03, + 0x80, 0x0f, 0x03, 0x03, 0x60, 0x2e, 0x04, 0x04, 0x70, 0x2e, 0x04, 0x04, 0x80, 0x0c, 0x05, 0x04, 0xc0, 0x2a, 0x06, 0x05, 0x60, 0x0a, 0x07, 0x05, 0xc0, 0x08, 0x09, 0x06, 0xf0, 0x21, 0x00, 0x03, + 0xf8, 0x21, 0x00, 0x03, 0x00, 0x22, 0x00, 0x03, 0x08, 0x22, 0x00, 0x03, 0x3c, 0x12, 0x01, 0x02, 0x40, 0x12, 0x01, 0x02, 0x44, 0x12, 0x01, 0x02, 0x48, 0x12, 0x01, 0x02, 0x4c, 0x12, 0x01, 0x02, + 0x50, 0x12, 0x01, 0x02, 0x90, 0x32, 0x02, 0x03, 0x98, 0x32, 0x02, 0x03, 0xa0, 0x32, 0x02, 0x03, 0xa8, 0x32, 0x02, 0x03, 0xb0, 0x32, 0x02, 0x03, 0x88, 0x0f, 0x03, 0x03, 0x90, 0x0f, 0x03, 0x03, + 0x98, 0x0f, 0x03, 0x03, 0x80, 0x2e, 0x04, 0x04, 0x90, 0x2e, 0x04, 0x04, 0x90, 0x0c, 0x05, 0x04, 0xe0, 0x2a, 0x06, 0x05, 0x80, 0x0a, 0x07, 0x05, 0x00, 0x09, 0x09, 0x06, 0x10, 0x22, 0x00, 0x03, + 0x18, 0x22, 0x00, 0x03, 0x20, 0x22, 0x00, 0x03, 0x28, 0x22, 0x00, 0x03, 0x54, 0x12, 0x01, 0x02, 0x58, 0x12, 0x01, 0x02, 0x5c, 0x12, 0x01, 0x02, 0x60, 0x12, 0x01, 0x02, 0x64, 0x12, 0x01, 0x02, + 0x68, 0x12, 0x01, 0x02, 0xb8, 0x32, 0x02, 0x03, 0xc0, 0x32, 0x02, 0x03, 0xc8, 0x32, 0x02, 0x03, 0xd0, 0x32, 0x02, 0x03, 0xd8, 0x32, 0x02, 0x03, 0xa0, 0x0f, 0x03, 0x03, 0xa8, 0x0f, 0x03, 0x03, + 0xb0, 0x0f, 0x03, 0x03, 0xa0, 0x2e, 0x04, 0x04, 0xb0, 0x2e, 0x04, 0x04, 0xa0, 0x0c, 0x05, 0x04, 0x00, 0x2b, 0x06, 0x05, 0xa0, 0x0a, 0x07, 0x05, 0x40, 0x09, 0x09, 0x06, 0x30, 0x22, 0x00, 0x03, + 0x38, 0x22, 0x00, 0x03, 0x40, 0x22, 0x00, 0x03, 0x48, 0x22, 0x00, 0x03, 0x6c, 0x12, 0x01, 0x02, 0x70, 0x12, 0x01, 0x02, 0x74, 0x12, 0x01, 0x02, 0x78, 0x12, 0x01, 0x02, 0x7c, 0x12, 0x01, 0x02, + 0x80, 0x12, 0x01, 0x02, 0xe0, 0x32, 0x02, 0x03, 0xe8, 0x32, 0x02, 0x03, 0xf0, 0x32, 0x02, 0x03, 0xf8, 0x32, 0x02, 0x03, 0x00, 0x33, 0x02, 0x03, 0xb8, 0x0f, 0x03, 0x03, 0xc0, 0x0f, 0x03, 0x03, + 0xc8, 0x0f, 0x03, 0x03, 0xc0, 0x2e, 0x04, 0x04, 0xd0, 0x2e, 0x04, 0x04, 0xb0, 0x0c, 0x05, 0x04, 0x20, 0x2b, 0x06, 0x05, 0xc0, 0x0a, 0x07, 0x05, 0x80, 0x09, 0x09, 0x06, 0x50, 0x22, 0x00, 0x03, + 0x58, 0x22, 0x00, 0x03, 0x60, 0x22, 0x00, 0x03, 0x68, 0x22, 0x00, 0x03, 0x84, 0x12, 0x01, 0x02, 0x88, 0x12, 0x01, 0x02, 0x8c, 0x12, 0x01, 0x02, 0x90, 0x12, 0x01, 0x02, 0x94, 0x12, 0x01, 0x02, + 0x98, 0x12, 0x01, 0x02, 0x08, 0x33, 0x02, 0x03, 0x10, 0x33, 0x02, 0x03, 0x18, 0x33, 0x02, 0x03, 0x20, 0x33, 0x02, 0x03, 0x28, 0x33, 0x02, 0x03, 0xd0, 0x0f, 0x03, 0x03, 0xd8, 0x0f, 0x03, 0x03, + 0xe0, 0x0f, 0x03, 0x03, 0xe0, 0x2e, 0x04, 0x04, 0xf0, 0x2e, 0x04, 0x04, 0xc0, 0x0c, 0x05, 0x04, 0x40, 0x2b, 0x06, 0x05, 0xe0, 0x0a, 0x07, 0x05, 0xc0, 0x09, 0x09, 0x06, 0x70, 0x22, 0x00, 0x03, + 0x78, 0x22, 0x00, 0x03, 0x80, 0x22, 0x00, 0x03, 0x88, 0x22, 0x00, 0x03, 0x9c, 0x12, 0x01, 0x02, 0xa0, 0x12, 0x01, 0x02, 0xa4, 0x12, 0x01, 0x02, 0xa8, 0x12, 0x01, 0x02, 0xac, 0x12, 0x01, 0x02, + 0xb0, 0x12, 0x01, 0x02, 0x30, 0x33, 0x02, 0x03, 0x38, 0x33, 0x02, 0x03, 0x40, 0x33, 0x02, 0x03, 0x48, 0x33, 0x02, 0x03, 0x50, 0x33, 0x02, 0x03, 0xe8, 0x0f, 0x03, 0x03, 0xf0, 0x0f, 0x03, 0x03, + 0xf8, 0x0f, 0x03, 0x03, 0x00, 0x2f, 0x04, 0x04, 0x10, 0x2f, 0x04, 0x04, 0xd0, 0x0c, 0x05, 0x04, 0x60, 0x2b, 0x06, 0x05, 0x00, 0x0b, 0x07, 0x05, 0x00, 0x0a, 0x09, 0x06, 0x90, 0x22, 0x00, 0x03, + 0x98, 0x22, 0x00, 0x03, 0xa0, 0x22, 0x00, 0x03, 0xa8, 0x22, 0x00, 0x03, 0xb4, 0x12, 0x01, 0x02, 0xb8, 0x12, 0x01, 0x02, 0xbc, 0x12, 0x01, 0x02, 0xc0, 0x12, 0x01, 0x02, 0xc4, 0x12, 0x01, 0x02, + 0xc8, 0x12, 0x01, 0x02, 0x58, 0x33, 0x02, 0x03, 0x60, 0x33, 0x02, 0x03, 0x68, 0x33, 0x02, 0x03, 0x70, 0x33, 0x02, 0x03, 0x78, 0x33, 0x02, 0x03, 0x00, 0x10, 0x03, 0x03, 0x08, 0x10, 0x03, 0x03, + 0x10, 0x10, 0x03, 0x03, 0x20, 0x2f, 0x04, 0x04, 0x30, 0x2f, 0x04, 0x04, 0xe0, 0x0c, 0x05, 0x04, 0x80, 0x2b, 0x06, 0x05, 0x20, 0x0b, 0x07, 0x05, 0x40, 0x0a, 0x09, 0x06, 0xb0, 0x22, 0x00, 0x03, + 0xb8, 0x22, 0x00, 0x03, 0xc0, 0x22, 0x00, 0x03, 0xc8, 0x22, 0x00, 0x03, 0xcc, 0x12, 0x01, 0x02, 0xd0, 0x12, 0x01, 0x02, 0xd4, 0x12, 0x01, 0x02, 0xd8, 0x12, 0x01, 0x02, 0xdc, 0x12, 0x01, 0x02, + 0xe0, 0x12, 0x01, 0x02, 0x80, 0x33, 0x02, 0x03, 0x88, 0x33, 0x02, 0x03, 0x90, 0x33, 0x02, 0x03, 0x98, 0x33, 0x02, 0x03, 0xa0, 0x33, 0x02, 0x03, 0x18, 0x10, 0x03, 0x03, 0x20, 0x10, 0x03, 0x03, + 0x28, 0x10, 0x03, 0x03, 0x40, 0x2f, 0x04, 0x04, 0x50, 0x2f, 0x04, 0x04, 0xf0, 0x0c, 0x05, 0x04, 0xa0, 0x2b, 0x06, 0x05, 0x40, 0x0b, 0x07, 0x05, 0x80, 0x0a, 0x09, 0x06, 0xd0, 0x22, 0x00, 0x03, + 0xd8, 0x22, 0x00, 0x03, 0xe0, 0x22, 0x00, 0x03, 0xe8, 0x22, 0x00, 0x03, 0xe4, 0x12, 0x01, 0x02, 0xe8, 0x12, 0x01, 0x02, 0xec, 0x12, 0x01, 0x02, 0xf0, 0x12, 0x01, 0x02, 0xf4, 0x12, 0x01, 0x02, + 0xf8, 0x12, 0x01, 0x02, 0xa8, 0x33, 0x02, 0x03, 0xb0, 0x33, 0x02, 0x03, 0xb8, 0x33, 0x02, 0x03, 0xc0, 0x33, 0x02, 0x03, 0xc8, 0x33, 0x02, 0x03, 0x30, 0x10, 0x03, 0x03, 0x38, 0x10, 0x03, 0x03, + 0x40, 0x10, 0x03, 0x03, 0x60, 0x2f, 0x04, 0x04, 0x70, 0x2f, 0x04, 0x04, 0x00, 0x0d, 0x05, 0x04, 0xc0, 0x2b, 0x06, 0x05, 0x60, 0x0b, 0x07, 0x05, 0xc0, 0x0a, 0x09, 0x06, 0xf0, 0x22, 0x00, 0x03, + 0xf8, 0x22, 0x00, 0x03, 0x00, 0x23, 0x00, 0x03, 0x08, 0x23, 0x00, 0x03, 0xfc, 0x12, 0x01, 0x02, 0x00, 0x13, 0x01, 0x02, 0x04, 0x13, 0x01, 0x02, 0x08, 0x13, 0x01, 0x02, 0x0c, 0x13, 0x01, 0x02, + 0x10, 0x13, 0x01, 0x02, 0xd0, 0x33, 0x02, 0x03, 0xd8, 0x33, 0x02, 0x03, 0xe0, 0x33, 0x02, 0x03, 0xe8, 0x33, 0x02, 0x03, 0xf0, 0x33, 0x02, 0x03, 0x48, 0x10, 0x03, 0x03, 0x50, 0x10, 0x03, 0x03, + 0x58, 0x10, 0x03, 0x03, 0x80, 0x2f, 0x04, 0x04, 0x90, 0x2f, 0x04, 0x04, 0x10, 0x0d, 0x05, 0x04, 0xe0, 0x2b, 0x06, 0x05, 0x80, 0x0b, 0x07, 0x05, 0x00, 0x0b, 0x09, 0x06, 0x10, 0x23, 0x00, 0x03, + 0x18, 0x23, 0x00, 0x03, 0x20, 0x23, 0x00, 0x03, 0x28, 0x23, 0x00, 0x03, 0x14, 0x13, 0x01, 0x02, 0x18, 0x13, 0x01, 0x02, 0x1c, 0x13, 0x01, 0x02, 0x20, 0x13, 0x01, 0x02, 0x24, 0x13, 0x01, 0x02, + 0x28, 0x13, 0x01, 0x02, 0xf8, 0x33, 0x02, 0x03, 0x00, 0x34, 0x02, 0x03, 0x08, 0x34, 0x02, 0x03, 0x10, 0x34, 0x02, 0x03, 0x60, 0x10, 0x03, 0x03, 0x68, 0x10, 0x03, 0x03, 0x70, 0x10, 0x03, 0x03, + 0xa0, 0x2f, 0x04, 0x04, 0xb0, 0x2f, 0x04, 0x04, 0xc0, 0x2f, 0x04, 0x04, 0x20, 0x0d, 0x05, 0x04, 0x00, 0x2c, 0x06, 0x05, 0xa0, 0x0b, 0x07, 0x05, 0x40, 0x0b, 0x09, 0x06, 0x30, 0x23, 0x00, 0x03, + 0x38, 0x23, 0x00, 0x03, 0x40, 0x23, 0x00, 0x03, 0x48, 0x23, 0x00, 0x03, 0x2c, 0x13, 0x01, 0x02, 0x30, 0x13, 0x01, 0x02, 0x34, 0x13, 0x01, 0x02, 0x38, 0x13, 0x01, 0x02, 0x3c, 0x13, 0x01, 0x02, + 0x40, 0x13, 0x01, 0x02, 0x18, 0x34, 0x02, 0x03, 0x20, 0x34, 0x02, 0x03, 0x28, 0x34, 0x02, 0x03, 0x30, 0x34, 0x02, 0x03, 0x78, 0x10, 0x03, 0x03, 0x80, 0x10, 0x03, 0x03, 0x88, 0x10, 0x03, 0x03, + 0xd0, 0x2f, 0x04, 0x04, 0xe0, 0x2f, 0x04, 0x04, 0xf0, 0x2f, 0x04, 0x04, 0x30, 0x0d, 0x05, 0x04, 0x20, 0x2c, 0x06, 0x05, 0xc0, 0x0b, 0x07, 0x05, 0x80, 0x0b, 0x09, 0x06, 0x50, 0x23, 0x00, 0x03, + 0x58, 0x23, 0x00, 0x03, 0x60, 0x23, 0x00, 0x03, 0x68, 0x23, 0x00, 0x03, 0x44, 0x13, 0x01, 0x02, 0x48, 0x13, 0x01, 0x02, 0x4c, 0x13, 0x01, 0x02, 0x50, 0x13, 0x01, 0x02, 0x54, 0x13, 0x01, 0x02, + 0x58, 0x13, 0x01, 0x02, 0x38, 0x34, 0x02, 0x03, 0x40, 0x34, 0x02, 0x03, 0x48, 0x34, 0x02, 0x03, 0x50, 0x34, 0x02, 0x03, 0x90, 0x10, 0x03, 0x03, 0x98, 0x10, 0x03, 0x03, 0xa0, 0x10, 0x03, 0x03, + 0x00, 0x30, 0x04, 0x04, 0x10, 0x30, 0x04, 0x04, 0x20, 0x30, 0x04, 0x04, 0x40, 0x0d, 0x05, 0x04, 0x40, 0x2c, 0x06, 0x05, 0xe0, 0x0b, 0x07, 0x05, 0xc0, 0x0b, 0x09, 0x06, 0x70, 0x23, 0x00, 0x03, + 0x78, 0x23, 0x00, 0x03, 0x80, 0x23, 0x00, 0x03, 0x88, 0x23, 0x00, 0x03, 0x5c, 0x13, 0x01, 0x02, 0x60, 0x13, 0x01, 0x02, 0x64, 0x13, 0x01, 0x02, 0x68, 0x13, 0x01, 0x02, 0x6c, 0x13, 0x01, 0x02, + 0x70, 0x13, 0x01, 0x02, 0x58, 0x34, 0x02, 0x03, 0x60, 0x34, 0x02, 0x03, 0x68, 0x34, 0x02, 0x03, 0x70, 0x34, 0x02, 0x03, 0xa8, 0x10, 0x03, 0x03, 0xb0, 0x10, 0x03, 0x03, 0xb8, 0x10, 0x03, 0x03, + 0x30, 0x30, 0x04, 0x04, 0x40, 0x30, 0x04, 0x04, 0x50, 0x30, 0x04, 0x04, 0x50, 0x0d, 0x05, 0x04, 0x60, 0x2c, 0x06, 0x05, 0x00, 0x0c, 0x07, 0x05, 0x00, 0x0c, 0x09, 0x06, 0x90, 0x23, 0x00, 0x03, + 0x98, 0x23, 0x00, 0x03, 0xa0, 0x23, 0x00, 0x03, 0xa8, 0x23, 0x00, 0x03, 0x74, 0x13, 0x01, 0x02, 0x78, 0x13, 0x01, 0x02, 0x7c, 0x13, 0x01, 0x02, 0x80, 0x13, 0x01, 0x02, 0x84, 0x13, 0x01, 0x02, + 0x88, 0x13, 0x01, 0x02, 0x78, 0x34, 0x02, 0x03, 0x80, 0x34, 0x02, 0x03, 0x88, 0x34, 0x02, 0x03, 0x90, 0x34, 0x02, 0x03, 0xc0, 0x10, 0x03, 0x03, 0xc8, 0x10, 0x03, 0x03, 0xd0, 0x10, 0x03, 0x03, + 0x60, 0x30, 0x04, 0x04, 0x70, 0x30, 0x04, 0x04, 0x80, 0x30, 0x04, 0x04, 0x60, 0x0d, 0x05, 0x04, 0x80, 0x2c, 0x06, 0x05, 0x20, 0x0c, 0x07, 0x05, 0x00, 0x23, 0x0a, 0x07, 0xb0, 0x23, 0x00, 0x03, + 0xb8, 0x23, 0x00, 0x03, 0xc0, 0x23, 0x00, 0x03, 0xc8, 0x23, 0x00, 0x03, 0x8c, 0x13, 0x01, 0x02, 0x90, 0x13, 0x01, 0x02, 0x94, 0x13, 0x01, 0x02, 0x98, 0x13, 0x01, 0x02, 0x9c, 0x13, 0x01, 0x02, + 0xa0, 0x13, 0x01, 0x02, 0x98, 0x34, 0x02, 0x03, 0xa0, 0x34, 0x02, 0x03, 0xa8, 0x34, 0x02, 0x03, 0xb0, 0x34, 0x02, 0x03, 0xd8, 0x10, 0x03, 0x03, 0xe0, 0x10, 0x03, 0x03, 0xe8, 0x10, 0x03, 0x03, + 0x90, 0x30, 0x04, 0x04, 0xa0, 0x30, 0x04, 0x04, 0xb0, 0x30, 0x04, 0x04, 0x70, 0x0d, 0x05, 0x04, 0xa0, 0x2c, 0x06, 0x05, 0x40, 0x0c, 0x07, 0x05, 0x80, 0x23, 0x0a, 0x07, 0xd0, 0x23, 0x00, 0x03, + 0xd8, 0x23, 0x00, 0x03, 0xe0, 0x23, 0x00, 0x03, 0xe8, 0x23, 0x00, 0x03, 0xa4, 0x13, 0x01, 0x02, 0xa8, 0x13, 0x01, 0x02, 0xac, 0x13, 0x01, 0x02, 0xb0, 0x13, 0x01, 0x02, 0xb4, 0x13, 0x01, 0x02, + 0xb8, 0x13, 0x01, 0x02, 0xb8, 0x34, 0x02, 0x03, 0xc0, 0x34, 0x02, 0x03, 0xc8, 0x34, 0x02, 0x03, 0xd0, 0x34, 0x02, 0x03, 0xf0, 0x10, 0x03, 0x03, 0xf8, 0x10, 0x03, 0x03, 0x00, 0x11, 0x03, 0x03, + 0xc0, 0x30, 0x04, 0x04, 0xd0, 0x30, 0x04, 0x04, 0x80, 0x0d, 0x05, 0x04, 0x90, 0x0d, 0x05, 0x04, 0xc0, 0x2c, 0x06, 0x05, 0x60, 0x0c, 0x07, 0x05, 0x00, 0x24, 0x0a, 0x07, 0xf0, 0x23, 0x00, 0x03, + 0xf8, 0x23, 0x00, 0x03, 0x00, 0x24, 0x00, 0x03, 0x08, 0x24, 0x00, 0x03, 0xbc, 0x13, 0x01, 0x02, 0xc0, 0x13, 0x01, 0x02, 0xc4, 0x13, 0x01, 0x02, 0xc8, 0x13, 0x01, 0x02, 0xcc, 0x13, 0x01, 0x02, + 0xd0, 0x13, 0x01, 0x02, 0xd8, 0x34, 0x02, 0x03, 0xe0, 0x34, 0x02, 0x03, 0xe8, 0x34, 0x02, 0x03, 0xf0, 0x34, 0x02, 0x03, 0x08, 0x11, 0x03, 0x03, 0x10, 0x11, 0x03, 0x03, 0x18, 0x11, 0x03, 0x03, + 0xe0, 0x30, 0x04, 0x04, 0xf0, 0x30, 0x04, 0x04, 0xa0, 0x0d, 0x05, 0x04, 0xb0, 0x0d, 0x05, 0x04, 0xe0, 0x2c, 0x06, 0x05, 0x80, 0x0c, 0x07, 0x05, 0x80, 0x24, 0x0a, 0x07, 0x10, 0x24, 0x00, 0x03, + 0x18, 0x24, 0x00, 0x03, 0x20, 0x24, 0x00, 0x03, 0x28, 0x24, 0x00, 0x03, 0xd4, 0x13, 0x01, 0x02, 0xd8, 0x13, 0x01, 0x02, 0xdc, 0x13, 0x01, 0x02, 0xe0, 0x13, 0x01, 0x02, 0xe4, 0x13, 0x01, 0x02, + 0xe8, 0x13, 0x01, 0x02, 0xf8, 0x34, 0x02, 0x03, 0x00, 0x35, 0x02, 0x03, 0x08, 0x35, 0x02, 0x03, 0x10, 0x35, 0x02, 0x03, 0x20, 0x11, 0x03, 0x03, 0x28, 0x11, 0x03, 0x03, 0x30, 0x11, 0x03, 0x03, + 0x00, 0x31, 0x04, 0x04, 0x10, 0x31, 0x04, 0x04, 0xc0, 0x0d, 0x05, 0x04, 0xd0, 0x0d, 0x05, 0x04, 0x00, 0x2d, 0x06, 0x05, 0xa0, 0x0c, 0x07, 0x05, 0x00, 0x25, 0x0a, 0x07, 0x30, 0x24, 0x00, 0x03, + 0x38, 0x24, 0x00, 0x03, 0x40, 0x24, 0x00, 0x03, 0x48, 0x24, 0x00, 0x03, 0xec, 0x13, 0x01, 0x02, 0xf0, 0x13, 0x01, 0x02, 0xf4, 0x13, 0x01, 0x02, 0xf8, 0x13, 0x01, 0x02, 0xfc, 0x13, 0x01, 0x02, + 0x00, 0x14, 0x01, 0x02, 0x18, 0x35, 0x02, 0x03, 0x20, 0x35, 0x02, 0x03, 0x28, 0x35, 0x02, 0x03, 0x30, 0x35, 0x02, 0x03, 0x38, 0x11, 0x03, 0x03, 0x40, 0x11, 0x03, 0x03, 0x48, 0x11, 0x03, 0x03, + 0x20, 0x31, 0x04, 0x04, 0x30, 0x31, 0x04, 0x04, 0xe0, 0x0d, 0x05, 0x04, 0xf0, 0x0d, 0x05, 0x04, 0x20, 0x2d, 0x06, 0x05, 0xc0, 0x0c, 0x07, 0x05, 0x80, 0x25, 0x0a, 0x07, 0x50, 0x24, 0x00, 0x03, + 0x58, 0x24, 0x00, 0x03, 0x60, 0x24, 0x00, 0x03, 0x68, 0x24, 0x00, 0x03, 0x04, 0x14, 0x01, 0x02, 0x08, 0x14, 0x01, 0x02, 0x0c, 0x14, 0x01, 0x02, 0x10, 0x14, 0x01, 0x02, 0x14, 0x14, 0x01, 0x02, + 0x18, 0x14, 0x01, 0x02, 0x38, 0x35, 0x02, 0x03, 0x40, 0x35, 0x02, 0x03, 0x48, 0x35, 0x02, 0x03, 0x50, 0x35, 0x02, 0x03, 0x50, 0x11, 0x03, 0x03, 0x58, 0x11, 0x03, 0x03, 0x60, 0x11, 0x03, 0x03, + 0x40, 0x31, 0x04, 0x04, 0x50, 0x31, 0x04, 0x04, 0x00, 0x0e, 0x05, 0x04, 0x10, 0x0e, 0x05, 0x04, 0x40, 0x2d, 0x06, 0x05, 0xe0, 0x0c, 0x07, 0x05, 0x00, 0x26, 0x0a, 0x07, 0x70, 0x24, 0x00, 0x03, + 0x78, 0x24, 0x00, 0x03, 0x80, 0x24, 0x00, 0x03, 0x88, 0x24, 0x00, 0x03, 0x1c, 0x14, 0x01, 0x02, 0x20, 0x14, 0x01, 0x02, 0x24, 0x14, 0x01, 0x02, 0x28, 0x14, 0x01, 0x02, 0x2c, 0x14, 0x01, 0x02, + 0x30, 0x14, 0x01, 0x02, 0x58, 0x35, 0x02, 0x03, 0x60, 0x35, 0x02, 0x03, 0x68, 0x35, 0x02, 0x03, 0x70, 0x35, 0x02, 0x03, 0x68, 0x11, 0x03, 0x03, 0x70, 0x11, 0x03, 0x03, 0x78, 0x11, 0x03, 0x03, + 0x60, 0x31, 0x04, 0x04, 0x70, 0x31, 0x04, 0x04, 0x20, 0x0e, 0x05, 0x04, 0x30, 0x0e, 0x05, 0x04, 0x60, 0x2d, 0x06, 0x05, 0x00, 0x0d, 0x07, 0x05, 0x80, 0x26, 0x0a, 0x07, 0x90, 0x24, 0x00, 0x03, + 0x98, 0x24, 0x00, 0x03, 0xa0, 0x24, 0x00, 0x03, 0xa8, 0x24, 0x00, 0x03, 0x34, 0x14, 0x01, 0x02, 0x38, 0x14, 0x01, 0x02, 0x3c, 0x14, 0x01, 0x02, 0x40, 0x14, 0x01, 0x02, 0x44, 0x14, 0x01, 0x02, + 0x48, 0x14, 0x01, 0x02, 0x78, 0x35, 0x02, 0x03, 0x80, 0x35, 0x02, 0x03, 0x88, 0x35, 0x02, 0x03, 0x90, 0x35, 0x02, 0x03, 0x80, 0x11, 0x03, 0x03, 0x88, 0x11, 0x03, 0x03, 0x90, 0x11, 0x03, 0x03, + 0x80, 0x31, 0x04, 0x04, 0x90, 0x31, 0x04, 0x04, 0x40, 0x0e, 0x05, 0x04, 0x50, 0x0e, 0x05, 0x04, 0x80, 0x2d, 0x06, 0x05, 0x20, 0x0d, 0x07, 0x05, 0x00, 0x27, 0x0a, 0x07, 0xb0, 0x24, 0x00, 0x03, + 0xb8, 0x24, 0x00, 0x03, 0xc0, 0x24, 0x00, 0x03, 0xc8, 0x24, 0x00, 0x03, 0x4c, 0x14, 0x01, 0x02, 0x50, 0x14, 0x01, 0x02, 0x54, 0x14, 0x01, 0x02, 0x58, 0x14, 0x01, 0x02, 0x5c, 0x14, 0x01, 0x02, + 0x60, 0x14, 0x01, 0x02, 0x98, 0x35, 0x02, 0x03, 0xa0, 0x35, 0x02, 0x03, 0xa8, 0x35, 0x02, 0x03, 0xb0, 0x35, 0x02, 0x03, 0x98, 0x11, 0x03, 0x03, 0xa0, 0x11, 0x03, 0x03, 0xa8, 0x11, 0x03, 0x03, + 0xa0, 0x31, 0x04, 0x04, 0xb0, 0x31, 0x04, 0x04, 0x60, 0x0e, 0x05, 0x04, 0x70, 0x0e, 0x05, 0x04, 0xa0, 0x2d, 0x06, 0x05, 0x40, 0x0d, 0x07, 0x05, 0x80, 0x27, 0x0a, 0x07, 0xd0, 0x24, 0x00, 0x03, + 0xd8, 0x24, 0x00, 0x03, 0xe0, 0x24, 0x00, 0x03, 0xe8, 0x24, 0x00, 0x03, 0x64, 0x14, 0x01, 0x02, 0x68, 0x14, 0x01, 0x02, 0x6c, 0x14, 0x01, 0x02, 0x70, 0x14, 0x01, 0x02, 0x74, 0x14, 0x01, 0x02, + 0x78, 0x14, 0x01, 0x02, 0xb8, 0x35, 0x02, 0x03, 0xc0, 0x35, 0x02, 0x03, 0xc8, 0x35, 0x02, 0x03, 0xd0, 0x35, 0x02, 0x03, 0xb0, 0x11, 0x03, 0x03, 0xb8, 0x11, 0x03, 0x03, 0xc0, 0x11, 0x03, 0x03, + 0xc0, 0x31, 0x04, 0x04, 0xd0, 0x31, 0x04, 0x04, 0x80, 0x0e, 0x05, 0x04, 0x90, 0x0e, 0x05, 0x04, 0xc0, 0x2d, 0x06, 0x05, 0x60, 0x0d, 0x07, 0x05, 0x00, 0x28, 0x0a, 0x07, 0xf0, 0x24, 0x00, 0x03, + 0xf8, 0x24, 0x00, 0x03, 0x00, 0x25, 0x00, 0x03, 0x08, 0x25, 0x00, 0x03, 0x7c, 0x14, 0x01, 0x02, 0x80, 0x14, 0x01, 0x02, 0x84, 0x14, 0x01, 0x02, 0x88, 0x14, 0x01, 0x02, 0x8c, 0x14, 0x01, 0x02, + 0x90, 0x14, 0x01, 0x02, 0xd8, 0x35, 0x02, 0x03, 0xe0, 0x35, 0x02, 0x03, 0xe8, 0x35, 0x02, 0x03, 0xf0, 0x35, 0x02, 0x03, 0xc8, 0x11, 0x03, 0x03, 0xd0, 0x11, 0x03, 0x03, 0xd8, 0x11, 0x03, 0x03, + 0xe0, 0x31, 0x04, 0x04, 0xf0, 0x31, 0x04, 0x04, 0xa0, 0x0e, 0x05, 0x04, 0xb0, 0x0e, 0x05, 0x04, 0xe0, 0x2d, 0x06, 0x05, 0x80, 0x0d, 0x07, 0x05, 0x80, 0x28, 0x0a, 0x07, 0x10, 0x25, 0x00, 0x03, + 0x18, 0x25, 0x00, 0x03, 0x20, 0x25, 0x00, 0x03, 0x28, 0x25, 0x00, 0x03, 0x94, 0x14, 0x01, 0x02, 0x98, 0x14, 0x01, 0x02, 0x9c, 0x14, 0x01, 0x02, 0xa0, 0x14, 0x01, 0x02, 0xa4, 0x14, 0x01, 0x02, + 0xa8, 0x14, 0x01, 0x02, 0xf8, 0x35, 0x02, 0x03, 0x00, 0x36, 0x02, 0x03, 0x08, 0x36, 0x02, 0x03, 0x10, 0x36, 0x02, 0x03, 0xe0, 0x11, 0x03, 0x03, 0xe8, 0x11, 0x03, 0x03, 0xf0, 0x11, 0x03, 0x03, + 0x00, 0x32, 0x04, 0x04, 0x10, 0x32, 0x04, 0x04, 0xc0, 0x0e, 0x05, 0x04, 0xd0, 0x0e, 0x05, 0x04, 0x00, 0x2e, 0x06, 0x05, 0xa0, 0x0d, 0x07, 0x05, 0x00, 0x29, 0x0a, 0x07, 0x30, 0x25, 0x00, 0x03, + 0x38, 0x25, 0x00, 0x03, 0x40, 0x25, 0x00, 0x03, 0x48, 0x25, 0x00, 0x03, 0xac, 0x14, 0x01, 0x02, 0xb0, 0x14, 0x01, 0x02, 0xb4, 0x14, 0x01, 0x02, 0xb8, 0x14, 0x01, 0x02, 0xbc, 0x14, 0x01, 0x02, + 0xc0, 0x14, 0x01, 0x02, 0x18, 0x36, 0x02, 0x03, 0x20, 0x36, 0x02, 0x03, 0x28, 0x36, 0x02, 0x03, 0x30, 0x36, 0x02, 0x03, 0xf8, 0x11, 0x03, 0x03, 0x00, 0x12, 0x03, 0x03, 0x08, 0x12, 0x03, 0x03, + 0x20, 0x32, 0x04, 0x04, 0x30, 0x32, 0x04, 0x04, 0xe0, 0x0e, 0x05, 0x04, 0xf0, 0x0e, 0x05, 0x04, 0x20, 0x2e, 0x06, 0x05, 0xc0, 0x0d, 0x07, 0x05, 0x80, 0x29, 0x0a, 0x07, 0x50, 0x25, 0x00, 0x03, + 0x58, 0x25, 0x00, 0x03, 0x60, 0x25, 0x00, 0x03, 0x68, 0x25, 0x00, 0x03, 0xc4, 0x14, 0x01, 0x02, 0xc8, 0x14, 0x01, 0x02, 0xcc, 0x14, 0x01, 0x02, 0xd0, 0x14, 0x01, 0x02, 0xd4, 0x14, 0x01, 0x02, + 0xd8, 0x14, 0x01, 0x02, 0x38, 0x36, 0x02, 0x03, 0x40, 0x36, 0x02, 0x03, 0x48, 0x36, 0x02, 0x03, 0x50, 0x36, 0x02, 0x03, 0x10, 0x12, 0x03, 0x03, 0x18, 0x12, 0x03, 0x03, 0x20, 0x12, 0x03, 0x03, + 0x40, 0x32, 0x04, 0x04, 0x50, 0x32, 0x04, 0x04, 0x00, 0x0f, 0x05, 0x04, 0x10, 0x0f, 0x05, 0x04, 0x40, 0x2e, 0x06, 0x05, 0xe0, 0x0d, 0x07, 0x05, 0x00, 0x2a, 0x0a, 0x07, 0x70, 0x25, 0x00, 0x03, + 0x78, 0x25, 0x00, 0x03, 0x80, 0x25, 0x00, 0x03, 0x88, 0x25, 0x00, 0x03, 0xdc, 0x14, 0x01, 0x02, 0xe0, 0x14, 0x01, 0x02, 0xe4, 0x14, 0x01, 0x02, 0xe8, 0x14, 0x01, 0x02, 0xec, 0x14, 0x01, 0x02, + 0xf0, 0x14, 0x01, 0x02, 0x58, 0x36, 0x02, 0x03, 0x60, 0x36, 0x02, 0x03, 0x68, 0x36, 0x02, 0x03, 0x70, 0x36, 0x02, 0x03, 0x28, 0x12, 0x03, 0x03, 0x30, 0x12, 0x03, 0x03, 0x38, 0x12, 0x03, 0x03, + 0x60, 0x32, 0x04, 0x04, 0x70, 0x32, 0x04, 0x04, 0x20, 0x0f, 0x05, 0x04, 0x30, 0x0f, 0x05, 0x04, 0x60, 0x2e, 0x06, 0x05, 0x40, 0x26, 0x08, 0x06, 0x80, 0x2a, 0x0a, 0x07, 0x90, 0x25, 0x00, 0x03, + 0x98, 0x25, 0x00, 0x03, 0xa0, 0x25, 0x00, 0x03, 0xa8, 0x25, 0x00, 0x03, 0xf4, 0x14, 0x01, 0x02, 0xf8, 0x14, 0x01, 0x02, 0xfc, 0x14, 0x01, 0x02, 0x00, 0x15, 0x01, 0x02, 0x04, 0x15, 0x01, 0x02, + 0x08, 0x15, 0x01, 0x02, 0x78, 0x36, 0x02, 0x03, 0x80, 0x36, 0x02, 0x03, 0x88, 0x36, 0x02, 0x03, 0x90, 0x36, 0x02, 0x03, 0x40, 0x12, 0x03, 0x03, 0x48, 0x12, 0x03, 0x03, 0x50, 0x12, 0x03, 0x03, + 0x80, 0x32, 0x04, 0x04, 0x90, 0x32, 0x04, 0x04, 0x40, 0x0f, 0x05, 0x04, 0x50, 0x0f, 0x05, 0x04, 0x80, 0x2e, 0x06, 0x05, 0x80, 0x26, 0x08, 0x06, 0x00, 0x2b, 0x0a, 0x07, 0xb0, 0x25, 0x00, 0x03, + 0xb8, 0x25, 0x00, 0x03, 0xc0, 0x25, 0x00, 0x03, 0xc8, 0x25, 0x00, 0x03, 0x0c, 0x15, 0x01, 0x02, 0x10, 0x15, 0x01, 0x02, 0x14, 0x15, 0x01, 0x02, 0x18, 0x15, 0x01, 0x02, 0x1c, 0x15, 0x01, 0x02, + 0x20, 0x15, 0x01, 0x02, 0x98, 0x36, 0x02, 0x03, 0xa0, 0x36, 0x02, 0x03, 0xa8, 0x36, 0x02, 0x03, 0xb0, 0x36, 0x02, 0x03, 0x58, 0x12, 0x03, 0x03, 0x60, 0x12, 0x03, 0x03, 0x68, 0x12, 0x03, 0x03, + 0xa0, 0x32, 0x04, 0x04, 0xb0, 0x32, 0x04, 0x04, 0x60, 0x0f, 0x05, 0x04, 0x70, 0x0f, 0x05, 0x04, 0xa0, 0x2e, 0x06, 0x05, 0xc0, 0x26, 0x08, 0x06, 0x80, 0x2b, 0x0a, 0x07, 0xd0, 0x25, 0x00, 0x03, + 0xd8, 0x25, 0x00, 0x03, 0xe0, 0x25, 0x00, 0x03, 0xe8, 0x25, 0x00, 0x03, 0x24, 0x15, 0x01, 0x02, 0x28, 0x15, 0x01, 0x02, 0x2c, 0x15, 0x01, 0x02, 0x30, 0x15, 0x01, 0x02, 0x34, 0x15, 0x01, 0x02, + 0x38, 0x15, 0x01, 0x02, 0xb8, 0x36, 0x02, 0x03, 0xc0, 0x36, 0x02, 0x03, 0xc8, 0x36, 0x02, 0x03, 0xd0, 0x36, 0x02, 0x03, 0x70, 0x12, 0x03, 0x03, 0x78, 0x12, 0x03, 0x03, 0x80, 0x12, 0x03, 0x03, + 0xc0, 0x32, 0x04, 0x04, 0xd0, 0x32, 0x04, 0x04, 0x80, 0x0f, 0x05, 0x04, 0x90, 0x0f, 0x05, 0x04, 0xc0, 0x2e, 0x06, 0x05, 0x00, 0x27, 0x08, 0x06, 0x00, 0x2c, 0x0a, 0x07, 0xf0, 0x25, 0x00, 0x03, + 0xf8, 0x25, 0x00, 0x03, 0x00, 0x26, 0x00, 0x03, 0x08, 0x26, 0x00, 0x03, 0x3c, 0x15, 0x01, 0x02, 0x40, 0x15, 0x01, 0x02, 0x44, 0x15, 0x01, 0x02, 0x48, 0x15, 0x01, 0x02, 0x4c, 0x15, 0x01, 0x02, + 0x50, 0x15, 0x01, 0x02, 0xd8, 0x36, 0x02, 0x03, 0xe0, 0x36, 0x02, 0x03, 0xe8, 0x36, 0x02, 0x03, 0xf0, 0x36, 0x02, 0x03, 0x88, 0x12, 0x03, 0x03, 0x90, 0x12, 0x03, 0x03, 0x98, 0x12, 0x03, 0x03, + 0xe0, 0x32, 0x04, 0x04, 0xf0, 0x32, 0x04, 0x04, 0xa0, 0x0f, 0x05, 0x04, 0xb0, 0x0f, 0x05, 0x04, 0xe0, 0x2e, 0x06, 0x05, 0x40, 0x27, 0x08, 0x06, 0x80, 0x2c, 0x0a, 0x07, 0x10, 0x26, 0x00, 0x03, + 0x18, 0x26, 0x00, 0x03, 0x20, 0x26, 0x00, 0x03, 0x28, 0x26, 0x00, 0x03, 0x54, 0x15, 0x01, 0x02, 0x58, 0x15, 0x01, 0x02, 0x5c, 0x15, 0x01, 0x02, 0x60, 0x15, 0x01, 0x02, 0x64, 0x15, 0x01, 0x02, + 0x68, 0x15, 0x01, 0x02, 0xf8, 0x36, 0x02, 0x03, 0x00, 0x37, 0x02, 0x03, 0x08, 0x37, 0x02, 0x03, 0x10, 0x37, 0x02, 0x03, 0xa0, 0x12, 0x03, 0x03, 0xa8, 0x12, 0x03, 0x03, 0xb0, 0x12, 0x03, 0x03, + 0x00, 0x33, 0x04, 0x04, 0x10, 0x33, 0x04, 0x04, 0xc0, 0x0f, 0x05, 0x04, 0xd0, 0x0f, 0x05, 0x04, 0x00, 0x2f, 0x06, 0x05, 0x80, 0x27, 0x08, 0x06, 0x80, 0x04, 0x0b, 0x07, 0x30, 0x26, 0x00, 0x03, + 0x38, 0x26, 0x00, 0x03, 0x40, 0x26, 0x00, 0x03, 0x48, 0x26, 0x00, 0x03, 0x6c, 0x15, 0x01, 0x02, 0x70, 0x15, 0x01, 0x02, 0x74, 0x15, 0x01, 0x02, 0x78, 0x15, 0x01, 0x02, 0x7c, 0x15, 0x01, 0x02, + 0x80, 0x15, 0x01, 0x02, 0x18, 0x37, 0x02, 0x03, 0x20, 0x37, 0x02, 0x03, 0x28, 0x37, 0x02, 0x03, 0x30, 0x37, 0x02, 0x03, 0xb8, 0x12, 0x03, 0x03, 0xc0, 0x12, 0x03, 0x03, 0xc8, 0x12, 0x03, 0x03, + 0x20, 0x33, 0x04, 0x04, 0x30, 0x33, 0x04, 0x04, 0xe0, 0x0f, 0x05, 0x04, 0xf0, 0x0f, 0x05, 0x04, 0x20, 0x2f, 0x06, 0x05, 0xc0, 0x27, 0x08, 0x06, 0x00, 0x05, 0x0b, 0x07, 0x50, 0x26, 0x00, 0x03, + 0x58, 0x26, 0x00, 0x03, 0x60, 0x26, 0x00, 0x03, 0x68, 0x26, 0x00, 0x03, 0x84, 0x15, 0x01, 0x02, 0x88, 0x15, 0x01, 0x02, 0x8c, 0x15, 0x01, 0x02, 0x90, 0x15, 0x01, 0x02, 0x94, 0x15, 0x01, 0x02, + 0x98, 0x15, 0x01, 0x02, 0x38, 0x37, 0x02, 0x03, 0x40, 0x37, 0x02, 0x03, 0x48, 0x37, 0x02, 0x03, 0x50, 0x37, 0x02, 0x03, 0xd0, 0x12, 0x03, 0x03, 0xd8, 0x12, 0x03, 0x03, 0xe0, 0x12, 0x03, 0x03, + 0x40, 0x33, 0x04, 0x04, 0x50, 0x33, 0x04, 0x04, 0x00, 0x10, 0x05, 0x04, 0x10, 0x10, 0x05, 0x04, 0x40, 0x2f, 0x06, 0x05, 0x00, 0x28, 0x08, 0x06, 0x80, 0x05, 0x0b, 0x07, 0x70, 0x26, 0x00, 0x03, + 0x78, 0x26, 0x00, 0x03, 0x80, 0x26, 0x00, 0x03, 0x88, 0x26, 0x00, 0x03, 0x9c, 0x15, 0x01, 0x02, 0xa0, 0x15, 0x01, 0x02, 0xa4, 0x15, 0x01, 0x02, 0xa8, 0x15, 0x01, 0x02, 0xac, 0x15, 0x01, 0x02, + 0xb0, 0x15, 0x01, 0x02, 0x58, 0x37, 0x02, 0x03, 0x60, 0x37, 0x02, 0x03, 0x68, 0x37, 0x02, 0x03, 0x70, 0x37, 0x02, 0x03, 0xe8, 0x12, 0x03, 0x03, 0xf0, 0x12, 0x03, 0x03, 0xf8, 0x12, 0x03, 0x03, + 0x60, 0x33, 0x04, 0x04, 0x70, 0x33, 0x04, 0x04, 0x20, 0x10, 0x05, 0x04, 0x30, 0x10, 0x05, 0x04, 0x60, 0x2f, 0x06, 0x05, 0x40, 0x28, 0x08, 0x06, 0x00, 0x06, 0x0b, 0x07, 0x90, 0x26, 0x00, 0x03, + 0x98, 0x26, 0x00, 0x03, 0xa0, 0x26, 0x00, 0x03, 0xa8, 0x26, 0x00, 0x03, 0xb4, 0x15, 0x01, 0x02, 0xb8, 0x15, 0x01, 0x02, 0xbc, 0x15, 0x01, 0x02, 0xc0, 0x15, 0x01, 0x02, 0xc4, 0x15, 0x01, 0x02, + 0xc8, 0x15, 0x01, 0x02, 0x78, 0x37, 0x02, 0x03, 0x80, 0x37, 0x02, 0x03, 0x88, 0x37, 0x02, 0x03, 0x90, 0x37, 0x02, 0x03, 0x00, 0x13, 0x03, 0x03, 0x08, 0x13, 0x03, 0x03, 0x10, 0x13, 0x03, 0x03, + 0x80, 0x33, 0x04, 0x04, 0x90, 0x33, 0x04, 0x04, 0x40, 0x10, 0x05, 0x04, 0x50, 0x10, 0x05, 0x04, 0x80, 0x2f, 0x06, 0x05, 0x80, 0x28, 0x08, 0x06, 0x80, 0x06, 0x0b, 0x07, 0xb0, 0x26, 0x00, 0x03, + 0xb8, 0x26, 0x00, 0x03, 0xc0, 0x26, 0x00, 0x03, 0xc8, 0x26, 0x00, 0x03, 0xcc, 0x15, 0x01, 0x02, 0xd0, 0x15, 0x01, 0x02, 0xd4, 0x15, 0x01, 0x02, 0xd8, 0x15, 0x01, 0x02, 0xdc, 0x15, 0x01, 0x02, + 0xe0, 0x15, 0x01, 0x02, 0x98, 0x37, 0x02, 0x03, 0xa0, 0x37, 0x02, 0x03, 0xa8, 0x37, 0x02, 0x03, 0xb0, 0x37, 0x02, 0x03, 0x18, 0x13, 0x03, 0x03, 0x20, 0x13, 0x03, 0x03, 0x28, 0x13, 0x03, 0x03, + 0xa0, 0x33, 0x04, 0x04, 0xb0, 0x33, 0x04, 0x04, 0x60, 0x10, 0x05, 0x04, 0x70, 0x10, 0x05, 0x04, 0xa0, 0x2f, 0x06, 0x05, 0xc0, 0x28, 0x08, 0x06, 0x00, 0x07, 0x0b, 0x07, 0xd0, 0x26, 0x00, 0x03, + 0xd8, 0x26, 0x00, 0x03, 0xe0, 0x26, 0x00, 0x03, 0xe8, 0x26, 0x00, 0x03, 0xe4, 0x15, 0x01, 0x02, 0xe8, 0x15, 0x01, 0x02, 0xec, 0x15, 0x01, 0x02, 0xf0, 0x15, 0x01, 0x02, 0xf4, 0x15, 0x01, 0x02, + 0xf8, 0x15, 0x01, 0x02, 0xb8, 0x37, 0x02, 0x03, 0xc0, 0x37, 0x02, 0x03, 0xc8, 0x37, 0x02, 0x03, 0xd0, 0x37, 0x02, 0x03, 0x30, 0x13, 0x03, 0x03, 0x38, 0x13, 0x03, 0x03, 0x40, 0x13, 0x03, 0x03, + 0xc0, 0x33, 0x04, 0x04, 0xd0, 0x33, 0x04, 0x04, 0x80, 0x10, 0x05, 0x04, 0x90, 0x10, 0x05, 0x04, 0xc0, 0x2f, 0x06, 0x05, 0x00, 0x29, 0x08, 0x06, 0x80, 0x07, 0x0b, 0x07, 0xf0, 0x26, 0x00, 0x03, + 0xf8, 0x26, 0x00, 0x03, 0x00, 0x27, 0x00, 0x03, 0x08, 0x27, 0x00, 0x03, 0xfc, 0x15, 0x01, 0x02, 0x00, 0x16, 0x01, 0x02, 0x04, 0x16, 0x01, 0x02, 0x08, 0x16, 0x01, 0x02, 0x0c, 0x16, 0x01, 0x02, + 0x10, 0x16, 0x01, 0x02, 0xd8, 0x37, 0x02, 0x03, 0xe0, 0x37, 0x02, 0x03, 0xe8, 0x37, 0x02, 0x03, 0xf0, 0x37, 0x02, 0x03, 0x48, 0x13, 0x03, 0x03, 0x50, 0x13, 0x03, 0x03, 0x58, 0x13, 0x03, 0x03, + 0xe0, 0x33, 0x04, 0x04, 0xf0, 0x33, 0x04, 0x04, 0xa0, 0x10, 0x05, 0x04, 0xb0, 0x10, 0x05, 0x04, 0xe0, 0x2f, 0x06, 0x05, 0x40, 0x29, 0x08, 0x06, 0x00, 0x08, 0x0b, 0x07, 0x10, 0x27, 0x00, 0x03, + 0x18, 0x27, 0x00, 0x03, 0x20, 0x27, 0x00, 0x03, 0x28, 0x27, 0x00, 0x03, 0x14, 0x16, 0x01, 0x02, 0x18, 0x16, 0x01, 0x02, 0x1c, 0x16, 0x01, 0x02, 0x20, 0x16, 0x01, 0x02, 0x24, 0x16, 0x01, 0x02, + 0x28, 0x16, 0x01, 0x02, 0xf8, 0x37, 0x02, 0x03, 0x00, 0x38, 0x02, 0x03, 0x08, 0x38, 0x02, 0x03, 0x10, 0x38, 0x02, 0x03, 0x60, 0x13, 0x03, 0x03, 0x68, 0x13, 0x03, 0x03, 0x70, 0x13, 0x03, 0x03, + 0x00, 0x34, 0x04, 0x04, 0x10, 0x34, 0x04, 0x04, 0xc0, 0x10, 0x05, 0x04, 0xd0, 0x10, 0x05, 0x04, 0x00, 0x30, 0x06, 0x05, 0x80, 0x29, 0x08, 0x06, 0x80, 0x08, 0x0b, 0x07, 0x30, 0x27, 0x00, 0x03, + 0x38, 0x27, 0x00, 0x03, 0x40, 0x27, 0x00, 0x03, 0x48, 0x27, 0x00, 0x03, 0x2c, 0x16, 0x01, 0x02, 0x30, 0x16, 0x01, 0x02, 0x34, 0x16, 0x01, 0x02, 0x38, 0x16, 0x01, 0x02, 0x3c, 0x16, 0x01, 0x02, + 0x40, 0x16, 0x01, 0x02, 0x18, 0x38, 0x02, 0x03, 0x20, 0x38, 0x02, 0x03, 0x28, 0x38, 0x02, 0x03, 0x30, 0x38, 0x02, 0x03, 0x78, 0x13, 0x03, 0x03, 0x80, 0x13, 0x03, 0x03, 0x88, 0x13, 0x03, 0x03, + 0x20, 0x34, 0x04, 0x04, 0x30, 0x34, 0x04, 0x04, 0xe0, 0x10, 0x05, 0x04, 0xf0, 0x10, 0x05, 0x04, 0x20, 0x30, 0x06, 0x05, 0xc0, 0x29, 0x08, 0x06, 0x00, 0x09, 0x0b, 0x07, 0x50, 0x27, 0x00, 0x03, + 0x58, 0x27, 0x00, 0x03, 0x60, 0x27, 0x00, 0x03, 0x68, 0x27, 0x00, 0x03, 0x44, 0x16, 0x01, 0x02, 0x48, 0x16, 0x01, 0x02, 0x4c, 0x16, 0x01, 0x02, 0x50, 0x16, 0x01, 0x02, 0x54, 0x16, 0x01, 0x02, + 0x58, 0x16, 0x01, 0x02, 0x38, 0x38, 0x02, 0x03, 0x40, 0x38, 0x02, 0x03, 0x48, 0x38, 0x02, 0x03, 0x50, 0x38, 0x02, 0x03, 0x90, 0x13, 0x03, 0x03, 0x98, 0x13, 0x03, 0x03, 0xa0, 0x13, 0x03, 0x03, + 0x40, 0x34, 0x04, 0x04, 0x50, 0x34, 0x04, 0x04, 0x00, 0x11, 0x05, 0x04, 0x10, 0x11, 0x05, 0x04, 0x40, 0x30, 0x06, 0x05, 0x00, 0x2a, 0x08, 0x06, 0x80, 0x09, 0x0b, 0x07, 0x70, 0x27, 0x00, 0x03, + 0x78, 0x27, 0x00, 0x03, 0x80, 0x27, 0x00, 0x03, 0x88, 0x27, 0x00, 0x03, 0x5c, 0x16, 0x01, 0x02, 0x60, 0x16, 0x01, 0x02, 0x64, 0x16, 0x01, 0x02, 0x68, 0x16, 0x01, 0x02, 0x6c, 0x16, 0x01, 0x02, + 0x70, 0x16, 0x01, 0x02, 0x58, 0x38, 0x02, 0x03, 0x60, 0x38, 0x02, 0x03, 0x68, 0x38, 0x02, 0x03, 0x70, 0x38, 0x02, 0x03, 0xa8, 0x13, 0x03, 0x03, 0xb0, 0x13, 0x03, 0x03, 0xb8, 0x13, 0x03, 0x03, + 0x60, 0x34, 0x04, 0x04, 0x70, 0x34, 0x04, 0x04, 0x20, 0x11, 0x05, 0x04, 0x30, 0x11, 0x05, 0x04, 0x60, 0x30, 0x06, 0x05, 0x40, 0x2a, 0x08, 0x06, 0x00, 0x0a, 0x0b, 0x07, 0x90, 0x27, 0x00, 0x03, + 0x98, 0x27, 0x00, 0x03, 0xa0, 0x27, 0x00, 0x03, 0xa8, 0x27, 0x00, 0x03, 0x74, 0x16, 0x01, 0x02, 0x78, 0x16, 0x01, 0x02, 0x7c, 0x16, 0x01, 0x02, 0x80, 0x16, 0x01, 0x02, 0x84, 0x16, 0x01, 0x02, + 0x88, 0x16, 0x01, 0x02, 0x78, 0x38, 0x02, 0x03, 0x80, 0x38, 0x02, 0x03, 0x88, 0x38, 0x02, 0x03, 0x90, 0x38, 0x02, 0x03, 0xc0, 0x13, 0x03, 0x03, 0xc8, 0x13, 0x03, 0x03, 0xd0, 0x13, 0x03, 0x03, + 0x80, 0x34, 0x04, 0x04, 0x90, 0x34, 0x04, 0x04, 0x40, 0x11, 0x05, 0x04, 0x50, 0x11, 0x05, 0x04, 0x80, 0x30, 0x06, 0x05, 0x80, 0x2a, 0x08, 0x06, 0x80, 0x0a, 0x0b, 0x07, 0xb0, 0x27, 0x00, 0x03, + 0xb8, 0x27, 0x00, 0x03, 0xc0, 0x27, 0x00, 0x03, 0xc8, 0x27, 0x00, 0x03, 0x8c, 0x16, 0x01, 0x02, 0x90, 0x16, 0x01, 0x02, 0x94, 0x16, 0x01, 0x02, 0x98, 0x16, 0x01, 0x02, 0x9c, 0x16, 0x01, 0x02, + 0xa0, 0x16, 0x01, 0x02, 0x98, 0x38, 0x02, 0x03, 0xa0, 0x38, 0x02, 0x03, 0xa8, 0x38, 0x02, 0x03, 0xb0, 0x38, 0x02, 0x03, 0xd8, 0x13, 0x03, 0x03, 0xe0, 0x13, 0x03, 0x03, 0xe8, 0x13, 0x03, 0x03, + 0xa0, 0x34, 0x04, 0x04, 0xb0, 0x34, 0x04, 0x04, 0x60, 0x11, 0x05, 0x04, 0x70, 0x11, 0x05, 0x04, 0xa0, 0x30, 0x06, 0x05, 0xc0, 0x2a, 0x08, 0x06, 0x00, 0x0b, 0x0b, 0x07, 0xd0, 0x27, 0x00, 0x03, + 0xd8, 0x27, 0x00, 0x03, 0xe0, 0x27, 0x00, 0x03, 0xe8, 0x27, 0x00, 0x03, 0xa4, 0x16, 0x01, 0x02, 0xa8, 0x16, 0x01, 0x02, 0xac, 0x16, 0x01, 0x02, 0xb0, 0x16, 0x01, 0x02, 0xb4, 0x16, 0x01, 0x02, + 0xb8, 0x16, 0x01, 0x02, 0xb8, 0x38, 0x02, 0x03, 0xc0, 0x38, 0x02, 0x03, 0xc8, 0x38, 0x02, 0x03, 0xd0, 0x38, 0x02, 0x03, 0xf0, 0x13, 0x03, 0x03, 0xf8, 0x13, 0x03, 0x03, 0x00, 0x14, 0x03, 0x03, + 0xc0, 0x34, 0x04, 0x04, 0xd0, 0x34, 0x04, 0x04, 0x80, 0x11, 0x05, 0x04, 0x90, 0x11, 0x05, 0x04, 0xc0, 0x30, 0x06, 0x05, 0x00, 0x2b, 0x08, 0x06, 0x00, 0x1f, 0x0c, 0x08, 0xf0, 0x27, 0x00, 0x03, + 0xf8, 0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x03, 0x08, 0x28, 0x00, 0x03, 0xbc, 0x16, 0x01, 0x02, 0xc0, 0x16, 0x01, 0x02, 0xc4, 0x16, 0x01, 0x02, 0xc8, 0x16, 0x01, 0x02, 0xcc, 0x16, 0x01, 0x02, + 0xd0, 0x16, 0x01, 0x02, 0xd8, 0x38, 0x02, 0x03, 0xe0, 0x38, 0x02, 0x03, 0xe8, 0x38, 0x02, 0x03, 0xf0, 0x38, 0x02, 0x03, 0x08, 0x14, 0x03, 0x03, 0x10, 0x14, 0x03, 0x03, 0x18, 0x14, 0x03, 0x03, + 0xe0, 0x34, 0x04, 0x04, 0xf0, 0x34, 0x04, 0x04, 0xa0, 0x11, 0x05, 0x04, 0xb0, 0x11, 0x05, 0x04, 0xe0, 0x30, 0x06, 0x05, 0x40, 0x2b, 0x08, 0x06, 0x00, 0x20, 0x0c, 0x08, 0x10, 0x28, 0x00, 0x03, + 0x18, 0x28, 0x00, 0x03, 0x20, 0x28, 0x00, 0x03, 0x28, 0x28, 0x00, 0x03, 0xd4, 0x16, 0x01, 0x02, 0xd8, 0x16, 0x01, 0x02, 0xdc, 0x16, 0x01, 0x02, 0xe0, 0x16, 0x01, 0x02, 0xe4, 0x16, 0x01, 0x02, + 0xe8, 0x16, 0x01, 0x02, 0xf8, 0x38, 0x02, 0x03, 0x00, 0x39, 0x02, 0x03, 0x08, 0x39, 0x02, 0x03, 0x10, 0x39, 0x02, 0x03, 0x20, 0x14, 0x03, 0x03, 0x28, 0x14, 0x03, 0x03, 0x30, 0x14, 0x03, 0x03, + 0x00, 0x35, 0x04, 0x04, 0x10, 0x35, 0x04, 0x04, 0xc0, 0x11, 0x05, 0x04, 0xd0, 0x11, 0x05, 0x04, 0x00, 0x31, 0x06, 0x05, 0x80, 0x2b, 0x08, 0x06, 0x00, 0x21, 0x0c, 0x08, 0x30, 0x28, 0x00, 0x03, + 0x38, 0x28, 0x00, 0x03, 0x40, 0x28, 0x00, 0x03, 0x48, 0x28, 0x00, 0x03, 0xec, 0x16, 0x01, 0x02, 0xf0, 0x16, 0x01, 0x02, 0xf4, 0x16, 0x01, 0x02, 0xf8, 0x16, 0x01, 0x02, 0xfc, 0x16, 0x01, 0x02, + 0x00, 0x17, 0x01, 0x02, 0x18, 0x39, 0x02, 0x03, 0x20, 0x39, 0x02, 0x03, 0x28, 0x39, 0x02, 0x03, 0x30, 0x39, 0x02, 0x03, 0x38, 0x14, 0x03, 0x03, 0x40, 0x14, 0x03, 0x03, 0x48, 0x14, 0x03, 0x03, + 0x20, 0x35, 0x04, 0x04, 0x30, 0x35, 0x04, 0x04, 0xe0, 0x11, 0x05, 0x04, 0xf0, 0x11, 0x05, 0x04, 0x20, 0x31, 0x06, 0x05, 0xc0, 0x2b, 0x08, 0x06, 0x00, 0x22, 0x0c, 0x08, 0x50, 0x28, 0x00, 0x03, + 0x58, 0x28, 0x00, 0x03, 0x60, 0x28, 0x00, 0x03, 0x68, 0x28, 0x00, 0x03, 0x04, 0x17, 0x01, 0x02, 0x08, 0x17, 0x01, 0x02, 0x0c, 0x17, 0x01, 0x02, 0x10, 0x17, 0x01, 0x02, 0x14, 0x17, 0x01, 0x02, + 0x18, 0x17, 0x01, 0x02, 0x38, 0x39, 0x02, 0x03, 0x40, 0x39, 0x02, 0x03, 0x48, 0x39, 0x02, 0x03, 0x50, 0x39, 0x02, 0x03, 0x50, 0x14, 0x03, 0x03, 0x58, 0x14, 0x03, 0x03, 0x60, 0x14, 0x03, 0x03, + 0x40, 0x35, 0x04, 0x04, 0x50, 0x35, 0x04, 0x04, 0x00, 0x12, 0x05, 0x04, 0x10, 0x12, 0x05, 0x04, 0x40, 0x31, 0x06, 0x05, 0x00, 0x2c, 0x08, 0x06, 0x00, 0x23, 0x0c, 0x08, 0x70, 0x28, 0x00, 0x03, + 0x78, 0x28, 0x00, 0x03, 0x80, 0x28, 0x00, 0x03, 0x1c, 0x17, 0x01, 0x02, 0x20, 0x17, 0x01, 0x02, 0x24, 0x17, 0x01, 0x02, 0x28, 0x17, 0x01, 0x02, 0x2c, 0x17, 0x01, 0x02, 0x30, 0x17, 0x01, 0x02, + 0x34, 0x17, 0x01, 0x02, 0x58, 0x39, 0x02, 0x03, 0x60, 0x39, 0x02, 0x03, 0x68, 0x39, 0x02, 0x03, 0x70, 0x39, 0x02, 0x03, 0x68, 0x14, 0x03, 0x03, 0x70, 0x14, 0x03, 0x03, 0x78, 0x14, 0x03, 0x03, + 0x60, 0x35, 0x04, 0x04, 0x70, 0x35, 0x04, 0x04, 0x20, 0x12, 0x05, 0x04, 0x30, 0x12, 0x05, 0x04, 0x60, 0x31, 0x06, 0x05, 0x40, 0x2c, 0x08, 0x06, 0x00, 0x24, 0x0c, 0x08, 0x88, 0x28, 0x00, 0x03, + 0x90, 0x28, 0x00, 0x03, 0x98, 0x28, 0x00, 0x03, 0x38, 0x17, 0x01, 0x02, 0x3c, 0x17, 0x01, 0x02, 0x40, 0x17, 0x01, 0x02, 0x44, 0x17, 0x01, 0x02, 0x48, 0x17, 0x01, 0x02, 0x4c, 0x17, 0x01, 0x02, + 0x50, 0x17, 0x01, 0x02, 0x78, 0x39, 0x02, 0x03, 0x80, 0x39, 0x02, 0x03, 0x88, 0x39, 0x02, 0x03, 0x90, 0x39, 0x02, 0x03, 0x80, 0x14, 0x03, 0x03, 0x88, 0x14, 0x03, 0x03, 0x90, 0x14, 0x03, 0x03, + 0x80, 0x35, 0x04, 0x04, 0x90, 0x35, 0x04, 0x04, 0x40, 0x12, 0x05, 0x04, 0x80, 0x31, 0x06, 0x05, 0x00, 0x0e, 0x07, 0x05, 0x80, 0x2c, 0x08, 0x06, 0x00, 0x25, 0x0c, 0x08, 0xa0, 0x28, 0x00, 0x03, + 0xa8, 0x28, 0x00, 0x03, 0xb0, 0x28, 0x00, 0x03, 0x54, 0x17, 0x01, 0x02, 0x58, 0x17, 0x01, 0x02, 0x5c, 0x17, 0x01, 0x02, 0x60, 0x17, 0x01, 0x02, 0x64, 0x17, 0x01, 0x02, 0x68, 0x17, 0x01, 0x02, + 0x6c, 0x17, 0x01, 0x02, 0x98, 0x39, 0x02, 0x03, 0xa0, 0x39, 0x02, 0x03, 0xa8, 0x39, 0x02, 0x03, 0xb0, 0x39, 0x02, 0x03, 0x98, 0x14, 0x03, 0x03, 0xa0, 0x14, 0x03, 0x03, 0xa8, 0x14, 0x03, 0x03, + 0xa0, 0x35, 0x04, 0x04, 0xb0, 0x35, 0x04, 0x04, 0x50, 0x12, 0x05, 0x04, 0xa0, 0x31, 0x06, 0x05, 0x20, 0x0e, 0x07, 0x05, 0xc0, 0x2c, 0x08, 0x06, 0x00, 0x26, 0x0c, 0x08, 0xb8, 0x28, 0x00, 0x03, + 0xc0, 0x28, 0x00, 0x03, 0xc8, 0x28, 0x00, 0x03, 0x70, 0x17, 0x01, 0x02, 0x74, 0x17, 0x01, 0x02, 0x78, 0x17, 0x01, 0x02, 0x7c, 0x17, 0x01, 0x02, 0x80, 0x17, 0x01, 0x02, 0x84, 0x17, 0x01, 0x02, + 0x88, 0x17, 0x01, 0x02, 0xb8, 0x39, 0x02, 0x03, 0xc0, 0x39, 0x02, 0x03, 0xc8, 0x39, 0x02, 0x03, 0xd0, 0x39, 0x02, 0x03, 0xb0, 0x14, 0x03, 0x03, 0xb8, 0x14, 0x03, 0x03, 0xc0, 0x14, 0x03, 0x03, + 0xc0, 0x35, 0x04, 0x04, 0xd0, 0x35, 0x04, 0x04, 0x60, 0x12, 0x05, 0x04, 0xc0, 0x31, 0x06, 0x05, 0x40, 0x0e, 0x07, 0x05, 0x00, 0x2d, 0x08, 0x06, 0x00, 0x27, 0x0c, 0x08, 0xd0, 0x28, 0x00, 0x03, + 0xd8, 0x28, 0x00, 0x03, 0xe0, 0x28, 0x00, 0x03, 0x8c, 0x17, 0x01, 0x02, 0x90, 0x17, 0x01, 0x02, 0x94, 0x17, 0x01, 0x02, 0x98, 0x17, 0x01, 0x02, 0x9c, 0x17, 0x01, 0x02, 0xa0, 0x17, 0x01, 0x02, + 0xa4, 0x17, 0x01, 0x02, 0xd8, 0x39, 0x02, 0x03, 0xe0, 0x39, 0x02, 0x03, 0xe8, 0x39, 0x02, 0x03, 0xf0, 0x39, 0x02, 0x03, 0xc8, 0x14, 0x03, 0x03, 0xd0, 0x14, 0x03, 0x03, 0xd8, 0x14, 0x03, 0x03, + 0xe0, 0x35, 0x04, 0x04, 0xf0, 0x35, 0x04, 0x04, 0x70, 0x12, 0x05, 0x04, 0xe0, 0x31, 0x06, 0x05, 0x60, 0x0e, 0x07, 0x05, 0x40, 0x2d, 0x08, 0x06, 0x00, 0x02, 0x0d, 0x08, 0xe8, 0x28, 0x00, 0x03, + 0xf0, 0x28, 0x00, 0x03, 0xf8, 0x28, 0x00, 0x03, 0xa8, 0x17, 0x01, 0x02, 0xac, 0x17, 0x01, 0x02, 0xb0, 0x17, 0x01, 0x02, 0xb4, 0x17, 0x01, 0x02, 0xb8, 0x17, 0x01, 0x02, 0xbc, 0x17, 0x01, 0x02, + 0xc0, 0x17, 0x01, 0x02, 0xf8, 0x39, 0x02, 0x03, 0x00, 0x3a, 0x02, 0x03, 0x08, 0x3a, 0x02, 0x03, 0x10, 0x3a, 0x02, 0x03, 0xe0, 0x14, 0x03, 0x03, 0xe8, 0x14, 0x03, 0x03, 0xf0, 0x14, 0x03, 0x03, + 0x00, 0x36, 0x04, 0x04, 0x10, 0x36, 0x04, 0x04, 0x80, 0x12, 0x05, 0x04, 0x00, 0x32, 0x06, 0x05, 0x80, 0x0e, 0x07, 0x05, 0x80, 0x2d, 0x08, 0x06, 0x00, 0x03, 0x0d, 0x08, 0x00, 0x29, 0x00, 0x03, + 0x08, 0x29, 0x00, 0x03, 0x10, 0x29, 0x00, 0x03, 0xc4, 0x17, 0x01, 0x02, 0xc8, 0x17, 0x01, 0x02, 0xcc, 0x17, 0x01, 0x02, 0xd0, 0x17, 0x01, 0x02, 0xd4, 0x17, 0x01, 0x02, 0xd8, 0x17, 0x01, 0x02, + 0xdc, 0x17, 0x01, 0x02, 0x18, 0x3a, 0x02, 0x03, 0x20, 0x3a, 0x02, 0x03, 0x28, 0x3a, 0x02, 0x03, 0x30, 0x3a, 0x02, 0x03, 0xf8, 0x14, 0x03, 0x03, 0x00, 0x15, 0x03, 0x03, 0x08, 0x15, 0x03, 0x03, + 0x20, 0x36, 0x04, 0x04, 0x30, 0x36, 0x04, 0x04, 0x90, 0x12, 0x05, 0x04, 0x20, 0x32, 0x06, 0x05, 0xa0, 0x0e, 0x07, 0x05, 0xc0, 0x2d, 0x08, 0x06, 0x00, 0x04, 0x0d, 0x08, 0x18, 0x29, 0x00, 0x03, + 0x20, 0x29, 0x00, 0x03, 0x28, 0x29, 0x00, 0x03, 0xe0, 0x17, 0x01, 0x02, 0xe4, 0x17, 0x01, 0x02, 0xe8, 0x17, 0x01, 0x02, 0xec, 0x17, 0x01, 0x02, 0xf0, 0x17, 0x01, 0x02, 0xf4, 0x17, 0x01, 0x02, + 0xf8, 0x17, 0x01, 0x02, 0x38, 0x3a, 0x02, 0x03, 0x40, 0x3a, 0x02, 0x03, 0x48, 0x3a, 0x02, 0x03, 0x50, 0x3a, 0x02, 0x03, 0x10, 0x15, 0x03, 0x03, 0x18, 0x15, 0x03, 0x03, 0x20, 0x15, 0x03, 0x03, + 0x40, 0x36, 0x04, 0x04, 0x50, 0x36, 0x04, 0x04, 0xa0, 0x12, 0x05, 0x04, 0x40, 0x32, 0x06, 0x05, 0xc0, 0x0e, 0x07, 0x05, 0x00, 0x2e, 0x08, 0x06, 0x00, 0x05, 0x0d, 0x08, 0x30, 0x29, 0x00, 0x03, + 0x38, 0x29, 0x00, 0x03, 0x40, 0x29, 0x00, 0x03, 0xfc, 0x17, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x04, 0x18, 0x01, 0x02, 0x08, 0x18, 0x01, 0x02, 0x0c, 0x18, 0x01, 0x02, 0x10, 0x18, 0x01, 0x02, + 0x14, 0x18, 0x01, 0x02, 0x58, 0x3a, 0x02, 0x03, 0x60, 0x3a, 0x02, 0x03, 0x68, 0x3a, 0x02, 0x03, 0x70, 0x3a, 0x02, 0x03, 0x28, 0x15, 0x03, 0x03, 0x30, 0x15, 0x03, 0x03, 0x38, 0x15, 0x03, 0x03, + 0x60, 0x36, 0x04, 0x04, 0x70, 0x36, 0x04, 0x04, 0xb0, 0x12, 0x05, 0x04, 0x60, 0x32, 0x06, 0x05, 0xe0, 0x0e, 0x07, 0x05, 0x40, 0x2e, 0x08, 0x06, 0x00, 0x06, 0x0d, 0x08, 0x48, 0x29, 0x00, 0x03, + 0x50, 0x29, 0x00, 0x03, 0x58, 0x29, 0x00, 0x03, 0x18, 0x18, 0x01, 0x02, 0x1c, 0x18, 0x01, 0x02, 0x20, 0x18, 0x01, 0x02, 0x24, 0x18, 0x01, 0x02, 0x28, 0x18, 0x01, 0x02, 0x2c, 0x18, 0x01, 0x02, + 0x30, 0x18, 0x01, 0x02, 0x78, 0x3a, 0x02, 0x03, 0x80, 0x3a, 0x02, 0x03, 0x88, 0x3a, 0x02, 0x03, 0x90, 0x3a, 0x02, 0x03, 0x40, 0x15, 0x03, 0x03, 0x48, 0x15, 0x03, 0x03, 0x50, 0x15, 0x03, 0x03, + 0x80, 0x36, 0x04, 0x04, 0x90, 0x36, 0x04, 0x04, 0xc0, 0x12, 0x05, 0x04, 0x80, 0x32, 0x06, 0x05, 0x00, 0x0f, 0x07, 0x05, 0x80, 0x2e, 0x08, 0x06, 0x00, 0x07, 0x0d, 0x08, 0x60, 0x29, 0x00, 0x03, + 0x68, 0x29, 0x00, 0x03, 0x70, 0x29, 0x00, 0x03, 0x34, 0x18, 0x01, 0x02, 0x38, 0x18, 0x01, 0x02, 0x3c, 0x18, 0x01, 0x02, 0x40, 0x18, 0x01, 0x02, 0x44, 0x18, 0x01, 0x02, 0x48, 0x18, 0x01, 0x02, + 0x4c, 0x18, 0x01, 0x02, 0x98, 0x3a, 0x02, 0x03, 0xa0, 0x3a, 0x02, 0x03, 0xa8, 0x3a, 0x02, 0x03, 0xb0, 0x3a, 0x02, 0x03, 0x58, 0x15, 0x03, 0x03, 0x60, 0x15, 0x03, 0x03, 0x68, 0x15, 0x03, 0x03, + 0xa0, 0x36, 0x04, 0x04, 0xb0, 0x36, 0x04, 0x04, 0xd0, 0x12, 0x05, 0x04, 0xa0, 0x32, 0x06, 0x05, 0x20, 0x0f, 0x07, 0x05, 0xc0, 0x2e, 0x08, 0x06, 0x00, 0x08, 0x0d, 0x08, 0x78, 0x29, 0x00, 0x03, + 0x80, 0x29, 0x00, 0x03, 0x88, 0x29, 0x00, 0x03, 0x50, 0x18, 0x01, 0x02, 0x54, 0x18, 0x01, 0x02, 0x58, 0x18, 0x01, 0x02, 0x5c, 0x18, 0x01, 0x02, 0x60, 0x18, 0x01, 0x02, 0x64, 0x18, 0x01, 0x02, + 0x68, 0x18, 0x01, 0x02, 0xb8, 0x3a, 0x02, 0x03, 0xc0, 0x3a, 0x02, 0x03, 0xc8, 0x3a, 0x02, 0x03, 0xd0, 0x3a, 0x02, 0x03, 0x70, 0x15, 0x03, 0x03, 0x78, 0x15, 0x03, 0x03, 0x80, 0x15, 0x03, 0x03, + 0xc0, 0x36, 0x04, 0x04, 0xd0, 0x36, 0x04, 0x04, 0xe0, 0x12, 0x05, 0x04, 0xc0, 0x32, 0x06, 0x05, 0x40, 0x0f, 0x07, 0x05, 0x00, 0x2f, 0x08, 0x06, 0x00, 0x1e, 0x0e, 0x09, 0x90, 0x29, 0x00, 0x03, + 0x98, 0x29, 0x00, 0x03, 0xa0, 0x29, 0x00, 0x03, 0x6c, 0x18, 0x01, 0x02, 0x70, 0x18, 0x01, 0x02, 0x74, 0x18, 0x01, 0x02, 0x78, 0x18, 0x01, 0x02, 0x7c, 0x18, 0x01, 0x02, 0x80, 0x18, 0x01, 0x02, + 0x84, 0x18, 0x01, 0x02, 0xd8, 0x3a, 0x02, 0x03, 0xe0, 0x3a, 0x02, 0x03, 0xe8, 0x3a, 0x02, 0x03, 0xf0, 0x3a, 0x02, 0x03, 0x88, 0x15, 0x03, 0x03, 0x90, 0x15, 0x03, 0x03, 0x98, 0x15, 0x03, 0x03, + 0xe0, 0x36, 0x04, 0x04, 0xf0, 0x36, 0x04, 0x04, 0xf0, 0x12, 0x05, 0x04, 0xe0, 0x32, 0x06, 0x05, 0x60, 0x0f, 0x07, 0x05, 0x40, 0x2f, 0x08, 0x06, 0x00, 0x20, 0x0e, 0x09, 0xa8, 0x29, 0x00, 0x03, + 0xb0, 0x29, 0x00, 0x03, 0xb8, 0x29, 0x00, 0x03, 0x88, 0x18, 0x01, 0x02, 0x8c, 0x18, 0x01, 0x02, 0x90, 0x18, 0x01, 0x02, 0x94, 0x18, 0x01, 0x02, 0x98, 0x18, 0x01, 0x02, 0x9c, 0x18, 0x01, 0x02, + 0xa0, 0x18, 0x01, 0x02, 0xf8, 0x3a, 0x02, 0x03, 0x00, 0x3b, 0x02, 0x03, 0x08, 0x3b, 0x02, 0x03, 0x10, 0x3b, 0x02, 0x03, 0xa0, 0x15, 0x03, 0x03, 0xa8, 0x15, 0x03, 0x03, 0xb0, 0x15, 0x03, 0x03, + 0x00, 0x37, 0x04, 0x04, 0x10, 0x37, 0x04, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x33, 0x06, 0x05, 0x80, 0x0f, 0x07, 0x05, 0x80, 0x2f, 0x08, 0x06, 0x00, 0x22, 0x0e, 0x09, 0xc0, 0x29, 0x00, 0x03, + 0xc8, 0x29, 0x00, 0x03, 0xd0, 0x29, 0x00, 0x03, 0xa4, 0x18, 0x01, 0x02, 0xa8, 0x18, 0x01, 0x02, 0xac, 0x18, 0x01, 0x02, 0xb0, 0x18, 0x01, 0x02, 0xb4, 0x18, 0x01, 0x02, 0xb8, 0x18, 0x01, 0x02, + 0xbc, 0x18, 0x01, 0x02, 0x18, 0x3b, 0x02, 0x03, 0x20, 0x3b, 0x02, 0x03, 0x28, 0x3b, 0x02, 0x03, 0x30, 0x3b, 0x02, 0x03, 0xb8, 0x15, 0x03, 0x03, 0xc0, 0x15, 0x03, 0x03, 0xc8, 0x15, 0x03, 0x03, + 0x20, 0x37, 0x04, 0x04, 0x30, 0x37, 0x04, 0x04, 0x10, 0x13, 0x05, 0x04, 0x20, 0x33, 0x06, 0x05, 0xa0, 0x0f, 0x07, 0x05, 0xc0, 0x2f, 0x08, 0x06, 0x00, 0x24, 0x0e, 0x09, 0xd8, 0x29, 0x00, 0x03, + 0xe0, 0x29, 0x00, 0x03, 0xe8, 0x29, 0x00, 0x03, 0xc0, 0x18, 0x01, 0x02, 0xc4, 0x18, 0x01, 0x02, 0xc8, 0x18, 0x01, 0x02, 0xcc, 0x18, 0x01, 0x02, 0xd0, 0x18, 0x01, 0x02, 0xd4, 0x18, 0x01, 0x02, + 0xd8, 0x18, 0x01, 0x02, 0x38, 0x3b, 0x02, 0x03, 0x40, 0x3b, 0x02, 0x03, 0x48, 0x3b, 0x02, 0x03, 0x50, 0x3b, 0x02, 0x03, 0xd0, 0x15, 0x03, 0x03, 0xd8, 0x15, 0x03, 0x03, 0xe0, 0x15, 0x03, 0x03, + 0x40, 0x37, 0x04, 0x04, 0x50, 0x37, 0x04, 0x04, 0x20, 0x13, 0x05, 0x04, 0x40, 0x33, 0x06, 0x05, 0xc0, 0x0f, 0x07, 0x05, 0x00, 0x30, 0x08, 0x06, 0x00, 0x02, 0x0f, 0x09, 0xf0, 0x29, 0x00, 0x03, + 0xf8, 0x29, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x03, 0xdc, 0x18, 0x01, 0x02, 0xe0, 0x18, 0x01, 0x02, 0xe4, 0x18, 0x01, 0x02, 0xe8, 0x18, 0x01, 0x02, 0xec, 0x18, 0x01, 0x02, 0xf0, 0x18, 0x01, 0x02, + 0x58, 0x3b, 0x02, 0x03, 0x60, 0x3b, 0x02, 0x03, 0x68, 0x3b, 0x02, 0x03, 0x70, 0x3b, 0x02, 0x03, 0x78, 0x3b, 0x02, 0x03, 0xe8, 0x15, 0x03, 0x03, 0xf0, 0x15, 0x03, 0x03, 0xf8, 0x15, 0x03, 0x03, + 0x60, 0x37, 0x04, 0x04, 0x70, 0x37, 0x04, 0x04, 0x30, 0x13, 0x05, 0x04, 0x60, 0x33, 0x06, 0x05, 0xe0, 0x0f, 0x07, 0x05, 0x40, 0x30, 0x08, 0x06, 0x00, 0x04, 0x0f, 0x09, 0x08, 0x2a, 0x00, 0x03, + 0x10, 0x2a, 0x00, 0x03, 0x18, 0x2a, 0x00, 0x03, 0xf4, 0x18, 0x01, 0x02, 0xf8, 0x18, 0x01, 0x02, 0xfc, 0x18, 0x01, 0x02, 0x00, 0x19, 0x01, 0x02, 0x04, 0x19, 0x01, 0x02, 0x08, 0x19, 0x01, 0x02, + 0x80, 0x3b, 0x02, 0x03, 0x88, 0x3b, 0x02, 0x03, 0x90, 0x3b, 0x02, 0x03, 0x98, 0x3b, 0x02, 0x03, 0xa0, 0x3b, 0x02, 0x03, 0x00, 0x16, 0x03, 0x03, 0x08, 0x16, 0x03, 0x03, 0x10, 0x16, 0x03, 0x03, + 0x80, 0x37, 0x04, 0x04, 0x90, 0x37, 0x04, 0x04, 0x40, 0x13, 0x05, 0x04, 0x80, 0x33, 0x06, 0x05, 0x00, 0x10, 0x07, 0x05, 0x40, 0x0c, 0x09, 0x06, 0x00, 0x06, 0x0f, 0x09, 0x20, 0x2a, 0x00, 0x03, + 0x28, 0x2a, 0x00, 0x03, 0x30, 0x2a, 0x00, 0x03, 0x0c, 0x19, 0x01, 0x02, 0x10, 0x19, 0x01, 0x02, 0x14, 0x19, 0x01, 0x02, 0x18, 0x19, 0x01, 0x02, 0x1c, 0x19, 0x01, 0x02, 0x20, 0x19, 0x01, 0x02, + 0xa8, 0x3b, 0x02, 0x03, 0xb0, 0x3b, 0x02, 0x03, 0xb8, 0x3b, 0x02, 0x03, 0xc0, 0x3b, 0x02, 0x03, 0xc8, 0x3b, 0x02, 0x03, 0x18, 0x16, 0x03, 0x03, 0x20, 0x16, 0x03, 0x03, 0x28, 0x16, 0x03, 0x03, + 0xa0, 0x37, 0x04, 0x04, 0xb0, 0x37, 0x04, 0x04, 0x50, 0x13, 0x05, 0x04, 0xa0, 0x33, 0x06, 0x05, 0x20, 0x10, 0x07, 0x05, 0x80, 0x0c, 0x09, 0x06, 0x00, 0x08, 0x0f, 0x09, 0x38, 0x2a, 0x00, 0x03, + 0x40, 0x2a, 0x00, 0x03, 0x48, 0x2a, 0x00, 0x03, 0x24, 0x19, 0x01, 0x02, 0x28, 0x19, 0x01, 0x02, 0x2c, 0x19, 0x01, 0x02, 0x30, 0x19, 0x01, 0x02, 0x34, 0x19, 0x01, 0x02, 0x38, 0x19, 0x01, 0x02, + 0xd0, 0x3b, 0x02, 0x03, 0xd8, 0x3b, 0x02, 0x03, 0xe0, 0x3b, 0x02, 0x03, 0xe8, 0x3b, 0x02, 0x03, 0xf0, 0x3b, 0x02, 0x03, 0x30, 0x16, 0x03, 0x03, 0x38, 0x16, 0x03, 0x03, 0x40, 0x16, 0x03, 0x03, + 0xc0, 0x37, 0x04, 0x04, 0xd0, 0x37, 0x04, 0x04, 0x60, 0x13, 0x05, 0x04, 0xc0, 0x33, 0x06, 0x05, 0x40, 0x10, 0x07, 0x05, 0xc0, 0x0c, 0x09, 0x06, 0x00, 0x1c, 0x10, 0x0a, 0x50, 0x2a, 0x00, 0x03, + 0x58, 0x2a, 0x00, 0x03, 0x60, 0x2a, 0x00, 0x03, 0x3c, 0x19, 0x01, 0x02, 0x40, 0x19, 0x01, 0x02, 0x44, 0x19, 0x01, 0x02, 0x48, 0x19, 0x01, 0x02, 0x4c, 0x19, 0x01, 0x02, 0x50, 0x19, 0x01, 0x02, + 0xf8, 0x3b, 0x02, 0x03, 0x00, 0x3c, 0x02, 0x03, 0x08, 0x3c, 0x02, 0x03, 0x10, 0x3c, 0x02, 0x03, 0x18, 0x3c, 0x02, 0x03, 0x48, 0x16, 0x03, 0x03, 0x50, 0x16, 0x03, 0x03, 0x58, 0x16, 0x03, 0x03, + 0xe0, 0x37, 0x04, 0x04, 0xf0, 0x37, 0x04, 0x04, 0x70, 0x13, 0x05, 0x04, 0xe0, 0x33, 0x06, 0x05, 0x60, 0x10, 0x07, 0x05, 0x00, 0x0d, 0x09, 0x06, 0x00, 0x20, 0x10, 0x0a, 0x68, 0x2a, 0x00, 0x03, + 0x70, 0x2a, 0x00, 0x03, 0x78, 0x2a, 0x00, 0x03, 0x54, 0x19, 0x01, 0x02, 0x58, 0x19, 0x01, 0x02, 0x5c, 0x19, 0x01, 0x02, 0x60, 0x19, 0x01, 0x02, 0x64, 0x19, 0x01, 0x02, 0x68, 0x19, 0x01, 0x02, + 0x20, 0x3c, 0x02, 0x03, 0x28, 0x3c, 0x02, 0x03, 0x30, 0x3c, 0x02, 0x03, 0x38, 0x3c, 0x02, 0x03, 0x40, 0x3c, 0x02, 0x03, 0x60, 0x16, 0x03, 0x03, 0x68, 0x16, 0x03, 0x03, 0x70, 0x16, 0x03, 0x03, + 0x00, 0x38, 0x04, 0x04, 0x10, 0x38, 0x04, 0x04, 0x80, 0x13, 0x05, 0x04, 0x00, 0x34, 0x06, 0x05, 0x80, 0x10, 0x07, 0x05, 0x40, 0x0d, 0x09, 0x06, 0x00, 0x38, 0x11, 0x0b, 0x80, 0x2a, 0x00, 0x03, + 0x88, 0x2a, 0x00, 0x03, 0x90, 0x2a, 0x00, 0x03, 0x6c, 0x19, 0x01, 0x02, 0x70, 0x19, 0x01, 0x02, 0x74, 0x19, 0x01, 0x02, 0x78, 0x19, 0x01, 0x02, 0x7c, 0x19, 0x01, 0x02, 0x80, 0x19, 0x01, 0x02, + 0x48, 0x3c, 0x02, 0x03, 0x50, 0x3c, 0x02, 0x03, 0x58, 0x3c, 0x02, 0x03, 0x60, 0x3c, 0x02, 0x03, 0x68, 0x3c, 0x02, 0x03, 0x78, 0x16, 0x03, 0x03, 0x80, 0x16, 0x03, 0x03, 0x88, 0x16, 0x03, 0x03, + 0x20, 0x38, 0x04, 0x04, 0x30, 0x38, 0x04, 0x04, 0x90, 0x13, 0x05, 0x04, 0x20, 0x34, 0x06, 0x05, 0xa0, 0x10, 0x07, 0x05, 0x80, 0x0d, 0x09, 0x06, 0x00, 0x00, 0x11, 0x0a, 0x98, 0x2a, 0x00, 0x03, + 0xa0, 0x2a, 0x00, 0x03, 0xa8, 0x2a, 0x00, 0x03, 0x84, 0x19, 0x01, 0x02, 0x88, 0x19, 0x01, 0x02, 0x8c, 0x19, 0x01, 0x02, 0x90, 0x19, 0x01, 0x02, 0x94, 0x19, 0x01, 0x02, 0x98, 0x19, 0x01, 0x02, + 0x70, 0x3c, 0x02, 0x03, 0x78, 0x3c, 0x02, 0x03, 0x80, 0x3c, 0x02, 0x03, 0x88, 0x3c, 0x02, 0x03, 0x90, 0x3c, 0x02, 0x03, 0x90, 0x16, 0x03, 0x03, 0x98, 0x16, 0x03, 0x03, 0xa0, 0x16, 0x03, 0x03, + 0x40, 0x38, 0x04, 0x04, 0x50, 0x38, 0x04, 0x04, 0xa0, 0x13, 0x05, 0x04, 0x40, 0x34, 0x06, 0x05, 0xc0, 0x10, 0x07, 0x05, 0xc0, 0x0d, 0x09, 0x06, 0x00, 0x20, 0x12, 0x0b, 0xb0, 0x2a, 0x00, 0x03, + 0xb8, 0x2a, 0x00, 0x03, 0xc0, 0x2a, 0x00, 0x03, 0x9c, 0x19, 0x01, 0x02, 0xa0, 0x19, 0x01, 0x02, 0xa4, 0x19, 0x01, 0x02, 0xa8, 0x19, 0x01, 0x02, 0xac, 0x19, 0x01, 0x02, 0xb0, 0x19, 0x01, 0x02, + 0x98, 0x3c, 0x02, 0x03, 0xa0, 0x3c, 0x02, 0x03, 0xa8, 0x3c, 0x02, 0x03, 0xb0, 0x3c, 0x02, 0x03, 0xb8, 0x3c, 0x02, 0x03, 0xa8, 0x16, 0x03, 0x03, 0xb0, 0x16, 0x03, 0x03, 0xb8, 0x16, 0x03, 0x03, + 0x60, 0x38, 0x04, 0x04, 0x70, 0x38, 0x04, 0x04, 0xb0, 0x13, 0x05, 0x04, 0x60, 0x34, 0x06, 0x05, 0xe0, 0x10, 0x07, 0x05, 0x00, 0x0e, 0x09, 0x06, 0x00, 0x00, 0x13, 0x0b, 0xc8, 0x2a, 0x00, 0x03, + 0xd0, 0x2a, 0x00, 0x03, 0xd8, 0x2a, 0x00, 0x03, 0xb4, 0x19, 0x01, 0x02, 0xb8, 0x19, 0x01, 0x02, 0xbc, 0x19, 0x01, 0x02, 0xc0, 0x19, 0x01, 0x02, 0xc4, 0x19, 0x01, 0x02, 0xc8, 0x19, 0x01, 0x02, + 0xc0, 0x3c, 0x02, 0x03, 0xc8, 0x3c, 0x02, 0x03, 0xd0, 0x3c, 0x02, 0x03, 0xd8, 0x3c, 0x02, 0x03, 0xe0, 0x3c, 0x02, 0x03, 0xc0, 0x16, 0x03, 0x03, 0xc8, 0x16, 0x03, 0x03, 0xd0, 0x16, 0x03, 0x03, + 0x80, 0x38, 0x04, 0x04, 0x90, 0x38, 0x04, 0x04, 0xc0, 0x13, 0x05, 0x04, 0x80, 0x34, 0x06, 0x05, 0x00, 0x11, 0x07, 0x05, 0x40, 0x0e, 0x09, 0x06, 0x00, 0x10, 0x14, 0x0c, 0xe0, 0x2a, 0x00, 0x03, + 0xe8, 0x2a, 0x00, 0x03, 0xf0, 0x2a, 0x00, 0x03, 0xcc, 0x19, 0x01, 0x02, 0xd0, 0x19, 0x01, 0x02, 0xd4, 0x19, 0x01, 0x02, 0xd8, 0x19, 0x01, 0x02, 0xdc, 0x19, 0x01, 0x02, 0xe0, 0x19, 0x01, 0x02, + 0xe8, 0x3c, 0x02, 0x03, 0xf0, 0x3c, 0x02, 0x03, 0xf8, 0x3c, 0x02, 0x03, 0x00, 0x3d, 0x02, 0x03, 0x08, 0x3d, 0x02, 0x03, 0xd8, 0x16, 0x03, 0x03, 0xe0, 0x16, 0x03, 0x03, 0xe8, 0x16, 0x03, 0x03, + 0xa0, 0x38, 0x04, 0x04, 0xb0, 0x38, 0x04, 0x04, 0xd0, 0x13, 0x05, 0x04, 0xa0, 0x34, 0x06, 0x05, 0x20, 0x11, 0x07, 0x05, 0x80, 0x0e, 0x09, 0x06, 0x00, 0x00, 0x16, 0x0d, 0xf8, 0x2a, 0x00, 0x03, + 0x00, 0x2b, 0x00, 0x03, 0x08, 0x2b, 0x00, 0x03, 0xe4, 0x19, 0x01, 0x02, 0xe8, 0x19, 0x01, 0x02, 0xec, 0x19, 0x01, 0x02, 0xf0, 0x19, 0x01, 0x02, 0xf4, 0x19, 0x01, 0x02, 0xf8, 0x19, 0x01, 0x02, + 0x10, 0x3d, 0x02, 0x03, 0x18, 0x3d, 0x02, 0x03, 0x20, 0x3d, 0x02, 0x03, 0x28, 0x3d, 0x02, 0x03, 0x30, 0x3d, 0x02, 0x03, 0xf0, 0x16, 0x03, 0x03, 0xf8, 0x16, 0x03, 0x03, 0x00, 0x17, 0x03, 0x03, + 0xc0, 0x38, 0x04, 0x04, 0xd0, 0x38, 0x04, 0x04, 0xe0, 0x13, 0x05, 0x04, 0xc0, 0x34, 0x06, 0x05, 0x40, 0x11, 0x07, 0x05, 0xc0, 0x0e, 0x09, 0x06, 0x10, 0x2b, 0x00, 0x03, 0x18, 0x2b, 0x00, 0x03, + 0x20, 0x2b, 0x00, 0x03, 0x28, 0x2b, 0x00, 0x03, 0xfc, 0x19, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x04, 0x1a, 0x01, 0x02, 0x08, 0x1a, 0x01, 0x02, 0x0c, 0x1a, 0x01, 0x02, 0x10, 0x1a, 0x01, 0x02, + 0x38, 0x3d, 0x02, 0x03, 0x40, 0x3d, 0x02, 0x03, 0x48, 0x3d, 0x02, 0x03, 0x50, 0x3d, 0x02, 0x03, 0x58, 0x3d, 0x02, 0x03, 0x08, 0x17, 0x03, 0x03, 0x10, 0x17, 0x03, 0x03, 0x18, 0x17, 0x03, 0x03, + 0xe0, 0x38, 0x04, 0x04, 0xf0, 0x38, 0x04, 0x04, 0xf0, 0x13, 0x05, 0x04, 0xe0, 0x34, 0x06, 0x05, 0x60, 0x11, 0x07, 0x05, 0x00, 0x0f, 0x09, 0x06, 0x30, 0x2b, 0x00, 0x03, 0x38, 0x2b, 0x00, 0x03, + 0x40, 0x2b, 0x00, 0x03, 0x48, 0x2b, 0x00, 0x03, 0x14, 0x1a, 0x01, 0x02, 0x18, 0x1a, 0x01, 0x02, 0x1c, 0x1a, 0x01, 0x02, 0x20, 0x1a, 0x01, 0x02, 0x24, 0x1a, 0x01, 0x02, 0x28, 0x1a, 0x01, 0x02, + 0x60, 0x3d, 0x02, 0x03, 0x68, 0x3d, 0x02, 0x03, 0x70, 0x3d, 0x02, 0x03, 0x78, 0x3d, 0x02, 0x03, 0x80, 0x3d, 0x02, 0x03, 0x20, 0x17, 0x03, 0x03, 0x28, 0x17, 0x03, 0x03, 0x30, 0x17, 0x03, 0x03, + 0x00, 0x39, 0x04, 0x04, 0x10, 0x39, 0x04, 0x04, 0x00, 0x14, 0x05, 0x04, 0x00, 0x35, 0x06, 0x05, 0x80, 0x11, 0x07, 0x05, 0x40, 0x0f, 0x09, 0x06, 0x50, 0x2b, 0x00, 0x03, 0x58, 0x2b, 0x00, 0x03, + 0x60, 0x2b, 0x00, 0x03, 0x68, 0x2b, 0x00, 0x03, 0x2c, 0x1a, 0x01, 0x02, 0x30, 0x1a, 0x01, 0x02, 0x34, 0x1a, 0x01, 0x02, 0x38, 0x1a, 0x01, 0x02, 0x3c, 0x1a, 0x01, 0x02, 0x40, 0x1a, 0x01, 0x02, + 0x88, 0x3d, 0x02, 0x03, 0x90, 0x3d, 0x02, 0x03, 0x98, 0x3d, 0x02, 0x03, 0xa0, 0x3d, 0x02, 0x03, 0xa8, 0x3d, 0x02, 0x03, 0x38, 0x17, 0x03, 0x03, 0x40, 0x17, 0x03, 0x03, 0x48, 0x17, 0x03, 0x03, + 0x20, 0x39, 0x04, 0x04, 0x30, 0x39, 0x04, 0x04, 0x10, 0x14, 0x05, 0x04, 0x20, 0x35, 0x06, 0x05, 0xa0, 0x11, 0x07, 0x05, 0x80, 0x0f, 0x09, 0x06, 0x70, 0x2b, 0x00, 0x03, 0x78, 0x2b, 0x00, 0x03, + 0x80, 0x2b, 0x00, 0x03, 0x88, 0x2b, 0x00, 0x03, 0x44, 0x1a, 0x01, 0x02, 0x48, 0x1a, 0x01, 0x02, 0x4c, 0x1a, 0x01, 0x02, 0x50, 0x1a, 0x01, 0x02, 0x54, 0x1a, 0x01, 0x02, 0x58, 0x1a, 0x01, 0x02, + 0xb0, 0x3d, 0x02, 0x03, 0xb8, 0x3d, 0x02, 0x03, 0xc0, 0x3d, 0x02, 0x03, 0xc8, 0x3d, 0x02, 0x03, 0xd0, 0x3d, 0x02, 0x03, 0x50, 0x17, 0x03, 0x03, 0x58, 0x17, 0x03, 0x03, 0x60, 0x17, 0x03, 0x03, + 0x40, 0x39, 0x04, 0x04, 0x50, 0x39, 0x04, 0x04, 0x20, 0x14, 0x05, 0x04, 0x40, 0x35, 0x06, 0x05, 0xc0, 0x11, 0x07, 0x05, 0xc0, 0x0f, 0x09, 0x06, 0x90, 0x2b, 0x00, 0x03, 0x98, 0x2b, 0x00, 0x03, + 0xa0, 0x2b, 0x00, 0x03, 0xa8, 0x2b, 0x00, 0x03, 0x5c, 0x1a, 0x01, 0x02, 0x60, 0x1a, 0x01, 0x02, 0x64, 0x1a, 0x01, 0x02, 0x68, 0x1a, 0x01, 0x02, 0x6c, 0x1a, 0x01, 0x02, 0x70, 0x1a, 0x01, 0x02, + 0xd8, 0x3d, 0x02, 0x03, 0xe0, 0x3d, 0x02, 0x03, 0xe8, 0x3d, 0x02, 0x03, 0xf0, 0x3d, 0x02, 0x03, 0xf8, 0x3d, 0x02, 0x03, 0x68, 0x17, 0x03, 0x03, 0x70, 0x17, 0x03, 0x03, 0x78, 0x17, 0x03, 0x03, + 0x60, 0x39, 0x04, 0x04, 0x70, 0x39, 0x04, 0x04, 0x30, 0x14, 0x05, 0x04, 0x60, 0x35, 0x06, 0x05, 0xe0, 0x11, 0x07, 0x05, 0x00, 0x10, 0x09, 0x06, 0xb0, 0x2b, 0x00, 0x03, 0xb8, 0x2b, 0x00, 0x03, + 0xc0, 0x2b, 0x00, 0x03, 0xc8, 0x2b, 0x00, 0x03, 0x74, 0x1a, 0x01, 0x02, 0x78, 0x1a, 0x01, 0x02, 0x7c, 0x1a, 0x01, 0x02, 0x80, 0x1a, 0x01, 0x02, 0x84, 0x1a, 0x01, 0x02, 0x88, 0x1a, 0x01, 0x02, + 0x00, 0x3e, 0x02, 0x03, 0x08, 0x3e, 0x02, 0x03, 0x10, 0x3e, 0x02, 0x03, 0x18, 0x3e, 0x02, 0x03, 0x20, 0x3e, 0x02, 0x03, 0x80, 0x17, 0x03, 0x03, 0x88, 0x17, 0x03, 0x03, 0x90, 0x17, 0x03, 0x03, + 0x80, 0x39, 0x04, 0x04, 0x90, 0x39, 0x04, 0x04, 0x40, 0x14, 0x05, 0x04, 0x80, 0x35, 0x06, 0x05, 0x00, 0x12, 0x07, 0x05, 0x40, 0x10, 0x09, 0x06, 0xd0, 0x2b, 0x00, 0x03, 0xd8, 0x2b, 0x00, 0x03, + 0xe0, 0x2b, 0x00, 0x03, 0xe8, 0x2b, 0x00, 0x03, 0x8c, 0x1a, 0x01, 0x02, 0x90, 0x1a, 0x01, 0x02, 0x94, 0x1a, 0x01, 0x02, 0x98, 0x1a, 0x01, 0x02, 0x9c, 0x1a, 0x01, 0x02, 0xa0, 0x1a, 0x01, 0x02, + 0x28, 0x3e, 0x02, 0x03, 0x30, 0x3e, 0x02, 0x03, 0x38, 0x3e, 0x02, 0x03, 0x40, 0x3e, 0x02, 0x03, 0x48, 0x3e, 0x02, 0x03, 0x98, 0x17, 0x03, 0x03, 0xa0, 0x17, 0x03, 0x03, 0xa8, 0x17, 0x03, 0x03, + 0xa0, 0x39, 0x04, 0x04, 0xb0, 0x39, 0x04, 0x04, 0x50, 0x14, 0x05, 0x04, 0xa0, 0x35, 0x06, 0x05, 0x20, 0x12, 0x07, 0x05, 0x80, 0x10, 0x09, 0x06, 0xf0, 0x2b, 0x00, 0x03, 0xf8, 0x2b, 0x00, 0x03, + 0x00, 0x2c, 0x00, 0x03, 0x08, 0x2c, 0x00, 0x03, 0xa4, 0x1a, 0x01, 0x02, 0xa8, 0x1a, 0x01, 0x02, 0xac, 0x1a, 0x01, 0x02, 0xb0, 0x1a, 0x01, 0x02, 0xb4, 0x1a, 0x01, 0x02, 0xb8, 0x1a, 0x01, 0x02, + 0x50, 0x3e, 0x02, 0x03, 0x58, 0x3e, 0x02, 0x03, 0x60, 0x3e, 0x02, 0x03, 0x68, 0x3e, 0x02, 0x03, 0x70, 0x3e, 0x02, 0x03, 0xb0, 0x17, 0x03, 0x03, 0xb8, 0x17, 0x03, 0x03, 0xc0, 0x17, 0x03, 0x03, + 0xc0, 0x39, 0x04, 0x04, 0xd0, 0x39, 0x04, 0x04, 0x60, 0x14, 0x05, 0x04, 0xc0, 0x35, 0x06, 0x05, 0x40, 0x12, 0x07, 0x05, 0xc0, 0x10, 0x09, 0x06, 0x10, 0x2c, 0x00, 0x03, 0x18, 0x2c, 0x00, 0x03, + 0x20, 0x2c, 0x00, 0x03, 0x28, 0x2c, 0x00, 0x03, 0xbc, 0x1a, 0x01, 0x02, 0xc0, 0x1a, 0x01, 0x02, 0xc4, 0x1a, 0x01, 0x02, 0xc8, 0x1a, 0x01, 0x02, 0xcc, 0x1a, 0x01, 0x02, 0xd0, 0x1a, 0x01, 0x02, + 0x78, 0x3e, 0x02, 0x03, 0x80, 0x3e, 0x02, 0x03, 0x88, 0x3e, 0x02, 0x03, 0x90, 0x3e, 0x02, 0x03, 0x98, 0x3e, 0x02, 0x03, 0xc8, 0x17, 0x03, 0x03, 0xd0, 0x17, 0x03, 0x03, 0xd8, 0x17, 0x03, 0x03, + 0xe0, 0x39, 0x04, 0x04, 0xf0, 0x39, 0x04, 0x04, 0x70, 0x14, 0x05, 0x04, 0xe0, 0x35, 0x06, 0x05, 0x60, 0x12, 0x07, 0x05, 0x00, 0x11, 0x09, 0x06, 0x30, 0x2c, 0x00, 0x03, 0x38, 0x2c, 0x00, 0x03, + 0x40, 0x2c, 0x00, 0x03, 0x48, 0x2c, 0x00, 0x03, 0xd4, 0x1a, 0x01, 0x02, 0xd8, 0x1a, 0x01, 0x02, 0xdc, 0x1a, 0x01, 0x02, 0xe0, 0x1a, 0x01, 0x02, 0xe4, 0x1a, 0x01, 0x02, 0xe8, 0x1a, 0x01, 0x02, + 0xa0, 0x3e, 0x02, 0x03, 0xa8, 0x3e, 0x02, 0x03, 0xb0, 0x3e, 0x02, 0x03, 0xb8, 0x3e, 0x02, 0x03, 0xc0, 0x3e, 0x02, 0x03, 0xe0, 0x17, 0x03, 0x03, 0xe8, 0x17, 0x03, 0x03, 0xf0, 0x17, 0x03, 0x03, + 0x00, 0x3a, 0x04, 0x04, 0x10, 0x3a, 0x04, 0x04, 0x80, 0x14, 0x05, 0x04, 0x00, 0x36, 0x06, 0x05, 0x80, 0x12, 0x07, 0x05, 0x40, 0x11, 0x09, 0x06, 0x50, 0x2c, 0x00, 0x03, 0x58, 0x2c, 0x00, 0x03, + 0x60, 0x2c, 0x00, 0x03, 0x68, 0x2c, 0x00, 0x03, 0xec, 0x1a, 0x01, 0x02, 0xf0, 0x1a, 0x01, 0x02, 0xf4, 0x1a, 0x01, 0x02, 0xf8, 0x1a, 0x01, 0x02, 0xfc, 0x1a, 0x01, 0x02, 0x00, 0x1b, 0x01, 0x02, + 0xc8, 0x3e, 0x02, 0x03, 0xd0, 0x3e, 0x02, 0x03, 0xd8, 0x3e, 0x02, 0x03, 0xe0, 0x3e, 0x02, 0x03, 0xe8, 0x3e, 0x02, 0x03, 0xf8, 0x17, 0x03, 0x03, 0x00, 0x18, 0x03, 0x03, 0x08, 0x18, 0x03, 0x03, + 0x20, 0x3a, 0x04, 0x04, 0x30, 0x3a, 0x04, 0x04, 0x90, 0x14, 0x05, 0x04, 0x20, 0x36, 0x06, 0x05, 0xa0, 0x12, 0x07, 0x05, 0x80, 0x11, 0x09, 0x06, 0x70, 0x2c, 0x00, 0x03, 0x78, 0x2c, 0x00, 0x03, + 0x80, 0x2c, 0x00, 0x03, 0x88, 0x2c, 0x00, 0x03, 0x04, 0x1b, 0x01, 0x02, 0x08, 0x1b, 0x01, 0x02, 0x0c, 0x1b, 0x01, 0x02, 0x10, 0x1b, 0x01, 0x02, 0x14, 0x1b, 0x01, 0x02, 0x18, 0x1b, 0x01, 0x02, + 0xf0, 0x3e, 0x02, 0x03, 0xf8, 0x3e, 0x02, 0x03, 0x00, 0x3f, 0x02, 0x03, 0x08, 0x3f, 0x02, 0x03, 0x10, 0x3f, 0x02, 0x03, 0x10, 0x18, 0x03, 0x03, 0x18, 0x18, 0x03, 0x03, 0x20, 0x18, 0x03, 0x03, + 0x40, 0x3a, 0x04, 0x04, 0x50, 0x3a, 0x04, 0x04, 0xa0, 0x14, 0x05, 0x04, 0x40, 0x36, 0x06, 0x05, 0xc0, 0x12, 0x07, 0x05, 0xc0, 0x11, 0x09, 0x06, 0x90, 0x2c, 0x00, 0x03, 0x98, 0x2c, 0x00, 0x03, + 0xa0, 0x2c, 0x00, 0x03, 0xa8, 0x2c, 0x00, 0x03, 0x1c, 0x1b, 0x01, 0x02, 0x20, 0x1b, 0x01, 0x02, 0x24, 0x1b, 0x01, 0x02, 0x28, 0x1b, 0x01, 0x02, 0x2c, 0x1b, 0x01, 0x02, 0x30, 0x1b, 0x01, 0x02, + 0x18, 0x3f, 0x02, 0x03, 0x20, 0x3f, 0x02, 0x03, 0x28, 0x3f, 0x02, 0x03, 0x30, 0x3f, 0x02, 0x03, 0x38, 0x3f, 0x02, 0x03, 0x28, 0x18, 0x03, 0x03, 0x30, 0x18, 0x03, 0x03, 0x38, 0x18, 0x03, 0x03, + 0x60, 0x3a, 0x04, 0x04, 0x70, 0x3a, 0x04, 0x04, 0xb0, 0x14, 0x05, 0x04, 0x60, 0x36, 0x06, 0x05, 0xe0, 0x12, 0x07, 0x05, 0x00, 0x12, 0x09, 0x06, 0xb0, 0x2c, 0x00, 0x03, 0xb8, 0x2c, 0x00, 0x03, + 0xc0, 0x2c, 0x00, 0x03, 0xc8, 0x2c, 0x00, 0x03, 0x34, 0x1b, 0x01, 0x02, 0x38, 0x1b, 0x01, 0x02, 0x3c, 0x1b, 0x01, 0x02, 0x40, 0x1b, 0x01, 0x02, 0x44, 0x1b, 0x01, 0x02, 0x48, 0x1b, 0x01, 0x02, + 0x40, 0x3f, 0x02, 0x03, 0x48, 0x3f, 0x02, 0x03, 0x50, 0x3f, 0x02, 0x03, 0x58, 0x3f, 0x02, 0x03, 0x60, 0x3f, 0x02, 0x03, 0x40, 0x18, 0x03, 0x03, 0x48, 0x18, 0x03, 0x03, 0x50, 0x18, 0x03, 0x03, + 0x80, 0x3a, 0x04, 0x04, 0x90, 0x3a, 0x04, 0x04, 0xc0, 0x14, 0x05, 0x04, 0x80, 0x36, 0x06, 0x05, 0x00, 0x13, 0x07, 0x05, 0x40, 0x12, 0x09, 0x06, 0xd0, 0x2c, 0x00, 0x03, 0xd8, 0x2c, 0x00, 0x03, + 0xe0, 0x2c, 0x00, 0x03, 0xe8, 0x2c, 0x00, 0x03, 0x4c, 0x1b, 0x01, 0x02, 0x50, 0x1b, 0x01, 0x02, 0x54, 0x1b, 0x01, 0x02, 0x58, 0x1b, 0x01, 0x02, 0x5c, 0x1b, 0x01, 0x02, 0x60, 0x1b, 0x01, 0x02, + 0x68, 0x3f, 0x02, 0x03, 0x70, 0x3f, 0x02, 0x03, 0x78, 0x3f, 0x02, 0x03, 0x80, 0x3f, 0x02, 0x03, 0x88, 0x3f, 0x02, 0x03, 0x58, 0x18, 0x03, 0x03, 0x60, 0x18, 0x03, 0x03, 0xa0, 0x3a, 0x04, 0x04, + 0xb0, 0x3a, 0x04, 0x04, 0xc0, 0x3a, 0x04, 0x04, 0xd0, 0x14, 0x05, 0x04, 0xa0, 0x36, 0x06, 0x05, 0x20, 0x13, 0x07, 0x05, 0x80, 0x12, 0x09, 0x06, 0xf0, 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x03, + 0x00, 0x2d, 0x00, 0x03, 0x08, 0x2d, 0x00, 0x03, 0x64, 0x1b, 0x01, 0x02, 0x68, 0x1b, 0x01, 0x02, 0x6c, 0x1b, 0x01, 0x02, 0x70, 0x1b, 0x01, 0x02, 0x74, 0x1b, 0x01, 0x02, 0x78, 0x1b, 0x01, 0x02, + 0x90, 0x3f, 0x02, 0x03, 0x98, 0x3f, 0x02, 0x03, 0xa0, 0x3f, 0x02, 0x03, 0xa8, 0x3f, 0x02, 0x03, 0x68, 0x18, 0x03, 0x03, 0x70, 0x18, 0x03, 0x03, 0x78, 0x18, 0x03, 0x03, 0xd0, 0x3a, 0x04, 0x04, + 0xe0, 0x3a, 0x04, 0x04, 0xf0, 0x3a, 0x04, 0x04, 0xe0, 0x14, 0x05, 0x04, 0xc0, 0x36, 0x06, 0x05, 0x40, 0x13, 0x07, 0x05, 0xc0, 0x12, 0x09, 0x06, 0x10, 0x2d, 0x00, 0x03, 0x18, 0x2d, 0x00, 0x03, + 0x20, 0x2d, 0x00, 0x03, 0x28, 0x2d, 0x00, 0x03, 0x7c, 0x1b, 0x01, 0x02, 0x80, 0x1b, 0x01, 0x02, 0x84, 0x1b, 0x01, 0x02, 0x88, 0x1b, 0x01, 0x02, 0x8c, 0x1b, 0x01, 0x02, 0x90, 0x1b, 0x01, 0x02, + 0xb0, 0x3f, 0x02, 0x03, 0xb8, 0x3f, 0x02, 0x03, 0xc0, 0x3f, 0x02, 0x03, 0xc8, 0x3f, 0x02, 0x03, 0x80, 0x18, 0x03, 0x03, 0x88, 0x18, 0x03, 0x03, 0x90, 0x18, 0x03, 0x03, 0x00, 0x3b, 0x04, 0x04, + 0x10, 0x3b, 0x04, 0x04, 0x20, 0x3b, 0x04, 0x04, 0xf0, 0x14, 0x05, 0x04, 0xe0, 0x36, 0x06, 0x05, 0x60, 0x13, 0x07, 0x05, 0x00, 0x13, 0x09, 0x06, 0x30, 0x2d, 0x00, 0x03, 0x38, 0x2d, 0x00, 0x03, + 0x40, 0x2d, 0x00, 0x03, 0x48, 0x2d, 0x00, 0x03, 0x94, 0x1b, 0x01, 0x02, 0x98, 0x1b, 0x01, 0x02, 0x9c, 0x1b, 0x01, 0x02, 0xa0, 0x1b, 0x01, 0x02, 0xa4, 0x1b, 0x01, 0x02, 0xa8, 0x1b, 0x01, 0x02, + 0xd0, 0x3f, 0x02, 0x03, 0xd8, 0x3f, 0x02, 0x03, 0xe0, 0x3f, 0x02, 0x03, 0xe8, 0x3f, 0x02, 0x03, 0x98, 0x18, 0x03, 0x03, 0xa0, 0x18, 0x03, 0x03, 0xa8, 0x18, 0x03, 0x03, 0x30, 0x3b, 0x04, 0x04, + 0x40, 0x3b, 0x04, 0x04, 0x50, 0x3b, 0x04, 0x04, 0x00, 0x15, 0x05, 0x04, 0x00, 0x37, 0x06, 0x05, 0x80, 0x13, 0x07, 0x05, 0x40, 0x13, 0x09, 0x06, 0x50, 0x2d, 0x00, 0x03, 0x58, 0x2d, 0x00, 0x03, + 0x60, 0x2d, 0x00, 0x03, 0x68, 0x2d, 0x00, 0x03, 0xac, 0x1b, 0x01, 0x02, 0xb0, 0x1b, 0x01, 0x02, 0xb4, 0x1b, 0x01, 0x02, 0xb8, 0x1b, 0x01, 0x02, 0xbc, 0x1b, 0x01, 0x02, 0xc0, 0x1b, 0x01, 0x02, + 0xf0, 0x3f, 0x02, 0x03, 0xf8, 0x3f, 0x02, 0x03, 0x00, 0x00, 0x02, 0x02, 0x04, 0x00, 0x02, 0x02, 0xb0, 0x18, 0x03, 0x03, 0xb8, 0x18, 0x03, 0x03, 0xc0, 0x18, 0x03, 0x03, 0x60, 0x3b, 0x04, 0x04, + 0x70, 0x3b, 0x04, 0x04, 0x80, 0x3b, 0x04, 0x04, 0x10, 0x15, 0x05, 0x04, 0x20, 0x37, 0x06, 0x05, 0xa0, 0x13, 0x07, 0x05, 0x80, 0x13, 0x09, 0x06, 0x70, 0x2d, 0x00, 0x03, 0x78, 0x2d, 0x00, 0x03, + 0x80, 0x2d, 0x00, 0x03, 0x88, 0x2d, 0x00, 0x03, 0xc4, 0x1b, 0x01, 0x02, 0xc8, 0x1b, 0x01, 0x02, 0xcc, 0x1b, 0x01, 0x02, 0xd0, 0x1b, 0x01, 0x02, 0xd4, 0x1b, 0x01, 0x02, 0xd8, 0x1b, 0x01, 0x02, + 0x08, 0x00, 0x02, 0x02, 0x0c, 0x00, 0x02, 0x02, 0x10, 0x00, 0x02, 0x02, 0x14, 0x00, 0x02, 0x02, 0xc8, 0x18, 0x03, 0x03, 0xd0, 0x18, 0x03, 0x03, 0xd8, 0x18, 0x03, 0x03, 0x90, 0x3b, 0x04, 0x04, + 0xa0, 0x3b, 0x04, 0x04, 0xb0, 0x3b, 0x04, 0x04, 0x20, 0x15, 0x05, 0x04, 0x40, 0x37, 0x06, 0x05, 0xc0, 0x13, 0x07, 0x05, 0x00, 0x2d, 0x0a, 0x07, 0x90, 0x2d, 0x00, 0x03, 0x98, 0x2d, 0x00, 0x03, + 0xa0, 0x2d, 0x00, 0x03, 0xa8, 0x2d, 0x00, 0x03, 0xdc, 0x1b, 0x01, 0x02, 0xe0, 0x1b, 0x01, 0x02, 0xe4, 0x1b, 0x01, 0x02, 0xe8, 0x1b, 0x01, 0x02, 0xec, 0x1b, 0x01, 0x02, 0xf0, 0x1b, 0x01, 0x02, + 0x18, 0x00, 0x02, 0x02, 0x1c, 0x00, 0x02, 0x02, 0x20, 0x00, 0x02, 0x02, 0x24, 0x00, 0x02, 0x02, 0xe0, 0x18, 0x03, 0x03, 0xe8, 0x18, 0x03, 0x03, 0xf0, 0x18, 0x03, 0x03, 0xc0, 0x3b, 0x04, 0x04, + 0xd0, 0x3b, 0x04, 0x04, 0xe0, 0x3b, 0x04, 0x04, 0x30, 0x15, 0x05, 0x04, 0x60, 0x37, 0x06, 0x05, 0xe0, 0x13, 0x07, 0x05, 0x80, 0x2d, 0x0a, 0x07, 0xb0, 0x2d, 0x00, 0x03, 0xb8, 0x2d, 0x00, 0x03, + 0xc0, 0x2d, 0x00, 0x03, 0xc8, 0x2d, 0x00, 0x03, 0xf4, 0x1b, 0x01, 0x02, 0xf8, 0x1b, 0x01, 0x02, 0xfc, 0x1b, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x04, 0x1c, 0x01, 0x02, 0x08, 0x1c, 0x01, 0x02, + 0x28, 0x00, 0x02, 0x02, 0x2c, 0x00, 0x02, 0x02, 0x30, 0x00, 0x02, 0x02, 0x34, 0x00, 0x02, 0x02, 0xf8, 0x18, 0x03, 0x03, 0x00, 0x19, 0x03, 0x03, 0x08, 0x19, 0x03, 0x03, 0xf0, 0x3b, 0x04, 0x04, + 0x00, 0x3c, 0x04, 0x04, 0x40, 0x15, 0x05, 0x04, 0x50, 0x15, 0x05, 0x04, 0x80, 0x37, 0x06, 0x05, 0x00, 0x14, 0x07, 0x05, 0x00, 0x2e, 0x0a, 0x07, 0xd0, 0x2d, 0x00, 0x03, 0xd8, 0x2d, 0x00, 0x03, + 0xe0, 0x2d, 0x00, 0x03, 0xe8, 0x2d, 0x00, 0x03, 0x0c, 0x1c, 0x01, 0x02, 0x10, 0x1c, 0x01, 0x02, 0x14, 0x1c, 0x01, 0x02, 0x18, 0x1c, 0x01, 0x02, 0x1c, 0x1c, 0x01, 0x02, 0x20, 0x1c, 0x01, 0x02, + 0x38, 0x00, 0x02, 0x02, 0x3c, 0x00, 0x02, 0x02, 0x40, 0x00, 0x02, 0x02, 0x44, 0x00, 0x02, 0x02, 0x10, 0x19, 0x03, 0x03, 0x18, 0x19, 0x03, 0x03, 0x20, 0x19, 0x03, 0x03, 0x10, 0x3c, 0x04, 0x04, + 0x20, 0x3c, 0x04, 0x04, 0x60, 0x15, 0x05, 0x04, 0x70, 0x15, 0x05, 0x04, 0xa0, 0x37, 0x06, 0x05, 0x20, 0x14, 0x07, 0x05, 0x80, 0x2e, 0x0a, 0x07, 0xf0, 0x2d, 0x00, 0x03, 0xf8, 0x2d, 0x00, 0x03, + 0x00, 0x2e, 0x00, 0x03, 0x08, 0x2e, 0x00, 0x03, 0x24, 0x1c, 0x01, 0x02, 0x28, 0x1c, 0x01, 0x02, 0x2c, 0x1c, 0x01, 0x02, 0x30, 0x1c, 0x01, 0x02, 0x34, 0x1c, 0x01, 0x02, 0x38, 0x1c, 0x01, 0x02, + 0x48, 0x00, 0x02, 0x02, 0x4c, 0x00, 0x02, 0x02, 0x50, 0x00, 0x02, 0x02, 0x54, 0x00, 0x02, 0x02, 0x28, 0x19, 0x03, 0x03, 0x30, 0x19, 0x03, 0x03, 0x38, 0x19, 0x03, 0x03, 0x30, 0x3c, 0x04, 0x04, + 0x40, 0x3c, 0x04, 0x04, 0x80, 0x15, 0x05, 0x04, 0x90, 0x15, 0x05, 0x04, 0xc0, 0x37, 0x06, 0x05, 0x40, 0x14, 0x07, 0x05, 0x00, 0x2f, 0x0a, 0x07, 0x10, 0x2e, 0x00, 0x03, 0x18, 0x2e, 0x00, 0x03, + 0x20, 0x2e, 0x00, 0x03, 0x28, 0x2e, 0x00, 0x03, 0x3c, 0x1c, 0x01, 0x02, 0x40, 0x1c, 0x01, 0x02, 0x44, 0x1c, 0x01, 0x02, 0x48, 0x1c, 0x01, 0x02, 0x4c, 0x1c, 0x01, 0x02, 0x50, 0x1c, 0x01, 0x02, + 0x58, 0x00, 0x02, 0x02, 0x5c, 0x00, 0x02, 0x02, 0x60, 0x00, 0x02, 0x02, 0x64, 0x00, 0x02, 0x02, 0x40, 0x19, 0x03, 0x03, 0x48, 0x19, 0x03, 0x03, 0x50, 0x19, 0x03, 0x03, 0x50, 0x3c, 0x04, 0x04, + 0x60, 0x3c, 0x04, 0x04, 0xa0, 0x15, 0x05, 0x04, 0xb0, 0x15, 0x05, 0x04, 0xe0, 0x37, 0x06, 0x05, 0x60, 0x14, 0x07, 0x05, 0x80, 0x2f, 0x0a, 0x07, 0x30, 0x2e, 0x00, 0x03, 0x38, 0x2e, 0x00, 0x03, + 0x40, 0x2e, 0x00, 0x03, 0x48, 0x2e, 0x00, 0x03, 0x54, 0x1c, 0x01, 0x02, 0x58, 0x1c, 0x01, 0x02, 0x5c, 0x1c, 0x01, 0x02, 0x60, 0x1c, 0x01, 0x02, 0x64, 0x1c, 0x01, 0x02, 0x68, 0x1c, 0x01, 0x02, + 0x68, 0x00, 0x02, 0x02, 0x6c, 0x00, 0x02, 0x02, 0x70, 0x00, 0x02, 0x02, 0x74, 0x00, 0x02, 0x02, 0x58, 0x19, 0x03, 0x03, 0x60, 0x19, 0x03, 0x03, 0x68, 0x19, 0x03, 0x03, 0x70, 0x3c, 0x04, 0x04, + 0x80, 0x3c, 0x04, 0x04, 0xc0, 0x15, 0x05, 0x04, 0xd0, 0x15, 0x05, 0x04, 0x00, 0x38, 0x06, 0x05, 0x80, 0x14, 0x07, 0x05, 0x00, 0x30, 0x0a, 0x07, 0x50, 0x2e, 0x00, 0x03, 0x58, 0x2e, 0x00, 0x03, + 0x60, 0x2e, 0x00, 0x03, 0x68, 0x2e, 0x00, 0x03, 0x6c, 0x1c, 0x01, 0x02, 0x70, 0x1c, 0x01, 0x02, 0x74, 0x1c, 0x01, 0x02, 0x78, 0x1c, 0x01, 0x02, 0x7c, 0x1c, 0x01, 0x02, 0x80, 0x1c, 0x01, 0x02, + 0x78, 0x00, 0x02, 0x02, 0x7c, 0x00, 0x02, 0x02, 0x80, 0x00, 0x02, 0x02, 0x84, 0x00, 0x02, 0x02, 0x70, 0x19, 0x03, 0x03, 0x78, 0x19, 0x03, 0x03, 0x80, 0x19, 0x03, 0x03, 0x90, 0x3c, 0x04, 0x04, + 0xa0, 0x3c, 0x04, 0x04, 0xe0, 0x15, 0x05, 0x04, 0xf0, 0x15, 0x05, 0x04, 0x20, 0x38, 0x06, 0x05, 0xa0, 0x14, 0x07, 0x05, 0x80, 0x30, 0x0a, 0x07, 0x70, 0x2e, 0x00, 0x03, 0x78, 0x2e, 0x00, 0x03, + 0x80, 0x2e, 0x00, 0x03, 0x88, 0x2e, 0x00, 0x03, 0x84, 0x1c, 0x01, 0x02, 0x88, 0x1c, 0x01, 0x02, 0x8c, 0x1c, 0x01, 0x02, 0x90, 0x1c, 0x01, 0x02, 0x94, 0x1c, 0x01, 0x02, 0x98, 0x1c, 0x01, 0x02, + 0x88, 0x00, 0x02, 0x02, 0x8c, 0x00, 0x02, 0x02, 0x90, 0x00, 0x02, 0x02, 0x94, 0x00, 0x02, 0x02, 0x88, 0x19, 0x03, 0x03, 0x90, 0x19, 0x03, 0x03, 0x98, 0x19, 0x03, 0x03, 0xb0, 0x3c, 0x04, 0x04, + 0xc0, 0x3c, 0x04, 0x04, 0x00, 0x16, 0x05, 0x04, 0x10, 0x16, 0x05, 0x04, 0x40, 0x38, 0x06, 0x05, 0xc0, 0x14, 0x07, 0x05, 0x00, 0x31, 0x0a, 0x07, 0x90, 0x2e, 0x00, 0x03, 0x98, 0x2e, 0x00, 0x03, + 0xa0, 0x2e, 0x00, 0x03, 0xa8, 0x2e, 0x00, 0x03, 0x9c, 0x1c, 0x01, 0x02, 0xa0, 0x1c, 0x01, 0x02, 0xa4, 0x1c, 0x01, 0x02, 0xa8, 0x1c, 0x01, 0x02, 0xac, 0x1c, 0x01, 0x02, 0xb0, 0x1c, 0x01, 0x02, + 0x98, 0x00, 0x02, 0x02, 0x9c, 0x00, 0x02, 0x02, 0xa0, 0x00, 0x02, 0x02, 0xa4, 0x00, 0x02, 0x02, 0xa0, 0x19, 0x03, 0x03, 0xa8, 0x19, 0x03, 0x03, 0xb0, 0x19, 0x03, 0x03, 0xd0, 0x3c, 0x04, 0x04, + 0xe0, 0x3c, 0x04, 0x04, 0x20, 0x16, 0x05, 0x04, 0x30, 0x16, 0x05, 0x04, 0x60, 0x38, 0x06, 0x05, 0xe0, 0x14, 0x07, 0x05, 0x80, 0x31, 0x0a, 0x07, 0xb0, 0x2e, 0x00, 0x03, 0xb8, 0x2e, 0x00, 0x03, + 0xc0, 0x2e, 0x00, 0x03, 0xc8, 0x2e, 0x00, 0x03, 0xb4, 0x1c, 0x01, 0x02, 0xb8, 0x1c, 0x01, 0x02, 0xbc, 0x1c, 0x01, 0x02, 0xc0, 0x1c, 0x01, 0x02, 0xc4, 0x1c, 0x01, 0x02, 0xc8, 0x1c, 0x01, 0x02, + 0xa8, 0x00, 0x02, 0x02, 0xac, 0x00, 0x02, 0x02, 0xb0, 0x00, 0x02, 0x02, 0xb4, 0x00, 0x02, 0x02, 0xb8, 0x19, 0x03, 0x03, 0xc0, 0x19, 0x03, 0x03, 0xc8, 0x19, 0x03, 0x03, 0xf0, 0x3c, 0x04, 0x04, + 0x00, 0x3d, 0x04, 0x04, 0x40, 0x16, 0x05, 0x04, 0x50, 0x16, 0x05, 0x04, 0x80, 0x38, 0x06, 0x05, 0x00, 0x15, 0x07, 0x05, 0x00, 0x32, 0x0a, 0x07, 0xd0, 0x2e, 0x00, 0x03, 0xd8, 0x2e, 0x00, 0x03, + 0xe0, 0x2e, 0x00, 0x03, 0xe8, 0x2e, 0x00, 0x03, 0xcc, 0x1c, 0x01, 0x02, 0xd0, 0x1c, 0x01, 0x02, 0xd4, 0x1c, 0x01, 0x02, 0xd8, 0x1c, 0x01, 0x02, 0xdc, 0x1c, 0x01, 0x02, 0xe0, 0x1c, 0x01, 0x02, + 0xb8, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x02, 0x02, 0xc0, 0x00, 0x02, 0x02, 0xc4, 0x00, 0x02, 0x02, 0xd0, 0x19, 0x03, 0x03, 0xd8, 0x19, 0x03, 0x03, 0xe0, 0x19, 0x03, 0x03, 0x10, 0x3d, 0x04, 0x04, + 0x20, 0x3d, 0x04, 0x04, 0x60, 0x16, 0x05, 0x04, 0x70, 0x16, 0x05, 0x04, 0xa0, 0x38, 0x06, 0x05, 0x20, 0x15, 0x07, 0x05, 0x80, 0x32, 0x0a, 0x07, 0xf0, 0x2e, 0x00, 0x03, 0xf8, 0x2e, 0x00, 0x03, + 0x00, 0x2f, 0x00, 0x03, 0x08, 0x2f, 0x00, 0x03, 0xe4, 0x1c, 0x01, 0x02, 0xe8, 0x1c, 0x01, 0x02, 0xec, 0x1c, 0x01, 0x02, 0xf0, 0x1c, 0x01, 0x02, 0xf4, 0x1c, 0x01, 0x02, 0xf8, 0x1c, 0x01, 0x02, + 0xc8, 0x00, 0x02, 0x02, 0xcc, 0x00, 0x02, 0x02, 0xd0, 0x00, 0x02, 0x02, 0xd4, 0x00, 0x02, 0x02, 0xe8, 0x19, 0x03, 0x03, 0xf0, 0x19, 0x03, 0x03, 0xf8, 0x19, 0x03, 0x03, 0x30, 0x3d, 0x04, 0x04, + 0x40, 0x3d, 0x04, 0x04, 0x80, 0x16, 0x05, 0x04, 0x90, 0x16, 0x05, 0x04, 0xc0, 0x38, 0x06, 0x05, 0x40, 0x15, 0x07, 0x05, 0x00, 0x33, 0x0a, 0x07, 0x10, 0x2f, 0x00, 0x03, 0x18, 0x2f, 0x00, 0x03, + 0x20, 0x2f, 0x00, 0x03, 0x28, 0x2f, 0x00, 0x03, 0xfc, 0x1c, 0x01, 0x02, 0x00, 0x1d, 0x01, 0x02, 0x04, 0x1d, 0x01, 0x02, 0x08, 0x1d, 0x01, 0x02, 0x0c, 0x1d, 0x01, 0x02, 0x10, 0x1d, 0x01, 0x02, + 0xd8, 0x00, 0x02, 0x02, 0xdc, 0x00, 0x02, 0x02, 0xe0, 0x00, 0x02, 0x02, 0xe4, 0x00, 0x02, 0x02, 0x00, 0x1a, 0x03, 0x03, 0x08, 0x1a, 0x03, 0x03, 0x10, 0x1a, 0x03, 0x03, 0x50, 0x3d, 0x04, 0x04, + 0x60, 0x3d, 0x04, 0x04, 0xa0, 0x16, 0x05, 0x04, 0xb0, 0x16, 0x05, 0x04, 0xe0, 0x38, 0x06, 0x05, 0x60, 0x15, 0x07, 0x05, 0x80, 0x33, 0x0a, 0x07, 0x30, 0x2f, 0x00, 0x03, 0x38, 0x2f, 0x00, 0x03, + 0x40, 0x2f, 0x00, 0x03, 0x48, 0x2f, 0x00, 0x03, 0x14, 0x1d, 0x01, 0x02, 0x18, 0x1d, 0x01, 0x02, 0x1c, 0x1d, 0x01, 0x02, 0x20, 0x1d, 0x01, 0x02, 0x24, 0x1d, 0x01, 0x02, 0x28, 0x1d, 0x01, 0x02, + 0xe8, 0x00, 0x02, 0x02, 0xec, 0x00, 0x02, 0x02, 0xf0, 0x00, 0x02, 0x02, 0xf4, 0x00, 0x02, 0x02, 0x18, 0x1a, 0x03, 0x03, 0x20, 0x1a, 0x03, 0x03, 0x28, 0x1a, 0x03, 0x03, 0x70, 0x3d, 0x04, 0x04, + 0x80, 0x3d, 0x04, 0x04, 0xc0, 0x16, 0x05, 0x04, 0xd0, 0x16, 0x05, 0x04, 0x00, 0x39, 0x06, 0x05, 0x80, 0x30, 0x08, 0x06, 0x00, 0x34, 0x0a, 0x07, 0x50, 0x2f, 0x00, 0x03, 0x58, 0x2f, 0x00, 0x03, + 0x60, 0x2f, 0x00, 0x03, 0x68, 0x2f, 0x00, 0x03, 0x2c, 0x1d, 0x01, 0x02, 0x30, 0x1d, 0x01, 0x02, 0x34, 0x1d, 0x01, 0x02, 0x38, 0x1d, 0x01, 0x02, 0x3c, 0x1d, 0x01, 0x02, 0x40, 0x1d, 0x01, 0x02, + 0xf8, 0x00, 0x02, 0x02, 0xfc, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x04, 0x01, 0x02, 0x02, 0x30, 0x1a, 0x03, 0x03, 0x38, 0x1a, 0x03, 0x03, 0x40, 0x1a, 0x03, 0x03, 0x90, 0x3d, 0x04, 0x04, + 0xa0, 0x3d, 0x04, 0x04, 0xe0, 0x16, 0x05, 0x04, 0xf0, 0x16, 0x05, 0x04, 0x20, 0x39, 0x06, 0x05, 0xc0, 0x30, 0x08, 0x06, 0x80, 0x34, 0x0a, 0x07, 0x70, 0x2f, 0x00, 0x03, 0x78, 0x2f, 0x00, 0x03, + 0x80, 0x2f, 0x00, 0x03, 0x88, 0x2f, 0x00, 0x03, 0x44, 0x1d, 0x01, 0x02, 0x48, 0x1d, 0x01, 0x02, 0x4c, 0x1d, 0x01, 0x02, 0x50, 0x1d, 0x01, 0x02, 0x54, 0x1d, 0x01, 0x02, 0x58, 0x1d, 0x01, 0x02, + 0x08, 0x01, 0x02, 0x02, 0x0c, 0x01, 0x02, 0x02, 0x10, 0x01, 0x02, 0x02, 0x14, 0x01, 0x02, 0x02, 0x48, 0x1a, 0x03, 0x03, 0x50, 0x1a, 0x03, 0x03, 0x58, 0x1a, 0x03, 0x03, 0xb0, 0x3d, 0x04, 0x04, + 0xc0, 0x3d, 0x04, 0x04, 0x00, 0x17, 0x05, 0x04, 0x10, 0x17, 0x05, 0x04, 0x40, 0x39, 0x06, 0x05, 0x00, 0x31, 0x08, 0x06, 0x00, 0x35, 0x0a, 0x07, 0x90, 0x2f, 0x00, 0x03, 0x98, 0x2f, 0x00, 0x03, + 0xa0, 0x2f, 0x00, 0x03, 0xa8, 0x2f, 0x00, 0x03, 0x5c, 0x1d, 0x01, 0x02, 0x60, 0x1d, 0x01, 0x02, 0x64, 0x1d, 0x01, 0x02, 0x68, 0x1d, 0x01, 0x02, 0x6c, 0x1d, 0x01, 0x02, 0x70, 0x1d, 0x01, 0x02, + 0x18, 0x01, 0x02, 0x02, 0x1c, 0x01, 0x02, 0x02, 0x20, 0x01, 0x02, 0x02, 0x24, 0x01, 0x02, 0x02, 0x60, 0x1a, 0x03, 0x03, 0x68, 0x1a, 0x03, 0x03, 0x70, 0x1a, 0x03, 0x03, 0xd0, 0x3d, 0x04, 0x04, + 0xe0, 0x3d, 0x04, 0x04, 0x20, 0x17, 0x05, 0x04, 0x30, 0x17, 0x05, 0x04, 0x60, 0x39, 0x06, 0x05, 0x40, 0x31, 0x08, 0x06, 0x80, 0x35, 0x0a, 0x07, 0xb0, 0x2f, 0x00, 0x03, 0xb8, 0x2f, 0x00, 0x03, + 0xc0, 0x2f, 0x00, 0x03, 0xc8, 0x2f, 0x00, 0x03, 0x74, 0x1d, 0x01, 0x02, 0x78, 0x1d, 0x01, 0x02, 0x7c, 0x1d, 0x01, 0x02, 0x80, 0x1d, 0x01, 0x02, 0x84, 0x1d, 0x01, 0x02, 0x88, 0x1d, 0x01, 0x02, + 0x28, 0x01, 0x02, 0x02, 0x2c, 0x01, 0x02, 0x02, 0x30, 0x01, 0x02, 0x02, 0x34, 0x01, 0x02, 0x02, 0x78, 0x1a, 0x03, 0x03, 0x80, 0x1a, 0x03, 0x03, 0x88, 0x1a, 0x03, 0x03, 0xf0, 0x3d, 0x04, 0x04, + 0x00, 0x3e, 0x04, 0x04, 0x40, 0x17, 0x05, 0x04, 0x50, 0x17, 0x05, 0x04, 0x80, 0x39, 0x06, 0x05, 0x80, 0x31, 0x08, 0x06, 0x00, 0x36, 0x0a, 0x07, 0xd0, 0x2f, 0x00, 0x03, 0xd8, 0x2f, 0x00, 0x03, + 0xe0, 0x2f, 0x00, 0x03, 0xe8, 0x2f, 0x00, 0x03, 0x8c, 0x1d, 0x01, 0x02, 0x90, 0x1d, 0x01, 0x02, 0x94, 0x1d, 0x01, 0x02, 0x98, 0x1d, 0x01, 0x02, 0x9c, 0x1d, 0x01, 0x02, 0xa0, 0x1d, 0x01, 0x02, + 0x38, 0x01, 0x02, 0x02, 0x3c, 0x01, 0x02, 0x02, 0x40, 0x01, 0x02, 0x02, 0x44, 0x01, 0x02, 0x02, 0x90, 0x1a, 0x03, 0x03, 0x98, 0x1a, 0x03, 0x03, 0xa0, 0x1a, 0x03, 0x03, 0x10, 0x3e, 0x04, 0x04, + 0x20, 0x3e, 0x04, 0x04, 0x60, 0x17, 0x05, 0x04, 0x70, 0x17, 0x05, 0x04, 0xa0, 0x39, 0x06, 0x05, 0xc0, 0x31, 0x08, 0x06, 0x80, 0x0b, 0x0b, 0x07, 0xf0, 0x2f, 0x00, 0x03, 0xf8, 0x2f, 0x00, 0x03, + 0x00, 0x30, 0x00, 0x03, 0x08, 0x30, 0x00, 0x03, 0xa4, 0x1d, 0x01, 0x02, 0xa8, 0x1d, 0x01, 0x02, 0xac, 0x1d, 0x01, 0x02, 0xb0, 0x1d, 0x01, 0x02, 0xb4, 0x1d, 0x01, 0x02, 0xb8, 0x1d, 0x01, 0x02, + 0x48, 0x01, 0x02, 0x02, 0x4c, 0x01, 0x02, 0x02, 0x50, 0x01, 0x02, 0x02, 0x54, 0x01, 0x02, 0x02, 0xa8, 0x1a, 0x03, 0x03, 0xb0, 0x1a, 0x03, 0x03, 0xb8, 0x1a, 0x03, 0x03, 0x30, 0x3e, 0x04, 0x04, + 0x40, 0x3e, 0x04, 0x04, 0x80, 0x17, 0x05, 0x04, 0x90, 0x17, 0x05, 0x04, 0xc0, 0x39, 0x06, 0x05, 0x00, 0x32, 0x08, 0x06, 0x00, 0x0c, 0x0b, 0x07, 0x10, 0x30, 0x00, 0x03, 0x18, 0x30, 0x00, 0x03, + 0x20, 0x30, 0x00, 0x03, 0x28, 0x30, 0x00, 0x03, 0xbc, 0x1d, 0x01, 0x02, 0xc0, 0x1d, 0x01, 0x02, 0xc4, 0x1d, 0x01, 0x02, 0xc8, 0x1d, 0x01, 0x02, 0xcc, 0x1d, 0x01, 0x02, 0xd0, 0x1d, 0x01, 0x02, + 0x58, 0x01, 0x02, 0x02, 0x5c, 0x01, 0x02, 0x02, 0x60, 0x01, 0x02, 0x02, 0x64, 0x01, 0x02, 0x02, 0xc0, 0x1a, 0x03, 0x03, 0xc8, 0x1a, 0x03, 0x03, 0xd0, 0x1a, 0x03, 0x03, 0x50, 0x3e, 0x04, 0x04, + 0x60, 0x3e, 0x04, 0x04, 0xa0, 0x17, 0x05, 0x04, 0xb0, 0x17, 0x05, 0x04, 0xe0, 0x39, 0x06, 0x05, 0x40, 0x32, 0x08, 0x06, 0x80, 0x0c, 0x0b, 0x07, 0x30, 0x30, 0x00, 0x03, 0x38, 0x30, 0x00, 0x03, + 0x40, 0x30, 0x00, 0x03, 0x48, 0x30, 0x00, 0x03, 0xd4, 0x1d, 0x01, 0x02, 0xd8, 0x1d, 0x01, 0x02, 0xdc, 0x1d, 0x01, 0x02, 0xe0, 0x1d, 0x01, 0x02, 0xe4, 0x1d, 0x01, 0x02, 0xe8, 0x1d, 0x01, 0x02, + 0x68, 0x01, 0x02, 0x02, 0x6c, 0x01, 0x02, 0x02, 0x70, 0x01, 0x02, 0x02, 0x74, 0x01, 0x02, 0x02, 0xd8, 0x1a, 0x03, 0x03, 0xe0, 0x1a, 0x03, 0x03, 0xe8, 0x1a, 0x03, 0x03, 0x70, 0x3e, 0x04, 0x04, + 0x80, 0x3e, 0x04, 0x04, 0xc0, 0x17, 0x05, 0x04, 0xd0, 0x17, 0x05, 0x04, 0x00, 0x3a, 0x06, 0x05, 0x80, 0x32, 0x08, 0x06, 0x00, 0x0d, 0x0b, 0x07, 0x50, 0x30, 0x00, 0x03, 0x58, 0x30, 0x00, 0x03, + 0x60, 0x30, 0x00, 0x03, 0x68, 0x30, 0x00, 0x03, 0xec, 0x1d, 0x01, 0x02, 0xf0, 0x1d, 0x01, 0x02, 0xf4, 0x1d, 0x01, 0x02, 0xf8, 0x1d, 0x01, 0x02, 0xfc, 0x1d, 0x01, 0x02, 0x00, 0x1e, 0x01, 0x02, + 0x78, 0x01, 0x02, 0x02, 0x7c, 0x01, 0x02, 0x02, 0x80, 0x01, 0x02, 0x02, 0x84, 0x01, 0x02, 0x02, 0xf0, 0x1a, 0x03, 0x03, 0xf8, 0x1a, 0x03, 0x03, 0x00, 0x1b, 0x03, 0x03, 0x90, 0x3e, 0x04, 0x04, + 0xa0, 0x3e, 0x04, 0x04, 0xe0, 0x17, 0x05, 0x04, 0xf0, 0x17, 0x05, 0x04, 0x20, 0x3a, 0x06, 0x05, 0xc0, 0x32, 0x08, 0x06, 0x80, 0x0d, 0x0b, 0x07, 0x70, 0x30, 0x00, 0x03, 0x78, 0x30, 0x00, 0x03, + 0x80, 0x30, 0x00, 0x03, 0x88, 0x30, 0x00, 0x03, 0x04, 0x1e, 0x01, 0x02, 0x08, 0x1e, 0x01, 0x02, 0x0c, 0x1e, 0x01, 0x02, 0x10, 0x1e, 0x01, 0x02, 0x14, 0x1e, 0x01, 0x02, 0x18, 0x1e, 0x01, 0x02, + 0x88, 0x01, 0x02, 0x02, 0x8c, 0x01, 0x02, 0x02, 0x90, 0x01, 0x02, 0x02, 0x94, 0x01, 0x02, 0x02, 0x08, 0x1b, 0x03, 0x03, 0x10, 0x1b, 0x03, 0x03, 0x18, 0x1b, 0x03, 0x03, 0xb0, 0x3e, 0x04, 0x04, + 0xc0, 0x3e, 0x04, 0x04, 0x00, 0x18, 0x05, 0x04, 0x10, 0x18, 0x05, 0x04, 0x40, 0x3a, 0x06, 0x05, 0x00, 0x33, 0x08, 0x06, 0x00, 0x0e, 0x0b, 0x07, 0x90, 0x30, 0x00, 0x03, 0x98, 0x30, 0x00, 0x03, + 0xa0, 0x30, 0x00, 0x03, 0xa8, 0x30, 0x00, 0x03, 0x1c, 0x1e, 0x01, 0x02, 0x20, 0x1e, 0x01, 0x02, 0x24, 0x1e, 0x01, 0x02, 0x28, 0x1e, 0x01, 0x02, 0x2c, 0x1e, 0x01, 0x02, 0x30, 0x1e, 0x01, 0x02, + 0x98, 0x01, 0x02, 0x02, 0x9c, 0x01, 0x02, 0x02, 0xa0, 0x01, 0x02, 0x02, 0xa4, 0x01, 0x02, 0x02, 0x20, 0x1b, 0x03, 0x03, 0x28, 0x1b, 0x03, 0x03, 0x30, 0x1b, 0x03, 0x03, 0xd0, 0x3e, 0x04, 0x04, + 0xe0, 0x3e, 0x04, 0x04, 0x20, 0x18, 0x05, 0x04, 0x30, 0x18, 0x05, 0x04, 0x60, 0x3a, 0x06, 0x05, 0x40, 0x33, 0x08, 0x06, 0x80, 0x0e, 0x0b, 0x07, 0xb0, 0x30, 0x00, 0x03, 0xb8, 0x30, 0x00, 0x03, + 0xc0, 0x30, 0x00, 0x03, 0xc8, 0x30, 0x00, 0x03, 0x34, 0x1e, 0x01, 0x02, 0x38, 0x1e, 0x01, 0x02, 0x3c, 0x1e, 0x01, 0x02, 0x40, 0x1e, 0x01, 0x02, 0x44, 0x1e, 0x01, 0x02, 0x48, 0x1e, 0x01, 0x02, + 0xa8, 0x01, 0x02, 0x02, 0xac, 0x01, 0x02, 0x02, 0xb0, 0x01, 0x02, 0x02, 0xb4, 0x01, 0x02, 0x02, 0x38, 0x1b, 0x03, 0x03, 0x40, 0x1b, 0x03, 0x03, 0x48, 0x1b, 0x03, 0x03, 0xf0, 0x3e, 0x04, 0x04, + 0x00, 0x3f, 0x04, 0x04, 0x40, 0x18, 0x05, 0x04, 0x50, 0x18, 0x05, 0x04, 0x80, 0x3a, 0x06, 0x05, 0x80, 0x33, 0x08, 0x06, 0x00, 0x0f, 0x0b, 0x07, 0xd0, 0x30, 0x00, 0x03, 0xd8, 0x30, 0x00, 0x03, + 0xe0, 0x30, 0x00, 0x03, 0xe8, 0x30, 0x00, 0x03, 0x4c, 0x1e, 0x01, 0x02, 0x50, 0x1e, 0x01, 0x02, 0x54, 0x1e, 0x01, 0x02, 0x58, 0x1e, 0x01, 0x02, 0x5c, 0x1e, 0x01, 0x02, 0x60, 0x1e, 0x01, 0x02, + 0xb8, 0x01, 0x02, 0x02, 0xbc, 0x01, 0x02, 0x02, 0xc0, 0x01, 0x02, 0x02, 0xc4, 0x01, 0x02, 0x02, 0x50, 0x1b, 0x03, 0x03, 0x58, 0x1b, 0x03, 0x03, 0x60, 0x1b, 0x03, 0x03, 0x10, 0x3f, 0x04, 0x04, + 0x20, 0x3f, 0x04, 0x04, 0x60, 0x18, 0x05, 0x04, 0x70, 0x18, 0x05, 0x04, 0xa0, 0x3a, 0x06, 0x05, 0xc0, 0x33, 0x08, 0x06, 0x80, 0x0f, 0x0b, 0x07, 0xf0, 0x30, 0x00, 0x03, 0xf8, 0x30, 0x00, 0x03, + 0x00, 0x31, 0x00, 0x03, 0x08, 0x31, 0x00, 0x03, 0x64, 0x1e, 0x01, 0x02, 0x68, 0x1e, 0x01, 0x02, 0x6c, 0x1e, 0x01, 0x02, 0x70, 0x1e, 0x01, 0x02, 0x74, 0x1e, 0x01, 0x02, 0x78, 0x1e, 0x01, 0x02, + 0xc8, 0x01, 0x02, 0x02, 0xcc, 0x01, 0x02, 0x02, 0xd0, 0x01, 0x02, 0x02, 0xd4, 0x01, 0x02, 0x02, 0x68, 0x1b, 0x03, 0x03, 0x70, 0x1b, 0x03, 0x03, 0x78, 0x1b, 0x03, 0x03, 0x30, 0x3f, 0x04, 0x04, + 0x40, 0x3f, 0x04, 0x04, 0x80, 0x18, 0x05, 0x04, 0x90, 0x18, 0x05, 0x04, 0xc0, 0x3a, 0x06, 0x05, 0x00, 0x34, 0x08, 0x06, 0x00, 0x10, 0x0b, 0x07, 0x10, 0x31, 0x00, 0x03, 0x18, 0x31, 0x00, 0x03, + 0x20, 0x31, 0x00, 0x03, 0x28, 0x31, 0x00, 0x03, 0x7c, 0x1e, 0x01, 0x02, 0x80, 0x1e, 0x01, 0x02, 0x84, 0x1e, 0x01, 0x02, 0x88, 0x1e, 0x01, 0x02, 0x8c, 0x1e, 0x01, 0x02, 0x90, 0x1e, 0x01, 0x02, + 0xd8, 0x01, 0x02, 0x02, 0xdc, 0x01, 0x02, 0x02, 0xe0, 0x01, 0x02, 0x02, 0xe4, 0x01, 0x02, 0x02, 0x80, 0x1b, 0x03, 0x03, 0x88, 0x1b, 0x03, 0x03, 0x90, 0x1b, 0x03, 0x03, 0x50, 0x3f, 0x04, 0x04, + 0x60, 0x3f, 0x04, 0x04, 0xa0, 0x18, 0x05, 0x04, 0xb0, 0x18, 0x05, 0x04, 0xe0, 0x3a, 0x06, 0x05, 0x40, 0x34, 0x08, 0x06, 0x80, 0x10, 0x0b, 0x07, 0x30, 0x31, 0x00, 0x03, 0x38, 0x31, 0x00, 0x03, + 0x40, 0x31, 0x00, 0x03, 0x48, 0x31, 0x00, 0x03, 0x94, 0x1e, 0x01, 0x02, 0x98, 0x1e, 0x01, 0x02, 0x9c, 0x1e, 0x01, 0x02, 0xa0, 0x1e, 0x01, 0x02, 0xa4, 0x1e, 0x01, 0x02, 0xa8, 0x1e, 0x01, 0x02, + 0xe8, 0x01, 0x02, 0x02, 0xec, 0x01, 0x02, 0x02, 0xf0, 0x01, 0x02, 0x02, 0xf4, 0x01, 0x02, 0x02, 0x98, 0x1b, 0x03, 0x03, 0xa0, 0x1b, 0x03, 0x03, 0xa8, 0x1b, 0x03, 0x03, 0x70, 0x3f, 0x04, 0x04, + 0x80, 0x3f, 0x04, 0x04, 0xc0, 0x18, 0x05, 0x04, 0xd0, 0x18, 0x05, 0x04, 0x00, 0x3b, 0x06, 0x05, 0x80, 0x34, 0x08, 0x06, 0x00, 0x11, 0x0b, 0x07, 0x50, 0x31, 0x00, 0x03, 0x58, 0x31, 0x00, 0x03, + 0x60, 0x31, 0x00, 0x03, 0x68, 0x31, 0x00, 0x03, 0xac, 0x1e, 0x01, 0x02, 0xb0, 0x1e, 0x01, 0x02, 0xb4, 0x1e, 0x01, 0x02, 0xb8, 0x1e, 0x01, 0x02, 0xbc, 0x1e, 0x01, 0x02, 0xc0, 0x1e, 0x01, 0x02, + 0xf8, 0x01, 0x02, 0x02, 0xfc, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0xb0, 0x1b, 0x03, 0x03, 0xb8, 0x1b, 0x03, 0x03, 0xc0, 0x1b, 0x03, 0x03, 0x90, 0x3f, 0x04, 0x04, + 0xa0, 0x3f, 0x04, 0x04, 0xe0, 0x18, 0x05, 0x04, 0xf0, 0x18, 0x05, 0x04, 0x20, 0x3b, 0x06, 0x05, 0xc0, 0x34, 0x08, 0x06, 0x80, 0x11, 0x0b, 0x07, 0x70, 0x31, 0x00, 0x03, 0x78, 0x31, 0x00, 0x03, + 0x80, 0x31, 0x00, 0x03, 0x88, 0x31, 0x00, 0x03, 0xc4, 0x1e, 0x01, 0x02, 0xc8, 0x1e, 0x01, 0x02, 0xcc, 0x1e, 0x01, 0x02, 0xd0, 0x1e, 0x01, 0x02, 0xd4, 0x1e, 0x01, 0x02, 0xd8, 0x1e, 0x01, 0x02, + 0x08, 0x02, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x02, 0x10, 0x02, 0x02, 0x02, 0x14, 0x02, 0x02, 0x02, 0xc8, 0x1b, 0x03, 0x03, 0xd0, 0x1b, 0x03, 0x03, 0xd8, 0x1b, 0x03, 0x03, 0xb0, 0x3f, 0x04, 0x04, + 0xc0, 0x3f, 0x04, 0x04, 0x00, 0x19, 0x05, 0x04, 0x10, 0x19, 0x05, 0x04, 0x40, 0x3b, 0x06, 0x05, 0x00, 0x35, 0x08, 0x06, 0x00, 0x12, 0x0b, 0x07, 0x90, 0x31, 0x00, 0x03, 0x98, 0x31, 0x00, 0x03, + 0xa0, 0x31, 0x00, 0x03, 0xa8, 0x31, 0x00, 0x03, 0xdc, 0x1e, 0x01, 0x02, 0xe0, 0x1e, 0x01, 0x02, 0xe4, 0x1e, 0x01, 0x02, 0xe8, 0x1e, 0x01, 0x02, 0xec, 0x1e, 0x01, 0x02, 0xf0, 0x1e, 0x01, 0x02, + 0x18, 0x02, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0x20, 0x02, 0x02, 0x02, 0x24, 0x02, 0x02, 0x02, 0xe0, 0x1b, 0x03, 0x03, 0xe8, 0x1b, 0x03, 0x03, 0xf0, 0x1b, 0x03, 0x03, 0xd0, 0x3f, 0x04, 0x04, + 0xe0, 0x3f, 0x04, 0x04, 0x20, 0x19, 0x05, 0x04, 0x30, 0x19, 0x05, 0x04, 0x60, 0x3b, 0x06, 0x05, 0x40, 0x35, 0x08, 0x06, 0x00, 0x28, 0x0c, 0x08, 0xb0, 0x31, 0x00, 0x03, 0xb8, 0x31, 0x00, 0x03, + 0xc0, 0x31, 0x00, 0x03, 0xc8, 0x31, 0x00, 0x03, 0xf4, 0x1e, 0x01, 0x02, 0xf8, 0x1e, 0x01, 0x02, 0xfc, 0x1e, 0x01, 0x02, 0x00, 0x1f, 0x01, 0x02, 0x04, 0x1f, 0x01, 0x02, 0x08, 0x1f, 0x01, 0x02, + 0x28, 0x02, 0x02, 0x02, 0x2c, 0x02, 0x02, 0x02, 0x30, 0x02, 0x02, 0x02, 0x34, 0x02, 0x02, 0x02, 0xf8, 0x1b, 0x03, 0x03, 0x00, 0x1c, 0x03, 0x03, 0x08, 0x1c, 0x03, 0x03, 0xf0, 0x3f, 0x04, 0x04, + 0x00, 0x00, 0x04, 0x03, 0x40, 0x19, 0x05, 0x04, 0x50, 0x19, 0x05, 0x04, 0x80, 0x3b, 0x06, 0x05, 0x80, 0x35, 0x08, 0x06, 0x00, 0x29, 0x0c, 0x08, 0xd0, 0x31, 0x00, 0x03, 0xd8, 0x31, 0x00, 0x03, + 0xe0, 0x31, 0x00, 0x03, 0xe8, 0x31, 0x00, 0x03, 0x0c, 0x1f, 0x01, 0x02, 0x10, 0x1f, 0x01, 0x02, 0x14, 0x1f, 0x01, 0x02, 0x18, 0x1f, 0x01, 0x02, 0x1c, 0x1f, 0x01, 0x02, 0x20, 0x1f, 0x01, 0x02, + 0x38, 0x02, 0x02, 0x02, 0x3c, 0x02, 0x02, 0x02, 0x40, 0x02, 0x02, 0x02, 0x44, 0x02, 0x02, 0x02, 0x10, 0x1c, 0x03, 0x03, 0x18, 0x1c, 0x03, 0x03, 0x20, 0x1c, 0x03, 0x03, 0x08, 0x00, 0x04, 0x03, + 0x10, 0x00, 0x04, 0x03, 0x60, 0x19, 0x05, 0x04, 0x70, 0x19, 0x05, 0x04, 0xa0, 0x3b, 0x06, 0x05, 0xc0, 0x35, 0x08, 0x06, 0x00, 0x2a, 0x0c, 0x08, 0xf0, 0x31, 0x00, 0x03, 0xf8, 0x31, 0x00, 0x03, + 0x00, 0x32, 0x00, 0x03, 0x08, 0x32, 0x00, 0x03, 0x24, 0x1f, 0x01, 0x02, 0x28, 0x1f, 0x01, 0x02, 0x2c, 0x1f, 0x01, 0x02, 0x30, 0x1f, 0x01, 0x02, 0x34, 0x1f, 0x01, 0x02, 0x38, 0x1f, 0x01, 0x02, + 0x48, 0x02, 0x02, 0x02, 0x4c, 0x02, 0x02, 0x02, 0x50, 0x02, 0x02, 0x02, 0x54, 0x02, 0x02, 0x02, 0x28, 0x1c, 0x03, 0x03, 0x30, 0x1c, 0x03, 0x03, 0x38, 0x1c, 0x03, 0x03, 0x18, 0x00, 0x04, 0x03, + 0x20, 0x00, 0x04, 0x03, 0x80, 0x19, 0x05, 0x04, 0x90, 0x19, 0x05, 0x04, 0xc0, 0x3b, 0x06, 0x05, 0x00, 0x36, 0x08, 0x06, 0x00, 0x2b, 0x0c, 0x08, 0x10, 0x32, 0x00, 0x03, 0x18, 0x32, 0x00, 0x03, + 0x20, 0x32, 0x00, 0x03, 0x28, 0x32, 0x00, 0x03, 0x3c, 0x1f, 0x01, 0x02, 0x40, 0x1f, 0x01, 0x02, 0x44, 0x1f, 0x01, 0x02, 0x48, 0x1f, 0x01, 0x02, 0x4c, 0x1f, 0x01, 0x02, 0x50, 0x1f, 0x01, 0x02, + 0x58, 0x02, 0x02, 0x02, 0x5c, 0x02, 0x02, 0x02, 0x60, 0x02, 0x02, 0x02, 0x64, 0x02, 0x02, 0x02, 0x40, 0x1c, 0x03, 0x03, 0x48, 0x1c, 0x03, 0x03, 0x50, 0x1c, 0x03, 0x03, 0x28, 0x00, 0x04, 0x03, + 0x30, 0x00, 0x04, 0x03, 0xa0, 0x19, 0x05, 0x04, 0xb0, 0x19, 0x05, 0x04, 0xe0, 0x3b, 0x06, 0x05, 0x40, 0x36, 0x08, 0x06, 0x00, 0x2c, 0x0c, 0x08, 0x30, 0x32, 0x00, 0x03, 0x38, 0x32, 0x00, 0x03, + 0x40, 0x32, 0x00, 0x03, 0x54, 0x1f, 0x01, 0x02, 0x58, 0x1f, 0x01, 0x02, 0x5c, 0x1f, 0x01, 0x02, 0x60, 0x1f, 0x01, 0x02, 0x64, 0x1f, 0x01, 0x02, 0x68, 0x1f, 0x01, 0x02, 0x6c, 0x1f, 0x01, 0x02, + 0x68, 0x02, 0x02, 0x02, 0x6c, 0x02, 0x02, 0x02, 0x70, 0x02, 0x02, 0x02, 0x74, 0x02, 0x02, 0x02, 0x58, 0x1c, 0x03, 0x03, 0x60, 0x1c, 0x03, 0x03, 0x68, 0x1c, 0x03, 0x03, 0x38, 0x00, 0x04, 0x03, + 0x40, 0x00, 0x04, 0x03, 0xc0, 0x19, 0x05, 0x04, 0xd0, 0x19, 0x05, 0x04, 0x00, 0x3c, 0x06, 0x05, 0x80, 0x36, 0x08, 0x06, 0x00, 0x2d, 0x0c, 0x08, 0x48, 0x32, 0x00, 0x03, 0x50, 0x32, 0x00, 0x03, + 0x58, 0x32, 0x00, 0x03, 0x70, 0x1f, 0x01, 0x02, 0x74, 0x1f, 0x01, 0x02, 0x78, 0x1f, 0x01, 0x02, 0x7c, 0x1f, 0x01, 0x02, 0x80, 0x1f, 0x01, 0x02, 0x84, 0x1f, 0x01, 0x02, 0x88, 0x1f, 0x01, 0x02, + 0x78, 0x02, 0x02, 0x02, 0x7c, 0x02, 0x02, 0x02, 0x80, 0x02, 0x02, 0x02, 0x84, 0x02, 0x02, 0x02, 0x70, 0x1c, 0x03, 0x03, 0x78, 0x1c, 0x03, 0x03, 0x80, 0x1c, 0x03, 0x03, 0x48, 0x00, 0x04, 0x03, + 0x50, 0x00, 0x04, 0x03, 0xe0, 0x19, 0x05, 0x04, 0x20, 0x3c, 0x06, 0x05, 0x40, 0x3c, 0x06, 0x05, 0xc0, 0x36, 0x08, 0x06, 0x00, 0x2e, 0x0c, 0x08, 0x60, 0x32, 0x00, 0x03, 0x68, 0x32, 0x00, 0x03, + 0x70, 0x32, 0x00, 0x03, 0x8c, 0x1f, 0x01, 0x02, 0x90, 0x1f, 0x01, 0x02, 0x94, 0x1f, 0x01, 0x02, 0x98, 0x1f, 0x01, 0x02, 0x9c, 0x1f, 0x01, 0x02, 0xa0, 0x1f, 0x01, 0x02, 0xa4, 0x1f, 0x01, 0x02, + 0x88, 0x02, 0x02, 0x02, 0x8c, 0x02, 0x02, 0x02, 0x90, 0x02, 0x02, 0x02, 0x94, 0x02, 0x02, 0x02, 0x88, 0x1c, 0x03, 0x03, 0x90, 0x1c, 0x03, 0x03, 0x98, 0x1c, 0x03, 0x03, 0x58, 0x00, 0x04, 0x03, + 0x60, 0x00, 0x04, 0x03, 0xf0, 0x19, 0x05, 0x04, 0x60, 0x3c, 0x06, 0x05, 0x80, 0x15, 0x07, 0x05, 0x00, 0x37, 0x08, 0x06, 0x00, 0x2f, 0x0c, 0x08, 0x78, 0x32, 0x00, 0x03, 0x80, 0x32, 0x00, 0x03, + 0x88, 0x32, 0x00, 0x03, 0xa8, 0x1f, 0x01, 0x02, 0xac, 0x1f, 0x01, 0x02, 0xb0, 0x1f, 0x01, 0x02, 0xb4, 0x1f, 0x01, 0x02, 0xb8, 0x1f, 0x01, 0x02, 0xbc, 0x1f, 0x01, 0x02, 0xc0, 0x1f, 0x01, 0x02, + 0x98, 0x02, 0x02, 0x02, 0x9c, 0x02, 0x02, 0x02, 0xa0, 0x02, 0x02, 0x02, 0xa4, 0x02, 0x02, 0x02, 0xa0, 0x1c, 0x03, 0x03, 0xa8, 0x1c, 0x03, 0x03, 0xb0, 0x1c, 0x03, 0x03, 0x68, 0x00, 0x04, 0x03, + 0x70, 0x00, 0x04, 0x03, 0x00, 0x1a, 0x05, 0x04, 0x80, 0x3c, 0x06, 0x05, 0xa0, 0x15, 0x07, 0x05, 0x40, 0x37, 0x08, 0x06, 0x00, 0x30, 0x0c, 0x08, 0x90, 0x32, 0x00, 0x03, 0x98, 0x32, 0x00, 0x03, + 0xa0, 0x32, 0x00, 0x03, 0xc4, 0x1f, 0x01, 0x02, 0xc8, 0x1f, 0x01, 0x02, 0xcc, 0x1f, 0x01, 0x02, 0xd0, 0x1f, 0x01, 0x02, 0xd4, 0x1f, 0x01, 0x02, 0xd8, 0x1f, 0x01, 0x02, 0xdc, 0x1f, 0x01, 0x02, + 0xa8, 0x02, 0x02, 0x02, 0xac, 0x02, 0x02, 0x02, 0xb0, 0x02, 0x02, 0x02, 0xb4, 0x02, 0x02, 0x02, 0xb8, 0x1c, 0x03, 0x03, 0xc0, 0x1c, 0x03, 0x03, 0xc8, 0x1c, 0x03, 0x03, 0x78, 0x00, 0x04, 0x03, + 0x80, 0x00, 0x04, 0x03, 0x10, 0x1a, 0x05, 0x04, 0xa0, 0x3c, 0x06, 0x05, 0xc0, 0x15, 0x07, 0x05, 0x80, 0x37, 0x08, 0x06, 0x00, 0x31, 0x0c, 0x08, 0xa8, 0x32, 0x00, 0x03, 0xb0, 0x32, 0x00, 0x03, + 0xb8, 0x32, 0x00, 0x03, 0xe0, 0x1f, 0x01, 0x02, 0xe4, 0x1f, 0x01, 0x02, 0xe8, 0x1f, 0x01, 0x02, 0xec, 0x1f, 0x01, 0x02, 0xf0, 0x1f, 0x01, 0x02, 0xf4, 0x1f, 0x01, 0x02, 0xf8, 0x1f, 0x01, 0x02, + 0xb8, 0x02, 0x02, 0x02, 0xbc, 0x02, 0x02, 0x02, 0xc0, 0x02, 0x02, 0x02, 0xc4, 0x02, 0x02, 0x02, 0xd0, 0x1c, 0x03, 0x03, 0xd8, 0x1c, 0x03, 0x03, 0xe0, 0x1c, 0x03, 0x03, 0x88, 0x00, 0x04, 0x03, + 0x90, 0x00, 0x04, 0x03, 0x20, 0x1a, 0x05, 0x04, 0xc0, 0x3c, 0x06, 0x05, 0xe0, 0x15, 0x07, 0x05, 0xc0, 0x37, 0x08, 0x06, 0x00, 0x09, 0x0d, 0x08, 0xc0, 0x32, 0x00, 0x03, 0xc8, 0x32, 0x00, 0x03, + 0xd0, 0x32, 0x00, 0x03, 0xfc, 0x1f, 0x01, 0x02, 0x00, 0x20, 0x01, 0x02, 0x04, 0x20, 0x01, 0x02, 0x08, 0x20, 0x01, 0x02, 0x0c, 0x20, 0x01, 0x02, 0x10, 0x20, 0x01, 0x02, 0x14, 0x20, 0x01, 0x02, + 0xc8, 0x02, 0x02, 0x02, 0xcc, 0x02, 0x02, 0x02, 0xd0, 0x02, 0x02, 0x02, 0xd4, 0x02, 0x02, 0x02, 0xe8, 0x1c, 0x03, 0x03, 0xf0, 0x1c, 0x03, 0x03, 0xf8, 0x1c, 0x03, 0x03, 0x98, 0x00, 0x04, 0x03, + 0xa0, 0x00, 0x04, 0x03, 0x30, 0x1a, 0x05, 0x04, 0xe0, 0x3c, 0x06, 0x05, 0x00, 0x16, 0x07, 0x05, 0x00, 0x38, 0x08, 0x06, 0x00, 0x0a, 0x0d, 0x08, 0xd8, 0x32, 0x00, 0x03, 0xe0, 0x32, 0x00, 0x03, + 0xe8, 0x32, 0x00, 0x03, 0x18, 0x20, 0x01, 0x02, 0x1c, 0x20, 0x01, 0x02, 0x20, 0x20, 0x01, 0x02, 0x24, 0x20, 0x01, 0x02, 0x28, 0x20, 0x01, 0x02, 0x2c, 0x20, 0x01, 0x02, 0x30, 0x20, 0x01, 0x02, + 0xd8, 0x02, 0x02, 0x02, 0xdc, 0x02, 0x02, 0x02, 0xe0, 0x02, 0x02, 0x02, 0xe4, 0x02, 0x02, 0x02, 0x00, 0x1d, 0x03, 0x03, 0x08, 0x1d, 0x03, 0x03, 0x10, 0x1d, 0x03, 0x03, 0xa8, 0x00, 0x04, 0x03, + 0xb0, 0x00, 0x04, 0x03, 0x40, 0x1a, 0x05, 0x04, 0x00, 0x3d, 0x06, 0x05, 0x20, 0x16, 0x07, 0x05, 0x40, 0x38, 0x08, 0x06, 0x00, 0x0b, 0x0d, 0x08, 0xf0, 0x32, 0x00, 0x03, 0xf8, 0x32, 0x00, 0x03, + 0x00, 0x33, 0x00, 0x03, 0x34, 0x20, 0x01, 0x02, 0x38, 0x20, 0x01, 0x02, 0x3c, 0x20, 0x01, 0x02, 0x40, 0x20, 0x01, 0x02, 0x44, 0x20, 0x01, 0x02, 0x48, 0x20, 0x01, 0x02, 0x4c, 0x20, 0x01, 0x02, + 0xe8, 0x02, 0x02, 0x02, 0xec, 0x02, 0x02, 0x02, 0xf0, 0x02, 0x02, 0x02, 0xf4, 0x02, 0x02, 0x02, 0x18, 0x1d, 0x03, 0x03, 0x20, 0x1d, 0x03, 0x03, 0x28, 0x1d, 0x03, 0x03, 0xb8, 0x00, 0x04, 0x03, + 0xc0, 0x00, 0x04, 0x03, 0x50, 0x1a, 0x05, 0x04, 0x20, 0x3d, 0x06, 0x05, 0x40, 0x16, 0x07, 0x05, 0x80, 0x38, 0x08, 0x06, 0x00, 0x0c, 0x0d, 0x08, 0x08, 0x33, 0x00, 0x03, 0x10, 0x33, 0x00, 0x03, + 0x18, 0x33, 0x00, 0x03, 0x50, 0x20, 0x01, 0x02, 0x54, 0x20, 0x01, 0x02, 0x58, 0x20, 0x01, 0x02, 0x5c, 0x20, 0x01, 0x02, 0x60, 0x20, 0x01, 0x02, 0x64, 0x20, 0x01, 0x02, 0x68, 0x20, 0x01, 0x02, + 0xf8, 0x02, 0x02, 0x02, 0xfc, 0x02, 0x02, 0x02, 0x00, 0x03, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x30, 0x1d, 0x03, 0x03, 0x38, 0x1d, 0x03, 0x03, 0x40, 0x1d, 0x03, 0x03, 0xc8, 0x00, 0x04, 0x03, + 0xd0, 0x00, 0x04, 0x03, 0x60, 0x1a, 0x05, 0x04, 0x40, 0x3d, 0x06, 0x05, 0x60, 0x16, 0x07, 0x05, 0xc0, 0x38, 0x08, 0x06, 0x00, 0x0d, 0x0d, 0x08, 0x20, 0x33, 0x00, 0x03, 0x28, 0x33, 0x00, 0x03, + 0x30, 0x33, 0x00, 0x03, 0x6c, 0x20, 0x01, 0x02, 0x70, 0x20, 0x01, 0x02, 0x74, 0x20, 0x01, 0x02, 0x78, 0x20, 0x01, 0x02, 0x7c, 0x20, 0x01, 0x02, 0x80, 0x20, 0x01, 0x02, 0x84, 0x20, 0x01, 0x02, + 0x08, 0x03, 0x02, 0x02, 0x0c, 0x03, 0x02, 0x02, 0x10, 0x03, 0x02, 0x02, 0x14, 0x03, 0x02, 0x02, 0x48, 0x1d, 0x03, 0x03, 0x50, 0x1d, 0x03, 0x03, 0x58, 0x1d, 0x03, 0x03, 0xd8, 0x00, 0x04, 0x03, + 0xe0, 0x00, 0x04, 0x03, 0x70, 0x1a, 0x05, 0x04, 0x60, 0x3d, 0x06, 0x05, 0x80, 0x16, 0x07, 0x05, 0x00, 0x39, 0x08, 0x06, 0x00, 0x0e, 0x0d, 0x08, 0x38, 0x33, 0x00, 0x03, 0x40, 0x33, 0x00, 0x03, + 0x48, 0x33, 0x00, 0x03, 0x88, 0x20, 0x01, 0x02, 0x8c, 0x20, 0x01, 0x02, 0x90, 0x20, 0x01, 0x02, 0x94, 0x20, 0x01, 0x02, 0x98, 0x20, 0x01, 0x02, 0x9c, 0x20, 0x01, 0x02, 0xa0, 0x20, 0x01, 0x02, + 0x18, 0x03, 0x02, 0x02, 0x1c, 0x03, 0x02, 0x02, 0x20, 0x03, 0x02, 0x02, 0x24, 0x03, 0x02, 0x02, 0x60, 0x1d, 0x03, 0x03, 0x68, 0x1d, 0x03, 0x03, 0x70, 0x1d, 0x03, 0x03, 0xe8, 0x00, 0x04, 0x03, + 0xf0, 0x00, 0x04, 0x03, 0x80, 0x1a, 0x05, 0x04, 0x80, 0x3d, 0x06, 0x05, 0xa0, 0x16, 0x07, 0x05, 0x40, 0x39, 0x08, 0x06, 0x00, 0x26, 0x0e, 0x09, 0x50, 0x33, 0x00, 0x03, 0x58, 0x33, 0x00, 0x03, + 0x60, 0x33, 0x00, 0x03, 0xa4, 0x20, 0x01, 0x02, 0xa8, 0x20, 0x01, 0x02, 0xac, 0x20, 0x01, 0x02, 0xb0, 0x20, 0x01, 0x02, 0xb4, 0x20, 0x01, 0x02, 0xb8, 0x20, 0x01, 0x02, 0xbc, 0x20, 0x01, 0x02, + 0x28, 0x03, 0x02, 0x02, 0x2c, 0x03, 0x02, 0x02, 0x30, 0x03, 0x02, 0x02, 0x34, 0x03, 0x02, 0x02, 0x78, 0x1d, 0x03, 0x03, 0x80, 0x1d, 0x03, 0x03, 0x88, 0x1d, 0x03, 0x03, 0xf8, 0x00, 0x04, 0x03, + 0x00, 0x01, 0x04, 0x03, 0x90, 0x1a, 0x05, 0x04, 0xa0, 0x3d, 0x06, 0x05, 0xc0, 0x16, 0x07, 0x05, 0x80, 0x39, 0x08, 0x06, 0x00, 0x28, 0x0e, 0x09, 0x68, 0x33, 0x00, 0x03, 0x70, 0x33, 0x00, 0x03, + 0x78, 0x33, 0x00, 0x03, 0xc0, 0x20, 0x01, 0x02, 0xc4, 0x20, 0x01, 0x02, 0xc8, 0x20, 0x01, 0x02, 0xcc, 0x20, 0x01, 0x02, 0xd0, 0x20, 0x01, 0x02, 0xd4, 0x20, 0x01, 0x02, 0xd8, 0x20, 0x01, 0x02, + 0x38, 0x03, 0x02, 0x02, 0x3c, 0x03, 0x02, 0x02, 0x40, 0x03, 0x02, 0x02, 0x44, 0x03, 0x02, 0x02, 0x90, 0x1d, 0x03, 0x03, 0x98, 0x1d, 0x03, 0x03, 0xa0, 0x1d, 0x03, 0x03, 0x08, 0x01, 0x04, 0x03, + 0x10, 0x01, 0x04, 0x03, 0xa0, 0x1a, 0x05, 0x04, 0xc0, 0x3d, 0x06, 0x05, 0xe0, 0x16, 0x07, 0x05, 0xc0, 0x39, 0x08, 0x06, 0x00, 0x2a, 0x0e, 0x09, 0x80, 0x33, 0x00, 0x03, 0x88, 0x33, 0x00, 0x03, + 0x90, 0x33, 0x00, 0x03, 0xdc, 0x20, 0x01, 0x02, 0xe0, 0x20, 0x01, 0x02, 0xe4, 0x20, 0x01, 0x02, 0xe8, 0x20, 0x01, 0x02, 0xec, 0x20, 0x01, 0x02, 0xf0, 0x20, 0x01, 0x02, 0xf4, 0x20, 0x01, 0x02, + 0x48, 0x03, 0x02, 0x02, 0x4c, 0x03, 0x02, 0x02, 0x50, 0x03, 0x02, 0x02, 0x54, 0x03, 0x02, 0x02, 0xa8, 0x1d, 0x03, 0x03, 0xb0, 0x1d, 0x03, 0x03, 0xb8, 0x1d, 0x03, 0x03, 0x18, 0x01, 0x04, 0x03, + 0x20, 0x01, 0x04, 0x03, 0xb0, 0x1a, 0x05, 0x04, 0xe0, 0x3d, 0x06, 0x05, 0x00, 0x17, 0x07, 0x05, 0x00, 0x3a, 0x08, 0x06, 0x00, 0x2c, 0x0e, 0x09, 0x98, 0x33, 0x00, 0x03, 0xa0, 0x33, 0x00, 0x03, + 0xa8, 0x33, 0x00, 0x03, 0xf8, 0x20, 0x01, 0x02, 0xfc, 0x20, 0x01, 0x02, 0x00, 0x21, 0x01, 0x02, 0x04, 0x21, 0x01, 0x02, 0x08, 0x21, 0x01, 0x02, 0x0c, 0x21, 0x01, 0x02, 0x10, 0x21, 0x01, 0x02, + 0x58, 0x03, 0x02, 0x02, 0x5c, 0x03, 0x02, 0x02, 0x60, 0x03, 0x02, 0x02, 0x64, 0x03, 0x02, 0x02, 0xc0, 0x1d, 0x03, 0x03, 0xc8, 0x1d, 0x03, 0x03, 0xd0, 0x1d, 0x03, 0x03, 0x28, 0x01, 0x04, 0x03, + 0x30, 0x01, 0x04, 0x03, 0xc0, 0x1a, 0x05, 0x04, 0x00, 0x3e, 0x06, 0x05, 0x20, 0x17, 0x07, 0x05, 0x40, 0x3a, 0x08, 0x06, 0x00, 0x2e, 0x0e, 0x09, 0xb0, 0x33, 0x00, 0x03, 0xb8, 0x33, 0x00, 0x03, + 0xc0, 0x33, 0x00, 0x03, 0x14, 0x21, 0x01, 0x02, 0x18, 0x21, 0x01, 0x02, 0x1c, 0x21, 0x01, 0x02, 0x20, 0x21, 0x01, 0x02, 0x24, 0x21, 0x01, 0x02, 0x28, 0x21, 0x01, 0x02, 0x68, 0x03, 0x02, 0x02, + 0x6c, 0x03, 0x02, 0x02, 0x70, 0x03, 0x02, 0x02, 0x74, 0x03, 0x02, 0x02, 0x78, 0x03, 0x02, 0x02, 0xd8, 0x1d, 0x03, 0x03, 0xe0, 0x1d, 0x03, 0x03, 0xe8, 0x1d, 0x03, 0x03, 0x38, 0x01, 0x04, 0x03, + 0x40, 0x01, 0x04, 0x03, 0xd0, 0x1a, 0x05, 0x04, 0x20, 0x3e, 0x06, 0x05, 0x40, 0x17, 0x07, 0x05, 0x80, 0x3a, 0x08, 0x06, 0x00, 0x0a, 0x0f, 0x09, 0xc8, 0x33, 0x00, 0x03, 0xd0, 0x33, 0x00, 0x03, + 0xd8, 0x33, 0x00, 0x03, 0x2c, 0x21, 0x01, 0x02, 0x30, 0x21, 0x01, 0x02, 0x34, 0x21, 0x01, 0x02, 0x38, 0x21, 0x01, 0x02, 0x3c, 0x21, 0x01, 0x02, 0x40, 0x21, 0x01, 0x02, 0x7c, 0x03, 0x02, 0x02, + 0x80, 0x03, 0x02, 0x02, 0x84, 0x03, 0x02, 0x02, 0x88, 0x03, 0x02, 0x02, 0x8c, 0x03, 0x02, 0x02, 0xf0, 0x1d, 0x03, 0x03, 0xf8, 0x1d, 0x03, 0x03, 0x00, 0x1e, 0x03, 0x03, 0x48, 0x01, 0x04, 0x03, + 0x50, 0x01, 0x04, 0x03, 0xe0, 0x1a, 0x05, 0x04, 0x40, 0x3e, 0x06, 0x05, 0x60, 0x17, 0x07, 0x05, 0xc0, 0x13, 0x09, 0x06, 0x00, 0x0c, 0x0f, 0x09, 0xe0, 0x33, 0x00, 0x03, 0xe8, 0x33, 0x00, 0x03, + 0xf0, 0x33, 0x00, 0x03, 0x44, 0x21, 0x01, 0x02, 0x48, 0x21, 0x01, 0x02, 0x4c, 0x21, 0x01, 0x02, 0x50, 0x21, 0x01, 0x02, 0x54, 0x21, 0x01, 0x02, 0x58, 0x21, 0x01, 0x02, 0x90, 0x03, 0x02, 0x02, + 0x94, 0x03, 0x02, 0x02, 0x98, 0x03, 0x02, 0x02, 0x9c, 0x03, 0x02, 0x02, 0xa0, 0x03, 0x02, 0x02, 0x08, 0x1e, 0x03, 0x03, 0x10, 0x1e, 0x03, 0x03, 0x18, 0x1e, 0x03, 0x03, 0x58, 0x01, 0x04, 0x03, + 0x60, 0x01, 0x04, 0x03, 0xf0, 0x1a, 0x05, 0x04, 0x60, 0x3e, 0x06, 0x05, 0x80, 0x17, 0x07, 0x05, 0x00, 0x14, 0x09, 0x06, 0x00, 0x0e, 0x0f, 0x09, 0xf8, 0x33, 0x00, 0x03, 0x00, 0x34, 0x00, 0x03, + 0x08, 0x34, 0x00, 0x03, 0x5c, 0x21, 0x01, 0x02, 0x60, 0x21, 0x01, 0x02, 0x64, 0x21, 0x01, 0x02, 0x68, 0x21, 0x01, 0x02, 0x6c, 0x21, 0x01, 0x02, 0x70, 0x21, 0x01, 0x02, 0xa4, 0x03, 0x02, 0x02, + 0xa8, 0x03, 0x02, 0x02, 0xac, 0x03, 0x02, 0x02, 0xb0, 0x03, 0x02, 0x02, 0xb4, 0x03, 0x02, 0x02, 0x20, 0x1e, 0x03, 0x03, 0x28, 0x1e, 0x03, 0x03, 0x30, 0x1e, 0x03, 0x03, 0x68, 0x01, 0x04, 0x03, + 0x70, 0x01, 0x04, 0x03, 0x00, 0x1b, 0x05, 0x04, 0x80, 0x3e, 0x06, 0x05, 0xa0, 0x17, 0x07, 0x05, 0x40, 0x14, 0x09, 0x06, 0x00, 0x24, 0x10, 0x0a, 0x10, 0x34, 0x00, 0x03, 0x18, 0x34, 0x00, 0x03, + 0x20, 0x34, 0x00, 0x03, 0x74, 0x21, 0x01, 0x02, 0x78, 0x21, 0x01, 0x02, 0x7c, 0x21, 0x01, 0x02, 0x80, 0x21, 0x01, 0x02, 0x84, 0x21, 0x01, 0x02, 0x88, 0x21, 0x01, 0x02, 0xb8, 0x03, 0x02, 0x02, + 0xbc, 0x03, 0x02, 0x02, 0xc0, 0x03, 0x02, 0x02, 0xc4, 0x03, 0x02, 0x02, 0xc8, 0x03, 0x02, 0x02, 0x38, 0x1e, 0x03, 0x03, 0x40, 0x1e, 0x03, 0x03, 0x48, 0x1e, 0x03, 0x03, 0x78, 0x01, 0x04, 0x03, + 0x80, 0x01, 0x04, 0x03, 0x10, 0x1b, 0x05, 0x04, 0xa0, 0x3e, 0x06, 0x05, 0xc0, 0x17, 0x07, 0x05, 0x80, 0x14, 0x09, 0x06, 0x00, 0x28, 0x10, 0x0a, 0x28, 0x34, 0x00, 0x03, 0x30, 0x34, 0x00, 0x03, + 0x38, 0x34, 0x00, 0x03, 0x8c, 0x21, 0x01, 0x02, 0x90, 0x21, 0x01, 0x02, 0x94, 0x21, 0x01, 0x02, 0x98, 0x21, 0x01, 0x02, 0x9c, 0x21, 0x01, 0x02, 0xa0, 0x21, 0x01, 0x02, 0xcc, 0x03, 0x02, 0x02, + 0xd0, 0x03, 0x02, 0x02, 0xd4, 0x03, 0x02, 0x02, 0xd8, 0x03, 0x02, 0x02, 0xdc, 0x03, 0x02, 0x02, 0x50, 0x1e, 0x03, 0x03, 0x58, 0x1e, 0x03, 0x03, 0x60, 0x1e, 0x03, 0x03, 0x88, 0x01, 0x04, 0x03, + 0x90, 0x01, 0x04, 0x03, 0x20, 0x1b, 0x05, 0x04, 0xc0, 0x3e, 0x06, 0x05, 0xe0, 0x17, 0x07, 0x05, 0xc0, 0x14, 0x09, 0x06, 0x00, 0x2c, 0x10, 0x0a, 0x40, 0x34, 0x00, 0x03, 0x48, 0x34, 0x00, 0x03, + 0x50, 0x34, 0x00, 0x03, 0xa4, 0x21, 0x01, 0x02, 0xa8, 0x21, 0x01, 0x02, 0xac, 0x21, 0x01, 0x02, 0xb0, 0x21, 0x01, 0x02, 0xb4, 0x21, 0x01, 0x02, 0xb8, 0x21, 0x01, 0x02, 0xe0, 0x03, 0x02, 0x02, + 0xe4, 0x03, 0x02, 0x02, 0xe8, 0x03, 0x02, 0x02, 0xec, 0x03, 0x02, 0x02, 0xf0, 0x03, 0x02, 0x02, 0x68, 0x1e, 0x03, 0x03, 0x70, 0x1e, 0x03, 0x03, 0x78, 0x1e, 0x03, 0x03, 0x98, 0x01, 0x04, 0x03, + 0xa0, 0x01, 0x04, 0x03, 0x30, 0x1b, 0x05, 0x04, 0xe0, 0x3e, 0x06, 0x05, 0x00, 0x18, 0x07, 0x05, 0x00, 0x15, 0x09, 0x06, 0x00, 0x04, 0x11, 0x0a, 0x58, 0x34, 0x00, 0x03, 0x60, 0x34, 0x00, 0x03, + 0x68, 0x34, 0x00, 0x03, 0xbc, 0x21, 0x01, 0x02, 0xc0, 0x21, 0x01, 0x02, 0xc4, 0x21, 0x01, 0x02, 0xc8, 0x21, 0x01, 0x02, 0xcc, 0x21, 0x01, 0x02, 0xd0, 0x21, 0x01, 0x02, 0xf4, 0x03, 0x02, 0x02, + 0xf8, 0x03, 0x02, 0x02, 0xfc, 0x03, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x80, 0x1e, 0x03, 0x03, 0x88, 0x1e, 0x03, 0x03, 0x90, 0x1e, 0x03, 0x03, 0xa8, 0x01, 0x04, 0x03, + 0xb0, 0x01, 0x04, 0x03, 0x40, 0x1b, 0x05, 0x04, 0x00, 0x3f, 0x06, 0x05, 0x20, 0x18, 0x07, 0x05, 0x40, 0x15, 0x09, 0x06, 0x00, 0x08, 0x11, 0x0a, 0x70, 0x34, 0x00, 0x03, 0x78, 0x34, 0x00, 0x03, + 0x80, 0x34, 0x00, 0x03, 0xd4, 0x21, 0x01, 0x02, 0xd8, 0x21, 0x01, 0x02, 0xdc, 0x21, 0x01, 0x02, 0xe0, 0x21, 0x01, 0x02, 0xe4, 0x21, 0x01, 0x02, 0xe8, 0x21, 0x01, 0x02, 0x08, 0x04, 0x02, 0x02, + 0x0c, 0x04, 0x02, 0x02, 0x10, 0x04, 0x02, 0x02, 0x14, 0x04, 0x02, 0x02, 0x18, 0x04, 0x02, 0x02, 0x98, 0x1e, 0x03, 0x03, 0xa0, 0x1e, 0x03, 0x03, 0xa8, 0x1e, 0x03, 0x03, 0xb8, 0x01, 0x04, 0x03, + 0xc0, 0x01, 0x04, 0x03, 0x50, 0x1b, 0x05, 0x04, 0x20, 0x3f, 0x06, 0x05, 0x40, 0x18, 0x07, 0x05, 0x80, 0x15, 0x09, 0x06, 0x00, 0x28, 0x12, 0x0b, 0x88, 0x34, 0x00, 0x03, 0x90, 0x34, 0x00, 0x03, + 0x98, 0x34, 0x00, 0x03, 0xec, 0x21, 0x01, 0x02, 0xf0, 0x21, 0x01, 0x02, 0xf4, 0x21, 0x01, 0x02, 0xf8, 0x21, 0x01, 0x02, 0xfc, 0x21, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x1c, 0x04, 0x02, 0x02, + 0x20, 0x04, 0x02, 0x02, 0x24, 0x04, 0x02, 0x02, 0x28, 0x04, 0x02, 0x02, 0x2c, 0x04, 0x02, 0x02, 0xb0, 0x1e, 0x03, 0x03, 0xb8, 0x1e, 0x03, 0x03, 0xc0, 0x1e, 0x03, 0x03, 0xc8, 0x01, 0x04, 0x03, + 0xd0, 0x01, 0x04, 0x03, 0x60, 0x1b, 0x05, 0x04, 0x40, 0x3f, 0x06, 0x05, 0x60, 0x18, 0x07, 0x05, 0xc0, 0x15, 0x09, 0x06, 0x00, 0x08, 0x13, 0x0b, 0xa0, 0x34, 0x00, 0x03, 0xa8, 0x34, 0x00, 0x03, + 0xb0, 0x34, 0x00, 0x03, 0x04, 0x22, 0x01, 0x02, 0x08, 0x22, 0x01, 0x02, 0x0c, 0x22, 0x01, 0x02, 0x10, 0x22, 0x01, 0x02, 0x14, 0x22, 0x01, 0x02, 0x18, 0x22, 0x01, 0x02, 0x30, 0x04, 0x02, 0x02, + 0x34, 0x04, 0x02, 0x02, 0x38, 0x04, 0x02, 0x02, 0x3c, 0x04, 0x02, 0x02, 0x40, 0x04, 0x02, 0x02, 0xc8, 0x1e, 0x03, 0x03, 0xd0, 0x1e, 0x03, 0x03, 0xd8, 0x1e, 0x03, 0x03, 0xd8, 0x01, 0x04, 0x03, + 0xe0, 0x01, 0x04, 0x03, 0x70, 0x1b, 0x05, 0x04, 0x60, 0x3f, 0x06, 0x05, 0x80, 0x18, 0x07, 0x05, 0x00, 0x16, 0x09, 0x06, 0x00, 0x00, 0x15, 0x0c, 0xb8, 0x34, 0x00, 0x03, 0xc0, 0x34, 0x00, 0x03, + 0xc8, 0x34, 0x00, 0x03, 0x1c, 0x22, 0x01, 0x02, 0x20, 0x22, 0x01, 0x02, 0x24, 0x22, 0x01, 0x02, 0x28, 0x22, 0x01, 0x02, 0x2c, 0x22, 0x01, 0x02, 0x30, 0x22, 0x01, 0x02, 0x44, 0x04, 0x02, 0x02, + 0x48, 0x04, 0x02, 0x02, 0x4c, 0x04, 0x02, 0x02, 0x50, 0x04, 0x02, 0x02, 0x54, 0x04, 0x02, 0x02, 0xe0, 0x1e, 0x03, 0x03, 0xe8, 0x1e, 0x03, 0x03, 0xf0, 0x1e, 0x03, 0x03, 0xe8, 0x01, 0x04, 0x03, + 0xf0, 0x01, 0x04, 0x03, 0x80, 0x1b, 0x05, 0x04, 0x80, 0x3f, 0x06, 0x05, 0xa0, 0x18, 0x07, 0x05, 0x40, 0x16, 0x09, 0x06, 0xd0, 0x34, 0x00, 0x03, 0xd8, 0x34, 0x00, 0x03, 0xe0, 0x34, 0x00, 0x03, + 0xe8, 0x34, 0x00, 0x03, 0x34, 0x22, 0x01, 0x02, 0x38, 0x22, 0x01, 0x02, 0x3c, 0x22, 0x01, 0x02, 0x40, 0x22, 0x01, 0x02, 0x44, 0x22, 0x01, 0x02, 0x48, 0x22, 0x01, 0x02, 0x58, 0x04, 0x02, 0x02, + 0x5c, 0x04, 0x02, 0x02, 0x60, 0x04, 0x02, 0x02, 0x64, 0x04, 0x02, 0x02, 0x68, 0x04, 0x02, 0x02, 0xf8, 0x1e, 0x03, 0x03, 0x00, 0x1f, 0x03, 0x03, 0x08, 0x1f, 0x03, 0x03, 0xf8, 0x01, 0x04, 0x03, + 0x00, 0x02, 0x04, 0x03, 0x90, 0x1b, 0x05, 0x04, 0xa0, 0x3f, 0x06, 0x05, 0xc0, 0x18, 0x07, 0x05, 0x80, 0x16, 0x09, 0x06, 0xf0, 0x34, 0x00, 0x03, 0xf8, 0x34, 0x00, 0x03, 0x00, 0x35, 0x00, 0x03, + 0x08, 0x35, 0x00, 0x03, 0x4c, 0x22, 0x01, 0x02, 0x50, 0x22, 0x01, 0x02, 0x54, 0x22, 0x01, 0x02, 0x58, 0x22, 0x01, 0x02, 0x5c, 0x22, 0x01, 0x02, 0x60, 0x22, 0x01, 0x02, 0x6c, 0x04, 0x02, 0x02, + 0x70, 0x04, 0x02, 0x02, 0x74, 0x04, 0x02, 0x02, 0x78, 0x04, 0x02, 0x02, 0x7c, 0x04, 0x02, 0x02, 0x10, 0x1f, 0x03, 0x03, 0x18, 0x1f, 0x03, 0x03, 0x20, 0x1f, 0x03, 0x03, 0x08, 0x02, 0x04, 0x03, + 0x10, 0x02, 0x04, 0x03, 0xa0, 0x1b, 0x05, 0x04, 0xc0, 0x3f, 0x06, 0x05, 0xe0, 0x18, 0x07, 0x05, 0xc0, 0x16, 0x09, 0x06, 0x10, 0x35, 0x00, 0x03, 0x18, 0x35, 0x00, 0x03, 0x20, 0x35, 0x00, 0x03, + 0x28, 0x35, 0x00, 0x03, 0x64, 0x22, 0x01, 0x02, 0x68, 0x22, 0x01, 0x02, 0x6c, 0x22, 0x01, 0x02, 0x70, 0x22, 0x01, 0x02, 0x74, 0x22, 0x01, 0x02, 0x78, 0x22, 0x01, 0x02, 0x80, 0x04, 0x02, 0x02, + 0x84, 0x04, 0x02, 0x02, 0x88, 0x04, 0x02, 0x02, 0x8c, 0x04, 0x02, 0x02, 0x90, 0x04, 0x02, 0x02, 0x28, 0x1f, 0x03, 0x03, 0x30, 0x1f, 0x03, 0x03, 0x38, 0x1f, 0x03, 0x03, 0x18, 0x02, 0x04, 0x03, + 0x20, 0x02, 0x04, 0x03, 0xb0, 0x1b, 0x05, 0x04, 0xe0, 0x3f, 0x06, 0x05, 0x00, 0x19, 0x07, 0x05, 0x00, 0x17, 0x09, 0x06, 0x30, 0x35, 0x00, 0x03, 0x38, 0x35, 0x00, 0x03, 0x40, 0x35, 0x00, 0x03, + 0x48, 0x35, 0x00, 0x03, 0x7c, 0x22, 0x01, 0x02, 0x80, 0x22, 0x01, 0x02, 0x84, 0x22, 0x01, 0x02, 0x88, 0x22, 0x01, 0x02, 0x8c, 0x22, 0x01, 0x02, 0x90, 0x22, 0x01, 0x02, 0x94, 0x04, 0x02, 0x02, + 0x98, 0x04, 0x02, 0x02, 0x9c, 0x04, 0x02, 0x02, 0xa0, 0x04, 0x02, 0x02, 0xa4, 0x04, 0x02, 0x02, 0x40, 0x1f, 0x03, 0x03, 0x48, 0x1f, 0x03, 0x03, 0x50, 0x1f, 0x03, 0x03, 0x28, 0x02, 0x04, 0x03, + 0x30, 0x02, 0x04, 0x03, 0xc0, 0x1b, 0x05, 0x04, 0x00, 0x00, 0x06, 0x04, 0x20, 0x19, 0x07, 0x05, 0x40, 0x17, 0x09, 0x06, 0x50, 0x35, 0x00, 0x03, 0x58, 0x35, 0x00, 0x03, 0x60, 0x35, 0x00, 0x03, + 0x68, 0x35, 0x00, 0x03, 0x94, 0x22, 0x01, 0x02, 0x98, 0x22, 0x01, 0x02, 0x9c, 0x22, 0x01, 0x02, 0xa0, 0x22, 0x01, 0x02, 0xa4, 0x22, 0x01, 0x02, 0xa8, 0x22, 0x01, 0x02, 0xa8, 0x04, 0x02, 0x02, + 0xac, 0x04, 0x02, 0x02, 0xb0, 0x04, 0x02, 0x02, 0xb4, 0x04, 0x02, 0x02, 0xb8, 0x04, 0x02, 0x02, 0x58, 0x1f, 0x03, 0x03, 0x60, 0x1f, 0x03, 0x03, 0x68, 0x1f, 0x03, 0x03, 0x38, 0x02, 0x04, 0x03, + 0x40, 0x02, 0x04, 0x03, 0xd0, 0x1b, 0x05, 0x04, 0x10, 0x00, 0x06, 0x04, 0x40, 0x19, 0x07, 0x05, 0x80, 0x17, 0x09, 0x06, 0x70, 0x35, 0x00, 0x03, 0x78, 0x35, 0x00, 0x03, 0x80, 0x35, 0x00, 0x03, + 0x88, 0x35, 0x00, 0x03, 0xac, 0x22, 0x01, 0x02, 0xb0, 0x22, 0x01, 0x02, 0xb4, 0x22, 0x01, 0x02, 0xb8, 0x22, 0x01, 0x02, 0xbc, 0x22, 0x01, 0x02, 0xc0, 0x22, 0x01, 0x02, 0xbc, 0x04, 0x02, 0x02, + 0xc0, 0x04, 0x02, 0x02, 0xc4, 0x04, 0x02, 0x02, 0xc8, 0x04, 0x02, 0x02, 0xcc, 0x04, 0x02, 0x02, 0x70, 0x1f, 0x03, 0x03, 0x78, 0x1f, 0x03, 0x03, 0x80, 0x1f, 0x03, 0x03, 0x48, 0x02, 0x04, 0x03, + 0x50, 0x02, 0x04, 0x03, 0xe0, 0x1b, 0x05, 0x04, 0x20, 0x00, 0x06, 0x04, 0x60, 0x19, 0x07, 0x05, 0xc0, 0x17, 0x09, 0x06, 0x90, 0x35, 0x00, 0x03, 0x98, 0x35, 0x00, 0x03, 0xa0, 0x35, 0x00, 0x03, + 0xa8, 0x35, 0x00, 0x03, 0xc4, 0x22, 0x01, 0x02, 0xc8, 0x22, 0x01, 0x02, 0xcc, 0x22, 0x01, 0x02, 0xd0, 0x22, 0x01, 0x02, 0xd4, 0x22, 0x01, 0x02, 0xd8, 0x22, 0x01, 0x02, 0xd0, 0x04, 0x02, 0x02, + 0xd4, 0x04, 0x02, 0x02, 0xd8, 0x04, 0x02, 0x02, 0xdc, 0x04, 0x02, 0x02, 0xe0, 0x04, 0x02, 0x02, 0x88, 0x1f, 0x03, 0x03, 0x90, 0x1f, 0x03, 0x03, 0x98, 0x1f, 0x03, 0x03, 0x58, 0x02, 0x04, 0x03, + 0x60, 0x02, 0x04, 0x03, 0xf0, 0x1b, 0x05, 0x04, 0x30, 0x00, 0x06, 0x04, 0x80, 0x19, 0x07, 0x05, 0x00, 0x18, 0x09, 0x06, 0xb0, 0x35, 0x00, 0x03, 0xb8, 0x35, 0x00, 0x03, 0xc0, 0x35, 0x00, 0x03, + 0xc8, 0x35, 0x00, 0x03, 0xdc, 0x22, 0x01, 0x02, 0xe0, 0x22, 0x01, 0x02, 0xe4, 0x22, 0x01, 0x02, 0xe8, 0x22, 0x01, 0x02, 0xec, 0x22, 0x01, 0x02, 0xf0, 0x22, 0x01, 0x02, 0xe4, 0x04, 0x02, 0x02, + 0xe8, 0x04, 0x02, 0x02, 0xec, 0x04, 0x02, 0x02, 0xf0, 0x04, 0x02, 0x02, 0xf4, 0x04, 0x02, 0x02, 0xa0, 0x1f, 0x03, 0x03, 0xa8, 0x1f, 0x03, 0x03, 0xb0, 0x1f, 0x03, 0x03, 0x68, 0x02, 0x04, 0x03, + 0x70, 0x02, 0x04, 0x03, 0x00, 0x1c, 0x05, 0x04, 0x40, 0x00, 0x06, 0x04, 0xa0, 0x19, 0x07, 0x05, 0x40, 0x18, 0x09, 0x06, 0xd0, 0x35, 0x00, 0x03, 0xd8, 0x35, 0x00, 0x03, 0xe0, 0x35, 0x00, 0x03, + 0xe8, 0x35, 0x00, 0x03, 0xf4, 0x22, 0x01, 0x02, 0xf8, 0x22, 0x01, 0x02, 0xfc, 0x22, 0x01, 0x02, 0x00, 0x23, 0x01, 0x02, 0x04, 0x23, 0x01, 0x02, 0x08, 0x23, 0x01, 0x02, 0xf8, 0x04, 0x02, 0x02, + 0xfc, 0x04, 0x02, 0x02, 0x00, 0x05, 0x02, 0x02, 0x04, 0x05, 0x02, 0x02, 0x08, 0x05, 0x02, 0x02, 0xb8, 0x1f, 0x03, 0x03, 0xc0, 0x1f, 0x03, 0x03, 0xc8, 0x1f, 0x03, 0x03, 0x78, 0x02, 0x04, 0x03, + 0x80, 0x02, 0x04, 0x03, 0x10, 0x1c, 0x05, 0x04, 0x50, 0x00, 0x06, 0x04, 0xc0, 0x19, 0x07, 0x05, 0x80, 0x18, 0x09, 0x06, 0xf0, 0x35, 0x00, 0x03, 0xf8, 0x35, 0x00, 0x03, 0x00, 0x36, 0x00, 0x03, + 0x08, 0x36, 0x00, 0x03, 0x0c, 0x23, 0x01, 0x02, 0x10, 0x23, 0x01, 0x02, 0x14, 0x23, 0x01, 0x02, 0x18, 0x23, 0x01, 0x02, 0x1c, 0x23, 0x01, 0x02, 0x20, 0x23, 0x01, 0x02, 0x0c, 0x05, 0x02, 0x02, + 0x10, 0x05, 0x02, 0x02, 0x14, 0x05, 0x02, 0x02, 0x18, 0x05, 0x02, 0x02, 0x1c, 0x05, 0x02, 0x02, 0xd0, 0x1f, 0x03, 0x03, 0xd8, 0x1f, 0x03, 0x03, 0xe0, 0x1f, 0x03, 0x03, 0x88, 0x02, 0x04, 0x03, + 0x90, 0x02, 0x04, 0x03, 0x20, 0x1c, 0x05, 0x04, 0x60, 0x00, 0x06, 0x04, 0xe0, 0x19, 0x07, 0x05, 0xc0, 0x18, 0x09, 0x06, 0x10, 0x36, 0x00, 0x03, 0x18, 0x36, 0x00, 0x03, 0x20, 0x36, 0x00, 0x03, + 0x28, 0x36, 0x00, 0x03, 0x24, 0x23, 0x01, 0x02, 0x28, 0x23, 0x01, 0x02, 0x2c, 0x23, 0x01, 0x02, 0x30, 0x23, 0x01, 0x02, 0x34, 0x23, 0x01, 0x02, 0x38, 0x23, 0x01, 0x02, 0x20, 0x05, 0x02, 0x02, + 0x24, 0x05, 0x02, 0x02, 0x28, 0x05, 0x02, 0x02, 0x2c, 0x05, 0x02, 0x02, 0x30, 0x05, 0x02, 0x02, 0xe8, 0x1f, 0x03, 0x03, 0xf0, 0x1f, 0x03, 0x03, 0xf8, 0x1f, 0x03, 0x03, 0x98, 0x02, 0x04, 0x03, + 0xa0, 0x02, 0x04, 0x03, 0x30, 0x1c, 0x05, 0x04, 0x70, 0x00, 0x06, 0x04, 0x00, 0x1a, 0x07, 0x05, 0x00, 0x19, 0x09, 0x06, 0x30, 0x36, 0x00, 0x03, 0x38, 0x36, 0x00, 0x03, 0x40, 0x36, 0x00, 0x03, + 0x48, 0x36, 0x00, 0x03, 0x3c, 0x23, 0x01, 0x02, 0x40, 0x23, 0x01, 0x02, 0x44, 0x23, 0x01, 0x02, 0x48, 0x23, 0x01, 0x02, 0x4c, 0x23, 0x01, 0x02, 0x50, 0x23, 0x01, 0x02, 0x34, 0x05, 0x02, 0x02, + 0x38, 0x05, 0x02, 0x02, 0x3c, 0x05, 0x02, 0x02, 0x40, 0x05, 0x02, 0x02, 0x44, 0x05, 0x02, 0x02, 0x00, 0x20, 0x03, 0x03, 0x08, 0x20, 0x03, 0x03, 0x10, 0x20, 0x03, 0x03, 0xa8, 0x02, 0x04, 0x03, + 0xb0, 0x02, 0x04, 0x03, 0x40, 0x1c, 0x05, 0x04, 0x80, 0x00, 0x06, 0x04, 0x20, 0x1a, 0x07, 0x05, 0x40, 0x19, 0x09, 0x06, 0x50, 0x36, 0x00, 0x03, 0x58, 0x36, 0x00, 0x03, 0x60, 0x36, 0x00, 0x03, + 0x68, 0x36, 0x00, 0x03, 0x54, 0x23, 0x01, 0x02, 0x58, 0x23, 0x01, 0x02, 0x5c, 0x23, 0x01, 0x02, 0x60, 0x23, 0x01, 0x02, 0x64, 0x23, 0x01, 0x02, 0x68, 0x23, 0x01, 0x02, 0x48, 0x05, 0x02, 0x02, + 0x4c, 0x05, 0x02, 0x02, 0x50, 0x05, 0x02, 0x02, 0x54, 0x05, 0x02, 0x02, 0x58, 0x05, 0x02, 0x02, 0x18, 0x20, 0x03, 0x03, 0x20, 0x20, 0x03, 0x03, 0x28, 0x20, 0x03, 0x03, 0xb8, 0x02, 0x04, 0x03, + 0xc0, 0x02, 0x04, 0x03, 0x50, 0x1c, 0x05, 0x04, 0x90, 0x00, 0x06, 0x04, 0x40, 0x1a, 0x07, 0x05, 0x80, 0x19, 0x09, 0x06, 0x70, 0x36, 0x00, 0x03, 0x78, 0x36, 0x00, 0x03, 0x80, 0x36, 0x00, 0x03, + 0x88, 0x36, 0x00, 0x03, 0x6c, 0x23, 0x01, 0x02, 0x70, 0x23, 0x01, 0x02, 0x74, 0x23, 0x01, 0x02, 0x78, 0x23, 0x01, 0x02, 0x7c, 0x23, 0x01, 0x02, 0x80, 0x23, 0x01, 0x02, 0x5c, 0x05, 0x02, 0x02, + 0x60, 0x05, 0x02, 0x02, 0x64, 0x05, 0x02, 0x02, 0x68, 0x05, 0x02, 0x02, 0x6c, 0x05, 0x02, 0x02, 0x30, 0x20, 0x03, 0x03, 0x38, 0x20, 0x03, 0x03, 0x40, 0x20, 0x03, 0x03, 0xc8, 0x02, 0x04, 0x03, + 0xd0, 0x02, 0x04, 0x03, 0x60, 0x1c, 0x05, 0x04, 0xa0, 0x00, 0x06, 0x04, 0x60, 0x1a, 0x07, 0x05, 0xc0, 0x19, 0x09, 0x06, 0x90, 0x36, 0x00, 0x03, 0x98, 0x36, 0x00, 0x03, 0xa0, 0x36, 0x00, 0x03, + 0xa8, 0x36, 0x00, 0x03, 0x84, 0x23, 0x01, 0x02, 0x88, 0x23, 0x01, 0x02, 0x8c, 0x23, 0x01, 0x02, 0x90, 0x23, 0x01, 0x02, 0x94, 0x23, 0x01, 0x02, 0x98, 0x23, 0x01, 0x02, 0x70, 0x05, 0x02, 0x02, + 0x74, 0x05, 0x02, 0x02, 0x78, 0x05, 0x02, 0x02, 0x7c, 0x05, 0x02, 0x02, 0x80, 0x05, 0x02, 0x02, 0x48, 0x20, 0x03, 0x03, 0x50, 0x20, 0x03, 0x03, 0xd8, 0x02, 0x04, 0x03, 0xe0, 0x02, 0x04, 0x03, + 0xe8, 0x02, 0x04, 0x03, 0x70, 0x1c, 0x05, 0x04, 0xb0, 0x00, 0x06, 0x04, 0x80, 0x1a, 0x07, 0x05, 0x00, 0x1a, 0x09, 0x06, 0xb0, 0x36, 0x00, 0x03, 0xb8, 0x36, 0x00, 0x03, 0xc0, 0x36, 0x00, 0x03, + 0xc8, 0x36, 0x00, 0x03, 0x9c, 0x23, 0x01, 0x02, 0xa0, 0x23, 0x01, 0x02, 0xa4, 0x23, 0x01, 0x02, 0xa8, 0x23, 0x01, 0x02, 0xac, 0x23, 0x01, 0x02, 0xb0, 0x23, 0x01, 0x02, 0x84, 0x05, 0x02, 0x02, + 0x88, 0x05, 0x02, 0x02, 0x8c, 0x05, 0x02, 0x02, 0x90, 0x05, 0x02, 0x02, 0x58, 0x20, 0x03, 0x03, 0x60, 0x20, 0x03, 0x03, 0x68, 0x20, 0x03, 0x03, 0xf0, 0x02, 0x04, 0x03, 0xf8, 0x02, 0x04, 0x03, + 0x00, 0x03, 0x04, 0x03, 0x80, 0x1c, 0x05, 0x04, 0xc0, 0x00, 0x06, 0x04, 0xa0, 0x1a, 0x07, 0x05, 0x40, 0x1a, 0x09, 0x06, 0xd0, 0x36, 0x00, 0x03, 0xd8, 0x36, 0x00, 0x03, 0xe0, 0x36, 0x00, 0x03, + 0xe8, 0x36, 0x00, 0x03, 0xb4, 0x23, 0x01, 0x02, 0xb8, 0x23, 0x01, 0x02, 0xbc, 0x23, 0x01, 0x02, 0xc0, 0x23, 0x01, 0x02, 0xc4, 0x23, 0x01, 0x02, 0xc8, 0x23, 0x01, 0x02, 0x94, 0x05, 0x02, 0x02, + 0x98, 0x05, 0x02, 0x02, 0x9c, 0x05, 0x02, 0x02, 0xa0, 0x05, 0x02, 0x02, 0x70, 0x20, 0x03, 0x03, 0x78, 0x20, 0x03, 0x03, 0x80, 0x20, 0x03, 0x03, 0x08, 0x03, 0x04, 0x03, 0x10, 0x03, 0x04, 0x03, + 0x18, 0x03, 0x04, 0x03, 0x90, 0x1c, 0x05, 0x04, 0xd0, 0x00, 0x06, 0x04, 0xc0, 0x1a, 0x07, 0x05, 0x80, 0x1a, 0x09, 0x06, 0xf0, 0x36, 0x00, 0x03, 0xf8, 0x36, 0x00, 0x03, 0x00, 0x37, 0x00, 0x03, + 0x08, 0x37, 0x00, 0x03, 0xcc, 0x23, 0x01, 0x02, 0xd0, 0x23, 0x01, 0x02, 0xd4, 0x23, 0x01, 0x02, 0xd8, 0x23, 0x01, 0x02, 0xdc, 0x23, 0x01, 0x02, 0xe0, 0x23, 0x01, 0x02, 0xa4, 0x05, 0x02, 0x02, + 0xa8, 0x05, 0x02, 0x02, 0xac, 0x05, 0x02, 0x02, 0xb0, 0x05, 0x02, 0x02, 0x88, 0x20, 0x03, 0x03, 0x90, 0x20, 0x03, 0x03, 0x98, 0x20, 0x03, 0x03, 0x20, 0x03, 0x04, 0x03, 0x28, 0x03, 0x04, 0x03, + 0x30, 0x03, 0x04, 0x03, 0xa0, 0x1c, 0x05, 0x04, 0xe0, 0x00, 0x06, 0x04, 0xe0, 0x1a, 0x07, 0x05, 0xc0, 0x1a, 0x09, 0x06, 0x10, 0x37, 0x00, 0x03, 0x18, 0x37, 0x00, 0x03, 0x20, 0x37, 0x00, 0x03, + 0x28, 0x37, 0x00, 0x03, 0xe4, 0x23, 0x01, 0x02, 0xe8, 0x23, 0x01, 0x02, 0xec, 0x23, 0x01, 0x02, 0xf0, 0x23, 0x01, 0x02, 0xf4, 0x23, 0x01, 0x02, 0xf8, 0x23, 0x01, 0x02, 0xb4, 0x05, 0x02, 0x02, + 0xb8, 0x05, 0x02, 0x02, 0xbc, 0x05, 0x02, 0x02, 0xc0, 0x05, 0x02, 0x02, 0xa0, 0x20, 0x03, 0x03, 0xa8, 0x20, 0x03, 0x03, 0xb0, 0x20, 0x03, 0x03, 0x38, 0x03, 0x04, 0x03, 0x40, 0x03, 0x04, 0x03, + 0x48, 0x03, 0x04, 0x03, 0xb0, 0x1c, 0x05, 0x04, 0xf0, 0x00, 0x06, 0x04, 0x00, 0x1b, 0x07, 0x05, 0x00, 0x1b, 0x09, 0x06, 0x30, 0x37, 0x00, 0x03, 0x38, 0x37, 0x00, 0x03, 0x40, 0x37, 0x00, 0x03, + 0x48, 0x37, 0x00, 0x03, 0xfc, 0x23, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x04, 0x24, 0x01, 0x02, 0x08, 0x24, 0x01, 0x02, 0x0c, 0x24, 0x01, 0x02, 0x10, 0x24, 0x01, 0x02, 0xc4, 0x05, 0x02, 0x02, + 0xc8, 0x05, 0x02, 0x02, 0xcc, 0x05, 0x02, 0x02, 0xd0, 0x05, 0x02, 0x02, 0xb8, 0x20, 0x03, 0x03, 0xc0, 0x20, 0x03, 0x03, 0xc8, 0x20, 0x03, 0x03, 0x50, 0x03, 0x04, 0x03, 0x58, 0x03, 0x04, 0x03, + 0x60, 0x03, 0x04, 0x03, 0xc0, 0x1c, 0x05, 0x04, 0x00, 0x01, 0x06, 0x04, 0x20, 0x1b, 0x07, 0x05, 0x80, 0x36, 0x0a, 0x07, 0x50, 0x37, 0x00, 0x03, 0x58, 0x37, 0x00, 0x03, 0x60, 0x37, 0x00, 0x03, + 0x68, 0x37, 0x00, 0x03, 0x14, 0x24, 0x01, 0x02, 0x18, 0x24, 0x01, 0x02, 0x1c, 0x24, 0x01, 0x02, 0x20, 0x24, 0x01, 0x02, 0x24, 0x24, 0x01, 0x02, 0x28, 0x24, 0x01, 0x02, 0xd4, 0x05, 0x02, 0x02, + 0xd8, 0x05, 0x02, 0x02, 0xdc, 0x05, 0x02, 0x02, 0xe0, 0x05, 0x02, 0x02, 0xd0, 0x20, 0x03, 0x03, 0xd8, 0x20, 0x03, 0x03, 0xe0, 0x20, 0x03, 0x03, 0x68, 0x03, 0x04, 0x03, 0x70, 0x03, 0x04, 0x03, + 0x78, 0x03, 0x04, 0x03, 0xd0, 0x1c, 0x05, 0x04, 0x10, 0x01, 0x06, 0x04, 0x40, 0x1b, 0x07, 0x05, 0x00, 0x37, 0x0a, 0x07, 0x70, 0x37, 0x00, 0x03, 0x78, 0x37, 0x00, 0x03, 0x80, 0x37, 0x00, 0x03, + 0x88, 0x37, 0x00, 0x03, 0x2c, 0x24, 0x01, 0x02, 0x30, 0x24, 0x01, 0x02, 0x34, 0x24, 0x01, 0x02, 0x38, 0x24, 0x01, 0x02, 0x3c, 0x24, 0x01, 0x02, 0x40, 0x24, 0x01, 0x02, 0xe4, 0x05, 0x02, 0x02, + 0xe8, 0x05, 0x02, 0x02, 0xec, 0x05, 0x02, 0x02, 0xf0, 0x05, 0x02, 0x02, 0xe8, 0x20, 0x03, 0x03, 0xf0, 0x20, 0x03, 0x03, 0xf8, 0x20, 0x03, 0x03, 0x80, 0x03, 0x04, 0x03, 0x88, 0x03, 0x04, 0x03, + 0xe0, 0x1c, 0x05, 0x04, 0xf0, 0x1c, 0x05, 0x04, 0x20, 0x01, 0x06, 0x04, 0x60, 0x1b, 0x07, 0x05, 0x80, 0x37, 0x0a, 0x07, 0x90, 0x37, 0x00, 0x03, 0x98, 0x37, 0x00, 0x03, 0xa0, 0x37, 0x00, 0x03, + 0xa8, 0x37, 0x00, 0x03, 0x44, 0x24, 0x01, 0x02, 0x48, 0x24, 0x01, 0x02, 0x4c, 0x24, 0x01, 0x02, 0x50, 0x24, 0x01, 0x02, 0x54, 0x24, 0x01, 0x02, 0x58, 0x24, 0x01, 0x02, 0xf4, 0x05, 0x02, 0x02, + 0xf8, 0x05, 0x02, 0x02, 0xfc, 0x05, 0x02, 0x02, 0x00, 0x06, 0x02, 0x02, 0x00, 0x21, 0x03, 0x03, 0x08, 0x21, 0x03, 0x03, 0x10, 0x21, 0x03, 0x03, 0x90, 0x03, 0x04, 0x03, 0x98, 0x03, 0x04, 0x03, + 0x00, 0x1d, 0x05, 0x04, 0x10, 0x1d, 0x05, 0x04, 0x30, 0x01, 0x06, 0x04, 0x80, 0x1b, 0x07, 0x05, 0x00, 0x38, 0x0a, 0x07, 0xb0, 0x37, 0x00, 0x03, 0xb8, 0x37, 0x00, 0x03, 0xc0, 0x37, 0x00, 0x03, + 0xc8, 0x37, 0x00, 0x03, 0x5c, 0x24, 0x01, 0x02, 0x60, 0x24, 0x01, 0x02, 0x64, 0x24, 0x01, 0x02, 0x68, 0x24, 0x01, 0x02, 0x6c, 0x24, 0x01, 0x02, 0x70, 0x24, 0x01, 0x02, 0x04, 0x06, 0x02, 0x02, + 0x08, 0x06, 0x02, 0x02, 0x0c, 0x06, 0x02, 0x02, 0x10, 0x06, 0x02, 0x02, 0x18, 0x21, 0x03, 0x03, 0x20, 0x21, 0x03, 0x03, 0x28, 0x21, 0x03, 0x03, 0xa0, 0x03, 0x04, 0x03, 0xa8, 0x03, 0x04, 0x03, + 0x20, 0x1d, 0x05, 0x04, 0x30, 0x1d, 0x05, 0x04, 0x40, 0x01, 0x06, 0x04, 0xa0, 0x1b, 0x07, 0x05, 0x80, 0x38, 0x0a, 0x07, 0xd0, 0x37, 0x00, 0x03, 0xd8, 0x37, 0x00, 0x03, 0xe0, 0x37, 0x00, 0x03, + 0xe8, 0x37, 0x00, 0x03, 0x74, 0x24, 0x01, 0x02, 0x78, 0x24, 0x01, 0x02, 0x7c, 0x24, 0x01, 0x02, 0x80, 0x24, 0x01, 0x02, 0x84, 0x24, 0x01, 0x02, 0x88, 0x24, 0x01, 0x02, 0x14, 0x06, 0x02, 0x02, + 0x18, 0x06, 0x02, 0x02, 0x1c, 0x06, 0x02, 0x02, 0x20, 0x06, 0x02, 0x02, 0x30, 0x21, 0x03, 0x03, 0x38, 0x21, 0x03, 0x03, 0x40, 0x21, 0x03, 0x03, 0xb0, 0x03, 0x04, 0x03, 0xb8, 0x03, 0x04, 0x03, + 0x40, 0x1d, 0x05, 0x04, 0x50, 0x1d, 0x05, 0x04, 0x50, 0x01, 0x06, 0x04, 0xc0, 0x1b, 0x07, 0x05, 0x00, 0x39, 0x0a, 0x07, 0xf0, 0x37, 0x00, 0x03, 0xf8, 0x37, 0x00, 0x03, 0x00, 0x38, 0x00, 0x03, + 0x08, 0x38, 0x00, 0x03, 0x8c, 0x24, 0x01, 0x02, 0x90, 0x24, 0x01, 0x02, 0x94, 0x24, 0x01, 0x02, 0x98, 0x24, 0x01, 0x02, 0x9c, 0x24, 0x01, 0x02, 0xa0, 0x24, 0x01, 0x02, 0x24, 0x06, 0x02, 0x02, + 0x28, 0x06, 0x02, 0x02, 0x2c, 0x06, 0x02, 0x02, 0x30, 0x06, 0x02, 0x02, 0x48, 0x21, 0x03, 0x03, 0x50, 0x21, 0x03, 0x03, 0x58, 0x21, 0x03, 0x03, 0xc0, 0x03, 0x04, 0x03, 0xc8, 0x03, 0x04, 0x03, + 0x60, 0x1d, 0x05, 0x04, 0x70, 0x1d, 0x05, 0x04, 0x60, 0x01, 0x06, 0x04, 0xe0, 0x1b, 0x07, 0x05, 0x80, 0x39, 0x0a, 0x07, 0x10, 0x38, 0x00, 0x03, 0x18, 0x38, 0x00, 0x03, 0x20, 0x38, 0x00, 0x03, + 0x28, 0x38, 0x00, 0x03, 0xa4, 0x24, 0x01, 0x02, 0xa8, 0x24, 0x01, 0x02, 0xac, 0x24, 0x01, 0x02, 0xb0, 0x24, 0x01, 0x02, 0xb4, 0x24, 0x01, 0x02, 0xb8, 0x24, 0x01, 0x02, 0x34, 0x06, 0x02, 0x02, + 0x38, 0x06, 0x02, 0x02, 0x3c, 0x06, 0x02, 0x02, 0x40, 0x06, 0x02, 0x02, 0x60, 0x21, 0x03, 0x03, 0x68, 0x21, 0x03, 0x03, 0x70, 0x21, 0x03, 0x03, 0xd0, 0x03, 0x04, 0x03, 0xd8, 0x03, 0x04, 0x03, + 0x80, 0x1d, 0x05, 0x04, 0x90, 0x1d, 0x05, 0x04, 0x70, 0x01, 0x06, 0x04, 0x00, 0x1c, 0x07, 0x05, 0x00, 0x3a, 0x0a, 0x07, 0x30, 0x38, 0x00, 0x03, 0x38, 0x38, 0x00, 0x03, 0x40, 0x38, 0x00, 0x03, + 0x48, 0x38, 0x00, 0x03, 0xbc, 0x24, 0x01, 0x02, 0xc0, 0x24, 0x01, 0x02, 0xc4, 0x24, 0x01, 0x02, 0xc8, 0x24, 0x01, 0x02, 0xcc, 0x24, 0x01, 0x02, 0xd0, 0x24, 0x01, 0x02, 0x44, 0x06, 0x02, 0x02, + 0x48, 0x06, 0x02, 0x02, 0x4c, 0x06, 0x02, 0x02, 0x50, 0x06, 0x02, 0x02, 0x78, 0x21, 0x03, 0x03, 0x80, 0x21, 0x03, 0x03, 0x88, 0x21, 0x03, 0x03, 0xe0, 0x03, 0x04, 0x03, 0xe8, 0x03, 0x04, 0x03, + 0xa0, 0x1d, 0x05, 0x04, 0xb0, 0x1d, 0x05, 0x04, 0x80, 0x01, 0x06, 0x04, 0x20, 0x1c, 0x07, 0x05, 0x80, 0x3a, 0x0a, 0x07, 0x50, 0x38, 0x00, 0x03, 0x58, 0x38, 0x00, 0x03, 0x60, 0x38, 0x00, 0x03, + 0x68, 0x38, 0x00, 0x03, 0xd4, 0x24, 0x01, 0x02, 0xd8, 0x24, 0x01, 0x02, 0xdc, 0x24, 0x01, 0x02, 0xe0, 0x24, 0x01, 0x02, 0xe4, 0x24, 0x01, 0x02, 0xe8, 0x24, 0x01, 0x02, 0x54, 0x06, 0x02, 0x02, + 0x58, 0x06, 0x02, 0x02, 0x5c, 0x06, 0x02, 0x02, 0x60, 0x06, 0x02, 0x02, 0x90, 0x21, 0x03, 0x03, 0x98, 0x21, 0x03, 0x03, 0xa0, 0x21, 0x03, 0x03, 0xf0, 0x03, 0x04, 0x03, 0xf8, 0x03, 0x04, 0x03, + 0xc0, 0x1d, 0x05, 0x04, 0xd0, 0x1d, 0x05, 0x04, 0x90, 0x01, 0x06, 0x04, 0x40, 0x1c, 0x07, 0x05, 0x00, 0x3b, 0x0a, 0x07, 0x70, 0x38, 0x00, 0x03, 0x78, 0x38, 0x00, 0x03, 0x80, 0x38, 0x00, 0x03, + 0x88, 0x38, 0x00, 0x03, 0xec, 0x24, 0x01, 0x02, 0xf0, 0x24, 0x01, 0x02, 0xf4, 0x24, 0x01, 0x02, 0xf8, 0x24, 0x01, 0x02, 0xfc, 0x24, 0x01, 0x02, 0x00, 0x25, 0x01, 0x02, 0x64, 0x06, 0x02, 0x02, + 0x68, 0x06, 0x02, 0x02, 0x6c, 0x06, 0x02, 0x02, 0x70, 0x06, 0x02, 0x02, 0xa8, 0x21, 0x03, 0x03, 0xb0, 0x21, 0x03, 0x03, 0xb8, 0x21, 0x03, 0x03, 0x00, 0x04, 0x04, 0x03, 0x08, 0x04, 0x04, 0x03, + 0xe0, 0x1d, 0x05, 0x04, 0xf0, 0x1d, 0x05, 0x04, 0xa0, 0x01, 0x06, 0x04, 0x60, 0x1c, 0x07, 0x05, 0x80, 0x3b, 0x0a, 0x07, 0x90, 0x38, 0x00, 0x03, 0x98, 0x38, 0x00, 0x03, 0xa0, 0x38, 0x00, 0x03, + 0xa8, 0x38, 0x00, 0x03, 0x04, 0x25, 0x01, 0x02, 0x08, 0x25, 0x01, 0x02, 0x0c, 0x25, 0x01, 0x02, 0x10, 0x25, 0x01, 0x02, 0x14, 0x25, 0x01, 0x02, 0x18, 0x25, 0x01, 0x02, 0x74, 0x06, 0x02, 0x02, + 0x78, 0x06, 0x02, 0x02, 0x7c, 0x06, 0x02, 0x02, 0x80, 0x06, 0x02, 0x02, 0xc0, 0x21, 0x03, 0x03, 0xc8, 0x21, 0x03, 0x03, 0xd0, 0x21, 0x03, 0x03, 0x10, 0x04, 0x04, 0x03, 0x18, 0x04, 0x04, 0x03, + 0x00, 0x1e, 0x05, 0x04, 0x10, 0x1e, 0x05, 0x04, 0xb0, 0x01, 0x06, 0x04, 0x80, 0x1c, 0x07, 0x05, 0x00, 0x3c, 0x0a, 0x07, 0xb0, 0x38, 0x00, 0x03, 0xb8, 0x38, 0x00, 0x03, 0xc0, 0x38, 0x00, 0x03, + 0xc8, 0x38, 0x00, 0x03, 0x1c, 0x25, 0x01, 0x02, 0x20, 0x25, 0x01, 0x02, 0x24, 0x25, 0x01, 0x02, 0x28, 0x25, 0x01, 0x02, 0x2c, 0x25, 0x01, 0x02, 0x30, 0x25, 0x01, 0x02, 0x84, 0x06, 0x02, 0x02, + 0x88, 0x06, 0x02, 0x02, 0x8c, 0x06, 0x02, 0x02, 0x90, 0x06, 0x02, 0x02, 0xd8, 0x21, 0x03, 0x03, 0xe0, 0x21, 0x03, 0x03, 0xe8, 0x21, 0x03, 0x03, 0x20, 0x04, 0x04, 0x03, 0x28, 0x04, 0x04, 0x03, + 0x20, 0x1e, 0x05, 0x04, 0x30, 0x1e, 0x05, 0x04, 0xc0, 0x01, 0x06, 0x04, 0xa0, 0x1c, 0x07, 0x05, 0x80, 0x3c, 0x0a, 0x07, 0xd0, 0x38, 0x00, 0x03, 0xd8, 0x38, 0x00, 0x03, 0xe0, 0x38, 0x00, 0x03, + 0xe8, 0x38, 0x00, 0x03, 0x34, 0x25, 0x01, 0x02, 0x38, 0x25, 0x01, 0x02, 0x3c, 0x25, 0x01, 0x02, 0x40, 0x25, 0x01, 0x02, 0x44, 0x25, 0x01, 0x02, 0x48, 0x25, 0x01, 0x02, 0x94, 0x06, 0x02, 0x02, + 0x98, 0x06, 0x02, 0x02, 0x9c, 0x06, 0x02, 0x02, 0xa0, 0x06, 0x02, 0x02, 0xf0, 0x21, 0x03, 0x03, 0xf8, 0x21, 0x03, 0x03, 0x00, 0x22, 0x03, 0x03, 0x30, 0x04, 0x04, 0x03, 0x38, 0x04, 0x04, 0x03, + 0x40, 0x1e, 0x05, 0x04, 0x50, 0x1e, 0x05, 0x04, 0xd0, 0x01, 0x06, 0x04, 0xc0, 0x1c, 0x07, 0x05, 0x00, 0x3d, 0x0a, 0x07, 0xf0, 0x38, 0x00, 0x03, 0xf8, 0x38, 0x00, 0x03, 0x00, 0x39, 0x00, 0x03, + 0x08, 0x39, 0x00, 0x03, 0x4c, 0x25, 0x01, 0x02, 0x50, 0x25, 0x01, 0x02, 0x54, 0x25, 0x01, 0x02, 0x58, 0x25, 0x01, 0x02, 0x5c, 0x25, 0x01, 0x02, 0x60, 0x25, 0x01, 0x02, 0xa4, 0x06, 0x02, 0x02, + 0xa8, 0x06, 0x02, 0x02, 0xac, 0x06, 0x02, 0x02, 0xb0, 0x06, 0x02, 0x02, 0x08, 0x22, 0x03, 0x03, 0x10, 0x22, 0x03, 0x03, 0x18, 0x22, 0x03, 0x03, 0x40, 0x04, 0x04, 0x03, 0x48, 0x04, 0x04, 0x03, + 0x60, 0x1e, 0x05, 0x04, 0x70, 0x1e, 0x05, 0x04, 0xe0, 0x01, 0x06, 0x04, 0xe0, 0x1c, 0x07, 0x05, 0x80, 0x3d, 0x0a, 0x07, 0x10, 0x39, 0x00, 0x03, 0x18, 0x39, 0x00, 0x03, 0x20, 0x39, 0x00, 0x03, + 0x28, 0x39, 0x00, 0x03, 0x64, 0x25, 0x01, 0x02, 0x68, 0x25, 0x01, 0x02, 0x6c, 0x25, 0x01, 0x02, 0x70, 0x25, 0x01, 0x02, 0x74, 0x25, 0x01, 0x02, 0x78, 0x25, 0x01, 0x02, 0xb4, 0x06, 0x02, 0x02, + 0xb8, 0x06, 0x02, 0x02, 0xbc, 0x06, 0x02, 0x02, 0xc0, 0x06, 0x02, 0x02, 0x20, 0x22, 0x03, 0x03, 0x28, 0x22, 0x03, 0x03, 0x30, 0x22, 0x03, 0x03, 0x50, 0x04, 0x04, 0x03, 0x58, 0x04, 0x04, 0x03, + 0x80, 0x1e, 0x05, 0x04, 0x90, 0x1e, 0x05, 0x04, 0xf0, 0x01, 0x06, 0x04, 0xc0, 0x3a, 0x08, 0x06, 0x00, 0x3e, 0x0a, 0x07, 0x30, 0x39, 0x00, 0x03, 0x38, 0x39, 0x00, 0x03, 0x40, 0x39, 0x00, 0x03, + 0x48, 0x39, 0x00, 0x03, 0x7c, 0x25, 0x01, 0x02, 0x80, 0x25, 0x01, 0x02, 0x84, 0x25, 0x01, 0x02, 0x88, 0x25, 0x01, 0x02, 0x8c, 0x25, 0x01, 0x02, 0x90, 0x25, 0x01, 0x02, 0xc4, 0x06, 0x02, 0x02, + 0xc8, 0x06, 0x02, 0x02, 0xcc, 0x06, 0x02, 0x02, 0xd0, 0x06, 0x02, 0x02, 0x38, 0x22, 0x03, 0x03, 0x40, 0x22, 0x03, 0x03, 0x48, 0x22, 0x03, 0x03, 0x60, 0x04, 0x04, 0x03, 0x68, 0x04, 0x04, 0x03, + 0xa0, 0x1e, 0x05, 0x04, 0xb0, 0x1e, 0x05, 0x04, 0x00, 0x02, 0x06, 0x04, 0x00, 0x3b, 0x08, 0x06, 0x80, 0x3e, 0x0a, 0x07, 0x50, 0x39, 0x00, 0x03, 0x58, 0x39, 0x00, 0x03, 0x60, 0x39, 0x00, 0x03, + 0x68, 0x39, 0x00, 0x03, 0x94, 0x25, 0x01, 0x02, 0x98, 0x25, 0x01, 0x02, 0x9c, 0x25, 0x01, 0x02, 0xa0, 0x25, 0x01, 0x02, 0xa4, 0x25, 0x01, 0x02, 0xa8, 0x25, 0x01, 0x02, 0xd4, 0x06, 0x02, 0x02, + 0xd8, 0x06, 0x02, 0x02, 0xdc, 0x06, 0x02, 0x02, 0xe0, 0x06, 0x02, 0x02, 0x50, 0x22, 0x03, 0x03, 0x58, 0x22, 0x03, 0x03, 0x60, 0x22, 0x03, 0x03, 0x70, 0x04, 0x04, 0x03, 0x78, 0x04, 0x04, 0x03, + 0xc0, 0x1e, 0x05, 0x04, 0xd0, 0x1e, 0x05, 0x04, 0x10, 0x02, 0x06, 0x04, 0x40, 0x3b, 0x08, 0x06, 0x00, 0x3f, 0x0a, 0x07, 0x70, 0x39, 0x00, 0x03, 0x78, 0x39, 0x00, 0x03, 0x80, 0x39, 0x00, 0x03, + 0x88, 0x39, 0x00, 0x03, 0xac, 0x25, 0x01, 0x02, 0xb0, 0x25, 0x01, 0x02, 0xb4, 0x25, 0x01, 0x02, 0xb8, 0x25, 0x01, 0x02, 0xbc, 0x25, 0x01, 0x02, 0xc0, 0x25, 0x01, 0x02, 0xe4, 0x06, 0x02, 0x02, + 0xe8, 0x06, 0x02, 0x02, 0xec, 0x06, 0x02, 0x02, 0xf0, 0x06, 0x02, 0x02, 0x68, 0x22, 0x03, 0x03, 0x70, 0x22, 0x03, 0x03, 0x78, 0x22, 0x03, 0x03, 0x80, 0x04, 0x04, 0x03, 0x88, 0x04, 0x04, 0x03, + 0xe0, 0x1e, 0x05, 0x04, 0xf0, 0x1e, 0x05, 0x04, 0x20, 0x02, 0x06, 0x04, 0x80, 0x3b, 0x08, 0x06, 0x80, 0x3f, 0x0a, 0x07, 0x90, 0x39, 0x00, 0x03, 0x98, 0x39, 0x00, 0x03, 0xa0, 0x39, 0x00, 0x03, + 0xa8, 0x39, 0x00, 0x03, 0xc4, 0x25, 0x01, 0x02, 0xc8, 0x25, 0x01, 0x02, 0xcc, 0x25, 0x01, 0x02, 0xd0, 0x25, 0x01, 0x02, 0xd4, 0x25, 0x01, 0x02, 0xd8, 0x25, 0x01, 0x02, 0xf4, 0x06, 0x02, 0x02, + 0xf8, 0x06, 0x02, 0x02, 0xfc, 0x06, 0x02, 0x02, 0x00, 0x07, 0x02, 0x02, 0x80, 0x22, 0x03, 0x03, 0x88, 0x22, 0x03, 0x03, 0x90, 0x22, 0x03, 0x03, 0x90, 0x04, 0x04, 0x03, 0x98, 0x04, 0x04, 0x03, + 0x00, 0x1f, 0x05, 0x04, 0x10, 0x1f, 0x05, 0x04, 0x30, 0x02, 0x06, 0x04, 0xc0, 0x3b, 0x08, 0x06, 0x00, 0x00, 0x0a, 0x06, 0xb0, 0x39, 0x00, 0x03, 0xb8, 0x39, 0x00, 0x03, 0xc0, 0x39, 0x00, 0x03, + 0xc8, 0x39, 0x00, 0x03, 0xdc, 0x25, 0x01, 0x02, 0xe0, 0x25, 0x01, 0x02, 0xe4, 0x25, 0x01, 0x02, 0xe8, 0x25, 0x01, 0x02, 0xec, 0x25, 0x01, 0x02, 0xf0, 0x25, 0x01, 0x02, 0x04, 0x07, 0x02, 0x02, + 0x08, 0x07, 0x02, 0x02, 0x0c, 0x07, 0x02, 0x02, 0x10, 0x07, 0x02, 0x02, 0x98, 0x22, 0x03, 0x03, 0xa0, 0x22, 0x03, 0x03, 0xa8, 0x22, 0x03, 0x03, 0xa0, 0x04, 0x04, 0x03, 0xa8, 0x04, 0x04, 0x03, + 0x20, 0x1f, 0x05, 0x04, 0x30, 0x1f, 0x05, 0x04, 0x40, 0x02, 0x06, 0x04, 0x00, 0x3c, 0x08, 0x06, 0x80, 0x12, 0x0b, 0x07, 0xd0, 0x39, 0x00, 0x03, 0xd8, 0x39, 0x00, 0x03, 0xe0, 0x39, 0x00, 0x03, + 0xe8, 0x39, 0x00, 0x03, 0xf4, 0x25, 0x01, 0x02, 0xf8, 0x25, 0x01, 0x02, 0xfc, 0x25, 0x01, 0x02, 0x00, 0x26, 0x01, 0x02, 0x04, 0x26, 0x01, 0x02, 0x08, 0x26, 0x01, 0x02, 0x14, 0x07, 0x02, 0x02, + 0x18, 0x07, 0x02, 0x02, 0x1c, 0x07, 0x02, 0x02, 0x20, 0x07, 0x02, 0x02, 0xb0, 0x22, 0x03, 0x03, 0xb8, 0x22, 0x03, 0x03, 0xc0, 0x22, 0x03, 0x03, 0xb0, 0x04, 0x04, 0x03, 0xb8, 0x04, 0x04, 0x03, + 0x40, 0x1f, 0x05, 0x04, 0x50, 0x1f, 0x05, 0x04, 0x50, 0x02, 0x06, 0x04, 0x40, 0x3c, 0x08, 0x06, 0x00, 0x13, 0x0b, 0x07, 0xf0, 0x39, 0x00, 0x03, 0xf8, 0x39, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x03, + 0x08, 0x3a, 0x00, 0x03, 0x0c, 0x26, 0x01, 0x02, 0x10, 0x26, 0x01, 0x02, 0x14, 0x26, 0x01, 0x02, 0x18, 0x26, 0x01, 0x02, 0x1c, 0x26, 0x01, 0x02, 0x20, 0x26, 0x01, 0x02, 0x24, 0x07, 0x02, 0x02, + 0x28, 0x07, 0x02, 0x02, 0x2c, 0x07, 0x02, 0x02, 0x30, 0x07, 0x02, 0x02, 0xc8, 0x22, 0x03, 0x03, 0xd0, 0x22, 0x03, 0x03, 0xd8, 0x22, 0x03, 0x03, 0xc0, 0x04, 0x04, 0x03, 0xc8, 0x04, 0x04, 0x03, + 0x60, 0x1f, 0x05, 0x04, 0x70, 0x1f, 0x05, 0x04, 0x60, 0x02, 0x06, 0x04, 0x80, 0x3c, 0x08, 0x06, 0x80, 0x13, 0x0b, 0x07, 0x10, 0x3a, 0x00, 0x03, 0x18, 0x3a, 0x00, 0x03, 0x20, 0x3a, 0x00, 0x03, + 0x28, 0x3a, 0x00, 0x03, 0x24, 0x26, 0x01, 0x02, 0x28, 0x26, 0x01, 0x02, 0x2c, 0x26, 0x01, 0x02, 0x30, 0x26, 0x01, 0x02, 0x34, 0x26, 0x01, 0x02, 0x38, 0x26, 0x01, 0x02, 0x34, 0x07, 0x02, 0x02, + 0x38, 0x07, 0x02, 0x02, 0x3c, 0x07, 0x02, 0x02, 0x40, 0x07, 0x02, 0x02, 0xe0, 0x22, 0x03, 0x03, 0xe8, 0x22, 0x03, 0x03, 0xf0, 0x22, 0x03, 0x03, 0xd0, 0x04, 0x04, 0x03, 0xd8, 0x04, 0x04, 0x03, + 0x80, 0x1f, 0x05, 0x04, 0x90, 0x1f, 0x05, 0x04, 0x70, 0x02, 0x06, 0x04, 0xc0, 0x3c, 0x08, 0x06, 0x00, 0x14, 0x0b, 0x07, 0x30, 0x3a, 0x00, 0x03, 0x38, 0x3a, 0x00, 0x03, 0x40, 0x3a, 0x00, 0x03, + 0x48, 0x3a, 0x00, 0x03, 0x3c, 0x26, 0x01, 0x02, 0x40, 0x26, 0x01, 0x02, 0x44, 0x26, 0x01, 0x02, 0x48, 0x26, 0x01, 0x02, 0x4c, 0x26, 0x01, 0x02, 0x50, 0x26, 0x01, 0x02, 0x44, 0x07, 0x02, 0x02, + 0x48, 0x07, 0x02, 0x02, 0x4c, 0x07, 0x02, 0x02, 0x50, 0x07, 0x02, 0x02, 0xf8, 0x22, 0x03, 0x03, 0x00, 0x23, 0x03, 0x03, 0x08, 0x23, 0x03, 0x03, 0xe0, 0x04, 0x04, 0x03, 0xe8, 0x04, 0x04, 0x03, + 0xa0, 0x1f, 0x05, 0x04, 0xb0, 0x1f, 0x05, 0x04, 0x80, 0x02, 0x06, 0x04, 0x00, 0x3d, 0x08, 0x06, 0x80, 0x14, 0x0b, 0x07, 0x50, 0x3a, 0x00, 0x03, 0x58, 0x3a, 0x00, 0x03, 0x60, 0x3a, 0x00, 0x03, + 0x68, 0x3a, 0x00, 0x03, 0x54, 0x26, 0x01, 0x02, 0x58, 0x26, 0x01, 0x02, 0x5c, 0x26, 0x01, 0x02, 0x60, 0x26, 0x01, 0x02, 0x64, 0x26, 0x01, 0x02, 0x68, 0x26, 0x01, 0x02, 0x54, 0x07, 0x02, 0x02, + 0x58, 0x07, 0x02, 0x02, 0x5c, 0x07, 0x02, 0x02, 0x60, 0x07, 0x02, 0x02, 0x10, 0x23, 0x03, 0x03, 0x18, 0x23, 0x03, 0x03, 0x20, 0x23, 0x03, 0x03, 0xf0, 0x04, 0x04, 0x03, 0xf8, 0x04, 0x04, 0x03, + 0xc0, 0x1f, 0x05, 0x04, 0xd0, 0x1f, 0x05, 0x04, 0x90, 0x02, 0x06, 0x04, 0x40, 0x3d, 0x08, 0x06, 0x00, 0x15, 0x0b, 0x07, 0x70, 0x3a, 0x00, 0x03, 0x78, 0x3a, 0x00, 0x03, 0x80, 0x3a, 0x00, 0x03, + 0x88, 0x3a, 0x00, 0x03, 0x6c, 0x26, 0x01, 0x02, 0x70, 0x26, 0x01, 0x02, 0x74, 0x26, 0x01, 0x02, 0x78, 0x26, 0x01, 0x02, 0x7c, 0x26, 0x01, 0x02, 0x80, 0x26, 0x01, 0x02, 0x64, 0x07, 0x02, 0x02, + 0x68, 0x07, 0x02, 0x02, 0x6c, 0x07, 0x02, 0x02, 0x70, 0x07, 0x02, 0x02, 0x28, 0x23, 0x03, 0x03, 0x30, 0x23, 0x03, 0x03, 0x38, 0x23, 0x03, 0x03, 0x00, 0x05, 0x04, 0x03, 0x08, 0x05, 0x04, 0x03, + 0xe0, 0x1f, 0x05, 0x04, 0xf0, 0x1f, 0x05, 0x04, 0xa0, 0x02, 0x06, 0x04, 0x80, 0x3d, 0x08, 0x06, 0x80, 0x15, 0x0b, 0x07, 0x90, 0x3a, 0x00, 0x03, 0x98, 0x3a, 0x00, 0x03, 0xa0, 0x3a, 0x00, 0x03, + 0xa8, 0x3a, 0x00, 0x03, 0x84, 0x26, 0x01, 0x02, 0x88, 0x26, 0x01, 0x02, 0x8c, 0x26, 0x01, 0x02, 0x90, 0x26, 0x01, 0x02, 0x94, 0x26, 0x01, 0x02, 0x98, 0x26, 0x01, 0x02, 0x74, 0x07, 0x02, 0x02, + 0x78, 0x07, 0x02, 0x02, 0x7c, 0x07, 0x02, 0x02, 0x80, 0x07, 0x02, 0x02, 0x40, 0x23, 0x03, 0x03, 0x48, 0x23, 0x03, 0x03, 0x50, 0x23, 0x03, 0x03, 0x10, 0x05, 0x04, 0x03, 0x18, 0x05, 0x04, 0x03, + 0x00, 0x20, 0x05, 0x04, 0x10, 0x20, 0x05, 0x04, 0xb0, 0x02, 0x06, 0x04, 0xc0, 0x3d, 0x08, 0x06, 0x00, 0x16, 0x0b, 0x07, 0xb0, 0x3a, 0x00, 0x03, 0xb8, 0x3a, 0x00, 0x03, 0xc0, 0x3a, 0x00, 0x03, + 0xc8, 0x3a, 0x00, 0x03, 0x9c, 0x26, 0x01, 0x02, 0xa0, 0x26, 0x01, 0x02, 0xa4, 0x26, 0x01, 0x02, 0xa8, 0x26, 0x01, 0x02, 0xac, 0x26, 0x01, 0x02, 0xb0, 0x26, 0x01, 0x02, 0x84, 0x07, 0x02, 0x02, + 0x88, 0x07, 0x02, 0x02, 0x8c, 0x07, 0x02, 0x02, 0x90, 0x07, 0x02, 0x02, 0x58, 0x23, 0x03, 0x03, 0x60, 0x23, 0x03, 0x03, 0x68, 0x23, 0x03, 0x03, 0x20, 0x05, 0x04, 0x03, 0x28, 0x05, 0x04, 0x03, + 0x20, 0x20, 0x05, 0x04, 0x30, 0x20, 0x05, 0x04, 0xc0, 0x02, 0x06, 0x04, 0x00, 0x3e, 0x08, 0x06, 0x80, 0x16, 0x0b, 0x07, 0xd0, 0x3a, 0x00, 0x03, 0xd8, 0x3a, 0x00, 0x03, 0xe0, 0x3a, 0x00, 0x03, + 0xe8, 0x3a, 0x00, 0x03, 0xb4, 0x26, 0x01, 0x02, 0xb8, 0x26, 0x01, 0x02, 0xbc, 0x26, 0x01, 0x02, 0xc0, 0x26, 0x01, 0x02, 0xc4, 0x26, 0x01, 0x02, 0xc8, 0x26, 0x01, 0x02, 0x94, 0x07, 0x02, 0x02, + 0x98, 0x07, 0x02, 0x02, 0x9c, 0x07, 0x02, 0x02, 0xa0, 0x07, 0x02, 0x02, 0x70, 0x23, 0x03, 0x03, 0x78, 0x23, 0x03, 0x03, 0x80, 0x23, 0x03, 0x03, 0x30, 0x05, 0x04, 0x03, 0x38, 0x05, 0x04, 0x03, + 0x40, 0x20, 0x05, 0x04, 0x50, 0x20, 0x05, 0x04, 0xd0, 0x02, 0x06, 0x04, 0x40, 0x3e, 0x08, 0x06, 0x00, 0x17, 0x0b, 0x07, 0xf0, 0x3a, 0x00, 0x03, 0xf8, 0x3a, 0x00, 0x03, 0x00, 0x3b, 0x00, 0x03, + 0x08, 0x3b, 0x00, 0x03, 0xcc, 0x26, 0x01, 0x02, 0xd0, 0x26, 0x01, 0x02, 0xd4, 0x26, 0x01, 0x02, 0xd8, 0x26, 0x01, 0x02, 0xdc, 0x26, 0x01, 0x02, 0xe0, 0x26, 0x01, 0x02, 0xa4, 0x07, 0x02, 0x02, + 0xa8, 0x07, 0x02, 0x02, 0xac, 0x07, 0x02, 0x02, 0xb0, 0x07, 0x02, 0x02, 0x88, 0x23, 0x03, 0x03, 0x90, 0x23, 0x03, 0x03, 0x98, 0x23, 0x03, 0x03, 0x40, 0x05, 0x04, 0x03, 0x48, 0x05, 0x04, 0x03, + 0x60, 0x20, 0x05, 0x04, 0x70, 0x20, 0x05, 0x04, 0xe0, 0x02, 0x06, 0x04, 0x80, 0x3e, 0x08, 0x06, 0x80, 0x17, 0x0b, 0x07, 0x10, 0x3b, 0x00, 0x03, 0x18, 0x3b, 0x00, 0x03, 0x20, 0x3b, 0x00, 0x03, + 0x28, 0x3b, 0x00, 0x03, 0xe4, 0x26, 0x01, 0x02, 0xe8, 0x26, 0x01, 0x02, 0xec, 0x26, 0x01, 0x02, 0xf0, 0x26, 0x01, 0x02, 0xf4, 0x26, 0x01, 0x02, 0xf8, 0x26, 0x01, 0x02, 0xb4, 0x07, 0x02, 0x02, + 0xb8, 0x07, 0x02, 0x02, 0xbc, 0x07, 0x02, 0x02, 0xc0, 0x07, 0x02, 0x02, 0xa0, 0x23, 0x03, 0x03, 0xa8, 0x23, 0x03, 0x03, 0xb0, 0x23, 0x03, 0x03, 0x50, 0x05, 0x04, 0x03, 0x58, 0x05, 0x04, 0x03, + 0x80, 0x20, 0x05, 0x04, 0x90, 0x20, 0x05, 0x04, 0xf0, 0x02, 0x06, 0x04, 0xc0, 0x3e, 0x08, 0x06, 0x00, 0x18, 0x0b, 0x07, 0x30, 0x3b, 0x00, 0x03, 0x38, 0x3b, 0x00, 0x03, 0x40, 0x3b, 0x00, 0x03, + 0x48, 0x3b, 0x00, 0x03, 0xfc, 0x26, 0x01, 0x02, 0x00, 0x27, 0x01, 0x02, 0x04, 0x27, 0x01, 0x02, 0x08, 0x27, 0x01, 0x02, 0x0c, 0x27, 0x01, 0x02, 0x10, 0x27, 0x01, 0x02, 0xc4, 0x07, 0x02, 0x02, + 0xc8, 0x07, 0x02, 0x02, 0xcc, 0x07, 0x02, 0x02, 0xd0, 0x07, 0x02, 0x02, 0xb8, 0x23, 0x03, 0x03, 0xc0, 0x23, 0x03, 0x03, 0xc8, 0x23, 0x03, 0x03, 0x60, 0x05, 0x04, 0x03, 0x68, 0x05, 0x04, 0x03, + 0xa0, 0x20, 0x05, 0x04, 0xb0, 0x20, 0x05, 0x04, 0x00, 0x03, 0x06, 0x04, 0x00, 0x3f, 0x08, 0x06, 0x80, 0x18, 0x0b, 0x07, 0x50, 0x3b, 0x00, 0x03, 0x58, 0x3b, 0x00, 0x03, 0x60, 0x3b, 0x00, 0x03, + 0x68, 0x3b, 0x00, 0x03, 0x14, 0x27, 0x01, 0x02, 0x18, 0x27, 0x01, 0x02, 0x1c, 0x27, 0x01, 0x02, 0x20, 0x27, 0x01, 0x02, 0x24, 0x27, 0x01, 0x02, 0x28, 0x27, 0x01, 0x02, 0xd4, 0x07, 0x02, 0x02, + 0xd8, 0x07, 0x02, 0x02, 0xdc, 0x07, 0x02, 0x02, 0xe0, 0x07, 0x02, 0x02, 0xd0, 0x23, 0x03, 0x03, 0xd8, 0x23, 0x03, 0x03, 0xe0, 0x23, 0x03, 0x03, 0x70, 0x05, 0x04, 0x03, 0x78, 0x05, 0x04, 0x03, + 0xc0, 0x20, 0x05, 0x04, 0xd0, 0x20, 0x05, 0x04, 0x10, 0x03, 0x06, 0x04, 0x40, 0x3f, 0x08, 0x06, 0x00, 0x32, 0x0c, 0x08, 0x70, 0x3b, 0x00, 0x03, 0x78, 0x3b, 0x00, 0x03, 0x80, 0x3b, 0x00, 0x03, + 0x88, 0x3b, 0x00, 0x03, 0x2c, 0x27, 0x01, 0x02, 0x30, 0x27, 0x01, 0x02, 0x34, 0x27, 0x01, 0x02, 0x38, 0x27, 0x01, 0x02, 0x3c, 0x27, 0x01, 0x02, 0x40, 0x27, 0x01, 0x02, 0xe4, 0x07, 0x02, 0x02, + 0xe8, 0x07, 0x02, 0x02, 0xec, 0x07, 0x02, 0x02, 0xf0, 0x07, 0x02, 0x02, 0xe8, 0x23, 0x03, 0x03, 0xf0, 0x23, 0x03, 0x03, 0xf8, 0x23, 0x03, 0x03, 0x80, 0x05, 0x04, 0x03, 0x88, 0x05, 0x04, 0x03, + 0xe0, 0x20, 0x05, 0x04, 0xf0, 0x20, 0x05, 0x04, 0x20, 0x03, 0x06, 0x04, 0x80, 0x3f, 0x08, 0x06, 0x00, 0x33, 0x0c, 0x08, 0x90, 0x3b, 0x00, 0x03, 0x98, 0x3b, 0x00, 0x03, 0xa0, 0x3b, 0x00, 0x03, + 0xa8, 0x3b, 0x00, 0x03, 0x44, 0x27, 0x01, 0x02, 0x48, 0x27, 0x01, 0x02, 0x4c, 0x27, 0x01, 0x02, 0x50, 0x27, 0x01, 0x02, 0x54, 0x27, 0x01, 0x02, 0x58, 0x27, 0x01, 0x02, 0xf4, 0x07, 0x02, 0x02, + 0xf8, 0x07, 0x02, 0x02, 0xfc, 0x07, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x00, 0x24, 0x03, 0x03, 0x08, 0x24, 0x03, 0x03, 0x10, 0x24, 0x03, 0x03, 0x90, 0x05, 0x04, 0x03, 0x98, 0x05, 0x04, 0x03, + 0x00, 0x21, 0x05, 0x04, 0x10, 0x21, 0x05, 0x04, 0x30, 0x03, 0x06, 0x04, 0xc0, 0x3f, 0x08, 0x06, 0x00, 0x34, 0x0c, 0x08, 0xb0, 0x3b, 0x00, 0x03, 0xb8, 0x3b, 0x00, 0x03, 0xc0, 0x3b, 0x00, 0x03, + 0xc8, 0x3b, 0x00, 0x03, 0x5c, 0x27, 0x01, 0x02, 0x60, 0x27, 0x01, 0x02, 0x64, 0x27, 0x01, 0x02, 0x68, 0x27, 0x01, 0x02, 0x6c, 0x27, 0x01, 0x02, 0x70, 0x27, 0x01, 0x02, 0x04, 0x08, 0x02, 0x02, + 0x08, 0x08, 0x02, 0x02, 0x0c, 0x08, 0x02, 0x02, 0x10, 0x08, 0x02, 0x02, 0x18, 0x24, 0x03, 0x03, 0x20, 0x24, 0x03, 0x03, 0x28, 0x24, 0x03, 0x03, 0xa0, 0x05, 0x04, 0x03, 0xa8, 0x05, 0x04, 0x03, + 0x20, 0x21, 0x05, 0x04, 0x30, 0x21, 0x05, 0x04, 0x40, 0x03, 0x06, 0x04, 0x00, 0x00, 0x08, 0x05, 0x00, 0x35, 0x0c, 0x08, 0xd0, 0x3b, 0x00, 0x03, 0xd8, 0x3b, 0x00, 0x03, 0xe0, 0x3b, 0x00, 0x03, + 0xe8, 0x3b, 0x00, 0x03, 0x74, 0x27, 0x01, 0x02, 0x78, 0x27, 0x01, 0x02, 0x7c, 0x27, 0x01, 0x02, 0x80, 0x27, 0x01, 0x02, 0x84, 0x27, 0x01, 0x02, 0x88, 0x27, 0x01, 0x02, 0x14, 0x08, 0x02, 0x02, + 0x18, 0x08, 0x02, 0x02, 0x1c, 0x08, 0x02, 0x02, 0x20, 0x08, 0x02, 0x02, 0x30, 0x24, 0x03, 0x03, 0x38, 0x24, 0x03, 0x03, 0x40, 0x24, 0x03, 0x03, 0xb0, 0x05, 0x04, 0x03, 0xb8, 0x05, 0x04, 0x03, + 0x40, 0x21, 0x05, 0x04, 0x50, 0x21, 0x05, 0x04, 0x50, 0x03, 0x06, 0x04, 0x20, 0x00, 0x08, 0x05, 0x00, 0x36, 0x0c, 0x08, 0xf0, 0x3b, 0x00, 0x03, 0xf8, 0x3b, 0x00, 0x03, 0x00, 0x3c, 0x00, 0x03, + 0x8c, 0x27, 0x01, 0x02, 0x90, 0x27, 0x01, 0x02, 0x94, 0x27, 0x01, 0x02, 0x98, 0x27, 0x01, 0x02, 0x9c, 0x27, 0x01, 0x02, 0xa0, 0x27, 0x01, 0x02, 0xa4, 0x27, 0x01, 0x02, 0x24, 0x08, 0x02, 0x02, + 0x28, 0x08, 0x02, 0x02, 0x2c, 0x08, 0x02, 0x02, 0x30, 0x08, 0x02, 0x02, 0x48, 0x24, 0x03, 0x03, 0x50, 0x24, 0x03, 0x03, 0x58, 0x24, 0x03, 0x03, 0xc0, 0x05, 0x04, 0x03, 0xc8, 0x05, 0x04, 0x03, + 0x60, 0x21, 0x05, 0x04, 0x70, 0x21, 0x05, 0x04, 0x60, 0x03, 0x06, 0x04, 0x40, 0x00, 0x08, 0x05, 0x00, 0x37, 0x0c, 0x08, 0x08, 0x3c, 0x00, 0x03, 0x10, 0x3c, 0x00, 0x03, 0x18, 0x3c, 0x00, 0x03, + 0xa8, 0x27, 0x01, 0x02, 0xac, 0x27, 0x01, 0x02, 0xb0, 0x27, 0x01, 0x02, 0xb4, 0x27, 0x01, 0x02, 0xb8, 0x27, 0x01, 0x02, 0xbc, 0x27, 0x01, 0x02, 0xc0, 0x27, 0x01, 0x02, 0x34, 0x08, 0x02, 0x02, + 0x38, 0x08, 0x02, 0x02, 0x3c, 0x08, 0x02, 0x02, 0x40, 0x08, 0x02, 0x02, 0x60, 0x24, 0x03, 0x03, 0x68, 0x24, 0x03, 0x03, 0x70, 0x24, 0x03, 0x03, 0xd0, 0x05, 0x04, 0x03, 0xd8, 0x05, 0x04, 0x03, + 0x80, 0x21, 0x05, 0x04, 0x90, 0x21, 0x05, 0x04, 0x70, 0x03, 0x06, 0x04, 0x60, 0x00, 0x08, 0x05, 0x00, 0x38, 0x0c, 0x08, 0x20, 0x3c, 0x00, 0x03, 0x28, 0x3c, 0x00, 0x03, 0x30, 0x3c, 0x00, 0x03, + 0xc4, 0x27, 0x01, 0x02, 0xc8, 0x27, 0x01, 0x02, 0xcc, 0x27, 0x01, 0x02, 0xd0, 0x27, 0x01, 0x02, 0xd4, 0x27, 0x01, 0x02, 0xd8, 0x27, 0x01, 0x02, 0xdc, 0x27, 0x01, 0x02, 0x44, 0x08, 0x02, 0x02, + 0x48, 0x08, 0x02, 0x02, 0x4c, 0x08, 0x02, 0x02, 0x50, 0x08, 0x02, 0x02, 0x78, 0x24, 0x03, 0x03, 0x80, 0x24, 0x03, 0x03, 0x88, 0x24, 0x03, 0x03, 0xe0, 0x05, 0x04, 0x03, 0xe8, 0x05, 0x04, 0x03, + 0xa0, 0x21, 0x05, 0x04, 0x80, 0x03, 0x06, 0x04, 0x00, 0x1d, 0x07, 0x05, 0x80, 0x00, 0x08, 0x05, 0x00, 0x39, 0x0c, 0x08, 0x38, 0x3c, 0x00, 0x03, 0x40, 0x3c, 0x00, 0x03, 0x48, 0x3c, 0x00, 0x03, + 0xe0, 0x27, 0x01, 0x02, 0xe4, 0x27, 0x01, 0x02, 0xe8, 0x27, 0x01, 0x02, 0xec, 0x27, 0x01, 0x02, 0xf0, 0x27, 0x01, 0x02, 0xf4, 0x27, 0x01, 0x02, 0xf8, 0x27, 0x01, 0x02, 0x54, 0x08, 0x02, 0x02, + 0x58, 0x08, 0x02, 0x02, 0x5c, 0x08, 0x02, 0x02, 0x60, 0x08, 0x02, 0x02, 0x90, 0x24, 0x03, 0x03, 0x98, 0x24, 0x03, 0x03, 0xa0, 0x24, 0x03, 0x03, 0xf0, 0x05, 0x04, 0x03, 0xf8, 0x05, 0x04, 0x03, + 0xb0, 0x21, 0x05, 0x04, 0x90, 0x03, 0x06, 0x04, 0x20, 0x1d, 0x07, 0x05, 0xa0, 0x00, 0x08, 0x05, 0x00, 0x3a, 0x0c, 0x08, 0x50, 0x3c, 0x00, 0x03, 0x58, 0x3c, 0x00, 0x03, 0x60, 0x3c, 0x00, 0x03, + 0xfc, 0x27, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x04, 0x28, 0x01, 0x02, 0x08, 0x28, 0x01, 0x02, 0x0c, 0x28, 0x01, 0x02, 0x10, 0x28, 0x01, 0x02, 0x14, 0x28, 0x01, 0x02, 0x64, 0x08, 0x02, 0x02, + 0x68, 0x08, 0x02, 0x02, 0x6c, 0x08, 0x02, 0x02, 0x70, 0x08, 0x02, 0x02, 0xa8, 0x24, 0x03, 0x03, 0xb0, 0x24, 0x03, 0x03, 0xb8, 0x24, 0x03, 0x03, 0x00, 0x06, 0x04, 0x03, 0x08, 0x06, 0x04, 0x03, + 0xc0, 0x21, 0x05, 0x04, 0xa0, 0x03, 0x06, 0x04, 0x40, 0x1d, 0x07, 0x05, 0xc0, 0x00, 0x08, 0x05, 0x00, 0x3b, 0x0c, 0x08, 0x68, 0x3c, 0x00, 0x03, 0x70, 0x3c, 0x00, 0x03, 0x78, 0x3c, 0x00, 0x03, + 0x18, 0x28, 0x01, 0x02, 0x1c, 0x28, 0x01, 0x02, 0x20, 0x28, 0x01, 0x02, 0x24, 0x28, 0x01, 0x02, 0x28, 0x28, 0x01, 0x02, 0x2c, 0x28, 0x01, 0x02, 0x30, 0x28, 0x01, 0x02, 0x74, 0x08, 0x02, 0x02, + 0x78, 0x08, 0x02, 0x02, 0x7c, 0x08, 0x02, 0x02, 0x80, 0x08, 0x02, 0x02, 0xc0, 0x24, 0x03, 0x03, 0xc8, 0x24, 0x03, 0x03, 0xd0, 0x24, 0x03, 0x03, 0x10, 0x06, 0x04, 0x03, 0x18, 0x06, 0x04, 0x03, + 0xd0, 0x21, 0x05, 0x04, 0xb0, 0x03, 0x06, 0x04, 0x60, 0x1d, 0x07, 0x05, 0xe0, 0x00, 0x08, 0x05, 0x00, 0x0f, 0x0d, 0x08, 0x80, 0x3c, 0x00, 0x03, 0x88, 0x3c, 0x00, 0x03, 0x90, 0x3c, 0x00, 0x03, + 0x34, 0x28, 0x01, 0x02, 0x38, 0x28, 0x01, 0x02, 0x3c, 0x28, 0x01, 0x02, 0x40, 0x28, 0x01, 0x02, 0x44, 0x28, 0x01, 0x02, 0x48, 0x28, 0x01, 0x02, 0x4c, 0x28, 0x01, 0x02, 0x84, 0x08, 0x02, 0x02, + 0x88, 0x08, 0x02, 0x02, 0x8c, 0x08, 0x02, 0x02, 0x90, 0x08, 0x02, 0x02, 0xd8, 0x24, 0x03, 0x03, 0xe0, 0x24, 0x03, 0x03, 0xe8, 0x24, 0x03, 0x03, 0x20, 0x06, 0x04, 0x03, 0x28, 0x06, 0x04, 0x03, + 0xe0, 0x21, 0x05, 0x04, 0xc0, 0x03, 0x06, 0x04, 0x80, 0x1d, 0x07, 0x05, 0x00, 0x01, 0x08, 0x05, 0x00, 0x10, 0x0d, 0x08, 0x98, 0x3c, 0x00, 0x03, 0xa0, 0x3c, 0x00, 0x03, 0xa8, 0x3c, 0x00, 0x03, + 0x50, 0x28, 0x01, 0x02, 0x54, 0x28, 0x01, 0x02, 0x58, 0x28, 0x01, 0x02, 0x5c, 0x28, 0x01, 0x02, 0x60, 0x28, 0x01, 0x02, 0x64, 0x28, 0x01, 0x02, 0x68, 0x28, 0x01, 0x02, 0x94, 0x08, 0x02, 0x02, + 0x98, 0x08, 0x02, 0x02, 0x9c, 0x08, 0x02, 0x02, 0xa0, 0x08, 0x02, 0x02, 0xf0, 0x24, 0x03, 0x03, 0xf8, 0x24, 0x03, 0x03, 0x00, 0x25, 0x03, 0x03, 0x30, 0x06, 0x04, 0x03, 0x38, 0x06, 0x04, 0x03, + 0xf0, 0x21, 0x05, 0x04, 0xd0, 0x03, 0x06, 0x04, 0xa0, 0x1d, 0x07, 0x05, 0x20, 0x01, 0x08, 0x05, 0x00, 0x11, 0x0d, 0x08, 0xb0, 0x3c, 0x00, 0x03, 0xb8, 0x3c, 0x00, 0x03, 0xc0, 0x3c, 0x00, 0x03, + 0x6c, 0x28, 0x01, 0x02, 0x70, 0x28, 0x01, 0x02, 0x74, 0x28, 0x01, 0x02, 0x78, 0x28, 0x01, 0x02, 0x7c, 0x28, 0x01, 0x02, 0x80, 0x28, 0x01, 0x02, 0x84, 0x28, 0x01, 0x02, 0xa4, 0x08, 0x02, 0x02, + 0xa8, 0x08, 0x02, 0x02, 0xac, 0x08, 0x02, 0x02, 0xb0, 0x08, 0x02, 0x02, 0x08, 0x25, 0x03, 0x03, 0x10, 0x25, 0x03, 0x03, 0x18, 0x25, 0x03, 0x03, 0x40, 0x06, 0x04, 0x03, 0x48, 0x06, 0x04, 0x03, + 0x00, 0x22, 0x05, 0x04, 0xe0, 0x03, 0x06, 0x04, 0xc0, 0x1d, 0x07, 0x05, 0x40, 0x01, 0x08, 0x05, 0x00, 0x12, 0x0d, 0x08, 0xc8, 0x3c, 0x00, 0x03, 0xd0, 0x3c, 0x00, 0x03, 0xd8, 0x3c, 0x00, 0x03, + 0x88, 0x28, 0x01, 0x02, 0x8c, 0x28, 0x01, 0x02, 0x90, 0x28, 0x01, 0x02, 0x94, 0x28, 0x01, 0x02, 0x98, 0x28, 0x01, 0x02, 0x9c, 0x28, 0x01, 0x02, 0xa0, 0x28, 0x01, 0x02, 0xb4, 0x08, 0x02, 0x02, + 0xb8, 0x08, 0x02, 0x02, 0xbc, 0x08, 0x02, 0x02, 0xc0, 0x08, 0x02, 0x02, 0x20, 0x25, 0x03, 0x03, 0x28, 0x25, 0x03, 0x03, 0x30, 0x25, 0x03, 0x03, 0x50, 0x06, 0x04, 0x03, 0x58, 0x06, 0x04, 0x03, + 0x10, 0x22, 0x05, 0x04, 0xf0, 0x03, 0x06, 0x04, 0xe0, 0x1d, 0x07, 0x05, 0x60, 0x01, 0x08, 0x05, 0x00, 0x13, 0x0d, 0x08, 0xe0, 0x3c, 0x00, 0x03, 0xe8, 0x3c, 0x00, 0x03, 0xf0, 0x3c, 0x00, 0x03, + 0xa4, 0x28, 0x01, 0x02, 0xa8, 0x28, 0x01, 0x02, 0xac, 0x28, 0x01, 0x02, 0xb0, 0x28, 0x01, 0x02, 0xb4, 0x28, 0x01, 0x02, 0xb8, 0x28, 0x01, 0x02, 0xbc, 0x28, 0x01, 0x02, 0xc4, 0x08, 0x02, 0x02, + 0xc8, 0x08, 0x02, 0x02, 0xcc, 0x08, 0x02, 0x02, 0xd0, 0x08, 0x02, 0x02, 0x38, 0x25, 0x03, 0x03, 0x40, 0x25, 0x03, 0x03, 0x48, 0x25, 0x03, 0x03, 0x60, 0x06, 0x04, 0x03, 0x68, 0x06, 0x04, 0x03, + 0x20, 0x22, 0x05, 0x04, 0x00, 0x04, 0x06, 0x04, 0x00, 0x1e, 0x07, 0x05, 0x80, 0x01, 0x08, 0x05, 0x00, 0x14, 0x0d, 0x08, 0xf8, 0x3c, 0x00, 0x03, 0x00, 0x3d, 0x00, 0x03, 0x08, 0x3d, 0x00, 0x03, + 0xc0, 0x28, 0x01, 0x02, 0xc4, 0x28, 0x01, 0x02, 0xc8, 0x28, 0x01, 0x02, 0xcc, 0x28, 0x01, 0x02, 0xd0, 0x28, 0x01, 0x02, 0xd4, 0x28, 0x01, 0x02, 0xd8, 0x28, 0x01, 0x02, 0xd4, 0x08, 0x02, 0x02, + 0xd8, 0x08, 0x02, 0x02, 0xdc, 0x08, 0x02, 0x02, 0xe0, 0x08, 0x02, 0x02, 0x50, 0x25, 0x03, 0x03, 0x58, 0x25, 0x03, 0x03, 0x60, 0x25, 0x03, 0x03, 0x70, 0x06, 0x04, 0x03, 0x78, 0x06, 0x04, 0x03, + 0x30, 0x22, 0x05, 0x04, 0x10, 0x04, 0x06, 0x04, 0x20, 0x1e, 0x07, 0x05, 0xa0, 0x01, 0x08, 0x05, 0x00, 0x15, 0x0d, 0x08, 0x10, 0x3d, 0x00, 0x03, 0x18, 0x3d, 0x00, 0x03, 0x20, 0x3d, 0x00, 0x03, + 0xdc, 0x28, 0x01, 0x02, 0xe0, 0x28, 0x01, 0x02, 0xe4, 0x28, 0x01, 0x02, 0xe8, 0x28, 0x01, 0x02, 0xec, 0x28, 0x01, 0x02, 0xf0, 0x28, 0x01, 0x02, 0xf4, 0x28, 0x01, 0x02, 0xe4, 0x08, 0x02, 0x02, + 0xe8, 0x08, 0x02, 0x02, 0xec, 0x08, 0x02, 0x02, 0xf0, 0x08, 0x02, 0x02, 0x68, 0x25, 0x03, 0x03, 0x70, 0x25, 0x03, 0x03, 0x78, 0x25, 0x03, 0x03, 0x80, 0x06, 0x04, 0x03, 0x88, 0x06, 0x04, 0x03, + 0x40, 0x22, 0x05, 0x04, 0x20, 0x04, 0x06, 0x04, 0x40, 0x1e, 0x07, 0x05, 0xc0, 0x01, 0x08, 0x05, 0x00, 0x30, 0x0e, 0x09, 0x28, 0x3d, 0x00, 0x03, 0x30, 0x3d, 0x00, 0x03, 0x38, 0x3d, 0x00, 0x03, + 0xf8, 0x28, 0x01, 0x02, 0xfc, 0x28, 0x01, 0x02, 0x00, 0x29, 0x01, 0x02, 0x04, 0x29, 0x01, 0x02, 0x08, 0x29, 0x01, 0x02, 0x0c, 0x29, 0x01, 0x02, 0x10, 0x29, 0x01, 0x02, 0xf4, 0x08, 0x02, 0x02, + 0xf8, 0x08, 0x02, 0x02, 0xfc, 0x08, 0x02, 0x02, 0x00, 0x09, 0x02, 0x02, 0x80, 0x25, 0x03, 0x03, 0x88, 0x25, 0x03, 0x03, 0x90, 0x25, 0x03, 0x03, 0x90, 0x06, 0x04, 0x03, 0x98, 0x06, 0x04, 0x03, + 0x50, 0x22, 0x05, 0x04, 0x30, 0x04, 0x06, 0x04, 0x60, 0x1e, 0x07, 0x05, 0xe0, 0x01, 0x08, 0x05, 0x00, 0x32, 0x0e, 0x09, 0x40, 0x3d, 0x00, 0x03, 0x48, 0x3d, 0x00, 0x03, 0x50, 0x3d, 0x00, 0x03, + 0x14, 0x29, 0x01, 0x02, 0x18, 0x29, 0x01, 0x02, 0x1c, 0x29, 0x01, 0x02, 0x20, 0x29, 0x01, 0x02, 0x24, 0x29, 0x01, 0x02, 0x28, 0x29, 0x01, 0x02, 0x2c, 0x29, 0x01, 0x02, 0x04, 0x09, 0x02, 0x02, + 0x08, 0x09, 0x02, 0x02, 0x0c, 0x09, 0x02, 0x02, 0x10, 0x09, 0x02, 0x02, 0x98, 0x25, 0x03, 0x03, 0xa0, 0x25, 0x03, 0x03, 0xa8, 0x25, 0x03, 0x03, 0xa0, 0x06, 0x04, 0x03, 0xa8, 0x06, 0x04, 0x03, + 0x60, 0x22, 0x05, 0x04, 0x40, 0x04, 0x06, 0x04, 0x80, 0x1e, 0x07, 0x05, 0x00, 0x02, 0x08, 0x05, 0x00, 0x34, 0x0e, 0x09, 0x58, 0x3d, 0x00, 0x03, 0x60, 0x3d, 0x00, 0x03, 0x68, 0x3d, 0x00, 0x03, + 0x30, 0x29, 0x01, 0x02, 0x34, 0x29, 0x01, 0x02, 0x38, 0x29, 0x01, 0x02, 0x3c, 0x29, 0x01, 0x02, 0x40, 0x29, 0x01, 0x02, 0x44, 0x29, 0x01, 0x02, 0x48, 0x29, 0x01, 0x02, 0x14, 0x09, 0x02, 0x02, + 0x18, 0x09, 0x02, 0x02, 0x1c, 0x09, 0x02, 0x02, 0x20, 0x09, 0x02, 0x02, 0xb0, 0x25, 0x03, 0x03, 0xb8, 0x25, 0x03, 0x03, 0xc0, 0x25, 0x03, 0x03, 0xb0, 0x06, 0x04, 0x03, 0xb8, 0x06, 0x04, 0x03, + 0x70, 0x22, 0x05, 0x04, 0x50, 0x04, 0x06, 0x04, 0xa0, 0x1e, 0x07, 0x05, 0x20, 0x02, 0x08, 0x05, 0x00, 0x36, 0x0e, 0x09, 0x70, 0x3d, 0x00, 0x03, 0x78, 0x3d, 0x00, 0x03, 0x80, 0x3d, 0x00, 0x03, + 0x4c, 0x29, 0x01, 0x02, 0x50, 0x29, 0x01, 0x02, 0x54, 0x29, 0x01, 0x02, 0x58, 0x29, 0x01, 0x02, 0x5c, 0x29, 0x01, 0x02, 0x60, 0x29, 0x01, 0x02, 0x24, 0x09, 0x02, 0x02, 0x28, 0x09, 0x02, 0x02, + 0x2c, 0x09, 0x02, 0x02, 0x30, 0x09, 0x02, 0x02, 0x34, 0x09, 0x02, 0x02, 0xc8, 0x25, 0x03, 0x03, 0xd0, 0x25, 0x03, 0x03, 0xd8, 0x25, 0x03, 0x03, 0xc0, 0x06, 0x04, 0x03, 0xc8, 0x06, 0x04, 0x03, + 0x80, 0x22, 0x05, 0x04, 0x60, 0x04, 0x06, 0x04, 0xc0, 0x1e, 0x07, 0x05, 0x40, 0x02, 0x08, 0x05, 0x00, 0x10, 0x0f, 0x09, 0x88, 0x3d, 0x00, 0x03, 0x90, 0x3d, 0x00, 0x03, 0x98, 0x3d, 0x00, 0x03, + 0x64, 0x29, 0x01, 0x02, 0x68, 0x29, 0x01, 0x02, 0x6c, 0x29, 0x01, 0x02, 0x70, 0x29, 0x01, 0x02, 0x74, 0x29, 0x01, 0x02, 0x78, 0x29, 0x01, 0x02, 0x38, 0x09, 0x02, 0x02, 0x3c, 0x09, 0x02, 0x02, + 0x40, 0x09, 0x02, 0x02, 0x44, 0x09, 0x02, 0x02, 0x48, 0x09, 0x02, 0x02, 0xe0, 0x25, 0x03, 0x03, 0xe8, 0x25, 0x03, 0x03, 0xf0, 0x25, 0x03, 0x03, 0xd0, 0x06, 0x04, 0x03, 0xd8, 0x06, 0x04, 0x03, + 0x90, 0x22, 0x05, 0x04, 0x70, 0x04, 0x06, 0x04, 0xe0, 0x1e, 0x07, 0x05, 0x60, 0x02, 0x08, 0x05, 0x00, 0x12, 0x0f, 0x09, 0xa0, 0x3d, 0x00, 0x03, 0xa8, 0x3d, 0x00, 0x03, 0xb0, 0x3d, 0x00, 0x03, + 0x7c, 0x29, 0x01, 0x02, 0x80, 0x29, 0x01, 0x02, 0x84, 0x29, 0x01, 0x02, 0x88, 0x29, 0x01, 0x02, 0x8c, 0x29, 0x01, 0x02, 0x90, 0x29, 0x01, 0x02, 0x4c, 0x09, 0x02, 0x02, 0x50, 0x09, 0x02, 0x02, + 0x54, 0x09, 0x02, 0x02, 0x58, 0x09, 0x02, 0x02, 0x5c, 0x09, 0x02, 0x02, 0xf8, 0x25, 0x03, 0x03, 0x00, 0x26, 0x03, 0x03, 0x08, 0x26, 0x03, 0x03, 0xe0, 0x06, 0x04, 0x03, 0xe8, 0x06, 0x04, 0x03, + 0xa0, 0x22, 0x05, 0x04, 0x80, 0x04, 0x06, 0x04, 0x00, 0x1f, 0x07, 0x05, 0x40, 0x1b, 0x09, 0x06, 0x00, 0x14, 0x0f, 0x09, 0xb8, 0x3d, 0x00, 0x03, 0xc0, 0x3d, 0x00, 0x03, 0xc8, 0x3d, 0x00, 0x03, + 0x94, 0x29, 0x01, 0x02, 0x98, 0x29, 0x01, 0x02, 0x9c, 0x29, 0x01, 0x02, 0xa0, 0x29, 0x01, 0x02, 0xa4, 0x29, 0x01, 0x02, 0xa8, 0x29, 0x01, 0x02, 0x60, 0x09, 0x02, 0x02, 0x64, 0x09, 0x02, 0x02, + 0x68, 0x09, 0x02, 0x02, 0x6c, 0x09, 0x02, 0x02, 0x70, 0x09, 0x02, 0x02, 0x10, 0x26, 0x03, 0x03, 0x18, 0x26, 0x03, 0x03, 0x20, 0x26, 0x03, 0x03, 0xf0, 0x06, 0x04, 0x03, 0xf8, 0x06, 0x04, 0x03, + 0xb0, 0x22, 0x05, 0x04, 0x90, 0x04, 0x06, 0x04, 0x20, 0x1f, 0x07, 0x05, 0x80, 0x1b, 0x09, 0x06, 0x00, 0x16, 0x0f, 0x09, 0xd0, 0x3d, 0x00, 0x03, 0xd8, 0x3d, 0x00, 0x03, 0xe0, 0x3d, 0x00, 0x03, + 0xac, 0x29, 0x01, 0x02, 0xb0, 0x29, 0x01, 0x02, 0xb4, 0x29, 0x01, 0x02, 0xb8, 0x29, 0x01, 0x02, 0xbc, 0x29, 0x01, 0x02, 0xc0, 0x29, 0x01, 0x02, 0x74, 0x09, 0x02, 0x02, 0x78, 0x09, 0x02, 0x02, + 0x7c, 0x09, 0x02, 0x02, 0x80, 0x09, 0x02, 0x02, 0x84, 0x09, 0x02, 0x02, 0x28, 0x26, 0x03, 0x03, 0x30, 0x26, 0x03, 0x03, 0x38, 0x26, 0x03, 0x03, 0x00, 0x07, 0x04, 0x03, 0x08, 0x07, 0x04, 0x03, + 0xc0, 0x22, 0x05, 0x04, 0xa0, 0x04, 0x06, 0x04, 0x40, 0x1f, 0x07, 0x05, 0xc0, 0x1b, 0x09, 0x06, 0x00, 0x30, 0x10, 0x0a, 0xe8, 0x3d, 0x00, 0x03, 0xf0, 0x3d, 0x00, 0x03, 0xf8, 0x3d, 0x00, 0x03, + 0xc4, 0x29, 0x01, 0x02, 0xc8, 0x29, 0x01, 0x02, 0xcc, 0x29, 0x01, 0x02, 0xd0, 0x29, 0x01, 0x02, 0xd4, 0x29, 0x01, 0x02, 0xd8, 0x29, 0x01, 0x02, 0x88, 0x09, 0x02, 0x02, 0x8c, 0x09, 0x02, 0x02, + 0x90, 0x09, 0x02, 0x02, 0x94, 0x09, 0x02, 0x02, 0x98, 0x09, 0x02, 0x02, 0x40, 0x26, 0x03, 0x03, 0x48, 0x26, 0x03, 0x03, 0x50, 0x26, 0x03, 0x03, 0x10, 0x07, 0x04, 0x03, 0x18, 0x07, 0x04, 0x03, + 0xd0, 0x22, 0x05, 0x04, 0xb0, 0x04, 0x06, 0x04, 0x60, 0x1f, 0x07, 0x05, 0x00, 0x1c, 0x09, 0x06, 0x00, 0x34, 0x10, 0x0a, 0x00, 0x3e, 0x00, 0x03, 0x08, 0x3e, 0x00, 0x03, 0x10, 0x3e, 0x00, 0x03, + 0xdc, 0x29, 0x01, 0x02, 0xe0, 0x29, 0x01, 0x02, 0xe4, 0x29, 0x01, 0x02, 0xe8, 0x29, 0x01, 0x02, 0xec, 0x29, 0x01, 0x02, 0xf0, 0x29, 0x01, 0x02, 0x9c, 0x09, 0x02, 0x02, 0xa0, 0x09, 0x02, 0x02, + 0xa4, 0x09, 0x02, 0x02, 0xa8, 0x09, 0x02, 0x02, 0xac, 0x09, 0x02, 0x02, 0x58, 0x26, 0x03, 0x03, 0x60, 0x26, 0x03, 0x03, 0x68, 0x26, 0x03, 0x03, 0x20, 0x07, 0x04, 0x03, 0x28, 0x07, 0x04, 0x03, + 0xe0, 0x22, 0x05, 0x04, 0xc0, 0x04, 0x06, 0x04, 0x80, 0x1f, 0x07, 0x05, 0x40, 0x1c, 0x09, 0x06, 0x00, 0x0c, 0x11, 0x0a, 0x18, 0x3e, 0x00, 0x03, 0x20, 0x3e, 0x00, 0x03, 0x28, 0x3e, 0x00, 0x03, + 0xf4, 0x29, 0x01, 0x02, 0xf8, 0x29, 0x01, 0x02, 0xfc, 0x29, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x04, 0x2a, 0x01, 0x02, 0x08, 0x2a, 0x01, 0x02, 0xb0, 0x09, 0x02, 0x02, 0xb4, 0x09, 0x02, 0x02, + 0xb8, 0x09, 0x02, 0x02, 0xbc, 0x09, 0x02, 0x02, 0xc0, 0x09, 0x02, 0x02, 0x70, 0x26, 0x03, 0x03, 0x78, 0x26, 0x03, 0x03, 0x80, 0x26, 0x03, 0x03, 0x30, 0x07, 0x04, 0x03, 0x38, 0x07, 0x04, 0x03, + 0xf0, 0x22, 0x05, 0x04, 0xd0, 0x04, 0x06, 0x04, 0xa0, 0x1f, 0x07, 0x05, 0x80, 0x1c, 0x09, 0x06, 0x00, 0x10, 0x11, 0x0a, 0x30, 0x3e, 0x00, 0x03, 0x38, 0x3e, 0x00, 0x03, 0x40, 0x3e, 0x00, 0x03, + 0x0c, 0x2a, 0x01, 0x02, 0x10, 0x2a, 0x01, 0x02, 0x14, 0x2a, 0x01, 0x02, 0x18, 0x2a, 0x01, 0x02, 0x1c, 0x2a, 0x01, 0x02, 0x20, 0x2a, 0x01, 0x02, 0xc4, 0x09, 0x02, 0x02, 0xc8, 0x09, 0x02, 0x02, + 0xcc, 0x09, 0x02, 0x02, 0xd0, 0x09, 0x02, 0x02, 0xd4, 0x09, 0x02, 0x02, 0x88, 0x26, 0x03, 0x03, 0x90, 0x26, 0x03, 0x03, 0x98, 0x26, 0x03, 0x03, 0x40, 0x07, 0x04, 0x03, 0x48, 0x07, 0x04, 0x03, + 0x00, 0x23, 0x05, 0x04, 0xe0, 0x04, 0x06, 0x04, 0xc0, 0x1f, 0x07, 0x05, 0xc0, 0x1c, 0x09, 0x06, 0x00, 0x30, 0x12, 0x0b, 0x48, 0x3e, 0x00, 0x03, 0x50, 0x3e, 0x00, 0x03, 0x58, 0x3e, 0x00, 0x03, + 0x24, 0x2a, 0x01, 0x02, 0x28, 0x2a, 0x01, 0x02, 0x2c, 0x2a, 0x01, 0x02, 0x30, 0x2a, 0x01, 0x02, 0x34, 0x2a, 0x01, 0x02, 0x38, 0x2a, 0x01, 0x02, 0xd8, 0x09, 0x02, 0x02, 0xdc, 0x09, 0x02, 0x02, + 0xe0, 0x09, 0x02, 0x02, 0xe4, 0x09, 0x02, 0x02, 0xe8, 0x09, 0x02, 0x02, 0xa0, 0x26, 0x03, 0x03, 0xa8, 0x26, 0x03, 0x03, 0xb0, 0x26, 0x03, 0x03, 0x50, 0x07, 0x04, 0x03, 0x58, 0x07, 0x04, 0x03, + 0x10, 0x23, 0x05, 0x04, 0xf0, 0x04, 0x06, 0x04, 0xe0, 0x1f, 0x07, 0x05, 0x00, 0x1d, 0x09, 0x06, 0x00, 0x10, 0x13, 0x0b, 0x60, 0x3e, 0x00, 0x03, 0x68, 0x3e, 0x00, 0x03, 0x70, 0x3e, 0x00, 0x03, + 0x3c, 0x2a, 0x01, 0x02, 0x40, 0x2a, 0x01, 0x02, 0x44, 0x2a, 0x01, 0x02, 0x48, 0x2a, 0x01, 0x02, 0x4c, 0x2a, 0x01, 0x02, 0x50, 0x2a, 0x01, 0x02, 0xec, 0x09, 0x02, 0x02, 0xf0, 0x09, 0x02, 0x02, + 0xf4, 0x09, 0x02, 0x02, 0xf8, 0x09, 0x02, 0x02, 0xfc, 0x09, 0x02, 0x02, 0xb8, 0x26, 0x03, 0x03, 0xc0, 0x26, 0x03, 0x03, 0xc8, 0x26, 0x03, 0x03, 0x60, 0x07, 0x04, 0x03, 0x68, 0x07, 0x04, 0x03, + 0x20, 0x23, 0x05, 0x04, 0x00, 0x05, 0x06, 0x04, 0x00, 0x20, 0x07, 0x05, 0x40, 0x1d, 0x09, 0x06, 0x00, 0x20, 0x14, 0x0c, 0x78, 0x3e, 0x00, 0x03, 0x80, 0x3e, 0x00, 0x03, 0x88, 0x3e, 0x00, 0x03, + 0x54, 0x2a, 0x01, 0x02, 0x58, 0x2a, 0x01, 0x02, 0x5c, 0x2a, 0x01, 0x02, 0x60, 0x2a, 0x01, 0x02, 0x64, 0x2a, 0x01, 0x02, 0x68, 0x2a, 0x01, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x04, 0x0a, 0x02, 0x02, + 0x08, 0x0a, 0x02, 0x02, 0x0c, 0x0a, 0x02, 0x02, 0x10, 0x0a, 0x02, 0x02, 0xd0, 0x26, 0x03, 0x03, 0xd8, 0x26, 0x03, 0x03, 0xe0, 0x26, 0x03, 0x03, 0x70, 0x07, 0x04, 0x03, 0x78, 0x07, 0x04, 0x03, + 0x30, 0x23, 0x05, 0x04, 0x10, 0x05, 0x06, 0x04, 0x20, 0x20, 0x07, 0x05, 0x80, 0x1d, 0x09, 0x06, 0x90, 0x3e, 0x00, 0x03, 0x98, 0x3e, 0x00, 0x03, 0xa0, 0x3e, 0x00, 0x03, 0xa8, 0x3e, 0x00, 0x03, + 0x6c, 0x2a, 0x01, 0x02, 0x70, 0x2a, 0x01, 0x02, 0x74, 0x2a, 0x01, 0x02, 0x78, 0x2a, 0x01, 0x02, 0x7c, 0x2a, 0x01, 0x02, 0x80, 0x2a, 0x01, 0x02, 0x14, 0x0a, 0x02, 0x02, 0x18, 0x0a, 0x02, 0x02, + 0x1c, 0x0a, 0x02, 0x02, 0x20, 0x0a, 0x02, 0x02, 0x24, 0x0a, 0x02, 0x02, 0xe8, 0x26, 0x03, 0x03, 0xf0, 0x26, 0x03, 0x03, 0xf8, 0x26, 0x03, 0x03, 0x80, 0x07, 0x04, 0x03, 0x88, 0x07, 0x04, 0x03, + 0x40, 0x23, 0x05, 0x04, 0x20, 0x05, 0x06, 0x04, 0x40, 0x20, 0x07, 0x05, 0xc0, 0x1d, 0x09, 0x06, 0xb0, 0x3e, 0x00, 0x03, 0xb8, 0x3e, 0x00, 0x03, 0xc0, 0x3e, 0x00, 0x03, 0xc8, 0x3e, 0x00, 0x03, + 0x84, 0x2a, 0x01, 0x02, 0x88, 0x2a, 0x01, 0x02, 0x8c, 0x2a, 0x01, 0x02, 0x90, 0x2a, 0x01, 0x02, 0x94, 0x2a, 0x01, 0x02, 0x98, 0x2a, 0x01, 0x02, 0x28, 0x0a, 0x02, 0x02, 0x2c, 0x0a, 0x02, 0x02, + 0x30, 0x0a, 0x02, 0x02, 0x34, 0x0a, 0x02, 0x02, 0x38, 0x0a, 0x02, 0x02, 0x00, 0x27, 0x03, 0x03, 0x08, 0x27, 0x03, 0x03, 0x10, 0x27, 0x03, 0x03, 0x90, 0x07, 0x04, 0x03, 0x98, 0x07, 0x04, 0x03, + 0x50, 0x23, 0x05, 0x04, 0x30, 0x05, 0x06, 0x04, 0x60, 0x20, 0x07, 0x05, 0x00, 0x1e, 0x09, 0x06, 0xd0, 0x3e, 0x00, 0x03, 0xd8, 0x3e, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x03, 0xe8, 0x3e, 0x00, 0x03, + 0x9c, 0x2a, 0x01, 0x02, 0xa0, 0x2a, 0x01, 0x02, 0xa4, 0x2a, 0x01, 0x02, 0xa8, 0x2a, 0x01, 0x02, 0xac, 0x2a, 0x01, 0x02, 0xb0, 0x2a, 0x01, 0x02, 0x3c, 0x0a, 0x02, 0x02, 0x40, 0x0a, 0x02, 0x02, + 0x44, 0x0a, 0x02, 0x02, 0x48, 0x0a, 0x02, 0x02, 0x4c, 0x0a, 0x02, 0x02, 0x18, 0x27, 0x03, 0x03, 0x20, 0x27, 0x03, 0x03, 0x28, 0x27, 0x03, 0x03, 0xa0, 0x07, 0x04, 0x03, 0xa8, 0x07, 0x04, 0x03, + 0x60, 0x23, 0x05, 0x04, 0x40, 0x05, 0x06, 0x04, 0x80, 0x20, 0x07, 0x05, 0x40, 0x1e, 0x09, 0x06, 0xf0, 0x3e, 0x00, 0x03, 0xf8, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x03, 0x08, 0x3f, 0x00, 0x03, + 0xb4, 0x2a, 0x01, 0x02, 0xb8, 0x2a, 0x01, 0x02, 0xbc, 0x2a, 0x01, 0x02, 0xc0, 0x2a, 0x01, 0x02, 0xc4, 0x2a, 0x01, 0x02, 0xc8, 0x2a, 0x01, 0x02, 0x50, 0x0a, 0x02, 0x02, 0x54, 0x0a, 0x02, 0x02, + 0x58, 0x0a, 0x02, 0x02, 0x5c, 0x0a, 0x02, 0x02, 0x60, 0x0a, 0x02, 0x02, 0x30, 0x27, 0x03, 0x03, 0x38, 0x27, 0x03, 0x03, 0x40, 0x27, 0x03, 0x03, 0xb0, 0x07, 0x04, 0x03, 0xb8, 0x07, 0x04, 0x03, + 0x70, 0x23, 0x05, 0x04, 0x50, 0x05, 0x06, 0x04, 0xa0, 0x20, 0x07, 0x05, 0x80, 0x1e, 0x09, 0x06, 0x10, 0x3f, 0x00, 0x03, 0x18, 0x3f, 0x00, 0x03, 0x20, 0x3f, 0x00, 0x03, 0x28, 0x3f, 0x00, 0x03, + 0xcc, 0x2a, 0x01, 0x02, 0xd0, 0x2a, 0x01, 0x02, 0xd4, 0x2a, 0x01, 0x02, 0xd8, 0x2a, 0x01, 0x02, 0xdc, 0x2a, 0x01, 0x02, 0xe0, 0x2a, 0x01, 0x02, 0x64, 0x0a, 0x02, 0x02, 0x68, 0x0a, 0x02, 0x02, + 0x6c, 0x0a, 0x02, 0x02, 0x70, 0x0a, 0x02, 0x02, 0x74, 0x0a, 0x02, 0x02, 0x48, 0x27, 0x03, 0x03, 0x50, 0x27, 0x03, 0x03, 0x58, 0x27, 0x03, 0x03, 0xc0, 0x07, 0x04, 0x03, 0xc8, 0x07, 0x04, 0x03, + 0x80, 0x23, 0x05, 0x04, 0x60, 0x05, 0x06, 0x04, 0xc0, 0x20, 0x07, 0x05, 0xc0, 0x1e, 0x09, 0x06, 0x30, 0x3f, 0x00, 0x03, 0x38, 0x3f, 0x00, 0x03, 0x40, 0x3f, 0x00, 0x03, 0x48, 0x3f, 0x00, 0x03, + 0xe4, 0x2a, 0x01, 0x02, 0xe8, 0x2a, 0x01, 0x02, 0xec, 0x2a, 0x01, 0x02, 0xf0, 0x2a, 0x01, 0x02, 0xf4, 0x2a, 0x01, 0x02, 0xf8, 0x2a, 0x01, 0x02, 0x78, 0x0a, 0x02, 0x02, 0x7c, 0x0a, 0x02, 0x02, + 0x80, 0x0a, 0x02, 0x02, 0x84, 0x0a, 0x02, 0x02, 0x88, 0x0a, 0x02, 0x02, 0x60, 0x27, 0x03, 0x03, 0x68, 0x27, 0x03, 0x03, 0x70, 0x27, 0x03, 0x03, 0xd0, 0x07, 0x04, 0x03, 0xd8, 0x07, 0x04, 0x03, + 0x90, 0x23, 0x05, 0x04, 0x70, 0x05, 0x06, 0x04, 0xe0, 0x20, 0x07, 0x05, 0x00, 0x1f, 0x09, 0x06, 0x50, 0x3f, 0x00, 0x03, 0x58, 0x3f, 0x00, 0x03, 0x60, 0x3f, 0x00, 0x03, 0x68, 0x3f, 0x00, 0x03, + 0xfc, 0x2a, 0x01, 0x02, 0x00, 0x2b, 0x01, 0x02, 0x04, 0x2b, 0x01, 0x02, 0x08, 0x2b, 0x01, 0x02, 0x0c, 0x2b, 0x01, 0x02, 0x10, 0x2b, 0x01, 0x02, 0x8c, 0x0a, 0x02, 0x02, 0x90, 0x0a, 0x02, 0x02, + 0x94, 0x0a, 0x02, 0x02, 0x98, 0x0a, 0x02, 0x02, 0x9c, 0x0a, 0x02, 0x02, 0x78, 0x27, 0x03, 0x03, 0x80, 0x27, 0x03, 0x03, 0x88, 0x27, 0x03, 0x03, 0xe0, 0x07, 0x04, 0x03, 0xe8, 0x07, 0x04, 0x03, + 0xa0, 0x23, 0x05, 0x04, 0x80, 0x05, 0x06, 0x04, 0x00, 0x21, 0x07, 0x05, 0x40, 0x1f, 0x09, 0x06, 0x70, 0x3f, 0x00, 0x03, 0x78, 0x3f, 0x00, 0x03, 0x80, 0x3f, 0x00, 0x03, 0x88, 0x3f, 0x00, 0x03, + 0x14, 0x2b, 0x01, 0x02, 0x18, 0x2b, 0x01, 0x02, 0x1c, 0x2b, 0x01, 0x02, 0x20, 0x2b, 0x01, 0x02, 0x24, 0x2b, 0x01, 0x02, 0x28, 0x2b, 0x01, 0x02, 0xa0, 0x0a, 0x02, 0x02, 0xa4, 0x0a, 0x02, 0x02, + 0xa8, 0x0a, 0x02, 0x02, 0xac, 0x0a, 0x02, 0x02, 0xb0, 0x0a, 0x02, 0x02, 0x90, 0x27, 0x03, 0x03, 0x98, 0x27, 0x03, 0x03, 0xa0, 0x27, 0x03, 0x03, 0xf0, 0x07, 0x04, 0x03, 0xf8, 0x07, 0x04, 0x03, + 0xb0, 0x23, 0x05, 0x04, 0x90, 0x05, 0x06, 0x04, 0x20, 0x21, 0x07, 0x05, 0x80, 0x1f, 0x09, 0x06, 0x90, 0x3f, 0x00, 0x03, 0x98, 0x3f, 0x00, 0x03, 0xa0, 0x3f, 0x00, 0x03, 0xa8, 0x3f, 0x00, 0x03, + 0x2c, 0x2b, 0x01, 0x02, 0x30, 0x2b, 0x01, 0x02, 0x34, 0x2b, 0x01, 0x02, 0x38, 0x2b, 0x01, 0x02, 0x3c, 0x2b, 0x01, 0x02, 0x40, 0x2b, 0x01, 0x02, 0xb4, 0x0a, 0x02, 0x02, 0xb8, 0x0a, 0x02, 0x02, + 0xbc, 0x0a, 0x02, 0x02, 0xc0, 0x0a, 0x02, 0x02, 0xc4, 0x0a, 0x02, 0x02, 0xa8, 0x27, 0x03, 0x03, 0xb0, 0x27, 0x03, 0x03, 0xb8, 0x27, 0x03, 0x03, 0x00, 0x08, 0x04, 0x03, 0x08, 0x08, 0x04, 0x03, + 0xc0, 0x23, 0x05, 0x04, 0xa0, 0x05, 0x06, 0x04, 0x40, 0x21, 0x07, 0x05, 0xc0, 0x1f, 0x09, 0x06, 0xb0, 0x3f, 0x00, 0x03, 0xb8, 0x3f, 0x00, 0x03, 0xc0, 0x3f, 0x00, 0x03, 0xc8, 0x3f, 0x00, 0x03, + 0x44, 0x2b, 0x01, 0x02, 0x48, 0x2b, 0x01, 0x02, 0x4c, 0x2b, 0x01, 0x02, 0x50, 0x2b, 0x01, 0x02, 0x54, 0x2b, 0x01, 0x02, 0x58, 0x2b, 0x01, 0x02, 0xc8, 0x0a, 0x02, 0x02, 0xcc, 0x0a, 0x02, 0x02, + 0xd0, 0x0a, 0x02, 0x02, 0xd4, 0x0a, 0x02, 0x02, 0xd8, 0x0a, 0x02, 0x02, 0xc0, 0x27, 0x03, 0x03, 0xc8, 0x27, 0x03, 0x03, 0xd0, 0x27, 0x03, 0x03, 0x10, 0x08, 0x04, 0x03, 0x18, 0x08, 0x04, 0x03, + 0xd0, 0x23, 0x05, 0x04, 0xb0, 0x05, 0x06, 0x04, 0x60, 0x21, 0x07, 0x05, 0x00, 0x20, 0x09, 0x06, 0xd0, 0x3f, 0x00, 0x03, 0xd8, 0x3f, 0x00, 0x03, 0xe0, 0x3f, 0x00, 0x03, 0xe8, 0x3f, 0x00, 0x03, + 0x5c, 0x2b, 0x01, 0x02, 0x60, 0x2b, 0x01, 0x02, 0x64, 0x2b, 0x01, 0x02, 0x68, 0x2b, 0x01, 0x02, 0x6c, 0x2b, 0x01, 0x02, 0x70, 0x2b, 0x01, 0x02, 0xdc, 0x0a, 0x02, 0x02, 0xe0, 0x0a, 0x02, 0x02, + 0xe4, 0x0a, 0x02, 0x02, 0xe8, 0x0a, 0x02, 0x02, 0xec, 0x0a, 0x02, 0x02, 0xd8, 0x27, 0x03, 0x03, 0xe0, 0x27, 0x03, 0x03, 0xe8, 0x27, 0x03, 0x03, 0x20, 0x08, 0x04, 0x03, 0x28, 0x08, 0x04, 0x03, + 0xe0, 0x23, 0x05, 0x04, 0xc0, 0x05, 0x06, 0x04, 0x80, 0x21, 0x07, 0x05, 0x40, 0x20, 0x09, 0x06, 0xf0, 0x3f, 0x00, 0x03, 0xf8, 0x3f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, + 0x74, 0x2b, 0x01, 0x02, 0x78, 0x2b, 0x01, 0x02, 0x7c, 0x2b, 0x01, 0x02, 0x80, 0x2b, 0x01, 0x02, 0x84, 0x2b, 0x01, 0x02, 0x88, 0x2b, 0x01, 0x02, 0xf0, 0x0a, 0x02, 0x02, 0xf4, 0x0a, 0x02, 0x02, + 0xf8, 0x0a, 0x02, 0x02, 0xfc, 0x0a, 0x02, 0x02, 0x00, 0x0b, 0x02, 0x02, 0xf0, 0x27, 0x03, 0x03, 0xf8, 0x27, 0x03, 0x03, 0x00, 0x28, 0x03, 0x03, 0x30, 0x08, 0x04, 0x03, 0x38, 0x08, 0x04, 0x03, + 0xf0, 0x23, 0x05, 0x04, 0xd0, 0x05, 0x06, 0x04, 0xa0, 0x21, 0x07, 0x05, 0x80, 0x20, 0x09, 0x06, 0x08, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x02, + 0x8c, 0x2b, 0x01, 0x02, 0x90, 0x2b, 0x01, 0x02, 0x94, 0x2b, 0x01, 0x02, 0x98, 0x2b, 0x01, 0x02, 0x9c, 0x2b, 0x01, 0x02, 0xa0, 0x2b, 0x01, 0x02, 0x04, 0x0b, 0x02, 0x02, 0x08, 0x0b, 0x02, 0x02, + 0x0c, 0x0b, 0x02, 0x02, 0x10, 0x0b, 0x02, 0x02, 0x14, 0x0b, 0x02, 0x02, 0x08, 0x28, 0x03, 0x03, 0x10, 0x28, 0x03, 0x03, 0x18, 0x28, 0x03, 0x03, 0x40, 0x08, 0x04, 0x03, 0x48, 0x08, 0x04, 0x03, + 0x00, 0x24, 0x05, 0x04, 0xe0, 0x05, 0x06, 0x04, 0xc0, 0x21, 0x07, 0x05, 0xc0, 0x20, 0x09, 0x06, 0x18, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x02, + 0xa4, 0x2b, 0x01, 0x02, 0xa8, 0x2b, 0x01, 0x02, 0xac, 0x2b, 0x01, 0x02, 0xb0, 0x2b, 0x01, 0x02, 0xb4, 0x2b, 0x01, 0x02, 0xb8, 0x2b, 0x01, 0x02, 0x18, 0x0b, 0x02, 0x02, 0x1c, 0x0b, 0x02, 0x02, + 0x20, 0x0b, 0x02, 0x02, 0x24, 0x0b, 0x02, 0x02, 0x28, 0x0b, 0x02, 0x02, 0x20, 0x28, 0x03, 0x03, 0x28, 0x28, 0x03, 0x03, 0x30, 0x28, 0x03, 0x03, 0x50, 0x08, 0x04, 0x03, 0x58, 0x08, 0x04, 0x03, + 0x10, 0x24, 0x05, 0x04, 0xf0, 0x05, 0x06, 0x04, 0xe0, 0x21, 0x07, 0x05, 0x00, 0x21, 0x09, 0x06, 0x28, 0x00, 0x00, 0x02, 0x2c, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x02, 0x34, 0x00, 0x00, 0x02, + 0xbc, 0x2b, 0x01, 0x02, 0xc0, 0x2b, 0x01, 0x02, 0xc4, 0x2b, 0x01, 0x02, 0xc8, 0x2b, 0x01, 0x02, 0xcc, 0x2b, 0x01, 0x02, 0xd0, 0x2b, 0x01, 0x02, 0x2c, 0x0b, 0x02, 0x02, 0x30, 0x0b, 0x02, 0x02, + 0x34, 0x0b, 0x02, 0x02, 0x38, 0x0b, 0x02, 0x02, 0x3c, 0x0b, 0x02, 0x02, 0x38, 0x28, 0x03, 0x03, 0x40, 0x28, 0x03, 0x03, 0x48, 0x28, 0x03, 0x03, 0x60, 0x08, 0x04, 0x03, 0x68, 0x08, 0x04, 0x03, + 0x20, 0x24, 0x05, 0x04, 0x00, 0x06, 0x06, 0x04, 0x00, 0x22, 0x07, 0x05, 0x40, 0x21, 0x09, 0x06, 0x38, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x44, 0x00, 0x00, 0x02, + 0xd4, 0x2b, 0x01, 0x02, 0xd8, 0x2b, 0x01, 0x02, 0xdc, 0x2b, 0x01, 0x02, 0xe0, 0x2b, 0x01, 0x02, 0xe4, 0x2b, 0x01, 0x02, 0xe8, 0x2b, 0x01, 0x02, 0x40, 0x0b, 0x02, 0x02, 0x44, 0x0b, 0x02, 0x02, + 0x48, 0x0b, 0x02, 0x02, 0x4c, 0x0b, 0x02, 0x02, 0x50, 0x28, 0x03, 0x03, 0x58, 0x28, 0x03, 0x03, 0x60, 0x28, 0x03, 0x03, 0x70, 0x08, 0x04, 0x03, 0x78, 0x08, 0x04, 0x03, 0x80, 0x08, 0x04, 0x03, + 0x30, 0x24, 0x05, 0x04, 0x10, 0x06, 0x06, 0x04, 0x20, 0x22, 0x07, 0x05, 0x80, 0x21, 0x09, 0x06, 0x48, 0x00, 0x00, 0x02, 0x4c, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x02, + 0xec, 0x2b, 0x01, 0x02, 0xf0, 0x2b, 0x01, 0x02, 0xf4, 0x2b, 0x01, 0x02, 0xf8, 0x2b, 0x01, 0x02, 0xfc, 0x2b, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x50, 0x0b, 0x02, 0x02, 0x54, 0x0b, 0x02, 0x02, + 0x58, 0x0b, 0x02, 0x02, 0x5c, 0x0b, 0x02, 0x02, 0x68, 0x28, 0x03, 0x03, 0x70, 0x28, 0x03, 0x03, 0x78, 0x28, 0x03, 0x03, 0x88, 0x08, 0x04, 0x03, 0x90, 0x08, 0x04, 0x03, 0x98, 0x08, 0x04, 0x03, + 0x40, 0x24, 0x05, 0x04, 0x20, 0x06, 0x06, 0x04, 0x40, 0x22, 0x07, 0x05, 0xc0, 0x21, 0x09, 0x06, 0x58, 0x00, 0x00, 0x02, 0x5c, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x02, 0x64, 0x00, 0x00, 0x02, + 0x04, 0x2c, 0x01, 0x02, 0x08, 0x2c, 0x01, 0x02, 0x0c, 0x2c, 0x01, 0x02, 0x10, 0x2c, 0x01, 0x02, 0x14, 0x2c, 0x01, 0x02, 0x18, 0x2c, 0x01, 0x02, 0x60, 0x0b, 0x02, 0x02, 0x64, 0x0b, 0x02, 0x02, + 0x68, 0x0b, 0x02, 0x02, 0x6c, 0x0b, 0x02, 0x02, 0x80, 0x28, 0x03, 0x03, 0x88, 0x28, 0x03, 0x03, 0x90, 0x28, 0x03, 0x03, 0xa0, 0x08, 0x04, 0x03, 0xa8, 0x08, 0x04, 0x03, 0xb0, 0x08, 0x04, 0x03, + 0x50, 0x24, 0x05, 0x04, 0x30, 0x06, 0x06, 0x04, 0x60, 0x22, 0x07, 0x05, 0x00, 0x22, 0x09, 0x06, 0x68, 0x00, 0x00, 0x02, 0x6c, 0x00, 0x00, 0x02, 0x70, 0x00, 0x00, 0x02, 0x74, 0x00, 0x00, 0x02, + 0x1c, 0x2c, 0x01, 0x02, 0x20, 0x2c, 0x01, 0x02, 0x24, 0x2c, 0x01, 0x02, 0x28, 0x2c, 0x01, 0x02, 0x2c, 0x2c, 0x01, 0x02, 0x30, 0x2c, 0x01, 0x02, 0x70, 0x0b, 0x02, 0x02, 0x74, 0x0b, 0x02, 0x02, + 0x78, 0x0b, 0x02, 0x02, 0x7c, 0x0b, 0x02, 0x02, 0x98, 0x28, 0x03, 0x03, 0xa0, 0x28, 0x03, 0x03, 0xa8, 0x28, 0x03, 0x03, 0xb8, 0x08, 0x04, 0x03, 0xc0, 0x08, 0x04, 0x03, 0xc8, 0x08, 0x04, 0x03, + 0x60, 0x24, 0x05, 0x04, 0x40, 0x06, 0x06, 0x04, 0x80, 0x22, 0x07, 0x05, 0x40, 0x22, 0x09, 0x06, 0x78, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x02, 0x84, 0x00, 0x00, 0x02, + 0x34, 0x2c, 0x01, 0x02, 0x38, 0x2c, 0x01, 0x02, 0x3c, 0x2c, 0x01, 0x02, 0x40, 0x2c, 0x01, 0x02, 0x44, 0x2c, 0x01, 0x02, 0x48, 0x2c, 0x01, 0x02, 0x80, 0x0b, 0x02, 0x02, 0x84, 0x0b, 0x02, 0x02, + 0x88, 0x0b, 0x02, 0x02, 0x8c, 0x0b, 0x02, 0x02, 0xb0, 0x28, 0x03, 0x03, 0xb8, 0x28, 0x03, 0x03, 0xc0, 0x28, 0x03, 0x03, 0xd0, 0x08, 0x04, 0x03, 0xd8, 0x08, 0x04, 0x03, 0xe0, 0x08, 0x04, 0x03, + 0x70, 0x24, 0x05, 0x04, 0x50, 0x06, 0x06, 0x04, 0xa0, 0x22, 0x07, 0x05, 0x40, 0x00, 0x0a, 0x06, 0x88, 0x00, 0x00, 0x02, 0x8c, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, 0x94, 0x00, 0x00, 0x02, + 0x4c, 0x2c, 0x01, 0x02, 0x50, 0x2c, 0x01, 0x02, 0x54, 0x2c, 0x01, 0x02, 0x58, 0x2c, 0x01, 0x02, 0x5c, 0x2c, 0x01, 0x02, 0x60, 0x2c, 0x01, 0x02, 0x90, 0x0b, 0x02, 0x02, 0x94, 0x0b, 0x02, 0x02, + 0x98, 0x0b, 0x02, 0x02, 0x9c, 0x0b, 0x02, 0x02, 0xc8, 0x28, 0x03, 0x03, 0xd0, 0x28, 0x03, 0x03, 0xd8, 0x28, 0x03, 0x03, 0xe8, 0x08, 0x04, 0x03, 0xf0, 0x08, 0x04, 0x03, 0xf8, 0x08, 0x04, 0x03, + 0x80, 0x24, 0x05, 0x04, 0x60, 0x06, 0x06, 0x04, 0xc0, 0x22, 0x07, 0x05, 0x80, 0x00, 0x0a, 0x06, 0x98, 0x00, 0x00, 0x02, 0x9c, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x02, 0xa4, 0x00, 0x00, 0x02, + 0x64, 0x2c, 0x01, 0x02, 0x68, 0x2c, 0x01, 0x02, 0x6c, 0x2c, 0x01, 0x02, 0x70, 0x2c, 0x01, 0x02, 0x74, 0x2c, 0x01, 0x02, 0x78, 0x2c, 0x01, 0x02, 0xa0, 0x0b, 0x02, 0x02, 0xa4, 0x0b, 0x02, 0x02, + 0xa8, 0x0b, 0x02, 0x02, 0xac, 0x0b, 0x02, 0x02, 0xe0, 0x28, 0x03, 0x03, 0xe8, 0x28, 0x03, 0x03, 0xf0, 0x28, 0x03, 0x03, 0x00, 0x09, 0x04, 0x03, 0x08, 0x09, 0x04, 0x03, 0x10, 0x09, 0x04, 0x03, + 0x90, 0x24, 0x05, 0x04, 0x70, 0x06, 0x06, 0x04, 0xe0, 0x22, 0x07, 0x05, 0xc0, 0x00, 0x0a, 0x06, 0xa8, 0x00, 0x00, 0x02, 0xac, 0x00, 0x00, 0x02, 0xb0, 0x00, 0x00, 0x02, 0xb4, 0x00, 0x00, 0x02, + 0x7c, 0x2c, 0x01, 0x02, 0x80, 0x2c, 0x01, 0x02, 0x84, 0x2c, 0x01, 0x02, 0x88, 0x2c, 0x01, 0x02, 0x8c, 0x2c, 0x01, 0x02, 0x90, 0x2c, 0x01, 0x02, 0xb0, 0x0b, 0x02, 0x02, 0xb4, 0x0b, 0x02, 0x02, + 0xb8, 0x0b, 0x02, 0x02, 0xbc, 0x0b, 0x02, 0x02, 0xf8, 0x28, 0x03, 0x03, 0x00, 0x29, 0x03, 0x03, 0x08, 0x29, 0x03, 0x03, 0x18, 0x09, 0x04, 0x03, 0x20, 0x09, 0x04, 0x03, 0xa0, 0x24, 0x05, 0x04, + 0xb0, 0x24, 0x05, 0x04, 0x80, 0x06, 0x06, 0x04, 0x00, 0x23, 0x07, 0x05, 0x00, 0x01, 0x0a, 0x06, 0xb8, 0x00, 0x00, 0x02, 0xbc, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x02, + 0x94, 0x2c, 0x01, 0x02, 0x98, 0x2c, 0x01, 0x02, 0x9c, 0x2c, 0x01, 0x02, 0xa0, 0x2c, 0x01, 0x02, 0xa4, 0x2c, 0x01, 0x02, 0xa8, 0x2c, 0x01, 0x02, 0xc0, 0x0b, 0x02, 0x02, 0xc4, 0x0b, 0x02, 0x02, + 0xc8, 0x0b, 0x02, 0x02, 0xcc, 0x0b, 0x02, 0x02, 0x10, 0x29, 0x03, 0x03, 0x18, 0x29, 0x03, 0x03, 0x20, 0x29, 0x03, 0x03, 0x28, 0x09, 0x04, 0x03, 0x30, 0x09, 0x04, 0x03, 0xc0, 0x24, 0x05, 0x04, + 0xd0, 0x24, 0x05, 0x04, 0x90, 0x06, 0x06, 0x04, 0x20, 0x23, 0x07, 0x05, 0x40, 0x01, 0x0a, 0x06, 0xc8, 0x00, 0x00, 0x02, 0xcc, 0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x02, 0xd4, 0x00, 0x00, 0x02, + 0xac, 0x2c, 0x01, 0x02, 0xb0, 0x2c, 0x01, 0x02, 0xb4, 0x2c, 0x01, 0x02, 0xb8, 0x2c, 0x01, 0x02, 0xbc, 0x2c, 0x01, 0x02, 0xc0, 0x2c, 0x01, 0x02, 0xd0, 0x0b, 0x02, 0x02, 0xd4, 0x0b, 0x02, 0x02, + 0xd8, 0x0b, 0x02, 0x02, 0xdc, 0x0b, 0x02, 0x02, 0x28, 0x29, 0x03, 0x03, 0x30, 0x29, 0x03, 0x03, 0x38, 0x29, 0x03, 0x03, 0x38, 0x09, 0x04, 0x03, 0x40, 0x09, 0x04, 0x03, 0xe0, 0x24, 0x05, 0x04, + 0xf0, 0x24, 0x05, 0x04, 0xa0, 0x06, 0x06, 0x04, 0x40, 0x23, 0x07, 0x05, 0x80, 0x01, 0x0a, 0x06, 0xd8, 0x00, 0x00, 0x02, 0xdc, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, 0xe4, 0x00, 0x00, 0x02, + 0xc4, 0x2c, 0x01, 0x02, 0xc8, 0x2c, 0x01, 0x02, 0xcc, 0x2c, 0x01, 0x02, 0xd0, 0x2c, 0x01, 0x02, 0xd4, 0x2c, 0x01, 0x02, 0xd8, 0x2c, 0x01, 0x02, 0xe0, 0x0b, 0x02, 0x02, 0xe4, 0x0b, 0x02, 0x02, + 0xe8, 0x0b, 0x02, 0x02, 0xec, 0x0b, 0x02, 0x02, 0x40, 0x29, 0x03, 0x03, 0x48, 0x29, 0x03, 0x03, 0x50, 0x29, 0x03, 0x03, 0x48, 0x09, 0x04, 0x03, 0x50, 0x09, 0x04, 0x03, 0x00, 0x25, 0x05, 0x04, + 0x10, 0x25, 0x05, 0x04, 0xb0, 0x06, 0x06, 0x04, 0x60, 0x23, 0x07, 0x05, 0xc0, 0x01, 0x0a, 0x06, 0xe8, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x02, 0xf0, 0x00, 0x00, 0x02, 0xf4, 0x00, 0x00, 0x02, + 0xdc, 0x2c, 0x01, 0x02, 0xe0, 0x2c, 0x01, 0x02, 0xe4, 0x2c, 0x01, 0x02, 0xe8, 0x2c, 0x01, 0x02, 0xec, 0x2c, 0x01, 0x02, 0xf0, 0x2c, 0x01, 0x02, 0xf0, 0x0b, 0x02, 0x02, 0xf4, 0x0b, 0x02, 0x02, + 0xf8, 0x0b, 0x02, 0x02, 0xfc, 0x0b, 0x02, 0x02, 0x58, 0x29, 0x03, 0x03, 0x60, 0x29, 0x03, 0x03, 0x68, 0x29, 0x03, 0x03, 0x58, 0x09, 0x04, 0x03, 0x60, 0x09, 0x04, 0x03, 0x20, 0x25, 0x05, 0x04, + 0x30, 0x25, 0x05, 0x04, 0xc0, 0x06, 0x06, 0x04, 0x80, 0x23, 0x07, 0x05, 0x00, 0x02, 0x0a, 0x06, 0xf8, 0x00, 0x00, 0x02, 0xfc, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02, + 0xf4, 0x2c, 0x01, 0x02, 0xf8, 0x2c, 0x01, 0x02, 0xfc, 0x2c, 0x01, 0x02, 0x00, 0x2d, 0x01, 0x02, 0x04, 0x2d, 0x01, 0x02, 0x08, 0x2d, 0x01, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x04, 0x0c, 0x02, 0x02, + 0x08, 0x0c, 0x02, 0x02, 0x0c, 0x0c, 0x02, 0x02, 0x70, 0x29, 0x03, 0x03, 0x78, 0x29, 0x03, 0x03, 0x80, 0x29, 0x03, 0x03, 0x68, 0x09, 0x04, 0x03, 0x70, 0x09, 0x04, 0x03, 0x40, 0x25, 0x05, 0x04, + 0x50, 0x25, 0x05, 0x04, 0xd0, 0x06, 0x06, 0x04, 0xa0, 0x23, 0x07, 0x05, 0x40, 0x02, 0x0a, 0x06, 0x08, 0x01, 0x00, 0x02, 0x0c, 0x01, 0x00, 0x02, 0x10, 0x01, 0x00, 0x02, 0x14, 0x01, 0x00, 0x02, + 0x0c, 0x2d, 0x01, 0x02, 0x10, 0x2d, 0x01, 0x02, 0x14, 0x2d, 0x01, 0x02, 0x18, 0x2d, 0x01, 0x02, 0x1c, 0x2d, 0x01, 0x02, 0x20, 0x2d, 0x01, 0x02, 0x10, 0x0c, 0x02, 0x02, 0x14, 0x0c, 0x02, 0x02, + 0x18, 0x0c, 0x02, 0x02, 0x1c, 0x0c, 0x02, 0x02, 0x88, 0x29, 0x03, 0x03, 0x90, 0x29, 0x03, 0x03, 0x98, 0x29, 0x03, 0x03, 0x78, 0x09, 0x04, 0x03, 0x80, 0x09, 0x04, 0x03, 0x60, 0x25, 0x05, 0x04, + 0x70, 0x25, 0x05, 0x04, 0xe0, 0x06, 0x06, 0x04, 0xc0, 0x23, 0x07, 0x05, 0x80, 0x02, 0x0a, 0x06, 0x18, 0x01, 0x00, 0x02, 0x1c, 0x01, 0x00, 0x02, 0x20, 0x01, 0x00, 0x02, 0x24, 0x01, 0x00, 0x02, + 0x24, 0x2d, 0x01, 0x02, 0x28, 0x2d, 0x01, 0x02, 0x2c, 0x2d, 0x01, 0x02, 0x30, 0x2d, 0x01, 0x02, 0x34, 0x2d, 0x01, 0x02, 0x38, 0x2d, 0x01, 0x02, 0x20, 0x0c, 0x02, 0x02, 0x24, 0x0c, 0x02, 0x02, + 0x28, 0x0c, 0x02, 0x02, 0x2c, 0x0c, 0x02, 0x02, 0xa0, 0x29, 0x03, 0x03, 0xa8, 0x29, 0x03, 0x03, 0xb0, 0x29, 0x03, 0x03, 0x88, 0x09, 0x04, 0x03, 0x90, 0x09, 0x04, 0x03, 0x80, 0x25, 0x05, 0x04, + 0x90, 0x25, 0x05, 0x04, 0xf0, 0x06, 0x06, 0x04, 0xe0, 0x23, 0x07, 0x05, 0xc0, 0x02, 0x0a, 0x06, 0x28, 0x01, 0x00, 0x02, 0x2c, 0x01, 0x00, 0x02, 0x30, 0x01, 0x00, 0x02, 0x34, 0x01, 0x00, 0x02, + 0x3c, 0x2d, 0x01, 0x02, 0x40, 0x2d, 0x01, 0x02, 0x44, 0x2d, 0x01, 0x02, 0x48, 0x2d, 0x01, 0x02, 0x4c, 0x2d, 0x01, 0x02, 0x50, 0x2d, 0x01, 0x02, 0x30, 0x0c, 0x02, 0x02, 0x34, 0x0c, 0x02, 0x02, + 0x38, 0x0c, 0x02, 0x02, 0x3c, 0x0c, 0x02, 0x02, 0xb8, 0x29, 0x03, 0x03, 0xc0, 0x29, 0x03, 0x03, 0xc8, 0x29, 0x03, 0x03, 0x98, 0x09, 0x04, 0x03, 0xa0, 0x09, 0x04, 0x03, 0xa0, 0x25, 0x05, 0x04, + 0xb0, 0x25, 0x05, 0x04, 0x00, 0x07, 0x06, 0x04, 0x00, 0x24, 0x07, 0x05, 0x00, 0x03, 0x0a, 0x06, 0x38, 0x01, 0x00, 0x02, 0x3c, 0x01, 0x00, 0x02, 0x40, 0x01, 0x00, 0x02, 0x44, 0x01, 0x00, 0x02, + 0x54, 0x2d, 0x01, 0x02, 0x58, 0x2d, 0x01, 0x02, 0x5c, 0x2d, 0x01, 0x02, 0x60, 0x2d, 0x01, 0x02, 0x64, 0x2d, 0x01, 0x02, 0x68, 0x2d, 0x01, 0x02, 0x40, 0x0c, 0x02, 0x02, 0x44, 0x0c, 0x02, 0x02, + 0x48, 0x0c, 0x02, 0x02, 0x4c, 0x0c, 0x02, 0x02, 0xd0, 0x29, 0x03, 0x03, 0xd8, 0x29, 0x03, 0x03, 0xe0, 0x29, 0x03, 0x03, 0xa8, 0x09, 0x04, 0x03, 0xb0, 0x09, 0x04, 0x03, 0xc0, 0x25, 0x05, 0x04, + 0xd0, 0x25, 0x05, 0x04, 0x10, 0x07, 0x06, 0x04, 0x20, 0x24, 0x07, 0x05, 0x40, 0x03, 0x0a, 0x06, 0x48, 0x01, 0x00, 0x02, 0x4c, 0x01, 0x00, 0x02, 0x50, 0x01, 0x00, 0x02, 0x54, 0x01, 0x00, 0x02, + 0x6c, 0x2d, 0x01, 0x02, 0x70, 0x2d, 0x01, 0x02, 0x74, 0x2d, 0x01, 0x02, 0x78, 0x2d, 0x01, 0x02, 0x7c, 0x2d, 0x01, 0x02, 0x80, 0x2d, 0x01, 0x02, 0x50, 0x0c, 0x02, 0x02, 0x54, 0x0c, 0x02, 0x02, + 0x58, 0x0c, 0x02, 0x02, 0x5c, 0x0c, 0x02, 0x02, 0xe8, 0x29, 0x03, 0x03, 0xf0, 0x29, 0x03, 0x03, 0xf8, 0x29, 0x03, 0x03, 0xb8, 0x09, 0x04, 0x03, 0xc0, 0x09, 0x04, 0x03, 0xe0, 0x25, 0x05, 0x04, + 0xf0, 0x25, 0x05, 0x04, 0x20, 0x07, 0x06, 0x04, 0x40, 0x24, 0x07, 0x05, 0x80, 0x03, 0x0a, 0x06, 0x58, 0x01, 0x00, 0x02, 0x5c, 0x01, 0x00, 0x02, 0x60, 0x01, 0x00, 0x02, 0x64, 0x01, 0x00, 0x02, + 0x84, 0x2d, 0x01, 0x02, 0x88, 0x2d, 0x01, 0x02, 0x8c, 0x2d, 0x01, 0x02, 0x90, 0x2d, 0x01, 0x02, 0x94, 0x2d, 0x01, 0x02, 0x98, 0x2d, 0x01, 0x02, 0x60, 0x0c, 0x02, 0x02, 0x64, 0x0c, 0x02, 0x02, + 0x68, 0x0c, 0x02, 0x02, 0x6c, 0x0c, 0x02, 0x02, 0x00, 0x2a, 0x03, 0x03, 0x08, 0x2a, 0x03, 0x03, 0x10, 0x2a, 0x03, 0x03, 0xc8, 0x09, 0x04, 0x03, 0xd0, 0x09, 0x04, 0x03, 0x00, 0x26, 0x05, 0x04, + 0x10, 0x26, 0x05, 0x04, 0x30, 0x07, 0x06, 0x04, 0x60, 0x24, 0x07, 0x05, 0xc0, 0x03, 0x0a, 0x06, 0x68, 0x01, 0x00, 0x02, 0x6c, 0x01, 0x00, 0x02, 0x70, 0x01, 0x00, 0x02, 0x74, 0x01, 0x00, 0x02, + 0x9c, 0x2d, 0x01, 0x02, 0xa0, 0x2d, 0x01, 0x02, 0xa4, 0x2d, 0x01, 0x02, 0xa8, 0x2d, 0x01, 0x02, 0xac, 0x2d, 0x01, 0x02, 0xb0, 0x2d, 0x01, 0x02, 0x70, 0x0c, 0x02, 0x02, 0x74, 0x0c, 0x02, 0x02, + 0x78, 0x0c, 0x02, 0x02, 0x7c, 0x0c, 0x02, 0x02, 0x18, 0x2a, 0x03, 0x03, 0x20, 0x2a, 0x03, 0x03, 0x28, 0x2a, 0x03, 0x03, 0xd8, 0x09, 0x04, 0x03, 0xe0, 0x09, 0x04, 0x03, 0x20, 0x26, 0x05, 0x04, + 0x30, 0x26, 0x05, 0x04, 0x40, 0x07, 0x06, 0x04, 0x80, 0x02, 0x08, 0x05, 0x00, 0x04, 0x0a, 0x06, 0x78, 0x01, 0x00, 0x02, 0x7c, 0x01, 0x00, 0x02, 0x80, 0x01, 0x00, 0x02, 0x84, 0x01, 0x00, 0x02, + 0xb4, 0x2d, 0x01, 0x02, 0xb8, 0x2d, 0x01, 0x02, 0xbc, 0x2d, 0x01, 0x02, 0xc0, 0x2d, 0x01, 0x02, 0xc4, 0x2d, 0x01, 0x02, 0xc8, 0x2d, 0x01, 0x02, 0x80, 0x0c, 0x02, 0x02, 0x84, 0x0c, 0x02, 0x02, + 0x88, 0x0c, 0x02, 0x02, 0x8c, 0x0c, 0x02, 0x02, 0x30, 0x2a, 0x03, 0x03, 0x38, 0x2a, 0x03, 0x03, 0x40, 0x2a, 0x03, 0x03, 0xe8, 0x09, 0x04, 0x03, 0xf0, 0x09, 0x04, 0x03, 0x40, 0x26, 0x05, 0x04, + 0x50, 0x26, 0x05, 0x04, 0x50, 0x07, 0x06, 0x04, 0xa0, 0x02, 0x08, 0x05, 0x40, 0x04, 0x0a, 0x06, 0x88, 0x01, 0x00, 0x02, 0x8c, 0x01, 0x00, 0x02, 0x90, 0x01, 0x00, 0x02, 0x94, 0x01, 0x00, 0x02, + 0xcc, 0x2d, 0x01, 0x02, 0xd0, 0x2d, 0x01, 0x02, 0xd4, 0x2d, 0x01, 0x02, 0xd8, 0x2d, 0x01, 0x02, 0xdc, 0x2d, 0x01, 0x02, 0xe0, 0x2d, 0x01, 0x02, 0x90, 0x0c, 0x02, 0x02, 0x94, 0x0c, 0x02, 0x02, + 0x98, 0x0c, 0x02, 0x02, 0x9c, 0x0c, 0x02, 0x02, 0x48, 0x2a, 0x03, 0x03, 0x50, 0x2a, 0x03, 0x03, 0x58, 0x2a, 0x03, 0x03, 0xf8, 0x09, 0x04, 0x03, 0x00, 0x0a, 0x04, 0x03, 0x60, 0x26, 0x05, 0x04, + 0x70, 0x26, 0x05, 0x04, 0x60, 0x07, 0x06, 0x04, 0xc0, 0x02, 0x08, 0x05, 0x80, 0x04, 0x0a, 0x06, 0x98, 0x01, 0x00, 0x02, 0x9c, 0x01, 0x00, 0x02, 0xa0, 0x01, 0x00, 0x02, 0xa4, 0x01, 0x00, 0x02, + 0xe4, 0x2d, 0x01, 0x02, 0xe8, 0x2d, 0x01, 0x02, 0xec, 0x2d, 0x01, 0x02, 0xf0, 0x2d, 0x01, 0x02, 0xf4, 0x2d, 0x01, 0x02, 0xf8, 0x2d, 0x01, 0x02, 0xa0, 0x0c, 0x02, 0x02, 0xa4, 0x0c, 0x02, 0x02, + 0xa8, 0x0c, 0x02, 0x02, 0xac, 0x0c, 0x02, 0x02, 0x60, 0x2a, 0x03, 0x03, 0x68, 0x2a, 0x03, 0x03, 0x70, 0x2a, 0x03, 0x03, 0x08, 0x0a, 0x04, 0x03, 0x10, 0x0a, 0x04, 0x03, 0x80, 0x26, 0x05, 0x04, + 0x90, 0x26, 0x05, 0x04, 0x70, 0x07, 0x06, 0x04, 0xe0, 0x02, 0x08, 0x05, 0xc0, 0x04, 0x0a, 0x06, 0xa8, 0x01, 0x00, 0x02, 0xac, 0x01, 0x00, 0x02, 0xb0, 0x01, 0x00, 0x02, 0xb4, 0x01, 0x00, 0x02, + 0xfc, 0x2d, 0x01, 0x02, 0x00, 0x2e, 0x01, 0x02, 0x04, 0x2e, 0x01, 0x02, 0x08, 0x2e, 0x01, 0x02, 0x0c, 0x2e, 0x01, 0x02, 0x10, 0x2e, 0x01, 0x02, 0xb0, 0x0c, 0x02, 0x02, 0xb4, 0x0c, 0x02, 0x02, + 0xb8, 0x0c, 0x02, 0x02, 0xbc, 0x0c, 0x02, 0x02, 0x78, 0x2a, 0x03, 0x03, 0x80, 0x2a, 0x03, 0x03, 0x88, 0x2a, 0x03, 0x03, 0x18, 0x0a, 0x04, 0x03, 0x20, 0x0a, 0x04, 0x03, 0xa0, 0x26, 0x05, 0x04, + 0xb0, 0x26, 0x05, 0x04, 0x80, 0x07, 0x06, 0x04, 0x00, 0x03, 0x08, 0x05, 0x00, 0x05, 0x0a, 0x06, 0xb8, 0x01, 0x00, 0x02, 0xbc, 0x01, 0x00, 0x02, 0xc0, 0x01, 0x00, 0x02, 0xc4, 0x01, 0x00, 0x02, + 0x14, 0x2e, 0x01, 0x02, 0x18, 0x2e, 0x01, 0x02, 0x1c, 0x2e, 0x01, 0x02, 0x20, 0x2e, 0x01, 0x02, 0x24, 0x2e, 0x01, 0x02, 0x28, 0x2e, 0x01, 0x02, 0xc0, 0x0c, 0x02, 0x02, 0xc4, 0x0c, 0x02, 0x02, + 0xc8, 0x0c, 0x02, 0x02, 0xcc, 0x0c, 0x02, 0x02, 0x90, 0x2a, 0x03, 0x03, 0x98, 0x2a, 0x03, 0x03, 0xa0, 0x2a, 0x03, 0x03, 0x28, 0x0a, 0x04, 0x03, 0x30, 0x0a, 0x04, 0x03, 0xc0, 0x26, 0x05, 0x04, + 0xd0, 0x26, 0x05, 0x04, 0x90, 0x07, 0x06, 0x04, 0x20, 0x03, 0x08, 0x05, 0x00, 0x19, 0x0b, 0x07, 0xc8, 0x01, 0x00, 0x02, 0xcc, 0x01, 0x00, 0x02, 0xd0, 0x01, 0x00, 0x02, 0xd4, 0x01, 0x00, 0x02, + 0x2c, 0x2e, 0x01, 0x02, 0x30, 0x2e, 0x01, 0x02, 0x34, 0x2e, 0x01, 0x02, 0x38, 0x2e, 0x01, 0x02, 0x3c, 0x2e, 0x01, 0x02, 0x40, 0x2e, 0x01, 0x02, 0xd0, 0x0c, 0x02, 0x02, 0xd4, 0x0c, 0x02, 0x02, + 0xd8, 0x0c, 0x02, 0x02, 0xdc, 0x0c, 0x02, 0x02, 0xa8, 0x2a, 0x03, 0x03, 0xb0, 0x2a, 0x03, 0x03, 0xb8, 0x2a, 0x03, 0x03, 0x38, 0x0a, 0x04, 0x03, 0x40, 0x0a, 0x04, 0x03, 0xe0, 0x26, 0x05, 0x04, + 0xf0, 0x26, 0x05, 0x04, 0xa0, 0x07, 0x06, 0x04, 0x40, 0x03, 0x08, 0x05, 0x80, 0x19, 0x0b, 0x07, 0xd8, 0x01, 0x00, 0x02, 0xdc, 0x01, 0x00, 0x02, 0xe0, 0x01, 0x00, 0x02, 0xe4, 0x01, 0x00, 0x02, + 0x44, 0x2e, 0x01, 0x02, 0x48, 0x2e, 0x01, 0x02, 0x4c, 0x2e, 0x01, 0x02, 0x50, 0x2e, 0x01, 0x02, 0x54, 0x2e, 0x01, 0x02, 0x58, 0x2e, 0x01, 0x02, 0xe0, 0x0c, 0x02, 0x02, 0xe4, 0x0c, 0x02, 0x02, + 0xe8, 0x0c, 0x02, 0x02, 0xec, 0x0c, 0x02, 0x02, 0xc0, 0x2a, 0x03, 0x03, 0xc8, 0x2a, 0x03, 0x03, 0xd0, 0x2a, 0x03, 0x03, 0x48, 0x0a, 0x04, 0x03, 0x50, 0x0a, 0x04, 0x03, 0x00, 0x27, 0x05, 0x04, + 0x10, 0x27, 0x05, 0x04, 0xb0, 0x07, 0x06, 0x04, 0x60, 0x03, 0x08, 0x05, 0x00, 0x1a, 0x0b, 0x07, 0xe8, 0x01, 0x00, 0x02, 0xec, 0x01, 0x00, 0x02, 0xf0, 0x01, 0x00, 0x02, 0xf4, 0x01, 0x00, 0x02, + 0x5c, 0x2e, 0x01, 0x02, 0x60, 0x2e, 0x01, 0x02, 0x64, 0x2e, 0x01, 0x02, 0x68, 0x2e, 0x01, 0x02, 0x6c, 0x2e, 0x01, 0x02, 0x70, 0x2e, 0x01, 0x02, 0xf0, 0x0c, 0x02, 0x02, 0xf4, 0x0c, 0x02, 0x02, + 0xf8, 0x0c, 0x02, 0x02, 0xfc, 0x0c, 0x02, 0x02, 0xd8, 0x2a, 0x03, 0x03, 0xe0, 0x2a, 0x03, 0x03, 0xe8, 0x2a, 0x03, 0x03, 0x58, 0x0a, 0x04, 0x03, 0x60, 0x0a, 0x04, 0x03, 0x20, 0x27, 0x05, 0x04, + 0x30, 0x27, 0x05, 0x04, 0xc0, 0x07, 0x06, 0x04, 0x80, 0x03, 0x08, 0x05, 0x80, 0x1a, 0x0b, 0x07, 0xf8, 0x01, 0x00, 0x02, 0xfc, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x04, 0x02, 0x00, 0x02, + 0x74, 0x2e, 0x01, 0x02, 0x78, 0x2e, 0x01, 0x02, 0x7c, 0x2e, 0x01, 0x02, 0x80, 0x2e, 0x01, 0x02, 0x84, 0x2e, 0x01, 0x02, 0x88, 0x2e, 0x01, 0x02, 0x00, 0x0d, 0x02, 0x02, 0x04, 0x0d, 0x02, 0x02, + 0x08, 0x0d, 0x02, 0x02, 0x0c, 0x0d, 0x02, 0x02, 0xf0, 0x2a, 0x03, 0x03, 0xf8, 0x2a, 0x03, 0x03, 0x00, 0x2b, 0x03, 0x03, 0x68, 0x0a, 0x04, 0x03, 0x70, 0x0a, 0x04, 0x03, 0x40, 0x27, 0x05, 0x04, + 0x50, 0x27, 0x05, 0x04, 0xd0, 0x07, 0x06, 0x04, 0xa0, 0x03, 0x08, 0x05, 0x00, 0x1b, 0x0b, 0x07, 0x08, 0x02, 0x00, 0x02, 0x0c, 0x02, 0x00, 0x02, 0x10, 0x02, 0x00, 0x02, 0x14, 0x02, 0x00, 0x02, + 0x8c, 0x2e, 0x01, 0x02, 0x90, 0x2e, 0x01, 0x02, 0x94, 0x2e, 0x01, 0x02, 0x98, 0x2e, 0x01, 0x02, 0x9c, 0x2e, 0x01, 0x02, 0xa0, 0x2e, 0x01, 0x02, 0x10, 0x0d, 0x02, 0x02, 0x14, 0x0d, 0x02, 0x02, + 0x18, 0x0d, 0x02, 0x02, 0x1c, 0x0d, 0x02, 0x02, 0x08, 0x2b, 0x03, 0x03, 0x10, 0x2b, 0x03, 0x03, 0x18, 0x2b, 0x03, 0x03, 0x78, 0x0a, 0x04, 0x03, 0x80, 0x0a, 0x04, 0x03, 0x60, 0x27, 0x05, 0x04, + 0x70, 0x27, 0x05, 0x04, 0xe0, 0x07, 0x06, 0x04, 0xc0, 0x03, 0x08, 0x05, 0x80, 0x1b, 0x0b, 0x07, 0x18, 0x02, 0x00, 0x02, 0x1c, 0x02, 0x00, 0x02, 0x20, 0x02, 0x00, 0x02, 0x24, 0x02, 0x00, 0x02, + 0xa4, 0x2e, 0x01, 0x02, 0xa8, 0x2e, 0x01, 0x02, 0xac, 0x2e, 0x01, 0x02, 0xb0, 0x2e, 0x01, 0x02, 0xb4, 0x2e, 0x01, 0x02, 0xb8, 0x2e, 0x01, 0x02, 0x20, 0x0d, 0x02, 0x02, 0x24, 0x0d, 0x02, 0x02, + 0x28, 0x0d, 0x02, 0x02, 0x2c, 0x0d, 0x02, 0x02, 0x20, 0x2b, 0x03, 0x03, 0x28, 0x2b, 0x03, 0x03, 0x30, 0x2b, 0x03, 0x03, 0x88, 0x0a, 0x04, 0x03, 0x90, 0x0a, 0x04, 0x03, 0x80, 0x27, 0x05, 0x04, + 0x90, 0x27, 0x05, 0x04, 0xf0, 0x07, 0x06, 0x04, 0xe0, 0x03, 0x08, 0x05, 0x00, 0x1c, 0x0b, 0x07, 0x28, 0x02, 0x00, 0x02, 0x2c, 0x02, 0x00, 0x02, 0x30, 0x02, 0x00, 0x02, 0x34, 0x02, 0x00, 0x02, + 0xbc, 0x2e, 0x01, 0x02, 0xc0, 0x2e, 0x01, 0x02, 0xc4, 0x2e, 0x01, 0x02, 0xc8, 0x2e, 0x01, 0x02, 0xcc, 0x2e, 0x01, 0x02, 0xd0, 0x2e, 0x01, 0x02, 0x30, 0x0d, 0x02, 0x02, 0x34, 0x0d, 0x02, 0x02, + 0x38, 0x0d, 0x02, 0x02, 0x3c, 0x0d, 0x02, 0x02, 0x38, 0x2b, 0x03, 0x03, 0x40, 0x2b, 0x03, 0x03, 0x48, 0x2b, 0x03, 0x03, 0x98, 0x0a, 0x04, 0x03, 0xa0, 0x0a, 0x04, 0x03, 0xa0, 0x27, 0x05, 0x04, + 0xb0, 0x27, 0x05, 0x04, 0x00, 0x08, 0x06, 0x04, 0x00, 0x04, 0x08, 0x05, 0x80, 0x1c, 0x0b, 0x07, 0x38, 0x02, 0x00, 0x02, 0x3c, 0x02, 0x00, 0x02, 0x40, 0x02, 0x00, 0x02, 0x44, 0x02, 0x00, 0x02, + 0xd4, 0x2e, 0x01, 0x02, 0xd8, 0x2e, 0x01, 0x02, 0xdc, 0x2e, 0x01, 0x02, 0xe0, 0x2e, 0x01, 0x02, 0xe4, 0x2e, 0x01, 0x02, 0xe8, 0x2e, 0x01, 0x02, 0x40, 0x0d, 0x02, 0x02, 0x44, 0x0d, 0x02, 0x02, + 0x48, 0x0d, 0x02, 0x02, 0x4c, 0x0d, 0x02, 0x02, 0x50, 0x2b, 0x03, 0x03, 0x58, 0x2b, 0x03, 0x03, 0x60, 0x2b, 0x03, 0x03, 0xa8, 0x0a, 0x04, 0x03, 0xb0, 0x0a, 0x04, 0x03, 0xc0, 0x27, 0x05, 0x04, + 0xd0, 0x27, 0x05, 0x04, 0x10, 0x08, 0x06, 0x04, 0x20, 0x04, 0x08, 0x05, 0x00, 0x1d, 0x0b, 0x07, 0x48, 0x02, 0x00, 0x02, 0x4c, 0x02, 0x00, 0x02, 0x50, 0x02, 0x00, 0x02, 0x54, 0x02, 0x00, 0x02, + 0xec, 0x2e, 0x01, 0x02, 0xf0, 0x2e, 0x01, 0x02, 0xf4, 0x2e, 0x01, 0x02, 0xf8, 0x2e, 0x01, 0x02, 0xfc, 0x2e, 0x01, 0x02, 0x00, 0x2f, 0x01, 0x02, 0x50, 0x0d, 0x02, 0x02, 0x54, 0x0d, 0x02, 0x02, + 0x58, 0x0d, 0x02, 0x02, 0x5c, 0x0d, 0x02, 0x02, 0x68, 0x2b, 0x03, 0x03, 0x70, 0x2b, 0x03, 0x03, 0x78, 0x2b, 0x03, 0x03, 0xb8, 0x0a, 0x04, 0x03, 0xc0, 0x0a, 0x04, 0x03, 0xe0, 0x27, 0x05, 0x04, + 0xf0, 0x27, 0x05, 0x04, 0x20, 0x08, 0x06, 0x04, 0x40, 0x04, 0x08, 0x05, 0x80, 0x1d, 0x0b, 0x07, 0x58, 0x02, 0x00, 0x02, 0x5c, 0x02, 0x00, 0x02, 0x60, 0x02, 0x00, 0x02, 0x64, 0x02, 0x00, 0x02, + 0x04, 0x2f, 0x01, 0x02, 0x08, 0x2f, 0x01, 0x02, 0x0c, 0x2f, 0x01, 0x02, 0x10, 0x2f, 0x01, 0x02, 0x14, 0x2f, 0x01, 0x02, 0x18, 0x2f, 0x01, 0x02, 0x60, 0x0d, 0x02, 0x02, 0x64, 0x0d, 0x02, 0x02, + 0x68, 0x0d, 0x02, 0x02, 0x6c, 0x0d, 0x02, 0x02, 0x80, 0x2b, 0x03, 0x03, 0x88, 0x2b, 0x03, 0x03, 0x90, 0x2b, 0x03, 0x03, 0xc8, 0x0a, 0x04, 0x03, 0xd0, 0x0a, 0x04, 0x03, 0x00, 0x28, 0x05, 0x04, + 0x10, 0x28, 0x05, 0x04, 0x30, 0x08, 0x06, 0x04, 0x60, 0x04, 0x08, 0x05, 0x00, 0x1e, 0x0b, 0x07, 0x68, 0x02, 0x00, 0x02, 0x6c, 0x02, 0x00, 0x02, 0x70, 0x02, 0x00, 0x02, 0x74, 0x02, 0x00, 0x02, + 0x1c, 0x2f, 0x01, 0x02, 0x20, 0x2f, 0x01, 0x02, 0x24, 0x2f, 0x01, 0x02, 0x28, 0x2f, 0x01, 0x02, 0x2c, 0x2f, 0x01, 0x02, 0x30, 0x2f, 0x01, 0x02, 0x70, 0x0d, 0x02, 0x02, 0x74, 0x0d, 0x02, 0x02, + 0x78, 0x0d, 0x02, 0x02, 0x7c, 0x0d, 0x02, 0x02, 0x98, 0x2b, 0x03, 0x03, 0xa0, 0x2b, 0x03, 0x03, 0xa8, 0x2b, 0x03, 0x03, 0xd8, 0x0a, 0x04, 0x03, 0xe0, 0x0a, 0x04, 0x03, 0x20, 0x28, 0x05, 0x04, + 0x30, 0x28, 0x05, 0x04, 0x40, 0x08, 0x06, 0x04, 0x80, 0x04, 0x08, 0x05, 0x80, 0x1e, 0x0b, 0x07, 0x78, 0x02, 0x00, 0x02, 0x7c, 0x02, 0x00, 0x02, 0x80, 0x02, 0x00, 0x02, 0x84, 0x02, 0x00, 0x02, + 0x34, 0x2f, 0x01, 0x02, 0x38, 0x2f, 0x01, 0x02, 0x3c, 0x2f, 0x01, 0x02, 0x40, 0x2f, 0x01, 0x02, 0x44, 0x2f, 0x01, 0x02, 0x48, 0x2f, 0x01, 0x02, 0x80, 0x0d, 0x02, 0x02, 0x84, 0x0d, 0x02, 0x02, + 0x88, 0x0d, 0x02, 0x02, 0x8c, 0x0d, 0x02, 0x02, 0xb0, 0x2b, 0x03, 0x03, 0xb8, 0x2b, 0x03, 0x03, 0xc0, 0x2b, 0x03, 0x03, 0xe8, 0x0a, 0x04, 0x03, 0xf0, 0x0a, 0x04, 0x03, 0x40, 0x28, 0x05, 0x04, + 0x50, 0x28, 0x05, 0x04, 0x50, 0x08, 0x06, 0x04, 0xa0, 0x04, 0x08, 0x05, 0x00, 0x1f, 0x0b, 0x07, 0x88, 0x02, 0x00, 0x02, 0x8c, 0x02, 0x00, 0x02, 0x90, 0x02, 0x00, 0x02, 0x94, 0x02, 0x00, 0x02, + 0x4c, 0x2f, 0x01, 0x02, 0x50, 0x2f, 0x01, 0x02, 0x54, 0x2f, 0x01, 0x02, 0x58, 0x2f, 0x01, 0x02, 0x5c, 0x2f, 0x01, 0x02, 0x60, 0x2f, 0x01, 0x02, 0x90, 0x0d, 0x02, 0x02, 0x94, 0x0d, 0x02, 0x02, + 0x98, 0x0d, 0x02, 0x02, 0x9c, 0x0d, 0x02, 0x02, 0xc8, 0x2b, 0x03, 0x03, 0xd0, 0x2b, 0x03, 0x03, 0xd8, 0x2b, 0x03, 0x03, 0xf8, 0x0a, 0x04, 0x03, 0x00, 0x0b, 0x04, 0x03, 0x60, 0x28, 0x05, 0x04, + 0x70, 0x28, 0x05, 0x04, 0x60, 0x08, 0x06, 0x04, 0xc0, 0x04, 0x08, 0x05, 0x80, 0x1f, 0x0b, 0x07, 0x98, 0x02, 0x00, 0x02, 0x9c, 0x02, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x02, 0xa4, 0x02, 0x00, 0x02, + 0x64, 0x2f, 0x01, 0x02, 0x68, 0x2f, 0x01, 0x02, 0x6c, 0x2f, 0x01, 0x02, 0x70, 0x2f, 0x01, 0x02, 0x74, 0x2f, 0x01, 0x02, 0x78, 0x2f, 0x01, 0x02, 0xa0, 0x0d, 0x02, 0x02, 0xa4, 0x0d, 0x02, 0x02, + 0xa8, 0x0d, 0x02, 0x02, 0xac, 0x0d, 0x02, 0x02, 0xe0, 0x2b, 0x03, 0x03, 0xe8, 0x2b, 0x03, 0x03, 0xf0, 0x2b, 0x03, 0x03, 0x08, 0x0b, 0x04, 0x03, 0x10, 0x0b, 0x04, 0x03, 0x80, 0x28, 0x05, 0x04, + 0x90, 0x28, 0x05, 0x04, 0x70, 0x08, 0x06, 0x04, 0xe0, 0x04, 0x08, 0x05, 0x00, 0x3c, 0x0c, 0x08, 0xa8, 0x02, 0x00, 0x02, 0xac, 0x02, 0x00, 0x02, 0xb0, 0x02, 0x00, 0x02, 0xb4, 0x02, 0x00, 0x02, + 0x7c, 0x2f, 0x01, 0x02, 0x80, 0x2f, 0x01, 0x02, 0x84, 0x2f, 0x01, 0x02, 0x88, 0x2f, 0x01, 0x02, 0x8c, 0x2f, 0x01, 0x02, 0x90, 0x2f, 0x01, 0x02, 0xb0, 0x0d, 0x02, 0x02, 0xb4, 0x0d, 0x02, 0x02, + 0xb8, 0x0d, 0x02, 0x02, 0xbc, 0x0d, 0x02, 0x02, 0xf8, 0x2b, 0x03, 0x03, 0x00, 0x2c, 0x03, 0x03, 0x08, 0x2c, 0x03, 0x03, 0x18, 0x0b, 0x04, 0x03, 0x20, 0x0b, 0x04, 0x03, 0xa0, 0x28, 0x05, 0x04, + 0xb0, 0x28, 0x05, 0x04, 0x80, 0x08, 0x06, 0x04, 0x00, 0x05, 0x08, 0x05, 0x00, 0x3d, 0x0c, 0x08, 0xb8, 0x02, 0x00, 0x02, 0xbc, 0x02, 0x00, 0x02, 0xc0, 0x02, 0x00, 0x02, 0xc4, 0x02, 0x00, 0x02, + 0x94, 0x2f, 0x01, 0x02, 0x98, 0x2f, 0x01, 0x02, 0x9c, 0x2f, 0x01, 0x02, 0xa0, 0x2f, 0x01, 0x02, 0xa4, 0x2f, 0x01, 0x02, 0xa8, 0x2f, 0x01, 0x02, 0xc0, 0x0d, 0x02, 0x02, 0xc4, 0x0d, 0x02, 0x02, + 0xc8, 0x0d, 0x02, 0x02, 0xcc, 0x0d, 0x02, 0x02, 0x10, 0x2c, 0x03, 0x03, 0x18, 0x2c, 0x03, 0x03, 0x20, 0x2c, 0x03, 0x03, 0x28, 0x0b, 0x04, 0x03, 0x30, 0x0b, 0x04, 0x03, 0xc0, 0x28, 0x05, 0x04, + 0xd0, 0x28, 0x05, 0x04, 0x90, 0x08, 0x06, 0x04, 0x20, 0x05, 0x08, 0x05, 0x00, 0x3e, 0x0c, 0x08, 0xc8, 0x02, 0x00, 0x02, 0xcc, 0x02, 0x00, 0x02, 0xd0, 0x02, 0x00, 0x02, 0xd4, 0x02, 0x00, 0x02, + 0xac, 0x2f, 0x01, 0x02, 0xb0, 0x2f, 0x01, 0x02, 0xb4, 0x2f, 0x01, 0x02, 0xb8, 0x2f, 0x01, 0x02, 0xbc, 0x2f, 0x01, 0x02, 0xc0, 0x2f, 0x01, 0x02, 0xd0, 0x0d, 0x02, 0x02, 0xd4, 0x0d, 0x02, 0x02, + 0xd8, 0x0d, 0x02, 0x02, 0xdc, 0x0d, 0x02, 0x02, 0x28, 0x2c, 0x03, 0x03, 0x30, 0x2c, 0x03, 0x03, 0x38, 0x2c, 0x03, 0x03, 0x38, 0x0b, 0x04, 0x03, 0x40, 0x0b, 0x04, 0x03, 0xe0, 0x28, 0x05, 0x04, + 0xf0, 0x28, 0x05, 0x04, 0xa0, 0x08, 0x06, 0x04, 0x40, 0x05, 0x08, 0x05, 0x00, 0x3f, 0x0c, 0x08, 0xd8, 0x02, 0x00, 0x02, 0xdc, 0x02, 0x00, 0x02, 0xe0, 0x02, 0x00, 0x02, 0xe4, 0x02, 0x00, 0x02, + 0xc4, 0x2f, 0x01, 0x02, 0xc8, 0x2f, 0x01, 0x02, 0xcc, 0x2f, 0x01, 0x02, 0xd0, 0x2f, 0x01, 0x02, 0xd4, 0x2f, 0x01, 0x02, 0xd8, 0x2f, 0x01, 0x02, 0xe0, 0x0d, 0x02, 0x02, 0xe4, 0x0d, 0x02, 0x02, + 0xe8, 0x0d, 0x02, 0x02, 0xec, 0x0d, 0x02, 0x02, 0x40, 0x2c, 0x03, 0x03, 0x48, 0x2c, 0x03, 0x03, 0x50, 0x2c, 0x03, 0x03, 0x48, 0x0b, 0x04, 0x03, 0x50, 0x0b, 0x04, 0x03, 0x00, 0x29, 0x05, 0x04, + 0x10, 0x29, 0x05, 0x04, 0xb0, 0x08, 0x06, 0x04, 0x60, 0x05, 0x08, 0x05, 0x00, 0x00, 0x0c, 0x07, 0xe8, 0x02, 0x00, 0x02, 0xec, 0x02, 0x00, 0x02, 0xf0, 0x02, 0x00, 0x02, 0xdc, 0x2f, 0x01, 0x02, + 0xe0, 0x2f, 0x01, 0x02, 0xe4, 0x2f, 0x01, 0x02, 0xe8, 0x2f, 0x01, 0x02, 0xec, 0x2f, 0x01, 0x02, 0xf0, 0x2f, 0x01, 0x02, 0xf4, 0x2f, 0x01, 0x02, 0xf0, 0x0d, 0x02, 0x02, 0xf4, 0x0d, 0x02, 0x02, + 0xf8, 0x0d, 0x02, 0x02, 0xfc, 0x0d, 0x02, 0x02, 0x58, 0x2c, 0x03, 0x03, 0x60, 0x2c, 0x03, 0x03, 0x68, 0x2c, 0x03, 0x03, 0x58, 0x0b, 0x04, 0x03, 0x60, 0x0b, 0x04, 0x03, 0x20, 0x29, 0x05, 0x04, + 0x30, 0x29, 0x05, 0x04, 0xc0, 0x08, 0x06, 0x04, 0x80, 0x05, 0x08, 0x05, 0x80, 0x00, 0x0c, 0x07, 0xf4, 0x02, 0x00, 0x02, 0xf8, 0x02, 0x00, 0x02, 0xfc, 0x02, 0x00, 0x02, 0xf8, 0x2f, 0x01, 0x02, + 0xfc, 0x2f, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x04, 0x30, 0x01, 0x02, 0x08, 0x30, 0x01, 0x02, 0x0c, 0x30, 0x01, 0x02, 0x10, 0x30, 0x01, 0x02, 0x00, 0x0e, 0x02, 0x02, 0x04, 0x0e, 0x02, 0x02, + 0x08, 0x0e, 0x02, 0x02, 0x0c, 0x0e, 0x02, 0x02, 0x70, 0x2c, 0x03, 0x03, 0x78, 0x2c, 0x03, 0x03, 0x80, 0x2c, 0x03, 0x03, 0x68, 0x0b, 0x04, 0x03, 0x70, 0x0b, 0x04, 0x03, 0x40, 0x29, 0x05, 0x04, + 0xd0, 0x08, 0x06, 0x04, 0xe0, 0x08, 0x06, 0x04, 0xa0, 0x05, 0x08, 0x05, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x03, 0x00, 0x02, 0x04, 0x03, 0x00, 0x02, 0x08, 0x03, 0x00, 0x02, 0x14, 0x30, 0x01, 0x02, + 0x18, 0x30, 0x01, 0x02, 0x1c, 0x30, 0x01, 0x02, 0x20, 0x30, 0x01, 0x02, 0x24, 0x30, 0x01, 0x02, 0x28, 0x30, 0x01, 0x02, 0x2c, 0x30, 0x01, 0x02, 0x10, 0x0e, 0x02, 0x02, 0x14, 0x0e, 0x02, 0x02, + 0x18, 0x0e, 0x02, 0x02, 0x1c, 0x0e, 0x02, 0x02, 0x88, 0x2c, 0x03, 0x03, 0x90, 0x2c, 0x03, 0x03, 0x98, 0x2c, 0x03, 0x03, 0x78, 0x0b, 0x04, 0x03, 0x80, 0x0b, 0x04, 0x03, 0x50, 0x29, 0x05, 0x04, + 0xf0, 0x08, 0x06, 0x04, 0x80, 0x24, 0x07, 0x05, 0xc0, 0x05, 0x08, 0x05, 0x80, 0x01, 0x0c, 0x07, 0x0c, 0x03, 0x00, 0x02, 0x10, 0x03, 0x00, 0x02, 0x14, 0x03, 0x00, 0x02, 0x30, 0x30, 0x01, 0x02, + 0x34, 0x30, 0x01, 0x02, 0x38, 0x30, 0x01, 0x02, 0x3c, 0x30, 0x01, 0x02, 0x40, 0x30, 0x01, 0x02, 0x44, 0x30, 0x01, 0x02, 0x48, 0x30, 0x01, 0x02, 0x20, 0x0e, 0x02, 0x02, 0x24, 0x0e, 0x02, 0x02, + 0x28, 0x0e, 0x02, 0x02, 0x2c, 0x0e, 0x02, 0x02, 0xa0, 0x2c, 0x03, 0x03, 0xa8, 0x2c, 0x03, 0x03, 0xb0, 0x2c, 0x03, 0x03, 0x88, 0x0b, 0x04, 0x03, 0x90, 0x0b, 0x04, 0x03, 0x60, 0x29, 0x05, 0x04, + 0x00, 0x09, 0x06, 0x04, 0xa0, 0x24, 0x07, 0x05, 0xe0, 0x05, 0x08, 0x05, 0x00, 0x02, 0x0c, 0x07, 0x18, 0x03, 0x00, 0x02, 0x1c, 0x03, 0x00, 0x02, 0x20, 0x03, 0x00, 0x02, 0x4c, 0x30, 0x01, 0x02, + 0x50, 0x30, 0x01, 0x02, 0x54, 0x30, 0x01, 0x02, 0x58, 0x30, 0x01, 0x02, 0x5c, 0x30, 0x01, 0x02, 0x60, 0x30, 0x01, 0x02, 0x64, 0x30, 0x01, 0x02, 0x30, 0x0e, 0x02, 0x02, 0x34, 0x0e, 0x02, 0x02, + 0x38, 0x0e, 0x02, 0x02, 0x3c, 0x0e, 0x02, 0x02, 0xb8, 0x2c, 0x03, 0x03, 0xc0, 0x2c, 0x03, 0x03, 0xc8, 0x2c, 0x03, 0x03, 0x98, 0x0b, 0x04, 0x03, 0xa0, 0x0b, 0x04, 0x03, 0x70, 0x29, 0x05, 0x04, + 0x10, 0x09, 0x06, 0x04, 0xc0, 0x24, 0x07, 0x05, 0x00, 0x06, 0x08, 0x05, 0x00, 0x16, 0x0d, 0x08, 0x24, 0x03, 0x00, 0x02, 0x28, 0x03, 0x00, 0x02, 0x2c, 0x03, 0x00, 0x02, 0x68, 0x30, 0x01, 0x02, + 0x6c, 0x30, 0x01, 0x02, 0x70, 0x30, 0x01, 0x02, 0x74, 0x30, 0x01, 0x02, 0x78, 0x30, 0x01, 0x02, 0x7c, 0x30, 0x01, 0x02, 0x80, 0x30, 0x01, 0x02, 0x40, 0x0e, 0x02, 0x02, 0x44, 0x0e, 0x02, 0x02, + 0x48, 0x0e, 0x02, 0x02, 0x4c, 0x0e, 0x02, 0x02, 0xd0, 0x2c, 0x03, 0x03, 0xd8, 0x2c, 0x03, 0x03, 0xe0, 0x2c, 0x03, 0x03, 0xa8, 0x0b, 0x04, 0x03, 0xb0, 0x0b, 0x04, 0x03, 0x80, 0x29, 0x05, 0x04, + 0x20, 0x09, 0x06, 0x04, 0xe0, 0x24, 0x07, 0x05, 0x20, 0x06, 0x08, 0x05, 0x00, 0x17, 0x0d, 0x08, 0x30, 0x03, 0x00, 0x02, 0x34, 0x03, 0x00, 0x02, 0x38, 0x03, 0x00, 0x02, 0x84, 0x30, 0x01, 0x02, + 0x88, 0x30, 0x01, 0x02, 0x8c, 0x30, 0x01, 0x02, 0x90, 0x30, 0x01, 0x02, 0x94, 0x30, 0x01, 0x02, 0x98, 0x30, 0x01, 0x02, 0x9c, 0x30, 0x01, 0x02, 0x50, 0x0e, 0x02, 0x02, 0x54, 0x0e, 0x02, 0x02, + 0x58, 0x0e, 0x02, 0x02, 0x5c, 0x0e, 0x02, 0x02, 0xe8, 0x2c, 0x03, 0x03, 0xf0, 0x2c, 0x03, 0x03, 0xf8, 0x2c, 0x03, 0x03, 0xb8, 0x0b, 0x04, 0x03, 0xc0, 0x0b, 0x04, 0x03, 0x90, 0x29, 0x05, 0x04, + 0x30, 0x09, 0x06, 0x04, 0x00, 0x25, 0x07, 0x05, 0x40, 0x06, 0x08, 0x05, 0x00, 0x18, 0x0d, 0x08, 0x3c, 0x03, 0x00, 0x02, 0x40, 0x03, 0x00, 0x02, 0x44, 0x03, 0x00, 0x02, 0xa0, 0x30, 0x01, 0x02, + 0xa4, 0x30, 0x01, 0x02, 0xa8, 0x30, 0x01, 0x02, 0xac, 0x30, 0x01, 0x02, 0xb0, 0x30, 0x01, 0x02, 0xb4, 0x30, 0x01, 0x02, 0xb8, 0x30, 0x01, 0x02, 0x60, 0x0e, 0x02, 0x02, 0x64, 0x0e, 0x02, 0x02, + 0x68, 0x0e, 0x02, 0x02, 0x6c, 0x0e, 0x02, 0x02, 0x00, 0x2d, 0x03, 0x03, 0x08, 0x2d, 0x03, 0x03, 0x10, 0x2d, 0x03, 0x03, 0xc8, 0x0b, 0x04, 0x03, 0xd0, 0x0b, 0x04, 0x03, 0xa0, 0x29, 0x05, 0x04, + 0x40, 0x09, 0x06, 0x04, 0x20, 0x25, 0x07, 0x05, 0x60, 0x06, 0x08, 0x05, 0x00, 0x19, 0x0d, 0x08, 0x48, 0x03, 0x00, 0x02, 0x4c, 0x03, 0x00, 0x02, 0x50, 0x03, 0x00, 0x02, 0xbc, 0x30, 0x01, 0x02, + 0xc0, 0x30, 0x01, 0x02, 0xc4, 0x30, 0x01, 0x02, 0xc8, 0x30, 0x01, 0x02, 0xcc, 0x30, 0x01, 0x02, 0xd0, 0x30, 0x01, 0x02, 0xd4, 0x30, 0x01, 0x02, 0x70, 0x0e, 0x02, 0x02, 0x74, 0x0e, 0x02, 0x02, + 0x78, 0x0e, 0x02, 0x02, 0x7c, 0x0e, 0x02, 0x02, 0x18, 0x2d, 0x03, 0x03, 0x20, 0x2d, 0x03, 0x03, 0x28, 0x2d, 0x03, 0x03, 0xd8, 0x0b, 0x04, 0x03, 0xe0, 0x0b, 0x04, 0x03, 0xb0, 0x29, 0x05, 0x04, + 0x50, 0x09, 0x06, 0x04, 0x40, 0x25, 0x07, 0x05, 0x80, 0x06, 0x08, 0x05, 0x00, 0x1a, 0x0d, 0x08, 0x54, 0x03, 0x00, 0x02, 0x58, 0x03, 0x00, 0x02, 0x5c, 0x03, 0x00, 0x02, 0xd8, 0x30, 0x01, 0x02, + 0xdc, 0x30, 0x01, 0x02, 0xe0, 0x30, 0x01, 0x02, 0xe4, 0x30, 0x01, 0x02, 0xe8, 0x30, 0x01, 0x02, 0xec, 0x30, 0x01, 0x02, 0xf0, 0x30, 0x01, 0x02, 0x80, 0x0e, 0x02, 0x02, 0x84, 0x0e, 0x02, 0x02, + 0x88, 0x0e, 0x02, 0x02, 0x8c, 0x0e, 0x02, 0x02, 0x30, 0x2d, 0x03, 0x03, 0x38, 0x2d, 0x03, 0x03, 0x40, 0x2d, 0x03, 0x03, 0xe8, 0x0b, 0x04, 0x03, 0xf0, 0x0b, 0x04, 0x03, 0xc0, 0x29, 0x05, 0x04, + 0x60, 0x09, 0x06, 0x04, 0x60, 0x25, 0x07, 0x05, 0xa0, 0x06, 0x08, 0x05, 0x00, 0x1b, 0x0d, 0x08, 0x60, 0x03, 0x00, 0x02, 0x64, 0x03, 0x00, 0x02, 0x68, 0x03, 0x00, 0x02, 0xf4, 0x30, 0x01, 0x02, + 0xf8, 0x30, 0x01, 0x02, 0xfc, 0x30, 0x01, 0x02, 0x00, 0x31, 0x01, 0x02, 0x04, 0x31, 0x01, 0x02, 0x08, 0x31, 0x01, 0x02, 0x0c, 0x31, 0x01, 0x02, 0x90, 0x0e, 0x02, 0x02, 0x94, 0x0e, 0x02, 0x02, + 0x98, 0x0e, 0x02, 0x02, 0x9c, 0x0e, 0x02, 0x02, 0x48, 0x2d, 0x03, 0x03, 0x50, 0x2d, 0x03, 0x03, 0x58, 0x2d, 0x03, 0x03, 0xf8, 0x0b, 0x04, 0x03, 0x00, 0x0c, 0x04, 0x03, 0xd0, 0x29, 0x05, 0x04, + 0x70, 0x09, 0x06, 0x04, 0x80, 0x25, 0x07, 0x05, 0xc0, 0x06, 0x08, 0x05, 0x00, 0x1c, 0x0d, 0x08, 0x6c, 0x03, 0x00, 0x02, 0x70, 0x03, 0x00, 0x02, 0x74, 0x03, 0x00, 0x02, 0x10, 0x31, 0x01, 0x02, + 0x14, 0x31, 0x01, 0x02, 0x18, 0x31, 0x01, 0x02, 0x1c, 0x31, 0x01, 0x02, 0x20, 0x31, 0x01, 0x02, 0x24, 0x31, 0x01, 0x02, 0x28, 0x31, 0x01, 0x02, 0xa0, 0x0e, 0x02, 0x02, 0xa4, 0x0e, 0x02, 0x02, + 0xa8, 0x0e, 0x02, 0x02, 0xac, 0x0e, 0x02, 0x02, 0x60, 0x2d, 0x03, 0x03, 0x68, 0x2d, 0x03, 0x03, 0x70, 0x2d, 0x03, 0x03, 0x08, 0x0c, 0x04, 0x03, 0x10, 0x0c, 0x04, 0x03, 0xe0, 0x29, 0x05, 0x04, + 0x80, 0x09, 0x06, 0x04, 0xa0, 0x25, 0x07, 0x05, 0xe0, 0x06, 0x08, 0x05, 0x00, 0x38, 0x0e, 0x09, 0x78, 0x03, 0x00, 0x02, 0x7c, 0x03, 0x00, 0x02, 0x80, 0x03, 0x00, 0x02, 0x2c, 0x31, 0x01, 0x02, + 0x30, 0x31, 0x01, 0x02, 0x34, 0x31, 0x01, 0x02, 0x38, 0x31, 0x01, 0x02, 0x3c, 0x31, 0x01, 0x02, 0x40, 0x31, 0x01, 0x02, 0x44, 0x31, 0x01, 0x02, 0xb0, 0x0e, 0x02, 0x02, 0xb4, 0x0e, 0x02, 0x02, + 0xb8, 0x0e, 0x02, 0x02, 0xbc, 0x0e, 0x02, 0x02, 0x78, 0x2d, 0x03, 0x03, 0x80, 0x2d, 0x03, 0x03, 0x88, 0x2d, 0x03, 0x03, 0x18, 0x0c, 0x04, 0x03, 0x20, 0x0c, 0x04, 0x03, 0xf0, 0x29, 0x05, 0x04, + 0x90, 0x09, 0x06, 0x04, 0xc0, 0x25, 0x07, 0x05, 0x00, 0x07, 0x08, 0x05, 0x00, 0x3a, 0x0e, 0x09, 0x84, 0x03, 0x00, 0x02, 0x88, 0x03, 0x00, 0x02, 0x8c, 0x03, 0x00, 0x02, 0x48, 0x31, 0x01, 0x02, + 0x4c, 0x31, 0x01, 0x02, 0x50, 0x31, 0x01, 0x02, 0x54, 0x31, 0x01, 0x02, 0x58, 0x31, 0x01, 0x02, 0x5c, 0x31, 0x01, 0x02, 0x60, 0x31, 0x01, 0x02, 0xc0, 0x0e, 0x02, 0x02, 0xc4, 0x0e, 0x02, 0x02, + 0xc8, 0x0e, 0x02, 0x02, 0xcc, 0x0e, 0x02, 0x02, 0x90, 0x2d, 0x03, 0x03, 0x98, 0x2d, 0x03, 0x03, 0xa0, 0x2d, 0x03, 0x03, 0x28, 0x0c, 0x04, 0x03, 0x30, 0x0c, 0x04, 0x03, 0x00, 0x2a, 0x05, 0x04, + 0xa0, 0x09, 0x06, 0x04, 0xe0, 0x25, 0x07, 0x05, 0x20, 0x07, 0x08, 0x05, 0x00, 0x3c, 0x0e, 0x09, 0x90, 0x03, 0x00, 0x02, 0x94, 0x03, 0x00, 0x02, 0x98, 0x03, 0x00, 0x02, 0x64, 0x31, 0x01, 0x02, + 0x68, 0x31, 0x01, 0x02, 0x6c, 0x31, 0x01, 0x02, 0x70, 0x31, 0x01, 0x02, 0x74, 0x31, 0x01, 0x02, 0x78, 0x31, 0x01, 0x02, 0x7c, 0x31, 0x01, 0x02, 0xd0, 0x0e, 0x02, 0x02, 0xd4, 0x0e, 0x02, 0x02, + 0xd8, 0x0e, 0x02, 0x02, 0xdc, 0x0e, 0x02, 0x02, 0xa8, 0x2d, 0x03, 0x03, 0xb0, 0x2d, 0x03, 0x03, 0xb8, 0x2d, 0x03, 0x03, 0x38, 0x0c, 0x04, 0x03, 0x40, 0x0c, 0x04, 0x03, 0x10, 0x2a, 0x05, 0x04, + 0xb0, 0x09, 0x06, 0x04, 0x00, 0x26, 0x07, 0x05, 0x40, 0x07, 0x08, 0x05, 0x00, 0x3e, 0x0e, 0x09, 0x9c, 0x03, 0x00, 0x02, 0xa0, 0x03, 0x00, 0x02, 0xa4, 0x03, 0x00, 0x02, 0x80, 0x31, 0x01, 0x02, + 0x84, 0x31, 0x01, 0x02, 0x88, 0x31, 0x01, 0x02, 0x8c, 0x31, 0x01, 0x02, 0x90, 0x31, 0x01, 0x02, 0x94, 0x31, 0x01, 0x02, 0x98, 0x31, 0x01, 0x02, 0xe0, 0x0e, 0x02, 0x02, 0xe4, 0x0e, 0x02, 0x02, + 0xe8, 0x0e, 0x02, 0x02, 0xec, 0x0e, 0x02, 0x02, 0xc0, 0x2d, 0x03, 0x03, 0xc8, 0x2d, 0x03, 0x03, 0xd0, 0x2d, 0x03, 0x03, 0x48, 0x0c, 0x04, 0x03, 0x50, 0x0c, 0x04, 0x03, 0x20, 0x2a, 0x05, 0x04, + 0xc0, 0x09, 0x06, 0x04, 0x20, 0x26, 0x07, 0x05, 0x60, 0x07, 0x08, 0x05, 0x00, 0x00, 0x0e, 0x08, 0xa8, 0x03, 0x00, 0x02, 0xac, 0x03, 0x00, 0x02, 0xb0, 0x03, 0x00, 0x02, 0x9c, 0x31, 0x01, 0x02, + 0xa0, 0x31, 0x01, 0x02, 0xa4, 0x31, 0x01, 0x02, 0xa8, 0x31, 0x01, 0x02, 0xac, 0x31, 0x01, 0x02, 0xb0, 0x31, 0x01, 0x02, 0xf0, 0x0e, 0x02, 0x02, 0xf4, 0x0e, 0x02, 0x02, 0xf8, 0x0e, 0x02, 0x02, + 0xfc, 0x0e, 0x02, 0x02, 0x00, 0x0f, 0x02, 0x02, 0xd8, 0x2d, 0x03, 0x03, 0xe0, 0x2d, 0x03, 0x03, 0xe8, 0x2d, 0x03, 0x03, 0x58, 0x0c, 0x04, 0x03, 0x60, 0x0c, 0x04, 0x03, 0x30, 0x2a, 0x05, 0x04, + 0xd0, 0x09, 0x06, 0x04, 0x40, 0x26, 0x07, 0x05, 0x80, 0x07, 0x08, 0x05, 0x00, 0x18, 0x0f, 0x09, 0xb4, 0x03, 0x00, 0x02, 0xb8, 0x03, 0x00, 0x02, 0xbc, 0x03, 0x00, 0x02, 0xb4, 0x31, 0x01, 0x02, + 0xb8, 0x31, 0x01, 0x02, 0xbc, 0x31, 0x01, 0x02, 0xc0, 0x31, 0x01, 0x02, 0xc4, 0x31, 0x01, 0x02, 0xc8, 0x31, 0x01, 0x02, 0x04, 0x0f, 0x02, 0x02, 0x08, 0x0f, 0x02, 0x02, 0x0c, 0x0f, 0x02, 0x02, + 0x10, 0x0f, 0x02, 0x02, 0x14, 0x0f, 0x02, 0x02, 0xf0, 0x2d, 0x03, 0x03, 0xf8, 0x2d, 0x03, 0x03, 0x00, 0x2e, 0x03, 0x03, 0x68, 0x0c, 0x04, 0x03, 0x70, 0x0c, 0x04, 0x03, 0x40, 0x2a, 0x05, 0x04, + 0xe0, 0x09, 0x06, 0x04, 0x60, 0x26, 0x07, 0x05, 0x80, 0x22, 0x09, 0x06, 0x00, 0x1a, 0x0f, 0x09, 0xc0, 0x03, 0x00, 0x02, 0xc4, 0x03, 0x00, 0x02, 0xc8, 0x03, 0x00, 0x02, 0xcc, 0x31, 0x01, 0x02, + 0xd0, 0x31, 0x01, 0x02, 0xd4, 0x31, 0x01, 0x02, 0xd8, 0x31, 0x01, 0x02, 0xdc, 0x31, 0x01, 0x02, 0xe0, 0x31, 0x01, 0x02, 0x18, 0x0f, 0x02, 0x02, 0x1c, 0x0f, 0x02, 0x02, 0x20, 0x0f, 0x02, 0x02, + 0x24, 0x0f, 0x02, 0x02, 0x28, 0x0f, 0x02, 0x02, 0x08, 0x2e, 0x03, 0x03, 0x10, 0x2e, 0x03, 0x03, 0x18, 0x2e, 0x03, 0x03, 0x78, 0x0c, 0x04, 0x03, 0x80, 0x0c, 0x04, 0x03, 0x50, 0x2a, 0x05, 0x04, + 0xf0, 0x09, 0x06, 0x04, 0x80, 0x26, 0x07, 0x05, 0xc0, 0x22, 0x09, 0x06, 0x00, 0x1c, 0x0f, 0x09, 0xcc, 0x03, 0x00, 0x02, 0xd0, 0x03, 0x00, 0x02, 0xd4, 0x03, 0x00, 0x02, 0xe4, 0x31, 0x01, 0x02, + 0xe8, 0x31, 0x01, 0x02, 0xec, 0x31, 0x01, 0x02, 0xf0, 0x31, 0x01, 0x02, 0xf4, 0x31, 0x01, 0x02, 0xf8, 0x31, 0x01, 0x02, 0x2c, 0x0f, 0x02, 0x02, 0x30, 0x0f, 0x02, 0x02, 0x34, 0x0f, 0x02, 0x02, + 0x38, 0x0f, 0x02, 0x02, 0x3c, 0x0f, 0x02, 0x02, 0x20, 0x2e, 0x03, 0x03, 0x28, 0x2e, 0x03, 0x03, 0x30, 0x2e, 0x03, 0x03, 0x88, 0x0c, 0x04, 0x03, 0x90, 0x0c, 0x04, 0x03, 0x60, 0x2a, 0x05, 0x04, + 0x00, 0x0a, 0x06, 0x04, 0xa0, 0x26, 0x07, 0x05, 0x00, 0x23, 0x09, 0x06, 0x00, 0x38, 0x10, 0x0a, 0xd8, 0x03, 0x00, 0x02, 0xdc, 0x03, 0x00, 0x02, 0xe0, 0x03, 0x00, 0x02, 0xfc, 0x31, 0x01, 0x02, + 0x00, 0x32, 0x01, 0x02, 0x04, 0x32, 0x01, 0x02, 0x08, 0x32, 0x01, 0x02, 0x0c, 0x32, 0x01, 0x02, 0x10, 0x32, 0x01, 0x02, 0x40, 0x0f, 0x02, 0x02, 0x44, 0x0f, 0x02, 0x02, 0x48, 0x0f, 0x02, 0x02, + 0x4c, 0x0f, 0x02, 0x02, 0x50, 0x0f, 0x02, 0x02, 0x38, 0x2e, 0x03, 0x03, 0x40, 0x2e, 0x03, 0x03, 0x48, 0x2e, 0x03, 0x03, 0x98, 0x0c, 0x04, 0x03, 0xa0, 0x0c, 0x04, 0x03, 0x70, 0x2a, 0x05, 0x04, + 0x10, 0x0a, 0x06, 0x04, 0xc0, 0x26, 0x07, 0x05, 0x40, 0x23, 0x09, 0x06, 0x00, 0x3c, 0x10, 0x0a, 0xe4, 0x03, 0x00, 0x02, 0xe8, 0x03, 0x00, 0x02, 0xec, 0x03, 0x00, 0x02, 0x14, 0x32, 0x01, 0x02, + 0x18, 0x32, 0x01, 0x02, 0x1c, 0x32, 0x01, 0x02, 0x20, 0x32, 0x01, 0x02, 0x24, 0x32, 0x01, 0x02, 0x28, 0x32, 0x01, 0x02, 0x54, 0x0f, 0x02, 0x02, 0x58, 0x0f, 0x02, 0x02, 0x5c, 0x0f, 0x02, 0x02, + 0x60, 0x0f, 0x02, 0x02, 0x64, 0x0f, 0x02, 0x02, 0x50, 0x2e, 0x03, 0x03, 0x58, 0x2e, 0x03, 0x03, 0x60, 0x2e, 0x03, 0x03, 0xa8, 0x0c, 0x04, 0x03, 0xb0, 0x0c, 0x04, 0x03, 0x80, 0x2a, 0x05, 0x04, + 0x20, 0x0a, 0x06, 0x04, 0xe0, 0x26, 0x07, 0x05, 0x80, 0x23, 0x09, 0x06, 0x00, 0x00, 0x10, 0x09, 0xf0, 0x03, 0x00, 0x02, 0xf4, 0x03, 0x00, 0x02, 0xf8, 0x03, 0x00, 0x02, 0x2c, 0x32, 0x01, 0x02, + 0x30, 0x32, 0x01, 0x02, 0x34, 0x32, 0x01, 0x02, 0x38, 0x32, 0x01, 0x02, 0x3c, 0x32, 0x01, 0x02, 0x40, 0x32, 0x01, 0x02, 0x68, 0x0f, 0x02, 0x02, 0x6c, 0x0f, 0x02, 0x02, 0x70, 0x0f, 0x02, 0x02, + 0x74, 0x0f, 0x02, 0x02, 0x78, 0x0f, 0x02, 0x02, 0x68, 0x2e, 0x03, 0x03, 0x70, 0x2e, 0x03, 0x03, 0x78, 0x2e, 0x03, 0x03, 0xb8, 0x0c, 0x04, 0x03, 0xc0, 0x0c, 0x04, 0x03, 0x90, 0x2a, 0x05, 0x04, + 0x30, 0x0a, 0x06, 0x04, 0x00, 0x27, 0x07, 0x05, 0xc0, 0x23, 0x09, 0x06, 0x00, 0x14, 0x11, 0x0a, 0xfc, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x04, 0x04, 0x00, 0x02, 0x44, 0x32, 0x01, 0x02, + 0x48, 0x32, 0x01, 0x02, 0x4c, 0x32, 0x01, 0x02, 0x50, 0x32, 0x01, 0x02, 0x54, 0x32, 0x01, 0x02, 0x58, 0x32, 0x01, 0x02, 0x7c, 0x0f, 0x02, 0x02, 0x80, 0x0f, 0x02, 0x02, 0x84, 0x0f, 0x02, 0x02, + 0x88, 0x0f, 0x02, 0x02, 0x8c, 0x0f, 0x02, 0x02, 0x80, 0x2e, 0x03, 0x03, 0x88, 0x2e, 0x03, 0x03, 0x90, 0x2e, 0x03, 0x03, 0xc8, 0x0c, 0x04, 0x03, 0xd0, 0x0c, 0x04, 0x03, 0xa0, 0x2a, 0x05, 0x04, + 0x40, 0x0a, 0x06, 0x04, 0x20, 0x27, 0x07, 0x05, 0x00, 0x24, 0x09, 0x06, 0x00, 0x38, 0x12, 0x0b, 0x08, 0x04, 0x00, 0x02, 0x0c, 0x04, 0x00, 0x02, 0x10, 0x04, 0x00, 0x02, 0x5c, 0x32, 0x01, 0x02, + 0x60, 0x32, 0x01, 0x02, 0x64, 0x32, 0x01, 0x02, 0x68, 0x32, 0x01, 0x02, 0x6c, 0x32, 0x01, 0x02, 0x70, 0x32, 0x01, 0x02, 0x90, 0x0f, 0x02, 0x02, 0x94, 0x0f, 0x02, 0x02, 0x98, 0x0f, 0x02, 0x02, + 0x9c, 0x0f, 0x02, 0x02, 0xa0, 0x0f, 0x02, 0x02, 0x98, 0x2e, 0x03, 0x03, 0xa0, 0x2e, 0x03, 0x03, 0xa8, 0x2e, 0x03, 0x03, 0xd8, 0x0c, 0x04, 0x03, 0xe0, 0x0c, 0x04, 0x03, 0xb0, 0x2a, 0x05, 0x04, + 0x50, 0x0a, 0x06, 0x04, 0x40, 0x27, 0x07, 0x05, 0x40, 0x24, 0x09, 0x06, 0x00, 0x00, 0x12, 0x0a, 0x14, 0x04, 0x00, 0x02, 0x18, 0x04, 0x00, 0x02, 0x1c, 0x04, 0x00, 0x02, 0x74, 0x32, 0x01, 0x02, + 0x78, 0x32, 0x01, 0x02, 0x7c, 0x32, 0x01, 0x02, 0x80, 0x32, 0x01, 0x02, 0x84, 0x32, 0x01, 0x02, 0x88, 0x32, 0x01, 0x02, 0xa4, 0x0f, 0x02, 0x02, 0xa8, 0x0f, 0x02, 0x02, 0xac, 0x0f, 0x02, 0x02, + 0xb0, 0x0f, 0x02, 0x02, 0xb4, 0x0f, 0x02, 0x02, 0xb0, 0x2e, 0x03, 0x03, 0xb8, 0x2e, 0x03, 0x03, 0xc0, 0x2e, 0x03, 0x03, 0xe8, 0x0c, 0x04, 0x03, 0xf0, 0x0c, 0x04, 0x03, 0xc0, 0x2a, 0x05, 0x04, + 0x60, 0x0a, 0x06, 0x04, 0x60, 0x27, 0x07, 0x05, 0x80, 0x24, 0x09, 0x06, 0x00, 0x30, 0x14, 0x0c, 0x20, 0x04, 0x00, 0x02, 0x24, 0x04, 0x00, 0x02, 0x28, 0x04, 0x00, 0x02, 0x8c, 0x32, 0x01, 0x02, + 0x90, 0x32, 0x01, 0x02, 0x94, 0x32, 0x01, 0x02, 0x98, 0x32, 0x01, 0x02, 0x9c, 0x32, 0x01, 0x02, 0xa0, 0x32, 0x01, 0x02, 0xb8, 0x0f, 0x02, 0x02, 0xbc, 0x0f, 0x02, 0x02, 0xc0, 0x0f, 0x02, 0x02, + 0xc4, 0x0f, 0x02, 0x02, 0xc8, 0x0f, 0x02, 0x02, 0xc8, 0x2e, 0x03, 0x03, 0xd0, 0x2e, 0x03, 0x03, 0xd8, 0x2e, 0x03, 0x03, 0xf8, 0x0c, 0x04, 0x03, 0x00, 0x0d, 0x04, 0x03, 0xd0, 0x2a, 0x05, 0x04, + 0x70, 0x0a, 0x06, 0x04, 0x80, 0x27, 0x07, 0x05, 0xc0, 0x24, 0x09, 0x06, 0x00, 0x20, 0x16, 0x0d, 0x2c, 0x04, 0x00, 0x02, 0x30, 0x04, 0x00, 0x02, 0x34, 0x04, 0x00, 0x02, 0xa4, 0x32, 0x01, 0x02, + 0xa8, 0x32, 0x01, 0x02, 0xac, 0x32, 0x01, 0x02, 0xb0, 0x32, 0x01, 0x02, 0xb4, 0x32, 0x01, 0x02, 0xb8, 0x32, 0x01, 0x02, 0xcc, 0x0f, 0x02, 0x02, 0xd0, 0x0f, 0x02, 0x02, 0xd4, 0x0f, 0x02, 0x02, + 0xd8, 0x0f, 0x02, 0x02, 0xdc, 0x0f, 0x02, 0x02, 0xe0, 0x2e, 0x03, 0x03, 0xe8, 0x2e, 0x03, 0x03, 0xf0, 0x2e, 0x03, 0x03, 0x08, 0x0d, 0x04, 0x03, 0x10, 0x0d, 0x04, 0x03, 0xe0, 0x2a, 0x05, 0x04, + 0x80, 0x0a, 0x06, 0x04, 0xa0, 0x27, 0x07, 0x05, 0x00, 0x25, 0x09, 0x06, 0x38, 0x04, 0x00, 0x02, 0x3c, 0x04, 0x00, 0x02, 0x40, 0x04, 0x00, 0x02, 0x44, 0x04, 0x00, 0x02, 0xbc, 0x32, 0x01, 0x02, + 0xc0, 0x32, 0x01, 0x02, 0xc4, 0x32, 0x01, 0x02, 0xc8, 0x32, 0x01, 0x02, 0xcc, 0x32, 0x01, 0x02, 0xd0, 0x32, 0x01, 0x02, 0xe0, 0x0f, 0x02, 0x02, 0xe4, 0x0f, 0x02, 0x02, 0xe8, 0x0f, 0x02, 0x02, + 0xec, 0x0f, 0x02, 0x02, 0xf0, 0x0f, 0x02, 0x02, 0xf8, 0x2e, 0x03, 0x03, 0x00, 0x2f, 0x03, 0x03, 0x08, 0x2f, 0x03, 0x03, 0x18, 0x0d, 0x04, 0x03, 0x20, 0x0d, 0x04, 0x03, 0xf0, 0x2a, 0x05, 0x04, + 0x90, 0x0a, 0x06, 0x04, 0xc0, 0x27, 0x07, 0x05, 0x40, 0x25, 0x09, 0x06, 0x48, 0x04, 0x00, 0x02, 0x4c, 0x04, 0x00, 0x02, 0x50, 0x04, 0x00, 0x02, 0x54, 0x04, 0x00, 0x02, 0xd4, 0x32, 0x01, 0x02, + 0xd8, 0x32, 0x01, 0x02, 0xdc, 0x32, 0x01, 0x02, 0xe0, 0x32, 0x01, 0x02, 0xe4, 0x32, 0x01, 0x02, 0xe8, 0x32, 0x01, 0x02, 0xf4, 0x0f, 0x02, 0x02, 0xf8, 0x0f, 0x02, 0x02, 0xfc, 0x0f, 0x02, 0x02, + 0x00, 0x10, 0x02, 0x02, 0x04, 0x10, 0x02, 0x02, 0x10, 0x2f, 0x03, 0x03, 0x18, 0x2f, 0x03, 0x03, 0x20, 0x2f, 0x03, 0x03, 0x28, 0x0d, 0x04, 0x03, 0x30, 0x0d, 0x04, 0x03, 0x00, 0x2b, 0x05, 0x04, + 0xa0, 0x0a, 0x06, 0x04, 0xe0, 0x27, 0x07, 0x05, 0x80, 0x25, 0x09, 0x06, 0x58, 0x04, 0x00, 0x02, 0x5c, 0x04, 0x00, 0x02, 0x60, 0x04, 0x00, 0x02, 0x64, 0x04, 0x00, 0x02, 0xec, 0x32, 0x01, 0x02, + 0xf0, 0x32, 0x01, 0x02, 0xf4, 0x32, 0x01, 0x02, 0xf8, 0x32, 0x01, 0x02, 0xfc, 0x32, 0x01, 0x02, 0x00, 0x33, 0x01, 0x02, 0x08, 0x10, 0x02, 0x02, 0x0c, 0x10, 0x02, 0x02, 0x10, 0x10, 0x02, 0x02, + 0x14, 0x10, 0x02, 0x02, 0x18, 0x10, 0x02, 0x02, 0x28, 0x2f, 0x03, 0x03, 0x30, 0x2f, 0x03, 0x03, 0x38, 0x2f, 0x03, 0x03, 0x38, 0x0d, 0x04, 0x03, 0x40, 0x0d, 0x04, 0x03, 0x10, 0x2b, 0x05, 0x04, + 0xb0, 0x0a, 0x06, 0x04, 0x00, 0x28, 0x07, 0x05, 0xc0, 0x25, 0x09, 0x06, 0x68, 0x04, 0x00, 0x02, 0x6c, 0x04, 0x00, 0x02, 0x70, 0x04, 0x00, 0x02, 0x74, 0x04, 0x00, 0x02, 0x04, 0x33, 0x01, 0x02, + 0x08, 0x33, 0x01, 0x02, 0x0c, 0x33, 0x01, 0x02, 0x10, 0x33, 0x01, 0x02, 0x14, 0x33, 0x01, 0x02, 0x18, 0x33, 0x01, 0x02, 0x1c, 0x10, 0x02, 0x02, 0x20, 0x10, 0x02, 0x02, 0x24, 0x10, 0x02, 0x02, + 0x28, 0x10, 0x02, 0x02, 0x2c, 0x10, 0x02, 0x02, 0x40, 0x2f, 0x03, 0x03, 0x48, 0x2f, 0x03, 0x03, 0x50, 0x2f, 0x03, 0x03, 0x48, 0x0d, 0x04, 0x03, 0x50, 0x0d, 0x04, 0x03, 0x20, 0x2b, 0x05, 0x04, + 0xc0, 0x0a, 0x06, 0x04, 0x20, 0x28, 0x07, 0x05, 0x00, 0x26, 0x09, 0x06, 0x78, 0x04, 0x00, 0x02, 0x7c, 0x04, 0x00, 0x02, 0x80, 0x04, 0x00, 0x02, 0x84, 0x04, 0x00, 0x02, 0x1c, 0x33, 0x01, 0x02, + 0x20, 0x33, 0x01, 0x02, 0x24, 0x33, 0x01, 0x02, 0x28, 0x33, 0x01, 0x02, 0x2c, 0x33, 0x01, 0x02, 0x30, 0x33, 0x01, 0x02, 0x30, 0x10, 0x02, 0x02, 0x34, 0x10, 0x02, 0x02, 0x38, 0x10, 0x02, 0x02, + 0x3c, 0x10, 0x02, 0x02, 0x40, 0x10, 0x02, 0x02, 0x58, 0x2f, 0x03, 0x03, 0x60, 0x2f, 0x03, 0x03, 0x68, 0x2f, 0x03, 0x03, 0x58, 0x0d, 0x04, 0x03, 0x60, 0x0d, 0x04, 0x03, 0x30, 0x2b, 0x05, 0x04, + 0xd0, 0x0a, 0x06, 0x04, 0x40, 0x28, 0x07, 0x05, 0x40, 0x26, 0x09, 0x06, 0x88, 0x04, 0x00, 0x02, 0x8c, 0x04, 0x00, 0x02, 0x90, 0x04, 0x00, 0x02, 0x94, 0x04, 0x00, 0x02, 0x34, 0x33, 0x01, 0x02, + 0x38, 0x33, 0x01, 0x02, 0x3c, 0x33, 0x01, 0x02, 0x40, 0x33, 0x01, 0x02, 0x44, 0x33, 0x01, 0x02, 0x48, 0x33, 0x01, 0x02, 0x44, 0x10, 0x02, 0x02, 0x48, 0x10, 0x02, 0x02, 0x4c, 0x10, 0x02, 0x02, + 0x50, 0x10, 0x02, 0x02, 0x54, 0x10, 0x02, 0x02, 0x70, 0x2f, 0x03, 0x03, 0x78, 0x2f, 0x03, 0x03, 0x80, 0x2f, 0x03, 0x03, 0x68, 0x0d, 0x04, 0x03, 0x70, 0x0d, 0x04, 0x03, 0x40, 0x2b, 0x05, 0x04, + 0xe0, 0x0a, 0x06, 0x04, 0x60, 0x28, 0x07, 0x05, 0x80, 0x26, 0x09, 0x06, 0x98, 0x04, 0x00, 0x02, 0x9c, 0x04, 0x00, 0x02, 0xa0, 0x04, 0x00, 0x02, 0xa4, 0x04, 0x00, 0x02, 0x4c, 0x33, 0x01, 0x02, + 0x50, 0x33, 0x01, 0x02, 0x54, 0x33, 0x01, 0x02, 0x58, 0x33, 0x01, 0x02, 0x5c, 0x33, 0x01, 0x02, 0x60, 0x33, 0x01, 0x02, 0x58, 0x10, 0x02, 0x02, 0x5c, 0x10, 0x02, 0x02, 0x60, 0x10, 0x02, 0x02, + 0x64, 0x10, 0x02, 0x02, 0x68, 0x10, 0x02, 0x02, 0x88, 0x2f, 0x03, 0x03, 0x90, 0x2f, 0x03, 0x03, 0x98, 0x2f, 0x03, 0x03, 0x78, 0x0d, 0x04, 0x03, 0x80, 0x0d, 0x04, 0x03, 0x50, 0x2b, 0x05, 0x04, + 0xf0, 0x0a, 0x06, 0x04, 0x80, 0x28, 0x07, 0x05, 0xc0, 0x26, 0x09, 0x06, 0xa8, 0x04, 0x00, 0x02, 0xac, 0x04, 0x00, 0x02, 0xb0, 0x04, 0x00, 0x02, 0xb4, 0x04, 0x00, 0x02, 0x64, 0x33, 0x01, 0x02, + 0x68, 0x33, 0x01, 0x02, 0x6c, 0x33, 0x01, 0x02, 0x70, 0x33, 0x01, 0x02, 0x74, 0x33, 0x01, 0x02, 0x78, 0x33, 0x01, 0x02, 0x6c, 0x10, 0x02, 0x02, 0x70, 0x10, 0x02, 0x02, 0x74, 0x10, 0x02, 0x02, + 0x78, 0x10, 0x02, 0x02, 0x7c, 0x10, 0x02, 0x02, 0xa0, 0x2f, 0x03, 0x03, 0xa8, 0x2f, 0x03, 0x03, 0xb0, 0x2f, 0x03, 0x03, 0x88, 0x0d, 0x04, 0x03, 0x90, 0x0d, 0x04, 0x03, 0x60, 0x2b, 0x05, 0x04, + 0x00, 0x0b, 0x06, 0x04, 0xa0, 0x28, 0x07, 0x05, 0x00, 0x27, 0x09, 0x06, 0xb8, 0x04, 0x00, 0x02, 0xbc, 0x04, 0x00, 0x02, 0xc0, 0x04, 0x00, 0x02, 0xc4, 0x04, 0x00, 0x02, 0x7c, 0x33, 0x01, 0x02, + 0x80, 0x33, 0x01, 0x02, 0x84, 0x33, 0x01, 0x02, 0x88, 0x33, 0x01, 0x02, 0x8c, 0x33, 0x01, 0x02, 0x90, 0x33, 0x01, 0x02, 0x80, 0x10, 0x02, 0x02, 0x84, 0x10, 0x02, 0x02, 0x88, 0x10, 0x02, 0x02, + 0x8c, 0x10, 0x02, 0x02, 0x90, 0x10, 0x02, 0x02, 0xb8, 0x2f, 0x03, 0x03, 0xc0, 0x2f, 0x03, 0x03, 0xc8, 0x2f, 0x03, 0x03, 0x98, 0x0d, 0x04, 0x03, 0xa0, 0x0d, 0x04, 0x03, 0x70, 0x2b, 0x05, 0x04, + 0x10, 0x0b, 0x06, 0x04, 0xc0, 0x28, 0x07, 0x05, 0x40, 0x27, 0x09, 0x06, 0xc8, 0x04, 0x00, 0x02, 0xcc, 0x04, 0x00, 0x02, 0xd0, 0x04, 0x00, 0x02, 0xd4, 0x04, 0x00, 0x02, 0x94, 0x33, 0x01, 0x02, + 0x98, 0x33, 0x01, 0x02, 0x9c, 0x33, 0x01, 0x02, 0xa0, 0x33, 0x01, 0x02, 0xa4, 0x33, 0x01, 0x02, 0xa8, 0x33, 0x01, 0x02, 0x94, 0x10, 0x02, 0x02, 0x98, 0x10, 0x02, 0x02, 0x9c, 0x10, 0x02, 0x02, + 0xa0, 0x10, 0x02, 0x02, 0xa4, 0x10, 0x02, 0x02, 0xd0, 0x2f, 0x03, 0x03, 0xd8, 0x2f, 0x03, 0x03, 0xe0, 0x2f, 0x03, 0x03, 0xa8, 0x0d, 0x04, 0x03, 0xb0, 0x0d, 0x04, 0x03, 0x80, 0x2b, 0x05, 0x04, + 0x20, 0x0b, 0x06, 0x04, 0xe0, 0x28, 0x07, 0x05, 0x80, 0x27, 0x09, 0x06, 0xd8, 0x04, 0x00, 0x02, 0xdc, 0x04, 0x00, 0x02, 0xe0, 0x04, 0x00, 0x02, 0xe4, 0x04, 0x00, 0x02, 0xac, 0x33, 0x01, 0x02, + 0xb0, 0x33, 0x01, 0x02, 0xb4, 0x33, 0x01, 0x02, 0xb8, 0x33, 0x01, 0x02, 0xbc, 0x33, 0x01, 0x02, 0xc0, 0x33, 0x01, 0x02, 0xa8, 0x10, 0x02, 0x02, 0xac, 0x10, 0x02, 0x02, 0xb0, 0x10, 0x02, 0x02, + 0xb4, 0x10, 0x02, 0x02, 0xb8, 0x10, 0x02, 0x02, 0xe8, 0x2f, 0x03, 0x03, 0xf0, 0x2f, 0x03, 0x03, 0xf8, 0x2f, 0x03, 0x03, 0xb8, 0x0d, 0x04, 0x03, 0xc0, 0x0d, 0x04, 0x03, 0x90, 0x2b, 0x05, 0x04, + 0x30, 0x0b, 0x06, 0x04, 0x00, 0x29, 0x07, 0x05, 0xc0, 0x27, 0x09, 0x06, 0xe8, 0x04, 0x00, 0x02, 0xec, 0x04, 0x00, 0x02, 0xf0, 0x04, 0x00, 0x02, 0xf4, 0x04, 0x00, 0x02, 0xc4, 0x33, 0x01, 0x02, + 0xc8, 0x33, 0x01, 0x02, 0xcc, 0x33, 0x01, 0x02, 0xd0, 0x33, 0x01, 0x02, 0xd4, 0x33, 0x01, 0x02, 0xd8, 0x33, 0x01, 0x02, 0xbc, 0x10, 0x02, 0x02, 0xc0, 0x10, 0x02, 0x02, 0xc4, 0x10, 0x02, 0x02, + 0xc8, 0x10, 0x02, 0x02, 0xcc, 0x10, 0x02, 0x02, 0x00, 0x30, 0x03, 0x03, 0x08, 0x30, 0x03, 0x03, 0x10, 0x30, 0x03, 0x03, 0xc8, 0x0d, 0x04, 0x03, 0xd0, 0x0d, 0x04, 0x03, 0xa0, 0x2b, 0x05, 0x04, + 0x40, 0x0b, 0x06, 0x04, 0x20, 0x29, 0x07, 0x05, 0x00, 0x28, 0x09, 0x06, 0xf8, 0x04, 0x00, 0x02, 0xfc, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x04, 0x05, 0x00, 0x02, 0xdc, 0x33, 0x01, 0x02, + 0xe0, 0x33, 0x01, 0x02, 0xe4, 0x33, 0x01, 0x02, 0xe8, 0x33, 0x01, 0x02, 0xec, 0x33, 0x01, 0x02, 0xf0, 0x33, 0x01, 0x02, 0xd0, 0x10, 0x02, 0x02, 0xd4, 0x10, 0x02, 0x02, 0xd8, 0x10, 0x02, 0x02, + 0xdc, 0x10, 0x02, 0x02, 0xe0, 0x10, 0x02, 0x02, 0x18, 0x30, 0x03, 0x03, 0x20, 0x30, 0x03, 0x03, 0x28, 0x30, 0x03, 0x03, 0xd8, 0x0d, 0x04, 0x03, 0xe0, 0x0d, 0x04, 0x03, 0xb0, 0x2b, 0x05, 0x04, + 0x50, 0x0b, 0x06, 0x04, 0x40, 0x29, 0x07, 0x05, 0x40, 0x28, 0x09, 0x06, 0x08, 0x05, 0x00, 0x02, 0x0c, 0x05, 0x00, 0x02, 0x10, 0x05, 0x00, 0x02, 0x14, 0x05, 0x00, 0x02, 0xf4, 0x33, 0x01, 0x02, + 0xf8, 0x33, 0x01, 0x02, 0xfc, 0x33, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x04, 0x34, 0x01, 0x02, 0x08, 0x34, 0x01, 0x02, 0xe4, 0x10, 0x02, 0x02, 0xe8, 0x10, 0x02, 0x02, 0xec, 0x10, 0x02, 0x02, + 0xf0, 0x10, 0x02, 0x02, 0xf4, 0x10, 0x02, 0x02, 0x30, 0x30, 0x03, 0x03, 0x38, 0x30, 0x03, 0x03, 0x40, 0x30, 0x03, 0x03, 0xe8, 0x0d, 0x04, 0x03, 0xf0, 0x0d, 0x04, 0x03, 0xc0, 0x2b, 0x05, 0x04, + 0x60, 0x0b, 0x06, 0x04, 0x60, 0x29, 0x07, 0x05, 0x80, 0x28, 0x09, 0x06, 0x18, 0x05, 0x00, 0x02, 0x1c, 0x05, 0x00, 0x02, 0x20, 0x05, 0x00, 0x02, 0x24, 0x05, 0x00, 0x02, 0x0c, 0x34, 0x01, 0x02, + 0x10, 0x34, 0x01, 0x02, 0x14, 0x34, 0x01, 0x02, 0x18, 0x34, 0x01, 0x02, 0x1c, 0x34, 0x01, 0x02, 0x20, 0x34, 0x01, 0x02, 0xf8, 0x10, 0x02, 0x02, 0xfc, 0x10, 0x02, 0x02, 0x00, 0x11, 0x02, 0x02, + 0x04, 0x11, 0x02, 0x02, 0x08, 0x11, 0x02, 0x02, 0x48, 0x30, 0x03, 0x03, 0x50, 0x30, 0x03, 0x03, 0xf8, 0x0d, 0x04, 0x03, 0x00, 0x0e, 0x04, 0x03, 0x08, 0x0e, 0x04, 0x03, 0xd0, 0x2b, 0x05, 0x04, + 0x70, 0x0b, 0x06, 0x04, 0x80, 0x29, 0x07, 0x05, 0xc0, 0x28, 0x09, 0x06, 0x28, 0x05, 0x00, 0x02, 0x2c, 0x05, 0x00, 0x02, 0x30, 0x05, 0x00, 0x02, 0x34, 0x05, 0x00, 0x02, 0x24, 0x34, 0x01, 0x02, + 0x28, 0x34, 0x01, 0x02, 0x2c, 0x34, 0x01, 0x02, 0x30, 0x34, 0x01, 0x02, 0x34, 0x34, 0x01, 0x02, 0x38, 0x34, 0x01, 0x02, 0x0c, 0x11, 0x02, 0x02, 0x10, 0x11, 0x02, 0x02, 0x14, 0x11, 0x02, 0x02, + 0x18, 0x11, 0x02, 0x02, 0x58, 0x30, 0x03, 0x03, 0x60, 0x30, 0x03, 0x03, 0x68, 0x30, 0x03, 0x03, 0x10, 0x0e, 0x04, 0x03, 0x18, 0x0e, 0x04, 0x03, 0x20, 0x0e, 0x04, 0x03, 0xe0, 0x2b, 0x05, 0x04, + 0x80, 0x0b, 0x06, 0x04, 0xa0, 0x29, 0x07, 0x05, 0x00, 0x29, 0x09, 0x06, 0x38, 0x05, 0x00, 0x02, 0x3c, 0x05, 0x00, 0x02, 0x40, 0x05, 0x00, 0x02, 0x44, 0x05, 0x00, 0x02, 0x3c, 0x34, 0x01, 0x02, + 0x40, 0x34, 0x01, 0x02, 0x44, 0x34, 0x01, 0x02, 0x48, 0x34, 0x01, 0x02, 0x4c, 0x34, 0x01, 0x02, 0x50, 0x34, 0x01, 0x02, 0x1c, 0x11, 0x02, 0x02, 0x20, 0x11, 0x02, 0x02, 0x24, 0x11, 0x02, 0x02, + 0x28, 0x11, 0x02, 0x02, 0x70, 0x30, 0x03, 0x03, 0x78, 0x30, 0x03, 0x03, 0x80, 0x30, 0x03, 0x03, 0x28, 0x0e, 0x04, 0x03, 0x30, 0x0e, 0x04, 0x03, 0x38, 0x0e, 0x04, 0x03, 0xf0, 0x2b, 0x05, 0x04, + 0x90, 0x0b, 0x06, 0x04, 0xc0, 0x29, 0x07, 0x05, 0x40, 0x29, 0x09, 0x06, 0x48, 0x05, 0x00, 0x02, 0x4c, 0x05, 0x00, 0x02, 0x50, 0x05, 0x00, 0x02, 0x54, 0x05, 0x00, 0x02, 0x54, 0x34, 0x01, 0x02, + 0x58, 0x34, 0x01, 0x02, 0x5c, 0x34, 0x01, 0x02, 0x60, 0x34, 0x01, 0x02, 0x64, 0x34, 0x01, 0x02, 0x68, 0x34, 0x01, 0x02, 0x2c, 0x11, 0x02, 0x02, 0x30, 0x11, 0x02, 0x02, 0x34, 0x11, 0x02, 0x02, + 0x38, 0x11, 0x02, 0x02, 0x88, 0x30, 0x03, 0x03, 0x90, 0x30, 0x03, 0x03, 0x98, 0x30, 0x03, 0x03, 0x40, 0x0e, 0x04, 0x03, 0x48, 0x0e, 0x04, 0x03, 0x50, 0x0e, 0x04, 0x03, 0x00, 0x2c, 0x05, 0x04, + 0xa0, 0x0b, 0x06, 0x04, 0xe0, 0x29, 0x07, 0x05, 0x80, 0x29, 0x09, 0x06, 0x58, 0x05, 0x00, 0x02, 0x5c, 0x05, 0x00, 0x02, 0x60, 0x05, 0x00, 0x02, 0x64, 0x05, 0x00, 0x02, 0x6c, 0x34, 0x01, 0x02, + 0x70, 0x34, 0x01, 0x02, 0x74, 0x34, 0x01, 0x02, 0x78, 0x34, 0x01, 0x02, 0x7c, 0x34, 0x01, 0x02, 0x80, 0x34, 0x01, 0x02, 0x3c, 0x11, 0x02, 0x02, 0x40, 0x11, 0x02, 0x02, 0x44, 0x11, 0x02, 0x02, + 0x48, 0x11, 0x02, 0x02, 0xa0, 0x30, 0x03, 0x03, 0xa8, 0x30, 0x03, 0x03, 0xb0, 0x30, 0x03, 0x03, 0x58, 0x0e, 0x04, 0x03, 0x60, 0x0e, 0x04, 0x03, 0x68, 0x0e, 0x04, 0x03, 0x10, 0x2c, 0x05, 0x04, + 0xb0, 0x0b, 0x06, 0x04, 0x00, 0x2a, 0x07, 0x05, 0xc0, 0x29, 0x09, 0x06, 0x68, 0x05, 0x00, 0x02, 0x6c, 0x05, 0x00, 0x02, 0x70, 0x05, 0x00, 0x02, 0x74, 0x05, 0x00, 0x02, 0x84, 0x34, 0x01, 0x02, + 0x88, 0x34, 0x01, 0x02, 0x8c, 0x34, 0x01, 0x02, 0x90, 0x34, 0x01, 0x02, 0x94, 0x34, 0x01, 0x02, 0x98, 0x34, 0x01, 0x02, 0x4c, 0x11, 0x02, 0x02, 0x50, 0x11, 0x02, 0x02, 0x54, 0x11, 0x02, 0x02, + 0x58, 0x11, 0x02, 0x02, 0xb8, 0x30, 0x03, 0x03, 0xc0, 0x30, 0x03, 0x03, 0xc8, 0x30, 0x03, 0x03, 0x70, 0x0e, 0x04, 0x03, 0x78, 0x0e, 0x04, 0x03, 0x80, 0x0e, 0x04, 0x03, 0x20, 0x2c, 0x05, 0x04, + 0xc0, 0x0b, 0x06, 0x04, 0x20, 0x2a, 0x07, 0x05, 0x40, 0x05, 0x0a, 0x06, 0x78, 0x05, 0x00, 0x02, 0x7c, 0x05, 0x00, 0x02, 0x80, 0x05, 0x00, 0x02, 0x84, 0x05, 0x00, 0x02, 0x9c, 0x34, 0x01, 0x02, + 0xa0, 0x34, 0x01, 0x02, 0xa4, 0x34, 0x01, 0x02, 0xa8, 0x34, 0x01, 0x02, 0xac, 0x34, 0x01, 0x02, 0xb0, 0x34, 0x01, 0x02, 0x5c, 0x11, 0x02, 0x02, 0x60, 0x11, 0x02, 0x02, 0x64, 0x11, 0x02, 0x02, + 0x68, 0x11, 0x02, 0x02, 0xd0, 0x30, 0x03, 0x03, 0xd8, 0x30, 0x03, 0x03, 0xe0, 0x30, 0x03, 0x03, 0x88, 0x0e, 0x04, 0x03, 0x90, 0x0e, 0x04, 0x03, 0x98, 0x0e, 0x04, 0x03, 0x30, 0x2c, 0x05, 0x04, + 0xd0, 0x0b, 0x06, 0x04, 0x40, 0x2a, 0x07, 0x05, 0x80, 0x05, 0x0a, 0x06, 0x88, 0x05, 0x00, 0x02, 0x8c, 0x05, 0x00, 0x02, 0x90, 0x05, 0x00, 0x02, 0x94, 0x05, 0x00, 0x02, 0xb4, 0x34, 0x01, 0x02, + 0xb8, 0x34, 0x01, 0x02, 0xbc, 0x34, 0x01, 0x02, 0xc0, 0x34, 0x01, 0x02, 0xc4, 0x34, 0x01, 0x02, 0xc8, 0x34, 0x01, 0x02, 0x6c, 0x11, 0x02, 0x02, 0x70, 0x11, 0x02, 0x02, 0x74, 0x11, 0x02, 0x02, + 0x78, 0x11, 0x02, 0x02, 0xe8, 0x30, 0x03, 0x03, 0xf0, 0x30, 0x03, 0x03, 0xf8, 0x30, 0x03, 0x03, 0xa0, 0x0e, 0x04, 0x03, 0xa8, 0x0e, 0x04, 0x03, 0x40, 0x2c, 0x05, 0x04, 0x50, 0x2c, 0x05, 0x04, + 0xe0, 0x0b, 0x06, 0x04, 0x60, 0x2a, 0x07, 0x05, 0xc0, 0x05, 0x0a, 0x06, 0x98, 0x05, 0x00, 0x02, 0x9c, 0x05, 0x00, 0x02, 0xa0, 0x05, 0x00, 0x02, 0xa4, 0x05, 0x00, 0x02, 0xcc, 0x34, 0x01, 0x02, + 0xd0, 0x34, 0x01, 0x02, 0xd4, 0x34, 0x01, 0x02, 0xd8, 0x34, 0x01, 0x02, 0xdc, 0x34, 0x01, 0x02, 0xe0, 0x34, 0x01, 0x02, 0x7c, 0x11, 0x02, 0x02, 0x80, 0x11, 0x02, 0x02, 0x84, 0x11, 0x02, 0x02, + 0x88, 0x11, 0x02, 0x02, 0x00, 0x31, 0x03, 0x03, 0x08, 0x31, 0x03, 0x03, 0x10, 0x31, 0x03, 0x03, 0xb0, 0x0e, 0x04, 0x03, 0xb8, 0x0e, 0x04, 0x03, 0x60, 0x2c, 0x05, 0x04, 0x70, 0x2c, 0x05, 0x04, + 0xf0, 0x0b, 0x06, 0x04, 0x80, 0x2a, 0x07, 0x05, 0x00, 0x06, 0x0a, 0x06, 0xa8, 0x05, 0x00, 0x02, 0xac, 0x05, 0x00, 0x02, 0xb0, 0x05, 0x00, 0x02, 0xb4, 0x05, 0x00, 0x02, 0xe4, 0x34, 0x01, 0x02, + 0xe8, 0x34, 0x01, 0x02, 0xec, 0x34, 0x01, 0x02, 0xf0, 0x34, 0x01, 0x02, 0xf4, 0x34, 0x01, 0x02, 0xf8, 0x34, 0x01, 0x02, 0x8c, 0x11, 0x02, 0x02, 0x90, 0x11, 0x02, 0x02, 0x94, 0x11, 0x02, 0x02, + 0x98, 0x11, 0x02, 0x02, 0x18, 0x31, 0x03, 0x03, 0x20, 0x31, 0x03, 0x03, 0x28, 0x31, 0x03, 0x03, 0xc0, 0x0e, 0x04, 0x03, 0xc8, 0x0e, 0x04, 0x03, 0x80, 0x2c, 0x05, 0x04, 0x90, 0x2c, 0x05, 0x04, + 0x00, 0x0c, 0x06, 0x04, 0xa0, 0x2a, 0x07, 0x05, 0x40, 0x06, 0x0a, 0x06, 0xb8, 0x05, 0x00, 0x02, 0xbc, 0x05, 0x00, 0x02, 0xc0, 0x05, 0x00, 0x02, 0xc4, 0x05, 0x00, 0x02, 0xfc, 0x34, 0x01, 0x02, + 0x00, 0x35, 0x01, 0x02, 0x04, 0x35, 0x01, 0x02, 0x08, 0x35, 0x01, 0x02, 0x0c, 0x35, 0x01, 0x02, 0x10, 0x35, 0x01, 0x02, 0x9c, 0x11, 0x02, 0x02, 0xa0, 0x11, 0x02, 0x02, 0xa4, 0x11, 0x02, 0x02, + 0xa8, 0x11, 0x02, 0x02, 0x30, 0x31, 0x03, 0x03, 0x38, 0x31, 0x03, 0x03, 0x40, 0x31, 0x03, 0x03, 0xd0, 0x0e, 0x04, 0x03, 0xd8, 0x0e, 0x04, 0x03, 0xa0, 0x2c, 0x05, 0x04, 0xb0, 0x2c, 0x05, 0x04, + 0x10, 0x0c, 0x06, 0x04, 0xc0, 0x2a, 0x07, 0x05, 0x80, 0x06, 0x0a, 0x06, 0xc8, 0x05, 0x00, 0x02, 0xcc, 0x05, 0x00, 0x02, 0xd0, 0x05, 0x00, 0x02, 0xd4, 0x05, 0x00, 0x02, 0x14, 0x35, 0x01, 0x02, + 0x18, 0x35, 0x01, 0x02, 0x1c, 0x35, 0x01, 0x02, 0x20, 0x35, 0x01, 0x02, 0x24, 0x35, 0x01, 0x02, 0x28, 0x35, 0x01, 0x02, 0xac, 0x11, 0x02, 0x02, 0xb0, 0x11, 0x02, 0x02, 0xb4, 0x11, 0x02, 0x02, + 0xb8, 0x11, 0x02, 0x02, 0x48, 0x31, 0x03, 0x03, 0x50, 0x31, 0x03, 0x03, 0x58, 0x31, 0x03, 0x03, 0xe0, 0x0e, 0x04, 0x03, 0xe8, 0x0e, 0x04, 0x03, 0xc0, 0x2c, 0x05, 0x04, 0xd0, 0x2c, 0x05, 0x04, + 0x20, 0x0c, 0x06, 0x04, 0xe0, 0x2a, 0x07, 0x05, 0xc0, 0x06, 0x0a, 0x06, 0xd8, 0x05, 0x00, 0x02, 0xdc, 0x05, 0x00, 0x02, 0xe0, 0x05, 0x00, 0x02, 0xe4, 0x05, 0x00, 0x02, 0x2c, 0x35, 0x01, 0x02, + 0x30, 0x35, 0x01, 0x02, 0x34, 0x35, 0x01, 0x02, 0x38, 0x35, 0x01, 0x02, 0x3c, 0x35, 0x01, 0x02, 0x40, 0x35, 0x01, 0x02, 0xbc, 0x11, 0x02, 0x02, 0xc0, 0x11, 0x02, 0x02, 0xc4, 0x11, 0x02, 0x02, + 0xc8, 0x11, 0x02, 0x02, 0x60, 0x31, 0x03, 0x03, 0x68, 0x31, 0x03, 0x03, 0x70, 0x31, 0x03, 0x03, 0xf0, 0x0e, 0x04, 0x03, 0xf8, 0x0e, 0x04, 0x03, 0xe0, 0x2c, 0x05, 0x04, 0xf0, 0x2c, 0x05, 0x04, + 0x30, 0x0c, 0x06, 0x04, 0x00, 0x2b, 0x07, 0x05, 0x00, 0x07, 0x0a, 0x06, 0xe8, 0x05, 0x00, 0x02, 0xec, 0x05, 0x00, 0x02, 0xf0, 0x05, 0x00, 0x02, 0xf4, 0x05, 0x00, 0x02, 0x44, 0x35, 0x01, 0x02, + 0x48, 0x35, 0x01, 0x02, 0x4c, 0x35, 0x01, 0x02, 0x50, 0x35, 0x01, 0x02, 0x54, 0x35, 0x01, 0x02, 0x58, 0x35, 0x01, 0x02, 0xcc, 0x11, 0x02, 0x02, 0xd0, 0x11, 0x02, 0x02, 0xd4, 0x11, 0x02, 0x02, + 0xd8, 0x11, 0x02, 0x02, 0x78, 0x31, 0x03, 0x03, 0x80, 0x31, 0x03, 0x03, 0x88, 0x31, 0x03, 0x03, 0x00, 0x0f, 0x04, 0x03, 0x08, 0x0f, 0x04, 0x03, 0x00, 0x2d, 0x05, 0x04, 0x10, 0x2d, 0x05, 0x04, + 0x40, 0x0c, 0x06, 0x04, 0x20, 0x2b, 0x07, 0x05, 0x40, 0x07, 0x0a, 0x06, 0xf8, 0x05, 0x00, 0x02, 0xfc, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x04, 0x06, 0x00, 0x02, 0x5c, 0x35, 0x01, 0x02, + 0x60, 0x35, 0x01, 0x02, 0x64, 0x35, 0x01, 0x02, 0x68, 0x35, 0x01, 0x02, 0x6c, 0x35, 0x01, 0x02, 0x70, 0x35, 0x01, 0x02, 0xdc, 0x11, 0x02, 0x02, 0xe0, 0x11, 0x02, 0x02, 0xe4, 0x11, 0x02, 0x02, + 0xe8, 0x11, 0x02, 0x02, 0x90, 0x31, 0x03, 0x03, 0x98, 0x31, 0x03, 0x03, 0xa0, 0x31, 0x03, 0x03, 0x10, 0x0f, 0x04, 0x03, 0x18, 0x0f, 0x04, 0x03, 0x20, 0x2d, 0x05, 0x04, 0x30, 0x2d, 0x05, 0x04, + 0x50, 0x0c, 0x06, 0x04, 0x40, 0x2b, 0x07, 0x05, 0x80, 0x07, 0x0a, 0x06, 0x08, 0x06, 0x00, 0x02, 0x0c, 0x06, 0x00, 0x02, 0x10, 0x06, 0x00, 0x02, 0x14, 0x06, 0x00, 0x02, 0x74, 0x35, 0x01, 0x02, + 0x78, 0x35, 0x01, 0x02, 0x7c, 0x35, 0x01, 0x02, 0x80, 0x35, 0x01, 0x02, 0x84, 0x35, 0x01, 0x02, 0x88, 0x35, 0x01, 0x02, 0xec, 0x11, 0x02, 0x02, 0xf0, 0x11, 0x02, 0x02, 0xf4, 0x11, 0x02, 0x02, + 0xf8, 0x11, 0x02, 0x02, 0xa8, 0x31, 0x03, 0x03, 0xb0, 0x31, 0x03, 0x03, 0xb8, 0x31, 0x03, 0x03, 0x20, 0x0f, 0x04, 0x03, 0x28, 0x0f, 0x04, 0x03, 0x40, 0x2d, 0x05, 0x04, 0x50, 0x2d, 0x05, 0x04, + 0x60, 0x0c, 0x06, 0x04, 0x60, 0x2b, 0x07, 0x05, 0xc0, 0x07, 0x0a, 0x06, 0x18, 0x06, 0x00, 0x02, 0x1c, 0x06, 0x00, 0x02, 0x20, 0x06, 0x00, 0x02, 0x24, 0x06, 0x00, 0x02, 0x8c, 0x35, 0x01, 0x02, + 0x90, 0x35, 0x01, 0x02, 0x94, 0x35, 0x01, 0x02, 0x98, 0x35, 0x01, 0x02, 0x9c, 0x35, 0x01, 0x02, 0xa0, 0x35, 0x01, 0x02, 0xfc, 0x11, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x04, 0x12, 0x02, 0x02, + 0x08, 0x12, 0x02, 0x02, 0xc0, 0x31, 0x03, 0x03, 0xc8, 0x31, 0x03, 0x03, 0xd0, 0x31, 0x03, 0x03, 0x30, 0x0f, 0x04, 0x03, 0x38, 0x0f, 0x04, 0x03, 0x60, 0x2d, 0x05, 0x04, 0x70, 0x2d, 0x05, 0x04, + 0x70, 0x0c, 0x06, 0x04, 0x80, 0x2b, 0x07, 0x05, 0x00, 0x08, 0x0a, 0x06, 0x28, 0x06, 0x00, 0x02, 0x2c, 0x06, 0x00, 0x02, 0x30, 0x06, 0x00, 0x02, 0x34, 0x06, 0x00, 0x02, 0xa4, 0x35, 0x01, 0x02, + 0xa8, 0x35, 0x01, 0x02, 0xac, 0x35, 0x01, 0x02, 0xb0, 0x35, 0x01, 0x02, 0xb4, 0x35, 0x01, 0x02, 0xb8, 0x35, 0x01, 0x02, 0x0c, 0x12, 0x02, 0x02, 0x10, 0x12, 0x02, 0x02, 0x14, 0x12, 0x02, 0x02, + 0x18, 0x12, 0x02, 0x02, 0xd8, 0x31, 0x03, 0x03, 0xe0, 0x31, 0x03, 0x03, 0xe8, 0x31, 0x03, 0x03, 0x40, 0x0f, 0x04, 0x03, 0x48, 0x0f, 0x04, 0x03, 0x80, 0x2d, 0x05, 0x04, 0x90, 0x2d, 0x05, 0x04, + 0x80, 0x0c, 0x06, 0x04, 0xa0, 0x2b, 0x07, 0x05, 0x40, 0x08, 0x0a, 0x06, 0x38, 0x06, 0x00, 0x02, 0x3c, 0x06, 0x00, 0x02, 0x40, 0x06, 0x00, 0x02, 0x44, 0x06, 0x00, 0x02, 0xbc, 0x35, 0x01, 0x02, + 0xc0, 0x35, 0x01, 0x02, 0xc4, 0x35, 0x01, 0x02, 0xc8, 0x35, 0x01, 0x02, 0xcc, 0x35, 0x01, 0x02, 0xd0, 0x35, 0x01, 0x02, 0x1c, 0x12, 0x02, 0x02, 0x20, 0x12, 0x02, 0x02, 0x24, 0x12, 0x02, 0x02, + 0x28, 0x12, 0x02, 0x02, 0xf0, 0x31, 0x03, 0x03, 0xf8, 0x31, 0x03, 0x03, 0x00, 0x32, 0x03, 0x03, 0x50, 0x0f, 0x04, 0x03, 0x58, 0x0f, 0x04, 0x03, 0xa0, 0x2d, 0x05, 0x04, 0xb0, 0x2d, 0x05, 0x04, + 0x90, 0x0c, 0x06, 0x04, 0xc0, 0x2b, 0x07, 0x05, 0x80, 0x08, 0x0a, 0x06, 0x48, 0x06, 0x00, 0x02, 0x4c, 0x06, 0x00, 0x02, 0x50, 0x06, 0x00, 0x02, 0x54, 0x06, 0x00, 0x02, 0xd4, 0x35, 0x01, 0x02, + 0xd8, 0x35, 0x01, 0x02, 0xdc, 0x35, 0x01, 0x02, 0xe0, 0x35, 0x01, 0x02, 0xe4, 0x35, 0x01, 0x02, 0xe8, 0x35, 0x01, 0x02, 0x2c, 0x12, 0x02, 0x02, 0x30, 0x12, 0x02, 0x02, 0x34, 0x12, 0x02, 0x02, + 0x38, 0x12, 0x02, 0x02, 0x08, 0x32, 0x03, 0x03, 0x10, 0x32, 0x03, 0x03, 0x18, 0x32, 0x03, 0x03, 0x60, 0x0f, 0x04, 0x03, 0x68, 0x0f, 0x04, 0x03, 0xc0, 0x2d, 0x05, 0x04, 0xd0, 0x2d, 0x05, 0x04, + 0xa0, 0x0c, 0x06, 0x04, 0xe0, 0x2b, 0x07, 0x05, 0xc0, 0x08, 0x0a, 0x06, 0x58, 0x06, 0x00, 0x02, 0x5c, 0x06, 0x00, 0x02, 0x60, 0x06, 0x00, 0x02, 0x64, 0x06, 0x00, 0x02, 0xec, 0x35, 0x01, 0x02, + 0xf0, 0x35, 0x01, 0x02, 0xf4, 0x35, 0x01, 0x02, 0xf8, 0x35, 0x01, 0x02, 0xfc, 0x35, 0x01, 0x02, 0x00, 0x36, 0x01, 0x02, 0x3c, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x02, 0x44, 0x12, 0x02, 0x02, + 0x48, 0x12, 0x02, 0x02, 0x20, 0x32, 0x03, 0x03, 0x28, 0x32, 0x03, 0x03, 0x30, 0x32, 0x03, 0x03, 0x70, 0x0f, 0x04, 0x03, 0x78, 0x0f, 0x04, 0x03, 0xe0, 0x2d, 0x05, 0x04, 0xf0, 0x2d, 0x05, 0x04, + 0xb0, 0x0c, 0x06, 0x04, 0xa0, 0x07, 0x08, 0x05, 0x00, 0x09, 0x0a, 0x06, 0x68, 0x06, 0x00, 0x02, 0x6c, 0x06, 0x00, 0x02, 0x70, 0x06, 0x00, 0x02, 0x74, 0x06, 0x00, 0x02, 0x04, 0x36, 0x01, 0x02, + 0x08, 0x36, 0x01, 0x02, 0x0c, 0x36, 0x01, 0x02, 0x10, 0x36, 0x01, 0x02, 0x14, 0x36, 0x01, 0x02, 0x18, 0x36, 0x01, 0x02, 0x4c, 0x12, 0x02, 0x02, 0x50, 0x12, 0x02, 0x02, 0x54, 0x12, 0x02, 0x02, + 0x58, 0x12, 0x02, 0x02, 0x38, 0x32, 0x03, 0x03, 0x40, 0x32, 0x03, 0x03, 0x48, 0x32, 0x03, 0x03, 0x80, 0x0f, 0x04, 0x03, 0x88, 0x0f, 0x04, 0x03, 0x00, 0x2e, 0x05, 0x04, 0x10, 0x2e, 0x05, 0x04, + 0xc0, 0x0c, 0x06, 0x04, 0xc0, 0x07, 0x08, 0x05, 0x40, 0x09, 0x0a, 0x06, 0x78, 0x06, 0x00, 0x02, 0x7c, 0x06, 0x00, 0x02, 0x80, 0x06, 0x00, 0x02, 0x84, 0x06, 0x00, 0x02, 0x1c, 0x36, 0x01, 0x02, + 0x20, 0x36, 0x01, 0x02, 0x24, 0x36, 0x01, 0x02, 0x28, 0x36, 0x01, 0x02, 0x2c, 0x36, 0x01, 0x02, 0x30, 0x36, 0x01, 0x02, 0x5c, 0x12, 0x02, 0x02, 0x60, 0x12, 0x02, 0x02, 0x64, 0x12, 0x02, 0x02, + 0x68, 0x12, 0x02, 0x02, 0x50, 0x32, 0x03, 0x03, 0x58, 0x32, 0x03, 0x03, 0x60, 0x32, 0x03, 0x03, 0x90, 0x0f, 0x04, 0x03, 0x98, 0x0f, 0x04, 0x03, 0x20, 0x2e, 0x05, 0x04, 0x30, 0x2e, 0x05, 0x04, + 0xd0, 0x0c, 0x06, 0x04, 0xe0, 0x07, 0x08, 0x05, 0x80, 0x09, 0x0a, 0x06, 0x88, 0x06, 0x00, 0x02, 0x8c, 0x06, 0x00, 0x02, 0x90, 0x06, 0x00, 0x02, 0x94, 0x06, 0x00, 0x02, 0x34, 0x36, 0x01, 0x02, + 0x38, 0x36, 0x01, 0x02, 0x3c, 0x36, 0x01, 0x02, 0x40, 0x36, 0x01, 0x02, 0x44, 0x36, 0x01, 0x02, 0x48, 0x36, 0x01, 0x02, 0x6c, 0x12, 0x02, 0x02, 0x70, 0x12, 0x02, 0x02, 0x74, 0x12, 0x02, 0x02, + 0x78, 0x12, 0x02, 0x02, 0x68, 0x32, 0x03, 0x03, 0x70, 0x32, 0x03, 0x03, 0x78, 0x32, 0x03, 0x03, 0xa0, 0x0f, 0x04, 0x03, 0xa8, 0x0f, 0x04, 0x03, 0x40, 0x2e, 0x05, 0x04, 0x50, 0x2e, 0x05, 0x04, + 0xe0, 0x0c, 0x06, 0x04, 0x00, 0x08, 0x08, 0x05, 0xc0, 0x09, 0x0a, 0x06, 0x98, 0x06, 0x00, 0x02, 0x9c, 0x06, 0x00, 0x02, 0xa0, 0x06, 0x00, 0x02, 0xa4, 0x06, 0x00, 0x02, 0x4c, 0x36, 0x01, 0x02, + 0x50, 0x36, 0x01, 0x02, 0x54, 0x36, 0x01, 0x02, 0x58, 0x36, 0x01, 0x02, 0x5c, 0x36, 0x01, 0x02, 0x60, 0x36, 0x01, 0x02, 0x7c, 0x12, 0x02, 0x02, 0x80, 0x12, 0x02, 0x02, 0x84, 0x12, 0x02, 0x02, + 0x88, 0x12, 0x02, 0x02, 0x80, 0x32, 0x03, 0x03, 0x88, 0x32, 0x03, 0x03, 0x90, 0x32, 0x03, 0x03, 0xb0, 0x0f, 0x04, 0x03, 0xb8, 0x0f, 0x04, 0x03, 0x60, 0x2e, 0x05, 0x04, 0x70, 0x2e, 0x05, 0x04, + 0xf0, 0x0c, 0x06, 0x04, 0x20, 0x08, 0x08, 0x05, 0x00, 0x20, 0x0b, 0x07, 0xa8, 0x06, 0x00, 0x02, 0xac, 0x06, 0x00, 0x02, 0xb0, 0x06, 0x00, 0x02, 0xb4, 0x06, 0x00, 0x02, 0x64, 0x36, 0x01, 0x02, + 0x68, 0x36, 0x01, 0x02, 0x6c, 0x36, 0x01, 0x02, 0x70, 0x36, 0x01, 0x02, 0x74, 0x36, 0x01, 0x02, 0x78, 0x36, 0x01, 0x02, 0x8c, 0x12, 0x02, 0x02, 0x90, 0x12, 0x02, 0x02, 0x94, 0x12, 0x02, 0x02, + 0x98, 0x12, 0x02, 0x02, 0x98, 0x32, 0x03, 0x03, 0xa0, 0x32, 0x03, 0x03, 0xa8, 0x32, 0x03, 0x03, 0xc0, 0x0f, 0x04, 0x03, 0xc8, 0x0f, 0x04, 0x03, 0x80, 0x2e, 0x05, 0x04, 0x90, 0x2e, 0x05, 0x04, + 0x00, 0x0d, 0x06, 0x04, 0x40, 0x08, 0x08, 0x05, 0x80, 0x20, 0x0b, 0x07, 0xb8, 0x06, 0x00, 0x02, 0xbc, 0x06, 0x00, 0x02, 0xc0, 0x06, 0x00, 0x02, 0xc4, 0x06, 0x00, 0x02, 0x7c, 0x36, 0x01, 0x02, + 0x80, 0x36, 0x01, 0x02, 0x84, 0x36, 0x01, 0x02, 0x88, 0x36, 0x01, 0x02, 0x8c, 0x36, 0x01, 0x02, 0x90, 0x36, 0x01, 0x02, 0x9c, 0x12, 0x02, 0x02, 0xa0, 0x12, 0x02, 0x02, 0xa4, 0x12, 0x02, 0x02, + 0xa8, 0x12, 0x02, 0x02, 0xb0, 0x32, 0x03, 0x03, 0xb8, 0x32, 0x03, 0x03, 0xc0, 0x32, 0x03, 0x03, 0xd0, 0x0f, 0x04, 0x03, 0xd8, 0x0f, 0x04, 0x03, 0xa0, 0x2e, 0x05, 0x04, 0xb0, 0x2e, 0x05, 0x04, + 0x10, 0x0d, 0x06, 0x04, 0x60, 0x08, 0x08, 0x05, 0x00, 0x21, 0x0b, 0x07, 0xc8, 0x06, 0x00, 0x02, 0xcc, 0x06, 0x00, 0x02, 0xd0, 0x06, 0x00, 0x02, 0xd4, 0x06, 0x00, 0x02, 0x94, 0x36, 0x01, 0x02, + 0x98, 0x36, 0x01, 0x02, 0x9c, 0x36, 0x01, 0x02, 0xa0, 0x36, 0x01, 0x02, 0xa4, 0x36, 0x01, 0x02, 0xa8, 0x36, 0x01, 0x02, 0xac, 0x12, 0x02, 0x02, 0xb0, 0x12, 0x02, 0x02, 0xb4, 0x12, 0x02, 0x02, + 0xb8, 0x12, 0x02, 0x02, 0xc8, 0x32, 0x03, 0x03, 0xd0, 0x32, 0x03, 0x03, 0xd8, 0x32, 0x03, 0x03, 0xe0, 0x0f, 0x04, 0x03, 0xe8, 0x0f, 0x04, 0x03, 0xc0, 0x2e, 0x05, 0x04, 0xd0, 0x2e, 0x05, 0x04, + 0x20, 0x0d, 0x06, 0x04, 0x80, 0x08, 0x08, 0x05, 0x80, 0x21, 0x0b, 0x07, 0xd8, 0x06, 0x00, 0x02, 0xdc, 0x06, 0x00, 0x02, 0xe0, 0x06, 0x00, 0x02, 0xe4, 0x06, 0x00, 0x02, 0xac, 0x36, 0x01, 0x02, + 0xb0, 0x36, 0x01, 0x02, 0xb4, 0x36, 0x01, 0x02, 0xb8, 0x36, 0x01, 0x02, 0xbc, 0x36, 0x01, 0x02, 0xc0, 0x36, 0x01, 0x02, 0xbc, 0x12, 0x02, 0x02, 0xc0, 0x12, 0x02, 0x02, 0xc4, 0x12, 0x02, 0x02, + 0xc8, 0x12, 0x02, 0x02, 0xe0, 0x32, 0x03, 0x03, 0xe8, 0x32, 0x03, 0x03, 0xf0, 0x32, 0x03, 0x03, 0xf0, 0x0f, 0x04, 0x03, 0xf8, 0x0f, 0x04, 0x03, 0xe0, 0x2e, 0x05, 0x04, 0xf0, 0x2e, 0x05, 0x04, + 0x30, 0x0d, 0x06, 0x04, 0xa0, 0x08, 0x08, 0x05, 0x00, 0x22, 0x0b, 0x07, 0xe8, 0x06, 0x00, 0x02, 0xec, 0x06, 0x00, 0x02, 0xf0, 0x06, 0x00, 0x02, 0xf4, 0x06, 0x00, 0x02, 0xc4, 0x36, 0x01, 0x02, + 0xc8, 0x36, 0x01, 0x02, 0xcc, 0x36, 0x01, 0x02, 0xd0, 0x36, 0x01, 0x02, 0xd4, 0x36, 0x01, 0x02, 0xd8, 0x36, 0x01, 0x02, 0xcc, 0x12, 0x02, 0x02, 0xd0, 0x12, 0x02, 0x02, 0xd4, 0x12, 0x02, 0x02, + 0xd8, 0x12, 0x02, 0x02, 0xf8, 0x32, 0x03, 0x03, 0x00, 0x33, 0x03, 0x03, 0x08, 0x33, 0x03, 0x03, 0x00, 0x10, 0x04, 0x03, 0x08, 0x10, 0x04, 0x03, 0x00, 0x2f, 0x05, 0x04, 0x10, 0x2f, 0x05, 0x04, + 0x40, 0x0d, 0x06, 0x04, 0xc0, 0x08, 0x08, 0x05, 0x80, 0x22, 0x0b, 0x07, 0xf8, 0x06, 0x00, 0x02, 0xfc, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x04, 0x07, 0x00, 0x02, 0xdc, 0x36, 0x01, 0x02, + 0xe0, 0x36, 0x01, 0x02, 0xe4, 0x36, 0x01, 0x02, 0xe8, 0x36, 0x01, 0x02, 0xec, 0x36, 0x01, 0x02, 0xf0, 0x36, 0x01, 0x02, 0xdc, 0x12, 0x02, 0x02, 0xe0, 0x12, 0x02, 0x02, 0xe4, 0x12, 0x02, 0x02, + 0xe8, 0x12, 0x02, 0x02, 0x10, 0x33, 0x03, 0x03, 0x18, 0x33, 0x03, 0x03, 0x20, 0x33, 0x03, 0x03, 0x10, 0x10, 0x04, 0x03, 0x18, 0x10, 0x04, 0x03, 0x20, 0x2f, 0x05, 0x04, 0x30, 0x2f, 0x05, 0x04, + 0x50, 0x0d, 0x06, 0x04, 0xe0, 0x08, 0x08, 0x05, 0x00, 0x23, 0x0b, 0x07, 0x08, 0x07, 0x00, 0x02, 0x0c, 0x07, 0x00, 0x02, 0x10, 0x07, 0x00, 0x02, 0x14, 0x07, 0x00, 0x02, 0xf4, 0x36, 0x01, 0x02, + 0xf8, 0x36, 0x01, 0x02, 0xfc, 0x36, 0x01, 0x02, 0x00, 0x37, 0x01, 0x02, 0x04, 0x37, 0x01, 0x02, 0x08, 0x37, 0x01, 0x02, 0xec, 0x12, 0x02, 0x02, 0xf0, 0x12, 0x02, 0x02, 0xf4, 0x12, 0x02, 0x02, + 0xf8, 0x12, 0x02, 0x02, 0x28, 0x33, 0x03, 0x03, 0x30, 0x33, 0x03, 0x03, 0x38, 0x33, 0x03, 0x03, 0x20, 0x10, 0x04, 0x03, 0x28, 0x10, 0x04, 0x03, 0x40, 0x2f, 0x05, 0x04, 0x50, 0x2f, 0x05, 0x04, + 0x60, 0x0d, 0x06, 0x04, 0x00, 0x09, 0x08, 0x05, 0x80, 0x23, 0x0b, 0x07, 0x18, 0x07, 0x00, 0x02, 0x1c, 0x07, 0x00, 0x02, 0x20, 0x07, 0x00, 0x02, 0x24, 0x07, 0x00, 0x02, 0x0c, 0x37, 0x01, 0x02, + 0x10, 0x37, 0x01, 0x02, 0x14, 0x37, 0x01, 0x02, 0x18, 0x37, 0x01, 0x02, 0x1c, 0x37, 0x01, 0x02, 0x20, 0x37, 0x01, 0x02, 0xfc, 0x12, 0x02, 0x02, 0x00, 0x13, 0x02, 0x02, 0x04, 0x13, 0x02, 0x02, + 0x08, 0x13, 0x02, 0x02, 0x40, 0x33, 0x03, 0x03, 0x48, 0x33, 0x03, 0x03, 0x50, 0x33, 0x03, 0x03, 0x30, 0x10, 0x04, 0x03, 0x38, 0x10, 0x04, 0x03, 0x60, 0x2f, 0x05, 0x04, 0x70, 0x2f, 0x05, 0x04, + 0x70, 0x0d, 0x06, 0x04, 0x20, 0x09, 0x08, 0x05, 0x00, 0x24, 0x0b, 0x07, 0x28, 0x07, 0x00, 0x02, 0x2c, 0x07, 0x00, 0x02, 0x30, 0x07, 0x00, 0x02, 0x34, 0x07, 0x00, 0x02, 0x24, 0x37, 0x01, 0x02, + 0x28, 0x37, 0x01, 0x02, 0x2c, 0x37, 0x01, 0x02, 0x30, 0x37, 0x01, 0x02, 0x34, 0x37, 0x01, 0x02, 0x38, 0x37, 0x01, 0x02, 0x0c, 0x13, 0x02, 0x02, 0x10, 0x13, 0x02, 0x02, 0x14, 0x13, 0x02, 0x02, + 0x18, 0x13, 0x02, 0x02, 0x58, 0x33, 0x03, 0x03, 0x60, 0x33, 0x03, 0x03, 0x68, 0x33, 0x03, 0x03, 0x40, 0x10, 0x04, 0x03, 0x48, 0x10, 0x04, 0x03, 0x80, 0x2f, 0x05, 0x04, 0x90, 0x2f, 0x05, 0x04, + 0x80, 0x0d, 0x06, 0x04, 0x40, 0x09, 0x08, 0x05, 0x80, 0x24, 0x0b, 0x07, 0x38, 0x07, 0x00, 0x02, 0x3c, 0x07, 0x00, 0x02, 0x40, 0x07, 0x00, 0x02, 0x44, 0x07, 0x00, 0x02, 0x3c, 0x37, 0x01, 0x02, + 0x40, 0x37, 0x01, 0x02, 0x44, 0x37, 0x01, 0x02, 0x48, 0x37, 0x01, 0x02, 0x4c, 0x37, 0x01, 0x02, 0x50, 0x37, 0x01, 0x02, 0x1c, 0x13, 0x02, 0x02, 0x20, 0x13, 0x02, 0x02, 0x24, 0x13, 0x02, 0x02, + 0x28, 0x13, 0x02, 0x02, 0x70, 0x33, 0x03, 0x03, 0x78, 0x33, 0x03, 0x03, 0x80, 0x33, 0x03, 0x03, 0x50, 0x10, 0x04, 0x03, 0x58, 0x10, 0x04, 0x03, 0xa0, 0x2f, 0x05, 0x04, 0xb0, 0x2f, 0x05, 0x04, + 0x90, 0x0d, 0x06, 0x04, 0x60, 0x09, 0x08, 0x05, 0x00, 0x25, 0x0b, 0x07, 0x48, 0x07, 0x00, 0x02, 0x4c, 0x07, 0x00, 0x02, 0x50, 0x07, 0x00, 0x02, 0x54, 0x07, 0x00, 0x02, 0x54, 0x37, 0x01, 0x02, + 0x58, 0x37, 0x01, 0x02, 0x5c, 0x37, 0x01, 0x02, 0x60, 0x37, 0x01, 0x02, 0x64, 0x37, 0x01, 0x02, 0x68, 0x37, 0x01, 0x02, 0x2c, 0x13, 0x02, 0x02, 0x30, 0x13, 0x02, 0x02, 0x34, 0x13, 0x02, 0x02, + 0x38, 0x13, 0x02, 0x02, 0x88, 0x33, 0x03, 0x03, 0x90, 0x33, 0x03, 0x03, 0x98, 0x33, 0x03, 0x03, 0x60, 0x10, 0x04, 0x03, 0x68, 0x10, 0x04, 0x03, 0xc0, 0x2f, 0x05, 0x04, 0xd0, 0x2f, 0x05, 0x04, + 0xa0, 0x0d, 0x06, 0x04, 0x80, 0x09, 0x08, 0x05, 0x80, 0x25, 0x0b, 0x07, 0x58, 0x07, 0x00, 0x02, 0x5c, 0x07, 0x00, 0x02, 0x60, 0x07, 0x00, 0x02, 0x64, 0x07, 0x00, 0x02, 0x6c, 0x37, 0x01, 0x02, + 0x70, 0x37, 0x01, 0x02, 0x74, 0x37, 0x01, 0x02, 0x78, 0x37, 0x01, 0x02, 0x7c, 0x37, 0x01, 0x02, 0x80, 0x37, 0x01, 0x02, 0x3c, 0x13, 0x02, 0x02, 0x40, 0x13, 0x02, 0x02, 0x44, 0x13, 0x02, 0x02, + 0x48, 0x13, 0x02, 0x02, 0xa0, 0x33, 0x03, 0x03, 0xa8, 0x33, 0x03, 0x03, 0xb0, 0x33, 0x03, 0x03, 0x70, 0x10, 0x04, 0x03, 0x78, 0x10, 0x04, 0x03, 0xe0, 0x2f, 0x05, 0x04, 0xf0, 0x2f, 0x05, 0x04, + 0xb0, 0x0d, 0x06, 0x04, 0xa0, 0x09, 0x08, 0x05, 0x00, 0x26, 0x0b, 0x07, 0x68, 0x07, 0x00, 0x02, 0x6c, 0x07, 0x00, 0x02, 0x70, 0x07, 0x00, 0x02, 0x74, 0x07, 0x00, 0x02, 0x84, 0x37, 0x01, 0x02, + 0x88, 0x37, 0x01, 0x02, 0x8c, 0x37, 0x01, 0x02, 0x90, 0x37, 0x01, 0x02, 0x94, 0x37, 0x01, 0x02, 0x98, 0x37, 0x01, 0x02, 0x4c, 0x13, 0x02, 0x02, 0x50, 0x13, 0x02, 0x02, 0x54, 0x13, 0x02, 0x02, + 0x58, 0x13, 0x02, 0x02, 0xb8, 0x33, 0x03, 0x03, 0xc0, 0x33, 0x03, 0x03, 0xc8, 0x33, 0x03, 0x03, 0x80, 0x10, 0x04, 0x03, 0x88, 0x10, 0x04, 0x03, 0x00, 0x30, 0x05, 0x04, 0x10, 0x30, 0x05, 0x04, + 0xc0, 0x0d, 0x06, 0x04, 0xc0, 0x09, 0x08, 0x05, 0x80, 0x26, 0x0b, 0x07, 0x78, 0x07, 0x00, 0x02, 0x7c, 0x07, 0x00, 0x02, 0x80, 0x07, 0x00, 0x02, 0x84, 0x07, 0x00, 0x02, 0x9c, 0x37, 0x01, 0x02, + 0xa0, 0x37, 0x01, 0x02, 0xa4, 0x37, 0x01, 0x02, 0xa8, 0x37, 0x01, 0x02, 0xac, 0x37, 0x01, 0x02, 0xb0, 0x37, 0x01, 0x02, 0x5c, 0x13, 0x02, 0x02, 0x60, 0x13, 0x02, 0x02, 0x64, 0x13, 0x02, 0x02, + 0x68, 0x13, 0x02, 0x02, 0xd0, 0x33, 0x03, 0x03, 0xd8, 0x33, 0x03, 0x03, 0xe0, 0x33, 0x03, 0x03, 0x90, 0x10, 0x04, 0x03, 0x98, 0x10, 0x04, 0x03, 0x20, 0x30, 0x05, 0x04, 0x30, 0x30, 0x05, 0x04, + 0xd0, 0x0d, 0x06, 0x04, 0xe0, 0x09, 0x08, 0x05, 0x80, 0x02, 0x0c, 0x07, 0x88, 0x07, 0x00, 0x02, 0x8c, 0x07, 0x00, 0x02, 0x90, 0x07, 0x00, 0x02, 0x94, 0x07, 0x00, 0x02, 0xb4, 0x37, 0x01, 0x02, + 0xb8, 0x37, 0x01, 0x02, 0xbc, 0x37, 0x01, 0x02, 0xc0, 0x37, 0x01, 0x02, 0xc4, 0x37, 0x01, 0x02, 0xc8, 0x37, 0x01, 0x02, 0x6c, 0x13, 0x02, 0x02, 0x70, 0x13, 0x02, 0x02, 0x74, 0x13, 0x02, 0x02, + 0x78, 0x13, 0x02, 0x02, 0xe8, 0x33, 0x03, 0x03, 0xf0, 0x33, 0x03, 0x03, 0xf8, 0x33, 0x03, 0x03, 0xa0, 0x10, 0x04, 0x03, 0xa8, 0x10, 0x04, 0x03, 0x40, 0x30, 0x05, 0x04, 0x50, 0x30, 0x05, 0x04, + 0xe0, 0x0d, 0x06, 0x04, 0x00, 0x0a, 0x08, 0x05, 0x00, 0x03, 0x0c, 0x07, 0x98, 0x07, 0x00, 0x02, 0x9c, 0x07, 0x00, 0x02, 0xa0, 0x07, 0x00, 0x02, 0xa4, 0x07, 0x00, 0x02, 0xcc, 0x37, 0x01, 0x02, + 0xd0, 0x37, 0x01, 0x02, 0xd4, 0x37, 0x01, 0x02, 0xd8, 0x37, 0x01, 0x02, 0xdc, 0x37, 0x01, 0x02, 0xe0, 0x37, 0x01, 0x02, 0x7c, 0x13, 0x02, 0x02, 0x80, 0x13, 0x02, 0x02, 0x84, 0x13, 0x02, 0x02, + 0x88, 0x13, 0x02, 0x02, 0x00, 0x34, 0x03, 0x03, 0x08, 0x34, 0x03, 0x03, 0x10, 0x34, 0x03, 0x03, 0xb0, 0x10, 0x04, 0x03, 0xb8, 0x10, 0x04, 0x03, 0x60, 0x30, 0x05, 0x04, 0x70, 0x30, 0x05, 0x04, + 0xf0, 0x0d, 0x06, 0x04, 0x20, 0x0a, 0x08, 0x05, 0x80, 0x03, 0x0c, 0x07, 0xa8, 0x07, 0x00, 0x02, 0xac, 0x07, 0x00, 0x02, 0xb0, 0x07, 0x00, 0x02, 0xb4, 0x07, 0x00, 0x02, 0xe4, 0x37, 0x01, 0x02, + 0xe8, 0x37, 0x01, 0x02, 0xec, 0x37, 0x01, 0x02, 0xf0, 0x37, 0x01, 0x02, 0xf4, 0x37, 0x01, 0x02, 0xf8, 0x37, 0x01, 0x02, 0x8c, 0x13, 0x02, 0x02, 0x90, 0x13, 0x02, 0x02, 0x94, 0x13, 0x02, 0x02, + 0x98, 0x13, 0x02, 0x02, 0x18, 0x34, 0x03, 0x03, 0x20, 0x34, 0x03, 0x03, 0x28, 0x34, 0x03, 0x03, 0xc0, 0x10, 0x04, 0x03, 0xc8, 0x10, 0x04, 0x03, 0x80, 0x30, 0x05, 0x04, 0x90, 0x30, 0x05, 0x04, + 0x00, 0x0e, 0x06, 0x04, 0x40, 0x0a, 0x08, 0x05, 0x00, 0x04, 0x0c, 0x07, 0xb8, 0x07, 0x00, 0x02, 0xbc, 0x07, 0x00, 0x02, 0xc0, 0x07, 0x00, 0x02, 0xc4, 0x07, 0x00, 0x02, 0xfc, 0x37, 0x01, 0x02, + 0x00, 0x38, 0x01, 0x02, 0x04, 0x38, 0x01, 0x02, 0x08, 0x38, 0x01, 0x02, 0x0c, 0x38, 0x01, 0x02, 0x10, 0x38, 0x01, 0x02, 0x9c, 0x13, 0x02, 0x02, 0xa0, 0x13, 0x02, 0x02, 0xa4, 0x13, 0x02, 0x02, + 0xa8, 0x13, 0x02, 0x02, 0x30, 0x34, 0x03, 0x03, 0x38, 0x34, 0x03, 0x03, 0x40, 0x34, 0x03, 0x03, 0xd0, 0x10, 0x04, 0x03, 0xd8, 0x10, 0x04, 0x03, 0xa0, 0x30, 0x05, 0x04, 0xb0, 0x30, 0x05, 0x04, + 0x10, 0x0e, 0x06, 0x04, 0x60, 0x0a, 0x08, 0x05, 0x80, 0x04, 0x0c, 0x07, 0xc8, 0x07, 0x00, 0x02, 0xcc, 0x07, 0x00, 0x02, 0xd0, 0x07, 0x00, 0x02, 0x14, 0x38, 0x01, 0x02, 0x18, 0x38, 0x01, 0x02, + 0x1c, 0x38, 0x01, 0x02, 0x20, 0x38, 0x01, 0x02, 0x24, 0x38, 0x01, 0x02, 0x28, 0x38, 0x01, 0x02, 0x2c, 0x38, 0x01, 0x02, 0xac, 0x13, 0x02, 0x02, 0xb0, 0x13, 0x02, 0x02, 0xb4, 0x13, 0x02, 0x02, + 0xb8, 0x13, 0x02, 0x02, 0x48, 0x34, 0x03, 0x03, 0x50, 0x34, 0x03, 0x03, 0x58, 0x34, 0x03, 0x03, 0xe0, 0x10, 0x04, 0x03, 0xe8, 0x10, 0x04, 0x03, 0xc0, 0x30, 0x05, 0x04, 0xd0, 0x30, 0x05, 0x04, + 0x20, 0x0e, 0x06, 0x04, 0x80, 0x0a, 0x08, 0x05, 0x00, 0x05, 0x0c, 0x07, 0xd4, 0x07, 0x00, 0x02, 0xd8, 0x07, 0x00, 0x02, 0xdc, 0x07, 0x00, 0x02, 0x30, 0x38, 0x01, 0x02, 0x34, 0x38, 0x01, 0x02, + 0x38, 0x38, 0x01, 0x02, 0x3c, 0x38, 0x01, 0x02, 0x40, 0x38, 0x01, 0x02, 0x44, 0x38, 0x01, 0x02, 0x48, 0x38, 0x01, 0x02, 0xbc, 0x13, 0x02, 0x02, 0xc0, 0x13, 0x02, 0x02, 0xc4, 0x13, 0x02, 0x02, + 0xc8, 0x13, 0x02, 0x02, 0x60, 0x34, 0x03, 0x03, 0x68, 0x34, 0x03, 0x03, 0x70, 0x34, 0x03, 0x03, 0xf0, 0x10, 0x04, 0x03, 0xf8, 0x10, 0x04, 0x03, 0xe0, 0x30, 0x05, 0x04, 0x30, 0x0e, 0x06, 0x04, + 0x40, 0x0e, 0x06, 0x04, 0xa0, 0x0a, 0x08, 0x05, 0x80, 0x05, 0x0c, 0x07, 0xe0, 0x07, 0x00, 0x02, 0xe4, 0x07, 0x00, 0x02, 0xe8, 0x07, 0x00, 0x02, 0x4c, 0x38, 0x01, 0x02, 0x50, 0x38, 0x01, 0x02, + 0x54, 0x38, 0x01, 0x02, 0x58, 0x38, 0x01, 0x02, 0x5c, 0x38, 0x01, 0x02, 0x60, 0x38, 0x01, 0x02, 0x64, 0x38, 0x01, 0x02, 0xcc, 0x13, 0x02, 0x02, 0xd0, 0x13, 0x02, 0x02, 0xd4, 0x13, 0x02, 0x02, + 0xd8, 0x13, 0x02, 0x02, 0x78, 0x34, 0x03, 0x03, 0x80, 0x34, 0x03, 0x03, 0x88, 0x34, 0x03, 0x03, 0x00, 0x11, 0x04, 0x03, 0x08, 0x11, 0x04, 0x03, 0xf0, 0x30, 0x05, 0x04, 0x50, 0x0e, 0x06, 0x04, + 0x00, 0x2c, 0x07, 0x05, 0xc0, 0x0a, 0x08, 0x05, 0x00, 0x06, 0x0c, 0x07, 0xec, 0x07, 0x00, 0x02, 0xf0, 0x07, 0x00, 0x02, 0xf4, 0x07, 0x00, 0x02, 0x68, 0x38, 0x01, 0x02, 0x6c, 0x38, 0x01, 0x02, + 0x70, 0x38, 0x01, 0x02, 0x74, 0x38, 0x01, 0x02, 0x78, 0x38, 0x01, 0x02, 0x7c, 0x38, 0x01, 0x02, 0x80, 0x38, 0x01, 0x02, 0xdc, 0x13, 0x02, 0x02, 0xe0, 0x13, 0x02, 0x02, 0xe4, 0x13, 0x02, 0x02, + 0xe8, 0x13, 0x02, 0x02, 0x90, 0x34, 0x03, 0x03, 0x98, 0x34, 0x03, 0x03, 0xa0, 0x34, 0x03, 0x03, 0x10, 0x11, 0x04, 0x03, 0x18, 0x11, 0x04, 0x03, 0x00, 0x31, 0x05, 0x04, 0x60, 0x0e, 0x06, 0x04, + 0x20, 0x2c, 0x07, 0x05, 0xe0, 0x0a, 0x08, 0x05, 0x80, 0x06, 0x0c, 0x07, 0xf8, 0x07, 0x00, 0x02, 0xfc, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x84, 0x38, 0x01, 0x02, 0x88, 0x38, 0x01, 0x02, + 0x8c, 0x38, 0x01, 0x02, 0x90, 0x38, 0x01, 0x02, 0x94, 0x38, 0x01, 0x02, 0x98, 0x38, 0x01, 0x02, 0x9c, 0x38, 0x01, 0x02, 0xec, 0x13, 0x02, 0x02, 0xf0, 0x13, 0x02, 0x02, 0xf4, 0x13, 0x02, 0x02, + 0xf8, 0x13, 0x02, 0x02, 0xa8, 0x34, 0x03, 0x03, 0xb0, 0x34, 0x03, 0x03, 0xb8, 0x34, 0x03, 0x03, 0x20, 0x11, 0x04, 0x03, 0x28, 0x11, 0x04, 0x03, 0x10, 0x31, 0x05, 0x04, 0x70, 0x0e, 0x06, 0x04, + 0x40, 0x2c, 0x07, 0x05, 0x00, 0x0b, 0x08, 0x05, 0x00, 0x07, 0x0c, 0x07, 0x04, 0x08, 0x00, 0x02, 0x08, 0x08, 0x00, 0x02, 0x0c, 0x08, 0x00, 0x02, 0xa0, 0x38, 0x01, 0x02, 0xa4, 0x38, 0x01, 0x02, + 0xa8, 0x38, 0x01, 0x02, 0xac, 0x38, 0x01, 0x02, 0xb0, 0x38, 0x01, 0x02, 0xb4, 0x38, 0x01, 0x02, 0xb8, 0x38, 0x01, 0x02, 0xfc, 0x13, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x04, 0x14, 0x02, 0x02, + 0x08, 0x14, 0x02, 0x02, 0xc0, 0x34, 0x03, 0x03, 0xc8, 0x34, 0x03, 0x03, 0xd0, 0x34, 0x03, 0x03, 0x30, 0x11, 0x04, 0x03, 0x38, 0x11, 0x04, 0x03, 0x20, 0x31, 0x05, 0x04, 0x80, 0x0e, 0x06, 0x04, + 0x60, 0x2c, 0x07, 0x05, 0x20, 0x0b, 0x08, 0x05, 0x00, 0x1d, 0x0d, 0x08, 0x10, 0x08, 0x00, 0x02, 0x14, 0x08, 0x00, 0x02, 0x18, 0x08, 0x00, 0x02, 0xbc, 0x38, 0x01, 0x02, 0xc0, 0x38, 0x01, 0x02, + 0xc4, 0x38, 0x01, 0x02, 0xc8, 0x38, 0x01, 0x02, 0xcc, 0x38, 0x01, 0x02, 0xd0, 0x38, 0x01, 0x02, 0xd4, 0x38, 0x01, 0x02, 0x0c, 0x14, 0x02, 0x02, 0x10, 0x14, 0x02, 0x02, 0x14, 0x14, 0x02, 0x02, + 0x18, 0x14, 0x02, 0x02, 0xd8, 0x34, 0x03, 0x03, 0xe0, 0x34, 0x03, 0x03, 0xe8, 0x34, 0x03, 0x03, 0x40, 0x11, 0x04, 0x03, 0x48, 0x11, 0x04, 0x03, 0x30, 0x31, 0x05, 0x04, 0x90, 0x0e, 0x06, 0x04, + 0x80, 0x2c, 0x07, 0x05, 0x40, 0x0b, 0x08, 0x05, 0x00, 0x1e, 0x0d, 0x08, 0x1c, 0x08, 0x00, 0x02, 0x20, 0x08, 0x00, 0x02, 0x24, 0x08, 0x00, 0x02, 0xd8, 0x38, 0x01, 0x02, 0xdc, 0x38, 0x01, 0x02, + 0xe0, 0x38, 0x01, 0x02, 0xe4, 0x38, 0x01, 0x02, 0xe8, 0x38, 0x01, 0x02, 0xec, 0x38, 0x01, 0x02, 0xf0, 0x38, 0x01, 0x02, 0x1c, 0x14, 0x02, 0x02, 0x20, 0x14, 0x02, 0x02, 0x24, 0x14, 0x02, 0x02, + 0x28, 0x14, 0x02, 0x02, 0xf0, 0x34, 0x03, 0x03, 0xf8, 0x34, 0x03, 0x03, 0x00, 0x35, 0x03, 0x03, 0x50, 0x11, 0x04, 0x03, 0x58, 0x11, 0x04, 0x03, 0x40, 0x31, 0x05, 0x04, 0xa0, 0x0e, 0x06, 0x04, + 0xa0, 0x2c, 0x07, 0x05, 0x60, 0x0b, 0x08, 0x05, 0x00, 0x1f, 0x0d, 0x08, 0x28, 0x08, 0x00, 0x02, 0x2c, 0x08, 0x00, 0x02, 0x30, 0x08, 0x00, 0x02, 0xf4, 0x38, 0x01, 0x02, 0xf8, 0x38, 0x01, 0x02, + 0xfc, 0x38, 0x01, 0x02, 0x00, 0x39, 0x01, 0x02, 0x04, 0x39, 0x01, 0x02, 0x08, 0x39, 0x01, 0x02, 0x0c, 0x39, 0x01, 0x02, 0x2c, 0x14, 0x02, 0x02, 0x30, 0x14, 0x02, 0x02, 0x34, 0x14, 0x02, 0x02, + 0x38, 0x14, 0x02, 0x02, 0x08, 0x35, 0x03, 0x03, 0x10, 0x35, 0x03, 0x03, 0x18, 0x35, 0x03, 0x03, 0x60, 0x11, 0x04, 0x03, 0x68, 0x11, 0x04, 0x03, 0x50, 0x31, 0x05, 0x04, 0xb0, 0x0e, 0x06, 0x04, + 0xc0, 0x2c, 0x07, 0x05, 0x80, 0x0b, 0x08, 0x05, 0x00, 0x20, 0x0d, 0x08, 0x34, 0x08, 0x00, 0x02, 0x38, 0x08, 0x00, 0x02, 0x3c, 0x08, 0x00, 0x02, 0x10, 0x39, 0x01, 0x02, 0x14, 0x39, 0x01, 0x02, + 0x18, 0x39, 0x01, 0x02, 0x1c, 0x39, 0x01, 0x02, 0x20, 0x39, 0x01, 0x02, 0x24, 0x39, 0x01, 0x02, 0x28, 0x39, 0x01, 0x02, 0x3c, 0x14, 0x02, 0x02, 0x40, 0x14, 0x02, 0x02, 0x44, 0x14, 0x02, 0x02, + 0x48, 0x14, 0x02, 0x02, 0x20, 0x35, 0x03, 0x03, 0x28, 0x35, 0x03, 0x03, 0x30, 0x35, 0x03, 0x03, 0x70, 0x11, 0x04, 0x03, 0x78, 0x11, 0x04, 0x03, 0x60, 0x31, 0x05, 0x04, 0xc0, 0x0e, 0x06, 0x04, + 0xe0, 0x2c, 0x07, 0x05, 0xa0, 0x0b, 0x08, 0x05, 0x00, 0x21, 0x0d, 0x08, 0x40, 0x08, 0x00, 0x02, 0x44, 0x08, 0x00, 0x02, 0x48, 0x08, 0x00, 0x02, 0x2c, 0x39, 0x01, 0x02, 0x30, 0x39, 0x01, 0x02, + 0x34, 0x39, 0x01, 0x02, 0x38, 0x39, 0x01, 0x02, 0x3c, 0x39, 0x01, 0x02, 0x40, 0x39, 0x01, 0x02, 0x44, 0x39, 0x01, 0x02, 0x4c, 0x14, 0x02, 0x02, 0x50, 0x14, 0x02, 0x02, 0x54, 0x14, 0x02, 0x02, + 0x58, 0x14, 0x02, 0x02, 0x38, 0x35, 0x03, 0x03, 0x40, 0x35, 0x03, 0x03, 0x48, 0x35, 0x03, 0x03, 0x80, 0x11, 0x04, 0x03, 0x88, 0x11, 0x04, 0x03, 0x70, 0x31, 0x05, 0x04, 0xd0, 0x0e, 0x06, 0x04, + 0x00, 0x2d, 0x07, 0x05, 0xc0, 0x0b, 0x08, 0x05, 0x00, 0x22, 0x0d, 0x08, 0x4c, 0x08, 0x00, 0x02, 0x50, 0x08, 0x00, 0x02, 0x54, 0x08, 0x00, 0x02, 0x48, 0x39, 0x01, 0x02, 0x4c, 0x39, 0x01, 0x02, + 0x50, 0x39, 0x01, 0x02, 0x54, 0x39, 0x01, 0x02, 0x58, 0x39, 0x01, 0x02, 0x5c, 0x39, 0x01, 0x02, 0x60, 0x39, 0x01, 0x02, 0x5c, 0x14, 0x02, 0x02, 0x60, 0x14, 0x02, 0x02, 0x64, 0x14, 0x02, 0x02, + 0x68, 0x14, 0x02, 0x02, 0x50, 0x35, 0x03, 0x03, 0x58, 0x35, 0x03, 0x03, 0x60, 0x35, 0x03, 0x03, 0x90, 0x11, 0x04, 0x03, 0x98, 0x11, 0x04, 0x03, 0x80, 0x31, 0x05, 0x04, 0xe0, 0x0e, 0x06, 0x04, + 0x20, 0x2d, 0x07, 0x05, 0xe0, 0x0b, 0x08, 0x05, 0x00, 0x01, 0x0e, 0x08, 0x58, 0x08, 0x00, 0x02, 0x5c, 0x08, 0x00, 0x02, 0x60, 0x08, 0x00, 0x02, 0x64, 0x39, 0x01, 0x02, 0x68, 0x39, 0x01, 0x02, + 0x6c, 0x39, 0x01, 0x02, 0x70, 0x39, 0x01, 0x02, 0x74, 0x39, 0x01, 0x02, 0x78, 0x39, 0x01, 0x02, 0x7c, 0x39, 0x01, 0x02, 0x6c, 0x14, 0x02, 0x02, 0x70, 0x14, 0x02, 0x02, 0x74, 0x14, 0x02, 0x02, + 0x78, 0x14, 0x02, 0x02, 0x68, 0x35, 0x03, 0x03, 0x70, 0x35, 0x03, 0x03, 0x78, 0x35, 0x03, 0x03, 0xa0, 0x11, 0x04, 0x03, 0xa8, 0x11, 0x04, 0x03, 0x90, 0x31, 0x05, 0x04, 0xf0, 0x0e, 0x06, 0x04, + 0x40, 0x2d, 0x07, 0x05, 0x00, 0x0c, 0x08, 0x05, 0x00, 0x02, 0x0e, 0x08, 0x64, 0x08, 0x00, 0x02, 0x68, 0x08, 0x00, 0x02, 0x6c, 0x08, 0x00, 0x02, 0x80, 0x39, 0x01, 0x02, 0x84, 0x39, 0x01, 0x02, + 0x88, 0x39, 0x01, 0x02, 0x8c, 0x39, 0x01, 0x02, 0x90, 0x39, 0x01, 0x02, 0x94, 0x39, 0x01, 0x02, 0x98, 0x39, 0x01, 0x02, 0x7c, 0x14, 0x02, 0x02, 0x80, 0x14, 0x02, 0x02, 0x84, 0x14, 0x02, 0x02, + 0x88, 0x14, 0x02, 0x02, 0x80, 0x35, 0x03, 0x03, 0x88, 0x35, 0x03, 0x03, 0x90, 0x35, 0x03, 0x03, 0xb0, 0x11, 0x04, 0x03, 0xb8, 0x11, 0x04, 0x03, 0xa0, 0x31, 0x05, 0x04, 0x00, 0x0f, 0x06, 0x04, + 0x60, 0x2d, 0x07, 0x05, 0x20, 0x0c, 0x08, 0x05, 0x00, 0x03, 0x0e, 0x08, 0x70, 0x08, 0x00, 0x02, 0x74, 0x08, 0x00, 0x02, 0x78, 0x08, 0x00, 0x02, 0x9c, 0x39, 0x01, 0x02, 0xa0, 0x39, 0x01, 0x02, + 0xa4, 0x39, 0x01, 0x02, 0xa8, 0x39, 0x01, 0x02, 0xac, 0x39, 0x01, 0x02, 0xb0, 0x39, 0x01, 0x02, 0xb4, 0x39, 0x01, 0x02, 0x8c, 0x14, 0x02, 0x02, 0x90, 0x14, 0x02, 0x02, 0x94, 0x14, 0x02, 0x02, + 0x98, 0x14, 0x02, 0x02, 0x98, 0x35, 0x03, 0x03, 0xa0, 0x35, 0x03, 0x03, 0xa8, 0x35, 0x03, 0x03, 0xc0, 0x11, 0x04, 0x03, 0xc8, 0x11, 0x04, 0x03, 0xb0, 0x31, 0x05, 0x04, 0x10, 0x0f, 0x06, 0x04, + 0x80, 0x2d, 0x07, 0x05, 0x40, 0x0c, 0x08, 0x05, 0x00, 0x04, 0x0e, 0x08, 0x7c, 0x08, 0x00, 0x02, 0x80, 0x08, 0x00, 0x02, 0x84, 0x08, 0x00, 0x02, 0xb8, 0x39, 0x01, 0x02, 0xbc, 0x39, 0x01, 0x02, + 0xc0, 0x39, 0x01, 0x02, 0xc4, 0x39, 0x01, 0x02, 0xc8, 0x39, 0x01, 0x02, 0xcc, 0x39, 0x01, 0x02, 0xd0, 0x39, 0x01, 0x02, 0x9c, 0x14, 0x02, 0x02, 0xa0, 0x14, 0x02, 0x02, 0xa4, 0x14, 0x02, 0x02, + 0xa8, 0x14, 0x02, 0x02, 0xb0, 0x35, 0x03, 0x03, 0xb8, 0x35, 0x03, 0x03, 0xc0, 0x35, 0x03, 0x03, 0xd0, 0x11, 0x04, 0x03, 0xd8, 0x11, 0x04, 0x03, 0xc0, 0x31, 0x05, 0x04, 0x20, 0x0f, 0x06, 0x04, + 0xa0, 0x2d, 0x07, 0x05, 0x60, 0x0c, 0x08, 0x05, 0x00, 0x05, 0x0e, 0x08, 0x88, 0x08, 0x00, 0x02, 0x8c, 0x08, 0x00, 0x02, 0x90, 0x08, 0x00, 0x02, 0xd4, 0x39, 0x01, 0x02, 0xd8, 0x39, 0x01, 0x02, + 0xdc, 0x39, 0x01, 0x02, 0xe0, 0x39, 0x01, 0x02, 0xe4, 0x39, 0x01, 0x02, 0xe8, 0x39, 0x01, 0x02, 0xac, 0x14, 0x02, 0x02, 0xb0, 0x14, 0x02, 0x02, 0xb4, 0x14, 0x02, 0x02, 0xb8, 0x14, 0x02, 0x02, + 0xbc, 0x14, 0x02, 0x02, 0xc8, 0x35, 0x03, 0x03, 0xd0, 0x35, 0x03, 0x03, 0xd8, 0x35, 0x03, 0x03, 0xe0, 0x11, 0x04, 0x03, 0xe8, 0x11, 0x04, 0x03, 0xd0, 0x31, 0x05, 0x04, 0x30, 0x0f, 0x06, 0x04, + 0xc0, 0x2d, 0x07, 0x05, 0x80, 0x0c, 0x08, 0x05, 0x00, 0x1e, 0x0f, 0x09, 0x94, 0x08, 0x00, 0x02, 0x98, 0x08, 0x00, 0x02, 0x9c, 0x08, 0x00, 0x02, 0xec, 0x39, 0x01, 0x02, 0xf0, 0x39, 0x01, 0x02, + 0xf4, 0x39, 0x01, 0x02, 0xf8, 0x39, 0x01, 0x02, 0xfc, 0x39, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0xc0, 0x14, 0x02, 0x02, 0xc4, 0x14, 0x02, 0x02, 0xc8, 0x14, 0x02, 0x02, 0xcc, 0x14, 0x02, 0x02, + 0xd0, 0x14, 0x02, 0x02, 0xe0, 0x35, 0x03, 0x03, 0xe8, 0x35, 0x03, 0x03, 0xf0, 0x35, 0x03, 0x03, 0xf0, 0x11, 0x04, 0x03, 0xf8, 0x11, 0x04, 0x03, 0xe0, 0x31, 0x05, 0x04, 0x40, 0x0f, 0x06, 0x04, + 0xe0, 0x2d, 0x07, 0x05, 0x00, 0x2a, 0x09, 0x06, 0x00, 0x20, 0x0f, 0x09, 0xa0, 0x08, 0x00, 0x02, 0xa4, 0x08, 0x00, 0x02, 0xa8, 0x08, 0x00, 0x02, 0x04, 0x3a, 0x01, 0x02, 0x08, 0x3a, 0x01, 0x02, + 0x0c, 0x3a, 0x01, 0x02, 0x10, 0x3a, 0x01, 0x02, 0x14, 0x3a, 0x01, 0x02, 0x18, 0x3a, 0x01, 0x02, 0xd4, 0x14, 0x02, 0x02, 0xd8, 0x14, 0x02, 0x02, 0xdc, 0x14, 0x02, 0x02, 0xe0, 0x14, 0x02, 0x02, + 0xe4, 0x14, 0x02, 0x02, 0xf8, 0x35, 0x03, 0x03, 0x00, 0x36, 0x03, 0x03, 0x08, 0x36, 0x03, 0x03, 0x00, 0x12, 0x04, 0x03, 0x08, 0x12, 0x04, 0x03, 0xf0, 0x31, 0x05, 0x04, 0x50, 0x0f, 0x06, 0x04, + 0x00, 0x2e, 0x07, 0x05, 0x40, 0x2a, 0x09, 0x06, 0x00, 0x22, 0x0f, 0x09, 0xac, 0x08, 0x00, 0x02, 0xb0, 0x08, 0x00, 0x02, 0xb4, 0x08, 0x00, 0x02, 0x1c, 0x3a, 0x01, 0x02, 0x20, 0x3a, 0x01, 0x02, + 0x24, 0x3a, 0x01, 0x02, 0x28, 0x3a, 0x01, 0x02, 0x2c, 0x3a, 0x01, 0x02, 0x30, 0x3a, 0x01, 0x02, 0xe8, 0x14, 0x02, 0x02, 0xec, 0x14, 0x02, 0x02, 0xf0, 0x14, 0x02, 0x02, 0xf4, 0x14, 0x02, 0x02, + 0xf8, 0x14, 0x02, 0x02, 0x10, 0x36, 0x03, 0x03, 0x18, 0x36, 0x03, 0x03, 0x20, 0x36, 0x03, 0x03, 0x10, 0x12, 0x04, 0x03, 0x18, 0x12, 0x04, 0x03, 0x00, 0x32, 0x05, 0x04, 0x60, 0x0f, 0x06, 0x04, + 0x20, 0x2e, 0x07, 0x05, 0x80, 0x2a, 0x09, 0x06, 0x00, 0x02, 0x10, 0x09, 0xb8, 0x08, 0x00, 0x02, 0xbc, 0x08, 0x00, 0x02, 0xc0, 0x08, 0x00, 0x02, 0x34, 0x3a, 0x01, 0x02, 0x38, 0x3a, 0x01, 0x02, + 0x3c, 0x3a, 0x01, 0x02, 0x40, 0x3a, 0x01, 0x02, 0x44, 0x3a, 0x01, 0x02, 0x48, 0x3a, 0x01, 0x02, 0xfc, 0x14, 0x02, 0x02, 0x00, 0x15, 0x02, 0x02, 0x04, 0x15, 0x02, 0x02, 0x08, 0x15, 0x02, 0x02, + 0x0c, 0x15, 0x02, 0x02, 0x28, 0x36, 0x03, 0x03, 0x30, 0x36, 0x03, 0x03, 0x38, 0x36, 0x03, 0x03, 0x20, 0x12, 0x04, 0x03, 0x28, 0x12, 0x04, 0x03, 0x10, 0x32, 0x05, 0x04, 0x70, 0x0f, 0x06, 0x04, + 0x40, 0x2e, 0x07, 0x05, 0xc0, 0x2a, 0x09, 0x06, 0x00, 0x04, 0x10, 0x09, 0xc4, 0x08, 0x00, 0x02, 0xc8, 0x08, 0x00, 0x02, 0xcc, 0x08, 0x00, 0x02, 0x4c, 0x3a, 0x01, 0x02, 0x50, 0x3a, 0x01, 0x02, + 0x54, 0x3a, 0x01, 0x02, 0x58, 0x3a, 0x01, 0x02, 0x5c, 0x3a, 0x01, 0x02, 0x60, 0x3a, 0x01, 0x02, 0x10, 0x15, 0x02, 0x02, 0x14, 0x15, 0x02, 0x02, 0x18, 0x15, 0x02, 0x02, 0x1c, 0x15, 0x02, 0x02, + 0x20, 0x15, 0x02, 0x02, 0x40, 0x36, 0x03, 0x03, 0x48, 0x36, 0x03, 0x03, 0x50, 0x36, 0x03, 0x03, 0x30, 0x12, 0x04, 0x03, 0x38, 0x12, 0x04, 0x03, 0x20, 0x32, 0x05, 0x04, 0x80, 0x0f, 0x06, 0x04, + 0x60, 0x2e, 0x07, 0x05, 0x00, 0x2b, 0x09, 0x06, 0x00, 0x06, 0x10, 0x09, 0xd0, 0x08, 0x00, 0x02, 0xd4, 0x08, 0x00, 0x02, 0xd8, 0x08, 0x00, 0x02, 0x64, 0x3a, 0x01, 0x02, 0x68, 0x3a, 0x01, 0x02, + 0x6c, 0x3a, 0x01, 0x02, 0x70, 0x3a, 0x01, 0x02, 0x74, 0x3a, 0x01, 0x02, 0x78, 0x3a, 0x01, 0x02, 0x24, 0x15, 0x02, 0x02, 0x28, 0x15, 0x02, 0x02, 0x2c, 0x15, 0x02, 0x02, 0x30, 0x15, 0x02, 0x02, + 0x34, 0x15, 0x02, 0x02, 0x58, 0x36, 0x03, 0x03, 0x60, 0x36, 0x03, 0x03, 0x68, 0x36, 0x03, 0x03, 0x40, 0x12, 0x04, 0x03, 0x48, 0x12, 0x04, 0x03, 0x30, 0x32, 0x05, 0x04, 0x90, 0x0f, 0x06, 0x04, + 0x80, 0x2e, 0x07, 0x05, 0x40, 0x2b, 0x09, 0x06, 0x00, 0x18, 0x11, 0x0a, 0xdc, 0x08, 0x00, 0x02, 0xe0, 0x08, 0x00, 0x02, 0xe4, 0x08, 0x00, 0x02, 0x7c, 0x3a, 0x01, 0x02, 0x80, 0x3a, 0x01, 0x02, + 0x84, 0x3a, 0x01, 0x02, 0x88, 0x3a, 0x01, 0x02, 0x8c, 0x3a, 0x01, 0x02, 0x90, 0x3a, 0x01, 0x02, 0x38, 0x15, 0x02, 0x02, 0x3c, 0x15, 0x02, 0x02, 0x40, 0x15, 0x02, 0x02, 0x44, 0x15, 0x02, 0x02, + 0x48, 0x15, 0x02, 0x02, 0x70, 0x36, 0x03, 0x03, 0x78, 0x36, 0x03, 0x03, 0x80, 0x36, 0x03, 0x03, 0x50, 0x12, 0x04, 0x03, 0x58, 0x12, 0x04, 0x03, 0x40, 0x32, 0x05, 0x04, 0xa0, 0x0f, 0x06, 0x04, + 0xa0, 0x2e, 0x07, 0x05, 0x80, 0x2b, 0x09, 0x06, 0x00, 0x1c, 0x11, 0x0a, 0xe8, 0x08, 0x00, 0x02, 0xec, 0x08, 0x00, 0x02, 0xf0, 0x08, 0x00, 0x02, 0x94, 0x3a, 0x01, 0x02, 0x98, 0x3a, 0x01, 0x02, + 0x9c, 0x3a, 0x01, 0x02, 0xa0, 0x3a, 0x01, 0x02, 0xa4, 0x3a, 0x01, 0x02, 0xa8, 0x3a, 0x01, 0x02, 0x4c, 0x15, 0x02, 0x02, 0x50, 0x15, 0x02, 0x02, 0x54, 0x15, 0x02, 0x02, 0x58, 0x15, 0x02, 0x02, + 0x5c, 0x15, 0x02, 0x02, 0x88, 0x36, 0x03, 0x03, 0x90, 0x36, 0x03, 0x03, 0x98, 0x36, 0x03, 0x03, 0x60, 0x12, 0x04, 0x03, 0x68, 0x12, 0x04, 0x03, 0x50, 0x32, 0x05, 0x04, 0xb0, 0x0f, 0x06, 0x04, + 0xc0, 0x2e, 0x07, 0x05, 0xc0, 0x2b, 0x09, 0x06, 0x00, 0x04, 0x12, 0x0a, 0xf4, 0x08, 0x00, 0x02, 0xf8, 0x08, 0x00, 0x02, 0xfc, 0x08, 0x00, 0x02, 0xac, 0x3a, 0x01, 0x02, 0xb0, 0x3a, 0x01, 0x02, + 0xb4, 0x3a, 0x01, 0x02, 0xb8, 0x3a, 0x01, 0x02, 0xbc, 0x3a, 0x01, 0x02, 0xc0, 0x3a, 0x01, 0x02, 0x60, 0x15, 0x02, 0x02, 0x64, 0x15, 0x02, 0x02, 0x68, 0x15, 0x02, 0x02, 0x6c, 0x15, 0x02, 0x02, + 0x70, 0x15, 0x02, 0x02, 0xa0, 0x36, 0x03, 0x03, 0xa8, 0x36, 0x03, 0x03, 0xb0, 0x36, 0x03, 0x03, 0x70, 0x12, 0x04, 0x03, 0x78, 0x12, 0x04, 0x03, 0x60, 0x32, 0x05, 0x04, 0xc0, 0x0f, 0x06, 0x04, + 0xe0, 0x2e, 0x07, 0x05, 0x00, 0x2c, 0x09, 0x06, 0x00, 0x18, 0x13, 0x0b, 0x00, 0x09, 0x00, 0x02, 0x04, 0x09, 0x00, 0x02, 0x08, 0x09, 0x00, 0x02, 0xc4, 0x3a, 0x01, 0x02, 0xc8, 0x3a, 0x01, 0x02, + 0xcc, 0x3a, 0x01, 0x02, 0xd0, 0x3a, 0x01, 0x02, 0xd4, 0x3a, 0x01, 0x02, 0xd8, 0x3a, 0x01, 0x02, 0x74, 0x15, 0x02, 0x02, 0x78, 0x15, 0x02, 0x02, 0x7c, 0x15, 0x02, 0x02, 0x80, 0x15, 0x02, 0x02, + 0x84, 0x15, 0x02, 0x02, 0xb8, 0x36, 0x03, 0x03, 0xc0, 0x36, 0x03, 0x03, 0xc8, 0x36, 0x03, 0x03, 0x80, 0x12, 0x04, 0x03, 0x88, 0x12, 0x04, 0x03, 0x70, 0x32, 0x05, 0x04, 0xd0, 0x0f, 0x06, 0x04, + 0x00, 0x2f, 0x07, 0x05, 0x40, 0x2c, 0x09, 0x06, 0x00, 0x10, 0x15, 0x0c, 0x0c, 0x09, 0x00, 0x02, 0x10, 0x09, 0x00, 0x02, 0x14, 0x09, 0x00, 0x02, 0xdc, 0x3a, 0x01, 0x02, 0xe0, 0x3a, 0x01, 0x02, + 0xe4, 0x3a, 0x01, 0x02, 0xe8, 0x3a, 0x01, 0x02, 0xec, 0x3a, 0x01, 0x02, 0xf0, 0x3a, 0x01, 0x02, 0x88, 0x15, 0x02, 0x02, 0x8c, 0x15, 0x02, 0x02, 0x90, 0x15, 0x02, 0x02, 0x94, 0x15, 0x02, 0x02, + 0x98, 0x15, 0x02, 0x02, 0xd0, 0x36, 0x03, 0x03, 0xd8, 0x36, 0x03, 0x03, 0xe0, 0x36, 0x03, 0x03, 0x90, 0x12, 0x04, 0x03, 0x98, 0x12, 0x04, 0x03, 0x80, 0x32, 0x05, 0x04, 0xe0, 0x0f, 0x06, 0x04, + 0x20, 0x2f, 0x07, 0x05, 0x80, 0x2c, 0x09, 0x06, 0x18, 0x09, 0x00, 0x02, 0x1c, 0x09, 0x00, 0x02, 0x20, 0x09, 0x00, 0x02, 0x24, 0x09, 0x00, 0x02, 0xf4, 0x3a, 0x01, 0x02, 0xf8, 0x3a, 0x01, 0x02, + 0xfc, 0x3a, 0x01, 0x02, 0x00, 0x3b, 0x01, 0x02, 0x04, 0x3b, 0x01, 0x02, 0x08, 0x3b, 0x01, 0x02, 0x9c, 0x15, 0x02, 0x02, 0xa0, 0x15, 0x02, 0x02, 0xa4, 0x15, 0x02, 0x02, 0xa8, 0x15, 0x02, 0x02, + 0xac, 0x15, 0x02, 0x02, 0xe8, 0x36, 0x03, 0x03, 0xf0, 0x36, 0x03, 0x03, 0xf8, 0x36, 0x03, 0x03, 0xa0, 0x12, 0x04, 0x03, 0xa8, 0x12, 0x04, 0x03, 0x90, 0x32, 0x05, 0x04, 0xf0, 0x0f, 0x06, 0x04, + 0x40, 0x2f, 0x07, 0x05, 0xc0, 0x2c, 0x09, 0x06, 0x28, 0x09, 0x00, 0x02, 0x2c, 0x09, 0x00, 0x02, 0x30, 0x09, 0x00, 0x02, 0x34, 0x09, 0x00, 0x02, 0x0c, 0x3b, 0x01, 0x02, 0x10, 0x3b, 0x01, 0x02, + 0x14, 0x3b, 0x01, 0x02, 0x18, 0x3b, 0x01, 0x02, 0x1c, 0x3b, 0x01, 0x02, 0x20, 0x3b, 0x01, 0x02, 0xb0, 0x15, 0x02, 0x02, 0xb4, 0x15, 0x02, 0x02, 0xb8, 0x15, 0x02, 0x02, 0xbc, 0x15, 0x02, 0x02, + 0xc0, 0x15, 0x02, 0x02, 0x00, 0x37, 0x03, 0x03, 0x08, 0x37, 0x03, 0x03, 0x10, 0x37, 0x03, 0x03, 0xb0, 0x12, 0x04, 0x03, 0xb8, 0x12, 0x04, 0x03, 0xa0, 0x32, 0x05, 0x04, 0x00, 0x10, 0x06, 0x04, + 0x60, 0x2f, 0x07, 0x05, 0x00, 0x2d, 0x09, 0x06, 0x38, 0x09, 0x00, 0x02, 0x3c, 0x09, 0x00, 0x02, 0x40, 0x09, 0x00, 0x02, 0x44, 0x09, 0x00, 0x02, 0x24, 0x3b, 0x01, 0x02, 0x28, 0x3b, 0x01, 0x02, + 0x2c, 0x3b, 0x01, 0x02, 0x30, 0x3b, 0x01, 0x02, 0x34, 0x3b, 0x01, 0x02, 0x38, 0x3b, 0x01, 0x02, 0xc4, 0x15, 0x02, 0x02, 0xc8, 0x15, 0x02, 0x02, 0xcc, 0x15, 0x02, 0x02, 0xd0, 0x15, 0x02, 0x02, + 0xd4, 0x15, 0x02, 0x02, 0x18, 0x37, 0x03, 0x03, 0x20, 0x37, 0x03, 0x03, 0x28, 0x37, 0x03, 0x03, 0xc0, 0x12, 0x04, 0x03, 0xc8, 0x12, 0x04, 0x03, 0xb0, 0x32, 0x05, 0x04, 0x10, 0x10, 0x06, 0x04, + 0x80, 0x2f, 0x07, 0x05, 0x40, 0x2d, 0x09, 0x06, 0x48, 0x09, 0x00, 0x02, 0x4c, 0x09, 0x00, 0x02, 0x50, 0x09, 0x00, 0x02, 0x54, 0x09, 0x00, 0x02, 0x3c, 0x3b, 0x01, 0x02, 0x40, 0x3b, 0x01, 0x02, + 0x44, 0x3b, 0x01, 0x02, 0x48, 0x3b, 0x01, 0x02, 0x4c, 0x3b, 0x01, 0x02, 0x50, 0x3b, 0x01, 0x02, 0xd8, 0x15, 0x02, 0x02, 0xdc, 0x15, 0x02, 0x02, 0xe0, 0x15, 0x02, 0x02, 0xe4, 0x15, 0x02, 0x02, + 0xe8, 0x15, 0x02, 0x02, 0x30, 0x37, 0x03, 0x03, 0x38, 0x37, 0x03, 0x03, 0x40, 0x37, 0x03, 0x03, 0xd0, 0x12, 0x04, 0x03, 0xd8, 0x12, 0x04, 0x03, 0xc0, 0x32, 0x05, 0x04, 0x20, 0x10, 0x06, 0x04, + 0xa0, 0x2f, 0x07, 0x05, 0x80, 0x2d, 0x09, 0x06, 0x58, 0x09, 0x00, 0x02, 0x5c, 0x09, 0x00, 0x02, 0x60, 0x09, 0x00, 0x02, 0x64, 0x09, 0x00, 0x02, 0x54, 0x3b, 0x01, 0x02, 0x58, 0x3b, 0x01, 0x02, + 0x5c, 0x3b, 0x01, 0x02, 0x60, 0x3b, 0x01, 0x02, 0x64, 0x3b, 0x01, 0x02, 0x68, 0x3b, 0x01, 0x02, 0xec, 0x15, 0x02, 0x02, 0xf0, 0x15, 0x02, 0x02, 0xf4, 0x15, 0x02, 0x02, 0xf8, 0x15, 0x02, 0x02, + 0xfc, 0x15, 0x02, 0x02, 0x48, 0x37, 0x03, 0x03, 0x50, 0x37, 0x03, 0x03, 0x58, 0x37, 0x03, 0x03, 0xe0, 0x12, 0x04, 0x03, 0xe8, 0x12, 0x04, 0x03, 0xd0, 0x32, 0x05, 0x04, 0x30, 0x10, 0x06, 0x04, + 0xc0, 0x2f, 0x07, 0x05, 0xc0, 0x2d, 0x09, 0x06, 0x68, 0x09, 0x00, 0x02, 0x6c, 0x09, 0x00, 0x02, 0x70, 0x09, 0x00, 0x02, 0x74, 0x09, 0x00, 0x02, 0x6c, 0x3b, 0x01, 0x02, 0x70, 0x3b, 0x01, 0x02, + 0x74, 0x3b, 0x01, 0x02, 0x78, 0x3b, 0x01, 0x02, 0x7c, 0x3b, 0x01, 0x02, 0x80, 0x3b, 0x01, 0x02, 0x00, 0x16, 0x02, 0x02, 0x04, 0x16, 0x02, 0x02, 0x08, 0x16, 0x02, 0x02, 0x0c, 0x16, 0x02, 0x02, + 0x10, 0x16, 0x02, 0x02, 0x60, 0x37, 0x03, 0x03, 0x68, 0x37, 0x03, 0x03, 0x70, 0x37, 0x03, 0x03, 0xf0, 0x12, 0x04, 0x03, 0xf8, 0x12, 0x04, 0x03, 0xe0, 0x32, 0x05, 0x04, 0x40, 0x10, 0x06, 0x04, + 0xe0, 0x2f, 0x07, 0x05, 0x00, 0x2e, 0x09, 0x06, 0x78, 0x09, 0x00, 0x02, 0x7c, 0x09, 0x00, 0x02, 0x80, 0x09, 0x00, 0x02, 0x84, 0x09, 0x00, 0x02, 0x84, 0x3b, 0x01, 0x02, 0x88, 0x3b, 0x01, 0x02, + 0x8c, 0x3b, 0x01, 0x02, 0x90, 0x3b, 0x01, 0x02, 0x94, 0x3b, 0x01, 0x02, 0x98, 0x3b, 0x01, 0x02, 0x14, 0x16, 0x02, 0x02, 0x18, 0x16, 0x02, 0x02, 0x1c, 0x16, 0x02, 0x02, 0x20, 0x16, 0x02, 0x02, + 0x24, 0x16, 0x02, 0x02, 0x78, 0x37, 0x03, 0x03, 0x80, 0x37, 0x03, 0x03, 0x88, 0x37, 0x03, 0x03, 0x00, 0x13, 0x04, 0x03, 0x08, 0x13, 0x04, 0x03, 0xf0, 0x32, 0x05, 0x04, 0x50, 0x10, 0x06, 0x04, + 0x00, 0x30, 0x07, 0x05, 0x40, 0x2e, 0x09, 0x06, 0x88, 0x09, 0x00, 0x02, 0x8c, 0x09, 0x00, 0x02, 0x90, 0x09, 0x00, 0x02, 0x94, 0x09, 0x00, 0x02, 0x9c, 0x3b, 0x01, 0x02, 0xa0, 0x3b, 0x01, 0x02, + 0xa4, 0x3b, 0x01, 0x02, 0xa8, 0x3b, 0x01, 0x02, 0xac, 0x3b, 0x01, 0x02, 0xb0, 0x3b, 0x01, 0x02, 0x28, 0x16, 0x02, 0x02, 0x2c, 0x16, 0x02, 0x02, 0x30, 0x16, 0x02, 0x02, 0x34, 0x16, 0x02, 0x02, + 0x38, 0x16, 0x02, 0x02, 0x90, 0x37, 0x03, 0x03, 0x98, 0x37, 0x03, 0x03, 0xa0, 0x37, 0x03, 0x03, 0x10, 0x13, 0x04, 0x03, 0x18, 0x13, 0x04, 0x03, 0x00, 0x33, 0x05, 0x04, 0x60, 0x10, 0x06, 0x04, + 0x20, 0x30, 0x07, 0x05, 0x80, 0x2e, 0x09, 0x06, 0x98, 0x09, 0x00, 0x02, 0x9c, 0x09, 0x00, 0x02, 0xa0, 0x09, 0x00, 0x02, 0xa4, 0x09, 0x00, 0x02, 0xb4, 0x3b, 0x01, 0x02, 0xb8, 0x3b, 0x01, 0x02, + 0xbc, 0x3b, 0x01, 0x02, 0xc0, 0x3b, 0x01, 0x02, 0xc4, 0x3b, 0x01, 0x02, 0xc8, 0x3b, 0x01, 0x02, 0x3c, 0x16, 0x02, 0x02, 0x40, 0x16, 0x02, 0x02, 0x44, 0x16, 0x02, 0x02, 0x48, 0x16, 0x02, 0x02, + 0x4c, 0x16, 0x02, 0x02, 0xa8, 0x37, 0x03, 0x03, 0xb0, 0x37, 0x03, 0x03, 0xb8, 0x37, 0x03, 0x03, 0x20, 0x13, 0x04, 0x03, 0x28, 0x13, 0x04, 0x03, 0x10, 0x33, 0x05, 0x04, 0x70, 0x10, 0x06, 0x04, + 0x40, 0x30, 0x07, 0x05, 0xc0, 0x2e, 0x09, 0x06, 0xa8, 0x09, 0x00, 0x02, 0xac, 0x09, 0x00, 0x02, 0xb0, 0x09, 0x00, 0x02, 0xb4, 0x09, 0x00, 0x02, 0xcc, 0x3b, 0x01, 0x02, 0xd0, 0x3b, 0x01, 0x02, + 0xd4, 0x3b, 0x01, 0x02, 0xd8, 0x3b, 0x01, 0x02, 0xdc, 0x3b, 0x01, 0x02, 0xe0, 0x3b, 0x01, 0x02, 0x50, 0x16, 0x02, 0x02, 0x54, 0x16, 0x02, 0x02, 0x58, 0x16, 0x02, 0x02, 0x5c, 0x16, 0x02, 0x02, + 0x60, 0x16, 0x02, 0x02, 0xc0, 0x37, 0x03, 0x03, 0xc8, 0x37, 0x03, 0x03, 0xd0, 0x37, 0x03, 0x03, 0x30, 0x13, 0x04, 0x03, 0x38, 0x13, 0x04, 0x03, 0x20, 0x33, 0x05, 0x04, 0x80, 0x10, 0x06, 0x04, + 0x60, 0x30, 0x07, 0x05, 0x00, 0x2f, 0x09, 0x06, 0xb8, 0x09, 0x00, 0x02, 0xbc, 0x09, 0x00, 0x02, 0xc0, 0x09, 0x00, 0x02, 0xc4, 0x09, 0x00, 0x02, 0xe4, 0x3b, 0x01, 0x02, 0xe8, 0x3b, 0x01, 0x02, + 0xec, 0x3b, 0x01, 0x02, 0xf0, 0x3b, 0x01, 0x02, 0xf4, 0x3b, 0x01, 0x02, 0xf8, 0x3b, 0x01, 0x02, 0x64, 0x16, 0x02, 0x02, 0x68, 0x16, 0x02, 0x02, 0x6c, 0x16, 0x02, 0x02, 0x70, 0x16, 0x02, 0x02, + 0x74, 0x16, 0x02, 0x02, 0xd8, 0x37, 0x03, 0x03, 0xe0, 0x37, 0x03, 0x03, 0xe8, 0x37, 0x03, 0x03, 0x40, 0x13, 0x04, 0x03, 0x48, 0x13, 0x04, 0x03, 0x30, 0x33, 0x05, 0x04, 0x90, 0x10, 0x06, 0x04, + 0x80, 0x30, 0x07, 0x05, 0x40, 0x2f, 0x09, 0x06, 0xc8, 0x09, 0x00, 0x02, 0xcc, 0x09, 0x00, 0x02, 0xd0, 0x09, 0x00, 0x02, 0xd4, 0x09, 0x00, 0x02, 0xfc, 0x3b, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, + 0x04, 0x3c, 0x01, 0x02, 0x08, 0x3c, 0x01, 0x02, 0x0c, 0x3c, 0x01, 0x02, 0x10, 0x3c, 0x01, 0x02, 0x78, 0x16, 0x02, 0x02, 0x7c, 0x16, 0x02, 0x02, 0x80, 0x16, 0x02, 0x02, 0x84, 0x16, 0x02, 0x02, + 0x88, 0x16, 0x02, 0x02, 0xf0, 0x37, 0x03, 0x03, 0xf8, 0x37, 0x03, 0x03, 0x00, 0x38, 0x03, 0x03, 0x50, 0x13, 0x04, 0x03, 0x58, 0x13, 0x04, 0x03, 0x40, 0x33, 0x05, 0x04, 0xa0, 0x10, 0x06, 0x04, + 0xa0, 0x30, 0x07, 0x05, 0x80, 0x2f, 0x09, 0x06, 0xd8, 0x09, 0x00, 0x02, 0xdc, 0x09, 0x00, 0x02, 0xe0, 0x09, 0x00, 0x02, 0xe4, 0x09, 0x00, 0x02, 0x14, 0x3c, 0x01, 0x02, 0x18, 0x3c, 0x01, 0x02, + 0x1c, 0x3c, 0x01, 0x02, 0x20, 0x3c, 0x01, 0x02, 0x24, 0x3c, 0x01, 0x02, 0x28, 0x3c, 0x01, 0x02, 0x8c, 0x16, 0x02, 0x02, 0x90, 0x16, 0x02, 0x02, 0x94, 0x16, 0x02, 0x02, 0x98, 0x16, 0x02, 0x02, + 0x9c, 0x16, 0x02, 0x02, 0x08, 0x38, 0x03, 0x03, 0x10, 0x38, 0x03, 0x03, 0x18, 0x38, 0x03, 0x03, 0x60, 0x13, 0x04, 0x03, 0x68, 0x13, 0x04, 0x03, 0x50, 0x33, 0x05, 0x04, 0xb0, 0x10, 0x06, 0x04, + 0xc0, 0x30, 0x07, 0x05, 0xc0, 0x2f, 0x09, 0x06, 0xe8, 0x09, 0x00, 0x02, 0xec, 0x09, 0x00, 0x02, 0xf0, 0x09, 0x00, 0x02, 0xf4, 0x09, 0x00, 0x02, 0x2c, 0x3c, 0x01, 0x02, 0x30, 0x3c, 0x01, 0x02, + 0x34, 0x3c, 0x01, 0x02, 0x38, 0x3c, 0x01, 0x02, 0x3c, 0x3c, 0x01, 0x02, 0x40, 0x3c, 0x01, 0x02, 0xa0, 0x16, 0x02, 0x02, 0xa4, 0x16, 0x02, 0x02, 0xa8, 0x16, 0x02, 0x02, 0xac, 0x16, 0x02, 0x02, + 0xb0, 0x16, 0x02, 0x02, 0x20, 0x38, 0x03, 0x03, 0x28, 0x38, 0x03, 0x03, 0x30, 0x38, 0x03, 0x03, 0x70, 0x13, 0x04, 0x03, 0x78, 0x13, 0x04, 0x03, 0x60, 0x33, 0x05, 0x04, 0xc0, 0x10, 0x06, 0x04, + 0xe0, 0x30, 0x07, 0x05, 0x00, 0x30, 0x09, 0x06, 0xf8, 0x09, 0x00, 0x02, 0xfc, 0x09, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x04, 0x0a, 0x00, 0x02, 0x44, 0x3c, 0x01, 0x02, 0x48, 0x3c, 0x01, 0x02, + 0x4c, 0x3c, 0x01, 0x02, 0x50, 0x3c, 0x01, 0x02, 0x54, 0x3c, 0x01, 0x02, 0x58, 0x3c, 0x01, 0x02, 0xb4, 0x16, 0x02, 0x02, 0xb8, 0x16, 0x02, 0x02, 0xbc, 0x16, 0x02, 0x02, 0xc0, 0x16, 0x02, 0x02, + 0xc4, 0x16, 0x02, 0x02, 0x38, 0x38, 0x03, 0x03, 0x40, 0x38, 0x03, 0x03, 0x48, 0x38, 0x03, 0x03, 0x80, 0x13, 0x04, 0x03, 0x88, 0x13, 0x04, 0x03, 0x70, 0x33, 0x05, 0x04, 0xd0, 0x10, 0x06, 0x04, + 0x00, 0x31, 0x07, 0x05, 0x40, 0x30, 0x09, 0x06, 0x08, 0x0a, 0x00, 0x02, 0x0c, 0x0a, 0x00, 0x02, 0x10, 0x0a, 0x00, 0x02, 0x14, 0x0a, 0x00, 0x02, 0x5c, 0x3c, 0x01, 0x02, 0x60, 0x3c, 0x01, 0x02, + 0x64, 0x3c, 0x01, 0x02, 0x68, 0x3c, 0x01, 0x02, 0x6c, 0x3c, 0x01, 0x02, 0x70, 0x3c, 0x01, 0x02, 0xc8, 0x16, 0x02, 0x02, 0xcc, 0x16, 0x02, 0x02, 0xd0, 0x16, 0x02, 0x02, 0xd4, 0x16, 0x02, 0x02, + 0x50, 0x38, 0x03, 0x03, 0x58, 0x38, 0x03, 0x03, 0x60, 0x38, 0x03, 0x03, 0x90, 0x13, 0x04, 0x03, 0x98, 0x13, 0x04, 0x03, 0xa0, 0x13, 0x04, 0x03, 0x80, 0x33, 0x05, 0x04, 0xe0, 0x10, 0x06, 0x04, + 0x20, 0x31, 0x07, 0x05, 0x80, 0x30, 0x09, 0x06, 0x18, 0x0a, 0x00, 0x02, 0x1c, 0x0a, 0x00, 0x02, 0x20, 0x0a, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x02, 0x74, 0x3c, 0x01, 0x02, 0x78, 0x3c, 0x01, 0x02, + 0x7c, 0x3c, 0x01, 0x02, 0x80, 0x3c, 0x01, 0x02, 0x84, 0x3c, 0x01, 0x02, 0x88, 0x3c, 0x01, 0x02, 0xd8, 0x16, 0x02, 0x02, 0xdc, 0x16, 0x02, 0x02, 0xe0, 0x16, 0x02, 0x02, 0xe4, 0x16, 0x02, 0x02, + 0x68, 0x38, 0x03, 0x03, 0x70, 0x38, 0x03, 0x03, 0x78, 0x38, 0x03, 0x03, 0xa8, 0x13, 0x04, 0x03, 0xb0, 0x13, 0x04, 0x03, 0xb8, 0x13, 0x04, 0x03, 0x90, 0x33, 0x05, 0x04, 0xf0, 0x10, 0x06, 0x04, + 0x40, 0x31, 0x07, 0x05, 0xc0, 0x30, 0x09, 0x06, 0x28, 0x0a, 0x00, 0x02, 0x2c, 0x0a, 0x00, 0x02, 0x30, 0x0a, 0x00, 0x02, 0x34, 0x0a, 0x00, 0x02, 0x8c, 0x3c, 0x01, 0x02, 0x90, 0x3c, 0x01, 0x02, + 0x94, 0x3c, 0x01, 0x02, 0x98, 0x3c, 0x01, 0x02, 0x9c, 0x3c, 0x01, 0x02, 0xa0, 0x3c, 0x01, 0x02, 0xe8, 0x16, 0x02, 0x02, 0xec, 0x16, 0x02, 0x02, 0xf0, 0x16, 0x02, 0x02, 0xf4, 0x16, 0x02, 0x02, + 0x80, 0x38, 0x03, 0x03, 0x88, 0x38, 0x03, 0x03, 0x90, 0x38, 0x03, 0x03, 0xc0, 0x13, 0x04, 0x03, 0xc8, 0x13, 0x04, 0x03, 0xd0, 0x13, 0x04, 0x03, 0xa0, 0x33, 0x05, 0x04, 0x00, 0x11, 0x06, 0x04, + 0x60, 0x31, 0x07, 0x05, 0x00, 0x31, 0x09, 0x06, 0x38, 0x0a, 0x00, 0x02, 0x3c, 0x0a, 0x00, 0x02, 0x40, 0x0a, 0x00, 0x02, 0x44, 0x0a, 0x00, 0x02, 0xa4, 0x3c, 0x01, 0x02, 0xa8, 0x3c, 0x01, 0x02, + 0xac, 0x3c, 0x01, 0x02, 0xb0, 0x3c, 0x01, 0x02, 0xb4, 0x3c, 0x01, 0x02, 0xb8, 0x3c, 0x01, 0x02, 0xf8, 0x16, 0x02, 0x02, 0xfc, 0x16, 0x02, 0x02, 0x00, 0x17, 0x02, 0x02, 0x04, 0x17, 0x02, 0x02, + 0x98, 0x38, 0x03, 0x03, 0xa0, 0x38, 0x03, 0x03, 0xa8, 0x38, 0x03, 0x03, 0xd8, 0x13, 0x04, 0x03, 0xe0, 0x13, 0x04, 0x03, 0xe8, 0x13, 0x04, 0x03, 0xb0, 0x33, 0x05, 0x04, 0x10, 0x11, 0x06, 0x04, + 0x80, 0x31, 0x07, 0x05, 0x40, 0x31, 0x09, 0x06, 0x48, 0x0a, 0x00, 0x02, 0x4c, 0x0a, 0x00, 0x02, 0x50, 0x0a, 0x00, 0x02, 0x54, 0x0a, 0x00, 0x02, 0xbc, 0x3c, 0x01, 0x02, 0xc0, 0x3c, 0x01, 0x02, + 0xc4, 0x3c, 0x01, 0x02, 0xc8, 0x3c, 0x01, 0x02, 0xcc, 0x3c, 0x01, 0x02, 0xd0, 0x3c, 0x01, 0x02, 0x08, 0x17, 0x02, 0x02, 0x0c, 0x17, 0x02, 0x02, 0x10, 0x17, 0x02, 0x02, 0x14, 0x17, 0x02, 0x02, + 0xb0, 0x38, 0x03, 0x03, 0xb8, 0x38, 0x03, 0x03, 0xc0, 0x38, 0x03, 0x03, 0xf0, 0x13, 0x04, 0x03, 0xf8, 0x13, 0x04, 0x03, 0x00, 0x14, 0x04, 0x03, 0xc0, 0x33, 0x05, 0x04, 0x20, 0x11, 0x06, 0x04, + 0xa0, 0x31, 0x07, 0x05, 0x00, 0x0a, 0x0a, 0x06, 0x58, 0x0a, 0x00, 0x02, 0x5c, 0x0a, 0x00, 0x02, 0x60, 0x0a, 0x00, 0x02, 0x64, 0x0a, 0x00, 0x02, 0xd4, 0x3c, 0x01, 0x02, 0xd8, 0x3c, 0x01, 0x02, + 0xdc, 0x3c, 0x01, 0x02, 0xe0, 0x3c, 0x01, 0x02, 0xe4, 0x3c, 0x01, 0x02, 0xe8, 0x3c, 0x01, 0x02, 0x18, 0x17, 0x02, 0x02, 0x1c, 0x17, 0x02, 0x02, 0x20, 0x17, 0x02, 0x02, 0x24, 0x17, 0x02, 0x02, + 0xc8, 0x38, 0x03, 0x03, 0xd0, 0x38, 0x03, 0x03, 0xd8, 0x38, 0x03, 0x03, 0x08, 0x14, 0x04, 0x03, 0x10, 0x14, 0x04, 0x03, 0x18, 0x14, 0x04, 0x03, 0xd0, 0x33, 0x05, 0x04, 0x30, 0x11, 0x06, 0x04, + 0xc0, 0x31, 0x07, 0x05, 0x40, 0x0a, 0x0a, 0x06, 0x68, 0x0a, 0x00, 0x02, 0x6c, 0x0a, 0x00, 0x02, 0x70, 0x0a, 0x00, 0x02, 0x74, 0x0a, 0x00, 0x02, 0xec, 0x3c, 0x01, 0x02, 0xf0, 0x3c, 0x01, 0x02, + 0xf4, 0x3c, 0x01, 0x02, 0xf8, 0x3c, 0x01, 0x02, 0xfc, 0x3c, 0x01, 0x02, 0x00, 0x3d, 0x01, 0x02, 0x28, 0x17, 0x02, 0x02, 0x2c, 0x17, 0x02, 0x02, 0x30, 0x17, 0x02, 0x02, 0x34, 0x17, 0x02, 0x02, + 0xe0, 0x38, 0x03, 0x03, 0xe8, 0x38, 0x03, 0x03, 0xf0, 0x38, 0x03, 0x03, 0x20, 0x14, 0x04, 0x03, 0x28, 0x14, 0x04, 0x03, 0xe0, 0x33, 0x05, 0x04, 0xf0, 0x33, 0x05, 0x04, 0x40, 0x11, 0x06, 0x04, + 0xe0, 0x31, 0x07, 0x05, 0x80, 0x0a, 0x0a, 0x06, 0x78, 0x0a, 0x00, 0x02, 0x7c, 0x0a, 0x00, 0x02, 0x80, 0x0a, 0x00, 0x02, 0x84, 0x0a, 0x00, 0x02, 0x04, 0x3d, 0x01, 0x02, 0x08, 0x3d, 0x01, 0x02, + 0x0c, 0x3d, 0x01, 0x02, 0x10, 0x3d, 0x01, 0x02, 0x14, 0x3d, 0x01, 0x02, 0x18, 0x3d, 0x01, 0x02, 0x38, 0x17, 0x02, 0x02, 0x3c, 0x17, 0x02, 0x02, 0x40, 0x17, 0x02, 0x02, 0x44, 0x17, 0x02, 0x02, + 0xf8, 0x38, 0x03, 0x03, 0x00, 0x39, 0x03, 0x03, 0x08, 0x39, 0x03, 0x03, 0x30, 0x14, 0x04, 0x03, 0x38, 0x14, 0x04, 0x03, 0x00, 0x34, 0x05, 0x04, 0x10, 0x34, 0x05, 0x04, 0x50, 0x11, 0x06, 0x04, + 0x00, 0x32, 0x07, 0x05, 0xc0, 0x0a, 0x0a, 0x06, 0x88, 0x0a, 0x00, 0x02, 0x8c, 0x0a, 0x00, 0x02, 0x90, 0x0a, 0x00, 0x02, 0x94, 0x0a, 0x00, 0x02, 0x1c, 0x3d, 0x01, 0x02, 0x20, 0x3d, 0x01, 0x02, + 0x24, 0x3d, 0x01, 0x02, 0x28, 0x3d, 0x01, 0x02, 0x2c, 0x3d, 0x01, 0x02, 0x30, 0x3d, 0x01, 0x02, 0x48, 0x17, 0x02, 0x02, 0x4c, 0x17, 0x02, 0x02, 0x50, 0x17, 0x02, 0x02, 0x54, 0x17, 0x02, 0x02, + 0x10, 0x39, 0x03, 0x03, 0x18, 0x39, 0x03, 0x03, 0x20, 0x39, 0x03, 0x03, 0x40, 0x14, 0x04, 0x03, 0x48, 0x14, 0x04, 0x03, 0x20, 0x34, 0x05, 0x04, 0x30, 0x34, 0x05, 0x04, 0x60, 0x11, 0x06, 0x04, + 0x20, 0x32, 0x07, 0x05, 0x00, 0x0b, 0x0a, 0x06, 0x98, 0x0a, 0x00, 0x02, 0x9c, 0x0a, 0x00, 0x02, 0xa0, 0x0a, 0x00, 0x02, 0xa4, 0x0a, 0x00, 0x02, 0x34, 0x3d, 0x01, 0x02, 0x38, 0x3d, 0x01, 0x02, + 0x3c, 0x3d, 0x01, 0x02, 0x40, 0x3d, 0x01, 0x02, 0x44, 0x3d, 0x01, 0x02, 0x48, 0x3d, 0x01, 0x02, 0x58, 0x17, 0x02, 0x02, 0x5c, 0x17, 0x02, 0x02, 0x60, 0x17, 0x02, 0x02, 0x64, 0x17, 0x02, 0x02, + 0x28, 0x39, 0x03, 0x03, 0x30, 0x39, 0x03, 0x03, 0x38, 0x39, 0x03, 0x03, 0x50, 0x14, 0x04, 0x03, 0x58, 0x14, 0x04, 0x03, 0x40, 0x34, 0x05, 0x04, 0x50, 0x34, 0x05, 0x04, 0x70, 0x11, 0x06, 0x04, + 0x40, 0x32, 0x07, 0x05, 0x40, 0x0b, 0x0a, 0x06, 0xa8, 0x0a, 0x00, 0x02, 0xac, 0x0a, 0x00, 0x02, 0xb0, 0x0a, 0x00, 0x02, 0xb4, 0x0a, 0x00, 0x02, 0x4c, 0x3d, 0x01, 0x02, 0x50, 0x3d, 0x01, 0x02, + 0x54, 0x3d, 0x01, 0x02, 0x58, 0x3d, 0x01, 0x02, 0x5c, 0x3d, 0x01, 0x02, 0x60, 0x3d, 0x01, 0x02, 0x68, 0x17, 0x02, 0x02, 0x6c, 0x17, 0x02, 0x02, 0x70, 0x17, 0x02, 0x02, 0x74, 0x17, 0x02, 0x02, + 0x40, 0x39, 0x03, 0x03, 0x48, 0x39, 0x03, 0x03, 0x50, 0x39, 0x03, 0x03, 0x60, 0x14, 0x04, 0x03, 0x68, 0x14, 0x04, 0x03, 0x60, 0x34, 0x05, 0x04, 0x70, 0x34, 0x05, 0x04, 0x80, 0x11, 0x06, 0x04, + 0x60, 0x32, 0x07, 0x05, 0x80, 0x0b, 0x0a, 0x06, 0xb8, 0x0a, 0x00, 0x02, 0xbc, 0x0a, 0x00, 0x02, 0xc0, 0x0a, 0x00, 0x02, 0xc4, 0x0a, 0x00, 0x02, 0x64, 0x3d, 0x01, 0x02, 0x68, 0x3d, 0x01, 0x02, + 0x6c, 0x3d, 0x01, 0x02, 0x70, 0x3d, 0x01, 0x02, 0x74, 0x3d, 0x01, 0x02, 0x78, 0x3d, 0x01, 0x02, 0x78, 0x17, 0x02, 0x02, 0x7c, 0x17, 0x02, 0x02, 0x80, 0x17, 0x02, 0x02, 0x84, 0x17, 0x02, 0x02, + 0x58, 0x39, 0x03, 0x03, 0x60, 0x39, 0x03, 0x03, 0x68, 0x39, 0x03, 0x03, 0x70, 0x14, 0x04, 0x03, 0x78, 0x14, 0x04, 0x03, 0x80, 0x34, 0x05, 0x04, 0x90, 0x34, 0x05, 0x04, 0x90, 0x11, 0x06, 0x04, + 0x80, 0x32, 0x07, 0x05, 0xc0, 0x0b, 0x0a, 0x06, 0xc8, 0x0a, 0x00, 0x02, 0xcc, 0x0a, 0x00, 0x02, 0xd0, 0x0a, 0x00, 0x02, 0xd4, 0x0a, 0x00, 0x02, 0x7c, 0x3d, 0x01, 0x02, 0x80, 0x3d, 0x01, 0x02, + 0x84, 0x3d, 0x01, 0x02, 0x88, 0x3d, 0x01, 0x02, 0x8c, 0x3d, 0x01, 0x02, 0x90, 0x3d, 0x01, 0x02, 0x88, 0x17, 0x02, 0x02, 0x8c, 0x17, 0x02, 0x02, 0x90, 0x17, 0x02, 0x02, 0x94, 0x17, 0x02, 0x02, + 0x70, 0x39, 0x03, 0x03, 0x78, 0x39, 0x03, 0x03, 0x80, 0x39, 0x03, 0x03, 0x80, 0x14, 0x04, 0x03, 0x88, 0x14, 0x04, 0x03, 0xa0, 0x34, 0x05, 0x04, 0xb0, 0x34, 0x05, 0x04, 0xa0, 0x11, 0x06, 0x04, + 0xa0, 0x32, 0x07, 0x05, 0x00, 0x0c, 0x0a, 0x06, 0xd8, 0x0a, 0x00, 0x02, 0xdc, 0x0a, 0x00, 0x02, 0xe0, 0x0a, 0x00, 0x02, 0xe4, 0x0a, 0x00, 0x02, 0x94, 0x3d, 0x01, 0x02, 0x98, 0x3d, 0x01, 0x02, + 0x9c, 0x3d, 0x01, 0x02, 0xa0, 0x3d, 0x01, 0x02, 0xa4, 0x3d, 0x01, 0x02, 0xa8, 0x3d, 0x01, 0x02, 0x98, 0x17, 0x02, 0x02, 0x9c, 0x17, 0x02, 0x02, 0xa0, 0x17, 0x02, 0x02, 0xa4, 0x17, 0x02, 0x02, + 0x88, 0x39, 0x03, 0x03, 0x90, 0x39, 0x03, 0x03, 0x98, 0x39, 0x03, 0x03, 0x90, 0x14, 0x04, 0x03, 0x98, 0x14, 0x04, 0x03, 0xc0, 0x34, 0x05, 0x04, 0xd0, 0x34, 0x05, 0x04, 0xb0, 0x11, 0x06, 0x04, + 0xc0, 0x32, 0x07, 0x05, 0x40, 0x0c, 0x0a, 0x06, 0xe8, 0x0a, 0x00, 0x02, 0xec, 0x0a, 0x00, 0x02, 0xf0, 0x0a, 0x00, 0x02, 0xf4, 0x0a, 0x00, 0x02, 0xac, 0x3d, 0x01, 0x02, 0xb0, 0x3d, 0x01, 0x02, + 0xb4, 0x3d, 0x01, 0x02, 0xb8, 0x3d, 0x01, 0x02, 0xbc, 0x3d, 0x01, 0x02, 0xc0, 0x3d, 0x01, 0x02, 0xa8, 0x17, 0x02, 0x02, 0xac, 0x17, 0x02, 0x02, 0xb0, 0x17, 0x02, 0x02, 0xb4, 0x17, 0x02, 0x02, + 0xa0, 0x39, 0x03, 0x03, 0xa8, 0x39, 0x03, 0x03, 0xb0, 0x39, 0x03, 0x03, 0xa0, 0x14, 0x04, 0x03, 0xa8, 0x14, 0x04, 0x03, 0xe0, 0x34, 0x05, 0x04, 0xf0, 0x34, 0x05, 0x04, 0xc0, 0x11, 0x06, 0x04, + 0xe0, 0x32, 0x07, 0x05, 0x80, 0x0c, 0x0a, 0x06, 0xf8, 0x0a, 0x00, 0x02, 0xfc, 0x0a, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x04, 0x0b, 0x00, 0x02, 0xc4, 0x3d, 0x01, 0x02, 0xc8, 0x3d, 0x01, 0x02, + 0xcc, 0x3d, 0x01, 0x02, 0xd0, 0x3d, 0x01, 0x02, 0xd4, 0x3d, 0x01, 0x02, 0xd8, 0x3d, 0x01, 0x02, 0xb8, 0x17, 0x02, 0x02, 0xbc, 0x17, 0x02, 0x02, 0xc0, 0x17, 0x02, 0x02, 0xc4, 0x17, 0x02, 0x02, + 0xb8, 0x39, 0x03, 0x03, 0xc0, 0x39, 0x03, 0x03, 0xc8, 0x39, 0x03, 0x03, 0xb0, 0x14, 0x04, 0x03, 0xb8, 0x14, 0x04, 0x03, 0x00, 0x35, 0x05, 0x04, 0x10, 0x35, 0x05, 0x04, 0xd0, 0x11, 0x06, 0x04, + 0x00, 0x33, 0x07, 0x05, 0xc0, 0x0c, 0x0a, 0x06, 0x08, 0x0b, 0x00, 0x02, 0x0c, 0x0b, 0x00, 0x02, 0x10, 0x0b, 0x00, 0x02, 0x14, 0x0b, 0x00, 0x02, 0xdc, 0x3d, 0x01, 0x02, 0xe0, 0x3d, 0x01, 0x02, + 0xe4, 0x3d, 0x01, 0x02, 0xe8, 0x3d, 0x01, 0x02, 0xec, 0x3d, 0x01, 0x02, 0xf0, 0x3d, 0x01, 0x02, 0xc8, 0x17, 0x02, 0x02, 0xcc, 0x17, 0x02, 0x02, 0xd0, 0x17, 0x02, 0x02, 0xd4, 0x17, 0x02, 0x02, + 0xd0, 0x39, 0x03, 0x03, 0xd8, 0x39, 0x03, 0x03, 0xe0, 0x39, 0x03, 0x03, 0xc0, 0x14, 0x04, 0x03, 0xc8, 0x14, 0x04, 0x03, 0x20, 0x35, 0x05, 0x04, 0x30, 0x35, 0x05, 0x04, 0xe0, 0x11, 0x06, 0x04, + 0x20, 0x33, 0x07, 0x05, 0x00, 0x0d, 0x0a, 0x06, 0x18, 0x0b, 0x00, 0x02, 0x1c, 0x0b, 0x00, 0x02, 0x20, 0x0b, 0x00, 0x02, 0x24, 0x0b, 0x00, 0x02, 0xf4, 0x3d, 0x01, 0x02, 0xf8, 0x3d, 0x01, 0x02, + 0xfc, 0x3d, 0x01, 0x02, 0x00, 0x3e, 0x01, 0x02, 0x04, 0x3e, 0x01, 0x02, 0x08, 0x3e, 0x01, 0x02, 0xd8, 0x17, 0x02, 0x02, 0xdc, 0x17, 0x02, 0x02, 0xe0, 0x17, 0x02, 0x02, 0xe4, 0x17, 0x02, 0x02, + 0xe8, 0x39, 0x03, 0x03, 0xf0, 0x39, 0x03, 0x03, 0xf8, 0x39, 0x03, 0x03, 0xd0, 0x14, 0x04, 0x03, 0xd8, 0x14, 0x04, 0x03, 0x40, 0x35, 0x05, 0x04, 0x50, 0x35, 0x05, 0x04, 0xf0, 0x11, 0x06, 0x04, + 0x40, 0x33, 0x07, 0x05, 0x40, 0x0d, 0x0a, 0x06, 0x28, 0x0b, 0x00, 0x02, 0x2c, 0x0b, 0x00, 0x02, 0x30, 0x0b, 0x00, 0x02, 0x34, 0x0b, 0x00, 0x02, 0x0c, 0x3e, 0x01, 0x02, 0x10, 0x3e, 0x01, 0x02, + 0x14, 0x3e, 0x01, 0x02, 0x18, 0x3e, 0x01, 0x02, 0x1c, 0x3e, 0x01, 0x02, 0x20, 0x3e, 0x01, 0x02, 0xe8, 0x17, 0x02, 0x02, 0xec, 0x17, 0x02, 0x02, 0xf0, 0x17, 0x02, 0x02, 0xf4, 0x17, 0x02, 0x02, + 0x00, 0x3a, 0x03, 0x03, 0x08, 0x3a, 0x03, 0x03, 0x10, 0x3a, 0x03, 0x03, 0xe0, 0x14, 0x04, 0x03, 0xe8, 0x14, 0x04, 0x03, 0x60, 0x35, 0x05, 0x04, 0x70, 0x35, 0x05, 0x04, 0x00, 0x12, 0x06, 0x04, + 0x60, 0x33, 0x07, 0x05, 0x80, 0x0d, 0x0a, 0x06, 0x38, 0x0b, 0x00, 0x02, 0x3c, 0x0b, 0x00, 0x02, 0x40, 0x0b, 0x00, 0x02, 0x44, 0x0b, 0x00, 0x02, 0x24, 0x3e, 0x01, 0x02, 0x28, 0x3e, 0x01, 0x02, + 0x2c, 0x3e, 0x01, 0x02, 0x30, 0x3e, 0x01, 0x02, 0x34, 0x3e, 0x01, 0x02, 0x38, 0x3e, 0x01, 0x02, 0xf8, 0x17, 0x02, 0x02, 0xfc, 0x17, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, 0x04, 0x18, 0x02, 0x02, + 0x18, 0x3a, 0x03, 0x03, 0x20, 0x3a, 0x03, 0x03, 0x28, 0x3a, 0x03, 0x03, 0xf0, 0x14, 0x04, 0x03, 0xf8, 0x14, 0x04, 0x03, 0x80, 0x35, 0x05, 0x04, 0x90, 0x35, 0x05, 0x04, 0x10, 0x12, 0x06, 0x04, + 0xa0, 0x0c, 0x08, 0x05, 0xc0, 0x0d, 0x0a, 0x06, 0x48, 0x0b, 0x00, 0x02, 0x4c, 0x0b, 0x00, 0x02, 0x50, 0x0b, 0x00, 0x02, 0x54, 0x0b, 0x00, 0x02, 0x3c, 0x3e, 0x01, 0x02, 0x40, 0x3e, 0x01, 0x02, + 0x44, 0x3e, 0x01, 0x02, 0x48, 0x3e, 0x01, 0x02, 0x4c, 0x3e, 0x01, 0x02, 0x50, 0x3e, 0x01, 0x02, 0x08, 0x18, 0x02, 0x02, 0x0c, 0x18, 0x02, 0x02, 0x10, 0x18, 0x02, 0x02, 0x14, 0x18, 0x02, 0x02, + 0x30, 0x3a, 0x03, 0x03, 0x38, 0x3a, 0x03, 0x03, 0x40, 0x3a, 0x03, 0x03, 0x00, 0x15, 0x04, 0x03, 0x08, 0x15, 0x04, 0x03, 0xa0, 0x35, 0x05, 0x04, 0xb0, 0x35, 0x05, 0x04, 0x20, 0x12, 0x06, 0x04, + 0xc0, 0x0c, 0x08, 0x05, 0x00, 0x0e, 0x0a, 0x06, 0x58, 0x0b, 0x00, 0x02, 0x5c, 0x0b, 0x00, 0x02, 0x60, 0x0b, 0x00, 0x02, 0x64, 0x0b, 0x00, 0x02, 0x54, 0x3e, 0x01, 0x02, 0x58, 0x3e, 0x01, 0x02, + 0x5c, 0x3e, 0x01, 0x02, 0x60, 0x3e, 0x01, 0x02, 0x64, 0x3e, 0x01, 0x02, 0x68, 0x3e, 0x01, 0x02, 0x18, 0x18, 0x02, 0x02, 0x1c, 0x18, 0x02, 0x02, 0x20, 0x18, 0x02, 0x02, 0x24, 0x18, 0x02, 0x02, + 0x48, 0x3a, 0x03, 0x03, 0x50, 0x3a, 0x03, 0x03, 0x58, 0x3a, 0x03, 0x03, 0x10, 0x15, 0x04, 0x03, 0x18, 0x15, 0x04, 0x03, 0xc0, 0x35, 0x05, 0x04, 0xd0, 0x35, 0x05, 0x04, 0x30, 0x12, 0x06, 0x04, + 0xe0, 0x0c, 0x08, 0x05, 0x40, 0x0e, 0x0a, 0x06, 0x68, 0x0b, 0x00, 0x02, 0x6c, 0x0b, 0x00, 0x02, 0x70, 0x0b, 0x00, 0x02, 0x74, 0x0b, 0x00, 0x02, 0x6c, 0x3e, 0x01, 0x02, 0x70, 0x3e, 0x01, 0x02, + 0x74, 0x3e, 0x01, 0x02, 0x78, 0x3e, 0x01, 0x02, 0x7c, 0x3e, 0x01, 0x02, 0x80, 0x3e, 0x01, 0x02, 0x28, 0x18, 0x02, 0x02, 0x2c, 0x18, 0x02, 0x02, 0x30, 0x18, 0x02, 0x02, 0x34, 0x18, 0x02, 0x02, + 0x60, 0x3a, 0x03, 0x03, 0x68, 0x3a, 0x03, 0x03, 0x70, 0x3a, 0x03, 0x03, 0x20, 0x15, 0x04, 0x03, 0x28, 0x15, 0x04, 0x03, 0xe0, 0x35, 0x05, 0x04, 0xf0, 0x35, 0x05, 0x04, 0x40, 0x12, 0x06, 0x04, + 0x00, 0x0d, 0x08, 0x05, 0x80, 0x0e, 0x0a, 0x06, 0x78, 0x0b, 0x00, 0x02, 0x7c, 0x0b, 0x00, 0x02, 0x80, 0x0b, 0x00, 0x02, 0x84, 0x0b, 0x00, 0x02, 0x84, 0x3e, 0x01, 0x02, 0x88, 0x3e, 0x01, 0x02, + 0x8c, 0x3e, 0x01, 0x02, 0x90, 0x3e, 0x01, 0x02, 0x94, 0x3e, 0x01, 0x02, 0x98, 0x3e, 0x01, 0x02, 0x38, 0x18, 0x02, 0x02, 0x3c, 0x18, 0x02, 0x02, 0x40, 0x18, 0x02, 0x02, 0x44, 0x18, 0x02, 0x02, + 0x78, 0x3a, 0x03, 0x03, 0x80, 0x3a, 0x03, 0x03, 0x88, 0x3a, 0x03, 0x03, 0x30, 0x15, 0x04, 0x03, 0x38, 0x15, 0x04, 0x03, 0x00, 0x36, 0x05, 0x04, 0x10, 0x36, 0x05, 0x04, 0x50, 0x12, 0x06, 0x04, + 0x20, 0x0d, 0x08, 0x05, 0xc0, 0x0e, 0x0a, 0x06, 0x88, 0x0b, 0x00, 0x02, 0x8c, 0x0b, 0x00, 0x02, 0x90, 0x0b, 0x00, 0x02, 0x94, 0x0b, 0x00, 0x02, 0x9c, 0x3e, 0x01, 0x02, 0xa0, 0x3e, 0x01, 0x02, + 0xa4, 0x3e, 0x01, 0x02, 0xa8, 0x3e, 0x01, 0x02, 0xac, 0x3e, 0x01, 0x02, 0xb0, 0x3e, 0x01, 0x02, 0x48, 0x18, 0x02, 0x02, 0x4c, 0x18, 0x02, 0x02, 0x50, 0x18, 0x02, 0x02, 0x54, 0x18, 0x02, 0x02, + 0x90, 0x3a, 0x03, 0x03, 0x98, 0x3a, 0x03, 0x03, 0xa0, 0x3a, 0x03, 0x03, 0x40, 0x15, 0x04, 0x03, 0x48, 0x15, 0x04, 0x03, 0x20, 0x36, 0x05, 0x04, 0x30, 0x36, 0x05, 0x04, 0x60, 0x12, 0x06, 0x04, + 0x40, 0x0d, 0x08, 0x05, 0x00, 0x27, 0x0b, 0x07, 0x98, 0x0b, 0x00, 0x02, 0x9c, 0x0b, 0x00, 0x02, 0xa0, 0x0b, 0x00, 0x02, 0xa4, 0x0b, 0x00, 0x02, 0xb4, 0x3e, 0x01, 0x02, 0xb8, 0x3e, 0x01, 0x02, + 0xbc, 0x3e, 0x01, 0x02, 0xc0, 0x3e, 0x01, 0x02, 0xc4, 0x3e, 0x01, 0x02, 0xc8, 0x3e, 0x01, 0x02, 0x58, 0x18, 0x02, 0x02, 0x5c, 0x18, 0x02, 0x02, 0x60, 0x18, 0x02, 0x02, 0x64, 0x18, 0x02, 0x02, + 0xa8, 0x3a, 0x03, 0x03, 0xb0, 0x3a, 0x03, 0x03, 0xb8, 0x3a, 0x03, 0x03, 0x50, 0x15, 0x04, 0x03, 0x58, 0x15, 0x04, 0x03, 0x40, 0x36, 0x05, 0x04, 0x50, 0x36, 0x05, 0x04, 0x70, 0x12, 0x06, 0x04, + 0x60, 0x0d, 0x08, 0x05, 0x80, 0x27, 0x0b, 0x07, 0xa8, 0x0b, 0x00, 0x02, 0xac, 0x0b, 0x00, 0x02, 0xb0, 0x0b, 0x00, 0x02, 0xb4, 0x0b, 0x00, 0x02, 0xcc, 0x3e, 0x01, 0x02, 0xd0, 0x3e, 0x01, 0x02, + 0xd4, 0x3e, 0x01, 0x02, 0xd8, 0x3e, 0x01, 0x02, 0xdc, 0x3e, 0x01, 0x02, 0xe0, 0x3e, 0x01, 0x02, 0x68, 0x18, 0x02, 0x02, 0x6c, 0x18, 0x02, 0x02, 0x70, 0x18, 0x02, 0x02, 0x74, 0x18, 0x02, 0x02, + 0xc0, 0x3a, 0x03, 0x03, 0xc8, 0x3a, 0x03, 0x03, 0xd0, 0x3a, 0x03, 0x03, 0x60, 0x15, 0x04, 0x03, 0x68, 0x15, 0x04, 0x03, 0x60, 0x36, 0x05, 0x04, 0x70, 0x36, 0x05, 0x04, 0x80, 0x12, 0x06, 0x04, + 0x80, 0x0d, 0x08, 0x05, 0x00, 0x28, 0x0b, 0x07, 0xb8, 0x0b, 0x00, 0x02, 0xbc, 0x0b, 0x00, 0x02, 0xc0, 0x0b, 0x00, 0x02, 0xc4, 0x0b, 0x00, 0x02, 0xe4, 0x3e, 0x01, 0x02, 0xe8, 0x3e, 0x01, 0x02, + 0xec, 0x3e, 0x01, 0x02, 0xf0, 0x3e, 0x01, 0x02, 0xf4, 0x3e, 0x01, 0x02, 0xf8, 0x3e, 0x01, 0x02, 0x78, 0x18, 0x02, 0x02, 0x7c, 0x18, 0x02, 0x02, 0x80, 0x18, 0x02, 0x02, 0x84, 0x18, 0x02, 0x02, + 0xd8, 0x3a, 0x03, 0x03, 0xe0, 0x3a, 0x03, 0x03, 0xe8, 0x3a, 0x03, 0x03, 0x70, 0x15, 0x04, 0x03, 0x78, 0x15, 0x04, 0x03, 0x80, 0x36, 0x05, 0x04, 0x90, 0x36, 0x05, 0x04, 0x90, 0x12, 0x06, 0x04, + 0xa0, 0x0d, 0x08, 0x05, 0x80, 0x28, 0x0b, 0x07, 0xc8, 0x0b, 0x00, 0x02, 0xcc, 0x0b, 0x00, 0x02, 0xd0, 0x0b, 0x00, 0x02, 0xd4, 0x0b, 0x00, 0x02, 0xfc, 0x3e, 0x01, 0x02, 0x00, 0x3f, 0x01, 0x02, + 0x04, 0x3f, 0x01, 0x02, 0x08, 0x3f, 0x01, 0x02, 0x0c, 0x3f, 0x01, 0x02, 0x10, 0x3f, 0x01, 0x02, 0x88, 0x18, 0x02, 0x02, 0x8c, 0x18, 0x02, 0x02, 0x90, 0x18, 0x02, 0x02, 0x94, 0x18, 0x02, 0x02, + 0xf0, 0x3a, 0x03, 0x03, 0xf8, 0x3a, 0x03, 0x03, 0x00, 0x3b, 0x03, 0x03, 0x80, 0x15, 0x04, 0x03, 0x88, 0x15, 0x04, 0x03, 0xa0, 0x36, 0x05, 0x04, 0xb0, 0x36, 0x05, 0x04, 0xa0, 0x12, 0x06, 0x04, + 0xc0, 0x0d, 0x08, 0x05, 0x00, 0x29, 0x0b, 0x07, 0xd8, 0x0b, 0x00, 0x02, 0xdc, 0x0b, 0x00, 0x02, 0xe0, 0x0b, 0x00, 0x02, 0xe4, 0x0b, 0x00, 0x02, 0x14, 0x3f, 0x01, 0x02, 0x18, 0x3f, 0x01, 0x02, + 0x1c, 0x3f, 0x01, 0x02, 0x20, 0x3f, 0x01, 0x02, 0x24, 0x3f, 0x01, 0x02, 0x28, 0x3f, 0x01, 0x02, 0x98, 0x18, 0x02, 0x02, 0x9c, 0x18, 0x02, 0x02, 0xa0, 0x18, 0x02, 0x02, 0xa4, 0x18, 0x02, 0x02, + 0x08, 0x3b, 0x03, 0x03, 0x10, 0x3b, 0x03, 0x03, 0x18, 0x3b, 0x03, 0x03, 0x90, 0x15, 0x04, 0x03, 0x98, 0x15, 0x04, 0x03, 0xc0, 0x36, 0x05, 0x04, 0xd0, 0x36, 0x05, 0x04, 0xb0, 0x12, 0x06, 0x04, + 0xe0, 0x0d, 0x08, 0x05, 0x80, 0x29, 0x0b, 0x07, 0xe8, 0x0b, 0x00, 0x02, 0xec, 0x0b, 0x00, 0x02, 0xf0, 0x0b, 0x00, 0x02, 0xf4, 0x0b, 0x00, 0x02, 0x2c, 0x3f, 0x01, 0x02, 0x30, 0x3f, 0x01, 0x02, + 0x34, 0x3f, 0x01, 0x02, 0x38, 0x3f, 0x01, 0x02, 0x3c, 0x3f, 0x01, 0x02, 0x40, 0x3f, 0x01, 0x02, 0xa8, 0x18, 0x02, 0x02, 0xac, 0x18, 0x02, 0x02, 0xb0, 0x18, 0x02, 0x02, 0xb4, 0x18, 0x02, 0x02, + 0x20, 0x3b, 0x03, 0x03, 0x28, 0x3b, 0x03, 0x03, 0x30, 0x3b, 0x03, 0x03, 0xa0, 0x15, 0x04, 0x03, 0xa8, 0x15, 0x04, 0x03, 0xe0, 0x36, 0x05, 0x04, 0xf0, 0x36, 0x05, 0x04, 0xc0, 0x12, 0x06, 0x04, + 0x00, 0x0e, 0x08, 0x05, 0x00, 0x2a, 0x0b, 0x07, 0xf8, 0x0b, 0x00, 0x02, 0xfc, 0x0b, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x04, 0x0c, 0x00, 0x02, 0x44, 0x3f, 0x01, 0x02, 0x48, 0x3f, 0x01, 0x02, + 0x4c, 0x3f, 0x01, 0x02, 0x50, 0x3f, 0x01, 0x02, 0x54, 0x3f, 0x01, 0x02, 0x58, 0x3f, 0x01, 0x02, 0xb8, 0x18, 0x02, 0x02, 0xbc, 0x18, 0x02, 0x02, 0xc0, 0x18, 0x02, 0x02, 0xc4, 0x18, 0x02, 0x02, + 0x38, 0x3b, 0x03, 0x03, 0x40, 0x3b, 0x03, 0x03, 0x48, 0x3b, 0x03, 0x03, 0xb0, 0x15, 0x04, 0x03, 0xb8, 0x15, 0x04, 0x03, 0x00, 0x37, 0x05, 0x04, 0x10, 0x37, 0x05, 0x04, 0xd0, 0x12, 0x06, 0x04, + 0x20, 0x0e, 0x08, 0x05, 0x80, 0x2a, 0x0b, 0x07, 0x08, 0x0c, 0x00, 0x02, 0x0c, 0x0c, 0x00, 0x02, 0x10, 0x0c, 0x00, 0x02, 0x14, 0x0c, 0x00, 0x02, 0x5c, 0x3f, 0x01, 0x02, 0x60, 0x3f, 0x01, 0x02, + 0x64, 0x3f, 0x01, 0x02, 0x68, 0x3f, 0x01, 0x02, 0x6c, 0x3f, 0x01, 0x02, 0x70, 0x3f, 0x01, 0x02, 0xc8, 0x18, 0x02, 0x02, 0xcc, 0x18, 0x02, 0x02, 0xd0, 0x18, 0x02, 0x02, 0xd4, 0x18, 0x02, 0x02, + 0x50, 0x3b, 0x03, 0x03, 0x58, 0x3b, 0x03, 0x03, 0x60, 0x3b, 0x03, 0x03, 0xc0, 0x15, 0x04, 0x03, 0xc8, 0x15, 0x04, 0x03, 0x20, 0x37, 0x05, 0x04, 0x30, 0x37, 0x05, 0x04, 0xe0, 0x12, 0x06, 0x04, + 0x40, 0x0e, 0x08, 0x05, 0x00, 0x2b, 0x0b, 0x07, 0x18, 0x0c, 0x00, 0x02, 0x1c, 0x0c, 0x00, 0x02, 0x20, 0x0c, 0x00, 0x02, 0x24, 0x0c, 0x00, 0x02, 0x74, 0x3f, 0x01, 0x02, 0x78, 0x3f, 0x01, 0x02, + 0x7c, 0x3f, 0x01, 0x02, 0x80, 0x3f, 0x01, 0x02, 0x84, 0x3f, 0x01, 0x02, 0x88, 0x3f, 0x01, 0x02, 0xd8, 0x18, 0x02, 0x02, 0xdc, 0x18, 0x02, 0x02, 0xe0, 0x18, 0x02, 0x02, 0xe4, 0x18, 0x02, 0x02, + 0x68, 0x3b, 0x03, 0x03, 0x70, 0x3b, 0x03, 0x03, 0x78, 0x3b, 0x03, 0x03, 0xd0, 0x15, 0x04, 0x03, 0xd8, 0x15, 0x04, 0x03, 0x40, 0x37, 0x05, 0x04, 0x50, 0x37, 0x05, 0x04, 0xf0, 0x12, 0x06, 0x04, + 0x60, 0x0e, 0x08, 0x05, 0x80, 0x2b, 0x0b, 0x07, 0x28, 0x0c, 0x00, 0x02, 0x2c, 0x0c, 0x00, 0x02, 0x30, 0x0c, 0x00, 0x02, 0x34, 0x0c, 0x00, 0x02, 0x8c, 0x3f, 0x01, 0x02, 0x90, 0x3f, 0x01, 0x02, + 0x94, 0x3f, 0x01, 0x02, 0x98, 0x3f, 0x01, 0x02, 0x9c, 0x3f, 0x01, 0x02, 0xa0, 0x3f, 0x01, 0x02, 0xe8, 0x18, 0x02, 0x02, 0xec, 0x18, 0x02, 0x02, 0xf0, 0x18, 0x02, 0x02, 0xf4, 0x18, 0x02, 0x02, + 0x80, 0x3b, 0x03, 0x03, 0x88, 0x3b, 0x03, 0x03, 0x90, 0x3b, 0x03, 0x03, 0xe0, 0x15, 0x04, 0x03, 0xe8, 0x15, 0x04, 0x03, 0x60, 0x37, 0x05, 0x04, 0x70, 0x37, 0x05, 0x04, 0x00, 0x13, 0x06, 0x04, + 0x80, 0x0e, 0x08, 0x05, 0x00, 0x2c, 0x0b, 0x07, 0x38, 0x0c, 0x00, 0x02, 0x3c, 0x0c, 0x00, 0x02, 0x40, 0x0c, 0x00, 0x02, 0x44, 0x0c, 0x00, 0x02, 0xa4, 0x3f, 0x01, 0x02, 0xa8, 0x3f, 0x01, 0x02, + 0xac, 0x3f, 0x01, 0x02, 0xb0, 0x3f, 0x01, 0x02, 0xb4, 0x3f, 0x01, 0x02, 0xb8, 0x3f, 0x01, 0x02, 0xf8, 0x18, 0x02, 0x02, 0xfc, 0x18, 0x02, 0x02, 0x00, 0x19, 0x02, 0x02, 0x04, 0x19, 0x02, 0x02, + 0x98, 0x3b, 0x03, 0x03, 0xa0, 0x3b, 0x03, 0x03, 0xa8, 0x3b, 0x03, 0x03, 0xf0, 0x15, 0x04, 0x03, 0xf8, 0x15, 0x04, 0x03, 0x80, 0x37, 0x05, 0x04, 0x90, 0x37, 0x05, 0x04, 0x10, 0x13, 0x06, 0x04, + 0xa0, 0x0e, 0x08, 0x05, 0x80, 0x2c, 0x0b, 0x07, 0x48, 0x0c, 0x00, 0x02, 0x4c, 0x0c, 0x00, 0x02, 0x50, 0x0c, 0x00, 0x02, 0x54, 0x0c, 0x00, 0x02, 0xbc, 0x3f, 0x01, 0x02, 0xc0, 0x3f, 0x01, 0x02, + 0xc4, 0x3f, 0x01, 0x02, 0xc8, 0x3f, 0x01, 0x02, 0xcc, 0x3f, 0x01, 0x02, 0xd0, 0x3f, 0x01, 0x02, 0x08, 0x19, 0x02, 0x02, 0x0c, 0x19, 0x02, 0x02, 0x10, 0x19, 0x02, 0x02, 0x14, 0x19, 0x02, 0x02, + 0xb0, 0x3b, 0x03, 0x03, 0xb8, 0x3b, 0x03, 0x03, 0xc0, 0x3b, 0x03, 0x03, 0x00, 0x16, 0x04, 0x03, 0x08, 0x16, 0x04, 0x03, 0xa0, 0x37, 0x05, 0x04, 0xb0, 0x37, 0x05, 0x04, 0x20, 0x13, 0x06, 0x04, + 0xc0, 0x0e, 0x08, 0x05, 0x00, 0x2d, 0x0b, 0x07, 0x58, 0x0c, 0x00, 0x02, 0x5c, 0x0c, 0x00, 0x02, 0x60, 0x0c, 0x00, 0x02, 0x64, 0x0c, 0x00, 0x02, 0xd4, 0x3f, 0x01, 0x02, 0xd8, 0x3f, 0x01, 0x02, + 0xdc, 0x3f, 0x01, 0x02, 0xe0, 0x3f, 0x01, 0x02, 0xe4, 0x3f, 0x01, 0x02, 0xe8, 0x3f, 0x01, 0x02, 0x18, 0x19, 0x02, 0x02, 0x1c, 0x19, 0x02, 0x02, 0x20, 0x19, 0x02, 0x02, 0x24, 0x19, 0x02, 0x02, + 0xc8, 0x3b, 0x03, 0x03, 0xd0, 0x3b, 0x03, 0x03, 0xd8, 0x3b, 0x03, 0x03, 0x10, 0x16, 0x04, 0x03, 0x18, 0x16, 0x04, 0x03, 0xc0, 0x37, 0x05, 0x04, 0xd0, 0x37, 0x05, 0x04, 0x30, 0x13, 0x06, 0x04, + 0xe0, 0x0e, 0x08, 0x05, 0x80, 0x2d, 0x0b, 0x07, 0x68, 0x0c, 0x00, 0x02, 0x6c, 0x0c, 0x00, 0x02, 0x70, 0x0c, 0x00, 0x02, 0x74, 0x0c, 0x00, 0x02, 0xec, 0x3f, 0x01, 0x02, 0xf0, 0x3f, 0x01, 0x02, + 0xf4, 0x3f, 0x01, 0x02, 0xf8, 0x3f, 0x01, 0x02, 0xfc, 0x3f, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x28, 0x19, 0x02, 0x02, 0x2c, 0x19, 0x02, 0x02, 0x30, 0x19, 0x02, 0x02, 0x34, 0x19, 0x02, 0x02, + 0xe0, 0x3b, 0x03, 0x03, 0xe8, 0x3b, 0x03, 0x03, 0xf0, 0x3b, 0x03, 0x03, 0x20, 0x16, 0x04, 0x03, 0x28, 0x16, 0x04, 0x03, 0xe0, 0x37, 0x05, 0x04, 0xf0, 0x37, 0x05, 0x04, 0x40, 0x13, 0x06, 0x04, + 0x00, 0x0f, 0x08, 0x05, 0x80, 0x07, 0x0c, 0x07, 0x78, 0x0c, 0x00, 0x02, 0x7c, 0x0c, 0x00, 0x02, 0x80, 0x0c, 0x00, 0x02, 0x84, 0x0c, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x01, + 0x06, 0x00, 0x01, 0x01, 0x08, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x01, 0x0c, 0x00, 0x01, 0x01, 0x38, 0x19, 0x02, 0x02, 0x3c, 0x19, 0x02, 0x02, 0x40, 0x19, 0x02, 0x02, 0x44, 0x19, 0x02, 0x02, + 0xf8, 0x3b, 0x03, 0x03, 0x00, 0x3c, 0x03, 0x03, 0x08, 0x3c, 0x03, 0x03, 0x30, 0x16, 0x04, 0x03, 0x38, 0x16, 0x04, 0x03, 0x00, 0x38, 0x05, 0x04, 0x10, 0x38, 0x05, 0x04, 0x50, 0x13, 0x06, 0x04, + 0x20, 0x0f, 0x08, 0x05, 0x00, 0x08, 0x0c, 0x07, 0x88, 0x0c, 0x00, 0x02, 0x8c, 0x0c, 0x00, 0x02, 0x90, 0x0c, 0x00, 0x02, 0x94, 0x0c, 0x00, 0x02, 0x0e, 0x00, 0x01, 0x01, 0x10, 0x00, 0x01, 0x01, + 0x12, 0x00, 0x01, 0x01, 0x14, 0x00, 0x01, 0x01, 0x16, 0x00, 0x01, 0x01, 0x18, 0x00, 0x01, 0x01, 0x48, 0x19, 0x02, 0x02, 0x4c, 0x19, 0x02, 0x02, 0x50, 0x19, 0x02, 0x02, 0x54, 0x19, 0x02, 0x02, + 0x10, 0x3c, 0x03, 0x03, 0x18, 0x3c, 0x03, 0x03, 0x20, 0x3c, 0x03, 0x03, 0x40, 0x16, 0x04, 0x03, 0x48, 0x16, 0x04, 0x03, 0x20, 0x38, 0x05, 0x04, 0x30, 0x38, 0x05, 0x04, 0x60, 0x13, 0x06, 0x04, + 0x40, 0x0f, 0x08, 0x05, 0x80, 0x08, 0x0c, 0x07, 0x98, 0x0c, 0x00, 0x02, 0x9c, 0x0c, 0x00, 0x02, 0xa0, 0x0c, 0x00, 0x02, 0xa4, 0x0c, 0x00, 0x02, 0x1a, 0x00, 0x01, 0x01, 0x1c, 0x00, 0x01, 0x01, + 0x1e, 0x00, 0x01, 0x01, 0x20, 0x00, 0x01, 0x01, 0x22, 0x00, 0x01, 0x01, 0x24, 0x00, 0x01, 0x01, 0x58, 0x19, 0x02, 0x02, 0x5c, 0x19, 0x02, 0x02, 0x60, 0x19, 0x02, 0x02, 0x64, 0x19, 0x02, 0x02, + 0x28, 0x3c, 0x03, 0x03, 0x30, 0x3c, 0x03, 0x03, 0x38, 0x3c, 0x03, 0x03, 0x50, 0x16, 0x04, 0x03, 0x58, 0x16, 0x04, 0x03, 0x40, 0x38, 0x05, 0x04, 0x50, 0x38, 0x05, 0x04, 0x70, 0x13, 0x06, 0x04, + 0x60, 0x0f, 0x08, 0x05, 0x00, 0x09, 0x0c, 0x07, 0xa8, 0x0c, 0x00, 0x02, 0xac, 0x0c, 0x00, 0x02, 0xb0, 0x0c, 0x00, 0x02, 0xb4, 0x0c, 0x00, 0x02, 0x26, 0x00, 0x01, 0x01, 0x28, 0x00, 0x01, 0x01, + 0x2a, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x01, 0x01, 0x2e, 0x00, 0x01, 0x01, 0x30, 0x00, 0x01, 0x01, 0x68, 0x19, 0x02, 0x02, 0x6c, 0x19, 0x02, 0x02, 0x70, 0x19, 0x02, 0x02, 0x74, 0x19, 0x02, 0x02, + 0x40, 0x3c, 0x03, 0x03, 0x48, 0x3c, 0x03, 0x03, 0x50, 0x3c, 0x03, 0x03, 0x60, 0x16, 0x04, 0x03, 0x68, 0x16, 0x04, 0x03, 0x60, 0x38, 0x05, 0x04, 0x70, 0x38, 0x05, 0x04, 0x80, 0x13, 0x06, 0x04, + 0x80, 0x0f, 0x08, 0x05, 0x80, 0x09, 0x0c, 0x07, 0xb8, 0x0c, 0x00, 0x02, 0xbc, 0x0c, 0x00, 0x02, 0xc0, 0x0c, 0x00, 0x02, 0x32, 0x00, 0x01, 0x01, 0x34, 0x00, 0x01, 0x01, 0x36, 0x00, 0x01, 0x01, + 0x38, 0x00, 0x01, 0x01, 0x3a, 0x00, 0x01, 0x01, 0x3c, 0x00, 0x01, 0x01, 0x3e, 0x00, 0x01, 0x01, 0x78, 0x19, 0x02, 0x02, 0x7c, 0x19, 0x02, 0x02, 0x80, 0x19, 0x02, 0x02, 0x84, 0x19, 0x02, 0x02, + 0x58, 0x3c, 0x03, 0x03, 0x60, 0x3c, 0x03, 0x03, 0x68, 0x3c, 0x03, 0x03, 0x70, 0x16, 0x04, 0x03, 0x78, 0x16, 0x04, 0x03, 0x80, 0x38, 0x05, 0x04, 0x90, 0x38, 0x05, 0x04, 0x90, 0x13, 0x06, 0x04, + 0xa0, 0x0f, 0x08, 0x05, 0x00, 0x0a, 0x0c, 0x07, 0xc4, 0x0c, 0x00, 0x02, 0xc8, 0x0c, 0x00, 0x02, 0xcc, 0x0c, 0x00, 0x02, 0x40, 0x00, 0x01, 0x01, 0x42, 0x00, 0x01, 0x01, 0x44, 0x00, 0x01, 0x01, + 0x46, 0x00, 0x01, 0x01, 0x48, 0x00, 0x01, 0x01, 0x4a, 0x00, 0x01, 0x01, 0x4c, 0x00, 0x01, 0x01, 0x88, 0x19, 0x02, 0x02, 0x8c, 0x19, 0x02, 0x02, 0x90, 0x19, 0x02, 0x02, 0x94, 0x19, 0x02, 0x02, + 0x70, 0x3c, 0x03, 0x03, 0x78, 0x3c, 0x03, 0x03, 0x80, 0x3c, 0x03, 0x03, 0x80, 0x16, 0x04, 0x03, 0x88, 0x16, 0x04, 0x03, 0xa0, 0x38, 0x05, 0x04, 0xa0, 0x13, 0x06, 0x04, 0x80, 0x33, 0x07, 0x05, + 0xc0, 0x0f, 0x08, 0x05, 0x80, 0x0a, 0x0c, 0x07, 0xd0, 0x0c, 0x00, 0x02, 0xd4, 0x0c, 0x00, 0x02, 0xd8, 0x0c, 0x00, 0x02, 0x4e, 0x00, 0x01, 0x01, 0x50, 0x00, 0x01, 0x01, 0x52, 0x00, 0x01, 0x01, + 0x54, 0x00, 0x01, 0x01, 0x56, 0x00, 0x01, 0x01, 0x58, 0x00, 0x01, 0x01, 0x5a, 0x00, 0x01, 0x01, 0x98, 0x19, 0x02, 0x02, 0x9c, 0x19, 0x02, 0x02, 0xa0, 0x19, 0x02, 0x02, 0xa4, 0x19, 0x02, 0x02, + 0x88, 0x3c, 0x03, 0x03, 0x90, 0x3c, 0x03, 0x03, 0x98, 0x3c, 0x03, 0x03, 0x90, 0x16, 0x04, 0x03, 0x98, 0x16, 0x04, 0x03, 0xb0, 0x38, 0x05, 0x04, 0xb0, 0x13, 0x06, 0x04, 0xa0, 0x33, 0x07, 0x05, + 0xe0, 0x0f, 0x08, 0x05, 0x00, 0x0b, 0x0c, 0x07, 0xdc, 0x0c, 0x00, 0x02, 0xe0, 0x0c, 0x00, 0x02, 0xe4, 0x0c, 0x00, 0x02, 0x5c, 0x00, 0x01, 0x01, 0x5e, 0x00, 0x01, 0x01, 0x60, 0x00, 0x01, 0x01, + 0x62, 0x00, 0x01, 0x01, 0x64, 0x00, 0x01, 0x01, 0x66, 0x00, 0x01, 0x01, 0x68, 0x00, 0x01, 0x01, 0xa8, 0x19, 0x02, 0x02, 0xac, 0x19, 0x02, 0x02, 0xb0, 0x19, 0x02, 0x02, 0xb4, 0x19, 0x02, 0x02, + 0xa0, 0x3c, 0x03, 0x03, 0xa8, 0x3c, 0x03, 0x03, 0xb0, 0x3c, 0x03, 0x03, 0xa0, 0x16, 0x04, 0x03, 0xa8, 0x16, 0x04, 0x03, 0xc0, 0x38, 0x05, 0x04, 0xc0, 0x13, 0x06, 0x04, 0xc0, 0x33, 0x07, 0x05, + 0x00, 0x10, 0x08, 0x05, 0x80, 0x0b, 0x0c, 0x07, 0xe8, 0x0c, 0x00, 0x02, 0xec, 0x0c, 0x00, 0x02, 0xf0, 0x0c, 0x00, 0x02, 0x6a, 0x00, 0x01, 0x01, 0x6c, 0x00, 0x01, 0x01, 0x6e, 0x00, 0x01, 0x01, + 0x70, 0x00, 0x01, 0x01, 0x72, 0x00, 0x01, 0x01, 0x74, 0x00, 0x01, 0x01, 0x76, 0x00, 0x01, 0x01, 0xb8, 0x19, 0x02, 0x02, 0xbc, 0x19, 0x02, 0x02, 0xc0, 0x19, 0x02, 0x02, 0xc4, 0x19, 0x02, 0x02, + 0xb8, 0x3c, 0x03, 0x03, 0xc0, 0x3c, 0x03, 0x03, 0xc8, 0x3c, 0x03, 0x03, 0xb0, 0x16, 0x04, 0x03, 0xb8, 0x16, 0x04, 0x03, 0xd0, 0x38, 0x05, 0x04, 0xd0, 0x13, 0x06, 0x04, 0xe0, 0x33, 0x07, 0x05, + 0x20, 0x10, 0x08, 0x05, 0x00, 0x23, 0x0d, 0x08, 0xf4, 0x0c, 0x00, 0x02, 0xf8, 0x0c, 0x00, 0x02, 0xfc, 0x0c, 0x00, 0x02, 0x78, 0x00, 0x01, 0x01, 0x7a, 0x00, 0x01, 0x01, 0x7c, 0x00, 0x01, 0x01, + 0x7e, 0x00, 0x01, 0x01, 0x80, 0x00, 0x01, 0x01, 0x82, 0x00, 0x01, 0x01, 0x84, 0x00, 0x01, 0x01, 0xc8, 0x19, 0x02, 0x02, 0xcc, 0x19, 0x02, 0x02, 0xd0, 0x19, 0x02, 0x02, 0xd4, 0x19, 0x02, 0x02, + 0xd0, 0x3c, 0x03, 0x03, 0xd8, 0x3c, 0x03, 0x03, 0xe0, 0x3c, 0x03, 0x03, 0xc0, 0x16, 0x04, 0x03, 0xc8, 0x16, 0x04, 0x03, 0xe0, 0x38, 0x05, 0x04, 0xe0, 0x13, 0x06, 0x04, 0x00, 0x34, 0x07, 0x05, + 0x40, 0x10, 0x08, 0x05, 0x00, 0x24, 0x0d, 0x08, 0x00, 0x0d, 0x00, 0x02, 0x04, 0x0d, 0x00, 0x02, 0x08, 0x0d, 0x00, 0x02, 0x86, 0x00, 0x01, 0x01, 0x88, 0x00, 0x01, 0x01, 0x8a, 0x00, 0x01, 0x01, + 0x8c, 0x00, 0x01, 0x01, 0x8e, 0x00, 0x01, 0x01, 0x90, 0x00, 0x01, 0x01, 0x92, 0x00, 0x01, 0x01, 0xd8, 0x19, 0x02, 0x02, 0xdc, 0x19, 0x02, 0x02, 0xe0, 0x19, 0x02, 0x02, 0xe4, 0x19, 0x02, 0x02, + 0xe8, 0x3c, 0x03, 0x03, 0xf0, 0x3c, 0x03, 0x03, 0xf8, 0x3c, 0x03, 0x03, 0xd0, 0x16, 0x04, 0x03, 0xd8, 0x16, 0x04, 0x03, 0xf0, 0x38, 0x05, 0x04, 0xf0, 0x13, 0x06, 0x04, 0x20, 0x34, 0x07, 0x05, + 0x60, 0x10, 0x08, 0x05, 0x00, 0x25, 0x0d, 0x08, 0x0c, 0x0d, 0x00, 0x02, 0x10, 0x0d, 0x00, 0x02, 0x14, 0x0d, 0x00, 0x02, 0x94, 0x00, 0x01, 0x01, 0x96, 0x00, 0x01, 0x01, 0x98, 0x00, 0x01, 0x01, + 0x9a, 0x00, 0x01, 0x01, 0x9c, 0x00, 0x01, 0x01, 0x9e, 0x00, 0x01, 0x01, 0xa0, 0x00, 0x01, 0x01, 0xe8, 0x19, 0x02, 0x02, 0xec, 0x19, 0x02, 0x02, 0xf0, 0x19, 0x02, 0x02, 0xf4, 0x19, 0x02, 0x02, + 0x00, 0x3d, 0x03, 0x03, 0x08, 0x3d, 0x03, 0x03, 0x10, 0x3d, 0x03, 0x03, 0xe0, 0x16, 0x04, 0x03, 0xe8, 0x16, 0x04, 0x03, 0x00, 0x39, 0x05, 0x04, 0x00, 0x14, 0x06, 0x04, 0x40, 0x34, 0x07, 0x05, + 0x80, 0x10, 0x08, 0x05, 0x00, 0x26, 0x0d, 0x08, 0x18, 0x0d, 0x00, 0x02, 0x1c, 0x0d, 0x00, 0x02, 0x20, 0x0d, 0x00, 0x02, 0xa2, 0x00, 0x01, 0x01, 0xa4, 0x00, 0x01, 0x01, 0xa6, 0x00, 0x01, 0x01, + 0xa8, 0x00, 0x01, 0x01, 0xaa, 0x00, 0x01, 0x01, 0xac, 0x00, 0x01, 0x01, 0xae, 0x00, 0x01, 0x01, 0xf8, 0x19, 0x02, 0x02, 0xfc, 0x19, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x04, 0x1a, 0x02, 0x02, + 0x18, 0x3d, 0x03, 0x03, 0x20, 0x3d, 0x03, 0x03, 0x28, 0x3d, 0x03, 0x03, 0xf0, 0x16, 0x04, 0x03, 0xf8, 0x16, 0x04, 0x03, 0x10, 0x39, 0x05, 0x04, 0x10, 0x14, 0x06, 0x04, 0x60, 0x34, 0x07, 0x05, + 0xa0, 0x10, 0x08, 0x05, 0x00, 0x27, 0x0d, 0x08, 0x24, 0x0d, 0x00, 0x02, 0x28, 0x0d, 0x00, 0x02, 0x2c, 0x0d, 0x00, 0x02, 0xb0, 0x00, 0x01, 0x01, 0xb2, 0x00, 0x01, 0x01, 0xb4, 0x00, 0x01, 0x01, + 0xb6, 0x00, 0x01, 0x01, 0xb8, 0x00, 0x01, 0x01, 0xba, 0x00, 0x01, 0x01, 0xbc, 0x00, 0x01, 0x01, 0x08, 0x1a, 0x02, 0x02, 0x0c, 0x1a, 0x02, 0x02, 0x10, 0x1a, 0x02, 0x02, 0x14, 0x1a, 0x02, 0x02, + 0x30, 0x3d, 0x03, 0x03, 0x38, 0x3d, 0x03, 0x03, 0x40, 0x3d, 0x03, 0x03, 0x00, 0x17, 0x04, 0x03, 0x08, 0x17, 0x04, 0x03, 0x20, 0x39, 0x05, 0x04, 0x20, 0x14, 0x06, 0x04, 0x80, 0x34, 0x07, 0x05, + 0xc0, 0x10, 0x08, 0x05, 0x00, 0x28, 0x0d, 0x08, 0x30, 0x0d, 0x00, 0x02, 0x34, 0x0d, 0x00, 0x02, 0x38, 0x0d, 0x00, 0x02, 0xbe, 0x00, 0x01, 0x01, 0xc0, 0x00, 0x01, 0x01, 0xc2, 0x00, 0x01, 0x01, + 0xc4, 0x00, 0x01, 0x01, 0xc6, 0x00, 0x01, 0x01, 0xc8, 0x00, 0x01, 0x01, 0xca, 0x00, 0x01, 0x01, 0x18, 0x1a, 0x02, 0x02, 0x1c, 0x1a, 0x02, 0x02, 0x20, 0x1a, 0x02, 0x02, 0x24, 0x1a, 0x02, 0x02, + 0x48, 0x3d, 0x03, 0x03, 0x50, 0x3d, 0x03, 0x03, 0x58, 0x3d, 0x03, 0x03, 0x10, 0x17, 0x04, 0x03, 0x18, 0x17, 0x04, 0x03, 0x30, 0x39, 0x05, 0x04, 0x30, 0x14, 0x06, 0x04, 0xa0, 0x34, 0x07, 0x05, + 0xe0, 0x10, 0x08, 0x05, 0x00, 0x29, 0x0d, 0x08, 0x3c, 0x0d, 0x00, 0x02, 0x40, 0x0d, 0x00, 0x02, 0x44, 0x0d, 0x00, 0x02, 0xcc, 0x00, 0x01, 0x01, 0xce, 0x00, 0x01, 0x01, 0xd0, 0x00, 0x01, 0x01, + 0xd2, 0x00, 0x01, 0x01, 0xd4, 0x00, 0x01, 0x01, 0xd6, 0x00, 0x01, 0x01, 0xd8, 0x00, 0x01, 0x01, 0x28, 0x1a, 0x02, 0x02, 0x2c, 0x1a, 0x02, 0x02, 0x30, 0x1a, 0x02, 0x02, 0x34, 0x1a, 0x02, 0x02, + 0x60, 0x3d, 0x03, 0x03, 0x68, 0x3d, 0x03, 0x03, 0x70, 0x3d, 0x03, 0x03, 0x20, 0x17, 0x04, 0x03, 0x28, 0x17, 0x04, 0x03, 0x40, 0x39, 0x05, 0x04, 0x40, 0x14, 0x06, 0x04, 0xc0, 0x34, 0x07, 0x05, + 0x00, 0x11, 0x08, 0x05, 0x00, 0x06, 0x0e, 0x08, 0x48, 0x0d, 0x00, 0x02, 0x4c, 0x0d, 0x00, 0x02, 0x50, 0x0d, 0x00, 0x02, 0xda, 0x00, 0x01, 0x01, 0xdc, 0x00, 0x01, 0x01, 0xde, 0x00, 0x01, 0x01, + 0xe0, 0x00, 0x01, 0x01, 0xe2, 0x00, 0x01, 0x01, 0xe4, 0x00, 0x01, 0x01, 0xe6, 0x00, 0x01, 0x01, 0x38, 0x1a, 0x02, 0x02, 0x3c, 0x1a, 0x02, 0x02, 0x40, 0x1a, 0x02, 0x02, 0x44, 0x1a, 0x02, 0x02, + 0x78, 0x3d, 0x03, 0x03, 0x80, 0x3d, 0x03, 0x03, 0x88, 0x3d, 0x03, 0x03, 0x30, 0x17, 0x04, 0x03, 0x38, 0x17, 0x04, 0x03, 0x50, 0x39, 0x05, 0x04, 0x50, 0x14, 0x06, 0x04, 0xe0, 0x34, 0x07, 0x05, + 0x20, 0x11, 0x08, 0x05, 0x00, 0x07, 0x0e, 0x08, 0x54, 0x0d, 0x00, 0x02, 0x58, 0x0d, 0x00, 0x02, 0x5c, 0x0d, 0x00, 0x02, 0xe8, 0x00, 0x01, 0x01, 0xea, 0x00, 0x01, 0x01, 0xec, 0x00, 0x01, 0x01, + 0xee, 0x00, 0x01, 0x01, 0xf0, 0x00, 0x01, 0x01, 0xf2, 0x00, 0x01, 0x01, 0xf4, 0x00, 0x01, 0x01, 0x48, 0x1a, 0x02, 0x02, 0x4c, 0x1a, 0x02, 0x02, 0x50, 0x1a, 0x02, 0x02, 0x54, 0x1a, 0x02, 0x02, + 0x90, 0x3d, 0x03, 0x03, 0x98, 0x3d, 0x03, 0x03, 0xa0, 0x3d, 0x03, 0x03, 0x40, 0x17, 0x04, 0x03, 0x48, 0x17, 0x04, 0x03, 0x60, 0x39, 0x05, 0x04, 0x60, 0x14, 0x06, 0x04, 0x00, 0x35, 0x07, 0x05, + 0x40, 0x11, 0x08, 0x05, 0x00, 0x08, 0x0e, 0x08, 0x60, 0x0d, 0x00, 0x02, 0x64, 0x0d, 0x00, 0x02, 0x68, 0x0d, 0x00, 0x02, 0xf6, 0x00, 0x01, 0x01, 0xf8, 0x00, 0x01, 0x01, 0xfa, 0x00, 0x01, 0x01, + 0xfc, 0x00, 0x01, 0x01, 0xfe, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x58, 0x1a, 0x02, 0x02, 0x5c, 0x1a, 0x02, 0x02, 0x60, 0x1a, 0x02, 0x02, 0x64, 0x1a, 0x02, 0x02, + 0xa8, 0x3d, 0x03, 0x03, 0xb0, 0x3d, 0x03, 0x03, 0xb8, 0x3d, 0x03, 0x03, 0x50, 0x17, 0x04, 0x03, 0x58, 0x17, 0x04, 0x03, 0x70, 0x39, 0x05, 0x04, 0x70, 0x14, 0x06, 0x04, 0x20, 0x35, 0x07, 0x05, + 0x60, 0x11, 0x08, 0x05, 0x00, 0x09, 0x0e, 0x08, 0x6c, 0x0d, 0x00, 0x02, 0x70, 0x0d, 0x00, 0x02, 0x74, 0x0d, 0x00, 0x02, 0x04, 0x01, 0x01, 0x01, 0x06, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, + 0x0a, 0x01, 0x01, 0x01, 0x0c, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x01, 0x68, 0x1a, 0x02, 0x02, 0x6c, 0x1a, 0x02, 0x02, 0x70, 0x1a, 0x02, 0x02, 0x74, 0x1a, 0x02, 0x02, 0x78, 0x1a, 0x02, 0x02, + 0xc0, 0x3d, 0x03, 0x03, 0xc8, 0x3d, 0x03, 0x03, 0xd0, 0x3d, 0x03, 0x03, 0x60, 0x17, 0x04, 0x03, 0x68, 0x17, 0x04, 0x03, 0x80, 0x39, 0x05, 0x04, 0x80, 0x14, 0x06, 0x04, 0x40, 0x35, 0x07, 0x05, + 0x80, 0x11, 0x08, 0x05, 0x00, 0x24, 0x0f, 0x09, 0x78, 0x0d, 0x00, 0x02, 0x7c, 0x0d, 0x00, 0x02, 0x80, 0x0d, 0x00, 0x02, 0x10, 0x01, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x14, 0x01, 0x01, 0x01, + 0x16, 0x01, 0x01, 0x01, 0x18, 0x01, 0x01, 0x01, 0x1a, 0x01, 0x01, 0x01, 0x7c, 0x1a, 0x02, 0x02, 0x80, 0x1a, 0x02, 0x02, 0x84, 0x1a, 0x02, 0x02, 0x88, 0x1a, 0x02, 0x02, 0x8c, 0x1a, 0x02, 0x02, + 0xd8, 0x3d, 0x03, 0x03, 0xe0, 0x3d, 0x03, 0x03, 0xe8, 0x3d, 0x03, 0x03, 0x70, 0x17, 0x04, 0x03, 0x78, 0x17, 0x04, 0x03, 0x90, 0x39, 0x05, 0x04, 0x90, 0x14, 0x06, 0x04, 0x60, 0x35, 0x07, 0x05, + 0xa0, 0x11, 0x08, 0x05, 0x00, 0x26, 0x0f, 0x09, 0x84, 0x0d, 0x00, 0x02, 0x88, 0x0d, 0x00, 0x02, 0x8c, 0x0d, 0x00, 0x02, 0x1c, 0x01, 0x01, 0x01, 0x1e, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, + 0x22, 0x01, 0x01, 0x01, 0x00, 0x00, 0xfe, 0x0e, 0x00, 0x00, 0xfd, 0x0e, 0x00, 0x00, 0xfc, 0x0e, 0x00, 0x00, 0xfb, 0x0e, 0x00, 0x00, 0xfa, 0x0e, 0x00, 0x00, 0xf9, 0x0e, 0x00, 0x00, 0xf8, 0x0e, + 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0xf6, 0x0e, 0x00, 0x00, 0xf5, 0x0e, 0x00, 0x00, 0xf4, 0x0e, 0x00, 0x00, 0xf3, 0x0e, 0x00, 0x00, 0xf2, 0x0e, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0x00, 0xf0, 0x0e, + 0x00, 0x00, 0xef, 0x0e, 0x00, 0x00, 0xee, 0x0e, 0x00, 0x00, 0xed, 0x0e, 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xeb, 0x0e, 0x00, 0x00, 0xea, 0x0e, 0x00, 0x00, 0xe9, 0x0e, 0x00, 0x00, 0xe8, 0x0e, + 0x00, 0x00, 0xe7, 0x0e, 0x00, 0x00, 0xe6, 0x0e, 0x00, 0x00, 0xe5, 0x0e, 0x00, 0x00, 0xe4, 0x0e, 0x00, 0x00, 0xe3, 0x0e, 0x00, 0x00, 0xe2, 0x0e, 0x00, 0x00, 0xe1, 0x0e, 0x00, 0x00, 0xe0, 0x0e, + 0x00, 0x00, 0xdf, 0x0e, 0x00, 0x00, 0xde, 0x0e, 0x00, 0x00, 0xdd, 0x0e, 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0xdb, 0x0e, 0x00, 0x00, 0xda, 0x0e, 0x00, 0x00, 0xd9, 0x0e, 0x00, 0x00, 0xd8, 0x0e, + 0x00, 0x00, 0xd7, 0x0e, 0x00, 0x00, 0xd6, 0x0e, 0x00, 0x00, 0xd5, 0x0e, 0x00, 0x00, 0xd4, 0x0e, 0x00, 0x00, 0xd3, 0x0e, 0x00, 0x00, 0xd2, 0x0e, 0x00, 0x00, 0xd1, 0x0e, 0x00, 0x00, 0xd0, 0x0e, + 0x00, 0x00, 0xcf, 0x0e, 0x00, 0x00, 0xce, 0x0e, 0x00, 0x00, 0xcd, 0x0e, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x00, 0xcb, 0x0e, 0x00, 0x00, 0xca, 0x0e, 0x00, 0x00, 0xc9, 0x0e, 0x00, 0x00, 0xc8, 0x0e, + 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0xc5, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc3, 0x0e, 0x00, 0x00, 0xc2, 0x0e, 0x00, 0x00, 0xc1, 0x0e, 0x00, 0x00, 0xc0, 0x0e, + 0x00, 0x00, 0xbf, 0x0e, 0x00, 0x00, 0xbe, 0x0e, 0x00, 0x00, 0xbd, 0x0e, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x00, 0xbb, 0x0e, 0x00, 0x00, 0xba, 0x0e, 0x00, 0x00, 0xb9, 0x0e, 0x00, 0x00, 0xb8, 0x0e, + 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x00, 0xb6, 0x0e, 0x00, 0x00, 0xb5, 0x0e, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x00, 0xb3, 0x0e, 0x00, 0x00, 0xb2, 0x0e, 0x00, 0x00, 0xb1, 0x0e, 0x00, 0x00, 0xb0, 0x0e, + 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0xae, 0x0e, 0x00, 0x00, 0xad, 0x0e, 0x00, 0x00, 0xac, 0x0e, 0x00, 0x00, 0xab, 0x0e, 0x00, 0x00, 0xaa, 0x0e, 0x00, 0x00, 0xa9, 0x0e, 0x00, 0x00, 0xa8, 0x0e, + 0x00, 0x00, 0xa7, 0x0e, 0x00, 0x00, 0xa6, 0x0e, 0x00, 0x00, 0xa5, 0x0e, 0x00, 0x00, 0xa4, 0x0e, 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0xa2, 0x0e, 0x00, 0x00, 0xa1, 0x0e, 0x00, 0x00, 0xa0, 0x0e, + 0x00, 0x00, 0x9f, 0x0e, 0x00, 0x00, 0x9e, 0x0e, 0x00, 0x00, 0x9d, 0x0e, 0x00, 0x00, 0x9c, 0x0e, 0x00, 0x00, 0x9b, 0x0e, 0x00, 0x00, 0x9a, 0x0e, 0x00, 0x00, 0x99, 0x0e, 0x00, 0x00, 0x98, 0x0e, + 0x00, 0x00, 0x97, 0x0e, 0x00, 0x00, 0x96, 0x0e, 0x00, 0x00, 0x95, 0x0e, 0x00, 0x00, 0x94, 0x0e, 0x00, 0x00, 0x93, 0x0e, 0x00, 0x00, 0x92, 0x0e, 0x00, 0x00, 0x91, 0x0e, 0x00, 0x00, 0x90, 0x0e, + 0x00, 0x00, 0x8f, 0x0e, 0x00, 0x00, 0x8e, 0x0e, 0x00, 0x00, 0x8d, 0x0e, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x00, 0x8b, 0x0e, 0x00, 0x00, 0x8a, 0x0e, 0x00, 0x00, 0x89, 0x0e, 0x00, 0x00, 0x88, 0x0e, + 0x00, 0x00, 0x87, 0x0e, 0x00, 0x00, 0x86, 0x0e, 0x00, 0x00, 0x85, 0x0e, 0x00, 0x00, 0x84, 0x0e, 0x00, 0x00, 0x83, 0x0e, 0x00, 0x00, 0x82, 0x0e, 0x00, 0x00, 0x81, 0x0e, 0x00, 0x00, 0x80, 0x0e, + 0x00, 0x00, 0x7f, 0x0e, 0x00, 0x00, 0x7e, 0x0e, 0x00, 0x00, 0x7d, 0x0e, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x00, 0x7b, 0x0e, 0x00, 0x00, 0x7a, 0x0e, 0x00, 0x00, 0x79, 0x0e, 0x00, 0x00, 0x78, 0x0e, + 0x00, 0x00, 0x77, 0x0e, 0x00, 0x00, 0x76, 0x0e, 0x00, 0x00, 0x75, 0x0e, 0x00, 0x00, 0x74, 0x0e, 0x00, 0x00, 0x73, 0x0e, 0x00, 0x00, 0x72, 0x0e, 0x00, 0x00, 0x71, 0x0e, 0x00, 0x00, 0x70, 0x0e, + 0x00, 0x00, 0x6f, 0x0e, 0x00, 0x00, 0x6e, 0x0e, 0x00, 0x00, 0x6d, 0x0e, 0x00, 0x00, 0x6c, 0x0e, 0x00, 0x00, 0x6b, 0x0e, 0x00, 0x00, 0x6a, 0x0e, 0x00, 0x00, 0x69, 0x0e, 0x00, 0x00, 0x68, 0x0e, + 0x00, 0x00, 0x67, 0x0e, 0x00, 0x00, 0x66, 0x0e, 0x00, 0x00, 0x65, 0x0e, 0x00, 0x00, 0x64, 0x0e, 0x00, 0x00, 0x63, 0x0e, 0x00, 0x00, 0x62, 0x0e, 0x00, 0x00, 0x61, 0x0e, 0x00, 0x00, 0x60, 0x0e, + 0x00, 0x00, 0x5f, 0x0e, 0x00, 0x00, 0x5e, 0x0e, 0x00, 0x00, 0x5d, 0x0e, 0x00, 0x00, 0x5c, 0x0e, 0x00, 0x00, 0x5b, 0x0e, 0x00, 0x00, 0x5a, 0x0e, 0x00, 0x00, 0x59, 0x0e, 0x00, 0x00, 0x58, 0x0e, + 0x00, 0x00, 0x57, 0x0e, 0x00, 0x00, 0x56, 0x0e, 0x00, 0x00, 0x55, 0x0e, 0x00, 0x00, 0x54, 0x0e, 0x00, 0x00, 0x53, 0x0e, 0x00, 0x00, 0x52, 0x0e, 0x00, 0x00, 0x51, 0x0e, 0x00, 0x00, 0x50, 0x0e, + 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x4e, 0x0e, 0x00, 0x00, 0x4d, 0x0e, 0x00, 0x00, 0x4c, 0x0e, 0x00, 0x00, 0x4b, 0x0e, 0x00, 0x00, 0x4a, 0x0e, 0x00, 0x00, 0x49, 0x0e, 0x00, 0x00, 0x48, 0x0e, + 0x00, 0x00, 0x47, 0x0e, 0x00, 0x00, 0x46, 0x0e, 0x00, 0x00, 0x45, 0x0e, 0x00, 0x00, 0x44, 0x0e, 0x00, 0x00, 0x43, 0x0e, 0x00, 0x00, 0x42, 0x0e, 0x00, 0x00, 0x41, 0x0e, 0x00, 0x00, 0x40, 0x0e, + 0x00, 0x00, 0x3f, 0x0e, 0x00, 0x00, 0x3e, 0x0e, 0x00, 0x00, 0x3d, 0x0e, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x3a, 0x0e, 0x00, 0x00, 0x39, 0x0e, 0x00, 0x00, 0x38, 0x0e, + 0x00, 0x00, 0x37, 0x0e, 0x00, 0x00, 0x36, 0x0e, 0x00, 0x00, 0x35, 0x0e, 0x00, 0x00, 0x34, 0x0e, 0x00, 0x00, 0x33, 0x0e, 0x00, 0x00, 0x32, 0x0e, 0x00, 0x00, 0x31, 0x0e, 0x00, 0x00, 0x30, 0x0e, + 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x2e, 0x0e, 0x00, 0x00, 0x2d, 0x0e, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00, 0x2b, 0x0e, 0x00, 0x00, 0x2a, 0x0e, 0x00, 0x00, 0x29, 0x0e, 0x00, 0x00, 0x28, 0x0e, + 0x00, 0x00, 0x27, 0x0e, 0x00, 0x00, 0x26, 0x0e, 0x00, 0x00, 0x25, 0x0e, 0x00, 0x00, 0x24, 0x0e, 0x00, 0x00, 0x23, 0x0e, 0x00, 0x00, 0x22, 0x0e, 0x00, 0x00, 0x21, 0x0e, 0x00, 0x00, 0x20, 0x0e, + 0x00, 0x00, 0x1f, 0x0e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x1d, 0x0e, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0x1b, 0x0e, 0x00, 0x00, 0x1a, 0x0e, 0x00, 0x00, 0x19, 0x0e, 0x00, 0x00, 0x18, 0x0e, + 0x00, 0x00, 0x17, 0x0e +}; + +const byte DTable_3[65540] = { + 0x0e, 0x00, 0x01, 0x00, 0xe0, 0x0e, 0x00, 0x03, 0xe8, 0x0e, 0x00, 0x03, 0xf0, 0x0e, 0x00, 0x03, 0xf8, 0x0e, 0x00, 0x03, 0xec, 0x01, 0x01, 0x02, 0xf0, 0x01, 0x01, 0x02, 0xf4, 0x01, 0x01, 0x02, + 0xf8, 0x01, 0x01, 0x02, 0xfc, 0x01, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02, 0x08, 0x1b, 0x02, 0x03, 0x10, 0x1b, 0x02, 0x03, 0x18, 0x1b, 0x02, 0x03, 0x20, 0x1b, 0x02, 0x03, + 0xb0, 0x3d, 0x03, 0x04, 0xc0, 0x3d, 0x03, 0x04, 0xd0, 0x3d, 0x03, 0x04, 0xd0, 0x16, 0x04, 0x04, 0xe0, 0x16, 0x04, 0x04, 0xe0, 0x37, 0x05, 0x05, 0xc0, 0x12, 0x06, 0x05, 0x40, 0x32, 0x07, 0x06, + 0x00, 0x2d, 0x09, 0x07, 0x00, 0x0f, 0x00, 0x03, 0x08, 0x0f, 0x00, 0x03, 0x10, 0x0f, 0x00, 0x03, 0x18, 0x0f, 0x00, 0x03, 0x08, 0x02, 0x01, 0x02, 0x0c, 0x02, 0x01, 0x02, 0x10, 0x02, 0x01, 0x02, + 0x14, 0x02, 0x01, 0x02, 0x18, 0x02, 0x01, 0x02, 0x1c, 0x02, 0x01, 0x02, 0x28, 0x1b, 0x02, 0x03, 0x30, 0x1b, 0x02, 0x03, 0x38, 0x1b, 0x02, 0x03, 0x40, 0x1b, 0x02, 0x03, 0x48, 0x1b, 0x02, 0x03, + 0xe0, 0x3d, 0x03, 0x04, 0xf0, 0x3d, 0x03, 0x04, 0x00, 0x3e, 0x03, 0x04, 0xf0, 0x16, 0x04, 0x04, 0x00, 0x17, 0x04, 0x04, 0x00, 0x38, 0x05, 0x05, 0xe0, 0x12, 0x06, 0x05, 0x80, 0x32, 0x07, 0x06, + 0x80, 0x2d, 0x09, 0x07, 0x20, 0x0f, 0x00, 0x03, 0x28, 0x0f, 0x00, 0x03, 0x30, 0x0f, 0x00, 0x03, 0x38, 0x0f, 0x00, 0x03, 0x20, 0x02, 0x01, 0x02, 0x24, 0x02, 0x01, 0x02, 0x28, 0x02, 0x01, 0x02, + 0x2c, 0x02, 0x01, 0x02, 0x30, 0x02, 0x01, 0x02, 0x34, 0x02, 0x01, 0x02, 0x50, 0x1b, 0x02, 0x03, 0x58, 0x1b, 0x02, 0x03, 0x60, 0x1b, 0x02, 0x03, 0x68, 0x1b, 0x02, 0x03, 0x70, 0x1b, 0x02, 0x03, + 0x10, 0x3e, 0x03, 0x04, 0x20, 0x3e, 0x03, 0x04, 0x30, 0x3e, 0x03, 0x04, 0x10, 0x17, 0x04, 0x04, 0x20, 0x17, 0x04, 0x04, 0x20, 0x38, 0x05, 0x05, 0x00, 0x13, 0x06, 0x05, 0xc0, 0x32, 0x07, 0x06, + 0x00, 0x2e, 0x09, 0x07, 0x40, 0x0f, 0x00, 0x03, 0x48, 0x0f, 0x00, 0x03, 0x50, 0x0f, 0x00, 0x03, 0x58, 0x0f, 0x00, 0x03, 0x38, 0x02, 0x01, 0x02, 0x3c, 0x02, 0x01, 0x02, 0x40, 0x02, 0x01, 0x02, + 0x44, 0x02, 0x01, 0x02, 0x48, 0x02, 0x01, 0x02, 0x4c, 0x02, 0x01, 0x02, 0x78, 0x1b, 0x02, 0x03, 0x80, 0x1b, 0x02, 0x03, 0x88, 0x1b, 0x02, 0x03, 0x90, 0x1b, 0x02, 0x03, 0x98, 0x1b, 0x02, 0x03, + 0x40, 0x3e, 0x03, 0x04, 0x50, 0x3e, 0x03, 0x04, 0x60, 0x3e, 0x03, 0x04, 0x30, 0x17, 0x04, 0x04, 0x40, 0x17, 0x04, 0x04, 0x40, 0x38, 0x05, 0x05, 0x20, 0x13, 0x06, 0x05, 0x00, 0x33, 0x07, 0x06, + 0x80, 0x2e, 0x09, 0x07, 0x60, 0x0f, 0x00, 0x03, 0x68, 0x0f, 0x00, 0x03, 0x70, 0x0f, 0x00, 0x03, 0x78, 0x0f, 0x00, 0x03, 0x50, 0x02, 0x01, 0x02, 0x54, 0x02, 0x01, 0x02, 0x58, 0x02, 0x01, 0x02, + 0x5c, 0x02, 0x01, 0x02, 0x60, 0x02, 0x01, 0x02, 0x64, 0x02, 0x01, 0x02, 0xa0, 0x1b, 0x02, 0x03, 0xa8, 0x1b, 0x02, 0x03, 0xb0, 0x1b, 0x02, 0x03, 0xb8, 0x1b, 0x02, 0x03, 0xc0, 0x1b, 0x02, 0x03, + 0x70, 0x3e, 0x03, 0x04, 0x80, 0x3e, 0x03, 0x04, 0x90, 0x3e, 0x03, 0x04, 0x50, 0x17, 0x04, 0x04, 0x60, 0x17, 0x04, 0x04, 0x60, 0x38, 0x05, 0x05, 0x40, 0x13, 0x06, 0x05, 0x40, 0x33, 0x07, 0x06, + 0x00, 0x2f, 0x09, 0x07, 0x80, 0x0f, 0x00, 0x03, 0x88, 0x0f, 0x00, 0x03, 0x90, 0x0f, 0x00, 0x03, 0x98, 0x0f, 0x00, 0x03, 0x68, 0x02, 0x01, 0x02, 0x6c, 0x02, 0x01, 0x02, 0x70, 0x02, 0x01, 0x02, + 0x74, 0x02, 0x01, 0x02, 0x78, 0x02, 0x01, 0x02, 0x7c, 0x02, 0x01, 0x02, 0xc8, 0x1b, 0x02, 0x03, 0xd0, 0x1b, 0x02, 0x03, 0xd8, 0x1b, 0x02, 0x03, 0xe0, 0x1b, 0x02, 0x03, 0xe8, 0x1b, 0x02, 0x03, + 0xa0, 0x3e, 0x03, 0x04, 0xb0, 0x3e, 0x03, 0x04, 0xc0, 0x3e, 0x03, 0x04, 0x70, 0x17, 0x04, 0x04, 0x80, 0x17, 0x04, 0x04, 0x80, 0x38, 0x05, 0x05, 0x60, 0x13, 0x06, 0x05, 0x80, 0x33, 0x07, 0x06, + 0x80, 0x2f, 0x09, 0x07, 0xa0, 0x0f, 0x00, 0x03, 0xa8, 0x0f, 0x00, 0x03, 0xb0, 0x0f, 0x00, 0x03, 0xb8, 0x0f, 0x00, 0x03, 0x80, 0x02, 0x01, 0x02, 0x84, 0x02, 0x01, 0x02, 0x88, 0x02, 0x01, 0x02, + 0x8c, 0x02, 0x01, 0x02, 0x90, 0x02, 0x01, 0x02, 0x94, 0x02, 0x01, 0x02, 0xf0, 0x1b, 0x02, 0x03, 0xf8, 0x1b, 0x02, 0x03, 0x00, 0x1c, 0x02, 0x03, 0x08, 0x1c, 0x02, 0x03, 0x10, 0x1c, 0x02, 0x03, + 0xd0, 0x3e, 0x03, 0x04, 0xe0, 0x3e, 0x03, 0x04, 0xf0, 0x3e, 0x03, 0x04, 0x90, 0x17, 0x04, 0x04, 0xa0, 0x17, 0x04, 0x04, 0xa0, 0x38, 0x05, 0x05, 0x80, 0x13, 0x06, 0x05, 0xc0, 0x33, 0x07, 0x06, + 0x00, 0x30, 0x09, 0x07, 0xc0, 0x0f, 0x00, 0x03, 0xc8, 0x0f, 0x00, 0x03, 0xd0, 0x0f, 0x00, 0x03, 0xd8, 0x0f, 0x00, 0x03, 0x98, 0x02, 0x01, 0x02, 0x9c, 0x02, 0x01, 0x02, 0xa0, 0x02, 0x01, 0x02, + 0xa4, 0x02, 0x01, 0x02, 0xa8, 0x02, 0x01, 0x02, 0xac, 0x02, 0x01, 0x02, 0x18, 0x1c, 0x02, 0x03, 0x20, 0x1c, 0x02, 0x03, 0x28, 0x1c, 0x02, 0x03, 0x30, 0x1c, 0x02, 0x03, 0x38, 0x1c, 0x02, 0x03, + 0x00, 0x3f, 0x03, 0x04, 0x10, 0x3f, 0x03, 0x04, 0x20, 0x3f, 0x03, 0x04, 0xb0, 0x17, 0x04, 0x04, 0xc0, 0x17, 0x04, 0x04, 0xc0, 0x38, 0x05, 0x05, 0xa0, 0x13, 0x06, 0x05, 0x00, 0x34, 0x07, 0x06, + 0x80, 0x30, 0x09, 0x07, 0xe0, 0x0f, 0x00, 0x03, 0xe8, 0x0f, 0x00, 0x03, 0xf0, 0x0f, 0x00, 0x03, 0xf8, 0x0f, 0x00, 0x03, 0xb0, 0x02, 0x01, 0x02, 0xb4, 0x02, 0x01, 0x02, 0xb8, 0x02, 0x01, 0x02, + 0xbc, 0x02, 0x01, 0x02, 0xc0, 0x02, 0x01, 0x02, 0xc4, 0x02, 0x01, 0x02, 0x40, 0x1c, 0x02, 0x03, 0x48, 0x1c, 0x02, 0x03, 0x50, 0x1c, 0x02, 0x03, 0x58, 0x1c, 0x02, 0x03, 0x60, 0x1c, 0x02, 0x03, + 0x30, 0x3f, 0x03, 0x04, 0x40, 0x3f, 0x03, 0x04, 0x50, 0x3f, 0x03, 0x04, 0xd0, 0x17, 0x04, 0x04, 0xe0, 0x17, 0x04, 0x04, 0xe0, 0x38, 0x05, 0x05, 0xc0, 0x13, 0x06, 0x05, 0x40, 0x34, 0x07, 0x06, + 0x00, 0x31, 0x09, 0x07, 0x00, 0x10, 0x00, 0x03, 0x08, 0x10, 0x00, 0x03, 0x10, 0x10, 0x00, 0x03, 0x18, 0x10, 0x00, 0x03, 0xc8, 0x02, 0x01, 0x02, 0xcc, 0x02, 0x01, 0x02, 0xd0, 0x02, 0x01, 0x02, + 0xd4, 0x02, 0x01, 0x02, 0xd8, 0x02, 0x01, 0x02, 0xdc, 0x02, 0x01, 0x02, 0x68, 0x1c, 0x02, 0x03, 0x70, 0x1c, 0x02, 0x03, 0x78, 0x1c, 0x02, 0x03, 0x80, 0x1c, 0x02, 0x03, 0x88, 0x1c, 0x02, 0x03, + 0x60, 0x3f, 0x03, 0x04, 0x70, 0x3f, 0x03, 0x04, 0x80, 0x3f, 0x03, 0x04, 0xf0, 0x17, 0x04, 0x04, 0x00, 0x18, 0x04, 0x04, 0x00, 0x39, 0x05, 0x05, 0xe0, 0x13, 0x06, 0x05, 0x80, 0x34, 0x07, 0x06, + 0x80, 0x31, 0x09, 0x07, 0x20, 0x10, 0x00, 0x03, 0x28, 0x10, 0x00, 0x03, 0x30, 0x10, 0x00, 0x03, 0x38, 0x10, 0x00, 0x03, 0xe0, 0x02, 0x01, 0x02, 0xe4, 0x02, 0x01, 0x02, 0xe8, 0x02, 0x01, 0x02, + 0xec, 0x02, 0x01, 0x02, 0xf0, 0x02, 0x01, 0x02, 0xf4, 0x02, 0x01, 0x02, 0x90, 0x1c, 0x02, 0x03, 0x98, 0x1c, 0x02, 0x03, 0xa0, 0x1c, 0x02, 0x03, 0xa8, 0x1c, 0x02, 0x03, 0xb0, 0x1c, 0x02, 0x03, + 0x90, 0x3f, 0x03, 0x04, 0xa0, 0x3f, 0x03, 0x04, 0xb0, 0x3f, 0x03, 0x04, 0x10, 0x18, 0x04, 0x04, 0x20, 0x18, 0x04, 0x04, 0x20, 0x39, 0x05, 0x05, 0x00, 0x14, 0x06, 0x05, 0xc0, 0x34, 0x07, 0x06, + 0x00, 0x32, 0x09, 0x07, 0x40, 0x10, 0x00, 0x03, 0x48, 0x10, 0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x58, 0x10, 0x00, 0x03, 0xf8, 0x02, 0x01, 0x02, 0xfc, 0x02, 0x01, 0x02, 0x00, 0x03, 0x01, 0x02, + 0x04, 0x03, 0x01, 0x02, 0x08, 0x03, 0x01, 0x02, 0x0c, 0x03, 0x01, 0x02, 0xb8, 0x1c, 0x02, 0x03, 0xc0, 0x1c, 0x02, 0x03, 0xc8, 0x1c, 0x02, 0x03, 0xd0, 0x1c, 0x02, 0x03, 0xd8, 0x1c, 0x02, 0x03, + 0xc0, 0x3f, 0x03, 0x04, 0xd0, 0x3f, 0x03, 0x04, 0xe0, 0x3f, 0x03, 0x04, 0x30, 0x18, 0x04, 0x04, 0x40, 0x18, 0x04, 0x04, 0x40, 0x39, 0x05, 0x05, 0x20, 0x14, 0x06, 0x05, 0x00, 0x35, 0x07, 0x06, + 0x80, 0x32, 0x09, 0x07, 0x60, 0x10, 0x00, 0x03, 0x68, 0x10, 0x00, 0x03, 0x70, 0x10, 0x00, 0x03, 0x78, 0x10, 0x00, 0x03, 0x10, 0x03, 0x01, 0x02, 0x14, 0x03, 0x01, 0x02, 0x18, 0x03, 0x01, 0x02, + 0x1c, 0x03, 0x01, 0x02, 0x20, 0x03, 0x01, 0x02, 0x24, 0x03, 0x01, 0x02, 0xe0, 0x1c, 0x02, 0x03, 0xe8, 0x1c, 0x02, 0x03, 0xf0, 0x1c, 0x02, 0x03, 0xf8, 0x1c, 0x02, 0x03, 0x00, 0x1d, 0x02, 0x03, + 0xf0, 0x3f, 0x03, 0x04, 0x00, 0x00, 0x03, 0x03, 0x08, 0x00, 0x03, 0x03, 0x50, 0x18, 0x04, 0x04, 0x60, 0x18, 0x04, 0x04, 0x60, 0x39, 0x05, 0x05, 0x40, 0x14, 0x06, 0x05, 0x40, 0x35, 0x07, 0x06, + 0x00, 0x33, 0x09, 0x07, 0x80, 0x10, 0x00, 0x03, 0x88, 0x10, 0x00, 0x03, 0x90, 0x10, 0x00, 0x03, 0x98, 0x10, 0x00, 0x03, 0x28, 0x03, 0x01, 0x02, 0x2c, 0x03, 0x01, 0x02, 0x30, 0x03, 0x01, 0x02, + 0x34, 0x03, 0x01, 0x02, 0x38, 0x03, 0x01, 0x02, 0x3c, 0x03, 0x01, 0x02, 0x08, 0x1d, 0x02, 0x03, 0x10, 0x1d, 0x02, 0x03, 0x18, 0x1d, 0x02, 0x03, 0x20, 0x1d, 0x02, 0x03, 0x28, 0x1d, 0x02, 0x03, + 0x10, 0x00, 0x03, 0x03, 0x18, 0x00, 0x03, 0x03, 0x20, 0x00, 0x03, 0x03, 0x70, 0x18, 0x04, 0x04, 0x80, 0x18, 0x04, 0x04, 0x80, 0x39, 0x05, 0x05, 0x60, 0x14, 0x06, 0x05, 0x80, 0x35, 0x07, 0x06, + 0x80, 0x33, 0x09, 0x07, 0xa0, 0x10, 0x00, 0x03, 0xa8, 0x10, 0x00, 0x03, 0xb0, 0x10, 0x00, 0x03, 0xb8, 0x10, 0x00, 0x03, 0x40, 0x03, 0x01, 0x02, 0x44, 0x03, 0x01, 0x02, 0x48, 0x03, 0x01, 0x02, + 0x4c, 0x03, 0x01, 0x02, 0x50, 0x03, 0x01, 0x02, 0x54, 0x03, 0x01, 0x02, 0x30, 0x1d, 0x02, 0x03, 0x38, 0x1d, 0x02, 0x03, 0x40, 0x1d, 0x02, 0x03, 0x48, 0x1d, 0x02, 0x03, 0x50, 0x1d, 0x02, 0x03, + 0x28, 0x00, 0x03, 0x03, 0x30, 0x00, 0x03, 0x03, 0x38, 0x00, 0x03, 0x03, 0x90, 0x18, 0x04, 0x04, 0xa0, 0x18, 0x04, 0x04, 0xa0, 0x39, 0x05, 0x05, 0x80, 0x14, 0x06, 0x05, 0xc0, 0x35, 0x07, 0x06, + 0x00, 0x34, 0x09, 0x07, 0xc0, 0x10, 0x00, 0x03, 0xc8, 0x10, 0x00, 0x03, 0xd0, 0x10, 0x00, 0x03, 0xd8, 0x10, 0x00, 0x03, 0x58, 0x03, 0x01, 0x02, 0x5c, 0x03, 0x01, 0x02, 0x60, 0x03, 0x01, 0x02, + 0x64, 0x03, 0x01, 0x02, 0x68, 0x03, 0x01, 0x02, 0x6c, 0x03, 0x01, 0x02, 0x58, 0x1d, 0x02, 0x03, 0x60, 0x1d, 0x02, 0x03, 0x68, 0x1d, 0x02, 0x03, 0x70, 0x1d, 0x02, 0x03, 0x78, 0x1d, 0x02, 0x03, + 0x40, 0x00, 0x03, 0x03, 0x48, 0x00, 0x03, 0x03, 0x50, 0x00, 0x03, 0x03, 0xb0, 0x18, 0x04, 0x04, 0xc0, 0x18, 0x04, 0x04, 0xc0, 0x39, 0x05, 0x05, 0xa0, 0x14, 0x06, 0x05, 0x00, 0x36, 0x07, 0x06, + 0x80, 0x34, 0x09, 0x07, 0xe0, 0x10, 0x00, 0x03, 0xe8, 0x10, 0x00, 0x03, 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x10, 0x00, 0x03, 0x70, 0x03, 0x01, 0x02, 0x74, 0x03, 0x01, 0x02, 0x78, 0x03, 0x01, 0x02, + 0x7c, 0x03, 0x01, 0x02, 0x80, 0x03, 0x01, 0x02, 0x84, 0x03, 0x01, 0x02, 0x80, 0x1d, 0x02, 0x03, 0x88, 0x1d, 0x02, 0x03, 0x90, 0x1d, 0x02, 0x03, 0x98, 0x1d, 0x02, 0x03, 0xa0, 0x1d, 0x02, 0x03, + 0x58, 0x00, 0x03, 0x03, 0x60, 0x00, 0x03, 0x03, 0x68, 0x00, 0x03, 0x03, 0xd0, 0x18, 0x04, 0x04, 0xe0, 0x18, 0x04, 0x04, 0xe0, 0x39, 0x05, 0x05, 0xc0, 0x14, 0x06, 0x05, 0x40, 0x36, 0x07, 0x06, + 0x00, 0x35, 0x09, 0x07, 0x00, 0x11, 0x00, 0x03, 0x08, 0x11, 0x00, 0x03, 0x10, 0x11, 0x00, 0x03, 0x18, 0x11, 0x00, 0x03, 0x88, 0x03, 0x01, 0x02, 0x8c, 0x03, 0x01, 0x02, 0x90, 0x03, 0x01, 0x02, + 0x94, 0x03, 0x01, 0x02, 0x98, 0x03, 0x01, 0x02, 0x9c, 0x03, 0x01, 0x02, 0xa8, 0x1d, 0x02, 0x03, 0xb0, 0x1d, 0x02, 0x03, 0xb8, 0x1d, 0x02, 0x03, 0xc0, 0x1d, 0x02, 0x03, 0xc8, 0x1d, 0x02, 0x03, + 0x70, 0x00, 0x03, 0x03, 0x78, 0x00, 0x03, 0x03, 0x80, 0x00, 0x03, 0x03, 0xf0, 0x18, 0x04, 0x04, 0x00, 0x19, 0x04, 0x04, 0x00, 0x3a, 0x05, 0x05, 0xe0, 0x14, 0x06, 0x05, 0x80, 0x36, 0x07, 0x06, + 0x80, 0x35, 0x09, 0x07, 0x20, 0x11, 0x00, 0x03, 0x28, 0x11, 0x00, 0x03, 0x30, 0x11, 0x00, 0x03, 0x38, 0x11, 0x00, 0x03, 0xa0, 0x03, 0x01, 0x02, 0xa4, 0x03, 0x01, 0x02, 0xa8, 0x03, 0x01, 0x02, + 0xac, 0x03, 0x01, 0x02, 0xb0, 0x03, 0x01, 0x02, 0xb4, 0x03, 0x01, 0x02, 0xd0, 0x1d, 0x02, 0x03, 0xd8, 0x1d, 0x02, 0x03, 0xe0, 0x1d, 0x02, 0x03, 0xe8, 0x1d, 0x02, 0x03, 0xf0, 0x1d, 0x02, 0x03, + 0x88, 0x00, 0x03, 0x03, 0x90, 0x00, 0x03, 0x03, 0x98, 0x00, 0x03, 0x03, 0x10, 0x19, 0x04, 0x04, 0x20, 0x19, 0x04, 0x04, 0x20, 0x3a, 0x05, 0x05, 0x00, 0x15, 0x06, 0x05, 0xc0, 0x36, 0x07, 0x06, + 0x00, 0x36, 0x09, 0x07, 0x40, 0x11, 0x00, 0x03, 0x48, 0x11, 0x00, 0x03, 0x50, 0x11, 0x00, 0x03, 0x58, 0x11, 0x00, 0x03, 0xb8, 0x03, 0x01, 0x02, 0xbc, 0x03, 0x01, 0x02, 0xc0, 0x03, 0x01, 0x02, + 0xc4, 0x03, 0x01, 0x02, 0xc8, 0x03, 0x01, 0x02, 0xcc, 0x03, 0x01, 0x02, 0xf8, 0x1d, 0x02, 0x03, 0x00, 0x1e, 0x02, 0x03, 0x08, 0x1e, 0x02, 0x03, 0x10, 0x1e, 0x02, 0x03, 0x18, 0x1e, 0x02, 0x03, + 0xa0, 0x00, 0x03, 0x03, 0xa8, 0x00, 0x03, 0x03, 0xb0, 0x00, 0x03, 0x03, 0x30, 0x19, 0x04, 0x04, 0x40, 0x19, 0x04, 0x04, 0x40, 0x3a, 0x05, 0x05, 0x20, 0x15, 0x06, 0x05, 0x00, 0x37, 0x07, 0x06, + 0x80, 0x36, 0x09, 0x07, 0x60, 0x11, 0x00, 0x03, 0x68, 0x11, 0x00, 0x03, 0x70, 0x11, 0x00, 0x03, 0x78, 0x11, 0x00, 0x03, 0xd0, 0x03, 0x01, 0x02, 0xd4, 0x03, 0x01, 0x02, 0xd8, 0x03, 0x01, 0x02, + 0xdc, 0x03, 0x01, 0x02, 0xe0, 0x03, 0x01, 0x02, 0xe4, 0x03, 0x01, 0x02, 0x20, 0x1e, 0x02, 0x03, 0x28, 0x1e, 0x02, 0x03, 0x30, 0x1e, 0x02, 0x03, 0x38, 0x1e, 0x02, 0x03, 0x40, 0x1e, 0x02, 0x03, + 0xb8, 0x00, 0x03, 0x03, 0xc0, 0x00, 0x03, 0x03, 0xc8, 0x00, 0x03, 0x03, 0x50, 0x19, 0x04, 0x04, 0x60, 0x19, 0x04, 0x04, 0x60, 0x3a, 0x05, 0x05, 0x40, 0x15, 0x06, 0x05, 0x40, 0x37, 0x07, 0x06, + 0x00, 0x37, 0x09, 0x07, 0x80, 0x11, 0x00, 0x03, 0x88, 0x11, 0x00, 0x03, 0x90, 0x11, 0x00, 0x03, 0x98, 0x11, 0x00, 0x03, 0xe8, 0x03, 0x01, 0x02, 0xec, 0x03, 0x01, 0x02, 0xf0, 0x03, 0x01, 0x02, + 0xf4, 0x03, 0x01, 0x02, 0xf8, 0x03, 0x01, 0x02, 0xfc, 0x03, 0x01, 0x02, 0x48, 0x1e, 0x02, 0x03, 0x50, 0x1e, 0x02, 0x03, 0x58, 0x1e, 0x02, 0x03, 0x60, 0x1e, 0x02, 0x03, 0x68, 0x1e, 0x02, 0x03, + 0xd0, 0x00, 0x03, 0x03, 0xd8, 0x00, 0x03, 0x03, 0xe0, 0x00, 0x03, 0x03, 0x70, 0x19, 0x04, 0x04, 0x80, 0x19, 0x04, 0x04, 0x80, 0x3a, 0x05, 0x05, 0x60, 0x15, 0x06, 0x05, 0x80, 0x37, 0x07, 0x06, + 0x80, 0x37, 0x09, 0x07, 0xa0, 0x11, 0x00, 0x03, 0xa8, 0x11, 0x00, 0x03, 0xb0, 0x11, 0x00, 0x03, 0xb8, 0x11, 0x00, 0x03, 0x00, 0x04, 0x01, 0x02, 0x04, 0x04, 0x01, 0x02, 0x08, 0x04, 0x01, 0x02, + 0x0c, 0x04, 0x01, 0x02, 0x10, 0x04, 0x01, 0x02, 0x14, 0x04, 0x01, 0x02, 0x70, 0x1e, 0x02, 0x03, 0x78, 0x1e, 0x02, 0x03, 0x80, 0x1e, 0x02, 0x03, 0x88, 0x1e, 0x02, 0x03, 0x90, 0x1e, 0x02, 0x03, + 0xe8, 0x00, 0x03, 0x03, 0xf0, 0x00, 0x03, 0x03, 0xf8, 0x00, 0x03, 0x03, 0x90, 0x19, 0x04, 0x04, 0xa0, 0x19, 0x04, 0x04, 0xa0, 0x3a, 0x05, 0x05, 0x80, 0x15, 0x06, 0x05, 0xc0, 0x37, 0x07, 0x06, + 0x00, 0x38, 0x09, 0x07, 0xc0, 0x11, 0x00, 0x03, 0xc8, 0x11, 0x00, 0x03, 0xd0, 0x11, 0x00, 0x03, 0xd8, 0x11, 0x00, 0x03, 0x18, 0x04, 0x01, 0x02, 0x1c, 0x04, 0x01, 0x02, 0x20, 0x04, 0x01, 0x02, + 0x24, 0x04, 0x01, 0x02, 0x28, 0x04, 0x01, 0x02, 0x2c, 0x04, 0x01, 0x02, 0x98, 0x1e, 0x02, 0x03, 0xa0, 0x1e, 0x02, 0x03, 0xa8, 0x1e, 0x02, 0x03, 0xb0, 0x1e, 0x02, 0x03, 0xb8, 0x1e, 0x02, 0x03, + 0x00, 0x01, 0x03, 0x03, 0x08, 0x01, 0x03, 0x03, 0x10, 0x01, 0x03, 0x03, 0xb0, 0x19, 0x04, 0x04, 0xc0, 0x19, 0x04, 0x04, 0xc0, 0x3a, 0x05, 0x05, 0xa0, 0x15, 0x06, 0x05, 0x00, 0x38, 0x07, 0x06, + 0x80, 0x0b, 0x0a, 0x07, 0xe0, 0x11, 0x00, 0x03, 0xe8, 0x11, 0x00, 0x03, 0xf0, 0x11, 0x00, 0x03, 0xf8, 0x11, 0x00, 0x03, 0x30, 0x04, 0x01, 0x02, 0x34, 0x04, 0x01, 0x02, 0x38, 0x04, 0x01, 0x02, + 0x3c, 0x04, 0x01, 0x02, 0x40, 0x04, 0x01, 0x02, 0x44, 0x04, 0x01, 0x02, 0xc0, 0x1e, 0x02, 0x03, 0xc8, 0x1e, 0x02, 0x03, 0xd0, 0x1e, 0x02, 0x03, 0xd8, 0x1e, 0x02, 0x03, 0xe0, 0x1e, 0x02, 0x03, + 0x18, 0x01, 0x03, 0x03, 0x20, 0x01, 0x03, 0x03, 0x28, 0x01, 0x03, 0x03, 0xd0, 0x19, 0x04, 0x04, 0xe0, 0x19, 0x04, 0x04, 0xe0, 0x3a, 0x05, 0x05, 0xc0, 0x15, 0x06, 0x05, 0x40, 0x38, 0x07, 0x06, + 0x00, 0x0c, 0x0a, 0x07, 0x00, 0x12, 0x00, 0x03, 0x08, 0x12, 0x00, 0x03, 0x10, 0x12, 0x00, 0x03, 0x18, 0x12, 0x00, 0x03, 0x48, 0x04, 0x01, 0x02, 0x4c, 0x04, 0x01, 0x02, 0x50, 0x04, 0x01, 0x02, + 0x54, 0x04, 0x01, 0x02, 0x58, 0x04, 0x01, 0x02, 0x5c, 0x04, 0x01, 0x02, 0xe8, 0x1e, 0x02, 0x03, 0xf0, 0x1e, 0x02, 0x03, 0xf8, 0x1e, 0x02, 0x03, 0x00, 0x1f, 0x02, 0x03, 0x08, 0x1f, 0x02, 0x03, + 0x30, 0x01, 0x03, 0x03, 0x38, 0x01, 0x03, 0x03, 0x40, 0x01, 0x03, 0x03, 0xf0, 0x19, 0x04, 0x04, 0x00, 0x1a, 0x04, 0x04, 0x00, 0x3b, 0x05, 0x05, 0xe0, 0x15, 0x06, 0x05, 0x80, 0x38, 0x07, 0x06, + 0x80, 0x0c, 0x0a, 0x07, 0x20, 0x12, 0x00, 0x03, 0x28, 0x12, 0x00, 0x03, 0x30, 0x12, 0x00, 0x03, 0x38, 0x12, 0x00, 0x03, 0x60, 0x04, 0x01, 0x02, 0x64, 0x04, 0x01, 0x02, 0x68, 0x04, 0x01, 0x02, + 0x6c, 0x04, 0x01, 0x02, 0x70, 0x04, 0x01, 0x02, 0x74, 0x04, 0x01, 0x02, 0x10, 0x1f, 0x02, 0x03, 0x18, 0x1f, 0x02, 0x03, 0x20, 0x1f, 0x02, 0x03, 0x28, 0x1f, 0x02, 0x03, 0x30, 0x1f, 0x02, 0x03, + 0x48, 0x01, 0x03, 0x03, 0x50, 0x01, 0x03, 0x03, 0x58, 0x01, 0x03, 0x03, 0x10, 0x1a, 0x04, 0x04, 0x20, 0x1a, 0x04, 0x04, 0x20, 0x3b, 0x05, 0x05, 0x00, 0x16, 0x06, 0x05, 0xc0, 0x38, 0x07, 0x06, + 0x00, 0x0d, 0x0a, 0x07, 0x40, 0x12, 0x00, 0x03, 0x48, 0x12, 0x00, 0x03, 0x50, 0x12, 0x00, 0x03, 0x58, 0x12, 0x00, 0x03, 0x78, 0x04, 0x01, 0x02, 0x7c, 0x04, 0x01, 0x02, 0x80, 0x04, 0x01, 0x02, + 0x84, 0x04, 0x01, 0x02, 0x88, 0x04, 0x01, 0x02, 0x8c, 0x04, 0x01, 0x02, 0x38, 0x1f, 0x02, 0x03, 0x40, 0x1f, 0x02, 0x03, 0x48, 0x1f, 0x02, 0x03, 0x50, 0x1f, 0x02, 0x03, 0x58, 0x1f, 0x02, 0x03, + 0x60, 0x01, 0x03, 0x03, 0x68, 0x01, 0x03, 0x03, 0x70, 0x01, 0x03, 0x03, 0x30, 0x1a, 0x04, 0x04, 0x40, 0x1a, 0x04, 0x04, 0x40, 0x3b, 0x05, 0x05, 0x20, 0x16, 0x06, 0x05, 0x00, 0x39, 0x07, 0x06, + 0x80, 0x0d, 0x0a, 0x07, 0x60, 0x12, 0x00, 0x03, 0x68, 0x12, 0x00, 0x03, 0x70, 0x12, 0x00, 0x03, 0x78, 0x12, 0x00, 0x03, 0x90, 0x04, 0x01, 0x02, 0x94, 0x04, 0x01, 0x02, 0x98, 0x04, 0x01, 0x02, + 0x9c, 0x04, 0x01, 0x02, 0xa0, 0x04, 0x01, 0x02, 0xa4, 0x04, 0x01, 0x02, 0x60, 0x1f, 0x02, 0x03, 0x68, 0x1f, 0x02, 0x03, 0x70, 0x1f, 0x02, 0x03, 0x78, 0x1f, 0x02, 0x03, 0x80, 0x1f, 0x02, 0x03, + 0x78, 0x01, 0x03, 0x03, 0x80, 0x01, 0x03, 0x03, 0x50, 0x1a, 0x04, 0x04, 0x60, 0x1a, 0x04, 0x04, 0x70, 0x1a, 0x04, 0x04, 0x60, 0x3b, 0x05, 0x05, 0x40, 0x16, 0x06, 0x05, 0x40, 0x39, 0x07, 0x06, + 0x00, 0x0e, 0x0a, 0x07, 0x80, 0x12, 0x00, 0x03, 0x88, 0x12, 0x00, 0x03, 0x90, 0x12, 0x00, 0x03, 0x98, 0x12, 0x00, 0x03, 0xa8, 0x04, 0x01, 0x02, 0xac, 0x04, 0x01, 0x02, 0xb0, 0x04, 0x01, 0x02, + 0xb4, 0x04, 0x01, 0x02, 0xb8, 0x04, 0x01, 0x02, 0xbc, 0x04, 0x01, 0x02, 0x88, 0x1f, 0x02, 0x03, 0x90, 0x1f, 0x02, 0x03, 0x98, 0x1f, 0x02, 0x03, 0xa0, 0x1f, 0x02, 0x03, 0x88, 0x01, 0x03, 0x03, + 0x90, 0x01, 0x03, 0x03, 0x98, 0x01, 0x03, 0x03, 0x80, 0x1a, 0x04, 0x04, 0x90, 0x1a, 0x04, 0x04, 0xa0, 0x1a, 0x04, 0x04, 0x80, 0x3b, 0x05, 0x05, 0x60, 0x16, 0x06, 0x05, 0x80, 0x39, 0x07, 0x06, + 0x80, 0x0e, 0x0a, 0x07, 0xa0, 0x12, 0x00, 0x03, 0xa8, 0x12, 0x00, 0x03, 0xb0, 0x12, 0x00, 0x03, 0xb8, 0x12, 0x00, 0x03, 0xc0, 0x04, 0x01, 0x02, 0xc4, 0x04, 0x01, 0x02, 0xc8, 0x04, 0x01, 0x02, + 0xcc, 0x04, 0x01, 0x02, 0xd0, 0x04, 0x01, 0x02, 0xd4, 0x04, 0x01, 0x02, 0xa8, 0x1f, 0x02, 0x03, 0xb0, 0x1f, 0x02, 0x03, 0xb8, 0x1f, 0x02, 0x03, 0xc0, 0x1f, 0x02, 0x03, 0xa0, 0x01, 0x03, 0x03, + 0xa8, 0x01, 0x03, 0x03, 0xb0, 0x01, 0x03, 0x03, 0xb0, 0x1a, 0x04, 0x04, 0xc0, 0x1a, 0x04, 0x04, 0xd0, 0x1a, 0x04, 0x04, 0xa0, 0x3b, 0x05, 0x05, 0x80, 0x16, 0x06, 0x05, 0xc0, 0x39, 0x07, 0x06, + 0x00, 0x0f, 0x0a, 0x07, 0xc0, 0x12, 0x00, 0x03, 0xc8, 0x12, 0x00, 0x03, 0xd0, 0x12, 0x00, 0x03, 0xd8, 0x12, 0x00, 0x03, 0xd8, 0x04, 0x01, 0x02, 0xdc, 0x04, 0x01, 0x02, 0xe0, 0x04, 0x01, 0x02, + 0xe4, 0x04, 0x01, 0x02, 0xe8, 0x04, 0x01, 0x02, 0xec, 0x04, 0x01, 0x02, 0xc8, 0x1f, 0x02, 0x03, 0xd0, 0x1f, 0x02, 0x03, 0xd8, 0x1f, 0x02, 0x03, 0xe0, 0x1f, 0x02, 0x03, 0xb8, 0x01, 0x03, 0x03, + 0xc0, 0x01, 0x03, 0x03, 0xc8, 0x01, 0x03, 0x03, 0xe0, 0x1a, 0x04, 0x04, 0xf0, 0x1a, 0x04, 0x04, 0x00, 0x1b, 0x04, 0x04, 0xc0, 0x3b, 0x05, 0x05, 0xa0, 0x16, 0x06, 0x05, 0x00, 0x3a, 0x07, 0x06, + 0x80, 0x0f, 0x0a, 0x07, 0xe0, 0x12, 0x00, 0x03, 0xe8, 0x12, 0x00, 0x03, 0xf0, 0x12, 0x00, 0x03, 0xf8, 0x12, 0x00, 0x03, 0xf0, 0x04, 0x01, 0x02, 0xf4, 0x04, 0x01, 0x02, 0xf8, 0x04, 0x01, 0x02, + 0xfc, 0x04, 0x01, 0x02, 0x00, 0x05, 0x01, 0x02, 0x04, 0x05, 0x01, 0x02, 0xe8, 0x1f, 0x02, 0x03, 0xf0, 0x1f, 0x02, 0x03, 0xf8, 0x1f, 0x02, 0x03, 0x00, 0x20, 0x02, 0x03, 0xd0, 0x01, 0x03, 0x03, + 0xd8, 0x01, 0x03, 0x03, 0xe0, 0x01, 0x03, 0x03, 0x10, 0x1b, 0x04, 0x04, 0x20, 0x1b, 0x04, 0x04, 0x30, 0x1b, 0x04, 0x04, 0xe0, 0x3b, 0x05, 0x05, 0xc0, 0x16, 0x06, 0x05, 0x40, 0x3a, 0x07, 0x06, + 0x00, 0x10, 0x0a, 0x07, 0x00, 0x13, 0x00, 0x03, 0x08, 0x13, 0x00, 0x03, 0x10, 0x13, 0x00, 0x03, 0x18, 0x13, 0x00, 0x03, 0x08, 0x05, 0x01, 0x02, 0x0c, 0x05, 0x01, 0x02, 0x10, 0x05, 0x01, 0x02, + 0x14, 0x05, 0x01, 0x02, 0x18, 0x05, 0x01, 0x02, 0x1c, 0x05, 0x01, 0x02, 0x08, 0x20, 0x02, 0x03, 0x10, 0x20, 0x02, 0x03, 0x18, 0x20, 0x02, 0x03, 0x20, 0x20, 0x02, 0x03, 0xe8, 0x01, 0x03, 0x03, + 0xf0, 0x01, 0x03, 0x03, 0xf8, 0x01, 0x03, 0x03, 0x40, 0x1b, 0x04, 0x04, 0x50, 0x1b, 0x04, 0x04, 0x00, 0x3c, 0x05, 0x05, 0x20, 0x3c, 0x05, 0x05, 0xe0, 0x16, 0x06, 0x05, 0x80, 0x3a, 0x07, 0x06, + 0x80, 0x10, 0x0a, 0x07, 0x20, 0x13, 0x00, 0x03, 0x28, 0x13, 0x00, 0x03, 0x30, 0x13, 0x00, 0x03, 0x38, 0x13, 0x00, 0x03, 0x20, 0x05, 0x01, 0x02, 0x24, 0x05, 0x01, 0x02, 0x28, 0x05, 0x01, 0x02, + 0x2c, 0x05, 0x01, 0x02, 0x30, 0x05, 0x01, 0x02, 0x34, 0x05, 0x01, 0x02, 0x28, 0x20, 0x02, 0x03, 0x30, 0x20, 0x02, 0x03, 0x38, 0x20, 0x02, 0x03, 0x40, 0x20, 0x02, 0x03, 0x00, 0x02, 0x03, 0x03, + 0x08, 0x02, 0x03, 0x03, 0x10, 0x02, 0x03, 0x03, 0x60, 0x1b, 0x04, 0x04, 0x70, 0x1b, 0x04, 0x04, 0x40, 0x3c, 0x05, 0x05, 0x60, 0x3c, 0x05, 0x05, 0x00, 0x17, 0x06, 0x05, 0xc0, 0x3a, 0x07, 0x06, + 0x00, 0x11, 0x0a, 0x07, 0x40, 0x13, 0x00, 0x03, 0x48, 0x13, 0x00, 0x03, 0x50, 0x13, 0x00, 0x03, 0x58, 0x13, 0x00, 0x03, 0x38, 0x05, 0x01, 0x02, 0x3c, 0x05, 0x01, 0x02, 0x40, 0x05, 0x01, 0x02, + 0x44, 0x05, 0x01, 0x02, 0x48, 0x05, 0x01, 0x02, 0x4c, 0x05, 0x01, 0x02, 0x48, 0x20, 0x02, 0x03, 0x50, 0x20, 0x02, 0x03, 0x58, 0x20, 0x02, 0x03, 0x60, 0x20, 0x02, 0x03, 0x18, 0x02, 0x03, 0x03, + 0x20, 0x02, 0x03, 0x03, 0x28, 0x02, 0x03, 0x03, 0x80, 0x1b, 0x04, 0x04, 0x90, 0x1b, 0x04, 0x04, 0x80, 0x3c, 0x05, 0x05, 0xa0, 0x3c, 0x05, 0x05, 0x20, 0x17, 0x06, 0x05, 0x00, 0x3b, 0x07, 0x06, + 0x80, 0x11, 0x0a, 0x07, 0x60, 0x13, 0x00, 0x03, 0x68, 0x13, 0x00, 0x03, 0x70, 0x13, 0x00, 0x03, 0x78, 0x13, 0x00, 0x03, 0x50, 0x05, 0x01, 0x02, 0x54, 0x05, 0x01, 0x02, 0x58, 0x05, 0x01, 0x02, + 0x5c, 0x05, 0x01, 0x02, 0x60, 0x05, 0x01, 0x02, 0x64, 0x05, 0x01, 0x02, 0x68, 0x20, 0x02, 0x03, 0x70, 0x20, 0x02, 0x03, 0x78, 0x20, 0x02, 0x03, 0x80, 0x20, 0x02, 0x03, 0x30, 0x02, 0x03, 0x03, + 0x38, 0x02, 0x03, 0x03, 0x40, 0x02, 0x03, 0x03, 0xa0, 0x1b, 0x04, 0x04, 0xb0, 0x1b, 0x04, 0x04, 0xc0, 0x3c, 0x05, 0x05, 0xe0, 0x3c, 0x05, 0x05, 0x40, 0x17, 0x06, 0x05, 0x40, 0x3b, 0x07, 0x06, + 0x00, 0x12, 0x0a, 0x07, 0x80, 0x13, 0x00, 0x03, 0x88, 0x13, 0x00, 0x03, 0x90, 0x13, 0x00, 0x03, 0x98, 0x13, 0x00, 0x03, 0x68, 0x05, 0x01, 0x02, 0x6c, 0x05, 0x01, 0x02, 0x70, 0x05, 0x01, 0x02, + 0x74, 0x05, 0x01, 0x02, 0x78, 0x05, 0x01, 0x02, 0x7c, 0x05, 0x01, 0x02, 0x88, 0x20, 0x02, 0x03, 0x90, 0x20, 0x02, 0x03, 0x98, 0x20, 0x02, 0x03, 0xa0, 0x20, 0x02, 0x03, 0x48, 0x02, 0x03, 0x03, + 0x50, 0x02, 0x03, 0x03, 0x58, 0x02, 0x03, 0x03, 0xc0, 0x1b, 0x04, 0x04, 0xd0, 0x1b, 0x04, 0x04, 0x00, 0x3d, 0x05, 0x05, 0x20, 0x3d, 0x05, 0x05, 0x60, 0x17, 0x06, 0x05, 0x80, 0x3b, 0x07, 0x06, + 0x80, 0x12, 0x0a, 0x07, 0xa0, 0x13, 0x00, 0x03, 0xa8, 0x13, 0x00, 0x03, 0xb0, 0x13, 0x00, 0x03, 0xb8, 0x13, 0x00, 0x03, 0x80, 0x05, 0x01, 0x02, 0x84, 0x05, 0x01, 0x02, 0x88, 0x05, 0x01, 0x02, + 0x8c, 0x05, 0x01, 0x02, 0x90, 0x05, 0x01, 0x02, 0x94, 0x05, 0x01, 0x02, 0xa8, 0x20, 0x02, 0x03, 0xb0, 0x20, 0x02, 0x03, 0xb8, 0x20, 0x02, 0x03, 0xc0, 0x20, 0x02, 0x03, 0x60, 0x02, 0x03, 0x03, + 0x68, 0x02, 0x03, 0x03, 0x70, 0x02, 0x03, 0x03, 0xe0, 0x1b, 0x04, 0x04, 0xf0, 0x1b, 0x04, 0x04, 0x40, 0x3d, 0x05, 0x05, 0x60, 0x3d, 0x05, 0x05, 0x80, 0x17, 0x06, 0x05, 0xc0, 0x3b, 0x07, 0x06, + 0x00, 0x13, 0x0a, 0x07, 0xc0, 0x13, 0x00, 0x03, 0xc8, 0x13, 0x00, 0x03, 0xd0, 0x13, 0x00, 0x03, 0xd8, 0x13, 0x00, 0x03, 0x98, 0x05, 0x01, 0x02, 0x9c, 0x05, 0x01, 0x02, 0xa0, 0x05, 0x01, 0x02, + 0xa4, 0x05, 0x01, 0x02, 0xa8, 0x05, 0x01, 0x02, 0xac, 0x05, 0x01, 0x02, 0xc8, 0x20, 0x02, 0x03, 0xd0, 0x20, 0x02, 0x03, 0xd8, 0x20, 0x02, 0x03, 0xe0, 0x20, 0x02, 0x03, 0x78, 0x02, 0x03, 0x03, + 0x80, 0x02, 0x03, 0x03, 0x88, 0x02, 0x03, 0x03, 0x00, 0x1c, 0x04, 0x04, 0x10, 0x1c, 0x04, 0x04, 0x80, 0x3d, 0x05, 0x05, 0xa0, 0x3d, 0x05, 0x05, 0xa0, 0x17, 0x06, 0x05, 0x00, 0x3c, 0x07, 0x06, + 0x80, 0x13, 0x0a, 0x07, 0xe0, 0x13, 0x00, 0x03, 0xe8, 0x13, 0x00, 0x03, 0xf0, 0x13, 0x00, 0x03, 0xf8, 0x13, 0x00, 0x03, 0xb0, 0x05, 0x01, 0x02, 0xb4, 0x05, 0x01, 0x02, 0xb8, 0x05, 0x01, 0x02, + 0xbc, 0x05, 0x01, 0x02, 0xc0, 0x05, 0x01, 0x02, 0xc4, 0x05, 0x01, 0x02, 0xe8, 0x20, 0x02, 0x03, 0xf0, 0x20, 0x02, 0x03, 0xf8, 0x20, 0x02, 0x03, 0x00, 0x21, 0x02, 0x03, 0x90, 0x02, 0x03, 0x03, + 0x98, 0x02, 0x03, 0x03, 0xa0, 0x02, 0x03, 0x03, 0x20, 0x1c, 0x04, 0x04, 0x30, 0x1c, 0x04, 0x04, 0xc0, 0x3d, 0x05, 0x05, 0xe0, 0x3d, 0x05, 0x05, 0xc0, 0x17, 0x06, 0x05, 0x40, 0x3c, 0x07, 0x06, + 0x00, 0x14, 0x0a, 0x07, 0x00, 0x14, 0x00, 0x03, 0x08, 0x14, 0x00, 0x03, 0x10, 0x14, 0x00, 0x03, 0x18, 0x14, 0x00, 0x03, 0xc8, 0x05, 0x01, 0x02, 0xcc, 0x05, 0x01, 0x02, 0xd0, 0x05, 0x01, 0x02, + 0xd4, 0x05, 0x01, 0x02, 0xd8, 0x05, 0x01, 0x02, 0xdc, 0x05, 0x01, 0x02, 0x08, 0x21, 0x02, 0x03, 0x10, 0x21, 0x02, 0x03, 0x18, 0x21, 0x02, 0x03, 0x20, 0x21, 0x02, 0x03, 0xa8, 0x02, 0x03, 0x03, + 0xb0, 0x02, 0x03, 0x03, 0xb8, 0x02, 0x03, 0x03, 0x40, 0x1c, 0x04, 0x04, 0x50, 0x1c, 0x04, 0x04, 0x00, 0x3e, 0x05, 0x05, 0x20, 0x3e, 0x05, 0x05, 0xe0, 0x17, 0x06, 0x05, 0x00, 0x0f, 0x08, 0x06, + 0x80, 0x14, 0x0a, 0x07, 0x20, 0x14, 0x00, 0x03, 0x28, 0x14, 0x00, 0x03, 0x30, 0x14, 0x00, 0x03, 0x38, 0x14, 0x00, 0x03, 0xe0, 0x05, 0x01, 0x02, 0xe4, 0x05, 0x01, 0x02, 0xe8, 0x05, 0x01, 0x02, + 0xec, 0x05, 0x01, 0x02, 0xf0, 0x05, 0x01, 0x02, 0xf4, 0x05, 0x01, 0x02, 0x28, 0x21, 0x02, 0x03, 0x30, 0x21, 0x02, 0x03, 0x38, 0x21, 0x02, 0x03, 0x40, 0x21, 0x02, 0x03, 0xc0, 0x02, 0x03, 0x03, + 0xc8, 0x02, 0x03, 0x03, 0xd0, 0x02, 0x03, 0x03, 0x60, 0x1c, 0x04, 0x04, 0x70, 0x1c, 0x04, 0x04, 0x40, 0x3e, 0x05, 0x05, 0x60, 0x3e, 0x05, 0x05, 0x00, 0x18, 0x06, 0x05, 0x40, 0x0f, 0x08, 0x06, + 0x00, 0x28, 0x0b, 0x08, 0x40, 0x14, 0x00, 0x03, 0x48, 0x14, 0x00, 0x03, 0x50, 0x14, 0x00, 0x03, 0x58, 0x14, 0x00, 0x03, 0xf8, 0x05, 0x01, 0x02, 0xfc, 0x05, 0x01, 0x02, 0x00, 0x06, 0x01, 0x02, + 0x04, 0x06, 0x01, 0x02, 0x08, 0x06, 0x01, 0x02, 0x0c, 0x06, 0x01, 0x02, 0x48, 0x21, 0x02, 0x03, 0x50, 0x21, 0x02, 0x03, 0x58, 0x21, 0x02, 0x03, 0x60, 0x21, 0x02, 0x03, 0xd8, 0x02, 0x03, 0x03, + 0xe0, 0x02, 0x03, 0x03, 0xe8, 0x02, 0x03, 0x03, 0x80, 0x1c, 0x04, 0x04, 0x90, 0x1c, 0x04, 0x04, 0x80, 0x3e, 0x05, 0x05, 0xa0, 0x3e, 0x05, 0x05, 0x20, 0x18, 0x06, 0x05, 0x80, 0x0f, 0x08, 0x06, + 0x00, 0x29, 0x0b, 0x08, 0x60, 0x14, 0x00, 0x03, 0x68, 0x14, 0x00, 0x03, 0x70, 0x14, 0x00, 0x03, 0x78, 0x14, 0x00, 0x03, 0x10, 0x06, 0x01, 0x02, 0x14, 0x06, 0x01, 0x02, 0x18, 0x06, 0x01, 0x02, + 0x1c, 0x06, 0x01, 0x02, 0x20, 0x06, 0x01, 0x02, 0x24, 0x06, 0x01, 0x02, 0x68, 0x21, 0x02, 0x03, 0x70, 0x21, 0x02, 0x03, 0x78, 0x21, 0x02, 0x03, 0x80, 0x21, 0x02, 0x03, 0xf0, 0x02, 0x03, 0x03, + 0xf8, 0x02, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0xa0, 0x1c, 0x04, 0x04, 0xb0, 0x1c, 0x04, 0x04, 0xc0, 0x3e, 0x05, 0x05, 0xe0, 0x3e, 0x05, 0x05, 0x40, 0x18, 0x06, 0x05, 0xc0, 0x0f, 0x08, 0x06, + 0x00, 0x2a, 0x0b, 0x08, 0x80, 0x14, 0x00, 0x03, 0x88, 0x14, 0x00, 0x03, 0x90, 0x14, 0x00, 0x03, 0x98, 0x14, 0x00, 0x03, 0x28, 0x06, 0x01, 0x02, 0x2c, 0x06, 0x01, 0x02, 0x30, 0x06, 0x01, 0x02, + 0x34, 0x06, 0x01, 0x02, 0x38, 0x06, 0x01, 0x02, 0x3c, 0x06, 0x01, 0x02, 0x88, 0x21, 0x02, 0x03, 0x90, 0x21, 0x02, 0x03, 0x98, 0x21, 0x02, 0x03, 0xa0, 0x21, 0x02, 0x03, 0x08, 0x03, 0x03, 0x03, + 0x10, 0x03, 0x03, 0x03, 0x18, 0x03, 0x03, 0x03, 0xc0, 0x1c, 0x04, 0x04, 0xd0, 0x1c, 0x04, 0x04, 0x00, 0x3f, 0x05, 0x05, 0x20, 0x3f, 0x05, 0x05, 0x60, 0x18, 0x06, 0x05, 0x00, 0x10, 0x08, 0x06, + 0x00, 0x2b, 0x0b, 0x08, 0xa0, 0x14, 0x00, 0x03, 0xa8, 0x14, 0x00, 0x03, 0xb0, 0x14, 0x00, 0x03, 0xb8, 0x14, 0x00, 0x03, 0x40, 0x06, 0x01, 0x02, 0x44, 0x06, 0x01, 0x02, 0x48, 0x06, 0x01, 0x02, + 0x4c, 0x06, 0x01, 0x02, 0x50, 0x06, 0x01, 0x02, 0x54, 0x06, 0x01, 0x02, 0xa8, 0x21, 0x02, 0x03, 0xb0, 0x21, 0x02, 0x03, 0xb8, 0x21, 0x02, 0x03, 0xc0, 0x21, 0x02, 0x03, 0x20, 0x03, 0x03, 0x03, + 0x28, 0x03, 0x03, 0x03, 0x30, 0x03, 0x03, 0x03, 0xe0, 0x1c, 0x04, 0x04, 0xf0, 0x1c, 0x04, 0x04, 0x40, 0x3f, 0x05, 0x05, 0x60, 0x3f, 0x05, 0x05, 0x80, 0x18, 0x06, 0x05, 0x40, 0x10, 0x08, 0x06, + 0x00, 0x2c, 0x0b, 0x08, 0xc0, 0x14, 0x00, 0x03, 0xc8, 0x14, 0x00, 0x03, 0xd0, 0x14, 0x00, 0x03, 0xd8, 0x14, 0x00, 0x03, 0x58, 0x06, 0x01, 0x02, 0x5c, 0x06, 0x01, 0x02, 0x60, 0x06, 0x01, 0x02, + 0x64, 0x06, 0x01, 0x02, 0x68, 0x06, 0x01, 0x02, 0x6c, 0x06, 0x01, 0x02, 0xc8, 0x21, 0x02, 0x03, 0xd0, 0x21, 0x02, 0x03, 0xd8, 0x21, 0x02, 0x03, 0xe0, 0x21, 0x02, 0x03, 0x38, 0x03, 0x03, 0x03, + 0x40, 0x03, 0x03, 0x03, 0x48, 0x03, 0x03, 0x03, 0x00, 0x1d, 0x04, 0x04, 0x10, 0x1d, 0x04, 0x04, 0x80, 0x3f, 0x05, 0x05, 0xa0, 0x3f, 0x05, 0x05, 0xa0, 0x18, 0x06, 0x05, 0x80, 0x10, 0x08, 0x06, + 0x00, 0x2d, 0x0b, 0x08, 0xe0, 0x14, 0x00, 0x03, 0xe8, 0x14, 0x00, 0x03, 0xf0, 0x14, 0x00, 0x03, 0xf8, 0x14, 0x00, 0x03, 0x70, 0x06, 0x01, 0x02, 0x74, 0x06, 0x01, 0x02, 0x78, 0x06, 0x01, 0x02, + 0x7c, 0x06, 0x01, 0x02, 0x80, 0x06, 0x01, 0x02, 0x84, 0x06, 0x01, 0x02, 0xe8, 0x21, 0x02, 0x03, 0xf0, 0x21, 0x02, 0x03, 0xf8, 0x21, 0x02, 0x03, 0x00, 0x22, 0x02, 0x03, 0x50, 0x03, 0x03, 0x03, + 0x58, 0x03, 0x03, 0x03, 0x60, 0x03, 0x03, 0x03, 0x20, 0x1d, 0x04, 0x04, 0x30, 0x1d, 0x04, 0x04, 0xc0, 0x3f, 0x05, 0x05, 0xe0, 0x3f, 0x05, 0x05, 0xc0, 0x18, 0x06, 0x05, 0xc0, 0x10, 0x08, 0x06, + 0x00, 0x2e, 0x0b, 0x08, 0x00, 0x15, 0x00, 0x03, 0x08, 0x15, 0x00, 0x03, 0x10, 0x15, 0x00, 0x03, 0x18, 0x15, 0x00, 0x03, 0x88, 0x06, 0x01, 0x02, 0x8c, 0x06, 0x01, 0x02, 0x90, 0x06, 0x01, 0x02, + 0x94, 0x06, 0x01, 0x02, 0x98, 0x06, 0x01, 0x02, 0x9c, 0x06, 0x01, 0x02, 0x08, 0x22, 0x02, 0x03, 0x10, 0x22, 0x02, 0x03, 0x18, 0x22, 0x02, 0x03, 0x20, 0x22, 0x02, 0x03, 0x68, 0x03, 0x03, 0x03, + 0x70, 0x03, 0x03, 0x03, 0x78, 0x03, 0x03, 0x03, 0x40, 0x1d, 0x04, 0x04, 0x50, 0x1d, 0x04, 0x04, 0x00, 0x00, 0x05, 0x04, 0x10, 0x00, 0x05, 0x04, 0xe0, 0x18, 0x06, 0x05, 0x00, 0x11, 0x08, 0x06, + 0x00, 0x2f, 0x0b, 0x08, 0x20, 0x15, 0x00, 0x03, 0x28, 0x15, 0x00, 0x03, 0x30, 0x15, 0x00, 0x03, 0x38, 0x15, 0x00, 0x03, 0xa0, 0x06, 0x01, 0x02, 0xa4, 0x06, 0x01, 0x02, 0xa8, 0x06, 0x01, 0x02, + 0xac, 0x06, 0x01, 0x02, 0xb0, 0x06, 0x01, 0x02, 0xb4, 0x06, 0x01, 0x02, 0x28, 0x22, 0x02, 0x03, 0x30, 0x22, 0x02, 0x03, 0x38, 0x22, 0x02, 0x03, 0x40, 0x22, 0x02, 0x03, 0x80, 0x03, 0x03, 0x03, + 0x88, 0x03, 0x03, 0x03, 0x90, 0x03, 0x03, 0x03, 0x60, 0x1d, 0x04, 0x04, 0x70, 0x1d, 0x04, 0x04, 0x20, 0x00, 0x05, 0x04, 0x30, 0x00, 0x05, 0x04, 0x00, 0x19, 0x06, 0x05, 0x40, 0x11, 0x08, 0x06, + 0x00, 0x30, 0x0b, 0x08, 0x40, 0x15, 0x00, 0x03, 0x48, 0x15, 0x00, 0x03, 0x50, 0x15, 0x00, 0x03, 0x58, 0x15, 0x00, 0x03, 0xb8, 0x06, 0x01, 0x02, 0xbc, 0x06, 0x01, 0x02, 0xc0, 0x06, 0x01, 0x02, + 0xc4, 0x06, 0x01, 0x02, 0xc8, 0x06, 0x01, 0x02, 0xcc, 0x06, 0x01, 0x02, 0x48, 0x22, 0x02, 0x03, 0x50, 0x22, 0x02, 0x03, 0x58, 0x22, 0x02, 0x03, 0x60, 0x22, 0x02, 0x03, 0x98, 0x03, 0x03, 0x03, + 0xa0, 0x03, 0x03, 0x03, 0xa8, 0x03, 0x03, 0x03, 0x80, 0x1d, 0x04, 0x04, 0x90, 0x1d, 0x04, 0x04, 0x40, 0x00, 0x05, 0x04, 0x50, 0x00, 0x05, 0x04, 0x20, 0x19, 0x06, 0x05, 0x80, 0x11, 0x08, 0x06, + 0x00, 0x31, 0x0b, 0x08, 0x60, 0x15, 0x00, 0x03, 0x68, 0x15, 0x00, 0x03, 0x70, 0x15, 0x00, 0x03, 0x78, 0x15, 0x00, 0x03, 0xd0, 0x06, 0x01, 0x02, 0xd4, 0x06, 0x01, 0x02, 0xd8, 0x06, 0x01, 0x02, + 0xdc, 0x06, 0x01, 0x02, 0xe0, 0x06, 0x01, 0x02, 0xe4, 0x06, 0x01, 0x02, 0x68, 0x22, 0x02, 0x03, 0x70, 0x22, 0x02, 0x03, 0x78, 0x22, 0x02, 0x03, 0x80, 0x22, 0x02, 0x03, 0xb0, 0x03, 0x03, 0x03, + 0xb8, 0x03, 0x03, 0x03, 0xc0, 0x03, 0x03, 0x03, 0xa0, 0x1d, 0x04, 0x04, 0xb0, 0x1d, 0x04, 0x04, 0x60, 0x00, 0x05, 0x04, 0x70, 0x00, 0x05, 0x04, 0x40, 0x19, 0x06, 0x05, 0xc0, 0x11, 0x08, 0x06, + 0x00, 0x32, 0x0b, 0x08, 0x80, 0x15, 0x00, 0x03, 0x88, 0x15, 0x00, 0x03, 0x90, 0x15, 0x00, 0x03, 0x98, 0x15, 0x00, 0x03, 0xe8, 0x06, 0x01, 0x02, 0xec, 0x06, 0x01, 0x02, 0xf0, 0x06, 0x01, 0x02, + 0xf4, 0x06, 0x01, 0x02, 0xf8, 0x06, 0x01, 0x02, 0xfc, 0x06, 0x01, 0x02, 0x88, 0x22, 0x02, 0x03, 0x90, 0x22, 0x02, 0x03, 0x98, 0x22, 0x02, 0x03, 0xa0, 0x22, 0x02, 0x03, 0xc8, 0x03, 0x03, 0x03, + 0xd0, 0x03, 0x03, 0x03, 0xd8, 0x03, 0x03, 0x03, 0xc0, 0x1d, 0x04, 0x04, 0xd0, 0x1d, 0x04, 0x04, 0x80, 0x00, 0x05, 0x04, 0x90, 0x00, 0x05, 0x04, 0x60, 0x19, 0x06, 0x05, 0x00, 0x12, 0x08, 0x06, + 0x00, 0x33, 0x0b, 0x08, 0xa0, 0x15, 0x00, 0x03, 0xa8, 0x15, 0x00, 0x03, 0xb0, 0x15, 0x00, 0x03, 0xb8, 0x15, 0x00, 0x03, 0x00, 0x07, 0x01, 0x02, 0x04, 0x07, 0x01, 0x02, 0x08, 0x07, 0x01, 0x02, + 0x0c, 0x07, 0x01, 0x02, 0x10, 0x07, 0x01, 0x02, 0x14, 0x07, 0x01, 0x02, 0xa8, 0x22, 0x02, 0x03, 0xb0, 0x22, 0x02, 0x03, 0xb8, 0x22, 0x02, 0x03, 0xc0, 0x22, 0x02, 0x03, 0xe0, 0x03, 0x03, 0x03, + 0xe8, 0x03, 0x03, 0x03, 0xf0, 0x03, 0x03, 0x03, 0xe0, 0x1d, 0x04, 0x04, 0xf0, 0x1d, 0x04, 0x04, 0xa0, 0x00, 0x05, 0x04, 0xb0, 0x00, 0x05, 0x04, 0x80, 0x19, 0x06, 0x05, 0x40, 0x12, 0x08, 0x06, + 0x00, 0x34, 0x0b, 0x08, 0xc0, 0x15, 0x00, 0x03, 0xc8, 0x15, 0x00, 0x03, 0xd0, 0x15, 0x00, 0x03, 0xd8, 0x15, 0x00, 0x03, 0x18, 0x07, 0x01, 0x02, 0x1c, 0x07, 0x01, 0x02, 0x20, 0x07, 0x01, 0x02, + 0x24, 0x07, 0x01, 0x02, 0x28, 0x07, 0x01, 0x02, 0x2c, 0x07, 0x01, 0x02, 0xc8, 0x22, 0x02, 0x03, 0xd0, 0x22, 0x02, 0x03, 0xd8, 0x22, 0x02, 0x03, 0xe0, 0x22, 0x02, 0x03, 0xf8, 0x03, 0x03, 0x03, + 0x00, 0x04, 0x03, 0x03, 0x08, 0x04, 0x03, 0x03, 0x00, 0x1e, 0x04, 0x04, 0x10, 0x1e, 0x04, 0x04, 0xc0, 0x00, 0x05, 0x04, 0xd0, 0x00, 0x05, 0x04, 0xa0, 0x19, 0x06, 0x05, 0x80, 0x12, 0x08, 0x06, + 0x00, 0x08, 0x0c, 0x08, 0xe0, 0x15, 0x00, 0x03, 0xe8, 0x15, 0x00, 0x03, 0xf0, 0x15, 0x00, 0x03, 0xf8, 0x15, 0x00, 0x03, 0x30, 0x07, 0x01, 0x02, 0x34, 0x07, 0x01, 0x02, 0x38, 0x07, 0x01, 0x02, + 0x3c, 0x07, 0x01, 0x02, 0x40, 0x07, 0x01, 0x02, 0x44, 0x07, 0x01, 0x02, 0xe8, 0x22, 0x02, 0x03, 0xf0, 0x22, 0x02, 0x03, 0xf8, 0x22, 0x02, 0x03, 0x00, 0x23, 0x02, 0x03, 0x10, 0x04, 0x03, 0x03, + 0x18, 0x04, 0x03, 0x03, 0x20, 0x04, 0x03, 0x03, 0x20, 0x1e, 0x04, 0x04, 0x30, 0x1e, 0x04, 0x04, 0xe0, 0x00, 0x05, 0x04, 0xf0, 0x00, 0x05, 0x04, 0xc0, 0x19, 0x06, 0x05, 0xc0, 0x12, 0x08, 0x06, + 0x00, 0x09, 0x0c, 0x08, 0x00, 0x16, 0x00, 0x03, 0x08, 0x16, 0x00, 0x03, 0x10, 0x16, 0x00, 0x03, 0x18, 0x16, 0x00, 0x03, 0x48, 0x07, 0x01, 0x02, 0x4c, 0x07, 0x01, 0x02, 0x50, 0x07, 0x01, 0x02, + 0x54, 0x07, 0x01, 0x02, 0x58, 0x07, 0x01, 0x02, 0x5c, 0x07, 0x01, 0x02, 0x08, 0x23, 0x02, 0x03, 0x10, 0x23, 0x02, 0x03, 0x18, 0x23, 0x02, 0x03, 0x20, 0x23, 0x02, 0x03, 0x28, 0x04, 0x03, 0x03, + 0x30, 0x04, 0x03, 0x03, 0x38, 0x04, 0x03, 0x03, 0x40, 0x1e, 0x04, 0x04, 0x50, 0x1e, 0x04, 0x04, 0x00, 0x01, 0x05, 0x04, 0x10, 0x01, 0x05, 0x04, 0xe0, 0x19, 0x06, 0x05, 0x00, 0x13, 0x08, 0x06, + 0x00, 0x0a, 0x0c, 0x08, 0x20, 0x16, 0x00, 0x03, 0x28, 0x16, 0x00, 0x03, 0x30, 0x16, 0x00, 0x03, 0x38, 0x16, 0x00, 0x03, 0x60, 0x07, 0x01, 0x02, 0x64, 0x07, 0x01, 0x02, 0x68, 0x07, 0x01, 0x02, + 0x6c, 0x07, 0x01, 0x02, 0x70, 0x07, 0x01, 0x02, 0x74, 0x07, 0x01, 0x02, 0x28, 0x23, 0x02, 0x03, 0x30, 0x23, 0x02, 0x03, 0x38, 0x23, 0x02, 0x03, 0x40, 0x23, 0x02, 0x03, 0x40, 0x04, 0x03, 0x03, + 0x48, 0x04, 0x03, 0x03, 0x50, 0x04, 0x03, 0x03, 0x60, 0x1e, 0x04, 0x04, 0x70, 0x1e, 0x04, 0x04, 0x20, 0x01, 0x05, 0x04, 0x30, 0x01, 0x05, 0x04, 0x00, 0x1a, 0x06, 0x05, 0x40, 0x13, 0x08, 0x06, + 0x00, 0x0b, 0x0c, 0x08, 0x40, 0x16, 0x00, 0x03, 0x48, 0x16, 0x00, 0x03, 0x50, 0x16, 0x00, 0x03, 0x58, 0x16, 0x00, 0x03, 0x78, 0x07, 0x01, 0x02, 0x7c, 0x07, 0x01, 0x02, 0x80, 0x07, 0x01, 0x02, + 0x84, 0x07, 0x01, 0x02, 0x88, 0x07, 0x01, 0x02, 0x8c, 0x07, 0x01, 0x02, 0x48, 0x23, 0x02, 0x03, 0x50, 0x23, 0x02, 0x03, 0x58, 0x23, 0x02, 0x03, 0x60, 0x23, 0x02, 0x03, 0x58, 0x04, 0x03, 0x03, + 0x60, 0x04, 0x03, 0x03, 0x68, 0x04, 0x03, 0x03, 0x80, 0x1e, 0x04, 0x04, 0x90, 0x1e, 0x04, 0x04, 0x40, 0x01, 0x05, 0x04, 0x50, 0x01, 0x05, 0x04, 0x20, 0x1a, 0x06, 0x05, 0x80, 0x13, 0x08, 0x06, + 0x00, 0x0c, 0x0c, 0x08, 0x60, 0x16, 0x00, 0x03, 0x68, 0x16, 0x00, 0x03, 0x70, 0x16, 0x00, 0x03, 0x78, 0x16, 0x00, 0x03, 0x90, 0x07, 0x01, 0x02, 0x94, 0x07, 0x01, 0x02, 0x98, 0x07, 0x01, 0x02, + 0x9c, 0x07, 0x01, 0x02, 0xa0, 0x07, 0x01, 0x02, 0xa4, 0x07, 0x01, 0x02, 0x68, 0x23, 0x02, 0x03, 0x70, 0x23, 0x02, 0x03, 0x78, 0x23, 0x02, 0x03, 0x80, 0x23, 0x02, 0x03, 0x70, 0x04, 0x03, 0x03, + 0x78, 0x04, 0x03, 0x03, 0x80, 0x04, 0x03, 0x03, 0xa0, 0x1e, 0x04, 0x04, 0xb0, 0x1e, 0x04, 0x04, 0x60, 0x01, 0x05, 0x04, 0x70, 0x01, 0x05, 0x04, 0x40, 0x1a, 0x06, 0x05, 0xc0, 0x13, 0x08, 0x06, + 0x00, 0x0d, 0x0c, 0x08, 0x80, 0x16, 0x00, 0x03, 0x88, 0x16, 0x00, 0x03, 0x90, 0x16, 0x00, 0x03, 0x98, 0x16, 0x00, 0x03, 0xa8, 0x07, 0x01, 0x02, 0xac, 0x07, 0x01, 0x02, 0xb0, 0x07, 0x01, 0x02, + 0xb4, 0x07, 0x01, 0x02, 0xb8, 0x07, 0x01, 0x02, 0xbc, 0x07, 0x01, 0x02, 0x88, 0x23, 0x02, 0x03, 0x90, 0x23, 0x02, 0x03, 0x98, 0x23, 0x02, 0x03, 0xa0, 0x23, 0x02, 0x03, 0x88, 0x04, 0x03, 0x03, + 0x90, 0x04, 0x03, 0x03, 0x98, 0x04, 0x03, 0x03, 0xc0, 0x1e, 0x04, 0x04, 0xd0, 0x1e, 0x04, 0x04, 0x80, 0x01, 0x05, 0x04, 0x90, 0x01, 0x05, 0x04, 0x60, 0x1a, 0x06, 0x05, 0x00, 0x14, 0x08, 0x06, + 0x00, 0x0e, 0x0c, 0x08, 0xa0, 0x16, 0x00, 0x03, 0xa8, 0x16, 0x00, 0x03, 0xb0, 0x16, 0x00, 0x03, 0xb8, 0x16, 0x00, 0x03, 0xc0, 0x07, 0x01, 0x02, 0xc4, 0x07, 0x01, 0x02, 0xc8, 0x07, 0x01, 0x02, + 0xcc, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd4, 0x07, 0x01, 0x02, 0xa8, 0x23, 0x02, 0x03, 0xb0, 0x23, 0x02, 0x03, 0xb8, 0x23, 0x02, 0x03, 0xc0, 0x23, 0x02, 0x03, 0xa0, 0x04, 0x03, 0x03, + 0xa8, 0x04, 0x03, 0x03, 0xb0, 0x04, 0x03, 0x03, 0xe0, 0x1e, 0x04, 0x04, 0xf0, 0x1e, 0x04, 0x04, 0xa0, 0x01, 0x05, 0x04, 0xb0, 0x01, 0x05, 0x04, 0x80, 0x1a, 0x06, 0x05, 0x40, 0x14, 0x08, 0x06, + 0x00, 0x0f, 0x0c, 0x08, 0xc0, 0x16, 0x00, 0x03, 0xc8, 0x16, 0x00, 0x03, 0xd0, 0x16, 0x00, 0x03, 0xd8, 0x07, 0x01, 0x02, 0xdc, 0x07, 0x01, 0x02, 0xe0, 0x07, 0x01, 0x02, 0xe4, 0x07, 0x01, 0x02, + 0xe8, 0x07, 0x01, 0x02, 0xec, 0x07, 0x01, 0x02, 0xf0, 0x07, 0x01, 0x02, 0xc8, 0x23, 0x02, 0x03, 0xd0, 0x23, 0x02, 0x03, 0xd8, 0x23, 0x02, 0x03, 0xe0, 0x23, 0x02, 0x03, 0xb8, 0x04, 0x03, 0x03, + 0xc0, 0x04, 0x03, 0x03, 0xc8, 0x04, 0x03, 0x03, 0x00, 0x1f, 0x04, 0x04, 0x10, 0x1f, 0x04, 0x04, 0xc0, 0x01, 0x05, 0x04, 0xd0, 0x01, 0x05, 0x04, 0xa0, 0x1a, 0x06, 0x05, 0x80, 0x14, 0x08, 0x06, + 0x00, 0x10, 0x0c, 0x08, 0xd8, 0x16, 0x00, 0x03, 0xe0, 0x16, 0x00, 0x03, 0xe8, 0x16, 0x00, 0x03, 0xf4, 0x07, 0x01, 0x02, 0xf8, 0x07, 0x01, 0x02, 0xfc, 0x07, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, + 0x04, 0x08, 0x01, 0x02, 0x08, 0x08, 0x01, 0x02, 0x0c, 0x08, 0x01, 0x02, 0xe8, 0x23, 0x02, 0x03, 0xf0, 0x23, 0x02, 0x03, 0xf8, 0x23, 0x02, 0x03, 0x00, 0x24, 0x02, 0x03, 0xd0, 0x04, 0x03, 0x03, + 0xd8, 0x04, 0x03, 0x03, 0xe0, 0x04, 0x03, 0x03, 0x20, 0x1f, 0x04, 0x04, 0x30, 0x1f, 0x04, 0x04, 0xe0, 0x01, 0x05, 0x04, 0xf0, 0x01, 0x05, 0x04, 0xc0, 0x1a, 0x06, 0x05, 0xc0, 0x14, 0x08, 0x06, + 0x00, 0x24, 0x0d, 0x09, 0xf0, 0x16, 0x00, 0x03, 0xf8, 0x16, 0x00, 0x03, 0x00, 0x17, 0x00, 0x03, 0x10, 0x08, 0x01, 0x02, 0x14, 0x08, 0x01, 0x02, 0x18, 0x08, 0x01, 0x02, 0x1c, 0x08, 0x01, 0x02, + 0x20, 0x08, 0x01, 0x02, 0x24, 0x08, 0x01, 0x02, 0x28, 0x08, 0x01, 0x02, 0x08, 0x24, 0x02, 0x03, 0x10, 0x24, 0x02, 0x03, 0x18, 0x24, 0x02, 0x03, 0x20, 0x24, 0x02, 0x03, 0xe8, 0x04, 0x03, 0x03, + 0xf0, 0x04, 0x03, 0x03, 0xf8, 0x04, 0x03, 0x03, 0x40, 0x1f, 0x04, 0x04, 0x50, 0x1f, 0x04, 0x04, 0x00, 0x02, 0x05, 0x04, 0x10, 0x02, 0x05, 0x04, 0xe0, 0x1a, 0x06, 0x05, 0x00, 0x15, 0x08, 0x06, + 0x00, 0x26, 0x0d, 0x09, 0x08, 0x17, 0x00, 0x03, 0x10, 0x17, 0x00, 0x03, 0x18, 0x17, 0x00, 0x03, 0x2c, 0x08, 0x01, 0x02, 0x30, 0x08, 0x01, 0x02, 0x34, 0x08, 0x01, 0x02, 0x38, 0x08, 0x01, 0x02, + 0x3c, 0x08, 0x01, 0x02, 0x40, 0x08, 0x01, 0x02, 0x44, 0x08, 0x01, 0x02, 0x28, 0x24, 0x02, 0x03, 0x30, 0x24, 0x02, 0x03, 0x38, 0x24, 0x02, 0x03, 0x40, 0x24, 0x02, 0x03, 0x00, 0x05, 0x03, 0x03, + 0x08, 0x05, 0x03, 0x03, 0x10, 0x05, 0x03, 0x03, 0x60, 0x1f, 0x04, 0x04, 0x70, 0x1f, 0x04, 0x04, 0x20, 0x02, 0x05, 0x04, 0x30, 0x02, 0x05, 0x04, 0x00, 0x1b, 0x06, 0x05, 0x40, 0x15, 0x08, 0x06, + 0x00, 0x28, 0x0d, 0x09, 0x20, 0x17, 0x00, 0x03, 0x28, 0x17, 0x00, 0x03, 0x30, 0x17, 0x00, 0x03, 0x48, 0x08, 0x01, 0x02, 0x4c, 0x08, 0x01, 0x02, 0x50, 0x08, 0x01, 0x02, 0x54, 0x08, 0x01, 0x02, + 0x58, 0x08, 0x01, 0x02, 0x5c, 0x08, 0x01, 0x02, 0x60, 0x08, 0x01, 0x02, 0x48, 0x24, 0x02, 0x03, 0x50, 0x24, 0x02, 0x03, 0x58, 0x24, 0x02, 0x03, 0x60, 0x24, 0x02, 0x03, 0x18, 0x05, 0x03, 0x03, + 0x20, 0x05, 0x03, 0x03, 0x28, 0x05, 0x03, 0x03, 0x80, 0x1f, 0x04, 0x04, 0x90, 0x1f, 0x04, 0x04, 0x40, 0x02, 0x05, 0x04, 0x50, 0x02, 0x05, 0x04, 0x20, 0x1b, 0x06, 0x05, 0x80, 0x15, 0x08, 0x06, + 0x00, 0x2a, 0x0d, 0x09, 0x38, 0x17, 0x00, 0x03, 0x40, 0x17, 0x00, 0x03, 0x48, 0x17, 0x00, 0x03, 0x64, 0x08, 0x01, 0x02, 0x68, 0x08, 0x01, 0x02, 0x6c, 0x08, 0x01, 0x02, 0x70, 0x08, 0x01, 0x02, + 0x74, 0x08, 0x01, 0x02, 0x78, 0x08, 0x01, 0x02, 0x7c, 0x08, 0x01, 0x02, 0x68, 0x24, 0x02, 0x03, 0x70, 0x24, 0x02, 0x03, 0x78, 0x24, 0x02, 0x03, 0x80, 0x24, 0x02, 0x03, 0x30, 0x05, 0x03, 0x03, + 0x38, 0x05, 0x03, 0x03, 0x40, 0x05, 0x03, 0x03, 0xa0, 0x1f, 0x04, 0x04, 0xb0, 0x1f, 0x04, 0x04, 0x60, 0x02, 0x05, 0x04, 0x70, 0x02, 0x05, 0x04, 0x80, 0x3c, 0x07, 0x06, 0xc0, 0x15, 0x08, 0x06, + 0x00, 0x2c, 0x0d, 0x09, 0x50, 0x17, 0x00, 0x03, 0x58, 0x17, 0x00, 0x03, 0x60, 0x17, 0x00, 0x03, 0x80, 0x08, 0x01, 0x02, 0x84, 0x08, 0x01, 0x02, 0x88, 0x08, 0x01, 0x02, 0x8c, 0x08, 0x01, 0x02, + 0x90, 0x08, 0x01, 0x02, 0x94, 0x08, 0x01, 0x02, 0x98, 0x08, 0x01, 0x02, 0x88, 0x24, 0x02, 0x03, 0x90, 0x24, 0x02, 0x03, 0x98, 0x24, 0x02, 0x03, 0xa0, 0x24, 0x02, 0x03, 0x48, 0x05, 0x03, 0x03, + 0x50, 0x05, 0x03, 0x03, 0x58, 0x05, 0x03, 0x03, 0xc0, 0x1f, 0x04, 0x04, 0xd0, 0x1f, 0x04, 0x04, 0x80, 0x02, 0x05, 0x04, 0x40, 0x1b, 0x06, 0x05, 0xc0, 0x3c, 0x07, 0x06, 0x00, 0x16, 0x08, 0x06, + 0x00, 0x2e, 0x0d, 0x09, 0x68, 0x17, 0x00, 0x03, 0x70, 0x17, 0x00, 0x03, 0x78, 0x17, 0x00, 0x03, 0x9c, 0x08, 0x01, 0x02, 0xa0, 0x08, 0x01, 0x02, 0xa4, 0x08, 0x01, 0x02, 0xa8, 0x08, 0x01, 0x02, + 0xac, 0x08, 0x01, 0x02, 0xb0, 0x08, 0x01, 0x02, 0xb4, 0x08, 0x01, 0x02, 0xa8, 0x24, 0x02, 0x03, 0xb0, 0x24, 0x02, 0x03, 0xb8, 0x24, 0x02, 0x03, 0xc0, 0x24, 0x02, 0x03, 0x60, 0x05, 0x03, 0x03, + 0x68, 0x05, 0x03, 0x03, 0x70, 0x05, 0x03, 0x03, 0xe0, 0x1f, 0x04, 0x04, 0xf0, 0x1f, 0x04, 0x04, 0x90, 0x02, 0x05, 0x04, 0x60, 0x1b, 0x06, 0x05, 0x00, 0x3d, 0x07, 0x06, 0x40, 0x16, 0x08, 0x06, + 0x00, 0x04, 0x0e, 0x09, 0x80, 0x17, 0x00, 0x03, 0x88, 0x17, 0x00, 0x03, 0x90, 0x17, 0x00, 0x03, 0xb8, 0x08, 0x01, 0x02, 0xbc, 0x08, 0x01, 0x02, 0xc0, 0x08, 0x01, 0x02, 0xc4, 0x08, 0x01, 0x02, + 0xc8, 0x08, 0x01, 0x02, 0xcc, 0x08, 0x01, 0x02, 0xd0, 0x08, 0x01, 0x02, 0xc8, 0x24, 0x02, 0x03, 0xd0, 0x24, 0x02, 0x03, 0xd8, 0x24, 0x02, 0x03, 0xe0, 0x24, 0x02, 0x03, 0x78, 0x05, 0x03, 0x03, + 0x80, 0x05, 0x03, 0x03, 0x88, 0x05, 0x03, 0x03, 0x00, 0x20, 0x04, 0x04, 0x10, 0x20, 0x04, 0x04, 0xa0, 0x02, 0x05, 0x04, 0x80, 0x1b, 0x06, 0x05, 0x40, 0x3d, 0x07, 0x06, 0x80, 0x16, 0x08, 0x06, + 0x00, 0x06, 0x0e, 0x09, 0x98, 0x17, 0x00, 0x03, 0xa0, 0x17, 0x00, 0x03, 0xa8, 0x17, 0x00, 0x03, 0xd4, 0x08, 0x01, 0x02, 0xd8, 0x08, 0x01, 0x02, 0xdc, 0x08, 0x01, 0x02, 0xe0, 0x08, 0x01, 0x02, + 0xe4, 0x08, 0x01, 0x02, 0xe8, 0x08, 0x01, 0x02, 0xec, 0x08, 0x01, 0x02, 0xe8, 0x24, 0x02, 0x03, 0xf0, 0x24, 0x02, 0x03, 0xf8, 0x24, 0x02, 0x03, 0x00, 0x25, 0x02, 0x03, 0x90, 0x05, 0x03, 0x03, + 0x98, 0x05, 0x03, 0x03, 0xa0, 0x05, 0x03, 0x03, 0x20, 0x20, 0x04, 0x04, 0x30, 0x20, 0x04, 0x04, 0xb0, 0x02, 0x05, 0x04, 0xa0, 0x1b, 0x06, 0x05, 0x80, 0x3d, 0x07, 0x06, 0xc0, 0x16, 0x08, 0x06, + 0x00, 0x08, 0x0e, 0x09, 0xb0, 0x17, 0x00, 0x03, 0xb8, 0x17, 0x00, 0x03, 0xc0, 0x17, 0x00, 0x03, 0xf0, 0x08, 0x01, 0x02, 0xf4, 0x08, 0x01, 0x02, 0xf8, 0x08, 0x01, 0x02, 0xfc, 0x08, 0x01, 0x02, + 0x00, 0x09, 0x01, 0x02, 0x04, 0x09, 0x01, 0x02, 0x08, 0x09, 0x01, 0x02, 0x08, 0x25, 0x02, 0x03, 0x10, 0x25, 0x02, 0x03, 0x18, 0x25, 0x02, 0x03, 0x20, 0x25, 0x02, 0x03, 0xa8, 0x05, 0x03, 0x03, + 0xb0, 0x05, 0x03, 0x03, 0xb8, 0x05, 0x03, 0x03, 0x40, 0x20, 0x04, 0x04, 0x50, 0x20, 0x04, 0x04, 0xc0, 0x02, 0x05, 0x04, 0xc0, 0x1b, 0x06, 0x05, 0xc0, 0x3d, 0x07, 0x06, 0x00, 0x17, 0x08, 0x06, + 0x00, 0x0a, 0x0e, 0x09, 0xc8, 0x17, 0x00, 0x03, 0xd0, 0x17, 0x00, 0x03, 0xd8, 0x17, 0x00, 0x03, 0x0c, 0x09, 0x01, 0x02, 0x10, 0x09, 0x01, 0x02, 0x14, 0x09, 0x01, 0x02, 0x18, 0x09, 0x01, 0x02, + 0x1c, 0x09, 0x01, 0x02, 0x20, 0x09, 0x01, 0x02, 0x24, 0x09, 0x01, 0x02, 0x28, 0x25, 0x02, 0x03, 0x30, 0x25, 0x02, 0x03, 0x38, 0x25, 0x02, 0x03, 0x40, 0x25, 0x02, 0x03, 0xc0, 0x05, 0x03, 0x03, + 0xc8, 0x05, 0x03, 0x03, 0xd0, 0x05, 0x03, 0x03, 0x60, 0x20, 0x04, 0x04, 0x70, 0x20, 0x04, 0x04, 0xd0, 0x02, 0x05, 0x04, 0xe0, 0x1b, 0x06, 0x05, 0x00, 0x3e, 0x07, 0x06, 0x40, 0x17, 0x08, 0x06, + 0x00, 0x0c, 0x0e, 0x09, 0xe0, 0x17, 0x00, 0x03, 0xe8, 0x17, 0x00, 0x03, 0xf0, 0x17, 0x00, 0x03, 0x28, 0x09, 0x01, 0x02, 0x2c, 0x09, 0x01, 0x02, 0x30, 0x09, 0x01, 0x02, 0x34, 0x09, 0x01, 0x02, + 0x38, 0x09, 0x01, 0x02, 0x3c, 0x09, 0x01, 0x02, 0x40, 0x09, 0x01, 0x02, 0x48, 0x25, 0x02, 0x03, 0x50, 0x25, 0x02, 0x03, 0x58, 0x25, 0x02, 0x03, 0x60, 0x25, 0x02, 0x03, 0xd8, 0x05, 0x03, 0x03, + 0xe0, 0x05, 0x03, 0x03, 0xe8, 0x05, 0x03, 0x03, 0x80, 0x20, 0x04, 0x04, 0x90, 0x20, 0x04, 0x04, 0xe0, 0x02, 0x05, 0x04, 0x00, 0x1c, 0x06, 0x05, 0x40, 0x3e, 0x07, 0x06, 0x80, 0x17, 0x08, 0x06, + 0x00, 0x20, 0x0f, 0x0a, 0xf8, 0x17, 0x00, 0x03, 0x00, 0x18, 0x00, 0x03, 0x08, 0x18, 0x00, 0x03, 0x44, 0x09, 0x01, 0x02, 0x48, 0x09, 0x01, 0x02, 0x4c, 0x09, 0x01, 0x02, 0x50, 0x09, 0x01, 0x02, + 0x54, 0x09, 0x01, 0x02, 0x58, 0x09, 0x01, 0x02, 0x5c, 0x09, 0x01, 0x02, 0x68, 0x25, 0x02, 0x03, 0x70, 0x25, 0x02, 0x03, 0x78, 0x25, 0x02, 0x03, 0x80, 0x25, 0x02, 0x03, 0xf0, 0x05, 0x03, 0x03, + 0xf8, 0x05, 0x03, 0x03, 0x00, 0x06, 0x03, 0x03, 0xa0, 0x20, 0x04, 0x04, 0xb0, 0x20, 0x04, 0x04, 0xf0, 0x02, 0x05, 0x04, 0x20, 0x1c, 0x06, 0x05, 0x80, 0x3e, 0x07, 0x06, 0xc0, 0x17, 0x08, 0x06, + 0x00, 0x24, 0x0f, 0x0a, 0x10, 0x18, 0x00, 0x03, 0x18, 0x18, 0x00, 0x03, 0x20, 0x18, 0x00, 0x03, 0x60, 0x09, 0x01, 0x02, 0x64, 0x09, 0x01, 0x02, 0x68, 0x09, 0x01, 0x02, 0x6c, 0x09, 0x01, 0x02, + 0x70, 0x09, 0x01, 0x02, 0x74, 0x09, 0x01, 0x02, 0x78, 0x09, 0x01, 0x02, 0x88, 0x25, 0x02, 0x03, 0x90, 0x25, 0x02, 0x03, 0x98, 0x25, 0x02, 0x03, 0xa0, 0x25, 0x02, 0x03, 0x08, 0x06, 0x03, 0x03, + 0x10, 0x06, 0x03, 0x03, 0x18, 0x06, 0x03, 0x03, 0xc0, 0x20, 0x04, 0x04, 0xd0, 0x20, 0x04, 0x04, 0x00, 0x03, 0x05, 0x04, 0x40, 0x1c, 0x06, 0x05, 0xc0, 0x3e, 0x07, 0x06, 0x00, 0x18, 0x08, 0x06, + 0x00, 0x28, 0x0f, 0x0a, 0x28, 0x18, 0x00, 0x03, 0x30, 0x18, 0x00, 0x03, 0x38, 0x18, 0x00, 0x03, 0x7c, 0x09, 0x01, 0x02, 0x80, 0x09, 0x01, 0x02, 0x84, 0x09, 0x01, 0x02, 0x88, 0x09, 0x01, 0x02, + 0x8c, 0x09, 0x01, 0x02, 0x90, 0x09, 0x01, 0x02, 0x94, 0x09, 0x01, 0x02, 0xa8, 0x25, 0x02, 0x03, 0xb0, 0x25, 0x02, 0x03, 0xb8, 0x25, 0x02, 0x03, 0xc0, 0x25, 0x02, 0x03, 0x20, 0x06, 0x03, 0x03, + 0x28, 0x06, 0x03, 0x03, 0x30, 0x06, 0x03, 0x03, 0xe0, 0x20, 0x04, 0x04, 0xf0, 0x20, 0x04, 0x04, 0x10, 0x03, 0x05, 0x04, 0x60, 0x1c, 0x06, 0x05, 0x00, 0x3f, 0x07, 0x06, 0x40, 0x18, 0x08, 0x06, + 0x00, 0x00, 0x10, 0x0a, 0x40, 0x18, 0x00, 0x03, 0x48, 0x18, 0x00, 0x03, 0x50, 0x18, 0x00, 0x03, 0x98, 0x09, 0x01, 0x02, 0x9c, 0x09, 0x01, 0x02, 0xa0, 0x09, 0x01, 0x02, 0xa4, 0x09, 0x01, 0x02, + 0xa8, 0x09, 0x01, 0x02, 0xac, 0x09, 0x01, 0x02, 0xb0, 0x09, 0x01, 0x02, 0xc8, 0x25, 0x02, 0x03, 0xd0, 0x25, 0x02, 0x03, 0xd8, 0x25, 0x02, 0x03, 0xe0, 0x25, 0x02, 0x03, 0x38, 0x06, 0x03, 0x03, + 0x40, 0x06, 0x03, 0x03, 0x48, 0x06, 0x03, 0x03, 0x00, 0x21, 0x04, 0x04, 0x10, 0x21, 0x04, 0x04, 0x20, 0x03, 0x05, 0x04, 0x80, 0x1c, 0x06, 0x05, 0x40, 0x3f, 0x07, 0x06, 0x80, 0x18, 0x08, 0x06, + 0x00, 0x04, 0x10, 0x0a, 0x58, 0x18, 0x00, 0x03, 0x60, 0x18, 0x00, 0x03, 0x68, 0x18, 0x00, 0x03, 0xb4, 0x09, 0x01, 0x02, 0xb8, 0x09, 0x01, 0x02, 0xbc, 0x09, 0x01, 0x02, 0xc0, 0x09, 0x01, 0x02, + 0xc4, 0x09, 0x01, 0x02, 0xc8, 0x09, 0x01, 0x02, 0xcc, 0x09, 0x01, 0x02, 0xe8, 0x25, 0x02, 0x03, 0xf0, 0x25, 0x02, 0x03, 0xf8, 0x25, 0x02, 0x03, 0x00, 0x26, 0x02, 0x03, 0x50, 0x06, 0x03, 0x03, + 0x58, 0x06, 0x03, 0x03, 0x60, 0x06, 0x03, 0x03, 0x20, 0x21, 0x04, 0x04, 0x30, 0x21, 0x04, 0x04, 0x30, 0x03, 0x05, 0x04, 0xa0, 0x1c, 0x06, 0x05, 0x80, 0x3f, 0x07, 0x06, 0xc0, 0x18, 0x08, 0x06, + 0x00, 0x18, 0x11, 0x0b, 0x70, 0x18, 0x00, 0x03, 0x78, 0x18, 0x00, 0x03, 0x80, 0x18, 0x00, 0x03, 0xd0, 0x09, 0x01, 0x02, 0xd4, 0x09, 0x01, 0x02, 0xd8, 0x09, 0x01, 0x02, 0xdc, 0x09, 0x01, 0x02, + 0xe0, 0x09, 0x01, 0x02, 0xe4, 0x09, 0x01, 0x02, 0xe8, 0x09, 0x01, 0x02, 0x08, 0x26, 0x02, 0x03, 0x10, 0x26, 0x02, 0x03, 0x18, 0x26, 0x02, 0x03, 0x20, 0x26, 0x02, 0x03, 0x68, 0x06, 0x03, 0x03, + 0x70, 0x06, 0x03, 0x03, 0x78, 0x06, 0x03, 0x03, 0x40, 0x21, 0x04, 0x04, 0x50, 0x21, 0x04, 0x04, 0x40, 0x03, 0x05, 0x04, 0xc0, 0x1c, 0x06, 0x05, 0xc0, 0x3f, 0x07, 0x06, 0x80, 0x38, 0x09, 0x07, + 0x00, 0x20, 0x11, 0x0b, 0x88, 0x18, 0x00, 0x03, 0x90, 0x18, 0x00, 0x03, 0x98, 0x18, 0x00, 0x03, 0xec, 0x09, 0x01, 0x02, 0xf0, 0x09, 0x01, 0x02, 0xf4, 0x09, 0x01, 0x02, 0xf8, 0x09, 0x01, 0x02, + 0xfc, 0x09, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0x04, 0x0a, 0x01, 0x02, 0x28, 0x26, 0x02, 0x03, 0x30, 0x26, 0x02, 0x03, 0x38, 0x26, 0x02, 0x03, 0x40, 0x26, 0x02, 0x03, 0x80, 0x06, 0x03, 0x03, + 0x88, 0x06, 0x03, 0x03, 0x90, 0x06, 0x03, 0x03, 0x60, 0x21, 0x04, 0x04, 0x70, 0x21, 0x04, 0x04, 0x50, 0x03, 0x05, 0x04, 0xe0, 0x1c, 0x06, 0x05, 0x00, 0x00, 0x07, 0x05, 0x00, 0x39, 0x09, 0x07, + 0x00, 0x00, 0x12, 0x0b, 0xa0, 0x18, 0x00, 0x03, 0xa8, 0x18, 0x00, 0x03, 0xb0, 0x18, 0x00, 0x03, 0x08, 0x0a, 0x01, 0x02, 0x0c, 0x0a, 0x01, 0x02, 0x10, 0x0a, 0x01, 0x02, 0x14, 0x0a, 0x01, 0x02, + 0x18, 0x0a, 0x01, 0x02, 0x1c, 0x0a, 0x01, 0x02, 0x20, 0x0a, 0x01, 0x02, 0x48, 0x26, 0x02, 0x03, 0x50, 0x26, 0x02, 0x03, 0x58, 0x26, 0x02, 0x03, 0x60, 0x26, 0x02, 0x03, 0x98, 0x06, 0x03, 0x03, + 0xa0, 0x06, 0x03, 0x03, 0xa8, 0x06, 0x03, 0x03, 0x80, 0x21, 0x04, 0x04, 0x90, 0x21, 0x04, 0x04, 0x60, 0x03, 0x05, 0x04, 0x00, 0x1d, 0x06, 0x05, 0x20, 0x00, 0x07, 0x05, 0x80, 0x39, 0x09, 0x07, + 0x00, 0x10, 0x13, 0x0c, 0xb8, 0x18, 0x00, 0x03, 0xc0, 0x18, 0x00, 0x03, 0xc8, 0x18, 0x00, 0x03, 0x24, 0x0a, 0x01, 0x02, 0x28, 0x0a, 0x01, 0x02, 0x2c, 0x0a, 0x01, 0x02, 0x30, 0x0a, 0x01, 0x02, + 0x34, 0x0a, 0x01, 0x02, 0x38, 0x0a, 0x01, 0x02, 0x3c, 0x0a, 0x01, 0x02, 0x68, 0x26, 0x02, 0x03, 0x70, 0x26, 0x02, 0x03, 0x78, 0x26, 0x02, 0x03, 0x80, 0x26, 0x02, 0x03, 0xb0, 0x06, 0x03, 0x03, + 0xb8, 0x06, 0x03, 0x03, 0xc0, 0x06, 0x03, 0x03, 0xa0, 0x21, 0x04, 0x04, 0xb0, 0x21, 0x04, 0x04, 0x70, 0x03, 0x05, 0x04, 0x20, 0x1d, 0x06, 0x05, 0x40, 0x00, 0x07, 0x05, 0x00, 0x3a, 0x09, 0x07, + 0x00, 0x20, 0x15, 0x0d, 0xd0, 0x18, 0x00, 0x03, 0xd8, 0x18, 0x00, 0x03, 0xe0, 0x18, 0x00, 0x03, 0x40, 0x0a, 0x01, 0x02, 0x44, 0x0a, 0x01, 0x02, 0x48, 0x0a, 0x01, 0x02, 0x4c, 0x0a, 0x01, 0x02, + 0x50, 0x0a, 0x01, 0x02, 0x54, 0x0a, 0x01, 0x02, 0x58, 0x0a, 0x01, 0x02, 0x88, 0x26, 0x02, 0x03, 0x90, 0x26, 0x02, 0x03, 0x98, 0x26, 0x02, 0x03, 0xa0, 0x26, 0x02, 0x03, 0xc8, 0x06, 0x03, 0x03, + 0xd0, 0x06, 0x03, 0x03, 0xd8, 0x06, 0x03, 0x03, 0xc0, 0x21, 0x04, 0x04, 0xd0, 0x21, 0x04, 0x04, 0x80, 0x03, 0x05, 0x04, 0x40, 0x1d, 0x06, 0x05, 0x60, 0x00, 0x07, 0x05, 0x80, 0x3a, 0x09, 0x07, + 0xe8, 0x18, 0x00, 0x03, 0xf0, 0x18, 0x00, 0x03, 0xf8, 0x18, 0x00, 0x03, 0x00, 0x19, 0x00, 0x03, 0x5c, 0x0a, 0x01, 0x02, 0x60, 0x0a, 0x01, 0x02, 0x64, 0x0a, 0x01, 0x02, 0x68, 0x0a, 0x01, 0x02, + 0x6c, 0x0a, 0x01, 0x02, 0x70, 0x0a, 0x01, 0x02, 0x74, 0x0a, 0x01, 0x02, 0xa8, 0x26, 0x02, 0x03, 0xb0, 0x26, 0x02, 0x03, 0xb8, 0x26, 0x02, 0x03, 0xc0, 0x26, 0x02, 0x03, 0xe0, 0x06, 0x03, 0x03, + 0xe8, 0x06, 0x03, 0x03, 0xf0, 0x06, 0x03, 0x03, 0xe0, 0x21, 0x04, 0x04, 0xf0, 0x21, 0x04, 0x04, 0x90, 0x03, 0x05, 0x04, 0x60, 0x1d, 0x06, 0x05, 0x80, 0x00, 0x07, 0x05, 0x00, 0x3b, 0x09, 0x07, + 0x08, 0x19, 0x00, 0x03, 0x10, 0x19, 0x00, 0x03, 0x18, 0x19, 0x00, 0x03, 0x20, 0x19, 0x00, 0x03, 0x78, 0x0a, 0x01, 0x02, 0x7c, 0x0a, 0x01, 0x02, 0x80, 0x0a, 0x01, 0x02, 0x84, 0x0a, 0x01, 0x02, + 0x88, 0x0a, 0x01, 0x02, 0x8c, 0x0a, 0x01, 0x02, 0xc8, 0x26, 0x02, 0x03, 0xd0, 0x26, 0x02, 0x03, 0xd8, 0x26, 0x02, 0x03, 0xe0, 0x26, 0x02, 0x03, 0xe8, 0x26, 0x02, 0x03, 0xf8, 0x06, 0x03, 0x03, + 0x00, 0x07, 0x03, 0x03, 0x08, 0x07, 0x03, 0x03, 0x00, 0x22, 0x04, 0x04, 0x10, 0x22, 0x04, 0x04, 0xa0, 0x03, 0x05, 0x04, 0x80, 0x1d, 0x06, 0x05, 0xa0, 0x00, 0x07, 0x05, 0x80, 0x3b, 0x09, 0x07, + 0x28, 0x19, 0x00, 0x03, 0x30, 0x19, 0x00, 0x03, 0x38, 0x19, 0x00, 0x03, 0x40, 0x19, 0x00, 0x03, 0x90, 0x0a, 0x01, 0x02, 0x94, 0x0a, 0x01, 0x02, 0x98, 0x0a, 0x01, 0x02, 0x9c, 0x0a, 0x01, 0x02, + 0xa0, 0x0a, 0x01, 0x02, 0xa4, 0x0a, 0x01, 0x02, 0xf0, 0x26, 0x02, 0x03, 0xf8, 0x26, 0x02, 0x03, 0x00, 0x27, 0x02, 0x03, 0x08, 0x27, 0x02, 0x03, 0x10, 0x27, 0x02, 0x03, 0x10, 0x07, 0x03, 0x03, + 0x18, 0x07, 0x03, 0x03, 0x20, 0x07, 0x03, 0x03, 0x20, 0x22, 0x04, 0x04, 0x30, 0x22, 0x04, 0x04, 0xb0, 0x03, 0x05, 0x04, 0xa0, 0x1d, 0x06, 0x05, 0xc0, 0x00, 0x07, 0x05, 0x00, 0x3c, 0x09, 0x07, + 0x48, 0x19, 0x00, 0x03, 0x50, 0x19, 0x00, 0x03, 0x58, 0x19, 0x00, 0x03, 0x60, 0x19, 0x00, 0x03, 0xa8, 0x0a, 0x01, 0x02, 0xac, 0x0a, 0x01, 0x02, 0xb0, 0x0a, 0x01, 0x02, 0xb4, 0x0a, 0x01, 0x02, + 0xb8, 0x0a, 0x01, 0x02, 0xbc, 0x0a, 0x01, 0x02, 0x18, 0x27, 0x02, 0x03, 0x20, 0x27, 0x02, 0x03, 0x28, 0x27, 0x02, 0x03, 0x30, 0x27, 0x02, 0x03, 0x38, 0x27, 0x02, 0x03, 0x28, 0x07, 0x03, 0x03, + 0x30, 0x07, 0x03, 0x03, 0x38, 0x07, 0x03, 0x03, 0x40, 0x22, 0x04, 0x04, 0x50, 0x22, 0x04, 0x04, 0xc0, 0x03, 0x05, 0x04, 0xc0, 0x1d, 0x06, 0x05, 0xe0, 0x00, 0x07, 0x05, 0x80, 0x3c, 0x09, 0x07, + 0x68, 0x19, 0x00, 0x03, 0x70, 0x19, 0x00, 0x03, 0x78, 0x19, 0x00, 0x03, 0x80, 0x19, 0x00, 0x03, 0xc0, 0x0a, 0x01, 0x02, 0xc4, 0x0a, 0x01, 0x02, 0xc8, 0x0a, 0x01, 0x02, 0xcc, 0x0a, 0x01, 0x02, + 0xd0, 0x0a, 0x01, 0x02, 0xd4, 0x0a, 0x01, 0x02, 0x40, 0x27, 0x02, 0x03, 0x48, 0x27, 0x02, 0x03, 0x50, 0x27, 0x02, 0x03, 0x58, 0x27, 0x02, 0x03, 0x60, 0x27, 0x02, 0x03, 0x40, 0x07, 0x03, 0x03, + 0x48, 0x07, 0x03, 0x03, 0x50, 0x07, 0x03, 0x03, 0x60, 0x22, 0x04, 0x04, 0x70, 0x22, 0x04, 0x04, 0xd0, 0x03, 0x05, 0x04, 0xe0, 0x1d, 0x06, 0x05, 0x00, 0x01, 0x07, 0x05, 0x00, 0x3d, 0x09, 0x07, + 0x88, 0x19, 0x00, 0x03, 0x90, 0x19, 0x00, 0x03, 0x98, 0x19, 0x00, 0x03, 0xa0, 0x19, 0x00, 0x03, 0xd8, 0x0a, 0x01, 0x02, 0xdc, 0x0a, 0x01, 0x02, 0xe0, 0x0a, 0x01, 0x02, 0xe4, 0x0a, 0x01, 0x02, + 0xe8, 0x0a, 0x01, 0x02, 0xec, 0x0a, 0x01, 0x02, 0x68, 0x27, 0x02, 0x03, 0x70, 0x27, 0x02, 0x03, 0x78, 0x27, 0x02, 0x03, 0x80, 0x27, 0x02, 0x03, 0x88, 0x27, 0x02, 0x03, 0x58, 0x07, 0x03, 0x03, + 0x60, 0x07, 0x03, 0x03, 0x68, 0x07, 0x03, 0x03, 0x80, 0x22, 0x04, 0x04, 0x90, 0x22, 0x04, 0x04, 0xe0, 0x03, 0x05, 0x04, 0x00, 0x1e, 0x06, 0x05, 0x20, 0x01, 0x07, 0x05, 0x80, 0x3d, 0x09, 0x07, + 0xa8, 0x19, 0x00, 0x03, 0xb0, 0x19, 0x00, 0x03, 0xb8, 0x19, 0x00, 0x03, 0xc0, 0x19, 0x00, 0x03, 0xf0, 0x0a, 0x01, 0x02, 0xf4, 0x0a, 0x01, 0x02, 0xf8, 0x0a, 0x01, 0x02, 0xfc, 0x0a, 0x01, 0x02, + 0x00, 0x0b, 0x01, 0x02, 0x04, 0x0b, 0x01, 0x02, 0x90, 0x27, 0x02, 0x03, 0x98, 0x27, 0x02, 0x03, 0xa0, 0x27, 0x02, 0x03, 0xa8, 0x27, 0x02, 0x03, 0xb0, 0x27, 0x02, 0x03, 0x70, 0x07, 0x03, 0x03, + 0x78, 0x07, 0x03, 0x03, 0x80, 0x07, 0x03, 0x03, 0xa0, 0x22, 0x04, 0x04, 0xb0, 0x22, 0x04, 0x04, 0xf0, 0x03, 0x05, 0x04, 0x20, 0x1e, 0x06, 0x05, 0x40, 0x01, 0x07, 0x05, 0x00, 0x3e, 0x09, 0x07, + 0xc8, 0x19, 0x00, 0x03, 0xd0, 0x19, 0x00, 0x03, 0xd8, 0x19, 0x00, 0x03, 0xe0, 0x19, 0x00, 0x03, 0x08, 0x0b, 0x01, 0x02, 0x0c, 0x0b, 0x01, 0x02, 0x10, 0x0b, 0x01, 0x02, 0x14, 0x0b, 0x01, 0x02, + 0x18, 0x0b, 0x01, 0x02, 0x1c, 0x0b, 0x01, 0x02, 0xb8, 0x27, 0x02, 0x03, 0xc0, 0x27, 0x02, 0x03, 0xc8, 0x27, 0x02, 0x03, 0xd0, 0x27, 0x02, 0x03, 0xd8, 0x27, 0x02, 0x03, 0x88, 0x07, 0x03, 0x03, + 0x90, 0x07, 0x03, 0x03, 0x98, 0x07, 0x03, 0x03, 0xc0, 0x22, 0x04, 0x04, 0xd0, 0x22, 0x04, 0x04, 0x00, 0x04, 0x05, 0x04, 0x40, 0x1e, 0x06, 0x05, 0x60, 0x01, 0x07, 0x05, 0x80, 0x3e, 0x09, 0x07, + 0xe8, 0x19, 0x00, 0x03, 0xf0, 0x19, 0x00, 0x03, 0xf8, 0x19, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x03, 0x20, 0x0b, 0x01, 0x02, 0x24, 0x0b, 0x01, 0x02, 0x28, 0x0b, 0x01, 0x02, 0x2c, 0x0b, 0x01, 0x02, + 0x30, 0x0b, 0x01, 0x02, 0x34, 0x0b, 0x01, 0x02, 0xe0, 0x27, 0x02, 0x03, 0xe8, 0x27, 0x02, 0x03, 0xf0, 0x27, 0x02, 0x03, 0xf8, 0x27, 0x02, 0x03, 0x00, 0x28, 0x02, 0x03, 0xa0, 0x07, 0x03, 0x03, + 0xa8, 0x07, 0x03, 0x03, 0xb0, 0x07, 0x03, 0x03, 0xe0, 0x22, 0x04, 0x04, 0xf0, 0x22, 0x04, 0x04, 0x10, 0x04, 0x05, 0x04, 0x60, 0x1e, 0x06, 0x05, 0x80, 0x01, 0x07, 0x05, 0x00, 0x3f, 0x09, 0x07, + 0x08, 0x1a, 0x00, 0x03, 0x10, 0x1a, 0x00, 0x03, 0x18, 0x1a, 0x00, 0x03, 0x20, 0x1a, 0x00, 0x03, 0x38, 0x0b, 0x01, 0x02, 0x3c, 0x0b, 0x01, 0x02, 0x40, 0x0b, 0x01, 0x02, 0x44, 0x0b, 0x01, 0x02, + 0x48, 0x0b, 0x01, 0x02, 0x4c, 0x0b, 0x01, 0x02, 0x08, 0x28, 0x02, 0x03, 0x10, 0x28, 0x02, 0x03, 0x18, 0x28, 0x02, 0x03, 0x20, 0x28, 0x02, 0x03, 0x28, 0x28, 0x02, 0x03, 0xb8, 0x07, 0x03, 0x03, + 0xc0, 0x07, 0x03, 0x03, 0xc8, 0x07, 0x03, 0x03, 0x00, 0x23, 0x04, 0x04, 0x10, 0x23, 0x04, 0x04, 0x20, 0x04, 0x05, 0x04, 0x80, 0x1e, 0x06, 0x05, 0xa0, 0x01, 0x07, 0x05, 0x80, 0x3f, 0x09, 0x07, + 0x28, 0x1a, 0x00, 0x03, 0x30, 0x1a, 0x00, 0x03, 0x38, 0x1a, 0x00, 0x03, 0x40, 0x1a, 0x00, 0x03, 0x50, 0x0b, 0x01, 0x02, 0x54, 0x0b, 0x01, 0x02, 0x58, 0x0b, 0x01, 0x02, 0x5c, 0x0b, 0x01, 0x02, + 0x60, 0x0b, 0x01, 0x02, 0x64, 0x0b, 0x01, 0x02, 0x30, 0x28, 0x02, 0x03, 0x38, 0x28, 0x02, 0x03, 0x40, 0x28, 0x02, 0x03, 0x48, 0x28, 0x02, 0x03, 0x50, 0x28, 0x02, 0x03, 0xd0, 0x07, 0x03, 0x03, + 0xd8, 0x07, 0x03, 0x03, 0xe0, 0x07, 0x03, 0x03, 0x20, 0x23, 0x04, 0x04, 0x30, 0x23, 0x04, 0x04, 0x30, 0x04, 0x05, 0x04, 0xa0, 0x1e, 0x06, 0x05, 0xc0, 0x01, 0x07, 0x05, 0x00, 0x00, 0x09, 0x06, + 0x48, 0x1a, 0x00, 0x03, 0x50, 0x1a, 0x00, 0x03, 0x58, 0x1a, 0x00, 0x03, 0x60, 0x1a, 0x00, 0x03, 0x68, 0x0b, 0x01, 0x02, 0x6c, 0x0b, 0x01, 0x02, 0x70, 0x0b, 0x01, 0x02, 0x74, 0x0b, 0x01, 0x02, + 0x78, 0x0b, 0x01, 0x02, 0x7c, 0x0b, 0x01, 0x02, 0x58, 0x28, 0x02, 0x03, 0x60, 0x28, 0x02, 0x03, 0x68, 0x28, 0x02, 0x03, 0x70, 0x28, 0x02, 0x03, 0x78, 0x28, 0x02, 0x03, 0xe8, 0x07, 0x03, 0x03, + 0xf0, 0x07, 0x03, 0x03, 0xf8, 0x07, 0x03, 0x03, 0x40, 0x23, 0x04, 0x04, 0x50, 0x23, 0x04, 0x04, 0x40, 0x04, 0x05, 0x04, 0xc0, 0x1e, 0x06, 0x05, 0xe0, 0x01, 0x07, 0x05, 0x40, 0x00, 0x09, 0x06, + 0x68, 0x1a, 0x00, 0x03, 0x70, 0x1a, 0x00, 0x03, 0x78, 0x1a, 0x00, 0x03, 0x80, 0x1a, 0x00, 0x03, 0x80, 0x0b, 0x01, 0x02, 0x84, 0x0b, 0x01, 0x02, 0x88, 0x0b, 0x01, 0x02, 0x8c, 0x0b, 0x01, 0x02, + 0x90, 0x0b, 0x01, 0x02, 0x94, 0x0b, 0x01, 0x02, 0x80, 0x28, 0x02, 0x03, 0x88, 0x28, 0x02, 0x03, 0x90, 0x28, 0x02, 0x03, 0x98, 0x28, 0x02, 0x03, 0xa0, 0x28, 0x02, 0x03, 0x00, 0x08, 0x03, 0x03, + 0x08, 0x08, 0x03, 0x03, 0x10, 0x08, 0x03, 0x03, 0x60, 0x23, 0x04, 0x04, 0x70, 0x23, 0x04, 0x04, 0x50, 0x04, 0x05, 0x04, 0xe0, 0x1e, 0x06, 0x05, 0x00, 0x02, 0x07, 0x05, 0x80, 0x00, 0x09, 0x06, + 0x88, 0x1a, 0x00, 0x03, 0x90, 0x1a, 0x00, 0x03, 0x98, 0x1a, 0x00, 0x03, 0xa0, 0x1a, 0x00, 0x03, 0x98, 0x0b, 0x01, 0x02, 0x9c, 0x0b, 0x01, 0x02, 0xa0, 0x0b, 0x01, 0x02, 0xa4, 0x0b, 0x01, 0x02, + 0xa8, 0x0b, 0x01, 0x02, 0xac, 0x0b, 0x01, 0x02, 0xa8, 0x28, 0x02, 0x03, 0xb0, 0x28, 0x02, 0x03, 0xb8, 0x28, 0x02, 0x03, 0xc0, 0x28, 0x02, 0x03, 0xc8, 0x28, 0x02, 0x03, 0x18, 0x08, 0x03, 0x03, + 0x20, 0x08, 0x03, 0x03, 0x28, 0x08, 0x03, 0x03, 0x80, 0x23, 0x04, 0x04, 0x90, 0x23, 0x04, 0x04, 0x60, 0x04, 0x05, 0x04, 0x00, 0x1f, 0x06, 0x05, 0x20, 0x02, 0x07, 0x05, 0xc0, 0x00, 0x09, 0x06, + 0xa8, 0x1a, 0x00, 0x03, 0xb0, 0x1a, 0x00, 0x03, 0xb8, 0x1a, 0x00, 0x03, 0xc0, 0x1a, 0x00, 0x03, 0xb0, 0x0b, 0x01, 0x02, 0xb4, 0x0b, 0x01, 0x02, 0xb8, 0x0b, 0x01, 0x02, 0xbc, 0x0b, 0x01, 0x02, + 0xc0, 0x0b, 0x01, 0x02, 0xc4, 0x0b, 0x01, 0x02, 0xd0, 0x28, 0x02, 0x03, 0xd8, 0x28, 0x02, 0x03, 0xe0, 0x28, 0x02, 0x03, 0xe8, 0x28, 0x02, 0x03, 0xf0, 0x28, 0x02, 0x03, 0x30, 0x08, 0x03, 0x03, + 0x38, 0x08, 0x03, 0x03, 0x40, 0x08, 0x03, 0x03, 0xa0, 0x23, 0x04, 0x04, 0xb0, 0x23, 0x04, 0x04, 0x70, 0x04, 0x05, 0x04, 0x20, 0x1f, 0x06, 0x05, 0x40, 0x02, 0x07, 0x05, 0x00, 0x01, 0x09, 0x06, + 0xc8, 0x1a, 0x00, 0x03, 0xd0, 0x1a, 0x00, 0x03, 0xd8, 0x1a, 0x00, 0x03, 0xe0, 0x1a, 0x00, 0x03, 0xc8, 0x0b, 0x01, 0x02, 0xcc, 0x0b, 0x01, 0x02, 0xd0, 0x0b, 0x01, 0x02, 0xd4, 0x0b, 0x01, 0x02, + 0xd8, 0x0b, 0x01, 0x02, 0xdc, 0x0b, 0x01, 0x02, 0xf8, 0x28, 0x02, 0x03, 0x00, 0x29, 0x02, 0x03, 0x08, 0x29, 0x02, 0x03, 0x10, 0x29, 0x02, 0x03, 0x18, 0x29, 0x02, 0x03, 0x48, 0x08, 0x03, 0x03, + 0x50, 0x08, 0x03, 0x03, 0x58, 0x08, 0x03, 0x03, 0xc0, 0x23, 0x04, 0x04, 0xd0, 0x23, 0x04, 0x04, 0x80, 0x04, 0x05, 0x04, 0x40, 0x1f, 0x06, 0x05, 0x60, 0x02, 0x07, 0x05, 0x40, 0x01, 0x09, 0x06, + 0xe8, 0x1a, 0x00, 0x03, 0xf0, 0x1a, 0x00, 0x03, 0xf8, 0x1a, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x03, 0xe0, 0x0b, 0x01, 0x02, 0xe4, 0x0b, 0x01, 0x02, 0xe8, 0x0b, 0x01, 0x02, 0xec, 0x0b, 0x01, 0x02, + 0xf0, 0x0b, 0x01, 0x02, 0xf4, 0x0b, 0x01, 0x02, 0x20, 0x29, 0x02, 0x03, 0x28, 0x29, 0x02, 0x03, 0x30, 0x29, 0x02, 0x03, 0x38, 0x29, 0x02, 0x03, 0x40, 0x29, 0x02, 0x03, 0x60, 0x08, 0x03, 0x03, + 0x68, 0x08, 0x03, 0x03, 0x70, 0x08, 0x03, 0x03, 0xe0, 0x23, 0x04, 0x04, 0xf0, 0x23, 0x04, 0x04, 0x90, 0x04, 0x05, 0x04, 0x60, 0x1f, 0x06, 0x05, 0x80, 0x02, 0x07, 0x05, 0x80, 0x01, 0x09, 0x06, + 0x08, 0x1b, 0x00, 0x03, 0x10, 0x1b, 0x00, 0x03, 0x18, 0x1b, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x03, 0xf8, 0x0b, 0x01, 0x02, 0xfc, 0x0b, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x04, 0x0c, 0x01, 0x02, + 0x08, 0x0c, 0x01, 0x02, 0x0c, 0x0c, 0x01, 0x02, 0x48, 0x29, 0x02, 0x03, 0x50, 0x29, 0x02, 0x03, 0x58, 0x29, 0x02, 0x03, 0x60, 0x29, 0x02, 0x03, 0x68, 0x29, 0x02, 0x03, 0x78, 0x08, 0x03, 0x03, + 0x80, 0x08, 0x03, 0x03, 0x88, 0x08, 0x03, 0x03, 0x00, 0x24, 0x04, 0x04, 0x10, 0x24, 0x04, 0x04, 0xa0, 0x04, 0x05, 0x04, 0x80, 0x1f, 0x06, 0x05, 0xa0, 0x02, 0x07, 0x05, 0xc0, 0x01, 0x09, 0x06, + 0x28, 0x1b, 0x00, 0x03, 0x30, 0x1b, 0x00, 0x03, 0x38, 0x1b, 0x00, 0x03, 0x40, 0x1b, 0x00, 0x03, 0x10, 0x0c, 0x01, 0x02, 0x14, 0x0c, 0x01, 0x02, 0x18, 0x0c, 0x01, 0x02, 0x1c, 0x0c, 0x01, 0x02, + 0x20, 0x0c, 0x01, 0x02, 0x24, 0x0c, 0x01, 0x02, 0x70, 0x29, 0x02, 0x03, 0x78, 0x29, 0x02, 0x03, 0x80, 0x29, 0x02, 0x03, 0x88, 0x29, 0x02, 0x03, 0x90, 0x29, 0x02, 0x03, 0x90, 0x08, 0x03, 0x03, + 0x98, 0x08, 0x03, 0x03, 0xa0, 0x08, 0x03, 0x03, 0x20, 0x24, 0x04, 0x04, 0x30, 0x24, 0x04, 0x04, 0xb0, 0x04, 0x05, 0x04, 0xa0, 0x1f, 0x06, 0x05, 0xc0, 0x02, 0x07, 0x05, 0x00, 0x02, 0x09, 0x06, + 0x48, 0x1b, 0x00, 0x03, 0x50, 0x1b, 0x00, 0x03, 0x58, 0x1b, 0x00, 0x03, 0x60, 0x1b, 0x00, 0x03, 0x28, 0x0c, 0x01, 0x02, 0x2c, 0x0c, 0x01, 0x02, 0x30, 0x0c, 0x01, 0x02, 0x34, 0x0c, 0x01, 0x02, + 0x38, 0x0c, 0x01, 0x02, 0x3c, 0x0c, 0x01, 0x02, 0x98, 0x29, 0x02, 0x03, 0xa0, 0x29, 0x02, 0x03, 0xa8, 0x29, 0x02, 0x03, 0xb0, 0x29, 0x02, 0x03, 0xb8, 0x29, 0x02, 0x03, 0xa8, 0x08, 0x03, 0x03, + 0xb0, 0x08, 0x03, 0x03, 0xb8, 0x08, 0x03, 0x03, 0x40, 0x24, 0x04, 0x04, 0x50, 0x24, 0x04, 0x04, 0xc0, 0x04, 0x05, 0x04, 0xc0, 0x1f, 0x06, 0x05, 0xe0, 0x02, 0x07, 0x05, 0x40, 0x02, 0x09, 0x06, + 0x68, 0x1b, 0x00, 0x03, 0x70, 0x1b, 0x00, 0x03, 0x78, 0x1b, 0x00, 0x03, 0x80, 0x1b, 0x00, 0x03, 0x40, 0x0c, 0x01, 0x02, 0x44, 0x0c, 0x01, 0x02, 0x48, 0x0c, 0x01, 0x02, 0x4c, 0x0c, 0x01, 0x02, + 0x50, 0x0c, 0x01, 0x02, 0x54, 0x0c, 0x01, 0x02, 0xc0, 0x29, 0x02, 0x03, 0xc8, 0x29, 0x02, 0x03, 0xd0, 0x29, 0x02, 0x03, 0xd8, 0x29, 0x02, 0x03, 0xe0, 0x29, 0x02, 0x03, 0xc0, 0x08, 0x03, 0x03, + 0xc8, 0x08, 0x03, 0x03, 0xd0, 0x08, 0x03, 0x03, 0x60, 0x24, 0x04, 0x04, 0x70, 0x24, 0x04, 0x04, 0xd0, 0x04, 0x05, 0x04, 0xe0, 0x1f, 0x06, 0x05, 0x00, 0x03, 0x07, 0x05, 0x80, 0x02, 0x09, 0x06, + 0x88, 0x1b, 0x00, 0x03, 0x90, 0x1b, 0x00, 0x03, 0x98, 0x1b, 0x00, 0x03, 0xa0, 0x1b, 0x00, 0x03, 0x58, 0x0c, 0x01, 0x02, 0x5c, 0x0c, 0x01, 0x02, 0x60, 0x0c, 0x01, 0x02, 0x64, 0x0c, 0x01, 0x02, + 0x68, 0x0c, 0x01, 0x02, 0x6c, 0x0c, 0x01, 0x02, 0xe8, 0x29, 0x02, 0x03, 0xf0, 0x29, 0x02, 0x03, 0xf8, 0x29, 0x02, 0x03, 0x00, 0x2a, 0x02, 0x03, 0x08, 0x2a, 0x02, 0x03, 0xd8, 0x08, 0x03, 0x03, + 0xe0, 0x08, 0x03, 0x03, 0xe8, 0x08, 0x03, 0x03, 0x80, 0x24, 0x04, 0x04, 0x90, 0x24, 0x04, 0x04, 0xe0, 0x04, 0x05, 0x04, 0x00, 0x20, 0x06, 0x05, 0x20, 0x03, 0x07, 0x05, 0xc0, 0x02, 0x09, 0x06, + 0xa8, 0x1b, 0x00, 0x03, 0xb0, 0x1b, 0x00, 0x03, 0xb8, 0x1b, 0x00, 0x03, 0xc0, 0x1b, 0x00, 0x03, 0x70, 0x0c, 0x01, 0x02, 0x74, 0x0c, 0x01, 0x02, 0x78, 0x0c, 0x01, 0x02, 0x7c, 0x0c, 0x01, 0x02, + 0x80, 0x0c, 0x01, 0x02, 0x84, 0x0c, 0x01, 0x02, 0x10, 0x2a, 0x02, 0x03, 0x18, 0x2a, 0x02, 0x03, 0x20, 0x2a, 0x02, 0x03, 0x28, 0x2a, 0x02, 0x03, 0x30, 0x2a, 0x02, 0x03, 0xf0, 0x08, 0x03, 0x03, + 0xf8, 0x08, 0x03, 0x03, 0x00, 0x09, 0x03, 0x03, 0xa0, 0x24, 0x04, 0x04, 0xb0, 0x24, 0x04, 0x04, 0xf0, 0x04, 0x05, 0x04, 0x20, 0x20, 0x06, 0x05, 0x40, 0x03, 0x07, 0x05, 0x00, 0x03, 0x09, 0x06, + 0xc8, 0x1b, 0x00, 0x03, 0xd0, 0x1b, 0x00, 0x03, 0xd8, 0x1b, 0x00, 0x03, 0xe0, 0x1b, 0x00, 0x03, 0x88, 0x0c, 0x01, 0x02, 0x8c, 0x0c, 0x01, 0x02, 0x90, 0x0c, 0x01, 0x02, 0x94, 0x0c, 0x01, 0x02, + 0x98, 0x0c, 0x01, 0x02, 0x9c, 0x0c, 0x01, 0x02, 0x38, 0x2a, 0x02, 0x03, 0x40, 0x2a, 0x02, 0x03, 0x48, 0x2a, 0x02, 0x03, 0x50, 0x2a, 0x02, 0x03, 0x58, 0x2a, 0x02, 0x03, 0x08, 0x09, 0x03, 0x03, + 0x10, 0x09, 0x03, 0x03, 0x18, 0x09, 0x03, 0x03, 0xc0, 0x24, 0x04, 0x04, 0xd0, 0x24, 0x04, 0x04, 0x00, 0x05, 0x05, 0x04, 0x40, 0x20, 0x06, 0x05, 0x60, 0x03, 0x07, 0x05, 0x00, 0x15, 0x0a, 0x07, + 0xe8, 0x1b, 0x00, 0x03, 0xf0, 0x1b, 0x00, 0x03, 0xf8, 0x1b, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x03, 0xa0, 0x0c, 0x01, 0x02, 0xa4, 0x0c, 0x01, 0x02, 0xa8, 0x0c, 0x01, 0x02, 0xac, 0x0c, 0x01, 0x02, + 0xb0, 0x0c, 0x01, 0x02, 0xb4, 0x0c, 0x01, 0x02, 0x60, 0x2a, 0x02, 0x03, 0x68, 0x2a, 0x02, 0x03, 0x70, 0x2a, 0x02, 0x03, 0x78, 0x2a, 0x02, 0x03, 0x80, 0x2a, 0x02, 0x03, 0x20, 0x09, 0x03, 0x03, + 0x28, 0x09, 0x03, 0x03, 0x30, 0x09, 0x03, 0x03, 0xe0, 0x24, 0x04, 0x04, 0xf0, 0x24, 0x04, 0x04, 0x10, 0x05, 0x05, 0x04, 0x60, 0x20, 0x06, 0x05, 0x80, 0x03, 0x07, 0x05, 0x80, 0x15, 0x0a, 0x07, + 0x08, 0x1c, 0x00, 0x03, 0x10, 0x1c, 0x00, 0x03, 0x18, 0x1c, 0x00, 0x03, 0x20, 0x1c, 0x00, 0x03, 0xb8, 0x0c, 0x01, 0x02, 0xbc, 0x0c, 0x01, 0x02, 0xc0, 0x0c, 0x01, 0x02, 0xc4, 0x0c, 0x01, 0x02, + 0xc8, 0x0c, 0x01, 0x02, 0xcc, 0x0c, 0x01, 0x02, 0x88, 0x2a, 0x02, 0x03, 0x90, 0x2a, 0x02, 0x03, 0x98, 0x2a, 0x02, 0x03, 0xa0, 0x2a, 0x02, 0x03, 0xa8, 0x2a, 0x02, 0x03, 0x38, 0x09, 0x03, 0x03, + 0x40, 0x09, 0x03, 0x03, 0x48, 0x09, 0x03, 0x03, 0x00, 0x25, 0x04, 0x04, 0x10, 0x25, 0x04, 0x04, 0x20, 0x05, 0x05, 0x04, 0x80, 0x20, 0x06, 0x05, 0xa0, 0x03, 0x07, 0x05, 0x00, 0x16, 0x0a, 0x07, + 0x28, 0x1c, 0x00, 0x03, 0x30, 0x1c, 0x00, 0x03, 0x38, 0x1c, 0x00, 0x03, 0x40, 0x1c, 0x00, 0x03, 0xd0, 0x0c, 0x01, 0x02, 0xd4, 0x0c, 0x01, 0x02, 0xd8, 0x0c, 0x01, 0x02, 0xdc, 0x0c, 0x01, 0x02, + 0xe0, 0x0c, 0x01, 0x02, 0xe4, 0x0c, 0x01, 0x02, 0xb0, 0x2a, 0x02, 0x03, 0xb8, 0x2a, 0x02, 0x03, 0xc0, 0x2a, 0x02, 0x03, 0xc8, 0x2a, 0x02, 0x03, 0xd0, 0x2a, 0x02, 0x03, 0x50, 0x09, 0x03, 0x03, + 0x58, 0x09, 0x03, 0x03, 0x60, 0x09, 0x03, 0x03, 0x20, 0x25, 0x04, 0x04, 0x30, 0x25, 0x04, 0x04, 0x30, 0x05, 0x05, 0x04, 0xa0, 0x20, 0x06, 0x05, 0xc0, 0x03, 0x07, 0x05, 0x80, 0x16, 0x0a, 0x07, + 0x48, 0x1c, 0x00, 0x03, 0x50, 0x1c, 0x00, 0x03, 0x58, 0x1c, 0x00, 0x03, 0x60, 0x1c, 0x00, 0x03, 0xe8, 0x0c, 0x01, 0x02, 0xec, 0x0c, 0x01, 0x02, 0xf0, 0x0c, 0x01, 0x02, 0xf4, 0x0c, 0x01, 0x02, + 0xf8, 0x0c, 0x01, 0x02, 0xfc, 0x0c, 0x01, 0x02, 0xd8, 0x2a, 0x02, 0x03, 0xe0, 0x2a, 0x02, 0x03, 0xe8, 0x2a, 0x02, 0x03, 0xf0, 0x2a, 0x02, 0x03, 0xf8, 0x2a, 0x02, 0x03, 0x68, 0x09, 0x03, 0x03, + 0x70, 0x09, 0x03, 0x03, 0x40, 0x25, 0x04, 0x04, 0x50, 0x25, 0x04, 0x04, 0x60, 0x25, 0x04, 0x04, 0x40, 0x05, 0x05, 0x04, 0xc0, 0x20, 0x06, 0x05, 0xe0, 0x03, 0x07, 0x05, 0x00, 0x17, 0x0a, 0x07, + 0x68, 0x1c, 0x00, 0x03, 0x70, 0x1c, 0x00, 0x03, 0x78, 0x1c, 0x00, 0x03, 0x80, 0x1c, 0x00, 0x03, 0x00, 0x0d, 0x01, 0x02, 0x04, 0x0d, 0x01, 0x02, 0x08, 0x0d, 0x01, 0x02, 0x0c, 0x0d, 0x01, 0x02, + 0x10, 0x0d, 0x01, 0x02, 0x14, 0x0d, 0x01, 0x02, 0x00, 0x2b, 0x02, 0x03, 0x08, 0x2b, 0x02, 0x03, 0x10, 0x2b, 0x02, 0x03, 0x18, 0x2b, 0x02, 0x03, 0x78, 0x09, 0x03, 0x03, 0x80, 0x09, 0x03, 0x03, + 0x88, 0x09, 0x03, 0x03, 0x70, 0x25, 0x04, 0x04, 0x80, 0x25, 0x04, 0x04, 0x90, 0x25, 0x04, 0x04, 0x50, 0x05, 0x05, 0x04, 0xe0, 0x20, 0x06, 0x05, 0x00, 0x04, 0x07, 0x05, 0x80, 0x17, 0x0a, 0x07, + 0x88, 0x1c, 0x00, 0x03, 0x90, 0x1c, 0x00, 0x03, 0x98, 0x1c, 0x00, 0x03, 0xa0, 0x1c, 0x00, 0x03, 0x18, 0x0d, 0x01, 0x02, 0x1c, 0x0d, 0x01, 0x02, 0x20, 0x0d, 0x01, 0x02, 0x24, 0x0d, 0x01, 0x02, + 0x28, 0x0d, 0x01, 0x02, 0x2c, 0x0d, 0x01, 0x02, 0x20, 0x2b, 0x02, 0x03, 0x28, 0x2b, 0x02, 0x03, 0x30, 0x2b, 0x02, 0x03, 0x38, 0x2b, 0x02, 0x03, 0x90, 0x09, 0x03, 0x03, 0x98, 0x09, 0x03, 0x03, + 0xa0, 0x09, 0x03, 0x03, 0xa0, 0x25, 0x04, 0x04, 0xb0, 0x25, 0x04, 0x04, 0xc0, 0x25, 0x04, 0x04, 0x60, 0x05, 0x05, 0x04, 0x00, 0x21, 0x06, 0x05, 0x20, 0x04, 0x07, 0x05, 0x00, 0x18, 0x0a, 0x07, + 0xa8, 0x1c, 0x00, 0x03, 0xb0, 0x1c, 0x00, 0x03, 0xb8, 0x1c, 0x00, 0x03, 0xc0, 0x1c, 0x00, 0x03, 0x30, 0x0d, 0x01, 0x02, 0x34, 0x0d, 0x01, 0x02, 0x38, 0x0d, 0x01, 0x02, 0x3c, 0x0d, 0x01, 0x02, + 0x40, 0x0d, 0x01, 0x02, 0x44, 0x0d, 0x01, 0x02, 0x40, 0x2b, 0x02, 0x03, 0x48, 0x2b, 0x02, 0x03, 0x50, 0x2b, 0x02, 0x03, 0x58, 0x2b, 0x02, 0x03, 0xa8, 0x09, 0x03, 0x03, 0xb0, 0x09, 0x03, 0x03, + 0xb8, 0x09, 0x03, 0x03, 0xd0, 0x25, 0x04, 0x04, 0xe0, 0x25, 0x04, 0x04, 0xf0, 0x25, 0x04, 0x04, 0x70, 0x05, 0x05, 0x04, 0x20, 0x21, 0x06, 0x05, 0x40, 0x04, 0x07, 0x05, 0x80, 0x18, 0x0a, 0x07, + 0xc8, 0x1c, 0x00, 0x03, 0xd0, 0x1c, 0x00, 0x03, 0xd8, 0x1c, 0x00, 0x03, 0xe0, 0x1c, 0x00, 0x03, 0x48, 0x0d, 0x01, 0x02, 0x4c, 0x0d, 0x01, 0x02, 0x50, 0x0d, 0x01, 0x02, 0x54, 0x0d, 0x01, 0x02, + 0x58, 0x0d, 0x01, 0x02, 0x5c, 0x0d, 0x01, 0x02, 0x60, 0x2b, 0x02, 0x03, 0x68, 0x2b, 0x02, 0x03, 0x70, 0x2b, 0x02, 0x03, 0x78, 0x2b, 0x02, 0x03, 0xc0, 0x09, 0x03, 0x03, 0xc8, 0x09, 0x03, 0x03, + 0xd0, 0x09, 0x03, 0x03, 0x00, 0x26, 0x04, 0x04, 0x10, 0x26, 0x04, 0x04, 0x20, 0x26, 0x04, 0x04, 0x80, 0x05, 0x05, 0x04, 0x40, 0x21, 0x06, 0x05, 0x60, 0x04, 0x07, 0x05, 0x00, 0x19, 0x0a, 0x07, + 0xe8, 0x1c, 0x00, 0x03, 0xf0, 0x1c, 0x00, 0x03, 0xf8, 0x1c, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x03, 0x60, 0x0d, 0x01, 0x02, 0x64, 0x0d, 0x01, 0x02, 0x68, 0x0d, 0x01, 0x02, 0x6c, 0x0d, 0x01, 0x02, + 0x70, 0x0d, 0x01, 0x02, 0x74, 0x0d, 0x01, 0x02, 0x80, 0x2b, 0x02, 0x03, 0x88, 0x2b, 0x02, 0x03, 0x90, 0x2b, 0x02, 0x03, 0x98, 0x2b, 0x02, 0x03, 0xd8, 0x09, 0x03, 0x03, 0xe0, 0x09, 0x03, 0x03, + 0xe8, 0x09, 0x03, 0x03, 0x30, 0x26, 0x04, 0x04, 0x40, 0x26, 0x04, 0x04, 0x50, 0x26, 0x04, 0x04, 0x90, 0x05, 0x05, 0x04, 0x60, 0x21, 0x06, 0x05, 0x80, 0x04, 0x07, 0x05, 0x80, 0x19, 0x0a, 0x07, + 0x08, 0x1d, 0x00, 0x03, 0x10, 0x1d, 0x00, 0x03, 0x18, 0x1d, 0x00, 0x03, 0x20, 0x1d, 0x00, 0x03, 0x78, 0x0d, 0x01, 0x02, 0x7c, 0x0d, 0x01, 0x02, 0x80, 0x0d, 0x01, 0x02, 0x84, 0x0d, 0x01, 0x02, + 0x88, 0x0d, 0x01, 0x02, 0x8c, 0x0d, 0x01, 0x02, 0xa0, 0x2b, 0x02, 0x03, 0xa8, 0x2b, 0x02, 0x03, 0xb0, 0x2b, 0x02, 0x03, 0xb8, 0x2b, 0x02, 0x03, 0xf0, 0x09, 0x03, 0x03, 0xf8, 0x09, 0x03, 0x03, + 0x00, 0x0a, 0x03, 0x03, 0x60, 0x26, 0x04, 0x04, 0x70, 0x26, 0x04, 0x04, 0xa0, 0x05, 0x05, 0x04, 0xb0, 0x05, 0x05, 0x04, 0x80, 0x21, 0x06, 0x05, 0xa0, 0x04, 0x07, 0x05, 0x00, 0x1a, 0x0a, 0x07, + 0x28, 0x1d, 0x00, 0x03, 0x30, 0x1d, 0x00, 0x03, 0x38, 0x1d, 0x00, 0x03, 0x40, 0x1d, 0x00, 0x03, 0x90, 0x0d, 0x01, 0x02, 0x94, 0x0d, 0x01, 0x02, 0x98, 0x0d, 0x01, 0x02, 0x9c, 0x0d, 0x01, 0x02, + 0xa0, 0x0d, 0x01, 0x02, 0xa4, 0x0d, 0x01, 0x02, 0xc0, 0x2b, 0x02, 0x03, 0xc8, 0x2b, 0x02, 0x03, 0xd0, 0x2b, 0x02, 0x03, 0xd8, 0x2b, 0x02, 0x03, 0x08, 0x0a, 0x03, 0x03, 0x10, 0x0a, 0x03, 0x03, + 0x18, 0x0a, 0x03, 0x03, 0x80, 0x26, 0x04, 0x04, 0x90, 0x26, 0x04, 0x04, 0xc0, 0x05, 0x05, 0x04, 0xd0, 0x05, 0x05, 0x04, 0xa0, 0x21, 0x06, 0x05, 0xc0, 0x04, 0x07, 0x05, 0x80, 0x1a, 0x0a, 0x07, + 0x48, 0x1d, 0x00, 0x03, 0x50, 0x1d, 0x00, 0x03, 0x58, 0x1d, 0x00, 0x03, 0x60, 0x1d, 0x00, 0x03, 0xa8, 0x0d, 0x01, 0x02, 0xac, 0x0d, 0x01, 0x02, 0xb0, 0x0d, 0x01, 0x02, 0xb4, 0x0d, 0x01, 0x02, + 0xb8, 0x0d, 0x01, 0x02, 0xbc, 0x0d, 0x01, 0x02, 0xe0, 0x2b, 0x02, 0x03, 0xe8, 0x2b, 0x02, 0x03, 0xf0, 0x2b, 0x02, 0x03, 0xf8, 0x2b, 0x02, 0x03, 0x20, 0x0a, 0x03, 0x03, 0x28, 0x0a, 0x03, 0x03, + 0x30, 0x0a, 0x03, 0x03, 0xa0, 0x26, 0x04, 0x04, 0xb0, 0x26, 0x04, 0x04, 0xe0, 0x05, 0x05, 0x04, 0xf0, 0x05, 0x05, 0x04, 0xc0, 0x21, 0x06, 0x05, 0xe0, 0x04, 0x07, 0x05, 0x00, 0x1b, 0x0a, 0x07, + 0x68, 0x1d, 0x00, 0x03, 0x70, 0x1d, 0x00, 0x03, 0x78, 0x1d, 0x00, 0x03, 0x80, 0x1d, 0x00, 0x03, 0xc0, 0x0d, 0x01, 0x02, 0xc4, 0x0d, 0x01, 0x02, 0xc8, 0x0d, 0x01, 0x02, 0xcc, 0x0d, 0x01, 0x02, + 0xd0, 0x0d, 0x01, 0x02, 0xd4, 0x0d, 0x01, 0x02, 0x00, 0x2c, 0x02, 0x03, 0x08, 0x2c, 0x02, 0x03, 0x10, 0x2c, 0x02, 0x03, 0x18, 0x2c, 0x02, 0x03, 0x38, 0x0a, 0x03, 0x03, 0x40, 0x0a, 0x03, 0x03, + 0x48, 0x0a, 0x03, 0x03, 0xc0, 0x26, 0x04, 0x04, 0xd0, 0x26, 0x04, 0x04, 0x00, 0x06, 0x05, 0x04, 0x10, 0x06, 0x05, 0x04, 0xe0, 0x21, 0x06, 0x05, 0x00, 0x05, 0x07, 0x05, 0x80, 0x1b, 0x0a, 0x07, + 0x88, 0x1d, 0x00, 0x03, 0x90, 0x1d, 0x00, 0x03, 0x98, 0x1d, 0x00, 0x03, 0xa0, 0x1d, 0x00, 0x03, 0xd8, 0x0d, 0x01, 0x02, 0xdc, 0x0d, 0x01, 0x02, 0xe0, 0x0d, 0x01, 0x02, 0xe4, 0x0d, 0x01, 0x02, + 0xe8, 0x0d, 0x01, 0x02, 0xec, 0x0d, 0x01, 0x02, 0x20, 0x2c, 0x02, 0x03, 0x28, 0x2c, 0x02, 0x03, 0x30, 0x2c, 0x02, 0x03, 0x38, 0x2c, 0x02, 0x03, 0x50, 0x0a, 0x03, 0x03, 0x58, 0x0a, 0x03, 0x03, + 0x60, 0x0a, 0x03, 0x03, 0xe0, 0x26, 0x04, 0x04, 0xf0, 0x26, 0x04, 0x04, 0x20, 0x06, 0x05, 0x04, 0x30, 0x06, 0x05, 0x04, 0x00, 0x22, 0x06, 0x05, 0x20, 0x05, 0x07, 0x05, 0x00, 0x1c, 0x0a, 0x07, + 0xa8, 0x1d, 0x00, 0x03, 0xb0, 0x1d, 0x00, 0x03, 0xb8, 0x1d, 0x00, 0x03, 0xc0, 0x1d, 0x00, 0x03, 0xf0, 0x0d, 0x01, 0x02, 0xf4, 0x0d, 0x01, 0x02, 0xf8, 0x0d, 0x01, 0x02, 0xfc, 0x0d, 0x01, 0x02, + 0x00, 0x0e, 0x01, 0x02, 0x04, 0x0e, 0x01, 0x02, 0x40, 0x2c, 0x02, 0x03, 0x48, 0x2c, 0x02, 0x03, 0x50, 0x2c, 0x02, 0x03, 0x58, 0x2c, 0x02, 0x03, 0x68, 0x0a, 0x03, 0x03, 0x70, 0x0a, 0x03, 0x03, + 0x78, 0x0a, 0x03, 0x03, 0x00, 0x27, 0x04, 0x04, 0x10, 0x27, 0x04, 0x04, 0x40, 0x06, 0x05, 0x04, 0x50, 0x06, 0x05, 0x04, 0x20, 0x22, 0x06, 0x05, 0x40, 0x05, 0x07, 0x05, 0x80, 0x1c, 0x0a, 0x07, + 0xc8, 0x1d, 0x00, 0x03, 0xd0, 0x1d, 0x00, 0x03, 0xd8, 0x1d, 0x00, 0x03, 0xe0, 0x1d, 0x00, 0x03, 0x08, 0x0e, 0x01, 0x02, 0x0c, 0x0e, 0x01, 0x02, 0x10, 0x0e, 0x01, 0x02, 0x14, 0x0e, 0x01, 0x02, + 0x18, 0x0e, 0x01, 0x02, 0x1c, 0x0e, 0x01, 0x02, 0x60, 0x2c, 0x02, 0x03, 0x68, 0x2c, 0x02, 0x03, 0x70, 0x2c, 0x02, 0x03, 0x78, 0x2c, 0x02, 0x03, 0x80, 0x0a, 0x03, 0x03, 0x88, 0x0a, 0x03, 0x03, + 0x90, 0x0a, 0x03, 0x03, 0x20, 0x27, 0x04, 0x04, 0x30, 0x27, 0x04, 0x04, 0x60, 0x06, 0x05, 0x04, 0x70, 0x06, 0x05, 0x04, 0x40, 0x22, 0x06, 0x05, 0x60, 0x05, 0x07, 0x05, 0x00, 0x1d, 0x0a, 0x07, + 0xe8, 0x1d, 0x00, 0x03, 0xf0, 0x1d, 0x00, 0x03, 0xf8, 0x1d, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x03, 0x20, 0x0e, 0x01, 0x02, 0x24, 0x0e, 0x01, 0x02, 0x28, 0x0e, 0x01, 0x02, 0x2c, 0x0e, 0x01, 0x02, + 0x30, 0x0e, 0x01, 0x02, 0x34, 0x0e, 0x01, 0x02, 0x80, 0x2c, 0x02, 0x03, 0x88, 0x2c, 0x02, 0x03, 0x90, 0x2c, 0x02, 0x03, 0x98, 0x2c, 0x02, 0x03, 0x98, 0x0a, 0x03, 0x03, 0xa0, 0x0a, 0x03, 0x03, + 0xa8, 0x0a, 0x03, 0x03, 0x40, 0x27, 0x04, 0x04, 0x50, 0x27, 0x04, 0x04, 0x80, 0x06, 0x05, 0x04, 0x90, 0x06, 0x05, 0x04, 0x60, 0x22, 0x06, 0x05, 0x00, 0x19, 0x08, 0x06, 0x80, 0x1d, 0x0a, 0x07, + 0x08, 0x1e, 0x00, 0x03, 0x10, 0x1e, 0x00, 0x03, 0x18, 0x1e, 0x00, 0x03, 0x20, 0x1e, 0x00, 0x03, 0x38, 0x0e, 0x01, 0x02, 0x3c, 0x0e, 0x01, 0x02, 0x40, 0x0e, 0x01, 0x02, 0x44, 0x0e, 0x01, 0x02, + 0x48, 0x0e, 0x01, 0x02, 0x4c, 0x0e, 0x01, 0x02, 0xa0, 0x2c, 0x02, 0x03, 0xa8, 0x2c, 0x02, 0x03, 0xb0, 0x2c, 0x02, 0x03, 0xb8, 0x2c, 0x02, 0x03, 0xb0, 0x0a, 0x03, 0x03, 0xb8, 0x0a, 0x03, 0x03, + 0xc0, 0x0a, 0x03, 0x03, 0x60, 0x27, 0x04, 0x04, 0x70, 0x27, 0x04, 0x04, 0xa0, 0x06, 0x05, 0x04, 0xb0, 0x06, 0x05, 0x04, 0x80, 0x22, 0x06, 0x05, 0x40, 0x19, 0x08, 0x06, 0x00, 0x35, 0x0b, 0x08, + 0x28, 0x1e, 0x00, 0x03, 0x30, 0x1e, 0x00, 0x03, 0x38, 0x1e, 0x00, 0x03, 0x40, 0x1e, 0x00, 0x03, 0x50, 0x0e, 0x01, 0x02, 0x54, 0x0e, 0x01, 0x02, 0x58, 0x0e, 0x01, 0x02, 0x5c, 0x0e, 0x01, 0x02, + 0x60, 0x0e, 0x01, 0x02, 0x64, 0x0e, 0x01, 0x02, 0xc0, 0x2c, 0x02, 0x03, 0xc8, 0x2c, 0x02, 0x03, 0xd0, 0x2c, 0x02, 0x03, 0xd8, 0x2c, 0x02, 0x03, 0xc8, 0x0a, 0x03, 0x03, 0xd0, 0x0a, 0x03, 0x03, + 0xd8, 0x0a, 0x03, 0x03, 0x80, 0x27, 0x04, 0x04, 0x90, 0x27, 0x04, 0x04, 0xc0, 0x06, 0x05, 0x04, 0xd0, 0x06, 0x05, 0x04, 0xa0, 0x22, 0x06, 0x05, 0x80, 0x19, 0x08, 0x06, 0x00, 0x36, 0x0b, 0x08, + 0x48, 0x1e, 0x00, 0x03, 0x50, 0x1e, 0x00, 0x03, 0x58, 0x1e, 0x00, 0x03, 0x60, 0x1e, 0x00, 0x03, 0x68, 0x0e, 0x01, 0x02, 0x6c, 0x0e, 0x01, 0x02, 0x70, 0x0e, 0x01, 0x02, 0x74, 0x0e, 0x01, 0x02, + 0x78, 0x0e, 0x01, 0x02, 0x7c, 0x0e, 0x01, 0x02, 0xe0, 0x2c, 0x02, 0x03, 0xe8, 0x2c, 0x02, 0x03, 0xf0, 0x2c, 0x02, 0x03, 0xf8, 0x2c, 0x02, 0x03, 0xe0, 0x0a, 0x03, 0x03, 0xe8, 0x0a, 0x03, 0x03, + 0xf0, 0x0a, 0x03, 0x03, 0xa0, 0x27, 0x04, 0x04, 0xb0, 0x27, 0x04, 0x04, 0xe0, 0x06, 0x05, 0x04, 0xf0, 0x06, 0x05, 0x04, 0xc0, 0x22, 0x06, 0x05, 0xc0, 0x19, 0x08, 0x06, 0x00, 0x37, 0x0b, 0x08, + 0x68, 0x1e, 0x00, 0x03, 0x70, 0x1e, 0x00, 0x03, 0x78, 0x1e, 0x00, 0x03, 0x80, 0x1e, 0x00, 0x03, 0x80, 0x0e, 0x01, 0x02, 0x84, 0x0e, 0x01, 0x02, 0x88, 0x0e, 0x01, 0x02, 0x8c, 0x0e, 0x01, 0x02, + 0x90, 0x0e, 0x01, 0x02, 0x94, 0x0e, 0x01, 0x02, 0x00, 0x2d, 0x02, 0x03, 0x08, 0x2d, 0x02, 0x03, 0x10, 0x2d, 0x02, 0x03, 0x18, 0x2d, 0x02, 0x03, 0xf8, 0x0a, 0x03, 0x03, 0x00, 0x0b, 0x03, 0x03, + 0x08, 0x0b, 0x03, 0x03, 0xc0, 0x27, 0x04, 0x04, 0xd0, 0x27, 0x04, 0x04, 0x00, 0x07, 0x05, 0x04, 0x10, 0x07, 0x05, 0x04, 0xe0, 0x22, 0x06, 0x05, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x38, 0x0b, 0x08, + 0x88, 0x1e, 0x00, 0x03, 0x90, 0x1e, 0x00, 0x03, 0x98, 0x1e, 0x00, 0x03, 0xa0, 0x1e, 0x00, 0x03, 0x98, 0x0e, 0x01, 0x02, 0x9c, 0x0e, 0x01, 0x02, 0xa0, 0x0e, 0x01, 0x02, 0xa4, 0x0e, 0x01, 0x02, + 0xa8, 0x0e, 0x01, 0x02, 0xac, 0x0e, 0x01, 0x02, 0x20, 0x2d, 0x02, 0x03, 0x28, 0x2d, 0x02, 0x03, 0x30, 0x2d, 0x02, 0x03, 0x38, 0x2d, 0x02, 0x03, 0x10, 0x0b, 0x03, 0x03, 0x18, 0x0b, 0x03, 0x03, + 0x20, 0x0b, 0x03, 0x03, 0xe0, 0x27, 0x04, 0x04, 0xf0, 0x27, 0x04, 0x04, 0x20, 0x07, 0x05, 0x04, 0x30, 0x07, 0x05, 0x04, 0x00, 0x23, 0x06, 0x05, 0x40, 0x1a, 0x08, 0x06, 0x00, 0x39, 0x0b, 0x08, + 0xa8, 0x1e, 0x00, 0x03, 0xb0, 0x1e, 0x00, 0x03, 0xb8, 0x1e, 0x00, 0x03, 0xc0, 0x1e, 0x00, 0x03, 0xb0, 0x0e, 0x01, 0x02, 0xb4, 0x0e, 0x01, 0x02, 0xb8, 0x0e, 0x01, 0x02, 0xbc, 0x0e, 0x01, 0x02, + 0xc0, 0x0e, 0x01, 0x02, 0xc4, 0x0e, 0x01, 0x02, 0x40, 0x2d, 0x02, 0x03, 0x48, 0x2d, 0x02, 0x03, 0x50, 0x2d, 0x02, 0x03, 0x58, 0x2d, 0x02, 0x03, 0x28, 0x0b, 0x03, 0x03, 0x30, 0x0b, 0x03, 0x03, + 0x38, 0x0b, 0x03, 0x03, 0x00, 0x28, 0x04, 0x04, 0x10, 0x28, 0x04, 0x04, 0x40, 0x07, 0x05, 0x04, 0x50, 0x07, 0x05, 0x04, 0x20, 0x23, 0x06, 0x05, 0x80, 0x1a, 0x08, 0x06, 0x00, 0x3a, 0x0b, 0x08, + 0xc8, 0x1e, 0x00, 0x03, 0xd0, 0x1e, 0x00, 0x03, 0xd8, 0x1e, 0x00, 0x03, 0xe0, 0x1e, 0x00, 0x03, 0xc8, 0x0e, 0x01, 0x02, 0xcc, 0x0e, 0x01, 0x02, 0xd0, 0x0e, 0x01, 0x02, 0xd4, 0x0e, 0x01, 0x02, + 0xd8, 0x0e, 0x01, 0x02, 0xdc, 0x0e, 0x01, 0x02, 0x60, 0x2d, 0x02, 0x03, 0x68, 0x2d, 0x02, 0x03, 0x70, 0x2d, 0x02, 0x03, 0x78, 0x2d, 0x02, 0x03, 0x40, 0x0b, 0x03, 0x03, 0x48, 0x0b, 0x03, 0x03, + 0x50, 0x0b, 0x03, 0x03, 0x20, 0x28, 0x04, 0x04, 0x30, 0x28, 0x04, 0x04, 0x60, 0x07, 0x05, 0x04, 0x70, 0x07, 0x05, 0x04, 0x40, 0x23, 0x06, 0x05, 0xc0, 0x1a, 0x08, 0x06, 0x00, 0x3b, 0x0b, 0x08, + 0xe8, 0x1e, 0x00, 0x03, 0xf0, 0x1e, 0x00, 0x03, 0xf8, 0x1e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x03, 0xe0, 0x0e, 0x01, 0x02, 0xe4, 0x0e, 0x01, 0x02, 0xe8, 0x0e, 0x01, 0x02, 0xec, 0x0e, 0x01, 0x02, + 0xf0, 0x0e, 0x01, 0x02, 0xf4, 0x0e, 0x01, 0x02, 0x80, 0x2d, 0x02, 0x03, 0x88, 0x2d, 0x02, 0x03, 0x90, 0x2d, 0x02, 0x03, 0x98, 0x2d, 0x02, 0x03, 0x58, 0x0b, 0x03, 0x03, 0x60, 0x0b, 0x03, 0x03, + 0x68, 0x0b, 0x03, 0x03, 0x40, 0x28, 0x04, 0x04, 0x50, 0x28, 0x04, 0x04, 0x80, 0x07, 0x05, 0x04, 0x90, 0x07, 0x05, 0x04, 0x60, 0x23, 0x06, 0x05, 0x00, 0x1b, 0x08, 0x06, 0x00, 0x3c, 0x0b, 0x08, + 0x08, 0x1f, 0x00, 0x03, 0x10, 0x1f, 0x00, 0x03, 0x18, 0x1f, 0x00, 0x03, 0x20, 0x1f, 0x00, 0x03, 0xf8, 0x0e, 0x01, 0x02, 0xfc, 0x0e, 0x01, 0x02, 0x00, 0x0f, 0x01, 0x02, 0x04, 0x0f, 0x01, 0x02, + 0x08, 0x0f, 0x01, 0x02, 0x0c, 0x0f, 0x01, 0x02, 0xa0, 0x2d, 0x02, 0x03, 0xa8, 0x2d, 0x02, 0x03, 0xb0, 0x2d, 0x02, 0x03, 0xb8, 0x2d, 0x02, 0x03, 0x70, 0x0b, 0x03, 0x03, 0x78, 0x0b, 0x03, 0x03, + 0x80, 0x0b, 0x03, 0x03, 0x60, 0x28, 0x04, 0x04, 0x70, 0x28, 0x04, 0x04, 0xa0, 0x07, 0x05, 0x04, 0xb0, 0x07, 0x05, 0x04, 0x80, 0x23, 0x06, 0x05, 0x40, 0x1b, 0x08, 0x06, 0x00, 0x3d, 0x0b, 0x08, + 0x28, 0x1f, 0x00, 0x03, 0x30, 0x1f, 0x00, 0x03, 0x38, 0x1f, 0x00, 0x03, 0x40, 0x1f, 0x00, 0x03, 0x10, 0x0f, 0x01, 0x02, 0x14, 0x0f, 0x01, 0x02, 0x18, 0x0f, 0x01, 0x02, 0x1c, 0x0f, 0x01, 0x02, + 0x20, 0x0f, 0x01, 0x02, 0x24, 0x0f, 0x01, 0x02, 0xc0, 0x2d, 0x02, 0x03, 0xc8, 0x2d, 0x02, 0x03, 0xd0, 0x2d, 0x02, 0x03, 0xd8, 0x2d, 0x02, 0x03, 0x88, 0x0b, 0x03, 0x03, 0x90, 0x0b, 0x03, 0x03, + 0x98, 0x0b, 0x03, 0x03, 0x80, 0x28, 0x04, 0x04, 0x90, 0x28, 0x04, 0x04, 0xc0, 0x07, 0x05, 0x04, 0xd0, 0x07, 0x05, 0x04, 0xa0, 0x23, 0x06, 0x05, 0x80, 0x1b, 0x08, 0x06, 0x00, 0x3e, 0x0b, 0x08, + 0x48, 0x1f, 0x00, 0x03, 0x50, 0x1f, 0x00, 0x03, 0x58, 0x1f, 0x00, 0x03, 0x60, 0x1f, 0x00, 0x03, 0x28, 0x0f, 0x01, 0x02, 0x2c, 0x0f, 0x01, 0x02, 0x30, 0x0f, 0x01, 0x02, 0x34, 0x0f, 0x01, 0x02, + 0x38, 0x0f, 0x01, 0x02, 0x3c, 0x0f, 0x01, 0x02, 0xe0, 0x2d, 0x02, 0x03, 0xe8, 0x2d, 0x02, 0x03, 0xf0, 0x2d, 0x02, 0x03, 0xf8, 0x2d, 0x02, 0x03, 0xa0, 0x0b, 0x03, 0x03, 0xa8, 0x0b, 0x03, 0x03, + 0xb0, 0x0b, 0x03, 0x03, 0xa0, 0x28, 0x04, 0x04, 0xb0, 0x28, 0x04, 0x04, 0xe0, 0x07, 0x05, 0x04, 0xf0, 0x07, 0x05, 0x04, 0xc0, 0x23, 0x06, 0x05, 0xc0, 0x1b, 0x08, 0x06, 0x00, 0x3f, 0x0b, 0x08, + 0x68, 0x1f, 0x00, 0x03, 0x70, 0x1f, 0x00, 0x03, 0x78, 0x1f, 0x00, 0x03, 0x80, 0x1f, 0x00, 0x03, 0x40, 0x0f, 0x01, 0x02, 0x44, 0x0f, 0x01, 0x02, 0x48, 0x0f, 0x01, 0x02, 0x4c, 0x0f, 0x01, 0x02, + 0x50, 0x0f, 0x01, 0x02, 0x54, 0x0f, 0x01, 0x02, 0x00, 0x2e, 0x02, 0x03, 0x08, 0x2e, 0x02, 0x03, 0x10, 0x2e, 0x02, 0x03, 0x18, 0x2e, 0x02, 0x03, 0xb8, 0x0b, 0x03, 0x03, 0xc0, 0x0b, 0x03, 0x03, + 0xc8, 0x0b, 0x03, 0x03, 0xc0, 0x28, 0x04, 0x04, 0xd0, 0x28, 0x04, 0x04, 0x00, 0x08, 0x05, 0x04, 0x10, 0x08, 0x05, 0x04, 0xe0, 0x23, 0x06, 0x05, 0x00, 0x1c, 0x08, 0x06, 0x00, 0x00, 0x0b, 0x07, + 0x88, 0x1f, 0x00, 0x03, 0x90, 0x1f, 0x00, 0x03, 0x98, 0x1f, 0x00, 0x03, 0xa0, 0x1f, 0x00, 0x03, 0x58, 0x0f, 0x01, 0x02, 0x5c, 0x0f, 0x01, 0x02, 0x60, 0x0f, 0x01, 0x02, 0x64, 0x0f, 0x01, 0x02, + 0x68, 0x0f, 0x01, 0x02, 0x6c, 0x0f, 0x01, 0x02, 0x20, 0x2e, 0x02, 0x03, 0x28, 0x2e, 0x02, 0x03, 0x30, 0x2e, 0x02, 0x03, 0x38, 0x2e, 0x02, 0x03, 0xd0, 0x0b, 0x03, 0x03, 0xd8, 0x0b, 0x03, 0x03, + 0xe0, 0x0b, 0x03, 0x03, 0xe0, 0x28, 0x04, 0x04, 0xf0, 0x28, 0x04, 0x04, 0x20, 0x08, 0x05, 0x04, 0x30, 0x08, 0x05, 0x04, 0x00, 0x24, 0x06, 0x05, 0x40, 0x1c, 0x08, 0x06, 0x80, 0x00, 0x0b, 0x07, + 0xa8, 0x1f, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x03, 0xb8, 0x1f, 0x00, 0x03, 0xc0, 0x1f, 0x00, 0x03, 0x70, 0x0f, 0x01, 0x02, 0x74, 0x0f, 0x01, 0x02, 0x78, 0x0f, 0x01, 0x02, 0x7c, 0x0f, 0x01, 0x02, + 0x80, 0x0f, 0x01, 0x02, 0x84, 0x0f, 0x01, 0x02, 0x40, 0x2e, 0x02, 0x03, 0x48, 0x2e, 0x02, 0x03, 0x50, 0x2e, 0x02, 0x03, 0x58, 0x2e, 0x02, 0x03, 0xe8, 0x0b, 0x03, 0x03, 0xf0, 0x0b, 0x03, 0x03, + 0xf8, 0x0b, 0x03, 0x03, 0x00, 0x29, 0x04, 0x04, 0x10, 0x29, 0x04, 0x04, 0x40, 0x08, 0x05, 0x04, 0x50, 0x08, 0x05, 0x04, 0x20, 0x24, 0x06, 0x05, 0x80, 0x1c, 0x08, 0x06, 0x00, 0x11, 0x0c, 0x08, + 0xc8, 0x1f, 0x00, 0x03, 0xd0, 0x1f, 0x00, 0x03, 0xd8, 0x1f, 0x00, 0x03, 0xe0, 0x1f, 0x00, 0x03, 0x88, 0x0f, 0x01, 0x02, 0x8c, 0x0f, 0x01, 0x02, 0x90, 0x0f, 0x01, 0x02, 0x94, 0x0f, 0x01, 0x02, + 0x98, 0x0f, 0x01, 0x02, 0x9c, 0x0f, 0x01, 0x02, 0x60, 0x2e, 0x02, 0x03, 0x68, 0x2e, 0x02, 0x03, 0x70, 0x2e, 0x02, 0x03, 0x78, 0x2e, 0x02, 0x03, 0x00, 0x0c, 0x03, 0x03, 0x08, 0x0c, 0x03, 0x03, + 0x10, 0x0c, 0x03, 0x03, 0x20, 0x29, 0x04, 0x04, 0x30, 0x29, 0x04, 0x04, 0x60, 0x08, 0x05, 0x04, 0x70, 0x08, 0x05, 0x04, 0x40, 0x24, 0x06, 0x05, 0xc0, 0x1c, 0x08, 0x06, 0x00, 0x12, 0x0c, 0x08, + 0xe8, 0x1f, 0x00, 0x03, 0xf0, 0x1f, 0x00, 0x03, 0xf8, 0x1f, 0x00, 0x03, 0x00, 0x20, 0x00, 0x03, 0xa0, 0x0f, 0x01, 0x02, 0xa4, 0x0f, 0x01, 0x02, 0xa8, 0x0f, 0x01, 0x02, 0xac, 0x0f, 0x01, 0x02, + 0xb0, 0x0f, 0x01, 0x02, 0xb4, 0x0f, 0x01, 0x02, 0x80, 0x2e, 0x02, 0x03, 0x88, 0x2e, 0x02, 0x03, 0x90, 0x2e, 0x02, 0x03, 0x98, 0x2e, 0x02, 0x03, 0x18, 0x0c, 0x03, 0x03, 0x20, 0x0c, 0x03, 0x03, + 0x28, 0x0c, 0x03, 0x03, 0x40, 0x29, 0x04, 0x04, 0x50, 0x29, 0x04, 0x04, 0x80, 0x08, 0x05, 0x04, 0x90, 0x08, 0x05, 0x04, 0x60, 0x24, 0x06, 0x05, 0x00, 0x1d, 0x08, 0x06, 0x00, 0x13, 0x0c, 0x08, + 0x08, 0x20, 0x00, 0x03, 0x10, 0x20, 0x00, 0x03, 0x18, 0x20, 0x00, 0x03, 0x20, 0x20, 0x00, 0x03, 0xb8, 0x0f, 0x01, 0x02, 0xbc, 0x0f, 0x01, 0x02, 0xc0, 0x0f, 0x01, 0x02, 0xc4, 0x0f, 0x01, 0x02, + 0xc8, 0x0f, 0x01, 0x02, 0xcc, 0x0f, 0x01, 0x02, 0xa0, 0x2e, 0x02, 0x03, 0xa8, 0x2e, 0x02, 0x03, 0xb0, 0x2e, 0x02, 0x03, 0xb8, 0x2e, 0x02, 0x03, 0x30, 0x0c, 0x03, 0x03, 0x38, 0x0c, 0x03, 0x03, + 0x40, 0x0c, 0x03, 0x03, 0x60, 0x29, 0x04, 0x04, 0x70, 0x29, 0x04, 0x04, 0xa0, 0x08, 0x05, 0x04, 0xb0, 0x08, 0x05, 0x04, 0x80, 0x24, 0x06, 0x05, 0x40, 0x1d, 0x08, 0x06, 0x00, 0x14, 0x0c, 0x08, + 0x28, 0x20, 0x00, 0x03, 0x30, 0x20, 0x00, 0x03, 0x38, 0x20, 0x00, 0x03, 0x40, 0x20, 0x00, 0x03, 0xd0, 0x0f, 0x01, 0x02, 0xd4, 0x0f, 0x01, 0x02, 0xd8, 0x0f, 0x01, 0x02, 0xdc, 0x0f, 0x01, 0x02, + 0xe0, 0x0f, 0x01, 0x02, 0xe4, 0x0f, 0x01, 0x02, 0xc0, 0x2e, 0x02, 0x03, 0xc8, 0x2e, 0x02, 0x03, 0xd0, 0x2e, 0x02, 0x03, 0xd8, 0x2e, 0x02, 0x03, 0x48, 0x0c, 0x03, 0x03, 0x50, 0x0c, 0x03, 0x03, + 0x58, 0x0c, 0x03, 0x03, 0x80, 0x29, 0x04, 0x04, 0x90, 0x29, 0x04, 0x04, 0xc0, 0x08, 0x05, 0x04, 0xd0, 0x08, 0x05, 0x04, 0xa0, 0x24, 0x06, 0x05, 0x80, 0x1d, 0x08, 0x06, 0x00, 0x15, 0x0c, 0x08, + 0x48, 0x20, 0x00, 0x03, 0x50, 0x20, 0x00, 0x03, 0x58, 0x20, 0x00, 0x03, 0x60, 0x20, 0x00, 0x03, 0xe8, 0x0f, 0x01, 0x02, 0xec, 0x0f, 0x01, 0x02, 0xf0, 0x0f, 0x01, 0x02, 0xf4, 0x0f, 0x01, 0x02, + 0xf8, 0x0f, 0x01, 0x02, 0xfc, 0x0f, 0x01, 0x02, 0xe0, 0x2e, 0x02, 0x03, 0xe8, 0x2e, 0x02, 0x03, 0xf0, 0x2e, 0x02, 0x03, 0xf8, 0x2e, 0x02, 0x03, 0x60, 0x0c, 0x03, 0x03, 0x68, 0x0c, 0x03, 0x03, + 0x70, 0x0c, 0x03, 0x03, 0xa0, 0x29, 0x04, 0x04, 0xb0, 0x29, 0x04, 0x04, 0xe0, 0x08, 0x05, 0x04, 0xf0, 0x08, 0x05, 0x04, 0xc0, 0x24, 0x06, 0x05, 0xc0, 0x1d, 0x08, 0x06, 0x00, 0x16, 0x0c, 0x08, + 0x68, 0x20, 0x00, 0x03, 0x70, 0x20, 0x00, 0x03, 0x78, 0x20, 0x00, 0x03, 0x80, 0x20, 0x00, 0x03, 0x00, 0x10, 0x01, 0x02, 0x04, 0x10, 0x01, 0x02, 0x08, 0x10, 0x01, 0x02, 0x0c, 0x10, 0x01, 0x02, + 0x10, 0x10, 0x01, 0x02, 0x14, 0x10, 0x01, 0x02, 0x00, 0x2f, 0x02, 0x03, 0x08, 0x2f, 0x02, 0x03, 0x10, 0x2f, 0x02, 0x03, 0x18, 0x2f, 0x02, 0x03, 0x78, 0x0c, 0x03, 0x03, 0x80, 0x0c, 0x03, 0x03, + 0x88, 0x0c, 0x03, 0x03, 0xc0, 0x29, 0x04, 0x04, 0xd0, 0x29, 0x04, 0x04, 0x00, 0x09, 0x05, 0x04, 0x10, 0x09, 0x05, 0x04, 0xe0, 0x24, 0x06, 0x05, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x17, 0x0c, 0x08, + 0x88, 0x20, 0x00, 0x03, 0x90, 0x20, 0x00, 0x03, 0x98, 0x20, 0x00, 0x03, 0xa0, 0x20, 0x00, 0x03, 0x18, 0x10, 0x01, 0x02, 0x1c, 0x10, 0x01, 0x02, 0x20, 0x10, 0x01, 0x02, 0x24, 0x10, 0x01, 0x02, + 0x28, 0x10, 0x01, 0x02, 0x2c, 0x10, 0x01, 0x02, 0x20, 0x2f, 0x02, 0x03, 0x28, 0x2f, 0x02, 0x03, 0x30, 0x2f, 0x02, 0x03, 0x38, 0x2f, 0x02, 0x03, 0x90, 0x0c, 0x03, 0x03, 0x98, 0x0c, 0x03, 0x03, + 0xa0, 0x0c, 0x03, 0x03, 0xe0, 0x29, 0x04, 0x04, 0xf0, 0x29, 0x04, 0x04, 0x20, 0x09, 0x05, 0x04, 0x30, 0x09, 0x05, 0x04, 0x00, 0x25, 0x06, 0x05, 0x40, 0x1e, 0x08, 0x06, 0x00, 0x18, 0x0c, 0x08, + 0xa8, 0x20, 0x00, 0x03, 0xb0, 0x20, 0x00, 0x03, 0xb8, 0x20, 0x00, 0x03, 0xc0, 0x20, 0x00, 0x03, 0x30, 0x10, 0x01, 0x02, 0x34, 0x10, 0x01, 0x02, 0x38, 0x10, 0x01, 0x02, 0x3c, 0x10, 0x01, 0x02, + 0x40, 0x10, 0x01, 0x02, 0x44, 0x10, 0x01, 0x02, 0x40, 0x2f, 0x02, 0x03, 0x48, 0x2f, 0x02, 0x03, 0x50, 0x2f, 0x02, 0x03, 0x58, 0x2f, 0x02, 0x03, 0xa8, 0x0c, 0x03, 0x03, 0xb0, 0x0c, 0x03, 0x03, + 0xb8, 0x0c, 0x03, 0x03, 0x00, 0x2a, 0x04, 0x04, 0x10, 0x2a, 0x04, 0x04, 0x40, 0x09, 0x05, 0x04, 0x50, 0x09, 0x05, 0x04, 0x20, 0x25, 0x06, 0x05, 0x80, 0x1e, 0x08, 0x06, 0x00, 0x19, 0x0c, 0x08, + 0xc8, 0x20, 0x00, 0x03, 0xd0, 0x20, 0x00, 0x03, 0xd8, 0x20, 0x00, 0x03, 0x48, 0x10, 0x01, 0x02, 0x4c, 0x10, 0x01, 0x02, 0x50, 0x10, 0x01, 0x02, 0x54, 0x10, 0x01, 0x02, 0x58, 0x10, 0x01, 0x02, + 0x5c, 0x10, 0x01, 0x02, 0x60, 0x10, 0x01, 0x02, 0x60, 0x2f, 0x02, 0x03, 0x68, 0x2f, 0x02, 0x03, 0x70, 0x2f, 0x02, 0x03, 0x78, 0x2f, 0x02, 0x03, 0xc0, 0x0c, 0x03, 0x03, 0xc8, 0x0c, 0x03, 0x03, + 0xd0, 0x0c, 0x03, 0x03, 0x20, 0x2a, 0x04, 0x04, 0x30, 0x2a, 0x04, 0x04, 0x60, 0x09, 0x05, 0x04, 0x70, 0x09, 0x05, 0x04, 0x40, 0x25, 0x06, 0x05, 0xc0, 0x1e, 0x08, 0x06, 0x00, 0x30, 0x0d, 0x09, + 0xe0, 0x20, 0x00, 0x03, 0xe8, 0x20, 0x00, 0x03, 0xf0, 0x20, 0x00, 0x03, 0x64, 0x10, 0x01, 0x02, 0x68, 0x10, 0x01, 0x02, 0x6c, 0x10, 0x01, 0x02, 0x70, 0x10, 0x01, 0x02, 0x74, 0x10, 0x01, 0x02, + 0x78, 0x10, 0x01, 0x02, 0x7c, 0x10, 0x01, 0x02, 0x80, 0x2f, 0x02, 0x03, 0x88, 0x2f, 0x02, 0x03, 0x90, 0x2f, 0x02, 0x03, 0x98, 0x2f, 0x02, 0x03, 0xd8, 0x0c, 0x03, 0x03, 0xe0, 0x0c, 0x03, 0x03, + 0xe8, 0x0c, 0x03, 0x03, 0x40, 0x2a, 0x04, 0x04, 0x50, 0x2a, 0x04, 0x04, 0x80, 0x09, 0x05, 0x04, 0x90, 0x09, 0x05, 0x04, 0x60, 0x25, 0x06, 0x05, 0x00, 0x1f, 0x08, 0x06, 0x00, 0x32, 0x0d, 0x09, + 0xf8, 0x20, 0x00, 0x03, 0x00, 0x21, 0x00, 0x03, 0x08, 0x21, 0x00, 0x03, 0x80, 0x10, 0x01, 0x02, 0x84, 0x10, 0x01, 0x02, 0x88, 0x10, 0x01, 0x02, 0x8c, 0x10, 0x01, 0x02, 0x90, 0x10, 0x01, 0x02, + 0x94, 0x10, 0x01, 0x02, 0x98, 0x10, 0x01, 0x02, 0xa0, 0x2f, 0x02, 0x03, 0xa8, 0x2f, 0x02, 0x03, 0xb0, 0x2f, 0x02, 0x03, 0xb8, 0x2f, 0x02, 0x03, 0xf0, 0x0c, 0x03, 0x03, 0xf8, 0x0c, 0x03, 0x03, + 0x00, 0x0d, 0x03, 0x03, 0x60, 0x2a, 0x04, 0x04, 0x70, 0x2a, 0x04, 0x04, 0xa0, 0x09, 0x05, 0x04, 0xb0, 0x09, 0x05, 0x04, 0x80, 0x25, 0x06, 0x05, 0x40, 0x1f, 0x08, 0x06, 0x00, 0x34, 0x0d, 0x09, + 0x10, 0x21, 0x00, 0x03, 0x18, 0x21, 0x00, 0x03, 0x20, 0x21, 0x00, 0x03, 0x9c, 0x10, 0x01, 0x02, 0xa0, 0x10, 0x01, 0x02, 0xa4, 0x10, 0x01, 0x02, 0xa8, 0x10, 0x01, 0x02, 0xac, 0x10, 0x01, 0x02, + 0xb0, 0x10, 0x01, 0x02, 0xb4, 0x10, 0x01, 0x02, 0xc0, 0x2f, 0x02, 0x03, 0xc8, 0x2f, 0x02, 0x03, 0xd0, 0x2f, 0x02, 0x03, 0xd8, 0x2f, 0x02, 0x03, 0x08, 0x0d, 0x03, 0x03, 0x10, 0x0d, 0x03, 0x03, + 0x18, 0x0d, 0x03, 0x03, 0x80, 0x2a, 0x04, 0x04, 0x90, 0x2a, 0x04, 0x04, 0xc0, 0x09, 0x05, 0x04, 0xd0, 0x09, 0x05, 0x04, 0xa0, 0x25, 0x06, 0x05, 0x80, 0x1f, 0x08, 0x06, 0x00, 0x36, 0x0d, 0x09, + 0x28, 0x21, 0x00, 0x03, 0x30, 0x21, 0x00, 0x03, 0x38, 0x21, 0x00, 0x03, 0xb8, 0x10, 0x01, 0x02, 0xbc, 0x10, 0x01, 0x02, 0xc0, 0x10, 0x01, 0x02, 0xc4, 0x10, 0x01, 0x02, 0xc8, 0x10, 0x01, 0x02, + 0xcc, 0x10, 0x01, 0x02, 0xd0, 0x10, 0x01, 0x02, 0xe0, 0x2f, 0x02, 0x03, 0xe8, 0x2f, 0x02, 0x03, 0xf0, 0x2f, 0x02, 0x03, 0xf8, 0x2f, 0x02, 0x03, 0x20, 0x0d, 0x03, 0x03, 0x28, 0x0d, 0x03, 0x03, + 0x30, 0x0d, 0x03, 0x03, 0xa0, 0x2a, 0x04, 0x04, 0xb0, 0x2a, 0x04, 0x04, 0xe0, 0x09, 0x05, 0x04, 0xf0, 0x09, 0x05, 0x04, 0x80, 0x05, 0x07, 0x05, 0xc0, 0x1f, 0x08, 0x06, 0x00, 0x38, 0x0d, 0x09, + 0x40, 0x21, 0x00, 0x03, 0x48, 0x21, 0x00, 0x03, 0x50, 0x21, 0x00, 0x03, 0xd4, 0x10, 0x01, 0x02, 0xd8, 0x10, 0x01, 0x02, 0xdc, 0x10, 0x01, 0x02, 0xe0, 0x10, 0x01, 0x02, 0xe4, 0x10, 0x01, 0x02, + 0xe8, 0x10, 0x01, 0x02, 0xec, 0x10, 0x01, 0x02, 0x00, 0x30, 0x02, 0x03, 0x08, 0x30, 0x02, 0x03, 0x10, 0x30, 0x02, 0x03, 0x18, 0x30, 0x02, 0x03, 0x38, 0x0d, 0x03, 0x03, 0x40, 0x0d, 0x03, 0x03, + 0x48, 0x0d, 0x03, 0x03, 0xc0, 0x2a, 0x04, 0x04, 0xd0, 0x2a, 0x04, 0x04, 0x00, 0x0a, 0x05, 0x04, 0xc0, 0x25, 0x06, 0x05, 0xa0, 0x05, 0x07, 0x05, 0x00, 0x20, 0x08, 0x06, 0x00, 0x3a, 0x0d, 0x09, + 0x58, 0x21, 0x00, 0x03, 0x60, 0x21, 0x00, 0x03, 0x68, 0x21, 0x00, 0x03, 0xf0, 0x10, 0x01, 0x02, 0xf4, 0x10, 0x01, 0x02, 0xf8, 0x10, 0x01, 0x02, 0xfc, 0x10, 0x01, 0x02, 0x00, 0x11, 0x01, 0x02, + 0x04, 0x11, 0x01, 0x02, 0x08, 0x11, 0x01, 0x02, 0x20, 0x30, 0x02, 0x03, 0x28, 0x30, 0x02, 0x03, 0x30, 0x30, 0x02, 0x03, 0x38, 0x30, 0x02, 0x03, 0x50, 0x0d, 0x03, 0x03, 0x58, 0x0d, 0x03, 0x03, + 0x60, 0x0d, 0x03, 0x03, 0xe0, 0x2a, 0x04, 0x04, 0xf0, 0x2a, 0x04, 0x04, 0x10, 0x0a, 0x05, 0x04, 0xe0, 0x25, 0x06, 0x05, 0xc0, 0x05, 0x07, 0x05, 0x40, 0x20, 0x08, 0x06, 0x00, 0x3c, 0x0d, 0x09, + 0x70, 0x21, 0x00, 0x03, 0x78, 0x21, 0x00, 0x03, 0x80, 0x21, 0x00, 0x03, 0x0c, 0x11, 0x01, 0x02, 0x10, 0x11, 0x01, 0x02, 0x14, 0x11, 0x01, 0x02, 0x18, 0x11, 0x01, 0x02, 0x1c, 0x11, 0x01, 0x02, + 0x20, 0x11, 0x01, 0x02, 0x24, 0x11, 0x01, 0x02, 0x40, 0x30, 0x02, 0x03, 0x48, 0x30, 0x02, 0x03, 0x50, 0x30, 0x02, 0x03, 0x58, 0x30, 0x02, 0x03, 0x68, 0x0d, 0x03, 0x03, 0x70, 0x0d, 0x03, 0x03, + 0x78, 0x0d, 0x03, 0x03, 0x00, 0x2b, 0x04, 0x04, 0x10, 0x2b, 0x04, 0x04, 0x20, 0x0a, 0x05, 0x04, 0x00, 0x26, 0x06, 0x05, 0xe0, 0x05, 0x07, 0x05, 0x80, 0x20, 0x08, 0x06, 0x00, 0x0e, 0x0e, 0x09, + 0x88, 0x21, 0x00, 0x03, 0x90, 0x21, 0x00, 0x03, 0x98, 0x21, 0x00, 0x03, 0x28, 0x11, 0x01, 0x02, 0x2c, 0x11, 0x01, 0x02, 0x30, 0x11, 0x01, 0x02, 0x34, 0x11, 0x01, 0x02, 0x38, 0x11, 0x01, 0x02, + 0x3c, 0x11, 0x01, 0x02, 0x40, 0x11, 0x01, 0x02, 0x60, 0x30, 0x02, 0x03, 0x68, 0x30, 0x02, 0x03, 0x70, 0x30, 0x02, 0x03, 0x78, 0x30, 0x02, 0x03, 0x80, 0x0d, 0x03, 0x03, 0x88, 0x0d, 0x03, 0x03, + 0x90, 0x0d, 0x03, 0x03, 0x20, 0x2b, 0x04, 0x04, 0x30, 0x2b, 0x04, 0x04, 0x30, 0x0a, 0x05, 0x04, 0x20, 0x26, 0x06, 0x05, 0x00, 0x06, 0x07, 0x05, 0xc0, 0x20, 0x08, 0x06, 0x00, 0x10, 0x0e, 0x09, + 0xa0, 0x21, 0x00, 0x03, 0xa8, 0x21, 0x00, 0x03, 0xb0, 0x21, 0x00, 0x03, 0x44, 0x11, 0x01, 0x02, 0x48, 0x11, 0x01, 0x02, 0x4c, 0x11, 0x01, 0x02, 0x50, 0x11, 0x01, 0x02, 0x54, 0x11, 0x01, 0x02, + 0x58, 0x11, 0x01, 0x02, 0x5c, 0x11, 0x01, 0x02, 0x80, 0x30, 0x02, 0x03, 0x88, 0x30, 0x02, 0x03, 0x90, 0x30, 0x02, 0x03, 0x98, 0x30, 0x02, 0x03, 0x98, 0x0d, 0x03, 0x03, 0xa0, 0x0d, 0x03, 0x03, + 0xa8, 0x0d, 0x03, 0x03, 0x40, 0x2b, 0x04, 0x04, 0x50, 0x2b, 0x04, 0x04, 0x40, 0x0a, 0x05, 0x04, 0x40, 0x26, 0x06, 0x05, 0x20, 0x06, 0x07, 0x05, 0x00, 0x21, 0x08, 0x06, 0x00, 0x12, 0x0e, 0x09, + 0xb8, 0x21, 0x00, 0x03, 0xc0, 0x21, 0x00, 0x03, 0xc8, 0x21, 0x00, 0x03, 0x60, 0x11, 0x01, 0x02, 0x64, 0x11, 0x01, 0x02, 0x68, 0x11, 0x01, 0x02, 0x6c, 0x11, 0x01, 0x02, 0x70, 0x11, 0x01, 0x02, + 0x74, 0x11, 0x01, 0x02, 0x78, 0x11, 0x01, 0x02, 0xa0, 0x30, 0x02, 0x03, 0xa8, 0x30, 0x02, 0x03, 0xb0, 0x30, 0x02, 0x03, 0xb8, 0x30, 0x02, 0x03, 0xb0, 0x0d, 0x03, 0x03, 0xb8, 0x0d, 0x03, 0x03, + 0xc0, 0x0d, 0x03, 0x03, 0x60, 0x2b, 0x04, 0x04, 0x70, 0x2b, 0x04, 0x04, 0x50, 0x0a, 0x05, 0x04, 0x60, 0x26, 0x06, 0x05, 0x40, 0x06, 0x07, 0x05, 0x40, 0x21, 0x08, 0x06, 0x00, 0x14, 0x0e, 0x09, + 0xd0, 0x21, 0x00, 0x03, 0xd8, 0x21, 0x00, 0x03, 0xe0, 0x21, 0x00, 0x03, 0x7c, 0x11, 0x01, 0x02, 0x80, 0x11, 0x01, 0x02, 0x84, 0x11, 0x01, 0x02, 0x88, 0x11, 0x01, 0x02, 0x8c, 0x11, 0x01, 0x02, + 0x90, 0x11, 0x01, 0x02, 0x94, 0x11, 0x01, 0x02, 0xc0, 0x30, 0x02, 0x03, 0xc8, 0x30, 0x02, 0x03, 0xd0, 0x30, 0x02, 0x03, 0xd8, 0x30, 0x02, 0x03, 0xc8, 0x0d, 0x03, 0x03, 0xd0, 0x0d, 0x03, 0x03, + 0xd8, 0x0d, 0x03, 0x03, 0x80, 0x2b, 0x04, 0x04, 0x90, 0x2b, 0x04, 0x04, 0x60, 0x0a, 0x05, 0x04, 0x80, 0x26, 0x06, 0x05, 0x60, 0x06, 0x07, 0x05, 0x80, 0x21, 0x08, 0x06, 0x00, 0x2c, 0x0f, 0x0a, + 0xe8, 0x21, 0x00, 0x03, 0xf0, 0x21, 0x00, 0x03, 0xf8, 0x21, 0x00, 0x03, 0x98, 0x11, 0x01, 0x02, 0x9c, 0x11, 0x01, 0x02, 0xa0, 0x11, 0x01, 0x02, 0xa4, 0x11, 0x01, 0x02, 0xa8, 0x11, 0x01, 0x02, + 0xac, 0x11, 0x01, 0x02, 0xb0, 0x11, 0x01, 0x02, 0xe0, 0x30, 0x02, 0x03, 0xe8, 0x30, 0x02, 0x03, 0xf0, 0x30, 0x02, 0x03, 0xf8, 0x30, 0x02, 0x03, 0xe0, 0x0d, 0x03, 0x03, 0xe8, 0x0d, 0x03, 0x03, + 0xf0, 0x0d, 0x03, 0x03, 0xa0, 0x2b, 0x04, 0x04, 0xb0, 0x2b, 0x04, 0x04, 0x70, 0x0a, 0x05, 0x04, 0xa0, 0x26, 0x06, 0x05, 0x80, 0x06, 0x07, 0x05, 0xc0, 0x21, 0x08, 0x06, 0x00, 0x30, 0x0f, 0x0a, + 0x00, 0x22, 0x00, 0x03, 0x08, 0x22, 0x00, 0x03, 0x10, 0x22, 0x00, 0x03, 0xb4, 0x11, 0x01, 0x02, 0xb8, 0x11, 0x01, 0x02, 0xbc, 0x11, 0x01, 0x02, 0xc0, 0x11, 0x01, 0x02, 0xc4, 0x11, 0x01, 0x02, + 0xc8, 0x11, 0x01, 0x02, 0xcc, 0x11, 0x01, 0x02, 0x00, 0x31, 0x02, 0x03, 0x08, 0x31, 0x02, 0x03, 0x10, 0x31, 0x02, 0x03, 0x18, 0x31, 0x02, 0x03, 0xf8, 0x0d, 0x03, 0x03, 0x00, 0x0e, 0x03, 0x03, + 0x08, 0x0e, 0x03, 0x03, 0xc0, 0x2b, 0x04, 0x04, 0xd0, 0x2b, 0x04, 0x04, 0x80, 0x0a, 0x05, 0x04, 0xc0, 0x26, 0x06, 0x05, 0xa0, 0x06, 0x07, 0x05, 0x00, 0x22, 0x08, 0x06, 0x00, 0x34, 0x0f, 0x0a, + 0x18, 0x22, 0x00, 0x03, 0x20, 0x22, 0x00, 0x03, 0x28, 0x22, 0x00, 0x03, 0xd0, 0x11, 0x01, 0x02, 0xd4, 0x11, 0x01, 0x02, 0xd8, 0x11, 0x01, 0x02, 0xdc, 0x11, 0x01, 0x02, 0xe0, 0x11, 0x01, 0x02, + 0xe4, 0x11, 0x01, 0x02, 0xe8, 0x11, 0x01, 0x02, 0x20, 0x31, 0x02, 0x03, 0x28, 0x31, 0x02, 0x03, 0x30, 0x31, 0x02, 0x03, 0x38, 0x31, 0x02, 0x03, 0x10, 0x0e, 0x03, 0x03, 0x18, 0x0e, 0x03, 0x03, + 0x20, 0x0e, 0x03, 0x03, 0xe0, 0x2b, 0x04, 0x04, 0xf0, 0x2b, 0x04, 0x04, 0x90, 0x0a, 0x05, 0x04, 0xe0, 0x26, 0x06, 0x05, 0xc0, 0x06, 0x07, 0x05, 0x40, 0x22, 0x08, 0x06, 0x00, 0x08, 0x10, 0x0a, + 0x30, 0x22, 0x00, 0x03, 0x38, 0x22, 0x00, 0x03, 0x40, 0x22, 0x00, 0x03, 0xec, 0x11, 0x01, 0x02, 0xf0, 0x11, 0x01, 0x02, 0xf4, 0x11, 0x01, 0x02, 0xf8, 0x11, 0x01, 0x02, 0xfc, 0x11, 0x01, 0x02, + 0x00, 0x12, 0x01, 0x02, 0x04, 0x12, 0x01, 0x02, 0x40, 0x31, 0x02, 0x03, 0x48, 0x31, 0x02, 0x03, 0x50, 0x31, 0x02, 0x03, 0x58, 0x31, 0x02, 0x03, 0x28, 0x0e, 0x03, 0x03, 0x30, 0x0e, 0x03, 0x03, + 0x38, 0x0e, 0x03, 0x03, 0x00, 0x2c, 0x04, 0x04, 0x10, 0x2c, 0x04, 0x04, 0xa0, 0x0a, 0x05, 0x04, 0x00, 0x27, 0x06, 0x05, 0xe0, 0x06, 0x07, 0x05, 0x80, 0x22, 0x08, 0x06, 0x00, 0x0c, 0x10, 0x0a, + 0x48, 0x22, 0x00, 0x03, 0x50, 0x22, 0x00, 0x03, 0x58, 0x22, 0x00, 0x03, 0x08, 0x12, 0x01, 0x02, 0x0c, 0x12, 0x01, 0x02, 0x10, 0x12, 0x01, 0x02, 0x14, 0x12, 0x01, 0x02, 0x18, 0x12, 0x01, 0x02, + 0x1c, 0x12, 0x01, 0x02, 0x20, 0x12, 0x01, 0x02, 0x60, 0x31, 0x02, 0x03, 0x68, 0x31, 0x02, 0x03, 0x70, 0x31, 0x02, 0x03, 0x78, 0x31, 0x02, 0x03, 0x40, 0x0e, 0x03, 0x03, 0x48, 0x0e, 0x03, 0x03, + 0x50, 0x0e, 0x03, 0x03, 0x20, 0x2c, 0x04, 0x04, 0x30, 0x2c, 0x04, 0x04, 0xb0, 0x0a, 0x05, 0x04, 0x20, 0x27, 0x06, 0x05, 0x00, 0x07, 0x07, 0x05, 0xc0, 0x22, 0x08, 0x06, 0x00, 0x10, 0x10, 0x0a, + 0x60, 0x22, 0x00, 0x03, 0x68, 0x22, 0x00, 0x03, 0x70, 0x22, 0x00, 0x03, 0x24, 0x12, 0x01, 0x02, 0x28, 0x12, 0x01, 0x02, 0x2c, 0x12, 0x01, 0x02, 0x30, 0x12, 0x01, 0x02, 0x34, 0x12, 0x01, 0x02, + 0x38, 0x12, 0x01, 0x02, 0x3c, 0x12, 0x01, 0x02, 0x80, 0x31, 0x02, 0x03, 0x88, 0x31, 0x02, 0x03, 0x90, 0x31, 0x02, 0x03, 0x98, 0x31, 0x02, 0x03, 0x58, 0x0e, 0x03, 0x03, 0x60, 0x0e, 0x03, 0x03, + 0x68, 0x0e, 0x03, 0x03, 0x40, 0x2c, 0x04, 0x04, 0x50, 0x2c, 0x04, 0x04, 0xc0, 0x0a, 0x05, 0x04, 0x40, 0x27, 0x06, 0x05, 0x20, 0x07, 0x07, 0x05, 0x40, 0x03, 0x09, 0x06, 0x00, 0x28, 0x11, 0x0b, + 0x78, 0x22, 0x00, 0x03, 0x80, 0x22, 0x00, 0x03, 0x88, 0x22, 0x00, 0x03, 0x40, 0x12, 0x01, 0x02, 0x44, 0x12, 0x01, 0x02, 0x48, 0x12, 0x01, 0x02, 0x4c, 0x12, 0x01, 0x02, 0x50, 0x12, 0x01, 0x02, + 0x54, 0x12, 0x01, 0x02, 0x58, 0x12, 0x01, 0x02, 0xa0, 0x31, 0x02, 0x03, 0xa8, 0x31, 0x02, 0x03, 0xb0, 0x31, 0x02, 0x03, 0xb8, 0x31, 0x02, 0x03, 0x70, 0x0e, 0x03, 0x03, 0x78, 0x0e, 0x03, 0x03, + 0x80, 0x0e, 0x03, 0x03, 0x60, 0x2c, 0x04, 0x04, 0x70, 0x2c, 0x04, 0x04, 0xd0, 0x0a, 0x05, 0x04, 0x60, 0x27, 0x06, 0x05, 0x40, 0x07, 0x07, 0x05, 0x80, 0x03, 0x09, 0x06, 0x00, 0x08, 0x12, 0x0b, + 0x90, 0x22, 0x00, 0x03, 0x98, 0x22, 0x00, 0x03, 0xa0, 0x22, 0x00, 0x03, 0x5c, 0x12, 0x01, 0x02, 0x60, 0x12, 0x01, 0x02, 0x64, 0x12, 0x01, 0x02, 0x68, 0x12, 0x01, 0x02, 0x6c, 0x12, 0x01, 0x02, + 0x70, 0x12, 0x01, 0x02, 0x74, 0x12, 0x01, 0x02, 0xc0, 0x31, 0x02, 0x03, 0xc8, 0x31, 0x02, 0x03, 0xd0, 0x31, 0x02, 0x03, 0xd8, 0x31, 0x02, 0x03, 0x88, 0x0e, 0x03, 0x03, 0x90, 0x0e, 0x03, 0x03, + 0x98, 0x0e, 0x03, 0x03, 0x80, 0x2c, 0x04, 0x04, 0x90, 0x2c, 0x04, 0x04, 0xe0, 0x0a, 0x05, 0x04, 0x80, 0x27, 0x06, 0x05, 0x60, 0x07, 0x07, 0x05, 0xc0, 0x03, 0x09, 0x06, 0x00, 0x20, 0x13, 0x0c, + 0xa8, 0x22, 0x00, 0x03, 0xb0, 0x22, 0x00, 0x03, 0xb8, 0x22, 0x00, 0x03, 0x78, 0x12, 0x01, 0x02, 0x7c, 0x12, 0x01, 0x02, 0x80, 0x12, 0x01, 0x02, 0x84, 0x12, 0x01, 0x02, 0x88, 0x12, 0x01, 0x02, + 0x8c, 0x12, 0x01, 0x02, 0x90, 0x12, 0x01, 0x02, 0xe0, 0x31, 0x02, 0x03, 0xe8, 0x31, 0x02, 0x03, 0xf0, 0x31, 0x02, 0x03, 0xf8, 0x31, 0x02, 0x03, 0xa0, 0x0e, 0x03, 0x03, 0xa8, 0x0e, 0x03, 0x03, + 0xb0, 0x0e, 0x03, 0x03, 0xa0, 0x2c, 0x04, 0x04, 0xb0, 0x2c, 0x04, 0x04, 0xf0, 0x0a, 0x05, 0x04, 0xa0, 0x27, 0x06, 0x05, 0x80, 0x07, 0x07, 0x05, 0x00, 0x04, 0x09, 0x06, 0x00, 0x00, 0x14, 0x0c, + 0xc0, 0x22, 0x00, 0x03, 0xc8, 0x22, 0x00, 0x03, 0xd0, 0x22, 0x00, 0x03, 0x94, 0x12, 0x01, 0x02, 0x98, 0x12, 0x01, 0x02, 0x9c, 0x12, 0x01, 0x02, 0xa0, 0x12, 0x01, 0x02, 0xa4, 0x12, 0x01, 0x02, + 0xa8, 0x12, 0x01, 0x02, 0xac, 0x12, 0x01, 0x02, 0x00, 0x32, 0x02, 0x03, 0x08, 0x32, 0x02, 0x03, 0x10, 0x32, 0x02, 0x03, 0x18, 0x32, 0x02, 0x03, 0xb8, 0x0e, 0x03, 0x03, 0xc0, 0x0e, 0x03, 0x03, + 0xc8, 0x0e, 0x03, 0x03, 0xc0, 0x2c, 0x04, 0x04, 0xd0, 0x2c, 0x04, 0x04, 0x00, 0x0b, 0x05, 0x04, 0xc0, 0x27, 0x06, 0x05, 0xa0, 0x07, 0x07, 0x05, 0x40, 0x04, 0x09, 0x06, 0xd8, 0x22, 0x00, 0x03, + 0xe0, 0x22, 0x00, 0x03, 0xe8, 0x22, 0x00, 0x03, 0xf0, 0x22, 0x00, 0x03, 0xb0, 0x12, 0x01, 0x02, 0xb4, 0x12, 0x01, 0x02, 0xb8, 0x12, 0x01, 0x02, 0xbc, 0x12, 0x01, 0x02, 0xc0, 0x12, 0x01, 0x02, + 0xc4, 0x12, 0x01, 0x02, 0xc8, 0x12, 0x01, 0x02, 0x20, 0x32, 0x02, 0x03, 0x28, 0x32, 0x02, 0x03, 0x30, 0x32, 0x02, 0x03, 0x38, 0x32, 0x02, 0x03, 0xd0, 0x0e, 0x03, 0x03, 0xd8, 0x0e, 0x03, 0x03, + 0xe0, 0x0e, 0x03, 0x03, 0xe0, 0x2c, 0x04, 0x04, 0xf0, 0x2c, 0x04, 0x04, 0x10, 0x0b, 0x05, 0x04, 0xe0, 0x27, 0x06, 0x05, 0xc0, 0x07, 0x07, 0x05, 0x80, 0x04, 0x09, 0x06, 0xf8, 0x22, 0x00, 0x03, + 0x00, 0x23, 0x00, 0x03, 0x08, 0x23, 0x00, 0x03, 0x10, 0x23, 0x00, 0x03, 0xcc, 0x12, 0x01, 0x02, 0xd0, 0x12, 0x01, 0x02, 0xd4, 0x12, 0x01, 0x02, 0xd8, 0x12, 0x01, 0x02, 0xdc, 0x12, 0x01, 0x02, + 0xe0, 0x12, 0x01, 0x02, 0x40, 0x32, 0x02, 0x03, 0x48, 0x32, 0x02, 0x03, 0x50, 0x32, 0x02, 0x03, 0x58, 0x32, 0x02, 0x03, 0x60, 0x32, 0x02, 0x03, 0xe8, 0x0e, 0x03, 0x03, 0xf0, 0x0e, 0x03, 0x03, + 0xf8, 0x0e, 0x03, 0x03, 0x00, 0x2d, 0x04, 0x04, 0x10, 0x2d, 0x04, 0x04, 0x20, 0x0b, 0x05, 0x04, 0x00, 0x28, 0x06, 0x05, 0xe0, 0x07, 0x07, 0x05, 0xc0, 0x04, 0x09, 0x06, 0x18, 0x23, 0x00, 0x03, + 0x20, 0x23, 0x00, 0x03, 0x28, 0x23, 0x00, 0x03, 0x30, 0x23, 0x00, 0x03, 0xe4, 0x12, 0x01, 0x02, 0xe8, 0x12, 0x01, 0x02, 0xec, 0x12, 0x01, 0x02, 0xf0, 0x12, 0x01, 0x02, 0xf4, 0x12, 0x01, 0x02, + 0xf8, 0x12, 0x01, 0x02, 0x68, 0x32, 0x02, 0x03, 0x70, 0x32, 0x02, 0x03, 0x78, 0x32, 0x02, 0x03, 0x80, 0x32, 0x02, 0x03, 0x88, 0x32, 0x02, 0x03, 0x00, 0x0f, 0x03, 0x03, 0x08, 0x0f, 0x03, 0x03, + 0x10, 0x0f, 0x03, 0x03, 0x20, 0x2d, 0x04, 0x04, 0x30, 0x2d, 0x04, 0x04, 0x30, 0x0b, 0x05, 0x04, 0x20, 0x28, 0x06, 0x05, 0x00, 0x08, 0x07, 0x05, 0x00, 0x05, 0x09, 0x06, 0x38, 0x23, 0x00, 0x03, + 0x40, 0x23, 0x00, 0x03, 0x48, 0x23, 0x00, 0x03, 0x50, 0x23, 0x00, 0x03, 0xfc, 0x12, 0x01, 0x02, 0x00, 0x13, 0x01, 0x02, 0x04, 0x13, 0x01, 0x02, 0x08, 0x13, 0x01, 0x02, 0x0c, 0x13, 0x01, 0x02, + 0x10, 0x13, 0x01, 0x02, 0x90, 0x32, 0x02, 0x03, 0x98, 0x32, 0x02, 0x03, 0xa0, 0x32, 0x02, 0x03, 0xa8, 0x32, 0x02, 0x03, 0xb0, 0x32, 0x02, 0x03, 0x18, 0x0f, 0x03, 0x03, 0x20, 0x0f, 0x03, 0x03, + 0x28, 0x0f, 0x03, 0x03, 0x40, 0x2d, 0x04, 0x04, 0x50, 0x2d, 0x04, 0x04, 0x40, 0x0b, 0x05, 0x04, 0x40, 0x28, 0x06, 0x05, 0x20, 0x08, 0x07, 0x05, 0x40, 0x05, 0x09, 0x06, 0x58, 0x23, 0x00, 0x03, + 0x60, 0x23, 0x00, 0x03, 0x68, 0x23, 0x00, 0x03, 0x70, 0x23, 0x00, 0x03, 0x14, 0x13, 0x01, 0x02, 0x18, 0x13, 0x01, 0x02, 0x1c, 0x13, 0x01, 0x02, 0x20, 0x13, 0x01, 0x02, 0x24, 0x13, 0x01, 0x02, + 0x28, 0x13, 0x01, 0x02, 0xb8, 0x32, 0x02, 0x03, 0xc0, 0x32, 0x02, 0x03, 0xc8, 0x32, 0x02, 0x03, 0xd0, 0x32, 0x02, 0x03, 0xd8, 0x32, 0x02, 0x03, 0x30, 0x0f, 0x03, 0x03, 0x38, 0x0f, 0x03, 0x03, + 0x40, 0x0f, 0x03, 0x03, 0x60, 0x2d, 0x04, 0x04, 0x70, 0x2d, 0x04, 0x04, 0x50, 0x0b, 0x05, 0x04, 0x60, 0x28, 0x06, 0x05, 0x40, 0x08, 0x07, 0x05, 0x80, 0x05, 0x09, 0x06, 0x78, 0x23, 0x00, 0x03, + 0x80, 0x23, 0x00, 0x03, 0x88, 0x23, 0x00, 0x03, 0x90, 0x23, 0x00, 0x03, 0x2c, 0x13, 0x01, 0x02, 0x30, 0x13, 0x01, 0x02, 0x34, 0x13, 0x01, 0x02, 0x38, 0x13, 0x01, 0x02, 0x3c, 0x13, 0x01, 0x02, + 0x40, 0x13, 0x01, 0x02, 0xe0, 0x32, 0x02, 0x03, 0xe8, 0x32, 0x02, 0x03, 0xf0, 0x32, 0x02, 0x03, 0xf8, 0x32, 0x02, 0x03, 0x00, 0x33, 0x02, 0x03, 0x48, 0x0f, 0x03, 0x03, 0x50, 0x0f, 0x03, 0x03, + 0x58, 0x0f, 0x03, 0x03, 0x80, 0x2d, 0x04, 0x04, 0x90, 0x2d, 0x04, 0x04, 0x60, 0x0b, 0x05, 0x04, 0x80, 0x28, 0x06, 0x05, 0x60, 0x08, 0x07, 0x05, 0xc0, 0x05, 0x09, 0x06, 0x98, 0x23, 0x00, 0x03, + 0xa0, 0x23, 0x00, 0x03, 0xa8, 0x23, 0x00, 0x03, 0xb0, 0x23, 0x00, 0x03, 0x44, 0x13, 0x01, 0x02, 0x48, 0x13, 0x01, 0x02, 0x4c, 0x13, 0x01, 0x02, 0x50, 0x13, 0x01, 0x02, 0x54, 0x13, 0x01, 0x02, + 0x58, 0x13, 0x01, 0x02, 0x08, 0x33, 0x02, 0x03, 0x10, 0x33, 0x02, 0x03, 0x18, 0x33, 0x02, 0x03, 0x20, 0x33, 0x02, 0x03, 0x28, 0x33, 0x02, 0x03, 0x60, 0x0f, 0x03, 0x03, 0x68, 0x0f, 0x03, 0x03, + 0x70, 0x0f, 0x03, 0x03, 0xa0, 0x2d, 0x04, 0x04, 0xb0, 0x2d, 0x04, 0x04, 0x70, 0x0b, 0x05, 0x04, 0xa0, 0x28, 0x06, 0x05, 0x80, 0x08, 0x07, 0x05, 0x00, 0x06, 0x09, 0x06, 0xb8, 0x23, 0x00, 0x03, + 0xc0, 0x23, 0x00, 0x03, 0xc8, 0x23, 0x00, 0x03, 0xd0, 0x23, 0x00, 0x03, 0x5c, 0x13, 0x01, 0x02, 0x60, 0x13, 0x01, 0x02, 0x64, 0x13, 0x01, 0x02, 0x68, 0x13, 0x01, 0x02, 0x6c, 0x13, 0x01, 0x02, + 0x70, 0x13, 0x01, 0x02, 0x30, 0x33, 0x02, 0x03, 0x38, 0x33, 0x02, 0x03, 0x40, 0x33, 0x02, 0x03, 0x48, 0x33, 0x02, 0x03, 0x50, 0x33, 0x02, 0x03, 0x78, 0x0f, 0x03, 0x03, 0x80, 0x0f, 0x03, 0x03, + 0x88, 0x0f, 0x03, 0x03, 0xc0, 0x2d, 0x04, 0x04, 0xd0, 0x2d, 0x04, 0x04, 0x80, 0x0b, 0x05, 0x04, 0xc0, 0x28, 0x06, 0x05, 0xa0, 0x08, 0x07, 0x05, 0x40, 0x06, 0x09, 0x06, 0xd8, 0x23, 0x00, 0x03, + 0xe0, 0x23, 0x00, 0x03, 0xe8, 0x23, 0x00, 0x03, 0xf0, 0x23, 0x00, 0x03, 0x74, 0x13, 0x01, 0x02, 0x78, 0x13, 0x01, 0x02, 0x7c, 0x13, 0x01, 0x02, 0x80, 0x13, 0x01, 0x02, 0x84, 0x13, 0x01, 0x02, + 0x88, 0x13, 0x01, 0x02, 0x58, 0x33, 0x02, 0x03, 0x60, 0x33, 0x02, 0x03, 0x68, 0x33, 0x02, 0x03, 0x70, 0x33, 0x02, 0x03, 0x78, 0x33, 0x02, 0x03, 0x90, 0x0f, 0x03, 0x03, 0x98, 0x0f, 0x03, 0x03, + 0xa0, 0x0f, 0x03, 0x03, 0xe0, 0x2d, 0x04, 0x04, 0xf0, 0x2d, 0x04, 0x04, 0x90, 0x0b, 0x05, 0x04, 0xe0, 0x28, 0x06, 0x05, 0xc0, 0x08, 0x07, 0x05, 0x80, 0x06, 0x09, 0x06, 0xf8, 0x23, 0x00, 0x03, + 0x00, 0x24, 0x00, 0x03, 0x08, 0x24, 0x00, 0x03, 0x10, 0x24, 0x00, 0x03, 0x8c, 0x13, 0x01, 0x02, 0x90, 0x13, 0x01, 0x02, 0x94, 0x13, 0x01, 0x02, 0x98, 0x13, 0x01, 0x02, 0x9c, 0x13, 0x01, 0x02, + 0xa0, 0x13, 0x01, 0x02, 0x80, 0x33, 0x02, 0x03, 0x88, 0x33, 0x02, 0x03, 0x90, 0x33, 0x02, 0x03, 0x98, 0x33, 0x02, 0x03, 0xa0, 0x33, 0x02, 0x03, 0xa8, 0x0f, 0x03, 0x03, 0xb0, 0x0f, 0x03, 0x03, + 0xb8, 0x0f, 0x03, 0x03, 0x00, 0x2e, 0x04, 0x04, 0x10, 0x2e, 0x04, 0x04, 0xa0, 0x0b, 0x05, 0x04, 0x00, 0x29, 0x06, 0x05, 0xe0, 0x08, 0x07, 0x05, 0xc0, 0x06, 0x09, 0x06, 0x18, 0x24, 0x00, 0x03, + 0x20, 0x24, 0x00, 0x03, 0x28, 0x24, 0x00, 0x03, 0x30, 0x24, 0x00, 0x03, 0xa4, 0x13, 0x01, 0x02, 0xa8, 0x13, 0x01, 0x02, 0xac, 0x13, 0x01, 0x02, 0xb0, 0x13, 0x01, 0x02, 0xb4, 0x13, 0x01, 0x02, + 0xb8, 0x13, 0x01, 0x02, 0xa8, 0x33, 0x02, 0x03, 0xb0, 0x33, 0x02, 0x03, 0xb8, 0x33, 0x02, 0x03, 0xc0, 0x33, 0x02, 0x03, 0xc8, 0x33, 0x02, 0x03, 0xc0, 0x0f, 0x03, 0x03, 0xc8, 0x0f, 0x03, 0x03, + 0xd0, 0x0f, 0x03, 0x03, 0x20, 0x2e, 0x04, 0x04, 0x30, 0x2e, 0x04, 0x04, 0xb0, 0x0b, 0x05, 0x04, 0x20, 0x29, 0x06, 0x05, 0x00, 0x09, 0x07, 0x05, 0x00, 0x07, 0x09, 0x06, 0x38, 0x24, 0x00, 0x03, + 0x40, 0x24, 0x00, 0x03, 0x48, 0x24, 0x00, 0x03, 0x50, 0x24, 0x00, 0x03, 0xbc, 0x13, 0x01, 0x02, 0xc0, 0x13, 0x01, 0x02, 0xc4, 0x13, 0x01, 0x02, 0xc8, 0x13, 0x01, 0x02, 0xcc, 0x13, 0x01, 0x02, + 0xd0, 0x13, 0x01, 0x02, 0xd0, 0x33, 0x02, 0x03, 0xd8, 0x33, 0x02, 0x03, 0xe0, 0x33, 0x02, 0x03, 0xe8, 0x33, 0x02, 0x03, 0xf0, 0x33, 0x02, 0x03, 0xd8, 0x0f, 0x03, 0x03, 0xe0, 0x0f, 0x03, 0x03, + 0xe8, 0x0f, 0x03, 0x03, 0x40, 0x2e, 0x04, 0x04, 0x50, 0x2e, 0x04, 0x04, 0xc0, 0x0b, 0x05, 0x04, 0x40, 0x29, 0x06, 0x05, 0x20, 0x09, 0x07, 0x05, 0x40, 0x07, 0x09, 0x06, 0x58, 0x24, 0x00, 0x03, + 0x60, 0x24, 0x00, 0x03, 0x68, 0x24, 0x00, 0x03, 0x70, 0x24, 0x00, 0x03, 0xd4, 0x13, 0x01, 0x02, 0xd8, 0x13, 0x01, 0x02, 0xdc, 0x13, 0x01, 0x02, 0xe0, 0x13, 0x01, 0x02, 0xe4, 0x13, 0x01, 0x02, + 0xe8, 0x13, 0x01, 0x02, 0xf8, 0x33, 0x02, 0x03, 0x00, 0x34, 0x02, 0x03, 0x08, 0x34, 0x02, 0x03, 0x10, 0x34, 0x02, 0x03, 0x18, 0x34, 0x02, 0x03, 0xf0, 0x0f, 0x03, 0x03, 0xf8, 0x0f, 0x03, 0x03, + 0x00, 0x10, 0x03, 0x03, 0x60, 0x2e, 0x04, 0x04, 0x70, 0x2e, 0x04, 0x04, 0xd0, 0x0b, 0x05, 0x04, 0x60, 0x29, 0x06, 0x05, 0x40, 0x09, 0x07, 0x05, 0x80, 0x07, 0x09, 0x06, 0x78, 0x24, 0x00, 0x03, + 0x80, 0x24, 0x00, 0x03, 0x88, 0x24, 0x00, 0x03, 0x90, 0x24, 0x00, 0x03, 0xec, 0x13, 0x01, 0x02, 0xf0, 0x13, 0x01, 0x02, 0xf4, 0x13, 0x01, 0x02, 0xf8, 0x13, 0x01, 0x02, 0xfc, 0x13, 0x01, 0x02, + 0x00, 0x14, 0x01, 0x02, 0x20, 0x34, 0x02, 0x03, 0x28, 0x34, 0x02, 0x03, 0x30, 0x34, 0x02, 0x03, 0x38, 0x34, 0x02, 0x03, 0x40, 0x34, 0x02, 0x03, 0x08, 0x10, 0x03, 0x03, 0x10, 0x10, 0x03, 0x03, + 0x18, 0x10, 0x03, 0x03, 0x80, 0x2e, 0x04, 0x04, 0x90, 0x2e, 0x04, 0x04, 0xe0, 0x0b, 0x05, 0x04, 0x80, 0x29, 0x06, 0x05, 0x60, 0x09, 0x07, 0x05, 0xc0, 0x07, 0x09, 0x06, 0x98, 0x24, 0x00, 0x03, + 0xa0, 0x24, 0x00, 0x03, 0xa8, 0x24, 0x00, 0x03, 0xb0, 0x24, 0x00, 0x03, 0x04, 0x14, 0x01, 0x02, 0x08, 0x14, 0x01, 0x02, 0x0c, 0x14, 0x01, 0x02, 0x10, 0x14, 0x01, 0x02, 0x14, 0x14, 0x01, 0x02, + 0x18, 0x14, 0x01, 0x02, 0x48, 0x34, 0x02, 0x03, 0x50, 0x34, 0x02, 0x03, 0x58, 0x34, 0x02, 0x03, 0x60, 0x34, 0x02, 0x03, 0x68, 0x34, 0x02, 0x03, 0x20, 0x10, 0x03, 0x03, 0x28, 0x10, 0x03, 0x03, + 0x30, 0x10, 0x03, 0x03, 0xa0, 0x2e, 0x04, 0x04, 0xb0, 0x2e, 0x04, 0x04, 0xf0, 0x0b, 0x05, 0x04, 0xa0, 0x29, 0x06, 0x05, 0x80, 0x09, 0x07, 0x05, 0x00, 0x08, 0x09, 0x06, 0xb8, 0x24, 0x00, 0x03, + 0xc0, 0x24, 0x00, 0x03, 0xc8, 0x24, 0x00, 0x03, 0xd0, 0x24, 0x00, 0x03, 0x1c, 0x14, 0x01, 0x02, 0x20, 0x14, 0x01, 0x02, 0x24, 0x14, 0x01, 0x02, 0x28, 0x14, 0x01, 0x02, 0x2c, 0x14, 0x01, 0x02, + 0x30, 0x14, 0x01, 0x02, 0x70, 0x34, 0x02, 0x03, 0x78, 0x34, 0x02, 0x03, 0x80, 0x34, 0x02, 0x03, 0x88, 0x34, 0x02, 0x03, 0x90, 0x34, 0x02, 0x03, 0x38, 0x10, 0x03, 0x03, 0x40, 0x10, 0x03, 0x03, + 0x48, 0x10, 0x03, 0x03, 0xc0, 0x2e, 0x04, 0x04, 0xd0, 0x2e, 0x04, 0x04, 0x00, 0x0c, 0x05, 0x04, 0xc0, 0x29, 0x06, 0x05, 0xa0, 0x09, 0x07, 0x05, 0x40, 0x08, 0x09, 0x06, 0xd8, 0x24, 0x00, 0x03, + 0xe0, 0x24, 0x00, 0x03, 0xe8, 0x24, 0x00, 0x03, 0xf0, 0x24, 0x00, 0x03, 0x34, 0x14, 0x01, 0x02, 0x38, 0x14, 0x01, 0x02, 0x3c, 0x14, 0x01, 0x02, 0x40, 0x14, 0x01, 0x02, 0x44, 0x14, 0x01, 0x02, + 0x48, 0x14, 0x01, 0x02, 0x98, 0x34, 0x02, 0x03, 0xa0, 0x34, 0x02, 0x03, 0xa8, 0x34, 0x02, 0x03, 0xb0, 0x34, 0x02, 0x03, 0xb8, 0x34, 0x02, 0x03, 0x50, 0x10, 0x03, 0x03, 0x58, 0x10, 0x03, 0x03, + 0x60, 0x10, 0x03, 0x03, 0xe0, 0x2e, 0x04, 0x04, 0xf0, 0x2e, 0x04, 0x04, 0x10, 0x0c, 0x05, 0x04, 0xe0, 0x29, 0x06, 0x05, 0xc0, 0x09, 0x07, 0x05, 0x80, 0x08, 0x09, 0x06, 0xf8, 0x24, 0x00, 0x03, + 0x00, 0x25, 0x00, 0x03, 0x08, 0x25, 0x00, 0x03, 0x10, 0x25, 0x00, 0x03, 0x4c, 0x14, 0x01, 0x02, 0x50, 0x14, 0x01, 0x02, 0x54, 0x14, 0x01, 0x02, 0x58, 0x14, 0x01, 0x02, 0x5c, 0x14, 0x01, 0x02, + 0x60, 0x14, 0x01, 0x02, 0xc0, 0x34, 0x02, 0x03, 0xc8, 0x34, 0x02, 0x03, 0xd0, 0x34, 0x02, 0x03, 0xd8, 0x34, 0x02, 0x03, 0xe0, 0x34, 0x02, 0x03, 0x68, 0x10, 0x03, 0x03, 0x70, 0x10, 0x03, 0x03, + 0x78, 0x10, 0x03, 0x03, 0x00, 0x2f, 0x04, 0x04, 0x10, 0x2f, 0x04, 0x04, 0x20, 0x0c, 0x05, 0x04, 0x00, 0x2a, 0x06, 0x05, 0xe0, 0x09, 0x07, 0x05, 0xc0, 0x08, 0x09, 0x06, 0x18, 0x25, 0x00, 0x03, + 0x20, 0x25, 0x00, 0x03, 0x28, 0x25, 0x00, 0x03, 0x30, 0x25, 0x00, 0x03, 0x64, 0x14, 0x01, 0x02, 0x68, 0x14, 0x01, 0x02, 0x6c, 0x14, 0x01, 0x02, 0x70, 0x14, 0x01, 0x02, 0x74, 0x14, 0x01, 0x02, + 0x78, 0x14, 0x01, 0x02, 0xe8, 0x34, 0x02, 0x03, 0xf0, 0x34, 0x02, 0x03, 0xf8, 0x34, 0x02, 0x03, 0x00, 0x35, 0x02, 0x03, 0x08, 0x35, 0x02, 0x03, 0x80, 0x10, 0x03, 0x03, 0x88, 0x10, 0x03, 0x03, + 0x90, 0x10, 0x03, 0x03, 0x20, 0x2f, 0x04, 0x04, 0x30, 0x2f, 0x04, 0x04, 0x30, 0x0c, 0x05, 0x04, 0x20, 0x2a, 0x06, 0x05, 0x00, 0x0a, 0x07, 0x05, 0x00, 0x09, 0x09, 0x06, 0x38, 0x25, 0x00, 0x03, + 0x40, 0x25, 0x00, 0x03, 0x48, 0x25, 0x00, 0x03, 0x50, 0x25, 0x00, 0x03, 0x7c, 0x14, 0x01, 0x02, 0x80, 0x14, 0x01, 0x02, 0x84, 0x14, 0x01, 0x02, 0x88, 0x14, 0x01, 0x02, 0x8c, 0x14, 0x01, 0x02, + 0x90, 0x14, 0x01, 0x02, 0x10, 0x35, 0x02, 0x03, 0x18, 0x35, 0x02, 0x03, 0x20, 0x35, 0x02, 0x03, 0x28, 0x35, 0x02, 0x03, 0x30, 0x35, 0x02, 0x03, 0x98, 0x10, 0x03, 0x03, 0xa0, 0x10, 0x03, 0x03, + 0xa8, 0x10, 0x03, 0x03, 0x40, 0x2f, 0x04, 0x04, 0x50, 0x2f, 0x04, 0x04, 0x40, 0x0c, 0x05, 0x04, 0x40, 0x2a, 0x06, 0x05, 0x20, 0x0a, 0x07, 0x05, 0x40, 0x09, 0x09, 0x06, 0x58, 0x25, 0x00, 0x03, + 0x60, 0x25, 0x00, 0x03, 0x68, 0x25, 0x00, 0x03, 0x70, 0x25, 0x00, 0x03, 0x94, 0x14, 0x01, 0x02, 0x98, 0x14, 0x01, 0x02, 0x9c, 0x14, 0x01, 0x02, 0xa0, 0x14, 0x01, 0x02, 0xa4, 0x14, 0x01, 0x02, + 0xa8, 0x14, 0x01, 0x02, 0x38, 0x35, 0x02, 0x03, 0x40, 0x35, 0x02, 0x03, 0x48, 0x35, 0x02, 0x03, 0x50, 0x35, 0x02, 0x03, 0x58, 0x35, 0x02, 0x03, 0xb0, 0x10, 0x03, 0x03, 0xb8, 0x10, 0x03, 0x03, + 0xc0, 0x10, 0x03, 0x03, 0x60, 0x2f, 0x04, 0x04, 0x70, 0x2f, 0x04, 0x04, 0x50, 0x0c, 0x05, 0x04, 0x60, 0x2a, 0x06, 0x05, 0x40, 0x0a, 0x07, 0x05, 0x80, 0x09, 0x09, 0x06, 0x78, 0x25, 0x00, 0x03, + 0x80, 0x25, 0x00, 0x03, 0x88, 0x25, 0x00, 0x03, 0x90, 0x25, 0x00, 0x03, 0xac, 0x14, 0x01, 0x02, 0xb0, 0x14, 0x01, 0x02, 0xb4, 0x14, 0x01, 0x02, 0xb8, 0x14, 0x01, 0x02, 0xbc, 0x14, 0x01, 0x02, + 0xc0, 0x14, 0x01, 0x02, 0x60, 0x35, 0x02, 0x03, 0x68, 0x35, 0x02, 0x03, 0x70, 0x35, 0x02, 0x03, 0x78, 0x35, 0x02, 0x03, 0x80, 0x35, 0x02, 0x03, 0xc8, 0x10, 0x03, 0x03, 0xd0, 0x10, 0x03, 0x03, + 0xd8, 0x10, 0x03, 0x03, 0x80, 0x2f, 0x04, 0x04, 0x90, 0x2f, 0x04, 0x04, 0x60, 0x0c, 0x05, 0x04, 0x80, 0x2a, 0x06, 0x05, 0x60, 0x0a, 0x07, 0x05, 0xc0, 0x09, 0x09, 0x06, 0x98, 0x25, 0x00, 0x03, + 0xa0, 0x25, 0x00, 0x03, 0xa8, 0x25, 0x00, 0x03, 0xb0, 0x25, 0x00, 0x03, 0xc4, 0x14, 0x01, 0x02, 0xc8, 0x14, 0x01, 0x02, 0xcc, 0x14, 0x01, 0x02, 0xd0, 0x14, 0x01, 0x02, 0xd4, 0x14, 0x01, 0x02, + 0xd8, 0x14, 0x01, 0x02, 0x88, 0x35, 0x02, 0x03, 0x90, 0x35, 0x02, 0x03, 0x98, 0x35, 0x02, 0x03, 0xa0, 0x35, 0x02, 0x03, 0xa8, 0x35, 0x02, 0x03, 0xe0, 0x10, 0x03, 0x03, 0xe8, 0x10, 0x03, 0x03, + 0xf0, 0x10, 0x03, 0x03, 0xa0, 0x2f, 0x04, 0x04, 0xb0, 0x2f, 0x04, 0x04, 0x70, 0x0c, 0x05, 0x04, 0xa0, 0x2a, 0x06, 0x05, 0x80, 0x0a, 0x07, 0x05, 0x00, 0x0a, 0x09, 0x06, 0xb8, 0x25, 0x00, 0x03, + 0xc0, 0x25, 0x00, 0x03, 0xc8, 0x25, 0x00, 0x03, 0xd0, 0x25, 0x00, 0x03, 0xdc, 0x14, 0x01, 0x02, 0xe0, 0x14, 0x01, 0x02, 0xe4, 0x14, 0x01, 0x02, 0xe8, 0x14, 0x01, 0x02, 0xec, 0x14, 0x01, 0x02, + 0xf0, 0x14, 0x01, 0x02, 0xb0, 0x35, 0x02, 0x03, 0xb8, 0x35, 0x02, 0x03, 0xc0, 0x35, 0x02, 0x03, 0xc8, 0x35, 0x02, 0x03, 0xd0, 0x35, 0x02, 0x03, 0xf8, 0x10, 0x03, 0x03, 0x00, 0x11, 0x03, 0x03, + 0x08, 0x11, 0x03, 0x03, 0xc0, 0x2f, 0x04, 0x04, 0xd0, 0x2f, 0x04, 0x04, 0x80, 0x0c, 0x05, 0x04, 0xc0, 0x2a, 0x06, 0x05, 0xa0, 0x0a, 0x07, 0x05, 0x00, 0x1e, 0x0a, 0x07, 0xd8, 0x25, 0x00, 0x03, + 0xe0, 0x25, 0x00, 0x03, 0xe8, 0x25, 0x00, 0x03, 0xf0, 0x25, 0x00, 0x03, 0xf4, 0x14, 0x01, 0x02, 0xf8, 0x14, 0x01, 0x02, 0xfc, 0x14, 0x01, 0x02, 0x00, 0x15, 0x01, 0x02, 0x04, 0x15, 0x01, 0x02, + 0x08, 0x15, 0x01, 0x02, 0xd8, 0x35, 0x02, 0x03, 0xe0, 0x35, 0x02, 0x03, 0xe8, 0x35, 0x02, 0x03, 0xf0, 0x35, 0x02, 0x03, 0xf8, 0x35, 0x02, 0x03, 0x10, 0x11, 0x03, 0x03, 0x18, 0x11, 0x03, 0x03, + 0x20, 0x11, 0x03, 0x03, 0xe0, 0x2f, 0x04, 0x04, 0xf0, 0x2f, 0x04, 0x04, 0x90, 0x0c, 0x05, 0x04, 0xe0, 0x2a, 0x06, 0x05, 0xc0, 0x0a, 0x07, 0x05, 0x80, 0x1e, 0x0a, 0x07, 0xf8, 0x25, 0x00, 0x03, + 0x00, 0x26, 0x00, 0x03, 0x08, 0x26, 0x00, 0x03, 0x10, 0x26, 0x00, 0x03, 0x0c, 0x15, 0x01, 0x02, 0x10, 0x15, 0x01, 0x02, 0x14, 0x15, 0x01, 0x02, 0x18, 0x15, 0x01, 0x02, 0x1c, 0x15, 0x01, 0x02, + 0x20, 0x15, 0x01, 0x02, 0x00, 0x36, 0x02, 0x03, 0x08, 0x36, 0x02, 0x03, 0x10, 0x36, 0x02, 0x03, 0x18, 0x36, 0x02, 0x03, 0x20, 0x36, 0x02, 0x03, 0x28, 0x11, 0x03, 0x03, 0x30, 0x11, 0x03, 0x03, + 0x38, 0x11, 0x03, 0x03, 0x00, 0x30, 0x04, 0x04, 0x10, 0x30, 0x04, 0x04, 0xa0, 0x0c, 0x05, 0x04, 0x00, 0x2b, 0x06, 0x05, 0xe0, 0x0a, 0x07, 0x05, 0x00, 0x1f, 0x0a, 0x07, 0x18, 0x26, 0x00, 0x03, + 0x20, 0x26, 0x00, 0x03, 0x28, 0x26, 0x00, 0x03, 0x30, 0x26, 0x00, 0x03, 0x24, 0x15, 0x01, 0x02, 0x28, 0x15, 0x01, 0x02, 0x2c, 0x15, 0x01, 0x02, 0x30, 0x15, 0x01, 0x02, 0x34, 0x15, 0x01, 0x02, + 0x38, 0x15, 0x01, 0x02, 0x28, 0x36, 0x02, 0x03, 0x30, 0x36, 0x02, 0x03, 0x38, 0x36, 0x02, 0x03, 0x40, 0x36, 0x02, 0x03, 0x48, 0x36, 0x02, 0x03, 0x40, 0x11, 0x03, 0x03, 0x48, 0x11, 0x03, 0x03, + 0x50, 0x11, 0x03, 0x03, 0x20, 0x30, 0x04, 0x04, 0x30, 0x30, 0x04, 0x04, 0xb0, 0x0c, 0x05, 0x04, 0x20, 0x2b, 0x06, 0x05, 0x00, 0x0b, 0x07, 0x05, 0x80, 0x1f, 0x0a, 0x07, 0x38, 0x26, 0x00, 0x03, + 0x40, 0x26, 0x00, 0x03, 0x48, 0x26, 0x00, 0x03, 0x50, 0x26, 0x00, 0x03, 0x3c, 0x15, 0x01, 0x02, 0x40, 0x15, 0x01, 0x02, 0x44, 0x15, 0x01, 0x02, 0x48, 0x15, 0x01, 0x02, 0x4c, 0x15, 0x01, 0x02, + 0x50, 0x15, 0x01, 0x02, 0x50, 0x36, 0x02, 0x03, 0x58, 0x36, 0x02, 0x03, 0x60, 0x36, 0x02, 0x03, 0x68, 0x36, 0x02, 0x03, 0x70, 0x36, 0x02, 0x03, 0x58, 0x11, 0x03, 0x03, 0x60, 0x11, 0x03, 0x03, + 0x68, 0x11, 0x03, 0x03, 0x40, 0x30, 0x04, 0x04, 0x50, 0x30, 0x04, 0x04, 0xc0, 0x0c, 0x05, 0x04, 0x40, 0x2b, 0x06, 0x05, 0x20, 0x0b, 0x07, 0x05, 0x00, 0x20, 0x0a, 0x07, 0x58, 0x26, 0x00, 0x03, + 0x60, 0x26, 0x00, 0x03, 0x68, 0x26, 0x00, 0x03, 0x70, 0x26, 0x00, 0x03, 0x54, 0x15, 0x01, 0x02, 0x58, 0x15, 0x01, 0x02, 0x5c, 0x15, 0x01, 0x02, 0x60, 0x15, 0x01, 0x02, 0x64, 0x15, 0x01, 0x02, + 0x68, 0x15, 0x01, 0x02, 0x78, 0x36, 0x02, 0x03, 0x80, 0x36, 0x02, 0x03, 0x88, 0x36, 0x02, 0x03, 0x90, 0x36, 0x02, 0x03, 0x98, 0x36, 0x02, 0x03, 0x70, 0x11, 0x03, 0x03, 0x78, 0x11, 0x03, 0x03, + 0x60, 0x30, 0x04, 0x04, 0x70, 0x30, 0x04, 0x04, 0x80, 0x30, 0x04, 0x04, 0xd0, 0x0c, 0x05, 0x04, 0x60, 0x2b, 0x06, 0x05, 0x40, 0x0b, 0x07, 0x05, 0x80, 0x20, 0x0a, 0x07, 0x78, 0x26, 0x00, 0x03, + 0x80, 0x26, 0x00, 0x03, 0x88, 0x26, 0x00, 0x03, 0x90, 0x26, 0x00, 0x03, 0x6c, 0x15, 0x01, 0x02, 0x70, 0x15, 0x01, 0x02, 0x74, 0x15, 0x01, 0x02, 0x78, 0x15, 0x01, 0x02, 0x7c, 0x15, 0x01, 0x02, + 0x80, 0x15, 0x01, 0x02, 0xa0, 0x36, 0x02, 0x03, 0xa8, 0x36, 0x02, 0x03, 0xb0, 0x36, 0x02, 0x03, 0xb8, 0x36, 0x02, 0x03, 0x80, 0x11, 0x03, 0x03, 0x88, 0x11, 0x03, 0x03, 0x90, 0x11, 0x03, 0x03, + 0x90, 0x30, 0x04, 0x04, 0xa0, 0x30, 0x04, 0x04, 0xb0, 0x30, 0x04, 0x04, 0xe0, 0x0c, 0x05, 0x04, 0x80, 0x2b, 0x06, 0x05, 0x60, 0x0b, 0x07, 0x05, 0x00, 0x21, 0x0a, 0x07, 0x98, 0x26, 0x00, 0x03, + 0xa0, 0x26, 0x00, 0x03, 0xa8, 0x26, 0x00, 0x03, 0xb0, 0x26, 0x00, 0x03, 0x84, 0x15, 0x01, 0x02, 0x88, 0x15, 0x01, 0x02, 0x8c, 0x15, 0x01, 0x02, 0x90, 0x15, 0x01, 0x02, 0x94, 0x15, 0x01, 0x02, + 0x98, 0x15, 0x01, 0x02, 0xc0, 0x36, 0x02, 0x03, 0xc8, 0x36, 0x02, 0x03, 0xd0, 0x36, 0x02, 0x03, 0xd8, 0x36, 0x02, 0x03, 0x98, 0x11, 0x03, 0x03, 0xa0, 0x11, 0x03, 0x03, 0xa8, 0x11, 0x03, 0x03, + 0xc0, 0x30, 0x04, 0x04, 0xd0, 0x30, 0x04, 0x04, 0xe0, 0x30, 0x04, 0x04, 0xf0, 0x0c, 0x05, 0x04, 0xa0, 0x2b, 0x06, 0x05, 0x80, 0x0b, 0x07, 0x05, 0x80, 0x21, 0x0a, 0x07, 0xb8, 0x26, 0x00, 0x03, + 0xc0, 0x26, 0x00, 0x03, 0xc8, 0x26, 0x00, 0x03, 0xd0, 0x26, 0x00, 0x03, 0x9c, 0x15, 0x01, 0x02, 0xa0, 0x15, 0x01, 0x02, 0xa4, 0x15, 0x01, 0x02, 0xa8, 0x15, 0x01, 0x02, 0xac, 0x15, 0x01, 0x02, + 0xb0, 0x15, 0x01, 0x02, 0xe0, 0x36, 0x02, 0x03, 0xe8, 0x36, 0x02, 0x03, 0xf0, 0x36, 0x02, 0x03, 0xf8, 0x36, 0x02, 0x03, 0xb0, 0x11, 0x03, 0x03, 0xb8, 0x11, 0x03, 0x03, 0xc0, 0x11, 0x03, 0x03, + 0xf0, 0x30, 0x04, 0x04, 0x00, 0x31, 0x04, 0x04, 0x10, 0x31, 0x04, 0x04, 0x00, 0x0d, 0x05, 0x04, 0xc0, 0x2b, 0x06, 0x05, 0xa0, 0x0b, 0x07, 0x05, 0x00, 0x22, 0x0a, 0x07, 0xd8, 0x26, 0x00, 0x03, + 0xe0, 0x26, 0x00, 0x03, 0xe8, 0x26, 0x00, 0x03, 0xf0, 0x26, 0x00, 0x03, 0xb4, 0x15, 0x01, 0x02, 0xb8, 0x15, 0x01, 0x02, 0xbc, 0x15, 0x01, 0x02, 0xc0, 0x15, 0x01, 0x02, 0xc4, 0x15, 0x01, 0x02, + 0xc8, 0x15, 0x01, 0x02, 0x00, 0x37, 0x02, 0x03, 0x08, 0x37, 0x02, 0x03, 0x10, 0x37, 0x02, 0x03, 0x18, 0x37, 0x02, 0x03, 0xc8, 0x11, 0x03, 0x03, 0xd0, 0x11, 0x03, 0x03, 0xd8, 0x11, 0x03, 0x03, + 0x20, 0x31, 0x04, 0x04, 0x30, 0x31, 0x04, 0x04, 0x40, 0x31, 0x04, 0x04, 0x10, 0x0d, 0x05, 0x04, 0xe0, 0x2b, 0x06, 0x05, 0xc0, 0x0b, 0x07, 0x05, 0x80, 0x22, 0x0a, 0x07, 0xf8, 0x26, 0x00, 0x03, + 0x00, 0x27, 0x00, 0x03, 0x08, 0x27, 0x00, 0x03, 0x10, 0x27, 0x00, 0x03, 0xcc, 0x15, 0x01, 0x02, 0xd0, 0x15, 0x01, 0x02, 0xd4, 0x15, 0x01, 0x02, 0xd8, 0x15, 0x01, 0x02, 0xdc, 0x15, 0x01, 0x02, + 0xe0, 0x15, 0x01, 0x02, 0x20, 0x37, 0x02, 0x03, 0x28, 0x37, 0x02, 0x03, 0x30, 0x37, 0x02, 0x03, 0x38, 0x37, 0x02, 0x03, 0xe0, 0x11, 0x03, 0x03, 0xe8, 0x11, 0x03, 0x03, 0xf0, 0x11, 0x03, 0x03, + 0x50, 0x31, 0x04, 0x04, 0x60, 0x31, 0x04, 0x04, 0x20, 0x0d, 0x05, 0x04, 0x30, 0x0d, 0x05, 0x04, 0x00, 0x2c, 0x06, 0x05, 0xe0, 0x0b, 0x07, 0x05, 0x00, 0x23, 0x0a, 0x07, 0x18, 0x27, 0x00, 0x03, + 0x20, 0x27, 0x00, 0x03, 0x28, 0x27, 0x00, 0x03, 0x30, 0x27, 0x00, 0x03, 0xe4, 0x15, 0x01, 0x02, 0xe8, 0x15, 0x01, 0x02, 0xec, 0x15, 0x01, 0x02, 0xf0, 0x15, 0x01, 0x02, 0xf4, 0x15, 0x01, 0x02, + 0xf8, 0x15, 0x01, 0x02, 0x40, 0x37, 0x02, 0x03, 0x48, 0x37, 0x02, 0x03, 0x50, 0x37, 0x02, 0x03, 0x58, 0x37, 0x02, 0x03, 0xf8, 0x11, 0x03, 0x03, 0x00, 0x12, 0x03, 0x03, 0x08, 0x12, 0x03, 0x03, + 0x70, 0x31, 0x04, 0x04, 0x80, 0x31, 0x04, 0x04, 0x40, 0x0d, 0x05, 0x04, 0x50, 0x0d, 0x05, 0x04, 0x20, 0x2c, 0x06, 0x05, 0x00, 0x0c, 0x07, 0x05, 0x80, 0x23, 0x0a, 0x07, 0x38, 0x27, 0x00, 0x03, + 0x40, 0x27, 0x00, 0x03, 0x48, 0x27, 0x00, 0x03, 0x50, 0x27, 0x00, 0x03, 0xfc, 0x15, 0x01, 0x02, 0x00, 0x16, 0x01, 0x02, 0x04, 0x16, 0x01, 0x02, 0x08, 0x16, 0x01, 0x02, 0x0c, 0x16, 0x01, 0x02, + 0x10, 0x16, 0x01, 0x02, 0x60, 0x37, 0x02, 0x03, 0x68, 0x37, 0x02, 0x03, 0x70, 0x37, 0x02, 0x03, 0x78, 0x37, 0x02, 0x03, 0x10, 0x12, 0x03, 0x03, 0x18, 0x12, 0x03, 0x03, 0x20, 0x12, 0x03, 0x03, + 0x90, 0x31, 0x04, 0x04, 0xa0, 0x31, 0x04, 0x04, 0x60, 0x0d, 0x05, 0x04, 0x70, 0x0d, 0x05, 0x04, 0x40, 0x2c, 0x06, 0x05, 0x20, 0x0c, 0x07, 0x05, 0x00, 0x24, 0x0a, 0x07, 0x58, 0x27, 0x00, 0x03, + 0x60, 0x27, 0x00, 0x03, 0x68, 0x27, 0x00, 0x03, 0x70, 0x27, 0x00, 0x03, 0x14, 0x16, 0x01, 0x02, 0x18, 0x16, 0x01, 0x02, 0x1c, 0x16, 0x01, 0x02, 0x20, 0x16, 0x01, 0x02, 0x24, 0x16, 0x01, 0x02, + 0x28, 0x16, 0x01, 0x02, 0x80, 0x37, 0x02, 0x03, 0x88, 0x37, 0x02, 0x03, 0x90, 0x37, 0x02, 0x03, 0x98, 0x37, 0x02, 0x03, 0x28, 0x12, 0x03, 0x03, 0x30, 0x12, 0x03, 0x03, 0x38, 0x12, 0x03, 0x03, + 0xb0, 0x31, 0x04, 0x04, 0xc0, 0x31, 0x04, 0x04, 0x80, 0x0d, 0x05, 0x04, 0x90, 0x0d, 0x05, 0x04, 0x60, 0x2c, 0x06, 0x05, 0x40, 0x0c, 0x07, 0x05, 0x80, 0x24, 0x0a, 0x07, 0x78, 0x27, 0x00, 0x03, + 0x80, 0x27, 0x00, 0x03, 0x88, 0x27, 0x00, 0x03, 0x90, 0x27, 0x00, 0x03, 0x2c, 0x16, 0x01, 0x02, 0x30, 0x16, 0x01, 0x02, 0x34, 0x16, 0x01, 0x02, 0x38, 0x16, 0x01, 0x02, 0x3c, 0x16, 0x01, 0x02, + 0x40, 0x16, 0x01, 0x02, 0xa0, 0x37, 0x02, 0x03, 0xa8, 0x37, 0x02, 0x03, 0xb0, 0x37, 0x02, 0x03, 0xb8, 0x37, 0x02, 0x03, 0x40, 0x12, 0x03, 0x03, 0x48, 0x12, 0x03, 0x03, 0x50, 0x12, 0x03, 0x03, + 0xd0, 0x31, 0x04, 0x04, 0xe0, 0x31, 0x04, 0x04, 0xa0, 0x0d, 0x05, 0x04, 0xb0, 0x0d, 0x05, 0x04, 0x80, 0x2c, 0x06, 0x05, 0x60, 0x0c, 0x07, 0x05, 0x00, 0x25, 0x0a, 0x07, 0x98, 0x27, 0x00, 0x03, + 0xa0, 0x27, 0x00, 0x03, 0xa8, 0x27, 0x00, 0x03, 0xb0, 0x27, 0x00, 0x03, 0x44, 0x16, 0x01, 0x02, 0x48, 0x16, 0x01, 0x02, 0x4c, 0x16, 0x01, 0x02, 0x50, 0x16, 0x01, 0x02, 0x54, 0x16, 0x01, 0x02, + 0x58, 0x16, 0x01, 0x02, 0xc0, 0x37, 0x02, 0x03, 0xc8, 0x37, 0x02, 0x03, 0xd0, 0x37, 0x02, 0x03, 0xd8, 0x37, 0x02, 0x03, 0x58, 0x12, 0x03, 0x03, 0x60, 0x12, 0x03, 0x03, 0x68, 0x12, 0x03, 0x03, + 0xf0, 0x31, 0x04, 0x04, 0x00, 0x32, 0x04, 0x04, 0xc0, 0x0d, 0x05, 0x04, 0xd0, 0x0d, 0x05, 0x04, 0xa0, 0x2c, 0x06, 0x05, 0x80, 0x0c, 0x07, 0x05, 0x80, 0x25, 0x0a, 0x07, 0xb8, 0x27, 0x00, 0x03, + 0xc0, 0x27, 0x00, 0x03, 0xc8, 0x27, 0x00, 0x03, 0xd0, 0x27, 0x00, 0x03, 0x5c, 0x16, 0x01, 0x02, 0x60, 0x16, 0x01, 0x02, 0x64, 0x16, 0x01, 0x02, 0x68, 0x16, 0x01, 0x02, 0x6c, 0x16, 0x01, 0x02, + 0x70, 0x16, 0x01, 0x02, 0xe0, 0x37, 0x02, 0x03, 0xe8, 0x37, 0x02, 0x03, 0xf0, 0x37, 0x02, 0x03, 0xf8, 0x37, 0x02, 0x03, 0x70, 0x12, 0x03, 0x03, 0x78, 0x12, 0x03, 0x03, 0x80, 0x12, 0x03, 0x03, + 0x10, 0x32, 0x04, 0x04, 0x20, 0x32, 0x04, 0x04, 0xe0, 0x0d, 0x05, 0x04, 0xf0, 0x0d, 0x05, 0x04, 0xc0, 0x2c, 0x06, 0x05, 0xa0, 0x0c, 0x07, 0x05, 0x00, 0x26, 0x0a, 0x07, 0xd8, 0x27, 0x00, 0x03, + 0xe0, 0x27, 0x00, 0x03, 0xe8, 0x27, 0x00, 0x03, 0xf0, 0x27, 0x00, 0x03, 0x74, 0x16, 0x01, 0x02, 0x78, 0x16, 0x01, 0x02, 0x7c, 0x16, 0x01, 0x02, 0x80, 0x16, 0x01, 0x02, 0x84, 0x16, 0x01, 0x02, + 0x88, 0x16, 0x01, 0x02, 0x00, 0x38, 0x02, 0x03, 0x08, 0x38, 0x02, 0x03, 0x10, 0x38, 0x02, 0x03, 0x18, 0x38, 0x02, 0x03, 0x88, 0x12, 0x03, 0x03, 0x90, 0x12, 0x03, 0x03, 0x98, 0x12, 0x03, 0x03, + 0x30, 0x32, 0x04, 0x04, 0x40, 0x32, 0x04, 0x04, 0x00, 0x0e, 0x05, 0x04, 0x10, 0x0e, 0x05, 0x04, 0xe0, 0x2c, 0x06, 0x05, 0x00, 0x23, 0x08, 0x06, 0x80, 0x26, 0x0a, 0x07, 0xf8, 0x27, 0x00, 0x03, + 0x00, 0x28, 0x00, 0x03, 0x08, 0x28, 0x00, 0x03, 0x10, 0x28, 0x00, 0x03, 0x8c, 0x16, 0x01, 0x02, 0x90, 0x16, 0x01, 0x02, 0x94, 0x16, 0x01, 0x02, 0x98, 0x16, 0x01, 0x02, 0x9c, 0x16, 0x01, 0x02, + 0xa0, 0x16, 0x01, 0x02, 0x20, 0x38, 0x02, 0x03, 0x28, 0x38, 0x02, 0x03, 0x30, 0x38, 0x02, 0x03, 0x38, 0x38, 0x02, 0x03, 0xa0, 0x12, 0x03, 0x03, 0xa8, 0x12, 0x03, 0x03, 0xb0, 0x12, 0x03, 0x03, + 0x50, 0x32, 0x04, 0x04, 0x60, 0x32, 0x04, 0x04, 0x20, 0x0e, 0x05, 0x04, 0x30, 0x0e, 0x05, 0x04, 0x00, 0x2d, 0x06, 0x05, 0x40, 0x23, 0x08, 0x06, 0x00, 0x27, 0x0a, 0x07, 0x18, 0x28, 0x00, 0x03, + 0x20, 0x28, 0x00, 0x03, 0x28, 0x28, 0x00, 0x03, 0x30, 0x28, 0x00, 0x03, 0xa4, 0x16, 0x01, 0x02, 0xa8, 0x16, 0x01, 0x02, 0xac, 0x16, 0x01, 0x02, 0xb0, 0x16, 0x01, 0x02, 0xb4, 0x16, 0x01, 0x02, + 0xb8, 0x16, 0x01, 0x02, 0x40, 0x38, 0x02, 0x03, 0x48, 0x38, 0x02, 0x03, 0x50, 0x38, 0x02, 0x03, 0x58, 0x38, 0x02, 0x03, 0xb8, 0x12, 0x03, 0x03, 0xc0, 0x12, 0x03, 0x03, 0xc8, 0x12, 0x03, 0x03, + 0x70, 0x32, 0x04, 0x04, 0x80, 0x32, 0x04, 0x04, 0x40, 0x0e, 0x05, 0x04, 0x50, 0x0e, 0x05, 0x04, 0x20, 0x2d, 0x06, 0x05, 0x80, 0x23, 0x08, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x38, 0x28, 0x00, 0x03, + 0x40, 0x28, 0x00, 0x03, 0x48, 0x28, 0x00, 0x03, 0x50, 0x28, 0x00, 0x03, 0xbc, 0x16, 0x01, 0x02, 0xc0, 0x16, 0x01, 0x02, 0xc4, 0x16, 0x01, 0x02, 0xc8, 0x16, 0x01, 0x02, 0xcc, 0x16, 0x01, 0x02, + 0xd0, 0x16, 0x01, 0x02, 0x60, 0x38, 0x02, 0x03, 0x68, 0x38, 0x02, 0x03, 0x70, 0x38, 0x02, 0x03, 0x78, 0x38, 0x02, 0x03, 0xd0, 0x12, 0x03, 0x03, 0xd8, 0x12, 0x03, 0x03, 0xe0, 0x12, 0x03, 0x03, + 0x90, 0x32, 0x04, 0x04, 0xa0, 0x32, 0x04, 0x04, 0x60, 0x0e, 0x05, 0x04, 0x70, 0x0e, 0x05, 0x04, 0x40, 0x2d, 0x06, 0x05, 0xc0, 0x23, 0x08, 0x06, 0x80, 0x01, 0x0b, 0x07, 0x58, 0x28, 0x00, 0x03, + 0x60, 0x28, 0x00, 0x03, 0x68, 0x28, 0x00, 0x03, 0x70, 0x28, 0x00, 0x03, 0xd4, 0x16, 0x01, 0x02, 0xd8, 0x16, 0x01, 0x02, 0xdc, 0x16, 0x01, 0x02, 0xe0, 0x16, 0x01, 0x02, 0xe4, 0x16, 0x01, 0x02, + 0xe8, 0x16, 0x01, 0x02, 0x80, 0x38, 0x02, 0x03, 0x88, 0x38, 0x02, 0x03, 0x90, 0x38, 0x02, 0x03, 0x98, 0x38, 0x02, 0x03, 0xe8, 0x12, 0x03, 0x03, 0xf0, 0x12, 0x03, 0x03, 0xf8, 0x12, 0x03, 0x03, + 0xb0, 0x32, 0x04, 0x04, 0xc0, 0x32, 0x04, 0x04, 0x80, 0x0e, 0x05, 0x04, 0x90, 0x0e, 0x05, 0x04, 0x60, 0x2d, 0x06, 0x05, 0x00, 0x24, 0x08, 0x06, 0x00, 0x02, 0x0b, 0x07, 0x78, 0x28, 0x00, 0x03, + 0x80, 0x28, 0x00, 0x03, 0x88, 0x28, 0x00, 0x03, 0x90, 0x28, 0x00, 0x03, 0xec, 0x16, 0x01, 0x02, 0xf0, 0x16, 0x01, 0x02, 0xf4, 0x16, 0x01, 0x02, 0xf8, 0x16, 0x01, 0x02, 0xfc, 0x16, 0x01, 0x02, + 0x00, 0x17, 0x01, 0x02, 0xa0, 0x38, 0x02, 0x03, 0xa8, 0x38, 0x02, 0x03, 0xb0, 0x38, 0x02, 0x03, 0xb8, 0x38, 0x02, 0x03, 0x00, 0x13, 0x03, 0x03, 0x08, 0x13, 0x03, 0x03, 0x10, 0x13, 0x03, 0x03, + 0xd0, 0x32, 0x04, 0x04, 0xe0, 0x32, 0x04, 0x04, 0xa0, 0x0e, 0x05, 0x04, 0xb0, 0x0e, 0x05, 0x04, 0x80, 0x2d, 0x06, 0x05, 0x40, 0x24, 0x08, 0x06, 0x80, 0x02, 0x0b, 0x07, 0x98, 0x28, 0x00, 0x03, + 0xa0, 0x28, 0x00, 0x03, 0xa8, 0x28, 0x00, 0x03, 0xb0, 0x28, 0x00, 0x03, 0x04, 0x17, 0x01, 0x02, 0x08, 0x17, 0x01, 0x02, 0x0c, 0x17, 0x01, 0x02, 0x10, 0x17, 0x01, 0x02, 0x14, 0x17, 0x01, 0x02, + 0x18, 0x17, 0x01, 0x02, 0xc0, 0x38, 0x02, 0x03, 0xc8, 0x38, 0x02, 0x03, 0xd0, 0x38, 0x02, 0x03, 0xd8, 0x38, 0x02, 0x03, 0x18, 0x13, 0x03, 0x03, 0x20, 0x13, 0x03, 0x03, 0x28, 0x13, 0x03, 0x03, + 0xf0, 0x32, 0x04, 0x04, 0x00, 0x33, 0x04, 0x04, 0xc0, 0x0e, 0x05, 0x04, 0xd0, 0x0e, 0x05, 0x04, 0xa0, 0x2d, 0x06, 0x05, 0x80, 0x24, 0x08, 0x06, 0x00, 0x03, 0x0b, 0x07, 0xb8, 0x28, 0x00, 0x03, + 0xc0, 0x28, 0x00, 0x03, 0xc8, 0x28, 0x00, 0x03, 0xd0, 0x28, 0x00, 0x03, 0x1c, 0x17, 0x01, 0x02, 0x20, 0x17, 0x01, 0x02, 0x24, 0x17, 0x01, 0x02, 0x28, 0x17, 0x01, 0x02, 0x2c, 0x17, 0x01, 0x02, + 0x30, 0x17, 0x01, 0x02, 0xe0, 0x38, 0x02, 0x03, 0xe8, 0x38, 0x02, 0x03, 0xf0, 0x38, 0x02, 0x03, 0xf8, 0x38, 0x02, 0x03, 0x30, 0x13, 0x03, 0x03, 0x38, 0x13, 0x03, 0x03, 0x40, 0x13, 0x03, 0x03, + 0x10, 0x33, 0x04, 0x04, 0x20, 0x33, 0x04, 0x04, 0xe0, 0x0e, 0x05, 0x04, 0xf0, 0x0e, 0x05, 0x04, 0xc0, 0x2d, 0x06, 0x05, 0xc0, 0x24, 0x08, 0x06, 0x80, 0x03, 0x0b, 0x07, 0xd8, 0x28, 0x00, 0x03, + 0xe0, 0x28, 0x00, 0x03, 0xe8, 0x28, 0x00, 0x03, 0xf0, 0x28, 0x00, 0x03, 0x34, 0x17, 0x01, 0x02, 0x38, 0x17, 0x01, 0x02, 0x3c, 0x17, 0x01, 0x02, 0x40, 0x17, 0x01, 0x02, 0x44, 0x17, 0x01, 0x02, + 0x48, 0x17, 0x01, 0x02, 0x00, 0x39, 0x02, 0x03, 0x08, 0x39, 0x02, 0x03, 0x10, 0x39, 0x02, 0x03, 0x18, 0x39, 0x02, 0x03, 0x48, 0x13, 0x03, 0x03, 0x50, 0x13, 0x03, 0x03, 0x58, 0x13, 0x03, 0x03, + 0x30, 0x33, 0x04, 0x04, 0x40, 0x33, 0x04, 0x04, 0x00, 0x0f, 0x05, 0x04, 0x10, 0x0f, 0x05, 0x04, 0xe0, 0x2d, 0x06, 0x05, 0x00, 0x25, 0x08, 0x06, 0x00, 0x04, 0x0b, 0x07, 0xf8, 0x28, 0x00, 0x03, + 0x00, 0x29, 0x00, 0x03, 0x08, 0x29, 0x00, 0x03, 0x10, 0x29, 0x00, 0x03, 0x4c, 0x17, 0x01, 0x02, 0x50, 0x17, 0x01, 0x02, 0x54, 0x17, 0x01, 0x02, 0x58, 0x17, 0x01, 0x02, 0x5c, 0x17, 0x01, 0x02, + 0x60, 0x17, 0x01, 0x02, 0x20, 0x39, 0x02, 0x03, 0x28, 0x39, 0x02, 0x03, 0x30, 0x39, 0x02, 0x03, 0x38, 0x39, 0x02, 0x03, 0x60, 0x13, 0x03, 0x03, 0x68, 0x13, 0x03, 0x03, 0x70, 0x13, 0x03, 0x03, + 0x50, 0x33, 0x04, 0x04, 0x60, 0x33, 0x04, 0x04, 0x20, 0x0f, 0x05, 0x04, 0x30, 0x0f, 0x05, 0x04, 0x00, 0x2e, 0x06, 0x05, 0x40, 0x25, 0x08, 0x06, 0x80, 0x04, 0x0b, 0x07, 0x18, 0x29, 0x00, 0x03, + 0x20, 0x29, 0x00, 0x03, 0x28, 0x29, 0x00, 0x03, 0x30, 0x29, 0x00, 0x03, 0x64, 0x17, 0x01, 0x02, 0x68, 0x17, 0x01, 0x02, 0x6c, 0x17, 0x01, 0x02, 0x70, 0x17, 0x01, 0x02, 0x74, 0x17, 0x01, 0x02, + 0x78, 0x17, 0x01, 0x02, 0x40, 0x39, 0x02, 0x03, 0x48, 0x39, 0x02, 0x03, 0x50, 0x39, 0x02, 0x03, 0x58, 0x39, 0x02, 0x03, 0x78, 0x13, 0x03, 0x03, 0x80, 0x13, 0x03, 0x03, 0x88, 0x13, 0x03, 0x03, + 0x70, 0x33, 0x04, 0x04, 0x80, 0x33, 0x04, 0x04, 0x40, 0x0f, 0x05, 0x04, 0x50, 0x0f, 0x05, 0x04, 0x20, 0x2e, 0x06, 0x05, 0x80, 0x25, 0x08, 0x06, 0x00, 0x05, 0x0b, 0x07, 0x38, 0x29, 0x00, 0x03, + 0x40, 0x29, 0x00, 0x03, 0x48, 0x29, 0x00, 0x03, 0x50, 0x29, 0x00, 0x03, 0x7c, 0x17, 0x01, 0x02, 0x80, 0x17, 0x01, 0x02, 0x84, 0x17, 0x01, 0x02, 0x88, 0x17, 0x01, 0x02, 0x8c, 0x17, 0x01, 0x02, + 0x90, 0x17, 0x01, 0x02, 0x60, 0x39, 0x02, 0x03, 0x68, 0x39, 0x02, 0x03, 0x70, 0x39, 0x02, 0x03, 0x78, 0x39, 0x02, 0x03, 0x90, 0x13, 0x03, 0x03, 0x98, 0x13, 0x03, 0x03, 0xa0, 0x13, 0x03, 0x03, + 0x90, 0x33, 0x04, 0x04, 0xa0, 0x33, 0x04, 0x04, 0x60, 0x0f, 0x05, 0x04, 0x70, 0x0f, 0x05, 0x04, 0x40, 0x2e, 0x06, 0x05, 0xc0, 0x25, 0x08, 0x06, 0x80, 0x05, 0x0b, 0x07, 0x58, 0x29, 0x00, 0x03, + 0x60, 0x29, 0x00, 0x03, 0x68, 0x29, 0x00, 0x03, 0x70, 0x29, 0x00, 0x03, 0x94, 0x17, 0x01, 0x02, 0x98, 0x17, 0x01, 0x02, 0x9c, 0x17, 0x01, 0x02, 0xa0, 0x17, 0x01, 0x02, 0xa4, 0x17, 0x01, 0x02, + 0xa8, 0x17, 0x01, 0x02, 0x80, 0x39, 0x02, 0x03, 0x88, 0x39, 0x02, 0x03, 0x90, 0x39, 0x02, 0x03, 0x98, 0x39, 0x02, 0x03, 0xa8, 0x13, 0x03, 0x03, 0xb0, 0x13, 0x03, 0x03, 0xb8, 0x13, 0x03, 0x03, + 0xb0, 0x33, 0x04, 0x04, 0xc0, 0x33, 0x04, 0x04, 0x80, 0x0f, 0x05, 0x04, 0x90, 0x0f, 0x05, 0x04, 0x60, 0x2e, 0x06, 0x05, 0x00, 0x26, 0x08, 0x06, 0x00, 0x06, 0x0b, 0x07, 0x78, 0x29, 0x00, 0x03, + 0x80, 0x29, 0x00, 0x03, 0x88, 0x29, 0x00, 0x03, 0x90, 0x29, 0x00, 0x03, 0xac, 0x17, 0x01, 0x02, 0xb0, 0x17, 0x01, 0x02, 0xb4, 0x17, 0x01, 0x02, 0xb8, 0x17, 0x01, 0x02, 0xbc, 0x17, 0x01, 0x02, + 0xc0, 0x17, 0x01, 0x02, 0xa0, 0x39, 0x02, 0x03, 0xa8, 0x39, 0x02, 0x03, 0xb0, 0x39, 0x02, 0x03, 0xb8, 0x39, 0x02, 0x03, 0xc0, 0x13, 0x03, 0x03, 0xc8, 0x13, 0x03, 0x03, 0xd0, 0x13, 0x03, 0x03, + 0xd0, 0x33, 0x04, 0x04, 0xe0, 0x33, 0x04, 0x04, 0xa0, 0x0f, 0x05, 0x04, 0xb0, 0x0f, 0x05, 0x04, 0x80, 0x2e, 0x06, 0x05, 0x40, 0x26, 0x08, 0x06, 0x80, 0x06, 0x0b, 0x07, 0x98, 0x29, 0x00, 0x03, + 0xa0, 0x29, 0x00, 0x03, 0xa8, 0x29, 0x00, 0x03, 0xb0, 0x29, 0x00, 0x03, 0xc4, 0x17, 0x01, 0x02, 0xc8, 0x17, 0x01, 0x02, 0xcc, 0x17, 0x01, 0x02, 0xd0, 0x17, 0x01, 0x02, 0xd4, 0x17, 0x01, 0x02, + 0xd8, 0x17, 0x01, 0x02, 0xc0, 0x39, 0x02, 0x03, 0xc8, 0x39, 0x02, 0x03, 0xd0, 0x39, 0x02, 0x03, 0xd8, 0x39, 0x02, 0x03, 0xd8, 0x13, 0x03, 0x03, 0xe0, 0x13, 0x03, 0x03, 0xe8, 0x13, 0x03, 0x03, + 0xf0, 0x33, 0x04, 0x04, 0x00, 0x34, 0x04, 0x04, 0xc0, 0x0f, 0x05, 0x04, 0xd0, 0x0f, 0x05, 0x04, 0xa0, 0x2e, 0x06, 0x05, 0x80, 0x26, 0x08, 0x06, 0x00, 0x07, 0x0b, 0x07, 0xb8, 0x29, 0x00, 0x03, + 0xc0, 0x29, 0x00, 0x03, 0xc8, 0x29, 0x00, 0x03, 0xd0, 0x29, 0x00, 0x03, 0xdc, 0x17, 0x01, 0x02, 0xe0, 0x17, 0x01, 0x02, 0xe4, 0x17, 0x01, 0x02, 0xe8, 0x17, 0x01, 0x02, 0xec, 0x17, 0x01, 0x02, + 0xf0, 0x17, 0x01, 0x02, 0xe0, 0x39, 0x02, 0x03, 0xe8, 0x39, 0x02, 0x03, 0xf0, 0x39, 0x02, 0x03, 0xf8, 0x39, 0x02, 0x03, 0xf0, 0x13, 0x03, 0x03, 0xf8, 0x13, 0x03, 0x03, 0x00, 0x14, 0x03, 0x03, + 0x10, 0x34, 0x04, 0x04, 0x20, 0x34, 0x04, 0x04, 0xe0, 0x0f, 0x05, 0x04, 0xf0, 0x0f, 0x05, 0x04, 0xc0, 0x2e, 0x06, 0x05, 0xc0, 0x26, 0x08, 0x06, 0x00, 0x1a, 0x0c, 0x08, 0xd8, 0x29, 0x00, 0x03, + 0xe0, 0x29, 0x00, 0x03, 0xe8, 0x29, 0x00, 0x03, 0xf0, 0x29, 0x00, 0x03, 0xf4, 0x17, 0x01, 0x02, 0xf8, 0x17, 0x01, 0x02, 0xfc, 0x17, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x04, 0x18, 0x01, 0x02, + 0x08, 0x18, 0x01, 0x02, 0x00, 0x3a, 0x02, 0x03, 0x08, 0x3a, 0x02, 0x03, 0x10, 0x3a, 0x02, 0x03, 0x18, 0x3a, 0x02, 0x03, 0x08, 0x14, 0x03, 0x03, 0x10, 0x14, 0x03, 0x03, 0x18, 0x14, 0x03, 0x03, + 0x30, 0x34, 0x04, 0x04, 0x40, 0x34, 0x04, 0x04, 0x00, 0x10, 0x05, 0x04, 0x10, 0x10, 0x05, 0x04, 0xe0, 0x2e, 0x06, 0x05, 0x00, 0x27, 0x08, 0x06, 0x00, 0x1b, 0x0c, 0x08, 0xf8, 0x29, 0x00, 0x03, + 0x00, 0x2a, 0x00, 0x03, 0x08, 0x2a, 0x00, 0x03, 0x10, 0x2a, 0x00, 0x03, 0x0c, 0x18, 0x01, 0x02, 0x10, 0x18, 0x01, 0x02, 0x14, 0x18, 0x01, 0x02, 0x18, 0x18, 0x01, 0x02, 0x1c, 0x18, 0x01, 0x02, + 0x20, 0x18, 0x01, 0x02, 0x20, 0x3a, 0x02, 0x03, 0x28, 0x3a, 0x02, 0x03, 0x30, 0x3a, 0x02, 0x03, 0x38, 0x3a, 0x02, 0x03, 0x20, 0x14, 0x03, 0x03, 0x28, 0x14, 0x03, 0x03, 0x30, 0x14, 0x03, 0x03, + 0x50, 0x34, 0x04, 0x04, 0x60, 0x34, 0x04, 0x04, 0x20, 0x10, 0x05, 0x04, 0x30, 0x10, 0x05, 0x04, 0x00, 0x2f, 0x06, 0x05, 0x40, 0x27, 0x08, 0x06, 0x00, 0x1c, 0x0c, 0x08, 0x18, 0x2a, 0x00, 0x03, + 0x20, 0x2a, 0x00, 0x03, 0x28, 0x2a, 0x00, 0x03, 0x30, 0x2a, 0x00, 0x03, 0x24, 0x18, 0x01, 0x02, 0x28, 0x18, 0x01, 0x02, 0x2c, 0x18, 0x01, 0x02, 0x30, 0x18, 0x01, 0x02, 0x34, 0x18, 0x01, 0x02, + 0x38, 0x18, 0x01, 0x02, 0x40, 0x3a, 0x02, 0x03, 0x48, 0x3a, 0x02, 0x03, 0x50, 0x3a, 0x02, 0x03, 0x58, 0x3a, 0x02, 0x03, 0x38, 0x14, 0x03, 0x03, 0x40, 0x14, 0x03, 0x03, 0x48, 0x14, 0x03, 0x03, + 0x70, 0x34, 0x04, 0x04, 0x80, 0x34, 0x04, 0x04, 0x40, 0x10, 0x05, 0x04, 0x50, 0x10, 0x05, 0x04, 0x20, 0x2f, 0x06, 0x05, 0x80, 0x27, 0x08, 0x06, 0x00, 0x1d, 0x0c, 0x08, 0x38, 0x2a, 0x00, 0x03, + 0x40, 0x2a, 0x00, 0x03, 0x48, 0x2a, 0x00, 0x03, 0x50, 0x2a, 0x00, 0x03, 0x3c, 0x18, 0x01, 0x02, 0x40, 0x18, 0x01, 0x02, 0x44, 0x18, 0x01, 0x02, 0x48, 0x18, 0x01, 0x02, 0x4c, 0x18, 0x01, 0x02, + 0x50, 0x18, 0x01, 0x02, 0x60, 0x3a, 0x02, 0x03, 0x68, 0x3a, 0x02, 0x03, 0x70, 0x3a, 0x02, 0x03, 0x78, 0x3a, 0x02, 0x03, 0x50, 0x14, 0x03, 0x03, 0x58, 0x14, 0x03, 0x03, 0x60, 0x14, 0x03, 0x03, + 0x90, 0x34, 0x04, 0x04, 0xa0, 0x34, 0x04, 0x04, 0x60, 0x10, 0x05, 0x04, 0x70, 0x10, 0x05, 0x04, 0x40, 0x2f, 0x06, 0x05, 0xc0, 0x27, 0x08, 0x06, 0x00, 0x1e, 0x0c, 0x08, 0x58, 0x2a, 0x00, 0x03, + 0x60, 0x2a, 0x00, 0x03, 0x68, 0x2a, 0x00, 0x03, 0x70, 0x2a, 0x00, 0x03, 0x54, 0x18, 0x01, 0x02, 0x58, 0x18, 0x01, 0x02, 0x5c, 0x18, 0x01, 0x02, 0x60, 0x18, 0x01, 0x02, 0x64, 0x18, 0x01, 0x02, + 0x68, 0x18, 0x01, 0x02, 0x80, 0x3a, 0x02, 0x03, 0x88, 0x3a, 0x02, 0x03, 0x90, 0x3a, 0x02, 0x03, 0x98, 0x3a, 0x02, 0x03, 0x68, 0x14, 0x03, 0x03, 0x70, 0x14, 0x03, 0x03, 0x78, 0x14, 0x03, 0x03, + 0xb0, 0x34, 0x04, 0x04, 0xc0, 0x34, 0x04, 0x04, 0x80, 0x10, 0x05, 0x04, 0x90, 0x10, 0x05, 0x04, 0x60, 0x2f, 0x06, 0x05, 0x00, 0x28, 0x08, 0x06, 0x00, 0x1f, 0x0c, 0x08, 0x78, 0x2a, 0x00, 0x03, + 0x80, 0x2a, 0x00, 0x03, 0x88, 0x2a, 0x00, 0x03, 0x90, 0x2a, 0x00, 0x03, 0x6c, 0x18, 0x01, 0x02, 0x70, 0x18, 0x01, 0x02, 0x74, 0x18, 0x01, 0x02, 0x78, 0x18, 0x01, 0x02, 0x7c, 0x18, 0x01, 0x02, + 0x80, 0x18, 0x01, 0x02, 0xa0, 0x3a, 0x02, 0x03, 0xa8, 0x3a, 0x02, 0x03, 0xb0, 0x3a, 0x02, 0x03, 0xb8, 0x3a, 0x02, 0x03, 0x80, 0x14, 0x03, 0x03, 0x88, 0x14, 0x03, 0x03, 0x90, 0x14, 0x03, 0x03, + 0xd0, 0x34, 0x04, 0x04, 0xe0, 0x34, 0x04, 0x04, 0xa0, 0x10, 0x05, 0x04, 0xb0, 0x10, 0x05, 0x04, 0x80, 0x2f, 0x06, 0x05, 0x40, 0x28, 0x08, 0x06, 0x00, 0x20, 0x0c, 0x08, 0x98, 0x2a, 0x00, 0x03, + 0xa0, 0x2a, 0x00, 0x03, 0xa8, 0x2a, 0x00, 0x03, 0xb0, 0x2a, 0x00, 0x03, 0x84, 0x18, 0x01, 0x02, 0x88, 0x18, 0x01, 0x02, 0x8c, 0x18, 0x01, 0x02, 0x90, 0x18, 0x01, 0x02, 0x94, 0x18, 0x01, 0x02, + 0x98, 0x18, 0x01, 0x02, 0xc0, 0x3a, 0x02, 0x03, 0xc8, 0x3a, 0x02, 0x03, 0xd0, 0x3a, 0x02, 0x03, 0xd8, 0x3a, 0x02, 0x03, 0x98, 0x14, 0x03, 0x03, 0xa0, 0x14, 0x03, 0x03, 0xa8, 0x14, 0x03, 0x03, + 0xf0, 0x34, 0x04, 0x04, 0x00, 0x35, 0x04, 0x04, 0xc0, 0x10, 0x05, 0x04, 0xd0, 0x10, 0x05, 0x04, 0xa0, 0x2f, 0x06, 0x05, 0x80, 0x28, 0x08, 0x06, 0x00, 0x21, 0x0c, 0x08, 0xb8, 0x2a, 0x00, 0x03, + 0xc0, 0x2a, 0x00, 0x03, 0xc8, 0x2a, 0x00, 0x03, 0x9c, 0x18, 0x01, 0x02, 0xa0, 0x18, 0x01, 0x02, 0xa4, 0x18, 0x01, 0x02, 0xa8, 0x18, 0x01, 0x02, 0xac, 0x18, 0x01, 0x02, 0xb0, 0x18, 0x01, 0x02, + 0xb4, 0x18, 0x01, 0x02, 0xe0, 0x3a, 0x02, 0x03, 0xe8, 0x3a, 0x02, 0x03, 0xf0, 0x3a, 0x02, 0x03, 0xf8, 0x3a, 0x02, 0x03, 0xb0, 0x14, 0x03, 0x03, 0xb8, 0x14, 0x03, 0x03, 0xc0, 0x14, 0x03, 0x03, + 0x10, 0x35, 0x04, 0x04, 0x20, 0x35, 0x04, 0x04, 0xe0, 0x10, 0x05, 0x04, 0xf0, 0x10, 0x05, 0x04, 0xc0, 0x2f, 0x06, 0x05, 0xc0, 0x28, 0x08, 0x06, 0x00, 0x22, 0x0c, 0x08, 0xd0, 0x2a, 0x00, 0x03, + 0xd8, 0x2a, 0x00, 0x03, 0xe0, 0x2a, 0x00, 0x03, 0xb8, 0x18, 0x01, 0x02, 0xbc, 0x18, 0x01, 0x02, 0xc0, 0x18, 0x01, 0x02, 0xc4, 0x18, 0x01, 0x02, 0xc8, 0x18, 0x01, 0x02, 0xcc, 0x18, 0x01, 0x02, + 0xd0, 0x18, 0x01, 0x02, 0x00, 0x3b, 0x02, 0x03, 0x08, 0x3b, 0x02, 0x03, 0x10, 0x3b, 0x02, 0x03, 0x18, 0x3b, 0x02, 0x03, 0xc8, 0x14, 0x03, 0x03, 0xd0, 0x14, 0x03, 0x03, 0xd8, 0x14, 0x03, 0x03, + 0x30, 0x35, 0x04, 0x04, 0x40, 0x35, 0x04, 0x04, 0x00, 0x11, 0x05, 0x04, 0x10, 0x11, 0x05, 0x04, 0xe0, 0x2f, 0x06, 0x05, 0x00, 0x29, 0x08, 0x06, 0x00, 0x3e, 0x0d, 0x09, 0xe8, 0x2a, 0x00, 0x03, + 0xf0, 0x2a, 0x00, 0x03, 0xf8, 0x2a, 0x00, 0x03, 0xd4, 0x18, 0x01, 0x02, 0xd8, 0x18, 0x01, 0x02, 0xdc, 0x18, 0x01, 0x02, 0xe0, 0x18, 0x01, 0x02, 0xe4, 0x18, 0x01, 0x02, 0xe8, 0x18, 0x01, 0x02, + 0xec, 0x18, 0x01, 0x02, 0x20, 0x3b, 0x02, 0x03, 0x28, 0x3b, 0x02, 0x03, 0x30, 0x3b, 0x02, 0x03, 0x38, 0x3b, 0x02, 0x03, 0xe0, 0x14, 0x03, 0x03, 0xe8, 0x14, 0x03, 0x03, 0xf0, 0x14, 0x03, 0x03, + 0x50, 0x35, 0x04, 0x04, 0x60, 0x35, 0x04, 0x04, 0x20, 0x11, 0x05, 0x04, 0x30, 0x11, 0x05, 0x04, 0x00, 0x30, 0x06, 0x05, 0x40, 0x29, 0x08, 0x06, 0x00, 0x00, 0x0d, 0x08, 0x00, 0x2b, 0x00, 0x03, + 0x08, 0x2b, 0x00, 0x03, 0x10, 0x2b, 0x00, 0x03, 0xf0, 0x18, 0x01, 0x02, 0xf4, 0x18, 0x01, 0x02, 0xf8, 0x18, 0x01, 0x02, 0xfc, 0x18, 0x01, 0x02, 0x00, 0x19, 0x01, 0x02, 0x04, 0x19, 0x01, 0x02, + 0x08, 0x19, 0x01, 0x02, 0x40, 0x3b, 0x02, 0x03, 0x48, 0x3b, 0x02, 0x03, 0x50, 0x3b, 0x02, 0x03, 0x58, 0x3b, 0x02, 0x03, 0xf8, 0x14, 0x03, 0x03, 0x00, 0x15, 0x03, 0x03, 0x08, 0x15, 0x03, 0x03, + 0x70, 0x35, 0x04, 0x04, 0x80, 0x35, 0x04, 0x04, 0x40, 0x11, 0x05, 0x04, 0x50, 0x11, 0x05, 0x04, 0x20, 0x30, 0x06, 0x05, 0x80, 0x29, 0x08, 0x06, 0x00, 0x01, 0x0d, 0x08, 0x18, 0x2b, 0x00, 0x03, + 0x20, 0x2b, 0x00, 0x03, 0x28, 0x2b, 0x00, 0x03, 0x0c, 0x19, 0x01, 0x02, 0x10, 0x19, 0x01, 0x02, 0x14, 0x19, 0x01, 0x02, 0x18, 0x19, 0x01, 0x02, 0x1c, 0x19, 0x01, 0x02, 0x20, 0x19, 0x01, 0x02, + 0x24, 0x19, 0x01, 0x02, 0x60, 0x3b, 0x02, 0x03, 0x68, 0x3b, 0x02, 0x03, 0x70, 0x3b, 0x02, 0x03, 0x78, 0x3b, 0x02, 0x03, 0x10, 0x15, 0x03, 0x03, 0x18, 0x15, 0x03, 0x03, 0x20, 0x15, 0x03, 0x03, + 0x90, 0x35, 0x04, 0x04, 0xa0, 0x35, 0x04, 0x04, 0x60, 0x11, 0x05, 0x04, 0x70, 0x11, 0x05, 0x04, 0xc0, 0x0c, 0x07, 0x05, 0xc0, 0x29, 0x08, 0x06, 0x00, 0x02, 0x0d, 0x08, 0x30, 0x2b, 0x00, 0x03, + 0x38, 0x2b, 0x00, 0x03, 0x40, 0x2b, 0x00, 0x03, 0x28, 0x19, 0x01, 0x02, 0x2c, 0x19, 0x01, 0x02, 0x30, 0x19, 0x01, 0x02, 0x34, 0x19, 0x01, 0x02, 0x38, 0x19, 0x01, 0x02, 0x3c, 0x19, 0x01, 0x02, + 0x40, 0x19, 0x01, 0x02, 0x80, 0x3b, 0x02, 0x03, 0x88, 0x3b, 0x02, 0x03, 0x90, 0x3b, 0x02, 0x03, 0x98, 0x3b, 0x02, 0x03, 0x28, 0x15, 0x03, 0x03, 0x30, 0x15, 0x03, 0x03, 0x38, 0x15, 0x03, 0x03, + 0xb0, 0x35, 0x04, 0x04, 0xc0, 0x35, 0x04, 0x04, 0x80, 0x11, 0x05, 0x04, 0x90, 0x11, 0x05, 0x04, 0xe0, 0x0c, 0x07, 0x05, 0x00, 0x2a, 0x08, 0x06, 0x00, 0x03, 0x0d, 0x08, 0x48, 0x2b, 0x00, 0x03, + 0x50, 0x2b, 0x00, 0x03, 0x58, 0x2b, 0x00, 0x03, 0x44, 0x19, 0x01, 0x02, 0x48, 0x19, 0x01, 0x02, 0x4c, 0x19, 0x01, 0x02, 0x50, 0x19, 0x01, 0x02, 0x54, 0x19, 0x01, 0x02, 0x58, 0x19, 0x01, 0x02, + 0x5c, 0x19, 0x01, 0x02, 0xa0, 0x3b, 0x02, 0x03, 0xa8, 0x3b, 0x02, 0x03, 0xb0, 0x3b, 0x02, 0x03, 0xb8, 0x3b, 0x02, 0x03, 0x40, 0x15, 0x03, 0x03, 0x48, 0x15, 0x03, 0x03, 0x50, 0x15, 0x03, 0x03, + 0xd0, 0x35, 0x04, 0x04, 0xe0, 0x35, 0x04, 0x04, 0xa0, 0x11, 0x05, 0x04, 0x40, 0x30, 0x06, 0x05, 0x00, 0x0d, 0x07, 0x05, 0x40, 0x2a, 0x08, 0x06, 0x00, 0x04, 0x0d, 0x08, 0x60, 0x2b, 0x00, 0x03, + 0x68, 0x2b, 0x00, 0x03, 0x70, 0x2b, 0x00, 0x03, 0x60, 0x19, 0x01, 0x02, 0x64, 0x19, 0x01, 0x02, 0x68, 0x19, 0x01, 0x02, 0x6c, 0x19, 0x01, 0x02, 0x70, 0x19, 0x01, 0x02, 0x74, 0x19, 0x01, 0x02, + 0x78, 0x19, 0x01, 0x02, 0xc0, 0x3b, 0x02, 0x03, 0xc8, 0x3b, 0x02, 0x03, 0xd0, 0x3b, 0x02, 0x03, 0xd8, 0x3b, 0x02, 0x03, 0x58, 0x15, 0x03, 0x03, 0x60, 0x15, 0x03, 0x03, 0x68, 0x15, 0x03, 0x03, + 0xf0, 0x35, 0x04, 0x04, 0x00, 0x36, 0x04, 0x04, 0xb0, 0x11, 0x05, 0x04, 0x60, 0x30, 0x06, 0x05, 0x20, 0x0d, 0x07, 0x05, 0x80, 0x2a, 0x08, 0x06, 0x00, 0x16, 0x0e, 0x09, 0x78, 0x2b, 0x00, 0x03, + 0x80, 0x2b, 0x00, 0x03, 0x88, 0x2b, 0x00, 0x03, 0x7c, 0x19, 0x01, 0x02, 0x80, 0x19, 0x01, 0x02, 0x84, 0x19, 0x01, 0x02, 0x88, 0x19, 0x01, 0x02, 0x8c, 0x19, 0x01, 0x02, 0x90, 0x19, 0x01, 0x02, + 0x94, 0x19, 0x01, 0x02, 0xe0, 0x3b, 0x02, 0x03, 0xe8, 0x3b, 0x02, 0x03, 0xf0, 0x3b, 0x02, 0x03, 0xf8, 0x3b, 0x02, 0x03, 0x70, 0x15, 0x03, 0x03, 0x78, 0x15, 0x03, 0x03, 0x80, 0x15, 0x03, 0x03, + 0x10, 0x36, 0x04, 0x04, 0x20, 0x36, 0x04, 0x04, 0xc0, 0x11, 0x05, 0x04, 0x80, 0x30, 0x06, 0x05, 0x40, 0x0d, 0x07, 0x05, 0xc0, 0x2a, 0x08, 0x06, 0x00, 0x18, 0x0e, 0x09, 0x90, 0x2b, 0x00, 0x03, + 0x98, 0x2b, 0x00, 0x03, 0xa0, 0x2b, 0x00, 0x03, 0x98, 0x19, 0x01, 0x02, 0x9c, 0x19, 0x01, 0x02, 0xa0, 0x19, 0x01, 0x02, 0xa4, 0x19, 0x01, 0x02, 0xa8, 0x19, 0x01, 0x02, 0xac, 0x19, 0x01, 0x02, + 0xb0, 0x19, 0x01, 0x02, 0x00, 0x3c, 0x02, 0x03, 0x08, 0x3c, 0x02, 0x03, 0x10, 0x3c, 0x02, 0x03, 0x18, 0x3c, 0x02, 0x03, 0x88, 0x15, 0x03, 0x03, 0x90, 0x15, 0x03, 0x03, 0x98, 0x15, 0x03, 0x03, + 0x30, 0x36, 0x04, 0x04, 0x40, 0x36, 0x04, 0x04, 0xd0, 0x11, 0x05, 0x04, 0xa0, 0x30, 0x06, 0x05, 0x60, 0x0d, 0x07, 0x05, 0x00, 0x2b, 0x08, 0x06, 0x00, 0x1a, 0x0e, 0x09, 0xa8, 0x2b, 0x00, 0x03, + 0xb0, 0x2b, 0x00, 0x03, 0xb8, 0x2b, 0x00, 0x03, 0xb4, 0x19, 0x01, 0x02, 0xb8, 0x19, 0x01, 0x02, 0xbc, 0x19, 0x01, 0x02, 0xc0, 0x19, 0x01, 0x02, 0xc4, 0x19, 0x01, 0x02, 0xc8, 0x19, 0x01, 0x02, + 0xcc, 0x19, 0x01, 0x02, 0x20, 0x3c, 0x02, 0x03, 0x28, 0x3c, 0x02, 0x03, 0x30, 0x3c, 0x02, 0x03, 0x38, 0x3c, 0x02, 0x03, 0xa0, 0x15, 0x03, 0x03, 0xa8, 0x15, 0x03, 0x03, 0xb0, 0x15, 0x03, 0x03, + 0x50, 0x36, 0x04, 0x04, 0x60, 0x36, 0x04, 0x04, 0xe0, 0x11, 0x05, 0x04, 0xc0, 0x30, 0x06, 0x05, 0x80, 0x0d, 0x07, 0x05, 0x40, 0x2b, 0x08, 0x06, 0x00, 0x1c, 0x0e, 0x09, 0xc0, 0x2b, 0x00, 0x03, + 0xc8, 0x2b, 0x00, 0x03, 0xd0, 0x2b, 0x00, 0x03, 0xd0, 0x19, 0x01, 0x02, 0xd4, 0x19, 0x01, 0x02, 0xd8, 0x19, 0x01, 0x02, 0xdc, 0x19, 0x01, 0x02, 0xe0, 0x19, 0x01, 0x02, 0xe4, 0x19, 0x01, 0x02, + 0xe8, 0x19, 0x01, 0x02, 0x40, 0x3c, 0x02, 0x03, 0x48, 0x3c, 0x02, 0x03, 0x50, 0x3c, 0x02, 0x03, 0x58, 0x3c, 0x02, 0x03, 0xb8, 0x15, 0x03, 0x03, 0xc0, 0x15, 0x03, 0x03, 0xc8, 0x15, 0x03, 0x03, + 0x70, 0x36, 0x04, 0x04, 0x80, 0x36, 0x04, 0x04, 0xf0, 0x11, 0x05, 0x04, 0xe0, 0x30, 0x06, 0x05, 0xa0, 0x0d, 0x07, 0x05, 0x80, 0x2b, 0x08, 0x06, 0x00, 0x38, 0x0f, 0x0a, 0xd8, 0x2b, 0x00, 0x03, + 0xe0, 0x2b, 0x00, 0x03, 0xe8, 0x2b, 0x00, 0x03, 0xec, 0x19, 0x01, 0x02, 0xf0, 0x19, 0x01, 0x02, 0xf4, 0x19, 0x01, 0x02, 0xf8, 0x19, 0x01, 0x02, 0xfc, 0x19, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, + 0x04, 0x1a, 0x01, 0x02, 0x60, 0x3c, 0x02, 0x03, 0x68, 0x3c, 0x02, 0x03, 0x70, 0x3c, 0x02, 0x03, 0x78, 0x3c, 0x02, 0x03, 0xd0, 0x15, 0x03, 0x03, 0xd8, 0x15, 0x03, 0x03, 0xe0, 0x15, 0x03, 0x03, + 0x90, 0x36, 0x04, 0x04, 0xa0, 0x36, 0x04, 0x04, 0x00, 0x12, 0x05, 0x04, 0x00, 0x31, 0x06, 0x05, 0xc0, 0x0d, 0x07, 0x05, 0xc0, 0x2b, 0x08, 0x06, 0x00, 0x3c, 0x0f, 0x0a, 0xf0, 0x2b, 0x00, 0x03, + 0xf8, 0x2b, 0x00, 0x03, 0x00, 0x2c, 0x00, 0x03, 0x08, 0x1a, 0x01, 0x02, 0x0c, 0x1a, 0x01, 0x02, 0x10, 0x1a, 0x01, 0x02, 0x14, 0x1a, 0x01, 0x02, 0x18, 0x1a, 0x01, 0x02, 0x1c, 0x1a, 0x01, 0x02, + 0x20, 0x1a, 0x01, 0x02, 0x80, 0x3c, 0x02, 0x03, 0x88, 0x3c, 0x02, 0x03, 0x90, 0x3c, 0x02, 0x03, 0x98, 0x3c, 0x02, 0x03, 0xe8, 0x15, 0x03, 0x03, 0xf0, 0x15, 0x03, 0x03, 0xf8, 0x15, 0x03, 0x03, + 0xb0, 0x36, 0x04, 0x04, 0xc0, 0x36, 0x04, 0x04, 0x10, 0x12, 0x05, 0x04, 0x20, 0x31, 0x06, 0x05, 0xe0, 0x0d, 0x07, 0x05, 0x00, 0x2c, 0x08, 0x06, 0x00, 0x00, 0x0f, 0x09, 0x08, 0x2c, 0x00, 0x03, + 0x10, 0x2c, 0x00, 0x03, 0x18, 0x2c, 0x00, 0x03, 0x24, 0x1a, 0x01, 0x02, 0x28, 0x1a, 0x01, 0x02, 0x2c, 0x1a, 0x01, 0x02, 0x30, 0x1a, 0x01, 0x02, 0x34, 0x1a, 0x01, 0x02, 0x38, 0x1a, 0x01, 0x02, + 0x3c, 0x1a, 0x01, 0x02, 0xa0, 0x3c, 0x02, 0x03, 0xa8, 0x3c, 0x02, 0x03, 0xb0, 0x3c, 0x02, 0x03, 0xb8, 0x3c, 0x02, 0x03, 0x00, 0x16, 0x03, 0x03, 0x08, 0x16, 0x03, 0x03, 0x10, 0x16, 0x03, 0x03, + 0xd0, 0x36, 0x04, 0x04, 0xe0, 0x36, 0x04, 0x04, 0x20, 0x12, 0x05, 0x04, 0x40, 0x31, 0x06, 0x05, 0x00, 0x0e, 0x07, 0x05, 0x40, 0x2c, 0x08, 0x06, 0x00, 0x02, 0x0f, 0x09, 0x20, 0x2c, 0x00, 0x03, + 0x28, 0x2c, 0x00, 0x03, 0x30, 0x2c, 0x00, 0x03, 0x40, 0x1a, 0x01, 0x02, 0x44, 0x1a, 0x01, 0x02, 0x48, 0x1a, 0x01, 0x02, 0x4c, 0x1a, 0x01, 0x02, 0x50, 0x1a, 0x01, 0x02, 0x54, 0x1a, 0x01, 0x02, + 0x58, 0x1a, 0x01, 0x02, 0xc0, 0x3c, 0x02, 0x03, 0xc8, 0x3c, 0x02, 0x03, 0xd0, 0x3c, 0x02, 0x03, 0xd8, 0x3c, 0x02, 0x03, 0x18, 0x16, 0x03, 0x03, 0x20, 0x16, 0x03, 0x03, 0x28, 0x16, 0x03, 0x03, + 0xf0, 0x36, 0x04, 0x04, 0x00, 0x37, 0x04, 0x04, 0x30, 0x12, 0x05, 0x04, 0x60, 0x31, 0x06, 0x05, 0x20, 0x0e, 0x07, 0x05, 0x80, 0x2c, 0x08, 0x06, 0x00, 0x14, 0x10, 0x0a, 0x38, 0x2c, 0x00, 0x03, + 0x40, 0x2c, 0x00, 0x03, 0x48, 0x2c, 0x00, 0x03, 0x5c, 0x1a, 0x01, 0x02, 0x60, 0x1a, 0x01, 0x02, 0x64, 0x1a, 0x01, 0x02, 0x68, 0x1a, 0x01, 0x02, 0x6c, 0x1a, 0x01, 0x02, 0x70, 0x1a, 0x01, 0x02, + 0x74, 0x1a, 0x01, 0x02, 0xe0, 0x3c, 0x02, 0x03, 0xe8, 0x3c, 0x02, 0x03, 0xf0, 0x3c, 0x02, 0x03, 0xf8, 0x3c, 0x02, 0x03, 0x30, 0x16, 0x03, 0x03, 0x38, 0x16, 0x03, 0x03, 0x40, 0x16, 0x03, 0x03, + 0x10, 0x37, 0x04, 0x04, 0x20, 0x37, 0x04, 0x04, 0x40, 0x12, 0x05, 0x04, 0x80, 0x31, 0x06, 0x05, 0x40, 0x0e, 0x07, 0x05, 0xc0, 0x2c, 0x08, 0x06, 0x00, 0x18, 0x10, 0x0a, 0x50, 0x2c, 0x00, 0x03, + 0x58, 0x2c, 0x00, 0x03, 0x60, 0x2c, 0x00, 0x03, 0x78, 0x1a, 0x01, 0x02, 0x7c, 0x1a, 0x01, 0x02, 0x80, 0x1a, 0x01, 0x02, 0x84, 0x1a, 0x01, 0x02, 0x88, 0x1a, 0x01, 0x02, 0x8c, 0x1a, 0x01, 0x02, + 0x90, 0x1a, 0x01, 0x02, 0x00, 0x3d, 0x02, 0x03, 0x08, 0x3d, 0x02, 0x03, 0x10, 0x3d, 0x02, 0x03, 0x18, 0x3d, 0x02, 0x03, 0x48, 0x16, 0x03, 0x03, 0x50, 0x16, 0x03, 0x03, 0x58, 0x16, 0x03, 0x03, + 0x30, 0x37, 0x04, 0x04, 0x40, 0x37, 0x04, 0x04, 0x50, 0x12, 0x05, 0x04, 0xa0, 0x31, 0x06, 0x05, 0x60, 0x0e, 0x07, 0x05, 0x40, 0x0a, 0x09, 0x06, 0x00, 0x30, 0x11, 0x0b, 0x68, 0x2c, 0x00, 0x03, + 0x70, 0x2c, 0x00, 0x03, 0x78, 0x2c, 0x00, 0x03, 0x94, 0x1a, 0x01, 0x02, 0x98, 0x1a, 0x01, 0x02, 0x9c, 0x1a, 0x01, 0x02, 0xa0, 0x1a, 0x01, 0x02, 0xa4, 0x1a, 0x01, 0x02, 0xa8, 0x1a, 0x01, 0x02, + 0xac, 0x1a, 0x01, 0x02, 0x20, 0x3d, 0x02, 0x03, 0x28, 0x3d, 0x02, 0x03, 0x30, 0x3d, 0x02, 0x03, 0x38, 0x3d, 0x02, 0x03, 0x60, 0x16, 0x03, 0x03, 0x68, 0x16, 0x03, 0x03, 0x70, 0x16, 0x03, 0x03, + 0x50, 0x37, 0x04, 0x04, 0x60, 0x37, 0x04, 0x04, 0x60, 0x12, 0x05, 0x04, 0xc0, 0x31, 0x06, 0x05, 0x80, 0x0e, 0x07, 0x05, 0x80, 0x0a, 0x09, 0x06, 0x00, 0x10, 0x12, 0x0b, 0x80, 0x2c, 0x00, 0x03, + 0x88, 0x2c, 0x00, 0x03, 0x90, 0x2c, 0x00, 0x03, 0xb0, 0x1a, 0x01, 0x02, 0xb4, 0x1a, 0x01, 0x02, 0xb8, 0x1a, 0x01, 0x02, 0xbc, 0x1a, 0x01, 0x02, 0xc0, 0x1a, 0x01, 0x02, 0xc4, 0x1a, 0x01, 0x02, + 0xc8, 0x1a, 0x01, 0x02, 0x40, 0x3d, 0x02, 0x03, 0x48, 0x3d, 0x02, 0x03, 0x50, 0x3d, 0x02, 0x03, 0x58, 0x3d, 0x02, 0x03, 0x78, 0x16, 0x03, 0x03, 0x80, 0x16, 0x03, 0x03, 0x88, 0x16, 0x03, 0x03, + 0x70, 0x37, 0x04, 0x04, 0x80, 0x37, 0x04, 0x04, 0x70, 0x12, 0x05, 0x04, 0xe0, 0x31, 0x06, 0x05, 0xa0, 0x0e, 0x07, 0x05, 0xc0, 0x0a, 0x09, 0x06, 0x00, 0x18, 0x12, 0x0b, 0x98, 0x2c, 0x00, 0x03, + 0xa0, 0x2c, 0x00, 0x03, 0xa8, 0x2c, 0x00, 0x03, 0xcc, 0x1a, 0x01, 0x02, 0xd0, 0x1a, 0x01, 0x02, 0xd4, 0x1a, 0x01, 0x02, 0xd8, 0x1a, 0x01, 0x02, 0xdc, 0x1a, 0x01, 0x02, 0xe0, 0x1a, 0x01, 0x02, + 0xe4, 0x1a, 0x01, 0x02, 0x60, 0x3d, 0x02, 0x03, 0x68, 0x3d, 0x02, 0x03, 0x70, 0x3d, 0x02, 0x03, 0x78, 0x3d, 0x02, 0x03, 0x90, 0x16, 0x03, 0x03, 0x98, 0x16, 0x03, 0x03, 0xa0, 0x16, 0x03, 0x03, + 0x90, 0x37, 0x04, 0x04, 0xa0, 0x37, 0x04, 0x04, 0x80, 0x12, 0x05, 0x04, 0x00, 0x32, 0x06, 0x05, 0xc0, 0x0e, 0x07, 0x05, 0x00, 0x0b, 0x09, 0x06, 0x00, 0x10, 0x14, 0x0c, 0xb0, 0x2c, 0x00, 0x03, + 0xb8, 0x2c, 0x00, 0x03, 0xc0, 0x2c, 0x00, 0x03, 0xe8, 0x1a, 0x01, 0x02, 0xec, 0x1a, 0x01, 0x02, 0xf0, 0x1a, 0x01, 0x02, 0xf4, 0x1a, 0x01, 0x02, 0xf8, 0x1a, 0x01, 0x02, 0xfc, 0x1a, 0x01, 0x02, + 0x00, 0x1b, 0x01, 0x02, 0x80, 0x3d, 0x02, 0x03, 0x88, 0x3d, 0x02, 0x03, 0x90, 0x3d, 0x02, 0x03, 0x98, 0x3d, 0x02, 0x03, 0xa8, 0x16, 0x03, 0x03, 0xb0, 0x16, 0x03, 0x03, 0xb8, 0x16, 0x03, 0x03, + 0xb0, 0x37, 0x04, 0x04, 0xc0, 0x37, 0x04, 0x04, 0x90, 0x12, 0x05, 0x04, 0x20, 0x32, 0x06, 0x05, 0xe0, 0x0e, 0x07, 0x05, 0x40, 0x0b, 0x09, 0x06, 0x00, 0x00, 0x16, 0x0d, 0xc8, 0x2c, 0x00, 0x03, + 0xd0, 0x2c, 0x00, 0x03, 0xd8, 0x2c, 0x00, 0x03, 0x04, 0x1b, 0x01, 0x02, 0x08, 0x1b, 0x01, 0x02, 0x0c, 0x1b, 0x01, 0x02, 0x10, 0x1b, 0x01, 0x02, 0x14, 0x1b, 0x01, 0x02, 0x18, 0x1b, 0x01, 0x02, + 0x1c, 0x1b, 0x01, 0x02, 0xa0, 0x3d, 0x02, 0x03, 0xa8, 0x3d, 0x02, 0x03, 0xb0, 0x3d, 0x02, 0x03, 0xb8, 0x3d, 0x02, 0x03, 0xc0, 0x16, 0x03, 0x03, 0xc8, 0x16, 0x03, 0x03, 0xd0, 0x16, 0x03, 0x03, + 0xd0, 0x37, 0x04, 0x04, 0xe0, 0x37, 0x04, 0x04, 0xa0, 0x12, 0x05, 0x04, 0x40, 0x32, 0x06, 0x05, 0x00, 0x0f, 0x07, 0x05, 0x80, 0x0b, 0x09, 0x06, 0xe0, 0x2c, 0x00, 0x03, 0xe8, 0x2c, 0x00, 0x03, + 0xf0, 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x03, 0x20, 0x1b, 0x01, 0x02, 0x24, 0x1b, 0x01, 0x02, 0x28, 0x1b, 0x01, 0x02, 0x2c, 0x1b, 0x01, 0x02, 0x30, 0x1b, 0x01, 0x02, 0x34, 0x1b, 0x01, 0x02, + 0xc0, 0x3d, 0x02, 0x03, 0xc8, 0x3d, 0x02, 0x03, 0xd0, 0x3d, 0x02, 0x03, 0xd8, 0x3d, 0x02, 0x03, 0xe0, 0x3d, 0x02, 0x03, 0xd8, 0x16, 0x03, 0x03, 0xe0, 0x16, 0x03, 0x03, 0xe8, 0x16, 0x03, 0x03, + 0xf0, 0x37, 0x04, 0x04, 0x00, 0x38, 0x04, 0x04, 0xb0, 0x12, 0x05, 0x04, 0x60, 0x32, 0x06, 0x05, 0x20, 0x0f, 0x07, 0x05, 0xc0, 0x0b, 0x09, 0x06, 0x00, 0x2d, 0x00, 0x03, 0x08, 0x2d, 0x00, 0x03, + 0x10, 0x2d, 0x00, 0x03, 0x18, 0x2d, 0x00, 0x03, 0x38, 0x1b, 0x01, 0x02, 0x3c, 0x1b, 0x01, 0x02, 0x40, 0x1b, 0x01, 0x02, 0x44, 0x1b, 0x01, 0x02, 0x48, 0x1b, 0x01, 0x02, 0x4c, 0x1b, 0x01, 0x02, + 0xe8, 0x3d, 0x02, 0x03, 0xf0, 0x3d, 0x02, 0x03, 0xf8, 0x3d, 0x02, 0x03, 0x00, 0x3e, 0x02, 0x03, 0x08, 0x3e, 0x02, 0x03, 0xf0, 0x16, 0x03, 0x03, 0xf8, 0x16, 0x03, 0x03, 0x00, 0x17, 0x03, 0x03, + 0x10, 0x38, 0x04, 0x04, 0x20, 0x38, 0x04, 0x04, 0xc0, 0x12, 0x05, 0x04, 0x80, 0x32, 0x06, 0x05, 0x40, 0x0f, 0x07, 0x05, 0x00, 0x0c, 0x09, 0x06, 0x20, 0x2d, 0x00, 0x03, 0x28, 0x2d, 0x00, 0x03, + 0x30, 0x2d, 0x00, 0x03, 0x38, 0x2d, 0x00, 0x03, 0x50, 0x1b, 0x01, 0x02, 0x54, 0x1b, 0x01, 0x02, 0x58, 0x1b, 0x01, 0x02, 0x5c, 0x1b, 0x01, 0x02, 0x60, 0x1b, 0x01, 0x02, 0x64, 0x1b, 0x01, 0x02, + 0x10, 0x3e, 0x02, 0x03, 0x18, 0x3e, 0x02, 0x03, 0x20, 0x3e, 0x02, 0x03, 0x28, 0x3e, 0x02, 0x03, 0x30, 0x3e, 0x02, 0x03, 0x08, 0x17, 0x03, 0x03, 0x10, 0x17, 0x03, 0x03, 0x18, 0x17, 0x03, 0x03, + 0x30, 0x38, 0x04, 0x04, 0x40, 0x38, 0x04, 0x04, 0xd0, 0x12, 0x05, 0x04, 0xa0, 0x32, 0x06, 0x05, 0x60, 0x0f, 0x07, 0x05, 0x40, 0x0c, 0x09, 0x06, 0x40, 0x2d, 0x00, 0x03, 0x48, 0x2d, 0x00, 0x03, + 0x50, 0x2d, 0x00, 0x03, 0x58, 0x2d, 0x00, 0x03, 0x68, 0x1b, 0x01, 0x02, 0x6c, 0x1b, 0x01, 0x02, 0x70, 0x1b, 0x01, 0x02, 0x74, 0x1b, 0x01, 0x02, 0x78, 0x1b, 0x01, 0x02, 0x7c, 0x1b, 0x01, 0x02, + 0x38, 0x3e, 0x02, 0x03, 0x40, 0x3e, 0x02, 0x03, 0x48, 0x3e, 0x02, 0x03, 0x50, 0x3e, 0x02, 0x03, 0x58, 0x3e, 0x02, 0x03, 0x20, 0x17, 0x03, 0x03, 0x28, 0x17, 0x03, 0x03, 0x30, 0x17, 0x03, 0x03, + 0x50, 0x38, 0x04, 0x04, 0x60, 0x38, 0x04, 0x04, 0xe0, 0x12, 0x05, 0x04, 0xc0, 0x32, 0x06, 0x05, 0x80, 0x0f, 0x07, 0x05, 0x80, 0x0c, 0x09, 0x06, 0x60, 0x2d, 0x00, 0x03, 0x68, 0x2d, 0x00, 0x03, + 0x70, 0x2d, 0x00, 0x03, 0x78, 0x2d, 0x00, 0x03, 0x80, 0x1b, 0x01, 0x02, 0x84, 0x1b, 0x01, 0x02, 0x88, 0x1b, 0x01, 0x02, 0x8c, 0x1b, 0x01, 0x02, 0x90, 0x1b, 0x01, 0x02, 0x94, 0x1b, 0x01, 0x02, + 0x60, 0x3e, 0x02, 0x03, 0x68, 0x3e, 0x02, 0x03, 0x70, 0x3e, 0x02, 0x03, 0x78, 0x3e, 0x02, 0x03, 0x80, 0x3e, 0x02, 0x03, 0x38, 0x17, 0x03, 0x03, 0x40, 0x17, 0x03, 0x03, 0x48, 0x17, 0x03, 0x03, + 0x70, 0x38, 0x04, 0x04, 0x80, 0x38, 0x04, 0x04, 0xf0, 0x12, 0x05, 0x04, 0xe0, 0x32, 0x06, 0x05, 0xa0, 0x0f, 0x07, 0x05, 0xc0, 0x0c, 0x09, 0x06, 0x80, 0x2d, 0x00, 0x03, 0x88, 0x2d, 0x00, 0x03, + 0x90, 0x2d, 0x00, 0x03, 0x98, 0x2d, 0x00, 0x03, 0x98, 0x1b, 0x01, 0x02, 0x9c, 0x1b, 0x01, 0x02, 0xa0, 0x1b, 0x01, 0x02, 0xa4, 0x1b, 0x01, 0x02, 0xa8, 0x1b, 0x01, 0x02, 0xac, 0x1b, 0x01, 0x02, + 0x88, 0x3e, 0x02, 0x03, 0x90, 0x3e, 0x02, 0x03, 0x98, 0x3e, 0x02, 0x03, 0xa0, 0x3e, 0x02, 0x03, 0xa8, 0x3e, 0x02, 0x03, 0x50, 0x17, 0x03, 0x03, 0x58, 0x17, 0x03, 0x03, 0x60, 0x17, 0x03, 0x03, + 0x90, 0x38, 0x04, 0x04, 0xa0, 0x38, 0x04, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x33, 0x06, 0x05, 0xc0, 0x0f, 0x07, 0x05, 0x00, 0x0d, 0x09, 0x06, 0xa0, 0x2d, 0x00, 0x03, 0xa8, 0x2d, 0x00, 0x03, + 0xb0, 0x2d, 0x00, 0x03, 0xb8, 0x2d, 0x00, 0x03, 0xb0, 0x1b, 0x01, 0x02, 0xb4, 0x1b, 0x01, 0x02, 0xb8, 0x1b, 0x01, 0x02, 0xbc, 0x1b, 0x01, 0x02, 0xc0, 0x1b, 0x01, 0x02, 0xc4, 0x1b, 0x01, 0x02, + 0xb0, 0x3e, 0x02, 0x03, 0xb8, 0x3e, 0x02, 0x03, 0xc0, 0x3e, 0x02, 0x03, 0xc8, 0x3e, 0x02, 0x03, 0xd0, 0x3e, 0x02, 0x03, 0x68, 0x17, 0x03, 0x03, 0x70, 0x17, 0x03, 0x03, 0x78, 0x17, 0x03, 0x03, + 0xb0, 0x38, 0x04, 0x04, 0xc0, 0x38, 0x04, 0x04, 0x10, 0x13, 0x05, 0x04, 0x20, 0x33, 0x06, 0x05, 0xe0, 0x0f, 0x07, 0x05, 0x40, 0x0d, 0x09, 0x06, 0xc0, 0x2d, 0x00, 0x03, 0xc8, 0x2d, 0x00, 0x03, + 0xd0, 0x2d, 0x00, 0x03, 0xd8, 0x2d, 0x00, 0x03, 0xc8, 0x1b, 0x01, 0x02, 0xcc, 0x1b, 0x01, 0x02, 0xd0, 0x1b, 0x01, 0x02, 0xd4, 0x1b, 0x01, 0x02, 0xd8, 0x1b, 0x01, 0x02, 0xdc, 0x1b, 0x01, 0x02, + 0xd8, 0x3e, 0x02, 0x03, 0xe0, 0x3e, 0x02, 0x03, 0xe8, 0x3e, 0x02, 0x03, 0xf0, 0x3e, 0x02, 0x03, 0xf8, 0x3e, 0x02, 0x03, 0x80, 0x17, 0x03, 0x03, 0x88, 0x17, 0x03, 0x03, 0x90, 0x17, 0x03, 0x03, + 0xd0, 0x38, 0x04, 0x04, 0xe0, 0x38, 0x04, 0x04, 0x20, 0x13, 0x05, 0x04, 0x40, 0x33, 0x06, 0x05, 0x00, 0x10, 0x07, 0x05, 0x80, 0x0d, 0x09, 0x06, 0xe0, 0x2d, 0x00, 0x03, 0xe8, 0x2d, 0x00, 0x03, + 0xf0, 0x2d, 0x00, 0x03, 0xf8, 0x2d, 0x00, 0x03, 0xe0, 0x1b, 0x01, 0x02, 0xe4, 0x1b, 0x01, 0x02, 0xe8, 0x1b, 0x01, 0x02, 0xec, 0x1b, 0x01, 0x02, 0xf0, 0x1b, 0x01, 0x02, 0xf4, 0x1b, 0x01, 0x02, + 0x00, 0x3f, 0x02, 0x03, 0x08, 0x3f, 0x02, 0x03, 0x10, 0x3f, 0x02, 0x03, 0x18, 0x3f, 0x02, 0x03, 0x20, 0x3f, 0x02, 0x03, 0x98, 0x17, 0x03, 0x03, 0xa0, 0x17, 0x03, 0x03, 0xa8, 0x17, 0x03, 0x03, + 0xf0, 0x38, 0x04, 0x04, 0x00, 0x39, 0x04, 0x04, 0x30, 0x13, 0x05, 0x04, 0x60, 0x33, 0x06, 0x05, 0x20, 0x10, 0x07, 0x05, 0xc0, 0x0d, 0x09, 0x06, 0x00, 0x2e, 0x00, 0x03, 0x08, 0x2e, 0x00, 0x03, + 0x10, 0x2e, 0x00, 0x03, 0x18, 0x2e, 0x00, 0x03, 0xf8, 0x1b, 0x01, 0x02, 0xfc, 0x1b, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x04, 0x1c, 0x01, 0x02, 0x08, 0x1c, 0x01, 0x02, 0x0c, 0x1c, 0x01, 0x02, + 0x28, 0x3f, 0x02, 0x03, 0x30, 0x3f, 0x02, 0x03, 0x38, 0x3f, 0x02, 0x03, 0x40, 0x3f, 0x02, 0x03, 0x48, 0x3f, 0x02, 0x03, 0xb0, 0x17, 0x03, 0x03, 0xb8, 0x17, 0x03, 0x03, 0xc0, 0x17, 0x03, 0x03, + 0x10, 0x39, 0x04, 0x04, 0x20, 0x39, 0x04, 0x04, 0x40, 0x13, 0x05, 0x04, 0x80, 0x33, 0x06, 0x05, 0x40, 0x10, 0x07, 0x05, 0x00, 0x0e, 0x09, 0x06, 0x20, 0x2e, 0x00, 0x03, 0x28, 0x2e, 0x00, 0x03, + 0x30, 0x2e, 0x00, 0x03, 0x38, 0x2e, 0x00, 0x03, 0x10, 0x1c, 0x01, 0x02, 0x14, 0x1c, 0x01, 0x02, 0x18, 0x1c, 0x01, 0x02, 0x1c, 0x1c, 0x01, 0x02, 0x20, 0x1c, 0x01, 0x02, 0x24, 0x1c, 0x01, 0x02, + 0x50, 0x3f, 0x02, 0x03, 0x58, 0x3f, 0x02, 0x03, 0x60, 0x3f, 0x02, 0x03, 0x68, 0x3f, 0x02, 0x03, 0x70, 0x3f, 0x02, 0x03, 0xc8, 0x17, 0x03, 0x03, 0xd0, 0x17, 0x03, 0x03, 0xd8, 0x17, 0x03, 0x03, + 0x30, 0x39, 0x04, 0x04, 0x40, 0x39, 0x04, 0x04, 0x50, 0x13, 0x05, 0x04, 0xa0, 0x33, 0x06, 0x05, 0x60, 0x10, 0x07, 0x05, 0x40, 0x0e, 0x09, 0x06, 0x40, 0x2e, 0x00, 0x03, 0x48, 0x2e, 0x00, 0x03, + 0x50, 0x2e, 0x00, 0x03, 0x58, 0x2e, 0x00, 0x03, 0x28, 0x1c, 0x01, 0x02, 0x2c, 0x1c, 0x01, 0x02, 0x30, 0x1c, 0x01, 0x02, 0x34, 0x1c, 0x01, 0x02, 0x38, 0x1c, 0x01, 0x02, 0x3c, 0x1c, 0x01, 0x02, + 0x78, 0x3f, 0x02, 0x03, 0x80, 0x3f, 0x02, 0x03, 0x88, 0x3f, 0x02, 0x03, 0x90, 0x3f, 0x02, 0x03, 0x98, 0x3f, 0x02, 0x03, 0xe0, 0x17, 0x03, 0x03, 0xe8, 0x17, 0x03, 0x03, 0xf0, 0x17, 0x03, 0x03, + 0x50, 0x39, 0x04, 0x04, 0x60, 0x39, 0x04, 0x04, 0x60, 0x13, 0x05, 0x04, 0xc0, 0x33, 0x06, 0x05, 0x80, 0x10, 0x07, 0x05, 0x80, 0x0e, 0x09, 0x06, 0x60, 0x2e, 0x00, 0x03, 0x68, 0x2e, 0x00, 0x03, + 0x70, 0x2e, 0x00, 0x03, 0x78, 0x2e, 0x00, 0x03, 0x40, 0x1c, 0x01, 0x02, 0x44, 0x1c, 0x01, 0x02, 0x48, 0x1c, 0x01, 0x02, 0x4c, 0x1c, 0x01, 0x02, 0x50, 0x1c, 0x01, 0x02, 0x54, 0x1c, 0x01, 0x02, + 0xa0, 0x3f, 0x02, 0x03, 0xa8, 0x3f, 0x02, 0x03, 0xb0, 0x3f, 0x02, 0x03, 0xb8, 0x3f, 0x02, 0x03, 0xc0, 0x3f, 0x02, 0x03, 0xf8, 0x17, 0x03, 0x03, 0x00, 0x18, 0x03, 0x03, 0x08, 0x18, 0x03, 0x03, + 0x70, 0x39, 0x04, 0x04, 0x80, 0x39, 0x04, 0x04, 0x70, 0x13, 0x05, 0x04, 0xe0, 0x33, 0x06, 0x05, 0xa0, 0x10, 0x07, 0x05, 0xc0, 0x0e, 0x09, 0x06, 0x80, 0x2e, 0x00, 0x03, 0x88, 0x2e, 0x00, 0x03, + 0x90, 0x2e, 0x00, 0x03, 0x98, 0x2e, 0x00, 0x03, 0x58, 0x1c, 0x01, 0x02, 0x5c, 0x1c, 0x01, 0x02, 0x60, 0x1c, 0x01, 0x02, 0x64, 0x1c, 0x01, 0x02, 0x68, 0x1c, 0x01, 0x02, 0x6c, 0x1c, 0x01, 0x02, + 0xc8, 0x3f, 0x02, 0x03, 0xd0, 0x3f, 0x02, 0x03, 0xd8, 0x3f, 0x02, 0x03, 0xe0, 0x3f, 0x02, 0x03, 0xe8, 0x3f, 0x02, 0x03, 0x10, 0x18, 0x03, 0x03, 0x18, 0x18, 0x03, 0x03, 0x20, 0x18, 0x03, 0x03, + 0x90, 0x39, 0x04, 0x04, 0xa0, 0x39, 0x04, 0x04, 0x80, 0x13, 0x05, 0x04, 0x00, 0x34, 0x06, 0x05, 0xc0, 0x10, 0x07, 0x05, 0x00, 0x0f, 0x09, 0x06, 0xa0, 0x2e, 0x00, 0x03, 0xa8, 0x2e, 0x00, 0x03, + 0xb0, 0x2e, 0x00, 0x03, 0xb8, 0x2e, 0x00, 0x03, 0x70, 0x1c, 0x01, 0x02, 0x74, 0x1c, 0x01, 0x02, 0x78, 0x1c, 0x01, 0x02, 0x7c, 0x1c, 0x01, 0x02, 0x80, 0x1c, 0x01, 0x02, 0x84, 0x1c, 0x01, 0x02, + 0xf0, 0x3f, 0x02, 0x03, 0xf8, 0x3f, 0x02, 0x03, 0x00, 0x00, 0x02, 0x02, 0x04, 0x00, 0x02, 0x02, 0x08, 0x00, 0x02, 0x02, 0x28, 0x18, 0x03, 0x03, 0x30, 0x18, 0x03, 0x03, 0x38, 0x18, 0x03, 0x03, + 0xb0, 0x39, 0x04, 0x04, 0xc0, 0x39, 0x04, 0x04, 0x90, 0x13, 0x05, 0x04, 0x20, 0x34, 0x06, 0x05, 0xe0, 0x10, 0x07, 0x05, 0x40, 0x0f, 0x09, 0x06, 0xc0, 0x2e, 0x00, 0x03, 0xc8, 0x2e, 0x00, 0x03, + 0xd0, 0x2e, 0x00, 0x03, 0xd8, 0x2e, 0x00, 0x03, 0x88, 0x1c, 0x01, 0x02, 0x8c, 0x1c, 0x01, 0x02, 0x90, 0x1c, 0x01, 0x02, 0x94, 0x1c, 0x01, 0x02, 0x98, 0x1c, 0x01, 0x02, 0x9c, 0x1c, 0x01, 0x02, + 0x0c, 0x00, 0x02, 0x02, 0x10, 0x00, 0x02, 0x02, 0x14, 0x00, 0x02, 0x02, 0x18, 0x00, 0x02, 0x02, 0x1c, 0x00, 0x02, 0x02, 0x40, 0x18, 0x03, 0x03, 0x48, 0x18, 0x03, 0x03, 0x50, 0x18, 0x03, 0x03, + 0xd0, 0x39, 0x04, 0x04, 0xe0, 0x39, 0x04, 0x04, 0xa0, 0x13, 0x05, 0x04, 0x40, 0x34, 0x06, 0x05, 0x00, 0x11, 0x07, 0x05, 0x80, 0x0f, 0x09, 0x06, 0xe0, 0x2e, 0x00, 0x03, 0xe8, 0x2e, 0x00, 0x03, + 0xf0, 0x2e, 0x00, 0x03, 0xf8, 0x2e, 0x00, 0x03, 0xa0, 0x1c, 0x01, 0x02, 0xa4, 0x1c, 0x01, 0x02, 0xa8, 0x1c, 0x01, 0x02, 0xac, 0x1c, 0x01, 0x02, 0xb0, 0x1c, 0x01, 0x02, 0xb4, 0x1c, 0x01, 0x02, + 0x20, 0x00, 0x02, 0x02, 0x24, 0x00, 0x02, 0x02, 0x28, 0x00, 0x02, 0x02, 0x2c, 0x00, 0x02, 0x02, 0x30, 0x00, 0x02, 0x02, 0x58, 0x18, 0x03, 0x03, 0x60, 0x18, 0x03, 0x03, 0x68, 0x18, 0x03, 0x03, + 0xf0, 0x39, 0x04, 0x04, 0x00, 0x3a, 0x04, 0x04, 0xb0, 0x13, 0x05, 0x04, 0x60, 0x34, 0x06, 0x05, 0x20, 0x11, 0x07, 0x05, 0xc0, 0x0f, 0x09, 0x06, 0x00, 0x2f, 0x00, 0x03, 0x08, 0x2f, 0x00, 0x03, + 0x10, 0x2f, 0x00, 0x03, 0x18, 0x2f, 0x00, 0x03, 0xb8, 0x1c, 0x01, 0x02, 0xbc, 0x1c, 0x01, 0x02, 0xc0, 0x1c, 0x01, 0x02, 0xc4, 0x1c, 0x01, 0x02, 0xc8, 0x1c, 0x01, 0x02, 0xcc, 0x1c, 0x01, 0x02, + 0x34, 0x00, 0x02, 0x02, 0x38, 0x00, 0x02, 0x02, 0x3c, 0x00, 0x02, 0x02, 0x40, 0x00, 0x02, 0x02, 0x44, 0x00, 0x02, 0x02, 0x70, 0x18, 0x03, 0x03, 0x78, 0x18, 0x03, 0x03, 0x80, 0x18, 0x03, 0x03, + 0x10, 0x3a, 0x04, 0x04, 0x20, 0x3a, 0x04, 0x04, 0xc0, 0x13, 0x05, 0x04, 0x80, 0x34, 0x06, 0x05, 0x40, 0x11, 0x07, 0x05, 0x00, 0x10, 0x09, 0x06, 0x20, 0x2f, 0x00, 0x03, 0x28, 0x2f, 0x00, 0x03, + 0x30, 0x2f, 0x00, 0x03, 0x38, 0x2f, 0x00, 0x03, 0xd0, 0x1c, 0x01, 0x02, 0xd4, 0x1c, 0x01, 0x02, 0xd8, 0x1c, 0x01, 0x02, 0xdc, 0x1c, 0x01, 0x02, 0xe0, 0x1c, 0x01, 0x02, 0xe4, 0x1c, 0x01, 0x02, + 0x48, 0x00, 0x02, 0x02, 0x4c, 0x00, 0x02, 0x02, 0x50, 0x00, 0x02, 0x02, 0x54, 0x00, 0x02, 0x02, 0x58, 0x00, 0x02, 0x02, 0x88, 0x18, 0x03, 0x03, 0x90, 0x18, 0x03, 0x03, 0x98, 0x18, 0x03, 0x03, + 0x30, 0x3a, 0x04, 0x04, 0x40, 0x3a, 0x04, 0x04, 0xd0, 0x13, 0x05, 0x04, 0xa0, 0x34, 0x06, 0x05, 0x60, 0x11, 0x07, 0x05, 0x40, 0x10, 0x09, 0x06, 0x40, 0x2f, 0x00, 0x03, 0x48, 0x2f, 0x00, 0x03, + 0x50, 0x2f, 0x00, 0x03, 0x58, 0x2f, 0x00, 0x03, 0xe8, 0x1c, 0x01, 0x02, 0xec, 0x1c, 0x01, 0x02, 0xf0, 0x1c, 0x01, 0x02, 0xf4, 0x1c, 0x01, 0x02, 0xf8, 0x1c, 0x01, 0x02, 0xfc, 0x1c, 0x01, 0x02, + 0x5c, 0x00, 0x02, 0x02, 0x60, 0x00, 0x02, 0x02, 0x64, 0x00, 0x02, 0x02, 0x68, 0x00, 0x02, 0x02, 0x6c, 0x00, 0x02, 0x02, 0xa0, 0x18, 0x03, 0x03, 0xa8, 0x18, 0x03, 0x03, 0xb0, 0x18, 0x03, 0x03, + 0x50, 0x3a, 0x04, 0x04, 0x60, 0x3a, 0x04, 0x04, 0xe0, 0x13, 0x05, 0x04, 0xc0, 0x34, 0x06, 0x05, 0x80, 0x11, 0x07, 0x05, 0x80, 0x10, 0x09, 0x06, 0x60, 0x2f, 0x00, 0x03, 0x68, 0x2f, 0x00, 0x03, + 0x70, 0x2f, 0x00, 0x03, 0x78, 0x2f, 0x00, 0x03, 0x00, 0x1d, 0x01, 0x02, 0x04, 0x1d, 0x01, 0x02, 0x08, 0x1d, 0x01, 0x02, 0x0c, 0x1d, 0x01, 0x02, 0x10, 0x1d, 0x01, 0x02, 0x14, 0x1d, 0x01, 0x02, + 0x70, 0x00, 0x02, 0x02, 0x74, 0x00, 0x02, 0x02, 0x78, 0x00, 0x02, 0x02, 0x7c, 0x00, 0x02, 0x02, 0x80, 0x00, 0x02, 0x02, 0xb8, 0x18, 0x03, 0x03, 0xc0, 0x18, 0x03, 0x03, 0xc8, 0x18, 0x03, 0x03, + 0x70, 0x3a, 0x04, 0x04, 0x80, 0x3a, 0x04, 0x04, 0xf0, 0x13, 0x05, 0x04, 0xe0, 0x34, 0x06, 0x05, 0xa0, 0x11, 0x07, 0x05, 0xc0, 0x10, 0x09, 0x06, 0x80, 0x2f, 0x00, 0x03, 0x88, 0x2f, 0x00, 0x03, + 0x90, 0x2f, 0x00, 0x03, 0x98, 0x2f, 0x00, 0x03, 0x18, 0x1d, 0x01, 0x02, 0x1c, 0x1d, 0x01, 0x02, 0x20, 0x1d, 0x01, 0x02, 0x24, 0x1d, 0x01, 0x02, 0x28, 0x1d, 0x01, 0x02, 0x2c, 0x1d, 0x01, 0x02, + 0x84, 0x00, 0x02, 0x02, 0x88, 0x00, 0x02, 0x02, 0x8c, 0x00, 0x02, 0x02, 0x90, 0x00, 0x02, 0x02, 0x94, 0x00, 0x02, 0x02, 0xd0, 0x18, 0x03, 0x03, 0xd8, 0x18, 0x03, 0x03, 0xe0, 0x18, 0x03, 0x03, + 0x90, 0x3a, 0x04, 0x04, 0xa0, 0x3a, 0x04, 0x04, 0x00, 0x14, 0x05, 0x04, 0x00, 0x35, 0x06, 0x05, 0xc0, 0x11, 0x07, 0x05, 0x00, 0x11, 0x09, 0x06, 0xa0, 0x2f, 0x00, 0x03, 0xa8, 0x2f, 0x00, 0x03, + 0xb0, 0x2f, 0x00, 0x03, 0xb8, 0x2f, 0x00, 0x03, 0x30, 0x1d, 0x01, 0x02, 0x34, 0x1d, 0x01, 0x02, 0x38, 0x1d, 0x01, 0x02, 0x3c, 0x1d, 0x01, 0x02, 0x40, 0x1d, 0x01, 0x02, 0x44, 0x1d, 0x01, 0x02, + 0x98, 0x00, 0x02, 0x02, 0x9c, 0x00, 0x02, 0x02, 0xa0, 0x00, 0x02, 0x02, 0xa4, 0x00, 0x02, 0x02, 0xa8, 0x00, 0x02, 0x02, 0xe8, 0x18, 0x03, 0x03, 0xf0, 0x18, 0x03, 0x03, 0xf8, 0x18, 0x03, 0x03, + 0xb0, 0x3a, 0x04, 0x04, 0xc0, 0x3a, 0x04, 0x04, 0x10, 0x14, 0x05, 0x04, 0x20, 0x35, 0x06, 0x05, 0xe0, 0x11, 0x07, 0x05, 0x80, 0x27, 0x0a, 0x07, 0xc0, 0x2f, 0x00, 0x03, 0xc8, 0x2f, 0x00, 0x03, + 0xd0, 0x2f, 0x00, 0x03, 0xd8, 0x2f, 0x00, 0x03, 0x48, 0x1d, 0x01, 0x02, 0x4c, 0x1d, 0x01, 0x02, 0x50, 0x1d, 0x01, 0x02, 0x54, 0x1d, 0x01, 0x02, 0x58, 0x1d, 0x01, 0x02, 0x5c, 0x1d, 0x01, 0x02, + 0xac, 0x00, 0x02, 0x02, 0xb0, 0x00, 0x02, 0x02, 0xb4, 0x00, 0x02, 0x02, 0xb8, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x02, 0x02, 0x00, 0x19, 0x03, 0x03, 0x08, 0x19, 0x03, 0x03, 0x10, 0x19, 0x03, 0x03, + 0xd0, 0x3a, 0x04, 0x04, 0xe0, 0x3a, 0x04, 0x04, 0x20, 0x14, 0x05, 0x04, 0x40, 0x35, 0x06, 0x05, 0x00, 0x12, 0x07, 0x05, 0x00, 0x28, 0x0a, 0x07, 0xe0, 0x2f, 0x00, 0x03, 0xe8, 0x2f, 0x00, 0x03, + 0xf0, 0x2f, 0x00, 0x03, 0xf8, 0x2f, 0x00, 0x03, 0x60, 0x1d, 0x01, 0x02, 0x64, 0x1d, 0x01, 0x02, 0x68, 0x1d, 0x01, 0x02, 0x6c, 0x1d, 0x01, 0x02, 0x70, 0x1d, 0x01, 0x02, 0x74, 0x1d, 0x01, 0x02, + 0xc0, 0x00, 0x02, 0x02, 0xc4, 0x00, 0x02, 0x02, 0xc8, 0x00, 0x02, 0x02, 0xcc, 0x00, 0x02, 0x02, 0xd0, 0x00, 0x02, 0x02, 0x18, 0x19, 0x03, 0x03, 0x20, 0x19, 0x03, 0x03, 0x28, 0x19, 0x03, 0x03, + 0xf0, 0x3a, 0x04, 0x04, 0x00, 0x3b, 0x04, 0x04, 0x30, 0x14, 0x05, 0x04, 0x60, 0x35, 0x06, 0x05, 0x20, 0x12, 0x07, 0x05, 0x80, 0x28, 0x0a, 0x07, 0x00, 0x30, 0x00, 0x03, 0x08, 0x30, 0x00, 0x03, + 0x10, 0x30, 0x00, 0x03, 0x18, 0x30, 0x00, 0x03, 0x78, 0x1d, 0x01, 0x02, 0x7c, 0x1d, 0x01, 0x02, 0x80, 0x1d, 0x01, 0x02, 0x84, 0x1d, 0x01, 0x02, 0x88, 0x1d, 0x01, 0x02, 0x8c, 0x1d, 0x01, 0x02, + 0xd4, 0x00, 0x02, 0x02, 0xd8, 0x00, 0x02, 0x02, 0xdc, 0x00, 0x02, 0x02, 0xe0, 0x00, 0x02, 0x02, 0xe4, 0x00, 0x02, 0x02, 0x30, 0x19, 0x03, 0x03, 0x38, 0x19, 0x03, 0x03, 0x40, 0x19, 0x03, 0x03, + 0x10, 0x3b, 0x04, 0x04, 0x20, 0x3b, 0x04, 0x04, 0x40, 0x14, 0x05, 0x04, 0x80, 0x35, 0x06, 0x05, 0x40, 0x12, 0x07, 0x05, 0x00, 0x29, 0x0a, 0x07, 0x20, 0x30, 0x00, 0x03, 0x28, 0x30, 0x00, 0x03, + 0x30, 0x30, 0x00, 0x03, 0x38, 0x30, 0x00, 0x03, 0x90, 0x1d, 0x01, 0x02, 0x94, 0x1d, 0x01, 0x02, 0x98, 0x1d, 0x01, 0x02, 0x9c, 0x1d, 0x01, 0x02, 0xa0, 0x1d, 0x01, 0x02, 0xa4, 0x1d, 0x01, 0x02, + 0xe8, 0x00, 0x02, 0x02, 0xec, 0x00, 0x02, 0x02, 0xf0, 0x00, 0x02, 0x02, 0xf4, 0x00, 0x02, 0x02, 0xf8, 0x00, 0x02, 0x02, 0x48, 0x19, 0x03, 0x03, 0x50, 0x19, 0x03, 0x03, 0x58, 0x19, 0x03, 0x03, + 0x30, 0x3b, 0x04, 0x04, 0x40, 0x3b, 0x04, 0x04, 0x50, 0x14, 0x05, 0x04, 0xa0, 0x35, 0x06, 0x05, 0x60, 0x12, 0x07, 0x05, 0x80, 0x29, 0x0a, 0x07, 0x40, 0x30, 0x00, 0x03, 0x48, 0x30, 0x00, 0x03, + 0x50, 0x30, 0x00, 0x03, 0x58, 0x30, 0x00, 0x03, 0xa8, 0x1d, 0x01, 0x02, 0xac, 0x1d, 0x01, 0x02, 0xb0, 0x1d, 0x01, 0x02, 0xb4, 0x1d, 0x01, 0x02, 0xb8, 0x1d, 0x01, 0x02, 0xbc, 0x1d, 0x01, 0x02, + 0xfc, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x04, 0x01, 0x02, 0x02, 0x08, 0x01, 0x02, 0x02, 0x0c, 0x01, 0x02, 0x02, 0x60, 0x19, 0x03, 0x03, 0x68, 0x19, 0x03, 0x03, 0x50, 0x3b, 0x04, 0x04, + 0x60, 0x3b, 0x04, 0x04, 0x70, 0x3b, 0x04, 0x04, 0x60, 0x14, 0x05, 0x04, 0xc0, 0x35, 0x06, 0x05, 0x80, 0x12, 0x07, 0x05, 0x00, 0x2a, 0x0a, 0x07, 0x60, 0x30, 0x00, 0x03, 0x68, 0x30, 0x00, 0x03, + 0x70, 0x30, 0x00, 0x03, 0x78, 0x30, 0x00, 0x03, 0xc0, 0x1d, 0x01, 0x02, 0xc4, 0x1d, 0x01, 0x02, 0xc8, 0x1d, 0x01, 0x02, 0xcc, 0x1d, 0x01, 0x02, 0xd0, 0x1d, 0x01, 0x02, 0xd4, 0x1d, 0x01, 0x02, + 0x10, 0x01, 0x02, 0x02, 0x14, 0x01, 0x02, 0x02, 0x18, 0x01, 0x02, 0x02, 0x1c, 0x01, 0x02, 0x02, 0x70, 0x19, 0x03, 0x03, 0x78, 0x19, 0x03, 0x03, 0x80, 0x19, 0x03, 0x03, 0x80, 0x3b, 0x04, 0x04, + 0x90, 0x3b, 0x04, 0x04, 0xa0, 0x3b, 0x04, 0x04, 0x70, 0x14, 0x05, 0x04, 0xe0, 0x35, 0x06, 0x05, 0xa0, 0x12, 0x07, 0x05, 0x80, 0x2a, 0x0a, 0x07, 0x80, 0x30, 0x00, 0x03, 0x88, 0x30, 0x00, 0x03, + 0x90, 0x30, 0x00, 0x03, 0x98, 0x30, 0x00, 0x03, 0xd8, 0x1d, 0x01, 0x02, 0xdc, 0x1d, 0x01, 0x02, 0xe0, 0x1d, 0x01, 0x02, 0xe4, 0x1d, 0x01, 0x02, 0xe8, 0x1d, 0x01, 0x02, 0xec, 0x1d, 0x01, 0x02, + 0x20, 0x01, 0x02, 0x02, 0x24, 0x01, 0x02, 0x02, 0x28, 0x01, 0x02, 0x02, 0x2c, 0x01, 0x02, 0x02, 0x88, 0x19, 0x03, 0x03, 0x90, 0x19, 0x03, 0x03, 0x98, 0x19, 0x03, 0x03, 0xb0, 0x3b, 0x04, 0x04, + 0xc0, 0x3b, 0x04, 0x04, 0xd0, 0x3b, 0x04, 0x04, 0x80, 0x14, 0x05, 0x04, 0x00, 0x36, 0x06, 0x05, 0xc0, 0x12, 0x07, 0x05, 0x00, 0x2b, 0x0a, 0x07, 0xa0, 0x30, 0x00, 0x03, 0xa8, 0x30, 0x00, 0x03, + 0xb0, 0x30, 0x00, 0x03, 0xb8, 0x30, 0x00, 0x03, 0xf0, 0x1d, 0x01, 0x02, 0xf4, 0x1d, 0x01, 0x02, 0xf8, 0x1d, 0x01, 0x02, 0xfc, 0x1d, 0x01, 0x02, 0x00, 0x1e, 0x01, 0x02, 0x04, 0x1e, 0x01, 0x02, + 0x30, 0x01, 0x02, 0x02, 0x34, 0x01, 0x02, 0x02, 0x38, 0x01, 0x02, 0x02, 0x3c, 0x01, 0x02, 0x02, 0xa0, 0x19, 0x03, 0x03, 0xa8, 0x19, 0x03, 0x03, 0xb0, 0x19, 0x03, 0x03, 0xe0, 0x3b, 0x04, 0x04, + 0xf0, 0x3b, 0x04, 0x04, 0x00, 0x3c, 0x04, 0x04, 0x90, 0x14, 0x05, 0x04, 0x20, 0x36, 0x06, 0x05, 0xe0, 0x12, 0x07, 0x05, 0x80, 0x2b, 0x0a, 0x07, 0xc0, 0x30, 0x00, 0x03, 0xc8, 0x30, 0x00, 0x03, + 0xd0, 0x30, 0x00, 0x03, 0xd8, 0x30, 0x00, 0x03, 0x08, 0x1e, 0x01, 0x02, 0x0c, 0x1e, 0x01, 0x02, 0x10, 0x1e, 0x01, 0x02, 0x14, 0x1e, 0x01, 0x02, 0x18, 0x1e, 0x01, 0x02, 0x1c, 0x1e, 0x01, 0x02, + 0x40, 0x01, 0x02, 0x02, 0x44, 0x01, 0x02, 0x02, 0x48, 0x01, 0x02, 0x02, 0x4c, 0x01, 0x02, 0x02, 0xb8, 0x19, 0x03, 0x03, 0xc0, 0x19, 0x03, 0x03, 0xc8, 0x19, 0x03, 0x03, 0x10, 0x3c, 0x04, 0x04, + 0x20, 0x3c, 0x04, 0x04, 0x30, 0x3c, 0x04, 0x04, 0xa0, 0x14, 0x05, 0x04, 0x40, 0x36, 0x06, 0x05, 0x00, 0x13, 0x07, 0x05, 0x00, 0x2c, 0x0a, 0x07, 0xe0, 0x30, 0x00, 0x03, 0xe8, 0x30, 0x00, 0x03, + 0xf0, 0x30, 0x00, 0x03, 0xf8, 0x30, 0x00, 0x03, 0x20, 0x1e, 0x01, 0x02, 0x24, 0x1e, 0x01, 0x02, 0x28, 0x1e, 0x01, 0x02, 0x2c, 0x1e, 0x01, 0x02, 0x30, 0x1e, 0x01, 0x02, 0x34, 0x1e, 0x01, 0x02, + 0x50, 0x01, 0x02, 0x02, 0x54, 0x01, 0x02, 0x02, 0x58, 0x01, 0x02, 0x02, 0x5c, 0x01, 0x02, 0x02, 0xd0, 0x19, 0x03, 0x03, 0xd8, 0x19, 0x03, 0x03, 0xe0, 0x19, 0x03, 0x03, 0x40, 0x3c, 0x04, 0x04, + 0x50, 0x3c, 0x04, 0x04, 0xb0, 0x14, 0x05, 0x04, 0xc0, 0x14, 0x05, 0x04, 0x60, 0x36, 0x06, 0x05, 0x20, 0x13, 0x07, 0x05, 0x80, 0x2c, 0x0a, 0x07, 0x00, 0x31, 0x00, 0x03, 0x08, 0x31, 0x00, 0x03, + 0x10, 0x31, 0x00, 0x03, 0x18, 0x31, 0x00, 0x03, 0x38, 0x1e, 0x01, 0x02, 0x3c, 0x1e, 0x01, 0x02, 0x40, 0x1e, 0x01, 0x02, 0x44, 0x1e, 0x01, 0x02, 0x48, 0x1e, 0x01, 0x02, 0x4c, 0x1e, 0x01, 0x02, + 0x60, 0x01, 0x02, 0x02, 0x64, 0x01, 0x02, 0x02, 0x68, 0x01, 0x02, 0x02, 0x6c, 0x01, 0x02, 0x02, 0xe8, 0x19, 0x03, 0x03, 0xf0, 0x19, 0x03, 0x03, 0xf8, 0x19, 0x03, 0x03, 0x60, 0x3c, 0x04, 0x04, + 0x70, 0x3c, 0x04, 0x04, 0xd0, 0x14, 0x05, 0x04, 0xe0, 0x14, 0x05, 0x04, 0x80, 0x36, 0x06, 0x05, 0x40, 0x13, 0x07, 0x05, 0x00, 0x2d, 0x0a, 0x07, 0x20, 0x31, 0x00, 0x03, 0x28, 0x31, 0x00, 0x03, + 0x30, 0x31, 0x00, 0x03, 0x38, 0x31, 0x00, 0x03, 0x50, 0x1e, 0x01, 0x02, 0x54, 0x1e, 0x01, 0x02, 0x58, 0x1e, 0x01, 0x02, 0x5c, 0x1e, 0x01, 0x02, 0x60, 0x1e, 0x01, 0x02, 0x64, 0x1e, 0x01, 0x02, + 0x70, 0x01, 0x02, 0x02, 0x74, 0x01, 0x02, 0x02, 0x78, 0x01, 0x02, 0x02, 0x7c, 0x01, 0x02, 0x02, 0x00, 0x1a, 0x03, 0x03, 0x08, 0x1a, 0x03, 0x03, 0x10, 0x1a, 0x03, 0x03, 0x80, 0x3c, 0x04, 0x04, + 0x90, 0x3c, 0x04, 0x04, 0xf0, 0x14, 0x05, 0x04, 0x00, 0x15, 0x05, 0x04, 0xa0, 0x36, 0x06, 0x05, 0x60, 0x13, 0x07, 0x05, 0x80, 0x2d, 0x0a, 0x07, 0x40, 0x31, 0x00, 0x03, 0x48, 0x31, 0x00, 0x03, + 0x50, 0x31, 0x00, 0x03, 0x58, 0x31, 0x00, 0x03, 0x68, 0x1e, 0x01, 0x02, 0x6c, 0x1e, 0x01, 0x02, 0x70, 0x1e, 0x01, 0x02, 0x74, 0x1e, 0x01, 0x02, 0x78, 0x1e, 0x01, 0x02, 0x7c, 0x1e, 0x01, 0x02, + 0x80, 0x01, 0x02, 0x02, 0x84, 0x01, 0x02, 0x02, 0x88, 0x01, 0x02, 0x02, 0x8c, 0x01, 0x02, 0x02, 0x18, 0x1a, 0x03, 0x03, 0x20, 0x1a, 0x03, 0x03, 0x28, 0x1a, 0x03, 0x03, 0xa0, 0x3c, 0x04, 0x04, + 0xb0, 0x3c, 0x04, 0x04, 0x10, 0x15, 0x05, 0x04, 0x20, 0x15, 0x05, 0x04, 0xc0, 0x36, 0x06, 0x05, 0x80, 0x13, 0x07, 0x05, 0x00, 0x2e, 0x0a, 0x07, 0x60, 0x31, 0x00, 0x03, 0x68, 0x31, 0x00, 0x03, + 0x70, 0x31, 0x00, 0x03, 0x78, 0x31, 0x00, 0x03, 0x80, 0x1e, 0x01, 0x02, 0x84, 0x1e, 0x01, 0x02, 0x88, 0x1e, 0x01, 0x02, 0x8c, 0x1e, 0x01, 0x02, 0x90, 0x1e, 0x01, 0x02, 0x94, 0x1e, 0x01, 0x02, + 0x90, 0x01, 0x02, 0x02, 0x94, 0x01, 0x02, 0x02, 0x98, 0x01, 0x02, 0x02, 0x9c, 0x01, 0x02, 0x02, 0x30, 0x1a, 0x03, 0x03, 0x38, 0x1a, 0x03, 0x03, 0x40, 0x1a, 0x03, 0x03, 0xc0, 0x3c, 0x04, 0x04, + 0xd0, 0x3c, 0x04, 0x04, 0x30, 0x15, 0x05, 0x04, 0x40, 0x15, 0x05, 0x04, 0xe0, 0x36, 0x06, 0x05, 0xa0, 0x13, 0x07, 0x05, 0x80, 0x2e, 0x0a, 0x07, 0x80, 0x31, 0x00, 0x03, 0x88, 0x31, 0x00, 0x03, + 0x90, 0x31, 0x00, 0x03, 0x98, 0x31, 0x00, 0x03, 0x98, 0x1e, 0x01, 0x02, 0x9c, 0x1e, 0x01, 0x02, 0xa0, 0x1e, 0x01, 0x02, 0xa4, 0x1e, 0x01, 0x02, 0xa8, 0x1e, 0x01, 0x02, 0xac, 0x1e, 0x01, 0x02, + 0xa0, 0x01, 0x02, 0x02, 0xa4, 0x01, 0x02, 0x02, 0xa8, 0x01, 0x02, 0x02, 0xac, 0x01, 0x02, 0x02, 0x48, 0x1a, 0x03, 0x03, 0x50, 0x1a, 0x03, 0x03, 0x58, 0x1a, 0x03, 0x03, 0xe0, 0x3c, 0x04, 0x04, + 0xf0, 0x3c, 0x04, 0x04, 0x50, 0x15, 0x05, 0x04, 0x60, 0x15, 0x05, 0x04, 0x00, 0x37, 0x06, 0x05, 0xc0, 0x13, 0x07, 0x05, 0x00, 0x2f, 0x0a, 0x07, 0xa0, 0x31, 0x00, 0x03, 0xa8, 0x31, 0x00, 0x03, + 0xb0, 0x31, 0x00, 0x03, 0xb8, 0x31, 0x00, 0x03, 0xb0, 0x1e, 0x01, 0x02, 0xb4, 0x1e, 0x01, 0x02, 0xb8, 0x1e, 0x01, 0x02, 0xbc, 0x1e, 0x01, 0x02, 0xc0, 0x1e, 0x01, 0x02, 0xc4, 0x1e, 0x01, 0x02, + 0xb0, 0x01, 0x02, 0x02, 0xb4, 0x01, 0x02, 0x02, 0xb8, 0x01, 0x02, 0x02, 0xbc, 0x01, 0x02, 0x02, 0x60, 0x1a, 0x03, 0x03, 0x68, 0x1a, 0x03, 0x03, 0x70, 0x1a, 0x03, 0x03, 0x00, 0x3d, 0x04, 0x04, + 0x10, 0x3d, 0x04, 0x04, 0x70, 0x15, 0x05, 0x04, 0x80, 0x15, 0x05, 0x04, 0x20, 0x37, 0x06, 0x05, 0xe0, 0x13, 0x07, 0x05, 0x80, 0x2f, 0x0a, 0x07, 0xc0, 0x31, 0x00, 0x03, 0xc8, 0x31, 0x00, 0x03, + 0xd0, 0x31, 0x00, 0x03, 0xd8, 0x31, 0x00, 0x03, 0xc8, 0x1e, 0x01, 0x02, 0xcc, 0x1e, 0x01, 0x02, 0xd0, 0x1e, 0x01, 0x02, 0xd4, 0x1e, 0x01, 0x02, 0xd8, 0x1e, 0x01, 0x02, 0xdc, 0x1e, 0x01, 0x02, + 0xc0, 0x01, 0x02, 0x02, 0xc4, 0x01, 0x02, 0x02, 0xc8, 0x01, 0x02, 0x02, 0xcc, 0x01, 0x02, 0x02, 0x78, 0x1a, 0x03, 0x03, 0x80, 0x1a, 0x03, 0x03, 0x88, 0x1a, 0x03, 0x03, 0x20, 0x3d, 0x04, 0x04, + 0x30, 0x3d, 0x04, 0x04, 0x90, 0x15, 0x05, 0x04, 0xa0, 0x15, 0x05, 0x04, 0x40, 0x37, 0x06, 0x05, 0x00, 0x14, 0x07, 0x05, 0x00, 0x30, 0x0a, 0x07, 0xe0, 0x31, 0x00, 0x03, 0xe8, 0x31, 0x00, 0x03, + 0xf0, 0x31, 0x00, 0x03, 0xf8, 0x31, 0x00, 0x03, 0xe0, 0x1e, 0x01, 0x02, 0xe4, 0x1e, 0x01, 0x02, 0xe8, 0x1e, 0x01, 0x02, 0xec, 0x1e, 0x01, 0x02, 0xf0, 0x1e, 0x01, 0x02, 0xf4, 0x1e, 0x01, 0x02, + 0xd0, 0x01, 0x02, 0x02, 0xd4, 0x01, 0x02, 0x02, 0xd8, 0x01, 0x02, 0x02, 0xdc, 0x01, 0x02, 0x02, 0x90, 0x1a, 0x03, 0x03, 0x98, 0x1a, 0x03, 0x03, 0xa0, 0x1a, 0x03, 0x03, 0x40, 0x3d, 0x04, 0x04, + 0x50, 0x3d, 0x04, 0x04, 0xb0, 0x15, 0x05, 0x04, 0xc0, 0x15, 0x05, 0x04, 0x60, 0x37, 0x06, 0x05, 0x00, 0x2d, 0x08, 0x06, 0x80, 0x30, 0x0a, 0x07, 0x00, 0x32, 0x00, 0x03, 0x08, 0x32, 0x00, 0x03, + 0x10, 0x32, 0x00, 0x03, 0x18, 0x32, 0x00, 0x03, 0xf8, 0x1e, 0x01, 0x02, 0xfc, 0x1e, 0x01, 0x02, 0x00, 0x1f, 0x01, 0x02, 0x04, 0x1f, 0x01, 0x02, 0x08, 0x1f, 0x01, 0x02, 0x0c, 0x1f, 0x01, 0x02, + 0xe0, 0x01, 0x02, 0x02, 0xe4, 0x01, 0x02, 0x02, 0xe8, 0x01, 0x02, 0x02, 0xec, 0x01, 0x02, 0x02, 0xa8, 0x1a, 0x03, 0x03, 0xb0, 0x1a, 0x03, 0x03, 0xb8, 0x1a, 0x03, 0x03, 0x60, 0x3d, 0x04, 0x04, + 0x70, 0x3d, 0x04, 0x04, 0xd0, 0x15, 0x05, 0x04, 0xe0, 0x15, 0x05, 0x04, 0x80, 0x37, 0x06, 0x05, 0x40, 0x2d, 0x08, 0x06, 0x80, 0x07, 0x0b, 0x07, 0x20, 0x32, 0x00, 0x03, 0x28, 0x32, 0x00, 0x03, + 0x30, 0x32, 0x00, 0x03, 0x38, 0x32, 0x00, 0x03, 0x10, 0x1f, 0x01, 0x02, 0x14, 0x1f, 0x01, 0x02, 0x18, 0x1f, 0x01, 0x02, 0x1c, 0x1f, 0x01, 0x02, 0x20, 0x1f, 0x01, 0x02, 0x24, 0x1f, 0x01, 0x02, + 0xf0, 0x01, 0x02, 0x02, 0xf4, 0x01, 0x02, 0x02, 0xf8, 0x01, 0x02, 0x02, 0xfc, 0x01, 0x02, 0x02, 0xc0, 0x1a, 0x03, 0x03, 0xc8, 0x1a, 0x03, 0x03, 0xd0, 0x1a, 0x03, 0x03, 0x80, 0x3d, 0x04, 0x04, + 0x90, 0x3d, 0x04, 0x04, 0xf0, 0x15, 0x05, 0x04, 0x00, 0x16, 0x05, 0x04, 0xa0, 0x37, 0x06, 0x05, 0x80, 0x2d, 0x08, 0x06, 0x00, 0x08, 0x0b, 0x07, 0x40, 0x32, 0x00, 0x03, 0x48, 0x32, 0x00, 0x03, + 0x50, 0x32, 0x00, 0x03, 0x58, 0x32, 0x00, 0x03, 0x28, 0x1f, 0x01, 0x02, 0x2c, 0x1f, 0x01, 0x02, 0x30, 0x1f, 0x01, 0x02, 0x34, 0x1f, 0x01, 0x02, 0x38, 0x1f, 0x01, 0x02, 0x3c, 0x1f, 0x01, 0x02, + 0x00, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x08, 0x02, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x02, 0xd8, 0x1a, 0x03, 0x03, 0xe0, 0x1a, 0x03, 0x03, 0xe8, 0x1a, 0x03, 0x03, 0xa0, 0x3d, 0x04, 0x04, + 0xb0, 0x3d, 0x04, 0x04, 0x10, 0x16, 0x05, 0x04, 0x20, 0x16, 0x05, 0x04, 0xc0, 0x37, 0x06, 0x05, 0xc0, 0x2d, 0x08, 0x06, 0x80, 0x08, 0x0b, 0x07, 0x60, 0x32, 0x00, 0x03, 0x68, 0x32, 0x00, 0x03, + 0x70, 0x32, 0x00, 0x03, 0x78, 0x32, 0x00, 0x03, 0x40, 0x1f, 0x01, 0x02, 0x44, 0x1f, 0x01, 0x02, 0x48, 0x1f, 0x01, 0x02, 0x4c, 0x1f, 0x01, 0x02, 0x50, 0x1f, 0x01, 0x02, 0x54, 0x1f, 0x01, 0x02, + 0x10, 0x02, 0x02, 0x02, 0x14, 0x02, 0x02, 0x02, 0x18, 0x02, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0xf0, 0x1a, 0x03, 0x03, 0xf8, 0x1a, 0x03, 0x03, 0x00, 0x1b, 0x03, 0x03, 0xc0, 0x3d, 0x04, 0x04, + 0xd0, 0x3d, 0x04, 0x04, 0x30, 0x16, 0x05, 0x04, 0x40, 0x16, 0x05, 0x04, 0xe0, 0x37, 0x06, 0x05, 0x00, 0x2e, 0x08, 0x06, 0x00, 0x09, 0x0b, 0x07, 0x80, 0x32, 0x00, 0x03, 0x88, 0x32, 0x00, 0x03, + 0x90, 0x32, 0x00, 0x03, 0x98, 0x32, 0x00, 0x03, 0x58, 0x1f, 0x01, 0x02, 0x5c, 0x1f, 0x01, 0x02, 0x60, 0x1f, 0x01, 0x02, 0x64, 0x1f, 0x01, 0x02, 0x68, 0x1f, 0x01, 0x02, 0x6c, 0x1f, 0x01, 0x02, + 0x20, 0x02, 0x02, 0x02, 0x24, 0x02, 0x02, 0x02, 0x28, 0x02, 0x02, 0x02, 0x2c, 0x02, 0x02, 0x02, 0x08, 0x1b, 0x03, 0x03, 0x10, 0x1b, 0x03, 0x03, 0x18, 0x1b, 0x03, 0x03, 0xe0, 0x3d, 0x04, 0x04, + 0xf0, 0x3d, 0x04, 0x04, 0x50, 0x16, 0x05, 0x04, 0x60, 0x16, 0x05, 0x04, 0x00, 0x38, 0x06, 0x05, 0x40, 0x2e, 0x08, 0x06, 0x80, 0x09, 0x0b, 0x07, 0xa0, 0x32, 0x00, 0x03, 0xa8, 0x32, 0x00, 0x03, + 0xb0, 0x32, 0x00, 0x03, 0xb8, 0x32, 0x00, 0x03, 0x70, 0x1f, 0x01, 0x02, 0x74, 0x1f, 0x01, 0x02, 0x78, 0x1f, 0x01, 0x02, 0x7c, 0x1f, 0x01, 0x02, 0x80, 0x1f, 0x01, 0x02, 0x84, 0x1f, 0x01, 0x02, + 0x30, 0x02, 0x02, 0x02, 0x34, 0x02, 0x02, 0x02, 0x38, 0x02, 0x02, 0x02, 0x3c, 0x02, 0x02, 0x02, 0x20, 0x1b, 0x03, 0x03, 0x28, 0x1b, 0x03, 0x03, 0x30, 0x1b, 0x03, 0x03, 0x00, 0x3e, 0x04, 0x04, + 0x10, 0x3e, 0x04, 0x04, 0x70, 0x16, 0x05, 0x04, 0x80, 0x16, 0x05, 0x04, 0x20, 0x38, 0x06, 0x05, 0x80, 0x2e, 0x08, 0x06, 0x00, 0x0a, 0x0b, 0x07, 0xc0, 0x32, 0x00, 0x03, 0xc8, 0x32, 0x00, 0x03, + 0xd0, 0x32, 0x00, 0x03, 0xd8, 0x32, 0x00, 0x03, 0x88, 0x1f, 0x01, 0x02, 0x8c, 0x1f, 0x01, 0x02, 0x90, 0x1f, 0x01, 0x02, 0x94, 0x1f, 0x01, 0x02, 0x98, 0x1f, 0x01, 0x02, 0x9c, 0x1f, 0x01, 0x02, + 0x40, 0x02, 0x02, 0x02, 0x44, 0x02, 0x02, 0x02, 0x48, 0x02, 0x02, 0x02, 0x4c, 0x02, 0x02, 0x02, 0x38, 0x1b, 0x03, 0x03, 0x40, 0x1b, 0x03, 0x03, 0x48, 0x1b, 0x03, 0x03, 0x20, 0x3e, 0x04, 0x04, + 0x30, 0x3e, 0x04, 0x04, 0x90, 0x16, 0x05, 0x04, 0xa0, 0x16, 0x05, 0x04, 0x40, 0x38, 0x06, 0x05, 0xc0, 0x2e, 0x08, 0x06, 0x80, 0x0a, 0x0b, 0x07, 0xe0, 0x32, 0x00, 0x03, 0xe8, 0x32, 0x00, 0x03, + 0xf0, 0x32, 0x00, 0x03, 0xf8, 0x32, 0x00, 0x03, 0xa0, 0x1f, 0x01, 0x02, 0xa4, 0x1f, 0x01, 0x02, 0xa8, 0x1f, 0x01, 0x02, 0xac, 0x1f, 0x01, 0x02, 0xb0, 0x1f, 0x01, 0x02, 0xb4, 0x1f, 0x01, 0x02, + 0x50, 0x02, 0x02, 0x02, 0x54, 0x02, 0x02, 0x02, 0x58, 0x02, 0x02, 0x02, 0x5c, 0x02, 0x02, 0x02, 0x50, 0x1b, 0x03, 0x03, 0x58, 0x1b, 0x03, 0x03, 0x60, 0x1b, 0x03, 0x03, 0x40, 0x3e, 0x04, 0x04, + 0x50, 0x3e, 0x04, 0x04, 0xb0, 0x16, 0x05, 0x04, 0xc0, 0x16, 0x05, 0x04, 0x60, 0x38, 0x06, 0x05, 0x00, 0x2f, 0x08, 0x06, 0x00, 0x0b, 0x0b, 0x07, 0x00, 0x33, 0x00, 0x03, 0x08, 0x33, 0x00, 0x03, + 0x10, 0x33, 0x00, 0x03, 0x18, 0x33, 0x00, 0x03, 0xb8, 0x1f, 0x01, 0x02, 0xbc, 0x1f, 0x01, 0x02, 0xc0, 0x1f, 0x01, 0x02, 0xc4, 0x1f, 0x01, 0x02, 0xc8, 0x1f, 0x01, 0x02, 0xcc, 0x1f, 0x01, 0x02, + 0x60, 0x02, 0x02, 0x02, 0x64, 0x02, 0x02, 0x02, 0x68, 0x02, 0x02, 0x02, 0x6c, 0x02, 0x02, 0x02, 0x68, 0x1b, 0x03, 0x03, 0x70, 0x1b, 0x03, 0x03, 0x78, 0x1b, 0x03, 0x03, 0x60, 0x3e, 0x04, 0x04, + 0x70, 0x3e, 0x04, 0x04, 0xd0, 0x16, 0x05, 0x04, 0xe0, 0x16, 0x05, 0x04, 0x80, 0x38, 0x06, 0x05, 0x40, 0x2f, 0x08, 0x06, 0x80, 0x0b, 0x0b, 0x07, 0x20, 0x33, 0x00, 0x03, 0x28, 0x33, 0x00, 0x03, + 0x30, 0x33, 0x00, 0x03, 0x38, 0x33, 0x00, 0x03, 0xd0, 0x1f, 0x01, 0x02, 0xd4, 0x1f, 0x01, 0x02, 0xd8, 0x1f, 0x01, 0x02, 0xdc, 0x1f, 0x01, 0x02, 0xe0, 0x1f, 0x01, 0x02, 0xe4, 0x1f, 0x01, 0x02, + 0x70, 0x02, 0x02, 0x02, 0x74, 0x02, 0x02, 0x02, 0x78, 0x02, 0x02, 0x02, 0x7c, 0x02, 0x02, 0x02, 0x80, 0x1b, 0x03, 0x03, 0x88, 0x1b, 0x03, 0x03, 0x90, 0x1b, 0x03, 0x03, 0x80, 0x3e, 0x04, 0x04, + 0x90, 0x3e, 0x04, 0x04, 0xf0, 0x16, 0x05, 0x04, 0x00, 0x17, 0x05, 0x04, 0xa0, 0x38, 0x06, 0x05, 0x80, 0x2f, 0x08, 0x06, 0x00, 0x0c, 0x0b, 0x07, 0x40, 0x33, 0x00, 0x03, 0x48, 0x33, 0x00, 0x03, + 0x50, 0x33, 0x00, 0x03, 0x58, 0x33, 0x00, 0x03, 0xe8, 0x1f, 0x01, 0x02, 0xec, 0x1f, 0x01, 0x02, 0xf0, 0x1f, 0x01, 0x02, 0xf4, 0x1f, 0x01, 0x02, 0xf8, 0x1f, 0x01, 0x02, 0xfc, 0x1f, 0x01, 0x02, + 0x80, 0x02, 0x02, 0x02, 0x84, 0x02, 0x02, 0x02, 0x88, 0x02, 0x02, 0x02, 0x8c, 0x02, 0x02, 0x02, 0x98, 0x1b, 0x03, 0x03, 0xa0, 0x1b, 0x03, 0x03, 0xa8, 0x1b, 0x03, 0x03, 0xa0, 0x3e, 0x04, 0x04, + 0xb0, 0x3e, 0x04, 0x04, 0x10, 0x17, 0x05, 0x04, 0x20, 0x17, 0x05, 0x04, 0xc0, 0x38, 0x06, 0x05, 0xc0, 0x2f, 0x08, 0x06, 0x80, 0x0c, 0x0b, 0x07, 0x60, 0x33, 0x00, 0x03, 0x68, 0x33, 0x00, 0x03, + 0x70, 0x33, 0x00, 0x03, 0x78, 0x33, 0x00, 0x03, 0x00, 0x20, 0x01, 0x02, 0x04, 0x20, 0x01, 0x02, 0x08, 0x20, 0x01, 0x02, 0x0c, 0x20, 0x01, 0x02, 0x10, 0x20, 0x01, 0x02, 0x14, 0x20, 0x01, 0x02, + 0x90, 0x02, 0x02, 0x02, 0x94, 0x02, 0x02, 0x02, 0x98, 0x02, 0x02, 0x02, 0x9c, 0x02, 0x02, 0x02, 0xb0, 0x1b, 0x03, 0x03, 0xb8, 0x1b, 0x03, 0x03, 0xc0, 0x1b, 0x03, 0x03, 0xc0, 0x3e, 0x04, 0x04, + 0xd0, 0x3e, 0x04, 0x04, 0x30, 0x17, 0x05, 0x04, 0x40, 0x17, 0x05, 0x04, 0xe0, 0x38, 0x06, 0x05, 0x00, 0x30, 0x08, 0x06, 0x00, 0x0d, 0x0b, 0x07, 0x80, 0x33, 0x00, 0x03, 0x88, 0x33, 0x00, 0x03, + 0x90, 0x33, 0x00, 0x03, 0x98, 0x33, 0x00, 0x03, 0x18, 0x20, 0x01, 0x02, 0x1c, 0x20, 0x01, 0x02, 0x20, 0x20, 0x01, 0x02, 0x24, 0x20, 0x01, 0x02, 0x28, 0x20, 0x01, 0x02, 0x2c, 0x20, 0x01, 0x02, + 0xa0, 0x02, 0x02, 0x02, 0xa4, 0x02, 0x02, 0x02, 0xa8, 0x02, 0x02, 0x02, 0xac, 0x02, 0x02, 0x02, 0xc8, 0x1b, 0x03, 0x03, 0xd0, 0x1b, 0x03, 0x03, 0xd8, 0x1b, 0x03, 0x03, 0xe0, 0x3e, 0x04, 0x04, + 0xf0, 0x3e, 0x04, 0x04, 0x50, 0x17, 0x05, 0x04, 0x60, 0x17, 0x05, 0x04, 0x00, 0x39, 0x06, 0x05, 0x40, 0x30, 0x08, 0x06, 0x80, 0x0d, 0x0b, 0x07, 0xa0, 0x33, 0x00, 0x03, 0xa8, 0x33, 0x00, 0x03, + 0xb0, 0x33, 0x00, 0x03, 0xb8, 0x33, 0x00, 0x03, 0x30, 0x20, 0x01, 0x02, 0x34, 0x20, 0x01, 0x02, 0x38, 0x20, 0x01, 0x02, 0x3c, 0x20, 0x01, 0x02, 0x40, 0x20, 0x01, 0x02, 0x44, 0x20, 0x01, 0x02, + 0xb0, 0x02, 0x02, 0x02, 0xb4, 0x02, 0x02, 0x02, 0xb8, 0x02, 0x02, 0x02, 0xbc, 0x02, 0x02, 0x02, 0xe0, 0x1b, 0x03, 0x03, 0xe8, 0x1b, 0x03, 0x03, 0xf0, 0x1b, 0x03, 0x03, 0x00, 0x3f, 0x04, 0x04, + 0x10, 0x3f, 0x04, 0x04, 0x70, 0x17, 0x05, 0x04, 0x80, 0x17, 0x05, 0x04, 0x20, 0x39, 0x06, 0x05, 0x80, 0x30, 0x08, 0x06, 0x00, 0x23, 0x0c, 0x08, 0xc0, 0x33, 0x00, 0x03, 0xc8, 0x33, 0x00, 0x03, + 0xd0, 0x33, 0x00, 0x03, 0xd8, 0x33, 0x00, 0x03, 0x48, 0x20, 0x01, 0x02, 0x4c, 0x20, 0x01, 0x02, 0x50, 0x20, 0x01, 0x02, 0x54, 0x20, 0x01, 0x02, 0x58, 0x20, 0x01, 0x02, 0x5c, 0x20, 0x01, 0x02, + 0xc0, 0x02, 0x02, 0x02, 0xc4, 0x02, 0x02, 0x02, 0xc8, 0x02, 0x02, 0x02, 0xcc, 0x02, 0x02, 0x02, 0xf8, 0x1b, 0x03, 0x03, 0x00, 0x1c, 0x03, 0x03, 0x08, 0x1c, 0x03, 0x03, 0x20, 0x3f, 0x04, 0x04, + 0x30, 0x3f, 0x04, 0x04, 0x90, 0x17, 0x05, 0x04, 0xa0, 0x17, 0x05, 0x04, 0x40, 0x39, 0x06, 0x05, 0xc0, 0x30, 0x08, 0x06, 0x00, 0x24, 0x0c, 0x08, 0xe0, 0x33, 0x00, 0x03, 0xe8, 0x33, 0x00, 0x03, + 0xf0, 0x33, 0x00, 0x03, 0xf8, 0x33, 0x00, 0x03, 0x60, 0x20, 0x01, 0x02, 0x64, 0x20, 0x01, 0x02, 0x68, 0x20, 0x01, 0x02, 0x6c, 0x20, 0x01, 0x02, 0x70, 0x20, 0x01, 0x02, 0x74, 0x20, 0x01, 0x02, + 0xd0, 0x02, 0x02, 0x02, 0xd4, 0x02, 0x02, 0x02, 0xd8, 0x02, 0x02, 0x02, 0xdc, 0x02, 0x02, 0x02, 0x10, 0x1c, 0x03, 0x03, 0x18, 0x1c, 0x03, 0x03, 0x20, 0x1c, 0x03, 0x03, 0x40, 0x3f, 0x04, 0x04, + 0x50, 0x3f, 0x04, 0x04, 0xb0, 0x17, 0x05, 0x04, 0xc0, 0x17, 0x05, 0x04, 0x60, 0x39, 0x06, 0x05, 0x00, 0x31, 0x08, 0x06, 0x00, 0x25, 0x0c, 0x08, 0x00, 0x34, 0x00, 0x03, 0x08, 0x34, 0x00, 0x03, + 0x10, 0x34, 0x00, 0x03, 0x18, 0x34, 0x00, 0x03, 0x78, 0x20, 0x01, 0x02, 0x7c, 0x20, 0x01, 0x02, 0x80, 0x20, 0x01, 0x02, 0x84, 0x20, 0x01, 0x02, 0x88, 0x20, 0x01, 0x02, 0x8c, 0x20, 0x01, 0x02, + 0xe0, 0x02, 0x02, 0x02, 0xe4, 0x02, 0x02, 0x02, 0xe8, 0x02, 0x02, 0x02, 0xec, 0x02, 0x02, 0x02, 0x28, 0x1c, 0x03, 0x03, 0x30, 0x1c, 0x03, 0x03, 0x38, 0x1c, 0x03, 0x03, 0x60, 0x3f, 0x04, 0x04, + 0x70, 0x3f, 0x04, 0x04, 0xd0, 0x17, 0x05, 0x04, 0xe0, 0x17, 0x05, 0x04, 0x80, 0x39, 0x06, 0x05, 0x40, 0x31, 0x08, 0x06, 0x00, 0x26, 0x0c, 0x08, 0x20, 0x34, 0x00, 0x03, 0x28, 0x34, 0x00, 0x03, + 0x30, 0x34, 0x00, 0x03, 0x38, 0x34, 0x00, 0x03, 0x90, 0x20, 0x01, 0x02, 0x94, 0x20, 0x01, 0x02, 0x98, 0x20, 0x01, 0x02, 0x9c, 0x20, 0x01, 0x02, 0xa0, 0x20, 0x01, 0x02, 0xa4, 0x20, 0x01, 0x02, + 0xf0, 0x02, 0x02, 0x02, 0xf4, 0x02, 0x02, 0x02, 0xf8, 0x02, 0x02, 0x02, 0xfc, 0x02, 0x02, 0x02, 0x40, 0x1c, 0x03, 0x03, 0x48, 0x1c, 0x03, 0x03, 0x50, 0x1c, 0x03, 0x03, 0x80, 0x3f, 0x04, 0x04, + 0x90, 0x3f, 0x04, 0x04, 0xf0, 0x17, 0x05, 0x04, 0x00, 0x18, 0x05, 0x04, 0xa0, 0x39, 0x06, 0x05, 0x80, 0x31, 0x08, 0x06, 0x00, 0x27, 0x0c, 0x08, 0x40, 0x34, 0x00, 0x03, 0x48, 0x34, 0x00, 0x03, + 0x50, 0x34, 0x00, 0x03, 0x58, 0x34, 0x00, 0x03, 0xa8, 0x20, 0x01, 0x02, 0xac, 0x20, 0x01, 0x02, 0xb0, 0x20, 0x01, 0x02, 0xb4, 0x20, 0x01, 0x02, 0xb8, 0x20, 0x01, 0x02, 0xbc, 0x20, 0x01, 0x02, + 0x00, 0x03, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x08, 0x03, 0x02, 0x02, 0x0c, 0x03, 0x02, 0x02, 0x58, 0x1c, 0x03, 0x03, 0x60, 0x1c, 0x03, 0x03, 0x68, 0x1c, 0x03, 0x03, 0xa0, 0x3f, 0x04, 0x04, + 0xb0, 0x3f, 0x04, 0x04, 0x10, 0x18, 0x05, 0x04, 0x20, 0x18, 0x05, 0x04, 0xc0, 0x39, 0x06, 0x05, 0xc0, 0x31, 0x08, 0x06, 0x00, 0x28, 0x0c, 0x08, 0x60, 0x34, 0x00, 0x03, 0x68, 0x34, 0x00, 0x03, + 0x70, 0x34, 0x00, 0x03, 0x78, 0x34, 0x00, 0x03, 0xc0, 0x20, 0x01, 0x02, 0xc4, 0x20, 0x01, 0x02, 0xc8, 0x20, 0x01, 0x02, 0xcc, 0x20, 0x01, 0x02, 0xd0, 0x20, 0x01, 0x02, 0xd4, 0x20, 0x01, 0x02, + 0x10, 0x03, 0x02, 0x02, 0x14, 0x03, 0x02, 0x02, 0x18, 0x03, 0x02, 0x02, 0x1c, 0x03, 0x02, 0x02, 0x70, 0x1c, 0x03, 0x03, 0x78, 0x1c, 0x03, 0x03, 0x80, 0x1c, 0x03, 0x03, 0xc0, 0x3f, 0x04, 0x04, + 0xd0, 0x3f, 0x04, 0x04, 0x30, 0x18, 0x05, 0x04, 0x40, 0x18, 0x05, 0x04, 0xe0, 0x39, 0x06, 0x05, 0x00, 0x32, 0x08, 0x06, 0x00, 0x29, 0x0c, 0x08, 0x80, 0x34, 0x00, 0x03, 0x88, 0x34, 0x00, 0x03, + 0x90, 0x34, 0x00, 0x03, 0x98, 0x34, 0x00, 0x03, 0xd8, 0x20, 0x01, 0x02, 0xdc, 0x20, 0x01, 0x02, 0xe0, 0x20, 0x01, 0x02, 0xe4, 0x20, 0x01, 0x02, 0xe8, 0x20, 0x01, 0x02, 0xec, 0x20, 0x01, 0x02, + 0x20, 0x03, 0x02, 0x02, 0x24, 0x03, 0x02, 0x02, 0x28, 0x03, 0x02, 0x02, 0x2c, 0x03, 0x02, 0x02, 0x88, 0x1c, 0x03, 0x03, 0x90, 0x1c, 0x03, 0x03, 0x98, 0x1c, 0x03, 0x03, 0xe0, 0x3f, 0x04, 0x04, + 0xf0, 0x3f, 0x04, 0x04, 0x50, 0x18, 0x05, 0x04, 0x60, 0x18, 0x05, 0x04, 0x00, 0x3a, 0x06, 0x05, 0x40, 0x32, 0x08, 0x06, 0x00, 0x2a, 0x0c, 0x08, 0xa0, 0x34, 0x00, 0x03, 0xa8, 0x34, 0x00, 0x03, + 0xb0, 0x34, 0x00, 0x03, 0xf0, 0x20, 0x01, 0x02, 0xf4, 0x20, 0x01, 0x02, 0xf8, 0x20, 0x01, 0x02, 0xfc, 0x20, 0x01, 0x02, 0x00, 0x21, 0x01, 0x02, 0x04, 0x21, 0x01, 0x02, 0x08, 0x21, 0x01, 0x02, + 0x30, 0x03, 0x02, 0x02, 0x34, 0x03, 0x02, 0x02, 0x38, 0x03, 0x02, 0x02, 0x3c, 0x03, 0x02, 0x02, 0xa0, 0x1c, 0x03, 0x03, 0xa8, 0x1c, 0x03, 0x03, 0xb0, 0x1c, 0x03, 0x03, 0x00, 0x00, 0x04, 0x03, + 0x08, 0x00, 0x04, 0x03, 0x70, 0x18, 0x05, 0x04, 0x80, 0x18, 0x05, 0x04, 0x20, 0x3a, 0x06, 0x05, 0x80, 0x32, 0x08, 0x06, 0x00, 0x2b, 0x0c, 0x08, 0xb8, 0x34, 0x00, 0x03, 0xc0, 0x34, 0x00, 0x03, + 0xc8, 0x34, 0x00, 0x03, 0x0c, 0x21, 0x01, 0x02, 0x10, 0x21, 0x01, 0x02, 0x14, 0x21, 0x01, 0x02, 0x18, 0x21, 0x01, 0x02, 0x1c, 0x21, 0x01, 0x02, 0x20, 0x21, 0x01, 0x02, 0x24, 0x21, 0x01, 0x02, + 0x40, 0x03, 0x02, 0x02, 0x44, 0x03, 0x02, 0x02, 0x48, 0x03, 0x02, 0x02, 0x4c, 0x03, 0x02, 0x02, 0xb8, 0x1c, 0x03, 0x03, 0xc0, 0x1c, 0x03, 0x03, 0xc8, 0x1c, 0x03, 0x03, 0x10, 0x00, 0x04, 0x03, + 0x18, 0x00, 0x04, 0x03, 0x90, 0x18, 0x05, 0x04, 0xa0, 0x18, 0x05, 0x04, 0x40, 0x3a, 0x06, 0x05, 0xc0, 0x32, 0x08, 0x06, 0x00, 0x05, 0x0d, 0x08, 0xd0, 0x34, 0x00, 0x03, 0xd8, 0x34, 0x00, 0x03, + 0xe0, 0x34, 0x00, 0x03, 0x28, 0x21, 0x01, 0x02, 0x2c, 0x21, 0x01, 0x02, 0x30, 0x21, 0x01, 0x02, 0x34, 0x21, 0x01, 0x02, 0x38, 0x21, 0x01, 0x02, 0x3c, 0x21, 0x01, 0x02, 0x40, 0x21, 0x01, 0x02, + 0x50, 0x03, 0x02, 0x02, 0x54, 0x03, 0x02, 0x02, 0x58, 0x03, 0x02, 0x02, 0x5c, 0x03, 0x02, 0x02, 0xd0, 0x1c, 0x03, 0x03, 0xd8, 0x1c, 0x03, 0x03, 0xe0, 0x1c, 0x03, 0x03, 0x20, 0x00, 0x04, 0x03, + 0x28, 0x00, 0x04, 0x03, 0xb0, 0x18, 0x05, 0x04, 0xc0, 0x18, 0x05, 0x04, 0x60, 0x3a, 0x06, 0x05, 0x00, 0x33, 0x08, 0x06, 0x00, 0x06, 0x0d, 0x08, 0xe8, 0x34, 0x00, 0x03, 0xf0, 0x34, 0x00, 0x03, + 0xf8, 0x34, 0x00, 0x03, 0x44, 0x21, 0x01, 0x02, 0x48, 0x21, 0x01, 0x02, 0x4c, 0x21, 0x01, 0x02, 0x50, 0x21, 0x01, 0x02, 0x54, 0x21, 0x01, 0x02, 0x58, 0x21, 0x01, 0x02, 0x5c, 0x21, 0x01, 0x02, + 0x60, 0x03, 0x02, 0x02, 0x64, 0x03, 0x02, 0x02, 0x68, 0x03, 0x02, 0x02, 0x6c, 0x03, 0x02, 0x02, 0xe8, 0x1c, 0x03, 0x03, 0xf0, 0x1c, 0x03, 0x03, 0xf8, 0x1c, 0x03, 0x03, 0x30, 0x00, 0x04, 0x03, + 0x38, 0x00, 0x04, 0x03, 0xd0, 0x18, 0x05, 0x04, 0xe0, 0x18, 0x05, 0x04, 0x80, 0x3a, 0x06, 0x05, 0x40, 0x33, 0x08, 0x06, 0x00, 0x07, 0x0d, 0x08, 0x00, 0x35, 0x00, 0x03, 0x08, 0x35, 0x00, 0x03, + 0x10, 0x35, 0x00, 0x03, 0x60, 0x21, 0x01, 0x02, 0x64, 0x21, 0x01, 0x02, 0x68, 0x21, 0x01, 0x02, 0x6c, 0x21, 0x01, 0x02, 0x70, 0x21, 0x01, 0x02, 0x74, 0x21, 0x01, 0x02, 0x78, 0x21, 0x01, 0x02, + 0x70, 0x03, 0x02, 0x02, 0x74, 0x03, 0x02, 0x02, 0x78, 0x03, 0x02, 0x02, 0x7c, 0x03, 0x02, 0x02, 0x00, 0x1d, 0x03, 0x03, 0x08, 0x1d, 0x03, 0x03, 0x10, 0x1d, 0x03, 0x03, 0x40, 0x00, 0x04, 0x03, + 0x48, 0x00, 0x04, 0x03, 0xf0, 0x18, 0x05, 0x04, 0x00, 0x19, 0x05, 0x04, 0xa0, 0x3a, 0x06, 0x05, 0x80, 0x33, 0x08, 0x06, 0x00, 0x08, 0x0d, 0x08, 0x18, 0x35, 0x00, 0x03, 0x20, 0x35, 0x00, 0x03, + 0x28, 0x35, 0x00, 0x03, 0x7c, 0x21, 0x01, 0x02, 0x80, 0x21, 0x01, 0x02, 0x84, 0x21, 0x01, 0x02, 0x88, 0x21, 0x01, 0x02, 0x8c, 0x21, 0x01, 0x02, 0x90, 0x21, 0x01, 0x02, 0x94, 0x21, 0x01, 0x02, + 0x80, 0x03, 0x02, 0x02, 0x84, 0x03, 0x02, 0x02, 0x88, 0x03, 0x02, 0x02, 0x8c, 0x03, 0x02, 0x02, 0x18, 0x1d, 0x03, 0x03, 0x20, 0x1d, 0x03, 0x03, 0x28, 0x1d, 0x03, 0x03, 0x50, 0x00, 0x04, 0x03, + 0x58, 0x00, 0x04, 0x03, 0x10, 0x19, 0x05, 0x04, 0x20, 0x19, 0x05, 0x04, 0x20, 0x14, 0x07, 0x05, 0xc0, 0x33, 0x08, 0x06, 0x00, 0x09, 0x0d, 0x08, 0x30, 0x35, 0x00, 0x03, 0x38, 0x35, 0x00, 0x03, + 0x40, 0x35, 0x00, 0x03, 0x98, 0x21, 0x01, 0x02, 0x9c, 0x21, 0x01, 0x02, 0xa0, 0x21, 0x01, 0x02, 0xa4, 0x21, 0x01, 0x02, 0xa8, 0x21, 0x01, 0x02, 0xac, 0x21, 0x01, 0x02, 0xb0, 0x21, 0x01, 0x02, + 0x90, 0x03, 0x02, 0x02, 0x94, 0x03, 0x02, 0x02, 0x98, 0x03, 0x02, 0x02, 0x9c, 0x03, 0x02, 0x02, 0x30, 0x1d, 0x03, 0x03, 0x38, 0x1d, 0x03, 0x03, 0x40, 0x1d, 0x03, 0x03, 0x60, 0x00, 0x04, 0x03, + 0x68, 0x00, 0x04, 0x03, 0x30, 0x19, 0x05, 0x04, 0xc0, 0x3a, 0x06, 0x05, 0x40, 0x14, 0x07, 0x05, 0x00, 0x34, 0x08, 0x06, 0x00, 0x0a, 0x0d, 0x08, 0x48, 0x35, 0x00, 0x03, 0x50, 0x35, 0x00, 0x03, + 0x58, 0x35, 0x00, 0x03, 0xb4, 0x21, 0x01, 0x02, 0xb8, 0x21, 0x01, 0x02, 0xbc, 0x21, 0x01, 0x02, 0xc0, 0x21, 0x01, 0x02, 0xc4, 0x21, 0x01, 0x02, 0xc8, 0x21, 0x01, 0x02, 0xcc, 0x21, 0x01, 0x02, + 0xa0, 0x03, 0x02, 0x02, 0xa4, 0x03, 0x02, 0x02, 0xa8, 0x03, 0x02, 0x02, 0xac, 0x03, 0x02, 0x02, 0x48, 0x1d, 0x03, 0x03, 0x50, 0x1d, 0x03, 0x03, 0x58, 0x1d, 0x03, 0x03, 0x70, 0x00, 0x04, 0x03, + 0x78, 0x00, 0x04, 0x03, 0x40, 0x19, 0x05, 0x04, 0xe0, 0x3a, 0x06, 0x05, 0x60, 0x14, 0x07, 0x05, 0x40, 0x34, 0x08, 0x06, 0x00, 0x1e, 0x0e, 0x09, 0x60, 0x35, 0x00, 0x03, 0x68, 0x35, 0x00, 0x03, + 0x70, 0x35, 0x00, 0x03, 0xd0, 0x21, 0x01, 0x02, 0xd4, 0x21, 0x01, 0x02, 0xd8, 0x21, 0x01, 0x02, 0xdc, 0x21, 0x01, 0x02, 0xe0, 0x21, 0x01, 0x02, 0xe4, 0x21, 0x01, 0x02, 0xe8, 0x21, 0x01, 0x02, + 0xb0, 0x03, 0x02, 0x02, 0xb4, 0x03, 0x02, 0x02, 0xb8, 0x03, 0x02, 0x02, 0xbc, 0x03, 0x02, 0x02, 0x60, 0x1d, 0x03, 0x03, 0x68, 0x1d, 0x03, 0x03, 0x70, 0x1d, 0x03, 0x03, 0x80, 0x00, 0x04, 0x03, + 0x88, 0x00, 0x04, 0x03, 0x50, 0x19, 0x05, 0x04, 0x00, 0x3b, 0x06, 0x05, 0x80, 0x14, 0x07, 0x05, 0x80, 0x34, 0x08, 0x06, 0x00, 0x20, 0x0e, 0x09, 0x78, 0x35, 0x00, 0x03, 0x80, 0x35, 0x00, 0x03, + 0x88, 0x35, 0x00, 0x03, 0xec, 0x21, 0x01, 0x02, 0xf0, 0x21, 0x01, 0x02, 0xf4, 0x21, 0x01, 0x02, 0xf8, 0x21, 0x01, 0x02, 0xfc, 0x21, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x04, 0x22, 0x01, 0x02, + 0xc0, 0x03, 0x02, 0x02, 0xc4, 0x03, 0x02, 0x02, 0xc8, 0x03, 0x02, 0x02, 0xcc, 0x03, 0x02, 0x02, 0x78, 0x1d, 0x03, 0x03, 0x80, 0x1d, 0x03, 0x03, 0x88, 0x1d, 0x03, 0x03, 0x90, 0x00, 0x04, 0x03, + 0x98, 0x00, 0x04, 0x03, 0x60, 0x19, 0x05, 0x04, 0x20, 0x3b, 0x06, 0x05, 0xa0, 0x14, 0x07, 0x05, 0xc0, 0x34, 0x08, 0x06, 0x00, 0x22, 0x0e, 0x09, 0x90, 0x35, 0x00, 0x03, 0x98, 0x35, 0x00, 0x03, + 0xa0, 0x35, 0x00, 0x03, 0x08, 0x22, 0x01, 0x02, 0x0c, 0x22, 0x01, 0x02, 0x10, 0x22, 0x01, 0x02, 0x14, 0x22, 0x01, 0x02, 0x18, 0x22, 0x01, 0x02, 0x1c, 0x22, 0x01, 0x02, 0x20, 0x22, 0x01, 0x02, + 0xd0, 0x03, 0x02, 0x02, 0xd4, 0x03, 0x02, 0x02, 0xd8, 0x03, 0x02, 0x02, 0xdc, 0x03, 0x02, 0x02, 0x90, 0x1d, 0x03, 0x03, 0x98, 0x1d, 0x03, 0x03, 0xa0, 0x1d, 0x03, 0x03, 0xa0, 0x00, 0x04, 0x03, + 0xa8, 0x00, 0x04, 0x03, 0x70, 0x19, 0x05, 0x04, 0x40, 0x3b, 0x06, 0x05, 0xc0, 0x14, 0x07, 0x05, 0x00, 0x35, 0x08, 0x06, 0x00, 0x24, 0x0e, 0x09, 0xa8, 0x35, 0x00, 0x03, 0xb0, 0x35, 0x00, 0x03, + 0xb8, 0x35, 0x00, 0x03, 0x24, 0x22, 0x01, 0x02, 0x28, 0x22, 0x01, 0x02, 0x2c, 0x22, 0x01, 0x02, 0x30, 0x22, 0x01, 0x02, 0x34, 0x22, 0x01, 0x02, 0x38, 0x22, 0x01, 0x02, 0x3c, 0x22, 0x01, 0x02, + 0xe0, 0x03, 0x02, 0x02, 0xe4, 0x03, 0x02, 0x02, 0xe8, 0x03, 0x02, 0x02, 0xec, 0x03, 0x02, 0x02, 0xa8, 0x1d, 0x03, 0x03, 0xb0, 0x1d, 0x03, 0x03, 0xb8, 0x1d, 0x03, 0x03, 0xb0, 0x00, 0x04, 0x03, + 0xb8, 0x00, 0x04, 0x03, 0x80, 0x19, 0x05, 0x04, 0x60, 0x3b, 0x06, 0x05, 0xe0, 0x14, 0x07, 0x05, 0x40, 0x35, 0x08, 0x06, 0x00, 0x26, 0x0e, 0x09, 0xc0, 0x35, 0x00, 0x03, 0xc8, 0x35, 0x00, 0x03, + 0xd0, 0x35, 0x00, 0x03, 0x40, 0x22, 0x01, 0x02, 0x44, 0x22, 0x01, 0x02, 0x48, 0x22, 0x01, 0x02, 0x4c, 0x22, 0x01, 0x02, 0x50, 0x22, 0x01, 0x02, 0x54, 0x22, 0x01, 0x02, 0x58, 0x22, 0x01, 0x02, + 0xf0, 0x03, 0x02, 0x02, 0xf4, 0x03, 0x02, 0x02, 0xf8, 0x03, 0x02, 0x02, 0xfc, 0x03, 0x02, 0x02, 0xc0, 0x1d, 0x03, 0x03, 0xc8, 0x1d, 0x03, 0x03, 0xd0, 0x1d, 0x03, 0x03, 0xc0, 0x00, 0x04, 0x03, + 0xc8, 0x00, 0x04, 0x03, 0x90, 0x19, 0x05, 0x04, 0x80, 0x3b, 0x06, 0x05, 0x00, 0x15, 0x07, 0x05, 0x80, 0x35, 0x08, 0x06, 0x00, 0x04, 0x0f, 0x09, 0xd8, 0x35, 0x00, 0x03, 0xe0, 0x35, 0x00, 0x03, + 0xe8, 0x35, 0x00, 0x03, 0x5c, 0x22, 0x01, 0x02, 0x60, 0x22, 0x01, 0x02, 0x64, 0x22, 0x01, 0x02, 0x68, 0x22, 0x01, 0x02, 0x6c, 0x22, 0x01, 0x02, 0x70, 0x22, 0x01, 0x02, 0x74, 0x22, 0x01, 0x02, + 0x00, 0x04, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x08, 0x04, 0x02, 0x02, 0x0c, 0x04, 0x02, 0x02, 0xd8, 0x1d, 0x03, 0x03, 0xe0, 0x1d, 0x03, 0x03, 0xe8, 0x1d, 0x03, 0x03, 0xd0, 0x00, 0x04, 0x03, + 0xd8, 0x00, 0x04, 0x03, 0xa0, 0x19, 0x05, 0x04, 0xa0, 0x3b, 0x06, 0x05, 0x20, 0x15, 0x07, 0x05, 0xc0, 0x35, 0x08, 0x06, 0x00, 0x06, 0x0f, 0x09, 0xf0, 0x35, 0x00, 0x03, 0xf8, 0x35, 0x00, 0x03, + 0x00, 0x36, 0x00, 0x03, 0x78, 0x22, 0x01, 0x02, 0x7c, 0x22, 0x01, 0x02, 0x80, 0x22, 0x01, 0x02, 0x84, 0x22, 0x01, 0x02, 0x88, 0x22, 0x01, 0x02, 0x8c, 0x22, 0x01, 0x02, 0x90, 0x22, 0x01, 0x02, + 0x10, 0x04, 0x02, 0x02, 0x14, 0x04, 0x02, 0x02, 0x18, 0x04, 0x02, 0x02, 0x1c, 0x04, 0x02, 0x02, 0xf0, 0x1d, 0x03, 0x03, 0xf8, 0x1d, 0x03, 0x03, 0x00, 0x1e, 0x03, 0x03, 0xe0, 0x00, 0x04, 0x03, + 0xe8, 0x00, 0x04, 0x03, 0xb0, 0x19, 0x05, 0x04, 0xc0, 0x3b, 0x06, 0x05, 0x40, 0x15, 0x07, 0x05, 0x00, 0x36, 0x08, 0x06, 0x00, 0x08, 0x0f, 0x09, 0x08, 0x36, 0x00, 0x03, 0x10, 0x36, 0x00, 0x03, + 0x18, 0x36, 0x00, 0x03, 0x94, 0x22, 0x01, 0x02, 0x98, 0x22, 0x01, 0x02, 0x9c, 0x22, 0x01, 0x02, 0xa0, 0x22, 0x01, 0x02, 0xa4, 0x22, 0x01, 0x02, 0xa8, 0x22, 0x01, 0x02, 0xac, 0x22, 0x01, 0x02, + 0x20, 0x04, 0x02, 0x02, 0x24, 0x04, 0x02, 0x02, 0x28, 0x04, 0x02, 0x02, 0x2c, 0x04, 0x02, 0x02, 0x08, 0x1e, 0x03, 0x03, 0x10, 0x1e, 0x03, 0x03, 0x18, 0x1e, 0x03, 0x03, 0xf0, 0x00, 0x04, 0x03, + 0xf8, 0x00, 0x04, 0x03, 0xc0, 0x19, 0x05, 0x04, 0xe0, 0x3b, 0x06, 0x05, 0x60, 0x15, 0x07, 0x05, 0x40, 0x36, 0x08, 0x06, 0x00, 0x1c, 0x10, 0x0a, 0x20, 0x36, 0x00, 0x03, 0x28, 0x36, 0x00, 0x03, + 0x30, 0x36, 0x00, 0x03, 0xb0, 0x22, 0x01, 0x02, 0xb4, 0x22, 0x01, 0x02, 0xb8, 0x22, 0x01, 0x02, 0xbc, 0x22, 0x01, 0x02, 0xc0, 0x22, 0x01, 0x02, 0xc4, 0x22, 0x01, 0x02, 0xc8, 0x22, 0x01, 0x02, + 0x30, 0x04, 0x02, 0x02, 0x34, 0x04, 0x02, 0x02, 0x38, 0x04, 0x02, 0x02, 0x3c, 0x04, 0x02, 0x02, 0x20, 0x1e, 0x03, 0x03, 0x28, 0x1e, 0x03, 0x03, 0x30, 0x1e, 0x03, 0x03, 0x00, 0x01, 0x04, 0x03, + 0x08, 0x01, 0x04, 0x03, 0xd0, 0x19, 0x05, 0x04, 0x00, 0x3c, 0x06, 0x05, 0x80, 0x15, 0x07, 0x05, 0x80, 0x36, 0x08, 0x06, 0x00, 0x20, 0x10, 0x0a, 0x38, 0x36, 0x00, 0x03, 0x40, 0x36, 0x00, 0x03, + 0x48, 0x36, 0x00, 0x03, 0xcc, 0x22, 0x01, 0x02, 0xd0, 0x22, 0x01, 0x02, 0xd4, 0x22, 0x01, 0x02, 0xd8, 0x22, 0x01, 0x02, 0xdc, 0x22, 0x01, 0x02, 0xe0, 0x22, 0x01, 0x02, 0xe4, 0x22, 0x01, 0x02, + 0x40, 0x04, 0x02, 0x02, 0x44, 0x04, 0x02, 0x02, 0x48, 0x04, 0x02, 0x02, 0x4c, 0x04, 0x02, 0x02, 0x38, 0x1e, 0x03, 0x03, 0x40, 0x1e, 0x03, 0x03, 0x48, 0x1e, 0x03, 0x03, 0x10, 0x01, 0x04, 0x03, + 0x18, 0x01, 0x04, 0x03, 0xe0, 0x19, 0x05, 0x04, 0x20, 0x3c, 0x06, 0x05, 0xa0, 0x15, 0x07, 0x05, 0xc0, 0x36, 0x08, 0x06, 0x00, 0x38, 0x11, 0x0b, 0x50, 0x36, 0x00, 0x03, 0x58, 0x36, 0x00, 0x03, + 0x60, 0x36, 0x00, 0x03, 0xe8, 0x22, 0x01, 0x02, 0xec, 0x22, 0x01, 0x02, 0xf0, 0x22, 0x01, 0x02, 0xf4, 0x22, 0x01, 0x02, 0xf8, 0x22, 0x01, 0x02, 0xfc, 0x22, 0x01, 0x02, 0x00, 0x23, 0x01, 0x02, + 0x50, 0x04, 0x02, 0x02, 0x54, 0x04, 0x02, 0x02, 0x58, 0x04, 0x02, 0x02, 0x5c, 0x04, 0x02, 0x02, 0x50, 0x1e, 0x03, 0x03, 0x58, 0x1e, 0x03, 0x03, 0x60, 0x1e, 0x03, 0x03, 0x20, 0x01, 0x04, 0x03, + 0x28, 0x01, 0x04, 0x03, 0xf0, 0x19, 0x05, 0x04, 0x40, 0x3c, 0x06, 0x05, 0xc0, 0x15, 0x07, 0x05, 0x40, 0x11, 0x09, 0x06, 0x00, 0x00, 0x11, 0x0a, 0x68, 0x36, 0x00, 0x03, 0x70, 0x36, 0x00, 0x03, + 0x78, 0x36, 0x00, 0x03, 0x04, 0x23, 0x01, 0x02, 0x08, 0x23, 0x01, 0x02, 0x0c, 0x23, 0x01, 0x02, 0x10, 0x23, 0x01, 0x02, 0x14, 0x23, 0x01, 0x02, 0x18, 0x23, 0x01, 0x02, 0x1c, 0x23, 0x01, 0x02, + 0x60, 0x04, 0x02, 0x02, 0x64, 0x04, 0x02, 0x02, 0x68, 0x04, 0x02, 0x02, 0x6c, 0x04, 0x02, 0x02, 0x68, 0x1e, 0x03, 0x03, 0x70, 0x1e, 0x03, 0x03, 0x78, 0x1e, 0x03, 0x03, 0x30, 0x01, 0x04, 0x03, + 0x38, 0x01, 0x04, 0x03, 0x00, 0x1a, 0x05, 0x04, 0x60, 0x3c, 0x06, 0x05, 0xe0, 0x15, 0x07, 0x05, 0x80, 0x11, 0x09, 0x06, 0x00, 0x20, 0x12, 0x0b, 0x80, 0x36, 0x00, 0x03, 0x88, 0x36, 0x00, 0x03, + 0x90, 0x36, 0x00, 0x03, 0x20, 0x23, 0x01, 0x02, 0x24, 0x23, 0x01, 0x02, 0x28, 0x23, 0x01, 0x02, 0x2c, 0x23, 0x01, 0x02, 0x30, 0x23, 0x01, 0x02, 0x34, 0x23, 0x01, 0x02, 0x38, 0x23, 0x01, 0x02, + 0x70, 0x04, 0x02, 0x02, 0x74, 0x04, 0x02, 0x02, 0x78, 0x04, 0x02, 0x02, 0x7c, 0x04, 0x02, 0x02, 0x80, 0x1e, 0x03, 0x03, 0x88, 0x1e, 0x03, 0x03, 0x90, 0x1e, 0x03, 0x03, 0x40, 0x01, 0x04, 0x03, + 0x48, 0x01, 0x04, 0x03, 0x10, 0x1a, 0x05, 0x04, 0x80, 0x3c, 0x06, 0x05, 0x00, 0x16, 0x07, 0x05, 0xc0, 0x11, 0x09, 0x06, 0x00, 0x30, 0x13, 0x0c, 0x98, 0x36, 0x00, 0x03, 0xa0, 0x36, 0x00, 0x03, + 0xa8, 0x36, 0x00, 0x03, 0x3c, 0x23, 0x01, 0x02, 0x40, 0x23, 0x01, 0x02, 0x44, 0x23, 0x01, 0x02, 0x48, 0x23, 0x01, 0x02, 0x4c, 0x23, 0x01, 0x02, 0x50, 0x23, 0x01, 0x02, 0x54, 0x23, 0x01, 0x02, + 0x80, 0x04, 0x02, 0x02, 0x84, 0x04, 0x02, 0x02, 0x88, 0x04, 0x02, 0x02, 0x8c, 0x04, 0x02, 0x02, 0x98, 0x1e, 0x03, 0x03, 0xa0, 0x1e, 0x03, 0x03, 0xa8, 0x1e, 0x03, 0x03, 0x50, 0x01, 0x04, 0x03, + 0x58, 0x01, 0x04, 0x03, 0x20, 0x1a, 0x05, 0x04, 0xa0, 0x3c, 0x06, 0x05, 0x20, 0x16, 0x07, 0x05, 0x00, 0x12, 0x09, 0x06, 0x00, 0x00, 0x15, 0x0c, 0xb0, 0x36, 0x00, 0x03, 0xb8, 0x36, 0x00, 0x03, + 0xc0, 0x36, 0x00, 0x03, 0x58, 0x23, 0x01, 0x02, 0x5c, 0x23, 0x01, 0x02, 0x60, 0x23, 0x01, 0x02, 0x64, 0x23, 0x01, 0x02, 0x68, 0x23, 0x01, 0x02, 0x6c, 0x23, 0x01, 0x02, 0x70, 0x23, 0x01, 0x02, + 0x90, 0x04, 0x02, 0x02, 0x94, 0x04, 0x02, 0x02, 0x98, 0x04, 0x02, 0x02, 0x9c, 0x04, 0x02, 0x02, 0xb0, 0x1e, 0x03, 0x03, 0xb8, 0x1e, 0x03, 0x03, 0xc0, 0x1e, 0x03, 0x03, 0x60, 0x01, 0x04, 0x03, + 0x68, 0x01, 0x04, 0x03, 0x30, 0x1a, 0x05, 0x04, 0xc0, 0x3c, 0x06, 0x05, 0x40, 0x16, 0x07, 0x05, 0x40, 0x12, 0x09, 0x06, 0xc8, 0x36, 0x00, 0x03, 0xd0, 0x36, 0x00, 0x03, 0xd8, 0x36, 0x00, 0x03, + 0xe0, 0x36, 0x00, 0x03, 0x74, 0x23, 0x01, 0x02, 0x78, 0x23, 0x01, 0x02, 0x7c, 0x23, 0x01, 0x02, 0x80, 0x23, 0x01, 0x02, 0x84, 0x23, 0x01, 0x02, 0x88, 0x23, 0x01, 0x02, 0x8c, 0x23, 0x01, 0x02, + 0xa0, 0x04, 0x02, 0x02, 0xa4, 0x04, 0x02, 0x02, 0xa8, 0x04, 0x02, 0x02, 0xac, 0x04, 0x02, 0x02, 0xc8, 0x1e, 0x03, 0x03, 0xd0, 0x1e, 0x03, 0x03, 0xd8, 0x1e, 0x03, 0x03, 0x70, 0x01, 0x04, 0x03, + 0x78, 0x01, 0x04, 0x03, 0x40, 0x1a, 0x05, 0x04, 0xe0, 0x3c, 0x06, 0x05, 0x60, 0x16, 0x07, 0x05, 0x80, 0x12, 0x09, 0x06, 0xe8, 0x36, 0x00, 0x03, 0xf0, 0x36, 0x00, 0x03, 0xf8, 0x36, 0x00, 0x03, + 0x00, 0x37, 0x00, 0x03, 0x90, 0x23, 0x01, 0x02, 0x94, 0x23, 0x01, 0x02, 0x98, 0x23, 0x01, 0x02, 0x9c, 0x23, 0x01, 0x02, 0xa0, 0x23, 0x01, 0x02, 0xa4, 0x23, 0x01, 0x02, 0xb0, 0x04, 0x02, 0x02, + 0xb4, 0x04, 0x02, 0x02, 0xb8, 0x04, 0x02, 0x02, 0xbc, 0x04, 0x02, 0x02, 0xc0, 0x04, 0x02, 0x02, 0xe0, 0x1e, 0x03, 0x03, 0xe8, 0x1e, 0x03, 0x03, 0xf0, 0x1e, 0x03, 0x03, 0x80, 0x01, 0x04, 0x03, + 0x88, 0x01, 0x04, 0x03, 0x50, 0x1a, 0x05, 0x04, 0x00, 0x3d, 0x06, 0x05, 0x80, 0x16, 0x07, 0x05, 0xc0, 0x12, 0x09, 0x06, 0x08, 0x37, 0x00, 0x03, 0x10, 0x37, 0x00, 0x03, 0x18, 0x37, 0x00, 0x03, + 0x20, 0x37, 0x00, 0x03, 0xa8, 0x23, 0x01, 0x02, 0xac, 0x23, 0x01, 0x02, 0xb0, 0x23, 0x01, 0x02, 0xb4, 0x23, 0x01, 0x02, 0xb8, 0x23, 0x01, 0x02, 0xbc, 0x23, 0x01, 0x02, 0xc4, 0x04, 0x02, 0x02, + 0xc8, 0x04, 0x02, 0x02, 0xcc, 0x04, 0x02, 0x02, 0xd0, 0x04, 0x02, 0x02, 0xd4, 0x04, 0x02, 0x02, 0xf8, 0x1e, 0x03, 0x03, 0x00, 0x1f, 0x03, 0x03, 0x08, 0x1f, 0x03, 0x03, 0x90, 0x01, 0x04, 0x03, + 0x98, 0x01, 0x04, 0x03, 0x60, 0x1a, 0x05, 0x04, 0x20, 0x3d, 0x06, 0x05, 0xa0, 0x16, 0x07, 0x05, 0x00, 0x13, 0x09, 0x06, 0x28, 0x37, 0x00, 0x03, 0x30, 0x37, 0x00, 0x03, 0x38, 0x37, 0x00, 0x03, + 0x40, 0x37, 0x00, 0x03, 0xc0, 0x23, 0x01, 0x02, 0xc4, 0x23, 0x01, 0x02, 0xc8, 0x23, 0x01, 0x02, 0xcc, 0x23, 0x01, 0x02, 0xd0, 0x23, 0x01, 0x02, 0xd4, 0x23, 0x01, 0x02, 0xd8, 0x04, 0x02, 0x02, + 0xdc, 0x04, 0x02, 0x02, 0xe0, 0x04, 0x02, 0x02, 0xe4, 0x04, 0x02, 0x02, 0xe8, 0x04, 0x02, 0x02, 0x10, 0x1f, 0x03, 0x03, 0x18, 0x1f, 0x03, 0x03, 0x20, 0x1f, 0x03, 0x03, 0xa0, 0x01, 0x04, 0x03, + 0xa8, 0x01, 0x04, 0x03, 0x70, 0x1a, 0x05, 0x04, 0x40, 0x3d, 0x06, 0x05, 0xc0, 0x16, 0x07, 0x05, 0x40, 0x13, 0x09, 0x06, 0x48, 0x37, 0x00, 0x03, 0x50, 0x37, 0x00, 0x03, 0x58, 0x37, 0x00, 0x03, + 0x60, 0x37, 0x00, 0x03, 0xd8, 0x23, 0x01, 0x02, 0xdc, 0x23, 0x01, 0x02, 0xe0, 0x23, 0x01, 0x02, 0xe4, 0x23, 0x01, 0x02, 0xe8, 0x23, 0x01, 0x02, 0xec, 0x23, 0x01, 0x02, 0xec, 0x04, 0x02, 0x02, + 0xf0, 0x04, 0x02, 0x02, 0xf4, 0x04, 0x02, 0x02, 0xf8, 0x04, 0x02, 0x02, 0xfc, 0x04, 0x02, 0x02, 0x28, 0x1f, 0x03, 0x03, 0x30, 0x1f, 0x03, 0x03, 0x38, 0x1f, 0x03, 0x03, 0xb0, 0x01, 0x04, 0x03, + 0xb8, 0x01, 0x04, 0x03, 0x80, 0x1a, 0x05, 0x04, 0x60, 0x3d, 0x06, 0x05, 0xe0, 0x16, 0x07, 0x05, 0x80, 0x13, 0x09, 0x06, 0x68, 0x37, 0x00, 0x03, 0x70, 0x37, 0x00, 0x03, 0x78, 0x37, 0x00, 0x03, + 0x80, 0x37, 0x00, 0x03, 0xf0, 0x23, 0x01, 0x02, 0xf4, 0x23, 0x01, 0x02, 0xf8, 0x23, 0x01, 0x02, 0xfc, 0x23, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x04, 0x24, 0x01, 0x02, 0x00, 0x05, 0x02, 0x02, + 0x04, 0x05, 0x02, 0x02, 0x08, 0x05, 0x02, 0x02, 0x0c, 0x05, 0x02, 0x02, 0x10, 0x05, 0x02, 0x02, 0x40, 0x1f, 0x03, 0x03, 0x48, 0x1f, 0x03, 0x03, 0x50, 0x1f, 0x03, 0x03, 0xc0, 0x01, 0x04, 0x03, + 0xc8, 0x01, 0x04, 0x03, 0x90, 0x1a, 0x05, 0x04, 0x80, 0x3d, 0x06, 0x05, 0x00, 0x17, 0x07, 0x05, 0xc0, 0x13, 0x09, 0x06, 0x88, 0x37, 0x00, 0x03, 0x90, 0x37, 0x00, 0x03, 0x98, 0x37, 0x00, 0x03, + 0xa0, 0x37, 0x00, 0x03, 0x08, 0x24, 0x01, 0x02, 0x0c, 0x24, 0x01, 0x02, 0x10, 0x24, 0x01, 0x02, 0x14, 0x24, 0x01, 0x02, 0x18, 0x24, 0x01, 0x02, 0x1c, 0x24, 0x01, 0x02, 0x14, 0x05, 0x02, 0x02, + 0x18, 0x05, 0x02, 0x02, 0x1c, 0x05, 0x02, 0x02, 0x20, 0x05, 0x02, 0x02, 0x24, 0x05, 0x02, 0x02, 0x58, 0x1f, 0x03, 0x03, 0x60, 0x1f, 0x03, 0x03, 0x68, 0x1f, 0x03, 0x03, 0xd0, 0x01, 0x04, 0x03, + 0xd8, 0x01, 0x04, 0x03, 0xa0, 0x1a, 0x05, 0x04, 0xa0, 0x3d, 0x06, 0x05, 0x20, 0x17, 0x07, 0x05, 0x00, 0x14, 0x09, 0x06, 0xa8, 0x37, 0x00, 0x03, 0xb0, 0x37, 0x00, 0x03, 0xb8, 0x37, 0x00, 0x03, + 0xc0, 0x37, 0x00, 0x03, 0x20, 0x24, 0x01, 0x02, 0x24, 0x24, 0x01, 0x02, 0x28, 0x24, 0x01, 0x02, 0x2c, 0x24, 0x01, 0x02, 0x30, 0x24, 0x01, 0x02, 0x34, 0x24, 0x01, 0x02, 0x28, 0x05, 0x02, 0x02, + 0x2c, 0x05, 0x02, 0x02, 0x30, 0x05, 0x02, 0x02, 0x34, 0x05, 0x02, 0x02, 0x38, 0x05, 0x02, 0x02, 0x70, 0x1f, 0x03, 0x03, 0x78, 0x1f, 0x03, 0x03, 0x80, 0x1f, 0x03, 0x03, 0xe0, 0x01, 0x04, 0x03, + 0xe8, 0x01, 0x04, 0x03, 0xb0, 0x1a, 0x05, 0x04, 0xc0, 0x3d, 0x06, 0x05, 0x40, 0x17, 0x07, 0x05, 0x40, 0x14, 0x09, 0x06, 0xc8, 0x37, 0x00, 0x03, 0xd0, 0x37, 0x00, 0x03, 0xd8, 0x37, 0x00, 0x03, + 0xe0, 0x37, 0x00, 0x03, 0x38, 0x24, 0x01, 0x02, 0x3c, 0x24, 0x01, 0x02, 0x40, 0x24, 0x01, 0x02, 0x44, 0x24, 0x01, 0x02, 0x48, 0x24, 0x01, 0x02, 0x4c, 0x24, 0x01, 0x02, 0x3c, 0x05, 0x02, 0x02, + 0x40, 0x05, 0x02, 0x02, 0x44, 0x05, 0x02, 0x02, 0x48, 0x05, 0x02, 0x02, 0x4c, 0x05, 0x02, 0x02, 0x88, 0x1f, 0x03, 0x03, 0x90, 0x1f, 0x03, 0x03, 0x98, 0x1f, 0x03, 0x03, 0xf0, 0x01, 0x04, 0x03, + 0xf8, 0x01, 0x04, 0x03, 0xc0, 0x1a, 0x05, 0x04, 0xe0, 0x3d, 0x06, 0x05, 0x60, 0x17, 0x07, 0x05, 0x80, 0x14, 0x09, 0x06, 0xe8, 0x37, 0x00, 0x03, 0xf0, 0x37, 0x00, 0x03, 0xf8, 0x37, 0x00, 0x03, + 0x00, 0x38, 0x00, 0x03, 0x50, 0x24, 0x01, 0x02, 0x54, 0x24, 0x01, 0x02, 0x58, 0x24, 0x01, 0x02, 0x5c, 0x24, 0x01, 0x02, 0x60, 0x24, 0x01, 0x02, 0x64, 0x24, 0x01, 0x02, 0x50, 0x05, 0x02, 0x02, + 0x54, 0x05, 0x02, 0x02, 0x58, 0x05, 0x02, 0x02, 0x5c, 0x05, 0x02, 0x02, 0x60, 0x05, 0x02, 0x02, 0xa0, 0x1f, 0x03, 0x03, 0xa8, 0x1f, 0x03, 0x03, 0xb0, 0x1f, 0x03, 0x03, 0x00, 0x02, 0x04, 0x03, + 0x08, 0x02, 0x04, 0x03, 0xd0, 0x1a, 0x05, 0x04, 0x00, 0x3e, 0x06, 0x05, 0x80, 0x17, 0x07, 0x05, 0xc0, 0x14, 0x09, 0x06, 0x08, 0x38, 0x00, 0x03, 0x10, 0x38, 0x00, 0x03, 0x18, 0x38, 0x00, 0x03, + 0x20, 0x38, 0x00, 0x03, 0x68, 0x24, 0x01, 0x02, 0x6c, 0x24, 0x01, 0x02, 0x70, 0x24, 0x01, 0x02, 0x74, 0x24, 0x01, 0x02, 0x78, 0x24, 0x01, 0x02, 0x7c, 0x24, 0x01, 0x02, 0x64, 0x05, 0x02, 0x02, + 0x68, 0x05, 0x02, 0x02, 0x6c, 0x05, 0x02, 0x02, 0x70, 0x05, 0x02, 0x02, 0x74, 0x05, 0x02, 0x02, 0xb8, 0x1f, 0x03, 0x03, 0xc0, 0x1f, 0x03, 0x03, 0xc8, 0x1f, 0x03, 0x03, 0x10, 0x02, 0x04, 0x03, + 0x18, 0x02, 0x04, 0x03, 0xe0, 0x1a, 0x05, 0x04, 0x20, 0x3e, 0x06, 0x05, 0xa0, 0x17, 0x07, 0x05, 0x00, 0x15, 0x09, 0x06, 0x28, 0x38, 0x00, 0x03, 0x30, 0x38, 0x00, 0x03, 0x38, 0x38, 0x00, 0x03, + 0x40, 0x38, 0x00, 0x03, 0x80, 0x24, 0x01, 0x02, 0x84, 0x24, 0x01, 0x02, 0x88, 0x24, 0x01, 0x02, 0x8c, 0x24, 0x01, 0x02, 0x90, 0x24, 0x01, 0x02, 0x94, 0x24, 0x01, 0x02, 0x78, 0x05, 0x02, 0x02, + 0x7c, 0x05, 0x02, 0x02, 0x80, 0x05, 0x02, 0x02, 0x84, 0x05, 0x02, 0x02, 0x88, 0x05, 0x02, 0x02, 0xd0, 0x1f, 0x03, 0x03, 0xd8, 0x1f, 0x03, 0x03, 0xe0, 0x1f, 0x03, 0x03, 0x20, 0x02, 0x04, 0x03, + 0x28, 0x02, 0x04, 0x03, 0xf0, 0x1a, 0x05, 0x04, 0x40, 0x3e, 0x06, 0x05, 0xc0, 0x17, 0x07, 0x05, 0x40, 0x15, 0x09, 0x06, 0x48, 0x38, 0x00, 0x03, 0x50, 0x38, 0x00, 0x03, 0x58, 0x38, 0x00, 0x03, + 0x60, 0x38, 0x00, 0x03, 0x98, 0x24, 0x01, 0x02, 0x9c, 0x24, 0x01, 0x02, 0xa0, 0x24, 0x01, 0x02, 0xa4, 0x24, 0x01, 0x02, 0xa8, 0x24, 0x01, 0x02, 0xac, 0x24, 0x01, 0x02, 0x8c, 0x05, 0x02, 0x02, + 0x90, 0x05, 0x02, 0x02, 0x94, 0x05, 0x02, 0x02, 0x98, 0x05, 0x02, 0x02, 0x9c, 0x05, 0x02, 0x02, 0xe8, 0x1f, 0x03, 0x03, 0xf0, 0x1f, 0x03, 0x03, 0xf8, 0x1f, 0x03, 0x03, 0x30, 0x02, 0x04, 0x03, + 0x38, 0x02, 0x04, 0x03, 0x00, 0x1b, 0x05, 0x04, 0x60, 0x3e, 0x06, 0x05, 0xe0, 0x17, 0x07, 0x05, 0x80, 0x15, 0x09, 0x06, 0x68, 0x38, 0x00, 0x03, 0x70, 0x38, 0x00, 0x03, 0x78, 0x38, 0x00, 0x03, + 0x80, 0x38, 0x00, 0x03, 0xb0, 0x24, 0x01, 0x02, 0xb4, 0x24, 0x01, 0x02, 0xb8, 0x24, 0x01, 0x02, 0xbc, 0x24, 0x01, 0x02, 0xc0, 0x24, 0x01, 0x02, 0xc4, 0x24, 0x01, 0x02, 0xa0, 0x05, 0x02, 0x02, + 0xa4, 0x05, 0x02, 0x02, 0xa8, 0x05, 0x02, 0x02, 0xac, 0x05, 0x02, 0x02, 0xb0, 0x05, 0x02, 0x02, 0x00, 0x20, 0x03, 0x03, 0x08, 0x20, 0x03, 0x03, 0x10, 0x20, 0x03, 0x03, 0x40, 0x02, 0x04, 0x03, + 0x48, 0x02, 0x04, 0x03, 0x10, 0x1b, 0x05, 0x04, 0x80, 0x3e, 0x06, 0x05, 0x00, 0x18, 0x07, 0x05, 0xc0, 0x15, 0x09, 0x06, 0x88, 0x38, 0x00, 0x03, 0x90, 0x38, 0x00, 0x03, 0x98, 0x38, 0x00, 0x03, + 0xa0, 0x38, 0x00, 0x03, 0xc8, 0x24, 0x01, 0x02, 0xcc, 0x24, 0x01, 0x02, 0xd0, 0x24, 0x01, 0x02, 0xd4, 0x24, 0x01, 0x02, 0xd8, 0x24, 0x01, 0x02, 0xdc, 0x24, 0x01, 0x02, 0xb4, 0x05, 0x02, 0x02, + 0xb8, 0x05, 0x02, 0x02, 0xbc, 0x05, 0x02, 0x02, 0xc0, 0x05, 0x02, 0x02, 0xc4, 0x05, 0x02, 0x02, 0x18, 0x20, 0x03, 0x03, 0x20, 0x20, 0x03, 0x03, 0x28, 0x20, 0x03, 0x03, 0x50, 0x02, 0x04, 0x03, + 0x58, 0x02, 0x04, 0x03, 0x20, 0x1b, 0x05, 0x04, 0xa0, 0x3e, 0x06, 0x05, 0x20, 0x18, 0x07, 0x05, 0x00, 0x16, 0x09, 0x06, 0xa8, 0x38, 0x00, 0x03, 0xb0, 0x38, 0x00, 0x03, 0xb8, 0x38, 0x00, 0x03, + 0xc0, 0x38, 0x00, 0x03, 0xe0, 0x24, 0x01, 0x02, 0xe4, 0x24, 0x01, 0x02, 0xe8, 0x24, 0x01, 0x02, 0xec, 0x24, 0x01, 0x02, 0xf0, 0x24, 0x01, 0x02, 0xf4, 0x24, 0x01, 0x02, 0xc8, 0x05, 0x02, 0x02, + 0xcc, 0x05, 0x02, 0x02, 0xd0, 0x05, 0x02, 0x02, 0xd4, 0x05, 0x02, 0x02, 0xd8, 0x05, 0x02, 0x02, 0x30, 0x20, 0x03, 0x03, 0x38, 0x20, 0x03, 0x03, 0x40, 0x20, 0x03, 0x03, 0x60, 0x02, 0x04, 0x03, + 0x68, 0x02, 0x04, 0x03, 0x30, 0x1b, 0x05, 0x04, 0xc0, 0x3e, 0x06, 0x05, 0x40, 0x18, 0x07, 0x05, 0x40, 0x16, 0x09, 0x06, 0xc8, 0x38, 0x00, 0x03, 0xd0, 0x38, 0x00, 0x03, 0xd8, 0x38, 0x00, 0x03, + 0xe0, 0x38, 0x00, 0x03, 0xf8, 0x24, 0x01, 0x02, 0xfc, 0x24, 0x01, 0x02, 0x00, 0x25, 0x01, 0x02, 0x04, 0x25, 0x01, 0x02, 0x08, 0x25, 0x01, 0x02, 0x0c, 0x25, 0x01, 0x02, 0xdc, 0x05, 0x02, 0x02, + 0xe0, 0x05, 0x02, 0x02, 0xe4, 0x05, 0x02, 0x02, 0xe8, 0x05, 0x02, 0x02, 0xec, 0x05, 0x02, 0x02, 0x48, 0x20, 0x03, 0x03, 0x50, 0x20, 0x03, 0x03, 0x58, 0x20, 0x03, 0x03, 0x70, 0x02, 0x04, 0x03, + 0x78, 0x02, 0x04, 0x03, 0x40, 0x1b, 0x05, 0x04, 0xe0, 0x3e, 0x06, 0x05, 0x60, 0x18, 0x07, 0x05, 0x80, 0x16, 0x09, 0x06, 0xe8, 0x38, 0x00, 0x03, 0xf0, 0x38, 0x00, 0x03, 0xf8, 0x38, 0x00, 0x03, + 0x00, 0x39, 0x00, 0x03, 0x10, 0x25, 0x01, 0x02, 0x14, 0x25, 0x01, 0x02, 0x18, 0x25, 0x01, 0x02, 0x1c, 0x25, 0x01, 0x02, 0x20, 0x25, 0x01, 0x02, 0x24, 0x25, 0x01, 0x02, 0xf0, 0x05, 0x02, 0x02, + 0xf4, 0x05, 0x02, 0x02, 0xf8, 0x05, 0x02, 0x02, 0xfc, 0x05, 0x02, 0x02, 0x00, 0x06, 0x02, 0x02, 0x60, 0x20, 0x03, 0x03, 0x68, 0x20, 0x03, 0x03, 0x70, 0x20, 0x03, 0x03, 0x80, 0x02, 0x04, 0x03, + 0x88, 0x02, 0x04, 0x03, 0x50, 0x1b, 0x05, 0x04, 0x00, 0x3f, 0x06, 0x05, 0x80, 0x18, 0x07, 0x05, 0xc0, 0x16, 0x09, 0x06, 0x08, 0x39, 0x00, 0x03, 0x10, 0x39, 0x00, 0x03, 0x18, 0x39, 0x00, 0x03, + 0x20, 0x39, 0x00, 0x03, 0x28, 0x25, 0x01, 0x02, 0x2c, 0x25, 0x01, 0x02, 0x30, 0x25, 0x01, 0x02, 0x34, 0x25, 0x01, 0x02, 0x38, 0x25, 0x01, 0x02, 0x3c, 0x25, 0x01, 0x02, 0x04, 0x06, 0x02, 0x02, + 0x08, 0x06, 0x02, 0x02, 0x0c, 0x06, 0x02, 0x02, 0x10, 0x06, 0x02, 0x02, 0x14, 0x06, 0x02, 0x02, 0x78, 0x20, 0x03, 0x03, 0x80, 0x20, 0x03, 0x03, 0x88, 0x20, 0x03, 0x03, 0x90, 0x02, 0x04, 0x03, + 0x98, 0x02, 0x04, 0x03, 0x60, 0x1b, 0x05, 0x04, 0x20, 0x3f, 0x06, 0x05, 0xa0, 0x18, 0x07, 0x05, 0x00, 0x17, 0x09, 0x06, 0x28, 0x39, 0x00, 0x03, 0x30, 0x39, 0x00, 0x03, 0x38, 0x39, 0x00, 0x03, + 0x40, 0x39, 0x00, 0x03, 0x40, 0x25, 0x01, 0x02, 0x44, 0x25, 0x01, 0x02, 0x48, 0x25, 0x01, 0x02, 0x4c, 0x25, 0x01, 0x02, 0x50, 0x25, 0x01, 0x02, 0x54, 0x25, 0x01, 0x02, 0x18, 0x06, 0x02, 0x02, + 0x1c, 0x06, 0x02, 0x02, 0x20, 0x06, 0x02, 0x02, 0x24, 0x06, 0x02, 0x02, 0x28, 0x06, 0x02, 0x02, 0x90, 0x20, 0x03, 0x03, 0x98, 0x20, 0x03, 0x03, 0xa0, 0x20, 0x03, 0x03, 0xa0, 0x02, 0x04, 0x03, + 0xa8, 0x02, 0x04, 0x03, 0x70, 0x1b, 0x05, 0x04, 0x40, 0x3f, 0x06, 0x05, 0xc0, 0x18, 0x07, 0x05, 0x40, 0x17, 0x09, 0x06, 0x48, 0x39, 0x00, 0x03, 0x50, 0x39, 0x00, 0x03, 0x58, 0x39, 0x00, 0x03, + 0x60, 0x39, 0x00, 0x03, 0x58, 0x25, 0x01, 0x02, 0x5c, 0x25, 0x01, 0x02, 0x60, 0x25, 0x01, 0x02, 0x64, 0x25, 0x01, 0x02, 0x68, 0x25, 0x01, 0x02, 0x6c, 0x25, 0x01, 0x02, 0x2c, 0x06, 0x02, 0x02, + 0x30, 0x06, 0x02, 0x02, 0x34, 0x06, 0x02, 0x02, 0x38, 0x06, 0x02, 0x02, 0x3c, 0x06, 0x02, 0x02, 0xa8, 0x20, 0x03, 0x03, 0xb0, 0x20, 0x03, 0x03, 0xb8, 0x20, 0x03, 0x03, 0xb0, 0x02, 0x04, 0x03, + 0xb8, 0x02, 0x04, 0x03, 0x80, 0x1b, 0x05, 0x04, 0x60, 0x3f, 0x06, 0x05, 0xe0, 0x18, 0x07, 0x05, 0x80, 0x17, 0x09, 0x06, 0x68, 0x39, 0x00, 0x03, 0x70, 0x39, 0x00, 0x03, 0x78, 0x39, 0x00, 0x03, + 0x80, 0x39, 0x00, 0x03, 0x70, 0x25, 0x01, 0x02, 0x74, 0x25, 0x01, 0x02, 0x78, 0x25, 0x01, 0x02, 0x7c, 0x25, 0x01, 0x02, 0x80, 0x25, 0x01, 0x02, 0x84, 0x25, 0x01, 0x02, 0x40, 0x06, 0x02, 0x02, + 0x44, 0x06, 0x02, 0x02, 0x48, 0x06, 0x02, 0x02, 0x4c, 0x06, 0x02, 0x02, 0x50, 0x06, 0x02, 0x02, 0xc0, 0x20, 0x03, 0x03, 0xc8, 0x20, 0x03, 0x03, 0xd0, 0x20, 0x03, 0x03, 0xc0, 0x02, 0x04, 0x03, + 0xc8, 0x02, 0x04, 0x03, 0x90, 0x1b, 0x05, 0x04, 0x80, 0x3f, 0x06, 0x05, 0x00, 0x19, 0x07, 0x05, 0xc0, 0x17, 0x09, 0x06, 0x88, 0x39, 0x00, 0x03, 0x90, 0x39, 0x00, 0x03, 0x98, 0x39, 0x00, 0x03, + 0xa0, 0x39, 0x00, 0x03, 0x88, 0x25, 0x01, 0x02, 0x8c, 0x25, 0x01, 0x02, 0x90, 0x25, 0x01, 0x02, 0x94, 0x25, 0x01, 0x02, 0x98, 0x25, 0x01, 0x02, 0x9c, 0x25, 0x01, 0x02, 0x54, 0x06, 0x02, 0x02, + 0x58, 0x06, 0x02, 0x02, 0x5c, 0x06, 0x02, 0x02, 0x60, 0x06, 0x02, 0x02, 0x64, 0x06, 0x02, 0x02, 0xd8, 0x20, 0x03, 0x03, 0xe0, 0x20, 0x03, 0x03, 0xe8, 0x20, 0x03, 0x03, 0xd0, 0x02, 0x04, 0x03, + 0xd8, 0x02, 0x04, 0x03, 0xa0, 0x1b, 0x05, 0x04, 0xa0, 0x3f, 0x06, 0x05, 0x20, 0x19, 0x07, 0x05, 0x00, 0x18, 0x09, 0x06, 0xa8, 0x39, 0x00, 0x03, 0xb0, 0x39, 0x00, 0x03, 0xb8, 0x39, 0x00, 0x03, + 0xc0, 0x39, 0x00, 0x03, 0xa0, 0x25, 0x01, 0x02, 0xa4, 0x25, 0x01, 0x02, 0xa8, 0x25, 0x01, 0x02, 0xac, 0x25, 0x01, 0x02, 0xb0, 0x25, 0x01, 0x02, 0xb4, 0x25, 0x01, 0x02, 0x68, 0x06, 0x02, 0x02, + 0x6c, 0x06, 0x02, 0x02, 0x70, 0x06, 0x02, 0x02, 0x74, 0x06, 0x02, 0x02, 0x78, 0x06, 0x02, 0x02, 0xf0, 0x20, 0x03, 0x03, 0xf8, 0x20, 0x03, 0x03, 0x00, 0x21, 0x03, 0x03, 0xe0, 0x02, 0x04, 0x03, + 0xe8, 0x02, 0x04, 0x03, 0xb0, 0x1b, 0x05, 0x04, 0xc0, 0x3f, 0x06, 0x05, 0x40, 0x19, 0x07, 0x05, 0x00, 0x31, 0x0a, 0x07, 0xc8, 0x39, 0x00, 0x03, 0xd0, 0x39, 0x00, 0x03, 0xd8, 0x39, 0x00, 0x03, + 0xe0, 0x39, 0x00, 0x03, 0xb8, 0x25, 0x01, 0x02, 0xbc, 0x25, 0x01, 0x02, 0xc0, 0x25, 0x01, 0x02, 0xc4, 0x25, 0x01, 0x02, 0xc8, 0x25, 0x01, 0x02, 0xcc, 0x25, 0x01, 0x02, 0x7c, 0x06, 0x02, 0x02, + 0x80, 0x06, 0x02, 0x02, 0x84, 0x06, 0x02, 0x02, 0x88, 0x06, 0x02, 0x02, 0x8c, 0x06, 0x02, 0x02, 0x08, 0x21, 0x03, 0x03, 0x10, 0x21, 0x03, 0x03, 0x18, 0x21, 0x03, 0x03, 0xf0, 0x02, 0x04, 0x03, + 0xf8, 0x02, 0x04, 0x03, 0xc0, 0x1b, 0x05, 0x04, 0xe0, 0x3f, 0x06, 0x05, 0x60, 0x19, 0x07, 0x05, 0x80, 0x31, 0x0a, 0x07, 0xe8, 0x39, 0x00, 0x03, 0xf0, 0x39, 0x00, 0x03, 0xf8, 0x39, 0x00, 0x03, + 0x00, 0x3a, 0x00, 0x03, 0xd0, 0x25, 0x01, 0x02, 0xd4, 0x25, 0x01, 0x02, 0xd8, 0x25, 0x01, 0x02, 0xdc, 0x25, 0x01, 0x02, 0xe0, 0x25, 0x01, 0x02, 0xe4, 0x25, 0x01, 0x02, 0x90, 0x06, 0x02, 0x02, + 0x94, 0x06, 0x02, 0x02, 0x98, 0x06, 0x02, 0x02, 0x9c, 0x06, 0x02, 0x02, 0xa0, 0x06, 0x02, 0x02, 0x20, 0x21, 0x03, 0x03, 0x28, 0x21, 0x03, 0x03, 0x30, 0x21, 0x03, 0x03, 0x00, 0x03, 0x04, 0x03, + 0x08, 0x03, 0x04, 0x03, 0xd0, 0x1b, 0x05, 0x04, 0x00, 0x00, 0x06, 0x04, 0x80, 0x19, 0x07, 0x05, 0x00, 0x32, 0x0a, 0x07, 0x08, 0x3a, 0x00, 0x03, 0x10, 0x3a, 0x00, 0x03, 0x18, 0x3a, 0x00, 0x03, + 0x20, 0x3a, 0x00, 0x03, 0xe8, 0x25, 0x01, 0x02, 0xec, 0x25, 0x01, 0x02, 0xf0, 0x25, 0x01, 0x02, 0xf4, 0x25, 0x01, 0x02, 0xf8, 0x25, 0x01, 0x02, 0xfc, 0x25, 0x01, 0x02, 0xa4, 0x06, 0x02, 0x02, + 0xa8, 0x06, 0x02, 0x02, 0xac, 0x06, 0x02, 0x02, 0xb0, 0x06, 0x02, 0x02, 0xb4, 0x06, 0x02, 0x02, 0x38, 0x21, 0x03, 0x03, 0x40, 0x21, 0x03, 0x03, 0x48, 0x21, 0x03, 0x03, 0x10, 0x03, 0x04, 0x03, + 0x18, 0x03, 0x04, 0x03, 0xe0, 0x1b, 0x05, 0x04, 0x10, 0x00, 0x06, 0x04, 0xa0, 0x19, 0x07, 0x05, 0x80, 0x32, 0x0a, 0x07, 0x28, 0x3a, 0x00, 0x03, 0x30, 0x3a, 0x00, 0x03, 0x38, 0x3a, 0x00, 0x03, + 0x40, 0x3a, 0x00, 0x03, 0x00, 0x26, 0x01, 0x02, 0x04, 0x26, 0x01, 0x02, 0x08, 0x26, 0x01, 0x02, 0x0c, 0x26, 0x01, 0x02, 0x10, 0x26, 0x01, 0x02, 0x14, 0x26, 0x01, 0x02, 0xb8, 0x06, 0x02, 0x02, + 0xbc, 0x06, 0x02, 0x02, 0xc0, 0x06, 0x02, 0x02, 0xc4, 0x06, 0x02, 0x02, 0xc8, 0x06, 0x02, 0x02, 0x50, 0x21, 0x03, 0x03, 0x58, 0x21, 0x03, 0x03, 0x20, 0x03, 0x04, 0x03, 0x28, 0x03, 0x04, 0x03, + 0x30, 0x03, 0x04, 0x03, 0xf0, 0x1b, 0x05, 0x04, 0x20, 0x00, 0x06, 0x04, 0xc0, 0x19, 0x07, 0x05, 0x00, 0x33, 0x0a, 0x07, 0x48, 0x3a, 0x00, 0x03, 0x50, 0x3a, 0x00, 0x03, 0x58, 0x3a, 0x00, 0x03, + 0x60, 0x3a, 0x00, 0x03, 0x18, 0x26, 0x01, 0x02, 0x1c, 0x26, 0x01, 0x02, 0x20, 0x26, 0x01, 0x02, 0x24, 0x26, 0x01, 0x02, 0x28, 0x26, 0x01, 0x02, 0x2c, 0x26, 0x01, 0x02, 0xcc, 0x06, 0x02, 0x02, + 0xd0, 0x06, 0x02, 0x02, 0xd4, 0x06, 0x02, 0x02, 0xd8, 0x06, 0x02, 0x02, 0x60, 0x21, 0x03, 0x03, 0x68, 0x21, 0x03, 0x03, 0x70, 0x21, 0x03, 0x03, 0x38, 0x03, 0x04, 0x03, 0x40, 0x03, 0x04, 0x03, + 0x48, 0x03, 0x04, 0x03, 0x00, 0x1c, 0x05, 0x04, 0x30, 0x00, 0x06, 0x04, 0xe0, 0x19, 0x07, 0x05, 0x80, 0x33, 0x0a, 0x07, 0x68, 0x3a, 0x00, 0x03, 0x70, 0x3a, 0x00, 0x03, 0x78, 0x3a, 0x00, 0x03, + 0x80, 0x3a, 0x00, 0x03, 0x30, 0x26, 0x01, 0x02, 0x34, 0x26, 0x01, 0x02, 0x38, 0x26, 0x01, 0x02, 0x3c, 0x26, 0x01, 0x02, 0x40, 0x26, 0x01, 0x02, 0x44, 0x26, 0x01, 0x02, 0xdc, 0x06, 0x02, 0x02, + 0xe0, 0x06, 0x02, 0x02, 0xe4, 0x06, 0x02, 0x02, 0xe8, 0x06, 0x02, 0x02, 0x78, 0x21, 0x03, 0x03, 0x80, 0x21, 0x03, 0x03, 0x88, 0x21, 0x03, 0x03, 0x50, 0x03, 0x04, 0x03, 0x58, 0x03, 0x04, 0x03, + 0x60, 0x03, 0x04, 0x03, 0x10, 0x1c, 0x05, 0x04, 0x40, 0x00, 0x06, 0x04, 0x00, 0x1a, 0x07, 0x05, 0x00, 0x34, 0x0a, 0x07, 0x88, 0x3a, 0x00, 0x03, 0x90, 0x3a, 0x00, 0x03, 0x98, 0x3a, 0x00, 0x03, + 0xa0, 0x3a, 0x00, 0x03, 0x48, 0x26, 0x01, 0x02, 0x4c, 0x26, 0x01, 0x02, 0x50, 0x26, 0x01, 0x02, 0x54, 0x26, 0x01, 0x02, 0x58, 0x26, 0x01, 0x02, 0x5c, 0x26, 0x01, 0x02, 0xec, 0x06, 0x02, 0x02, + 0xf0, 0x06, 0x02, 0x02, 0xf4, 0x06, 0x02, 0x02, 0xf8, 0x06, 0x02, 0x02, 0x90, 0x21, 0x03, 0x03, 0x98, 0x21, 0x03, 0x03, 0xa0, 0x21, 0x03, 0x03, 0x68, 0x03, 0x04, 0x03, 0x70, 0x03, 0x04, 0x03, + 0x78, 0x03, 0x04, 0x03, 0x20, 0x1c, 0x05, 0x04, 0x50, 0x00, 0x06, 0x04, 0x20, 0x1a, 0x07, 0x05, 0x80, 0x34, 0x0a, 0x07, 0xa8, 0x3a, 0x00, 0x03, 0xb0, 0x3a, 0x00, 0x03, 0xb8, 0x3a, 0x00, 0x03, + 0xc0, 0x3a, 0x00, 0x03, 0x60, 0x26, 0x01, 0x02, 0x64, 0x26, 0x01, 0x02, 0x68, 0x26, 0x01, 0x02, 0x6c, 0x26, 0x01, 0x02, 0x70, 0x26, 0x01, 0x02, 0x74, 0x26, 0x01, 0x02, 0xfc, 0x06, 0x02, 0x02, + 0x00, 0x07, 0x02, 0x02, 0x04, 0x07, 0x02, 0x02, 0x08, 0x07, 0x02, 0x02, 0xa8, 0x21, 0x03, 0x03, 0xb0, 0x21, 0x03, 0x03, 0xb8, 0x21, 0x03, 0x03, 0x80, 0x03, 0x04, 0x03, 0x88, 0x03, 0x04, 0x03, + 0x90, 0x03, 0x04, 0x03, 0x30, 0x1c, 0x05, 0x04, 0x60, 0x00, 0x06, 0x04, 0x40, 0x1a, 0x07, 0x05, 0x00, 0x35, 0x0a, 0x07, 0xc8, 0x3a, 0x00, 0x03, 0xd0, 0x3a, 0x00, 0x03, 0xd8, 0x3a, 0x00, 0x03, + 0xe0, 0x3a, 0x00, 0x03, 0x78, 0x26, 0x01, 0x02, 0x7c, 0x26, 0x01, 0x02, 0x80, 0x26, 0x01, 0x02, 0x84, 0x26, 0x01, 0x02, 0x88, 0x26, 0x01, 0x02, 0x8c, 0x26, 0x01, 0x02, 0x0c, 0x07, 0x02, 0x02, + 0x10, 0x07, 0x02, 0x02, 0x14, 0x07, 0x02, 0x02, 0x18, 0x07, 0x02, 0x02, 0xc0, 0x21, 0x03, 0x03, 0xc8, 0x21, 0x03, 0x03, 0xd0, 0x21, 0x03, 0x03, 0x98, 0x03, 0x04, 0x03, 0xa0, 0x03, 0x04, 0x03, + 0xa8, 0x03, 0x04, 0x03, 0x40, 0x1c, 0x05, 0x04, 0x70, 0x00, 0x06, 0x04, 0x60, 0x1a, 0x07, 0x05, 0x80, 0x35, 0x0a, 0x07, 0xe8, 0x3a, 0x00, 0x03, 0xf0, 0x3a, 0x00, 0x03, 0xf8, 0x3a, 0x00, 0x03, + 0x00, 0x3b, 0x00, 0x03, 0x90, 0x26, 0x01, 0x02, 0x94, 0x26, 0x01, 0x02, 0x98, 0x26, 0x01, 0x02, 0x9c, 0x26, 0x01, 0x02, 0xa0, 0x26, 0x01, 0x02, 0xa4, 0x26, 0x01, 0x02, 0x1c, 0x07, 0x02, 0x02, + 0x20, 0x07, 0x02, 0x02, 0x24, 0x07, 0x02, 0x02, 0x28, 0x07, 0x02, 0x02, 0xd8, 0x21, 0x03, 0x03, 0xe0, 0x21, 0x03, 0x03, 0xe8, 0x21, 0x03, 0x03, 0xb0, 0x03, 0x04, 0x03, 0xb8, 0x03, 0x04, 0x03, + 0x50, 0x1c, 0x05, 0x04, 0x60, 0x1c, 0x05, 0x04, 0x80, 0x00, 0x06, 0x04, 0x80, 0x1a, 0x07, 0x05, 0x00, 0x36, 0x0a, 0x07, 0x08, 0x3b, 0x00, 0x03, 0x10, 0x3b, 0x00, 0x03, 0x18, 0x3b, 0x00, 0x03, + 0x20, 0x3b, 0x00, 0x03, 0xa8, 0x26, 0x01, 0x02, 0xac, 0x26, 0x01, 0x02, 0xb0, 0x26, 0x01, 0x02, 0xb4, 0x26, 0x01, 0x02, 0xb8, 0x26, 0x01, 0x02, 0xbc, 0x26, 0x01, 0x02, 0x2c, 0x07, 0x02, 0x02, + 0x30, 0x07, 0x02, 0x02, 0x34, 0x07, 0x02, 0x02, 0x38, 0x07, 0x02, 0x02, 0xf0, 0x21, 0x03, 0x03, 0xf8, 0x21, 0x03, 0x03, 0x00, 0x22, 0x03, 0x03, 0xc0, 0x03, 0x04, 0x03, 0xc8, 0x03, 0x04, 0x03, + 0x70, 0x1c, 0x05, 0x04, 0x80, 0x1c, 0x05, 0x04, 0x90, 0x00, 0x06, 0x04, 0xa0, 0x1a, 0x07, 0x05, 0x80, 0x36, 0x0a, 0x07, 0x28, 0x3b, 0x00, 0x03, 0x30, 0x3b, 0x00, 0x03, 0x38, 0x3b, 0x00, 0x03, + 0x40, 0x3b, 0x00, 0x03, 0xc0, 0x26, 0x01, 0x02, 0xc4, 0x26, 0x01, 0x02, 0xc8, 0x26, 0x01, 0x02, 0xcc, 0x26, 0x01, 0x02, 0xd0, 0x26, 0x01, 0x02, 0xd4, 0x26, 0x01, 0x02, 0x3c, 0x07, 0x02, 0x02, + 0x40, 0x07, 0x02, 0x02, 0x44, 0x07, 0x02, 0x02, 0x48, 0x07, 0x02, 0x02, 0x08, 0x22, 0x03, 0x03, 0x10, 0x22, 0x03, 0x03, 0x18, 0x22, 0x03, 0x03, 0xd0, 0x03, 0x04, 0x03, 0xd8, 0x03, 0x04, 0x03, + 0x90, 0x1c, 0x05, 0x04, 0xa0, 0x1c, 0x05, 0x04, 0xa0, 0x00, 0x06, 0x04, 0xc0, 0x1a, 0x07, 0x05, 0x00, 0x37, 0x0a, 0x07, 0x48, 0x3b, 0x00, 0x03, 0x50, 0x3b, 0x00, 0x03, 0x58, 0x3b, 0x00, 0x03, + 0x60, 0x3b, 0x00, 0x03, 0xd8, 0x26, 0x01, 0x02, 0xdc, 0x26, 0x01, 0x02, 0xe0, 0x26, 0x01, 0x02, 0xe4, 0x26, 0x01, 0x02, 0xe8, 0x26, 0x01, 0x02, 0xec, 0x26, 0x01, 0x02, 0x4c, 0x07, 0x02, 0x02, + 0x50, 0x07, 0x02, 0x02, 0x54, 0x07, 0x02, 0x02, 0x58, 0x07, 0x02, 0x02, 0x20, 0x22, 0x03, 0x03, 0x28, 0x22, 0x03, 0x03, 0x30, 0x22, 0x03, 0x03, 0xe0, 0x03, 0x04, 0x03, 0xe8, 0x03, 0x04, 0x03, + 0xb0, 0x1c, 0x05, 0x04, 0xc0, 0x1c, 0x05, 0x04, 0xb0, 0x00, 0x06, 0x04, 0xe0, 0x1a, 0x07, 0x05, 0x80, 0x37, 0x0a, 0x07, 0x68, 0x3b, 0x00, 0x03, 0x70, 0x3b, 0x00, 0x03, 0x78, 0x3b, 0x00, 0x03, + 0x80, 0x3b, 0x00, 0x03, 0xf0, 0x26, 0x01, 0x02, 0xf4, 0x26, 0x01, 0x02, 0xf8, 0x26, 0x01, 0x02, 0xfc, 0x26, 0x01, 0x02, 0x00, 0x27, 0x01, 0x02, 0x04, 0x27, 0x01, 0x02, 0x5c, 0x07, 0x02, 0x02, + 0x60, 0x07, 0x02, 0x02, 0x64, 0x07, 0x02, 0x02, 0x68, 0x07, 0x02, 0x02, 0x38, 0x22, 0x03, 0x03, 0x40, 0x22, 0x03, 0x03, 0x48, 0x22, 0x03, 0x03, 0xf0, 0x03, 0x04, 0x03, 0xf8, 0x03, 0x04, 0x03, + 0xd0, 0x1c, 0x05, 0x04, 0xe0, 0x1c, 0x05, 0x04, 0xc0, 0x00, 0x06, 0x04, 0x00, 0x1b, 0x07, 0x05, 0x00, 0x38, 0x0a, 0x07, 0x88, 0x3b, 0x00, 0x03, 0x90, 0x3b, 0x00, 0x03, 0x98, 0x3b, 0x00, 0x03, + 0xa0, 0x3b, 0x00, 0x03, 0x08, 0x27, 0x01, 0x02, 0x0c, 0x27, 0x01, 0x02, 0x10, 0x27, 0x01, 0x02, 0x14, 0x27, 0x01, 0x02, 0x18, 0x27, 0x01, 0x02, 0x1c, 0x27, 0x01, 0x02, 0x6c, 0x07, 0x02, 0x02, + 0x70, 0x07, 0x02, 0x02, 0x74, 0x07, 0x02, 0x02, 0x78, 0x07, 0x02, 0x02, 0x50, 0x22, 0x03, 0x03, 0x58, 0x22, 0x03, 0x03, 0x60, 0x22, 0x03, 0x03, 0x00, 0x04, 0x04, 0x03, 0x08, 0x04, 0x04, 0x03, + 0xf0, 0x1c, 0x05, 0x04, 0x00, 0x1d, 0x05, 0x04, 0xd0, 0x00, 0x06, 0x04, 0x20, 0x1b, 0x07, 0x05, 0x80, 0x38, 0x0a, 0x07, 0xa8, 0x3b, 0x00, 0x03, 0xb0, 0x3b, 0x00, 0x03, 0xb8, 0x3b, 0x00, 0x03, + 0xc0, 0x3b, 0x00, 0x03, 0x20, 0x27, 0x01, 0x02, 0x24, 0x27, 0x01, 0x02, 0x28, 0x27, 0x01, 0x02, 0x2c, 0x27, 0x01, 0x02, 0x30, 0x27, 0x01, 0x02, 0x34, 0x27, 0x01, 0x02, 0x7c, 0x07, 0x02, 0x02, + 0x80, 0x07, 0x02, 0x02, 0x84, 0x07, 0x02, 0x02, 0x88, 0x07, 0x02, 0x02, 0x68, 0x22, 0x03, 0x03, 0x70, 0x22, 0x03, 0x03, 0x78, 0x22, 0x03, 0x03, 0x10, 0x04, 0x04, 0x03, 0x18, 0x04, 0x04, 0x03, + 0x10, 0x1d, 0x05, 0x04, 0x20, 0x1d, 0x05, 0x04, 0xe0, 0x00, 0x06, 0x04, 0x40, 0x1b, 0x07, 0x05, 0x00, 0x39, 0x0a, 0x07, 0xc8, 0x3b, 0x00, 0x03, 0xd0, 0x3b, 0x00, 0x03, 0xd8, 0x3b, 0x00, 0x03, + 0xe0, 0x3b, 0x00, 0x03, 0x38, 0x27, 0x01, 0x02, 0x3c, 0x27, 0x01, 0x02, 0x40, 0x27, 0x01, 0x02, 0x44, 0x27, 0x01, 0x02, 0x48, 0x27, 0x01, 0x02, 0x4c, 0x27, 0x01, 0x02, 0x8c, 0x07, 0x02, 0x02, + 0x90, 0x07, 0x02, 0x02, 0x94, 0x07, 0x02, 0x02, 0x98, 0x07, 0x02, 0x02, 0x80, 0x22, 0x03, 0x03, 0x88, 0x22, 0x03, 0x03, 0x90, 0x22, 0x03, 0x03, 0x20, 0x04, 0x04, 0x03, 0x28, 0x04, 0x04, 0x03, + 0x30, 0x1d, 0x05, 0x04, 0x40, 0x1d, 0x05, 0x04, 0xf0, 0x00, 0x06, 0x04, 0x00, 0x37, 0x08, 0x06, 0x80, 0x39, 0x0a, 0x07, 0xe8, 0x3b, 0x00, 0x03, 0xf0, 0x3b, 0x00, 0x03, 0xf8, 0x3b, 0x00, 0x03, + 0x00, 0x3c, 0x00, 0x03, 0x50, 0x27, 0x01, 0x02, 0x54, 0x27, 0x01, 0x02, 0x58, 0x27, 0x01, 0x02, 0x5c, 0x27, 0x01, 0x02, 0x60, 0x27, 0x01, 0x02, 0x64, 0x27, 0x01, 0x02, 0x9c, 0x07, 0x02, 0x02, + 0xa0, 0x07, 0x02, 0x02, 0xa4, 0x07, 0x02, 0x02, 0xa8, 0x07, 0x02, 0x02, 0x98, 0x22, 0x03, 0x03, 0xa0, 0x22, 0x03, 0x03, 0xa8, 0x22, 0x03, 0x03, 0x30, 0x04, 0x04, 0x03, 0x38, 0x04, 0x04, 0x03, + 0x50, 0x1d, 0x05, 0x04, 0x60, 0x1d, 0x05, 0x04, 0x00, 0x01, 0x06, 0x04, 0x40, 0x37, 0x08, 0x06, 0x00, 0x3a, 0x0a, 0x07, 0x08, 0x3c, 0x00, 0x03, 0x10, 0x3c, 0x00, 0x03, 0x18, 0x3c, 0x00, 0x03, + 0x20, 0x3c, 0x00, 0x03, 0x68, 0x27, 0x01, 0x02, 0x6c, 0x27, 0x01, 0x02, 0x70, 0x27, 0x01, 0x02, 0x74, 0x27, 0x01, 0x02, 0x78, 0x27, 0x01, 0x02, 0x7c, 0x27, 0x01, 0x02, 0xac, 0x07, 0x02, 0x02, + 0xb0, 0x07, 0x02, 0x02, 0xb4, 0x07, 0x02, 0x02, 0xb8, 0x07, 0x02, 0x02, 0xb0, 0x22, 0x03, 0x03, 0xb8, 0x22, 0x03, 0x03, 0xc0, 0x22, 0x03, 0x03, 0x40, 0x04, 0x04, 0x03, 0x48, 0x04, 0x04, 0x03, + 0x70, 0x1d, 0x05, 0x04, 0x80, 0x1d, 0x05, 0x04, 0x10, 0x01, 0x06, 0x04, 0x80, 0x37, 0x08, 0x06, 0x00, 0x0e, 0x0b, 0x07, 0x28, 0x3c, 0x00, 0x03, 0x30, 0x3c, 0x00, 0x03, 0x38, 0x3c, 0x00, 0x03, + 0x40, 0x3c, 0x00, 0x03, 0x80, 0x27, 0x01, 0x02, 0x84, 0x27, 0x01, 0x02, 0x88, 0x27, 0x01, 0x02, 0x8c, 0x27, 0x01, 0x02, 0x90, 0x27, 0x01, 0x02, 0x94, 0x27, 0x01, 0x02, 0xbc, 0x07, 0x02, 0x02, + 0xc0, 0x07, 0x02, 0x02, 0xc4, 0x07, 0x02, 0x02, 0xc8, 0x07, 0x02, 0x02, 0xc8, 0x22, 0x03, 0x03, 0xd0, 0x22, 0x03, 0x03, 0xd8, 0x22, 0x03, 0x03, 0x50, 0x04, 0x04, 0x03, 0x58, 0x04, 0x04, 0x03, + 0x90, 0x1d, 0x05, 0x04, 0xa0, 0x1d, 0x05, 0x04, 0x20, 0x01, 0x06, 0x04, 0xc0, 0x37, 0x08, 0x06, 0x80, 0x0e, 0x0b, 0x07, 0x48, 0x3c, 0x00, 0x03, 0x50, 0x3c, 0x00, 0x03, 0x58, 0x3c, 0x00, 0x03, + 0x60, 0x3c, 0x00, 0x03, 0x98, 0x27, 0x01, 0x02, 0x9c, 0x27, 0x01, 0x02, 0xa0, 0x27, 0x01, 0x02, 0xa4, 0x27, 0x01, 0x02, 0xa8, 0x27, 0x01, 0x02, 0xac, 0x27, 0x01, 0x02, 0xcc, 0x07, 0x02, 0x02, + 0xd0, 0x07, 0x02, 0x02, 0xd4, 0x07, 0x02, 0x02, 0xd8, 0x07, 0x02, 0x02, 0xe0, 0x22, 0x03, 0x03, 0xe8, 0x22, 0x03, 0x03, 0xf0, 0x22, 0x03, 0x03, 0x60, 0x04, 0x04, 0x03, 0x68, 0x04, 0x04, 0x03, + 0xb0, 0x1d, 0x05, 0x04, 0xc0, 0x1d, 0x05, 0x04, 0x30, 0x01, 0x06, 0x04, 0x00, 0x38, 0x08, 0x06, 0x00, 0x0f, 0x0b, 0x07, 0x68, 0x3c, 0x00, 0x03, 0x70, 0x3c, 0x00, 0x03, 0x78, 0x3c, 0x00, 0x03, + 0x80, 0x3c, 0x00, 0x03, 0xb0, 0x27, 0x01, 0x02, 0xb4, 0x27, 0x01, 0x02, 0xb8, 0x27, 0x01, 0x02, 0xbc, 0x27, 0x01, 0x02, 0xc0, 0x27, 0x01, 0x02, 0xc4, 0x27, 0x01, 0x02, 0xdc, 0x07, 0x02, 0x02, + 0xe0, 0x07, 0x02, 0x02, 0xe4, 0x07, 0x02, 0x02, 0xe8, 0x07, 0x02, 0x02, 0xf8, 0x22, 0x03, 0x03, 0x00, 0x23, 0x03, 0x03, 0x08, 0x23, 0x03, 0x03, 0x70, 0x04, 0x04, 0x03, 0x78, 0x04, 0x04, 0x03, + 0xd0, 0x1d, 0x05, 0x04, 0xe0, 0x1d, 0x05, 0x04, 0x40, 0x01, 0x06, 0x04, 0x40, 0x38, 0x08, 0x06, 0x80, 0x0f, 0x0b, 0x07, 0x88, 0x3c, 0x00, 0x03, 0x90, 0x3c, 0x00, 0x03, 0x98, 0x3c, 0x00, 0x03, + 0xa0, 0x3c, 0x00, 0x03, 0xc8, 0x27, 0x01, 0x02, 0xcc, 0x27, 0x01, 0x02, 0xd0, 0x27, 0x01, 0x02, 0xd4, 0x27, 0x01, 0x02, 0xd8, 0x27, 0x01, 0x02, 0xdc, 0x27, 0x01, 0x02, 0xec, 0x07, 0x02, 0x02, + 0xf0, 0x07, 0x02, 0x02, 0xf4, 0x07, 0x02, 0x02, 0xf8, 0x07, 0x02, 0x02, 0x10, 0x23, 0x03, 0x03, 0x18, 0x23, 0x03, 0x03, 0x20, 0x23, 0x03, 0x03, 0x80, 0x04, 0x04, 0x03, 0x88, 0x04, 0x04, 0x03, + 0xf0, 0x1d, 0x05, 0x04, 0x00, 0x1e, 0x05, 0x04, 0x50, 0x01, 0x06, 0x04, 0x80, 0x38, 0x08, 0x06, 0x00, 0x10, 0x0b, 0x07, 0xa8, 0x3c, 0x00, 0x03, 0xb0, 0x3c, 0x00, 0x03, 0xb8, 0x3c, 0x00, 0x03, + 0xc0, 0x3c, 0x00, 0x03, 0xe0, 0x27, 0x01, 0x02, 0xe4, 0x27, 0x01, 0x02, 0xe8, 0x27, 0x01, 0x02, 0xec, 0x27, 0x01, 0x02, 0xf0, 0x27, 0x01, 0x02, 0xf4, 0x27, 0x01, 0x02, 0xfc, 0x07, 0x02, 0x02, + 0x00, 0x08, 0x02, 0x02, 0x04, 0x08, 0x02, 0x02, 0x08, 0x08, 0x02, 0x02, 0x28, 0x23, 0x03, 0x03, 0x30, 0x23, 0x03, 0x03, 0x38, 0x23, 0x03, 0x03, 0x90, 0x04, 0x04, 0x03, 0x98, 0x04, 0x04, 0x03, + 0x10, 0x1e, 0x05, 0x04, 0x20, 0x1e, 0x05, 0x04, 0x60, 0x01, 0x06, 0x04, 0xc0, 0x38, 0x08, 0x06, 0x80, 0x10, 0x0b, 0x07, 0xc8, 0x3c, 0x00, 0x03, 0xd0, 0x3c, 0x00, 0x03, 0xd8, 0x3c, 0x00, 0x03, + 0xe0, 0x3c, 0x00, 0x03, 0xf8, 0x27, 0x01, 0x02, 0xfc, 0x27, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x04, 0x28, 0x01, 0x02, 0x08, 0x28, 0x01, 0x02, 0x0c, 0x28, 0x01, 0x02, 0x0c, 0x08, 0x02, 0x02, + 0x10, 0x08, 0x02, 0x02, 0x14, 0x08, 0x02, 0x02, 0x18, 0x08, 0x02, 0x02, 0x40, 0x23, 0x03, 0x03, 0x48, 0x23, 0x03, 0x03, 0x50, 0x23, 0x03, 0x03, 0xa0, 0x04, 0x04, 0x03, 0xa8, 0x04, 0x04, 0x03, + 0x30, 0x1e, 0x05, 0x04, 0x40, 0x1e, 0x05, 0x04, 0x70, 0x01, 0x06, 0x04, 0x00, 0x39, 0x08, 0x06, 0x00, 0x11, 0x0b, 0x07, 0xe8, 0x3c, 0x00, 0x03, 0xf0, 0x3c, 0x00, 0x03, 0xf8, 0x3c, 0x00, 0x03, + 0x00, 0x3d, 0x00, 0x03, 0x10, 0x28, 0x01, 0x02, 0x14, 0x28, 0x01, 0x02, 0x18, 0x28, 0x01, 0x02, 0x1c, 0x28, 0x01, 0x02, 0x20, 0x28, 0x01, 0x02, 0x24, 0x28, 0x01, 0x02, 0x1c, 0x08, 0x02, 0x02, + 0x20, 0x08, 0x02, 0x02, 0x24, 0x08, 0x02, 0x02, 0x28, 0x08, 0x02, 0x02, 0x58, 0x23, 0x03, 0x03, 0x60, 0x23, 0x03, 0x03, 0x68, 0x23, 0x03, 0x03, 0xb0, 0x04, 0x04, 0x03, 0xb8, 0x04, 0x04, 0x03, + 0x50, 0x1e, 0x05, 0x04, 0x60, 0x1e, 0x05, 0x04, 0x80, 0x01, 0x06, 0x04, 0x40, 0x39, 0x08, 0x06, 0x80, 0x11, 0x0b, 0x07, 0x08, 0x3d, 0x00, 0x03, 0x10, 0x3d, 0x00, 0x03, 0x18, 0x3d, 0x00, 0x03, + 0x20, 0x3d, 0x00, 0x03, 0x28, 0x28, 0x01, 0x02, 0x2c, 0x28, 0x01, 0x02, 0x30, 0x28, 0x01, 0x02, 0x34, 0x28, 0x01, 0x02, 0x38, 0x28, 0x01, 0x02, 0x3c, 0x28, 0x01, 0x02, 0x2c, 0x08, 0x02, 0x02, + 0x30, 0x08, 0x02, 0x02, 0x34, 0x08, 0x02, 0x02, 0x38, 0x08, 0x02, 0x02, 0x70, 0x23, 0x03, 0x03, 0x78, 0x23, 0x03, 0x03, 0x80, 0x23, 0x03, 0x03, 0xc0, 0x04, 0x04, 0x03, 0xc8, 0x04, 0x04, 0x03, + 0x70, 0x1e, 0x05, 0x04, 0x80, 0x1e, 0x05, 0x04, 0x90, 0x01, 0x06, 0x04, 0x80, 0x39, 0x08, 0x06, 0x00, 0x12, 0x0b, 0x07, 0x28, 0x3d, 0x00, 0x03, 0x30, 0x3d, 0x00, 0x03, 0x38, 0x3d, 0x00, 0x03, + 0x40, 0x3d, 0x00, 0x03, 0x40, 0x28, 0x01, 0x02, 0x44, 0x28, 0x01, 0x02, 0x48, 0x28, 0x01, 0x02, 0x4c, 0x28, 0x01, 0x02, 0x50, 0x28, 0x01, 0x02, 0x54, 0x28, 0x01, 0x02, 0x3c, 0x08, 0x02, 0x02, + 0x40, 0x08, 0x02, 0x02, 0x44, 0x08, 0x02, 0x02, 0x48, 0x08, 0x02, 0x02, 0x88, 0x23, 0x03, 0x03, 0x90, 0x23, 0x03, 0x03, 0x98, 0x23, 0x03, 0x03, 0xd0, 0x04, 0x04, 0x03, 0xd8, 0x04, 0x04, 0x03, + 0x90, 0x1e, 0x05, 0x04, 0xa0, 0x1e, 0x05, 0x04, 0xa0, 0x01, 0x06, 0x04, 0xc0, 0x39, 0x08, 0x06, 0x80, 0x12, 0x0b, 0x07, 0x48, 0x3d, 0x00, 0x03, 0x50, 0x3d, 0x00, 0x03, 0x58, 0x3d, 0x00, 0x03, + 0x60, 0x3d, 0x00, 0x03, 0x58, 0x28, 0x01, 0x02, 0x5c, 0x28, 0x01, 0x02, 0x60, 0x28, 0x01, 0x02, 0x64, 0x28, 0x01, 0x02, 0x68, 0x28, 0x01, 0x02, 0x6c, 0x28, 0x01, 0x02, 0x4c, 0x08, 0x02, 0x02, + 0x50, 0x08, 0x02, 0x02, 0x54, 0x08, 0x02, 0x02, 0x58, 0x08, 0x02, 0x02, 0xa0, 0x23, 0x03, 0x03, 0xa8, 0x23, 0x03, 0x03, 0xb0, 0x23, 0x03, 0x03, 0xe0, 0x04, 0x04, 0x03, 0xe8, 0x04, 0x04, 0x03, + 0xb0, 0x1e, 0x05, 0x04, 0xc0, 0x1e, 0x05, 0x04, 0xb0, 0x01, 0x06, 0x04, 0x00, 0x3a, 0x08, 0x06, 0x00, 0x13, 0x0b, 0x07, 0x68, 0x3d, 0x00, 0x03, 0x70, 0x3d, 0x00, 0x03, 0x78, 0x3d, 0x00, 0x03, + 0x80, 0x3d, 0x00, 0x03, 0x70, 0x28, 0x01, 0x02, 0x74, 0x28, 0x01, 0x02, 0x78, 0x28, 0x01, 0x02, 0x7c, 0x28, 0x01, 0x02, 0x80, 0x28, 0x01, 0x02, 0x84, 0x28, 0x01, 0x02, 0x5c, 0x08, 0x02, 0x02, + 0x60, 0x08, 0x02, 0x02, 0x64, 0x08, 0x02, 0x02, 0x68, 0x08, 0x02, 0x02, 0xb8, 0x23, 0x03, 0x03, 0xc0, 0x23, 0x03, 0x03, 0xc8, 0x23, 0x03, 0x03, 0xf0, 0x04, 0x04, 0x03, 0xf8, 0x04, 0x04, 0x03, + 0xd0, 0x1e, 0x05, 0x04, 0xe0, 0x1e, 0x05, 0x04, 0xc0, 0x01, 0x06, 0x04, 0x40, 0x3a, 0x08, 0x06, 0x80, 0x13, 0x0b, 0x07, 0x88, 0x3d, 0x00, 0x03, 0x90, 0x3d, 0x00, 0x03, 0x98, 0x3d, 0x00, 0x03, + 0xa0, 0x3d, 0x00, 0x03, 0x88, 0x28, 0x01, 0x02, 0x8c, 0x28, 0x01, 0x02, 0x90, 0x28, 0x01, 0x02, 0x94, 0x28, 0x01, 0x02, 0x98, 0x28, 0x01, 0x02, 0x9c, 0x28, 0x01, 0x02, 0x6c, 0x08, 0x02, 0x02, + 0x70, 0x08, 0x02, 0x02, 0x74, 0x08, 0x02, 0x02, 0x78, 0x08, 0x02, 0x02, 0xd0, 0x23, 0x03, 0x03, 0xd8, 0x23, 0x03, 0x03, 0xe0, 0x23, 0x03, 0x03, 0x00, 0x05, 0x04, 0x03, 0x08, 0x05, 0x04, 0x03, + 0xf0, 0x1e, 0x05, 0x04, 0x00, 0x1f, 0x05, 0x04, 0xd0, 0x01, 0x06, 0x04, 0x80, 0x3a, 0x08, 0x06, 0x00, 0x14, 0x0b, 0x07, 0xa8, 0x3d, 0x00, 0x03, 0xb0, 0x3d, 0x00, 0x03, 0xb8, 0x3d, 0x00, 0x03, + 0xc0, 0x3d, 0x00, 0x03, 0xa0, 0x28, 0x01, 0x02, 0xa4, 0x28, 0x01, 0x02, 0xa8, 0x28, 0x01, 0x02, 0xac, 0x28, 0x01, 0x02, 0xb0, 0x28, 0x01, 0x02, 0xb4, 0x28, 0x01, 0x02, 0x7c, 0x08, 0x02, 0x02, + 0x80, 0x08, 0x02, 0x02, 0x84, 0x08, 0x02, 0x02, 0x88, 0x08, 0x02, 0x02, 0xe8, 0x23, 0x03, 0x03, 0xf0, 0x23, 0x03, 0x03, 0xf8, 0x23, 0x03, 0x03, 0x10, 0x05, 0x04, 0x03, 0x18, 0x05, 0x04, 0x03, + 0x10, 0x1f, 0x05, 0x04, 0x20, 0x1f, 0x05, 0x04, 0xe0, 0x01, 0x06, 0x04, 0xc0, 0x3a, 0x08, 0x06, 0x00, 0x2c, 0x0c, 0x08, 0xc8, 0x3d, 0x00, 0x03, 0xd0, 0x3d, 0x00, 0x03, 0xd8, 0x3d, 0x00, 0x03, + 0xe0, 0x3d, 0x00, 0x03, 0xb8, 0x28, 0x01, 0x02, 0xbc, 0x28, 0x01, 0x02, 0xc0, 0x28, 0x01, 0x02, 0xc4, 0x28, 0x01, 0x02, 0xc8, 0x28, 0x01, 0x02, 0xcc, 0x28, 0x01, 0x02, 0x8c, 0x08, 0x02, 0x02, + 0x90, 0x08, 0x02, 0x02, 0x94, 0x08, 0x02, 0x02, 0x98, 0x08, 0x02, 0x02, 0x00, 0x24, 0x03, 0x03, 0x08, 0x24, 0x03, 0x03, 0x10, 0x24, 0x03, 0x03, 0x20, 0x05, 0x04, 0x03, 0x28, 0x05, 0x04, 0x03, + 0x30, 0x1f, 0x05, 0x04, 0x40, 0x1f, 0x05, 0x04, 0xf0, 0x01, 0x06, 0x04, 0x00, 0x3b, 0x08, 0x06, 0x00, 0x2d, 0x0c, 0x08, 0xe8, 0x3d, 0x00, 0x03, 0xf0, 0x3d, 0x00, 0x03, 0xf8, 0x3d, 0x00, 0x03, + 0x00, 0x3e, 0x00, 0x03, 0xd0, 0x28, 0x01, 0x02, 0xd4, 0x28, 0x01, 0x02, 0xd8, 0x28, 0x01, 0x02, 0xdc, 0x28, 0x01, 0x02, 0xe0, 0x28, 0x01, 0x02, 0xe4, 0x28, 0x01, 0x02, 0x9c, 0x08, 0x02, 0x02, + 0xa0, 0x08, 0x02, 0x02, 0xa4, 0x08, 0x02, 0x02, 0xa8, 0x08, 0x02, 0x02, 0x18, 0x24, 0x03, 0x03, 0x20, 0x24, 0x03, 0x03, 0x28, 0x24, 0x03, 0x03, 0x30, 0x05, 0x04, 0x03, 0x38, 0x05, 0x04, 0x03, + 0x50, 0x1f, 0x05, 0x04, 0x60, 0x1f, 0x05, 0x04, 0x00, 0x02, 0x06, 0x04, 0x40, 0x3b, 0x08, 0x06, 0x00, 0x2e, 0x0c, 0x08, 0x08, 0x3e, 0x00, 0x03, 0x10, 0x3e, 0x00, 0x03, 0x18, 0x3e, 0x00, 0x03, + 0x20, 0x3e, 0x00, 0x03, 0xe8, 0x28, 0x01, 0x02, 0xec, 0x28, 0x01, 0x02, 0xf0, 0x28, 0x01, 0x02, 0xf4, 0x28, 0x01, 0x02, 0xf8, 0x28, 0x01, 0x02, 0xfc, 0x28, 0x01, 0x02, 0xac, 0x08, 0x02, 0x02, + 0xb0, 0x08, 0x02, 0x02, 0xb4, 0x08, 0x02, 0x02, 0xb8, 0x08, 0x02, 0x02, 0x30, 0x24, 0x03, 0x03, 0x38, 0x24, 0x03, 0x03, 0x40, 0x24, 0x03, 0x03, 0x40, 0x05, 0x04, 0x03, 0x48, 0x05, 0x04, 0x03, + 0x70, 0x1f, 0x05, 0x04, 0x80, 0x1f, 0x05, 0x04, 0x10, 0x02, 0x06, 0x04, 0x80, 0x3b, 0x08, 0x06, 0x00, 0x2f, 0x0c, 0x08, 0x28, 0x3e, 0x00, 0x03, 0x30, 0x3e, 0x00, 0x03, 0x38, 0x3e, 0x00, 0x03, + 0x40, 0x3e, 0x00, 0x03, 0x00, 0x29, 0x01, 0x02, 0x04, 0x29, 0x01, 0x02, 0x08, 0x29, 0x01, 0x02, 0x0c, 0x29, 0x01, 0x02, 0x10, 0x29, 0x01, 0x02, 0x14, 0x29, 0x01, 0x02, 0xbc, 0x08, 0x02, 0x02, + 0xc0, 0x08, 0x02, 0x02, 0xc4, 0x08, 0x02, 0x02, 0xc8, 0x08, 0x02, 0x02, 0x48, 0x24, 0x03, 0x03, 0x50, 0x24, 0x03, 0x03, 0x58, 0x24, 0x03, 0x03, 0x50, 0x05, 0x04, 0x03, 0x58, 0x05, 0x04, 0x03, + 0x90, 0x1f, 0x05, 0x04, 0xa0, 0x1f, 0x05, 0x04, 0x20, 0x02, 0x06, 0x04, 0xc0, 0x3b, 0x08, 0x06, 0x00, 0x30, 0x0c, 0x08, 0x48, 0x3e, 0x00, 0x03, 0x50, 0x3e, 0x00, 0x03, 0x58, 0x3e, 0x00, 0x03, + 0x60, 0x3e, 0x00, 0x03, 0x18, 0x29, 0x01, 0x02, 0x1c, 0x29, 0x01, 0x02, 0x20, 0x29, 0x01, 0x02, 0x24, 0x29, 0x01, 0x02, 0x28, 0x29, 0x01, 0x02, 0x2c, 0x29, 0x01, 0x02, 0xcc, 0x08, 0x02, 0x02, + 0xd0, 0x08, 0x02, 0x02, 0xd4, 0x08, 0x02, 0x02, 0xd8, 0x08, 0x02, 0x02, 0x60, 0x24, 0x03, 0x03, 0x68, 0x24, 0x03, 0x03, 0x70, 0x24, 0x03, 0x03, 0x60, 0x05, 0x04, 0x03, 0x68, 0x05, 0x04, 0x03, + 0xb0, 0x1f, 0x05, 0x04, 0xc0, 0x1f, 0x05, 0x04, 0x30, 0x02, 0x06, 0x04, 0x00, 0x3c, 0x08, 0x06, 0x00, 0x31, 0x0c, 0x08, 0x68, 0x3e, 0x00, 0x03, 0x70, 0x3e, 0x00, 0x03, 0x78, 0x3e, 0x00, 0x03, + 0x80, 0x3e, 0x00, 0x03, 0x30, 0x29, 0x01, 0x02, 0x34, 0x29, 0x01, 0x02, 0x38, 0x29, 0x01, 0x02, 0x3c, 0x29, 0x01, 0x02, 0x40, 0x29, 0x01, 0x02, 0x44, 0x29, 0x01, 0x02, 0xdc, 0x08, 0x02, 0x02, + 0xe0, 0x08, 0x02, 0x02, 0xe4, 0x08, 0x02, 0x02, 0xe8, 0x08, 0x02, 0x02, 0x78, 0x24, 0x03, 0x03, 0x80, 0x24, 0x03, 0x03, 0x88, 0x24, 0x03, 0x03, 0x70, 0x05, 0x04, 0x03, 0x78, 0x05, 0x04, 0x03, + 0xd0, 0x1f, 0x05, 0x04, 0xe0, 0x1f, 0x05, 0x04, 0x40, 0x02, 0x06, 0x04, 0x40, 0x3c, 0x08, 0x06, 0x00, 0x32, 0x0c, 0x08, 0x88, 0x3e, 0x00, 0x03, 0x90, 0x3e, 0x00, 0x03, 0x98, 0x3e, 0x00, 0x03, + 0xa0, 0x3e, 0x00, 0x03, 0x48, 0x29, 0x01, 0x02, 0x4c, 0x29, 0x01, 0x02, 0x50, 0x29, 0x01, 0x02, 0x54, 0x29, 0x01, 0x02, 0x58, 0x29, 0x01, 0x02, 0x5c, 0x29, 0x01, 0x02, 0xec, 0x08, 0x02, 0x02, + 0xf0, 0x08, 0x02, 0x02, 0xf4, 0x08, 0x02, 0x02, 0xf8, 0x08, 0x02, 0x02, 0x90, 0x24, 0x03, 0x03, 0x98, 0x24, 0x03, 0x03, 0xa0, 0x24, 0x03, 0x03, 0x80, 0x05, 0x04, 0x03, 0x88, 0x05, 0x04, 0x03, + 0xf0, 0x1f, 0x05, 0x04, 0x00, 0x20, 0x05, 0x04, 0x50, 0x02, 0x06, 0x04, 0x80, 0x3c, 0x08, 0x06, 0x00, 0x33, 0x0c, 0x08, 0xa8, 0x3e, 0x00, 0x03, 0xb0, 0x3e, 0x00, 0x03, 0xb8, 0x3e, 0x00, 0x03, + 0x60, 0x29, 0x01, 0x02, 0x64, 0x29, 0x01, 0x02, 0x68, 0x29, 0x01, 0x02, 0x6c, 0x29, 0x01, 0x02, 0x70, 0x29, 0x01, 0x02, 0x74, 0x29, 0x01, 0x02, 0x78, 0x29, 0x01, 0x02, 0xfc, 0x08, 0x02, 0x02, + 0x00, 0x09, 0x02, 0x02, 0x04, 0x09, 0x02, 0x02, 0x08, 0x09, 0x02, 0x02, 0xa8, 0x24, 0x03, 0x03, 0xb0, 0x24, 0x03, 0x03, 0xb8, 0x24, 0x03, 0x03, 0x90, 0x05, 0x04, 0x03, 0x98, 0x05, 0x04, 0x03, + 0x10, 0x20, 0x05, 0x04, 0x20, 0x20, 0x05, 0x04, 0x60, 0x02, 0x06, 0x04, 0xc0, 0x3c, 0x08, 0x06, 0x00, 0x34, 0x0c, 0x08, 0xc0, 0x3e, 0x00, 0x03, 0xc8, 0x3e, 0x00, 0x03, 0xd0, 0x3e, 0x00, 0x03, + 0x7c, 0x29, 0x01, 0x02, 0x80, 0x29, 0x01, 0x02, 0x84, 0x29, 0x01, 0x02, 0x88, 0x29, 0x01, 0x02, 0x8c, 0x29, 0x01, 0x02, 0x90, 0x29, 0x01, 0x02, 0x94, 0x29, 0x01, 0x02, 0x0c, 0x09, 0x02, 0x02, + 0x10, 0x09, 0x02, 0x02, 0x14, 0x09, 0x02, 0x02, 0x18, 0x09, 0x02, 0x02, 0xc0, 0x24, 0x03, 0x03, 0xc8, 0x24, 0x03, 0x03, 0xd0, 0x24, 0x03, 0x03, 0xa0, 0x05, 0x04, 0x03, 0xa8, 0x05, 0x04, 0x03, + 0x30, 0x20, 0x05, 0x04, 0x40, 0x20, 0x05, 0x04, 0x70, 0x02, 0x06, 0x04, 0x00, 0x3d, 0x08, 0x06, 0x00, 0x0b, 0x0d, 0x08, 0xd8, 0x3e, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x03, 0xe8, 0x3e, 0x00, 0x03, + 0x98, 0x29, 0x01, 0x02, 0x9c, 0x29, 0x01, 0x02, 0xa0, 0x29, 0x01, 0x02, 0xa4, 0x29, 0x01, 0x02, 0xa8, 0x29, 0x01, 0x02, 0xac, 0x29, 0x01, 0x02, 0xb0, 0x29, 0x01, 0x02, 0x1c, 0x09, 0x02, 0x02, + 0x20, 0x09, 0x02, 0x02, 0x24, 0x09, 0x02, 0x02, 0x28, 0x09, 0x02, 0x02, 0xd8, 0x24, 0x03, 0x03, 0xe0, 0x24, 0x03, 0x03, 0xe8, 0x24, 0x03, 0x03, 0xb0, 0x05, 0x04, 0x03, 0xb8, 0x05, 0x04, 0x03, + 0x50, 0x20, 0x05, 0x04, 0x60, 0x20, 0x05, 0x04, 0x80, 0x02, 0x06, 0x04, 0x40, 0x3d, 0x08, 0x06, 0x00, 0x0c, 0x0d, 0x08, 0xf0, 0x3e, 0x00, 0x03, 0xf8, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x03, + 0xb4, 0x29, 0x01, 0x02, 0xb8, 0x29, 0x01, 0x02, 0xbc, 0x29, 0x01, 0x02, 0xc0, 0x29, 0x01, 0x02, 0xc4, 0x29, 0x01, 0x02, 0xc8, 0x29, 0x01, 0x02, 0xcc, 0x29, 0x01, 0x02, 0x2c, 0x09, 0x02, 0x02, + 0x30, 0x09, 0x02, 0x02, 0x34, 0x09, 0x02, 0x02, 0x38, 0x09, 0x02, 0x02, 0xf0, 0x24, 0x03, 0x03, 0xf8, 0x24, 0x03, 0x03, 0x00, 0x25, 0x03, 0x03, 0xc0, 0x05, 0x04, 0x03, 0xc8, 0x05, 0x04, 0x03, + 0x70, 0x20, 0x05, 0x04, 0x80, 0x20, 0x05, 0x04, 0x90, 0x02, 0x06, 0x04, 0x80, 0x3d, 0x08, 0x06, 0x00, 0x0d, 0x0d, 0x08, 0x08, 0x3f, 0x00, 0x03, 0x10, 0x3f, 0x00, 0x03, 0x18, 0x3f, 0x00, 0x03, + 0xd0, 0x29, 0x01, 0x02, 0xd4, 0x29, 0x01, 0x02, 0xd8, 0x29, 0x01, 0x02, 0xdc, 0x29, 0x01, 0x02, 0xe0, 0x29, 0x01, 0x02, 0xe4, 0x29, 0x01, 0x02, 0xe8, 0x29, 0x01, 0x02, 0x3c, 0x09, 0x02, 0x02, + 0x40, 0x09, 0x02, 0x02, 0x44, 0x09, 0x02, 0x02, 0x48, 0x09, 0x02, 0x02, 0x08, 0x25, 0x03, 0x03, 0x10, 0x25, 0x03, 0x03, 0x18, 0x25, 0x03, 0x03, 0xd0, 0x05, 0x04, 0x03, 0xd8, 0x05, 0x04, 0x03, + 0x90, 0x20, 0x05, 0x04, 0xa0, 0x20, 0x05, 0x04, 0x60, 0x1b, 0x07, 0x05, 0xc0, 0x3d, 0x08, 0x06, 0x00, 0x0e, 0x0d, 0x08, 0x20, 0x3f, 0x00, 0x03, 0x28, 0x3f, 0x00, 0x03, 0x30, 0x3f, 0x00, 0x03, + 0xec, 0x29, 0x01, 0x02, 0xf0, 0x29, 0x01, 0x02, 0xf4, 0x29, 0x01, 0x02, 0xf8, 0x29, 0x01, 0x02, 0xfc, 0x29, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x04, 0x2a, 0x01, 0x02, 0x4c, 0x09, 0x02, 0x02, + 0x50, 0x09, 0x02, 0x02, 0x54, 0x09, 0x02, 0x02, 0x58, 0x09, 0x02, 0x02, 0x20, 0x25, 0x03, 0x03, 0x28, 0x25, 0x03, 0x03, 0x30, 0x25, 0x03, 0x03, 0xe0, 0x05, 0x04, 0x03, 0xe8, 0x05, 0x04, 0x03, + 0xb0, 0x20, 0x05, 0x04, 0xa0, 0x02, 0x06, 0x04, 0x80, 0x1b, 0x07, 0x05, 0x00, 0x3e, 0x08, 0x06, 0x00, 0x0f, 0x0d, 0x08, 0x38, 0x3f, 0x00, 0x03, 0x40, 0x3f, 0x00, 0x03, 0x48, 0x3f, 0x00, 0x03, + 0x08, 0x2a, 0x01, 0x02, 0x0c, 0x2a, 0x01, 0x02, 0x10, 0x2a, 0x01, 0x02, 0x14, 0x2a, 0x01, 0x02, 0x18, 0x2a, 0x01, 0x02, 0x1c, 0x2a, 0x01, 0x02, 0x20, 0x2a, 0x01, 0x02, 0x5c, 0x09, 0x02, 0x02, + 0x60, 0x09, 0x02, 0x02, 0x64, 0x09, 0x02, 0x02, 0x68, 0x09, 0x02, 0x02, 0x38, 0x25, 0x03, 0x03, 0x40, 0x25, 0x03, 0x03, 0x48, 0x25, 0x03, 0x03, 0xf0, 0x05, 0x04, 0x03, 0xf8, 0x05, 0x04, 0x03, + 0xc0, 0x20, 0x05, 0x04, 0xb0, 0x02, 0x06, 0x04, 0xa0, 0x1b, 0x07, 0x05, 0x40, 0x3e, 0x08, 0x06, 0x00, 0x10, 0x0d, 0x08, 0x50, 0x3f, 0x00, 0x03, 0x58, 0x3f, 0x00, 0x03, 0x60, 0x3f, 0x00, 0x03, + 0x24, 0x2a, 0x01, 0x02, 0x28, 0x2a, 0x01, 0x02, 0x2c, 0x2a, 0x01, 0x02, 0x30, 0x2a, 0x01, 0x02, 0x34, 0x2a, 0x01, 0x02, 0x38, 0x2a, 0x01, 0x02, 0x3c, 0x2a, 0x01, 0x02, 0x6c, 0x09, 0x02, 0x02, + 0x70, 0x09, 0x02, 0x02, 0x74, 0x09, 0x02, 0x02, 0x78, 0x09, 0x02, 0x02, 0x50, 0x25, 0x03, 0x03, 0x58, 0x25, 0x03, 0x03, 0x60, 0x25, 0x03, 0x03, 0x00, 0x06, 0x04, 0x03, 0x08, 0x06, 0x04, 0x03, + 0xd0, 0x20, 0x05, 0x04, 0xc0, 0x02, 0x06, 0x04, 0xc0, 0x1b, 0x07, 0x05, 0x80, 0x3e, 0x08, 0x06, 0x00, 0x28, 0x0e, 0x09, 0x68, 0x3f, 0x00, 0x03, 0x70, 0x3f, 0x00, 0x03, 0x78, 0x3f, 0x00, 0x03, + 0x40, 0x2a, 0x01, 0x02, 0x44, 0x2a, 0x01, 0x02, 0x48, 0x2a, 0x01, 0x02, 0x4c, 0x2a, 0x01, 0x02, 0x50, 0x2a, 0x01, 0x02, 0x54, 0x2a, 0x01, 0x02, 0x58, 0x2a, 0x01, 0x02, 0x7c, 0x09, 0x02, 0x02, + 0x80, 0x09, 0x02, 0x02, 0x84, 0x09, 0x02, 0x02, 0x88, 0x09, 0x02, 0x02, 0x68, 0x25, 0x03, 0x03, 0x70, 0x25, 0x03, 0x03, 0x78, 0x25, 0x03, 0x03, 0x10, 0x06, 0x04, 0x03, 0x18, 0x06, 0x04, 0x03, + 0xe0, 0x20, 0x05, 0x04, 0xd0, 0x02, 0x06, 0x04, 0xe0, 0x1b, 0x07, 0x05, 0xc0, 0x3e, 0x08, 0x06, 0x00, 0x2a, 0x0e, 0x09, 0x80, 0x3f, 0x00, 0x03, 0x88, 0x3f, 0x00, 0x03, 0x90, 0x3f, 0x00, 0x03, + 0x5c, 0x2a, 0x01, 0x02, 0x60, 0x2a, 0x01, 0x02, 0x64, 0x2a, 0x01, 0x02, 0x68, 0x2a, 0x01, 0x02, 0x6c, 0x2a, 0x01, 0x02, 0x70, 0x2a, 0x01, 0x02, 0x74, 0x2a, 0x01, 0x02, 0x8c, 0x09, 0x02, 0x02, + 0x90, 0x09, 0x02, 0x02, 0x94, 0x09, 0x02, 0x02, 0x98, 0x09, 0x02, 0x02, 0x80, 0x25, 0x03, 0x03, 0x88, 0x25, 0x03, 0x03, 0x90, 0x25, 0x03, 0x03, 0x20, 0x06, 0x04, 0x03, 0x28, 0x06, 0x04, 0x03, + 0xf0, 0x20, 0x05, 0x04, 0xe0, 0x02, 0x06, 0x04, 0x00, 0x1c, 0x07, 0x05, 0x00, 0x3f, 0x08, 0x06, 0x00, 0x2c, 0x0e, 0x09, 0x98, 0x3f, 0x00, 0x03, 0xa0, 0x3f, 0x00, 0x03, 0xa8, 0x3f, 0x00, 0x03, + 0x78, 0x2a, 0x01, 0x02, 0x7c, 0x2a, 0x01, 0x02, 0x80, 0x2a, 0x01, 0x02, 0x84, 0x2a, 0x01, 0x02, 0x88, 0x2a, 0x01, 0x02, 0x8c, 0x2a, 0x01, 0x02, 0x90, 0x2a, 0x01, 0x02, 0x9c, 0x09, 0x02, 0x02, + 0xa0, 0x09, 0x02, 0x02, 0xa4, 0x09, 0x02, 0x02, 0xa8, 0x09, 0x02, 0x02, 0x98, 0x25, 0x03, 0x03, 0xa0, 0x25, 0x03, 0x03, 0xa8, 0x25, 0x03, 0x03, 0x30, 0x06, 0x04, 0x03, 0x38, 0x06, 0x04, 0x03, + 0x00, 0x21, 0x05, 0x04, 0xf0, 0x02, 0x06, 0x04, 0x20, 0x1c, 0x07, 0x05, 0x40, 0x3f, 0x08, 0x06, 0x00, 0x2e, 0x0e, 0x09, 0xb0, 0x3f, 0x00, 0x03, 0xb8, 0x3f, 0x00, 0x03, 0xc0, 0x3f, 0x00, 0x03, + 0x94, 0x2a, 0x01, 0x02, 0x98, 0x2a, 0x01, 0x02, 0x9c, 0x2a, 0x01, 0x02, 0xa0, 0x2a, 0x01, 0x02, 0xa4, 0x2a, 0x01, 0x02, 0xa8, 0x2a, 0x01, 0x02, 0xac, 0x2a, 0x01, 0x02, 0xac, 0x09, 0x02, 0x02, + 0xb0, 0x09, 0x02, 0x02, 0xb4, 0x09, 0x02, 0x02, 0xb8, 0x09, 0x02, 0x02, 0xb0, 0x25, 0x03, 0x03, 0xb8, 0x25, 0x03, 0x03, 0xc0, 0x25, 0x03, 0x03, 0x40, 0x06, 0x04, 0x03, 0x48, 0x06, 0x04, 0x03, + 0x10, 0x21, 0x05, 0x04, 0x00, 0x03, 0x06, 0x04, 0x40, 0x1c, 0x07, 0x05, 0x80, 0x3f, 0x08, 0x06, 0x00, 0x0a, 0x0f, 0x09, 0xc8, 0x3f, 0x00, 0x03, 0xd0, 0x3f, 0x00, 0x03, 0xd8, 0x3f, 0x00, 0x03, + 0xb0, 0x2a, 0x01, 0x02, 0xb4, 0x2a, 0x01, 0x02, 0xb8, 0x2a, 0x01, 0x02, 0xbc, 0x2a, 0x01, 0x02, 0xc0, 0x2a, 0x01, 0x02, 0xc4, 0x2a, 0x01, 0x02, 0xc8, 0x2a, 0x01, 0x02, 0xbc, 0x09, 0x02, 0x02, + 0xc0, 0x09, 0x02, 0x02, 0xc4, 0x09, 0x02, 0x02, 0xc8, 0x09, 0x02, 0x02, 0xc8, 0x25, 0x03, 0x03, 0xd0, 0x25, 0x03, 0x03, 0xd8, 0x25, 0x03, 0x03, 0x50, 0x06, 0x04, 0x03, 0x58, 0x06, 0x04, 0x03, + 0x20, 0x21, 0x05, 0x04, 0x10, 0x03, 0x06, 0x04, 0x60, 0x1c, 0x07, 0x05, 0xc0, 0x3f, 0x08, 0x06, 0x00, 0x0c, 0x0f, 0x09, 0xe0, 0x3f, 0x00, 0x03, 0xe8, 0x3f, 0x00, 0x03, 0xf0, 0x3f, 0x00, 0x03, + 0xcc, 0x2a, 0x01, 0x02, 0xd0, 0x2a, 0x01, 0x02, 0xd4, 0x2a, 0x01, 0x02, 0xd8, 0x2a, 0x01, 0x02, 0xdc, 0x2a, 0x01, 0x02, 0xe0, 0x2a, 0x01, 0x02, 0xe4, 0x2a, 0x01, 0x02, 0xcc, 0x09, 0x02, 0x02, + 0xd0, 0x09, 0x02, 0x02, 0xd4, 0x09, 0x02, 0x02, 0xd8, 0x09, 0x02, 0x02, 0xe0, 0x25, 0x03, 0x03, 0xe8, 0x25, 0x03, 0x03, 0xf0, 0x25, 0x03, 0x03, 0x60, 0x06, 0x04, 0x03, 0x68, 0x06, 0x04, 0x03, + 0x30, 0x21, 0x05, 0x04, 0x20, 0x03, 0x06, 0x04, 0x80, 0x1c, 0x07, 0x05, 0x00, 0x00, 0x08, 0x05, 0x00, 0x0e, 0x0f, 0x09, 0xf8, 0x3f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, + 0xe8, 0x2a, 0x01, 0x02, 0xec, 0x2a, 0x01, 0x02, 0xf0, 0x2a, 0x01, 0x02, 0xf4, 0x2a, 0x01, 0x02, 0xf8, 0x2a, 0x01, 0x02, 0xfc, 0x2a, 0x01, 0x02, 0x00, 0x2b, 0x01, 0x02, 0xdc, 0x09, 0x02, 0x02, + 0xe0, 0x09, 0x02, 0x02, 0xe4, 0x09, 0x02, 0x02, 0xe8, 0x09, 0x02, 0x02, 0xf8, 0x25, 0x03, 0x03, 0x00, 0x26, 0x03, 0x03, 0x08, 0x26, 0x03, 0x03, 0x70, 0x06, 0x04, 0x03, 0x78, 0x06, 0x04, 0x03, + 0x40, 0x21, 0x05, 0x04, 0x30, 0x03, 0x06, 0x04, 0xa0, 0x1c, 0x07, 0x05, 0x20, 0x00, 0x08, 0x05, 0x00, 0x24, 0x10, 0x0a, 0x08, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x02, + 0x04, 0x2b, 0x01, 0x02, 0x08, 0x2b, 0x01, 0x02, 0x0c, 0x2b, 0x01, 0x02, 0x10, 0x2b, 0x01, 0x02, 0x14, 0x2b, 0x01, 0x02, 0x18, 0x2b, 0x01, 0x02, 0x1c, 0x2b, 0x01, 0x02, 0xec, 0x09, 0x02, 0x02, + 0xf0, 0x09, 0x02, 0x02, 0xf4, 0x09, 0x02, 0x02, 0xf8, 0x09, 0x02, 0x02, 0x10, 0x26, 0x03, 0x03, 0x18, 0x26, 0x03, 0x03, 0x20, 0x26, 0x03, 0x03, 0x80, 0x06, 0x04, 0x03, 0x88, 0x06, 0x04, 0x03, + 0x50, 0x21, 0x05, 0x04, 0x40, 0x03, 0x06, 0x04, 0xc0, 0x1c, 0x07, 0x05, 0x40, 0x00, 0x08, 0x05, 0x00, 0x28, 0x10, 0x0a, 0x14, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x02, + 0x20, 0x2b, 0x01, 0x02, 0x24, 0x2b, 0x01, 0x02, 0x28, 0x2b, 0x01, 0x02, 0x2c, 0x2b, 0x01, 0x02, 0x30, 0x2b, 0x01, 0x02, 0x34, 0x2b, 0x01, 0x02, 0x38, 0x2b, 0x01, 0x02, 0xfc, 0x09, 0x02, 0x02, + 0x00, 0x0a, 0x02, 0x02, 0x04, 0x0a, 0x02, 0x02, 0x08, 0x0a, 0x02, 0x02, 0x28, 0x26, 0x03, 0x03, 0x30, 0x26, 0x03, 0x03, 0x38, 0x26, 0x03, 0x03, 0x90, 0x06, 0x04, 0x03, 0x98, 0x06, 0x04, 0x03, + 0x60, 0x21, 0x05, 0x04, 0x50, 0x03, 0x06, 0x04, 0xe0, 0x1c, 0x07, 0x05, 0x60, 0x00, 0x08, 0x05, 0x00, 0x2c, 0x10, 0x0a, 0x20, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x02, 0x28, 0x00, 0x00, 0x02, + 0x3c, 0x2b, 0x01, 0x02, 0x40, 0x2b, 0x01, 0x02, 0x44, 0x2b, 0x01, 0x02, 0x48, 0x2b, 0x01, 0x02, 0x4c, 0x2b, 0x01, 0x02, 0x50, 0x2b, 0x01, 0x02, 0x54, 0x2b, 0x01, 0x02, 0x0c, 0x0a, 0x02, 0x02, + 0x10, 0x0a, 0x02, 0x02, 0x14, 0x0a, 0x02, 0x02, 0x18, 0x0a, 0x02, 0x02, 0x40, 0x26, 0x03, 0x03, 0x48, 0x26, 0x03, 0x03, 0x50, 0x26, 0x03, 0x03, 0xa0, 0x06, 0x04, 0x03, 0xa8, 0x06, 0x04, 0x03, + 0x70, 0x21, 0x05, 0x04, 0x60, 0x03, 0x06, 0x04, 0x00, 0x1d, 0x07, 0x05, 0x40, 0x18, 0x09, 0x06, 0x00, 0x04, 0x11, 0x0a, 0x2c, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x02, 0x34, 0x00, 0x00, 0x02, + 0x58, 0x2b, 0x01, 0x02, 0x5c, 0x2b, 0x01, 0x02, 0x60, 0x2b, 0x01, 0x02, 0x64, 0x2b, 0x01, 0x02, 0x68, 0x2b, 0x01, 0x02, 0x6c, 0x2b, 0x01, 0x02, 0x70, 0x2b, 0x01, 0x02, 0x1c, 0x0a, 0x02, 0x02, + 0x20, 0x0a, 0x02, 0x02, 0x24, 0x0a, 0x02, 0x02, 0x28, 0x0a, 0x02, 0x02, 0x58, 0x26, 0x03, 0x03, 0x60, 0x26, 0x03, 0x03, 0x68, 0x26, 0x03, 0x03, 0xb0, 0x06, 0x04, 0x03, 0xb8, 0x06, 0x04, 0x03, + 0x80, 0x21, 0x05, 0x04, 0x70, 0x03, 0x06, 0x04, 0x20, 0x1d, 0x07, 0x05, 0x80, 0x18, 0x09, 0x06, 0x00, 0x28, 0x12, 0x0b, 0x38, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, + 0x74, 0x2b, 0x01, 0x02, 0x78, 0x2b, 0x01, 0x02, 0x7c, 0x2b, 0x01, 0x02, 0x80, 0x2b, 0x01, 0x02, 0x84, 0x2b, 0x01, 0x02, 0x88, 0x2b, 0x01, 0x02, 0x8c, 0x2b, 0x01, 0x02, 0x2c, 0x0a, 0x02, 0x02, + 0x30, 0x0a, 0x02, 0x02, 0x34, 0x0a, 0x02, 0x02, 0x38, 0x0a, 0x02, 0x02, 0x70, 0x26, 0x03, 0x03, 0x78, 0x26, 0x03, 0x03, 0x80, 0x26, 0x03, 0x03, 0xc0, 0x06, 0x04, 0x03, 0xc8, 0x06, 0x04, 0x03, + 0x90, 0x21, 0x05, 0x04, 0x80, 0x03, 0x06, 0x04, 0x40, 0x1d, 0x07, 0x05, 0xc0, 0x18, 0x09, 0x06, 0x00, 0x00, 0x13, 0x0b, 0x44, 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x02, 0x4c, 0x00, 0x00, 0x02, + 0x90, 0x2b, 0x01, 0x02, 0x94, 0x2b, 0x01, 0x02, 0x98, 0x2b, 0x01, 0x02, 0x9c, 0x2b, 0x01, 0x02, 0xa0, 0x2b, 0x01, 0x02, 0xa4, 0x2b, 0x01, 0x02, 0xa8, 0x2b, 0x01, 0x02, 0x3c, 0x0a, 0x02, 0x02, + 0x40, 0x0a, 0x02, 0x02, 0x44, 0x0a, 0x02, 0x02, 0x48, 0x0a, 0x02, 0x02, 0x88, 0x26, 0x03, 0x03, 0x90, 0x26, 0x03, 0x03, 0x98, 0x26, 0x03, 0x03, 0xd0, 0x06, 0x04, 0x03, 0xd8, 0x06, 0x04, 0x03, + 0xa0, 0x21, 0x05, 0x04, 0x90, 0x03, 0x06, 0x04, 0x60, 0x1d, 0x07, 0x05, 0x00, 0x19, 0x09, 0x06, 0x00, 0x20, 0x14, 0x0c, 0x50, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x02, 0x58, 0x00, 0x00, 0x02, + 0xac, 0x2b, 0x01, 0x02, 0xb0, 0x2b, 0x01, 0x02, 0xb4, 0x2b, 0x01, 0x02, 0xb8, 0x2b, 0x01, 0x02, 0xbc, 0x2b, 0x01, 0x02, 0xc0, 0x2b, 0x01, 0x02, 0xc4, 0x2b, 0x01, 0x02, 0x4c, 0x0a, 0x02, 0x02, + 0x50, 0x0a, 0x02, 0x02, 0x54, 0x0a, 0x02, 0x02, 0x58, 0x0a, 0x02, 0x02, 0xa0, 0x26, 0x03, 0x03, 0xa8, 0x26, 0x03, 0x03, 0xb0, 0x26, 0x03, 0x03, 0xe0, 0x06, 0x04, 0x03, 0xe8, 0x06, 0x04, 0x03, + 0xb0, 0x21, 0x05, 0x04, 0xa0, 0x03, 0x06, 0x04, 0x80, 0x1d, 0x07, 0x05, 0x40, 0x19, 0x09, 0x06, 0x5c, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x02, 0x64, 0x00, 0x00, 0x02, 0x68, 0x00, 0x00, 0x02, + 0xc8, 0x2b, 0x01, 0x02, 0xcc, 0x2b, 0x01, 0x02, 0xd0, 0x2b, 0x01, 0x02, 0xd4, 0x2b, 0x01, 0x02, 0xd8, 0x2b, 0x01, 0x02, 0xdc, 0x2b, 0x01, 0x02, 0xe0, 0x2b, 0x01, 0x02, 0x5c, 0x0a, 0x02, 0x02, + 0x60, 0x0a, 0x02, 0x02, 0x64, 0x0a, 0x02, 0x02, 0x68, 0x0a, 0x02, 0x02, 0xb8, 0x26, 0x03, 0x03, 0xc0, 0x26, 0x03, 0x03, 0xc8, 0x26, 0x03, 0x03, 0xf0, 0x06, 0x04, 0x03, 0xf8, 0x06, 0x04, 0x03, + 0xc0, 0x21, 0x05, 0x04, 0xb0, 0x03, 0x06, 0x04, 0xa0, 0x1d, 0x07, 0x05, 0x80, 0x19, 0x09, 0x06, 0x6c, 0x00, 0x00, 0x02, 0x70, 0x00, 0x00, 0x02, 0x74, 0x00, 0x00, 0x02, 0x78, 0x00, 0x00, 0x02, + 0xe4, 0x2b, 0x01, 0x02, 0xe8, 0x2b, 0x01, 0x02, 0xec, 0x2b, 0x01, 0x02, 0xf0, 0x2b, 0x01, 0x02, 0xf4, 0x2b, 0x01, 0x02, 0xf8, 0x2b, 0x01, 0x02, 0x6c, 0x0a, 0x02, 0x02, 0x70, 0x0a, 0x02, 0x02, + 0x74, 0x0a, 0x02, 0x02, 0x78, 0x0a, 0x02, 0x02, 0x7c, 0x0a, 0x02, 0x02, 0xd0, 0x26, 0x03, 0x03, 0xd8, 0x26, 0x03, 0x03, 0xe0, 0x26, 0x03, 0x03, 0x00, 0x07, 0x04, 0x03, 0x08, 0x07, 0x04, 0x03, + 0xd0, 0x21, 0x05, 0x04, 0xc0, 0x03, 0x06, 0x04, 0xc0, 0x1d, 0x07, 0x05, 0xc0, 0x19, 0x09, 0x06, 0x7c, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x02, 0x84, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x02, + 0xfc, 0x2b, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x04, 0x2c, 0x01, 0x02, 0x08, 0x2c, 0x01, 0x02, 0x0c, 0x2c, 0x01, 0x02, 0x10, 0x2c, 0x01, 0x02, 0x80, 0x0a, 0x02, 0x02, 0x84, 0x0a, 0x02, 0x02, + 0x88, 0x0a, 0x02, 0x02, 0x8c, 0x0a, 0x02, 0x02, 0x90, 0x0a, 0x02, 0x02, 0xe8, 0x26, 0x03, 0x03, 0xf0, 0x26, 0x03, 0x03, 0xf8, 0x26, 0x03, 0x03, 0x10, 0x07, 0x04, 0x03, 0x18, 0x07, 0x04, 0x03, + 0xe0, 0x21, 0x05, 0x04, 0xd0, 0x03, 0x06, 0x04, 0xe0, 0x1d, 0x07, 0x05, 0x00, 0x1a, 0x09, 0x06, 0x8c, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, 0x94, 0x00, 0x00, 0x02, 0x98, 0x00, 0x00, 0x02, + 0x14, 0x2c, 0x01, 0x02, 0x18, 0x2c, 0x01, 0x02, 0x1c, 0x2c, 0x01, 0x02, 0x20, 0x2c, 0x01, 0x02, 0x24, 0x2c, 0x01, 0x02, 0x28, 0x2c, 0x01, 0x02, 0x94, 0x0a, 0x02, 0x02, 0x98, 0x0a, 0x02, 0x02, + 0x9c, 0x0a, 0x02, 0x02, 0xa0, 0x0a, 0x02, 0x02, 0xa4, 0x0a, 0x02, 0x02, 0x00, 0x27, 0x03, 0x03, 0x08, 0x27, 0x03, 0x03, 0x10, 0x27, 0x03, 0x03, 0x20, 0x07, 0x04, 0x03, 0x28, 0x07, 0x04, 0x03, + 0xf0, 0x21, 0x05, 0x04, 0xe0, 0x03, 0x06, 0x04, 0x00, 0x1e, 0x07, 0x05, 0x40, 0x1a, 0x09, 0x06, 0x9c, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x02, 0xa4, 0x00, 0x00, 0x02, 0xa8, 0x00, 0x00, 0x02, + 0x2c, 0x2c, 0x01, 0x02, 0x30, 0x2c, 0x01, 0x02, 0x34, 0x2c, 0x01, 0x02, 0x38, 0x2c, 0x01, 0x02, 0x3c, 0x2c, 0x01, 0x02, 0x40, 0x2c, 0x01, 0x02, 0xa8, 0x0a, 0x02, 0x02, 0xac, 0x0a, 0x02, 0x02, + 0xb0, 0x0a, 0x02, 0x02, 0xb4, 0x0a, 0x02, 0x02, 0xb8, 0x0a, 0x02, 0x02, 0x18, 0x27, 0x03, 0x03, 0x20, 0x27, 0x03, 0x03, 0x28, 0x27, 0x03, 0x03, 0x30, 0x07, 0x04, 0x03, 0x38, 0x07, 0x04, 0x03, + 0x00, 0x22, 0x05, 0x04, 0xf0, 0x03, 0x06, 0x04, 0x20, 0x1e, 0x07, 0x05, 0x80, 0x1a, 0x09, 0x06, 0xac, 0x00, 0x00, 0x02, 0xb0, 0x00, 0x00, 0x02, 0xb4, 0x00, 0x00, 0x02, 0xb8, 0x00, 0x00, 0x02, + 0x44, 0x2c, 0x01, 0x02, 0x48, 0x2c, 0x01, 0x02, 0x4c, 0x2c, 0x01, 0x02, 0x50, 0x2c, 0x01, 0x02, 0x54, 0x2c, 0x01, 0x02, 0x58, 0x2c, 0x01, 0x02, 0xbc, 0x0a, 0x02, 0x02, 0xc0, 0x0a, 0x02, 0x02, + 0xc4, 0x0a, 0x02, 0x02, 0xc8, 0x0a, 0x02, 0x02, 0xcc, 0x0a, 0x02, 0x02, 0x30, 0x27, 0x03, 0x03, 0x38, 0x27, 0x03, 0x03, 0x40, 0x27, 0x03, 0x03, 0x40, 0x07, 0x04, 0x03, 0x48, 0x07, 0x04, 0x03, + 0x10, 0x22, 0x05, 0x04, 0x00, 0x04, 0x06, 0x04, 0x40, 0x1e, 0x07, 0x05, 0xc0, 0x1a, 0x09, 0x06, 0xbc, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x02, 0xc8, 0x00, 0x00, 0x02, + 0x5c, 0x2c, 0x01, 0x02, 0x60, 0x2c, 0x01, 0x02, 0x64, 0x2c, 0x01, 0x02, 0x68, 0x2c, 0x01, 0x02, 0x6c, 0x2c, 0x01, 0x02, 0x70, 0x2c, 0x01, 0x02, 0xd0, 0x0a, 0x02, 0x02, 0xd4, 0x0a, 0x02, 0x02, + 0xd8, 0x0a, 0x02, 0x02, 0xdc, 0x0a, 0x02, 0x02, 0xe0, 0x0a, 0x02, 0x02, 0x48, 0x27, 0x03, 0x03, 0x50, 0x27, 0x03, 0x03, 0x58, 0x27, 0x03, 0x03, 0x50, 0x07, 0x04, 0x03, 0x58, 0x07, 0x04, 0x03, + 0x20, 0x22, 0x05, 0x04, 0x10, 0x04, 0x06, 0x04, 0x60, 0x1e, 0x07, 0x05, 0x00, 0x1b, 0x09, 0x06, 0xcc, 0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x02, 0xd4, 0x00, 0x00, 0x02, 0xd8, 0x00, 0x00, 0x02, + 0x74, 0x2c, 0x01, 0x02, 0x78, 0x2c, 0x01, 0x02, 0x7c, 0x2c, 0x01, 0x02, 0x80, 0x2c, 0x01, 0x02, 0x84, 0x2c, 0x01, 0x02, 0x88, 0x2c, 0x01, 0x02, 0xe4, 0x0a, 0x02, 0x02, 0xe8, 0x0a, 0x02, 0x02, + 0xec, 0x0a, 0x02, 0x02, 0xf0, 0x0a, 0x02, 0x02, 0xf4, 0x0a, 0x02, 0x02, 0x60, 0x27, 0x03, 0x03, 0x68, 0x27, 0x03, 0x03, 0x70, 0x27, 0x03, 0x03, 0x60, 0x07, 0x04, 0x03, 0x68, 0x07, 0x04, 0x03, + 0x30, 0x22, 0x05, 0x04, 0x20, 0x04, 0x06, 0x04, 0x80, 0x1e, 0x07, 0x05, 0x40, 0x1b, 0x09, 0x06, 0xdc, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, 0xe4, 0x00, 0x00, 0x02, 0xe8, 0x00, 0x00, 0x02, + 0x8c, 0x2c, 0x01, 0x02, 0x90, 0x2c, 0x01, 0x02, 0x94, 0x2c, 0x01, 0x02, 0x98, 0x2c, 0x01, 0x02, 0x9c, 0x2c, 0x01, 0x02, 0xa0, 0x2c, 0x01, 0x02, 0xf8, 0x0a, 0x02, 0x02, 0xfc, 0x0a, 0x02, 0x02, + 0x00, 0x0b, 0x02, 0x02, 0x04, 0x0b, 0x02, 0x02, 0x08, 0x0b, 0x02, 0x02, 0x78, 0x27, 0x03, 0x03, 0x80, 0x27, 0x03, 0x03, 0x88, 0x27, 0x03, 0x03, 0x70, 0x07, 0x04, 0x03, 0x78, 0x07, 0x04, 0x03, + 0x40, 0x22, 0x05, 0x04, 0x30, 0x04, 0x06, 0x04, 0xa0, 0x1e, 0x07, 0x05, 0x80, 0x1b, 0x09, 0x06, 0xec, 0x00, 0x00, 0x02, 0xf0, 0x00, 0x00, 0x02, 0xf4, 0x00, 0x00, 0x02, 0xf8, 0x00, 0x00, 0x02, + 0xa4, 0x2c, 0x01, 0x02, 0xa8, 0x2c, 0x01, 0x02, 0xac, 0x2c, 0x01, 0x02, 0xb0, 0x2c, 0x01, 0x02, 0xb4, 0x2c, 0x01, 0x02, 0xb8, 0x2c, 0x01, 0x02, 0x0c, 0x0b, 0x02, 0x02, 0x10, 0x0b, 0x02, 0x02, + 0x14, 0x0b, 0x02, 0x02, 0x18, 0x0b, 0x02, 0x02, 0x1c, 0x0b, 0x02, 0x02, 0x90, 0x27, 0x03, 0x03, 0x98, 0x27, 0x03, 0x03, 0xa0, 0x27, 0x03, 0x03, 0x80, 0x07, 0x04, 0x03, 0x88, 0x07, 0x04, 0x03, + 0x50, 0x22, 0x05, 0x04, 0x40, 0x04, 0x06, 0x04, 0xc0, 0x1e, 0x07, 0x05, 0xc0, 0x1b, 0x09, 0x06, 0xfc, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02, 0x08, 0x01, 0x00, 0x02, + 0xbc, 0x2c, 0x01, 0x02, 0xc0, 0x2c, 0x01, 0x02, 0xc4, 0x2c, 0x01, 0x02, 0xc8, 0x2c, 0x01, 0x02, 0xcc, 0x2c, 0x01, 0x02, 0xd0, 0x2c, 0x01, 0x02, 0x20, 0x0b, 0x02, 0x02, 0x24, 0x0b, 0x02, 0x02, + 0x28, 0x0b, 0x02, 0x02, 0x2c, 0x0b, 0x02, 0x02, 0x30, 0x0b, 0x02, 0x02, 0xa8, 0x27, 0x03, 0x03, 0xb0, 0x27, 0x03, 0x03, 0xb8, 0x27, 0x03, 0x03, 0x90, 0x07, 0x04, 0x03, 0x98, 0x07, 0x04, 0x03, + 0x60, 0x22, 0x05, 0x04, 0x50, 0x04, 0x06, 0x04, 0xe0, 0x1e, 0x07, 0x05, 0x00, 0x1c, 0x09, 0x06, 0x0c, 0x01, 0x00, 0x02, 0x10, 0x01, 0x00, 0x02, 0x14, 0x01, 0x00, 0x02, 0x18, 0x01, 0x00, 0x02, + 0xd4, 0x2c, 0x01, 0x02, 0xd8, 0x2c, 0x01, 0x02, 0xdc, 0x2c, 0x01, 0x02, 0xe0, 0x2c, 0x01, 0x02, 0xe4, 0x2c, 0x01, 0x02, 0xe8, 0x2c, 0x01, 0x02, 0x34, 0x0b, 0x02, 0x02, 0x38, 0x0b, 0x02, 0x02, + 0x3c, 0x0b, 0x02, 0x02, 0x40, 0x0b, 0x02, 0x02, 0x44, 0x0b, 0x02, 0x02, 0xc0, 0x27, 0x03, 0x03, 0xc8, 0x27, 0x03, 0x03, 0xd0, 0x27, 0x03, 0x03, 0xa0, 0x07, 0x04, 0x03, 0xa8, 0x07, 0x04, 0x03, + 0x70, 0x22, 0x05, 0x04, 0x60, 0x04, 0x06, 0x04, 0x00, 0x1f, 0x07, 0x05, 0x40, 0x1c, 0x09, 0x06, 0x1c, 0x01, 0x00, 0x02, 0x20, 0x01, 0x00, 0x02, 0x24, 0x01, 0x00, 0x02, 0x28, 0x01, 0x00, 0x02, + 0xec, 0x2c, 0x01, 0x02, 0xf0, 0x2c, 0x01, 0x02, 0xf4, 0x2c, 0x01, 0x02, 0xf8, 0x2c, 0x01, 0x02, 0xfc, 0x2c, 0x01, 0x02, 0x00, 0x2d, 0x01, 0x02, 0x48, 0x0b, 0x02, 0x02, 0x4c, 0x0b, 0x02, 0x02, + 0x50, 0x0b, 0x02, 0x02, 0x54, 0x0b, 0x02, 0x02, 0x58, 0x0b, 0x02, 0x02, 0xd8, 0x27, 0x03, 0x03, 0xe0, 0x27, 0x03, 0x03, 0xe8, 0x27, 0x03, 0x03, 0xb0, 0x07, 0x04, 0x03, 0xb8, 0x07, 0x04, 0x03, + 0x80, 0x22, 0x05, 0x04, 0x70, 0x04, 0x06, 0x04, 0x20, 0x1f, 0x07, 0x05, 0x80, 0x1c, 0x09, 0x06, 0x2c, 0x01, 0x00, 0x02, 0x30, 0x01, 0x00, 0x02, 0x34, 0x01, 0x00, 0x02, 0x38, 0x01, 0x00, 0x02, + 0x04, 0x2d, 0x01, 0x02, 0x08, 0x2d, 0x01, 0x02, 0x0c, 0x2d, 0x01, 0x02, 0x10, 0x2d, 0x01, 0x02, 0x14, 0x2d, 0x01, 0x02, 0x18, 0x2d, 0x01, 0x02, 0x5c, 0x0b, 0x02, 0x02, 0x60, 0x0b, 0x02, 0x02, + 0x64, 0x0b, 0x02, 0x02, 0x68, 0x0b, 0x02, 0x02, 0x6c, 0x0b, 0x02, 0x02, 0xf0, 0x27, 0x03, 0x03, 0xf8, 0x27, 0x03, 0x03, 0x00, 0x28, 0x03, 0x03, 0xc0, 0x07, 0x04, 0x03, 0xc8, 0x07, 0x04, 0x03, + 0x90, 0x22, 0x05, 0x04, 0x80, 0x04, 0x06, 0x04, 0x40, 0x1f, 0x07, 0x05, 0xc0, 0x1c, 0x09, 0x06, 0x3c, 0x01, 0x00, 0x02, 0x40, 0x01, 0x00, 0x02, 0x44, 0x01, 0x00, 0x02, 0x48, 0x01, 0x00, 0x02, + 0x1c, 0x2d, 0x01, 0x02, 0x20, 0x2d, 0x01, 0x02, 0x24, 0x2d, 0x01, 0x02, 0x28, 0x2d, 0x01, 0x02, 0x2c, 0x2d, 0x01, 0x02, 0x30, 0x2d, 0x01, 0x02, 0x70, 0x0b, 0x02, 0x02, 0x74, 0x0b, 0x02, 0x02, + 0x78, 0x0b, 0x02, 0x02, 0x7c, 0x0b, 0x02, 0x02, 0x80, 0x0b, 0x02, 0x02, 0x08, 0x28, 0x03, 0x03, 0x10, 0x28, 0x03, 0x03, 0x18, 0x28, 0x03, 0x03, 0xd0, 0x07, 0x04, 0x03, 0xd8, 0x07, 0x04, 0x03, + 0xa0, 0x22, 0x05, 0x04, 0x90, 0x04, 0x06, 0x04, 0x60, 0x1f, 0x07, 0x05, 0x00, 0x1d, 0x09, 0x06, 0x4c, 0x01, 0x00, 0x02, 0x50, 0x01, 0x00, 0x02, 0x54, 0x01, 0x00, 0x02, 0x58, 0x01, 0x00, 0x02, + 0x34, 0x2d, 0x01, 0x02, 0x38, 0x2d, 0x01, 0x02, 0x3c, 0x2d, 0x01, 0x02, 0x40, 0x2d, 0x01, 0x02, 0x44, 0x2d, 0x01, 0x02, 0x48, 0x2d, 0x01, 0x02, 0x84, 0x0b, 0x02, 0x02, 0x88, 0x0b, 0x02, 0x02, + 0x8c, 0x0b, 0x02, 0x02, 0x90, 0x0b, 0x02, 0x02, 0x94, 0x0b, 0x02, 0x02, 0x20, 0x28, 0x03, 0x03, 0x28, 0x28, 0x03, 0x03, 0x30, 0x28, 0x03, 0x03, 0xe0, 0x07, 0x04, 0x03, 0xe8, 0x07, 0x04, 0x03, + 0xb0, 0x22, 0x05, 0x04, 0xa0, 0x04, 0x06, 0x04, 0x80, 0x1f, 0x07, 0x05, 0x40, 0x1d, 0x09, 0x06, 0x5c, 0x01, 0x00, 0x02, 0x60, 0x01, 0x00, 0x02, 0x64, 0x01, 0x00, 0x02, 0x68, 0x01, 0x00, 0x02, + 0x4c, 0x2d, 0x01, 0x02, 0x50, 0x2d, 0x01, 0x02, 0x54, 0x2d, 0x01, 0x02, 0x58, 0x2d, 0x01, 0x02, 0x5c, 0x2d, 0x01, 0x02, 0x60, 0x2d, 0x01, 0x02, 0x98, 0x0b, 0x02, 0x02, 0x9c, 0x0b, 0x02, 0x02, + 0xa0, 0x0b, 0x02, 0x02, 0xa4, 0x0b, 0x02, 0x02, 0xa8, 0x0b, 0x02, 0x02, 0x38, 0x28, 0x03, 0x03, 0x40, 0x28, 0x03, 0x03, 0x48, 0x28, 0x03, 0x03, 0xf0, 0x07, 0x04, 0x03, 0xf8, 0x07, 0x04, 0x03, + 0xc0, 0x22, 0x05, 0x04, 0xb0, 0x04, 0x06, 0x04, 0xa0, 0x1f, 0x07, 0x05, 0x80, 0x1d, 0x09, 0x06, 0x6c, 0x01, 0x00, 0x02, 0x70, 0x01, 0x00, 0x02, 0x74, 0x01, 0x00, 0x02, 0x78, 0x01, 0x00, 0x02, + 0x64, 0x2d, 0x01, 0x02, 0x68, 0x2d, 0x01, 0x02, 0x6c, 0x2d, 0x01, 0x02, 0x70, 0x2d, 0x01, 0x02, 0x74, 0x2d, 0x01, 0x02, 0x78, 0x2d, 0x01, 0x02, 0xac, 0x0b, 0x02, 0x02, 0xb0, 0x0b, 0x02, 0x02, + 0xb4, 0x0b, 0x02, 0x02, 0xb8, 0x0b, 0x02, 0x02, 0xbc, 0x0b, 0x02, 0x02, 0x50, 0x28, 0x03, 0x03, 0x58, 0x28, 0x03, 0x03, 0x60, 0x28, 0x03, 0x03, 0x00, 0x08, 0x04, 0x03, 0x08, 0x08, 0x04, 0x03, + 0xd0, 0x22, 0x05, 0x04, 0xc0, 0x04, 0x06, 0x04, 0xc0, 0x1f, 0x07, 0x05, 0xc0, 0x1d, 0x09, 0x06, 0x7c, 0x01, 0x00, 0x02, 0x80, 0x01, 0x00, 0x02, 0x84, 0x01, 0x00, 0x02, 0x88, 0x01, 0x00, 0x02, + 0x7c, 0x2d, 0x01, 0x02, 0x80, 0x2d, 0x01, 0x02, 0x84, 0x2d, 0x01, 0x02, 0x88, 0x2d, 0x01, 0x02, 0x8c, 0x2d, 0x01, 0x02, 0x90, 0x2d, 0x01, 0x02, 0xc0, 0x0b, 0x02, 0x02, 0xc4, 0x0b, 0x02, 0x02, + 0xc8, 0x0b, 0x02, 0x02, 0xcc, 0x0b, 0x02, 0x02, 0xd0, 0x0b, 0x02, 0x02, 0x68, 0x28, 0x03, 0x03, 0x70, 0x28, 0x03, 0x03, 0x78, 0x28, 0x03, 0x03, 0x10, 0x08, 0x04, 0x03, 0x18, 0x08, 0x04, 0x03, + 0xe0, 0x22, 0x05, 0x04, 0xd0, 0x04, 0x06, 0x04, 0xe0, 0x1f, 0x07, 0x05, 0x00, 0x1e, 0x09, 0x06, 0x8c, 0x01, 0x00, 0x02, 0x90, 0x01, 0x00, 0x02, 0x94, 0x01, 0x00, 0x02, 0x98, 0x01, 0x00, 0x02, + 0x94, 0x2d, 0x01, 0x02, 0x98, 0x2d, 0x01, 0x02, 0x9c, 0x2d, 0x01, 0x02, 0xa0, 0x2d, 0x01, 0x02, 0xa4, 0x2d, 0x01, 0x02, 0xa8, 0x2d, 0x01, 0x02, 0xd4, 0x0b, 0x02, 0x02, 0xd8, 0x0b, 0x02, 0x02, + 0xdc, 0x0b, 0x02, 0x02, 0xe0, 0x0b, 0x02, 0x02, 0xe4, 0x0b, 0x02, 0x02, 0x80, 0x28, 0x03, 0x03, 0x88, 0x28, 0x03, 0x03, 0x90, 0x28, 0x03, 0x03, 0x20, 0x08, 0x04, 0x03, 0x28, 0x08, 0x04, 0x03, + 0xf0, 0x22, 0x05, 0x04, 0xe0, 0x04, 0x06, 0x04, 0x00, 0x20, 0x07, 0x05, 0x40, 0x1e, 0x09, 0x06, 0x9c, 0x01, 0x00, 0x02, 0xa0, 0x01, 0x00, 0x02, 0xa4, 0x01, 0x00, 0x02, 0xa8, 0x01, 0x00, 0x02, + 0xac, 0x2d, 0x01, 0x02, 0xb0, 0x2d, 0x01, 0x02, 0xb4, 0x2d, 0x01, 0x02, 0xb8, 0x2d, 0x01, 0x02, 0xbc, 0x2d, 0x01, 0x02, 0xc0, 0x2d, 0x01, 0x02, 0xe8, 0x0b, 0x02, 0x02, 0xec, 0x0b, 0x02, 0x02, + 0xf0, 0x0b, 0x02, 0x02, 0xf4, 0x0b, 0x02, 0x02, 0xf8, 0x0b, 0x02, 0x02, 0x98, 0x28, 0x03, 0x03, 0xa0, 0x28, 0x03, 0x03, 0xa8, 0x28, 0x03, 0x03, 0x30, 0x08, 0x04, 0x03, 0x38, 0x08, 0x04, 0x03, + 0x00, 0x23, 0x05, 0x04, 0xf0, 0x04, 0x06, 0x04, 0x20, 0x20, 0x07, 0x05, 0x80, 0x1e, 0x09, 0x06, 0xac, 0x01, 0x00, 0x02, 0xb0, 0x01, 0x00, 0x02, 0xb4, 0x01, 0x00, 0x02, 0xb8, 0x01, 0x00, 0x02, + 0xc4, 0x2d, 0x01, 0x02, 0xc8, 0x2d, 0x01, 0x02, 0xcc, 0x2d, 0x01, 0x02, 0xd0, 0x2d, 0x01, 0x02, 0xd4, 0x2d, 0x01, 0x02, 0xd8, 0x2d, 0x01, 0x02, 0xfc, 0x0b, 0x02, 0x02, 0x00, 0x0c, 0x02, 0x02, + 0x04, 0x0c, 0x02, 0x02, 0x08, 0x0c, 0x02, 0x02, 0x0c, 0x0c, 0x02, 0x02, 0xb0, 0x28, 0x03, 0x03, 0xb8, 0x28, 0x03, 0x03, 0xc0, 0x28, 0x03, 0x03, 0x40, 0x08, 0x04, 0x03, 0x48, 0x08, 0x04, 0x03, + 0x10, 0x23, 0x05, 0x04, 0x00, 0x05, 0x06, 0x04, 0x40, 0x20, 0x07, 0x05, 0xc0, 0x1e, 0x09, 0x06, 0xbc, 0x01, 0x00, 0x02, 0xc0, 0x01, 0x00, 0x02, 0xc4, 0x01, 0x00, 0x02, 0xc8, 0x01, 0x00, 0x02, + 0xdc, 0x2d, 0x01, 0x02, 0xe0, 0x2d, 0x01, 0x02, 0xe4, 0x2d, 0x01, 0x02, 0xe8, 0x2d, 0x01, 0x02, 0xec, 0x2d, 0x01, 0x02, 0xf0, 0x2d, 0x01, 0x02, 0x10, 0x0c, 0x02, 0x02, 0x14, 0x0c, 0x02, 0x02, + 0x18, 0x0c, 0x02, 0x02, 0x1c, 0x0c, 0x02, 0x02, 0x20, 0x0c, 0x02, 0x02, 0xc8, 0x28, 0x03, 0x03, 0xd0, 0x28, 0x03, 0x03, 0xd8, 0x28, 0x03, 0x03, 0x50, 0x08, 0x04, 0x03, 0x58, 0x08, 0x04, 0x03, + 0x20, 0x23, 0x05, 0x04, 0x10, 0x05, 0x06, 0x04, 0x60, 0x20, 0x07, 0x05, 0x00, 0x1f, 0x09, 0x06, 0xcc, 0x01, 0x00, 0x02, 0xd0, 0x01, 0x00, 0x02, 0xd4, 0x01, 0x00, 0x02, 0xd8, 0x01, 0x00, 0x02, + 0xf4, 0x2d, 0x01, 0x02, 0xf8, 0x2d, 0x01, 0x02, 0xfc, 0x2d, 0x01, 0x02, 0x00, 0x2e, 0x01, 0x02, 0x04, 0x2e, 0x01, 0x02, 0x08, 0x2e, 0x01, 0x02, 0x24, 0x0c, 0x02, 0x02, 0x28, 0x0c, 0x02, 0x02, + 0x2c, 0x0c, 0x02, 0x02, 0x30, 0x0c, 0x02, 0x02, 0x34, 0x0c, 0x02, 0x02, 0xe0, 0x28, 0x03, 0x03, 0xe8, 0x28, 0x03, 0x03, 0xf0, 0x28, 0x03, 0x03, 0x60, 0x08, 0x04, 0x03, 0x68, 0x08, 0x04, 0x03, + 0x30, 0x23, 0x05, 0x04, 0x20, 0x05, 0x06, 0x04, 0x80, 0x20, 0x07, 0x05, 0x80, 0x3a, 0x0a, 0x07, 0xdc, 0x01, 0x00, 0x02, 0xe0, 0x01, 0x00, 0x02, 0xe4, 0x01, 0x00, 0x02, 0xe8, 0x01, 0x00, 0x02, + 0x0c, 0x2e, 0x01, 0x02, 0x10, 0x2e, 0x01, 0x02, 0x14, 0x2e, 0x01, 0x02, 0x18, 0x2e, 0x01, 0x02, 0x1c, 0x2e, 0x01, 0x02, 0x20, 0x2e, 0x01, 0x02, 0x38, 0x0c, 0x02, 0x02, 0x3c, 0x0c, 0x02, 0x02, + 0x40, 0x0c, 0x02, 0x02, 0x44, 0x0c, 0x02, 0x02, 0x48, 0x0c, 0x02, 0x02, 0xf8, 0x28, 0x03, 0x03, 0x00, 0x29, 0x03, 0x03, 0x08, 0x29, 0x03, 0x03, 0x70, 0x08, 0x04, 0x03, 0x78, 0x08, 0x04, 0x03, + 0x40, 0x23, 0x05, 0x04, 0x30, 0x05, 0x06, 0x04, 0xa0, 0x20, 0x07, 0x05, 0x00, 0x3b, 0x0a, 0x07, 0xec, 0x01, 0x00, 0x02, 0xf0, 0x01, 0x00, 0x02, 0xf4, 0x01, 0x00, 0x02, 0xf8, 0x01, 0x00, 0x02, + 0x24, 0x2e, 0x01, 0x02, 0x28, 0x2e, 0x01, 0x02, 0x2c, 0x2e, 0x01, 0x02, 0x30, 0x2e, 0x01, 0x02, 0x34, 0x2e, 0x01, 0x02, 0x38, 0x2e, 0x01, 0x02, 0x4c, 0x0c, 0x02, 0x02, 0x50, 0x0c, 0x02, 0x02, + 0x54, 0x0c, 0x02, 0x02, 0x58, 0x0c, 0x02, 0x02, 0x5c, 0x0c, 0x02, 0x02, 0x10, 0x29, 0x03, 0x03, 0x18, 0x29, 0x03, 0x03, 0x20, 0x29, 0x03, 0x03, 0x80, 0x08, 0x04, 0x03, 0x88, 0x08, 0x04, 0x03, + 0x50, 0x23, 0x05, 0x04, 0x40, 0x05, 0x06, 0x04, 0xc0, 0x20, 0x07, 0x05, 0x80, 0x3b, 0x0a, 0x07, 0xfc, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x04, 0x02, 0x00, 0x02, 0x08, 0x02, 0x00, 0x02, + 0x3c, 0x2e, 0x01, 0x02, 0x40, 0x2e, 0x01, 0x02, 0x44, 0x2e, 0x01, 0x02, 0x48, 0x2e, 0x01, 0x02, 0x4c, 0x2e, 0x01, 0x02, 0x50, 0x2e, 0x01, 0x02, 0x60, 0x0c, 0x02, 0x02, 0x64, 0x0c, 0x02, 0x02, + 0x68, 0x0c, 0x02, 0x02, 0x6c, 0x0c, 0x02, 0x02, 0x70, 0x0c, 0x02, 0x02, 0x28, 0x29, 0x03, 0x03, 0x30, 0x29, 0x03, 0x03, 0x38, 0x29, 0x03, 0x03, 0x90, 0x08, 0x04, 0x03, 0x98, 0x08, 0x04, 0x03, + 0x60, 0x23, 0x05, 0x04, 0x50, 0x05, 0x06, 0x04, 0xe0, 0x20, 0x07, 0x05, 0x00, 0x3c, 0x0a, 0x07, 0x0c, 0x02, 0x00, 0x02, 0x10, 0x02, 0x00, 0x02, 0x14, 0x02, 0x00, 0x02, 0x18, 0x02, 0x00, 0x02, + 0x54, 0x2e, 0x01, 0x02, 0x58, 0x2e, 0x01, 0x02, 0x5c, 0x2e, 0x01, 0x02, 0x60, 0x2e, 0x01, 0x02, 0x64, 0x2e, 0x01, 0x02, 0x68, 0x2e, 0x01, 0x02, 0x74, 0x0c, 0x02, 0x02, 0x78, 0x0c, 0x02, 0x02, + 0x7c, 0x0c, 0x02, 0x02, 0x80, 0x0c, 0x02, 0x02, 0x84, 0x0c, 0x02, 0x02, 0x40, 0x29, 0x03, 0x03, 0x48, 0x29, 0x03, 0x03, 0x50, 0x29, 0x03, 0x03, 0xa0, 0x08, 0x04, 0x03, 0xa8, 0x08, 0x04, 0x03, + 0x70, 0x23, 0x05, 0x04, 0x60, 0x05, 0x06, 0x04, 0x00, 0x21, 0x07, 0x05, 0x80, 0x3c, 0x0a, 0x07, 0x1c, 0x02, 0x00, 0x02, 0x20, 0x02, 0x00, 0x02, 0x24, 0x02, 0x00, 0x02, 0x28, 0x02, 0x00, 0x02, + 0x6c, 0x2e, 0x01, 0x02, 0x70, 0x2e, 0x01, 0x02, 0x74, 0x2e, 0x01, 0x02, 0x78, 0x2e, 0x01, 0x02, 0x7c, 0x2e, 0x01, 0x02, 0x80, 0x2e, 0x01, 0x02, 0x88, 0x0c, 0x02, 0x02, 0x8c, 0x0c, 0x02, 0x02, + 0x90, 0x0c, 0x02, 0x02, 0x94, 0x0c, 0x02, 0x02, 0x98, 0x0c, 0x02, 0x02, 0x58, 0x29, 0x03, 0x03, 0x60, 0x29, 0x03, 0x03, 0xb0, 0x08, 0x04, 0x03, 0xb8, 0x08, 0x04, 0x03, 0xc0, 0x08, 0x04, 0x03, + 0x80, 0x23, 0x05, 0x04, 0x70, 0x05, 0x06, 0x04, 0x20, 0x21, 0x07, 0x05, 0x00, 0x3d, 0x0a, 0x07, 0x2c, 0x02, 0x00, 0x02, 0x30, 0x02, 0x00, 0x02, 0x34, 0x02, 0x00, 0x02, 0x38, 0x02, 0x00, 0x02, + 0x84, 0x2e, 0x01, 0x02, 0x88, 0x2e, 0x01, 0x02, 0x8c, 0x2e, 0x01, 0x02, 0x90, 0x2e, 0x01, 0x02, 0x94, 0x2e, 0x01, 0x02, 0x98, 0x2e, 0x01, 0x02, 0x9c, 0x0c, 0x02, 0x02, 0xa0, 0x0c, 0x02, 0x02, + 0xa4, 0x0c, 0x02, 0x02, 0xa8, 0x0c, 0x02, 0x02, 0x68, 0x29, 0x03, 0x03, 0x70, 0x29, 0x03, 0x03, 0x78, 0x29, 0x03, 0x03, 0xc8, 0x08, 0x04, 0x03, 0xd0, 0x08, 0x04, 0x03, 0xd8, 0x08, 0x04, 0x03, + 0x90, 0x23, 0x05, 0x04, 0x80, 0x05, 0x06, 0x04, 0x40, 0x21, 0x07, 0x05, 0x80, 0x3d, 0x0a, 0x07, 0x3c, 0x02, 0x00, 0x02, 0x40, 0x02, 0x00, 0x02, 0x44, 0x02, 0x00, 0x02, 0x48, 0x02, 0x00, 0x02, + 0x9c, 0x2e, 0x01, 0x02, 0xa0, 0x2e, 0x01, 0x02, 0xa4, 0x2e, 0x01, 0x02, 0xa8, 0x2e, 0x01, 0x02, 0xac, 0x2e, 0x01, 0x02, 0xb0, 0x2e, 0x01, 0x02, 0xac, 0x0c, 0x02, 0x02, 0xb0, 0x0c, 0x02, 0x02, + 0xb4, 0x0c, 0x02, 0x02, 0xb8, 0x0c, 0x02, 0x02, 0x80, 0x29, 0x03, 0x03, 0x88, 0x29, 0x03, 0x03, 0x90, 0x29, 0x03, 0x03, 0xe0, 0x08, 0x04, 0x03, 0xe8, 0x08, 0x04, 0x03, 0xf0, 0x08, 0x04, 0x03, + 0xa0, 0x23, 0x05, 0x04, 0x90, 0x05, 0x06, 0x04, 0x60, 0x21, 0x07, 0x05, 0x00, 0x3e, 0x0a, 0x07, 0x4c, 0x02, 0x00, 0x02, 0x50, 0x02, 0x00, 0x02, 0x54, 0x02, 0x00, 0x02, 0x58, 0x02, 0x00, 0x02, + 0xb4, 0x2e, 0x01, 0x02, 0xb8, 0x2e, 0x01, 0x02, 0xbc, 0x2e, 0x01, 0x02, 0xc0, 0x2e, 0x01, 0x02, 0xc4, 0x2e, 0x01, 0x02, 0xc8, 0x2e, 0x01, 0x02, 0xbc, 0x0c, 0x02, 0x02, 0xc0, 0x0c, 0x02, 0x02, + 0xc4, 0x0c, 0x02, 0x02, 0xc8, 0x0c, 0x02, 0x02, 0x98, 0x29, 0x03, 0x03, 0xa0, 0x29, 0x03, 0x03, 0xa8, 0x29, 0x03, 0x03, 0xf8, 0x08, 0x04, 0x03, 0x00, 0x09, 0x04, 0x03, 0x08, 0x09, 0x04, 0x03, + 0xb0, 0x23, 0x05, 0x04, 0xa0, 0x05, 0x06, 0x04, 0x80, 0x21, 0x07, 0x05, 0x80, 0x3e, 0x0a, 0x07, 0x5c, 0x02, 0x00, 0x02, 0x60, 0x02, 0x00, 0x02, 0x64, 0x02, 0x00, 0x02, 0x68, 0x02, 0x00, 0x02, + 0xcc, 0x2e, 0x01, 0x02, 0xd0, 0x2e, 0x01, 0x02, 0xd4, 0x2e, 0x01, 0x02, 0xd8, 0x2e, 0x01, 0x02, 0xdc, 0x2e, 0x01, 0x02, 0xe0, 0x2e, 0x01, 0x02, 0xcc, 0x0c, 0x02, 0x02, 0xd0, 0x0c, 0x02, 0x02, + 0xd4, 0x0c, 0x02, 0x02, 0xd8, 0x0c, 0x02, 0x02, 0xb0, 0x29, 0x03, 0x03, 0xb8, 0x29, 0x03, 0x03, 0xc0, 0x29, 0x03, 0x03, 0x10, 0x09, 0x04, 0x03, 0x18, 0x09, 0x04, 0x03, 0x20, 0x09, 0x04, 0x03, + 0xc0, 0x23, 0x05, 0x04, 0xb0, 0x05, 0x06, 0x04, 0xa0, 0x21, 0x07, 0x05, 0x00, 0x3f, 0x0a, 0x07, 0x6c, 0x02, 0x00, 0x02, 0x70, 0x02, 0x00, 0x02, 0x74, 0x02, 0x00, 0x02, 0x78, 0x02, 0x00, 0x02, + 0xe4, 0x2e, 0x01, 0x02, 0xe8, 0x2e, 0x01, 0x02, 0xec, 0x2e, 0x01, 0x02, 0xf0, 0x2e, 0x01, 0x02, 0xf4, 0x2e, 0x01, 0x02, 0xf8, 0x2e, 0x01, 0x02, 0xdc, 0x0c, 0x02, 0x02, 0xe0, 0x0c, 0x02, 0x02, + 0xe4, 0x0c, 0x02, 0x02, 0xe8, 0x0c, 0x02, 0x02, 0xc8, 0x29, 0x03, 0x03, 0xd0, 0x29, 0x03, 0x03, 0xd8, 0x29, 0x03, 0x03, 0x28, 0x09, 0x04, 0x03, 0x30, 0x09, 0x04, 0x03, 0xd0, 0x23, 0x05, 0x04, + 0xe0, 0x23, 0x05, 0x04, 0xc0, 0x05, 0x06, 0x04, 0xc0, 0x21, 0x07, 0x05, 0x80, 0x3f, 0x0a, 0x07, 0x7c, 0x02, 0x00, 0x02, 0x80, 0x02, 0x00, 0x02, 0x84, 0x02, 0x00, 0x02, 0x88, 0x02, 0x00, 0x02, + 0xfc, 0x2e, 0x01, 0x02, 0x00, 0x2f, 0x01, 0x02, 0x04, 0x2f, 0x01, 0x02, 0x08, 0x2f, 0x01, 0x02, 0x0c, 0x2f, 0x01, 0x02, 0x10, 0x2f, 0x01, 0x02, 0xec, 0x0c, 0x02, 0x02, 0xf0, 0x0c, 0x02, 0x02, + 0xf4, 0x0c, 0x02, 0x02, 0xf8, 0x0c, 0x02, 0x02, 0xe0, 0x29, 0x03, 0x03, 0xe8, 0x29, 0x03, 0x03, 0xf0, 0x29, 0x03, 0x03, 0x38, 0x09, 0x04, 0x03, 0x40, 0x09, 0x04, 0x03, 0xf0, 0x23, 0x05, 0x04, + 0x00, 0x24, 0x05, 0x04, 0xd0, 0x05, 0x06, 0x04, 0xe0, 0x21, 0x07, 0x05, 0x00, 0x00, 0x0a, 0x06, 0x8c, 0x02, 0x00, 0x02, 0x90, 0x02, 0x00, 0x02, 0x94, 0x02, 0x00, 0x02, 0x98, 0x02, 0x00, 0x02, + 0x14, 0x2f, 0x01, 0x02, 0x18, 0x2f, 0x01, 0x02, 0x1c, 0x2f, 0x01, 0x02, 0x20, 0x2f, 0x01, 0x02, 0x24, 0x2f, 0x01, 0x02, 0x28, 0x2f, 0x01, 0x02, 0xfc, 0x0c, 0x02, 0x02, 0x00, 0x0d, 0x02, 0x02, + 0x04, 0x0d, 0x02, 0x02, 0x08, 0x0d, 0x02, 0x02, 0xf8, 0x29, 0x03, 0x03, 0x00, 0x2a, 0x03, 0x03, 0x08, 0x2a, 0x03, 0x03, 0x48, 0x09, 0x04, 0x03, 0x50, 0x09, 0x04, 0x03, 0x10, 0x24, 0x05, 0x04, + 0x20, 0x24, 0x05, 0x04, 0xe0, 0x05, 0x06, 0x04, 0x00, 0x22, 0x07, 0x05, 0x40, 0x00, 0x0a, 0x06, 0x9c, 0x02, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x02, 0xa4, 0x02, 0x00, 0x02, 0xa8, 0x02, 0x00, 0x02, + 0x2c, 0x2f, 0x01, 0x02, 0x30, 0x2f, 0x01, 0x02, 0x34, 0x2f, 0x01, 0x02, 0x38, 0x2f, 0x01, 0x02, 0x3c, 0x2f, 0x01, 0x02, 0x40, 0x2f, 0x01, 0x02, 0x0c, 0x0d, 0x02, 0x02, 0x10, 0x0d, 0x02, 0x02, + 0x14, 0x0d, 0x02, 0x02, 0x18, 0x0d, 0x02, 0x02, 0x10, 0x2a, 0x03, 0x03, 0x18, 0x2a, 0x03, 0x03, 0x20, 0x2a, 0x03, 0x03, 0x58, 0x09, 0x04, 0x03, 0x60, 0x09, 0x04, 0x03, 0x30, 0x24, 0x05, 0x04, + 0x40, 0x24, 0x05, 0x04, 0xf0, 0x05, 0x06, 0x04, 0x20, 0x22, 0x07, 0x05, 0x80, 0x00, 0x0a, 0x06, 0xac, 0x02, 0x00, 0x02, 0xb0, 0x02, 0x00, 0x02, 0xb4, 0x02, 0x00, 0x02, 0xb8, 0x02, 0x00, 0x02, + 0x44, 0x2f, 0x01, 0x02, 0x48, 0x2f, 0x01, 0x02, 0x4c, 0x2f, 0x01, 0x02, 0x50, 0x2f, 0x01, 0x02, 0x54, 0x2f, 0x01, 0x02, 0x58, 0x2f, 0x01, 0x02, 0x1c, 0x0d, 0x02, 0x02, 0x20, 0x0d, 0x02, 0x02, + 0x24, 0x0d, 0x02, 0x02, 0x28, 0x0d, 0x02, 0x02, 0x28, 0x2a, 0x03, 0x03, 0x30, 0x2a, 0x03, 0x03, 0x38, 0x2a, 0x03, 0x03, 0x68, 0x09, 0x04, 0x03, 0x70, 0x09, 0x04, 0x03, 0x50, 0x24, 0x05, 0x04, + 0x60, 0x24, 0x05, 0x04, 0x00, 0x06, 0x06, 0x04, 0x40, 0x22, 0x07, 0x05, 0xc0, 0x00, 0x0a, 0x06, 0xbc, 0x02, 0x00, 0x02, 0xc0, 0x02, 0x00, 0x02, 0xc4, 0x02, 0x00, 0x02, 0xc8, 0x02, 0x00, 0x02, + 0x5c, 0x2f, 0x01, 0x02, 0x60, 0x2f, 0x01, 0x02, 0x64, 0x2f, 0x01, 0x02, 0x68, 0x2f, 0x01, 0x02, 0x6c, 0x2f, 0x01, 0x02, 0x70, 0x2f, 0x01, 0x02, 0x2c, 0x0d, 0x02, 0x02, 0x30, 0x0d, 0x02, 0x02, + 0x34, 0x0d, 0x02, 0x02, 0x38, 0x0d, 0x02, 0x02, 0x40, 0x2a, 0x03, 0x03, 0x48, 0x2a, 0x03, 0x03, 0x50, 0x2a, 0x03, 0x03, 0x78, 0x09, 0x04, 0x03, 0x80, 0x09, 0x04, 0x03, 0x70, 0x24, 0x05, 0x04, + 0x80, 0x24, 0x05, 0x04, 0x10, 0x06, 0x06, 0x04, 0x60, 0x22, 0x07, 0x05, 0x00, 0x01, 0x0a, 0x06, 0xcc, 0x02, 0x00, 0x02, 0xd0, 0x02, 0x00, 0x02, 0xd4, 0x02, 0x00, 0x02, 0xd8, 0x02, 0x00, 0x02, + 0x74, 0x2f, 0x01, 0x02, 0x78, 0x2f, 0x01, 0x02, 0x7c, 0x2f, 0x01, 0x02, 0x80, 0x2f, 0x01, 0x02, 0x84, 0x2f, 0x01, 0x02, 0x88, 0x2f, 0x01, 0x02, 0x3c, 0x0d, 0x02, 0x02, 0x40, 0x0d, 0x02, 0x02, + 0x44, 0x0d, 0x02, 0x02, 0x48, 0x0d, 0x02, 0x02, 0x58, 0x2a, 0x03, 0x03, 0x60, 0x2a, 0x03, 0x03, 0x68, 0x2a, 0x03, 0x03, 0x88, 0x09, 0x04, 0x03, 0x90, 0x09, 0x04, 0x03, 0x90, 0x24, 0x05, 0x04, + 0xa0, 0x24, 0x05, 0x04, 0x20, 0x06, 0x06, 0x04, 0x80, 0x22, 0x07, 0x05, 0x40, 0x01, 0x0a, 0x06, 0xdc, 0x02, 0x00, 0x02, 0xe0, 0x02, 0x00, 0x02, 0xe4, 0x02, 0x00, 0x02, 0xe8, 0x02, 0x00, 0x02, + 0x8c, 0x2f, 0x01, 0x02, 0x90, 0x2f, 0x01, 0x02, 0x94, 0x2f, 0x01, 0x02, 0x98, 0x2f, 0x01, 0x02, 0x9c, 0x2f, 0x01, 0x02, 0xa0, 0x2f, 0x01, 0x02, 0x4c, 0x0d, 0x02, 0x02, 0x50, 0x0d, 0x02, 0x02, + 0x54, 0x0d, 0x02, 0x02, 0x58, 0x0d, 0x02, 0x02, 0x70, 0x2a, 0x03, 0x03, 0x78, 0x2a, 0x03, 0x03, 0x80, 0x2a, 0x03, 0x03, 0x98, 0x09, 0x04, 0x03, 0xa0, 0x09, 0x04, 0x03, 0xb0, 0x24, 0x05, 0x04, + 0xc0, 0x24, 0x05, 0x04, 0x30, 0x06, 0x06, 0x04, 0x80, 0x00, 0x08, 0x05, 0x80, 0x01, 0x0a, 0x06, 0xec, 0x02, 0x00, 0x02, 0xf0, 0x02, 0x00, 0x02, 0xf4, 0x02, 0x00, 0x02, 0xf8, 0x02, 0x00, 0x02, + 0xa4, 0x2f, 0x01, 0x02, 0xa8, 0x2f, 0x01, 0x02, 0xac, 0x2f, 0x01, 0x02, 0xb0, 0x2f, 0x01, 0x02, 0xb4, 0x2f, 0x01, 0x02, 0xb8, 0x2f, 0x01, 0x02, 0x5c, 0x0d, 0x02, 0x02, 0x60, 0x0d, 0x02, 0x02, + 0x64, 0x0d, 0x02, 0x02, 0x68, 0x0d, 0x02, 0x02, 0x88, 0x2a, 0x03, 0x03, 0x90, 0x2a, 0x03, 0x03, 0x98, 0x2a, 0x03, 0x03, 0xa8, 0x09, 0x04, 0x03, 0xb0, 0x09, 0x04, 0x03, 0xd0, 0x24, 0x05, 0x04, + 0xe0, 0x24, 0x05, 0x04, 0x40, 0x06, 0x06, 0x04, 0xa0, 0x00, 0x08, 0x05, 0xc0, 0x01, 0x0a, 0x06, 0xfc, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x04, 0x03, 0x00, 0x02, 0x08, 0x03, 0x00, 0x02, + 0xbc, 0x2f, 0x01, 0x02, 0xc0, 0x2f, 0x01, 0x02, 0xc4, 0x2f, 0x01, 0x02, 0xc8, 0x2f, 0x01, 0x02, 0xcc, 0x2f, 0x01, 0x02, 0xd0, 0x2f, 0x01, 0x02, 0x6c, 0x0d, 0x02, 0x02, 0x70, 0x0d, 0x02, 0x02, + 0x74, 0x0d, 0x02, 0x02, 0x78, 0x0d, 0x02, 0x02, 0xa0, 0x2a, 0x03, 0x03, 0xa8, 0x2a, 0x03, 0x03, 0xb0, 0x2a, 0x03, 0x03, 0xb8, 0x09, 0x04, 0x03, 0xc0, 0x09, 0x04, 0x03, 0xf0, 0x24, 0x05, 0x04, + 0x00, 0x25, 0x05, 0x04, 0x50, 0x06, 0x06, 0x04, 0xc0, 0x00, 0x08, 0x05, 0x80, 0x14, 0x0b, 0x07, 0x0c, 0x03, 0x00, 0x02, 0x10, 0x03, 0x00, 0x02, 0x14, 0x03, 0x00, 0x02, 0x18, 0x03, 0x00, 0x02, + 0xd4, 0x2f, 0x01, 0x02, 0xd8, 0x2f, 0x01, 0x02, 0xdc, 0x2f, 0x01, 0x02, 0xe0, 0x2f, 0x01, 0x02, 0xe4, 0x2f, 0x01, 0x02, 0xe8, 0x2f, 0x01, 0x02, 0x7c, 0x0d, 0x02, 0x02, 0x80, 0x0d, 0x02, 0x02, + 0x84, 0x0d, 0x02, 0x02, 0x88, 0x0d, 0x02, 0x02, 0xb8, 0x2a, 0x03, 0x03, 0xc0, 0x2a, 0x03, 0x03, 0xc8, 0x2a, 0x03, 0x03, 0xc8, 0x09, 0x04, 0x03, 0xd0, 0x09, 0x04, 0x03, 0x10, 0x25, 0x05, 0x04, + 0x20, 0x25, 0x05, 0x04, 0x60, 0x06, 0x06, 0x04, 0xe0, 0x00, 0x08, 0x05, 0x00, 0x15, 0x0b, 0x07, 0x1c, 0x03, 0x00, 0x02, 0x20, 0x03, 0x00, 0x02, 0x24, 0x03, 0x00, 0x02, 0x28, 0x03, 0x00, 0x02, + 0xec, 0x2f, 0x01, 0x02, 0xf0, 0x2f, 0x01, 0x02, 0xf4, 0x2f, 0x01, 0x02, 0xf8, 0x2f, 0x01, 0x02, 0xfc, 0x2f, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x8c, 0x0d, 0x02, 0x02, 0x90, 0x0d, 0x02, 0x02, + 0x94, 0x0d, 0x02, 0x02, 0x98, 0x0d, 0x02, 0x02, 0xd0, 0x2a, 0x03, 0x03, 0xd8, 0x2a, 0x03, 0x03, 0xe0, 0x2a, 0x03, 0x03, 0xd8, 0x09, 0x04, 0x03, 0xe0, 0x09, 0x04, 0x03, 0x30, 0x25, 0x05, 0x04, + 0x40, 0x25, 0x05, 0x04, 0x70, 0x06, 0x06, 0x04, 0x00, 0x01, 0x08, 0x05, 0x80, 0x15, 0x0b, 0x07, 0x2c, 0x03, 0x00, 0x02, 0x30, 0x03, 0x00, 0x02, 0x34, 0x03, 0x00, 0x02, 0x38, 0x03, 0x00, 0x02, + 0x04, 0x30, 0x01, 0x02, 0x08, 0x30, 0x01, 0x02, 0x0c, 0x30, 0x01, 0x02, 0x10, 0x30, 0x01, 0x02, 0x14, 0x30, 0x01, 0x02, 0x18, 0x30, 0x01, 0x02, 0x9c, 0x0d, 0x02, 0x02, 0xa0, 0x0d, 0x02, 0x02, + 0xa4, 0x0d, 0x02, 0x02, 0xa8, 0x0d, 0x02, 0x02, 0xe8, 0x2a, 0x03, 0x03, 0xf0, 0x2a, 0x03, 0x03, 0xf8, 0x2a, 0x03, 0x03, 0xe8, 0x09, 0x04, 0x03, 0xf0, 0x09, 0x04, 0x03, 0x50, 0x25, 0x05, 0x04, + 0x60, 0x25, 0x05, 0x04, 0x80, 0x06, 0x06, 0x04, 0x20, 0x01, 0x08, 0x05, 0x00, 0x16, 0x0b, 0x07, 0x3c, 0x03, 0x00, 0x02, 0x40, 0x03, 0x00, 0x02, 0x44, 0x03, 0x00, 0x02, 0x48, 0x03, 0x00, 0x02, + 0x1c, 0x30, 0x01, 0x02, 0x20, 0x30, 0x01, 0x02, 0x24, 0x30, 0x01, 0x02, 0x28, 0x30, 0x01, 0x02, 0x2c, 0x30, 0x01, 0x02, 0x30, 0x30, 0x01, 0x02, 0xac, 0x0d, 0x02, 0x02, 0xb0, 0x0d, 0x02, 0x02, + 0xb4, 0x0d, 0x02, 0x02, 0xb8, 0x0d, 0x02, 0x02, 0x00, 0x2b, 0x03, 0x03, 0x08, 0x2b, 0x03, 0x03, 0x10, 0x2b, 0x03, 0x03, 0xf8, 0x09, 0x04, 0x03, 0x00, 0x0a, 0x04, 0x03, 0x70, 0x25, 0x05, 0x04, + 0x80, 0x25, 0x05, 0x04, 0x90, 0x06, 0x06, 0x04, 0x40, 0x01, 0x08, 0x05, 0x80, 0x16, 0x0b, 0x07, 0x4c, 0x03, 0x00, 0x02, 0x50, 0x03, 0x00, 0x02, 0x54, 0x03, 0x00, 0x02, 0x58, 0x03, 0x00, 0x02, + 0x34, 0x30, 0x01, 0x02, 0x38, 0x30, 0x01, 0x02, 0x3c, 0x30, 0x01, 0x02, 0x40, 0x30, 0x01, 0x02, 0x44, 0x30, 0x01, 0x02, 0x48, 0x30, 0x01, 0x02, 0xbc, 0x0d, 0x02, 0x02, 0xc0, 0x0d, 0x02, 0x02, + 0xc4, 0x0d, 0x02, 0x02, 0xc8, 0x0d, 0x02, 0x02, 0x18, 0x2b, 0x03, 0x03, 0x20, 0x2b, 0x03, 0x03, 0x28, 0x2b, 0x03, 0x03, 0x08, 0x0a, 0x04, 0x03, 0x10, 0x0a, 0x04, 0x03, 0x90, 0x25, 0x05, 0x04, + 0xa0, 0x25, 0x05, 0x04, 0xa0, 0x06, 0x06, 0x04, 0x60, 0x01, 0x08, 0x05, 0x00, 0x17, 0x0b, 0x07, 0x5c, 0x03, 0x00, 0x02, 0x60, 0x03, 0x00, 0x02, 0x64, 0x03, 0x00, 0x02, 0x68, 0x03, 0x00, 0x02, + 0x4c, 0x30, 0x01, 0x02, 0x50, 0x30, 0x01, 0x02, 0x54, 0x30, 0x01, 0x02, 0x58, 0x30, 0x01, 0x02, 0x5c, 0x30, 0x01, 0x02, 0x60, 0x30, 0x01, 0x02, 0xcc, 0x0d, 0x02, 0x02, 0xd0, 0x0d, 0x02, 0x02, + 0xd4, 0x0d, 0x02, 0x02, 0xd8, 0x0d, 0x02, 0x02, 0x30, 0x2b, 0x03, 0x03, 0x38, 0x2b, 0x03, 0x03, 0x40, 0x2b, 0x03, 0x03, 0x18, 0x0a, 0x04, 0x03, 0x20, 0x0a, 0x04, 0x03, 0xb0, 0x25, 0x05, 0x04, + 0xc0, 0x25, 0x05, 0x04, 0xb0, 0x06, 0x06, 0x04, 0x80, 0x01, 0x08, 0x05, 0x80, 0x17, 0x0b, 0x07, 0x6c, 0x03, 0x00, 0x02, 0x70, 0x03, 0x00, 0x02, 0x74, 0x03, 0x00, 0x02, 0x78, 0x03, 0x00, 0x02, + 0x64, 0x30, 0x01, 0x02, 0x68, 0x30, 0x01, 0x02, 0x6c, 0x30, 0x01, 0x02, 0x70, 0x30, 0x01, 0x02, 0x74, 0x30, 0x01, 0x02, 0x78, 0x30, 0x01, 0x02, 0xdc, 0x0d, 0x02, 0x02, 0xe0, 0x0d, 0x02, 0x02, + 0xe4, 0x0d, 0x02, 0x02, 0xe8, 0x0d, 0x02, 0x02, 0x48, 0x2b, 0x03, 0x03, 0x50, 0x2b, 0x03, 0x03, 0x58, 0x2b, 0x03, 0x03, 0x28, 0x0a, 0x04, 0x03, 0x30, 0x0a, 0x04, 0x03, 0xd0, 0x25, 0x05, 0x04, + 0xe0, 0x25, 0x05, 0x04, 0xc0, 0x06, 0x06, 0x04, 0xa0, 0x01, 0x08, 0x05, 0x00, 0x18, 0x0b, 0x07, 0x7c, 0x03, 0x00, 0x02, 0x80, 0x03, 0x00, 0x02, 0x84, 0x03, 0x00, 0x02, 0x88, 0x03, 0x00, 0x02, + 0x7c, 0x30, 0x01, 0x02, 0x80, 0x30, 0x01, 0x02, 0x84, 0x30, 0x01, 0x02, 0x88, 0x30, 0x01, 0x02, 0x8c, 0x30, 0x01, 0x02, 0x90, 0x30, 0x01, 0x02, 0xec, 0x0d, 0x02, 0x02, 0xf0, 0x0d, 0x02, 0x02, + 0xf4, 0x0d, 0x02, 0x02, 0xf8, 0x0d, 0x02, 0x02, 0x60, 0x2b, 0x03, 0x03, 0x68, 0x2b, 0x03, 0x03, 0x70, 0x2b, 0x03, 0x03, 0x38, 0x0a, 0x04, 0x03, 0x40, 0x0a, 0x04, 0x03, 0xf0, 0x25, 0x05, 0x04, + 0x00, 0x26, 0x05, 0x04, 0xd0, 0x06, 0x06, 0x04, 0xc0, 0x01, 0x08, 0x05, 0x80, 0x18, 0x0b, 0x07, 0x8c, 0x03, 0x00, 0x02, 0x90, 0x03, 0x00, 0x02, 0x94, 0x03, 0x00, 0x02, 0x98, 0x03, 0x00, 0x02, + 0x94, 0x30, 0x01, 0x02, 0x98, 0x30, 0x01, 0x02, 0x9c, 0x30, 0x01, 0x02, 0xa0, 0x30, 0x01, 0x02, 0xa4, 0x30, 0x01, 0x02, 0xa8, 0x30, 0x01, 0x02, 0xfc, 0x0d, 0x02, 0x02, 0x00, 0x0e, 0x02, 0x02, + 0x04, 0x0e, 0x02, 0x02, 0x08, 0x0e, 0x02, 0x02, 0x78, 0x2b, 0x03, 0x03, 0x80, 0x2b, 0x03, 0x03, 0x88, 0x2b, 0x03, 0x03, 0x48, 0x0a, 0x04, 0x03, 0x50, 0x0a, 0x04, 0x03, 0x10, 0x26, 0x05, 0x04, + 0x20, 0x26, 0x05, 0x04, 0xe0, 0x06, 0x06, 0x04, 0xe0, 0x01, 0x08, 0x05, 0x00, 0x19, 0x0b, 0x07, 0x9c, 0x03, 0x00, 0x02, 0xa0, 0x03, 0x00, 0x02, 0xa4, 0x03, 0x00, 0x02, 0xa8, 0x03, 0x00, 0x02, + 0xac, 0x30, 0x01, 0x02, 0xb0, 0x30, 0x01, 0x02, 0xb4, 0x30, 0x01, 0x02, 0xb8, 0x30, 0x01, 0x02, 0xbc, 0x30, 0x01, 0x02, 0xc0, 0x30, 0x01, 0x02, 0x0c, 0x0e, 0x02, 0x02, 0x10, 0x0e, 0x02, 0x02, + 0x14, 0x0e, 0x02, 0x02, 0x18, 0x0e, 0x02, 0x02, 0x90, 0x2b, 0x03, 0x03, 0x98, 0x2b, 0x03, 0x03, 0xa0, 0x2b, 0x03, 0x03, 0x58, 0x0a, 0x04, 0x03, 0x60, 0x0a, 0x04, 0x03, 0x30, 0x26, 0x05, 0x04, + 0x40, 0x26, 0x05, 0x04, 0xf0, 0x06, 0x06, 0x04, 0x00, 0x02, 0x08, 0x05, 0x80, 0x19, 0x0b, 0x07, 0xac, 0x03, 0x00, 0x02, 0xb0, 0x03, 0x00, 0x02, 0xb4, 0x03, 0x00, 0x02, 0xb8, 0x03, 0x00, 0x02, + 0xc4, 0x30, 0x01, 0x02, 0xc8, 0x30, 0x01, 0x02, 0xcc, 0x30, 0x01, 0x02, 0xd0, 0x30, 0x01, 0x02, 0xd4, 0x30, 0x01, 0x02, 0xd8, 0x30, 0x01, 0x02, 0x1c, 0x0e, 0x02, 0x02, 0x20, 0x0e, 0x02, 0x02, + 0x24, 0x0e, 0x02, 0x02, 0x28, 0x0e, 0x02, 0x02, 0xa8, 0x2b, 0x03, 0x03, 0xb0, 0x2b, 0x03, 0x03, 0xb8, 0x2b, 0x03, 0x03, 0x68, 0x0a, 0x04, 0x03, 0x70, 0x0a, 0x04, 0x03, 0x50, 0x26, 0x05, 0x04, + 0x60, 0x26, 0x05, 0x04, 0x00, 0x07, 0x06, 0x04, 0x20, 0x02, 0x08, 0x05, 0x00, 0x1a, 0x0b, 0x07, 0xbc, 0x03, 0x00, 0x02, 0xc0, 0x03, 0x00, 0x02, 0xc4, 0x03, 0x00, 0x02, 0xc8, 0x03, 0x00, 0x02, + 0xdc, 0x30, 0x01, 0x02, 0xe0, 0x30, 0x01, 0x02, 0xe4, 0x30, 0x01, 0x02, 0xe8, 0x30, 0x01, 0x02, 0xec, 0x30, 0x01, 0x02, 0xf0, 0x30, 0x01, 0x02, 0x2c, 0x0e, 0x02, 0x02, 0x30, 0x0e, 0x02, 0x02, + 0x34, 0x0e, 0x02, 0x02, 0x38, 0x0e, 0x02, 0x02, 0xc0, 0x2b, 0x03, 0x03, 0xc8, 0x2b, 0x03, 0x03, 0xd0, 0x2b, 0x03, 0x03, 0x78, 0x0a, 0x04, 0x03, 0x80, 0x0a, 0x04, 0x03, 0x70, 0x26, 0x05, 0x04, + 0x80, 0x26, 0x05, 0x04, 0x10, 0x07, 0x06, 0x04, 0x40, 0x02, 0x08, 0x05, 0x80, 0x1a, 0x0b, 0x07, 0xcc, 0x03, 0x00, 0x02, 0xd0, 0x03, 0x00, 0x02, 0xd4, 0x03, 0x00, 0x02, 0xd8, 0x03, 0x00, 0x02, + 0xf4, 0x30, 0x01, 0x02, 0xf8, 0x30, 0x01, 0x02, 0xfc, 0x30, 0x01, 0x02, 0x00, 0x31, 0x01, 0x02, 0x04, 0x31, 0x01, 0x02, 0x08, 0x31, 0x01, 0x02, 0x3c, 0x0e, 0x02, 0x02, 0x40, 0x0e, 0x02, 0x02, + 0x44, 0x0e, 0x02, 0x02, 0x48, 0x0e, 0x02, 0x02, 0xd8, 0x2b, 0x03, 0x03, 0xe0, 0x2b, 0x03, 0x03, 0xe8, 0x2b, 0x03, 0x03, 0x88, 0x0a, 0x04, 0x03, 0x90, 0x0a, 0x04, 0x03, 0x90, 0x26, 0x05, 0x04, + 0xa0, 0x26, 0x05, 0x04, 0x20, 0x07, 0x06, 0x04, 0x60, 0x02, 0x08, 0x05, 0x00, 0x35, 0x0c, 0x08, 0xdc, 0x03, 0x00, 0x02, 0xe0, 0x03, 0x00, 0x02, 0xe4, 0x03, 0x00, 0x02, 0xe8, 0x03, 0x00, 0x02, + 0x0c, 0x31, 0x01, 0x02, 0x10, 0x31, 0x01, 0x02, 0x14, 0x31, 0x01, 0x02, 0x18, 0x31, 0x01, 0x02, 0x1c, 0x31, 0x01, 0x02, 0x20, 0x31, 0x01, 0x02, 0x4c, 0x0e, 0x02, 0x02, 0x50, 0x0e, 0x02, 0x02, + 0x54, 0x0e, 0x02, 0x02, 0x58, 0x0e, 0x02, 0x02, 0xf0, 0x2b, 0x03, 0x03, 0xf8, 0x2b, 0x03, 0x03, 0x00, 0x2c, 0x03, 0x03, 0x98, 0x0a, 0x04, 0x03, 0xa0, 0x0a, 0x04, 0x03, 0xb0, 0x26, 0x05, 0x04, + 0xc0, 0x26, 0x05, 0x04, 0x30, 0x07, 0x06, 0x04, 0x80, 0x02, 0x08, 0x05, 0x00, 0x36, 0x0c, 0x08, 0xec, 0x03, 0x00, 0x02, 0xf0, 0x03, 0x00, 0x02, 0xf4, 0x03, 0x00, 0x02, 0xf8, 0x03, 0x00, 0x02, + 0x24, 0x31, 0x01, 0x02, 0x28, 0x31, 0x01, 0x02, 0x2c, 0x31, 0x01, 0x02, 0x30, 0x31, 0x01, 0x02, 0x34, 0x31, 0x01, 0x02, 0x38, 0x31, 0x01, 0x02, 0x5c, 0x0e, 0x02, 0x02, 0x60, 0x0e, 0x02, 0x02, + 0x64, 0x0e, 0x02, 0x02, 0x68, 0x0e, 0x02, 0x02, 0x08, 0x2c, 0x03, 0x03, 0x10, 0x2c, 0x03, 0x03, 0x18, 0x2c, 0x03, 0x03, 0xa8, 0x0a, 0x04, 0x03, 0xb0, 0x0a, 0x04, 0x03, 0xd0, 0x26, 0x05, 0x04, + 0xe0, 0x26, 0x05, 0x04, 0x40, 0x07, 0x06, 0x04, 0xa0, 0x02, 0x08, 0x05, 0x00, 0x37, 0x0c, 0x08, 0xfc, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x04, 0x04, 0x00, 0x02, 0x08, 0x04, 0x00, 0x02, + 0x3c, 0x31, 0x01, 0x02, 0x40, 0x31, 0x01, 0x02, 0x44, 0x31, 0x01, 0x02, 0x48, 0x31, 0x01, 0x02, 0x4c, 0x31, 0x01, 0x02, 0x50, 0x31, 0x01, 0x02, 0x6c, 0x0e, 0x02, 0x02, 0x70, 0x0e, 0x02, 0x02, + 0x74, 0x0e, 0x02, 0x02, 0x78, 0x0e, 0x02, 0x02, 0x20, 0x2c, 0x03, 0x03, 0x28, 0x2c, 0x03, 0x03, 0x30, 0x2c, 0x03, 0x03, 0xb8, 0x0a, 0x04, 0x03, 0xc0, 0x0a, 0x04, 0x03, 0xf0, 0x26, 0x05, 0x04, + 0x00, 0x27, 0x05, 0x04, 0x50, 0x07, 0x06, 0x04, 0xc0, 0x02, 0x08, 0x05, 0x00, 0x38, 0x0c, 0x08, 0x0c, 0x04, 0x00, 0x02, 0x10, 0x04, 0x00, 0x02, 0x14, 0x04, 0x00, 0x02, 0x18, 0x04, 0x00, 0x02, + 0x54, 0x31, 0x01, 0x02, 0x58, 0x31, 0x01, 0x02, 0x5c, 0x31, 0x01, 0x02, 0x60, 0x31, 0x01, 0x02, 0x64, 0x31, 0x01, 0x02, 0x68, 0x31, 0x01, 0x02, 0x7c, 0x0e, 0x02, 0x02, 0x80, 0x0e, 0x02, 0x02, + 0x84, 0x0e, 0x02, 0x02, 0x88, 0x0e, 0x02, 0x02, 0x38, 0x2c, 0x03, 0x03, 0x40, 0x2c, 0x03, 0x03, 0x48, 0x2c, 0x03, 0x03, 0xc8, 0x0a, 0x04, 0x03, 0xd0, 0x0a, 0x04, 0x03, 0x10, 0x27, 0x05, 0x04, + 0x20, 0x27, 0x05, 0x04, 0x60, 0x07, 0x06, 0x04, 0xe0, 0x02, 0x08, 0x05, 0x00, 0x39, 0x0c, 0x08, 0x1c, 0x04, 0x00, 0x02, 0x20, 0x04, 0x00, 0x02, 0x24, 0x04, 0x00, 0x02, 0x28, 0x04, 0x00, 0x02, + 0x6c, 0x31, 0x01, 0x02, 0x70, 0x31, 0x01, 0x02, 0x74, 0x31, 0x01, 0x02, 0x78, 0x31, 0x01, 0x02, 0x7c, 0x31, 0x01, 0x02, 0x80, 0x31, 0x01, 0x02, 0x8c, 0x0e, 0x02, 0x02, 0x90, 0x0e, 0x02, 0x02, + 0x94, 0x0e, 0x02, 0x02, 0x98, 0x0e, 0x02, 0x02, 0x50, 0x2c, 0x03, 0x03, 0x58, 0x2c, 0x03, 0x03, 0x60, 0x2c, 0x03, 0x03, 0xd8, 0x0a, 0x04, 0x03, 0xe0, 0x0a, 0x04, 0x03, 0x30, 0x27, 0x05, 0x04, + 0x40, 0x27, 0x05, 0x04, 0x70, 0x07, 0x06, 0x04, 0x00, 0x03, 0x08, 0x05, 0x00, 0x3a, 0x0c, 0x08, 0x2c, 0x04, 0x00, 0x02, 0x30, 0x04, 0x00, 0x02, 0x34, 0x04, 0x00, 0x02, 0x38, 0x04, 0x00, 0x02, + 0x84, 0x31, 0x01, 0x02, 0x88, 0x31, 0x01, 0x02, 0x8c, 0x31, 0x01, 0x02, 0x90, 0x31, 0x01, 0x02, 0x94, 0x31, 0x01, 0x02, 0x98, 0x31, 0x01, 0x02, 0x9c, 0x0e, 0x02, 0x02, 0xa0, 0x0e, 0x02, 0x02, + 0xa4, 0x0e, 0x02, 0x02, 0xa8, 0x0e, 0x02, 0x02, 0x68, 0x2c, 0x03, 0x03, 0x70, 0x2c, 0x03, 0x03, 0x78, 0x2c, 0x03, 0x03, 0xe8, 0x0a, 0x04, 0x03, 0xf0, 0x0a, 0x04, 0x03, 0x50, 0x27, 0x05, 0x04, + 0x60, 0x27, 0x05, 0x04, 0x80, 0x07, 0x06, 0x04, 0x20, 0x03, 0x08, 0x05, 0x00, 0x3b, 0x0c, 0x08, 0x3c, 0x04, 0x00, 0x02, 0x40, 0x04, 0x00, 0x02, 0x44, 0x04, 0x00, 0x02, 0x48, 0x04, 0x00, 0x02, + 0x9c, 0x31, 0x01, 0x02, 0xa0, 0x31, 0x01, 0x02, 0xa4, 0x31, 0x01, 0x02, 0xa8, 0x31, 0x01, 0x02, 0xac, 0x31, 0x01, 0x02, 0xb0, 0x31, 0x01, 0x02, 0xac, 0x0e, 0x02, 0x02, 0xb0, 0x0e, 0x02, 0x02, + 0xb4, 0x0e, 0x02, 0x02, 0xb8, 0x0e, 0x02, 0x02, 0x80, 0x2c, 0x03, 0x03, 0x88, 0x2c, 0x03, 0x03, 0x90, 0x2c, 0x03, 0x03, 0xf8, 0x0a, 0x04, 0x03, 0x00, 0x0b, 0x04, 0x03, 0x70, 0x27, 0x05, 0x04, + 0x80, 0x27, 0x05, 0x04, 0x90, 0x07, 0x06, 0x04, 0x40, 0x03, 0x08, 0x05, 0x00, 0x3c, 0x0c, 0x08, 0x4c, 0x04, 0x00, 0x02, 0x50, 0x04, 0x00, 0x02, 0x54, 0x04, 0x00, 0x02, 0xb4, 0x31, 0x01, 0x02, + 0xb8, 0x31, 0x01, 0x02, 0xbc, 0x31, 0x01, 0x02, 0xc0, 0x31, 0x01, 0x02, 0xc4, 0x31, 0x01, 0x02, 0xc8, 0x31, 0x01, 0x02, 0xcc, 0x31, 0x01, 0x02, 0xbc, 0x0e, 0x02, 0x02, 0xc0, 0x0e, 0x02, 0x02, + 0xc4, 0x0e, 0x02, 0x02, 0xc8, 0x0e, 0x02, 0x02, 0x98, 0x2c, 0x03, 0x03, 0xa0, 0x2c, 0x03, 0x03, 0xa8, 0x2c, 0x03, 0x03, 0x08, 0x0b, 0x04, 0x03, 0x10, 0x0b, 0x04, 0x03, 0x90, 0x27, 0x05, 0x04, + 0xa0, 0x27, 0x05, 0x04, 0xa0, 0x07, 0x06, 0x04, 0x60, 0x03, 0x08, 0x05, 0x00, 0x3d, 0x0c, 0x08, 0x58, 0x04, 0x00, 0x02, 0x5c, 0x04, 0x00, 0x02, 0x60, 0x04, 0x00, 0x02, 0xd0, 0x31, 0x01, 0x02, + 0xd4, 0x31, 0x01, 0x02, 0xd8, 0x31, 0x01, 0x02, 0xdc, 0x31, 0x01, 0x02, 0xe0, 0x31, 0x01, 0x02, 0xe4, 0x31, 0x01, 0x02, 0xe8, 0x31, 0x01, 0x02, 0xcc, 0x0e, 0x02, 0x02, 0xd0, 0x0e, 0x02, 0x02, + 0xd4, 0x0e, 0x02, 0x02, 0xd8, 0x0e, 0x02, 0x02, 0xb0, 0x2c, 0x03, 0x03, 0xb8, 0x2c, 0x03, 0x03, 0xc0, 0x2c, 0x03, 0x03, 0x18, 0x0b, 0x04, 0x03, 0x20, 0x0b, 0x04, 0x03, 0xb0, 0x27, 0x05, 0x04, + 0xc0, 0x27, 0x05, 0x04, 0xb0, 0x07, 0x06, 0x04, 0x80, 0x03, 0x08, 0x05, 0x00, 0x11, 0x0d, 0x08, 0x64, 0x04, 0x00, 0x02, 0x68, 0x04, 0x00, 0x02, 0x6c, 0x04, 0x00, 0x02, 0xec, 0x31, 0x01, 0x02, + 0xf0, 0x31, 0x01, 0x02, 0xf4, 0x31, 0x01, 0x02, 0xf8, 0x31, 0x01, 0x02, 0xfc, 0x31, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, 0x04, 0x32, 0x01, 0x02, 0xdc, 0x0e, 0x02, 0x02, 0xe0, 0x0e, 0x02, 0x02, + 0xe4, 0x0e, 0x02, 0x02, 0xe8, 0x0e, 0x02, 0x02, 0xc8, 0x2c, 0x03, 0x03, 0xd0, 0x2c, 0x03, 0x03, 0xd8, 0x2c, 0x03, 0x03, 0x28, 0x0b, 0x04, 0x03, 0x30, 0x0b, 0x04, 0x03, 0xd0, 0x27, 0x05, 0x04, + 0xe0, 0x27, 0x05, 0x04, 0xc0, 0x07, 0x06, 0x04, 0xa0, 0x03, 0x08, 0x05, 0x00, 0x12, 0x0d, 0x08, 0x70, 0x04, 0x00, 0x02, 0x74, 0x04, 0x00, 0x02, 0x78, 0x04, 0x00, 0x02, 0x08, 0x32, 0x01, 0x02, + 0x0c, 0x32, 0x01, 0x02, 0x10, 0x32, 0x01, 0x02, 0x14, 0x32, 0x01, 0x02, 0x18, 0x32, 0x01, 0x02, 0x1c, 0x32, 0x01, 0x02, 0x20, 0x32, 0x01, 0x02, 0xec, 0x0e, 0x02, 0x02, 0xf0, 0x0e, 0x02, 0x02, + 0xf4, 0x0e, 0x02, 0x02, 0xf8, 0x0e, 0x02, 0x02, 0xe0, 0x2c, 0x03, 0x03, 0xe8, 0x2c, 0x03, 0x03, 0xf0, 0x2c, 0x03, 0x03, 0x38, 0x0b, 0x04, 0x03, 0x40, 0x0b, 0x04, 0x03, 0xf0, 0x27, 0x05, 0x04, + 0x00, 0x28, 0x05, 0x04, 0xd0, 0x07, 0x06, 0x04, 0xc0, 0x03, 0x08, 0x05, 0x00, 0x13, 0x0d, 0x08, 0x7c, 0x04, 0x00, 0x02, 0x80, 0x04, 0x00, 0x02, 0x84, 0x04, 0x00, 0x02, 0x24, 0x32, 0x01, 0x02, + 0x28, 0x32, 0x01, 0x02, 0x2c, 0x32, 0x01, 0x02, 0x30, 0x32, 0x01, 0x02, 0x34, 0x32, 0x01, 0x02, 0x38, 0x32, 0x01, 0x02, 0x3c, 0x32, 0x01, 0x02, 0xfc, 0x0e, 0x02, 0x02, 0x00, 0x0f, 0x02, 0x02, + 0x04, 0x0f, 0x02, 0x02, 0x08, 0x0f, 0x02, 0x02, 0xf8, 0x2c, 0x03, 0x03, 0x00, 0x2d, 0x03, 0x03, 0x08, 0x2d, 0x03, 0x03, 0x48, 0x0b, 0x04, 0x03, 0x50, 0x0b, 0x04, 0x03, 0x10, 0x28, 0x05, 0x04, + 0x20, 0x28, 0x05, 0x04, 0xa0, 0x22, 0x07, 0x05, 0xe0, 0x03, 0x08, 0x05, 0x00, 0x14, 0x0d, 0x08, 0x88, 0x04, 0x00, 0x02, 0x8c, 0x04, 0x00, 0x02, 0x90, 0x04, 0x00, 0x02, 0x40, 0x32, 0x01, 0x02, + 0x44, 0x32, 0x01, 0x02, 0x48, 0x32, 0x01, 0x02, 0x4c, 0x32, 0x01, 0x02, 0x50, 0x32, 0x01, 0x02, 0x54, 0x32, 0x01, 0x02, 0x58, 0x32, 0x01, 0x02, 0x0c, 0x0f, 0x02, 0x02, 0x10, 0x0f, 0x02, 0x02, + 0x14, 0x0f, 0x02, 0x02, 0x18, 0x0f, 0x02, 0x02, 0x10, 0x2d, 0x03, 0x03, 0x18, 0x2d, 0x03, 0x03, 0x20, 0x2d, 0x03, 0x03, 0x58, 0x0b, 0x04, 0x03, 0x60, 0x0b, 0x04, 0x03, 0x30, 0x28, 0x05, 0x04, + 0x40, 0x28, 0x05, 0x04, 0xc0, 0x22, 0x07, 0x05, 0x00, 0x04, 0x08, 0x05, 0x00, 0x15, 0x0d, 0x08, 0x94, 0x04, 0x00, 0x02, 0x98, 0x04, 0x00, 0x02, 0x9c, 0x04, 0x00, 0x02, 0x5c, 0x32, 0x01, 0x02, + 0x60, 0x32, 0x01, 0x02, 0x64, 0x32, 0x01, 0x02, 0x68, 0x32, 0x01, 0x02, 0x6c, 0x32, 0x01, 0x02, 0x70, 0x32, 0x01, 0x02, 0x74, 0x32, 0x01, 0x02, 0x1c, 0x0f, 0x02, 0x02, 0x20, 0x0f, 0x02, 0x02, + 0x24, 0x0f, 0x02, 0x02, 0x28, 0x0f, 0x02, 0x02, 0x28, 0x2d, 0x03, 0x03, 0x30, 0x2d, 0x03, 0x03, 0x38, 0x2d, 0x03, 0x03, 0x68, 0x0b, 0x04, 0x03, 0x70, 0x0b, 0x04, 0x03, 0x50, 0x28, 0x05, 0x04, + 0xe0, 0x07, 0x06, 0x04, 0xe0, 0x22, 0x07, 0x05, 0x20, 0x04, 0x08, 0x05, 0x00, 0x16, 0x0d, 0x08, 0xa0, 0x04, 0x00, 0x02, 0xa4, 0x04, 0x00, 0x02, 0xa8, 0x04, 0x00, 0x02, 0x78, 0x32, 0x01, 0x02, + 0x7c, 0x32, 0x01, 0x02, 0x80, 0x32, 0x01, 0x02, 0x84, 0x32, 0x01, 0x02, 0x88, 0x32, 0x01, 0x02, 0x8c, 0x32, 0x01, 0x02, 0x90, 0x32, 0x01, 0x02, 0x2c, 0x0f, 0x02, 0x02, 0x30, 0x0f, 0x02, 0x02, + 0x34, 0x0f, 0x02, 0x02, 0x38, 0x0f, 0x02, 0x02, 0x40, 0x2d, 0x03, 0x03, 0x48, 0x2d, 0x03, 0x03, 0x50, 0x2d, 0x03, 0x03, 0x78, 0x0b, 0x04, 0x03, 0x80, 0x0b, 0x04, 0x03, 0x60, 0x28, 0x05, 0x04, + 0xf0, 0x07, 0x06, 0x04, 0x00, 0x23, 0x07, 0x05, 0x40, 0x04, 0x08, 0x05, 0x00, 0x30, 0x0e, 0x09, 0xac, 0x04, 0x00, 0x02, 0xb0, 0x04, 0x00, 0x02, 0xb4, 0x04, 0x00, 0x02, 0x94, 0x32, 0x01, 0x02, + 0x98, 0x32, 0x01, 0x02, 0x9c, 0x32, 0x01, 0x02, 0xa0, 0x32, 0x01, 0x02, 0xa4, 0x32, 0x01, 0x02, 0xa8, 0x32, 0x01, 0x02, 0xac, 0x32, 0x01, 0x02, 0x3c, 0x0f, 0x02, 0x02, 0x40, 0x0f, 0x02, 0x02, + 0x44, 0x0f, 0x02, 0x02, 0x48, 0x0f, 0x02, 0x02, 0x58, 0x2d, 0x03, 0x03, 0x60, 0x2d, 0x03, 0x03, 0x68, 0x2d, 0x03, 0x03, 0x88, 0x0b, 0x04, 0x03, 0x90, 0x0b, 0x04, 0x03, 0x70, 0x28, 0x05, 0x04, + 0x00, 0x08, 0x06, 0x04, 0x20, 0x23, 0x07, 0x05, 0x60, 0x04, 0x08, 0x05, 0x00, 0x32, 0x0e, 0x09, 0xb8, 0x04, 0x00, 0x02, 0xbc, 0x04, 0x00, 0x02, 0xc0, 0x04, 0x00, 0x02, 0xb0, 0x32, 0x01, 0x02, + 0xb4, 0x32, 0x01, 0x02, 0xb8, 0x32, 0x01, 0x02, 0xbc, 0x32, 0x01, 0x02, 0xc0, 0x32, 0x01, 0x02, 0xc4, 0x32, 0x01, 0x02, 0xc8, 0x32, 0x01, 0x02, 0x4c, 0x0f, 0x02, 0x02, 0x50, 0x0f, 0x02, 0x02, + 0x54, 0x0f, 0x02, 0x02, 0x58, 0x0f, 0x02, 0x02, 0x70, 0x2d, 0x03, 0x03, 0x78, 0x2d, 0x03, 0x03, 0x80, 0x2d, 0x03, 0x03, 0x98, 0x0b, 0x04, 0x03, 0xa0, 0x0b, 0x04, 0x03, 0x80, 0x28, 0x05, 0x04, + 0x10, 0x08, 0x06, 0x04, 0x40, 0x23, 0x07, 0x05, 0x80, 0x04, 0x08, 0x05, 0x00, 0x34, 0x0e, 0x09, 0xc4, 0x04, 0x00, 0x02, 0xc8, 0x04, 0x00, 0x02, 0xcc, 0x04, 0x00, 0x02, 0xcc, 0x32, 0x01, 0x02, + 0xd0, 0x32, 0x01, 0x02, 0xd4, 0x32, 0x01, 0x02, 0xd8, 0x32, 0x01, 0x02, 0xdc, 0x32, 0x01, 0x02, 0xe0, 0x32, 0x01, 0x02, 0xe4, 0x32, 0x01, 0x02, 0x5c, 0x0f, 0x02, 0x02, 0x60, 0x0f, 0x02, 0x02, + 0x64, 0x0f, 0x02, 0x02, 0x68, 0x0f, 0x02, 0x02, 0x88, 0x2d, 0x03, 0x03, 0x90, 0x2d, 0x03, 0x03, 0x98, 0x2d, 0x03, 0x03, 0xa8, 0x0b, 0x04, 0x03, 0xb0, 0x0b, 0x04, 0x03, 0x90, 0x28, 0x05, 0x04, + 0x20, 0x08, 0x06, 0x04, 0x60, 0x23, 0x07, 0x05, 0xa0, 0x04, 0x08, 0x05, 0x00, 0x36, 0x0e, 0x09, 0xd0, 0x04, 0x00, 0x02, 0xd4, 0x04, 0x00, 0x02, 0xd8, 0x04, 0x00, 0x02, 0xe8, 0x32, 0x01, 0x02, + 0xec, 0x32, 0x01, 0x02, 0xf0, 0x32, 0x01, 0x02, 0xf4, 0x32, 0x01, 0x02, 0xf8, 0x32, 0x01, 0x02, 0xfc, 0x32, 0x01, 0x02, 0x00, 0x33, 0x01, 0x02, 0x6c, 0x0f, 0x02, 0x02, 0x70, 0x0f, 0x02, 0x02, + 0x74, 0x0f, 0x02, 0x02, 0x78, 0x0f, 0x02, 0x02, 0xa0, 0x2d, 0x03, 0x03, 0xa8, 0x2d, 0x03, 0x03, 0xb0, 0x2d, 0x03, 0x03, 0xb8, 0x0b, 0x04, 0x03, 0xc0, 0x0b, 0x04, 0x03, 0xa0, 0x28, 0x05, 0x04, + 0x30, 0x08, 0x06, 0x04, 0x80, 0x23, 0x07, 0x05, 0xc0, 0x04, 0x08, 0x05, 0x00, 0x10, 0x0f, 0x09, 0xdc, 0x04, 0x00, 0x02, 0xe0, 0x04, 0x00, 0x02, 0xe4, 0x04, 0x00, 0x02, 0x04, 0x33, 0x01, 0x02, + 0x08, 0x33, 0x01, 0x02, 0x0c, 0x33, 0x01, 0x02, 0x10, 0x33, 0x01, 0x02, 0x14, 0x33, 0x01, 0x02, 0x18, 0x33, 0x01, 0x02, 0x1c, 0x33, 0x01, 0x02, 0x7c, 0x0f, 0x02, 0x02, 0x80, 0x0f, 0x02, 0x02, + 0x84, 0x0f, 0x02, 0x02, 0x88, 0x0f, 0x02, 0x02, 0xb8, 0x2d, 0x03, 0x03, 0xc0, 0x2d, 0x03, 0x03, 0xc8, 0x2d, 0x03, 0x03, 0xc8, 0x0b, 0x04, 0x03, 0xd0, 0x0b, 0x04, 0x03, 0xb0, 0x28, 0x05, 0x04, + 0x40, 0x08, 0x06, 0x04, 0xa0, 0x23, 0x07, 0x05, 0xe0, 0x04, 0x08, 0x05, 0x00, 0x12, 0x0f, 0x09, 0xe8, 0x04, 0x00, 0x02, 0xec, 0x04, 0x00, 0x02, 0xf0, 0x04, 0x00, 0x02, 0x20, 0x33, 0x01, 0x02, + 0x24, 0x33, 0x01, 0x02, 0x28, 0x33, 0x01, 0x02, 0x2c, 0x33, 0x01, 0x02, 0x30, 0x33, 0x01, 0x02, 0x34, 0x33, 0x01, 0x02, 0x38, 0x33, 0x01, 0x02, 0x8c, 0x0f, 0x02, 0x02, 0x90, 0x0f, 0x02, 0x02, + 0x94, 0x0f, 0x02, 0x02, 0x98, 0x0f, 0x02, 0x02, 0xd0, 0x2d, 0x03, 0x03, 0xd8, 0x2d, 0x03, 0x03, 0xe0, 0x2d, 0x03, 0x03, 0xd8, 0x0b, 0x04, 0x03, 0xe0, 0x0b, 0x04, 0x03, 0xc0, 0x28, 0x05, 0x04, + 0x50, 0x08, 0x06, 0x04, 0xc0, 0x23, 0x07, 0x05, 0x00, 0x05, 0x08, 0x05, 0x00, 0x14, 0x0f, 0x09, 0xf4, 0x04, 0x00, 0x02, 0xf8, 0x04, 0x00, 0x02, 0xfc, 0x04, 0x00, 0x02, 0x3c, 0x33, 0x01, 0x02, + 0x40, 0x33, 0x01, 0x02, 0x44, 0x33, 0x01, 0x02, 0x48, 0x33, 0x01, 0x02, 0x4c, 0x33, 0x01, 0x02, 0x50, 0x33, 0x01, 0x02, 0x54, 0x33, 0x01, 0x02, 0x9c, 0x0f, 0x02, 0x02, 0xa0, 0x0f, 0x02, 0x02, + 0xa4, 0x0f, 0x02, 0x02, 0xa8, 0x0f, 0x02, 0x02, 0xe8, 0x2d, 0x03, 0x03, 0xf0, 0x2d, 0x03, 0x03, 0xf8, 0x2d, 0x03, 0x03, 0xe8, 0x0b, 0x04, 0x03, 0xf0, 0x0b, 0x04, 0x03, 0xd0, 0x28, 0x05, 0x04, + 0x60, 0x08, 0x06, 0x04, 0xe0, 0x23, 0x07, 0x05, 0x20, 0x05, 0x08, 0x05, 0x00, 0x16, 0x0f, 0x09, 0x00, 0x05, 0x00, 0x02, 0x04, 0x05, 0x00, 0x02, 0x08, 0x05, 0x00, 0x02, 0x58, 0x33, 0x01, 0x02, + 0x5c, 0x33, 0x01, 0x02, 0x60, 0x33, 0x01, 0x02, 0x64, 0x33, 0x01, 0x02, 0x68, 0x33, 0x01, 0x02, 0x6c, 0x33, 0x01, 0x02, 0x70, 0x33, 0x01, 0x02, 0xac, 0x0f, 0x02, 0x02, 0xb0, 0x0f, 0x02, 0x02, + 0xb4, 0x0f, 0x02, 0x02, 0xb8, 0x0f, 0x02, 0x02, 0x00, 0x2e, 0x03, 0x03, 0x08, 0x2e, 0x03, 0x03, 0x10, 0x2e, 0x03, 0x03, 0xf8, 0x0b, 0x04, 0x03, 0x00, 0x0c, 0x04, 0x03, 0xe0, 0x28, 0x05, 0x04, + 0x70, 0x08, 0x06, 0x04, 0x00, 0x24, 0x07, 0x05, 0x40, 0x05, 0x08, 0x05, 0x00, 0x30, 0x10, 0x0a, 0x0c, 0x05, 0x00, 0x02, 0x10, 0x05, 0x00, 0x02, 0x14, 0x05, 0x00, 0x02, 0x74, 0x33, 0x01, 0x02, + 0x78, 0x33, 0x01, 0x02, 0x7c, 0x33, 0x01, 0x02, 0x80, 0x33, 0x01, 0x02, 0x84, 0x33, 0x01, 0x02, 0x88, 0x33, 0x01, 0x02, 0x8c, 0x33, 0x01, 0x02, 0xbc, 0x0f, 0x02, 0x02, 0xc0, 0x0f, 0x02, 0x02, + 0xc4, 0x0f, 0x02, 0x02, 0xc8, 0x0f, 0x02, 0x02, 0x18, 0x2e, 0x03, 0x03, 0x20, 0x2e, 0x03, 0x03, 0x28, 0x2e, 0x03, 0x03, 0x08, 0x0c, 0x04, 0x03, 0x10, 0x0c, 0x04, 0x03, 0xf0, 0x28, 0x05, 0x04, + 0x80, 0x08, 0x06, 0x04, 0x20, 0x24, 0x07, 0x05, 0x60, 0x05, 0x08, 0x05, 0x00, 0x34, 0x10, 0x0a, 0x18, 0x05, 0x00, 0x02, 0x1c, 0x05, 0x00, 0x02, 0x20, 0x05, 0x00, 0x02, 0x90, 0x33, 0x01, 0x02, + 0x94, 0x33, 0x01, 0x02, 0x98, 0x33, 0x01, 0x02, 0x9c, 0x33, 0x01, 0x02, 0xa0, 0x33, 0x01, 0x02, 0xa4, 0x33, 0x01, 0x02, 0xa8, 0x33, 0x01, 0x02, 0xcc, 0x0f, 0x02, 0x02, 0xd0, 0x0f, 0x02, 0x02, + 0xd4, 0x0f, 0x02, 0x02, 0xd8, 0x0f, 0x02, 0x02, 0x30, 0x2e, 0x03, 0x03, 0x38, 0x2e, 0x03, 0x03, 0x40, 0x2e, 0x03, 0x03, 0x18, 0x0c, 0x04, 0x03, 0x20, 0x0c, 0x04, 0x03, 0x00, 0x29, 0x05, 0x04, + 0x90, 0x08, 0x06, 0x04, 0x40, 0x24, 0x07, 0x05, 0x80, 0x05, 0x08, 0x05, 0x00, 0x08, 0x11, 0x0a, 0x24, 0x05, 0x00, 0x02, 0x28, 0x05, 0x00, 0x02, 0x2c, 0x05, 0x00, 0x02, 0xac, 0x33, 0x01, 0x02, + 0xb0, 0x33, 0x01, 0x02, 0xb4, 0x33, 0x01, 0x02, 0xb8, 0x33, 0x01, 0x02, 0xbc, 0x33, 0x01, 0x02, 0xc0, 0x33, 0x01, 0x02, 0xc4, 0x33, 0x01, 0x02, 0xdc, 0x0f, 0x02, 0x02, 0xe0, 0x0f, 0x02, 0x02, + 0xe4, 0x0f, 0x02, 0x02, 0xe8, 0x0f, 0x02, 0x02, 0x48, 0x2e, 0x03, 0x03, 0x50, 0x2e, 0x03, 0x03, 0x58, 0x2e, 0x03, 0x03, 0x28, 0x0c, 0x04, 0x03, 0x30, 0x0c, 0x04, 0x03, 0x10, 0x29, 0x05, 0x04, + 0xa0, 0x08, 0x06, 0x04, 0x60, 0x24, 0x07, 0x05, 0x40, 0x1f, 0x09, 0x06, 0x00, 0x0c, 0x11, 0x0a, 0x30, 0x05, 0x00, 0x02, 0x34, 0x05, 0x00, 0x02, 0x38, 0x05, 0x00, 0x02, 0xc8, 0x33, 0x01, 0x02, + 0xcc, 0x33, 0x01, 0x02, 0xd0, 0x33, 0x01, 0x02, 0xd4, 0x33, 0x01, 0x02, 0xd8, 0x33, 0x01, 0x02, 0xdc, 0x33, 0x01, 0x02, 0xe0, 0x33, 0x01, 0x02, 0xec, 0x0f, 0x02, 0x02, 0xf0, 0x0f, 0x02, 0x02, + 0xf4, 0x0f, 0x02, 0x02, 0xf8, 0x0f, 0x02, 0x02, 0x60, 0x2e, 0x03, 0x03, 0x68, 0x2e, 0x03, 0x03, 0x70, 0x2e, 0x03, 0x03, 0x38, 0x0c, 0x04, 0x03, 0x40, 0x0c, 0x04, 0x03, 0x20, 0x29, 0x05, 0x04, + 0xb0, 0x08, 0x06, 0x04, 0x80, 0x24, 0x07, 0x05, 0x80, 0x1f, 0x09, 0x06, 0x00, 0x30, 0x12, 0x0b, 0x3c, 0x05, 0x00, 0x02, 0x40, 0x05, 0x00, 0x02, 0x44, 0x05, 0x00, 0x02, 0xe4, 0x33, 0x01, 0x02, + 0xe8, 0x33, 0x01, 0x02, 0xec, 0x33, 0x01, 0x02, 0xf0, 0x33, 0x01, 0x02, 0xf4, 0x33, 0x01, 0x02, 0xf8, 0x33, 0x01, 0x02, 0xfc, 0x33, 0x01, 0x02, 0xfc, 0x0f, 0x02, 0x02, 0x00, 0x10, 0x02, 0x02, + 0x04, 0x10, 0x02, 0x02, 0x08, 0x10, 0x02, 0x02, 0x78, 0x2e, 0x03, 0x03, 0x80, 0x2e, 0x03, 0x03, 0x88, 0x2e, 0x03, 0x03, 0x48, 0x0c, 0x04, 0x03, 0x50, 0x0c, 0x04, 0x03, 0x30, 0x29, 0x05, 0x04, + 0xc0, 0x08, 0x06, 0x04, 0xa0, 0x24, 0x07, 0x05, 0xc0, 0x1f, 0x09, 0x06, 0x00, 0x30, 0x14, 0x0c, 0x48, 0x05, 0x00, 0x02, 0x4c, 0x05, 0x00, 0x02, 0x50, 0x05, 0x00, 0x02, 0x00, 0x34, 0x01, 0x02, + 0x04, 0x34, 0x01, 0x02, 0x08, 0x34, 0x01, 0x02, 0x0c, 0x34, 0x01, 0x02, 0x10, 0x34, 0x01, 0x02, 0x14, 0x34, 0x01, 0x02, 0x18, 0x34, 0x01, 0x02, 0x0c, 0x10, 0x02, 0x02, 0x10, 0x10, 0x02, 0x02, + 0x14, 0x10, 0x02, 0x02, 0x18, 0x10, 0x02, 0x02, 0x90, 0x2e, 0x03, 0x03, 0x98, 0x2e, 0x03, 0x03, 0xa0, 0x2e, 0x03, 0x03, 0x58, 0x0c, 0x04, 0x03, 0x60, 0x0c, 0x04, 0x03, 0x40, 0x29, 0x05, 0x04, + 0xd0, 0x08, 0x06, 0x04, 0xc0, 0x24, 0x07, 0x05, 0x00, 0x20, 0x09, 0x06, 0x00, 0x20, 0x16, 0x0d, 0x54, 0x05, 0x00, 0x02, 0x58, 0x05, 0x00, 0x02, 0x5c, 0x05, 0x00, 0x02, 0x1c, 0x34, 0x01, 0x02, + 0x20, 0x34, 0x01, 0x02, 0x24, 0x34, 0x01, 0x02, 0x28, 0x34, 0x01, 0x02, 0x2c, 0x34, 0x01, 0x02, 0x30, 0x34, 0x01, 0x02, 0x34, 0x34, 0x01, 0x02, 0x1c, 0x10, 0x02, 0x02, 0x20, 0x10, 0x02, 0x02, + 0x24, 0x10, 0x02, 0x02, 0x28, 0x10, 0x02, 0x02, 0xa8, 0x2e, 0x03, 0x03, 0xb0, 0x2e, 0x03, 0x03, 0xb8, 0x2e, 0x03, 0x03, 0x68, 0x0c, 0x04, 0x03, 0x70, 0x0c, 0x04, 0x03, 0x50, 0x29, 0x05, 0x04, + 0xe0, 0x08, 0x06, 0x04, 0xe0, 0x24, 0x07, 0x05, 0x40, 0x20, 0x09, 0x06, 0x60, 0x05, 0x00, 0x02, 0x64, 0x05, 0x00, 0x02, 0x68, 0x05, 0x00, 0x02, 0x6c, 0x05, 0x00, 0x02, 0x38, 0x34, 0x01, 0x02, + 0x3c, 0x34, 0x01, 0x02, 0x40, 0x34, 0x01, 0x02, 0x44, 0x34, 0x01, 0x02, 0x48, 0x34, 0x01, 0x02, 0x4c, 0x34, 0x01, 0x02, 0x2c, 0x10, 0x02, 0x02, 0x30, 0x10, 0x02, 0x02, 0x34, 0x10, 0x02, 0x02, + 0x38, 0x10, 0x02, 0x02, 0x3c, 0x10, 0x02, 0x02, 0xc0, 0x2e, 0x03, 0x03, 0xc8, 0x2e, 0x03, 0x03, 0xd0, 0x2e, 0x03, 0x03, 0x78, 0x0c, 0x04, 0x03, 0x80, 0x0c, 0x04, 0x03, 0x60, 0x29, 0x05, 0x04, + 0xf0, 0x08, 0x06, 0x04, 0x00, 0x25, 0x07, 0x05, 0x80, 0x20, 0x09, 0x06, 0x70, 0x05, 0x00, 0x02, 0x74, 0x05, 0x00, 0x02, 0x78, 0x05, 0x00, 0x02, 0x7c, 0x05, 0x00, 0x02, 0x50, 0x34, 0x01, 0x02, + 0x54, 0x34, 0x01, 0x02, 0x58, 0x34, 0x01, 0x02, 0x5c, 0x34, 0x01, 0x02, 0x60, 0x34, 0x01, 0x02, 0x64, 0x34, 0x01, 0x02, 0x40, 0x10, 0x02, 0x02, 0x44, 0x10, 0x02, 0x02, 0x48, 0x10, 0x02, 0x02, + 0x4c, 0x10, 0x02, 0x02, 0x50, 0x10, 0x02, 0x02, 0xd8, 0x2e, 0x03, 0x03, 0xe0, 0x2e, 0x03, 0x03, 0xe8, 0x2e, 0x03, 0x03, 0x88, 0x0c, 0x04, 0x03, 0x90, 0x0c, 0x04, 0x03, 0x70, 0x29, 0x05, 0x04, + 0x00, 0x09, 0x06, 0x04, 0x20, 0x25, 0x07, 0x05, 0xc0, 0x20, 0x09, 0x06, 0x80, 0x05, 0x00, 0x02, 0x84, 0x05, 0x00, 0x02, 0x88, 0x05, 0x00, 0x02, 0x8c, 0x05, 0x00, 0x02, 0x68, 0x34, 0x01, 0x02, + 0x6c, 0x34, 0x01, 0x02, 0x70, 0x34, 0x01, 0x02, 0x74, 0x34, 0x01, 0x02, 0x78, 0x34, 0x01, 0x02, 0x7c, 0x34, 0x01, 0x02, 0x54, 0x10, 0x02, 0x02, 0x58, 0x10, 0x02, 0x02, 0x5c, 0x10, 0x02, 0x02, + 0x60, 0x10, 0x02, 0x02, 0x64, 0x10, 0x02, 0x02, 0xf0, 0x2e, 0x03, 0x03, 0xf8, 0x2e, 0x03, 0x03, 0x00, 0x2f, 0x03, 0x03, 0x98, 0x0c, 0x04, 0x03, 0xa0, 0x0c, 0x04, 0x03, 0x80, 0x29, 0x05, 0x04, + 0x10, 0x09, 0x06, 0x04, 0x40, 0x25, 0x07, 0x05, 0x00, 0x21, 0x09, 0x06, 0x90, 0x05, 0x00, 0x02, 0x94, 0x05, 0x00, 0x02, 0x98, 0x05, 0x00, 0x02, 0x9c, 0x05, 0x00, 0x02, 0x80, 0x34, 0x01, 0x02, + 0x84, 0x34, 0x01, 0x02, 0x88, 0x34, 0x01, 0x02, 0x8c, 0x34, 0x01, 0x02, 0x90, 0x34, 0x01, 0x02, 0x94, 0x34, 0x01, 0x02, 0x68, 0x10, 0x02, 0x02, 0x6c, 0x10, 0x02, 0x02, 0x70, 0x10, 0x02, 0x02, + 0x74, 0x10, 0x02, 0x02, 0x78, 0x10, 0x02, 0x02, 0x08, 0x2f, 0x03, 0x03, 0x10, 0x2f, 0x03, 0x03, 0x18, 0x2f, 0x03, 0x03, 0xa8, 0x0c, 0x04, 0x03, 0xb0, 0x0c, 0x04, 0x03, 0x90, 0x29, 0x05, 0x04, + 0x20, 0x09, 0x06, 0x04, 0x60, 0x25, 0x07, 0x05, 0x40, 0x21, 0x09, 0x06, 0xa0, 0x05, 0x00, 0x02, 0xa4, 0x05, 0x00, 0x02, 0xa8, 0x05, 0x00, 0x02, 0xac, 0x05, 0x00, 0x02, 0x98, 0x34, 0x01, 0x02, + 0x9c, 0x34, 0x01, 0x02, 0xa0, 0x34, 0x01, 0x02, 0xa4, 0x34, 0x01, 0x02, 0xa8, 0x34, 0x01, 0x02, 0xac, 0x34, 0x01, 0x02, 0x7c, 0x10, 0x02, 0x02, 0x80, 0x10, 0x02, 0x02, 0x84, 0x10, 0x02, 0x02, + 0x88, 0x10, 0x02, 0x02, 0x8c, 0x10, 0x02, 0x02, 0x20, 0x2f, 0x03, 0x03, 0x28, 0x2f, 0x03, 0x03, 0x30, 0x2f, 0x03, 0x03, 0xb8, 0x0c, 0x04, 0x03, 0xc0, 0x0c, 0x04, 0x03, 0xa0, 0x29, 0x05, 0x04, + 0x30, 0x09, 0x06, 0x04, 0x80, 0x25, 0x07, 0x05, 0x80, 0x21, 0x09, 0x06, 0xb0, 0x05, 0x00, 0x02, 0xb4, 0x05, 0x00, 0x02, 0xb8, 0x05, 0x00, 0x02, 0xbc, 0x05, 0x00, 0x02, 0xb0, 0x34, 0x01, 0x02, + 0xb4, 0x34, 0x01, 0x02, 0xb8, 0x34, 0x01, 0x02, 0xbc, 0x34, 0x01, 0x02, 0xc0, 0x34, 0x01, 0x02, 0xc4, 0x34, 0x01, 0x02, 0x90, 0x10, 0x02, 0x02, 0x94, 0x10, 0x02, 0x02, 0x98, 0x10, 0x02, 0x02, + 0x9c, 0x10, 0x02, 0x02, 0xa0, 0x10, 0x02, 0x02, 0x38, 0x2f, 0x03, 0x03, 0x40, 0x2f, 0x03, 0x03, 0x48, 0x2f, 0x03, 0x03, 0xc8, 0x0c, 0x04, 0x03, 0xd0, 0x0c, 0x04, 0x03, 0xb0, 0x29, 0x05, 0x04, + 0x40, 0x09, 0x06, 0x04, 0xa0, 0x25, 0x07, 0x05, 0xc0, 0x21, 0x09, 0x06, 0xc0, 0x05, 0x00, 0x02, 0xc4, 0x05, 0x00, 0x02, 0xc8, 0x05, 0x00, 0x02, 0xcc, 0x05, 0x00, 0x02, 0xc8, 0x34, 0x01, 0x02, + 0xcc, 0x34, 0x01, 0x02, 0xd0, 0x34, 0x01, 0x02, 0xd4, 0x34, 0x01, 0x02, 0xd8, 0x34, 0x01, 0x02, 0xdc, 0x34, 0x01, 0x02, 0xa4, 0x10, 0x02, 0x02, 0xa8, 0x10, 0x02, 0x02, 0xac, 0x10, 0x02, 0x02, + 0xb0, 0x10, 0x02, 0x02, 0xb4, 0x10, 0x02, 0x02, 0x50, 0x2f, 0x03, 0x03, 0x58, 0x2f, 0x03, 0x03, 0x60, 0x2f, 0x03, 0x03, 0xd8, 0x0c, 0x04, 0x03, 0xe0, 0x0c, 0x04, 0x03, 0xc0, 0x29, 0x05, 0x04, + 0x50, 0x09, 0x06, 0x04, 0xc0, 0x25, 0x07, 0x05, 0x00, 0x22, 0x09, 0x06, 0xd0, 0x05, 0x00, 0x02, 0xd4, 0x05, 0x00, 0x02, 0xd8, 0x05, 0x00, 0x02, 0xdc, 0x05, 0x00, 0x02, 0xe0, 0x34, 0x01, 0x02, + 0xe4, 0x34, 0x01, 0x02, 0xe8, 0x34, 0x01, 0x02, 0xec, 0x34, 0x01, 0x02, 0xf0, 0x34, 0x01, 0x02, 0xf4, 0x34, 0x01, 0x02, 0xb8, 0x10, 0x02, 0x02, 0xbc, 0x10, 0x02, 0x02, 0xc0, 0x10, 0x02, 0x02, + 0xc4, 0x10, 0x02, 0x02, 0xc8, 0x10, 0x02, 0x02, 0x68, 0x2f, 0x03, 0x03, 0x70, 0x2f, 0x03, 0x03, 0x78, 0x2f, 0x03, 0x03, 0xe8, 0x0c, 0x04, 0x03, 0xf0, 0x0c, 0x04, 0x03, 0xd0, 0x29, 0x05, 0x04, + 0x60, 0x09, 0x06, 0x04, 0xe0, 0x25, 0x07, 0x05, 0x40, 0x22, 0x09, 0x06, 0xe0, 0x05, 0x00, 0x02, 0xe4, 0x05, 0x00, 0x02, 0xe8, 0x05, 0x00, 0x02, 0xec, 0x05, 0x00, 0x02, 0xf8, 0x34, 0x01, 0x02, + 0xfc, 0x34, 0x01, 0x02, 0x00, 0x35, 0x01, 0x02, 0x04, 0x35, 0x01, 0x02, 0x08, 0x35, 0x01, 0x02, 0x0c, 0x35, 0x01, 0x02, 0xcc, 0x10, 0x02, 0x02, 0xd0, 0x10, 0x02, 0x02, 0xd4, 0x10, 0x02, 0x02, + 0xd8, 0x10, 0x02, 0x02, 0xdc, 0x10, 0x02, 0x02, 0x80, 0x2f, 0x03, 0x03, 0x88, 0x2f, 0x03, 0x03, 0x90, 0x2f, 0x03, 0x03, 0xf8, 0x0c, 0x04, 0x03, 0x00, 0x0d, 0x04, 0x03, 0xe0, 0x29, 0x05, 0x04, + 0x70, 0x09, 0x06, 0x04, 0x00, 0x26, 0x07, 0x05, 0x80, 0x22, 0x09, 0x06, 0xf0, 0x05, 0x00, 0x02, 0xf4, 0x05, 0x00, 0x02, 0xf8, 0x05, 0x00, 0x02, 0xfc, 0x05, 0x00, 0x02, 0x10, 0x35, 0x01, 0x02, + 0x14, 0x35, 0x01, 0x02, 0x18, 0x35, 0x01, 0x02, 0x1c, 0x35, 0x01, 0x02, 0x20, 0x35, 0x01, 0x02, 0x24, 0x35, 0x01, 0x02, 0xe0, 0x10, 0x02, 0x02, 0xe4, 0x10, 0x02, 0x02, 0xe8, 0x10, 0x02, 0x02, + 0xec, 0x10, 0x02, 0x02, 0xf0, 0x10, 0x02, 0x02, 0x98, 0x2f, 0x03, 0x03, 0xa0, 0x2f, 0x03, 0x03, 0xa8, 0x2f, 0x03, 0x03, 0x08, 0x0d, 0x04, 0x03, 0x10, 0x0d, 0x04, 0x03, 0xf0, 0x29, 0x05, 0x04, + 0x80, 0x09, 0x06, 0x04, 0x20, 0x26, 0x07, 0x05, 0xc0, 0x22, 0x09, 0x06, 0x00, 0x06, 0x00, 0x02, 0x04, 0x06, 0x00, 0x02, 0x08, 0x06, 0x00, 0x02, 0x0c, 0x06, 0x00, 0x02, 0x28, 0x35, 0x01, 0x02, + 0x2c, 0x35, 0x01, 0x02, 0x30, 0x35, 0x01, 0x02, 0x34, 0x35, 0x01, 0x02, 0x38, 0x35, 0x01, 0x02, 0x3c, 0x35, 0x01, 0x02, 0xf4, 0x10, 0x02, 0x02, 0xf8, 0x10, 0x02, 0x02, 0xfc, 0x10, 0x02, 0x02, + 0x00, 0x11, 0x02, 0x02, 0x04, 0x11, 0x02, 0x02, 0xb0, 0x2f, 0x03, 0x03, 0xb8, 0x2f, 0x03, 0x03, 0xc0, 0x2f, 0x03, 0x03, 0x18, 0x0d, 0x04, 0x03, 0x20, 0x0d, 0x04, 0x03, 0x00, 0x2a, 0x05, 0x04, + 0x90, 0x09, 0x06, 0x04, 0x40, 0x26, 0x07, 0x05, 0x00, 0x23, 0x09, 0x06, 0x10, 0x06, 0x00, 0x02, 0x14, 0x06, 0x00, 0x02, 0x18, 0x06, 0x00, 0x02, 0x1c, 0x06, 0x00, 0x02, 0x40, 0x35, 0x01, 0x02, + 0x44, 0x35, 0x01, 0x02, 0x48, 0x35, 0x01, 0x02, 0x4c, 0x35, 0x01, 0x02, 0x50, 0x35, 0x01, 0x02, 0x54, 0x35, 0x01, 0x02, 0x08, 0x11, 0x02, 0x02, 0x0c, 0x11, 0x02, 0x02, 0x10, 0x11, 0x02, 0x02, + 0x14, 0x11, 0x02, 0x02, 0x18, 0x11, 0x02, 0x02, 0xc8, 0x2f, 0x03, 0x03, 0xd0, 0x2f, 0x03, 0x03, 0xd8, 0x2f, 0x03, 0x03, 0x28, 0x0d, 0x04, 0x03, 0x30, 0x0d, 0x04, 0x03, 0x10, 0x2a, 0x05, 0x04, + 0xa0, 0x09, 0x06, 0x04, 0x60, 0x26, 0x07, 0x05, 0x40, 0x23, 0x09, 0x06, 0x20, 0x06, 0x00, 0x02, 0x24, 0x06, 0x00, 0x02, 0x28, 0x06, 0x00, 0x02, 0x2c, 0x06, 0x00, 0x02, 0x58, 0x35, 0x01, 0x02, + 0x5c, 0x35, 0x01, 0x02, 0x60, 0x35, 0x01, 0x02, 0x64, 0x35, 0x01, 0x02, 0x68, 0x35, 0x01, 0x02, 0x6c, 0x35, 0x01, 0x02, 0x1c, 0x11, 0x02, 0x02, 0x20, 0x11, 0x02, 0x02, 0x24, 0x11, 0x02, 0x02, + 0x28, 0x11, 0x02, 0x02, 0x2c, 0x11, 0x02, 0x02, 0xe0, 0x2f, 0x03, 0x03, 0xe8, 0x2f, 0x03, 0x03, 0xf0, 0x2f, 0x03, 0x03, 0x38, 0x0d, 0x04, 0x03, 0x40, 0x0d, 0x04, 0x03, 0x20, 0x2a, 0x05, 0x04, + 0xb0, 0x09, 0x06, 0x04, 0x80, 0x26, 0x07, 0x05, 0x80, 0x23, 0x09, 0x06, 0x30, 0x06, 0x00, 0x02, 0x34, 0x06, 0x00, 0x02, 0x38, 0x06, 0x00, 0x02, 0x3c, 0x06, 0x00, 0x02, 0x70, 0x35, 0x01, 0x02, + 0x74, 0x35, 0x01, 0x02, 0x78, 0x35, 0x01, 0x02, 0x7c, 0x35, 0x01, 0x02, 0x80, 0x35, 0x01, 0x02, 0x84, 0x35, 0x01, 0x02, 0x30, 0x11, 0x02, 0x02, 0x34, 0x11, 0x02, 0x02, 0x38, 0x11, 0x02, 0x02, + 0x3c, 0x11, 0x02, 0x02, 0x40, 0x11, 0x02, 0x02, 0xf8, 0x2f, 0x03, 0x03, 0x00, 0x30, 0x03, 0x03, 0x08, 0x30, 0x03, 0x03, 0x48, 0x0d, 0x04, 0x03, 0x50, 0x0d, 0x04, 0x03, 0x30, 0x2a, 0x05, 0x04, + 0xc0, 0x09, 0x06, 0x04, 0xa0, 0x26, 0x07, 0x05, 0xc0, 0x23, 0x09, 0x06, 0x40, 0x06, 0x00, 0x02, 0x44, 0x06, 0x00, 0x02, 0x48, 0x06, 0x00, 0x02, 0x4c, 0x06, 0x00, 0x02, 0x88, 0x35, 0x01, 0x02, + 0x8c, 0x35, 0x01, 0x02, 0x90, 0x35, 0x01, 0x02, 0x94, 0x35, 0x01, 0x02, 0x98, 0x35, 0x01, 0x02, 0x9c, 0x35, 0x01, 0x02, 0x44, 0x11, 0x02, 0x02, 0x48, 0x11, 0x02, 0x02, 0x4c, 0x11, 0x02, 0x02, + 0x50, 0x11, 0x02, 0x02, 0x54, 0x11, 0x02, 0x02, 0x10, 0x30, 0x03, 0x03, 0x18, 0x30, 0x03, 0x03, 0x20, 0x30, 0x03, 0x03, 0x58, 0x0d, 0x04, 0x03, 0x60, 0x0d, 0x04, 0x03, 0x40, 0x2a, 0x05, 0x04, + 0xd0, 0x09, 0x06, 0x04, 0xc0, 0x26, 0x07, 0x05, 0x00, 0x24, 0x09, 0x06, 0x50, 0x06, 0x00, 0x02, 0x54, 0x06, 0x00, 0x02, 0x58, 0x06, 0x00, 0x02, 0x5c, 0x06, 0x00, 0x02, 0xa0, 0x35, 0x01, 0x02, + 0xa4, 0x35, 0x01, 0x02, 0xa8, 0x35, 0x01, 0x02, 0xac, 0x35, 0x01, 0x02, 0xb0, 0x35, 0x01, 0x02, 0xb4, 0x35, 0x01, 0x02, 0x58, 0x11, 0x02, 0x02, 0x5c, 0x11, 0x02, 0x02, 0x60, 0x11, 0x02, 0x02, + 0x64, 0x11, 0x02, 0x02, 0x68, 0x11, 0x02, 0x02, 0x28, 0x30, 0x03, 0x03, 0x30, 0x30, 0x03, 0x03, 0x38, 0x30, 0x03, 0x03, 0x68, 0x0d, 0x04, 0x03, 0x70, 0x0d, 0x04, 0x03, 0x50, 0x2a, 0x05, 0x04, + 0xe0, 0x09, 0x06, 0x04, 0xe0, 0x26, 0x07, 0x05, 0x40, 0x24, 0x09, 0x06, 0x60, 0x06, 0x00, 0x02, 0x64, 0x06, 0x00, 0x02, 0x68, 0x06, 0x00, 0x02, 0x6c, 0x06, 0x00, 0x02, 0xb8, 0x35, 0x01, 0x02, + 0xbc, 0x35, 0x01, 0x02, 0xc0, 0x35, 0x01, 0x02, 0xc4, 0x35, 0x01, 0x02, 0xc8, 0x35, 0x01, 0x02, 0xcc, 0x35, 0x01, 0x02, 0x6c, 0x11, 0x02, 0x02, 0x70, 0x11, 0x02, 0x02, 0x74, 0x11, 0x02, 0x02, + 0x78, 0x11, 0x02, 0x02, 0x7c, 0x11, 0x02, 0x02, 0x40, 0x30, 0x03, 0x03, 0x48, 0x30, 0x03, 0x03, 0x50, 0x30, 0x03, 0x03, 0x78, 0x0d, 0x04, 0x03, 0x80, 0x0d, 0x04, 0x03, 0x60, 0x2a, 0x05, 0x04, + 0xf0, 0x09, 0x06, 0x04, 0x00, 0x27, 0x07, 0x05, 0x80, 0x24, 0x09, 0x06, 0x70, 0x06, 0x00, 0x02, 0x74, 0x06, 0x00, 0x02, 0x78, 0x06, 0x00, 0x02, 0x7c, 0x06, 0x00, 0x02, 0xd0, 0x35, 0x01, 0x02, + 0xd4, 0x35, 0x01, 0x02, 0xd8, 0x35, 0x01, 0x02, 0xdc, 0x35, 0x01, 0x02, 0xe0, 0x35, 0x01, 0x02, 0xe4, 0x35, 0x01, 0x02, 0x80, 0x11, 0x02, 0x02, 0x84, 0x11, 0x02, 0x02, 0x88, 0x11, 0x02, 0x02, + 0x8c, 0x11, 0x02, 0x02, 0x90, 0x11, 0x02, 0x02, 0x58, 0x30, 0x03, 0x03, 0x60, 0x30, 0x03, 0x03, 0x68, 0x30, 0x03, 0x03, 0x88, 0x0d, 0x04, 0x03, 0x90, 0x0d, 0x04, 0x03, 0x70, 0x2a, 0x05, 0x04, + 0x00, 0x0a, 0x06, 0x04, 0x20, 0x27, 0x07, 0x05, 0xc0, 0x24, 0x09, 0x06, 0x80, 0x06, 0x00, 0x02, 0x84, 0x06, 0x00, 0x02, 0x88, 0x06, 0x00, 0x02, 0x8c, 0x06, 0x00, 0x02, 0xe8, 0x35, 0x01, 0x02, + 0xec, 0x35, 0x01, 0x02, 0xf0, 0x35, 0x01, 0x02, 0xf4, 0x35, 0x01, 0x02, 0xf8, 0x35, 0x01, 0x02, 0xfc, 0x35, 0x01, 0x02, 0x94, 0x11, 0x02, 0x02, 0x98, 0x11, 0x02, 0x02, 0x9c, 0x11, 0x02, 0x02, + 0xa0, 0x11, 0x02, 0x02, 0xa4, 0x11, 0x02, 0x02, 0x70, 0x30, 0x03, 0x03, 0x78, 0x30, 0x03, 0x03, 0x80, 0x30, 0x03, 0x03, 0x98, 0x0d, 0x04, 0x03, 0xa0, 0x0d, 0x04, 0x03, 0x80, 0x2a, 0x05, 0x04, + 0x10, 0x0a, 0x06, 0x04, 0x40, 0x27, 0x07, 0x05, 0x00, 0x25, 0x09, 0x06, 0x90, 0x06, 0x00, 0x02, 0x94, 0x06, 0x00, 0x02, 0x98, 0x06, 0x00, 0x02, 0x9c, 0x06, 0x00, 0x02, 0x00, 0x36, 0x01, 0x02, + 0x04, 0x36, 0x01, 0x02, 0x08, 0x36, 0x01, 0x02, 0x0c, 0x36, 0x01, 0x02, 0x10, 0x36, 0x01, 0x02, 0x14, 0x36, 0x01, 0x02, 0xa8, 0x11, 0x02, 0x02, 0xac, 0x11, 0x02, 0x02, 0xb0, 0x11, 0x02, 0x02, + 0xb4, 0x11, 0x02, 0x02, 0xb8, 0x11, 0x02, 0x02, 0x88, 0x30, 0x03, 0x03, 0x90, 0x30, 0x03, 0x03, 0x98, 0x30, 0x03, 0x03, 0xa8, 0x0d, 0x04, 0x03, 0xb0, 0x0d, 0x04, 0x03, 0x90, 0x2a, 0x05, 0x04, + 0x20, 0x0a, 0x06, 0x04, 0x60, 0x27, 0x07, 0x05, 0x40, 0x25, 0x09, 0x06, 0xa0, 0x06, 0x00, 0x02, 0xa4, 0x06, 0x00, 0x02, 0xa8, 0x06, 0x00, 0x02, 0xac, 0x06, 0x00, 0x02, 0x18, 0x36, 0x01, 0x02, + 0x1c, 0x36, 0x01, 0x02, 0x20, 0x36, 0x01, 0x02, 0x24, 0x36, 0x01, 0x02, 0x28, 0x36, 0x01, 0x02, 0x2c, 0x36, 0x01, 0x02, 0xbc, 0x11, 0x02, 0x02, 0xc0, 0x11, 0x02, 0x02, 0xc4, 0x11, 0x02, 0x02, + 0xc8, 0x11, 0x02, 0x02, 0xcc, 0x11, 0x02, 0x02, 0xa0, 0x30, 0x03, 0x03, 0xa8, 0x30, 0x03, 0x03, 0xb0, 0x30, 0x03, 0x03, 0xb8, 0x0d, 0x04, 0x03, 0xc0, 0x0d, 0x04, 0x03, 0xa0, 0x2a, 0x05, 0x04, + 0x30, 0x0a, 0x06, 0x04, 0x80, 0x27, 0x07, 0x05, 0x80, 0x25, 0x09, 0x06, 0xb0, 0x06, 0x00, 0x02, 0xb4, 0x06, 0x00, 0x02, 0xb8, 0x06, 0x00, 0x02, 0xbc, 0x06, 0x00, 0x02, 0x30, 0x36, 0x01, 0x02, + 0x34, 0x36, 0x01, 0x02, 0x38, 0x36, 0x01, 0x02, 0x3c, 0x36, 0x01, 0x02, 0x40, 0x36, 0x01, 0x02, 0x44, 0x36, 0x01, 0x02, 0xd0, 0x11, 0x02, 0x02, 0xd4, 0x11, 0x02, 0x02, 0xd8, 0x11, 0x02, 0x02, + 0xdc, 0x11, 0x02, 0x02, 0xe0, 0x11, 0x02, 0x02, 0xb8, 0x30, 0x03, 0x03, 0xc0, 0x30, 0x03, 0x03, 0xc8, 0x30, 0x03, 0x03, 0xc8, 0x0d, 0x04, 0x03, 0xd0, 0x0d, 0x04, 0x03, 0xb0, 0x2a, 0x05, 0x04, + 0x40, 0x0a, 0x06, 0x04, 0xa0, 0x27, 0x07, 0x05, 0xc0, 0x25, 0x09, 0x06, 0xc0, 0x06, 0x00, 0x02, 0xc4, 0x06, 0x00, 0x02, 0xc8, 0x06, 0x00, 0x02, 0xcc, 0x06, 0x00, 0x02, 0x48, 0x36, 0x01, 0x02, + 0x4c, 0x36, 0x01, 0x02, 0x50, 0x36, 0x01, 0x02, 0x54, 0x36, 0x01, 0x02, 0x58, 0x36, 0x01, 0x02, 0x5c, 0x36, 0x01, 0x02, 0xe4, 0x11, 0x02, 0x02, 0xe8, 0x11, 0x02, 0x02, 0xec, 0x11, 0x02, 0x02, + 0xf0, 0x11, 0x02, 0x02, 0xf4, 0x11, 0x02, 0x02, 0xd0, 0x30, 0x03, 0x03, 0xd8, 0x30, 0x03, 0x03, 0xe0, 0x30, 0x03, 0x03, 0xd8, 0x0d, 0x04, 0x03, 0xe0, 0x0d, 0x04, 0x03, 0xc0, 0x2a, 0x05, 0x04, + 0x50, 0x0a, 0x06, 0x04, 0xc0, 0x27, 0x07, 0x05, 0x00, 0x02, 0x0a, 0x06, 0xd0, 0x06, 0x00, 0x02, 0xd4, 0x06, 0x00, 0x02, 0xd8, 0x06, 0x00, 0x02, 0xdc, 0x06, 0x00, 0x02, 0x60, 0x36, 0x01, 0x02, + 0x64, 0x36, 0x01, 0x02, 0x68, 0x36, 0x01, 0x02, 0x6c, 0x36, 0x01, 0x02, 0x70, 0x36, 0x01, 0x02, 0x74, 0x36, 0x01, 0x02, 0xf8, 0x11, 0x02, 0x02, 0xfc, 0x11, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, + 0x04, 0x12, 0x02, 0x02, 0x08, 0x12, 0x02, 0x02, 0xe8, 0x30, 0x03, 0x03, 0xf0, 0x30, 0x03, 0x03, 0xf8, 0x30, 0x03, 0x03, 0xe8, 0x0d, 0x04, 0x03, 0xf0, 0x0d, 0x04, 0x03, 0xd0, 0x2a, 0x05, 0x04, + 0x60, 0x0a, 0x06, 0x04, 0xe0, 0x27, 0x07, 0x05, 0x40, 0x02, 0x0a, 0x06, 0xe0, 0x06, 0x00, 0x02, 0xe4, 0x06, 0x00, 0x02, 0xe8, 0x06, 0x00, 0x02, 0xec, 0x06, 0x00, 0x02, 0x78, 0x36, 0x01, 0x02, + 0x7c, 0x36, 0x01, 0x02, 0x80, 0x36, 0x01, 0x02, 0x84, 0x36, 0x01, 0x02, 0x88, 0x36, 0x01, 0x02, 0x8c, 0x36, 0x01, 0x02, 0x0c, 0x12, 0x02, 0x02, 0x10, 0x12, 0x02, 0x02, 0x14, 0x12, 0x02, 0x02, + 0x18, 0x12, 0x02, 0x02, 0x1c, 0x12, 0x02, 0x02, 0x00, 0x31, 0x03, 0x03, 0x08, 0x31, 0x03, 0x03, 0x10, 0x31, 0x03, 0x03, 0xf8, 0x0d, 0x04, 0x03, 0x00, 0x0e, 0x04, 0x03, 0xe0, 0x2a, 0x05, 0x04, + 0x70, 0x0a, 0x06, 0x04, 0x00, 0x28, 0x07, 0x05, 0x80, 0x02, 0x0a, 0x06, 0xf0, 0x06, 0x00, 0x02, 0xf4, 0x06, 0x00, 0x02, 0xf8, 0x06, 0x00, 0x02, 0xfc, 0x06, 0x00, 0x02, 0x90, 0x36, 0x01, 0x02, + 0x94, 0x36, 0x01, 0x02, 0x98, 0x36, 0x01, 0x02, 0x9c, 0x36, 0x01, 0x02, 0xa0, 0x36, 0x01, 0x02, 0xa4, 0x36, 0x01, 0x02, 0x20, 0x12, 0x02, 0x02, 0x24, 0x12, 0x02, 0x02, 0x28, 0x12, 0x02, 0x02, + 0x2c, 0x12, 0x02, 0x02, 0x30, 0x12, 0x02, 0x02, 0x18, 0x31, 0x03, 0x03, 0x20, 0x31, 0x03, 0x03, 0x28, 0x31, 0x03, 0x03, 0x08, 0x0e, 0x04, 0x03, 0x10, 0x0e, 0x04, 0x03, 0xf0, 0x2a, 0x05, 0x04, + 0x80, 0x0a, 0x06, 0x04, 0x20, 0x28, 0x07, 0x05, 0xc0, 0x02, 0x0a, 0x06, 0x00, 0x07, 0x00, 0x02, 0x04, 0x07, 0x00, 0x02, 0x08, 0x07, 0x00, 0x02, 0x0c, 0x07, 0x00, 0x02, 0xa8, 0x36, 0x01, 0x02, + 0xac, 0x36, 0x01, 0x02, 0xb0, 0x36, 0x01, 0x02, 0xb4, 0x36, 0x01, 0x02, 0xb8, 0x36, 0x01, 0x02, 0xbc, 0x36, 0x01, 0x02, 0x34, 0x12, 0x02, 0x02, 0x38, 0x12, 0x02, 0x02, 0x3c, 0x12, 0x02, 0x02, + 0x40, 0x12, 0x02, 0x02, 0x44, 0x12, 0x02, 0x02, 0x30, 0x31, 0x03, 0x03, 0x38, 0x31, 0x03, 0x03, 0x40, 0x31, 0x03, 0x03, 0x18, 0x0e, 0x04, 0x03, 0x20, 0x0e, 0x04, 0x03, 0x00, 0x2b, 0x05, 0x04, + 0x90, 0x0a, 0x06, 0x04, 0x40, 0x28, 0x07, 0x05, 0x00, 0x03, 0x0a, 0x06, 0x10, 0x07, 0x00, 0x02, 0x14, 0x07, 0x00, 0x02, 0x18, 0x07, 0x00, 0x02, 0x1c, 0x07, 0x00, 0x02, 0xc0, 0x36, 0x01, 0x02, + 0xc4, 0x36, 0x01, 0x02, 0xc8, 0x36, 0x01, 0x02, 0xcc, 0x36, 0x01, 0x02, 0xd0, 0x36, 0x01, 0x02, 0xd4, 0x36, 0x01, 0x02, 0x48, 0x12, 0x02, 0x02, 0x4c, 0x12, 0x02, 0x02, 0x50, 0x12, 0x02, 0x02, + 0x54, 0x12, 0x02, 0x02, 0x58, 0x12, 0x02, 0x02, 0x48, 0x31, 0x03, 0x03, 0x50, 0x31, 0x03, 0x03, 0x28, 0x0e, 0x04, 0x03, 0x30, 0x0e, 0x04, 0x03, 0x38, 0x0e, 0x04, 0x03, 0x10, 0x2b, 0x05, 0x04, + 0xa0, 0x0a, 0x06, 0x04, 0x60, 0x28, 0x07, 0x05, 0x40, 0x03, 0x0a, 0x06, 0x20, 0x07, 0x00, 0x02, 0x24, 0x07, 0x00, 0x02, 0x28, 0x07, 0x00, 0x02, 0x2c, 0x07, 0x00, 0x02, 0xd8, 0x36, 0x01, 0x02, + 0xdc, 0x36, 0x01, 0x02, 0xe0, 0x36, 0x01, 0x02, 0xe4, 0x36, 0x01, 0x02, 0xe8, 0x36, 0x01, 0x02, 0xec, 0x36, 0x01, 0x02, 0x5c, 0x12, 0x02, 0x02, 0x60, 0x12, 0x02, 0x02, 0x64, 0x12, 0x02, 0x02, + 0x68, 0x12, 0x02, 0x02, 0x58, 0x31, 0x03, 0x03, 0x60, 0x31, 0x03, 0x03, 0x68, 0x31, 0x03, 0x03, 0x40, 0x0e, 0x04, 0x03, 0x48, 0x0e, 0x04, 0x03, 0x50, 0x0e, 0x04, 0x03, 0x20, 0x2b, 0x05, 0x04, + 0xb0, 0x0a, 0x06, 0x04, 0x80, 0x28, 0x07, 0x05, 0x80, 0x03, 0x0a, 0x06, 0x30, 0x07, 0x00, 0x02, 0x34, 0x07, 0x00, 0x02, 0x38, 0x07, 0x00, 0x02, 0x3c, 0x07, 0x00, 0x02, 0xf0, 0x36, 0x01, 0x02, + 0xf4, 0x36, 0x01, 0x02, 0xf8, 0x36, 0x01, 0x02, 0xfc, 0x36, 0x01, 0x02, 0x00, 0x37, 0x01, 0x02, 0x04, 0x37, 0x01, 0x02, 0x6c, 0x12, 0x02, 0x02, 0x70, 0x12, 0x02, 0x02, 0x74, 0x12, 0x02, 0x02, + 0x78, 0x12, 0x02, 0x02, 0x70, 0x31, 0x03, 0x03, 0x78, 0x31, 0x03, 0x03, 0x80, 0x31, 0x03, 0x03, 0x58, 0x0e, 0x04, 0x03, 0x60, 0x0e, 0x04, 0x03, 0x68, 0x0e, 0x04, 0x03, 0x30, 0x2b, 0x05, 0x04, + 0xc0, 0x0a, 0x06, 0x04, 0xa0, 0x28, 0x07, 0x05, 0xc0, 0x03, 0x0a, 0x06, 0x40, 0x07, 0x00, 0x02, 0x44, 0x07, 0x00, 0x02, 0x48, 0x07, 0x00, 0x02, 0x4c, 0x07, 0x00, 0x02, 0x08, 0x37, 0x01, 0x02, + 0x0c, 0x37, 0x01, 0x02, 0x10, 0x37, 0x01, 0x02, 0x14, 0x37, 0x01, 0x02, 0x18, 0x37, 0x01, 0x02, 0x1c, 0x37, 0x01, 0x02, 0x7c, 0x12, 0x02, 0x02, 0x80, 0x12, 0x02, 0x02, 0x84, 0x12, 0x02, 0x02, + 0x88, 0x12, 0x02, 0x02, 0x88, 0x31, 0x03, 0x03, 0x90, 0x31, 0x03, 0x03, 0x98, 0x31, 0x03, 0x03, 0x70, 0x0e, 0x04, 0x03, 0x78, 0x0e, 0x04, 0x03, 0x80, 0x0e, 0x04, 0x03, 0x40, 0x2b, 0x05, 0x04, + 0xd0, 0x0a, 0x06, 0x04, 0xc0, 0x28, 0x07, 0x05, 0x00, 0x04, 0x0a, 0x06, 0x50, 0x07, 0x00, 0x02, 0x54, 0x07, 0x00, 0x02, 0x58, 0x07, 0x00, 0x02, 0x5c, 0x07, 0x00, 0x02, 0x20, 0x37, 0x01, 0x02, + 0x24, 0x37, 0x01, 0x02, 0x28, 0x37, 0x01, 0x02, 0x2c, 0x37, 0x01, 0x02, 0x30, 0x37, 0x01, 0x02, 0x34, 0x37, 0x01, 0x02, 0x8c, 0x12, 0x02, 0x02, 0x90, 0x12, 0x02, 0x02, 0x94, 0x12, 0x02, 0x02, + 0x98, 0x12, 0x02, 0x02, 0xa0, 0x31, 0x03, 0x03, 0xa8, 0x31, 0x03, 0x03, 0xb0, 0x31, 0x03, 0x03, 0x88, 0x0e, 0x04, 0x03, 0x90, 0x0e, 0x04, 0x03, 0x98, 0x0e, 0x04, 0x03, 0x50, 0x2b, 0x05, 0x04, + 0xe0, 0x0a, 0x06, 0x04, 0xe0, 0x28, 0x07, 0x05, 0x40, 0x04, 0x0a, 0x06, 0x60, 0x07, 0x00, 0x02, 0x64, 0x07, 0x00, 0x02, 0x68, 0x07, 0x00, 0x02, 0x6c, 0x07, 0x00, 0x02, 0x38, 0x37, 0x01, 0x02, + 0x3c, 0x37, 0x01, 0x02, 0x40, 0x37, 0x01, 0x02, 0x44, 0x37, 0x01, 0x02, 0x48, 0x37, 0x01, 0x02, 0x4c, 0x37, 0x01, 0x02, 0x9c, 0x12, 0x02, 0x02, 0xa0, 0x12, 0x02, 0x02, 0xa4, 0x12, 0x02, 0x02, + 0xa8, 0x12, 0x02, 0x02, 0xb8, 0x31, 0x03, 0x03, 0xc0, 0x31, 0x03, 0x03, 0xc8, 0x31, 0x03, 0x03, 0xa0, 0x0e, 0x04, 0x03, 0xa8, 0x0e, 0x04, 0x03, 0x60, 0x2b, 0x05, 0x04, 0x70, 0x2b, 0x05, 0x04, + 0xf0, 0x0a, 0x06, 0x04, 0x00, 0x29, 0x07, 0x05, 0x80, 0x04, 0x0a, 0x06, 0x70, 0x07, 0x00, 0x02, 0x74, 0x07, 0x00, 0x02, 0x78, 0x07, 0x00, 0x02, 0x7c, 0x07, 0x00, 0x02, 0x50, 0x37, 0x01, 0x02, + 0x54, 0x37, 0x01, 0x02, 0x58, 0x37, 0x01, 0x02, 0x5c, 0x37, 0x01, 0x02, 0x60, 0x37, 0x01, 0x02, 0x64, 0x37, 0x01, 0x02, 0xac, 0x12, 0x02, 0x02, 0xb0, 0x12, 0x02, 0x02, 0xb4, 0x12, 0x02, 0x02, + 0xb8, 0x12, 0x02, 0x02, 0xd0, 0x31, 0x03, 0x03, 0xd8, 0x31, 0x03, 0x03, 0xe0, 0x31, 0x03, 0x03, 0xb0, 0x0e, 0x04, 0x03, 0xb8, 0x0e, 0x04, 0x03, 0x80, 0x2b, 0x05, 0x04, 0x90, 0x2b, 0x05, 0x04, + 0x00, 0x0b, 0x06, 0x04, 0x20, 0x29, 0x07, 0x05, 0xc0, 0x04, 0x0a, 0x06, 0x80, 0x07, 0x00, 0x02, 0x84, 0x07, 0x00, 0x02, 0x88, 0x07, 0x00, 0x02, 0x8c, 0x07, 0x00, 0x02, 0x68, 0x37, 0x01, 0x02, + 0x6c, 0x37, 0x01, 0x02, 0x70, 0x37, 0x01, 0x02, 0x74, 0x37, 0x01, 0x02, 0x78, 0x37, 0x01, 0x02, 0x7c, 0x37, 0x01, 0x02, 0xbc, 0x12, 0x02, 0x02, 0xc0, 0x12, 0x02, 0x02, 0xc4, 0x12, 0x02, 0x02, + 0xc8, 0x12, 0x02, 0x02, 0xe8, 0x31, 0x03, 0x03, 0xf0, 0x31, 0x03, 0x03, 0xf8, 0x31, 0x03, 0x03, 0xc0, 0x0e, 0x04, 0x03, 0xc8, 0x0e, 0x04, 0x03, 0xa0, 0x2b, 0x05, 0x04, 0xb0, 0x2b, 0x05, 0x04, + 0x10, 0x0b, 0x06, 0x04, 0x40, 0x29, 0x07, 0x05, 0x00, 0x05, 0x0a, 0x06, 0x90, 0x07, 0x00, 0x02, 0x94, 0x07, 0x00, 0x02, 0x98, 0x07, 0x00, 0x02, 0x9c, 0x07, 0x00, 0x02, 0x80, 0x37, 0x01, 0x02, + 0x84, 0x37, 0x01, 0x02, 0x88, 0x37, 0x01, 0x02, 0x8c, 0x37, 0x01, 0x02, 0x90, 0x37, 0x01, 0x02, 0x94, 0x37, 0x01, 0x02, 0xcc, 0x12, 0x02, 0x02, 0xd0, 0x12, 0x02, 0x02, 0xd4, 0x12, 0x02, 0x02, + 0xd8, 0x12, 0x02, 0x02, 0x00, 0x32, 0x03, 0x03, 0x08, 0x32, 0x03, 0x03, 0x10, 0x32, 0x03, 0x03, 0xd0, 0x0e, 0x04, 0x03, 0xd8, 0x0e, 0x04, 0x03, 0xc0, 0x2b, 0x05, 0x04, 0xd0, 0x2b, 0x05, 0x04, + 0x20, 0x0b, 0x06, 0x04, 0x60, 0x29, 0x07, 0x05, 0x40, 0x05, 0x0a, 0x06, 0xa0, 0x07, 0x00, 0x02, 0xa4, 0x07, 0x00, 0x02, 0xa8, 0x07, 0x00, 0x02, 0xac, 0x07, 0x00, 0x02, 0x98, 0x37, 0x01, 0x02, + 0x9c, 0x37, 0x01, 0x02, 0xa0, 0x37, 0x01, 0x02, 0xa4, 0x37, 0x01, 0x02, 0xa8, 0x37, 0x01, 0x02, 0xac, 0x37, 0x01, 0x02, 0xdc, 0x12, 0x02, 0x02, 0xe0, 0x12, 0x02, 0x02, 0xe4, 0x12, 0x02, 0x02, + 0xe8, 0x12, 0x02, 0x02, 0x18, 0x32, 0x03, 0x03, 0x20, 0x32, 0x03, 0x03, 0x28, 0x32, 0x03, 0x03, 0xe0, 0x0e, 0x04, 0x03, 0xe8, 0x0e, 0x04, 0x03, 0xe0, 0x2b, 0x05, 0x04, 0xf0, 0x2b, 0x05, 0x04, + 0x30, 0x0b, 0x06, 0x04, 0x80, 0x29, 0x07, 0x05, 0x80, 0x05, 0x0a, 0x06, 0xb0, 0x07, 0x00, 0x02, 0xb4, 0x07, 0x00, 0x02, 0xb8, 0x07, 0x00, 0x02, 0xbc, 0x07, 0x00, 0x02, 0xb0, 0x37, 0x01, 0x02, + 0xb4, 0x37, 0x01, 0x02, 0xb8, 0x37, 0x01, 0x02, 0xbc, 0x37, 0x01, 0x02, 0xc0, 0x37, 0x01, 0x02, 0xc4, 0x37, 0x01, 0x02, 0xec, 0x12, 0x02, 0x02, 0xf0, 0x12, 0x02, 0x02, 0xf4, 0x12, 0x02, 0x02, + 0xf8, 0x12, 0x02, 0x02, 0x30, 0x32, 0x03, 0x03, 0x38, 0x32, 0x03, 0x03, 0x40, 0x32, 0x03, 0x03, 0xf0, 0x0e, 0x04, 0x03, 0xf8, 0x0e, 0x04, 0x03, 0x00, 0x2c, 0x05, 0x04, 0x10, 0x2c, 0x05, 0x04, + 0x40, 0x0b, 0x06, 0x04, 0xa0, 0x29, 0x07, 0x05, 0xc0, 0x05, 0x0a, 0x06, 0xc0, 0x07, 0x00, 0x02, 0xc4, 0x07, 0x00, 0x02, 0xc8, 0x07, 0x00, 0x02, 0xcc, 0x07, 0x00, 0x02, 0xc8, 0x37, 0x01, 0x02, + 0xcc, 0x37, 0x01, 0x02, 0xd0, 0x37, 0x01, 0x02, 0xd4, 0x37, 0x01, 0x02, 0xd8, 0x37, 0x01, 0x02, 0xdc, 0x37, 0x01, 0x02, 0xfc, 0x12, 0x02, 0x02, 0x00, 0x13, 0x02, 0x02, 0x04, 0x13, 0x02, 0x02, + 0x08, 0x13, 0x02, 0x02, 0x48, 0x32, 0x03, 0x03, 0x50, 0x32, 0x03, 0x03, 0x58, 0x32, 0x03, 0x03, 0x00, 0x0f, 0x04, 0x03, 0x08, 0x0f, 0x04, 0x03, 0x20, 0x2c, 0x05, 0x04, 0x30, 0x2c, 0x05, 0x04, + 0x50, 0x0b, 0x06, 0x04, 0xc0, 0x29, 0x07, 0x05, 0x00, 0x06, 0x0a, 0x06, 0xd0, 0x07, 0x00, 0x02, 0xd4, 0x07, 0x00, 0x02, 0xd8, 0x07, 0x00, 0x02, 0xdc, 0x07, 0x00, 0x02, 0xe0, 0x37, 0x01, 0x02, + 0xe4, 0x37, 0x01, 0x02, 0xe8, 0x37, 0x01, 0x02, 0xec, 0x37, 0x01, 0x02, 0xf0, 0x37, 0x01, 0x02, 0xf4, 0x37, 0x01, 0x02, 0x0c, 0x13, 0x02, 0x02, 0x10, 0x13, 0x02, 0x02, 0x14, 0x13, 0x02, 0x02, + 0x18, 0x13, 0x02, 0x02, 0x60, 0x32, 0x03, 0x03, 0x68, 0x32, 0x03, 0x03, 0x70, 0x32, 0x03, 0x03, 0x10, 0x0f, 0x04, 0x03, 0x18, 0x0f, 0x04, 0x03, 0x40, 0x2c, 0x05, 0x04, 0x50, 0x2c, 0x05, 0x04, + 0x60, 0x0b, 0x06, 0x04, 0xe0, 0x29, 0x07, 0x05, 0x40, 0x06, 0x0a, 0x06, 0xe0, 0x07, 0x00, 0x02, 0xe4, 0x07, 0x00, 0x02, 0xe8, 0x07, 0x00, 0x02, 0xec, 0x07, 0x00, 0x02, 0xf8, 0x37, 0x01, 0x02, + 0xfc, 0x37, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0x04, 0x38, 0x01, 0x02, 0x08, 0x38, 0x01, 0x02, 0x0c, 0x38, 0x01, 0x02, 0x1c, 0x13, 0x02, 0x02, 0x20, 0x13, 0x02, 0x02, 0x24, 0x13, 0x02, 0x02, + 0x28, 0x13, 0x02, 0x02, 0x78, 0x32, 0x03, 0x03, 0x80, 0x32, 0x03, 0x03, 0x88, 0x32, 0x03, 0x03, 0x20, 0x0f, 0x04, 0x03, 0x28, 0x0f, 0x04, 0x03, 0x60, 0x2c, 0x05, 0x04, 0x70, 0x2c, 0x05, 0x04, + 0x70, 0x0b, 0x06, 0x04, 0xa0, 0x05, 0x08, 0x05, 0x80, 0x06, 0x0a, 0x06, 0xf0, 0x07, 0x00, 0x02, 0xf4, 0x07, 0x00, 0x02, 0xf8, 0x07, 0x00, 0x02, 0xfc, 0x07, 0x00, 0x02, 0x10, 0x38, 0x01, 0x02, + 0x14, 0x38, 0x01, 0x02, 0x18, 0x38, 0x01, 0x02, 0x1c, 0x38, 0x01, 0x02, 0x20, 0x38, 0x01, 0x02, 0x24, 0x38, 0x01, 0x02, 0x2c, 0x13, 0x02, 0x02, 0x30, 0x13, 0x02, 0x02, 0x34, 0x13, 0x02, 0x02, + 0x38, 0x13, 0x02, 0x02, 0x90, 0x32, 0x03, 0x03, 0x98, 0x32, 0x03, 0x03, 0xa0, 0x32, 0x03, 0x03, 0x30, 0x0f, 0x04, 0x03, 0x38, 0x0f, 0x04, 0x03, 0x80, 0x2c, 0x05, 0x04, 0x90, 0x2c, 0x05, 0x04, + 0x80, 0x0b, 0x06, 0x04, 0xc0, 0x05, 0x08, 0x05, 0x00, 0x1b, 0x0b, 0x07, 0x00, 0x08, 0x00, 0x02, 0x04, 0x08, 0x00, 0x02, 0x08, 0x08, 0x00, 0x02, 0x0c, 0x08, 0x00, 0x02, 0x28, 0x38, 0x01, 0x02, + 0x2c, 0x38, 0x01, 0x02, 0x30, 0x38, 0x01, 0x02, 0x34, 0x38, 0x01, 0x02, 0x38, 0x38, 0x01, 0x02, 0x3c, 0x38, 0x01, 0x02, 0x3c, 0x13, 0x02, 0x02, 0x40, 0x13, 0x02, 0x02, 0x44, 0x13, 0x02, 0x02, + 0x48, 0x13, 0x02, 0x02, 0xa8, 0x32, 0x03, 0x03, 0xb0, 0x32, 0x03, 0x03, 0xb8, 0x32, 0x03, 0x03, 0x40, 0x0f, 0x04, 0x03, 0x48, 0x0f, 0x04, 0x03, 0xa0, 0x2c, 0x05, 0x04, 0xb0, 0x2c, 0x05, 0x04, + 0x90, 0x0b, 0x06, 0x04, 0xe0, 0x05, 0x08, 0x05, 0x80, 0x1b, 0x0b, 0x07, 0x10, 0x08, 0x00, 0x02, 0x14, 0x08, 0x00, 0x02, 0x18, 0x08, 0x00, 0x02, 0x1c, 0x08, 0x00, 0x02, 0x40, 0x38, 0x01, 0x02, + 0x44, 0x38, 0x01, 0x02, 0x48, 0x38, 0x01, 0x02, 0x4c, 0x38, 0x01, 0x02, 0x50, 0x38, 0x01, 0x02, 0x54, 0x38, 0x01, 0x02, 0x4c, 0x13, 0x02, 0x02, 0x50, 0x13, 0x02, 0x02, 0x54, 0x13, 0x02, 0x02, + 0x58, 0x13, 0x02, 0x02, 0xc0, 0x32, 0x03, 0x03, 0xc8, 0x32, 0x03, 0x03, 0xd0, 0x32, 0x03, 0x03, 0x50, 0x0f, 0x04, 0x03, 0x58, 0x0f, 0x04, 0x03, 0xc0, 0x2c, 0x05, 0x04, 0xd0, 0x2c, 0x05, 0x04, + 0xa0, 0x0b, 0x06, 0x04, 0x00, 0x06, 0x08, 0x05, 0x00, 0x1c, 0x0b, 0x07, 0x20, 0x08, 0x00, 0x02, 0x24, 0x08, 0x00, 0x02, 0x28, 0x08, 0x00, 0x02, 0x2c, 0x08, 0x00, 0x02, 0x58, 0x38, 0x01, 0x02, + 0x5c, 0x38, 0x01, 0x02, 0x60, 0x38, 0x01, 0x02, 0x64, 0x38, 0x01, 0x02, 0x68, 0x38, 0x01, 0x02, 0x6c, 0x38, 0x01, 0x02, 0x5c, 0x13, 0x02, 0x02, 0x60, 0x13, 0x02, 0x02, 0x64, 0x13, 0x02, 0x02, + 0x68, 0x13, 0x02, 0x02, 0xd8, 0x32, 0x03, 0x03, 0xe0, 0x32, 0x03, 0x03, 0xe8, 0x32, 0x03, 0x03, 0x60, 0x0f, 0x04, 0x03, 0x68, 0x0f, 0x04, 0x03, 0xe0, 0x2c, 0x05, 0x04, 0xf0, 0x2c, 0x05, 0x04, + 0xb0, 0x0b, 0x06, 0x04, 0x20, 0x06, 0x08, 0x05, 0x80, 0x1c, 0x0b, 0x07, 0x30, 0x08, 0x00, 0x02, 0x34, 0x08, 0x00, 0x02, 0x38, 0x08, 0x00, 0x02, 0x3c, 0x08, 0x00, 0x02, 0x70, 0x38, 0x01, 0x02, + 0x74, 0x38, 0x01, 0x02, 0x78, 0x38, 0x01, 0x02, 0x7c, 0x38, 0x01, 0x02, 0x80, 0x38, 0x01, 0x02, 0x84, 0x38, 0x01, 0x02, 0x6c, 0x13, 0x02, 0x02, 0x70, 0x13, 0x02, 0x02, 0x74, 0x13, 0x02, 0x02, + 0x78, 0x13, 0x02, 0x02, 0xf0, 0x32, 0x03, 0x03, 0xf8, 0x32, 0x03, 0x03, 0x00, 0x33, 0x03, 0x03, 0x70, 0x0f, 0x04, 0x03, 0x78, 0x0f, 0x04, 0x03, 0x00, 0x2d, 0x05, 0x04, 0x10, 0x2d, 0x05, 0x04, + 0xc0, 0x0b, 0x06, 0x04, 0x40, 0x06, 0x08, 0x05, 0x00, 0x1d, 0x0b, 0x07, 0x40, 0x08, 0x00, 0x02, 0x44, 0x08, 0x00, 0x02, 0x48, 0x08, 0x00, 0x02, 0x4c, 0x08, 0x00, 0x02, 0x88, 0x38, 0x01, 0x02, + 0x8c, 0x38, 0x01, 0x02, 0x90, 0x38, 0x01, 0x02, 0x94, 0x38, 0x01, 0x02, 0x98, 0x38, 0x01, 0x02, 0x9c, 0x38, 0x01, 0x02, 0x7c, 0x13, 0x02, 0x02, 0x80, 0x13, 0x02, 0x02, 0x84, 0x13, 0x02, 0x02, + 0x88, 0x13, 0x02, 0x02, 0x08, 0x33, 0x03, 0x03, 0x10, 0x33, 0x03, 0x03, 0x18, 0x33, 0x03, 0x03, 0x80, 0x0f, 0x04, 0x03, 0x88, 0x0f, 0x04, 0x03, 0x20, 0x2d, 0x05, 0x04, 0x30, 0x2d, 0x05, 0x04, + 0xd0, 0x0b, 0x06, 0x04, 0x60, 0x06, 0x08, 0x05, 0x80, 0x1d, 0x0b, 0x07, 0x50, 0x08, 0x00, 0x02, 0x54, 0x08, 0x00, 0x02, 0x58, 0x08, 0x00, 0x02, 0x5c, 0x08, 0x00, 0x02, 0xa0, 0x38, 0x01, 0x02, + 0xa4, 0x38, 0x01, 0x02, 0xa8, 0x38, 0x01, 0x02, 0xac, 0x38, 0x01, 0x02, 0xb0, 0x38, 0x01, 0x02, 0xb4, 0x38, 0x01, 0x02, 0x8c, 0x13, 0x02, 0x02, 0x90, 0x13, 0x02, 0x02, 0x94, 0x13, 0x02, 0x02, + 0x98, 0x13, 0x02, 0x02, 0x20, 0x33, 0x03, 0x03, 0x28, 0x33, 0x03, 0x03, 0x30, 0x33, 0x03, 0x03, 0x90, 0x0f, 0x04, 0x03, 0x98, 0x0f, 0x04, 0x03, 0x40, 0x2d, 0x05, 0x04, 0x50, 0x2d, 0x05, 0x04, + 0xe0, 0x0b, 0x06, 0x04, 0x80, 0x06, 0x08, 0x05, 0x00, 0x1e, 0x0b, 0x07, 0x60, 0x08, 0x00, 0x02, 0x64, 0x08, 0x00, 0x02, 0x68, 0x08, 0x00, 0x02, 0x6c, 0x08, 0x00, 0x02, 0xb8, 0x38, 0x01, 0x02, + 0xbc, 0x38, 0x01, 0x02, 0xc0, 0x38, 0x01, 0x02, 0xc4, 0x38, 0x01, 0x02, 0xc8, 0x38, 0x01, 0x02, 0xcc, 0x38, 0x01, 0x02, 0x9c, 0x13, 0x02, 0x02, 0xa0, 0x13, 0x02, 0x02, 0xa4, 0x13, 0x02, 0x02, + 0xa8, 0x13, 0x02, 0x02, 0x38, 0x33, 0x03, 0x03, 0x40, 0x33, 0x03, 0x03, 0x48, 0x33, 0x03, 0x03, 0xa0, 0x0f, 0x04, 0x03, 0xa8, 0x0f, 0x04, 0x03, 0x60, 0x2d, 0x05, 0x04, 0x70, 0x2d, 0x05, 0x04, + 0xf0, 0x0b, 0x06, 0x04, 0xa0, 0x06, 0x08, 0x05, 0x80, 0x1e, 0x0b, 0x07, 0x70, 0x08, 0x00, 0x02, 0x74, 0x08, 0x00, 0x02, 0x78, 0x08, 0x00, 0x02, 0x7c, 0x08, 0x00, 0x02, 0xd0, 0x38, 0x01, 0x02, + 0xd4, 0x38, 0x01, 0x02, 0xd8, 0x38, 0x01, 0x02, 0xdc, 0x38, 0x01, 0x02, 0xe0, 0x38, 0x01, 0x02, 0xe4, 0x38, 0x01, 0x02, 0xac, 0x13, 0x02, 0x02, 0xb0, 0x13, 0x02, 0x02, 0xb4, 0x13, 0x02, 0x02, + 0xb8, 0x13, 0x02, 0x02, 0x50, 0x33, 0x03, 0x03, 0x58, 0x33, 0x03, 0x03, 0x60, 0x33, 0x03, 0x03, 0xb0, 0x0f, 0x04, 0x03, 0xb8, 0x0f, 0x04, 0x03, 0x80, 0x2d, 0x05, 0x04, 0x90, 0x2d, 0x05, 0x04, + 0x00, 0x0c, 0x06, 0x04, 0xc0, 0x06, 0x08, 0x05, 0x00, 0x1f, 0x0b, 0x07, 0x80, 0x08, 0x00, 0x02, 0x84, 0x08, 0x00, 0x02, 0x88, 0x08, 0x00, 0x02, 0x8c, 0x08, 0x00, 0x02, 0xe8, 0x38, 0x01, 0x02, + 0xec, 0x38, 0x01, 0x02, 0xf0, 0x38, 0x01, 0x02, 0xf4, 0x38, 0x01, 0x02, 0xf8, 0x38, 0x01, 0x02, 0xfc, 0x38, 0x01, 0x02, 0xbc, 0x13, 0x02, 0x02, 0xc0, 0x13, 0x02, 0x02, 0xc4, 0x13, 0x02, 0x02, + 0xc8, 0x13, 0x02, 0x02, 0x68, 0x33, 0x03, 0x03, 0x70, 0x33, 0x03, 0x03, 0x78, 0x33, 0x03, 0x03, 0xc0, 0x0f, 0x04, 0x03, 0xc8, 0x0f, 0x04, 0x03, 0xa0, 0x2d, 0x05, 0x04, 0xb0, 0x2d, 0x05, 0x04, + 0x10, 0x0c, 0x06, 0x04, 0xe0, 0x06, 0x08, 0x05, 0x80, 0x1f, 0x0b, 0x07, 0x90, 0x08, 0x00, 0x02, 0x94, 0x08, 0x00, 0x02, 0x98, 0x08, 0x00, 0x02, 0x9c, 0x08, 0x00, 0x02, 0x00, 0x39, 0x01, 0x02, + 0x04, 0x39, 0x01, 0x02, 0x08, 0x39, 0x01, 0x02, 0x0c, 0x39, 0x01, 0x02, 0x10, 0x39, 0x01, 0x02, 0x14, 0x39, 0x01, 0x02, 0xcc, 0x13, 0x02, 0x02, 0xd0, 0x13, 0x02, 0x02, 0xd4, 0x13, 0x02, 0x02, + 0xd8, 0x13, 0x02, 0x02, 0x80, 0x33, 0x03, 0x03, 0x88, 0x33, 0x03, 0x03, 0x90, 0x33, 0x03, 0x03, 0xd0, 0x0f, 0x04, 0x03, 0xd8, 0x0f, 0x04, 0x03, 0xc0, 0x2d, 0x05, 0x04, 0xd0, 0x2d, 0x05, 0x04, + 0x20, 0x0c, 0x06, 0x04, 0x00, 0x07, 0x08, 0x05, 0x00, 0x20, 0x0b, 0x07, 0xa0, 0x08, 0x00, 0x02, 0xa4, 0x08, 0x00, 0x02, 0xa8, 0x08, 0x00, 0x02, 0xac, 0x08, 0x00, 0x02, 0x18, 0x39, 0x01, 0x02, + 0x1c, 0x39, 0x01, 0x02, 0x20, 0x39, 0x01, 0x02, 0x24, 0x39, 0x01, 0x02, 0x28, 0x39, 0x01, 0x02, 0x2c, 0x39, 0x01, 0x02, 0xdc, 0x13, 0x02, 0x02, 0xe0, 0x13, 0x02, 0x02, 0xe4, 0x13, 0x02, 0x02, + 0xe8, 0x13, 0x02, 0x02, 0x98, 0x33, 0x03, 0x03, 0xa0, 0x33, 0x03, 0x03, 0xa8, 0x33, 0x03, 0x03, 0xe0, 0x0f, 0x04, 0x03, 0xe8, 0x0f, 0x04, 0x03, 0xe0, 0x2d, 0x05, 0x04, 0xf0, 0x2d, 0x05, 0x04, + 0x30, 0x0c, 0x06, 0x04, 0x20, 0x07, 0x08, 0x05, 0x80, 0x20, 0x0b, 0x07, 0xb0, 0x08, 0x00, 0x02, 0xb4, 0x08, 0x00, 0x02, 0xb8, 0x08, 0x00, 0x02, 0xbc, 0x08, 0x00, 0x02, 0x30, 0x39, 0x01, 0x02, + 0x34, 0x39, 0x01, 0x02, 0x38, 0x39, 0x01, 0x02, 0x3c, 0x39, 0x01, 0x02, 0x40, 0x39, 0x01, 0x02, 0x44, 0x39, 0x01, 0x02, 0xec, 0x13, 0x02, 0x02, 0xf0, 0x13, 0x02, 0x02, 0xf4, 0x13, 0x02, 0x02, + 0xf8, 0x13, 0x02, 0x02, 0xb0, 0x33, 0x03, 0x03, 0xb8, 0x33, 0x03, 0x03, 0xc0, 0x33, 0x03, 0x03, 0xf0, 0x0f, 0x04, 0x03, 0xf8, 0x0f, 0x04, 0x03, 0x00, 0x2e, 0x05, 0x04, 0x10, 0x2e, 0x05, 0x04, + 0x40, 0x0c, 0x06, 0x04, 0x40, 0x07, 0x08, 0x05, 0x00, 0x21, 0x0b, 0x07, 0xc0, 0x08, 0x00, 0x02, 0xc4, 0x08, 0x00, 0x02, 0xc8, 0x08, 0x00, 0x02, 0xcc, 0x08, 0x00, 0x02, 0x48, 0x39, 0x01, 0x02, + 0x4c, 0x39, 0x01, 0x02, 0x50, 0x39, 0x01, 0x02, 0x54, 0x39, 0x01, 0x02, 0x58, 0x39, 0x01, 0x02, 0x5c, 0x39, 0x01, 0x02, 0xfc, 0x13, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x04, 0x14, 0x02, 0x02, + 0x08, 0x14, 0x02, 0x02, 0xc8, 0x33, 0x03, 0x03, 0xd0, 0x33, 0x03, 0x03, 0xd8, 0x33, 0x03, 0x03, 0x00, 0x10, 0x04, 0x03, 0x08, 0x10, 0x04, 0x03, 0x20, 0x2e, 0x05, 0x04, 0x30, 0x2e, 0x05, 0x04, + 0x50, 0x0c, 0x06, 0x04, 0x60, 0x07, 0x08, 0x05, 0x00, 0x3e, 0x0c, 0x08, 0xd0, 0x08, 0x00, 0x02, 0xd4, 0x08, 0x00, 0x02, 0xd8, 0x08, 0x00, 0x02, 0xdc, 0x08, 0x00, 0x02, 0x60, 0x39, 0x01, 0x02, + 0x64, 0x39, 0x01, 0x02, 0x68, 0x39, 0x01, 0x02, 0x6c, 0x39, 0x01, 0x02, 0x70, 0x39, 0x01, 0x02, 0x74, 0x39, 0x01, 0x02, 0x0c, 0x14, 0x02, 0x02, 0x10, 0x14, 0x02, 0x02, 0x14, 0x14, 0x02, 0x02, + 0x18, 0x14, 0x02, 0x02, 0xe0, 0x33, 0x03, 0x03, 0xe8, 0x33, 0x03, 0x03, 0xf0, 0x33, 0x03, 0x03, 0x10, 0x10, 0x04, 0x03, 0x18, 0x10, 0x04, 0x03, 0x40, 0x2e, 0x05, 0x04, 0x50, 0x2e, 0x05, 0x04, + 0x60, 0x0c, 0x06, 0x04, 0x80, 0x07, 0x08, 0x05, 0x00, 0x3f, 0x0c, 0x08, 0xe0, 0x08, 0x00, 0x02, 0xe4, 0x08, 0x00, 0x02, 0xe8, 0x08, 0x00, 0x02, 0xec, 0x08, 0x00, 0x02, 0x78, 0x39, 0x01, 0x02, + 0x7c, 0x39, 0x01, 0x02, 0x80, 0x39, 0x01, 0x02, 0x84, 0x39, 0x01, 0x02, 0x88, 0x39, 0x01, 0x02, 0x8c, 0x39, 0x01, 0x02, 0x1c, 0x14, 0x02, 0x02, 0x20, 0x14, 0x02, 0x02, 0x24, 0x14, 0x02, 0x02, + 0x28, 0x14, 0x02, 0x02, 0xf8, 0x33, 0x03, 0x03, 0x00, 0x34, 0x03, 0x03, 0x08, 0x34, 0x03, 0x03, 0x20, 0x10, 0x04, 0x03, 0x28, 0x10, 0x04, 0x03, 0x60, 0x2e, 0x05, 0x04, 0x70, 0x2e, 0x05, 0x04, + 0x70, 0x0c, 0x06, 0x04, 0xa0, 0x07, 0x08, 0x05, 0x00, 0x00, 0x0c, 0x07, 0xf0, 0x08, 0x00, 0x02, 0xf4, 0x08, 0x00, 0x02, 0xf8, 0x08, 0x00, 0x02, 0xfc, 0x08, 0x00, 0x02, 0x90, 0x39, 0x01, 0x02, + 0x94, 0x39, 0x01, 0x02, 0x98, 0x39, 0x01, 0x02, 0x9c, 0x39, 0x01, 0x02, 0xa0, 0x39, 0x01, 0x02, 0xa4, 0x39, 0x01, 0x02, 0x2c, 0x14, 0x02, 0x02, 0x30, 0x14, 0x02, 0x02, 0x34, 0x14, 0x02, 0x02, + 0x38, 0x14, 0x02, 0x02, 0x10, 0x34, 0x03, 0x03, 0x18, 0x34, 0x03, 0x03, 0x20, 0x34, 0x03, 0x03, 0x30, 0x10, 0x04, 0x03, 0x38, 0x10, 0x04, 0x03, 0x80, 0x2e, 0x05, 0x04, 0x90, 0x2e, 0x05, 0x04, + 0x80, 0x0c, 0x06, 0x04, 0xc0, 0x07, 0x08, 0x05, 0x80, 0x00, 0x0c, 0x07, 0x00, 0x09, 0x00, 0x02, 0x04, 0x09, 0x00, 0x02, 0x08, 0x09, 0x00, 0x02, 0x0c, 0x09, 0x00, 0x02, 0xa8, 0x39, 0x01, 0x02, + 0xac, 0x39, 0x01, 0x02, 0xb0, 0x39, 0x01, 0x02, 0xb4, 0x39, 0x01, 0x02, 0xb8, 0x39, 0x01, 0x02, 0xbc, 0x39, 0x01, 0x02, 0x3c, 0x14, 0x02, 0x02, 0x40, 0x14, 0x02, 0x02, 0x44, 0x14, 0x02, 0x02, + 0x48, 0x14, 0x02, 0x02, 0x28, 0x34, 0x03, 0x03, 0x30, 0x34, 0x03, 0x03, 0x38, 0x34, 0x03, 0x03, 0x40, 0x10, 0x04, 0x03, 0x48, 0x10, 0x04, 0x03, 0xa0, 0x2e, 0x05, 0x04, 0xb0, 0x2e, 0x05, 0x04, + 0x90, 0x0c, 0x06, 0x04, 0xe0, 0x07, 0x08, 0x05, 0x00, 0x01, 0x0c, 0x07, 0x10, 0x09, 0x00, 0x02, 0x14, 0x09, 0x00, 0x02, 0x18, 0x09, 0x00, 0x02, 0x1c, 0x09, 0x00, 0x02, 0xc0, 0x39, 0x01, 0x02, + 0xc4, 0x39, 0x01, 0x02, 0xc8, 0x39, 0x01, 0x02, 0xcc, 0x39, 0x01, 0x02, 0xd0, 0x39, 0x01, 0x02, 0xd4, 0x39, 0x01, 0x02, 0x4c, 0x14, 0x02, 0x02, 0x50, 0x14, 0x02, 0x02, 0x54, 0x14, 0x02, 0x02, + 0x58, 0x14, 0x02, 0x02, 0x40, 0x34, 0x03, 0x03, 0x48, 0x34, 0x03, 0x03, 0x50, 0x34, 0x03, 0x03, 0x50, 0x10, 0x04, 0x03, 0x58, 0x10, 0x04, 0x03, 0xc0, 0x2e, 0x05, 0x04, 0xd0, 0x2e, 0x05, 0x04, + 0xa0, 0x0c, 0x06, 0x04, 0x00, 0x08, 0x08, 0x05, 0x80, 0x01, 0x0c, 0x07, 0x20, 0x09, 0x00, 0x02, 0x24, 0x09, 0x00, 0x02, 0x28, 0x09, 0x00, 0x02, 0x2c, 0x09, 0x00, 0x02, 0xd8, 0x39, 0x01, 0x02, + 0xdc, 0x39, 0x01, 0x02, 0xe0, 0x39, 0x01, 0x02, 0xe4, 0x39, 0x01, 0x02, 0xe8, 0x39, 0x01, 0x02, 0xec, 0x39, 0x01, 0x02, 0x5c, 0x14, 0x02, 0x02, 0x60, 0x14, 0x02, 0x02, 0x64, 0x14, 0x02, 0x02, + 0x68, 0x14, 0x02, 0x02, 0x58, 0x34, 0x03, 0x03, 0x60, 0x34, 0x03, 0x03, 0x68, 0x34, 0x03, 0x03, 0x60, 0x10, 0x04, 0x03, 0x68, 0x10, 0x04, 0x03, 0xe0, 0x2e, 0x05, 0x04, 0xf0, 0x2e, 0x05, 0x04, + 0xb0, 0x0c, 0x06, 0x04, 0x20, 0x08, 0x08, 0x05, 0x00, 0x02, 0x0c, 0x07, 0x30, 0x09, 0x00, 0x02, 0x34, 0x09, 0x00, 0x02, 0x38, 0x09, 0x00, 0x02, 0x3c, 0x09, 0x00, 0x02, 0xf0, 0x39, 0x01, 0x02, + 0xf4, 0x39, 0x01, 0x02, 0xf8, 0x39, 0x01, 0x02, 0xfc, 0x39, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x04, 0x3a, 0x01, 0x02, 0x6c, 0x14, 0x02, 0x02, 0x70, 0x14, 0x02, 0x02, 0x74, 0x14, 0x02, 0x02, + 0x78, 0x14, 0x02, 0x02, 0x70, 0x34, 0x03, 0x03, 0x78, 0x34, 0x03, 0x03, 0x80, 0x34, 0x03, 0x03, 0x70, 0x10, 0x04, 0x03, 0x78, 0x10, 0x04, 0x03, 0x00, 0x2f, 0x05, 0x04, 0x10, 0x2f, 0x05, 0x04, + 0xc0, 0x0c, 0x06, 0x04, 0x40, 0x08, 0x08, 0x05, 0x80, 0x02, 0x0c, 0x07, 0x40, 0x09, 0x00, 0x02, 0x44, 0x09, 0x00, 0x02, 0x48, 0x09, 0x00, 0x02, 0x08, 0x3a, 0x01, 0x02, 0x0c, 0x3a, 0x01, 0x02, + 0x10, 0x3a, 0x01, 0x02, 0x14, 0x3a, 0x01, 0x02, 0x18, 0x3a, 0x01, 0x02, 0x1c, 0x3a, 0x01, 0x02, 0x20, 0x3a, 0x01, 0x02, 0x7c, 0x14, 0x02, 0x02, 0x80, 0x14, 0x02, 0x02, 0x84, 0x14, 0x02, 0x02, + 0x88, 0x14, 0x02, 0x02, 0x88, 0x34, 0x03, 0x03, 0x90, 0x34, 0x03, 0x03, 0x98, 0x34, 0x03, 0x03, 0x80, 0x10, 0x04, 0x03, 0x88, 0x10, 0x04, 0x03, 0x20, 0x2f, 0x05, 0x04, 0x30, 0x2f, 0x05, 0x04, + 0xd0, 0x0c, 0x06, 0x04, 0x60, 0x08, 0x08, 0x05, 0x00, 0x03, 0x0c, 0x07, 0x4c, 0x09, 0x00, 0x02, 0x50, 0x09, 0x00, 0x02, 0x54, 0x09, 0x00, 0x02, 0x24, 0x3a, 0x01, 0x02, 0x28, 0x3a, 0x01, 0x02, + 0x2c, 0x3a, 0x01, 0x02, 0x30, 0x3a, 0x01, 0x02, 0x34, 0x3a, 0x01, 0x02, 0x38, 0x3a, 0x01, 0x02, 0x3c, 0x3a, 0x01, 0x02, 0x8c, 0x14, 0x02, 0x02, 0x90, 0x14, 0x02, 0x02, 0x94, 0x14, 0x02, 0x02, + 0x98, 0x14, 0x02, 0x02, 0xa0, 0x34, 0x03, 0x03, 0xa8, 0x34, 0x03, 0x03, 0xb0, 0x34, 0x03, 0x03, 0x90, 0x10, 0x04, 0x03, 0x98, 0x10, 0x04, 0x03, 0x40, 0x2f, 0x05, 0x04, 0x50, 0x2f, 0x05, 0x04, + 0xe0, 0x0c, 0x06, 0x04, 0x80, 0x08, 0x08, 0x05, 0x00, 0x17, 0x0d, 0x08, 0x58, 0x09, 0x00, 0x02, 0x5c, 0x09, 0x00, 0x02, 0x60, 0x09, 0x00, 0x02, 0x40, 0x3a, 0x01, 0x02, 0x44, 0x3a, 0x01, 0x02, + 0x48, 0x3a, 0x01, 0x02, 0x4c, 0x3a, 0x01, 0x02, 0x50, 0x3a, 0x01, 0x02, 0x54, 0x3a, 0x01, 0x02, 0x58, 0x3a, 0x01, 0x02, 0x9c, 0x14, 0x02, 0x02, 0xa0, 0x14, 0x02, 0x02, 0xa4, 0x14, 0x02, 0x02, + 0xa8, 0x14, 0x02, 0x02, 0xb8, 0x34, 0x03, 0x03, 0xc0, 0x34, 0x03, 0x03, 0xc8, 0x34, 0x03, 0x03, 0xa0, 0x10, 0x04, 0x03, 0xa8, 0x10, 0x04, 0x03, 0x60, 0x2f, 0x05, 0x04, 0x70, 0x2f, 0x05, 0x04, + 0xf0, 0x0c, 0x06, 0x04, 0xa0, 0x08, 0x08, 0x05, 0x00, 0x18, 0x0d, 0x08, 0x64, 0x09, 0x00, 0x02, 0x68, 0x09, 0x00, 0x02, 0x6c, 0x09, 0x00, 0x02, 0x5c, 0x3a, 0x01, 0x02, 0x60, 0x3a, 0x01, 0x02, + 0x64, 0x3a, 0x01, 0x02, 0x68, 0x3a, 0x01, 0x02, 0x6c, 0x3a, 0x01, 0x02, 0x70, 0x3a, 0x01, 0x02, 0x74, 0x3a, 0x01, 0x02, 0xac, 0x14, 0x02, 0x02, 0xb0, 0x14, 0x02, 0x02, 0xb4, 0x14, 0x02, 0x02, + 0xb8, 0x14, 0x02, 0x02, 0xd0, 0x34, 0x03, 0x03, 0xd8, 0x34, 0x03, 0x03, 0xe0, 0x34, 0x03, 0x03, 0xb0, 0x10, 0x04, 0x03, 0xb8, 0x10, 0x04, 0x03, 0x80, 0x2f, 0x05, 0x04, 0x90, 0x2f, 0x05, 0x04, + 0x00, 0x0d, 0x06, 0x04, 0xc0, 0x08, 0x08, 0x05, 0x00, 0x19, 0x0d, 0x08, 0x70, 0x09, 0x00, 0x02, 0x74, 0x09, 0x00, 0x02, 0x78, 0x09, 0x00, 0x02, 0x78, 0x3a, 0x01, 0x02, 0x7c, 0x3a, 0x01, 0x02, + 0x80, 0x3a, 0x01, 0x02, 0x84, 0x3a, 0x01, 0x02, 0x88, 0x3a, 0x01, 0x02, 0x8c, 0x3a, 0x01, 0x02, 0x90, 0x3a, 0x01, 0x02, 0xbc, 0x14, 0x02, 0x02, 0xc0, 0x14, 0x02, 0x02, 0xc4, 0x14, 0x02, 0x02, + 0xc8, 0x14, 0x02, 0x02, 0xe8, 0x34, 0x03, 0x03, 0xf0, 0x34, 0x03, 0x03, 0xf8, 0x34, 0x03, 0x03, 0xc0, 0x10, 0x04, 0x03, 0xc8, 0x10, 0x04, 0x03, 0xa0, 0x2f, 0x05, 0x04, 0xb0, 0x2f, 0x05, 0x04, + 0x10, 0x0d, 0x06, 0x04, 0xe0, 0x08, 0x08, 0x05, 0x00, 0x1a, 0x0d, 0x08, 0x7c, 0x09, 0x00, 0x02, 0x80, 0x09, 0x00, 0x02, 0x84, 0x09, 0x00, 0x02, 0x94, 0x3a, 0x01, 0x02, 0x98, 0x3a, 0x01, 0x02, + 0x9c, 0x3a, 0x01, 0x02, 0xa0, 0x3a, 0x01, 0x02, 0xa4, 0x3a, 0x01, 0x02, 0xa8, 0x3a, 0x01, 0x02, 0xac, 0x3a, 0x01, 0x02, 0xcc, 0x14, 0x02, 0x02, 0xd0, 0x14, 0x02, 0x02, 0xd4, 0x14, 0x02, 0x02, + 0xd8, 0x14, 0x02, 0x02, 0x00, 0x35, 0x03, 0x03, 0x08, 0x35, 0x03, 0x03, 0x10, 0x35, 0x03, 0x03, 0xd0, 0x10, 0x04, 0x03, 0xd8, 0x10, 0x04, 0x03, 0xc0, 0x2f, 0x05, 0x04, 0xd0, 0x2f, 0x05, 0x04, + 0x00, 0x2a, 0x07, 0x05, 0x00, 0x09, 0x08, 0x05, 0x00, 0x1b, 0x0d, 0x08, 0x88, 0x09, 0x00, 0x02, 0x8c, 0x09, 0x00, 0x02, 0x90, 0x09, 0x00, 0x02, 0xb0, 0x3a, 0x01, 0x02, 0xb4, 0x3a, 0x01, 0x02, + 0xb8, 0x3a, 0x01, 0x02, 0xbc, 0x3a, 0x01, 0x02, 0xc0, 0x3a, 0x01, 0x02, 0xc4, 0x3a, 0x01, 0x02, 0xc8, 0x3a, 0x01, 0x02, 0xdc, 0x14, 0x02, 0x02, 0xe0, 0x14, 0x02, 0x02, 0xe4, 0x14, 0x02, 0x02, + 0xe8, 0x14, 0x02, 0x02, 0x18, 0x35, 0x03, 0x03, 0x20, 0x35, 0x03, 0x03, 0x28, 0x35, 0x03, 0x03, 0xe0, 0x10, 0x04, 0x03, 0xe8, 0x10, 0x04, 0x03, 0xe0, 0x2f, 0x05, 0x04, 0x20, 0x0d, 0x06, 0x04, + 0x20, 0x2a, 0x07, 0x05, 0x20, 0x09, 0x08, 0x05, 0x00, 0x1c, 0x0d, 0x08, 0x94, 0x09, 0x00, 0x02, 0x98, 0x09, 0x00, 0x02, 0x9c, 0x09, 0x00, 0x02, 0xcc, 0x3a, 0x01, 0x02, 0xd0, 0x3a, 0x01, 0x02, + 0xd4, 0x3a, 0x01, 0x02, 0xd8, 0x3a, 0x01, 0x02, 0xdc, 0x3a, 0x01, 0x02, 0xe0, 0x3a, 0x01, 0x02, 0xe4, 0x3a, 0x01, 0x02, 0xec, 0x14, 0x02, 0x02, 0xf0, 0x14, 0x02, 0x02, 0xf4, 0x14, 0x02, 0x02, + 0xf8, 0x14, 0x02, 0x02, 0x30, 0x35, 0x03, 0x03, 0x38, 0x35, 0x03, 0x03, 0x40, 0x35, 0x03, 0x03, 0xf0, 0x10, 0x04, 0x03, 0xf8, 0x10, 0x04, 0x03, 0xf0, 0x2f, 0x05, 0x04, 0x30, 0x0d, 0x06, 0x04, + 0x40, 0x2a, 0x07, 0x05, 0x40, 0x09, 0x08, 0x05, 0x00, 0x1d, 0x0d, 0x08, 0xa0, 0x09, 0x00, 0x02, 0xa4, 0x09, 0x00, 0x02, 0xa8, 0x09, 0x00, 0x02, 0xe8, 0x3a, 0x01, 0x02, 0xec, 0x3a, 0x01, 0x02, + 0xf0, 0x3a, 0x01, 0x02, 0xf4, 0x3a, 0x01, 0x02, 0xf8, 0x3a, 0x01, 0x02, 0xfc, 0x3a, 0x01, 0x02, 0x00, 0x3b, 0x01, 0x02, 0xfc, 0x14, 0x02, 0x02, 0x00, 0x15, 0x02, 0x02, 0x04, 0x15, 0x02, 0x02, + 0x08, 0x15, 0x02, 0x02, 0x48, 0x35, 0x03, 0x03, 0x50, 0x35, 0x03, 0x03, 0x58, 0x35, 0x03, 0x03, 0x00, 0x11, 0x04, 0x03, 0x08, 0x11, 0x04, 0x03, 0x00, 0x30, 0x05, 0x04, 0x40, 0x0d, 0x06, 0x04, + 0x60, 0x2a, 0x07, 0x05, 0x60, 0x09, 0x08, 0x05, 0x00, 0x38, 0x0e, 0x09, 0xac, 0x09, 0x00, 0x02, 0xb0, 0x09, 0x00, 0x02, 0xb4, 0x09, 0x00, 0x02, 0x04, 0x3b, 0x01, 0x02, 0x08, 0x3b, 0x01, 0x02, + 0x0c, 0x3b, 0x01, 0x02, 0x10, 0x3b, 0x01, 0x02, 0x14, 0x3b, 0x01, 0x02, 0x18, 0x3b, 0x01, 0x02, 0x1c, 0x3b, 0x01, 0x02, 0x0c, 0x15, 0x02, 0x02, 0x10, 0x15, 0x02, 0x02, 0x14, 0x15, 0x02, 0x02, + 0x18, 0x15, 0x02, 0x02, 0x60, 0x35, 0x03, 0x03, 0x68, 0x35, 0x03, 0x03, 0x70, 0x35, 0x03, 0x03, 0x10, 0x11, 0x04, 0x03, 0x18, 0x11, 0x04, 0x03, 0x10, 0x30, 0x05, 0x04, 0x50, 0x0d, 0x06, 0x04, + 0x80, 0x2a, 0x07, 0x05, 0x80, 0x09, 0x08, 0x05, 0x00, 0x3a, 0x0e, 0x09, 0xb8, 0x09, 0x00, 0x02, 0xbc, 0x09, 0x00, 0x02, 0xc0, 0x09, 0x00, 0x02, 0x20, 0x3b, 0x01, 0x02, 0x24, 0x3b, 0x01, 0x02, + 0x28, 0x3b, 0x01, 0x02, 0x2c, 0x3b, 0x01, 0x02, 0x30, 0x3b, 0x01, 0x02, 0x34, 0x3b, 0x01, 0x02, 0x38, 0x3b, 0x01, 0x02, 0x1c, 0x15, 0x02, 0x02, 0x20, 0x15, 0x02, 0x02, 0x24, 0x15, 0x02, 0x02, + 0x28, 0x15, 0x02, 0x02, 0x78, 0x35, 0x03, 0x03, 0x80, 0x35, 0x03, 0x03, 0x88, 0x35, 0x03, 0x03, 0x20, 0x11, 0x04, 0x03, 0x28, 0x11, 0x04, 0x03, 0x20, 0x30, 0x05, 0x04, 0x60, 0x0d, 0x06, 0x04, + 0xa0, 0x2a, 0x07, 0x05, 0xa0, 0x09, 0x08, 0x05, 0x00, 0x3c, 0x0e, 0x09, 0xc4, 0x09, 0x00, 0x02, 0xc8, 0x09, 0x00, 0x02, 0xcc, 0x09, 0x00, 0x02, 0x3c, 0x3b, 0x01, 0x02, 0x40, 0x3b, 0x01, 0x02, + 0x44, 0x3b, 0x01, 0x02, 0x48, 0x3b, 0x01, 0x02, 0x4c, 0x3b, 0x01, 0x02, 0x50, 0x3b, 0x01, 0x02, 0x54, 0x3b, 0x01, 0x02, 0x2c, 0x15, 0x02, 0x02, 0x30, 0x15, 0x02, 0x02, 0x34, 0x15, 0x02, 0x02, + 0x38, 0x15, 0x02, 0x02, 0x90, 0x35, 0x03, 0x03, 0x98, 0x35, 0x03, 0x03, 0xa0, 0x35, 0x03, 0x03, 0x30, 0x11, 0x04, 0x03, 0x38, 0x11, 0x04, 0x03, 0x30, 0x30, 0x05, 0x04, 0x70, 0x0d, 0x06, 0x04, + 0xc0, 0x2a, 0x07, 0x05, 0xc0, 0x09, 0x08, 0x05, 0x00, 0x3e, 0x0e, 0x09, 0xd0, 0x09, 0x00, 0x02, 0xd4, 0x09, 0x00, 0x02, 0xd8, 0x09, 0x00, 0x02, 0x58, 0x3b, 0x01, 0x02, 0x5c, 0x3b, 0x01, 0x02, + 0x60, 0x3b, 0x01, 0x02, 0x64, 0x3b, 0x01, 0x02, 0x68, 0x3b, 0x01, 0x02, 0x6c, 0x3b, 0x01, 0x02, 0x70, 0x3b, 0x01, 0x02, 0x3c, 0x15, 0x02, 0x02, 0x40, 0x15, 0x02, 0x02, 0x44, 0x15, 0x02, 0x02, + 0x48, 0x15, 0x02, 0x02, 0xa8, 0x35, 0x03, 0x03, 0xb0, 0x35, 0x03, 0x03, 0xb8, 0x35, 0x03, 0x03, 0x40, 0x11, 0x04, 0x03, 0x48, 0x11, 0x04, 0x03, 0x40, 0x30, 0x05, 0x04, 0x80, 0x0d, 0x06, 0x04, + 0xe0, 0x2a, 0x07, 0x05, 0xe0, 0x09, 0x08, 0x05, 0x00, 0x18, 0x0f, 0x09, 0xdc, 0x09, 0x00, 0x02, 0xe0, 0x09, 0x00, 0x02, 0xe4, 0x09, 0x00, 0x02, 0x74, 0x3b, 0x01, 0x02, 0x78, 0x3b, 0x01, 0x02, + 0x7c, 0x3b, 0x01, 0x02, 0x80, 0x3b, 0x01, 0x02, 0x84, 0x3b, 0x01, 0x02, 0x88, 0x3b, 0x01, 0x02, 0x8c, 0x3b, 0x01, 0x02, 0x4c, 0x15, 0x02, 0x02, 0x50, 0x15, 0x02, 0x02, 0x54, 0x15, 0x02, 0x02, + 0x58, 0x15, 0x02, 0x02, 0xc0, 0x35, 0x03, 0x03, 0xc8, 0x35, 0x03, 0x03, 0xd0, 0x35, 0x03, 0x03, 0x50, 0x11, 0x04, 0x03, 0x58, 0x11, 0x04, 0x03, 0x50, 0x30, 0x05, 0x04, 0x90, 0x0d, 0x06, 0x04, + 0x00, 0x2b, 0x07, 0x05, 0x00, 0x0a, 0x08, 0x05, 0x00, 0x1a, 0x0f, 0x09, 0xe8, 0x09, 0x00, 0x02, 0xec, 0x09, 0x00, 0x02, 0xf0, 0x09, 0x00, 0x02, 0x90, 0x3b, 0x01, 0x02, 0x94, 0x3b, 0x01, 0x02, + 0x98, 0x3b, 0x01, 0x02, 0x9c, 0x3b, 0x01, 0x02, 0xa0, 0x3b, 0x01, 0x02, 0xa4, 0x3b, 0x01, 0x02, 0xa8, 0x3b, 0x01, 0x02, 0x5c, 0x15, 0x02, 0x02, 0x60, 0x15, 0x02, 0x02, 0x64, 0x15, 0x02, 0x02, + 0x68, 0x15, 0x02, 0x02, 0xd8, 0x35, 0x03, 0x03, 0xe0, 0x35, 0x03, 0x03, 0xe8, 0x35, 0x03, 0x03, 0x60, 0x11, 0x04, 0x03, 0x68, 0x11, 0x04, 0x03, 0x60, 0x30, 0x05, 0x04, 0xa0, 0x0d, 0x06, 0x04, + 0x20, 0x2b, 0x07, 0x05, 0x20, 0x0a, 0x08, 0x05, 0x00, 0x1c, 0x0f, 0x09, 0xf4, 0x09, 0x00, 0x02, 0xf8, 0x09, 0x00, 0x02, 0xfc, 0x09, 0x00, 0x02, 0xac, 0x3b, 0x01, 0x02, 0xb0, 0x3b, 0x01, 0x02, + 0xb4, 0x3b, 0x01, 0x02, 0xb8, 0x3b, 0x01, 0x02, 0xbc, 0x3b, 0x01, 0x02, 0xc0, 0x3b, 0x01, 0x02, 0xc4, 0x3b, 0x01, 0x02, 0x6c, 0x15, 0x02, 0x02, 0x70, 0x15, 0x02, 0x02, 0x74, 0x15, 0x02, 0x02, + 0x78, 0x15, 0x02, 0x02, 0xf0, 0x35, 0x03, 0x03, 0xf8, 0x35, 0x03, 0x03, 0x00, 0x36, 0x03, 0x03, 0x70, 0x11, 0x04, 0x03, 0x78, 0x11, 0x04, 0x03, 0x70, 0x30, 0x05, 0x04, 0xb0, 0x0d, 0x06, 0x04, + 0x40, 0x2b, 0x07, 0x05, 0x40, 0x0a, 0x08, 0x05, 0x00, 0x38, 0x10, 0x0a, 0x00, 0x0a, 0x00, 0x02, 0x04, 0x0a, 0x00, 0x02, 0x08, 0x0a, 0x00, 0x02, 0xc8, 0x3b, 0x01, 0x02, 0xcc, 0x3b, 0x01, 0x02, + 0xd0, 0x3b, 0x01, 0x02, 0xd4, 0x3b, 0x01, 0x02, 0xd8, 0x3b, 0x01, 0x02, 0xdc, 0x3b, 0x01, 0x02, 0xe0, 0x3b, 0x01, 0x02, 0x7c, 0x15, 0x02, 0x02, 0x80, 0x15, 0x02, 0x02, 0x84, 0x15, 0x02, 0x02, + 0x88, 0x15, 0x02, 0x02, 0x08, 0x36, 0x03, 0x03, 0x10, 0x36, 0x03, 0x03, 0x18, 0x36, 0x03, 0x03, 0x80, 0x11, 0x04, 0x03, 0x88, 0x11, 0x04, 0x03, 0x80, 0x30, 0x05, 0x04, 0xc0, 0x0d, 0x06, 0x04, + 0x60, 0x2b, 0x07, 0x05, 0x60, 0x0a, 0x08, 0x05, 0x00, 0x3c, 0x10, 0x0a, 0x0c, 0x0a, 0x00, 0x02, 0x10, 0x0a, 0x00, 0x02, 0x14, 0x0a, 0x00, 0x02, 0xe4, 0x3b, 0x01, 0x02, 0xe8, 0x3b, 0x01, 0x02, + 0xec, 0x3b, 0x01, 0x02, 0xf0, 0x3b, 0x01, 0x02, 0xf4, 0x3b, 0x01, 0x02, 0xf8, 0x3b, 0x01, 0x02, 0xfc, 0x3b, 0x01, 0x02, 0x8c, 0x15, 0x02, 0x02, 0x90, 0x15, 0x02, 0x02, 0x94, 0x15, 0x02, 0x02, + 0x98, 0x15, 0x02, 0x02, 0x20, 0x36, 0x03, 0x03, 0x28, 0x36, 0x03, 0x03, 0x30, 0x36, 0x03, 0x03, 0x90, 0x11, 0x04, 0x03, 0x98, 0x11, 0x04, 0x03, 0x90, 0x30, 0x05, 0x04, 0xd0, 0x0d, 0x06, 0x04, + 0x80, 0x2b, 0x07, 0x05, 0x80, 0x0a, 0x08, 0x05, 0x00, 0x10, 0x11, 0x0a, 0x18, 0x0a, 0x00, 0x02, 0x1c, 0x0a, 0x00, 0x02, 0x20, 0x0a, 0x00, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x04, 0x3c, 0x01, 0x02, + 0x08, 0x3c, 0x01, 0x02, 0x0c, 0x3c, 0x01, 0x02, 0x10, 0x3c, 0x01, 0x02, 0x14, 0x3c, 0x01, 0x02, 0x18, 0x3c, 0x01, 0x02, 0x9c, 0x15, 0x02, 0x02, 0xa0, 0x15, 0x02, 0x02, 0xa4, 0x15, 0x02, 0x02, + 0xa8, 0x15, 0x02, 0x02, 0x38, 0x36, 0x03, 0x03, 0x40, 0x36, 0x03, 0x03, 0x48, 0x36, 0x03, 0x03, 0xa0, 0x11, 0x04, 0x03, 0xa8, 0x11, 0x04, 0x03, 0xa0, 0x30, 0x05, 0x04, 0xe0, 0x0d, 0x06, 0x04, + 0xa0, 0x2b, 0x07, 0x05, 0x00, 0x26, 0x09, 0x06, 0x00, 0x14, 0x11, 0x0a, 0x24, 0x0a, 0x00, 0x02, 0x28, 0x0a, 0x00, 0x02, 0x2c, 0x0a, 0x00, 0x02, 0x1c, 0x3c, 0x01, 0x02, 0x20, 0x3c, 0x01, 0x02, + 0x24, 0x3c, 0x01, 0x02, 0x28, 0x3c, 0x01, 0x02, 0x2c, 0x3c, 0x01, 0x02, 0x30, 0x3c, 0x01, 0x02, 0x34, 0x3c, 0x01, 0x02, 0xac, 0x15, 0x02, 0x02, 0xb0, 0x15, 0x02, 0x02, 0xb4, 0x15, 0x02, 0x02, + 0xb8, 0x15, 0x02, 0x02, 0x50, 0x36, 0x03, 0x03, 0x58, 0x36, 0x03, 0x03, 0x60, 0x36, 0x03, 0x03, 0xb0, 0x11, 0x04, 0x03, 0xb8, 0x11, 0x04, 0x03, 0xb0, 0x30, 0x05, 0x04, 0xf0, 0x0d, 0x06, 0x04, + 0xc0, 0x2b, 0x07, 0x05, 0x40, 0x26, 0x09, 0x06, 0x00, 0x38, 0x12, 0x0b, 0x30, 0x0a, 0x00, 0x02, 0x34, 0x0a, 0x00, 0x02, 0x38, 0x0a, 0x00, 0x02, 0x38, 0x3c, 0x01, 0x02, 0x3c, 0x3c, 0x01, 0x02, + 0x40, 0x3c, 0x01, 0x02, 0x44, 0x3c, 0x01, 0x02, 0x48, 0x3c, 0x01, 0x02, 0x4c, 0x3c, 0x01, 0x02, 0x50, 0x3c, 0x01, 0x02, 0xbc, 0x15, 0x02, 0x02, 0xc0, 0x15, 0x02, 0x02, 0xc4, 0x15, 0x02, 0x02, + 0xc8, 0x15, 0x02, 0x02, 0x68, 0x36, 0x03, 0x03, 0x70, 0x36, 0x03, 0x03, 0x78, 0x36, 0x03, 0x03, 0xc0, 0x11, 0x04, 0x03, 0xc8, 0x11, 0x04, 0x03, 0xc0, 0x30, 0x05, 0x04, 0x00, 0x0e, 0x06, 0x04, + 0xe0, 0x2b, 0x07, 0x05, 0x80, 0x26, 0x09, 0x06, 0x00, 0x08, 0x13, 0x0b, 0x3c, 0x0a, 0x00, 0x02, 0x40, 0x0a, 0x00, 0x02, 0x44, 0x0a, 0x00, 0x02, 0x54, 0x3c, 0x01, 0x02, 0x58, 0x3c, 0x01, 0x02, + 0x5c, 0x3c, 0x01, 0x02, 0x60, 0x3c, 0x01, 0x02, 0x64, 0x3c, 0x01, 0x02, 0x68, 0x3c, 0x01, 0x02, 0x6c, 0x3c, 0x01, 0x02, 0xcc, 0x15, 0x02, 0x02, 0xd0, 0x15, 0x02, 0x02, 0xd4, 0x15, 0x02, 0x02, + 0xd8, 0x15, 0x02, 0x02, 0x80, 0x36, 0x03, 0x03, 0x88, 0x36, 0x03, 0x03, 0x90, 0x36, 0x03, 0x03, 0xd0, 0x11, 0x04, 0x03, 0xd8, 0x11, 0x04, 0x03, 0xd0, 0x30, 0x05, 0x04, 0x10, 0x0e, 0x06, 0x04, + 0x00, 0x2c, 0x07, 0x05, 0xc0, 0x26, 0x09, 0x06, 0x00, 0x10, 0x15, 0x0c, 0x48, 0x0a, 0x00, 0x02, 0x4c, 0x0a, 0x00, 0x02, 0x50, 0x0a, 0x00, 0x02, 0x70, 0x3c, 0x01, 0x02, 0x74, 0x3c, 0x01, 0x02, + 0x78, 0x3c, 0x01, 0x02, 0x7c, 0x3c, 0x01, 0x02, 0x80, 0x3c, 0x01, 0x02, 0x84, 0x3c, 0x01, 0x02, 0x88, 0x3c, 0x01, 0x02, 0xdc, 0x15, 0x02, 0x02, 0xe0, 0x15, 0x02, 0x02, 0xe4, 0x15, 0x02, 0x02, + 0xe8, 0x15, 0x02, 0x02, 0x98, 0x36, 0x03, 0x03, 0xa0, 0x36, 0x03, 0x03, 0xa8, 0x36, 0x03, 0x03, 0xe0, 0x11, 0x04, 0x03, 0xe8, 0x11, 0x04, 0x03, 0xe0, 0x30, 0x05, 0x04, 0x20, 0x0e, 0x06, 0x04, + 0x20, 0x2c, 0x07, 0x05, 0x00, 0x27, 0x09, 0x06, 0x54, 0x0a, 0x00, 0x02, 0x58, 0x0a, 0x00, 0x02, 0x5c, 0x0a, 0x00, 0x02, 0x60, 0x0a, 0x00, 0x02, 0x8c, 0x3c, 0x01, 0x02, 0x90, 0x3c, 0x01, 0x02, + 0x94, 0x3c, 0x01, 0x02, 0x98, 0x3c, 0x01, 0x02, 0x9c, 0x3c, 0x01, 0x02, 0xa0, 0x3c, 0x01, 0x02, 0xa4, 0x3c, 0x01, 0x02, 0xec, 0x15, 0x02, 0x02, 0xf0, 0x15, 0x02, 0x02, 0xf4, 0x15, 0x02, 0x02, + 0xf8, 0x15, 0x02, 0x02, 0xb0, 0x36, 0x03, 0x03, 0xb8, 0x36, 0x03, 0x03, 0xc0, 0x36, 0x03, 0x03, 0xf0, 0x11, 0x04, 0x03, 0xf8, 0x11, 0x04, 0x03, 0xf0, 0x30, 0x05, 0x04, 0x30, 0x0e, 0x06, 0x04, + 0x40, 0x2c, 0x07, 0x05, 0x40, 0x27, 0x09, 0x06, 0x64, 0x0a, 0x00, 0x02, 0x68, 0x0a, 0x00, 0x02, 0x6c, 0x0a, 0x00, 0x02, 0x70, 0x0a, 0x00, 0x02, 0xa8, 0x3c, 0x01, 0x02, 0xac, 0x3c, 0x01, 0x02, + 0xb0, 0x3c, 0x01, 0x02, 0xb4, 0x3c, 0x01, 0x02, 0xb8, 0x3c, 0x01, 0x02, 0xbc, 0x3c, 0x01, 0x02, 0xfc, 0x15, 0x02, 0x02, 0x00, 0x16, 0x02, 0x02, 0x04, 0x16, 0x02, 0x02, 0x08, 0x16, 0x02, 0x02, + 0x0c, 0x16, 0x02, 0x02, 0xc8, 0x36, 0x03, 0x03, 0xd0, 0x36, 0x03, 0x03, 0xd8, 0x36, 0x03, 0x03, 0x00, 0x12, 0x04, 0x03, 0x08, 0x12, 0x04, 0x03, 0x00, 0x31, 0x05, 0x04, 0x40, 0x0e, 0x06, 0x04, + 0x60, 0x2c, 0x07, 0x05, 0x80, 0x27, 0x09, 0x06, 0x74, 0x0a, 0x00, 0x02, 0x78, 0x0a, 0x00, 0x02, 0x7c, 0x0a, 0x00, 0x02, 0x80, 0x0a, 0x00, 0x02, 0xc0, 0x3c, 0x01, 0x02, 0xc4, 0x3c, 0x01, 0x02, + 0xc8, 0x3c, 0x01, 0x02, 0xcc, 0x3c, 0x01, 0x02, 0xd0, 0x3c, 0x01, 0x02, 0xd4, 0x3c, 0x01, 0x02, 0x10, 0x16, 0x02, 0x02, 0x14, 0x16, 0x02, 0x02, 0x18, 0x16, 0x02, 0x02, 0x1c, 0x16, 0x02, 0x02, + 0x20, 0x16, 0x02, 0x02, 0xe0, 0x36, 0x03, 0x03, 0xe8, 0x36, 0x03, 0x03, 0xf0, 0x36, 0x03, 0x03, 0x10, 0x12, 0x04, 0x03, 0x18, 0x12, 0x04, 0x03, 0x10, 0x31, 0x05, 0x04, 0x50, 0x0e, 0x06, 0x04, + 0x80, 0x2c, 0x07, 0x05, 0xc0, 0x27, 0x09, 0x06, 0x84, 0x0a, 0x00, 0x02, 0x88, 0x0a, 0x00, 0x02, 0x8c, 0x0a, 0x00, 0x02, 0x90, 0x0a, 0x00, 0x02, 0xd8, 0x3c, 0x01, 0x02, 0xdc, 0x3c, 0x01, 0x02, + 0xe0, 0x3c, 0x01, 0x02, 0xe4, 0x3c, 0x01, 0x02, 0xe8, 0x3c, 0x01, 0x02, 0xec, 0x3c, 0x01, 0x02, 0x24, 0x16, 0x02, 0x02, 0x28, 0x16, 0x02, 0x02, 0x2c, 0x16, 0x02, 0x02, 0x30, 0x16, 0x02, 0x02, + 0x34, 0x16, 0x02, 0x02, 0xf8, 0x36, 0x03, 0x03, 0x00, 0x37, 0x03, 0x03, 0x08, 0x37, 0x03, 0x03, 0x20, 0x12, 0x04, 0x03, 0x28, 0x12, 0x04, 0x03, 0x20, 0x31, 0x05, 0x04, 0x60, 0x0e, 0x06, 0x04, + 0xa0, 0x2c, 0x07, 0x05, 0x00, 0x28, 0x09, 0x06, 0x94, 0x0a, 0x00, 0x02, 0x98, 0x0a, 0x00, 0x02, 0x9c, 0x0a, 0x00, 0x02, 0xa0, 0x0a, 0x00, 0x02, 0xf0, 0x3c, 0x01, 0x02, 0xf4, 0x3c, 0x01, 0x02, + 0xf8, 0x3c, 0x01, 0x02, 0xfc, 0x3c, 0x01, 0x02, 0x00, 0x3d, 0x01, 0x02, 0x04, 0x3d, 0x01, 0x02, 0x38, 0x16, 0x02, 0x02, 0x3c, 0x16, 0x02, 0x02, 0x40, 0x16, 0x02, 0x02, 0x44, 0x16, 0x02, 0x02, + 0x48, 0x16, 0x02, 0x02, 0x10, 0x37, 0x03, 0x03, 0x18, 0x37, 0x03, 0x03, 0x20, 0x37, 0x03, 0x03, 0x30, 0x12, 0x04, 0x03, 0x38, 0x12, 0x04, 0x03, 0x30, 0x31, 0x05, 0x04, 0x70, 0x0e, 0x06, 0x04, + 0xc0, 0x2c, 0x07, 0x05, 0x40, 0x28, 0x09, 0x06, 0xa4, 0x0a, 0x00, 0x02, 0xa8, 0x0a, 0x00, 0x02, 0xac, 0x0a, 0x00, 0x02, 0xb0, 0x0a, 0x00, 0x02, 0x08, 0x3d, 0x01, 0x02, 0x0c, 0x3d, 0x01, 0x02, + 0x10, 0x3d, 0x01, 0x02, 0x14, 0x3d, 0x01, 0x02, 0x18, 0x3d, 0x01, 0x02, 0x1c, 0x3d, 0x01, 0x02, 0x4c, 0x16, 0x02, 0x02, 0x50, 0x16, 0x02, 0x02, 0x54, 0x16, 0x02, 0x02, 0x58, 0x16, 0x02, 0x02, + 0x5c, 0x16, 0x02, 0x02, 0x28, 0x37, 0x03, 0x03, 0x30, 0x37, 0x03, 0x03, 0x38, 0x37, 0x03, 0x03, 0x40, 0x12, 0x04, 0x03, 0x48, 0x12, 0x04, 0x03, 0x40, 0x31, 0x05, 0x04, 0x80, 0x0e, 0x06, 0x04, + 0xe0, 0x2c, 0x07, 0x05, 0x80, 0x28, 0x09, 0x06, 0xb4, 0x0a, 0x00, 0x02, 0xb8, 0x0a, 0x00, 0x02, 0xbc, 0x0a, 0x00, 0x02, 0xc0, 0x0a, 0x00, 0x02, 0x20, 0x3d, 0x01, 0x02, 0x24, 0x3d, 0x01, 0x02, + 0x28, 0x3d, 0x01, 0x02, 0x2c, 0x3d, 0x01, 0x02, 0x30, 0x3d, 0x01, 0x02, 0x34, 0x3d, 0x01, 0x02, 0x60, 0x16, 0x02, 0x02, 0x64, 0x16, 0x02, 0x02, 0x68, 0x16, 0x02, 0x02, 0x6c, 0x16, 0x02, 0x02, + 0x70, 0x16, 0x02, 0x02, 0x40, 0x37, 0x03, 0x03, 0x48, 0x37, 0x03, 0x03, 0x50, 0x37, 0x03, 0x03, 0x50, 0x12, 0x04, 0x03, 0x58, 0x12, 0x04, 0x03, 0x50, 0x31, 0x05, 0x04, 0x90, 0x0e, 0x06, 0x04, + 0x00, 0x2d, 0x07, 0x05, 0xc0, 0x28, 0x09, 0x06, 0xc4, 0x0a, 0x00, 0x02, 0xc8, 0x0a, 0x00, 0x02, 0xcc, 0x0a, 0x00, 0x02, 0xd0, 0x0a, 0x00, 0x02, 0x38, 0x3d, 0x01, 0x02, 0x3c, 0x3d, 0x01, 0x02, + 0x40, 0x3d, 0x01, 0x02, 0x44, 0x3d, 0x01, 0x02, 0x48, 0x3d, 0x01, 0x02, 0x4c, 0x3d, 0x01, 0x02, 0x74, 0x16, 0x02, 0x02, 0x78, 0x16, 0x02, 0x02, 0x7c, 0x16, 0x02, 0x02, 0x80, 0x16, 0x02, 0x02, + 0x84, 0x16, 0x02, 0x02, 0x58, 0x37, 0x03, 0x03, 0x60, 0x37, 0x03, 0x03, 0x68, 0x37, 0x03, 0x03, 0x60, 0x12, 0x04, 0x03, 0x68, 0x12, 0x04, 0x03, 0x60, 0x31, 0x05, 0x04, 0xa0, 0x0e, 0x06, 0x04, + 0x20, 0x2d, 0x07, 0x05, 0x00, 0x29, 0x09, 0x06, 0xd4, 0x0a, 0x00, 0x02, 0xd8, 0x0a, 0x00, 0x02, 0xdc, 0x0a, 0x00, 0x02, 0xe0, 0x0a, 0x00, 0x02, 0x50, 0x3d, 0x01, 0x02, 0x54, 0x3d, 0x01, 0x02, + 0x58, 0x3d, 0x01, 0x02, 0x5c, 0x3d, 0x01, 0x02, 0x60, 0x3d, 0x01, 0x02, 0x64, 0x3d, 0x01, 0x02, 0x88, 0x16, 0x02, 0x02, 0x8c, 0x16, 0x02, 0x02, 0x90, 0x16, 0x02, 0x02, 0x94, 0x16, 0x02, 0x02, + 0x98, 0x16, 0x02, 0x02, 0x70, 0x37, 0x03, 0x03, 0x78, 0x37, 0x03, 0x03, 0x80, 0x37, 0x03, 0x03, 0x70, 0x12, 0x04, 0x03, 0x78, 0x12, 0x04, 0x03, 0x70, 0x31, 0x05, 0x04, 0xb0, 0x0e, 0x06, 0x04, + 0x40, 0x2d, 0x07, 0x05, 0x40, 0x29, 0x09, 0x06, 0xe4, 0x0a, 0x00, 0x02, 0xe8, 0x0a, 0x00, 0x02, 0xec, 0x0a, 0x00, 0x02, 0xf0, 0x0a, 0x00, 0x02, 0x68, 0x3d, 0x01, 0x02, 0x6c, 0x3d, 0x01, 0x02, + 0x70, 0x3d, 0x01, 0x02, 0x74, 0x3d, 0x01, 0x02, 0x78, 0x3d, 0x01, 0x02, 0x7c, 0x3d, 0x01, 0x02, 0x9c, 0x16, 0x02, 0x02, 0xa0, 0x16, 0x02, 0x02, 0xa4, 0x16, 0x02, 0x02, 0xa8, 0x16, 0x02, 0x02, + 0xac, 0x16, 0x02, 0x02, 0x88, 0x37, 0x03, 0x03, 0x90, 0x37, 0x03, 0x03, 0x98, 0x37, 0x03, 0x03, 0x80, 0x12, 0x04, 0x03, 0x88, 0x12, 0x04, 0x03, 0x80, 0x31, 0x05, 0x04, 0xc0, 0x0e, 0x06, 0x04, + 0x60, 0x2d, 0x07, 0x05, 0x80, 0x29, 0x09, 0x06, 0xf4, 0x0a, 0x00, 0x02, 0xf8, 0x0a, 0x00, 0x02, 0xfc, 0x0a, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x80, 0x3d, 0x01, 0x02, 0x84, 0x3d, 0x01, 0x02, + 0x88, 0x3d, 0x01, 0x02, 0x8c, 0x3d, 0x01, 0x02, 0x90, 0x3d, 0x01, 0x02, 0x94, 0x3d, 0x01, 0x02, 0xb0, 0x16, 0x02, 0x02, 0xb4, 0x16, 0x02, 0x02, 0xb8, 0x16, 0x02, 0x02, 0xbc, 0x16, 0x02, 0x02, + 0xc0, 0x16, 0x02, 0x02, 0xa0, 0x37, 0x03, 0x03, 0xa8, 0x37, 0x03, 0x03, 0xb0, 0x37, 0x03, 0x03, 0x90, 0x12, 0x04, 0x03, 0x98, 0x12, 0x04, 0x03, 0x90, 0x31, 0x05, 0x04, 0xd0, 0x0e, 0x06, 0x04, + 0x80, 0x2d, 0x07, 0x05, 0xc0, 0x29, 0x09, 0x06, 0x04, 0x0b, 0x00, 0x02, 0x08, 0x0b, 0x00, 0x02, 0x0c, 0x0b, 0x00, 0x02, 0x10, 0x0b, 0x00, 0x02, 0x98, 0x3d, 0x01, 0x02, 0x9c, 0x3d, 0x01, 0x02, + 0xa0, 0x3d, 0x01, 0x02, 0xa4, 0x3d, 0x01, 0x02, 0xa8, 0x3d, 0x01, 0x02, 0xac, 0x3d, 0x01, 0x02, 0xc4, 0x16, 0x02, 0x02, 0xc8, 0x16, 0x02, 0x02, 0xcc, 0x16, 0x02, 0x02, 0xd0, 0x16, 0x02, 0x02, + 0xd4, 0x16, 0x02, 0x02, 0xb8, 0x37, 0x03, 0x03, 0xc0, 0x37, 0x03, 0x03, 0xc8, 0x37, 0x03, 0x03, 0xa0, 0x12, 0x04, 0x03, 0xa8, 0x12, 0x04, 0x03, 0xa0, 0x31, 0x05, 0x04, 0xe0, 0x0e, 0x06, 0x04, + 0xa0, 0x2d, 0x07, 0x05, 0x00, 0x2a, 0x09, 0x06, 0x14, 0x0b, 0x00, 0x02, 0x18, 0x0b, 0x00, 0x02, 0x1c, 0x0b, 0x00, 0x02, 0x20, 0x0b, 0x00, 0x02, 0xb0, 0x3d, 0x01, 0x02, 0xb4, 0x3d, 0x01, 0x02, + 0xb8, 0x3d, 0x01, 0x02, 0xbc, 0x3d, 0x01, 0x02, 0xc0, 0x3d, 0x01, 0x02, 0xc4, 0x3d, 0x01, 0x02, 0xd8, 0x16, 0x02, 0x02, 0xdc, 0x16, 0x02, 0x02, 0xe0, 0x16, 0x02, 0x02, 0xe4, 0x16, 0x02, 0x02, + 0xe8, 0x16, 0x02, 0x02, 0xd0, 0x37, 0x03, 0x03, 0xd8, 0x37, 0x03, 0x03, 0xe0, 0x37, 0x03, 0x03, 0xb0, 0x12, 0x04, 0x03, 0xb8, 0x12, 0x04, 0x03, 0xb0, 0x31, 0x05, 0x04, 0xf0, 0x0e, 0x06, 0x04, + 0xc0, 0x2d, 0x07, 0x05, 0x40, 0x2a, 0x09, 0x06, 0x24, 0x0b, 0x00, 0x02, 0x28, 0x0b, 0x00, 0x02, 0x2c, 0x0b, 0x00, 0x02, 0x30, 0x0b, 0x00, 0x02, 0xc8, 0x3d, 0x01, 0x02, 0xcc, 0x3d, 0x01, 0x02, + 0xd0, 0x3d, 0x01, 0x02, 0xd4, 0x3d, 0x01, 0x02, 0xd8, 0x3d, 0x01, 0x02, 0xdc, 0x3d, 0x01, 0x02, 0xec, 0x16, 0x02, 0x02, 0xf0, 0x16, 0x02, 0x02, 0xf4, 0x16, 0x02, 0x02, 0xf8, 0x16, 0x02, 0x02, + 0xfc, 0x16, 0x02, 0x02, 0xe8, 0x37, 0x03, 0x03, 0xf0, 0x37, 0x03, 0x03, 0xf8, 0x37, 0x03, 0x03, 0xc0, 0x12, 0x04, 0x03, 0xc8, 0x12, 0x04, 0x03, 0xc0, 0x31, 0x05, 0x04, 0x00, 0x0f, 0x06, 0x04, + 0xe0, 0x2d, 0x07, 0x05, 0x80, 0x2a, 0x09, 0x06, 0x34, 0x0b, 0x00, 0x02, 0x38, 0x0b, 0x00, 0x02, 0x3c, 0x0b, 0x00, 0x02, 0x40, 0x0b, 0x00, 0x02, 0xe0, 0x3d, 0x01, 0x02, 0xe4, 0x3d, 0x01, 0x02, + 0xe8, 0x3d, 0x01, 0x02, 0xec, 0x3d, 0x01, 0x02, 0xf0, 0x3d, 0x01, 0x02, 0xf4, 0x3d, 0x01, 0x02, 0x00, 0x17, 0x02, 0x02, 0x04, 0x17, 0x02, 0x02, 0x08, 0x17, 0x02, 0x02, 0x0c, 0x17, 0x02, 0x02, + 0x10, 0x17, 0x02, 0x02, 0x00, 0x38, 0x03, 0x03, 0x08, 0x38, 0x03, 0x03, 0x10, 0x38, 0x03, 0x03, 0xd0, 0x12, 0x04, 0x03, 0xd8, 0x12, 0x04, 0x03, 0xd0, 0x31, 0x05, 0x04, 0x10, 0x0f, 0x06, 0x04, + 0x00, 0x2e, 0x07, 0x05, 0xc0, 0x2a, 0x09, 0x06, 0x44, 0x0b, 0x00, 0x02, 0x48, 0x0b, 0x00, 0x02, 0x4c, 0x0b, 0x00, 0x02, 0x50, 0x0b, 0x00, 0x02, 0xf8, 0x3d, 0x01, 0x02, 0xfc, 0x3d, 0x01, 0x02, + 0x00, 0x3e, 0x01, 0x02, 0x04, 0x3e, 0x01, 0x02, 0x08, 0x3e, 0x01, 0x02, 0x0c, 0x3e, 0x01, 0x02, 0x14, 0x17, 0x02, 0x02, 0x18, 0x17, 0x02, 0x02, 0x1c, 0x17, 0x02, 0x02, 0x20, 0x17, 0x02, 0x02, + 0x24, 0x17, 0x02, 0x02, 0x18, 0x38, 0x03, 0x03, 0x20, 0x38, 0x03, 0x03, 0x28, 0x38, 0x03, 0x03, 0xe0, 0x12, 0x04, 0x03, 0xe8, 0x12, 0x04, 0x03, 0xe0, 0x31, 0x05, 0x04, 0x20, 0x0f, 0x06, 0x04, + 0x20, 0x2e, 0x07, 0x05, 0x00, 0x2b, 0x09, 0x06, 0x54, 0x0b, 0x00, 0x02, 0x58, 0x0b, 0x00, 0x02, 0x5c, 0x0b, 0x00, 0x02, 0x60, 0x0b, 0x00, 0x02, 0x10, 0x3e, 0x01, 0x02, 0x14, 0x3e, 0x01, 0x02, + 0x18, 0x3e, 0x01, 0x02, 0x1c, 0x3e, 0x01, 0x02, 0x20, 0x3e, 0x01, 0x02, 0x24, 0x3e, 0x01, 0x02, 0x28, 0x17, 0x02, 0x02, 0x2c, 0x17, 0x02, 0x02, 0x30, 0x17, 0x02, 0x02, 0x34, 0x17, 0x02, 0x02, + 0x38, 0x17, 0x02, 0x02, 0x30, 0x38, 0x03, 0x03, 0x38, 0x38, 0x03, 0x03, 0x40, 0x38, 0x03, 0x03, 0xf0, 0x12, 0x04, 0x03, 0xf8, 0x12, 0x04, 0x03, 0xf0, 0x31, 0x05, 0x04, 0x30, 0x0f, 0x06, 0x04, + 0x40, 0x2e, 0x07, 0x05, 0x40, 0x2b, 0x09, 0x06, 0x64, 0x0b, 0x00, 0x02, 0x68, 0x0b, 0x00, 0x02, 0x6c, 0x0b, 0x00, 0x02, 0x70, 0x0b, 0x00, 0x02, 0x28, 0x3e, 0x01, 0x02, 0x2c, 0x3e, 0x01, 0x02, + 0x30, 0x3e, 0x01, 0x02, 0x34, 0x3e, 0x01, 0x02, 0x38, 0x3e, 0x01, 0x02, 0x3c, 0x3e, 0x01, 0x02, 0x3c, 0x17, 0x02, 0x02, 0x40, 0x17, 0x02, 0x02, 0x44, 0x17, 0x02, 0x02, 0x48, 0x17, 0x02, 0x02, + 0x4c, 0x17, 0x02, 0x02, 0x48, 0x38, 0x03, 0x03, 0x50, 0x38, 0x03, 0x03, 0x58, 0x38, 0x03, 0x03, 0x00, 0x13, 0x04, 0x03, 0x08, 0x13, 0x04, 0x03, 0x00, 0x32, 0x05, 0x04, 0x40, 0x0f, 0x06, 0x04, + 0x60, 0x2e, 0x07, 0x05, 0x80, 0x2b, 0x09, 0x06, 0x74, 0x0b, 0x00, 0x02, 0x78, 0x0b, 0x00, 0x02, 0x7c, 0x0b, 0x00, 0x02, 0x80, 0x0b, 0x00, 0x02, 0x40, 0x3e, 0x01, 0x02, 0x44, 0x3e, 0x01, 0x02, + 0x48, 0x3e, 0x01, 0x02, 0x4c, 0x3e, 0x01, 0x02, 0x50, 0x3e, 0x01, 0x02, 0x54, 0x3e, 0x01, 0x02, 0x50, 0x17, 0x02, 0x02, 0x54, 0x17, 0x02, 0x02, 0x58, 0x17, 0x02, 0x02, 0x5c, 0x17, 0x02, 0x02, + 0x60, 0x17, 0x02, 0x02, 0x60, 0x38, 0x03, 0x03, 0x68, 0x38, 0x03, 0x03, 0x70, 0x38, 0x03, 0x03, 0x10, 0x13, 0x04, 0x03, 0x18, 0x13, 0x04, 0x03, 0x10, 0x32, 0x05, 0x04, 0x50, 0x0f, 0x06, 0x04, + 0x80, 0x2e, 0x07, 0x05, 0xc0, 0x2b, 0x09, 0x06, 0x84, 0x0b, 0x00, 0x02, 0x88, 0x0b, 0x00, 0x02, 0x8c, 0x0b, 0x00, 0x02, 0x90, 0x0b, 0x00, 0x02, 0x58, 0x3e, 0x01, 0x02, 0x5c, 0x3e, 0x01, 0x02, + 0x60, 0x3e, 0x01, 0x02, 0x64, 0x3e, 0x01, 0x02, 0x68, 0x3e, 0x01, 0x02, 0x6c, 0x3e, 0x01, 0x02, 0x64, 0x17, 0x02, 0x02, 0x68, 0x17, 0x02, 0x02, 0x6c, 0x17, 0x02, 0x02, 0x70, 0x17, 0x02, 0x02, + 0x74, 0x17, 0x02, 0x02, 0x78, 0x38, 0x03, 0x03, 0x80, 0x38, 0x03, 0x03, 0x88, 0x38, 0x03, 0x03, 0x20, 0x13, 0x04, 0x03, 0x28, 0x13, 0x04, 0x03, 0x20, 0x32, 0x05, 0x04, 0x60, 0x0f, 0x06, 0x04, + 0xa0, 0x2e, 0x07, 0x05, 0x00, 0x2c, 0x09, 0x06, 0x94, 0x0b, 0x00, 0x02, 0x98, 0x0b, 0x00, 0x02, 0x9c, 0x0b, 0x00, 0x02, 0xa0, 0x0b, 0x00, 0x02, 0x70, 0x3e, 0x01, 0x02, 0x74, 0x3e, 0x01, 0x02, + 0x78, 0x3e, 0x01, 0x02, 0x7c, 0x3e, 0x01, 0x02, 0x80, 0x3e, 0x01, 0x02, 0x84, 0x3e, 0x01, 0x02, 0x78, 0x17, 0x02, 0x02, 0x7c, 0x17, 0x02, 0x02, 0x80, 0x17, 0x02, 0x02, 0x84, 0x17, 0x02, 0x02, + 0x88, 0x17, 0x02, 0x02, 0x90, 0x38, 0x03, 0x03, 0x98, 0x38, 0x03, 0x03, 0xa0, 0x38, 0x03, 0x03, 0x30, 0x13, 0x04, 0x03, 0x38, 0x13, 0x04, 0x03, 0x30, 0x32, 0x05, 0x04, 0x70, 0x0f, 0x06, 0x04, + 0xc0, 0x2e, 0x07, 0x05, 0x40, 0x2c, 0x09, 0x06, 0xa4, 0x0b, 0x00, 0x02, 0xa8, 0x0b, 0x00, 0x02, 0xac, 0x0b, 0x00, 0x02, 0xb0, 0x0b, 0x00, 0x02, 0x88, 0x3e, 0x01, 0x02, 0x8c, 0x3e, 0x01, 0x02, + 0x90, 0x3e, 0x01, 0x02, 0x94, 0x3e, 0x01, 0x02, 0x98, 0x3e, 0x01, 0x02, 0x9c, 0x3e, 0x01, 0x02, 0x8c, 0x17, 0x02, 0x02, 0x90, 0x17, 0x02, 0x02, 0x94, 0x17, 0x02, 0x02, 0x98, 0x17, 0x02, 0x02, + 0x9c, 0x17, 0x02, 0x02, 0xa8, 0x38, 0x03, 0x03, 0xb0, 0x38, 0x03, 0x03, 0xb8, 0x38, 0x03, 0x03, 0x40, 0x13, 0x04, 0x03, 0x48, 0x13, 0x04, 0x03, 0x40, 0x32, 0x05, 0x04, 0x80, 0x0f, 0x06, 0x04, + 0xe0, 0x2e, 0x07, 0x05, 0x80, 0x2c, 0x09, 0x06, 0xb4, 0x0b, 0x00, 0x02, 0xb8, 0x0b, 0x00, 0x02, 0xbc, 0x0b, 0x00, 0x02, 0xc0, 0x0b, 0x00, 0x02, 0xa0, 0x3e, 0x01, 0x02, 0xa4, 0x3e, 0x01, 0x02, + 0xa8, 0x3e, 0x01, 0x02, 0xac, 0x3e, 0x01, 0x02, 0xb0, 0x3e, 0x01, 0x02, 0xb4, 0x3e, 0x01, 0x02, 0xa0, 0x17, 0x02, 0x02, 0xa4, 0x17, 0x02, 0x02, 0xa8, 0x17, 0x02, 0x02, 0xac, 0x17, 0x02, 0x02, + 0xb0, 0x17, 0x02, 0x02, 0xc0, 0x38, 0x03, 0x03, 0xc8, 0x38, 0x03, 0x03, 0xd0, 0x38, 0x03, 0x03, 0x50, 0x13, 0x04, 0x03, 0x58, 0x13, 0x04, 0x03, 0x50, 0x32, 0x05, 0x04, 0x90, 0x0f, 0x06, 0x04, + 0x00, 0x2f, 0x07, 0x05, 0xc0, 0x2c, 0x09, 0x06, 0xc4, 0x0b, 0x00, 0x02, 0xc8, 0x0b, 0x00, 0x02, 0xcc, 0x0b, 0x00, 0x02, 0xd0, 0x0b, 0x00, 0x02, 0xb8, 0x3e, 0x01, 0x02, 0xbc, 0x3e, 0x01, 0x02, + 0xc0, 0x3e, 0x01, 0x02, 0xc4, 0x3e, 0x01, 0x02, 0xc8, 0x3e, 0x01, 0x02, 0xcc, 0x3e, 0x01, 0x02, 0xb4, 0x17, 0x02, 0x02, 0xb8, 0x17, 0x02, 0x02, 0xbc, 0x17, 0x02, 0x02, 0xc0, 0x17, 0x02, 0x02, + 0xc4, 0x17, 0x02, 0x02, 0xd8, 0x38, 0x03, 0x03, 0xe0, 0x38, 0x03, 0x03, 0xe8, 0x38, 0x03, 0x03, 0x60, 0x13, 0x04, 0x03, 0x68, 0x13, 0x04, 0x03, 0x60, 0x32, 0x05, 0x04, 0xa0, 0x0f, 0x06, 0x04, + 0x20, 0x2f, 0x07, 0x05, 0xc0, 0x06, 0x0a, 0x06, 0xd4, 0x0b, 0x00, 0x02, 0xd8, 0x0b, 0x00, 0x02, 0xdc, 0x0b, 0x00, 0x02, 0xe0, 0x0b, 0x00, 0x02, 0xd0, 0x3e, 0x01, 0x02, 0xd4, 0x3e, 0x01, 0x02, + 0xd8, 0x3e, 0x01, 0x02, 0xdc, 0x3e, 0x01, 0x02, 0xe0, 0x3e, 0x01, 0x02, 0xe4, 0x3e, 0x01, 0x02, 0xc8, 0x17, 0x02, 0x02, 0xcc, 0x17, 0x02, 0x02, 0xd0, 0x17, 0x02, 0x02, 0xd4, 0x17, 0x02, 0x02, + 0xd8, 0x17, 0x02, 0x02, 0xf0, 0x38, 0x03, 0x03, 0xf8, 0x38, 0x03, 0x03, 0x00, 0x39, 0x03, 0x03, 0x70, 0x13, 0x04, 0x03, 0x78, 0x13, 0x04, 0x03, 0x70, 0x32, 0x05, 0x04, 0xb0, 0x0f, 0x06, 0x04, + 0x40, 0x2f, 0x07, 0x05, 0x00, 0x07, 0x0a, 0x06, 0xe4, 0x0b, 0x00, 0x02, 0xe8, 0x0b, 0x00, 0x02, 0xec, 0x0b, 0x00, 0x02, 0xf0, 0x0b, 0x00, 0x02, 0xe8, 0x3e, 0x01, 0x02, 0xec, 0x3e, 0x01, 0x02, + 0xf0, 0x3e, 0x01, 0x02, 0xf4, 0x3e, 0x01, 0x02, 0xf8, 0x3e, 0x01, 0x02, 0xfc, 0x3e, 0x01, 0x02, 0xdc, 0x17, 0x02, 0x02, 0xe0, 0x17, 0x02, 0x02, 0xe4, 0x17, 0x02, 0x02, 0xe8, 0x17, 0x02, 0x02, + 0xec, 0x17, 0x02, 0x02, 0x08, 0x39, 0x03, 0x03, 0x10, 0x39, 0x03, 0x03, 0x18, 0x39, 0x03, 0x03, 0x80, 0x13, 0x04, 0x03, 0x88, 0x13, 0x04, 0x03, 0x80, 0x32, 0x05, 0x04, 0xc0, 0x0f, 0x06, 0x04, + 0x60, 0x2f, 0x07, 0x05, 0x40, 0x07, 0x0a, 0x06, 0xf4, 0x0b, 0x00, 0x02, 0xf8, 0x0b, 0x00, 0x02, 0xfc, 0x0b, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x3f, 0x01, 0x02, 0x04, 0x3f, 0x01, 0x02, + 0x08, 0x3f, 0x01, 0x02, 0x0c, 0x3f, 0x01, 0x02, 0x10, 0x3f, 0x01, 0x02, 0x14, 0x3f, 0x01, 0x02, 0xf0, 0x17, 0x02, 0x02, 0xf4, 0x17, 0x02, 0x02, 0xf8, 0x17, 0x02, 0x02, 0xfc, 0x17, 0x02, 0x02, + 0x00, 0x18, 0x02, 0x02, 0x20, 0x39, 0x03, 0x03, 0x28, 0x39, 0x03, 0x03, 0x30, 0x39, 0x03, 0x03, 0x90, 0x13, 0x04, 0x03, 0x98, 0x13, 0x04, 0x03, 0x90, 0x32, 0x05, 0x04, 0xd0, 0x0f, 0x06, 0x04, + 0x80, 0x2f, 0x07, 0x05, 0x80, 0x07, 0x0a, 0x06, 0x04, 0x0c, 0x00, 0x02, 0x08, 0x0c, 0x00, 0x02, 0x0c, 0x0c, 0x00, 0x02, 0x10, 0x0c, 0x00, 0x02, 0x18, 0x3f, 0x01, 0x02, 0x1c, 0x3f, 0x01, 0x02, + 0x20, 0x3f, 0x01, 0x02, 0x24, 0x3f, 0x01, 0x02, 0x28, 0x3f, 0x01, 0x02, 0x2c, 0x3f, 0x01, 0x02, 0x04, 0x18, 0x02, 0x02, 0x08, 0x18, 0x02, 0x02, 0x0c, 0x18, 0x02, 0x02, 0x10, 0x18, 0x02, 0x02, + 0x14, 0x18, 0x02, 0x02, 0x38, 0x39, 0x03, 0x03, 0x40, 0x39, 0x03, 0x03, 0xa0, 0x13, 0x04, 0x03, 0xa8, 0x13, 0x04, 0x03, 0xb0, 0x13, 0x04, 0x03, 0xa0, 0x32, 0x05, 0x04, 0xe0, 0x0f, 0x06, 0x04, + 0xa0, 0x2f, 0x07, 0x05, 0xc0, 0x07, 0x0a, 0x06, 0x14, 0x0c, 0x00, 0x02, 0x18, 0x0c, 0x00, 0x02, 0x1c, 0x0c, 0x00, 0x02, 0x20, 0x0c, 0x00, 0x02, 0x30, 0x3f, 0x01, 0x02, 0x34, 0x3f, 0x01, 0x02, + 0x38, 0x3f, 0x01, 0x02, 0x3c, 0x3f, 0x01, 0x02, 0x40, 0x3f, 0x01, 0x02, 0x44, 0x3f, 0x01, 0x02, 0x18, 0x18, 0x02, 0x02, 0x1c, 0x18, 0x02, 0x02, 0x20, 0x18, 0x02, 0x02, 0x24, 0x18, 0x02, 0x02, + 0x48, 0x39, 0x03, 0x03, 0x50, 0x39, 0x03, 0x03, 0x58, 0x39, 0x03, 0x03, 0xb8, 0x13, 0x04, 0x03, 0xc0, 0x13, 0x04, 0x03, 0xc8, 0x13, 0x04, 0x03, 0xb0, 0x32, 0x05, 0x04, 0xf0, 0x0f, 0x06, 0x04, + 0xc0, 0x2f, 0x07, 0x05, 0x00, 0x08, 0x0a, 0x06, 0x24, 0x0c, 0x00, 0x02, 0x28, 0x0c, 0x00, 0x02, 0x2c, 0x0c, 0x00, 0x02, 0x30, 0x0c, 0x00, 0x02, 0x48, 0x3f, 0x01, 0x02, 0x4c, 0x3f, 0x01, 0x02, + 0x50, 0x3f, 0x01, 0x02, 0x54, 0x3f, 0x01, 0x02, 0x58, 0x3f, 0x01, 0x02, 0x5c, 0x3f, 0x01, 0x02, 0x28, 0x18, 0x02, 0x02, 0x2c, 0x18, 0x02, 0x02, 0x30, 0x18, 0x02, 0x02, 0x34, 0x18, 0x02, 0x02, + 0x60, 0x39, 0x03, 0x03, 0x68, 0x39, 0x03, 0x03, 0x70, 0x39, 0x03, 0x03, 0xd0, 0x13, 0x04, 0x03, 0xd8, 0x13, 0x04, 0x03, 0xe0, 0x13, 0x04, 0x03, 0xc0, 0x32, 0x05, 0x04, 0x00, 0x10, 0x06, 0x04, + 0xe0, 0x2f, 0x07, 0x05, 0x40, 0x08, 0x0a, 0x06, 0x34, 0x0c, 0x00, 0x02, 0x38, 0x0c, 0x00, 0x02, 0x3c, 0x0c, 0x00, 0x02, 0x40, 0x0c, 0x00, 0x02, 0x60, 0x3f, 0x01, 0x02, 0x64, 0x3f, 0x01, 0x02, + 0x68, 0x3f, 0x01, 0x02, 0x6c, 0x3f, 0x01, 0x02, 0x70, 0x3f, 0x01, 0x02, 0x74, 0x3f, 0x01, 0x02, 0x38, 0x18, 0x02, 0x02, 0x3c, 0x18, 0x02, 0x02, 0x40, 0x18, 0x02, 0x02, 0x44, 0x18, 0x02, 0x02, + 0x78, 0x39, 0x03, 0x03, 0x80, 0x39, 0x03, 0x03, 0x88, 0x39, 0x03, 0x03, 0xe8, 0x13, 0x04, 0x03, 0xf0, 0x13, 0x04, 0x03, 0xf8, 0x13, 0x04, 0x03, 0xd0, 0x32, 0x05, 0x04, 0x10, 0x10, 0x06, 0x04, + 0x00, 0x30, 0x07, 0x05, 0x80, 0x08, 0x0a, 0x06, 0x44, 0x0c, 0x00, 0x02, 0x48, 0x0c, 0x00, 0x02, 0x4c, 0x0c, 0x00, 0x02, 0x50, 0x0c, 0x00, 0x02, 0x78, 0x3f, 0x01, 0x02, 0x7c, 0x3f, 0x01, 0x02, + 0x80, 0x3f, 0x01, 0x02, 0x84, 0x3f, 0x01, 0x02, 0x88, 0x3f, 0x01, 0x02, 0x8c, 0x3f, 0x01, 0x02, 0x48, 0x18, 0x02, 0x02, 0x4c, 0x18, 0x02, 0x02, 0x50, 0x18, 0x02, 0x02, 0x54, 0x18, 0x02, 0x02, + 0x90, 0x39, 0x03, 0x03, 0x98, 0x39, 0x03, 0x03, 0xa0, 0x39, 0x03, 0x03, 0x00, 0x14, 0x04, 0x03, 0x08, 0x14, 0x04, 0x03, 0x10, 0x14, 0x04, 0x03, 0xe0, 0x32, 0x05, 0x04, 0x20, 0x10, 0x06, 0x04, + 0x20, 0x30, 0x07, 0x05, 0xc0, 0x08, 0x0a, 0x06, 0x54, 0x0c, 0x00, 0x02, 0x58, 0x0c, 0x00, 0x02, 0x5c, 0x0c, 0x00, 0x02, 0x60, 0x0c, 0x00, 0x02, 0x90, 0x3f, 0x01, 0x02, 0x94, 0x3f, 0x01, 0x02, + 0x98, 0x3f, 0x01, 0x02, 0x9c, 0x3f, 0x01, 0x02, 0xa0, 0x3f, 0x01, 0x02, 0xa4, 0x3f, 0x01, 0x02, 0x58, 0x18, 0x02, 0x02, 0x5c, 0x18, 0x02, 0x02, 0x60, 0x18, 0x02, 0x02, 0x64, 0x18, 0x02, 0x02, + 0xa8, 0x39, 0x03, 0x03, 0xb0, 0x39, 0x03, 0x03, 0xb8, 0x39, 0x03, 0x03, 0x18, 0x14, 0x04, 0x03, 0x20, 0x14, 0x04, 0x03, 0x28, 0x14, 0x04, 0x03, 0xf0, 0x32, 0x05, 0x04, 0x30, 0x10, 0x06, 0x04, + 0x40, 0x30, 0x07, 0x05, 0x00, 0x09, 0x0a, 0x06, 0x64, 0x0c, 0x00, 0x02, 0x68, 0x0c, 0x00, 0x02, 0x6c, 0x0c, 0x00, 0x02, 0x70, 0x0c, 0x00, 0x02, 0xa8, 0x3f, 0x01, 0x02, 0xac, 0x3f, 0x01, 0x02, + 0xb0, 0x3f, 0x01, 0x02, 0xb4, 0x3f, 0x01, 0x02, 0xb8, 0x3f, 0x01, 0x02, 0xbc, 0x3f, 0x01, 0x02, 0x68, 0x18, 0x02, 0x02, 0x6c, 0x18, 0x02, 0x02, 0x70, 0x18, 0x02, 0x02, 0x74, 0x18, 0x02, 0x02, + 0xc0, 0x39, 0x03, 0x03, 0xc8, 0x39, 0x03, 0x03, 0xd0, 0x39, 0x03, 0x03, 0x30, 0x14, 0x04, 0x03, 0x38, 0x14, 0x04, 0x03, 0x00, 0x33, 0x05, 0x04, 0x10, 0x33, 0x05, 0x04, 0x40, 0x10, 0x06, 0x04, + 0x60, 0x30, 0x07, 0x05, 0x40, 0x09, 0x0a, 0x06, 0x74, 0x0c, 0x00, 0x02, 0x78, 0x0c, 0x00, 0x02, 0x7c, 0x0c, 0x00, 0x02, 0x80, 0x0c, 0x00, 0x02, 0xc0, 0x3f, 0x01, 0x02, 0xc4, 0x3f, 0x01, 0x02, + 0xc8, 0x3f, 0x01, 0x02, 0xcc, 0x3f, 0x01, 0x02, 0xd0, 0x3f, 0x01, 0x02, 0xd4, 0x3f, 0x01, 0x02, 0x78, 0x18, 0x02, 0x02, 0x7c, 0x18, 0x02, 0x02, 0x80, 0x18, 0x02, 0x02, 0x84, 0x18, 0x02, 0x02, + 0xd8, 0x39, 0x03, 0x03, 0xe0, 0x39, 0x03, 0x03, 0xe8, 0x39, 0x03, 0x03, 0x40, 0x14, 0x04, 0x03, 0x48, 0x14, 0x04, 0x03, 0x20, 0x33, 0x05, 0x04, 0x30, 0x33, 0x05, 0x04, 0x50, 0x10, 0x06, 0x04, + 0x80, 0x30, 0x07, 0x05, 0x80, 0x09, 0x0a, 0x06, 0x84, 0x0c, 0x00, 0x02, 0x88, 0x0c, 0x00, 0x02, 0x8c, 0x0c, 0x00, 0x02, 0x90, 0x0c, 0x00, 0x02, 0xd8, 0x3f, 0x01, 0x02, 0xdc, 0x3f, 0x01, 0x02, + 0xe0, 0x3f, 0x01, 0x02, 0xe4, 0x3f, 0x01, 0x02, 0xe8, 0x3f, 0x01, 0x02, 0xec, 0x3f, 0x01, 0x02, 0x88, 0x18, 0x02, 0x02, 0x8c, 0x18, 0x02, 0x02, 0x90, 0x18, 0x02, 0x02, 0x94, 0x18, 0x02, 0x02, + 0xf0, 0x39, 0x03, 0x03, 0xf8, 0x39, 0x03, 0x03, 0x00, 0x3a, 0x03, 0x03, 0x50, 0x14, 0x04, 0x03, 0x58, 0x14, 0x04, 0x03, 0x40, 0x33, 0x05, 0x04, 0x50, 0x33, 0x05, 0x04, 0x60, 0x10, 0x06, 0x04, + 0xa0, 0x30, 0x07, 0x05, 0xc0, 0x09, 0x0a, 0x06, 0x94, 0x0c, 0x00, 0x02, 0x98, 0x0c, 0x00, 0x02, 0x9c, 0x0c, 0x00, 0x02, 0xa0, 0x0c, 0x00, 0x02, 0xf0, 0x3f, 0x01, 0x02, 0xf4, 0x3f, 0x01, 0x02, + 0xf8, 0x3f, 0x01, 0x02, 0xfc, 0x3f, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x98, 0x18, 0x02, 0x02, 0x9c, 0x18, 0x02, 0x02, 0xa0, 0x18, 0x02, 0x02, 0xa4, 0x18, 0x02, 0x02, + 0x08, 0x3a, 0x03, 0x03, 0x10, 0x3a, 0x03, 0x03, 0x18, 0x3a, 0x03, 0x03, 0x60, 0x14, 0x04, 0x03, 0x68, 0x14, 0x04, 0x03, 0x60, 0x33, 0x05, 0x04, 0x70, 0x33, 0x05, 0x04, 0x70, 0x10, 0x06, 0x04, + 0xc0, 0x30, 0x07, 0x05, 0x00, 0x0a, 0x0a, 0x06, 0xa4, 0x0c, 0x00, 0x02, 0xa8, 0x0c, 0x00, 0x02, 0xac, 0x0c, 0x00, 0x02, 0xb0, 0x0c, 0x00, 0x02, 0x04, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x01, + 0x08, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x01, 0x0c, 0x00, 0x01, 0x01, 0x0e, 0x00, 0x01, 0x01, 0xa8, 0x18, 0x02, 0x02, 0xac, 0x18, 0x02, 0x02, 0xb0, 0x18, 0x02, 0x02, 0xb4, 0x18, 0x02, 0x02, + 0x20, 0x3a, 0x03, 0x03, 0x28, 0x3a, 0x03, 0x03, 0x30, 0x3a, 0x03, 0x03, 0x70, 0x14, 0x04, 0x03, 0x78, 0x14, 0x04, 0x03, 0x80, 0x33, 0x05, 0x04, 0x90, 0x33, 0x05, 0x04, 0x80, 0x10, 0x06, 0x04, + 0xe0, 0x30, 0x07, 0x05, 0x40, 0x0a, 0x0a, 0x06, 0xb4, 0x0c, 0x00, 0x02, 0xb8, 0x0c, 0x00, 0x02, 0xbc, 0x0c, 0x00, 0x02, 0xc0, 0x0c, 0x00, 0x02, 0x10, 0x00, 0x01, 0x01, 0x12, 0x00, 0x01, 0x01, + 0x14, 0x00, 0x01, 0x01, 0x16, 0x00, 0x01, 0x01, 0x18, 0x00, 0x01, 0x01, 0x1a, 0x00, 0x01, 0x01, 0xb8, 0x18, 0x02, 0x02, 0xbc, 0x18, 0x02, 0x02, 0xc0, 0x18, 0x02, 0x02, 0xc4, 0x18, 0x02, 0x02, + 0x38, 0x3a, 0x03, 0x03, 0x40, 0x3a, 0x03, 0x03, 0x48, 0x3a, 0x03, 0x03, 0x80, 0x14, 0x04, 0x03, 0x88, 0x14, 0x04, 0x03, 0xa0, 0x33, 0x05, 0x04, 0xb0, 0x33, 0x05, 0x04, 0x90, 0x10, 0x06, 0x04, + 0x00, 0x31, 0x07, 0x05, 0x80, 0x0a, 0x0a, 0x06, 0xc4, 0x0c, 0x00, 0x02, 0xc8, 0x0c, 0x00, 0x02, 0xcc, 0x0c, 0x00, 0x02, 0xd0, 0x0c, 0x00, 0x02, 0x1c, 0x00, 0x01, 0x01, 0x1e, 0x00, 0x01, 0x01, + 0x20, 0x00, 0x01, 0x01, 0x22, 0x00, 0x01, 0x01, 0x24, 0x00, 0x01, 0x01, 0x26, 0x00, 0x01, 0x01, 0xc8, 0x18, 0x02, 0x02, 0xcc, 0x18, 0x02, 0x02, 0xd0, 0x18, 0x02, 0x02, 0xd4, 0x18, 0x02, 0x02, + 0x50, 0x3a, 0x03, 0x03, 0x58, 0x3a, 0x03, 0x03, 0x60, 0x3a, 0x03, 0x03, 0x90, 0x14, 0x04, 0x03, 0x98, 0x14, 0x04, 0x03, 0xc0, 0x33, 0x05, 0x04, 0xd0, 0x33, 0x05, 0x04, 0xa0, 0x10, 0x06, 0x04, + 0x20, 0x31, 0x07, 0x05, 0xc0, 0x0a, 0x0a, 0x06, 0xd4, 0x0c, 0x00, 0x02, 0xd8, 0x0c, 0x00, 0x02, 0xdc, 0x0c, 0x00, 0x02, 0xe0, 0x0c, 0x00, 0x02, 0x28, 0x00, 0x01, 0x01, 0x2a, 0x00, 0x01, 0x01, + 0x2c, 0x00, 0x01, 0x01, 0x2e, 0x00, 0x01, 0x01, 0x30, 0x00, 0x01, 0x01, 0x32, 0x00, 0x01, 0x01, 0xd8, 0x18, 0x02, 0x02, 0xdc, 0x18, 0x02, 0x02, 0xe0, 0x18, 0x02, 0x02, 0xe4, 0x18, 0x02, 0x02, + 0x68, 0x3a, 0x03, 0x03, 0x70, 0x3a, 0x03, 0x03, 0x78, 0x3a, 0x03, 0x03, 0xa0, 0x14, 0x04, 0x03, 0xa8, 0x14, 0x04, 0x03, 0xe0, 0x33, 0x05, 0x04, 0xf0, 0x33, 0x05, 0x04, 0xb0, 0x10, 0x06, 0x04, + 0xa0, 0x0a, 0x08, 0x05, 0x00, 0x0b, 0x0a, 0x06, 0xe4, 0x0c, 0x00, 0x02, 0xe8, 0x0c, 0x00, 0x02, 0xec, 0x0c, 0x00, 0x02, 0xf0, 0x0c, 0x00, 0x02, 0x34, 0x00, 0x01, 0x01, 0x36, 0x00, 0x01, 0x01, + 0x38, 0x00, 0x01, 0x01, 0x3a, 0x00, 0x01, 0x01, 0x3c, 0x00, 0x01, 0x01, 0x3e, 0x00, 0x01, 0x01, 0xe8, 0x18, 0x02, 0x02, 0xec, 0x18, 0x02, 0x02, 0xf0, 0x18, 0x02, 0x02, 0xf4, 0x18, 0x02, 0x02, + 0x80, 0x3a, 0x03, 0x03, 0x88, 0x3a, 0x03, 0x03, 0x90, 0x3a, 0x03, 0x03, 0xb0, 0x14, 0x04, 0x03, 0xb8, 0x14, 0x04, 0x03, 0x00, 0x34, 0x05, 0x04, 0x10, 0x34, 0x05, 0x04, 0xc0, 0x10, 0x06, 0x04, + 0xc0, 0x0a, 0x08, 0x05, 0x40, 0x0b, 0x0a, 0x06, 0xf4, 0x0c, 0x00, 0x02, 0xf8, 0x0c, 0x00, 0x02, 0xfc, 0x0c, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x02, 0x40, 0x00, 0x01, 0x01, 0x42, 0x00, 0x01, 0x01, + 0x44, 0x00, 0x01, 0x01, 0x46, 0x00, 0x01, 0x01, 0x48, 0x00, 0x01, 0x01, 0x4a, 0x00, 0x01, 0x01, 0xf8, 0x18, 0x02, 0x02, 0xfc, 0x18, 0x02, 0x02, 0x00, 0x19, 0x02, 0x02, 0x04, 0x19, 0x02, 0x02, + 0x98, 0x3a, 0x03, 0x03, 0xa0, 0x3a, 0x03, 0x03, 0xa8, 0x3a, 0x03, 0x03, 0xc0, 0x14, 0x04, 0x03, 0xc8, 0x14, 0x04, 0x03, 0x20, 0x34, 0x05, 0x04, 0x30, 0x34, 0x05, 0x04, 0xd0, 0x10, 0x06, 0x04, + 0xe0, 0x0a, 0x08, 0x05, 0x80, 0x21, 0x0b, 0x07, 0x04, 0x0d, 0x00, 0x02, 0x08, 0x0d, 0x00, 0x02, 0x0c, 0x0d, 0x00, 0x02, 0x10, 0x0d, 0x00, 0x02, 0x4c, 0x00, 0x01, 0x01, 0x4e, 0x00, 0x01, 0x01, + 0x50, 0x00, 0x01, 0x01, 0x52, 0x00, 0x01, 0x01, 0x54, 0x00, 0x01, 0x01, 0x56, 0x00, 0x01, 0x01, 0x08, 0x19, 0x02, 0x02, 0x0c, 0x19, 0x02, 0x02, 0x10, 0x19, 0x02, 0x02, 0x14, 0x19, 0x02, 0x02, + 0xb0, 0x3a, 0x03, 0x03, 0xb8, 0x3a, 0x03, 0x03, 0xc0, 0x3a, 0x03, 0x03, 0xd0, 0x14, 0x04, 0x03, 0xd8, 0x14, 0x04, 0x03, 0x40, 0x34, 0x05, 0x04, 0x50, 0x34, 0x05, 0x04, 0xe0, 0x10, 0x06, 0x04, + 0x00, 0x0b, 0x08, 0x05, 0x00, 0x22, 0x0b, 0x07, 0x14, 0x0d, 0x00, 0x02, 0x18, 0x0d, 0x00, 0x02, 0x1c, 0x0d, 0x00, 0x02, 0x20, 0x0d, 0x00, 0x02, 0x58, 0x00, 0x01, 0x01, 0x5a, 0x00, 0x01, 0x01, + 0x5c, 0x00, 0x01, 0x01, 0x5e, 0x00, 0x01, 0x01, 0x60, 0x00, 0x01, 0x01, 0x62, 0x00, 0x01, 0x01, 0x18, 0x19, 0x02, 0x02, 0x1c, 0x19, 0x02, 0x02, 0x20, 0x19, 0x02, 0x02, 0x24, 0x19, 0x02, 0x02, + 0xc8, 0x3a, 0x03, 0x03, 0xd0, 0x3a, 0x03, 0x03, 0xd8, 0x3a, 0x03, 0x03, 0xe0, 0x14, 0x04, 0x03, 0xe8, 0x14, 0x04, 0x03, 0x60, 0x34, 0x05, 0x04, 0x70, 0x34, 0x05, 0x04, 0xf0, 0x10, 0x06, 0x04, + 0x20, 0x0b, 0x08, 0x05, 0x80, 0x22, 0x0b, 0x07, 0x24, 0x0d, 0x00, 0x02, 0x28, 0x0d, 0x00, 0x02, 0x2c, 0x0d, 0x00, 0x02, 0x30, 0x0d, 0x00, 0x02, 0x64, 0x00, 0x01, 0x01, 0x66, 0x00, 0x01, 0x01, + 0x68, 0x00, 0x01, 0x01, 0x6a, 0x00, 0x01, 0x01, 0x6c, 0x00, 0x01, 0x01, 0x6e, 0x00, 0x01, 0x01, 0x28, 0x19, 0x02, 0x02, 0x2c, 0x19, 0x02, 0x02, 0x30, 0x19, 0x02, 0x02, 0x34, 0x19, 0x02, 0x02, + 0xe0, 0x3a, 0x03, 0x03, 0xe8, 0x3a, 0x03, 0x03, 0xf0, 0x3a, 0x03, 0x03, 0xf0, 0x14, 0x04, 0x03, 0xf8, 0x14, 0x04, 0x03, 0x80, 0x34, 0x05, 0x04, 0x90, 0x34, 0x05, 0x04, 0x00, 0x11, 0x06, 0x04, + 0x40, 0x0b, 0x08, 0x05, 0x00, 0x23, 0x0b, 0x07, 0x34, 0x0d, 0x00, 0x02, 0x38, 0x0d, 0x00, 0x02, 0x3c, 0x0d, 0x00, 0x02, 0x40, 0x0d, 0x00, 0x02, 0x70, 0x00, 0x01, 0x01, 0x72, 0x00, 0x01, 0x01, + 0x74, 0x00, 0x01, 0x01, 0x76, 0x00, 0x01, 0x01, 0x78, 0x00, 0x01, 0x01, 0x7a, 0x00, 0x01, 0x01, 0x38, 0x19, 0x02, 0x02, 0x3c, 0x19, 0x02, 0x02, 0x40, 0x19, 0x02, 0x02, 0x44, 0x19, 0x02, 0x02, + 0xf8, 0x3a, 0x03, 0x03, 0x00, 0x3b, 0x03, 0x03, 0x08, 0x3b, 0x03, 0x03, 0x00, 0x15, 0x04, 0x03, 0x08, 0x15, 0x04, 0x03, 0xa0, 0x34, 0x05, 0x04, 0xb0, 0x34, 0x05, 0x04, 0x10, 0x11, 0x06, 0x04, + 0x60, 0x0b, 0x08, 0x05, 0x80, 0x23, 0x0b, 0x07, 0x44, 0x0d, 0x00, 0x02, 0x48, 0x0d, 0x00, 0x02, 0x4c, 0x0d, 0x00, 0x02, 0x50, 0x0d, 0x00, 0x02, 0x7c, 0x00, 0x01, 0x01, 0x7e, 0x00, 0x01, 0x01, + 0x80, 0x00, 0x01, 0x01, 0x82, 0x00, 0x01, 0x01, 0x84, 0x00, 0x01, 0x01, 0x86, 0x00, 0x01, 0x01, 0x48, 0x19, 0x02, 0x02, 0x4c, 0x19, 0x02, 0x02, 0x50, 0x19, 0x02, 0x02, 0x54, 0x19, 0x02, 0x02, + 0x10, 0x3b, 0x03, 0x03, 0x18, 0x3b, 0x03, 0x03, 0x20, 0x3b, 0x03, 0x03, 0x10, 0x15, 0x04, 0x03, 0x18, 0x15, 0x04, 0x03, 0xc0, 0x34, 0x05, 0x04, 0xd0, 0x34, 0x05, 0x04, 0x20, 0x11, 0x06, 0x04, + 0x80, 0x0b, 0x08, 0x05, 0x00, 0x24, 0x0b, 0x07, 0x54, 0x0d, 0x00, 0x02, 0x58, 0x0d, 0x00, 0x02, 0x5c, 0x0d, 0x00, 0x02, 0x60, 0x0d, 0x00, 0x02, 0x88, 0x00, 0x01, 0x01, 0x8a, 0x00, 0x01, 0x01, + 0x8c, 0x00, 0x01, 0x01, 0x8e, 0x00, 0x01, 0x01, 0x90, 0x00, 0x01, 0x01, 0x92, 0x00, 0x01, 0x01, 0x58, 0x19, 0x02, 0x02, 0x5c, 0x19, 0x02, 0x02, 0x60, 0x19, 0x02, 0x02, 0x64, 0x19, 0x02, 0x02, + 0x28, 0x3b, 0x03, 0x03, 0x30, 0x3b, 0x03, 0x03, 0x38, 0x3b, 0x03, 0x03, 0x20, 0x15, 0x04, 0x03, 0x28, 0x15, 0x04, 0x03, 0xe0, 0x34, 0x05, 0x04, 0xf0, 0x34, 0x05, 0x04, 0x30, 0x11, 0x06, 0x04, + 0xa0, 0x0b, 0x08, 0x05, 0x80, 0x24, 0x0b, 0x07, 0x64, 0x0d, 0x00, 0x02, 0x68, 0x0d, 0x00, 0x02, 0x6c, 0x0d, 0x00, 0x02, 0x70, 0x0d, 0x00, 0x02, 0x94, 0x00, 0x01, 0x01, 0x96, 0x00, 0x01, 0x01, + 0x98, 0x00, 0x01, 0x01, 0x9a, 0x00, 0x01, 0x01, 0x9c, 0x00, 0x01, 0x01, 0x9e, 0x00, 0x01, 0x01, 0x68, 0x19, 0x02, 0x02, 0x6c, 0x19, 0x02, 0x02, 0x70, 0x19, 0x02, 0x02, 0x74, 0x19, 0x02, 0x02, + 0x40, 0x3b, 0x03, 0x03, 0x48, 0x3b, 0x03, 0x03, 0x50, 0x3b, 0x03, 0x03, 0x30, 0x15, 0x04, 0x03, 0x38, 0x15, 0x04, 0x03, 0x00, 0x35, 0x05, 0x04, 0x10, 0x35, 0x05, 0x04, 0x40, 0x11, 0x06, 0x04, + 0xc0, 0x0b, 0x08, 0x05, 0x00, 0x25, 0x0b, 0x07, 0x74, 0x0d, 0x00, 0x02, 0x78, 0x0d, 0x00, 0x02, 0x7c, 0x0d, 0x00, 0x02, 0x80, 0x0d, 0x00, 0x02, 0xa0, 0x00, 0x01, 0x01, 0xa2, 0x00, 0x01, 0x01, + 0xa4, 0x00, 0x01, 0x01, 0xa6, 0x00, 0x01, 0x01, 0xa8, 0x00, 0x01, 0x01, 0xaa, 0x00, 0x01, 0x01, 0x78, 0x19, 0x02, 0x02, 0x7c, 0x19, 0x02, 0x02, 0x80, 0x19, 0x02, 0x02, 0x84, 0x19, 0x02, 0x02, + 0x58, 0x3b, 0x03, 0x03, 0x60, 0x3b, 0x03, 0x03, 0x68, 0x3b, 0x03, 0x03, 0x40, 0x15, 0x04, 0x03, 0x48, 0x15, 0x04, 0x03, 0x20, 0x35, 0x05, 0x04, 0x30, 0x35, 0x05, 0x04, 0x50, 0x11, 0x06, 0x04, + 0xe0, 0x0b, 0x08, 0x05, 0x80, 0x25, 0x0b, 0x07, 0x84, 0x0d, 0x00, 0x02, 0x88, 0x0d, 0x00, 0x02, 0x8c, 0x0d, 0x00, 0x02, 0x90, 0x0d, 0x00, 0x02, 0xac, 0x00, 0x01, 0x01, 0xae, 0x00, 0x01, 0x01, + 0xb0, 0x00, 0x01, 0x01, 0xb2, 0x00, 0x01, 0x01, 0xb4, 0x00, 0x01, 0x01, 0xb6, 0x00, 0x01, 0x01, 0x88, 0x19, 0x02, 0x02, 0x8c, 0x19, 0x02, 0x02, 0x90, 0x19, 0x02, 0x02, 0x94, 0x19, 0x02, 0x02, + 0x70, 0x3b, 0x03, 0x03, 0x78, 0x3b, 0x03, 0x03, 0x80, 0x3b, 0x03, 0x03, 0x50, 0x15, 0x04, 0x03, 0x58, 0x15, 0x04, 0x03, 0x40, 0x35, 0x05, 0x04, 0x50, 0x35, 0x05, 0x04, 0x60, 0x11, 0x06, 0x04, + 0x00, 0x0c, 0x08, 0x05, 0x00, 0x26, 0x0b, 0x07, 0x94, 0x0d, 0x00, 0x02, 0x98, 0x0d, 0x00, 0x02, 0x9c, 0x0d, 0x00, 0x02, 0xa0, 0x0d, 0x00, 0x02, 0xb8, 0x00, 0x01, 0x01, 0xba, 0x00, 0x01, 0x01, + 0xbc, 0x00, 0x01, 0x01, 0xbe, 0x00, 0x01, 0x01, 0xc0, 0x00, 0x01, 0x01, 0xc2, 0x00, 0x01, 0x01, 0x98, 0x19, 0x02, 0x02, 0x9c, 0x19, 0x02, 0x02, 0xa0, 0x19, 0x02, 0x02, 0xa4, 0x19, 0x02, 0x02, + 0x88, 0x3b, 0x03, 0x03, 0x90, 0x3b, 0x03, 0x03, 0x98, 0x3b, 0x03, 0x03, 0x60, 0x15, 0x04, 0x03, 0x68, 0x15, 0x04, 0x03, 0x60, 0x35, 0x05, 0x04, 0x70, 0x35, 0x05, 0x04, 0x70, 0x11, 0x06, 0x04, + 0x20, 0x0c, 0x08, 0x05, 0x80, 0x26, 0x0b, 0x07, 0xa4, 0x0d, 0x00, 0x02, 0xa8, 0x0d, 0x00, 0x02, 0xac, 0x0d, 0x00, 0x02, 0xb0, 0x0d, 0x00, 0x02, 0xc4, 0x00, 0x01, 0x01, 0xc6, 0x00, 0x01, 0x01, + 0xc8, 0x00, 0x01, 0x01, 0xca, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x01, 0x01, 0xce, 0x00, 0x01, 0x01, 0xa8, 0x19, 0x02, 0x02, 0xac, 0x19, 0x02, 0x02, 0xb0, 0x19, 0x02, 0x02, 0xb4, 0x19, 0x02, 0x02, + 0xa0, 0x3b, 0x03, 0x03, 0xa8, 0x3b, 0x03, 0x03, 0xb0, 0x3b, 0x03, 0x03, 0x70, 0x15, 0x04, 0x03, 0x78, 0x15, 0x04, 0x03, 0x80, 0x35, 0x05, 0x04, 0x90, 0x35, 0x05, 0x04, 0x80, 0x11, 0x06, 0x04, + 0x40, 0x0c, 0x08, 0x05, 0x00, 0x27, 0x0b, 0x07, 0xb4, 0x0d, 0x00, 0x02, 0xb8, 0x0d, 0x00, 0x02, 0xbc, 0x0d, 0x00, 0x02, 0xc0, 0x0d, 0x00, 0x02, 0xd0, 0x00, 0x01, 0x01, 0xd2, 0x00, 0x01, 0x01, + 0xd4, 0x00, 0x01, 0x01, 0xd6, 0x00, 0x01, 0x01, 0xd8, 0x00, 0x01, 0x01, 0xda, 0x00, 0x01, 0x01, 0xb8, 0x19, 0x02, 0x02, 0xbc, 0x19, 0x02, 0x02, 0xc0, 0x19, 0x02, 0x02, 0xc4, 0x19, 0x02, 0x02, + 0xb8, 0x3b, 0x03, 0x03, 0xc0, 0x3b, 0x03, 0x03, 0xc8, 0x3b, 0x03, 0x03, 0x80, 0x15, 0x04, 0x03, 0x88, 0x15, 0x04, 0x03, 0xa0, 0x35, 0x05, 0x04, 0xb0, 0x35, 0x05, 0x04, 0x90, 0x11, 0x06, 0x04, + 0x60, 0x0c, 0x08, 0x05, 0x80, 0x27, 0x0b, 0x07, 0xc4, 0x0d, 0x00, 0x02, 0xc8, 0x0d, 0x00, 0x02, 0xcc, 0x0d, 0x00, 0x02, 0xd0, 0x0d, 0x00, 0x02, 0xdc, 0x00, 0x01, 0x01, 0xde, 0x00, 0x01, 0x01, + 0xe0, 0x00, 0x01, 0x01, 0xe2, 0x00, 0x01, 0x01, 0xe4, 0x00, 0x01, 0x01, 0xe6, 0x00, 0x01, 0x01, 0xc8, 0x19, 0x02, 0x02, 0xcc, 0x19, 0x02, 0x02, 0xd0, 0x19, 0x02, 0x02, 0xd4, 0x19, 0x02, 0x02, + 0xd0, 0x3b, 0x03, 0x03, 0xd8, 0x3b, 0x03, 0x03, 0xe0, 0x3b, 0x03, 0x03, 0x90, 0x15, 0x04, 0x03, 0x98, 0x15, 0x04, 0x03, 0xc0, 0x35, 0x05, 0x04, 0xd0, 0x35, 0x05, 0x04, 0xa0, 0x11, 0x06, 0x04, + 0x80, 0x0c, 0x08, 0x05, 0x80, 0x03, 0x0c, 0x07, 0xd4, 0x0d, 0x00, 0x02, 0xd8, 0x0d, 0x00, 0x02, 0xdc, 0x0d, 0x00, 0x02, 0xe0, 0x0d, 0x00, 0x02, 0xe8, 0x00, 0x01, 0x01, 0xea, 0x00, 0x01, 0x01, + 0xec, 0x00, 0x01, 0x01, 0xee, 0x00, 0x01, 0x01, 0xf0, 0x00, 0x01, 0x01, 0xf2, 0x00, 0x01, 0x01, 0xd8, 0x19, 0x02, 0x02, 0xdc, 0x19, 0x02, 0x02, 0xe0, 0x19, 0x02, 0x02, 0xe4, 0x19, 0x02, 0x02, + 0xe8, 0x3b, 0x03, 0x03, 0xf0, 0x3b, 0x03, 0x03, 0xf8, 0x3b, 0x03, 0x03, 0xa0, 0x15, 0x04, 0x03, 0xa8, 0x15, 0x04, 0x03, 0xe0, 0x35, 0x05, 0x04, 0xf0, 0x35, 0x05, 0x04, 0xb0, 0x11, 0x06, 0x04, + 0xa0, 0x0c, 0x08, 0x05, 0x00, 0x04, 0x0c, 0x07, 0xe4, 0x0d, 0x00, 0x02, 0xe8, 0x0d, 0x00, 0x02, 0xec, 0x0d, 0x00, 0x02, 0xf0, 0x0d, 0x00, 0x02, 0xf4, 0x00, 0x01, 0x01, 0xf6, 0x00, 0x01, 0x01, + 0xf8, 0x00, 0x01, 0x01, 0xfa, 0x00, 0x01, 0x01, 0xfc, 0x00, 0x01, 0x01, 0xfe, 0x00, 0x01, 0x01, 0xe8, 0x19, 0x02, 0x02, 0xec, 0x19, 0x02, 0x02, 0xf0, 0x19, 0x02, 0x02, 0xf4, 0x19, 0x02, 0x02, + 0x00, 0x3c, 0x03, 0x03, 0x08, 0x3c, 0x03, 0x03, 0x10, 0x3c, 0x03, 0x03, 0xb0, 0x15, 0x04, 0x03, 0xb8, 0x15, 0x04, 0x03, 0x00, 0x36, 0x05, 0x04, 0x10, 0x36, 0x05, 0x04, 0xc0, 0x11, 0x06, 0x04, + 0xc0, 0x0c, 0x08, 0x05, 0x80, 0x04, 0x0c, 0x07, 0xf4, 0x0d, 0x00, 0x02, 0xf8, 0x0d, 0x00, 0x02, 0xfc, 0x0d, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x04, 0x01, 0x01, 0x01, 0x06, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x0a, 0x01, 0x01, 0x01, 0xf8, 0x19, 0x02, 0x02, 0xfc, 0x19, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x04, 0x1a, 0x02, 0x02, + 0x18, 0x3c, 0x03, 0x03, 0x20, 0x3c, 0x03, 0x03, 0x28, 0x3c, 0x03, 0x03, 0xc0, 0x15, 0x04, 0x03, 0xc8, 0x15, 0x04, 0x03, 0x20, 0x36, 0x05, 0x04, 0x30, 0x36, 0x05, 0x04, 0xd0, 0x11, 0x06, 0x04, + 0xe0, 0x0c, 0x08, 0x05, 0x00, 0x05, 0x0c, 0x07, 0x04, 0x0e, 0x00, 0x02, 0x08, 0x0e, 0x00, 0x02, 0x0c, 0x0e, 0x00, 0x02, 0x10, 0x0e, 0x00, 0x02, 0x0c, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x01, + 0x10, 0x01, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x14, 0x01, 0x01, 0x01, 0x16, 0x01, 0x01, 0x01, 0x08, 0x1a, 0x02, 0x02, 0x0c, 0x1a, 0x02, 0x02, 0x10, 0x1a, 0x02, 0x02, 0x14, 0x1a, 0x02, 0x02, + 0x30, 0x3c, 0x03, 0x03, 0x38, 0x3c, 0x03, 0x03, 0x40, 0x3c, 0x03, 0x03, 0xd0, 0x15, 0x04, 0x03, 0xd8, 0x15, 0x04, 0x03, 0x40, 0x36, 0x05, 0x04, 0x50, 0x36, 0x05, 0x04, 0xe0, 0x11, 0x06, 0x04, + 0x00, 0x0d, 0x08, 0x05, 0x80, 0x05, 0x0c, 0x07, 0x14, 0x0e, 0x00, 0x02, 0x18, 0x0e, 0x00, 0x02, 0x1c, 0x0e, 0x00, 0x02, 0x20, 0x0e, 0x00, 0x02, 0x18, 0x01, 0x01, 0x01, 0x1a, 0x01, 0x01, 0x01, + 0x1c, 0x01, 0x01, 0x01, 0x1e, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x22, 0x01, 0x01, 0x01, 0x18, 0x1a, 0x02, 0x02, 0x1c, 0x1a, 0x02, 0x02, 0x20, 0x1a, 0x02, 0x02, 0x24, 0x1a, 0x02, 0x02, + 0x48, 0x3c, 0x03, 0x03, 0x50, 0x3c, 0x03, 0x03, 0x58, 0x3c, 0x03, 0x03, 0xe0, 0x15, 0x04, 0x03, 0xe8, 0x15, 0x04, 0x03, 0x60, 0x36, 0x05, 0x04, 0x70, 0x36, 0x05, 0x04, 0xf0, 0x11, 0x06, 0x04, + 0x20, 0x0d, 0x08, 0x05, 0x00, 0x06, 0x0c, 0x07, 0x24, 0x0e, 0x00, 0x02, 0x28, 0x0e, 0x00, 0x02, 0x2c, 0x0e, 0x00, 0x02, 0x30, 0x0e, 0x00, 0x02, 0x24, 0x01, 0x01, 0x01, 0x26, 0x01, 0x01, 0x01, + 0x28, 0x01, 0x01, 0x01, 0x2a, 0x01, 0x01, 0x01, 0x2c, 0x01, 0x01, 0x01, 0x2e, 0x01, 0x01, 0x01, 0x28, 0x1a, 0x02, 0x02, 0x2c, 0x1a, 0x02, 0x02, 0x30, 0x1a, 0x02, 0x02, 0x34, 0x1a, 0x02, 0x02, + 0x60, 0x3c, 0x03, 0x03, 0x68, 0x3c, 0x03, 0x03, 0x70, 0x3c, 0x03, 0x03, 0xf0, 0x15, 0x04, 0x03, 0xf8, 0x15, 0x04, 0x03, 0x80, 0x36, 0x05, 0x04, 0x90, 0x36, 0x05, 0x04, 0x00, 0x12, 0x06, 0x04, + 0x40, 0x0d, 0x08, 0x05, 0x80, 0x06, 0x0c, 0x07, 0x34, 0x0e, 0x00, 0x02, 0x38, 0x0e, 0x00, 0x02, 0x3c, 0x0e, 0x00, 0x02, 0x40, 0x0e, 0x00, 0x02, 0x30, 0x01, 0x01, 0x01, 0x32, 0x01, 0x01, 0x01, + 0x34, 0x01, 0x01, 0x01, 0x36, 0x01, 0x01, 0x01, 0x38, 0x01, 0x01, 0x01, 0x3a, 0x01, 0x01, 0x01, 0x38, 0x1a, 0x02, 0x02, 0x3c, 0x1a, 0x02, 0x02, 0x40, 0x1a, 0x02, 0x02, 0x44, 0x1a, 0x02, 0x02, + 0x78, 0x3c, 0x03, 0x03, 0x80, 0x3c, 0x03, 0x03, 0x88, 0x3c, 0x03, 0x03, 0x00, 0x16, 0x04, 0x03, 0x08, 0x16, 0x04, 0x03, 0xa0, 0x36, 0x05, 0x04, 0xb0, 0x36, 0x05, 0x04, 0x10, 0x12, 0x06, 0x04, + 0x60, 0x0d, 0x08, 0x05, 0x00, 0x07, 0x0c, 0x07, 0x44, 0x0e, 0x00, 0x02, 0x48, 0x0e, 0x00, 0x02, 0x4c, 0x0e, 0x00, 0x02, 0x3c, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, + 0x42, 0x01, 0x01, 0x01, 0x44, 0x01, 0x01, 0x01, 0x46, 0x01, 0x01, 0x01, 0x48, 0x01, 0x01, 0x01, 0x48, 0x1a, 0x02, 0x02, 0x4c, 0x1a, 0x02, 0x02, 0x50, 0x1a, 0x02, 0x02, 0x54, 0x1a, 0x02, 0x02, + 0x90, 0x3c, 0x03, 0x03, 0x98, 0x3c, 0x03, 0x03, 0xa0, 0x3c, 0x03, 0x03, 0x10, 0x16, 0x04, 0x03, 0x18, 0x16, 0x04, 0x03, 0xc0, 0x36, 0x05, 0x04, 0xd0, 0x36, 0x05, 0x04, 0x20, 0x12, 0x06, 0x04, + 0x80, 0x0d, 0x08, 0x05, 0x80, 0x07, 0x0c, 0x07, 0x50, 0x0e, 0x00, 0x02, 0x54, 0x0e, 0x00, 0x02, 0x58, 0x0e, 0x00, 0x02, 0x4a, 0x01, 0x01, 0x01, 0x4c, 0x01, 0x01, 0x01, 0x4e, 0x01, 0x01, 0x01, + 0x50, 0x01, 0x01, 0x01, 0x52, 0x01, 0x01, 0x01, 0x54, 0x01, 0x01, 0x01, 0x56, 0x01, 0x01, 0x01, 0x58, 0x1a, 0x02, 0x02, 0x5c, 0x1a, 0x02, 0x02, 0x60, 0x1a, 0x02, 0x02, 0x64, 0x1a, 0x02, 0x02, + 0xa8, 0x3c, 0x03, 0x03, 0xb0, 0x3c, 0x03, 0x03, 0xb8, 0x3c, 0x03, 0x03, 0x20, 0x16, 0x04, 0x03, 0x28, 0x16, 0x04, 0x03, 0xe0, 0x36, 0x05, 0x04, 0xf0, 0x36, 0x05, 0x04, 0x30, 0x12, 0x06, 0x04, + 0xa0, 0x0d, 0x08, 0x05, 0x00, 0x1e, 0x0d, 0x08, 0x5c, 0x0e, 0x00, 0x02, 0x60, 0x0e, 0x00, 0x02, 0x64, 0x0e, 0x00, 0x02, 0x58, 0x01, 0x01, 0x01, 0x5a, 0x01, 0x01, 0x01, 0x5c, 0x01, 0x01, 0x01, + 0x5e, 0x01, 0x01, 0x01, 0x60, 0x01, 0x01, 0x01, 0x62, 0x01, 0x01, 0x01, 0x64, 0x01, 0x01, 0x01, 0x68, 0x1a, 0x02, 0x02, 0x6c, 0x1a, 0x02, 0x02, 0x70, 0x1a, 0x02, 0x02, 0x74, 0x1a, 0x02, 0x02, + 0xc0, 0x3c, 0x03, 0x03, 0xc8, 0x3c, 0x03, 0x03, 0xd0, 0x3c, 0x03, 0x03, 0x30, 0x16, 0x04, 0x03, 0x38, 0x16, 0x04, 0x03, 0x00, 0x37, 0x05, 0x04, 0x10, 0x37, 0x05, 0x04, 0x40, 0x12, 0x06, 0x04, + 0xc0, 0x0d, 0x08, 0x05, 0x00, 0x1f, 0x0d, 0x08, 0x68, 0x0e, 0x00, 0x02, 0x6c, 0x0e, 0x00, 0x02, 0x70, 0x0e, 0x00, 0x02, 0x66, 0x01, 0x01, 0x01, 0x68, 0x01, 0x01, 0x01, 0x6a, 0x01, 0x01, 0x01, + 0x6c, 0x01, 0x01, 0x01, 0x6e, 0x01, 0x01, 0x01, 0x70, 0x01, 0x01, 0x01, 0x72, 0x01, 0x01, 0x01, 0x78, 0x1a, 0x02, 0x02, 0x7c, 0x1a, 0x02, 0x02, 0x80, 0x1a, 0x02, 0x02, 0x84, 0x1a, 0x02, 0x02, + 0xd8, 0x3c, 0x03, 0x03, 0xe0, 0x3c, 0x03, 0x03, 0xe8, 0x3c, 0x03, 0x03, 0x40, 0x16, 0x04, 0x03, 0x48, 0x16, 0x04, 0x03, 0x20, 0x37, 0x05, 0x04, 0x30, 0x37, 0x05, 0x04, 0x50, 0x12, 0x06, 0x04, + 0xe0, 0x0d, 0x08, 0x05, 0x00, 0x20, 0x0d, 0x08, 0x74, 0x0e, 0x00, 0x02, 0x78, 0x0e, 0x00, 0x02, 0x7c, 0x0e, 0x00, 0x02, 0x74, 0x01, 0x01, 0x01, 0x76, 0x01, 0x01, 0x01, 0x78, 0x01, 0x01, 0x01, + 0x7a, 0x01, 0x01, 0x01, 0x7c, 0x01, 0x01, 0x01, 0x7e, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x88, 0x1a, 0x02, 0x02, 0x8c, 0x1a, 0x02, 0x02, 0x90, 0x1a, 0x02, 0x02, 0x94, 0x1a, 0x02, 0x02, + 0xf0, 0x3c, 0x03, 0x03, 0xf8, 0x3c, 0x03, 0x03, 0x00, 0x3d, 0x03, 0x03, 0x50, 0x16, 0x04, 0x03, 0x58, 0x16, 0x04, 0x03, 0x40, 0x37, 0x05, 0x04, 0x50, 0x37, 0x05, 0x04, 0x40, 0x31, 0x07, 0x05, + 0x00, 0x0e, 0x08, 0x05, 0x00, 0x21, 0x0d, 0x08, 0x80, 0x0e, 0x00, 0x02, 0x84, 0x0e, 0x00, 0x02, 0x88, 0x0e, 0x00, 0x02, 0x82, 0x01, 0x01, 0x01, 0x84, 0x01, 0x01, 0x01, 0x86, 0x01, 0x01, 0x01, + 0x88, 0x01, 0x01, 0x01, 0x8a, 0x01, 0x01, 0x01, 0x8c, 0x01, 0x01, 0x01, 0x8e, 0x01, 0x01, 0x01, 0x98, 0x1a, 0x02, 0x02, 0x9c, 0x1a, 0x02, 0x02, 0xa0, 0x1a, 0x02, 0x02, 0xa4, 0x1a, 0x02, 0x02, + 0x08, 0x3d, 0x03, 0x03, 0x10, 0x3d, 0x03, 0x03, 0x18, 0x3d, 0x03, 0x03, 0x60, 0x16, 0x04, 0x03, 0x68, 0x16, 0x04, 0x03, 0x60, 0x37, 0x05, 0x04, 0x70, 0x37, 0x05, 0x04, 0x60, 0x31, 0x07, 0x05, + 0x20, 0x0e, 0x08, 0x05, 0x00, 0x22, 0x0d, 0x08, 0x8c, 0x0e, 0x00, 0x02, 0x90, 0x0e, 0x00, 0x02, 0x94, 0x0e, 0x00, 0x02, 0x90, 0x01, 0x01, 0x01, 0x92, 0x01, 0x01, 0x01, 0x94, 0x01, 0x01, 0x01, + 0x96, 0x01, 0x01, 0x01, 0x98, 0x01, 0x01, 0x01, 0x9a, 0x01, 0x01, 0x01, 0x9c, 0x01, 0x01, 0x01, 0xa8, 0x1a, 0x02, 0x02, 0xac, 0x1a, 0x02, 0x02, 0xb0, 0x1a, 0x02, 0x02, 0xb4, 0x1a, 0x02, 0x02, + 0x20, 0x3d, 0x03, 0x03, 0x28, 0x3d, 0x03, 0x03, 0x30, 0x3d, 0x03, 0x03, 0x70, 0x16, 0x04, 0x03, 0x78, 0x16, 0x04, 0x03, 0x80, 0x37, 0x05, 0x04, 0x60, 0x12, 0x06, 0x04, 0x80, 0x31, 0x07, 0x05, + 0x40, 0x0e, 0x08, 0x05, 0x00, 0x23, 0x0d, 0x08, 0x98, 0x0e, 0x00, 0x02, 0x9c, 0x0e, 0x00, 0x02, 0xa0, 0x0e, 0x00, 0x02, 0x9e, 0x01, 0x01, 0x01, 0xa0, 0x01, 0x01, 0x01, 0xa2, 0x01, 0x01, 0x01, + 0xa4, 0x01, 0x01, 0x01, 0xa6, 0x01, 0x01, 0x01, 0xa8, 0x01, 0x01, 0x01, 0xaa, 0x01, 0x01, 0x01, 0xb8, 0x1a, 0x02, 0x02, 0xbc, 0x1a, 0x02, 0x02, 0xc0, 0x1a, 0x02, 0x02, 0xc4, 0x1a, 0x02, 0x02, + 0x38, 0x3d, 0x03, 0x03, 0x40, 0x3d, 0x03, 0x03, 0x48, 0x3d, 0x03, 0x03, 0x80, 0x16, 0x04, 0x03, 0x88, 0x16, 0x04, 0x03, 0x90, 0x37, 0x05, 0x04, 0x70, 0x12, 0x06, 0x04, 0xa0, 0x31, 0x07, 0x05, + 0x60, 0x0e, 0x08, 0x05, 0x00, 0x00, 0x0e, 0x08, 0xa4, 0x0e, 0x00, 0x02, 0xa8, 0x0e, 0x00, 0x02, 0xac, 0x0e, 0x00, 0x02, 0xac, 0x01, 0x01, 0x01, 0xae, 0x01, 0x01, 0x01, 0xb0, 0x01, 0x01, 0x01, + 0xb2, 0x01, 0x01, 0x01, 0xb4, 0x01, 0x01, 0x01, 0xb6, 0x01, 0x01, 0x01, 0xb8, 0x01, 0x01, 0x01, 0xc8, 0x1a, 0x02, 0x02, 0xcc, 0x1a, 0x02, 0x02, 0xd0, 0x1a, 0x02, 0x02, 0xd4, 0x1a, 0x02, 0x02, + 0x50, 0x3d, 0x03, 0x03, 0x58, 0x3d, 0x03, 0x03, 0x60, 0x3d, 0x03, 0x03, 0x90, 0x16, 0x04, 0x03, 0x98, 0x16, 0x04, 0x03, 0xa0, 0x37, 0x05, 0x04, 0x80, 0x12, 0x06, 0x04, 0xc0, 0x31, 0x07, 0x05, + 0x80, 0x0e, 0x08, 0x05, 0x00, 0x01, 0x0e, 0x08, 0xb0, 0x0e, 0x00, 0x02, 0xb4, 0x0e, 0x00, 0x02, 0xb8, 0x0e, 0x00, 0x02, 0xba, 0x01, 0x01, 0x01, 0xbc, 0x01, 0x01, 0x01, 0xbe, 0x01, 0x01, 0x01, + 0xc0, 0x01, 0x01, 0x01, 0xc2, 0x01, 0x01, 0x01, 0xc4, 0x01, 0x01, 0x01, 0xc6, 0x01, 0x01, 0x01, 0xd8, 0x1a, 0x02, 0x02, 0xdc, 0x1a, 0x02, 0x02, 0xe0, 0x1a, 0x02, 0x02, 0xe4, 0x1a, 0x02, 0x02, + 0x68, 0x3d, 0x03, 0x03, 0x70, 0x3d, 0x03, 0x03, 0x78, 0x3d, 0x03, 0x03, 0xa0, 0x16, 0x04, 0x03, 0xa8, 0x16, 0x04, 0x03, 0xb0, 0x37, 0x05, 0x04, 0x90, 0x12, 0x06, 0x04, 0xe0, 0x31, 0x07, 0x05, + 0xa0, 0x0e, 0x08, 0x05, 0x00, 0x02, 0x0e, 0x08, 0xbc, 0x0e, 0x00, 0x02, 0xc0, 0x0e, 0x00, 0x02, 0xc4, 0x0e, 0x00, 0x02, 0xc8, 0x01, 0x01, 0x01, 0xca, 0x01, 0x01, 0x01, 0xcc, 0x01, 0x01, 0x01, + 0xce, 0x01, 0x01, 0x01, 0xd0, 0x01, 0x01, 0x01, 0xd2, 0x01, 0x01, 0x01, 0xd4, 0x01, 0x01, 0x01, 0xe8, 0x1a, 0x02, 0x02, 0xec, 0x1a, 0x02, 0x02, 0xf0, 0x1a, 0x02, 0x02, 0xf4, 0x1a, 0x02, 0x02, + 0x80, 0x3d, 0x03, 0x03, 0x88, 0x3d, 0x03, 0x03, 0x90, 0x3d, 0x03, 0x03, 0xb0, 0x16, 0x04, 0x03, 0xb8, 0x16, 0x04, 0x03, 0xc0, 0x37, 0x05, 0x04, 0xa0, 0x12, 0x06, 0x04, 0x00, 0x32, 0x07, 0x05, + 0xc0, 0x0e, 0x08, 0x05, 0x00, 0x03, 0x0e, 0x08, 0xc8, 0x0e, 0x00, 0x02, 0xcc, 0x0e, 0x00, 0x02, 0xd0, 0x0e, 0x00, 0x02, 0xd6, 0x01, 0x01, 0x01, 0xd8, 0x01, 0x01, 0x01, 0xda, 0x01, 0x01, 0x01, + 0xdc, 0x01, 0x01, 0x01, 0xde, 0x01, 0x01, 0x01, 0xe0, 0x01, 0x01, 0x01, 0xe2, 0x01, 0x01, 0x01, 0xf8, 0x1a, 0x02, 0x02, 0xfc, 0x1a, 0x02, 0x02, 0x00, 0x1b, 0x02, 0x02, 0x04, 0x1b, 0x02, 0x02, + 0x98, 0x3d, 0x03, 0x03, 0xa0, 0x3d, 0x03, 0x03, 0xa8, 0x3d, 0x03, 0x03, 0xc0, 0x16, 0x04, 0x03, 0xc8, 0x16, 0x04, 0x03, 0xd0, 0x37, 0x05, 0x04, 0xb0, 0x12, 0x06, 0x04, 0x20, 0x32, 0x07, 0x05, + 0xe0, 0x0e, 0x08, 0x05, 0x00, 0x1e, 0x0f, 0x09, 0xd4, 0x0e, 0x00, 0x02, 0xd8, 0x0e, 0x00, 0x02, 0xdc, 0x0e, 0x00, 0x02, 0xe4, 0x01, 0x01, 0x01, 0xe6, 0x01, 0x01, 0x01, 0xe8, 0x01, 0x01, 0x01, + 0xea, 0x01, 0x01, 0x01, 0x00, 0x00, 0xfe, 0x0e, 0x00, 0x00, 0xfd, 0x0e, 0x00, 0x00, 0xfc, 0x0e, 0x00, 0x00, 0xfb, 0x0e, 0x00, 0x00, 0xfa, 0x0e, 0x00, 0x00, 0xf9, 0x0e, 0x00, 0x00, 0xf8, 0x0e, + 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0xf6, 0x0e, 0x00, 0x00, 0xf5, 0x0e, 0x00, 0x00, 0xf4, 0x0e, 0x00, 0x00, 0xf3, 0x0e, 0x00, 0x00, 0xf2, 0x0e, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0x00, 0xf0, 0x0e, + 0x00, 0x00, 0xef, 0x0e, 0x00, 0x00, 0xee, 0x0e, 0x00, 0x00, 0xed, 0x0e, 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xeb, 0x0e, 0x00, 0x00, 0xea, 0x0e, 0x00, 0x00, 0xe9, 0x0e, 0x00, 0x00, 0xe8, 0x0e, + 0x00, 0x00, 0xe7, 0x0e, 0x00, 0x00, 0xe6, 0x0e, 0x00, 0x00, 0xe5, 0x0e, 0x00, 0x00, 0xe4, 0x0e, 0x00, 0x00, 0xe3, 0x0e, 0x00, 0x00, 0xe2, 0x0e, 0x00, 0x00, 0xe1, 0x0e, 0x00, 0x00, 0xe0, 0x0e, + 0x00, 0x00, 0xdf, 0x0e, 0x00, 0x00, 0xde, 0x0e, 0x00, 0x00, 0xdd, 0x0e, 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0xdb, 0x0e, 0x00, 0x00, 0xda, 0x0e, 0x00, 0x00, 0xd9, 0x0e, 0x00, 0x00, 0xd8, 0x0e, + 0x00, 0x00, 0xd7, 0x0e, 0x00, 0x00, 0xd6, 0x0e, 0x00, 0x00, 0xd5, 0x0e, 0x00, 0x00, 0xd4, 0x0e, 0x00, 0x00, 0xd3, 0x0e, 0x00, 0x00, 0xd2, 0x0e, 0x00, 0x00, 0xd1, 0x0e, 0x00, 0x00, 0xd0, 0x0e, + 0x00, 0x00, 0xcf, 0x0e, 0x00, 0x00, 0xce, 0x0e, 0x00, 0x00, 0xcd, 0x0e, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x00, 0xcb, 0x0e, 0x00, 0x00, 0xca, 0x0e, 0x00, 0x00, 0xc9, 0x0e, 0x00, 0x00, 0xc8, 0x0e, + 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0xc5, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc3, 0x0e, 0x00, 0x00, 0xc2, 0x0e, 0x00, 0x00, 0xc1, 0x0e, 0x00, 0x00, 0xc0, 0x0e, + 0x00, 0x00, 0xbf, 0x0e, 0x00, 0x00, 0xbe, 0x0e, 0x00, 0x00, 0xbd, 0x0e, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x00, 0xbb, 0x0e, 0x00, 0x00, 0xba, 0x0e, 0x00, 0x00, 0xb9, 0x0e, 0x00, 0x00, 0xb8, 0x0e, + 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x00, 0xb6, 0x0e, 0x00, 0x00, 0xb5, 0x0e, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x00, 0xb3, 0x0e, 0x00, 0x00, 0xb2, 0x0e, 0x00, 0x00, 0xb1, 0x0e, 0x00, 0x00, 0xb0, 0x0e, + 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0xae, 0x0e, 0x00, 0x00, 0xad, 0x0e, 0x00, 0x00, 0xac, 0x0e, 0x00, 0x00, 0xab, 0x0e, 0x00, 0x00, 0xaa, 0x0e, 0x00, 0x00, 0xa9, 0x0e, 0x00, 0x00, 0xa8, 0x0e, + 0x00, 0x00, 0xa7, 0x0e, 0x00, 0x00, 0xa6, 0x0e, 0x00, 0x00, 0xa5, 0x0e, 0x00, 0x00, 0xa4, 0x0e, 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0xa2, 0x0e, 0x00, 0x00, 0xa1, 0x0e, 0x00, 0x00, 0xa0, 0x0e, + 0x00, 0x00, 0x9f, 0x0e, 0x00, 0x00, 0x9e, 0x0e, 0x00, 0x00, 0x9d, 0x0e, 0x00, 0x00, 0x9c, 0x0e, 0x00, 0x00, 0x9b, 0x0e, 0x00, 0x00, 0x9a, 0x0e, 0x00, 0x00, 0x99, 0x0e, 0x00, 0x00, 0x98, 0x0e, + 0x00, 0x00, 0x97, 0x0e, 0x00, 0x00, 0x96, 0x0e, 0x00, 0x00, 0x95, 0x0e, 0x00, 0x00, 0x94, 0x0e, 0x00, 0x00, 0x93, 0x0e, 0x00, 0x00, 0x92, 0x0e, 0x00, 0x00, 0x91, 0x0e, 0x00, 0x00, 0x90, 0x0e, + 0x00, 0x00, 0x8f, 0x0e, 0x00, 0x00, 0x8e, 0x0e, 0x00, 0x00, 0x8d, 0x0e, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x00, 0x8b, 0x0e, 0x00, 0x00, 0x8a, 0x0e, 0x00, 0x00, 0x89, 0x0e, 0x00, 0x00, 0x88, 0x0e, + 0x00, 0x00, 0x87, 0x0e, 0x00, 0x00, 0x86, 0x0e, 0x00, 0x00, 0x85, 0x0e, 0x00, 0x00, 0x84, 0x0e, 0x00, 0x00, 0x83, 0x0e, 0x00, 0x00, 0x82, 0x0e, 0x00, 0x00, 0x81, 0x0e, 0x00, 0x00, 0x80, 0x0e, + 0x00, 0x00, 0x7f, 0x0e, 0x00, 0x00, 0x7e, 0x0e, 0x00, 0x00, 0x7d, 0x0e, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x00, 0x7b, 0x0e, 0x00, 0x00, 0x7a, 0x0e, 0x00, 0x00, 0x79, 0x0e, 0x00, 0x00, 0x78, 0x0e, + 0x00, 0x00, 0x77, 0x0e, 0x00, 0x00, 0x76, 0x0e, 0x00, 0x00, 0x75, 0x0e, 0x00, 0x00, 0x74, 0x0e, 0x00, 0x00, 0x73, 0x0e, 0x00, 0x00, 0x72, 0x0e, 0x00, 0x00, 0x71, 0x0e, 0x00, 0x00, 0x70, 0x0e, + 0x00, 0x00, 0x6f, 0x0e, 0x00, 0x00, 0x6e, 0x0e, 0x00, 0x00, 0x6d, 0x0e, 0x00, 0x00, 0x6c, 0x0e, 0x00, 0x00, 0x6b, 0x0e, 0x00, 0x00, 0x6a, 0x0e, 0x00, 0x00, 0x69, 0x0e, 0x00, 0x00, 0x68, 0x0e, + 0x00, 0x00, 0x67, 0x0e, 0x00, 0x00, 0x66, 0x0e, 0x00, 0x00, 0x65, 0x0e, 0x00, 0x00, 0x64, 0x0e, 0x00, 0x00, 0x63, 0x0e, 0x00, 0x00, 0x62, 0x0e, 0x00, 0x00, 0x61, 0x0e, 0x00, 0x00, 0x60, 0x0e, + 0x00, 0x00, 0x5f, 0x0e, 0x00, 0x00, 0x5e, 0x0e, 0x00, 0x00, 0x5d, 0x0e, 0x00, 0x00, 0x5c, 0x0e, 0x00, 0x00, 0x5b, 0x0e, 0x00, 0x00, 0x5a, 0x0e, 0x00, 0x00, 0x59, 0x0e, 0x00, 0x00, 0x58, 0x0e, + 0x00, 0x00, 0x57, 0x0e, 0x00, 0x00, 0x56, 0x0e, 0x00, 0x00, 0x55, 0x0e, 0x00, 0x00, 0x54, 0x0e, 0x00, 0x00, 0x53, 0x0e, 0x00, 0x00, 0x52, 0x0e, 0x00, 0x00, 0x51, 0x0e, 0x00, 0x00, 0x50, 0x0e, + 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x4e, 0x0e, 0x00, 0x00, 0x4d, 0x0e, 0x00, 0x00, 0x4c, 0x0e, 0x00, 0x00, 0x4b, 0x0e, 0x00, 0x00, 0x4a, 0x0e, 0x00, 0x00, 0x49, 0x0e, 0x00, 0x00, 0x48, 0x0e, + 0x00, 0x00, 0x47, 0x0e, 0x00, 0x00, 0x46, 0x0e, 0x00, 0x00, 0x45, 0x0e, 0x00, 0x00, 0x44, 0x0e, 0x00, 0x00, 0x43, 0x0e, 0x00, 0x00, 0x42, 0x0e, 0x00, 0x00, 0x41, 0x0e, 0x00, 0x00, 0x40, 0x0e, + 0x00, 0x00, 0x3f, 0x0e, 0x00, 0x00, 0x3e, 0x0e, 0x00, 0x00, 0x3d, 0x0e, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x3a, 0x0e, 0x00, 0x00, 0x39, 0x0e, 0x00, 0x00, 0x38, 0x0e, + 0x00, 0x00, 0x37, 0x0e, 0x00, 0x00, 0x36, 0x0e, 0x00, 0x00, 0x35, 0x0e, 0x00, 0x00, 0x34, 0x0e, 0x00, 0x00, 0x33, 0x0e, 0x00, 0x00, 0x32, 0x0e, 0x00, 0x00, 0x31, 0x0e, 0x00, 0x00, 0x30, 0x0e, + 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x2e, 0x0e, 0x00, 0x00, 0x2d, 0x0e, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00, 0x2b, 0x0e, 0x00, 0x00, 0x2a, 0x0e, 0x00, 0x00, 0x29, 0x0e, 0x00, 0x00, 0x28, 0x0e, + 0x00, 0x00, 0x27, 0x0e, 0x00, 0x00, 0x26, 0x0e, 0x00, 0x00, 0x25, 0x0e, 0x00, 0x00, 0x24, 0x0e, 0x00, 0x00, 0x23, 0x0e, 0x00, 0x00, 0x22, 0x0e, 0x00, 0x00, 0x21, 0x0e, 0x00, 0x00, 0x20, 0x0e, + 0x00, 0x00, 0x1f, 0x0e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x1d, 0x0e, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0x1b, 0x0e, 0x00, 0x00, 0x1a, 0x0e, 0x00, 0x00, 0x19, 0x0e, 0x00, 0x00, 0x18, 0x0e, + 0x00, 0x00, 0x17, 0x0e +}; + +const byte DTable_4[65540] = { + 0x0e, 0x00, 0x01, 0x00, 0xa8, 0x11, 0x00, 0x03, 0xb0, 0x11, 0x00, 0x03, 0xb8, 0x11, 0x00, 0x03, 0xc0, 0x11, 0x00, 0x03, 0x90, 0x03, 0x01, 0x02, 0x94, 0x03, 0x01, 0x02, 0x98, 0x03, 0x01, 0x02, + 0x9c, 0x03, 0x01, 0x02, 0xa0, 0x03, 0x01, 0x02, 0xa4, 0x03, 0x01, 0x02, 0xa8, 0x03, 0x01, 0x02, 0xf8, 0x1b, 0x02, 0x03, 0x00, 0x1c, 0x02, 0x03, 0x08, 0x1c, 0x02, 0x03, 0x10, 0x1c, 0x02, 0x03, + 0x40, 0x3d, 0x03, 0x04, 0x50, 0x3d, 0x03, 0x04, 0x60, 0x3d, 0x03, 0x04, 0x40, 0x15, 0x04, 0x04, 0x50, 0x15, 0x04, 0x04, 0x00, 0x34, 0x05, 0x05, 0x20, 0x34, 0x05, 0x05, 0x80, 0x2b, 0x07, 0x06, + 0x40, 0x09, 0x08, 0x06, 0xc8, 0x11, 0x00, 0x03, 0xd0, 0x11, 0x00, 0x03, 0xd8, 0x11, 0x00, 0x03, 0xe0, 0x11, 0x00, 0x03, 0xac, 0x03, 0x01, 0x02, 0xb0, 0x03, 0x01, 0x02, 0xb4, 0x03, 0x01, 0x02, + 0xb8, 0x03, 0x01, 0x02, 0xbc, 0x03, 0x01, 0x02, 0xc0, 0x03, 0x01, 0x02, 0xc4, 0x03, 0x01, 0x02, 0x18, 0x1c, 0x02, 0x03, 0x20, 0x1c, 0x02, 0x03, 0x28, 0x1c, 0x02, 0x03, 0x30, 0x1c, 0x02, 0x03, + 0x70, 0x3d, 0x03, 0x04, 0x80, 0x3d, 0x03, 0x04, 0x90, 0x3d, 0x03, 0x04, 0x60, 0x15, 0x04, 0x04, 0x70, 0x15, 0x04, 0x04, 0x40, 0x34, 0x05, 0x05, 0x60, 0x34, 0x05, 0x05, 0xc0, 0x2b, 0x07, 0x06, + 0x80, 0x09, 0x08, 0x06, 0xe8, 0x11, 0x00, 0x03, 0xf0, 0x11, 0x00, 0x03, 0xf8, 0x11, 0x00, 0x03, 0x00, 0x12, 0x00, 0x03, 0xc8, 0x03, 0x01, 0x02, 0xcc, 0x03, 0x01, 0x02, 0xd0, 0x03, 0x01, 0x02, + 0xd4, 0x03, 0x01, 0x02, 0xd8, 0x03, 0x01, 0x02, 0xdc, 0x03, 0x01, 0x02, 0xe0, 0x03, 0x01, 0x02, 0x38, 0x1c, 0x02, 0x03, 0x40, 0x1c, 0x02, 0x03, 0x48, 0x1c, 0x02, 0x03, 0x50, 0x1c, 0x02, 0x03, + 0xa0, 0x3d, 0x03, 0x04, 0xb0, 0x3d, 0x03, 0x04, 0xc0, 0x3d, 0x03, 0x04, 0x80, 0x15, 0x04, 0x04, 0x90, 0x15, 0x04, 0x04, 0x80, 0x34, 0x05, 0x05, 0xa0, 0x34, 0x05, 0x05, 0x00, 0x2c, 0x07, 0x06, + 0xc0, 0x09, 0x08, 0x06, 0x08, 0x12, 0x00, 0x03, 0x10, 0x12, 0x00, 0x03, 0x18, 0x12, 0x00, 0x03, 0x20, 0x12, 0x00, 0x03, 0xe4, 0x03, 0x01, 0x02, 0xe8, 0x03, 0x01, 0x02, 0xec, 0x03, 0x01, 0x02, + 0xf0, 0x03, 0x01, 0x02, 0xf4, 0x03, 0x01, 0x02, 0xf8, 0x03, 0x01, 0x02, 0xfc, 0x03, 0x01, 0x02, 0x58, 0x1c, 0x02, 0x03, 0x60, 0x1c, 0x02, 0x03, 0x68, 0x1c, 0x02, 0x03, 0x70, 0x1c, 0x02, 0x03, + 0xd0, 0x3d, 0x03, 0x04, 0xe0, 0x3d, 0x03, 0x04, 0xf0, 0x3d, 0x03, 0x04, 0xa0, 0x15, 0x04, 0x04, 0xb0, 0x15, 0x04, 0x04, 0xc0, 0x34, 0x05, 0x05, 0xe0, 0x34, 0x05, 0x05, 0x40, 0x2c, 0x07, 0x06, + 0x00, 0x0a, 0x08, 0x06, 0x28, 0x12, 0x00, 0x03, 0x30, 0x12, 0x00, 0x03, 0x38, 0x12, 0x00, 0x03, 0x40, 0x12, 0x00, 0x03, 0x00, 0x04, 0x01, 0x02, 0x04, 0x04, 0x01, 0x02, 0x08, 0x04, 0x01, 0x02, + 0x0c, 0x04, 0x01, 0x02, 0x10, 0x04, 0x01, 0x02, 0x14, 0x04, 0x01, 0x02, 0x18, 0x04, 0x01, 0x02, 0x78, 0x1c, 0x02, 0x03, 0x80, 0x1c, 0x02, 0x03, 0x88, 0x1c, 0x02, 0x03, 0x90, 0x1c, 0x02, 0x03, + 0x00, 0x3e, 0x03, 0x04, 0x10, 0x3e, 0x03, 0x04, 0x20, 0x3e, 0x03, 0x04, 0xc0, 0x15, 0x04, 0x04, 0xd0, 0x15, 0x04, 0x04, 0x00, 0x35, 0x05, 0x05, 0x20, 0x35, 0x05, 0x05, 0x80, 0x2c, 0x07, 0x06, + 0x40, 0x0a, 0x08, 0x06, 0x48, 0x12, 0x00, 0x03, 0x50, 0x12, 0x00, 0x03, 0x58, 0x12, 0x00, 0x03, 0x60, 0x12, 0x00, 0x03, 0x1c, 0x04, 0x01, 0x02, 0x20, 0x04, 0x01, 0x02, 0x24, 0x04, 0x01, 0x02, + 0x28, 0x04, 0x01, 0x02, 0x2c, 0x04, 0x01, 0x02, 0x30, 0x04, 0x01, 0x02, 0x34, 0x04, 0x01, 0x02, 0x98, 0x1c, 0x02, 0x03, 0xa0, 0x1c, 0x02, 0x03, 0xa8, 0x1c, 0x02, 0x03, 0xb0, 0x1c, 0x02, 0x03, + 0x30, 0x3e, 0x03, 0x04, 0x40, 0x3e, 0x03, 0x04, 0x50, 0x3e, 0x03, 0x04, 0xe0, 0x15, 0x04, 0x04, 0xf0, 0x15, 0x04, 0x04, 0x40, 0x35, 0x05, 0x05, 0x00, 0x0f, 0x06, 0x05, 0xc0, 0x2c, 0x07, 0x06, + 0x80, 0x0a, 0x08, 0x06, 0x68, 0x12, 0x00, 0x03, 0x70, 0x12, 0x00, 0x03, 0x78, 0x12, 0x00, 0x03, 0x80, 0x12, 0x00, 0x03, 0x38, 0x04, 0x01, 0x02, 0x3c, 0x04, 0x01, 0x02, 0x40, 0x04, 0x01, 0x02, + 0x44, 0x04, 0x01, 0x02, 0x48, 0x04, 0x01, 0x02, 0x4c, 0x04, 0x01, 0x02, 0x50, 0x04, 0x01, 0x02, 0xb8, 0x1c, 0x02, 0x03, 0xc0, 0x1c, 0x02, 0x03, 0xc8, 0x1c, 0x02, 0x03, 0xd0, 0x1c, 0x02, 0x03, + 0x60, 0x3e, 0x03, 0x04, 0x70, 0x3e, 0x03, 0x04, 0x80, 0x3e, 0x03, 0x04, 0x00, 0x16, 0x04, 0x04, 0x10, 0x16, 0x04, 0x04, 0x60, 0x35, 0x05, 0x05, 0x20, 0x0f, 0x06, 0x05, 0x00, 0x2d, 0x07, 0x06, + 0x80, 0x23, 0x09, 0x07, 0x88, 0x12, 0x00, 0x03, 0x90, 0x12, 0x00, 0x03, 0x98, 0x12, 0x00, 0x03, 0xa0, 0x12, 0x00, 0x03, 0x54, 0x04, 0x01, 0x02, 0x58, 0x04, 0x01, 0x02, 0x5c, 0x04, 0x01, 0x02, + 0x60, 0x04, 0x01, 0x02, 0x64, 0x04, 0x01, 0x02, 0x68, 0x04, 0x01, 0x02, 0x6c, 0x04, 0x01, 0x02, 0xd8, 0x1c, 0x02, 0x03, 0xe0, 0x1c, 0x02, 0x03, 0xe8, 0x1c, 0x02, 0x03, 0xf0, 0x1c, 0x02, 0x03, + 0x90, 0x3e, 0x03, 0x04, 0xa0, 0x3e, 0x03, 0x04, 0xb0, 0x3e, 0x03, 0x04, 0x20, 0x16, 0x04, 0x04, 0x30, 0x16, 0x04, 0x04, 0x80, 0x35, 0x05, 0x05, 0x40, 0x0f, 0x06, 0x05, 0x40, 0x2d, 0x07, 0x06, + 0x00, 0x24, 0x09, 0x07, 0xa8, 0x12, 0x00, 0x03, 0xb0, 0x12, 0x00, 0x03, 0xb8, 0x12, 0x00, 0x03, 0xc0, 0x12, 0x00, 0x03, 0x70, 0x04, 0x01, 0x02, 0x74, 0x04, 0x01, 0x02, 0x78, 0x04, 0x01, 0x02, + 0x7c, 0x04, 0x01, 0x02, 0x80, 0x04, 0x01, 0x02, 0x84, 0x04, 0x01, 0x02, 0x88, 0x04, 0x01, 0x02, 0xf8, 0x1c, 0x02, 0x03, 0x00, 0x1d, 0x02, 0x03, 0x08, 0x1d, 0x02, 0x03, 0x10, 0x1d, 0x02, 0x03, + 0xc0, 0x3e, 0x03, 0x04, 0xd0, 0x3e, 0x03, 0x04, 0xe0, 0x3e, 0x03, 0x04, 0x40, 0x16, 0x04, 0x04, 0x50, 0x16, 0x04, 0x04, 0xa0, 0x35, 0x05, 0x05, 0x60, 0x0f, 0x06, 0x05, 0x80, 0x2d, 0x07, 0x06, + 0x80, 0x24, 0x09, 0x07, 0xc8, 0x12, 0x00, 0x03, 0xd0, 0x12, 0x00, 0x03, 0xd8, 0x12, 0x00, 0x03, 0xe0, 0x12, 0x00, 0x03, 0x8c, 0x04, 0x01, 0x02, 0x90, 0x04, 0x01, 0x02, 0x94, 0x04, 0x01, 0x02, + 0x98, 0x04, 0x01, 0x02, 0x9c, 0x04, 0x01, 0x02, 0xa0, 0x04, 0x01, 0x02, 0xa4, 0x04, 0x01, 0x02, 0x18, 0x1d, 0x02, 0x03, 0x20, 0x1d, 0x02, 0x03, 0x28, 0x1d, 0x02, 0x03, 0x30, 0x1d, 0x02, 0x03, + 0xf0, 0x3e, 0x03, 0x04, 0x00, 0x3f, 0x03, 0x04, 0x10, 0x3f, 0x03, 0x04, 0x60, 0x16, 0x04, 0x04, 0x70, 0x16, 0x04, 0x04, 0xc0, 0x35, 0x05, 0x05, 0x80, 0x0f, 0x06, 0x05, 0xc0, 0x2d, 0x07, 0x06, + 0x00, 0x25, 0x09, 0x07, 0xe8, 0x12, 0x00, 0x03, 0xf0, 0x12, 0x00, 0x03, 0xf8, 0x12, 0x00, 0x03, 0x00, 0x13, 0x00, 0x03, 0xa8, 0x04, 0x01, 0x02, 0xac, 0x04, 0x01, 0x02, 0xb0, 0x04, 0x01, 0x02, + 0xb4, 0x04, 0x01, 0x02, 0xb8, 0x04, 0x01, 0x02, 0xbc, 0x04, 0x01, 0x02, 0xc0, 0x04, 0x01, 0x02, 0x38, 0x1d, 0x02, 0x03, 0x40, 0x1d, 0x02, 0x03, 0x48, 0x1d, 0x02, 0x03, 0x50, 0x1d, 0x02, 0x03, + 0x20, 0x3f, 0x03, 0x04, 0x30, 0x3f, 0x03, 0x04, 0x40, 0x3f, 0x03, 0x04, 0x80, 0x16, 0x04, 0x04, 0x90, 0x16, 0x04, 0x04, 0xe0, 0x35, 0x05, 0x05, 0xa0, 0x0f, 0x06, 0x05, 0x00, 0x2e, 0x07, 0x06, + 0x80, 0x25, 0x09, 0x07, 0x08, 0x13, 0x00, 0x03, 0x10, 0x13, 0x00, 0x03, 0x18, 0x13, 0x00, 0x03, 0x20, 0x13, 0x00, 0x03, 0xc4, 0x04, 0x01, 0x02, 0xc8, 0x04, 0x01, 0x02, 0xcc, 0x04, 0x01, 0x02, + 0xd0, 0x04, 0x01, 0x02, 0xd4, 0x04, 0x01, 0x02, 0xd8, 0x04, 0x01, 0x02, 0xdc, 0x04, 0x01, 0x02, 0x58, 0x1d, 0x02, 0x03, 0x60, 0x1d, 0x02, 0x03, 0x68, 0x1d, 0x02, 0x03, 0x70, 0x1d, 0x02, 0x03, + 0x50, 0x3f, 0x03, 0x04, 0x60, 0x3f, 0x03, 0x04, 0x70, 0x3f, 0x03, 0x04, 0xa0, 0x16, 0x04, 0x04, 0xb0, 0x16, 0x04, 0x04, 0x00, 0x36, 0x05, 0x05, 0xc0, 0x0f, 0x06, 0x05, 0x40, 0x2e, 0x07, 0x06, + 0x00, 0x26, 0x09, 0x07, 0x28, 0x13, 0x00, 0x03, 0x30, 0x13, 0x00, 0x03, 0x38, 0x13, 0x00, 0x03, 0x40, 0x13, 0x00, 0x03, 0xe0, 0x04, 0x01, 0x02, 0xe4, 0x04, 0x01, 0x02, 0xe8, 0x04, 0x01, 0x02, + 0xec, 0x04, 0x01, 0x02, 0xf0, 0x04, 0x01, 0x02, 0xf4, 0x04, 0x01, 0x02, 0xf8, 0x04, 0x01, 0x02, 0x78, 0x1d, 0x02, 0x03, 0x80, 0x1d, 0x02, 0x03, 0x88, 0x1d, 0x02, 0x03, 0x90, 0x1d, 0x02, 0x03, + 0x80, 0x3f, 0x03, 0x04, 0x90, 0x3f, 0x03, 0x04, 0xa0, 0x3f, 0x03, 0x04, 0xc0, 0x16, 0x04, 0x04, 0xd0, 0x16, 0x04, 0x04, 0x20, 0x36, 0x05, 0x05, 0xe0, 0x0f, 0x06, 0x05, 0x80, 0x2e, 0x07, 0x06, + 0x80, 0x26, 0x09, 0x07, 0x48, 0x13, 0x00, 0x03, 0x50, 0x13, 0x00, 0x03, 0x58, 0x13, 0x00, 0x03, 0x60, 0x13, 0x00, 0x03, 0xfc, 0x04, 0x01, 0x02, 0x00, 0x05, 0x01, 0x02, 0x04, 0x05, 0x01, 0x02, + 0x08, 0x05, 0x01, 0x02, 0x0c, 0x05, 0x01, 0x02, 0x10, 0x05, 0x01, 0x02, 0x14, 0x05, 0x01, 0x02, 0x98, 0x1d, 0x02, 0x03, 0xa0, 0x1d, 0x02, 0x03, 0xa8, 0x1d, 0x02, 0x03, 0xb0, 0x1d, 0x02, 0x03, + 0xb0, 0x3f, 0x03, 0x04, 0xc0, 0x3f, 0x03, 0x04, 0xd0, 0x3f, 0x03, 0x04, 0xe0, 0x16, 0x04, 0x04, 0xf0, 0x16, 0x04, 0x04, 0x40, 0x36, 0x05, 0x05, 0x00, 0x10, 0x06, 0x05, 0xc0, 0x2e, 0x07, 0x06, + 0x00, 0x27, 0x09, 0x07, 0x68, 0x13, 0x00, 0x03, 0x70, 0x13, 0x00, 0x03, 0x78, 0x13, 0x00, 0x03, 0x80, 0x13, 0x00, 0x03, 0x18, 0x05, 0x01, 0x02, 0x1c, 0x05, 0x01, 0x02, 0x20, 0x05, 0x01, 0x02, + 0x24, 0x05, 0x01, 0x02, 0x28, 0x05, 0x01, 0x02, 0x2c, 0x05, 0x01, 0x02, 0x30, 0x05, 0x01, 0x02, 0xb8, 0x1d, 0x02, 0x03, 0xc0, 0x1d, 0x02, 0x03, 0xc8, 0x1d, 0x02, 0x03, 0xd0, 0x1d, 0x02, 0x03, + 0xe0, 0x3f, 0x03, 0x04, 0xf0, 0x3f, 0x03, 0x04, 0x00, 0x00, 0x03, 0x03, 0x00, 0x17, 0x04, 0x04, 0x10, 0x17, 0x04, 0x04, 0x60, 0x36, 0x05, 0x05, 0x20, 0x10, 0x06, 0x05, 0x00, 0x2f, 0x07, 0x06, + 0x80, 0x27, 0x09, 0x07, 0x88, 0x13, 0x00, 0x03, 0x90, 0x13, 0x00, 0x03, 0x98, 0x13, 0x00, 0x03, 0xa0, 0x13, 0x00, 0x03, 0x34, 0x05, 0x01, 0x02, 0x38, 0x05, 0x01, 0x02, 0x3c, 0x05, 0x01, 0x02, + 0x40, 0x05, 0x01, 0x02, 0x44, 0x05, 0x01, 0x02, 0x48, 0x05, 0x01, 0x02, 0x4c, 0x05, 0x01, 0x02, 0xd8, 0x1d, 0x02, 0x03, 0xe0, 0x1d, 0x02, 0x03, 0xe8, 0x1d, 0x02, 0x03, 0xf0, 0x1d, 0x02, 0x03, + 0x08, 0x00, 0x03, 0x03, 0x10, 0x00, 0x03, 0x03, 0x18, 0x00, 0x03, 0x03, 0x20, 0x17, 0x04, 0x04, 0x30, 0x17, 0x04, 0x04, 0x80, 0x36, 0x05, 0x05, 0x40, 0x10, 0x06, 0x05, 0x40, 0x2f, 0x07, 0x06, + 0x00, 0x28, 0x09, 0x07, 0xa8, 0x13, 0x00, 0x03, 0xb0, 0x13, 0x00, 0x03, 0xb8, 0x13, 0x00, 0x03, 0xc0, 0x13, 0x00, 0x03, 0x50, 0x05, 0x01, 0x02, 0x54, 0x05, 0x01, 0x02, 0x58, 0x05, 0x01, 0x02, + 0x5c, 0x05, 0x01, 0x02, 0x60, 0x05, 0x01, 0x02, 0x64, 0x05, 0x01, 0x02, 0x68, 0x05, 0x01, 0x02, 0xf8, 0x1d, 0x02, 0x03, 0x00, 0x1e, 0x02, 0x03, 0x08, 0x1e, 0x02, 0x03, 0x10, 0x1e, 0x02, 0x03, + 0x20, 0x00, 0x03, 0x03, 0x28, 0x00, 0x03, 0x03, 0x30, 0x00, 0x03, 0x03, 0x40, 0x17, 0x04, 0x04, 0x50, 0x17, 0x04, 0x04, 0xa0, 0x36, 0x05, 0x05, 0x60, 0x10, 0x06, 0x05, 0x80, 0x2f, 0x07, 0x06, + 0x80, 0x28, 0x09, 0x07, 0xc8, 0x13, 0x00, 0x03, 0xd0, 0x13, 0x00, 0x03, 0xd8, 0x13, 0x00, 0x03, 0xe0, 0x13, 0x00, 0x03, 0x6c, 0x05, 0x01, 0x02, 0x70, 0x05, 0x01, 0x02, 0x74, 0x05, 0x01, 0x02, + 0x78, 0x05, 0x01, 0x02, 0x7c, 0x05, 0x01, 0x02, 0x80, 0x05, 0x01, 0x02, 0x84, 0x05, 0x01, 0x02, 0x18, 0x1e, 0x02, 0x03, 0x20, 0x1e, 0x02, 0x03, 0x28, 0x1e, 0x02, 0x03, 0x30, 0x1e, 0x02, 0x03, + 0x38, 0x00, 0x03, 0x03, 0x40, 0x00, 0x03, 0x03, 0x48, 0x00, 0x03, 0x03, 0x60, 0x17, 0x04, 0x04, 0x70, 0x17, 0x04, 0x04, 0xc0, 0x36, 0x05, 0x05, 0x80, 0x10, 0x06, 0x05, 0xc0, 0x2f, 0x07, 0x06, + 0x00, 0x29, 0x09, 0x07, 0xe8, 0x13, 0x00, 0x03, 0xf0, 0x13, 0x00, 0x03, 0xf8, 0x13, 0x00, 0x03, 0x00, 0x14, 0x00, 0x03, 0x88, 0x05, 0x01, 0x02, 0x8c, 0x05, 0x01, 0x02, 0x90, 0x05, 0x01, 0x02, + 0x94, 0x05, 0x01, 0x02, 0x98, 0x05, 0x01, 0x02, 0x9c, 0x05, 0x01, 0x02, 0xa0, 0x05, 0x01, 0x02, 0x38, 0x1e, 0x02, 0x03, 0x40, 0x1e, 0x02, 0x03, 0x48, 0x1e, 0x02, 0x03, 0x50, 0x1e, 0x02, 0x03, + 0x50, 0x00, 0x03, 0x03, 0x58, 0x00, 0x03, 0x03, 0x60, 0x00, 0x03, 0x03, 0x80, 0x17, 0x04, 0x04, 0x90, 0x17, 0x04, 0x04, 0xe0, 0x36, 0x05, 0x05, 0xa0, 0x10, 0x06, 0x05, 0x00, 0x30, 0x07, 0x06, + 0x80, 0x29, 0x09, 0x07, 0x08, 0x14, 0x00, 0x03, 0x10, 0x14, 0x00, 0x03, 0x18, 0x14, 0x00, 0x03, 0x20, 0x14, 0x00, 0x03, 0xa4, 0x05, 0x01, 0x02, 0xa8, 0x05, 0x01, 0x02, 0xac, 0x05, 0x01, 0x02, + 0xb0, 0x05, 0x01, 0x02, 0xb4, 0x05, 0x01, 0x02, 0xb8, 0x05, 0x01, 0x02, 0xbc, 0x05, 0x01, 0x02, 0x58, 0x1e, 0x02, 0x03, 0x60, 0x1e, 0x02, 0x03, 0x68, 0x1e, 0x02, 0x03, 0x70, 0x1e, 0x02, 0x03, + 0x68, 0x00, 0x03, 0x03, 0x70, 0x00, 0x03, 0x03, 0x78, 0x00, 0x03, 0x03, 0xa0, 0x17, 0x04, 0x04, 0xb0, 0x17, 0x04, 0x04, 0x00, 0x37, 0x05, 0x05, 0xc0, 0x10, 0x06, 0x05, 0x40, 0x30, 0x07, 0x06, + 0x00, 0x2a, 0x09, 0x07, 0x28, 0x14, 0x00, 0x03, 0x30, 0x14, 0x00, 0x03, 0x38, 0x14, 0x00, 0x03, 0x40, 0x14, 0x00, 0x03, 0xc0, 0x05, 0x01, 0x02, 0xc4, 0x05, 0x01, 0x02, 0xc8, 0x05, 0x01, 0x02, + 0xcc, 0x05, 0x01, 0x02, 0xd0, 0x05, 0x01, 0x02, 0xd4, 0x05, 0x01, 0x02, 0xd8, 0x05, 0x01, 0x02, 0x78, 0x1e, 0x02, 0x03, 0x80, 0x1e, 0x02, 0x03, 0x88, 0x1e, 0x02, 0x03, 0x90, 0x1e, 0x02, 0x03, + 0x80, 0x00, 0x03, 0x03, 0x88, 0x00, 0x03, 0x03, 0x90, 0x00, 0x03, 0x03, 0xc0, 0x17, 0x04, 0x04, 0xd0, 0x17, 0x04, 0x04, 0x20, 0x37, 0x05, 0x05, 0xe0, 0x10, 0x06, 0x05, 0x80, 0x30, 0x07, 0x06, + 0x80, 0x2a, 0x09, 0x07, 0x48, 0x14, 0x00, 0x03, 0x50, 0x14, 0x00, 0x03, 0x58, 0x14, 0x00, 0x03, 0x60, 0x14, 0x00, 0x03, 0xdc, 0x05, 0x01, 0x02, 0xe0, 0x05, 0x01, 0x02, 0xe4, 0x05, 0x01, 0x02, + 0xe8, 0x05, 0x01, 0x02, 0xec, 0x05, 0x01, 0x02, 0xf0, 0x05, 0x01, 0x02, 0xf4, 0x05, 0x01, 0x02, 0x98, 0x1e, 0x02, 0x03, 0xa0, 0x1e, 0x02, 0x03, 0xa8, 0x1e, 0x02, 0x03, 0xb0, 0x1e, 0x02, 0x03, + 0x98, 0x00, 0x03, 0x03, 0xa0, 0x00, 0x03, 0x03, 0xa8, 0x00, 0x03, 0x03, 0xe0, 0x17, 0x04, 0x04, 0xf0, 0x17, 0x04, 0x04, 0x40, 0x37, 0x05, 0x05, 0x00, 0x11, 0x06, 0x05, 0xc0, 0x30, 0x07, 0x06, + 0x00, 0x2b, 0x09, 0x07, 0x68, 0x14, 0x00, 0x03, 0x70, 0x14, 0x00, 0x03, 0x78, 0x14, 0x00, 0x03, 0x80, 0x14, 0x00, 0x03, 0xf8, 0x05, 0x01, 0x02, 0xfc, 0x05, 0x01, 0x02, 0x00, 0x06, 0x01, 0x02, + 0x04, 0x06, 0x01, 0x02, 0x08, 0x06, 0x01, 0x02, 0x0c, 0x06, 0x01, 0x02, 0x10, 0x06, 0x01, 0x02, 0xb8, 0x1e, 0x02, 0x03, 0xc0, 0x1e, 0x02, 0x03, 0xc8, 0x1e, 0x02, 0x03, 0xd0, 0x1e, 0x02, 0x03, + 0xb0, 0x00, 0x03, 0x03, 0xb8, 0x00, 0x03, 0x03, 0xc0, 0x00, 0x03, 0x03, 0x00, 0x18, 0x04, 0x04, 0x10, 0x18, 0x04, 0x04, 0x60, 0x37, 0x05, 0x05, 0x20, 0x11, 0x06, 0x05, 0x00, 0x31, 0x07, 0x06, + 0x80, 0x2b, 0x09, 0x07, 0x88, 0x14, 0x00, 0x03, 0x90, 0x14, 0x00, 0x03, 0x98, 0x14, 0x00, 0x03, 0xa0, 0x14, 0x00, 0x03, 0x14, 0x06, 0x01, 0x02, 0x18, 0x06, 0x01, 0x02, 0x1c, 0x06, 0x01, 0x02, + 0x20, 0x06, 0x01, 0x02, 0x24, 0x06, 0x01, 0x02, 0x28, 0x06, 0x01, 0x02, 0x2c, 0x06, 0x01, 0x02, 0xd8, 0x1e, 0x02, 0x03, 0xe0, 0x1e, 0x02, 0x03, 0xe8, 0x1e, 0x02, 0x03, 0xf0, 0x1e, 0x02, 0x03, + 0xc8, 0x00, 0x03, 0x03, 0xd0, 0x00, 0x03, 0x03, 0xd8, 0x00, 0x03, 0x03, 0x20, 0x18, 0x04, 0x04, 0x30, 0x18, 0x04, 0x04, 0x80, 0x37, 0x05, 0x05, 0x40, 0x11, 0x06, 0x05, 0x40, 0x31, 0x07, 0x06, + 0x00, 0x2c, 0x09, 0x07, 0xa8, 0x14, 0x00, 0x03, 0xb0, 0x14, 0x00, 0x03, 0xb8, 0x14, 0x00, 0x03, 0xc0, 0x14, 0x00, 0x03, 0x30, 0x06, 0x01, 0x02, 0x34, 0x06, 0x01, 0x02, 0x38, 0x06, 0x01, 0x02, + 0x3c, 0x06, 0x01, 0x02, 0x40, 0x06, 0x01, 0x02, 0x44, 0x06, 0x01, 0x02, 0x48, 0x06, 0x01, 0x02, 0xf8, 0x1e, 0x02, 0x03, 0x00, 0x1f, 0x02, 0x03, 0x08, 0x1f, 0x02, 0x03, 0x10, 0x1f, 0x02, 0x03, + 0xe0, 0x00, 0x03, 0x03, 0xe8, 0x00, 0x03, 0x03, 0xf0, 0x00, 0x03, 0x03, 0x40, 0x18, 0x04, 0x04, 0x50, 0x18, 0x04, 0x04, 0xa0, 0x37, 0x05, 0x05, 0x60, 0x11, 0x06, 0x05, 0x80, 0x31, 0x07, 0x06, + 0x80, 0x2c, 0x09, 0x07, 0xc8, 0x14, 0x00, 0x03, 0xd0, 0x14, 0x00, 0x03, 0xd8, 0x14, 0x00, 0x03, 0xe0, 0x14, 0x00, 0x03, 0x4c, 0x06, 0x01, 0x02, 0x50, 0x06, 0x01, 0x02, 0x54, 0x06, 0x01, 0x02, + 0x58, 0x06, 0x01, 0x02, 0x5c, 0x06, 0x01, 0x02, 0x60, 0x06, 0x01, 0x02, 0x64, 0x06, 0x01, 0x02, 0x18, 0x1f, 0x02, 0x03, 0x20, 0x1f, 0x02, 0x03, 0x28, 0x1f, 0x02, 0x03, 0x30, 0x1f, 0x02, 0x03, + 0xf8, 0x00, 0x03, 0x03, 0x00, 0x01, 0x03, 0x03, 0x08, 0x01, 0x03, 0x03, 0x60, 0x18, 0x04, 0x04, 0x70, 0x18, 0x04, 0x04, 0xc0, 0x37, 0x05, 0x05, 0x80, 0x11, 0x06, 0x05, 0xc0, 0x31, 0x07, 0x06, + 0x00, 0x2d, 0x09, 0x07, 0xe8, 0x14, 0x00, 0x03, 0xf0, 0x14, 0x00, 0x03, 0xf8, 0x14, 0x00, 0x03, 0x00, 0x15, 0x00, 0x03, 0x68, 0x06, 0x01, 0x02, 0x6c, 0x06, 0x01, 0x02, 0x70, 0x06, 0x01, 0x02, + 0x74, 0x06, 0x01, 0x02, 0x78, 0x06, 0x01, 0x02, 0x7c, 0x06, 0x01, 0x02, 0x38, 0x1f, 0x02, 0x03, 0x40, 0x1f, 0x02, 0x03, 0x48, 0x1f, 0x02, 0x03, 0x50, 0x1f, 0x02, 0x03, 0x58, 0x1f, 0x02, 0x03, + 0x10, 0x01, 0x03, 0x03, 0x18, 0x01, 0x03, 0x03, 0x20, 0x01, 0x03, 0x03, 0x80, 0x18, 0x04, 0x04, 0x90, 0x18, 0x04, 0x04, 0xe0, 0x37, 0x05, 0x05, 0xa0, 0x11, 0x06, 0x05, 0x00, 0x32, 0x07, 0x06, + 0x80, 0x2d, 0x09, 0x07, 0x08, 0x15, 0x00, 0x03, 0x10, 0x15, 0x00, 0x03, 0x18, 0x15, 0x00, 0x03, 0x20, 0x15, 0x00, 0x03, 0x80, 0x06, 0x01, 0x02, 0x84, 0x06, 0x01, 0x02, 0x88, 0x06, 0x01, 0x02, + 0x8c, 0x06, 0x01, 0x02, 0x90, 0x06, 0x01, 0x02, 0x94, 0x06, 0x01, 0x02, 0x60, 0x1f, 0x02, 0x03, 0x68, 0x1f, 0x02, 0x03, 0x70, 0x1f, 0x02, 0x03, 0x78, 0x1f, 0x02, 0x03, 0x80, 0x1f, 0x02, 0x03, + 0x28, 0x01, 0x03, 0x03, 0x30, 0x01, 0x03, 0x03, 0x38, 0x01, 0x03, 0x03, 0xa0, 0x18, 0x04, 0x04, 0xb0, 0x18, 0x04, 0x04, 0x00, 0x38, 0x05, 0x05, 0xc0, 0x11, 0x06, 0x05, 0x40, 0x32, 0x07, 0x06, + 0x00, 0x2e, 0x09, 0x07, 0x28, 0x15, 0x00, 0x03, 0x30, 0x15, 0x00, 0x03, 0x38, 0x15, 0x00, 0x03, 0x40, 0x15, 0x00, 0x03, 0x98, 0x06, 0x01, 0x02, 0x9c, 0x06, 0x01, 0x02, 0xa0, 0x06, 0x01, 0x02, + 0xa4, 0x06, 0x01, 0x02, 0xa8, 0x06, 0x01, 0x02, 0xac, 0x06, 0x01, 0x02, 0x88, 0x1f, 0x02, 0x03, 0x90, 0x1f, 0x02, 0x03, 0x98, 0x1f, 0x02, 0x03, 0xa0, 0x1f, 0x02, 0x03, 0xa8, 0x1f, 0x02, 0x03, + 0x40, 0x01, 0x03, 0x03, 0x48, 0x01, 0x03, 0x03, 0x50, 0x01, 0x03, 0x03, 0xc0, 0x18, 0x04, 0x04, 0xd0, 0x18, 0x04, 0x04, 0x20, 0x38, 0x05, 0x05, 0xe0, 0x11, 0x06, 0x05, 0x80, 0x32, 0x07, 0x06, + 0x80, 0x2e, 0x09, 0x07, 0x48, 0x15, 0x00, 0x03, 0x50, 0x15, 0x00, 0x03, 0x58, 0x15, 0x00, 0x03, 0x60, 0x15, 0x00, 0x03, 0xb0, 0x06, 0x01, 0x02, 0xb4, 0x06, 0x01, 0x02, 0xb8, 0x06, 0x01, 0x02, + 0xbc, 0x06, 0x01, 0x02, 0xc0, 0x06, 0x01, 0x02, 0xc4, 0x06, 0x01, 0x02, 0xb0, 0x1f, 0x02, 0x03, 0xb8, 0x1f, 0x02, 0x03, 0xc0, 0x1f, 0x02, 0x03, 0xc8, 0x1f, 0x02, 0x03, 0xd0, 0x1f, 0x02, 0x03, + 0x58, 0x01, 0x03, 0x03, 0x60, 0x01, 0x03, 0x03, 0x68, 0x01, 0x03, 0x03, 0xe0, 0x18, 0x04, 0x04, 0xf0, 0x18, 0x04, 0x04, 0x40, 0x38, 0x05, 0x05, 0x00, 0x12, 0x06, 0x05, 0xc0, 0x32, 0x07, 0x06, + 0x00, 0x2f, 0x09, 0x07, 0x68, 0x15, 0x00, 0x03, 0x70, 0x15, 0x00, 0x03, 0x78, 0x15, 0x00, 0x03, 0x80, 0x15, 0x00, 0x03, 0xc8, 0x06, 0x01, 0x02, 0xcc, 0x06, 0x01, 0x02, 0xd0, 0x06, 0x01, 0x02, + 0xd4, 0x06, 0x01, 0x02, 0xd8, 0x06, 0x01, 0x02, 0xdc, 0x06, 0x01, 0x02, 0xd8, 0x1f, 0x02, 0x03, 0xe0, 0x1f, 0x02, 0x03, 0xe8, 0x1f, 0x02, 0x03, 0xf0, 0x1f, 0x02, 0x03, 0xf8, 0x1f, 0x02, 0x03, + 0x70, 0x01, 0x03, 0x03, 0x78, 0x01, 0x03, 0x03, 0x80, 0x01, 0x03, 0x03, 0x00, 0x19, 0x04, 0x04, 0x10, 0x19, 0x04, 0x04, 0x60, 0x38, 0x05, 0x05, 0x20, 0x12, 0x06, 0x05, 0x00, 0x33, 0x07, 0x06, + 0x80, 0x2f, 0x09, 0x07, 0x88, 0x15, 0x00, 0x03, 0x90, 0x15, 0x00, 0x03, 0x98, 0x15, 0x00, 0x03, 0xa0, 0x15, 0x00, 0x03, 0xe0, 0x06, 0x01, 0x02, 0xe4, 0x06, 0x01, 0x02, 0xe8, 0x06, 0x01, 0x02, + 0xec, 0x06, 0x01, 0x02, 0xf0, 0x06, 0x01, 0x02, 0xf4, 0x06, 0x01, 0x02, 0x00, 0x20, 0x02, 0x03, 0x08, 0x20, 0x02, 0x03, 0x10, 0x20, 0x02, 0x03, 0x18, 0x20, 0x02, 0x03, 0x20, 0x20, 0x02, 0x03, + 0x88, 0x01, 0x03, 0x03, 0x90, 0x01, 0x03, 0x03, 0x98, 0x01, 0x03, 0x03, 0x20, 0x19, 0x04, 0x04, 0x30, 0x19, 0x04, 0x04, 0x80, 0x38, 0x05, 0x05, 0x40, 0x12, 0x06, 0x05, 0x40, 0x33, 0x07, 0x06, + 0x00, 0x04, 0x0a, 0x07, 0xa8, 0x15, 0x00, 0x03, 0xb0, 0x15, 0x00, 0x03, 0xb8, 0x15, 0x00, 0x03, 0xc0, 0x15, 0x00, 0x03, 0xf8, 0x06, 0x01, 0x02, 0xfc, 0x06, 0x01, 0x02, 0x00, 0x07, 0x01, 0x02, + 0x04, 0x07, 0x01, 0x02, 0x08, 0x07, 0x01, 0x02, 0x0c, 0x07, 0x01, 0x02, 0x28, 0x20, 0x02, 0x03, 0x30, 0x20, 0x02, 0x03, 0x38, 0x20, 0x02, 0x03, 0x40, 0x20, 0x02, 0x03, 0x48, 0x20, 0x02, 0x03, + 0xa0, 0x01, 0x03, 0x03, 0xa8, 0x01, 0x03, 0x03, 0xb0, 0x01, 0x03, 0x03, 0x40, 0x19, 0x04, 0x04, 0x50, 0x19, 0x04, 0x04, 0xa0, 0x38, 0x05, 0x05, 0x60, 0x12, 0x06, 0x05, 0x80, 0x33, 0x07, 0x06, + 0x80, 0x04, 0x0a, 0x07, 0xc8, 0x15, 0x00, 0x03, 0xd0, 0x15, 0x00, 0x03, 0xd8, 0x15, 0x00, 0x03, 0xe0, 0x15, 0x00, 0x03, 0x10, 0x07, 0x01, 0x02, 0x14, 0x07, 0x01, 0x02, 0x18, 0x07, 0x01, 0x02, + 0x1c, 0x07, 0x01, 0x02, 0x20, 0x07, 0x01, 0x02, 0x24, 0x07, 0x01, 0x02, 0x50, 0x20, 0x02, 0x03, 0x58, 0x20, 0x02, 0x03, 0x60, 0x20, 0x02, 0x03, 0x68, 0x20, 0x02, 0x03, 0x70, 0x20, 0x02, 0x03, + 0xb8, 0x01, 0x03, 0x03, 0xc0, 0x01, 0x03, 0x03, 0xc8, 0x01, 0x03, 0x03, 0x60, 0x19, 0x04, 0x04, 0x70, 0x19, 0x04, 0x04, 0xc0, 0x38, 0x05, 0x05, 0x80, 0x12, 0x06, 0x05, 0xc0, 0x33, 0x07, 0x06, + 0x00, 0x05, 0x0a, 0x07, 0xe8, 0x15, 0x00, 0x03, 0xf0, 0x15, 0x00, 0x03, 0xf8, 0x15, 0x00, 0x03, 0x00, 0x16, 0x00, 0x03, 0x28, 0x07, 0x01, 0x02, 0x2c, 0x07, 0x01, 0x02, 0x30, 0x07, 0x01, 0x02, + 0x34, 0x07, 0x01, 0x02, 0x38, 0x07, 0x01, 0x02, 0x3c, 0x07, 0x01, 0x02, 0x78, 0x20, 0x02, 0x03, 0x80, 0x20, 0x02, 0x03, 0x88, 0x20, 0x02, 0x03, 0x90, 0x20, 0x02, 0x03, 0x98, 0x20, 0x02, 0x03, + 0xd0, 0x01, 0x03, 0x03, 0xd8, 0x01, 0x03, 0x03, 0xe0, 0x01, 0x03, 0x03, 0x80, 0x19, 0x04, 0x04, 0x90, 0x19, 0x04, 0x04, 0xe0, 0x38, 0x05, 0x05, 0xa0, 0x12, 0x06, 0x05, 0x00, 0x34, 0x07, 0x06, + 0x80, 0x05, 0x0a, 0x07, 0x08, 0x16, 0x00, 0x03, 0x10, 0x16, 0x00, 0x03, 0x18, 0x16, 0x00, 0x03, 0x20, 0x16, 0x00, 0x03, 0x40, 0x07, 0x01, 0x02, 0x44, 0x07, 0x01, 0x02, 0x48, 0x07, 0x01, 0x02, + 0x4c, 0x07, 0x01, 0x02, 0x50, 0x07, 0x01, 0x02, 0x54, 0x07, 0x01, 0x02, 0xa0, 0x20, 0x02, 0x03, 0xa8, 0x20, 0x02, 0x03, 0xb0, 0x20, 0x02, 0x03, 0xb8, 0x20, 0x02, 0x03, 0xc0, 0x20, 0x02, 0x03, + 0xe8, 0x01, 0x03, 0x03, 0xf0, 0x01, 0x03, 0x03, 0xf8, 0x01, 0x03, 0x03, 0xa0, 0x19, 0x04, 0x04, 0xb0, 0x19, 0x04, 0x04, 0x00, 0x39, 0x05, 0x05, 0xc0, 0x12, 0x06, 0x05, 0x40, 0x34, 0x07, 0x06, + 0x00, 0x06, 0x0a, 0x07, 0x28, 0x16, 0x00, 0x03, 0x30, 0x16, 0x00, 0x03, 0x38, 0x16, 0x00, 0x03, 0x40, 0x16, 0x00, 0x03, 0x58, 0x07, 0x01, 0x02, 0x5c, 0x07, 0x01, 0x02, 0x60, 0x07, 0x01, 0x02, + 0x64, 0x07, 0x01, 0x02, 0x68, 0x07, 0x01, 0x02, 0x6c, 0x07, 0x01, 0x02, 0xc8, 0x20, 0x02, 0x03, 0xd0, 0x20, 0x02, 0x03, 0xd8, 0x20, 0x02, 0x03, 0xe0, 0x20, 0x02, 0x03, 0xe8, 0x20, 0x02, 0x03, + 0x00, 0x02, 0x03, 0x03, 0x08, 0x02, 0x03, 0x03, 0x10, 0x02, 0x03, 0x03, 0xc0, 0x19, 0x04, 0x04, 0xd0, 0x19, 0x04, 0x04, 0x20, 0x39, 0x05, 0x05, 0xe0, 0x12, 0x06, 0x05, 0x80, 0x34, 0x07, 0x06, + 0x80, 0x06, 0x0a, 0x07, 0x48, 0x16, 0x00, 0x03, 0x50, 0x16, 0x00, 0x03, 0x58, 0x16, 0x00, 0x03, 0x60, 0x16, 0x00, 0x03, 0x70, 0x07, 0x01, 0x02, 0x74, 0x07, 0x01, 0x02, 0x78, 0x07, 0x01, 0x02, + 0x7c, 0x07, 0x01, 0x02, 0x80, 0x07, 0x01, 0x02, 0x84, 0x07, 0x01, 0x02, 0xf0, 0x20, 0x02, 0x03, 0xf8, 0x20, 0x02, 0x03, 0x00, 0x21, 0x02, 0x03, 0x08, 0x21, 0x02, 0x03, 0x10, 0x21, 0x02, 0x03, + 0x18, 0x02, 0x03, 0x03, 0x20, 0x02, 0x03, 0x03, 0x28, 0x02, 0x03, 0x03, 0xe0, 0x19, 0x04, 0x04, 0xf0, 0x19, 0x04, 0x04, 0x40, 0x39, 0x05, 0x05, 0x00, 0x13, 0x06, 0x05, 0xc0, 0x34, 0x07, 0x06, + 0x00, 0x07, 0x0a, 0x07, 0x68, 0x16, 0x00, 0x03, 0x70, 0x16, 0x00, 0x03, 0x78, 0x16, 0x00, 0x03, 0x80, 0x16, 0x00, 0x03, 0x88, 0x07, 0x01, 0x02, 0x8c, 0x07, 0x01, 0x02, 0x90, 0x07, 0x01, 0x02, + 0x94, 0x07, 0x01, 0x02, 0x98, 0x07, 0x01, 0x02, 0x9c, 0x07, 0x01, 0x02, 0x18, 0x21, 0x02, 0x03, 0x20, 0x21, 0x02, 0x03, 0x28, 0x21, 0x02, 0x03, 0x30, 0x21, 0x02, 0x03, 0x38, 0x21, 0x02, 0x03, + 0x30, 0x02, 0x03, 0x03, 0x38, 0x02, 0x03, 0x03, 0x40, 0x02, 0x03, 0x03, 0x00, 0x1a, 0x04, 0x04, 0x10, 0x1a, 0x04, 0x04, 0x60, 0x39, 0x05, 0x05, 0x20, 0x13, 0x06, 0x05, 0x00, 0x35, 0x07, 0x06, + 0x80, 0x07, 0x0a, 0x07, 0x88, 0x16, 0x00, 0x03, 0x90, 0x16, 0x00, 0x03, 0x98, 0x16, 0x00, 0x03, 0xa0, 0x16, 0x00, 0x03, 0xa0, 0x07, 0x01, 0x02, 0xa4, 0x07, 0x01, 0x02, 0xa8, 0x07, 0x01, 0x02, + 0xac, 0x07, 0x01, 0x02, 0xb0, 0x07, 0x01, 0x02, 0xb4, 0x07, 0x01, 0x02, 0x40, 0x21, 0x02, 0x03, 0x48, 0x21, 0x02, 0x03, 0x50, 0x21, 0x02, 0x03, 0x58, 0x21, 0x02, 0x03, 0x60, 0x21, 0x02, 0x03, + 0x48, 0x02, 0x03, 0x03, 0x50, 0x02, 0x03, 0x03, 0x58, 0x02, 0x03, 0x03, 0x20, 0x1a, 0x04, 0x04, 0x30, 0x1a, 0x04, 0x04, 0x80, 0x39, 0x05, 0x05, 0x40, 0x13, 0x06, 0x05, 0x40, 0x35, 0x07, 0x06, + 0x00, 0x08, 0x0a, 0x07, 0xa8, 0x16, 0x00, 0x03, 0xb0, 0x16, 0x00, 0x03, 0xb8, 0x16, 0x00, 0x03, 0xc0, 0x16, 0x00, 0x03, 0xb8, 0x07, 0x01, 0x02, 0xbc, 0x07, 0x01, 0x02, 0xc0, 0x07, 0x01, 0x02, + 0xc4, 0x07, 0x01, 0x02, 0xc8, 0x07, 0x01, 0x02, 0xcc, 0x07, 0x01, 0x02, 0x68, 0x21, 0x02, 0x03, 0x70, 0x21, 0x02, 0x03, 0x78, 0x21, 0x02, 0x03, 0x80, 0x21, 0x02, 0x03, 0x88, 0x21, 0x02, 0x03, + 0x60, 0x02, 0x03, 0x03, 0x68, 0x02, 0x03, 0x03, 0x70, 0x02, 0x03, 0x03, 0x40, 0x1a, 0x04, 0x04, 0x50, 0x1a, 0x04, 0x04, 0xa0, 0x39, 0x05, 0x05, 0x60, 0x13, 0x06, 0x05, 0x80, 0x35, 0x07, 0x06, + 0x80, 0x08, 0x0a, 0x07, 0xc8, 0x16, 0x00, 0x03, 0xd0, 0x16, 0x00, 0x03, 0xd8, 0x16, 0x00, 0x03, 0xe0, 0x16, 0x00, 0x03, 0xd0, 0x07, 0x01, 0x02, 0xd4, 0x07, 0x01, 0x02, 0xd8, 0x07, 0x01, 0x02, + 0xdc, 0x07, 0x01, 0x02, 0xe0, 0x07, 0x01, 0x02, 0xe4, 0x07, 0x01, 0x02, 0x90, 0x21, 0x02, 0x03, 0x98, 0x21, 0x02, 0x03, 0xa0, 0x21, 0x02, 0x03, 0xa8, 0x21, 0x02, 0x03, 0xb0, 0x21, 0x02, 0x03, + 0x78, 0x02, 0x03, 0x03, 0x80, 0x02, 0x03, 0x03, 0x88, 0x02, 0x03, 0x03, 0x60, 0x1a, 0x04, 0x04, 0x70, 0x1a, 0x04, 0x04, 0xc0, 0x39, 0x05, 0x05, 0x80, 0x13, 0x06, 0x05, 0xc0, 0x35, 0x07, 0x06, + 0x00, 0x09, 0x0a, 0x07, 0xe8, 0x16, 0x00, 0x03, 0xf0, 0x16, 0x00, 0x03, 0xf8, 0x16, 0x00, 0x03, 0x00, 0x17, 0x00, 0x03, 0xe8, 0x07, 0x01, 0x02, 0xec, 0x07, 0x01, 0x02, 0xf0, 0x07, 0x01, 0x02, + 0xf4, 0x07, 0x01, 0x02, 0xf8, 0x07, 0x01, 0x02, 0xfc, 0x07, 0x01, 0x02, 0xb8, 0x21, 0x02, 0x03, 0xc0, 0x21, 0x02, 0x03, 0xc8, 0x21, 0x02, 0x03, 0xd0, 0x21, 0x02, 0x03, 0xd8, 0x21, 0x02, 0x03, + 0x90, 0x02, 0x03, 0x03, 0x98, 0x02, 0x03, 0x03, 0xa0, 0x02, 0x03, 0x03, 0x80, 0x1a, 0x04, 0x04, 0x90, 0x1a, 0x04, 0x04, 0xe0, 0x39, 0x05, 0x05, 0xa0, 0x13, 0x06, 0x05, 0x00, 0x36, 0x07, 0x06, + 0x80, 0x09, 0x0a, 0x07, 0x08, 0x17, 0x00, 0x03, 0x10, 0x17, 0x00, 0x03, 0x18, 0x17, 0x00, 0x03, 0x20, 0x17, 0x00, 0x03, 0x00, 0x08, 0x01, 0x02, 0x04, 0x08, 0x01, 0x02, 0x08, 0x08, 0x01, 0x02, + 0x0c, 0x08, 0x01, 0x02, 0x10, 0x08, 0x01, 0x02, 0x14, 0x08, 0x01, 0x02, 0xe0, 0x21, 0x02, 0x03, 0xe8, 0x21, 0x02, 0x03, 0xf0, 0x21, 0x02, 0x03, 0xf8, 0x21, 0x02, 0x03, 0x00, 0x22, 0x02, 0x03, + 0xa8, 0x02, 0x03, 0x03, 0xb0, 0x02, 0x03, 0x03, 0xb8, 0x02, 0x03, 0x03, 0xa0, 0x1a, 0x04, 0x04, 0xb0, 0x1a, 0x04, 0x04, 0x00, 0x3a, 0x05, 0x05, 0xc0, 0x13, 0x06, 0x05, 0x40, 0x36, 0x07, 0x06, + 0x00, 0x0a, 0x0a, 0x07, 0x28, 0x17, 0x00, 0x03, 0x30, 0x17, 0x00, 0x03, 0x38, 0x17, 0x00, 0x03, 0x40, 0x17, 0x00, 0x03, 0x18, 0x08, 0x01, 0x02, 0x1c, 0x08, 0x01, 0x02, 0x20, 0x08, 0x01, 0x02, + 0x24, 0x08, 0x01, 0x02, 0x28, 0x08, 0x01, 0x02, 0x2c, 0x08, 0x01, 0x02, 0x08, 0x22, 0x02, 0x03, 0x10, 0x22, 0x02, 0x03, 0x18, 0x22, 0x02, 0x03, 0x20, 0x22, 0x02, 0x03, 0x28, 0x22, 0x02, 0x03, + 0xc0, 0x02, 0x03, 0x03, 0xc8, 0x02, 0x03, 0x03, 0xd0, 0x02, 0x03, 0x03, 0xc0, 0x1a, 0x04, 0x04, 0xd0, 0x1a, 0x04, 0x04, 0x20, 0x3a, 0x05, 0x05, 0xe0, 0x13, 0x06, 0x05, 0x80, 0x36, 0x07, 0x06, + 0x80, 0x0a, 0x0a, 0x07, 0x48, 0x17, 0x00, 0x03, 0x50, 0x17, 0x00, 0x03, 0x58, 0x17, 0x00, 0x03, 0x60, 0x17, 0x00, 0x03, 0x30, 0x08, 0x01, 0x02, 0x34, 0x08, 0x01, 0x02, 0x38, 0x08, 0x01, 0x02, + 0x3c, 0x08, 0x01, 0x02, 0x40, 0x08, 0x01, 0x02, 0x44, 0x08, 0x01, 0x02, 0x30, 0x22, 0x02, 0x03, 0x38, 0x22, 0x02, 0x03, 0x40, 0x22, 0x02, 0x03, 0x48, 0x22, 0x02, 0x03, 0x50, 0x22, 0x02, 0x03, + 0xd8, 0x02, 0x03, 0x03, 0xe0, 0x02, 0x03, 0x03, 0xe8, 0x02, 0x03, 0x03, 0xe0, 0x1a, 0x04, 0x04, 0xf0, 0x1a, 0x04, 0x04, 0x40, 0x3a, 0x05, 0x05, 0x00, 0x14, 0x06, 0x05, 0xc0, 0x36, 0x07, 0x06, + 0x00, 0x0b, 0x0a, 0x07, 0x68, 0x17, 0x00, 0x03, 0x70, 0x17, 0x00, 0x03, 0x78, 0x17, 0x00, 0x03, 0x80, 0x17, 0x00, 0x03, 0x48, 0x08, 0x01, 0x02, 0x4c, 0x08, 0x01, 0x02, 0x50, 0x08, 0x01, 0x02, + 0x54, 0x08, 0x01, 0x02, 0x58, 0x08, 0x01, 0x02, 0x5c, 0x08, 0x01, 0x02, 0x58, 0x22, 0x02, 0x03, 0x60, 0x22, 0x02, 0x03, 0x68, 0x22, 0x02, 0x03, 0x70, 0x22, 0x02, 0x03, 0x78, 0x22, 0x02, 0x03, + 0xf0, 0x02, 0x03, 0x03, 0xf8, 0x02, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x00, 0x1b, 0x04, 0x04, 0x10, 0x1b, 0x04, 0x04, 0x60, 0x3a, 0x05, 0x05, 0x20, 0x14, 0x06, 0x05, 0x00, 0x37, 0x07, 0x06, + 0x80, 0x0b, 0x0a, 0x07, 0x88, 0x17, 0x00, 0x03, 0x90, 0x17, 0x00, 0x03, 0x98, 0x17, 0x00, 0x03, 0xa0, 0x17, 0x00, 0x03, 0x60, 0x08, 0x01, 0x02, 0x64, 0x08, 0x01, 0x02, 0x68, 0x08, 0x01, 0x02, + 0x6c, 0x08, 0x01, 0x02, 0x70, 0x08, 0x01, 0x02, 0x74, 0x08, 0x01, 0x02, 0x80, 0x22, 0x02, 0x03, 0x88, 0x22, 0x02, 0x03, 0x90, 0x22, 0x02, 0x03, 0x98, 0x22, 0x02, 0x03, 0xa0, 0x22, 0x02, 0x03, + 0x08, 0x03, 0x03, 0x03, 0x10, 0x03, 0x03, 0x03, 0x18, 0x03, 0x03, 0x03, 0x20, 0x1b, 0x04, 0x04, 0x30, 0x1b, 0x04, 0x04, 0x80, 0x3a, 0x05, 0x05, 0x40, 0x14, 0x06, 0x05, 0x40, 0x37, 0x07, 0x06, + 0x00, 0x0c, 0x0a, 0x07, 0xa8, 0x17, 0x00, 0x03, 0xb0, 0x17, 0x00, 0x03, 0xb8, 0x17, 0x00, 0x03, 0xc0, 0x17, 0x00, 0x03, 0x78, 0x08, 0x01, 0x02, 0x7c, 0x08, 0x01, 0x02, 0x80, 0x08, 0x01, 0x02, + 0x84, 0x08, 0x01, 0x02, 0x88, 0x08, 0x01, 0x02, 0x8c, 0x08, 0x01, 0x02, 0xa8, 0x22, 0x02, 0x03, 0xb0, 0x22, 0x02, 0x03, 0xb8, 0x22, 0x02, 0x03, 0xc0, 0x22, 0x02, 0x03, 0xc8, 0x22, 0x02, 0x03, + 0x20, 0x03, 0x03, 0x03, 0x28, 0x03, 0x03, 0x03, 0x30, 0x03, 0x03, 0x03, 0x40, 0x1b, 0x04, 0x04, 0x50, 0x1b, 0x04, 0x04, 0xa0, 0x3a, 0x05, 0x05, 0x60, 0x14, 0x06, 0x05, 0x80, 0x37, 0x07, 0x06, + 0x00, 0x1c, 0x0b, 0x08, 0xc8, 0x17, 0x00, 0x03, 0xd0, 0x17, 0x00, 0x03, 0xd8, 0x17, 0x00, 0x03, 0xe0, 0x17, 0x00, 0x03, 0x90, 0x08, 0x01, 0x02, 0x94, 0x08, 0x01, 0x02, 0x98, 0x08, 0x01, 0x02, + 0x9c, 0x08, 0x01, 0x02, 0xa0, 0x08, 0x01, 0x02, 0xa4, 0x08, 0x01, 0x02, 0xd0, 0x22, 0x02, 0x03, 0xd8, 0x22, 0x02, 0x03, 0xe0, 0x22, 0x02, 0x03, 0xe8, 0x22, 0x02, 0x03, 0xf0, 0x22, 0x02, 0x03, + 0x38, 0x03, 0x03, 0x03, 0x40, 0x03, 0x03, 0x03, 0x48, 0x03, 0x03, 0x03, 0x60, 0x1b, 0x04, 0x04, 0x70, 0x1b, 0x04, 0x04, 0xc0, 0x3a, 0x05, 0x05, 0x80, 0x14, 0x06, 0x05, 0xc0, 0x37, 0x07, 0x06, + 0x00, 0x1d, 0x0b, 0x08, 0xe8, 0x17, 0x00, 0x03, 0xf0, 0x17, 0x00, 0x03, 0xf8, 0x17, 0x00, 0x03, 0x00, 0x18, 0x00, 0x03, 0xa8, 0x08, 0x01, 0x02, 0xac, 0x08, 0x01, 0x02, 0xb0, 0x08, 0x01, 0x02, + 0xb4, 0x08, 0x01, 0x02, 0xb8, 0x08, 0x01, 0x02, 0xbc, 0x08, 0x01, 0x02, 0xf8, 0x22, 0x02, 0x03, 0x00, 0x23, 0x02, 0x03, 0x08, 0x23, 0x02, 0x03, 0x10, 0x23, 0x02, 0x03, 0x18, 0x23, 0x02, 0x03, + 0x50, 0x03, 0x03, 0x03, 0x58, 0x03, 0x03, 0x03, 0x60, 0x03, 0x03, 0x03, 0x80, 0x1b, 0x04, 0x04, 0x90, 0x1b, 0x04, 0x04, 0xe0, 0x3a, 0x05, 0x05, 0xa0, 0x14, 0x06, 0x05, 0x00, 0x38, 0x07, 0x06, + 0x00, 0x1e, 0x0b, 0x08, 0x08, 0x18, 0x00, 0x03, 0x10, 0x18, 0x00, 0x03, 0x18, 0x18, 0x00, 0x03, 0x20, 0x18, 0x00, 0x03, 0xc0, 0x08, 0x01, 0x02, 0xc4, 0x08, 0x01, 0x02, 0xc8, 0x08, 0x01, 0x02, + 0xcc, 0x08, 0x01, 0x02, 0xd0, 0x08, 0x01, 0x02, 0xd4, 0x08, 0x01, 0x02, 0x20, 0x23, 0x02, 0x03, 0x28, 0x23, 0x02, 0x03, 0x30, 0x23, 0x02, 0x03, 0x38, 0x23, 0x02, 0x03, 0x40, 0x23, 0x02, 0x03, + 0x68, 0x03, 0x03, 0x03, 0x70, 0x03, 0x03, 0x03, 0x78, 0x03, 0x03, 0x03, 0xa0, 0x1b, 0x04, 0x04, 0xb0, 0x1b, 0x04, 0x04, 0x00, 0x3b, 0x05, 0x05, 0xc0, 0x14, 0x06, 0x05, 0x40, 0x38, 0x07, 0x06, + 0x00, 0x1f, 0x0b, 0x08, 0x28, 0x18, 0x00, 0x03, 0x30, 0x18, 0x00, 0x03, 0x38, 0x18, 0x00, 0x03, 0x40, 0x18, 0x00, 0x03, 0xd8, 0x08, 0x01, 0x02, 0xdc, 0x08, 0x01, 0x02, 0xe0, 0x08, 0x01, 0x02, + 0xe4, 0x08, 0x01, 0x02, 0xe8, 0x08, 0x01, 0x02, 0xec, 0x08, 0x01, 0x02, 0x48, 0x23, 0x02, 0x03, 0x50, 0x23, 0x02, 0x03, 0x58, 0x23, 0x02, 0x03, 0x60, 0x23, 0x02, 0x03, 0x68, 0x23, 0x02, 0x03, + 0x80, 0x03, 0x03, 0x03, 0x88, 0x03, 0x03, 0x03, 0x90, 0x03, 0x03, 0x03, 0xc0, 0x1b, 0x04, 0x04, 0xd0, 0x1b, 0x04, 0x04, 0x20, 0x3b, 0x05, 0x05, 0xe0, 0x14, 0x06, 0x05, 0x80, 0x38, 0x07, 0x06, + 0x00, 0x20, 0x0b, 0x08, 0x48, 0x18, 0x00, 0x03, 0x50, 0x18, 0x00, 0x03, 0x58, 0x18, 0x00, 0x03, 0x60, 0x18, 0x00, 0x03, 0xf0, 0x08, 0x01, 0x02, 0xf4, 0x08, 0x01, 0x02, 0xf8, 0x08, 0x01, 0x02, + 0xfc, 0x08, 0x01, 0x02, 0x00, 0x09, 0x01, 0x02, 0x04, 0x09, 0x01, 0x02, 0x70, 0x23, 0x02, 0x03, 0x78, 0x23, 0x02, 0x03, 0x80, 0x23, 0x02, 0x03, 0x88, 0x23, 0x02, 0x03, 0x90, 0x23, 0x02, 0x03, + 0x98, 0x03, 0x03, 0x03, 0xa0, 0x03, 0x03, 0x03, 0xa8, 0x03, 0x03, 0x03, 0xe0, 0x1b, 0x04, 0x04, 0xf0, 0x1b, 0x04, 0x04, 0x40, 0x3b, 0x05, 0x05, 0x00, 0x15, 0x06, 0x05, 0xc0, 0x38, 0x07, 0x06, + 0x00, 0x21, 0x0b, 0x08, 0x68, 0x18, 0x00, 0x03, 0x70, 0x18, 0x00, 0x03, 0x78, 0x18, 0x00, 0x03, 0x80, 0x18, 0x00, 0x03, 0x08, 0x09, 0x01, 0x02, 0x0c, 0x09, 0x01, 0x02, 0x10, 0x09, 0x01, 0x02, + 0x14, 0x09, 0x01, 0x02, 0x18, 0x09, 0x01, 0x02, 0x1c, 0x09, 0x01, 0x02, 0x98, 0x23, 0x02, 0x03, 0xa0, 0x23, 0x02, 0x03, 0xa8, 0x23, 0x02, 0x03, 0xb0, 0x23, 0x02, 0x03, 0xb8, 0x23, 0x02, 0x03, + 0xb0, 0x03, 0x03, 0x03, 0xb8, 0x03, 0x03, 0x03, 0xc0, 0x03, 0x03, 0x03, 0x00, 0x1c, 0x04, 0x04, 0x10, 0x1c, 0x04, 0x04, 0x60, 0x3b, 0x05, 0x05, 0x20, 0x15, 0x06, 0x05, 0xc0, 0x0a, 0x08, 0x06, + 0x00, 0x22, 0x0b, 0x08, 0x88, 0x18, 0x00, 0x03, 0x90, 0x18, 0x00, 0x03, 0x98, 0x18, 0x00, 0x03, 0xa0, 0x18, 0x00, 0x03, 0x20, 0x09, 0x01, 0x02, 0x24, 0x09, 0x01, 0x02, 0x28, 0x09, 0x01, 0x02, + 0x2c, 0x09, 0x01, 0x02, 0x30, 0x09, 0x01, 0x02, 0x34, 0x09, 0x01, 0x02, 0xc0, 0x23, 0x02, 0x03, 0xc8, 0x23, 0x02, 0x03, 0xd0, 0x23, 0x02, 0x03, 0xd8, 0x23, 0x02, 0x03, 0xe0, 0x23, 0x02, 0x03, + 0xc8, 0x03, 0x03, 0x03, 0xd0, 0x03, 0x03, 0x03, 0x20, 0x1c, 0x04, 0x04, 0x30, 0x1c, 0x04, 0x04, 0x40, 0x1c, 0x04, 0x04, 0x80, 0x3b, 0x05, 0x05, 0x40, 0x15, 0x06, 0x05, 0x00, 0x0b, 0x08, 0x06, + 0x00, 0x23, 0x0b, 0x08, 0xa8, 0x18, 0x00, 0x03, 0xb0, 0x18, 0x00, 0x03, 0xb8, 0x18, 0x00, 0x03, 0xc0, 0x18, 0x00, 0x03, 0x38, 0x09, 0x01, 0x02, 0x3c, 0x09, 0x01, 0x02, 0x40, 0x09, 0x01, 0x02, + 0x44, 0x09, 0x01, 0x02, 0x48, 0x09, 0x01, 0x02, 0x4c, 0x09, 0x01, 0x02, 0xe8, 0x23, 0x02, 0x03, 0xf0, 0x23, 0x02, 0x03, 0xf8, 0x23, 0x02, 0x03, 0x00, 0x24, 0x02, 0x03, 0x08, 0x24, 0x02, 0x03, + 0xd8, 0x03, 0x03, 0x03, 0xe0, 0x03, 0x03, 0x03, 0x50, 0x1c, 0x04, 0x04, 0x60, 0x1c, 0x04, 0x04, 0x70, 0x1c, 0x04, 0x04, 0xa0, 0x3b, 0x05, 0x05, 0x60, 0x15, 0x06, 0x05, 0x40, 0x0b, 0x08, 0x06, + 0x00, 0x24, 0x0b, 0x08, 0xc8, 0x18, 0x00, 0x03, 0xd0, 0x18, 0x00, 0x03, 0xd8, 0x18, 0x00, 0x03, 0xe0, 0x18, 0x00, 0x03, 0x50, 0x09, 0x01, 0x02, 0x54, 0x09, 0x01, 0x02, 0x58, 0x09, 0x01, 0x02, + 0x5c, 0x09, 0x01, 0x02, 0x60, 0x09, 0x01, 0x02, 0x64, 0x09, 0x01, 0x02, 0x10, 0x24, 0x02, 0x03, 0x18, 0x24, 0x02, 0x03, 0x20, 0x24, 0x02, 0x03, 0x28, 0x24, 0x02, 0x03, 0xe8, 0x03, 0x03, 0x03, + 0xf0, 0x03, 0x03, 0x03, 0xf8, 0x03, 0x03, 0x03, 0x80, 0x1c, 0x04, 0x04, 0x90, 0x1c, 0x04, 0x04, 0xc0, 0x3b, 0x05, 0x05, 0xe0, 0x3b, 0x05, 0x05, 0x80, 0x15, 0x06, 0x05, 0x80, 0x0b, 0x08, 0x06, + 0x00, 0x25, 0x0b, 0x08, 0xe8, 0x18, 0x00, 0x03, 0xf0, 0x18, 0x00, 0x03, 0xf8, 0x18, 0x00, 0x03, 0x00, 0x19, 0x00, 0x03, 0x68, 0x09, 0x01, 0x02, 0x6c, 0x09, 0x01, 0x02, 0x70, 0x09, 0x01, 0x02, + 0x74, 0x09, 0x01, 0x02, 0x78, 0x09, 0x01, 0x02, 0x7c, 0x09, 0x01, 0x02, 0x30, 0x24, 0x02, 0x03, 0x38, 0x24, 0x02, 0x03, 0x40, 0x24, 0x02, 0x03, 0x48, 0x24, 0x02, 0x03, 0x00, 0x04, 0x03, 0x03, + 0x08, 0x04, 0x03, 0x03, 0x10, 0x04, 0x03, 0x03, 0xa0, 0x1c, 0x04, 0x04, 0xb0, 0x1c, 0x04, 0x04, 0x00, 0x3c, 0x05, 0x05, 0x20, 0x3c, 0x05, 0x05, 0xa0, 0x15, 0x06, 0x05, 0xc0, 0x0b, 0x08, 0x06, + 0x00, 0x26, 0x0b, 0x08, 0x08, 0x19, 0x00, 0x03, 0x10, 0x19, 0x00, 0x03, 0x18, 0x19, 0x00, 0x03, 0x20, 0x19, 0x00, 0x03, 0x80, 0x09, 0x01, 0x02, 0x84, 0x09, 0x01, 0x02, 0x88, 0x09, 0x01, 0x02, + 0x8c, 0x09, 0x01, 0x02, 0x90, 0x09, 0x01, 0x02, 0x94, 0x09, 0x01, 0x02, 0x50, 0x24, 0x02, 0x03, 0x58, 0x24, 0x02, 0x03, 0x60, 0x24, 0x02, 0x03, 0x68, 0x24, 0x02, 0x03, 0x18, 0x04, 0x03, 0x03, + 0x20, 0x04, 0x03, 0x03, 0x28, 0x04, 0x03, 0x03, 0xc0, 0x1c, 0x04, 0x04, 0xd0, 0x1c, 0x04, 0x04, 0x40, 0x3c, 0x05, 0x05, 0x60, 0x3c, 0x05, 0x05, 0xc0, 0x15, 0x06, 0x05, 0x00, 0x0c, 0x08, 0x06, + 0x00, 0x27, 0x0b, 0x08, 0x28, 0x19, 0x00, 0x03, 0x30, 0x19, 0x00, 0x03, 0x38, 0x19, 0x00, 0x03, 0x40, 0x19, 0x00, 0x03, 0x98, 0x09, 0x01, 0x02, 0x9c, 0x09, 0x01, 0x02, 0xa0, 0x09, 0x01, 0x02, + 0xa4, 0x09, 0x01, 0x02, 0xa8, 0x09, 0x01, 0x02, 0xac, 0x09, 0x01, 0x02, 0x70, 0x24, 0x02, 0x03, 0x78, 0x24, 0x02, 0x03, 0x80, 0x24, 0x02, 0x03, 0x88, 0x24, 0x02, 0x03, 0x30, 0x04, 0x03, 0x03, + 0x38, 0x04, 0x03, 0x03, 0x40, 0x04, 0x03, 0x03, 0xe0, 0x1c, 0x04, 0x04, 0xf0, 0x1c, 0x04, 0x04, 0x80, 0x3c, 0x05, 0x05, 0xa0, 0x3c, 0x05, 0x05, 0xe0, 0x15, 0x06, 0x05, 0x40, 0x0c, 0x08, 0x06, + 0x00, 0x3e, 0x0c, 0x09, 0x48, 0x19, 0x00, 0x03, 0x50, 0x19, 0x00, 0x03, 0x58, 0x19, 0x00, 0x03, 0x60, 0x19, 0x00, 0x03, 0xb0, 0x09, 0x01, 0x02, 0xb4, 0x09, 0x01, 0x02, 0xb8, 0x09, 0x01, 0x02, + 0xbc, 0x09, 0x01, 0x02, 0xc0, 0x09, 0x01, 0x02, 0xc4, 0x09, 0x01, 0x02, 0x90, 0x24, 0x02, 0x03, 0x98, 0x24, 0x02, 0x03, 0xa0, 0x24, 0x02, 0x03, 0xa8, 0x24, 0x02, 0x03, 0x48, 0x04, 0x03, 0x03, + 0x50, 0x04, 0x03, 0x03, 0x58, 0x04, 0x03, 0x03, 0x00, 0x1d, 0x04, 0x04, 0x10, 0x1d, 0x04, 0x04, 0xc0, 0x3c, 0x05, 0x05, 0xe0, 0x3c, 0x05, 0x05, 0x00, 0x16, 0x06, 0x05, 0x80, 0x0c, 0x08, 0x06, + 0x00, 0x00, 0x0c, 0x08, 0x68, 0x19, 0x00, 0x03, 0x70, 0x19, 0x00, 0x03, 0x78, 0x19, 0x00, 0x03, 0x80, 0x19, 0x00, 0x03, 0xc8, 0x09, 0x01, 0x02, 0xcc, 0x09, 0x01, 0x02, 0xd0, 0x09, 0x01, 0x02, + 0xd4, 0x09, 0x01, 0x02, 0xd8, 0x09, 0x01, 0x02, 0xdc, 0x09, 0x01, 0x02, 0xb0, 0x24, 0x02, 0x03, 0xb8, 0x24, 0x02, 0x03, 0xc0, 0x24, 0x02, 0x03, 0xc8, 0x24, 0x02, 0x03, 0x60, 0x04, 0x03, 0x03, + 0x68, 0x04, 0x03, 0x03, 0x70, 0x04, 0x03, 0x03, 0x20, 0x1d, 0x04, 0x04, 0x30, 0x1d, 0x04, 0x04, 0x00, 0x3d, 0x05, 0x05, 0x20, 0x3d, 0x05, 0x05, 0x20, 0x16, 0x06, 0x05, 0xc0, 0x0c, 0x08, 0x06, + 0x00, 0x01, 0x0c, 0x08, 0x88, 0x19, 0x00, 0x03, 0x90, 0x19, 0x00, 0x03, 0x98, 0x19, 0x00, 0x03, 0xa0, 0x19, 0x00, 0x03, 0xe0, 0x09, 0x01, 0x02, 0xe4, 0x09, 0x01, 0x02, 0xe8, 0x09, 0x01, 0x02, + 0xec, 0x09, 0x01, 0x02, 0xf0, 0x09, 0x01, 0x02, 0xf4, 0x09, 0x01, 0x02, 0xd0, 0x24, 0x02, 0x03, 0xd8, 0x24, 0x02, 0x03, 0xe0, 0x24, 0x02, 0x03, 0xe8, 0x24, 0x02, 0x03, 0x78, 0x04, 0x03, 0x03, + 0x80, 0x04, 0x03, 0x03, 0x88, 0x04, 0x03, 0x03, 0x40, 0x1d, 0x04, 0x04, 0x50, 0x1d, 0x04, 0x04, 0x40, 0x3d, 0x05, 0x05, 0x60, 0x3d, 0x05, 0x05, 0x40, 0x16, 0x06, 0x05, 0x00, 0x0d, 0x08, 0x06, + 0x00, 0x02, 0x0c, 0x08, 0xa8, 0x19, 0x00, 0x03, 0xb0, 0x19, 0x00, 0x03, 0xb8, 0x19, 0x00, 0x03, 0xc0, 0x19, 0x00, 0x03, 0xf8, 0x09, 0x01, 0x02, 0xfc, 0x09, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, + 0x04, 0x0a, 0x01, 0x02, 0x08, 0x0a, 0x01, 0x02, 0x0c, 0x0a, 0x01, 0x02, 0xf0, 0x24, 0x02, 0x03, 0xf8, 0x24, 0x02, 0x03, 0x00, 0x25, 0x02, 0x03, 0x08, 0x25, 0x02, 0x03, 0x90, 0x04, 0x03, 0x03, + 0x98, 0x04, 0x03, 0x03, 0xa0, 0x04, 0x03, 0x03, 0x60, 0x1d, 0x04, 0x04, 0x70, 0x1d, 0x04, 0x04, 0x80, 0x3d, 0x05, 0x05, 0xa0, 0x3d, 0x05, 0x05, 0x60, 0x16, 0x06, 0x05, 0x40, 0x0d, 0x08, 0x06, + 0x00, 0x03, 0x0c, 0x08, 0xc8, 0x19, 0x00, 0x03, 0xd0, 0x19, 0x00, 0x03, 0xd8, 0x19, 0x00, 0x03, 0xe0, 0x19, 0x00, 0x03, 0x10, 0x0a, 0x01, 0x02, 0x14, 0x0a, 0x01, 0x02, 0x18, 0x0a, 0x01, 0x02, + 0x1c, 0x0a, 0x01, 0x02, 0x20, 0x0a, 0x01, 0x02, 0x24, 0x0a, 0x01, 0x02, 0x10, 0x25, 0x02, 0x03, 0x18, 0x25, 0x02, 0x03, 0x20, 0x25, 0x02, 0x03, 0x28, 0x25, 0x02, 0x03, 0xa8, 0x04, 0x03, 0x03, + 0xb0, 0x04, 0x03, 0x03, 0xb8, 0x04, 0x03, 0x03, 0x80, 0x1d, 0x04, 0x04, 0x90, 0x1d, 0x04, 0x04, 0xc0, 0x3d, 0x05, 0x05, 0xe0, 0x3d, 0x05, 0x05, 0x80, 0x16, 0x06, 0x05, 0x80, 0x0d, 0x08, 0x06, + 0x00, 0x04, 0x0c, 0x08, 0xe8, 0x19, 0x00, 0x03, 0xf0, 0x19, 0x00, 0x03, 0xf8, 0x19, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x03, 0x28, 0x0a, 0x01, 0x02, 0x2c, 0x0a, 0x01, 0x02, 0x30, 0x0a, 0x01, 0x02, + 0x34, 0x0a, 0x01, 0x02, 0x38, 0x0a, 0x01, 0x02, 0x3c, 0x0a, 0x01, 0x02, 0x30, 0x25, 0x02, 0x03, 0x38, 0x25, 0x02, 0x03, 0x40, 0x25, 0x02, 0x03, 0x48, 0x25, 0x02, 0x03, 0xc0, 0x04, 0x03, 0x03, + 0xc8, 0x04, 0x03, 0x03, 0xd0, 0x04, 0x03, 0x03, 0xa0, 0x1d, 0x04, 0x04, 0xb0, 0x1d, 0x04, 0x04, 0x00, 0x3e, 0x05, 0x05, 0x20, 0x3e, 0x05, 0x05, 0xa0, 0x16, 0x06, 0x05, 0xc0, 0x0d, 0x08, 0x06, + 0x00, 0x05, 0x0c, 0x08, 0x08, 0x1a, 0x00, 0x03, 0x10, 0x1a, 0x00, 0x03, 0x18, 0x1a, 0x00, 0x03, 0x20, 0x1a, 0x00, 0x03, 0x40, 0x0a, 0x01, 0x02, 0x44, 0x0a, 0x01, 0x02, 0x48, 0x0a, 0x01, 0x02, + 0x4c, 0x0a, 0x01, 0x02, 0x50, 0x0a, 0x01, 0x02, 0x54, 0x0a, 0x01, 0x02, 0x50, 0x25, 0x02, 0x03, 0x58, 0x25, 0x02, 0x03, 0x60, 0x25, 0x02, 0x03, 0x68, 0x25, 0x02, 0x03, 0xd8, 0x04, 0x03, 0x03, + 0xe0, 0x04, 0x03, 0x03, 0xe8, 0x04, 0x03, 0x03, 0xc0, 0x1d, 0x04, 0x04, 0xd0, 0x1d, 0x04, 0x04, 0x40, 0x3e, 0x05, 0x05, 0x60, 0x3e, 0x05, 0x05, 0xc0, 0x16, 0x06, 0x05, 0x00, 0x0e, 0x08, 0x06, + 0x00, 0x16, 0x0d, 0x09, 0x28, 0x1a, 0x00, 0x03, 0x30, 0x1a, 0x00, 0x03, 0x38, 0x1a, 0x00, 0x03, 0x40, 0x1a, 0x00, 0x03, 0x58, 0x0a, 0x01, 0x02, 0x5c, 0x0a, 0x01, 0x02, 0x60, 0x0a, 0x01, 0x02, + 0x64, 0x0a, 0x01, 0x02, 0x68, 0x0a, 0x01, 0x02, 0x6c, 0x0a, 0x01, 0x02, 0x70, 0x25, 0x02, 0x03, 0x78, 0x25, 0x02, 0x03, 0x80, 0x25, 0x02, 0x03, 0x88, 0x25, 0x02, 0x03, 0xf0, 0x04, 0x03, 0x03, + 0xf8, 0x04, 0x03, 0x03, 0x00, 0x05, 0x03, 0x03, 0xe0, 0x1d, 0x04, 0x04, 0xf0, 0x1d, 0x04, 0x04, 0x80, 0x3e, 0x05, 0x05, 0xa0, 0x3e, 0x05, 0x05, 0xe0, 0x16, 0x06, 0x05, 0x40, 0x0e, 0x08, 0x06, + 0x00, 0x18, 0x0d, 0x09, 0x48, 0x1a, 0x00, 0x03, 0x50, 0x1a, 0x00, 0x03, 0x58, 0x1a, 0x00, 0x03, 0x60, 0x1a, 0x00, 0x03, 0x70, 0x0a, 0x01, 0x02, 0x74, 0x0a, 0x01, 0x02, 0x78, 0x0a, 0x01, 0x02, + 0x7c, 0x0a, 0x01, 0x02, 0x80, 0x0a, 0x01, 0x02, 0x84, 0x0a, 0x01, 0x02, 0x90, 0x25, 0x02, 0x03, 0x98, 0x25, 0x02, 0x03, 0xa0, 0x25, 0x02, 0x03, 0xa8, 0x25, 0x02, 0x03, 0x08, 0x05, 0x03, 0x03, + 0x10, 0x05, 0x03, 0x03, 0x18, 0x05, 0x03, 0x03, 0x00, 0x1e, 0x04, 0x04, 0x10, 0x1e, 0x04, 0x04, 0xc0, 0x3e, 0x05, 0x05, 0xe0, 0x3e, 0x05, 0x05, 0x00, 0x17, 0x06, 0x05, 0x80, 0x0e, 0x08, 0x06, + 0x00, 0x1a, 0x0d, 0x09, 0x68, 0x1a, 0x00, 0x03, 0x70, 0x1a, 0x00, 0x03, 0x78, 0x1a, 0x00, 0x03, 0x80, 0x1a, 0x00, 0x03, 0x88, 0x0a, 0x01, 0x02, 0x8c, 0x0a, 0x01, 0x02, 0x90, 0x0a, 0x01, 0x02, + 0x94, 0x0a, 0x01, 0x02, 0x98, 0x0a, 0x01, 0x02, 0x9c, 0x0a, 0x01, 0x02, 0xb0, 0x25, 0x02, 0x03, 0xb8, 0x25, 0x02, 0x03, 0xc0, 0x25, 0x02, 0x03, 0xc8, 0x25, 0x02, 0x03, 0x20, 0x05, 0x03, 0x03, + 0x28, 0x05, 0x03, 0x03, 0x30, 0x05, 0x03, 0x03, 0x20, 0x1e, 0x04, 0x04, 0x30, 0x1e, 0x04, 0x04, 0x00, 0x3f, 0x05, 0x05, 0x20, 0x3f, 0x05, 0x05, 0x20, 0x17, 0x06, 0x05, 0xc0, 0x0e, 0x08, 0x06, + 0x00, 0x1c, 0x0d, 0x09, 0x88, 0x1a, 0x00, 0x03, 0x90, 0x1a, 0x00, 0x03, 0x98, 0x1a, 0x00, 0x03, 0xa0, 0x1a, 0x00, 0x03, 0xa0, 0x0a, 0x01, 0x02, 0xa4, 0x0a, 0x01, 0x02, 0xa8, 0x0a, 0x01, 0x02, + 0xac, 0x0a, 0x01, 0x02, 0xb0, 0x0a, 0x01, 0x02, 0xb4, 0x0a, 0x01, 0x02, 0xd0, 0x25, 0x02, 0x03, 0xd8, 0x25, 0x02, 0x03, 0xe0, 0x25, 0x02, 0x03, 0xe8, 0x25, 0x02, 0x03, 0x38, 0x05, 0x03, 0x03, + 0x40, 0x05, 0x03, 0x03, 0x48, 0x05, 0x03, 0x03, 0x40, 0x1e, 0x04, 0x04, 0x50, 0x1e, 0x04, 0x04, 0x40, 0x3f, 0x05, 0x05, 0x60, 0x3f, 0x05, 0x05, 0x40, 0x17, 0x06, 0x05, 0x00, 0x0f, 0x08, 0x06, + 0x00, 0x1e, 0x0d, 0x09, 0xa8, 0x1a, 0x00, 0x03, 0xb0, 0x1a, 0x00, 0x03, 0xb8, 0x1a, 0x00, 0x03, 0xc0, 0x1a, 0x00, 0x03, 0xb8, 0x0a, 0x01, 0x02, 0xbc, 0x0a, 0x01, 0x02, 0xc0, 0x0a, 0x01, 0x02, + 0xc4, 0x0a, 0x01, 0x02, 0xc8, 0x0a, 0x01, 0x02, 0xcc, 0x0a, 0x01, 0x02, 0xf0, 0x25, 0x02, 0x03, 0xf8, 0x25, 0x02, 0x03, 0x00, 0x26, 0x02, 0x03, 0x08, 0x26, 0x02, 0x03, 0x50, 0x05, 0x03, 0x03, + 0x58, 0x05, 0x03, 0x03, 0x60, 0x05, 0x03, 0x03, 0x60, 0x1e, 0x04, 0x04, 0x70, 0x1e, 0x04, 0x04, 0x80, 0x3f, 0x05, 0x05, 0xa0, 0x3f, 0x05, 0x05, 0x60, 0x17, 0x06, 0x05, 0x40, 0x0f, 0x08, 0x06, + 0x00, 0x20, 0x0d, 0x09, 0xc8, 0x1a, 0x00, 0x03, 0xd0, 0x1a, 0x00, 0x03, 0xd8, 0x1a, 0x00, 0x03, 0xe0, 0x1a, 0x00, 0x03, 0xd0, 0x0a, 0x01, 0x02, 0xd4, 0x0a, 0x01, 0x02, 0xd8, 0x0a, 0x01, 0x02, + 0xdc, 0x0a, 0x01, 0x02, 0xe0, 0x0a, 0x01, 0x02, 0xe4, 0x0a, 0x01, 0x02, 0x10, 0x26, 0x02, 0x03, 0x18, 0x26, 0x02, 0x03, 0x20, 0x26, 0x02, 0x03, 0x28, 0x26, 0x02, 0x03, 0x68, 0x05, 0x03, 0x03, + 0x70, 0x05, 0x03, 0x03, 0x78, 0x05, 0x03, 0x03, 0x80, 0x1e, 0x04, 0x04, 0x90, 0x1e, 0x04, 0x04, 0xc0, 0x3f, 0x05, 0x05, 0xe0, 0x3f, 0x05, 0x05, 0x80, 0x17, 0x06, 0x05, 0x80, 0x0f, 0x08, 0x06, + 0x00, 0x34, 0x0e, 0x0a, 0xe8, 0x1a, 0x00, 0x03, 0xf0, 0x1a, 0x00, 0x03, 0xf8, 0x1a, 0x00, 0x03, 0xe8, 0x0a, 0x01, 0x02, 0xec, 0x0a, 0x01, 0x02, 0xf0, 0x0a, 0x01, 0x02, 0xf4, 0x0a, 0x01, 0x02, + 0xf8, 0x0a, 0x01, 0x02, 0xfc, 0x0a, 0x01, 0x02, 0x00, 0x0b, 0x01, 0x02, 0x30, 0x26, 0x02, 0x03, 0x38, 0x26, 0x02, 0x03, 0x40, 0x26, 0x02, 0x03, 0x48, 0x26, 0x02, 0x03, 0x80, 0x05, 0x03, 0x03, + 0x88, 0x05, 0x03, 0x03, 0x90, 0x05, 0x03, 0x03, 0xa0, 0x1e, 0x04, 0x04, 0xb0, 0x1e, 0x04, 0x04, 0x00, 0x00, 0x05, 0x04, 0x10, 0x00, 0x05, 0x04, 0xa0, 0x17, 0x06, 0x05, 0xc0, 0x0f, 0x08, 0x06, + 0x00, 0x38, 0x0e, 0x0a, 0x00, 0x1b, 0x00, 0x03, 0x08, 0x1b, 0x00, 0x03, 0x10, 0x1b, 0x00, 0x03, 0x04, 0x0b, 0x01, 0x02, 0x08, 0x0b, 0x01, 0x02, 0x0c, 0x0b, 0x01, 0x02, 0x10, 0x0b, 0x01, 0x02, + 0x14, 0x0b, 0x01, 0x02, 0x18, 0x0b, 0x01, 0x02, 0x1c, 0x0b, 0x01, 0x02, 0x50, 0x26, 0x02, 0x03, 0x58, 0x26, 0x02, 0x03, 0x60, 0x26, 0x02, 0x03, 0x68, 0x26, 0x02, 0x03, 0x98, 0x05, 0x03, 0x03, + 0xa0, 0x05, 0x03, 0x03, 0xa8, 0x05, 0x03, 0x03, 0xc0, 0x1e, 0x04, 0x04, 0xd0, 0x1e, 0x04, 0x04, 0x20, 0x00, 0x05, 0x04, 0x30, 0x00, 0x05, 0x04, 0xc0, 0x17, 0x06, 0x05, 0x00, 0x10, 0x08, 0x06, + 0x00, 0x3c, 0x0e, 0x0a, 0x18, 0x1b, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x03, 0x28, 0x1b, 0x00, 0x03, 0x20, 0x0b, 0x01, 0x02, 0x24, 0x0b, 0x01, 0x02, 0x28, 0x0b, 0x01, 0x02, 0x2c, 0x0b, 0x01, 0x02, + 0x30, 0x0b, 0x01, 0x02, 0x34, 0x0b, 0x01, 0x02, 0x38, 0x0b, 0x01, 0x02, 0x70, 0x26, 0x02, 0x03, 0x78, 0x26, 0x02, 0x03, 0x80, 0x26, 0x02, 0x03, 0x88, 0x26, 0x02, 0x03, 0xb0, 0x05, 0x03, 0x03, + 0xb8, 0x05, 0x03, 0x03, 0xc0, 0x05, 0x03, 0x03, 0xe0, 0x1e, 0x04, 0x04, 0xf0, 0x1e, 0x04, 0x04, 0x40, 0x00, 0x05, 0x04, 0x50, 0x00, 0x05, 0x04, 0xe0, 0x17, 0x06, 0x05, 0x40, 0x10, 0x08, 0x06, + 0x00, 0x00, 0x0e, 0x09, 0x30, 0x1b, 0x00, 0x03, 0x38, 0x1b, 0x00, 0x03, 0x40, 0x1b, 0x00, 0x03, 0x3c, 0x0b, 0x01, 0x02, 0x40, 0x0b, 0x01, 0x02, 0x44, 0x0b, 0x01, 0x02, 0x48, 0x0b, 0x01, 0x02, + 0x4c, 0x0b, 0x01, 0x02, 0x50, 0x0b, 0x01, 0x02, 0x54, 0x0b, 0x01, 0x02, 0x90, 0x26, 0x02, 0x03, 0x98, 0x26, 0x02, 0x03, 0xa0, 0x26, 0x02, 0x03, 0xa8, 0x26, 0x02, 0x03, 0xc8, 0x05, 0x03, 0x03, + 0xd0, 0x05, 0x03, 0x03, 0xd8, 0x05, 0x03, 0x03, 0x00, 0x1f, 0x04, 0x04, 0x10, 0x1f, 0x04, 0x04, 0x60, 0x00, 0x05, 0x04, 0x70, 0x00, 0x05, 0x04, 0x00, 0x18, 0x06, 0x05, 0x80, 0x10, 0x08, 0x06, + 0x00, 0x10, 0x0f, 0x0a, 0x48, 0x1b, 0x00, 0x03, 0x50, 0x1b, 0x00, 0x03, 0x58, 0x1b, 0x00, 0x03, 0x58, 0x0b, 0x01, 0x02, 0x5c, 0x0b, 0x01, 0x02, 0x60, 0x0b, 0x01, 0x02, 0x64, 0x0b, 0x01, 0x02, + 0x68, 0x0b, 0x01, 0x02, 0x6c, 0x0b, 0x01, 0x02, 0x70, 0x0b, 0x01, 0x02, 0xb0, 0x26, 0x02, 0x03, 0xb8, 0x26, 0x02, 0x03, 0xc0, 0x26, 0x02, 0x03, 0xc8, 0x26, 0x02, 0x03, 0xe0, 0x05, 0x03, 0x03, + 0xe8, 0x05, 0x03, 0x03, 0xf0, 0x05, 0x03, 0x03, 0x20, 0x1f, 0x04, 0x04, 0x30, 0x1f, 0x04, 0x04, 0x80, 0x00, 0x05, 0x04, 0x90, 0x00, 0x05, 0x04, 0x20, 0x18, 0x06, 0x05, 0xc0, 0x10, 0x08, 0x06, + 0x00, 0x14, 0x0f, 0x0a, 0x60, 0x1b, 0x00, 0x03, 0x68, 0x1b, 0x00, 0x03, 0x70, 0x1b, 0x00, 0x03, 0x74, 0x0b, 0x01, 0x02, 0x78, 0x0b, 0x01, 0x02, 0x7c, 0x0b, 0x01, 0x02, 0x80, 0x0b, 0x01, 0x02, + 0x84, 0x0b, 0x01, 0x02, 0x88, 0x0b, 0x01, 0x02, 0x8c, 0x0b, 0x01, 0x02, 0xd0, 0x26, 0x02, 0x03, 0xd8, 0x26, 0x02, 0x03, 0xe0, 0x26, 0x02, 0x03, 0xe8, 0x26, 0x02, 0x03, 0xf8, 0x05, 0x03, 0x03, + 0x00, 0x06, 0x03, 0x03, 0x08, 0x06, 0x03, 0x03, 0x40, 0x1f, 0x04, 0x04, 0x50, 0x1f, 0x04, 0x04, 0xa0, 0x00, 0x05, 0x04, 0xb0, 0x00, 0x05, 0x04, 0x40, 0x18, 0x06, 0x05, 0x00, 0x11, 0x08, 0x06, + 0x00, 0x30, 0x10, 0x0b, 0x78, 0x1b, 0x00, 0x03, 0x80, 0x1b, 0x00, 0x03, 0x88, 0x1b, 0x00, 0x03, 0x90, 0x0b, 0x01, 0x02, 0x94, 0x0b, 0x01, 0x02, 0x98, 0x0b, 0x01, 0x02, 0x9c, 0x0b, 0x01, 0x02, + 0xa0, 0x0b, 0x01, 0x02, 0xa4, 0x0b, 0x01, 0x02, 0xa8, 0x0b, 0x01, 0x02, 0xf0, 0x26, 0x02, 0x03, 0xf8, 0x26, 0x02, 0x03, 0x00, 0x27, 0x02, 0x03, 0x08, 0x27, 0x02, 0x03, 0x10, 0x06, 0x03, 0x03, + 0x18, 0x06, 0x03, 0x03, 0x20, 0x06, 0x03, 0x03, 0x60, 0x1f, 0x04, 0x04, 0x70, 0x1f, 0x04, 0x04, 0xc0, 0x00, 0x05, 0x04, 0xd0, 0x00, 0x05, 0x04, 0x60, 0x18, 0x06, 0x05, 0x40, 0x11, 0x08, 0x06, + 0x00, 0x38, 0x10, 0x0b, 0x90, 0x1b, 0x00, 0x03, 0x98, 0x1b, 0x00, 0x03, 0xa0, 0x1b, 0x00, 0x03, 0xac, 0x0b, 0x01, 0x02, 0xb0, 0x0b, 0x01, 0x02, 0xb4, 0x0b, 0x01, 0x02, 0xb8, 0x0b, 0x01, 0x02, + 0xbc, 0x0b, 0x01, 0x02, 0xc0, 0x0b, 0x01, 0x02, 0xc4, 0x0b, 0x01, 0x02, 0x10, 0x27, 0x02, 0x03, 0x18, 0x27, 0x02, 0x03, 0x20, 0x27, 0x02, 0x03, 0x28, 0x27, 0x02, 0x03, 0x28, 0x06, 0x03, 0x03, + 0x30, 0x06, 0x03, 0x03, 0x38, 0x06, 0x03, 0x03, 0x80, 0x1f, 0x04, 0x04, 0x90, 0x1f, 0x04, 0x04, 0xe0, 0x00, 0x05, 0x04, 0xf0, 0x00, 0x05, 0x04, 0x80, 0x18, 0x06, 0x05, 0x80, 0x11, 0x08, 0x06, + 0x00, 0x08, 0x11, 0x0b, 0xa8, 0x1b, 0x00, 0x03, 0xb0, 0x1b, 0x00, 0x03, 0xb8, 0x1b, 0x00, 0x03, 0xc8, 0x0b, 0x01, 0x02, 0xcc, 0x0b, 0x01, 0x02, 0xd0, 0x0b, 0x01, 0x02, 0xd4, 0x0b, 0x01, 0x02, + 0xd8, 0x0b, 0x01, 0x02, 0xdc, 0x0b, 0x01, 0x02, 0xe0, 0x0b, 0x01, 0x02, 0x30, 0x27, 0x02, 0x03, 0x38, 0x27, 0x02, 0x03, 0x40, 0x27, 0x02, 0x03, 0x48, 0x27, 0x02, 0x03, 0x40, 0x06, 0x03, 0x03, + 0x48, 0x06, 0x03, 0x03, 0x50, 0x06, 0x03, 0x03, 0xa0, 0x1f, 0x04, 0x04, 0xb0, 0x1f, 0x04, 0x04, 0x00, 0x01, 0x05, 0x04, 0x10, 0x01, 0x05, 0x04, 0xa0, 0x18, 0x06, 0x05, 0xc0, 0x11, 0x08, 0x06, + 0x00, 0x10, 0x11, 0x0b, 0xc0, 0x1b, 0x00, 0x03, 0xc8, 0x1b, 0x00, 0x03, 0xd0, 0x1b, 0x00, 0x03, 0xe4, 0x0b, 0x01, 0x02, 0xe8, 0x0b, 0x01, 0x02, 0xec, 0x0b, 0x01, 0x02, 0xf0, 0x0b, 0x01, 0x02, + 0xf4, 0x0b, 0x01, 0x02, 0xf8, 0x0b, 0x01, 0x02, 0xfc, 0x0b, 0x01, 0x02, 0x50, 0x27, 0x02, 0x03, 0x58, 0x27, 0x02, 0x03, 0x60, 0x27, 0x02, 0x03, 0x68, 0x27, 0x02, 0x03, 0x58, 0x06, 0x03, 0x03, + 0x60, 0x06, 0x03, 0x03, 0x68, 0x06, 0x03, 0x03, 0xc0, 0x1f, 0x04, 0x04, 0xd0, 0x1f, 0x04, 0x04, 0x20, 0x01, 0x05, 0x04, 0x30, 0x01, 0x05, 0x04, 0xc0, 0x18, 0x06, 0x05, 0x00, 0x12, 0x08, 0x06, + 0x00, 0x20, 0x12, 0x0c, 0xd8, 0x1b, 0x00, 0x03, 0xe0, 0x1b, 0x00, 0x03, 0xe8, 0x1b, 0x00, 0x03, 0x00, 0x0c, 0x01, 0x02, 0x04, 0x0c, 0x01, 0x02, 0x08, 0x0c, 0x01, 0x02, 0x0c, 0x0c, 0x01, 0x02, + 0x10, 0x0c, 0x01, 0x02, 0x14, 0x0c, 0x01, 0x02, 0x18, 0x0c, 0x01, 0x02, 0x70, 0x27, 0x02, 0x03, 0x78, 0x27, 0x02, 0x03, 0x80, 0x27, 0x02, 0x03, 0x88, 0x27, 0x02, 0x03, 0x70, 0x06, 0x03, 0x03, + 0x78, 0x06, 0x03, 0x03, 0x80, 0x06, 0x03, 0x03, 0xe0, 0x1f, 0x04, 0x04, 0xf0, 0x1f, 0x04, 0x04, 0x40, 0x01, 0x05, 0x04, 0x50, 0x01, 0x05, 0x04, 0xe0, 0x18, 0x06, 0x05, 0x40, 0x12, 0x08, 0x06, + 0x00, 0x20, 0x14, 0x0d, 0xf0, 0x1b, 0x00, 0x03, 0xf8, 0x1b, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x03, 0x1c, 0x0c, 0x01, 0x02, 0x20, 0x0c, 0x01, 0x02, 0x24, 0x0c, 0x01, 0x02, 0x28, 0x0c, 0x01, 0x02, + 0x2c, 0x0c, 0x01, 0x02, 0x30, 0x0c, 0x01, 0x02, 0x34, 0x0c, 0x01, 0x02, 0x90, 0x27, 0x02, 0x03, 0x98, 0x27, 0x02, 0x03, 0xa0, 0x27, 0x02, 0x03, 0xa8, 0x27, 0x02, 0x03, 0x88, 0x06, 0x03, 0x03, + 0x90, 0x06, 0x03, 0x03, 0x98, 0x06, 0x03, 0x03, 0x00, 0x20, 0x04, 0x04, 0x10, 0x20, 0x04, 0x04, 0x60, 0x01, 0x05, 0x04, 0x70, 0x01, 0x05, 0x04, 0x00, 0x39, 0x07, 0x06, 0x80, 0x12, 0x08, 0x06, + 0x08, 0x1c, 0x00, 0x03, 0x10, 0x1c, 0x00, 0x03, 0x18, 0x1c, 0x00, 0x03, 0x20, 0x1c, 0x00, 0x03, 0x38, 0x0c, 0x01, 0x02, 0x3c, 0x0c, 0x01, 0x02, 0x40, 0x0c, 0x01, 0x02, 0x44, 0x0c, 0x01, 0x02, + 0x48, 0x0c, 0x01, 0x02, 0x4c, 0x0c, 0x01, 0x02, 0x50, 0x0c, 0x01, 0x02, 0xb0, 0x27, 0x02, 0x03, 0xb8, 0x27, 0x02, 0x03, 0xc0, 0x27, 0x02, 0x03, 0xc8, 0x27, 0x02, 0x03, 0xa0, 0x06, 0x03, 0x03, + 0xa8, 0x06, 0x03, 0x03, 0xb0, 0x06, 0x03, 0x03, 0x20, 0x20, 0x04, 0x04, 0x30, 0x20, 0x04, 0x04, 0x80, 0x01, 0x05, 0x04, 0x90, 0x01, 0x05, 0x04, 0x40, 0x39, 0x07, 0x06, 0xc0, 0x12, 0x08, 0x06, + 0x28, 0x1c, 0x00, 0x03, 0x30, 0x1c, 0x00, 0x03, 0x38, 0x1c, 0x00, 0x03, 0x40, 0x1c, 0x00, 0x03, 0x54, 0x0c, 0x01, 0x02, 0x58, 0x0c, 0x01, 0x02, 0x5c, 0x0c, 0x01, 0x02, 0x60, 0x0c, 0x01, 0x02, + 0x64, 0x0c, 0x01, 0x02, 0x68, 0x0c, 0x01, 0x02, 0x6c, 0x0c, 0x01, 0x02, 0xd0, 0x27, 0x02, 0x03, 0xd8, 0x27, 0x02, 0x03, 0xe0, 0x27, 0x02, 0x03, 0xe8, 0x27, 0x02, 0x03, 0xb8, 0x06, 0x03, 0x03, + 0xc0, 0x06, 0x03, 0x03, 0xc8, 0x06, 0x03, 0x03, 0x40, 0x20, 0x04, 0x04, 0x50, 0x20, 0x04, 0x04, 0xa0, 0x01, 0x05, 0x04, 0xb0, 0x01, 0x05, 0x04, 0x80, 0x39, 0x07, 0x06, 0x00, 0x13, 0x08, 0x06, + 0x48, 0x1c, 0x00, 0x03, 0x50, 0x1c, 0x00, 0x03, 0x58, 0x1c, 0x00, 0x03, 0x60, 0x1c, 0x00, 0x03, 0x70, 0x0c, 0x01, 0x02, 0x74, 0x0c, 0x01, 0x02, 0x78, 0x0c, 0x01, 0x02, 0x7c, 0x0c, 0x01, 0x02, + 0x80, 0x0c, 0x01, 0x02, 0x84, 0x0c, 0x01, 0x02, 0x88, 0x0c, 0x01, 0x02, 0xf0, 0x27, 0x02, 0x03, 0xf8, 0x27, 0x02, 0x03, 0x00, 0x28, 0x02, 0x03, 0x08, 0x28, 0x02, 0x03, 0xd0, 0x06, 0x03, 0x03, + 0xd8, 0x06, 0x03, 0x03, 0xe0, 0x06, 0x03, 0x03, 0x60, 0x20, 0x04, 0x04, 0x70, 0x20, 0x04, 0x04, 0xc0, 0x01, 0x05, 0x04, 0xd0, 0x01, 0x05, 0x04, 0xc0, 0x39, 0x07, 0x06, 0x40, 0x13, 0x08, 0x06, + 0x68, 0x1c, 0x00, 0x03, 0x70, 0x1c, 0x00, 0x03, 0x78, 0x1c, 0x00, 0x03, 0x80, 0x1c, 0x00, 0x03, 0x8c, 0x0c, 0x01, 0x02, 0x90, 0x0c, 0x01, 0x02, 0x94, 0x0c, 0x01, 0x02, 0x98, 0x0c, 0x01, 0x02, + 0x9c, 0x0c, 0x01, 0x02, 0xa0, 0x0c, 0x01, 0x02, 0xa4, 0x0c, 0x01, 0x02, 0x10, 0x28, 0x02, 0x03, 0x18, 0x28, 0x02, 0x03, 0x20, 0x28, 0x02, 0x03, 0x28, 0x28, 0x02, 0x03, 0xe8, 0x06, 0x03, 0x03, + 0xf0, 0x06, 0x03, 0x03, 0xf8, 0x06, 0x03, 0x03, 0x80, 0x20, 0x04, 0x04, 0x90, 0x20, 0x04, 0x04, 0xe0, 0x01, 0x05, 0x04, 0xf0, 0x01, 0x05, 0x04, 0x00, 0x3a, 0x07, 0x06, 0x80, 0x13, 0x08, 0x06, + 0x88, 0x1c, 0x00, 0x03, 0x90, 0x1c, 0x00, 0x03, 0x98, 0x1c, 0x00, 0x03, 0xa0, 0x1c, 0x00, 0x03, 0xa8, 0x0c, 0x01, 0x02, 0xac, 0x0c, 0x01, 0x02, 0xb0, 0x0c, 0x01, 0x02, 0xb4, 0x0c, 0x01, 0x02, + 0xb8, 0x0c, 0x01, 0x02, 0xbc, 0x0c, 0x01, 0x02, 0xc0, 0x0c, 0x01, 0x02, 0x30, 0x28, 0x02, 0x03, 0x38, 0x28, 0x02, 0x03, 0x40, 0x28, 0x02, 0x03, 0x48, 0x28, 0x02, 0x03, 0x00, 0x07, 0x03, 0x03, + 0x08, 0x07, 0x03, 0x03, 0x10, 0x07, 0x03, 0x03, 0xa0, 0x20, 0x04, 0x04, 0xb0, 0x20, 0x04, 0x04, 0x00, 0x02, 0x05, 0x04, 0x00, 0x19, 0x06, 0x05, 0x40, 0x3a, 0x07, 0x06, 0xc0, 0x13, 0x08, 0x06, + 0xa8, 0x1c, 0x00, 0x03, 0xb0, 0x1c, 0x00, 0x03, 0xb8, 0x1c, 0x00, 0x03, 0xc0, 0x1c, 0x00, 0x03, 0xc4, 0x0c, 0x01, 0x02, 0xc8, 0x0c, 0x01, 0x02, 0xcc, 0x0c, 0x01, 0x02, 0xd0, 0x0c, 0x01, 0x02, + 0xd4, 0x0c, 0x01, 0x02, 0xd8, 0x0c, 0x01, 0x02, 0xdc, 0x0c, 0x01, 0x02, 0x50, 0x28, 0x02, 0x03, 0x58, 0x28, 0x02, 0x03, 0x60, 0x28, 0x02, 0x03, 0x68, 0x28, 0x02, 0x03, 0x18, 0x07, 0x03, 0x03, + 0x20, 0x07, 0x03, 0x03, 0x28, 0x07, 0x03, 0x03, 0xc0, 0x20, 0x04, 0x04, 0xd0, 0x20, 0x04, 0x04, 0x10, 0x02, 0x05, 0x04, 0x20, 0x19, 0x06, 0x05, 0x80, 0x3a, 0x07, 0x06, 0x00, 0x14, 0x08, 0x06, + 0xc8, 0x1c, 0x00, 0x03, 0xd0, 0x1c, 0x00, 0x03, 0xd8, 0x1c, 0x00, 0x03, 0xe0, 0x1c, 0x00, 0x03, 0xe0, 0x0c, 0x01, 0x02, 0xe4, 0x0c, 0x01, 0x02, 0xe8, 0x0c, 0x01, 0x02, 0xec, 0x0c, 0x01, 0x02, + 0xf0, 0x0c, 0x01, 0x02, 0xf4, 0x0c, 0x01, 0x02, 0xf8, 0x0c, 0x01, 0x02, 0x70, 0x28, 0x02, 0x03, 0x78, 0x28, 0x02, 0x03, 0x80, 0x28, 0x02, 0x03, 0x88, 0x28, 0x02, 0x03, 0x30, 0x07, 0x03, 0x03, + 0x38, 0x07, 0x03, 0x03, 0x40, 0x07, 0x03, 0x03, 0xe0, 0x20, 0x04, 0x04, 0xf0, 0x20, 0x04, 0x04, 0x20, 0x02, 0x05, 0x04, 0x40, 0x19, 0x06, 0x05, 0xc0, 0x3a, 0x07, 0x06, 0x00, 0x30, 0x09, 0x07, + 0xe8, 0x1c, 0x00, 0x03, 0xf0, 0x1c, 0x00, 0x03, 0xf8, 0x1c, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x03, 0xfc, 0x0c, 0x01, 0x02, 0x00, 0x0d, 0x01, 0x02, 0x04, 0x0d, 0x01, 0x02, 0x08, 0x0d, 0x01, 0x02, + 0x0c, 0x0d, 0x01, 0x02, 0x10, 0x0d, 0x01, 0x02, 0x14, 0x0d, 0x01, 0x02, 0x90, 0x28, 0x02, 0x03, 0x98, 0x28, 0x02, 0x03, 0xa0, 0x28, 0x02, 0x03, 0xa8, 0x28, 0x02, 0x03, 0x48, 0x07, 0x03, 0x03, + 0x50, 0x07, 0x03, 0x03, 0x58, 0x07, 0x03, 0x03, 0x00, 0x21, 0x04, 0x04, 0x10, 0x21, 0x04, 0x04, 0x30, 0x02, 0x05, 0x04, 0x60, 0x19, 0x06, 0x05, 0x00, 0x3b, 0x07, 0x06, 0x80, 0x30, 0x09, 0x07, + 0x08, 0x1d, 0x00, 0x03, 0x10, 0x1d, 0x00, 0x03, 0x18, 0x1d, 0x00, 0x03, 0x20, 0x1d, 0x00, 0x03, 0x18, 0x0d, 0x01, 0x02, 0x1c, 0x0d, 0x01, 0x02, 0x20, 0x0d, 0x01, 0x02, 0x24, 0x0d, 0x01, 0x02, + 0x28, 0x0d, 0x01, 0x02, 0x2c, 0x0d, 0x01, 0x02, 0x30, 0x0d, 0x01, 0x02, 0xb0, 0x28, 0x02, 0x03, 0xb8, 0x28, 0x02, 0x03, 0xc0, 0x28, 0x02, 0x03, 0xc8, 0x28, 0x02, 0x03, 0x60, 0x07, 0x03, 0x03, + 0x68, 0x07, 0x03, 0x03, 0x70, 0x07, 0x03, 0x03, 0x20, 0x21, 0x04, 0x04, 0x30, 0x21, 0x04, 0x04, 0x40, 0x02, 0x05, 0x04, 0x80, 0x19, 0x06, 0x05, 0x40, 0x3b, 0x07, 0x06, 0x00, 0x31, 0x09, 0x07, + 0x28, 0x1d, 0x00, 0x03, 0x30, 0x1d, 0x00, 0x03, 0x38, 0x1d, 0x00, 0x03, 0x40, 0x1d, 0x00, 0x03, 0x34, 0x0d, 0x01, 0x02, 0x38, 0x0d, 0x01, 0x02, 0x3c, 0x0d, 0x01, 0x02, 0x40, 0x0d, 0x01, 0x02, + 0x44, 0x0d, 0x01, 0x02, 0x48, 0x0d, 0x01, 0x02, 0x4c, 0x0d, 0x01, 0x02, 0xd0, 0x28, 0x02, 0x03, 0xd8, 0x28, 0x02, 0x03, 0xe0, 0x28, 0x02, 0x03, 0xe8, 0x28, 0x02, 0x03, 0x78, 0x07, 0x03, 0x03, + 0x80, 0x07, 0x03, 0x03, 0x88, 0x07, 0x03, 0x03, 0x40, 0x21, 0x04, 0x04, 0x50, 0x21, 0x04, 0x04, 0x50, 0x02, 0x05, 0x04, 0xa0, 0x19, 0x06, 0x05, 0x80, 0x3b, 0x07, 0x06, 0x80, 0x31, 0x09, 0x07, + 0x48, 0x1d, 0x00, 0x03, 0x50, 0x1d, 0x00, 0x03, 0x58, 0x1d, 0x00, 0x03, 0x60, 0x1d, 0x00, 0x03, 0x50, 0x0d, 0x01, 0x02, 0x54, 0x0d, 0x01, 0x02, 0x58, 0x0d, 0x01, 0x02, 0x5c, 0x0d, 0x01, 0x02, + 0x60, 0x0d, 0x01, 0x02, 0x64, 0x0d, 0x01, 0x02, 0x68, 0x0d, 0x01, 0x02, 0xf0, 0x28, 0x02, 0x03, 0xf8, 0x28, 0x02, 0x03, 0x00, 0x29, 0x02, 0x03, 0x08, 0x29, 0x02, 0x03, 0x90, 0x07, 0x03, 0x03, + 0x98, 0x07, 0x03, 0x03, 0xa0, 0x07, 0x03, 0x03, 0x60, 0x21, 0x04, 0x04, 0x70, 0x21, 0x04, 0x04, 0x60, 0x02, 0x05, 0x04, 0xc0, 0x19, 0x06, 0x05, 0xc0, 0x3b, 0x07, 0x06, 0x00, 0x32, 0x09, 0x07, + 0x68, 0x1d, 0x00, 0x03, 0x70, 0x1d, 0x00, 0x03, 0x78, 0x1d, 0x00, 0x03, 0x80, 0x1d, 0x00, 0x03, 0x6c, 0x0d, 0x01, 0x02, 0x70, 0x0d, 0x01, 0x02, 0x74, 0x0d, 0x01, 0x02, 0x78, 0x0d, 0x01, 0x02, + 0x7c, 0x0d, 0x01, 0x02, 0x80, 0x0d, 0x01, 0x02, 0x84, 0x0d, 0x01, 0x02, 0x10, 0x29, 0x02, 0x03, 0x18, 0x29, 0x02, 0x03, 0x20, 0x29, 0x02, 0x03, 0x28, 0x29, 0x02, 0x03, 0xa8, 0x07, 0x03, 0x03, + 0xb0, 0x07, 0x03, 0x03, 0xb8, 0x07, 0x03, 0x03, 0x80, 0x21, 0x04, 0x04, 0x90, 0x21, 0x04, 0x04, 0x70, 0x02, 0x05, 0x04, 0xe0, 0x19, 0x06, 0x05, 0x00, 0x3c, 0x07, 0x06, 0x80, 0x32, 0x09, 0x07, + 0x88, 0x1d, 0x00, 0x03, 0x90, 0x1d, 0x00, 0x03, 0x98, 0x1d, 0x00, 0x03, 0xa0, 0x1d, 0x00, 0x03, 0x88, 0x0d, 0x01, 0x02, 0x8c, 0x0d, 0x01, 0x02, 0x90, 0x0d, 0x01, 0x02, 0x94, 0x0d, 0x01, 0x02, + 0x98, 0x0d, 0x01, 0x02, 0x9c, 0x0d, 0x01, 0x02, 0xa0, 0x0d, 0x01, 0x02, 0x30, 0x29, 0x02, 0x03, 0x38, 0x29, 0x02, 0x03, 0x40, 0x29, 0x02, 0x03, 0x48, 0x29, 0x02, 0x03, 0xc0, 0x07, 0x03, 0x03, + 0xc8, 0x07, 0x03, 0x03, 0xd0, 0x07, 0x03, 0x03, 0xa0, 0x21, 0x04, 0x04, 0xb0, 0x21, 0x04, 0x04, 0x80, 0x02, 0x05, 0x04, 0x00, 0x1a, 0x06, 0x05, 0x40, 0x3c, 0x07, 0x06, 0x00, 0x33, 0x09, 0x07, + 0xa8, 0x1d, 0x00, 0x03, 0xb0, 0x1d, 0x00, 0x03, 0xb8, 0x1d, 0x00, 0x03, 0xc0, 0x1d, 0x00, 0x03, 0xa4, 0x0d, 0x01, 0x02, 0xa8, 0x0d, 0x01, 0x02, 0xac, 0x0d, 0x01, 0x02, 0xb0, 0x0d, 0x01, 0x02, + 0xb4, 0x0d, 0x01, 0x02, 0xb8, 0x0d, 0x01, 0x02, 0xbc, 0x0d, 0x01, 0x02, 0x50, 0x29, 0x02, 0x03, 0x58, 0x29, 0x02, 0x03, 0x60, 0x29, 0x02, 0x03, 0x68, 0x29, 0x02, 0x03, 0xd8, 0x07, 0x03, 0x03, + 0xe0, 0x07, 0x03, 0x03, 0xe8, 0x07, 0x03, 0x03, 0xc0, 0x21, 0x04, 0x04, 0xd0, 0x21, 0x04, 0x04, 0x90, 0x02, 0x05, 0x04, 0x20, 0x1a, 0x06, 0x05, 0x80, 0x3c, 0x07, 0x06, 0x80, 0x33, 0x09, 0x07, + 0xc8, 0x1d, 0x00, 0x03, 0xd0, 0x1d, 0x00, 0x03, 0xd8, 0x1d, 0x00, 0x03, 0xe0, 0x1d, 0x00, 0x03, 0xc0, 0x0d, 0x01, 0x02, 0xc4, 0x0d, 0x01, 0x02, 0xc8, 0x0d, 0x01, 0x02, 0xcc, 0x0d, 0x01, 0x02, + 0xd0, 0x0d, 0x01, 0x02, 0xd4, 0x0d, 0x01, 0x02, 0xd8, 0x0d, 0x01, 0x02, 0x70, 0x29, 0x02, 0x03, 0x78, 0x29, 0x02, 0x03, 0x80, 0x29, 0x02, 0x03, 0x88, 0x29, 0x02, 0x03, 0xf0, 0x07, 0x03, 0x03, + 0xf8, 0x07, 0x03, 0x03, 0x00, 0x08, 0x03, 0x03, 0xe0, 0x21, 0x04, 0x04, 0xf0, 0x21, 0x04, 0x04, 0xa0, 0x02, 0x05, 0x04, 0x40, 0x1a, 0x06, 0x05, 0xc0, 0x3c, 0x07, 0x06, 0x00, 0x34, 0x09, 0x07, + 0xe8, 0x1d, 0x00, 0x03, 0xf0, 0x1d, 0x00, 0x03, 0xf8, 0x1d, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x03, 0xdc, 0x0d, 0x01, 0x02, 0xe0, 0x0d, 0x01, 0x02, 0xe4, 0x0d, 0x01, 0x02, 0xe8, 0x0d, 0x01, 0x02, + 0xec, 0x0d, 0x01, 0x02, 0xf0, 0x0d, 0x01, 0x02, 0xf4, 0x0d, 0x01, 0x02, 0x90, 0x29, 0x02, 0x03, 0x98, 0x29, 0x02, 0x03, 0xa0, 0x29, 0x02, 0x03, 0xa8, 0x29, 0x02, 0x03, 0x08, 0x08, 0x03, 0x03, + 0x10, 0x08, 0x03, 0x03, 0x18, 0x08, 0x03, 0x03, 0x00, 0x22, 0x04, 0x04, 0x10, 0x22, 0x04, 0x04, 0xb0, 0x02, 0x05, 0x04, 0x60, 0x1a, 0x06, 0x05, 0x00, 0x3d, 0x07, 0x06, 0x80, 0x34, 0x09, 0x07, + 0x08, 0x1e, 0x00, 0x03, 0x10, 0x1e, 0x00, 0x03, 0x18, 0x1e, 0x00, 0x03, 0x20, 0x1e, 0x00, 0x03, 0xf8, 0x0d, 0x01, 0x02, 0xfc, 0x0d, 0x01, 0x02, 0x00, 0x0e, 0x01, 0x02, 0x04, 0x0e, 0x01, 0x02, + 0x08, 0x0e, 0x01, 0x02, 0x0c, 0x0e, 0x01, 0x02, 0x10, 0x0e, 0x01, 0x02, 0xb0, 0x29, 0x02, 0x03, 0xb8, 0x29, 0x02, 0x03, 0xc0, 0x29, 0x02, 0x03, 0xc8, 0x29, 0x02, 0x03, 0x20, 0x08, 0x03, 0x03, + 0x28, 0x08, 0x03, 0x03, 0x30, 0x08, 0x03, 0x03, 0x20, 0x22, 0x04, 0x04, 0x30, 0x22, 0x04, 0x04, 0xc0, 0x02, 0x05, 0x04, 0x80, 0x1a, 0x06, 0x05, 0x40, 0x3d, 0x07, 0x06, 0x00, 0x35, 0x09, 0x07, + 0x28, 0x1e, 0x00, 0x03, 0x30, 0x1e, 0x00, 0x03, 0x38, 0x1e, 0x00, 0x03, 0x40, 0x1e, 0x00, 0x03, 0x14, 0x0e, 0x01, 0x02, 0x18, 0x0e, 0x01, 0x02, 0x1c, 0x0e, 0x01, 0x02, 0x20, 0x0e, 0x01, 0x02, + 0x24, 0x0e, 0x01, 0x02, 0x28, 0x0e, 0x01, 0x02, 0x2c, 0x0e, 0x01, 0x02, 0xd0, 0x29, 0x02, 0x03, 0xd8, 0x29, 0x02, 0x03, 0xe0, 0x29, 0x02, 0x03, 0xe8, 0x29, 0x02, 0x03, 0x38, 0x08, 0x03, 0x03, + 0x40, 0x08, 0x03, 0x03, 0x48, 0x08, 0x03, 0x03, 0x40, 0x22, 0x04, 0x04, 0x50, 0x22, 0x04, 0x04, 0xd0, 0x02, 0x05, 0x04, 0xa0, 0x1a, 0x06, 0x05, 0x80, 0x3d, 0x07, 0x06, 0x80, 0x35, 0x09, 0x07, + 0x48, 0x1e, 0x00, 0x03, 0x50, 0x1e, 0x00, 0x03, 0x58, 0x1e, 0x00, 0x03, 0x60, 0x1e, 0x00, 0x03, 0x30, 0x0e, 0x01, 0x02, 0x34, 0x0e, 0x01, 0x02, 0x38, 0x0e, 0x01, 0x02, 0x3c, 0x0e, 0x01, 0x02, + 0x40, 0x0e, 0x01, 0x02, 0x44, 0x0e, 0x01, 0x02, 0x48, 0x0e, 0x01, 0x02, 0xf0, 0x29, 0x02, 0x03, 0xf8, 0x29, 0x02, 0x03, 0x00, 0x2a, 0x02, 0x03, 0x08, 0x2a, 0x02, 0x03, 0x50, 0x08, 0x03, 0x03, + 0x58, 0x08, 0x03, 0x03, 0x60, 0x08, 0x03, 0x03, 0x60, 0x22, 0x04, 0x04, 0x70, 0x22, 0x04, 0x04, 0xe0, 0x02, 0x05, 0x04, 0xc0, 0x1a, 0x06, 0x05, 0xc0, 0x3d, 0x07, 0x06, 0x00, 0x36, 0x09, 0x07, + 0x68, 0x1e, 0x00, 0x03, 0x70, 0x1e, 0x00, 0x03, 0x78, 0x1e, 0x00, 0x03, 0x80, 0x1e, 0x00, 0x03, 0x4c, 0x0e, 0x01, 0x02, 0x50, 0x0e, 0x01, 0x02, 0x54, 0x0e, 0x01, 0x02, 0x58, 0x0e, 0x01, 0x02, + 0x5c, 0x0e, 0x01, 0x02, 0x60, 0x0e, 0x01, 0x02, 0x64, 0x0e, 0x01, 0x02, 0x10, 0x2a, 0x02, 0x03, 0x18, 0x2a, 0x02, 0x03, 0x20, 0x2a, 0x02, 0x03, 0x28, 0x2a, 0x02, 0x03, 0x68, 0x08, 0x03, 0x03, + 0x70, 0x08, 0x03, 0x03, 0x78, 0x08, 0x03, 0x03, 0x80, 0x22, 0x04, 0x04, 0x90, 0x22, 0x04, 0x04, 0xf0, 0x02, 0x05, 0x04, 0xe0, 0x1a, 0x06, 0x05, 0x00, 0x3e, 0x07, 0x06, 0x80, 0x36, 0x09, 0x07, + 0x88, 0x1e, 0x00, 0x03, 0x90, 0x1e, 0x00, 0x03, 0x98, 0x1e, 0x00, 0x03, 0xa0, 0x1e, 0x00, 0x03, 0x68, 0x0e, 0x01, 0x02, 0x6c, 0x0e, 0x01, 0x02, 0x70, 0x0e, 0x01, 0x02, 0x74, 0x0e, 0x01, 0x02, + 0x78, 0x0e, 0x01, 0x02, 0x7c, 0x0e, 0x01, 0x02, 0x80, 0x0e, 0x01, 0x02, 0x30, 0x2a, 0x02, 0x03, 0x38, 0x2a, 0x02, 0x03, 0x40, 0x2a, 0x02, 0x03, 0x48, 0x2a, 0x02, 0x03, 0x80, 0x08, 0x03, 0x03, + 0x88, 0x08, 0x03, 0x03, 0x90, 0x08, 0x03, 0x03, 0xa0, 0x22, 0x04, 0x04, 0xb0, 0x22, 0x04, 0x04, 0x00, 0x03, 0x05, 0x04, 0x00, 0x1b, 0x06, 0x05, 0x40, 0x3e, 0x07, 0x06, 0x00, 0x37, 0x09, 0x07, + 0xa8, 0x1e, 0x00, 0x03, 0xb0, 0x1e, 0x00, 0x03, 0xb8, 0x1e, 0x00, 0x03, 0xc0, 0x1e, 0x00, 0x03, 0x84, 0x0e, 0x01, 0x02, 0x88, 0x0e, 0x01, 0x02, 0x8c, 0x0e, 0x01, 0x02, 0x90, 0x0e, 0x01, 0x02, + 0x94, 0x0e, 0x01, 0x02, 0x98, 0x0e, 0x01, 0x02, 0x9c, 0x0e, 0x01, 0x02, 0x50, 0x2a, 0x02, 0x03, 0x58, 0x2a, 0x02, 0x03, 0x60, 0x2a, 0x02, 0x03, 0x68, 0x2a, 0x02, 0x03, 0x98, 0x08, 0x03, 0x03, + 0xa0, 0x08, 0x03, 0x03, 0xa8, 0x08, 0x03, 0x03, 0xc0, 0x22, 0x04, 0x04, 0xd0, 0x22, 0x04, 0x04, 0x10, 0x03, 0x05, 0x04, 0x20, 0x1b, 0x06, 0x05, 0x80, 0x3e, 0x07, 0x06, 0x80, 0x37, 0x09, 0x07, + 0xc8, 0x1e, 0x00, 0x03, 0xd0, 0x1e, 0x00, 0x03, 0xd8, 0x1e, 0x00, 0x03, 0xe0, 0x1e, 0x00, 0x03, 0xa0, 0x0e, 0x01, 0x02, 0xa4, 0x0e, 0x01, 0x02, 0xa8, 0x0e, 0x01, 0x02, 0xac, 0x0e, 0x01, 0x02, + 0xb0, 0x0e, 0x01, 0x02, 0xb4, 0x0e, 0x01, 0x02, 0xb8, 0x0e, 0x01, 0x02, 0x70, 0x2a, 0x02, 0x03, 0x78, 0x2a, 0x02, 0x03, 0x80, 0x2a, 0x02, 0x03, 0x88, 0x2a, 0x02, 0x03, 0xb0, 0x08, 0x03, 0x03, + 0xb8, 0x08, 0x03, 0x03, 0xc0, 0x08, 0x03, 0x03, 0xe0, 0x22, 0x04, 0x04, 0xf0, 0x22, 0x04, 0x04, 0x20, 0x03, 0x05, 0x04, 0x40, 0x1b, 0x06, 0x05, 0xc0, 0x3e, 0x07, 0x06, 0x00, 0x38, 0x09, 0x07, + 0xe8, 0x1e, 0x00, 0x03, 0xf0, 0x1e, 0x00, 0x03, 0xf8, 0x1e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x03, 0xbc, 0x0e, 0x01, 0x02, 0xc0, 0x0e, 0x01, 0x02, 0xc4, 0x0e, 0x01, 0x02, 0xc8, 0x0e, 0x01, 0x02, + 0xcc, 0x0e, 0x01, 0x02, 0xd0, 0x0e, 0x01, 0x02, 0xd4, 0x0e, 0x01, 0x02, 0x90, 0x2a, 0x02, 0x03, 0x98, 0x2a, 0x02, 0x03, 0xa0, 0x2a, 0x02, 0x03, 0xa8, 0x2a, 0x02, 0x03, 0xc8, 0x08, 0x03, 0x03, + 0xd0, 0x08, 0x03, 0x03, 0xd8, 0x08, 0x03, 0x03, 0x00, 0x23, 0x04, 0x04, 0x10, 0x23, 0x04, 0x04, 0x30, 0x03, 0x05, 0x04, 0x60, 0x1b, 0x06, 0x05, 0x00, 0x3f, 0x07, 0x06, 0x80, 0x38, 0x09, 0x07, + 0x08, 0x1f, 0x00, 0x03, 0x10, 0x1f, 0x00, 0x03, 0x18, 0x1f, 0x00, 0x03, 0x20, 0x1f, 0x00, 0x03, 0xd8, 0x0e, 0x01, 0x02, 0xdc, 0x0e, 0x01, 0x02, 0xe0, 0x0e, 0x01, 0x02, 0xe4, 0x0e, 0x01, 0x02, + 0xe8, 0x0e, 0x01, 0x02, 0xec, 0x0e, 0x01, 0x02, 0xf0, 0x0e, 0x01, 0x02, 0xb0, 0x2a, 0x02, 0x03, 0xb8, 0x2a, 0x02, 0x03, 0xc0, 0x2a, 0x02, 0x03, 0xc8, 0x2a, 0x02, 0x03, 0xe0, 0x08, 0x03, 0x03, + 0xe8, 0x08, 0x03, 0x03, 0xf0, 0x08, 0x03, 0x03, 0x20, 0x23, 0x04, 0x04, 0x30, 0x23, 0x04, 0x04, 0x40, 0x03, 0x05, 0x04, 0x80, 0x1b, 0x06, 0x05, 0x40, 0x3f, 0x07, 0x06, 0x00, 0x39, 0x09, 0x07, + 0x28, 0x1f, 0x00, 0x03, 0x30, 0x1f, 0x00, 0x03, 0x38, 0x1f, 0x00, 0x03, 0x40, 0x1f, 0x00, 0x03, 0xf4, 0x0e, 0x01, 0x02, 0xf8, 0x0e, 0x01, 0x02, 0xfc, 0x0e, 0x01, 0x02, 0x00, 0x0f, 0x01, 0x02, + 0x04, 0x0f, 0x01, 0x02, 0x08, 0x0f, 0x01, 0x02, 0xd0, 0x2a, 0x02, 0x03, 0xd8, 0x2a, 0x02, 0x03, 0xe0, 0x2a, 0x02, 0x03, 0xe8, 0x2a, 0x02, 0x03, 0xf0, 0x2a, 0x02, 0x03, 0xf8, 0x08, 0x03, 0x03, + 0x00, 0x09, 0x03, 0x03, 0x08, 0x09, 0x03, 0x03, 0x40, 0x23, 0x04, 0x04, 0x50, 0x23, 0x04, 0x04, 0x50, 0x03, 0x05, 0x04, 0xa0, 0x1b, 0x06, 0x05, 0x80, 0x3f, 0x07, 0x06, 0x80, 0x39, 0x09, 0x07, + 0x48, 0x1f, 0x00, 0x03, 0x50, 0x1f, 0x00, 0x03, 0x58, 0x1f, 0x00, 0x03, 0x60, 0x1f, 0x00, 0x03, 0x0c, 0x0f, 0x01, 0x02, 0x10, 0x0f, 0x01, 0x02, 0x14, 0x0f, 0x01, 0x02, 0x18, 0x0f, 0x01, 0x02, + 0x1c, 0x0f, 0x01, 0x02, 0x20, 0x0f, 0x01, 0x02, 0xf8, 0x2a, 0x02, 0x03, 0x00, 0x2b, 0x02, 0x03, 0x08, 0x2b, 0x02, 0x03, 0x10, 0x2b, 0x02, 0x03, 0x18, 0x2b, 0x02, 0x03, 0x10, 0x09, 0x03, 0x03, + 0x18, 0x09, 0x03, 0x03, 0x20, 0x09, 0x03, 0x03, 0x60, 0x23, 0x04, 0x04, 0x70, 0x23, 0x04, 0x04, 0x60, 0x03, 0x05, 0x04, 0xc0, 0x1b, 0x06, 0x05, 0xc0, 0x3f, 0x07, 0x06, 0x00, 0x3a, 0x09, 0x07, + 0x68, 0x1f, 0x00, 0x03, 0x70, 0x1f, 0x00, 0x03, 0x78, 0x1f, 0x00, 0x03, 0x80, 0x1f, 0x00, 0x03, 0x24, 0x0f, 0x01, 0x02, 0x28, 0x0f, 0x01, 0x02, 0x2c, 0x0f, 0x01, 0x02, 0x30, 0x0f, 0x01, 0x02, + 0x34, 0x0f, 0x01, 0x02, 0x38, 0x0f, 0x01, 0x02, 0x20, 0x2b, 0x02, 0x03, 0x28, 0x2b, 0x02, 0x03, 0x30, 0x2b, 0x02, 0x03, 0x38, 0x2b, 0x02, 0x03, 0x40, 0x2b, 0x02, 0x03, 0x28, 0x09, 0x03, 0x03, + 0x30, 0x09, 0x03, 0x03, 0x38, 0x09, 0x03, 0x03, 0x80, 0x23, 0x04, 0x04, 0x90, 0x23, 0x04, 0x04, 0x70, 0x03, 0x05, 0x04, 0xe0, 0x1b, 0x06, 0x05, 0x00, 0x00, 0x07, 0x05, 0x80, 0x3a, 0x09, 0x07, + 0x88, 0x1f, 0x00, 0x03, 0x90, 0x1f, 0x00, 0x03, 0x98, 0x1f, 0x00, 0x03, 0xa0, 0x1f, 0x00, 0x03, 0x3c, 0x0f, 0x01, 0x02, 0x40, 0x0f, 0x01, 0x02, 0x44, 0x0f, 0x01, 0x02, 0x48, 0x0f, 0x01, 0x02, + 0x4c, 0x0f, 0x01, 0x02, 0x50, 0x0f, 0x01, 0x02, 0x48, 0x2b, 0x02, 0x03, 0x50, 0x2b, 0x02, 0x03, 0x58, 0x2b, 0x02, 0x03, 0x60, 0x2b, 0x02, 0x03, 0x68, 0x2b, 0x02, 0x03, 0x40, 0x09, 0x03, 0x03, + 0x48, 0x09, 0x03, 0x03, 0x50, 0x09, 0x03, 0x03, 0xa0, 0x23, 0x04, 0x04, 0xb0, 0x23, 0x04, 0x04, 0x80, 0x03, 0x05, 0x04, 0x00, 0x1c, 0x06, 0x05, 0x20, 0x00, 0x07, 0x05, 0x00, 0x3b, 0x09, 0x07, + 0xa8, 0x1f, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x03, 0xb8, 0x1f, 0x00, 0x03, 0xc0, 0x1f, 0x00, 0x03, 0x54, 0x0f, 0x01, 0x02, 0x58, 0x0f, 0x01, 0x02, 0x5c, 0x0f, 0x01, 0x02, 0x60, 0x0f, 0x01, 0x02, + 0x64, 0x0f, 0x01, 0x02, 0x68, 0x0f, 0x01, 0x02, 0x70, 0x2b, 0x02, 0x03, 0x78, 0x2b, 0x02, 0x03, 0x80, 0x2b, 0x02, 0x03, 0x88, 0x2b, 0x02, 0x03, 0x90, 0x2b, 0x02, 0x03, 0x58, 0x09, 0x03, 0x03, + 0x60, 0x09, 0x03, 0x03, 0x68, 0x09, 0x03, 0x03, 0xc0, 0x23, 0x04, 0x04, 0xd0, 0x23, 0x04, 0x04, 0x90, 0x03, 0x05, 0x04, 0x20, 0x1c, 0x06, 0x05, 0x40, 0x00, 0x07, 0x05, 0x80, 0x3b, 0x09, 0x07, + 0xc8, 0x1f, 0x00, 0x03, 0xd0, 0x1f, 0x00, 0x03, 0xd8, 0x1f, 0x00, 0x03, 0xe0, 0x1f, 0x00, 0x03, 0x6c, 0x0f, 0x01, 0x02, 0x70, 0x0f, 0x01, 0x02, 0x74, 0x0f, 0x01, 0x02, 0x78, 0x0f, 0x01, 0x02, + 0x7c, 0x0f, 0x01, 0x02, 0x80, 0x0f, 0x01, 0x02, 0x98, 0x2b, 0x02, 0x03, 0xa0, 0x2b, 0x02, 0x03, 0xa8, 0x2b, 0x02, 0x03, 0xb0, 0x2b, 0x02, 0x03, 0xb8, 0x2b, 0x02, 0x03, 0x70, 0x09, 0x03, 0x03, + 0x78, 0x09, 0x03, 0x03, 0x80, 0x09, 0x03, 0x03, 0xe0, 0x23, 0x04, 0x04, 0xf0, 0x23, 0x04, 0x04, 0xa0, 0x03, 0x05, 0x04, 0x40, 0x1c, 0x06, 0x05, 0x60, 0x00, 0x07, 0x05, 0x80, 0x0c, 0x0a, 0x07, + 0xe8, 0x1f, 0x00, 0x03, 0xf0, 0x1f, 0x00, 0x03, 0xf8, 0x1f, 0x00, 0x03, 0x00, 0x20, 0x00, 0x03, 0x84, 0x0f, 0x01, 0x02, 0x88, 0x0f, 0x01, 0x02, 0x8c, 0x0f, 0x01, 0x02, 0x90, 0x0f, 0x01, 0x02, + 0x94, 0x0f, 0x01, 0x02, 0x98, 0x0f, 0x01, 0x02, 0xc0, 0x2b, 0x02, 0x03, 0xc8, 0x2b, 0x02, 0x03, 0xd0, 0x2b, 0x02, 0x03, 0xd8, 0x2b, 0x02, 0x03, 0xe0, 0x2b, 0x02, 0x03, 0x88, 0x09, 0x03, 0x03, + 0x90, 0x09, 0x03, 0x03, 0x98, 0x09, 0x03, 0x03, 0x00, 0x24, 0x04, 0x04, 0x10, 0x24, 0x04, 0x04, 0xb0, 0x03, 0x05, 0x04, 0x60, 0x1c, 0x06, 0x05, 0x80, 0x00, 0x07, 0x05, 0x00, 0x0d, 0x0a, 0x07, + 0x08, 0x20, 0x00, 0x03, 0x10, 0x20, 0x00, 0x03, 0x18, 0x20, 0x00, 0x03, 0x20, 0x20, 0x00, 0x03, 0x9c, 0x0f, 0x01, 0x02, 0xa0, 0x0f, 0x01, 0x02, 0xa4, 0x0f, 0x01, 0x02, 0xa8, 0x0f, 0x01, 0x02, + 0xac, 0x0f, 0x01, 0x02, 0xb0, 0x0f, 0x01, 0x02, 0xe8, 0x2b, 0x02, 0x03, 0xf0, 0x2b, 0x02, 0x03, 0xf8, 0x2b, 0x02, 0x03, 0x00, 0x2c, 0x02, 0x03, 0x08, 0x2c, 0x02, 0x03, 0xa0, 0x09, 0x03, 0x03, + 0xa8, 0x09, 0x03, 0x03, 0xb0, 0x09, 0x03, 0x03, 0x20, 0x24, 0x04, 0x04, 0x30, 0x24, 0x04, 0x04, 0xc0, 0x03, 0x05, 0x04, 0x80, 0x1c, 0x06, 0x05, 0xa0, 0x00, 0x07, 0x05, 0x80, 0x0d, 0x0a, 0x07, + 0x28, 0x20, 0x00, 0x03, 0x30, 0x20, 0x00, 0x03, 0x38, 0x20, 0x00, 0x03, 0x40, 0x20, 0x00, 0x03, 0xb4, 0x0f, 0x01, 0x02, 0xb8, 0x0f, 0x01, 0x02, 0xbc, 0x0f, 0x01, 0x02, 0xc0, 0x0f, 0x01, 0x02, + 0xc4, 0x0f, 0x01, 0x02, 0xc8, 0x0f, 0x01, 0x02, 0x10, 0x2c, 0x02, 0x03, 0x18, 0x2c, 0x02, 0x03, 0x20, 0x2c, 0x02, 0x03, 0x28, 0x2c, 0x02, 0x03, 0x30, 0x2c, 0x02, 0x03, 0xb8, 0x09, 0x03, 0x03, + 0xc0, 0x09, 0x03, 0x03, 0xc8, 0x09, 0x03, 0x03, 0x40, 0x24, 0x04, 0x04, 0x50, 0x24, 0x04, 0x04, 0xd0, 0x03, 0x05, 0x04, 0xa0, 0x1c, 0x06, 0x05, 0xc0, 0x00, 0x07, 0x05, 0x00, 0x0e, 0x0a, 0x07, + 0x48, 0x20, 0x00, 0x03, 0x50, 0x20, 0x00, 0x03, 0x58, 0x20, 0x00, 0x03, 0x60, 0x20, 0x00, 0x03, 0xcc, 0x0f, 0x01, 0x02, 0xd0, 0x0f, 0x01, 0x02, 0xd4, 0x0f, 0x01, 0x02, 0xd8, 0x0f, 0x01, 0x02, + 0xdc, 0x0f, 0x01, 0x02, 0xe0, 0x0f, 0x01, 0x02, 0x38, 0x2c, 0x02, 0x03, 0x40, 0x2c, 0x02, 0x03, 0x48, 0x2c, 0x02, 0x03, 0x50, 0x2c, 0x02, 0x03, 0x58, 0x2c, 0x02, 0x03, 0xd0, 0x09, 0x03, 0x03, + 0xd8, 0x09, 0x03, 0x03, 0xe0, 0x09, 0x03, 0x03, 0x60, 0x24, 0x04, 0x04, 0x70, 0x24, 0x04, 0x04, 0xe0, 0x03, 0x05, 0x04, 0xc0, 0x1c, 0x06, 0x05, 0xe0, 0x00, 0x07, 0x05, 0x80, 0x0e, 0x0a, 0x07, + 0x68, 0x20, 0x00, 0x03, 0x70, 0x20, 0x00, 0x03, 0x78, 0x20, 0x00, 0x03, 0x80, 0x20, 0x00, 0x03, 0xe4, 0x0f, 0x01, 0x02, 0xe8, 0x0f, 0x01, 0x02, 0xec, 0x0f, 0x01, 0x02, 0xf0, 0x0f, 0x01, 0x02, + 0xf4, 0x0f, 0x01, 0x02, 0xf8, 0x0f, 0x01, 0x02, 0x60, 0x2c, 0x02, 0x03, 0x68, 0x2c, 0x02, 0x03, 0x70, 0x2c, 0x02, 0x03, 0x78, 0x2c, 0x02, 0x03, 0x80, 0x2c, 0x02, 0x03, 0xe8, 0x09, 0x03, 0x03, + 0xf0, 0x09, 0x03, 0x03, 0xf8, 0x09, 0x03, 0x03, 0x80, 0x24, 0x04, 0x04, 0x90, 0x24, 0x04, 0x04, 0xf0, 0x03, 0x05, 0x04, 0xe0, 0x1c, 0x06, 0x05, 0x00, 0x01, 0x07, 0x05, 0x00, 0x0f, 0x0a, 0x07, + 0x88, 0x20, 0x00, 0x03, 0x90, 0x20, 0x00, 0x03, 0x98, 0x20, 0x00, 0x03, 0xa0, 0x20, 0x00, 0x03, 0xfc, 0x0f, 0x01, 0x02, 0x00, 0x10, 0x01, 0x02, 0x04, 0x10, 0x01, 0x02, 0x08, 0x10, 0x01, 0x02, + 0x0c, 0x10, 0x01, 0x02, 0x10, 0x10, 0x01, 0x02, 0x88, 0x2c, 0x02, 0x03, 0x90, 0x2c, 0x02, 0x03, 0x98, 0x2c, 0x02, 0x03, 0xa0, 0x2c, 0x02, 0x03, 0xa8, 0x2c, 0x02, 0x03, 0x00, 0x0a, 0x03, 0x03, + 0x08, 0x0a, 0x03, 0x03, 0x10, 0x0a, 0x03, 0x03, 0xa0, 0x24, 0x04, 0x04, 0xb0, 0x24, 0x04, 0x04, 0x00, 0x04, 0x05, 0x04, 0x00, 0x1d, 0x06, 0x05, 0x20, 0x01, 0x07, 0x05, 0x80, 0x0f, 0x0a, 0x07, + 0xa8, 0x20, 0x00, 0x03, 0xb0, 0x20, 0x00, 0x03, 0xb8, 0x20, 0x00, 0x03, 0xc0, 0x20, 0x00, 0x03, 0x14, 0x10, 0x01, 0x02, 0x18, 0x10, 0x01, 0x02, 0x1c, 0x10, 0x01, 0x02, 0x20, 0x10, 0x01, 0x02, + 0x24, 0x10, 0x01, 0x02, 0x28, 0x10, 0x01, 0x02, 0xb0, 0x2c, 0x02, 0x03, 0xb8, 0x2c, 0x02, 0x03, 0xc0, 0x2c, 0x02, 0x03, 0xc8, 0x2c, 0x02, 0x03, 0xd0, 0x2c, 0x02, 0x03, 0x18, 0x0a, 0x03, 0x03, + 0x20, 0x0a, 0x03, 0x03, 0x28, 0x0a, 0x03, 0x03, 0xc0, 0x24, 0x04, 0x04, 0xd0, 0x24, 0x04, 0x04, 0x10, 0x04, 0x05, 0x04, 0x20, 0x1d, 0x06, 0x05, 0x40, 0x01, 0x07, 0x05, 0x00, 0x10, 0x0a, 0x07, + 0xc8, 0x20, 0x00, 0x03, 0xd0, 0x20, 0x00, 0x03, 0xd8, 0x20, 0x00, 0x03, 0xe0, 0x20, 0x00, 0x03, 0x2c, 0x10, 0x01, 0x02, 0x30, 0x10, 0x01, 0x02, 0x34, 0x10, 0x01, 0x02, 0x38, 0x10, 0x01, 0x02, + 0x3c, 0x10, 0x01, 0x02, 0x40, 0x10, 0x01, 0x02, 0xd8, 0x2c, 0x02, 0x03, 0xe0, 0x2c, 0x02, 0x03, 0xe8, 0x2c, 0x02, 0x03, 0xf0, 0x2c, 0x02, 0x03, 0xf8, 0x2c, 0x02, 0x03, 0x30, 0x0a, 0x03, 0x03, + 0x38, 0x0a, 0x03, 0x03, 0x40, 0x0a, 0x03, 0x03, 0xe0, 0x24, 0x04, 0x04, 0xf0, 0x24, 0x04, 0x04, 0x20, 0x04, 0x05, 0x04, 0x40, 0x1d, 0x06, 0x05, 0x60, 0x01, 0x07, 0x05, 0x80, 0x10, 0x0a, 0x07, + 0xe8, 0x20, 0x00, 0x03, 0xf0, 0x20, 0x00, 0x03, 0xf8, 0x20, 0x00, 0x03, 0x00, 0x21, 0x00, 0x03, 0x44, 0x10, 0x01, 0x02, 0x48, 0x10, 0x01, 0x02, 0x4c, 0x10, 0x01, 0x02, 0x50, 0x10, 0x01, 0x02, + 0x54, 0x10, 0x01, 0x02, 0x58, 0x10, 0x01, 0x02, 0x00, 0x2d, 0x02, 0x03, 0x08, 0x2d, 0x02, 0x03, 0x10, 0x2d, 0x02, 0x03, 0x18, 0x2d, 0x02, 0x03, 0x20, 0x2d, 0x02, 0x03, 0x48, 0x0a, 0x03, 0x03, + 0x50, 0x0a, 0x03, 0x03, 0x58, 0x0a, 0x03, 0x03, 0x00, 0x25, 0x04, 0x04, 0x10, 0x25, 0x04, 0x04, 0x30, 0x04, 0x05, 0x04, 0x60, 0x1d, 0x06, 0x05, 0x80, 0x01, 0x07, 0x05, 0x00, 0x11, 0x0a, 0x07, + 0x08, 0x21, 0x00, 0x03, 0x10, 0x21, 0x00, 0x03, 0x18, 0x21, 0x00, 0x03, 0x20, 0x21, 0x00, 0x03, 0x5c, 0x10, 0x01, 0x02, 0x60, 0x10, 0x01, 0x02, 0x64, 0x10, 0x01, 0x02, 0x68, 0x10, 0x01, 0x02, + 0x6c, 0x10, 0x01, 0x02, 0x70, 0x10, 0x01, 0x02, 0x28, 0x2d, 0x02, 0x03, 0x30, 0x2d, 0x02, 0x03, 0x38, 0x2d, 0x02, 0x03, 0x40, 0x2d, 0x02, 0x03, 0x48, 0x2d, 0x02, 0x03, 0x60, 0x0a, 0x03, 0x03, + 0x68, 0x0a, 0x03, 0x03, 0x70, 0x0a, 0x03, 0x03, 0x20, 0x25, 0x04, 0x04, 0x30, 0x25, 0x04, 0x04, 0x40, 0x04, 0x05, 0x04, 0x80, 0x1d, 0x06, 0x05, 0xa0, 0x01, 0x07, 0x05, 0x80, 0x11, 0x0a, 0x07, + 0x28, 0x21, 0x00, 0x03, 0x30, 0x21, 0x00, 0x03, 0x38, 0x21, 0x00, 0x03, 0x40, 0x21, 0x00, 0x03, 0x74, 0x10, 0x01, 0x02, 0x78, 0x10, 0x01, 0x02, 0x7c, 0x10, 0x01, 0x02, 0x80, 0x10, 0x01, 0x02, + 0x84, 0x10, 0x01, 0x02, 0x88, 0x10, 0x01, 0x02, 0x50, 0x2d, 0x02, 0x03, 0x58, 0x2d, 0x02, 0x03, 0x60, 0x2d, 0x02, 0x03, 0x68, 0x2d, 0x02, 0x03, 0x70, 0x2d, 0x02, 0x03, 0x78, 0x0a, 0x03, 0x03, + 0x80, 0x0a, 0x03, 0x03, 0x88, 0x0a, 0x03, 0x03, 0x40, 0x25, 0x04, 0x04, 0x50, 0x25, 0x04, 0x04, 0x50, 0x04, 0x05, 0x04, 0xa0, 0x1d, 0x06, 0x05, 0xc0, 0x01, 0x07, 0x05, 0x00, 0x12, 0x0a, 0x07, + 0x48, 0x21, 0x00, 0x03, 0x50, 0x21, 0x00, 0x03, 0x58, 0x21, 0x00, 0x03, 0x60, 0x21, 0x00, 0x03, 0x8c, 0x10, 0x01, 0x02, 0x90, 0x10, 0x01, 0x02, 0x94, 0x10, 0x01, 0x02, 0x98, 0x10, 0x01, 0x02, + 0x9c, 0x10, 0x01, 0x02, 0xa0, 0x10, 0x01, 0x02, 0x78, 0x2d, 0x02, 0x03, 0x80, 0x2d, 0x02, 0x03, 0x88, 0x2d, 0x02, 0x03, 0x90, 0x2d, 0x02, 0x03, 0x98, 0x2d, 0x02, 0x03, 0x90, 0x0a, 0x03, 0x03, + 0x98, 0x0a, 0x03, 0x03, 0xa0, 0x0a, 0x03, 0x03, 0x60, 0x25, 0x04, 0x04, 0x70, 0x25, 0x04, 0x04, 0x60, 0x04, 0x05, 0x04, 0xc0, 0x1d, 0x06, 0x05, 0xe0, 0x01, 0x07, 0x05, 0x80, 0x12, 0x0a, 0x07, + 0x68, 0x21, 0x00, 0x03, 0x70, 0x21, 0x00, 0x03, 0x78, 0x21, 0x00, 0x03, 0x80, 0x21, 0x00, 0x03, 0xa4, 0x10, 0x01, 0x02, 0xa8, 0x10, 0x01, 0x02, 0xac, 0x10, 0x01, 0x02, 0xb0, 0x10, 0x01, 0x02, + 0xb4, 0x10, 0x01, 0x02, 0xb8, 0x10, 0x01, 0x02, 0xa0, 0x2d, 0x02, 0x03, 0xa8, 0x2d, 0x02, 0x03, 0xb0, 0x2d, 0x02, 0x03, 0xb8, 0x2d, 0x02, 0x03, 0xc0, 0x2d, 0x02, 0x03, 0xa8, 0x0a, 0x03, 0x03, + 0xb0, 0x0a, 0x03, 0x03, 0xb8, 0x0a, 0x03, 0x03, 0x80, 0x25, 0x04, 0x04, 0x90, 0x25, 0x04, 0x04, 0x70, 0x04, 0x05, 0x04, 0xe0, 0x1d, 0x06, 0x05, 0x00, 0x02, 0x07, 0x05, 0x00, 0x13, 0x0a, 0x07, + 0x88, 0x21, 0x00, 0x03, 0x90, 0x21, 0x00, 0x03, 0x98, 0x21, 0x00, 0x03, 0xa0, 0x21, 0x00, 0x03, 0xbc, 0x10, 0x01, 0x02, 0xc0, 0x10, 0x01, 0x02, 0xc4, 0x10, 0x01, 0x02, 0xc8, 0x10, 0x01, 0x02, + 0xcc, 0x10, 0x01, 0x02, 0xd0, 0x10, 0x01, 0x02, 0xc8, 0x2d, 0x02, 0x03, 0xd0, 0x2d, 0x02, 0x03, 0xd8, 0x2d, 0x02, 0x03, 0xe0, 0x2d, 0x02, 0x03, 0xe8, 0x2d, 0x02, 0x03, 0xc0, 0x0a, 0x03, 0x03, + 0xc8, 0x0a, 0x03, 0x03, 0xd0, 0x0a, 0x03, 0x03, 0xa0, 0x25, 0x04, 0x04, 0xb0, 0x25, 0x04, 0x04, 0x80, 0x04, 0x05, 0x04, 0x00, 0x1e, 0x06, 0x05, 0x20, 0x02, 0x07, 0x05, 0x80, 0x13, 0x0a, 0x07, + 0xa8, 0x21, 0x00, 0x03, 0xb0, 0x21, 0x00, 0x03, 0xb8, 0x21, 0x00, 0x03, 0xc0, 0x21, 0x00, 0x03, 0xd4, 0x10, 0x01, 0x02, 0xd8, 0x10, 0x01, 0x02, 0xdc, 0x10, 0x01, 0x02, 0xe0, 0x10, 0x01, 0x02, + 0xe4, 0x10, 0x01, 0x02, 0xe8, 0x10, 0x01, 0x02, 0xf0, 0x2d, 0x02, 0x03, 0xf8, 0x2d, 0x02, 0x03, 0x00, 0x2e, 0x02, 0x03, 0x08, 0x2e, 0x02, 0x03, 0x10, 0x2e, 0x02, 0x03, 0xd8, 0x0a, 0x03, 0x03, + 0xe0, 0x0a, 0x03, 0x03, 0xe8, 0x0a, 0x03, 0x03, 0xc0, 0x25, 0x04, 0x04, 0xd0, 0x25, 0x04, 0x04, 0x90, 0x04, 0x05, 0x04, 0x20, 0x1e, 0x06, 0x05, 0x40, 0x02, 0x07, 0x05, 0x00, 0x14, 0x0a, 0x07, + 0xc8, 0x21, 0x00, 0x03, 0xd0, 0x21, 0x00, 0x03, 0xd8, 0x21, 0x00, 0x03, 0xe0, 0x21, 0x00, 0x03, 0xec, 0x10, 0x01, 0x02, 0xf0, 0x10, 0x01, 0x02, 0xf4, 0x10, 0x01, 0x02, 0xf8, 0x10, 0x01, 0x02, + 0xfc, 0x10, 0x01, 0x02, 0x00, 0x11, 0x01, 0x02, 0x18, 0x2e, 0x02, 0x03, 0x20, 0x2e, 0x02, 0x03, 0x28, 0x2e, 0x02, 0x03, 0x30, 0x2e, 0x02, 0x03, 0x38, 0x2e, 0x02, 0x03, 0xf0, 0x0a, 0x03, 0x03, + 0xf8, 0x0a, 0x03, 0x03, 0x00, 0x0b, 0x03, 0x03, 0xe0, 0x25, 0x04, 0x04, 0xf0, 0x25, 0x04, 0x04, 0xa0, 0x04, 0x05, 0x04, 0x40, 0x1e, 0x06, 0x05, 0x60, 0x02, 0x07, 0x05, 0x80, 0x14, 0x0a, 0x07, + 0xe8, 0x21, 0x00, 0x03, 0xf0, 0x21, 0x00, 0x03, 0xf8, 0x21, 0x00, 0x03, 0x00, 0x22, 0x00, 0x03, 0x04, 0x11, 0x01, 0x02, 0x08, 0x11, 0x01, 0x02, 0x0c, 0x11, 0x01, 0x02, 0x10, 0x11, 0x01, 0x02, + 0x14, 0x11, 0x01, 0x02, 0x18, 0x11, 0x01, 0x02, 0x40, 0x2e, 0x02, 0x03, 0x48, 0x2e, 0x02, 0x03, 0x50, 0x2e, 0x02, 0x03, 0x58, 0x2e, 0x02, 0x03, 0x60, 0x2e, 0x02, 0x03, 0x08, 0x0b, 0x03, 0x03, + 0x10, 0x0b, 0x03, 0x03, 0x18, 0x0b, 0x03, 0x03, 0x00, 0x26, 0x04, 0x04, 0x10, 0x26, 0x04, 0x04, 0xb0, 0x04, 0x05, 0x04, 0x60, 0x1e, 0x06, 0x05, 0x80, 0x02, 0x07, 0x05, 0x00, 0x28, 0x0b, 0x08, + 0x08, 0x22, 0x00, 0x03, 0x10, 0x22, 0x00, 0x03, 0x18, 0x22, 0x00, 0x03, 0x20, 0x22, 0x00, 0x03, 0x1c, 0x11, 0x01, 0x02, 0x20, 0x11, 0x01, 0x02, 0x24, 0x11, 0x01, 0x02, 0x28, 0x11, 0x01, 0x02, + 0x2c, 0x11, 0x01, 0x02, 0x30, 0x11, 0x01, 0x02, 0x68, 0x2e, 0x02, 0x03, 0x70, 0x2e, 0x02, 0x03, 0x78, 0x2e, 0x02, 0x03, 0x80, 0x2e, 0x02, 0x03, 0x88, 0x2e, 0x02, 0x03, 0x20, 0x0b, 0x03, 0x03, + 0x28, 0x0b, 0x03, 0x03, 0x30, 0x0b, 0x03, 0x03, 0x20, 0x26, 0x04, 0x04, 0x30, 0x26, 0x04, 0x04, 0xc0, 0x04, 0x05, 0x04, 0x80, 0x1e, 0x06, 0x05, 0xa0, 0x02, 0x07, 0x05, 0x00, 0x29, 0x0b, 0x08, + 0x28, 0x22, 0x00, 0x03, 0x30, 0x22, 0x00, 0x03, 0x38, 0x22, 0x00, 0x03, 0x40, 0x22, 0x00, 0x03, 0x34, 0x11, 0x01, 0x02, 0x38, 0x11, 0x01, 0x02, 0x3c, 0x11, 0x01, 0x02, 0x40, 0x11, 0x01, 0x02, + 0x44, 0x11, 0x01, 0x02, 0x48, 0x11, 0x01, 0x02, 0x90, 0x2e, 0x02, 0x03, 0x98, 0x2e, 0x02, 0x03, 0xa0, 0x2e, 0x02, 0x03, 0xa8, 0x2e, 0x02, 0x03, 0xb0, 0x2e, 0x02, 0x03, 0x38, 0x0b, 0x03, 0x03, + 0x40, 0x0b, 0x03, 0x03, 0x48, 0x0b, 0x03, 0x03, 0x40, 0x26, 0x04, 0x04, 0x50, 0x26, 0x04, 0x04, 0xd0, 0x04, 0x05, 0x04, 0xa0, 0x1e, 0x06, 0x05, 0xc0, 0x02, 0x07, 0x05, 0x00, 0x2a, 0x0b, 0x08, + 0x48, 0x22, 0x00, 0x03, 0x50, 0x22, 0x00, 0x03, 0x58, 0x22, 0x00, 0x03, 0x60, 0x22, 0x00, 0x03, 0x4c, 0x11, 0x01, 0x02, 0x50, 0x11, 0x01, 0x02, 0x54, 0x11, 0x01, 0x02, 0x58, 0x11, 0x01, 0x02, + 0x5c, 0x11, 0x01, 0x02, 0x60, 0x11, 0x01, 0x02, 0xb8, 0x2e, 0x02, 0x03, 0xc0, 0x2e, 0x02, 0x03, 0xc8, 0x2e, 0x02, 0x03, 0xd0, 0x2e, 0x02, 0x03, 0xd8, 0x2e, 0x02, 0x03, 0x50, 0x0b, 0x03, 0x03, + 0x58, 0x0b, 0x03, 0x03, 0x60, 0x0b, 0x03, 0x03, 0x60, 0x26, 0x04, 0x04, 0x70, 0x26, 0x04, 0x04, 0xe0, 0x04, 0x05, 0x04, 0xc0, 0x1e, 0x06, 0x05, 0xe0, 0x02, 0x07, 0x05, 0x00, 0x2b, 0x0b, 0x08, + 0x68, 0x22, 0x00, 0x03, 0x70, 0x22, 0x00, 0x03, 0x78, 0x22, 0x00, 0x03, 0x80, 0x22, 0x00, 0x03, 0x64, 0x11, 0x01, 0x02, 0x68, 0x11, 0x01, 0x02, 0x6c, 0x11, 0x01, 0x02, 0x70, 0x11, 0x01, 0x02, + 0x74, 0x11, 0x01, 0x02, 0x78, 0x11, 0x01, 0x02, 0xe0, 0x2e, 0x02, 0x03, 0xe8, 0x2e, 0x02, 0x03, 0xf0, 0x2e, 0x02, 0x03, 0xf8, 0x2e, 0x02, 0x03, 0x00, 0x2f, 0x02, 0x03, 0x68, 0x0b, 0x03, 0x03, + 0x70, 0x0b, 0x03, 0x03, 0x78, 0x0b, 0x03, 0x03, 0x80, 0x26, 0x04, 0x04, 0x90, 0x26, 0x04, 0x04, 0xf0, 0x04, 0x05, 0x04, 0xe0, 0x1e, 0x06, 0x05, 0x00, 0x03, 0x07, 0x05, 0x00, 0x2c, 0x0b, 0x08, + 0x88, 0x22, 0x00, 0x03, 0x90, 0x22, 0x00, 0x03, 0x98, 0x22, 0x00, 0x03, 0xa0, 0x22, 0x00, 0x03, 0x7c, 0x11, 0x01, 0x02, 0x80, 0x11, 0x01, 0x02, 0x84, 0x11, 0x01, 0x02, 0x88, 0x11, 0x01, 0x02, + 0x8c, 0x11, 0x01, 0x02, 0x90, 0x11, 0x01, 0x02, 0x08, 0x2f, 0x02, 0x03, 0x10, 0x2f, 0x02, 0x03, 0x18, 0x2f, 0x02, 0x03, 0x20, 0x2f, 0x02, 0x03, 0x28, 0x2f, 0x02, 0x03, 0x80, 0x0b, 0x03, 0x03, + 0x88, 0x0b, 0x03, 0x03, 0x90, 0x0b, 0x03, 0x03, 0xa0, 0x26, 0x04, 0x04, 0xb0, 0x26, 0x04, 0x04, 0x00, 0x05, 0x05, 0x04, 0x00, 0x1f, 0x06, 0x05, 0x20, 0x03, 0x07, 0x05, 0x00, 0x2d, 0x0b, 0x08, + 0xa8, 0x22, 0x00, 0x03, 0xb0, 0x22, 0x00, 0x03, 0xb8, 0x22, 0x00, 0x03, 0xc0, 0x22, 0x00, 0x03, 0x94, 0x11, 0x01, 0x02, 0x98, 0x11, 0x01, 0x02, 0x9c, 0x11, 0x01, 0x02, 0xa0, 0x11, 0x01, 0x02, + 0xa4, 0x11, 0x01, 0x02, 0xa8, 0x11, 0x01, 0x02, 0x30, 0x2f, 0x02, 0x03, 0x38, 0x2f, 0x02, 0x03, 0x40, 0x2f, 0x02, 0x03, 0x48, 0x2f, 0x02, 0x03, 0x50, 0x2f, 0x02, 0x03, 0x98, 0x0b, 0x03, 0x03, + 0xa0, 0x0b, 0x03, 0x03, 0xa8, 0x0b, 0x03, 0x03, 0xc0, 0x26, 0x04, 0x04, 0xd0, 0x26, 0x04, 0x04, 0x10, 0x05, 0x05, 0x04, 0x20, 0x1f, 0x06, 0x05, 0x40, 0x14, 0x08, 0x06, 0x00, 0x2e, 0x0b, 0x08, + 0xc8, 0x22, 0x00, 0x03, 0xd0, 0x22, 0x00, 0x03, 0xd8, 0x22, 0x00, 0x03, 0xe0, 0x22, 0x00, 0x03, 0xac, 0x11, 0x01, 0x02, 0xb0, 0x11, 0x01, 0x02, 0xb4, 0x11, 0x01, 0x02, 0xb8, 0x11, 0x01, 0x02, + 0xbc, 0x11, 0x01, 0x02, 0xc0, 0x11, 0x01, 0x02, 0x58, 0x2f, 0x02, 0x03, 0x60, 0x2f, 0x02, 0x03, 0x68, 0x2f, 0x02, 0x03, 0x70, 0x2f, 0x02, 0x03, 0x78, 0x2f, 0x02, 0x03, 0xb0, 0x0b, 0x03, 0x03, + 0xb8, 0x0b, 0x03, 0x03, 0xe0, 0x26, 0x04, 0x04, 0xf0, 0x26, 0x04, 0x04, 0x00, 0x27, 0x04, 0x04, 0x20, 0x05, 0x05, 0x04, 0x40, 0x1f, 0x06, 0x05, 0x80, 0x14, 0x08, 0x06, 0x00, 0x2f, 0x0b, 0x08, + 0xe8, 0x22, 0x00, 0x03, 0xf0, 0x22, 0x00, 0x03, 0xf8, 0x22, 0x00, 0x03, 0x00, 0x23, 0x00, 0x03, 0xc4, 0x11, 0x01, 0x02, 0xc8, 0x11, 0x01, 0x02, 0xcc, 0x11, 0x01, 0x02, 0xd0, 0x11, 0x01, 0x02, + 0xd4, 0x11, 0x01, 0x02, 0xd8, 0x11, 0x01, 0x02, 0x80, 0x2f, 0x02, 0x03, 0x88, 0x2f, 0x02, 0x03, 0x90, 0x2f, 0x02, 0x03, 0x98, 0x2f, 0x02, 0x03, 0xa0, 0x2f, 0x02, 0x03, 0xc0, 0x0b, 0x03, 0x03, + 0xc8, 0x0b, 0x03, 0x03, 0x10, 0x27, 0x04, 0x04, 0x20, 0x27, 0x04, 0x04, 0x30, 0x27, 0x04, 0x04, 0x30, 0x05, 0x05, 0x04, 0x60, 0x1f, 0x06, 0x05, 0xc0, 0x14, 0x08, 0x06, 0x00, 0x30, 0x0b, 0x08, + 0x08, 0x23, 0x00, 0x03, 0x10, 0x23, 0x00, 0x03, 0x18, 0x23, 0x00, 0x03, 0x20, 0x23, 0x00, 0x03, 0xdc, 0x11, 0x01, 0x02, 0xe0, 0x11, 0x01, 0x02, 0xe4, 0x11, 0x01, 0x02, 0xe8, 0x11, 0x01, 0x02, + 0xec, 0x11, 0x01, 0x02, 0xf0, 0x11, 0x01, 0x02, 0xa8, 0x2f, 0x02, 0x03, 0xb0, 0x2f, 0x02, 0x03, 0xb8, 0x2f, 0x02, 0x03, 0xc0, 0x2f, 0x02, 0x03, 0xd0, 0x0b, 0x03, 0x03, 0xd8, 0x0b, 0x03, 0x03, + 0xe0, 0x0b, 0x03, 0x03, 0x40, 0x27, 0x04, 0x04, 0x50, 0x27, 0x04, 0x04, 0x60, 0x27, 0x04, 0x04, 0x40, 0x05, 0x05, 0x04, 0x80, 0x1f, 0x06, 0x05, 0x00, 0x15, 0x08, 0x06, 0x00, 0x31, 0x0b, 0x08, + 0x28, 0x23, 0x00, 0x03, 0x30, 0x23, 0x00, 0x03, 0x38, 0x23, 0x00, 0x03, 0x40, 0x23, 0x00, 0x03, 0xf4, 0x11, 0x01, 0x02, 0xf8, 0x11, 0x01, 0x02, 0xfc, 0x11, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, + 0x04, 0x12, 0x01, 0x02, 0x08, 0x12, 0x01, 0x02, 0xc8, 0x2f, 0x02, 0x03, 0xd0, 0x2f, 0x02, 0x03, 0xd8, 0x2f, 0x02, 0x03, 0xe0, 0x2f, 0x02, 0x03, 0xe8, 0x0b, 0x03, 0x03, 0xf0, 0x0b, 0x03, 0x03, + 0xf8, 0x0b, 0x03, 0x03, 0x70, 0x27, 0x04, 0x04, 0x80, 0x27, 0x04, 0x04, 0x50, 0x05, 0x05, 0x04, 0x60, 0x05, 0x05, 0x04, 0xa0, 0x1f, 0x06, 0x05, 0x40, 0x15, 0x08, 0x06, 0x00, 0x32, 0x0b, 0x08, + 0x48, 0x23, 0x00, 0x03, 0x50, 0x23, 0x00, 0x03, 0x58, 0x23, 0x00, 0x03, 0x60, 0x23, 0x00, 0x03, 0x0c, 0x12, 0x01, 0x02, 0x10, 0x12, 0x01, 0x02, 0x14, 0x12, 0x01, 0x02, 0x18, 0x12, 0x01, 0x02, + 0x1c, 0x12, 0x01, 0x02, 0x20, 0x12, 0x01, 0x02, 0xe8, 0x2f, 0x02, 0x03, 0xf0, 0x2f, 0x02, 0x03, 0xf8, 0x2f, 0x02, 0x03, 0x00, 0x30, 0x02, 0x03, 0x00, 0x0c, 0x03, 0x03, 0x08, 0x0c, 0x03, 0x03, + 0x10, 0x0c, 0x03, 0x03, 0x90, 0x27, 0x04, 0x04, 0xa0, 0x27, 0x04, 0x04, 0x70, 0x05, 0x05, 0x04, 0x80, 0x05, 0x05, 0x04, 0xc0, 0x1f, 0x06, 0x05, 0x80, 0x15, 0x08, 0x06, 0x00, 0x33, 0x0b, 0x08, + 0x68, 0x23, 0x00, 0x03, 0x70, 0x23, 0x00, 0x03, 0x78, 0x23, 0x00, 0x03, 0x80, 0x23, 0x00, 0x03, 0x24, 0x12, 0x01, 0x02, 0x28, 0x12, 0x01, 0x02, 0x2c, 0x12, 0x01, 0x02, 0x30, 0x12, 0x01, 0x02, + 0x34, 0x12, 0x01, 0x02, 0x38, 0x12, 0x01, 0x02, 0x08, 0x30, 0x02, 0x03, 0x10, 0x30, 0x02, 0x03, 0x18, 0x30, 0x02, 0x03, 0x20, 0x30, 0x02, 0x03, 0x18, 0x0c, 0x03, 0x03, 0x20, 0x0c, 0x03, 0x03, + 0x28, 0x0c, 0x03, 0x03, 0xb0, 0x27, 0x04, 0x04, 0xc0, 0x27, 0x04, 0x04, 0x90, 0x05, 0x05, 0x04, 0xa0, 0x05, 0x05, 0x04, 0xe0, 0x1f, 0x06, 0x05, 0xc0, 0x15, 0x08, 0x06, 0x00, 0x06, 0x0c, 0x08, + 0x88, 0x23, 0x00, 0x03, 0x90, 0x23, 0x00, 0x03, 0x98, 0x23, 0x00, 0x03, 0xa0, 0x23, 0x00, 0x03, 0x3c, 0x12, 0x01, 0x02, 0x40, 0x12, 0x01, 0x02, 0x44, 0x12, 0x01, 0x02, 0x48, 0x12, 0x01, 0x02, + 0x4c, 0x12, 0x01, 0x02, 0x50, 0x12, 0x01, 0x02, 0x28, 0x30, 0x02, 0x03, 0x30, 0x30, 0x02, 0x03, 0x38, 0x30, 0x02, 0x03, 0x40, 0x30, 0x02, 0x03, 0x30, 0x0c, 0x03, 0x03, 0x38, 0x0c, 0x03, 0x03, + 0x40, 0x0c, 0x03, 0x03, 0xd0, 0x27, 0x04, 0x04, 0xe0, 0x27, 0x04, 0x04, 0xb0, 0x05, 0x05, 0x04, 0xc0, 0x05, 0x05, 0x04, 0x00, 0x20, 0x06, 0x05, 0x00, 0x16, 0x08, 0x06, 0x00, 0x07, 0x0c, 0x08, + 0xa8, 0x23, 0x00, 0x03, 0xb0, 0x23, 0x00, 0x03, 0xb8, 0x23, 0x00, 0x03, 0xc0, 0x23, 0x00, 0x03, 0x54, 0x12, 0x01, 0x02, 0x58, 0x12, 0x01, 0x02, 0x5c, 0x12, 0x01, 0x02, 0x60, 0x12, 0x01, 0x02, + 0x64, 0x12, 0x01, 0x02, 0x68, 0x12, 0x01, 0x02, 0x48, 0x30, 0x02, 0x03, 0x50, 0x30, 0x02, 0x03, 0x58, 0x30, 0x02, 0x03, 0x60, 0x30, 0x02, 0x03, 0x48, 0x0c, 0x03, 0x03, 0x50, 0x0c, 0x03, 0x03, + 0x58, 0x0c, 0x03, 0x03, 0xf0, 0x27, 0x04, 0x04, 0x00, 0x28, 0x04, 0x04, 0xd0, 0x05, 0x05, 0x04, 0xe0, 0x05, 0x05, 0x04, 0x20, 0x20, 0x06, 0x05, 0x40, 0x16, 0x08, 0x06, 0x00, 0x08, 0x0c, 0x08, + 0xc8, 0x23, 0x00, 0x03, 0xd0, 0x23, 0x00, 0x03, 0xd8, 0x23, 0x00, 0x03, 0xe0, 0x23, 0x00, 0x03, 0x6c, 0x12, 0x01, 0x02, 0x70, 0x12, 0x01, 0x02, 0x74, 0x12, 0x01, 0x02, 0x78, 0x12, 0x01, 0x02, + 0x7c, 0x12, 0x01, 0x02, 0x80, 0x12, 0x01, 0x02, 0x68, 0x30, 0x02, 0x03, 0x70, 0x30, 0x02, 0x03, 0x78, 0x30, 0x02, 0x03, 0x80, 0x30, 0x02, 0x03, 0x60, 0x0c, 0x03, 0x03, 0x68, 0x0c, 0x03, 0x03, + 0x70, 0x0c, 0x03, 0x03, 0x10, 0x28, 0x04, 0x04, 0x20, 0x28, 0x04, 0x04, 0xf0, 0x05, 0x05, 0x04, 0x00, 0x06, 0x05, 0x04, 0x40, 0x20, 0x06, 0x05, 0x80, 0x16, 0x08, 0x06, 0x00, 0x09, 0x0c, 0x08, + 0xe8, 0x23, 0x00, 0x03, 0xf0, 0x23, 0x00, 0x03, 0xf8, 0x23, 0x00, 0x03, 0x00, 0x24, 0x00, 0x03, 0x84, 0x12, 0x01, 0x02, 0x88, 0x12, 0x01, 0x02, 0x8c, 0x12, 0x01, 0x02, 0x90, 0x12, 0x01, 0x02, + 0x94, 0x12, 0x01, 0x02, 0x98, 0x12, 0x01, 0x02, 0x88, 0x30, 0x02, 0x03, 0x90, 0x30, 0x02, 0x03, 0x98, 0x30, 0x02, 0x03, 0xa0, 0x30, 0x02, 0x03, 0x78, 0x0c, 0x03, 0x03, 0x80, 0x0c, 0x03, 0x03, + 0x88, 0x0c, 0x03, 0x03, 0x30, 0x28, 0x04, 0x04, 0x40, 0x28, 0x04, 0x04, 0x10, 0x06, 0x05, 0x04, 0x20, 0x06, 0x05, 0x04, 0x60, 0x20, 0x06, 0x05, 0xc0, 0x16, 0x08, 0x06, 0x00, 0x0a, 0x0c, 0x08, + 0x08, 0x24, 0x00, 0x03, 0x10, 0x24, 0x00, 0x03, 0x18, 0x24, 0x00, 0x03, 0x20, 0x24, 0x00, 0x03, 0x9c, 0x12, 0x01, 0x02, 0xa0, 0x12, 0x01, 0x02, 0xa4, 0x12, 0x01, 0x02, 0xa8, 0x12, 0x01, 0x02, + 0xac, 0x12, 0x01, 0x02, 0xb0, 0x12, 0x01, 0x02, 0xa8, 0x30, 0x02, 0x03, 0xb0, 0x30, 0x02, 0x03, 0xb8, 0x30, 0x02, 0x03, 0xc0, 0x30, 0x02, 0x03, 0x90, 0x0c, 0x03, 0x03, 0x98, 0x0c, 0x03, 0x03, + 0xa0, 0x0c, 0x03, 0x03, 0x50, 0x28, 0x04, 0x04, 0x60, 0x28, 0x04, 0x04, 0x30, 0x06, 0x05, 0x04, 0x40, 0x06, 0x05, 0x04, 0x80, 0x20, 0x06, 0x05, 0x00, 0x17, 0x08, 0x06, 0x00, 0x0b, 0x0c, 0x08, + 0x28, 0x24, 0x00, 0x03, 0x30, 0x24, 0x00, 0x03, 0x38, 0x24, 0x00, 0x03, 0x40, 0x24, 0x00, 0x03, 0xb4, 0x12, 0x01, 0x02, 0xb8, 0x12, 0x01, 0x02, 0xbc, 0x12, 0x01, 0x02, 0xc0, 0x12, 0x01, 0x02, + 0xc4, 0x12, 0x01, 0x02, 0xc8, 0x12, 0x01, 0x02, 0xc8, 0x30, 0x02, 0x03, 0xd0, 0x30, 0x02, 0x03, 0xd8, 0x30, 0x02, 0x03, 0xe0, 0x30, 0x02, 0x03, 0xa8, 0x0c, 0x03, 0x03, 0xb0, 0x0c, 0x03, 0x03, + 0xb8, 0x0c, 0x03, 0x03, 0x70, 0x28, 0x04, 0x04, 0x80, 0x28, 0x04, 0x04, 0x50, 0x06, 0x05, 0x04, 0x60, 0x06, 0x05, 0x04, 0xa0, 0x20, 0x06, 0x05, 0x40, 0x17, 0x08, 0x06, 0x00, 0x0c, 0x0c, 0x08, + 0x48, 0x24, 0x00, 0x03, 0x50, 0x24, 0x00, 0x03, 0x58, 0x24, 0x00, 0x03, 0x60, 0x24, 0x00, 0x03, 0xcc, 0x12, 0x01, 0x02, 0xd0, 0x12, 0x01, 0x02, 0xd4, 0x12, 0x01, 0x02, 0xd8, 0x12, 0x01, 0x02, + 0xdc, 0x12, 0x01, 0x02, 0xe0, 0x12, 0x01, 0x02, 0xe8, 0x30, 0x02, 0x03, 0xf0, 0x30, 0x02, 0x03, 0xf8, 0x30, 0x02, 0x03, 0x00, 0x31, 0x02, 0x03, 0xc0, 0x0c, 0x03, 0x03, 0xc8, 0x0c, 0x03, 0x03, + 0xd0, 0x0c, 0x03, 0x03, 0x90, 0x28, 0x04, 0x04, 0xa0, 0x28, 0x04, 0x04, 0x70, 0x06, 0x05, 0x04, 0x80, 0x06, 0x05, 0x04, 0xc0, 0x20, 0x06, 0x05, 0x80, 0x17, 0x08, 0x06, 0x00, 0x0d, 0x0c, 0x08, + 0x68, 0x24, 0x00, 0x03, 0x70, 0x24, 0x00, 0x03, 0x78, 0x24, 0x00, 0x03, 0x80, 0x24, 0x00, 0x03, 0xe4, 0x12, 0x01, 0x02, 0xe8, 0x12, 0x01, 0x02, 0xec, 0x12, 0x01, 0x02, 0xf0, 0x12, 0x01, 0x02, + 0xf4, 0x12, 0x01, 0x02, 0xf8, 0x12, 0x01, 0x02, 0x08, 0x31, 0x02, 0x03, 0x10, 0x31, 0x02, 0x03, 0x18, 0x31, 0x02, 0x03, 0x20, 0x31, 0x02, 0x03, 0xd8, 0x0c, 0x03, 0x03, 0xe0, 0x0c, 0x03, 0x03, + 0xe8, 0x0c, 0x03, 0x03, 0xb0, 0x28, 0x04, 0x04, 0xc0, 0x28, 0x04, 0x04, 0x90, 0x06, 0x05, 0x04, 0xa0, 0x06, 0x05, 0x04, 0xe0, 0x20, 0x06, 0x05, 0xc0, 0x17, 0x08, 0x06, 0x00, 0x22, 0x0d, 0x09, + 0x88, 0x24, 0x00, 0x03, 0x90, 0x24, 0x00, 0x03, 0x98, 0x24, 0x00, 0x03, 0xa0, 0x24, 0x00, 0x03, 0xfc, 0x12, 0x01, 0x02, 0x00, 0x13, 0x01, 0x02, 0x04, 0x13, 0x01, 0x02, 0x08, 0x13, 0x01, 0x02, + 0x0c, 0x13, 0x01, 0x02, 0x10, 0x13, 0x01, 0x02, 0x28, 0x31, 0x02, 0x03, 0x30, 0x31, 0x02, 0x03, 0x38, 0x31, 0x02, 0x03, 0x40, 0x31, 0x02, 0x03, 0xf0, 0x0c, 0x03, 0x03, 0xf8, 0x0c, 0x03, 0x03, + 0x00, 0x0d, 0x03, 0x03, 0xd0, 0x28, 0x04, 0x04, 0xe0, 0x28, 0x04, 0x04, 0xb0, 0x06, 0x05, 0x04, 0xc0, 0x06, 0x05, 0x04, 0x00, 0x21, 0x06, 0x05, 0x00, 0x18, 0x08, 0x06, 0x00, 0x24, 0x0d, 0x09, + 0xa8, 0x24, 0x00, 0x03, 0xb0, 0x24, 0x00, 0x03, 0xb8, 0x24, 0x00, 0x03, 0xc0, 0x24, 0x00, 0x03, 0x14, 0x13, 0x01, 0x02, 0x18, 0x13, 0x01, 0x02, 0x1c, 0x13, 0x01, 0x02, 0x20, 0x13, 0x01, 0x02, + 0x24, 0x13, 0x01, 0x02, 0x28, 0x13, 0x01, 0x02, 0x48, 0x31, 0x02, 0x03, 0x50, 0x31, 0x02, 0x03, 0x58, 0x31, 0x02, 0x03, 0x60, 0x31, 0x02, 0x03, 0x08, 0x0d, 0x03, 0x03, 0x10, 0x0d, 0x03, 0x03, + 0x18, 0x0d, 0x03, 0x03, 0xf0, 0x28, 0x04, 0x04, 0x00, 0x29, 0x04, 0x04, 0xd0, 0x06, 0x05, 0x04, 0xe0, 0x06, 0x05, 0x04, 0x20, 0x21, 0x06, 0x05, 0x40, 0x18, 0x08, 0x06, 0x00, 0x26, 0x0d, 0x09, + 0xc8, 0x24, 0x00, 0x03, 0xd0, 0x24, 0x00, 0x03, 0xd8, 0x24, 0x00, 0x03, 0xe0, 0x24, 0x00, 0x03, 0x2c, 0x13, 0x01, 0x02, 0x30, 0x13, 0x01, 0x02, 0x34, 0x13, 0x01, 0x02, 0x38, 0x13, 0x01, 0x02, + 0x3c, 0x13, 0x01, 0x02, 0x40, 0x13, 0x01, 0x02, 0x68, 0x31, 0x02, 0x03, 0x70, 0x31, 0x02, 0x03, 0x78, 0x31, 0x02, 0x03, 0x80, 0x31, 0x02, 0x03, 0x20, 0x0d, 0x03, 0x03, 0x28, 0x0d, 0x03, 0x03, + 0x30, 0x0d, 0x03, 0x03, 0x10, 0x29, 0x04, 0x04, 0x20, 0x29, 0x04, 0x04, 0xf0, 0x06, 0x05, 0x04, 0x00, 0x07, 0x05, 0x04, 0x40, 0x21, 0x06, 0x05, 0x80, 0x18, 0x08, 0x06, 0x00, 0x28, 0x0d, 0x09, + 0xe8, 0x24, 0x00, 0x03, 0xf0, 0x24, 0x00, 0x03, 0xf8, 0x24, 0x00, 0x03, 0x00, 0x25, 0x00, 0x03, 0x44, 0x13, 0x01, 0x02, 0x48, 0x13, 0x01, 0x02, 0x4c, 0x13, 0x01, 0x02, 0x50, 0x13, 0x01, 0x02, + 0x54, 0x13, 0x01, 0x02, 0x58, 0x13, 0x01, 0x02, 0x88, 0x31, 0x02, 0x03, 0x90, 0x31, 0x02, 0x03, 0x98, 0x31, 0x02, 0x03, 0xa0, 0x31, 0x02, 0x03, 0x38, 0x0d, 0x03, 0x03, 0x40, 0x0d, 0x03, 0x03, + 0x48, 0x0d, 0x03, 0x03, 0x30, 0x29, 0x04, 0x04, 0x40, 0x29, 0x04, 0x04, 0x10, 0x07, 0x05, 0x04, 0x20, 0x07, 0x05, 0x04, 0x60, 0x21, 0x06, 0x05, 0xc0, 0x18, 0x08, 0x06, 0x00, 0x2a, 0x0d, 0x09, + 0x08, 0x25, 0x00, 0x03, 0x10, 0x25, 0x00, 0x03, 0x18, 0x25, 0x00, 0x03, 0x20, 0x25, 0x00, 0x03, 0x5c, 0x13, 0x01, 0x02, 0x60, 0x13, 0x01, 0x02, 0x64, 0x13, 0x01, 0x02, 0x68, 0x13, 0x01, 0x02, + 0x6c, 0x13, 0x01, 0x02, 0x70, 0x13, 0x01, 0x02, 0xa8, 0x31, 0x02, 0x03, 0xb0, 0x31, 0x02, 0x03, 0xb8, 0x31, 0x02, 0x03, 0xc0, 0x31, 0x02, 0x03, 0x50, 0x0d, 0x03, 0x03, 0x58, 0x0d, 0x03, 0x03, + 0x60, 0x0d, 0x03, 0x03, 0x50, 0x29, 0x04, 0x04, 0x60, 0x29, 0x04, 0x04, 0x30, 0x07, 0x05, 0x04, 0x40, 0x07, 0x05, 0x04, 0x80, 0x21, 0x06, 0x05, 0x00, 0x19, 0x08, 0x06, 0x00, 0x02, 0x0e, 0x09, + 0x28, 0x25, 0x00, 0x03, 0x30, 0x25, 0x00, 0x03, 0x38, 0x25, 0x00, 0x03, 0x40, 0x25, 0x00, 0x03, 0x74, 0x13, 0x01, 0x02, 0x78, 0x13, 0x01, 0x02, 0x7c, 0x13, 0x01, 0x02, 0x80, 0x13, 0x01, 0x02, + 0x84, 0x13, 0x01, 0x02, 0x88, 0x13, 0x01, 0x02, 0xc8, 0x31, 0x02, 0x03, 0xd0, 0x31, 0x02, 0x03, 0xd8, 0x31, 0x02, 0x03, 0xe0, 0x31, 0x02, 0x03, 0x68, 0x0d, 0x03, 0x03, 0x70, 0x0d, 0x03, 0x03, + 0x78, 0x0d, 0x03, 0x03, 0x70, 0x29, 0x04, 0x04, 0x80, 0x29, 0x04, 0x04, 0x50, 0x07, 0x05, 0x04, 0x60, 0x07, 0x05, 0x04, 0xa0, 0x21, 0x06, 0x05, 0x40, 0x19, 0x08, 0x06, 0x00, 0x04, 0x0e, 0x09, + 0x48, 0x25, 0x00, 0x03, 0x50, 0x25, 0x00, 0x03, 0x58, 0x25, 0x00, 0x03, 0x8c, 0x13, 0x01, 0x02, 0x90, 0x13, 0x01, 0x02, 0x94, 0x13, 0x01, 0x02, 0x98, 0x13, 0x01, 0x02, 0x9c, 0x13, 0x01, 0x02, + 0xa0, 0x13, 0x01, 0x02, 0xa4, 0x13, 0x01, 0x02, 0xe8, 0x31, 0x02, 0x03, 0xf0, 0x31, 0x02, 0x03, 0xf8, 0x31, 0x02, 0x03, 0x00, 0x32, 0x02, 0x03, 0x80, 0x0d, 0x03, 0x03, 0x88, 0x0d, 0x03, 0x03, + 0x90, 0x0d, 0x03, 0x03, 0x90, 0x29, 0x04, 0x04, 0xa0, 0x29, 0x04, 0x04, 0x70, 0x07, 0x05, 0x04, 0x80, 0x07, 0x05, 0x04, 0xc0, 0x21, 0x06, 0x05, 0x80, 0x19, 0x08, 0x06, 0x00, 0x06, 0x0e, 0x09, + 0x60, 0x25, 0x00, 0x03, 0x68, 0x25, 0x00, 0x03, 0x70, 0x25, 0x00, 0x03, 0xa8, 0x13, 0x01, 0x02, 0xac, 0x13, 0x01, 0x02, 0xb0, 0x13, 0x01, 0x02, 0xb4, 0x13, 0x01, 0x02, 0xb8, 0x13, 0x01, 0x02, + 0xbc, 0x13, 0x01, 0x02, 0xc0, 0x13, 0x01, 0x02, 0x08, 0x32, 0x02, 0x03, 0x10, 0x32, 0x02, 0x03, 0x18, 0x32, 0x02, 0x03, 0x20, 0x32, 0x02, 0x03, 0x98, 0x0d, 0x03, 0x03, 0xa0, 0x0d, 0x03, 0x03, + 0xa8, 0x0d, 0x03, 0x03, 0xb0, 0x29, 0x04, 0x04, 0xc0, 0x29, 0x04, 0x04, 0x90, 0x07, 0x05, 0x04, 0xa0, 0x07, 0x05, 0x04, 0xe0, 0x21, 0x06, 0x05, 0xc0, 0x19, 0x08, 0x06, 0x00, 0x08, 0x0e, 0x09, + 0x78, 0x25, 0x00, 0x03, 0x80, 0x25, 0x00, 0x03, 0x88, 0x25, 0x00, 0x03, 0xc4, 0x13, 0x01, 0x02, 0xc8, 0x13, 0x01, 0x02, 0xcc, 0x13, 0x01, 0x02, 0xd0, 0x13, 0x01, 0x02, 0xd4, 0x13, 0x01, 0x02, + 0xd8, 0x13, 0x01, 0x02, 0xdc, 0x13, 0x01, 0x02, 0x28, 0x32, 0x02, 0x03, 0x30, 0x32, 0x02, 0x03, 0x38, 0x32, 0x02, 0x03, 0x40, 0x32, 0x02, 0x03, 0xb0, 0x0d, 0x03, 0x03, 0xb8, 0x0d, 0x03, 0x03, + 0xc0, 0x0d, 0x03, 0x03, 0xd0, 0x29, 0x04, 0x04, 0xe0, 0x29, 0x04, 0x04, 0xb0, 0x07, 0x05, 0x04, 0xc0, 0x07, 0x05, 0x04, 0x00, 0x22, 0x06, 0x05, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x18, 0x0f, 0x0a, + 0x90, 0x25, 0x00, 0x03, 0x98, 0x25, 0x00, 0x03, 0xa0, 0x25, 0x00, 0x03, 0xe0, 0x13, 0x01, 0x02, 0xe4, 0x13, 0x01, 0x02, 0xe8, 0x13, 0x01, 0x02, 0xec, 0x13, 0x01, 0x02, 0xf0, 0x13, 0x01, 0x02, + 0xf4, 0x13, 0x01, 0x02, 0xf8, 0x13, 0x01, 0x02, 0x48, 0x32, 0x02, 0x03, 0x50, 0x32, 0x02, 0x03, 0x58, 0x32, 0x02, 0x03, 0x60, 0x32, 0x02, 0x03, 0xc8, 0x0d, 0x03, 0x03, 0xd0, 0x0d, 0x03, 0x03, + 0xd8, 0x0d, 0x03, 0x03, 0xf0, 0x29, 0x04, 0x04, 0x00, 0x2a, 0x04, 0x04, 0xd0, 0x07, 0x05, 0x04, 0xe0, 0x07, 0x05, 0x04, 0x20, 0x22, 0x06, 0x05, 0x40, 0x1a, 0x08, 0x06, 0x00, 0x1c, 0x0f, 0x0a, + 0xa8, 0x25, 0x00, 0x03, 0xb0, 0x25, 0x00, 0x03, 0xb8, 0x25, 0x00, 0x03, 0xfc, 0x13, 0x01, 0x02, 0x00, 0x14, 0x01, 0x02, 0x04, 0x14, 0x01, 0x02, 0x08, 0x14, 0x01, 0x02, 0x0c, 0x14, 0x01, 0x02, + 0x10, 0x14, 0x01, 0x02, 0x14, 0x14, 0x01, 0x02, 0x68, 0x32, 0x02, 0x03, 0x70, 0x32, 0x02, 0x03, 0x78, 0x32, 0x02, 0x03, 0x80, 0x32, 0x02, 0x03, 0xe0, 0x0d, 0x03, 0x03, 0xe8, 0x0d, 0x03, 0x03, + 0xf0, 0x0d, 0x03, 0x03, 0x10, 0x2a, 0x04, 0x04, 0x20, 0x2a, 0x04, 0x04, 0xf0, 0x07, 0x05, 0x04, 0x00, 0x08, 0x05, 0x04, 0x40, 0x22, 0x06, 0x05, 0x80, 0x1a, 0x08, 0x06, 0x00, 0x20, 0x0f, 0x0a, + 0xc0, 0x25, 0x00, 0x03, 0xc8, 0x25, 0x00, 0x03, 0xd0, 0x25, 0x00, 0x03, 0x18, 0x14, 0x01, 0x02, 0x1c, 0x14, 0x01, 0x02, 0x20, 0x14, 0x01, 0x02, 0x24, 0x14, 0x01, 0x02, 0x28, 0x14, 0x01, 0x02, + 0x2c, 0x14, 0x01, 0x02, 0x30, 0x14, 0x01, 0x02, 0x88, 0x32, 0x02, 0x03, 0x90, 0x32, 0x02, 0x03, 0x98, 0x32, 0x02, 0x03, 0xa0, 0x32, 0x02, 0x03, 0xf8, 0x0d, 0x03, 0x03, 0x00, 0x0e, 0x03, 0x03, + 0x08, 0x0e, 0x03, 0x03, 0x30, 0x2a, 0x04, 0x04, 0x40, 0x2a, 0x04, 0x04, 0x10, 0x08, 0x05, 0x04, 0x20, 0x08, 0x05, 0x04, 0x60, 0x22, 0x06, 0x05, 0xc0, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x10, 0x0a, + 0xd8, 0x25, 0x00, 0x03, 0xe0, 0x25, 0x00, 0x03, 0xe8, 0x25, 0x00, 0x03, 0x34, 0x14, 0x01, 0x02, 0x38, 0x14, 0x01, 0x02, 0x3c, 0x14, 0x01, 0x02, 0x40, 0x14, 0x01, 0x02, 0x44, 0x14, 0x01, 0x02, + 0x48, 0x14, 0x01, 0x02, 0x4c, 0x14, 0x01, 0x02, 0xa8, 0x32, 0x02, 0x03, 0xb0, 0x32, 0x02, 0x03, 0xb8, 0x32, 0x02, 0x03, 0xc0, 0x32, 0x02, 0x03, 0x10, 0x0e, 0x03, 0x03, 0x18, 0x0e, 0x03, 0x03, + 0x20, 0x0e, 0x03, 0x03, 0x50, 0x2a, 0x04, 0x04, 0x60, 0x2a, 0x04, 0x04, 0x30, 0x08, 0x05, 0x04, 0x40, 0x08, 0x05, 0x04, 0x80, 0x22, 0x06, 0x05, 0x00, 0x1b, 0x08, 0x06, 0x00, 0x04, 0x10, 0x0a, + 0xf0, 0x25, 0x00, 0x03, 0xf8, 0x25, 0x00, 0x03, 0x00, 0x26, 0x00, 0x03, 0x50, 0x14, 0x01, 0x02, 0x54, 0x14, 0x01, 0x02, 0x58, 0x14, 0x01, 0x02, 0x5c, 0x14, 0x01, 0x02, 0x60, 0x14, 0x01, 0x02, + 0x64, 0x14, 0x01, 0x02, 0x68, 0x14, 0x01, 0x02, 0xc8, 0x32, 0x02, 0x03, 0xd0, 0x32, 0x02, 0x03, 0xd8, 0x32, 0x02, 0x03, 0xe0, 0x32, 0x02, 0x03, 0x28, 0x0e, 0x03, 0x03, 0x30, 0x0e, 0x03, 0x03, + 0x38, 0x0e, 0x03, 0x03, 0x70, 0x2a, 0x04, 0x04, 0x80, 0x2a, 0x04, 0x04, 0x50, 0x08, 0x05, 0x04, 0x60, 0x08, 0x05, 0x04, 0xa0, 0x22, 0x06, 0x05, 0x40, 0x1b, 0x08, 0x06, 0x00, 0x18, 0x11, 0x0b, + 0x08, 0x26, 0x00, 0x03, 0x10, 0x26, 0x00, 0x03, 0x18, 0x26, 0x00, 0x03, 0x6c, 0x14, 0x01, 0x02, 0x70, 0x14, 0x01, 0x02, 0x74, 0x14, 0x01, 0x02, 0x78, 0x14, 0x01, 0x02, 0x7c, 0x14, 0x01, 0x02, + 0x80, 0x14, 0x01, 0x02, 0x84, 0x14, 0x01, 0x02, 0xe8, 0x32, 0x02, 0x03, 0xf0, 0x32, 0x02, 0x03, 0xf8, 0x32, 0x02, 0x03, 0x00, 0x33, 0x02, 0x03, 0x40, 0x0e, 0x03, 0x03, 0x48, 0x0e, 0x03, 0x03, + 0x50, 0x0e, 0x03, 0x03, 0x90, 0x2a, 0x04, 0x04, 0xa0, 0x2a, 0x04, 0x04, 0x70, 0x08, 0x05, 0x04, 0x80, 0x08, 0x05, 0x04, 0xc0, 0x22, 0x06, 0x05, 0x80, 0x1b, 0x08, 0x06, 0x00, 0x30, 0x12, 0x0c, + 0x20, 0x26, 0x00, 0x03, 0x28, 0x26, 0x00, 0x03, 0x30, 0x26, 0x00, 0x03, 0x88, 0x14, 0x01, 0x02, 0x8c, 0x14, 0x01, 0x02, 0x90, 0x14, 0x01, 0x02, 0x94, 0x14, 0x01, 0x02, 0x98, 0x14, 0x01, 0x02, + 0x9c, 0x14, 0x01, 0x02, 0xa0, 0x14, 0x01, 0x02, 0x08, 0x33, 0x02, 0x03, 0x10, 0x33, 0x02, 0x03, 0x18, 0x33, 0x02, 0x03, 0x20, 0x33, 0x02, 0x03, 0x58, 0x0e, 0x03, 0x03, 0x60, 0x0e, 0x03, 0x03, + 0x68, 0x0e, 0x03, 0x03, 0xb0, 0x2a, 0x04, 0x04, 0xc0, 0x2a, 0x04, 0x04, 0x90, 0x08, 0x05, 0x04, 0xa0, 0x08, 0x05, 0x04, 0xe0, 0x22, 0x06, 0x05, 0xc0, 0x1b, 0x08, 0x06, 0x00, 0x00, 0x13, 0x0c, + 0x38, 0x26, 0x00, 0x03, 0x40, 0x26, 0x00, 0x03, 0x48, 0x26, 0x00, 0x03, 0xa4, 0x14, 0x01, 0x02, 0xa8, 0x14, 0x01, 0x02, 0xac, 0x14, 0x01, 0x02, 0xb0, 0x14, 0x01, 0x02, 0xb4, 0x14, 0x01, 0x02, + 0xb8, 0x14, 0x01, 0x02, 0xbc, 0x14, 0x01, 0x02, 0x28, 0x33, 0x02, 0x03, 0x30, 0x33, 0x02, 0x03, 0x38, 0x33, 0x02, 0x03, 0x40, 0x33, 0x02, 0x03, 0x70, 0x0e, 0x03, 0x03, 0x78, 0x0e, 0x03, 0x03, + 0x80, 0x0e, 0x03, 0x03, 0xd0, 0x2a, 0x04, 0x04, 0xe0, 0x2a, 0x04, 0x04, 0xb0, 0x08, 0x05, 0x04, 0xc0, 0x08, 0x05, 0x04, 0x00, 0x23, 0x06, 0x05, 0x00, 0x1c, 0x08, 0x06, 0x50, 0x26, 0x00, 0x03, + 0x58, 0x26, 0x00, 0x03, 0x60, 0x26, 0x00, 0x03, 0x68, 0x26, 0x00, 0x03, 0xc0, 0x14, 0x01, 0x02, 0xc4, 0x14, 0x01, 0x02, 0xc8, 0x14, 0x01, 0x02, 0xcc, 0x14, 0x01, 0x02, 0xd0, 0x14, 0x01, 0x02, + 0xd4, 0x14, 0x01, 0x02, 0xd8, 0x14, 0x01, 0x02, 0x48, 0x33, 0x02, 0x03, 0x50, 0x33, 0x02, 0x03, 0x58, 0x33, 0x02, 0x03, 0x60, 0x33, 0x02, 0x03, 0x88, 0x0e, 0x03, 0x03, 0x90, 0x0e, 0x03, 0x03, + 0x98, 0x0e, 0x03, 0x03, 0xf0, 0x2a, 0x04, 0x04, 0x00, 0x2b, 0x04, 0x04, 0xd0, 0x08, 0x05, 0x04, 0xe0, 0x08, 0x05, 0x04, 0x40, 0x03, 0x07, 0x05, 0x40, 0x1c, 0x08, 0x06, 0x70, 0x26, 0x00, 0x03, + 0x78, 0x26, 0x00, 0x03, 0x80, 0x26, 0x00, 0x03, 0x88, 0x26, 0x00, 0x03, 0xdc, 0x14, 0x01, 0x02, 0xe0, 0x14, 0x01, 0x02, 0xe4, 0x14, 0x01, 0x02, 0xe8, 0x14, 0x01, 0x02, 0xec, 0x14, 0x01, 0x02, + 0xf0, 0x14, 0x01, 0x02, 0xf4, 0x14, 0x01, 0x02, 0x68, 0x33, 0x02, 0x03, 0x70, 0x33, 0x02, 0x03, 0x78, 0x33, 0x02, 0x03, 0x80, 0x33, 0x02, 0x03, 0xa0, 0x0e, 0x03, 0x03, 0xa8, 0x0e, 0x03, 0x03, + 0xb0, 0x0e, 0x03, 0x03, 0x10, 0x2b, 0x04, 0x04, 0x20, 0x2b, 0x04, 0x04, 0xf0, 0x08, 0x05, 0x04, 0x00, 0x09, 0x05, 0x04, 0x60, 0x03, 0x07, 0x05, 0x80, 0x1c, 0x08, 0x06, 0x90, 0x26, 0x00, 0x03, + 0x98, 0x26, 0x00, 0x03, 0xa0, 0x26, 0x00, 0x03, 0xa8, 0x26, 0x00, 0x03, 0xf8, 0x14, 0x01, 0x02, 0xfc, 0x14, 0x01, 0x02, 0x00, 0x15, 0x01, 0x02, 0x04, 0x15, 0x01, 0x02, 0x08, 0x15, 0x01, 0x02, + 0x0c, 0x15, 0x01, 0x02, 0x10, 0x15, 0x01, 0x02, 0x88, 0x33, 0x02, 0x03, 0x90, 0x33, 0x02, 0x03, 0x98, 0x33, 0x02, 0x03, 0xa0, 0x33, 0x02, 0x03, 0xb8, 0x0e, 0x03, 0x03, 0xc0, 0x0e, 0x03, 0x03, + 0xc8, 0x0e, 0x03, 0x03, 0x30, 0x2b, 0x04, 0x04, 0x40, 0x2b, 0x04, 0x04, 0x10, 0x09, 0x05, 0x04, 0x20, 0x09, 0x05, 0x04, 0x80, 0x03, 0x07, 0x05, 0xc0, 0x1c, 0x08, 0x06, 0xb0, 0x26, 0x00, 0x03, + 0xb8, 0x26, 0x00, 0x03, 0xc0, 0x26, 0x00, 0x03, 0xc8, 0x26, 0x00, 0x03, 0x14, 0x15, 0x01, 0x02, 0x18, 0x15, 0x01, 0x02, 0x1c, 0x15, 0x01, 0x02, 0x20, 0x15, 0x01, 0x02, 0x24, 0x15, 0x01, 0x02, + 0x28, 0x15, 0x01, 0x02, 0x2c, 0x15, 0x01, 0x02, 0xa8, 0x33, 0x02, 0x03, 0xb0, 0x33, 0x02, 0x03, 0xb8, 0x33, 0x02, 0x03, 0xc0, 0x33, 0x02, 0x03, 0xd0, 0x0e, 0x03, 0x03, 0xd8, 0x0e, 0x03, 0x03, + 0xe0, 0x0e, 0x03, 0x03, 0x50, 0x2b, 0x04, 0x04, 0x60, 0x2b, 0x04, 0x04, 0x30, 0x09, 0x05, 0x04, 0x40, 0x09, 0x05, 0x04, 0xa0, 0x03, 0x07, 0x05, 0x00, 0x1d, 0x08, 0x06, 0xd0, 0x26, 0x00, 0x03, + 0xd8, 0x26, 0x00, 0x03, 0xe0, 0x26, 0x00, 0x03, 0xe8, 0x26, 0x00, 0x03, 0x30, 0x15, 0x01, 0x02, 0x34, 0x15, 0x01, 0x02, 0x38, 0x15, 0x01, 0x02, 0x3c, 0x15, 0x01, 0x02, 0x40, 0x15, 0x01, 0x02, + 0x44, 0x15, 0x01, 0x02, 0x48, 0x15, 0x01, 0x02, 0xc8, 0x33, 0x02, 0x03, 0xd0, 0x33, 0x02, 0x03, 0xd8, 0x33, 0x02, 0x03, 0xe0, 0x33, 0x02, 0x03, 0xe8, 0x0e, 0x03, 0x03, 0xf0, 0x0e, 0x03, 0x03, + 0xf8, 0x0e, 0x03, 0x03, 0x70, 0x2b, 0x04, 0x04, 0x80, 0x2b, 0x04, 0x04, 0x50, 0x09, 0x05, 0x04, 0x60, 0x09, 0x05, 0x04, 0xc0, 0x03, 0x07, 0x05, 0x40, 0x1d, 0x08, 0x06, 0xf0, 0x26, 0x00, 0x03, + 0xf8, 0x26, 0x00, 0x03, 0x00, 0x27, 0x00, 0x03, 0x08, 0x27, 0x00, 0x03, 0x4c, 0x15, 0x01, 0x02, 0x50, 0x15, 0x01, 0x02, 0x54, 0x15, 0x01, 0x02, 0x58, 0x15, 0x01, 0x02, 0x5c, 0x15, 0x01, 0x02, + 0x60, 0x15, 0x01, 0x02, 0x64, 0x15, 0x01, 0x02, 0xe8, 0x33, 0x02, 0x03, 0xf0, 0x33, 0x02, 0x03, 0xf8, 0x33, 0x02, 0x03, 0x00, 0x34, 0x02, 0x03, 0x00, 0x0f, 0x03, 0x03, 0x08, 0x0f, 0x03, 0x03, + 0x10, 0x0f, 0x03, 0x03, 0x90, 0x2b, 0x04, 0x04, 0xa0, 0x2b, 0x04, 0x04, 0x70, 0x09, 0x05, 0x04, 0x20, 0x23, 0x06, 0x05, 0xe0, 0x03, 0x07, 0x05, 0x80, 0x1d, 0x08, 0x06, 0x10, 0x27, 0x00, 0x03, + 0x18, 0x27, 0x00, 0x03, 0x20, 0x27, 0x00, 0x03, 0x28, 0x27, 0x00, 0x03, 0x68, 0x15, 0x01, 0x02, 0x6c, 0x15, 0x01, 0x02, 0x70, 0x15, 0x01, 0x02, 0x74, 0x15, 0x01, 0x02, 0x78, 0x15, 0x01, 0x02, + 0x7c, 0x15, 0x01, 0x02, 0x80, 0x15, 0x01, 0x02, 0x08, 0x34, 0x02, 0x03, 0x10, 0x34, 0x02, 0x03, 0x18, 0x34, 0x02, 0x03, 0x20, 0x34, 0x02, 0x03, 0x18, 0x0f, 0x03, 0x03, 0x20, 0x0f, 0x03, 0x03, + 0x28, 0x0f, 0x03, 0x03, 0xb0, 0x2b, 0x04, 0x04, 0xc0, 0x2b, 0x04, 0x04, 0x80, 0x09, 0x05, 0x04, 0x40, 0x23, 0x06, 0x05, 0x00, 0x04, 0x07, 0x05, 0x00, 0x3c, 0x09, 0x07, 0x30, 0x27, 0x00, 0x03, + 0x38, 0x27, 0x00, 0x03, 0x40, 0x27, 0x00, 0x03, 0x48, 0x27, 0x00, 0x03, 0x84, 0x15, 0x01, 0x02, 0x88, 0x15, 0x01, 0x02, 0x8c, 0x15, 0x01, 0x02, 0x90, 0x15, 0x01, 0x02, 0x94, 0x15, 0x01, 0x02, + 0x98, 0x15, 0x01, 0x02, 0x9c, 0x15, 0x01, 0x02, 0x28, 0x34, 0x02, 0x03, 0x30, 0x34, 0x02, 0x03, 0x38, 0x34, 0x02, 0x03, 0x40, 0x34, 0x02, 0x03, 0x30, 0x0f, 0x03, 0x03, 0x38, 0x0f, 0x03, 0x03, + 0x40, 0x0f, 0x03, 0x03, 0xd0, 0x2b, 0x04, 0x04, 0xe0, 0x2b, 0x04, 0x04, 0x90, 0x09, 0x05, 0x04, 0x60, 0x23, 0x06, 0x05, 0x20, 0x04, 0x07, 0x05, 0x80, 0x3c, 0x09, 0x07, 0x50, 0x27, 0x00, 0x03, + 0x58, 0x27, 0x00, 0x03, 0x60, 0x27, 0x00, 0x03, 0x68, 0x27, 0x00, 0x03, 0xa0, 0x15, 0x01, 0x02, 0xa4, 0x15, 0x01, 0x02, 0xa8, 0x15, 0x01, 0x02, 0xac, 0x15, 0x01, 0x02, 0xb0, 0x15, 0x01, 0x02, + 0xb4, 0x15, 0x01, 0x02, 0xb8, 0x15, 0x01, 0x02, 0x48, 0x34, 0x02, 0x03, 0x50, 0x34, 0x02, 0x03, 0x58, 0x34, 0x02, 0x03, 0x60, 0x34, 0x02, 0x03, 0x48, 0x0f, 0x03, 0x03, 0x50, 0x0f, 0x03, 0x03, + 0x58, 0x0f, 0x03, 0x03, 0xf0, 0x2b, 0x04, 0x04, 0x00, 0x2c, 0x04, 0x04, 0xa0, 0x09, 0x05, 0x04, 0x80, 0x23, 0x06, 0x05, 0x40, 0x04, 0x07, 0x05, 0x00, 0x3d, 0x09, 0x07, 0x70, 0x27, 0x00, 0x03, + 0x78, 0x27, 0x00, 0x03, 0x80, 0x27, 0x00, 0x03, 0x88, 0x27, 0x00, 0x03, 0xbc, 0x15, 0x01, 0x02, 0xc0, 0x15, 0x01, 0x02, 0xc4, 0x15, 0x01, 0x02, 0xc8, 0x15, 0x01, 0x02, 0xcc, 0x15, 0x01, 0x02, + 0xd0, 0x15, 0x01, 0x02, 0xd4, 0x15, 0x01, 0x02, 0x68, 0x34, 0x02, 0x03, 0x70, 0x34, 0x02, 0x03, 0x78, 0x34, 0x02, 0x03, 0x80, 0x34, 0x02, 0x03, 0x60, 0x0f, 0x03, 0x03, 0x68, 0x0f, 0x03, 0x03, + 0x70, 0x0f, 0x03, 0x03, 0x10, 0x2c, 0x04, 0x04, 0x20, 0x2c, 0x04, 0x04, 0xb0, 0x09, 0x05, 0x04, 0xa0, 0x23, 0x06, 0x05, 0x60, 0x04, 0x07, 0x05, 0x80, 0x3d, 0x09, 0x07, 0x90, 0x27, 0x00, 0x03, + 0x98, 0x27, 0x00, 0x03, 0xa0, 0x27, 0x00, 0x03, 0xa8, 0x27, 0x00, 0x03, 0xd8, 0x15, 0x01, 0x02, 0xdc, 0x15, 0x01, 0x02, 0xe0, 0x15, 0x01, 0x02, 0xe4, 0x15, 0x01, 0x02, 0xe8, 0x15, 0x01, 0x02, + 0xec, 0x15, 0x01, 0x02, 0xf0, 0x15, 0x01, 0x02, 0x88, 0x34, 0x02, 0x03, 0x90, 0x34, 0x02, 0x03, 0x98, 0x34, 0x02, 0x03, 0xa0, 0x34, 0x02, 0x03, 0x78, 0x0f, 0x03, 0x03, 0x80, 0x0f, 0x03, 0x03, + 0x88, 0x0f, 0x03, 0x03, 0x30, 0x2c, 0x04, 0x04, 0x40, 0x2c, 0x04, 0x04, 0xc0, 0x09, 0x05, 0x04, 0xc0, 0x23, 0x06, 0x05, 0x80, 0x04, 0x07, 0x05, 0x00, 0x3e, 0x09, 0x07, 0xb0, 0x27, 0x00, 0x03, + 0xb8, 0x27, 0x00, 0x03, 0xc0, 0x27, 0x00, 0x03, 0xc8, 0x27, 0x00, 0x03, 0xf4, 0x15, 0x01, 0x02, 0xf8, 0x15, 0x01, 0x02, 0xfc, 0x15, 0x01, 0x02, 0x00, 0x16, 0x01, 0x02, 0x04, 0x16, 0x01, 0x02, + 0x08, 0x16, 0x01, 0x02, 0x0c, 0x16, 0x01, 0x02, 0xa8, 0x34, 0x02, 0x03, 0xb0, 0x34, 0x02, 0x03, 0xb8, 0x34, 0x02, 0x03, 0xc0, 0x34, 0x02, 0x03, 0x90, 0x0f, 0x03, 0x03, 0x98, 0x0f, 0x03, 0x03, + 0xa0, 0x0f, 0x03, 0x03, 0x50, 0x2c, 0x04, 0x04, 0x60, 0x2c, 0x04, 0x04, 0xd0, 0x09, 0x05, 0x04, 0xe0, 0x23, 0x06, 0x05, 0xa0, 0x04, 0x07, 0x05, 0x80, 0x3e, 0x09, 0x07, 0xd0, 0x27, 0x00, 0x03, + 0xd8, 0x27, 0x00, 0x03, 0xe0, 0x27, 0x00, 0x03, 0xe8, 0x27, 0x00, 0x03, 0x10, 0x16, 0x01, 0x02, 0x14, 0x16, 0x01, 0x02, 0x18, 0x16, 0x01, 0x02, 0x1c, 0x16, 0x01, 0x02, 0x20, 0x16, 0x01, 0x02, + 0x24, 0x16, 0x01, 0x02, 0x28, 0x16, 0x01, 0x02, 0xc8, 0x34, 0x02, 0x03, 0xd0, 0x34, 0x02, 0x03, 0xd8, 0x34, 0x02, 0x03, 0xe0, 0x34, 0x02, 0x03, 0xa8, 0x0f, 0x03, 0x03, 0xb0, 0x0f, 0x03, 0x03, + 0xb8, 0x0f, 0x03, 0x03, 0x70, 0x2c, 0x04, 0x04, 0x80, 0x2c, 0x04, 0x04, 0xe0, 0x09, 0x05, 0x04, 0x00, 0x24, 0x06, 0x05, 0xc0, 0x04, 0x07, 0x05, 0x00, 0x3f, 0x09, 0x07, 0xf0, 0x27, 0x00, 0x03, + 0xf8, 0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x03, 0x08, 0x28, 0x00, 0x03, 0x2c, 0x16, 0x01, 0x02, 0x30, 0x16, 0x01, 0x02, 0x34, 0x16, 0x01, 0x02, 0x38, 0x16, 0x01, 0x02, 0x3c, 0x16, 0x01, 0x02, + 0x40, 0x16, 0x01, 0x02, 0x44, 0x16, 0x01, 0x02, 0xe8, 0x34, 0x02, 0x03, 0xf0, 0x34, 0x02, 0x03, 0xf8, 0x34, 0x02, 0x03, 0x00, 0x35, 0x02, 0x03, 0xc0, 0x0f, 0x03, 0x03, 0xc8, 0x0f, 0x03, 0x03, + 0xd0, 0x0f, 0x03, 0x03, 0x90, 0x2c, 0x04, 0x04, 0xa0, 0x2c, 0x04, 0x04, 0xf0, 0x09, 0x05, 0x04, 0x20, 0x24, 0x06, 0x05, 0xe0, 0x04, 0x07, 0x05, 0x80, 0x3f, 0x09, 0x07, 0x10, 0x28, 0x00, 0x03, + 0x18, 0x28, 0x00, 0x03, 0x20, 0x28, 0x00, 0x03, 0x28, 0x28, 0x00, 0x03, 0x48, 0x16, 0x01, 0x02, 0x4c, 0x16, 0x01, 0x02, 0x50, 0x16, 0x01, 0x02, 0x54, 0x16, 0x01, 0x02, 0x58, 0x16, 0x01, 0x02, + 0x5c, 0x16, 0x01, 0x02, 0x60, 0x16, 0x01, 0x02, 0x08, 0x35, 0x02, 0x03, 0x10, 0x35, 0x02, 0x03, 0x18, 0x35, 0x02, 0x03, 0x20, 0x35, 0x02, 0x03, 0xd8, 0x0f, 0x03, 0x03, 0xe0, 0x0f, 0x03, 0x03, + 0xe8, 0x0f, 0x03, 0x03, 0xb0, 0x2c, 0x04, 0x04, 0xc0, 0x2c, 0x04, 0x04, 0x00, 0x0a, 0x05, 0x04, 0x40, 0x24, 0x06, 0x05, 0x00, 0x05, 0x07, 0x05, 0x00, 0x00, 0x09, 0x06, 0x30, 0x28, 0x00, 0x03, + 0x38, 0x28, 0x00, 0x03, 0x40, 0x28, 0x00, 0x03, 0x48, 0x28, 0x00, 0x03, 0x64, 0x16, 0x01, 0x02, 0x68, 0x16, 0x01, 0x02, 0x6c, 0x16, 0x01, 0x02, 0x70, 0x16, 0x01, 0x02, 0x74, 0x16, 0x01, 0x02, + 0x78, 0x16, 0x01, 0x02, 0x7c, 0x16, 0x01, 0x02, 0x28, 0x35, 0x02, 0x03, 0x30, 0x35, 0x02, 0x03, 0x38, 0x35, 0x02, 0x03, 0x40, 0x35, 0x02, 0x03, 0xf0, 0x0f, 0x03, 0x03, 0xf8, 0x0f, 0x03, 0x03, + 0x00, 0x10, 0x03, 0x03, 0xd0, 0x2c, 0x04, 0x04, 0xe0, 0x2c, 0x04, 0x04, 0x10, 0x0a, 0x05, 0x04, 0x60, 0x24, 0x06, 0x05, 0x20, 0x05, 0x07, 0x05, 0x40, 0x00, 0x09, 0x06, 0x50, 0x28, 0x00, 0x03, + 0x58, 0x28, 0x00, 0x03, 0x60, 0x28, 0x00, 0x03, 0x68, 0x28, 0x00, 0x03, 0x80, 0x16, 0x01, 0x02, 0x84, 0x16, 0x01, 0x02, 0x88, 0x16, 0x01, 0x02, 0x8c, 0x16, 0x01, 0x02, 0x90, 0x16, 0x01, 0x02, + 0x94, 0x16, 0x01, 0x02, 0x98, 0x16, 0x01, 0x02, 0x48, 0x35, 0x02, 0x03, 0x50, 0x35, 0x02, 0x03, 0x58, 0x35, 0x02, 0x03, 0x60, 0x35, 0x02, 0x03, 0x08, 0x10, 0x03, 0x03, 0x10, 0x10, 0x03, 0x03, + 0x18, 0x10, 0x03, 0x03, 0xf0, 0x2c, 0x04, 0x04, 0x00, 0x2d, 0x04, 0x04, 0x20, 0x0a, 0x05, 0x04, 0x80, 0x24, 0x06, 0x05, 0x40, 0x05, 0x07, 0x05, 0x80, 0x00, 0x09, 0x06, 0x70, 0x28, 0x00, 0x03, + 0x78, 0x28, 0x00, 0x03, 0x80, 0x28, 0x00, 0x03, 0x88, 0x28, 0x00, 0x03, 0x9c, 0x16, 0x01, 0x02, 0xa0, 0x16, 0x01, 0x02, 0xa4, 0x16, 0x01, 0x02, 0xa8, 0x16, 0x01, 0x02, 0xac, 0x16, 0x01, 0x02, + 0xb0, 0x16, 0x01, 0x02, 0xb4, 0x16, 0x01, 0x02, 0x68, 0x35, 0x02, 0x03, 0x70, 0x35, 0x02, 0x03, 0x78, 0x35, 0x02, 0x03, 0x80, 0x35, 0x02, 0x03, 0x20, 0x10, 0x03, 0x03, 0x28, 0x10, 0x03, 0x03, + 0x30, 0x10, 0x03, 0x03, 0x10, 0x2d, 0x04, 0x04, 0x20, 0x2d, 0x04, 0x04, 0x30, 0x0a, 0x05, 0x04, 0xa0, 0x24, 0x06, 0x05, 0x60, 0x05, 0x07, 0x05, 0xc0, 0x00, 0x09, 0x06, 0x90, 0x28, 0x00, 0x03, + 0x98, 0x28, 0x00, 0x03, 0xa0, 0x28, 0x00, 0x03, 0xa8, 0x28, 0x00, 0x03, 0xb8, 0x16, 0x01, 0x02, 0xbc, 0x16, 0x01, 0x02, 0xc0, 0x16, 0x01, 0x02, 0xc4, 0x16, 0x01, 0x02, 0xc8, 0x16, 0x01, 0x02, + 0xcc, 0x16, 0x01, 0x02, 0xd0, 0x16, 0x01, 0x02, 0x88, 0x35, 0x02, 0x03, 0x90, 0x35, 0x02, 0x03, 0x98, 0x35, 0x02, 0x03, 0xa0, 0x35, 0x02, 0x03, 0x38, 0x10, 0x03, 0x03, 0x40, 0x10, 0x03, 0x03, + 0x48, 0x10, 0x03, 0x03, 0x30, 0x2d, 0x04, 0x04, 0x40, 0x2d, 0x04, 0x04, 0x40, 0x0a, 0x05, 0x04, 0xc0, 0x24, 0x06, 0x05, 0x80, 0x05, 0x07, 0x05, 0x00, 0x01, 0x09, 0x06, 0xb0, 0x28, 0x00, 0x03, + 0xb8, 0x28, 0x00, 0x03, 0xc0, 0x28, 0x00, 0x03, 0xc8, 0x28, 0x00, 0x03, 0xd4, 0x16, 0x01, 0x02, 0xd8, 0x16, 0x01, 0x02, 0xdc, 0x16, 0x01, 0x02, 0xe0, 0x16, 0x01, 0x02, 0xe4, 0x16, 0x01, 0x02, + 0xe8, 0x16, 0x01, 0x02, 0xec, 0x16, 0x01, 0x02, 0xa8, 0x35, 0x02, 0x03, 0xb0, 0x35, 0x02, 0x03, 0xb8, 0x35, 0x02, 0x03, 0xc0, 0x35, 0x02, 0x03, 0x50, 0x10, 0x03, 0x03, 0x58, 0x10, 0x03, 0x03, + 0x60, 0x10, 0x03, 0x03, 0x50, 0x2d, 0x04, 0x04, 0x60, 0x2d, 0x04, 0x04, 0x50, 0x0a, 0x05, 0x04, 0xe0, 0x24, 0x06, 0x05, 0xa0, 0x05, 0x07, 0x05, 0x40, 0x01, 0x09, 0x06, 0xd0, 0x28, 0x00, 0x03, + 0xd8, 0x28, 0x00, 0x03, 0xe0, 0x28, 0x00, 0x03, 0xe8, 0x28, 0x00, 0x03, 0xf0, 0x16, 0x01, 0x02, 0xf4, 0x16, 0x01, 0x02, 0xf8, 0x16, 0x01, 0x02, 0xfc, 0x16, 0x01, 0x02, 0x00, 0x17, 0x01, 0x02, + 0x04, 0x17, 0x01, 0x02, 0x08, 0x17, 0x01, 0x02, 0xc8, 0x35, 0x02, 0x03, 0xd0, 0x35, 0x02, 0x03, 0xd8, 0x35, 0x02, 0x03, 0xe0, 0x35, 0x02, 0x03, 0x68, 0x10, 0x03, 0x03, 0x70, 0x10, 0x03, 0x03, + 0x78, 0x10, 0x03, 0x03, 0x70, 0x2d, 0x04, 0x04, 0x80, 0x2d, 0x04, 0x04, 0x60, 0x0a, 0x05, 0x04, 0x00, 0x25, 0x06, 0x05, 0xc0, 0x05, 0x07, 0x05, 0x80, 0x01, 0x09, 0x06, 0xf0, 0x28, 0x00, 0x03, + 0xf8, 0x28, 0x00, 0x03, 0x00, 0x29, 0x00, 0x03, 0x08, 0x29, 0x00, 0x03, 0x0c, 0x17, 0x01, 0x02, 0x10, 0x17, 0x01, 0x02, 0x14, 0x17, 0x01, 0x02, 0x18, 0x17, 0x01, 0x02, 0x1c, 0x17, 0x01, 0x02, + 0x20, 0x17, 0x01, 0x02, 0x24, 0x17, 0x01, 0x02, 0xe8, 0x35, 0x02, 0x03, 0xf0, 0x35, 0x02, 0x03, 0xf8, 0x35, 0x02, 0x03, 0x00, 0x36, 0x02, 0x03, 0x80, 0x10, 0x03, 0x03, 0x88, 0x10, 0x03, 0x03, + 0x90, 0x10, 0x03, 0x03, 0x90, 0x2d, 0x04, 0x04, 0xa0, 0x2d, 0x04, 0x04, 0x70, 0x0a, 0x05, 0x04, 0x20, 0x25, 0x06, 0x05, 0xe0, 0x05, 0x07, 0x05, 0xc0, 0x01, 0x09, 0x06, 0x10, 0x29, 0x00, 0x03, + 0x18, 0x29, 0x00, 0x03, 0x20, 0x29, 0x00, 0x03, 0x28, 0x29, 0x00, 0x03, 0x28, 0x17, 0x01, 0x02, 0x2c, 0x17, 0x01, 0x02, 0x30, 0x17, 0x01, 0x02, 0x34, 0x17, 0x01, 0x02, 0x38, 0x17, 0x01, 0x02, + 0x3c, 0x17, 0x01, 0x02, 0x40, 0x17, 0x01, 0x02, 0x08, 0x36, 0x02, 0x03, 0x10, 0x36, 0x02, 0x03, 0x18, 0x36, 0x02, 0x03, 0x20, 0x36, 0x02, 0x03, 0x98, 0x10, 0x03, 0x03, 0xa0, 0x10, 0x03, 0x03, + 0xa8, 0x10, 0x03, 0x03, 0xb0, 0x2d, 0x04, 0x04, 0xc0, 0x2d, 0x04, 0x04, 0x80, 0x0a, 0x05, 0x04, 0x40, 0x25, 0x06, 0x05, 0x00, 0x06, 0x07, 0x05, 0x00, 0x02, 0x09, 0x06, 0x30, 0x29, 0x00, 0x03, + 0x38, 0x29, 0x00, 0x03, 0x40, 0x29, 0x00, 0x03, 0x48, 0x29, 0x00, 0x03, 0x44, 0x17, 0x01, 0x02, 0x48, 0x17, 0x01, 0x02, 0x4c, 0x17, 0x01, 0x02, 0x50, 0x17, 0x01, 0x02, 0x54, 0x17, 0x01, 0x02, + 0x58, 0x17, 0x01, 0x02, 0x5c, 0x17, 0x01, 0x02, 0x28, 0x36, 0x02, 0x03, 0x30, 0x36, 0x02, 0x03, 0x38, 0x36, 0x02, 0x03, 0x40, 0x36, 0x02, 0x03, 0xb0, 0x10, 0x03, 0x03, 0xb8, 0x10, 0x03, 0x03, + 0xc0, 0x10, 0x03, 0x03, 0xd0, 0x2d, 0x04, 0x04, 0xe0, 0x2d, 0x04, 0x04, 0x90, 0x0a, 0x05, 0x04, 0x60, 0x25, 0x06, 0x05, 0x20, 0x06, 0x07, 0x05, 0x40, 0x02, 0x09, 0x06, 0x50, 0x29, 0x00, 0x03, + 0x58, 0x29, 0x00, 0x03, 0x60, 0x29, 0x00, 0x03, 0x68, 0x29, 0x00, 0x03, 0x60, 0x17, 0x01, 0x02, 0x64, 0x17, 0x01, 0x02, 0x68, 0x17, 0x01, 0x02, 0x6c, 0x17, 0x01, 0x02, 0x70, 0x17, 0x01, 0x02, + 0x74, 0x17, 0x01, 0x02, 0x78, 0x17, 0x01, 0x02, 0x48, 0x36, 0x02, 0x03, 0x50, 0x36, 0x02, 0x03, 0x58, 0x36, 0x02, 0x03, 0x60, 0x36, 0x02, 0x03, 0xc8, 0x10, 0x03, 0x03, 0xd0, 0x10, 0x03, 0x03, + 0xd8, 0x10, 0x03, 0x03, 0xf0, 0x2d, 0x04, 0x04, 0x00, 0x2e, 0x04, 0x04, 0xa0, 0x0a, 0x05, 0x04, 0x80, 0x25, 0x06, 0x05, 0x40, 0x06, 0x07, 0x05, 0x80, 0x02, 0x09, 0x06, 0x70, 0x29, 0x00, 0x03, + 0x78, 0x29, 0x00, 0x03, 0x80, 0x29, 0x00, 0x03, 0x88, 0x29, 0x00, 0x03, 0x7c, 0x17, 0x01, 0x02, 0x80, 0x17, 0x01, 0x02, 0x84, 0x17, 0x01, 0x02, 0x88, 0x17, 0x01, 0x02, 0x8c, 0x17, 0x01, 0x02, + 0x90, 0x17, 0x01, 0x02, 0x68, 0x36, 0x02, 0x03, 0x70, 0x36, 0x02, 0x03, 0x78, 0x36, 0x02, 0x03, 0x80, 0x36, 0x02, 0x03, 0x88, 0x36, 0x02, 0x03, 0xe0, 0x10, 0x03, 0x03, 0xe8, 0x10, 0x03, 0x03, + 0xf0, 0x10, 0x03, 0x03, 0x10, 0x2e, 0x04, 0x04, 0x20, 0x2e, 0x04, 0x04, 0xb0, 0x0a, 0x05, 0x04, 0xa0, 0x25, 0x06, 0x05, 0x60, 0x06, 0x07, 0x05, 0xc0, 0x02, 0x09, 0x06, 0x90, 0x29, 0x00, 0x03, + 0x98, 0x29, 0x00, 0x03, 0xa0, 0x29, 0x00, 0x03, 0xa8, 0x29, 0x00, 0x03, 0x94, 0x17, 0x01, 0x02, 0x98, 0x17, 0x01, 0x02, 0x9c, 0x17, 0x01, 0x02, 0xa0, 0x17, 0x01, 0x02, 0xa4, 0x17, 0x01, 0x02, + 0xa8, 0x17, 0x01, 0x02, 0x90, 0x36, 0x02, 0x03, 0x98, 0x36, 0x02, 0x03, 0xa0, 0x36, 0x02, 0x03, 0xa8, 0x36, 0x02, 0x03, 0xb0, 0x36, 0x02, 0x03, 0xf8, 0x10, 0x03, 0x03, 0x00, 0x11, 0x03, 0x03, + 0x08, 0x11, 0x03, 0x03, 0x30, 0x2e, 0x04, 0x04, 0x40, 0x2e, 0x04, 0x04, 0xc0, 0x0a, 0x05, 0x04, 0xc0, 0x25, 0x06, 0x05, 0x80, 0x06, 0x07, 0x05, 0x00, 0x03, 0x09, 0x06, 0xb0, 0x29, 0x00, 0x03, + 0xb8, 0x29, 0x00, 0x03, 0xc0, 0x29, 0x00, 0x03, 0xc8, 0x29, 0x00, 0x03, 0xac, 0x17, 0x01, 0x02, 0xb0, 0x17, 0x01, 0x02, 0xb4, 0x17, 0x01, 0x02, 0xb8, 0x17, 0x01, 0x02, 0xbc, 0x17, 0x01, 0x02, + 0xc0, 0x17, 0x01, 0x02, 0xb8, 0x36, 0x02, 0x03, 0xc0, 0x36, 0x02, 0x03, 0xc8, 0x36, 0x02, 0x03, 0xd0, 0x36, 0x02, 0x03, 0xd8, 0x36, 0x02, 0x03, 0x10, 0x11, 0x03, 0x03, 0x18, 0x11, 0x03, 0x03, + 0x20, 0x11, 0x03, 0x03, 0x50, 0x2e, 0x04, 0x04, 0x60, 0x2e, 0x04, 0x04, 0xd0, 0x0a, 0x05, 0x04, 0xe0, 0x25, 0x06, 0x05, 0xa0, 0x06, 0x07, 0x05, 0x40, 0x03, 0x09, 0x06, 0xd0, 0x29, 0x00, 0x03, + 0xd8, 0x29, 0x00, 0x03, 0xe0, 0x29, 0x00, 0x03, 0xe8, 0x29, 0x00, 0x03, 0xc4, 0x17, 0x01, 0x02, 0xc8, 0x17, 0x01, 0x02, 0xcc, 0x17, 0x01, 0x02, 0xd0, 0x17, 0x01, 0x02, 0xd4, 0x17, 0x01, 0x02, + 0xd8, 0x17, 0x01, 0x02, 0xe0, 0x36, 0x02, 0x03, 0xe8, 0x36, 0x02, 0x03, 0xf0, 0x36, 0x02, 0x03, 0xf8, 0x36, 0x02, 0x03, 0x00, 0x37, 0x02, 0x03, 0x28, 0x11, 0x03, 0x03, 0x30, 0x11, 0x03, 0x03, + 0x38, 0x11, 0x03, 0x03, 0x70, 0x2e, 0x04, 0x04, 0x80, 0x2e, 0x04, 0x04, 0xe0, 0x0a, 0x05, 0x04, 0x00, 0x26, 0x06, 0x05, 0xc0, 0x06, 0x07, 0x05, 0x80, 0x03, 0x09, 0x06, 0xf0, 0x29, 0x00, 0x03, + 0xf8, 0x29, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x03, 0x08, 0x2a, 0x00, 0x03, 0xdc, 0x17, 0x01, 0x02, 0xe0, 0x17, 0x01, 0x02, 0xe4, 0x17, 0x01, 0x02, 0xe8, 0x17, 0x01, 0x02, 0xec, 0x17, 0x01, 0x02, + 0xf0, 0x17, 0x01, 0x02, 0x08, 0x37, 0x02, 0x03, 0x10, 0x37, 0x02, 0x03, 0x18, 0x37, 0x02, 0x03, 0x20, 0x37, 0x02, 0x03, 0x28, 0x37, 0x02, 0x03, 0x40, 0x11, 0x03, 0x03, 0x48, 0x11, 0x03, 0x03, + 0x50, 0x11, 0x03, 0x03, 0x90, 0x2e, 0x04, 0x04, 0xa0, 0x2e, 0x04, 0x04, 0xf0, 0x0a, 0x05, 0x04, 0x20, 0x26, 0x06, 0x05, 0xe0, 0x06, 0x07, 0x05, 0xc0, 0x03, 0x09, 0x06, 0x10, 0x2a, 0x00, 0x03, + 0x18, 0x2a, 0x00, 0x03, 0x20, 0x2a, 0x00, 0x03, 0x28, 0x2a, 0x00, 0x03, 0xf4, 0x17, 0x01, 0x02, 0xf8, 0x17, 0x01, 0x02, 0xfc, 0x17, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x04, 0x18, 0x01, 0x02, + 0x08, 0x18, 0x01, 0x02, 0x30, 0x37, 0x02, 0x03, 0x38, 0x37, 0x02, 0x03, 0x40, 0x37, 0x02, 0x03, 0x48, 0x37, 0x02, 0x03, 0x50, 0x37, 0x02, 0x03, 0x58, 0x11, 0x03, 0x03, 0x60, 0x11, 0x03, 0x03, + 0x68, 0x11, 0x03, 0x03, 0xb0, 0x2e, 0x04, 0x04, 0xc0, 0x2e, 0x04, 0x04, 0x00, 0x0b, 0x05, 0x04, 0x40, 0x26, 0x06, 0x05, 0x00, 0x07, 0x07, 0x05, 0x00, 0x04, 0x09, 0x06, 0x30, 0x2a, 0x00, 0x03, + 0x38, 0x2a, 0x00, 0x03, 0x40, 0x2a, 0x00, 0x03, 0x48, 0x2a, 0x00, 0x03, 0x0c, 0x18, 0x01, 0x02, 0x10, 0x18, 0x01, 0x02, 0x14, 0x18, 0x01, 0x02, 0x18, 0x18, 0x01, 0x02, 0x1c, 0x18, 0x01, 0x02, + 0x20, 0x18, 0x01, 0x02, 0x58, 0x37, 0x02, 0x03, 0x60, 0x37, 0x02, 0x03, 0x68, 0x37, 0x02, 0x03, 0x70, 0x37, 0x02, 0x03, 0x78, 0x37, 0x02, 0x03, 0x70, 0x11, 0x03, 0x03, 0x78, 0x11, 0x03, 0x03, + 0x80, 0x11, 0x03, 0x03, 0xd0, 0x2e, 0x04, 0x04, 0xe0, 0x2e, 0x04, 0x04, 0x10, 0x0b, 0x05, 0x04, 0x60, 0x26, 0x06, 0x05, 0x20, 0x07, 0x07, 0x05, 0x00, 0x15, 0x0a, 0x07, 0x50, 0x2a, 0x00, 0x03, + 0x58, 0x2a, 0x00, 0x03, 0x60, 0x2a, 0x00, 0x03, 0x68, 0x2a, 0x00, 0x03, 0x24, 0x18, 0x01, 0x02, 0x28, 0x18, 0x01, 0x02, 0x2c, 0x18, 0x01, 0x02, 0x30, 0x18, 0x01, 0x02, 0x34, 0x18, 0x01, 0x02, + 0x38, 0x18, 0x01, 0x02, 0x80, 0x37, 0x02, 0x03, 0x88, 0x37, 0x02, 0x03, 0x90, 0x37, 0x02, 0x03, 0x98, 0x37, 0x02, 0x03, 0xa0, 0x37, 0x02, 0x03, 0x88, 0x11, 0x03, 0x03, 0x90, 0x11, 0x03, 0x03, + 0x98, 0x11, 0x03, 0x03, 0xf0, 0x2e, 0x04, 0x04, 0x00, 0x2f, 0x04, 0x04, 0x20, 0x0b, 0x05, 0x04, 0x80, 0x26, 0x06, 0x05, 0x40, 0x07, 0x07, 0x05, 0x80, 0x15, 0x0a, 0x07, 0x70, 0x2a, 0x00, 0x03, + 0x78, 0x2a, 0x00, 0x03, 0x80, 0x2a, 0x00, 0x03, 0x88, 0x2a, 0x00, 0x03, 0x3c, 0x18, 0x01, 0x02, 0x40, 0x18, 0x01, 0x02, 0x44, 0x18, 0x01, 0x02, 0x48, 0x18, 0x01, 0x02, 0x4c, 0x18, 0x01, 0x02, + 0x50, 0x18, 0x01, 0x02, 0xa8, 0x37, 0x02, 0x03, 0xb0, 0x37, 0x02, 0x03, 0xb8, 0x37, 0x02, 0x03, 0xc0, 0x37, 0x02, 0x03, 0xc8, 0x37, 0x02, 0x03, 0xa0, 0x11, 0x03, 0x03, 0xa8, 0x11, 0x03, 0x03, + 0xb0, 0x11, 0x03, 0x03, 0x10, 0x2f, 0x04, 0x04, 0x20, 0x2f, 0x04, 0x04, 0x30, 0x0b, 0x05, 0x04, 0xa0, 0x26, 0x06, 0x05, 0x60, 0x07, 0x07, 0x05, 0x00, 0x16, 0x0a, 0x07, 0x90, 0x2a, 0x00, 0x03, + 0x98, 0x2a, 0x00, 0x03, 0xa0, 0x2a, 0x00, 0x03, 0xa8, 0x2a, 0x00, 0x03, 0x54, 0x18, 0x01, 0x02, 0x58, 0x18, 0x01, 0x02, 0x5c, 0x18, 0x01, 0x02, 0x60, 0x18, 0x01, 0x02, 0x64, 0x18, 0x01, 0x02, + 0x68, 0x18, 0x01, 0x02, 0xd0, 0x37, 0x02, 0x03, 0xd8, 0x37, 0x02, 0x03, 0xe0, 0x37, 0x02, 0x03, 0xe8, 0x37, 0x02, 0x03, 0xf0, 0x37, 0x02, 0x03, 0xb8, 0x11, 0x03, 0x03, 0xc0, 0x11, 0x03, 0x03, + 0xc8, 0x11, 0x03, 0x03, 0x30, 0x2f, 0x04, 0x04, 0x40, 0x2f, 0x04, 0x04, 0x40, 0x0b, 0x05, 0x04, 0xc0, 0x26, 0x06, 0x05, 0x80, 0x07, 0x07, 0x05, 0x80, 0x16, 0x0a, 0x07, 0xb0, 0x2a, 0x00, 0x03, + 0xb8, 0x2a, 0x00, 0x03, 0xc0, 0x2a, 0x00, 0x03, 0xc8, 0x2a, 0x00, 0x03, 0x6c, 0x18, 0x01, 0x02, 0x70, 0x18, 0x01, 0x02, 0x74, 0x18, 0x01, 0x02, 0x78, 0x18, 0x01, 0x02, 0x7c, 0x18, 0x01, 0x02, + 0x80, 0x18, 0x01, 0x02, 0xf8, 0x37, 0x02, 0x03, 0x00, 0x38, 0x02, 0x03, 0x08, 0x38, 0x02, 0x03, 0x10, 0x38, 0x02, 0x03, 0x18, 0x38, 0x02, 0x03, 0xd0, 0x11, 0x03, 0x03, 0xd8, 0x11, 0x03, 0x03, + 0xe0, 0x11, 0x03, 0x03, 0x50, 0x2f, 0x04, 0x04, 0x60, 0x2f, 0x04, 0x04, 0x50, 0x0b, 0x05, 0x04, 0xe0, 0x26, 0x06, 0x05, 0xa0, 0x07, 0x07, 0x05, 0x00, 0x17, 0x0a, 0x07, 0xd0, 0x2a, 0x00, 0x03, + 0xd8, 0x2a, 0x00, 0x03, 0xe0, 0x2a, 0x00, 0x03, 0xe8, 0x2a, 0x00, 0x03, 0x84, 0x18, 0x01, 0x02, 0x88, 0x18, 0x01, 0x02, 0x8c, 0x18, 0x01, 0x02, 0x90, 0x18, 0x01, 0x02, 0x94, 0x18, 0x01, 0x02, + 0x98, 0x18, 0x01, 0x02, 0x20, 0x38, 0x02, 0x03, 0x28, 0x38, 0x02, 0x03, 0x30, 0x38, 0x02, 0x03, 0x38, 0x38, 0x02, 0x03, 0x40, 0x38, 0x02, 0x03, 0xe8, 0x11, 0x03, 0x03, 0xf0, 0x11, 0x03, 0x03, + 0xf8, 0x11, 0x03, 0x03, 0x70, 0x2f, 0x04, 0x04, 0x80, 0x2f, 0x04, 0x04, 0x60, 0x0b, 0x05, 0x04, 0x00, 0x27, 0x06, 0x05, 0xc0, 0x07, 0x07, 0x05, 0x80, 0x17, 0x0a, 0x07, 0xf0, 0x2a, 0x00, 0x03, + 0xf8, 0x2a, 0x00, 0x03, 0x00, 0x2b, 0x00, 0x03, 0x08, 0x2b, 0x00, 0x03, 0x9c, 0x18, 0x01, 0x02, 0xa0, 0x18, 0x01, 0x02, 0xa4, 0x18, 0x01, 0x02, 0xa8, 0x18, 0x01, 0x02, 0xac, 0x18, 0x01, 0x02, + 0xb0, 0x18, 0x01, 0x02, 0x48, 0x38, 0x02, 0x03, 0x50, 0x38, 0x02, 0x03, 0x58, 0x38, 0x02, 0x03, 0x60, 0x38, 0x02, 0x03, 0x68, 0x38, 0x02, 0x03, 0x00, 0x12, 0x03, 0x03, 0x08, 0x12, 0x03, 0x03, + 0x10, 0x12, 0x03, 0x03, 0x90, 0x2f, 0x04, 0x04, 0xa0, 0x2f, 0x04, 0x04, 0x70, 0x0b, 0x05, 0x04, 0x20, 0x27, 0x06, 0x05, 0xe0, 0x07, 0x07, 0x05, 0x00, 0x18, 0x0a, 0x07, 0x10, 0x2b, 0x00, 0x03, + 0x18, 0x2b, 0x00, 0x03, 0x20, 0x2b, 0x00, 0x03, 0x28, 0x2b, 0x00, 0x03, 0xb4, 0x18, 0x01, 0x02, 0xb8, 0x18, 0x01, 0x02, 0xbc, 0x18, 0x01, 0x02, 0xc0, 0x18, 0x01, 0x02, 0xc4, 0x18, 0x01, 0x02, + 0xc8, 0x18, 0x01, 0x02, 0x70, 0x38, 0x02, 0x03, 0x78, 0x38, 0x02, 0x03, 0x80, 0x38, 0x02, 0x03, 0x88, 0x38, 0x02, 0x03, 0x90, 0x38, 0x02, 0x03, 0x18, 0x12, 0x03, 0x03, 0x20, 0x12, 0x03, 0x03, + 0x28, 0x12, 0x03, 0x03, 0xb0, 0x2f, 0x04, 0x04, 0xc0, 0x2f, 0x04, 0x04, 0x80, 0x0b, 0x05, 0x04, 0x40, 0x27, 0x06, 0x05, 0x00, 0x08, 0x07, 0x05, 0x80, 0x18, 0x0a, 0x07, 0x30, 0x2b, 0x00, 0x03, + 0x38, 0x2b, 0x00, 0x03, 0x40, 0x2b, 0x00, 0x03, 0x48, 0x2b, 0x00, 0x03, 0xcc, 0x18, 0x01, 0x02, 0xd0, 0x18, 0x01, 0x02, 0xd4, 0x18, 0x01, 0x02, 0xd8, 0x18, 0x01, 0x02, 0xdc, 0x18, 0x01, 0x02, + 0xe0, 0x18, 0x01, 0x02, 0x98, 0x38, 0x02, 0x03, 0xa0, 0x38, 0x02, 0x03, 0xa8, 0x38, 0x02, 0x03, 0xb0, 0x38, 0x02, 0x03, 0xb8, 0x38, 0x02, 0x03, 0x30, 0x12, 0x03, 0x03, 0x38, 0x12, 0x03, 0x03, + 0x40, 0x12, 0x03, 0x03, 0xd0, 0x2f, 0x04, 0x04, 0xe0, 0x2f, 0x04, 0x04, 0x90, 0x0b, 0x05, 0x04, 0x60, 0x27, 0x06, 0x05, 0x20, 0x08, 0x07, 0x05, 0x00, 0x19, 0x0a, 0x07, 0x50, 0x2b, 0x00, 0x03, + 0x58, 0x2b, 0x00, 0x03, 0x60, 0x2b, 0x00, 0x03, 0x68, 0x2b, 0x00, 0x03, 0xe4, 0x18, 0x01, 0x02, 0xe8, 0x18, 0x01, 0x02, 0xec, 0x18, 0x01, 0x02, 0xf0, 0x18, 0x01, 0x02, 0xf4, 0x18, 0x01, 0x02, + 0xf8, 0x18, 0x01, 0x02, 0xc0, 0x38, 0x02, 0x03, 0xc8, 0x38, 0x02, 0x03, 0xd0, 0x38, 0x02, 0x03, 0xd8, 0x38, 0x02, 0x03, 0xe0, 0x38, 0x02, 0x03, 0x48, 0x12, 0x03, 0x03, 0x50, 0x12, 0x03, 0x03, + 0x58, 0x12, 0x03, 0x03, 0xf0, 0x2f, 0x04, 0x04, 0x00, 0x30, 0x04, 0x04, 0xa0, 0x0b, 0x05, 0x04, 0x80, 0x27, 0x06, 0x05, 0x40, 0x08, 0x07, 0x05, 0x80, 0x19, 0x0a, 0x07, 0x70, 0x2b, 0x00, 0x03, + 0x78, 0x2b, 0x00, 0x03, 0x80, 0x2b, 0x00, 0x03, 0x88, 0x2b, 0x00, 0x03, 0xfc, 0x18, 0x01, 0x02, 0x00, 0x19, 0x01, 0x02, 0x04, 0x19, 0x01, 0x02, 0x08, 0x19, 0x01, 0x02, 0x0c, 0x19, 0x01, 0x02, + 0x10, 0x19, 0x01, 0x02, 0xe8, 0x38, 0x02, 0x03, 0xf0, 0x38, 0x02, 0x03, 0xf8, 0x38, 0x02, 0x03, 0x00, 0x39, 0x02, 0x03, 0x08, 0x39, 0x02, 0x03, 0x60, 0x12, 0x03, 0x03, 0x68, 0x12, 0x03, 0x03, + 0x70, 0x12, 0x03, 0x03, 0x10, 0x30, 0x04, 0x04, 0x20, 0x30, 0x04, 0x04, 0xb0, 0x0b, 0x05, 0x04, 0xa0, 0x27, 0x06, 0x05, 0x60, 0x08, 0x07, 0x05, 0x00, 0x1a, 0x0a, 0x07, 0x90, 0x2b, 0x00, 0x03, + 0x98, 0x2b, 0x00, 0x03, 0xa0, 0x2b, 0x00, 0x03, 0xa8, 0x2b, 0x00, 0x03, 0x14, 0x19, 0x01, 0x02, 0x18, 0x19, 0x01, 0x02, 0x1c, 0x19, 0x01, 0x02, 0x20, 0x19, 0x01, 0x02, 0x24, 0x19, 0x01, 0x02, + 0x28, 0x19, 0x01, 0x02, 0x10, 0x39, 0x02, 0x03, 0x18, 0x39, 0x02, 0x03, 0x20, 0x39, 0x02, 0x03, 0x28, 0x39, 0x02, 0x03, 0x30, 0x39, 0x02, 0x03, 0x78, 0x12, 0x03, 0x03, 0x80, 0x12, 0x03, 0x03, + 0x88, 0x12, 0x03, 0x03, 0x30, 0x30, 0x04, 0x04, 0x40, 0x30, 0x04, 0x04, 0xc0, 0x0b, 0x05, 0x04, 0xc0, 0x27, 0x06, 0x05, 0x80, 0x08, 0x07, 0x05, 0x80, 0x1a, 0x0a, 0x07, 0xb0, 0x2b, 0x00, 0x03, + 0xb8, 0x2b, 0x00, 0x03, 0xc0, 0x2b, 0x00, 0x03, 0xc8, 0x2b, 0x00, 0x03, 0x2c, 0x19, 0x01, 0x02, 0x30, 0x19, 0x01, 0x02, 0x34, 0x19, 0x01, 0x02, 0x38, 0x19, 0x01, 0x02, 0x3c, 0x19, 0x01, 0x02, + 0x40, 0x19, 0x01, 0x02, 0x38, 0x39, 0x02, 0x03, 0x40, 0x39, 0x02, 0x03, 0x48, 0x39, 0x02, 0x03, 0x50, 0x39, 0x02, 0x03, 0x58, 0x39, 0x02, 0x03, 0x90, 0x12, 0x03, 0x03, 0x98, 0x12, 0x03, 0x03, + 0xa0, 0x12, 0x03, 0x03, 0x50, 0x30, 0x04, 0x04, 0x60, 0x30, 0x04, 0x04, 0xd0, 0x0b, 0x05, 0x04, 0xe0, 0x27, 0x06, 0x05, 0xa0, 0x08, 0x07, 0x05, 0x00, 0x1b, 0x0a, 0x07, 0xd0, 0x2b, 0x00, 0x03, + 0xd8, 0x2b, 0x00, 0x03, 0xe0, 0x2b, 0x00, 0x03, 0xe8, 0x2b, 0x00, 0x03, 0x44, 0x19, 0x01, 0x02, 0x48, 0x19, 0x01, 0x02, 0x4c, 0x19, 0x01, 0x02, 0x50, 0x19, 0x01, 0x02, 0x54, 0x19, 0x01, 0x02, + 0x58, 0x19, 0x01, 0x02, 0x60, 0x39, 0x02, 0x03, 0x68, 0x39, 0x02, 0x03, 0x70, 0x39, 0x02, 0x03, 0x78, 0x39, 0x02, 0x03, 0x80, 0x39, 0x02, 0x03, 0xa8, 0x12, 0x03, 0x03, 0xb0, 0x12, 0x03, 0x03, + 0xb8, 0x12, 0x03, 0x03, 0x70, 0x30, 0x04, 0x04, 0x80, 0x30, 0x04, 0x04, 0xe0, 0x0b, 0x05, 0x04, 0x00, 0x28, 0x06, 0x05, 0xc0, 0x08, 0x07, 0x05, 0x80, 0x1b, 0x0a, 0x07, 0xf0, 0x2b, 0x00, 0x03, + 0xf8, 0x2b, 0x00, 0x03, 0x00, 0x2c, 0x00, 0x03, 0x08, 0x2c, 0x00, 0x03, 0x5c, 0x19, 0x01, 0x02, 0x60, 0x19, 0x01, 0x02, 0x64, 0x19, 0x01, 0x02, 0x68, 0x19, 0x01, 0x02, 0x6c, 0x19, 0x01, 0x02, + 0x70, 0x19, 0x01, 0x02, 0x88, 0x39, 0x02, 0x03, 0x90, 0x39, 0x02, 0x03, 0x98, 0x39, 0x02, 0x03, 0xa0, 0x39, 0x02, 0x03, 0xa8, 0x39, 0x02, 0x03, 0xc0, 0x12, 0x03, 0x03, 0xc8, 0x12, 0x03, 0x03, + 0xd0, 0x12, 0x03, 0x03, 0x90, 0x30, 0x04, 0x04, 0xa0, 0x30, 0x04, 0x04, 0xf0, 0x0b, 0x05, 0x04, 0x20, 0x28, 0x06, 0x05, 0xe0, 0x08, 0x07, 0x05, 0x00, 0x1c, 0x0a, 0x07, 0x10, 0x2c, 0x00, 0x03, + 0x18, 0x2c, 0x00, 0x03, 0x20, 0x2c, 0x00, 0x03, 0x28, 0x2c, 0x00, 0x03, 0x74, 0x19, 0x01, 0x02, 0x78, 0x19, 0x01, 0x02, 0x7c, 0x19, 0x01, 0x02, 0x80, 0x19, 0x01, 0x02, 0x84, 0x19, 0x01, 0x02, + 0x88, 0x19, 0x01, 0x02, 0xb0, 0x39, 0x02, 0x03, 0xb8, 0x39, 0x02, 0x03, 0xc0, 0x39, 0x02, 0x03, 0xc8, 0x39, 0x02, 0x03, 0xd0, 0x39, 0x02, 0x03, 0xd8, 0x12, 0x03, 0x03, 0xe0, 0x12, 0x03, 0x03, + 0xe8, 0x12, 0x03, 0x03, 0xb0, 0x30, 0x04, 0x04, 0xc0, 0x30, 0x04, 0x04, 0x00, 0x0c, 0x05, 0x04, 0x40, 0x28, 0x06, 0x05, 0x00, 0x09, 0x07, 0x05, 0x80, 0x1c, 0x0a, 0x07, 0x30, 0x2c, 0x00, 0x03, + 0x38, 0x2c, 0x00, 0x03, 0x40, 0x2c, 0x00, 0x03, 0x48, 0x2c, 0x00, 0x03, 0x8c, 0x19, 0x01, 0x02, 0x90, 0x19, 0x01, 0x02, 0x94, 0x19, 0x01, 0x02, 0x98, 0x19, 0x01, 0x02, 0x9c, 0x19, 0x01, 0x02, + 0xa0, 0x19, 0x01, 0x02, 0xd8, 0x39, 0x02, 0x03, 0xe0, 0x39, 0x02, 0x03, 0xe8, 0x39, 0x02, 0x03, 0xf0, 0x39, 0x02, 0x03, 0xf8, 0x39, 0x02, 0x03, 0xf0, 0x12, 0x03, 0x03, 0xf8, 0x12, 0x03, 0x03, + 0x00, 0x13, 0x03, 0x03, 0xd0, 0x30, 0x04, 0x04, 0xe0, 0x30, 0x04, 0x04, 0x10, 0x0c, 0x05, 0x04, 0x60, 0x28, 0x06, 0x05, 0x20, 0x09, 0x07, 0x05, 0x00, 0x1d, 0x0a, 0x07, 0x50, 0x2c, 0x00, 0x03, + 0x58, 0x2c, 0x00, 0x03, 0x60, 0x2c, 0x00, 0x03, 0x68, 0x2c, 0x00, 0x03, 0xa4, 0x19, 0x01, 0x02, 0xa8, 0x19, 0x01, 0x02, 0xac, 0x19, 0x01, 0x02, 0xb0, 0x19, 0x01, 0x02, 0xb4, 0x19, 0x01, 0x02, + 0xb8, 0x19, 0x01, 0x02, 0x00, 0x3a, 0x02, 0x03, 0x08, 0x3a, 0x02, 0x03, 0x10, 0x3a, 0x02, 0x03, 0x18, 0x3a, 0x02, 0x03, 0x20, 0x3a, 0x02, 0x03, 0x08, 0x13, 0x03, 0x03, 0x10, 0x13, 0x03, 0x03, + 0x18, 0x13, 0x03, 0x03, 0xf0, 0x30, 0x04, 0x04, 0x00, 0x31, 0x04, 0x04, 0x20, 0x0c, 0x05, 0x04, 0x80, 0x28, 0x06, 0x05, 0x40, 0x09, 0x07, 0x05, 0x00, 0x34, 0x0b, 0x08, 0x70, 0x2c, 0x00, 0x03, + 0x78, 0x2c, 0x00, 0x03, 0x80, 0x2c, 0x00, 0x03, 0x88, 0x2c, 0x00, 0x03, 0xbc, 0x19, 0x01, 0x02, 0xc0, 0x19, 0x01, 0x02, 0xc4, 0x19, 0x01, 0x02, 0xc8, 0x19, 0x01, 0x02, 0xcc, 0x19, 0x01, 0x02, + 0xd0, 0x19, 0x01, 0x02, 0x28, 0x3a, 0x02, 0x03, 0x30, 0x3a, 0x02, 0x03, 0x38, 0x3a, 0x02, 0x03, 0x40, 0x3a, 0x02, 0x03, 0x48, 0x3a, 0x02, 0x03, 0x20, 0x13, 0x03, 0x03, 0x28, 0x13, 0x03, 0x03, + 0x30, 0x13, 0x03, 0x03, 0x10, 0x31, 0x04, 0x04, 0x20, 0x31, 0x04, 0x04, 0x30, 0x0c, 0x05, 0x04, 0xa0, 0x28, 0x06, 0x05, 0x60, 0x09, 0x07, 0x05, 0x00, 0x35, 0x0b, 0x08, 0x90, 0x2c, 0x00, 0x03, + 0x98, 0x2c, 0x00, 0x03, 0xa0, 0x2c, 0x00, 0x03, 0xa8, 0x2c, 0x00, 0x03, 0xd4, 0x19, 0x01, 0x02, 0xd8, 0x19, 0x01, 0x02, 0xdc, 0x19, 0x01, 0x02, 0xe0, 0x19, 0x01, 0x02, 0xe4, 0x19, 0x01, 0x02, + 0xe8, 0x19, 0x01, 0x02, 0x50, 0x3a, 0x02, 0x03, 0x58, 0x3a, 0x02, 0x03, 0x60, 0x3a, 0x02, 0x03, 0x68, 0x3a, 0x02, 0x03, 0x70, 0x3a, 0x02, 0x03, 0x38, 0x13, 0x03, 0x03, 0x40, 0x13, 0x03, 0x03, + 0x48, 0x13, 0x03, 0x03, 0x30, 0x31, 0x04, 0x04, 0x40, 0x31, 0x04, 0x04, 0x40, 0x0c, 0x05, 0x04, 0xc0, 0x28, 0x06, 0x05, 0x80, 0x09, 0x07, 0x05, 0x00, 0x36, 0x0b, 0x08, 0xb0, 0x2c, 0x00, 0x03, + 0xb8, 0x2c, 0x00, 0x03, 0xc0, 0x2c, 0x00, 0x03, 0xc8, 0x2c, 0x00, 0x03, 0xec, 0x19, 0x01, 0x02, 0xf0, 0x19, 0x01, 0x02, 0xf4, 0x19, 0x01, 0x02, 0xf8, 0x19, 0x01, 0x02, 0xfc, 0x19, 0x01, 0x02, + 0x00, 0x1a, 0x01, 0x02, 0x78, 0x3a, 0x02, 0x03, 0x80, 0x3a, 0x02, 0x03, 0x88, 0x3a, 0x02, 0x03, 0x90, 0x3a, 0x02, 0x03, 0x98, 0x3a, 0x02, 0x03, 0x50, 0x13, 0x03, 0x03, 0x58, 0x13, 0x03, 0x03, + 0x60, 0x13, 0x03, 0x03, 0x50, 0x31, 0x04, 0x04, 0x60, 0x31, 0x04, 0x04, 0x50, 0x0c, 0x05, 0x04, 0xe0, 0x28, 0x06, 0x05, 0xa0, 0x09, 0x07, 0x05, 0x00, 0x37, 0x0b, 0x08, 0xd0, 0x2c, 0x00, 0x03, + 0xd8, 0x2c, 0x00, 0x03, 0xe0, 0x2c, 0x00, 0x03, 0xe8, 0x2c, 0x00, 0x03, 0x04, 0x1a, 0x01, 0x02, 0x08, 0x1a, 0x01, 0x02, 0x0c, 0x1a, 0x01, 0x02, 0x10, 0x1a, 0x01, 0x02, 0x14, 0x1a, 0x01, 0x02, + 0x18, 0x1a, 0x01, 0x02, 0xa0, 0x3a, 0x02, 0x03, 0xa8, 0x3a, 0x02, 0x03, 0xb0, 0x3a, 0x02, 0x03, 0xb8, 0x3a, 0x02, 0x03, 0xc0, 0x3a, 0x02, 0x03, 0x68, 0x13, 0x03, 0x03, 0x70, 0x13, 0x03, 0x03, + 0x78, 0x13, 0x03, 0x03, 0x70, 0x31, 0x04, 0x04, 0x80, 0x31, 0x04, 0x04, 0x60, 0x0c, 0x05, 0x04, 0x00, 0x29, 0x06, 0x05, 0xc0, 0x09, 0x07, 0x05, 0x00, 0x38, 0x0b, 0x08, 0xf0, 0x2c, 0x00, 0x03, + 0xf8, 0x2c, 0x00, 0x03, 0x00, 0x2d, 0x00, 0x03, 0x08, 0x2d, 0x00, 0x03, 0x1c, 0x1a, 0x01, 0x02, 0x20, 0x1a, 0x01, 0x02, 0x24, 0x1a, 0x01, 0x02, 0x28, 0x1a, 0x01, 0x02, 0x2c, 0x1a, 0x01, 0x02, + 0x30, 0x1a, 0x01, 0x02, 0xc8, 0x3a, 0x02, 0x03, 0xd0, 0x3a, 0x02, 0x03, 0xd8, 0x3a, 0x02, 0x03, 0xe0, 0x3a, 0x02, 0x03, 0xe8, 0x3a, 0x02, 0x03, 0x80, 0x13, 0x03, 0x03, 0x88, 0x13, 0x03, 0x03, + 0x90, 0x13, 0x03, 0x03, 0x90, 0x31, 0x04, 0x04, 0xa0, 0x31, 0x04, 0x04, 0x70, 0x0c, 0x05, 0x04, 0x20, 0x29, 0x06, 0x05, 0xc0, 0x1d, 0x08, 0x06, 0x00, 0x39, 0x0b, 0x08, 0x10, 0x2d, 0x00, 0x03, + 0x18, 0x2d, 0x00, 0x03, 0x20, 0x2d, 0x00, 0x03, 0x28, 0x2d, 0x00, 0x03, 0x34, 0x1a, 0x01, 0x02, 0x38, 0x1a, 0x01, 0x02, 0x3c, 0x1a, 0x01, 0x02, 0x40, 0x1a, 0x01, 0x02, 0x44, 0x1a, 0x01, 0x02, + 0x48, 0x1a, 0x01, 0x02, 0xf0, 0x3a, 0x02, 0x03, 0xf8, 0x3a, 0x02, 0x03, 0x00, 0x3b, 0x02, 0x03, 0x08, 0x3b, 0x02, 0x03, 0x10, 0x3b, 0x02, 0x03, 0x98, 0x13, 0x03, 0x03, 0xa0, 0x13, 0x03, 0x03, + 0xa8, 0x13, 0x03, 0x03, 0xb0, 0x31, 0x04, 0x04, 0xc0, 0x31, 0x04, 0x04, 0x80, 0x0c, 0x05, 0x04, 0x40, 0x29, 0x06, 0x05, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x3a, 0x0b, 0x08, 0x30, 0x2d, 0x00, 0x03, + 0x38, 0x2d, 0x00, 0x03, 0x40, 0x2d, 0x00, 0x03, 0x48, 0x2d, 0x00, 0x03, 0x4c, 0x1a, 0x01, 0x02, 0x50, 0x1a, 0x01, 0x02, 0x54, 0x1a, 0x01, 0x02, 0x58, 0x1a, 0x01, 0x02, 0x5c, 0x1a, 0x01, 0x02, + 0x60, 0x1a, 0x01, 0x02, 0x18, 0x3b, 0x02, 0x03, 0x20, 0x3b, 0x02, 0x03, 0x28, 0x3b, 0x02, 0x03, 0x30, 0x3b, 0x02, 0x03, 0x38, 0x3b, 0x02, 0x03, 0xb0, 0x13, 0x03, 0x03, 0xb8, 0x13, 0x03, 0x03, + 0xd0, 0x31, 0x04, 0x04, 0xe0, 0x31, 0x04, 0x04, 0xf0, 0x31, 0x04, 0x04, 0x90, 0x0c, 0x05, 0x04, 0x60, 0x29, 0x06, 0x05, 0x40, 0x1e, 0x08, 0x06, 0x00, 0x3b, 0x0b, 0x08, 0x50, 0x2d, 0x00, 0x03, + 0x58, 0x2d, 0x00, 0x03, 0x60, 0x2d, 0x00, 0x03, 0x68, 0x2d, 0x00, 0x03, 0x64, 0x1a, 0x01, 0x02, 0x68, 0x1a, 0x01, 0x02, 0x6c, 0x1a, 0x01, 0x02, 0x70, 0x1a, 0x01, 0x02, 0x74, 0x1a, 0x01, 0x02, + 0x78, 0x1a, 0x01, 0x02, 0x40, 0x3b, 0x02, 0x03, 0x48, 0x3b, 0x02, 0x03, 0x50, 0x3b, 0x02, 0x03, 0x58, 0x3b, 0x02, 0x03, 0x60, 0x3b, 0x02, 0x03, 0xc0, 0x13, 0x03, 0x03, 0xc8, 0x13, 0x03, 0x03, + 0x00, 0x32, 0x04, 0x04, 0x10, 0x32, 0x04, 0x04, 0x20, 0x32, 0x04, 0x04, 0xa0, 0x0c, 0x05, 0x04, 0x80, 0x29, 0x06, 0x05, 0x80, 0x1e, 0x08, 0x06, 0x00, 0x3c, 0x0b, 0x08, 0x70, 0x2d, 0x00, 0x03, + 0x78, 0x2d, 0x00, 0x03, 0x80, 0x2d, 0x00, 0x03, 0x88, 0x2d, 0x00, 0x03, 0x7c, 0x1a, 0x01, 0x02, 0x80, 0x1a, 0x01, 0x02, 0x84, 0x1a, 0x01, 0x02, 0x88, 0x1a, 0x01, 0x02, 0x8c, 0x1a, 0x01, 0x02, + 0x90, 0x1a, 0x01, 0x02, 0x68, 0x3b, 0x02, 0x03, 0x70, 0x3b, 0x02, 0x03, 0x78, 0x3b, 0x02, 0x03, 0x80, 0x3b, 0x02, 0x03, 0xd0, 0x13, 0x03, 0x03, 0xd8, 0x13, 0x03, 0x03, 0xe0, 0x13, 0x03, 0x03, + 0x30, 0x32, 0x04, 0x04, 0x40, 0x32, 0x04, 0x04, 0xb0, 0x0c, 0x05, 0x04, 0xc0, 0x0c, 0x05, 0x04, 0xa0, 0x29, 0x06, 0x05, 0xc0, 0x1e, 0x08, 0x06, 0x00, 0x3d, 0x0b, 0x08, 0x90, 0x2d, 0x00, 0x03, + 0x98, 0x2d, 0x00, 0x03, 0xa0, 0x2d, 0x00, 0x03, 0xa8, 0x2d, 0x00, 0x03, 0x94, 0x1a, 0x01, 0x02, 0x98, 0x1a, 0x01, 0x02, 0x9c, 0x1a, 0x01, 0x02, 0xa0, 0x1a, 0x01, 0x02, 0xa4, 0x1a, 0x01, 0x02, + 0xa8, 0x1a, 0x01, 0x02, 0x88, 0x3b, 0x02, 0x03, 0x90, 0x3b, 0x02, 0x03, 0x98, 0x3b, 0x02, 0x03, 0xa0, 0x3b, 0x02, 0x03, 0xe8, 0x13, 0x03, 0x03, 0xf0, 0x13, 0x03, 0x03, 0xf8, 0x13, 0x03, 0x03, + 0x50, 0x32, 0x04, 0x04, 0x60, 0x32, 0x04, 0x04, 0xd0, 0x0c, 0x05, 0x04, 0xe0, 0x0c, 0x05, 0x04, 0xc0, 0x29, 0x06, 0x05, 0x00, 0x1f, 0x08, 0x06, 0x00, 0x3e, 0x0b, 0x08, 0xb0, 0x2d, 0x00, 0x03, + 0xb8, 0x2d, 0x00, 0x03, 0xc0, 0x2d, 0x00, 0x03, 0xc8, 0x2d, 0x00, 0x03, 0xac, 0x1a, 0x01, 0x02, 0xb0, 0x1a, 0x01, 0x02, 0xb4, 0x1a, 0x01, 0x02, 0xb8, 0x1a, 0x01, 0x02, 0xbc, 0x1a, 0x01, 0x02, + 0xc0, 0x1a, 0x01, 0x02, 0xa8, 0x3b, 0x02, 0x03, 0xb0, 0x3b, 0x02, 0x03, 0xb8, 0x3b, 0x02, 0x03, 0xc0, 0x3b, 0x02, 0x03, 0x00, 0x14, 0x03, 0x03, 0x08, 0x14, 0x03, 0x03, 0x10, 0x14, 0x03, 0x03, + 0x70, 0x32, 0x04, 0x04, 0x80, 0x32, 0x04, 0x04, 0xf0, 0x0c, 0x05, 0x04, 0x00, 0x0d, 0x05, 0x04, 0xe0, 0x29, 0x06, 0x05, 0x40, 0x1f, 0x08, 0x06, 0x00, 0x0e, 0x0c, 0x08, 0xd0, 0x2d, 0x00, 0x03, + 0xd8, 0x2d, 0x00, 0x03, 0xe0, 0x2d, 0x00, 0x03, 0xe8, 0x2d, 0x00, 0x03, 0xc4, 0x1a, 0x01, 0x02, 0xc8, 0x1a, 0x01, 0x02, 0xcc, 0x1a, 0x01, 0x02, 0xd0, 0x1a, 0x01, 0x02, 0xd4, 0x1a, 0x01, 0x02, + 0xd8, 0x1a, 0x01, 0x02, 0xc8, 0x3b, 0x02, 0x03, 0xd0, 0x3b, 0x02, 0x03, 0xd8, 0x3b, 0x02, 0x03, 0xe0, 0x3b, 0x02, 0x03, 0x18, 0x14, 0x03, 0x03, 0x20, 0x14, 0x03, 0x03, 0x28, 0x14, 0x03, 0x03, + 0x90, 0x32, 0x04, 0x04, 0xa0, 0x32, 0x04, 0x04, 0x10, 0x0d, 0x05, 0x04, 0x20, 0x0d, 0x05, 0x04, 0x00, 0x2a, 0x06, 0x05, 0x80, 0x1f, 0x08, 0x06, 0x00, 0x0f, 0x0c, 0x08, 0xf0, 0x2d, 0x00, 0x03, + 0xf8, 0x2d, 0x00, 0x03, 0x00, 0x2e, 0x00, 0x03, 0x08, 0x2e, 0x00, 0x03, 0xdc, 0x1a, 0x01, 0x02, 0xe0, 0x1a, 0x01, 0x02, 0xe4, 0x1a, 0x01, 0x02, 0xe8, 0x1a, 0x01, 0x02, 0xec, 0x1a, 0x01, 0x02, + 0xf0, 0x1a, 0x01, 0x02, 0xe8, 0x3b, 0x02, 0x03, 0xf0, 0x3b, 0x02, 0x03, 0xf8, 0x3b, 0x02, 0x03, 0x00, 0x3c, 0x02, 0x03, 0x30, 0x14, 0x03, 0x03, 0x38, 0x14, 0x03, 0x03, 0x40, 0x14, 0x03, 0x03, + 0xb0, 0x32, 0x04, 0x04, 0xc0, 0x32, 0x04, 0x04, 0x30, 0x0d, 0x05, 0x04, 0x40, 0x0d, 0x05, 0x04, 0x20, 0x2a, 0x06, 0x05, 0xc0, 0x1f, 0x08, 0x06, 0x00, 0x10, 0x0c, 0x08, 0x10, 0x2e, 0x00, 0x03, + 0x18, 0x2e, 0x00, 0x03, 0x20, 0x2e, 0x00, 0x03, 0x28, 0x2e, 0x00, 0x03, 0xf4, 0x1a, 0x01, 0x02, 0xf8, 0x1a, 0x01, 0x02, 0xfc, 0x1a, 0x01, 0x02, 0x00, 0x1b, 0x01, 0x02, 0x04, 0x1b, 0x01, 0x02, + 0x08, 0x1b, 0x01, 0x02, 0x08, 0x3c, 0x02, 0x03, 0x10, 0x3c, 0x02, 0x03, 0x18, 0x3c, 0x02, 0x03, 0x20, 0x3c, 0x02, 0x03, 0x48, 0x14, 0x03, 0x03, 0x50, 0x14, 0x03, 0x03, 0x58, 0x14, 0x03, 0x03, + 0xd0, 0x32, 0x04, 0x04, 0xe0, 0x32, 0x04, 0x04, 0x50, 0x0d, 0x05, 0x04, 0x60, 0x0d, 0x05, 0x04, 0x40, 0x2a, 0x06, 0x05, 0x00, 0x20, 0x08, 0x06, 0x00, 0x11, 0x0c, 0x08, 0x30, 0x2e, 0x00, 0x03, + 0x38, 0x2e, 0x00, 0x03, 0x40, 0x2e, 0x00, 0x03, 0x48, 0x2e, 0x00, 0x03, 0x0c, 0x1b, 0x01, 0x02, 0x10, 0x1b, 0x01, 0x02, 0x14, 0x1b, 0x01, 0x02, 0x18, 0x1b, 0x01, 0x02, 0x1c, 0x1b, 0x01, 0x02, + 0x20, 0x1b, 0x01, 0x02, 0x28, 0x3c, 0x02, 0x03, 0x30, 0x3c, 0x02, 0x03, 0x38, 0x3c, 0x02, 0x03, 0x40, 0x3c, 0x02, 0x03, 0x60, 0x14, 0x03, 0x03, 0x68, 0x14, 0x03, 0x03, 0x70, 0x14, 0x03, 0x03, + 0xf0, 0x32, 0x04, 0x04, 0x00, 0x33, 0x04, 0x04, 0x70, 0x0d, 0x05, 0x04, 0x80, 0x0d, 0x05, 0x04, 0x60, 0x2a, 0x06, 0x05, 0x40, 0x20, 0x08, 0x06, 0x00, 0x12, 0x0c, 0x08, 0x50, 0x2e, 0x00, 0x03, + 0x58, 0x2e, 0x00, 0x03, 0x60, 0x2e, 0x00, 0x03, 0x68, 0x2e, 0x00, 0x03, 0x24, 0x1b, 0x01, 0x02, 0x28, 0x1b, 0x01, 0x02, 0x2c, 0x1b, 0x01, 0x02, 0x30, 0x1b, 0x01, 0x02, 0x34, 0x1b, 0x01, 0x02, + 0x38, 0x1b, 0x01, 0x02, 0x48, 0x3c, 0x02, 0x03, 0x50, 0x3c, 0x02, 0x03, 0x58, 0x3c, 0x02, 0x03, 0x60, 0x3c, 0x02, 0x03, 0x78, 0x14, 0x03, 0x03, 0x80, 0x14, 0x03, 0x03, 0x88, 0x14, 0x03, 0x03, + 0x10, 0x33, 0x04, 0x04, 0x20, 0x33, 0x04, 0x04, 0x90, 0x0d, 0x05, 0x04, 0xa0, 0x0d, 0x05, 0x04, 0x80, 0x2a, 0x06, 0x05, 0x80, 0x20, 0x08, 0x06, 0x00, 0x13, 0x0c, 0x08, 0x70, 0x2e, 0x00, 0x03, + 0x78, 0x2e, 0x00, 0x03, 0x80, 0x2e, 0x00, 0x03, 0x88, 0x2e, 0x00, 0x03, 0x3c, 0x1b, 0x01, 0x02, 0x40, 0x1b, 0x01, 0x02, 0x44, 0x1b, 0x01, 0x02, 0x48, 0x1b, 0x01, 0x02, 0x4c, 0x1b, 0x01, 0x02, + 0x50, 0x1b, 0x01, 0x02, 0x68, 0x3c, 0x02, 0x03, 0x70, 0x3c, 0x02, 0x03, 0x78, 0x3c, 0x02, 0x03, 0x80, 0x3c, 0x02, 0x03, 0x90, 0x14, 0x03, 0x03, 0x98, 0x14, 0x03, 0x03, 0xa0, 0x14, 0x03, 0x03, + 0x30, 0x33, 0x04, 0x04, 0x40, 0x33, 0x04, 0x04, 0xb0, 0x0d, 0x05, 0x04, 0xc0, 0x0d, 0x05, 0x04, 0xa0, 0x2a, 0x06, 0x05, 0xc0, 0x20, 0x08, 0x06, 0x00, 0x14, 0x0c, 0x08, 0x90, 0x2e, 0x00, 0x03, + 0x98, 0x2e, 0x00, 0x03, 0xa0, 0x2e, 0x00, 0x03, 0xa8, 0x2e, 0x00, 0x03, 0x54, 0x1b, 0x01, 0x02, 0x58, 0x1b, 0x01, 0x02, 0x5c, 0x1b, 0x01, 0x02, 0x60, 0x1b, 0x01, 0x02, 0x64, 0x1b, 0x01, 0x02, + 0x68, 0x1b, 0x01, 0x02, 0x88, 0x3c, 0x02, 0x03, 0x90, 0x3c, 0x02, 0x03, 0x98, 0x3c, 0x02, 0x03, 0xa0, 0x3c, 0x02, 0x03, 0xa8, 0x14, 0x03, 0x03, 0xb0, 0x14, 0x03, 0x03, 0xb8, 0x14, 0x03, 0x03, + 0x50, 0x33, 0x04, 0x04, 0x60, 0x33, 0x04, 0x04, 0xd0, 0x0d, 0x05, 0x04, 0xe0, 0x0d, 0x05, 0x04, 0xc0, 0x2a, 0x06, 0x05, 0x00, 0x21, 0x08, 0x06, 0x00, 0x15, 0x0c, 0x08, 0xb0, 0x2e, 0x00, 0x03, + 0xb8, 0x2e, 0x00, 0x03, 0xc0, 0x2e, 0x00, 0x03, 0xc8, 0x2e, 0x00, 0x03, 0x6c, 0x1b, 0x01, 0x02, 0x70, 0x1b, 0x01, 0x02, 0x74, 0x1b, 0x01, 0x02, 0x78, 0x1b, 0x01, 0x02, 0x7c, 0x1b, 0x01, 0x02, + 0x80, 0x1b, 0x01, 0x02, 0xa8, 0x3c, 0x02, 0x03, 0xb0, 0x3c, 0x02, 0x03, 0xb8, 0x3c, 0x02, 0x03, 0xc0, 0x3c, 0x02, 0x03, 0xc0, 0x14, 0x03, 0x03, 0xc8, 0x14, 0x03, 0x03, 0xd0, 0x14, 0x03, 0x03, + 0x70, 0x33, 0x04, 0x04, 0x80, 0x33, 0x04, 0x04, 0xf0, 0x0d, 0x05, 0x04, 0x00, 0x0e, 0x05, 0x04, 0xe0, 0x2a, 0x06, 0x05, 0x40, 0x21, 0x08, 0x06, 0x00, 0x2c, 0x0d, 0x09, 0xd0, 0x2e, 0x00, 0x03, + 0xd8, 0x2e, 0x00, 0x03, 0xe0, 0x2e, 0x00, 0x03, 0xe8, 0x2e, 0x00, 0x03, 0x84, 0x1b, 0x01, 0x02, 0x88, 0x1b, 0x01, 0x02, 0x8c, 0x1b, 0x01, 0x02, 0x90, 0x1b, 0x01, 0x02, 0x94, 0x1b, 0x01, 0x02, + 0x98, 0x1b, 0x01, 0x02, 0xc8, 0x3c, 0x02, 0x03, 0xd0, 0x3c, 0x02, 0x03, 0xd8, 0x3c, 0x02, 0x03, 0xe0, 0x3c, 0x02, 0x03, 0xd8, 0x14, 0x03, 0x03, 0xe0, 0x14, 0x03, 0x03, 0xe8, 0x14, 0x03, 0x03, + 0x90, 0x33, 0x04, 0x04, 0xa0, 0x33, 0x04, 0x04, 0x10, 0x0e, 0x05, 0x04, 0x20, 0x0e, 0x05, 0x04, 0x00, 0x2b, 0x06, 0x05, 0x80, 0x21, 0x08, 0x06, 0x00, 0x2e, 0x0d, 0x09, 0xf0, 0x2e, 0x00, 0x03, + 0xf8, 0x2e, 0x00, 0x03, 0x00, 0x2f, 0x00, 0x03, 0x08, 0x2f, 0x00, 0x03, 0x9c, 0x1b, 0x01, 0x02, 0xa0, 0x1b, 0x01, 0x02, 0xa4, 0x1b, 0x01, 0x02, 0xa8, 0x1b, 0x01, 0x02, 0xac, 0x1b, 0x01, 0x02, + 0xb0, 0x1b, 0x01, 0x02, 0xe8, 0x3c, 0x02, 0x03, 0xf0, 0x3c, 0x02, 0x03, 0xf8, 0x3c, 0x02, 0x03, 0x00, 0x3d, 0x02, 0x03, 0xf0, 0x14, 0x03, 0x03, 0xf8, 0x14, 0x03, 0x03, 0x00, 0x15, 0x03, 0x03, + 0xb0, 0x33, 0x04, 0x04, 0xc0, 0x33, 0x04, 0x04, 0x30, 0x0e, 0x05, 0x04, 0x40, 0x0e, 0x05, 0x04, 0x20, 0x2b, 0x06, 0x05, 0xc0, 0x21, 0x08, 0x06, 0x00, 0x30, 0x0d, 0x09, 0x10, 0x2f, 0x00, 0x03, + 0x18, 0x2f, 0x00, 0x03, 0x20, 0x2f, 0x00, 0x03, 0x28, 0x2f, 0x00, 0x03, 0xb4, 0x1b, 0x01, 0x02, 0xb8, 0x1b, 0x01, 0x02, 0xbc, 0x1b, 0x01, 0x02, 0xc0, 0x1b, 0x01, 0x02, 0xc4, 0x1b, 0x01, 0x02, + 0xc8, 0x1b, 0x01, 0x02, 0x08, 0x3d, 0x02, 0x03, 0x10, 0x3d, 0x02, 0x03, 0x18, 0x3d, 0x02, 0x03, 0x20, 0x3d, 0x02, 0x03, 0x08, 0x15, 0x03, 0x03, 0x10, 0x15, 0x03, 0x03, 0x18, 0x15, 0x03, 0x03, + 0xd0, 0x33, 0x04, 0x04, 0xe0, 0x33, 0x04, 0x04, 0x50, 0x0e, 0x05, 0x04, 0x60, 0x0e, 0x05, 0x04, 0x40, 0x2b, 0x06, 0x05, 0x00, 0x22, 0x08, 0x06, 0x00, 0x32, 0x0d, 0x09, 0x30, 0x2f, 0x00, 0x03, + 0x38, 0x2f, 0x00, 0x03, 0x40, 0x2f, 0x00, 0x03, 0x48, 0x2f, 0x00, 0x03, 0xcc, 0x1b, 0x01, 0x02, 0xd0, 0x1b, 0x01, 0x02, 0xd4, 0x1b, 0x01, 0x02, 0xd8, 0x1b, 0x01, 0x02, 0xdc, 0x1b, 0x01, 0x02, + 0xe0, 0x1b, 0x01, 0x02, 0x28, 0x3d, 0x02, 0x03, 0x30, 0x3d, 0x02, 0x03, 0x38, 0x3d, 0x02, 0x03, 0x40, 0x3d, 0x02, 0x03, 0x20, 0x15, 0x03, 0x03, 0x28, 0x15, 0x03, 0x03, 0x30, 0x15, 0x03, 0x03, + 0xf0, 0x33, 0x04, 0x04, 0x00, 0x34, 0x04, 0x04, 0x70, 0x0e, 0x05, 0x04, 0x80, 0x0e, 0x05, 0x04, 0x60, 0x2b, 0x06, 0x05, 0x40, 0x22, 0x08, 0x06, 0x00, 0x34, 0x0d, 0x09, 0x50, 0x2f, 0x00, 0x03, + 0x58, 0x2f, 0x00, 0x03, 0x60, 0x2f, 0x00, 0x03, 0x68, 0x2f, 0x00, 0x03, 0xe4, 0x1b, 0x01, 0x02, 0xe8, 0x1b, 0x01, 0x02, 0xec, 0x1b, 0x01, 0x02, 0xf0, 0x1b, 0x01, 0x02, 0xf4, 0x1b, 0x01, 0x02, + 0xf8, 0x1b, 0x01, 0x02, 0x48, 0x3d, 0x02, 0x03, 0x50, 0x3d, 0x02, 0x03, 0x58, 0x3d, 0x02, 0x03, 0x60, 0x3d, 0x02, 0x03, 0x38, 0x15, 0x03, 0x03, 0x40, 0x15, 0x03, 0x03, 0x48, 0x15, 0x03, 0x03, + 0x10, 0x34, 0x04, 0x04, 0x20, 0x34, 0x04, 0x04, 0x90, 0x0e, 0x05, 0x04, 0xa0, 0x0e, 0x05, 0x04, 0x80, 0x2b, 0x06, 0x05, 0x80, 0x22, 0x08, 0x06, 0x00, 0x36, 0x0d, 0x09, 0x70, 0x2f, 0x00, 0x03, + 0x78, 0x2f, 0x00, 0x03, 0x80, 0x2f, 0x00, 0x03, 0x88, 0x2f, 0x00, 0x03, 0xfc, 0x1b, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x04, 0x1c, 0x01, 0x02, 0x08, 0x1c, 0x01, 0x02, 0x0c, 0x1c, 0x01, 0x02, + 0x10, 0x1c, 0x01, 0x02, 0x68, 0x3d, 0x02, 0x03, 0x70, 0x3d, 0x02, 0x03, 0x78, 0x3d, 0x02, 0x03, 0x80, 0x3d, 0x02, 0x03, 0x50, 0x15, 0x03, 0x03, 0x58, 0x15, 0x03, 0x03, 0x60, 0x15, 0x03, 0x03, + 0x30, 0x34, 0x04, 0x04, 0x40, 0x34, 0x04, 0x04, 0xb0, 0x0e, 0x05, 0x04, 0xc0, 0x0e, 0x05, 0x04, 0xa0, 0x2b, 0x06, 0x05, 0xc0, 0x22, 0x08, 0x06, 0x00, 0x0a, 0x0e, 0x09, 0x90, 0x2f, 0x00, 0x03, + 0x98, 0x2f, 0x00, 0x03, 0xa0, 0x2f, 0x00, 0x03, 0x14, 0x1c, 0x01, 0x02, 0x18, 0x1c, 0x01, 0x02, 0x1c, 0x1c, 0x01, 0x02, 0x20, 0x1c, 0x01, 0x02, 0x24, 0x1c, 0x01, 0x02, 0x28, 0x1c, 0x01, 0x02, + 0x2c, 0x1c, 0x01, 0x02, 0x88, 0x3d, 0x02, 0x03, 0x90, 0x3d, 0x02, 0x03, 0x98, 0x3d, 0x02, 0x03, 0xa0, 0x3d, 0x02, 0x03, 0x68, 0x15, 0x03, 0x03, 0x70, 0x15, 0x03, 0x03, 0x78, 0x15, 0x03, 0x03, + 0x50, 0x34, 0x04, 0x04, 0x60, 0x34, 0x04, 0x04, 0xd0, 0x0e, 0x05, 0x04, 0xe0, 0x0e, 0x05, 0x04, 0xc0, 0x2b, 0x06, 0x05, 0x00, 0x23, 0x08, 0x06, 0x00, 0x0c, 0x0e, 0x09, 0xa8, 0x2f, 0x00, 0x03, + 0xb0, 0x2f, 0x00, 0x03, 0xb8, 0x2f, 0x00, 0x03, 0x30, 0x1c, 0x01, 0x02, 0x34, 0x1c, 0x01, 0x02, 0x38, 0x1c, 0x01, 0x02, 0x3c, 0x1c, 0x01, 0x02, 0x40, 0x1c, 0x01, 0x02, 0x44, 0x1c, 0x01, 0x02, + 0x48, 0x1c, 0x01, 0x02, 0xa8, 0x3d, 0x02, 0x03, 0xb0, 0x3d, 0x02, 0x03, 0xb8, 0x3d, 0x02, 0x03, 0xc0, 0x3d, 0x02, 0x03, 0x80, 0x15, 0x03, 0x03, 0x88, 0x15, 0x03, 0x03, 0x90, 0x15, 0x03, 0x03, + 0x70, 0x34, 0x04, 0x04, 0x80, 0x34, 0x04, 0x04, 0xf0, 0x0e, 0x05, 0x04, 0x00, 0x0f, 0x05, 0x04, 0xe0, 0x2b, 0x06, 0x05, 0x40, 0x23, 0x08, 0x06, 0x00, 0x0e, 0x0e, 0x09, 0xc0, 0x2f, 0x00, 0x03, + 0xc8, 0x2f, 0x00, 0x03, 0xd0, 0x2f, 0x00, 0x03, 0x4c, 0x1c, 0x01, 0x02, 0x50, 0x1c, 0x01, 0x02, 0x54, 0x1c, 0x01, 0x02, 0x58, 0x1c, 0x01, 0x02, 0x5c, 0x1c, 0x01, 0x02, 0x60, 0x1c, 0x01, 0x02, + 0x64, 0x1c, 0x01, 0x02, 0xc8, 0x3d, 0x02, 0x03, 0xd0, 0x3d, 0x02, 0x03, 0xd8, 0x3d, 0x02, 0x03, 0xe0, 0x3d, 0x02, 0x03, 0x98, 0x15, 0x03, 0x03, 0xa0, 0x15, 0x03, 0x03, 0xa8, 0x15, 0x03, 0x03, + 0x90, 0x34, 0x04, 0x04, 0xa0, 0x34, 0x04, 0x04, 0x10, 0x0f, 0x05, 0x04, 0x20, 0x0f, 0x05, 0x04, 0x00, 0x2c, 0x06, 0x05, 0x80, 0x23, 0x08, 0x06, 0x00, 0x24, 0x0f, 0x0a, 0xd8, 0x2f, 0x00, 0x03, + 0xe0, 0x2f, 0x00, 0x03, 0xe8, 0x2f, 0x00, 0x03, 0x68, 0x1c, 0x01, 0x02, 0x6c, 0x1c, 0x01, 0x02, 0x70, 0x1c, 0x01, 0x02, 0x74, 0x1c, 0x01, 0x02, 0x78, 0x1c, 0x01, 0x02, 0x7c, 0x1c, 0x01, 0x02, + 0x80, 0x1c, 0x01, 0x02, 0xe8, 0x3d, 0x02, 0x03, 0xf0, 0x3d, 0x02, 0x03, 0xf8, 0x3d, 0x02, 0x03, 0x00, 0x3e, 0x02, 0x03, 0xb0, 0x15, 0x03, 0x03, 0xb8, 0x15, 0x03, 0x03, 0xc0, 0x15, 0x03, 0x03, + 0xb0, 0x34, 0x04, 0x04, 0xc0, 0x34, 0x04, 0x04, 0x30, 0x0f, 0x05, 0x04, 0x40, 0x0f, 0x05, 0x04, 0x20, 0x2c, 0x06, 0x05, 0xc0, 0x23, 0x08, 0x06, 0x00, 0x28, 0x0f, 0x0a, 0xf0, 0x2f, 0x00, 0x03, + 0xf8, 0x2f, 0x00, 0x03, 0x00, 0x30, 0x00, 0x03, 0x84, 0x1c, 0x01, 0x02, 0x88, 0x1c, 0x01, 0x02, 0x8c, 0x1c, 0x01, 0x02, 0x90, 0x1c, 0x01, 0x02, 0x94, 0x1c, 0x01, 0x02, 0x98, 0x1c, 0x01, 0x02, + 0x9c, 0x1c, 0x01, 0x02, 0x08, 0x3e, 0x02, 0x03, 0x10, 0x3e, 0x02, 0x03, 0x18, 0x3e, 0x02, 0x03, 0x20, 0x3e, 0x02, 0x03, 0xc8, 0x15, 0x03, 0x03, 0xd0, 0x15, 0x03, 0x03, 0xd8, 0x15, 0x03, 0x03, + 0xd0, 0x34, 0x04, 0x04, 0xe0, 0x34, 0x04, 0x04, 0x50, 0x0f, 0x05, 0x04, 0x60, 0x0f, 0x05, 0x04, 0x40, 0x2c, 0x06, 0x05, 0x00, 0x24, 0x08, 0x06, 0x00, 0x2c, 0x0f, 0x0a, 0x08, 0x30, 0x00, 0x03, + 0x10, 0x30, 0x00, 0x03, 0x18, 0x30, 0x00, 0x03, 0xa0, 0x1c, 0x01, 0x02, 0xa4, 0x1c, 0x01, 0x02, 0xa8, 0x1c, 0x01, 0x02, 0xac, 0x1c, 0x01, 0x02, 0xb0, 0x1c, 0x01, 0x02, 0xb4, 0x1c, 0x01, 0x02, + 0xb8, 0x1c, 0x01, 0x02, 0x28, 0x3e, 0x02, 0x03, 0x30, 0x3e, 0x02, 0x03, 0x38, 0x3e, 0x02, 0x03, 0x40, 0x3e, 0x02, 0x03, 0xe0, 0x15, 0x03, 0x03, 0xe8, 0x15, 0x03, 0x03, 0xf0, 0x15, 0x03, 0x03, + 0xf0, 0x34, 0x04, 0x04, 0x00, 0x35, 0x04, 0x04, 0x70, 0x0f, 0x05, 0x04, 0x80, 0x0f, 0x05, 0x04, 0x60, 0x2c, 0x06, 0x05, 0x40, 0x24, 0x08, 0x06, 0x00, 0x08, 0x10, 0x0a, 0x20, 0x30, 0x00, 0x03, + 0x28, 0x30, 0x00, 0x03, 0x30, 0x30, 0x00, 0x03, 0xbc, 0x1c, 0x01, 0x02, 0xc0, 0x1c, 0x01, 0x02, 0xc4, 0x1c, 0x01, 0x02, 0xc8, 0x1c, 0x01, 0x02, 0xcc, 0x1c, 0x01, 0x02, 0xd0, 0x1c, 0x01, 0x02, + 0xd4, 0x1c, 0x01, 0x02, 0x48, 0x3e, 0x02, 0x03, 0x50, 0x3e, 0x02, 0x03, 0x58, 0x3e, 0x02, 0x03, 0x60, 0x3e, 0x02, 0x03, 0xf8, 0x15, 0x03, 0x03, 0x00, 0x16, 0x03, 0x03, 0x08, 0x16, 0x03, 0x03, + 0x10, 0x35, 0x04, 0x04, 0x20, 0x35, 0x04, 0x04, 0x90, 0x0f, 0x05, 0x04, 0xa0, 0x0f, 0x05, 0x04, 0x80, 0x2c, 0x06, 0x05, 0x80, 0x24, 0x08, 0x06, 0x00, 0x0c, 0x10, 0x0a, 0x38, 0x30, 0x00, 0x03, + 0x40, 0x30, 0x00, 0x03, 0x48, 0x30, 0x00, 0x03, 0xd8, 0x1c, 0x01, 0x02, 0xdc, 0x1c, 0x01, 0x02, 0xe0, 0x1c, 0x01, 0x02, 0xe4, 0x1c, 0x01, 0x02, 0xe8, 0x1c, 0x01, 0x02, 0xec, 0x1c, 0x01, 0x02, + 0xf0, 0x1c, 0x01, 0x02, 0x68, 0x3e, 0x02, 0x03, 0x70, 0x3e, 0x02, 0x03, 0x78, 0x3e, 0x02, 0x03, 0x80, 0x3e, 0x02, 0x03, 0x10, 0x16, 0x03, 0x03, 0x18, 0x16, 0x03, 0x03, 0x20, 0x16, 0x03, 0x03, + 0x30, 0x35, 0x04, 0x04, 0x40, 0x35, 0x04, 0x04, 0xb0, 0x0f, 0x05, 0x04, 0xc0, 0x0f, 0x05, 0x04, 0xa0, 0x2c, 0x06, 0x05, 0xc0, 0x24, 0x08, 0x06, 0x00, 0x20, 0x11, 0x0b, 0x50, 0x30, 0x00, 0x03, + 0x58, 0x30, 0x00, 0x03, 0x60, 0x30, 0x00, 0x03, 0xf4, 0x1c, 0x01, 0x02, 0xf8, 0x1c, 0x01, 0x02, 0xfc, 0x1c, 0x01, 0x02, 0x00, 0x1d, 0x01, 0x02, 0x04, 0x1d, 0x01, 0x02, 0x08, 0x1d, 0x01, 0x02, + 0x0c, 0x1d, 0x01, 0x02, 0x88, 0x3e, 0x02, 0x03, 0x90, 0x3e, 0x02, 0x03, 0x98, 0x3e, 0x02, 0x03, 0xa0, 0x3e, 0x02, 0x03, 0x28, 0x16, 0x03, 0x03, 0x30, 0x16, 0x03, 0x03, 0x38, 0x16, 0x03, 0x03, + 0x50, 0x35, 0x04, 0x04, 0x60, 0x35, 0x04, 0x04, 0xd0, 0x0f, 0x05, 0x04, 0xe0, 0x0f, 0x05, 0x04, 0xc0, 0x2c, 0x06, 0x05, 0x00, 0x25, 0x08, 0x06, 0x00, 0x00, 0x12, 0x0b, 0x68, 0x30, 0x00, 0x03, + 0x70, 0x30, 0x00, 0x03, 0x78, 0x30, 0x00, 0x03, 0x10, 0x1d, 0x01, 0x02, 0x14, 0x1d, 0x01, 0x02, 0x18, 0x1d, 0x01, 0x02, 0x1c, 0x1d, 0x01, 0x02, 0x20, 0x1d, 0x01, 0x02, 0x24, 0x1d, 0x01, 0x02, + 0x28, 0x1d, 0x01, 0x02, 0xa8, 0x3e, 0x02, 0x03, 0xb0, 0x3e, 0x02, 0x03, 0xb8, 0x3e, 0x02, 0x03, 0xc0, 0x3e, 0x02, 0x03, 0x40, 0x16, 0x03, 0x03, 0x48, 0x16, 0x03, 0x03, 0x50, 0x16, 0x03, 0x03, + 0x70, 0x35, 0x04, 0x04, 0x80, 0x35, 0x04, 0x04, 0xf0, 0x0f, 0x05, 0x04, 0x00, 0x10, 0x05, 0x04, 0xe0, 0x2c, 0x06, 0x05, 0x40, 0x25, 0x08, 0x06, 0x00, 0x10, 0x13, 0x0c, 0x80, 0x30, 0x00, 0x03, + 0x88, 0x30, 0x00, 0x03, 0x90, 0x30, 0x00, 0x03, 0x2c, 0x1d, 0x01, 0x02, 0x30, 0x1d, 0x01, 0x02, 0x34, 0x1d, 0x01, 0x02, 0x38, 0x1d, 0x01, 0x02, 0x3c, 0x1d, 0x01, 0x02, 0x40, 0x1d, 0x01, 0x02, + 0x44, 0x1d, 0x01, 0x02, 0xc8, 0x3e, 0x02, 0x03, 0xd0, 0x3e, 0x02, 0x03, 0xd8, 0x3e, 0x02, 0x03, 0xe0, 0x3e, 0x02, 0x03, 0x58, 0x16, 0x03, 0x03, 0x60, 0x16, 0x03, 0x03, 0x68, 0x16, 0x03, 0x03, + 0x90, 0x35, 0x04, 0x04, 0xa0, 0x35, 0x04, 0x04, 0x10, 0x10, 0x05, 0x04, 0x20, 0x10, 0x05, 0x04, 0x00, 0x2d, 0x06, 0x05, 0x80, 0x25, 0x08, 0x06, 0x00, 0x00, 0x15, 0x0d, 0x98, 0x30, 0x00, 0x03, + 0xa0, 0x30, 0x00, 0x03, 0xa8, 0x30, 0x00, 0x03, 0x48, 0x1d, 0x01, 0x02, 0x4c, 0x1d, 0x01, 0x02, 0x50, 0x1d, 0x01, 0x02, 0x54, 0x1d, 0x01, 0x02, 0x58, 0x1d, 0x01, 0x02, 0x5c, 0x1d, 0x01, 0x02, + 0x60, 0x1d, 0x01, 0x02, 0xe8, 0x3e, 0x02, 0x03, 0xf0, 0x3e, 0x02, 0x03, 0xf8, 0x3e, 0x02, 0x03, 0x00, 0x3f, 0x02, 0x03, 0x70, 0x16, 0x03, 0x03, 0x78, 0x16, 0x03, 0x03, 0x80, 0x16, 0x03, 0x03, + 0xb0, 0x35, 0x04, 0x04, 0xc0, 0x35, 0x04, 0x04, 0x30, 0x10, 0x05, 0x04, 0x40, 0x10, 0x05, 0x04, 0xe0, 0x09, 0x07, 0x05, 0xc0, 0x25, 0x08, 0x06, 0xb0, 0x30, 0x00, 0x03, 0xb8, 0x30, 0x00, 0x03, + 0xc0, 0x30, 0x00, 0x03, 0xc8, 0x30, 0x00, 0x03, 0x64, 0x1d, 0x01, 0x02, 0x68, 0x1d, 0x01, 0x02, 0x6c, 0x1d, 0x01, 0x02, 0x70, 0x1d, 0x01, 0x02, 0x74, 0x1d, 0x01, 0x02, 0x78, 0x1d, 0x01, 0x02, + 0x7c, 0x1d, 0x01, 0x02, 0x08, 0x3f, 0x02, 0x03, 0x10, 0x3f, 0x02, 0x03, 0x18, 0x3f, 0x02, 0x03, 0x20, 0x3f, 0x02, 0x03, 0x88, 0x16, 0x03, 0x03, 0x90, 0x16, 0x03, 0x03, 0x98, 0x16, 0x03, 0x03, + 0xd0, 0x35, 0x04, 0x04, 0xe0, 0x35, 0x04, 0x04, 0x50, 0x10, 0x05, 0x04, 0x60, 0x10, 0x05, 0x04, 0x00, 0x0a, 0x07, 0x05, 0x00, 0x26, 0x08, 0x06, 0xd0, 0x30, 0x00, 0x03, 0xd8, 0x30, 0x00, 0x03, + 0xe0, 0x30, 0x00, 0x03, 0xe8, 0x30, 0x00, 0x03, 0x80, 0x1d, 0x01, 0x02, 0x84, 0x1d, 0x01, 0x02, 0x88, 0x1d, 0x01, 0x02, 0x8c, 0x1d, 0x01, 0x02, 0x90, 0x1d, 0x01, 0x02, 0x94, 0x1d, 0x01, 0x02, + 0x98, 0x1d, 0x01, 0x02, 0x28, 0x3f, 0x02, 0x03, 0x30, 0x3f, 0x02, 0x03, 0x38, 0x3f, 0x02, 0x03, 0x40, 0x3f, 0x02, 0x03, 0xa0, 0x16, 0x03, 0x03, 0xa8, 0x16, 0x03, 0x03, 0xb0, 0x16, 0x03, 0x03, + 0xf0, 0x35, 0x04, 0x04, 0x00, 0x36, 0x04, 0x04, 0x70, 0x10, 0x05, 0x04, 0x80, 0x10, 0x05, 0x04, 0x20, 0x0a, 0x07, 0x05, 0x40, 0x26, 0x08, 0x06, 0xf0, 0x30, 0x00, 0x03, 0xf8, 0x30, 0x00, 0x03, + 0x00, 0x31, 0x00, 0x03, 0x08, 0x31, 0x00, 0x03, 0x9c, 0x1d, 0x01, 0x02, 0xa0, 0x1d, 0x01, 0x02, 0xa4, 0x1d, 0x01, 0x02, 0xa8, 0x1d, 0x01, 0x02, 0xac, 0x1d, 0x01, 0x02, 0xb0, 0x1d, 0x01, 0x02, + 0xb4, 0x1d, 0x01, 0x02, 0x48, 0x3f, 0x02, 0x03, 0x50, 0x3f, 0x02, 0x03, 0x58, 0x3f, 0x02, 0x03, 0x60, 0x3f, 0x02, 0x03, 0xb8, 0x16, 0x03, 0x03, 0xc0, 0x16, 0x03, 0x03, 0xc8, 0x16, 0x03, 0x03, + 0x10, 0x36, 0x04, 0x04, 0x20, 0x36, 0x04, 0x04, 0x90, 0x10, 0x05, 0x04, 0xa0, 0x10, 0x05, 0x04, 0x40, 0x0a, 0x07, 0x05, 0x80, 0x26, 0x08, 0x06, 0x10, 0x31, 0x00, 0x03, 0x18, 0x31, 0x00, 0x03, + 0x20, 0x31, 0x00, 0x03, 0x28, 0x31, 0x00, 0x03, 0xb8, 0x1d, 0x01, 0x02, 0xbc, 0x1d, 0x01, 0x02, 0xc0, 0x1d, 0x01, 0x02, 0xc4, 0x1d, 0x01, 0x02, 0xc8, 0x1d, 0x01, 0x02, 0xcc, 0x1d, 0x01, 0x02, + 0xd0, 0x1d, 0x01, 0x02, 0x68, 0x3f, 0x02, 0x03, 0x70, 0x3f, 0x02, 0x03, 0x78, 0x3f, 0x02, 0x03, 0x80, 0x3f, 0x02, 0x03, 0xd0, 0x16, 0x03, 0x03, 0xd8, 0x16, 0x03, 0x03, 0xe0, 0x16, 0x03, 0x03, + 0x30, 0x36, 0x04, 0x04, 0x40, 0x36, 0x04, 0x04, 0xb0, 0x10, 0x05, 0x04, 0xc0, 0x10, 0x05, 0x04, 0x60, 0x0a, 0x07, 0x05, 0xc0, 0x26, 0x08, 0x06, 0x30, 0x31, 0x00, 0x03, 0x38, 0x31, 0x00, 0x03, + 0x40, 0x31, 0x00, 0x03, 0x48, 0x31, 0x00, 0x03, 0xd4, 0x1d, 0x01, 0x02, 0xd8, 0x1d, 0x01, 0x02, 0xdc, 0x1d, 0x01, 0x02, 0xe0, 0x1d, 0x01, 0x02, 0xe4, 0x1d, 0x01, 0x02, 0xe8, 0x1d, 0x01, 0x02, + 0xec, 0x1d, 0x01, 0x02, 0x88, 0x3f, 0x02, 0x03, 0x90, 0x3f, 0x02, 0x03, 0x98, 0x3f, 0x02, 0x03, 0xa0, 0x3f, 0x02, 0x03, 0xe8, 0x16, 0x03, 0x03, 0xf0, 0x16, 0x03, 0x03, 0xf8, 0x16, 0x03, 0x03, + 0x50, 0x36, 0x04, 0x04, 0x60, 0x36, 0x04, 0x04, 0xd0, 0x10, 0x05, 0x04, 0x20, 0x2d, 0x06, 0x05, 0x80, 0x0a, 0x07, 0x05, 0x00, 0x27, 0x08, 0x06, 0x50, 0x31, 0x00, 0x03, 0x58, 0x31, 0x00, 0x03, + 0x60, 0x31, 0x00, 0x03, 0x68, 0x31, 0x00, 0x03, 0xf0, 0x1d, 0x01, 0x02, 0xf4, 0x1d, 0x01, 0x02, 0xf8, 0x1d, 0x01, 0x02, 0xfc, 0x1d, 0x01, 0x02, 0x00, 0x1e, 0x01, 0x02, 0x04, 0x1e, 0x01, 0x02, + 0x08, 0x1e, 0x01, 0x02, 0xa8, 0x3f, 0x02, 0x03, 0xb0, 0x3f, 0x02, 0x03, 0xb8, 0x3f, 0x02, 0x03, 0xc0, 0x3f, 0x02, 0x03, 0x00, 0x17, 0x03, 0x03, 0x08, 0x17, 0x03, 0x03, 0x10, 0x17, 0x03, 0x03, + 0x70, 0x36, 0x04, 0x04, 0x80, 0x36, 0x04, 0x04, 0xe0, 0x10, 0x05, 0x04, 0x40, 0x2d, 0x06, 0x05, 0xa0, 0x0a, 0x07, 0x05, 0x40, 0x04, 0x09, 0x06, 0x70, 0x31, 0x00, 0x03, 0x78, 0x31, 0x00, 0x03, + 0x80, 0x31, 0x00, 0x03, 0x88, 0x31, 0x00, 0x03, 0x0c, 0x1e, 0x01, 0x02, 0x10, 0x1e, 0x01, 0x02, 0x14, 0x1e, 0x01, 0x02, 0x18, 0x1e, 0x01, 0x02, 0x1c, 0x1e, 0x01, 0x02, 0x20, 0x1e, 0x01, 0x02, + 0x24, 0x1e, 0x01, 0x02, 0xc8, 0x3f, 0x02, 0x03, 0xd0, 0x3f, 0x02, 0x03, 0xd8, 0x3f, 0x02, 0x03, 0xe0, 0x3f, 0x02, 0x03, 0x18, 0x17, 0x03, 0x03, 0x20, 0x17, 0x03, 0x03, 0x28, 0x17, 0x03, 0x03, + 0x90, 0x36, 0x04, 0x04, 0xa0, 0x36, 0x04, 0x04, 0xf0, 0x10, 0x05, 0x04, 0x60, 0x2d, 0x06, 0x05, 0xc0, 0x0a, 0x07, 0x05, 0x80, 0x04, 0x09, 0x06, 0x90, 0x31, 0x00, 0x03, 0x98, 0x31, 0x00, 0x03, + 0xa0, 0x31, 0x00, 0x03, 0xa8, 0x31, 0x00, 0x03, 0x28, 0x1e, 0x01, 0x02, 0x2c, 0x1e, 0x01, 0x02, 0x30, 0x1e, 0x01, 0x02, 0x34, 0x1e, 0x01, 0x02, 0x38, 0x1e, 0x01, 0x02, 0x3c, 0x1e, 0x01, 0x02, + 0x40, 0x1e, 0x01, 0x02, 0xe8, 0x3f, 0x02, 0x03, 0xf0, 0x3f, 0x02, 0x03, 0xf8, 0x3f, 0x02, 0x03, 0x00, 0x00, 0x02, 0x02, 0x30, 0x17, 0x03, 0x03, 0x38, 0x17, 0x03, 0x03, 0x40, 0x17, 0x03, 0x03, + 0xb0, 0x36, 0x04, 0x04, 0xc0, 0x36, 0x04, 0x04, 0x00, 0x11, 0x05, 0x04, 0x80, 0x2d, 0x06, 0x05, 0xe0, 0x0a, 0x07, 0x05, 0xc0, 0x04, 0x09, 0x06, 0xb0, 0x31, 0x00, 0x03, 0xb8, 0x31, 0x00, 0x03, + 0xc0, 0x31, 0x00, 0x03, 0xc8, 0x31, 0x00, 0x03, 0x44, 0x1e, 0x01, 0x02, 0x48, 0x1e, 0x01, 0x02, 0x4c, 0x1e, 0x01, 0x02, 0x50, 0x1e, 0x01, 0x02, 0x54, 0x1e, 0x01, 0x02, 0x58, 0x1e, 0x01, 0x02, + 0x5c, 0x1e, 0x01, 0x02, 0x04, 0x00, 0x02, 0x02, 0x08, 0x00, 0x02, 0x02, 0x0c, 0x00, 0x02, 0x02, 0x10, 0x00, 0x02, 0x02, 0x48, 0x17, 0x03, 0x03, 0x50, 0x17, 0x03, 0x03, 0x58, 0x17, 0x03, 0x03, + 0xd0, 0x36, 0x04, 0x04, 0xe0, 0x36, 0x04, 0x04, 0x10, 0x11, 0x05, 0x04, 0xa0, 0x2d, 0x06, 0x05, 0x00, 0x0b, 0x07, 0x05, 0x00, 0x05, 0x09, 0x06, 0xd0, 0x31, 0x00, 0x03, 0xd8, 0x31, 0x00, 0x03, + 0xe0, 0x31, 0x00, 0x03, 0xe8, 0x31, 0x00, 0x03, 0x60, 0x1e, 0x01, 0x02, 0x64, 0x1e, 0x01, 0x02, 0x68, 0x1e, 0x01, 0x02, 0x6c, 0x1e, 0x01, 0x02, 0x70, 0x1e, 0x01, 0x02, 0x74, 0x1e, 0x01, 0x02, + 0x78, 0x1e, 0x01, 0x02, 0x14, 0x00, 0x02, 0x02, 0x18, 0x00, 0x02, 0x02, 0x1c, 0x00, 0x02, 0x02, 0x20, 0x00, 0x02, 0x02, 0x60, 0x17, 0x03, 0x03, 0x68, 0x17, 0x03, 0x03, 0x70, 0x17, 0x03, 0x03, + 0xf0, 0x36, 0x04, 0x04, 0x00, 0x37, 0x04, 0x04, 0x20, 0x11, 0x05, 0x04, 0xc0, 0x2d, 0x06, 0x05, 0x20, 0x0b, 0x07, 0x05, 0x40, 0x05, 0x09, 0x06, 0xf0, 0x31, 0x00, 0x03, 0xf8, 0x31, 0x00, 0x03, + 0x00, 0x32, 0x00, 0x03, 0x08, 0x32, 0x00, 0x03, 0x7c, 0x1e, 0x01, 0x02, 0x80, 0x1e, 0x01, 0x02, 0x84, 0x1e, 0x01, 0x02, 0x88, 0x1e, 0x01, 0x02, 0x8c, 0x1e, 0x01, 0x02, 0x90, 0x1e, 0x01, 0x02, + 0x94, 0x1e, 0x01, 0x02, 0x24, 0x00, 0x02, 0x02, 0x28, 0x00, 0x02, 0x02, 0x2c, 0x00, 0x02, 0x02, 0x30, 0x00, 0x02, 0x02, 0x78, 0x17, 0x03, 0x03, 0x80, 0x17, 0x03, 0x03, 0x88, 0x17, 0x03, 0x03, + 0x10, 0x37, 0x04, 0x04, 0x20, 0x37, 0x04, 0x04, 0x30, 0x11, 0x05, 0x04, 0xe0, 0x2d, 0x06, 0x05, 0x40, 0x0b, 0x07, 0x05, 0x80, 0x05, 0x09, 0x06, 0x10, 0x32, 0x00, 0x03, 0x18, 0x32, 0x00, 0x03, + 0x20, 0x32, 0x00, 0x03, 0x28, 0x32, 0x00, 0x03, 0x98, 0x1e, 0x01, 0x02, 0x9c, 0x1e, 0x01, 0x02, 0xa0, 0x1e, 0x01, 0x02, 0xa4, 0x1e, 0x01, 0x02, 0xa8, 0x1e, 0x01, 0x02, 0xac, 0x1e, 0x01, 0x02, + 0xb0, 0x1e, 0x01, 0x02, 0x34, 0x00, 0x02, 0x02, 0x38, 0x00, 0x02, 0x02, 0x3c, 0x00, 0x02, 0x02, 0x40, 0x00, 0x02, 0x02, 0x90, 0x17, 0x03, 0x03, 0x98, 0x17, 0x03, 0x03, 0xa0, 0x17, 0x03, 0x03, + 0x30, 0x37, 0x04, 0x04, 0x40, 0x37, 0x04, 0x04, 0x40, 0x11, 0x05, 0x04, 0x00, 0x2e, 0x06, 0x05, 0x60, 0x0b, 0x07, 0x05, 0xc0, 0x05, 0x09, 0x06, 0x30, 0x32, 0x00, 0x03, 0x38, 0x32, 0x00, 0x03, + 0x40, 0x32, 0x00, 0x03, 0x48, 0x32, 0x00, 0x03, 0xb4, 0x1e, 0x01, 0x02, 0xb8, 0x1e, 0x01, 0x02, 0xbc, 0x1e, 0x01, 0x02, 0xc0, 0x1e, 0x01, 0x02, 0xc4, 0x1e, 0x01, 0x02, 0xc8, 0x1e, 0x01, 0x02, + 0xcc, 0x1e, 0x01, 0x02, 0x44, 0x00, 0x02, 0x02, 0x48, 0x00, 0x02, 0x02, 0x4c, 0x00, 0x02, 0x02, 0x50, 0x00, 0x02, 0x02, 0xa8, 0x17, 0x03, 0x03, 0xb0, 0x17, 0x03, 0x03, 0xb8, 0x17, 0x03, 0x03, + 0x50, 0x37, 0x04, 0x04, 0x60, 0x37, 0x04, 0x04, 0x50, 0x11, 0x05, 0x04, 0x20, 0x2e, 0x06, 0x05, 0x80, 0x0b, 0x07, 0x05, 0x00, 0x06, 0x09, 0x06, 0x50, 0x32, 0x00, 0x03, 0x58, 0x32, 0x00, 0x03, + 0x60, 0x32, 0x00, 0x03, 0x68, 0x32, 0x00, 0x03, 0xd0, 0x1e, 0x01, 0x02, 0xd4, 0x1e, 0x01, 0x02, 0xd8, 0x1e, 0x01, 0x02, 0xdc, 0x1e, 0x01, 0x02, 0xe0, 0x1e, 0x01, 0x02, 0xe4, 0x1e, 0x01, 0x02, + 0xe8, 0x1e, 0x01, 0x02, 0x54, 0x00, 0x02, 0x02, 0x58, 0x00, 0x02, 0x02, 0x5c, 0x00, 0x02, 0x02, 0x60, 0x00, 0x02, 0x02, 0xc0, 0x17, 0x03, 0x03, 0xc8, 0x17, 0x03, 0x03, 0xd0, 0x17, 0x03, 0x03, + 0x70, 0x37, 0x04, 0x04, 0x80, 0x37, 0x04, 0x04, 0x60, 0x11, 0x05, 0x04, 0x40, 0x2e, 0x06, 0x05, 0xa0, 0x0b, 0x07, 0x05, 0x40, 0x06, 0x09, 0x06, 0x70, 0x32, 0x00, 0x03, 0x78, 0x32, 0x00, 0x03, + 0x80, 0x32, 0x00, 0x03, 0x88, 0x32, 0x00, 0x03, 0xec, 0x1e, 0x01, 0x02, 0xf0, 0x1e, 0x01, 0x02, 0xf4, 0x1e, 0x01, 0x02, 0xf8, 0x1e, 0x01, 0x02, 0xfc, 0x1e, 0x01, 0x02, 0x00, 0x1f, 0x01, 0x02, + 0x04, 0x1f, 0x01, 0x02, 0x64, 0x00, 0x02, 0x02, 0x68, 0x00, 0x02, 0x02, 0x6c, 0x00, 0x02, 0x02, 0x70, 0x00, 0x02, 0x02, 0xd8, 0x17, 0x03, 0x03, 0xe0, 0x17, 0x03, 0x03, 0xe8, 0x17, 0x03, 0x03, + 0x90, 0x37, 0x04, 0x04, 0xa0, 0x37, 0x04, 0x04, 0x70, 0x11, 0x05, 0x04, 0x60, 0x2e, 0x06, 0x05, 0xc0, 0x0b, 0x07, 0x05, 0x80, 0x06, 0x09, 0x06, 0x90, 0x32, 0x00, 0x03, 0x98, 0x32, 0x00, 0x03, + 0xa0, 0x32, 0x00, 0x03, 0xa8, 0x32, 0x00, 0x03, 0x08, 0x1f, 0x01, 0x02, 0x0c, 0x1f, 0x01, 0x02, 0x10, 0x1f, 0x01, 0x02, 0x14, 0x1f, 0x01, 0x02, 0x18, 0x1f, 0x01, 0x02, 0x1c, 0x1f, 0x01, 0x02, + 0x20, 0x1f, 0x01, 0x02, 0x74, 0x00, 0x02, 0x02, 0x78, 0x00, 0x02, 0x02, 0x7c, 0x00, 0x02, 0x02, 0x80, 0x00, 0x02, 0x02, 0xf0, 0x17, 0x03, 0x03, 0xf8, 0x17, 0x03, 0x03, 0x00, 0x18, 0x03, 0x03, + 0xb0, 0x37, 0x04, 0x04, 0xc0, 0x37, 0x04, 0x04, 0x80, 0x11, 0x05, 0x04, 0x80, 0x2e, 0x06, 0x05, 0xe0, 0x0b, 0x07, 0x05, 0xc0, 0x06, 0x09, 0x06, 0xb0, 0x32, 0x00, 0x03, 0xb8, 0x32, 0x00, 0x03, + 0xc0, 0x32, 0x00, 0x03, 0xc8, 0x32, 0x00, 0x03, 0x24, 0x1f, 0x01, 0x02, 0x28, 0x1f, 0x01, 0x02, 0x2c, 0x1f, 0x01, 0x02, 0x30, 0x1f, 0x01, 0x02, 0x34, 0x1f, 0x01, 0x02, 0x38, 0x1f, 0x01, 0x02, + 0x3c, 0x1f, 0x01, 0x02, 0x84, 0x00, 0x02, 0x02, 0x88, 0x00, 0x02, 0x02, 0x8c, 0x00, 0x02, 0x02, 0x90, 0x00, 0x02, 0x02, 0x08, 0x18, 0x03, 0x03, 0x10, 0x18, 0x03, 0x03, 0x18, 0x18, 0x03, 0x03, + 0xd0, 0x37, 0x04, 0x04, 0xe0, 0x37, 0x04, 0x04, 0x90, 0x11, 0x05, 0x04, 0xa0, 0x2e, 0x06, 0x05, 0x00, 0x0c, 0x07, 0x05, 0x00, 0x07, 0x09, 0x06, 0xd0, 0x32, 0x00, 0x03, 0xd8, 0x32, 0x00, 0x03, + 0xe0, 0x32, 0x00, 0x03, 0xe8, 0x32, 0x00, 0x03, 0x40, 0x1f, 0x01, 0x02, 0x44, 0x1f, 0x01, 0x02, 0x48, 0x1f, 0x01, 0x02, 0x4c, 0x1f, 0x01, 0x02, 0x50, 0x1f, 0x01, 0x02, 0x54, 0x1f, 0x01, 0x02, + 0x58, 0x1f, 0x01, 0x02, 0x94, 0x00, 0x02, 0x02, 0x98, 0x00, 0x02, 0x02, 0x9c, 0x00, 0x02, 0x02, 0xa0, 0x00, 0x02, 0x02, 0x20, 0x18, 0x03, 0x03, 0x28, 0x18, 0x03, 0x03, 0x30, 0x18, 0x03, 0x03, + 0xf0, 0x37, 0x04, 0x04, 0x00, 0x38, 0x04, 0x04, 0xa0, 0x11, 0x05, 0x04, 0xc0, 0x2e, 0x06, 0x05, 0x20, 0x0c, 0x07, 0x05, 0x40, 0x07, 0x09, 0x06, 0xf0, 0x32, 0x00, 0x03, 0xf8, 0x32, 0x00, 0x03, + 0x00, 0x33, 0x00, 0x03, 0x08, 0x33, 0x00, 0x03, 0x5c, 0x1f, 0x01, 0x02, 0x60, 0x1f, 0x01, 0x02, 0x64, 0x1f, 0x01, 0x02, 0x68, 0x1f, 0x01, 0x02, 0x6c, 0x1f, 0x01, 0x02, 0x70, 0x1f, 0x01, 0x02, + 0x74, 0x1f, 0x01, 0x02, 0xa4, 0x00, 0x02, 0x02, 0xa8, 0x00, 0x02, 0x02, 0xac, 0x00, 0x02, 0x02, 0xb0, 0x00, 0x02, 0x02, 0x38, 0x18, 0x03, 0x03, 0x40, 0x18, 0x03, 0x03, 0x48, 0x18, 0x03, 0x03, + 0x10, 0x38, 0x04, 0x04, 0x20, 0x38, 0x04, 0x04, 0xb0, 0x11, 0x05, 0x04, 0xe0, 0x2e, 0x06, 0x05, 0x40, 0x0c, 0x07, 0x05, 0x80, 0x07, 0x09, 0x06, 0x10, 0x33, 0x00, 0x03, 0x18, 0x33, 0x00, 0x03, + 0x20, 0x33, 0x00, 0x03, 0x28, 0x33, 0x00, 0x03, 0x78, 0x1f, 0x01, 0x02, 0x7c, 0x1f, 0x01, 0x02, 0x80, 0x1f, 0x01, 0x02, 0x84, 0x1f, 0x01, 0x02, 0x88, 0x1f, 0x01, 0x02, 0x8c, 0x1f, 0x01, 0x02, + 0x90, 0x1f, 0x01, 0x02, 0xb4, 0x00, 0x02, 0x02, 0xb8, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x02, 0x02, 0xc0, 0x00, 0x02, 0x02, 0x50, 0x18, 0x03, 0x03, 0x58, 0x18, 0x03, 0x03, 0x60, 0x18, 0x03, 0x03, + 0x30, 0x38, 0x04, 0x04, 0x40, 0x38, 0x04, 0x04, 0xc0, 0x11, 0x05, 0x04, 0x00, 0x2f, 0x06, 0x05, 0x60, 0x0c, 0x07, 0x05, 0xc0, 0x07, 0x09, 0x06, 0x30, 0x33, 0x00, 0x03, 0x38, 0x33, 0x00, 0x03, + 0x40, 0x33, 0x00, 0x03, 0x48, 0x33, 0x00, 0x03, 0x94, 0x1f, 0x01, 0x02, 0x98, 0x1f, 0x01, 0x02, 0x9c, 0x1f, 0x01, 0x02, 0xa0, 0x1f, 0x01, 0x02, 0xa4, 0x1f, 0x01, 0x02, 0xa8, 0x1f, 0x01, 0x02, + 0xac, 0x1f, 0x01, 0x02, 0xc4, 0x00, 0x02, 0x02, 0xc8, 0x00, 0x02, 0x02, 0xcc, 0x00, 0x02, 0x02, 0xd0, 0x00, 0x02, 0x02, 0x68, 0x18, 0x03, 0x03, 0x70, 0x18, 0x03, 0x03, 0x78, 0x18, 0x03, 0x03, + 0x50, 0x38, 0x04, 0x04, 0x60, 0x38, 0x04, 0x04, 0xd0, 0x11, 0x05, 0x04, 0x20, 0x2f, 0x06, 0x05, 0x80, 0x0c, 0x07, 0x05, 0x00, 0x08, 0x09, 0x06, 0x50, 0x33, 0x00, 0x03, 0x58, 0x33, 0x00, 0x03, + 0x60, 0x33, 0x00, 0x03, 0x68, 0x33, 0x00, 0x03, 0xb0, 0x1f, 0x01, 0x02, 0xb4, 0x1f, 0x01, 0x02, 0xb8, 0x1f, 0x01, 0x02, 0xbc, 0x1f, 0x01, 0x02, 0xc0, 0x1f, 0x01, 0x02, 0xc4, 0x1f, 0x01, 0x02, + 0xc8, 0x1f, 0x01, 0x02, 0xd4, 0x00, 0x02, 0x02, 0xd8, 0x00, 0x02, 0x02, 0xdc, 0x00, 0x02, 0x02, 0xe0, 0x00, 0x02, 0x02, 0x80, 0x18, 0x03, 0x03, 0x88, 0x18, 0x03, 0x03, 0x90, 0x18, 0x03, 0x03, + 0x70, 0x38, 0x04, 0x04, 0x80, 0x38, 0x04, 0x04, 0xe0, 0x11, 0x05, 0x04, 0x40, 0x2f, 0x06, 0x05, 0xa0, 0x0c, 0x07, 0x05, 0x40, 0x08, 0x09, 0x06, 0x70, 0x33, 0x00, 0x03, 0x78, 0x33, 0x00, 0x03, + 0x80, 0x33, 0x00, 0x03, 0x88, 0x33, 0x00, 0x03, 0xcc, 0x1f, 0x01, 0x02, 0xd0, 0x1f, 0x01, 0x02, 0xd4, 0x1f, 0x01, 0x02, 0xd8, 0x1f, 0x01, 0x02, 0xdc, 0x1f, 0x01, 0x02, 0xe0, 0x1f, 0x01, 0x02, + 0xe4, 0x1f, 0x01, 0x02, 0xe4, 0x00, 0x02, 0x02, 0xe8, 0x00, 0x02, 0x02, 0xec, 0x00, 0x02, 0x02, 0xf0, 0x00, 0x02, 0x02, 0x98, 0x18, 0x03, 0x03, 0xa0, 0x18, 0x03, 0x03, 0xa8, 0x18, 0x03, 0x03, + 0x90, 0x38, 0x04, 0x04, 0xa0, 0x38, 0x04, 0x04, 0xf0, 0x11, 0x05, 0x04, 0x60, 0x2f, 0x06, 0x05, 0xc0, 0x0c, 0x07, 0x05, 0x80, 0x08, 0x09, 0x06, 0x90, 0x33, 0x00, 0x03, 0x98, 0x33, 0x00, 0x03, + 0xa0, 0x33, 0x00, 0x03, 0xa8, 0x33, 0x00, 0x03, 0xe8, 0x1f, 0x01, 0x02, 0xec, 0x1f, 0x01, 0x02, 0xf0, 0x1f, 0x01, 0x02, 0xf4, 0x1f, 0x01, 0x02, 0xf8, 0x1f, 0x01, 0x02, 0xfc, 0x1f, 0x01, 0x02, + 0x00, 0x20, 0x01, 0x02, 0xf4, 0x00, 0x02, 0x02, 0xf8, 0x00, 0x02, 0x02, 0xfc, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0xb0, 0x18, 0x03, 0x03, 0xb8, 0x18, 0x03, 0x03, 0xc0, 0x18, 0x03, 0x03, + 0xb0, 0x38, 0x04, 0x04, 0xc0, 0x38, 0x04, 0x04, 0x00, 0x12, 0x05, 0x04, 0x80, 0x2f, 0x06, 0x05, 0xe0, 0x0c, 0x07, 0x05, 0xc0, 0x08, 0x09, 0x06, 0xb0, 0x33, 0x00, 0x03, 0xb8, 0x33, 0x00, 0x03, + 0xc0, 0x33, 0x00, 0x03, 0xc8, 0x33, 0x00, 0x03, 0x04, 0x20, 0x01, 0x02, 0x08, 0x20, 0x01, 0x02, 0x0c, 0x20, 0x01, 0x02, 0x10, 0x20, 0x01, 0x02, 0x14, 0x20, 0x01, 0x02, 0x18, 0x20, 0x01, 0x02, + 0x1c, 0x20, 0x01, 0x02, 0x04, 0x01, 0x02, 0x02, 0x08, 0x01, 0x02, 0x02, 0x0c, 0x01, 0x02, 0x02, 0x10, 0x01, 0x02, 0x02, 0xc8, 0x18, 0x03, 0x03, 0xd0, 0x18, 0x03, 0x03, 0xd8, 0x18, 0x03, 0x03, + 0xd0, 0x38, 0x04, 0x04, 0xe0, 0x38, 0x04, 0x04, 0x10, 0x12, 0x05, 0x04, 0xa0, 0x2f, 0x06, 0x05, 0x00, 0x0d, 0x07, 0x05, 0x00, 0x09, 0x09, 0x06, 0xd0, 0x33, 0x00, 0x03, 0xd8, 0x33, 0x00, 0x03, + 0xe0, 0x33, 0x00, 0x03, 0xe8, 0x33, 0x00, 0x03, 0x20, 0x20, 0x01, 0x02, 0x24, 0x20, 0x01, 0x02, 0x28, 0x20, 0x01, 0x02, 0x2c, 0x20, 0x01, 0x02, 0x30, 0x20, 0x01, 0x02, 0x34, 0x20, 0x01, 0x02, + 0x14, 0x01, 0x02, 0x02, 0x18, 0x01, 0x02, 0x02, 0x1c, 0x01, 0x02, 0x02, 0x20, 0x01, 0x02, 0x02, 0x24, 0x01, 0x02, 0x02, 0xe0, 0x18, 0x03, 0x03, 0xe8, 0x18, 0x03, 0x03, 0xf0, 0x18, 0x03, 0x03, + 0xf0, 0x38, 0x04, 0x04, 0x00, 0x39, 0x04, 0x04, 0x20, 0x12, 0x05, 0x04, 0xc0, 0x2f, 0x06, 0x05, 0x20, 0x0d, 0x07, 0x05, 0x40, 0x09, 0x09, 0x06, 0xf0, 0x33, 0x00, 0x03, 0xf8, 0x33, 0x00, 0x03, + 0x00, 0x34, 0x00, 0x03, 0x08, 0x34, 0x00, 0x03, 0x38, 0x20, 0x01, 0x02, 0x3c, 0x20, 0x01, 0x02, 0x40, 0x20, 0x01, 0x02, 0x44, 0x20, 0x01, 0x02, 0x48, 0x20, 0x01, 0x02, 0x4c, 0x20, 0x01, 0x02, + 0x28, 0x01, 0x02, 0x02, 0x2c, 0x01, 0x02, 0x02, 0x30, 0x01, 0x02, 0x02, 0x34, 0x01, 0x02, 0x02, 0x38, 0x01, 0x02, 0x02, 0xf8, 0x18, 0x03, 0x03, 0x00, 0x19, 0x03, 0x03, 0x08, 0x19, 0x03, 0x03, + 0x10, 0x39, 0x04, 0x04, 0x20, 0x39, 0x04, 0x04, 0x30, 0x12, 0x05, 0x04, 0xe0, 0x2f, 0x06, 0x05, 0x40, 0x0d, 0x07, 0x05, 0x80, 0x09, 0x09, 0x06, 0x10, 0x34, 0x00, 0x03, 0x18, 0x34, 0x00, 0x03, + 0x20, 0x34, 0x00, 0x03, 0x28, 0x34, 0x00, 0x03, 0x50, 0x20, 0x01, 0x02, 0x54, 0x20, 0x01, 0x02, 0x58, 0x20, 0x01, 0x02, 0x5c, 0x20, 0x01, 0x02, 0x60, 0x20, 0x01, 0x02, 0x64, 0x20, 0x01, 0x02, + 0x3c, 0x01, 0x02, 0x02, 0x40, 0x01, 0x02, 0x02, 0x44, 0x01, 0x02, 0x02, 0x48, 0x01, 0x02, 0x02, 0x4c, 0x01, 0x02, 0x02, 0x10, 0x19, 0x03, 0x03, 0x18, 0x19, 0x03, 0x03, 0x20, 0x19, 0x03, 0x03, + 0x30, 0x39, 0x04, 0x04, 0x40, 0x39, 0x04, 0x04, 0x40, 0x12, 0x05, 0x04, 0x00, 0x30, 0x06, 0x05, 0x60, 0x0d, 0x07, 0x05, 0xc0, 0x09, 0x09, 0x06, 0x30, 0x34, 0x00, 0x03, 0x38, 0x34, 0x00, 0x03, + 0x40, 0x34, 0x00, 0x03, 0x48, 0x34, 0x00, 0x03, 0x68, 0x20, 0x01, 0x02, 0x6c, 0x20, 0x01, 0x02, 0x70, 0x20, 0x01, 0x02, 0x74, 0x20, 0x01, 0x02, 0x78, 0x20, 0x01, 0x02, 0x7c, 0x20, 0x01, 0x02, + 0x50, 0x01, 0x02, 0x02, 0x54, 0x01, 0x02, 0x02, 0x58, 0x01, 0x02, 0x02, 0x5c, 0x01, 0x02, 0x02, 0x60, 0x01, 0x02, 0x02, 0x28, 0x19, 0x03, 0x03, 0x30, 0x19, 0x03, 0x03, 0x38, 0x19, 0x03, 0x03, + 0x50, 0x39, 0x04, 0x04, 0x60, 0x39, 0x04, 0x04, 0x50, 0x12, 0x05, 0x04, 0x20, 0x30, 0x06, 0x05, 0x80, 0x0d, 0x07, 0x05, 0x00, 0x0a, 0x09, 0x06, 0x50, 0x34, 0x00, 0x03, 0x58, 0x34, 0x00, 0x03, + 0x60, 0x34, 0x00, 0x03, 0x68, 0x34, 0x00, 0x03, 0x80, 0x20, 0x01, 0x02, 0x84, 0x20, 0x01, 0x02, 0x88, 0x20, 0x01, 0x02, 0x8c, 0x20, 0x01, 0x02, 0x90, 0x20, 0x01, 0x02, 0x94, 0x20, 0x01, 0x02, + 0x64, 0x01, 0x02, 0x02, 0x68, 0x01, 0x02, 0x02, 0x6c, 0x01, 0x02, 0x02, 0x70, 0x01, 0x02, 0x02, 0x74, 0x01, 0x02, 0x02, 0x40, 0x19, 0x03, 0x03, 0x48, 0x19, 0x03, 0x03, 0x50, 0x19, 0x03, 0x03, + 0x70, 0x39, 0x04, 0x04, 0x80, 0x39, 0x04, 0x04, 0x60, 0x12, 0x05, 0x04, 0x40, 0x30, 0x06, 0x05, 0xa0, 0x0d, 0x07, 0x05, 0x40, 0x0a, 0x09, 0x06, 0x70, 0x34, 0x00, 0x03, 0x78, 0x34, 0x00, 0x03, + 0x80, 0x34, 0x00, 0x03, 0x88, 0x34, 0x00, 0x03, 0x98, 0x20, 0x01, 0x02, 0x9c, 0x20, 0x01, 0x02, 0xa0, 0x20, 0x01, 0x02, 0xa4, 0x20, 0x01, 0x02, 0xa8, 0x20, 0x01, 0x02, 0xac, 0x20, 0x01, 0x02, + 0x78, 0x01, 0x02, 0x02, 0x7c, 0x01, 0x02, 0x02, 0x80, 0x01, 0x02, 0x02, 0x84, 0x01, 0x02, 0x02, 0x88, 0x01, 0x02, 0x02, 0x58, 0x19, 0x03, 0x03, 0x60, 0x19, 0x03, 0x03, 0x68, 0x19, 0x03, 0x03, + 0x90, 0x39, 0x04, 0x04, 0xa0, 0x39, 0x04, 0x04, 0x70, 0x12, 0x05, 0x04, 0x60, 0x30, 0x06, 0x05, 0xc0, 0x0d, 0x07, 0x05, 0x80, 0x1d, 0x0a, 0x07, 0x90, 0x34, 0x00, 0x03, 0x98, 0x34, 0x00, 0x03, + 0xa0, 0x34, 0x00, 0x03, 0xa8, 0x34, 0x00, 0x03, 0xb0, 0x20, 0x01, 0x02, 0xb4, 0x20, 0x01, 0x02, 0xb8, 0x20, 0x01, 0x02, 0xbc, 0x20, 0x01, 0x02, 0xc0, 0x20, 0x01, 0x02, 0xc4, 0x20, 0x01, 0x02, + 0x8c, 0x01, 0x02, 0x02, 0x90, 0x01, 0x02, 0x02, 0x94, 0x01, 0x02, 0x02, 0x98, 0x01, 0x02, 0x02, 0x9c, 0x01, 0x02, 0x02, 0x70, 0x19, 0x03, 0x03, 0x78, 0x19, 0x03, 0x03, 0x80, 0x19, 0x03, 0x03, + 0xb0, 0x39, 0x04, 0x04, 0xc0, 0x39, 0x04, 0x04, 0x80, 0x12, 0x05, 0x04, 0x80, 0x30, 0x06, 0x05, 0xe0, 0x0d, 0x07, 0x05, 0x00, 0x1e, 0x0a, 0x07, 0xb0, 0x34, 0x00, 0x03, 0xb8, 0x34, 0x00, 0x03, + 0xc0, 0x34, 0x00, 0x03, 0xc8, 0x34, 0x00, 0x03, 0xc8, 0x20, 0x01, 0x02, 0xcc, 0x20, 0x01, 0x02, 0xd0, 0x20, 0x01, 0x02, 0xd4, 0x20, 0x01, 0x02, 0xd8, 0x20, 0x01, 0x02, 0xdc, 0x20, 0x01, 0x02, + 0xa0, 0x01, 0x02, 0x02, 0xa4, 0x01, 0x02, 0x02, 0xa8, 0x01, 0x02, 0x02, 0xac, 0x01, 0x02, 0x02, 0xb0, 0x01, 0x02, 0x02, 0x88, 0x19, 0x03, 0x03, 0x90, 0x19, 0x03, 0x03, 0x98, 0x19, 0x03, 0x03, + 0xd0, 0x39, 0x04, 0x04, 0xe0, 0x39, 0x04, 0x04, 0x90, 0x12, 0x05, 0x04, 0xa0, 0x30, 0x06, 0x05, 0x00, 0x0e, 0x07, 0x05, 0x80, 0x1e, 0x0a, 0x07, 0xd0, 0x34, 0x00, 0x03, 0xd8, 0x34, 0x00, 0x03, + 0xe0, 0x34, 0x00, 0x03, 0xe8, 0x34, 0x00, 0x03, 0xe0, 0x20, 0x01, 0x02, 0xe4, 0x20, 0x01, 0x02, 0xe8, 0x20, 0x01, 0x02, 0xec, 0x20, 0x01, 0x02, 0xf0, 0x20, 0x01, 0x02, 0xf4, 0x20, 0x01, 0x02, + 0xb4, 0x01, 0x02, 0x02, 0xb8, 0x01, 0x02, 0x02, 0xbc, 0x01, 0x02, 0x02, 0xc0, 0x01, 0x02, 0x02, 0xc4, 0x01, 0x02, 0x02, 0xa0, 0x19, 0x03, 0x03, 0xa8, 0x19, 0x03, 0x03, 0xb0, 0x19, 0x03, 0x03, + 0xf0, 0x39, 0x04, 0x04, 0x00, 0x3a, 0x04, 0x04, 0xa0, 0x12, 0x05, 0x04, 0xc0, 0x30, 0x06, 0x05, 0x20, 0x0e, 0x07, 0x05, 0x00, 0x1f, 0x0a, 0x07, 0xf0, 0x34, 0x00, 0x03, 0xf8, 0x34, 0x00, 0x03, + 0x00, 0x35, 0x00, 0x03, 0x08, 0x35, 0x00, 0x03, 0xf8, 0x20, 0x01, 0x02, 0xfc, 0x20, 0x01, 0x02, 0x00, 0x21, 0x01, 0x02, 0x04, 0x21, 0x01, 0x02, 0x08, 0x21, 0x01, 0x02, 0x0c, 0x21, 0x01, 0x02, + 0xc8, 0x01, 0x02, 0x02, 0xcc, 0x01, 0x02, 0x02, 0xd0, 0x01, 0x02, 0x02, 0xd4, 0x01, 0x02, 0x02, 0xd8, 0x01, 0x02, 0x02, 0xb8, 0x19, 0x03, 0x03, 0xc0, 0x19, 0x03, 0x03, 0xc8, 0x19, 0x03, 0x03, + 0x10, 0x3a, 0x04, 0x04, 0x20, 0x3a, 0x04, 0x04, 0xb0, 0x12, 0x05, 0x04, 0xe0, 0x30, 0x06, 0x05, 0x40, 0x0e, 0x07, 0x05, 0x80, 0x1f, 0x0a, 0x07, 0x10, 0x35, 0x00, 0x03, 0x18, 0x35, 0x00, 0x03, + 0x20, 0x35, 0x00, 0x03, 0x28, 0x35, 0x00, 0x03, 0x10, 0x21, 0x01, 0x02, 0x14, 0x21, 0x01, 0x02, 0x18, 0x21, 0x01, 0x02, 0x1c, 0x21, 0x01, 0x02, 0x20, 0x21, 0x01, 0x02, 0x24, 0x21, 0x01, 0x02, + 0xdc, 0x01, 0x02, 0x02, 0xe0, 0x01, 0x02, 0x02, 0xe4, 0x01, 0x02, 0x02, 0xe8, 0x01, 0x02, 0x02, 0xec, 0x01, 0x02, 0x02, 0xd0, 0x19, 0x03, 0x03, 0xd8, 0x19, 0x03, 0x03, 0xe0, 0x19, 0x03, 0x03, + 0x30, 0x3a, 0x04, 0x04, 0x40, 0x3a, 0x04, 0x04, 0xc0, 0x12, 0x05, 0x04, 0x00, 0x31, 0x06, 0x05, 0x60, 0x0e, 0x07, 0x05, 0x00, 0x20, 0x0a, 0x07, 0x30, 0x35, 0x00, 0x03, 0x38, 0x35, 0x00, 0x03, + 0x40, 0x35, 0x00, 0x03, 0x48, 0x35, 0x00, 0x03, 0x28, 0x21, 0x01, 0x02, 0x2c, 0x21, 0x01, 0x02, 0x30, 0x21, 0x01, 0x02, 0x34, 0x21, 0x01, 0x02, 0x38, 0x21, 0x01, 0x02, 0x3c, 0x21, 0x01, 0x02, + 0xf0, 0x01, 0x02, 0x02, 0xf4, 0x01, 0x02, 0x02, 0xf8, 0x01, 0x02, 0x02, 0xfc, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0xe8, 0x19, 0x03, 0x03, 0xf0, 0x19, 0x03, 0x03, 0xf8, 0x19, 0x03, 0x03, + 0x50, 0x3a, 0x04, 0x04, 0x60, 0x3a, 0x04, 0x04, 0xd0, 0x12, 0x05, 0x04, 0x20, 0x31, 0x06, 0x05, 0x80, 0x0e, 0x07, 0x05, 0x80, 0x20, 0x0a, 0x07, 0x50, 0x35, 0x00, 0x03, 0x58, 0x35, 0x00, 0x03, + 0x60, 0x35, 0x00, 0x03, 0x68, 0x35, 0x00, 0x03, 0x40, 0x21, 0x01, 0x02, 0x44, 0x21, 0x01, 0x02, 0x48, 0x21, 0x01, 0x02, 0x4c, 0x21, 0x01, 0x02, 0x50, 0x21, 0x01, 0x02, 0x54, 0x21, 0x01, 0x02, + 0x04, 0x02, 0x02, 0x02, 0x08, 0x02, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x02, 0x10, 0x02, 0x02, 0x02, 0x14, 0x02, 0x02, 0x02, 0x00, 0x1a, 0x03, 0x03, 0x08, 0x1a, 0x03, 0x03, 0x10, 0x1a, 0x03, 0x03, + 0x70, 0x3a, 0x04, 0x04, 0x80, 0x3a, 0x04, 0x04, 0xe0, 0x12, 0x05, 0x04, 0x40, 0x31, 0x06, 0x05, 0xa0, 0x0e, 0x07, 0x05, 0x00, 0x21, 0x0a, 0x07, 0x70, 0x35, 0x00, 0x03, 0x78, 0x35, 0x00, 0x03, + 0x80, 0x35, 0x00, 0x03, 0x88, 0x35, 0x00, 0x03, 0x58, 0x21, 0x01, 0x02, 0x5c, 0x21, 0x01, 0x02, 0x60, 0x21, 0x01, 0x02, 0x64, 0x21, 0x01, 0x02, 0x68, 0x21, 0x01, 0x02, 0x6c, 0x21, 0x01, 0x02, + 0x18, 0x02, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0x20, 0x02, 0x02, 0x02, 0x24, 0x02, 0x02, 0x02, 0x28, 0x02, 0x02, 0x02, 0x18, 0x1a, 0x03, 0x03, 0x20, 0x1a, 0x03, 0x03, 0x28, 0x1a, 0x03, 0x03, + 0x90, 0x3a, 0x04, 0x04, 0xa0, 0x3a, 0x04, 0x04, 0xf0, 0x12, 0x05, 0x04, 0x60, 0x31, 0x06, 0x05, 0xc0, 0x0e, 0x07, 0x05, 0x80, 0x21, 0x0a, 0x07, 0x90, 0x35, 0x00, 0x03, 0x98, 0x35, 0x00, 0x03, + 0xa0, 0x35, 0x00, 0x03, 0xa8, 0x35, 0x00, 0x03, 0x70, 0x21, 0x01, 0x02, 0x74, 0x21, 0x01, 0x02, 0x78, 0x21, 0x01, 0x02, 0x7c, 0x21, 0x01, 0x02, 0x80, 0x21, 0x01, 0x02, 0x84, 0x21, 0x01, 0x02, + 0x2c, 0x02, 0x02, 0x02, 0x30, 0x02, 0x02, 0x02, 0x34, 0x02, 0x02, 0x02, 0x38, 0x02, 0x02, 0x02, 0x3c, 0x02, 0x02, 0x02, 0x30, 0x1a, 0x03, 0x03, 0x38, 0x1a, 0x03, 0x03, 0x40, 0x1a, 0x03, 0x03, + 0xb0, 0x3a, 0x04, 0x04, 0xc0, 0x3a, 0x04, 0x04, 0x00, 0x13, 0x05, 0x04, 0x80, 0x31, 0x06, 0x05, 0xe0, 0x0e, 0x07, 0x05, 0x00, 0x22, 0x0a, 0x07, 0xb0, 0x35, 0x00, 0x03, 0xb8, 0x35, 0x00, 0x03, + 0xc0, 0x35, 0x00, 0x03, 0xc8, 0x35, 0x00, 0x03, 0x88, 0x21, 0x01, 0x02, 0x8c, 0x21, 0x01, 0x02, 0x90, 0x21, 0x01, 0x02, 0x94, 0x21, 0x01, 0x02, 0x98, 0x21, 0x01, 0x02, 0x9c, 0x21, 0x01, 0x02, + 0x40, 0x02, 0x02, 0x02, 0x44, 0x02, 0x02, 0x02, 0x48, 0x02, 0x02, 0x02, 0x4c, 0x02, 0x02, 0x02, 0x50, 0x02, 0x02, 0x02, 0x48, 0x1a, 0x03, 0x03, 0x50, 0x1a, 0x03, 0x03, 0x58, 0x1a, 0x03, 0x03, + 0xd0, 0x3a, 0x04, 0x04, 0xe0, 0x3a, 0x04, 0x04, 0x10, 0x13, 0x05, 0x04, 0xa0, 0x31, 0x06, 0x05, 0x00, 0x0f, 0x07, 0x05, 0x80, 0x22, 0x0a, 0x07, 0xd0, 0x35, 0x00, 0x03, 0xd8, 0x35, 0x00, 0x03, + 0xe0, 0x35, 0x00, 0x03, 0xe8, 0x35, 0x00, 0x03, 0xa0, 0x21, 0x01, 0x02, 0xa4, 0x21, 0x01, 0x02, 0xa8, 0x21, 0x01, 0x02, 0xac, 0x21, 0x01, 0x02, 0xb0, 0x21, 0x01, 0x02, 0xb4, 0x21, 0x01, 0x02, + 0x54, 0x02, 0x02, 0x02, 0x58, 0x02, 0x02, 0x02, 0x5c, 0x02, 0x02, 0x02, 0x60, 0x02, 0x02, 0x02, 0x64, 0x02, 0x02, 0x02, 0x60, 0x1a, 0x03, 0x03, 0x68, 0x1a, 0x03, 0x03, 0x70, 0x1a, 0x03, 0x03, + 0xf0, 0x3a, 0x04, 0x04, 0x00, 0x3b, 0x04, 0x04, 0x20, 0x13, 0x05, 0x04, 0xc0, 0x31, 0x06, 0x05, 0x20, 0x0f, 0x07, 0x05, 0x00, 0x23, 0x0a, 0x07, 0xf0, 0x35, 0x00, 0x03, 0xf8, 0x35, 0x00, 0x03, + 0x00, 0x36, 0x00, 0x03, 0x08, 0x36, 0x00, 0x03, 0xb8, 0x21, 0x01, 0x02, 0xbc, 0x21, 0x01, 0x02, 0xc0, 0x21, 0x01, 0x02, 0xc4, 0x21, 0x01, 0x02, 0xc8, 0x21, 0x01, 0x02, 0xcc, 0x21, 0x01, 0x02, + 0x68, 0x02, 0x02, 0x02, 0x6c, 0x02, 0x02, 0x02, 0x70, 0x02, 0x02, 0x02, 0x74, 0x02, 0x02, 0x02, 0x78, 0x02, 0x02, 0x02, 0x78, 0x1a, 0x03, 0x03, 0x80, 0x1a, 0x03, 0x03, 0x88, 0x1a, 0x03, 0x03, + 0x10, 0x3b, 0x04, 0x04, 0x20, 0x3b, 0x04, 0x04, 0x30, 0x13, 0x05, 0x04, 0xe0, 0x31, 0x06, 0x05, 0x40, 0x0f, 0x07, 0x05, 0x80, 0x23, 0x0a, 0x07, 0x10, 0x36, 0x00, 0x03, 0x18, 0x36, 0x00, 0x03, + 0x20, 0x36, 0x00, 0x03, 0x28, 0x36, 0x00, 0x03, 0xd0, 0x21, 0x01, 0x02, 0xd4, 0x21, 0x01, 0x02, 0xd8, 0x21, 0x01, 0x02, 0xdc, 0x21, 0x01, 0x02, 0xe0, 0x21, 0x01, 0x02, 0xe4, 0x21, 0x01, 0x02, + 0x7c, 0x02, 0x02, 0x02, 0x80, 0x02, 0x02, 0x02, 0x84, 0x02, 0x02, 0x02, 0x88, 0x02, 0x02, 0x02, 0x8c, 0x02, 0x02, 0x02, 0x90, 0x1a, 0x03, 0x03, 0x98, 0x1a, 0x03, 0x03, 0xa0, 0x1a, 0x03, 0x03, + 0x30, 0x3b, 0x04, 0x04, 0x40, 0x3b, 0x04, 0x04, 0x40, 0x13, 0x05, 0x04, 0x00, 0x32, 0x06, 0x05, 0x60, 0x0f, 0x07, 0x05, 0x00, 0x24, 0x0a, 0x07, 0x30, 0x36, 0x00, 0x03, 0x38, 0x36, 0x00, 0x03, + 0x40, 0x36, 0x00, 0x03, 0x48, 0x36, 0x00, 0x03, 0xe8, 0x21, 0x01, 0x02, 0xec, 0x21, 0x01, 0x02, 0xf0, 0x21, 0x01, 0x02, 0xf4, 0x21, 0x01, 0x02, 0xf8, 0x21, 0x01, 0x02, 0xfc, 0x21, 0x01, 0x02, + 0x90, 0x02, 0x02, 0x02, 0x94, 0x02, 0x02, 0x02, 0x98, 0x02, 0x02, 0x02, 0x9c, 0x02, 0x02, 0x02, 0xa0, 0x02, 0x02, 0x02, 0xa8, 0x1a, 0x03, 0x03, 0xb0, 0x1a, 0x03, 0x03, 0xb8, 0x1a, 0x03, 0x03, + 0x50, 0x3b, 0x04, 0x04, 0x60, 0x3b, 0x04, 0x04, 0x50, 0x13, 0x05, 0x04, 0x20, 0x32, 0x06, 0x05, 0x80, 0x0f, 0x07, 0x05, 0x80, 0x24, 0x0a, 0x07, 0x50, 0x36, 0x00, 0x03, 0x58, 0x36, 0x00, 0x03, + 0x60, 0x36, 0x00, 0x03, 0x68, 0x36, 0x00, 0x03, 0x00, 0x22, 0x01, 0x02, 0x04, 0x22, 0x01, 0x02, 0x08, 0x22, 0x01, 0x02, 0x0c, 0x22, 0x01, 0x02, 0x10, 0x22, 0x01, 0x02, 0x14, 0x22, 0x01, 0x02, + 0xa4, 0x02, 0x02, 0x02, 0xa8, 0x02, 0x02, 0x02, 0xac, 0x02, 0x02, 0x02, 0xb0, 0x02, 0x02, 0x02, 0xb4, 0x02, 0x02, 0x02, 0xc0, 0x1a, 0x03, 0x03, 0xc8, 0x1a, 0x03, 0x03, 0xd0, 0x1a, 0x03, 0x03, + 0x70, 0x3b, 0x04, 0x04, 0x80, 0x3b, 0x04, 0x04, 0x60, 0x13, 0x05, 0x04, 0x40, 0x32, 0x06, 0x05, 0xa0, 0x0f, 0x07, 0x05, 0x00, 0x25, 0x0a, 0x07, 0x70, 0x36, 0x00, 0x03, 0x78, 0x36, 0x00, 0x03, + 0x80, 0x36, 0x00, 0x03, 0x88, 0x36, 0x00, 0x03, 0x18, 0x22, 0x01, 0x02, 0x1c, 0x22, 0x01, 0x02, 0x20, 0x22, 0x01, 0x02, 0x24, 0x22, 0x01, 0x02, 0x28, 0x22, 0x01, 0x02, 0x2c, 0x22, 0x01, 0x02, + 0xb8, 0x02, 0x02, 0x02, 0xbc, 0x02, 0x02, 0x02, 0xc0, 0x02, 0x02, 0x02, 0xc4, 0x02, 0x02, 0x02, 0xc8, 0x02, 0x02, 0x02, 0xd8, 0x1a, 0x03, 0x03, 0xe0, 0x1a, 0x03, 0x03, 0xe8, 0x1a, 0x03, 0x03, + 0x90, 0x3b, 0x04, 0x04, 0xa0, 0x3b, 0x04, 0x04, 0x70, 0x13, 0x05, 0x04, 0x60, 0x32, 0x06, 0x05, 0xc0, 0x0f, 0x07, 0x05, 0x80, 0x25, 0x0a, 0x07, 0x90, 0x36, 0x00, 0x03, 0x98, 0x36, 0x00, 0x03, + 0xa0, 0x36, 0x00, 0x03, 0xa8, 0x36, 0x00, 0x03, 0x30, 0x22, 0x01, 0x02, 0x34, 0x22, 0x01, 0x02, 0x38, 0x22, 0x01, 0x02, 0x3c, 0x22, 0x01, 0x02, 0x40, 0x22, 0x01, 0x02, 0x44, 0x22, 0x01, 0x02, + 0xcc, 0x02, 0x02, 0x02, 0xd0, 0x02, 0x02, 0x02, 0xd4, 0x02, 0x02, 0x02, 0xd8, 0x02, 0x02, 0x02, 0xdc, 0x02, 0x02, 0x02, 0xf0, 0x1a, 0x03, 0x03, 0xf8, 0x1a, 0x03, 0x03, 0x00, 0x1b, 0x03, 0x03, + 0xb0, 0x3b, 0x04, 0x04, 0xc0, 0x3b, 0x04, 0x04, 0x80, 0x13, 0x05, 0x04, 0x80, 0x32, 0x06, 0x05, 0xe0, 0x0f, 0x07, 0x05, 0x00, 0x3f, 0x0b, 0x08, 0xb0, 0x36, 0x00, 0x03, 0xb8, 0x36, 0x00, 0x03, + 0xc0, 0x36, 0x00, 0x03, 0xc8, 0x36, 0x00, 0x03, 0x48, 0x22, 0x01, 0x02, 0x4c, 0x22, 0x01, 0x02, 0x50, 0x22, 0x01, 0x02, 0x54, 0x22, 0x01, 0x02, 0x58, 0x22, 0x01, 0x02, 0x5c, 0x22, 0x01, 0x02, + 0xe0, 0x02, 0x02, 0x02, 0xe4, 0x02, 0x02, 0x02, 0xe8, 0x02, 0x02, 0x02, 0xec, 0x02, 0x02, 0x02, 0xf0, 0x02, 0x02, 0x02, 0x08, 0x1b, 0x03, 0x03, 0x10, 0x1b, 0x03, 0x03, 0x18, 0x1b, 0x03, 0x03, + 0xd0, 0x3b, 0x04, 0x04, 0xe0, 0x3b, 0x04, 0x04, 0x90, 0x13, 0x05, 0x04, 0xa0, 0x32, 0x06, 0x05, 0x00, 0x10, 0x07, 0x05, 0x00, 0x00, 0x0b, 0x07, 0xd0, 0x36, 0x00, 0x03, 0xd8, 0x36, 0x00, 0x03, + 0xe0, 0x36, 0x00, 0x03, 0xe8, 0x36, 0x00, 0x03, 0x60, 0x22, 0x01, 0x02, 0x64, 0x22, 0x01, 0x02, 0x68, 0x22, 0x01, 0x02, 0x6c, 0x22, 0x01, 0x02, 0x70, 0x22, 0x01, 0x02, 0x74, 0x22, 0x01, 0x02, + 0xf4, 0x02, 0x02, 0x02, 0xf8, 0x02, 0x02, 0x02, 0xfc, 0x02, 0x02, 0x02, 0x00, 0x03, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x20, 0x1b, 0x03, 0x03, 0x28, 0x1b, 0x03, 0x03, 0x30, 0x1b, 0x03, 0x03, + 0xf0, 0x3b, 0x04, 0x04, 0x00, 0x3c, 0x04, 0x04, 0xa0, 0x13, 0x05, 0x04, 0xc0, 0x32, 0x06, 0x05, 0x20, 0x10, 0x07, 0x05, 0x80, 0x00, 0x0b, 0x07, 0xf0, 0x36, 0x00, 0x03, 0xf8, 0x36, 0x00, 0x03, + 0x00, 0x37, 0x00, 0x03, 0x08, 0x37, 0x00, 0x03, 0x78, 0x22, 0x01, 0x02, 0x7c, 0x22, 0x01, 0x02, 0x80, 0x22, 0x01, 0x02, 0x84, 0x22, 0x01, 0x02, 0x88, 0x22, 0x01, 0x02, 0x8c, 0x22, 0x01, 0x02, + 0x08, 0x03, 0x02, 0x02, 0x0c, 0x03, 0x02, 0x02, 0x10, 0x03, 0x02, 0x02, 0x14, 0x03, 0x02, 0x02, 0x18, 0x03, 0x02, 0x02, 0x38, 0x1b, 0x03, 0x03, 0x40, 0x1b, 0x03, 0x03, 0x48, 0x1b, 0x03, 0x03, + 0x10, 0x3c, 0x04, 0x04, 0x20, 0x3c, 0x04, 0x04, 0xb0, 0x13, 0x05, 0x04, 0xe0, 0x32, 0x06, 0x05, 0x40, 0x10, 0x07, 0x05, 0x00, 0x01, 0x0b, 0x07, 0x10, 0x37, 0x00, 0x03, 0x18, 0x37, 0x00, 0x03, + 0x20, 0x37, 0x00, 0x03, 0x28, 0x37, 0x00, 0x03, 0x90, 0x22, 0x01, 0x02, 0x94, 0x22, 0x01, 0x02, 0x98, 0x22, 0x01, 0x02, 0x9c, 0x22, 0x01, 0x02, 0xa0, 0x22, 0x01, 0x02, 0xa4, 0x22, 0x01, 0x02, + 0x1c, 0x03, 0x02, 0x02, 0x20, 0x03, 0x02, 0x02, 0x24, 0x03, 0x02, 0x02, 0x28, 0x03, 0x02, 0x02, 0x2c, 0x03, 0x02, 0x02, 0x50, 0x1b, 0x03, 0x03, 0x58, 0x1b, 0x03, 0x03, 0x60, 0x1b, 0x03, 0x03, + 0x30, 0x3c, 0x04, 0x04, 0x40, 0x3c, 0x04, 0x04, 0xc0, 0x13, 0x05, 0x04, 0x00, 0x33, 0x06, 0x05, 0x60, 0x10, 0x07, 0x05, 0x80, 0x01, 0x0b, 0x07, 0x30, 0x37, 0x00, 0x03, 0x38, 0x37, 0x00, 0x03, + 0x40, 0x37, 0x00, 0x03, 0x48, 0x37, 0x00, 0x03, 0xa8, 0x22, 0x01, 0x02, 0xac, 0x22, 0x01, 0x02, 0xb0, 0x22, 0x01, 0x02, 0xb4, 0x22, 0x01, 0x02, 0xb8, 0x22, 0x01, 0x02, 0xbc, 0x22, 0x01, 0x02, + 0x30, 0x03, 0x02, 0x02, 0x34, 0x03, 0x02, 0x02, 0x38, 0x03, 0x02, 0x02, 0x3c, 0x03, 0x02, 0x02, 0x40, 0x03, 0x02, 0x02, 0x68, 0x1b, 0x03, 0x03, 0x70, 0x1b, 0x03, 0x03, 0x78, 0x1b, 0x03, 0x03, + 0x50, 0x3c, 0x04, 0x04, 0x60, 0x3c, 0x04, 0x04, 0xd0, 0x13, 0x05, 0x04, 0x20, 0x33, 0x06, 0x05, 0x80, 0x10, 0x07, 0x05, 0x00, 0x02, 0x0b, 0x07, 0x50, 0x37, 0x00, 0x03, 0x58, 0x37, 0x00, 0x03, + 0x60, 0x37, 0x00, 0x03, 0x68, 0x37, 0x00, 0x03, 0xc0, 0x22, 0x01, 0x02, 0xc4, 0x22, 0x01, 0x02, 0xc8, 0x22, 0x01, 0x02, 0xcc, 0x22, 0x01, 0x02, 0xd0, 0x22, 0x01, 0x02, 0xd4, 0x22, 0x01, 0x02, + 0x44, 0x03, 0x02, 0x02, 0x48, 0x03, 0x02, 0x02, 0x4c, 0x03, 0x02, 0x02, 0x50, 0x03, 0x02, 0x02, 0x54, 0x03, 0x02, 0x02, 0x80, 0x1b, 0x03, 0x03, 0x88, 0x1b, 0x03, 0x03, 0x90, 0x1b, 0x03, 0x03, + 0x70, 0x3c, 0x04, 0x04, 0x80, 0x3c, 0x04, 0x04, 0xe0, 0x13, 0x05, 0x04, 0x40, 0x33, 0x06, 0x05, 0x40, 0x27, 0x08, 0x06, 0x80, 0x02, 0x0b, 0x07, 0x70, 0x37, 0x00, 0x03, 0x78, 0x37, 0x00, 0x03, + 0x80, 0x37, 0x00, 0x03, 0x88, 0x37, 0x00, 0x03, 0xd8, 0x22, 0x01, 0x02, 0xdc, 0x22, 0x01, 0x02, 0xe0, 0x22, 0x01, 0x02, 0xe4, 0x22, 0x01, 0x02, 0xe8, 0x22, 0x01, 0x02, 0xec, 0x22, 0x01, 0x02, + 0x58, 0x03, 0x02, 0x02, 0x5c, 0x03, 0x02, 0x02, 0x60, 0x03, 0x02, 0x02, 0x64, 0x03, 0x02, 0x02, 0x68, 0x03, 0x02, 0x02, 0x98, 0x1b, 0x03, 0x03, 0xa0, 0x1b, 0x03, 0x03, 0x90, 0x3c, 0x04, 0x04, + 0xa0, 0x3c, 0x04, 0x04, 0xb0, 0x3c, 0x04, 0x04, 0xf0, 0x13, 0x05, 0x04, 0x60, 0x33, 0x06, 0x05, 0x80, 0x27, 0x08, 0x06, 0x00, 0x03, 0x0b, 0x07, 0x90, 0x37, 0x00, 0x03, 0x98, 0x37, 0x00, 0x03, + 0xa0, 0x37, 0x00, 0x03, 0xa8, 0x37, 0x00, 0x03, 0xf0, 0x22, 0x01, 0x02, 0xf4, 0x22, 0x01, 0x02, 0xf8, 0x22, 0x01, 0x02, 0xfc, 0x22, 0x01, 0x02, 0x00, 0x23, 0x01, 0x02, 0x04, 0x23, 0x01, 0x02, + 0x6c, 0x03, 0x02, 0x02, 0x70, 0x03, 0x02, 0x02, 0x74, 0x03, 0x02, 0x02, 0x78, 0x03, 0x02, 0x02, 0x7c, 0x03, 0x02, 0x02, 0xa8, 0x1b, 0x03, 0x03, 0xb0, 0x1b, 0x03, 0x03, 0xc0, 0x3c, 0x04, 0x04, + 0xd0, 0x3c, 0x04, 0x04, 0xe0, 0x3c, 0x04, 0x04, 0x00, 0x14, 0x05, 0x04, 0x80, 0x33, 0x06, 0x05, 0xc0, 0x27, 0x08, 0x06, 0x80, 0x03, 0x0b, 0x07, 0xb0, 0x37, 0x00, 0x03, 0xb8, 0x37, 0x00, 0x03, + 0xc0, 0x37, 0x00, 0x03, 0xc8, 0x37, 0x00, 0x03, 0x08, 0x23, 0x01, 0x02, 0x0c, 0x23, 0x01, 0x02, 0x10, 0x23, 0x01, 0x02, 0x14, 0x23, 0x01, 0x02, 0x18, 0x23, 0x01, 0x02, 0x1c, 0x23, 0x01, 0x02, + 0x80, 0x03, 0x02, 0x02, 0x84, 0x03, 0x02, 0x02, 0x88, 0x03, 0x02, 0x02, 0x8c, 0x03, 0x02, 0x02, 0xb8, 0x1b, 0x03, 0x03, 0xc0, 0x1b, 0x03, 0x03, 0xc8, 0x1b, 0x03, 0x03, 0xf0, 0x3c, 0x04, 0x04, + 0x00, 0x3d, 0x04, 0x04, 0x10, 0x14, 0x05, 0x04, 0x20, 0x14, 0x05, 0x04, 0xa0, 0x33, 0x06, 0x05, 0x00, 0x28, 0x08, 0x06, 0x00, 0x04, 0x0b, 0x07, 0xd0, 0x37, 0x00, 0x03, 0xd8, 0x37, 0x00, 0x03, + 0xe0, 0x37, 0x00, 0x03, 0xe8, 0x37, 0x00, 0x03, 0x20, 0x23, 0x01, 0x02, 0x24, 0x23, 0x01, 0x02, 0x28, 0x23, 0x01, 0x02, 0x2c, 0x23, 0x01, 0x02, 0x30, 0x23, 0x01, 0x02, 0x34, 0x23, 0x01, 0x02, + 0x90, 0x03, 0x02, 0x02, 0x94, 0x03, 0x02, 0x02, 0x98, 0x03, 0x02, 0x02, 0x9c, 0x03, 0x02, 0x02, 0xd0, 0x1b, 0x03, 0x03, 0xd8, 0x1b, 0x03, 0x03, 0xe0, 0x1b, 0x03, 0x03, 0x10, 0x3d, 0x04, 0x04, + 0x20, 0x3d, 0x04, 0x04, 0x30, 0x14, 0x05, 0x04, 0x40, 0x14, 0x05, 0x04, 0xc0, 0x33, 0x06, 0x05, 0x40, 0x28, 0x08, 0x06, 0x80, 0x04, 0x0b, 0x07, 0xf0, 0x37, 0x00, 0x03, 0xf8, 0x37, 0x00, 0x03, + 0x00, 0x38, 0x00, 0x03, 0x08, 0x38, 0x00, 0x03, 0x38, 0x23, 0x01, 0x02, 0x3c, 0x23, 0x01, 0x02, 0x40, 0x23, 0x01, 0x02, 0x44, 0x23, 0x01, 0x02, 0x48, 0x23, 0x01, 0x02, 0x4c, 0x23, 0x01, 0x02, + 0xa0, 0x03, 0x02, 0x02, 0xa4, 0x03, 0x02, 0x02, 0xa8, 0x03, 0x02, 0x02, 0xac, 0x03, 0x02, 0x02, 0xe8, 0x1b, 0x03, 0x03, 0xf0, 0x1b, 0x03, 0x03, 0xf8, 0x1b, 0x03, 0x03, 0x30, 0x3d, 0x04, 0x04, + 0x40, 0x3d, 0x04, 0x04, 0x50, 0x14, 0x05, 0x04, 0x60, 0x14, 0x05, 0x04, 0xe0, 0x33, 0x06, 0x05, 0x80, 0x28, 0x08, 0x06, 0x00, 0x05, 0x0b, 0x07, 0x10, 0x38, 0x00, 0x03, 0x18, 0x38, 0x00, 0x03, + 0x20, 0x38, 0x00, 0x03, 0x28, 0x38, 0x00, 0x03, 0x50, 0x23, 0x01, 0x02, 0x54, 0x23, 0x01, 0x02, 0x58, 0x23, 0x01, 0x02, 0x5c, 0x23, 0x01, 0x02, 0x60, 0x23, 0x01, 0x02, 0x64, 0x23, 0x01, 0x02, + 0xb0, 0x03, 0x02, 0x02, 0xb4, 0x03, 0x02, 0x02, 0xb8, 0x03, 0x02, 0x02, 0xbc, 0x03, 0x02, 0x02, 0x00, 0x1c, 0x03, 0x03, 0x08, 0x1c, 0x03, 0x03, 0x10, 0x1c, 0x03, 0x03, 0x50, 0x3d, 0x04, 0x04, + 0x60, 0x3d, 0x04, 0x04, 0x70, 0x14, 0x05, 0x04, 0x80, 0x14, 0x05, 0x04, 0x00, 0x34, 0x06, 0x05, 0xc0, 0x28, 0x08, 0x06, 0x00, 0x16, 0x0c, 0x08, 0x30, 0x38, 0x00, 0x03, 0x38, 0x38, 0x00, 0x03, + 0x40, 0x38, 0x00, 0x03, 0x48, 0x38, 0x00, 0x03, 0x68, 0x23, 0x01, 0x02, 0x6c, 0x23, 0x01, 0x02, 0x70, 0x23, 0x01, 0x02, 0x74, 0x23, 0x01, 0x02, 0x78, 0x23, 0x01, 0x02, 0x7c, 0x23, 0x01, 0x02, + 0xc0, 0x03, 0x02, 0x02, 0xc4, 0x03, 0x02, 0x02, 0xc8, 0x03, 0x02, 0x02, 0xcc, 0x03, 0x02, 0x02, 0x18, 0x1c, 0x03, 0x03, 0x20, 0x1c, 0x03, 0x03, 0x28, 0x1c, 0x03, 0x03, 0x70, 0x3d, 0x04, 0x04, + 0x80, 0x3d, 0x04, 0x04, 0x90, 0x14, 0x05, 0x04, 0xa0, 0x14, 0x05, 0x04, 0x20, 0x34, 0x06, 0x05, 0x00, 0x29, 0x08, 0x06, 0x00, 0x17, 0x0c, 0x08, 0x50, 0x38, 0x00, 0x03, 0x58, 0x38, 0x00, 0x03, + 0x60, 0x38, 0x00, 0x03, 0x68, 0x38, 0x00, 0x03, 0x80, 0x23, 0x01, 0x02, 0x84, 0x23, 0x01, 0x02, 0x88, 0x23, 0x01, 0x02, 0x8c, 0x23, 0x01, 0x02, 0x90, 0x23, 0x01, 0x02, 0x94, 0x23, 0x01, 0x02, + 0xd0, 0x03, 0x02, 0x02, 0xd4, 0x03, 0x02, 0x02, 0xd8, 0x03, 0x02, 0x02, 0xdc, 0x03, 0x02, 0x02, 0x30, 0x1c, 0x03, 0x03, 0x38, 0x1c, 0x03, 0x03, 0x40, 0x1c, 0x03, 0x03, 0x90, 0x3d, 0x04, 0x04, + 0xa0, 0x3d, 0x04, 0x04, 0xb0, 0x14, 0x05, 0x04, 0xc0, 0x14, 0x05, 0x04, 0x40, 0x34, 0x06, 0x05, 0x40, 0x29, 0x08, 0x06, 0x00, 0x18, 0x0c, 0x08, 0x70, 0x38, 0x00, 0x03, 0x78, 0x38, 0x00, 0x03, + 0x80, 0x38, 0x00, 0x03, 0x88, 0x38, 0x00, 0x03, 0x98, 0x23, 0x01, 0x02, 0x9c, 0x23, 0x01, 0x02, 0xa0, 0x23, 0x01, 0x02, 0xa4, 0x23, 0x01, 0x02, 0xa8, 0x23, 0x01, 0x02, 0xac, 0x23, 0x01, 0x02, + 0xe0, 0x03, 0x02, 0x02, 0xe4, 0x03, 0x02, 0x02, 0xe8, 0x03, 0x02, 0x02, 0xec, 0x03, 0x02, 0x02, 0x48, 0x1c, 0x03, 0x03, 0x50, 0x1c, 0x03, 0x03, 0x58, 0x1c, 0x03, 0x03, 0xb0, 0x3d, 0x04, 0x04, + 0xc0, 0x3d, 0x04, 0x04, 0xd0, 0x14, 0x05, 0x04, 0xe0, 0x14, 0x05, 0x04, 0x60, 0x34, 0x06, 0x05, 0x80, 0x29, 0x08, 0x06, 0x00, 0x19, 0x0c, 0x08, 0x90, 0x38, 0x00, 0x03, 0x98, 0x38, 0x00, 0x03, + 0xa0, 0x38, 0x00, 0x03, 0xa8, 0x38, 0x00, 0x03, 0xb0, 0x23, 0x01, 0x02, 0xb4, 0x23, 0x01, 0x02, 0xb8, 0x23, 0x01, 0x02, 0xbc, 0x23, 0x01, 0x02, 0xc0, 0x23, 0x01, 0x02, 0xc4, 0x23, 0x01, 0x02, + 0xf0, 0x03, 0x02, 0x02, 0xf4, 0x03, 0x02, 0x02, 0xf8, 0x03, 0x02, 0x02, 0xfc, 0x03, 0x02, 0x02, 0x60, 0x1c, 0x03, 0x03, 0x68, 0x1c, 0x03, 0x03, 0x70, 0x1c, 0x03, 0x03, 0xd0, 0x3d, 0x04, 0x04, + 0xe0, 0x3d, 0x04, 0x04, 0xf0, 0x14, 0x05, 0x04, 0x00, 0x15, 0x05, 0x04, 0x80, 0x34, 0x06, 0x05, 0xc0, 0x29, 0x08, 0x06, 0x00, 0x1a, 0x0c, 0x08, 0xb0, 0x38, 0x00, 0x03, 0xb8, 0x38, 0x00, 0x03, + 0xc0, 0x38, 0x00, 0x03, 0xc8, 0x38, 0x00, 0x03, 0xc8, 0x23, 0x01, 0x02, 0xcc, 0x23, 0x01, 0x02, 0xd0, 0x23, 0x01, 0x02, 0xd4, 0x23, 0x01, 0x02, 0xd8, 0x23, 0x01, 0x02, 0xdc, 0x23, 0x01, 0x02, + 0x00, 0x04, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x08, 0x04, 0x02, 0x02, 0x0c, 0x04, 0x02, 0x02, 0x78, 0x1c, 0x03, 0x03, 0x80, 0x1c, 0x03, 0x03, 0x88, 0x1c, 0x03, 0x03, 0xf0, 0x3d, 0x04, 0x04, + 0x00, 0x3e, 0x04, 0x04, 0x10, 0x15, 0x05, 0x04, 0x20, 0x15, 0x05, 0x04, 0xa0, 0x34, 0x06, 0x05, 0x00, 0x2a, 0x08, 0x06, 0x00, 0x1b, 0x0c, 0x08, 0xd0, 0x38, 0x00, 0x03, 0xd8, 0x38, 0x00, 0x03, + 0xe0, 0x38, 0x00, 0x03, 0xe8, 0x38, 0x00, 0x03, 0xe0, 0x23, 0x01, 0x02, 0xe4, 0x23, 0x01, 0x02, 0xe8, 0x23, 0x01, 0x02, 0xec, 0x23, 0x01, 0x02, 0xf0, 0x23, 0x01, 0x02, 0xf4, 0x23, 0x01, 0x02, + 0x10, 0x04, 0x02, 0x02, 0x14, 0x04, 0x02, 0x02, 0x18, 0x04, 0x02, 0x02, 0x1c, 0x04, 0x02, 0x02, 0x90, 0x1c, 0x03, 0x03, 0x98, 0x1c, 0x03, 0x03, 0xa0, 0x1c, 0x03, 0x03, 0x10, 0x3e, 0x04, 0x04, + 0x20, 0x3e, 0x04, 0x04, 0x30, 0x15, 0x05, 0x04, 0x40, 0x15, 0x05, 0x04, 0xc0, 0x34, 0x06, 0x05, 0x40, 0x2a, 0x08, 0x06, 0x00, 0x1c, 0x0c, 0x08, 0xf0, 0x38, 0x00, 0x03, 0xf8, 0x38, 0x00, 0x03, + 0x00, 0x39, 0x00, 0x03, 0x08, 0x39, 0x00, 0x03, 0xf8, 0x23, 0x01, 0x02, 0xfc, 0x23, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x04, 0x24, 0x01, 0x02, 0x08, 0x24, 0x01, 0x02, 0x0c, 0x24, 0x01, 0x02, + 0x20, 0x04, 0x02, 0x02, 0x24, 0x04, 0x02, 0x02, 0x28, 0x04, 0x02, 0x02, 0x2c, 0x04, 0x02, 0x02, 0xa8, 0x1c, 0x03, 0x03, 0xb0, 0x1c, 0x03, 0x03, 0xb8, 0x1c, 0x03, 0x03, 0x30, 0x3e, 0x04, 0x04, + 0x40, 0x3e, 0x04, 0x04, 0x50, 0x15, 0x05, 0x04, 0x60, 0x15, 0x05, 0x04, 0xe0, 0x34, 0x06, 0x05, 0x80, 0x2a, 0x08, 0x06, 0x00, 0x1d, 0x0c, 0x08, 0x10, 0x39, 0x00, 0x03, 0x18, 0x39, 0x00, 0x03, + 0x20, 0x39, 0x00, 0x03, 0x28, 0x39, 0x00, 0x03, 0x10, 0x24, 0x01, 0x02, 0x14, 0x24, 0x01, 0x02, 0x18, 0x24, 0x01, 0x02, 0x1c, 0x24, 0x01, 0x02, 0x20, 0x24, 0x01, 0x02, 0x24, 0x24, 0x01, 0x02, + 0x30, 0x04, 0x02, 0x02, 0x34, 0x04, 0x02, 0x02, 0x38, 0x04, 0x02, 0x02, 0x3c, 0x04, 0x02, 0x02, 0xc0, 0x1c, 0x03, 0x03, 0xc8, 0x1c, 0x03, 0x03, 0xd0, 0x1c, 0x03, 0x03, 0x50, 0x3e, 0x04, 0x04, + 0x60, 0x3e, 0x04, 0x04, 0x70, 0x15, 0x05, 0x04, 0x80, 0x15, 0x05, 0x04, 0x00, 0x35, 0x06, 0x05, 0xc0, 0x2a, 0x08, 0x06, 0x00, 0x38, 0x0d, 0x09, 0x30, 0x39, 0x00, 0x03, 0x38, 0x39, 0x00, 0x03, + 0x40, 0x39, 0x00, 0x03, 0x48, 0x39, 0x00, 0x03, 0x28, 0x24, 0x01, 0x02, 0x2c, 0x24, 0x01, 0x02, 0x30, 0x24, 0x01, 0x02, 0x34, 0x24, 0x01, 0x02, 0x38, 0x24, 0x01, 0x02, 0x3c, 0x24, 0x01, 0x02, + 0x40, 0x04, 0x02, 0x02, 0x44, 0x04, 0x02, 0x02, 0x48, 0x04, 0x02, 0x02, 0x4c, 0x04, 0x02, 0x02, 0xd8, 0x1c, 0x03, 0x03, 0xe0, 0x1c, 0x03, 0x03, 0xe8, 0x1c, 0x03, 0x03, 0x70, 0x3e, 0x04, 0x04, + 0x80, 0x3e, 0x04, 0x04, 0x90, 0x15, 0x05, 0x04, 0xa0, 0x15, 0x05, 0x04, 0x20, 0x35, 0x06, 0x05, 0x00, 0x2b, 0x08, 0x06, 0x00, 0x3a, 0x0d, 0x09, 0x50, 0x39, 0x00, 0x03, 0x58, 0x39, 0x00, 0x03, + 0x60, 0x39, 0x00, 0x03, 0x68, 0x39, 0x00, 0x03, 0x40, 0x24, 0x01, 0x02, 0x44, 0x24, 0x01, 0x02, 0x48, 0x24, 0x01, 0x02, 0x4c, 0x24, 0x01, 0x02, 0x50, 0x24, 0x01, 0x02, 0x54, 0x24, 0x01, 0x02, + 0x50, 0x04, 0x02, 0x02, 0x54, 0x04, 0x02, 0x02, 0x58, 0x04, 0x02, 0x02, 0x5c, 0x04, 0x02, 0x02, 0xf0, 0x1c, 0x03, 0x03, 0xf8, 0x1c, 0x03, 0x03, 0x00, 0x1d, 0x03, 0x03, 0x90, 0x3e, 0x04, 0x04, + 0xa0, 0x3e, 0x04, 0x04, 0xb0, 0x15, 0x05, 0x04, 0xc0, 0x15, 0x05, 0x04, 0x40, 0x35, 0x06, 0x05, 0x40, 0x2b, 0x08, 0x06, 0x00, 0x3c, 0x0d, 0x09, 0x70, 0x39, 0x00, 0x03, 0x78, 0x39, 0x00, 0x03, + 0x80, 0x39, 0x00, 0x03, 0x88, 0x39, 0x00, 0x03, 0x58, 0x24, 0x01, 0x02, 0x5c, 0x24, 0x01, 0x02, 0x60, 0x24, 0x01, 0x02, 0x64, 0x24, 0x01, 0x02, 0x68, 0x24, 0x01, 0x02, 0x6c, 0x24, 0x01, 0x02, + 0x60, 0x04, 0x02, 0x02, 0x64, 0x04, 0x02, 0x02, 0x68, 0x04, 0x02, 0x02, 0x6c, 0x04, 0x02, 0x02, 0x08, 0x1d, 0x03, 0x03, 0x10, 0x1d, 0x03, 0x03, 0x18, 0x1d, 0x03, 0x03, 0xb0, 0x3e, 0x04, 0x04, + 0xc0, 0x3e, 0x04, 0x04, 0xd0, 0x15, 0x05, 0x04, 0xe0, 0x15, 0x05, 0x04, 0x60, 0x35, 0x06, 0x05, 0x80, 0x2b, 0x08, 0x06, 0x00, 0x3e, 0x0d, 0x09, 0x90, 0x39, 0x00, 0x03, 0x98, 0x39, 0x00, 0x03, + 0xa0, 0x39, 0x00, 0x03, 0xa8, 0x39, 0x00, 0x03, 0x70, 0x24, 0x01, 0x02, 0x74, 0x24, 0x01, 0x02, 0x78, 0x24, 0x01, 0x02, 0x7c, 0x24, 0x01, 0x02, 0x80, 0x24, 0x01, 0x02, 0x84, 0x24, 0x01, 0x02, + 0x70, 0x04, 0x02, 0x02, 0x74, 0x04, 0x02, 0x02, 0x78, 0x04, 0x02, 0x02, 0x7c, 0x04, 0x02, 0x02, 0x20, 0x1d, 0x03, 0x03, 0x28, 0x1d, 0x03, 0x03, 0x30, 0x1d, 0x03, 0x03, 0xd0, 0x3e, 0x04, 0x04, + 0xe0, 0x3e, 0x04, 0x04, 0xf0, 0x15, 0x05, 0x04, 0x00, 0x16, 0x05, 0x04, 0x80, 0x35, 0x06, 0x05, 0xc0, 0x2b, 0x08, 0x06, 0x00, 0x00, 0x0d, 0x08, 0xb0, 0x39, 0x00, 0x03, 0xb8, 0x39, 0x00, 0x03, + 0xc0, 0x39, 0x00, 0x03, 0xc8, 0x39, 0x00, 0x03, 0x88, 0x24, 0x01, 0x02, 0x8c, 0x24, 0x01, 0x02, 0x90, 0x24, 0x01, 0x02, 0x94, 0x24, 0x01, 0x02, 0x98, 0x24, 0x01, 0x02, 0x9c, 0x24, 0x01, 0x02, + 0x80, 0x04, 0x02, 0x02, 0x84, 0x04, 0x02, 0x02, 0x88, 0x04, 0x02, 0x02, 0x8c, 0x04, 0x02, 0x02, 0x38, 0x1d, 0x03, 0x03, 0x40, 0x1d, 0x03, 0x03, 0x48, 0x1d, 0x03, 0x03, 0xf0, 0x3e, 0x04, 0x04, + 0x00, 0x3f, 0x04, 0x04, 0x10, 0x16, 0x05, 0x04, 0x20, 0x16, 0x05, 0x04, 0xa0, 0x35, 0x06, 0x05, 0x00, 0x2c, 0x08, 0x06, 0x00, 0x10, 0x0e, 0x09, 0xd0, 0x39, 0x00, 0x03, 0xd8, 0x39, 0x00, 0x03, + 0xe0, 0x39, 0x00, 0x03, 0xa0, 0x24, 0x01, 0x02, 0xa4, 0x24, 0x01, 0x02, 0xa8, 0x24, 0x01, 0x02, 0xac, 0x24, 0x01, 0x02, 0xb0, 0x24, 0x01, 0x02, 0xb4, 0x24, 0x01, 0x02, 0xb8, 0x24, 0x01, 0x02, + 0x90, 0x04, 0x02, 0x02, 0x94, 0x04, 0x02, 0x02, 0x98, 0x04, 0x02, 0x02, 0x9c, 0x04, 0x02, 0x02, 0x50, 0x1d, 0x03, 0x03, 0x58, 0x1d, 0x03, 0x03, 0x60, 0x1d, 0x03, 0x03, 0x10, 0x3f, 0x04, 0x04, + 0x20, 0x3f, 0x04, 0x04, 0x30, 0x16, 0x05, 0x04, 0x40, 0x16, 0x05, 0x04, 0xc0, 0x35, 0x06, 0x05, 0x40, 0x2c, 0x08, 0x06, 0x00, 0x12, 0x0e, 0x09, 0xe8, 0x39, 0x00, 0x03, 0xf0, 0x39, 0x00, 0x03, + 0xf8, 0x39, 0x00, 0x03, 0xbc, 0x24, 0x01, 0x02, 0xc0, 0x24, 0x01, 0x02, 0xc4, 0x24, 0x01, 0x02, 0xc8, 0x24, 0x01, 0x02, 0xcc, 0x24, 0x01, 0x02, 0xd0, 0x24, 0x01, 0x02, 0xd4, 0x24, 0x01, 0x02, + 0xa0, 0x04, 0x02, 0x02, 0xa4, 0x04, 0x02, 0x02, 0xa8, 0x04, 0x02, 0x02, 0xac, 0x04, 0x02, 0x02, 0x68, 0x1d, 0x03, 0x03, 0x70, 0x1d, 0x03, 0x03, 0x78, 0x1d, 0x03, 0x03, 0x30, 0x3f, 0x04, 0x04, + 0x40, 0x3f, 0x04, 0x04, 0x50, 0x16, 0x05, 0x04, 0x60, 0x16, 0x05, 0x04, 0xe0, 0x35, 0x06, 0x05, 0x80, 0x2c, 0x08, 0x06, 0x00, 0x14, 0x0e, 0x09, 0x00, 0x3a, 0x00, 0x03, 0x08, 0x3a, 0x00, 0x03, + 0x10, 0x3a, 0x00, 0x03, 0xd8, 0x24, 0x01, 0x02, 0xdc, 0x24, 0x01, 0x02, 0xe0, 0x24, 0x01, 0x02, 0xe4, 0x24, 0x01, 0x02, 0xe8, 0x24, 0x01, 0x02, 0xec, 0x24, 0x01, 0x02, 0xf0, 0x24, 0x01, 0x02, + 0xb0, 0x04, 0x02, 0x02, 0xb4, 0x04, 0x02, 0x02, 0xb8, 0x04, 0x02, 0x02, 0xbc, 0x04, 0x02, 0x02, 0x80, 0x1d, 0x03, 0x03, 0x88, 0x1d, 0x03, 0x03, 0x90, 0x1d, 0x03, 0x03, 0x50, 0x3f, 0x04, 0x04, + 0x60, 0x3f, 0x04, 0x04, 0x70, 0x16, 0x05, 0x04, 0x80, 0x16, 0x05, 0x04, 0x00, 0x36, 0x06, 0x05, 0xc0, 0x2c, 0x08, 0x06, 0x00, 0x16, 0x0e, 0x09, 0x18, 0x3a, 0x00, 0x03, 0x20, 0x3a, 0x00, 0x03, + 0x28, 0x3a, 0x00, 0x03, 0xf4, 0x24, 0x01, 0x02, 0xf8, 0x24, 0x01, 0x02, 0xfc, 0x24, 0x01, 0x02, 0x00, 0x25, 0x01, 0x02, 0x04, 0x25, 0x01, 0x02, 0x08, 0x25, 0x01, 0x02, 0x0c, 0x25, 0x01, 0x02, + 0xc0, 0x04, 0x02, 0x02, 0xc4, 0x04, 0x02, 0x02, 0xc8, 0x04, 0x02, 0x02, 0xcc, 0x04, 0x02, 0x02, 0x98, 0x1d, 0x03, 0x03, 0xa0, 0x1d, 0x03, 0x03, 0xa8, 0x1d, 0x03, 0x03, 0x70, 0x3f, 0x04, 0x04, + 0x80, 0x3f, 0x04, 0x04, 0x90, 0x16, 0x05, 0x04, 0xa0, 0x16, 0x05, 0x04, 0x20, 0x36, 0x06, 0x05, 0x00, 0x2d, 0x08, 0x06, 0x00, 0x30, 0x0f, 0x0a, 0x30, 0x3a, 0x00, 0x03, 0x38, 0x3a, 0x00, 0x03, + 0x40, 0x3a, 0x00, 0x03, 0x10, 0x25, 0x01, 0x02, 0x14, 0x25, 0x01, 0x02, 0x18, 0x25, 0x01, 0x02, 0x1c, 0x25, 0x01, 0x02, 0x20, 0x25, 0x01, 0x02, 0x24, 0x25, 0x01, 0x02, 0x28, 0x25, 0x01, 0x02, + 0xd0, 0x04, 0x02, 0x02, 0xd4, 0x04, 0x02, 0x02, 0xd8, 0x04, 0x02, 0x02, 0xdc, 0x04, 0x02, 0x02, 0xb0, 0x1d, 0x03, 0x03, 0xb8, 0x1d, 0x03, 0x03, 0xc0, 0x1d, 0x03, 0x03, 0x90, 0x3f, 0x04, 0x04, + 0xa0, 0x3f, 0x04, 0x04, 0xb0, 0x16, 0x05, 0x04, 0xc0, 0x16, 0x05, 0x04, 0x40, 0x36, 0x06, 0x05, 0x40, 0x2d, 0x08, 0x06, 0x00, 0x34, 0x0f, 0x0a, 0x48, 0x3a, 0x00, 0x03, 0x50, 0x3a, 0x00, 0x03, + 0x58, 0x3a, 0x00, 0x03, 0x2c, 0x25, 0x01, 0x02, 0x30, 0x25, 0x01, 0x02, 0x34, 0x25, 0x01, 0x02, 0x38, 0x25, 0x01, 0x02, 0x3c, 0x25, 0x01, 0x02, 0x40, 0x25, 0x01, 0x02, 0x44, 0x25, 0x01, 0x02, + 0xe0, 0x04, 0x02, 0x02, 0xe4, 0x04, 0x02, 0x02, 0xe8, 0x04, 0x02, 0x02, 0xec, 0x04, 0x02, 0x02, 0xc8, 0x1d, 0x03, 0x03, 0xd0, 0x1d, 0x03, 0x03, 0xd8, 0x1d, 0x03, 0x03, 0xb0, 0x3f, 0x04, 0x04, + 0xc0, 0x3f, 0x04, 0x04, 0xd0, 0x16, 0x05, 0x04, 0xe0, 0x16, 0x05, 0x04, 0x60, 0x36, 0x06, 0x05, 0x80, 0x2d, 0x08, 0x06, 0x00, 0x38, 0x0f, 0x0a, 0x60, 0x3a, 0x00, 0x03, 0x68, 0x3a, 0x00, 0x03, + 0x70, 0x3a, 0x00, 0x03, 0x48, 0x25, 0x01, 0x02, 0x4c, 0x25, 0x01, 0x02, 0x50, 0x25, 0x01, 0x02, 0x54, 0x25, 0x01, 0x02, 0x58, 0x25, 0x01, 0x02, 0x5c, 0x25, 0x01, 0x02, 0x60, 0x25, 0x01, 0x02, + 0xf0, 0x04, 0x02, 0x02, 0xf4, 0x04, 0x02, 0x02, 0xf8, 0x04, 0x02, 0x02, 0xfc, 0x04, 0x02, 0x02, 0xe0, 0x1d, 0x03, 0x03, 0xe8, 0x1d, 0x03, 0x03, 0xf0, 0x1d, 0x03, 0x03, 0xd0, 0x3f, 0x04, 0x04, + 0xe0, 0x3f, 0x04, 0x04, 0xf0, 0x16, 0x05, 0x04, 0x00, 0x17, 0x05, 0x04, 0x80, 0x36, 0x06, 0x05, 0xc0, 0x2d, 0x08, 0x06, 0x00, 0x10, 0x10, 0x0a, 0x78, 0x3a, 0x00, 0x03, 0x80, 0x3a, 0x00, 0x03, + 0x88, 0x3a, 0x00, 0x03, 0x64, 0x25, 0x01, 0x02, 0x68, 0x25, 0x01, 0x02, 0x6c, 0x25, 0x01, 0x02, 0x70, 0x25, 0x01, 0x02, 0x74, 0x25, 0x01, 0x02, 0x78, 0x25, 0x01, 0x02, 0x7c, 0x25, 0x01, 0x02, + 0x00, 0x05, 0x02, 0x02, 0x04, 0x05, 0x02, 0x02, 0x08, 0x05, 0x02, 0x02, 0x0c, 0x05, 0x02, 0x02, 0xf8, 0x1d, 0x03, 0x03, 0x00, 0x1e, 0x03, 0x03, 0x08, 0x1e, 0x03, 0x03, 0xf0, 0x3f, 0x04, 0x04, + 0x00, 0x00, 0x04, 0x03, 0x10, 0x17, 0x05, 0x04, 0x20, 0x17, 0x05, 0x04, 0xa0, 0x36, 0x06, 0x05, 0x00, 0x2e, 0x08, 0x06, 0x00, 0x14, 0x10, 0x0a, 0x90, 0x3a, 0x00, 0x03, 0x98, 0x3a, 0x00, 0x03, + 0xa0, 0x3a, 0x00, 0x03, 0x80, 0x25, 0x01, 0x02, 0x84, 0x25, 0x01, 0x02, 0x88, 0x25, 0x01, 0x02, 0x8c, 0x25, 0x01, 0x02, 0x90, 0x25, 0x01, 0x02, 0x94, 0x25, 0x01, 0x02, 0x98, 0x25, 0x01, 0x02, + 0x10, 0x05, 0x02, 0x02, 0x14, 0x05, 0x02, 0x02, 0x18, 0x05, 0x02, 0x02, 0x1c, 0x05, 0x02, 0x02, 0x10, 0x1e, 0x03, 0x03, 0x18, 0x1e, 0x03, 0x03, 0x20, 0x1e, 0x03, 0x03, 0x08, 0x00, 0x04, 0x03, + 0x10, 0x00, 0x04, 0x03, 0x30, 0x17, 0x05, 0x04, 0x40, 0x17, 0x05, 0x04, 0xc0, 0x36, 0x06, 0x05, 0x40, 0x2e, 0x08, 0x06, 0x00, 0x28, 0x11, 0x0b, 0xa8, 0x3a, 0x00, 0x03, 0xb0, 0x3a, 0x00, 0x03, + 0xb8, 0x3a, 0x00, 0x03, 0x9c, 0x25, 0x01, 0x02, 0xa0, 0x25, 0x01, 0x02, 0xa4, 0x25, 0x01, 0x02, 0xa8, 0x25, 0x01, 0x02, 0xac, 0x25, 0x01, 0x02, 0xb0, 0x25, 0x01, 0x02, 0xb4, 0x25, 0x01, 0x02, + 0x20, 0x05, 0x02, 0x02, 0x24, 0x05, 0x02, 0x02, 0x28, 0x05, 0x02, 0x02, 0x2c, 0x05, 0x02, 0x02, 0x28, 0x1e, 0x03, 0x03, 0x30, 0x1e, 0x03, 0x03, 0x38, 0x1e, 0x03, 0x03, 0x18, 0x00, 0x04, 0x03, + 0x20, 0x00, 0x04, 0x03, 0x50, 0x17, 0x05, 0x04, 0x60, 0x17, 0x05, 0x04, 0xe0, 0x36, 0x06, 0x05, 0x80, 0x2e, 0x08, 0x06, 0x00, 0x08, 0x12, 0x0b, 0xc0, 0x3a, 0x00, 0x03, 0xc8, 0x3a, 0x00, 0x03, + 0xd0, 0x3a, 0x00, 0x03, 0xb8, 0x25, 0x01, 0x02, 0xbc, 0x25, 0x01, 0x02, 0xc0, 0x25, 0x01, 0x02, 0xc4, 0x25, 0x01, 0x02, 0xc8, 0x25, 0x01, 0x02, 0xcc, 0x25, 0x01, 0x02, 0xd0, 0x25, 0x01, 0x02, + 0x30, 0x05, 0x02, 0x02, 0x34, 0x05, 0x02, 0x02, 0x38, 0x05, 0x02, 0x02, 0x3c, 0x05, 0x02, 0x02, 0x40, 0x1e, 0x03, 0x03, 0x48, 0x1e, 0x03, 0x03, 0x50, 0x1e, 0x03, 0x03, 0x28, 0x00, 0x04, 0x03, + 0x30, 0x00, 0x04, 0x03, 0x70, 0x17, 0x05, 0x04, 0x80, 0x17, 0x05, 0x04, 0x00, 0x37, 0x06, 0x05, 0xc0, 0x2e, 0x08, 0x06, 0x00, 0x00, 0x14, 0x0c, 0xd8, 0x3a, 0x00, 0x03, 0xe0, 0x3a, 0x00, 0x03, + 0xe8, 0x3a, 0x00, 0x03, 0xd4, 0x25, 0x01, 0x02, 0xd8, 0x25, 0x01, 0x02, 0xdc, 0x25, 0x01, 0x02, 0xe0, 0x25, 0x01, 0x02, 0xe4, 0x25, 0x01, 0x02, 0xe8, 0x25, 0x01, 0x02, 0xec, 0x25, 0x01, 0x02, + 0x40, 0x05, 0x02, 0x02, 0x44, 0x05, 0x02, 0x02, 0x48, 0x05, 0x02, 0x02, 0x4c, 0x05, 0x02, 0x02, 0x58, 0x1e, 0x03, 0x03, 0x60, 0x1e, 0x03, 0x03, 0x68, 0x1e, 0x03, 0x03, 0x38, 0x00, 0x04, 0x03, + 0x40, 0x00, 0x04, 0x03, 0x90, 0x17, 0x05, 0x04, 0xa0, 0x17, 0x05, 0x04, 0xa0, 0x10, 0x07, 0x05, 0x00, 0x2f, 0x08, 0x06, 0xf0, 0x3a, 0x00, 0x03, 0xf8, 0x3a, 0x00, 0x03, 0x00, 0x3b, 0x00, 0x03, + 0x08, 0x3b, 0x00, 0x03, 0xf0, 0x25, 0x01, 0x02, 0xf4, 0x25, 0x01, 0x02, 0xf8, 0x25, 0x01, 0x02, 0xfc, 0x25, 0x01, 0x02, 0x00, 0x26, 0x01, 0x02, 0x04, 0x26, 0x01, 0x02, 0x08, 0x26, 0x01, 0x02, + 0x50, 0x05, 0x02, 0x02, 0x54, 0x05, 0x02, 0x02, 0x58, 0x05, 0x02, 0x02, 0x5c, 0x05, 0x02, 0x02, 0x70, 0x1e, 0x03, 0x03, 0x78, 0x1e, 0x03, 0x03, 0x80, 0x1e, 0x03, 0x03, 0x48, 0x00, 0x04, 0x03, + 0x50, 0x00, 0x04, 0x03, 0xb0, 0x17, 0x05, 0x04, 0xc0, 0x17, 0x05, 0x04, 0xc0, 0x10, 0x07, 0x05, 0x40, 0x2f, 0x08, 0x06, 0x10, 0x3b, 0x00, 0x03, 0x18, 0x3b, 0x00, 0x03, 0x20, 0x3b, 0x00, 0x03, + 0x28, 0x3b, 0x00, 0x03, 0x0c, 0x26, 0x01, 0x02, 0x10, 0x26, 0x01, 0x02, 0x14, 0x26, 0x01, 0x02, 0x18, 0x26, 0x01, 0x02, 0x1c, 0x26, 0x01, 0x02, 0x20, 0x26, 0x01, 0x02, 0x24, 0x26, 0x01, 0x02, + 0x60, 0x05, 0x02, 0x02, 0x64, 0x05, 0x02, 0x02, 0x68, 0x05, 0x02, 0x02, 0x6c, 0x05, 0x02, 0x02, 0x88, 0x1e, 0x03, 0x03, 0x90, 0x1e, 0x03, 0x03, 0x98, 0x1e, 0x03, 0x03, 0x58, 0x00, 0x04, 0x03, + 0x60, 0x00, 0x04, 0x03, 0xd0, 0x17, 0x05, 0x04, 0xe0, 0x17, 0x05, 0x04, 0xe0, 0x10, 0x07, 0x05, 0x80, 0x2f, 0x08, 0x06, 0x30, 0x3b, 0x00, 0x03, 0x38, 0x3b, 0x00, 0x03, 0x40, 0x3b, 0x00, 0x03, + 0x48, 0x3b, 0x00, 0x03, 0x28, 0x26, 0x01, 0x02, 0x2c, 0x26, 0x01, 0x02, 0x30, 0x26, 0x01, 0x02, 0x34, 0x26, 0x01, 0x02, 0x38, 0x26, 0x01, 0x02, 0x3c, 0x26, 0x01, 0x02, 0x40, 0x26, 0x01, 0x02, + 0x70, 0x05, 0x02, 0x02, 0x74, 0x05, 0x02, 0x02, 0x78, 0x05, 0x02, 0x02, 0x7c, 0x05, 0x02, 0x02, 0xa0, 0x1e, 0x03, 0x03, 0xa8, 0x1e, 0x03, 0x03, 0xb0, 0x1e, 0x03, 0x03, 0x68, 0x00, 0x04, 0x03, + 0x70, 0x00, 0x04, 0x03, 0xf0, 0x17, 0x05, 0x04, 0x00, 0x18, 0x05, 0x04, 0x00, 0x11, 0x07, 0x05, 0xc0, 0x2f, 0x08, 0x06, 0x50, 0x3b, 0x00, 0x03, 0x58, 0x3b, 0x00, 0x03, 0x60, 0x3b, 0x00, 0x03, + 0x68, 0x3b, 0x00, 0x03, 0x44, 0x26, 0x01, 0x02, 0x48, 0x26, 0x01, 0x02, 0x4c, 0x26, 0x01, 0x02, 0x50, 0x26, 0x01, 0x02, 0x54, 0x26, 0x01, 0x02, 0x58, 0x26, 0x01, 0x02, 0x5c, 0x26, 0x01, 0x02, + 0x80, 0x05, 0x02, 0x02, 0x84, 0x05, 0x02, 0x02, 0x88, 0x05, 0x02, 0x02, 0x8c, 0x05, 0x02, 0x02, 0xb8, 0x1e, 0x03, 0x03, 0xc0, 0x1e, 0x03, 0x03, 0xc8, 0x1e, 0x03, 0x03, 0x78, 0x00, 0x04, 0x03, + 0x80, 0x00, 0x04, 0x03, 0x10, 0x18, 0x05, 0x04, 0x20, 0x18, 0x05, 0x04, 0x20, 0x11, 0x07, 0x05, 0x00, 0x30, 0x08, 0x06, 0x70, 0x3b, 0x00, 0x03, 0x78, 0x3b, 0x00, 0x03, 0x80, 0x3b, 0x00, 0x03, + 0x88, 0x3b, 0x00, 0x03, 0x60, 0x26, 0x01, 0x02, 0x64, 0x26, 0x01, 0x02, 0x68, 0x26, 0x01, 0x02, 0x6c, 0x26, 0x01, 0x02, 0x70, 0x26, 0x01, 0x02, 0x74, 0x26, 0x01, 0x02, 0x78, 0x26, 0x01, 0x02, + 0x90, 0x05, 0x02, 0x02, 0x94, 0x05, 0x02, 0x02, 0x98, 0x05, 0x02, 0x02, 0x9c, 0x05, 0x02, 0x02, 0xd0, 0x1e, 0x03, 0x03, 0xd8, 0x1e, 0x03, 0x03, 0xe0, 0x1e, 0x03, 0x03, 0x88, 0x00, 0x04, 0x03, + 0x90, 0x00, 0x04, 0x03, 0x30, 0x18, 0x05, 0x04, 0x40, 0x18, 0x05, 0x04, 0x40, 0x11, 0x07, 0x05, 0x40, 0x30, 0x08, 0x06, 0x90, 0x3b, 0x00, 0x03, 0x98, 0x3b, 0x00, 0x03, 0xa0, 0x3b, 0x00, 0x03, + 0xa8, 0x3b, 0x00, 0x03, 0x7c, 0x26, 0x01, 0x02, 0x80, 0x26, 0x01, 0x02, 0x84, 0x26, 0x01, 0x02, 0x88, 0x26, 0x01, 0x02, 0x8c, 0x26, 0x01, 0x02, 0x90, 0x26, 0x01, 0x02, 0x94, 0x26, 0x01, 0x02, + 0xa0, 0x05, 0x02, 0x02, 0xa4, 0x05, 0x02, 0x02, 0xa8, 0x05, 0x02, 0x02, 0xac, 0x05, 0x02, 0x02, 0xe8, 0x1e, 0x03, 0x03, 0xf0, 0x1e, 0x03, 0x03, 0xf8, 0x1e, 0x03, 0x03, 0x98, 0x00, 0x04, 0x03, + 0xa0, 0x00, 0x04, 0x03, 0x50, 0x18, 0x05, 0x04, 0x20, 0x37, 0x06, 0x05, 0x60, 0x11, 0x07, 0x05, 0x80, 0x30, 0x08, 0x06, 0xb0, 0x3b, 0x00, 0x03, 0xb8, 0x3b, 0x00, 0x03, 0xc0, 0x3b, 0x00, 0x03, + 0xc8, 0x3b, 0x00, 0x03, 0x98, 0x26, 0x01, 0x02, 0x9c, 0x26, 0x01, 0x02, 0xa0, 0x26, 0x01, 0x02, 0xa4, 0x26, 0x01, 0x02, 0xa8, 0x26, 0x01, 0x02, 0xac, 0x26, 0x01, 0x02, 0xb0, 0x26, 0x01, 0x02, + 0xb0, 0x05, 0x02, 0x02, 0xb4, 0x05, 0x02, 0x02, 0xb8, 0x05, 0x02, 0x02, 0xbc, 0x05, 0x02, 0x02, 0x00, 0x1f, 0x03, 0x03, 0x08, 0x1f, 0x03, 0x03, 0x10, 0x1f, 0x03, 0x03, 0xa8, 0x00, 0x04, 0x03, + 0xb0, 0x00, 0x04, 0x03, 0x60, 0x18, 0x05, 0x04, 0x40, 0x37, 0x06, 0x05, 0x80, 0x11, 0x07, 0x05, 0x80, 0x0a, 0x09, 0x06, 0xd0, 0x3b, 0x00, 0x03, 0xd8, 0x3b, 0x00, 0x03, 0xe0, 0x3b, 0x00, 0x03, + 0xe8, 0x3b, 0x00, 0x03, 0xb4, 0x26, 0x01, 0x02, 0xb8, 0x26, 0x01, 0x02, 0xbc, 0x26, 0x01, 0x02, 0xc0, 0x26, 0x01, 0x02, 0xc4, 0x26, 0x01, 0x02, 0xc8, 0x26, 0x01, 0x02, 0xcc, 0x26, 0x01, 0x02, + 0xc0, 0x05, 0x02, 0x02, 0xc4, 0x05, 0x02, 0x02, 0xc8, 0x05, 0x02, 0x02, 0xcc, 0x05, 0x02, 0x02, 0x18, 0x1f, 0x03, 0x03, 0x20, 0x1f, 0x03, 0x03, 0x28, 0x1f, 0x03, 0x03, 0xb8, 0x00, 0x04, 0x03, + 0xc0, 0x00, 0x04, 0x03, 0x70, 0x18, 0x05, 0x04, 0x60, 0x37, 0x06, 0x05, 0xa0, 0x11, 0x07, 0x05, 0xc0, 0x0a, 0x09, 0x06, 0xf0, 0x3b, 0x00, 0x03, 0xf8, 0x3b, 0x00, 0x03, 0x00, 0x3c, 0x00, 0x03, + 0x08, 0x3c, 0x00, 0x03, 0xd0, 0x26, 0x01, 0x02, 0xd4, 0x26, 0x01, 0x02, 0xd8, 0x26, 0x01, 0x02, 0xdc, 0x26, 0x01, 0x02, 0xe0, 0x26, 0x01, 0x02, 0xe4, 0x26, 0x01, 0x02, 0xe8, 0x26, 0x01, 0x02, + 0xd0, 0x05, 0x02, 0x02, 0xd4, 0x05, 0x02, 0x02, 0xd8, 0x05, 0x02, 0x02, 0xdc, 0x05, 0x02, 0x02, 0x30, 0x1f, 0x03, 0x03, 0x38, 0x1f, 0x03, 0x03, 0x40, 0x1f, 0x03, 0x03, 0xc8, 0x00, 0x04, 0x03, + 0xd0, 0x00, 0x04, 0x03, 0x80, 0x18, 0x05, 0x04, 0x80, 0x37, 0x06, 0x05, 0xc0, 0x11, 0x07, 0x05, 0x00, 0x0b, 0x09, 0x06, 0x10, 0x3c, 0x00, 0x03, 0x18, 0x3c, 0x00, 0x03, 0x20, 0x3c, 0x00, 0x03, + 0x28, 0x3c, 0x00, 0x03, 0xec, 0x26, 0x01, 0x02, 0xf0, 0x26, 0x01, 0x02, 0xf4, 0x26, 0x01, 0x02, 0xf8, 0x26, 0x01, 0x02, 0xfc, 0x26, 0x01, 0x02, 0x00, 0x27, 0x01, 0x02, 0x04, 0x27, 0x01, 0x02, + 0xe0, 0x05, 0x02, 0x02, 0xe4, 0x05, 0x02, 0x02, 0xe8, 0x05, 0x02, 0x02, 0xec, 0x05, 0x02, 0x02, 0x48, 0x1f, 0x03, 0x03, 0x50, 0x1f, 0x03, 0x03, 0x58, 0x1f, 0x03, 0x03, 0xd8, 0x00, 0x04, 0x03, + 0xe0, 0x00, 0x04, 0x03, 0x90, 0x18, 0x05, 0x04, 0xa0, 0x37, 0x06, 0x05, 0xe0, 0x11, 0x07, 0x05, 0x40, 0x0b, 0x09, 0x06, 0x30, 0x3c, 0x00, 0x03, 0x38, 0x3c, 0x00, 0x03, 0x40, 0x3c, 0x00, 0x03, + 0x48, 0x3c, 0x00, 0x03, 0x08, 0x27, 0x01, 0x02, 0x0c, 0x27, 0x01, 0x02, 0x10, 0x27, 0x01, 0x02, 0x14, 0x27, 0x01, 0x02, 0x18, 0x27, 0x01, 0x02, 0x1c, 0x27, 0x01, 0x02, 0x20, 0x27, 0x01, 0x02, + 0xf0, 0x05, 0x02, 0x02, 0xf4, 0x05, 0x02, 0x02, 0xf8, 0x05, 0x02, 0x02, 0xfc, 0x05, 0x02, 0x02, 0x60, 0x1f, 0x03, 0x03, 0x68, 0x1f, 0x03, 0x03, 0x70, 0x1f, 0x03, 0x03, 0xe8, 0x00, 0x04, 0x03, + 0xf0, 0x00, 0x04, 0x03, 0xa0, 0x18, 0x05, 0x04, 0xc0, 0x37, 0x06, 0x05, 0x00, 0x12, 0x07, 0x05, 0x80, 0x0b, 0x09, 0x06, 0x50, 0x3c, 0x00, 0x03, 0x58, 0x3c, 0x00, 0x03, 0x60, 0x3c, 0x00, 0x03, + 0x68, 0x3c, 0x00, 0x03, 0x24, 0x27, 0x01, 0x02, 0x28, 0x27, 0x01, 0x02, 0x2c, 0x27, 0x01, 0x02, 0x30, 0x27, 0x01, 0x02, 0x34, 0x27, 0x01, 0x02, 0x38, 0x27, 0x01, 0x02, 0x3c, 0x27, 0x01, 0x02, + 0x00, 0x06, 0x02, 0x02, 0x04, 0x06, 0x02, 0x02, 0x08, 0x06, 0x02, 0x02, 0x0c, 0x06, 0x02, 0x02, 0x78, 0x1f, 0x03, 0x03, 0x80, 0x1f, 0x03, 0x03, 0x88, 0x1f, 0x03, 0x03, 0xf8, 0x00, 0x04, 0x03, + 0x00, 0x01, 0x04, 0x03, 0xb0, 0x18, 0x05, 0x04, 0xe0, 0x37, 0x06, 0x05, 0x20, 0x12, 0x07, 0x05, 0xc0, 0x0b, 0x09, 0x06, 0x70, 0x3c, 0x00, 0x03, 0x78, 0x3c, 0x00, 0x03, 0x80, 0x3c, 0x00, 0x03, + 0x88, 0x3c, 0x00, 0x03, 0x40, 0x27, 0x01, 0x02, 0x44, 0x27, 0x01, 0x02, 0x48, 0x27, 0x01, 0x02, 0x4c, 0x27, 0x01, 0x02, 0x50, 0x27, 0x01, 0x02, 0x54, 0x27, 0x01, 0x02, 0x58, 0x27, 0x01, 0x02, + 0x10, 0x06, 0x02, 0x02, 0x14, 0x06, 0x02, 0x02, 0x18, 0x06, 0x02, 0x02, 0x1c, 0x06, 0x02, 0x02, 0x90, 0x1f, 0x03, 0x03, 0x98, 0x1f, 0x03, 0x03, 0xa0, 0x1f, 0x03, 0x03, 0x08, 0x01, 0x04, 0x03, + 0x10, 0x01, 0x04, 0x03, 0xc0, 0x18, 0x05, 0x04, 0x00, 0x38, 0x06, 0x05, 0x40, 0x12, 0x07, 0x05, 0x00, 0x0c, 0x09, 0x06, 0x90, 0x3c, 0x00, 0x03, 0x98, 0x3c, 0x00, 0x03, 0xa0, 0x3c, 0x00, 0x03, + 0xa8, 0x3c, 0x00, 0x03, 0x5c, 0x27, 0x01, 0x02, 0x60, 0x27, 0x01, 0x02, 0x64, 0x27, 0x01, 0x02, 0x68, 0x27, 0x01, 0x02, 0x6c, 0x27, 0x01, 0x02, 0x70, 0x27, 0x01, 0x02, 0x74, 0x27, 0x01, 0x02, + 0x20, 0x06, 0x02, 0x02, 0x24, 0x06, 0x02, 0x02, 0x28, 0x06, 0x02, 0x02, 0x2c, 0x06, 0x02, 0x02, 0xa8, 0x1f, 0x03, 0x03, 0xb0, 0x1f, 0x03, 0x03, 0xb8, 0x1f, 0x03, 0x03, 0x18, 0x01, 0x04, 0x03, + 0x20, 0x01, 0x04, 0x03, 0xd0, 0x18, 0x05, 0x04, 0x20, 0x38, 0x06, 0x05, 0x60, 0x12, 0x07, 0x05, 0x40, 0x0c, 0x09, 0x06, 0xb0, 0x3c, 0x00, 0x03, 0xb8, 0x3c, 0x00, 0x03, 0xc0, 0x3c, 0x00, 0x03, + 0xc8, 0x3c, 0x00, 0x03, 0x78, 0x27, 0x01, 0x02, 0x7c, 0x27, 0x01, 0x02, 0x80, 0x27, 0x01, 0x02, 0x84, 0x27, 0x01, 0x02, 0x88, 0x27, 0x01, 0x02, 0x8c, 0x27, 0x01, 0x02, 0x90, 0x27, 0x01, 0x02, + 0x30, 0x06, 0x02, 0x02, 0x34, 0x06, 0x02, 0x02, 0x38, 0x06, 0x02, 0x02, 0x3c, 0x06, 0x02, 0x02, 0xc0, 0x1f, 0x03, 0x03, 0xc8, 0x1f, 0x03, 0x03, 0xd0, 0x1f, 0x03, 0x03, 0x28, 0x01, 0x04, 0x03, + 0x30, 0x01, 0x04, 0x03, 0xe0, 0x18, 0x05, 0x04, 0x40, 0x38, 0x06, 0x05, 0x80, 0x12, 0x07, 0x05, 0x80, 0x0c, 0x09, 0x06, 0xd0, 0x3c, 0x00, 0x03, 0xd8, 0x3c, 0x00, 0x03, 0xe0, 0x3c, 0x00, 0x03, + 0xe8, 0x3c, 0x00, 0x03, 0x94, 0x27, 0x01, 0x02, 0x98, 0x27, 0x01, 0x02, 0x9c, 0x27, 0x01, 0x02, 0xa0, 0x27, 0x01, 0x02, 0xa4, 0x27, 0x01, 0x02, 0xa8, 0x27, 0x01, 0x02, 0xac, 0x27, 0x01, 0x02, + 0x40, 0x06, 0x02, 0x02, 0x44, 0x06, 0x02, 0x02, 0x48, 0x06, 0x02, 0x02, 0x4c, 0x06, 0x02, 0x02, 0xd8, 0x1f, 0x03, 0x03, 0xe0, 0x1f, 0x03, 0x03, 0xe8, 0x1f, 0x03, 0x03, 0x38, 0x01, 0x04, 0x03, + 0x40, 0x01, 0x04, 0x03, 0xf0, 0x18, 0x05, 0x04, 0x60, 0x38, 0x06, 0x05, 0xa0, 0x12, 0x07, 0x05, 0xc0, 0x0c, 0x09, 0x06, 0xf0, 0x3c, 0x00, 0x03, 0xf8, 0x3c, 0x00, 0x03, 0x00, 0x3d, 0x00, 0x03, + 0x08, 0x3d, 0x00, 0x03, 0xb0, 0x27, 0x01, 0x02, 0xb4, 0x27, 0x01, 0x02, 0xb8, 0x27, 0x01, 0x02, 0xbc, 0x27, 0x01, 0x02, 0xc0, 0x27, 0x01, 0x02, 0xc4, 0x27, 0x01, 0x02, 0xc8, 0x27, 0x01, 0x02, + 0x50, 0x06, 0x02, 0x02, 0x54, 0x06, 0x02, 0x02, 0x58, 0x06, 0x02, 0x02, 0x5c, 0x06, 0x02, 0x02, 0xf0, 0x1f, 0x03, 0x03, 0xf8, 0x1f, 0x03, 0x03, 0x00, 0x20, 0x03, 0x03, 0x48, 0x01, 0x04, 0x03, + 0x50, 0x01, 0x04, 0x03, 0x00, 0x19, 0x05, 0x04, 0x80, 0x38, 0x06, 0x05, 0xc0, 0x12, 0x07, 0x05, 0x00, 0x0d, 0x09, 0x06, 0x10, 0x3d, 0x00, 0x03, 0x18, 0x3d, 0x00, 0x03, 0x20, 0x3d, 0x00, 0x03, + 0x28, 0x3d, 0x00, 0x03, 0xcc, 0x27, 0x01, 0x02, 0xd0, 0x27, 0x01, 0x02, 0xd4, 0x27, 0x01, 0x02, 0xd8, 0x27, 0x01, 0x02, 0xdc, 0x27, 0x01, 0x02, 0xe0, 0x27, 0x01, 0x02, 0xe4, 0x27, 0x01, 0x02, + 0x60, 0x06, 0x02, 0x02, 0x64, 0x06, 0x02, 0x02, 0x68, 0x06, 0x02, 0x02, 0x6c, 0x06, 0x02, 0x02, 0x08, 0x20, 0x03, 0x03, 0x10, 0x20, 0x03, 0x03, 0x18, 0x20, 0x03, 0x03, 0x58, 0x01, 0x04, 0x03, + 0x60, 0x01, 0x04, 0x03, 0x10, 0x19, 0x05, 0x04, 0xa0, 0x38, 0x06, 0x05, 0xe0, 0x12, 0x07, 0x05, 0x40, 0x0d, 0x09, 0x06, 0x30, 0x3d, 0x00, 0x03, 0x38, 0x3d, 0x00, 0x03, 0x40, 0x3d, 0x00, 0x03, + 0x48, 0x3d, 0x00, 0x03, 0xe8, 0x27, 0x01, 0x02, 0xec, 0x27, 0x01, 0x02, 0xf0, 0x27, 0x01, 0x02, 0xf4, 0x27, 0x01, 0x02, 0xf8, 0x27, 0x01, 0x02, 0xfc, 0x27, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, + 0x70, 0x06, 0x02, 0x02, 0x74, 0x06, 0x02, 0x02, 0x78, 0x06, 0x02, 0x02, 0x7c, 0x06, 0x02, 0x02, 0x20, 0x20, 0x03, 0x03, 0x28, 0x20, 0x03, 0x03, 0x30, 0x20, 0x03, 0x03, 0x68, 0x01, 0x04, 0x03, + 0x70, 0x01, 0x04, 0x03, 0x20, 0x19, 0x05, 0x04, 0xc0, 0x38, 0x06, 0x05, 0x00, 0x13, 0x07, 0x05, 0x80, 0x0d, 0x09, 0x06, 0x50, 0x3d, 0x00, 0x03, 0x58, 0x3d, 0x00, 0x03, 0x60, 0x3d, 0x00, 0x03, + 0x68, 0x3d, 0x00, 0x03, 0x04, 0x28, 0x01, 0x02, 0x08, 0x28, 0x01, 0x02, 0x0c, 0x28, 0x01, 0x02, 0x10, 0x28, 0x01, 0x02, 0x14, 0x28, 0x01, 0x02, 0x18, 0x28, 0x01, 0x02, 0x1c, 0x28, 0x01, 0x02, + 0x80, 0x06, 0x02, 0x02, 0x84, 0x06, 0x02, 0x02, 0x88, 0x06, 0x02, 0x02, 0x8c, 0x06, 0x02, 0x02, 0x38, 0x20, 0x03, 0x03, 0x40, 0x20, 0x03, 0x03, 0x48, 0x20, 0x03, 0x03, 0x78, 0x01, 0x04, 0x03, + 0x80, 0x01, 0x04, 0x03, 0x30, 0x19, 0x05, 0x04, 0xe0, 0x38, 0x06, 0x05, 0x20, 0x13, 0x07, 0x05, 0xc0, 0x0d, 0x09, 0x06, 0x70, 0x3d, 0x00, 0x03, 0x78, 0x3d, 0x00, 0x03, 0x80, 0x3d, 0x00, 0x03, + 0x88, 0x3d, 0x00, 0x03, 0x20, 0x28, 0x01, 0x02, 0x24, 0x28, 0x01, 0x02, 0x28, 0x28, 0x01, 0x02, 0x2c, 0x28, 0x01, 0x02, 0x30, 0x28, 0x01, 0x02, 0x34, 0x28, 0x01, 0x02, 0x38, 0x28, 0x01, 0x02, + 0x90, 0x06, 0x02, 0x02, 0x94, 0x06, 0x02, 0x02, 0x98, 0x06, 0x02, 0x02, 0x9c, 0x06, 0x02, 0x02, 0x50, 0x20, 0x03, 0x03, 0x58, 0x20, 0x03, 0x03, 0x60, 0x20, 0x03, 0x03, 0x88, 0x01, 0x04, 0x03, + 0x90, 0x01, 0x04, 0x03, 0x40, 0x19, 0x05, 0x04, 0x00, 0x39, 0x06, 0x05, 0x40, 0x13, 0x07, 0x05, 0x00, 0x0e, 0x09, 0x06, 0x90, 0x3d, 0x00, 0x03, 0x98, 0x3d, 0x00, 0x03, 0xa0, 0x3d, 0x00, 0x03, + 0xa8, 0x3d, 0x00, 0x03, 0x3c, 0x28, 0x01, 0x02, 0x40, 0x28, 0x01, 0x02, 0x44, 0x28, 0x01, 0x02, 0x48, 0x28, 0x01, 0x02, 0x4c, 0x28, 0x01, 0x02, 0x50, 0x28, 0x01, 0x02, 0x54, 0x28, 0x01, 0x02, + 0xa0, 0x06, 0x02, 0x02, 0xa4, 0x06, 0x02, 0x02, 0xa8, 0x06, 0x02, 0x02, 0xac, 0x06, 0x02, 0x02, 0x68, 0x20, 0x03, 0x03, 0x70, 0x20, 0x03, 0x03, 0x78, 0x20, 0x03, 0x03, 0x98, 0x01, 0x04, 0x03, + 0xa0, 0x01, 0x04, 0x03, 0x50, 0x19, 0x05, 0x04, 0x20, 0x39, 0x06, 0x05, 0x60, 0x13, 0x07, 0x05, 0x40, 0x0e, 0x09, 0x06, 0xb0, 0x3d, 0x00, 0x03, 0xb8, 0x3d, 0x00, 0x03, 0xc0, 0x3d, 0x00, 0x03, + 0xc8, 0x3d, 0x00, 0x03, 0x58, 0x28, 0x01, 0x02, 0x5c, 0x28, 0x01, 0x02, 0x60, 0x28, 0x01, 0x02, 0x64, 0x28, 0x01, 0x02, 0x68, 0x28, 0x01, 0x02, 0x6c, 0x28, 0x01, 0x02, 0x70, 0x28, 0x01, 0x02, + 0xb0, 0x06, 0x02, 0x02, 0xb4, 0x06, 0x02, 0x02, 0xb8, 0x06, 0x02, 0x02, 0xbc, 0x06, 0x02, 0x02, 0x80, 0x20, 0x03, 0x03, 0x88, 0x20, 0x03, 0x03, 0x90, 0x20, 0x03, 0x03, 0xa8, 0x01, 0x04, 0x03, + 0xb0, 0x01, 0x04, 0x03, 0x60, 0x19, 0x05, 0x04, 0x40, 0x39, 0x06, 0x05, 0x80, 0x13, 0x07, 0x05, 0x80, 0x0e, 0x09, 0x06, 0xd0, 0x3d, 0x00, 0x03, 0xd8, 0x3d, 0x00, 0x03, 0xe0, 0x3d, 0x00, 0x03, + 0xe8, 0x3d, 0x00, 0x03, 0x74, 0x28, 0x01, 0x02, 0x78, 0x28, 0x01, 0x02, 0x7c, 0x28, 0x01, 0x02, 0x80, 0x28, 0x01, 0x02, 0x84, 0x28, 0x01, 0x02, 0x88, 0x28, 0x01, 0x02, 0x8c, 0x28, 0x01, 0x02, + 0xc0, 0x06, 0x02, 0x02, 0xc4, 0x06, 0x02, 0x02, 0xc8, 0x06, 0x02, 0x02, 0xcc, 0x06, 0x02, 0x02, 0x98, 0x20, 0x03, 0x03, 0xa0, 0x20, 0x03, 0x03, 0xa8, 0x20, 0x03, 0x03, 0xb8, 0x01, 0x04, 0x03, + 0xc0, 0x01, 0x04, 0x03, 0x70, 0x19, 0x05, 0x04, 0x60, 0x39, 0x06, 0x05, 0xa0, 0x13, 0x07, 0x05, 0xc0, 0x0e, 0x09, 0x06, 0xf0, 0x3d, 0x00, 0x03, 0xf8, 0x3d, 0x00, 0x03, 0x00, 0x3e, 0x00, 0x03, + 0x08, 0x3e, 0x00, 0x03, 0x90, 0x28, 0x01, 0x02, 0x94, 0x28, 0x01, 0x02, 0x98, 0x28, 0x01, 0x02, 0x9c, 0x28, 0x01, 0x02, 0xa0, 0x28, 0x01, 0x02, 0xa4, 0x28, 0x01, 0x02, 0xa8, 0x28, 0x01, 0x02, + 0xd0, 0x06, 0x02, 0x02, 0xd4, 0x06, 0x02, 0x02, 0xd8, 0x06, 0x02, 0x02, 0xdc, 0x06, 0x02, 0x02, 0xb0, 0x20, 0x03, 0x03, 0xb8, 0x20, 0x03, 0x03, 0xc0, 0x20, 0x03, 0x03, 0xc8, 0x01, 0x04, 0x03, + 0xd0, 0x01, 0x04, 0x03, 0x80, 0x19, 0x05, 0x04, 0x80, 0x39, 0x06, 0x05, 0xc0, 0x13, 0x07, 0x05, 0x00, 0x0f, 0x09, 0x06, 0x10, 0x3e, 0x00, 0x03, 0x18, 0x3e, 0x00, 0x03, 0x20, 0x3e, 0x00, 0x03, + 0x28, 0x3e, 0x00, 0x03, 0xac, 0x28, 0x01, 0x02, 0xb0, 0x28, 0x01, 0x02, 0xb4, 0x28, 0x01, 0x02, 0xb8, 0x28, 0x01, 0x02, 0xbc, 0x28, 0x01, 0x02, 0xc0, 0x28, 0x01, 0x02, 0xe0, 0x06, 0x02, 0x02, + 0xe4, 0x06, 0x02, 0x02, 0xe8, 0x06, 0x02, 0x02, 0xec, 0x06, 0x02, 0x02, 0xf0, 0x06, 0x02, 0x02, 0xc8, 0x20, 0x03, 0x03, 0xd0, 0x20, 0x03, 0x03, 0xd8, 0x20, 0x03, 0x03, 0xd8, 0x01, 0x04, 0x03, + 0xe0, 0x01, 0x04, 0x03, 0x90, 0x19, 0x05, 0x04, 0xa0, 0x39, 0x06, 0x05, 0xe0, 0x13, 0x07, 0x05, 0x40, 0x0f, 0x09, 0x06, 0x30, 0x3e, 0x00, 0x03, 0x38, 0x3e, 0x00, 0x03, 0x40, 0x3e, 0x00, 0x03, + 0x48, 0x3e, 0x00, 0x03, 0xc4, 0x28, 0x01, 0x02, 0xc8, 0x28, 0x01, 0x02, 0xcc, 0x28, 0x01, 0x02, 0xd0, 0x28, 0x01, 0x02, 0xd4, 0x28, 0x01, 0x02, 0xd8, 0x28, 0x01, 0x02, 0xf4, 0x06, 0x02, 0x02, + 0xf8, 0x06, 0x02, 0x02, 0xfc, 0x06, 0x02, 0x02, 0x00, 0x07, 0x02, 0x02, 0x04, 0x07, 0x02, 0x02, 0xe0, 0x20, 0x03, 0x03, 0xe8, 0x20, 0x03, 0x03, 0xf0, 0x20, 0x03, 0x03, 0xe8, 0x01, 0x04, 0x03, + 0xf0, 0x01, 0x04, 0x03, 0xa0, 0x19, 0x05, 0x04, 0xc0, 0x39, 0x06, 0x05, 0x00, 0x14, 0x07, 0x05, 0x80, 0x0f, 0x09, 0x06, 0x50, 0x3e, 0x00, 0x03, 0x58, 0x3e, 0x00, 0x03, 0x60, 0x3e, 0x00, 0x03, + 0x68, 0x3e, 0x00, 0x03, 0xdc, 0x28, 0x01, 0x02, 0xe0, 0x28, 0x01, 0x02, 0xe4, 0x28, 0x01, 0x02, 0xe8, 0x28, 0x01, 0x02, 0xec, 0x28, 0x01, 0x02, 0xf0, 0x28, 0x01, 0x02, 0x08, 0x07, 0x02, 0x02, + 0x0c, 0x07, 0x02, 0x02, 0x10, 0x07, 0x02, 0x02, 0x14, 0x07, 0x02, 0x02, 0x18, 0x07, 0x02, 0x02, 0xf8, 0x20, 0x03, 0x03, 0x00, 0x21, 0x03, 0x03, 0x08, 0x21, 0x03, 0x03, 0xf8, 0x01, 0x04, 0x03, + 0x00, 0x02, 0x04, 0x03, 0xb0, 0x19, 0x05, 0x04, 0xe0, 0x39, 0x06, 0x05, 0x20, 0x14, 0x07, 0x05, 0xc0, 0x0f, 0x09, 0x06, 0x70, 0x3e, 0x00, 0x03, 0x78, 0x3e, 0x00, 0x03, 0x80, 0x3e, 0x00, 0x03, + 0x88, 0x3e, 0x00, 0x03, 0xf4, 0x28, 0x01, 0x02, 0xf8, 0x28, 0x01, 0x02, 0xfc, 0x28, 0x01, 0x02, 0x00, 0x29, 0x01, 0x02, 0x04, 0x29, 0x01, 0x02, 0x08, 0x29, 0x01, 0x02, 0x1c, 0x07, 0x02, 0x02, + 0x20, 0x07, 0x02, 0x02, 0x24, 0x07, 0x02, 0x02, 0x28, 0x07, 0x02, 0x02, 0x2c, 0x07, 0x02, 0x02, 0x10, 0x21, 0x03, 0x03, 0x18, 0x21, 0x03, 0x03, 0x20, 0x21, 0x03, 0x03, 0x08, 0x02, 0x04, 0x03, + 0x10, 0x02, 0x04, 0x03, 0xc0, 0x19, 0x05, 0x04, 0x00, 0x3a, 0x06, 0x05, 0x40, 0x14, 0x07, 0x05, 0x00, 0x10, 0x09, 0x06, 0x90, 0x3e, 0x00, 0x03, 0x98, 0x3e, 0x00, 0x03, 0xa0, 0x3e, 0x00, 0x03, + 0xa8, 0x3e, 0x00, 0x03, 0x0c, 0x29, 0x01, 0x02, 0x10, 0x29, 0x01, 0x02, 0x14, 0x29, 0x01, 0x02, 0x18, 0x29, 0x01, 0x02, 0x1c, 0x29, 0x01, 0x02, 0x20, 0x29, 0x01, 0x02, 0x30, 0x07, 0x02, 0x02, + 0x34, 0x07, 0x02, 0x02, 0x38, 0x07, 0x02, 0x02, 0x3c, 0x07, 0x02, 0x02, 0x40, 0x07, 0x02, 0x02, 0x28, 0x21, 0x03, 0x03, 0x30, 0x21, 0x03, 0x03, 0x38, 0x21, 0x03, 0x03, 0x18, 0x02, 0x04, 0x03, + 0x20, 0x02, 0x04, 0x03, 0xd0, 0x19, 0x05, 0x04, 0x20, 0x3a, 0x06, 0x05, 0x60, 0x14, 0x07, 0x05, 0x40, 0x10, 0x09, 0x06, 0xb0, 0x3e, 0x00, 0x03, 0xb8, 0x3e, 0x00, 0x03, 0xc0, 0x3e, 0x00, 0x03, + 0xc8, 0x3e, 0x00, 0x03, 0x24, 0x29, 0x01, 0x02, 0x28, 0x29, 0x01, 0x02, 0x2c, 0x29, 0x01, 0x02, 0x30, 0x29, 0x01, 0x02, 0x34, 0x29, 0x01, 0x02, 0x38, 0x29, 0x01, 0x02, 0x44, 0x07, 0x02, 0x02, + 0x48, 0x07, 0x02, 0x02, 0x4c, 0x07, 0x02, 0x02, 0x50, 0x07, 0x02, 0x02, 0x54, 0x07, 0x02, 0x02, 0x40, 0x21, 0x03, 0x03, 0x48, 0x21, 0x03, 0x03, 0x50, 0x21, 0x03, 0x03, 0x28, 0x02, 0x04, 0x03, + 0x30, 0x02, 0x04, 0x03, 0xe0, 0x19, 0x05, 0x04, 0x40, 0x3a, 0x06, 0x05, 0x80, 0x14, 0x07, 0x05, 0x80, 0x10, 0x09, 0x06, 0xd0, 0x3e, 0x00, 0x03, 0xd8, 0x3e, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x03, + 0xe8, 0x3e, 0x00, 0x03, 0x3c, 0x29, 0x01, 0x02, 0x40, 0x29, 0x01, 0x02, 0x44, 0x29, 0x01, 0x02, 0x48, 0x29, 0x01, 0x02, 0x4c, 0x29, 0x01, 0x02, 0x50, 0x29, 0x01, 0x02, 0x58, 0x07, 0x02, 0x02, + 0x5c, 0x07, 0x02, 0x02, 0x60, 0x07, 0x02, 0x02, 0x64, 0x07, 0x02, 0x02, 0x68, 0x07, 0x02, 0x02, 0x58, 0x21, 0x03, 0x03, 0x60, 0x21, 0x03, 0x03, 0x68, 0x21, 0x03, 0x03, 0x38, 0x02, 0x04, 0x03, + 0x40, 0x02, 0x04, 0x03, 0xf0, 0x19, 0x05, 0x04, 0x60, 0x3a, 0x06, 0x05, 0xa0, 0x14, 0x07, 0x05, 0x00, 0x26, 0x0a, 0x07, 0xf0, 0x3e, 0x00, 0x03, 0xf8, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x03, + 0x08, 0x3f, 0x00, 0x03, 0x54, 0x29, 0x01, 0x02, 0x58, 0x29, 0x01, 0x02, 0x5c, 0x29, 0x01, 0x02, 0x60, 0x29, 0x01, 0x02, 0x64, 0x29, 0x01, 0x02, 0x68, 0x29, 0x01, 0x02, 0x6c, 0x07, 0x02, 0x02, + 0x70, 0x07, 0x02, 0x02, 0x74, 0x07, 0x02, 0x02, 0x78, 0x07, 0x02, 0x02, 0x7c, 0x07, 0x02, 0x02, 0x70, 0x21, 0x03, 0x03, 0x78, 0x21, 0x03, 0x03, 0x80, 0x21, 0x03, 0x03, 0x48, 0x02, 0x04, 0x03, + 0x50, 0x02, 0x04, 0x03, 0x00, 0x1a, 0x05, 0x04, 0x80, 0x3a, 0x06, 0x05, 0xc0, 0x14, 0x07, 0x05, 0x80, 0x26, 0x0a, 0x07, 0x10, 0x3f, 0x00, 0x03, 0x18, 0x3f, 0x00, 0x03, 0x20, 0x3f, 0x00, 0x03, + 0x28, 0x3f, 0x00, 0x03, 0x6c, 0x29, 0x01, 0x02, 0x70, 0x29, 0x01, 0x02, 0x74, 0x29, 0x01, 0x02, 0x78, 0x29, 0x01, 0x02, 0x7c, 0x29, 0x01, 0x02, 0x80, 0x29, 0x01, 0x02, 0x80, 0x07, 0x02, 0x02, + 0x84, 0x07, 0x02, 0x02, 0x88, 0x07, 0x02, 0x02, 0x8c, 0x07, 0x02, 0x02, 0x90, 0x07, 0x02, 0x02, 0x88, 0x21, 0x03, 0x03, 0x90, 0x21, 0x03, 0x03, 0x98, 0x21, 0x03, 0x03, 0x58, 0x02, 0x04, 0x03, + 0x60, 0x02, 0x04, 0x03, 0x10, 0x1a, 0x05, 0x04, 0xa0, 0x3a, 0x06, 0x05, 0xe0, 0x14, 0x07, 0x05, 0x00, 0x27, 0x0a, 0x07, 0x30, 0x3f, 0x00, 0x03, 0x38, 0x3f, 0x00, 0x03, 0x40, 0x3f, 0x00, 0x03, + 0x48, 0x3f, 0x00, 0x03, 0x84, 0x29, 0x01, 0x02, 0x88, 0x29, 0x01, 0x02, 0x8c, 0x29, 0x01, 0x02, 0x90, 0x29, 0x01, 0x02, 0x94, 0x29, 0x01, 0x02, 0x98, 0x29, 0x01, 0x02, 0x94, 0x07, 0x02, 0x02, + 0x98, 0x07, 0x02, 0x02, 0x9c, 0x07, 0x02, 0x02, 0xa0, 0x07, 0x02, 0x02, 0xa4, 0x07, 0x02, 0x02, 0xa0, 0x21, 0x03, 0x03, 0xa8, 0x21, 0x03, 0x03, 0xb0, 0x21, 0x03, 0x03, 0x68, 0x02, 0x04, 0x03, + 0x70, 0x02, 0x04, 0x03, 0x20, 0x1a, 0x05, 0x04, 0xc0, 0x3a, 0x06, 0x05, 0x00, 0x15, 0x07, 0x05, 0x80, 0x27, 0x0a, 0x07, 0x50, 0x3f, 0x00, 0x03, 0x58, 0x3f, 0x00, 0x03, 0x60, 0x3f, 0x00, 0x03, + 0x68, 0x3f, 0x00, 0x03, 0x9c, 0x29, 0x01, 0x02, 0xa0, 0x29, 0x01, 0x02, 0xa4, 0x29, 0x01, 0x02, 0xa8, 0x29, 0x01, 0x02, 0xac, 0x29, 0x01, 0x02, 0xb0, 0x29, 0x01, 0x02, 0xa8, 0x07, 0x02, 0x02, + 0xac, 0x07, 0x02, 0x02, 0xb0, 0x07, 0x02, 0x02, 0xb4, 0x07, 0x02, 0x02, 0xb8, 0x07, 0x02, 0x02, 0xb8, 0x21, 0x03, 0x03, 0xc0, 0x21, 0x03, 0x03, 0xc8, 0x21, 0x03, 0x03, 0x78, 0x02, 0x04, 0x03, + 0x80, 0x02, 0x04, 0x03, 0x30, 0x1a, 0x05, 0x04, 0xe0, 0x3a, 0x06, 0x05, 0x20, 0x15, 0x07, 0x05, 0x00, 0x28, 0x0a, 0x07, 0x70, 0x3f, 0x00, 0x03, 0x78, 0x3f, 0x00, 0x03, 0x80, 0x3f, 0x00, 0x03, + 0x88, 0x3f, 0x00, 0x03, 0xb4, 0x29, 0x01, 0x02, 0xb8, 0x29, 0x01, 0x02, 0xbc, 0x29, 0x01, 0x02, 0xc0, 0x29, 0x01, 0x02, 0xc4, 0x29, 0x01, 0x02, 0xc8, 0x29, 0x01, 0x02, 0xbc, 0x07, 0x02, 0x02, + 0xc0, 0x07, 0x02, 0x02, 0xc4, 0x07, 0x02, 0x02, 0xc8, 0x07, 0x02, 0x02, 0xcc, 0x07, 0x02, 0x02, 0xd0, 0x21, 0x03, 0x03, 0xd8, 0x21, 0x03, 0x03, 0xe0, 0x21, 0x03, 0x03, 0x88, 0x02, 0x04, 0x03, + 0x90, 0x02, 0x04, 0x03, 0x40, 0x1a, 0x05, 0x04, 0x00, 0x3b, 0x06, 0x05, 0x40, 0x15, 0x07, 0x05, 0x80, 0x28, 0x0a, 0x07, 0x90, 0x3f, 0x00, 0x03, 0x98, 0x3f, 0x00, 0x03, 0xa0, 0x3f, 0x00, 0x03, + 0xa8, 0x3f, 0x00, 0x03, 0xcc, 0x29, 0x01, 0x02, 0xd0, 0x29, 0x01, 0x02, 0xd4, 0x29, 0x01, 0x02, 0xd8, 0x29, 0x01, 0x02, 0xdc, 0x29, 0x01, 0x02, 0xe0, 0x29, 0x01, 0x02, 0xd0, 0x07, 0x02, 0x02, + 0xd4, 0x07, 0x02, 0x02, 0xd8, 0x07, 0x02, 0x02, 0xdc, 0x07, 0x02, 0x02, 0xe0, 0x07, 0x02, 0x02, 0xe8, 0x21, 0x03, 0x03, 0xf0, 0x21, 0x03, 0x03, 0xf8, 0x21, 0x03, 0x03, 0x98, 0x02, 0x04, 0x03, + 0xa0, 0x02, 0x04, 0x03, 0x50, 0x1a, 0x05, 0x04, 0x20, 0x3b, 0x06, 0x05, 0x60, 0x15, 0x07, 0x05, 0x00, 0x29, 0x0a, 0x07, 0xb0, 0x3f, 0x00, 0x03, 0xb8, 0x3f, 0x00, 0x03, 0xc0, 0x3f, 0x00, 0x03, + 0xc8, 0x3f, 0x00, 0x03, 0xe4, 0x29, 0x01, 0x02, 0xe8, 0x29, 0x01, 0x02, 0xec, 0x29, 0x01, 0x02, 0xf0, 0x29, 0x01, 0x02, 0xf4, 0x29, 0x01, 0x02, 0xf8, 0x29, 0x01, 0x02, 0xe4, 0x07, 0x02, 0x02, + 0xe8, 0x07, 0x02, 0x02, 0xec, 0x07, 0x02, 0x02, 0xf0, 0x07, 0x02, 0x02, 0xf4, 0x07, 0x02, 0x02, 0x00, 0x22, 0x03, 0x03, 0x08, 0x22, 0x03, 0x03, 0x10, 0x22, 0x03, 0x03, 0xa8, 0x02, 0x04, 0x03, + 0xb0, 0x02, 0x04, 0x03, 0x60, 0x1a, 0x05, 0x04, 0x40, 0x3b, 0x06, 0x05, 0x80, 0x15, 0x07, 0x05, 0x80, 0x29, 0x0a, 0x07, 0xd0, 0x3f, 0x00, 0x03, 0xd8, 0x3f, 0x00, 0x03, 0xe0, 0x3f, 0x00, 0x03, + 0xe8, 0x3f, 0x00, 0x03, 0xfc, 0x29, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x04, 0x2a, 0x01, 0x02, 0x08, 0x2a, 0x01, 0x02, 0x0c, 0x2a, 0x01, 0x02, 0x10, 0x2a, 0x01, 0x02, 0xf8, 0x07, 0x02, 0x02, + 0xfc, 0x07, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x04, 0x08, 0x02, 0x02, 0x08, 0x08, 0x02, 0x02, 0x18, 0x22, 0x03, 0x03, 0x20, 0x22, 0x03, 0x03, 0x28, 0x22, 0x03, 0x03, 0xb8, 0x02, 0x04, 0x03, + 0xc0, 0x02, 0x04, 0x03, 0x70, 0x1a, 0x05, 0x04, 0x60, 0x3b, 0x06, 0x05, 0xa0, 0x15, 0x07, 0x05, 0x00, 0x2a, 0x0a, 0x07, 0xf0, 0x3f, 0x00, 0x03, 0xf8, 0x3f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x02, 0x14, 0x2a, 0x01, 0x02, 0x18, 0x2a, 0x01, 0x02, 0x1c, 0x2a, 0x01, 0x02, 0x20, 0x2a, 0x01, 0x02, 0x24, 0x2a, 0x01, 0x02, 0x28, 0x2a, 0x01, 0x02, 0x0c, 0x08, 0x02, 0x02, + 0x10, 0x08, 0x02, 0x02, 0x14, 0x08, 0x02, 0x02, 0x18, 0x08, 0x02, 0x02, 0x1c, 0x08, 0x02, 0x02, 0x30, 0x22, 0x03, 0x03, 0x38, 0x22, 0x03, 0x03, 0x40, 0x22, 0x03, 0x03, 0xc8, 0x02, 0x04, 0x03, + 0xd0, 0x02, 0x04, 0x03, 0x80, 0x1a, 0x05, 0x04, 0x80, 0x3b, 0x06, 0x05, 0xc0, 0x15, 0x07, 0x05, 0x80, 0x2a, 0x0a, 0x07, 0x08, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x02, + 0x14, 0x00, 0x00, 0x02, 0x2c, 0x2a, 0x01, 0x02, 0x30, 0x2a, 0x01, 0x02, 0x34, 0x2a, 0x01, 0x02, 0x38, 0x2a, 0x01, 0x02, 0x3c, 0x2a, 0x01, 0x02, 0x40, 0x2a, 0x01, 0x02, 0x20, 0x08, 0x02, 0x02, + 0x24, 0x08, 0x02, 0x02, 0x28, 0x08, 0x02, 0x02, 0x2c, 0x08, 0x02, 0x02, 0x30, 0x08, 0x02, 0x02, 0x48, 0x22, 0x03, 0x03, 0x50, 0x22, 0x03, 0x03, 0x58, 0x22, 0x03, 0x03, 0xd8, 0x02, 0x04, 0x03, + 0xe0, 0x02, 0x04, 0x03, 0x90, 0x1a, 0x05, 0x04, 0xa0, 0x3b, 0x06, 0x05, 0xe0, 0x15, 0x07, 0x05, 0x00, 0x2b, 0x0a, 0x07, 0x18, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x02, + 0x24, 0x00, 0x00, 0x02, 0x44, 0x2a, 0x01, 0x02, 0x48, 0x2a, 0x01, 0x02, 0x4c, 0x2a, 0x01, 0x02, 0x50, 0x2a, 0x01, 0x02, 0x54, 0x2a, 0x01, 0x02, 0x58, 0x2a, 0x01, 0x02, 0x34, 0x08, 0x02, 0x02, + 0x38, 0x08, 0x02, 0x02, 0x3c, 0x08, 0x02, 0x02, 0x40, 0x08, 0x02, 0x02, 0x44, 0x08, 0x02, 0x02, 0x60, 0x22, 0x03, 0x03, 0x68, 0x22, 0x03, 0x03, 0x70, 0x22, 0x03, 0x03, 0xe8, 0x02, 0x04, 0x03, + 0xf0, 0x02, 0x04, 0x03, 0xa0, 0x1a, 0x05, 0x04, 0xc0, 0x3b, 0x06, 0x05, 0x00, 0x16, 0x07, 0x05, 0x80, 0x2b, 0x0a, 0x07, 0x28, 0x00, 0x00, 0x02, 0x2c, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x02, + 0x34, 0x00, 0x00, 0x02, 0x5c, 0x2a, 0x01, 0x02, 0x60, 0x2a, 0x01, 0x02, 0x64, 0x2a, 0x01, 0x02, 0x68, 0x2a, 0x01, 0x02, 0x6c, 0x2a, 0x01, 0x02, 0x70, 0x2a, 0x01, 0x02, 0x48, 0x08, 0x02, 0x02, + 0x4c, 0x08, 0x02, 0x02, 0x50, 0x08, 0x02, 0x02, 0x54, 0x08, 0x02, 0x02, 0x58, 0x08, 0x02, 0x02, 0x78, 0x22, 0x03, 0x03, 0x80, 0x22, 0x03, 0x03, 0x88, 0x22, 0x03, 0x03, 0xf8, 0x02, 0x04, 0x03, + 0x00, 0x03, 0x04, 0x03, 0xb0, 0x1a, 0x05, 0x04, 0xe0, 0x3b, 0x06, 0x05, 0x20, 0x16, 0x07, 0x05, 0x00, 0x2c, 0x0a, 0x07, 0x38, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, + 0x44, 0x00, 0x00, 0x02, 0x74, 0x2a, 0x01, 0x02, 0x78, 0x2a, 0x01, 0x02, 0x7c, 0x2a, 0x01, 0x02, 0x80, 0x2a, 0x01, 0x02, 0x84, 0x2a, 0x01, 0x02, 0x88, 0x2a, 0x01, 0x02, 0x5c, 0x08, 0x02, 0x02, + 0x60, 0x08, 0x02, 0x02, 0x64, 0x08, 0x02, 0x02, 0x68, 0x08, 0x02, 0x02, 0x6c, 0x08, 0x02, 0x02, 0x90, 0x22, 0x03, 0x03, 0x98, 0x22, 0x03, 0x03, 0xa0, 0x22, 0x03, 0x03, 0x08, 0x03, 0x04, 0x03, + 0x10, 0x03, 0x04, 0x03, 0xc0, 0x1a, 0x05, 0x04, 0x00, 0x3c, 0x06, 0x05, 0x40, 0x16, 0x07, 0x05, 0x80, 0x2c, 0x0a, 0x07, 0x48, 0x00, 0x00, 0x02, 0x4c, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x02, + 0x54, 0x00, 0x00, 0x02, 0x8c, 0x2a, 0x01, 0x02, 0x90, 0x2a, 0x01, 0x02, 0x94, 0x2a, 0x01, 0x02, 0x98, 0x2a, 0x01, 0x02, 0x9c, 0x2a, 0x01, 0x02, 0xa0, 0x2a, 0x01, 0x02, 0x70, 0x08, 0x02, 0x02, + 0x74, 0x08, 0x02, 0x02, 0x78, 0x08, 0x02, 0x02, 0x7c, 0x08, 0x02, 0x02, 0x80, 0x08, 0x02, 0x02, 0xa8, 0x22, 0x03, 0x03, 0xb0, 0x22, 0x03, 0x03, 0xb8, 0x22, 0x03, 0x03, 0x18, 0x03, 0x04, 0x03, + 0x20, 0x03, 0x04, 0x03, 0xd0, 0x1a, 0x05, 0x04, 0x20, 0x3c, 0x06, 0x05, 0x60, 0x16, 0x07, 0x05, 0x00, 0x2d, 0x0a, 0x07, 0x58, 0x00, 0x00, 0x02, 0x5c, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x02, + 0x64, 0x00, 0x00, 0x02, 0xa4, 0x2a, 0x01, 0x02, 0xa8, 0x2a, 0x01, 0x02, 0xac, 0x2a, 0x01, 0x02, 0xb0, 0x2a, 0x01, 0x02, 0xb4, 0x2a, 0x01, 0x02, 0xb8, 0x2a, 0x01, 0x02, 0x84, 0x08, 0x02, 0x02, + 0x88, 0x08, 0x02, 0x02, 0x8c, 0x08, 0x02, 0x02, 0x90, 0x08, 0x02, 0x02, 0x94, 0x08, 0x02, 0x02, 0xc0, 0x22, 0x03, 0x03, 0xc8, 0x22, 0x03, 0x03, 0xd0, 0x22, 0x03, 0x03, 0x28, 0x03, 0x04, 0x03, + 0x30, 0x03, 0x04, 0x03, 0xe0, 0x1a, 0x05, 0x04, 0x40, 0x3c, 0x06, 0x05, 0x80, 0x16, 0x07, 0x05, 0x80, 0x2d, 0x0a, 0x07, 0x68, 0x00, 0x00, 0x02, 0x6c, 0x00, 0x00, 0x02, 0x70, 0x00, 0x00, 0x02, + 0x74, 0x00, 0x00, 0x02, 0xbc, 0x2a, 0x01, 0x02, 0xc0, 0x2a, 0x01, 0x02, 0xc4, 0x2a, 0x01, 0x02, 0xc8, 0x2a, 0x01, 0x02, 0xcc, 0x2a, 0x01, 0x02, 0xd0, 0x2a, 0x01, 0x02, 0x98, 0x08, 0x02, 0x02, + 0x9c, 0x08, 0x02, 0x02, 0xa0, 0x08, 0x02, 0x02, 0xa4, 0x08, 0x02, 0x02, 0xa8, 0x08, 0x02, 0x02, 0xd8, 0x22, 0x03, 0x03, 0xe0, 0x22, 0x03, 0x03, 0xe8, 0x22, 0x03, 0x03, 0x38, 0x03, 0x04, 0x03, + 0x40, 0x03, 0x04, 0x03, 0xf0, 0x1a, 0x05, 0x04, 0x60, 0x3c, 0x06, 0x05, 0xa0, 0x16, 0x07, 0x05, 0x00, 0x2e, 0x0a, 0x07, 0x78, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x02, + 0x84, 0x00, 0x00, 0x02, 0xd4, 0x2a, 0x01, 0x02, 0xd8, 0x2a, 0x01, 0x02, 0xdc, 0x2a, 0x01, 0x02, 0xe0, 0x2a, 0x01, 0x02, 0xe4, 0x2a, 0x01, 0x02, 0xe8, 0x2a, 0x01, 0x02, 0xac, 0x08, 0x02, 0x02, + 0xb0, 0x08, 0x02, 0x02, 0xb4, 0x08, 0x02, 0x02, 0xb8, 0x08, 0x02, 0x02, 0xbc, 0x08, 0x02, 0x02, 0xf0, 0x22, 0x03, 0x03, 0xf8, 0x22, 0x03, 0x03, 0x00, 0x23, 0x03, 0x03, 0x48, 0x03, 0x04, 0x03, + 0x50, 0x03, 0x04, 0x03, 0x00, 0x1b, 0x05, 0x04, 0x80, 0x3c, 0x06, 0x05, 0xc0, 0x16, 0x07, 0x05, 0x80, 0x05, 0x0b, 0x07, 0x88, 0x00, 0x00, 0x02, 0x8c, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, + 0x94, 0x00, 0x00, 0x02, 0xec, 0x2a, 0x01, 0x02, 0xf0, 0x2a, 0x01, 0x02, 0xf4, 0x2a, 0x01, 0x02, 0xf8, 0x2a, 0x01, 0x02, 0xfc, 0x2a, 0x01, 0x02, 0x00, 0x2b, 0x01, 0x02, 0xc0, 0x08, 0x02, 0x02, + 0xc4, 0x08, 0x02, 0x02, 0xc8, 0x08, 0x02, 0x02, 0xcc, 0x08, 0x02, 0x02, 0xd0, 0x08, 0x02, 0x02, 0x08, 0x23, 0x03, 0x03, 0x10, 0x23, 0x03, 0x03, 0x18, 0x23, 0x03, 0x03, 0x58, 0x03, 0x04, 0x03, + 0x60, 0x03, 0x04, 0x03, 0x10, 0x1b, 0x05, 0x04, 0xa0, 0x3c, 0x06, 0x05, 0xe0, 0x16, 0x07, 0x05, 0x00, 0x06, 0x0b, 0x07, 0x98, 0x00, 0x00, 0x02, 0x9c, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x02, + 0xa4, 0x00, 0x00, 0x02, 0x04, 0x2b, 0x01, 0x02, 0x08, 0x2b, 0x01, 0x02, 0x0c, 0x2b, 0x01, 0x02, 0x10, 0x2b, 0x01, 0x02, 0x14, 0x2b, 0x01, 0x02, 0x18, 0x2b, 0x01, 0x02, 0xd4, 0x08, 0x02, 0x02, + 0xd8, 0x08, 0x02, 0x02, 0xdc, 0x08, 0x02, 0x02, 0xe0, 0x08, 0x02, 0x02, 0xe4, 0x08, 0x02, 0x02, 0x20, 0x23, 0x03, 0x03, 0x28, 0x23, 0x03, 0x03, 0x30, 0x23, 0x03, 0x03, 0x68, 0x03, 0x04, 0x03, + 0x70, 0x03, 0x04, 0x03, 0x20, 0x1b, 0x05, 0x04, 0xc0, 0x3c, 0x06, 0x05, 0x00, 0x17, 0x07, 0x05, 0x80, 0x06, 0x0b, 0x07, 0xa8, 0x00, 0x00, 0x02, 0xac, 0x00, 0x00, 0x02, 0xb0, 0x00, 0x00, 0x02, + 0xb4, 0x00, 0x00, 0x02, 0x1c, 0x2b, 0x01, 0x02, 0x20, 0x2b, 0x01, 0x02, 0x24, 0x2b, 0x01, 0x02, 0x28, 0x2b, 0x01, 0x02, 0x2c, 0x2b, 0x01, 0x02, 0x30, 0x2b, 0x01, 0x02, 0xe8, 0x08, 0x02, 0x02, + 0xec, 0x08, 0x02, 0x02, 0xf0, 0x08, 0x02, 0x02, 0xf4, 0x08, 0x02, 0x02, 0xf8, 0x08, 0x02, 0x02, 0x38, 0x23, 0x03, 0x03, 0x40, 0x23, 0x03, 0x03, 0x48, 0x23, 0x03, 0x03, 0x78, 0x03, 0x04, 0x03, + 0x80, 0x03, 0x04, 0x03, 0x30, 0x1b, 0x05, 0x04, 0xe0, 0x3c, 0x06, 0x05, 0x20, 0x17, 0x07, 0x05, 0x00, 0x07, 0x0b, 0x07, 0xb8, 0x00, 0x00, 0x02, 0xbc, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x02, + 0xc4, 0x00, 0x00, 0x02, 0x34, 0x2b, 0x01, 0x02, 0x38, 0x2b, 0x01, 0x02, 0x3c, 0x2b, 0x01, 0x02, 0x40, 0x2b, 0x01, 0x02, 0x44, 0x2b, 0x01, 0x02, 0x48, 0x2b, 0x01, 0x02, 0xfc, 0x08, 0x02, 0x02, + 0x00, 0x09, 0x02, 0x02, 0x04, 0x09, 0x02, 0x02, 0x08, 0x09, 0x02, 0x02, 0x0c, 0x09, 0x02, 0x02, 0x50, 0x23, 0x03, 0x03, 0x58, 0x23, 0x03, 0x03, 0x60, 0x23, 0x03, 0x03, 0x88, 0x03, 0x04, 0x03, + 0x90, 0x03, 0x04, 0x03, 0x40, 0x1b, 0x05, 0x04, 0x00, 0x3d, 0x06, 0x05, 0x40, 0x17, 0x07, 0x05, 0x80, 0x07, 0x0b, 0x07, 0xc8, 0x00, 0x00, 0x02, 0xcc, 0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x02, + 0xd4, 0x00, 0x00, 0x02, 0x4c, 0x2b, 0x01, 0x02, 0x50, 0x2b, 0x01, 0x02, 0x54, 0x2b, 0x01, 0x02, 0x58, 0x2b, 0x01, 0x02, 0x5c, 0x2b, 0x01, 0x02, 0x60, 0x2b, 0x01, 0x02, 0x10, 0x09, 0x02, 0x02, + 0x14, 0x09, 0x02, 0x02, 0x18, 0x09, 0x02, 0x02, 0x1c, 0x09, 0x02, 0x02, 0x20, 0x09, 0x02, 0x02, 0x68, 0x23, 0x03, 0x03, 0x70, 0x23, 0x03, 0x03, 0x78, 0x23, 0x03, 0x03, 0x98, 0x03, 0x04, 0x03, + 0xa0, 0x03, 0x04, 0x03, 0x50, 0x1b, 0x05, 0x04, 0x20, 0x3d, 0x06, 0x05, 0xc0, 0x30, 0x08, 0x06, 0x00, 0x08, 0x0b, 0x07, 0xd8, 0x00, 0x00, 0x02, 0xdc, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, + 0xe4, 0x00, 0x00, 0x02, 0x64, 0x2b, 0x01, 0x02, 0x68, 0x2b, 0x01, 0x02, 0x6c, 0x2b, 0x01, 0x02, 0x70, 0x2b, 0x01, 0x02, 0x74, 0x2b, 0x01, 0x02, 0x78, 0x2b, 0x01, 0x02, 0x24, 0x09, 0x02, 0x02, + 0x28, 0x09, 0x02, 0x02, 0x2c, 0x09, 0x02, 0x02, 0x30, 0x09, 0x02, 0x02, 0x34, 0x09, 0x02, 0x02, 0x80, 0x23, 0x03, 0x03, 0x88, 0x23, 0x03, 0x03, 0x90, 0x23, 0x03, 0x03, 0xa8, 0x03, 0x04, 0x03, + 0xb0, 0x03, 0x04, 0x03, 0x60, 0x1b, 0x05, 0x04, 0x40, 0x3d, 0x06, 0x05, 0x00, 0x31, 0x08, 0x06, 0x80, 0x08, 0x0b, 0x07, 0xe8, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x02, 0xf0, 0x00, 0x00, 0x02, + 0xf4, 0x00, 0x00, 0x02, 0x7c, 0x2b, 0x01, 0x02, 0x80, 0x2b, 0x01, 0x02, 0x84, 0x2b, 0x01, 0x02, 0x88, 0x2b, 0x01, 0x02, 0x8c, 0x2b, 0x01, 0x02, 0x90, 0x2b, 0x01, 0x02, 0x38, 0x09, 0x02, 0x02, + 0x3c, 0x09, 0x02, 0x02, 0x40, 0x09, 0x02, 0x02, 0x44, 0x09, 0x02, 0x02, 0x48, 0x09, 0x02, 0x02, 0x98, 0x23, 0x03, 0x03, 0xa0, 0x23, 0x03, 0x03, 0xb8, 0x03, 0x04, 0x03, 0xc0, 0x03, 0x04, 0x03, + 0xc8, 0x03, 0x04, 0x03, 0x70, 0x1b, 0x05, 0x04, 0x60, 0x3d, 0x06, 0x05, 0x40, 0x31, 0x08, 0x06, 0x00, 0x09, 0x0b, 0x07, 0xf8, 0x00, 0x00, 0x02, 0xfc, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, + 0x04, 0x01, 0x00, 0x02, 0x94, 0x2b, 0x01, 0x02, 0x98, 0x2b, 0x01, 0x02, 0x9c, 0x2b, 0x01, 0x02, 0xa0, 0x2b, 0x01, 0x02, 0xa4, 0x2b, 0x01, 0x02, 0xa8, 0x2b, 0x01, 0x02, 0x4c, 0x09, 0x02, 0x02, + 0x50, 0x09, 0x02, 0x02, 0x54, 0x09, 0x02, 0x02, 0x58, 0x09, 0x02, 0x02, 0xa8, 0x23, 0x03, 0x03, 0xb0, 0x23, 0x03, 0x03, 0xb8, 0x23, 0x03, 0x03, 0xd0, 0x03, 0x04, 0x03, 0xd8, 0x03, 0x04, 0x03, + 0xe0, 0x03, 0x04, 0x03, 0x80, 0x1b, 0x05, 0x04, 0x80, 0x3d, 0x06, 0x05, 0x80, 0x31, 0x08, 0x06, 0x80, 0x09, 0x0b, 0x07, 0x08, 0x01, 0x00, 0x02, 0x0c, 0x01, 0x00, 0x02, 0x10, 0x01, 0x00, 0x02, + 0x14, 0x01, 0x00, 0x02, 0xac, 0x2b, 0x01, 0x02, 0xb0, 0x2b, 0x01, 0x02, 0xb4, 0x2b, 0x01, 0x02, 0xb8, 0x2b, 0x01, 0x02, 0xbc, 0x2b, 0x01, 0x02, 0xc0, 0x2b, 0x01, 0x02, 0x5c, 0x09, 0x02, 0x02, + 0x60, 0x09, 0x02, 0x02, 0x64, 0x09, 0x02, 0x02, 0x68, 0x09, 0x02, 0x02, 0xc0, 0x23, 0x03, 0x03, 0xc8, 0x23, 0x03, 0x03, 0xd0, 0x23, 0x03, 0x03, 0xe8, 0x03, 0x04, 0x03, 0xf0, 0x03, 0x04, 0x03, + 0x90, 0x1b, 0x05, 0x04, 0xa0, 0x1b, 0x05, 0x04, 0xa0, 0x3d, 0x06, 0x05, 0xc0, 0x31, 0x08, 0x06, 0x00, 0x0a, 0x0b, 0x07, 0x18, 0x01, 0x00, 0x02, 0x1c, 0x01, 0x00, 0x02, 0x20, 0x01, 0x00, 0x02, + 0x24, 0x01, 0x00, 0x02, 0xc4, 0x2b, 0x01, 0x02, 0xc8, 0x2b, 0x01, 0x02, 0xcc, 0x2b, 0x01, 0x02, 0xd0, 0x2b, 0x01, 0x02, 0xd4, 0x2b, 0x01, 0x02, 0xd8, 0x2b, 0x01, 0x02, 0x6c, 0x09, 0x02, 0x02, + 0x70, 0x09, 0x02, 0x02, 0x74, 0x09, 0x02, 0x02, 0x78, 0x09, 0x02, 0x02, 0xd8, 0x23, 0x03, 0x03, 0xe0, 0x23, 0x03, 0x03, 0xe8, 0x23, 0x03, 0x03, 0xf8, 0x03, 0x04, 0x03, 0x00, 0x04, 0x04, 0x03, + 0xb0, 0x1b, 0x05, 0x04, 0xc0, 0x1b, 0x05, 0x04, 0xc0, 0x3d, 0x06, 0x05, 0x00, 0x32, 0x08, 0x06, 0x80, 0x0a, 0x0b, 0x07, 0x28, 0x01, 0x00, 0x02, 0x2c, 0x01, 0x00, 0x02, 0x30, 0x01, 0x00, 0x02, + 0x34, 0x01, 0x00, 0x02, 0xdc, 0x2b, 0x01, 0x02, 0xe0, 0x2b, 0x01, 0x02, 0xe4, 0x2b, 0x01, 0x02, 0xe8, 0x2b, 0x01, 0x02, 0xec, 0x2b, 0x01, 0x02, 0xf0, 0x2b, 0x01, 0x02, 0x7c, 0x09, 0x02, 0x02, + 0x80, 0x09, 0x02, 0x02, 0x84, 0x09, 0x02, 0x02, 0x88, 0x09, 0x02, 0x02, 0xf0, 0x23, 0x03, 0x03, 0xf8, 0x23, 0x03, 0x03, 0x00, 0x24, 0x03, 0x03, 0x08, 0x04, 0x04, 0x03, 0x10, 0x04, 0x04, 0x03, + 0xd0, 0x1b, 0x05, 0x04, 0xe0, 0x1b, 0x05, 0x04, 0xe0, 0x3d, 0x06, 0x05, 0x40, 0x32, 0x08, 0x06, 0x00, 0x1e, 0x0c, 0x08, 0x38, 0x01, 0x00, 0x02, 0x3c, 0x01, 0x00, 0x02, 0x40, 0x01, 0x00, 0x02, + 0x44, 0x01, 0x00, 0x02, 0xf4, 0x2b, 0x01, 0x02, 0xf8, 0x2b, 0x01, 0x02, 0xfc, 0x2b, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x04, 0x2c, 0x01, 0x02, 0x08, 0x2c, 0x01, 0x02, 0x8c, 0x09, 0x02, 0x02, + 0x90, 0x09, 0x02, 0x02, 0x94, 0x09, 0x02, 0x02, 0x98, 0x09, 0x02, 0x02, 0x08, 0x24, 0x03, 0x03, 0x10, 0x24, 0x03, 0x03, 0x18, 0x24, 0x03, 0x03, 0x18, 0x04, 0x04, 0x03, 0x20, 0x04, 0x04, 0x03, + 0xf0, 0x1b, 0x05, 0x04, 0x00, 0x1c, 0x05, 0x04, 0x00, 0x3e, 0x06, 0x05, 0x80, 0x32, 0x08, 0x06, 0x00, 0x1f, 0x0c, 0x08, 0x48, 0x01, 0x00, 0x02, 0x4c, 0x01, 0x00, 0x02, 0x50, 0x01, 0x00, 0x02, + 0x54, 0x01, 0x00, 0x02, 0x0c, 0x2c, 0x01, 0x02, 0x10, 0x2c, 0x01, 0x02, 0x14, 0x2c, 0x01, 0x02, 0x18, 0x2c, 0x01, 0x02, 0x1c, 0x2c, 0x01, 0x02, 0x20, 0x2c, 0x01, 0x02, 0x9c, 0x09, 0x02, 0x02, + 0xa0, 0x09, 0x02, 0x02, 0xa4, 0x09, 0x02, 0x02, 0xa8, 0x09, 0x02, 0x02, 0x20, 0x24, 0x03, 0x03, 0x28, 0x24, 0x03, 0x03, 0x30, 0x24, 0x03, 0x03, 0x28, 0x04, 0x04, 0x03, 0x30, 0x04, 0x04, 0x03, + 0x10, 0x1c, 0x05, 0x04, 0x20, 0x1c, 0x05, 0x04, 0x20, 0x3e, 0x06, 0x05, 0xc0, 0x32, 0x08, 0x06, 0x00, 0x20, 0x0c, 0x08, 0x58, 0x01, 0x00, 0x02, 0x5c, 0x01, 0x00, 0x02, 0x60, 0x01, 0x00, 0x02, + 0x64, 0x01, 0x00, 0x02, 0x24, 0x2c, 0x01, 0x02, 0x28, 0x2c, 0x01, 0x02, 0x2c, 0x2c, 0x01, 0x02, 0x30, 0x2c, 0x01, 0x02, 0x34, 0x2c, 0x01, 0x02, 0x38, 0x2c, 0x01, 0x02, 0xac, 0x09, 0x02, 0x02, + 0xb0, 0x09, 0x02, 0x02, 0xb4, 0x09, 0x02, 0x02, 0xb8, 0x09, 0x02, 0x02, 0x38, 0x24, 0x03, 0x03, 0x40, 0x24, 0x03, 0x03, 0x48, 0x24, 0x03, 0x03, 0x38, 0x04, 0x04, 0x03, 0x40, 0x04, 0x04, 0x03, + 0x30, 0x1c, 0x05, 0x04, 0x40, 0x1c, 0x05, 0x04, 0x40, 0x3e, 0x06, 0x05, 0x00, 0x33, 0x08, 0x06, 0x00, 0x21, 0x0c, 0x08, 0x68, 0x01, 0x00, 0x02, 0x6c, 0x01, 0x00, 0x02, 0x70, 0x01, 0x00, 0x02, + 0x74, 0x01, 0x00, 0x02, 0x3c, 0x2c, 0x01, 0x02, 0x40, 0x2c, 0x01, 0x02, 0x44, 0x2c, 0x01, 0x02, 0x48, 0x2c, 0x01, 0x02, 0x4c, 0x2c, 0x01, 0x02, 0x50, 0x2c, 0x01, 0x02, 0xbc, 0x09, 0x02, 0x02, + 0xc0, 0x09, 0x02, 0x02, 0xc4, 0x09, 0x02, 0x02, 0xc8, 0x09, 0x02, 0x02, 0x50, 0x24, 0x03, 0x03, 0x58, 0x24, 0x03, 0x03, 0x60, 0x24, 0x03, 0x03, 0x48, 0x04, 0x04, 0x03, 0x50, 0x04, 0x04, 0x03, + 0x50, 0x1c, 0x05, 0x04, 0x60, 0x1c, 0x05, 0x04, 0x60, 0x3e, 0x06, 0x05, 0x40, 0x33, 0x08, 0x06, 0x00, 0x22, 0x0c, 0x08, 0x78, 0x01, 0x00, 0x02, 0x7c, 0x01, 0x00, 0x02, 0x80, 0x01, 0x00, 0x02, + 0x84, 0x01, 0x00, 0x02, 0x54, 0x2c, 0x01, 0x02, 0x58, 0x2c, 0x01, 0x02, 0x5c, 0x2c, 0x01, 0x02, 0x60, 0x2c, 0x01, 0x02, 0x64, 0x2c, 0x01, 0x02, 0x68, 0x2c, 0x01, 0x02, 0xcc, 0x09, 0x02, 0x02, + 0xd0, 0x09, 0x02, 0x02, 0xd4, 0x09, 0x02, 0x02, 0xd8, 0x09, 0x02, 0x02, 0x68, 0x24, 0x03, 0x03, 0x70, 0x24, 0x03, 0x03, 0x78, 0x24, 0x03, 0x03, 0x58, 0x04, 0x04, 0x03, 0x60, 0x04, 0x04, 0x03, + 0x70, 0x1c, 0x05, 0x04, 0x80, 0x1c, 0x05, 0x04, 0x80, 0x3e, 0x06, 0x05, 0x80, 0x33, 0x08, 0x06, 0x00, 0x23, 0x0c, 0x08, 0x88, 0x01, 0x00, 0x02, 0x8c, 0x01, 0x00, 0x02, 0x90, 0x01, 0x00, 0x02, + 0x94, 0x01, 0x00, 0x02, 0x6c, 0x2c, 0x01, 0x02, 0x70, 0x2c, 0x01, 0x02, 0x74, 0x2c, 0x01, 0x02, 0x78, 0x2c, 0x01, 0x02, 0x7c, 0x2c, 0x01, 0x02, 0x80, 0x2c, 0x01, 0x02, 0xdc, 0x09, 0x02, 0x02, + 0xe0, 0x09, 0x02, 0x02, 0xe4, 0x09, 0x02, 0x02, 0xe8, 0x09, 0x02, 0x02, 0x80, 0x24, 0x03, 0x03, 0x88, 0x24, 0x03, 0x03, 0x90, 0x24, 0x03, 0x03, 0x68, 0x04, 0x04, 0x03, 0x70, 0x04, 0x04, 0x03, + 0x90, 0x1c, 0x05, 0x04, 0xa0, 0x1c, 0x05, 0x04, 0xa0, 0x3e, 0x06, 0x05, 0xc0, 0x33, 0x08, 0x06, 0x00, 0x24, 0x0c, 0x08, 0x98, 0x01, 0x00, 0x02, 0x9c, 0x01, 0x00, 0x02, 0xa0, 0x01, 0x00, 0x02, + 0xa4, 0x01, 0x00, 0x02, 0x84, 0x2c, 0x01, 0x02, 0x88, 0x2c, 0x01, 0x02, 0x8c, 0x2c, 0x01, 0x02, 0x90, 0x2c, 0x01, 0x02, 0x94, 0x2c, 0x01, 0x02, 0x98, 0x2c, 0x01, 0x02, 0xec, 0x09, 0x02, 0x02, + 0xf0, 0x09, 0x02, 0x02, 0xf4, 0x09, 0x02, 0x02, 0xf8, 0x09, 0x02, 0x02, 0x98, 0x24, 0x03, 0x03, 0xa0, 0x24, 0x03, 0x03, 0xa8, 0x24, 0x03, 0x03, 0x78, 0x04, 0x04, 0x03, 0x80, 0x04, 0x04, 0x03, + 0xb0, 0x1c, 0x05, 0x04, 0xc0, 0x1c, 0x05, 0x04, 0xc0, 0x3e, 0x06, 0x05, 0x00, 0x34, 0x08, 0x06, 0x00, 0x25, 0x0c, 0x08, 0xa8, 0x01, 0x00, 0x02, 0xac, 0x01, 0x00, 0x02, 0xb0, 0x01, 0x00, 0x02, + 0xb4, 0x01, 0x00, 0x02, 0x9c, 0x2c, 0x01, 0x02, 0xa0, 0x2c, 0x01, 0x02, 0xa4, 0x2c, 0x01, 0x02, 0xa8, 0x2c, 0x01, 0x02, 0xac, 0x2c, 0x01, 0x02, 0xb0, 0x2c, 0x01, 0x02, 0xfc, 0x09, 0x02, 0x02, + 0x00, 0x0a, 0x02, 0x02, 0x04, 0x0a, 0x02, 0x02, 0x08, 0x0a, 0x02, 0x02, 0xb0, 0x24, 0x03, 0x03, 0xb8, 0x24, 0x03, 0x03, 0xc0, 0x24, 0x03, 0x03, 0x88, 0x04, 0x04, 0x03, 0x90, 0x04, 0x04, 0x03, + 0xd0, 0x1c, 0x05, 0x04, 0xe0, 0x1c, 0x05, 0x04, 0xe0, 0x3e, 0x06, 0x05, 0x40, 0x34, 0x08, 0x06, 0x00, 0x01, 0x0d, 0x08, 0xb8, 0x01, 0x00, 0x02, 0xbc, 0x01, 0x00, 0x02, 0xc0, 0x01, 0x00, 0x02, + 0xc4, 0x01, 0x00, 0x02, 0xb4, 0x2c, 0x01, 0x02, 0xb8, 0x2c, 0x01, 0x02, 0xbc, 0x2c, 0x01, 0x02, 0xc0, 0x2c, 0x01, 0x02, 0xc4, 0x2c, 0x01, 0x02, 0xc8, 0x2c, 0x01, 0x02, 0x0c, 0x0a, 0x02, 0x02, + 0x10, 0x0a, 0x02, 0x02, 0x14, 0x0a, 0x02, 0x02, 0x18, 0x0a, 0x02, 0x02, 0xc8, 0x24, 0x03, 0x03, 0xd0, 0x24, 0x03, 0x03, 0xd8, 0x24, 0x03, 0x03, 0x98, 0x04, 0x04, 0x03, 0xa0, 0x04, 0x04, 0x03, + 0xf0, 0x1c, 0x05, 0x04, 0x00, 0x1d, 0x05, 0x04, 0x00, 0x3f, 0x06, 0x05, 0x80, 0x34, 0x08, 0x06, 0x00, 0x02, 0x0d, 0x08, 0xc8, 0x01, 0x00, 0x02, 0xcc, 0x01, 0x00, 0x02, 0xd0, 0x01, 0x00, 0x02, + 0xd4, 0x01, 0x00, 0x02, 0xcc, 0x2c, 0x01, 0x02, 0xd0, 0x2c, 0x01, 0x02, 0xd4, 0x2c, 0x01, 0x02, 0xd8, 0x2c, 0x01, 0x02, 0xdc, 0x2c, 0x01, 0x02, 0xe0, 0x2c, 0x01, 0x02, 0x1c, 0x0a, 0x02, 0x02, + 0x20, 0x0a, 0x02, 0x02, 0x24, 0x0a, 0x02, 0x02, 0x28, 0x0a, 0x02, 0x02, 0xe0, 0x24, 0x03, 0x03, 0xe8, 0x24, 0x03, 0x03, 0xf0, 0x24, 0x03, 0x03, 0xa8, 0x04, 0x04, 0x03, 0xb0, 0x04, 0x04, 0x03, + 0x10, 0x1d, 0x05, 0x04, 0x20, 0x1d, 0x05, 0x04, 0x20, 0x3f, 0x06, 0x05, 0xc0, 0x34, 0x08, 0x06, 0x00, 0x03, 0x0d, 0x08, 0xd8, 0x01, 0x00, 0x02, 0xdc, 0x01, 0x00, 0x02, 0xe0, 0x01, 0x00, 0x02, + 0xe4, 0x01, 0x00, 0x02, 0xe4, 0x2c, 0x01, 0x02, 0xe8, 0x2c, 0x01, 0x02, 0xec, 0x2c, 0x01, 0x02, 0xf0, 0x2c, 0x01, 0x02, 0xf4, 0x2c, 0x01, 0x02, 0xf8, 0x2c, 0x01, 0x02, 0x2c, 0x0a, 0x02, 0x02, + 0x30, 0x0a, 0x02, 0x02, 0x34, 0x0a, 0x02, 0x02, 0x38, 0x0a, 0x02, 0x02, 0xf8, 0x24, 0x03, 0x03, 0x00, 0x25, 0x03, 0x03, 0x08, 0x25, 0x03, 0x03, 0xb8, 0x04, 0x04, 0x03, 0xc0, 0x04, 0x04, 0x03, + 0x30, 0x1d, 0x05, 0x04, 0x40, 0x1d, 0x05, 0x04, 0x40, 0x3f, 0x06, 0x05, 0x00, 0x35, 0x08, 0x06, 0x00, 0x04, 0x0d, 0x08, 0xe8, 0x01, 0x00, 0x02, 0xec, 0x01, 0x00, 0x02, 0xf0, 0x01, 0x00, 0x02, + 0xf4, 0x01, 0x00, 0x02, 0xfc, 0x2c, 0x01, 0x02, 0x00, 0x2d, 0x01, 0x02, 0x04, 0x2d, 0x01, 0x02, 0x08, 0x2d, 0x01, 0x02, 0x0c, 0x2d, 0x01, 0x02, 0x10, 0x2d, 0x01, 0x02, 0x3c, 0x0a, 0x02, 0x02, + 0x40, 0x0a, 0x02, 0x02, 0x44, 0x0a, 0x02, 0x02, 0x48, 0x0a, 0x02, 0x02, 0x10, 0x25, 0x03, 0x03, 0x18, 0x25, 0x03, 0x03, 0x20, 0x25, 0x03, 0x03, 0xc8, 0x04, 0x04, 0x03, 0xd0, 0x04, 0x04, 0x03, + 0x50, 0x1d, 0x05, 0x04, 0x60, 0x1d, 0x05, 0x04, 0x60, 0x3f, 0x06, 0x05, 0x40, 0x35, 0x08, 0x06, 0x00, 0x05, 0x0d, 0x08, 0xf8, 0x01, 0x00, 0x02, 0xfc, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x04, 0x02, 0x00, 0x02, 0x14, 0x2d, 0x01, 0x02, 0x18, 0x2d, 0x01, 0x02, 0x1c, 0x2d, 0x01, 0x02, 0x20, 0x2d, 0x01, 0x02, 0x24, 0x2d, 0x01, 0x02, 0x28, 0x2d, 0x01, 0x02, 0x4c, 0x0a, 0x02, 0x02, + 0x50, 0x0a, 0x02, 0x02, 0x54, 0x0a, 0x02, 0x02, 0x58, 0x0a, 0x02, 0x02, 0x28, 0x25, 0x03, 0x03, 0x30, 0x25, 0x03, 0x03, 0x38, 0x25, 0x03, 0x03, 0xd8, 0x04, 0x04, 0x03, 0xe0, 0x04, 0x04, 0x03, + 0x70, 0x1d, 0x05, 0x04, 0x80, 0x1d, 0x05, 0x04, 0x80, 0x3f, 0x06, 0x05, 0x80, 0x35, 0x08, 0x06, 0x00, 0x18, 0x0e, 0x09, 0x08, 0x02, 0x00, 0x02, 0x0c, 0x02, 0x00, 0x02, 0x10, 0x02, 0x00, 0x02, + 0x14, 0x02, 0x00, 0x02, 0x2c, 0x2d, 0x01, 0x02, 0x30, 0x2d, 0x01, 0x02, 0x34, 0x2d, 0x01, 0x02, 0x38, 0x2d, 0x01, 0x02, 0x3c, 0x2d, 0x01, 0x02, 0x40, 0x2d, 0x01, 0x02, 0x5c, 0x0a, 0x02, 0x02, + 0x60, 0x0a, 0x02, 0x02, 0x64, 0x0a, 0x02, 0x02, 0x68, 0x0a, 0x02, 0x02, 0x40, 0x25, 0x03, 0x03, 0x48, 0x25, 0x03, 0x03, 0x50, 0x25, 0x03, 0x03, 0xe8, 0x04, 0x04, 0x03, 0xf0, 0x04, 0x04, 0x03, + 0x90, 0x1d, 0x05, 0x04, 0xa0, 0x1d, 0x05, 0x04, 0xa0, 0x3f, 0x06, 0x05, 0xc0, 0x35, 0x08, 0x06, 0x00, 0x1a, 0x0e, 0x09, 0x18, 0x02, 0x00, 0x02, 0x1c, 0x02, 0x00, 0x02, 0x20, 0x02, 0x00, 0x02, + 0x44, 0x2d, 0x01, 0x02, 0x48, 0x2d, 0x01, 0x02, 0x4c, 0x2d, 0x01, 0x02, 0x50, 0x2d, 0x01, 0x02, 0x54, 0x2d, 0x01, 0x02, 0x58, 0x2d, 0x01, 0x02, 0x5c, 0x2d, 0x01, 0x02, 0x6c, 0x0a, 0x02, 0x02, + 0x70, 0x0a, 0x02, 0x02, 0x74, 0x0a, 0x02, 0x02, 0x78, 0x0a, 0x02, 0x02, 0x58, 0x25, 0x03, 0x03, 0x60, 0x25, 0x03, 0x03, 0x68, 0x25, 0x03, 0x03, 0xf8, 0x04, 0x04, 0x03, 0x00, 0x05, 0x04, 0x03, + 0xb0, 0x1d, 0x05, 0x04, 0xc0, 0x1d, 0x05, 0x04, 0xc0, 0x3f, 0x06, 0x05, 0x00, 0x36, 0x08, 0x06, 0x00, 0x1c, 0x0e, 0x09, 0x24, 0x02, 0x00, 0x02, 0x28, 0x02, 0x00, 0x02, 0x2c, 0x02, 0x00, 0x02, + 0x60, 0x2d, 0x01, 0x02, 0x64, 0x2d, 0x01, 0x02, 0x68, 0x2d, 0x01, 0x02, 0x6c, 0x2d, 0x01, 0x02, 0x70, 0x2d, 0x01, 0x02, 0x74, 0x2d, 0x01, 0x02, 0x78, 0x2d, 0x01, 0x02, 0x7c, 0x0a, 0x02, 0x02, + 0x80, 0x0a, 0x02, 0x02, 0x84, 0x0a, 0x02, 0x02, 0x88, 0x0a, 0x02, 0x02, 0x70, 0x25, 0x03, 0x03, 0x78, 0x25, 0x03, 0x03, 0x80, 0x25, 0x03, 0x03, 0x08, 0x05, 0x04, 0x03, 0x10, 0x05, 0x04, 0x03, + 0xd0, 0x1d, 0x05, 0x04, 0xe0, 0x1d, 0x05, 0x04, 0xe0, 0x3f, 0x06, 0x05, 0x40, 0x36, 0x08, 0x06, 0x00, 0x1e, 0x0e, 0x09, 0x30, 0x02, 0x00, 0x02, 0x34, 0x02, 0x00, 0x02, 0x38, 0x02, 0x00, 0x02, + 0x7c, 0x2d, 0x01, 0x02, 0x80, 0x2d, 0x01, 0x02, 0x84, 0x2d, 0x01, 0x02, 0x88, 0x2d, 0x01, 0x02, 0x8c, 0x2d, 0x01, 0x02, 0x90, 0x2d, 0x01, 0x02, 0x94, 0x2d, 0x01, 0x02, 0x8c, 0x0a, 0x02, 0x02, + 0x90, 0x0a, 0x02, 0x02, 0x94, 0x0a, 0x02, 0x02, 0x98, 0x0a, 0x02, 0x02, 0x88, 0x25, 0x03, 0x03, 0x90, 0x25, 0x03, 0x03, 0x98, 0x25, 0x03, 0x03, 0x18, 0x05, 0x04, 0x03, 0x20, 0x05, 0x04, 0x03, + 0xf0, 0x1d, 0x05, 0x04, 0x00, 0x1e, 0x05, 0x04, 0x00, 0x00, 0x06, 0x04, 0x80, 0x36, 0x08, 0x06, 0x00, 0x3c, 0x0f, 0x0a, 0x3c, 0x02, 0x00, 0x02, 0x40, 0x02, 0x00, 0x02, 0x44, 0x02, 0x00, 0x02, + 0x98, 0x2d, 0x01, 0x02, 0x9c, 0x2d, 0x01, 0x02, 0xa0, 0x2d, 0x01, 0x02, 0xa4, 0x2d, 0x01, 0x02, 0xa8, 0x2d, 0x01, 0x02, 0xac, 0x2d, 0x01, 0x02, 0xb0, 0x2d, 0x01, 0x02, 0x9c, 0x0a, 0x02, 0x02, + 0xa0, 0x0a, 0x02, 0x02, 0xa4, 0x0a, 0x02, 0x02, 0xa8, 0x0a, 0x02, 0x02, 0xa0, 0x25, 0x03, 0x03, 0xa8, 0x25, 0x03, 0x03, 0xb0, 0x25, 0x03, 0x03, 0x28, 0x05, 0x04, 0x03, 0x30, 0x05, 0x04, 0x03, + 0x10, 0x1e, 0x05, 0x04, 0x20, 0x1e, 0x05, 0x04, 0x10, 0x00, 0x06, 0x04, 0xc0, 0x36, 0x08, 0x06, 0x00, 0x00, 0x0f, 0x09, 0x48, 0x02, 0x00, 0x02, 0x4c, 0x02, 0x00, 0x02, 0x50, 0x02, 0x00, 0x02, + 0xb4, 0x2d, 0x01, 0x02, 0xb8, 0x2d, 0x01, 0x02, 0xbc, 0x2d, 0x01, 0x02, 0xc0, 0x2d, 0x01, 0x02, 0xc4, 0x2d, 0x01, 0x02, 0xc8, 0x2d, 0x01, 0x02, 0xcc, 0x2d, 0x01, 0x02, 0xac, 0x0a, 0x02, 0x02, + 0xb0, 0x0a, 0x02, 0x02, 0xb4, 0x0a, 0x02, 0x02, 0xb8, 0x0a, 0x02, 0x02, 0xb8, 0x25, 0x03, 0x03, 0xc0, 0x25, 0x03, 0x03, 0xc8, 0x25, 0x03, 0x03, 0x38, 0x05, 0x04, 0x03, 0x40, 0x05, 0x04, 0x03, + 0x30, 0x1e, 0x05, 0x04, 0x40, 0x1e, 0x05, 0x04, 0x20, 0x00, 0x06, 0x04, 0x00, 0x37, 0x08, 0x06, 0x00, 0x02, 0x0f, 0x09, 0x54, 0x02, 0x00, 0x02, 0x58, 0x02, 0x00, 0x02, 0x5c, 0x02, 0x00, 0x02, + 0xd0, 0x2d, 0x01, 0x02, 0xd4, 0x2d, 0x01, 0x02, 0xd8, 0x2d, 0x01, 0x02, 0xdc, 0x2d, 0x01, 0x02, 0xe0, 0x2d, 0x01, 0x02, 0xe4, 0x2d, 0x01, 0x02, 0xe8, 0x2d, 0x01, 0x02, 0xbc, 0x0a, 0x02, 0x02, + 0xc0, 0x0a, 0x02, 0x02, 0xc4, 0x0a, 0x02, 0x02, 0xc8, 0x0a, 0x02, 0x02, 0xd0, 0x25, 0x03, 0x03, 0xd8, 0x25, 0x03, 0x03, 0xe0, 0x25, 0x03, 0x03, 0x48, 0x05, 0x04, 0x03, 0x50, 0x05, 0x04, 0x03, + 0x50, 0x1e, 0x05, 0x04, 0x60, 0x1e, 0x05, 0x04, 0x30, 0x00, 0x06, 0x04, 0x40, 0x37, 0x08, 0x06, 0x00, 0x18, 0x10, 0x0a, 0x60, 0x02, 0x00, 0x02, 0x64, 0x02, 0x00, 0x02, 0x68, 0x02, 0x00, 0x02, + 0xec, 0x2d, 0x01, 0x02, 0xf0, 0x2d, 0x01, 0x02, 0xf4, 0x2d, 0x01, 0x02, 0xf8, 0x2d, 0x01, 0x02, 0xfc, 0x2d, 0x01, 0x02, 0x00, 0x2e, 0x01, 0x02, 0x04, 0x2e, 0x01, 0x02, 0xcc, 0x0a, 0x02, 0x02, + 0xd0, 0x0a, 0x02, 0x02, 0xd4, 0x0a, 0x02, 0x02, 0xd8, 0x0a, 0x02, 0x02, 0xe8, 0x25, 0x03, 0x03, 0xf0, 0x25, 0x03, 0x03, 0xf8, 0x25, 0x03, 0x03, 0x58, 0x05, 0x04, 0x03, 0x60, 0x05, 0x04, 0x03, + 0x70, 0x1e, 0x05, 0x04, 0x80, 0x1e, 0x05, 0x04, 0x40, 0x00, 0x06, 0x04, 0x80, 0x37, 0x08, 0x06, 0x00, 0x1c, 0x10, 0x0a, 0x6c, 0x02, 0x00, 0x02, 0x70, 0x02, 0x00, 0x02, 0x74, 0x02, 0x00, 0x02, + 0x08, 0x2e, 0x01, 0x02, 0x0c, 0x2e, 0x01, 0x02, 0x10, 0x2e, 0x01, 0x02, 0x14, 0x2e, 0x01, 0x02, 0x18, 0x2e, 0x01, 0x02, 0x1c, 0x2e, 0x01, 0x02, 0x20, 0x2e, 0x01, 0x02, 0xdc, 0x0a, 0x02, 0x02, + 0xe0, 0x0a, 0x02, 0x02, 0xe4, 0x0a, 0x02, 0x02, 0xe8, 0x0a, 0x02, 0x02, 0x00, 0x26, 0x03, 0x03, 0x08, 0x26, 0x03, 0x03, 0x10, 0x26, 0x03, 0x03, 0x68, 0x05, 0x04, 0x03, 0x70, 0x05, 0x04, 0x03, + 0x90, 0x1e, 0x05, 0x04, 0xa0, 0x1e, 0x05, 0x04, 0x50, 0x00, 0x06, 0x04, 0xc0, 0x37, 0x08, 0x06, 0x00, 0x30, 0x11, 0x0b, 0x78, 0x02, 0x00, 0x02, 0x7c, 0x02, 0x00, 0x02, 0x80, 0x02, 0x00, 0x02, + 0x24, 0x2e, 0x01, 0x02, 0x28, 0x2e, 0x01, 0x02, 0x2c, 0x2e, 0x01, 0x02, 0x30, 0x2e, 0x01, 0x02, 0x34, 0x2e, 0x01, 0x02, 0x38, 0x2e, 0x01, 0x02, 0x3c, 0x2e, 0x01, 0x02, 0xec, 0x0a, 0x02, 0x02, + 0xf0, 0x0a, 0x02, 0x02, 0xf4, 0x0a, 0x02, 0x02, 0xf8, 0x0a, 0x02, 0x02, 0x18, 0x26, 0x03, 0x03, 0x20, 0x26, 0x03, 0x03, 0x28, 0x26, 0x03, 0x03, 0x78, 0x05, 0x04, 0x03, 0x80, 0x05, 0x04, 0x03, + 0xb0, 0x1e, 0x05, 0x04, 0xc0, 0x1e, 0x05, 0x04, 0x60, 0x00, 0x06, 0x04, 0x00, 0x38, 0x08, 0x06, 0x00, 0x10, 0x12, 0x0b, 0x84, 0x02, 0x00, 0x02, 0x88, 0x02, 0x00, 0x02, 0x8c, 0x02, 0x00, 0x02, + 0x40, 0x2e, 0x01, 0x02, 0x44, 0x2e, 0x01, 0x02, 0x48, 0x2e, 0x01, 0x02, 0x4c, 0x2e, 0x01, 0x02, 0x50, 0x2e, 0x01, 0x02, 0x54, 0x2e, 0x01, 0x02, 0x58, 0x2e, 0x01, 0x02, 0xfc, 0x0a, 0x02, 0x02, + 0x00, 0x0b, 0x02, 0x02, 0x04, 0x0b, 0x02, 0x02, 0x08, 0x0b, 0x02, 0x02, 0x30, 0x26, 0x03, 0x03, 0x38, 0x26, 0x03, 0x03, 0x40, 0x26, 0x03, 0x03, 0x88, 0x05, 0x04, 0x03, 0x90, 0x05, 0x04, 0x03, + 0xd0, 0x1e, 0x05, 0x04, 0xe0, 0x1e, 0x05, 0x04, 0x70, 0x00, 0x06, 0x04, 0x40, 0x38, 0x08, 0x06, 0x00, 0x20, 0x13, 0x0c, 0x90, 0x02, 0x00, 0x02, 0x94, 0x02, 0x00, 0x02, 0x98, 0x02, 0x00, 0x02, + 0x5c, 0x2e, 0x01, 0x02, 0x60, 0x2e, 0x01, 0x02, 0x64, 0x2e, 0x01, 0x02, 0x68, 0x2e, 0x01, 0x02, 0x6c, 0x2e, 0x01, 0x02, 0x70, 0x2e, 0x01, 0x02, 0x74, 0x2e, 0x01, 0x02, 0x0c, 0x0b, 0x02, 0x02, + 0x10, 0x0b, 0x02, 0x02, 0x14, 0x0b, 0x02, 0x02, 0x18, 0x0b, 0x02, 0x02, 0x48, 0x26, 0x03, 0x03, 0x50, 0x26, 0x03, 0x03, 0x58, 0x26, 0x03, 0x03, 0x98, 0x05, 0x04, 0x03, 0xa0, 0x05, 0x04, 0x03, + 0xf0, 0x1e, 0x05, 0x04, 0x00, 0x1f, 0x05, 0x04, 0x80, 0x00, 0x06, 0x04, 0x80, 0x38, 0x08, 0x06, 0x9c, 0x02, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x02, 0xa4, 0x02, 0x00, 0x02, 0xa8, 0x02, 0x00, 0x02, + 0x78, 0x2e, 0x01, 0x02, 0x7c, 0x2e, 0x01, 0x02, 0x80, 0x2e, 0x01, 0x02, 0x84, 0x2e, 0x01, 0x02, 0x88, 0x2e, 0x01, 0x02, 0x8c, 0x2e, 0x01, 0x02, 0x90, 0x2e, 0x01, 0x02, 0x1c, 0x0b, 0x02, 0x02, + 0x20, 0x0b, 0x02, 0x02, 0x24, 0x0b, 0x02, 0x02, 0x28, 0x0b, 0x02, 0x02, 0x60, 0x26, 0x03, 0x03, 0x68, 0x26, 0x03, 0x03, 0x70, 0x26, 0x03, 0x03, 0xa8, 0x05, 0x04, 0x03, 0xb0, 0x05, 0x04, 0x03, + 0x10, 0x1f, 0x05, 0x04, 0x20, 0x1f, 0x05, 0x04, 0x60, 0x17, 0x07, 0x05, 0xc0, 0x38, 0x08, 0x06, 0xac, 0x02, 0x00, 0x02, 0xb0, 0x02, 0x00, 0x02, 0xb4, 0x02, 0x00, 0x02, 0xb8, 0x02, 0x00, 0x02, + 0x94, 0x2e, 0x01, 0x02, 0x98, 0x2e, 0x01, 0x02, 0x9c, 0x2e, 0x01, 0x02, 0xa0, 0x2e, 0x01, 0x02, 0xa4, 0x2e, 0x01, 0x02, 0xa8, 0x2e, 0x01, 0x02, 0xac, 0x2e, 0x01, 0x02, 0x2c, 0x0b, 0x02, 0x02, + 0x30, 0x0b, 0x02, 0x02, 0x34, 0x0b, 0x02, 0x02, 0x38, 0x0b, 0x02, 0x02, 0x78, 0x26, 0x03, 0x03, 0x80, 0x26, 0x03, 0x03, 0x88, 0x26, 0x03, 0x03, 0xb8, 0x05, 0x04, 0x03, 0xc0, 0x05, 0x04, 0x03, + 0x30, 0x1f, 0x05, 0x04, 0x40, 0x1f, 0x05, 0x04, 0x80, 0x17, 0x07, 0x05, 0x00, 0x39, 0x08, 0x06, 0xbc, 0x02, 0x00, 0x02, 0xc0, 0x02, 0x00, 0x02, 0xc4, 0x02, 0x00, 0x02, 0xc8, 0x02, 0x00, 0x02, + 0xb0, 0x2e, 0x01, 0x02, 0xb4, 0x2e, 0x01, 0x02, 0xb8, 0x2e, 0x01, 0x02, 0xbc, 0x2e, 0x01, 0x02, 0xc0, 0x2e, 0x01, 0x02, 0xc4, 0x2e, 0x01, 0x02, 0xc8, 0x2e, 0x01, 0x02, 0x3c, 0x0b, 0x02, 0x02, + 0x40, 0x0b, 0x02, 0x02, 0x44, 0x0b, 0x02, 0x02, 0x48, 0x0b, 0x02, 0x02, 0x90, 0x26, 0x03, 0x03, 0x98, 0x26, 0x03, 0x03, 0xa0, 0x26, 0x03, 0x03, 0xc8, 0x05, 0x04, 0x03, 0xd0, 0x05, 0x04, 0x03, + 0x50, 0x1f, 0x05, 0x04, 0x60, 0x1f, 0x05, 0x04, 0xa0, 0x17, 0x07, 0x05, 0x40, 0x39, 0x08, 0x06, 0xcc, 0x02, 0x00, 0x02, 0xd0, 0x02, 0x00, 0x02, 0xd4, 0x02, 0x00, 0x02, 0xd8, 0x02, 0x00, 0x02, + 0xcc, 0x2e, 0x01, 0x02, 0xd0, 0x2e, 0x01, 0x02, 0xd4, 0x2e, 0x01, 0x02, 0xd8, 0x2e, 0x01, 0x02, 0xdc, 0x2e, 0x01, 0x02, 0xe0, 0x2e, 0x01, 0x02, 0xe4, 0x2e, 0x01, 0x02, 0x4c, 0x0b, 0x02, 0x02, + 0x50, 0x0b, 0x02, 0x02, 0x54, 0x0b, 0x02, 0x02, 0x58, 0x0b, 0x02, 0x02, 0xa8, 0x26, 0x03, 0x03, 0xb0, 0x26, 0x03, 0x03, 0xb8, 0x26, 0x03, 0x03, 0xd8, 0x05, 0x04, 0x03, 0xe0, 0x05, 0x04, 0x03, + 0x70, 0x1f, 0x05, 0x04, 0x80, 0x1f, 0x05, 0x04, 0xc0, 0x17, 0x07, 0x05, 0x80, 0x39, 0x08, 0x06, 0xdc, 0x02, 0x00, 0x02, 0xe0, 0x02, 0x00, 0x02, 0xe4, 0x02, 0x00, 0x02, 0xe8, 0x02, 0x00, 0x02, + 0xe8, 0x2e, 0x01, 0x02, 0xec, 0x2e, 0x01, 0x02, 0xf0, 0x2e, 0x01, 0x02, 0xf4, 0x2e, 0x01, 0x02, 0xf8, 0x2e, 0x01, 0x02, 0xfc, 0x2e, 0x01, 0x02, 0x00, 0x2f, 0x01, 0x02, 0x5c, 0x0b, 0x02, 0x02, + 0x60, 0x0b, 0x02, 0x02, 0x64, 0x0b, 0x02, 0x02, 0x68, 0x0b, 0x02, 0x02, 0xc0, 0x26, 0x03, 0x03, 0xc8, 0x26, 0x03, 0x03, 0xd0, 0x26, 0x03, 0x03, 0xe8, 0x05, 0x04, 0x03, 0xf0, 0x05, 0x04, 0x03, + 0x90, 0x1f, 0x05, 0x04, 0xa0, 0x1f, 0x05, 0x04, 0xe0, 0x17, 0x07, 0x05, 0xc0, 0x39, 0x08, 0x06, 0xec, 0x02, 0x00, 0x02, 0xf0, 0x02, 0x00, 0x02, 0xf4, 0x02, 0x00, 0x02, 0xf8, 0x02, 0x00, 0x02, + 0x04, 0x2f, 0x01, 0x02, 0x08, 0x2f, 0x01, 0x02, 0x0c, 0x2f, 0x01, 0x02, 0x10, 0x2f, 0x01, 0x02, 0x14, 0x2f, 0x01, 0x02, 0x18, 0x2f, 0x01, 0x02, 0x1c, 0x2f, 0x01, 0x02, 0x6c, 0x0b, 0x02, 0x02, + 0x70, 0x0b, 0x02, 0x02, 0x74, 0x0b, 0x02, 0x02, 0x78, 0x0b, 0x02, 0x02, 0xd8, 0x26, 0x03, 0x03, 0xe0, 0x26, 0x03, 0x03, 0xe8, 0x26, 0x03, 0x03, 0xf8, 0x05, 0x04, 0x03, 0x00, 0x06, 0x04, 0x03, + 0xb0, 0x1f, 0x05, 0x04, 0x90, 0x00, 0x06, 0x04, 0x00, 0x18, 0x07, 0x05, 0x00, 0x3a, 0x08, 0x06, 0xfc, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x04, 0x03, 0x00, 0x02, 0x08, 0x03, 0x00, 0x02, + 0x20, 0x2f, 0x01, 0x02, 0x24, 0x2f, 0x01, 0x02, 0x28, 0x2f, 0x01, 0x02, 0x2c, 0x2f, 0x01, 0x02, 0x30, 0x2f, 0x01, 0x02, 0x34, 0x2f, 0x01, 0x02, 0x38, 0x2f, 0x01, 0x02, 0x7c, 0x0b, 0x02, 0x02, + 0x80, 0x0b, 0x02, 0x02, 0x84, 0x0b, 0x02, 0x02, 0x88, 0x0b, 0x02, 0x02, 0xf0, 0x26, 0x03, 0x03, 0xf8, 0x26, 0x03, 0x03, 0x00, 0x27, 0x03, 0x03, 0x08, 0x06, 0x04, 0x03, 0x10, 0x06, 0x04, 0x03, + 0xc0, 0x1f, 0x05, 0x04, 0xa0, 0x00, 0x06, 0x04, 0x20, 0x18, 0x07, 0x05, 0xc0, 0x10, 0x09, 0x06, 0x0c, 0x03, 0x00, 0x02, 0x10, 0x03, 0x00, 0x02, 0x14, 0x03, 0x00, 0x02, 0x18, 0x03, 0x00, 0x02, + 0x3c, 0x2f, 0x01, 0x02, 0x40, 0x2f, 0x01, 0x02, 0x44, 0x2f, 0x01, 0x02, 0x48, 0x2f, 0x01, 0x02, 0x4c, 0x2f, 0x01, 0x02, 0x50, 0x2f, 0x01, 0x02, 0x54, 0x2f, 0x01, 0x02, 0x8c, 0x0b, 0x02, 0x02, + 0x90, 0x0b, 0x02, 0x02, 0x94, 0x0b, 0x02, 0x02, 0x98, 0x0b, 0x02, 0x02, 0x08, 0x27, 0x03, 0x03, 0x10, 0x27, 0x03, 0x03, 0x18, 0x27, 0x03, 0x03, 0x18, 0x06, 0x04, 0x03, 0x20, 0x06, 0x04, 0x03, + 0xd0, 0x1f, 0x05, 0x04, 0xb0, 0x00, 0x06, 0x04, 0x40, 0x18, 0x07, 0x05, 0x00, 0x11, 0x09, 0x06, 0x1c, 0x03, 0x00, 0x02, 0x20, 0x03, 0x00, 0x02, 0x24, 0x03, 0x00, 0x02, 0x28, 0x03, 0x00, 0x02, + 0x58, 0x2f, 0x01, 0x02, 0x5c, 0x2f, 0x01, 0x02, 0x60, 0x2f, 0x01, 0x02, 0x64, 0x2f, 0x01, 0x02, 0x68, 0x2f, 0x01, 0x02, 0x6c, 0x2f, 0x01, 0x02, 0x70, 0x2f, 0x01, 0x02, 0x9c, 0x0b, 0x02, 0x02, + 0xa0, 0x0b, 0x02, 0x02, 0xa4, 0x0b, 0x02, 0x02, 0xa8, 0x0b, 0x02, 0x02, 0x20, 0x27, 0x03, 0x03, 0x28, 0x27, 0x03, 0x03, 0x30, 0x27, 0x03, 0x03, 0x28, 0x06, 0x04, 0x03, 0x30, 0x06, 0x04, 0x03, + 0xe0, 0x1f, 0x05, 0x04, 0xc0, 0x00, 0x06, 0x04, 0x60, 0x18, 0x07, 0x05, 0x40, 0x11, 0x09, 0x06, 0x2c, 0x03, 0x00, 0x02, 0x30, 0x03, 0x00, 0x02, 0x34, 0x03, 0x00, 0x02, 0x38, 0x03, 0x00, 0x02, + 0x74, 0x2f, 0x01, 0x02, 0x78, 0x2f, 0x01, 0x02, 0x7c, 0x2f, 0x01, 0x02, 0x80, 0x2f, 0x01, 0x02, 0x84, 0x2f, 0x01, 0x02, 0x88, 0x2f, 0x01, 0x02, 0x8c, 0x2f, 0x01, 0x02, 0xac, 0x0b, 0x02, 0x02, + 0xb0, 0x0b, 0x02, 0x02, 0xb4, 0x0b, 0x02, 0x02, 0xb8, 0x0b, 0x02, 0x02, 0x38, 0x27, 0x03, 0x03, 0x40, 0x27, 0x03, 0x03, 0x48, 0x27, 0x03, 0x03, 0x38, 0x06, 0x04, 0x03, 0x40, 0x06, 0x04, 0x03, + 0xf0, 0x1f, 0x05, 0x04, 0xd0, 0x00, 0x06, 0x04, 0x80, 0x18, 0x07, 0x05, 0x80, 0x11, 0x09, 0x06, 0x3c, 0x03, 0x00, 0x02, 0x40, 0x03, 0x00, 0x02, 0x44, 0x03, 0x00, 0x02, 0x48, 0x03, 0x00, 0x02, + 0x90, 0x2f, 0x01, 0x02, 0x94, 0x2f, 0x01, 0x02, 0x98, 0x2f, 0x01, 0x02, 0x9c, 0x2f, 0x01, 0x02, 0xa0, 0x2f, 0x01, 0x02, 0xa4, 0x2f, 0x01, 0x02, 0xa8, 0x2f, 0x01, 0x02, 0xbc, 0x0b, 0x02, 0x02, + 0xc0, 0x0b, 0x02, 0x02, 0xc4, 0x0b, 0x02, 0x02, 0xc8, 0x0b, 0x02, 0x02, 0x50, 0x27, 0x03, 0x03, 0x58, 0x27, 0x03, 0x03, 0x60, 0x27, 0x03, 0x03, 0x48, 0x06, 0x04, 0x03, 0x50, 0x06, 0x04, 0x03, + 0x00, 0x20, 0x05, 0x04, 0xe0, 0x00, 0x06, 0x04, 0xa0, 0x18, 0x07, 0x05, 0xc0, 0x11, 0x09, 0x06, 0x4c, 0x03, 0x00, 0x02, 0x50, 0x03, 0x00, 0x02, 0x54, 0x03, 0x00, 0x02, 0x58, 0x03, 0x00, 0x02, + 0xac, 0x2f, 0x01, 0x02, 0xb0, 0x2f, 0x01, 0x02, 0xb4, 0x2f, 0x01, 0x02, 0xb8, 0x2f, 0x01, 0x02, 0xbc, 0x2f, 0x01, 0x02, 0xc0, 0x2f, 0x01, 0x02, 0xc4, 0x2f, 0x01, 0x02, 0xcc, 0x0b, 0x02, 0x02, + 0xd0, 0x0b, 0x02, 0x02, 0xd4, 0x0b, 0x02, 0x02, 0xd8, 0x0b, 0x02, 0x02, 0x68, 0x27, 0x03, 0x03, 0x70, 0x27, 0x03, 0x03, 0x78, 0x27, 0x03, 0x03, 0x58, 0x06, 0x04, 0x03, 0x60, 0x06, 0x04, 0x03, + 0x10, 0x20, 0x05, 0x04, 0xf0, 0x00, 0x06, 0x04, 0xc0, 0x18, 0x07, 0x05, 0x00, 0x12, 0x09, 0x06, 0x5c, 0x03, 0x00, 0x02, 0x60, 0x03, 0x00, 0x02, 0x64, 0x03, 0x00, 0x02, 0x68, 0x03, 0x00, 0x02, + 0xc8, 0x2f, 0x01, 0x02, 0xcc, 0x2f, 0x01, 0x02, 0xd0, 0x2f, 0x01, 0x02, 0xd4, 0x2f, 0x01, 0x02, 0xd8, 0x2f, 0x01, 0x02, 0xdc, 0x2f, 0x01, 0x02, 0xe0, 0x2f, 0x01, 0x02, 0xdc, 0x0b, 0x02, 0x02, + 0xe0, 0x0b, 0x02, 0x02, 0xe4, 0x0b, 0x02, 0x02, 0xe8, 0x0b, 0x02, 0x02, 0x80, 0x27, 0x03, 0x03, 0x88, 0x27, 0x03, 0x03, 0x90, 0x27, 0x03, 0x03, 0x68, 0x06, 0x04, 0x03, 0x70, 0x06, 0x04, 0x03, + 0x20, 0x20, 0x05, 0x04, 0x00, 0x01, 0x06, 0x04, 0xe0, 0x18, 0x07, 0x05, 0x40, 0x12, 0x09, 0x06, 0x6c, 0x03, 0x00, 0x02, 0x70, 0x03, 0x00, 0x02, 0x74, 0x03, 0x00, 0x02, 0x78, 0x03, 0x00, 0x02, + 0xe4, 0x2f, 0x01, 0x02, 0xe8, 0x2f, 0x01, 0x02, 0xec, 0x2f, 0x01, 0x02, 0xf0, 0x2f, 0x01, 0x02, 0xf4, 0x2f, 0x01, 0x02, 0xf8, 0x2f, 0x01, 0x02, 0xfc, 0x2f, 0x01, 0x02, 0xec, 0x0b, 0x02, 0x02, + 0xf0, 0x0b, 0x02, 0x02, 0xf4, 0x0b, 0x02, 0x02, 0xf8, 0x0b, 0x02, 0x02, 0x98, 0x27, 0x03, 0x03, 0xa0, 0x27, 0x03, 0x03, 0xa8, 0x27, 0x03, 0x03, 0x78, 0x06, 0x04, 0x03, 0x80, 0x06, 0x04, 0x03, + 0x30, 0x20, 0x05, 0x04, 0x10, 0x01, 0x06, 0x04, 0x00, 0x19, 0x07, 0x05, 0x80, 0x12, 0x09, 0x06, 0x7c, 0x03, 0x00, 0x02, 0x80, 0x03, 0x00, 0x02, 0x84, 0x03, 0x00, 0x02, 0x88, 0x03, 0x00, 0x02, + 0x00, 0x30, 0x01, 0x02, 0x04, 0x30, 0x01, 0x02, 0x08, 0x30, 0x01, 0x02, 0x0c, 0x30, 0x01, 0x02, 0x10, 0x30, 0x01, 0x02, 0x14, 0x30, 0x01, 0x02, 0x18, 0x30, 0x01, 0x02, 0xfc, 0x0b, 0x02, 0x02, + 0x00, 0x0c, 0x02, 0x02, 0x04, 0x0c, 0x02, 0x02, 0x08, 0x0c, 0x02, 0x02, 0xb0, 0x27, 0x03, 0x03, 0xb8, 0x27, 0x03, 0x03, 0xc0, 0x27, 0x03, 0x03, 0x88, 0x06, 0x04, 0x03, 0x90, 0x06, 0x04, 0x03, + 0x40, 0x20, 0x05, 0x04, 0x20, 0x01, 0x06, 0x04, 0x20, 0x19, 0x07, 0x05, 0xc0, 0x12, 0x09, 0x06, 0x8c, 0x03, 0x00, 0x02, 0x90, 0x03, 0x00, 0x02, 0x94, 0x03, 0x00, 0x02, 0x98, 0x03, 0x00, 0x02, + 0x1c, 0x30, 0x01, 0x02, 0x20, 0x30, 0x01, 0x02, 0x24, 0x30, 0x01, 0x02, 0x28, 0x30, 0x01, 0x02, 0x2c, 0x30, 0x01, 0x02, 0x30, 0x30, 0x01, 0x02, 0x34, 0x30, 0x01, 0x02, 0x0c, 0x0c, 0x02, 0x02, + 0x10, 0x0c, 0x02, 0x02, 0x14, 0x0c, 0x02, 0x02, 0x18, 0x0c, 0x02, 0x02, 0xc8, 0x27, 0x03, 0x03, 0xd0, 0x27, 0x03, 0x03, 0xd8, 0x27, 0x03, 0x03, 0x98, 0x06, 0x04, 0x03, 0xa0, 0x06, 0x04, 0x03, + 0x50, 0x20, 0x05, 0x04, 0x30, 0x01, 0x06, 0x04, 0x40, 0x19, 0x07, 0x05, 0x00, 0x13, 0x09, 0x06, 0x9c, 0x03, 0x00, 0x02, 0xa0, 0x03, 0x00, 0x02, 0xa4, 0x03, 0x00, 0x02, 0xa8, 0x03, 0x00, 0x02, + 0x38, 0x30, 0x01, 0x02, 0x3c, 0x30, 0x01, 0x02, 0x40, 0x30, 0x01, 0x02, 0x44, 0x30, 0x01, 0x02, 0x48, 0x30, 0x01, 0x02, 0x4c, 0x30, 0x01, 0x02, 0x50, 0x30, 0x01, 0x02, 0x1c, 0x0c, 0x02, 0x02, + 0x20, 0x0c, 0x02, 0x02, 0x24, 0x0c, 0x02, 0x02, 0x28, 0x0c, 0x02, 0x02, 0xe0, 0x27, 0x03, 0x03, 0xe8, 0x27, 0x03, 0x03, 0xf0, 0x27, 0x03, 0x03, 0xa8, 0x06, 0x04, 0x03, 0xb0, 0x06, 0x04, 0x03, + 0x60, 0x20, 0x05, 0x04, 0x40, 0x01, 0x06, 0x04, 0x60, 0x19, 0x07, 0x05, 0x40, 0x13, 0x09, 0x06, 0xac, 0x03, 0x00, 0x02, 0xb0, 0x03, 0x00, 0x02, 0xb4, 0x03, 0x00, 0x02, 0xb8, 0x03, 0x00, 0x02, + 0x54, 0x30, 0x01, 0x02, 0x58, 0x30, 0x01, 0x02, 0x5c, 0x30, 0x01, 0x02, 0x60, 0x30, 0x01, 0x02, 0x64, 0x30, 0x01, 0x02, 0x68, 0x30, 0x01, 0x02, 0x6c, 0x30, 0x01, 0x02, 0x2c, 0x0c, 0x02, 0x02, + 0x30, 0x0c, 0x02, 0x02, 0x34, 0x0c, 0x02, 0x02, 0x38, 0x0c, 0x02, 0x02, 0xf8, 0x27, 0x03, 0x03, 0x00, 0x28, 0x03, 0x03, 0x08, 0x28, 0x03, 0x03, 0xb8, 0x06, 0x04, 0x03, 0xc0, 0x06, 0x04, 0x03, + 0x70, 0x20, 0x05, 0x04, 0x50, 0x01, 0x06, 0x04, 0x80, 0x19, 0x07, 0x05, 0x80, 0x13, 0x09, 0x06, 0xbc, 0x03, 0x00, 0x02, 0xc0, 0x03, 0x00, 0x02, 0xc4, 0x03, 0x00, 0x02, 0xc8, 0x03, 0x00, 0x02, + 0x70, 0x30, 0x01, 0x02, 0x74, 0x30, 0x01, 0x02, 0x78, 0x30, 0x01, 0x02, 0x7c, 0x30, 0x01, 0x02, 0x80, 0x30, 0x01, 0x02, 0x84, 0x30, 0x01, 0x02, 0x88, 0x30, 0x01, 0x02, 0x3c, 0x0c, 0x02, 0x02, + 0x40, 0x0c, 0x02, 0x02, 0x44, 0x0c, 0x02, 0x02, 0x48, 0x0c, 0x02, 0x02, 0x10, 0x28, 0x03, 0x03, 0x18, 0x28, 0x03, 0x03, 0x20, 0x28, 0x03, 0x03, 0xc8, 0x06, 0x04, 0x03, 0xd0, 0x06, 0x04, 0x03, + 0x80, 0x20, 0x05, 0x04, 0x60, 0x01, 0x06, 0x04, 0xa0, 0x19, 0x07, 0x05, 0xc0, 0x13, 0x09, 0x06, 0xcc, 0x03, 0x00, 0x02, 0xd0, 0x03, 0x00, 0x02, 0xd4, 0x03, 0x00, 0x02, 0xd8, 0x03, 0x00, 0x02, + 0x8c, 0x30, 0x01, 0x02, 0x90, 0x30, 0x01, 0x02, 0x94, 0x30, 0x01, 0x02, 0x98, 0x30, 0x01, 0x02, 0x9c, 0x30, 0x01, 0x02, 0xa0, 0x30, 0x01, 0x02, 0xa4, 0x30, 0x01, 0x02, 0x4c, 0x0c, 0x02, 0x02, + 0x50, 0x0c, 0x02, 0x02, 0x54, 0x0c, 0x02, 0x02, 0x58, 0x0c, 0x02, 0x02, 0x28, 0x28, 0x03, 0x03, 0x30, 0x28, 0x03, 0x03, 0x38, 0x28, 0x03, 0x03, 0xd8, 0x06, 0x04, 0x03, 0xe0, 0x06, 0x04, 0x03, + 0x90, 0x20, 0x05, 0x04, 0x70, 0x01, 0x06, 0x04, 0xc0, 0x19, 0x07, 0x05, 0x00, 0x14, 0x09, 0x06, 0xdc, 0x03, 0x00, 0x02, 0xe0, 0x03, 0x00, 0x02, 0xe4, 0x03, 0x00, 0x02, 0xe8, 0x03, 0x00, 0x02, + 0xa8, 0x30, 0x01, 0x02, 0xac, 0x30, 0x01, 0x02, 0xb0, 0x30, 0x01, 0x02, 0xb4, 0x30, 0x01, 0x02, 0xb8, 0x30, 0x01, 0x02, 0xbc, 0x30, 0x01, 0x02, 0xc0, 0x30, 0x01, 0x02, 0x5c, 0x0c, 0x02, 0x02, + 0x60, 0x0c, 0x02, 0x02, 0x64, 0x0c, 0x02, 0x02, 0x68, 0x0c, 0x02, 0x02, 0x40, 0x28, 0x03, 0x03, 0x48, 0x28, 0x03, 0x03, 0x50, 0x28, 0x03, 0x03, 0xe8, 0x06, 0x04, 0x03, 0xf0, 0x06, 0x04, 0x03, + 0xa0, 0x20, 0x05, 0x04, 0x80, 0x01, 0x06, 0x04, 0xe0, 0x19, 0x07, 0x05, 0x40, 0x14, 0x09, 0x06, 0xec, 0x03, 0x00, 0x02, 0xf0, 0x03, 0x00, 0x02, 0xf4, 0x03, 0x00, 0x02, 0xf8, 0x03, 0x00, 0x02, + 0xc4, 0x30, 0x01, 0x02, 0xc8, 0x30, 0x01, 0x02, 0xcc, 0x30, 0x01, 0x02, 0xd0, 0x30, 0x01, 0x02, 0xd4, 0x30, 0x01, 0x02, 0xd8, 0x30, 0x01, 0x02, 0xdc, 0x30, 0x01, 0x02, 0x6c, 0x0c, 0x02, 0x02, + 0x70, 0x0c, 0x02, 0x02, 0x74, 0x0c, 0x02, 0x02, 0x78, 0x0c, 0x02, 0x02, 0x58, 0x28, 0x03, 0x03, 0x60, 0x28, 0x03, 0x03, 0x68, 0x28, 0x03, 0x03, 0xf8, 0x06, 0x04, 0x03, 0x00, 0x07, 0x04, 0x03, + 0xb0, 0x20, 0x05, 0x04, 0x90, 0x01, 0x06, 0x04, 0x00, 0x1a, 0x07, 0x05, 0x80, 0x14, 0x09, 0x06, 0xfc, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x04, 0x04, 0x00, 0x02, 0x08, 0x04, 0x00, 0x02, + 0xe0, 0x30, 0x01, 0x02, 0xe4, 0x30, 0x01, 0x02, 0xe8, 0x30, 0x01, 0x02, 0xec, 0x30, 0x01, 0x02, 0xf0, 0x30, 0x01, 0x02, 0xf4, 0x30, 0x01, 0x02, 0xf8, 0x30, 0x01, 0x02, 0x7c, 0x0c, 0x02, 0x02, + 0x80, 0x0c, 0x02, 0x02, 0x84, 0x0c, 0x02, 0x02, 0x88, 0x0c, 0x02, 0x02, 0x70, 0x28, 0x03, 0x03, 0x78, 0x28, 0x03, 0x03, 0x80, 0x28, 0x03, 0x03, 0x08, 0x07, 0x04, 0x03, 0x10, 0x07, 0x04, 0x03, + 0xc0, 0x20, 0x05, 0x04, 0xa0, 0x01, 0x06, 0x04, 0x20, 0x1a, 0x07, 0x05, 0xc0, 0x14, 0x09, 0x06, 0x0c, 0x04, 0x00, 0x02, 0x10, 0x04, 0x00, 0x02, 0x14, 0x04, 0x00, 0x02, 0x18, 0x04, 0x00, 0x02, + 0xfc, 0x30, 0x01, 0x02, 0x00, 0x31, 0x01, 0x02, 0x04, 0x31, 0x01, 0x02, 0x08, 0x31, 0x01, 0x02, 0x0c, 0x31, 0x01, 0x02, 0x10, 0x31, 0x01, 0x02, 0x14, 0x31, 0x01, 0x02, 0x8c, 0x0c, 0x02, 0x02, + 0x90, 0x0c, 0x02, 0x02, 0x94, 0x0c, 0x02, 0x02, 0x98, 0x0c, 0x02, 0x02, 0x88, 0x28, 0x03, 0x03, 0x90, 0x28, 0x03, 0x03, 0x98, 0x28, 0x03, 0x03, 0x18, 0x07, 0x04, 0x03, 0x20, 0x07, 0x04, 0x03, + 0xd0, 0x20, 0x05, 0x04, 0xb0, 0x01, 0x06, 0x04, 0x40, 0x1a, 0x07, 0x05, 0x00, 0x15, 0x09, 0x06, 0x1c, 0x04, 0x00, 0x02, 0x20, 0x04, 0x00, 0x02, 0x24, 0x04, 0x00, 0x02, 0x28, 0x04, 0x00, 0x02, + 0x18, 0x31, 0x01, 0x02, 0x1c, 0x31, 0x01, 0x02, 0x20, 0x31, 0x01, 0x02, 0x24, 0x31, 0x01, 0x02, 0x28, 0x31, 0x01, 0x02, 0x2c, 0x31, 0x01, 0x02, 0x30, 0x31, 0x01, 0x02, 0x9c, 0x0c, 0x02, 0x02, + 0xa0, 0x0c, 0x02, 0x02, 0xa4, 0x0c, 0x02, 0x02, 0xa8, 0x0c, 0x02, 0x02, 0xa0, 0x28, 0x03, 0x03, 0xa8, 0x28, 0x03, 0x03, 0xb0, 0x28, 0x03, 0x03, 0x28, 0x07, 0x04, 0x03, 0x30, 0x07, 0x04, 0x03, + 0xe0, 0x20, 0x05, 0x04, 0xc0, 0x01, 0x06, 0x04, 0x60, 0x1a, 0x07, 0x05, 0x40, 0x15, 0x09, 0x06, 0x2c, 0x04, 0x00, 0x02, 0x30, 0x04, 0x00, 0x02, 0x34, 0x04, 0x00, 0x02, 0x38, 0x04, 0x00, 0x02, + 0x34, 0x31, 0x01, 0x02, 0x38, 0x31, 0x01, 0x02, 0x3c, 0x31, 0x01, 0x02, 0x40, 0x31, 0x01, 0x02, 0x44, 0x31, 0x01, 0x02, 0x48, 0x31, 0x01, 0x02, 0xac, 0x0c, 0x02, 0x02, 0xb0, 0x0c, 0x02, 0x02, + 0xb4, 0x0c, 0x02, 0x02, 0xb8, 0x0c, 0x02, 0x02, 0xbc, 0x0c, 0x02, 0x02, 0xb8, 0x28, 0x03, 0x03, 0xc0, 0x28, 0x03, 0x03, 0xc8, 0x28, 0x03, 0x03, 0x38, 0x07, 0x04, 0x03, 0x40, 0x07, 0x04, 0x03, + 0xf0, 0x20, 0x05, 0x04, 0xd0, 0x01, 0x06, 0x04, 0x80, 0x1a, 0x07, 0x05, 0x80, 0x15, 0x09, 0x06, 0x3c, 0x04, 0x00, 0x02, 0x40, 0x04, 0x00, 0x02, 0x44, 0x04, 0x00, 0x02, 0x48, 0x04, 0x00, 0x02, + 0x4c, 0x31, 0x01, 0x02, 0x50, 0x31, 0x01, 0x02, 0x54, 0x31, 0x01, 0x02, 0x58, 0x31, 0x01, 0x02, 0x5c, 0x31, 0x01, 0x02, 0x60, 0x31, 0x01, 0x02, 0xc0, 0x0c, 0x02, 0x02, 0xc4, 0x0c, 0x02, 0x02, + 0xc8, 0x0c, 0x02, 0x02, 0xcc, 0x0c, 0x02, 0x02, 0xd0, 0x0c, 0x02, 0x02, 0xd0, 0x28, 0x03, 0x03, 0xd8, 0x28, 0x03, 0x03, 0xe0, 0x28, 0x03, 0x03, 0x48, 0x07, 0x04, 0x03, 0x50, 0x07, 0x04, 0x03, + 0x00, 0x21, 0x05, 0x04, 0xe0, 0x01, 0x06, 0x04, 0xa0, 0x1a, 0x07, 0x05, 0xc0, 0x15, 0x09, 0x06, 0x4c, 0x04, 0x00, 0x02, 0x50, 0x04, 0x00, 0x02, 0x54, 0x04, 0x00, 0x02, 0x58, 0x04, 0x00, 0x02, + 0x64, 0x31, 0x01, 0x02, 0x68, 0x31, 0x01, 0x02, 0x6c, 0x31, 0x01, 0x02, 0x70, 0x31, 0x01, 0x02, 0x74, 0x31, 0x01, 0x02, 0x78, 0x31, 0x01, 0x02, 0xd4, 0x0c, 0x02, 0x02, 0xd8, 0x0c, 0x02, 0x02, + 0xdc, 0x0c, 0x02, 0x02, 0xe0, 0x0c, 0x02, 0x02, 0xe4, 0x0c, 0x02, 0x02, 0xe8, 0x28, 0x03, 0x03, 0xf0, 0x28, 0x03, 0x03, 0xf8, 0x28, 0x03, 0x03, 0x58, 0x07, 0x04, 0x03, 0x60, 0x07, 0x04, 0x03, + 0x10, 0x21, 0x05, 0x04, 0xf0, 0x01, 0x06, 0x04, 0xc0, 0x1a, 0x07, 0x05, 0x00, 0x16, 0x09, 0x06, 0x5c, 0x04, 0x00, 0x02, 0x60, 0x04, 0x00, 0x02, 0x64, 0x04, 0x00, 0x02, 0x68, 0x04, 0x00, 0x02, + 0x7c, 0x31, 0x01, 0x02, 0x80, 0x31, 0x01, 0x02, 0x84, 0x31, 0x01, 0x02, 0x88, 0x31, 0x01, 0x02, 0x8c, 0x31, 0x01, 0x02, 0x90, 0x31, 0x01, 0x02, 0xe8, 0x0c, 0x02, 0x02, 0xec, 0x0c, 0x02, 0x02, + 0xf0, 0x0c, 0x02, 0x02, 0xf4, 0x0c, 0x02, 0x02, 0xf8, 0x0c, 0x02, 0x02, 0x00, 0x29, 0x03, 0x03, 0x08, 0x29, 0x03, 0x03, 0x10, 0x29, 0x03, 0x03, 0x68, 0x07, 0x04, 0x03, 0x70, 0x07, 0x04, 0x03, + 0x20, 0x21, 0x05, 0x04, 0x00, 0x02, 0x06, 0x04, 0xe0, 0x1a, 0x07, 0x05, 0x40, 0x16, 0x09, 0x06, 0x6c, 0x04, 0x00, 0x02, 0x70, 0x04, 0x00, 0x02, 0x74, 0x04, 0x00, 0x02, 0x78, 0x04, 0x00, 0x02, + 0x94, 0x31, 0x01, 0x02, 0x98, 0x31, 0x01, 0x02, 0x9c, 0x31, 0x01, 0x02, 0xa0, 0x31, 0x01, 0x02, 0xa4, 0x31, 0x01, 0x02, 0xa8, 0x31, 0x01, 0x02, 0xfc, 0x0c, 0x02, 0x02, 0x00, 0x0d, 0x02, 0x02, + 0x04, 0x0d, 0x02, 0x02, 0x08, 0x0d, 0x02, 0x02, 0x0c, 0x0d, 0x02, 0x02, 0x18, 0x29, 0x03, 0x03, 0x20, 0x29, 0x03, 0x03, 0x28, 0x29, 0x03, 0x03, 0x78, 0x07, 0x04, 0x03, 0x80, 0x07, 0x04, 0x03, + 0x30, 0x21, 0x05, 0x04, 0x10, 0x02, 0x06, 0x04, 0x00, 0x1b, 0x07, 0x05, 0x80, 0x16, 0x09, 0x06, 0x7c, 0x04, 0x00, 0x02, 0x80, 0x04, 0x00, 0x02, 0x84, 0x04, 0x00, 0x02, 0x88, 0x04, 0x00, 0x02, + 0xac, 0x31, 0x01, 0x02, 0xb0, 0x31, 0x01, 0x02, 0xb4, 0x31, 0x01, 0x02, 0xb8, 0x31, 0x01, 0x02, 0xbc, 0x31, 0x01, 0x02, 0xc0, 0x31, 0x01, 0x02, 0x10, 0x0d, 0x02, 0x02, 0x14, 0x0d, 0x02, 0x02, + 0x18, 0x0d, 0x02, 0x02, 0x1c, 0x0d, 0x02, 0x02, 0x20, 0x0d, 0x02, 0x02, 0x30, 0x29, 0x03, 0x03, 0x38, 0x29, 0x03, 0x03, 0x40, 0x29, 0x03, 0x03, 0x88, 0x07, 0x04, 0x03, 0x90, 0x07, 0x04, 0x03, + 0x40, 0x21, 0x05, 0x04, 0x20, 0x02, 0x06, 0x04, 0x20, 0x1b, 0x07, 0x05, 0xc0, 0x16, 0x09, 0x06, 0x8c, 0x04, 0x00, 0x02, 0x90, 0x04, 0x00, 0x02, 0x94, 0x04, 0x00, 0x02, 0x98, 0x04, 0x00, 0x02, + 0xc4, 0x31, 0x01, 0x02, 0xc8, 0x31, 0x01, 0x02, 0xcc, 0x31, 0x01, 0x02, 0xd0, 0x31, 0x01, 0x02, 0xd4, 0x31, 0x01, 0x02, 0xd8, 0x31, 0x01, 0x02, 0x24, 0x0d, 0x02, 0x02, 0x28, 0x0d, 0x02, 0x02, + 0x2c, 0x0d, 0x02, 0x02, 0x30, 0x0d, 0x02, 0x02, 0x34, 0x0d, 0x02, 0x02, 0x48, 0x29, 0x03, 0x03, 0x50, 0x29, 0x03, 0x03, 0x58, 0x29, 0x03, 0x03, 0x98, 0x07, 0x04, 0x03, 0xa0, 0x07, 0x04, 0x03, + 0x50, 0x21, 0x05, 0x04, 0x30, 0x02, 0x06, 0x04, 0x40, 0x1b, 0x07, 0x05, 0x80, 0x2e, 0x0a, 0x07, 0x9c, 0x04, 0x00, 0x02, 0xa0, 0x04, 0x00, 0x02, 0xa4, 0x04, 0x00, 0x02, 0xa8, 0x04, 0x00, 0x02, + 0xdc, 0x31, 0x01, 0x02, 0xe0, 0x31, 0x01, 0x02, 0xe4, 0x31, 0x01, 0x02, 0xe8, 0x31, 0x01, 0x02, 0xec, 0x31, 0x01, 0x02, 0xf0, 0x31, 0x01, 0x02, 0x38, 0x0d, 0x02, 0x02, 0x3c, 0x0d, 0x02, 0x02, + 0x40, 0x0d, 0x02, 0x02, 0x44, 0x0d, 0x02, 0x02, 0x48, 0x0d, 0x02, 0x02, 0x60, 0x29, 0x03, 0x03, 0x68, 0x29, 0x03, 0x03, 0x70, 0x29, 0x03, 0x03, 0xa8, 0x07, 0x04, 0x03, 0xb0, 0x07, 0x04, 0x03, + 0x60, 0x21, 0x05, 0x04, 0x40, 0x02, 0x06, 0x04, 0x60, 0x1b, 0x07, 0x05, 0x00, 0x2f, 0x0a, 0x07, 0xac, 0x04, 0x00, 0x02, 0xb0, 0x04, 0x00, 0x02, 0xb4, 0x04, 0x00, 0x02, 0xb8, 0x04, 0x00, 0x02, + 0xf4, 0x31, 0x01, 0x02, 0xf8, 0x31, 0x01, 0x02, 0xfc, 0x31, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, 0x04, 0x32, 0x01, 0x02, 0x08, 0x32, 0x01, 0x02, 0x4c, 0x0d, 0x02, 0x02, 0x50, 0x0d, 0x02, 0x02, + 0x54, 0x0d, 0x02, 0x02, 0x58, 0x0d, 0x02, 0x02, 0x5c, 0x0d, 0x02, 0x02, 0x78, 0x29, 0x03, 0x03, 0x80, 0x29, 0x03, 0x03, 0x88, 0x29, 0x03, 0x03, 0xb8, 0x07, 0x04, 0x03, 0xc0, 0x07, 0x04, 0x03, + 0x70, 0x21, 0x05, 0x04, 0x50, 0x02, 0x06, 0x04, 0x80, 0x1b, 0x07, 0x05, 0x80, 0x2f, 0x0a, 0x07, 0xbc, 0x04, 0x00, 0x02, 0xc0, 0x04, 0x00, 0x02, 0xc4, 0x04, 0x00, 0x02, 0xc8, 0x04, 0x00, 0x02, + 0x0c, 0x32, 0x01, 0x02, 0x10, 0x32, 0x01, 0x02, 0x14, 0x32, 0x01, 0x02, 0x18, 0x32, 0x01, 0x02, 0x1c, 0x32, 0x01, 0x02, 0x20, 0x32, 0x01, 0x02, 0x60, 0x0d, 0x02, 0x02, 0x64, 0x0d, 0x02, 0x02, + 0x68, 0x0d, 0x02, 0x02, 0x6c, 0x0d, 0x02, 0x02, 0x70, 0x0d, 0x02, 0x02, 0x90, 0x29, 0x03, 0x03, 0x98, 0x29, 0x03, 0x03, 0xa0, 0x29, 0x03, 0x03, 0xc8, 0x07, 0x04, 0x03, 0xd0, 0x07, 0x04, 0x03, + 0x80, 0x21, 0x05, 0x04, 0x60, 0x02, 0x06, 0x04, 0xa0, 0x1b, 0x07, 0x05, 0x00, 0x30, 0x0a, 0x07, 0xcc, 0x04, 0x00, 0x02, 0xd0, 0x04, 0x00, 0x02, 0xd4, 0x04, 0x00, 0x02, 0xd8, 0x04, 0x00, 0x02, + 0x24, 0x32, 0x01, 0x02, 0x28, 0x32, 0x01, 0x02, 0x2c, 0x32, 0x01, 0x02, 0x30, 0x32, 0x01, 0x02, 0x34, 0x32, 0x01, 0x02, 0x38, 0x32, 0x01, 0x02, 0x74, 0x0d, 0x02, 0x02, 0x78, 0x0d, 0x02, 0x02, + 0x7c, 0x0d, 0x02, 0x02, 0x80, 0x0d, 0x02, 0x02, 0x84, 0x0d, 0x02, 0x02, 0xa8, 0x29, 0x03, 0x03, 0xb0, 0x29, 0x03, 0x03, 0xb8, 0x29, 0x03, 0x03, 0xd8, 0x07, 0x04, 0x03, 0xe0, 0x07, 0x04, 0x03, + 0x90, 0x21, 0x05, 0x04, 0x70, 0x02, 0x06, 0x04, 0xc0, 0x1b, 0x07, 0x05, 0x80, 0x30, 0x0a, 0x07, 0xdc, 0x04, 0x00, 0x02, 0xe0, 0x04, 0x00, 0x02, 0xe4, 0x04, 0x00, 0x02, 0xe8, 0x04, 0x00, 0x02, + 0x3c, 0x32, 0x01, 0x02, 0x40, 0x32, 0x01, 0x02, 0x44, 0x32, 0x01, 0x02, 0x48, 0x32, 0x01, 0x02, 0x4c, 0x32, 0x01, 0x02, 0x50, 0x32, 0x01, 0x02, 0x88, 0x0d, 0x02, 0x02, 0x8c, 0x0d, 0x02, 0x02, + 0x90, 0x0d, 0x02, 0x02, 0x94, 0x0d, 0x02, 0x02, 0x98, 0x0d, 0x02, 0x02, 0xc0, 0x29, 0x03, 0x03, 0xc8, 0x29, 0x03, 0x03, 0xd0, 0x29, 0x03, 0x03, 0xe8, 0x07, 0x04, 0x03, 0xf0, 0x07, 0x04, 0x03, + 0xa0, 0x21, 0x05, 0x04, 0x80, 0x02, 0x06, 0x04, 0xe0, 0x1b, 0x07, 0x05, 0x00, 0x31, 0x0a, 0x07, 0xec, 0x04, 0x00, 0x02, 0xf0, 0x04, 0x00, 0x02, 0xf4, 0x04, 0x00, 0x02, 0xf8, 0x04, 0x00, 0x02, + 0x54, 0x32, 0x01, 0x02, 0x58, 0x32, 0x01, 0x02, 0x5c, 0x32, 0x01, 0x02, 0x60, 0x32, 0x01, 0x02, 0x64, 0x32, 0x01, 0x02, 0x68, 0x32, 0x01, 0x02, 0x9c, 0x0d, 0x02, 0x02, 0xa0, 0x0d, 0x02, 0x02, + 0xa4, 0x0d, 0x02, 0x02, 0xa8, 0x0d, 0x02, 0x02, 0xac, 0x0d, 0x02, 0x02, 0xd8, 0x29, 0x03, 0x03, 0xe0, 0x29, 0x03, 0x03, 0xe8, 0x29, 0x03, 0x03, 0xf8, 0x07, 0x04, 0x03, 0x00, 0x08, 0x04, 0x03, + 0xb0, 0x21, 0x05, 0x04, 0x90, 0x02, 0x06, 0x04, 0x00, 0x1c, 0x07, 0x05, 0x80, 0x31, 0x0a, 0x07, 0xfc, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x04, 0x05, 0x00, 0x02, 0x08, 0x05, 0x00, 0x02, + 0x6c, 0x32, 0x01, 0x02, 0x70, 0x32, 0x01, 0x02, 0x74, 0x32, 0x01, 0x02, 0x78, 0x32, 0x01, 0x02, 0x7c, 0x32, 0x01, 0x02, 0x80, 0x32, 0x01, 0x02, 0xb0, 0x0d, 0x02, 0x02, 0xb4, 0x0d, 0x02, 0x02, + 0xb8, 0x0d, 0x02, 0x02, 0xbc, 0x0d, 0x02, 0x02, 0xc0, 0x0d, 0x02, 0x02, 0xf0, 0x29, 0x03, 0x03, 0xf8, 0x29, 0x03, 0x03, 0x00, 0x2a, 0x03, 0x03, 0x08, 0x08, 0x04, 0x03, 0x10, 0x08, 0x04, 0x03, + 0xc0, 0x21, 0x05, 0x04, 0xa0, 0x02, 0x06, 0x04, 0x20, 0x1c, 0x07, 0x05, 0x00, 0x32, 0x0a, 0x07, 0x0c, 0x05, 0x00, 0x02, 0x10, 0x05, 0x00, 0x02, 0x14, 0x05, 0x00, 0x02, 0x18, 0x05, 0x00, 0x02, + 0x84, 0x32, 0x01, 0x02, 0x88, 0x32, 0x01, 0x02, 0x8c, 0x32, 0x01, 0x02, 0x90, 0x32, 0x01, 0x02, 0x94, 0x32, 0x01, 0x02, 0x98, 0x32, 0x01, 0x02, 0xc4, 0x0d, 0x02, 0x02, 0xc8, 0x0d, 0x02, 0x02, + 0xcc, 0x0d, 0x02, 0x02, 0xd0, 0x0d, 0x02, 0x02, 0xd4, 0x0d, 0x02, 0x02, 0x08, 0x2a, 0x03, 0x03, 0x10, 0x2a, 0x03, 0x03, 0x18, 0x2a, 0x03, 0x03, 0x18, 0x08, 0x04, 0x03, 0x20, 0x08, 0x04, 0x03, + 0xd0, 0x21, 0x05, 0x04, 0xb0, 0x02, 0x06, 0x04, 0x40, 0x1c, 0x07, 0x05, 0x80, 0x32, 0x0a, 0x07, 0x1c, 0x05, 0x00, 0x02, 0x20, 0x05, 0x00, 0x02, 0x24, 0x05, 0x00, 0x02, 0x28, 0x05, 0x00, 0x02, + 0x9c, 0x32, 0x01, 0x02, 0xa0, 0x32, 0x01, 0x02, 0xa4, 0x32, 0x01, 0x02, 0xa8, 0x32, 0x01, 0x02, 0xac, 0x32, 0x01, 0x02, 0xb0, 0x32, 0x01, 0x02, 0xd8, 0x0d, 0x02, 0x02, 0xdc, 0x0d, 0x02, 0x02, + 0xe0, 0x0d, 0x02, 0x02, 0xe4, 0x0d, 0x02, 0x02, 0xe8, 0x0d, 0x02, 0x02, 0x20, 0x2a, 0x03, 0x03, 0x28, 0x2a, 0x03, 0x03, 0x30, 0x2a, 0x03, 0x03, 0x28, 0x08, 0x04, 0x03, 0x30, 0x08, 0x04, 0x03, + 0xe0, 0x21, 0x05, 0x04, 0xc0, 0x02, 0x06, 0x04, 0x60, 0x1c, 0x07, 0x05, 0x00, 0x33, 0x0a, 0x07, 0x2c, 0x05, 0x00, 0x02, 0x30, 0x05, 0x00, 0x02, 0x34, 0x05, 0x00, 0x02, 0x38, 0x05, 0x00, 0x02, + 0xb4, 0x32, 0x01, 0x02, 0xb8, 0x32, 0x01, 0x02, 0xbc, 0x32, 0x01, 0x02, 0xc0, 0x32, 0x01, 0x02, 0xc4, 0x32, 0x01, 0x02, 0xc8, 0x32, 0x01, 0x02, 0xec, 0x0d, 0x02, 0x02, 0xf0, 0x0d, 0x02, 0x02, + 0xf4, 0x0d, 0x02, 0x02, 0xf8, 0x0d, 0x02, 0x02, 0xfc, 0x0d, 0x02, 0x02, 0x38, 0x2a, 0x03, 0x03, 0x40, 0x2a, 0x03, 0x03, 0x48, 0x2a, 0x03, 0x03, 0x38, 0x08, 0x04, 0x03, 0x40, 0x08, 0x04, 0x03, + 0xf0, 0x21, 0x05, 0x04, 0xd0, 0x02, 0x06, 0x04, 0x80, 0x1c, 0x07, 0x05, 0x80, 0x33, 0x0a, 0x07, 0x3c, 0x05, 0x00, 0x02, 0x40, 0x05, 0x00, 0x02, 0x44, 0x05, 0x00, 0x02, 0x48, 0x05, 0x00, 0x02, + 0xcc, 0x32, 0x01, 0x02, 0xd0, 0x32, 0x01, 0x02, 0xd4, 0x32, 0x01, 0x02, 0xd8, 0x32, 0x01, 0x02, 0xdc, 0x32, 0x01, 0x02, 0xe0, 0x32, 0x01, 0x02, 0x00, 0x0e, 0x02, 0x02, 0x04, 0x0e, 0x02, 0x02, + 0x08, 0x0e, 0x02, 0x02, 0x0c, 0x0e, 0x02, 0x02, 0x10, 0x0e, 0x02, 0x02, 0x50, 0x2a, 0x03, 0x03, 0x58, 0x2a, 0x03, 0x03, 0x60, 0x2a, 0x03, 0x03, 0x48, 0x08, 0x04, 0x03, 0x50, 0x08, 0x04, 0x03, + 0x00, 0x22, 0x05, 0x04, 0xe0, 0x02, 0x06, 0x04, 0xa0, 0x1c, 0x07, 0x05, 0x00, 0x34, 0x0a, 0x07, 0x4c, 0x05, 0x00, 0x02, 0x50, 0x05, 0x00, 0x02, 0x54, 0x05, 0x00, 0x02, 0x58, 0x05, 0x00, 0x02, + 0xe4, 0x32, 0x01, 0x02, 0xe8, 0x32, 0x01, 0x02, 0xec, 0x32, 0x01, 0x02, 0xf0, 0x32, 0x01, 0x02, 0xf4, 0x32, 0x01, 0x02, 0xf8, 0x32, 0x01, 0x02, 0x14, 0x0e, 0x02, 0x02, 0x18, 0x0e, 0x02, 0x02, + 0x1c, 0x0e, 0x02, 0x02, 0x20, 0x0e, 0x02, 0x02, 0x24, 0x0e, 0x02, 0x02, 0x68, 0x2a, 0x03, 0x03, 0x70, 0x2a, 0x03, 0x03, 0x78, 0x2a, 0x03, 0x03, 0x58, 0x08, 0x04, 0x03, 0x60, 0x08, 0x04, 0x03, + 0x10, 0x22, 0x05, 0x04, 0xf0, 0x02, 0x06, 0x04, 0xc0, 0x1c, 0x07, 0x05, 0x80, 0x34, 0x0a, 0x07, 0x5c, 0x05, 0x00, 0x02, 0x60, 0x05, 0x00, 0x02, 0x64, 0x05, 0x00, 0x02, 0x68, 0x05, 0x00, 0x02, + 0xfc, 0x32, 0x01, 0x02, 0x00, 0x33, 0x01, 0x02, 0x04, 0x33, 0x01, 0x02, 0x08, 0x33, 0x01, 0x02, 0x0c, 0x33, 0x01, 0x02, 0x10, 0x33, 0x01, 0x02, 0x28, 0x0e, 0x02, 0x02, 0x2c, 0x0e, 0x02, 0x02, + 0x30, 0x0e, 0x02, 0x02, 0x34, 0x0e, 0x02, 0x02, 0x38, 0x0e, 0x02, 0x02, 0x80, 0x2a, 0x03, 0x03, 0x88, 0x2a, 0x03, 0x03, 0x90, 0x2a, 0x03, 0x03, 0x68, 0x08, 0x04, 0x03, 0x70, 0x08, 0x04, 0x03, + 0x20, 0x22, 0x05, 0x04, 0x00, 0x03, 0x06, 0x04, 0xe0, 0x1c, 0x07, 0x05, 0x00, 0x35, 0x0a, 0x07, 0x6c, 0x05, 0x00, 0x02, 0x70, 0x05, 0x00, 0x02, 0x74, 0x05, 0x00, 0x02, 0x78, 0x05, 0x00, 0x02, + 0x14, 0x33, 0x01, 0x02, 0x18, 0x33, 0x01, 0x02, 0x1c, 0x33, 0x01, 0x02, 0x20, 0x33, 0x01, 0x02, 0x24, 0x33, 0x01, 0x02, 0x28, 0x33, 0x01, 0x02, 0x3c, 0x0e, 0x02, 0x02, 0x40, 0x0e, 0x02, 0x02, + 0x44, 0x0e, 0x02, 0x02, 0x48, 0x0e, 0x02, 0x02, 0x4c, 0x0e, 0x02, 0x02, 0x98, 0x2a, 0x03, 0x03, 0xa0, 0x2a, 0x03, 0x03, 0xa8, 0x2a, 0x03, 0x03, 0x78, 0x08, 0x04, 0x03, 0x80, 0x08, 0x04, 0x03, + 0x30, 0x22, 0x05, 0x04, 0x10, 0x03, 0x06, 0x04, 0x00, 0x1d, 0x07, 0x05, 0x80, 0x35, 0x0a, 0x07, 0x7c, 0x05, 0x00, 0x02, 0x80, 0x05, 0x00, 0x02, 0x84, 0x05, 0x00, 0x02, 0x88, 0x05, 0x00, 0x02, + 0x2c, 0x33, 0x01, 0x02, 0x30, 0x33, 0x01, 0x02, 0x34, 0x33, 0x01, 0x02, 0x38, 0x33, 0x01, 0x02, 0x3c, 0x33, 0x01, 0x02, 0x40, 0x33, 0x01, 0x02, 0x50, 0x0e, 0x02, 0x02, 0x54, 0x0e, 0x02, 0x02, + 0x58, 0x0e, 0x02, 0x02, 0x5c, 0x0e, 0x02, 0x02, 0x60, 0x0e, 0x02, 0x02, 0xb0, 0x2a, 0x03, 0x03, 0xb8, 0x2a, 0x03, 0x03, 0xc0, 0x2a, 0x03, 0x03, 0x88, 0x08, 0x04, 0x03, 0x90, 0x08, 0x04, 0x03, + 0x40, 0x22, 0x05, 0x04, 0x20, 0x03, 0x06, 0x04, 0x20, 0x1d, 0x07, 0x05, 0x00, 0x36, 0x0a, 0x07, 0x8c, 0x05, 0x00, 0x02, 0x90, 0x05, 0x00, 0x02, 0x94, 0x05, 0x00, 0x02, 0x98, 0x05, 0x00, 0x02, + 0x44, 0x33, 0x01, 0x02, 0x48, 0x33, 0x01, 0x02, 0x4c, 0x33, 0x01, 0x02, 0x50, 0x33, 0x01, 0x02, 0x54, 0x33, 0x01, 0x02, 0x58, 0x33, 0x01, 0x02, 0x64, 0x0e, 0x02, 0x02, 0x68, 0x0e, 0x02, 0x02, + 0x6c, 0x0e, 0x02, 0x02, 0x70, 0x0e, 0x02, 0x02, 0x74, 0x0e, 0x02, 0x02, 0xc8, 0x2a, 0x03, 0x03, 0xd0, 0x2a, 0x03, 0x03, 0xd8, 0x2a, 0x03, 0x03, 0x98, 0x08, 0x04, 0x03, 0xa0, 0x08, 0x04, 0x03, + 0x50, 0x22, 0x05, 0x04, 0x30, 0x03, 0x06, 0x04, 0x40, 0x1d, 0x07, 0x05, 0x80, 0x36, 0x0a, 0x07, 0x9c, 0x05, 0x00, 0x02, 0xa0, 0x05, 0x00, 0x02, 0xa4, 0x05, 0x00, 0x02, 0xa8, 0x05, 0x00, 0x02, + 0x5c, 0x33, 0x01, 0x02, 0x60, 0x33, 0x01, 0x02, 0x64, 0x33, 0x01, 0x02, 0x68, 0x33, 0x01, 0x02, 0x6c, 0x33, 0x01, 0x02, 0x70, 0x33, 0x01, 0x02, 0x78, 0x0e, 0x02, 0x02, 0x7c, 0x0e, 0x02, 0x02, + 0x80, 0x0e, 0x02, 0x02, 0x84, 0x0e, 0x02, 0x02, 0x88, 0x0e, 0x02, 0x02, 0xe0, 0x2a, 0x03, 0x03, 0xe8, 0x2a, 0x03, 0x03, 0xf0, 0x2a, 0x03, 0x03, 0xa8, 0x08, 0x04, 0x03, 0xb0, 0x08, 0x04, 0x03, + 0x60, 0x22, 0x05, 0x04, 0x40, 0x03, 0x06, 0x04, 0x60, 0x1d, 0x07, 0x05, 0x00, 0x0b, 0x0b, 0x07, 0xac, 0x05, 0x00, 0x02, 0xb0, 0x05, 0x00, 0x02, 0xb4, 0x05, 0x00, 0x02, 0xb8, 0x05, 0x00, 0x02, + 0x74, 0x33, 0x01, 0x02, 0x78, 0x33, 0x01, 0x02, 0x7c, 0x33, 0x01, 0x02, 0x80, 0x33, 0x01, 0x02, 0x84, 0x33, 0x01, 0x02, 0x88, 0x33, 0x01, 0x02, 0x8c, 0x0e, 0x02, 0x02, 0x90, 0x0e, 0x02, 0x02, + 0x94, 0x0e, 0x02, 0x02, 0x98, 0x0e, 0x02, 0x02, 0x9c, 0x0e, 0x02, 0x02, 0xf8, 0x2a, 0x03, 0x03, 0x00, 0x2b, 0x03, 0x03, 0x08, 0x2b, 0x03, 0x03, 0xb8, 0x08, 0x04, 0x03, 0xc0, 0x08, 0x04, 0x03, + 0x70, 0x22, 0x05, 0x04, 0x50, 0x03, 0x06, 0x04, 0x80, 0x1d, 0x07, 0x05, 0x80, 0x0b, 0x0b, 0x07, 0xbc, 0x05, 0x00, 0x02, 0xc0, 0x05, 0x00, 0x02, 0xc4, 0x05, 0x00, 0x02, 0xc8, 0x05, 0x00, 0x02, + 0x8c, 0x33, 0x01, 0x02, 0x90, 0x33, 0x01, 0x02, 0x94, 0x33, 0x01, 0x02, 0x98, 0x33, 0x01, 0x02, 0x9c, 0x33, 0x01, 0x02, 0xa0, 0x33, 0x01, 0x02, 0xa0, 0x0e, 0x02, 0x02, 0xa4, 0x0e, 0x02, 0x02, + 0xa8, 0x0e, 0x02, 0x02, 0xac, 0x0e, 0x02, 0x02, 0xb0, 0x0e, 0x02, 0x02, 0x10, 0x2b, 0x03, 0x03, 0x18, 0x2b, 0x03, 0x03, 0x20, 0x2b, 0x03, 0x03, 0xc8, 0x08, 0x04, 0x03, 0xd0, 0x08, 0x04, 0x03, + 0x80, 0x22, 0x05, 0x04, 0x60, 0x03, 0x06, 0x04, 0xa0, 0x1d, 0x07, 0x05, 0x00, 0x0c, 0x0b, 0x07, 0xcc, 0x05, 0x00, 0x02, 0xd0, 0x05, 0x00, 0x02, 0xd4, 0x05, 0x00, 0x02, 0xd8, 0x05, 0x00, 0x02, + 0xa4, 0x33, 0x01, 0x02, 0xa8, 0x33, 0x01, 0x02, 0xac, 0x33, 0x01, 0x02, 0xb0, 0x33, 0x01, 0x02, 0xb4, 0x33, 0x01, 0x02, 0xb8, 0x33, 0x01, 0x02, 0xb4, 0x0e, 0x02, 0x02, 0xb8, 0x0e, 0x02, 0x02, + 0xbc, 0x0e, 0x02, 0x02, 0xc0, 0x0e, 0x02, 0x02, 0xc4, 0x0e, 0x02, 0x02, 0x28, 0x2b, 0x03, 0x03, 0x30, 0x2b, 0x03, 0x03, 0x38, 0x2b, 0x03, 0x03, 0xd8, 0x08, 0x04, 0x03, 0xe0, 0x08, 0x04, 0x03, + 0x90, 0x22, 0x05, 0x04, 0x70, 0x03, 0x06, 0x04, 0xc0, 0x1d, 0x07, 0x05, 0x80, 0x0c, 0x0b, 0x07, 0xdc, 0x05, 0x00, 0x02, 0xe0, 0x05, 0x00, 0x02, 0xe4, 0x05, 0x00, 0x02, 0xe8, 0x05, 0x00, 0x02, + 0xbc, 0x33, 0x01, 0x02, 0xc0, 0x33, 0x01, 0x02, 0xc4, 0x33, 0x01, 0x02, 0xc8, 0x33, 0x01, 0x02, 0xcc, 0x33, 0x01, 0x02, 0xd0, 0x33, 0x01, 0x02, 0xc8, 0x0e, 0x02, 0x02, 0xcc, 0x0e, 0x02, 0x02, + 0xd0, 0x0e, 0x02, 0x02, 0xd4, 0x0e, 0x02, 0x02, 0xd8, 0x0e, 0x02, 0x02, 0x40, 0x2b, 0x03, 0x03, 0x48, 0x2b, 0x03, 0x03, 0x50, 0x2b, 0x03, 0x03, 0xe8, 0x08, 0x04, 0x03, 0xf0, 0x08, 0x04, 0x03, + 0xa0, 0x22, 0x05, 0x04, 0x80, 0x03, 0x06, 0x04, 0xe0, 0x1d, 0x07, 0x05, 0x00, 0x0d, 0x0b, 0x07, 0xec, 0x05, 0x00, 0x02, 0xf0, 0x05, 0x00, 0x02, 0xf4, 0x05, 0x00, 0x02, 0xf8, 0x05, 0x00, 0x02, + 0xd4, 0x33, 0x01, 0x02, 0xd8, 0x33, 0x01, 0x02, 0xdc, 0x33, 0x01, 0x02, 0xe0, 0x33, 0x01, 0x02, 0xe4, 0x33, 0x01, 0x02, 0xe8, 0x33, 0x01, 0x02, 0xdc, 0x0e, 0x02, 0x02, 0xe0, 0x0e, 0x02, 0x02, + 0xe4, 0x0e, 0x02, 0x02, 0xe8, 0x0e, 0x02, 0x02, 0xec, 0x0e, 0x02, 0x02, 0x58, 0x2b, 0x03, 0x03, 0x60, 0x2b, 0x03, 0x03, 0x68, 0x2b, 0x03, 0x03, 0xf8, 0x08, 0x04, 0x03, 0x00, 0x09, 0x04, 0x03, + 0xb0, 0x22, 0x05, 0x04, 0x90, 0x03, 0x06, 0x04, 0x00, 0x1e, 0x07, 0x05, 0x80, 0x0d, 0x0b, 0x07, 0xfc, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x04, 0x06, 0x00, 0x02, 0x08, 0x06, 0x00, 0x02, + 0xec, 0x33, 0x01, 0x02, 0xf0, 0x33, 0x01, 0x02, 0xf4, 0x33, 0x01, 0x02, 0xf8, 0x33, 0x01, 0x02, 0xfc, 0x33, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0xf0, 0x0e, 0x02, 0x02, 0xf4, 0x0e, 0x02, 0x02, + 0xf8, 0x0e, 0x02, 0x02, 0xfc, 0x0e, 0x02, 0x02, 0x00, 0x0f, 0x02, 0x02, 0x70, 0x2b, 0x03, 0x03, 0x78, 0x2b, 0x03, 0x03, 0x80, 0x2b, 0x03, 0x03, 0x08, 0x09, 0x04, 0x03, 0x10, 0x09, 0x04, 0x03, + 0xc0, 0x22, 0x05, 0x04, 0xa0, 0x03, 0x06, 0x04, 0x40, 0x3a, 0x08, 0x06, 0x00, 0x0e, 0x0b, 0x07, 0x0c, 0x06, 0x00, 0x02, 0x10, 0x06, 0x00, 0x02, 0x14, 0x06, 0x00, 0x02, 0x18, 0x06, 0x00, 0x02, + 0x04, 0x34, 0x01, 0x02, 0x08, 0x34, 0x01, 0x02, 0x0c, 0x34, 0x01, 0x02, 0x10, 0x34, 0x01, 0x02, 0x14, 0x34, 0x01, 0x02, 0x18, 0x34, 0x01, 0x02, 0x04, 0x0f, 0x02, 0x02, 0x08, 0x0f, 0x02, 0x02, + 0x0c, 0x0f, 0x02, 0x02, 0x10, 0x0f, 0x02, 0x02, 0x14, 0x0f, 0x02, 0x02, 0x88, 0x2b, 0x03, 0x03, 0x90, 0x2b, 0x03, 0x03, 0x18, 0x09, 0x04, 0x03, 0x20, 0x09, 0x04, 0x03, 0x28, 0x09, 0x04, 0x03, + 0xd0, 0x22, 0x05, 0x04, 0xb0, 0x03, 0x06, 0x04, 0x80, 0x3a, 0x08, 0x06, 0x80, 0x0e, 0x0b, 0x07, 0x1c, 0x06, 0x00, 0x02, 0x20, 0x06, 0x00, 0x02, 0x24, 0x06, 0x00, 0x02, 0x28, 0x06, 0x00, 0x02, + 0x1c, 0x34, 0x01, 0x02, 0x20, 0x34, 0x01, 0x02, 0x24, 0x34, 0x01, 0x02, 0x28, 0x34, 0x01, 0x02, 0x2c, 0x34, 0x01, 0x02, 0x30, 0x34, 0x01, 0x02, 0x18, 0x0f, 0x02, 0x02, 0x1c, 0x0f, 0x02, 0x02, + 0x20, 0x0f, 0x02, 0x02, 0x24, 0x0f, 0x02, 0x02, 0x28, 0x0f, 0x02, 0x02, 0x98, 0x2b, 0x03, 0x03, 0xa0, 0x2b, 0x03, 0x03, 0x30, 0x09, 0x04, 0x03, 0x38, 0x09, 0x04, 0x03, 0x40, 0x09, 0x04, 0x03, + 0xe0, 0x22, 0x05, 0x04, 0xc0, 0x03, 0x06, 0x04, 0xc0, 0x3a, 0x08, 0x06, 0x00, 0x0f, 0x0b, 0x07, 0x2c, 0x06, 0x00, 0x02, 0x30, 0x06, 0x00, 0x02, 0x34, 0x06, 0x00, 0x02, 0x38, 0x06, 0x00, 0x02, + 0x34, 0x34, 0x01, 0x02, 0x38, 0x34, 0x01, 0x02, 0x3c, 0x34, 0x01, 0x02, 0x40, 0x34, 0x01, 0x02, 0x44, 0x34, 0x01, 0x02, 0x48, 0x34, 0x01, 0x02, 0x2c, 0x0f, 0x02, 0x02, 0x30, 0x0f, 0x02, 0x02, + 0x34, 0x0f, 0x02, 0x02, 0x38, 0x0f, 0x02, 0x02, 0xa8, 0x2b, 0x03, 0x03, 0xb0, 0x2b, 0x03, 0x03, 0xb8, 0x2b, 0x03, 0x03, 0x48, 0x09, 0x04, 0x03, 0x50, 0x09, 0x04, 0x03, 0xf0, 0x22, 0x05, 0x04, + 0x00, 0x23, 0x05, 0x04, 0xd0, 0x03, 0x06, 0x04, 0x00, 0x3b, 0x08, 0x06, 0x80, 0x0f, 0x0b, 0x07, 0x3c, 0x06, 0x00, 0x02, 0x40, 0x06, 0x00, 0x02, 0x44, 0x06, 0x00, 0x02, 0x48, 0x06, 0x00, 0x02, + 0x4c, 0x34, 0x01, 0x02, 0x50, 0x34, 0x01, 0x02, 0x54, 0x34, 0x01, 0x02, 0x58, 0x34, 0x01, 0x02, 0x5c, 0x34, 0x01, 0x02, 0x60, 0x34, 0x01, 0x02, 0x3c, 0x0f, 0x02, 0x02, 0x40, 0x0f, 0x02, 0x02, + 0x44, 0x0f, 0x02, 0x02, 0x48, 0x0f, 0x02, 0x02, 0xc0, 0x2b, 0x03, 0x03, 0xc8, 0x2b, 0x03, 0x03, 0xd0, 0x2b, 0x03, 0x03, 0x58, 0x09, 0x04, 0x03, 0x60, 0x09, 0x04, 0x03, 0x10, 0x23, 0x05, 0x04, + 0x20, 0x23, 0x05, 0x04, 0xe0, 0x03, 0x06, 0x04, 0x40, 0x3b, 0x08, 0x06, 0x00, 0x10, 0x0b, 0x07, 0x4c, 0x06, 0x00, 0x02, 0x50, 0x06, 0x00, 0x02, 0x54, 0x06, 0x00, 0x02, 0x58, 0x06, 0x00, 0x02, + 0x64, 0x34, 0x01, 0x02, 0x68, 0x34, 0x01, 0x02, 0x6c, 0x34, 0x01, 0x02, 0x70, 0x34, 0x01, 0x02, 0x74, 0x34, 0x01, 0x02, 0x78, 0x34, 0x01, 0x02, 0x4c, 0x0f, 0x02, 0x02, 0x50, 0x0f, 0x02, 0x02, + 0x54, 0x0f, 0x02, 0x02, 0x58, 0x0f, 0x02, 0x02, 0xd8, 0x2b, 0x03, 0x03, 0xe0, 0x2b, 0x03, 0x03, 0xe8, 0x2b, 0x03, 0x03, 0x68, 0x09, 0x04, 0x03, 0x70, 0x09, 0x04, 0x03, 0x30, 0x23, 0x05, 0x04, + 0x40, 0x23, 0x05, 0x04, 0xf0, 0x03, 0x06, 0x04, 0x80, 0x3b, 0x08, 0x06, 0x00, 0x26, 0x0c, 0x08, 0x5c, 0x06, 0x00, 0x02, 0x60, 0x06, 0x00, 0x02, 0x64, 0x06, 0x00, 0x02, 0x68, 0x06, 0x00, 0x02, + 0x7c, 0x34, 0x01, 0x02, 0x80, 0x34, 0x01, 0x02, 0x84, 0x34, 0x01, 0x02, 0x88, 0x34, 0x01, 0x02, 0x8c, 0x34, 0x01, 0x02, 0x90, 0x34, 0x01, 0x02, 0x5c, 0x0f, 0x02, 0x02, 0x60, 0x0f, 0x02, 0x02, + 0x64, 0x0f, 0x02, 0x02, 0x68, 0x0f, 0x02, 0x02, 0xf0, 0x2b, 0x03, 0x03, 0xf8, 0x2b, 0x03, 0x03, 0x00, 0x2c, 0x03, 0x03, 0x78, 0x09, 0x04, 0x03, 0x80, 0x09, 0x04, 0x03, 0x50, 0x23, 0x05, 0x04, + 0x60, 0x23, 0x05, 0x04, 0x00, 0x04, 0x06, 0x04, 0xc0, 0x3b, 0x08, 0x06, 0x00, 0x27, 0x0c, 0x08, 0x6c, 0x06, 0x00, 0x02, 0x70, 0x06, 0x00, 0x02, 0x74, 0x06, 0x00, 0x02, 0x78, 0x06, 0x00, 0x02, + 0x94, 0x34, 0x01, 0x02, 0x98, 0x34, 0x01, 0x02, 0x9c, 0x34, 0x01, 0x02, 0xa0, 0x34, 0x01, 0x02, 0xa4, 0x34, 0x01, 0x02, 0xa8, 0x34, 0x01, 0x02, 0x6c, 0x0f, 0x02, 0x02, 0x70, 0x0f, 0x02, 0x02, + 0x74, 0x0f, 0x02, 0x02, 0x78, 0x0f, 0x02, 0x02, 0x08, 0x2c, 0x03, 0x03, 0x10, 0x2c, 0x03, 0x03, 0x18, 0x2c, 0x03, 0x03, 0x88, 0x09, 0x04, 0x03, 0x90, 0x09, 0x04, 0x03, 0x70, 0x23, 0x05, 0x04, + 0x80, 0x23, 0x05, 0x04, 0x10, 0x04, 0x06, 0x04, 0x00, 0x3c, 0x08, 0x06, 0x00, 0x28, 0x0c, 0x08, 0x7c, 0x06, 0x00, 0x02, 0x80, 0x06, 0x00, 0x02, 0x84, 0x06, 0x00, 0x02, 0x88, 0x06, 0x00, 0x02, + 0xac, 0x34, 0x01, 0x02, 0xb0, 0x34, 0x01, 0x02, 0xb4, 0x34, 0x01, 0x02, 0xb8, 0x34, 0x01, 0x02, 0xbc, 0x34, 0x01, 0x02, 0xc0, 0x34, 0x01, 0x02, 0x7c, 0x0f, 0x02, 0x02, 0x80, 0x0f, 0x02, 0x02, + 0x84, 0x0f, 0x02, 0x02, 0x88, 0x0f, 0x02, 0x02, 0x20, 0x2c, 0x03, 0x03, 0x28, 0x2c, 0x03, 0x03, 0x30, 0x2c, 0x03, 0x03, 0x98, 0x09, 0x04, 0x03, 0xa0, 0x09, 0x04, 0x03, 0x90, 0x23, 0x05, 0x04, + 0xa0, 0x23, 0x05, 0x04, 0x20, 0x04, 0x06, 0x04, 0x40, 0x3c, 0x08, 0x06, 0x00, 0x29, 0x0c, 0x08, 0x8c, 0x06, 0x00, 0x02, 0x90, 0x06, 0x00, 0x02, 0x94, 0x06, 0x00, 0x02, 0x98, 0x06, 0x00, 0x02, + 0xc4, 0x34, 0x01, 0x02, 0xc8, 0x34, 0x01, 0x02, 0xcc, 0x34, 0x01, 0x02, 0xd0, 0x34, 0x01, 0x02, 0xd4, 0x34, 0x01, 0x02, 0xd8, 0x34, 0x01, 0x02, 0x8c, 0x0f, 0x02, 0x02, 0x90, 0x0f, 0x02, 0x02, + 0x94, 0x0f, 0x02, 0x02, 0x98, 0x0f, 0x02, 0x02, 0x38, 0x2c, 0x03, 0x03, 0x40, 0x2c, 0x03, 0x03, 0x48, 0x2c, 0x03, 0x03, 0xa8, 0x09, 0x04, 0x03, 0xb0, 0x09, 0x04, 0x03, 0xb0, 0x23, 0x05, 0x04, + 0xc0, 0x23, 0x05, 0x04, 0x30, 0x04, 0x06, 0x04, 0x80, 0x3c, 0x08, 0x06, 0x00, 0x2a, 0x0c, 0x08, 0x9c, 0x06, 0x00, 0x02, 0xa0, 0x06, 0x00, 0x02, 0xa4, 0x06, 0x00, 0x02, 0xa8, 0x06, 0x00, 0x02, + 0xdc, 0x34, 0x01, 0x02, 0xe0, 0x34, 0x01, 0x02, 0xe4, 0x34, 0x01, 0x02, 0xe8, 0x34, 0x01, 0x02, 0xec, 0x34, 0x01, 0x02, 0xf0, 0x34, 0x01, 0x02, 0x9c, 0x0f, 0x02, 0x02, 0xa0, 0x0f, 0x02, 0x02, + 0xa4, 0x0f, 0x02, 0x02, 0xa8, 0x0f, 0x02, 0x02, 0x50, 0x2c, 0x03, 0x03, 0x58, 0x2c, 0x03, 0x03, 0x60, 0x2c, 0x03, 0x03, 0xb8, 0x09, 0x04, 0x03, 0xc0, 0x09, 0x04, 0x03, 0xd0, 0x23, 0x05, 0x04, + 0xe0, 0x23, 0x05, 0x04, 0x40, 0x04, 0x06, 0x04, 0xc0, 0x3c, 0x08, 0x06, 0x00, 0x2b, 0x0c, 0x08, 0xac, 0x06, 0x00, 0x02, 0xb0, 0x06, 0x00, 0x02, 0xb4, 0x06, 0x00, 0x02, 0xb8, 0x06, 0x00, 0x02, + 0xf4, 0x34, 0x01, 0x02, 0xf8, 0x34, 0x01, 0x02, 0xfc, 0x34, 0x01, 0x02, 0x00, 0x35, 0x01, 0x02, 0x04, 0x35, 0x01, 0x02, 0x08, 0x35, 0x01, 0x02, 0xac, 0x0f, 0x02, 0x02, 0xb0, 0x0f, 0x02, 0x02, + 0xb4, 0x0f, 0x02, 0x02, 0xb8, 0x0f, 0x02, 0x02, 0x68, 0x2c, 0x03, 0x03, 0x70, 0x2c, 0x03, 0x03, 0x78, 0x2c, 0x03, 0x03, 0xc8, 0x09, 0x04, 0x03, 0xd0, 0x09, 0x04, 0x03, 0xf0, 0x23, 0x05, 0x04, + 0x00, 0x24, 0x05, 0x04, 0x50, 0x04, 0x06, 0x04, 0x00, 0x3d, 0x08, 0x06, 0x00, 0x2c, 0x0c, 0x08, 0xbc, 0x06, 0x00, 0x02, 0xc0, 0x06, 0x00, 0x02, 0xc4, 0x06, 0x00, 0x02, 0xc8, 0x06, 0x00, 0x02, + 0x0c, 0x35, 0x01, 0x02, 0x10, 0x35, 0x01, 0x02, 0x14, 0x35, 0x01, 0x02, 0x18, 0x35, 0x01, 0x02, 0x1c, 0x35, 0x01, 0x02, 0x20, 0x35, 0x01, 0x02, 0xbc, 0x0f, 0x02, 0x02, 0xc0, 0x0f, 0x02, 0x02, + 0xc4, 0x0f, 0x02, 0x02, 0xc8, 0x0f, 0x02, 0x02, 0x80, 0x2c, 0x03, 0x03, 0x88, 0x2c, 0x03, 0x03, 0x90, 0x2c, 0x03, 0x03, 0xd8, 0x09, 0x04, 0x03, 0xe0, 0x09, 0x04, 0x03, 0x10, 0x24, 0x05, 0x04, + 0x20, 0x24, 0x05, 0x04, 0x60, 0x04, 0x06, 0x04, 0x40, 0x3d, 0x08, 0x06, 0x00, 0x2d, 0x0c, 0x08, 0xcc, 0x06, 0x00, 0x02, 0xd0, 0x06, 0x00, 0x02, 0xd4, 0x06, 0x00, 0x02, 0xd8, 0x06, 0x00, 0x02, + 0x24, 0x35, 0x01, 0x02, 0x28, 0x35, 0x01, 0x02, 0x2c, 0x35, 0x01, 0x02, 0x30, 0x35, 0x01, 0x02, 0x34, 0x35, 0x01, 0x02, 0x38, 0x35, 0x01, 0x02, 0xcc, 0x0f, 0x02, 0x02, 0xd0, 0x0f, 0x02, 0x02, + 0xd4, 0x0f, 0x02, 0x02, 0xd8, 0x0f, 0x02, 0x02, 0x98, 0x2c, 0x03, 0x03, 0xa0, 0x2c, 0x03, 0x03, 0xa8, 0x2c, 0x03, 0x03, 0xe8, 0x09, 0x04, 0x03, 0xf0, 0x09, 0x04, 0x03, 0x30, 0x24, 0x05, 0x04, + 0x40, 0x24, 0x05, 0x04, 0x70, 0x04, 0x06, 0x04, 0x80, 0x3d, 0x08, 0x06, 0x00, 0x06, 0x0d, 0x08, 0xdc, 0x06, 0x00, 0x02, 0xe0, 0x06, 0x00, 0x02, 0xe4, 0x06, 0x00, 0x02, 0xe8, 0x06, 0x00, 0x02, + 0x3c, 0x35, 0x01, 0x02, 0x40, 0x35, 0x01, 0x02, 0x44, 0x35, 0x01, 0x02, 0x48, 0x35, 0x01, 0x02, 0x4c, 0x35, 0x01, 0x02, 0x50, 0x35, 0x01, 0x02, 0xdc, 0x0f, 0x02, 0x02, 0xe0, 0x0f, 0x02, 0x02, + 0xe4, 0x0f, 0x02, 0x02, 0xe8, 0x0f, 0x02, 0x02, 0xb0, 0x2c, 0x03, 0x03, 0xb8, 0x2c, 0x03, 0x03, 0xc0, 0x2c, 0x03, 0x03, 0xf8, 0x09, 0x04, 0x03, 0x00, 0x0a, 0x04, 0x03, 0x50, 0x24, 0x05, 0x04, + 0x60, 0x24, 0x05, 0x04, 0x80, 0x04, 0x06, 0x04, 0xc0, 0x3d, 0x08, 0x06, 0x00, 0x07, 0x0d, 0x08, 0xec, 0x06, 0x00, 0x02, 0xf0, 0x06, 0x00, 0x02, 0xf4, 0x06, 0x00, 0x02, 0xf8, 0x06, 0x00, 0x02, + 0x54, 0x35, 0x01, 0x02, 0x58, 0x35, 0x01, 0x02, 0x5c, 0x35, 0x01, 0x02, 0x60, 0x35, 0x01, 0x02, 0x64, 0x35, 0x01, 0x02, 0x68, 0x35, 0x01, 0x02, 0xec, 0x0f, 0x02, 0x02, 0xf0, 0x0f, 0x02, 0x02, + 0xf4, 0x0f, 0x02, 0x02, 0xf8, 0x0f, 0x02, 0x02, 0xc8, 0x2c, 0x03, 0x03, 0xd0, 0x2c, 0x03, 0x03, 0xd8, 0x2c, 0x03, 0x03, 0x08, 0x0a, 0x04, 0x03, 0x10, 0x0a, 0x04, 0x03, 0x70, 0x24, 0x05, 0x04, + 0x80, 0x24, 0x05, 0x04, 0x90, 0x04, 0x06, 0x04, 0x00, 0x3e, 0x08, 0x06, 0x00, 0x08, 0x0d, 0x08, 0xfc, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x04, 0x07, 0x00, 0x02, 0x08, 0x07, 0x00, 0x02, + 0x6c, 0x35, 0x01, 0x02, 0x70, 0x35, 0x01, 0x02, 0x74, 0x35, 0x01, 0x02, 0x78, 0x35, 0x01, 0x02, 0x7c, 0x35, 0x01, 0x02, 0x80, 0x35, 0x01, 0x02, 0xfc, 0x0f, 0x02, 0x02, 0x00, 0x10, 0x02, 0x02, + 0x04, 0x10, 0x02, 0x02, 0x08, 0x10, 0x02, 0x02, 0xe0, 0x2c, 0x03, 0x03, 0xe8, 0x2c, 0x03, 0x03, 0xf0, 0x2c, 0x03, 0x03, 0x18, 0x0a, 0x04, 0x03, 0x20, 0x0a, 0x04, 0x03, 0x90, 0x24, 0x05, 0x04, + 0xa0, 0x24, 0x05, 0x04, 0xa0, 0x04, 0x06, 0x04, 0x40, 0x3e, 0x08, 0x06, 0x00, 0x09, 0x0d, 0x08, 0x0c, 0x07, 0x00, 0x02, 0x10, 0x07, 0x00, 0x02, 0x14, 0x07, 0x00, 0x02, 0x18, 0x07, 0x00, 0x02, + 0x84, 0x35, 0x01, 0x02, 0x88, 0x35, 0x01, 0x02, 0x8c, 0x35, 0x01, 0x02, 0x90, 0x35, 0x01, 0x02, 0x94, 0x35, 0x01, 0x02, 0x98, 0x35, 0x01, 0x02, 0x0c, 0x10, 0x02, 0x02, 0x10, 0x10, 0x02, 0x02, + 0x14, 0x10, 0x02, 0x02, 0x18, 0x10, 0x02, 0x02, 0xf8, 0x2c, 0x03, 0x03, 0x00, 0x2d, 0x03, 0x03, 0x08, 0x2d, 0x03, 0x03, 0x28, 0x0a, 0x04, 0x03, 0x30, 0x0a, 0x04, 0x03, 0xb0, 0x24, 0x05, 0x04, + 0xc0, 0x24, 0x05, 0x04, 0xb0, 0x04, 0x06, 0x04, 0x80, 0x3e, 0x08, 0x06, 0x00, 0x0a, 0x0d, 0x08, 0x1c, 0x07, 0x00, 0x02, 0x20, 0x07, 0x00, 0x02, 0x24, 0x07, 0x00, 0x02, 0x28, 0x07, 0x00, 0x02, + 0x9c, 0x35, 0x01, 0x02, 0xa0, 0x35, 0x01, 0x02, 0xa4, 0x35, 0x01, 0x02, 0xa8, 0x35, 0x01, 0x02, 0xac, 0x35, 0x01, 0x02, 0xb0, 0x35, 0x01, 0x02, 0x1c, 0x10, 0x02, 0x02, 0x20, 0x10, 0x02, 0x02, + 0x24, 0x10, 0x02, 0x02, 0x28, 0x10, 0x02, 0x02, 0x10, 0x2d, 0x03, 0x03, 0x18, 0x2d, 0x03, 0x03, 0x20, 0x2d, 0x03, 0x03, 0x38, 0x0a, 0x04, 0x03, 0x40, 0x0a, 0x04, 0x03, 0xd0, 0x24, 0x05, 0x04, + 0xe0, 0x24, 0x05, 0x04, 0xc0, 0x04, 0x06, 0x04, 0xc0, 0x3e, 0x08, 0x06, 0x00, 0x0b, 0x0d, 0x08, 0x2c, 0x07, 0x00, 0x02, 0x30, 0x07, 0x00, 0x02, 0x34, 0x07, 0x00, 0x02, 0x38, 0x07, 0x00, 0x02, + 0xb4, 0x35, 0x01, 0x02, 0xb8, 0x35, 0x01, 0x02, 0xbc, 0x35, 0x01, 0x02, 0xc0, 0x35, 0x01, 0x02, 0xc4, 0x35, 0x01, 0x02, 0xc8, 0x35, 0x01, 0x02, 0x2c, 0x10, 0x02, 0x02, 0x30, 0x10, 0x02, 0x02, + 0x34, 0x10, 0x02, 0x02, 0x38, 0x10, 0x02, 0x02, 0x28, 0x2d, 0x03, 0x03, 0x30, 0x2d, 0x03, 0x03, 0x38, 0x2d, 0x03, 0x03, 0x48, 0x0a, 0x04, 0x03, 0x50, 0x0a, 0x04, 0x03, 0xf0, 0x24, 0x05, 0x04, + 0x00, 0x25, 0x05, 0x04, 0xd0, 0x04, 0x06, 0x04, 0x00, 0x3f, 0x08, 0x06, 0x00, 0x20, 0x0e, 0x09, 0x3c, 0x07, 0x00, 0x02, 0x40, 0x07, 0x00, 0x02, 0x44, 0x07, 0x00, 0x02, 0xcc, 0x35, 0x01, 0x02, + 0xd0, 0x35, 0x01, 0x02, 0xd4, 0x35, 0x01, 0x02, 0xd8, 0x35, 0x01, 0x02, 0xdc, 0x35, 0x01, 0x02, 0xe0, 0x35, 0x01, 0x02, 0xe4, 0x35, 0x01, 0x02, 0x3c, 0x10, 0x02, 0x02, 0x40, 0x10, 0x02, 0x02, + 0x44, 0x10, 0x02, 0x02, 0x48, 0x10, 0x02, 0x02, 0x40, 0x2d, 0x03, 0x03, 0x48, 0x2d, 0x03, 0x03, 0x50, 0x2d, 0x03, 0x03, 0x58, 0x0a, 0x04, 0x03, 0x60, 0x0a, 0x04, 0x03, 0x10, 0x25, 0x05, 0x04, + 0x20, 0x25, 0x05, 0x04, 0xe0, 0x04, 0x06, 0x04, 0x40, 0x3f, 0x08, 0x06, 0x00, 0x22, 0x0e, 0x09, 0x48, 0x07, 0x00, 0x02, 0x4c, 0x07, 0x00, 0x02, 0x50, 0x07, 0x00, 0x02, 0xe8, 0x35, 0x01, 0x02, + 0xec, 0x35, 0x01, 0x02, 0xf0, 0x35, 0x01, 0x02, 0xf4, 0x35, 0x01, 0x02, 0xf8, 0x35, 0x01, 0x02, 0xfc, 0x35, 0x01, 0x02, 0x00, 0x36, 0x01, 0x02, 0x4c, 0x10, 0x02, 0x02, 0x50, 0x10, 0x02, 0x02, + 0x54, 0x10, 0x02, 0x02, 0x58, 0x10, 0x02, 0x02, 0x58, 0x2d, 0x03, 0x03, 0x60, 0x2d, 0x03, 0x03, 0x68, 0x2d, 0x03, 0x03, 0x68, 0x0a, 0x04, 0x03, 0x70, 0x0a, 0x04, 0x03, 0x30, 0x25, 0x05, 0x04, + 0x40, 0x25, 0x05, 0x04, 0xf0, 0x04, 0x06, 0x04, 0x80, 0x3f, 0x08, 0x06, 0x00, 0x24, 0x0e, 0x09, 0x54, 0x07, 0x00, 0x02, 0x58, 0x07, 0x00, 0x02, 0x5c, 0x07, 0x00, 0x02, 0x04, 0x36, 0x01, 0x02, + 0x08, 0x36, 0x01, 0x02, 0x0c, 0x36, 0x01, 0x02, 0x10, 0x36, 0x01, 0x02, 0x14, 0x36, 0x01, 0x02, 0x18, 0x36, 0x01, 0x02, 0x1c, 0x36, 0x01, 0x02, 0x5c, 0x10, 0x02, 0x02, 0x60, 0x10, 0x02, 0x02, + 0x64, 0x10, 0x02, 0x02, 0x68, 0x10, 0x02, 0x02, 0x70, 0x2d, 0x03, 0x03, 0x78, 0x2d, 0x03, 0x03, 0x80, 0x2d, 0x03, 0x03, 0x78, 0x0a, 0x04, 0x03, 0x80, 0x0a, 0x04, 0x03, 0x50, 0x25, 0x05, 0x04, + 0x60, 0x25, 0x05, 0x04, 0x00, 0x05, 0x06, 0x04, 0xc0, 0x3f, 0x08, 0x06, 0x00, 0x04, 0x0f, 0x09, 0x60, 0x07, 0x00, 0x02, 0x64, 0x07, 0x00, 0x02, 0x68, 0x07, 0x00, 0x02, 0x20, 0x36, 0x01, 0x02, + 0x24, 0x36, 0x01, 0x02, 0x28, 0x36, 0x01, 0x02, 0x2c, 0x36, 0x01, 0x02, 0x30, 0x36, 0x01, 0x02, 0x34, 0x36, 0x01, 0x02, 0x38, 0x36, 0x01, 0x02, 0x6c, 0x10, 0x02, 0x02, 0x70, 0x10, 0x02, 0x02, + 0x74, 0x10, 0x02, 0x02, 0x78, 0x10, 0x02, 0x02, 0x88, 0x2d, 0x03, 0x03, 0x90, 0x2d, 0x03, 0x03, 0x98, 0x2d, 0x03, 0x03, 0x88, 0x0a, 0x04, 0x03, 0x90, 0x0a, 0x04, 0x03, 0x70, 0x25, 0x05, 0x04, + 0x80, 0x25, 0x05, 0x04, 0x10, 0x05, 0x06, 0x04, 0x00, 0x00, 0x08, 0x05, 0x00, 0x06, 0x0f, 0x09, 0x6c, 0x07, 0x00, 0x02, 0x70, 0x07, 0x00, 0x02, 0x74, 0x07, 0x00, 0x02, 0x3c, 0x36, 0x01, 0x02, + 0x40, 0x36, 0x01, 0x02, 0x44, 0x36, 0x01, 0x02, 0x48, 0x36, 0x01, 0x02, 0x4c, 0x36, 0x01, 0x02, 0x50, 0x36, 0x01, 0x02, 0x54, 0x36, 0x01, 0x02, 0x7c, 0x10, 0x02, 0x02, 0x80, 0x10, 0x02, 0x02, + 0x84, 0x10, 0x02, 0x02, 0x88, 0x10, 0x02, 0x02, 0xa0, 0x2d, 0x03, 0x03, 0xa8, 0x2d, 0x03, 0x03, 0xb0, 0x2d, 0x03, 0x03, 0x98, 0x0a, 0x04, 0x03, 0xa0, 0x0a, 0x04, 0x03, 0x90, 0x25, 0x05, 0x04, + 0xa0, 0x25, 0x05, 0x04, 0x20, 0x05, 0x06, 0x04, 0x20, 0x00, 0x08, 0x05, 0x00, 0x08, 0x0f, 0x09, 0x78, 0x07, 0x00, 0x02, 0x7c, 0x07, 0x00, 0x02, 0x80, 0x07, 0x00, 0x02, 0x58, 0x36, 0x01, 0x02, + 0x5c, 0x36, 0x01, 0x02, 0x60, 0x36, 0x01, 0x02, 0x64, 0x36, 0x01, 0x02, 0x68, 0x36, 0x01, 0x02, 0x6c, 0x36, 0x01, 0x02, 0x70, 0x36, 0x01, 0x02, 0x8c, 0x10, 0x02, 0x02, 0x90, 0x10, 0x02, 0x02, + 0x94, 0x10, 0x02, 0x02, 0x98, 0x10, 0x02, 0x02, 0xb8, 0x2d, 0x03, 0x03, 0xc0, 0x2d, 0x03, 0x03, 0xc8, 0x2d, 0x03, 0x03, 0xa8, 0x0a, 0x04, 0x03, 0xb0, 0x0a, 0x04, 0x03, 0xb0, 0x25, 0x05, 0x04, + 0xc0, 0x25, 0x05, 0x04, 0x30, 0x05, 0x06, 0x04, 0x40, 0x00, 0x08, 0x05, 0x00, 0x20, 0x10, 0x0a, 0x84, 0x07, 0x00, 0x02, 0x88, 0x07, 0x00, 0x02, 0x8c, 0x07, 0x00, 0x02, 0x74, 0x36, 0x01, 0x02, + 0x78, 0x36, 0x01, 0x02, 0x7c, 0x36, 0x01, 0x02, 0x80, 0x36, 0x01, 0x02, 0x84, 0x36, 0x01, 0x02, 0x88, 0x36, 0x01, 0x02, 0x8c, 0x36, 0x01, 0x02, 0x9c, 0x10, 0x02, 0x02, 0xa0, 0x10, 0x02, 0x02, + 0xa4, 0x10, 0x02, 0x02, 0xa8, 0x10, 0x02, 0x02, 0xd0, 0x2d, 0x03, 0x03, 0xd8, 0x2d, 0x03, 0x03, 0xe0, 0x2d, 0x03, 0x03, 0xb8, 0x0a, 0x04, 0x03, 0xc0, 0x0a, 0x04, 0x03, 0xd0, 0x25, 0x05, 0x04, + 0xe0, 0x25, 0x05, 0x04, 0x40, 0x05, 0x06, 0x04, 0x60, 0x00, 0x08, 0x05, 0x00, 0x24, 0x10, 0x0a, 0x90, 0x07, 0x00, 0x02, 0x94, 0x07, 0x00, 0x02, 0x98, 0x07, 0x00, 0x02, 0x90, 0x36, 0x01, 0x02, + 0x94, 0x36, 0x01, 0x02, 0x98, 0x36, 0x01, 0x02, 0x9c, 0x36, 0x01, 0x02, 0xa0, 0x36, 0x01, 0x02, 0xa4, 0x36, 0x01, 0x02, 0xa8, 0x36, 0x01, 0x02, 0xac, 0x10, 0x02, 0x02, 0xb0, 0x10, 0x02, 0x02, + 0xb4, 0x10, 0x02, 0x02, 0xb8, 0x10, 0x02, 0x02, 0xe8, 0x2d, 0x03, 0x03, 0xf0, 0x2d, 0x03, 0x03, 0xf8, 0x2d, 0x03, 0x03, 0xc8, 0x0a, 0x04, 0x03, 0xd0, 0x0a, 0x04, 0x03, 0xf0, 0x25, 0x05, 0x04, + 0x00, 0x26, 0x05, 0x04, 0x50, 0x05, 0x06, 0x04, 0x80, 0x00, 0x08, 0x05, 0x00, 0x38, 0x11, 0x0b, 0x9c, 0x07, 0x00, 0x02, 0xa0, 0x07, 0x00, 0x02, 0xa4, 0x07, 0x00, 0x02, 0xac, 0x36, 0x01, 0x02, + 0xb0, 0x36, 0x01, 0x02, 0xb4, 0x36, 0x01, 0x02, 0xb8, 0x36, 0x01, 0x02, 0xbc, 0x36, 0x01, 0x02, 0xc0, 0x36, 0x01, 0x02, 0xc4, 0x36, 0x01, 0x02, 0xbc, 0x10, 0x02, 0x02, 0xc0, 0x10, 0x02, 0x02, + 0xc4, 0x10, 0x02, 0x02, 0xc8, 0x10, 0x02, 0x02, 0x00, 0x2e, 0x03, 0x03, 0x08, 0x2e, 0x03, 0x03, 0x10, 0x2e, 0x03, 0x03, 0xd8, 0x0a, 0x04, 0x03, 0xe0, 0x0a, 0x04, 0x03, 0x10, 0x26, 0x05, 0x04, + 0x20, 0x26, 0x05, 0x04, 0x60, 0x05, 0x06, 0x04, 0xa0, 0x00, 0x08, 0x05, 0x00, 0x00, 0x11, 0x0a, 0xa8, 0x07, 0x00, 0x02, 0xac, 0x07, 0x00, 0x02, 0xb0, 0x07, 0x00, 0x02, 0xc8, 0x36, 0x01, 0x02, + 0xcc, 0x36, 0x01, 0x02, 0xd0, 0x36, 0x01, 0x02, 0xd4, 0x36, 0x01, 0x02, 0xd8, 0x36, 0x01, 0x02, 0xdc, 0x36, 0x01, 0x02, 0xe0, 0x36, 0x01, 0x02, 0xcc, 0x10, 0x02, 0x02, 0xd0, 0x10, 0x02, 0x02, + 0xd4, 0x10, 0x02, 0x02, 0xd8, 0x10, 0x02, 0x02, 0x18, 0x2e, 0x03, 0x03, 0x20, 0x2e, 0x03, 0x03, 0x28, 0x2e, 0x03, 0x03, 0xe8, 0x0a, 0x04, 0x03, 0xf0, 0x0a, 0x04, 0x03, 0x30, 0x26, 0x05, 0x04, + 0x40, 0x26, 0x05, 0x04, 0x70, 0x05, 0x06, 0x04, 0xc0, 0x00, 0x08, 0x05, 0x00, 0x30, 0x13, 0x0c, 0xb4, 0x07, 0x00, 0x02, 0xb8, 0x07, 0x00, 0x02, 0xbc, 0x07, 0x00, 0x02, 0xe4, 0x36, 0x01, 0x02, + 0xe8, 0x36, 0x01, 0x02, 0xec, 0x36, 0x01, 0x02, 0xf0, 0x36, 0x01, 0x02, 0xf4, 0x36, 0x01, 0x02, 0xf8, 0x36, 0x01, 0x02, 0xfc, 0x36, 0x01, 0x02, 0xdc, 0x10, 0x02, 0x02, 0xe0, 0x10, 0x02, 0x02, + 0xe4, 0x10, 0x02, 0x02, 0xe8, 0x10, 0x02, 0x02, 0x30, 0x2e, 0x03, 0x03, 0x38, 0x2e, 0x03, 0x03, 0x40, 0x2e, 0x03, 0x03, 0xf8, 0x0a, 0x04, 0x03, 0x00, 0x0b, 0x04, 0x03, 0x50, 0x26, 0x05, 0x04, + 0x60, 0x26, 0x05, 0x04, 0x80, 0x05, 0x06, 0x04, 0xe0, 0x00, 0x08, 0x05, 0x00, 0x20, 0x15, 0x0d, 0xc0, 0x07, 0x00, 0x02, 0xc4, 0x07, 0x00, 0x02, 0xc8, 0x07, 0x00, 0x02, 0x00, 0x37, 0x01, 0x02, + 0x04, 0x37, 0x01, 0x02, 0x08, 0x37, 0x01, 0x02, 0x0c, 0x37, 0x01, 0x02, 0x10, 0x37, 0x01, 0x02, 0x14, 0x37, 0x01, 0x02, 0x18, 0x37, 0x01, 0x02, 0xec, 0x10, 0x02, 0x02, 0xf0, 0x10, 0x02, 0x02, + 0xf4, 0x10, 0x02, 0x02, 0xf8, 0x10, 0x02, 0x02, 0x48, 0x2e, 0x03, 0x03, 0x50, 0x2e, 0x03, 0x03, 0x58, 0x2e, 0x03, 0x03, 0x08, 0x0b, 0x04, 0x03, 0x10, 0x0b, 0x04, 0x03, 0x70, 0x26, 0x05, 0x04, + 0x80, 0x26, 0x05, 0x04, 0x20, 0x1e, 0x07, 0x05, 0x00, 0x01, 0x08, 0x05, 0xcc, 0x07, 0x00, 0x02, 0xd0, 0x07, 0x00, 0x02, 0xd4, 0x07, 0x00, 0x02, 0xd8, 0x07, 0x00, 0x02, 0x1c, 0x37, 0x01, 0x02, + 0x20, 0x37, 0x01, 0x02, 0x24, 0x37, 0x01, 0x02, 0x28, 0x37, 0x01, 0x02, 0x2c, 0x37, 0x01, 0x02, 0x30, 0x37, 0x01, 0x02, 0x34, 0x37, 0x01, 0x02, 0xfc, 0x10, 0x02, 0x02, 0x00, 0x11, 0x02, 0x02, + 0x04, 0x11, 0x02, 0x02, 0x08, 0x11, 0x02, 0x02, 0x60, 0x2e, 0x03, 0x03, 0x68, 0x2e, 0x03, 0x03, 0x70, 0x2e, 0x03, 0x03, 0x18, 0x0b, 0x04, 0x03, 0x20, 0x0b, 0x04, 0x03, 0x90, 0x26, 0x05, 0x04, + 0xa0, 0x26, 0x05, 0x04, 0x40, 0x1e, 0x07, 0x05, 0x20, 0x01, 0x08, 0x05, 0xdc, 0x07, 0x00, 0x02, 0xe0, 0x07, 0x00, 0x02, 0xe4, 0x07, 0x00, 0x02, 0xe8, 0x07, 0x00, 0x02, 0x38, 0x37, 0x01, 0x02, + 0x3c, 0x37, 0x01, 0x02, 0x40, 0x37, 0x01, 0x02, 0x44, 0x37, 0x01, 0x02, 0x48, 0x37, 0x01, 0x02, 0x4c, 0x37, 0x01, 0x02, 0x50, 0x37, 0x01, 0x02, 0x0c, 0x11, 0x02, 0x02, 0x10, 0x11, 0x02, 0x02, + 0x14, 0x11, 0x02, 0x02, 0x18, 0x11, 0x02, 0x02, 0x78, 0x2e, 0x03, 0x03, 0x80, 0x2e, 0x03, 0x03, 0x88, 0x2e, 0x03, 0x03, 0x28, 0x0b, 0x04, 0x03, 0x30, 0x0b, 0x04, 0x03, 0xb0, 0x26, 0x05, 0x04, + 0xc0, 0x26, 0x05, 0x04, 0x60, 0x1e, 0x07, 0x05, 0x40, 0x01, 0x08, 0x05, 0xec, 0x07, 0x00, 0x02, 0xf0, 0x07, 0x00, 0x02, 0xf4, 0x07, 0x00, 0x02, 0xf8, 0x07, 0x00, 0x02, 0x54, 0x37, 0x01, 0x02, + 0x58, 0x37, 0x01, 0x02, 0x5c, 0x37, 0x01, 0x02, 0x60, 0x37, 0x01, 0x02, 0x64, 0x37, 0x01, 0x02, 0x68, 0x37, 0x01, 0x02, 0x6c, 0x37, 0x01, 0x02, 0x1c, 0x11, 0x02, 0x02, 0x20, 0x11, 0x02, 0x02, + 0x24, 0x11, 0x02, 0x02, 0x28, 0x11, 0x02, 0x02, 0x90, 0x2e, 0x03, 0x03, 0x98, 0x2e, 0x03, 0x03, 0xa0, 0x2e, 0x03, 0x03, 0x38, 0x0b, 0x04, 0x03, 0x40, 0x0b, 0x04, 0x03, 0xd0, 0x26, 0x05, 0x04, + 0xe0, 0x26, 0x05, 0x04, 0x80, 0x1e, 0x07, 0x05, 0x60, 0x01, 0x08, 0x05, 0xfc, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x04, 0x08, 0x00, 0x02, 0x08, 0x08, 0x00, 0x02, 0x70, 0x37, 0x01, 0x02, + 0x74, 0x37, 0x01, 0x02, 0x78, 0x37, 0x01, 0x02, 0x7c, 0x37, 0x01, 0x02, 0x80, 0x37, 0x01, 0x02, 0x84, 0x37, 0x01, 0x02, 0x88, 0x37, 0x01, 0x02, 0x2c, 0x11, 0x02, 0x02, 0x30, 0x11, 0x02, 0x02, + 0x34, 0x11, 0x02, 0x02, 0x38, 0x11, 0x02, 0x02, 0xa8, 0x2e, 0x03, 0x03, 0xb0, 0x2e, 0x03, 0x03, 0xb8, 0x2e, 0x03, 0x03, 0x48, 0x0b, 0x04, 0x03, 0x50, 0x0b, 0x04, 0x03, 0xf0, 0x26, 0x05, 0x04, + 0x00, 0x27, 0x05, 0x04, 0xa0, 0x1e, 0x07, 0x05, 0x80, 0x01, 0x08, 0x05, 0x0c, 0x08, 0x00, 0x02, 0x10, 0x08, 0x00, 0x02, 0x14, 0x08, 0x00, 0x02, 0x18, 0x08, 0x00, 0x02, 0x8c, 0x37, 0x01, 0x02, + 0x90, 0x37, 0x01, 0x02, 0x94, 0x37, 0x01, 0x02, 0x98, 0x37, 0x01, 0x02, 0x9c, 0x37, 0x01, 0x02, 0xa0, 0x37, 0x01, 0x02, 0xa4, 0x37, 0x01, 0x02, 0x3c, 0x11, 0x02, 0x02, 0x40, 0x11, 0x02, 0x02, + 0x44, 0x11, 0x02, 0x02, 0x48, 0x11, 0x02, 0x02, 0xc0, 0x2e, 0x03, 0x03, 0xc8, 0x2e, 0x03, 0x03, 0xd0, 0x2e, 0x03, 0x03, 0x58, 0x0b, 0x04, 0x03, 0x60, 0x0b, 0x04, 0x03, 0x10, 0x27, 0x05, 0x04, + 0x90, 0x05, 0x06, 0x04, 0xc0, 0x1e, 0x07, 0x05, 0xa0, 0x01, 0x08, 0x05, 0x1c, 0x08, 0x00, 0x02, 0x20, 0x08, 0x00, 0x02, 0x24, 0x08, 0x00, 0x02, 0x28, 0x08, 0x00, 0x02, 0xa8, 0x37, 0x01, 0x02, + 0xac, 0x37, 0x01, 0x02, 0xb0, 0x37, 0x01, 0x02, 0xb4, 0x37, 0x01, 0x02, 0xb8, 0x37, 0x01, 0x02, 0xbc, 0x37, 0x01, 0x02, 0xc0, 0x37, 0x01, 0x02, 0x4c, 0x11, 0x02, 0x02, 0x50, 0x11, 0x02, 0x02, + 0x54, 0x11, 0x02, 0x02, 0x58, 0x11, 0x02, 0x02, 0xd8, 0x2e, 0x03, 0x03, 0xe0, 0x2e, 0x03, 0x03, 0xe8, 0x2e, 0x03, 0x03, 0x68, 0x0b, 0x04, 0x03, 0x70, 0x0b, 0x04, 0x03, 0x20, 0x27, 0x05, 0x04, + 0xa0, 0x05, 0x06, 0x04, 0xe0, 0x1e, 0x07, 0x05, 0x00, 0x17, 0x09, 0x06, 0x2c, 0x08, 0x00, 0x02, 0x30, 0x08, 0x00, 0x02, 0x34, 0x08, 0x00, 0x02, 0x38, 0x08, 0x00, 0x02, 0xc4, 0x37, 0x01, 0x02, + 0xc8, 0x37, 0x01, 0x02, 0xcc, 0x37, 0x01, 0x02, 0xd0, 0x37, 0x01, 0x02, 0xd4, 0x37, 0x01, 0x02, 0xd8, 0x37, 0x01, 0x02, 0xdc, 0x37, 0x01, 0x02, 0x5c, 0x11, 0x02, 0x02, 0x60, 0x11, 0x02, 0x02, + 0x64, 0x11, 0x02, 0x02, 0x68, 0x11, 0x02, 0x02, 0xf0, 0x2e, 0x03, 0x03, 0xf8, 0x2e, 0x03, 0x03, 0x00, 0x2f, 0x03, 0x03, 0x78, 0x0b, 0x04, 0x03, 0x80, 0x0b, 0x04, 0x03, 0x30, 0x27, 0x05, 0x04, + 0xb0, 0x05, 0x06, 0x04, 0x00, 0x1f, 0x07, 0x05, 0x40, 0x17, 0x09, 0x06, 0x3c, 0x08, 0x00, 0x02, 0x40, 0x08, 0x00, 0x02, 0x44, 0x08, 0x00, 0x02, 0x48, 0x08, 0x00, 0x02, 0xe0, 0x37, 0x01, 0x02, + 0xe4, 0x37, 0x01, 0x02, 0xe8, 0x37, 0x01, 0x02, 0xec, 0x37, 0x01, 0x02, 0xf0, 0x37, 0x01, 0x02, 0xf4, 0x37, 0x01, 0x02, 0xf8, 0x37, 0x01, 0x02, 0x6c, 0x11, 0x02, 0x02, 0x70, 0x11, 0x02, 0x02, + 0x74, 0x11, 0x02, 0x02, 0x78, 0x11, 0x02, 0x02, 0x08, 0x2f, 0x03, 0x03, 0x10, 0x2f, 0x03, 0x03, 0x18, 0x2f, 0x03, 0x03, 0x88, 0x0b, 0x04, 0x03, 0x90, 0x0b, 0x04, 0x03, 0x40, 0x27, 0x05, 0x04, + 0xc0, 0x05, 0x06, 0x04, 0x20, 0x1f, 0x07, 0x05, 0x80, 0x17, 0x09, 0x06, 0x4c, 0x08, 0x00, 0x02, 0x50, 0x08, 0x00, 0x02, 0x54, 0x08, 0x00, 0x02, 0x58, 0x08, 0x00, 0x02, 0xfc, 0x37, 0x01, 0x02, + 0x00, 0x38, 0x01, 0x02, 0x04, 0x38, 0x01, 0x02, 0x08, 0x38, 0x01, 0x02, 0x0c, 0x38, 0x01, 0x02, 0x10, 0x38, 0x01, 0x02, 0x14, 0x38, 0x01, 0x02, 0x7c, 0x11, 0x02, 0x02, 0x80, 0x11, 0x02, 0x02, + 0x84, 0x11, 0x02, 0x02, 0x88, 0x11, 0x02, 0x02, 0x20, 0x2f, 0x03, 0x03, 0x28, 0x2f, 0x03, 0x03, 0x30, 0x2f, 0x03, 0x03, 0x98, 0x0b, 0x04, 0x03, 0xa0, 0x0b, 0x04, 0x03, 0x50, 0x27, 0x05, 0x04, + 0xd0, 0x05, 0x06, 0x04, 0x40, 0x1f, 0x07, 0x05, 0xc0, 0x17, 0x09, 0x06, 0x5c, 0x08, 0x00, 0x02, 0x60, 0x08, 0x00, 0x02, 0x64, 0x08, 0x00, 0x02, 0x68, 0x08, 0x00, 0x02, 0x18, 0x38, 0x01, 0x02, + 0x1c, 0x38, 0x01, 0x02, 0x20, 0x38, 0x01, 0x02, 0x24, 0x38, 0x01, 0x02, 0x28, 0x38, 0x01, 0x02, 0x2c, 0x38, 0x01, 0x02, 0x30, 0x38, 0x01, 0x02, 0x8c, 0x11, 0x02, 0x02, 0x90, 0x11, 0x02, 0x02, + 0x94, 0x11, 0x02, 0x02, 0x98, 0x11, 0x02, 0x02, 0x38, 0x2f, 0x03, 0x03, 0x40, 0x2f, 0x03, 0x03, 0x48, 0x2f, 0x03, 0x03, 0xa8, 0x0b, 0x04, 0x03, 0xb0, 0x0b, 0x04, 0x03, 0x60, 0x27, 0x05, 0x04, + 0xe0, 0x05, 0x06, 0x04, 0x60, 0x1f, 0x07, 0x05, 0x00, 0x18, 0x09, 0x06, 0x6c, 0x08, 0x00, 0x02, 0x70, 0x08, 0x00, 0x02, 0x74, 0x08, 0x00, 0x02, 0x78, 0x08, 0x00, 0x02, 0x34, 0x38, 0x01, 0x02, + 0x38, 0x38, 0x01, 0x02, 0x3c, 0x38, 0x01, 0x02, 0x40, 0x38, 0x01, 0x02, 0x44, 0x38, 0x01, 0x02, 0x48, 0x38, 0x01, 0x02, 0x4c, 0x38, 0x01, 0x02, 0x9c, 0x11, 0x02, 0x02, 0xa0, 0x11, 0x02, 0x02, + 0xa4, 0x11, 0x02, 0x02, 0xa8, 0x11, 0x02, 0x02, 0x50, 0x2f, 0x03, 0x03, 0x58, 0x2f, 0x03, 0x03, 0x60, 0x2f, 0x03, 0x03, 0xb8, 0x0b, 0x04, 0x03, 0xc0, 0x0b, 0x04, 0x03, 0x70, 0x27, 0x05, 0x04, + 0xf0, 0x05, 0x06, 0x04, 0x80, 0x1f, 0x07, 0x05, 0x40, 0x18, 0x09, 0x06, 0x7c, 0x08, 0x00, 0x02, 0x80, 0x08, 0x00, 0x02, 0x84, 0x08, 0x00, 0x02, 0x88, 0x08, 0x00, 0x02, 0x50, 0x38, 0x01, 0x02, + 0x54, 0x38, 0x01, 0x02, 0x58, 0x38, 0x01, 0x02, 0x5c, 0x38, 0x01, 0x02, 0x60, 0x38, 0x01, 0x02, 0x64, 0x38, 0x01, 0x02, 0x68, 0x38, 0x01, 0x02, 0xac, 0x11, 0x02, 0x02, 0xb0, 0x11, 0x02, 0x02, + 0xb4, 0x11, 0x02, 0x02, 0xb8, 0x11, 0x02, 0x02, 0x68, 0x2f, 0x03, 0x03, 0x70, 0x2f, 0x03, 0x03, 0x78, 0x2f, 0x03, 0x03, 0xc8, 0x0b, 0x04, 0x03, 0xd0, 0x0b, 0x04, 0x03, 0x80, 0x27, 0x05, 0x04, + 0x00, 0x06, 0x06, 0x04, 0xa0, 0x1f, 0x07, 0x05, 0x80, 0x18, 0x09, 0x06, 0x8c, 0x08, 0x00, 0x02, 0x90, 0x08, 0x00, 0x02, 0x94, 0x08, 0x00, 0x02, 0x98, 0x08, 0x00, 0x02, 0x6c, 0x38, 0x01, 0x02, + 0x70, 0x38, 0x01, 0x02, 0x74, 0x38, 0x01, 0x02, 0x78, 0x38, 0x01, 0x02, 0x7c, 0x38, 0x01, 0x02, 0x80, 0x38, 0x01, 0x02, 0x84, 0x38, 0x01, 0x02, 0xbc, 0x11, 0x02, 0x02, 0xc0, 0x11, 0x02, 0x02, + 0xc4, 0x11, 0x02, 0x02, 0xc8, 0x11, 0x02, 0x02, 0x80, 0x2f, 0x03, 0x03, 0x88, 0x2f, 0x03, 0x03, 0x90, 0x2f, 0x03, 0x03, 0xd8, 0x0b, 0x04, 0x03, 0xe0, 0x0b, 0x04, 0x03, 0x90, 0x27, 0x05, 0x04, + 0x10, 0x06, 0x06, 0x04, 0xc0, 0x1f, 0x07, 0x05, 0xc0, 0x18, 0x09, 0x06, 0x9c, 0x08, 0x00, 0x02, 0xa0, 0x08, 0x00, 0x02, 0xa4, 0x08, 0x00, 0x02, 0xa8, 0x08, 0x00, 0x02, 0x88, 0x38, 0x01, 0x02, + 0x8c, 0x38, 0x01, 0x02, 0x90, 0x38, 0x01, 0x02, 0x94, 0x38, 0x01, 0x02, 0x98, 0x38, 0x01, 0x02, 0x9c, 0x38, 0x01, 0x02, 0xa0, 0x38, 0x01, 0x02, 0xcc, 0x11, 0x02, 0x02, 0xd0, 0x11, 0x02, 0x02, + 0xd4, 0x11, 0x02, 0x02, 0xd8, 0x11, 0x02, 0x02, 0x98, 0x2f, 0x03, 0x03, 0xa0, 0x2f, 0x03, 0x03, 0xa8, 0x2f, 0x03, 0x03, 0xe8, 0x0b, 0x04, 0x03, 0xf0, 0x0b, 0x04, 0x03, 0xa0, 0x27, 0x05, 0x04, + 0x20, 0x06, 0x06, 0x04, 0xe0, 0x1f, 0x07, 0x05, 0x00, 0x19, 0x09, 0x06, 0xac, 0x08, 0x00, 0x02, 0xb0, 0x08, 0x00, 0x02, 0xb4, 0x08, 0x00, 0x02, 0xb8, 0x08, 0x00, 0x02, 0xa4, 0x38, 0x01, 0x02, + 0xa8, 0x38, 0x01, 0x02, 0xac, 0x38, 0x01, 0x02, 0xb0, 0x38, 0x01, 0x02, 0xb4, 0x38, 0x01, 0x02, 0xb8, 0x38, 0x01, 0x02, 0xbc, 0x38, 0x01, 0x02, 0xdc, 0x11, 0x02, 0x02, 0xe0, 0x11, 0x02, 0x02, + 0xe4, 0x11, 0x02, 0x02, 0xe8, 0x11, 0x02, 0x02, 0xb0, 0x2f, 0x03, 0x03, 0xb8, 0x2f, 0x03, 0x03, 0xc0, 0x2f, 0x03, 0x03, 0xf8, 0x0b, 0x04, 0x03, 0x00, 0x0c, 0x04, 0x03, 0xb0, 0x27, 0x05, 0x04, + 0x30, 0x06, 0x06, 0x04, 0x00, 0x20, 0x07, 0x05, 0x40, 0x19, 0x09, 0x06, 0xbc, 0x08, 0x00, 0x02, 0xc0, 0x08, 0x00, 0x02, 0xc4, 0x08, 0x00, 0x02, 0xc8, 0x08, 0x00, 0x02, 0xc0, 0x38, 0x01, 0x02, + 0xc4, 0x38, 0x01, 0x02, 0xc8, 0x38, 0x01, 0x02, 0xcc, 0x38, 0x01, 0x02, 0xd0, 0x38, 0x01, 0x02, 0xd4, 0x38, 0x01, 0x02, 0xd8, 0x38, 0x01, 0x02, 0xec, 0x11, 0x02, 0x02, 0xf0, 0x11, 0x02, 0x02, + 0xf4, 0x11, 0x02, 0x02, 0xf8, 0x11, 0x02, 0x02, 0xc8, 0x2f, 0x03, 0x03, 0xd0, 0x2f, 0x03, 0x03, 0xd8, 0x2f, 0x03, 0x03, 0x08, 0x0c, 0x04, 0x03, 0x10, 0x0c, 0x04, 0x03, 0xc0, 0x27, 0x05, 0x04, + 0x40, 0x06, 0x06, 0x04, 0x20, 0x20, 0x07, 0x05, 0x80, 0x19, 0x09, 0x06, 0xcc, 0x08, 0x00, 0x02, 0xd0, 0x08, 0x00, 0x02, 0xd4, 0x08, 0x00, 0x02, 0xd8, 0x08, 0x00, 0x02, 0xdc, 0x38, 0x01, 0x02, + 0xe0, 0x38, 0x01, 0x02, 0xe4, 0x38, 0x01, 0x02, 0xe8, 0x38, 0x01, 0x02, 0xec, 0x38, 0x01, 0x02, 0xf0, 0x38, 0x01, 0x02, 0xf4, 0x38, 0x01, 0x02, 0xfc, 0x11, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, + 0x04, 0x12, 0x02, 0x02, 0x08, 0x12, 0x02, 0x02, 0xe0, 0x2f, 0x03, 0x03, 0xe8, 0x2f, 0x03, 0x03, 0xf0, 0x2f, 0x03, 0x03, 0x18, 0x0c, 0x04, 0x03, 0x20, 0x0c, 0x04, 0x03, 0xd0, 0x27, 0x05, 0x04, + 0x50, 0x06, 0x06, 0x04, 0x40, 0x20, 0x07, 0x05, 0xc0, 0x19, 0x09, 0x06, 0xdc, 0x08, 0x00, 0x02, 0xe0, 0x08, 0x00, 0x02, 0xe4, 0x08, 0x00, 0x02, 0xe8, 0x08, 0x00, 0x02, 0xf8, 0x38, 0x01, 0x02, + 0xfc, 0x38, 0x01, 0x02, 0x00, 0x39, 0x01, 0x02, 0x04, 0x39, 0x01, 0x02, 0x08, 0x39, 0x01, 0x02, 0x0c, 0x39, 0x01, 0x02, 0x10, 0x39, 0x01, 0x02, 0x0c, 0x12, 0x02, 0x02, 0x10, 0x12, 0x02, 0x02, + 0x14, 0x12, 0x02, 0x02, 0x18, 0x12, 0x02, 0x02, 0xf8, 0x2f, 0x03, 0x03, 0x00, 0x30, 0x03, 0x03, 0x08, 0x30, 0x03, 0x03, 0x28, 0x0c, 0x04, 0x03, 0x30, 0x0c, 0x04, 0x03, 0xe0, 0x27, 0x05, 0x04, + 0x60, 0x06, 0x06, 0x04, 0x60, 0x20, 0x07, 0x05, 0x00, 0x1a, 0x09, 0x06, 0xec, 0x08, 0x00, 0x02, 0xf0, 0x08, 0x00, 0x02, 0xf4, 0x08, 0x00, 0x02, 0xf8, 0x08, 0x00, 0x02, 0x14, 0x39, 0x01, 0x02, + 0x18, 0x39, 0x01, 0x02, 0x1c, 0x39, 0x01, 0x02, 0x20, 0x39, 0x01, 0x02, 0x24, 0x39, 0x01, 0x02, 0x28, 0x39, 0x01, 0x02, 0x2c, 0x39, 0x01, 0x02, 0x1c, 0x12, 0x02, 0x02, 0x20, 0x12, 0x02, 0x02, + 0x24, 0x12, 0x02, 0x02, 0x28, 0x12, 0x02, 0x02, 0x10, 0x30, 0x03, 0x03, 0x18, 0x30, 0x03, 0x03, 0x20, 0x30, 0x03, 0x03, 0x38, 0x0c, 0x04, 0x03, 0x40, 0x0c, 0x04, 0x03, 0xf0, 0x27, 0x05, 0x04, + 0x70, 0x06, 0x06, 0x04, 0x80, 0x20, 0x07, 0x05, 0x40, 0x1a, 0x09, 0x06, 0xfc, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x02, 0x04, 0x09, 0x00, 0x02, 0x08, 0x09, 0x00, 0x02, 0x30, 0x39, 0x01, 0x02, + 0x34, 0x39, 0x01, 0x02, 0x38, 0x39, 0x01, 0x02, 0x3c, 0x39, 0x01, 0x02, 0x40, 0x39, 0x01, 0x02, 0x44, 0x39, 0x01, 0x02, 0x48, 0x39, 0x01, 0x02, 0x2c, 0x12, 0x02, 0x02, 0x30, 0x12, 0x02, 0x02, + 0x34, 0x12, 0x02, 0x02, 0x38, 0x12, 0x02, 0x02, 0x28, 0x30, 0x03, 0x03, 0x30, 0x30, 0x03, 0x03, 0x38, 0x30, 0x03, 0x03, 0x48, 0x0c, 0x04, 0x03, 0x50, 0x0c, 0x04, 0x03, 0x00, 0x28, 0x05, 0x04, + 0x80, 0x06, 0x06, 0x04, 0xa0, 0x20, 0x07, 0x05, 0x80, 0x1a, 0x09, 0x06, 0x0c, 0x09, 0x00, 0x02, 0x10, 0x09, 0x00, 0x02, 0x14, 0x09, 0x00, 0x02, 0x18, 0x09, 0x00, 0x02, 0x4c, 0x39, 0x01, 0x02, + 0x50, 0x39, 0x01, 0x02, 0x54, 0x39, 0x01, 0x02, 0x58, 0x39, 0x01, 0x02, 0x5c, 0x39, 0x01, 0x02, 0x60, 0x39, 0x01, 0x02, 0x64, 0x39, 0x01, 0x02, 0x3c, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x02, + 0x44, 0x12, 0x02, 0x02, 0x48, 0x12, 0x02, 0x02, 0x40, 0x30, 0x03, 0x03, 0x48, 0x30, 0x03, 0x03, 0x50, 0x30, 0x03, 0x03, 0x58, 0x0c, 0x04, 0x03, 0x60, 0x0c, 0x04, 0x03, 0x10, 0x28, 0x05, 0x04, + 0x90, 0x06, 0x06, 0x04, 0xc0, 0x20, 0x07, 0x05, 0xc0, 0x1a, 0x09, 0x06, 0x1c, 0x09, 0x00, 0x02, 0x20, 0x09, 0x00, 0x02, 0x24, 0x09, 0x00, 0x02, 0x28, 0x09, 0x00, 0x02, 0x68, 0x39, 0x01, 0x02, + 0x6c, 0x39, 0x01, 0x02, 0x70, 0x39, 0x01, 0x02, 0x74, 0x39, 0x01, 0x02, 0x78, 0x39, 0x01, 0x02, 0x7c, 0x39, 0x01, 0x02, 0x80, 0x39, 0x01, 0x02, 0x4c, 0x12, 0x02, 0x02, 0x50, 0x12, 0x02, 0x02, + 0x54, 0x12, 0x02, 0x02, 0x58, 0x12, 0x02, 0x02, 0x58, 0x30, 0x03, 0x03, 0x60, 0x30, 0x03, 0x03, 0x68, 0x30, 0x03, 0x03, 0x68, 0x0c, 0x04, 0x03, 0x70, 0x0c, 0x04, 0x03, 0x20, 0x28, 0x05, 0x04, + 0xa0, 0x06, 0x06, 0x04, 0xe0, 0x20, 0x07, 0x05, 0x00, 0x1b, 0x09, 0x06, 0x2c, 0x09, 0x00, 0x02, 0x30, 0x09, 0x00, 0x02, 0x34, 0x09, 0x00, 0x02, 0x38, 0x09, 0x00, 0x02, 0x84, 0x39, 0x01, 0x02, + 0x88, 0x39, 0x01, 0x02, 0x8c, 0x39, 0x01, 0x02, 0x90, 0x39, 0x01, 0x02, 0x94, 0x39, 0x01, 0x02, 0x98, 0x39, 0x01, 0x02, 0x9c, 0x39, 0x01, 0x02, 0x5c, 0x12, 0x02, 0x02, 0x60, 0x12, 0x02, 0x02, + 0x64, 0x12, 0x02, 0x02, 0x68, 0x12, 0x02, 0x02, 0x70, 0x30, 0x03, 0x03, 0x78, 0x30, 0x03, 0x03, 0x80, 0x30, 0x03, 0x03, 0x78, 0x0c, 0x04, 0x03, 0x80, 0x0c, 0x04, 0x03, 0x30, 0x28, 0x05, 0x04, + 0xb0, 0x06, 0x06, 0x04, 0x00, 0x21, 0x07, 0x05, 0x40, 0x1b, 0x09, 0x06, 0x3c, 0x09, 0x00, 0x02, 0x40, 0x09, 0x00, 0x02, 0x44, 0x09, 0x00, 0x02, 0x48, 0x09, 0x00, 0x02, 0xa0, 0x39, 0x01, 0x02, + 0xa4, 0x39, 0x01, 0x02, 0xa8, 0x39, 0x01, 0x02, 0xac, 0x39, 0x01, 0x02, 0xb0, 0x39, 0x01, 0x02, 0xb4, 0x39, 0x01, 0x02, 0xb8, 0x39, 0x01, 0x02, 0x6c, 0x12, 0x02, 0x02, 0x70, 0x12, 0x02, 0x02, + 0x74, 0x12, 0x02, 0x02, 0x78, 0x12, 0x02, 0x02, 0x88, 0x30, 0x03, 0x03, 0x90, 0x30, 0x03, 0x03, 0x98, 0x30, 0x03, 0x03, 0x88, 0x0c, 0x04, 0x03, 0x90, 0x0c, 0x04, 0x03, 0x40, 0x28, 0x05, 0x04, + 0xc0, 0x06, 0x06, 0x04, 0x20, 0x21, 0x07, 0x05, 0x80, 0x1b, 0x09, 0x06, 0x4c, 0x09, 0x00, 0x02, 0x50, 0x09, 0x00, 0x02, 0x54, 0x09, 0x00, 0x02, 0x58, 0x09, 0x00, 0x02, 0xbc, 0x39, 0x01, 0x02, + 0xc0, 0x39, 0x01, 0x02, 0xc4, 0x39, 0x01, 0x02, 0xc8, 0x39, 0x01, 0x02, 0xcc, 0x39, 0x01, 0x02, 0xd0, 0x39, 0x01, 0x02, 0xd4, 0x39, 0x01, 0x02, 0x7c, 0x12, 0x02, 0x02, 0x80, 0x12, 0x02, 0x02, + 0x84, 0x12, 0x02, 0x02, 0x88, 0x12, 0x02, 0x02, 0xa0, 0x30, 0x03, 0x03, 0xa8, 0x30, 0x03, 0x03, 0xb0, 0x30, 0x03, 0x03, 0x98, 0x0c, 0x04, 0x03, 0xa0, 0x0c, 0x04, 0x03, 0x50, 0x28, 0x05, 0x04, + 0xd0, 0x06, 0x06, 0x04, 0x40, 0x21, 0x07, 0x05, 0xc0, 0x1b, 0x09, 0x06, 0x5c, 0x09, 0x00, 0x02, 0x60, 0x09, 0x00, 0x02, 0x64, 0x09, 0x00, 0x02, 0x68, 0x09, 0x00, 0x02, 0xd8, 0x39, 0x01, 0x02, + 0xdc, 0x39, 0x01, 0x02, 0xe0, 0x39, 0x01, 0x02, 0xe4, 0x39, 0x01, 0x02, 0xe8, 0x39, 0x01, 0x02, 0xec, 0x39, 0x01, 0x02, 0x8c, 0x12, 0x02, 0x02, 0x90, 0x12, 0x02, 0x02, 0x94, 0x12, 0x02, 0x02, + 0x98, 0x12, 0x02, 0x02, 0x9c, 0x12, 0x02, 0x02, 0xb8, 0x30, 0x03, 0x03, 0xc0, 0x30, 0x03, 0x03, 0xc8, 0x30, 0x03, 0x03, 0xa8, 0x0c, 0x04, 0x03, 0xb0, 0x0c, 0x04, 0x03, 0x60, 0x28, 0x05, 0x04, + 0xe0, 0x06, 0x06, 0x04, 0x60, 0x21, 0x07, 0x05, 0x00, 0x1c, 0x09, 0x06, 0x6c, 0x09, 0x00, 0x02, 0x70, 0x09, 0x00, 0x02, 0x74, 0x09, 0x00, 0x02, 0x78, 0x09, 0x00, 0x02, 0xf0, 0x39, 0x01, 0x02, + 0xf4, 0x39, 0x01, 0x02, 0xf8, 0x39, 0x01, 0x02, 0xfc, 0x39, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x04, 0x3a, 0x01, 0x02, 0xa0, 0x12, 0x02, 0x02, 0xa4, 0x12, 0x02, 0x02, 0xa8, 0x12, 0x02, 0x02, + 0xac, 0x12, 0x02, 0x02, 0xb0, 0x12, 0x02, 0x02, 0xd0, 0x30, 0x03, 0x03, 0xd8, 0x30, 0x03, 0x03, 0xe0, 0x30, 0x03, 0x03, 0xb8, 0x0c, 0x04, 0x03, 0xc0, 0x0c, 0x04, 0x03, 0x70, 0x28, 0x05, 0x04, + 0xf0, 0x06, 0x06, 0x04, 0x80, 0x21, 0x07, 0x05, 0x40, 0x1c, 0x09, 0x06, 0x7c, 0x09, 0x00, 0x02, 0x80, 0x09, 0x00, 0x02, 0x84, 0x09, 0x00, 0x02, 0x88, 0x09, 0x00, 0x02, 0x08, 0x3a, 0x01, 0x02, + 0x0c, 0x3a, 0x01, 0x02, 0x10, 0x3a, 0x01, 0x02, 0x14, 0x3a, 0x01, 0x02, 0x18, 0x3a, 0x01, 0x02, 0x1c, 0x3a, 0x01, 0x02, 0xb4, 0x12, 0x02, 0x02, 0xb8, 0x12, 0x02, 0x02, 0xbc, 0x12, 0x02, 0x02, + 0xc0, 0x12, 0x02, 0x02, 0xc4, 0x12, 0x02, 0x02, 0xe8, 0x30, 0x03, 0x03, 0xf0, 0x30, 0x03, 0x03, 0xf8, 0x30, 0x03, 0x03, 0xc8, 0x0c, 0x04, 0x03, 0xd0, 0x0c, 0x04, 0x03, 0x80, 0x28, 0x05, 0x04, + 0x00, 0x07, 0x06, 0x04, 0xa0, 0x21, 0x07, 0x05, 0x80, 0x1c, 0x09, 0x06, 0x8c, 0x09, 0x00, 0x02, 0x90, 0x09, 0x00, 0x02, 0x94, 0x09, 0x00, 0x02, 0x98, 0x09, 0x00, 0x02, 0x20, 0x3a, 0x01, 0x02, + 0x24, 0x3a, 0x01, 0x02, 0x28, 0x3a, 0x01, 0x02, 0x2c, 0x3a, 0x01, 0x02, 0x30, 0x3a, 0x01, 0x02, 0x34, 0x3a, 0x01, 0x02, 0xc8, 0x12, 0x02, 0x02, 0xcc, 0x12, 0x02, 0x02, 0xd0, 0x12, 0x02, 0x02, + 0xd4, 0x12, 0x02, 0x02, 0xd8, 0x12, 0x02, 0x02, 0x00, 0x31, 0x03, 0x03, 0x08, 0x31, 0x03, 0x03, 0x10, 0x31, 0x03, 0x03, 0xd8, 0x0c, 0x04, 0x03, 0xe0, 0x0c, 0x04, 0x03, 0x90, 0x28, 0x05, 0x04, + 0x10, 0x07, 0x06, 0x04, 0xc0, 0x21, 0x07, 0x05, 0xc0, 0x1c, 0x09, 0x06, 0x9c, 0x09, 0x00, 0x02, 0xa0, 0x09, 0x00, 0x02, 0xa4, 0x09, 0x00, 0x02, 0xa8, 0x09, 0x00, 0x02, 0x38, 0x3a, 0x01, 0x02, + 0x3c, 0x3a, 0x01, 0x02, 0x40, 0x3a, 0x01, 0x02, 0x44, 0x3a, 0x01, 0x02, 0x48, 0x3a, 0x01, 0x02, 0x4c, 0x3a, 0x01, 0x02, 0xdc, 0x12, 0x02, 0x02, 0xe0, 0x12, 0x02, 0x02, 0xe4, 0x12, 0x02, 0x02, + 0xe8, 0x12, 0x02, 0x02, 0xec, 0x12, 0x02, 0x02, 0x18, 0x31, 0x03, 0x03, 0x20, 0x31, 0x03, 0x03, 0x28, 0x31, 0x03, 0x03, 0xe8, 0x0c, 0x04, 0x03, 0xf0, 0x0c, 0x04, 0x03, 0xa0, 0x28, 0x05, 0x04, + 0x20, 0x07, 0x06, 0x04, 0xe0, 0x21, 0x07, 0x05, 0x00, 0x1d, 0x09, 0x06, 0xac, 0x09, 0x00, 0x02, 0xb0, 0x09, 0x00, 0x02, 0xb4, 0x09, 0x00, 0x02, 0xb8, 0x09, 0x00, 0x02, 0x50, 0x3a, 0x01, 0x02, + 0x54, 0x3a, 0x01, 0x02, 0x58, 0x3a, 0x01, 0x02, 0x5c, 0x3a, 0x01, 0x02, 0x60, 0x3a, 0x01, 0x02, 0x64, 0x3a, 0x01, 0x02, 0xf0, 0x12, 0x02, 0x02, 0xf4, 0x12, 0x02, 0x02, 0xf8, 0x12, 0x02, 0x02, + 0xfc, 0x12, 0x02, 0x02, 0x00, 0x13, 0x02, 0x02, 0x30, 0x31, 0x03, 0x03, 0x38, 0x31, 0x03, 0x03, 0x40, 0x31, 0x03, 0x03, 0xf8, 0x0c, 0x04, 0x03, 0x00, 0x0d, 0x04, 0x03, 0xb0, 0x28, 0x05, 0x04, + 0x30, 0x07, 0x06, 0x04, 0x00, 0x22, 0x07, 0x05, 0x00, 0x37, 0x0a, 0x07, 0xbc, 0x09, 0x00, 0x02, 0xc0, 0x09, 0x00, 0x02, 0xc4, 0x09, 0x00, 0x02, 0xc8, 0x09, 0x00, 0x02, 0x68, 0x3a, 0x01, 0x02, + 0x6c, 0x3a, 0x01, 0x02, 0x70, 0x3a, 0x01, 0x02, 0x74, 0x3a, 0x01, 0x02, 0x78, 0x3a, 0x01, 0x02, 0x7c, 0x3a, 0x01, 0x02, 0x04, 0x13, 0x02, 0x02, 0x08, 0x13, 0x02, 0x02, 0x0c, 0x13, 0x02, 0x02, + 0x10, 0x13, 0x02, 0x02, 0x14, 0x13, 0x02, 0x02, 0x48, 0x31, 0x03, 0x03, 0x50, 0x31, 0x03, 0x03, 0x58, 0x31, 0x03, 0x03, 0x08, 0x0d, 0x04, 0x03, 0x10, 0x0d, 0x04, 0x03, 0xc0, 0x28, 0x05, 0x04, + 0x40, 0x07, 0x06, 0x04, 0x20, 0x22, 0x07, 0x05, 0x80, 0x37, 0x0a, 0x07, 0xcc, 0x09, 0x00, 0x02, 0xd0, 0x09, 0x00, 0x02, 0xd4, 0x09, 0x00, 0x02, 0xd8, 0x09, 0x00, 0x02, 0x80, 0x3a, 0x01, 0x02, + 0x84, 0x3a, 0x01, 0x02, 0x88, 0x3a, 0x01, 0x02, 0x8c, 0x3a, 0x01, 0x02, 0x90, 0x3a, 0x01, 0x02, 0x94, 0x3a, 0x01, 0x02, 0x18, 0x13, 0x02, 0x02, 0x1c, 0x13, 0x02, 0x02, 0x20, 0x13, 0x02, 0x02, + 0x24, 0x13, 0x02, 0x02, 0x28, 0x13, 0x02, 0x02, 0x60, 0x31, 0x03, 0x03, 0x68, 0x31, 0x03, 0x03, 0x70, 0x31, 0x03, 0x03, 0x18, 0x0d, 0x04, 0x03, 0x20, 0x0d, 0x04, 0x03, 0xd0, 0x28, 0x05, 0x04, + 0x50, 0x07, 0x06, 0x04, 0x40, 0x22, 0x07, 0x05, 0x00, 0x38, 0x0a, 0x07, 0xdc, 0x09, 0x00, 0x02, 0xe0, 0x09, 0x00, 0x02, 0xe4, 0x09, 0x00, 0x02, 0xe8, 0x09, 0x00, 0x02, 0x98, 0x3a, 0x01, 0x02, + 0x9c, 0x3a, 0x01, 0x02, 0xa0, 0x3a, 0x01, 0x02, 0xa4, 0x3a, 0x01, 0x02, 0xa8, 0x3a, 0x01, 0x02, 0xac, 0x3a, 0x01, 0x02, 0x2c, 0x13, 0x02, 0x02, 0x30, 0x13, 0x02, 0x02, 0x34, 0x13, 0x02, 0x02, + 0x38, 0x13, 0x02, 0x02, 0x3c, 0x13, 0x02, 0x02, 0x78, 0x31, 0x03, 0x03, 0x80, 0x31, 0x03, 0x03, 0x88, 0x31, 0x03, 0x03, 0x28, 0x0d, 0x04, 0x03, 0x30, 0x0d, 0x04, 0x03, 0xe0, 0x28, 0x05, 0x04, + 0x60, 0x07, 0x06, 0x04, 0x60, 0x22, 0x07, 0x05, 0x80, 0x38, 0x0a, 0x07, 0xec, 0x09, 0x00, 0x02, 0xf0, 0x09, 0x00, 0x02, 0xf4, 0x09, 0x00, 0x02, 0xf8, 0x09, 0x00, 0x02, 0xb0, 0x3a, 0x01, 0x02, + 0xb4, 0x3a, 0x01, 0x02, 0xb8, 0x3a, 0x01, 0x02, 0xbc, 0x3a, 0x01, 0x02, 0xc0, 0x3a, 0x01, 0x02, 0xc4, 0x3a, 0x01, 0x02, 0x40, 0x13, 0x02, 0x02, 0x44, 0x13, 0x02, 0x02, 0x48, 0x13, 0x02, 0x02, + 0x4c, 0x13, 0x02, 0x02, 0x50, 0x13, 0x02, 0x02, 0x90, 0x31, 0x03, 0x03, 0x98, 0x31, 0x03, 0x03, 0xa0, 0x31, 0x03, 0x03, 0x38, 0x0d, 0x04, 0x03, 0x40, 0x0d, 0x04, 0x03, 0xf0, 0x28, 0x05, 0x04, + 0x70, 0x07, 0x06, 0x04, 0x80, 0x22, 0x07, 0x05, 0x00, 0x39, 0x0a, 0x07, 0xfc, 0x09, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x04, 0x0a, 0x00, 0x02, 0x08, 0x0a, 0x00, 0x02, 0xc8, 0x3a, 0x01, 0x02, + 0xcc, 0x3a, 0x01, 0x02, 0xd0, 0x3a, 0x01, 0x02, 0xd4, 0x3a, 0x01, 0x02, 0xd8, 0x3a, 0x01, 0x02, 0xdc, 0x3a, 0x01, 0x02, 0x54, 0x13, 0x02, 0x02, 0x58, 0x13, 0x02, 0x02, 0x5c, 0x13, 0x02, 0x02, + 0x60, 0x13, 0x02, 0x02, 0x64, 0x13, 0x02, 0x02, 0xa8, 0x31, 0x03, 0x03, 0xb0, 0x31, 0x03, 0x03, 0xb8, 0x31, 0x03, 0x03, 0x48, 0x0d, 0x04, 0x03, 0x50, 0x0d, 0x04, 0x03, 0x00, 0x29, 0x05, 0x04, + 0x80, 0x07, 0x06, 0x04, 0xa0, 0x22, 0x07, 0x05, 0x80, 0x39, 0x0a, 0x07, 0x0c, 0x0a, 0x00, 0x02, 0x10, 0x0a, 0x00, 0x02, 0x14, 0x0a, 0x00, 0x02, 0x18, 0x0a, 0x00, 0x02, 0xe0, 0x3a, 0x01, 0x02, + 0xe4, 0x3a, 0x01, 0x02, 0xe8, 0x3a, 0x01, 0x02, 0xec, 0x3a, 0x01, 0x02, 0xf0, 0x3a, 0x01, 0x02, 0xf4, 0x3a, 0x01, 0x02, 0x68, 0x13, 0x02, 0x02, 0x6c, 0x13, 0x02, 0x02, 0x70, 0x13, 0x02, 0x02, + 0x74, 0x13, 0x02, 0x02, 0x78, 0x13, 0x02, 0x02, 0xc0, 0x31, 0x03, 0x03, 0xc8, 0x31, 0x03, 0x03, 0xd0, 0x31, 0x03, 0x03, 0x58, 0x0d, 0x04, 0x03, 0x60, 0x0d, 0x04, 0x03, 0x10, 0x29, 0x05, 0x04, + 0x90, 0x07, 0x06, 0x04, 0xc0, 0x22, 0x07, 0x05, 0x00, 0x3a, 0x0a, 0x07, 0x1c, 0x0a, 0x00, 0x02, 0x20, 0x0a, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x02, 0x28, 0x0a, 0x00, 0x02, 0xf8, 0x3a, 0x01, 0x02, + 0xfc, 0x3a, 0x01, 0x02, 0x00, 0x3b, 0x01, 0x02, 0x04, 0x3b, 0x01, 0x02, 0x08, 0x3b, 0x01, 0x02, 0x0c, 0x3b, 0x01, 0x02, 0x7c, 0x13, 0x02, 0x02, 0x80, 0x13, 0x02, 0x02, 0x84, 0x13, 0x02, 0x02, + 0x88, 0x13, 0x02, 0x02, 0x8c, 0x13, 0x02, 0x02, 0xd8, 0x31, 0x03, 0x03, 0xe0, 0x31, 0x03, 0x03, 0xe8, 0x31, 0x03, 0x03, 0x68, 0x0d, 0x04, 0x03, 0x70, 0x0d, 0x04, 0x03, 0x20, 0x29, 0x05, 0x04, + 0xa0, 0x07, 0x06, 0x04, 0xe0, 0x22, 0x07, 0x05, 0x80, 0x3a, 0x0a, 0x07, 0x2c, 0x0a, 0x00, 0x02, 0x30, 0x0a, 0x00, 0x02, 0x34, 0x0a, 0x00, 0x02, 0x38, 0x0a, 0x00, 0x02, 0x10, 0x3b, 0x01, 0x02, + 0x14, 0x3b, 0x01, 0x02, 0x18, 0x3b, 0x01, 0x02, 0x1c, 0x3b, 0x01, 0x02, 0x20, 0x3b, 0x01, 0x02, 0x24, 0x3b, 0x01, 0x02, 0x90, 0x13, 0x02, 0x02, 0x94, 0x13, 0x02, 0x02, 0x98, 0x13, 0x02, 0x02, + 0x9c, 0x13, 0x02, 0x02, 0xa0, 0x13, 0x02, 0x02, 0xf0, 0x31, 0x03, 0x03, 0xf8, 0x31, 0x03, 0x03, 0x00, 0x32, 0x03, 0x03, 0x78, 0x0d, 0x04, 0x03, 0x80, 0x0d, 0x04, 0x03, 0x30, 0x29, 0x05, 0x04, + 0xb0, 0x07, 0x06, 0x04, 0x00, 0x23, 0x07, 0x05, 0x00, 0x3b, 0x0a, 0x07, 0x3c, 0x0a, 0x00, 0x02, 0x40, 0x0a, 0x00, 0x02, 0x44, 0x0a, 0x00, 0x02, 0x48, 0x0a, 0x00, 0x02, 0x28, 0x3b, 0x01, 0x02, + 0x2c, 0x3b, 0x01, 0x02, 0x30, 0x3b, 0x01, 0x02, 0x34, 0x3b, 0x01, 0x02, 0x38, 0x3b, 0x01, 0x02, 0x3c, 0x3b, 0x01, 0x02, 0xa4, 0x13, 0x02, 0x02, 0xa8, 0x13, 0x02, 0x02, 0xac, 0x13, 0x02, 0x02, + 0xb0, 0x13, 0x02, 0x02, 0xb4, 0x13, 0x02, 0x02, 0x08, 0x32, 0x03, 0x03, 0x10, 0x32, 0x03, 0x03, 0x18, 0x32, 0x03, 0x03, 0x88, 0x0d, 0x04, 0x03, 0x90, 0x0d, 0x04, 0x03, 0x40, 0x29, 0x05, 0x04, + 0xc0, 0x07, 0x06, 0x04, 0x20, 0x23, 0x07, 0x05, 0x80, 0x3b, 0x0a, 0x07, 0x4c, 0x0a, 0x00, 0x02, 0x50, 0x0a, 0x00, 0x02, 0x54, 0x0a, 0x00, 0x02, 0x58, 0x0a, 0x00, 0x02, 0x40, 0x3b, 0x01, 0x02, + 0x44, 0x3b, 0x01, 0x02, 0x48, 0x3b, 0x01, 0x02, 0x4c, 0x3b, 0x01, 0x02, 0x50, 0x3b, 0x01, 0x02, 0x54, 0x3b, 0x01, 0x02, 0xb8, 0x13, 0x02, 0x02, 0xbc, 0x13, 0x02, 0x02, 0xc0, 0x13, 0x02, 0x02, + 0xc4, 0x13, 0x02, 0x02, 0xc8, 0x13, 0x02, 0x02, 0x20, 0x32, 0x03, 0x03, 0x28, 0x32, 0x03, 0x03, 0x30, 0x32, 0x03, 0x03, 0x98, 0x0d, 0x04, 0x03, 0xa0, 0x0d, 0x04, 0x03, 0x50, 0x29, 0x05, 0x04, + 0xd0, 0x07, 0x06, 0x04, 0x40, 0x23, 0x07, 0x05, 0x00, 0x3c, 0x0a, 0x07, 0x5c, 0x0a, 0x00, 0x02, 0x60, 0x0a, 0x00, 0x02, 0x64, 0x0a, 0x00, 0x02, 0x68, 0x0a, 0x00, 0x02, 0x58, 0x3b, 0x01, 0x02, + 0x5c, 0x3b, 0x01, 0x02, 0x60, 0x3b, 0x01, 0x02, 0x64, 0x3b, 0x01, 0x02, 0x68, 0x3b, 0x01, 0x02, 0x6c, 0x3b, 0x01, 0x02, 0xcc, 0x13, 0x02, 0x02, 0xd0, 0x13, 0x02, 0x02, 0xd4, 0x13, 0x02, 0x02, + 0xd8, 0x13, 0x02, 0x02, 0xdc, 0x13, 0x02, 0x02, 0x38, 0x32, 0x03, 0x03, 0x40, 0x32, 0x03, 0x03, 0x48, 0x32, 0x03, 0x03, 0xa8, 0x0d, 0x04, 0x03, 0xb0, 0x0d, 0x04, 0x03, 0x60, 0x29, 0x05, 0x04, + 0xe0, 0x07, 0x06, 0x04, 0x60, 0x23, 0x07, 0x05, 0x80, 0x3c, 0x0a, 0x07, 0x6c, 0x0a, 0x00, 0x02, 0x70, 0x0a, 0x00, 0x02, 0x74, 0x0a, 0x00, 0x02, 0x78, 0x0a, 0x00, 0x02, 0x70, 0x3b, 0x01, 0x02, + 0x74, 0x3b, 0x01, 0x02, 0x78, 0x3b, 0x01, 0x02, 0x7c, 0x3b, 0x01, 0x02, 0x80, 0x3b, 0x01, 0x02, 0x84, 0x3b, 0x01, 0x02, 0xe0, 0x13, 0x02, 0x02, 0xe4, 0x13, 0x02, 0x02, 0xe8, 0x13, 0x02, 0x02, + 0xec, 0x13, 0x02, 0x02, 0xf0, 0x13, 0x02, 0x02, 0x50, 0x32, 0x03, 0x03, 0x58, 0x32, 0x03, 0x03, 0x60, 0x32, 0x03, 0x03, 0xb8, 0x0d, 0x04, 0x03, 0xc0, 0x0d, 0x04, 0x03, 0x70, 0x29, 0x05, 0x04, + 0xf0, 0x07, 0x06, 0x04, 0x80, 0x23, 0x07, 0x05, 0x00, 0x3d, 0x0a, 0x07, 0x7c, 0x0a, 0x00, 0x02, 0x80, 0x0a, 0x00, 0x02, 0x84, 0x0a, 0x00, 0x02, 0x88, 0x0a, 0x00, 0x02, 0x88, 0x3b, 0x01, 0x02, + 0x8c, 0x3b, 0x01, 0x02, 0x90, 0x3b, 0x01, 0x02, 0x94, 0x3b, 0x01, 0x02, 0x98, 0x3b, 0x01, 0x02, 0x9c, 0x3b, 0x01, 0x02, 0xf4, 0x13, 0x02, 0x02, 0xf8, 0x13, 0x02, 0x02, 0xfc, 0x13, 0x02, 0x02, + 0x00, 0x14, 0x02, 0x02, 0x04, 0x14, 0x02, 0x02, 0x68, 0x32, 0x03, 0x03, 0x70, 0x32, 0x03, 0x03, 0x78, 0x32, 0x03, 0x03, 0xc8, 0x0d, 0x04, 0x03, 0xd0, 0x0d, 0x04, 0x03, 0x80, 0x29, 0x05, 0x04, + 0x00, 0x08, 0x06, 0x04, 0xa0, 0x23, 0x07, 0x05, 0x80, 0x3d, 0x0a, 0x07, 0x8c, 0x0a, 0x00, 0x02, 0x90, 0x0a, 0x00, 0x02, 0x94, 0x0a, 0x00, 0x02, 0x98, 0x0a, 0x00, 0x02, 0xa0, 0x3b, 0x01, 0x02, + 0xa4, 0x3b, 0x01, 0x02, 0xa8, 0x3b, 0x01, 0x02, 0xac, 0x3b, 0x01, 0x02, 0xb0, 0x3b, 0x01, 0x02, 0xb4, 0x3b, 0x01, 0x02, 0x08, 0x14, 0x02, 0x02, 0x0c, 0x14, 0x02, 0x02, 0x10, 0x14, 0x02, 0x02, + 0x14, 0x14, 0x02, 0x02, 0x18, 0x14, 0x02, 0x02, 0x80, 0x32, 0x03, 0x03, 0x88, 0x32, 0x03, 0x03, 0x90, 0x32, 0x03, 0x03, 0xd8, 0x0d, 0x04, 0x03, 0xe0, 0x0d, 0x04, 0x03, 0x90, 0x29, 0x05, 0x04, + 0x10, 0x08, 0x06, 0x04, 0xc0, 0x23, 0x07, 0x05, 0x00, 0x3e, 0x0a, 0x07, 0x9c, 0x0a, 0x00, 0x02, 0xa0, 0x0a, 0x00, 0x02, 0xa4, 0x0a, 0x00, 0x02, 0xa8, 0x0a, 0x00, 0x02, 0xb8, 0x3b, 0x01, 0x02, + 0xbc, 0x3b, 0x01, 0x02, 0xc0, 0x3b, 0x01, 0x02, 0xc4, 0x3b, 0x01, 0x02, 0xc8, 0x3b, 0x01, 0x02, 0xcc, 0x3b, 0x01, 0x02, 0x1c, 0x14, 0x02, 0x02, 0x20, 0x14, 0x02, 0x02, 0x24, 0x14, 0x02, 0x02, + 0x28, 0x14, 0x02, 0x02, 0x2c, 0x14, 0x02, 0x02, 0x98, 0x32, 0x03, 0x03, 0xa0, 0x32, 0x03, 0x03, 0xa8, 0x32, 0x03, 0x03, 0xe8, 0x0d, 0x04, 0x03, 0xf0, 0x0d, 0x04, 0x03, 0xa0, 0x29, 0x05, 0x04, + 0x20, 0x08, 0x06, 0x04, 0xe0, 0x23, 0x07, 0x05, 0x80, 0x3e, 0x0a, 0x07, 0xac, 0x0a, 0x00, 0x02, 0xb0, 0x0a, 0x00, 0x02, 0xb4, 0x0a, 0x00, 0x02, 0xb8, 0x0a, 0x00, 0x02, 0xd0, 0x3b, 0x01, 0x02, + 0xd4, 0x3b, 0x01, 0x02, 0xd8, 0x3b, 0x01, 0x02, 0xdc, 0x3b, 0x01, 0x02, 0xe0, 0x3b, 0x01, 0x02, 0xe4, 0x3b, 0x01, 0x02, 0x30, 0x14, 0x02, 0x02, 0x34, 0x14, 0x02, 0x02, 0x38, 0x14, 0x02, 0x02, + 0x3c, 0x14, 0x02, 0x02, 0x40, 0x14, 0x02, 0x02, 0xb0, 0x32, 0x03, 0x03, 0xb8, 0x32, 0x03, 0x03, 0xc0, 0x32, 0x03, 0x03, 0xf8, 0x0d, 0x04, 0x03, 0x00, 0x0e, 0x04, 0x03, 0xb0, 0x29, 0x05, 0x04, + 0x30, 0x08, 0x06, 0x04, 0x00, 0x24, 0x07, 0x05, 0x00, 0x3f, 0x0a, 0x07, 0xbc, 0x0a, 0x00, 0x02, 0xc0, 0x0a, 0x00, 0x02, 0xc4, 0x0a, 0x00, 0x02, 0xc8, 0x0a, 0x00, 0x02, 0xe8, 0x3b, 0x01, 0x02, + 0xec, 0x3b, 0x01, 0x02, 0xf0, 0x3b, 0x01, 0x02, 0xf4, 0x3b, 0x01, 0x02, 0xf8, 0x3b, 0x01, 0x02, 0xfc, 0x3b, 0x01, 0x02, 0x44, 0x14, 0x02, 0x02, 0x48, 0x14, 0x02, 0x02, 0x4c, 0x14, 0x02, 0x02, + 0x50, 0x14, 0x02, 0x02, 0x54, 0x14, 0x02, 0x02, 0xc8, 0x32, 0x03, 0x03, 0xd0, 0x32, 0x03, 0x03, 0xd8, 0x32, 0x03, 0x03, 0x08, 0x0e, 0x04, 0x03, 0x10, 0x0e, 0x04, 0x03, 0xc0, 0x29, 0x05, 0x04, + 0x40, 0x08, 0x06, 0x04, 0x20, 0x24, 0x07, 0x05, 0x80, 0x10, 0x0b, 0x07, 0xcc, 0x0a, 0x00, 0x02, 0xd0, 0x0a, 0x00, 0x02, 0xd4, 0x0a, 0x00, 0x02, 0xd8, 0x0a, 0x00, 0x02, 0x00, 0x3c, 0x01, 0x02, + 0x04, 0x3c, 0x01, 0x02, 0x08, 0x3c, 0x01, 0x02, 0x0c, 0x3c, 0x01, 0x02, 0x10, 0x3c, 0x01, 0x02, 0x14, 0x3c, 0x01, 0x02, 0x58, 0x14, 0x02, 0x02, 0x5c, 0x14, 0x02, 0x02, 0x60, 0x14, 0x02, 0x02, + 0x64, 0x14, 0x02, 0x02, 0x68, 0x14, 0x02, 0x02, 0xe0, 0x32, 0x03, 0x03, 0xe8, 0x32, 0x03, 0x03, 0xf0, 0x32, 0x03, 0x03, 0x18, 0x0e, 0x04, 0x03, 0x20, 0x0e, 0x04, 0x03, 0xd0, 0x29, 0x05, 0x04, + 0x50, 0x08, 0x06, 0x04, 0x40, 0x24, 0x07, 0x05, 0x00, 0x11, 0x0b, 0x07, 0xdc, 0x0a, 0x00, 0x02, 0xe0, 0x0a, 0x00, 0x02, 0xe4, 0x0a, 0x00, 0x02, 0xe8, 0x0a, 0x00, 0x02, 0x18, 0x3c, 0x01, 0x02, + 0x1c, 0x3c, 0x01, 0x02, 0x20, 0x3c, 0x01, 0x02, 0x24, 0x3c, 0x01, 0x02, 0x28, 0x3c, 0x01, 0x02, 0x2c, 0x3c, 0x01, 0x02, 0x6c, 0x14, 0x02, 0x02, 0x70, 0x14, 0x02, 0x02, 0x74, 0x14, 0x02, 0x02, + 0x78, 0x14, 0x02, 0x02, 0x7c, 0x14, 0x02, 0x02, 0xf8, 0x32, 0x03, 0x03, 0x00, 0x33, 0x03, 0x03, 0x08, 0x33, 0x03, 0x03, 0x28, 0x0e, 0x04, 0x03, 0x30, 0x0e, 0x04, 0x03, 0xe0, 0x29, 0x05, 0x04, + 0x60, 0x08, 0x06, 0x04, 0x60, 0x24, 0x07, 0x05, 0x80, 0x11, 0x0b, 0x07, 0xec, 0x0a, 0x00, 0x02, 0xf0, 0x0a, 0x00, 0x02, 0xf4, 0x0a, 0x00, 0x02, 0xf8, 0x0a, 0x00, 0x02, 0x30, 0x3c, 0x01, 0x02, + 0x34, 0x3c, 0x01, 0x02, 0x38, 0x3c, 0x01, 0x02, 0x3c, 0x3c, 0x01, 0x02, 0x40, 0x3c, 0x01, 0x02, 0x44, 0x3c, 0x01, 0x02, 0x80, 0x14, 0x02, 0x02, 0x84, 0x14, 0x02, 0x02, 0x88, 0x14, 0x02, 0x02, + 0x8c, 0x14, 0x02, 0x02, 0x90, 0x14, 0x02, 0x02, 0x10, 0x33, 0x03, 0x03, 0x18, 0x33, 0x03, 0x03, 0x20, 0x33, 0x03, 0x03, 0x38, 0x0e, 0x04, 0x03, 0x40, 0x0e, 0x04, 0x03, 0xf0, 0x29, 0x05, 0x04, + 0x70, 0x08, 0x06, 0x04, 0x80, 0x24, 0x07, 0x05, 0x00, 0x12, 0x0b, 0x07, 0xfc, 0x0a, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x04, 0x0b, 0x00, 0x02, 0x08, 0x0b, 0x00, 0x02, 0x48, 0x3c, 0x01, 0x02, + 0x4c, 0x3c, 0x01, 0x02, 0x50, 0x3c, 0x01, 0x02, 0x54, 0x3c, 0x01, 0x02, 0x58, 0x3c, 0x01, 0x02, 0x5c, 0x3c, 0x01, 0x02, 0x94, 0x14, 0x02, 0x02, 0x98, 0x14, 0x02, 0x02, 0x9c, 0x14, 0x02, 0x02, + 0xa0, 0x14, 0x02, 0x02, 0xa4, 0x14, 0x02, 0x02, 0x28, 0x33, 0x03, 0x03, 0x30, 0x33, 0x03, 0x03, 0x38, 0x33, 0x03, 0x03, 0x48, 0x0e, 0x04, 0x03, 0x50, 0x0e, 0x04, 0x03, 0x00, 0x2a, 0x05, 0x04, + 0x80, 0x08, 0x06, 0x04, 0xa0, 0x24, 0x07, 0x05, 0x80, 0x12, 0x0b, 0x07, 0x0c, 0x0b, 0x00, 0x02, 0x10, 0x0b, 0x00, 0x02, 0x14, 0x0b, 0x00, 0x02, 0x18, 0x0b, 0x00, 0x02, 0x60, 0x3c, 0x01, 0x02, + 0x64, 0x3c, 0x01, 0x02, 0x68, 0x3c, 0x01, 0x02, 0x6c, 0x3c, 0x01, 0x02, 0x70, 0x3c, 0x01, 0x02, 0x74, 0x3c, 0x01, 0x02, 0xa8, 0x14, 0x02, 0x02, 0xac, 0x14, 0x02, 0x02, 0xb0, 0x14, 0x02, 0x02, + 0xb4, 0x14, 0x02, 0x02, 0xb8, 0x14, 0x02, 0x02, 0x40, 0x33, 0x03, 0x03, 0x48, 0x33, 0x03, 0x03, 0x50, 0x33, 0x03, 0x03, 0x58, 0x0e, 0x04, 0x03, 0x60, 0x0e, 0x04, 0x03, 0x10, 0x2a, 0x05, 0x04, + 0x90, 0x08, 0x06, 0x04, 0xc0, 0x24, 0x07, 0x05, 0x00, 0x13, 0x0b, 0x07, 0x1c, 0x0b, 0x00, 0x02, 0x20, 0x0b, 0x00, 0x02, 0x24, 0x0b, 0x00, 0x02, 0x28, 0x0b, 0x00, 0x02, 0x78, 0x3c, 0x01, 0x02, + 0x7c, 0x3c, 0x01, 0x02, 0x80, 0x3c, 0x01, 0x02, 0x84, 0x3c, 0x01, 0x02, 0x88, 0x3c, 0x01, 0x02, 0x8c, 0x3c, 0x01, 0x02, 0xbc, 0x14, 0x02, 0x02, 0xc0, 0x14, 0x02, 0x02, 0xc4, 0x14, 0x02, 0x02, + 0xc8, 0x14, 0x02, 0x02, 0xcc, 0x14, 0x02, 0x02, 0x58, 0x33, 0x03, 0x03, 0x60, 0x33, 0x03, 0x03, 0x68, 0x33, 0x03, 0x03, 0x68, 0x0e, 0x04, 0x03, 0x70, 0x0e, 0x04, 0x03, 0x20, 0x2a, 0x05, 0x04, + 0xa0, 0x08, 0x06, 0x04, 0xc0, 0x01, 0x08, 0x05, 0x80, 0x13, 0x0b, 0x07, 0x2c, 0x0b, 0x00, 0x02, 0x30, 0x0b, 0x00, 0x02, 0x34, 0x0b, 0x00, 0x02, 0x38, 0x0b, 0x00, 0x02, 0x90, 0x3c, 0x01, 0x02, + 0x94, 0x3c, 0x01, 0x02, 0x98, 0x3c, 0x01, 0x02, 0x9c, 0x3c, 0x01, 0x02, 0xa0, 0x3c, 0x01, 0x02, 0xa4, 0x3c, 0x01, 0x02, 0xd0, 0x14, 0x02, 0x02, 0xd4, 0x14, 0x02, 0x02, 0xd8, 0x14, 0x02, 0x02, + 0xdc, 0x14, 0x02, 0x02, 0xe0, 0x14, 0x02, 0x02, 0x70, 0x33, 0x03, 0x03, 0x78, 0x33, 0x03, 0x03, 0x78, 0x0e, 0x04, 0x03, 0x80, 0x0e, 0x04, 0x03, 0x88, 0x0e, 0x04, 0x03, 0x30, 0x2a, 0x05, 0x04, + 0xb0, 0x08, 0x06, 0x04, 0xe0, 0x01, 0x08, 0x05, 0x00, 0x14, 0x0b, 0x07, 0x3c, 0x0b, 0x00, 0x02, 0x40, 0x0b, 0x00, 0x02, 0x44, 0x0b, 0x00, 0x02, 0x48, 0x0b, 0x00, 0x02, 0xa8, 0x3c, 0x01, 0x02, + 0xac, 0x3c, 0x01, 0x02, 0xb0, 0x3c, 0x01, 0x02, 0xb4, 0x3c, 0x01, 0x02, 0xb8, 0x3c, 0x01, 0x02, 0xbc, 0x3c, 0x01, 0x02, 0xe4, 0x14, 0x02, 0x02, 0xe8, 0x14, 0x02, 0x02, 0xec, 0x14, 0x02, 0x02, + 0xf0, 0x14, 0x02, 0x02, 0xf4, 0x14, 0x02, 0x02, 0x80, 0x33, 0x03, 0x03, 0x88, 0x33, 0x03, 0x03, 0x90, 0x0e, 0x04, 0x03, 0x98, 0x0e, 0x04, 0x03, 0xa0, 0x0e, 0x04, 0x03, 0x40, 0x2a, 0x05, 0x04, + 0xc0, 0x08, 0x06, 0x04, 0x00, 0x02, 0x08, 0x05, 0x80, 0x14, 0x0b, 0x07, 0x4c, 0x0b, 0x00, 0x02, 0x50, 0x0b, 0x00, 0x02, 0x54, 0x0b, 0x00, 0x02, 0x58, 0x0b, 0x00, 0x02, 0xc0, 0x3c, 0x01, 0x02, + 0xc4, 0x3c, 0x01, 0x02, 0xc8, 0x3c, 0x01, 0x02, 0xcc, 0x3c, 0x01, 0x02, 0xd0, 0x3c, 0x01, 0x02, 0xd4, 0x3c, 0x01, 0x02, 0xf8, 0x14, 0x02, 0x02, 0xfc, 0x14, 0x02, 0x02, 0x00, 0x15, 0x02, 0x02, + 0x04, 0x15, 0x02, 0x02, 0x90, 0x33, 0x03, 0x03, 0x98, 0x33, 0x03, 0x03, 0xa0, 0x33, 0x03, 0x03, 0xa8, 0x0e, 0x04, 0x03, 0xb0, 0x0e, 0x04, 0x03, 0xb8, 0x0e, 0x04, 0x03, 0x50, 0x2a, 0x05, 0x04, + 0xd0, 0x08, 0x06, 0x04, 0x20, 0x02, 0x08, 0x05, 0x00, 0x15, 0x0b, 0x07, 0x5c, 0x0b, 0x00, 0x02, 0x60, 0x0b, 0x00, 0x02, 0x64, 0x0b, 0x00, 0x02, 0x68, 0x0b, 0x00, 0x02, 0xd8, 0x3c, 0x01, 0x02, + 0xdc, 0x3c, 0x01, 0x02, 0xe0, 0x3c, 0x01, 0x02, 0xe4, 0x3c, 0x01, 0x02, 0xe8, 0x3c, 0x01, 0x02, 0xec, 0x3c, 0x01, 0x02, 0x08, 0x15, 0x02, 0x02, 0x0c, 0x15, 0x02, 0x02, 0x10, 0x15, 0x02, 0x02, + 0x14, 0x15, 0x02, 0x02, 0xa8, 0x33, 0x03, 0x03, 0xb0, 0x33, 0x03, 0x03, 0xb8, 0x33, 0x03, 0x03, 0xc0, 0x0e, 0x04, 0x03, 0xc8, 0x0e, 0x04, 0x03, 0x60, 0x2a, 0x05, 0x04, 0x70, 0x2a, 0x05, 0x04, + 0xe0, 0x08, 0x06, 0x04, 0x40, 0x02, 0x08, 0x05, 0x80, 0x15, 0x0b, 0x07, 0x6c, 0x0b, 0x00, 0x02, 0x70, 0x0b, 0x00, 0x02, 0x74, 0x0b, 0x00, 0x02, 0x78, 0x0b, 0x00, 0x02, 0xf0, 0x3c, 0x01, 0x02, + 0xf4, 0x3c, 0x01, 0x02, 0xf8, 0x3c, 0x01, 0x02, 0xfc, 0x3c, 0x01, 0x02, 0x00, 0x3d, 0x01, 0x02, 0x04, 0x3d, 0x01, 0x02, 0x18, 0x15, 0x02, 0x02, 0x1c, 0x15, 0x02, 0x02, 0x20, 0x15, 0x02, 0x02, + 0x24, 0x15, 0x02, 0x02, 0xc0, 0x33, 0x03, 0x03, 0xc8, 0x33, 0x03, 0x03, 0xd0, 0x33, 0x03, 0x03, 0xd0, 0x0e, 0x04, 0x03, 0xd8, 0x0e, 0x04, 0x03, 0x80, 0x2a, 0x05, 0x04, 0x90, 0x2a, 0x05, 0x04, + 0xf0, 0x08, 0x06, 0x04, 0x60, 0x02, 0x08, 0x05, 0x00, 0x16, 0x0b, 0x07, 0x7c, 0x0b, 0x00, 0x02, 0x80, 0x0b, 0x00, 0x02, 0x84, 0x0b, 0x00, 0x02, 0x88, 0x0b, 0x00, 0x02, 0x08, 0x3d, 0x01, 0x02, + 0x0c, 0x3d, 0x01, 0x02, 0x10, 0x3d, 0x01, 0x02, 0x14, 0x3d, 0x01, 0x02, 0x18, 0x3d, 0x01, 0x02, 0x1c, 0x3d, 0x01, 0x02, 0x28, 0x15, 0x02, 0x02, 0x2c, 0x15, 0x02, 0x02, 0x30, 0x15, 0x02, 0x02, + 0x34, 0x15, 0x02, 0x02, 0xd8, 0x33, 0x03, 0x03, 0xe0, 0x33, 0x03, 0x03, 0xe8, 0x33, 0x03, 0x03, 0xe0, 0x0e, 0x04, 0x03, 0xe8, 0x0e, 0x04, 0x03, 0xa0, 0x2a, 0x05, 0x04, 0xb0, 0x2a, 0x05, 0x04, + 0x00, 0x09, 0x06, 0x04, 0x80, 0x02, 0x08, 0x05, 0x00, 0x2e, 0x0c, 0x08, 0x8c, 0x0b, 0x00, 0x02, 0x90, 0x0b, 0x00, 0x02, 0x94, 0x0b, 0x00, 0x02, 0x98, 0x0b, 0x00, 0x02, 0x20, 0x3d, 0x01, 0x02, + 0x24, 0x3d, 0x01, 0x02, 0x28, 0x3d, 0x01, 0x02, 0x2c, 0x3d, 0x01, 0x02, 0x30, 0x3d, 0x01, 0x02, 0x34, 0x3d, 0x01, 0x02, 0x38, 0x15, 0x02, 0x02, 0x3c, 0x15, 0x02, 0x02, 0x40, 0x15, 0x02, 0x02, + 0x44, 0x15, 0x02, 0x02, 0xf0, 0x33, 0x03, 0x03, 0xf8, 0x33, 0x03, 0x03, 0x00, 0x34, 0x03, 0x03, 0xf0, 0x0e, 0x04, 0x03, 0xf8, 0x0e, 0x04, 0x03, 0xc0, 0x2a, 0x05, 0x04, 0xd0, 0x2a, 0x05, 0x04, + 0x10, 0x09, 0x06, 0x04, 0xa0, 0x02, 0x08, 0x05, 0x00, 0x2f, 0x0c, 0x08, 0x9c, 0x0b, 0x00, 0x02, 0xa0, 0x0b, 0x00, 0x02, 0xa4, 0x0b, 0x00, 0x02, 0xa8, 0x0b, 0x00, 0x02, 0x38, 0x3d, 0x01, 0x02, + 0x3c, 0x3d, 0x01, 0x02, 0x40, 0x3d, 0x01, 0x02, 0x44, 0x3d, 0x01, 0x02, 0x48, 0x3d, 0x01, 0x02, 0x4c, 0x3d, 0x01, 0x02, 0x48, 0x15, 0x02, 0x02, 0x4c, 0x15, 0x02, 0x02, 0x50, 0x15, 0x02, 0x02, + 0x54, 0x15, 0x02, 0x02, 0x08, 0x34, 0x03, 0x03, 0x10, 0x34, 0x03, 0x03, 0x18, 0x34, 0x03, 0x03, 0x00, 0x0f, 0x04, 0x03, 0x08, 0x0f, 0x04, 0x03, 0xe0, 0x2a, 0x05, 0x04, 0xf0, 0x2a, 0x05, 0x04, + 0x20, 0x09, 0x06, 0x04, 0xc0, 0x02, 0x08, 0x05, 0x00, 0x30, 0x0c, 0x08, 0xac, 0x0b, 0x00, 0x02, 0xb0, 0x0b, 0x00, 0x02, 0xb4, 0x0b, 0x00, 0x02, 0xb8, 0x0b, 0x00, 0x02, 0x50, 0x3d, 0x01, 0x02, + 0x54, 0x3d, 0x01, 0x02, 0x58, 0x3d, 0x01, 0x02, 0x5c, 0x3d, 0x01, 0x02, 0x60, 0x3d, 0x01, 0x02, 0x64, 0x3d, 0x01, 0x02, 0x58, 0x15, 0x02, 0x02, 0x5c, 0x15, 0x02, 0x02, 0x60, 0x15, 0x02, 0x02, + 0x64, 0x15, 0x02, 0x02, 0x20, 0x34, 0x03, 0x03, 0x28, 0x34, 0x03, 0x03, 0x30, 0x34, 0x03, 0x03, 0x10, 0x0f, 0x04, 0x03, 0x18, 0x0f, 0x04, 0x03, 0x00, 0x2b, 0x05, 0x04, 0x10, 0x2b, 0x05, 0x04, + 0x30, 0x09, 0x06, 0x04, 0xe0, 0x02, 0x08, 0x05, 0x00, 0x31, 0x0c, 0x08, 0xbc, 0x0b, 0x00, 0x02, 0xc0, 0x0b, 0x00, 0x02, 0xc4, 0x0b, 0x00, 0x02, 0xc8, 0x0b, 0x00, 0x02, 0x68, 0x3d, 0x01, 0x02, + 0x6c, 0x3d, 0x01, 0x02, 0x70, 0x3d, 0x01, 0x02, 0x74, 0x3d, 0x01, 0x02, 0x78, 0x3d, 0x01, 0x02, 0x7c, 0x3d, 0x01, 0x02, 0x68, 0x15, 0x02, 0x02, 0x6c, 0x15, 0x02, 0x02, 0x70, 0x15, 0x02, 0x02, + 0x74, 0x15, 0x02, 0x02, 0x38, 0x34, 0x03, 0x03, 0x40, 0x34, 0x03, 0x03, 0x48, 0x34, 0x03, 0x03, 0x20, 0x0f, 0x04, 0x03, 0x28, 0x0f, 0x04, 0x03, 0x20, 0x2b, 0x05, 0x04, 0x30, 0x2b, 0x05, 0x04, + 0x40, 0x09, 0x06, 0x04, 0x00, 0x03, 0x08, 0x05, 0x00, 0x32, 0x0c, 0x08, 0xcc, 0x0b, 0x00, 0x02, 0xd0, 0x0b, 0x00, 0x02, 0xd4, 0x0b, 0x00, 0x02, 0xd8, 0x0b, 0x00, 0x02, 0x80, 0x3d, 0x01, 0x02, + 0x84, 0x3d, 0x01, 0x02, 0x88, 0x3d, 0x01, 0x02, 0x8c, 0x3d, 0x01, 0x02, 0x90, 0x3d, 0x01, 0x02, 0x94, 0x3d, 0x01, 0x02, 0x78, 0x15, 0x02, 0x02, 0x7c, 0x15, 0x02, 0x02, 0x80, 0x15, 0x02, 0x02, + 0x84, 0x15, 0x02, 0x02, 0x50, 0x34, 0x03, 0x03, 0x58, 0x34, 0x03, 0x03, 0x60, 0x34, 0x03, 0x03, 0x30, 0x0f, 0x04, 0x03, 0x38, 0x0f, 0x04, 0x03, 0x40, 0x2b, 0x05, 0x04, 0x50, 0x2b, 0x05, 0x04, + 0x50, 0x09, 0x06, 0x04, 0x20, 0x03, 0x08, 0x05, 0x00, 0x33, 0x0c, 0x08, 0xdc, 0x0b, 0x00, 0x02, 0xe0, 0x0b, 0x00, 0x02, 0xe4, 0x0b, 0x00, 0x02, 0xe8, 0x0b, 0x00, 0x02, 0x98, 0x3d, 0x01, 0x02, + 0x9c, 0x3d, 0x01, 0x02, 0xa0, 0x3d, 0x01, 0x02, 0xa4, 0x3d, 0x01, 0x02, 0xa8, 0x3d, 0x01, 0x02, 0xac, 0x3d, 0x01, 0x02, 0x88, 0x15, 0x02, 0x02, 0x8c, 0x15, 0x02, 0x02, 0x90, 0x15, 0x02, 0x02, + 0x94, 0x15, 0x02, 0x02, 0x68, 0x34, 0x03, 0x03, 0x70, 0x34, 0x03, 0x03, 0x78, 0x34, 0x03, 0x03, 0x40, 0x0f, 0x04, 0x03, 0x48, 0x0f, 0x04, 0x03, 0x60, 0x2b, 0x05, 0x04, 0x70, 0x2b, 0x05, 0x04, + 0x60, 0x09, 0x06, 0x04, 0x40, 0x03, 0x08, 0x05, 0x00, 0x34, 0x0c, 0x08, 0xec, 0x0b, 0x00, 0x02, 0xf0, 0x0b, 0x00, 0x02, 0xf4, 0x0b, 0x00, 0x02, 0xf8, 0x0b, 0x00, 0x02, 0xb0, 0x3d, 0x01, 0x02, + 0xb4, 0x3d, 0x01, 0x02, 0xb8, 0x3d, 0x01, 0x02, 0xbc, 0x3d, 0x01, 0x02, 0xc0, 0x3d, 0x01, 0x02, 0xc4, 0x3d, 0x01, 0x02, 0x98, 0x15, 0x02, 0x02, 0x9c, 0x15, 0x02, 0x02, 0xa0, 0x15, 0x02, 0x02, + 0xa4, 0x15, 0x02, 0x02, 0x80, 0x34, 0x03, 0x03, 0x88, 0x34, 0x03, 0x03, 0x90, 0x34, 0x03, 0x03, 0x50, 0x0f, 0x04, 0x03, 0x58, 0x0f, 0x04, 0x03, 0x80, 0x2b, 0x05, 0x04, 0x90, 0x2b, 0x05, 0x04, + 0x70, 0x09, 0x06, 0x04, 0x60, 0x03, 0x08, 0x05, 0x00, 0x35, 0x0c, 0x08, 0xfc, 0x0b, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x04, 0x0c, 0x00, 0x02, 0x08, 0x0c, 0x00, 0x02, 0xc8, 0x3d, 0x01, 0x02, + 0xcc, 0x3d, 0x01, 0x02, 0xd0, 0x3d, 0x01, 0x02, 0xd4, 0x3d, 0x01, 0x02, 0xd8, 0x3d, 0x01, 0x02, 0xdc, 0x3d, 0x01, 0x02, 0xa8, 0x15, 0x02, 0x02, 0xac, 0x15, 0x02, 0x02, 0xb0, 0x15, 0x02, 0x02, + 0xb4, 0x15, 0x02, 0x02, 0x98, 0x34, 0x03, 0x03, 0xa0, 0x34, 0x03, 0x03, 0xa8, 0x34, 0x03, 0x03, 0x60, 0x0f, 0x04, 0x03, 0x68, 0x0f, 0x04, 0x03, 0xa0, 0x2b, 0x05, 0x04, 0xb0, 0x2b, 0x05, 0x04, + 0x80, 0x09, 0x06, 0x04, 0x80, 0x03, 0x08, 0x05, 0x00, 0x0c, 0x0d, 0x08, 0x0c, 0x0c, 0x00, 0x02, 0x10, 0x0c, 0x00, 0x02, 0x14, 0x0c, 0x00, 0x02, 0x18, 0x0c, 0x00, 0x02, 0xe0, 0x3d, 0x01, 0x02, + 0xe4, 0x3d, 0x01, 0x02, 0xe8, 0x3d, 0x01, 0x02, 0xec, 0x3d, 0x01, 0x02, 0xf0, 0x3d, 0x01, 0x02, 0xf4, 0x3d, 0x01, 0x02, 0xb8, 0x15, 0x02, 0x02, 0xbc, 0x15, 0x02, 0x02, 0xc0, 0x15, 0x02, 0x02, + 0xc4, 0x15, 0x02, 0x02, 0xb0, 0x34, 0x03, 0x03, 0xb8, 0x34, 0x03, 0x03, 0xc0, 0x34, 0x03, 0x03, 0x70, 0x0f, 0x04, 0x03, 0x78, 0x0f, 0x04, 0x03, 0xc0, 0x2b, 0x05, 0x04, 0xd0, 0x2b, 0x05, 0x04, + 0x90, 0x09, 0x06, 0x04, 0xa0, 0x03, 0x08, 0x05, 0x00, 0x0d, 0x0d, 0x08, 0x1c, 0x0c, 0x00, 0x02, 0x20, 0x0c, 0x00, 0x02, 0x24, 0x0c, 0x00, 0x02, 0x28, 0x0c, 0x00, 0x02, 0xf8, 0x3d, 0x01, 0x02, + 0xfc, 0x3d, 0x01, 0x02, 0x00, 0x3e, 0x01, 0x02, 0x04, 0x3e, 0x01, 0x02, 0x08, 0x3e, 0x01, 0x02, 0x0c, 0x3e, 0x01, 0x02, 0xc8, 0x15, 0x02, 0x02, 0xcc, 0x15, 0x02, 0x02, 0xd0, 0x15, 0x02, 0x02, + 0xd4, 0x15, 0x02, 0x02, 0xc8, 0x34, 0x03, 0x03, 0xd0, 0x34, 0x03, 0x03, 0xd8, 0x34, 0x03, 0x03, 0x80, 0x0f, 0x04, 0x03, 0x88, 0x0f, 0x04, 0x03, 0xe0, 0x2b, 0x05, 0x04, 0xf0, 0x2b, 0x05, 0x04, + 0xa0, 0x09, 0x06, 0x04, 0xc0, 0x03, 0x08, 0x05, 0x00, 0x0e, 0x0d, 0x08, 0x2c, 0x0c, 0x00, 0x02, 0x30, 0x0c, 0x00, 0x02, 0x34, 0x0c, 0x00, 0x02, 0x38, 0x0c, 0x00, 0x02, 0x10, 0x3e, 0x01, 0x02, + 0x14, 0x3e, 0x01, 0x02, 0x18, 0x3e, 0x01, 0x02, 0x1c, 0x3e, 0x01, 0x02, 0x20, 0x3e, 0x01, 0x02, 0x24, 0x3e, 0x01, 0x02, 0xd8, 0x15, 0x02, 0x02, 0xdc, 0x15, 0x02, 0x02, 0xe0, 0x15, 0x02, 0x02, + 0xe4, 0x15, 0x02, 0x02, 0xe0, 0x34, 0x03, 0x03, 0xe8, 0x34, 0x03, 0x03, 0xf0, 0x34, 0x03, 0x03, 0x90, 0x0f, 0x04, 0x03, 0x98, 0x0f, 0x04, 0x03, 0x00, 0x2c, 0x05, 0x04, 0x10, 0x2c, 0x05, 0x04, + 0xb0, 0x09, 0x06, 0x04, 0xe0, 0x03, 0x08, 0x05, 0x00, 0x0f, 0x0d, 0x08, 0x3c, 0x0c, 0x00, 0x02, 0x40, 0x0c, 0x00, 0x02, 0x44, 0x0c, 0x00, 0x02, 0x48, 0x0c, 0x00, 0x02, 0x28, 0x3e, 0x01, 0x02, + 0x2c, 0x3e, 0x01, 0x02, 0x30, 0x3e, 0x01, 0x02, 0x34, 0x3e, 0x01, 0x02, 0x38, 0x3e, 0x01, 0x02, 0x3c, 0x3e, 0x01, 0x02, 0xe8, 0x15, 0x02, 0x02, 0xec, 0x15, 0x02, 0x02, 0xf0, 0x15, 0x02, 0x02, + 0xf4, 0x15, 0x02, 0x02, 0xf8, 0x34, 0x03, 0x03, 0x00, 0x35, 0x03, 0x03, 0x08, 0x35, 0x03, 0x03, 0xa0, 0x0f, 0x04, 0x03, 0xa8, 0x0f, 0x04, 0x03, 0x20, 0x2c, 0x05, 0x04, 0x30, 0x2c, 0x05, 0x04, + 0xc0, 0x09, 0x06, 0x04, 0x00, 0x04, 0x08, 0x05, 0x00, 0x10, 0x0d, 0x08, 0x4c, 0x0c, 0x00, 0x02, 0x50, 0x0c, 0x00, 0x02, 0x54, 0x0c, 0x00, 0x02, 0x58, 0x0c, 0x00, 0x02, 0x40, 0x3e, 0x01, 0x02, + 0x44, 0x3e, 0x01, 0x02, 0x48, 0x3e, 0x01, 0x02, 0x4c, 0x3e, 0x01, 0x02, 0x50, 0x3e, 0x01, 0x02, 0x54, 0x3e, 0x01, 0x02, 0xf8, 0x15, 0x02, 0x02, 0xfc, 0x15, 0x02, 0x02, 0x00, 0x16, 0x02, 0x02, + 0x04, 0x16, 0x02, 0x02, 0x10, 0x35, 0x03, 0x03, 0x18, 0x35, 0x03, 0x03, 0x20, 0x35, 0x03, 0x03, 0xb0, 0x0f, 0x04, 0x03, 0xb8, 0x0f, 0x04, 0x03, 0x40, 0x2c, 0x05, 0x04, 0x50, 0x2c, 0x05, 0x04, + 0xd0, 0x09, 0x06, 0x04, 0x20, 0x04, 0x08, 0x05, 0x00, 0x26, 0x0e, 0x09, 0x5c, 0x0c, 0x00, 0x02, 0x60, 0x0c, 0x00, 0x02, 0x64, 0x0c, 0x00, 0x02, 0x68, 0x0c, 0x00, 0x02, 0x58, 0x3e, 0x01, 0x02, + 0x5c, 0x3e, 0x01, 0x02, 0x60, 0x3e, 0x01, 0x02, 0x64, 0x3e, 0x01, 0x02, 0x68, 0x3e, 0x01, 0x02, 0x6c, 0x3e, 0x01, 0x02, 0x08, 0x16, 0x02, 0x02, 0x0c, 0x16, 0x02, 0x02, 0x10, 0x16, 0x02, 0x02, + 0x14, 0x16, 0x02, 0x02, 0x28, 0x35, 0x03, 0x03, 0x30, 0x35, 0x03, 0x03, 0x38, 0x35, 0x03, 0x03, 0xc0, 0x0f, 0x04, 0x03, 0xc8, 0x0f, 0x04, 0x03, 0x60, 0x2c, 0x05, 0x04, 0x70, 0x2c, 0x05, 0x04, + 0xe0, 0x09, 0x06, 0x04, 0x40, 0x04, 0x08, 0x05, 0x00, 0x28, 0x0e, 0x09, 0x6c, 0x0c, 0x00, 0x02, 0x70, 0x0c, 0x00, 0x02, 0x74, 0x0c, 0x00, 0x02, 0x70, 0x3e, 0x01, 0x02, 0x74, 0x3e, 0x01, 0x02, + 0x78, 0x3e, 0x01, 0x02, 0x7c, 0x3e, 0x01, 0x02, 0x80, 0x3e, 0x01, 0x02, 0x84, 0x3e, 0x01, 0x02, 0x88, 0x3e, 0x01, 0x02, 0x18, 0x16, 0x02, 0x02, 0x1c, 0x16, 0x02, 0x02, 0x20, 0x16, 0x02, 0x02, + 0x24, 0x16, 0x02, 0x02, 0x40, 0x35, 0x03, 0x03, 0x48, 0x35, 0x03, 0x03, 0x50, 0x35, 0x03, 0x03, 0xd0, 0x0f, 0x04, 0x03, 0xd8, 0x0f, 0x04, 0x03, 0x80, 0x2c, 0x05, 0x04, 0x90, 0x2c, 0x05, 0x04, + 0xf0, 0x09, 0x06, 0x04, 0x60, 0x04, 0x08, 0x05, 0x00, 0x2a, 0x0e, 0x09, 0x78, 0x0c, 0x00, 0x02, 0x7c, 0x0c, 0x00, 0x02, 0x80, 0x0c, 0x00, 0x02, 0x8c, 0x3e, 0x01, 0x02, 0x90, 0x3e, 0x01, 0x02, + 0x94, 0x3e, 0x01, 0x02, 0x98, 0x3e, 0x01, 0x02, 0x9c, 0x3e, 0x01, 0x02, 0xa0, 0x3e, 0x01, 0x02, 0xa4, 0x3e, 0x01, 0x02, 0x28, 0x16, 0x02, 0x02, 0x2c, 0x16, 0x02, 0x02, 0x30, 0x16, 0x02, 0x02, + 0x34, 0x16, 0x02, 0x02, 0x58, 0x35, 0x03, 0x03, 0x60, 0x35, 0x03, 0x03, 0x68, 0x35, 0x03, 0x03, 0xe0, 0x0f, 0x04, 0x03, 0xe8, 0x0f, 0x04, 0x03, 0xa0, 0x2c, 0x05, 0x04, 0xb0, 0x2c, 0x05, 0x04, + 0x00, 0x0a, 0x06, 0x04, 0x80, 0x04, 0x08, 0x05, 0x00, 0x2c, 0x0e, 0x09, 0x84, 0x0c, 0x00, 0x02, 0x88, 0x0c, 0x00, 0x02, 0x8c, 0x0c, 0x00, 0x02, 0xa8, 0x3e, 0x01, 0x02, 0xac, 0x3e, 0x01, 0x02, + 0xb0, 0x3e, 0x01, 0x02, 0xb4, 0x3e, 0x01, 0x02, 0xb8, 0x3e, 0x01, 0x02, 0xbc, 0x3e, 0x01, 0x02, 0xc0, 0x3e, 0x01, 0x02, 0x38, 0x16, 0x02, 0x02, 0x3c, 0x16, 0x02, 0x02, 0x40, 0x16, 0x02, 0x02, + 0x44, 0x16, 0x02, 0x02, 0x70, 0x35, 0x03, 0x03, 0x78, 0x35, 0x03, 0x03, 0x80, 0x35, 0x03, 0x03, 0xf0, 0x0f, 0x04, 0x03, 0xf8, 0x0f, 0x04, 0x03, 0xc0, 0x2c, 0x05, 0x04, 0xd0, 0x2c, 0x05, 0x04, + 0x10, 0x0a, 0x06, 0x04, 0xa0, 0x04, 0x08, 0x05, 0x00, 0x0a, 0x0f, 0x09, 0x90, 0x0c, 0x00, 0x02, 0x94, 0x0c, 0x00, 0x02, 0x98, 0x0c, 0x00, 0x02, 0xc4, 0x3e, 0x01, 0x02, 0xc8, 0x3e, 0x01, 0x02, + 0xcc, 0x3e, 0x01, 0x02, 0xd0, 0x3e, 0x01, 0x02, 0xd4, 0x3e, 0x01, 0x02, 0xd8, 0x3e, 0x01, 0x02, 0xdc, 0x3e, 0x01, 0x02, 0x48, 0x16, 0x02, 0x02, 0x4c, 0x16, 0x02, 0x02, 0x50, 0x16, 0x02, 0x02, + 0x54, 0x16, 0x02, 0x02, 0x88, 0x35, 0x03, 0x03, 0x90, 0x35, 0x03, 0x03, 0x98, 0x35, 0x03, 0x03, 0x00, 0x10, 0x04, 0x03, 0x08, 0x10, 0x04, 0x03, 0xe0, 0x2c, 0x05, 0x04, 0xf0, 0x2c, 0x05, 0x04, + 0x20, 0x0a, 0x06, 0x04, 0xc0, 0x04, 0x08, 0x05, 0x00, 0x0c, 0x0f, 0x09, 0x9c, 0x0c, 0x00, 0x02, 0xa0, 0x0c, 0x00, 0x02, 0xa4, 0x0c, 0x00, 0x02, 0xe0, 0x3e, 0x01, 0x02, 0xe4, 0x3e, 0x01, 0x02, + 0xe8, 0x3e, 0x01, 0x02, 0xec, 0x3e, 0x01, 0x02, 0xf0, 0x3e, 0x01, 0x02, 0xf4, 0x3e, 0x01, 0x02, 0xf8, 0x3e, 0x01, 0x02, 0x58, 0x16, 0x02, 0x02, 0x5c, 0x16, 0x02, 0x02, 0x60, 0x16, 0x02, 0x02, + 0x64, 0x16, 0x02, 0x02, 0xa0, 0x35, 0x03, 0x03, 0xa8, 0x35, 0x03, 0x03, 0xb0, 0x35, 0x03, 0x03, 0x10, 0x10, 0x04, 0x03, 0x18, 0x10, 0x04, 0x03, 0x00, 0x2d, 0x05, 0x04, 0x10, 0x2d, 0x05, 0x04, + 0x30, 0x0a, 0x06, 0x04, 0xe0, 0x04, 0x08, 0x05, 0x00, 0x0e, 0x0f, 0x09, 0xa8, 0x0c, 0x00, 0x02, 0xac, 0x0c, 0x00, 0x02, 0xb0, 0x0c, 0x00, 0x02, 0xfc, 0x3e, 0x01, 0x02, 0x00, 0x3f, 0x01, 0x02, + 0x04, 0x3f, 0x01, 0x02, 0x08, 0x3f, 0x01, 0x02, 0x0c, 0x3f, 0x01, 0x02, 0x10, 0x3f, 0x01, 0x02, 0x14, 0x3f, 0x01, 0x02, 0x68, 0x16, 0x02, 0x02, 0x6c, 0x16, 0x02, 0x02, 0x70, 0x16, 0x02, 0x02, + 0x74, 0x16, 0x02, 0x02, 0xb8, 0x35, 0x03, 0x03, 0xc0, 0x35, 0x03, 0x03, 0xc8, 0x35, 0x03, 0x03, 0x20, 0x10, 0x04, 0x03, 0x28, 0x10, 0x04, 0x03, 0x20, 0x2d, 0x05, 0x04, 0x30, 0x2d, 0x05, 0x04, + 0x40, 0x0a, 0x06, 0x04, 0x00, 0x05, 0x08, 0x05, 0x00, 0x28, 0x10, 0x0a, 0xb4, 0x0c, 0x00, 0x02, 0xb8, 0x0c, 0x00, 0x02, 0xbc, 0x0c, 0x00, 0x02, 0x18, 0x3f, 0x01, 0x02, 0x1c, 0x3f, 0x01, 0x02, + 0x20, 0x3f, 0x01, 0x02, 0x24, 0x3f, 0x01, 0x02, 0x28, 0x3f, 0x01, 0x02, 0x2c, 0x3f, 0x01, 0x02, 0x30, 0x3f, 0x01, 0x02, 0x78, 0x16, 0x02, 0x02, 0x7c, 0x16, 0x02, 0x02, 0x80, 0x16, 0x02, 0x02, + 0x84, 0x16, 0x02, 0x02, 0xd0, 0x35, 0x03, 0x03, 0xd8, 0x35, 0x03, 0x03, 0xe0, 0x35, 0x03, 0x03, 0x30, 0x10, 0x04, 0x03, 0x38, 0x10, 0x04, 0x03, 0x40, 0x2d, 0x05, 0x04, 0x50, 0x2d, 0x05, 0x04, + 0x50, 0x0a, 0x06, 0x04, 0x20, 0x05, 0x08, 0x05, 0x00, 0x2c, 0x10, 0x0a, 0xc0, 0x0c, 0x00, 0x02, 0xc4, 0x0c, 0x00, 0x02, 0xc8, 0x0c, 0x00, 0x02, 0x34, 0x3f, 0x01, 0x02, 0x38, 0x3f, 0x01, 0x02, + 0x3c, 0x3f, 0x01, 0x02, 0x40, 0x3f, 0x01, 0x02, 0x44, 0x3f, 0x01, 0x02, 0x48, 0x3f, 0x01, 0x02, 0x4c, 0x3f, 0x01, 0x02, 0x88, 0x16, 0x02, 0x02, 0x8c, 0x16, 0x02, 0x02, 0x90, 0x16, 0x02, 0x02, + 0x94, 0x16, 0x02, 0x02, 0xe8, 0x35, 0x03, 0x03, 0xf0, 0x35, 0x03, 0x03, 0xf8, 0x35, 0x03, 0x03, 0x40, 0x10, 0x04, 0x03, 0x48, 0x10, 0x04, 0x03, 0x60, 0x2d, 0x05, 0x04, 0x70, 0x2d, 0x05, 0x04, + 0x60, 0x0a, 0x06, 0x04, 0x40, 0x05, 0x08, 0x05, 0x00, 0x04, 0x11, 0x0a, 0xcc, 0x0c, 0x00, 0x02, 0xd0, 0x0c, 0x00, 0x02, 0xd4, 0x0c, 0x00, 0x02, 0x50, 0x3f, 0x01, 0x02, 0x54, 0x3f, 0x01, 0x02, + 0x58, 0x3f, 0x01, 0x02, 0x5c, 0x3f, 0x01, 0x02, 0x60, 0x3f, 0x01, 0x02, 0x64, 0x3f, 0x01, 0x02, 0x68, 0x3f, 0x01, 0x02, 0x98, 0x16, 0x02, 0x02, 0x9c, 0x16, 0x02, 0x02, 0xa0, 0x16, 0x02, 0x02, + 0xa4, 0x16, 0x02, 0x02, 0x00, 0x36, 0x03, 0x03, 0x08, 0x36, 0x03, 0x03, 0x10, 0x36, 0x03, 0x03, 0x50, 0x10, 0x04, 0x03, 0x58, 0x10, 0x04, 0x03, 0x80, 0x2d, 0x05, 0x04, 0x90, 0x2d, 0x05, 0x04, + 0x70, 0x0a, 0x06, 0x04, 0x60, 0x05, 0x08, 0x05, 0x00, 0x18, 0x12, 0x0b, 0xd8, 0x0c, 0x00, 0x02, 0xdc, 0x0c, 0x00, 0x02, 0xe0, 0x0c, 0x00, 0x02, 0x6c, 0x3f, 0x01, 0x02, 0x70, 0x3f, 0x01, 0x02, + 0x74, 0x3f, 0x01, 0x02, 0x78, 0x3f, 0x01, 0x02, 0x7c, 0x3f, 0x01, 0x02, 0x80, 0x3f, 0x01, 0x02, 0x84, 0x3f, 0x01, 0x02, 0xa8, 0x16, 0x02, 0x02, 0xac, 0x16, 0x02, 0x02, 0xb0, 0x16, 0x02, 0x02, + 0xb4, 0x16, 0x02, 0x02, 0x18, 0x36, 0x03, 0x03, 0x20, 0x36, 0x03, 0x03, 0x28, 0x36, 0x03, 0x03, 0x60, 0x10, 0x04, 0x03, 0x68, 0x10, 0x04, 0x03, 0xa0, 0x2d, 0x05, 0x04, 0xb0, 0x2d, 0x05, 0x04, + 0x80, 0x0a, 0x06, 0x04, 0x80, 0x05, 0x08, 0x05, 0x00, 0x10, 0x14, 0x0c, 0xe4, 0x0c, 0x00, 0x02, 0xe8, 0x0c, 0x00, 0x02, 0xec, 0x0c, 0x00, 0x02, 0x88, 0x3f, 0x01, 0x02, 0x8c, 0x3f, 0x01, 0x02, + 0x90, 0x3f, 0x01, 0x02, 0x94, 0x3f, 0x01, 0x02, 0x98, 0x3f, 0x01, 0x02, 0x9c, 0x3f, 0x01, 0x02, 0xa0, 0x3f, 0x01, 0x02, 0xb8, 0x16, 0x02, 0x02, 0xbc, 0x16, 0x02, 0x02, 0xc0, 0x16, 0x02, 0x02, + 0xc4, 0x16, 0x02, 0x02, 0x30, 0x36, 0x03, 0x03, 0x38, 0x36, 0x03, 0x03, 0x40, 0x36, 0x03, 0x03, 0x70, 0x10, 0x04, 0x03, 0x78, 0x10, 0x04, 0x03, 0xc0, 0x2d, 0x05, 0x04, 0xd0, 0x2d, 0x05, 0x04, + 0x90, 0x0a, 0x06, 0x04, 0xa0, 0x05, 0x08, 0x05, 0xf0, 0x0c, 0x00, 0x02, 0xf4, 0x0c, 0x00, 0x02, 0xf8, 0x0c, 0x00, 0x02, 0xfc, 0x0c, 0x00, 0x02, 0xa4, 0x3f, 0x01, 0x02, 0xa8, 0x3f, 0x01, 0x02, + 0xac, 0x3f, 0x01, 0x02, 0xb0, 0x3f, 0x01, 0x02, 0xb4, 0x3f, 0x01, 0x02, 0xb8, 0x3f, 0x01, 0x02, 0xbc, 0x3f, 0x01, 0x02, 0xc8, 0x16, 0x02, 0x02, 0xcc, 0x16, 0x02, 0x02, 0xd0, 0x16, 0x02, 0x02, + 0xd4, 0x16, 0x02, 0x02, 0x48, 0x36, 0x03, 0x03, 0x50, 0x36, 0x03, 0x03, 0x58, 0x36, 0x03, 0x03, 0x80, 0x10, 0x04, 0x03, 0x88, 0x10, 0x04, 0x03, 0xe0, 0x2d, 0x05, 0x04, 0xf0, 0x2d, 0x05, 0x04, + 0xe0, 0x24, 0x07, 0x05, 0xc0, 0x05, 0x08, 0x05, 0x00, 0x0d, 0x00, 0x02, 0x04, 0x0d, 0x00, 0x02, 0x08, 0x0d, 0x00, 0x02, 0x0c, 0x0d, 0x00, 0x02, 0xc0, 0x3f, 0x01, 0x02, 0xc4, 0x3f, 0x01, 0x02, + 0xc8, 0x3f, 0x01, 0x02, 0xcc, 0x3f, 0x01, 0x02, 0xd0, 0x3f, 0x01, 0x02, 0xd4, 0x3f, 0x01, 0x02, 0xd8, 0x3f, 0x01, 0x02, 0xd8, 0x16, 0x02, 0x02, 0xdc, 0x16, 0x02, 0x02, 0xe0, 0x16, 0x02, 0x02, + 0xe4, 0x16, 0x02, 0x02, 0x60, 0x36, 0x03, 0x03, 0x68, 0x36, 0x03, 0x03, 0x70, 0x36, 0x03, 0x03, 0x90, 0x10, 0x04, 0x03, 0x98, 0x10, 0x04, 0x03, 0x00, 0x2e, 0x05, 0x04, 0x10, 0x2e, 0x05, 0x04, + 0x00, 0x25, 0x07, 0x05, 0xe0, 0x05, 0x08, 0x05, 0x10, 0x0d, 0x00, 0x02, 0x14, 0x0d, 0x00, 0x02, 0x18, 0x0d, 0x00, 0x02, 0x1c, 0x0d, 0x00, 0x02, 0xdc, 0x3f, 0x01, 0x02, 0xe0, 0x3f, 0x01, 0x02, + 0xe4, 0x3f, 0x01, 0x02, 0xe8, 0x3f, 0x01, 0x02, 0xec, 0x3f, 0x01, 0x02, 0xf0, 0x3f, 0x01, 0x02, 0xf4, 0x3f, 0x01, 0x02, 0xe8, 0x16, 0x02, 0x02, 0xec, 0x16, 0x02, 0x02, 0xf0, 0x16, 0x02, 0x02, + 0xf4, 0x16, 0x02, 0x02, 0x78, 0x36, 0x03, 0x03, 0x80, 0x36, 0x03, 0x03, 0x88, 0x36, 0x03, 0x03, 0xa0, 0x10, 0x04, 0x03, 0xa8, 0x10, 0x04, 0x03, 0x20, 0x2e, 0x05, 0x04, 0x30, 0x2e, 0x05, 0x04, + 0x20, 0x25, 0x07, 0x05, 0x00, 0x06, 0x08, 0x05, 0x20, 0x0d, 0x00, 0x02, 0x24, 0x0d, 0x00, 0x02, 0x28, 0x0d, 0x00, 0x02, 0x2c, 0x0d, 0x00, 0x02, 0xf8, 0x3f, 0x01, 0x02, 0xfc, 0x3f, 0x01, 0x02, + 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x01, 0x08, 0x00, 0x01, 0x01, 0xf8, 0x16, 0x02, 0x02, 0xfc, 0x16, 0x02, 0x02, 0x00, 0x17, 0x02, 0x02, + 0x04, 0x17, 0x02, 0x02, 0x90, 0x36, 0x03, 0x03, 0x98, 0x36, 0x03, 0x03, 0xa0, 0x36, 0x03, 0x03, 0xb0, 0x10, 0x04, 0x03, 0xb8, 0x10, 0x04, 0x03, 0x40, 0x2e, 0x05, 0x04, 0x50, 0x2e, 0x05, 0x04, + 0x40, 0x25, 0x07, 0x05, 0x20, 0x06, 0x08, 0x05, 0x30, 0x0d, 0x00, 0x02, 0x34, 0x0d, 0x00, 0x02, 0x38, 0x0d, 0x00, 0x02, 0x3c, 0x0d, 0x00, 0x02, 0x0a, 0x00, 0x01, 0x01, 0x0c, 0x00, 0x01, 0x01, + 0x0e, 0x00, 0x01, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x00, 0x01, 0x01, 0x14, 0x00, 0x01, 0x01, 0x16, 0x00, 0x01, 0x01, 0x08, 0x17, 0x02, 0x02, 0x0c, 0x17, 0x02, 0x02, 0x10, 0x17, 0x02, 0x02, + 0x14, 0x17, 0x02, 0x02, 0xa8, 0x36, 0x03, 0x03, 0xb0, 0x36, 0x03, 0x03, 0xb8, 0x36, 0x03, 0x03, 0xc0, 0x10, 0x04, 0x03, 0xc8, 0x10, 0x04, 0x03, 0x60, 0x2e, 0x05, 0x04, 0x70, 0x2e, 0x05, 0x04, + 0x60, 0x25, 0x07, 0x05, 0x40, 0x06, 0x08, 0x05, 0x40, 0x0d, 0x00, 0x02, 0x44, 0x0d, 0x00, 0x02, 0x48, 0x0d, 0x00, 0x02, 0x4c, 0x0d, 0x00, 0x02, 0x18, 0x00, 0x01, 0x01, 0x1a, 0x00, 0x01, 0x01, + 0x1c, 0x00, 0x01, 0x01, 0x1e, 0x00, 0x01, 0x01, 0x20, 0x00, 0x01, 0x01, 0x22, 0x00, 0x01, 0x01, 0x24, 0x00, 0x01, 0x01, 0x18, 0x17, 0x02, 0x02, 0x1c, 0x17, 0x02, 0x02, 0x20, 0x17, 0x02, 0x02, + 0x24, 0x17, 0x02, 0x02, 0xc0, 0x36, 0x03, 0x03, 0xc8, 0x36, 0x03, 0x03, 0xd0, 0x36, 0x03, 0x03, 0xd0, 0x10, 0x04, 0x03, 0xd8, 0x10, 0x04, 0x03, 0x80, 0x2e, 0x05, 0x04, 0xa0, 0x0a, 0x06, 0x04, + 0x80, 0x25, 0x07, 0x05, 0x60, 0x06, 0x08, 0x05, 0x50, 0x0d, 0x00, 0x02, 0x54, 0x0d, 0x00, 0x02, 0x58, 0x0d, 0x00, 0x02, 0x5c, 0x0d, 0x00, 0x02, 0x26, 0x00, 0x01, 0x01, 0x28, 0x00, 0x01, 0x01, + 0x2a, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x01, 0x01, 0x2e, 0x00, 0x01, 0x01, 0x30, 0x00, 0x01, 0x01, 0x32, 0x00, 0x01, 0x01, 0x28, 0x17, 0x02, 0x02, 0x2c, 0x17, 0x02, 0x02, 0x30, 0x17, 0x02, 0x02, + 0x34, 0x17, 0x02, 0x02, 0xd8, 0x36, 0x03, 0x03, 0xe0, 0x36, 0x03, 0x03, 0xe8, 0x36, 0x03, 0x03, 0xe0, 0x10, 0x04, 0x03, 0xe8, 0x10, 0x04, 0x03, 0x90, 0x2e, 0x05, 0x04, 0xb0, 0x0a, 0x06, 0x04, + 0xa0, 0x25, 0x07, 0x05, 0x40, 0x1d, 0x09, 0x06, 0x60, 0x0d, 0x00, 0x02, 0x64, 0x0d, 0x00, 0x02, 0x68, 0x0d, 0x00, 0x02, 0x6c, 0x0d, 0x00, 0x02, 0x34, 0x00, 0x01, 0x01, 0x36, 0x00, 0x01, 0x01, + 0x38, 0x00, 0x01, 0x01, 0x3a, 0x00, 0x01, 0x01, 0x3c, 0x00, 0x01, 0x01, 0x3e, 0x00, 0x01, 0x01, 0x40, 0x00, 0x01, 0x01, 0x38, 0x17, 0x02, 0x02, 0x3c, 0x17, 0x02, 0x02, 0x40, 0x17, 0x02, 0x02, + 0x44, 0x17, 0x02, 0x02, 0xf0, 0x36, 0x03, 0x03, 0xf8, 0x36, 0x03, 0x03, 0x00, 0x37, 0x03, 0x03, 0xf0, 0x10, 0x04, 0x03, 0xf8, 0x10, 0x04, 0x03, 0xa0, 0x2e, 0x05, 0x04, 0xc0, 0x0a, 0x06, 0x04, + 0xc0, 0x25, 0x07, 0x05, 0x80, 0x1d, 0x09, 0x06, 0x70, 0x0d, 0x00, 0x02, 0x74, 0x0d, 0x00, 0x02, 0x78, 0x0d, 0x00, 0x02, 0x7c, 0x0d, 0x00, 0x02, 0x42, 0x00, 0x01, 0x01, 0x44, 0x00, 0x01, 0x01, + 0x46, 0x00, 0x01, 0x01, 0x48, 0x00, 0x01, 0x01, 0x4a, 0x00, 0x01, 0x01, 0x4c, 0x00, 0x01, 0x01, 0x4e, 0x00, 0x01, 0x01, 0x48, 0x17, 0x02, 0x02, 0x4c, 0x17, 0x02, 0x02, 0x50, 0x17, 0x02, 0x02, + 0x54, 0x17, 0x02, 0x02, 0x08, 0x37, 0x03, 0x03, 0x10, 0x37, 0x03, 0x03, 0x18, 0x37, 0x03, 0x03, 0x00, 0x11, 0x04, 0x03, 0x08, 0x11, 0x04, 0x03, 0xb0, 0x2e, 0x05, 0x04, 0xd0, 0x0a, 0x06, 0x04, + 0xe0, 0x25, 0x07, 0x05, 0xc0, 0x1d, 0x09, 0x06, 0x80, 0x0d, 0x00, 0x02, 0x84, 0x0d, 0x00, 0x02, 0x88, 0x0d, 0x00, 0x02, 0x8c, 0x0d, 0x00, 0x02, 0x50, 0x00, 0x01, 0x01, 0x52, 0x00, 0x01, 0x01, + 0x54, 0x00, 0x01, 0x01, 0x56, 0x00, 0x01, 0x01, 0x58, 0x00, 0x01, 0x01, 0x5a, 0x00, 0x01, 0x01, 0x5c, 0x00, 0x01, 0x01, 0x58, 0x17, 0x02, 0x02, 0x5c, 0x17, 0x02, 0x02, 0x60, 0x17, 0x02, 0x02, + 0x64, 0x17, 0x02, 0x02, 0x20, 0x37, 0x03, 0x03, 0x28, 0x37, 0x03, 0x03, 0x30, 0x37, 0x03, 0x03, 0x10, 0x11, 0x04, 0x03, 0x18, 0x11, 0x04, 0x03, 0xc0, 0x2e, 0x05, 0x04, 0xe0, 0x0a, 0x06, 0x04, + 0x00, 0x26, 0x07, 0x05, 0x00, 0x1e, 0x09, 0x06, 0x90, 0x0d, 0x00, 0x02, 0x94, 0x0d, 0x00, 0x02, 0x98, 0x0d, 0x00, 0x02, 0x9c, 0x0d, 0x00, 0x02, 0x5e, 0x00, 0x01, 0x01, 0x60, 0x00, 0x01, 0x01, + 0x62, 0x00, 0x01, 0x01, 0x64, 0x00, 0x01, 0x01, 0x66, 0x00, 0x01, 0x01, 0x68, 0x00, 0x01, 0x01, 0x6a, 0x00, 0x01, 0x01, 0x68, 0x17, 0x02, 0x02, 0x6c, 0x17, 0x02, 0x02, 0x70, 0x17, 0x02, 0x02, + 0x74, 0x17, 0x02, 0x02, 0x38, 0x37, 0x03, 0x03, 0x40, 0x37, 0x03, 0x03, 0x48, 0x37, 0x03, 0x03, 0x20, 0x11, 0x04, 0x03, 0x28, 0x11, 0x04, 0x03, 0xd0, 0x2e, 0x05, 0x04, 0xf0, 0x0a, 0x06, 0x04, + 0x20, 0x26, 0x07, 0x05, 0x40, 0x1e, 0x09, 0x06, 0xa0, 0x0d, 0x00, 0x02, 0xa4, 0x0d, 0x00, 0x02, 0xa8, 0x0d, 0x00, 0x02, 0xac, 0x0d, 0x00, 0x02, 0x6c, 0x00, 0x01, 0x01, 0x6e, 0x00, 0x01, 0x01, + 0x70, 0x00, 0x01, 0x01, 0x72, 0x00, 0x01, 0x01, 0x74, 0x00, 0x01, 0x01, 0x76, 0x00, 0x01, 0x01, 0x78, 0x00, 0x01, 0x01, 0x78, 0x17, 0x02, 0x02, 0x7c, 0x17, 0x02, 0x02, 0x80, 0x17, 0x02, 0x02, + 0x84, 0x17, 0x02, 0x02, 0x50, 0x37, 0x03, 0x03, 0x58, 0x37, 0x03, 0x03, 0x60, 0x37, 0x03, 0x03, 0x30, 0x11, 0x04, 0x03, 0x38, 0x11, 0x04, 0x03, 0xe0, 0x2e, 0x05, 0x04, 0x00, 0x0b, 0x06, 0x04, + 0x40, 0x26, 0x07, 0x05, 0x80, 0x1e, 0x09, 0x06, 0xb0, 0x0d, 0x00, 0x02, 0xb4, 0x0d, 0x00, 0x02, 0xb8, 0x0d, 0x00, 0x02, 0xbc, 0x0d, 0x00, 0x02, 0x7a, 0x00, 0x01, 0x01, 0x7c, 0x00, 0x01, 0x01, + 0x7e, 0x00, 0x01, 0x01, 0x80, 0x00, 0x01, 0x01, 0x82, 0x00, 0x01, 0x01, 0x84, 0x00, 0x01, 0x01, 0x86, 0x00, 0x01, 0x01, 0x88, 0x17, 0x02, 0x02, 0x8c, 0x17, 0x02, 0x02, 0x90, 0x17, 0x02, 0x02, + 0x94, 0x17, 0x02, 0x02, 0x68, 0x37, 0x03, 0x03, 0x70, 0x37, 0x03, 0x03, 0x78, 0x37, 0x03, 0x03, 0x40, 0x11, 0x04, 0x03, 0x48, 0x11, 0x04, 0x03, 0xf0, 0x2e, 0x05, 0x04, 0x10, 0x0b, 0x06, 0x04, + 0x60, 0x26, 0x07, 0x05, 0xc0, 0x1e, 0x09, 0x06, 0xc0, 0x0d, 0x00, 0x02, 0xc4, 0x0d, 0x00, 0x02, 0xc8, 0x0d, 0x00, 0x02, 0xcc, 0x0d, 0x00, 0x02, 0x88, 0x00, 0x01, 0x01, 0x8a, 0x00, 0x01, 0x01, + 0x8c, 0x00, 0x01, 0x01, 0x8e, 0x00, 0x01, 0x01, 0x90, 0x00, 0x01, 0x01, 0x92, 0x00, 0x01, 0x01, 0x94, 0x00, 0x01, 0x01, 0x98, 0x17, 0x02, 0x02, 0x9c, 0x17, 0x02, 0x02, 0xa0, 0x17, 0x02, 0x02, + 0xa4, 0x17, 0x02, 0x02, 0x80, 0x37, 0x03, 0x03, 0x88, 0x37, 0x03, 0x03, 0x90, 0x37, 0x03, 0x03, 0x50, 0x11, 0x04, 0x03, 0x58, 0x11, 0x04, 0x03, 0x00, 0x2f, 0x05, 0x04, 0x20, 0x0b, 0x06, 0x04, + 0x80, 0x26, 0x07, 0x05, 0x00, 0x1f, 0x09, 0x06, 0xd0, 0x0d, 0x00, 0x02, 0xd4, 0x0d, 0x00, 0x02, 0xd8, 0x0d, 0x00, 0x02, 0xdc, 0x0d, 0x00, 0x02, 0x96, 0x00, 0x01, 0x01, 0x98, 0x00, 0x01, 0x01, + 0x9a, 0x00, 0x01, 0x01, 0x9c, 0x00, 0x01, 0x01, 0x9e, 0x00, 0x01, 0x01, 0xa0, 0x00, 0x01, 0x01, 0xa2, 0x00, 0x01, 0x01, 0xa8, 0x17, 0x02, 0x02, 0xac, 0x17, 0x02, 0x02, 0xb0, 0x17, 0x02, 0x02, + 0xb4, 0x17, 0x02, 0x02, 0x98, 0x37, 0x03, 0x03, 0xa0, 0x37, 0x03, 0x03, 0xa8, 0x37, 0x03, 0x03, 0x60, 0x11, 0x04, 0x03, 0x68, 0x11, 0x04, 0x03, 0x10, 0x2f, 0x05, 0x04, 0x30, 0x0b, 0x06, 0x04, + 0xa0, 0x26, 0x07, 0x05, 0x40, 0x1f, 0x09, 0x06, 0xe0, 0x0d, 0x00, 0x02, 0xe4, 0x0d, 0x00, 0x02, 0xe8, 0x0d, 0x00, 0x02, 0xec, 0x0d, 0x00, 0x02, 0xa4, 0x00, 0x01, 0x01, 0xa6, 0x00, 0x01, 0x01, + 0xa8, 0x00, 0x01, 0x01, 0xaa, 0x00, 0x01, 0x01, 0xac, 0x00, 0x01, 0x01, 0xae, 0x00, 0x01, 0x01, 0xb0, 0x00, 0x01, 0x01, 0xb8, 0x17, 0x02, 0x02, 0xbc, 0x17, 0x02, 0x02, 0xc0, 0x17, 0x02, 0x02, + 0xc4, 0x17, 0x02, 0x02, 0xb0, 0x37, 0x03, 0x03, 0xb8, 0x37, 0x03, 0x03, 0xc0, 0x37, 0x03, 0x03, 0x70, 0x11, 0x04, 0x03, 0x78, 0x11, 0x04, 0x03, 0x20, 0x2f, 0x05, 0x04, 0x40, 0x0b, 0x06, 0x04, + 0xc0, 0x26, 0x07, 0x05, 0x80, 0x1f, 0x09, 0x06, 0xf0, 0x0d, 0x00, 0x02, 0xf4, 0x0d, 0x00, 0x02, 0xf8, 0x0d, 0x00, 0x02, 0xfc, 0x0d, 0x00, 0x02, 0xb2, 0x00, 0x01, 0x01, 0xb4, 0x00, 0x01, 0x01, + 0xb6, 0x00, 0x01, 0x01, 0xb8, 0x00, 0x01, 0x01, 0xba, 0x00, 0x01, 0x01, 0xbc, 0x00, 0x01, 0x01, 0xbe, 0x00, 0x01, 0x01, 0xc8, 0x17, 0x02, 0x02, 0xcc, 0x17, 0x02, 0x02, 0xd0, 0x17, 0x02, 0x02, + 0xd4, 0x17, 0x02, 0x02, 0xc8, 0x37, 0x03, 0x03, 0xd0, 0x37, 0x03, 0x03, 0xd8, 0x37, 0x03, 0x03, 0x80, 0x11, 0x04, 0x03, 0x88, 0x11, 0x04, 0x03, 0x30, 0x2f, 0x05, 0x04, 0x50, 0x0b, 0x06, 0x04, + 0xe0, 0x26, 0x07, 0x05, 0xc0, 0x1f, 0x09, 0x06, 0x00, 0x0e, 0x00, 0x02, 0x04, 0x0e, 0x00, 0x02, 0x08, 0x0e, 0x00, 0x02, 0x0c, 0x0e, 0x00, 0x02, 0xc0, 0x00, 0x01, 0x01, 0xc2, 0x00, 0x01, 0x01, + 0xc4, 0x00, 0x01, 0x01, 0xc6, 0x00, 0x01, 0x01, 0xc8, 0x00, 0x01, 0x01, 0xca, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x01, 0x01, 0xd8, 0x17, 0x02, 0x02, 0xdc, 0x17, 0x02, 0x02, 0xe0, 0x17, 0x02, 0x02, + 0xe4, 0x17, 0x02, 0x02, 0xe0, 0x37, 0x03, 0x03, 0xe8, 0x37, 0x03, 0x03, 0xf0, 0x37, 0x03, 0x03, 0x90, 0x11, 0x04, 0x03, 0x98, 0x11, 0x04, 0x03, 0x40, 0x2f, 0x05, 0x04, 0x60, 0x0b, 0x06, 0x04, + 0x00, 0x27, 0x07, 0x05, 0x00, 0x20, 0x09, 0x06, 0x10, 0x0e, 0x00, 0x02, 0x14, 0x0e, 0x00, 0x02, 0x18, 0x0e, 0x00, 0x02, 0x1c, 0x0e, 0x00, 0x02, 0xce, 0x00, 0x01, 0x01, 0xd0, 0x00, 0x01, 0x01, + 0xd2, 0x00, 0x01, 0x01, 0xd4, 0x00, 0x01, 0x01, 0xd6, 0x00, 0x01, 0x01, 0xd8, 0x00, 0x01, 0x01, 0xda, 0x00, 0x01, 0x01, 0xe8, 0x17, 0x02, 0x02, 0xec, 0x17, 0x02, 0x02, 0xf0, 0x17, 0x02, 0x02, + 0xf4, 0x17, 0x02, 0x02, 0xf8, 0x37, 0x03, 0x03, 0x00, 0x38, 0x03, 0x03, 0x08, 0x38, 0x03, 0x03, 0xa0, 0x11, 0x04, 0x03, 0xa8, 0x11, 0x04, 0x03, 0x50, 0x2f, 0x05, 0x04, 0x70, 0x0b, 0x06, 0x04, + 0x20, 0x27, 0x07, 0x05, 0x40, 0x20, 0x09, 0x06, 0x20, 0x0e, 0x00, 0x02, 0x24, 0x0e, 0x00, 0x02, 0x28, 0x0e, 0x00, 0x02, 0x2c, 0x0e, 0x00, 0x02, 0xdc, 0x00, 0x01, 0x01, 0xde, 0x00, 0x01, 0x01, + 0xe0, 0x00, 0x01, 0x01, 0xe2, 0x00, 0x01, 0x01, 0xe4, 0x00, 0x01, 0x01, 0xe6, 0x00, 0x01, 0x01, 0xe8, 0x00, 0x01, 0x01, 0xf8, 0x17, 0x02, 0x02, 0xfc, 0x17, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, + 0x04, 0x18, 0x02, 0x02, 0x10, 0x38, 0x03, 0x03, 0x18, 0x38, 0x03, 0x03, 0x20, 0x38, 0x03, 0x03, 0xb0, 0x11, 0x04, 0x03, 0xb8, 0x11, 0x04, 0x03, 0x60, 0x2f, 0x05, 0x04, 0x80, 0x0b, 0x06, 0x04, + 0x40, 0x27, 0x07, 0x05, 0x80, 0x20, 0x09, 0x06, 0x30, 0x0e, 0x00, 0x02, 0x34, 0x0e, 0x00, 0x02, 0x38, 0x0e, 0x00, 0x02, 0x3c, 0x0e, 0x00, 0x02, 0xea, 0x00, 0x01, 0x01, 0xec, 0x00, 0x01, 0x01, + 0xee, 0x00, 0x01, 0x01, 0xf0, 0x00, 0x01, 0x01, 0xf2, 0x00, 0x01, 0x01, 0xf4, 0x00, 0x01, 0x01, 0xf6, 0x00, 0x01, 0x01, 0x08, 0x18, 0x02, 0x02, 0x0c, 0x18, 0x02, 0x02, 0x10, 0x18, 0x02, 0x02, + 0x14, 0x18, 0x02, 0x02, 0x28, 0x38, 0x03, 0x03, 0x30, 0x38, 0x03, 0x03, 0x38, 0x38, 0x03, 0x03, 0xc0, 0x11, 0x04, 0x03, 0xc8, 0x11, 0x04, 0x03, 0x70, 0x2f, 0x05, 0x04, 0x90, 0x0b, 0x06, 0x04, + 0x60, 0x27, 0x07, 0x05, 0xc0, 0x20, 0x09, 0x06, 0x40, 0x0e, 0x00, 0x02, 0x44, 0x0e, 0x00, 0x02, 0x48, 0x0e, 0x00, 0x02, 0x4c, 0x0e, 0x00, 0x02, 0xf8, 0x00, 0x01, 0x01, 0xfa, 0x00, 0x01, 0x01, + 0xfc, 0x00, 0x01, 0x01, 0xfe, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x18, 0x18, 0x02, 0x02, 0x1c, 0x18, 0x02, 0x02, 0x20, 0x18, 0x02, 0x02, + 0x24, 0x18, 0x02, 0x02, 0x40, 0x38, 0x03, 0x03, 0x48, 0x38, 0x03, 0x03, 0x50, 0x38, 0x03, 0x03, 0xd0, 0x11, 0x04, 0x03, 0xd8, 0x11, 0x04, 0x03, 0x80, 0x2f, 0x05, 0x04, 0xa0, 0x0b, 0x06, 0x04, + 0x80, 0x27, 0x07, 0x05, 0x00, 0x21, 0x09, 0x06, 0x50, 0x0e, 0x00, 0x02, 0x54, 0x0e, 0x00, 0x02, 0x58, 0x0e, 0x00, 0x02, 0x5c, 0x0e, 0x00, 0x02, 0x06, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, + 0x0a, 0x01, 0x01, 0x01, 0x0c, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x28, 0x18, 0x02, 0x02, 0x2c, 0x18, 0x02, 0x02, 0x30, 0x18, 0x02, 0x02, + 0x34, 0x18, 0x02, 0x02, 0x58, 0x38, 0x03, 0x03, 0x60, 0x38, 0x03, 0x03, 0x68, 0x38, 0x03, 0x03, 0xe0, 0x11, 0x04, 0x03, 0xe8, 0x11, 0x04, 0x03, 0x90, 0x2f, 0x05, 0x04, 0xb0, 0x0b, 0x06, 0x04, + 0xa0, 0x27, 0x07, 0x05, 0x40, 0x21, 0x09, 0x06, 0x60, 0x0e, 0x00, 0x02, 0x64, 0x0e, 0x00, 0x02, 0x68, 0x0e, 0x00, 0x02, 0x6c, 0x0e, 0x00, 0x02, 0x14, 0x01, 0x01, 0x01, 0x16, 0x01, 0x01, 0x01, + 0x18, 0x01, 0x01, 0x01, 0x1a, 0x01, 0x01, 0x01, 0x1c, 0x01, 0x01, 0x01, 0x1e, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x38, 0x18, 0x02, 0x02, 0x3c, 0x18, 0x02, 0x02, 0x40, 0x18, 0x02, 0x02, + 0x44, 0x18, 0x02, 0x02, 0x70, 0x38, 0x03, 0x03, 0x78, 0x38, 0x03, 0x03, 0x80, 0x38, 0x03, 0x03, 0xf0, 0x11, 0x04, 0x03, 0xf8, 0x11, 0x04, 0x03, 0xa0, 0x2f, 0x05, 0x04, 0xc0, 0x0b, 0x06, 0x04, + 0xc0, 0x27, 0x07, 0x05, 0x80, 0x21, 0x09, 0x06, 0x70, 0x0e, 0x00, 0x02, 0x74, 0x0e, 0x00, 0x02, 0x78, 0x0e, 0x00, 0x02, 0x7c, 0x0e, 0x00, 0x02, 0x22, 0x01, 0x01, 0x01, 0x24, 0x01, 0x01, 0x01, + 0x26, 0x01, 0x01, 0x01, 0x28, 0x01, 0x01, 0x01, 0x2a, 0x01, 0x01, 0x01, 0x2c, 0x01, 0x01, 0x01, 0x2e, 0x01, 0x01, 0x01, 0x48, 0x18, 0x02, 0x02, 0x4c, 0x18, 0x02, 0x02, 0x50, 0x18, 0x02, 0x02, + 0x54, 0x18, 0x02, 0x02, 0x88, 0x38, 0x03, 0x03, 0x90, 0x38, 0x03, 0x03, 0x98, 0x38, 0x03, 0x03, 0x00, 0x12, 0x04, 0x03, 0x08, 0x12, 0x04, 0x03, 0xb0, 0x2f, 0x05, 0x04, 0xd0, 0x0b, 0x06, 0x04, + 0xe0, 0x27, 0x07, 0x05, 0xc0, 0x21, 0x09, 0x06, 0x80, 0x0e, 0x00, 0x02, 0x84, 0x0e, 0x00, 0x02, 0x88, 0x0e, 0x00, 0x02, 0x8c, 0x0e, 0x00, 0x02, 0x30, 0x01, 0x01, 0x01, 0x32, 0x01, 0x01, 0x01, + 0x34, 0x01, 0x01, 0x01, 0x36, 0x01, 0x01, 0x01, 0x38, 0x01, 0x01, 0x01, 0x3a, 0x01, 0x01, 0x01, 0x58, 0x18, 0x02, 0x02, 0x5c, 0x18, 0x02, 0x02, 0x60, 0x18, 0x02, 0x02, 0x64, 0x18, 0x02, 0x02, + 0x68, 0x18, 0x02, 0x02, 0xa0, 0x38, 0x03, 0x03, 0xa8, 0x38, 0x03, 0x03, 0xb0, 0x38, 0x03, 0x03, 0x10, 0x12, 0x04, 0x03, 0x18, 0x12, 0x04, 0x03, 0xc0, 0x2f, 0x05, 0x04, 0xe0, 0x0b, 0x06, 0x04, + 0x00, 0x28, 0x07, 0x05, 0x00, 0x22, 0x09, 0x06, 0x90, 0x0e, 0x00, 0x02, 0x94, 0x0e, 0x00, 0x02, 0x98, 0x0e, 0x00, 0x02, 0x9c, 0x0e, 0x00, 0x02, 0x3c, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x01, 0x01, + 0x40, 0x01, 0x01, 0x01, 0x42, 0x01, 0x01, 0x01, 0x44, 0x01, 0x01, 0x01, 0x46, 0x01, 0x01, 0x01, 0x6c, 0x18, 0x02, 0x02, 0x70, 0x18, 0x02, 0x02, 0x74, 0x18, 0x02, 0x02, 0x78, 0x18, 0x02, 0x02, + 0x7c, 0x18, 0x02, 0x02, 0xb8, 0x38, 0x03, 0x03, 0xc0, 0x38, 0x03, 0x03, 0xc8, 0x38, 0x03, 0x03, 0x20, 0x12, 0x04, 0x03, 0x28, 0x12, 0x04, 0x03, 0xd0, 0x2f, 0x05, 0x04, 0xf0, 0x0b, 0x06, 0x04, + 0x20, 0x28, 0x07, 0x05, 0x40, 0x22, 0x09, 0x06, 0xa0, 0x0e, 0x00, 0x02, 0xa4, 0x0e, 0x00, 0x02, 0xa8, 0x0e, 0x00, 0x02, 0xac, 0x0e, 0x00, 0x02, 0x48, 0x01, 0x01, 0x01, 0x4a, 0x01, 0x01, 0x01, + 0x4c, 0x01, 0x01, 0x01, 0x4e, 0x01, 0x01, 0x01, 0x50, 0x01, 0x01, 0x01, 0x52, 0x01, 0x01, 0x01, 0x80, 0x18, 0x02, 0x02, 0x84, 0x18, 0x02, 0x02, 0x88, 0x18, 0x02, 0x02, 0x8c, 0x18, 0x02, 0x02, + 0x90, 0x18, 0x02, 0x02, 0xd0, 0x38, 0x03, 0x03, 0xd8, 0x38, 0x03, 0x03, 0xe0, 0x38, 0x03, 0x03, 0x30, 0x12, 0x04, 0x03, 0x38, 0x12, 0x04, 0x03, 0xe0, 0x2f, 0x05, 0x04, 0x00, 0x0c, 0x06, 0x04, + 0x40, 0x28, 0x07, 0x05, 0x80, 0x22, 0x09, 0x06, 0xb0, 0x0e, 0x00, 0x02, 0xb4, 0x0e, 0x00, 0x02, 0xb8, 0x0e, 0x00, 0x02, 0xbc, 0x0e, 0x00, 0x02, 0x54, 0x01, 0x01, 0x01, 0x56, 0x01, 0x01, 0x01, + 0x58, 0x01, 0x01, 0x01, 0x5a, 0x01, 0x01, 0x01, 0x5c, 0x01, 0x01, 0x01, 0x5e, 0x01, 0x01, 0x01, 0x94, 0x18, 0x02, 0x02, 0x98, 0x18, 0x02, 0x02, 0x9c, 0x18, 0x02, 0x02, 0xa0, 0x18, 0x02, 0x02, + 0xa4, 0x18, 0x02, 0x02, 0xe8, 0x38, 0x03, 0x03, 0xf0, 0x38, 0x03, 0x03, 0xf8, 0x38, 0x03, 0x03, 0x40, 0x12, 0x04, 0x03, 0x48, 0x12, 0x04, 0x03, 0xf0, 0x2f, 0x05, 0x04, 0x10, 0x0c, 0x06, 0x04, + 0x60, 0x28, 0x07, 0x05, 0xc0, 0x22, 0x09, 0x06, 0xc0, 0x0e, 0x00, 0x02, 0xc4, 0x0e, 0x00, 0x02, 0xc8, 0x0e, 0x00, 0x02, 0xcc, 0x0e, 0x00, 0x02, 0x60, 0x01, 0x01, 0x01, 0x62, 0x01, 0x01, 0x01, + 0x64, 0x01, 0x01, 0x01, 0x66, 0x01, 0x01, 0x01, 0x68, 0x01, 0x01, 0x01, 0x6a, 0x01, 0x01, 0x01, 0xa8, 0x18, 0x02, 0x02, 0xac, 0x18, 0x02, 0x02, 0xb0, 0x18, 0x02, 0x02, 0xb4, 0x18, 0x02, 0x02, + 0xb8, 0x18, 0x02, 0x02, 0x00, 0x39, 0x03, 0x03, 0x08, 0x39, 0x03, 0x03, 0x10, 0x39, 0x03, 0x03, 0x50, 0x12, 0x04, 0x03, 0x58, 0x12, 0x04, 0x03, 0x00, 0x30, 0x05, 0x04, 0x20, 0x0c, 0x06, 0x04, + 0x80, 0x28, 0x07, 0x05, 0x00, 0x23, 0x09, 0x06, 0xd0, 0x0e, 0x00, 0x02, 0xd4, 0x0e, 0x00, 0x02, 0xd8, 0x0e, 0x00, 0x02, 0xdc, 0x0e, 0x00, 0x02, 0x6c, 0x01, 0x01, 0x01, 0x6e, 0x01, 0x01, 0x01, + 0x70, 0x01, 0x01, 0x01, 0x72, 0x01, 0x01, 0x01, 0x74, 0x01, 0x01, 0x01, 0x76, 0x01, 0x01, 0x01, 0xbc, 0x18, 0x02, 0x02, 0xc0, 0x18, 0x02, 0x02, 0xc4, 0x18, 0x02, 0x02, 0xc8, 0x18, 0x02, 0x02, + 0xcc, 0x18, 0x02, 0x02, 0x18, 0x39, 0x03, 0x03, 0x20, 0x39, 0x03, 0x03, 0x28, 0x39, 0x03, 0x03, 0x60, 0x12, 0x04, 0x03, 0x68, 0x12, 0x04, 0x03, 0x10, 0x30, 0x05, 0x04, 0x30, 0x0c, 0x06, 0x04, + 0xa0, 0x28, 0x07, 0x05, 0x40, 0x23, 0x09, 0x06, 0xe0, 0x0e, 0x00, 0x02, 0xe4, 0x0e, 0x00, 0x02, 0xe8, 0x0e, 0x00, 0x02, 0xec, 0x0e, 0x00, 0x02, 0x78, 0x01, 0x01, 0x01, 0x7a, 0x01, 0x01, 0x01, + 0x7c, 0x01, 0x01, 0x01, 0x7e, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x82, 0x01, 0x01, 0x01, 0xd0, 0x18, 0x02, 0x02, 0xd4, 0x18, 0x02, 0x02, 0xd8, 0x18, 0x02, 0x02, 0xdc, 0x18, 0x02, 0x02, + 0xe0, 0x18, 0x02, 0x02, 0x30, 0x39, 0x03, 0x03, 0x38, 0x39, 0x03, 0x03, 0x40, 0x39, 0x03, 0x03, 0x70, 0x12, 0x04, 0x03, 0x78, 0x12, 0x04, 0x03, 0x20, 0x30, 0x05, 0x04, 0x40, 0x0c, 0x06, 0x04, + 0xc0, 0x28, 0x07, 0x05, 0x80, 0x3f, 0x0a, 0x07, 0xf0, 0x0e, 0x00, 0x02, 0xf4, 0x0e, 0x00, 0x02, 0xf8, 0x0e, 0x00, 0x02, 0xfc, 0x0e, 0x00, 0x02, 0x84, 0x01, 0x01, 0x01, 0x86, 0x01, 0x01, 0x01, + 0x88, 0x01, 0x01, 0x01, 0x8a, 0x01, 0x01, 0x01, 0x8c, 0x01, 0x01, 0x01, 0x8e, 0x01, 0x01, 0x01, 0xe4, 0x18, 0x02, 0x02, 0xe8, 0x18, 0x02, 0x02, 0xec, 0x18, 0x02, 0x02, 0xf0, 0x18, 0x02, 0x02, + 0xf4, 0x18, 0x02, 0x02, 0x48, 0x39, 0x03, 0x03, 0x50, 0x39, 0x03, 0x03, 0x58, 0x39, 0x03, 0x03, 0x80, 0x12, 0x04, 0x03, 0x88, 0x12, 0x04, 0x03, 0x30, 0x30, 0x05, 0x04, 0x50, 0x0c, 0x06, 0x04, + 0xe0, 0x28, 0x07, 0x05, 0x00, 0x00, 0x0a, 0x06, 0x00, 0x0f, 0x00, 0x02, 0x04, 0x0f, 0x00, 0x02, 0x08, 0x0f, 0x00, 0x02, 0x0c, 0x0f, 0x00, 0x02, 0x90, 0x01, 0x01, 0x01, 0x92, 0x01, 0x01, 0x01, + 0x94, 0x01, 0x01, 0x01, 0x96, 0x01, 0x01, 0x01, 0x98, 0x01, 0x01, 0x01, 0x9a, 0x01, 0x01, 0x01, 0xf8, 0x18, 0x02, 0x02, 0xfc, 0x18, 0x02, 0x02, 0x00, 0x19, 0x02, 0x02, 0x04, 0x19, 0x02, 0x02, + 0x08, 0x19, 0x02, 0x02, 0x60, 0x39, 0x03, 0x03, 0x68, 0x39, 0x03, 0x03, 0x70, 0x39, 0x03, 0x03, 0x90, 0x12, 0x04, 0x03, 0x98, 0x12, 0x04, 0x03, 0x40, 0x30, 0x05, 0x04, 0x60, 0x0c, 0x06, 0x04, + 0x00, 0x29, 0x07, 0x05, 0x40, 0x00, 0x0a, 0x06, 0x10, 0x0f, 0x00, 0x02, 0x14, 0x0f, 0x00, 0x02, 0x18, 0x0f, 0x00, 0x02, 0x1c, 0x0f, 0x00, 0x02, 0x9c, 0x01, 0x01, 0x01, 0x9e, 0x01, 0x01, 0x01, + 0xa0, 0x01, 0x01, 0x01, 0xa2, 0x01, 0x01, 0x01, 0xa4, 0x01, 0x01, 0x01, 0xa6, 0x01, 0x01, 0x01, 0x0c, 0x19, 0x02, 0x02, 0x10, 0x19, 0x02, 0x02, 0x14, 0x19, 0x02, 0x02, 0x18, 0x19, 0x02, 0x02, + 0x1c, 0x19, 0x02, 0x02, 0x78, 0x39, 0x03, 0x03, 0x80, 0x39, 0x03, 0x03, 0x88, 0x39, 0x03, 0x03, 0xa0, 0x12, 0x04, 0x03, 0xa8, 0x12, 0x04, 0x03, 0x50, 0x30, 0x05, 0x04, 0x70, 0x0c, 0x06, 0x04, + 0x20, 0x29, 0x07, 0x05, 0x80, 0x00, 0x0a, 0x06, 0x20, 0x0f, 0x00, 0x02, 0x24, 0x0f, 0x00, 0x02, 0x28, 0x0f, 0x00, 0x02, 0x2c, 0x0f, 0x00, 0x02, 0xa8, 0x01, 0x01, 0x01, 0xaa, 0x01, 0x01, 0x01, + 0xac, 0x01, 0x01, 0x01, 0xae, 0x01, 0x01, 0x01, 0xb0, 0x01, 0x01, 0x01, 0xb2, 0x01, 0x01, 0x01, 0x20, 0x19, 0x02, 0x02, 0x24, 0x19, 0x02, 0x02, 0x28, 0x19, 0x02, 0x02, 0x2c, 0x19, 0x02, 0x02, + 0x30, 0x19, 0x02, 0x02, 0x90, 0x39, 0x03, 0x03, 0x98, 0x39, 0x03, 0x03, 0xa0, 0x39, 0x03, 0x03, 0xb0, 0x12, 0x04, 0x03, 0xb8, 0x12, 0x04, 0x03, 0x60, 0x30, 0x05, 0x04, 0x80, 0x0c, 0x06, 0x04, + 0x40, 0x29, 0x07, 0x05, 0xc0, 0x00, 0x0a, 0x06, 0x30, 0x0f, 0x00, 0x02, 0x34, 0x0f, 0x00, 0x02, 0x38, 0x0f, 0x00, 0x02, 0x3c, 0x0f, 0x00, 0x02, 0xb4, 0x01, 0x01, 0x01, 0xb6, 0x01, 0x01, 0x01, + 0xb8, 0x01, 0x01, 0x01, 0xba, 0x01, 0x01, 0x01, 0xbc, 0x01, 0x01, 0x01, 0xbe, 0x01, 0x01, 0x01, 0x34, 0x19, 0x02, 0x02, 0x38, 0x19, 0x02, 0x02, 0x3c, 0x19, 0x02, 0x02, 0x40, 0x19, 0x02, 0x02, + 0x44, 0x19, 0x02, 0x02, 0xa8, 0x39, 0x03, 0x03, 0xb0, 0x39, 0x03, 0x03, 0xb8, 0x39, 0x03, 0x03, 0xc0, 0x12, 0x04, 0x03, 0xc8, 0x12, 0x04, 0x03, 0x70, 0x30, 0x05, 0x04, 0x90, 0x0c, 0x06, 0x04, + 0x60, 0x29, 0x07, 0x05, 0x00, 0x01, 0x0a, 0x06, 0x40, 0x0f, 0x00, 0x02, 0x44, 0x0f, 0x00, 0x02, 0x48, 0x0f, 0x00, 0x02, 0x4c, 0x0f, 0x00, 0x02, 0xc0, 0x01, 0x01, 0x01, 0xc2, 0x01, 0x01, 0x01, + 0xc4, 0x01, 0x01, 0x01, 0xc6, 0x01, 0x01, 0x01, 0xc8, 0x01, 0x01, 0x01, 0xca, 0x01, 0x01, 0x01, 0x48, 0x19, 0x02, 0x02, 0x4c, 0x19, 0x02, 0x02, 0x50, 0x19, 0x02, 0x02, 0x54, 0x19, 0x02, 0x02, + 0x58, 0x19, 0x02, 0x02, 0xc0, 0x39, 0x03, 0x03, 0xc8, 0x39, 0x03, 0x03, 0xd0, 0x39, 0x03, 0x03, 0xd0, 0x12, 0x04, 0x03, 0xd8, 0x12, 0x04, 0x03, 0x80, 0x30, 0x05, 0x04, 0xa0, 0x0c, 0x06, 0x04, + 0x80, 0x29, 0x07, 0x05, 0x40, 0x01, 0x0a, 0x06, 0x50, 0x0f, 0x00, 0x02, 0x54, 0x0f, 0x00, 0x02, 0x58, 0x0f, 0x00, 0x02, 0x5c, 0x0f, 0x00, 0x02, 0xcc, 0x01, 0x01, 0x01, 0xce, 0x01, 0x01, 0x01, + 0xd0, 0x01, 0x01, 0x01, 0xd2, 0x01, 0x01, 0x01, 0xd4, 0x01, 0x01, 0x01, 0xd6, 0x01, 0x01, 0x01, 0x5c, 0x19, 0x02, 0x02, 0x60, 0x19, 0x02, 0x02, 0x64, 0x19, 0x02, 0x02, 0x68, 0x19, 0x02, 0x02, + 0x6c, 0x19, 0x02, 0x02, 0xd8, 0x39, 0x03, 0x03, 0xe0, 0x39, 0x03, 0x03, 0xe8, 0x39, 0x03, 0x03, 0xe0, 0x12, 0x04, 0x03, 0xe8, 0x12, 0x04, 0x03, 0x90, 0x30, 0x05, 0x04, 0xb0, 0x0c, 0x06, 0x04, + 0xa0, 0x29, 0x07, 0x05, 0x80, 0x01, 0x0a, 0x06, 0x60, 0x0f, 0x00, 0x02, 0x64, 0x0f, 0x00, 0x02, 0x68, 0x0f, 0x00, 0x02, 0x6c, 0x0f, 0x00, 0x02, 0xd8, 0x01, 0x01, 0x01, 0xda, 0x01, 0x01, 0x01, + 0xdc, 0x01, 0x01, 0x01, 0xde, 0x01, 0x01, 0x01, 0xe0, 0x01, 0x01, 0x01, 0xe2, 0x01, 0x01, 0x01, 0x70, 0x19, 0x02, 0x02, 0x74, 0x19, 0x02, 0x02, 0x78, 0x19, 0x02, 0x02, 0x7c, 0x19, 0x02, 0x02, + 0x80, 0x19, 0x02, 0x02, 0xf0, 0x39, 0x03, 0x03, 0xf8, 0x39, 0x03, 0x03, 0x00, 0x3a, 0x03, 0x03, 0xf0, 0x12, 0x04, 0x03, 0xf8, 0x12, 0x04, 0x03, 0xa0, 0x30, 0x05, 0x04, 0xc0, 0x0c, 0x06, 0x04, + 0xc0, 0x29, 0x07, 0x05, 0xc0, 0x01, 0x0a, 0x06, 0x70, 0x0f, 0x00, 0x02, 0x74, 0x0f, 0x00, 0x02, 0x78, 0x0f, 0x00, 0x02, 0x7c, 0x0f, 0x00, 0x02, 0xe4, 0x01, 0x01, 0x01, 0xe6, 0x01, 0x01, 0x01, + 0xe8, 0x01, 0x01, 0x01, 0xea, 0x01, 0x01, 0x01, 0xec, 0x01, 0x01, 0x01, 0xee, 0x01, 0x01, 0x01, 0x84, 0x19, 0x02, 0x02, 0x88, 0x19, 0x02, 0x02, 0x8c, 0x19, 0x02, 0x02, 0x90, 0x19, 0x02, 0x02, + 0x94, 0x19, 0x02, 0x02, 0x08, 0x3a, 0x03, 0x03, 0x10, 0x3a, 0x03, 0x03, 0x18, 0x3a, 0x03, 0x03, 0x00, 0x13, 0x04, 0x03, 0x08, 0x13, 0x04, 0x03, 0xb0, 0x30, 0x05, 0x04, 0xd0, 0x0c, 0x06, 0x04, + 0xe0, 0x29, 0x07, 0x05, 0x00, 0x02, 0x0a, 0x06, 0x80, 0x0f, 0x00, 0x02, 0x84, 0x0f, 0x00, 0x02, 0x88, 0x0f, 0x00, 0x02, 0x8c, 0x0f, 0x00, 0x02, 0xf0, 0x01, 0x01, 0x01, 0xf2, 0x01, 0x01, 0x01, + 0xf4, 0x01, 0x01, 0x01, 0xf6, 0x01, 0x01, 0x01, 0xf8, 0x01, 0x01, 0x01, 0xfa, 0x01, 0x01, 0x01, 0x98, 0x19, 0x02, 0x02, 0x9c, 0x19, 0x02, 0x02, 0xa0, 0x19, 0x02, 0x02, 0xa4, 0x19, 0x02, 0x02, + 0xa8, 0x19, 0x02, 0x02, 0x20, 0x3a, 0x03, 0x03, 0x28, 0x3a, 0x03, 0x03, 0x30, 0x3a, 0x03, 0x03, 0x10, 0x13, 0x04, 0x03, 0x18, 0x13, 0x04, 0x03, 0xc0, 0x30, 0x05, 0x04, 0xe0, 0x0c, 0x06, 0x04, + 0x00, 0x2a, 0x07, 0x05, 0x40, 0x02, 0x0a, 0x06, 0x90, 0x0f, 0x00, 0x02, 0x94, 0x0f, 0x00, 0x02, 0x98, 0x0f, 0x00, 0x02, 0x9c, 0x0f, 0x00, 0x02, 0xfc, 0x01, 0x01, 0x01, 0xfe, 0x01, 0x01, 0x01, + 0x00, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x06, 0x02, 0x01, 0x01, 0xac, 0x19, 0x02, 0x02, 0xb0, 0x19, 0x02, 0x02, 0xb4, 0x19, 0x02, 0x02, 0xb8, 0x19, 0x02, 0x02, + 0xbc, 0x19, 0x02, 0x02, 0x38, 0x3a, 0x03, 0x03, 0x40, 0x3a, 0x03, 0x03, 0x48, 0x3a, 0x03, 0x03, 0x20, 0x13, 0x04, 0x03, 0x28, 0x13, 0x04, 0x03, 0xd0, 0x30, 0x05, 0x04, 0xf0, 0x0c, 0x06, 0x04, + 0x20, 0x2a, 0x07, 0x05, 0x80, 0x02, 0x0a, 0x06, 0xa0, 0x0f, 0x00, 0x02, 0xa4, 0x0f, 0x00, 0x02, 0xa8, 0x0f, 0x00, 0x02, 0xac, 0x0f, 0x00, 0x02, 0x08, 0x02, 0x01, 0x01, 0x0a, 0x02, 0x01, 0x01, + 0x0c, 0x02, 0x01, 0x01, 0x0e, 0x02, 0x01, 0x01, 0x10, 0x02, 0x01, 0x01, 0x12, 0x02, 0x01, 0x01, 0xc0, 0x19, 0x02, 0x02, 0xc4, 0x19, 0x02, 0x02, 0xc8, 0x19, 0x02, 0x02, 0xcc, 0x19, 0x02, 0x02, + 0xd0, 0x19, 0x02, 0x02, 0x50, 0x3a, 0x03, 0x03, 0x58, 0x3a, 0x03, 0x03, 0x60, 0x3a, 0x03, 0x03, 0x30, 0x13, 0x04, 0x03, 0x38, 0x13, 0x04, 0x03, 0xe0, 0x30, 0x05, 0x04, 0x00, 0x0d, 0x06, 0x04, + 0x40, 0x2a, 0x07, 0x05, 0xc0, 0x02, 0x0a, 0x06, 0xb0, 0x0f, 0x00, 0x02, 0xb4, 0x0f, 0x00, 0x02, 0xb8, 0x0f, 0x00, 0x02, 0xbc, 0x0f, 0x00, 0x02, 0x14, 0x02, 0x01, 0x01, 0x16, 0x02, 0x01, 0x01, + 0x18, 0x02, 0x01, 0x01, 0x1a, 0x02, 0x01, 0x01, 0x1c, 0x02, 0x01, 0x01, 0x1e, 0x02, 0x01, 0x01, 0xd4, 0x19, 0x02, 0x02, 0xd8, 0x19, 0x02, 0x02, 0xdc, 0x19, 0x02, 0x02, 0xe0, 0x19, 0x02, 0x02, + 0xe4, 0x19, 0x02, 0x02, 0x68, 0x3a, 0x03, 0x03, 0x70, 0x3a, 0x03, 0x03, 0x78, 0x3a, 0x03, 0x03, 0x40, 0x13, 0x04, 0x03, 0x48, 0x13, 0x04, 0x03, 0xf0, 0x30, 0x05, 0x04, 0x10, 0x0d, 0x06, 0x04, + 0x60, 0x2a, 0x07, 0x05, 0x00, 0x03, 0x0a, 0x06, 0xc0, 0x0f, 0x00, 0x02, 0xc4, 0x0f, 0x00, 0x02, 0xc8, 0x0f, 0x00, 0x02, 0xcc, 0x0f, 0x00, 0x02, 0x20, 0x02, 0x01, 0x01, 0x22, 0x02, 0x01, 0x01, + 0x24, 0x02, 0x01, 0x01, 0x26, 0x02, 0x01, 0x01, 0x28, 0x02, 0x01, 0x01, 0x2a, 0x02, 0x01, 0x01, 0xe8, 0x19, 0x02, 0x02, 0xec, 0x19, 0x02, 0x02, 0xf0, 0x19, 0x02, 0x02, 0xf4, 0x19, 0x02, 0x02, + 0xf8, 0x19, 0x02, 0x02, 0x80, 0x3a, 0x03, 0x03, 0x88, 0x3a, 0x03, 0x03, 0x90, 0x3a, 0x03, 0x03, 0x50, 0x13, 0x04, 0x03, 0x58, 0x13, 0x04, 0x03, 0x00, 0x31, 0x05, 0x04, 0x20, 0x0d, 0x06, 0x04, + 0x80, 0x2a, 0x07, 0x05, 0x40, 0x03, 0x0a, 0x06, 0xd0, 0x0f, 0x00, 0x02, 0xd4, 0x0f, 0x00, 0x02, 0xd8, 0x0f, 0x00, 0x02, 0xdc, 0x0f, 0x00, 0x02, 0x2c, 0x02, 0x01, 0x01, 0x2e, 0x02, 0x01, 0x01, + 0x30, 0x02, 0x01, 0x01, 0x32, 0x02, 0x01, 0x01, 0x34, 0x02, 0x01, 0x01, 0x36, 0x02, 0x01, 0x01, 0xfc, 0x19, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x04, 0x1a, 0x02, 0x02, 0x08, 0x1a, 0x02, 0x02, + 0x0c, 0x1a, 0x02, 0x02, 0x98, 0x3a, 0x03, 0x03, 0xa0, 0x3a, 0x03, 0x03, 0xa8, 0x3a, 0x03, 0x03, 0x60, 0x13, 0x04, 0x03, 0x68, 0x13, 0x04, 0x03, 0x10, 0x31, 0x05, 0x04, 0x30, 0x0d, 0x06, 0x04, + 0xa0, 0x2a, 0x07, 0x05, 0x80, 0x03, 0x0a, 0x06, 0xe0, 0x0f, 0x00, 0x02, 0xe4, 0x0f, 0x00, 0x02, 0xe8, 0x0f, 0x00, 0x02, 0xec, 0x0f, 0x00, 0x02, 0x38, 0x02, 0x01, 0x01, 0x3a, 0x02, 0x01, 0x01, + 0x3c, 0x02, 0x01, 0x01, 0x3e, 0x02, 0x01, 0x01, 0x40, 0x02, 0x01, 0x01, 0x42, 0x02, 0x01, 0x01, 0x10, 0x1a, 0x02, 0x02, 0x14, 0x1a, 0x02, 0x02, 0x18, 0x1a, 0x02, 0x02, 0x1c, 0x1a, 0x02, 0x02, + 0x20, 0x1a, 0x02, 0x02, 0xb0, 0x3a, 0x03, 0x03, 0xb8, 0x3a, 0x03, 0x03, 0xc0, 0x3a, 0x03, 0x03, 0x70, 0x13, 0x04, 0x03, 0x78, 0x13, 0x04, 0x03, 0x20, 0x31, 0x05, 0x04, 0x40, 0x0d, 0x06, 0x04, + 0xc0, 0x2a, 0x07, 0x05, 0xc0, 0x03, 0x0a, 0x06, 0xf0, 0x0f, 0x00, 0x02, 0xf4, 0x0f, 0x00, 0x02, 0xf8, 0x0f, 0x00, 0x02, 0xfc, 0x0f, 0x00, 0x02, 0x44, 0x02, 0x01, 0x01, 0x46, 0x02, 0x01, 0x01, + 0x48, 0x02, 0x01, 0x01, 0x4a, 0x02, 0x01, 0x01, 0x4c, 0x02, 0x01, 0x01, 0x4e, 0x02, 0x01, 0x01, 0x24, 0x1a, 0x02, 0x02, 0x28, 0x1a, 0x02, 0x02, 0x2c, 0x1a, 0x02, 0x02, 0x30, 0x1a, 0x02, 0x02, + 0x34, 0x1a, 0x02, 0x02, 0xc8, 0x3a, 0x03, 0x03, 0xd0, 0x3a, 0x03, 0x03, 0xd8, 0x3a, 0x03, 0x03, 0x80, 0x13, 0x04, 0x03, 0x88, 0x13, 0x04, 0x03, 0x30, 0x31, 0x05, 0x04, 0x50, 0x0d, 0x06, 0x04, + 0xe0, 0x2a, 0x07, 0x05, 0x80, 0x16, 0x0b, 0x07, 0x00, 0x10, 0x00, 0x02, 0x04, 0x10, 0x00, 0x02, 0x08, 0x10, 0x00, 0x02, 0x0c, 0x10, 0x00, 0x02, 0x50, 0x02, 0x01, 0x01, 0x52, 0x02, 0x01, 0x01, + 0x54, 0x02, 0x01, 0x01, 0x56, 0x02, 0x01, 0x01, 0x58, 0x02, 0x01, 0x01, 0x5a, 0x02, 0x01, 0x01, 0x38, 0x1a, 0x02, 0x02, 0x3c, 0x1a, 0x02, 0x02, 0x40, 0x1a, 0x02, 0x02, 0x44, 0x1a, 0x02, 0x02, + 0x48, 0x1a, 0x02, 0x02, 0xe0, 0x3a, 0x03, 0x03, 0xe8, 0x3a, 0x03, 0x03, 0xf0, 0x3a, 0x03, 0x03, 0x90, 0x13, 0x04, 0x03, 0x98, 0x13, 0x04, 0x03, 0x40, 0x31, 0x05, 0x04, 0x60, 0x0d, 0x06, 0x04, + 0x00, 0x2b, 0x07, 0x05, 0x00, 0x17, 0x0b, 0x07, 0x10, 0x10, 0x00, 0x02, 0x14, 0x10, 0x00, 0x02, 0x18, 0x10, 0x00, 0x02, 0x1c, 0x10, 0x00, 0x02, 0x5c, 0x02, 0x01, 0x01, 0x5e, 0x02, 0x01, 0x01, + 0x60, 0x02, 0x01, 0x01, 0x62, 0x02, 0x01, 0x01, 0x64, 0x02, 0x01, 0x01, 0x66, 0x02, 0x01, 0x01, 0x4c, 0x1a, 0x02, 0x02, 0x50, 0x1a, 0x02, 0x02, 0x54, 0x1a, 0x02, 0x02, 0x58, 0x1a, 0x02, 0x02, + 0x5c, 0x1a, 0x02, 0x02, 0xf8, 0x3a, 0x03, 0x03, 0x00, 0x3b, 0x03, 0x03, 0x08, 0x3b, 0x03, 0x03, 0xa0, 0x13, 0x04, 0x03, 0xa8, 0x13, 0x04, 0x03, 0x50, 0x31, 0x05, 0x04, 0x70, 0x0d, 0x06, 0x04, + 0x20, 0x2b, 0x07, 0x05, 0x80, 0x17, 0x0b, 0x07, 0x20, 0x10, 0x00, 0x02, 0x24, 0x10, 0x00, 0x02, 0x28, 0x10, 0x00, 0x02, 0x2c, 0x10, 0x00, 0x02, 0x68, 0x02, 0x01, 0x01, 0x6a, 0x02, 0x01, 0x01, + 0x6c, 0x02, 0x01, 0x01, 0x6e, 0x02, 0x01, 0x01, 0x70, 0x02, 0x01, 0x01, 0x72, 0x02, 0x01, 0x01, 0x60, 0x1a, 0x02, 0x02, 0x64, 0x1a, 0x02, 0x02, 0x68, 0x1a, 0x02, 0x02, 0x6c, 0x1a, 0x02, 0x02, + 0x70, 0x1a, 0x02, 0x02, 0x10, 0x3b, 0x03, 0x03, 0x18, 0x3b, 0x03, 0x03, 0x20, 0x3b, 0x03, 0x03, 0xb0, 0x13, 0x04, 0x03, 0xb8, 0x13, 0x04, 0x03, 0x60, 0x31, 0x05, 0x04, 0x80, 0x0d, 0x06, 0x04, + 0x40, 0x2b, 0x07, 0x05, 0x00, 0x18, 0x0b, 0x07, 0x30, 0x10, 0x00, 0x02, 0x34, 0x10, 0x00, 0x02, 0x38, 0x10, 0x00, 0x02, 0x3c, 0x10, 0x00, 0x02, 0x74, 0x02, 0x01, 0x01, 0x76, 0x02, 0x01, 0x01, + 0x78, 0x02, 0x01, 0x01, 0x7a, 0x02, 0x01, 0x01, 0x7c, 0x02, 0x01, 0x01, 0x7e, 0x02, 0x01, 0x01, 0x74, 0x1a, 0x02, 0x02, 0x78, 0x1a, 0x02, 0x02, 0x7c, 0x1a, 0x02, 0x02, 0x80, 0x1a, 0x02, 0x02, + 0x84, 0x1a, 0x02, 0x02, 0x28, 0x3b, 0x03, 0x03, 0x30, 0x3b, 0x03, 0x03, 0x38, 0x3b, 0x03, 0x03, 0xc0, 0x13, 0x04, 0x03, 0xc8, 0x13, 0x04, 0x03, 0x70, 0x31, 0x05, 0x04, 0x90, 0x0d, 0x06, 0x04, + 0x60, 0x2b, 0x07, 0x05, 0x80, 0x18, 0x0b, 0x07, 0x40, 0x10, 0x00, 0x02, 0x44, 0x10, 0x00, 0x02, 0x48, 0x10, 0x00, 0x02, 0x4c, 0x10, 0x00, 0x02, 0x80, 0x02, 0x01, 0x01, 0x82, 0x02, 0x01, 0x01, + 0x84, 0x02, 0x01, 0x01, 0x86, 0x02, 0x01, 0x01, 0x88, 0x02, 0x01, 0x01, 0x8a, 0x02, 0x01, 0x01, 0x88, 0x1a, 0x02, 0x02, 0x8c, 0x1a, 0x02, 0x02, 0x90, 0x1a, 0x02, 0x02, 0x94, 0x1a, 0x02, 0x02, + 0x98, 0x1a, 0x02, 0x02, 0x40, 0x3b, 0x03, 0x03, 0x48, 0x3b, 0x03, 0x03, 0x50, 0x3b, 0x03, 0x03, 0xd0, 0x13, 0x04, 0x03, 0xd8, 0x13, 0x04, 0x03, 0x80, 0x31, 0x05, 0x04, 0xa0, 0x0d, 0x06, 0x04, + 0x80, 0x06, 0x08, 0x05, 0x00, 0x19, 0x0b, 0x07, 0x50, 0x10, 0x00, 0x02, 0x54, 0x10, 0x00, 0x02, 0x58, 0x10, 0x00, 0x02, 0x5c, 0x10, 0x00, 0x02, 0x8c, 0x02, 0x01, 0x01, 0x8e, 0x02, 0x01, 0x01, + 0x90, 0x02, 0x01, 0x01, 0x92, 0x02, 0x01, 0x01, 0x94, 0x02, 0x01, 0x01, 0x96, 0x02, 0x01, 0x01, 0x9c, 0x1a, 0x02, 0x02, 0xa0, 0x1a, 0x02, 0x02, 0xa4, 0x1a, 0x02, 0x02, 0xa8, 0x1a, 0x02, 0x02, + 0xac, 0x1a, 0x02, 0x02, 0x58, 0x3b, 0x03, 0x03, 0x60, 0x3b, 0x03, 0x03, 0x68, 0x3b, 0x03, 0x03, 0xe0, 0x13, 0x04, 0x03, 0xe8, 0x13, 0x04, 0x03, 0x90, 0x31, 0x05, 0x04, 0xb0, 0x0d, 0x06, 0x04, + 0xa0, 0x06, 0x08, 0x05, 0x80, 0x19, 0x0b, 0x07, 0x60, 0x10, 0x00, 0x02, 0x64, 0x10, 0x00, 0x02, 0x68, 0x10, 0x00, 0x02, 0x6c, 0x10, 0x00, 0x02, 0x98, 0x02, 0x01, 0x01, 0x9a, 0x02, 0x01, 0x01, + 0x9c, 0x02, 0x01, 0x01, 0x9e, 0x02, 0x01, 0x01, 0xa0, 0x02, 0x01, 0x01, 0xa2, 0x02, 0x01, 0x01, 0xb0, 0x1a, 0x02, 0x02, 0xb4, 0x1a, 0x02, 0x02, 0xb8, 0x1a, 0x02, 0x02, 0xbc, 0x1a, 0x02, 0x02, + 0xc0, 0x1a, 0x02, 0x02, 0x70, 0x3b, 0x03, 0x03, 0x78, 0x3b, 0x03, 0x03, 0xf0, 0x13, 0x04, 0x03, 0xf8, 0x13, 0x04, 0x03, 0x00, 0x14, 0x04, 0x03, 0xa0, 0x31, 0x05, 0x04, 0xc0, 0x0d, 0x06, 0x04, + 0xc0, 0x06, 0x08, 0x05, 0x00, 0x1a, 0x0b, 0x07, 0x70, 0x10, 0x00, 0x02, 0x74, 0x10, 0x00, 0x02, 0x78, 0x10, 0x00, 0x02, 0x7c, 0x10, 0x00, 0x02, 0xa4, 0x02, 0x01, 0x01, 0xa6, 0x02, 0x01, 0x01, + 0xa8, 0x02, 0x01, 0x01, 0xaa, 0x02, 0x01, 0x01, 0xac, 0x02, 0x01, 0x01, 0xae, 0x02, 0x01, 0x01, 0xc4, 0x1a, 0x02, 0x02, 0xc8, 0x1a, 0x02, 0x02, 0xcc, 0x1a, 0x02, 0x02, 0xd0, 0x1a, 0x02, 0x02, + 0xd4, 0x1a, 0x02, 0x02, 0x80, 0x3b, 0x03, 0x03, 0x88, 0x3b, 0x03, 0x03, 0x08, 0x14, 0x04, 0x03, 0x10, 0x14, 0x04, 0x03, 0x18, 0x14, 0x04, 0x03, 0xb0, 0x31, 0x05, 0x04, 0xd0, 0x0d, 0x06, 0x04, + 0xe0, 0x06, 0x08, 0x05, 0x80, 0x1a, 0x0b, 0x07, 0x80, 0x10, 0x00, 0x02, 0x84, 0x10, 0x00, 0x02, 0x88, 0x10, 0x00, 0x02, 0x8c, 0x10, 0x00, 0x02, 0xb0, 0x02, 0x01, 0x01, 0xb2, 0x02, 0x01, 0x01, + 0xb4, 0x02, 0x01, 0x01, 0xb6, 0x02, 0x01, 0x01, 0xb8, 0x02, 0x01, 0x01, 0xba, 0x02, 0x01, 0x01, 0xd8, 0x1a, 0x02, 0x02, 0xdc, 0x1a, 0x02, 0x02, 0xe0, 0x1a, 0x02, 0x02, 0xe4, 0x1a, 0x02, 0x02, + 0x90, 0x3b, 0x03, 0x03, 0x98, 0x3b, 0x03, 0x03, 0xa0, 0x3b, 0x03, 0x03, 0x20, 0x14, 0x04, 0x03, 0x28, 0x14, 0x04, 0x03, 0xc0, 0x31, 0x05, 0x04, 0xd0, 0x31, 0x05, 0x04, 0xe0, 0x0d, 0x06, 0x04, + 0x00, 0x07, 0x08, 0x05, 0x00, 0x1b, 0x0b, 0x07, 0x90, 0x10, 0x00, 0x02, 0x94, 0x10, 0x00, 0x02, 0x98, 0x10, 0x00, 0x02, 0x9c, 0x10, 0x00, 0x02, 0xbc, 0x02, 0x01, 0x01, 0xbe, 0x02, 0x01, 0x01, + 0xc0, 0x02, 0x01, 0x01, 0xc2, 0x02, 0x01, 0x01, 0xc4, 0x02, 0x01, 0x01, 0xc6, 0x02, 0x01, 0x01, 0xe8, 0x1a, 0x02, 0x02, 0xec, 0x1a, 0x02, 0x02, 0xf0, 0x1a, 0x02, 0x02, 0xf4, 0x1a, 0x02, 0x02, + 0xa8, 0x3b, 0x03, 0x03, 0xb0, 0x3b, 0x03, 0x03, 0xb8, 0x3b, 0x03, 0x03, 0x30, 0x14, 0x04, 0x03, 0x38, 0x14, 0x04, 0x03, 0xe0, 0x31, 0x05, 0x04, 0xf0, 0x31, 0x05, 0x04, 0xf0, 0x0d, 0x06, 0x04, + 0x20, 0x07, 0x08, 0x05, 0x80, 0x1b, 0x0b, 0x07, 0xa0, 0x10, 0x00, 0x02, 0xa4, 0x10, 0x00, 0x02, 0xa8, 0x10, 0x00, 0x02, 0xac, 0x10, 0x00, 0x02, 0xc8, 0x02, 0x01, 0x01, 0xca, 0x02, 0x01, 0x01, + 0xcc, 0x02, 0x01, 0x01, 0xce, 0x02, 0x01, 0x01, 0xd0, 0x02, 0x01, 0x01, 0xd2, 0x02, 0x01, 0x01, 0xf8, 0x1a, 0x02, 0x02, 0xfc, 0x1a, 0x02, 0x02, 0x00, 0x1b, 0x02, 0x02, 0x04, 0x1b, 0x02, 0x02, + 0xc0, 0x3b, 0x03, 0x03, 0xc8, 0x3b, 0x03, 0x03, 0xd0, 0x3b, 0x03, 0x03, 0x40, 0x14, 0x04, 0x03, 0x48, 0x14, 0x04, 0x03, 0x00, 0x32, 0x05, 0x04, 0x10, 0x32, 0x05, 0x04, 0x00, 0x0e, 0x06, 0x04, + 0x40, 0x07, 0x08, 0x05, 0x00, 0x36, 0x0c, 0x08, 0xb0, 0x10, 0x00, 0x02, 0xb4, 0x10, 0x00, 0x02, 0xb8, 0x10, 0x00, 0x02, 0xbc, 0x10, 0x00, 0x02, 0xd4, 0x02, 0x01, 0x01, 0xd6, 0x02, 0x01, 0x01, + 0xd8, 0x02, 0x01, 0x01, 0xda, 0x02, 0x01, 0x01, 0xdc, 0x02, 0x01, 0x01, 0xde, 0x02, 0x01, 0x01, 0x08, 0x1b, 0x02, 0x02, 0x0c, 0x1b, 0x02, 0x02, 0x10, 0x1b, 0x02, 0x02, 0x14, 0x1b, 0x02, 0x02, + 0xd8, 0x3b, 0x03, 0x03, 0xe0, 0x3b, 0x03, 0x03, 0xe8, 0x3b, 0x03, 0x03, 0x50, 0x14, 0x04, 0x03, 0x58, 0x14, 0x04, 0x03, 0x20, 0x32, 0x05, 0x04, 0x30, 0x32, 0x05, 0x04, 0x10, 0x0e, 0x06, 0x04, + 0x60, 0x07, 0x08, 0x05, 0x00, 0x37, 0x0c, 0x08, 0xc0, 0x10, 0x00, 0x02, 0xc4, 0x10, 0x00, 0x02, 0xc8, 0x10, 0x00, 0x02, 0xcc, 0x10, 0x00, 0x02, 0xe0, 0x02, 0x01, 0x01, 0xe2, 0x02, 0x01, 0x01, + 0xe4, 0x02, 0x01, 0x01, 0xe6, 0x02, 0x01, 0x01, 0xe8, 0x02, 0x01, 0x01, 0xea, 0x02, 0x01, 0x01, 0x18, 0x1b, 0x02, 0x02, 0x1c, 0x1b, 0x02, 0x02, 0x20, 0x1b, 0x02, 0x02, 0x24, 0x1b, 0x02, 0x02, + 0xf0, 0x3b, 0x03, 0x03, 0xf8, 0x3b, 0x03, 0x03, 0x00, 0x3c, 0x03, 0x03, 0x60, 0x14, 0x04, 0x03, 0x68, 0x14, 0x04, 0x03, 0x40, 0x32, 0x05, 0x04, 0x50, 0x32, 0x05, 0x04, 0x20, 0x0e, 0x06, 0x04, + 0x80, 0x07, 0x08, 0x05, 0x00, 0x38, 0x0c, 0x08, 0xd0, 0x10, 0x00, 0x02, 0xd4, 0x10, 0x00, 0x02, 0xd8, 0x10, 0x00, 0x02, 0xdc, 0x10, 0x00, 0x02, 0xec, 0x02, 0x01, 0x01, 0xee, 0x02, 0x01, 0x01, + 0xf0, 0x02, 0x01, 0x01, 0xf2, 0x02, 0x01, 0x01, 0xf4, 0x02, 0x01, 0x01, 0xf6, 0x02, 0x01, 0x01, 0x28, 0x1b, 0x02, 0x02, 0x2c, 0x1b, 0x02, 0x02, 0x30, 0x1b, 0x02, 0x02, 0x34, 0x1b, 0x02, 0x02, + 0x08, 0x3c, 0x03, 0x03, 0x10, 0x3c, 0x03, 0x03, 0x18, 0x3c, 0x03, 0x03, 0x70, 0x14, 0x04, 0x03, 0x78, 0x14, 0x04, 0x03, 0x60, 0x32, 0x05, 0x04, 0x70, 0x32, 0x05, 0x04, 0x30, 0x0e, 0x06, 0x04, + 0xa0, 0x07, 0x08, 0x05, 0x00, 0x39, 0x0c, 0x08, 0xe0, 0x10, 0x00, 0x02, 0xe4, 0x10, 0x00, 0x02, 0xe8, 0x10, 0x00, 0x02, 0xec, 0x10, 0x00, 0x02, 0xf8, 0x02, 0x01, 0x01, 0xfa, 0x02, 0x01, 0x01, + 0xfc, 0x02, 0x01, 0x01, 0xfe, 0x02, 0x01, 0x01, 0x00, 0x03, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x38, 0x1b, 0x02, 0x02, 0x3c, 0x1b, 0x02, 0x02, 0x40, 0x1b, 0x02, 0x02, 0x44, 0x1b, 0x02, 0x02, + 0x20, 0x3c, 0x03, 0x03, 0x28, 0x3c, 0x03, 0x03, 0x30, 0x3c, 0x03, 0x03, 0x80, 0x14, 0x04, 0x03, 0x88, 0x14, 0x04, 0x03, 0x80, 0x32, 0x05, 0x04, 0x90, 0x32, 0x05, 0x04, 0x40, 0x0e, 0x06, 0x04, + 0xc0, 0x07, 0x08, 0x05, 0x00, 0x3a, 0x0c, 0x08, 0xf0, 0x10, 0x00, 0x02, 0xf4, 0x10, 0x00, 0x02, 0xf8, 0x10, 0x00, 0x02, 0xfc, 0x10, 0x00, 0x02, 0x04, 0x03, 0x01, 0x01, 0x06, 0x03, 0x01, 0x01, + 0x08, 0x03, 0x01, 0x01, 0x0a, 0x03, 0x01, 0x01, 0x0c, 0x03, 0x01, 0x01, 0x0e, 0x03, 0x01, 0x01, 0x48, 0x1b, 0x02, 0x02, 0x4c, 0x1b, 0x02, 0x02, 0x50, 0x1b, 0x02, 0x02, 0x54, 0x1b, 0x02, 0x02, + 0x38, 0x3c, 0x03, 0x03, 0x40, 0x3c, 0x03, 0x03, 0x48, 0x3c, 0x03, 0x03, 0x90, 0x14, 0x04, 0x03, 0x98, 0x14, 0x04, 0x03, 0xa0, 0x32, 0x05, 0x04, 0xb0, 0x32, 0x05, 0x04, 0x50, 0x0e, 0x06, 0x04, + 0xe0, 0x07, 0x08, 0x05, 0x00, 0x3b, 0x0c, 0x08, 0x00, 0x11, 0x00, 0x02, 0x04, 0x11, 0x00, 0x02, 0x08, 0x11, 0x00, 0x02, 0x0c, 0x11, 0x00, 0x02, 0x10, 0x03, 0x01, 0x01, 0x12, 0x03, 0x01, 0x01, + 0x14, 0x03, 0x01, 0x01, 0x16, 0x03, 0x01, 0x01, 0x18, 0x03, 0x01, 0x01, 0x1a, 0x03, 0x01, 0x01, 0x58, 0x1b, 0x02, 0x02, 0x5c, 0x1b, 0x02, 0x02, 0x60, 0x1b, 0x02, 0x02, 0x64, 0x1b, 0x02, 0x02, + 0x50, 0x3c, 0x03, 0x03, 0x58, 0x3c, 0x03, 0x03, 0x60, 0x3c, 0x03, 0x03, 0xa0, 0x14, 0x04, 0x03, 0xa8, 0x14, 0x04, 0x03, 0xc0, 0x32, 0x05, 0x04, 0xd0, 0x32, 0x05, 0x04, 0x60, 0x0e, 0x06, 0x04, + 0x00, 0x08, 0x08, 0x05, 0x00, 0x3c, 0x0c, 0x08, 0x10, 0x11, 0x00, 0x02, 0x14, 0x11, 0x00, 0x02, 0x18, 0x11, 0x00, 0x02, 0x1c, 0x11, 0x00, 0x02, 0x1c, 0x03, 0x01, 0x01, 0x1e, 0x03, 0x01, 0x01, + 0x20, 0x03, 0x01, 0x01, 0x22, 0x03, 0x01, 0x01, 0x24, 0x03, 0x01, 0x01, 0x26, 0x03, 0x01, 0x01, 0x68, 0x1b, 0x02, 0x02, 0x6c, 0x1b, 0x02, 0x02, 0x70, 0x1b, 0x02, 0x02, 0x74, 0x1b, 0x02, 0x02, + 0x68, 0x3c, 0x03, 0x03, 0x70, 0x3c, 0x03, 0x03, 0x78, 0x3c, 0x03, 0x03, 0xb0, 0x14, 0x04, 0x03, 0xb8, 0x14, 0x04, 0x03, 0xe0, 0x32, 0x05, 0x04, 0xf0, 0x32, 0x05, 0x04, 0x70, 0x0e, 0x06, 0x04, + 0x20, 0x08, 0x08, 0x05, 0x00, 0x3d, 0x0c, 0x08, 0x20, 0x11, 0x00, 0x02, 0x24, 0x11, 0x00, 0x02, 0x28, 0x11, 0x00, 0x02, 0x2c, 0x11, 0x00, 0x02, 0x28, 0x03, 0x01, 0x01, 0x2a, 0x03, 0x01, 0x01, + 0x2c, 0x03, 0x01, 0x01, 0x2e, 0x03, 0x01, 0x01, 0x30, 0x03, 0x01, 0x01, 0x32, 0x03, 0x01, 0x01, 0x78, 0x1b, 0x02, 0x02, 0x7c, 0x1b, 0x02, 0x02, 0x80, 0x1b, 0x02, 0x02, 0x84, 0x1b, 0x02, 0x02, + 0x80, 0x3c, 0x03, 0x03, 0x88, 0x3c, 0x03, 0x03, 0x90, 0x3c, 0x03, 0x03, 0xc0, 0x14, 0x04, 0x03, 0xc8, 0x14, 0x04, 0x03, 0x00, 0x33, 0x05, 0x04, 0x10, 0x33, 0x05, 0x04, 0x80, 0x0e, 0x06, 0x04, + 0x40, 0x08, 0x08, 0x05, 0x00, 0x11, 0x0d, 0x08, 0x30, 0x11, 0x00, 0x02, 0x34, 0x11, 0x00, 0x02, 0x38, 0x11, 0x00, 0x02, 0x3c, 0x11, 0x00, 0x02, 0x34, 0x03, 0x01, 0x01, 0x36, 0x03, 0x01, 0x01, + 0x38, 0x03, 0x01, 0x01, 0x3a, 0x03, 0x01, 0x01, 0x3c, 0x03, 0x01, 0x01, 0x3e, 0x03, 0x01, 0x01, 0x88, 0x1b, 0x02, 0x02, 0x8c, 0x1b, 0x02, 0x02, 0x90, 0x1b, 0x02, 0x02, 0x94, 0x1b, 0x02, 0x02, + 0x98, 0x3c, 0x03, 0x03, 0xa0, 0x3c, 0x03, 0x03, 0xa8, 0x3c, 0x03, 0x03, 0xd0, 0x14, 0x04, 0x03, 0xd8, 0x14, 0x04, 0x03, 0x20, 0x33, 0x05, 0x04, 0x30, 0x33, 0x05, 0x04, 0x90, 0x0e, 0x06, 0x04, + 0x60, 0x08, 0x08, 0x05, 0x00, 0x12, 0x0d, 0x08, 0x40, 0x11, 0x00, 0x02, 0x44, 0x11, 0x00, 0x02, 0x48, 0x11, 0x00, 0x02, 0x4c, 0x11, 0x00, 0x02, 0x40, 0x03, 0x01, 0x01, 0x42, 0x03, 0x01, 0x01, + 0x44, 0x03, 0x01, 0x01, 0x46, 0x03, 0x01, 0x01, 0x48, 0x03, 0x01, 0x01, 0x4a, 0x03, 0x01, 0x01, 0x98, 0x1b, 0x02, 0x02, 0x9c, 0x1b, 0x02, 0x02, 0xa0, 0x1b, 0x02, 0x02, 0xa4, 0x1b, 0x02, 0x02, + 0xb0, 0x3c, 0x03, 0x03, 0xb8, 0x3c, 0x03, 0x03, 0xc0, 0x3c, 0x03, 0x03, 0xe0, 0x14, 0x04, 0x03, 0xe8, 0x14, 0x04, 0x03, 0x40, 0x33, 0x05, 0x04, 0x50, 0x33, 0x05, 0x04, 0xa0, 0x0e, 0x06, 0x04, + 0x80, 0x08, 0x08, 0x05, 0x00, 0x13, 0x0d, 0x08, 0x50, 0x11, 0x00, 0x02, 0x54, 0x11, 0x00, 0x02, 0x58, 0x11, 0x00, 0x02, 0x5c, 0x11, 0x00, 0x02, 0x4c, 0x03, 0x01, 0x01, 0x4e, 0x03, 0x01, 0x01, + 0x50, 0x03, 0x01, 0x01, 0x52, 0x03, 0x01, 0x01, 0x54, 0x03, 0x01, 0x01, 0x56, 0x03, 0x01, 0x01, 0xa8, 0x1b, 0x02, 0x02, 0xac, 0x1b, 0x02, 0x02, 0xb0, 0x1b, 0x02, 0x02, 0xb4, 0x1b, 0x02, 0x02, + 0xc8, 0x3c, 0x03, 0x03, 0xd0, 0x3c, 0x03, 0x03, 0xd8, 0x3c, 0x03, 0x03, 0xf0, 0x14, 0x04, 0x03, 0xf8, 0x14, 0x04, 0x03, 0x60, 0x33, 0x05, 0x04, 0x70, 0x33, 0x05, 0x04, 0xb0, 0x0e, 0x06, 0x04, + 0xa0, 0x08, 0x08, 0x05, 0x00, 0x14, 0x0d, 0x08, 0x60, 0x11, 0x00, 0x02, 0x64, 0x11, 0x00, 0x02, 0x68, 0x11, 0x00, 0x02, 0x6c, 0x11, 0x00, 0x02, 0x58, 0x03, 0x01, 0x01, 0x5a, 0x03, 0x01, 0x01, + 0x5c, 0x03, 0x01, 0x01, 0x5e, 0x03, 0x01, 0x01, 0x60, 0x03, 0x01, 0x01, 0x62, 0x03, 0x01, 0x01, 0xb8, 0x1b, 0x02, 0x02, 0xbc, 0x1b, 0x02, 0x02, 0xc0, 0x1b, 0x02, 0x02, 0xc4, 0x1b, 0x02, 0x02, + 0xe0, 0x3c, 0x03, 0x03, 0xe8, 0x3c, 0x03, 0x03, 0xf0, 0x3c, 0x03, 0x03, 0x00, 0x15, 0x04, 0x03, 0x08, 0x15, 0x04, 0x03, 0x80, 0x33, 0x05, 0x04, 0x90, 0x33, 0x05, 0x04, 0xc0, 0x0e, 0x06, 0x04, + 0xc0, 0x08, 0x08, 0x05, 0x00, 0x15, 0x0d, 0x08, 0x70, 0x11, 0x00, 0x02, 0x74, 0x11, 0x00, 0x02, 0x78, 0x11, 0x00, 0x02, 0x7c, 0x11, 0x00, 0x02, 0x64, 0x03, 0x01, 0x01, 0x66, 0x03, 0x01, 0x01, + 0x68, 0x03, 0x01, 0x01, 0x6a, 0x03, 0x01, 0x01, 0x6c, 0x03, 0x01, 0x01, 0x6e, 0x03, 0x01, 0x01, 0xc8, 0x1b, 0x02, 0x02, 0xcc, 0x1b, 0x02, 0x02, 0xd0, 0x1b, 0x02, 0x02, 0xd4, 0x1b, 0x02, 0x02, + 0xf8, 0x3c, 0x03, 0x03, 0x00, 0x3d, 0x03, 0x03, 0x08, 0x3d, 0x03, 0x03, 0x10, 0x15, 0x04, 0x03, 0x18, 0x15, 0x04, 0x03, 0xa0, 0x33, 0x05, 0x04, 0xb0, 0x33, 0x05, 0x04, 0xd0, 0x0e, 0x06, 0x04, + 0xe0, 0x08, 0x08, 0x05, 0x00, 0x2e, 0x0e, 0x09, 0x80, 0x11, 0x00, 0x02, 0x84, 0x11, 0x00, 0x02, 0x88, 0x11, 0x00, 0x02, 0x8c, 0x11, 0x00, 0x02, 0x70, 0x03, 0x01, 0x01, 0x72, 0x03, 0x01, 0x01, + 0x74, 0x03, 0x01, 0x01, 0x76, 0x03, 0x01, 0x01, 0x78, 0x03, 0x01, 0x01, 0x7a, 0x03, 0x01, 0x01, 0xd8, 0x1b, 0x02, 0x02, 0xdc, 0x1b, 0x02, 0x02, 0xe0, 0x1b, 0x02, 0x02, 0xe4, 0x1b, 0x02, 0x02, + 0x10, 0x3d, 0x03, 0x03, 0x18, 0x3d, 0x03, 0x03, 0x20, 0x3d, 0x03, 0x03, 0x20, 0x15, 0x04, 0x03, 0x28, 0x15, 0x04, 0x03, 0xc0, 0x33, 0x05, 0x04, 0xd0, 0x33, 0x05, 0x04, 0xe0, 0x0e, 0x06, 0x04, + 0x00, 0x09, 0x08, 0x05, 0x00, 0x30, 0x0e, 0x09, 0x90, 0x11, 0x00, 0x02, 0x94, 0x11, 0x00, 0x02, 0x98, 0x11, 0x00, 0x02, 0x7c, 0x03, 0x01, 0x01, 0x7e, 0x03, 0x01, 0x01, 0x80, 0x03, 0x01, 0x01, + 0x82, 0x03, 0x01, 0x01, 0x84, 0x03, 0x01, 0x01, 0x86, 0x03, 0x01, 0x01, 0x88, 0x03, 0x01, 0x01, 0xe8, 0x1b, 0x02, 0x02, 0xec, 0x1b, 0x02, 0x02, 0xf0, 0x1b, 0x02, 0x02, 0xf4, 0x1b, 0x02, 0x02, + 0x28, 0x3d, 0x03, 0x03, 0x30, 0x3d, 0x03, 0x03, 0x38, 0x3d, 0x03, 0x03, 0x30, 0x15, 0x04, 0x03, 0x38, 0x15, 0x04, 0x03, 0xe0, 0x33, 0x05, 0x04, 0xf0, 0x33, 0x05, 0x04, 0xf0, 0x0e, 0x06, 0x04, + 0x20, 0x09, 0x08, 0x05, 0x00, 0x32, 0x0e, 0x09, 0x9c, 0x11, 0x00, 0x02, 0xa0, 0x11, 0x00, 0x02, 0xa4, 0x11, 0x00, 0x02, 0x8a, 0x03, 0x01, 0x01, 0x8c, 0x03, 0x01, 0x01, 0x8e, 0x03, 0x01, 0x01, + 0x00, 0x00, 0xfe, 0x0e, 0x00, 0x00, 0xfd, 0x0e, 0x00, 0x00, 0xfc, 0x0e, 0x00, 0x00, 0xfb, 0x0e, 0x00, 0x00, 0xfa, 0x0e, 0x00, 0x00, 0xf9, 0x0e, 0x00, 0x00, 0xf8, 0x0e, 0x00, 0x00, 0xf7, 0x0e, + 0x00, 0x00, 0xf6, 0x0e, 0x00, 0x00, 0xf5, 0x0e, 0x00, 0x00, 0xf4, 0x0e, 0x00, 0x00, 0xf3, 0x0e, 0x00, 0x00, 0xf2, 0x0e, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0xef, 0x0e, + 0x00, 0x00, 0xee, 0x0e, 0x00, 0x00, 0xed, 0x0e, 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xeb, 0x0e, 0x00, 0x00, 0xea, 0x0e, 0x00, 0x00, 0xe9, 0x0e, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x00, 0xe7, 0x0e, + 0x00, 0x00, 0xe6, 0x0e, 0x00, 0x00, 0xe5, 0x0e, 0x00, 0x00, 0xe4, 0x0e, 0x00, 0x00, 0xe3, 0x0e, 0x00, 0x00, 0xe2, 0x0e, 0x00, 0x00, 0xe1, 0x0e, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0xdf, 0x0e, + 0x00, 0x00, 0xde, 0x0e, 0x00, 0x00, 0xdd, 0x0e, 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0xdb, 0x0e, 0x00, 0x00, 0xda, 0x0e, 0x00, 0x00, 0xd9, 0x0e, 0x00, 0x00, 0xd8, 0x0e, 0x00, 0x00, 0xd7, 0x0e, + 0x00, 0x00, 0xd6, 0x0e, 0x00, 0x00, 0xd5, 0x0e, 0x00, 0x00, 0xd4, 0x0e, 0x00, 0x00, 0xd3, 0x0e, 0x00, 0x00, 0xd2, 0x0e, 0x00, 0x00, 0xd1, 0x0e, 0x00, 0x00, 0xd0, 0x0e, 0x00, 0x00, 0xcf, 0x0e, + 0x00, 0x00, 0xce, 0x0e, 0x00, 0x00, 0xcd, 0x0e, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x00, 0xcb, 0x0e, 0x00, 0x00, 0xca, 0x0e, 0x00, 0x00, 0xc9, 0x0e, 0x00, 0x00, 0xc8, 0x0e, 0x00, 0x00, 0xc7, 0x0e, + 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0xc5, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc3, 0x0e, 0x00, 0x00, 0xc2, 0x0e, 0x00, 0x00, 0xc1, 0x0e, 0x00, 0x00, 0xc0, 0x0e, 0x00, 0x00, 0xbf, 0x0e, + 0x00, 0x00, 0xbe, 0x0e, 0x00, 0x00, 0xbd, 0x0e, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x00, 0xbb, 0x0e, 0x00, 0x00, 0xba, 0x0e, 0x00, 0x00, 0xb9, 0x0e, 0x00, 0x00, 0xb8, 0x0e, 0x00, 0x00, 0xb7, 0x0e, + 0x00, 0x00, 0xb6, 0x0e, 0x00, 0x00, 0xb5, 0x0e, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x00, 0xb3, 0x0e, 0x00, 0x00, 0xb2, 0x0e, 0x00, 0x00, 0xb1, 0x0e, 0x00, 0x00, 0xb0, 0x0e, 0x00, 0x00, 0xaf, 0x0e, + 0x00, 0x00, 0xae, 0x0e, 0x00, 0x00, 0xad, 0x0e, 0x00, 0x00, 0xac, 0x0e, 0x00, 0x00, 0xab, 0x0e, 0x00, 0x00, 0xaa, 0x0e, 0x00, 0x00, 0xa9, 0x0e, 0x00, 0x00, 0xa8, 0x0e, 0x00, 0x00, 0xa7, 0x0e, + 0x00, 0x00, 0xa6, 0x0e, 0x00, 0x00, 0xa5, 0x0e, 0x00, 0x00, 0xa4, 0x0e, 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0xa2, 0x0e, 0x00, 0x00, 0xa1, 0x0e, 0x00, 0x00, 0xa0, 0x0e, 0x00, 0x00, 0x9f, 0x0e, + 0x00, 0x00, 0x9e, 0x0e, 0x00, 0x00, 0x9d, 0x0e, 0x00, 0x00, 0x9c, 0x0e, 0x00, 0x00, 0x9b, 0x0e, 0x00, 0x00, 0x9a, 0x0e, 0x00, 0x00, 0x99, 0x0e, 0x00, 0x00, 0x98, 0x0e, 0x00, 0x00, 0x97, 0x0e, + 0x00, 0x00, 0x96, 0x0e, 0x00, 0x00, 0x95, 0x0e, 0x00, 0x00, 0x94, 0x0e, 0x00, 0x00, 0x93, 0x0e, 0x00, 0x00, 0x92, 0x0e, 0x00, 0x00, 0x91, 0x0e, 0x00, 0x00, 0x90, 0x0e, 0x00, 0x00, 0x8f, 0x0e, + 0x00, 0x00, 0x8e, 0x0e, 0x00, 0x00, 0x8d, 0x0e, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x00, 0x8b, 0x0e, 0x00, 0x00, 0x8a, 0x0e, 0x00, 0x00, 0x89, 0x0e, 0x00, 0x00, 0x88, 0x0e, 0x00, 0x00, 0x87, 0x0e, + 0x00, 0x00, 0x86, 0x0e, 0x00, 0x00, 0x85, 0x0e, 0x00, 0x00, 0x84, 0x0e, 0x00, 0x00, 0x83, 0x0e, 0x00, 0x00, 0x82, 0x0e, 0x00, 0x00, 0x81, 0x0e, 0x00, 0x00, 0x80, 0x0e, 0x00, 0x00, 0x7f, 0x0e, + 0x00, 0x00, 0x7e, 0x0e, 0x00, 0x00, 0x7d, 0x0e, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x00, 0x7b, 0x0e, 0x00, 0x00, 0x7a, 0x0e, 0x00, 0x00, 0x79, 0x0e, 0x00, 0x00, 0x78, 0x0e, 0x00, 0x00, 0x77, 0x0e, + 0x00, 0x00, 0x76, 0x0e, 0x00, 0x00, 0x75, 0x0e, 0x00, 0x00, 0x74, 0x0e, 0x00, 0x00, 0x73, 0x0e, 0x00, 0x00, 0x72, 0x0e, 0x00, 0x00, 0x71, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x6f, 0x0e, + 0x00, 0x00, 0x6e, 0x0e, 0x00, 0x00, 0x6d, 0x0e, 0x00, 0x00, 0x6c, 0x0e, 0x00, 0x00, 0x6b, 0x0e, 0x00, 0x00, 0x6a, 0x0e, 0x00, 0x00, 0x69, 0x0e, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x00, 0x67, 0x0e, + 0x00, 0x00, 0x66, 0x0e, 0x00, 0x00, 0x65, 0x0e, 0x00, 0x00, 0x64, 0x0e, 0x00, 0x00, 0x63, 0x0e, 0x00, 0x00, 0x62, 0x0e, 0x00, 0x00, 0x61, 0x0e, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x00, 0x5f, 0x0e, + 0x00, 0x00, 0x5e, 0x0e, 0x00, 0x00, 0x5d, 0x0e, 0x00, 0x00, 0x5c, 0x0e, 0x00, 0x00, 0x5b, 0x0e, 0x00, 0x00, 0x5a, 0x0e, 0x00, 0x00, 0x59, 0x0e, 0x00, 0x00, 0x58, 0x0e, 0x00, 0x00, 0x57, 0x0e, + 0x00, 0x00, 0x56, 0x0e, 0x00, 0x00, 0x55, 0x0e, 0x00, 0x00, 0x54, 0x0e, 0x00, 0x00, 0x53, 0x0e, 0x00, 0x00, 0x52, 0x0e, 0x00, 0x00, 0x51, 0x0e, 0x00, 0x00, 0x50, 0x0e, 0x00, 0x00, 0x4f, 0x0e, + 0x00, 0x00, 0x4e, 0x0e, 0x00, 0x00, 0x4d, 0x0e, 0x00, 0x00, 0x4c, 0x0e, 0x00, 0x00, 0x4b, 0x0e, 0x00, 0x00, 0x4a, 0x0e, 0x00, 0x00, 0x49, 0x0e, 0x00, 0x00, 0x48, 0x0e, 0x00, 0x00, 0x47, 0x0e, + 0x00, 0x00, 0x46, 0x0e, 0x00, 0x00, 0x45, 0x0e, 0x00, 0x00, 0x44, 0x0e, 0x00, 0x00, 0x43, 0x0e, 0x00, 0x00, 0x42, 0x0e, 0x00, 0x00, 0x41, 0x0e, 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x3f, 0x0e, + 0x00, 0x00, 0x3e, 0x0e, 0x00, 0x00, 0x3d, 0x0e, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x3a, 0x0e, 0x00, 0x00, 0x39, 0x0e, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 0x37, 0x0e, + 0x00, 0x00, 0x36, 0x0e, 0x00, 0x00, 0x35, 0x0e, 0x00, 0x00, 0x34, 0x0e, 0x00, 0x00, 0x33, 0x0e, 0x00, 0x00, 0x32, 0x0e, 0x00, 0x00, 0x31, 0x0e, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x2f, 0x0e, + 0x00, 0x00, 0x2e, 0x0e, 0x00, 0x00, 0x2d, 0x0e, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00, 0x2b, 0x0e, 0x00, 0x00, 0x2a, 0x0e, 0x00, 0x00, 0x29, 0x0e, 0x00, 0x00, 0x28, 0x0e, 0x00, 0x00, 0x27, 0x0e, + 0x00, 0x00, 0x26, 0x0e, 0x00, 0x00, 0x25, 0x0e, 0x00, 0x00, 0x24, 0x0e, 0x00, 0x00, 0x23, 0x0e, 0x00, 0x00, 0x22, 0x0e, 0x00, 0x00, 0x21, 0x0e, 0x00, 0x00, 0x20, 0x0e, 0x00, 0x00, 0x1f, 0x0e, + 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x1d, 0x0e, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0x1b, 0x0e, 0x00, 0x00, 0x1a, 0x0e, 0x00, 0x00, 0x19, 0x0e, 0x00, 0x00, 0x18, 0x0e, 0x00, 0x00, 0x17, 0x0e, + 0x00, 0x00, 0x16, 0x0e +}; + +const byte DTable_5[65540] = { + 0x0e, 0x00, 0x01, 0x00, 0x30, 0x16, 0x00, 0x03, 0x38, 0x16, 0x00, 0x03, 0x40, 0x16, 0x00, 0x03, 0x48, 0x16, 0x00, 0x03, 0x50, 0x16, 0x00, 0x03, 0x24, 0x06, 0x01, 0x02, 0x28, 0x06, 0x01, 0x02, + 0x2c, 0x06, 0x01, 0x02, 0x30, 0x06, 0x01, 0x02, 0x34, 0x06, 0x01, 0x02, 0x38, 0x06, 0x01, 0x02, 0x48, 0x1d, 0x02, 0x03, 0x50, 0x1d, 0x02, 0x03, 0x58, 0x1d, 0x02, 0x03, 0x60, 0x1d, 0x02, 0x03, + 0x68, 0x1d, 0x02, 0x03, 0x10, 0x3c, 0x03, 0x04, 0x20, 0x3c, 0x03, 0x04, 0x30, 0x3c, 0x03, 0x04, 0x70, 0x12, 0x04, 0x04, 0x80, 0x12, 0x04, 0x04, 0xa0, 0x2d, 0x05, 0x05, 0xe0, 0x08, 0x06, 0x05, + 0x80, 0x00, 0x08, 0x06, 0x58, 0x16, 0x00, 0x03, 0x60, 0x16, 0x00, 0x03, 0x68, 0x16, 0x00, 0x03, 0x70, 0x16, 0x00, 0x03, 0x78, 0x16, 0x00, 0x03, 0x3c, 0x06, 0x01, 0x02, 0x40, 0x06, 0x01, 0x02, + 0x44, 0x06, 0x01, 0x02, 0x48, 0x06, 0x01, 0x02, 0x4c, 0x06, 0x01, 0x02, 0x50, 0x06, 0x01, 0x02, 0x70, 0x1d, 0x02, 0x03, 0x78, 0x1d, 0x02, 0x03, 0x80, 0x1d, 0x02, 0x03, 0x88, 0x1d, 0x02, 0x03, + 0x90, 0x1d, 0x02, 0x03, 0x40, 0x3c, 0x03, 0x04, 0x50, 0x3c, 0x03, 0x04, 0x60, 0x3c, 0x03, 0x04, 0x90, 0x12, 0x04, 0x04, 0xa0, 0x12, 0x04, 0x04, 0xc0, 0x2d, 0x05, 0x05, 0x00, 0x09, 0x06, 0x05, + 0xc0, 0x00, 0x08, 0x06, 0x80, 0x16, 0x00, 0x03, 0x88, 0x16, 0x00, 0x03, 0x90, 0x16, 0x00, 0x03, 0x98, 0x16, 0x00, 0x03, 0xa0, 0x16, 0x00, 0x03, 0x54, 0x06, 0x01, 0x02, 0x58, 0x06, 0x01, 0x02, + 0x5c, 0x06, 0x01, 0x02, 0x60, 0x06, 0x01, 0x02, 0x64, 0x06, 0x01, 0x02, 0x68, 0x06, 0x01, 0x02, 0x98, 0x1d, 0x02, 0x03, 0xa0, 0x1d, 0x02, 0x03, 0xa8, 0x1d, 0x02, 0x03, 0xb0, 0x1d, 0x02, 0x03, + 0xb8, 0x1d, 0x02, 0x03, 0x70, 0x3c, 0x03, 0x04, 0x80, 0x3c, 0x03, 0x04, 0x90, 0x3c, 0x03, 0x04, 0xb0, 0x12, 0x04, 0x04, 0xc0, 0x12, 0x04, 0x04, 0xe0, 0x2d, 0x05, 0x05, 0x20, 0x09, 0x06, 0x05, + 0x00, 0x01, 0x08, 0x06, 0xa8, 0x16, 0x00, 0x03, 0xb0, 0x16, 0x00, 0x03, 0xb8, 0x16, 0x00, 0x03, 0xc0, 0x16, 0x00, 0x03, 0xc8, 0x16, 0x00, 0x03, 0x6c, 0x06, 0x01, 0x02, 0x70, 0x06, 0x01, 0x02, + 0x74, 0x06, 0x01, 0x02, 0x78, 0x06, 0x01, 0x02, 0x7c, 0x06, 0x01, 0x02, 0x80, 0x06, 0x01, 0x02, 0xc0, 0x1d, 0x02, 0x03, 0xc8, 0x1d, 0x02, 0x03, 0xd0, 0x1d, 0x02, 0x03, 0xd8, 0x1d, 0x02, 0x03, + 0xe0, 0x1d, 0x02, 0x03, 0xa0, 0x3c, 0x03, 0x04, 0xb0, 0x3c, 0x03, 0x04, 0xc0, 0x3c, 0x03, 0x04, 0xd0, 0x12, 0x04, 0x04, 0xe0, 0x12, 0x04, 0x04, 0x00, 0x2e, 0x05, 0x05, 0x40, 0x09, 0x06, 0x05, + 0x40, 0x01, 0x08, 0x06, 0xd0, 0x16, 0x00, 0x03, 0xd8, 0x16, 0x00, 0x03, 0xe0, 0x16, 0x00, 0x03, 0xe8, 0x16, 0x00, 0x03, 0xf0, 0x16, 0x00, 0x03, 0x84, 0x06, 0x01, 0x02, 0x88, 0x06, 0x01, 0x02, + 0x8c, 0x06, 0x01, 0x02, 0x90, 0x06, 0x01, 0x02, 0x94, 0x06, 0x01, 0x02, 0x98, 0x06, 0x01, 0x02, 0xe8, 0x1d, 0x02, 0x03, 0xf0, 0x1d, 0x02, 0x03, 0xf8, 0x1d, 0x02, 0x03, 0x00, 0x1e, 0x02, 0x03, + 0x08, 0x1e, 0x02, 0x03, 0xd0, 0x3c, 0x03, 0x04, 0xe0, 0x3c, 0x03, 0x04, 0xf0, 0x3c, 0x03, 0x04, 0xf0, 0x12, 0x04, 0x04, 0x00, 0x13, 0x04, 0x04, 0x20, 0x2e, 0x05, 0x05, 0x60, 0x09, 0x06, 0x05, + 0x80, 0x01, 0x08, 0x06, 0xf8, 0x16, 0x00, 0x03, 0x00, 0x17, 0x00, 0x03, 0x08, 0x17, 0x00, 0x03, 0x10, 0x17, 0x00, 0x03, 0x18, 0x17, 0x00, 0x03, 0x9c, 0x06, 0x01, 0x02, 0xa0, 0x06, 0x01, 0x02, + 0xa4, 0x06, 0x01, 0x02, 0xa8, 0x06, 0x01, 0x02, 0xac, 0x06, 0x01, 0x02, 0xb0, 0x06, 0x01, 0x02, 0x10, 0x1e, 0x02, 0x03, 0x18, 0x1e, 0x02, 0x03, 0x20, 0x1e, 0x02, 0x03, 0x28, 0x1e, 0x02, 0x03, + 0x30, 0x1e, 0x02, 0x03, 0x00, 0x3d, 0x03, 0x04, 0x10, 0x3d, 0x03, 0x04, 0x20, 0x3d, 0x03, 0x04, 0x10, 0x13, 0x04, 0x04, 0x20, 0x13, 0x04, 0x04, 0x40, 0x2e, 0x05, 0x05, 0x80, 0x09, 0x06, 0x05, + 0xc0, 0x01, 0x08, 0x06, 0x20, 0x17, 0x00, 0x03, 0x28, 0x17, 0x00, 0x03, 0x30, 0x17, 0x00, 0x03, 0x38, 0x17, 0x00, 0x03, 0x40, 0x17, 0x00, 0x03, 0xb4, 0x06, 0x01, 0x02, 0xb8, 0x06, 0x01, 0x02, + 0xbc, 0x06, 0x01, 0x02, 0xc0, 0x06, 0x01, 0x02, 0xc4, 0x06, 0x01, 0x02, 0xc8, 0x06, 0x01, 0x02, 0x38, 0x1e, 0x02, 0x03, 0x40, 0x1e, 0x02, 0x03, 0x48, 0x1e, 0x02, 0x03, 0x50, 0x1e, 0x02, 0x03, + 0x58, 0x1e, 0x02, 0x03, 0x30, 0x3d, 0x03, 0x04, 0x40, 0x3d, 0x03, 0x04, 0x50, 0x3d, 0x03, 0x04, 0x30, 0x13, 0x04, 0x04, 0x40, 0x13, 0x04, 0x04, 0x60, 0x2e, 0x05, 0x05, 0xa0, 0x09, 0x06, 0x05, + 0x00, 0x02, 0x08, 0x06, 0x48, 0x17, 0x00, 0x03, 0x50, 0x17, 0x00, 0x03, 0x58, 0x17, 0x00, 0x03, 0x60, 0x17, 0x00, 0x03, 0x68, 0x17, 0x00, 0x03, 0xcc, 0x06, 0x01, 0x02, 0xd0, 0x06, 0x01, 0x02, + 0xd4, 0x06, 0x01, 0x02, 0xd8, 0x06, 0x01, 0x02, 0xdc, 0x06, 0x01, 0x02, 0xe0, 0x06, 0x01, 0x02, 0x60, 0x1e, 0x02, 0x03, 0x68, 0x1e, 0x02, 0x03, 0x70, 0x1e, 0x02, 0x03, 0x78, 0x1e, 0x02, 0x03, + 0x80, 0x1e, 0x02, 0x03, 0x60, 0x3d, 0x03, 0x04, 0x70, 0x3d, 0x03, 0x04, 0x80, 0x3d, 0x03, 0x04, 0x50, 0x13, 0x04, 0x04, 0x60, 0x13, 0x04, 0x04, 0x80, 0x2e, 0x05, 0x05, 0xc0, 0x09, 0x06, 0x05, + 0x40, 0x02, 0x08, 0x06, 0x70, 0x17, 0x00, 0x03, 0x78, 0x17, 0x00, 0x03, 0x80, 0x17, 0x00, 0x03, 0x88, 0x17, 0x00, 0x03, 0xe4, 0x06, 0x01, 0x02, 0xe8, 0x06, 0x01, 0x02, 0xec, 0x06, 0x01, 0x02, + 0xf0, 0x06, 0x01, 0x02, 0xf4, 0x06, 0x01, 0x02, 0xf8, 0x06, 0x01, 0x02, 0xfc, 0x06, 0x01, 0x02, 0x88, 0x1e, 0x02, 0x03, 0x90, 0x1e, 0x02, 0x03, 0x98, 0x1e, 0x02, 0x03, 0xa0, 0x1e, 0x02, 0x03, + 0xa8, 0x1e, 0x02, 0x03, 0x90, 0x3d, 0x03, 0x04, 0xa0, 0x3d, 0x03, 0x04, 0xb0, 0x3d, 0x03, 0x04, 0x70, 0x13, 0x04, 0x04, 0x80, 0x13, 0x04, 0x04, 0xa0, 0x2e, 0x05, 0x05, 0xe0, 0x09, 0x06, 0x05, + 0x80, 0x02, 0x08, 0x06, 0x90, 0x17, 0x00, 0x03, 0x98, 0x17, 0x00, 0x03, 0xa0, 0x17, 0x00, 0x03, 0xa8, 0x17, 0x00, 0x03, 0x00, 0x07, 0x01, 0x02, 0x04, 0x07, 0x01, 0x02, 0x08, 0x07, 0x01, 0x02, + 0x0c, 0x07, 0x01, 0x02, 0x10, 0x07, 0x01, 0x02, 0x14, 0x07, 0x01, 0x02, 0x18, 0x07, 0x01, 0x02, 0xb0, 0x1e, 0x02, 0x03, 0xb8, 0x1e, 0x02, 0x03, 0xc0, 0x1e, 0x02, 0x03, 0xc8, 0x1e, 0x02, 0x03, + 0xd0, 0x1e, 0x02, 0x03, 0xc0, 0x3d, 0x03, 0x04, 0xd0, 0x3d, 0x03, 0x04, 0xe0, 0x3d, 0x03, 0x04, 0x90, 0x13, 0x04, 0x04, 0xc0, 0x2e, 0x05, 0x05, 0xe0, 0x2e, 0x05, 0x05, 0x00, 0x0a, 0x06, 0x05, + 0xc0, 0x02, 0x08, 0x06, 0xb0, 0x17, 0x00, 0x03, 0xb8, 0x17, 0x00, 0x03, 0xc0, 0x17, 0x00, 0x03, 0xc8, 0x17, 0x00, 0x03, 0x1c, 0x07, 0x01, 0x02, 0x20, 0x07, 0x01, 0x02, 0x24, 0x07, 0x01, 0x02, + 0x28, 0x07, 0x01, 0x02, 0x2c, 0x07, 0x01, 0x02, 0x30, 0x07, 0x01, 0x02, 0x34, 0x07, 0x01, 0x02, 0xd8, 0x1e, 0x02, 0x03, 0xe0, 0x1e, 0x02, 0x03, 0xe8, 0x1e, 0x02, 0x03, 0xf0, 0x1e, 0x02, 0x03, + 0xf8, 0x1e, 0x02, 0x03, 0xf0, 0x3d, 0x03, 0x04, 0x00, 0x3e, 0x03, 0x04, 0x10, 0x3e, 0x03, 0x04, 0xa0, 0x13, 0x04, 0x04, 0x00, 0x2f, 0x05, 0x05, 0x20, 0x2f, 0x05, 0x05, 0x20, 0x0a, 0x06, 0x05, + 0x00, 0x03, 0x08, 0x06, 0xd0, 0x17, 0x00, 0x03, 0xd8, 0x17, 0x00, 0x03, 0xe0, 0x17, 0x00, 0x03, 0xe8, 0x17, 0x00, 0x03, 0x38, 0x07, 0x01, 0x02, 0x3c, 0x07, 0x01, 0x02, 0x40, 0x07, 0x01, 0x02, + 0x44, 0x07, 0x01, 0x02, 0x48, 0x07, 0x01, 0x02, 0x4c, 0x07, 0x01, 0x02, 0x50, 0x07, 0x01, 0x02, 0x00, 0x1f, 0x02, 0x03, 0x08, 0x1f, 0x02, 0x03, 0x10, 0x1f, 0x02, 0x03, 0x18, 0x1f, 0x02, 0x03, + 0x20, 0x1f, 0x02, 0x03, 0x20, 0x3e, 0x03, 0x04, 0x30, 0x3e, 0x03, 0x04, 0x40, 0x3e, 0x03, 0x04, 0xb0, 0x13, 0x04, 0x04, 0x40, 0x2f, 0x05, 0x05, 0x60, 0x2f, 0x05, 0x05, 0x40, 0x0a, 0x06, 0x05, + 0x40, 0x03, 0x08, 0x06, 0xf0, 0x17, 0x00, 0x03, 0xf8, 0x17, 0x00, 0x03, 0x00, 0x18, 0x00, 0x03, 0x08, 0x18, 0x00, 0x03, 0x54, 0x07, 0x01, 0x02, 0x58, 0x07, 0x01, 0x02, 0x5c, 0x07, 0x01, 0x02, + 0x60, 0x07, 0x01, 0x02, 0x64, 0x07, 0x01, 0x02, 0x68, 0x07, 0x01, 0x02, 0x6c, 0x07, 0x01, 0x02, 0x28, 0x1f, 0x02, 0x03, 0x30, 0x1f, 0x02, 0x03, 0x38, 0x1f, 0x02, 0x03, 0x40, 0x1f, 0x02, 0x03, + 0x48, 0x1f, 0x02, 0x03, 0x50, 0x3e, 0x03, 0x04, 0x60, 0x3e, 0x03, 0x04, 0x70, 0x3e, 0x03, 0x04, 0xc0, 0x13, 0x04, 0x04, 0x80, 0x2f, 0x05, 0x05, 0xa0, 0x2f, 0x05, 0x05, 0x60, 0x0a, 0x06, 0x05, + 0x80, 0x03, 0x08, 0x06, 0x10, 0x18, 0x00, 0x03, 0x18, 0x18, 0x00, 0x03, 0x20, 0x18, 0x00, 0x03, 0x28, 0x18, 0x00, 0x03, 0x70, 0x07, 0x01, 0x02, 0x74, 0x07, 0x01, 0x02, 0x78, 0x07, 0x01, 0x02, + 0x7c, 0x07, 0x01, 0x02, 0x80, 0x07, 0x01, 0x02, 0x84, 0x07, 0x01, 0x02, 0x88, 0x07, 0x01, 0x02, 0x50, 0x1f, 0x02, 0x03, 0x58, 0x1f, 0x02, 0x03, 0x60, 0x1f, 0x02, 0x03, 0x68, 0x1f, 0x02, 0x03, + 0x70, 0x1f, 0x02, 0x03, 0x80, 0x3e, 0x03, 0x04, 0x90, 0x3e, 0x03, 0x04, 0xd0, 0x13, 0x04, 0x04, 0xe0, 0x13, 0x04, 0x04, 0xc0, 0x2f, 0x05, 0x05, 0xe0, 0x2f, 0x05, 0x05, 0x80, 0x0a, 0x06, 0x05, + 0xc0, 0x03, 0x08, 0x06, 0x30, 0x18, 0x00, 0x03, 0x38, 0x18, 0x00, 0x03, 0x40, 0x18, 0x00, 0x03, 0x48, 0x18, 0x00, 0x03, 0x8c, 0x07, 0x01, 0x02, 0x90, 0x07, 0x01, 0x02, 0x94, 0x07, 0x01, 0x02, + 0x98, 0x07, 0x01, 0x02, 0x9c, 0x07, 0x01, 0x02, 0xa0, 0x07, 0x01, 0x02, 0xa4, 0x07, 0x01, 0x02, 0x78, 0x1f, 0x02, 0x03, 0x80, 0x1f, 0x02, 0x03, 0x88, 0x1f, 0x02, 0x03, 0x90, 0x1f, 0x02, 0x03, + 0x98, 0x1f, 0x02, 0x03, 0xa0, 0x3e, 0x03, 0x04, 0xb0, 0x3e, 0x03, 0x04, 0xf0, 0x13, 0x04, 0x04, 0x00, 0x14, 0x04, 0x04, 0x00, 0x30, 0x05, 0x05, 0x20, 0x30, 0x05, 0x05, 0xa0, 0x0a, 0x06, 0x05, + 0x00, 0x04, 0x08, 0x06, 0x50, 0x18, 0x00, 0x03, 0x58, 0x18, 0x00, 0x03, 0x60, 0x18, 0x00, 0x03, 0x68, 0x18, 0x00, 0x03, 0xa8, 0x07, 0x01, 0x02, 0xac, 0x07, 0x01, 0x02, 0xb0, 0x07, 0x01, 0x02, + 0xb4, 0x07, 0x01, 0x02, 0xb8, 0x07, 0x01, 0x02, 0xbc, 0x07, 0x01, 0x02, 0xc0, 0x07, 0x01, 0x02, 0xa0, 0x1f, 0x02, 0x03, 0xa8, 0x1f, 0x02, 0x03, 0xb0, 0x1f, 0x02, 0x03, 0xb8, 0x1f, 0x02, 0x03, + 0xc0, 0x1f, 0x02, 0x03, 0xc0, 0x3e, 0x03, 0x04, 0xd0, 0x3e, 0x03, 0x04, 0x10, 0x14, 0x04, 0x04, 0x20, 0x14, 0x04, 0x04, 0x40, 0x30, 0x05, 0x05, 0x60, 0x30, 0x05, 0x05, 0xc0, 0x0a, 0x06, 0x05, + 0x40, 0x04, 0x08, 0x06, 0x70, 0x18, 0x00, 0x03, 0x78, 0x18, 0x00, 0x03, 0x80, 0x18, 0x00, 0x03, 0x88, 0x18, 0x00, 0x03, 0xc4, 0x07, 0x01, 0x02, 0xc8, 0x07, 0x01, 0x02, 0xcc, 0x07, 0x01, 0x02, + 0xd0, 0x07, 0x01, 0x02, 0xd4, 0x07, 0x01, 0x02, 0xd8, 0x07, 0x01, 0x02, 0xdc, 0x07, 0x01, 0x02, 0xc8, 0x1f, 0x02, 0x03, 0xd0, 0x1f, 0x02, 0x03, 0xd8, 0x1f, 0x02, 0x03, 0xe0, 0x1f, 0x02, 0x03, + 0xe8, 0x1f, 0x02, 0x03, 0xe0, 0x3e, 0x03, 0x04, 0xf0, 0x3e, 0x03, 0x04, 0x30, 0x14, 0x04, 0x04, 0x40, 0x14, 0x04, 0x04, 0x80, 0x30, 0x05, 0x05, 0xa0, 0x30, 0x05, 0x05, 0xe0, 0x0a, 0x06, 0x05, + 0x80, 0x04, 0x08, 0x06, 0x90, 0x18, 0x00, 0x03, 0x98, 0x18, 0x00, 0x03, 0xa0, 0x18, 0x00, 0x03, 0xa8, 0x18, 0x00, 0x03, 0xe0, 0x07, 0x01, 0x02, 0xe4, 0x07, 0x01, 0x02, 0xe8, 0x07, 0x01, 0x02, + 0xec, 0x07, 0x01, 0x02, 0xf0, 0x07, 0x01, 0x02, 0xf4, 0x07, 0x01, 0x02, 0xf8, 0x07, 0x01, 0x02, 0xf0, 0x1f, 0x02, 0x03, 0xf8, 0x1f, 0x02, 0x03, 0x00, 0x20, 0x02, 0x03, 0x08, 0x20, 0x02, 0x03, + 0x00, 0x3f, 0x03, 0x04, 0x10, 0x3f, 0x03, 0x04, 0x20, 0x3f, 0x03, 0x04, 0x50, 0x14, 0x04, 0x04, 0x60, 0x14, 0x04, 0x04, 0xc0, 0x30, 0x05, 0x05, 0xe0, 0x30, 0x05, 0x05, 0x00, 0x0b, 0x06, 0x05, + 0xc0, 0x04, 0x08, 0x06, 0xb0, 0x18, 0x00, 0x03, 0xb8, 0x18, 0x00, 0x03, 0xc0, 0x18, 0x00, 0x03, 0xc8, 0x18, 0x00, 0x03, 0xfc, 0x07, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x04, 0x08, 0x01, 0x02, + 0x08, 0x08, 0x01, 0x02, 0x0c, 0x08, 0x01, 0x02, 0x10, 0x08, 0x01, 0x02, 0x14, 0x08, 0x01, 0x02, 0x10, 0x20, 0x02, 0x03, 0x18, 0x20, 0x02, 0x03, 0x20, 0x20, 0x02, 0x03, 0x28, 0x20, 0x02, 0x03, + 0x30, 0x3f, 0x03, 0x04, 0x40, 0x3f, 0x03, 0x04, 0x50, 0x3f, 0x03, 0x04, 0x70, 0x14, 0x04, 0x04, 0x80, 0x14, 0x04, 0x04, 0x00, 0x31, 0x05, 0x05, 0x20, 0x31, 0x05, 0x05, 0x20, 0x0b, 0x06, 0x05, + 0x00, 0x05, 0x08, 0x06, 0xd0, 0x18, 0x00, 0x03, 0xd8, 0x18, 0x00, 0x03, 0xe0, 0x18, 0x00, 0x03, 0xe8, 0x18, 0x00, 0x03, 0x18, 0x08, 0x01, 0x02, 0x1c, 0x08, 0x01, 0x02, 0x20, 0x08, 0x01, 0x02, + 0x24, 0x08, 0x01, 0x02, 0x28, 0x08, 0x01, 0x02, 0x2c, 0x08, 0x01, 0x02, 0x30, 0x08, 0x01, 0x02, 0x30, 0x20, 0x02, 0x03, 0x38, 0x20, 0x02, 0x03, 0x40, 0x20, 0x02, 0x03, 0x48, 0x20, 0x02, 0x03, + 0x60, 0x3f, 0x03, 0x04, 0x70, 0x3f, 0x03, 0x04, 0x80, 0x3f, 0x03, 0x04, 0x90, 0x14, 0x04, 0x04, 0xa0, 0x14, 0x04, 0x04, 0x40, 0x31, 0x05, 0x05, 0x60, 0x31, 0x05, 0x05, 0x40, 0x0b, 0x06, 0x05, + 0x40, 0x05, 0x08, 0x06, 0xf0, 0x18, 0x00, 0x03, 0xf8, 0x18, 0x00, 0x03, 0x00, 0x19, 0x00, 0x03, 0x08, 0x19, 0x00, 0x03, 0x34, 0x08, 0x01, 0x02, 0x38, 0x08, 0x01, 0x02, 0x3c, 0x08, 0x01, 0x02, + 0x40, 0x08, 0x01, 0x02, 0x44, 0x08, 0x01, 0x02, 0x48, 0x08, 0x01, 0x02, 0x4c, 0x08, 0x01, 0x02, 0x50, 0x20, 0x02, 0x03, 0x58, 0x20, 0x02, 0x03, 0x60, 0x20, 0x02, 0x03, 0x68, 0x20, 0x02, 0x03, + 0x90, 0x3f, 0x03, 0x04, 0xa0, 0x3f, 0x03, 0x04, 0xb0, 0x3f, 0x03, 0x04, 0xb0, 0x14, 0x04, 0x04, 0xc0, 0x14, 0x04, 0x04, 0x80, 0x31, 0x05, 0x05, 0xa0, 0x31, 0x05, 0x05, 0x60, 0x0b, 0x06, 0x05, + 0x80, 0x15, 0x09, 0x07, 0x10, 0x19, 0x00, 0x03, 0x18, 0x19, 0x00, 0x03, 0x20, 0x19, 0x00, 0x03, 0x28, 0x19, 0x00, 0x03, 0x50, 0x08, 0x01, 0x02, 0x54, 0x08, 0x01, 0x02, 0x58, 0x08, 0x01, 0x02, + 0x5c, 0x08, 0x01, 0x02, 0x60, 0x08, 0x01, 0x02, 0x64, 0x08, 0x01, 0x02, 0x68, 0x08, 0x01, 0x02, 0x70, 0x20, 0x02, 0x03, 0x78, 0x20, 0x02, 0x03, 0x80, 0x20, 0x02, 0x03, 0x88, 0x20, 0x02, 0x03, + 0xc0, 0x3f, 0x03, 0x04, 0xd0, 0x3f, 0x03, 0x04, 0xe0, 0x3f, 0x03, 0x04, 0xd0, 0x14, 0x04, 0x04, 0xe0, 0x14, 0x04, 0x04, 0xc0, 0x31, 0x05, 0x05, 0xe0, 0x31, 0x05, 0x05, 0x80, 0x0b, 0x06, 0x05, + 0x00, 0x16, 0x09, 0x07, 0x30, 0x19, 0x00, 0x03, 0x38, 0x19, 0x00, 0x03, 0x40, 0x19, 0x00, 0x03, 0x48, 0x19, 0x00, 0x03, 0x6c, 0x08, 0x01, 0x02, 0x70, 0x08, 0x01, 0x02, 0x74, 0x08, 0x01, 0x02, + 0x78, 0x08, 0x01, 0x02, 0x7c, 0x08, 0x01, 0x02, 0x80, 0x08, 0x01, 0x02, 0x84, 0x08, 0x01, 0x02, 0x90, 0x20, 0x02, 0x03, 0x98, 0x20, 0x02, 0x03, 0xa0, 0x20, 0x02, 0x03, 0xa8, 0x20, 0x02, 0x03, + 0xf0, 0x3f, 0x03, 0x04, 0x00, 0x00, 0x03, 0x03, 0x08, 0x00, 0x03, 0x03, 0xf0, 0x14, 0x04, 0x04, 0x00, 0x15, 0x04, 0x04, 0x00, 0x32, 0x05, 0x05, 0x20, 0x32, 0x05, 0x05, 0xa0, 0x0b, 0x06, 0x05, + 0x80, 0x16, 0x09, 0x07, 0x50, 0x19, 0x00, 0x03, 0x58, 0x19, 0x00, 0x03, 0x60, 0x19, 0x00, 0x03, 0x68, 0x19, 0x00, 0x03, 0x88, 0x08, 0x01, 0x02, 0x8c, 0x08, 0x01, 0x02, 0x90, 0x08, 0x01, 0x02, + 0x94, 0x08, 0x01, 0x02, 0x98, 0x08, 0x01, 0x02, 0x9c, 0x08, 0x01, 0x02, 0xa0, 0x08, 0x01, 0x02, 0xb0, 0x20, 0x02, 0x03, 0xb8, 0x20, 0x02, 0x03, 0xc0, 0x20, 0x02, 0x03, 0xc8, 0x20, 0x02, 0x03, + 0x10, 0x00, 0x03, 0x03, 0x18, 0x00, 0x03, 0x03, 0x20, 0x00, 0x03, 0x03, 0x10, 0x15, 0x04, 0x04, 0x20, 0x15, 0x04, 0x04, 0x40, 0x32, 0x05, 0x05, 0x60, 0x32, 0x05, 0x05, 0xc0, 0x0b, 0x06, 0x05, + 0x00, 0x17, 0x09, 0x07, 0x70, 0x19, 0x00, 0x03, 0x78, 0x19, 0x00, 0x03, 0x80, 0x19, 0x00, 0x03, 0x88, 0x19, 0x00, 0x03, 0xa4, 0x08, 0x01, 0x02, 0xa8, 0x08, 0x01, 0x02, 0xac, 0x08, 0x01, 0x02, + 0xb0, 0x08, 0x01, 0x02, 0xb4, 0x08, 0x01, 0x02, 0xb8, 0x08, 0x01, 0x02, 0xbc, 0x08, 0x01, 0x02, 0xd0, 0x20, 0x02, 0x03, 0xd8, 0x20, 0x02, 0x03, 0xe0, 0x20, 0x02, 0x03, 0xe8, 0x20, 0x02, 0x03, + 0x28, 0x00, 0x03, 0x03, 0x30, 0x00, 0x03, 0x03, 0x38, 0x00, 0x03, 0x03, 0x30, 0x15, 0x04, 0x04, 0x40, 0x15, 0x04, 0x04, 0x80, 0x32, 0x05, 0x05, 0xa0, 0x32, 0x05, 0x05, 0x00, 0x21, 0x07, 0x06, + 0x80, 0x17, 0x09, 0x07, 0x90, 0x19, 0x00, 0x03, 0x98, 0x19, 0x00, 0x03, 0xa0, 0x19, 0x00, 0x03, 0xa8, 0x19, 0x00, 0x03, 0xc0, 0x08, 0x01, 0x02, 0xc4, 0x08, 0x01, 0x02, 0xc8, 0x08, 0x01, 0x02, + 0xcc, 0x08, 0x01, 0x02, 0xd0, 0x08, 0x01, 0x02, 0xd4, 0x08, 0x01, 0x02, 0xd8, 0x08, 0x01, 0x02, 0xf0, 0x20, 0x02, 0x03, 0xf8, 0x20, 0x02, 0x03, 0x00, 0x21, 0x02, 0x03, 0x08, 0x21, 0x02, 0x03, + 0x40, 0x00, 0x03, 0x03, 0x48, 0x00, 0x03, 0x03, 0x50, 0x00, 0x03, 0x03, 0x50, 0x15, 0x04, 0x04, 0x60, 0x15, 0x04, 0x04, 0xc0, 0x32, 0x05, 0x05, 0xe0, 0x32, 0x05, 0x05, 0x40, 0x21, 0x07, 0x06, + 0x00, 0x18, 0x09, 0x07, 0xb0, 0x19, 0x00, 0x03, 0xb8, 0x19, 0x00, 0x03, 0xc0, 0x19, 0x00, 0x03, 0xc8, 0x19, 0x00, 0x03, 0xdc, 0x08, 0x01, 0x02, 0xe0, 0x08, 0x01, 0x02, 0xe4, 0x08, 0x01, 0x02, + 0xe8, 0x08, 0x01, 0x02, 0xec, 0x08, 0x01, 0x02, 0xf0, 0x08, 0x01, 0x02, 0xf4, 0x08, 0x01, 0x02, 0x10, 0x21, 0x02, 0x03, 0x18, 0x21, 0x02, 0x03, 0x20, 0x21, 0x02, 0x03, 0x28, 0x21, 0x02, 0x03, + 0x58, 0x00, 0x03, 0x03, 0x60, 0x00, 0x03, 0x03, 0x68, 0x00, 0x03, 0x03, 0x70, 0x15, 0x04, 0x04, 0x80, 0x15, 0x04, 0x04, 0x00, 0x33, 0x05, 0x05, 0x20, 0x33, 0x05, 0x05, 0x80, 0x21, 0x07, 0x06, + 0x80, 0x18, 0x09, 0x07, 0xd0, 0x19, 0x00, 0x03, 0xd8, 0x19, 0x00, 0x03, 0xe0, 0x19, 0x00, 0x03, 0xe8, 0x19, 0x00, 0x03, 0xf8, 0x08, 0x01, 0x02, 0xfc, 0x08, 0x01, 0x02, 0x00, 0x09, 0x01, 0x02, + 0x04, 0x09, 0x01, 0x02, 0x08, 0x09, 0x01, 0x02, 0x0c, 0x09, 0x01, 0x02, 0x10, 0x09, 0x01, 0x02, 0x30, 0x21, 0x02, 0x03, 0x38, 0x21, 0x02, 0x03, 0x40, 0x21, 0x02, 0x03, 0x48, 0x21, 0x02, 0x03, + 0x70, 0x00, 0x03, 0x03, 0x78, 0x00, 0x03, 0x03, 0x80, 0x00, 0x03, 0x03, 0x90, 0x15, 0x04, 0x04, 0xa0, 0x15, 0x04, 0x04, 0x40, 0x33, 0x05, 0x05, 0x60, 0x33, 0x05, 0x05, 0xc0, 0x21, 0x07, 0x06, + 0x00, 0x19, 0x09, 0x07, 0xf0, 0x19, 0x00, 0x03, 0xf8, 0x19, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x03, 0x08, 0x1a, 0x00, 0x03, 0x14, 0x09, 0x01, 0x02, 0x18, 0x09, 0x01, 0x02, 0x1c, 0x09, 0x01, 0x02, + 0x20, 0x09, 0x01, 0x02, 0x24, 0x09, 0x01, 0x02, 0x28, 0x09, 0x01, 0x02, 0x2c, 0x09, 0x01, 0x02, 0x50, 0x21, 0x02, 0x03, 0x58, 0x21, 0x02, 0x03, 0x60, 0x21, 0x02, 0x03, 0x68, 0x21, 0x02, 0x03, + 0x88, 0x00, 0x03, 0x03, 0x90, 0x00, 0x03, 0x03, 0x98, 0x00, 0x03, 0x03, 0xb0, 0x15, 0x04, 0x04, 0xc0, 0x15, 0x04, 0x04, 0x80, 0x33, 0x05, 0x05, 0xa0, 0x33, 0x05, 0x05, 0x00, 0x22, 0x07, 0x06, + 0x80, 0x19, 0x09, 0x07, 0x10, 0x1a, 0x00, 0x03, 0x18, 0x1a, 0x00, 0x03, 0x20, 0x1a, 0x00, 0x03, 0x28, 0x1a, 0x00, 0x03, 0x30, 0x09, 0x01, 0x02, 0x34, 0x09, 0x01, 0x02, 0x38, 0x09, 0x01, 0x02, + 0x3c, 0x09, 0x01, 0x02, 0x40, 0x09, 0x01, 0x02, 0x44, 0x09, 0x01, 0x02, 0x48, 0x09, 0x01, 0x02, 0x70, 0x21, 0x02, 0x03, 0x78, 0x21, 0x02, 0x03, 0x80, 0x21, 0x02, 0x03, 0x88, 0x21, 0x02, 0x03, + 0xa0, 0x00, 0x03, 0x03, 0xa8, 0x00, 0x03, 0x03, 0xb0, 0x00, 0x03, 0x03, 0xd0, 0x15, 0x04, 0x04, 0xe0, 0x15, 0x04, 0x04, 0xc0, 0x33, 0x05, 0x05, 0xe0, 0x33, 0x05, 0x05, 0x40, 0x22, 0x07, 0x06, + 0x00, 0x1a, 0x09, 0x07, 0x30, 0x1a, 0x00, 0x03, 0x38, 0x1a, 0x00, 0x03, 0x40, 0x1a, 0x00, 0x03, 0x48, 0x1a, 0x00, 0x03, 0x4c, 0x09, 0x01, 0x02, 0x50, 0x09, 0x01, 0x02, 0x54, 0x09, 0x01, 0x02, + 0x58, 0x09, 0x01, 0x02, 0x5c, 0x09, 0x01, 0x02, 0x60, 0x09, 0x01, 0x02, 0x64, 0x09, 0x01, 0x02, 0x90, 0x21, 0x02, 0x03, 0x98, 0x21, 0x02, 0x03, 0xa0, 0x21, 0x02, 0x03, 0xa8, 0x21, 0x02, 0x03, + 0xb8, 0x00, 0x03, 0x03, 0xc0, 0x00, 0x03, 0x03, 0xc8, 0x00, 0x03, 0x03, 0xf0, 0x15, 0x04, 0x04, 0x00, 0x16, 0x04, 0x04, 0x00, 0x34, 0x05, 0x05, 0x20, 0x34, 0x05, 0x05, 0x80, 0x22, 0x07, 0x06, + 0x80, 0x1a, 0x09, 0x07, 0x50, 0x1a, 0x00, 0x03, 0x58, 0x1a, 0x00, 0x03, 0x60, 0x1a, 0x00, 0x03, 0x68, 0x1a, 0x00, 0x03, 0x68, 0x09, 0x01, 0x02, 0x6c, 0x09, 0x01, 0x02, 0x70, 0x09, 0x01, 0x02, + 0x74, 0x09, 0x01, 0x02, 0x78, 0x09, 0x01, 0x02, 0x7c, 0x09, 0x01, 0x02, 0x80, 0x09, 0x01, 0x02, 0xb0, 0x21, 0x02, 0x03, 0xb8, 0x21, 0x02, 0x03, 0xc0, 0x21, 0x02, 0x03, 0xc8, 0x21, 0x02, 0x03, + 0xd0, 0x00, 0x03, 0x03, 0xd8, 0x00, 0x03, 0x03, 0xe0, 0x00, 0x03, 0x03, 0x10, 0x16, 0x04, 0x04, 0x20, 0x16, 0x04, 0x04, 0x40, 0x34, 0x05, 0x05, 0x60, 0x34, 0x05, 0x05, 0xc0, 0x22, 0x07, 0x06, + 0x00, 0x1b, 0x09, 0x07, 0x70, 0x1a, 0x00, 0x03, 0x78, 0x1a, 0x00, 0x03, 0x80, 0x1a, 0x00, 0x03, 0x88, 0x1a, 0x00, 0x03, 0x84, 0x09, 0x01, 0x02, 0x88, 0x09, 0x01, 0x02, 0x8c, 0x09, 0x01, 0x02, + 0x90, 0x09, 0x01, 0x02, 0x94, 0x09, 0x01, 0x02, 0x98, 0x09, 0x01, 0x02, 0x9c, 0x09, 0x01, 0x02, 0xd0, 0x21, 0x02, 0x03, 0xd8, 0x21, 0x02, 0x03, 0xe0, 0x21, 0x02, 0x03, 0xe8, 0x21, 0x02, 0x03, + 0xe8, 0x00, 0x03, 0x03, 0xf0, 0x00, 0x03, 0x03, 0xf8, 0x00, 0x03, 0x03, 0x30, 0x16, 0x04, 0x04, 0x40, 0x16, 0x04, 0x04, 0x80, 0x34, 0x05, 0x05, 0xa0, 0x34, 0x05, 0x05, 0x00, 0x23, 0x07, 0x06, + 0x80, 0x1b, 0x09, 0x07, 0x90, 0x1a, 0x00, 0x03, 0x98, 0x1a, 0x00, 0x03, 0xa0, 0x1a, 0x00, 0x03, 0xa8, 0x1a, 0x00, 0x03, 0xa0, 0x09, 0x01, 0x02, 0xa4, 0x09, 0x01, 0x02, 0xa8, 0x09, 0x01, 0x02, + 0xac, 0x09, 0x01, 0x02, 0xb0, 0x09, 0x01, 0x02, 0xb4, 0x09, 0x01, 0x02, 0xb8, 0x09, 0x01, 0x02, 0xf0, 0x21, 0x02, 0x03, 0xf8, 0x21, 0x02, 0x03, 0x00, 0x22, 0x02, 0x03, 0x08, 0x22, 0x02, 0x03, + 0x00, 0x01, 0x03, 0x03, 0x08, 0x01, 0x03, 0x03, 0x10, 0x01, 0x03, 0x03, 0x50, 0x16, 0x04, 0x04, 0x60, 0x16, 0x04, 0x04, 0xc0, 0x34, 0x05, 0x05, 0xe0, 0x34, 0x05, 0x05, 0x40, 0x23, 0x07, 0x06, + 0x00, 0x1c, 0x09, 0x07, 0xb0, 0x1a, 0x00, 0x03, 0xb8, 0x1a, 0x00, 0x03, 0xc0, 0x1a, 0x00, 0x03, 0xc8, 0x1a, 0x00, 0x03, 0xbc, 0x09, 0x01, 0x02, 0xc0, 0x09, 0x01, 0x02, 0xc4, 0x09, 0x01, 0x02, + 0xc8, 0x09, 0x01, 0x02, 0xcc, 0x09, 0x01, 0x02, 0xd0, 0x09, 0x01, 0x02, 0xd4, 0x09, 0x01, 0x02, 0x10, 0x22, 0x02, 0x03, 0x18, 0x22, 0x02, 0x03, 0x20, 0x22, 0x02, 0x03, 0x28, 0x22, 0x02, 0x03, + 0x18, 0x01, 0x03, 0x03, 0x20, 0x01, 0x03, 0x03, 0x28, 0x01, 0x03, 0x03, 0x70, 0x16, 0x04, 0x04, 0x80, 0x16, 0x04, 0x04, 0x00, 0x35, 0x05, 0x05, 0x20, 0x35, 0x05, 0x05, 0x80, 0x23, 0x07, 0x06, + 0x80, 0x1c, 0x09, 0x07, 0xd0, 0x1a, 0x00, 0x03, 0xd8, 0x1a, 0x00, 0x03, 0xe0, 0x1a, 0x00, 0x03, 0xe8, 0x1a, 0x00, 0x03, 0xd8, 0x09, 0x01, 0x02, 0xdc, 0x09, 0x01, 0x02, 0xe0, 0x09, 0x01, 0x02, + 0xe4, 0x09, 0x01, 0x02, 0xe8, 0x09, 0x01, 0x02, 0xec, 0x09, 0x01, 0x02, 0xf0, 0x09, 0x01, 0x02, 0x30, 0x22, 0x02, 0x03, 0x38, 0x22, 0x02, 0x03, 0x40, 0x22, 0x02, 0x03, 0x48, 0x22, 0x02, 0x03, + 0x30, 0x01, 0x03, 0x03, 0x38, 0x01, 0x03, 0x03, 0x40, 0x01, 0x03, 0x03, 0x90, 0x16, 0x04, 0x04, 0xa0, 0x16, 0x04, 0x04, 0x40, 0x35, 0x05, 0x05, 0xe0, 0x0b, 0x06, 0x05, 0xc0, 0x23, 0x07, 0x06, + 0x00, 0x1d, 0x09, 0x07, 0xf0, 0x1a, 0x00, 0x03, 0xf8, 0x1a, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x03, 0x08, 0x1b, 0x00, 0x03, 0xf4, 0x09, 0x01, 0x02, 0xf8, 0x09, 0x01, 0x02, 0xfc, 0x09, 0x01, 0x02, + 0x00, 0x0a, 0x01, 0x02, 0x04, 0x0a, 0x01, 0x02, 0x08, 0x0a, 0x01, 0x02, 0x0c, 0x0a, 0x01, 0x02, 0x50, 0x22, 0x02, 0x03, 0x58, 0x22, 0x02, 0x03, 0x60, 0x22, 0x02, 0x03, 0x68, 0x22, 0x02, 0x03, + 0x48, 0x01, 0x03, 0x03, 0x50, 0x01, 0x03, 0x03, 0x58, 0x01, 0x03, 0x03, 0xb0, 0x16, 0x04, 0x04, 0xc0, 0x16, 0x04, 0x04, 0x60, 0x35, 0x05, 0x05, 0x00, 0x0c, 0x06, 0x05, 0x00, 0x24, 0x07, 0x06, + 0x80, 0x1d, 0x09, 0x07, 0x10, 0x1b, 0x00, 0x03, 0x18, 0x1b, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x03, 0x28, 0x1b, 0x00, 0x03, 0x10, 0x0a, 0x01, 0x02, 0x14, 0x0a, 0x01, 0x02, 0x18, 0x0a, 0x01, 0x02, + 0x1c, 0x0a, 0x01, 0x02, 0x20, 0x0a, 0x01, 0x02, 0x24, 0x0a, 0x01, 0x02, 0x28, 0x0a, 0x01, 0x02, 0x70, 0x22, 0x02, 0x03, 0x78, 0x22, 0x02, 0x03, 0x80, 0x22, 0x02, 0x03, 0x88, 0x22, 0x02, 0x03, + 0x60, 0x01, 0x03, 0x03, 0x68, 0x01, 0x03, 0x03, 0x70, 0x01, 0x03, 0x03, 0xd0, 0x16, 0x04, 0x04, 0xe0, 0x16, 0x04, 0x04, 0x80, 0x35, 0x05, 0x05, 0x20, 0x0c, 0x06, 0x05, 0x40, 0x24, 0x07, 0x06, + 0x00, 0x1e, 0x09, 0x07, 0x30, 0x1b, 0x00, 0x03, 0x38, 0x1b, 0x00, 0x03, 0x40, 0x1b, 0x00, 0x03, 0x48, 0x1b, 0x00, 0x03, 0x2c, 0x0a, 0x01, 0x02, 0x30, 0x0a, 0x01, 0x02, 0x34, 0x0a, 0x01, 0x02, + 0x38, 0x0a, 0x01, 0x02, 0x3c, 0x0a, 0x01, 0x02, 0x40, 0x0a, 0x01, 0x02, 0x44, 0x0a, 0x01, 0x02, 0x90, 0x22, 0x02, 0x03, 0x98, 0x22, 0x02, 0x03, 0xa0, 0x22, 0x02, 0x03, 0xa8, 0x22, 0x02, 0x03, + 0x78, 0x01, 0x03, 0x03, 0x80, 0x01, 0x03, 0x03, 0x88, 0x01, 0x03, 0x03, 0xf0, 0x16, 0x04, 0x04, 0x00, 0x17, 0x04, 0x04, 0xa0, 0x35, 0x05, 0x05, 0x40, 0x0c, 0x06, 0x05, 0x80, 0x24, 0x07, 0x06, + 0x80, 0x1e, 0x09, 0x07, 0x50, 0x1b, 0x00, 0x03, 0x58, 0x1b, 0x00, 0x03, 0x60, 0x1b, 0x00, 0x03, 0x68, 0x1b, 0x00, 0x03, 0x48, 0x0a, 0x01, 0x02, 0x4c, 0x0a, 0x01, 0x02, 0x50, 0x0a, 0x01, 0x02, + 0x54, 0x0a, 0x01, 0x02, 0x58, 0x0a, 0x01, 0x02, 0x5c, 0x0a, 0x01, 0x02, 0x60, 0x0a, 0x01, 0x02, 0xb0, 0x22, 0x02, 0x03, 0xb8, 0x22, 0x02, 0x03, 0xc0, 0x22, 0x02, 0x03, 0xc8, 0x22, 0x02, 0x03, + 0x90, 0x01, 0x03, 0x03, 0x98, 0x01, 0x03, 0x03, 0xa0, 0x01, 0x03, 0x03, 0x10, 0x17, 0x04, 0x04, 0x20, 0x17, 0x04, 0x04, 0xc0, 0x35, 0x05, 0x05, 0x60, 0x0c, 0x06, 0x05, 0xc0, 0x24, 0x07, 0x06, + 0x00, 0x1f, 0x09, 0x07, 0x70, 0x1b, 0x00, 0x03, 0x78, 0x1b, 0x00, 0x03, 0x80, 0x1b, 0x00, 0x03, 0x88, 0x1b, 0x00, 0x03, 0x64, 0x0a, 0x01, 0x02, 0x68, 0x0a, 0x01, 0x02, 0x6c, 0x0a, 0x01, 0x02, + 0x70, 0x0a, 0x01, 0x02, 0x74, 0x0a, 0x01, 0x02, 0x78, 0x0a, 0x01, 0x02, 0x7c, 0x0a, 0x01, 0x02, 0xd0, 0x22, 0x02, 0x03, 0xd8, 0x22, 0x02, 0x03, 0xe0, 0x22, 0x02, 0x03, 0xe8, 0x22, 0x02, 0x03, + 0xa8, 0x01, 0x03, 0x03, 0xb0, 0x01, 0x03, 0x03, 0xb8, 0x01, 0x03, 0x03, 0x30, 0x17, 0x04, 0x04, 0x40, 0x17, 0x04, 0x04, 0xe0, 0x35, 0x05, 0x05, 0x80, 0x0c, 0x06, 0x05, 0x00, 0x25, 0x07, 0x06, + 0x80, 0x1f, 0x09, 0x07, 0x90, 0x1b, 0x00, 0x03, 0x98, 0x1b, 0x00, 0x03, 0xa0, 0x1b, 0x00, 0x03, 0xa8, 0x1b, 0x00, 0x03, 0x80, 0x0a, 0x01, 0x02, 0x84, 0x0a, 0x01, 0x02, 0x88, 0x0a, 0x01, 0x02, + 0x8c, 0x0a, 0x01, 0x02, 0x90, 0x0a, 0x01, 0x02, 0x94, 0x0a, 0x01, 0x02, 0x98, 0x0a, 0x01, 0x02, 0xf0, 0x22, 0x02, 0x03, 0xf8, 0x22, 0x02, 0x03, 0x00, 0x23, 0x02, 0x03, 0x08, 0x23, 0x02, 0x03, + 0xc0, 0x01, 0x03, 0x03, 0xc8, 0x01, 0x03, 0x03, 0xd0, 0x01, 0x03, 0x03, 0x50, 0x17, 0x04, 0x04, 0x60, 0x17, 0x04, 0x04, 0x00, 0x36, 0x05, 0x05, 0xa0, 0x0c, 0x06, 0x05, 0x40, 0x25, 0x07, 0x06, + 0x00, 0x20, 0x09, 0x07, 0xb0, 0x1b, 0x00, 0x03, 0xb8, 0x1b, 0x00, 0x03, 0xc0, 0x1b, 0x00, 0x03, 0xc8, 0x1b, 0x00, 0x03, 0x9c, 0x0a, 0x01, 0x02, 0xa0, 0x0a, 0x01, 0x02, 0xa4, 0x0a, 0x01, 0x02, + 0xa8, 0x0a, 0x01, 0x02, 0xac, 0x0a, 0x01, 0x02, 0xb0, 0x0a, 0x01, 0x02, 0xb4, 0x0a, 0x01, 0x02, 0x10, 0x23, 0x02, 0x03, 0x18, 0x23, 0x02, 0x03, 0x20, 0x23, 0x02, 0x03, 0x28, 0x23, 0x02, 0x03, + 0xd8, 0x01, 0x03, 0x03, 0xe0, 0x01, 0x03, 0x03, 0xe8, 0x01, 0x03, 0x03, 0x70, 0x17, 0x04, 0x04, 0x80, 0x17, 0x04, 0x04, 0x20, 0x36, 0x05, 0x05, 0xc0, 0x0c, 0x06, 0x05, 0x80, 0x25, 0x07, 0x06, + 0x00, 0x32, 0x0a, 0x08, 0xd0, 0x1b, 0x00, 0x03, 0xd8, 0x1b, 0x00, 0x03, 0xe0, 0x1b, 0x00, 0x03, 0xe8, 0x1b, 0x00, 0x03, 0xb8, 0x0a, 0x01, 0x02, 0xbc, 0x0a, 0x01, 0x02, 0xc0, 0x0a, 0x01, 0x02, + 0xc4, 0x0a, 0x01, 0x02, 0xc8, 0x0a, 0x01, 0x02, 0xcc, 0x0a, 0x01, 0x02, 0xd0, 0x0a, 0x01, 0x02, 0x30, 0x23, 0x02, 0x03, 0x38, 0x23, 0x02, 0x03, 0x40, 0x23, 0x02, 0x03, 0x48, 0x23, 0x02, 0x03, + 0xf0, 0x01, 0x03, 0x03, 0xf8, 0x01, 0x03, 0x03, 0x00, 0x02, 0x03, 0x03, 0x90, 0x17, 0x04, 0x04, 0xa0, 0x17, 0x04, 0x04, 0x40, 0x36, 0x05, 0x05, 0xe0, 0x0c, 0x06, 0x05, 0xc0, 0x25, 0x07, 0x06, + 0x00, 0x33, 0x0a, 0x08, 0xf0, 0x1b, 0x00, 0x03, 0xf8, 0x1b, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x03, 0x08, 0x1c, 0x00, 0x03, 0xd4, 0x0a, 0x01, 0x02, 0xd8, 0x0a, 0x01, 0x02, 0xdc, 0x0a, 0x01, 0x02, + 0xe0, 0x0a, 0x01, 0x02, 0xe4, 0x0a, 0x01, 0x02, 0xe8, 0x0a, 0x01, 0x02, 0xec, 0x0a, 0x01, 0x02, 0x50, 0x23, 0x02, 0x03, 0x58, 0x23, 0x02, 0x03, 0x60, 0x23, 0x02, 0x03, 0x68, 0x23, 0x02, 0x03, + 0x08, 0x02, 0x03, 0x03, 0x10, 0x02, 0x03, 0x03, 0x18, 0x02, 0x03, 0x03, 0xb0, 0x17, 0x04, 0x04, 0xc0, 0x17, 0x04, 0x04, 0x60, 0x36, 0x05, 0x05, 0x00, 0x0d, 0x06, 0x05, 0x00, 0x26, 0x07, 0x06, + 0x00, 0x34, 0x0a, 0x08, 0x10, 0x1c, 0x00, 0x03, 0x18, 0x1c, 0x00, 0x03, 0x20, 0x1c, 0x00, 0x03, 0x28, 0x1c, 0x00, 0x03, 0xf0, 0x0a, 0x01, 0x02, 0xf4, 0x0a, 0x01, 0x02, 0xf8, 0x0a, 0x01, 0x02, + 0xfc, 0x0a, 0x01, 0x02, 0x00, 0x0b, 0x01, 0x02, 0x04, 0x0b, 0x01, 0x02, 0x08, 0x0b, 0x01, 0x02, 0x70, 0x23, 0x02, 0x03, 0x78, 0x23, 0x02, 0x03, 0x80, 0x23, 0x02, 0x03, 0x88, 0x23, 0x02, 0x03, + 0x20, 0x02, 0x03, 0x03, 0x28, 0x02, 0x03, 0x03, 0x30, 0x02, 0x03, 0x03, 0xd0, 0x17, 0x04, 0x04, 0xe0, 0x17, 0x04, 0x04, 0x80, 0x36, 0x05, 0x05, 0x20, 0x0d, 0x06, 0x05, 0x40, 0x26, 0x07, 0x06, + 0x00, 0x35, 0x0a, 0x08, 0x30, 0x1c, 0x00, 0x03, 0x38, 0x1c, 0x00, 0x03, 0x40, 0x1c, 0x00, 0x03, 0x48, 0x1c, 0x00, 0x03, 0x0c, 0x0b, 0x01, 0x02, 0x10, 0x0b, 0x01, 0x02, 0x14, 0x0b, 0x01, 0x02, + 0x18, 0x0b, 0x01, 0x02, 0x1c, 0x0b, 0x01, 0x02, 0x20, 0x0b, 0x01, 0x02, 0x24, 0x0b, 0x01, 0x02, 0x90, 0x23, 0x02, 0x03, 0x98, 0x23, 0x02, 0x03, 0xa0, 0x23, 0x02, 0x03, 0xa8, 0x23, 0x02, 0x03, + 0x38, 0x02, 0x03, 0x03, 0x40, 0x02, 0x03, 0x03, 0x48, 0x02, 0x03, 0x03, 0xf0, 0x17, 0x04, 0x04, 0x00, 0x18, 0x04, 0x04, 0xa0, 0x36, 0x05, 0x05, 0x40, 0x0d, 0x06, 0x05, 0x80, 0x26, 0x07, 0x06, + 0x00, 0x36, 0x0a, 0x08, 0x50, 0x1c, 0x00, 0x03, 0x58, 0x1c, 0x00, 0x03, 0x60, 0x1c, 0x00, 0x03, 0x68, 0x1c, 0x00, 0x03, 0x28, 0x0b, 0x01, 0x02, 0x2c, 0x0b, 0x01, 0x02, 0x30, 0x0b, 0x01, 0x02, + 0x34, 0x0b, 0x01, 0x02, 0x38, 0x0b, 0x01, 0x02, 0x3c, 0x0b, 0x01, 0x02, 0x40, 0x0b, 0x01, 0x02, 0xb0, 0x23, 0x02, 0x03, 0xb8, 0x23, 0x02, 0x03, 0xc0, 0x23, 0x02, 0x03, 0xc8, 0x23, 0x02, 0x03, + 0x50, 0x02, 0x03, 0x03, 0x58, 0x02, 0x03, 0x03, 0x60, 0x02, 0x03, 0x03, 0x10, 0x18, 0x04, 0x04, 0x20, 0x18, 0x04, 0x04, 0xc0, 0x36, 0x05, 0x05, 0x60, 0x0d, 0x06, 0x05, 0xc0, 0x26, 0x07, 0x06, + 0x00, 0x37, 0x0a, 0x08, 0x70, 0x1c, 0x00, 0x03, 0x78, 0x1c, 0x00, 0x03, 0x80, 0x1c, 0x00, 0x03, 0x88, 0x1c, 0x00, 0x03, 0x44, 0x0b, 0x01, 0x02, 0x48, 0x0b, 0x01, 0x02, 0x4c, 0x0b, 0x01, 0x02, + 0x50, 0x0b, 0x01, 0x02, 0x54, 0x0b, 0x01, 0x02, 0x58, 0x0b, 0x01, 0x02, 0x5c, 0x0b, 0x01, 0x02, 0xd0, 0x23, 0x02, 0x03, 0xd8, 0x23, 0x02, 0x03, 0xe0, 0x23, 0x02, 0x03, 0xe8, 0x23, 0x02, 0x03, + 0x68, 0x02, 0x03, 0x03, 0x70, 0x02, 0x03, 0x03, 0x78, 0x02, 0x03, 0x03, 0x30, 0x18, 0x04, 0x04, 0x40, 0x18, 0x04, 0x04, 0xe0, 0x36, 0x05, 0x05, 0x80, 0x0d, 0x06, 0x05, 0x00, 0x27, 0x07, 0x06, + 0x00, 0x38, 0x0a, 0x08, 0x90, 0x1c, 0x00, 0x03, 0x98, 0x1c, 0x00, 0x03, 0xa0, 0x1c, 0x00, 0x03, 0xa8, 0x1c, 0x00, 0x03, 0x60, 0x0b, 0x01, 0x02, 0x64, 0x0b, 0x01, 0x02, 0x68, 0x0b, 0x01, 0x02, + 0x6c, 0x0b, 0x01, 0x02, 0x70, 0x0b, 0x01, 0x02, 0x74, 0x0b, 0x01, 0x02, 0x78, 0x0b, 0x01, 0x02, 0xf0, 0x23, 0x02, 0x03, 0xf8, 0x23, 0x02, 0x03, 0x00, 0x24, 0x02, 0x03, 0x08, 0x24, 0x02, 0x03, + 0x80, 0x02, 0x03, 0x03, 0x88, 0x02, 0x03, 0x03, 0x90, 0x02, 0x03, 0x03, 0x50, 0x18, 0x04, 0x04, 0x60, 0x18, 0x04, 0x04, 0x00, 0x37, 0x05, 0x05, 0xa0, 0x0d, 0x06, 0x05, 0x40, 0x27, 0x07, 0x06, + 0x00, 0x39, 0x0a, 0x08, 0xb0, 0x1c, 0x00, 0x03, 0xb8, 0x1c, 0x00, 0x03, 0xc0, 0x1c, 0x00, 0x03, 0xc8, 0x1c, 0x00, 0x03, 0x7c, 0x0b, 0x01, 0x02, 0x80, 0x0b, 0x01, 0x02, 0x84, 0x0b, 0x01, 0x02, + 0x88, 0x0b, 0x01, 0x02, 0x8c, 0x0b, 0x01, 0x02, 0x90, 0x0b, 0x01, 0x02, 0x94, 0x0b, 0x01, 0x02, 0x10, 0x24, 0x02, 0x03, 0x18, 0x24, 0x02, 0x03, 0x20, 0x24, 0x02, 0x03, 0x28, 0x24, 0x02, 0x03, + 0x98, 0x02, 0x03, 0x03, 0xa0, 0x02, 0x03, 0x03, 0xa8, 0x02, 0x03, 0x03, 0x70, 0x18, 0x04, 0x04, 0x80, 0x18, 0x04, 0x04, 0x20, 0x37, 0x05, 0x05, 0xc0, 0x0d, 0x06, 0x05, 0x80, 0x27, 0x07, 0x06, + 0x00, 0x3a, 0x0a, 0x08, 0xd0, 0x1c, 0x00, 0x03, 0xd8, 0x1c, 0x00, 0x03, 0xe0, 0x1c, 0x00, 0x03, 0xe8, 0x1c, 0x00, 0x03, 0x98, 0x0b, 0x01, 0x02, 0x9c, 0x0b, 0x01, 0x02, 0xa0, 0x0b, 0x01, 0x02, + 0xa4, 0x0b, 0x01, 0x02, 0xa8, 0x0b, 0x01, 0x02, 0xac, 0x0b, 0x01, 0x02, 0xb0, 0x0b, 0x01, 0x02, 0x30, 0x24, 0x02, 0x03, 0x38, 0x24, 0x02, 0x03, 0x40, 0x24, 0x02, 0x03, 0x48, 0x24, 0x02, 0x03, + 0xb0, 0x02, 0x03, 0x03, 0xb8, 0x02, 0x03, 0x03, 0xc0, 0x02, 0x03, 0x03, 0x90, 0x18, 0x04, 0x04, 0xa0, 0x18, 0x04, 0x04, 0x40, 0x37, 0x05, 0x05, 0xe0, 0x0d, 0x06, 0x05, 0xc0, 0x27, 0x07, 0x06, + 0x00, 0x3b, 0x0a, 0x08, 0xf0, 0x1c, 0x00, 0x03, 0xf8, 0x1c, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x03, 0x08, 0x1d, 0x00, 0x03, 0xb4, 0x0b, 0x01, 0x02, 0xb8, 0x0b, 0x01, 0x02, 0xbc, 0x0b, 0x01, 0x02, + 0xc0, 0x0b, 0x01, 0x02, 0xc4, 0x0b, 0x01, 0x02, 0xc8, 0x0b, 0x01, 0x02, 0xcc, 0x0b, 0x01, 0x02, 0x50, 0x24, 0x02, 0x03, 0x58, 0x24, 0x02, 0x03, 0x60, 0x24, 0x02, 0x03, 0x68, 0x24, 0x02, 0x03, + 0xc8, 0x02, 0x03, 0x03, 0xd0, 0x02, 0x03, 0x03, 0xd8, 0x02, 0x03, 0x03, 0xb0, 0x18, 0x04, 0x04, 0xc0, 0x18, 0x04, 0x04, 0x60, 0x37, 0x05, 0x05, 0x00, 0x0e, 0x06, 0x05, 0x00, 0x28, 0x07, 0x06, + 0x00, 0x3c, 0x0a, 0x08, 0x10, 0x1d, 0x00, 0x03, 0x18, 0x1d, 0x00, 0x03, 0x20, 0x1d, 0x00, 0x03, 0x28, 0x1d, 0x00, 0x03, 0xd0, 0x0b, 0x01, 0x02, 0xd4, 0x0b, 0x01, 0x02, 0xd8, 0x0b, 0x01, 0x02, + 0xdc, 0x0b, 0x01, 0x02, 0xe0, 0x0b, 0x01, 0x02, 0xe4, 0x0b, 0x01, 0x02, 0xe8, 0x0b, 0x01, 0x02, 0x70, 0x24, 0x02, 0x03, 0x78, 0x24, 0x02, 0x03, 0x80, 0x24, 0x02, 0x03, 0x88, 0x24, 0x02, 0x03, + 0xe0, 0x02, 0x03, 0x03, 0xe8, 0x02, 0x03, 0x03, 0xf0, 0x02, 0x03, 0x03, 0xd0, 0x18, 0x04, 0x04, 0xe0, 0x18, 0x04, 0x04, 0x80, 0x37, 0x05, 0x05, 0x20, 0x0e, 0x06, 0x05, 0x40, 0x28, 0x07, 0x06, + 0x00, 0x3d, 0x0a, 0x08, 0x30, 0x1d, 0x00, 0x03, 0x38, 0x1d, 0x00, 0x03, 0x40, 0x1d, 0x00, 0x03, 0x48, 0x1d, 0x00, 0x03, 0xec, 0x0b, 0x01, 0x02, 0xf0, 0x0b, 0x01, 0x02, 0xf4, 0x0b, 0x01, 0x02, + 0xf8, 0x0b, 0x01, 0x02, 0xfc, 0x0b, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x04, 0x0c, 0x01, 0x02, 0x90, 0x24, 0x02, 0x03, 0x98, 0x24, 0x02, 0x03, 0xa0, 0x24, 0x02, 0x03, 0xa8, 0x24, 0x02, 0x03, + 0xf8, 0x02, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x08, 0x03, 0x03, 0x03, 0xf0, 0x18, 0x04, 0x04, 0x00, 0x19, 0x04, 0x04, 0xa0, 0x37, 0x05, 0x05, 0x40, 0x0e, 0x06, 0x05, 0x80, 0x28, 0x07, 0x06, + 0x00, 0x3e, 0x0a, 0x08, 0x50, 0x1d, 0x00, 0x03, 0x58, 0x1d, 0x00, 0x03, 0x60, 0x1d, 0x00, 0x03, 0x68, 0x1d, 0x00, 0x03, 0x08, 0x0c, 0x01, 0x02, 0x0c, 0x0c, 0x01, 0x02, 0x10, 0x0c, 0x01, 0x02, + 0x14, 0x0c, 0x01, 0x02, 0x18, 0x0c, 0x01, 0x02, 0x1c, 0x0c, 0x01, 0x02, 0x20, 0x0c, 0x01, 0x02, 0xb0, 0x24, 0x02, 0x03, 0xb8, 0x24, 0x02, 0x03, 0xc0, 0x24, 0x02, 0x03, 0xc8, 0x24, 0x02, 0x03, + 0x10, 0x03, 0x03, 0x03, 0x18, 0x03, 0x03, 0x03, 0x20, 0x03, 0x03, 0x03, 0x10, 0x19, 0x04, 0x04, 0x20, 0x19, 0x04, 0x04, 0xc0, 0x37, 0x05, 0x05, 0x60, 0x0e, 0x06, 0x05, 0xc0, 0x28, 0x07, 0x06, + 0x00, 0x3f, 0x0a, 0x08, 0x70, 0x1d, 0x00, 0x03, 0x78, 0x1d, 0x00, 0x03, 0x80, 0x1d, 0x00, 0x03, 0x88, 0x1d, 0x00, 0x03, 0x24, 0x0c, 0x01, 0x02, 0x28, 0x0c, 0x01, 0x02, 0x2c, 0x0c, 0x01, 0x02, + 0x30, 0x0c, 0x01, 0x02, 0x34, 0x0c, 0x01, 0x02, 0x38, 0x0c, 0x01, 0x02, 0x3c, 0x0c, 0x01, 0x02, 0xd0, 0x24, 0x02, 0x03, 0xd8, 0x24, 0x02, 0x03, 0xe0, 0x24, 0x02, 0x03, 0xe8, 0x24, 0x02, 0x03, + 0x28, 0x03, 0x03, 0x03, 0x30, 0x03, 0x03, 0x03, 0x38, 0x03, 0x03, 0x03, 0x30, 0x19, 0x04, 0x04, 0x40, 0x19, 0x04, 0x04, 0xe0, 0x37, 0x05, 0x05, 0x80, 0x0e, 0x06, 0x05, 0x00, 0x29, 0x07, 0x06, + 0x00, 0x0c, 0x0b, 0x08, 0x90, 0x1d, 0x00, 0x03, 0x98, 0x1d, 0x00, 0x03, 0xa0, 0x1d, 0x00, 0x03, 0xa8, 0x1d, 0x00, 0x03, 0x40, 0x0c, 0x01, 0x02, 0x44, 0x0c, 0x01, 0x02, 0x48, 0x0c, 0x01, 0x02, + 0x4c, 0x0c, 0x01, 0x02, 0x50, 0x0c, 0x01, 0x02, 0x54, 0x0c, 0x01, 0x02, 0x58, 0x0c, 0x01, 0x02, 0xf0, 0x24, 0x02, 0x03, 0xf8, 0x24, 0x02, 0x03, 0x00, 0x25, 0x02, 0x03, 0x08, 0x25, 0x02, 0x03, + 0x40, 0x03, 0x03, 0x03, 0x48, 0x03, 0x03, 0x03, 0x50, 0x03, 0x03, 0x03, 0x50, 0x19, 0x04, 0x04, 0x60, 0x19, 0x04, 0x04, 0x00, 0x38, 0x05, 0x05, 0xa0, 0x0e, 0x06, 0x05, 0x40, 0x29, 0x07, 0x06, + 0x00, 0x0d, 0x0b, 0x08, 0xb0, 0x1d, 0x00, 0x03, 0xb8, 0x1d, 0x00, 0x03, 0xc0, 0x1d, 0x00, 0x03, 0xc8, 0x1d, 0x00, 0x03, 0x5c, 0x0c, 0x01, 0x02, 0x60, 0x0c, 0x01, 0x02, 0x64, 0x0c, 0x01, 0x02, + 0x68, 0x0c, 0x01, 0x02, 0x6c, 0x0c, 0x01, 0x02, 0x70, 0x0c, 0x01, 0x02, 0x74, 0x0c, 0x01, 0x02, 0x10, 0x25, 0x02, 0x03, 0x18, 0x25, 0x02, 0x03, 0x20, 0x25, 0x02, 0x03, 0x28, 0x25, 0x02, 0x03, + 0x58, 0x03, 0x03, 0x03, 0x60, 0x03, 0x03, 0x03, 0x68, 0x03, 0x03, 0x03, 0x70, 0x19, 0x04, 0x04, 0x80, 0x19, 0x04, 0x04, 0x20, 0x38, 0x05, 0x05, 0xc0, 0x0e, 0x06, 0x05, 0x80, 0x29, 0x07, 0x06, + 0x00, 0x0e, 0x0b, 0x08, 0xd0, 0x1d, 0x00, 0x03, 0xd8, 0x1d, 0x00, 0x03, 0xe0, 0x1d, 0x00, 0x03, 0xe8, 0x1d, 0x00, 0x03, 0x78, 0x0c, 0x01, 0x02, 0x7c, 0x0c, 0x01, 0x02, 0x80, 0x0c, 0x01, 0x02, + 0x84, 0x0c, 0x01, 0x02, 0x88, 0x0c, 0x01, 0x02, 0x8c, 0x0c, 0x01, 0x02, 0x90, 0x0c, 0x01, 0x02, 0x30, 0x25, 0x02, 0x03, 0x38, 0x25, 0x02, 0x03, 0x40, 0x25, 0x02, 0x03, 0x48, 0x25, 0x02, 0x03, + 0x70, 0x03, 0x03, 0x03, 0x78, 0x03, 0x03, 0x03, 0x80, 0x03, 0x03, 0x03, 0x90, 0x19, 0x04, 0x04, 0xa0, 0x19, 0x04, 0x04, 0x40, 0x38, 0x05, 0x05, 0xe0, 0x0e, 0x06, 0x05, 0xc0, 0x29, 0x07, 0x06, + 0x00, 0x0f, 0x0b, 0x08, 0xf0, 0x1d, 0x00, 0x03, 0xf8, 0x1d, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x03, 0x08, 0x1e, 0x00, 0x03, 0x94, 0x0c, 0x01, 0x02, 0x98, 0x0c, 0x01, 0x02, 0x9c, 0x0c, 0x01, 0x02, + 0xa0, 0x0c, 0x01, 0x02, 0xa4, 0x0c, 0x01, 0x02, 0xa8, 0x0c, 0x01, 0x02, 0xac, 0x0c, 0x01, 0x02, 0x50, 0x25, 0x02, 0x03, 0x58, 0x25, 0x02, 0x03, 0x60, 0x25, 0x02, 0x03, 0x68, 0x25, 0x02, 0x03, + 0x88, 0x03, 0x03, 0x03, 0x90, 0x03, 0x03, 0x03, 0x98, 0x03, 0x03, 0x03, 0xb0, 0x19, 0x04, 0x04, 0xc0, 0x19, 0x04, 0x04, 0x60, 0x38, 0x05, 0x05, 0x00, 0x0f, 0x06, 0x05, 0x00, 0x2a, 0x07, 0x06, + 0x00, 0x10, 0x0b, 0x08, 0x10, 0x1e, 0x00, 0x03, 0x18, 0x1e, 0x00, 0x03, 0x20, 0x1e, 0x00, 0x03, 0x28, 0x1e, 0x00, 0x03, 0xb0, 0x0c, 0x01, 0x02, 0xb4, 0x0c, 0x01, 0x02, 0xb8, 0x0c, 0x01, 0x02, + 0xbc, 0x0c, 0x01, 0x02, 0xc0, 0x0c, 0x01, 0x02, 0xc4, 0x0c, 0x01, 0x02, 0xc8, 0x0c, 0x01, 0x02, 0x70, 0x25, 0x02, 0x03, 0x78, 0x25, 0x02, 0x03, 0x80, 0x25, 0x02, 0x03, 0x88, 0x25, 0x02, 0x03, + 0xa0, 0x03, 0x03, 0x03, 0xa8, 0x03, 0x03, 0x03, 0xb0, 0x03, 0x03, 0x03, 0xd0, 0x19, 0x04, 0x04, 0xe0, 0x19, 0x04, 0x04, 0x80, 0x38, 0x05, 0x05, 0x20, 0x0f, 0x06, 0x05, 0x40, 0x2a, 0x07, 0x06, + 0x00, 0x11, 0x0b, 0x08, 0x30, 0x1e, 0x00, 0x03, 0x38, 0x1e, 0x00, 0x03, 0x40, 0x1e, 0x00, 0x03, 0x48, 0x1e, 0x00, 0x03, 0xcc, 0x0c, 0x01, 0x02, 0xd0, 0x0c, 0x01, 0x02, 0xd4, 0x0c, 0x01, 0x02, + 0xd8, 0x0c, 0x01, 0x02, 0xdc, 0x0c, 0x01, 0x02, 0xe0, 0x0c, 0x01, 0x02, 0xe4, 0x0c, 0x01, 0x02, 0x90, 0x25, 0x02, 0x03, 0x98, 0x25, 0x02, 0x03, 0xa0, 0x25, 0x02, 0x03, 0xa8, 0x25, 0x02, 0x03, + 0xb8, 0x03, 0x03, 0x03, 0xc0, 0x03, 0x03, 0x03, 0xc8, 0x03, 0x03, 0x03, 0xf0, 0x19, 0x04, 0x04, 0x00, 0x1a, 0x04, 0x04, 0xa0, 0x38, 0x05, 0x05, 0x40, 0x0f, 0x06, 0x05, 0x80, 0x2a, 0x07, 0x06, + 0x00, 0x12, 0x0b, 0x08, 0x50, 0x1e, 0x00, 0x03, 0x58, 0x1e, 0x00, 0x03, 0x60, 0x1e, 0x00, 0x03, 0x68, 0x1e, 0x00, 0x03, 0xe8, 0x0c, 0x01, 0x02, 0xec, 0x0c, 0x01, 0x02, 0xf0, 0x0c, 0x01, 0x02, + 0xf4, 0x0c, 0x01, 0x02, 0xf8, 0x0c, 0x01, 0x02, 0xfc, 0x0c, 0x01, 0x02, 0x00, 0x0d, 0x01, 0x02, 0xb0, 0x25, 0x02, 0x03, 0xb8, 0x25, 0x02, 0x03, 0xc0, 0x25, 0x02, 0x03, 0xc8, 0x25, 0x02, 0x03, + 0xd0, 0x03, 0x03, 0x03, 0xd8, 0x03, 0x03, 0x03, 0xe0, 0x03, 0x03, 0x03, 0x10, 0x1a, 0x04, 0x04, 0x20, 0x1a, 0x04, 0x04, 0xc0, 0x38, 0x05, 0x05, 0x60, 0x0f, 0x06, 0x05, 0xc0, 0x2a, 0x07, 0x06, + 0x00, 0x13, 0x0b, 0x08, 0x70, 0x1e, 0x00, 0x03, 0x78, 0x1e, 0x00, 0x03, 0x80, 0x1e, 0x00, 0x03, 0x88, 0x1e, 0x00, 0x03, 0x04, 0x0d, 0x01, 0x02, 0x08, 0x0d, 0x01, 0x02, 0x0c, 0x0d, 0x01, 0x02, + 0x10, 0x0d, 0x01, 0x02, 0x14, 0x0d, 0x01, 0x02, 0x18, 0x0d, 0x01, 0x02, 0xd0, 0x25, 0x02, 0x03, 0xd8, 0x25, 0x02, 0x03, 0xe0, 0x25, 0x02, 0x03, 0xe8, 0x25, 0x02, 0x03, 0xf0, 0x25, 0x02, 0x03, + 0xe8, 0x03, 0x03, 0x03, 0xf0, 0x03, 0x03, 0x03, 0xf8, 0x03, 0x03, 0x03, 0x30, 0x1a, 0x04, 0x04, 0x40, 0x1a, 0x04, 0x04, 0xe0, 0x38, 0x05, 0x05, 0x80, 0x0f, 0x06, 0x05, 0x00, 0x2b, 0x07, 0x06, + 0x00, 0x14, 0x0b, 0x08, 0x90, 0x1e, 0x00, 0x03, 0x98, 0x1e, 0x00, 0x03, 0xa0, 0x1e, 0x00, 0x03, 0xa8, 0x1e, 0x00, 0x03, 0x1c, 0x0d, 0x01, 0x02, 0x20, 0x0d, 0x01, 0x02, 0x24, 0x0d, 0x01, 0x02, + 0x28, 0x0d, 0x01, 0x02, 0x2c, 0x0d, 0x01, 0x02, 0x30, 0x0d, 0x01, 0x02, 0xf8, 0x25, 0x02, 0x03, 0x00, 0x26, 0x02, 0x03, 0x08, 0x26, 0x02, 0x03, 0x10, 0x26, 0x02, 0x03, 0x18, 0x26, 0x02, 0x03, + 0x00, 0x04, 0x03, 0x03, 0x08, 0x04, 0x03, 0x03, 0x10, 0x04, 0x03, 0x03, 0x50, 0x1a, 0x04, 0x04, 0x60, 0x1a, 0x04, 0x04, 0x00, 0x39, 0x05, 0x05, 0xa0, 0x0f, 0x06, 0x05, 0x40, 0x2b, 0x07, 0x06, + 0x00, 0x24, 0x0c, 0x09, 0xb0, 0x1e, 0x00, 0x03, 0xb8, 0x1e, 0x00, 0x03, 0xc0, 0x1e, 0x00, 0x03, 0xc8, 0x1e, 0x00, 0x03, 0x34, 0x0d, 0x01, 0x02, 0x38, 0x0d, 0x01, 0x02, 0x3c, 0x0d, 0x01, 0x02, + 0x40, 0x0d, 0x01, 0x02, 0x44, 0x0d, 0x01, 0x02, 0x48, 0x0d, 0x01, 0x02, 0x20, 0x26, 0x02, 0x03, 0x28, 0x26, 0x02, 0x03, 0x30, 0x26, 0x02, 0x03, 0x38, 0x26, 0x02, 0x03, 0x40, 0x26, 0x02, 0x03, + 0x18, 0x04, 0x03, 0x03, 0x20, 0x04, 0x03, 0x03, 0x28, 0x04, 0x03, 0x03, 0x70, 0x1a, 0x04, 0x04, 0x80, 0x1a, 0x04, 0x04, 0x20, 0x39, 0x05, 0x05, 0xc0, 0x0f, 0x06, 0x05, 0x80, 0x2b, 0x07, 0x06, + 0x00, 0x26, 0x0c, 0x09, 0xd0, 0x1e, 0x00, 0x03, 0xd8, 0x1e, 0x00, 0x03, 0xe0, 0x1e, 0x00, 0x03, 0xe8, 0x1e, 0x00, 0x03, 0x4c, 0x0d, 0x01, 0x02, 0x50, 0x0d, 0x01, 0x02, 0x54, 0x0d, 0x01, 0x02, + 0x58, 0x0d, 0x01, 0x02, 0x5c, 0x0d, 0x01, 0x02, 0x60, 0x0d, 0x01, 0x02, 0x48, 0x26, 0x02, 0x03, 0x50, 0x26, 0x02, 0x03, 0x58, 0x26, 0x02, 0x03, 0x60, 0x26, 0x02, 0x03, 0x68, 0x26, 0x02, 0x03, + 0x30, 0x04, 0x03, 0x03, 0x38, 0x04, 0x03, 0x03, 0x40, 0x04, 0x03, 0x03, 0x90, 0x1a, 0x04, 0x04, 0xa0, 0x1a, 0x04, 0x04, 0x40, 0x39, 0x05, 0x05, 0xe0, 0x0f, 0x06, 0x05, 0xc0, 0x2b, 0x07, 0x06, + 0x00, 0x28, 0x0c, 0x09, 0xf0, 0x1e, 0x00, 0x03, 0xf8, 0x1e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x03, 0x08, 0x1f, 0x00, 0x03, 0x64, 0x0d, 0x01, 0x02, 0x68, 0x0d, 0x01, 0x02, 0x6c, 0x0d, 0x01, 0x02, + 0x70, 0x0d, 0x01, 0x02, 0x74, 0x0d, 0x01, 0x02, 0x78, 0x0d, 0x01, 0x02, 0x70, 0x26, 0x02, 0x03, 0x78, 0x26, 0x02, 0x03, 0x80, 0x26, 0x02, 0x03, 0x88, 0x26, 0x02, 0x03, 0x90, 0x26, 0x02, 0x03, + 0x48, 0x04, 0x03, 0x03, 0x50, 0x04, 0x03, 0x03, 0x58, 0x04, 0x03, 0x03, 0xb0, 0x1a, 0x04, 0x04, 0xc0, 0x1a, 0x04, 0x04, 0x60, 0x39, 0x05, 0x05, 0x00, 0x10, 0x06, 0x05, 0x00, 0x2c, 0x07, 0x06, + 0x00, 0x2a, 0x0c, 0x09, 0x10, 0x1f, 0x00, 0x03, 0x18, 0x1f, 0x00, 0x03, 0x20, 0x1f, 0x00, 0x03, 0x28, 0x1f, 0x00, 0x03, 0x7c, 0x0d, 0x01, 0x02, 0x80, 0x0d, 0x01, 0x02, 0x84, 0x0d, 0x01, 0x02, + 0x88, 0x0d, 0x01, 0x02, 0x8c, 0x0d, 0x01, 0x02, 0x90, 0x0d, 0x01, 0x02, 0x98, 0x26, 0x02, 0x03, 0xa0, 0x26, 0x02, 0x03, 0xa8, 0x26, 0x02, 0x03, 0xb0, 0x26, 0x02, 0x03, 0xb8, 0x26, 0x02, 0x03, + 0x60, 0x04, 0x03, 0x03, 0x68, 0x04, 0x03, 0x03, 0x70, 0x04, 0x03, 0x03, 0xd0, 0x1a, 0x04, 0x04, 0xe0, 0x1a, 0x04, 0x04, 0x80, 0x39, 0x05, 0x05, 0x20, 0x10, 0x06, 0x05, 0x40, 0x2c, 0x07, 0x06, + 0x00, 0x2c, 0x0c, 0x09, 0x30, 0x1f, 0x00, 0x03, 0x38, 0x1f, 0x00, 0x03, 0x40, 0x1f, 0x00, 0x03, 0x48, 0x1f, 0x00, 0x03, 0x94, 0x0d, 0x01, 0x02, 0x98, 0x0d, 0x01, 0x02, 0x9c, 0x0d, 0x01, 0x02, + 0xa0, 0x0d, 0x01, 0x02, 0xa4, 0x0d, 0x01, 0x02, 0xa8, 0x0d, 0x01, 0x02, 0xc0, 0x26, 0x02, 0x03, 0xc8, 0x26, 0x02, 0x03, 0xd0, 0x26, 0x02, 0x03, 0xd8, 0x26, 0x02, 0x03, 0xe0, 0x26, 0x02, 0x03, + 0x78, 0x04, 0x03, 0x03, 0x80, 0x04, 0x03, 0x03, 0x88, 0x04, 0x03, 0x03, 0xf0, 0x1a, 0x04, 0x04, 0x00, 0x1b, 0x04, 0x04, 0xa0, 0x39, 0x05, 0x05, 0x40, 0x10, 0x06, 0x05, 0x80, 0x2c, 0x07, 0x06, + 0x00, 0x2e, 0x0c, 0x09, 0x50, 0x1f, 0x00, 0x03, 0x58, 0x1f, 0x00, 0x03, 0x60, 0x1f, 0x00, 0x03, 0x68, 0x1f, 0x00, 0x03, 0xac, 0x0d, 0x01, 0x02, 0xb0, 0x0d, 0x01, 0x02, 0xb4, 0x0d, 0x01, 0x02, + 0xb8, 0x0d, 0x01, 0x02, 0xbc, 0x0d, 0x01, 0x02, 0xc0, 0x0d, 0x01, 0x02, 0xe8, 0x26, 0x02, 0x03, 0xf0, 0x26, 0x02, 0x03, 0xf8, 0x26, 0x02, 0x03, 0x00, 0x27, 0x02, 0x03, 0x08, 0x27, 0x02, 0x03, + 0x90, 0x04, 0x03, 0x03, 0x98, 0x04, 0x03, 0x03, 0xa0, 0x04, 0x03, 0x03, 0x10, 0x1b, 0x04, 0x04, 0x20, 0x1b, 0x04, 0x04, 0xc0, 0x39, 0x05, 0x05, 0x60, 0x10, 0x06, 0x05, 0xc0, 0x2c, 0x07, 0x06, + 0x00, 0x30, 0x0c, 0x09, 0x70, 0x1f, 0x00, 0x03, 0x78, 0x1f, 0x00, 0x03, 0x80, 0x1f, 0x00, 0x03, 0x88, 0x1f, 0x00, 0x03, 0xc4, 0x0d, 0x01, 0x02, 0xc8, 0x0d, 0x01, 0x02, 0xcc, 0x0d, 0x01, 0x02, + 0xd0, 0x0d, 0x01, 0x02, 0xd4, 0x0d, 0x01, 0x02, 0xd8, 0x0d, 0x01, 0x02, 0x10, 0x27, 0x02, 0x03, 0x18, 0x27, 0x02, 0x03, 0x20, 0x27, 0x02, 0x03, 0x28, 0x27, 0x02, 0x03, 0x30, 0x27, 0x02, 0x03, + 0xa8, 0x04, 0x03, 0x03, 0xb0, 0x04, 0x03, 0x03, 0xb8, 0x04, 0x03, 0x03, 0x30, 0x1b, 0x04, 0x04, 0x40, 0x1b, 0x04, 0x04, 0xe0, 0x39, 0x05, 0x05, 0x80, 0x10, 0x06, 0x05, 0x80, 0x05, 0x08, 0x06, + 0x00, 0x04, 0x0d, 0x09, 0x90, 0x1f, 0x00, 0x03, 0x98, 0x1f, 0x00, 0x03, 0xa0, 0x1f, 0x00, 0x03, 0xa8, 0x1f, 0x00, 0x03, 0xdc, 0x0d, 0x01, 0x02, 0xe0, 0x0d, 0x01, 0x02, 0xe4, 0x0d, 0x01, 0x02, + 0xe8, 0x0d, 0x01, 0x02, 0xec, 0x0d, 0x01, 0x02, 0xf0, 0x0d, 0x01, 0x02, 0x38, 0x27, 0x02, 0x03, 0x40, 0x27, 0x02, 0x03, 0x48, 0x27, 0x02, 0x03, 0x50, 0x27, 0x02, 0x03, 0x58, 0x27, 0x02, 0x03, + 0xc0, 0x04, 0x03, 0x03, 0xc8, 0x04, 0x03, 0x03, 0xd0, 0x04, 0x03, 0x03, 0x50, 0x1b, 0x04, 0x04, 0x60, 0x1b, 0x04, 0x04, 0x00, 0x3a, 0x05, 0x05, 0xa0, 0x10, 0x06, 0x05, 0xc0, 0x05, 0x08, 0x06, + 0x00, 0x06, 0x0d, 0x09, 0xb0, 0x1f, 0x00, 0x03, 0xb8, 0x1f, 0x00, 0x03, 0xc0, 0x1f, 0x00, 0x03, 0xc8, 0x1f, 0x00, 0x03, 0xf4, 0x0d, 0x01, 0x02, 0xf8, 0x0d, 0x01, 0x02, 0xfc, 0x0d, 0x01, 0x02, + 0x00, 0x0e, 0x01, 0x02, 0x04, 0x0e, 0x01, 0x02, 0x08, 0x0e, 0x01, 0x02, 0x60, 0x27, 0x02, 0x03, 0x68, 0x27, 0x02, 0x03, 0x70, 0x27, 0x02, 0x03, 0x78, 0x27, 0x02, 0x03, 0x80, 0x27, 0x02, 0x03, + 0xd8, 0x04, 0x03, 0x03, 0xe0, 0x04, 0x03, 0x03, 0xe8, 0x04, 0x03, 0x03, 0x70, 0x1b, 0x04, 0x04, 0x80, 0x1b, 0x04, 0x04, 0x20, 0x3a, 0x05, 0x05, 0xc0, 0x10, 0x06, 0x05, 0x00, 0x06, 0x08, 0x06, + 0x00, 0x08, 0x0d, 0x09, 0xd0, 0x1f, 0x00, 0x03, 0xd8, 0x1f, 0x00, 0x03, 0xe0, 0x1f, 0x00, 0x03, 0xe8, 0x1f, 0x00, 0x03, 0x0c, 0x0e, 0x01, 0x02, 0x10, 0x0e, 0x01, 0x02, 0x14, 0x0e, 0x01, 0x02, + 0x18, 0x0e, 0x01, 0x02, 0x1c, 0x0e, 0x01, 0x02, 0x20, 0x0e, 0x01, 0x02, 0x88, 0x27, 0x02, 0x03, 0x90, 0x27, 0x02, 0x03, 0x98, 0x27, 0x02, 0x03, 0xa0, 0x27, 0x02, 0x03, 0xa8, 0x27, 0x02, 0x03, + 0xf0, 0x04, 0x03, 0x03, 0xf8, 0x04, 0x03, 0x03, 0x00, 0x05, 0x03, 0x03, 0x90, 0x1b, 0x04, 0x04, 0xa0, 0x1b, 0x04, 0x04, 0x40, 0x3a, 0x05, 0x05, 0xe0, 0x10, 0x06, 0x05, 0x40, 0x06, 0x08, 0x06, + 0x00, 0x0a, 0x0d, 0x09, 0xf0, 0x1f, 0x00, 0x03, 0xf8, 0x1f, 0x00, 0x03, 0x00, 0x20, 0x00, 0x03, 0x08, 0x20, 0x00, 0x03, 0x24, 0x0e, 0x01, 0x02, 0x28, 0x0e, 0x01, 0x02, 0x2c, 0x0e, 0x01, 0x02, + 0x30, 0x0e, 0x01, 0x02, 0x34, 0x0e, 0x01, 0x02, 0x38, 0x0e, 0x01, 0x02, 0xb0, 0x27, 0x02, 0x03, 0xb8, 0x27, 0x02, 0x03, 0xc0, 0x27, 0x02, 0x03, 0xc8, 0x27, 0x02, 0x03, 0xd0, 0x27, 0x02, 0x03, + 0x08, 0x05, 0x03, 0x03, 0x10, 0x05, 0x03, 0x03, 0x18, 0x05, 0x03, 0x03, 0xb0, 0x1b, 0x04, 0x04, 0xc0, 0x1b, 0x04, 0x04, 0x60, 0x3a, 0x05, 0x05, 0x00, 0x11, 0x06, 0x05, 0x80, 0x06, 0x08, 0x06, + 0x00, 0x18, 0x0e, 0x0a, 0x10, 0x20, 0x00, 0x03, 0x18, 0x20, 0x00, 0x03, 0x20, 0x20, 0x00, 0x03, 0x28, 0x20, 0x00, 0x03, 0x3c, 0x0e, 0x01, 0x02, 0x40, 0x0e, 0x01, 0x02, 0x44, 0x0e, 0x01, 0x02, + 0x48, 0x0e, 0x01, 0x02, 0x4c, 0x0e, 0x01, 0x02, 0x50, 0x0e, 0x01, 0x02, 0xd8, 0x27, 0x02, 0x03, 0xe0, 0x27, 0x02, 0x03, 0xe8, 0x27, 0x02, 0x03, 0xf0, 0x27, 0x02, 0x03, 0xf8, 0x27, 0x02, 0x03, + 0x20, 0x05, 0x03, 0x03, 0x28, 0x05, 0x03, 0x03, 0x30, 0x05, 0x03, 0x03, 0xd0, 0x1b, 0x04, 0x04, 0xe0, 0x1b, 0x04, 0x04, 0x80, 0x3a, 0x05, 0x05, 0x20, 0x11, 0x06, 0x05, 0xc0, 0x06, 0x08, 0x06, + 0x00, 0x1c, 0x0e, 0x0a, 0x30, 0x20, 0x00, 0x03, 0x38, 0x20, 0x00, 0x03, 0x40, 0x20, 0x00, 0x03, 0x48, 0x20, 0x00, 0x03, 0x54, 0x0e, 0x01, 0x02, 0x58, 0x0e, 0x01, 0x02, 0x5c, 0x0e, 0x01, 0x02, + 0x60, 0x0e, 0x01, 0x02, 0x64, 0x0e, 0x01, 0x02, 0x68, 0x0e, 0x01, 0x02, 0x00, 0x28, 0x02, 0x03, 0x08, 0x28, 0x02, 0x03, 0x10, 0x28, 0x02, 0x03, 0x18, 0x28, 0x02, 0x03, 0x20, 0x28, 0x02, 0x03, + 0x38, 0x05, 0x03, 0x03, 0x40, 0x05, 0x03, 0x03, 0x48, 0x05, 0x03, 0x03, 0xf0, 0x1b, 0x04, 0x04, 0x00, 0x1c, 0x04, 0x04, 0xa0, 0x3a, 0x05, 0x05, 0x40, 0x11, 0x06, 0x05, 0x00, 0x07, 0x08, 0x06, + 0x00, 0x20, 0x0e, 0x0a, 0x50, 0x20, 0x00, 0x03, 0x58, 0x20, 0x00, 0x03, 0x60, 0x20, 0x00, 0x03, 0x68, 0x20, 0x00, 0x03, 0x6c, 0x0e, 0x01, 0x02, 0x70, 0x0e, 0x01, 0x02, 0x74, 0x0e, 0x01, 0x02, + 0x78, 0x0e, 0x01, 0x02, 0x7c, 0x0e, 0x01, 0x02, 0x80, 0x0e, 0x01, 0x02, 0x28, 0x28, 0x02, 0x03, 0x30, 0x28, 0x02, 0x03, 0x38, 0x28, 0x02, 0x03, 0x40, 0x28, 0x02, 0x03, 0x48, 0x28, 0x02, 0x03, + 0x50, 0x05, 0x03, 0x03, 0x58, 0x05, 0x03, 0x03, 0x60, 0x05, 0x03, 0x03, 0x10, 0x1c, 0x04, 0x04, 0x20, 0x1c, 0x04, 0x04, 0xc0, 0x3a, 0x05, 0x05, 0x60, 0x11, 0x06, 0x05, 0x40, 0x07, 0x08, 0x06, + 0x00, 0x38, 0x0f, 0x0b, 0x70, 0x20, 0x00, 0x03, 0x78, 0x20, 0x00, 0x03, 0x80, 0x20, 0x00, 0x03, 0x88, 0x20, 0x00, 0x03, 0x84, 0x0e, 0x01, 0x02, 0x88, 0x0e, 0x01, 0x02, 0x8c, 0x0e, 0x01, 0x02, + 0x90, 0x0e, 0x01, 0x02, 0x94, 0x0e, 0x01, 0x02, 0x98, 0x0e, 0x01, 0x02, 0x50, 0x28, 0x02, 0x03, 0x58, 0x28, 0x02, 0x03, 0x60, 0x28, 0x02, 0x03, 0x68, 0x28, 0x02, 0x03, 0x70, 0x28, 0x02, 0x03, + 0x68, 0x05, 0x03, 0x03, 0x70, 0x05, 0x03, 0x03, 0x78, 0x05, 0x03, 0x03, 0x30, 0x1c, 0x04, 0x04, 0x40, 0x1c, 0x04, 0x04, 0xe0, 0x3a, 0x05, 0x05, 0x80, 0x11, 0x06, 0x05, 0x80, 0x07, 0x08, 0x06, + 0x00, 0x00, 0x0f, 0x0a, 0x90, 0x20, 0x00, 0x03, 0x98, 0x20, 0x00, 0x03, 0xa0, 0x20, 0x00, 0x03, 0xa8, 0x20, 0x00, 0x03, 0x9c, 0x0e, 0x01, 0x02, 0xa0, 0x0e, 0x01, 0x02, 0xa4, 0x0e, 0x01, 0x02, + 0xa8, 0x0e, 0x01, 0x02, 0xac, 0x0e, 0x01, 0x02, 0xb0, 0x0e, 0x01, 0x02, 0x78, 0x28, 0x02, 0x03, 0x80, 0x28, 0x02, 0x03, 0x88, 0x28, 0x02, 0x03, 0x90, 0x28, 0x02, 0x03, 0x98, 0x28, 0x02, 0x03, + 0x80, 0x05, 0x03, 0x03, 0x88, 0x05, 0x03, 0x03, 0x90, 0x05, 0x03, 0x03, 0x50, 0x1c, 0x04, 0x04, 0x60, 0x1c, 0x04, 0x04, 0x00, 0x3b, 0x05, 0x05, 0xa0, 0x11, 0x06, 0x05, 0xc0, 0x07, 0x08, 0x06, + 0x00, 0x10, 0x10, 0x0b, 0xb0, 0x20, 0x00, 0x03, 0xb8, 0x20, 0x00, 0x03, 0xc0, 0x20, 0x00, 0x03, 0xc8, 0x20, 0x00, 0x03, 0xb4, 0x0e, 0x01, 0x02, 0xb8, 0x0e, 0x01, 0x02, 0xbc, 0x0e, 0x01, 0x02, + 0xc0, 0x0e, 0x01, 0x02, 0xc4, 0x0e, 0x01, 0x02, 0xc8, 0x0e, 0x01, 0x02, 0xa0, 0x28, 0x02, 0x03, 0xa8, 0x28, 0x02, 0x03, 0xb0, 0x28, 0x02, 0x03, 0xb8, 0x28, 0x02, 0x03, 0xc0, 0x28, 0x02, 0x03, + 0x98, 0x05, 0x03, 0x03, 0xa0, 0x05, 0x03, 0x03, 0xa8, 0x05, 0x03, 0x03, 0x70, 0x1c, 0x04, 0x04, 0x80, 0x1c, 0x04, 0x04, 0x20, 0x3b, 0x05, 0x05, 0xc0, 0x11, 0x06, 0x05, 0x00, 0x08, 0x08, 0x06, + 0x00, 0x18, 0x10, 0x0b, 0xd0, 0x20, 0x00, 0x03, 0xd8, 0x20, 0x00, 0x03, 0xe0, 0x20, 0x00, 0x03, 0xe8, 0x20, 0x00, 0x03, 0xcc, 0x0e, 0x01, 0x02, 0xd0, 0x0e, 0x01, 0x02, 0xd4, 0x0e, 0x01, 0x02, + 0xd8, 0x0e, 0x01, 0x02, 0xdc, 0x0e, 0x01, 0x02, 0xe0, 0x0e, 0x01, 0x02, 0xc8, 0x28, 0x02, 0x03, 0xd0, 0x28, 0x02, 0x03, 0xd8, 0x28, 0x02, 0x03, 0xe0, 0x28, 0x02, 0x03, 0xe8, 0x28, 0x02, 0x03, + 0xb0, 0x05, 0x03, 0x03, 0xb8, 0x05, 0x03, 0x03, 0xc0, 0x05, 0x03, 0x03, 0x90, 0x1c, 0x04, 0x04, 0xa0, 0x1c, 0x04, 0x04, 0x40, 0x3b, 0x05, 0x05, 0xe0, 0x11, 0x06, 0x05, 0x40, 0x08, 0x08, 0x06, + 0x00, 0x30, 0x11, 0x0c, 0xf0, 0x20, 0x00, 0x03, 0xf8, 0x20, 0x00, 0x03, 0x00, 0x21, 0x00, 0x03, 0x08, 0x21, 0x00, 0x03, 0xe4, 0x0e, 0x01, 0x02, 0xe8, 0x0e, 0x01, 0x02, 0xec, 0x0e, 0x01, 0x02, + 0xf0, 0x0e, 0x01, 0x02, 0xf4, 0x0e, 0x01, 0x02, 0xf8, 0x0e, 0x01, 0x02, 0xf0, 0x28, 0x02, 0x03, 0xf8, 0x28, 0x02, 0x03, 0x00, 0x29, 0x02, 0x03, 0x08, 0x29, 0x02, 0x03, 0x10, 0x29, 0x02, 0x03, + 0xc8, 0x05, 0x03, 0x03, 0xd0, 0x05, 0x03, 0x03, 0xd8, 0x05, 0x03, 0x03, 0xb0, 0x1c, 0x04, 0x04, 0xc0, 0x1c, 0x04, 0x04, 0x60, 0x3b, 0x05, 0x05, 0x00, 0x12, 0x06, 0x05, 0x80, 0x08, 0x08, 0x06, + 0x00, 0x20, 0x13, 0x0d, 0x10, 0x21, 0x00, 0x03, 0x18, 0x21, 0x00, 0x03, 0x20, 0x21, 0x00, 0x03, 0x28, 0x21, 0x00, 0x03, 0xfc, 0x0e, 0x01, 0x02, 0x00, 0x0f, 0x01, 0x02, 0x04, 0x0f, 0x01, 0x02, + 0x08, 0x0f, 0x01, 0x02, 0x0c, 0x0f, 0x01, 0x02, 0x10, 0x0f, 0x01, 0x02, 0x18, 0x29, 0x02, 0x03, 0x20, 0x29, 0x02, 0x03, 0x28, 0x29, 0x02, 0x03, 0x30, 0x29, 0x02, 0x03, 0x38, 0x29, 0x02, 0x03, + 0xe0, 0x05, 0x03, 0x03, 0xe8, 0x05, 0x03, 0x03, 0xf0, 0x05, 0x03, 0x03, 0xd0, 0x1c, 0x04, 0x04, 0xe0, 0x1c, 0x04, 0x04, 0x80, 0x3b, 0x05, 0x05, 0x20, 0x12, 0x06, 0x05, 0xc0, 0x08, 0x08, 0x06, + 0x30, 0x21, 0x00, 0x03, 0x38, 0x21, 0x00, 0x03, 0x40, 0x21, 0x00, 0x03, 0x48, 0x21, 0x00, 0x03, 0x50, 0x21, 0x00, 0x03, 0x14, 0x0f, 0x01, 0x02, 0x18, 0x0f, 0x01, 0x02, 0x1c, 0x0f, 0x01, 0x02, + 0x20, 0x0f, 0x01, 0x02, 0x24, 0x0f, 0x01, 0x02, 0x28, 0x0f, 0x01, 0x02, 0x40, 0x29, 0x02, 0x03, 0x48, 0x29, 0x02, 0x03, 0x50, 0x29, 0x02, 0x03, 0x58, 0x29, 0x02, 0x03, 0x60, 0x29, 0x02, 0x03, + 0xf8, 0x05, 0x03, 0x03, 0x00, 0x06, 0x03, 0x03, 0x08, 0x06, 0x03, 0x03, 0xf0, 0x1c, 0x04, 0x04, 0x00, 0x1d, 0x04, 0x04, 0xa0, 0x3b, 0x05, 0x05, 0x40, 0x12, 0x06, 0x05, 0x00, 0x09, 0x08, 0x06, + 0x58, 0x21, 0x00, 0x03, 0x60, 0x21, 0x00, 0x03, 0x68, 0x21, 0x00, 0x03, 0x70, 0x21, 0x00, 0x03, 0x78, 0x21, 0x00, 0x03, 0x2c, 0x0f, 0x01, 0x02, 0x30, 0x0f, 0x01, 0x02, 0x34, 0x0f, 0x01, 0x02, + 0x38, 0x0f, 0x01, 0x02, 0x3c, 0x0f, 0x01, 0x02, 0x40, 0x0f, 0x01, 0x02, 0x68, 0x29, 0x02, 0x03, 0x70, 0x29, 0x02, 0x03, 0x78, 0x29, 0x02, 0x03, 0x80, 0x29, 0x02, 0x03, 0x88, 0x29, 0x02, 0x03, + 0x10, 0x06, 0x03, 0x03, 0x18, 0x06, 0x03, 0x03, 0x20, 0x06, 0x03, 0x03, 0x10, 0x1d, 0x04, 0x04, 0x20, 0x1d, 0x04, 0x04, 0xc0, 0x3b, 0x05, 0x05, 0x60, 0x12, 0x06, 0x05, 0x40, 0x09, 0x08, 0x06, + 0x80, 0x21, 0x00, 0x03, 0x88, 0x21, 0x00, 0x03, 0x90, 0x21, 0x00, 0x03, 0x98, 0x21, 0x00, 0x03, 0xa0, 0x21, 0x00, 0x03, 0x44, 0x0f, 0x01, 0x02, 0x48, 0x0f, 0x01, 0x02, 0x4c, 0x0f, 0x01, 0x02, + 0x50, 0x0f, 0x01, 0x02, 0x54, 0x0f, 0x01, 0x02, 0x58, 0x0f, 0x01, 0x02, 0x90, 0x29, 0x02, 0x03, 0x98, 0x29, 0x02, 0x03, 0xa0, 0x29, 0x02, 0x03, 0xa8, 0x29, 0x02, 0x03, 0xb0, 0x29, 0x02, 0x03, + 0x28, 0x06, 0x03, 0x03, 0x30, 0x06, 0x03, 0x03, 0x38, 0x06, 0x03, 0x03, 0x30, 0x1d, 0x04, 0x04, 0x40, 0x1d, 0x04, 0x04, 0xe0, 0x3b, 0x05, 0x05, 0x80, 0x12, 0x06, 0x05, 0x80, 0x09, 0x08, 0x06, + 0xa8, 0x21, 0x00, 0x03, 0xb0, 0x21, 0x00, 0x03, 0xb8, 0x21, 0x00, 0x03, 0xc0, 0x21, 0x00, 0x03, 0xc8, 0x21, 0x00, 0x03, 0x5c, 0x0f, 0x01, 0x02, 0x60, 0x0f, 0x01, 0x02, 0x64, 0x0f, 0x01, 0x02, + 0x68, 0x0f, 0x01, 0x02, 0x6c, 0x0f, 0x01, 0x02, 0x70, 0x0f, 0x01, 0x02, 0xb8, 0x29, 0x02, 0x03, 0xc0, 0x29, 0x02, 0x03, 0xc8, 0x29, 0x02, 0x03, 0xd0, 0x29, 0x02, 0x03, 0xd8, 0x29, 0x02, 0x03, + 0x40, 0x06, 0x03, 0x03, 0x48, 0x06, 0x03, 0x03, 0x50, 0x06, 0x03, 0x03, 0x50, 0x1d, 0x04, 0x04, 0x60, 0x1d, 0x04, 0x04, 0x00, 0x3c, 0x05, 0x05, 0xa0, 0x12, 0x06, 0x05, 0xc0, 0x09, 0x08, 0x06, + 0xd0, 0x21, 0x00, 0x03, 0xd8, 0x21, 0x00, 0x03, 0xe0, 0x21, 0x00, 0x03, 0xe8, 0x21, 0x00, 0x03, 0xf0, 0x21, 0x00, 0x03, 0x74, 0x0f, 0x01, 0x02, 0x78, 0x0f, 0x01, 0x02, 0x7c, 0x0f, 0x01, 0x02, + 0x80, 0x0f, 0x01, 0x02, 0x84, 0x0f, 0x01, 0x02, 0x88, 0x0f, 0x01, 0x02, 0xe0, 0x29, 0x02, 0x03, 0xe8, 0x29, 0x02, 0x03, 0xf0, 0x29, 0x02, 0x03, 0xf8, 0x29, 0x02, 0x03, 0x00, 0x2a, 0x02, 0x03, + 0x58, 0x06, 0x03, 0x03, 0x60, 0x06, 0x03, 0x03, 0x68, 0x06, 0x03, 0x03, 0x70, 0x1d, 0x04, 0x04, 0x80, 0x1d, 0x04, 0x04, 0x20, 0x3c, 0x05, 0x05, 0xc0, 0x12, 0x06, 0x05, 0x00, 0x0a, 0x08, 0x06, + 0xf8, 0x21, 0x00, 0x03, 0x00, 0x22, 0x00, 0x03, 0x08, 0x22, 0x00, 0x03, 0x10, 0x22, 0x00, 0x03, 0x18, 0x22, 0x00, 0x03, 0x8c, 0x0f, 0x01, 0x02, 0x90, 0x0f, 0x01, 0x02, 0x94, 0x0f, 0x01, 0x02, + 0x98, 0x0f, 0x01, 0x02, 0x9c, 0x0f, 0x01, 0x02, 0xa0, 0x0f, 0x01, 0x02, 0x08, 0x2a, 0x02, 0x03, 0x10, 0x2a, 0x02, 0x03, 0x18, 0x2a, 0x02, 0x03, 0x20, 0x2a, 0x02, 0x03, 0x28, 0x2a, 0x02, 0x03, + 0x70, 0x06, 0x03, 0x03, 0x78, 0x06, 0x03, 0x03, 0x80, 0x06, 0x03, 0x03, 0x90, 0x1d, 0x04, 0x04, 0xa0, 0x1d, 0x04, 0x04, 0x40, 0x3c, 0x05, 0x05, 0xe0, 0x12, 0x06, 0x05, 0x40, 0x0a, 0x08, 0x06, + 0x20, 0x22, 0x00, 0x03, 0x28, 0x22, 0x00, 0x03, 0x30, 0x22, 0x00, 0x03, 0x38, 0x22, 0x00, 0x03, 0x40, 0x22, 0x00, 0x03, 0xa4, 0x0f, 0x01, 0x02, 0xa8, 0x0f, 0x01, 0x02, 0xac, 0x0f, 0x01, 0x02, + 0xb0, 0x0f, 0x01, 0x02, 0xb4, 0x0f, 0x01, 0x02, 0xb8, 0x0f, 0x01, 0x02, 0x30, 0x2a, 0x02, 0x03, 0x38, 0x2a, 0x02, 0x03, 0x40, 0x2a, 0x02, 0x03, 0x48, 0x2a, 0x02, 0x03, 0x50, 0x2a, 0x02, 0x03, + 0x88, 0x06, 0x03, 0x03, 0x90, 0x06, 0x03, 0x03, 0x98, 0x06, 0x03, 0x03, 0xb0, 0x1d, 0x04, 0x04, 0xc0, 0x1d, 0x04, 0x04, 0x60, 0x3c, 0x05, 0x05, 0x00, 0x13, 0x06, 0x05, 0x80, 0x0a, 0x08, 0x06, + 0x48, 0x22, 0x00, 0x03, 0x50, 0x22, 0x00, 0x03, 0x58, 0x22, 0x00, 0x03, 0x60, 0x22, 0x00, 0x03, 0x68, 0x22, 0x00, 0x03, 0xbc, 0x0f, 0x01, 0x02, 0xc0, 0x0f, 0x01, 0x02, 0xc4, 0x0f, 0x01, 0x02, + 0xc8, 0x0f, 0x01, 0x02, 0xcc, 0x0f, 0x01, 0x02, 0xd0, 0x0f, 0x01, 0x02, 0x58, 0x2a, 0x02, 0x03, 0x60, 0x2a, 0x02, 0x03, 0x68, 0x2a, 0x02, 0x03, 0x70, 0x2a, 0x02, 0x03, 0x78, 0x2a, 0x02, 0x03, + 0xa0, 0x06, 0x03, 0x03, 0xa8, 0x06, 0x03, 0x03, 0xb0, 0x06, 0x03, 0x03, 0xd0, 0x1d, 0x04, 0x04, 0xe0, 0x1d, 0x04, 0x04, 0x80, 0x3c, 0x05, 0x05, 0x20, 0x13, 0x06, 0x05, 0xc0, 0x0a, 0x08, 0x06, + 0x70, 0x22, 0x00, 0x03, 0x78, 0x22, 0x00, 0x03, 0x80, 0x22, 0x00, 0x03, 0x88, 0x22, 0x00, 0x03, 0xd4, 0x0f, 0x01, 0x02, 0xd8, 0x0f, 0x01, 0x02, 0xdc, 0x0f, 0x01, 0x02, 0xe0, 0x0f, 0x01, 0x02, + 0xe4, 0x0f, 0x01, 0x02, 0xe8, 0x0f, 0x01, 0x02, 0xec, 0x0f, 0x01, 0x02, 0x80, 0x2a, 0x02, 0x03, 0x88, 0x2a, 0x02, 0x03, 0x90, 0x2a, 0x02, 0x03, 0x98, 0x2a, 0x02, 0x03, 0xa0, 0x2a, 0x02, 0x03, + 0xb8, 0x06, 0x03, 0x03, 0xc0, 0x06, 0x03, 0x03, 0xc8, 0x06, 0x03, 0x03, 0xf0, 0x1d, 0x04, 0x04, 0x00, 0x1e, 0x04, 0x04, 0xa0, 0x3c, 0x05, 0x05, 0x40, 0x13, 0x06, 0x05, 0x00, 0x0b, 0x08, 0x06, + 0x90, 0x22, 0x00, 0x03, 0x98, 0x22, 0x00, 0x03, 0xa0, 0x22, 0x00, 0x03, 0xa8, 0x22, 0x00, 0x03, 0xf0, 0x0f, 0x01, 0x02, 0xf4, 0x0f, 0x01, 0x02, 0xf8, 0x0f, 0x01, 0x02, 0xfc, 0x0f, 0x01, 0x02, + 0x00, 0x10, 0x01, 0x02, 0x04, 0x10, 0x01, 0x02, 0x08, 0x10, 0x01, 0x02, 0xa8, 0x2a, 0x02, 0x03, 0xb0, 0x2a, 0x02, 0x03, 0xb8, 0x2a, 0x02, 0x03, 0xc0, 0x2a, 0x02, 0x03, 0xc8, 0x2a, 0x02, 0x03, + 0xd0, 0x06, 0x03, 0x03, 0xd8, 0x06, 0x03, 0x03, 0xe0, 0x06, 0x03, 0x03, 0x10, 0x1e, 0x04, 0x04, 0xc0, 0x3c, 0x05, 0x05, 0xe0, 0x3c, 0x05, 0x05, 0x60, 0x13, 0x06, 0x05, 0x40, 0x0b, 0x08, 0x06, + 0xb0, 0x22, 0x00, 0x03, 0xb8, 0x22, 0x00, 0x03, 0xc0, 0x22, 0x00, 0x03, 0xc8, 0x22, 0x00, 0x03, 0x0c, 0x10, 0x01, 0x02, 0x10, 0x10, 0x01, 0x02, 0x14, 0x10, 0x01, 0x02, 0x18, 0x10, 0x01, 0x02, + 0x1c, 0x10, 0x01, 0x02, 0x20, 0x10, 0x01, 0x02, 0x24, 0x10, 0x01, 0x02, 0xd0, 0x2a, 0x02, 0x03, 0xd8, 0x2a, 0x02, 0x03, 0xe0, 0x2a, 0x02, 0x03, 0xe8, 0x2a, 0x02, 0x03, 0xf0, 0x2a, 0x02, 0x03, + 0xe8, 0x06, 0x03, 0x03, 0xf0, 0x06, 0x03, 0x03, 0xf8, 0x06, 0x03, 0x03, 0x20, 0x1e, 0x04, 0x04, 0x00, 0x3d, 0x05, 0x05, 0x20, 0x3d, 0x05, 0x05, 0x80, 0x13, 0x06, 0x05, 0x80, 0x0b, 0x08, 0x06, + 0xd0, 0x22, 0x00, 0x03, 0xd8, 0x22, 0x00, 0x03, 0xe0, 0x22, 0x00, 0x03, 0xe8, 0x22, 0x00, 0x03, 0x28, 0x10, 0x01, 0x02, 0x2c, 0x10, 0x01, 0x02, 0x30, 0x10, 0x01, 0x02, 0x34, 0x10, 0x01, 0x02, + 0x38, 0x10, 0x01, 0x02, 0x3c, 0x10, 0x01, 0x02, 0x40, 0x10, 0x01, 0x02, 0xf8, 0x2a, 0x02, 0x03, 0x00, 0x2b, 0x02, 0x03, 0x08, 0x2b, 0x02, 0x03, 0x10, 0x2b, 0x02, 0x03, 0x18, 0x2b, 0x02, 0x03, + 0x00, 0x07, 0x03, 0x03, 0x08, 0x07, 0x03, 0x03, 0x10, 0x07, 0x03, 0x03, 0x30, 0x1e, 0x04, 0x04, 0x40, 0x3d, 0x05, 0x05, 0x60, 0x3d, 0x05, 0x05, 0xa0, 0x13, 0x06, 0x05, 0xc0, 0x0b, 0x08, 0x06, + 0xf0, 0x22, 0x00, 0x03, 0xf8, 0x22, 0x00, 0x03, 0x00, 0x23, 0x00, 0x03, 0x08, 0x23, 0x00, 0x03, 0x44, 0x10, 0x01, 0x02, 0x48, 0x10, 0x01, 0x02, 0x4c, 0x10, 0x01, 0x02, 0x50, 0x10, 0x01, 0x02, + 0x54, 0x10, 0x01, 0x02, 0x58, 0x10, 0x01, 0x02, 0x5c, 0x10, 0x01, 0x02, 0x20, 0x2b, 0x02, 0x03, 0x28, 0x2b, 0x02, 0x03, 0x30, 0x2b, 0x02, 0x03, 0x38, 0x2b, 0x02, 0x03, 0x40, 0x2b, 0x02, 0x03, + 0x18, 0x07, 0x03, 0x03, 0x20, 0x07, 0x03, 0x03, 0x40, 0x1e, 0x04, 0x04, 0x50, 0x1e, 0x04, 0x04, 0x80, 0x3d, 0x05, 0x05, 0xa0, 0x3d, 0x05, 0x05, 0xc0, 0x13, 0x06, 0x05, 0x00, 0x0c, 0x08, 0x06, + 0x10, 0x23, 0x00, 0x03, 0x18, 0x23, 0x00, 0x03, 0x20, 0x23, 0x00, 0x03, 0x28, 0x23, 0x00, 0x03, 0x60, 0x10, 0x01, 0x02, 0x64, 0x10, 0x01, 0x02, 0x68, 0x10, 0x01, 0x02, 0x6c, 0x10, 0x01, 0x02, + 0x70, 0x10, 0x01, 0x02, 0x74, 0x10, 0x01, 0x02, 0x78, 0x10, 0x01, 0x02, 0x48, 0x2b, 0x02, 0x03, 0x50, 0x2b, 0x02, 0x03, 0x58, 0x2b, 0x02, 0x03, 0x60, 0x2b, 0x02, 0x03, 0x68, 0x2b, 0x02, 0x03, + 0x28, 0x07, 0x03, 0x03, 0x30, 0x07, 0x03, 0x03, 0x60, 0x1e, 0x04, 0x04, 0x70, 0x1e, 0x04, 0x04, 0xc0, 0x3d, 0x05, 0x05, 0xe0, 0x3d, 0x05, 0x05, 0xe0, 0x13, 0x06, 0x05, 0x40, 0x0c, 0x08, 0x06, + 0x30, 0x23, 0x00, 0x03, 0x38, 0x23, 0x00, 0x03, 0x40, 0x23, 0x00, 0x03, 0x48, 0x23, 0x00, 0x03, 0x7c, 0x10, 0x01, 0x02, 0x80, 0x10, 0x01, 0x02, 0x84, 0x10, 0x01, 0x02, 0x88, 0x10, 0x01, 0x02, + 0x8c, 0x10, 0x01, 0x02, 0x90, 0x10, 0x01, 0x02, 0x94, 0x10, 0x01, 0x02, 0x70, 0x2b, 0x02, 0x03, 0x78, 0x2b, 0x02, 0x03, 0x80, 0x2b, 0x02, 0x03, 0x88, 0x2b, 0x02, 0x03, 0x90, 0x2b, 0x02, 0x03, + 0x38, 0x07, 0x03, 0x03, 0x40, 0x07, 0x03, 0x03, 0x80, 0x1e, 0x04, 0x04, 0x90, 0x1e, 0x04, 0x04, 0x00, 0x3e, 0x05, 0x05, 0x20, 0x3e, 0x05, 0x05, 0x00, 0x14, 0x06, 0x05, 0x80, 0x0c, 0x08, 0x06, + 0x50, 0x23, 0x00, 0x03, 0x58, 0x23, 0x00, 0x03, 0x60, 0x23, 0x00, 0x03, 0x68, 0x23, 0x00, 0x03, 0x98, 0x10, 0x01, 0x02, 0x9c, 0x10, 0x01, 0x02, 0xa0, 0x10, 0x01, 0x02, 0xa4, 0x10, 0x01, 0x02, + 0xa8, 0x10, 0x01, 0x02, 0xac, 0x10, 0x01, 0x02, 0xb0, 0x10, 0x01, 0x02, 0x98, 0x2b, 0x02, 0x03, 0xa0, 0x2b, 0x02, 0x03, 0xa8, 0x2b, 0x02, 0x03, 0xb0, 0x2b, 0x02, 0x03, 0xb8, 0x2b, 0x02, 0x03, + 0x48, 0x07, 0x03, 0x03, 0x50, 0x07, 0x03, 0x03, 0xa0, 0x1e, 0x04, 0x04, 0xb0, 0x1e, 0x04, 0x04, 0x40, 0x3e, 0x05, 0x05, 0x60, 0x3e, 0x05, 0x05, 0x20, 0x14, 0x06, 0x05, 0xc0, 0x0c, 0x08, 0x06, + 0x70, 0x23, 0x00, 0x03, 0x78, 0x23, 0x00, 0x03, 0x80, 0x23, 0x00, 0x03, 0x88, 0x23, 0x00, 0x03, 0xb4, 0x10, 0x01, 0x02, 0xb8, 0x10, 0x01, 0x02, 0xbc, 0x10, 0x01, 0x02, 0xc0, 0x10, 0x01, 0x02, + 0xc4, 0x10, 0x01, 0x02, 0xc8, 0x10, 0x01, 0x02, 0xcc, 0x10, 0x01, 0x02, 0xc0, 0x2b, 0x02, 0x03, 0xc8, 0x2b, 0x02, 0x03, 0xd0, 0x2b, 0x02, 0x03, 0xd8, 0x2b, 0x02, 0x03, 0x58, 0x07, 0x03, 0x03, + 0x60, 0x07, 0x03, 0x03, 0x68, 0x07, 0x03, 0x03, 0xc0, 0x1e, 0x04, 0x04, 0xd0, 0x1e, 0x04, 0x04, 0x80, 0x3e, 0x05, 0x05, 0xa0, 0x3e, 0x05, 0x05, 0x40, 0x14, 0x06, 0x05, 0x00, 0x0d, 0x08, 0x06, + 0x90, 0x23, 0x00, 0x03, 0x98, 0x23, 0x00, 0x03, 0xa0, 0x23, 0x00, 0x03, 0xa8, 0x23, 0x00, 0x03, 0xd0, 0x10, 0x01, 0x02, 0xd4, 0x10, 0x01, 0x02, 0xd8, 0x10, 0x01, 0x02, 0xdc, 0x10, 0x01, 0x02, + 0xe0, 0x10, 0x01, 0x02, 0xe4, 0x10, 0x01, 0x02, 0xe8, 0x10, 0x01, 0x02, 0xe0, 0x2b, 0x02, 0x03, 0xe8, 0x2b, 0x02, 0x03, 0xf0, 0x2b, 0x02, 0x03, 0xf8, 0x2b, 0x02, 0x03, 0x70, 0x07, 0x03, 0x03, + 0x78, 0x07, 0x03, 0x03, 0x80, 0x07, 0x03, 0x03, 0xe0, 0x1e, 0x04, 0x04, 0xf0, 0x1e, 0x04, 0x04, 0xc0, 0x3e, 0x05, 0x05, 0xe0, 0x3e, 0x05, 0x05, 0x60, 0x14, 0x06, 0x05, 0x40, 0x0d, 0x08, 0x06, + 0xb0, 0x23, 0x00, 0x03, 0xb8, 0x23, 0x00, 0x03, 0xc0, 0x23, 0x00, 0x03, 0xc8, 0x23, 0x00, 0x03, 0xec, 0x10, 0x01, 0x02, 0xf0, 0x10, 0x01, 0x02, 0xf4, 0x10, 0x01, 0x02, 0xf8, 0x10, 0x01, 0x02, + 0xfc, 0x10, 0x01, 0x02, 0x00, 0x11, 0x01, 0x02, 0x04, 0x11, 0x01, 0x02, 0x00, 0x2c, 0x02, 0x03, 0x08, 0x2c, 0x02, 0x03, 0x10, 0x2c, 0x02, 0x03, 0x18, 0x2c, 0x02, 0x03, 0x88, 0x07, 0x03, 0x03, + 0x90, 0x07, 0x03, 0x03, 0x98, 0x07, 0x03, 0x03, 0x00, 0x1f, 0x04, 0x04, 0x10, 0x1f, 0x04, 0x04, 0x00, 0x3f, 0x05, 0x05, 0x20, 0x3f, 0x05, 0x05, 0x80, 0x14, 0x06, 0x05, 0x80, 0x0d, 0x08, 0x06, + 0xd0, 0x23, 0x00, 0x03, 0xd8, 0x23, 0x00, 0x03, 0xe0, 0x23, 0x00, 0x03, 0xe8, 0x23, 0x00, 0x03, 0x08, 0x11, 0x01, 0x02, 0x0c, 0x11, 0x01, 0x02, 0x10, 0x11, 0x01, 0x02, 0x14, 0x11, 0x01, 0x02, + 0x18, 0x11, 0x01, 0x02, 0x1c, 0x11, 0x01, 0x02, 0x20, 0x11, 0x01, 0x02, 0x20, 0x2c, 0x02, 0x03, 0x28, 0x2c, 0x02, 0x03, 0x30, 0x2c, 0x02, 0x03, 0x38, 0x2c, 0x02, 0x03, 0xa0, 0x07, 0x03, 0x03, + 0xa8, 0x07, 0x03, 0x03, 0xb0, 0x07, 0x03, 0x03, 0x20, 0x1f, 0x04, 0x04, 0x30, 0x1f, 0x04, 0x04, 0x40, 0x3f, 0x05, 0x05, 0x60, 0x3f, 0x05, 0x05, 0xa0, 0x14, 0x06, 0x05, 0xc0, 0x0d, 0x08, 0x06, + 0xf0, 0x23, 0x00, 0x03, 0xf8, 0x23, 0x00, 0x03, 0x00, 0x24, 0x00, 0x03, 0x08, 0x24, 0x00, 0x03, 0x24, 0x11, 0x01, 0x02, 0x28, 0x11, 0x01, 0x02, 0x2c, 0x11, 0x01, 0x02, 0x30, 0x11, 0x01, 0x02, + 0x34, 0x11, 0x01, 0x02, 0x38, 0x11, 0x01, 0x02, 0x3c, 0x11, 0x01, 0x02, 0x40, 0x2c, 0x02, 0x03, 0x48, 0x2c, 0x02, 0x03, 0x50, 0x2c, 0x02, 0x03, 0x58, 0x2c, 0x02, 0x03, 0xb8, 0x07, 0x03, 0x03, + 0xc0, 0x07, 0x03, 0x03, 0xc8, 0x07, 0x03, 0x03, 0x40, 0x1f, 0x04, 0x04, 0x50, 0x1f, 0x04, 0x04, 0x80, 0x3f, 0x05, 0x05, 0xa0, 0x3f, 0x05, 0x05, 0xc0, 0x14, 0x06, 0x05, 0x80, 0x20, 0x09, 0x07, + 0x10, 0x24, 0x00, 0x03, 0x18, 0x24, 0x00, 0x03, 0x20, 0x24, 0x00, 0x03, 0x28, 0x24, 0x00, 0x03, 0x40, 0x11, 0x01, 0x02, 0x44, 0x11, 0x01, 0x02, 0x48, 0x11, 0x01, 0x02, 0x4c, 0x11, 0x01, 0x02, + 0x50, 0x11, 0x01, 0x02, 0x54, 0x11, 0x01, 0x02, 0x58, 0x11, 0x01, 0x02, 0x60, 0x2c, 0x02, 0x03, 0x68, 0x2c, 0x02, 0x03, 0x70, 0x2c, 0x02, 0x03, 0x78, 0x2c, 0x02, 0x03, 0xd0, 0x07, 0x03, 0x03, + 0xd8, 0x07, 0x03, 0x03, 0xe0, 0x07, 0x03, 0x03, 0x60, 0x1f, 0x04, 0x04, 0x70, 0x1f, 0x04, 0x04, 0xc0, 0x3f, 0x05, 0x05, 0xe0, 0x3f, 0x05, 0x05, 0xe0, 0x14, 0x06, 0x05, 0x00, 0x21, 0x09, 0x07, + 0x30, 0x24, 0x00, 0x03, 0x38, 0x24, 0x00, 0x03, 0x40, 0x24, 0x00, 0x03, 0x48, 0x24, 0x00, 0x03, 0x5c, 0x11, 0x01, 0x02, 0x60, 0x11, 0x01, 0x02, 0x64, 0x11, 0x01, 0x02, 0x68, 0x11, 0x01, 0x02, + 0x6c, 0x11, 0x01, 0x02, 0x70, 0x11, 0x01, 0x02, 0x74, 0x11, 0x01, 0x02, 0x80, 0x2c, 0x02, 0x03, 0x88, 0x2c, 0x02, 0x03, 0x90, 0x2c, 0x02, 0x03, 0x98, 0x2c, 0x02, 0x03, 0xe8, 0x07, 0x03, 0x03, + 0xf0, 0x07, 0x03, 0x03, 0xf8, 0x07, 0x03, 0x03, 0x80, 0x1f, 0x04, 0x04, 0x90, 0x1f, 0x04, 0x04, 0x00, 0x00, 0x05, 0x04, 0x10, 0x00, 0x05, 0x04, 0x00, 0x15, 0x06, 0x05, 0x80, 0x21, 0x09, 0x07, + 0x50, 0x24, 0x00, 0x03, 0x58, 0x24, 0x00, 0x03, 0x60, 0x24, 0x00, 0x03, 0x68, 0x24, 0x00, 0x03, 0x78, 0x11, 0x01, 0x02, 0x7c, 0x11, 0x01, 0x02, 0x80, 0x11, 0x01, 0x02, 0x84, 0x11, 0x01, 0x02, + 0x88, 0x11, 0x01, 0x02, 0x8c, 0x11, 0x01, 0x02, 0x90, 0x11, 0x01, 0x02, 0xa0, 0x2c, 0x02, 0x03, 0xa8, 0x2c, 0x02, 0x03, 0xb0, 0x2c, 0x02, 0x03, 0xb8, 0x2c, 0x02, 0x03, 0x00, 0x08, 0x03, 0x03, + 0x08, 0x08, 0x03, 0x03, 0x10, 0x08, 0x03, 0x03, 0xa0, 0x1f, 0x04, 0x04, 0xb0, 0x1f, 0x04, 0x04, 0x20, 0x00, 0x05, 0x04, 0x30, 0x00, 0x05, 0x04, 0x00, 0x2d, 0x07, 0x06, 0x00, 0x22, 0x09, 0x07, + 0x70, 0x24, 0x00, 0x03, 0x78, 0x24, 0x00, 0x03, 0x80, 0x24, 0x00, 0x03, 0x88, 0x24, 0x00, 0x03, 0x94, 0x11, 0x01, 0x02, 0x98, 0x11, 0x01, 0x02, 0x9c, 0x11, 0x01, 0x02, 0xa0, 0x11, 0x01, 0x02, + 0xa4, 0x11, 0x01, 0x02, 0xa8, 0x11, 0x01, 0x02, 0xac, 0x11, 0x01, 0x02, 0xc0, 0x2c, 0x02, 0x03, 0xc8, 0x2c, 0x02, 0x03, 0xd0, 0x2c, 0x02, 0x03, 0xd8, 0x2c, 0x02, 0x03, 0x18, 0x08, 0x03, 0x03, + 0x20, 0x08, 0x03, 0x03, 0x28, 0x08, 0x03, 0x03, 0xc0, 0x1f, 0x04, 0x04, 0xd0, 0x1f, 0x04, 0x04, 0x40, 0x00, 0x05, 0x04, 0x50, 0x00, 0x05, 0x04, 0x40, 0x2d, 0x07, 0x06, 0x80, 0x22, 0x09, 0x07, + 0x90, 0x24, 0x00, 0x03, 0x98, 0x24, 0x00, 0x03, 0xa0, 0x24, 0x00, 0x03, 0xa8, 0x24, 0x00, 0x03, 0xb0, 0x11, 0x01, 0x02, 0xb4, 0x11, 0x01, 0x02, 0xb8, 0x11, 0x01, 0x02, 0xbc, 0x11, 0x01, 0x02, + 0xc0, 0x11, 0x01, 0x02, 0xc4, 0x11, 0x01, 0x02, 0xc8, 0x11, 0x01, 0x02, 0xe0, 0x2c, 0x02, 0x03, 0xe8, 0x2c, 0x02, 0x03, 0xf0, 0x2c, 0x02, 0x03, 0xf8, 0x2c, 0x02, 0x03, 0x30, 0x08, 0x03, 0x03, + 0x38, 0x08, 0x03, 0x03, 0x40, 0x08, 0x03, 0x03, 0xe0, 0x1f, 0x04, 0x04, 0xf0, 0x1f, 0x04, 0x04, 0x60, 0x00, 0x05, 0x04, 0x70, 0x00, 0x05, 0x04, 0x80, 0x2d, 0x07, 0x06, 0x00, 0x23, 0x09, 0x07, + 0xb0, 0x24, 0x00, 0x03, 0xb8, 0x24, 0x00, 0x03, 0xc0, 0x24, 0x00, 0x03, 0xc8, 0x24, 0x00, 0x03, 0xcc, 0x11, 0x01, 0x02, 0xd0, 0x11, 0x01, 0x02, 0xd4, 0x11, 0x01, 0x02, 0xd8, 0x11, 0x01, 0x02, + 0xdc, 0x11, 0x01, 0x02, 0xe0, 0x11, 0x01, 0x02, 0xe4, 0x11, 0x01, 0x02, 0x00, 0x2d, 0x02, 0x03, 0x08, 0x2d, 0x02, 0x03, 0x10, 0x2d, 0x02, 0x03, 0x18, 0x2d, 0x02, 0x03, 0x48, 0x08, 0x03, 0x03, + 0x50, 0x08, 0x03, 0x03, 0x58, 0x08, 0x03, 0x03, 0x00, 0x20, 0x04, 0x04, 0x10, 0x20, 0x04, 0x04, 0x80, 0x00, 0x05, 0x04, 0x90, 0x00, 0x05, 0x04, 0xc0, 0x2d, 0x07, 0x06, 0x80, 0x23, 0x09, 0x07, + 0xd0, 0x24, 0x00, 0x03, 0xd8, 0x24, 0x00, 0x03, 0xe0, 0x24, 0x00, 0x03, 0xe8, 0x24, 0x00, 0x03, 0xe8, 0x11, 0x01, 0x02, 0xec, 0x11, 0x01, 0x02, 0xf0, 0x11, 0x01, 0x02, 0xf4, 0x11, 0x01, 0x02, + 0xf8, 0x11, 0x01, 0x02, 0xfc, 0x11, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x20, 0x2d, 0x02, 0x03, 0x28, 0x2d, 0x02, 0x03, 0x30, 0x2d, 0x02, 0x03, 0x38, 0x2d, 0x02, 0x03, 0x60, 0x08, 0x03, 0x03, + 0x68, 0x08, 0x03, 0x03, 0x70, 0x08, 0x03, 0x03, 0x20, 0x20, 0x04, 0x04, 0x30, 0x20, 0x04, 0x04, 0xa0, 0x00, 0x05, 0x04, 0xb0, 0x00, 0x05, 0x04, 0x00, 0x2e, 0x07, 0x06, 0x00, 0x24, 0x09, 0x07, + 0xf0, 0x24, 0x00, 0x03, 0xf8, 0x24, 0x00, 0x03, 0x00, 0x25, 0x00, 0x03, 0x08, 0x25, 0x00, 0x03, 0x04, 0x12, 0x01, 0x02, 0x08, 0x12, 0x01, 0x02, 0x0c, 0x12, 0x01, 0x02, 0x10, 0x12, 0x01, 0x02, + 0x14, 0x12, 0x01, 0x02, 0x18, 0x12, 0x01, 0x02, 0x1c, 0x12, 0x01, 0x02, 0x40, 0x2d, 0x02, 0x03, 0x48, 0x2d, 0x02, 0x03, 0x50, 0x2d, 0x02, 0x03, 0x58, 0x2d, 0x02, 0x03, 0x78, 0x08, 0x03, 0x03, + 0x80, 0x08, 0x03, 0x03, 0x88, 0x08, 0x03, 0x03, 0x40, 0x20, 0x04, 0x04, 0x50, 0x20, 0x04, 0x04, 0xc0, 0x00, 0x05, 0x04, 0xd0, 0x00, 0x05, 0x04, 0x40, 0x2e, 0x07, 0x06, 0x80, 0x24, 0x09, 0x07, + 0x10, 0x25, 0x00, 0x03, 0x18, 0x25, 0x00, 0x03, 0x20, 0x25, 0x00, 0x03, 0x28, 0x25, 0x00, 0x03, 0x20, 0x12, 0x01, 0x02, 0x24, 0x12, 0x01, 0x02, 0x28, 0x12, 0x01, 0x02, 0x2c, 0x12, 0x01, 0x02, + 0x30, 0x12, 0x01, 0x02, 0x34, 0x12, 0x01, 0x02, 0x38, 0x12, 0x01, 0x02, 0x60, 0x2d, 0x02, 0x03, 0x68, 0x2d, 0x02, 0x03, 0x70, 0x2d, 0x02, 0x03, 0x78, 0x2d, 0x02, 0x03, 0x90, 0x08, 0x03, 0x03, + 0x98, 0x08, 0x03, 0x03, 0xa0, 0x08, 0x03, 0x03, 0x60, 0x20, 0x04, 0x04, 0x70, 0x20, 0x04, 0x04, 0xe0, 0x00, 0x05, 0x04, 0xf0, 0x00, 0x05, 0x04, 0x80, 0x2e, 0x07, 0x06, 0x00, 0x25, 0x09, 0x07, + 0x30, 0x25, 0x00, 0x03, 0x38, 0x25, 0x00, 0x03, 0x40, 0x25, 0x00, 0x03, 0x48, 0x25, 0x00, 0x03, 0x3c, 0x12, 0x01, 0x02, 0x40, 0x12, 0x01, 0x02, 0x44, 0x12, 0x01, 0x02, 0x48, 0x12, 0x01, 0x02, + 0x4c, 0x12, 0x01, 0x02, 0x50, 0x12, 0x01, 0x02, 0x54, 0x12, 0x01, 0x02, 0x80, 0x2d, 0x02, 0x03, 0x88, 0x2d, 0x02, 0x03, 0x90, 0x2d, 0x02, 0x03, 0x98, 0x2d, 0x02, 0x03, 0xa8, 0x08, 0x03, 0x03, + 0xb0, 0x08, 0x03, 0x03, 0xb8, 0x08, 0x03, 0x03, 0x80, 0x20, 0x04, 0x04, 0x90, 0x20, 0x04, 0x04, 0x00, 0x01, 0x05, 0x04, 0x10, 0x01, 0x05, 0x04, 0xc0, 0x2e, 0x07, 0x06, 0x80, 0x25, 0x09, 0x07, + 0x50, 0x25, 0x00, 0x03, 0x58, 0x25, 0x00, 0x03, 0x60, 0x25, 0x00, 0x03, 0x68, 0x25, 0x00, 0x03, 0x58, 0x12, 0x01, 0x02, 0x5c, 0x12, 0x01, 0x02, 0x60, 0x12, 0x01, 0x02, 0x64, 0x12, 0x01, 0x02, + 0x68, 0x12, 0x01, 0x02, 0x6c, 0x12, 0x01, 0x02, 0x70, 0x12, 0x01, 0x02, 0xa0, 0x2d, 0x02, 0x03, 0xa8, 0x2d, 0x02, 0x03, 0xb0, 0x2d, 0x02, 0x03, 0xb8, 0x2d, 0x02, 0x03, 0xc0, 0x08, 0x03, 0x03, + 0xc8, 0x08, 0x03, 0x03, 0xd0, 0x08, 0x03, 0x03, 0xa0, 0x20, 0x04, 0x04, 0xb0, 0x20, 0x04, 0x04, 0x20, 0x01, 0x05, 0x04, 0x30, 0x01, 0x05, 0x04, 0x00, 0x2f, 0x07, 0x06, 0x00, 0x26, 0x09, 0x07, + 0x70, 0x25, 0x00, 0x03, 0x78, 0x25, 0x00, 0x03, 0x80, 0x25, 0x00, 0x03, 0x88, 0x25, 0x00, 0x03, 0x74, 0x12, 0x01, 0x02, 0x78, 0x12, 0x01, 0x02, 0x7c, 0x12, 0x01, 0x02, 0x80, 0x12, 0x01, 0x02, + 0x84, 0x12, 0x01, 0x02, 0x88, 0x12, 0x01, 0x02, 0x8c, 0x12, 0x01, 0x02, 0xc0, 0x2d, 0x02, 0x03, 0xc8, 0x2d, 0x02, 0x03, 0xd0, 0x2d, 0x02, 0x03, 0xd8, 0x2d, 0x02, 0x03, 0xd8, 0x08, 0x03, 0x03, + 0xe0, 0x08, 0x03, 0x03, 0xe8, 0x08, 0x03, 0x03, 0xc0, 0x20, 0x04, 0x04, 0xd0, 0x20, 0x04, 0x04, 0x40, 0x01, 0x05, 0x04, 0x50, 0x01, 0x05, 0x04, 0x40, 0x2f, 0x07, 0x06, 0x80, 0x26, 0x09, 0x07, + 0x90, 0x25, 0x00, 0x03, 0x98, 0x25, 0x00, 0x03, 0xa0, 0x25, 0x00, 0x03, 0xa8, 0x25, 0x00, 0x03, 0x90, 0x12, 0x01, 0x02, 0x94, 0x12, 0x01, 0x02, 0x98, 0x12, 0x01, 0x02, 0x9c, 0x12, 0x01, 0x02, + 0xa0, 0x12, 0x01, 0x02, 0xa4, 0x12, 0x01, 0x02, 0xa8, 0x12, 0x01, 0x02, 0xe0, 0x2d, 0x02, 0x03, 0xe8, 0x2d, 0x02, 0x03, 0xf0, 0x2d, 0x02, 0x03, 0xf8, 0x2d, 0x02, 0x03, 0xf0, 0x08, 0x03, 0x03, + 0xf8, 0x08, 0x03, 0x03, 0x00, 0x09, 0x03, 0x03, 0xe0, 0x20, 0x04, 0x04, 0xf0, 0x20, 0x04, 0x04, 0x60, 0x01, 0x05, 0x04, 0x70, 0x01, 0x05, 0x04, 0x80, 0x2f, 0x07, 0x06, 0x00, 0x27, 0x09, 0x07, + 0xb0, 0x25, 0x00, 0x03, 0xb8, 0x25, 0x00, 0x03, 0xc0, 0x25, 0x00, 0x03, 0xc8, 0x25, 0x00, 0x03, 0xac, 0x12, 0x01, 0x02, 0xb0, 0x12, 0x01, 0x02, 0xb4, 0x12, 0x01, 0x02, 0xb8, 0x12, 0x01, 0x02, + 0xbc, 0x12, 0x01, 0x02, 0xc0, 0x12, 0x01, 0x02, 0xc4, 0x12, 0x01, 0x02, 0x00, 0x2e, 0x02, 0x03, 0x08, 0x2e, 0x02, 0x03, 0x10, 0x2e, 0x02, 0x03, 0x18, 0x2e, 0x02, 0x03, 0x08, 0x09, 0x03, 0x03, + 0x10, 0x09, 0x03, 0x03, 0x18, 0x09, 0x03, 0x03, 0x00, 0x21, 0x04, 0x04, 0x10, 0x21, 0x04, 0x04, 0x80, 0x01, 0x05, 0x04, 0x20, 0x15, 0x06, 0x05, 0xc0, 0x2f, 0x07, 0x06, 0x80, 0x27, 0x09, 0x07, + 0xd0, 0x25, 0x00, 0x03, 0xd8, 0x25, 0x00, 0x03, 0xe0, 0x25, 0x00, 0x03, 0xe8, 0x25, 0x00, 0x03, 0xc8, 0x12, 0x01, 0x02, 0xcc, 0x12, 0x01, 0x02, 0xd0, 0x12, 0x01, 0x02, 0xd4, 0x12, 0x01, 0x02, + 0xd8, 0x12, 0x01, 0x02, 0xdc, 0x12, 0x01, 0x02, 0xe0, 0x12, 0x01, 0x02, 0x20, 0x2e, 0x02, 0x03, 0x28, 0x2e, 0x02, 0x03, 0x30, 0x2e, 0x02, 0x03, 0x38, 0x2e, 0x02, 0x03, 0x20, 0x09, 0x03, 0x03, + 0x28, 0x09, 0x03, 0x03, 0x30, 0x09, 0x03, 0x03, 0x20, 0x21, 0x04, 0x04, 0x30, 0x21, 0x04, 0x04, 0x90, 0x01, 0x05, 0x04, 0x40, 0x15, 0x06, 0x05, 0x00, 0x30, 0x07, 0x06, 0x00, 0x28, 0x09, 0x07, + 0xf0, 0x25, 0x00, 0x03, 0xf8, 0x25, 0x00, 0x03, 0x00, 0x26, 0x00, 0x03, 0x08, 0x26, 0x00, 0x03, 0xe4, 0x12, 0x01, 0x02, 0xe8, 0x12, 0x01, 0x02, 0xec, 0x12, 0x01, 0x02, 0xf0, 0x12, 0x01, 0x02, + 0xf4, 0x12, 0x01, 0x02, 0xf8, 0x12, 0x01, 0x02, 0xfc, 0x12, 0x01, 0x02, 0x40, 0x2e, 0x02, 0x03, 0x48, 0x2e, 0x02, 0x03, 0x50, 0x2e, 0x02, 0x03, 0x58, 0x2e, 0x02, 0x03, 0x38, 0x09, 0x03, 0x03, + 0x40, 0x09, 0x03, 0x03, 0x48, 0x09, 0x03, 0x03, 0x40, 0x21, 0x04, 0x04, 0x50, 0x21, 0x04, 0x04, 0xa0, 0x01, 0x05, 0x04, 0x60, 0x15, 0x06, 0x05, 0x40, 0x30, 0x07, 0x06, 0x80, 0x28, 0x09, 0x07, + 0x10, 0x26, 0x00, 0x03, 0x18, 0x26, 0x00, 0x03, 0x20, 0x26, 0x00, 0x03, 0x28, 0x26, 0x00, 0x03, 0x00, 0x13, 0x01, 0x02, 0x04, 0x13, 0x01, 0x02, 0x08, 0x13, 0x01, 0x02, 0x0c, 0x13, 0x01, 0x02, + 0x10, 0x13, 0x01, 0x02, 0x14, 0x13, 0x01, 0x02, 0x18, 0x13, 0x01, 0x02, 0x60, 0x2e, 0x02, 0x03, 0x68, 0x2e, 0x02, 0x03, 0x70, 0x2e, 0x02, 0x03, 0x78, 0x2e, 0x02, 0x03, 0x50, 0x09, 0x03, 0x03, + 0x58, 0x09, 0x03, 0x03, 0x60, 0x09, 0x03, 0x03, 0x60, 0x21, 0x04, 0x04, 0x70, 0x21, 0x04, 0x04, 0xb0, 0x01, 0x05, 0x04, 0x80, 0x15, 0x06, 0x05, 0x80, 0x30, 0x07, 0x06, 0x00, 0x29, 0x09, 0x07, + 0x30, 0x26, 0x00, 0x03, 0x38, 0x26, 0x00, 0x03, 0x40, 0x26, 0x00, 0x03, 0x48, 0x26, 0x00, 0x03, 0x1c, 0x13, 0x01, 0x02, 0x20, 0x13, 0x01, 0x02, 0x24, 0x13, 0x01, 0x02, 0x28, 0x13, 0x01, 0x02, + 0x2c, 0x13, 0x01, 0x02, 0x30, 0x13, 0x01, 0x02, 0x34, 0x13, 0x01, 0x02, 0x80, 0x2e, 0x02, 0x03, 0x88, 0x2e, 0x02, 0x03, 0x90, 0x2e, 0x02, 0x03, 0x98, 0x2e, 0x02, 0x03, 0x68, 0x09, 0x03, 0x03, + 0x70, 0x09, 0x03, 0x03, 0x78, 0x09, 0x03, 0x03, 0x80, 0x21, 0x04, 0x04, 0x90, 0x21, 0x04, 0x04, 0xc0, 0x01, 0x05, 0x04, 0xa0, 0x15, 0x06, 0x05, 0xc0, 0x30, 0x07, 0x06, 0x80, 0x29, 0x09, 0x07, + 0x50, 0x26, 0x00, 0x03, 0x58, 0x26, 0x00, 0x03, 0x60, 0x26, 0x00, 0x03, 0x68, 0x26, 0x00, 0x03, 0x38, 0x13, 0x01, 0x02, 0x3c, 0x13, 0x01, 0x02, 0x40, 0x13, 0x01, 0x02, 0x44, 0x13, 0x01, 0x02, + 0x48, 0x13, 0x01, 0x02, 0x4c, 0x13, 0x01, 0x02, 0x50, 0x13, 0x01, 0x02, 0xa0, 0x2e, 0x02, 0x03, 0xa8, 0x2e, 0x02, 0x03, 0xb0, 0x2e, 0x02, 0x03, 0xb8, 0x2e, 0x02, 0x03, 0x80, 0x09, 0x03, 0x03, + 0x88, 0x09, 0x03, 0x03, 0x90, 0x09, 0x03, 0x03, 0xa0, 0x21, 0x04, 0x04, 0xb0, 0x21, 0x04, 0x04, 0xd0, 0x01, 0x05, 0x04, 0xc0, 0x15, 0x06, 0x05, 0x00, 0x31, 0x07, 0x06, 0x00, 0x2a, 0x09, 0x07, + 0x70, 0x26, 0x00, 0x03, 0x78, 0x26, 0x00, 0x03, 0x80, 0x26, 0x00, 0x03, 0x88, 0x26, 0x00, 0x03, 0x54, 0x13, 0x01, 0x02, 0x58, 0x13, 0x01, 0x02, 0x5c, 0x13, 0x01, 0x02, 0x60, 0x13, 0x01, 0x02, + 0x64, 0x13, 0x01, 0x02, 0x68, 0x13, 0x01, 0x02, 0x6c, 0x13, 0x01, 0x02, 0xc0, 0x2e, 0x02, 0x03, 0xc8, 0x2e, 0x02, 0x03, 0xd0, 0x2e, 0x02, 0x03, 0xd8, 0x2e, 0x02, 0x03, 0x98, 0x09, 0x03, 0x03, + 0xa0, 0x09, 0x03, 0x03, 0xa8, 0x09, 0x03, 0x03, 0xc0, 0x21, 0x04, 0x04, 0xd0, 0x21, 0x04, 0x04, 0xe0, 0x01, 0x05, 0x04, 0xe0, 0x15, 0x06, 0x05, 0x40, 0x31, 0x07, 0x06, 0x80, 0x2a, 0x09, 0x07, + 0x90, 0x26, 0x00, 0x03, 0x98, 0x26, 0x00, 0x03, 0xa0, 0x26, 0x00, 0x03, 0xa8, 0x26, 0x00, 0x03, 0x70, 0x13, 0x01, 0x02, 0x74, 0x13, 0x01, 0x02, 0x78, 0x13, 0x01, 0x02, 0x7c, 0x13, 0x01, 0x02, + 0x80, 0x13, 0x01, 0x02, 0x84, 0x13, 0x01, 0x02, 0x88, 0x13, 0x01, 0x02, 0xe0, 0x2e, 0x02, 0x03, 0xe8, 0x2e, 0x02, 0x03, 0xf0, 0x2e, 0x02, 0x03, 0xf8, 0x2e, 0x02, 0x03, 0xb0, 0x09, 0x03, 0x03, + 0xb8, 0x09, 0x03, 0x03, 0xc0, 0x09, 0x03, 0x03, 0xe0, 0x21, 0x04, 0x04, 0xf0, 0x21, 0x04, 0x04, 0xf0, 0x01, 0x05, 0x04, 0x00, 0x16, 0x06, 0x05, 0x80, 0x31, 0x07, 0x06, 0x00, 0x00, 0x0a, 0x07, + 0xb0, 0x26, 0x00, 0x03, 0xb8, 0x26, 0x00, 0x03, 0xc0, 0x26, 0x00, 0x03, 0xc8, 0x26, 0x00, 0x03, 0x8c, 0x13, 0x01, 0x02, 0x90, 0x13, 0x01, 0x02, 0x94, 0x13, 0x01, 0x02, 0x98, 0x13, 0x01, 0x02, + 0x9c, 0x13, 0x01, 0x02, 0xa0, 0x13, 0x01, 0x02, 0xa4, 0x13, 0x01, 0x02, 0x00, 0x2f, 0x02, 0x03, 0x08, 0x2f, 0x02, 0x03, 0x10, 0x2f, 0x02, 0x03, 0x18, 0x2f, 0x02, 0x03, 0xc8, 0x09, 0x03, 0x03, + 0xd0, 0x09, 0x03, 0x03, 0xd8, 0x09, 0x03, 0x03, 0x00, 0x22, 0x04, 0x04, 0x10, 0x22, 0x04, 0x04, 0x00, 0x02, 0x05, 0x04, 0x20, 0x16, 0x06, 0x05, 0xc0, 0x31, 0x07, 0x06, 0x80, 0x00, 0x0a, 0x07, + 0xd0, 0x26, 0x00, 0x03, 0xd8, 0x26, 0x00, 0x03, 0xe0, 0x26, 0x00, 0x03, 0xe8, 0x26, 0x00, 0x03, 0xa8, 0x13, 0x01, 0x02, 0xac, 0x13, 0x01, 0x02, 0xb0, 0x13, 0x01, 0x02, 0xb4, 0x13, 0x01, 0x02, + 0xb8, 0x13, 0x01, 0x02, 0xbc, 0x13, 0x01, 0x02, 0xc0, 0x13, 0x01, 0x02, 0x20, 0x2f, 0x02, 0x03, 0x28, 0x2f, 0x02, 0x03, 0x30, 0x2f, 0x02, 0x03, 0x38, 0x2f, 0x02, 0x03, 0xe0, 0x09, 0x03, 0x03, + 0xe8, 0x09, 0x03, 0x03, 0xf0, 0x09, 0x03, 0x03, 0x20, 0x22, 0x04, 0x04, 0x30, 0x22, 0x04, 0x04, 0x10, 0x02, 0x05, 0x04, 0x40, 0x16, 0x06, 0x05, 0x00, 0x32, 0x07, 0x06, 0x00, 0x01, 0x0a, 0x07, + 0xf0, 0x26, 0x00, 0x03, 0xf8, 0x26, 0x00, 0x03, 0x00, 0x27, 0x00, 0x03, 0x08, 0x27, 0x00, 0x03, 0xc4, 0x13, 0x01, 0x02, 0xc8, 0x13, 0x01, 0x02, 0xcc, 0x13, 0x01, 0x02, 0xd0, 0x13, 0x01, 0x02, + 0xd4, 0x13, 0x01, 0x02, 0xd8, 0x13, 0x01, 0x02, 0xdc, 0x13, 0x01, 0x02, 0x40, 0x2f, 0x02, 0x03, 0x48, 0x2f, 0x02, 0x03, 0x50, 0x2f, 0x02, 0x03, 0x58, 0x2f, 0x02, 0x03, 0xf8, 0x09, 0x03, 0x03, + 0x00, 0x0a, 0x03, 0x03, 0x08, 0x0a, 0x03, 0x03, 0x40, 0x22, 0x04, 0x04, 0x50, 0x22, 0x04, 0x04, 0x20, 0x02, 0x05, 0x04, 0x60, 0x16, 0x06, 0x05, 0x40, 0x32, 0x07, 0x06, 0x80, 0x01, 0x0a, 0x07, + 0x10, 0x27, 0x00, 0x03, 0x18, 0x27, 0x00, 0x03, 0x20, 0x27, 0x00, 0x03, 0x28, 0x27, 0x00, 0x03, 0xe0, 0x13, 0x01, 0x02, 0xe4, 0x13, 0x01, 0x02, 0xe8, 0x13, 0x01, 0x02, 0xec, 0x13, 0x01, 0x02, + 0xf0, 0x13, 0x01, 0x02, 0xf4, 0x13, 0x01, 0x02, 0xf8, 0x13, 0x01, 0x02, 0x60, 0x2f, 0x02, 0x03, 0x68, 0x2f, 0x02, 0x03, 0x70, 0x2f, 0x02, 0x03, 0x78, 0x2f, 0x02, 0x03, 0x10, 0x0a, 0x03, 0x03, + 0x18, 0x0a, 0x03, 0x03, 0x20, 0x0a, 0x03, 0x03, 0x60, 0x22, 0x04, 0x04, 0x70, 0x22, 0x04, 0x04, 0x30, 0x02, 0x05, 0x04, 0x80, 0x16, 0x06, 0x05, 0x80, 0x32, 0x07, 0x06, 0x00, 0x02, 0x0a, 0x07, + 0x30, 0x27, 0x00, 0x03, 0x38, 0x27, 0x00, 0x03, 0x40, 0x27, 0x00, 0x03, 0x48, 0x27, 0x00, 0x03, 0xfc, 0x13, 0x01, 0x02, 0x00, 0x14, 0x01, 0x02, 0x04, 0x14, 0x01, 0x02, 0x08, 0x14, 0x01, 0x02, + 0x0c, 0x14, 0x01, 0x02, 0x10, 0x14, 0x01, 0x02, 0x14, 0x14, 0x01, 0x02, 0x80, 0x2f, 0x02, 0x03, 0x88, 0x2f, 0x02, 0x03, 0x90, 0x2f, 0x02, 0x03, 0x98, 0x2f, 0x02, 0x03, 0x28, 0x0a, 0x03, 0x03, + 0x30, 0x0a, 0x03, 0x03, 0x38, 0x0a, 0x03, 0x03, 0x80, 0x22, 0x04, 0x04, 0x90, 0x22, 0x04, 0x04, 0x40, 0x02, 0x05, 0x04, 0xa0, 0x16, 0x06, 0x05, 0xc0, 0x32, 0x07, 0x06, 0x80, 0x02, 0x0a, 0x07, + 0x50, 0x27, 0x00, 0x03, 0x58, 0x27, 0x00, 0x03, 0x60, 0x27, 0x00, 0x03, 0x68, 0x27, 0x00, 0x03, 0x18, 0x14, 0x01, 0x02, 0x1c, 0x14, 0x01, 0x02, 0x20, 0x14, 0x01, 0x02, 0x24, 0x14, 0x01, 0x02, + 0x28, 0x14, 0x01, 0x02, 0x2c, 0x14, 0x01, 0x02, 0x30, 0x14, 0x01, 0x02, 0xa0, 0x2f, 0x02, 0x03, 0xa8, 0x2f, 0x02, 0x03, 0xb0, 0x2f, 0x02, 0x03, 0xb8, 0x2f, 0x02, 0x03, 0x40, 0x0a, 0x03, 0x03, + 0x48, 0x0a, 0x03, 0x03, 0x50, 0x0a, 0x03, 0x03, 0xa0, 0x22, 0x04, 0x04, 0xb0, 0x22, 0x04, 0x04, 0x50, 0x02, 0x05, 0x04, 0xc0, 0x16, 0x06, 0x05, 0x00, 0x33, 0x07, 0x06, 0x00, 0x03, 0x0a, 0x07, + 0x70, 0x27, 0x00, 0x03, 0x78, 0x27, 0x00, 0x03, 0x80, 0x27, 0x00, 0x03, 0x88, 0x27, 0x00, 0x03, 0x34, 0x14, 0x01, 0x02, 0x38, 0x14, 0x01, 0x02, 0x3c, 0x14, 0x01, 0x02, 0x40, 0x14, 0x01, 0x02, + 0x44, 0x14, 0x01, 0x02, 0x48, 0x14, 0x01, 0x02, 0x4c, 0x14, 0x01, 0x02, 0xc0, 0x2f, 0x02, 0x03, 0xc8, 0x2f, 0x02, 0x03, 0xd0, 0x2f, 0x02, 0x03, 0xd8, 0x2f, 0x02, 0x03, 0x58, 0x0a, 0x03, 0x03, + 0x60, 0x0a, 0x03, 0x03, 0x68, 0x0a, 0x03, 0x03, 0xc0, 0x22, 0x04, 0x04, 0xd0, 0x22, 0x04, 0x04, 0x60, 0x02, 0x05, 0x04, 0xe0, 0x16, 0x06, 0x05, 0x40, 0x33, 0x07, 0x06, 0x80, 0x03, 0x0a, 0x07, + 0x90, 0x27, 0x00, 0x03, 0x98, 0x27, 0x00, 0x03, 0xa0, 0x27, 0x00, 0x03, 0xa8, 0x27, 0x00, 0x03, 0x50, 0x14, 0x01, 0x02, 0x54, 0x14, 0x01, 0x02, 0x58, 0x14, 0x01, 0x02, 0x5c, 0x14, 0x01, 0x02, + 0x60, 0x14, 0x01, 0x02, 0x64, 0x14, 0x01, 0x02, 0x68, 0x14, 0x01, 0x02, 0xe0, 0x2f, 0x02, 0x03, 0xe8, 0x2f, 0x02, 0x03, 0xf0, 0x2f, 0x02, 0x03, 0xf8, 0x2f, 0x02, 0x03, 0x70, 0x0a, 0x03, 0x03, + 0x78, 0x0a, 0x03, 0x03, 0x80, 0x0a, 0x03, 0x03, 0xe0, 0x22, 0x04, 0x04, 0xf0, 0x22, 0x04, 0x04, 0x70, 0x02, 0x05, 0x04, 0x00, 0x17, 0x06, 0x05, 0x80, 0x33, 0x07, 0x06, 0x00, 0x04, 0x0a, 0x07, + 0xb0, 0x27, 0x00, 0x03, 0xb8, 0x27, 0x00, 0x03, 0xc0, 0x27, 0x00, 0x03, 0xc8, 0x27, 0x00, 0x03, 0x6c, 0x14, 0x01, 0x02, 0x70, 0x14, 0x01, 0x02, 0x74, 0x14, 0x01, 0x02, 0x78, 0x14, 0x01, 0x02, + 0x7c, 0x14, 0x01, 0x02, 0x80, 0x14, 0x01, 0x02, 0x84, 0x14, 0x01, 0x02, 0x00, 0x30, 0x02, 0x03, 0x08, 0x30, 0x02, 0x03, 0x10, 0x30, 0x02, 0x03, 0x18, 0x30, 0x02, 0x03, 0x88, 0x0a, 0x03, 0x03, + 0x90, 0x0a, 0x03, 0x03, 0x98, 0x0a, 0x03, 0x03, 0x00, 0x23, 0x04, 0x04, 0x10, 0x23, 0x04, 0x04, 0x80, 0x02, 0x05, 0x04, 0x20, 0x17, 0x06, 0x05, 0xc0, 0x33, 0x07, 0x06, 0x80, 0x04, 0x0a, 0x07, + 0xd0, 0x27, 0x00, 0x03, 0xd8, 0x27, 0x00, 0x03, 0xe0, 0x27, 0x00, 0x03, 0xe8, 0x27, 0x00, 0x03, 0x88, 0x14, 0x01, 0x02, 0x8c, 0x14, 0x01, 0x02, 0x90, 0x14, 0x01, 0x02, 0x94, 0x14, 0x01, 0x02, + 0x98, 0x14, 0x01, 0x02, 0x9c, 0x14, 0x01, 0x02, 0xa0, 0x14, 0x01, 0x02, 0x20, 0x30, 0x02, 0x03, 0x28, 0x30, 0x02, 0x03, 0x30, 0x30, 0x02, 0x03, 0x38, 0x30, 0x02, 0x03, 0xa0, 0x0a, 0x03, 0x03, + 0xa8, 0x0a, 0x03, 0x03, 0xb0, 0x0a, 0x03, 0x03, 0x20, 0x23, 0x04, 0x04, 0x30, 0x23, 0x04, 0x04, 0x90, 0x02, 0x05, 0x04, 0x40, 0x17, 0x06, 0x05, 0x00, 0x34, 0x07, 0x06, 0x00, 0x05, 0x0a, 0x07, + 0xf0, 0x27, 0x00, 0x03, 0xf8, 0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x03, 0x08, 0x28, 0x00, 0x03, 0xa4, 0x14, 0x01, 0x02, 0xa8, 0x14, 0x01, 0x02, 0xac, 0x14, 0x01, 0x02, 0xb0, 0x14, 0x01, 0x02, + 0xb4, 0x14, 0x01, 0x02, 0xb8, 0x14, 0x01, 0x02, 0xbc, 0x14, 0x01, 0x02, 0x40, 0x30, 0x02, 0x03, 0x48, 0x30, 0x02, 0x03, 0x50, 0x30, 0x02, 0x03, 0x58, 0x30, 0x02, 0x03, 0xb8, 0x0a, 0x03, 0x03, + 0xc0, 0x0a, 0x03, 0x03, 0xc8, 0x0a, 0x03, 0x03, 0x40, 0x23, 0x04, 0x04, 0x50, 0x23, 0x04, 0x04, 0xa0, 0x02, 0x05, 0x04, 0x60, 0x17, 0x06, 0x05, 0x40, 0x34, 0x07, 0x06, 0x80, 0x05, 0x0a, 0x07, + 0x10, 0x28, 0x00, 0x03, 0x18, 0x28, 0x00, 0x03, 0x20, 0x28, 0x00, 0x03, 0x28, 0x28, 0x00, 0x03, 0xc0, 0x14, 0x01, 0x02, 0xc4, 0x14, 0x01, 0x02, 0xc8, 0x14, 0x01, 0x02, 0xcc, 0x14, 0x01, 0x02, + 0xd0, 0x14, 0x01, 0x02, 0xd4, 0x14, 0x01, 0x02, 0xd8, 0x14, 0x01, 0x02, 0x60, 0x30, 0x02, 0x03, 0x68, 0x30, 0x02, 0x03, 0x70, 0x30, 0x02, 0x03, 0x78, 0x30, 0x02, 0x03, 0xd0, 0x0a, 0x03, 0x03, + 0xd8, 0x0a, 0x03, 0x03, 0xe0, 0x0a, 0x03, 0x03, 0x60, 0x23, 0x04, 0x04, 0x70, 0x23, 0x04, 0x04, 0xb0, 0x02, 0x05, 0x04, 0x80, 0x17, 0x06, 0x05, 0x80, 0x34, 0x07, 0x06, 0x00, 0x06, 0x0a, 0x07, + 0x30, 0x28, 0x00, 0x03, 0x38, 0x28, 0x00, 0x03, 0x40, 0x28, 0x00, 0x03, 0x48, 0x28, 0x00, 0x03, 0xdc, 0x14, 0x01, 0x02, 0xe0, 0x14, 0x01, 0x02, 0xe4, 0x14, 0x01, 0x02, 0xe8, 0x14, 0x01, 0x02, + 0xec, 0x14, 0x01, 0x02, 0xf0, 0x14, 0x01, 0x02, 0xf4, 0x14, 0x01, 0x02, 0x80, 0x30, 0x02, 0x03, 0x88, 0x30, 0x02, 0x03, 0x90, 0x30, 0x02, 0x03, 0x98, 0x30, 0x02, 0x03, 0xe8, 0x0a, 0x03, 0x03, + 0xf0, 0x0a, 0x03, 0x03, 0xf8, 0x0a, 0x03, 0x03, 0x80, 0x23, 0x04, 0x04, 0x90, 0x23, 0x04, 0x04, 0xc0, 0x02, 0x05, 0x04, 0xa0, 0x17, 0x06, 0x05, 0xc0, 0x34, 0x07, 0x06, 0x80, 0x06, 0x0a, 0x07, + 0x50, 0x28, 0x00, 0x03, 0x58, 0x28, 0x00, 0x03, 0x60, 0x28, 0x00, 0x03, 0x68, 0x28, 0x00, 0x03, 0xf8, 0x14, 0x01, 0x02, 0xfc, 0x14, 0x01, 0x02, 0x00, 0x15, 0x01, 0x02, 0x04, 0x15, 0x01, 0x02, + 0x08, 0x15, 0x01, 0x02, 0x0c, 0x15, 0x01, 0x02, 0x10, 0x15, 0x01, 0x02, 0xa0, 0x30, 0x02, 0x03, 0xa8, 0x30, 0x02, 0x03, 0xb0, 0x30, 0x02, 0x03, 0xb8, 0x30, 0x02, 0x03, 0x00, 0x0b, 0x03, 0x03, + 0x08, 0x0b, 0x03, 0x03, 0x10, 0x0b, 0x03, 0x03, 0xa0, 0x23, 0x04, 0x04, 0xb0, 0x23, 0x04, 0x04, 0xd0, 0x02, 0x05, 0x04, 0xc0, 0x17, 0x06, 0x05, 0x00, 0x35, 0x07, 0x06, 0x00, 0x15, 0x0b, 0x08, + 0x70, 0x28, 0x00, 0x03, 0x78, 0x28, 0x00, 0x03, 0x80, 0x28, 0x00, 0x03, 0x88, 0x28, 0x00, 0x03, 0x14, 0x15, 0x01, 0x02, 0x18, 0x15, 0x01, 0x02, 0x1c, 0x15, 0x01, 0x02, 0x20, 0x15, 0x01, 0x02, + 0x24, 0x15, 0x01, 0x02, 0x28, 0x15, 0x01, 0x02, 0x2c, 0x15, 0x01, 0x02, 0xc0, 0x30, 0x02, 0x03, 0xc8, 0x30, 0x02, 0x03, 0xd0, 0x30, 0x02, 0x03, 0xd8, 0x30, 0x02, 0x03, 0x18, 0x0b, 0x03, 0x03, + 0x20, 0x0b, 0x03, 0x03, 0x28, 0x0b, 0x03, 0x03, 0xc0, 0x23, 0x04, 0x04, 0xd0, 0x23, 0x04, 0x04, 0xe0, 0x02, 0x05, 0x04, 0xe0, 0x17, 0x06, 0x05, 0x40, 0x35, 0x07, 0x06, 0x00, 0x16, 0x0b, 0x08, + 0x90, 0x28, 0x00, 0x03, 0x98, 0x28, 0x00, 0x03, 0xa0, 0x28, 0x00, 0x03, 0xa8, 0x28, 0x00, 0x03, 0x30, 0x15, 0x01, 0x02, 0x34, 0x15, 0x01, 0x02, 0x38, 0x15, 0x01, 0x02, 0x3c, 0x15, 0x01, 0x02, + 0x40, 0x15, 0x01, 0x02, 0x44, 0x15, 0x01, 0x02, 0x48, 0x15, 0x01, 0x02, 0xe0, 0x30, 0x02, 0x03, 0xe8, 0x30, 0x02, 0x03, 0xf0, 0x30, 0x02, 0x03, 0xf8, 0x30, 0x02, 0x03, 0x30, 0x0b, 0x03, 0x03, + 0x38, 0x0b, 0x03, 0x03, 0x40, 0x0b, 0x03, 0x03, 0xe0, 0x23, 0x04, 0x04, 0xf0, 0x23, 0x04, 0x04, 0xf0, 0x02, 0x05, 0x04, 0x00, 0x18, 0x06, 0x05, 0x80, 0x35, 0x07, 0x06, 0x00, 0x17, 0x0b, 0x08, + 0xb0, 0x28, 0x00, 0x03, 0xb8, 0x28, 0x00, 0x03, 0xc0, 0x28, 0x00, 0x03, 0xc8, 0x28, 0x00, 0x03, 0x4c, 0x15, 0x01, 0x02, 0x50, 0x15, 0x01, 0x02, 0x54, 0x15, 0x01, 0x02, 0x58, 0x15, 0x01, 0x02, + 0x5c, 0x15, 0x01, 0x02, 0x60, 0x15, 0x01, 0x02, 0x64, 0x15, 0x01, 0x02, 0x00, 0x31, 0x02, 0x03, 0x08, 0x31, 0x02, 0x03, 0x10, 0x31, 0x02, 0x03, 0x18, 0x31, 0x02, 0x03, 0x48, 0x0b, 0x03, 0x03, + 0x50, 0x0b, 0x03, 0x03, 0x58, 0x0b, 0x03, 0x03, 0x00, 0x24, 0x04, 0x04, 0x10, 0x24, 0x04, 0x04, 0x00, 0x03, 0x05, 0x04, 0x20, 0x18, 0x06, 0x05, 0xc0, 0x35, 0x07, 0x06, 0x00, 0x18, 0x0b, 0x08, + 0xd0, 0x28, 0x00, 0x03, 0xd8, 0x28, 0x00, 0x03, 0xe0, 0x28, 0x00, 0x03, 0xe8, 0x28, 0x00, 0x03, 0x68, 0x15, 0x01, 0x02, 0x6c, 0x15, 0x01, 0x02, 0x70, 0x15, 0x01, 0x02, 0x74, 0x15, 0x01, 0x02, + 0x78, 0x15, 0x01, 0x02, 0x7c, 0x15, 0x01, 0x02, 0x80, 0x15, 0x01, 0x02, 0x20, 0x31, 0x02, 0x03, 0x28, 0x31, 0x02, 0x03, 0x30, 0x31, 0x02, 0x03, 0x38, 0x31, 0x02, 0x03, 0x60, 0x0b, 0x03, 0x03, + 0x68, 0x0b, 0x03, 0x03, 0x70, 0x0b, 0x03, 0x03, 0x20, 0x24, 0x04, 0x04, 0x30, 0x24, 0x04, 0x04, 0x10, 0x03, 0x05, 0x04, 0x40, 0x18, 0x06, 0x05, 0x00, 0x36, 0x07, 0x06, 0x00, 0x19, 0x0b, 0x08, + 0xf0, 0x28, 0x00, 0x03, 0xf8, 0x28, 0x00, 0x03, 0x00, 0x29, 0x00, 0x03, 0x08, 0x29, 0x00, 0x03, 0x84, 0x15, 0x01, 0x02, 0x88, 0x15, 0x01, 0x02, 0x8c, 0x15, 0x01, 0x02, 0x90, 0x15, 0x01, 0x02, + 0x94, 0x15, 0x01, 0x02, 0x98, 0x15, 0x01, 0x02, 0x9c, 0x15, 0x01, 0x02, 0x40, 0x31, 0x02, 0x03, 0x48, 0x31, 0x02, 0x03, 0x50, 0x31, 0x02, 0x03, 0x58, 0x31, 0x02, 0x03, 0x78, 0x0b, 0x03, 0x03, + 0x80, 0x0b, 0x03, 0x03, 0x88, 0x0b, 0x03, 0x03, 0x40, 0x24, 0x04, 0x04, 0x50, 0x24, 0x04, 0x04, 0x20, 0x03, 0x05, 0x04, 0x60, 0x18, 0x06, 0x05, 0x40, 0x36, 0x07, 0x06, 0x00, 0x1a, 0x0b, 0x08, + 0x10, 0x29, 0x00, 0x03, 0x18, 0x29, 0x00, 0x03, 0x20, 0x29, 0x00, 0x03, 0x28, 0x29, 0x00, 0x03, 0xa0, 0x15, 0x01, 0x02, 0xa4, 0x15, 0x01, 0x02, 0xa8, 0x15, 0x01, 0x02, 0xac, 0x15, 0x01, 0x02, + 0xb0, 0x15, 0x01, 0x02, 0xb4, 0x15, 0x01, 0x02, 0xb8, 0x15, 0x01, 0x02, 0x60, 0x31, 0x02, 0x03, 0x68, 0x31, 0x02, 0x03, 0x70, 0x31, 0x02, 0x03, 0x78, 0x31, 0x02, 0x03, 0x90, 0x0b, 0x03, 0x03, + 0x98, 0x0b, 0x03, 0x03, 0xa0, 0x0b, 0x03, 0x03, 0x60, 0x24, 0x04, 0x04, 0x70, 0x24, 0x04, 0x04, 0x30, 0x03, 0x05, 0x04, 0x80, 0x18, 0x06, 0x05, 0x80, 0x36, 0x07, 0x06, 0x00, 0x1b, 0x0b, 0x08, + 0x30, 0x29, 0x00, 0x03, 0x38, 0x29, 0x00, 0x03, 0x40, 0x29, 0x00, 0x03, 0x48, 0x29, 0x00, 0x03, 0xbc, 0x15, 0x01, 0x02, 0xc0, 0x15, 0x01, 0x02, 0xc4, 0x15, 0x01, 0x02, 0xc8, 0x15, 0x01, 0x02, + 0xcc, 0x15, 0x01, 0x02, 0xd0, 0x15, 0x01, 0x02, 0xd4, 0x15, 0x01, 0x02, 0x80, 0x31, 0x02, 0x03, 0x88, 0x31, 0x02, 0x03, 0x90, 0x31, 0x02, 0x03, 0x98, 0x31, 0x02, 0x03, 0xa8, 0x0b, 0x03, 0x03, + 0xb0, 0x0b, 0x03, 0x03, 0xb8, 0x0b, 0x03, 0x03, 0x80, 0x24, 0x04, 0x04, 0x90, 0x24, 0x04, 0x04, 0x40, 0x03, 0x05, 0x04, 0xa0, 0x18, 0x06, 0x05, 0xc0, 0x36, 0x07, 0x06, 0x00, 0x1c, 0x0b, 0x08, + 0x50, 0x29, 0x00, 0x03, 0x58, 0x29, 0x00, 0x03, 0x60, 0x29, 0x00, 0x03, 0x68, 0x29, 0x00, 0x03, 0xd8, 0x15, 0x01, 0x02, 0xdc, 0x15, 0x01, 0x02, 0xe0, 0x15, 0x01, 0x02, 0xe4, 0x15, 0x01, 0x02, + 0xe8, 0x15, 0x01, 0x02, 0xec, 0x15, 0x01, 0x02, 0xf0, 0x15, 0x01, 0x02, 0xa0, 0x31, 0x02, 0x03, 0xa8, 0x31, 0x02, 0x03, 0xb0, 0x31, 0x02, 0x03, 0xb8, 0x31, 0x02, 0x03, 0xc0, 0x0b, 0x03, 0x03, + 0xc8, 0x0b, 0x03, 0x03, 0xd0, 0x0b, 0x03, 0x03, 0xa0, 0x24, 0x04, 0x04, 0xb0, 0x24, 0x04, 0x04, 0x50, 0x03, 0x05, 0x04, 0xc0, 0x18, 0x06, 0x05, 0x00, 0x37, 0x07, 0x06, 0x00, 0x1d, 0x0b, 0x08, + 0x70, 0x29, 0x00, 0x03, 0x78, 0x29, 0x00, 0x03, 0x80, 0x29, 0x00, 0x03, 0x88, 0x29, 0x00, 0x03, 0xf4, 0x15, 0x01, 0x02, 0xf8, 0x15, 0x01, 0x02, 0xfc, 0x15, 0x01, 0x02, 0x00, 0x16, 0x01, 0x02, + 0x04, 0x16, 0x01, 0x02, 0x08, 0x16, 0x01, 0x02, 0xc0, 0x31, 0x02, 0x03, 0xc8, 0x31, 0x02, 0x03, 0xd0, 0x31, 0x02, 0x03, 0xd8, 0x31, 0x02, 0x03, 0xe0, 0x31, 0x02, 0x03, 0xd8, 0x0b, 0x03, 0x03, + 0xe0, 0x0b, 0x03, 0x03, 0xe8, 0x0b, 0x03, 0x03, 0xc0, 0x24, 0x04, 0x04, 0xd0, 0x24, 0x04, 0x04, 0x60, 0x03, 0x05, 0x04, 0xe0, 0x18, 0x06, 0x05, 0x40, 0x37, 0x07, 0x06, 0x00, 0x1e, 0x0b, 0x08, + 0x90, 0x29, 0x00, 0x03, 0x98, 0x29, 0x00, 0x03, 0xa0, 0x29, 0x00, 0x03, 0xa8, 0x29, 0x00, 0x03, 0x0c, 0x16, 0x01, 0x02, 0x10, 0x16, 0x01, 0x02, 0x14, 0x16, 0x01, 0x02, 0x18, 0x16, 0x01, 0x02, + 0x1c, 0x16, 0x01, 0x02, 0x20, 0x16, 0x01, 0x02, 0xe8, 0x31, 0x02, 0x03, 0xf0, 0x31, 0x02, 0x03, 0xf8, 0x31, 0x02, 0x03, 0x00, 0x32, 0x02, 0x03, 0x08, 0x32, 0x02, 0x03, 0xf0, 0x0b, 0x03, 0x03, + 0xf8, 0x0b, 0x03, 0x03, 0x00, 0x0c, 0x03, 0x03, 0xe0, 0x24, 0x04, 0x04, 0xf0, 0x24, 0x04, 0x04, 0x70, 0x03, 0x05, 0x04, 0x00, 0x19, 0x06, 0x05, 0x80, 0x37, 0x07, 0x06, 0x00, 0x32, 0x0c, 0x09, + 0xb0, 0x29, 0x00, 0x03, 0xb8, 0x29, 0x00, 0x03, 0xc0, 0x29, 0x00, 0x03, 0xc8, 0x29, 0x00, 0x03, 0x24, 0x16, 0x01, 0x02, 0x28, 0x16, 0x01, 0x02, 0x2c, 0x16, 0x01, 0x02, 0x30, 0x16, 0x01, 0x02, + 0x34, 0x16, 0x01, 0x02, 0x38, 0x16, 0x01, 0x02, 0x10, 0x32, 0x02, 0x03, 0x18, 0x32, 0x02, 0x03, 0x20, 0x32, 0x02, 0x03, 0x28, 0x32, 0x02, 0x03, 0x30, 0x32, 0x02, 0x03, 0x08, 0x0c, 0x03, 0x03, + 0x10, 0x0c, 0x03, 0x03, 0x18, 0x0c, 0x03, 0x03, 0x00, 0x25, 0x04, 0x04, 0x10, 0x25, 0x04, 0x04, 0x80, 0x03, 0x05, 0x04, 0x20, 0x19, 0x06, 0x05, 0xc0, 0x37, 0x07, 0x06, 0x00, 0x34, 0x0c, 0x09, + 0xd0, 0x29, 0x00, 0x03, 0xd8, 0x29, 0x00, 0x03, 0xe0, 0x29, 0x00, 0x03, 0xe8, 0x29, 0x00, 0x03, 0x3c, 0x16, 0x01, 0x02, 0x40, 0x16, 0x01, 0x02, 0x44, 0x16, 0x01, 0x02, 0x48, 0x16, 0x01, 0x02, + 0x4c, 0x16, 0x01, 0x02, 0x50, 0x16, 0x01, 0x02, 0x38, 0x32, 0x02, 0x03, 0x40, 0x32, 0x02, 0x03, 0x48, 0x32, 0x02, 0x03, 0x50, 0x32, 0x02, 0x03, 0x58, 0x32, 0x02, 0x03, 0x20, 0x0c, 0x03, 0x03, + 0x28, 0x0c, 0x03, 0x03, 0x30, 0x0c, 0x03, 0x03, 0x20, 0x25, 0x04, 0x04, 0x30, 0x25, 0x04, 0x04, 0x90, 0x03, 0x05, 0x04, 0x40, 0x19, 0x06, 0x05, 0x00, 0x38, 0x07, 0x06, 0x00, 0x36, 0x0c, 0x09, + 0xf0, 0x29, 0x00, 0x03, 0xf8, 0x29, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x03, 0x08, 0x2a, 0x00, 0x03, 0x54, 0x16, 0x01, 0x02, 0x58, 0x16, 0x01, 0x02, 0x5c, 0x16, 0x01, 0x02, 0x60, 0x16, 0x01, 0x02, + 0x64, 0x16, 0x01, 0x02, 0x68, 0x16, 0x01, 0x02, 0x60, 0x32, 0x02, 0x03, 0x68, 0x32, 0x02, 0x03, 0x70, 0x32, 0x02, 0x03, 0x78, 0x32, 0x02, 0x03, 0x80, 0x32, 0x02, 0x03, 0x38, 0x0c, 0x03, 0x03, + 0x40, 0x0c, 0x03, 0x03, 0x48, 0x0c, 0x03, 0x03, 0x40, 0x25, 0x04, 0x04, 0x50, 0x25, 0x04, 0x04, 0xa0, 0x03, 0x05, 0x04, 0x60, 0x19, 0x06, 0x05, 0x40, 0x38, 0x07, 0x06, 0x00, 0x38, 0x0c, 0x09, + 0x10, 0x2a, 0x00, 0x03, 0x18, 0x2a, 0x00, 0x03, 0x20, 0x2a, 0x00, 0x03, 0x28, 0x2a, 0x00, 0x03, 0x6c, 0x16, 0x01, 0x02, 0x70, 0x16, 0x01, 0x02, 0x74, 0x16, 0x01, 0x02, 0x78, 0x16, 0x01, 0x02, + 0x7c, 0x16, 0x01, 0x02, 0x80, 0x16, 0x01, 0x02, 0x88, 0x32, 0x02, 0x03, 0x90, 0x32, 0x02, 0x03, 0x98, 0x32, 0x02, 0x03, 0xa0, 0x32, 0x02, 0x03, 0xa8, 0x32, 0x02, 0x03, 0x50, 0x0c, 0x03, 0x03, + 0x58, 0x0c, 0x03, 0x03, 0x60, 0x0c, 0x03, 0x03, 0x60, 0x25, 0x04, 0x04, 0x70, 0x25, 0x04, 0x04, 0xb0, 0x03, 0x05, 0x04, 0x80, 0x19, 0x06, 0x05, 0x80, 0x38, 0x07, 0x06, 0x00, 0x3a, 0x0c, 0x09, + 0x30, 0x2a, 0x00, 0x03, 0x38, 0x2a, 0x00, 0x03, 0x40, 0x2a, 0x00, 0x03, 0x48, 0x2a, 0x00, 0x03, 0x84, 0x16, 0x01, 0x02, 0x88, 0x16, 0x01, 0x02, 0x8c, 0x16, 0x01, 0x02, 0x90, 0x16, 0x01, 0x02, + 0x94, 0x16, 0x01, 0x02, 0x98, 0x16, 0x01, 0x02, 0xb0, 0x32, 0x02, 0x03, 0xb8, 0x32, 0x02, 0x03, 0xc0, 0x32, 0x02, 0x03, 0xc8, 0x32, 0x02, 0x03, 0xd0, 0x32, 0x02, 0x03, 0x68, 0x0c, 0x03, 0x03, + 0x70, 0x0c, 0x03, 0x03, 0x78, 0x0c, 0x03, 0x03, 0x80, 0x25, 0x04, 0x04, 0x90, 0x25, 0x04, 0x04, 0xc0, 0x03, 0x05, 0x04, 0xa0, 0x19, 0x06, 0x05, 0xc0, 0x38, 0x07, 0x06, 0x00, 0x3c, 0x0c, 0x09, + 0x50, 0x2a, 0x00, 0x03, 0x58, 0x2a, 0x00, 0x03, 0x60, 0x2a, 0x00, 0x03, 0x68, 0x2a, 0x00, 0x03, 0x9c, 0x16, 0x01, 0x02, 0xa0, 0x16, 0x01, 0x02, 0xa4, 0x16, 0x01, 0x02, 0xa8, 0x16, 0x01, 0x02, + 0xac, 0x16, 0x01, 0x02, 0xb0, 0x16, 0x01, 0x02, 0xd8, 0x32, 0x02, 0x03, 0xe0, 0x32, 0x02, 0x03, 0xe8, 0x32, 0x02, 0x03, 0xf0, 0x32, 0x02, 0x03, 0xf8, 0x32, 0x02, 0x03, 0x80, 0x0c, 0x03, 0x03, + 0x88, 0x0c, 0x03, 0x03, 0x90, 0x0c, 0x03, 0x03, 0xa0, 0x25, 0x04, 0x04, 0xb0, 0x25, 0x04, 0x04, 0xd0, 0x03, 0x05, 0x04, 0xc0, 0x19, 0x06, 0x05, 0x00, 0x0e, 0x08, 0x06, 0x00, 0x0c, 0x0d, 0x09, + 0x70, 0x2a, 0x00, 0x03, 0x78, 0x2a, 0x00, 0x03, 0x80, 0x2a, 0x00, 0x03, 0x88, 0x2a, 0x00, 0x03, 0xb4, 0x16, 0x01, 0x02, 0xb8, 0x16, 0x01, 0x02, 0xbc, 0x16, 0x01, 0x02, 0xc0, 0x16, 0x01, 0x02, + 0xc4, 0x16, 0x01, 0x02, 0xc8, 0x16, 0x01, 0x02, 0x00, 0x33, 0x02, 0x03, 0x08, 0x33, 0x02, 0x03, 0x10, 0x33, 0x02, 0x03, 0x18, 0x33, 0x02, 0x03, 0x20, 0x33, 0x02, 0x03, 0x98, 0x0c, 0x03, 0x03, + 0xa0, 0x0c, 0x03, 0x03, 0xa8, 0x0c, 0x03, 0x03, 0xc0, 0x25, 0x04, 0x04, 0xd0, 0x25, 0x04, 0x04, 0xe0, 0x03, 0x05, 0x04, 0xe0, 0x19, 0x06, 0x05, 0x40, 0x0e, 0x08, 0x06, 0x00, 0x0e, 0x0d, 0x09, + 0x90, 0x2a, 0x00, 0x03, 0x98, 0x2a, 0x00, 0x03, 0xa0, 0x2a, 0x00, 0x03, 0xa8, 0x2a, 0x00, 0x03, 0xcc, 0x16, 0x01, 0x02, 0xd0, 0x16, 0x01, 0x02, 0xd4, 0x16, 0x01, 0x02, 0xd8, 0x16, 0x01, 0x02, + 0xdc, 0x16, 0x01, 0x02, 0xe0, 0x16, 0x01, 0x02, 0x28, 0x33, 0x02, 0x03, 0x30, 0x33, 0x02, 0x03, 0x38, 0x33, 0x02, 0x03, 0x40, 0x33, 0x02, 0x03, 0x48, 0x33, 0x02, 0x03, 0xb0, 0x0c, 0x03, 0x03, + 0xb8, 0x0c, 0x03, 0x03, 0xc0, 0x0c, 0x03, 0x03, 0xe0, 0x25, 0x04, 0x04, 0xf0, 0x25, 0x04, 0x04, 0xf0, 0x03, 0x05, 0x04, 0x00, 0x1a, 0x06, 0x05, 0x80, 0x0e, 0x08, 0x06, 0x00, 0x10, 0x0d, 0x09, + 0xb0, 0x2a, 0x00, 0x03, 0xb8, 0x2a, 0x00, 0x03, 0xc0, 0x2a, 0x00, 0x03, 0xc8, 0x2a, 0x00, 0x03, 0xe4, 0x16, 0x01, 0x02, 0xe8, 0x16, 0x01, 0x02, 0xec, 0x16, 0x01, 0x02, 0xf0, 0x16, 0x01, 0x02, + 0xf4, 0x16, 0x01, 0x02, 0xf8, 0x16, 0x01, 0x02, 0x50, 0x33, 0x02, 0x03, 0x58, 0x33, 0x02, 0x03, 0x60, 0x33, 0x02, 0x03, 0x68, 0x33, 0x02, 0x03, 0x70, 0x33, 0x02, 0x03, 0xc8, 0x0c, 0x03, 0x03, + 0xd0, 0x0c, 0x03, 0x03, 0xd8, 0x0c, 0x03, 0x03, 0x00, 0x26, 0x04, 0x04, 0x10, 0x26, 0x04, 0x04, 0x00, 0x04, 0x05, 0x04, 0x20, 0x1a, 0x06, 0x05, 0xc0, 0x0e, 0x08, 0x06, 0x00, 0x12, 0x0d, 0x09, + 0xd0, 0x2a, 0x00, 0x03, 0xd8, 0x2a, 0x00, 0x03, 0xe0, 0x2a, 0x00, 0x03, 0xe8, 0x2a, 0x00, 0x03, 0xfc, 0x16, 0x01, 0x02, 0x00, 0x17, 0x01, 0x02, 0x04, 0x17, 0x01, 0x02, 0x08, 0x17, 0x01, 0x02, + 0x0c, 0x17, 0x01, 0x02, 0x10, 0x17, 0x01, 0x02, 0x78, 0x33, 0x02, 0x03, 0x80, 0x33, 0x02, 0x03, 0x88, 0x33, 0x02, 0x03, 0x90, 0x33, 0x02, 0x03, 0x98, 0x33, 0x02, 0x03, 0xe0, 0x0c, 0x03, 0x03, + 0xe8, 0x0c, 0x03, 0x03, 0xf0, 0x0c, 0x03, 0x03, 0x20, 0x26, 0x04, 0x04, 0x30, 0x26, 0x04, 0x04, 0x10, 0x04, 0x05, 0x04, 0x40, 0x1a, 0x06, 0x05, 0x00, 0x0f, 0x08, 0x06, 0x00, 0x24, 0x0e, 0x0a, + 0xf0, 0x2a, 0x00, 0x03, 0xf8, 0x2a, 0x00, 0x03, 0x00, 0x2b, 0x00, 0x03, 0x08, 0x2b, 0x00, 0x03, 0x14, 0x17, 0x01, 0x02, 0x18, 0x17, 0x01, 0x02, 0x1c, 0x17, 0x01, 0x02, 0x20, 0x17, 0x01, 0x02, + 0x24, 0x17, 0x01, 0x02, 0x28, 0x17, 0x01, 0x02, 0xa0, 0x33, 0x02, 0x03, 0xa8, 0x33, 0x02, 0x03, 0xb0, 0x33, 0x02, 0x03, 0xb8, 0x33, 0x02, 0x03, 0xc0, 0x33, 0x02, 0x03, 0xf8, 0x0c, 0x03, 0x03, + 0x00, 0x0d, 0x03, 0x03, 0x08, 0x0d, 0x03, 0x03, 0x40, 0x26, 0x04, 0x04, 0x50, 0x26, 0x04, 0x04, 0x20, 0x04, 0x05, 0x04, 0x60, 0x1a, 0x06, 0x05, 0x40, 0x0f, 0x08, 0x06, 0x00, 0x28, 0x0e, 0x0a, + 0x10, 0x2b, 0x00, 0x03, 0x18, 0x2b, 0x00, 0x03, 0x20, 0x2b, 0x00, 0x03, 0x28, 0x2b, 0x00, 0x03, 0x2c, 0x17, 0x01, 0x02, 0x30, 0x17, 0x01, 0x02, 0x34, 0x17, 0x01, 0x02, 0x38, 0x17, 0x01, 0x02, + 0x3c, 0x17, 0x01, 0x02, 0x40, 0x17, 0x01, 0x02, 0xc8, 0x33, 0x02, 0x03, 0xd0, 0x33, 0x02, 0x03, 0xd8, 0x33, 0x02, 0x03, 0xe0, 0x33, 0x02, 0x03, 0xe8, 0x33, 0x02, 0x03, 0x10, 0x0d, 0x03, 0x03, + 0x18, 0x0d, 0x03, 0x03, 0x20, 0x0d, 0x03, 0x03, 0x60, 0x26, 0x04, 0x04, 0x70, 0x26, 0x04, 0x04, 0x30, 0x04, 0x05, 0x04, 0x80, 0x1a, 0x06, 0x05, 0x80, 0x0f, 0x08, 0x06, 0x00, 0x2c, 0x0e, 0x0a, + 0x30, 0x2b, 0x00, 0x03, 0x38, 0x2b, 0x00, 0x03, 0x40, 0x2b, 0x00, 0x03, 0x48, 0x2b, 0x00, 0x03, 0x44, 0x17, 0x01, 0x02, 0x48, 0x17, 0x01, 0x02, 0x4c, 0x17, 0x01, 0x02, 0x50, 0x17, 0x01, 0x02, + 0x54, 0x17, 0x01, 0x02, 0x58, 0x17, 0x01, 0x02, 0xf0, 0x33, 0x02, 0x03, 0xf8, 0x33, 0x02, 0x03, 0x00, 0x34, 0x02, 0x03, 0x08, 0x34, 0x02, 0x03, 0x10, 0x34, 0x02, 0x03, 0x28, 0x0d, 0x03, 0x03, + 0x30, 0x0d, 0x03, 0x03, 0x38, 0x0d, 0x03, 0x03, 0x80, 0x26, 0x04, 0x04, 0x90, 0x26, 0x04, 0x04, 0x40, 0x04, 0x05, 0x04, 0xa0, 0x1a, 0x06, 0x05, 0xc0, 0x0f, 0x08, 0x06, 0x00, 0x04, 0x0f, 0x0a, + 0x50, 0x2b, 0x00, 0x03, 0x58, 0x2b, 0x00, 0x03, 0x60, 0x2b, 0x00, 0x03, 0x68, 0x2b, 0x00, 0x03, 0x5c, 0x17, 0x01, 0x02, 0x60, 0x17, 0x01, 0x02, 0x64, 0x17, 0x01, 0x02, 0x68, 0x17, 0x01, 0x02, + 0x6c, 0x17, 0x01, 0x02, 0x70, 0x17, 0x01, 0x02, 0x18, 0x34, 0x02, 0x03, 0x20, 0x34, 0x02, 0x03, 0x28, 0x34, 0x02, 0x03, 0x30, 0x34, 0x02, 0x03, 0x38, 0x34, 0x02, 0x03, 0x40, 0x0d, 0x03, 0x03, + 0x48, 0x0d, 0x03, 0x03, 0x50, 0x0d, 0x03, 0x03, 0xa0, 0x26, 0x04, 0x04, 0xb0, 0x26, 0x04, 0x04, 0x50, 0x04, 0x05, 0x04, 0xc0, 0x1a, 0x06, 0x05, 0x00, 0x10, 0x08, 0x06, 0x00, 0x08, 0x0f, 0x0a, + 0x70, 0x2b, 0x00, 0x03, 0x78, 0x2b, 0x00, 0x03, 0x80, 0x2b, 0x00, 0x03, 0x88, 0x2b, 0x00, 0x03, 0x74, 0x17, 0x01, 0x02, 0x78, 0x17, 0x01, 0x02, 0x7c, 0x17, 0x01, 0x02, 0x80, 0x17, 0x01, 0x02, + 0x84, 0x17, 0x01, 0x02, 0x88, 0x17, 0x01, 0x02, 0x40, 0x34, 0x02, 0x03, 0x48, 0x34, 0x02, 0x03, 0x50, 0x34, 0x02, 0x03, 0x58, 0x34, 0x02, 0x03, 0x60, 0x34, 0x02, 0x03, 0x58, 0x0d, 0x03, 0x03, + 0x60, 0x0d, 0x03, 0x03, 0x68, 0x0d, 0x03, 0x03, 0xc0, 0x26, 0x04, 0x04, 0xd0, 0x26, 0x04, 0x04, 0x60, 0x04, 0x05, 0x04, 0xe0, 0x1a, 0x06, 0x05, 0x40, 0x10, 0x08, 0x06, 0x00, 0x0c, 0x0f, 0x0a, + 0x90, 0x2b, 0x00, 0x03, 0x98, 0x2b, 0x00, 0x03, 0xa0, 0x2b, 0x00, 0x03, 0xa8, 0x2b, 0x00, 0x03, 0x8c, 0x17, 0x01, 0x02, 0x90, 0x17, 0x01, 0x02, 0x94, 0x17, 0x01, 0x02, 0x98, 0x17, 0x01, 0x02, + 0x9c, 0x17, 0x01, 0x02, 0xa0, 0x17, 0x01, 0x02, 0x68, 0x34, 0x02, 0x03, 0x70, 0x34, 0x02, 0x03, 0x78, 0x34, 0x02, 0x03, 0x80, 0x34, 0x02, 0x03, 0x88, 0x34, 0x02, 0x03, 0x70, 0x0d, 0x03, 0x03, + 0x78, 0x0d, 0x03, 0x03, 0x80, 0x0d, 0x03, 0x03, 0xe0, 0x26, 0x04, 0x04, 0xf0, 0x26, 0x04, 0x04, 0x70, 0x04, 0x05, 0x04, 0x00, 0x1b, 0x06, 0x05, 0x80, 0x10, 0x08, 0x06, 0x00, 0x20, 0x10, 0x0b, + 0xb0, 0x2b, 0x00, 0x03, 0xb8, 0x2b, 0x00, 0x03, 0xc0, 0x2b, 0x00, 0x03, 0xc8, 0x2b, 0x00, 0x03, 0xa4, 0x17, 0x01, 0x02, 0xa8, 0x17, 0x01, 0x02, 0xac, 0x17, 0x01, 0x02, 0xb0, 0x17, 0x01, 0x02, + 0xb4, 0x17, 0x01, 0x02, 0xb8, 0x17, 0x01, 0x02, 0x90, 0x34, 0x02, 0x03, 0x98, 0x34, 0x02, 0x03, 0xa0, 0x34, 0x02, 0x03, 0xa8, 0x34, 0x02, 0x03, 0xb0, 0x34, 0x02, 0x03, 0x88, 0x0d, 0x03, 0x03, + 0x90, 0x0d, 0x03, 0x03, 0x98, 0x0d, 0x03, 0x03, 0x00, 0x27, 0x04, 0x04, 0x10, 0x27, 0x04, 0x04, 0x80, 0x04, 0x05, 0x04, 0x20, 0x1b, 0x06, 0x05, 0xc0, 0x10, 0x08, 0x06, 0x00, 0x00, 0x11, 0x0b, + 0xd0, 0x2b, 0x00, 0x03, 0xd8, 0x2b, 0x00, 0x03, 0xe0, 0x2b, 0x00, 0x03, 0xe8, 0x2b, 0x00, 0x03, 0xbc, 0x17, 0x01, 0x02, 0xc0, 0x17, 0x01, 0x02, 0xc4, 0x17, 0x01, 0x02, 0xc8, 0x17, 0x01, 0x02, + 0xcc, 0x17, 0x01, 0x02, 0xd0, 0x17, 0x01, 0x02, 0xb8, 0x34, 0x02, 0x03, 0xc0, 0x34, 0x02, 0x03, 0xc8, 0x34, 0x02, 0x03, 0xd0, 0x34, 0x02, 0x03, 0xd8, 0x34, 0x02, 0x03, 0xa0, 0x0d, 0x03, 0x03, + 0xa8, 0x0d, 0x03, 0x03, 0xb0, 0x0d, 0x03, 0x03, 0x20, 0x27, 0x04, 0x04, 0x30, 0x27, 0x04, 0x04, 0x90, 0x04, 0x05, 0x04, 0x40, 0x1b, 0x06, 0x05, 0x00, 0x11, 0x08, 0x06, 0x00, 0x00, 0x12, 0x0c, + 0xf0, 0x2b, 0x00, 0x03, 0xf8, 0x2b, 0x00, 0x03, 0x00, 0x2c, 0x00, 0x03, 0x08, 0x2c, 0x00, 0x03, 0xd4, 0x17, 0x01, 0x02, 0xd8, 0x17, 0x01, 0x02, 0xdc, 0x17, 0x01, 0x02, 0xe0, 0x17, 0x01, 0x02, + 0xe4, 0x17, 0x01, 0x02, 0xe8, 0x17, 0x01, 0x02, 0xe0, 0x34, 0x02, 0x03, 0xe8, 0x34, 0x02, 0x03, 0xf0, 0x34, 0x02, 0x03, 0xf8, 0x34, 0x02, 0x03, 0x00, 0x35, 0x02, 0x03, 0xb8, 0x0d, 0x03, 0x03, + 0xc0, 0x0d, 0x03, 0x03, 0xc8, 0x0d, 0x03, 0x03, 0x40, 0x27, 0x04, 0x04, 0x50, 0x27, 0x04, 0x04, 0xa0, 0x04, 0x05, 0x04, 0x60, 0x1b, 0x06, 0x05, 0x40, 0x11, 0x08, 0x06, 0x10, 0x2c, 0x00, 0x03, + 0x18, 0x2c, 0x00, 0x03, 0x20, 0x2c, 0x00, 0x03, 0x28, 0x2c, 0x00, 0x03, 0x30, 0x2c, 0x00, 0x03, 0xec, 0x17, 0x01, 0x02, 0xf0, 0x17, 0x01, 0x02, 0xf4, 0x17, 0x01, 0x02, 0xf8, 0x17, 0x01, 0x02, + 0xfc, 0x17, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x08, 0x35, 0x02, 0x03, 0x10, 0x35, 0x02, 0x03, 0x18, 0x35, 0x02, 0x03, 0x20, 0x35, 0x02, 0x03, 0x28, 0x35, 0x02, 0x03, 0xd0, 0x0d, 0x03, 0x03, + 0xd8, 0x0d, 0x03, 0x03, 0xe0, 0x0d, 0x03, 0x03, 0x60, 0x27, 0x04, 0x04, 0x70, 0x27, 0x04, 0x04, 0xb0, 0x04, 0x05, 0x04, 0x80, 0x1b, 0x06, 0x05, 0x80, 0x11, 0x08, 0x06, 0x38, 0x2c, 0x00, 0x03, + 0x40, 0x2c, 0x00, 0x03, 0x48, 0x2c, 0x00, 0x03, 0x50, 0x2c, 0x00, 0x03, 0x58, 0x2c, 0x00, 0x03, 0x04, 0x18, 0x01, 0x02, 0x08, 0x18, 0x01, 0x02, 0x0c, 0x18, 0x01, 0x02, 0x10, 0x18, 0x01, 0x02, + 0x14, 0x18, 0x01, 0x02, 0x18, 0x18, 0x01, 0x02, 0x30, 0x35, 0x02, 0x03, 0x38, 0x35, 0x02, 0x03, 0x40, 0x35, 0x02, 0x03, 0x48, 0x35, 0x02, 0x03, 0x50, 0x35, 0x02, 0x03, 0xe8, 0x0d, 0x03, 0x03, + 0xf0, 0x0d, 0x03, 0x03, 0xf8, 0x0d, 0x03, 0x03, 0x80, 0x27, 0x04, 0x04, 0x90, 0x27, 0x04, 0x04, 0xc0, 0x04, 0x05, 0x04, 0xa0, 0x1b, 0x06, 0x05, 0xc0, 0x11, 0x08, 0x06, 0x60, 0x2c, 0x00, 0x03, + 0x68, 0x2c, 0x00, 0x03, 0x70, 0x2c, 0x00, 0x03, 0x78, 0x2c, 0x00, 0x03, 0x80, 0x2c, 0x00, 0x03, 0x1c, 0x18, 0x01, 0x02, 0x20, 0x18, 0x01, 0x02, 0x24, 0x18, 0x01, 0x02, 0x28, 0x18, 0x01, 0x02, + 0x2c, 0x18, 0x01, 0x02, 0x30, 0x18, 0x01, 0x02, 0x58, 0x35, 0x02, 0x03, 0x60, 0x35, 0x02, 0x03, 0x68, 0x35, 0x02, 0x03, 0x70, 0x35, 0x02, 0x03, 0x78, 0x35, 0x02, 0x03, 0x00, 0x0e, 0x03, 0x03, + 0x08, 0x0e, 0x03, 0x03, 0x10, 0x0e, 0x03, 0x03, 0xa0, 0x27, 0x04, 0x04, 0xb0, 0x27, 0x04, 0x04, 0xd0, 0x04, 0x05, 0x04, 0xc0, 0x1b, 0x06, 0x05, 0x00, 0x12, 0x08, 0x06, 0x88, 0x2c, 0x00, 0x03, + 0x90, 0x2c, 0x00, 0x03, 0x98, 0x2c, 0x00, 0x03, 0xa0, 0x2c, 0x00, 0x03, 0xa8, 0x2c, 0x00, 0x03, 0x34, 0x18, 0x01, 0x02, 0x38, 0x18, 0x01, 0x02, 0x3c, 0x18, 0x01, 0x02, 0x40, 0x18, 0x01, 0x02, + 0x44, 0x18, 0x01, 0x02, 0x48, 0x18, 0x01, 0x02, 0x80, 0x35, 0x02, 0x03, 0x88, 0x35, 0x02, 0x03, 0x90, 0x35, 0x02, 0x03, 0x98, 0x35, 0x02, 0x03, 0xa0, 0x35, 0x02, 0x03, 0x18, 0x0e, 0x03, 0x03, + 0x20, 0x0e, 0x03, 0x03, 0x28, 0x0e, 0x03, 0x03, 0xc0, 0x27, 0x04, 0x04, 0xd0, 0x27, 0x04, 0x04, 0xe0, 0x04, 0x05, 0x04, 0xe0, 0x1b, 0x06, 0x05, 0x40, 0x12, 0x08, 0x06, 0xb0, 0x2c, 0x00, 0x03, + 0xb8, 0x2c, 0x00, 0x03, 0xc0, 0x2c, 0x00, 0x03, 0xc8, 0x2c, 0x00, 0x03, 0xd0, 0x2c, 0x00, 0x03, 0x4c, 0x18, 0x01, 0x02, 0x50, 0x18, 0x01, 0x02, 0x54, 0x18, 0x01, 0x02, 0x58, 0x18, 0x01, 0x02, + 0x5c, 0x18, 0x01, 0x02, 0x60, 0x18, 0x01, 0x02, 0xa8, 0x35, 0x02, 0x03, 0xb0, 0x35, 0x02, 0x03, 0xb8, 0x35, 0x02, 0x03, 0xc0, 0x35, 0x02, 0x03, 0xc8, 0x35, 0x02, 0x03, 0x30, 0x0e, 0x03, 0x03, + 0x38, 0x0e, 0x03, 0x03, 0x40, 0x0e, 0x03, 0x03, 0xe0, 0x27, 0x04, 0x04, 0xf0, 0x27, 0x04, 0x04, 0xf0, 0x04, 0x05, 0x04, 0x00, 0x1c, 0x06, 0x05, 0x80, 0x12, 0x08, 0x06, 0xd8, 0x2c, 0x00, 0x03, + 0xe0, 0x2c, 0x00, 0x03, 0xe8, 0x2c, 0x00, 0x03, 0xf0, 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x03, 0x64, 0x18, 0x01, 0x02, 0x68, 0x18, 0x01, 0x02, 0x6c, 0x18, 0x01, 0x02, 0x70, 0x18, 0x01, 0x02, + 0x74, 0x18, 0x01, 0x02, 0x78, 0x18, 0x01, 0x02, 0xd0, 0x35, 0x02, 0x03, 0xd8, 0x35, 0x02, 0x03, 0xe0, 0x35, 0x02, 0x03, 0xe8, 0x35, 0x02, 0x03, 0xf0, 0x35, 0x02, 0x03, 0x48, 0x0e, 0x03, 0x03, + 0x50, 0x0e, 0x03, 0x03, 0x58, 0x0e, 0x03, 0x03, 0x00, 0x28, 0x04, 0x04, 0x10, 0x28, 0x04, 0x04, 0x00, 0x05, 0x05, 0x04, 0x20, 0x1c, 0x06, 0x05, 0xc0, 0x12, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x03, + 0x08, 0x2d, 0x00, 0x03, 0x10, 0x2d, 0x00, 0x03, 0x18, 0x2d, 0x00, 0x03, 0x20, 0x2d, 0x00, 0x03, 0x7c, 0x18, 0x01, 0x02, 0x80, 0x18, 0x01, 0x02, 0x84, 0x18, 0x01, 0x02, 0x88, 0x18, 0x01, 0x02, + 0x8c, 0x18, 0x01, 0x02, 0x90, 0x18, 0x01, 0x02, 0xf8, 0x35, 0x02, 0x03, 0x00, 0x36, 0x02, 0x03, 0x08, 0x36, 0x02, 0x03, 0x10, 0x36, 0x02, 0x03, 0x18, 0x36, 0x02, 0x03, 0x60, 0x0e, 0x03, 0x03, + 0x68, 0x0e, 0x03, 0x03, 0x70, 0x0e, 0x03, 0x03, 0x20, 0x28, 0x04, 0x04, 0x30, 0x28, 0x04, 0x04, 0x10, 0x05, 0x05, 0x04, 0x40, 0x1c, 0x06, 0x05, 0x00, 0x13, 0x08, 0x06, 0x28, 0x2d, 0x00, 0x03, + 0x30, 0x2d, 0x00, 0x03, 0x38, 0x2d, 0x00, 0x03, 0x40, 0x2d, 0x00, 0x03, 0x48, 0x2d, 0x00, 0x03, 0x94, 0x18, 0x01, 0x02, 0x98, 0x18, 0x01, 0x02, 0x9c, 0x18, 0x01, 0x02, 0xa0, 0x18, 0x01, 0x02, + 0xa4, 0x18, 0x01, 0x02, 0xa8, 0x18, 0x01, 0x02, 0x20, 0x36, 0x02, 0x03, 0x28, 0x36, 0x02, 0x03, 0x30, 0x36, 0x02, 0x03, 0x38, 0x36, 0x02, 0x03, 0x40, 0x36, 0x02, 0x03, 0x78, 0x0e, 0x03, 0x03, + 0x80, 0x0e, 0x03, 0x03, 0x88, 0x0e, 0x03, 0x03, 0x40, 0x28, 0x04, 0x04, 0x50, 0x28, 0x04, 0x04, 0x20, 0x05, 0x05, 0x04, 0x60, 0x1c, 0x06, 0x05, 0x40, 0x13, 0x08, 0x06, 0x50, 0x2d, 0x00, 0x03, + 0x58, 0x2d, 0x00, 0x03, 0x60, 0x2d, 0x00, 0x03, 0x68, 0x2d, 0x00, 0x03, 0xac, 0x18, 0x01, 0x02, 0xb0, 0x18, 0x01, 0x02, 0xb4, 0x18, 0x01, 0x02, 0xb8, 0x18, 0x01, 0x02, 0xbc, 0x18, 0x01, 0x02, + 0xc0, 0x18, 0x01, 0x02, 0xc4, 0x18, 0x01, 0x02, 0x48, 0x36, 0x02, 0x03, 0x50, 0x36, 0x02, 0x03, 0x58, 0x36, 0x02, 0x03, 0x60, 0x36, 0x02, 0x03, 0x68, 0x36, 0x02, 0x03, 0x90, 0x0e, 0x03, 0x03, + 0x98, 0x0e, 0x03, 0x03, 0xa0, 0x0e, 0x03, 0x03, 0x60, 0x28, 0x04, 0x04, 0x70, 0x28, 0x04, 0x04, 0x30, 0x05, 0x05, 0x04, 0x80, 0x1c, 0x06, 0x05, 0x80, 0x13, 0x08, 0x06, 0x70, 0x2d, 0x00, 0x03, + 0x78, 0x2d, 0x00, 0x03, 0x80, 0x2d, 0x00, 0x03, 0x88, 0x2d, 0x00, 0x03, 0xc8, 0x18, 0x01, 0x02, 0xcc, 0x18, 0x01, 0x02, 0xd0, 0x18, 0x01, 0x02, 0xd4, 0x18, 0x01, 0x02, 0xd8, 0x18, 0x01, 0x02, + 0xdc, 0x18, 0x01, 0x02, 0xe0, 0x18, 0x01, 0x02, 0x70, 0x36, 0x02, 0x03, 0x78, 0x36, 0x02, 0x03, 0x80, 0x36, 0x02, 0x03, 0x88, 0x36, 0x02, 0x03, 0x90, 0x36, 0x02, 0x03, 0xa8, 0x0e, 0x03, 0x03, + 0xb0, 0x0e, 0x03, 0x03, 0xb8, 0x0e, 0x03, 0x03, 0x80, 0x28, 0x04, 0x04, 0x40, 0x05, 0x05, 0x04, 0x50, 0x05, 0x05, 0x04, 0xa0, 0x1c, 0x06, 0x05, 0xc0, 0x13, 0x08, 0x06, 0x90, 0x2d, 0x00, 0x03, + 0x98, 0x2d, 0x00, 0x03, 0xa0, 0x2d, 0x00, 0x03, 0xa8, 0x2d, 0x00, 0x03, 0xe4, 0x18, 0x01, 0x02, 0xe8, 0x18, 0x01, 0x02, 0xec, 0x18, 0x01, 0x02, 0xf0, 0x18, 0x01, 0x02, 0xf4, 0x18, 0x01, 0x02, + 0xf8, 0x18, 0x01, 0x02, 0xfc, 0x18, 0x01, 0x02, 0x98, 0x36, 0x02, 0x03, 0xa0, 0x36, 0x02, 0x03, 0xa8, 0x36, 0x02, 0x03, 0xb0, 0x36, 0x02, 0x03, 0xb8, 0x36, 0x02, 0x03, 0xc0, 0x0e, 0x03, 0x03, + 0xc8, 0x0e, 0x03, 0x03, 0xd0, 0x0e, 0x03, 0x03, 0x90, 0x28, 0x04, 0x04, 0x60, 0x05, 0x05, 0x04, 0x70, 0x05, 0x05, 0x04, 0xc0, 0x1c, 0x06, 0x05, 0x00, 0x14, 0x08, 0x06, 0xb0, 0x2d, 0x00, 0x03, + 0xb8, 0x2d, 0x00, 0x03, 0xc0, 0x2d, 0x00, 0x03, 0xc8, 0x2d, 0x00, 0x03, 0x00, 0x19, 0x01, 0x02, 0x04, 0x19, 0x01, 0x02, 0x08, 0x19, 0x01, 0x02, 0x0c, 0x19, 0x01, 0x02, 0x10, 0x19, 0x01, 0x02, + 0x14, 0x19, 0x01, 0x02, 0x18, 0x19, 0x01, 0x02, 0xc0, 0x36, 0x02, 0x03, 0xc8, 0x36, 0x02, 0x03, 0xd0, 0x36, 0x02, 0x03, 0xd8, 0x36, 0x02, 0x03, 0xe0, 0x36, 0x02, 0x03, 0xd8, 0x0e, 0x03, 0x03, + 0xe0, 0x0e, 0x03, 0x03, 0xe8, 0x0e, 0x03, 0x03, 0xa0, 0x28, 0x04, 0x04, 0x80, 0x05, 0x05, 0x04, 0x90, 0x05, 0x05, 0x04, 0xe0, 0x1c, 0x06, 0x05, 0x40, 0x14, 0x08, 0x06, 0xd0, 0x2d, 0x00, 0x03, + 0xd8, 0x2d, 0x00, 0x03, 0xe0, 0x2d, 0x00, 0x03, 0xe8, 0x2d, 0x00, 0x03, 0x1c, 0x19, 0x01, 0x02, 0x20, 0x19, 0x01, 0x02, 0x24, 0x19, 0x01, 0x02, 0x28, 0x19, 0x01, 0x02, 0x2c, 0x19, 0x01, 0x02, + 0x30, 0x19, 0x01, 0x02, 0x34, 0x19, 0x01, 0x02, 0xe8, 0x36, 0x02, 0x03, 0xf0, 0x36, 0x02, 0x03, 0xf8, 0x36, 0x02, 0x03, 0x00, 0x37, 0x02, 0x03, 0x08, 0x37, 0x02, 0x03, 0xf0, 0x0e, 0x03, 0x03, + 0xf8, 0x0e, 0x03, 0x03, 0xb0, 0x28, 0x04, 0x04, 0xc0, 0x28, 0x04, 0x04, 0xa0, 0x05, 0x05, 0x04, 0xb0, 0x05, 0x05, 0x04, 0x00, 0x1d, 0x06, 0x05, 0x80, 0x14, 0x08, 0x06, 0xf0, 0x2d, 0x00, 0x03, + 0xf8, 0x2d, 0x00, 0x03, 0x00, 0x2e, 0x00, 0x03, 0x08, 0x2e, 0x00, 0x03, 0x38, 0x19, 0x01, 0x02, 0x3c, 0x19, 0x01, 0x02, 0x40, 0x19, 0x01, 0x02, 0x44, 0x19, 0x01, 0x02, 0x48, 0x19, 0x01, 0x02, + 0x4c, 0x19, 0x01, 0x02, 0x50, 0x19, 0x01, 0x02, 0x10, 0x37, 0x02, 0x03, 0x18, 0x37, 0x02, 0x03, 0x20, 0x37, 0x02, 0x03, 0x28, 0x37, 0x02, 0x03, 0x30, 0x37, 0x02, 0x03, 0x00, 0x0f, 0x03, 0x03, + 0x08, 0x0f, 0x03, 0x03, 0xd0, 0x28, 0x04, 0x04, 0xe0, 0x28, 0x04, 0x04, 0xc0, 0x05, 0x05, 0x04, 0xd0, 0x05, 0x05, 0x04, 0x20, 0x1d, 0x06, 0x05, 0xc0, 0x14, 0x08, 0x06, 0x10, 0x2e, 0x00, 0x03, + 0x18, 0x2e, 0x00, 0x03, 0x20, 0x2e, 0x00, 0x03, 0x28, 0x2e, 0x00, 0x03, 0x54, 0x19, 0x01, 0x02, 0x58, 0x19, 0x01, 0x02, 0x5c, 0x19, 0x01, 0x02, 0x60, 0x19, 0x01, 0x02, 0x64, 0x19, 0x01, 0x02, + 0x68, 0x19, 0x01, 0x02, 0x6c, 0x19, 0x01, 0x02, 0x38, 0x37, 0x02, 0x03, 0x40, 0x37, 0x02, 0x03, 0x48, 0x37, 0x02, 0x03, 0x50, 0x37, 0x02, 0x03, 0x58, 0x37, 0x02, 0x03, 0x10, 0x0f, 0x03, 0x03, + 0x18, 0x0f, 0x03, 0x03, 0xf0, 0x28, 0x04, 0x04, 0x00, 0x29, 0x04, 0x04, 0xe0, 0x05, 0x05, 0x04, 0xf0, 0x05, 0x05, 0x04, 0x40, 0x1d, 0x06, 0x05, 0x00, 0x15, 0x08, 0x06, 0x30, 0x2e, 0x00, 0x03, + 0x38, 0x2e, 0x00, 0x03, 0x40, 0x2e, 0x00, 0x03, 0x48, 0x2e, 0x00, 0x03, 0x70, 0x19, 0x01, 0x02, 0x74, 0x19, 0x01, 0x02, 0x78, 0x19, 0x01, 0x02, 0x7c, 0x19, 0x01, 0x02, 0x80, 0x19, 0x01, 0x02, + 0x84, 0x19, 0x01, 0x02, 0x88, 0x19, 0x01, 0x02, 0x60, 0x37, 0x02, 0x03, 0x68, 0x37, 0x02, 0x03, 0x70, 0x37, 0x02, 0x03, 0x78, 0x37, 0x02, 0x03, 0x80, 0x37, 0x02, 0x03, 0x20, 0x0f, 0x03, 0x03, + 0x28, 0x0f, 0x03, 0x03, 0x10, 0x29, 0x04, 0x04, 0x20, 0x29, 0x04, 0x04, 0x00, 0x06, 0x05, 0x04, 0x10, 0x06, 0x05, 0x04, 0x60, 0x1d, 0x06, 0x05, 0x40, 0x15, 0x08, 0x06, 0x50, 0x2e, 0x00, 0x03, + 0x58, 0x2e, 0x00, 0x03, 0x60, 0x2e, 0x00, 0x03, 0x68, 0x2e, 0x00, 0x03, 0x8c, 0x19, 0x01, 0x02, 0x90, 0x19, 0x01, 0x02, 0x94, 0x19, 0x01, 0x02, 0x98, 0x19, 0x01, 0x02, 0x9c, 0x19, 0x01, 0x02, + 0xa0, 0x19, 0x01, 0x02, 0xa4, 0x19, 0x01, 0x02, 0x88, 0x37, 0x02, 0x03, 0x90, 0x37, 0x02, 0x03, 0x98, 0x37, 0x02, 0x03, 0xa0, 0x37, 0x02, 0x03, 0xa8, 0x37, 0x02, 0x03, 0x30, 0x0f, 0x03, 0x03, + 0x38, 0x0f, 0x03, 0x03, 0x30, 0x29, 0x04, 0x04, 0x40, 0x29, 0x04, 0x04, 0x20, 0x06, 0x05, 0x04, 0x30, 0x06, 0x05, 0x04, 0x80, 0x1d, 0x06, 0x05, 0x80, 0x15, 0x08, 0x06, 0x70, 0x2e, 0x00, 0x03, + 0x78, 0x2e, 0x00, 0x03, 0x80, 0x2e, 0x00, 0x03, 0x88, 0x2e, 0x00, 0x03, 0xa8, 0x19, 0x01, 0x02, 0xac, 0x19, 0x01, 0x02, 0xb0, 0x19, 0x01, 0x02, 0xb4, 0x19, 0x01, 0x02, 0xb8, 0x19, 0x01, 0x02, + 0xbc, 0x19, 0x01, 0x02, 0xc0, 0x19, 0x01, 0x02, 0xb0, 0x37, 0x02, 0x03, 0xb8, 0x37, 0x02, 0x03, 0xc0, 0x37, 0x02, 0x03, 0xc8, 0x37, 0x02, 0x03, 0x40, 0x0f, 0x03, 0x03, 0x48, 0x0f, 0x03, 0x03, + 0x50, 0x0f, 0x03, 0x03, 0x50, 0x29, 0x04, 0x04, 0x60, 0x29, 0x04, 0x04, 0x40, 0x06, 0x05, 0x04, 0x50, 0x06, 0x05, 0x04, 0xa0, 0x1d, 0x06, 0x05, 0xc0, 0x15, 0x08, 0x06, 0x90, 0x2e, 0x00, 0x03, + 0x98, 0x2e, 0x00, 0x03, 0xa0, 0x2e, 0x00, 0x03, 0xa8, 0x2e, 0x00, 0x03, 0xc4, 0x19, 0x01, 0x02, 0xc8, 0x19, 0x01, 0x02, 0xcc, 0x19, 0x01, 0x02, 0xd0, 0x19, 0x01, 0x02, 0xd4, 0x19, 0x01, 0x02, + 0xd8, 0x19, 0x01, 0x02, 0xdc, 0x19, 0x01, 0x02, 0xd0, 0x37, 0x02, 0x03, 0xd8, 0x37, 0x02, 0x03, 0xe0, 0x37, 0x02, 0x03, 0xe8, 0x37, 0x02, 0x03, 0x58, 0x0f, 0x03, 0x03, 0x60, 0x0f, 0x03, 0x03, + 0x68, 0x0f, 0x03, 0x03, 0x70, 0x29, 0x04, 0x04, 0x80, 0x29, 0x04, 0x04, 0x60, 0x06, 0x05, 0x04, 0x70, 0x06, 0x05, 0x04, 0xc0, 0x1d, 0x06, 0x05, 0x00, 0x16, 0x08, 0x06, 0xb0, 0x2e, 0x00, 0x03, + 0xb8, 0x2e, 0x00, 0x03, 0xc0, 0x2e, 0x00, 0x03, 0xc8, 0x2e, 0x00, 0x03, 0xe0, 0x19, 0x01, 0x02, 0xe4, 0x19, 0x01, 0x02, 0xe8, 0x19, 0x01, 0x02, 0xec, 0x19, 0x01, 0x02, 0xf0, 0x19, 0x01, 0x02, + 0xf4, 0x19, 0x01, 0x02, 0xf8, 0x19, 0x01, 0x02, 0xf0, 0x37, 0x02, 0x03, 0xf8, 0x37, 0x02, 0x03, 0x00, 0x38, 0x02, 0x03, 0x08, 0x38, 0x02, 0x03, 0x70, 0x0f, 0x03, 0x03, 0x78, 0x0f, 0x03, 0x03, + 0x80, 0x0f, 0x03, 0x03, 0x90, 0x29, 0x04, 0x04, 0xa0, 0x29, 0x04, 0x04, 0x80, 0x06, 0x05, 0x04, 0x90, 0x06, 0x05, 0x04, 0xe0, 0x1d, 0x06, 0x05, 0x40, 0x16, 0x08, 0x06, 0xd0, 0x2e, 0x00, 0x03, + 0xd8, 0x2e, 0x00, 0x03, 0xe0, 0x2e, 0x00, 0x03, 0xe8, 0x2e, 0x00, 0x03, 0xfc, 0x19, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x04, 0x1a, 0x01, 0x02, 0x08, 0x1a, 0x01, 0x02, 0x0c, 0x1a, 0x01, 0x02, + 0x10, 0x1a, 0x01, 0x02, 0x14, 0x1a, 0x01, 0x02, 0x10, 0x38, 0x02, 0x03, 0x18, 0x38, 0x02, 0x03, 0x20, 0x38, 0x02, 0x03, 0x28, 0x38, 0x02, 0x03, 0x88, 0x0f, 0x03, 0x03, 0x90, 0x0f, 0x03, 0x03, + 0x98, 0x0f, 0x03, 0x03, 0xb0, 0x29, 0x04, 0x04, 0xc0, 0x29, 0x04, 0x04, 0xa0, 0x06, 0x05, 0x04, 0xb0, 0x06, 0x05, 0x04, 0x00, 0x1e, 0x06, 0x05, 0x00, 0x2b, 0x09, 0x07, 0xf0, 0x2e, 0x00, 0x03, + 0xf8, 0x2e, 0x00, 0x03, 0x00, 0x2f, 0x00, 0x03, 0x08, 0x2f, 0x00, 0x03, 0x18, 0x1a, 0x01, 0x02, 0x1c, 0x1a, 0x01, 0x02, 0x20, 0x1a, 0x01, 0x02, 0x24, 0x1a, 0x01, 0x02, 0x28, 0x1a, 0x01, 0x02, + 0x2c, 0x1a, 0x01, 0x02, 0x30, 0x1a, 0x01, 0x02, 0x30, 0x38, 0x02, 0x03, 0x38, 0x38, 0x02, 0x03, 0x40, 0x38, 0x02, 0x03, 0x48, 0x38, 0x02, 0x03, 0xa0, 0x0f, 0x03, 0x03, 0xa8, 0x0f, 0x03, 0x03, + 0xb0, 0x0f, 0x03, 0x03, 0xd0, 0x29, 0x04, 0x04, 0xe0, 0x29, 0x04, 0x04, 0xc0, 0x06, 0x05, 0x04, 0xd0, 0x06, 0x05, 0x04, 0x20, 0x1e, 0x06, 0x05, 0x80, 0x2b, 0x09, 0x07, 0x10, 0x2f, 0x00, 0x03, + 0x18, 0x2f, 0x00, 0x03, 0x20, 0x2f, 0x00, 0x03, 0x28, 0x2f, 0x00, 0x03, 0x34, 0x1a, 0x01, 0x02, 0x38, 0x1a, 0x01, 0x02, 0x3c, 0x1a, 0x01, 0x02, 0x40, 0x1a, 0x01, 0x02, 0x44, 0x1a, 0x01, 0x02, + 0x48, 0x1a, 0x01, 0x02, 0x4c, 0x1a, 0x01, 0x02, 0x50, 0x38, 0x02, 0x03, 0x58, 0x38, 0x02, 0x03, 0x60, 0x38, 0x02, 0x03, 0x68, 0x38, 0x02, 0x03, 0xb8, 0x0f, 0x03, 0x03, 0xc0, 0x0f, 0x03, 0x03, + 0xc8, 0x0f, 0x03, 0x03, 0xf0, 0x29, 0x04, 0x04, 0x00, 0x2a, 0x04, 0x04, 0xe0, 0x06, 0x05, 0x04, 0xf0, 0x06, 0x05, 0x04, 0x40, 0x1e, 0x06, 0x05, 0x00, 0x2c, 0x09, 0x07, 0x30, 0x2f, 0x00, 0x03, + 0x38, 0x2f, 0x00, 0x03, 0x40, 0x2f, 0x00, 0x03, 0x48, 0x2f, 0x00, 0x03, 0x50, 0x1a, 0x01, 0x02, 0x54, 0x1a, 0x01, 0x02, 0x58, 0x1a, 0x01, 0x02, 0x5c, 0x1a, 0x01, 0x02, 0x60, 0x1a, 0x01, 0x02, + 0x64, 0x1a, 0x01, 0x02, 0x68, 0x1a, 0x01, 0x02, 0x70, 0x38, 0x02, 0x03, 0x78, 0x38, 0x02, 0x03, 0x80, 0x38, 0x02, 0x03, 0x88, 0x38, 0x02, 0x03, 0xd0, 0x0f, 0x03, 0x03, 0xd8, 0x0f, 0x03, 0x03, + 0xe0, 0x0f, 0x03, 0x03, 0x10, 0x2a, 0x04, 0x04, 0x20, 0x2a, 0x04, 0x04, 0x00, 0x07, 0x05, 0x04, 0x10, 0x07, 0x05, 0x04, 0x00, 0x39, 0x07, 0x06, 0x80, 0x2c, 0x09, 0x07, 0x50, 0x2f, 0x00, 0x03, + 0x58, 0x2f, 0x00, 0x03, 0x60, 0x2f, 0x00, 0x03, 0x68, 0x2f, 0x00, 0x03, 0x6c, 0x1a, 0x01, 0x02, 0x70, 0x1a, 0x01, 0x02, 0x74, 0x1a, 0x01, 0x02, 0x78, 0x1a, 0x01, 0x02, 0x7c, 0x1a, 0x01, 0x02, + 0x80, 0x1a, 0x01, 0x02, 0x84, 0x1a, 0x01, 0x02, 0x90, 0x38, 0x02, 0x03, 0x98, 0x38, 0x02, 0x03, 0xa0, 0x38, 0x02, 0x03, 0xa8, 0x38, 0x02, 0x03, 0xe8, 0x0f, 0x03, 0x03, 0xf0, 0x0f, 0x03, 0x03, + 0xf8, 0x0f, 0x03, 0x03, 0x30, 0x2a, 0x04, 0x04, 0x40, 0x2a, 0x04, 0x04, 0x20, 0x07, 0x05, 0x04, 0x30, 0x07, 0x05, 0x04, 0x40, 0x39, 0x07, 0x06, 0x00, 0x2d, 0x09, 0x07, 0x70, 0x2f, 0x00, 0x03, + 0x78, 0x2f, 0x00, 0x03, 0x80, 0x2f, 0x00, 0x03, 0x88, 0x2f, 0x00, 0x03, 0x88, 0x1a, 0x01, 0x02, 0x8c, 0x1a, 0x01, 0x02, 0x90, 0x1a, 0x01, 0x02, 0x94, 0x1a, 0x01, 0x02, 0x98, 0x1a, 0x01, 0x02, + 0x9c, 0x1a, 0x01, 0x02, 0xa0, 0x1a, 0x01, 0x02, 0xb0, 0x38, 0x02, 0x03, 0xb8, 0x38, 0x02, 0x03, 0xc0, 0x38, 0x02, 0x03, 0xc8, 0x38, 0x02, 0x03, 0x00, 0x10, 0x03, 0x03, 0x08, 0x10, 0x03, 0x03, + 0x10, 0x10, 0x03, 0x03, 0x50, 0x2a, 0x04, 0x04, 0x60, 0x2a, 0x04, 0x04, 0x40, 0x07, 0x05, 0x04, 0x50, 0x07, 0x05, 0x04, 0x80, 0x39, 0x07, 0x06, 0x80, 0x2d, 0x09, 0x07, 0x90, 0x2f, 0x00, 0x03, + 0x98, 0x2f, 0x00, 0x03, 0xa0, 0x2f, 0x00, 0x03, 0xa8, 0x2f, 0x00, 0x03, 0xa4, 0x1a, 0x01, 0x02, 0xa8, 0x1a, 0x01, 0x02, 0xac, 0x1a, 0x01, 0x02, 0xb0, 0x1a, 0x01, 0x02, 0xb4, 0x1a, 0x01, 0x02, + 0xb8, 0x1a, 0x01, 0x02, 0xbc, 0x1a, 0x01, 0x02, 0xd0, 0x38, 0x02, 0x03, 0xd8, 0x38, 0x02, 0x03, 0xe0, 0x38, 0x02, 0x03, 0xe8, 0x38, 0x02, 0x03, 0x18, 0x10, 0x03, 0x03, 0x20, 0x10, 0x03, 0x03, + 0x28, 0x10, 0x03, 0x03, 0x70, 0x2a, 0x04, 0x04, 0x80, 0x2a, 0x04, 0x04, 0x60, 0x07, 0x05, 0x04, 0x70, 0x07, 0x05, 0x04, 0xc0, 0x39, 0x07, 0x06, 0x00, 0x2e, 0x09, 0x07, 0xb0, 0x2f, 0x00, 0x03, + 0xb8, 0x2f, 0x00, 0x03, 0xc0, 0x2f, 0x00, 0x03, 0xc8, 0x2f, 0x00, 0x03, 0xc0, 0x1a, 0x01, 0x02, 0xc4, 0x1a, 0x01, 0x02, 0xc8, 0x1a, 0x01, 0x02, 0xcc, 0x1a, 0x01, 0x02, 0xd0, 0x1a, 0x01, 0x02, + 0xd4, 0x1a, 0x01, 0x02, 0xd8, 0x1a, 0x01, 0x02, 0xf0, 0x38, 0x02, 0x03, 0xf8, 0x38, 0x02, 0x03, 0x00, 0x39, 0x02, 0x03, 0x08, 0x39, 0x02, 0x03, 0x30, 0x10, 0x03, 0x03, 0x38, 0x10, 0x03, 0x03, + 0x40, 0x10, 0x03, 0x03, 0x90, 0x2a, 0x04, 0x04, 0xa0, 0x2a, 0x04, 0x04, 0x80, 0x07, 0x05, 0x04, 0x90, 0x07, 0x05, 0x04, 0x00, 0x3a, 0x07, 0x06, 0x80, 0x2e, 0x09, 0x07, 0xd0, 0x2f, 0x00, 0x03, + 0xd8, 0x2f, 0x00, 0x03, 0xe0, 0x2f, 0x00, 0x03, 0xe8, 0x2f, 0x00, 0x03, 0xdc, 0x1a, 0x01, 0x02, 0xe0, 0x1a, 0x01, 0x02, 0xe4, 0x1a, 0x01, 0x02, 0xe8, 0x1a, 0x01, 0x02, 0xec, 0x1a, 0x01, 0x02, + 0xf0, 0x1a, 0x01, 0x02, 0xf4, 0x1a, 0x01, 0x02, 0x10, 0x39, 0x02, 0x03, 0x18, 0x39, 0x02, 0x03, 0x20, 0x39, 0x02, 0x03, 0x28, 0x39, 0x02, 0x03, 0x48, 0x10, 0x03, 0x03, 0x50, 0x10, 0x03, 0x03, + 0x58, 0x10, 0x03, 0x03, 0xb0, 0x2a, 0x04, 0x04, 0xc0, 0x2a, 0x04, 0x04, 0xa0, 0x07, 0x05, 0x04, 0xb0, 0x07, 0x05, 0x04, 0x40, 0x3a, 0x07, 0x06, 0x00, 0x2f, 0x09, 0x07, 0xf0, 0x2f, 0x00, 0x03, + 0xf8, 0x2f, 0x00, 0x03, 0x00, 0x30, 0x00, 0x03, 0x08, 0x30, 0x00, 0x03, 0xf8, 0x1a, 0x01, 0x02, 0xfc, 0x1a, 0x01, 0x02, 0x00, 0x1b, 0x01, 0x02, 0x04, 0x1b, 0x01, 0x02, 0x08, 0x1b, 0x01, 0x02, + 0x0c, 0x1b, 0x01, 0x02, 0x10, 0x1b, 0x01, 0x02, 0x30, 0x39, 0x02, 0x03, 0x38, 0x39, 0x02, 0x03, 0x40, 0x39, 0x02, 0x03, 0x48, 0x39, 0x02, 0x03, 0x60, 0x10, 0x03, 0x03, 0x68, 0x10, 0x03, 0x03, + 0x70, 0x10, 0x03, 0x03, 0xd0, 0x2a, 0x04, 0x04, 0xe0, 0x2a, 0x04, 0x04, 0xc0, 0x07, 0x05, 0x04, 0xd0, 0x07, 0x05, 0x04, 0x80, 0x3a, 0x07, 0x06, 0x80, 0x2f, 0x09, 0x07, 0x10, 0x30, 0x00, 0x03, + 0x18, 0x30, 0x00, 0x03, 0x20, 0x30, 0x00, 0x03, 0x28, 0x30, 0x00, 0x03, 0x14, 0x1b, 0x01, 0x02, 0x18, 0x1b, 0x01, 0x02, 0x1c, 0x1b, 0x01, 0x02, 0x20, 0x1b, 0x01, 0x02, 0x24, 0x1b, 0x01, 0x02, + 0x28, 0x1b, 0x01, 0x02, 0x2c, 0x1b, 0x01, 0x02, 0x50, 0x39, 0x02, 0x03, 0x58, 0x39, 0x02, 0x03, 0x60, 0x39, 0x02, 0x03, 0x68, 0x39, 0x02, 0x03, 0x78, 0x10, 0x03, 0x03, 0x80, 0x10, 0x03, 0x03, + 0x88, 0x10, 0x03, 0x03, 0xf0, 0x2a, 0x04, 0x04, 0x00, 0x2b, 0x04, 0x04, 0xe0, 0x07, 0x05, 0x04, 0xf0, 0x07, 0x05, 0x04, 0xc0, 0x3a, 0x07, 0x06, 0x00, 0x30, 0x09, 0x07, 0x30, 0x30, 0x00, 0x03, + 0x38, 0x30, 0x00, 0x03, 0x40, 0x30, 0x00, 0x03, 0x48, 0x30, 0x00, 0x03, 0x30, 0x1b, 0x01, 0x02, 0x34, 0x1b, 0x01, 0x02, 0x38, 0x1b, 0x01, 0x02, 0x3c, 0x1b, 0x01, 0x02, 0x40, 0x1b, 0x01, 0x02, + 0x44, 0x1b, 0x01, 0x02, 0x48, 0x1b, 0x01, 0x02, 0x70, 0x39, 0x02, 0x03, 0x78, 0x39, 0x02, 0x03, 0x80, 0x39, 0x02, 0x03, 0x88, 0x39, 0x02, 0x03, 0x90, 0x10, 0x03, 0x03, 0x98, 0x10, 0x03, 0x03, + 0xa0, 0x10, 0x03, 0x03, 0x10, 0x2b, 0x04, 0x04, 0x20, 0x2b, 0x04, 0x04, 0x00, 0x08, 0x05, 0x04, 0x10, 0x08, 0x05, 0x04, 0x00, 0x3b, 0x07, 0x06, 0x80, 0x30, 0x09, 0x07, 0x50, 0x30, 0x00, 0x03, + 0x58, 0x30, 0x00, 0x03, 0x60, 0x30, 0x00, 0x03, 0x68, 0x30, 0x00, 0x03, 0x4c, 0x1b, 0x01, 0x02, 0x50, 0x1b, 0x01, 0x02, 0x54, 0x1b, 0x01, 0x02, 0x58, 0x1b, 0x01, 0x02, 0x5c, 0x1b, 0x01, 0x02, + 0x60, 0x1b, 0x01, 0x02, 0x64, 0x1b, 0x01, 0x02, 0x90, 0x39, 0x02, 0x03, 0x98, 0x39, 0x02, 0x03, 0xa0, 0x39, 0x02, 0x03, 0xa8, 0x39, 0x02, 0x03, 0xa8, 0x10, 0x03, 0x03, 0xb0, 0x10, 0x03, 0x03, + 0xb8, 0x10, 0x03, 0x03, 0x30, 0x2b, 0x04, 0x04, 0x40, 0x2b, 0x04, 0x04, 0x20, 0x08, 0x05, 0x04, 0x30, 0x08, 0x05, 0x04, 0x40, 0x3b, 0x07, 0x06, 0x00, 0x31, 0x09, 0x07, 0x70, 0x30, 0x00, 0x03, + 0x78, 0x30, 0x00, 0x03, 0x80, 0x30, 0x00, 0x03, 0x88, 0x30, 0x00, 0x03, 0x68, 0x1b, 0x01, 0x02, 0x6c, 0x1b, 0x01, 0x02, 0x70, 0x1b, 0x01, 0x02, 0x74, 0x1b, 0x01, 0x02, 0x78, 0x1b, 0x01, 0x02, + 0x7c, 0x1b, 0x01, 0x02, 0x80, 0x1b, 0x01, 0x02, 0xb0, 0x39, 0x02, 0x03, 0xb8, 0x39, 0x02, 0x03, 0xc0, 0x39, 0x02, 0x03, 0xc8, 0x39, 0x02, 0x03, 0xc0, 0x10, 0x03, 0x03, 0xc8, 0x10, 0x03, 0x03, + 0xd0, 0x10, 0x03, 0x03, 0x50, 0x2b, 0x04, 0x04, 0x60, 0x2b, 0x04, 0x04, 0x40, 0x08, 0x05, 0x04, 0x50, 0x08, 0x05, 0x04, 0x80, 0x3b, 0x07, 0x06, 0x80, 0x31, 0x09, 0x07, 0x90, 0x30, 0x00, 0x03, + 0x98, 0x30, 0x00, 0x03, 0xa0, 0x30, 0x00, 0x03, 0xa8, 0x30, 0x00, 0x03, 0x84, 0x1b, 0x01, 0x02, 0x88, 0x1b, 0x01, 0x02, 0x8c, 0x1b, 0x01, 0x02, 0x90, 0x1b, 0x01, 0x02, 0x94, 0x1b, 0x01, 0x02, + 0x98, 0x1b, 0x01, 0x02, 0x9c, 0x1b, 0x01, 0x02, 0xd0, 0x39, 0x02, 0x03, 0xd8, 0x39, 0x02, 0x03, 0xe0, 0x39, 0x02, 0x03, 0xe8, 0x39, 0x02, 0x03, 0xd8, 0x10, 0x03, 0x03, 0xe0, 0x10, 0x03, 0x03, + 0xe8, 0x10, 0x03, 0x03, 0x70, 0x2b, 0x04, 0x04, 0x80, 0x2b, 0x04, 0x04, 0x60, 0x08, 0x05, 0x04, 0x70, 0x08, 0x05, 0x04, 0xc0, 0x3b, 0x07, 0x06, 0x00, 0x32, 0x09, 0x07, 0xb0, 0x30, 0x00, 0x03, + 0xb8, 0x30, 0x00, 0x03, 0xc0, 0x30, 0x00, 0x03, 0xc8, 0x30, 0x00, 0x03, 0xa0, 0x1b, 0x01, 0x02, 0xa4, 0x1b, 0x01, 0x02, 0xa8, 0x1b, 0x01, 0x02, 0xac, 0x1b, 0x01, 0x02, 0xb0, 0x1b, 0x01, 0x02, + 0xb4, 0x1b, 0x01, 0x02, 0xb8, 0x1b, 0x01, 0x02, 0xf0, 0x39, 0x02, 0x03, 0xf8, 0x39, 0x02, 0x03, 0x00, 0x3a, 0x02, 0x03, 0x08, 0x3a, 0x02, 0x03, 0xf0, 0x10, 0x03, 0x03, 0xf8, 0x10, 0x03, 0x03, + 0x00, 0x11, 0x03, 0x03, 0x90, 0x2b, 0x04, 0x04, 0xa0, 0x2b, 0x04, 0x04, 0x80, 0x08, 0x05, 0x04, 0x60, 0x1e, 0x06, 0x05, 0x00, 0x3c, 0x07, 0x06, 0x80, 0x32, 0x09, 0x07, 0xd0, 0x30, 0x00, 0x03, + 0xd8, 0x30, 0x00, 0x03, 0xe0, 0x30, 0x00, 0x03, 0xe8, 0x30, 0x00, 0x03, 0xbc, 0x1b, 0x01, 0x02, 0xc0, 0x1b, 0x01, 0x02, 0xc4, 0x1b, 0x01, 0x02, 0xc8, 0x1b, 0x01, 0x02, 0xcc, 0x1b, 0x01, 0x02, + 0xd0, 0x1b, 0x01, 0x02, 0xd4, 0x1b, 0x01, 0x02, 0x10, 0x3a, 0x02, 0x03, 0x18, 0x3a, 0x02, 0x03, 0x20, 0x3a, 0x02, 0x03, 0x28, 0x3a, 0x02, 0x03, 0x08, 0x11, 0x03, 0x03, 0x10, 0x11, 0x03, 0x03, + 0x18, 0x11, 0x03, 0x03, 0xb0, 0x2b, 0x04, 0x04, 0xc0, 0x2b, 0x04, 0x04, 0x90, 0x08, 0x05, 0x04, 0x80, 0x1e, 0x06, 0x05, 0x40, 0x3c, 0x07, 0x06, 0x00, 0x33, 0x09, 0x07, 0xf0, 0x30, 0x00, 0x03, + 0xf8, 0x30, 0x00, 0x03, 0x00, 0x31, 0x00, 0x03, 0x08, 0x31, 0x00, 0x03, 0xd8, 0x1b, 0x01, 0x02, 0xdc, 0x1b, 0x01, 0x02, 0xe0, 0x1b, 0x01, 0x02, 0xe4, 0x1b, 0x01, 0x02, 0xe8, 0x1b, 0x01, 0x02, + 0xec, 0x1b, 0x01, 0x02, 0xf0, 0x1b, 0x01, 0x02, 0x30, 0x3a, 0x02, 0x03, 0x38, 0x3a, 0x02, 0x03, 0x40, 0x3a, 0x02, 0x03, 0x48, 0x3a, 0x02, 0x03, 0x20, 0x11, 0x03, 0x03, 0x28, 0x11, 0x03, 0x03, + 0x30, 0x11, 0x03, 0x03, 0xd0, 0x2b, 0x04, 0x04, 0xe0, 0x2b, 0x04, 0x04, 0xa0, 0x08, 0x05, 0x04, 0xa0, 0x1e, 0x06, 0x05, 0x80, 0x3c, 0x07, 0x06, 0x80, 0x33, 0x09, 0x07, 0x10, 0x31, 0x00, 0x03, + 0x18, 0x31, 0x00, 0x03, 0x20, 0x31, 0x00, 0x03, 0x28, 0x31, 0x00, 0x03, 0xf4, 0x1b, 0x01, 0x02, 0xf8, 0x1b, 0x01, 0x02, 0xfc, 0x1b, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x04, 0x1c, 0x01, 0x02, + 0x08, 0x1c, 0x01, 0x02, 0x0c, 0x1c, 0x01, 0x02, 0x50, 0x3a, 0x02, 0x03, 0x58, 0x3a, 0x02, 0x03, 0x60, 0x3a, 0x02, 0x03, 0x68, 0x3a, 0x02, 0x03, 0x38, 0x11, 0x03, 0x03, 0x40, 0x11, 0x03, 0x03, + 0x48, 0x11, 0x03, 0x03, 0xf0, 0x2b, 0x04, 0x04, 0x00, 0x2c, 0x04, 0x04, 0xb0, 0x08, 0x05, 0x04, 0xc0, 0x1e, 0x06, 0x05, 0xc0, 0x3c, 0x07, 0x06, 0x00, 0x34, 0x09, 0x07, 0x30, 0x31, 0x00, 0x03, + 0x38, 0x31, 0x00, 0x03, 0x40, 0x31, 0x00, 0x03, 0x48, 0x31, 0x00, 0x03, 0x10, 0x1c, 0x01, 0x02, 0x14, 0x1c, 0x01, 0x02, 0x18, 0x1c, 0x01, 0x02, 0x1c, 0x1c, 0x01, 0x02, 0x20, 0x1c, 0x01, 0x02, + 0x24, 0x1c, 0x01, 0x02, 0x28, 0x1c, 0x01, 0x02, 0x70, 0x3a, 0x02, 0x03, 0x78, 0x3a, 0x02, 0x03, 0x80, 0x3a, 0x02, 0x03, 0x88, 0x3a, 0x02, 0x03, 0x50, 0x11, 0x03, 0x03, 0x58, 0x11, 0x03, 0x03, + 0x60, 0x11, 0x03, 0x03, 0x10, 0x2c, 0x04, 0x04, 0x20, 0x2c, 0x04, 0x04, 0xc0, 0x08, 0x05, 0x04, 0xe0, 0x1e, 0x06, 0x05, 0x00, 0x3d, 0x07, 0x06, 0x80, 0x34, 0x09, 0x07, 0x50, 0x31, 0x00, 0x03, + 0x58, 0x31, 0x00, 0x03, 0x60, 0x31, 0x00, 0x03, 0x68, 0x31, 0x00, 0x03, 0x2c, 0x1c, 0x01, 0x02, 0x30, 0x1c, 0x01, 0x02, 0x34, 0x1c, 0x01, 0x02, 0x38, 0x1c, 0x01, 0x02, 0x3c, 0x1c, 0x01, 0x02, + 0x40, 0x1c, 0x01, 0x02, 0x44, 0x1c, 0x01, 0x02, 0x90, 0x3a, 0x02, 0x03, 0x98, 0x3a, 0x02, 0x03, 0xa0, 0x3a, 0x02, 0x03, 0xa8, 0x3a, 0x02, 0x03, 0x68, 0x11, 0x03, 0x03, 0x70, 0x11, 0x03, 0x03, + 0x78, 0x11, 0x03, 0x03, 0x30, 0x2c, 0x04, 0x04, 0x40, 0x2c, 0x04, 0x04, 0xd0, 0x08, 0x05, 0x04, 0x00, 0x1f, 0x06, 0x05, 0x40, 0x3d, 0x07, 0x06, 0x00, 0x35, 0x09, 0x07, 0x70, 0x31, 0x00, 0x03, + 0x78, 0x31, 0x00, 0x03, 0x80, 0x31, 0x00, 0x03, 0x88, 0x31, 0x00, 0x03, 0x48, 0x1c, 0x01, 0x02, 0x4c, 0x1c, 0x01, 0x02, 0x50, 0x1c, 0x01, 0x02, 0x54, 0x1c, 0x01, 0x02, 0x58, 0x1c, 0x01, 0x02, + 0x5c, 0x1c, 0x01, 0x02, 0x60, 0x1c, 0x01, 0x02, 0xb0, 0x3a, 0x02, 0x03, 0xb8, 0x3a, 0x02, 0x03, 0xc0, 0x3a, 0x02, 0x03, 0xc8, 0x3a, 0x02, 0x03, 0x80, 0x11, 0x03, 0x03, 0x88, 0x11, 0x03, 0x03, + 0x90, 0x11, 0x03, 0x03, 0x50, 0x2c, 0x04, 0x04, 0x60, 0x2c, 0x04, 0x04, 0xe0, 0x08, 0x05, 0x04, 0x20, 0x1f, 0x06, 0x05, 0x80, 0x3d, 0x07, 0x06, 0x00, 0x07, 0x0a, 0x07, 0x90, 0x31, 0x00, 0x03, + 0x98, 0x31, 0x00, 0x03, 0xa0, 0x31, 0x00, 0x03, 0xa8, 0x31, 0x00, 0x03, 0x64, 0x1c, 0x01, 0x02, 0x68, 0x1c, 0x01, 0x02, 0x6c, 0x1c, 0x01, 0x02, 0x70, 0x1c, 0x01, 0x02, 0x74, 0x1c, 0x01, 0x02, + 0x78, 0x1c, 0x01, 0x02, 0x7c, 0x1c, 0x01, 0x02, 0xd0, 0x3a, 0x02, 0x03, 0xd8, 0x3a, 0x02, 0x03, 0xe0, 0x3a, 0x02, 0x03, 0xe8, 0x3a, 0x02, 0x03, 0x98, 0x11, 0x03, 0x03, 0xa0, 0x11, 0x03, 0x03, + 0xa8, 0x11, 0x03, 0x03, 0x70, 0x2c, 0x04, 0x04, 0x80, 0x2c, 0x04, 0x04, 0xf0, 0x08, 0x05, 0x04, 0x40, 0x1f, 0x06, 0x05, 0xc0, 0x3d, 0x07, 0x06, 0x80, 0x07, 0x0a, 0x07, 0xb0, 0x31, 0x00, 0x03, + 0xb8, 0x31, 0x00, 0x03, 0xc0, 0x31, 0x00, 0x03, 0xc8, 0x31, 0x00, 0x03, 0x80, 0x1c, 0x01, 0x02, 0x84, 0x1c, 0x01, 0x02, 0x88, 0x1c, 0x01, 0x02, 0x8c, 0x1c, 0x01, 0x02, 0x90, 0x1c, 0x01, 0x02, + 0x94, 0x1c, 0x01, 0x02, 0x98, 0x1c, 0x01, 0x02, 0xf0, 0x3a, 0x02, 0x03, 0xf8, 0x3a, 0x02, 0x03, 0x00, 0x3b, 0x02, 0x03, 0x08, 0x3b, 0x02, 0x03, 0xb0, 0x11, 0x03, 0x03, 0xb8, 0x11, 0x03, 0x03, + 0xc0, 0x11, 0x03, 0x03, 0x90, 0x2c, 0x04, 0x04, 0xa0, 0x2c, 0x04, 0x04, 0x00, 0x09, 0x05, 0x04, 0x60, 0x1f, 0x06, 0x05, 0x00, 0x3e, 0x07, 0x06, 0x00, 0x08, 0x0a, 0x07, 0xd0, 0x31, 0x00, 0x03, + 0xd8, 0x31, 0x00, 0x03, 0xe0, 0x31, 0x00, 0x03, 0xe8, 0x31, 0x00, 0x03, 0x9c, 0x1c, 0x01, 0x02, 0xa0, 0x1c, 0x01, 0x02, 0xa4, 0x1c, 0x01, 0x02, 0xa8, 0x1c, 0x01, 0x02, 0xac, 0x1c, 0x01, 0x02, + 0xb0, 0x1c, 0x01, 0x02, 0xb4, 0x1c, 0x01, 0x02, 0x10, 0x3b, 0x02, 0x03, 0x18, 0x3b, 0x02, 0x03, 0x20, 0x3b, 0x02, 0x03, 0x28, 0x3b, 0x02, 0x03, 0xc8, 0x11, 0x03, 0x03, 0xd0, 0x11, 0x03, 0x03, + 0xd8, 0x11, 0x03, 0x03, 0xb0, 0x2c, 0x04, 0x04, 0xc0, 0x2c, 0x04, 0x04, 0x10, 0x09, 0x05, 0x04, 0x80, 0x1f, 0x06, 0x05, 0x40, 0x3e, 0x07, 0x06, 0x80, 0x08, 0x0a, 0x07, 0xf0, 0x31, 0x00, 0x03, + 0xf8, 0x31, 0x00, 0x03, 0x00, 0x32, 0x00, 0x03, 0x08, 0x32, 0x00, 0x03, 0xb8, 0x1c, 0x01, 0x02, 0xbc, 0x1c, 0x01, 0x02, 0xc0, 0x1c, 0x01, 0x02, 0xc4, 0x1c, 0x01, 0x02, 0xc8, 0x1c, 0x01, 0x02, + 0xcc, 0x1c, 0x01, 0x02, 0xd0, 0x1c, 0x01, 0x02, 0x30, 0x3b, 0x02, 0x03, 0x38, 0x3b, 0x02, 0x03, 0x40, 0x3b, 0x02, 0x03, 0x48, 0x3b, 0x02, 0x03, 0xe0, 0x11, 0x03, 0x03, 0xe8, 0x11, 0x03, 0x03, + 0xf0, 0x11, 0x03, 0x03, 0xd0, 0x2c, 0x04, 0x04, 0xe0, 0x2c, 0x04, 0x04, 0x20, 0x09, 0x05, 0x04, 0xa0, 0x1f, 0x06, 0x05, 0x80, 0x3e, 0x07, 0x06, 0x00, 0x09, 0x0a, 0x07, 0x10, 0x32, 0x00, 0x03, + 0x18, 0x32, 0x00, 0x03, 0x20, 0x32, 0x00, 0x03, 0x28, 0x32, 0x00, 0x03, 0xd4, 0x1c, 0x01, 0x02, 0xd8, 0x1c, 0x01, 0x02, 0xdc, 0x1c, 0x01, 0x02, 0xe0, 0x1c, 0x01, 0x02, 0xe4, 0x1c, 0x01, 0x02, + 0xe8, 0x1c, 0x01, 0x02, 0xec, 0x1c, 0x01, 0x02, 0x50, 0x3b, 0x02, 0x03, 0x58, 0x3b, 0x02, 0x03, 0x60, 0x3b, 0x02, 0x03, 0x68, 0x3b, 0x02, 0x03, 0xf8, 0x11, 0x03, 0x03, 0x00, 0x12, 0x03, 0x03, + 0x08, 0x12, 0x03, 0x03, 0xf0, 0x2c, 0x04, 0x04, 0x00, 0x2d, 0x04, 0x04, 0x30, 0x09, 0x05, 0x04, 0xc0, 0x1f, 0x06, 0x05, 0xc0, 0x3e, 0x07, 0x06, 0x80, 0x09, 0x0a, 0x07, 0x30, 0x32, 0x00, 0x03, + 0x38, 0x32, 0x00, 0x03, 0x40, 0x32, 0x00, 0x03, 0x48, 0x32, 0x00, 0x03, 0xf0, 0x1c, 0x01, 0x02, 0xf4, 0x1c, 0x01, 0x02, 0xf8, 0x1c, 0x01, 0x02, 0xfc, 0x1c, 0x01, 0x02, 0x00, 0x1d, 0x01, 0x02, + 0x04, 0x1d, 0x01, 0x02, 0x08, 0x1d, 0x01, 0x02, 0x70, 0x3b, 0x02, 0x03, 0x78, 0x3b, 0x02, 0x03, 0x80, 0x3b, 0x02, 0x03, 0x88, 0x3b, 0x02, 0x03, 0x10, 0x12, 0x03, 0x03, 0x18, 0x12, 0x03, 0x03, + 0x20, 0x12, 0x03, 0x03, 0x10, 0x2d, 0x04, 0x04, 0x20, 0x2d, 0x04, 0x04, 0x40, 0x09, 0x05, 0x04, 0xe0, 0x1f, 0x06, 0x05, 0x00, 0x3f, 0x07, 0x06, 0x00, 0x0a, 0x0a, 0x07, 0x50, 0x32, 0x00, 0x03, + 0x58, 0x32, 0x00, 0x03, 0x60, 0x32, 0x00, 0x03, 0x68, 0x32, 0x00, 0x03, 0x0c, 0x1d, 0x01, 0x02, 0x10, 0x1d, 0x01, 0x02, 0x14, 0x1d, 0x01, 0x02, 0x18, 0x1d, 0x01, 0x02, 0x1c, 0x1d, 0x01, 0x02, + 0x20, 0x1d, 0x01, 0x02, 0x24, 0x1d, 0x01, 0x02, 0x90, 0x3b, 0x02, 0x03, 0x98, 0x3b, 0x02, 0x03, 0xa0, 0x3b, 0x02, 0x03, 0xa8, 0x3b, 0x02, 0x03, 0x28, 0x12, 0x03, 0x03, 0x30, 0x12, 0x03, 0x03, + 0x38, 0x12, 0x03, 0x03, 0x30, 0x2d, 0x04, 0x04, 0x40, 0x2d, 0x04, 0x04, 0x50, 0x09, 0x05, 0x04, 0x00, 0x20, 0x06, 0x05, 0x40, 0x3f, 0x07, 0x06, 0x80, 0x0a, 0x0a, 0x07, 0x70, 0x32, 0x00, 0x03, + 0x78, 0x32, 0x00, 0x03, 0x80, 0x32, 0x00, 0x03, 0x88, 0x32, 0x00, 0x03, 0x28, 0x1d, 0x01, 0x02, 0x2c, 0x1d, 0x01, 0x02, 0x30, 0x1d, 0x01, 0x02, 0x34, 0x1d, 0x01, 0x02, 0x38, 0x1d, 0x01, 0x02, + 0x3c, 0x1d, 0x01, 0x02, 0x40, 0x1d, 0x01, 0x02, 0xb0, 0x3b, 0x02, 0x03, 0xb8, 0x3b, 0x02, 0x03, 0xc0, 0x3b, 0x02, 0x03, 0xc8, 0x3b, 0x02, 0x03, 0x40, 0x12, 0x03, 0x03, 0x48, 0x12, 0x03, 0x03, + 0x50, 0x12, 0x03, 0x03, 0x50, 0x2d, 0x04, 0x04, 0x60, 0x2d, 0x04, 0x04, 0x60, 0x09, 0x05, 0x04, 0x20, 0x20, 0x06, 0x05, 0x80, 0x3f, 0x07, 0x06, 0x00, 0x0b, 0x0a, 0x07, 0x90, 0x32, 0x00, 0x03, + 0x98, 0x32, 0x00, 0x03, 0xa0, 0x32, 0x00, 0x03, 0xa8, 0x32, 0x00, 0x03, 0x44, 0x1d, 0x01, 0x02, 0x48, 0x1d, 0x01, 0x02, 0x4c, 0x1d, 0x01, 0x02, 0x50, 0x1d, 0x01, 0x02, 0x54, 0x1d, 0x01, 0x02, + 0x58, 0x1d, 0x01, 0x02, 0x5c, 0x1d, 0x01, 0x02, 0xd0, 0x3b, 0x02, 0x03, 0xd8, 0x3b, 0x02, 0x03, 0xe0, 0x3b, 0x02, 0x03, 0xe8, 0x3b, 0x02, 0x03, 0x58, 0x12, 0x03, 0x03, 0x60, 0x12, 0x03, 0x03, + 0x68, 0x12, 0x03, 0x03, 0x70, 0x2d, 0x04, 0x04, 0x80, 0x2d, 0x04, 0x04, 0x70, 0x09, 0x05, 0x04, 0x40, 0x20, 0x06, 0x05, 0xc0, 0x3f, 0x07, 0x06, 0x80, 0x0b, 0x0a, 0x07, 0xb0, 0x32, 0x00, 0x03, + 0xb8, 0x32, 0x00, 0x03, 0xc0, 0x32, 0x00, 0x03, 0xc8, 0x32, 0x00, 0x03, 0x60, 0x1d, 0x01, 0x02, 0x64, 0x1d, 0x01, 0x02, 0x68, 0x1d, 0x01, 0x02, 0x6c, 0x1d, 0x01, 0x02, 0x70, 0x1d, 0x01, 0x02, + 0x74, 0x1d, 0x01, 0x02, 0x78, 0x1d, 0x01, 0x02, 0xf0, 0x3b, 0x02, 0x03, 0xf8, 0x3b, 0x02, 0x03, 0x00, 0x3c, 0x02, 0x03, 0x08, 0x3c, 0x02, 0x03, 0x70, 0x12, 0x03, 0x03, 0x78, 0x12, 0x03, 0x03, + 0x80, 0x12, 0x03, 0x03, 0x90, 0x2d, 0x04, 0x04, 0xa0, 0x2d, 0x04, 0x04, 0x80, 0x09, 0x05, 0x04, 0x60, 0x20, 0x06, 0x05, 0x00, 0x00, 0x07, 0x05, 0x00, 0x0c, 0x0a, 0x07, 0xd0, 0x32, 0x00, 0x03, + 0xd8, 0x32, 0x00, 0x03, 0xe0, 0x32, 0x00, 0x03, 0xe8, 0x32, 0x00, 0x03, 0x7c, 0x1d, 0x01, 0x02, 0x80, 0x1d, 0x01, 0x02, 0x84, 0x1d, 0x01, 0x02, 0x88, 0x1d, 0x01, 0x02, 0x8c, 0x1d, 0x01, 0x02, + 0x90, 0x1d, 0x01, 0x02, 0x94, 0x1d, 0x01, 0x02, 0x10, 0x3c, 0x02, 0x03, 0x18, 0x3c, 0x02, 0x03, 0x20, 0x3c, 0x02, 0x03, 0x28, 0x3c, 0x02, 0x03, 0x88, 0x12, 0x03, 0x03, 0x90, 0x12, 0x03, 0x03, + 0x98, 0x12, 0x03, 0x03, 0xb0, 0x2d, 0x04, 0x04, 0xc0, 0x2d, 0x04, 0x04, 0x90, 0x09, 0x05, 0x04, 0x80, 0x20, 0x06, 0x05, 0x20, 0x00, 0x07, 0x05, 0x80, 0x0c, 0x0a, 0x07, 0xf0, 0x32, 0x00, 0x03, + 0xf8, 0x32, 0x00, 0x03, 0x00, 0x33, 0x00, 0x03, 0x08, 0x33, 0x00, 0x03, 0x98, 0x1d, 0x01, 0x02, 0x9c, 0x1d, 0x01, 0x02, 0xa0, 0x1d, 0x01, 0x02, 0xa4, 0x1d, 0x01, 0x02, 0xa8, 0x1d, 0x01, 0x02, + 0xac, 0x1d, 0x01, 0x02, 0xb0, 0x1d, 0x01, 0x02, 0x30, 0x3c, 0x02, 0x03, 0x38, 0x3c, 0x02, 0x03, 0x40, 0x3c, 0x02, 0x03, 0x48, 0x3c, 0x02, 0x03, 0xa0, 0x12, 0x03, 0x03, 0xa8, 0x12, 0x03, 0x03, + 0xb0, 0x12, 0x03, 0x03, 0xd0, 0x2d, 0x04, 0x04, 0xe0, 0x2d, 0x04, 0x04, 0xa0, 0x09, 0x05, 0x04, 0xa0, 0x20, 0x06, 0x05, 0x40, 0x00, 0x07, 0x05, 0x00, 0x0d, 0x0a, 0x07, 0x10, 0x33, 0x00, 0x03, + 0x18, 0x33, 0x00, 0x03, 0x20, 0x33, 0x00, 0x03, 0x28, 0x33, 0x00, 0x03, 0xb4, 0x1d, 0x01, 0x02, 0xb8, 0x1d, 0x01, 0x02, 0xbc, 0x1d, 0x01, 0x02, 0xc0, 0x1d, 0x01, 0x02, 0xc4, 0x1d, 0x01, 0x02, + 0xc8, 0x1d, 0x01, 0x02, 0xcc, 0x1d, 0x01, 0x02, 0x50, 0x3c, 0x02, 0x03, 0x58, 0x3c, 0x02, 0x03, 0x60, 0x3c, 0x02, 0x03, 0x68, 0x3c, 0x02, 0x03, 0xb8, 0x12, 0x03, 0x03, 0xc0, 0x12, 0x03, 0x03, + 0xc8, 0x12, 0x03, 0x03, 0xf0, 0x2d, 0x04, 0x04, 0x00, 0x2e, 0x04, 0x04, 0xb0, 0x09, 0x05, 0x04, 0xc0, 0x20, 0x06, 0x05, 0x60, 0x00, 0x07, 0x05, 0x80, 0x0d, 0x0a, 0x07, 0x30, 0x33, 0x00, 0x03, + 0x38, 0x33, 0x00, 0x03, 0x40, 0x33, 0x00, 0x03, 0x48, 0x33, 0x00, 0x03, 0xd0, 0x1d, 0x01, 0x02, 0xd4, 0x1d, 0x01, 0x02, 0xd8, 0x1d, 0x01, 0x02, 0xdc, 0x1d, 0x01, 0x02, 0xe0, 0x1d, 0x01, 0x02, + 0xe4, 0x1d, 0x01, 0x02, 0xe8, 0x1d, 0x01, 0x02, 0x70, 0x3c, 0x02, 0x03, 0x78, 0x3c, 0x02, 0x03, 0x80, 0x3c, 0x02, 0x03, 0x88, 0x3c, 0x02, 0x03, 0xd0, 0x12, 0x03, 0x03, 0xd8, 0x12, 0x03, 0x03, + 0xe0, 0x12, 0x03, 0x03, 0x10, 0x2e, 0x04, 0x04, 0x20, 0x2e, 0x04, 0x04, 0xc0, 0x09, 0x05, 0x04, 0xe0, 0x20, 0x06, 0x05, 0x80, 0x00, 0x07, 0x05, 0x00, 0x0e, 0x0a, 0x07, 0x50, 0x33, 0x00, 0x03, + 0x58, 0x33, 0x00, 0x03, 0x60, 0x33, 0x00, 0x03, 0x68, 0x33, 0x00, 0x03, 0xec, 0x1d, 0x01, 0x02, 0xf0, 0x1d, 0x01, 0x02, 0xf4, 0x1d, 0x01, 0x02, 0xf8, 0x1d, 0x01, 0x02, 0xfc, 0x1d, 0x01, 0x02, + 0x00, 0x1e, 0x01, 0x02, 0x04, 0x1e, 0x01, 0x02, 0x90, 0x3c, 0x02, 0x03, 0x98, 0x3c, 0x02, 0x03, 0xa0, 0x3c, 0x02, 0x03, 0xa8, 0x3c, 0x02, 0x03, 0xe8, 0x12, 0x03, 0x03, 0xf0, 0x12, 0x03, 0x03, + 0xf8, 0x12, 0x03, 0x03, 0x30, 0x2e, 0x04, 0x04, 0x40, 0x2e, 0x04, 0x04, 0xd0, 0x09, 0x05, 0x04, 0x00, 0x21, 0x06, 0x05, 0xa0, 0x00, 0x07, 0x05, 0x00, 0x1f, 0x0b, 0x08, 0x70, 0x33, 0x00, 0x03, + 0x78, 0x33, 0x00, 0x03, 0x80, 0x33, 0x00, 0x03, 0x88, 0x33, 0x00, 0x03, 0x08, 0x1e, 0x01, 0x02, 0x0c, 0x1e, 0x01, 0x02, 0x10, 0x1e, 0x01, 0x02, 0x14, 0x1e, 0x01, 0x02, 0x18, 0x1e, 0x01, 0x02, + 0x1c, 0x1e, 0x01, 0x02, 0x20, 0x1e, 0x01, 0x02, 0xb0, 0x3c, 0x02, 0x03, 0xb8, 0x3c, 0x02, 0x03, 0xc0, 0x3c, 0x02, 0x03, 0xc8, 0x3c, 0x02, 0x03, 0x00, 0x13, 0x03, 0x03, 0x08, 0x13, 0x03, 0x03, + 0x10, 0x13, 0x03, 0x03, 0x50, 0x2e, 0x04, 0x04, 0x60, 0x2e, 0x04, 0x04, 0xe0, 0x09, 0x05, 0x04, 0x20, 0x21, 0x06, 0x05, 0xc0, 0x00, 0x07, 0x05, 0x00, 0x20, 0x0b, 0x08, 0x90, 0x33, 0x00, 0x03, + 0x98, 0x33, 0x00, 0x03, 0xa0, 0x33, 0x00, 0x03, 0xa8, 0x33, 0x00, 0x03, 0x24, 0x1e, 0x01, 0x02, 0x28, 0x1e, 0x01, 0x02, 0x2c, 0x1e, 0x01, 0x02, 0x30, 0x1e, 0x01, 0x02, 0x34, 0x1e, 0x01, 0x02, + 0x38, 0x1e, 0x01, 0x02, 0x3c, 0x1e, 0x01, 0x02, 0xd0, 0x3c, 0x02, 0x03, 0xd8, 0x3c, 0x02, 0x03, 0xe0, 0x3c, 0x02, 0x03, 0xe8, 0x3c, 0x02, 0x03, 0x18, 0x13, 0x03, 0x03, 0x20, 0x13, 0x03, 0x03, + 0x28, 0x13, 0x03, 0x03, 0x70, 0x2e, 0x04, 0x04, 0x80, 0x2e, 0x04, 0x04, 0xf0, 0x09, 0x05, 0x04, 0x40, 0x21, 0x06, 0x05, 0xe0, 0x00, 0x07, 0x05, 0x00, 0x21, 0x0b, 0x08, 0xb0, 0x33, 0x00, 0x03, + 0xb8, 0x33, 0x00, 0x03, 0xc0, 0x33, 0x00, 0x03, 0xc8, 0x33, 0x00, 0x03, 0x40, 0x1e, 0x01, 0x02, 0x44, 0x1e, 0x01, 0x02, 0x48, 0x1e, 0x01, 0x02, 0x4c, 0x1e, 0x01, 0x02, 0x50, 0x1e, 0x01, 0x02, + 0x54, 0x1e, 0x01, 0x02, 0x58, 0x1e, 0x01, 0x02, 0xf0, 0x3c, 0x02, 0x03, 0xf8, 0x3c, 0x02, 0x03, 0x00, 0x3d, 0x02, 0x03, 0x08, 0x3d, 0x02, 0x03, 0x30, 0x13, 0x03, 0x03, 0x38, 0x13, 0x03, 0x03, + 0x40, 0x13, 0x03, 0x03, 0x90, 0x2e, 0x04, 0x04, 0xa0, 0x2e, 0x04, 0x04, 0x00, 0x0a, 0x05, 0x04, 0x60, 0x21, 0x06, 0x05, 0x00, 0x01, 0x07, 0x05, 0x00, 0x22, 0x0b, 0x08, 0xd0, 0x33, 0x00, 0x03, + 0xd8, 0x33, 0x00, 0x03, 0xe0, 0x33, 0x00, 0x03, 0xe8, 0x33, 0x00, 0x03, 0x5c, 0x1e, 0x01, 0x02, 0x60, 0x1e, 0x01, 0x02, 0x64, 0x1e, 0x01, 0x02, 0x68, 0x1e, 0x01, 0x02, 0x6c, 0x1e, 0x01, 0x02, + 0x70, 0x1e, 0x01, 0x02, 0x74, 0x1e, 0x01, 0x02, 0x10, 0x3d, 0x02, 0x03, 0x18, 0x3d, 0x02, 0x03, 0x20, 0x3d, 0x02, 0x03, 0x28, 0x3d, 0x02, 0x03, 0x48, 0x13, 0x03, 0x03, 0x50, 0x13, 0x03, 0x03, + 0x58, 0x13, 0x03, 0x03, 0xb0, 0x2e, 0x04, 0x04, 0xc0, 0x2e, 0x04, 0x04, 0x10, 0x0a, 0x05, 0x04, 0x80, 0x21, 0x06, 0x05, 0x20, 0x01, 0x07, 0x05, 0x00, 0x23, 0x0b, 0x08, 0xf0, 0x33, 0x00, 0x03, + 0xf8, 0x33, 0x00, 0x03, 0x00, 0x34, 0x00, 0x03, 0x08, 0x34, 0x00, 0x03, 0x78, 0x1e, 0x01, 0x02, 0x7c, 0x1e, 0x01, 0x02, 0x80, 0x1e, 0x01, 0x02, 0x84, 0x1e, 0x01, 0x02, 0x88, 0x1e, 0x01, 0x02, + 0x8c, 0x1e, 0x01, 0x02, 0x90, 0x1e, 0x01, 0x02, 0x30, 0x3d, 0x02, 0x03, 0x38, 0x3d, 0x02, 0x03, 0x40, 0x3d, 0x02, 0x03, 0x48, 0x3d, 0x02, 0x03, 0x60, 0x13, 0x03, 0x03, 0x68, 0x13, 0x03, 0x03, + 0x70, 0x13, 0x03, 0x03, 0xd0, 0x2e, 0x04, 0x04, 0xe0, 0x2e, 0x04, 0x04, 0x20, 0x0a, 0x05, 0x04, 0xa0, 0x21, 0x06, 0x05, 0x40, 0x01, 0x07, 0x05, 0x00, 0x24, 0x0b, 0x08, 0x10, 0x34, 0x00, 0x03, + 0x18, 0x34, 0x00, 0x03, 0x20, 0x34, 0x00, 0x03, 0x28, 0x34, 0x00, 0x03, 0x94, 0x1e, 0x01, 0x02, 0x98, 0x1e, 0x01, 0x02, 0x9c, 0x1e, 0x01, 0x02, 0xa0, 0x1e, 0x01, 0x02, 0xa4, 0x1e, 0x01, 0x02, + 0xa8, 0x1e, 0x01, 0x02, 0xac, 0x1e, 0x01, 0x02, 0x50, 0x3d, 0x02, 0x03, 0x58, 0x3d, 0x02, 0x03, 0x60, 0x3d, 0x02, 0x03, 0x68, 0x3d, 0x02, 0x03, 0x78, 0x13, 0x03, 0x03, 0x80, 0x13, 0x03, 0x03, + 0x88, 0x13, 0x03, 0x03, 0xf0, 0x2e, 0x04, 0x04, 0x00, 0x2f, 0x04, 0x04, 0x30, 0x0a, 0x05, 0x04, 0xc0, 0x21, 0x06, 0x05, 0x60, 0x01, 0x07, 0x05, 0x00, 0x25, 0x0b, 0x08, 0x30, 0x34, 0x00, 0x03, + 0x38, 0x34, 0x00, 0x03, 0x40, 0x34, 0x00, 0x03, 0x48, 0x34, 0x00, 0x03, 0xb0, 0x1e, 0x01, 0x02, 0xb4, 0x1e, 0x01, 0x02, 0xb8, 0x1e, 0x01, 0x02, 0xbc, 0x1e, 0x01, 0x02, 0xc0, 0x1e, 0x01, 0x02, + 0xc4, 0x1e, 0x01, 0x02, 0xc8, 0x1e, 0x01, 0x02, 0x70, 0x3d, 0x02, 0x03, 0x78, 0x3d, 0x02, 0x03, 0x80, 0x3d, 0x02, 0x03, 0x88, 0x3d, 0x02, 0x03, 0x90, 0x13, 0x03, 0x03, 0x98, 0x13, 0x03, 0x03, + 0xa0, 0x13, 0x03, 0x03, 0x10, 0x2f, 0x04, 0x04, 0x20, 0x2f, 0x04, 0x04, 0x40, 0x0a, 0x05, 0x04, 0xe0, 0x21, 0x06, 0x05, 0x80, 0x01, 0x07, 0x05, 0x00, 0x26, 0x0b, 0x08, 0x50, 0x34, 0x00, 0x03, + 0x58, 0x34, 0x00, 0x03, 0x60, 0x34, 0x00, 0x03, 0x68, 0x34, 0x00, 0x03, 0xcc, 0x1e, 0x01, 0x02, 0xd0, 0x1e, 0x01, 0x02, 0xd4, 0x1e, 0x01, 0x02, 0xd8, 0x1e, 0x01, 0x02, 0xdc, 0x1e, 0x01, 0x02, + 0xe0, 0x1e, 0x01, 0x02, 0x90, 0x3d, 0x02, 0x03, 0x98, 0x3d, 0x02, 0x03, 0xa0, 0x3d, 0x02, 0x03, 0xa8, 0x3d, 0x02, 0x03, 0xb0, 0x3d, 0x02, 0x03, 0xa8, 0x13, 0x03, 0x03, 0xb0, 0x13, 0x03, 0x03, + 0xb8, 0x13, 0x03, 0x03, 0x30, 0x2f, 0x04, 0x04, 0x40, 0x2f, 0x04, 0x04, 0x50, 0x0a, 0x05, 0x04, 0x00, 0x22, 0x06, 0x05, 0xa0, 0x01, 0x07, 0x05, 0x00, 0x27, 0x0b, 0x08, 0x70, 0x34, 0x00, 0x03, + 0x78, 0x34, 0x00, 0x03, 0x80, 0x34, 0x00, 0x03, 0x88, 0x34, 0x00, 0x03, 0xe4, 0x1e, 0x01, 0x02, 0xe8, 0x1e, 0x01, 0x02, 0xec, 0x1e, 0x01, 0x02, 0xf0, 0x1e, 0x01, 0x02, 0xf4, 0x1e, 0x01, 0x02, + 0xf8, 0x1e, 0x01, 0x02, 0xb8, 0x3d, 0x02, 0x03, 0xc0, 0x3d, 0x02, 0x03, 0xc8, 0x3d, 0x02, 0x03, 0xd0, 0x3d, 0x02, 0x03, 0xd8, 0x3d, 0x02, 0x03, 0xc0, 0x13, 0x03, 0x03, 0xc8, 0x13, 0x03, 0x03, + 0xd0, 0x13, 0x03, 0x03, 0x50, 0x2f, 0x04, 0x04, 0x60, 0x2f, 0x04, 0x04, 0x60, 0x0a, 0x05, 0x04, 0x20, 0x22, 0x06, 0x05, 0xc0, 0x01, 0x07, 0x05, 0x00, 0x3e, 0x0c, 0x09, 0x90, 0x34, 0x00, 0x03, + 0x98, 0x34, 0x00, 0x03, 0xa0, 0x34, 0x00, 0x03, 0xa8, 0x34, 0x00, 0x03, 0xfc, 0x1e, 0x01, 0x02, 0x00, 0x1f, 0x01, 0x02, 0x04, 0x1f, 0x01, 0x02, 0x08, 0x1f, 0x01, 0x02, 0x0c, 0x1f, 0x01, 0x02, + 0x10, 0x1f, 0x01, 0x02, 0xe0, 0x3d, 0x02, 0x03, 0xe8, 0x3d, 0x02, 0x03, 0xf0, 0x3d, 0x02, 0x03, 0xf8, 0x3d, 0x02, 0x03, 0x00, 0x3e, 0x02, 0x03, 0xd8, 0x13, 0x03, 0x03, 0xe0, 0x13, 0x03, 0x03, + 0xe8, 0x13, 0x03, 0x03, 0x70, 0x2f, 0x04, 0x04, 0x80, 0x2f, 0x04, 0x04, 0x70, 0x0a, 0x05, 0x04, 0x40, 0x22, 0x06, 0x05, 0xe0, 0x01, 0x07, 0x05, 0x00, 0x00, 0x0c, 0x08, 0xb0, 0x34, 0x00, 0x03, + 0xb8, 0x34, 0x00, 0x03, 0xc0, 0x34, 0x00, 0x03, 0xc8, 0x34, 0x00, 0x03, 0x14, 0x1f, 0x01, 0x02, 0x18, 0x1f, 0x01, 0x02, 0x1c, 0x1f, 0x01, 0x02, 0x20, 0x1f, 0x01, 0x02, 0x24, 0x1f, 0x01, 0x02, + 0x28, 0x1f, 0x01, 0x02, 0x08, 0x3e, 0x02, 0x03, 0x10, 0x3e, 0x02, 0x03, 0x18, 0x3e, 0x02, 0x03, 0x20, 0x3e, 0x02, 0x03, 0x28, 0x3e, 0x02, 0x03, 0xf0, 0x13, 0x03, 0x03, 0xf8, 0x13, 0x03, 0x03, + 0x00, 0x14, 0x03, 0x03, 0x90, 0x2f, 0x04, 0x04, 0xa0, 0x2f, 0x04, 0x04, 0x80, 0x0a, 0x05, 0x04, 0x60, 0x22, 0x06, 0x05, 0x00, 0x02, 0x07, 0x05, 0x00, 0x01, 0x0c, 0x08, 0xd0, 0x34, 0x00, 0x03, + 0xd8, 0x34, 0x00, 0x03, 0xe0, 0x34, 0x00, 0x03, 0xe8, 0x34, 0x00, 0x03, 0x2c, 0x1f, 0x01, 0x02, 0x30, 0x1f, 0x01, 0x02, 0x34, 0x1f, 0x01, 0x02, 0x38, 0x1f, 0x01, 0x02, 0x3c, 0x1f, 0x01, 0x02, + 0x40, 0x1f, 0x01, 0x02, 0x30, 0x3e, 0x02, 0x03, 0x38, 0x3e, 0x02, 0x03, 0x40, 0x3e, 0x02, 0x03, 0x48, 0x3e, 0x02, 0x03, 0x50, 0x3e, 0x02, 0x03, 0x08, 0x14, 0x03, 0x03, 0x10, 0x14, 0x03, 0x03, + 0x18, 0x14, 0x03, 0x03, 0xb0, 0x2f, 0x04, 0x04, 0xc0, 0x2f, 0x04, 0x04, 0x90, 0x0a, 0x05, 0x04, 0x80, 0x22, 0x06, 0x05, 0x20, 0x02, 0x07, 0x05, 0x00, 0x02, 0x0c, 0x08, 0xf0, 0x34, 0x00, 0x03, + 0xf8, 0x34, 0x00, 0x03, 0x00, 0x35, 0x00, 0x03, 0x08, 0x35, 0x00, 0x03, 0x44, 0x1f, 0x01, 0x02, 0x48, 0x1f, 0x01, 0x02, 0x4c, 0x1f, 0x01, 0x02, 0x50, 0x1f, 0x01, 0x02, 0x54, 0x1f, 0x01, 0x02, + 0x58, 0x1f, 0x01, 0x02, 0x58, 0x3e, 0x02, 0x03, 0x60, 0x3e, 0x02, 0x03, 0x68, 0x3e, 0x02, 0x03, 0x70, 0x3e, 0x02, 0x03, 0x78, 0x3e, 0x02, 0x03, 0x20, 0x14, 0x03, 0x03, 0x28, 0x14, 0x03, 0x03, + 0x30, 0x14, 0x03, 0x03, 0xd0, 0x2f, 0x04, 0x04, 0xe0, 0x2f, 0x04, 0x04, 0xa0, 0x0a, 0x05, 0x04, 0xa0, 0x22, 0x06, 0x05, 0x40, 0x02, 0x07, 0x05, 0x00, 0x03, 0x0c, 0x08, 0x10, 0x35, 0x00, 0x03, + 0x18, 0x35, 0x00, 0x03, 0x20, 0x35, 0x00, 0x03, 0x28, 0x35, 0x00, 0x03, 0x5c, 0x1f, 0x01, 0x02, 0x60, 0x1f, 0x01, 0x02, 0x64, 0x1f, 0x01, 0x02, 0x68, 0x1f, 0x01, 0x02, 0x6c, 0x1f, 0x01, 0x02, + 0x70, 0x1f, 0x01, 0x02, 0x80, 0x3e, 0x02, 0x03, 0x88, 0x3e, 0x02, 0x03, 0x90, 0x3e, 0x02, 0x03, 0x98, 0x3e, 0x02, 0x03, 0xa0, 0x3e, 0x02, 0x03, 0x38, 0x14, 0x03, 0x03, 0x40, 0x14, 0x03, 0x03, + 0x48, 0x14, 0x03, 0x03, 0xf0, 0x2f, 0x04, 0x04, 0x00, 0x30, 0x04, 0x04, 0xb0, 0x0a, 0x05, 0x04, 0xc0, 0x22, 0x06, 0x05, 0x60, 0x02, 0x07, 0x05, 0x00, 0x04, 0x0c, 0x08, 0x30, 0x35, 0x00, 0x03, + 0x38, 0x35, 0x00, 0x03, 0x40, 0x35, 0x00, 0x03, 0x48, 0x35, 0x00, 0x03, 0x74, 0x1f, 0x01, 0x02, 0x78, 0x1f, 0x01, 0x02, 0x7c, 0x1f, 0x01, 0x02, 0x80, 0x1f, 0x01, 0x02, 0x84, 0x1f, 0x01, 0x02, + 0x88, 0x1f, 0x01, 0x02, 0xa8, 0x3e, 0x02, 0x03, 0xb0, 0x3e, 0x02, 0x03, 0xb8, 0x3e, 0x02, 0x03, 0xc0, 0x3e, 0x02, 0x03, 0xc8, 0x3e, 0x02, 0x03, 0x50, 0x14, 0x03, 0x03, 0x58, 0x14, 0x03, 0x03, + 0x60, 0x14, 0x03, 0x03, 0x10, 0x30, 0x04, 0x04, 0x20, 0x30, 0x04, 0x04, 0xc0, 0x0a, 0x05, 0x04, 0xe0, 0x22, 0x06, 0x05, 0x80, 0x02, 0x07, 0x05, 0x00, 0x14, 0x0d, 0x09, 0x50, 0x35, 0x00, 0x03, + 0x58, 0x35, 0x00, 0x03, 0x60, 0x35, 0x00, 0x03, 0x68, 0x35, 0x00, 0x03, 0x8c, 0x1f, 0x01, 0x02, 0x90, 0x1f, 0x01, 0x02, 0x94, 0x1f, 0x01, 0x02, 0x98, 0x1f, 0x01, 0x02, 0x9c, 0x1f, 0x01, 0x02, + 0xa0, 0x1f, 0x01, 0x02, 0xd0, 0x3e, 0x02, 0x03, 0xd8, 0x3e, 0x02, 0x03, 0xe0, 0x3e, 0x02, 0x03, 0xe8, 0x3e, 0x02, 0x03, 0xf0, 0x3e, 0x02, 0x03, 0x68, 0x14, 0x03, 0x03, 0x70, 0x14, 0x03, 0x03, + 0x78, 0x14, 0x03, 0x03, 0x30, 0x30, 0x04, 0x04, 0x40, 0x30, 0x04, 0x04, 0xd0, 0x0a, 0x05, 0x04, 0x00, 0x23, 0x06, 0x05, 0x80, 0x16, 0x08, 0x06, 0x00, 0x16, 0x0d, 0x09, 0x70, 0x35, 0x00, 0x03, + 0x78, 0x35, 0x00, 0x03, 0x80, 0x35, 0x00, 0x03, 0x88, 0x35, 0x00, 0x03, 0xa4, 0x1f, 0x01, 0x02, 0xa8, 0x1f, 0x01, 0x02, 0xac, 0x1f, 0x01, 0x02, 0xb0, 0x1f, 0x01, 0x02, 0xb4, 0x1f, 0x01, 0x02, + 0xb8, 0x1f, 0x01, 0x02, 0xf8, 0x3e, 0x02, 0x03, 0x00, 0x3f, 0x02, 0x03, 0x08, 0x3f, 0x02, 0x03, 0x10, 0x3f, 0x02, 0x03, 0x18, 0x3f, 0x02, 0x03, 0x80, 0x14, 0x03, 0x03, 0x88, 0x14, 0x03, 0x03, + 0x90, 0x14, 0x03, 0x03, 0x50, 0x30, 0x04, 0x04, 0x60, 0x30, 0x04, 0x04, 0xe0, 0x0a, 0x05, 0x04, 0x20, 0x23, 0x06, 0x05, 0xc0, 0x16, 0x08, 0x06, 0x00, 0x18, 0x0d, 0x09, 0x90, 0x35, 0x00, 0x03, + 0x98, 0x35, 0x00, 0x03, 0xa0, 0x35, 0x00, 0x03, 0xa8, 0x35, 0x00, 0x03, 0xbc, 0x1f, 0x01, 0x02, 0xc0, 0x1f, 0x01, 0x02, 0xc4, 0x1f, 0x01, 0x02, 0xc8, 0x1f, 0x01, 0x02, 0xcc, 0x1f, 0x01, 0x02, + 0xd0, 0x1f, 0x01, 0x02, 0x20, 0x3f, 0x02, 0x03, 0x28, 0x3f, 0x02, 0x03, 0x30, 0x3f, 0x02, 0x03, 0x38, 0x3f, 0x02, 0x03, 0x40, 0x3f, 0x02, 0x03, 0x98, 0x14, 0x03, 0x03, 0xa0, 0x14, 0x03, 0x03, + 0xa8, 0x14, 0x03, 0x03, 0x70, 0x30, 0x04, 0x04, 0x80, 0x30, 0x04, 0x04, 0xf0, 0x0a, 0x05, 0x04, 0x40, 0x23, 0x06, 0x05, 0x00, 0x17, 0x08, 0x06, 0x00, 0x1a, 0x0d, 0x09, 0xb0, 0x35, 0x00, 0x03, + 0xb8, 0x35, 0x00, 0x03, 0xc0, 0x35, 0x00, 0x03, 0xc8, 0x35, 0x00, 0x03, 0xd4, 0x1f, 0x01, 0x02, 0xd8, 0x1f, 0x01, 0x02, 0xdc, 0x1f, 0x01, 0x02, 0xe0, 0x1f, 0x01, 0x02, 0xe4, 0x1f, 0x01, 0x02, + 0xe8, 0x1f, 0x01, 0x02, 0x48, 0x3f, 0x02, 0x03, 0x50, 0x3f, 0x02, 0x03, 0x58, 0x3f, 0x02, 0x03, 0x60, 0x3f, 0x02, 0x03, 0x68, 0x3f, 0x02, 0x03, 0xb0, 0x14, 0x03, 0x03, 0xb8, 0x14, 0x03, 0x03, + 0xc0, 0x14, 0x03, 0x03, 0x90, 0x30, 0x04, 0x04, 0xa0, 0x30, 0x04, 0x04, 0x00, 0x0b, 0x05, 0x04, 0x60, 0x23, 0x06, 0x05, 0x40, 0x17, 0x08, 0x06, 0x00, 0x1c, 0x0d, 0x09, 0xd0, 0x35, 0x00, 0x03, + 0xd8, 0x35, 0x00, 0x03, 0xe0, 0x35, 0x00, 0x03, 0xe8, 0x35, 0x00, 0x03, 0xec, 0x1f, 0x01, 0x02, 0xf0, 0x1f, 0x01, 0x02, 0xf4, 0x1f, 0x01, 0x02, 0xf8, 0x1f, 0x01, 0x02, 0xfc, 0x1f, 0x01, 0x02, + 0x00, 0x20, 0x01, 0x02, 0x70, 0x3f, 0x02, 0x03, 0x78, 0x3f, 0x02, 0x03, 0x80, 0x3f, 0x02, 0x03, 0x88, 0x3f, 0x02, 0x03, 0x90, 0x3f, 0x02, 0x03, 0xc8, 0x14, 0x03, 0x03, 0xd0, 0x14, 0x03, 0x03, + 0xd8, 0x14, 0x03, 0x03, 0xb0, 0x30, 0x04, 0x04, 0xc0, 0x30, 0x04, 0x04, 0x10, 0x0b, 0x05, 0x04, 0x80, 0x23, 0x06, 0x05, 0x80, 0x17, 0x08, 0x06, 0x00, 0x30, 0x0e, 0x0a, 0xf0, 0x35, 0x00, 0x03, + 0xf8, 0x35, 0x00, 0x03, 0x00, 0x36, 0x00, 0x03, 0x08, 0x36, 0x00, 0x03, 0x04, 0x20, 0x01, 0x02, 0x08, 0x20, 0x01, 0x02, 0x0c, 0x20, 0x01, 0x02, 0x10, 0x20, 0x01, 0x02, 0x14, 0x20, 0x01, 0x02, + 0x18, 0x20, 0x01, 0x02, 0x98, 0x3f, 0x02, 0x03, 0xa0, 0x3f, 0x02, 0x03, 0xa8, 0x3f, 0x02, 0x03, 0xb0, 0x3f, 0x02, 0x03, 0xb8, 0x3f, 0x02, 0x03, 0xe0, 0x14, 0x03, 0x03, 0xe8, 0x14, 0x03, 0x03, + 0xf0, 0x14, 0x03, 0x03, 0xd0, 0x30, 0x04, 0x04, 0xe0, 0x30, 0x04, 0x04, 0x20, 0x0b, 0x05, 0x04, 0xa0, 0x23, 0x06, 0x05, 0xc0, 0x17, 0x08, 0x06, 0x00, 0x34, 0x0e, 0x0a, 0x10, 0x36, 0x00, 0x03, + 0x18, 0x36, 0x00, 0x03, 0x20, 0x36, 0x00, 0x03, 0x28, 0x36, 0x00, 0x03, 0x1c, 0x20, 0x01, 0x02, 0x20, 0x20, 0x01, 0x02, 0x24, 0x20, 0x01, 0x02, 0x28, 0x20, 0x01, 0x02, 0x2c, 0x20, 0x01, 0x02, + 0x30, 0x20, 0x01, 0x02, 0xc0, 0x3f, 0x02, 0x03, 0xc8, 0x3f, 0x02, 0x03, 0xd0, 0x3f, 0x02, 0x03, 0xd8, 0x3f, 0x02, 0x03, 0xe0, 0x3f, 0x02, 0x03, 0xf8, 0x14, 0x03, 0x03, 0x00, 0x15, 0x03, 0x03, + 0x08, 0x15, 0x03, 0x03, 0xf0, 0x30, 0x04, 0x04, 0x00, 0x31, 0x04, 0x04, 0x30, 0x0b, 0x05, 0x04, 0xc0, 0x23, 0x06, 0x05, 0x00, 0x18, 0x08, 0x06, 0x00, 0x38, 0x0e, 0x0a, 0x30, 0x36, 0x00, 0x03, + 0x38, 0x36, 0x00, 0x03, 0x40, 0x36, 0x00, 0x03, 0x48, 0x36, 0x00, 0x03, 0x34, 0x20, 0x01, 0x02, 0x38, 0x20, 0x01, 0x02, 0x3c, 0x20, 0x01, 0x02, 0x40, 0x20, 0x01, 0x02, 0x44, 0x20, 0x01, 0x02, + 0x48, 0x20, 0x01, 0x02, 0xe8, 0x3f, 0x02, 0x03, 0xf0, 0x3f, 0x02, 0x03, 0xf8, 0x3f, 0x02, 0x03, 0x00, 0x00, 0x02, 0x02, 0x04, 0x00, 0x02, 0x02, 0x10, 0x15, 0x03, 0x03, 0x18, 0x15, 0x03, 0x03, + 0x20, 0x15, 0x03, 0x03, 0x10, 0x31, 0x04, 0x04, 0x20, 0x31, 0x04, 0x04, 0x40, 0x0b, 0x05, 0x04, 0xe0, 0x23, 0x06, 0x05, 0x40, 0x18, 0x08, 0x06, 0x00, 0x10, 0x0f, 0x0a, 0x50, 0x36, 0x00, 0x03, + 0x58, 0x36, 0x00, 0x03, 0x60, 0x36, 0x00, 0x03, 0x68, 0x36, 0x00, 0x03, 0x4c, 0x20, 0x01, 0x02, 0x50, 0x20, 0x01, 0x02, 0x54, 0x20, 0x01, 0x02, 0x58, 0x20, 0x01, 0x02, 0x5c, 0x20, 0x01, 0x02, + 0x60, 0x20, 0x01, 0x02, 0x08, 0x00, 0x02, 0x02, 0x0c, 0x00, 0x02, 0x02, 0x10, 0x00, 0x02, 0x02, 0x14, 0x00, 0x02, 0x02, 0x18, 0x00, 0x02, 0x02, 0x28, 0x15, 0x03, 0x03, 0x30, 0x15, 0x03, 0x03, + 0x38, 0x15, 0x03, 0x03, 0x30, 0x31, 0x04, 0x04, 0x40, 0x31, 0x04, 0x04, 0x50, 0x0b, 0x05, 0x04, 0x00, 0x24, 0x06, 0x05, 0x80, 0x18, 0x08, 0x06, 0x00, 0x14, 0x0f, 0x0a, 0x70, 0x36, 0x00, 0x03, + 0x78, 0x36, 0x00, 0x03, 0x80, 0x36, 0x00, 0x03, 0x88, 0x36, 0x00, 0x03, 0x64, 0x20, 0x01, 0x02, 0x68, 0x20, 0x01, 0x02, 0x6c, 0x20, 0x01, 0x02, 0x70, 0x20, 0x01, 0x02, 0x74, 0x20, 0x01, 0x02, + 0x78, 0x20, 0x01, 0x02, 0x1c, 0x00, 0x02, 0x02, 0x20, 0x00, 0x02, 0x02, 0x24, 0x00, 0x02, 0x02, 0x28, 0x00, 0x02, 0x02, 0x2c, 0x00, 0x02, 0x02, 0x40, 0x15, 0x03, 0x03, 0x48, 0x15, 0x03, 0x03, + 0x50, 0x15, 0x03, 0x03, 0x50, 0x31, 0x04, 0x04, 0x60, 0x31, 0x04, 0x04, 0x60, 0x0b, 0x05, 0x04, 0x20, 0x24, 0x06, 0x05, 0xc0, 0x18, 0x08, 0x06, 0x00, 0x28, 0x10, 0x0b, 0x90, 0x36, 0x00, 0x03, + 0x98, 0x36, 0x00, 0x03, 0xa0, 0x36, 0x00, 0x03, 0xa8, 0x36, 0x00, 0x03, 0x7c, 0x20, 0x01, 0x02, 0x80, 0x20, 0x01, 0x02, 0x84, 0x20, 0x01, 0x02, 0x88, 0x20, 0x01, 0x02, 0x8c, 0x20, 0x01, 0x02, + 0x90, 0x20, 0x01, 0x02, 0x30, 0x00, 0x02, 0x02, 0x34, 0x00, 0x02, 0x02, 0x38, 0x00, 0x02, 0x02, 0x3c, 0x00, 0x02, 0x02, 0x40, 0x00, 0x02, 0x02, 0x58, 0x15, 0x03, 0x03, 0x60, 0x15, 0x03, 0x03, + 0x68, 0x15, 0x03, 0x03, 0x70, 0x31, 0x04, 0x04, 0x80, 0x31, 0x04, 0x04, 0x70, 0x0b, 0x05, 0x04, 0x40, 0x24, 0x06, 0x05, 0x00, 0x19, 0x08, 0x06, 0x00, 0x08, 0x11, 0x0b, 0xb0, 0x36, 0x00, 0x03, + 0xb8, 0x36, 0x00, 0x03, 0xc0, 0x36, 0x00, 0x03, 0xc8, 0x36, 0x00, 0x03, 0x94, 0x20, 0x01, 0x02, 0x98, 0x20, 0x01, 0x02, 0x9c, 0x20, 0x01, 0x02, 0xa0, 0x20, 0x01, 0x02, 0xa4, 0x20, 0x01, 0x02, + 0xa8, 0x20, 0x01, 0x02, 0x44, 0x00, 0x02, 0x02, 0x48, 0x00, 0x02, 0x02, 0x4c, 0x00, 0x02, 0x02, 0x50, 0x00, 0x02, 0x02, 0x54, 0x00, 0x02, 0x02, 0x70, 0x15, 0x03, 0x03, 0x78, 0x15, 0x03, 0x03, + 0x80, 0x15, 0x03, 0x03, 0x90, 0x31, 0x04, 0x04, 0xa0, 0x31, 0x04, 0x04, 0x80, 0x0b, 0x05, 0x04, 0x60, 0x24, 0x06, 0x05, 0x40, 0x19, 0x08, 0x06, 0x00, 0x10, 0x12, 0x0c, 0xd0, 0x36, 0x00, 0x03, + 0xd8, 0x36, 0x00, 0x03, 0xe0, 0x36, 0x00, 0x03, 0xe8, 0x36, 0x00, 0x03, 0xac, 0x20, 0x01, 0x02, 0xb0, 0x20, 0x01, 0x02, 0xb4, 0x20, 0x01, 0x02, 0xb8, 0x20, 0x01, 0x02, 0xbc, 0x20, 0x01, 0x02, + 0xc0, 0x20, 0x01, 0x02, 0x58, 0x00, 0x02, 0x02, 0x5c, 0x00, 0x02, 0x02, 0x60, 0x00, 0x02, 0x02, 0x64, 0x00, 0x02, 0x02, 0x68, 0x00, 0x02, 0x02, 0x88, 0x15, 0x03, 0x03, 0x90, 0x15, 0x03, 0x03, + 0x98, 0x15, 0x03, 0x03, 0xb0, 0x31, 0x04, 0x04, 0xc0, 0x31, 0x04, 0x04, 0x90, 0x0b, 0x05, 0x04, 0x80, 0x24, 0x06, 0x05, 0x80, 0x19, 0x08, 0x06, 0x00, 0x00, 0x14, 0x0d, 0xf0, 0x36, 0x00, 0x03, + 0xf8, 0x36, 0x00, 0x03, 0x00, 0x37, 0x00, 0x03, 0x08, 0x37, 0x00, 0x03, 0xc4, 0x20, 0x01, 0x02, 0xc8, 0x20, 0x01, 0x02, 0xcc, 0x20, 0x01, 0x02, 0xd0, 0x20, 0x01, 0x02, 0xd4, 0x20, 0x01, 0x02, + 0xd8, 0x20, 0x01, 0x02, 0x6c, 0x00, 0x02, 0x02, 0x70, 0x00, 0x02, 0x02, 0x74, 0x00, 0x02, 0x02, 0x78, 0x00, 0x02, 0x02, 0x7c, 0x00, 0x02, 0x02, 0xa0, 0x15, 0x03, 0x03, 0xa8, 0x15, 0x03, 0x03, + 0xb0, 0x15, 0x03, 0x03, 0xd0, 0x31, 0x04, 0x04, 0xe0, 0x31, 0x04, 0x04, 0xa0, 0x0b, 0x05, 0x04, 0xa0, 0x24, 0x06, 0x05, 0xc0, 0x19, 0x08, 0x06, 0x10, 0x37, 0x00, 0x03, 0x18, 0x37, 0x00, 0x03, + 0x20, 0x37, 0x00, 0x03, 0x28, 0x37, 0x00, 0x03, 0x30, 0x37, 0x00, 0x03, 0xdc, 0x20, 0x01, 0x02, 0xe0, 0x20, 0x01, 0x02, 0xe4, 0x20, 0x01, 0x02, 0xe8, 0x20, 0x01, 0x02, 0xec, 0x20, 0x01, 0x02, + 0xf0, 0x20, 0x01, 0x02, 0x80, 0x00, 0x02, 0x02, 0x84, 0x00, 0x02, 0x02, 0x88, 0x00, 0x02, 0x02, 0x8c, 0x00, 0x02, 0x02, 0x90, 0x00, 0x02, 0x02, 0xb8, 0x15, 0x03, 0x03, 0xc0, 0x15, 0x03, 0x03, + 0xc8, 0x15, 0x03, 0x03, 0xf0, 0x31, 0x04, 0x04, 0x00, 0x32, 0x04, 0x04, 0xb0, 0x0b, 0x05, 0x04, 0xc0, 0x24, 0x06, 0x05, 0x00, 0x1a, 0x08, 0x06, 0x38, 0x37, 0x00, 0x03, 0x40, 0x37, 0x00, 0x03, + 0x48, 0x37, 0x00, 0x03, 0x50, 0x37, 0x00, 0x03, 0x58, 0x37, 0x00, 0x03, 0xf4, 0x20, 0x01, 0x02, 0xf8, 0x20, 0x01, 0x02, 0xfc, 0x20, 0x01, 0x02, 0x00, 0x21, 0x01, 0x02, 0x04, 0x21, 0x01, 0x02, + 0x08, 0x21, 0x01, 0x02, 0x94, 0x00, 0x02, 0x02, 0x98, 0x00, 0x02, 0x02, 0x9c, 0x00, 0x02, 0x02, 0xa0, 0x00, 0x02, 0x02, 0xa4, 0x00, 0x02, 0x02, 0xd0, 0x15, 0x03, 0x03, 0xd8, 0x15, 0x03, 0x03, + 0xe0, 0x15, 0x03, 0x03, 0x10, 0x32, 0x04, 0x04, 0x20, 0x32, 0x04, 0x04, 0xc0, 0x0b, 0x05, 0x04, 0xe0, 0x24, 0x06, 0x05, 0x40, 0x1a, 0x08, 0x06, 0x60, 0x37, 0x00, 0x03, 0x68, 0x37, 0x00, 0x03, + 0x70, 0x37, 0x00, 0x03, 0x78, 0x37, 0x00, 0x03, 0x80, 0x37, 0x00, 0x03, 0x0c, 0x21, 0x01, 0x02, 0x10, 0x21, 0x01, 0x02, 0x14, 0x21, 0x01, 0x02, 0x18, 0x21, 0x01, 0x02, 0x1c, 0x21, 0x01, 0x02, + 0x20, 0x21, 0x01, 0x02, 0xa8, 0x00, 0x02, 0x02, 0xac, 0x00, 0x02, 0x02, 0xb0, 0x00, 0x02, 0x02, 0xb4, 0x00, 0x02, 0x02, 0xb8, 0x00, 0x02, 0x02, 0xe8, 0x15, 0x03, 0x03, 0xf0, 0x15, 0x03, 0x03, + 0xf8, 0x15, 0x03, 0x03, 0x30, 0x32, 0x04, 0x04, 0x40, 0x32, 0x04, 0x04, 0xd0, 0x0b, 0x05, 0x04, 0x00, 0x25, 0x06, 0x05, 0x80, 0x1a, 0x08, 0x06, 0x88, 0x37, 0x00, 0x03, 0x90, 0x37, 0x00, 0x03, + 0x98, 0x37, 0x00, 0x03, 0xa0, 0x37, 0x00, 0x03, 0xa8, 0x37, 0x00, 0x03, 0x24, 0x21, 0x01, 0x02, 0x28, 0x21, 0x01, 0x02, 0x2c, 0x21, 0x01, 0x02, 0x30, 0x21, 0x01, 0x02, 0x34, 0x21, 0x01, 0x02, + 0x38, 0x21, 0x01, 0x02, 0xbc, 0x00, 0x02, 0x02, 0xc0, 0x00, 0x02, 0x02, 0xc4, 0x00, 0x02, 0x02, 0xc8, 0x00, 0x02, 0x02, 0xcc, 0x00, 0x02, 0x02, 0x00, 0x16, 0x03, 0x03, 0x08, 0x16, 0x03, 0x03, + 0x10, 0x16, 0x03, 0x03, 0x50, 0x32, 0x04, 0x04, 0x60, 0x32, 0x04, 0x04, 0xe0, 0x0b, 0x05, 0x04, 0x20, 0x25, 0x06, 0x05, 0xc0, 0x1a, 0x08, 0x06, 0xb0, 0x37, 0x00, 0x03, 0xb8, 0x37, 0x00, 0x03, + 0xc0, 0x37, 0x00, 0x03, 0xc8, 0x37, 0x00, 0x03, 0xd0, 0x37, 0x00, 0x03, 0x3c, 0x21, 0x01, 0x02, 0x40, 0x21, 0x01, 0x02, 0x44, 0x21, 0x01, 0x02, 0x48, 0x21, 0x01, 0x02, 0x4c, 0x21, 0x01, 0x02, + 0x50, 0x21, 0x01, 0x02, 0xd0, 0x00, 0x02, 0x02, 0xd4, 0x00, 0x02, 0x02, 0xd8, 0x00, 0x02, 0x02, 0xdc, 0x00, 0x02, 0x02, 0xe0, 0x00, 0x02, 0x02, 0x18, 0x16, 0x03, 0x03, 0x20, 0x16, 0x03, 0x03, + 0x28, 0x16, 0x03, 0x03, 0x70, 0x32, 0x04, 0x04, 0x80, 0x32, 0x04, 0x04, 0xf0, 0x0b, 0x05, 0x04, 0x40, 0x25, 0x06, 0x05, 0x00, 0x1b, 0x08, 0x06, 0xd8, 0x37, 0x00, 0x03, 0xe0, 0x37, 0x00, 0x03, + 0xe8, 0x37, 0x00, 0x03, 0xf0, 0x37, 0x00, 0x03, 0xf8, 0x37, 0x00, 0x03, 0x54, 0x21, 0x01, 0x02, 0x58, 0x21, 0x01, 0x02, 0x5c, 0x21, 0x01, 0x02, 0x60, 0x21, 0x01, 0x02, 0x64, 0x21, 0x01, 0x02, + 0x68, 0x21, 0x01, 0x02, 0xe4, 0x00, 0x02, 0x02, 0xe8, 0x00, 0x02, 0x02, 0xec, 0x00, 0x02, 0x02, 0xf0, 0x00, 0x02, 0x02, 0xf4, 0x00, 0x02, 0x02, 0x30, 0x16, 0x03, 0x03, 0x38, 0x16, 0x03, 0x03, + 0x40, 0x16, 0x03, 0x03, 0x90, 0x32, 0x04, 0x04, 0xa0, 0x32, 0x04, 0x04, 0x00, 0x0c, 0x05, 0x04, 0x60, 0x25, 0x06, 0x05, 0x40, 0x1b, 0x08, 0x06, 0x00, 0x38, 0x00, 0x03, 0x08, 0x38, 0x00, 0x03, + 0x10, 0x38, 0x00, 0x03, 0x18, 0x38, 0x00, 0x03, 0x20, 0x38, 0x00, 0x03, 0x6c, 0x21, 0x01, 0x02, 0x70, 0x21, 0x01, 0x02, 0x74, 0x21, 0x01, 0x02, 0x78, 0x21, 0x01, 0x02, 0x7c, 0x21, 0x01, 0x02, + 0x80, 0x21, 0x01, 0x02, 0xf8, 0x00, 0x02, 0x02, 0xfc, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x04, 0x01, 0x02, 0x02, 0x08, 0x01, 0x02, 0x02, 0x48, 0x16, 0x03, 0x03, 0x50, 0x16, 0x03, 0x03, + 0x58, 0x16, 0x03, 0x03, 0xb0, 0x32, 0x04, 0x04, 0xc0, 0x32, 0x04, 0x04, 0x10, 0x0c, 0x05, 0x04, 0x80, 0x25, 0x06, 0x05, 0x80, 0x1b, 0x08, 0x06, 0x28, 0x38, 0x00, 0x03, 0x30, 0x38, 0x00, 0x03, + 0x38, 0x38, 0x00, 0x03, 0x40, 0x38, 0x00, 0x03, 0x84, 0x21, 0x01, 0x02, 0x88, 0x21, 0x01, 0x02, 0x8c, 0x21, 0x01, 0x02, 0x90, 0x21, 0x01, 0x02, 0x94, 0x21, 0x01, 0x02, 0x98, 0x21, 0x01, 0x02, + 0x9c, 0x21, 0x01, 0x02, 0x0c, 0x01, 0x02, 0x02, 0x10, 0x01, 0x02, 0x02, 0x14, 0x01, 0x02, 0x02, 0x18, 0x01, 0x02, 0x02, 0x1c, 0x01, 0x02, 0x02, 0x60, 0x16, 0x03, 0x03, 0x68, 0x16, 0x03, 0x03, + 0x70, 0x16, 0x03, 0x03, 0xd0, 0x32, 0x04, 0x04, 0xe0, 0x32, 0x04, 0x04, 0x20, 0x0c, 0x05, 0x04, 0xa0, 0x25, 0x06, 0x05, 0xc0, 0x1b, 0x08, 0x06, 0x48, 0x38, 0x00, 0x03, 0x50, 0x38, 0x00, 0x03, + 0x58, 0x38, 0x00, 0x03, 0x60, 0x38, 0x00, 0x03, 0xa0, 0x21, 0x01, 0x02, 0xa4, 0x21, 0x01, 0x02, 0xa8, 0x21, 0x01, 0x02, 0xac, 0x21, 0x01, 0x02, 0xb0, 0x21, 0x01, 0x02, 0xb4, 0x21, 0x01, 0x02, + 0xb8, 0x21, 0x01, 0x02, 0x20, 0x01, 0x02, 0x02, 0x24, 0x01, 0x02, 0x02, 0x28, 0x01, 0x02, 0x02, 0x2c, 0x01, 0x02, 0x02, 0x30, 0x01, 0x02, 0x02, 0x78, 0x16, 0x03, 0x03, 0x80, 0x16, 0x03, 0x03, + 0x88, 0x16, 0x03, 0x03, 0xf0, 0x32, 0x04, 0x04, 0x30, 0x0c, 0x05, 0x04, 0x40, 0x0c, 0x05, 0x04, 0xc0, 0x25, 0x06, 0x05, 0x00, 0x1c, 0x08, 0x06, 0x68, 0x38, 0x00, 0x03, 0x70, 0x38, 0x00, 0x03, + 0x78, 0x38, 0x00, 0x03, 0x80, 0x38, 0x00, 0x03, 0xbc, 0x21, 0x01, 0x02, 0xc0, 0x21, 0x01, 0x02, 0xc4, 0x21, 0x01, 0x02, 0xc8, 0x21, 0x01, 0x02, 0xcc, 0x21, 0x01, 0x02, 0xd0, 0x21, 0x01, 0x02, + 0xd4, 0x21, 0x01, 0x02, 0x34, 0x01, 0x02, 0x02, 0x38, 0x01, 0x02, 0x02, 0x3c, 0x01, 0x02, 0x02, 0x40, 0x01, 0x02, 0x02, 0x44, 0x01, 0x02, 0x02, 0x90, 0x16, 0x03, 0x03, 0x98, 0x16, 0x03, 0x03, + 0xa0, 0x16, 0x03, 0x03, 0x00, 0x33, 0x04, 0x04, 0x50, 0x0c, 0x05, 0x04, 0x60, 0x0c, 0x05, 0x04, 0xe0, 0x25, 0x06, 0x05, 0x40, 0x1c, 0x08, 0x06, 0x88, 0x38, 0x00, 0x03, 0x90, 0x38, 0x00, 0x03, + 0x98, 0x38, 0x00, 0x03, 0xa0, 0x38, 0x00, 0x03, 0xd8, 0x21, 0x01, 0x02, 0xdc, 0x21, 0x01, 0x02, 0xe0, 0x21, 0x01, 0x02, 0xe4, 0x21, 0x01, 0x02, 0xe8, 0x21, 0x01, 0x02, 0xec, 0x21, 0x01, 0x02, + 0xf0, 0x21, 0x01, 0x02, 0x48, 0x01, 0x02, 0x02, 0x4c, 0x01, 0x02, 0x02, 0x50, 0x01, 0x02, 0x02, 0x54, 0x01, 0x02, 0x02, 0x58, 0x01, 0x02, 0x02, 0xa8, 0x16, 0x03, 0x03, 0xb0, 0x16, 0x03, 0x03, + 0xb8, 0x16, 0x03, 0x03, 0x10, 0x33, 0x04, 0x04, 0x70, 0x0c, 0x05, 0x04, 0x80, 0x0c, 0x05, 0x04, 0x00, 0x26, 0x06, 0x05, 0x80, 0x1c, 0x08, 0x06, 0xa8, 0x38, 0x00, 0x03, 0xb0, 0x38, 0x00, 0x03, + 0xb8, 0x38, 0x00, 0x03, 0xc0, 0x38, 0x00, 0x03, 0xf4, 0x21, 0x01, 0x02, 0xf8, 0x21, 0x01, 0x02, 0xfc, 0x21, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x04, 0x22, 0x01, 0x02, 0x08, 0x22, 0x01, 0x02, + 0x0c, 0x22, 0x01, 0x02, 0x5c, 0x01, 0x02, 0x02, 0x60, 0x01, 0x02, 0x02, 0x64, 0x01, 0x02, 0x02, 0x68, 0x01, 0x02, 0x02, 0x6c, 0x01, 0x02, 0x02, 0xc0, 0x16, 0x03, 0x03, 0xc8, 0x16, 0x03, 0x03, + 0xd0, 0x16, 0x03, 0x03, 0x20, 0x33, 0x04, 0x04, 0x90, 0x0c, 0x05, 0x04, 0xa0, 0x0c, 0x05, 0x04, 0x20, 0x26, 0x06, 0x05, 0xc0, 0x1c, 0x08, 0x06, 0xc8, 0x38, 0x00, 0x03, 0xd0, 0x38, 0x00, 0x03, + 0xd8, 0x38, 0x00, 0x03, 0xe0, 0x38, 0x00, 0x03, 0x10, 0x22, 0x01, 0x02, 0x14, 0x22, 0x01, 0x02, 0x18, 0x22, 0x01, 0x02, 0x1c, 0x22, 0x01, 0x02, 0x20, 0x22, 0x01, 0x02, 0x24, 0x22, 0x01, 0x02, + 0x28, 0x22, 0x01, 0x02, 0x70, 0x01, 0x02, 0x02, 0x74, 0x01, 0x02, 0x02, 0x78, 0x01, 0x02, 0x02, 0x7c, 0x01, 0x02, 0x02, 0x80, 0x01, 0x02, 0x02, 0xd8, 0x16, 0x03, 0x03, 0xe0, 0x16, 0x03, 0x03, + 0x30, 0x33, 0x04, 0x04, 0x40, 0x33, 0x04, 0x04, 0xb0, 0x0c, 0x05, 0x04, 0xc0, 0x0c, 0x05, 0x04, 0x40, 0x26, 0x06, 0x05, 0x00, 0x1d, 0x08, 0x06, 0xe8, 0x38, 0x00, 0x03, 0xf0, 0x38, 0x00, 0x03, + 0xf8, 0x38, 0x00, 0x03, 0x00, 0x39, 0x00, 0x03, 0x2c, 0x22, 0x01, 0x02, 0x30, 0x22, 0x01, 0x02, 0x34, 0x22, 0x01, 0x02, 0x38, 0x22, 0x01, 0x02, 0x3c, 0x22, 0x01, 0x02, 0x40, 0x22, 0x01, 0x02, + 0x44, 0x22, 0x01, 0x02, 0x84, 0x01, 0x02, 0x02, 0x88, 0x01, 0x02, 0x02, 0x8c, 0x01, 0x02, 0x02, 0x90, 0x01, 0x02, 0x02, 0x94, 0x01, 0x02, 0x02, 0xe8, 0x16, 0x03, 0x03, 0xf0, 0x16, 0x03, 0x03, + 0x50, 0x33, 0x04, 0x04, 0x60, 0x33, 0x04, 0x04, 0xd0, 0x0c, 0x05, 0x04, 0xe0, 0x0c, 0x05, 0x04, 0x60, 0x26, 0x06, 0x05, 0x40, 0x1d, 0x08, 0x06, 0x08, 0x39, 0x00, 0x03, 0x10, 0x39, 0x00, 0x03, + 0x18, 0x39, 0x00, 0x03, 0x20, 0x39, 0x00, 0x03, 0x48, 0x22, 0x01, 0x02, 0x4c, 0x22, 0x01, 0x02, 0x50, 0x22, 0x01, 0x02, 0x54, 0x22, 0x01, 0x02, 0x58, 0x22, 0x01, 0x02, 0x5c, 0x22, 0x01, 0x02, + 0x60, 0x22, 0x01, 0x02, 0x98, 0x01, 0x02, 0x02, 0x9c, 0x01, 0x02, 0x02, 0xa0, 0x01, 0x02, 0x02, 0xa4, 0x01, 0x02, 0x02, 0xa8, 0x01, 0x02, 0x02, 0xf8, 0x16, 0x03, 0x03, 0x00, 0x17, 0x03, 0x03, + 0x70, 0x33, 0x04, 0x04, 0x80, 0x33, 0x04, 0x04, 0xf0, 0x0c, 0x05, 0x04, 0x00, 0x0d, 0x05, 0x04, 0x80, 0x26, 0x06, 0x05, 0x80, 0x1d, 0x08, 0x06, 0x28, 0x39, 0x00, 0x03, 0x30, 0x39, 0x00, 0x03, + 0x38, 0x39, 0x00, 0x03, 0x40, 0x39, 0x00, 0x03, 0x64, 0x22, 0x01, 0x02, 0x68, 0x22, 0x01, 0x02, 0x6c, 0x22, 0x01, 0x02, 0x70, 0x22, 0x01, 0x02, 0x74, 0x22, 0x01, 0x02, 0x78, 0x22, 0x01, 0x02, + 0x7c, 0x22, 0x01, 0x02, 0xac, 0x01, 0x02, 0x02, 0xb0, 0x01, 0x02, 0x02, 0xb4, 0x01, 0x02, 0x02, 0xb8, 0x01, 0x02, 0x02, 0xbc, 0x01, 0x02, 0x02, 0x08, 0x17, 0x03, 0x03, 0x10, 0x17, 0x03, 0x03, + 0x90, 0x33, 0x04, 0x04, 0xa0, 0x33, 0x04, 0x04, 0x10, 0x0d, 0x05, 0x04, 0x20, 0x0d, 0x05, 0x04, 0xa0, 0x26, 0x06, 0x05, 0xc0, 0x1d, 0x08, 0x06, 0x48, 0x39, 0x00, 0x03, 0x50, 0x39, 0x00, 0x03, + 0x58, 0x39, 0x00, 0x03, 0x60, 0x39, 0x00, 0x03, 0x80, 0x22, 0x01, 0x02, 0x84, 0x22, 0x01, 0x02, 0x88, 0x22, 0x01, 0x02, 0x8c, 0x22, 0x01, 0x02, 0x90, 0x22, 0x01, 0x02, 0x94, 0x22, 0x01, 0x02, + 0x98, 0x22, 0x01, 0x02, 0xc0, 0x01, 0x02, 0x02, 0xc4, 0x01, 0x02, 0x02, 0xc8, 0x01, 0x02, 0x02, 0xcc, 0x01, 0x02, 0x02, 0x18, 0x17, 0x03, 0x03, 0x20, 0x17, 0x03, 0x03, 0x28, 0x17, 0x03, 0x03, + 0xb0, 0x33, 0x04, 0x04, 0xc0, 0x33, 0x04, 0x04, 0x30, 0x0d, 0x05, 0x04, 0x40, 0x0d, 0x05, 0x04, 0xc0, 0x26, 0x06, 0x05, 0x00, 0x1e, 0x08, 0x06, 0x68, 0x39, 0x00, 0x03, 0x70, 0x39, 0x00, 0x03, + 0x78, 0x39, 0x00, 0x03, 0x80, 0x39, 0x00, 0x03, 0x9c, 0x22, 0x01, 0x02, 0xa0, 0x22, 0x01, 0x02, 0xa4, 0x22, 0x01, 0x02, 0xa8, 0x22, 0x01, 0x02, 0xac, 0x22, 0x01, 0x02, 0xb0, 0x22, 0x01, 0x02, + 0xb4, 0x22, 0x01, 0x02, 0xd0, 0x01, 0x02, 0x02, 0xd4, 0x01, 0x02, 0x02, 0xd8, 0x01, 0x02, 0x02, 0xdc, 0x01, 0x02, 0x02, 0x30, 0x17, 0x03, 0x03, 0x38, 0x17, 0x03, 0x03, 0x40, 0x17, 0x03, 0x03, + 0xd0, 0x33, 0x04, 0x04, 0xe0, 0x33, 0x04, 0x04, 0x50, 0x0d, 0x05, 0x04, 0x60, 0x0d, 0x05, 0x04, 0xe0, 0x26, 0x06, 0x05, 0x40, 0x1e, 0x08, 0x06, 0x88, 0x39, 0x00, 0x03, 0x90, 0x39, 0x00, 0x03, + 0x98, 0x39, 0x00, 0x03, 0xa0, 0x39, 0x00, 0x03, 0xb8, 0x22, 0x01, 0x02, 0xbc, 0x22, 0x01, 0x02, 0xc0, 0x22, 0x01, 0x02, 0xc4, 0x22, 0x01, 0x02, 0xc8, 0x22, 0x01, 0x02, 0xcc, 0x22, 0x01, 0x02, + 0xd0, 0x22, 0x01, 0x02, 0xe0, 0x01, 0x02, 0x02, 0xe4, 0x01, 0x02, 0x02, 0xe8, 0x01, 0x02, 0x02, 0xec, 0x01, 0x02, 0x02, 0x48, 0x17, 0x03, 0x03, 0x50, 0x17, 0x03, 0x03, 0x58, 0x17, 0x03, 0x03, + 0xf0, 0x33, 0x04, 0x04, 0x00, 0x34, 0x04, 0x04, 0x70, 0x0d, 0x05, 0x04, 0x80, 0x0d, 0x05, 0x04, 0x00, 0x27, 0x06, 0x05, 0x80, 0x1e, 0x08, 0x06, 0xa8, 0x39, 0x00, 0x03, 0xb0, 0x39, 0x00, 0x03, + 0xb8, 0x39, 0x00, 0x03, 0xc0, 0x39, 0x00, 0x03, 0xd4, 0x22, 0x01, 0x02, 0xd8, 0x22, 0x01, 0x02, 0xdc, 0x22, 0x01, 0x02, 0xe0, 0x22, 0x01, 0x02, 0xe4, 0x22, 0x01, 0x02, 0xe8, 0x22, 0x01, 0x02, + 0xec, 0x22, 0x01, 0x02, 0xf0, 0x01, 0x02, 0x02, 0xf4, 0x01, 0x02, 0x02, 0xf8, 0x01, 0x02, 0x02, 0xfc, 0x01, 0x02, 0x02, 0x60, 0x17, 0x03, 0x03, 0x68, 0x17, 0x03, 0x03, 0x70, 0x17, 0x03, 0x03, + 0x10, 0x34, 0x04, 0x04, 0x20, 0x34, 0x04, 0x04, 0x90, 0x0d, 0x05, 0x04, 0xa0, 0x0d, 0x05, 0x04, 0x20, 0x27, 0x06, 0x05, 0x80, 0x35, 0x09, 0x07, 0xc8, 0x39, 0x00, 0x03, 0xd0, 0x39, 0x00, 0x03, + 0xd8, 0x39, 0x00, 0x03, 0xe0, 0x39, 0x00, 0x03, 0xf0, 0x22, 0x01, 0x02, 0xf4, 0x22, 0x01, 0x02, 0xf8, 0x22, 0x01, 0x02, 0xfc, 0x22, 0x01, 0x02, 0x00, 0x23, 0x01, 0x02, 0x04, 0x23, 0x01, 0x02, + 0x08, 0x23, 0x01, 0x02, 0x00, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x08, 0x02, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x02, 0x78, 0x17, 0x03, 0x03, 0x80, 0x17, 0x03, 0x03, 0x88, 0x17, 0x03, 0x03, + 0x30, 0x34, 0x04, 0x04, 0x40, 0x34, 0x04, 0x04, 0xb0, 0x0d, 0x05, 0x04, 0xc0, 0x0d, 0x05, 0x04, 0x40, 0x27, 0x06, 0x05, 0x00, 0x36, 0x09, 0x07, 0xe8, 0x39, 0x00, 0x03, 0xf0, 0x39, 0x00, 0x03, + 0xf8, 0x39, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x03, 0x0c, 0x23, 0x01, 0x02, 0x10, 0x23, 0x01, 0x02, 0x14, 0x23, 0x01, 0x02, 0x18, 0x23, 0x01, 0x02, 0x1c, 0x23, 0x01, 0x02, 0x20, 0x23, 0x01, 0x02, + 0x24, 0x23, 0x01, 0x02, 0x10, 0x02, 0x02, 0x02, 0x14, 0x02, 0x02, 0x02, 0x18, 0x02, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0x90, 0x17, 0x03, 0x03, 0x98, 0x17, 0x03, 0x03, 0xa0, 0x17, 0x03, 0x03, + 0x50, 0x34, 0x04, 0x04, 0x60, 0x34, 0x04, 0x04, 0xd0, 0x0d, 0x05, 0x04, 0xe0, 0x0d, 0x05, 0x04, 0x60, 0x27, 0x06, 0x05, 0x80, 0x36, 0x09, 0x07, 0x08, 0x3a, 0x00, 0x03, 0x10, 0x3a, 0x00, 0x03, + 0x18, 0x3a, 0x00, 0x03, 0x20, 0x3a, 0x00, 0x03, 0x28, 0x23, 0x01, 0x02, 0x2c, 0x23, 0x01, 0x02, 0x30, 0x23, 0x01, 0x02, 0x34, 0x23, 0x01, 0x02, 0x38, 0x23, 0x01, 0x02, 0x3c, 0x23, 0x01, 0x02, + 0x40, 0x23, 0x01, 0x02, 0x20, 0x02, 0x02, 0x02, 0x24, 0x02, 0x02, 0x02, 0x28, 0x02, 0x02, 0x02, 0x2c, 0x02, 0x02, 0x02, 0xa8, 0x17, 0x03, 0x03, 0xb0, 0x17, 0x03, 0x03, 0xb8, 0x17, 0x03, 0x03, + 0x70, 0x34, 0x04, 0x04, 0x80, 0x34, 0x04, 0x04, 0xf0, 0x0d, 0x05, 0x04, 0x00, 0x0e, 0x05, 0x04, 0x80, 0x27, 0x06, 0x05, 0x00, 0x37, 0x09, 0x07, 0x28, 0x3a, 0x00, 0x03, 0x30, 0x3a, 0x00, 0x03, + 0x38, 0x3a, 0x00, 0x03, 0x40, 0x3a, 0x00, 0x03, 0x44, 0x23, 0x01, 0x02, 0x48, 0x23, 0x01, 0x02, 0x4c, 0x23, 0x01, 0x02, 0x50, 0x23, 0x01, 0x02, 0x54, 0x23, 0x01, 0x02, 0x58, 0x23, 0x01, 0x02, + 0x5c, 0x23, 0x01, 0x02, 0x30, 0x02, 0x02, 0x02, 0x34, 0x02, 0x02, 0x02, 0x38, 0x02, 0x02, 0x02, 0x3c, 0x02, 0x02, 0x02, 0xc0, 0x17, 0x03, 0x03, 0xc8, 0x17, 0x03, 0x03, 0xd0, 0x17, 0x03, 0x03, + 0x90, 0x34, 0x04, 0x04, 0xa0, 0x34, 0x04, 0x04, 0x10, 0x0e, 0x05, 0x04, 0x20, 0x0e, 0x05, 0x04, 0xa0, 0x02, 0x07, 0x05, 0x80, 0x37, 0x09, 0x07, 0x48, 0x3a, 0x00, 0x03, 0x50, 0x3a, 0x00, 0x03, + 0x58, 0x3a, 0x00, 0x03, 0x60, 0x3a, 0x00, 0x03, 0x60, 0x23, 0x01, 0x02, 0x64, 0x23, 0x01, 0x02, 0x68, 0x23, 0x01, 0x02, 0x6c, 0x23, 0x01, 0x02, 0x70, 0x23, 0x01, 0x02, 0x74, 0x23, 0x01, 0x02, + 0x78, 0x23, 0x01, 0x02, 0x40, 0x02, 0x02, 0x02, 0x44, 0x02, 0x02, 0x02, 0x48, 0x02, 0x02, 0x02, 0x4c, 0x02, 0x02, 0x02, 0xd8, 0x17, 0x03, 0x03, 0xe0, 0x17, 0x03, 0x03, 0xe8, 0x17, 0x03, 0x03, + 0xb0, 0x34, 0x04, 0x04, 0xc0, 0x34, 0x04, 0x04, 0x30, 0x0e, 0x05, 0x04, 0x40, 0x0e, 0x05, 0x04, 0xc0, 0x02, 0x07, 0x05, 0x00, 0x38, 0x09, 0x07, 0x68, 0x3a, 0x00, 0x03, 0x70, 0x3a, 0x00, 0x03, + 0x78, 0x3a, 0x00, 0x03, 0x80, 0x3a, 0x00, 0x03, 0x7c, 0x23, 0x01, 0x02, 0x80, 0x23, 0x01, 0x02, 0x84, 0x23, 0x01, 0x02, 0x88, 0x23, 0x01, 0x02, 0x8c, 0x23, 0x01, 0x02, 0x90, 0x23, 0x01, 0x02, + 0x94, 0x23, 0x01, 0x02, 0x50, 0x02, 0x02, 0x02, 0x54, 0x02, 0x02, 0x02, 0x58, 0x02, 0x02, 0x02, 0x5c, 0x02, 0x02, 0x02, 0xf0, 0x17, 0x03, 0x03, 0xf8, 0x17, 0x03, 0x03, 0x00, 0x18, 0x03, 0x03, + 0xd0, 0x34, 0x04, 0x04, 0xe0, 0x34, 0x04, 0x04, 0x50, 0x0e, 0x05, 0x04, 0x60, 0x0e, 0x05, 0x04, 0xe0, 0x02, 0x07, 0x05, 0x80, 0x38, 0x09, 0x07, 0x88, 0x3a, 0x00, 0x03, 0x90, 0x3a, 0x00, 0x03, + 0x98, 0x3a, 0x00, 0x03, 0xa0, 0x3a, 0x00, 0x03, 0x98, 0x23, 0x01, 0x02, 0x9c, 0x23, 0x01, 0x02, 0xa0, 0x23, 0x01, 0x02, 0xa4, 0x23, 0x01, 0x02, 0xa8, 0x23, 0x01, 0x02, 0xac, 0x23, 0x01, 0x02, + 0xb0, 0x23, 0x01, 0x02, 0x60, 0x02, 0x02, 0x02, 0x64, 0x02, 0x02, 0x02, 0x68, 0x02, 0x02, 0x02, 0x6c, 0x02, 0x02, 0x02, 0x08, 0x18, 0x03, 0x03, 0x10, 0x18, 0x03, 0x03, 0x18, 0x18, 0x03, 0x03, + 0xf0, 0x34, 0x04, 0x04, 0x00, 0x35, 0x04, 0x04, 0x70, 0x0e, 0x05, 0x04, 0x80, 0x0e, 0x05, 0x04, 0x00, 0x03, 0x07, 0x05, 0x00, 0x39, 0x09, 0x07, 0xa8, 0x3a, 0x00, 0x03, 0xb0, 0x3a, 0x00, 0x03, + 0xb8, 0x3a, 0x00, 0x03, 0xc0, 0x3a, 0x00, 0x03, 0xb4, 0x23, 0x01, 0x02, 0xb8, 0x23, 0x01, 0x02, 0xbc, 0x23, 0x01, 0x02, 0xc0, 0x23, 0x01, 0x02, 0xc4, 0x23, 0x01, 0x02, 0xc8, 0x23, 0x01, 0x02, + 0xcc, 0x23, 0x01, 0x02, 0x70, 0x02, 0x02, 0x02, 0x74, 0x02, 0x02, 0x02, 0x78, 0x02, 0x02, 0x02, 0x7c, 0x02, 0x02, 0x02, 0x20, 0x18, 0x03, 0x03, 0x28, 0x18, 0x03, 0x03, 0x30, 0x18, 0x03, 0x03, + 0x10, 0x35, 0x04, 0x04, 0x20, 0x35, 0x04, 0x04, 0x90, 0x0e, 0x05, 0x04, 0xa0, 0x0e, 0x05, 0x04, 0x20, 0x03, 0x07, 0x05, 0x80, 0x39, 0x09, 0x07, 0xc8, 0x3a, 0x00, 0x03, 0xd0, 0x3a, 0x00, 0x03, + 0xd8, 0x3a, 0x00, 0x03, 0xe0, 0x3a, 0x00, 0x03, 0xd0, 0x23, 0x01, 0x02, 0xd4, 0x23, 0x01, 0x02, 0xd8, 0x23, 0x01, 0x02, 0xdc, 0x23, 0x01, 0x02, 0xe0, 0x23, 0x01, 0x02, 0xe4, 0x23, 0x01, 0x02, + 0xe8, 0x23, 0x01, 0x02, 0x80, 0x02, 0x02, 0x02, 0x84, 0x02, 0x02, 0x02, 0x88, 0x02, 0x02, 0x02, 0x8c, 0x02, 0x02, 0x02, 0x38, 0x18, 0x03, 0x03, 0x40, 0x18, 0x03, 0x03, 0x48, 0x18, 0x03, 0x03, + 0x30, 0x35, 0x04, 0x04, 0x40, 0x35, 0x04, 0x04, 0xb0, 0x0e, 0x05, 0x04, 0xc0, 0x0e, 0x05, 0x04, 0x40, 0x03, 0x07, 0x05, 0x00, 0x3a, 0x09, 0x07, 0xe8, 0x3a, 0x00, 0x03, 0xf0, 0x3a, 0x00, 0x03, + 0xf8, 0x3a, 0x00, 0x03, 0x00, 0x3b, 0x00, 0x03, 0xec, 0x23, 0x01, 0x02, 0xf0, 0x23, 0x01, 0x02, 0xf4, 0x23, 0x01, 0x02, 0xf8, 0x23, 0x01, 0x02, 0xfc, 0x23, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, + 0x04, 0x24, 0x01, 0x02, 0x90, 0x02, 0x02, 0x02, 0x94, 0x02, 0x02, 0x02, 0x98, 0x02, 0x02, 0x02, 0x9c, 0x02, 0x02, 0x02, 0x50, 0x18, 0x03, 0x03, 0x58, 0x18, 0x03, 0x03, 0x60, 0x18, 0x03, 0x03, + 0x50, 0x35, 0x04, 0x04, 0x60, 0x35, 0x04, 0x04, 0xd0, 0x0e, 0x05, 0x04, 0xe0, 0x0e, 0x05, 0x04, 0x60, 0x03, 0x07, 0x05, 0x80, 0x3a, 0x09, 0x07, 0x08, 0x3b, 0x00, 0x03, 0x10, 0x3b, 0x00, 0x03, + 0x18, 0x3b, 0x00, 0x03, 0x20, 0x3b, 0x00, 0x03, 0x08, 0x24, 0x01, 0x02, 0x0c, 0x24, 0x01, 0x02, 0x10, 0x24, 0x01, 0x02, 0x14, 0x24, 0x01, 0x02, 0x18, 0x24, 0x01, 0x02, 0x1c, 0x24, 0x01, 0x02, + 0x20, 0x24, 0x01, 0x02, 0xa0, 0x02, 0x02, 0x02, 0xa4, 0x02, 0x02, 0x02, 0xa8, 0x02, 0x02, 0x02, 0xac, 0x02, 0x02, 0x02, 0x68, 0x18, 0x03, 0x03, 0x70, 0x18, 0x03, 0x03, 0x78, 0x18, 0x03, 0x03, + 0x70, 0x35, 0x04, 0x04, 0x80, 0x35, 0x04, 0x04, 0xf0, 0x0e, 0x05, 0x04, 0x00, 0x0f, 0x05, 0x04, 0x80, 0x03, 0x07, 0x05, 0x00, 0x3b, 0x09, 0x07, 0x28, 0x3b, 0x00, 0x03, 0x30, 0x3b, 0x00, 0x03, + 0x38, 0x3b, 0x00, 0x03, 0x40, 0x3b, 0x00, 0x03, 0x24, 0x24, 0x01, 0x02, 0x28, 0x24, 0x01, 0x02, 0x2c, 0x24, 0x01, 0x02, 0x30, 0x24, 0x01, 0x02, 0x34, 0x24, 0x01, 0x02, 0x38, 0x24, 0x01, 0x02, + 0x3c, 0x24, 0x01, 0x02, 0xb0, 0x02, 0x02, 0x02, 0xb4, 0x02, 0x02, 0x02, 0xb8, 0x02, 0x02, 0x02, 0xbc, 0x02, 0x02, 0x02, 0x80, 0x18, 0x03, 0x03, 0x88, 0x18, 0x03, 0x03, 0x90, 0x18, 0x03, 0x03, + 0x90, 0x35, 0x04, 0x04, 0xa0, 0x35, 0x04, 0x04, 0x10, 0x0f, 0x05, 0x04, 0x20, 0x0f, 0x05, 0x04, 0xa0, 0x03, 0x07, 0x05, 0x80, 0x3b, 0x09, 0x07, 0x48, 0x3b, 0x00, 0x03, 0x50, 0x3b, 0x00, 0x03, + 0x58, 0x3b, 0x00, 0x03, 0x60, 0x3b, 0x00, 0x03, 0x40, 0x24, 0x01, 0x02, 0x44, 0x24, 0x01, 0x02, 0x48, 0x24, 0x01, 0x02, 0x4c, 0x24, 0x01, 0x02, 0x50, 0x24, 0x01, 0x02, 0x54, 0x24, 0x01, 0x02, + 0x58, 0x24, 0x01, 0x02, 0xc0, 0x02, 0x02, 0x02, 0xc4, 0x02, 0x02, 0x02, 0xc8, 0x02, 0x02, 0x02, 0xcc, 0x02, 0x02, 0x02, 0x98, 0x18, 0x03, 0x03, 0xa0, 0x18, 0x03, 0x03, 0xa8, 0x18, 0x03, 0x03, + 0xb0, 0x35, 0x04, 0x04, 0xc0, 0x35, 0x04, 0x04, 0x30, 0x0f, 0x05, 0x04, 0x40, 0x0f, 0x05, 0x04, 0xc0, 0x03, 0x07, 0x05, 0x00, 0x3c, 0x09, 0x07, 0x68, 0x3b, 0x00, 0x03, 0x70, 0x3b, 0x00, 0x03, + 0x78, 0x3b, 0x00, 0x03, 0x80, 0x3b, 0x00, 0x03, 0x5c, 0x24, 0x01, 0x02, 0x60, 0x24, 0x01, 0x02, 0x64, 0x24, 0x01, 0x02, 0x68, 0x24, 0x01, 0x02, 0x6c, 0x24, 0x01, 0x02, 0x70, 0x24, 0x01, 0x02, + 0x74, 0x24, 0x01, 0x02, 0xd0, 0x02, 0x02, 0x02, 0xd4, 0x02, 0x02, 0x02, 0xd8, 0x02, 0x02, 0x02, 0xdc, 0x02, 0x02, 0x02, 0xb0, 0x18, 0x03, 0x03, 0xb8, 0x18, 0x03, 0x03, 0xc0, 0x18, 0x03, 0x03, + 0xd0, 0x35, 0x04, 0x04, 0xe0, 0x35, 0x04, 0x04, 0x50, 0x0f, 0x05, 0x04, 0x60, 0x0f, 0x05, 0x04, 0xe0, 0x03, 0x07, 0x05, 0x80, 0x3c, 0x09, 0x07, 0x88, 0x3b, 0x00, 0x03, 0x90, 0x3b, 0x00, 0x03, + 0x98, 0x3b, 0x00, 0x03, 0xa0, 0x3b, 0x00, 0x03, 0x78, 0x24, 0x01, 0x02, 0x7c, 0x24, 0x01, 0x02, 0x80, 0x24, 0x01, 0x02, 0x84, 0x24, 0x01, 0x02, 0x88, 0x24, 0x01, 0x02, 0x8c, 0x24, 0x01, 0x02, + 0x90, 0x24, 0x01, 0x02, 0xe0, 0x02, 0x02, 0x02, 0xe4, 0x02, 0x02, 0x02, 0xe8, 0x02, 0x02, 0x02, 0xec, 0x02, 0x02, 0x02, 0xc8, 0x18, 0x03, 0x03, 0xd0, 0x18, 0x03, 0x03, 0xd8, 0x18, 0x03, 0x03, + 0xf0, 0x35, 0x04, 0x04, 0x00, 0x36, 0x04, 0x04, 0x70, 0x0f, 0x05, 0x04, 0xa0, 0x27, 0x06, 0x05, 0x00, 0x04, 0x07, 0x05, 0x00, 0x3d, 0x09, 0x07, 0xa8, 0x3b, 0x00, 0x03, 0xb0, 0x3b, 0x00, 0x03, + 0xb8, 0x3b, 0x00, 0x03, 0xc0, 0x3b, 0x00, 0x03, 0x94, 0x24, 0x01, 0x02, 0x98, 0x24, 0x01, 0x02, 0x9c, 0x24, 0x01, 0x02, 0xa0, 0x24, 0x01, 0x02, 0xa4, 0x24, 0x01, 0x02, 0xa8, 0x24, 0x01, 0x02, + 0xac, 0x24, 0x01, 0x02, 0xf0, 0x02, 0x02, 0x02, 0xf4, 0x02, 0x02, 0x02, 0xf8, 0x02, 0x02, 0x02, 0xfc, 0x02, 0x02, 0x02, 0xe0, 0x18, 0x03, 0x03, 0xe8, 0x18, 0x03, 0x03, 0xf0, 0x18, 0x03, 0x03, + 0x10, 0x36, 0x04, 0x04, 0x20, 0x36, 0x04, 0x04, 0x80, 0x0f, 0x05, 0x04, 0xc0, 0x27, 0x06, 0x05, 0x20, 0x04, 0x07, 0x05, 0x80, 0x3d, 0x09, 0x07, 0xc8, 0x3b, 0x00, 0x03, 0xd0, 0x3b, 0x00, 0x03, + 0xd8, 0x3b, 0x00, 0x03, 0xe0, 0x3b, 0x00, 0x03, 0xb0, 0x24, 0x01, 0x02, 0xb4, 0x24, 0x01, 0x02, 0xb8, 0x24, 0x01, 0x02, 0xbc, 0x24, 0x01, 0x02, 0xc0, 0x24, 0x01, 0x02, 0xc4, 0x24, 0x01, 0x02, + 0xc8, 0x24, 0x01, 0x02, 0x00, 0x03, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x08, 0x03, 0x02, 0x02, 0x0c, 0x03, 0x02, 0x02, 0xf8, 0x18, 0x03, 0x03, 0x00, 0x19, 0x03, 0x03, 0x08, 0x19, 0x03, 0x03, + 0x30, 0x36, 0x04, 0x04, 0x40, 0x36, 0x04, 0x04, 0x90, 0x0f, 0x05, 0x04, 0xe0, 0x27, 0x06, 0x05, 0x40, 0x04, 0x07, 0x05, 0x00, 0x3e, 0x09, 0x07, 0xe8, 0x3b, 0x00, 0x03, 0xf0, 0x3b, 0x00, 0x03, + 0xf8, 0x3b, 0x00, 0x03, 0x00, 0x3c, 0x00, 0x03, 0xcc, 0x24, 0x01, 0x02, 0xd0, 0x24, 0x01, 0x02, 0xd4, 0x24, 0x01, 0x02, 0xd8, 0x24, 0x01, 0x02, 0xdc, 0x24, 0x01, 0x02, 0xe0, 0x24, 0x01, 0x02, + 0xe4, 0x24, 0x01, 0x02, 0x10, 0x03, 0x02, 0x02, 0x14, 0x03, 0x02, 0x02, 0x18, 0x03, 0x02, 0x02, 0x1c, 0x03, 0x02, 0x02, 0x10, 0x19, 0x03, 0x03, 0x18, 0x19, 0x03, 0x03, 0x20, 0x19, 0x03, 0x03, + 0x50, 0x36, 0x04, 0x04, 0x60, 0x36, 0x04, 0x04, 0xa0, 0x0f, 0x05, 0x04, 0x00, 0x28, 0x06, 0x05, 0x60, 0x04, 0x07, 0x05, 0x80, 0x3e, 0x09, 0x07, 0x08, 0x3c, 0x00, 0x03, 0x10, 0x3c, 0x00, 0x03, + 0x18, 0x3c, 0x00, 0x03, 0x20, 0x3c, 0x00, 0x03, 0xe8, 0x24, 0x01, 0x02, 0xec, 0x24, 0x01, 0x02, 0xf0, 0x24, 0x01, 0x02, 0xf4, 0x24, 0x01, 0x02, 0xf8, 0x24, 0x01, 0x02, 0xfc, 0x24, 0x01, 0x02, + 0x00, 0x25, 0x01, 0x02, 0x20, 0x03, 0x02, 0x02, 0x24, 0x03, 0x02, 0x02, 0x28, 0x03, 0x02, 0x02, 0x2c, 0x03, 0x02, 0x02, 0x28, 0x19, 0x03, 0x03, 0x30, 0x19, 0x03, 0x03, 0x38, 0x19, 0x03, 0x03, + 0x70, 0x36, 0x04, 0x04, 0x80, 0x36, 0x04, 0x04, 0xb0, 0x0f, 0x05, 0x04, 0x20, 0x28, 0x06, 0x05, 0x80, 0x04, 0x07, 0x05, 0x00, 0x3f, 0x09, 0x07, 0x28, 0x3c, 0x00, 0x03, 0x30, 0x3c, 0x00, 0x03, + 0x38, 0x3c, 0x00, 0x03, 0x40, 0x3c, 0x00, 0x03, 0x04, 0x25, 0x01, 0x02, 0x08, 0x25, 0x01, 0x02, 0x0c, 0x25, 0x01, 0x02, 0x10, 0x25, 0x01, 0x02, 0x14, 0x25, 0x01, 0x02, 0x18, 0x25, 0x01, 0x02, + 0x1c, 0x25, 0x01, 0x02, 0x30, 0x03, 0x02, 0x02, 0x34, 0x03, 0x02, 0x02, 0x38, 0x03, 0x02, 0x02, 0x3c, 0x03, 0x02, 0x02, 0x40, 0x19, 0x03, 0x03, 0x48, 0x19, 0x03, 0x03, 0x50, 0x19, 0x03, 0x03, + 0x90, 0x36, 0x04, 0x04, 0xa0, 0x36, 0x04, 0x04, 0xc0, 0x0f, 0x05, 0x04, 0x40, 0x28, 0x06, 0x05, 0xa0, 0x04, 0x07, 0x05, 0x80, 0x3f, 0x09, 0x07, 0x48, 0x3c, 0x00, 0x03, 0x50, 0x3c, 0x00, 0x03, + 0x58, 0x3c, 0x00, 0x03, 0x60, 0x3c, 0x00, 0x03, 0x20, 0x25, 0x01, 0x02, 0x24, 0x25, 0x01, 0x02, 0x28, 0x25, 0x01, 0x02, 0x2c, 0x25, 0x01, 0x02, 0x30, 0x25, 0x01, 0x02, 0x34, 0x25, 0x01, 0x02, + 0x38, 0x25, 0x01, 0x02, 0x40, 0x03, 0x02, 0x02, 0x44, 0x03, 0x02, 0x02, 0x48, 0x03, 0x02, 0x02, 0x4c, 0x03, 0x02, 0x02, 0x58, 0x19, 0x03, 0x03, 0x60, 0x19, 0x03, 0x03, 0x68, 0x19, 0x03, 0x03, + 0xb0, 0x36, 0x04, 0x04, 0xc0, 0x36, 0x04, 0x04, 0xd0, 0x0f, 0x05, 0x04, 0x60, 0x28, 0x06, 0x05, 0xc0, 0x04, 0x07, 0x05, 0x00, 0x00, 0x09, 0x06, 0x68, 0x3c, 0x00, 0x03, 0x70, 0x3c, 0x00, 0x03, + 0x78, 0x3c, 0x00, 0x03, 0x80, 0x3c, 0x00, 0x03, 0x3c, 0x25, 0x01, 0x02, 0x40, 0x25, 0x01, 0x02, 0x44, 0x25, 0x01, 0x02, 0x48, 0x25, 0x01, 0x02, 0x4c, 0x25, 0x01, 0x02, 0x50, 0x25, 0x01, 0x02, + 0x54, 0x25, 0x01, 0x02, 0x50, 0x03, 0x02, 0x02, 0x54, 0x03, 0x02, 0x02, 0x58, 0x03, 0x02, 0x02, 0x5c, 0x03, 0x02, 0x02, 0x70, 0x19, 0x03, 0x03, 0x78, 0x19, 0x03, 0x03, 0x80, 0x19, 0x03, 0x03, + 0xd0, 0x36, 0x04, 0x04, 0xe0, 0x36, 0x04, 0x04, 0xe0, 0x0f, 0x05, 0x04, 0x80, 0x28, 0x06, 0x05, 0xe0, 0x04, 0x07, 0x05, 0x80, 0x0e, 0x0a, 0x07, 0x88, 0x3c, 0x00, 0x03, 0x90, 0x3c, 0x00, 0x03, + 0x98, 0x3c, 0x00, 0x03, 0xa0, 0x3c, 0x00, 0x03, 0x58, 0x25, 0x01, 0x02, 0x5c, 0x25, 0x01, 0x02, 0x60, 0x25, 0x01, 0x02, 0x64, 0x25, 0x01, 0x02, 0x68, 0x25, 0x01, 0x02, 0x6c, 0x25, 0x01, 0x02, + 0x70, 0x25, 0x01, 0x02, 0x60, 0x03, 0x02, 0x02, 0x64, 0x03, 0x02, 0x02, 0x68, 0x03, 0x02, 0x02, 0x6c, 0x03, 0x02, 0x02, 0x88, 0x19, 0x03, 0x03, 0x90, 0x19, 0x03, 0x03, 0x98, 0x19, 0x03, 0x03, + 0xf0, 0x36, 0x04, 0x04, 0x00, 0x37, 0x04, 0x04, 0xf0, 0x0f, 0x05, 0x04, 0xa0, 0x28, 0x06, 0x05, 0x00, 0x05, 0x07, 0x05, 0x00, 0x0f, 0x0a, 0x07, 0xa8, 0x3c, 0x00, 0x03, 0xb0, 0x3c, 0x00, 0x03, + 0xb8, 0x3c, 0x00, 0x03, 0xc0, 0x3c, 0x00, 0x03, 0x74, 0x25, 0x01, 0x02, 0x78, 0x25, 0x01, 0x02, 0x7c, 0x25, 0x01, 0x02, 0x80, 0x25, 0x01, 0x02, 0x84, 0x25, 0x01, 0x02, 0x88, 0x25, 0x01, 0x02, + 0x8c, 0x25, 0x01, 0x02, 0x70, 0x03, 0x02, 0x02, 0x74, 0x03, 0x02, 0x02, 0x78, 0x03, 0x02, 0x02, 0x7c, 0x03, 0x02, 0x02, 0xa0, 0x19, 0x03, 0x03, 0xa8, 0x19, 0x03, 0x03, 0xb0, 0x19, 0x03, 0x03, + 0x10, 0x37, 0x04, 0x04, 0x20, 0x37, 0x04, 0x04, 0x00, 0x10, 0x05, 0x04, 0xc0, 0x28, 0x06, 0x05, 0x20, 0x05, 0x07, 0x05, 0x80, 0x0f, 0x0a, 0x07, 0xc8, 0x3c, 0x00, 0x03, 0xd0, 0x3c, 0x00, 0x03, + 0xd8, 0x3c, 0x00, 0x03, 0xe0, 0x3c, 0x00, 0x03, 0x90, 0x25, 0x01, 0x02, 0x94, 0x25, 0x01, 0x02, 0x98, 0x25, 0x01, 0x02, 0x9c, 0x25, 0x01, 0x02, 0xa0, 0x25, 0x01, 0x02, 0xa4, 0x25, 0x01, 0x02, + 0xa8, 0x25, 0x01, 0x02, 0x80, 0x03, 0x02, 0x02, 0x84, 0x03, 0x02, 0x02, 0x88, 0x03, 0x02, 0x02, 0x8c, 0x03, 0x02, 0x02, 0xb8, 0x19, 0x03, 0x03, 0xc0, 0x19, 0x03, 0x03, 0xc8, 0x19, 0x03, 0x03, + 0x30, 0x37, 0x04, 0x04, 0x40, 0x37, 0x04, 0x04, 0x10, 0x10, 0x05, 0x04, 0xe0, 0x28, 0x06, 0x05, 0x40, 0x05, 0x07, 0x05, 0x00, 0x10, 0x0a, 0x07, 0xe8, 0x3c, 0x00, 0x03, 0xf0, 0x3c, 0x00, 0x03, + 0xf8, 0x3c, 0x00, 0x03, 0x00, 0x3d, 0x00, 0x03, 0xac, 0x25, 0x01, 0x02, 0xb0, 0x25, 0x01, 0x02, 0xb4, 0x25, 0x01, 0x02, 0xb8, 0x25, 0x01, 0x02, 0xbc, 0x25, 0x01, 0x02, 0xc0, 0x25, 0x01, 0x02, + 0xc4, 0x25, 0x01, 0x02, 0x90, 0x03, 0x02, 0x02, 0x94, 0x03, 0x02, 0x02, 0x98, 0x03, 0x02, 0x02, 0x9c, 0x03, 0x02, 0x02, 0xd0, 0x19, 0x03, 0x03, 0xd8, 0x19, 0x03, 0x03, 0xe0, 0x19, 0x03, 0x03, + 0x50, 0x37, 0x04, 0x04, 0x60, 0x37, 0x04, 0x04, 0x20, 0x10, 0x05, 0x04, 0x00, 0x29, 0x06, 0x05, 0x60, 0x05, 0x07, 0x05, 0x80, 0x10, 0x0a, 0x07, 0x08, 0x3d, 0x00, 0x03, 0x10, 0x3d, 0x00, 0x03, + 0x18, 0x3d, 0x00, 0x03, 0x20, 0x3d, 0x00, 0x03, 0xc8, 0x25, 0x01, 0x02, 0xcc, 0x25, 0x01, 0x02, 0xd0, 0x25, 0x01, 0x02, 0xd4, 0x25, 0x01, 0x02, 0xd8, 0x25, 0x01, 0x02, 0xdc, 0x25, 0x01, 0x02, + 0xe0, 0x25, 0x01, 0x02, 0xa0, 0x03, 0x02, 0x02, 0xa4, 0x03, 0x02, 0x02, 0xa8, 0x03, 0x02, 0x02, 0xac, 0x03, 0x02, 0x02, 0xe8, 0x19, 0x03, 0x03, 0xf0, 0x19, 0x03, 0x03, 0xf8, 0x19, 0x03, 0x03, + 0x70, 0x37, 0x04, 0x04, 0x80, 0x37, 0x04, 0x04, 0x30, 0x10, 0x05, 0x04, 0x20, 0x29, 0x06, 0x05, 0x80, 0x05, 0x07, 0x05, 0x00, 0x11, 0x0a, 0x07, 0x28, 0x3d, 0x00, 0x03, 0x30, 0x3d, 0x00, 0x03, + 0x38, 0x3d, 0x00, 0x03, 0x40, 0x3d, 0x00, 0x03, 0xe4, 0x25, 0x01, 0x02, 0xe8, 0x25, 0x01, 0x02, 0xec, 0x25, 0x01, 0x02, 0xf0, 0x25, 0x01, 0x02, 0xf4, 0x25, 0x01, 0x02, 0xf8, 0x25, 0x01, 0x02, + 0xfc, 0x25, 0x01, 0x02, 0xb0, 0x03, 0x02, 0x02, 0xb4, 0x03, 0x02, 0x02, 0xb8, 0x03, 0x02, 0x02, 0xbc, 0x03, 0x02, 0x02, 0x00, 0x1a, 0x03, 0x03, 0x08, 0x1a, 0x03, 0x03, 0x10, 0x1a, 0x03, 0x03, + 0x90, 0x37, 0x04, 0x04, 0xa0, 0x37, 0x04, 0x04, 0x40, 0x10, 0x05, 0x04, 0x40, 0x29, 0x06, 0x05, 0xa0, 0x05, 0x07, 0x05, 0x80, 0x11, 0x0a, 0x07, 0x48, 0x3d, 0x00, 0x03, 0x50, 0x3d, 0x00, 0x03, + 0x58, 0x3d, 0x00, 0x03, 0x60, 0x3d, 0x00, 0x03, 0x00, 0x26, 0x01, 0x02, 0x04, 0x26, 0x01, 0x02, 0x08, 0x26, 0x01, 0x02, 0x0c, 0x26, 0x01, 0x02, 0x10, 0x26, 0x01, 0x02, 0x14, 0x26, 0x01, 0x02, + 0x18, 0x26, 0x01, 0x02, 0xc0, 0x03, 0x02, 0x02, 0xc4, 0x03, 0x02, 0x02, 0xc8, 0x03, 0x02, 0x02, 0xcc, 0x03, 0x02, 0x02, 0x18, 0x1a, 0x03, 0x03, 0x20, 0x1a, 0x03, 0x03, 0x28, 0x1a, 0x03, 0x03, + 0xb0, 0x37, 0x04, 0x04, 0xc0, 0x37, 0x04, 0x04, 0x50, 0x10, 0x05, 0x04, 0x60, 0x29, 0x06, 0x05, 0xc0, 0x05, 0x07, 0x05, 0x00, 0x12, 0x0a, 0x07, 0x68, 0x3d, 0x00, 0x03, 0x70, 0x3d, 0x00, 0x03, + 0x78, 0x3d, 0x00, 0x03, 0x80, 0x3d, 0x00, 0x03, 0x1c, 0x26, 0x01, 0x02, 0x20, 0x26, 0x01, 0x02, 0x24, 0x26, 0x01, 0x02, 0x28, 0x26, 0x01, 0x02, 0x2c, 0x26, 0x01, 0x02, 0x30, 0x26, 0x01, 0x02, + 0x34, 0x26, 0x01, 0x02, 0xd0, 0x03, 0x02, 0x02, 0xd4, 0x03, 0x02, 0x02, 0xd8, 0x03, 0x02, 0x02, 0xdc, 0x03, 0x02, 0x02, 0x30, 0x1a, 0x03, 0x03, 0x38, 0x1a, 0x03, 0x03, 0x40, 0x1a, 0x03, 0x03, + 0xd0, 0x37, 0x04, 0x04, 0xe0, 0x37, 0x04, 0x04, 0x60, 0x10, 0x05, 0x04, 0x80, 0x29, 0x06, 0x05, 0xe0, 0x05, 0x07, 0x05, 0x80, 0x12, 0x0a, 0x07, 0x88, 0x3d, 0x00, 0x03, 0x90, 0x3d, 0x00, 0x03, + 0x98, 0x3d, 0x00, 0x03, 0xa0, 0x3d, 0x00, 0x03, 0x38, 0x26, 0x01, 0x02, 0x3c, 0x26, 0x01, 0x02, 0x40, 0x26, 0x01, 0x02, 0x44, 0x26, 0x01, 0x02, 0x48, 0x26, 0x01, 0x02, 0x4c, 0x26, 0x01, 0x02, + 0x50, 0x26, 0x01, 0x02, 0xe0, 0x03, 0x02, 0x02, 0xe4, 0x03, 0x02, 0x02, 0xe8, 0x03, 0x02, 0x02, 0xec, 0x03, 0x02, 0x02, 0x48, 0x1a, 0x03, 0x03, 0x50, 0x1a, 0x03, 0x03, 0x58, 0x1a, 0x03, 0x03, + 0xf0, 0x37, 0x04, 0x04, 0x00, 0x38, 0x04, 0x04, 0x70, 0x10, 0x05, 0x04, 0xa0, 0x29, 0x06, 0x05, 0x00, 0x06, 0x07, 0x05, 0x00, 0x13, 0x0a, 0x07, 0xa8, 0x3d, 0x00, 0x03, 0xb0, 0x3d, 0x00, 0x03, + 0xb8, 0x3d, 0x00, 0x03, 0xc0, 0x3d, 0x00, 0x03, 0x54, 0x26, 0x01, 0x02, 0x58, 0x26, 0x01, 0x02, 0x5c, 0x26, 0x01, 0x02, 0x60, 0x26, 0x01, 0x02, 0x64, 0x26, 0x01, 0x02, 0x68, 0x26, 0x01, 0x02, + 0x6c, 0x26, 0x01, 0x02, 0xf0, 0x03, 0x02, 0x02, 0xf4, 0x03, 0x02, 0x02, 0xf8, 0x03, 0x02, 0x02, 0xfc, 0x03, 0x02, 0x02, 0x60, 0x1a, 0x03, 0x03, 0x68, 0x1a, 0x03, 0x03, 0x70, 0x1a, 0x03, 0x03, + 0x10, 0x38, 0x04, 0x04, 0x20, 0x38, 0x04, 0x04, 0x80, 0x10, 0x05, 0x04, 0xc0, 0x29, 0x06, 0x05, 0x20, 0x06, 0x07, 0x05, 0x80, 0x13, 0x0a, 0x07, 0xc8, 0x3d, 0x00, 0x03, 0xd0, 0x3d, 0x00, 0x03, + 0xd8, 0x3d, 0x00, 0x03, 0xe0, 0x3d, 0x00, 0x03, 0x70, 0x26, 0x01, 0x02, 0x74, 0x26, 0x01, 0x02, 0x78, 0x26, 0x01, 0x02, 0x7c, 0x26, 0x01, 0x02, 0x80, 0x26, 0x01, 0x02, 0x84, 0x26, 0x01, 0x02, + 0x88, 0x26, 0x01, 0x02, 0x00, 0x04, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x08, 0x04, 0x02, 0x02, 0x0c, 0x04, 0x02, 0x02, 0x78, 0x1a, 0x03, 0x03, 0x80, 0x1a, 0x03, 0x03, 0x88, 0x1a, 0x03, 0x03, + 0x30, 0x38, 0x04, 0x04, 0x40, 0x38, 0x04, 0x04, 0x90, 0x10, 0x05, 0x04, 0xe0, 0x29, 0x06, 0x05, 0x40, 0x06, 0x07, 0x05, 0x00, 0x14, 0x0a, 0x07, 0xe8, 0x3d, 0x00, 0x03, 0xf0, 0x3d, 0x00, 0x03, + 0xf8, 0x3d, 0x00, 0x03, 0x00, 0x3e, 0x00, 0x03, 0x8c, 0x26, 0x01, 0x02, 0x90, 0x26, 0x01, 0x02, 0x94, 0x26, 0x01, 0x02, 0x98, 0x26, 0x01, 0x02, 0x9c, 0x26, 0x01, 0x02, 0xa0, 0x26, 0x01, 0x02, + 0xa4, 0x26, 0x01, 0x02, 0x10, 0x04, 0x02, 0x02, 0x14, 0x04, 0x02, 0x02, 0x18, 0x04, 0x02, 0x02, 0x1c, 0x04, 0x02, 0x02, 0x90, 0x1a, 0x03, 0x03, 0x98, 0x1a, 0x03, 0x03, 0xa0, 0x1a, 0x03, 0x03, + 0x50, 0x38, 0x04, 0x04, 0x60, 0x38, 0x04, 0x04, 0xa0, 0x10, 0x05, 0x04, 0x00, 0x2a, 0x06, 0x05, 0x60, 0x06, 0x07, 0x05, 0x80, 0x14, 0x0a, 0x07, 0x08, 0x3e, 0x00, 0x03, 0x10, 0x3e, 0x00, 0x03, + 0x18, 0x3e, 0x00, 0x03, 0x20, 0x3e, 0x00, 0x03, 0xa8, 0x26, 0x01, 0x02, 0xac, 0x26, 0x01, 0x02, 0xb0, 0x26, 0x01, 0x02, 0xb4, 0x26, 0x01, 0x02, 0xb8, 0x26, 0x01, 0x02, 0xbc, 0x26, 0x01, 0x02, + 0xc0, 0x26, 0x01, 0x02, 0x20, 0x04, 0x02, 0x02, 0x24, 0x04, 0x02, 0x02, 0x28, 0x04, 0x02, 0x02, 0x2c, 0x04, 0x02, 0x02, 0xa8, 0x1a, 0x03, 0x03, 0xb0, 0x1a, 0x03, 0x03, 0xb8, 0x1a, 0x03, 0x03, + 0x70, 0x38, 0x04, 0x04, 0x80, 0x38, 0x04, 0x04, 0xb0, 0x10, 0x05, 0x04, 0x20, 0x2a, 0x06, 0x05, 0x80, 0x06, 0x07, 0x05, 0x00, 0x15, 0x0a, 0x07, 0x28, 0x3e, 0x00, 0x03, 0x30, 0x3e, 0x00, 0x03, + 0x38, 0x3e, 0x00, 0x03, 0x40, 0x3e, 0x00, 0x03, 0xc4, 0x26, 0x01, 0x02, 0xc8, 0x26, 0x01, 0x02, 0xcc, 0x26, 0x01, 0x02, 0xd0, 0x26, 0x01, 0x02, 0xd4, 0x26, 0x01, 0x02, 0xd8, 0x26, 0x01, 0x02, + 0xdc, 0x26, 0x01, 0x02, 0x30, 0x04, 0x02, 0x02, 0x34, 0x04, 0x02, 0x02, 0x38, 0x04, 0x02, 0x02, 0x3c, 0x04, 0x02, 0x02, 0xc0, 0x1a, 0x03, 0x03, 0xc8, 0x1a, 0x03, 0x03, 0xd0, 0x1a, 0x03, 0x03, + 0x90, 0x38, 0x04, 0x04, 0xa0, 0x38, 0x04, 0x04, 0xc0, 0x10, 0x05, 0x04, 0x40, 0x2a, 0x06, 0x05, 0xa0, 0x06, 0x07, 0x05, 0x00, 0x28, 0x0b, 0x08, 0x48, 0x3e, 0x00, 0x03, 0x50, 0x3e, 0x00, 0x03, + 0x58, 0x3e, 0x00, 0x03, 0x60, 0x3e, 0x00, 0x03, 0xe0, 0x26, 0x01, 0x02, 0xe4, 0x26, 0x01, 0x02, 0xe8, 0x26, 0x01, 0x02, 0xec, 0x26, 0x01, 0x02, 0xf0, 0x26, 0x01, 0x02, 0xf4, 0x26, 0x01, 0x02, + 0xf8, 0x26, 0x01, 0x02, 0x40, 0x04, 0x02, 0x02, 0x44, 0x04, 0x02, 0x02, 0x48, 0x04, 0x02, 0x02, 0x4c, 0x04, 0x02, 0x02, 0xd8, 0x1a, 0x03, 0x03, 0xe0, 0x1a, 0x03, 0x03, 0xe8, 0x1a, 0x03, 0x03, + 0xb0, 0x38, 0x04, 0x04, 0xc0, 0x38, 0x04, 0x04, 0xd0, 0x10, 0x05, 0x04, 0x60, 0x2a, 0x06, 0x05, 0xc0, 0x06, 0x07, 0x05, 0x00, 0x29, 0x0b, 0x08, 0x68, 0x3e, 0x00, 0x03, 0x70, 0x3e, 0x00, 0x03, + 0x78, 0x3e, 0x00, 0x03, 0x80, 0x3e, 0x00, 0x03, 0xfc, 0x26, 0x01, 0x02, 0x00, 0x27, 0x01, 0x02, 0x04, 0x27, 0x01, 0x02, 0x08, 0x27, 0x01, 0x02, 0x0c, 0x27, 0x01, 0x02, 0x10, 0x27, 0x01, 0x02, + 0x14, 0x27, 0x01, 0x02, 0x50, 0x04, 0x02, 0x02, 0x54, 0x04, 0x02, 0x02, 0x58, 0x04, 0x02, 0x02, 0x5c, 0x04, 0x02, 0x02, 0xf0, 0x1a, 0x03, 0x03, 0xf8, 0x1a, 0x03, 0x03, 0x00, 0x1b, 0x03, 0x03, + 0xd0, 0x38, 0x04, 0x04, 0xe0, 0x38, 0x04, 0x04, 0xe0, 0x10, 0x05, 0x04, 0x80, 0x2a, 0x06, 0x05, 0xe0, 0x06, 0x07, 0x05, 0x00, 0x2a, 0x0b, 0x08, 0x88, 0x3e, 0x00, 0x03, 0x90, 0x3e, 0x00, 0x03, + 0x98, 0x3e, 0x00, 0x03, 0xa0, 0x3e, 0x00, 0x03, 0x18, 0x27, 0x01, 0x02, 0x1c, 0x27, 0x01, 0x02, 0x20, 0x27, 0x01, 0x02, 0x24, 0x27, 0x01, 0x02, 0x28, 0x27, 0x01, 0x02, 0x2c, 0x27, 0x01, 0x02, + 0x30, 0x27, 0x01, 0x02, 0x60, 0x04, 0x02, 0x02, 0x64, 0x04, 0x02, 0x02, 0x68, 0x04, 0x02, 0x02, 0x6c, 0x04, 0x02, 0x02, 0x08, 0x1b, 0x03, 0x03, 0x10, 0x1b, 0x03, 0x03, 0x18, 0x1b, 0x03, 0x03, + 0xf0, 0x38, 0x04, 0x04, 0x00, 0x39, 0x04, 0x04, 0xf0, 0x10, 0x05, 0x04, 0xa0, 0x2a, 0x06, 0x05, 0x00, 0x07, 0x07, 0x05, 0x00, 0x2b, 0x0b, 0x08, 0xa8, 0x3e, 0x00, 0x03, 0xb0, 0x3e, 0x00, 0x03, + 0xb8, 0x3e, 0x00, 0x03, 0xc0, 0x3e, 0x00, 0x03, 0x34, 0x27, 0x01, 0x02, 0x38, 0x27, 0x01, 0x02, 0x3c, 0x27, 0x01, 0x02, 0x40, 0x27, 0x01, 0x02, 0x44, 0x27, 0x01, 0x02, 0x48, 0x27, 0x01, 0x02, + 0x4c, 0x27, 0x01, 0x02, 0x70, 0x04, 0x02, 0x02, 0x74, 0x04, 0x02, 0x02, 0x78, 0x04, 0x02, 0x02, 0x7c, 0x04, 0x02, 0x02, 0x20, 0x1b, 0x03, 0x03, 0x28, 0x1b, 0x03, 0x03, 0x30, 0x1b, 0x03, 0x03, + 0x10, 0x39, 0x04, 0x04, 0x20, 0x39, 0x04, 0x04, 0x00, 0x11, 0x05, 0x04, 0xc0, 0x2a, 0x06, 0x05, 0x20, 0x07, 0x07, 0x05, 0x00, 0x2c, 0x0b, 0x08, 0xc8, 0x3e, 0x00, 0x03, 0xd0, 0x3e, 0x00, 0x03, + 0xd8, 0x3e, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x03, 0x50, 0x27, 0x01, 0x02, 0x54, 0x27, 0x01, 0x02, 0x58, 0x27, 0x01, 0x02, 0x5c, 0x27, 0x01, 0x02, 0x60, 0x27, 0x01, 0x02, 0x64, 0x27, 0x01, 0x02, + 0x68, 0x27, 0x01, 0x02, 0x80, 0x04, 0x02, 0x02, 0x84, 0x04, 0x02, 0x02, 0x88, 0x04, 0x02, 0x02, 0x8c, 0x04, 0x02, 0x02, 0x38, 0x1b, 0x03, 0x03, 0x40, 0x1b, 0x03, 0x03, 0x48, 0x1b, 0x03, 0x03, + 0x30, 0x39, 0x04, 0x04, 0x40, 0x39, 0x04, 0x04, 0x10, 0x11, 0x05, 0x04, 0xe0, 0x2a, 0x06, 0x05, 0x40, 0x07, 0x07, 0x05, 0x00, 0x2d, 0x0b, 0x08, 0xe8, 0x3e, 0x00, 0x03, 0xf0, 0x3e, 0x00, 0x03, + 0xf8, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x03, 0x6c, 0x27, 0x01, 0x02, 0x70, 0x27, 0x01, 0x02, 0x74, 0x27, 0x01, 0x02, 0x78, 0x27, 0x01, 0x02, 0x7c, 0x27, 0x01, 0x02, 0x80, 0x27, 0x01, 0x02, + 0x84, 0x27, 0x01, 0x02, 0x90, 0x04, 0x02, 0x02, 0x94, 0x04, 0x02, 0x02, 0x98, 0x04, 0x02, 0x02, 0x9c, 0x04, 0x02, 0x02, 0x50, 0x1b, 0x03, 0x03, 0x58, 0x1b, 0x03, 0x03, 0x60, 0x1b, 0x03, 0x03, + 0x50, 0x39, 0x04, 0x04, 0x60, 0x39, 0x04, 0x04, 0x20, 0x11, 0x05, 0x04, 0x00, 0x2b, 0x06, 0x05, 0x60, 0x07, 0x07, 0x05, 0x00, 0x2e, 0x0b, 0x08, 0x08, 0x3f, 0x00, 0x03, 0x10, 0x3f, 0x00, 0x03, + 0x18, 0x3f, 0x00, 0x03, 0x20, 0x3f, 0x00, 0x03, 0x88, 0x27, 0x01, 0x02, 0x8c, 0x27, 0x01, 0x02, 0x90, 0x27, 0x01, 0x02, 0x94, 0x27, 0x01, 0x02, 0x98, 0x27, 0x01, 0x02, 0x9c, 0x27, 0x01, 0x02, + 0xa0, 0x27, 0x01, 0x02, 0xa0, 0x04, 0x02, 0x02, 0xa4, 0x04, 0x02, 0x02, 0xa8, 0x04, 0x02, 0x02, 0xac, 0x04, 0x02, 0x02, 0x68, 0x1b, 0x03, 0x03, 0x70, 0x1b, 0x03, 0x03, 0x78, 0x1b, 0x03, 0x03, + 0x70, 0x39, 0x04, 0x04, 0x80, 0x39, 0x04, 0x04, 0x30, 0x11, 0x05, 0x04, 0x20, 0x2b, 0x06, 0x05, 0x80, 0x07, 0x07, 0x05, 0x00, 0x2f, 0x0b, 0x08, 0x28, 0x3f, 0x00, 0x03, 0x30, 0x3f, 0x00, 0x03, + 0x38, 0x3f, 0x00, 0x03, 0x40, 0x3f, 0x00, 0x03, 0xa4, 0x27, 0x01, 0x02, 0xa8, 0x27, 0x01, 0x02, 0xac, 0x27, 0x01, 0x02, 0xb0, 0x27, 0x01, 0x02, 0xb4, 0x27, 0x01, 0x02, 0xb8, 0x27, 0x01, 0x02, + 0xbc, 0x27, 0x01, 0x02, 0xb0, 0x04, 0x02, 0x02, 0xb4, 0x04, 0x02, 0x02, 0xb8, 0x04, 0x02, 0x02, 0xbc, 0x04, 0x02, 0x02, 0x80, 0x1b, 0x03, 0x03, 0x88, 0x1b, 0x03, 0x03, 0x90, 0x1b, 0x03, 0x03, + 0x90, 0x39, 0x04, 0x04, 0xa0, 0x39, 0x04, 0x04, 0x40, 0x11, 0x05, 0x04, 0x40, 0x2b, 0x06, 0x05, 0xa0, 0x07, 0x07, 0x05, 0x00, 0x30, 0x0b, 0x08, 0x48, 0x3f, 0x00, 0x03, 0x50, 0x3f, 0x00, 0x03, + 0x58, 0x3f, 0x00, 0x03, 0x60, 0x3f, 0x00, 0x03, 0xc0, 0x27, 0x01, 0x02, 0xc4, 0x27, 0x01, 0x02, 0xc8, 0x27, 0x01, 0x02, 0xcc, 0x27, 0x01, 0x02, 0xd0, 0x27, 0x01, 0x02, 0xd4, 0x27, 0x01, 0x02, + 0xc0, 0x04, 0x02, 0x02, 0xc4, 0x04, 0x02, 0x02, 0xc8, 0x04, 0x02, 0x02, 0xcc, 0x04, 0x02, 0x02, 0xd0, 0x04, 0x02, 0x02, 0x98, 0x1b, 0x03, 0x03, 0xa0, 0x1b, 0x03, 0x03, 0xa8, 0x1b, 0x03, 0x03, + 0xb0, 0x39, 0x04, 0x04, 0xc0, 0x39, 0x04, 0x04, 0x50, 0x11, 0x05, 0x04, 0x60, 0x2b, 0x06, 0x05, 0xc0, 0x07, 0x07, 0x05, 0x00, 0x05, 0x0c, 0x08, 0x68, 0x3f, 0x00, 0x03, 0x70, 0x3f, 0x00, 0x03, + 0x78, 0x3f, 0x00, 0x03, 0x80, 0x3f, 0x00, 0x03, 0xd8, 0x27, 0x01, 0x02, 0xdc, 0x27, 0x01, 0x02, 0xe0, 0x27, 0x01, 0x02, 0xe4, 0x27, 0x01, 0x02, 0xe8, 0x27, 0x01, 0x02, 0xec, 0x27, 0x01, 0x02, + 0xd4, 0x04, 0x02, 0x02, 0xd8, 0x04, 0x02, 0x02, 0xdc, 0x04, 0x02, 0x02, 0xe0, 0x04, 0x02, 0x02, 0xe4, 0x04, 0x02, 0x02, 0xb0, 0x1b, 0x03, 0x03, 0xb8, 0x1b, 0x03, 0x03, 0xc0, 0x1b, 0x03, 0x03, + 0xd0, 0x39, 0x04, 0x04, 0xe0, 0x39, 0x04, 0x04, 0x60, 0x11, 0x05, 0x04, 0x80, 0x2b, 0x06, 0x05, 0xe0, 0x07, 0x07, 0x05, 0x00, 0x06, 0x0c, 0x08, 0x88, 0x3f, 0x00, 0x03, 0x90, 0x3f, 0x00, 0x03, + 0x98, 0x3f, 0x00, 0x03, 0xa0, 0x3f, 0x00, 0x03, 0xf0, 0x27, 0x01, 0x02, 0xf4, 0x27, 0x01, 0x02, 0xf8, 0x27, 0x01, 0x02, 0xfc, 0x27, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x04, 0x28, 0x01, 0x02, + 0xe8, 0x04, 0x02, 0x02, 0xec, 0x04, 0x02, 0x02, 0xf0, 0x04, 0x02, 0x02, 0xf4, 0x04, 0x02, 0x02, 0xf8, 0x04, 0x02, 0x02, 0xc8, 0x1b, 0x03, 0x03, 0xd0, 0x1b, 0x03, 0x03, 0xd8, 0x1b, 0x03, 0x03, + 0xf0, 0x39, 0x04, 0x04, 0x00, 0x3a, 0x04, 0x04, 0x70, 0x11, 0x05, 0x04, 0xa0, 0x2b, 0x06, 0x05, 0x00, 0x08, 0x07, 0x05, 0x00, 0x07, 0x0c, 0x08, 0xa8, 0x3f, 0x00, 0x03, 0xb0, 0x3f, 0x00, 0x03, + 0xb8, 0x3f, 0x00, 0x03, 0xc0, 0x3f, 0x00, 0x03, 0x08, 0x28, 0x01, 0x02, 0x0c, 0x28, 0x01, 0x02, 0x10, 0x28, 0x01, 0x02, 0x14, 0x28, 0x01, 0x02, 0x18, 0x28, 0x01, 0x02, 0x1c, 0x28, 0x01, 0x02, + 0xfc, 0x04, 0x02, 0x02, 0x00, 0x05, 0x02, 0x02, 0x04, 0x05, 0x02, 0x02, 0x08, 0x05, 0x02, 0x02, 0x0c, 0x05, 0x02, 0x02, 0xe0, 0x1b, 0x03, 0x03, 0xe8, 0x1b, 0x03, 0x03, 0xf0, 0x1b, 0x03, 0x03, + 0x10, 0x3a, 0x04, 0x04, 0x20, 0x3a, 0x04, 0x04, 0x80, 0x11, 0x05, 0x04, 0xc0, 0x2b, 0x06, 0x05, 0x20, 0x08, 0x07, 0x05, 0x00, 0x08, 0x0c, 0x08, 0xc8, 0x3f, 0x00, 0x03, 0xd0, 0x3f, 0x00, 0x03, + 0xd8, 0x3f, 0x00, 0x03, 0xe0, 0x3f, 0x00, 0x03, 0x20, 0x28, 0x01, 0x02, 0x24, 0x28, 0x01, 0x02, 0x28, 0x28, 0x01, 0x02, 0x2c, 0x28, 0x01, 0x02, 0x30, 0x28, 0x01, 0x02, 0x34, 0x28, 0x01, 0x02, + 0x10, 0x05, 0x02, 0x02, 0x14, 0x05, 0x02, 0x02, 0x18, 0x05, 0x02, 0x02, 0x1c, 0x05, 0x02, 0x02, 0x20, 0x05, 0x02, 0x02, 0xf8, 0x1b, 0x03, 0x03, 0x00, 0x1c, 0x03, 0x03, 0x08, 0x1c, 0x03, 0x03, + 0x30, 0x3a, 0x04, 0x04, 0x40, 0x3a, 0x04, 0x04, 0x90, 0x11, 0x05, 0x04, 0xe0, 0x2b, 0x06, 0x05, 0x40, 0x08, 0x07, 0x05, 0x00, 0x09, 0x0c, 0x08, 0xe8, 0x3f, 0x00, 0x03, 0xf0, 0x3f, 0x00, 0x03, + 0xf8, 0x3f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x38, 0x28, 0x01, 0x02, 0x3c, 0x28, 0x01, 0x02, 0x40, 0x28, 0x01, 0x02, 0x44, 0x28, 0x01, 0x02, 0x48, 0x28, 0x01, 0x02, 0x4c, 0x28, 0x01, 0x02, + 0x24, 0x05, 0x02, 0x02, 0x28, 0x05, 0x02, 0x02, 0x2c, 0x05, 0x02, 0x02, 0x30, 0x05, 0x02, 0x02, 0x34, 0x05, 0x02, 0x02, 0x10, 0x1c, 0x03, 0x03, 0x18, 0x1c, 0x03, 0x03, 0x20, 0x1c, 0x03, 0x03, + 0x50, 0x3a, 0x04, 0x04, 0x60, 0x3a, 0x04, 0x04, 0xa0, 0x11, 0x05, 0x04, 0x00, 0x2c, 0x06, 0x05, 0x60, 0x08, 0x07, 0x05, 0x00, 0x0a, 0x0c, 0x08, 0x04, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x02, + 0x0c, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x02, 0x50, 0x28, 0x01, 0x02, 0x54, 0x28, 0x01, 0x02, 0x58, 0x28, 0x01, 0x02, 0x5c, 0x28, 0x01, 0x02, 0x60, 0x28, 0x01, 0x02, 0x64, 0x28, 0x01, 0x02, + 0x38, 0x05, 0x02, 0x02, 0x3c, 0x05, 0x02, 0x02, 0x40, 0x05, 0x02, 0x02, 0x44, 0x05, 0x02, 0x02, 0x48, 0x05, 0x02, 0x02, 0x28, 0x1c, 0x03, 0x03, 0x30, 0x1c, 0x03, 0x03, 0x38, 0x1c, 0x03, 0x03, + 0x70, 0x3a, 0x04, 0x04, 0x80, 0x3a, 0x04, 0x04, 0xb0, 0x11, 0x05, 0x04, 0x20, 0x2c, 0x06, 0x05, 0x80, 0x08, 0x07, 0x05, 0x00, 0x0b, 0x0c, 0x08, 0x14, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x02, + 0x1c, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x68, 0x28, 0x01, 0x02, 0x6c, 0x28, 0x01, 0x02, 0x70, 0x28, 0x01, 0x02, 0x74, 0x28, 0x01, 0x02, 0x78, 0x28, 0x01, 0x02, 0x7c, 0x28, 0x01, 0x02, + 0x4c, 0x05, 0x02, 0x02, 0x50, 0x05, 0x02, 0x02, 0x54, 0x05, 0x02, 0x02, 0x58, 0x05, 0x02, 0x02, 0x5c, 0x05, 0x02, 0x02, 0x40, 0x1c, 0x03, 0x03, 0x48, 0x1c, 0x03, 0x03, 0x50, 0x1c, 0x03, 0x03, + 0x90, 0x3a, 0x04, 0x04, 0xa0, 0x3a, 0x04, 0x04, 0xc0, 0x11, 0x05, 0x04, 0x40, 0x2c, 0x06, 0x05, 0xc0, 0x1e, 0x08, 0x06, 0x00, 0x1e, 0x0d, 0x09, 0x24, 0x00, 0x00, 0x02, 0x28, 0x00, 0x00, 0x02, + 0x2c, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x02, 0x80, 0x28, 0x01, 0x02, 0x84, 0x28, 0x01, 0x02, 0x88, 0x28, 0x01, 0x02, 0x8c, 0x28, 0x01, 0x02, 0x90, 0x28, 0x01, 0x02, 0x94, 0x28, 0x01, 0x02, + 0x60, 0x05, 0x02, 0x02, 0x64, 0x05, 0x02, 0x02, 0x68, 0x05, 0x02, 0x02, 0x6c, 0x05, 0x02, 0x02, 0x70, 0x05, 0x02, 0x02, 0x58, 0x1c, 0x03, 0x03, 0x60, 0x1c, 0x03, 0x03, 0x68, 0x1c, 0x03, 0x03, + 0xb0, 0x3a, 0x04, 0x04, 0xc0, 0x3a, 0x04, 0x04, 0xd0, 0x11, 0x05, 0x04, 0x60, 0x2c, 0x06, 0x05, 0x00, 0x1f, 0x08, 0x06, 0x00, 0x20, 0x0d, 0x09, 0x34, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00, 0x02, + 0x3c, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x98, 0x28, 0x01, 0x02, 0x9c, 0x28, 0x01, 0x02, 0xa0, 0x28, 0x01, 0x02, 0xa4, 0x28, 0x01, 0x02, 0xa8, 0x28, 0x01, 0x02, 0xac, 0x28, 0x01, 0x02, + 0x74, 0x05, 0x02, 0x02, 0x78, 0x05, 0x02, 0x02, 0x7c, 0x05, 0x02, 0x02, 0x80, 0x05, 0x02, 0x02, 0x84, 0x05, 0x02, 0x02, 0x70, 0x1c, 0x03, 0x03, 0x78, 0x1c, 0x03, 0x03, 0x80, 0x1c, 0x03, 0x03, + 0xd0, 0x3a, 0x04, 0x04, 0xe0, 0x3a, 0x04, 0x04, 0xe0, 0x11, 0x05, 0x04, 0x80, 0x2c, 0x06, 0x05, 0x40, 0x1f, 0x08, 0x06, 0x00, 0x22, 0x0d, 0x09, 0x44, 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, 0x02, + 0x4c, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x02, 0xb0, 0x28, 0x01, 0x02, 0xb4, 0x28, 0x01, 0x02, 0xb8, 0x28, 0x01, 0x02, 0xbc, 0x28, 0x01, 0x02, 0xc0, 0x28, 0x01, 0x02, 0xc4, 0x28, 0x01, 0x02, + 0x88, 0x05, 0x02, 0x02, 0x8c, 0x05, 0x02, 0x02, 0x90, 0x05, 0x02, 0x02, 0x94, 0x05, 0x02, 0x02, 0x98, 0x05, 0x02, 0x02, 0x88, 0x1c, 0x03, 0x03, 0x90, 0x1c, 0x03, 0x03, 0x98, 0x1c, 0x03, 0x03, + 0xf0, 0x3a, 0x04, 0x04, 0x00, 0x3b, 0x04, 0x04, 0xf0, 0x11, 0x05, 0x04, 0xa0, 0x2c, 0x06, 0x05, 0x80, 0x1f, 0x08, 0x06, 0x00, 0x24, 0x0d, 0x09, 0x54, 0x00, 0x00, 0x02, 0x58, 0x00, 0x00, 0x02, + 0x5c, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x02, 0xc8, 0x28, 0x01, 0x02, 0xcc, 0x28, 0x01, 0x02, 0xd0, 0x28, 0x01, 0x02, 0xd4, 0x28, 0x01, 0x02, 0xd8, 0x28, 0x01, 0x02, 0xdc, 0x28, 0x01, 0x02, + 0x9c, 0x05, 0x02, 0x02, 0xa0, 0x05, 0x02, 0x02, 0xa4, 0x05, 0x02, 0x02, 0xa8, 0x05, 0x02, 0x02, 0xac, 0x05, 0x02, 0x02, 0xa0, 0x1c, 0x03, 0x03, 0xa8, 0x1c, 0x03, 0x03, 0xb0, 0x1c, 0x03, 0x03, + 0x10, 0x3b, 0x04, 0x04, 0x20, 0x3b, 0x04, 0x04, 0x00, 0x12, 0x05, 0x04, 0xc0, 0x2c, 0x06, 0x05, 0xc0, 0x1f, 0x08, 0x06, 0x00, 0x3c, 0x0e, 0x0a, 0x64, 0x00, 0x00, 0x02, 0x68, 0x00, 0x00, 0x02, + 0x6c, 0x00, 0x00, 0x02, 0x70, 0x00, 0x00, 0x02, 0xe0, 0x28, 0x01, 0x02, 0xe4, 0x28, 0x01, 0x02, 0xe8, 0x28, 0x01, 0x02, 0xec, 0x28, 0x01, 0x02, 0xf0, 0x28, 0x01, 0x02, 0xf4, 0x28, 0x01, 0x02, + 0xb0, 0x05, 0x02, 0x02, 0xb4, 0x05, 0x02, 0x02, 0xb8, 0x05, 0x02, 0x02, 0xbc, 0x05, 0x02, 0x02, 0xc0, 0x05, 0x02, 0x02, 0xb8, 0x1c, 0x03, 0x03, 0xc0, 0x1c, 0x03, 0x03, 0xc8, 0x1c, 0x03, 0x03, + 0x30, 0x3b, 0x04, 0x04, 0x40, 0x3b, 0x04, 0x04, 0x10, 0x12, 0x05, 0x04, 0xe0, 0x2c, 0x06, 0x05, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x0e, 0x09, 0x74, 0x00, 0x00, 0x02, 0x78, 0x00, 0x00, 0x02, + 0x7c, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x02, 0xf8, 0x28, 0x01, 0x02, 0xfc, 0x28, 0x01, 0x02, 0x00, 0x29, 0x01, 0x02, 0x04, 0x29, 0x01, 0x02, 0x08, 0x29, 0x01, 0x02, 0x0c, 0x29, 0x01, 0x02, + 0xc4, 0x05, 0x02, 0x02, 0xc8, 0x05, 0x02, 0x02, 0xcc, 0x05, 0x02, 0x02, 0xd0, 0x05, 0x02, 0x02, 0xd4, 0x05, 0x02, 0x02, 0xd0, 0x1c, 0x03, 0x03, 0xd8, 0x1c, 0x03, 0x03, 0xe0, 0x1c, 0x03, 0x03, + 0x50, 0x3b, 0x04, 0x04, 0x60, 0x3b, 0x04, 0x04, 0x20, 0x12, 0x05, 0x04, 0x00, 0x2d, 0x06, 0x05, 0x40, 0x20, 0x08, 0x06, 0x00, 0x02, 0x0e, 0x09, 0x84, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x02, + 0x8c, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x02, 0x10, 0x29, 0x01, 0x02, 0x14, 0x29, 0x01, 0x02, 0x18, 0x29, 0x01, 0x02, 0x1c, 0x29, 0x01, 0x02, 0x20, 0x29, 0x01, 0x02, 0x24, 0x29, 0x01, 0x02, + 0xd8, 0x05, 0x02, 0x02, 0xdc, 0x05, 0x02, 0x02, 0xe0, 0x05, 0x02, 0x02, 0xe4, 0x05, 0x02, 0x02, 0xe8, 0x05, 0x02, 0x02, 0xe8, 0x1c, 0x03, 0x03, 0xf0, 0x1c, 0x03, 0x03, 0xf8, 0x1c, 0x03, 0x03, + 0x70, 0x3b, 0x04, 0x04, 0x80, 0x3b, 0x04, 0x04, 0x30, 0x12, 0x05, 0x04, 0x20, 0x2d, 0x06, 0x05, 0x80, 0x20, 0x08, 0x06, 0x00, 0x18, 0x0f, 0x0a, 0x94, 0x00, 0x00, 0x02, 0x98, 0x00, 0x00, 0x02, + 0x9c, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x02, 0x28, 0x29, 0x01, 0x02, 0x2c, 0x29, 0x01, 0x02, 0x30, 0x29, 0x01, 0x02, 0x34, 0x29, 0x01, 0x02, 0x38, 0x29, 0x01, 0x02, 0x3c, 0x29, 0x01, 0x02, + 0xec, 0x05, 0x02, 0x02, 0xf0, 0x05, 0x02, 0x02, 0xf4, 0x05, 0x02, 0x02, 0xf8, 0x05, 0x02, 0x02, 0xfc, 0x05, 0x02, 0x02, 0x00, 0x1d, 0x03, 0x03, 0x08, 0x1d, 0x03, 0x03, 0x10, 0x1d, 0x03, 0x03, + 0x90, 0x3b, 0x04, 0x04, 0xa0, 0x3b, 0x04, 0x04, 0x40, 0x12, 0x05, 0x04, 0x40, 0x2d, 0x06, 0x05, 0xc0, 0x20, 0x08, 0x06, 0x00, 0x1c, 0x0f, 0x0a, 0xa4, 0x00, 0x00, 0x02, 0xa8, 0x00, 0x00, 0x02, + 0xac, 0x00, 0x00, 0x02, 0xb0, 0x00, 0x00, 0x02, 0x40, 0x29, 0x01, 0x02, 0x44, 0x29, 0x01, 0x02, 0x48, 0x29, 0x01, 0x02, 0x4c, 0x29, 0x01, 0x02, 0x50, 0x29, 0x01, 0x02, 0x54, 0x29, 0x01, 0x02, + 0x00, 0x06, 0x02, 0x02, 0x04, 0x06, 0x02, 0x02, 0x08, 0x06, 0x02, 0x02, 0x0c, 0x06, 0x02, 0x02, 0x10, 0x06, 0x02, 0x02, 0x18, 0x1d, 0x03, 0x03, 0x20, 0x1d, 0x03, 0x03, 0x28, 0x1d, 0x03, 0x03, + 0xb0, 0x3b, 0x04, 0x04, 0xc0, 0x3b, 0x04, 0x04, 0x50, 0x12, 0x05, 0x04, 0x60, 0x2d, 0x06, 0x05, 0x00, 0x21, 0x08, 0x06, 0x00, 0x30, 0x10, 0x0b, 0xb4, 0x00, 0x00, 0x02, 0xb8, 0x00, 0x00, 0x02, + 0xbc, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x02, 0x58, 0x29, 0x01, 0x02, 0x5c, 0x29, 0x01, 0x02, 0x60, 0x29, 0x01, 0x02, 0x64, 0x29, 0x01, 0x02, 0x68, 0x29, 0x01, 0x02, 0x6c, 0x29, 0x01, 0x02, + 0x14, 0x06, 0x02, 0x02, 0x18, 0x06, 0x02, 0x02, 0x1c, 0x06, 0x02, 0x02, 0x20, 0x06, 0x02, 0x02, 0x24, 0x06, 0x02, 0x02, 0x30, 0x1d, 0x03, 0x03, 0x38, 0x1d, 0x03, 0x03, 0x40, 0x1d, 0x03, 0x03, + 0xd0, 0x3b, 0x04, 0x04, 0xe0, 0x3b, 0x04, 0x04, 0x60, 0x12, 0x05, 0x04, 0x80, 0x2d, 0x06, 0x05, 0x40, 0x21, 0x08, 0x06, 0x00, 0x38, 0x10, 0x0b, 0xc4, 0x00, 0x00, 0x02, 0xc8, 0x00, 0x00, 0x02, + 0xcc, 0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x02, 0x70, 0x29, 0x01, 0x02, 0x74, 0x29, 0x01, 0x02, 0x78, 0x29, 0x01, 0x02, 0x7c, 0x29, 0x01, 0x02, 0x80, 0x29, 0x01, 0x02, 0x84, 0x29, 0x01, 0x02, + 0x28, 0x06, 0x02, 0x02, 0x2c, 0x06, 0x02, 0x02, 0x30, 0x06, 0x02, 0x02, 0x34, 0x06, 0x02, 0x02, 0x38, 0x06, 0x02, 0x02, 0x48, 0x1d, 0x03, 0x03, 0x50, 0x1d, 0x03, 0x03, 0x58, 0x1d, 0x03, 0x03, + 0xf0, 0x3b, 0x04, 0x04, 0x00, 0x3c, 0x04, 0x04, 0x70, 0x12, 0x05, 0x04, 0xa0, 0x2d, 0x06, 0x05, 0x80, 0x21, 0x08, 0x06, 0x00, 0x10, 0x11, 0x0b, 0xd4, 0x00, 0x00, 0x02, 0xd8, 0x00, 0x00, 0x02, + 0xdc, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, 0x88, 0x29, 0x01, 0x02, 0x8c, 0x29, 0x01, 0x02, 0x90, 0x29, 0x01, 0x02, 0x94, 0x29, 0x01, 0x02, 0x98, 0x29, 0x01, 0x02, 0x9c, 0x29, 0x01, 0x02, + 0x3c, 0x06, 0x02, 0x02, 0x40, 0x06, 0x02, 0x02, 0x44, 0x06, 0x02, 0x02, 0x48, 0x06, 0x02, 0x02, 0x4c, 0x06, 0x02, 0x02, 0x60, 0x1d, 0x03, 0x03, 0x68, 0x1d, 0x03, 0x03, 0x70, 0x1d, 0x03, 0x03, + 0x10, 0x3c, 0x04, 0x04, 0x20, 0x3c, 0x04, 0x04, 0x80, 0x12, 0x05, 0x04, 0xc0, 0x2d, 0x06, 0x05, 0xc0, 0x21, 0x08, 0x06, 0x00, 0x00, 0x13, 0x0c, 0xe4, 0x00, 0x00, 0x02, 0xe8, 0x00, 0x00, 0x02, + 0xec, 0x00, 0x00, 0x02, 0xf0, 0x00, 0x00, 0x02, 0xa0, 0x29, 0x01, 0x02, 0xa4, 0x29, 0x01, 0x02, 0xa8, 0x29, 0x01, 0x02, 0xac, 0x29, 0x01, 0x02, 0xb0, 0x29, 0x01, 0x02, 0xb4, 0x29, 0x01, 0x02, + 0x50, 0x06, 0x02, 0x02, 0x54, 0x06, 0x02, 0x02, 0x58, 0x06, 0x02, 0x02, 0x5c, 0x06, 0x02, 0x02, 0x60, 0x06, 0x02, 0x02, 0x78, 0x1d, 0x03, 0x03, 0x80, 0x1d, 0x03, 0x03, 0x88, 0x1d, 0x03, 0x03, + 0x30, 0x3c, 0x04, 0x04, 0x40, 0x3c, 0x04, 0x04, 0x90, 0x12, 0x05, 0x04, 0xe0, 0x2d, 0x06, 0x05, 0x00, 0x22, 0x08, 0x06, 0xf4, 0x00, 0x00, 0x02, 0xf8, 0x00, 0x00, 0x02, 0xfc, 0x00, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02, 0xb8, 0x29, 0x01, 0x02, 0xbc, 0x29, 0x01, 0x02, 0xc0, 0x29, 0x01, 0x02, 0xc4, 0x29, 0x01, 0x02, 0xc8, 0x29, 0x01, 0x02, 0xcc, 0x29, 0x01, 0x02, + 0x64, 0x06, 0x02, 0x02, 0x68, 0x06, 0x02, 0x02, 0x6c, 0x06, 0x02, 0x02, 0x70, 0x06, 0x02, 0x02, 0x74, 0x06, 0x02, 0x02, 0x90, 0x1d, 0x03, 0x03, 0x98, 0x1d, 0x03, 0x03, 0xa0, 0x1d, 0x03, 0x03, + 0x50, 0x3c, 0x04, 0x04, 0x60, 0x3c, 0x04, 0x04, 0xa0, 0x12, 0x05, 0x04, 0x00, 0x2e, 0x06, 0x05, 0x40, 0x22, 0x08, 0x06, 0x08, 0x01, 0x00, 0x02, 0x0c, 0x01, 0x00, 0x02, 0x10, 0x01, 0x00, 0x02, + 0x14, 0x01, 0x00, 0x02, 0x18, 0x01, 0x00, 0x02, 0xd0, 0x29, 0x01, 0x02, 0xd4, 0x29, 0x01, 0x02, 0xd8, 0x29, 0x01, 0x02, 0xdc, 0x29, 0x01, 0x02, 0xe0, 0x29, 0x01, 0x02, 0xe4, 0x29, 0x01, 0x02, + 0x78, 0x06, 0x02, 0x02, 0x7c, 0x06, 0x02, 0x02, 0x80, 0x06, 0x02, 0x02, 0x84, 0x06, 0x02, 0x02, 0x88, 0x06, 0x02, 0x02, 0xa8, 0x1d, 0x03, 0x03, 0xb0, 0x1d, 0x03, 0x03, 0xb8, 0x1d, 0x03, 0x03, + 0x70, 0x3c, 0x04, 0x04, 0x80, 0x3c, 0x04, 0x04, 0xb0, 0x12, 0x05, 0x04, 0x20, 0x2e, 0x06, 0x05, 0x80, 0x22, 0x08, 0x06, 0x1c, 0x01, 0x00, 0x02, 0x20, 0x01, 0x00, 0x02, 0x24, 0x01, 0x00, 0x02, + 0x28, 0x01, 0x00, 0x02, 0x2c, 0x01, 0x00, 0x02, 0xe8, 0x29, 0x01, 0x02, 0xec, 0x29, 0x01, 0x02, 0xf0, 0x29, 0x01, 0x02, 0xf4, 0x29, 0x01, 0x02, 0xf8, 0x29, 0x01, 0x02, 0xfc, 0x29, 0x01, 0x02, + 0x8c, 0x06, 0x02, 0x02, 0x90, 0x06, 0x02, 0x02, 0x94, 0x06, 0x02, 0x02, 0x98, 0x06, 0x02, 0x02, 0x9c, 0x06, 0x02, 0x02, 0xc0, 0x1d, 0x03, 0x03, 0xc8, 0x1d, 0x03, 0x03, 0xd0, 0x1d, 0x03, 0x03, + 0x90, 0x3c, 0x04, 0x04, 0xa0, 0x3c, 0x04, 0x04, 0xc0, 0x12, 0x05, 0x04, 0x40, 0x2e, 0x06, 0x05, 0xc0, 0x22, 0x08, 0x06, 0x30, 0x01, 0x00, 0x02, 0x34, 0x01, 0x00, 0x02, 0x38, 0x01, 0x00, 0x02, + 0x3c, 0x01, 0x00, 0x02, 0x40, 0x01, 0x00, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x04, 0x2a, 0x01, 0x02, 0x08, 0x2a, 0x01, 0x02, 0x0c, 0x2a, 0x01, 0x02, 0x10, 0x2a, 0x01, 0x02, 0x14, 0x2a, 0x01, 0x02, + 0xa0, 0x06, 0x02, 0x02, 0xa4, 0x06, 0x02, 0x02, 0xa8, 0x06, 0x02, 0x02, 0xac, 0x06, 0x02, 0x02, 0xb0, 0x06, 0x02, 0x02, 0xd8, 0x1d, 0x03, 0x03, 0xe0, 0x1d, 0x03, 0x03, 0xe8, 0x1d, 0x03, 0x03, + 0xb0, 0x3c, 0x04, 0x04, 0xc0, 0x3c, 0x04, 0x04, 0xd0, 0x12, 0x05, 0x04, 0x60, 0x2e, 0x06, 0x05, 0x00, 0x23, 0x08, 0x06, 0x44, 0x01, 0x00, 0x02, 0x48, 0x01, 0x00, 0x02, 0x4c, 0x01, 0x00, 0x02, + 0x50, 0x01, 0x00, 0x02, 0x54, 0x01, 0x00, 0x02, 0x18, 0x2a, 0x01, 0x02, 0x1c, 0x2a, 0x01, 0x02, 0x20, 0x2a, 0x01, 0x02, 0x24, 0x2a, 0x01, 0x02, 0x28, 0x2a, 0x01, 0x02, 0x2c, 0x2a, 0x01, 0x02, + 0xb4, 0x06, 0x02, 0x02, 0xb8, 0x06, 0x02, 0x02, 0xbc, 0x06, 0x02, 0x02, 0xc0, 0x06, 0x02, 0x02, 0xc4, 0x06, 0x02, 0x02, 0xf0, 0x1d, 0x03, 0x03, 0xf8, 0x1d, 0x03, 0x03, 0x00, 0x1e, 0x03, 0x03, + 0xd0, 0x3c, 0x04, 0x04, 0xe0, 0x3c, 0x04, 0x04, 0xe0, 0x12, 0x05, 0x04, 0x80, 0x2e, 0x06, 0x05, 0x40, 0x23, 0x08, 0x06, 0x58, 0x01, 0x00, 0x02, 0x5c, 0x01, 0x00, 0x02, 0x60, 0x01, 0x00, 0x02, + 0x64, 0x01, 0x00, 0x02, 0x68, 0x01, 0x00, 0x02, 0x30, 0x2a, 0x01, 0x02, 0x34, 0x2a, 0x01, 0x02, 0x38, 0x2a, 0x01, 0x02, 0x3c, 0x2a, 0x01, 0x02, 0x40, 0x2a, 0x01, 0x02, 0x44, 0x2a, 0x01, 0x02, + 0xc8, 0x06, 0x02, 0x02, 0xcc, 0x06, 0x02, 0x02, 0xd0, 0x06, 0x02, 0x02, 0xd4, 0x06, 0x02, 0x02, 0xd8, 0x06, 0x02, 0x02, 0x08, 0x1e, 0x03, 0x03, 0x10, 0x1e, 0x03, 0x03, 0x18, 0x1e, 0x03, 0x03, + 0xf0, 0x3c, 0x04, 0x04, 0x00, 0x3d, 0x04, 0x04, 0xf0, 0x12, 0x05, 0x04, 0xa0, 0x2e, 0x06, 0x05, 0x80, 0x23, 0x08, 0x06, 0x6c, 0x01, 0x00, 0x02, 0x70, 0x01, 0x00, 0x02, 0x74, 0x01, 0x00, 0x02, + 0x78, 0x01, 0x00, 0x02, 0x7c, 0x01, 0x00, 0x02, 0x48, 0x2a, 0x01, 0x02, 0x4c, 0x2a, 0x01, 0x02, 0x50, 0x2a, 0x01, 0x02, 0x54, 0x2a, 0x01, 0x02, 0x58, 0x2a, 0x01, 0x02, 0x5c, 0x2a, 0x01, 0x02, + 0xdc, 0x06, 0x02, 0x02, 0xe0, 0x06, 0x02, 0x02, 0xe4, 0x06, 0x02, 0x02, 0xe8, 0x06, 0x02, 0x02, 0xec, 0x06, 0x02, 0x02, 0x20, 0x1e, 0x03, 0x03, 0x28, 0x1e, 0x03, 0x03, 0x30, 0x1e, 0x03, 0x03, + 0x10, 0x3d, 0x04, 0x04, 0x20, 0x3d, 0x04, 0x04, 0x00, 0x13, 0x05, 0x04, 0xc0, 0x2e, 0x06, 0x05, 0xc0, 0x23, 0x08, 0x06, 0x80, 0x01, 0x00, 0x02, 0x84, 0x01, 0x00, 0x02, 0x88, 0x01, 0x00, 0x02, + 0x8c, 0x01, 0x00, 0x02, 0x90, 0x01, 0x00, 0x02, 0x60, 0x2a, 0x01, 0x02, 0x64, 0x2a, 0x01, 0x02, 0x68, 0x2a, 0x01, 0x02, 0x6c, 0x2a, 0x01, 0x02, 0x70, 0x2a, 0x01, 0x02, 0x74, 0x2a, 0x01, 0x02, + 0xf0, 0x06, 0x02, 0x02, 0xf4, 0x06, 0x02, 0x02, 0xf8, 0x06, 0x02, 0x02, 0xfc, 0x06, 0x02, 0x02, 0x00, 0x07, 0x02, 0x02, 0x38, 0x1e, 0x03, 0x03, 0x40, 0x1e, 0x03, 0x03, 0x48, 0x1e, 0x03, 0x03, + 0x30, 0x3d, 0x04, 0x04, 0x40, 0x3d, 0x04, 0x04, 0x10, 0x13, 0x05, 0x04, 0xe0, 0x2e, 0x06, 0x05, 0x00, 0x24, 0x08, 0x06, 0x94, 0x01, 0x00, 0x02, 0x98, 0x01, 0x00, 0x02, 0x9c, 0x01, 0x00, 0x02, + 0xa0, 0x01, 0x00, 0x02, 0x78, 0x2a, 0x01, 0x02, 0x7c, 0x2a, 0x01, 0x02, 0x80, 0x2a, 0x01, 0x02, 0x84, 0x2a, 0x01, 0x02, 0x88, 0x2a, 0x01, 0x02, 0x8c, 0x2a, 0x01, 0x02, 0x90, 0x2a, 0x01, 0x02, + 0x04, 0x07, 0x02, 0x02, 0x08, 0x07, 0x02, 0x02, 0x0c, 0x07, 0x02, 0x02, 0x10, 0x07, 0x02, 0x02, 0x14, 0x07, 0x02, 0x02, 0x50, 0x1e, 0x03, 0x03, 0x58, 0x1e, 0x03, 0x03, 0x60, 0x1e, 0x03, 0x03, + 0x50, 0x3d, 0x04, 0x04, 0x60, 0x3d, 0x04, 0x04, 0x20, 0x13, 0x05, 0x04, 0x00, 0x2f, 0x06, 0x05, 0x40, 0x24, 0x08, 0x06, 0xa4, 0x01, 0x00, 0x02, 0xa8, 0x01, 0x00, 0x02, 0xac, 0x01, 0x00, 0x02, + 0xb0, 0x01, 0x00, 0x02, 0x94, 0x2a, 0x01, 0x02, 0x98, 0x2a, 0x01, 0x02, 0x9c, 0x2a, 0x01, 0x02, 0xa0, 0x2a, 0x01, 0x02, 0xa4, 0x2a, 0x01, 0x02, 0xa8, 0x2a, 0x01, 0x02, 0xac, 0x2a, 0x01, 0x02, + 0x18, 0x07, 0x02, 0x02, 0x1c, 0x07, 0x02, 0x02, 0x20, 0x07, 0x02, 0x02, 0x24, 0x07, 0x02, 0x02, 0x28, 0x07, 0x02, 0x02, 0x68, 0x1e, 0x03, 0x03, 0x70, 0x1e, 0x03, 0x03, 0x78, 0x1e, 0x03, 0x03, + 0x70, 0x3d, 0x04, 0x04, 0x30, 0x13, 0x05, 0x04, 0x40, 0x13, 0x05, 0x04, 0x20, 0x2f, 0x06, 0x05, 0x80, 0x24, 0x08, 0x06, 0xb4, 0x01, 0x00, 0x02, 0xb8, 0x01, 0x00, 0x02, 0xbc, 0x01, 0x00, 0x02, + 0xc0, 0x01, 0x00, 0x02, 0xb0, 0x2a, 0x01, 0x02, 0xb4, 0x2a, 0x01, 0x02, 0xb8, 0x2a, 0x01, 0x02, 0xbc, 0x2a, 0x01, 0x02, 0xc0, 0x2a, 0x01, 0x02, 0xc4, 0x2a, 0x01, 0x02, 0xc8, 0x2a, 0x01, 0x02, + 0x2c, 0x07, 0x02, 0x02, 0x30, 0x07, 0x02, 0x02, 0x34, 0x07, 0x02, 0x02, 0x38, 0x07, 0x02, 0x02, 0x3c, 0x07, 0x02, 0x02, 0x80, 0x1e, 0x03, 0x03, 0x88, 0x1e, 0x03, 0x03, 0x90, 0x1e, 0x03, 0x03, + 0x80, 0x3d, 0x04, 0x04, 0x50, 0x13, 0x05, 0x04, 0x60, 0x13, 0x05, 0x04, 0x40, 0x2f, 0x06, 0x05, 0xc0, 0x24, 0x08, 0x06, 0xc4, 0x01, 0x00, 0x02, 0xc8, 0x01, 0x00, 0x02, 0xcc, 0x01, 0x00, 0x02, + 0xd0, 0x01, 0x00, 0x02, 0xcc, 0x2a, 0x01, 0x02, 0xd0, 0x2a, 0x01, 0x02, 0xd4, 0x2a, 0x01, 0x02, 0xd8, 0x2a, 0x01, 0x02, 0xdc, 0x2a, 0x01, 0x02, 0xe0, 0x2a, 0x01, 0x02, 0xe4, 0x2a, 0x01, 0x02, + 0x40, 0x07, 0x02, 0x02, 0x44, 0x07, 0x02, 0x02, 0x48, 0x07, 0x02, 0x02, 0x4c, 0x07, 0x02, 0x02, 0x50, 0x07, 0x02, 0x02, 0x98, 0x1e, 0x03, 0x03, 0xa0, 0x1e, 0x03, 0x03, 0xa8, 0x1e, 0x03, 0x03, + 0x90, 0x3d, 0x04, 0x04, 0x70, 0x13, 0x05, 0x04, 0x80, 0x13, 0x05, 0x04, 0x60, 0x2f, 0x06, 0x05, 0x00, 0x25, 0x08, 0x06, 0xd4, 0x01, 0x00, 0x02, 0xd8, 0x01, 0x00, 0x02, 0xdc, 0x01, 0x00, 0x02, + 0xe0, 0x01, 0x00, 0x02, 0xe8, 0x2a, 0x01, 0x02, 0xec, 0x2a, 0x01, 0x02, 0xf0, 0x2a, 0x01, 0x02, 0xf4, 0x2a, 0x01, 0x02, 0xf8, 0x2a, 0x01, 0x02, 0xfc, 0x2a, 0x01, 0x02, 0x00, 0x2b, 0x01, 0x02, + 0x54, 0x07, 0x02, 0x02, 0x58, 0x07, 0x02, 0x02, 0x5c, 0x07, 0x02, 0x02, 0x60, 0x07, 0x02, 0x02, 0x64, 0x07, 0x02, 0x02, 0xb0, 0x1e, 0x03, 0x03, 0xb8, 0x1e, 0x03, 0x03, 0xa0, 0x3d, 0x04, 0x04, + 0xb0, 0x3d, 0x04, 0x04, 0x90, 0x13, 0x05, 0x04, 0xa0, 0x13, 0x05, 0x04, 0x80, 0x2f, 0x06, 0x05, 0x40, 0x25, 0x08, 0x06, 0xe4, 0x01, 0x00, 0x02, 0xe8, 0x01, 0x00, 0x02, 0xec, 0x01, 0x00, 0x02, + 0xf0, 0x01, 0x00, 0x02, 0x04, 0x2b, 0x01, 0x02, 0x08, 0x2b, 0x01, 0x02, 0x0c, 0x2b, 0x01, 0x02, 0x10, 0x2b, 0x01, 0x02, 0x14, 0x2b, 0x01, 0x02, 0x18, 0x2b, 0x01, 0x02, 0x1c, 0x2b, 0x01, 0x02, + 0x68, 0x07, 0x02, 0x02, 0x6c, 0x07, 0x02, 0x02, 0x70, 0x07, 0x02, 0x02, 0x74, 0x07, 0x02, 0x02, 0x78, 0x07, 0x02, 0x02, 0xc0, 0x1e, 0x03, 0x03, 0xc8, 0x1e, 0x03, 0x03, 0xc0, 0x3d, 0x04, 0x04, + 0xd0, 0x3d, 0x04, 0x04, 0xb0, 0x13, 0x05, 0x04, 0xc0, 0x13, 0x05, 0x04, 0xa0, 0x2f, 0x06, 0x05, 0x80, 0x25, 0x08, 0x06, 0xf4, 0x01, 0x00, 0x02, 0xf8, 0x01, 0x00, 0x02, 0xfc, 0x01, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x20, 0x2b, 0x01, 0x02, 0x24, 0x2b, 0x01, 0x02, 0x28, 0x2b, 0x01, 0x02, 0x2c, 0x2b, 0x01, 0x02, 0x30, 0x2b, 0x01, 0x02, 0x34, 0x2b, 0x01, 0x02, 0x38, 0x2b, 0x01, 0x02, + 0x7c, 0x07, 0x02, 0x02, 0x80, 0x07, 0x02, 0x02, 0x84, 0x07, 0x02, 0x02, 0x88, 0x07, 0x02, 0x02, 0x8c, 0x07, 0x02, 0x02, 0xd0, 0x1e, 0x03, 0x03, 0xd8, 0x1e, 0x03, 0x03, 0xe0, 0x3d, 0x04, 0x04, + 0xf0, 0x3d, 0x04, 0x04, 0xd0, 0x13, 0x05, 0x04, 0xe0, 0x13, 0x05, 0x04, 0xc0, 0x2f, 0x06, 0x05, 0xc0, 0x25, 0x08, 0x06, 0x04, 0x02, 0x00, 0x02, 0x08, 0x02, 0x00, 0x02, 0x0c, 0x02, 0x00, 0x02, + 0x10, 0x02, 0x00, 0x02, 0x3c, 0x2b, 0x01, 0x02, 0x40, 0x2b, 0x01, 0x02, 0x44, 0x2b, 0x01, 0x02, 0x48, 0x2b, 0x01, 0x02, 0x4c, 0x2b, 0x01, 0x02, 0x50, 0x2b, 0x01, 0x02, 0x54, 0x2b, 0x01, 0x02, + 0x90, 0x07, 0x02, 0x02, 0x94, 0x07, 0x02, 0x02, 0x98, 0x07, 0x02, 0x02, 0x9c, 0x07, 0x02, 0x02, 0xa0, 0x07, 0x02, 0x02, 0xe0, 0x1e, 0x03, 0x03, 0xe8, 0x1e, 0x03, 0x03, 0x00, 0x3e, 0x04, 0x04, + 0x10, 0x3e, 0x04, 0x04, 0xf0, 0x13, 0x05, 0x04, 0x00, 0x14, 0x05, 0x04, 0xe0, 0x2f, 0x06, 0x05, 0x00, 0x26, 0x08, 0x06, 0x14, 0x02, 0x00, 0x02, 0x18, 0x02, 0x00, 0x02, 0x1c, 0x02, 0x00, 0x02, + 0x20, 0x02, 0x00, 0x02, 0x58, 0x2b, 0x01, 0x02, 0x5c, 0x2b, 0x01, 0x02, 0x60, 0x2b, 0x01, 0x02, 0x64, 0x2b, 0x01, 0x02, 0x68, 0x2b, 0x01, 0x02, 0x6c, 0x2b, 0x01, 0x02, 0x70, 0x2b, 0x01, 0x02, + 0xa4, 0x07, 0x02, 0x02, 0xa8, 0x07, 0x02, 0x02, 0xac, 0x07, 0x02, 0x02, 0xb0, 0x07, 0x02, 0x02, 0xf0, 0x1e, 0x03, 0x03, 0xf8, 0x1e, 0x03, 0x03, 0x00, 0x1f, 0x03, 0x03, 0x20, 0x3e, 0x04, 0x04, + 0x30, 0x3e, 0x04, 0x04, 0x10, 0x14, 0x05, 0x04, 0x20, 0x14, 0x05, 0x04, 0x00, 0x30, 0x06, 0x05, 0x40, 0x26, 0x08, 0x06, 0x24, 0x02, 0x00, 0x02, 0x28, 0x02, 0x00, 0x02, 0x2c, 0x02, 0x00, 0x02, + 0x30, 0x02, 0x00, 0x02, 0x74, 0x2b, 0x01, 0x02, 0x78, 0x2b, 0x01, 0x02, 0x7c, 0x2b, 0x01, 0x02, 0x80, 0x2b, 0x01, 0x02, 0x84, 0x2b, 0x01, 0x02, 0x88, 0x2b, 0x01, 0x02, 0x8c, 0x2b, 0x01, 0x02, + 0xb4, 0x07, 0x02, 0x02, 0xb8, 0x07, 0x02, 0x02, 0xbc, 0x07, 0x02, 0x02, 0xc0, 0x07, 0x02, 0x02, 0x08, 0x1f, 0x03, 0x03, 0x10, 0x1f, 0x03, 0x03, 0x18, 0x1f, 0x03, 0x03, 0x40, 0x3e, 0x04, 0x04, + 0x50, 0x3e, 0x04, 0x04, 0x30, 0x14, 0x05, 0x04, 0x40, 0x14, 0x05, 0x04, 0x20, 0x30, 0x06, 0x05, 0x80, 0x26, 0x08, 0x06, 0x34, 0x02, 0x00, 0x02, 0x38, 0x02, 0x00, 0x02, 0x3c, 0x02, 0x00, 0x02, + 0x40, 0x02, 0x00, 0x02, 0x90, 0x2b, 0x01, 0x02, 0x94, 0x2b, 0x01, 0x02, 0x98, 0x2b, 0x01, 0x02, 0x9c, 0x2b, 0x01, 0x02, 0xa0, 0x2b, 0x01, 0x02, 0xa4, 0x2b, 0x01, 0x02, 0xa8, 0x2b, 0x01, 0x02, + 0xc4, 0x07, 0x02, 0x02, 0xc8, 0x07, 0x02, 0x02, 0xcc, 0x07, 0x02, 0x02, 0xd0, 0x07, 0x02, 0x02, 0x20, 0x1f, 0x03, 0x03, 0x28, 0x1f, 0x03, 0x03, 0x30, 0x1f, 0x03, 0x03, 0x60, 0x3e, 0x04, 0x04, + 0x70, 0x3e, 0x04, 0x04, 0x50, 0x14, 0x05, 0x04, 0x60, 0x14, 0x05, 0x04, 0x40, 0x30, 0x06, 0x05, 0xc0, 0x26, 0x08, 0x06, 0x44, 0x02, 0x00, 0x02, 0x48, 0x02, 0x00, 0x02, 0x4c, 0x02, 0x00, 0x02, + 0x50, 0x02, 0x00, 0x02, 0xac, 0x2b, 0x01, 0x02, 0xb0, 0x2b, 0x01, 0x02, 0xb4, 0x2b, 0x01, 0x02, 0xb8, 0x2b, 0x01, 0x02, 0xbc, 0x2b, 0x01, 0x02, 0xc0, 0x2b, 0x01, 0x02, 0xc4, 0x2b, 0x01, 0x02, + 0xd4, 0x07, 0x02, 0x02, 0xd8, 0x07, 0x02, 0x02, 0xdc, 0x07, 0x02, 0x02, 0xe0, 0x07, 0x02, 0x02, 0x38, 0x1f, 0x03, 0x03, 0x40, 0x1f, 0x03, 0x03, 0x48, 0x1f, 0x03, 0x03, 0x80, 0x3e, 0x04, 0x04, + 0x90, 0x3e, 0x04, 0x04, 0x70, 0x14, 0x05, 0x04, 0x80, 0x14, 0x05, 0x04, 0x60, 0x30, 0x06, 0x05, 0x00, 0x27, 0x08, 0x06, 0x54, 0x02, 0x00, 0x02, 0x58, 0x02, 0x00, 0x02, 0x5c, 0x02, 0x00, 0x02, + 0x60, 0x02, 0x00, 0x02, 0xc8, 0x2b, 0x01, 0x02, 0xcc, 0x2b, 0x01, 0x02, 0xd0, 0x2b, 0x01, 0x02, 0xd4, 0x2b, 0x01, 0x02, 0xd8, 0x2b, 0x01, 0x02, 0xdc, 0x2b, 0x01, 0x02, 0xe0, 0x2b, 0x01, 0x02, + 0xe4, 0x07, 0x02, 0x02, 0xe8, 0x07, 0x02, 0x02, 0xec, 0x07, 0x02, 0x02, 0xf0, 0x07, 0x02, 0x02, 0x50, 0x1f, 0x03, 0x03, 0x58, 0x1f, 0x03, 0x03, 0x60, 0x1f, 0x03, 0x03, 0xa0, 0x3e, 0x04, 0x04, + 0xb0, 0x3e, 0x04, 0x04, 0x90, 0x14, 0x05, 0x04, 0xa0, 0x14, 0x05, 0x04, 0x80, 0x30, 0x06, 0x05, 0x40, 0x00, 0x09, 0x06, 0x64, 0x02, 0x00, 0x02, 0x68, 0x02, 0x00, 0x02, 0x6c, 0x02, 0x00, 0x02, + 0x70, 0x02, 0x00, 0x02, 0xe4, 0x2b, 0x01, 0x02, 0xe8, 0x2b, 0x01, 0x02, 0xec, 0x2b, 0x01, 0x02, 0xf0, 0x2b, 0x01, 0x02, 0xf4, 0x2b, 0x01, 0x02, 0xf8, 0x2b, 0x01, 0x02, 0xfc, 0x2b, 0x01, 0x02, + 0xf4, 0x07, 0x02, 0x02, 0xf8, 0x07, 0x02, 0x02, 0xfc, 0x07, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x68, 0x1f, 0x03, 0x03, 0x70, 0x1f, 0x03, 0x03, 0x78, 0x1f, 0x03, 0x03, 0xc0, 0x3e, 0x04, 0x04, + 0xd0, 0x3e, 0x04, 0x04, 0xb0, 0x14, 0x05, 0x04, 0xc0, 0x14, 0x05, 0x04, 0xa0, 0x30, 0x06, 0x05, 0x80, 0x00, 0x09, 0x06, 0x74, 0x02, 0x00, 0x02, 0x78, 0x02, 0x00, 0x02, 0x7c, 0x02, 0x00, 0x02, + 0x80, 0x02, 0x00, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x04, 0x2c, 0x01, 0x02, 0x08, 0x2c, 0x01, 0x02, 0x0c, 0x2c, 0x01, 0x02, 0x10, 0x2c, 0x01, 0x02, 0x14, 0x2c, 0x01, 0x02, 0x18, 0x2c, 0x01, 0x02, + 0x04, 0x08, 0x02, 0x02, 0x08, 0x08, 0x02, 0x02, 0x0c, 0x08, 0x02, 0x02, 0x10, 0x08, 0x02, 0x02, 0x80, 0x1f, 0x03, 0x03, 0x88, 0x1f, 0x03, 0x03, 0x90, 0x1f, 0x03, 0x03, 0xe0, 0x3e, 0x04, 0x04, + 0xf0, 0x3e, 0x04, 0x04, 0xd0, 0x14, 0x05, 0x04, 0xe0, 0x14, 0x05, 0x04, 0xc0, 0x30, 0x06, 0x05, 0xc0, 0x00, 0x09, 0x06, 0x84, 0x02, 0x00, 0x02, 0x88, 0x02, 0x00, 0x02, 0x8c, 0x02, 0x00, 0x02, + 0x90, 0x02, 0x00, 0x02, 0x1c, 0x2c, 0x01, 0x02, 0x20, 0x2c, 0x01, 0x02, 0x24, 0x2c, 0x01, 0x02, 0x28, 0x2c, 0x01, 0x02, 0x2c, 0x2c, 0x01, 0x02, 0x30, 0x2c, 0x01, 0x02, 0x34, 0x2c, 0x01, 0x02, + 0x14, 0x08, 0x02, 0x02, 0x18, 0x08, 0x02, 0x02, 0x1c, 0x08, 0x02, 0x02, 0x20, 0x08, 0x02, 0x02, 0x98, 0x1f, 0x03, 0x03, 0xa0, 0x1f, 0x03, 0x03, 0xa8, 0x1f, 0x03, 0x03, 0x00, 0x3f, 0x04, 0x04, + 0x10, 0x3f, 0x04, 0x04, 0xf0, 0x14, 0x05, 0x04, 0x00, 0x15, 0x05, 0x04, 0xa0, 0x08, 0x07, 0x05, 0x00, 0x01, 0x09, 0x06, 0x94, 0x02, 0x00, 0x02, 0x98, 0x02, 0x00, 0x02, 0x9c, 0x02, 0x00, 0x02, + 0xa0, 0x02, 0x00, 0x02, 0x38, 0x2c, 0x01, 0x02, 0x3c, 0x2c, 0x01, 0x02, 0x40, 0x2c, 0x01, 0x02, 0x44, 0x2c, 0x01, 0x02, 0x48, 0x2c, 0x01, 0x02, 0x4c, 0x2c, 0x01, 0x02, 0x50, 0x2c, 0x01, 0x02, + 0x24, 0x08, 0x02, 0x02, 0x28, 0x08, 0x02, 0x02, 0x2c, 0x08, 0x02, 0x02, 0x30, 0x08, 0x02, 0x02, 0xb0, 0x1f, 0x03, 0x03, 0xb8, 0x1f, 0x03, 0x03, 0xc0, 0x1f, 0x03, 0x03, 0x20, 0x3f, 0x04, 0x04, + 0x30, 0x3f, 0x04, 0x04, 0x10, 0x15, 0x05, 0x04, 0x20, 0x15, 0x05, 0x04, 0xc0, 0x08, 0x07, 0x05, 0x40, 0x01, 0x09, 0x06, 0xa4, 0x02, 0x00, 0x02, 0xa8, 0x02, 0x00, 0x02, 0xac, 0x02, 0x00, 0x02, + 0xb0, 0x02, 0x00, 0x02, 0x54, 0x2c, 0x01, 0x02, 0x58, 0x2c, 0x01, 0x02, 0x5c, 0x2c, 0x01, 0x02, 0x60, 0x2c, 0x01, 0x02, 0x64, 0x2c, 0x01, 0x02, 0x68, 0x2c, 0x01, 0x02, 0x6c, 0x2c, 0x01, 0x02, + 0x34, 0x08, 0x02, 0x02, 0x38, 0x08, 0x02, 0x02, 0x3c, 0x08, 0x02, 0x02, 0x40, 0x08, 0x02, 0x02, 0xc8, 0x1f, 0x03, 0x03, 0xd0, 0x1f, 0x03, 0x03, 0xd8, 0x1f, 0x03, 0x03, 0x40, 0x3f, 0x04, 0x04, + 0x50, 0x3f, 0x04, 0x04, 0x30, 0x15, 0x05, 0x04, 0x40, 0x15, 0x05, 0x04, 0xe0, 0x08, 0x07, 0x05, 0x80, 0x01, 0x09, 0x06, 0xb4, 0x02, 0x00, 0x02, 0xb8, 0x02, 0x00, 0x02, 0xbc, 0x02, 0x00, 0x02, + 0xc0, 0x02, 0x00, 0x02, 0x70, 0x2c, 0x01, 0x02, 0x74, 0x2c, 0x01, 0x02, 0x78, 0x2c, 0x01, 0x02, 0x7c, 0x2c, 0x01, 0x02, 0x80, 0x2c, 0x01, 0x02, 0x84, 0x2c, 0x01, 0x02, 0x88, 0x2c, 0x01, 0x02, + 0x44, 0x08, 0x02, 0x02, 0x48, 0x08, 0x02, 0x02, 0x4c, 0x08, 0x02, 0x02, 0x50, 0x08, 0x02, 0x02, 0xe0, 0x1f, 0x03, 0x03, 0xe8, 0x1f, 0x03, 0x03, 0xf0, 0x1f, 0x03, 0x03, 0x60, 0x3f, 0x04, 0x04, + 0x70, 0x3f, 0x04, 0x04, 0x50, 0x15, 0x05, 0x04, 0x60, 0x15, 0x05, 0x04, 0x00, 0x09, 0x07, 0x05, 0xc0, 0x01, 0x09, 0x06, 0xc4, 0x02, 0x00, 0x02, 0xc8, 0x02, 0x00, 0x02, 0xcc, 0x02, 0x00, 0x02, + 0xd0, 0x02, 0x00, 0x02, 0x8c, 0x2c, 0x01, 0x02, 0x90, 0x2c, 0x01, 0x02, 0x94, 0x2c, 0x01, 0x02, 0x98, 0x2c, 0x01, 0x02, 0x9c, 0x2c, 0x01, 0x02, 0xa0, 0x2c, 0x01, 0x02, 0xa4, 0x2c, 0x01, 0x02, + 0x54, 0x08, 0x02, 0x02, 0x58, 0x08, 0x02, 0x02, 0x5c, 0x08, 0x02, 0x02, 0x60, 0x08, 0x02, 0x02, 0xf8, 0x1f, 0x03, 0x03, 0x00, 0x20, 0x03, 0x03, 0x08, 0x20, 0x03, 0x03, 0x80, 0x3f, 0x04, 0x04, + 0x90, 0x3f, 0x04, 0x04, 0x70, 0x15, 0x05, 0x04, 0x80, 0x15, 0x05, 0x04, 0x20, 0x09, 0x07, 0x05, 0x00, 0x02, 0x09, 0x06, 0xd4, 0x02, 0x00, 0x02, 0xd8, 0x02, 0x00, 0x02, 0xdc, 0x02, 0x00, 0x02, + 0xe0, 0x02, 0x00, 0x02, 0xa8, 0x2c, 0x01, 0x02, 0xac, 0x2c, 0x01, 0x02, 0xb0, 0x2c, 0x01, 0x02, 0xb4, 0x2c, 0x01, 0x02, 0xb8, 0x2c, 0x01, 0x02, 0xbc, 0x2c, 0x01, 0x02, 0xc0, 0x2c, 0x01, 0x02, + 0x64, 0x08, 0x02, 0x02, 0x68, 0x08, 0x02, 0x02, 0x6c, 0x08, 0x02, 0x02, 0x70, 0x08, 0x02, 0x02, 0x10, 0x20, 0x03, 0x03, 0x18, 0x20, 0x03, 0x03, 0x20, 0x20, 0x03, 0x03, 0xa0, 0x3f, 0x04, 0x04, + 0xb0, 0x3f, 0x04, 0x04, 0x90, 0x15, 0x05, 0x04, 0xa0, 0x15, 0x05, 0x04, 0x40, 0x09, 0x07, 0x05, 0x40, 0x02, 0x09, 0x06, 0xe4, 0x02, 0x00, 0x02, 0xe8, 0x02, 0x00, 0x02, 0xec, 0x02, 0x00, 0x02, + 0xf0, 0x02, 0x00, 0x02, 0xc4, 0x2c, 0x01, 0x02, 0xc8, 0x2c, 0x01, 0x02, 0xcc, 0x2c, 0x01, 0x02, 0xd0, 0x2c, 0x01, 0x02, 0xd4, 0x2c, 0x01, 0x02, 0xd8, 0x2c, 0x01, 0x02, 0xdc, 0x2c, 0x01, 0x02, + 0x74, 0x08, 0x02, 0x02, 0x78, 0x08, 0x02, 0x02, 0x7c, 0x08, 0x02, 0x02, 0x80, 0x08, 0x02, 0x02, 0x28, 0x20, 0x03, 0x03, 0x30, 0x20, 0x03, 0x03, 0x38, 0x20, 0x03, 0x03, 0xc0, 0x3f, 0x04, 0x04, + 0xd0, 0x3f, 0x04, 0x04, 0xb0, 0x15, 0x05, 0x04, 0xc0, 0x15, 0x05, 0x04, 0x60, 0x09, 0x07, 0x05, 0x80, 0x02, 0x09, 0x06, 0xf4, 0x02, 0x00, 0x02, 0xf8, 0x02, 0x00, 0x02, 0xfc, 0x02, 0x00, 0x02, + 0x00, 0x03, 0x00, 0x02, 0xe0, 0x2c, 0x01, 0x02, 0xe4, 0x2c, 0x01, 0x02, 0xe8, 0x2c, 0x01, 0x02, 0xec, 0x2c, 0x01, 0x02, 0xf0, 0x2c, 0x01, 0x02, 0xf4, 0x2c, 0x01, 0x02, 0xf8, 0x2c, 0x01, 0x02, + 0x84, 0x08, 0x02, 0x02, 0x88, 0x08, 0x02, 0x02, 0x8c, 0x08, 0x02, 0x02, 0x90, 0x08, 0x02, 0x02, 0x40, 0x20, 0x03, 0x03, 0x48, 0x20, 0x03, 0x03, 0x50, 0x20, 0x03, 0x03, 0xe0, 0x3f, 0x04, 0x04, + 0xf0, 0x3f, 0x04, 0x04, 0xd0, 0x15, 0x05, 0x04, 0xe0, 0x15, 0x05, 0x04, 0x80, 0x09, 0x07, 0x05, 0xc0, 0x02, 0x09, 0x06, 0x04, 0x03, 0x00, 0x02, 0x08, 0x03, 0x00, 0x02, 0x0c, 0x03, 0x00, 0x02, + 0x10, 0x03, 0x00, 0x02, 0xfc, 0x2c, 0x01, 0x02, 0x00, 0x2d, 0x01, 0x02, 0x04, 0x2d, 0x01, 0x02, 0x08, 0x2d, 0x01, 0x02, 0x0c, 0x2d, 0x01, 0x02, 0x10, 0x2d, 0x01, 0x02, 0x14, 0x2d, 0x01, 0x02, + 0x94, 0x08, 0x02, 0x02, 0x98, 0x08, 0x02, 0x02, 0x9c, 0x08, 0x02, 0x02, 0xa0, 0x08, 0x02, 0x02, 0x58, 0x20, 0x03, 0x03, 0x60, 0x20, 0x03, 0x03, 0x68, 0x20, 0x03, 0x03, 0x00, 0x00, 0x04, 0x03, + 0x08, 0x00, 0x04, 0x03, 0xf0, 0x15, 0x05, 0x04, 0x00, 0x16, 0x05, 0x04, 0xa0, 0x09, 0x07, 0x05, 0x00, 0x03, 0x09, 0x06, 0x14, 0x03, 0x00, 0x02, 0x18, 0x03, 0x00, 0x02, 0x1c, 0x03, 0x00, 0x02, + 0x20, 0x03, 0x00, 0x02, 0x18, 0x2d, 0x01, 0x02, 0x1c, 0x2d, 0x01, 0x02, 0x20, 0x2d, 0x01, 0x02, 0x24, 0x2d, 0x01, 0x02, 0x28, 0x2d, 0x01, 0x02, 0x2c, 0x2d, 0x01, 0x02, 0x30, 0x2d, 0x01, 0x02, + 0xa4, 0x08, 0x02, 0x02, 0xa8, 0x08, 0x02, 0x02, 0xac, 0x08, 0x02, 0x02, 0xb0, 0x08, 0x02, 0x02, 0x70, 0x20, 0x03, 0x03, 0x78, 0x20, 0x03, 0x03, 0x80, 0x20, 0x03, 0x03, 0x10, 0x00, 0x04, 0x03, + 0x18, 0x00, 0x04, 0x03, 0x10, 0x16, 0x05, 0x04, 0x20, 0x16, 0x05, 0x04, 0xc0, 0x09, 0x07, 0x05, 0x40, 0x03, 0x09, 0x06, 0x24, 0x03, 0x00, 0x02, 0x28, 0x03, 0x00, 0x02, 0x2c, 0x03, 0x00, 0x02, + 0x30, 0x03, 0x00, 0x02, 0x34, 0x2d, 0x01, 0x02, 0x38, 0x2d, 0x01, 0x02, 0x3c, 0x2d, 0x01, 0x02, 0x40, 0x2d, 0x01, 0x02, 0x44, 0x2d, 0x01, 0x02, 0x48, 0x2d, 0x01, 0x02, 0x4c, 0x2d, 0x01, 0x02, + 0xb4, 0x08, 0x02, 0x02, 0xb8, 0x08, 0x02, 0x02, 0xbc, 0x08, 0x02, 0x02, 0xc0, 0x08, 0x02, 0x02, 0x88, 0x20, 0x03, 0x03, 0x90, 0x20, 0x03, 0x03, 0x98, 0x20, 0x03, 0x03, 0x20, 0x00, 0x04, 0x03, + 0x28, 0x00, 0x04, 0x03, 0x30, 0x16, 0x05, 0x04, 0x40, 0x16, 0x05, 0x04, 0xe0, 0x09, 0x07, 0x05, 0x80, 0x03, 0x09, 0x06, 0x34, 0x03, 0x00, 0x02, 0x38, 0x03, 0x00, 0x02, 0x3c, 0x03, 0x00, 0x02, + 0x40, 0x03, 0x00, 0x02, 0x50, 0x2d, 0x01, 0x02, 0x54, 0x2d, 0x01, 0x02, 0x58, 0x2d, 0x01, 0x02, 0x5c, 0x2d, 0x01, 0x02, 0x60, 0x2d, 0x01, 0x02, 0x64, 0x2d, 0x01, 0x02, 0x68, 0x2d, 0x01, 0x02, + 0xc4, 0x08, 0x02, 0x02, 0xc8, 0x08, 0x02, 0x02, 0xcc, 0x08, 0x02, 0x02, 0xd0, 0x08, 0x02, 0x02, 0xa0, 0x20, 0x03, 0x03, 0xa8, 0x20, 0x03, 0x03, 0xb0, 0x20, 0x03, 0x03, 0x30, 0x00, 0x04, 0x03, + 0x38, 0x00, 0x04, 0x03, 0x50, 0x16, 0x05, 0x04, 0xe0, 0x30, 0x06, 0x05, 0x00, 0x0a, 0x07, 0x05, 0xc0, 0x03, 0x09, 0x06, 0x44, 0x03, 0x00, 0x02, 0x48, 0x03, 0x00, 0x02, 0x4c, 0x03, 0x00, 0x02, + 0x50, 0x03, 0x00, 0x02, 0x6c, 0x2d, 0x01, 0x02, 0x70, 0x2d, 0x01, 0x02, 0x74, 0x2d, 0x01, 0x02, 0x78, 0x2d, 0x01, 0x02, 0x7c, 0x2d, 0x01, 0x02, 0x80, 0x2d, 0x01, 0x02, 0x84, 0x2d, 0x01, 0x02, + 0xd4, 0x08, 0x02, 0x02, 0xd8, 0x08, 0x02, 0x02, 0xdc, 0x08, 0x02, 0x02, 0xe0, 0x08, 0x02, 0x02, 0xb8, 0x20, 0x03, 0x03, 0xc0, 0x20, 0x03, 0x03, 0xc8, 0x20, 0x03, 0x03, 0x40, 0x00, 0x04, 0x03, + 0x48, 0x00, 0x04, 0x03, 0x60, 0x16, 0x05, 0x04, 0x00, 0x31, 0x06, 0x05, 0x20, 0x0a, 0x07, 0x05, 0x00, 0x04, 0x09, 0x06, 0x54, 0x03, 0x00, 0x02, 0x58, 0x03, 0x00, 0x02, 0x5c, 0x03, 0x00, 0x02, + 0x60, 0x03, 0x00, 0x02, 0x88, 0x2d, 0x01, 0x02, 0x8c, 0x2d, 0x01, 0x02, 0x90, 0x2d, 0x01, 0x02, 0x94, 0x2d, 0x01, 0x02, 0x98, 0x2d, 0x01, 0x02, 0x9c, 0x2d, 0x01, 0x02, 0xa0, 0x2d, 0x01, 0x02, + 0xe4, 0x08, 0x02, 0x02, 0xe8, 0x08, 0x02, 0x02, 0xec, 0x08, 0x02, 0x02, 0xf0, 0x08, 0x02, 0x02, 0xd0, 0x20, 0x03, 0x03, 0xd8, 0x20, 0x03, 0x03, 0xe0, 0x20, 0x03, 0x03, 0x50, 0x00, 0x04, 0x03, + 0x58, 0x00, 0x04, 0x03, 0x70, 0x16, 0x05, 0x04, 0x20, 0x31, 0x06, 0x05, 0x40, 0x0a, 0x07, 0x05, 0x40, 0x04, 0x09, 0x06, 0x64, 0x03, 0x00, 0x02, 0x68, 0x03, 0x00, 0x02, 0x6c, 0x03, 0x00, 0x02, + 0x70, 0x03, 0x00, 0x02, 0xa4, 0x2d, 0x01, 0x02, 0xa8, 0x2d, 0x01, 0x02, 0xac, 0x2d, 0x01, 0x02, 0xb0, 0x2d, 0x01, 0x02, 0xb4, 0x2d, 0x01, 0x02, 0xb8, 0x2d, 0x01, 0x02, 0xbc, 0x2d, 0x01, 0x02, + 0xf4, 0x08, 0x02, 0x02, 0xf8, 0x08, 0x02, 0x02, 0xfc, 0x08, 0x02, 0x02, 0x00, 0x09, 0x02, 0x02, 0xe8, 0x20, 0x03, 0x03, 0xf0, 0x20, 0x03, 0x03, 0xf8, 0x20, 0x03, 0x03, 0x60, 0x00, 0x04, 0x03, + 0x68, 0x00, 0x04, 0x03, 0x80, 0x16, 0x05, 0x04, 0x40, 0x31, 0x06, 0x05, 0x60, 0x0a, 0x07, 0x05, 0x80, 0x04, 0x09, 0x06, 0x74, 0x03, 0x00, 0x02, 0x78, 0x03, 0x00, 0x02, 0x7c, 0x03, 0x00, 0x02, + 0x80, 0x03, 0x00, 0x02, 0xc0, 0x2d, 0x01, 0x02, 0xc4, 0x2d, 0x01, 0x02, 0xc8, 0x2d, 0x01, 0x02, 0xcc, 0x2d, 0x01, 0x02, 0xd0, 0x2d, 0x01, 0x02, 0xd4, 0x2d, 0x01, 0x02, 0xd8, 0x2d, 0x01, 0x02, + 0x04, 0x09, 0x02, 0x02, 0x08, 0x09, 0x02, 0x02, 0x0c, 0x09, 0x02, 0x02, 0x10, 0x09, 0x02, 0x02, 0x00, 0x21, 0x03, 0x03, 0x08, 0x21, 0x03, 0x03, 0x10, 0x21, 0x03, 0x03, 0x70, 0x00, 0x04, 0x03, + 0x78, 0x00, 0x04, 0x03, 0x90, 0x16, 0x05, 0x04, 0x60, 0x31, 0x06, 0x05, 0x80, 0x0a, 0x07, 0x05, 0xc0, 0x04, 0x09, 0x06, 0x84, 0x03, 0x00, 0x02, 0x88, 0x03, 0x00, 0x02, 0x8c, 0x03, 0x00, 0x02, + 0x90, 0x03, 0x00, 0x02, 0xdc, 0x2d, 0x01, 0x02, 0xe0, 0x2d, 0x01, 0x02, 0xe4, 0x2d, 0x01, 0x02, 0xe8, 0x2d, 0x01, 0x02, 0xec, 0x2d, 0x01, 0x02, 0xf0, 0x2d, 0x01, 0x02, 0xf4, 0x2d, 0x01, 0x02, + 0x14, 0x09, 0x02, 0x02, 0x18, 0x09, 0x02, 0x02, 0x1c, 0x09, 0x02, 0x02, 0x20, 0x09, 0x02, 0x02, 0x18, 0x21, 0x03, 0x03, 0x20, 0x21, 0x03, 0x03, 0x28, 0x21, 0x03, 0x03, 0x80, 0x00, 0x04, 0x03, + 0x88, 0x00, 0x04, 0x03, 0xa0, 0x16, 0x05, 0x04, 0x80, 0x31, 0x06, 0x05, 0xa0, 0x0a, 0x07, 0x05, 0x00, 0x05, 0x09, 0x06, 0x94, 0x03, 0x00, 0x02, 0x98, 0x03, 0x00, 0x02, 0x9c, 0x03, 0x00, 0x02, + 0xa0, 0x03, 0x00, 0x02, 0xf8, 0x2d, 0x01, 0x02, 0xfc, 0x2d, 0x01, 0x02, 0x00, 0x2e, 0x01, 0x02, 0x04, 0x2e, 0x01, 0x02, 0x08, 0x2e, 0x01, 0x02, 0x0c, 0x2e, 0x01, 0x02, 0x10, 0x2e, 0x01, 0x02, + 0x24, 0x09, 0x02, 0x02, 0x28, 0x09, 0x02, 0x02, 0x2c, 0x09, 0x02, 0x02, 0x30, 0x09, 0x02, 0x02, 0x30, 0x21, 0x03, 0x03, 0x38, 0x21, 0x03, 0x03, 0x40, 0x21, 0x03, 0x03, 0x90, 0x00, 0x04, 0x03, + 0x98, 0x00, 0x04, 0x03, 0xb0, 0x16, 0x05, 0x04, 0xa0, 0x31, 0x06, 0x05, 0xc0, 0x0a, 0x07, 0x05, 0x40, 0x05, 0x09, 0x06, 0xa4, 0x03, 0x00, 0x02, 0xa8, 0x03, 0x00, 0x02, 0xac, 0x03, 0x00, 0x02, + 0xb0, 0x03, 0x00, 0x02, 0x14, 0x2e, 0x01, 0x02, 0x18, 0x2e, 0x01, 0x02, 0x1c, 0x2e, 0x01, 0x02, 0x20, 0x2e, 0x01, 0x02, 0x24, 0x2e, 0x01, 0x02, 0x28, 0x2e, 0x01, 0x02, 0x2c, 0x2e, 0x01, 0x02, + 0x34, 0x09, 0x02, 0x02, 0x38, 0x09, 0x02, 0x02, 0x3c, 0x09, 0x02, 0x02, 0x40, 0x09, 0x02, 0x02, 0x48, 0x21, 0x03, 0x03, 0x50, 0x21, 0x03, 0x03, 0x58, 0x21, 0x03, 0x03, 0xa0, 0x00, 0x04, 0x03, + 0xa8, 0x00, 0x04, 0x03, 0xc0, 0x16, 0x05, 0x04, 0xc0, 0x31, 0x06, 0x05, 0xe0, 0x0a, 0x07, 0x05, 0x80, 0x15, 0x0a, 0x07, 0xb4, 0x03, 0x00, 0x02, 0xb8, 0x03, 0x00, 0x02, 0xbc, 0x03, 0x00, 0x02, + 0xc0, 0x03, 0x00, 0x02, 0x30, 0x2e, 0x01, 0x02, 0x34, 0x2e, 0x01, 0x02, 0x38, 0x2e, 0x01, 0x02, 0x3c, 0x2e, 0x01, 0x02, 0x40, 0x2e, 0x01, 0x02, 0x44, 0x2e, 0x01, 0x02, 0x48, 0x2e, 0x01, 0x02, + 0x44, 0x09, 0x02, 0x02, 0x48, 0x09, 0x02, 0x02, 0x4c, 0x09, 0x02, 0x02, 0x50, 0x09, 0x02, 0x02, 0x60, 0x21, 0x03, 0x03, 0x68, 0x21, 0x03, 0x03, 0x70, 0x21, 0x03, 0x03, 0xb0, 0x00, 0x04, 0x03, + 0xb8, 0x00, 0x04, 0x03, 0xd0, 0x16, 0x05, 0x04, 0xe0, 0x31, 0x06, 0x05, 0x00, 0x0b, 0x07, 0x05, 0x00, 0x16, 0x0a, 0x07, 0xc4, 0x03, 0x00, 0x02, 0xc8, 0x03, 0x00, 0x02, 0xcc, 0x03, 0x00, 0x02, + 0xd0, 0x03, 0x00, 0x02, 0x4c, 0x2e, 0x01, 0x02, 0x50, 0x2e, 0x01, 0x02, 0x54, 0x2e, 0x01, 0x02, 0x58, 0x2e, 0x01, 0x02, 0x5c, 0x2e, 0x01, 0x02, 0x60, 0x2e, 0x01, 0x02, 0x64, 0x2e, 0x01, 0x02, + 0x54, 0x09, 0x02, 0x02, 0x58, 0x09, 0x02, 0x02, 0x5c, 0x09, 0x02, 0x02, 0x60, 0x09, 0x02, 0x02, 0x78, 0x21, 0x03, 0x03, 0x80, 0x21, 0x03, 0x03, 0x88, 0x21, 0x03, 0x03, 0xc0, 0x00, 0x04, 0x03, + 0xc8, 0x00, 0x04, 0x03, 0xe0, 0x16, 0x05, 0x04, 0x00, 0x32, 0x06, 0x05, 0x20, 0x0b, 0x07, 0x05, 0x80, 0x16, 0x0a, 0x07, 0xd4, 0x03, 0x00, 0x02, 0xd8, 0x03, 0x00, 0x02, 0xdc, 0x03, 0x00, 0x02, + 0xe0, 0x03, 0x00, 0x02, 0x68, 0x2e, 0x01, 0x02, 0x6c, 0x2e, 0x01, 0x02, 0x70, 0x2e, 0x01, 0x02, 0x74, 0x2e, 0x01, 0x02, 0x78, 0x2e, 0x01, 0x02, 0x7c, 0x2e, 0x01, 0x02, 0x80, 0x2e, 0x01, 0x02, + 0x64, 0x09, 0x02, 0x02, 0x68, 0x09, 0x02, 0x02, 0x6c, 0x09, 0x02, 0x02, 0x70, 0x09, 0x02, 0x02, 0x90, 0x21, 0x03, 0x03, 0x98, 0x21, 0x03, 0x03, 0xa0, 0x21, 0x03, 0x03, 0xd0, 0x00, 0x04, 0x03, + 0xd8, 0x00, 0x04, 0x03, 0xf0, 0x16, 0x05, 0x04, 0x20, 0x32, 0x06, 0x05, 0x40, 0x0b, 0x07, 0x05, 0x00, 0x17, 0x0a, 0x07, 0xe4, 0x03, 0x00, 0x02, 0xe8, 0x03, 0x00, 0x02, 0xec, 0x03, 0x00, 0x02, + 0xf0, 0x03, 0x00, 0x02, 0x84, 0x2e, 0x01, 0x02, 0x88, 0x2e, 0x01, 0x02, 0x8c, 0x2e, 0x01, 0x02, 0x90, 0x2e, 0x01, 0x02, 0x94, 0x2e, 0x01, 0x02, 0x98, 0x2e, 0x01, 0x02, 0x9c, 0x2e, 0x01, 0x02, + 0x74, 0x09, 0x02, 0x02, 0x78, 0x09, 0x02, 0x02, 0x7c, 0x09, 0x02, 0x02, 0x80, 0x09, 0x02, 0x02, 0xa8, 0x21, 0x03, 0x03, 0xb0, 0x21, 0x03, 0x03, 0xb8, 0x21, 0x03, 0x03, 0xe0, 0x00, 0x04, 0x03, + 0xe8, 0x00, 0x04, 0x03, 0x00, 0x17, 0x05, 0x04, 0x40, 0x32, 0x06, 0x05, 0x60, 0x0b, 0x07, 0x05, 0x80, 0x17, 0x0a, 0x07, 0xf4, 0x03, 0x00, 0x02, 0xf8, 0x03, 0x00, 0x02, 0xfc, 0x03, 0x00, 0x02, + 0x00, 0x04, 0x00, 0x02, 0xa0, 0x2e, 0x01, 0x02, 0xa4, 0x2e, 0x01, 0x02, 0xa8, 0x2e, 0x01, 0x02, 0xac, 0x2e, 0x01, 0x02, 0xb0, 0x2e, 0x01, 0x02, 0xb4, 0x2e, 0x01, 0x02, 0xb8, 0x2e, 0x01, 0x02, + 0x84, 0x09, 0x02, 0x02, 0x88, 0x09, 0x02, 0x02, 0x8c, 0x09, 0x02, 0x02, 0x90, 0x09, 0x02, 0x02, 0xc0, 0x21, 0x03, 0x03, 0xc8, 0x21, 0x03, 0x03, 0xd0, 0x21, 0x03, 0x03, 0xf0, 0x00, 0x04, 0x03, + 0xf8, 0x00, 0x04, 0x03, 0x10, 0x17, 0x05, 0x04, 0x60, 0x32, 0x06, 0x05, 0x80, 0x0b, 0x07, 0x05, 0x00, 0x18, 0x0a, 0x07, 0x04, 0x04, 0x00, 0x02, 0x08, 0x04, 0x00, 0x02, 0x0c, 0x04, 0x00, 0x02, + 0x10, 0x04, 0x00, 0x02, 0xbc, 0x2e, 0x01, 0x02, 0xc0, 0x2e, 0x01, 0x02, 0xc4, 0x2e, 0x01, 0x02, 0xc8, 0x2e, 0x01, 0x02, 0xcc, 0x2e, 0x01, 0x02, 0xd0, 0x2e, 0x01, 0x02, 0xd4, 0x2e, 0x01, 0x02, + 0x94, 0x09, 0x02, 0x02, 0x98, 0x09, 0x02, 0x02, 0x9c, 0x09, 0x02, 0x02, 0xa0, 0x09, 0x02, 0x02, 0xd8, 0x21, 0x03, 0x03, 0xe0, 0x21, 0x03, 0x03, 0xe8, 0x21, 0x03, 0x03, 0x00, 0x01, 0x04, 0x03, + 0x08, 0x01, 0x04, 0x03, 0x20, 0x17, 0x05, 0x04, 0x80, 0x32, 0x06, 0x05, 0xa0, 0x0b, 0x07, 0x05, 0x80, 0x18, 0x0a, 0x07, 0x14, 0x04, 0x00, 0x02, 0x18, 0x04, 0x00, 0x02, 0x1c, 0x04, 0x00, 0x02, + 0x20, 0x04, 0x00, 0x02, 0xd8, 0x2e, 0x01, 0x02, 0xdc, 0x2e, 0x01, 0x02, 0xe0, 0x2e, 0x01, 0x02, 0xe4, 0x2e, 0x01, 0x02, 0xe8, 0x2e, 0x01, 0x02, 0xec, 0x2e, 0x01, 0x02, 0xf0, 0x2e, 0x01, 0x02, + 0xa4, 0x09, 0x02, 0x02, 0xa8, 0x09, 0x02, 0x02, 0xac, 0x09, 0x02, 0x02, 0xb0, 0x09, 0x02, 0x02, 0xf0, 0x21, 0x03, 0x03, 0xf8, 0x21, 0x03, 0x03, 0x00, 0x22, 0x03, 0x03, 0x10, 0x01, 0x04, 0x03, + 0x18, 0x01, 0x04, 0x03, 0x30, 0x17, 0x05, 0x04, 0xa0, 0x32, 0x06, 0x05, 0xc0, 0x0b, 0x07, 0x05, 0x00, 0x19, 0x0a, 0x07, 0x24, 0x04, 0x00, 0x02, 0x28, 0x04, 0x00, 0x02, 0x2c, 0x04, 0x00, 0x02, + 0x30, 0x04, 0x00, 0x02, 0xf4, 0x2e, 0x01, 0x02, 0xf8, 0x2e, 0x01, 0x02, 0xfc, 0x2e, 0x01, 0x02, 0x00, 0x2f, 0x01, 0x02, 0x04, 0x2f, 0x01, 0x02, 0x08, 0x2f, 0x01, 0x02, 0x0c, 0x2f, 0x01, 0x02, + 0xb4, 0x09, 0x02, 0x02, 0xb8, 0x09, 0x02, 0x02, 0xbc, 0x09, 0x02, 0x02, 0xc0, 0x09, 0x02, 0x02, 0x08, 0x22, 0x03, 0x03, 0x10, 0x22, 0x03, 0x03, 0x18, 0x22, 0x03, 0x03, 0x20, 0x01, 0x04, 0x03, + 0x28, 0x01, 0x04, 0x03, 0x40, 0x17, 0x05, 0x04, 0xc0, 0x32, 0x06, 0x05, 0xe0, 0x0b, 0x07, 0x05, 0x80, 0x19, 0x0a, 0x07, 0x34, 0x04, 0x00, 0x02, 0x38, 0x04, 0x00, 0x02, 0x3c, 0x04, 0x00, 0x02, + 0x40, 0x04, 0x00, 0x02, 0x10, 0x2f, 0x01, 0x02, 0x14, 0x2f, 0x01, 0x02, 0x18, 0x2f, 0x01, 0x02, 0x1c, 0x2f, 0x01, 0x02, 0x20, 0x2f, 0x01, 0x02, 0x24, 0x2f, 0x01, 0x02, 0x28, 0x2f, 0x01, 0x02, + 0xc4, 0x09, 0x02, 0x02, 0xc8, 0x09, 0x02, 0x02, 0xcc, 0x09, 0x02, 0x02, 0xd0, 0x09, 0x02, 0x02, 0x20, 0x22, 0x03, 0x03, 0x28, 0x22, 0x03, 0x03, 0x30, 0x22, 0x03, 0x03, 0x30, 0x01, 0x04, 0x03, + 0x38, 0x01, 0x04, 0x03, 0x50, 0x17, 0x05, 0x04, 0xe0, 0x32, 0x06, 0x05, 0x00, 0x0c, 0x07, 0x05, 0x00, 0x1a, 0x0a, 0x07, 0x44, 0x04, 0x00, 0x02, 0x48, 0x04, 0x00, 0x02, 0x4c, 0x04, 0x00, 0x02, + 0x50, 0x04, 0x00, 0x02, 0x2c, 0x2f, 0x01, 0x02, 0x30, 0x2f, 0x01, 0x02, 0x34, 0x2f, 0x01, 0x02, 0x38, 0x2f, 0x01, 0x02, 0x3c, 0x2f, 0x01, 0x02, 0x40, 0x2f, 0x01, 0x02, 0x44, 0x2f, 0x01, 0x02, + 0xd4, 0x09, 0x02, 0x02, 0xd8, 0x09, 0x02, 0x02, 0xdc, 0x09, 0x02, 0x02, 0xe0, 0x09, 0x02, 0x02, 0x38, 0x22, 0x03, 0x03, 0x40, 0x22, 0x03, 0x03, 0x48, 0x22, 0x03, 0x03, 0x40, 0x01, 0x04, 0x03, + 0x48, 0x01, 0x04, 0x03, 0x60, 0x17, 0x05, 0x04, 0x00, 0x33, 0x06, 0x05, 0x20, 0x0c, 0x07, 0x05, 0x80, 0x1a, 0x0a, 0x07, 0x54, 0x04, 0x00, 0x02, 0x58, 0x04, 0x00, 0x02, 0x5c, 0x04, 0x00, 0x02, + 0x60, 0x04, 0x00, 0x02, 0x48, 0x2f, 0x01, 0x02, 0x4c, 0x2f, 0x01, 0x02, 0x50, 0x2f, 0x01, 0x02, 0x54, 0x2f, 0x01, 0x02, 0x58, 0x2f, 0x01, 0x02, 0x5c, 0x2f, 0x01, 0x02, 0x60, 0x2f, 0x01, 0x02, + 0xe4, 0x09, 0x02, 0x02, 0xe8, 0x09, 0x02, 0x02, 0xec, 0x09, 0x02, 0x02, 0xf0, 0x09, 0x02, 0x02, 0x50, 0x22, 0x03, 0x03, 0x58, 0x22, 0x03, 0x03, 0x60, 0x22, 0x03, 0x03, 0x50, 0x01, 0x04, 0x03, + 0x58, 0x01, 0x04, 0x03, 0x70, 0x17, 0x05, 0x04, 0x20, 0x33, 0x06, 0x05, 0x40, 0x0c, 0x07, 0x05, 0x00, 0x1b, 0x0a, 0x07, 0x64, 0x04, 0x00, 0x02, 0x68, 0x04, 0x00, 0x02, 0x6c, 0x04, 0x00, 0x02, + 0x70, 0x04, 0x00, 0x02, 0x64, 0x2f, 0x01, 0x02, 0x68, 0x2f, 0x01, 0x02, 0x6c, 0x2f, 0x01, 0x02, 0x70, 0x2f, 0x01, 0x02, 0x74, 0x2f, 0x01, 0x02, 0x78, 0x2f, 0x01, 0x02, 0x7c, 0x2f, 0x01, 0x02, + 0xf4, 0x09, 0x02, 0x02, 0xf8, 0x09, 0x02, 0x02, 0xfc, 0x09, 0x02, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x68, 0x22, 0x03, 0x03, 0x70, 0x22, 0x03, 0x03, 0x78, 0x22, 0x03, 0x03, 0x60, 0x01, 0x04, 0x03, + 0x68, 0x01, 0x04, 0x03, 0x80, 0x17, 0x05, 0x04, 0x40, 0x33, 0x06, 0x05, 0x60, 0x0c, 0x07, 0x05, 0x80, 0x1b, 0x0a, 0x07, 0x74, 0x04, 0x00, 0x02, 0x78, 0x04, 0x00, 0x02, 0x7c, 0x04, 0x00, 0x02, + 0x80, 0x04, 0x00, 0x02, 0x80, 0x2f, 0x01, 0x02, 0x84, 0x2f, 0x01, 0x02, 0x88, 0x2f, 0x01, 0x02, 0x8c, 0x2f, 0x01, 0x02, 0x90, 0x2f, 0x01, 0x02, 0x94, 0x2f, 0x01, 0x02, 0x98, 0x2f, 0x01, 0x02, + 0x04, 0x0a, 0x02, 0x02, 0x08, 0x0a, 0x02, 0x02, 0x0c, 0x0a, 0x02, 0x02, 0x10, 0x0a, 0x02, 0x02, 0x80, 0x22, 0x03, 0x03, 0x88, 0x22, 0x03, 0x03, 0x90, 0x22, 0x03, 0x03, 0x70, 0x01, 0x04, 0x03, + 0x78, 0x01, 0x04, 0x03, 0x90, 0x17, 0x05, 0x04, 0x60, 0x33, 0x06, 0x05, 0x80, 0x0c, 0x07, 0x05, 0x00, 0x1c, 0x0a, 0x07, 0x84, 0x04, 0x00, 0x02, 0x88, 0x04, 0x00, 0x02, 0x8c, 0x04, 0x00, 0x02, + 0x90, 0x04, 0x00, 0x02, 0x9c, 0x2f, 0x01, 0x02, 0xa0, 0x2f, 0x01, 0x02, 0xa4, 0x2f, 0x01, 0x02, 0xa8, 0x2f, 0x01, 0x02, 0xac, 0x2f, 0x01, 0x02, 0xb0, 0x2f, 0x01, 0x02, 0xb4, 0x2f, 0x01, 0x02, + 0x14, 0x0a, 0x02, 0x02, 0x18, 0x0a, 0x02, 0x02, 0x1c, 0x0a, 0x02, 0x02, 0x20, 0x0a, 0x02, 0x02, 0x98, 0x22, 0x03, 0x03, 0xa0, 0x22, 0x03, 0x03, 0xa8, 0x22, 0x03, 0x03, 0x80, 0x01, 0x04, 0x03, + 0x88, 0x01, 0x04, 0x03, 0xa0, 0x17, 0x05, 0x04, 0x80, 0x33, 0x06, 0x05, 0xa0, 0x0c, 0x07, 0x05, 0x00, 0x31, 0x0b, 0x08, 0x94, 0x04, 0x00, 0x02, 0x98, 0x04, 0x00, 0x02, 0x9c, 0x04, 0x00, 0x02, + 0xa0, 0x04, 0x00, 0x02, 0xb8, 0x2f, 0x01, 0x02, 0xbc, 0x2f, 0x01, 0x02, 0xc0, 0x2f, 0x01, 0x02, 0xc4, 0x2f, 0x01, 0x02, 0xc8, 0x2f, 0x01, 0x02, 0xcc, 0x2f, 0x01, 0x02, 0xd0, 0x2f, 0x01, 0x02, + 0x24, 0x0a, 0x02, 0x02, 0x28, 0x0a, 0x02, 0x02, 0x2c, 0x0a, 0x02, 0x02, 0x30, 0x0a, 0x02, 0x02, 0xb0, 0x22, 0x03, 0x03, 0xb8, 0x22, 0x03, 0x03, 0xc0, 0x22, 0x03, 0x03, 0x90, 0x01, 0x04, 0x03, + 0x98, 0x01, 0x04, 0x03, 0xb0, 0x17, 0x05, 0x04, 0xa0, 0x33, 0x06, 0x05, 0xc0, 0x0c, 0x07, 0x05, 0x00, 0x32, 0x0b, 0x08, 0xa4, 0x04, 0x00, 0x02, 0xa8, 0x04, 0x00, 0x02, 0xac, 0x04, 0x00, 0x02, + 0xb0, 0x04, 0x00, 0x02, 0xd4, 0x2f, 0x01, 0x02, 0xd8, 0x2f, 0x01, 0x02, 0xdc, 0x2f, 0x01, 0x02, 0xe0, 0x2f, 0x01, 0x02, 0xe4, 0x2f, 0x01, 0x02, 0xe8, 0x2f, 0x01, 0x02, 0xec, 0x2f, 0x01, 0x02, + 0x34, 0x0a, 0x02, 0x02, 0x38, 0x0a, 0x02, 0x02, 0x3c, 0x0a, 0x02, 0x02, 0x40, 0x0a, 0x02, 0x02, 0xc8, 0x22, 0x03, 0x03, 0xd0, 0x22, 0x03, 0x03, 0xd8, 0x22, 0x03, 0x03, 0xa0, 0x01, 0x04, 0x03, + 0xa8, 0x01, 0x04, 0x03, 0xc0, 0x17, 0x05, 0x04, 0xc0, 0x33, 0x06, 0x05, 0xe0, 0x0c, 0x07, 0x05, 0x00, 0x33, 0x0b, 0x08, 0xb4, 0x04, 0x00, 0x02, 0xb8, 0x04, 0x00, 0x02, 0xbc, 0x04, 0x00, 0x02, + 0xc0, 0x04, 0x00, 0x02, 0xf0, 0x2f, 0x01, 0x02, 0xf4, 0x2f, 0x01, 0x02, 0xf8, 0x2f, 0x01, 0x02, 0xfc, 0x2f, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x04, 0x30, 0x01, 0x02, 0x08, 0x30, 0x01, 0x02, + 0x44, 0x0a, 0x02, 0x02, 0x48, 0x0a, 0x02, 0x02, 0x4c, 0x0a, 0x02, 0x02, 0x50, 0x0a, 0x02, 0x02, 0xe0, 0x22, 0x03, 0x03, 0xe8, 0x22, 0x03, 0x03, 0xf0, 0x22, 0x03, 0x03, 0xb0, 0x01, 0x04, 0x03, + 0xb8, 0x01, 0x04, 0x03, 0xd0, 0x17, 0x05, 0x04, 0xe0, 0x33, 0x06, 0x05, 0x00, 0x0d, 0x07, 0x05, 0x00, 0x34, 0x0b, 0x08, 0xc4, 0x04, 0x00, 0x02, 0xc8, 0x04, 0x00, 0x02, 0xcc, 0x04, 0x00, 0x02, + 0xd0, 0x04, 0x00, 0x02, 0x0c, 0x30, 0x01, 0x02, 0x10, 0x30, 0x01, 0x02, 0x14, 0x30, 0x01, 0x02, 0x18, 0x30, 0x01, 0x02, 0x1c, 0x30, 0x01, 0x02, 0x20, 0x30, 0x01, 0x02, 0x24, 0x30, 0x01, 0x02, + 0x54, 0x0a, 0x02, 0x02, 0x58, 0x0a, 0x02, 0x02, 0x5c, 0x0a, 0x02, 0x02, 0x60, 0x0a, 0x02, 0x02, 0xf8, 0x22, 0x03, 0x03, 0x00, 0x23, 0x03, 0x03, 0x08, 0x23, 0x03, 0x03, 0xc0, 0x01, 0x04, 0x03, + 0xc8, 0x01, 0x04, 0x03, 0xe0, 0x17, 0x05, 0x04, 0x00, 0x34, 0x06, 0x05, 0x20, 0x0d, 0x07, 0x05, 0x00, 0x35, 0x0b, 0x08, 0xd4, 0x04, 0x00, 0x02, 0xd8, 0x04, 0x00, 0x02, 0xdc, 0x04, 0x00, 0x02, + 0xe0, 0x04, 0x00, 0x02, 0x28, 0x30, 0x01, 0x02, 0x2c, 0x30, 0x01, 0x02, 0x30, 0x30, 0x01, 0x02, 0x34, 0x30, 0x01, 0x02, 0x38, 0x30, 0x01, 0x02, 0x3c, 0x30, 0x01, 0x02, 0x40, 0x30, 0x01, 0x02, + 0x64, 0x0a, 0x02, 0x02, 0x68, 0x0a, 0x02, 0x02, 0x6c, 0x0a, 0x02, 0x02, 0x70, 0x0a, 0x02, 0x02, 0x10, 0x23, 0x03, 0x03, 0x18, 0x23, 0x03, 0x03, 0x20, 0x23, 0x03, 0x03, 0xd0, 0x01, 0x04, 0x03, + 0xd8, 0x01, 0x04, 0x03, 0xf0, 0x17, 0x05, 0x04, 0x20, 0x34, 0x06, 0x05, 0x40, 0x0d, 0x07, 0x05, 0x00, 0x36, 0x0b, 0x08, 0xe4, 0x04, 0x00, 0x02, 0xe8, 0x04, 0x00, 0x02, 0xec, 0x04, 0x00, 0x02, + 0xf0, 0x04, 0x00, 0x02, 0x44, 0x30, 0x01, 0x02, 0x48, 0x30, 0x01, 0x02, 0x4c, 0x30, 0x01, 0x02, 0x50, 0x30, 0x01, 0x02, 0x54, 0x30, 0x01, 0x02, 0x58, 0x30, 0x01, 0x02, 0x5c, 0x30, 0x01, 0x02, + 0x74, 0x0a, 0x02, 0x02, 0x78, 0x0a, 0x02, 0x02, 0x7c, 0x0a, 0x02, 0x02, 0x80, 0x0a, 0x02, 0x02, 0x28, 0x23, 0x03, 0x03, 0x30, 0x23, 0x03, 0x03, 0x38, 0x23, 0x03, 0x03, 0xe0, 0x01, 0x04, 0x03, + 0xe8, 0x01, 0x04, 0x03, 0x00, 0x18, 0x05, 0x04, 0x40, 0x34, 0x06, 0x05, 0x60, 0x0d, 0x07, 0x05, 0x00, 0x37, 0x0b, 0x08, 0xf4, 0x04, 0x00, 0x02, 0xf8, 0x04, 0x00, 0x02, 0xfc, 0x04, 0x00, 0x02, + 0x00, 0x05, 0x00, 0x02, 0x60, 0x30, 0x01, 0x02, 0x64, 0x30, 0x01, 0x02, 0x68, 0x30, 0x01, 0x02, 0x6c, 0x30, 0x01, 0x02, 0x70, 0x30, 0x01, 0x02, 0x74, 0x30, 0x01, 0x02, 0x78, 0x30, 0x01, 0x02, + 0x84, 0x0a, 0x02, 0x02, 0x88, 0x0a, 0x02, 0x02, 0x8c, 0x0a, 0x02, 0x02, 0x90, 0x0a, 0x02, 0x02, 0x40, 0x23, 0x03, 0x03, 0x48, 0x23, 0x03, 0x03, 0x50, 0x23, 0x03, 0x03, 0xf0, 0x01, 0x04, 0x03, + 0xf8, 0x01, 0x04, 0x03, 0x10, 0x18, 0x05, 0x04, 0x60, 0x34, 0x06, 0x05, 0x80, 0x0d, 0x07, 0x05, 0x00, 0x38, 0x0b, 0x08, 0x04, 0x05, 0x00, 0x02, 0x08, 0x05, 0x00, 0x02, 0x0c, 0x05, 0x00, 0x02, + 0x10, 0x05, 0x00, 0x02, 0x7c, 0x30, 0x01, 0x02, 0x80, 0x30, 0x01, 0x02, 0x84, 0x30, 0x01, 0x02, 0x88, 0x30, 0x01, 0x02, 0x8c, 0x30, 0x01, 0x02, 0x90, 0x30, 0x01, 0x02, 0x94, 0x30, 0x01, 0x02, + 0x94, 0x0a, 0x02, 0x02, 0x98, 0x0a, 0x02, 0x02, 0x9c, 0x0a, 0x02, 0x02, 0xa0, 0x0a, 0x02, 0x02, 0x58, 0x23, 0x03, 0x03, 0x60, 0x23, 0x03, 0x03, 0x68, 0x23, 0x03, 0x03, 0x00, 0x02, 0x04, 0x03, + 0x08, 0x02, 0x04, 0x03, 0x20, 0x18, 0x05, 0x04, 0x80, 0x34, 0x06, 0x05, 0xa0, 0x0d, 0x07, 0x05, 0x00, 0x39, 0x0b, 0x08, 0x14, 0x05, 0x00, 0x02, 0x18, 0x05, 0x00, 0x02, 0x1c, 0x05, 0x00, 0x02, + 0x20, 0x05, 0x00, 0x02, 0x98, 0x30, 0x01, 0x02, 0x9c, 0x30, 0x01, 0x02, 0xa0, 0x30, 0x01, 0x02, 0xa4, 0x30, 0x01, 0x02, 0xa8, 0x30, 0x01, 0x02, 0xac, 0x30, 0x01, 0x02, 0xa4, 0x0a, 0x02, 0x02, + 0xa8, 0x0a, 0x02, 0x02, 0xac, 0x0a, 0x02, 0x02, 0xb0, 0x0a, 0x02, 0x02, 0xb4, 0x0a, 0x02, 0x02, 0x70, 0x23, 0x03, 0x03, 0x78, 0x23, 0x03, 0x03, 0x80, 0x23, 0x03, 0x03, 0x10, 0x02, 0x04, 0x03, + 0x18, 0x02, 0x04, 0x03, 0x30, 0x18, 0x05, 0x04, 0xa0, 0x34, 0x06, 0x05, 0xc0, 0x0d, 0x07, 0x05, 0x00, 0x3a, 0x0b, 0x08, 0x24, 0x05, 0x00, 0x02, 0x28, 0x05, 0x00, 0x02, 0x2c, 0x05, 0x00, 0x02, + 0x30, 0x05, 0x00, 0x02, 0xb0, 0x30, 0x01, 0x02, 0xb4, 0x30, 0x01, 0x02, 0xb8, 0x30, 0x01, 0x02, 0xbc, 0x30, 0x01, 0x02, 0xc0, 0x30, 0x01, 0x02, 0xc4, 0x30, 0x01, 0x02, 0xb8, 0x0a, 0x02, 0x02, + 0xbc, 0x0a, 0x02, 0x02, 0xc0, 0x0a, 0x02, 0x02, 0xc4, 0x0a, 0x02, 0x02, 0xc8, 0x0a, 0x02, 0x02, 0x88, 0x23, 0x03, 0x03, 0x90, 0x23, 0x03, 0x03, 0x98, 0x23, 0x03, 0x03, 0x20, 0x02, 0x04, 0x03, + 0x28, 0x02, 0x04, 0x03, 0x40, 0x18, 0x05, 0x04, 0xc0, 0x34, 0x06, 0x05, 0xe0, 0x0d, 0x07, 0x05, 0x00, 0x0c, 0x0c, 0x08, 0x34, 0x05, 0x00, 0x02, 0x38, 0x05, 0x00, 0x02, 0x3c, 0x05, 0x00, 0x02, + 0x40, 0x05, 0x00, 0x02, 0xc8, 0x30, 0x01, 0x02, 0xcc, 0x30, 0x01, 0x02, 0xd0, 0x30, 0x01, 0x02, 0xd4, 0x30, 0x01, 0x02, 0xd8, 0x30, 0x01, 0x02, 0xdc, 0x30, 0x01, 0x02, 0xcc, 0x0a, 0x02, 0x02, + 0xd0, 0x0a, 0x02, 0x02, 0xd4, 0x0a, 0x02, 0x02, 0xd8, 0x0a, 0x02, 0x02, 0xdc, 0x0a, 0x02, 0x02, 0xa0, 0x23, 0x03, 0x03, 0xa8, 0x23, 0x03, 0x03, 0xb0, 0x23, 0x03, 0x03, 0x30, 0x02, 0x04, 0x03, + 0x38, 0x02, 0x04, 0x03, 0x50, 0x18, 0x05, 0x04, 0xe0, 0x34, 0x06, 0x05, 0x00, 0x0e, 0x07, 0x05, 0x00, 0x0d, 0x0c, 0x08, 0x44, 0x05, 0x00, 0x02, 0x48, 0x05, 0x00, 0x02, 0x4c, 0x05, 0x00, 0x02, + 0x50, 0x05, 0x00, 0x02, 0xe0, 0x30, 0x01, 0x02, 0xe4, 0x30, 0x01, 0x02, 0xe8, 0x30, 0x01, 0x02, 0xec, 0x30, 0x01, 0x02, 0xf0, 0x30, 0x01, 0x02, 0xf4, 0x30, 0x01, 0x02, 0xe0, 0x0a, 0x02, 0x02, + 0xe4, 0x0a, 0x02, 0x02, 0xe8, 0x0a, 0x02, 0x02, 0xec, 0x0a, 0x02, 0x02, 0xf0, 0x0a, 0x02, 0x02, 0xb8, 0x23, 0x03, 0x03, 0xc0, 0x23, 0x03, 0x03, 0xc8, 0x23, 0x03, 0x03, 0x40, 0x02, 0x04, 0x03, + 0x48, 0x02, 0x04, 0x03, 0x60, 0x18, 0x05, 0x04, 0x00, 0x35, 0x06, 0x05, 0x20, 0x0e, 0x07, 0x05, 0x00, 0x0e, 0x0c, 0x08, 0x54, 0x05, 0x00, 0x02, 0x58, 0x05, 0x00, 0x02, 0x5c, 0x05, 0x00, 0x02, + 0x60, 0x05, 0x00, 0x02, 0xf8, 0x30, 0x01, 0x02, 0xfc, 0x30, 0x01, 0x02, 0x00, 0x31, 0x01, 0x02, 0x04, 0x31, 0x01, 0x02, 0x08, 0x31, 0x01, 0x02, 0x0c, 0x31, 0x01, 0x02, 0xf4, 0x0a, 0x02, 0x02, + 0xf8, 0x0a, 0x02, 0x02, 0xfc, 0x0a, 0x02, 0x02, 0x00, 0x0b, 0x02, 0x02, 0x04, 0x0b, 0x02, 0x02, 0xd0, 0x23, 0x03, 0x03, 0xd8, 0x23, 0x03, 0x03, 0xe0, 0x23, 0x03, 0x03, 0x50, 0x02, 0x04, 0x03, + 0x58, 0x02, 0x04, 0x03, 0x70, 0x18, 0x05, 0x04, 0x20, 0x35, 0x06, 0x05, 0x40, 0x0e, 0x07, 0x05, 0x00, 0x0f, 0x0c, 0x08, 0x64, 0x05, 0x00, 0x02, 0x68, 0x05, 0x00, 0x02, 0x6c, 0x05, 0x00, 0x02, + 0x70, 0x05, 0x00, 0x02, 0x10, 0x31, 0x01, 0x02, 0x14, 0x31, 0x01, 0x02, 0x18, 0x31, 0x01, 0x02, 0x1c, 0x31, 0x01, 0x02, 0x20, 0x31, 0x01, 0x02, 0x24, 0x31, 0x01, 0x02, 0x08, 0x0b, 0x02, 0x02, + 0x0c, 0x0b, 0x02, 0x02, 0x10, 0x0b, 0x02, 0x02, 0x14, 0x0b, 0x02, 0x02, 0x18, 0x0b, 0x02, 0x02, 0xe8, 0x23, 0x03, 0x03, 0xf0, 0x23, 0x03, 0x03, 0xf8, 0x23, 0x03, 0x03, 0x60, 0x02, 0x04, 0x03, + 0x68, 0x02, 0x04, 0x03, 0x80, 0x18, 0x05, 0x04, 0x40, 0x35, 0x06, 0x05, 0x60, 0x0e, 0x07, 0x05, 0x00, 0x10, 0x0c, 0x08, 0x74, 0x05, 0x00, 0x02, 0x78, 0x05, 0x00, 0x02, 0x7c, 0x05, 0x00, 0x02, + 0x80, 0x05, 0x00, 0x02, 0x28, 0x31, 0x01, 0x02, 0x2c, 0x31, 0x01, 0x02, 0x30, 0x31, 0x01, 0x02, 0x34, 0x31, 0x01, 0x02, 0x38, 0x31, 0x01, 0x02, 0x3c, 0x31, 0x01, 0x02, 0x1c, 0x0b, 0x02, 0x02, + 0x20, 0x0b, 0x02, 0x02, 0x24, 0x0b, 0x02, 0x02, 0x28, 0x0b, 0x02, 0x02, 0x2c, 0x0b, 0x02, 0x02, 0x00, 0x24, 0x03, 0x03, 0x08, 0x24, 0x03, 0x03, 0x10, 0x24, 0x03, 0x03, 0x70, 0x02, 0x04, 0x03, + 0x78, 0x02, 0x04, 0x03, 0x90, 0x18, 0x05, 0x04, 0x60, 0x35, 0x06, 0x05, 0x80, 0x0e, 0x07, 0x05, 0x00, 0x11, 0x0c, 0x08, 0x84, 0x05, 0x00, 0x02, 0x88, 0x05, 0x00, 0x02, 0x8c, 0x05, 0x00, 0x02, + 0x90, 0x05, 0x00, 0x02, 0x40, 0x31, 0x01, 0x02, 0x44, 0x31, 0x01, 0x02, 0x48, 0x31, 0x01, 0x02, 0x4c, 0x31, 0x01, 0x02, 0x50, 0x31, 0x01, 0x02, 0x54, 0x31, 0x01, 0x02, 0x30, 0x0b, 0x02, 0x02, + 0x34, 0x0b, 0x02, 0x02, 0x38, 0x0b, 0x02, 0x02, 0x3c, 0x0b, 0x02, 0x02, 0x40, 0x0b, 0x02, 0x02, 0x18, 0x24, 0x03, 0x03, 0x20, 0x24, 0x03, 0x03, 0x28, 0x24, 0x03, 0x03, 0x80, 0x02, 0x04, 0x03, + 0x88, 0x02, 0x04, 0x03, 0xa0, 0x18, 0x05, 0x04, 0x80, 0x35, 0x06, 0x05, 0xa0, 0x0e, 0x07, 0x05, 0x00, 0x26, 0x0d, 0x09, 0x94, 0x05, 0x00, 0x02, 0x98, 0x05, 0x00, 0x02, 0x9c, 0x05, 0x00, 0x02, + 0xa0, 0x05, 0x00, 0x02, 0x58, 0x31, 0x01, 0x02, 0x5c, 0x31, 0x01, 0x02, 0x60, 0x31, 0x01, 0x02, 0x64, 0x31, 0x01, 0x02, 0x68, 0x31, 0x01, 0x02, 0x6c, 0x31, 0x01, 0x02, 0x44, 0x0b, 0x02, 0x02, + 0x48, 0x0b, 0x02, 0x02, 0x4c, 0x0b, 0x02, 0x02, 0x50, 0x0b, 0x02, 0x02, 0x54, 0x0b, 0x02, 0x02, 0x30, 0x24, 0x03, 0x03, 0x38, 0x24, 0x03, 0x03, 0x40, 0x24, 0x03, 0x03, 0x90, 0x02, 0x04, 0x03, + 0x98, 0x02, 0x04, 0x03, 0xb0, 0x18, 0x05, 0x04, 0xa0, 0x35, 0x06, 0x05, 0x40, 0x27, 0x08, 0x06, 0x00, 0x28, 0x0d, 0x09, 0xa4, 0x05, 0x00, 0x02, 0xa8, 0x05, 0x00, 0x02, 0xac, 0x05, 0x00, 0x02, + 0xb0, 0x05, 0x00, 0x02, 0x70, 0x31, 0x01, 0x02, 0x74, 0x31, 0x01, 0x02, 0x78, 0x31, 0x01, 0x02, 0x7c, 0x31, 0x01, 0x02, 0x80, 0x31, 0x01, 0x02, 0x84, 0x31, 0x01, 0x02, 0x58, 0x0b, 0x02, 0x02, + 0x5c, 0x0b, 0x02, 0x02, 0x60, 0x0b, 0x02, 0x02, 0x64, 0x0b, 0x02, 0x02, 0x68, 0x0b, 0x02, 0x02, 0x48, 0x24, 0x03, 0x03, 0x50, 0x24, 0x03, 0x03, 0x58, 0x24, 0x03, 0x03, 0xa0, 0x02, 0x04, 0x03, + 0xa8, 0x02, 0x04, 0x03, 0xc0, 0x18, 0x05, 0x04, 0xc0, 0x35, 0x06, 0x05, 0x80, 0x27, 0x08, 0x06, 0x00, 0x2a, 0x0d, 0x09, 0xb4, 0x05, 0x00, 0x02, 0xb8, 0x05, 0x00, 0x02, 0xbc, 0x05, 0x00, 0x02, + 0xc0, 0x05, 0x00, 0x02, 0x88, 0x31, 0x01, 0x02, 0x8c, 0x31, 0x01, 0x02, 0x90, 0x31, 0x01, 0x02, 0x94, 0x31, 0x01, 0x02, 0x98, 0x31, 0x01, 0x02, 0x9c, 0x31, 0x01, 0x02, 0x6c, 0x0b, 0x02, 0x02, + 0x70, 0x0b, 0x02, 0x02, 0x74, 0x0b, 0x02, 0x02, 0x78, 0x0b, 0x02, 0x02, 0x7c, 0x0b, 0x02, 0x02, 0x60, 0x24, 0x03, 0x03, 0x68, 0x24, 0x03, 0x03, 0x70, 0x24, 0x03, 0x03, 0xb0, 0x02, 0x04, 0x03, + 0xb8, 0x02, 0x04, 0x03, 0xd0, 0x18, 0x05, 0x04, 0xe0, 0x35, 0x06, 0x05, 0xc0, 0x27, 0x08, 0x06, 0x00, 0x2c, 0x0d, 0x09, 0xc4, 0x05, 0x00, 0x02, 0xc8, 0x05, 0x00, 0x02, 0xcc, 0x05, 0x00, 0x02, + 0xd0, 0x05, 0x00, 0x02, 0xa0, 0x31, 0x01, 0x02, 0xa4, 0x31, 0x01, 0x02, 0xa8, 0x31, 0x01, 0x02, 0xac, 0x31, 0x01, 0x02, 0xb0, 0x31, 0x01, 0x02, 0xb4, 0x31, 0x01, 0x02, 0x80, 0x0b, 0x02, 0x02, + 0x84, 0x0b, 0x02, 0x02, 0x88, 0x0b, 0x02, 0x02, 0x8c, 0x0b, 0x02, 0x02, 0x90, 0x0b, 0x02, 0x02, 0x78, 0x24, 0x03, 0x03, 0x80, 0x24, 0x03, 0x03, 0x88, 0x24, 0x03, 0x03, 0xc0, 0x02, 0x04, 0x03, + 0xc8, 0x02, 0x04, 0x03, 0xe0, 0x18, 0x05, 0x04, 0x00, 0x36, 0x06, 0x05, 0x00, 0x28, 0x08, 0x06, 0x00, 0x04, 0x0e, 0x09, 0xd4, 0x05, 0x00, 0x02, 0xd8, 0x05, 0x00, 0x02, 0xdc, 0x05, 0x00, 0x02, + 0xe0, 0x05, 0x00, 0x02, 0xb8, 0x31, 0x01, 0x02, 0xbc, 0x31, 0x01, 0x02, 0xc0, 0x31, 0x01, 0x02, 0xc4, 0x31, 0x01, 0x02, 0xc8, 0x31, 0x01, 0x02, 0xcc, 0x31, 0x01, 0x02, 0x94, 0x0b, 0x02, 0x02, + 0x98, 0x0b, 0x02, 0x02, 0x9c, 0x0b, 0x02, 0x02, 0xa0, 0x0b, 0x02, 0x02, 0xa4, 0x0b, 0x02, 0x02, 0x90, 0x24, 0x03, 0x03, 0x98, 0x24, 0x03, 0x03, 0xa0, 0x24, 0x03, 0x03, 0xd0, 0x02, 0x04, 0x03, + 0xd8, 0x02, 0x04, 0x03, 0xf0, 0x18, 0x05, 0x04, 0x20, 0x36, 0x06, 0x05, 0x40, 0x28, 0x08, 0x06, 0x00, 0x06, 0x0e, 0x09, 0xe4, 0x05, 0x00, 0x02, 0xe8, 0x05, 0x00, 0x02, 0xec, 0x05, 0x00, 0x02, + 0xf0, 0x05, 0x00, 0x02, 0xd0, 0x31, 0x01, 0x02, 0xd4, 0x31, 0x01, 0x02, 0xd8, 0x31, 0x01, 0x02, 0xdc, 0x31, 0x01, 0x02, 0xe0, 0x31, 0x01, 0x02, 0xe4, 0x31, 0x01, 0x02, 0xa8, 0x0b, 0x02, 0x02, + 0xac, 0x0b, 0x02, 0x02, 0xb0, 0x0b, 0x02, 0x02, 0xb4, 0x0b, 0x02, 0x02, 0xb8, 0x0b, 0x02, 0x02, 0xa8, 0x24, 0x03, 0x03, 0xb0, 0x24, 0x03, 0x03, 0xb8, 0x24, 0x03, 0x03, 0xe0, 0x02, 0x04, 0x03, + 0xe8, 0x02, 0x04, 0x03, 0x00, 0x19, 0x05, 0x04, 0x40, 0x36, 0x06, 0x05, 0x80, 0x28, 0x08, 0x06, 0x00, 0x08, 0x0e, 0x09, 0xf4, 0x05, 0x00, 0x02, 0xf8, 0x05, 0x00, 0x02, 0xfc, 0x05, 0x00, 0x02, + 0x00, 0x06, 0x00, 0x02, 0xe8, 0x31, 0x01, 0x02, 0xec, 0x31, 0x01, 0x02, 0xf0, 0x31, 0x01, 0x02, 0xf4, 0x31, 0x01, 0x02, 0xf8, 0x31, 0x01, 0x02, 0xfc, 0x31, 0x01, 0x02, 0xbc, 0x0b, 0x02, 0x02, + 0xc0, 0x0b, 0x02, 0x02, 0xc4, 0x0b, 0x02, 0x02, 0xc8, 0x0b, 0x02, 0x02, 0xcc, 0x0b, 0x02, 0x02, 0xc0, 0x24, 0x03, 0x03, 0xc8, 0x24, 0x03, 0x03, 0xd0, 0x24, 0x03, 0x03, 0xf0, 0x02, 0x04, 0x03, + 0xf8, 0x02, 0x04, 0x03, 0x10, 0x19, 0x05, 0x04, 0x60, 0x36, 0x06, 0x05, 0xc0, 0x28, 0x08, 0x06, 0x00, 0x0a, 0x0e, 0x09, 0x04, 0x06, 0x00, 0x02, 0x08, 0x06, 0x00, 0x02, 0x0c, 0x06, 0x00, 0x02, + 0x10, 0x06, 0x00, 0x02, 0x00, 0x32, 0x01, 0x02, 0x04, 0x32, 0x01, 0x02, 0x08, 0x32, 0x01, 0x02, 0x0c, 0x32, 0x01, 0x02, 0x10, 0x32, 0x01, 0x02, 0x14, 0x32, 0x01, 0x02, 0xd0, 0x0b, 0x02, 0x02, + 0xd4, 0x0b, 0x02, 0x02, 0xd8, 0x0b, 0x02, 0x02, 0xdc, 0x0b, 0x02, 0x02, 0xe0, 0x0b, 0x02, 0x02, 0xd8, 0x24, 0x03, 0x03, 0xe0, 0x24, 0x03, 0x03, 0xe8, 0x24, 0x03, 0x03, 0x00, 0x03, 0x04, 0x03, + 0x08, 0x03, 0x04, 0x03, 0x20, 0x19, 0x05, 0x04, 0x80, 0x36, 0x06, 0x05, 0x00, 0x29, 0x08, 0x06, 0x00, 0x20, 0x0f, 0x0a, 0x14, 0x06, 0x00, 0x02, 0x18, 0x06, 0x00, 0x02, 0x1c, 0x06, 0x00, 0x02, + 0x20, 0x06, 0x00, 0x02, 0x18, 0x32, 0x01, 0x02, 0x1c, 0x32, 0x01, 0x02, 0x20, 0x32, 0x01, 0x02, 0x24, 0x32, 0x01, 0x02, 0x28, 0x32, 0x01, 0x02, 0x2c, 0x32, 0x01, 0x02, 0xe4, 0x0b, 0x02, 0x02, + 0xe8, 0x0b, 0x02, 0x02, 0xec, 0x0b, 0x02, 0x02, 0xf0, 0x0b, 0x02, 0x02, 0xf4, 0x0b, 0x02, 0x02, 0xf0, 0x24, 0x03, 0x03, 0xf8, 0x24, 0x03, 0x03, 0x00, 0x25, 0x03, 0x03, 0x10, 0x03, 0x04, 0x03, + 0x18, 0x03, 0x04, 0x03, 0x30, 0x19, 0x05, 0x04, 0xa0, 0x36, 0x06, 0x05, 0x40, 0x29, 0x08, 0x06, 0x00, 0x24, 0x0f, 0x0a, 0x24, 0x06, 0x00, 0x02, 0x28, 0x06, 0x00, 0x02, 0x2c, 0x06, 0x00, 0x02, + 0x30, 0x06, 0x00, 0x02, 0x30, 0x32, 0x01, 0x02, 0x34, 0x32, 0x01, 0x02, 0x38, 0x32, 0x01, 0x02, 0x3c, 0x32, 0x01, 0x02, 0x40, 0x32, 0x01, 0x02, 0x44, 0x32, 0x01, 0x02, 0xf8, 0x0b, 0x02, 0x02, + 0xfc, 0x0b, 0x02, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x04, 0x0c, 0x02, 0x02, 0x08, 0x0c, 0x02, 0x02, 0x08, 0x25, 0x03, 0x03, 0x10, 0x25, 0x03, 0x03, 0x18, 0x25, 0x03, 0x03, 0x20, 0x03, 0x04, 0x03, + 0x28, 0x03, 0x04, 0x03, 0x40, 0x19, 0x05, 0x04, 0xc0, 0x36, 0x06, 0x05, 0x80, 0x29, 0x08, 0x06, 0x00, 0x00, 0x10, 0x0a, 0x34, 0x06, 0x00, 0x02, 0x38, 0x06, 0x00, 0x02, 0x3c, 0x06, 0x00, 0x02, + 0x40, 0x06, 0x00, 0x02, 0x48, 0x32, 0x01, 0x02, 0x4c, 0x32, 0x01, 0x02, 0x50, 0x32, 0x01, 0x02, 0x54, 0x32, 0x01, 0x02, 0x58, 0x32, 0x01, 0x02, 0x5c, 0x32, 0x01, 0x02, 0x0c, 0x0c, 0x02, 0x02, + 0x10, 0x0c, 0x02, 0x02, 0x14, 0x0c, 0x02, 0x02, 0x18, 0x0c, 0x02, 0x02, 0x1c, 0x0c, 0x02, 0x02, 0x20, 0x25, 0x03, 0x03, 0x28, 0x25, 0x03, 0x03, 0x30, 0x25, 0x03, 0x03, 0x30, 0x03, 0x04, 0x03, + 0x38, 0x03, 0x04, 0x03, 0x50, 0x19, 0x05, 0x04, 0xe0, 0x36, 0x06, 0x05, 0xc0, 0x29, 0x08, 0x06, 0x00, 0x18, 0x11, 0x0b, 0x44, 0x06, 0x00, 0x02, 0x48, 0x06, 0x00, 0x02, 0x4c, 0x06, 0x00, 0x02, + 0x50, 0x06, 0x00, 0x02, 0x60, 0x32, 0x01, 0x02, 0x64, 0x32, 0x01, 0x02, 0x68, 0x32, 0x01, 0x02, 0x6c, 0x32, 0x01, 0x02, 0x70, 0x32, 0x01, 0x02, 0x74, 0x32, 0x01, 0x02, 0x20, 0x0c, 0x02, 0x02, + 0x24, 0x0c, 0x02, 0x02, 0x28, 0x0c, 0x02, 0x02, 0x2c, 0x0c, 0x02, 0x02, 0x30, 0x0c, 0x02, 0x02, 0x38, 0x25, 0x03, 0x03, 0x40, 0x25, 0x03, 0x03, 0x48, 0x25, 0x03, 0x03, 0x40, 0x03, 0x04, 0x03, + 0x48, 0x03, 0x04, 0x03, 0x60, 0x19, 0x05, 0x04, 0x00, 0x37, 0x06, 0x05, 0x00, 0x2a, 0x08, 0x06, 0x00, 0x20, 0x12, 0x0c, 0x54, 0x06, 0x00, 0x02, 0x58, 0x06, 0x00, 0x02, 0x5c, 0x06, 0x00, 0x02, + 0x60, 0x06, 0x00, 0x02, 0x78, 0x32, 0x01, 0x02, 0x7c, 0x32, 0x01, 0x02, 0x80, 0x32, 0x01, 0x02, 0x84, 0x32, 0x01, 0x02, 0x88, 0x32, 0x01, 0x02, 0x8c, 0x32, 0x01, 0x02, 0x34, 0x0c, 0x02, 0x02, + 0x38, 0x0c, 0x02, 0x02, 0x3c, 0x0c, 0x02, 0x02, 0x40, 0x0c, 0x02, 0x02, 0x44, 0x0c, 0x02, 0x02, 0x50, 0x25, 0x03, 0x03, 0x58, 0x25, 0x03, 0x03, 0x60, 0x25, 0x03, 0x03, 0x50, 0x03, 0x04, 0x03, + 0x58, 0x03, 0x04, 0x03, 0x70, 0x19, 0x05, 0x04, 0x20, 0x37, 0x06, 0x05, 0x40, 0x2a, 0x08, 0x06, 0x64, 0x06, 0x00, 0x02, 0x68, 0x06, 0x00, 0x02, 0x6c, 0x06, 0x00, 0x02, 0x70, 0x06, 0x00, 0x02, + 0x74, 0x06, 0x00, 0x02, 0x90, 0x32, 0x01, 0x02, 0x94, 0x32, 0x01, 0x02, 0x98, 0x32, 0x01, 0x02, 0x9c, 0x32, 0x01, 0x02, 0xa0, 0x32, 0x01, 0x02, 0xa4, 0x32, 0x01, 0x02, 0x48, 0x0c, 0x02, 0x02, + 0x4c, 0x0c, 0x02, 0x02, 0x50, 0x0c, 0x02, 0x02, 0x54, 0x0c, 0x02, 0x02, 0x58, 0x0c, 0x02, 0x02, 0x68, 0x25, 0x03, 0x03, 0x70, 0x25, 0x03, 0x03, 0x78, 0x25, 0x03, 0x03, 0x60, 0x03, 0x04, 0x03, + 0x68, 0x03, 0x04, 0x03, 0x80, 0x19, 0x05, 0x04, 0x40, 0x37, 0x06, 0x05, 0x80, 0x2a, 0x08, 0x06, 0x78, 0x06, 0x00, 0x02, 0x7c, 0x06, 0x00, 0x02, 0x80, 0x06, 0x00, 0x02, 0x84, 0x06, 0x00, 0x02, + 0x88, 0x06, 0x00, 0x02, 0xa8, 0x32, 0x01, 0x02, 0xac, 0x32, 0x01, 0x02, 0xb0, 0x32, 0x01, 0x02, 0xb4, 0x32, 0x01, 0x02, 0xb8, 0x32, 0x01, 0x02, 0xbc, 0x32, 0x01, 0x02, 0x5c, 0x0c, 0x02, 0x02, + 0x60, 0x0c, 0x02, 0x02, 0x64, 0x0c, 0x02, 0x02, 0x68, 0x0c, 0x02, 0x02, 0x6c, 0x0c, 0x02, 0x02, 0x80, 0x25, 0x03, 0x03, 0x88, 0x25, 0x03, 0x03, 0x90, 0x25, 0x03, 0x03, 0x70, 0x03, 0x04, 0x03, + 0x78, 0x03, 0x04, 0x03, 0x90, 0x19, 0x05, 0x04, 0x60, 0x37, 0x06, 0x05, 0xc0, 0x2a, 0x08, 0x06, 0x8c, 0x06, 0x00, 0x02, 0x90, 0x06, 0x00, 0x02, 0x94, 0x06, 0x00, 0x02, 0x98, 0x06, 0x00, 0x02, + 0x9c, 0x06, 0x00, 0x02, 0xc0, 0x32, 0x01, 0x02, 0xc4, 0x32, 0x01, 0x02, 0xc8, 0x32, 0x01, 0x02, 0xcc, 0x32, 0x01, 0x02, 0xd0, 0x32, 0x01, 0x02, 0xd4, 0x32, 0x01, 0x02, 0x70, 0x0c, 0x02, 0x02, + 0x74, 0x0c, 0x02, 0x02, 0x78, 0x0c, 0x02, 0x02, 0x7c, 0x0c, 0x02, 0x02, 0x80, 0x0c, 0x02, 0x02, 0x98, 0x25, 0x03, 0x03, 0xa0, 0x25, 0x03, 0x03, 0xa8, 0x25, 0x03, 0x03, 0x80, 0x03, 0x04, 0x03, + 0x88, 0x03, 0x04, 0x03, 0xa0, 0x19, 0x05, 0x04, 0x80, 0x37, 0x06, 0x05, 0x00, 0x2b, 0x08, 0x06, 0xa0, 0x06, 0x00, 0x02, 0xa4, 0x06, 0x00, 0x02, 0xa8, 0x06, 0x00, 0x02, 0xac, 0x06, 0x00, 0x02, + 0xb0, 0x06, 0x00, 0x02, 0xd8, 0x32, 0x01, 0x02, 0xdc, 0x32, 0x01, 0x02, 0xe0, 0x32, 0x01, 0x02, 0xe4, 0x32, 0x01, 0x02, 0xe8, 0x32, 0x01, 0x02, 0xec, 0x32, 0x01, 0x02, 0x84, 0x0c, 0x02, 0x02, + 0x88, 0x0c, 0x02, 0x02, 0x8c, 0x0c, 0x02, 0x02, 0x90, 0x0c, 0x02, 0x02, 0x94, 0x0c, 0x02, 0x02, 0xb0, 0x25, 0x03, 0x03, 0xb8, 0x25, 0x03, 0x03, 0xc0, 0x25, 0x03, 0x03, 0x90, 0x03, 0x04, 0x03, + 0x98, 0x03, 0x04, 0x03, 0xb0, 0x19, 0x05, 0x04, 0xa0, 0x37, 0x06, 0x05, 0x40, 0x2b, 0x08, 0x06, 0xb4, 0x06, 0x00, 0x02, 0xb8, 0x06, 0x00, 0x02, 0xbc, 0x06, 0x00, 0x02, 0xc0, 0x06, 0x00, 0x02, + 0xc4, 0x06, 0x00, 0x02, 0xf0, 0x32, 0x01, 0x02, 0xf4, 0x32, 0x01, 0x02, 0xf8, 0x32, 0x01, 0x02, 0xfc, 0x32, 0x01, 0x02, 0x00, 0x33, 0x01, 0x02, 0x04, 0x33, 0x01, 0x02, 0x98, 0x0c, 0x02, 0x02, + 0x9c, 0x0c, 0x02, 0x02, 0xa0, 0x0c, 0x02, 0x02, 0xa4, 0x0c, 0x02, 0x02, 0xa8, 0x0c, 0x02, 0x02, 0xc8, 0x25, 0x03, 0x03, 0xd0, 0x25, 0x03, 0x03, 0xd8, 0x25, 0x03, 0x03, 0xa0, 0x03, 0x04, 0x03, + 0xa8, 0x03, 0x04, 0x03, 0xc0, 0x19, 0x05, 0x04, 0xc0, 0x37, 0x06, 0x05, 0x80, 0x2b, 0x08, 0x06, 0xc8, 0x06, 0x00, 0x02, 0xcc, 0x06, 0x00, 0x02, 0xd0, 0x06, 0x00, 0x02, 0xd4, 0x06, 0x00, 0x02, + 0xd8, 0x06, 0x00, 0x02, 0x08, 0x33, 0x01, 0x02, 0x0c, 0x33, 0x01, 0x02, 0x10, 0x33, 0x01, 0x02, 0x14, 0x33, 0x01, 0x02, 0x18, 0x33, 0x01, 0x02, 0x1c, 0x33, 0x01, 0x02, 0xac, 0x0c, 0x02, 0x02, + 0xb0, 0x0c, 0x02, 0x02, 0xb4, 0x0c, 0x02, 0x02, 0xb8, 0x0c, 0x02, 0x02, 0xbc, 0x0c, 0x02, 0x02, 0xe0, 0x25, 0x03, 0x03, 0xe8, 0x25, 0x03, 0x03, 0xf0, 0x25, 0x03, 0x03, 0xb0, 0x03, 0x04, 0x03, + 0xb8, 0x03, 0x04, 0x03, 0xd0, 0x19, 0x05, 0x04, 0xe0, 0x37, 0x06, 0x05, 0xc0, 0x2b, 0x08, 0x06, 0xdc, 0x06, 0x00, 0x02, 0xe0, 0x06, 0x00, 0x02, 0xe4, 0x06, 0x00, 0x02, 0xe8, 0x06, 0x00, 0x02, + 0xec, 0x06, 0x00, 0x02, 0x20, 0x33, 0x01, 0x02, 0x24, 0x33, 0x01, 0x02, 0x28, 0x33, 0x01, 0x02, 0x2c, 0x33, 0x01, 0x02, 0x30, 0x33, 0x01, 0x02, 0x34, 0x33, 0x01, 0x02, 0xc0, 0x0c, 0x02, 0x02, + 0xc4, 0x0c, 0x02, 0x02, 0xc8, 0x0c, 0x02, 0x02, 0xcc, 0x0c, 0x02, 0x02, 0xd0, 0x0c, 0x02, 0x02, 0xf8, 0x25, 0x03, 0x03, 0x00, 0x26, 0x03, 0x03, 0x08, 0x26, 0x03, 0x03, 0xc0, 0x03, 0x04, 0x03, + 0xc8, 0x03, 0x04, 0x03, 0xe0, 0x19, 0x05, 0x04, 0x00, 0x38, 0x06, 0x05, 0x00, 0x2c, 0x08, 0x06, 0xf0, 0x06, 0x00, 0x02, 0xf4, 0x06, 0x00, 0x02, 0xf8, 0x06, 0x00, 0x02, 0xfc, 0x06, 0x00, 0x02, + 0x00, 0x07, 0x00, 0x02, 0x38, 0x33, 0x01, 0x02, 0x3c, 0x33, 0x01, 0x02, 0x40, 0x33, 0x01, 0x02, 0x44, 0x33, 0x01, 0x02, 0x48, 0x33, 0x01, 0x02, 0x4c, 0x33, 0x01, 0x02, 0xd4, 0x0c, 0x02, 0x02, + 0xd8, 0x0c, 0x02, 0x02, 0xdc, 0x0c, 0x02, 0x02, 0xe0, 0x0c, 0x02, 0x02, 0xe4, 0x0c, 0x02, 0x02, 0x10, 0x26, 0x03, 0x03, 0x18, 0x26, 0x03, 0x03, 0x20, 0x26, 0x03, 0x03, 0xd0, 0x03, 0x04, 0x03, + 0xd8, 0x03, 0x04, 0x03, 0xf0, 0x19, 0x05, 0x04, 0x20, 0x38, 0x06, 0x05, 0x40, 0x2c, 0x08, 0x06, 0x04, 0x07, 0x00, 0x02, 0x08, 0x07, 0x00, 0x02, 0x0c, 0x07, 0x00, 0x02, 0x10, 0x07, 0x00, 0x02, + 0x50, 0x33, 0x01, 0x02, 0x54, 0x33, 0x01, 0x02, 0x58, 0x33, 0x01, 0x02, 0x5c, 0x33, 0x01, 0x02, 0x60, 0x33, 0x01, 0x02, 0x64, 0x33, 0x01, 0x02, 0x68, 0x33, 0x01, 0x02, 0xe8, 0x0c, 0x02, 0x02, + 0xec, 0x0c, 0x02, 0x02, 0xf0, 0x0c, 0x02, 0x02, 0xf4, 0x0c, 0x02, 0x02, 0xf8, 0x0c, 0x02, 0x02, 0x28, 0x26, 0x03, 0x03, 0x30, 0x26, 0x03, 0x03, 0x38, 0x26, 0x03, 0x03, 0xe0, 0x03, 0x04, 0x03, + 0xe8, 0x03, 0x04, 0x03, 0x00, 0x1a, 0x05, 0x04, 0x40, 0x38, 0x06, 0x05, 0x80, 0x2c, 0x08, 0x06, 0x14, 0x07, 0x00, 0x02, 0x18, 0x07, 0x00, 0x02, 0x1c, 0x07, 0x00, 0x02, 0x20, 0x07, 0x00, 0x02, + 0x6c, 0x33, 0x01, 0x02, 0x70, 0x33, 0x01, 0x02, 0x74, 0x33, 0x01, 0x02, 0x78, 0x33, 0x01, 0x02, 0x7c, 0x33, 0x01, 0x02, 0x80, 0x33, 0x01, 0x02, 0x84, 0x33, 0x01, 0x02, 0xfc, 0x0c, 0x02, 0x02, + 0x00, 0x0d, 0x02, 0x02, 0x04, 0x0d, 0x02, 0x02, 0x08, 0x0d, 0x02, 0x02, 0x0c, 0x0d, 0x02, 0x02, 0x40, 0x26, 0x03, 0x03, 0x48, 0x26, 0x03, 0x03, 0x50, 0x26, 0x03, 0x03, 0xf0, 0x03, 0x04, 0x03, + 0x10, 0x1a, 0x05, 0x04, 0x20, 0x1a, 0x05, 0x04, 0x60, 0x38, 0x06, 0x05, 0xc0, 0x2c, 0x08, 0x06, 0x24, 0x07, 0x00, 0x02, 0x28, 0x07, 0x00, 0x02, 0x2c, 0x07, 0x00, 0x02, 0x30, 0x07, 0x00, 0x02, + 0x88, 0x33, 0x01, 0x02, 0x8c, 0x33, 0x01, 0x02, 0x90, 0x33, 0x01, 0x02, 0x94, 0x33, 0x01, 0x02, 0x98, 0x33, 0x01, 0x02, 0x9c, 0x33, 0x01, 0x02, 0xa0, 0x33, 0x01, 0x02, 0x10, 0x0d, 0x02, 0x02, + 0x14, 0x0d, 0x02, 0x02, 0x18, 0x0d, 0x02, 0x02, 0x1c, 0x0d, 0x02, 0x02, 0x20, 0x0d, 0x02, 0x02, 0x58, 0x26, 0x03, 0x03, 0x60, 0x26, 0x03, 0x03, 0x68, 0x26, 0x03, 0x03, 0xf8, 0x03, 0x04, 0x03, + 0x30, 0x1a, 0x05, 0x04, 0x40, 0x1a, 0x05, 0x04, 0x80, 0x38, 0x06, 0x05, 0x00, 0x2d, 0x08, 0x06, 0x34, 0x07, 0x00, 0x02, 0x38, 0x07, 0x00, 0x02, 0x3c, 0x07, 0x00, 0x02, 0x40, 0x07, 0x00, 0x02, + 0xa4, 0x33, 0x01, 0x02, 0xa8, 0x33, 0x01, 0x02, 0xac, 0x33, 0x01, 0x02, 0xb0, 0x33, 0x01, 0x02, 0xb4, 0x33, 0x01, 0x02, 0xb8, 0x33, 0x01, 0x02, 0xbc, 0x33, 0x01, 0x02, 0x24, 0x0d, 0x02, 0x02, + 0x28, 0x0d, 0x02, 0x02, 0x2c, 0x0d, 0x02, 0x02, 0x30, 0x0d, 0x02, 0x02, 0x34, 0x0d, 0x02, 0x02, 0x70, 0x26, 0x03, 0x03, 0x78, 0x26, 0x03, 0x03, 0x80, 0x26, 0x03, 0x03, 0x00, 0x04, 0x04, 0x03, + 0x50, 0x1a, 0x05, 0x04, 0x60, 0x1a, 0x05, 0x04, 0xa0, 0x38, 0x06, 0x05, 0x40, 0x2d, 0x08, 0x06, 0x44, 0x07, 0x00, 0x02, 0x48, 0x07, 0x00, 0x02, 0x4c, 0x07, 0x00, 0x02, 0x50, 0x07, 0x00, 0x02, + 0xc0, 0x33, 0x01, 0x02, 0xc4, 0x33, 0x01, 0x02, 0xc8, 0x33, 0x01, 0x02, 0xcc, 0x33, 0x01, 0x02, 0xd0, 0x33, 0x01, 0x02, 0xd4, 0x33, 0x01, 0x02, 0xd8, 0x33, 0x01, 0x02, 0x38, 0x0d, 0x02, 0x02, + 0x3c, 0x0d, 0x02, 0x02, 0x40, 0x0d, 0x02, 0x02, 0x44, 0x0d, 0x02, 0x02, 0x48, 0x0d, 0x02, 0x02, 0x88, 0x26, 0x03, 0x03, 0x90, 0x26, 0x03, 0x03, 0x98, 0x26, 0x03, 0x03, 0x08, 0x04, 0x04, 0x03, + 0x70, 0x1a, 0x05, 0x04, 0x80, 0x1a, 0x05, 0x04, 0xc0, 0x38, 0x06, 0x05, 0x80, 0x2d, 0x08, 0x06, 0x54, 0x07, 0x00, 0x02, 0x58, 0x07, 0x00, 0x02, 0x5c, 0x07, 0x00, 0x02, 0x60, 0x07, 0x00, 0x02, + 0xdc, 0x33, 0x01, 0x02, 0xe0, 0x33, 0x01, 0x02, 0xe4, 0x33, 0x01, 0x02, 0xe8, 0x33, 0x01, 0x02, 0xec, 0x33, 0x01, 0x02, 0xf0, 0x33, 0x01, 0x02, 0xf4, 0x33, 0x01, 0x02, 0x4c, 0x0d, 0x02, 0x02, + 0x50, 0x0d, 0x02, 0x02, 0x54, 0x0d, 0x02, 0x02, 0x58, 0x0d, 0x02, 0x02, 0x5c, 0x0d, 0x02, 0x02, 0xa0, 0x26, 0x03, 0x03, 0xa8, 0x26, 0x03, 0x03, 0x10, 0x04, 0x04, 0x03, 0x18, 0x04, 0x04, 0x03, + 0x90, 0x1a, 0x05, 0x04, 0xa0, 0x1a, 0x05, 0x04, 0xe0, 0x38, 0x06, 0x05, 0xc0, 0x2d, 0x08, 0x06, 0x64, 0x07, 0x00, 0x02, 0x68, 0x07, 0x00, 0x02, 0x6c, 0x07, 0x00, 0x02, 0x70, 0x07, 0x00, 0x02, + 0xf8, 0x33, 0x01, 0x02, 0xfc, 0x33, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x04, 0x34, 0x01, 0x02, 0x08, 0x34, 0x01, 0x02, 0x0c, 0x34, 0x01, 0x02, 0x10, 0x34, 0x01, 0x02, 0x60, 0x0d, 0x02, 0x02, + 0x64, 0x0d, 0x02, 0x02, 0x68, 0x0d, 0x02, 0x02, 0x6c, 0x0d, 0x02, 0x02, 0x70, 0x0d, 0x02, 0x02, 0xb0, 0x26, 0x03, 0x03, 0xb8, 0x26, 0x03, 0x03, 0x20, 0x04, 0x04, 0x03, 0x28, 0x04, 0x04, 0x03, + 0xb0, 0x1a, 0x05, 0x04, 0xc0, 0x1a, 0x05, 0x04, 0x00, 0x39, 0x06, 0x05, 0x00, 0x2e, 0x08, 0x06, 0x74, 0x07, 0x00, 0x02, 0x78, 0x07, 0x00, 0x02, 0x7c, 0x07, 0x00, 0x02, 0x80, 0x07, 0x00, 0x02, + 0x14, 0x34, 0x01, 0x02, 0x18, 0x34, 0x01, 0x02, 0x1c, 0x34, 0x01, 0x02, 0x20, 0x34, 0x01, 0x02, 0x24, 0x34, 0x01, 0x02, 0x28, 0x34, 0x01, 0x02, 0x2c, 0x34, 0x01, 0x02, 0x74, 0x0d, 0x02, 0x02, + 0x78, 0x0d, 0x02, 0x02, 0x7c, 0x0d, 0x02, 0x02, 0x80, 0x0d, 0x02, 0x02, 0x84, 0x0d, 0x02, 0x02, 0xc0, 0x26, 0x03, 0x03, 0xc8, 0x26, 0x03, 0x03, 0x30, 0x04, 0x04, 0x03, 0x38, 0x04, 0x04, 0x03, + 0xd0, 0x1a, 0x05, 0x04, 0xe0, 0x1a, 0x05, 0x04, 0x20, 0x39, 0x06, 0x05, 0x40, 0x2e, 0x08, 0x06, 0x84, 0x07, 0x00, 0x02, 0x88, 0x07, 0x00, 0x02, 0x8c, 0x07, 0x00, 0x02, 0x90, 0x07, 0x00, 0x02, + 0x30, 0x34, 0x01, 0x02, 0x34, 0x34, 0x01, 0x02, 0x38, 0x34, 0x01, 0x02, 0x3c, 0x34, 0x01, 0x02, 0x40, 0x34, 0x01, 0x02, 0x44, 0x34, 0x01, 0x02, 0x48, 0x34, 0x01, 0x02, 0x88, 0x0d, 0x02, 0x02, + 0x8c, 0x0d, 0x02, 0x02, 0x90, 0x0d, 0x02, 0x02, 0x94, 0x0d, 0x02, 0x02, 0x98, 0x0d, 0x02, 0x02, 0xd0, 0x26, 0x03, 0x03, 0xd8, 0x26, 0x03, 0x03, 0x40, 0x04, 0x04, 0x03, 0x48, 0x04, 0x04, 0x03, + 0xf0, 0x1a, 0x05, 0x04, 0x00, 0x1b, 0x05, 0x04, 0x40, 0x39, 0x06, 0x05, 0x80, 0x2e, 0x08, 0x06, 0x94, 0x07, 0x00, 0x02, 0x98, 0x07, 0x00, 0x02, 0x9c, 0x07, 0x00, 0x02, 0xa0, 0x07, 0x00, 0x02, + 0x4c, 0x34, 0x01, 0x02, 0x50, 0x34, 0x01, 0x02, 0x54, 0x34, 0x01, 0x02, 0x58, 0x34, 0x01, 0x02, 0x5c, 0x34, 0x01, 0x02, 0x60, 0x34, 0x01, 0x02, 0x64, 0x34, 0x01, 0x02, 0x9c, 0x0d, 0x02, 0x02, + 0xa0, 0x0d, 0x02, 0x02, 0xa4, 0x0d, 0x02, 0x02, 0xa8, 0x0d, 0x02, 0x02, 0xe0, 0x26, 0x03, 0x03, 0xe8, 0x26, 0x03, 0x03, 0xf0, 0x26, 0x03, 0x03, 0x50, 0x04, 0x04, 0x03, 0x58, 0x04, 0x04, 0x03, + 0x10, 0x1b, 0x05, 0x04, 0x20, 0x1b, 0x05, 0x04, 0x60, 0x39, 0x06, 0x05, 0xc0, 0x2e, 0x08, 0x06, 0xa4, 0x07, 0x00, 0x02, 0xa8, 0x07, 0x00, 0x02, 0xac, 0x07, 0x00, 0x02, 0xb0, 0x07, 0x00, 0x02, + 0x68, 0x34, 0x01, 0x02, 0x6c, 0x34, 0x01, 0x02, 0x70, 0x34, 0x01, 0x02, 0x74, 0x34, 0x01, 0x02, 0x78, 0x34, 0x01, 0x02, 0x7c, 0x34, 0x01, 0x02, 0x80, 0x34, 0x01, 0x02, 0xac, 0x0d, 0x02, 0x02, + 0xb0, 0x0d, 0x02, 0x02, 0xb4, 0x0d, 0x02, 0x02, 0xb8, 0x0d, 0x02, 0x02, 0xf8, 0x26, 0x03, 0x03, 0x00, 0x27, 0x03, 0x03, 0x08, 0x27, 0x03, 0x03, 0x60, 0x04, 0x04, 0x03, 0x68, 0x04, 0x04, 0x03, + 0x30, 0x1b, 0x05, 0x04, 0x40, 0x1b, 0x05, 0x04, 0x80, 0x39, 0x06, 0x05, 0x00, 0x2f, 0x08, 0x06, 0xb4, 0x07, 0x00, 0x02, 0xb8, 0x07, 0x00, 0x02, 0xbc, 0x07, 0x00, 0x02, 0xc0, 0x07, 0x00, 0x02, + 0x84, 0x34, 0x01, 0x02, 0x88, 0x34, 0x01, 0x02, 0x8c, 0x34, 0x01, 0x02, 0x90, 0x34, 0x01, 0x02, 0x94, 0x34, 0x01, 0x02, 0x98, 0x34, 0x01, 0x02, 0x9c, 0x34, 0x01, 0x02, 0xbc, 0x0d, 0x02, 0x02, + 0xc0, 0x0d, 0x02, 0x02, 0xc4, 0x0d, 0x02, 0x02, 0xc8, 0x0d, 0x02, 0x02, 0x10, 0x27, 0x03, 0x03, 0x18, 0x27, 0x03, 0x03, 0x20, 0x27, 0x03, 0x03, 0x70, 0x04, 0x04, 0x03, 0x78, 0x04, 0x04, 0x03, + 0x50, 0x1b, 0x05, 0x04, 0x60, 0x1b, 0x05, 0x04, 0xa0, 0x39, 0x06, 0x05, 0x40, 0x2f, 0x08, 0x06, 0xc4, 0x07, 0x00, 0x02, 0xc8, 0x07, 0x00, 0x02, 0xcc, 0x07, 0x00, 0x02, 0xd0, 0x07, 0x00, 0x02, + 0xa0, 0x34, 0x01, 0x02, 0xa4, 0x34, 0x01, 0x02, 0xa8, 0x34, 0x01, 0x02, 0xac, 0x34, 0x01, 0x02, 0xb0, 0x34, 0x01, 0x02, 0xb4, 0x34, 0x01, 0x02, 0xb8, 0x34, 0x01, 0x02, 0xcc, 0x0d, 0x02, 0x02, + 0xd0, 0x0d, 0x02, 0x02, 0xd4, 0x0d, 0x02, 0x02, 0xd8, 0x0d, 0x02, 0x02, 0x28, 0x27, 0x03, 0x03, 0x30, 0x27, 0x03, 0x03, 0x38, 0x27, 0x03, 0x03, 0x80, 0x04, 0x04, 0x03, 0x88, 0x04, 0x04, 0x03, + 0x70, 0x1b, 0x05, 0x04, 0x80, 0x1b, 0x05, 0x04, 0xc0, 0x39, 0x06, 0x05, 0x80, 0x05, 0x09, 0x06, 0xd4, 0x07, 0x00, 0x02, 0xd8, 0x07, 0x00, 0x02, 0xdc, 0x07, 0x00, 0x02, 0xe0, 0x07, 0x00, 0x02, + 0xbc, 0x34, 0x01, 0x02, 0xc0, 0x34, 0x01, 0x02, 0xc4, 0x34, 0x01, 0x02, 0xc8, 0x34, 0x01, 0x02, 0xcc, 0x34, 0x01, 0x02, 0xd0, 0x34, 0x01, 0x02, 0xd4, 0x34, 0x01, 0x02, 0xdc, 0x0d, 0x02, 0x02, + 0xe0, 0x0d, 0x02, 0x02, 0xe4, 0x0d, 0x02, 0x02, 0xe8, 0x0d, 0x02, 0x02, 0x40, 0x27, 0x03, 0x03, 0x48, 0x27, 0x03, 0x03, 0x50, 0x27, 0x03, 0x03, 0x90, 0x04, 0x04, 0x03, 0x98, 0x04, 0x04, 0x03, + 0x90, 0x1b, 0x05, 0x04, 0xa0, 0x1b, 0x05, 0x04, 0xe0, 0x39, 0x06, 0x05, 0xc0, 0x05, 0x09, 0x06, 0xe4, 0x07, 0x00, 0x02, 0xe8, 0x07, 0x00, 0x02, 0xec, 0x07, 0x00, 0x02, 0xf0, 0x07, 0x00, 0x02, + 0xd8, 0x34, 0x01, 0x02, 0xdc, 0x34, 0x01, 0x02, 0xe0, 0x34, 0x01, 0x02, 0xe4, 0x34, 0x01, 0x02, 0xe8, 0x34, 0x01, 0x02, 0xec, 0x34, 0x01, 0x02, 0xf0, 0x34, 0x01, 0x02, 0xec, 0x0d, 0x02, 0x02, + 0xf0, 0x0d, 0x02, 0x02, 0xf4, 0x0d, 0x02, 0x02, 0xf8, 0x0d, 0x02, 0x02, 0x58, 0x27, 0x03, 0x03, 0x60, 0x27, 0x03, 0x03, 0x68, 0x27, 0x03, 0x03, 0xa0, 0x04, 0x04, 0x03, 0xa8, 0x04, 0x04, 0x03, + 0xb0, 0x1b, 0x05, 0x04, 0xc0, 0x1b, 0x05, 0x04, 0x00, 0x3a, 0x06, 0x05, 0x00, 0x06, 0x09, 0x06, 0xf4, 0x07, 0x00, 0x02, 0xf8, 0x07, 0x00, 0x02, 0xfc, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, + 0xf4, 0x34, 0x01, 0x02, 0xf8, 0x34, 0x01, 0x02, 0xfc, 0x34, 0x01, 0x02, 0x00, 0x35, 0x01, 0x02, 0x04, 0x35, 0x01, 0x02, 0x08, 0x35, 0x01, 0x02, 0x0c, 0x35, 0x01, 0x02, 0xfc, 0x0d, 0x02, 0x02, + 0x00, 0x0e, 0x02, 0x02, 0x04, 0x0e, 0x02, 0x02, 0x08, 0x0e, 0x02, 0x02, 0x70, 0x27, 0x03, 0x03, 0x78, 0x27, 0x03, 0x03, 0x80, 0x27, 0x03, 0x03, 0xb0, 0x04, 0x04, 0x03, 0xb8, 0x04, 0x04, 0x03, + 0xd0, 0x1b, 0x05, 0x04, 0xe0, 0x1b, 0x05, 0x04, 0xc0, 0x0e, 0x07, 0x05, 0x40, 0x06, 0x09, 0x06, 0x04, 0x08, 0x00, 0x02, 0x08, 0x08, 0x00, 0x02, 0x0c, 0x08, 0x00, 0x02, 0x10, 0x08, 0x00, 0x02, + 0x10, 0x35, 0x01, 0x02, 0x14, 0x35, 0x01, 0x02, 0x18, 0x35, 0x01, 0x02, 0x1c, 0x35, 0x01, 0x02, 0x20, 0x35, 0x01, 0x02, 0x24, 0x35, 0x01, 0x02, 0x28, 0x35, 0x01, 0x02, 0x0c, 0x0e, 0x02, 0x02, + 0x10, 0x0e, 0x02, 0x02, 0x14, 0x0e, 0x02, 0x02, 0x18, 0x0e, 0x02, 0x02, 0x88, 0x27, 0x03, 0x03, 0x90, 0x27, 0x03, 0x03, 0x98, 0x27, 0x03, 0x03, 0xc0, 0x04, 0x04, 0x03, 0xc8, 0x04, 0x04, 0x03, + 0xf0, 0x1b, 0x05, 0x04, 0x00, 0x1c, 0x05, 0x04, 0xe0, 0x0e, 0x07, 0x05, 0x80, 0x06, 0x09, 0x06, 0x14, 0x08, 0x00, 0x02, 0x18, 0x08, 0x00, 0x02, 0x1c, 0x08, 0x00, 0x02, 0x20, 0x08, 0x00, 0x02, + 0x2c, 0x35, 0x01, 0x02, 0x30, 0x35, 0x01, 0x02, 0x34, 0x35, 0x01, 0x02, 0x38, 0x35, 0x01, 0x02, 0x3c, 0x35, 0x01, 0x02, 0x40, 0x35, 0x01, 0x02, 0x44, 0x35, 0x01, 0x02, 0x1c, 0x0e, 0x02, 0x02, + 0x20, 0x0e, 0x02, 0x02, 0x24, 0x0e, 0x02, 0x02, 0x28, 0x0e, 0x02, 0x02, 0xa0, 0x27, 0x03, 0x03, 0xa8, 0x27, 0x03, 0x03, 0xb0, 0x27, 0x03, 0x03, 0xd0, 0x04, 0x04, 0x03, 0xd8, 0x04, 0x04, 0x03, + 0x10, 0x1c, 0x05, 0x04, 0x20, 0x1c, 0x05, 0x04, 0x00, 0x0f, 0x07, 0x05, 0xc0, 0x06, 0x09, 0x06, 0x24, 0x08, 0x00, 0x02, 0x28, 0x08, 0x00, 0x02, 0x2c, 0x08, 0x00, 0x02, 0x30, 0x08, 0x00, 0x02, + 0x48, 0x35, 0x01, 0x02, 0x4c, 0x35, 0x01, 0x02, 0x50, 0x35, 0x01, 0x02, 0x54, 0x35, 0x01, 0x02, 0x58, 0x35, 0x01, 0x02, 0x5c, 0x35, 0x01, 0x02, 0x60, 0x35, 0x01, 0x02, 0x2c, 0x0e, 0x02, 0x02, + 0x30, 0x0e, 0x02, 0x02, 0x34, 0x0e, 0x02, 0x02, 0x38, 0x0e, 0x02, 0x02, 0xb8, 0x27, 0x03, 0x03, 0xc0, 0x27, 0x03, 0x03, 0xc8, 0x27, 0x03, 0x03, 0xe0, 0x04, 0x04, 0x03, 0xe8, 0x04, 0x04, 0x03, + 0x30, 0x1c, 0x05, 0x04, 0x40, 0x1c, 0x05, 0x04, 0x20, 0x0f, 0x07, 0x05, 0x00, 0x07, 0x09, 0x06, 0x34, 0x08, 0x00, 0x02, 0x38, 0x08, 0x00, 0x02, 0x3c, 0x08, 0x00, 0x02, 0x40, 0x08, 0x00, 0x02, + 0x64, 0x35, 0x01, 0x02, 0x68, 0x35, 0x01, 0x02, 0x6c, 0x35, 0x01, 0x02, 0x70, 0x35, 0x01, 0x02, 0x74, 0x35, 0x01, 0x02, 0x78, 0x35, 0x01, 0x02, 0x7c, 0x35, 0x01, 0x02, 0x3c, 0x0e, 0x02, 0x02, + 0x40, 0x0e, 0x02, 0x02, 0x44, 0x0e, 0x02, 0x02, 0x48, 0x0e, 0x02, 0x02, 0xd0, 0x27, 0x03, 0x03, 0xd8, 0x27, 0x03, 0x03, 0xe0, 0x27, 0x03, 0x03, 0xf0, 0x04, 0x04, 0x03, 0xf8, 0x04, 0x04, 0x03, + 0x50, 0x1c, 0x05, 0x04, 0x60, 0x1c, 0x05, 0x04, 0x40, 0x0f, 0x07, 0x05, 0x40, 0x07, 0x09, 0x06, 0x44, 0x08, 0x00, 0x02, 0x48, 0x08, 0x00, 0x02, 0x4c, 0x08, 0x00, 0x02, 0x50, 0x08, 0x00, 0x02, + 0x80, 0x35, 0x01, 0x02, 0x84, 0x35, 0x01, 0x02, 0x88, 0x35, 0x01, 0x02, 0x8c, 0x35, 0x01, 0x02, 0x90, 0x35, 0x01, 0x02, 0x94, 0x35, 0x01, 0x02, 0x98, 0x35, 0x01, 0x02, 0x4c, 0x0e, 0x02, 0x02, + 0x50, 0x0e, 0x02, 0x02, 0x54, 0x0e, 0x02, 0x02, 0x58, 0x0e, 0x02, 0x02, 0xe8, 0x27, 0x03, 0x03, 0xf0, 0x27, 0x03, 0x03, 0xf8, 0x27, 0x03, 0x03, 0x00, 0x05, 0x04, 0x03, 0x08, 0x05, 0x04, 0x03, + 0x70, 0x1c, 0x05, 0x04, 0x80, 0x1c, 0x05, 0x04, 0x60, 0x0f, 0x07, 0x05, 0x80, 0x07, 0x09, 0x06, 0x54, 0x08, 0x00, 0x02, 0x58, 0x08, 0x00, 0x02, 0x5c, 0x08, 0x00, 0x02, 0x60, 0x08, 0x00, 0x02, + 0x9c, 0x35, 0x01, 0x02, 0xa0, 0x35, 0x01, 0x02, 0xa4, 0x35, 0x01, 0x02, 0xa8, 0x35, 0x01, 0x02, 0xac, 0x35, 0x01, 0x02, 0xb0, 0x35, 0x01, 0x02, 0xb4, 0x35, 0x01, 0x02, 0x5c, 0x0e, 0x02, 0x02, + 0x60, 0x0e, 0x02, 0x02, 0x64, 0x0e, 0x02, 0x02, 0x68, 0x0e, 0x02, 0x02, 0x00, 0x28, 0x03, 0x03, 0x08, 0x28, 0x03, 0x03, 0x10, 0x28, 0x03, 0x03, 0x10, 0x05, 0x04, 0x03, 0x18, 0x05, 0x04, 0x03, + 0x90, 0x1c, 0x05, 0x04, 0xa0, 0x1c, 0x05, 0x04, 0x80, 0x0f, 0x07, 0x05, 0xc0, 0x07, 0x09, 0x06, 0x64, 0x08, 0x00, 0x02, 0x68, 0x08, 0x00, 0x02, 0x6c, 0x08, 0x00, 0x02, 0x70, 0x08, 0x00, 0x02, + 0xb8, 0x35, 0x01, 0x02, 0xbc, 0x35, 0x01, 0x02, 0xc0, 0x35, 0x01, 0x02, 0xc4, 0x35, 0x01, 0x02, 0xc8, 0x35, 0x01, 0x02, 0xcc, 0x35, 0x01, 0x02, 0xd0, 0x35, 0x01, 0x02, 0x6c, 0x0e, 0x02, 0x02, + 0x70, 0x0e, 0x02, 0x02, 0x74, 0x0e, 0x02, 0x02, 0x78, 0x0e, 0x02, 0x02, 0x18, 0x28, 0x03, 0x03, 0x20, 0x28, 0x03, 0x03, 0x28, 0x28, 0x03, 0x03, 0x20, 0x05, 0x04, 0x03, 0x28, 0x05, 0x04, 0x03, + 0xb0, 0x1c, 0x05, 0x04, 0xc0, 0x1c, 0x05, 0x04, 0xa0, 0x0f, 0x07, 0x05, 0x00, 0x08, 0x09, 0x06, 0x74, 0x08, 0x00, 0x02, 0x78, 0x08, 0x00, 0x02, 0x7c, 0x08, 0x00, 0x02, 0x80, 0x08, 0x00, 0x02, + 0xd4, 0x35, 0x01, 0x02, 0xd8, 0x35, 0x01, 0x02, 0xdc, 0x35, 0x01, 0x02, 0xe0, 0x35, 0x01, 0x02, 0xe4, 0x35, 0x01, 0x02, 0xe8, 0x35, 0x01, 0x02, 0xec, 0x35, 0x01, 0x02, 0x7c, 0x0e, 0x02, 0x02, + 0x80, 0x0e, 0x02, 0x02, 0x84, 0x0e, 0x02, 0x02, 0x88, 0x0e, 0x02, 0x02, 0x30, 0x28, 0x03, 0x03, 0x38, 0x28, 0x03, 0x03, 0x40, 0x28, 0x03, 0x03, 0x30, 0x05, 0x04, 0x03, 0x38, 0x05, 0x04, 0x03, + 0xd0, 0x1c, 0x05, 0x04, 0xe0, 0x1c, 0x05, 0x04, 0xc0, 0x0f, 0x07, 0x05, 0x40, 0x08, 0x09, 0x06, 0x84, 0x08, 0x00, 0x02, 0x88, 0x08, 0x00, 0x02, 0x8c, 0x08, 0x00, 0x02, 0x90, 0x08, 0x00, 0x02, + 0xf0, 0x35, 0x01, 0x02, 0xf4, 0x35, 0x01, 0x02, 0xf8, 0x35, 0x01, 0x02, 0xfc, 0x35, 0x01, 0x02, 0x00, 0x36, 0x01, 0x02, 0x04, 0x36, 0x01, 0x02, 0x08, 0x36, 0x01, 0x02, 0x8c, 0x0e, 0x02, 0x02, + 0x90, 0x0e, 0x02, 0x02, 0x94, 0x0e, 0x02, 0x02, 0x98, 0x0e, 0x02, 0x02, 0x48, 0x28, 0x03, 0x03, 0x50, 0x28, 0x03, 0x03, 0x58, 0x28, 0x03, 0x03, 0x40, 0x05, 0x04, 0x03, 0x48, 0x05, 0x04, 0x03, + 0xf0, 0x1c, 0x05, 0x04, 0x00, 0x1d, 0x05, 0x04, 0xe0, 0x0f, 0x07, 0x05, 0x80, 0x08, 0x09, 0x06, 0x94, 0x08, 0x00, 0x02, 0x98, 0x08, 0x00, 0x02, 0x9c, 0x08, 0x00, 0x02, 0xa0, 0x08, 0x00, 0x02, + 0x0c, 0x36, 0x01, 0x02, 0x10, 0x36, 0x01, 0x02, 0x14, 0x36, 0x01, 0x02, 0x18, 0x36, 0x01, 0x02, 0x1c, 0x36, 0x01, 0x02, 0x20, 0x36, 0x01, 0x02, 0x24, 0x36, 0x01, 0x02, 0x9c, 0x0e, 0x02, 0x02, + 0xa0, 0x0e, 0x02, 0x02, 0xa4, 0x0e, 0x02, 0x02, 0xa8, 0x0e, 0x02, 0x02, 0x60, 0x28, 0x03, 0x03, 0x68, 0x28, 0x03, 0x03, 0x70, 0x28, 0x03, 0x03, 0x50, 0x05, 0x04, 0x03, 0x58, 0x05, 0x04, 0x03, + 0x10, 0x1d, 0x05, 0x04, 0x20, 0x1d, 0x05, 0x04, 0x00, 0x10, 0x07, 0x05, 0xc0, 0x08, 0x09, 0x06, 0xa4, 0x08, 0x00, 0x02, 0xa8, 0x08, 0x00, 0x02, 0xac, 0x08, 0x00, 0x02, 0xb0, 0x08, 0x00, 0x02, + 0x28, 0x36, 0x01, 0x02, 0x2c, 0x36, 0x01, 0x02, 0x30, 0x36, 0x01, 0x02, 0x34, 0x36, 0x01, 0x02, 0x38, 0x36, 0x01, 0x02, 0x3c, 0x36, 0x01, 0x02, 0x40, 0x36, 0x01, 0x02, 0xac, 0x0e, 0x02, 0x02, + 0xb0, 0x0e, 0x02, 0x02, 0xb4, 0x0e, 0x02, 0x02, 0xb8, 0x0e, 0x02, 0x02, 0x78, 0x28, 0x03, 0x03, 0x80, 0x28, 0x03, 0x03, 0x88, 0x28, 0x03, 0x03, 0x60, 0x05, 0x04, 0x03, 0x68, 0x05, 0x04, 0x03, + 0x30, 0x1d, 0x05, 0x04, 0x40, 0x1d, 0x05, 0x04, 0x20, 0x10, 0x07, 0x05, 0x00, 0x09, 0x09, 0x06, 0xb4, 0x08, 0x00, 0x02, 0xb8, 0x08, 0x00, 0x02, 0xbc, 0x08, 0x00, 0x02, 0xc0, 0x08, 0x00, 0x02, + 0x44, 0x36, 0x01, 0x02, 0x48, 0x36, 0x01, 0x02, 0x4c, 0x36, 0x01, 0x02, 0x50, 0x36, 0x01, 0x02, 0x54, 0x36, 0x01, 0x02, 0x58, 0x36, 0x01, 0x02, 0x5c, 0x36, 0x01, 0x02, 0xbc, 0x0e, 0x02, 0x02, + 0xc0, 0x0e, 0x02, 0x02, 0xc4, 0x0e, 0x02, 0x02, 0xc8, 0x0e, 0x02, 0x02, 0x90, 0x28, 0x03, 0x03, 0x98, 0x28, 0x03, 0x03, 0xa0, 0x28, 0x03, 0x03, 0x70, 0x05, 0x04, 0x03, 0x78, 0x05, 0x04, 0x03, + 0x50, 0x1d, 0x05, 0x04, 0x20, 0x3a, 0x06, 0x05, 0x40, 0x10, 0x07, 0x05, 0x40, 0x09, 0x09, 0x06, 0xc4, 0x08, 0x00, 0x02, 0xc8, 0x08, 0x00, 0x02, 0xcc, 0x08, 0x00, 0x02, 0xd0, 0x08, 0x00, 0x02, + 0x60, 0x36, 0x01, 0x02, 0x64, 0x36, 0x01, 0x02, 0x68, 0x36, 0x01, 0x02, 0x6c, 0x36, 0x01, 0x02, 0x70, 0x36, 0x01, 0x02, 0x74, 0x36, 0x01, 0x02, 0x78, 0x36, 0x01, 0x02, 0xcc, 0x0e, 0x02, 0x02, + 0xd0, 0x0e, 0x02, 0x02, 0xd4, 0x0e, 0x02, 0x02, 0xd8, 0x0e, 0x02, 0x02, 0xa8, 0x28, 0x03, 0x03, 0xb0, 0x28, 0x03, 0x03, 0xb8, 0x28, 0x03, 0x03, 0x80, 0x05, 0x04, 0x03, 0x88, 0x05, 0x04, 0x03, + 0x60, 0x1d, 0x05, 0x04, 0x40, 0x3a, 0x06, 0x05, 0x60, 0x10, 0x07, 0x05, 0x80, 0x09, 0x09, 0x06, 0xd4, 0x08, 0x00, 0x02, 0xd8, 0x08, 0x00, 0x02, 0xdc, 0x08, 0x00, 0x02, 0xe0, 0x08, 0x00, 0x02, + 0x7c, 0x36, 0x01, 0x02, 0x80, 0x36, 0x01, 0x02, 0x84, 0x36, 0x01, 0x02, 0x88, 0x36, 0x01, 0x02, 0x8c, 0x36, 0x01, 0x02, 0x90, 0x36, 0x01, 0x02, 0x94, 0x36, 0x01, 0x02, 0xdc, 0x0e, 0x02, 0x02, + 0xe0, 0x0e, 0x02, 0x02, 0xe4, 0x0e, 0x02, 0x02, 0xe8, 0x0e, 0x02, 0x02, 0xc0, 0x28, 0x03, 0x03, 0xc8, 0x28, 0x03, 0x03, 0xd0, 0x28, 0x03, 0x03, 0x90, 0x05, 0x04, 0x03, 0x98, 0x05, 0x04, 0x03, + 0x70, 0x1d, 0x05, 0x04, 0x60, 0x3a, 0x06, 0x05, 0x80, 0x10, 0x07, 0x05, 0xc0, 0x09, 0x09, 0x06, 0xe4, 0x08, 0x00, 0x02, 0xe8, 0x08, 0x00, 0x02, 0xec, 0x08, 0x00, 0x02, 0xf0, 0x08, 0x00, 0x02, + 0x98, 0x36, 0x01, 0x02, 0x9c, 0x36, 0x01, 0x02, 0xa0, 0x36, 0x01, 0x02, 0xa4, 0x36, 0x01, 0x02, 0xa8, 0x36, 0x01, 0x02, 0xac, 0x36, 0x01, 0x02, 0xb0, 0x36, 0x01, 0x02, 0xec, 0x0e, 0x02, 0x02, + 0xf0, 0x0e, 0x02, 0x02, 0xf4, 0x0e, 0x02, 0x02, 0xf8, 0x0e, 0x02, 0x02, 0xd8, 0x28, 0x03, 0x03, 0xe0, 0x28, 0x03, 0x03, 0xe8, 0x28, 0x03, 0x03, 0xa0, 0x05, 0x04, 0x03, 0xa8, 0x05, 0x04, 0x03, + 0x80, 0x1d, 0x05, 0x04, 0x80, 0x3a, 0x06, 0x05, 0xa0, 0x10, 0x07, 0x05, 0x00, 0x0a, 0x09, 0x06, 0xf4, 0x08, 0x00, 0x02, 0xf8, 0x08, 0x00, 0x02, 0xfc, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x02, + 0xb4, 0x36, 0x01, 0x02, 0xb8, 0x36, 0x01, 0x02, 0xbc, 0x36, 0x01, 0x02, 0xc0, 0x36, 0x01, 0x02, 0xc4, 0x36, 0x01, 0x02, 0xc8, 0x36, 0x01, 0x02, 0xcc, 0x36, 0x01, 0x02, 0xfc, 0x0e, 0x02, 0x02, + 0x00, 0x0f, 0x02, 0x02, 0x04, 0x0f, 0x02, 0x02, 0x08, 0x0f, 0x02, 0x02, 0xf0, 0x28, 0x03, 0x03, 0xf8, 0x28, 0x03, 0x03, 0x00, 0x29, 0x03, 0x03, 0xb0, 0x05, 0x04, 0x03, 0xb8, 0x05, 0x04, 0x03, + 0x90, 0x1d, 0x05, 0x04, 0xa0, 0x3a, 0x06, 0x05, 0xc0, 0x10, 0x07, 0x05, 0x40, 0x0a, 0x09, 0x06, 0x04, 0x09, 0x00, 0x02, 0x08, 0x09, 0x00, 0x02, 0x0c, 0x09, 0x00, 0x02, 0x10, 0x09, 0x00, 0x02, + 0xd0, 0x36, 0x01, 0x02, 0xd4, 0x36, 0x01, 0x02, 0xd8, 0x36, 0x01, 0x02, 0xdc, 0x36, 0x01, 0x02, 0xe0, 0x36, 0x01, 0x02, 0xe4, 0x36, 0x01, 0x02, 0xe8, 0x36, 0x01, 0x02, 0x0c, 0x0f, 0x02, 0x02, + 0x10, 0x0f, 0x02, 0x02, 0x14, 0x0f, 0x02, 0x02, 0x18, 0x0f, 0x02, 0x02, 0x08, 0x29, 0x03, 0x03, 0x10, 0x29, 0x03, 0x03, 0x18, 0x29, 0x03, 0x03, 0xc0, 0x05, 0x04, 0x03, 0xc8, 0x05, 0x04, 0x03, + 0xa0, 0x1d, 0x05, 0x04, 0xc0, 0x3a, 0x06, 0x05, 0xe0, 0x10, 0x07, 0x05, 0x80, 0x0a, 0x09, 0x06, 0x14, 0x09, 0x00, 0x02, 0x18, 0x09, 0x00, 0x02, 0x1c, 0x09, 0x00, 0x02, 0x20, 0x09, 0x00, 0x02, + 0xec, 0x36, 0x01, 0x02, 0xf0, 0x36, 0x01, 0x02, 0xf4, 0x36, 0x01, 0x02, 0xf8, 0x36, 0x01, 0x02, 0xfc, 0x36, 0x01, 0x02, 0x00, 0x37, 0x01, 0x02, 0x04, 0x37, 0x01, 0x02, 0x1c, 0x0f, 0x02, 0x02, + 0x20, 0x0f, 0x02, 0x02, 0x24, 0x0f, 0x02, 0x02, 0x28, 0x0f, 0x02, 0x02, 0x20, 0x29, 0x03, 0x03, 0x28, 0x29, 0x03, 0x03, 0x30, 0x29, 0x03, 0x03, 0xd0, 0x05, 0x04, 0x03, 0xd8, 0x05, 0x04, 0x03, + 0xb0, 0x1d, 0x05, 0x04, 0xe0, 0x3a, 0x06, 0x05, 0x00, 0x11, 0x07, 0x05, 0x80, 0x1c, 0x0a, 0x07, 0x24, 0x09, 0x00, 0x02, 0x28, 0x09, 0x00, 0x02, 0x2c, 0x09, 0x00, 0x02, 0x30, 0x09, 0x00, 0x02, + 0x08, 0x37, 0x01, 0x02, 0x0c, 0x37, 0x01, 0x02, 0x10, 0x37, 0x01, 0x02, 0x14, 0x37, 0x01, 0x02, 0x18, 0x37, 0x01, 0x02, 0x1c, 0x37, 0x01, 0x02, 0x20, 0x37, 0x01, 0x02, 0x2c, 0x0f, 0x02, 0x02, + 0x30, 0x0f, 0x02, 0x02, 0x34, 0x0f, 0x02, 0x02, 0x38, 0x0f, 0x02, 0x02, 0x38, 0x29, 0x03, 0x03, 0x40, 0x29, 0x03, 0x03, 0x48, 0x29, 0x03, 0x03, 0xe0, 0x05, 0x04, 0x03, 0xe8, 0x05, 0x04, 0x03, + 0xc0, 0x1d, 0x05, 0x04, 0x00, 0x3b, 0x06, 0x05, 0x20, 0x11, 0x07, 0x05, 0x00, 0x1d, 0x0a, 0x07, 0x34, 0x09, 0x00, 0x02, 0x38, 0x09, 0x00, 0x02, 0x3c, 0x09, 0x00, 0x02, 0x40, 0x09, 0x00, 0x02, + 0x24, 0x37, 0x01, 0x02, 0x28, 0x37, 0x01, 0x02, 0x2c, 0x37, 0x01, 0x02, 0x30, 0x37, 0x01, 0x02, 0x34, 0x37, 0x01, 0x02, 0x38, 0x37, 0x01, 0x02, 0x3c, 0x37, 0x01, 0x02, 0x3c, 0x0f, 0x02, 0x02, + 0x40, 0x0f, 0x02, 0x02, 0x44, 0x0f, 0x02, 0x02, 0x48, 0x0f, 0x02, 0x02, 0x50, 0x29, 0x03, 0x03, 0x58, 0x29, 0x03, 0x03, 0x60, 0x29, 0x03, 0x03, 0xf0, 0x05, 0x04, 0x03, 0xf8, 0x05, 0x04, 0x03, + 0xd0, 0x1d, 0x05, 0x04, 0x20, 0x3b, 0x06, 0x05, 0x40, 0x11, 0x07, 0x05, 0x80, 0x1d, 0x0a, 0x07, 0x44, 0x09, 0x00, 0x02, 0x48, 0x09, 0x00, 0x02, 0x4c, 0x09, 0x00, 0x02, 0x50, 0x09, 0x00, 0x02, + 0x40, 0x37, 0x01, 0x02, 0x44, 0x37, 0x01, 0x02, 0x48, 0x37, 0x01, 0x02, 0x4c, 0x37, 0x01, 0x02, 0x50, 0x37, 0x01, 0x02, 0x54, 0x37, 0x01, 0x02, 0x58, 0x37, 0x01, 0x02, 0x4c, 0x0f, 0x02, 0x02, + 0x50, 0x0f, 0x02, 0x02, 0x54, 0x0f, 0x02, 0x02, 0x58, 0x0f, 0x02, 0x02, 0x68, 0x29, 0x03, 0x03, 0x70, 0x29, 0x03, 0x03, 0x78, 0x29, 0x03, 0x03, 0x00, 0x06, 0x04, 0x03, 0x08, 0x06, 0x04, 0x03, + 0xe0, 0x1d, 0x05, 0x04, 0x40, 0x3b, 0x06, 0x05, 0x60, 0x11, 0x07, 0x05, 0x00, 0x1e, 0x0a, 0x07, 0x54, 0x09, 0x00, 0x02, 0x58, 0x09, 0x00, 0x02, 0x5c, 0x09, 0x00, 0x02, 0x60, 0x09, 0x00, 0x02, + 0x5c, 0x37, 0x01, 0x02, 0x60, 0x37, 0x01, 0x02, 0x64, 0x37, 0x01, 0x02, 0x68, 0x37, 0x01, 0x02, 0x6c, 0x37, 0x01, 0x02, 0x70, 0x37, 0x01, 0x02, 0x74, 0x37, 0x01, 0x02, 0x5c, 0x0f, 0x02, 0x02, + 0x60, 0x0f, 0x02, 0x02, 0x64, 0x0f, 0x02, 0x02, 0x68, 0x0f, 0x02, 0x02, 0x80, 0x29, 0x03, 0x03, 0x88, 0x29, 0x03, 0x03, 0x90, 0x29, 0x03, 0x03, 0x10, 0x06, 0x04, 0x03, 0x18, 0x06, 0x04, 0x03, + 0xf0, 0x1d, 0x05, 0x04, 0x60, 0x3b, 0x06, 0x05, 0x80, 0x11, 0x07, 0x05, 0x80, 0x1e, 0x0a, 0x07, 0x64, 0x09, 0x00, 0x02, 0x68, 0x09, 0x00, 0x02, 0x6c, 0x09, 0x00, 0x02, 0x70, 0x09, 0x00, 0x02, + 0x78, 0x37, 0x01, 0x02, 0x7c, 0x37, 0x01, 0x02, 0x80, 0x37, 0x01, 0x02, 0x84, 0x37, 0x01, 0x02, 0x88, 0x37, 0x01, 0x02, 0x8c, 0x37, 0x01, 0x02, 0x90, 0x37, 0x01, 0x02, 0x6c, 0x0f, 0x02, 0x02, + 0x70, 0x0f, 0x02, 0x02, 0x74, 0x0f, 0x02, 0x02, 0x78, 0x0f, 0x02, 0x02, 0x98, 0x29, 0x03, 0x03, 0xa0, 0x29, 0x03, 0x03, 0xa8, 0x29, 0x03, 0x03, 0x20, 0x06, 0x04, 0x03, 0x28, 0x06, 0x04, 0x03, + 0x00, 0x1e, 0x05, 0x04, 0x80, 0x3b, 0x06, 0x05, 0xa0, 0x11, 0x07, 0x05, 0x00, 0x1f, 0x0a, 0x07, 0x74, 0x09, 0x00, 0x02, 0x78, 0x09, 0x00, 0x02, 0x7c, 0x09, 0x00, 0x02, 0x80, 0x09, 0x00, 0x02, + 0x94, 0x37, 0x01, 0x02, 0x98, 0x37, 0x01, 0x02, 0x9c, 0x37, 0x01, 0x02, 0xa0, 0x37, 0x01, 0x02, 0xa4, 0x37, 0x01, 0x02, 0xa8, 0x37, 0x01, 0x02, 0xac, 0x37, 0x01, 0x02, 0x7c, 0x0f, 0x02, 0x02, + 0x80, 0x0f, 0x02, 0x02, 0x84, 0x0f, 0x02, 0x02, 0x88, 0x0f, 0x02, 0x02, 0xb0, 0x29, 0x03, 0x03, 0xb8, 0x29, 0x03, 0x03, 0xc0, 0x29, 0x03, 0x03, 0x30, 0x06, 0x04, 0x03, 0x38, 0x06, 0x04, 0x03, + 0x10, 0x1e, 0x05, 0x04, 0xa0, 0x3b, 0x06, 0x05, 0xc0, 0x11, 0x07, 0x05, 0x80, 0x1f, 0x0a, 0x07, 0x84, 0x09, 0x00, 0x02, 0x88, 0x09, 0x00, 0x02, 0x8c, 0x09, 0x00, 0x02, 0x90, 0x09, 0x00, 0x02, + 0xb0, 0x37, 0x01, 0x02, 0xb4, 0x37, 0x01, 0x02, 0xb8, 0x37, 0x01, 0x02, 0xbc, 0x37, 0x01, 0x02, 0xc0, 0x37, 0x01, 0x02, 0xc4, 0x37, 0x01, 0x02, 0xc8, 0x37, 0x01, 0x02, 0x8c, 0x0f, 0x02, 0x02, + 0x90, 0x0f, 0x02, 0x02, 0x94, 0x0f, 0x02, 0x02, 0x98, 0x0f, 0x02, 0x02, 0xc8, 0x29, 0x03, 0x03, 0xd0, 0x29, 0x03, 0x03, 0xd8, 0x29, 0x03, 0x03, 0x40, 0x06, 0x04, 0x03, 0x48, 0x06, 0x04, 0x03, + 0x20, 0x1e, 0x05, 0x04, 0xc0, 0x3b, 0x06, 0x05, 0xe0, 0x11, 0x07, 0x05, 0x00, 0x20, 0x0a, 0x07, 0x94, 0x09, 0x00, 0x02, 0x98, 0x09, 0x00, 0x02, 0x9c, 0x09, 0x00, 0x02, 0xa0, 0x09, 0x00, 0x02, + 0xcc, 0x37, 0x01, 0x02, 0xd0, 0x37, 0x01, 0x02, 0xd4, 0x37, 0x01, 0x02, 0xd8, 0x37, 0x01, 0x02, 0xdc, 0x37, 0x01, 0x02, 0xe0, 0x37, 0x01, 0x02, 0xe4, 0x37, 0x01, 0x02, 0x9c, 0x0f, 0x02, 0x02, + 0xa0, 0x0f, 0x02, 0x02, 0xa4, 0x0f, 0x02, 0x02, 0xa8, 0x0f, 0x02, 0x02, 0xe0, 0x29, 0x03, 0x03, 0xe8, 0x29, 0x03, 0x03, 0xf0, 0x29, 0x03, 0x03, 0x50, 0x06, 0x04, 0x03, 0x58, 0x06, 0x04, 0x03, + 0x30, 0x1e, 0x05, 0x04, 0xe0, 0x3b, 0x06, 0x05, 0x00, 0x12, 0x07, 0x05, 0x80, 0x20, 0x0a, 0x07, 0xa4, 0x09, 0x00, 0x02, 0xa8, 0x09, 0x00, 0x02, 0xac, 0x09, 0x00, 0x02, 0xb0, 0x09, 0x00, 0x02, + 0xe8, 0x37, 0x01, 0x02, 0xec, 0x37, 0x01, 0x02, 0xf0, 0x37, 0x01, 0x02, 0xf4, 0x37, 0x01, 0x02, 0xf8, 0x37, 0x01, 0x02, 0xfc, 0x37, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0xac, 0x0f, 0x02, 0x02, + 0xb0, 0x0f, 0x02, 0x02, 0xb4, 0x0f, 0x02, 0x02, 0xb8, 0x0f, 0x02, 0x02, 0xf8, 0x29, 0x03, 0x03, 0x00, 0x2a, 0x03, 0x03, 0x08, 0x2a, 0x03, 0x03, 0x60, 0x06, 0x04, 0x03, 0x68, 0x06, 0x04, 0x03, + 0x40, 0x1e, 0x05, 0x04, 0x00, 0x3c, 0x06, 0x05, 0x20, 0x12, 0x07, 0x05, 0x00, 0x21, 0x0a, 0x07, 0xb4, 0x09, 0x00, 0x02, 0xb8, 0x09, 0x00, 0x02, 0xbc, 0x09, 0x00, 0x02, 0xc0, 0x09, 0x00, 0x02, + 0x04, 0x38, 0x01, 0x02, 0x08, 0x38, 0x01, 0x02, 0x0c, 0x38, 0x01, 0x02, 0x10, 0x38, 0x01, 0x02, 0x14, 0x38, 0x01, 0x02, 0x18, 0x38, 0x01, 0x02, 0x1c, 0x38, 0x01, 0x02, 0xbc, 0x0f, 0x02, 0x02, + 0xc0, 0x0f, 0x02, 0x02, 0xc4, 0x0f, 0x02, 0x02, 0xc8, 0x0f, 0x02, 0x02, 0x10, 0x2a, 0x03, 0x03, 0x18, 0x2a, 0x03, 0x03, 0x20, 0x2a, 0x03, 0x03, 0x70, 0x06, 0x04, 0x03, 0x78, 0x06, 0x04, 0x03, + 0x50, 0x1e, 0x05, 0x04, 0x20, 0x3c, 0x06, 0x05, 0x40, 0x12, 0x07, 0x05, 0x80, 0x21, 0x0a, 0x07, 0xc4, 0x09, 0x00, 0x02, 0xc8, 0x09, 0x00, 0x02, 0xcc, 0x09, 0x00, 0x02, 0xd0, 0x09, 0x00, 0x02, + 0x20, 0x38, 0x01, 0x02, 0x24, 0x38, 0x01, 0x02, 0x28, 0x38, 0x01, 0x02, 0x2c, 0x38, 0x01, 0x02, 0x30, 0x38, 0x01, 0x02, 0x34, 0x38, 0x01, 0x02, 0x38, 0x38, 0x01, 0x02, 0xcc, 0x0f, 0x02, 0x02, + 0xd0, 0x0f, 0x02, 0x02, 0xd4, 0x0f, 0x02, 0x02, 0xd8, 0x0f, 0x02, 0x02, 0x28, 0x2a, 0x03, 0x03, 0x30, 0x2a, 0x03, 0x03, 0x38, 0x2a, 0x03, 0x03, 0x80, 0x06, 0x04, 0x03, 0x88, 0x06, 0x04, 0x03, + 0x60, 0x1e, 0x05, 0x04, 0x40, 0x3c, 0x06, 0x05, 0x60, 0x12, 0x07, 0x05, 0x00, 0x22, 0x0a, 0x07, 0xd4, 0x09, 0x00, 0x02, 0xd8, 0x09, 0x00, 0x02, 0xdc, 0x09, 0x00, 0x02, 0xe0, 0x09, 0x00, 0x02, + 0x3c, 0x38, 0x01, 0x02, 0x40, 0x38, 0x01, 0x02, 0x44, 0x38, 0x01, 0x02, 0x48, 0x38, 0x01, 0x02, 0x4c, 0x38, 0x01, 0x02, 0x50, 0x38, 0x01, 0x02, 0x54, 0x38, 0x01, 0x02, 0xdc, 0x0f, 0x02, 0x02, + 0xe0, 0x0f, 0x02, 0x02, 0xe4, 0x0f, 0x02, 0x02, 0xe8, 0x0f, 0x02, 0x02, 0x40, 0x2a, 0x03, 0x03, 0x48, 0x2a, 0x03, 0x03, 0x50, 0x2a, 0x03, 0x03, 0x90, 0x06, 0x04, 0x03, 0x98, 0x06, 0x04, 0x03, + 0x70, 0x1e, 0x05, 0x04, 0x60, 0x3c, 0x06, 0x05, 0x80, 0x12, 0x07, 0x05, 0x80, 0x22, 0x0a, 0x07, 0xe4, 0x09, 0x00, 0x02, 0xe8, 0x09, 0x00, 0x02, 0xec, 0x09, 0x00, 0x02, 0xf0, 0x09, 0x00, 0x02, + 0x58, 0x38, 0x01, 0x02, 0x5c, 0x38, 0x01, 0x02, 0x60, 0x38, 0x01, 0x02, 0x64, 0x38, 0x01, 0x02, 0x68, 0x38, 0x01, 0x02, 0x6c, 0x38, 0x01, 0x02, 0x70, 0x38, 0x01, 0x02, 0xec, 0x0f, 0x02, 0x02, + 0xf0, 0x0f, 0x02, 0x02, 0xf4, 0x0f, 0x02, 0x02, 0xf8, 0x0f, 0x02, 0x02, 0x58, 0x2a, 0x03, 0x03, 0x60, 0x2a, 0x03, 0x03, 0x68, 0x2a, 0x03, 0x03, 0xa0, 0x06, 0x04, 0x03, 0xa8, 0x06, 0x04, 0x03, + 0x80, 0x1e, 0x05, 0x04, 0x80, 0x3c, 0x06, 0x05, 0xa0, 0x12, 0x07, 0x05, 0x00, 0x23, 0x0a, 0x07, 0xf4, 0x09, 0x00, 0x02, 0xf8, 0x09, 0x00, 0x02, 0xfc, 0x09, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, + 0x74, 0x38, 0x01, 0x02, 0x78, 0x38, 0x01, 0x02, 0x7c, 0x38, 0x01, 0x02, 0x80, 0x38, 0x01, 0x02, 0x84, 0x38, 0x01, 0x02, 0x88, 0x38, 0x01, 0x02, 0x8c, 0x38, 0x01, 0x02, 0xfc, 0x0f, 0x02, 0x02, + 0x00, 0x10, 0x02, 0x02, 0x04, 0x10, 0x02, 0x02, 0x08, 0x10, 0x02, 0x02, 0x70, 0x2a, 0x03, 0x03, 0x78, 0x2a, 0x03, 0x03, 0x80, 0x2a, 0x03, 0x03, 0xb0, 0x06, 0x04, 0x03, 0xb8, 0x06, 0x04, 0x03, + 0x90, 0x1e, 0x05, 0x04, 0xa0, 0x3c, 0x06, 0x05, 0xc0, 0x12, 0x07, 0x05, 0x80, 0x23, 0x0a, 0x07, 0x04, 0x0a, 0x00, 0x02, 0x08, 0x0a, 0x00, 0x02, 0x0c, 0x0a, 0x00, 0x02, 0x10, 0x0a, 0x00, 0x02, + 0x90, 0x38, 0x01, 0x02, 0x94, 0x38, 0x01, 0x02, 0x98, 0x38, 0x01, 0x02, 0x9c, 0x38, 0x01, 0x02, 0xa0, 0x38, 0x01, 0x02, 0xa4, 0x38, 0x01, 0x02, 0xa8, 0x38, 0x01, 0x02, 0x0c, 0x10, 0x02, 0x02, + 0x10, 0x10, 0x02, 0x02, 0x14, 0x10, 0x02, 0x02, 0x18, 0x10, 0x02, 0x02, 0x88, 0x2a, 0x03, 0x03, 0x90, 0x2a, 0x03, 0x03, 0x98, 0x2a, 0x03, 0x03, 0xc0, 0x06, 0x04, 0x03, 0xc8, 0x06, 0x04, 0x03, + 0xa0, 0x1e, 0x05, 0x04, 0xc0, 0x3c, 0x06, 0x05, 0xe0, 0x12, 0x07, 0x05, 0x00, 0x3b, 0x0b, 0x08, 0x14, 0x0a, 0x00, 0x02, 0x18, 0x0a, 0x00, 0x02, 0x1c, 0x0a, 0x00, 0x02, 0x20, 0x0a, 0x00, 0x02, + 0xac, 0x38, 0x01, 0x02, 0xb0, 0x38, 0x01, 0x02, 0xb4, 0x38, 0x01, 0x02, 0xb8, 0x38, 0x01, 0x02, 0xbc, 0x38, 0x01, 0x02, 0xc0, 0x38, 0x01, 0x02, 0xc4, 0x38, 0x01, 0x02, 0x1c, 0x10, 0x02, 0x02, + 0x20, 0x10, 0x02, 0x02, 0x24, 0x10, 0x02, 0x02, 0x28, 0x10, 0x02, 0x02, 0xa0, 0x2a, 0x03, 0x03, 0xa8, 0x2a, 0x03, 0x03, 0xb0, 0x2a, 0x03, 0x03, 0xd0, 0x06, 0x04, 0x03, 0xd8, 0x06, 0x04, 0x03, + 0xb0, 0x1e, 0x05, 0x04, 0xe0, 0x3c, 0x06, 0x05, 0x00, 0x13, 0x07, 0x05, 0x00, 0x3c, 0x0b, 0x08, 0x24, 0x0a, 0x00, 0x02, 0x28, 0x0a, 0x00, 0x02, 0x2c, 0x0a, 0x00, 0x02, 0x30, 0x0a, 0x00, 0x02, + 0xc8, 0x38, 0x01, 0x02, 0xcc, 0x38, 0x01, 0x02, 0xd0, 0x38, 0x01, 0x02, 0xd4, 0x38, 0x01, 0x02, 0xd8, 0x38, 0x01, 0x02, 0xdc, 0x38, 0x01, 0x02, 0xe0, 0x38, 0x01, 0x02, 0x2c, 0x10, 0x02, 0x02, + 0x30, 0x10, 0x02, 0x02, 0x34, 0x10, 0x02, 0x02, 0x38, 0x10, 0x02, 0x02, 0xb8, 0x2a, 0x03, 0x03, 0xc0, 0x2a, 0x03, 0x03, 0xc8, 0x2a, 0x03, 0x03, 0xe0, 0x06, 0x04, 0x03, 0xe8, 0x06, 0x04, 0x03, + 0xc0, 0x1e, 0x05, 0x04, 0x00, 0x3d, 0x06, 0x05, 0x20, 0x13, 0x07, 0x05, 0x00, 0x3d, 0x0b, 0x08, 0x34, 0x0a, 0x00, 0x02, 0x38, 0x0a, 0x00, 0x02, 0x3c, 0x0a, 0x00, 0x02, 0x40, 0x0a, 0x00, 0x02, + 0xe4, 0x38, 0x01, 0x02, 0xe8, 0x38, 0x01, 0x02, 0xec, 0x38, 0x01, 0x02, 0xf0, 0x38, 0x01, 0x02, 0xf4, 0x38, 0x01, 0x02, 0xf8, 0x38, 0x01, 0x02, 0xfc, 0x38, 0x01, 0x02, 0x3c, 0x10, 0x02, 0x02, + 0x40, 0x10, 0x02, 0x02, 0x44, 0x10, 0x02, 0x02, 0x48, 0x10, 0x02, 0x02, 0xd0, 0x2a, 0x03, 0x03, 0xd8, 0x2a, 0x03, 0x03, 0xe0, 0x2a, 0x03, 0x03, 0xf0, 0x06, 0x04, 0x03, 0xf8, 0x06, 0x04, 0x03, + 0xd0, 0x1e, 0x05, 0x04, 0x20, 0x3d, 0x06, 0x05, 0x40, 0x13, 0x07, 0x05, 0x00, 0x3e, 0x0b, 0x08, 0x44, 0x0a, 0x00, 0x02, 0x48, 0x0a, 0x00, 0x02, 0x4c, 0x0a, 0x00, 0x02, 0x50, 0x0a, 0x00, 0x02, + 0x00, 0x39, 0x01, 0x02, 0x04, 0x39, 0x01, 0x02, 0x08, 0x39, 0x01, 0x02, 0x0c, 0x39, 0x01, 0x02, 0x10, 0x39, 0x01, 0x02, 0x14, 0x39, 0x01, 0x02, 0x18, 0x39, 0x01, 0x02, 0x4c, 0x10, 0x02, 0x02, + 0x50, 0x10, 0x02, 0x02, 0x54, 0x10, 0x02, 0x02, 0x58, 0x10, 0x02, 0x02, 0xe8, 0x2a, 0x03, 0x03, 0xf0, 0x2a, 0x03, 0x03, 0xf8, 0x2a, 0x03, 0x03, 0x00, 0x07, 0x04, 0x03, 0x08, 0x07, 0x04, 0x03, + 0xe0, 0x1e, 0x05, 0x04, 0x40, 0x3d, 0x06, 0x05, 0x60, 0x13, 0x07, 0x05, 0x00, 0x3f, 0x0b, 0x08, 0x54, 0x0a, 0x00, 0x02, 0x58, 0x0a, 0x00, 0x02, 0x5c, 0x0a, 0x00, 0x02, 0x60, 0x0a, 0x00, 0x02, + 0x1c, 0x39, 0x01, 0x02, 0x20, 0x39, 0x01, 0x02, 0x24, 0x39, 0x01, 0x02, 0x28, 0x39, 0x01, 0x02, 0x2c, 0x39, 0x01, 0x02, 0x30, 0x39, 0x01, 0x02, 0x34, 0x39, 0x01, 0x02, 0x5c, 0x10, 0x02, 0x02, + 0x60, 0x10, 0x02, 0x02, 0x64, 0x10, 0x02, 0x02, 0x68, 0x10, 0x02, 0x02, 0x00, 0x2b, 0x03, 0x03, 0x08, 0x2b, 0x03, 0x03, 0x10, 0x2b, 0x03, 0x03, 0x10, 0x07, 0x04, 0x03, 0x18, 0x07, 0x04, 0x03, + 0xf0, 0x1e, 0x05, 0x04, 0x60, 0x3d, 0x06, 0x05, 0x80, 0x13, 0x07, 0x05, 0x00, 0x00, 0x0b, 0x07, 0x64, 0x0a, 0x00, 0x02, 0x68, 0x0a, 0x00, 0x02, 0x6c, 0x0a, 0x00, 0x02, 0x70, 0x0a, 0x00, 0x02, + 0x38, 0x39, 0x01, 0x02, 0x3c, 0x39, 0x01, 0x02, 0x40, 0x39, 0x01, 0x02, 0x44, 0x39, 0x01, 0x02, 0x48, 0x39, 0x01, 0x02, 0x4c, 0x39, 0x01, 0x02, 0x50, 0x39, 0x01, 0x02, 0x6c, 0x10, 0x02, 0x02, + 0x70, 0x10, 0x02, 0x02, 0x74, 0x10, 0x02, 0x02, 0x78, 0x10, 0x02, 0x02, 0x18, 0x2b, 0x03, 0x03, 0x20, 0x2b, 0x03, 0x03, 0x28, 0x2b, 0x03, 0x03, 0x20, 0x07, 0x04, 0x03, 0x28, 0x07, 0x04, 0x03, + 0x00, 0x1f, 0x05, 0x04, 0x80, 0x3d, 0x06, 0x05, 0xa0, 0x13, 0x07, 0x05, 0x80, 0x00, 0x0b, 0x07, 0x74, 0x0a, 0x00, 0x02, 0x78, 0x0a, 0x00, 0x02, 0x7c, 0x0a, 0x00, 0x02, 0x80, 0x0a, 0x00, 0x02, + 0x54, 0x39, 0x01, 0x02, 0x58, 0x39, 0x01, 0x02, 0x5c, 0x39, 0x01, 0x02, 0x60, 0x39, 0x01, 0x02, 0x64, 0x39, 0x01, 0x02, 0x68, 0x39, 0x01, 0x02, 0x6c, 0x39, 0x01, 0x02, 0x7c, 0x10, 0x02, 0x02, + 0x80, 0x10, 0x02, 0x02, 0x84, 0x10, 0x02, 0x02, 0x88, 0x10, 0x02, 0x02, 0x30, 0x2b, 0x03, 0x03, 0x38, 0x2b, 0x03, 0x03, 0x40, 0x2b, 0x03, 0x03, 0x30, 0x07, 0x04, 0x03, 0x38, 0x07, 0x04, 0x03, + 0x10, 0x1f, 0x05, 0x04, 0xa0, 0x3d, 0x06, 0x05, 0xc0, 0x13, 0x07, 0x05, 0x00, 0x01, 0x0b, 0x07, 0x84, 0x0a, 0x00, 0x02, 0x88, 0x0a, 0x00, 0x02, 0x8c, 0x0a, 0x00, 0x02, 0x90, 0x0a, 0x00, 0x02, + 0x70, 0x39, 0x01, 0x02, 0x74, 0x39, 0x01, 0x02, 0x78, 0x39, 0x01, 0x02, 0x7c, 0x39, 0x01, 0x02, 0x80, 0x39, 0x01, 0x02, 0x84, 0x39, 0x01, 0x02, 0x8c, 0x10, 0x02, 0x02, 0x90, 0x10, 0x02, 0x02, + 0x94, 0x10, 0x02, 0x02, 0x98, 0x10, 0x02, 0x02, 0x9c, 0x10, 0x02, 0x02, 0x48, 0x2b, 0x03, 0x03, 0x50, 0x2b, 0x03, 0x03, 0x58, 0x2b, 0x03, 0x03, 0x40, 0x07, 0x04, 0x03, 0x48, 0x07, 0x04, 0x03, + 0x20, 0x1f, 0x05, 0x04, 0xc0, 0x3d, 0x06, 0x05, 0xe0, 0x13, 0x07, 0x05, 0x80, 0x01, 0x0b, 0x07, 0x94, 0x0a, 0x00, 0x02, 0x98, 0x0a, 0x00, 0x02, 0x9c, 0x0a, 0x00, 0x02, 0xa0, 0x0a, 0x00, 0x02, + 0x88, 0x39, 0x01, 0x02, 0x8c, 0x39, 0x01, 0x02, 0x90, 0x39, 0x01, 0x02, 0x94, 0x39, 0x01, 0x02, 0x98, 0x39, 0x01, 0x02, 0x9c, 0x39, 0x01, 0x02, 0xa0, 0x10, 0x02, 0x02, 0xa4, 0x10, 0x02, 0x02, + 0xa8, 0x10, 0x02, 0x02, 0xac, 0x10, 0x02, 0x02, 0xb0, 0x10, 0x02, 0x02, 0x60, 0x2b, 0x03, 0x03, 0x68, 0x2b, 0x03, 0x03, 0x70, 0x2b, 0x03, 0x03, 0x50, 0x07, 0x04, 0x03, 0x58, 0x07, 0x04, 0x03, + 0x30, 0x1f, 0x05, 0x04, 0xe0, 0x3d, 0x06, 0x05, 0x00, 0x14, 0x07, 0x05, 0x00, 0x12, 0x0c, 0x08, 0xa4, 0x0a, 0x00, 0x02, 0xa8, 0x0a, 0x00, 0x02, 0xac, 0x0a, 0x00, 0x02, 0xb0, 0x0a, 0x00, 0x02, + 0xa0, 0x39, 0x01, 0x02, 0xa4, 0x39, 0x01, 0x02, 0xa8, 0x39, 0x01, 0x02, 0xac, 0x39, 0x01, 0x02, 0xb0, 0x39, 0x01, 0x02, 0xb4, 0x39, 0x01, 0x02, 0xb4, 0x10, 0x02, 0x02, 0xb8, 0x10, 0x02, 0x02, + 0xbc, 0x10, 0x02, 0x02, 0xc0, 0x10, 0x02, 0x02, 0xc4, 0x10, 0x02, 0x02, 0x78, 0x2b, 0x03, 0x03, 0x80, 0x2b, 0x03, 0x03, 0x88, 0x2b, 0x03, 0x03, 0x60, 0x07, 0x04, 0x03, 0x68, 0x07, 0x04, 0x03, + 0x40, 0x1f, 0x05, 0x04, 0x00, 0x3e, 0x06, 0x05, 0x20, 0x14, 0x07, 0x05, 0x00, 0x13, 0x0c, 0x08, 0xb4, 0x0a, 0x00, 0x02, 0xb8, 0x0a, 0x00, 0x02, 0xbc, 0x0a, 0x00, 0x02, 0xc0, 0x0a, 0x00, 0x02, + 0xb8, 0x39, 0x01, 0x02, 0xbc, 0x39, 0x01, 0x02, 0xc0, 0x39, 0x01, 0x02, 0xc4, 0x39, 0x01, 0x02, 0xc8, 0x39, 0x01, 0x02, 0xcc, 0x39, 0x01, 0x02, 0xc8, 0x10, 0x02, 0x02, 0xcc, 0x10, 0x02, 0x02, + 0xd0, 0x10, 0x02, 0x02, 0xd4, 0x10, 0x02, 0x02, 0xd8, 0x10, 0x02, 0x02, 0x90, 0x2b, 0x03, 0x03, 0x98, 0x2b, 0x03, 0x03, 0xa0, 0x2b, 0x03, 0x03, 0x70, 0x07, 0x04, 0x03, 0x78, 0x07, 0x04, 0x03, + 0x50, 0x1f, 0x05, 0x04, 0x20, 0x3e, 0x06, 0x05, 0x40, 0x14, 0x07, 0x05, 0x00, 0x14, 0x0c, 0x08, 0xc4, 0x0a, 0x00, 0x02, 0xc8, 0x0a, 0x00, 0x02, 0xcc, 0x0a, 0x00, 0x02, 0xd0, 0x0a, 0x00, 0x02, + 0xd0, 0x39, 0x01, 0x02, 0xd4, 0x39, 0x01, 0x02, 0xd8, 0x39, 0x01, 0x02, 0xdc, 0x39, 0x01, 0x02, 0xe0, 0x39, 0x01, 0x02, 0xe4, 0x39, 0x01, 0x02, 0xdc, 0x10, 0x02, 0x02, 0xe0, 0x10, 0x02, 0x02, + 0xe4, 0x10, 0x02, 0x02, 0xe8, 0x10, 0x02, 0x02, 0xec, 0x10, 0x02, 0x02, 0xa8, 0x2b, 0x03, 0x03, 0xb0, 0x2b, 0x03, 0x03, 0xb8, 0x2b, 0x03, 0x03, 0x80, 0x07, 0x04, 0x03, 0x88, 0x07, 0x04, 0x03, + 0x60, 0x1f, 0x05, 0x04, 0x40, 0x3e, 0x06, 0x05, 0x60, 0x14, 0x07, 0x05, 0x00, 0x15, 0x0c, 0x08, 0xd4, 0x0a, 0x00, 0x02, 0xd8, 0x0a, 0x00, 0x02, 0xdc, 0x0a, 0x00, 0x02, 0xe0, 0x0a, 0x00, 0x02, + 0xe8, 0x39, 0x01, 0x02, 0xec, 0x39, 0x01, 0x02, 0xf0, 0x39, 0x01, 0x02, 0xf4, 0x39, 0x01, 0x02, 0xf8, 0x39, 0x01, 0x02, 0xfc, 0x39, 0x01, 0x02, 0xf0, 0x10, 0x02, 0x02, 0xf4, 0x10, 0x02, 0x02, + 0xf8, 0x10, 0x02, 0x02, 0xfc, 0x10, 0x02, 0x02, 0x00, 0x11, 0x02, 0x02, 0xc0, 0x2b, 0x03, 0x03, 0xc8, 0x2b, 0x03, 0x03, 0xd0, 0x2b, 0x03, 0x03, 0x90, 0x07, 0x04, 0x03, 0x98, 0x07, 0x04, 0x03, + 0x70, 0x1f, 0x05, 0x04, 0x60, 0x3e, 0x06, 0x05, 0x80, 0x14, 0x07, 0x05, 0x00, 0x16, 0x0c, 0x08, 0xe4, 0x0a, 0x00, 0x02, 0xe8, 0x0a, 0x00, 0x02, 0xec, 0x0a, 0x00, 0x02, 0xf0, 0x0a, 0x00, 0x02, + 0x00, 0x3a, 0x01, 0x02, 0x04, 0x3a, 0x01, 0x02, 0x08, 0x3a, 0x01, 0x02, 0x0c, 0x3a, 0x01, 0x02, 0x10, 0x3a, 0x01, 0x02, 0x14, 0x3a, 0x01, 0x02, 0x04, 0x11, 0x02, 0x02, 0x08, 0x11, 0x02, 0x02, + 0x0c, 0x11, 0x02, 0x02, 0x10, 0x11, 0x02, 0x02, 0x14, 0x11, 0x02, 0x02, 0xd8, 0x2b, 0x03, 0x03, 0xe0, 0x2b, 0x03, 0x03, 0xe8, 0x2b, 0x03, 0x03, 0xa0, 0x07, 0x04, 0x03, 0xa8, 0x07, 0x04, 0x03, + 0x80, 0x1f, 0x05, 0x04, 0x80, 0x3e, 0x06, 0x05, 0xa0, 0x14, 0x07, 0x05, 0x00, 0x17, 0x0c, 0x08, 0xf4, 0x0a, 0x00, 0x02, 0xf8, 0x0a, 0x00, 0x02, 0xfc, 0x0a, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, + 0x18, 0x3a, 0x01, 0x02, 0x1c, 0x3a, 0x01, 0x02, 0x20, 0x3a, 0x01, 0x02, 0x24, 0x3a, 0x01, 0x02, 0x28, 0x3a, 0x01, 0x02, 0x2c, 0x3a, 0x01, 0x02, 0x18, 0x11, 0x02, 0x02, 0x1c, 0x11, 0x02, 0x02, + 0x20, 0x11, 0x02, 0x02, 0x24, 0x11, 0x02, 0x02, 0x28, 0x11, 0x02, 0x02, 0xf0, 0x2b, 0x03, 0x03, 0xf8, 0x2b, 0x03, 0x03, 0x00, 0x2c, 0x03, 0x03, 0xb0, 0x07, 0x04, 0x03, 0xb8, 0x07, 0x04, 0x03, + 0x90, 0x1f, 0x05, 0x04, 0xa0, 0x3e, 0x06, 0x05, 0xc0, 0x14, 0x07, 0x05, 0x00, 0x2e, 0x0d, 0x09, 0x04, 0x0b, 0x00, 0x02, 0x08, 0x0b, 0x00, 0x02, 0x0c, 0x0b, 0x00, 0x02, 0x10, 0x0b, 0x00, 0x02, + 0x30, 0x3a, 0x01, 0x02, 0x34, 0x3a, 0x01, 0x02, 0x38, 0x3a, 0x01, 0x02, 0x3c, 0x3a, 0x01, 0x02, 0x40, 0x3a, 0x01, 0x02, 0x44, 0x3a, 0x01, 0x02, 0x2c, 0x11, 0x02, 0x02, 0x30, 0x11, 0x02, 0x02, + 0x34, 0x11, 0x02, 0x02, 0x38, 0x11, 0x02, 0x02, 0x3c, 0x11, 0x02, 0x02, 0x08, 0x2c, 0x03, 0x03, 0x10, 0x2c, 0x03, 0x03, 0x18, 0x2c, 0x03, 0x03, 0xc0, 0x07, 0x04, 0x03, 0xc8, 0x07, 0x04, 0x03, + 0xa0, 0x1f, 0x05, 0x04, 0xc0, 0x3e, 0x06, 0x05, 0x80, 0x2f, 0x08, 0x06, 0x00, 0x30, 0x0d, 0x09, 0x14, 0x0b, 0x00, 0x02, 0x18, 0x0b, 0x00, 0x02, 0x1c, 0x0b, 0x00, 0x02, 0x20, 0x0b, 0x00, 0x02, + 0x48, 0x3a, 0x01, 0x02, 0x4c, 0x3a, 0x01, 0x02, 0x50, 0x3a, 0x01, 0x02, 0x54, 0x3a, 0x01, 0x02, 0x58, 0x3a, 0x01, 0x02, 0x5c, 0x3a, 0x01, 0x02, 0x40, 0x11, 0x02, 0x02, 0x44, 0x11, 0x02, 0x02, + 0x48, 0x11, 0x02, 0x02, 0x4c, 0x11, 0x02, 0x02, 0x50, 0x11, 0x02, 0x02, 0x20, 0x2c, 0x03, 0x03, 0x28, 0x2c, 0x03, 0x03, 0x30, 0x2c, 0x03, 0x03, 0xd0, 0x07, 0x04, 0x03, 0xd8, 0x07, 0x04, 0x03, + 0xb0, 0x1f, 0x05, 0x04, 0xe0, 0x3e, 0x06, 0x05, 0xc0, 0x2f, 0x08, 0x06, 0x00, 0x32, 0x0d, 0x09, 0x24, 0x0b, 0x00, 0x02, 0x28, 0x0b, 0x00, 0x02, 0x2c, 0x0b, 0x00, 0x02, 0x30, 0x0b, 0x00, 0x02, + 0x60, 0x3a, 0x01, 0x02, 0x64, 0x3a, 0x01, 0x02, 0x68, 0x3a, 0x01, 0x02, 0x6c, 0x3a, 0x01, 0x02, 0x70, 0x3a, 0x01, 0x02, 0x74, 0x3a, 0x01, 0x02, 0x54, 0x11, 0x02, 0x02, 0x58, 0x11, 0x02, 0x02, + 0x5c, 0x11, 0x02, 0x02, 0x60, 0x11, 0x02, 0x02, 0x64, 0x11, 0x02, 0x02, 0x38, 0x2c, 0x03, 0x03, 0x40, 0x2c, 0x03, 0x03, 0x48, 0x2c, 0x03, 0x03, 0xe0, 0x07, 0x04, 0x03, 0xe8, 0x07, 0x04, 0x03, + 0xc0, 0x1f, 0x05, 0x04, 0x00, 0x3f, 0x06, 0x05, 0x00, 0x30, 0x08, 0x06, 0x00, 0x34, 0x0d, 0x09, 0x34, 0x0b, 0x00, 0x02, 0x38, 0x0b, 0x00, 0x02, 0x3c, 0x0b, 0x00, 0x02, 0x40, 0x0b, 0x00, 0x02, + 0x78, 0x3a, 0x01, 0x02, 0x7c, 0x3a, 0x01, 0x02, 0x80, 0x3a, 0x01, 0x02, 0x84, 0x3a, 0x01, 0x02, 0x88, 0x3a, 0x01, 0x02, 0x8c, 0x3a, 0x01, 0x02, 0x68, 0x11, 0x02, 0x02, 0x6c, 0x11, 0x02, 0x02, + 0x70, 0x11, 0x02, 0x02, 0x74, 0x11, 0x02, 0x02, 0x78, 0x11, 0x02, 0x02, 0x50, 0x2c, 0x03, 0x03, 0x58, 0x2c, 0x03, 0x03, 0x60, 0x2c, 0x03, 0x03, 0xf0, 0x07, 0x04, 0x03, 0xf8, 0x07, 0x04, 0x03, + 0xd0, 0x1f, 0x05, 0x04, 0x20, 0x3f, 0x06, 0x05, 0x40, 0x30, 0x08, 0x06, 0x00, 0x36, 0x0d, 0x09, 0x44, 0x0b, 0x00, 0x02, 0x48, 0x0b, 0x00, 0x02, 0x4c, 0x0b, 0x00, 0x02, 0x50, 0x0b, 0x00, 0x02, + 0x90, 0x3a, 0x01, 0x02, 0x94, 0x3a, 0x01, 0x02, 0x98, 0x3a, 0x01, 0x02, 0x9c, 0x3a, 0x01, 0x02, 0xa0, 0x3a, 0x01, 0x02, 0xa4, 0x3a, 0x01, 0x02, 0x7c, 0x11, 0x02, 0x02, 0x80, 0x11, 0x02, 0x02, + 0x84, 0x11, 0x02, 0x02, 0x88, 0x11, 0x02, 0x02, 0x8c, 0x11, 0x02, 0x02, 0x68, 0x2c, 0x03, 0x03, 0x70, 0x2c, 0x03, 0x03, 0x78, 0x2c, 0x03, 0x03, 0x00, 0x08, 0x04, 0x03, 0x08, 0x08, 0x04, 0x03, + 0xe0, 0x1f, 0x05, 0x04, 0x40, 0x3f, 0x06, 0x05, 0x80, 0x30, 0x08, 0x06, 0x00, 0x0c, 0x0e, 0x09, 0x54, 0x0b, 0x00, 0x02, 0x58, 0x0b, 0x00, 0x02, 0x5c, 0x0b, 0x00, 0x02, 0x60, 0x0b, 0x00, 0x02, + 0xa8, 0x3a, 0x01, 0x02, 0xac, 0x3a, 0x01, 0x02, 0xb0, 0x3a, 0x01, 0x02, 0xb4, 0x3a, 0x01, 0x02, 0xb8, 0x3a, 0x01, 0x02, 0xbc, 0x3a, 0x01, 0x02, 0x90, 0x11, 0x02, 0x02, 0x94, 0x11, 0x02, 0x02, + 0x98, 0x11, 0x02, 0x02, 0x9c, 0x11, 0x02, 0x02, 0xa0, 0x11, 0x02, 0x02, 0x80, 0x2c, 0x03, 0x03, 0x88, 0x2c, 0x03, 0x03, 0x90, 0x2c, 0x03, 0x03, 0x10, 0x08, 0x04, 0x03, 0x18, 0x08, 0x04, 0x03, + 0xf0, 0x1f, 0x05, 0x04, 0x60, 0x3f, 0x06, 0x05, 0xc0, 0x30, 0x08, 0x06, 0x00, 0x0e, 0x0e, 0x09, 0x64, 0x0b, 0x00, 0x02, 0x68, 0x0b, 0x00, 0x02, 0x6c, 0x0b, 0x00, 0x02, 0x70, 0x0b, 0x00, 0x02, + 0xc0, 0x3a, 0x01, 0x02, 0xc4, 0x3a, 0x01, 0x02, 0xc8, 0x3a, 0x01, 0x02, 0xcc, 0x3a, 0x01, 0x02, 0xd0, 0x3a, 0x01, 0x02, 0xd4, 0x3a, 0x01, 0x02, 0xa4, 0x11, 0x02, 0x02, 0xa8, 0x11, 0x02, 0x02, + 0xac, 0x11, 0x02, 0x02, 0xb0, 0x11, 0x02, 0x02, 0xb4, 0x11, 0x02, 0x02, 0x98, 0x2c, 0x03, 0x03, 0xa0, 0x2c, 0x03, 0x03, 0xa8, 0x2c, 0x03, 0x03, 0x20, 0x08, 0x04, 0x03, 0x28, 0x08, 0x04, 0x03, + 0x00, 0x20, 0x05, 0x04, 0x80, 0x3f, 0x06, 0x05, 0x00, 0x31, 0x08, 0x06, 0x00, 0x10, 0x0e, 0x09, 0x74, 0x0b, 0x00, 0x02, 0x78, 0x0b, 0x00, 0x02, 0x7c, 0x0b, 0x00, 0x02, 0x80, 0x0b, 0x00, 0x02, + 0xd8, 0x3a, 0x01, 0x02, 0xdc, 0x3a, 0x01, 0x02, 0xe0, 0x3a, 0x01, 0x02, 0xe4, 0x3a, 0x01, 0x02, 0xe8, 0x3a, 0x01, 0x02, 0xec, 0x3a, 0x01, 0x02, 0xb8, 0x11, 0x02, 0x02, 0xbc, 0x11, 0x02, 0x02, + 0xc0, 0x11, 0x02, 0x02, 0xc4, 0x11, 0x02, 0x02, 0xc8, 0x11, 0x02, 0x02, 0xb0, 0x2c, 0x03, 0x03, 0xb8, 0x2c, 0x03, 0x03, 0xc0, 0x2c, 0x03, 0x03, 0x30, 0x08, 0x04, 0x03, 0x38, 0x08, 0x04, 0x03, + 0x10, 0x20, 0x05, 0x04, 0xa0, 0x3f, 0x06, 0x05, 0x40, 0x31, 0x08, 0x06, 0x00, 0x28, 0x0f, 0x0a, 0x84, 0x0b, 0x00, 0x02, 0x88, 0x0b, 0x00, 0x02, 0x8c, 0x0b, 0x00, 0x02, 0x90, 0x0b, 0x00, 0x02, + 0xf0, 0x3a, 0x01, 0x02, 0xf4, 0x3a, 0x01, 0x02, 0xf8, 0x3a, 0x01, 0x02, 0xfc, 0x3a, 0x01, 0x02, 0x00, 0x3b, 0x01, 0x02, 0x04, 0x3b, 0x01, 0x02, 0xcc, 0x11, 0x02, 0x02, 0xd0, 0x11, 0x02, 0x02, + 0xd4, 0x11, 0x02, 0x02, 0xd8, 0x11, 0x02, 0x02, 0xdc, 0x11, 0x02, 0x02, 0xc8, 0x2c, 0x03, 0x03, 0xd0, 0x2c, 0x03, 0x03, 0xd8, 0x2c, 0x03, 0x03, 0x40, 0x08, 0x04, 0x03, 0x48, 0x08, 0x04, 0x03, + 0x20, 0x20, 0x05, 0x04, 0xc0, 0x3f, 0x06, 0x05, 0x80, 0x31, 0x08, 0x06, 0x00, 0x2c, 0x0f, 0x0a, 0x94, 0x0b, 0x00, 0x02, 0x98, 0x0b, 0x00, 0x02, 0x9c, 0x0b, 0x00, 0x02, 0xa0, 0x0b, 0x00, 0x02, + 0x08, 0x3b, 0x01, 0x02, 0x0c, 0x3b, 0x01, 0x02, 0x10, 0x3b, 0x01, 0x02, 0x14, 0x3b, 0x01, 0x02, 0x18, 0x3b, 0x01, 0x02, 0x1c, 0x3b, 0x01, 0x02, 0xe0, 0x11, 0x02, 0x02, 0xe4, 0x11, 0x02, 0x02, + 0xe8, 0x11, 0x02, 0x02, 0xec, 0x11, 0x02, 0x02, 0xf0, 0x11, 0x02, 0x02, 0xe0, 0x2c, 0x03, 0x03, 0xe8, 0x2c, 0x03, 0x03, 0xf0, 0x2c, 0x03, 0x03, 0x50, 0x08, 0x04, 0x03, 0x58, 0x08, 0x04, 0x03, + 0x30, 0x20, 0x05, 0x04, 0xe0, 0x3f, 0x06, 0x05, 0xc0, 0x31, 0x08, 0x06, 0x00, 0x04, 0x10, 0x0a, 0xa4, 0x0b, 0x00, 0x02, 0xa8, 0x0b, 0x00, 0x02, 0xac, 0x0b, 0x00, 0x02, 0xb0, 0x0b, 0x00, 0x02, + 0x20, 0x3b, 0x01, 0x02, 0x24, 0x3b, 0x01, 0x02, 0x28, 0x3b, 0x01, 0x02, 0x2c, 0x3b, 0x01, 0x02, 0x30, 0x3b, 0x01, 0x02, 0x34, 0x3b, 0x01, 0x02, 0xf4, 0x11, 0x02, 0x02, 0xf8, 0x11, 0x02, 0x02, + 0xfc, 0x11, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x04, 0x12, 0x02, 0x02, 0xf8, 0x2c, 0x03, 0x03, 0x00, 0x2d, 0x03, 0x03, 0x08, 0x2d, 0x03, 0x03, 0x60, 0x08, 0x04, 0x03, 0x68, 0x08, 0x04, 0x03, + 0x40, 0x20, 0x05, 0x04, 0x00, 0x00, 0x06, 0x04, 0x00, 0x32, 0x08, 0x06, 0x00, 0x20, 0x11, 0x0b, 0xb4, 0x0b, 0x00, 0x02, 0xb8, 0x0b, 0x00, 0x02, 0xbc, 0x0b, 0x00, 0x02, 0xc0, 0x0b, 0x00, 0x02, + 0x38, 0x3b, 0x01, 0x02, 0x3c, 0x3b, 0x01, 0x02, 0x40, 0x3b, 0x01, 0x02, 0x44, 0x3b, 0x01, 0x02, 0x48, 0x3b, 0x01, 0x02, 0x4c, 0x3b, 0x01, 0x02, 0x08, 0x12, 0x02, 0x02, 0x0c, 0x12, 0x02, 0x02, + 0x10, 0x12, 0x02, 0x02, 0x14, 0x12, 0x02, 0x02, 0x18, 0x12, 0x02, 0x02, 0x10, 0x2d, 0x03, 0x03, 0x18, 0x2d, 0x03, 0x03, 0x20, 0x2d, 0x03, 0x03, 0x70, 0x08, 0x04, 0x03, 0x78, 0x08, 0x04, 0x03, + 0x50, 0x20, 0x05, 0x04, 0x10, 0x00, 0x06, 0x04, 0x40, 0x32, 0x08, 0x06, 0x00, 0x30, 0x12, 0x0c, 0xc4, 0x0b, 0x00, 0x02, 0xc8, 0x0b, 0x00, 0x02, 0xcc, 0x0b, 0x00, 0x02, 0xd0, 0x0b, 0x00, 0x02, + 0x50, 0x3b, 0x01, 0x02, 0x54, 0x3b, 0x01, 0x02, 0x58, 0x3b, 0x01, 0x02, 0x5c, 0x3b, 0x01, 0x02, 0x60, 0x3b, 0x01, 0x02, 0x64, 0x3b, 0x01, 0x02, 0x1c, 0x12, 0x02, 0x02, 0x20, 0x12, 0x02, 0x02, + 0x24, 0x12, 0x02, 0x02, 0x28, 0x12, 0x02, 0x02, 0x2c, 0x12, 0x02, 0x02, 0x28, 0x2d, 0x03, 0x03, 0x30, 0x2d, 0x03, 0x03, 0x38, 0x2d, 0x03, 0x03, 0x80, 0x08, 0x04, 0x03, 0x88, 0x08, 0x04, 0x03, + 0x60, 0x20, 0x05, 0x04, 0x20, 0x00, 0x06, 0x04, 0x80, 0x32, 0x08, 0x06, 0x00, 0x20, 0x14, 0x0d, 0xd4, 0x0b, 0x00, 0x02, 0xd8, 0x0b, 0x00, 0x02, 0xdc, 0x0b, 0x00, 0x02, 0xe0, 0x0b, 0x00, 0x02, + 0x68, 0x3b, 0x01, 0x02, 0x6c, 0x3b, 0x01, 0x02, 0x70, 0x3b, 0x01, 0x02, 0x74, 0x3b, 0x01, 0x02, 0x78, 0x3b, 0x01, 0x02, 0x7c, 0x3b, 0x01, 0x02, 0x30, 0x12, 0x02, 0x02, 0x34, 0x12, 0x02, 0x02, + 0x38, 0x12, 0x02, 0x02, 0x3c, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x02, 0x40, 0x2d, 0x03, 0x03, 0x48, 0x2d, 0x03, 0x03, 0x50, 0x2d, 0x03, 0x03, 0x90, 0x08, 0x04, 0x03, 0x98, 0x08, 0x04, 0x03, + 0x70, 0x20, 0x05, 0x04, 0x30, 0x00, 0x06, 0x04, 0xc0, 0x32, 0x08, 0x06, 0xe4, 0x0b, 0x00, 0x02, 0xe8, 0x0b, 0x00, 0x02, 0xec, 0x0b, 0x00, 0x02, 0xf0, 0x0b, 0x00, 0x02, 0xf4, 0x0b, 0x00, 0x02, + 0x80, 0x3b, 0x01, 0x02, 0x84, 0x3b, 0x01, 0x02, 0x88, 0x3b, 0x01, 0x02, 0x8c, 0x3b, 0x01, 0x02, 0x90, 0x3b, 0x01, 0x02, 0x94, 0x3b, 0x01, 0x02, 0x44, 0x12, 0x02, 0x02, 0x48, 0x12, 0x02, 0x02, + 0x4c, 0x12, 0x02, 0x02, 0x50, 0x12, 0x02, 0x02, 0x54, 0x12, 0x02, 0x02, 0x58, 0x2d, 0x03, 0x03, 0x60, 0x2d, 0x03, 0x03, 0x68, 0x2d, 0x03, 0x03, 0xa0, 0x08, 0x04, 0x03, 0xa8, 0x08, 0x04, 0x03, + 0x80, 0x20, 0x05, 0x04, 0x40, 0x00, 0x06, 0x04, 0x00, 0x33, 0x08, 0x06, 0xf8, 0x0b, 0x00, 0x02, 0xfc, 0x0b, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x04, 0x0c, 0x00, 0x02, 0x08, 0x0c, 0x00, 0x02, + 0x98, 0x3b, 0x01, 0x02, 0x9c, 0x3b, 0x01, 0x02, 0xa0, 0x3b, 0x01, 0x02, 0xa4, 0x3b, 0x01, 0x02, 0xa8, 0x3b, 0x01, 0x02, 0xac, 0x3b, 0x01, 0x02, 0x58, 0x12, 0x02, 0x02, 0x5c, 0x12, 0x02, 0x02, + 0x60, 0x12, 0x02, 0x02, 0x64, 0x12, 0x02, 0x02, 0x68, 0x12, 0x02, 0x02, 0x70, 0x2d, 0x03, 0x03, 0x78, 0x2d, 0x03, 0x03, 0x80, 0x2d, 0x03, 0x03, 0xb0, 0x08, 0x04, 0x03, 0xb8, 0x08, 0x04, 0x03, + 0x90, 0x20, 0x05, 0x04, 0x50, 0x00, 0x06, 0x04, 0x40, 0x33, 0x08, 0x06, 0x0c, 0x0c, 0x00, 0x02, 0x10, 0x0c, 0x00, 0x02, 0x14, 0x0c, 0x00, 0x02, 0x18, 0x0c, 0x00, 0x02, 0x1c, 0x0c, 0x00, 0x02, + 0xb0, 0x3b, 0x01, 0x02, 0xb4, 0x3b, 0x01, 0x02, 0xb8, 0x3b, 0x01, 0x02, 0xbc, 0x3b, 0x01, 0x02, 0xc0, 0x3b, 0x01, 0x02, 0xc4, 0x3b, 0x01, 0x02, 0x6c, 0x12, 0x02, 0x02, 0x70, 0x12, 0x02, 0x02, + 0x74, 0x12, 0x02, 0x02, 0x78, 0x12, 0x02, 0x02, 0x7c, 0x12, 0x02, 0x02, 0x88, 0x2d, 0x03, 0x03, 0x90, 0x2d, 0x03, 0x03, 0x98, 0x2d, 0x03, 0x03, 0xc0, 0x08, 0x04, 0x03, 0xc8, 0x08, 0x04, 0x03, + 0xa0, 0x20, 0x05, 0x04, 0x60, 0x00, 0x06, 0x04, 0x80, 0x33, 0x08, 0x06, 0x20, 0x0c, 0x00, 0x02, 0x24, 0x0c, 0x00, 0x02, 0x28, 0x0c, 0x00, 0x02, 0x2c, 0x0c, 0x00, 0x02, 0x30, 0x0c, 0x00, 0x02, + 0xc8, 0x3b, 0x01, 0x02, 0xcc, 0x3b, 0x01, 0x02, 0xd0, 0x3b, 0x01, 0x02, 0xd4, 0x3b, 0x01, 0x02, 0xd8, 0x3b, 0x01, 0x02, 0xdc, 0x3b, 0x01, 0x02, 0x80, 0x12, 0x02, 0x02, 0x84, 0x12, 0x02, 0x02, + 0x88, 0x12, 0x02, 0x02, 0x8c, 0x12, 0x02, 0x02, 0x90, 0x12, 0x02, 0x02, 0xa0, 0x2d, 0x03, 0x03, 0xa8, 0x2d, 0x03, 0x03, 0xb0, 0x2d, 0x03, 0x03, 0xd0, 0x08, 0x04, 0x03, 0xd8, 0x08, 0x04, 0x03, + 0xb0, 0x20, 0x05, 0x04, 0x70, 0x00, 0x06, 0x04, 0xc0, 0x33, 0x08, 0x06, 0x34, 0x0c, 0x00, 0x02, 0x38, 0x0c, 0x00, 0x02, 0x3c, 0x0c, 0x00, 0x02, 0x40, 0x0c, 0x00, 0x02, 0x44, 0x0c, 0x00, 0x02, + 0xe0, 0x3b, 0x01, 0x02, 0xe4, 0x3b, 0x01, 0x02, 0xe8, 0x3b, 0x01, 0x02, 0xec, 0x3b, 0x01, 0x02, 0xf0, 0x3b, 0x01, 0x02, 0xf4, 0x3b, 0x01, 0x02, 0x94, 0x12, 0x02, 0x02, 0x98, 0x12, 0x02, 0x02, + 0x9c, 0x12, 0x02, 0x02, 0xa0, 0x12, 0x02, 0x02, 0xa4, 0x12, 0x02, 0x02, 0xb8, 0x2d, 0x03, 0x03, 0xc0, 0x2d, 0x03, 0x03, 0xc8, 0x2d, 0x03, 0x03, 0xe0, 0x08, 0x04, 0x03, 0xe8, 0x08, 0x04, 0x03, + 0xc0, 0x20, 0x05, 0x04, 0x80, 0x00, 0x06, 0x04, 0x00, 0x34, 0x08, 0x06, 0x48, 0x0c, 0x00, 0x02, 0x4c, 0x0c, 0x00, 0x02, 0x50, 0x0c, 0x00, 0x02, 0x54, 0x0c, 0x00, 0x02, 0x58, 0x0c, 0x00, 0x02, + 0xf8, 0x3b, 0x01, 0x02, 0xfc, 0x3b, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x04, 0x3c, 0x01, 0x02, 0x08, 0x3c, 0x01, 0x02, 0x0c, 0x3c, 0x01, 0x02, 0xa8, 0x12, 0x02, 0x02, 0xac, 0x12, 0x02, 0x02, + 0xb0, 0x12, 0x02, 0x02, 0xb4, 0x12, 0x02, 0x02, 0xb8, 0x12, 0x02, 0x02, 0xd0, 0x2d, 0x03, 0x03, 0xd8, 0x2d, 0x03, 0x03, 0xe0, 0x2d, 0x03, 0x03, 0xf0, 0x08, 0x04, 0x03, 0xf8, 0x08, 0x04, 0x03, + 0xd0, 0x20, 0x05, 0x04, 0x90, 0x00, 0x06, 0x04, 0x40, 0x34, 0x08, 0x06, 0x5c, 0x0c, 0x00, 0x02, 0x60, 0x0c, 0x00, 0x02, 0x64, 0x0c, 0x00, 0x02, 0x68, 0x0c, 0x00, 0x02, 0x6c, 0x0c, 0x00, 0x02, + 0x10, 0x3c, 0x01, 0x02, 0x14, 0x3c, 0x01, 0x02, 0x18, 0x3c, 0x01, 0x02, 0x1c, 0x3c, 0x01, 0x02, 0x20, 0x3c, 0x01, 0x02, 0x24, 0x3c, 0x01, 0x02, 0xbc, 0x12, 0x02, 0x02, 0xc0, 0x12, 0x02, 0x02, + 0xc4, 0x12, 0x02, 0x02, 0xc8, 0x12, 0x02, 0x02, 0xcc, 0x12, 0x02, 0x02, 0xe8, 0x2d, 0x03, 0x03, 0xf0, 0x2d, 0x03, 0x03, 0xf8, 0x2d, 0x03, 0x03, 0x00, 0x09, 0x04, 0x03, 0x08, 0x09, 0x04, 0x03, + 0xe0, 0x20, 0x05, 0x04, 0xa0, 0x00, 0x06, 0x04, 0x80, 0x34, 0x08, 0x06, 0x70, 0x0c, 0x00, 0x02, 0x74, 0x0c, 0x00, 0x02, 0x78, 0x0c, 0x00, 0x02, 0x7c, 0x0c, 0x00, 0x02, 0x28, 0x3c, 0x01, 0x02, + 0x2c, 0x3c, 0x01, 0x02, 0x30, 0x3c, 0x01, 0x02, 0x34, 0x3c, 0x01, 0x02, 0x38, 0x3c, 0x01, 0x02, 0x3c, 0x3c, 0x01, 0x02, 0x40, 0x3c, 0x01, 0x02, 0xd0, 0x12, 0x02, 0x02, 0xd4, 0x12, 0x02, 0x02, + 0xd8, 0x12, 0x02, 0x02, 0xdc, 0x12, 0x02, 0x02, 0xe0, 0x12, 0x02, 0x02, 0x00, 0x2e, 0x03, 0x03, 0x08, 0x2e, 0x03, 0x03, 0x10, 0x2e, 0x03, 0x03, 0x10, 0x09, 0x04, 0x03, 0x18, 0x09, 0x04, 0x03, + 0xf0, 0x20, 0x05, 0x04, 0xb0, 0x00, 0x06, 0x04, 0xc0, 0x34, 0x08, 0x06, 0x80, 0x0c, 0x00, 0x02, 0x84, 0x0c, 0x00, 0x02, 0x88, 0x0c, 0x00, 0x02, 0x8c, 0x0c, 0x00, 0x02, 0x44, 0x3c, 0x01, 0x02, + 0x48, 0x3c, 0x01, 0x02, 0x4c, 0x3c, 0x01, 0x02, 0x50, 0x3c, 0x01, 0x02, 0x54, 0x3c, 0x01, 0x02, 0x58, 0x3c, 0x01, 0x02, 0x5c, 0x3c, 0x01, 0x02, 0xe4, 0x12, 0x02, 0x02, 0xe8, 0x12, 0x02, 0x02, + 0xec, 0x12, 0x02, 0x02, 0xf0, 0x12, 0x02, 0x02, 0xf4, 0x12, 0x02, 0x02, 0x18, 0x2e, 0x03, 0x03, 0x20, 0x2e, 0x03, 0x03, 0x28, 0x2e, 0x03, 0x03, 0x20, 0x09, 0x04, 0x03, 0x28, 0x09, 0x04, 0x03, + 0x00, 0x21, 0x05, 0x04, 0xc0, 0x00, 0x06, 0x04, 0x00, 0x35, 0x08, 0x06, 0x90, 0x0c, 0x00, 0x02, 0x94, 0x0c, 0x00, 0x02, 0x98, 0x0c, 0x00, 0x02, 0x9c, 0x0c, 0x00, 0x02, 0x60, 0x3c, 0x01, 0x02, + 0x64, 0x3c, 0x01, 0x02, 0x68, 0x3c, 0x01, 0x02, 0x6c, 0x3c, 0x01, 0x02, 0x70, 0x3c, 0x01, 0x02, 0x74, 0x3c, 0x01, 0x02, 0x78, 0x3c, 0x01, 0x02, 0xf8, 0x12, 0x02, 0x02, 0xfc, 0x12, 0x02, 0x02, + 0x00, 0x13, 0x02, 0x02, 0x04, 0x13, 0x02, 0x02, 0x08, 0x13, 0x02, 0x02, 0x30, 0x2e, 0x03, 0x03, 0x38, 0x2e, 0x03, 0x03, 0x40, 0x2e, 0x03, 0x03, 0x30, 0x09, 0x04, 0x03, 0x10, 0x21, 0x05, 0x04, + 0x20, 0x21, 0x05, 0x04, 0xd0, 0x00, 0x06, 0x04, 0x40, 0x35, 0x08, 0x06, 0xa0, 0x0c, 0x00, 0x02, 0xa4, 0x0c, 0x00, 0x02, 0xa8, 0x0c, 0x00, 0x02, 0xac, 0x0c, 0x00, 0x02, 0x7c, 0x3c, 0x01, 0x02, + 0x80, 0x3c, 0x01, 0x02, 0x84, 0x3c, 0x01, 0x02, 0x88, 0x3c, 0x01, 0x02, 0x8c, 0x3c, 0x01, 0x02, 0x90, 0x3c, 0x01, 0x02, 0x94, 0x3c, 0x01, 0x02, 0x0c, 0x13, 0x02, 0x02, 0x10, 0x13, 0x02, 0x02, + 0x14, 0x13, 0x02, 0x02, 0x18, 0x13, 0x02, 0x02, 0x1c, 0x13, 0x02, 0x02, 0x48, 0x2e, 0x03, 0x03, 0x50, 0x2e, 0x03, 0x03, 0x58, 0x2e, 0x03, 0x03, 0x38, 0x09, 0x04, 0x03, 0x30, 0x21, 0x05, 0x04, + 0x40, 0x21, 0x05, 0x04, 0xe0, 0x00, 0x06, 0x04, 0x80, 0x35, 0x08, 0x06, 0xb0, 0x0c, 0x00, 0x02, 0xb4, 0x0c, 0x00, 0x02, 0xb8, 0x0c, 0x00, 0x02, 0xbc, 0x0c, 0x00, 0x02, 0x98, 0x3c, 0x01, 0x02, + 0x9c, 0x3c, 0x01, 0x02, 0xa0, 0x3c, 0x01, 0x02, 0xa4, 0x3c, 0x01, 0x02, 0xa8, 0x3c, 0x01, 0x02, 0xac, 0x3c, 0x01, 0x02, 0xb0, 0x3c, 0x01, 0x02, 0x20, 0x13, 0x02, 0x02, 0x24, 0x13, 0x02, 0x02, + 0x28, 0x13, 0x02, 0x02, 0x2c, 0x13, 0x02, 0x02, 0x30, 0x13, 0x02, 0x02, 0x60, 0x2e, 0x03, 0x03, 0x68, 0x2e, 0x03, 0x03, 0x70, 0x2e, 0x03, 0x03, 0x40, 0x09, 0x04, 0x03, 0x50, 0x21, 0x05, 0x04, + 0x60, 0x21, 0x05, 0x04, 0xf0, 0x00, 0x06, 0x04, 0xc0, 0x35, 0x08, 0x06, 0xc0, 0x0c, 0x00, 0x02, 0xc4, 0x0c, 0x00, 0x02, 0xc8, 0x0c, 0x00, 0x02, 0xcc, 0x0c, 0x00, 0x02, 0xb4, 0x3c, 0x01, 0x02, + 0xb8, 0x3c, 0x01, 0x02, 0xbc, 0x3c, 0x01, 0x02, 0xc0, 0x3c, 0x01, 0x02, 0xc4, 0x3c, 0x01, 0x02, 0xc8, 0x3c, 0x01, 0x02, 0xcc, 0x3c, 0x01, 0x02, 0x34, 0x13, 0x02, 0x02, 0x38, 0x13, 0x02, 0x02, + 0x3c, 0x13, 0x02, 0x02, 0x40, 0x13, 0x02, 0x02, 0x44, 0x13, 0x02, 0x02, 0x78, 0x2e, 0x03, 0x03, 0x80, 0x2e, 0x03, 0x03, 0x48, 0x09, 0x04, 0x03, 0x50, 0x09, 0x04, 0x03, 0x70, 0x21, 0x05, 0x04, + 0x80, 0x21, 0x05, 0x04, 0x00, 0x01, 0x06, 0x04, 0x00, 0x36, 0x08, 0x06, 0xd0, 0x0c, 0x00, 0x02, 0xd4, 0x0c, 0x00, 0x02, 0xd8, 0x0c, 0x00, 0x02, 0xdc, 0x0c, 0x00, 0x02, 0xd0, 0x3c, 0x01, 0x02, + 0xd4, 0x3c, 0x01, 0x02, 0xd8, 0x3c, 0x01, 0x02, 0xdc, 0x3c, 0x01, 0x02, 0xe0, 0x3c, 0x01, 0x02, 0xe4, 0x3c, 0x01, 0x02, 0xe8, 0x3c, 0x01, 0x02, 0x48, 0x13, 0x02, 0x02, 0x4c, 0x13, 0x02, 0x02, + 0x50, 0x13, 0x02, 0x02, 0x54, 0x13, 0x02, 0x02, 0x58, 0x13, 0x02, 0x02, 0x88, 0x2e, 0x03, 0x03, 0x90, 0x2e, 0x03, 0x03, 0x58, 0x09, 0x04, 0x03, 0x60, 0x09, 0x04, 0x03, 0x90, 0x21, 0x05, 0x04, + 0xa0, 0x21, 0x05, 0x04, 0x10, 0x01, 0x06, 0x04, 0x40, 0x36, 0x08, 0x06, 0xe0, 0x0c, 0x00, 0x02, 0xe4, 0x0c, 0x00, 0x02, 0xe8, 0x0c, 0x00, 0x02, 0xec, 0x0c, 0x00, 0x02, 0xec, 0x3c, 0x01, 0x02, + 0xf0, 0x3c, 0x01, 0x02, 0xf4, 0x3c, 0x01, 0x02, 0xf8, 0x3c, 0x01, 0x02, 0xfc, 0x3c, 0x01, 0x02, 0x00, 0x3d, 0x01, 0x02, 0x04, 0x3d, 0x01, 0x02, 0x5c, 0x13, 0x02, 0x02, 0x60, 0x13, 0x02, 0x02, + 0x64, 0x13, 0x02, 0x02, 0x68, 0x13, 0x02, 0x02, 0x6c, 0x13, 0x02, 0x02, 0x98, 0x2e, 0x03, 0x03, 0xa0, 0x2e, 0x03, 0x03, 0x68, 0x09, 0x04, 0x03, 0x70, 0x09, 0x04, 0x03, 0xb0, 0x21, 0x05, 0x04, + 0xc0, 0x21, 0x05, 0x04, 0x20, 0x01, 0x06, 0x04, 0x80, 0x36, 0x08, 0x06, 0xf0, 0x0c, 0x00, 0x02, 0xf4, 0x0c, 0x00, 0x02, 0xf8, 0x0c, 0x00, 0x02, 0xfc, 0x0c, 0x00, 0x02, 0x08, 0x3d, 0x01, 0x02, + 0x0c, 0x3d, 0x01, 0x02, 0x10, 0x3d, 0x01, 0x02, 0x14, 0x3d, 0x01, 0x02, 0x18, 0x3d, 0x01, 0x02, 0x1c, 0x3d, 0x01, 0x02, 0x20, 0x3d, 0x01, 0x02, 0x70, 0x13, 0x02, 0x02, 0x74, 0x13, 0x02, 0x02, + 0x78, 0x13, 0x02, 0x02, 0x7c, 0x13, 0x02, 0x02, 0x80, 0x13, 0x02, 0x02, 0xa8, 0x2e, 0x03, 0x03, 0xb0, 0x2e, 0x03, 0x03, 0x78, 0x09, 0x04, 0x03, 0x80, 0x09, 0x04, 0x03, 0xd0, 0x21, 0x05, 0x04, + 0xe0, 0x21, 0x05, 0x04, 0x30, 0x01, 0x06, 0x04, 0xc0, 0x36, 0x08, 0x06, 0x00, 0x0d, 0x00, 0x02, 0x04, 0x0d, 0x00, 0x02, 0x08, 0x0d, 0x00, 0x02, 0x0c, 0x0d, 0x00, 0x02, 0x24, 0x3d, 0x01, 0x02, + 0x28, 0x3d, 0x01, 0x02, 0x2c, 0x3d, 0x01, 0x02, 0x30, 0x3d, 0x01, 0x02, 0x34, 0x3d, 0x01, 0x02, 0x38, 0x3d, 0x01, 0x02, 0x3c, 0x3d, 0x01, 0x02, 0x84, 0x13, 0x02, 0x02, 0x88, 0x13, 0x02, 0x02, + 0x8c, 0x13, 0x02, 0x02, 0x90, 0x13, 0x02, 0x02, 0xb8, 0x2e, 0x03, 0x03, 0xc0, 0x2e, 0x03, 0x03, 0xc8, 0x2e, 0x03, 0x03, 0x88, 0x09, 0x04, 0x03, 0x90, 0x09, 0x04, 0x03, 0xf0, 0x21, 0x05, 0x04, + 0x00, 0x22, 0x05, 0x04, 0x40, 0x01, 0x06, 0x04, 0x00, 0x37, 0x08, 0x06, 0x10, 0x0d, 0x00, 0x02, 0x14, 0x0d, 0x00, 0x02, 0x18, 0x0d, 0x00, 0x02, 0x1c, 0x0d, 0x00, 0x02, 0x40, 0x3d, 0x01, 0x02, + 0x44, 0x3d, 0x01, 0x02, 0x48, 0x3d, 0x01, 0x02, 0x4c, 0x3d, 0x01, 0x02, 0x50, 0x3d, 0x01, 0x02, 0x54, 0x3d, 0x01, 0x02, 0x58, 0x3d, 0x01, 0x02, 0x94, 0x13, 0x02, 0x02, 0x98, 0x13, 0x02, 0x02, + 0x9c, 0x13, 0x02, 0x02, 0xa0, 0x13, 0x02, 0x02, 0xd0, 0x2e, 0x03, 0x03, 0xd8, 0x2e, 0x03, 0x03, 0xe0, 0x2e, 0x03, 0x03, 0x98, 0x09, 0x04, 0x03, 0xa0, 0x09, 0x04, 0x03, 0x10, 0x22, 0x05, 0x04, + 0x20, 0x22, 0x05, 0x04, 0x50, 0x01, 0x06, 0x04, 0x40, 0x37, 0x08, 0x06, 0x20, 0x0d, 0x00, 0x02, 0x24, 0x0d, 0x00, 0x02, 0x28, 0x0d, 0x00, 0x02, 0x2c, 0x0d, 0x00, 0x02, 0x5c, 0x3d, 0x01, 0x02, + 0x60, 0x3d, 0x01, 0x02, 0x64, 0x3d, 0x01, 0x02, 0x68, 0x3d, 0x01, 0x02, 0x6c, 0x3d, 0x01, 0x02, 0x70, 0x3d, 0x01, 0x02, 0x74, 0x3d, 0x01, 0x02, 0xa4, 0x13, 0x02, 0x02, 0xa8, 0x13, 0x02, 0x02, + 0xac, 0x13, 0x02, 0x02, 0xb0, 0x13, 0x02, 0x02, 0xe8, 0x2e, 0x03, 0x03, 0xf0, 0x2e, 0x03, 0x03, 0xf8, 0x2e, 0x03, 0x03, 0xa8, 0x09, 0x04, 0x03, 0xb0, 0x09, 0x04, 0x03, 0x30, 0x22, 0x05, 0x04, + 0x40, 0x22, 0x05, 0x04, 0x60, 0x01, 0x06, 0x04, 0x80, 0x37, 0x08, 0x06, 0x30, 0x0d, 0x00, 0x02, 0x34, 0x0d, 0x00, 0x02, 0x38, 0x0d, 0x00, 0x02, 0x3c, 0x0d, 0x00, 0x02, 0x78, 0x3d, 0x01, 0x02, + 0x7c, 0x3d, 0x01, 0x02, 0x80, 0x3d, 0x01, 0x02, 0x84, 0x3d, 0x01, 0x02, 0x88, 0x3d, 0x01, 0x02, 0x8c, 0x3d, 0x01, 0x02, 0x90, 0x3d, 0x01, 0x02, 0xb4, 0x13, 0x02, 0x02, 0xb8, 0x13, 0x02, 0x02, + 0xbc, 0x13, 0x02, 0x02, 0xc0, 0x13, 0x02, 0x02, 0x00, 0x2f, 0x03, 0x03, 0x08, 0x2f, 0x03, 0x03, 0x10, 0x2f, 0x03, 0x03, 0xb8, 0x09, 0x04, 0x03, 0xc0, 0x09, 0x04, 0x03, 0x50, 0x22, 0x05, 0x04, + 0x60, 0x22, 0x05, 0x04, 0x70, 0x01, 0x06, 0x04, 0xc0, 0x0a, 0x09, 0x06, 0x40, 0x0d, 0x00, 0x02, 0x44, 0x0d, 0x00, 0x02, 0x48, 0x0d, 0x00, 0x02, 0x4c, 0x0d, 0x00, 0x02, 0x94, 0x3d, 0x01, 0x02, + 0x98, 0x3d, 0x01, 0x02, 0x9c, 0x3d, 0x01, 0x02, 0xa0, 0x3d, 0x01, 0x02, 0xa4, 0x3d, 0x01, 0x02, 0xa8, 0x3d, 0x01, 0x02, 0xac, 0x3d, 0x01, 0x02, 0xc4, 0x13, 0x02, 0x02, 0xc8, 0x13, 0x02, 0x02, + 0xcc, 0x13, 0x02, 0x02, 0xd0, 0x13, 0x02, 0x02, 0x18, 0x2f, 0x03, 0x03, 0x20, 0x2f, 0x03, 0x03, 0x28, 0x2f, 0x03, 0x03, 0xc8, 0x09, 0x04, 0x03, 0xd0, 0x09, 0x04, 0x03, 0x70, 0x22, 0x05, 0x04, + 0x80, 0x22, 0x05, 0x04, 0x80, 0x01, 0x06, 0x04, 0x00, 0x0b, 0x09, 0x06, 0x50, 0x0d, 0x00, 0x02, 0x54, 0x0d, 0x00, 0x02, 0x58, 0x0d, 0x00, 0x02, 0x5c, 0x0d, 0x00, 0x02, 0xb0, 0x3d, 0x01, 0x02, + 0xb4, 0x3d, 0x01, 0x02, 0xb8, 0x3d, 0x01, 0x02, 0xbc, 0x3d, 0x01, 0x02, 0xc0, 0x3d, 0x01, 0x02, 0xc4, 0x3d, 0x01, 0x02, 0xc8, 0x3d, 0x01, 0x02, 0xd4, 0x13, 0x02, 0x02, 0xd8, 0x13, 0x02, 0x02, + 0xdc, 0x13, 0x02, 0x02, 0xe0, 0x13, 0x02, 0x02, 0x30, 0x2f, 0x03, 0x03, 0x38, 0x2f, 0x03, 0x03, 0x40, 0x2f, 0x03, 0x03, 0xd8, 0x09, 0x04, 0x03, 0xe0, 0x09, 0x04, 0x03, 0x90, 0x22, 0x05, 0x04, + 0xa0, 0x22, 0x05, 0x04, 0x90, 0x01, 0x06, 0x04, 0x40, 0x0b, 0x09, 0x06, 0x60, 0x0d, 0x00, 0x02, 0x64, 0x0d, 0x00, 0x02, 0x68, 0x0d, 0x00, 0x02, 0x6c, 0x0d, 0x00, 0x02, 0xcc, 0x3d, 0x01, 0x02, + 0xd0, 0x3d, 0x01, 0x02, 0xd4, 0x3d, 0x01, 0x02, 0xd8, 0x3d, 0x01, 0x02, 0xdc, 0x3d, 0x01, 0x02, 0xe0, 0x3d, 0x01, 0x02, 0xe4, 0x3d, 0x01, 0x02, 0xe4, 0x13, 0x02, 0x02, 0xe8, 0x13, 0x02, 0x02, + 0xec, 0x13, 0x02, 0x02, 0xf0, 0x13, 0x02, 0x02, 0x48, 0x2f, 0x03, 0x03, 0x50, 0x2f, 0x03, 0x03, 0x58, 0x2f, 0x03, 0x03, 0xe8, 0x09, 0x04, 0x03, 0xf0, 0x09, 0x04, 0x03, 0xb0, 0x22, 0x05, 0x04, + 0xc0, 0x22, 0x05, 0x04, 0xa0, 0x01, 0x06, 0x04, 0x80, 0x0b, 0x09, 0x06, 0x70, 0x0d, 0x00, 0x02, 0x74, 0x0d, 0x00, 0x02, 0x78, 0x0d, 0x00, 0x02, 0x7c, 0x0d, 0x00, 0x02, 0xe8, 0x3d, 0x01, 0x02, + 0xec, 0x3d, 0x01, 0x02, 0xf0, 0x3d, 0x01, 0x02, 0xf4, 0x3d, 0x01, 0x02, 0xf8, 0x3d, 0x01, 0x02, 0xfc, 0x3d, 0x01, 0x02, 0x00, 0x3e, 0x01, 0x02, 0xf4, 0x13, 0x02, 0x02, 0xf8, 0x13, 0x02, 0x02, + 0xfc, 0x13, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x60, 0x2f, 0x03, 0x03, 0x68, 0x2f, 0x03, 0x03, 0x70, 0x2f, 0x03, 0x03, 0xf8, 0x09, 0x04, 0x03, 0x00, 0x0a, 0x04, 0x03, 0xd0, 0x22, 0x05, 0x04, + 0xe0, 0x22, 0x05, 0x04, 0xe0, 0x14, 0x07, 0x05, 0xc0, 0x0b, 0x09, 0x06, 0x80, 0x0d, 0x00, 0x02, 0x84, 0x0d, 0x00, 0x02, 0x88, 0x0d, 0x00, 0x02, 0x8c, 0x0d, 0x00, 0x02, 0x04, 0x3e, 0x01, 0x02, + 0x08, 0x3e, 0x01, 0x02, 0x0c, 0x3e, 0x01, 0x02, 0x10, 0x3e, 0x01, 0x02, 0x14, 0x3e, 0x01, 0x02, 0x18, 0x3e, 0x01, 0x02, 0x1c, 0x3e, 0x01, 0x02, 0x04, 0x14, 0x02, 0x02, 0x08, 0x14, 0x02, 0x02, + 0x0c, 0x14, 0x02, 0x02, 0x10, 0x14, 0x02, 0x02, 0x78, 0x2f, 0x03, 0x03, 0x80, 0x2f, 0x03, 0x03, 0x88, 0x2f, 0x03, 0x03, 0x08, 0x0a, 0x04, 0x03, 0x10, 0x0a, 0x04, 0x03, 0xf0, 0x22, 0x05, 0x04, + 0x00, 0x23, 0x05, 0x04, 0x00, 0x15, 0x07, 0x05, 0x00, 0x0c, 0x09, 0x06, 0x90, 0x0d, 0x00, 0x02, 0x94, 0x0d, 0x00, 0x02, 0x98, 0x0d, 0x00, 0x02, 0x9c, 0x0d, 0x00, 0x02, 0x20, 0x3e, 0x01, 0x02, + 0x24, 0x3e, 0x01, 0x02, 0x28, 0x3e, 0x01, 0x02, 0x2c, 0x3e, 0x01, 0x02, 0x30, 0x3e, 0x01, 0x02, 0x34, 0x3e, 0x01, 0x02, 0x38, 0x3e, 0x01, 0x02, 0x14, 0x14, 0x02, 0x02, 0x18, 0x14, 0x02, 0x02, + 0x1c, 0x14, 0x02, 0x02, 0x20, 0x14, 0x02, 0x02, 0x90, 0x2f, 0x03, 0x03, 0x98, 0x2f, 0x03, 0x03, 0xa0, 0x2f, 0x03, 0x03, 0x18, 0x0a, 0x04, 0x03, 0x20, 0x0a, 0x04, 0x03, 0x10, 0x23, 0x05, 0x04, + 0x20, 0x23, 0x05, 0x04, 0x20, 0x15, 0x07, 0x05, 0x40, 0x0c, 0x09, 0x06, 0xa0, 0x0d, 0x00, 0x02, 0xa4, 0x0d, 0x00, 0x02, 0xa8, 0x0d, 0x00, 0x02, 0xac, 0x0d, 0x00, 0x02, 0x3c, 0x3e, 0x01, 0x02, + 0x40, 0x3e, 0x01, 0x02, 0x44, 0x3e, 0x01, 0x02, 0x48, 0x3e, 0x01, 0x02, 0x4c, 0x3e, 0x01, 0x02, 0x50, 0x3e, 0x01, 0x02, 0x54, 0x3e, 0x01, 0x02, 0x24, 0x14, 0x02, 0x02, 0x28, 0x14, 0x02, 0x02, + 0x2c, 0x14, 0x02, 0x02, 0x30, 0x14, 0x02, 0x02, 0xa8, 0x2f, 0x03, 0x03, 0xb0, 0x2f, 0x03, 0x03, 0xb8, 0x2f, 0x03, 0x03, 0x28, 0x0a, 0x04, 0x03, 0x30, 0x0a, 0x04, 0x03, 0x30, 0x23, 0x05, 0x04, + 0x40, 0x23, 0x05, 0x04, 0x40, 0x15, 0x07, 0x05, 0x80, 0x0c, 0x09, 0x06, 0xb0, 0x0d, 0x00, 0x02, 0xb4, 0x0d, 0x00, 0x02, 0xb8, 0x0d, 0x00, 0x02, 0xbc, 0x0d, 0x00, 0x02, 0x58, 0x3e, 0x01, 0x02, + 0x5c, 0x3e, 0x01, 0x02, 0x60, 0x3e, 0x01, 0x02, 0x64, 0x3e, 0x01, 0x02, 0x68, 0x3e, 0x01, 0x02, 0x6c, 0x3e, 0x01, 0x02, 0x70, 0x3e, 0x01, 0x02, 0x34, 0x14, 0x02, 0x02, 0x38, 0x14, 0x02, 0x02, + 0x3c, 0x14, 0x02, 0x02, 0x40, 0x14, 0x02, 0x02, 0xc0, 0x2f, 0x03, 0x03, 0xc8, 0x2f, 0x03, 0x03, 0xd0, 0x2f, 0x03, 0x03, 0x38, 0x0a, 0x04, 0x03, 0x40, 0x0a, 0x04, 0x03, 0x50, 0x23, 0x05, 0x04, + 0x60, 0x23, 0x05, 0x04, 0x60, 0x15, 0x07, 0x05, 0xc0, 0x0c, 0x09, 0x06, 0xc0, 0x0d, 0x00, 0x02, 0xc4, 0x0d, 0x00, 0x02, 0xc8, 0x0d, 0x00, 0x02, 0xcc, 0x0d, 0x00, 0x02, 0x74, 0x3e, 0x01, 0x02, + 0x78, 0x3e, 0x01, 0x02, 0x7c, 0x3e, 0x01, 0x02, 0x80, 0x3e, 0x01, 0x02, 0x84, 0x3e, 0x01, 0x02, 0x88, 0x3e, 0x01, 0x02, 0x8c, 0x3e, 0x01, 0x02, 0x44, 0x14, 0x02, 0x02, 0x48, 0x14, 0x02, 0x02, + 0x4c, 0x14, 0x02, 0x02, 0x50, 0x14, 0x02, 0x02, 0xd8, 0x2f, 0x03, 0x03, 0xe0, 0x2f, 0x03, 0x03, 0xe8, 0x2f, 0x03, 0x03, 0x48, 0x0a, 0x04, 0x03, 0x50, 0x0a, 0x04, 0x03, 0x70, 0x23, 0x05, 0x04, + 0x80, 0x23, 0x05, 0x04, 0x80, 0x15, 0x07, 0x05, 0x00, 0x0d, 0x09, 0x06, 0xd0, 0x0d, 0x00, 0x02, 0xd4, 0x0d, 0x00, 0x02, 0xd8, 0x0d, 0x00, 0x02, 0xdc, 0x0d, 0x00, 0x02, 0x90, 0x3e, 0x01, 0x02, + 0x94, 0x3e, 0x01, 0x02, 0x98, 0x3e, 0x01, 0x02, 0x9c, 0x3e, 0x01, 0x02, 0xa0, 0x3e, 0x01, 0x02, 0xa4, 0x3e, 0x01, 0x02, 0xa8, 0x3e, 0x01, 0x02, 0x54, 0x14, 0x02, 0x02, 0x58, 0x14, 0x02, 0x02, + 0x5c, 0x14, 0x02, 0x02, 0x60, 0x14, 0x02, 0x02, 0xf0, 0x2f, 0x03, 0x03, 0xf8, 0x2f, 0x03, 0x03, 0x00, 0x30, 0x03, 0x03, 0x58, 0x0a, 0x04, 0x03, 0x60, 0x0a, 0x04, 0x03, 0x90, 0x23, 0x05, 0x04, + 0xa0, 0x23, 0x05, 0x04, 0xa0, 0x15, 0x07, 0x05, 0x40, 0x0d, 0x09, 0x06, 0xe0, 0x0d, 0x00, 0x02, 0xe4, 0x0d, 0x00, 0x02, 0xe8, 0x0d, 0x00, 0x02, 0xec, 0x0d, 0x00, 0x02, 0xac, 0x3e, 0x01, 0x02, + 0xb0, 0x3e, 0x01, 0x02, 0xb4, 0x3e, 0x01, 0x02, 0xb8, 0x3e, 0x01, 0x02, 0xbc, 0x3e, 0x01, 0x02, 0xc0, 0x3e, 0x01, 0x02, 0xc4, 0x3e, 0x01, 0x02, 0x64, 0x14, 0x02, 0x02, 0x68, 0x14, 0x02, 0x02, + 0x6c, 0x14, 0x02, 0x02, 0x70, 0x14, 0x02, 0x02, 0x08, 0x30, 0x03, 0x03, 0x10, 0x30, 0x03, 0x03, 0x18, 0x30, 0x03, 0x03, 0x68, 0x0a, 0x04, 0x03, 0x70, 0x0a, 0x04, 0x03, 0xb0, 0x23, 0x05, 0x04, + 0xc0, 0x23, 0x05, 0x04, 0xc0, 0x15, 0x07, 0x05, 0x80, 0x0d, 0x09, 0x06, 0xf0, 0x0d, 0x00, 0x02, 0xf4, 0x0d, 0x00, 0x02, 0xf8, 0x0d, 0x00, 0x02, 0xfc, 0x0d, 0x00, 0x02, 0xc8, 0x3e, 0x01, 0x02, + 0xcc, 0x3e, 0x01, 0x02, 0xd0, 0x3e, 0x01, 0x02, 0xd4, 0x3e, 0x01, 0x02, 0xd8, 0x3e, 0x01, 0x02, 0xdc, 0x3e, 0x01, 0x02, 0xe0, 0x3e, 0x01, 0x02, 0x74, 0x14, 0x02, 0x02, 0x78, 0x14, 0x02, 0x02, + 0x7c, 0x14, 0x02, 0x02, 0x80, 0x14, 0x02, 0x02, 0x20, 0x30, 0x03, 0x03, 0x28, 0x30, 0x03, 0x03, 0x30, 0x30, 0x03, 0x03, 0x78, 0x0a, 0x04, 0x03, 0x80, 0x0a, 0x04, 0x03, 0xd0, 0x23, 0x05, 0x04, + 0xe0, 0x23, 0x05, 0x04, 0xe0, 0x15, 0x07, 0x05, 0xc0, 0x0d, 0x09, 0x06, 0x00, 0x0e, 0x00, 0x02, 0x04, 0x0e, 0x00, 0x02, 0x08, 0x0e, 0x00, 0x02, 0x0c, 0x0e, 0x00, 0x02, 0xe4, 0x3e, 0x01, 0x02, + 0xe8, 0x3e, 0x01, 0x02, 0xec, 0x3e, 0x01, 0x02, 0xf0, 0x3e, 0x01, 0x02, 0xf4, 0x3e, 0x01, 0x02, 0xf8, 0x3e, 0x01, 0x02, 0xfc, 0x3e, 0x01, 0x02, 0x84, 0x14, 0x02, 0x02, 0x88, 0x14, 0x02, 0x02, + 0x8c, 0x14, 0x02, 0x02, 0x90, 0x14, 0x02, 0x02, 0x38, 0x30, 0x03, 0x03, 0x40, 0x30, 0x03, 0x03, 0x48, 0x30, 0x03, 0x03, 0x88, 0x0a, 0x04, 0x03, 0x90, 0x0a, 0x04, 0x03, 0xf0, 0x23, 0x05, 0x04, + 0x00, 0x24, 0x05, 0x04, 0x00, 0x16, 0x07, 0x05, 0x00, 0x0e, 0x09, 0x06, 0x10, 0x0e, 0x00, 0x02, 0x14, 0x0e, 0x00, 0x02, 0x18, 0x0e, 0x00, 0x02, 0x1c, 0x0e, 0x00, 0x02, 0x00, 0x3f, 0x01, 0x02, + 0x04, 0x3f, 0x01, 0x02, 0x08, 0x3f, 0x01, 0x02, 0x0c, 0x3f, 0x01, 0x02, 0x10, 0x3f, 0x01, 0x02, 0x14, 0x3f, 0x01, 0x02, 0x18, 0x3f, 0x01, 0x02, 0x94, 0x14, 0x02, 0x02, 0x98, 0x14, 0x02, 0x02, + 0x9c, 0x14, 0x02, 0x02, 0xa0, 0x14, 0x02, 0x02, 0x50, 0x30, 0x03, 0x03, 0x58, 0x30, 0x03, 0x03, 0x60, 0x30, 0x03, 0x03, 0x98, 0x0a, 0x04, 0x03, 0xa0, 0x0a, 0x04, 0x03, 0x10, 0x24, 0x05, 0x04, + 0x20, 0x24, 0x05, 0x04, 0x20, 0x16, 0x07, 0x05, 0x40, 0x0e, 0x09, 0x06, 0x20, 0x0e, 0x00, 0x02, 0x24, 0x0e, 0x00, 0x02, 0x28, 0x0e, 0x00, 0x02, 0x2c, 0x0e, 0x00, 0x02, 0x1c, 0x3f, 0x01, 0x02, + 0x20, 0x3f, 0x01, 0x02, 0x24, 0x3f, 0x01, 0x02, 0x28, 0x3f, 0x01, 0x02, 0x2c, 0x3f, 0x01, 0x02, 0x30, 0x3f, 0x01, 0x02, 0x34, 0x3f, 0x01, 0x02, 0xa4, 0x14, 0x02, 0x02, 0xa8, 0x14, 0x02, 0x02, + 0xac, 0x14, 0x02, 0x02, 0xb0, 0x14, 0x02, 0x02, 0x68, 0x30, 0x03, 0x03, 0x70, 0x30, 0x03, 0x03, 0x78, 0x30, 0x03, 0x03, 0xa8, 0x0a, 0x04, 0x03, 0xb0, 0x0a, 0x04, 0x03, 0x30, 0x24, 0x05, 0x04, + 0xb0, 0x01, 0x06, 0x04, 0x40, 0x16, 0x07, 0x05, 0x80, 0x0e, 0x09, 0x06, 0x30, 0x0e, 0x00, 0x02, 0x34, 0x0e, 0x00, 0x02, 0x38, 0x0e, 0x00, 0x02, 0x3c, 0x0e, 0x00, 0x02, 0x38, 0x3f, 0x01, 0x02, + 0x3c, 0x3f, 0x01, 0x02, 0x40, 0x3f, 0x01, 0x02, 0x44, 0x3f, 0x01, 0x02, 0x48, 0x3f, 0x01, 0x02, 0x4c, 0x3f, 0x01, 0x02, 0x50, 0x3f, 0x01, 0x02, 0xb4, 0x14, 0x02, 0x02, 0xb8, 0x14, 0x02, 0x02, + 0xbc, 0x14, 0x02, 0x02, 0xc0, 0x14, 0x02, 0x02, 0x80, 0x30, 0x03, 0x03, 0x88, 0x30, 0x03, 0x03, 0x90, 0x30, 0x03, 0x03, 0xb8, 0x0a, 0x04, 0x03, 0xc0, 0x0a, 0x04, 0x03, 0x40, 0x24, 0x05, 0x04, + 0xc0, 0x01, 0x06, 0x04, 0x60, 0x16, 0x07, 0x05, 0xc0, 0x0e, 0x09, 0x06, 0x40, 0x0e, 0x00, 0x02, 0x44, 0x0e, 0x00, 0x02, 0x48, 0x0e, 0x00, 0x02, 0x4c, 0x0e, 0x00, 0x02, 0x54, 0x3f, 0x01, 0x02, + 0x58, 0x3f, 0x01, 0x02, 0x5c, 0x3f, 0x01, 0x02, 0x60, 0x3f, 0x01, 0x02, 0x64, 0x3f, 0x01, 0x02, 0x68, 0x3f, 0x01, 0x02, 0x6c, 0x3f, 0x01, 0x02, 0xc4, 0x14, 0x02, 0x02, 0xc8, 0x14, 0x02, 0x02, + 0xcc, 0x14, 0x02, 0x02, 0xd0, 0x14, 0x02, 0x02, 0x98, 0x30, 0x03, 0x03, 0xa0, 0x30, 0x03, 0x03, 0xa8, 0x30, 0x03, 0x03, 0xc8, 0x0a, 0x04, 0x03, 0xd0, 0x0a, 0x04, 0x03, 0x50, 0x24, 0x05, 0x04, + 0xd0, 0x01, 0x06, 0x04, 0x80, 0x16, 0x07, 0x05, 0x00, 0x0f, 0x09, 0x06, 0x50, 0x0e, 0x00, 0x02, 0x54, 0x0e, 0x00, 0x02, 0x58, 0x0e, 0x00, 0x02, 0x5c, 0x0e, 0x00, 0x02, 0x70, 0x3f, 0x01, 0x02, + 0x74, 0x3f, 0x01, 0x02, 0x78, 0x3f, 0x01, 0x02, 0x7c, 0x3f, 0x01, 0x02, 0x80, 0x3f, 0x01, 0x02, 0x84, 0x3f, 0x01, 0x02, 0x88, 0x3f, 0x01, 0x02, 0xd4, 0x14, 0x02, 0x02, 0xd8, 0x14, 0x02, 0x02, + 0xdc, 0x14, 0x02, 0x02, 0xe0, 0x14, 0x02, 0x02, 0xb0, 0x30, 0x03, 0x03, 0xb8, 0x30, 0x03, 0x03, 0xc0, 0x30, 0x03, 0x03, 0xd8, 0x0a, 0x04, 0x03, 0xe0, 0x0a, 0x04, 0x03, 0x60, 0x24, 0x05, 0x04, + 0xe0, 0x01, 0x06, 0x04, 0xa0, 0x16, 0x07, 0x05, 0x40, 0x0f, 0x09, 0x06, 0x60, 0x0e, 0x00, 0x02, 0x64, 0x0e, 0x00, 0x02, 0x68, 0x0e, 0x00, 0x02, 0x6c, 0x0e, 0x00, 0x02, 0x8c, 0x3f, 0x01, 0x02, + 0x90, 0x3f, 0x01, 0x02, 0x94, 0x3f, 0x01, 0x02, 0x98, 0x3f, 0x01, 0x02, 0x9c, 0x3f, 0x01, 0x02, 0xa0, 0x3f, 0x01, 0x02, 0xa4, 0x3f, 0x01, 0x02, 0xe4, 0x14, 0x02, 0x02, 0xe8, 0x14, 0x02, 0x02, + 0xec, 0x14, 0x02, 0x02, 0xf0, 0x14, 0x02, 0x02, 0xc8, 0x30, 0x03, 0x03, 0xd0, 0x30, 0x03, 0x03, 0xd8, 0x30, 0x03, 0x03, 0xe8, 0x0a, 0x04, 0x03, 0xf0, 0x0a, 0x04, 0x03, 0x70, 0x24, 0x05, 0x04, + 0xf0, 0x01, 0x06, 0x04, 0xc0, 0x16, 0x07, 0x05, 0x80, 0x0f, 0x09, 0x06, 0x70, 0x0e, 0x00, 0x02, 0x74, 0x0e, 0x00, 0x02, 0x78, 0x0e, 0x00, 0x02, 0x7c, 0x0e, 0x00, 0x02, 0xa8, 0x3f, 0x01, 0x02, + 0xac, 0x3f, 0x01, 0x02, 0xb0, 0x3f, 0x01, 0x02, 0xb4, 0x3f, 0x01, 0x02, 0xb8, 0x3f, 0x01, 0x02, 0xbc, 0x3f, 0x01, 0x02, 0xc0, 0x3f, 0x01, 0x02, 0xf4, 0x14, 0x02, 0x02, 0xf8, 0x14, 0x02, 0x02, + 0xfc, 0x14, 0x02, 0x02, 0x00, 0x15, 0x02, 0x02, 0xe0, 0x30, 0x03, 0x03, 0xe8, 0x30, 0x03, 0x03, 0xf0, 0x30, 0x03, 0x03, 0xf8, 0x0a, 0x04, 0x03, 0x00, 0x0b, 0x04, 0x03, 0x80, 0x24, 0x05, 0x04, + 0x00, 0x02, 0x06, 0x04, 0xe0, 0x16, 0x07, 0x05, 0xc0, 0x0f, 0x09, 0x06, 0x80, 0x0e, 0x00, 0x02, 0x84, 0x0e, 0x00, 0x02, 0x88, 0x0e, 0x00, 0x02, 0x8c, 0x0e, 0x00, 0x02, 0xc4, 0x3f, 0x01, 0x02, + 0xc8, 0x3f, 0x01, 0x02, 0xcc, 0x3f, 0x01, 0x02, 0xd0, 0x3f, 0x01, 0x02, 0xd4, 0x3f, 0x01, 0x02, 0xd8, 0x3f, 0x01, 0x02, 0xdc, 0x3f, 0x01, 0x02, 0x04, 0x15, 0x02, 0x02, 0x08, 0x15, 0x02, 0x02, + 0x0c, 0x15, 0x02, 0x02, 0x10, 0x15, 0x02, 0x02, 0xf8, 0x30, 0x03, 0x03, 0x00, 0x31, 0x03, 0x03, 0x08, 0x31, 0x03, 0x03, 0x08, 0x0b, 0x04, 0x03, 0x10, 0x0b, 0x04, 0x03, 0x90, 0x24, 0x05, 0x04, + 0x10, 0x02, 0x06, 0x04, 0x00, 0x17, 0x07, 0x05, 0x00, 0x10, 0x09, 0x06, 0x90, 0x0e, 0x00, 0x02, 0x94, 0x0e, 0x00, 0x02, 0x98, 0x0e, 0x00, 0x02, 0x9c, 0x0e, 0x00, 0x02, 0xe0, 0x3f, 0x01, 0x02, + 0xe4, 0x3f, 0x01, 0x02, 0xe8, 0x3f, 0x01, 0x02, 0xec, 0x3f, 0x01, 0x02, 0xf0, 0x3f, 0x01, 0x02, 0xf4, 0x3f, 0x01, 0x02, 0xf8, 0x3f, 0x01, 0x02, 0x14, 0x15, 0x02, 0x02, 0x18, 0x15, 0x02, 0x02, + 0x1c, 0x15, 0x02, 0x02, 0x20, 0x15, 0x02, 0x02, 0x10, 0x31, 0x03, 0x03, 0x18, 0x31, 0x03, 0x03, 0x20, 0x31, 0x03, 0x03, 0x18, 0x0b, 0x04, 0x03, 0x20, 0x0b, 0x04, 0x03, 0xa0, 0x24, 0x05, 0x04, + 0x20, 0x02, 0x06, 0x04, 0x20, 0x17, 0x07, 0x05, 0x00, 0x24, 0x0a, 0x07, 0xa0, 0x0e, 0x00, 0x02, 0xa4, 0x0e, 0x00, 0x02, 0xa8, 0x0e, 0x00, 0x02, 0xac, 0x0e, 0x00, 0x02, 0xfc, 0x3f, 0x01, 0x02, + 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x01, 0x08, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x01, 0x24, 0x15, 0x02, 0x02, 0x28, 0x15, 0x02, 0x02, + 0x2c, 0x15, 0x02, 0x02, 0x30, 0x15, 0x02, 0x02, 0x28, 0x31, 0x03, 0x03, 0x30, 0x31, 0x03, 0x03, 0x38, 0x31, 0x03, 0x03, 0x28, 0x0b, 0x04, 0x03, 0x30, 0x0b, 0x04, 0x03, 0xb0, 0x24, 0x05, 0x04, + 0x30, 0x02, 0x06, 0x04, 0x40, 0x17, 0x07, 0x05, 0x80, 0x24, 0x0a, 0x07, 0xb0, 0x0e, 0x00, 0x02, 0xb4, 0x0e, 0x00, 0x02, 0xb8, 0x0e, 0x00, 0x02, 0xbc, 0x0e, 0x00, 0x02, 0x0c, 0x00, 0x01, 0x01, + 0x0e, 0x00, 0x01, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x00, 0x01, 0x01, 0x14, 0x00, 0x01, 0x01, 0x16, 0x00, 0x01, 0x01, 0x18, 0x00, 0x01, 0x01, 0x34, 0x15, 0x02, 0x02, 0x38, 0x15, 0x02, 0x02, + 0x3c, 0x15, 0x02, 0x02, 0x40, 0x15, 0x02, 0x02, 0x40, 0x31, 0x03, 0x03, 0x48, 0x31, 0x03, 0x03, 0x50, 0x31, 0x03, 0x03, 0x38, 0x0b, 0x04, 0x03, 0x40, 0x0b, 0x04, 0x03, 0xc0, 0x24, 0x05, 0x04, + 0x40, 0x02, 0x06, 0x04, 0x60, 0x17, 0x07, 0x05, 0x00, 0x25, 0x0a, 0x07, 0xc0, 0x0e, 0x00, 0x02, 0xc4, 0x0e, 0x00, 0x02, 0xc8, 0x0e, 0x00, 0x02, 0xcc, 0x0e, 0x00, 0x02, 0x1a, 0x00, 0x01, 0x01, + 0x1c, 0x00, 0x01, 0x01, 0x1e, 0x00, 0x01, 0x01, 0x20, 0x00, 0x01, 0x01, 0x22, 0x00, 0x01, 0x01, 0x24, 0x00, 0x01, 0x01, 0x26, 0x00, 0x01, 0x01, 0x44, 0x15, 0x02, 0x02, 0x48, 0x15, 0x02, 0x02, + 0x4c, 0x15, 0x02, 0x02, 0x50, 0x15, 0x02, 0x02, 0x58, 0x31, 0x03, 0x03, 0x60, 0x31, 0x03, 0x03, 0x68, 0x31, 0x03, 0x03, 0x48, 0x0b, 0x04, 0x03, 0x50, 0x0b, 0x04, 0x03, 0xd0, 0x24, 0x05, 0x04, + 0x50, 0x02, 0x06, 0x04, 0x80, 0x17, 0x07, 0x05, 0x80, 0x25, 0x0a, 0x07, 0xd0, 0x0e, 0x00, 0x02, 0xd4, 0x0e, 0x00, 0x02, 0xd8, 0x0e, 0x00, 0x02, 0xdc, 0x0e, 0x00, 0x02, 0x28, 0x00, 0x01, 0x01, + 0x2a, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x01, 0x01, 0x2e, 0x00, 0x01, 0x01, 0x30, 0x00, 0x01, 0x01, 0x32, 0x00, 0x01, 0x01, 0x34, 0x00, 0x01, 0x01, 0x54, 0x15, 0x02, 0x02, 0x58, 0x15, 0x02, 0x02, + 0x5c, 0x15, 0x02, 0x02, 0x60, 0x15, 0x02, 0x02, 0x70, 0x31, 0x03, 0x03, 0x78, 0x31, 0x03, 0x03, 0x80, 0x31, 0x03, 0x03, 0x58, 0x0b, 0x04, 0x03, 0x60, 0x0b, 0x04, 0x03, 0xe0, 0x24, 0x05, 0x04, + 0x60, 0x02, 0x06, 0x04, 0xa0, 0x17, 0x07, 0x05, 0x00, 0x26, 0x0a, 0x07, 0xe0, 0x0e, 0x00, 0x02, 0xe4, 0x0e, 0x00, 0x02, 0xe8, 0x0e, 0x00, 0x02, 0xec, 0x0e, 0x00, 0x02, 0x36, 0x00, 0x01, 0x01, + 0x38, 0x00, 0x01, 0x01, 0x3a, 0x00, 0x01, 0x01, 0x3c, 0x00, 0x01, 0x01, 0x3e, 0x00, 0x01, 0x01, 0x40, 0x00, 0x01, 0x01, 0x42, 0x00, 0x01, 0x01, 0x64, 0x15, 0x02, 0x02, 0x68, 0x15, 0x02, 0x02, + 0x6c, 0x15, 0x02, 0x02, 0x70, 0x15, 0x02, 0x02, 0x88, 0x31, 0x03, 0x03, 0x90, 0x31, 0x03, 0x03, 0x98, 0x31, 0x03, 0x03, 0x68, 0x0b, 0x04, 0x03, 0x70, 0x0b, 0x04, 0x03, 0xf0, 0x24, 0x05, 0x04, + 0x70, 0x02, 0x06, 0x04, 0xc0, 0x17, 0x07, 0x05, 0x80, 0x26, 0x0a, 0x07, 0xf0, 0x0e, 0x00, 0x02, 0xf4, 0x0e, 0x00, 0x02, 0xf8, 0x0e, 0x00, 0x02, 0xfc, 0x0e, 0x00, 0x02, 0x44, 0x00, 0x01, 0x01, + 0x46, 0x00, 0x01, 0x01, 0x48, 0x00, 0x01, 0x01, 0x4a, 0x00, 0x01, 0x01, 0x4c, 0x00, 0x01, 0x01, 0x4e, 0x00, 0x01, 0x01, 0x50, 0x00, 0x01, 0x01, 0x74, 0x15, 0x02, 0x02, 0x78, 0x15, 0x02, 0x02, + 0x7c, 0x15, 0x02, 0x02, 0x80, 0x15, 0x02, 0x02, 0xa0, 0x31, 0x03, 0x03, 0xa8, 0x31, 0x03, 0x03, 0xb0, 0x31, 0x03, 0x03, 0x78, 0x0b, 0x04, 0x03, 0x80, 0x0b, 0x04, 0x03, 0x00, 0x25, 0x05, 0x04, + 0x80, 0x02, 0x06, 0x04, 0xe0, 0x17, 0x07, 0x05, 0x00, 0x27, 0x0a, 0x07, 0x00, 0x0f, 0x00, 0x02, 0x04, 0x0f, 0x00, 0x02, 0x08, 0x0f, 0x00, 0x02, 0x0c, 0x0f, 0x00, 0x02, 0x52, 0x00, 0x01, 0x01, + 0x54, 0x00, 0x01, 0x01, 0x56, 0x00, 0x01, 0x01, 0x58, 0x00, 0x01, 0x01, 0x5a, 0x00, 0x01, 0x01, 0x5c, 0x00, 0x01, 0x01, 0x5e, 0x00, 0x01, 0x01, 0x84, 0x15, 0x02, 0x02, 0x88, 0x15, 0x02, 0x02, + 0x8c, 0x15, 0x02, 0x02, 0x90, 0x15, 0x02, 0x02, 0xb8, 0x31, 0x03, 0x03, 0xc0, 0x31, 0x03, 0x03, 0xc8, 0x31, 0x03, 0x03, 0x88, 0x0b, 0x04, 0x03, 0x90, 0x0b, 0x04, 0x03, 0x10, 0x25, 0x05, 0x04, + 0x90, 0x02, 0x06, 0x04, 0x00, 0x18, 0x07, 0x05, 0x80, 0x27, 0x0a, 0x07, 0x10, 0x0f, 0x00, 0x02, 0x14, 0x0f, 0x00, 0x02, 0x18, 0x0f, 0x00, 0x02, 0x1c, 0x0f, 0x00, 0x02, 0x60, 0x00, 0x01, 0x01, + 0x62, 0x00, 0x01, 0x01, 0x64, 0x00, 0x01, 0x01, 0x66, 0x00, 0x01, 0x01, 0x68, 0x00, 0x01, 0x01, 0x6a, 0x00, 0x01, 0x01, 0x6c, 0x00, 0x01, 0x01, 0x94, 0x15, 0x02, 0x02, 0x98, 0x15, 0x02, 0x02, + 0x9c, 0x15, 0x02, 0x02, 0xa0, 0x15, 0x02, 0x02, 0xd0, 0x31, 0x03, 0x03, 0xd8, 0x31, 0x03, 0x03, 0xe0, 0x31, 0x03, 0x03, 0x98, 0x0b, 0x04, 0x03, 0xa0, 0x0b, 0x04, 0x03, 0x20, 0x25, 0x05, 0x04, + 0xa0, 0x02, 0x06, 0x04, 0x20, 0x18, 0x07, 0x05, 0x00, 0x28, 0x0a, 0x07, 0x20, 0x0f, 0x00, 0x02, 0x24, 0x0f, 0x00, 0x02, 0x28, 0x0f, 0x00, 0x02, 0x2c, 0x0f, 0x00, 0x02, 0x6e, 0x00, 0x01, 0x01, + 0x70, 0x00, 0x01, 0x01, 0x72, 0x00, 0x01, 0x01, 0x74, 0x00, 0x01, 0x01, 0x76, 0x00, 0x01, 0x01, 0x78, 0x00, 0x01, 0x01, 0x7a, 0x00, 0x01, 0x01, 0xa4, 0x15, 0x02, 0x02, 0xa8, 0x15, 0x02, 0x02, + 0xac, 0x15, 0x02, 0x02, 0xb0, 0x15, 0x02, 0x02, 0xe8, 0x31, 0x03, 0x03, 0xf0, 0x31, 0x03, 0x03, 0xf8, 0x31, 0x03, 0x03, 0xa8, 0x0b, 0x04, 0x03, 0xb0, 0x0b, 0x04, 0x03, 0x30, 0x25, 0x05, 0x04, + 0xb0, 0x02, 0x06, 0x04, 0x40, 0x18, 0x07, 0x05, 0x80, 0x28, 0x0a, 0x07, 0x30, 0x0f, 0x00, 0x02, 0x34, 0x0f, 0x00, 0x02, 0x38, 0x0f, 0x00, 0x02, 0x3c, 0x0f, 0x00, 0x02, 0x7c, 0x00, 0x01, 0x01, + 0x7e, 0x00, 0x01, 0x01, 0x80, 0x00, 0x01, 0x01, 0x82, 0x00, 0x01, 0x01, 0x84, 0x00, 0x01, 0x01, 0x86, 0x00, 0x01, 0x01, 0x88, 0x00, 0x01, 0x01, 0xb4, 0x15, 0x02, 0x02, 0xb8, 0x15, 0x02, 0x02, + 0xbc, 0x15, 0x02, 0x02, 0xc0, 0x15, 0x02, 0x02, 0x00, 0x32, 0x03, 0x03, 0x08, 0x32, 0x03, 0x03, 0x10, 0x32, 0x03, 0x03, 0xb8, 0x0b, 0x04, 0x03, 0xc0, 0x0b, 0x04, 0x03, 0x40, 0x25, 0x05, 0x04, + 0xc0, 0x02, 0x06, 0x04, 0x60, 0x18, 0x07, 0x05, 0x00, 0x29, 0x0a, 0x07, 0x40, 0x0f, 0x00, 0x02, 0x44, 0x0f, 0x00, 0x02, 0x48, 0x0f, 0x00, 0x02, 0x4c, 0x0f, 0x00, 0x02, 0x8a, 0x00, 0x01, 0x01, + 0x8c, 0x00, 0x01, 0x01, 0x8e, 0x00, 0x01, 0x01, 0x90, 0x00, 0x01, 0x01, 0x92, 0x00, 0x01, 0x01, 0x94, 0x00, 0x01, 0x01, 0x96, 0x00, 0x01, 0x01, 0xc4, 0x15, 0x02, 0x02, 0xc8, 0x15, 0x02, 0x02, + 0xcc, 0x15, 0x02, 0x02, 0xd0, 0x15, 0x02, 0x02, 0x18, 0x32, 0x03, 0x03, 0x20, 0x32, 0x03, 0x03, 0x28, 0x32, 0x03, 0x03, 0xc8, 0x0b, 0x04, 0x03, 0xd0, 0x0b, 0x04, 0x03, 0x50, 0x25, 0x05, 0x04, + 0xd0, 0x02, 0x06, 0x04, 0x80, 0x18, 0x07, 0x05, 0x80, 0x29, 0x0a, 0x07, 0x50, 0x0f, 0x00, 0x02, 0x54, 0x0f, 0x00, 0x02, 0x58, 0x0f, 0x00, 0x02, 0x5c, 0x0f, 0x00, 0x02, 0x98, 0x00, 0x01, 0x01, + 0x9a, 0x00, 0x01, 0x01, 0x9c, 0x00, 0x01, 0x01, 0x9e, 0x00, 0x01, 0x01, 0xa0, 0x00, 0x01, 0x01, 0xa2, 0x00, 0x01, 0x01, 0xa4, 0x00, 0x01, 0x01, 0xd4, 0x15, 0x02, 0x02, 0xd8, 0x15, 0x02, 0x02, + 0xdc, 0x15, 0x02, 0x02, 0xe0, 0x15, 0x02, 0x02, 0x30, 0x32, 0x03, 0x03, 0x38, 0x32, 0x03, 0x03, 0x40, 0x32, 0x03, 0x03, 0xd8, 0x0b, 0x04, 0x03, 0xe0, 0x0b, 0x04, 0x03, 0x60, 0x25, 0x05, 0x04, + 0xe0, 0x02, 0x06, 0x04, 0xa0, 0x18, 0x07, 0x05, 0x00, 0x2a, 0x0a, 0x07, 0x60, 0x0f, 0x00, 0x02, 0x64, 0x0f, 0x00, 0x02, 0x68, 0x0f, 0x00, 0x02, 0x6c, 0x0f, 0x00, 0x02, 0xa6, 0x00, 0x01, 0x01, + 0xa8, 0x00, 0x01, 0x01, 0xaa, 0x00, 0x01, 0x01, 0xac, 0x00, 0x01, 0x01, 0xae, 0x00, 0x01, 0x01, 0xb0, 0x00, 0x01, 0x01, 0xb2, 0x00, 0x01, 0x01, 0xe4, 0x15, 0x02, 0x02, 0xe8, 0x15, 0x02, 0x02, + 0xec, 0x15, 0x02, 0x02, 0xf0, 0x15, 0x02, 0x02, 0x48, 0x32, 0x03, 0x03, 0x50, 0x32, 0x03, 0x03, 0x58, 0x32, 0x03, 0x03, 0xe8, 0x0b, 0x04, 0x03, 0xf0, 0x0b, 0x04, 0x03, 0x70, 0x25, 0x05, 0x04, + 0xf0, 0x02, 0x06, 0x04, 0xc0, 0x18, 0x07, 0x05, 0x80, 0x2a, 0x0a, 0x07, 0x70, 0x0f, 0x00, 0x02, 0x74, 0x0f, 0x00, 0x02, 0x78, 0x0f, 0x00, 0x02, 0x7c, 0x0f, 0x00, 0x02, 0xb4, 0x00, 0x01, 0x01, + 0xb6, 0x00, 0x01, 0x01, 0xb8, 0x00, 0x01, 0x01, 0xba, 0x00, 0x01, 0x01, 0xbc, 0x00, 0x01, 0x01, 0xbe, 0x00, 0x01, 0x01, 0xc0, 0x00, 0x01, 0x01, 0xf4, 0x15, 0x02, 0x02, 0xf8, 0x15, 0x02, 0x02, + 0xfc, 0x15, 0x02, 0x02, 0x00, 0x16, 0x02, 0x02, 0x60, 0x32, 0x03, 0x03, 0x68, 0x32, 0x03, 0x03, 0x70, 0x32, 0x03, 0x03, 0xf8, 0x0b, 0x04, 0x03, 0x00, 0x0c, 0x04, 0x03, 0x80, 0x25, 0x05, 0x04, + 0x00, 0x03, 0x06, 0x04, 0xe0, 0x18, 0x07, 0x05, 0x00, 0x02, 0x0b, 0x07, 0x80, 0x0f, 0x00, 0x02, 0x84, 0x0f, 0x00, 0x02, 0x88, 0x0f, 0x00, 0x02, 0x8c, 0x0f, 0x00, 0x02, 0xc2, 0x00, 0x01, 0x01, + 0xc4, 0x00, 0x01, 0x01, 0xc6, 0x00, 0x01, 0x01, 0xc8, 0x00, 0x01, 0x01, 0xca, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x01, 0x01, 0xce, 0x00, 0x01, 0x01, 0x04, 0x16, 0x02, 0x02, 0x08, 0x16, 0x02, 0x02, + 0x0c, 0x16, 0x02, 0x02, 0x10, 0x16, 0x02, 0x02, 0x78, 0x32, 0x03, 0x03, 0x80, 0x32, 0x03, 0x03, 0x88, 0x32, 0x03, 0x03, 0x08, 0x0c, 0x04, 0x03, 0x10, 0x0c, 0x04, 0x03, 0x90, 0x25, 0x05, 0x04, + 0x10, 0x03, 0x06, 0x04, 0x00, 0x19, 0x07, 0x05, 0x80, 0x02, 0x0b, 0x07, 0x90, 0x0f, 0x00, 0x02, 0x94, 0x0f, 0x00, 0x02, 0x98, 0x0f, 0x00, 0x02, 0x9c, 0x0f, 0x00, 0x02, 0xd0, 0x00, 0x01, 0x01, + 0xd2, 0x00, 0x01, 0x01, 0xd4, 0x00, 0x01, 0x01, 0xd6, 0x00, 0x01, 0x01, 0xd8, 0x00, 0x01, 0x01, 0xda, 0x00, 0x01, 0x01, 0xdc, 0x00, 0x01, 0x01, 0x14, 0x16, 0x02, 0x02, 0x18, 0x16, 0x02, 0x02, + 0x1c, 0x16, 0x02, 0x02, 0x20, 0x16, 0x02, 0x02, 0x90, 0x32, 0x03, 0x03, 0x98, 0x32, 0x03, 0x03, 0xa0, 0x32, 0x03, 0x03, 0x18, 0x0c, 0x04, 0x03, 0x20, 0x0c, 0x04, 0x03, 0xa0, 0x25, 0x05, 0x04, + 0x20, 0x03, 0x06, 0x04, 0x20, 0x19, 0x07, 0x05, 0x00, 0x03, 0x0b, 0x07, 0xa0, 0x0f, 0x00, 0x02, 0xa4, 0x0f, 0x00, 0x02, 0xa8, 0x0f, 0x00, 0x02, 0xac, 0x0f, 0x00, 0x02, 0xde, 0x00, 0x01, 0x01, + 0xe0, 0x00, 0x01, 0x01, 0xe2, 0x00, 0x01, 0x01, 0xe4, 0x00, 0x01, 0x01, 0xe6, 0x00, 0x01, 0x01, 0xe8, 0x00, 0x01, 0x01, 0xea, 0x00, 0x01, 0x01, 0x24, 0x16, 0x02, 0x02, 0x28, 0x16, 0x02, 0x02, + 0x2c, 0x16, 0x02, 0x02, 0x30, 0x16, 0x02, 0x02, 0xa8, 0x32, 0x03, 0x03, 0xb0, 0x32, 0x03, 0x03, 0xb8, 0x32, 0x03, 0x03, 0x28, 0x0c, 0x04, 0x03, 0x30, 0x0c, 0x04, 0x03, 0xb0, 0x25, 0x05, 0x04, + 0x30, 0x03, 0x06, 0x04, 0x40, 0x19, 0x07, 0x05, 0x80, 0x03, 0x0b, 0x07, 0xb0, 0x0f, 0x00, 0x02, 0xb4, 0x0f, 0x00, 0x02, 0xb8, 0x0f, 0x00, 0x02, 0xbc, 0x0f, 0x00, 0x02, 0xec, 0x00, 0x01, 0x01, + 0xee, 0x00, 0x01, 0x01, 0xf0, 0x00, 0x01, 0x01, 0xf2, 0x00, 0x01, 0x01, 0xf4, 0x00, 0x01, 0x01, 0xf6, 0x00, 0x01, 0x01, 0xf8, 0x00, 0x01, 0x01, 0x34, 0x16, 0x02, 0x02, 0x38, 0x16, 0x02, 0x02, + 0x3c, 0x16, 0x02, 0x02, 0x40, 0x16, 0x02, 0x02, 0xc0, 0x32, 0x03, 0x03, 0xc8, 0x32, 0x03, 0x03, 0xd0, 0x32, 0x03, 0x03, 0x38, 0x0c, 0x04, 0x03, 0x40, 0x0c, 0x04, 0x03, 0xc0, 0x25, 0x05, 0x04, + 0x40, 0x03, 0x06, 0x04, 0x60, 0x19, 0x07, 0x05, 0x00, 0x04, 0x0b, 0x07, 0xc0, 0x0f, 0x00, 0x02, 0xc4, 0x0f, 0x00, 0x02, 0xc8, 0x0f, 0x00, 0x02, 0xcc, 0x0f, 0x00, 0x02, 0xfa, 0x00, 0x01, 0x01, + 0xfc, 0x00, 0x01, 0x01, 0xfe, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x06, 0x01, 0x01, 0x01, 0x44, 0x16, 0x02, 0x02, 0x48, 0x16, 0x02, 0x02, + 0x4c, 0x16, 0x02, 0x02, 0x50, 0x16, 0x02, 0x02, 0xd8, 0x32, 0x03, 0x03, 0xe0, 0x32, 0x03, 0x03, 0xe8, 0x32, 0x03, 0x03, 0x48, 0x0c, 0x04, 0x03, 0x50, 0x0c, 0x04, 0x03, 0xd0, 0x25, 0x05, 0x04, + 0x50, 0x03, 0x06, 0x04, 0x80, 0x19, 0x07, 0x05, 0x80, 0x04, 0x0b, 0x07, 0xd0, 0x0f, 0x00, 0x02, 0xd4, 0x0f, 0x00, 0x02, 0xd8, 0x0f, 0x00, 0x02, 0xdc, 0x0f, 0x00, 0x02, 0x08, 0x01, 0x01, 0x01, + 0x0a, 0x01, 0x01, 0x01, 0x0c, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x14, 0x01, 0x01, 0x01, 0x54, 0x16, 0x02, 0x02, 0x58, 0x16, 0x02, 0x02, + 0x5c, 0x16, 0x02, 0x02, 0x60, 0x16, 0x02, 0x02, 0xf0, 0x32, 0x03, 0x03, 0xf8, 0x32, 0x03, 0x03, 0x00, 0x33, 0x03, 0x03, 0x58, 0x0c, 0x04, 0x03, 0x60, 0x0c, 0x04, 0x03, 0xe0, 0x25, 0x05, 0x04, + 0x60, 0x03, 0x06, 0x04, 0xa0, 0x19, 0x07, 0x05, 0x00, 0x05, 0x0b, 0x07, 0xe0, 0x0f, 0x00, 0x02, 0xe4, 0x0f, 0x00, 0x02, 0xe8, 0x0f, 0x00, 0x02, 0xec, 0x0f, 0x00, 0x02, 0x16, 0x01, 0x01, 0x01, + 0x18, 0x01, 0x01, 0x01, 0x1a, 0x01, 0x01, 0x01, 0x1c, 0x01, 0x01, 0x01, 0x1e, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x22, 0x01, 0x01, 0x01, 0x64, 0x16, 0x02, 0x02, 0x68, 0x16, 0x02, 0x02, + 0x6c, 0x16, 0x02, 0x02, 0x70, 0x16, 0x02, 0x02, 0x08, 0x33, 0x03, 0x03, 0x10, 0x33, 0x03, 0x03, 0x18, 0x33, 0x03, 0x03, 0x68, 0x0c, 0x04, 0x03, 0x70, 0x0c, 0x04, 0x03, 0xf0, 0x25, 0x05, 0x04, + 0x70, 0x03, 0x06, 0x04, 0xc0, 0x19, 0x07, 0x05, 0x80, 0x05, 0x0b, 0x07, 0xf0, 0x0f, 0x00, 0x02, 0xf4, 0x0f, 0x00, 0x02, 0xf8, 0x0f, 0x00, 0x02, 0xfc, 0x0f, 0x00, 0x02, 0x24, 0x01, 0x01, 0x01, + 0x26, 0x01, 0x01, 0x01, 0x28, 0x01, 0x01, 0x01, 0x2a, 0x01, 0x01, 0x01, 0x2c, 0x01, 0x01, 0x01, 0x2e, 0x01, 0x01, 0x01, 0x30, 0x01, 0x01, 0x01, 0x74, 0x16, 0x02, 0x02, 0x78, 0x16, 0x02, 0x02, + 0x7c, 0x16, 0x02, 0x02, 0x80, 0x16, 0x02, 0x02, 0x20, 0x33, 0x03, 0x03, 0x28, 0x33, 0x03, 0x03, 0x30, 0x33, 0x03, 0x03, 0x78, 0x0c, 0x04, 0x03, 0x80, 0x0c, 0x04, 0x03, 0x00, 0x26, 0x05, 0x04, + 0x80, 0x03, 0x06, 0x04, 0xe0, 0x19, 0x07, 0x05, 0x00, 0x06, 0x0b, 0x07, 0x00, 0x10, 0x00, 0x02, 0x04, 0x10, 0x00, 0x02, 0x08, 0x10, 0x00, 0x02, 0x0c, 0x10, 0x00, 0x02, 0x32, 0x01, 0x01, 0x01, + 0x34, 0x01, 0x01, 0x01, 0x36, 0x01, 0x01, 0x01, 0x38, 0x01, 0x01, 0x01, 0x3a, 0x01, 0x01, 0x01, 0x3c, 0x01, 0x01, 0x01, 0x84, 0x16, 0x02, 0x02, 0x88, 0x16, 0x02, 0x02, 0x8c, 0x16, 0x02, 0x02, + 0x90, 0x16, 0x02, 0x02, 0x94, 0x16, 0x02, 0x02, 0x38, 0x33, 0x03, 0x03, 0x40, 0x33, 0x03, 0x03, 0x48, 0x33, 0x03, 0x03, 0x88, 0x0c, 0x04, 0x03, 0x90, 0x0c, 0x04, 0x03, 0x10, 0x26, 0x05, 0x04, + 0x90, 0x03, 0x06, 0x04, 0x00, 0x1a, 0x07, 0x05, 0x80, 0x06, 0x0b, 0x07, 0x10, 0x10, 0x00, 0x02, 0x14, 0x10, 0x00, 0x02, 0x18, 0x10, 0x00, 0x02, 0x1c, 0x10, 0x00, 0x02, 0x3e, 0x01, 0x01, 0x01, + 0x40, 0x01, 0x01, 0x01, 0x42, 0x01, 0x01, 0x01, 0x44, 0x01, 0x01, 0x01, 0x46, 0x01, 0x01, 0x01, 0x48, 0x01, 0x01, 0x01, 0x98, 0x16, 0x02, 0x02, 0x9c, 0x16, 0x02, 0x02, 0xa0, 0x16, 0x02, 0x02, + 0xa4, 0x16, 0x02, 0x02, 0xa8, 0x16, 0x02, 0x02, 0x50, 0x33, 0x03, 0x03, 0x58, 0x33, 0x03, 0x03, 0x60, 0x33, 0x03, 0x03, 0x98, 0x0c, 0x04, 0x03, 0xa0, 0x0c, 0x04, 0x03, 0x20, 0x26, 0x05, 0x04, + 0xa0, 0x03, 0x06, 0x04, 0x20, 0x1a, 0x07, 0x05, 0x00, 0x18, 0x0c, 0x08, 0x20, 0x10, 0x00, 0x02, 0x24, 0x10, 0x00, 0x02, 0x28, 0x10, 0x00, 0x02, 0x2c, 0x10, 0x00, 0x02, 0x4a, 0x01, 0x01, 0x01, + 0x4c, 0x01, 0x01, 0x01, 0x4e, 0x01, 0x01, 0x01, 0x50, 0x01, 0x01, 0x01, 0x52, 0x01, 0x01, 0x01, 0x54, 0x01, 0x01, 0x01, 0xac, 0x16, 0x02, 0x02, 0xb0, 0x16, 0x02, 0x02, 0xb4, 0x16, 0x02, 0x02, + 0xb8, 0x16, 0x02, 0x02, 0xbc, 0x16, 0x02, 0x02, 0x68, 0x33, 0x03, 0x03, 0x70, 0x33, 0x03, 0x03, 0x78, 0x33, 0x03, 0x03, 0xa8, 0x0c, 0x04, 0x03, 0xb0, 0x0c, 0x04, 0x03, 0x30, 0x26, 0x05, 0x04, + 0xb0, 0x03, 0x06, 0x04, 0x40, 0x1a, 0x07, 0x05, 0x00, 0x19, 0x0c, 0x08, 0x30, 0x10, 0x00, 0x02, 0x34, 0x10, 0x00, 0x02, 0x38, 0x10, 0x00, 0x02, 0x3c, 0x10, 0x00, 0x02, 0x56, 0x01, 0x01, 0x01, + 0x58, 0x01, 0x01, 0x01, 0x5a, 0x01, 0x01, 0x01, 0x5c, 0x01, 0x01, 0x01, 0x5e, 0x01, 0x01, 0x01, 0x60, 0x01, 0x01, 0x01, 0xc0, 0x16, 0x02, 0x02, 0xc4, 0x16, 0x02, 0x02, 0xc8, 0x16, 0x02, 0x02, + 0xcc, 0x16, 0x02, 0x02, 0xd0, 0x16, 0x02, 0x02, 0x80, 0x33, 0x03, 0x03, 0x88, 0x33, 0x03, 0x03, 0x90, 0x33, 0x03, 0x03, 0xb8, 0x0c, 0x04, 0x03, 0xc0, 0x0c, 0x04, 0x03, 0x40, 0x26, 0x05, 0x04, + 0xc0, 0x03, 0x06, 0x04, 0x60, 0x1a, 0x07, 0x05, 0x00, 0x1a, 0x0c, 0x08, 0x40, 0x10, 0x00, 0x02, 0x44, 0x10, 0x00, 0x02, 0x48, 0x10, 0x00, 0x02, 0x4c, 0x10, 0x00, 0x02, 0x62, 0x01, 0x01, 0x01, + 0x64, 0x01, 0x01, 0x01, 0x66, 0x01, 0x01, 0x01, 0x68, 0x01, 0x01, 0x01, 0x6a, 0x01, 0x01, 0x01, 0x6c, 0x01, 0x01, 0x01, 0xd4, 0x16, 0x02, 0x02, 0xd8, 0x16, 0x02, 0x02, 0xdc, 0x16, 0x02, 0x02, + 0xe0, 0x16, 0x02, 0x02, 0xe4, 0x16, 0x02, 0x02, 0x98, 0x33, 0x03, 0x03, 0xa0, 0x33, 0x03, 0x03, 0xa8, 0x33, 0x03, 0x03, 0xc8, 0x0c, 0x04, 0x03, 0xd0, 0x0c, 0x04, 0x03, 0x50, 0x26, 0x05, 0x04, + 0xd0, 0x03, 0x06, 0x04, 0x80, 0x1a, 0x07, 0x05, 0x00, 0x1b, 0x0c, 0x08, 0x50, 0x10, 0x00, 0x02, 0x54, 0x10, 0x00, 0x02, 0x58, 0x10, 0x00, 0x02, 0x5c, 0x10, 0x00, 0x02, 0x6e, 0x01, 0x01, 0x01, + 0x70, 0x01, 0x01, 0x01, 0x72, 0x01, 0x01, 0x01, 0x74, 0x01, 0x01, 0x01, 0x76, 0x01, 0x01, 0x01, 0x78, 0x01, 0x01, 0x01, 0xe8, 0x16, 0x02, 0x02, 0xec, 0x16, 0x02, 0x02, 0xf0, 0x16, 0x02, 0x02, + 0xf4, 0x16, 0x02, 0x02, 0xf8, 0x16, 0x02, 0x02, 0xb0, 0x33, 0x03, 0x03, 0xb8, 0x33, 0x03, 0x03, 0xc0, 0x33, 0x03, 0x03, 0xd8, 0x0c, 0x04, 0x03, 0xe0, 0x0c, 0x04, 0x03, 0x60, 0x26, 0x05, 0x04, + 0xe0, 0x03, 0x06, 0x04, 0xa0, 0x1a, 0x07, 0x05, 0x00, 0x1c, 0x0c, 0x08, 0x60, 0x10, 0x00, 0x02, 0x64, 0x10, 0x00, 0x02, 0x68, 0x10, 0x00, 0x02, 0x6c, 0x10, 0x00, 0x02, 0x7a, 0x01, 0x01, 0x01, + 0x7c, 0x01, 0x01, 0x01, 0x7e, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x82, 0x01, 0x01, 0x01, 0x84, 0x01, 0x01, 0x01, 0xfc, 0x16, 0x02, 0x02, 0x00, 0x17, 0x02, 0x02, 0x04, 0x17, 0x02, 0x02, + 0x08, 0x17, 0x02, 0x02, 0x0c, 0x17, 0x02, 0x02, 0xc8, 0x33, 0x03, 0x03, 0xd0, 0x33, 0x03, 0x03, 0xd8, 0x33, 0x03, 0x03, 0xe8, 0x0c, 0x04, 0x03, 0xf0, 0x0c, 0x04, 0x03, 0x70, 0x26, 0x05, 0x04, + 0xf0, 0x03, 0x06, 0x04, 0xc0, 0x1a, 0x07, 0x05, 0x00, 0x1d, 0x0c, 0x08, 0x70, 0x10, 0x00, 0x02, 0x74, 0x10, 0x00, 0x02, 0x78, 0x10, 0x00, 0x02, 0x7c, 0x10, 0x00, 0x02, 0x86, 0x01, 0x01, 0x01, + 0x88, 0x01, 0x01, 0x01, 0x8a, 0x01, 0x01, 0x01, 0x8c, 0x01, 0x01, 0x01, 0x8e, 0x01, 0x01, 0x01, 0x90, 0x01, 0x01, 0x01, 0x10, 0x17, 0x02, 0x02, 0x14, 0x17, 0x02, 0x02, 0x18, 0x17, 0x02, 0x02, + 0x1c, 0x17, 0x02, 0x02, 0x20, 0x17, 0x02, 0x02, 0xe0, 0x33, 0x03, 0x03, 0xe8, 0x33, 0x03, 0x03, 0xf0, 0x33, 0x03, 0x03, 0xf8, 0x0c, 0x04, 0x03, 0x00, 0x0d, 0x04, 0x03, 0x80, 0x26, 0x05, 0x04, + 0x00, 0x04, 0x06, 0x04, 0xc0, 0x37, 0x08, 0x06, 0x00, 0x38, 0x0d, 0x09, 0x80, 0x10, 0x00, 0x02, 0x84, 0x10, 0x00, 0x02, 0x88, 0x10, 0x00, 0x02, 0x8c, 0x10, 0x00, 0x02, 0x92, 0x01, 0x01, 0x01, + 0x94, 0x01, 0x01, 0x01, 0x96, 0x01, 0x01, 0x01, 0x98, 0x01, 0x01, 0x01, 0x9a, 0x01, 0x01, 0x01, 0x9c, 0x01, 0x01, 0x01, 0x24, 0x17, 0x02, 0x02, 0x28, 0x17, 0x02, 0x02, 0x2c, 0x17, 0x02, 0x02, + 0x30, 0x17, 0x02, 0x02, 0x34, 0x17, 0x02, 0x02, 0xf8, 0x33, 0x03, 0x03, 0x00, 0x34, 0x03, 0x03, 0x08, 0x34, 0x03, 0x03, 0x08, 0x0d, 0x04, 0x03, 0x10, 0x0d, 0x04, 0x03, 0x90, 0x26, 0x05, 0x04, + 0x10, 0x04, 0x06, 0x04, 0x00, 0x38, 0x08, 0x06, 0x00, 0x3a, 0x0d, 0x09, 0x90, 0x10, 0x00, 0x02, 0x94, 0x10, 0x00, 0x02, 0x98, 0x10, 0x00, 0x02, 0x9c, 0x10, 0x00, 0x02, 0x9e, 0x01, 0x01, 0x01, + 0xa0, 0x01, 0x01, 0x01, 0xa2, 0x01, 0x01, 0x01, 0xa4, 0x01, 0x01, 0x01, 0xa6, 0x01, 0x01, 0x01, 0xa8, 0x01, 0x01, 0x01, 0x38, 0x17, 0x02, 0x02, 0x3c, 0x17, 0x02, 0x02, 0x40, 0x17, 0x02, 0x02, + 0x44, 0x17, 0x02, 0x02, 0x48, 0x17, 0x02, 0x02, 0x10, 0x34, 0x03, 0x03, 0x18, 0x34, 0x03, 0x03, 0x20, 0x34, 0x03, 0x03, 0x18, 0x0d, 0x04, 0x03, 0x20, 0x0d, 0x04, 0x03, 0xa0, 0x26, 0x05, 0x04, + 0x20, 0x04, 0x06, 0x04, 0x40, 0x38, 0x08, 0x06, 0x00, 0x3c, 0x0d, 0x09, 0xa0, 0x10, 0x00, 0x02, 0xa4, 0x10, 0x00, 0x02, 0xa8, 0x10, 0x00, 0x02, 0xac, 0x10, 0x00, 0x02, 0xaa, 0x01, 0x01, 0x01, + 0xac, 0x01, 0x01, 0x01, 0xae, 0x01, 0x01, 0x01, 0xb0, 0x01, 0x01, 0x01, 0xb2, 0x01, 0x01, 0x01, 0xb4, 0x01, 0x01, 0x01, 0x4c, 0x17, 0x02, 0x02, 0x50, 0x17, 0x02, 0x02, 0x54, 0x17, 0x02, 0x02, + 0x58, 0x17, 0x02, 0x02, 0x5c, 0x17, 0x02, 0x02, 0x28, 0x34, 0x03, 0x03, 0x30, 0x34, 0x03, 0x03, 0x38, 0x34, 0x03, 0x03, 0x28, 0x0d, 0x04, 0x03, 0x30, 0x0d, 0x04, 0x03, 0xb0, 0x26, 0x05, 0x04, + 0x30, 0x04, 0x06, 0x04, 0x80, 0x38, 0x08, 0x06, 0x00, 0x3e, 0x0d, 0x09, 0xb0, 0x10, 0x00, 0x02, 0xb4, 0x10, 0x00, 0x02, 0xb8, 0x10, 0x00, 0x02, 0xbc, 0x10, 0x00, 0x02, 0xb6, 0x01, 0x01, 0x01, + 0xb8, 0x01, 0x01, 0x01, 0xba, 0x01, 0x01, 0x01, 0xbc, 0x01, 0x01, 0x01, 0xbe, 0x01, 0x01, 0x01, 0xc0, 0x01, 0x01, 0x01, 0x60, 0x17, 0x02, 0x02, 0x64, 0x17, 0x02, 0x02, 0x68, 0x17, 0x02, 0x02, + 0x6c, 0x17, 0x02, 0x02, 0x70, 0x17, 0x02, 0x02, 0x40, 0x34, 0x03, 0x03, 0x48, 0x34, 0x03, 0x03, 0x50, 0x34, 0x03, 0x03, 0x38, 0x0d, 0x04, 0x03, 0x40, 0x0d, 0x04, 0x03, 0xc0, 0x26, 0x05, 0x04, + 0x40, 0x04, 0x06, 0x04, 0xc0, 0x38, 0x08, 0x06, 0x00, 0x12, 0x0e, 0x09, 0xc0, 0x10, 0x00, 0x02, 0xc4, 0x10, 0x00, 0x02, 0xc8, 0x10, 0x00, 0x02, 0xcc, 0x10, 0x00, 0x02, 0xc2, 0x01, 0x01, 0x01, + 0xc4, 0x01, 0x01, 0x01, 0xc6, 0x01, 0x01, 0x01, 0xc8, 0x01, 0x01, 0x01, 0xca, 0x01, 0x01, 0x01, 0xcc, 0x01, 0x01, 0x01, 0x74, 0x17, 0x02, 0x02, 0x78, 0x17, 0x02, 0x02, 0x7c, 0x17, 0x02, 0x02, + 0x80, 0x17, 0x02, 0x02, 0x84, 0x17, 0x02, 0x02, 0x58, 0x34, 0x03, 0x03, 0x60, 0x34, 0x03, 0x03, 0x68, 0x34, 0x03, 0x03, 0x48, 0x0d, 0x04, 0x03, 0x50, 0x0d, 0x04, 0x03, 0xd0, 0x26, 0x05, 0x04, + 0x50, 0x04, 0x06, 0x04, 0x00, 0x39, 0x08, 0x06, 0x00, 0x14, 0x0e, 0x09, 0xd0, 0x10, 0x00, 0x02, 0xd4, 0x10, 0x00, 0x02, 0xd8, 0x10, 0x00, 0x02, 0xdc, 0x10, 0x00, 0x02, 0xce, 0x01, 0x01, 0x01, + 0xd0, 0x01, 0x01, 0x01, 0xd2, 0x01, 0x01, 0x01, 0xd4, 0x01, 0x01, 0x01, 0xd6, 0x01, 0x01, 0x01, 0xd8, 0x01, 0x01, 0x01, 0x88, 0x17, 0x02, 0x02, 0x8c, 0x17, 0x02, 0x02, 0x90, 0x17, 0x02, 0x02, + 0x94, 0x17, 0x02, 0x02, 0x98, 0x17, 0x02, 0x02, 0x70, 0x34, 0x03, 0x03, 0x78, 0x34, 0x03, 0x03, 0x80, 0x34, 0x03, 0x03, 0x58, 0x0d, 0x04, 0x03, 0x60, 0x0d, 0x04, 0x03, 0xe0, 0x26, 0x05, 0x04, + 0x60, 0x04, 0x06, 0x04, 0x40, 0x39, 0x08, 0x06, 0x00, 0x16, 0x0e, 0x09, 0xe0, 0x10, 0x00, 0x02, 0xe4, 0x10, 0x00, 0x02, 0xe8, 0x10, 0x00, 0x02, 0xec, 0x10, 0x00, 0x02, 0xda, 0x01, 0x01, 0x01, + 0xdc, 0x01, 0x01, 0x01, 0xde, 0x01, 0x01, 0x01, 0xe0, 0x01, 0x01, 0x01, 0xe2, 0x01, 0x01, 0x01, 0xe4, 0x01, 0x01, 0x01, 0x9c, 0x17, 0x02, 0x02, 0xa0, 0x17, 0x02, 0x02, 0xa4, 0x17, 0x02, 0x02, + 0xa8, 0x17, 0x02, 0x02, 0xac, 0x17, 0x02, 0x02, 0x88, 0x34, 0x03, 0x03, 0x90, 0x34, 0x03, 0x03, 0x98, 0x34, 0x03, 0x03, 0x68, 0x0d, 0x04, 0x03, 0x70, 0x0d, 0x04, 0x03, 0xf0, 0x26, 0x05, 0x04, + 0x70, 0x04, 0x06, 0x04, 0x80, 0x39, 0x08, 0x06, 0x00, 0x30, 0x0f, 0x0a, 0xf0, 0x10, 0x00, 0x02, 0xf4, 0x10, 0x00, 0x02, 0xf8, 0x10, 0x00, 0x02, 0xfc, 0x10, 0x00, 0x02, 0xe6, 0x01, 0x01, 0x01, + 0xe8, 0x01, 0x01, 0x01, 0xea, 0x01, 0x01, 0x01, 0xec, 0x01, 0x01, 0x01, 0xee, 0x01, 0x01, 0x01, 0xf0, 0x01, 0x01, 0x01, 0xb0, 0x17, 0x02, 0x02, 0xb4, 0x17, 0x02, 0x02, 0xb8, 0x17, 0x02, 0x02, + 0xbc, 0x17, 0x02, 0x02, 0xc0, 0x17, 0x02, 0x02, 0xa0, 0x34, 0x03, 0x03, 0xa8, 0x34, 0x03, 0x03, 0xb0, 0x34, 0x03, 0x03, 0x78, 0x0d, 0x04, 0x03, 0x80, 0x0d, 0x04, 0x03, 0x00, 0x27, 0x05, 0x04, + 0x80, 0x04, 0x06, 0x04, 0xc0, 0x39, 0x08, 0x06, 0x00, 0x34, 0x0f, 0x0a, 0x00, 0x11, 0x00, 0x02, 0x04, 0x11, 0x00, 0x02, 0x08, 0x11, 0x00, 0x02, 0x0c, 0x11, 0x00, 0x02, 0xf2, 0x01, 0x01, 0x01, + 0xf4, 0x01, 0x01, 0x01, 0xf6, 0x01, 0x01, 0x01, 0xf8, 0x01, 0x01, 0x01, 0xfa, 0x01, 0x01, 0x01, 0xfc, 0x01, 0x01, 0x01, 0xc4, 0x17, 0x02, 0x02, 0xc8, 0x17, 0x02, 0x02, 0xcc, 0x17, 0x02, 0x02, + 0xd0, 0x17, 0x02, 0x02, 0xd4, 0x17, 0x02, 0x02, 0xb8, 0x34, 0x03, 0x03, 0xc0, 0x34, 0x03, 0x03, 0xc8, 0x34, 0x03, 0x03, 0x88, 0x0d, 0x04, 0x03, 0x90, 0x0d, 0x04, 0x03, 0x10, 0x27, 0x05, 0x04, + 0x90, 0x04, 0x06, 0x04, 0x00, 0x3a, 0x08, 0x06, 0x00, 0x08, 0x10, 0x0a, 0x10, 0x11, 0x00, 0x02, 0x14, 0x11, 0x00, 0x02, 0x18, 0x11, 0x00, 0x02, 0x1c, 0x11, 0x00, 0x02, 0xfe, 0x01, 0x01, 0x01, + 0x00, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x06, 0x02, 0x01, 0x01, 0x08, 0x02, 0x01, 0x01, 0xd8, 0x17, 0x02, 0x02, 0xdc, 0x17, 0x02, 0x02, 0xe0, 0x17, 0x02, 0x02, + 0xe4, 0x17, 0x02, 0x02, 0xe8, 0x17, 0x02, 0x02, 0xd0, 0x34, 0x03, 0x03, 0xd8, 0x34, 0x03, 0x03, 0xe0, 0x34, 0x03, 0x03, 0x98, 0x0d, 0x04, 0x03, 0xa0, 0x0d, 0x04, 0x03, 0x20, 0x27, 0x05, 0x04, + 0xa0, 0x04, 0x06, 0x04, 0x40, 0x3a, 0x08, 0x06, 0x00, 0x0c, 0x10, 0x0a, 0x20, 0x11, 0x00, 0x02, 0x24, 0x11, 0x00, 0x02, 0x28, 0x11, 0x00, 0x02, 0x2c, 0x11, 0x00, 0x02, 0x0a, 0x02, 0x01, 0x01, + 0x0c, 0x02, 0x01, 0x01, 0x0e, 0x02, 0x01, 0x01, 0x10, 0x02, 0x01, 0x01, 0x12, 0x02, 0x01, 0x01, 0x14, 0x02, 0x01, 0x01, 0xec, 0x17, 0x02, 0x02, 0xf0, 0x17, 0x02, 0x02, 0xf4, 0x17, 0x02, 0x02, + 0xf8, 0x17, 0x02, 0x02, 0xfc, 0x17, 0x02, 0x02, 0xe8, 0x34, 0x03, 0x03, 0xf0, 0x34, 0x03, 0x03, 0xf8, 0x34, 0x03, 0x03, 0xa8, 0x0d, 0x04, 0x03, 0xb0, 0x0d, 0x04, 0x03, 0x30, 0x27, 0x05, 0x04, + 0xb0, 0x04, 0x06, 0x04, 0x80, 0x3a, 0x08, 0x06, 0x00, 0x28, 0x11, 0x0b, 0x30, 0x11, 0x00, 0x02, 0x34, 0x11, 0x00, 0x02, 0x38, 0x11, 0x00, 0x02, 0x3c, 0x11, 0x00, 0x02, 0x16, 0x02, 0x01, 0x01, + 0x18, 0x02, 0x01, 0x01, 0x1a, 0x02, 0x01, 0x01, 0x1c, 0x02, 0x01, 0x01, 0x1e, 0x02, 0x01, 0x01, 0x20, 0x02, 0x01, 0x01, 0x00, 0x18, 0x02, 0x02, 0x04, 0x18, 0x02, 0x02, 0x08, 0x18, 0x02, 0x02, + 0x0c, 0x18, 0x02, 0x02, 0x10, 0x18, 0x02, 0x02, 0x00, 0x35, 0x03, 0x03, 0x08, 0x35, 0x03, 0x03, 0x10, 0x35, 0x03, 0x03, 0xb8, 0x0d, 0x04, 0x03, 0xc0, 0x0d, 0x04, 0x03, 0x40, 0x27, 0x05, 0x04, + 0xc0, 0x04, 0x06, 0x04, 0xc0, 0x3a, 0x08, 0x06, 0x00, 0x10, 0x13, 0x0c, 0x40, 0x11, 0x00, 0x02, 0x44, 0x11, 0x00, 0x02, 0x48, 0x11, 0x00, 0x02, 0x4c, 0x11, 0x00, 0x02, 0x22, 0x02, 0x01, 0x01, + 0x24, 0x02, 0x01, 0x01, 0x26, 0x02, 0x01, 0x01, 0x28, 0x02, 0x01, 0x01, 0x2a, 0x02, 0x01, 0x01, 0x2c, 0x02, 0x01, 0x01, 0x14, 0x18, 0x02, 0x02, 0x18, 0x18, 0x02, 0x02, 0x1c, 0x18, 0x02, 0x02, + 0x20, 0x18, 0x02, 0x02, 0x24, 0x18, 0x02, 0x02, 0x18, 0x35, 0x03, 0x03, 0x20, 0x35, 0x03, 0x03, 0x28, 0x35, 0x03, 0x03, 0xc8, 0x0d, 0x04, 0x03, 0xd0, 0x0d, 0x04, 0x03, 0x50, 0x27, 0x05, 0x04, + 0xd0, 0x04, 0x06, 0x04, 0x00, 0x3b, 0x08, 0x06, 0x50, 0x11, 0x00, 0x02, 0x54, 0x11, 0x00, 0x02, 0x58, 0x11, 0x00, 0x02, 0x5c, 0x11, 0x00, 0x02, 0x60, 0x11, 0x00, 0x02, 0x2e, 0x02, 0x01, 0x01, + 0x30, 0x02, 0x01, 0x01, 0x32, 0x02, 0x01, 0x01, 0x34, 0x02, 0x01, 0x01, 0x36, 0x02, 0x01, 0x01, 0x38, 0x02, 0x01, 0x01, 0x28, 0x18, 0x02, 0x02, 0x2c, 0x18, 0x02, 0x02, 0x30, 0x18, 0x02, 0x02, + 0x34, 0x18, 0x02, 0x02, 0x38, 0x18, 0x02, 0x02, 0x30, 0x35, 0x03, 0x03, 0x38, 0x35, 0x03, 0x03, 0x40, 0x35, 0x03, 0x03, 0xd8, 0x0d, 0x04, 0x03, 0xe0, 0x0d, 0x04, 0x03, 0x60, 0x27, 0x05, 0x04, + 0xe0, 0x04, 0x06, 0x04, 0x40, 0x3b, 0x08, 0x06, 0x64, 0x11, 0x00, 0x02, 0x68, 0x11, 0x00, 0x02, 0x6c, 0x11, 0x00, 0x02, 0x70, 0x11, 0x00, 0x02, 0x74, 0x11, 0x00, 0x02, 0x3a, 0x02, 0x01, 0x01, + 0x3c, 0x02, 0x01, 0x01, 0x3e, 0x02, 0x01, 0x01, 0x40, 0x02, 0x01, 0x01, 0x42, 0x02, 0x01, 0x01, 0x44, 0x02, 0x01, 0x01, 0x3c, 0x18, 0x02, 0x02, 0x40, 0x18, 0x02, 0x02, 0x44, 0x18, 0x02, 0x02, + 0x48, 0x18, 0x02, 0x02, 0x4c, 0x18, 0x02, 0x02, 0x48, 0x35, 0x03, 0x03, 0x50, 0x35, 0x03, 0x03, 0x58, 0x35, 0x03, 0x03, 0xe8, 0x0d, 0x04, 0x03, 0xf0, 0x0d, 0x04, 0x03, 0x70, 0x27, 0x05, 0x04, + 0xf0, 0x04, 0x06, 0x04, 0x80, 0x3b, 0x08, 0x06, 0x78, 0x11, 0x00, 0x02, 0x7c, 0x11, 0x00, 0x02, 0x80, 0x11, 0x00, 0x02, 0x84, 0x11, 0x00, 0x02, 0x88, 0x11, 0x00, 0x02, 0x46, 0x02, 0x01, 0x01, + 0x48, 0x02, 0x01, 0x01, 0x4a, 0x02, 0x01, 0x01, 0x4c, 0x02, 0x01, 0x01, 0x4e, 0x02, 0x01, 0x01, 0x50, 0x02, 0x01, 0x01, 0x50, 0x18, 0x02, 0x02, 0x54, 0x18, 0x02, 0x02, 0x58, 0x18, 0x02, 0x02, + 0x5c, 0x18, 0x02, 0x02, 0x60, 0x18, 0x02, 0x02, 0x60, 0x35, 0x03, 0x03, 0x68, 0x35, 0x03, 0x03, 0x70, 0x35, 0x03, 0x03, 0xf8, 0x0d, 0x04, 0x03, 0x00, 0x0e, 0x04, 0x03, 0x80, 0x27, 0x05, 0x04, + 0x00, 0x05, 0x06, 0x04, 0xc0, 0x3b, 0x08, 0x06, 0x8c, 0x11, 0x00, 0x02, 0x90, 0x11, 0x00, 0x02, 0x94, 0x11, 0x00, 0x02, 0x98, 0x11, 0x00, 0x02, 0x9c, 0x11, 0x00, 0x02, 0x52, 0x02, 0x01, 0x01, + 0x54, 0x02, 0x01, 0x01, 0x56, 0x02, 0x01, 0x01, 0x58, 0x02, 0x01, 0x01, 0x5a, 0x02, 0x01, 0x01, 0x5c, 0x02, 0x01, 0x01, 0x64, 0x18, 0x02, 0x02, 0x68, 0x18, 0x02, 0x02, 0x6c, 0x18, 0x02, 0x02, + 0x70, 0x18, 0x02, 0x02, 0x74, 0x18, 0x02, 0x02, 0x78, 0x35, 0x03, 0x03, 0x80, 0x35, 0x03, 0x03, 0x88, 0x35, 0x03, 0x03, 0x08, 0x0e, 0x04, 0x03, 0x10, 0x0e, 0x04, 0x03, 0x90, 0x27, 0x05, 0x04, + 0x10, 0x05, 0x06, 0x04, 0x00, 0x3c, 0x08, 0x06, 0xa0, 0x11, 0x00, 0x02, 0xa4, 0x11, 0x00, 0x02, 0xa8, 0x11, 0x00, 0x02, 0xac, 0x11, 0x00, 0x02, 0xb0, 0x11, 0x00, 0x02, 0x5e, 0x02, 0x01, 0x01, + 0x60, 0x02, 0x01, 0x01, 0x62, 0x02, 0x01, 0x01, 0x64, 0x02, 0x01, 0x01, 0x66, 0x02, 0x01, 0x01, 0x68, 0x02, 0x01, 0x01, 0x78, 0x18, 0x02, 0x02, 0x7c, 0x18, 0x02, 0x02, 0x80, 0x18, 0x02, 0x02, + 0x84, 0x18, 0x02, 0x02, 0x88, 0x18, 0x02, 0x02, 0x90, 0x35, 0x03, 0x03, 0x98, 0x35, 0x03, 0x03, 0xa0, 0x35, 0x03, 0x03, 0x18, 0x0e, 0x04, 0x03, 0x20, 0x0e, 0x04, 0x03, 0xa0, 0x27, 0x05, 0x04, + 0x20, 0x05, 0x06, 0x04, 0x40, 0x3c, 0x08, 0x06, 0xb4, 0x11, 0x00, 0x02, 0xb8, 0x11, 0x00, 0x02, 0xbc, 0x11, 0x00, 0x02, 0xc0, 0x11, 0x00, 0x02, 0xc4, 0x11, 0x00, 0x02, 0x6a, 0x02, 0x01, 0x01, + 0x6c, 0x02, 0x01, 0x01, 0x6e, 0x02, 0x01, 0x01, 0x70, 0x02, 0x01, 0x01, 0x72, 0x02, 0x01, 0x01, 0x74, 0x02, 0x01, 0x01, 0x8c, 0x18, 0x02, 0x02, 0x90, 0x18, 0x02, 0x02, 0x94, 0x18, 0x02, 0x02, + 0x98, 0x18, 0x02, 0x02, 0x9c, 0x18, 0x02, 0x02, 0xa8, 0x35, 0x03, 0x03, 0xb0, 0x35, 0x03, 0x03, 0xb8, 0x35, 0x03, 0x03, 0x28, 0x0e, 0x04, 0x03, 0x30, 0x0e, 0x04, 0x03, 0xb0, 0x27, 0x05, 0x04, + 0x30, 0x05, 0x06, 0x04, 0x80, 0x3c, 0x08, 0x06, 0xc8, 0x11, 0x00, 0x02, 0xcc, 0x11, 0x00, 0x02, 0xd0, 0x11, 0x00, 0x02, 0xd4, 0x11, 0x00, 0x02, 0xd8, 0x11, 0x00, 0x02, 0x76, 0x02, 0x01, 0x01, + 0x78, 0x02, 0x01, 0x01, 0x7a, 0x02, 0x01, 0x01, 0x7c, 0x02, 0x01, 0x01, 0x7e, 0x02, 0x01, 0x01, 0x80, 0x02, 0x01, 0x01, 0xa0, 0x18, 0x02, 0x02, 0xa4, 0x18, 0x02, 0x02, 0xa8, 0x18, 0x02, 0x02, + 0xac, 0x18, 0x02, 0x02, 0xb0, 0x18, 0x02, 0x02, 0xc0, 0x35, 0x03, 0x03, 0xc8, 0x35, 0x03, 0x03, 0xd0, 0x35, 0x03, 0x03, 0x38, 0x0e, 0x04, 0x03, 0x40, 0x0e, 0x04, 0x03, 0xc0, 0x27, 0x05, 0x04, + 0x40, 0x05, 0x06, 0x04, 0xc0, 0x3c, 0x08, 0x06, 0xdc, 0x11, 0x00, 0x02, 0xe0, 0x11, 0x00, 0x02, 0xe4, 0x11, 0x00, 0x02, 0xe8, 0x11, 0x00, 0x02, 0xec, 0x11, 0x00, 0x02, 0x82, 0x02, 0x01, 0x01, + 0x84, 0x02, 0x01, 0x01, 0x86, 0x02, 0x01, 0x01, 0x88, 0x02, 0x01, 0x01, 0x8a, 0x02, 0x01, 0x01, 0x8c, 0x02, 0x01, 0x01, 0xb4, 0x18, 0x02, 0x02, 0xb8, 0x18, 0x02, 0x02, 0xbc, 0x18, 0x02, 0x02, + 0xc0, 0x18, 0x02, 0x02, 0xc4, 0x18, 0x02, 0x02, 0xd8, 0x35, 0x03, 0x03, 0xe0, 0x35, 0x03, 0x03, 0xe8, 0x35, 0x03, 0x03, 0x48, 0x0e, 0x04, 0x03, 0x50, 0x0e, 0x04, 0x03, 0xd0, 0x27, 0x05, 0x04, + 0x50, 0x05, 0x06, 0x04, 0x00, 0x3d, 0x08, 0x06, 0xf0, 0x11, 0x00, 0x02, 0xf4, 0x11, 0x00, 0x02, 0xf8, 0x11, 0x00, 0x02, 0xfc, 0x11, 0x00, 0x02, 0x8e, 0x02, 0x01, 0x01, 0x90, 0x02, 0x01, 0x01, + 0x92, 0x02, 0x01, 0x01, 0x94, 0x02, 0x01, 0x01, 0x96, 0x02, 0x01, 0x01, 0x98, 0x02, 0x01, 0x01, 0x9a, 0x02, 0x01, 0x01, 0xc8, 0x18, 0x02, 0x02, 0xcc, 0x18, 0x02, 0x02, 0xd0, 0x18, 0x02, 0x02, + 0xd4, 0x18, 0x02, 0x02, 0xd8, 0x18, 0x02, 0x02, 0xf0, 0x35, 0x03, 0x03, 0xf8, 0x35, 0x03, 0x03, 0x00, 0x36, 0x03, 0x03, 0x58, 0x0e, 0x04, 0x03, 0x60, 0x0e, 0x04, 0x03, 0xe0, 0x27, 0x05, 0x04, + 0x60, 0x05, 0x06, 0x04, 0x40, 0x3d, 0x08, 0x06, 0x00, 0x12, 0x00, 0x02, 0x04, 0x12, 0x00, 0x02, 0x08, 0x12, 0x00, 0x02, 0x0c, 0x12, 0x00, 0x02, 0x9c, 0x02, 0x01, 0x01, 0x9e, 0x02, 0x01, 0x01, + 0xa0, 0x02, 0x01, 0x01, 0xa2, 0x02, 0x01, 0x01, 0xa4, 0x02, 0x01, 0x01, 0xa6, 0x02, 0x01, 0x01, 0xa8, 0x02, 0x01, 0x01, 0xdc, 0x18, 0x02, 0x02, 0xe0, 0x18, 0x02, 0x02, 0xe4, 0x18, 0x02, 0x02, + 0xe8, 0x18, 0x02, 0x02, 0xec, 0x18, 0x02, 0x02, 0x08, 0x36, 0x03, 0x03, 0x10, 0x36, 0x03, 0x03, 0x18, 0x36, 0x03, 0x03, 0x68, 0x0e, 0x04, 0x03, 0xf0, 0x27, 0x05, 0x04, 0x00, 0x28, 0x05, 0x04, + 0x70, 0x05, 0x06, 0x04, 0x80, 0x3d, 0x08, 0x06, 0x10, 0x12, 0x00, 0x02, 0x14, 0x12, 0x00, 0x02, 0x18, 0x12, 0x00, 0x02, 0x1c, 0x12, 0x00, 0x02, 0xaa, 0x02, 0x01, 0x01, 0xac, 0x02, 0x01, 0x01, + 0xae, 0x02, 0x01, 0x01, 0xb0, 0x02, 0x01, 0x01, 0xb2, 0x02, 0x01, 0x01, 0xb4, 0x02, 0x01, 0x01, 0xb6, 0x02, 0x01, 0x01, 0xf0, 0x18, 0x02, 0x02, 0xf4, 0x18, 0x02, 0x02, 0xf8, 0x18, 0x02, 0x02, + 0xfc, 0x18, 0x02, 0x02, 0x00, 0x19, 0x02, 0x02, 0x20, 0x36, 0x03, 0x03, 0x28, 0x36, 0x03, 0x03, 0x30, 0x36, 0x03, 0x03, 0x70, 0x0e, 0x04, 0x03, 0x10, 0x28, 0x05, 0x04, 0x20, 0x28, 0x05, 0x04, + 0x80, 0x05, 0x06, 0x04, 0xc0, 0x3d, 0x08, 0x06, 0x20, 0x12, 0x00, 0x02, 0x24, 0x12, 0x00, 0x02, 0x28, 0x12, 0x00, 0x02, 0x2c, 0x12, 0x00, 0x02, 0xb8, 0x02, 0x01, 0x01, 0xba, 0x02, 0x01, 0x01, + 0xbc, 0x02, 0x01, 0x01, 0xbe, 0x02, 0x01, 0x01, 0xc0, 0x02, 0x01, 0x01, 0xc2, 0x02, 0x01, 0x01, 0xc4, 0x02, 0x01, 0x01, 0x04, 0x19, 0x02, 0x02, 0x08, 0x19, 0x02, 0x02, 0x0c, 0x19, 0x02, 0x02, + 0x10, 0x19, 0x02, 0x02, 0x14, 0x19, 0x02, 0x02, 0x38, 0x36, 0x03, 0x03, 0x40, 0x36, 0x03, 0x03, 0x48, 0x36, 0x03, 0x03, 0x78, 0x0e, 0x04, 0x03, 0x30, 0x28, 0x05, 0x04, 0x40, 0x28, 0x05, 0x04, + 0x90, 0x05, 0x06, 0x04, 0x00, 0x3e, 0x08, 0x06, 0x30, 0x12, 0x00, 0x02, 0x34, 0x12, 0x00, 0x02, 0x38, 0x12, 0x00, 0x02, 0x3c, 0x12, 0x00, 0x02, 0xc6, 0x02, 0x01, 0x01, 0xc8, 0x02, 0x01, 0x01, + 0xca, 0x02, 0x01, 0x01, 0xcc, 0x02, 0x01, 0x01, 0xce, 0x02, 0x01, 0x01, 0xd0, 0x02, 0x01, 0x01, 0xd2, 0x02, 0x01, 0x01, 0x18, 0x19, 0x02, 0x02, 0x1c, 0x19, 0x02, 0x02, 0x20, 0x19, 0x02, 0x02, + 0x24, 0x19, 0x02, 0x02, 0x28, 0x19, 0x02, 0x02, 0x50, 0x36, 0x03, 0x03, 0x58, 0x36, 0x03, 0x03, 0x80, 0x0e, 0x04, 0x03, 0x88, 0x0e, 0x04, 0x03, 0x50, 0x28, 0x05, 0x04, 0x60, 0x28, 0x05, 0x04, + 0xa0, 0x05, 0x06, 0x04, 0x40, 0x3e, 0x08, 0x06, 0x40, 0x12, 0x00, 0x02, 0x44, 0x12, 0x00, 0x02, 0x48, 0x12, 0x00, 0x02, 0x4c, 0x12, 0x00, 0x02, 0xd4, 0x02, 0x01, 0x01, 0xd6, 0x02, 0x01, 0x01, + 0xd8, 0x02, 0x01, 0x01, 0xda, 0x02, 0x01, 0x01, 0xdc, 0x02, 0x01, 0x01, 0xde, 0x02, 0x01, 0x01, 0xe0, 0x02, 0x01, 0x01, 0x2c, 0x19, 0x02, 0x02, 0x30, 0x19, 0x02, 0x02, 0x34, 0x19, 0x02, 0x02, + 0x38, 0x19, 0x02, 0x02, 0x3c, 0x19, 0x02, 0x02, 0x60, 0x36, 0x03, 0x03, 0x68, 0x36, 0x03, 0x03, 0x90, 0x0e, 0x04, 0x03, 0x98, 0x0e, 0x04, 0x03, 0x70, 0x28, 0x05, 0x04, 0x80, 0x28, 0x05, 0x04, + 0xb0, 0x05, 0x06, 0x04, 0x80, 0x3e, 0x08, 0x06, 0x50, 0x12, 0x00, 0x02, 0x54, 0x12, 0x00, 0x02, 0x58, 0x12, 0x00, 0x02, 0x5c, 0x12, 0x00, 0x02, 0xe2, 0x02, 0x01, 0x01, 0xe4, 0x02, 0x01, 0x01, + 0xe6, 0x02, 0x01, 0x01, 0xe8, 0x02, 0x01, 0x01, 0xea, 0x02, 0x01, 0x01, 0xec, 0x02, 0x01, 0x01, 0xee, 0x02, 0x01, 0x01, 0x40, 0x19, 0x02, 0x02, 0x44, 0x19, 0x02, 0x02, 0x48, 0x19, 0x02, 0x02, + 0x4c, 0x19, 0x02, 0x02, 0x50, 0x19, 0x02, 0x02, 0x70, 0x36, 0x03, 0x03, 0x78, 0x36, 0x03, 0x03, 0xa0, 0x0e, 0x04, 0x03, 0xa8, 0x0e, 0x04, 0x03, 0x90, 0x28, 0x05, 0x04, 0xa0, 0x28, 0x05, 0x04, + 0xc0, 0x05, 0x06, 0x04, 0xc0, 0x3e, 0x08, 0x06, 0x60, 0x12, 0x00, 0x02, 0x64, 0x12, 0x00, 0x02, 0x68, 0x12, 0x00, 0x02, 0x6c, 0x12, 0x00, 0x02, 0xf0, 0x02, 0x01, 0x01, 0xf2, 0x02, 0x01, 0x01, + 0xf4, 0x02, 0x01, 0x01, 0xf6, 0x02, 0x01, 0x01, 0xf8, 0x02, 0x01, 0x01, 0xfa, 0x02, 0x01, 0x01, 0xfc, 0x02, 0x01, 0x01, 0x54, 0x19, 0x02, 0x02, 0x58, 0x19, 0x02, 0x02, 0x5c, 0x19, 0x02, 0x02, + 0x60, 0x19, 0x02, 0x02, 0x64, 0x19, 0x02, 0x02, 0x80, 0x36, 0x03, 0x03, 0x88, 0x36, 0x03, 0x03, 0xb0, 0x0e, 0x04, 0x03, 0xb8, 0x0e, 0x04, 0x03, 0xb0, 0x28, 0x05, 0x04, 0xc0, 0x28, 0x05, 0x04, + 0xd0, 0x05, 0x06, 0x04, 0x00, 0x3f, 0x08, 0x06, 0x70, 0x12, 0x00, 0x02, 0x74, 0x12, 0x00, 0x02, 0x78, 0x12, 0x00, 0x02, 0x7c, 0x12, 0x00, 0x02, 0xfe, 0x02, 0x01, 0x01, 0x00, 0x03, 0x01, 0x01, + 0x02, 0x03, 0x01, 0x01, 0x04, 0x03, 0x01, 0x01, 0x06, 0x03, 0x01, 0x01, 0x08, 0x03, 0x01, 0x01, 0x0a, 0x03, 0x01, 0x01, 0x68, 0x19, 0x02, 0x02, 0x6c, 0x19, 0x02, 0x02, 0x70, 0x19, 0x02, 0x02, + 0x74, 0x19, 0x02, 0x02, 0x78, 0x19, 0x02, 0x02, 0x90, 0x36, 0x03, 0x03, 0x98, 0x36, 0x03, 0x03, 0xc0, 0x0e, 0x04, 0x03, 0xc8, 0x0e, 0x04, 0x03, 0xd0, 0x28, 0x05, 0x04, 0xe0, 0x28, 0x05, 0x04, + 0xe0, 0x05, 0x06, 0x04, 0x40, 0x3f, 0x08, 0x06, 0x80, 0x12, 0x00, 0x02, 0x84, 0x12, 0x00, 0x02, 0x88, 0x12, 0x00, 0x02, 0x8c, 0x12, 0x00, 0x02, 0x0c, 0x03, 0x01, 0x01, 0x0e, 0x03, 0x01, 0x01, + 0x10, 0x03, 0x01, 0x01, 0x12, 0x03, 0x01, 0x01, 0x14, 0x03, 0x01, 0x01, 0x16, 0x03, 0x01, 0x01, 0x18, 0x03, 0x01, 0x01, 0x7c, 0x19, 0x02, 0x02, 0x80, 0x19, 0x02, 0x02, 0x84, 0x19, 0x02, 0x02, + 0x88, 0x19, 0x02, 0x02, 0xa0, 0x36, 0x03, 0x03, 0xa8, 0x36, 0x03, 0x03, 0xb0, 0x36, 0x03, 0x03, 0xd0, 0x0e, 0x04, 0x03, 0xd8, 0x0e, 0x04, 0x03, 0xf0, 0x28, 0x05, 0x04, 0x00, 0x29, 0x05, 0x04, + 0xf0, 0x05, 0x06, 0x04, 0x80, 0x3f, 0x08, 0x06, 0x90, 0x12, 0x00, 0x02, 0x94, 0x12, 0x00, 0x02, 0x98, 0x12, 0x00, 0x02, 0x9c, 0x12, 0x00, 0x02, 0x1a, 0x03, 0x01, 0x01, 0x1c, 0x03, 0x01, 0x01, + 0x1e, 0x03, 0x01, 0x01, 0x20, 0x03, 0x01, 0x01, 0x22, 0x03, 0x01, 0x01, 0x24, 0x03, 0x01, 0x01, 0x26, 0x03, 0x01, 0x01, 0x8c, 0x19, 0x02, 0x02, 0x90, 0x19, 0x02, 0x02, 0x94, 0x19, 0x02, 0x02, + 0x98, 0x19, 0x02, 0x02, 0xb8, 0x36, 0x03, 0x03, 0xc0, 0x36, 0x03, 0x03, 0xc8, 0x36, 0x03, 0x03, 0xe0, 0x0e, 0x04, 0x03, 0xe8, 0x0e, 0x04, 0x03, 0x10, 0x29, 0x05, 0x04, 0x20, 0x29, 0x05, 0x04, + 0x00, 0x06, 0x06, 0x04, 0xc0, 0x3f, 0x08, 0x06, 0xa0, 0x12, 0x00, 0x02, 0xa4, 0x12, 0x00, 0x02, 0xa8, 0x12, 0x00, 0x02, 0xac, 0x12, 0x00, 0x02, 0x28, 0x03, 0x01, 0x01, 0x2a, 0x03, 0x01, 0x01, + 0x2c, 0x03, 0x01, 0x01, 0x2e, 0x03, 0x01, 0x01, 0x30, 0x03, 0x01, 0x01, 0x32, 0x03, 0x01, 0x01, 0x34, 0x03, 0x01, 0x01, 0x9c, 0x19, 0x02, 0x02, 0xa0, 0x19, 0x02, 0x02, 0xa4, 0x19, 0x02, 0x02, + 0xa8, 0x19, 0x02, 0x02, 0xd0, 0x36, 0x03, 0x03, 0xd8, 0x36, 0x03, 0x03, 0xe0, 0x36, 0x03, 0x03, 0xf0, 0x0e, 0x04, 0x03, 0xf8, 0x0e, 0x04, 0x03, 0x30, 0x29, 0x05, 0x04, 0x40, 0x29, 0x05, 0x04, + 0x10, 0x06, 0x06, 0x04, 0x00, 0x00, 0x08, 0x05, 0xb0, 0x12, 0x00, 0x02, 0xb4, 0x12, 0x00, 0x02, 0xb8, 0x12, 0x00, 0x02, 0xbc, 0x12, 0x00, 0x02, 0x36, 0x03, 0x01, 0x01, 0x38, 0x03, 0x01, 0x01, + 0x3a, 0x03, 0x01, 0x01, 0x3c, 0x03, 0x01, 0x01, 0x3e, 0x03, 0x01, 0x01, 0x40, 0x03, 0x01, 0x01, 0x42, 0x03, 0x01, 0x01, 0xac, 0x19, 0x02, 0x02, 0xb0, 0x19, 0x02, 0x02, 0xb4, 0x19, 0x02, 0x02, + 0xb8, 0x19, 0x02, 0x02, 0xe8, 0x36, 0x03, 0x03, 0xf0, 0x36, 0x03, 0x03, 0xf8, 0x36, 0x03, 0x03, 0x00, 0x0f, 0x04, 0x03, 0x08, 0x0f, 0x04, 0x03, 0x50, 0x29, 0x05, 0x04, 0x60, 0x29, 0x05, 0x04, + 0x20, 0x06, 0x06, 0x04, 0x40, 0x10, 0x09, 0x06, 0xc0, 0x12, 0x00, 0x02, 0xc4, 0x12, 0x00, 0x02, 0xc8, 0x12, 0x00, 0x02, 0xcc, 0x12, 0x00, 0x02, 0x44, 0x03, 0x01, 0x01, 0x46, 0x03, 0x01, 0x01, + 0x48, 0x03, 0x01, 0x01, 0x4a, 0x03, 0x01, 0x01, 0x4c, 0x03, 0x01, 0x01, 0x4e, 0x03, 0x01, 0x01, 0x50, 0x03, 0x01, 0x01, 0xbc, 0x19, 0x02, 0x02, 0xc0, 0x19, 0x02, 0x02, 0xc4, 0x19, 0x02, 0x02, + 0xc8, 0x19, 0x02, 0x02, 0x00, 0x37, 0x03, 0x03, 0x08, 0x37, 0x03, 0x03, 0x10, 0x37, 0x03, 0x03, 0x10, 0x0f, 0x04, 0x03, 0x18, 0x0f, 0x04, 0x03, 0x70, 0x29, 0x05, 0x04, 0x80, 0x29, 0x05, 0x04, + 0x30, 0x06, 0x06, 0x04, 0x80, 0x10, 0x09, 0x06, 0xd0, 0x12, 0x00, 0x02, 0xd4, 0x12, 0x00, 0x02, 0xd8, 0x12, 0x00, 0x02, 0xdc, 0x12, 0x00, 0x02, 0x52, 0x03, 0x01, 0x01, 0x54, 0x03, 0x01, 0x01, + 0x56, 0x03, 0x01, 0x01, 0x58, 0x03, 0x01, 0x01, 0x5a, 0x03, 0x01, 0x01, 0x5c, 0x03, 0x01, 0x01, 0x5e, 0x03, 0x01, 0x01, 0xcc, 0x19, 0x02, 0x02, 0xd0, 0x19, 0x02, 0x02, 0xd4, 0x19, 0x02, 0x02, + 0xd8, 0x19, 0x02, 0x02, 0x18, 0x37, 0x03, 0x03, 0x20, 0x37, 0x03, 0x03, 0x28, 0x37, 0x03, 0x03, 0x20, 0x0f, 0x04, 0x03, 0x28, 0x0f, 0x04, 0x03, 0x90, 0x29, 0x05, 0x04, 0xa0, 0x29, 0x05, 0x04, + 0x40, 0x06, 0x06, 0x04, 0xc0, 0x10, 0x09, 0x06, 0xe0, 0x12, 0x00, 0x02, 0xe4, 0x12, 0x00, 0x02, 0xe8, 0x12, 0x00, 0x02, 0xec, 0x12, 0x00, 0x02, 0x60, 0x03, 0x01, 0x01, 0x62, 0x03, 0x01, 0x01, + 0x64, 0x03, 0x01, 0x01, 0x66, 0x03, 0x01, 0x01, 0x68, 0x03, 0x01, 0x01, 0x6a, 0x03, 0x01, 0x01, 0x6c, 0x03, 0x01, 0x01, 0xdc, 0x19, 0x02, 0x02, 0xe0, 0x19, 0x02, 0x02, 0xe4, 0x19, 0x02, 0x02, + 0xe8, 0x19, 0x02, 0x02, 0x30, 0x37, 0x03, 0x03, 0x38, 0x37, 0x03, 0x03, 0x40, 0x37, 0x03, 0x03, 0x30, 0x0f, 0x04, 0x03, 0x38, 0x0f, 0x04, 0x03, 0xb0, 0x29, 0x05, 0x04, 0xc0, 0x29, 0x05, 0x04, + 0xe0, 0x1a, 0x07, 0x05, 0x00, 0x11, 0x09, 0x06, 0xf0, 0x12, 0x00, 0x02, 0xf4, 0x12, 0x00, 0x02, 0xf8, 0x12, 0x00, 0x02, 0xfc, 0x12, 0x00, 0x02, 0x6e, 0x03, 0x01, 0x01, 0x70, 0x03, 0x01, 0x01, + 0x72, 0x03, 0x01, 0x01, 0x74, 0x03, 0x01, 0x01, 0x76, 0x03, 0x01, 0x01, 0x78, 0x03, 0x01, 0x01, 0x7a, 0x03, 0x01, 0x01, 0xec, 0x19, 0x02, 0x02, 0xf0, 0x19, 0x02, 0x02, 0xf4, 0x19, 0x02, 0x02, + 0xf8, 0x19, 0x02, 0x02, 0x48, 0x37, 0x03, 0x03, 0x50, 0x37, 0x03, 0x03, 0x58, 0x37, 0x03, 0x03, 0x40, 0x0f, 0x04, 0x03, 0x48, 0x0f, 0x04, 0x03, 0xd0, 0x29, 0x05, 0x04, 0xe0, 0x29, 0x05, 0x04, + 0x00, 0x1b, 0x07, 0x05, 0x40, 0x11, 0x09, 0x06, 0x00, 0x13, 0x00, 0x02, 0x04, 0x13, 0x00, 0x02, 0x08, 0x13, 0x00, 0x02, 0x0c, 0x13, 0x00, 0x02, 0x7c, 0x03, 0x01, 0x01, 0x7e, 0x03, 0x01, 0x01, + 0x80, 0x03, 0x01, 0x01, 0x82, 0x03, 0x01, 0x01, 0x84, 0x03, 0x01, 0x01, 0x86, 0x03, 0x01, 0x01, 0x88, 0x03, 0x01, 0x01, 0xfc, 0x19, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x04, 0x1a, 0x02, 0x02, + 0x08, 0x1a, 0x02, 0x02, 0x60, 0x37, 0x03, 0x03, 0x68, 0x37, 0x03, 0x03, 0x70, 0x37, 0x03, 0x03, 0x50, 0x0f, 0x04, 0x03, 0x58, 0x0f, 0x04, 0x03, 0xf0, 0x29, 0x05, 0x04, 0x00, 0x2a, 0x05, 0x04, + 0x20, 0x1b, 0x07, 0x05, 0x80, 0x11, 0x09, 0x06, 0x10, 0x13, 0x00, 0x02, 0x14, 0x13, 0x00, 0x02, 0x18, 0x13, 0x00, 0x02, 0x1c, 0x13, 0x00, 0x02, 0x8a, 0x03, 0x01, 0x01, 0x8c, 0x03, 0x01, 0x01, + 0x8e, 0x03, 0x01, 0x01, 0x90, 0x03, 0x01, 0x01, 0x92, 0x03, 0x01, 0x01, 0x94, 0x03, 0x01, 0x01, 0x96, 0x03, 0x01, 0x01, 0x0c, 0x1a, 0x02, 0x02, 0x10, 0x1a, 0x02, 0x02, 0x14, 0x1a, 0x02, 0x02, + 0x18, 0x1a, 0x02, 0x02, 0x78, 0x37, 0x03, 0x03, 0x80, 0x37, 0x03, 0x03, 0x88, 0x37, 0x03, 0x03, 0x60, 0x0f, 0x04, 0x03, 0x68, 0x0f, 0x04, 0x03, 0x10, 0x2a, 0x05, 0x04, 0x20, 0x2a, 0x05, 0x04, + 0x40, 0x1b, 0x07, 0x05, 0xc0, 0x11, 0x09, 0x06, 0x20, 0x13, 0x00, 0x02, 0x24, 0x13, 0x00, 0x02, 0x28, 0x13, 0x00, 0x02, 0x2c, 0x13, 0x00, 0x02, 0x98, 0x03, 0x01, 0x01, 0x9a, 0x03, 0x01, 0x01, + 0x9c, 0x03, 0x01, 0x01, 0x9e, 0x03, 0x01, 0x01, 0xa0, 0x03, 0x01, 0x01, 0xa2, 0x03, 0x01, 0x01, 0xa4, 0x03, 0x01, 0x01, 0x1c, 0x1a, 0x02, 0x02, 0x20, 0x1a, 0x02, 0x02, 0x24, 0x1a, 0x02, 0x02, + 0x28, 0x1a, 0x02, 0x02, 0x90, 0x37, 0x03, 0x03, 0x98, 0x37, 0x03, 0x03, 0xa0, 0x37, 0x03, 0x03, 0x70, 0x0f, 0x04, 0x03, 0x78, 0x0f, 0x04, 0x03, 0x30, 0x2a, 0x05, 0x04, 0x40, 0x2a, 0x05, 0x04, + 0x60, 0x1b, 0x07, 0x05, 0x00, 0x12, 0x09, 0x06, 0x30, 0x13, 0x00, 0x02, 0x34, 0x13, 0x00, 0x02, 0x38, 0x13, 0x00, 0x02, 0x3c, 0x13, 0x00, 0x02, 0xa6, 0x03, 0x01, 0x01, 0xa8, 0x03, 0x01, 0x01, + 0xaa, 0x03, 0x01, 0x01, 0xac, 0x03, 0x01, 0x01, 0xae, 0x03, 0x01, 0x01, 0xb0, 0x03, 0x01, 0x01, 0xb2, 0x03, 0x01, 0x01, 0x2c, 0x1a, 0x02, 0x02, 0x30, 0x1a, 0x02, 0x02, 0x34, 0x1a, 0x02, 0x02, + 0x38, 0x1a, 0x02, 0x02, 0xa8, 0x37, 0x03, 0x03, 0xb0, 0x37, 0x03, 0x03, 0xb8, 0x37, 0x03, 0x03, 0x80, 0x0f, 0x04, 0x03, 0x88, 0x0f, 0x04, 0x03, 0x50, 0x2a, 0x05, 0x04, 0x60, 0x2a, 0x05, 0x04, + 0x80, 0x1b, 0x07, 0x05, 0x40, 0x12, 0x09, 0x06, 0x40, 0x13, 0x00, 0x02, 0x44, 0x13, 0x00, 0x02, 0x48, 0x13, 0x00, 0x02, 0x4c, 0x13, 0x00, 0x02, 0xb4, 0x03, 0x01, 0x01, 0xb6, 0x03, 0x01, 0x01, + 0xb8, 0x03, 0x01, 0x01, 0xba, 0x03, 0x01, 0x01, 0xbc, 0x03, 0x01, 0x01, 0xbe, 0x03, 0x01, 0x01, 0xc0, 0x03, 0x01, 0x01, 0x3c, 0x1a, 0x02, 0x02, 0x40, 0x1a, 0x02, 0x02, 0x44, 0x1a, 0x02, 0x02, + 0x48, 0x1a, 0x02, 0x02, 0xc0, 0x37, 0x03, 0x03, 0xc8, 0x37, 0x03, 0x03, 0xd0, 0x37, 0x03, 0x03, 0x90, 0x0f, 0x04, 0x03, 0x98, 0x0f, 0x04, 0x03, 0x70, 0x2a, 0x05, 0x04, 0x80, 0x2a, 0x05, 0x04, + 0xa0, 0x1b, 0x07, 0x05, 0x80, 0x12, 0x09, 0x06, 0x50, 0x13, 0x00, 0x02, 0x54, 0x13, 0x00, 0x02, 0x58, 0x13, 0x00, 0x02, 0x5c, 0x13, 0x00, 0x02, 0xc2, 0x03, 0x01, 0x01, 0xc4, 0x03, 0x01, 0x01, + 0xc6, 0x03, 0x01, 0x01, 0xc8, 0x03, 0x01, 0x01, 0xca, 0x03, 0x01, 0x01, 0xcc, 0x03, 0x01, 0x01, 0xce, 0x03, 0x01, 0x01, 0x4c, 0x1a, 0x02, 0x02, 0x50, 0x1a, 0x02, 0x02, 0x54, 0x1a, 0x02, 0x02, + 0x58, 0x1a, 0x02, 0x02, 0xd8, 0x37, 0x03, 0x03, 0xe0, 0x37, 0x03, 0x03, 0xe8, 0x37, 0x03, 0x03, 0xa0, 0x0f, 0x04, 0x03, 0xa8, 0x0f, 0x04, 0x03, 0x90, 0x2a, 0x05, 0x04, 0xa0, 0x2a, 0x05, 0x04, + 0xc0, 0x1b, 0x07, 0x05, 0xc0, 0x12, 0x09, 0x06, 0x60, 0x13, 0x00, 0x02, 0x64, 0x13, 0x00, 0x02, 0x68, 0x13, 0x00, 0x02, 0x6c, 0x13, 0x00, 0x02, 0xd0, 0x03, 0x01, 0x01, 0xd2, 0x03, 0x01, 0x01, + 0xd4, 0x03, 0x01, 0x01, 0xd6, 0x03, 0x01, 0x01, 0xd8, 0x03, 0x01, 0x01, 0xda, 0x03, 0x01, 0x01, 0xdc, 0x03, 0x01, 0x01, 0x5c, 0x1a, 0x02, 0x02, 0x60, 0x1a, 0x02, 0x02, 0x64, 0x1a, 0x02, 0x02, + 0x68, 0x1a, 0x02, 0x02, 0xf0, 0x37, 0x03, 0x03, 0xf8, 0x37, 0x03, 0x03, 0x00, 0x38, 0x03, 0x03, 0xb0, 0x0f, 0x04, 0x03, 0xb8, 0x0f, 0x04, 0x03, 0xb0, 0x2a, 0x05, 0x04, 0xc0, 0x2a, 0x05, 0x04, + 0xe0, 0x1b, 0x07, 0x05, 0x00, 0x13, 0x09, 0x06, 0x70, 0x13, 0x00, 0x02, 0x74, 0x13, 0x00, 0x02, 0x78, 0x13, 0x00, 0x02, 0x7c, 0x13, 0x00, 0x02, 0xde, 0x03, 0x01, 0x01, 0xe0, 0x03, 0x01, 0x01, + 0xe2, 0x03, 0x01, 0x01, 0xe4, 0x03, 0x01, 0x01, 0xe6, 0x03, 0x01, 0x01, 0xe8, 0x03, 0x01, 0x01, 0xea, 0x03, 0x01, 0x01, 0x6c, 0x1a, 0x02, 0x02, 0x70, 0x1a, 0x02, 0x02, 0x74, 0x1a, 0x02, 0x02, + 0x78, 0x1a, 0x02, 0x02, 0x08, 0x38, 0x03, 0x03, 0x10, 0x38, 0x03, 0x03, 0x18, 0x38, 0x03, 0x03, 0xc0, 0x0f, 0x04, 0x03, 0xc8, 0x0f, 0x04, 0x03, 0xd0, 0x2a, 0x05, 0x04, 0xe0, 0x2a, 0x05, 0x04, + 0x00, 0x1c, 0x07, 0x05, 0x40, 0x13, 0x09, 0x06, 0x80, 0x13, 0x00, 0x02, 0x84, 0x13, 0x00, 0x02, 0x88, 0x13, 0x00, 0x02, 0x8c, 0x13, 0x00, 0x02, 0xec, 0x03, 0x01, 0x01, 0xee, 0x03, 0x01, 0x01, + 0xf0, 0x03, 0x01, 0x01, 0xf2, 0x03, 0x01, 0x01, 0xf4, 0x03, 0x01, 0x01, 0xf6, 0x03, 0x01, 0x01, 0xf8, 0x03, 0x01, 0x01, 0x7c, 0x1a, 0x02, 0x02, 0x80, 0x1a, 0x02, 0x02, 0x84, 0x1a, 0x02, 0x02, + 0x88, 0x1a, 0x02, 0x02, 0x20, 0x38, 0x03, 0x03, 0x28, 0x38, 0x03, 0x03, 0x30, 0x38, 0x03, 0x03, 0xd0, 0x0f, 0x04, 0x03, 0xd8, 0x0f, 0x04, 0x03, 0xf0, 0x2a, 0x05, 0x04, 0x00, 0x2b, 0x05, 0x04, + 0x20, 0x1c, 0x07, 0x05, 0x80, 0x13, 0x09, 0x06, 0x90, 0x13, 0x00, 0x02, 0x94, 0x13, 0x00, 0x02, 0x98, 0x13, 0x00, 0x02, 0x9c, 0x13, 0x00, 0x02, 0xfa, 0x03, 0x01, 0x01, 0xfc, 0x03, 0x01, 0x01, + 0xfe, 0x03, 0x01, 0x01, 0x00, 0x04, 0x01, 0x01, 0x02, 0x04, 0x01, 0x01, 0x04, 0x04, 0x01, 0x01, 0x06, 0x04, 0x01, 0x01, 0x8c, 0x1a, 0x02, 0x02, 0x90, 0x1a, 0x02, 0x02, 0x94, 0x1a, 0x02, 0x02, + 0x98, 0x1a, 0x02, 0x02, 0x38, 0x38, 0x03, 0x03, 0x40, 0x38, 0x03, 0x03, 0x48, 0x38, 0x03, 0x03, 0xe0, 0x0f, 0x04, 0x03, 0xe8, 0x0f, 0x04, 0x03, 0x10, 0x2b, 0x05, 0x04, 0x50, 0x06, 0x06, 0x04, + 0x40, 0x1c, 0x07, 0x05, 0xc0, 0x13, 0x09, 0x06, 0xa0, 0x13, 0x00, 0x02, 0xa4, 0x13, 0x00, 0x02, 0xa8, 0x13, 0x00, 0x02, 0xac, 0x13, 0x00, 0x02, 0x08, 0x04, 0x01, 0x01, 0x0a, 0x04, 0x01, 0x01, + 0x0c, 0x04, 0x01, 0x01, 0x0e, 0x04, 0x01, 0x01, 0x10, 0x04, 0x01, 0x01, 0x12, 0x04, 0x01, 0x01, 0x14, 0x04, 0x01, 0x01, 0x9c, 0x1a, 0x02, 0x02, 0xa0, 0x1a, 0x02, 0x02, 0xa4, 0x1a, 0x02, 0x02, + 0xa8, 0x1a, 0x02, 0x02, 0x50, 0x38, 0x03, 0x03, 0x58, 0x38, 0x03, 0x03, 0x60, 0x38, 0x03, 0x03, 0xf0, 0x0f, 0x04, 0x03, 0xf8, 0x0f, 0x04, 0x03, 0x20, 0x2b, 0x05, 0x04, 0x60, 0x06, 0x06, 0x04, + 0x60, 0x1c, 0x07, 0x05, 0x00, 0x14, 0x09, 0x06, 0xb0, 0x13, 0x00, 0x02, 0xb4, 0x13, 0x00, 0x02, 0xb8, 0x13, 0x00, 0x02, 0xbc, 0x13, 0x00, 0x02, 0x16, 0x04, 0x01, 0x01, 0x18, 0x04, 0x01, 0x01, + 0x1a, 0x04, 0x01, 0x01, 0x1c, 0x04, 0x01, 0x01, 0x1e, 0x04, 0x01, 0x01, 0x20, 0x04, 0x01, 0x01, 0x22, 0x04, 0x01, 0x01, 0xac, 0x1a, 0x02, 0x02, 0xb0, 0x1a, 0x02, 0x02, 0xb4, 0x1a, 0x02, 0x02, + 0xb8, 0x1a, 0x02, 0x02, 0x68, 0x38, 0x03, 0x03, 0x70, 0x38, 0x03, 0x03, 0x78, 0x38, 0x03, 0x03, 0x00, 0x10, 0x04, 0x03, 0x08, 0x10, 0x04, 0x03, 0x30, 0x2b, 0x05, 0x04, 0x70, 0x06, 0x06, 0x04, + 0x80, 0x1c, 0x07, 0x05, 0x40, 0x14, 0x09, 0x06, 0xc0, 0x13, 0x00, 0x02, 0xc4, 0x13, 0x00, 0x02, 0xc8, 0x13, 0x00, 0x02, 0xcc, 0x13, 0x00, 0x02, 0x24, 0x04, 0x01, 0x01, 0x26, 0x04, 0x01, 0x01, + 0x28, 0x04, 0x01, 0x01, 0x2a, 0x04, 0x01, 0x01, 0x2c, 0x04, 0x01, 0x01, 0x2e, 0x04, 0x01, 0x01, 0x30, 0x04, 0x01, 0x01, 0xbc, 0x1a, 0x02, 0x02, 0xc0, 0x1a, 0x02, 0x02, 0xc4, 0x1a, 0x02, 0x02, + 0xc8, 0x1a, 0x02, 0x02, 0x80, 0x38, 0x03, 0x03, 0x88, 0x38, 0x03, 0x03, 0x90, 0x38, 0x03, 0x03, 0x10, 0x10, 0x04, 0x03, 0x18, 0x10, 0x04, 0x03, 0x40, 0x2b, 0x05, 0x04, 0x80, 0x06, 0x06, 0x04, + 0xa0, 0x1c, 0x07, 0x05, 0x80, 0x14, 0x09, 0x06, 0xd0, 0x13, 0x00, 0x02, 0xd4, 0x13, 0x00, 0x02, 0xd8, 0x13, 0x00, 0x02, 0xdc, 0x13, 0x00, 0x02, 0x32, 0x04, 0x01, 0x01, 0x34, 0x04, 0x01, 0x01, + 0x36, 0x04, 0x01, 0x01, 0x38, 0x04, 0x01, 0x01, 0x3a, 0x04, 0x01, 0x01, 0x3c, 0x04, 0x01, 0x01, 0x3e, 0x04, 0x01, 0x01, 0xcc, 0x1a, 0x02, 0x02, 0xd0, 0x1a, 0x02, 0x02, 0xd4, 0x1a, 0x02, 0x02, + 0xd8, 0x1a, 0x02, 0x02, 0x98, 0x38, 0x03, 0x03, 0xa0, 0x38, 0x03, 0x03, 0xa8, 0x38, 0x03, 0x03, 0x20, 0x10, 0x04, 0x03, 0x28, 0x10, 0x04, 0x03, 0x50, 0x2b, 0x05, 0x04, 0x90, 0x06, 0x06, 0x04, + 0xc0, 0x1c, 0x07, 0x05, 0xc0, 0x14, 0x09, 0x06, 0xe0, 0x13, 0x00, 0x02, 0xe4, 0x13, 0x00, 0x02, 0xe8, 0x13, 0x00, 0x02, 0xec, 0x13, 0x00, 0x02, 0x40, 0x04, 0x01, 0x01, 0x42, 0x04, 0x01, 0x01, + 0x44, 0x04, 0x01, 0x01, 0x46, 0x04, 0x01, 0x01, 0x48, 0x04, 0x01, 0x01, 0x4a, 0x04, 0x01, 0x01, 0x4c, 0x04, 0x01, 0x01, 0xdc, 0x1a, 0x02, 0x02, 0xe0, 0x1a, 0x02, 0x02, 0xe4, 0x1a, 0x02, 0x02, + 0xe8, 0x1a, 0x02, 0x02, 0xb0, 0x38, 0x03, 0x03, 0xb8, 0x38, 0x03, 0x03, 0xc0, 0x38, 0x03, 0x03, 0x30, 0x10, 0x04, 0x03, 0x38, 0x10, 0x04, 0x03, 0x60, 0x2b, 0x05, 0x04, 0xa0, 0x06, 0x06, 0x04, + 0xe0, 0x1c, 0x07, 0x05, 0x00, 0x15, 0x09, 0x06, 0xf0, 0x13, 0x00, 0x02, 0xf4, 0x13, 0x00, 0x02, 0xf8, 0x13, 0x00, 0x02, 0xfc, 0x13, 0x00, 0x02, 0x4e, 0x04, 0x01, 0x01, 0x50, 0x04, 0x01, 0x01, + 0x52, 0x04, 0x01, 0x01, 0x54, 0x04, 0x01, 0x01, 0x56, 0x04, 0x01, 0x01, 0x58, 0x04, 0x01, 0x01, 0x5a, 0x04, 0x01, 0x01, 0xec, 0x1a, 0x02, 0x02, 0xf0, 0x1a, 0x02, 0x02, 0xf4, 0x1a, 0x02, 0x02, + 0xf8, 0x1a, 0x02, 0x02, 0xc8, 0x38, 0x03, 0x03, 0xd0, 0x38, 0x03, 0x03, 0xd8, 0x38, 0x03, 0x03, 0x40, 0x10, 0x04, 0x03, 0x48, 0x10, 0x04, 0x03, 0x70, 0x2b, 0x05, 0x04, 0xb0, 0x06, 0x06, 0x04, + 0x00, 0x1d, 0x07, 0x05, 0x40, 0x15, 0x09, 0x06, 0x00, 0x14, 0x00, 0x02, 0x04, 0x14, 0x00, 0x02, 0x08, 0x14, 0x00, 0x02, 0x0c, 0x14, 0x00, 0x02, 0x5c, 0x04, 0x01, 0x01, 0x5e, 0x04, 0x01, 0x01, + 0x60, 0x04, 0x01, 0x01, 0x62, 0x04, 0x01, 0x01, 0x64, 0x04, 0x01, 0x01, 0x66, 0x04, 0x01, 0x01, 0x68, 0x04, 0x01, 0x01, 0xfc, 0x1a, 0x02, 0x02, 0x00, 0x1b, 0x02, 0x02, 0x04, 0x1b, 0x02, 0x02, + 0x08, 0x1b, 0x02, 0x02, 0xe0, 0x38, 0x03, 0x03, 0xe8, 0x38, 0x03, 0x03, 0xf0, 0x38, 0x03, 0x03, 0x50, 0x10, 0x04, 0x03, 0x58, 0x10, 0x04, 0x03, 0x80, 0x2b, 0x05, 0x04, 0xc0, 0x06, 0x06, 0x04, + 0x20, 0x1d, 0x07, 0x05, 0x00, 0x2b, 0x0a, 0x07, 0x10, 0x14, 0x00, 0x02, 0x14, 0x14, 0x00, 0x02, 0x18, 0x14, 0x00, 0x02, 0x1c, 0x14, 0x00, 0x02, 0x6a, 0x04, 0x01, 0x01, 0x6c, 0x04, 0x01, 0x01, + 0x6e, 0x04, 0x01, 0x01, 0x70, 0x04, 0x01, 0x01, 0x72, 0x04, 0x01, 0x01, 0x74, 0x04, 0x01, 0x01, 0x76, 0x04, 0x01, 0x01, 0x0c, 0x1b, 0x02, 0x02, 0x10, 0x1b, 0x02, 0x02, 0x14, 0x1b, 0x02, 0x02, + 0x18, 0x1b, 0x02, 0x02, 0xf8, 0x38, 0x03, 0x03, 0x00, 0x39, 0x03, 0x03, 0x08, 0x39, 0x03, 0x03, 0x60, 0x10, 0x04, 0x03, 0x68, 0x10, 0x04, 0x03, 0x90, 0x2b, 0x05, 0x04, 0xd0, 0x06, 0x06, 0x04, + 0x40, 0x1d, 0x07, 0x05, 0x80, 0x2b, 0x0a, 0x07, 0x20, 0x14, 0x00, 0x02, 0x24, 0x14, 0x00, 0x02, 0x28, 0x14, 0x00, 0x02, 0x2c, 0x14, 0x00, 0x02, 0x78, 0x04, 0x01, 0x01, 0x7a, 0x04, 0x01, 0x01, + 0x7c, 0x04, 0x01, 0x01, 0x7e, 0x04, 0x01, 0x01, 0x80, 0x04, 0x01, 0x01, 0x82, 0x04, 0x01, 0x01, 0x84, 0x04, 0x01, 0x01, 0x1c, 0x1b, 0x02, 0x02, 0x20, 0x1b, 0x02, 0x02, 0x24, 0x1b, 0x02, 0x02, + 0x28, 0x1b, 0x02, 0x02, 0x10, 0x39, 0x03, 0x03, 0x18, 0x39, 0x03, 0x03, 0x20, 0x39, 0x03, 0x03, 0x70, 0x10, 0x04, 0x03, 0x78, 0x10, 0x04, 0x03, 0xa0, 0x2b, 0x05, 0x04, 0xe0, 0x06, 0x06, 0x04, + 0x60, 0x1d, 0x07, 0x05, 0x00, 0x2c, 0x0a, 0x07, 0x30, 0x14, 0x00, 0x02, 0x34, 0x14, 0x00, 0x02, 0x38, 0x14, 0x00, 0x02, 0x3c, 0x14, 0x00, 0x02, 0x86, 0x04, 0x01, 0x01, 0x88, 0x04, 0x01, 0x01, + 0x8a, 0x04, 0x01, 0x01, 0x8c, 0x04, 0x01, 0x01, 0x8e, 0x04, 0x01, 0x01, 0x90, 0x04, 0x01, 0x01, 0x92, 0x04, 0x01, 0x01, 0x2c, 0x1b, 0x02, 0x02, 0x30, 0x1b, 0x02, 0x02, 0x34, 0x1b, 0x02, 0x02, + 0x38, 0x1b, 0x02, 0x02, 0x28, 0x39, 0x03, 0x03, 0x30, 0x39, 0x03, 0x03, 0x38, 0x39, 0x03, 0x03, 0x80, 0x10, 0x04, 0x03, 0x88, 0x10, 0x04, 0x03, 0xb0, 0x2b, 0x05, 0x04, 0xf0, 0x06, 0x06, 0x04, + 0x80, 0x1d, 0x07, 0x05, 0x80, 0x2c, 0x0a, 0x07, 0x40, 0x14, 0x00, 0x02, 0x44, 0x14, 0x00, 0x02, 0x48, 0x14, 0x00, 0x02, 0x4c, 0x14, 0x00, 0x02, 0x94, 0x04, 0x01, 0x01, 0x96, 0x04, 0x01, 0x01, + 0x98, 0x04, 0x01, 0x01, 0x9a, 0x04, 0x01, 0x01, 0x9c, 0x04, 0x01, 0x01, 0x9e, 0x04, 0x01, 0x01, 0xa0, 0x04, 0x01, 0x01, 0x3c, 0x1b, 0x02, 0x02, 0x40, 0x1b, 0x02, 0x02, 0x44, 0x1b, 0x02, 0x02, + 0x48, 0x1b, 0x02, 0x02, 0x40, 0x39, 0x03, 0x03, 0x48, 0x39, 0x03, 0x03, 0x50, 0x39, 0x03, 0x03, 0x90, 0x10, 0x04, 0x03, 0x98, 0x10, 0x04, 0x03, 0xc0, 0x2b, 0x05, 0x04, 0x00, 0x07, 0x06, 0x04, + 0xa0, 0x1d, 0x07, 0x05, 0x00, 0x2d, 0x0a, 0x07, 0x50, 0x14, 0x00, 0x02, 0x54, 0x14, 0x00, 0x02, 0x58, 0x14, 0x00, 0x02, 0x5c, 0x14, 0x00, 0x02, 0xa2, 0x04, 0x01, 0x01, 0xa4, 0x04, 0x01, 0x01, + 0xa6, 0x04, 0x01, 0x01, 0xa8, 0x04, 0x01, 0x01, 0xaa, 0x04, 0x01, 0x01, 0xac, 0x04, 0x01, 0x01, 0xae, 0x04, 0x01, 0x01, 0x4c, 0x1b, 0x02, 0x02, 0x50, 0x1b, 0x02, 0x02, 0x54, 0x1b, 0x02, 0x02, + 0x58, 0x1b, 0x02, 0x02, 0x58, 0x39, 0x03, 0x03, 0x60, 0x39, 0x03, 0x03, 0x68, 0x39, 0x03, 0x03, 0xa0, 0x10, 0x04, 0x03, 0xa8, 0x10, 0x04, 0x03, 0xd0, 0x2b, 0x05, 0x04, 0x10, 0x07, 0x06, 0x04, + 0xc0, 0x1d, 0x07, 0x05, 0x80, 0x2d, 0x0a, 0x07, 0x60, 0x14, 0x00, 0x02, 0x64, 0x14, 0x00, 0x02, 0x68, 0x14, 0x00, 0x02, 0x6c, 0x14, 0x00, 0x02, 0xb0, 0x04, 0x01, 0x01, 0xb2, 0x04, 0x01, 0x01, + 0xb4, 0x04, 0x01, 0x01, 0xb6, 0x04, 0x01, 0x01, 0xb8, 0x04, 0x01, 0x01, 0xba, 0x04, 0x01, 0x01, 0xbc, 0x04, 0x01, 0x01, 0x5c, 0x1b, 0x02, 0x02, 0x60, 0x1b, 0x02, 0x02, 0x64, 0x1b, 0x02, 0x02, + 0x68, 0x1b, 0x02, 0x02, 0x70, 0x39, 0x03, 0x03, 0x78, 0x39, 0x03, 0x03, 0x80, 0x39, 0x03, 0x03, 0xb0, 0x10, 0x04, 0x03, 0xb8, 0x10, 0x04, 0x03, 0xe0, 0x2b, 0x05, 0x04, 0x20, 0x07, 0x06, 0x04, + 0xe0, 0x1d, 0x07, 0x05, 0x00, 0x2e, 0x0a, 0x07, 0x70, 0x14, 0x00, 0x02, 0x74, 0x14, 0x00, 0x02, 0x78, 0x14, 0x00, 0x02, 0x7c, 0x14, 0x00, 0x02, 0xbe, 0x04, 0x01, 0x01, 0xc0, 0x04, 0x01, 0x01, + 0xc2, 0x04, 0x01, 0x01, 0xc4, 0x04, 0x01, 0x01, 0xc6, 0x04, 0x01, 0x01, 0xc8, 0x04, 0x01, 0x01, 0xca, 0x04, 0x01, 0x01, 0x6c, 0x1b, 0x02, 0x02, 0x70, 0x1b, 0x02, 0x02, 0x74, 0x1b, 0x02, 0x02, + 0x78, 0x1b, 0x02, 0x02, 0x88, 0x39, 0x03, 0x03, 0x90, 0x39, 0x03, 0x03, 0x98, 0x39, 0x03, 0x03, 0xc0, 0x10, 0x04, 0x03, 0xc8, 0x10, 0x04, 0x03, 0xf0, 0x2b, 0x05, 0x04, 0x30, 0x07, 0x06, 0x04, + 0x00, 0x1e, 0x07, 0x05, 0x80, 0x2e, 0x0a, 0x07, 0x80, 0x14, 0x00, 0x02, 0x84, 0x14, 0x00, 0x02, 0x88, 0x14, 0x00, 0x02, 0x8c, 0x14, 0x00, 0x02, 0xcc, 0x04, 0x01, 0x01, 0xce, 0x04, 0x01, 0x01, + 0xd0, 0x04, 0x01, 0x01, 0xd2, 0x04, 0x01, 0x01, 0xd4, 0x04, 0x01, 0x01, 0xd6, 0x04, 0x01, 0x01, 0xd8, 0x04, 0x01, 0x01, 0x7c, 0x1b, 0x02, 0x02, 0x80, 0x1b, 0x02, 0x02, 0x84, 0x1b, 0x02, 0x02, + 0x88, 0x1b, 0x02, 0x02, 0xa0, 0x39, 0x03, 0x03, 0xa8, 0x39, 0x03, 0x03, 0xb0, 0x39, 0x03, 0x03, 0xd0, 0x10, 0x04, 0x03, 0xd8, 0x10, 0x04, 0x03, 0x00, 0x2c, 0x05, 0x04, 0x40, 0x07, 0x06, 0x04, + 0x20, 0x1e, 0x07, 0x05, 0x00, 0x2f, 0x0a, 0x07, 0x90, 0x14, 0x00, 0x02, 0x94, 0x14, 0x00, 0x02, 0x98, 0x14, 0x00, 0x02, 0x9c, 0x14, 0x00, 0x02, 0xda, 0x04, 0x01, 0x01, 0xdc, 0x04, 0x01, 0x01, + 0xde, 0x04, 0x01, 0x01, 0xe0, 0x04, 0x01, 0x01, 0xe2, 0x04, 0x01, 0x01, 0xe4, 0x04, 0x01, 0x01, 0xe6, 0x04, 0x01, 0x01, 0x8c, 0x1b, 0x02, 0x02, 0x90, 0x1b, 0x02, 0x02, 0x94, 0x1b, 0x02, 0x02, + 0x98, 0x1b, 0x02, 0x02, 0xb8, 0x39, 0x03, 0x03, 0xc0, 0x39, 0x03, 0x03, 0xc8, 0x39, 0x03, 0x03, 0xe0, 0x10, 0x04, 0x03, 0xe8, 0x10, 0x04, 0x03, 0x10, 0x2c, 0x05, 0x04, 0x50, 0x07, 0x06, 0x04, + 0x40, 0x1e, 0x07, 0x05, 0x80, 0x2f, 0x0a, 0x07, 0xa0, 0x14, 0x00, 0x02, 0xa4, 0x14, 0x00, 0x02, 0xa8, 0x14, 0x00, 0x02, 0xac, 0x14, 0x00, 0x02, 0xe8, 0x04, 0x01, 0x01, 0xea, 0x04, 0x01, 0x01, + 0xec, 0x04, 0x01, 0x01, 0xee, 0x04, 0x01, 0x01, 0xf0, 0x04, 0x01, 0x01, 0xf2, 0x04, 0x01, 0x01, 0xf4, 0x04, 0x01, 0x01, 0x9c, 0x1b, 0x02, 0x02, 0xa0, 0x1b, 0x02, 0x02, 0xa4, 0x1b, 0x02, 0x02, + 0xa8, 0x1b, 0x02, 0x02, 0xd0, 0x39, 0x03, 0x03, 0xd8, 0x39, 0x03, 0x03, 0xe0, 0x39, 0x03, 0x03, 0xf0, 0x10, 0x04, 0x03, 0xf8, 0x10, 0x04, 0x03, 0x20, 0x2c, 0x05, 0x04, 0x60, 0x07, 0x06, 0x04, + 0x60, 0x1e, 0x07, 0x05, 0x00, 0x30, 0x0a, 0x07, 0xb0, 0x14, 0x00, 0x02, 0xb4, 0x14, 0x00, 0x02, 0xb8, 0x14, 0x00, 0x02, 0xbc, 0x14, 0x00, 0x02, 0xf6, 0x04, 0x01, 0x01, 0xf8, 0x04, 0x01, 0x01, + 0xfa, 0x04, 0x01, 0x01, 0xfc, 0x04, 0x01, 0x01, 0xfe, 0x04, 0x01, 0x01, 0x00, 0x05, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0xac, 0x1b, 0x02, 0x02, 0xb0, 0x1b, 0x02, 0x02, 0xb4, 0x1b, 0x02, 0x02, + 0xb8, 0x1b, 0x02, 0x02, 0xe8, 0x39, 0x03, 0x03, 0xf0, 0x39, 0x03, 0x03, 0xf8, 0x39, 0x03, 0x03, 0x00, 0x11, 0x04, 0x03, 0x08, 0x11, 0x04, 0x03, 0x30, 0x2c, 0x05, 0x04, 0x70, 0x07, 0x06, 0x04, + 0x80, 0x1e, 0x07, 0x05, 0x80, 0x30, 0x0a, 0x07, 0xc0, 0x14, 0x00, 0x02, 0xc4, 0x14, 0x00, 0x02, 0xc8, 0x14, 0x00, 0x02, 0xcc, 0x14, 0x00, 0x02, 0x04, 0x05, 0x01, 0x01, 0x06, 0x05, 0x01, 0x01, + 0x08, 0x05, 0x01, 0x01, 0x0a, 0x05, 0x01, 0x01, 0x0c, 0x05, 0x01, 0x01, 0x0e, 0x05, 0x01, 0x01, 0x10, 0x05, 0x01, 0x01, 0xbc, 0x1b, 0x02, 0x02, 0xc0, 0x1b, 0x02, 0x02, 0xc4, 0x1b, 0x02, 0x02, + 0xc8, 0x1b, 0x02, 0x02, 0x00, 0x3a, 0x03, 0x03, 0x08, 0x3a, 0x03, 0x03, 0x10, 0x3a, 0x03, 0x03, 0x10, 0x11, 0x04, 0x03, 0x18, 0x11, 0x04, 0x03, 0x40, 0x2c, 0x05, 0x04, 0x80, 0x07, 0x06, 0x04, + 0xa0, 0x1e, 0x07, 0x05, 0x00, 0x31, 0x0a, 0x07, 0xd0, 0x14, 0x00, 0x02, 0xd4, 0x14, 0x00, 0x02, 0xd8, 0x14, 0x00, 0x02, 0xdc, 0x14, 0x00, 0x02, 0x12, 0x05, 0x01, 0x01, 0x14, 0x05, 0x01, 0x01, + 0x16, 0x05, 0x01, 0x01, 0x18, 0x05, 0x01, 0x01, 0x1a, 0x05, 0x01, 0x01, 0x1c, 0x05, 0x01, 0x01, 0x1e, 0x05, 0x01, 0x01, 0xcc, 0x1b, 0x02, 0x02, 0xd0, 0x1b, 0x02, 0x02, 0xd4, 0x1b, 0x02, 0x02, + 0xd8, 0x1b, 0x02, 0x02, 0x18, 0x3a, 0x03, 0x03, 0x20, 0x3a, 0x03, 0x03, 0x28, 0x3a, 0x03, 0x03, 0x20, 0x11, 0x04, 0x03, 0x28, 0x11, 0x04, 0x03, 0x50, 0x2c, 0x05, 0x04, 0x90, 0x07, 0x06, 0x04, + 0xc0, 0x1e, 0x07, 0x05, 0x80, 0x31, 0x0a, 0x07, 0xe0, 0x14, 0x00, 0x02, 0xe4, 0x14, 0x00, 0x02, 0xe8, 0x14, 0x00, 0x02, 0xec, 0x14, 0x00, 0x02, 0x20, 0x05, 0x01, 0x01, 0x22, 0x05, 0x01, 0x01, + 0x24, 0x05, 0x01, 0x01, 0x26, 0x05, 0x01, 0x01, 0x28, 0x05, 0x01, 0x01, 0x2a, 0x05, 0x01, 0x01, 0x2c, 0x05, 0x01, 0x01, 0xdc, 0x1b, 0x02, 0x02, 0xe0, 0x1b, 0x02, 0x02, 0xe4, 0x1b, 0x02, 0x02, + 0xe8, 0x1b, 0x02, 0x02, 0x30, 0x3a, 0x03, 0x03, 0x38, 0x3a, 0x03, 0x03, 0x40, 0x3a, 0x03, 0x03, 0x30, 0x11, 0x04, 0x03, 0x38, 0x11, 0x04, 0x03, 0x60, 0x2c, 0x05, 0x04, 0xa0, 0x07, 0x06, 0x04, + 0xe0, 0x1e, 0x07, 0x05, 0x00, 0x07, 0x0b, 0x07, 0xf0, 0x14, 0x00, 0x02, 0xf4, 0x14, 0x00, 0x02, 0xf8, 0x14, 0x00, 0x02, 0xfc, 0x14, 0x00, 0x02, 0x2e, 0x05, 0x01, 0x01, 0x30, 0x05, 0x01, 0x01, + 0x32, 0x05, 0x01, 0x01, 0x34, 0x05, 0x01, 0x01, 0x36, 0x05, 0x01, 0x01, 0x38, 0x05, 0x01, 0x01, 0x3a, 0x05, 0x01, 0x01, 0xec, 0x1b, 0x02, 0x02, 0xf0, 0x1b, 0x02, 0x02, 0xf4, 0x1b, 0x02, 0x02, + 0xf8, 0x1b, 0x02, 0x02, 0x48, 0x3a, 0x03, 0x03, 0x50, 0x3a, 0x03, 0x03, 0x58, 0x3a, 0x03, 0x03, 0x40, 0x11, 0x04, 0x03, 0x48, 0x11, 0x04, 0x03, 0x70, 0x2c, 0x05, 0x04, 0xb0, 0x07, 0x06, 0x04, + 0x00, 0x1f, 0x07, 0x05, 0x80, 0x07, 0x0b, 0x07, 0x00, 0x15, 0x00, 0x02, 0x04, 0x15, 0x00, 0x02, 0x08, 0x15, 0x00, 0x02, 0x0c, 0x15, 0x00, 0x02, 0x3c, 0x05, 0x01, 0x01, 0x3e, 0x05, 0x01, 0x01, + 0x40, 0x05, 0x01, 0x01, 0x42, 0x05, 0x01, 0x01, 0x44, 0x05, 0x01, 0x01, 0x46, 0x05, 0x01, 0x01, 0x48, 0x05, 0x01, 0x01, 0xfc, 0x1b, 0x02, 0x02, 0x00, 0x1c, 0x02, 0x02, 0x04, 0x1c, 0x02, 0x02, + 0x08, 0x1c, 0x02, 0x02, 0x60, 0x3a, 0x03, 0x03, 0x68, 0x3a, 0x03, 0x03, 0x70, 0x3a, 0x03, 0x03, 0x50, 0x11, 0x04, 0x03, 0x58, 0x11, 0x04, 0x03, 0x80, 0x2c, 0x05, 0x04, 0xc0, 0x07, 0x06, 0x04, + 0x20, 0x1f, 0x07, 0x05, 0x00, 0x08, 0x0b, 0x07, 0x10, 0x15, 0x00, 0x02, 0x14, 0x15, 0x00, 0x02, 0x18, 0x15, 0x00, 0x02, 0x1c, 0x15, 0x00, 0x02, 0x4a, 0x05, 0x01, 0x01, 0x4c, 0x05, 0x01, 0x01, + 0x4e, 0x05, 0x01, 0x01, 0x50, 0x05, 0x01, 0x01, 0x52, 0x05, 0x01, 0x01, 0x54, 0x05, 0x01, 0x01, 0x56, 0x05, 0x01, 0x01, 0x0c, 0x1c, 0x02, 0x02, 0x10, 0x1c, 0x02, 0x02, 0x14, 0x1c, 0x02, 0x02, + 0x18, 0x1c, 0x02, 0x02, 0x78, 0x3a, 0x03, 0x03, 0x80, 0x3a, 0x03, 0x03, 0x88, 0x3a, 0x03, 0x03, 0x60, 0x11, 0x04, 0x03, 0x68, 0x11, 0x04, 0x03, 0x90, 0x2c, 0x05, 0x04, 0xd0, 0x07, 0x06, 0x04, + 0x40, 0x1f, 0x07, 0x05, 0x80, 0x08, 0x0b, 0x07, 0x20, 0x15, 0x00, 0x02, 0x24, 0x15, 0x00, 0x02, 0x28, 0x15, 0x00, 0x02, 0x2c, 0x15, 0x00, 0x02, 0x58, 0x05, 0x01, 0x01, 0x5a, 0x05, 0x01, 0x01, + 0x5c, 0x05, 0x01, 0x01, 0x5e, 0x05, 0x01, 0x01, 0x60, 0x05, 0x01, 0x01, 0x62, 0x05, 0x01, 0x01, 0x64, 0x05, 0x01, 0x01, 0x1c, 0x1c, 0x02, 0x02, 0x20, 0x1c, 0x02, 0x02, 0x24, 0x1c, 0x02, 0x02, + 0x28, 0x1c, 0x02, 0x02, 0x90, 0x3a, 0x03, 0x03, 0x98, 0x3a, 0x03, 0x03, 0xa0, 0x3a, 0x03, 0x03, 0x70, 0x11, 0x04, 0x03, 0x78, 0x11, 0x04, 0x03, 0xa0, 0x2c, 0x05, 0x04, 0xe0, 0x07, 0x06, 0x04, + 0x60, 0x1f, 0x07, 0x05, 0x00, 0x09, 0x0b, 0x07, 0x30, 0x15, 0x00, 0x02, 0x34, 0x15, 0x00, 0x02, 0x38, 0x15, 0x00, 0x02, 0x3c, 0x15, 0x00, 0x02, 0x66, 0x05, 0x01, 0x01, 0x68, 0x05, 0x01, 0x01, + 0x6a, 0x05, 0x01, 0x01, 0x6c, 0x05, 0x01, 0x01, 0x6e, 0x05, 0x01, 0x01, 0x70, 0x05, 0x01, 0x01, 0x72, 0x05, 0x01, 0x01, 0x2c, 0x1c, 0x02, 0x02, 0x30, 0x1c, 0x02, 0x02, 0x34, 0x1c, 0x02, 0x02, + 0x38, 0x1c, 0x02, 0x02, 0xa8, 0x3a, 0x03, 0x03, 0xb0, 0x3a, 0x03, 0x03, 0xb8, 0x3a, 0x03, 0x03, 0x80, 0x11, 0x04, 0x03, 0x88, 0x11, 0x04, 0x03, 0xb0, 0x2c, 0x05, 0x04, 0xf0, 0x07, 0x06, 0x04, + 0x80, 0x1f, 0x07, 0x05, 0x80, 0x09, 0x0b, 0x07, 0x40, 0x15, 0x00, 0x02, 0x44, 0x15, 0x00, 0x02, 0x48, 0x15, 0x00, 0x02, 0x4c, 0x15, 0x00, 0x02, 0x74, 0x05, 0x01, 0x01, 0x76, 0x05, 0x01, 0x01, + 0x78, 0x05, 0x01, 0x01, 0x7a, 0x05, 0x01, 0x01, 0x7c, 0x05, 0x01, 0x01, 0x7e, 0x05, 0x01, 0x01, 0x80, 0x05, 0x01, 0x01, 0x3c, 0x1c, 0x02, 0x02, 0x40, 0x1c, 0x02, 0x02, 0x44, 0x1c, 0x02, 0x02, + 0x48, 0x1c, 0x02, 0x02, 0xc0, 0x3a, 0x03, 0x03, 0xc8, 0x3a, 0x03, 0x03, 0xd0, 0x3a, 0x03, 0x03, 0x90, 0x11, 0x04, 0x03, 0x98, 0x11, 0x04, 0x03, 0xc0, 0x2c, 0x05, 0x04, 0x00, 0x08, 0x06, 0x04, + 0xa0, 0x1f, 0x07, 0x05, 0x00, 0x0a, 0x0b, 0x07, 0x50, 0x15, 0x00, 0x02, 0x54, 0x15, 0x00, 0x02, 0x58, 0x15, 0x00, 0x02, 0x5c, 0x15, 0x00, 0x02, 0x82, 0x05, 0x01, 0x01, 0x84, 0x05, 0x01, 0x01, + 0x86, 0x05, 0x01, 0x01, 0x88, 0x05, 0x01, 0x01, 0x8a, 0x05, 0x01, 0x01, 0x8c, 0x05, 0x01, 0x01, 0x8e, 0x05, 0x01, 0x01, 0x4c, 0x1c, 0x02, 0x02, 0x50, 0x1c, 0x02, 0x02, 0x54, 0x1c, 0x02, 0x02, + 0x58, 0x1c, 0x02, 0x02, 0xd8, 0x3a, 0x03, 0x03, 0xe0, 0x3a, 0x03, 0x03, 0xe8, 0x3a, 0x03, 0x03, 0xa0, 0x11, 0x04, 0x03, 0xa8, 0x11, 0x04, 0x03, 0xd0, 0x2c, 0x05, 0x04, 0x10, 0x08, 0x06, 0x04, + 0xc0, 0x1f, 0x07, 0x05, 0x80, 0x0a, 0x0b, 0x07, 0x60, 0x15, 0x00, 0x02, 0x64, 0x15, 0x00, 0x02, 0x68, 0x15, 0x00, 0x02, 0x6c, 0x15, 0x00, 0x02, 0x90, 0x05, 0x01, 0x01, 0x92, 0x05, 0x01, 0x01, + 0x94, 0x05, 0x01, 0x01, 0x96, 0x05, 0x01, 0x01, 0x98, 0x05, 0x01, 0x01, 0x9a, 0x05, 0x01, 0x01, 0x9c, 0x05, 0x01, 0x01, 0x5c, 0x1c, 0x02, 0x02, 0x60, 0x1c, 0x02, 0x02, 0x64, 0x1c, 0x02, 0x02, + 0x68, 0x1c, 0x02, 0x02, 0xf0, 0x3a, 0x03, 0x03, 0xf8, 0x3a, 0x03, 0x03, 0x00, 0x3b, 0x03, 0x03, 0xb0, 0x11, 0x04, 0x03, 0xb8, 0x11, 0x04, 0x03, 0xe0, 0x2c, 0x05, 0x04, 0x20, 0x08, 0x06, 0x04, + 0xe0, 0x1f, 0x07, 0x05, 0x00, 0x0b, 0x0b, 0x07, 0x70, 0x15, 0x00, 0x02, 0x74, 0x15, 0x00, 0x02, 0x78, 0x15, 0x00, 0x02, 0x7c, 0x15, 0x00, 0x02, 0x9e, 0x05, 0x01, 0x01, 0xa0, 0x05, 0x01, 0x01, + 0xa2, 0x05, 0x01, 0x01, 0xa4, 0x05, 0x01, 0x01, 0xa6, 0x05, 0x01, 0x01, 0xa8, 0x05, 0x01, 0x01, 0x6c, 0x1c, 0x02, 0x02, 0x70, 0x1c, 0x02, 0x02, 0x74, 0x1c, 0x02, 0x02, 0x78, 0x1c, 0x02, 0x02, + 0x7c, 0x1c, 0x02, 0x02, 0x08, 0x3b, 0x03, 0x03, 0x10, 0x3b, 0x03, 0x03, 0x18, 0x3b, 0x03, 0x03, 0xc0, 0x11, 0x04, 0x03, 0xc8, 0x11, 0x04, 0x03, 0xf0, 0x2c, 0x05, 0x04, 0x30, 0x08, 0x06, 0x04, + 0x00, 0x20, 0x07, 0x05, 0x80, 0x0b, 0x0b, 0x07, 0x80, 0x15, 0x00, 0x02, 0x84, 0x15, 0x00, 0x02, 0x88, 0x15, 0x00, 0x02, 0x8c, 0x15, 0x00, 0x02, 0xaa, 0x05, 0x01, 0x01, 0xac, 0x05, 0x01, 0x01, + 0xae, 0x05, 0x01, 0x01, 0xb0, 0x05, 0x01, 0x01, 0xb2, 0x05, 0x01, 0x01, 0xb4, 0x05, 0x01, 0x01, 0x80, 0x1c, 0x02, 0x02, 0x84, 0x1c, 0x02, 0x02, 0x88, 0x1c, 0x02, 0x02, 0x8c, 0x1c, 0x02, 0x02, + 0x90, 0x1c, 0x02, 0x02, 0x20, 0x3b, 0x03, 0x03, 0x28, 0x3b, 0x03, 0x03, 0x30, 0x3b, 0x03, 0x03, 0xd0, 0x11, 0x04, 0x03, 0xd8, 0x11, 0x04, 0x03, 0x00, 0x2d, 0x05, 0x04, 0x40, 0x08, 0x06, 0x04, + 0x20, 0x20, 0x07, 0x05, 0x00, 0x1e, 0x0c, 0x08, 0x90, 0x15, 0x00, 0x02, 0x94, 0x15, 0x00, 0x02, 0x98, 0x15, 0x00, 0x02, 0x9c, 0x15, 0x00, 0x02, 0xb6, 0x05, 0x01, 0x01, 0xb8, 0x05, 0x01, 0x01, + 0xba, 0x05, 0x01, 0x01, 0xbc, 0x05, 0x01, 0x01, 0xbe, 0x05, 0x01, 0x01, 0xc0, 0x05, 0x01, 0x01, 0x94, 0x1c, 0x02, 0x02, 0x98, 0x1c, 0x02, 0x02, 0x9c, 0x1c, 0x02, 0x02, 0xa0, 0x1c, 0x02, 0x02, + 0xa4, 0x1c, 0x02, 0x02, 0x38, 0x3b, 0x03, 0x03, 0x40, 0x3b, 0x03, 0x03, 0x48, 0x3b, 0x03, 0x03, 0xe0, 0x11, 0x04, 0x03, 0xe8, 0x11, 0x04, 0x03, 0x10, 0x2d, 0x05, 0x04, 0x50, 0x08, 0x06, 0x04, + 0x40, 0x20, 0x07, 0x05, 0x00, 0x1f, 0x0c, 0x08, 0xa0, 0x15, 0x00, 0x02, 0xa4, 0x15, 0x00, 0x02, 0xa8, 0x15, 0x00, 0x02, 0xac, 0x15, 0x00, 0x02, 0xc2, 0x05, 0x01, 0x01, 0xc4, 0x05, 0x01, 0x01, + 0xc6, 0x05, 0x01, 0x01, 0xc8, 0x05, 0x01, 0x01, 0xca, 0x05, 0x01, 0x01, 0xcc, 0x05, 0x01, 0x01, 0xa8, 0x1c, 0x02, 0x02, 0xac, 0x1c, 0x02, 0x02, 0xb0, 0x1c, 0x02, 0x02, 0xb4, 0x1c, 0x02, 0x02, + 0xb8, 0x1c, 0x02, 0x02, 0x50, 0x3b, 0x03, 0x03, 0x58, 0x3b, 0x03, 0x03, 0x60, 0x3b, 0x03, 0x03, 0xf0, 0x11, 0x04, 0x03, 0xf8, 0x11, 0x04, 0x03, 0x20, 0x2d, 0x05, 0x04, 0x60, 0x08, 0x06, 0x04, + 0x60, 0x20, 0x07, 0x05, 0x00, 0x20, 0x0c, 0x08, 0xb0, 0x15, 0x00, 0x02, 0xb4, 0x15, 0x00, 0x02, 0xb8, 0x15, 0x00, 0x02, 0xbc, 0x15, 0x00, 0x02, 0xce, 0x05, 0x01, 0x01, 0xd0, 0x05, 0x01, 0x01, + 0xd2, 0x05, 0x01, 0x01, 0xd4, 0x05, 0x01, 0x01, 0xd6, 0x05, 0x01, 0x01, 0xd8, 0x05, 0x01, 0x01, 0xbc, 0x1c, 0x02, 0x02, 0xc0, 0x1c, 0x02, 0x02, 0xc4, 0x1c, 0x02, 0x02, 0xc8, 0x1c, 0x02, 0x02, + 0xcc, 0x1c, 0x02, 0x02, 0x68, 0x3b, 0x03, 0x03, 0x70, 0x3b, 0x03, 0x03, 0x78, 0x3b, 0x03, 0x03, 0x00, 0x12, 0x04, 0x03, 0x08, 0x12, 0x04, 0x03, 0x30, 0x2d, 0x05, 0x04, 0x70, 0x08, 0x06, 0x04, + 0x80, 0x20, 0x07, 0x05, 0x00, 0x21, 0x0c, 0x08, 0xc0, 0x15, 0x00, 0x02, 0xc4, 0x15, 0x00, 0x02, 0xc8, 0x15, 0x00, 0x02, 0xcc, 0x15, 0x00, 0x02, 0xda, 0x05, 0x01, 0x01, 0xdc, 0x05, 0x01, 0x01, + 0xde, 0x05, 0x01, 0x01, 0xe0, 0x05, 0x01, 0x01, 0xe2, 0x05, 0x01, 0x01, 0xe4, 0x05, 0x01, 0x01, 0xd0, 0x1c, 0x02, 0x02, 0xd4, 0x1c, 0x02, 0x02, 0xd8, 0x1c, 0x02, 0x02, 0xdc, 0x1c, 0x02, 0x02, + 0xe0, 0x1c, 0x02, 0x02, 0x80, 0x3b, 0x03, 0x03, 0x88, 0x3b, 0x03, 0x03, 0x90, 0x3b, 0x03, 0x03, 0x10, 0x12, 0x04, 0x03, 0x18, 0x12, 0x04, 0x03, 0x40, 0x2d, 0x05, 0x04, 0x80, 0x08, 0x06, 0x04, + 0xa0, 0x20, 0x07, 0x05, 0x00, 0x22, 0x0c, 0x08, 0xd0, 0x15, 0x00, 0x02, 0xd4, 0x15, 0x00, 0x02, 0xd8, 0x15, 0x00, 0x02, 0xdc, 0x15, 0x00, 0x02, 0xe6, 0x05, 0x01, 0x01, 0xe8, 0x05, 0x01, 0x01, + 0xea, 0x05, 0x01, 0x01, 0xec, 0x05, 0x01, 0x01, 0xee, 0x05, 0x01, 0x01, 0xf0, 0x05, 0x01, 0x01, 0xe4, 0x1c, 0x02, 0x02, 0xe8, 0x1c, 0x02, 0x02, 0xec, 0x1c, 0x02, 0x02, 0xf0, 0x1c, 0x02, 0x02, + 0xf4, 0x1c, 0x02, 0x02, 0x98, 0x3b, 0x03, 0x03, 0xa0, 0x3b, 0x03, 0x03, 0xa8, 0x3b, 0x03, 0x03, 0x20, 0x12, 0x04, 0x03, 0x28, 0x12, 0x04, 0x03, 0x50, 0x2d, 0x05, 0x04, 0x90, 0x08, 0x06, 0x04, + 0xc0, 0x20, 0x07, 0x05, 0x00, 0x23, 0x0c, 0x08, 0xe0, 0x15, 0x00, 0x02, 0xe4, 0x15, 0x00, 0x02, 0xe8, 0x15, 0x00, 0x02, 0xec, 0x15, 0x00, 0x02, 0xf2, 0x05, 0x01, 0x01, 0xf4, 0x05, 0x01, 0x01, + 0xf6, 0x05, 0x01, 0x01, 0xf8, 0x05, 0x01, 0x01, 0xfa, 0x05, 0x01, 0x01, 0xfc, 0x05, 0x01, 0x01, 0xf8, 0x1c, 0x02, 0x02, 0xfc, 0x1c, 0x02, 0x02, 0x00, 0x1d, 0x02, 0x02, 0x04, 0x1d, 0x02, 0x02, + 0x08, 0x1d, 0x02, 0x02, 0xb0, 0x3b, 0x03, 0x03, 0xb8, 0x3b, 0x03, 0x03, 0xc0, 0x3b, 0x03, 0x03, 0x30, 0x12, 0x04, 0x03, 0x38, 0x12, 0x04, 0x03, 0x60, 0x2d, 0x05, 0x04, 0xa0, 0x08, 0x06, 0x04, + 0xe0, 0x20, 0x07, 0x05, 0x00, 0x00, 0x0d, 0x08, 0xf0, 0x15, 0x00, 0x02, 0xf4, 0x15, 0x00, 0x02, 0xf8, 0x15, 0x00, 0x02, 0xfc, 0x15, 0x00, 0x02, 0xfe, 0x05, 0x01, 0x01, 0x00, 0x06, 0x01, 0x01, + 0x02, 0x06, 0x01, 0x01, 0x04, 0x06, 0x01, 0x01, 0x06, 0x06, 0x01, 0x01, 0x08, 0x06, 0x01, 0x01, 0x0c, 0x1d, 0x02, 0x02, 0x10, 0x1d, 0x02, 0x02, 0x14, 0x1d, 0x02, 0x02, 0x18, 0x1d, 0x02, 0x02, + 0x1c, 0x1d, 0x02, 0x02, 0xc8, 0x3b, 0x03, 0x03, 0xd0, 0x3b, 0x03, 0x03, 0xd8, 0x3b, 0x03, 0x03, 0x40, 0x12, 0x04, 0x03, 0x48, 0x12, 0x04, 0x03, 0x70, 0x2d, 0x05, 0x04, 0xb0, 0x08, 0x06, 0x04, + 0x20, 0x00, 0x08, 0x05, 0x00, 0x01, 0x0d, 0x08, 0x00, 0x16, 0x00, 0x02, 0x04, 0x16, 0x00, 0x02, 0x08, 0x16, 0x00, 0x02, 0x0c, 0x16, 0x00, 0x02, 0x0a, 0x06, 0x01, 0x01, 0x0c, 0x06, 0x01, 0x01, + 0x0e, 0x06, 0x01, 0x01, 0x10, 0x06, 0x01, 0x01, 0x12, 0x06, 0x01, 0x01, 0x14, 0x06, 0x01, 0x01, 0x20, 0x1d, 0x02, 0x02, 0x24, 0x1d, 0x02, 0x02, 0x28, 0x1d, 0x02, 0x02, 0x2c, 0x1d, 0x02, 0x02, + 0x30, 0x1d, 0x02, 0x02, 0xe0, 0x3b, 0x03, 0x03, 0xe8, 0x3b, 0x03, 0x03, 0xf0, 0x3b, 0x03, 0x03, 0x50, 0x12, 0x04, 0x03, 0x58, 0x12, 0x04, 0x03, 0x80, 0x2d, 0x05, 0x04, 0xc0, 0x08, 0x06, 0x04, + 0x40, 0x00, 0x08, 0x05, 0x00, 0x02, 0x0d, 0x08, 0x10, 0x16, 0x00, 0x02, 0x14, 0x16, 0x00, 0x02, 0x18, 0x16, 0x00, 0x02, 0x1c, 0x16, 0x00, 0x02, 0x16, 0x06, 0x01, 0x01, 0x18, 0x06, 0x01, 0x01, + 0x1a, 0x06, 0x01, 0x01, 0x1c, 0x06, 0x01, 0x01, 0x1e, 0x06, 0x01, 0x01, 0x20, 0x06, 0x01, 0x01, 0x34, 0x1d, 0x02, 0x02, 0x38, 0x1d, 0x02, 0x02, 0x3c, 0x1d, 0x02, 0x02, 0x40, 0x1d, 0x02, 0x02, + 0x44, 0x1d, 0x02, 0x02, 0xf8, 0x3b, 0x03, 0x03, 0x00, 0x3c, 0x03, 0x03, 0x08, 0x3c, 0x03, 0x03, 0x60, 0x12, 0x04, 0x03, 0x68, 0x12, 0x04, 0x03, 0x90, 0x2d, 0x05, 0x04, 0xd0, 0x08, 0x06, 0x04, + 0x60, 0x00, 0x08, 0x05, 0x00, 0x03, 0x0d, 0x08, 0x20, 0x16, 0x00, 0x02, 0x24, 0x16, 0x00, 0x02, 0x28, 0x16, 0x00, 0x02, 0x2c, 0x16, 0x00, 0x02, 0x22, 0x06, 0x01, 0x01, 0x00, 0x00, 0xfe, 0x0e, + 0x00, 0x00, 0xfd, 0x0e, 0x00, 0x00, 0xfc, 0x0e, 0x00, 0x00, 0xfb, 0x0e, 0x00, 0x00, 0xfa, 0x0e, 0x00, 0x00, 0xf9, 0x0e, 0x00, 0x00, 0xf8, 0x0e, 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0xf6, 0x0e, + 0x00, 0x00, 0xf5, 0x0e, 0x00, 0x00, 0xf4, 0x0e, 0x00, 0x00, 0xf3, 0x0e, 0x00, 0x00, 0xf2, 0x0e, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0xef, 0x0e, 0x00, 0x00, 0xee, 0x0e, + 0x00, 0x00, 0xed, 0x0e, 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xeb, 0x0e, 0x00, 0x00, 0xea, 0x0e, 0x00, 0x00, 0xe9, 0x0e, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x00, 0xe7, 0x0e, 0x00, 0x00, 0xe6, 0x0e, + 0x00, 0x00, 0xe5, 0x0e, 0x00, 0x00, 0xe4, 0x0e, 0x00, 0x00, 0xe3, 0x0e, 0x00, 0x00, 0xe2, 0x0e, 0x00, 0x00, 0xe1, 0x0e, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0xdf, 0x0e, 0x00, 0x00, 0xde, 0x0e, + 0x00, 0x00, 0xdd, 0x0e, 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0xdb, 0x0e, 0x00, 0x00, 0xda, 0x0e, 0x00, 0x00, 0xd9, 0x0e, 0x00, 0x00, 0xd8, 0x0e, 0x00, 0x00, 0xd7, 0x0e, 0x00, 0x00, 0xd6, 0x0e, + 0x00, 0x00, 0xd5, 0x0e, 0x00, 0x00, 0xd4, 0x0e, 0x00, 0x00, 0xd3, 0x0e, 0x00, 0x00, 0xd2, 0x0e, 0x00, 0x00, 0xd1, 0x0e, 0x00, 0x00, 0xd0, 0x0e, 0x00, 0x00, 0xcf, 0x0e, 0x00, 0x00, 0xce, 0x0e, + 0x00, 0x00, 0xcd, 0x0e, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x00, 0xcb, 0x0e, 0x00, 0x00, 0xca, 0x0e, 0x00, 0x00, 0xc9, 0x0e, 0x00, 0x00, 0xc8, 0x0e, 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0xc6, 0x0e, + 0x00, 0x00, 0xc5, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc3, 0x0e, 0x00, 0x00, 0xc2, 0x0e, 0x00, 0x00, 0xc1, 0x0e, 0x00, 0x00, 0xc0, 0x0e, 0x00, 0x00, 0xbf, 0x0e, 0x00, 0x00, 0xbe, 0x0e, + 0x00, 0x00, 0xbd, 0x0e, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x00, 0xbb, 0x0e, 0x00, 0x00, 0xba, 0x0e, 0x00, 0x00, 0xb9, 0x0e, 0x00, 0x00, 0xb8, 0x0e, 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x00, 0xb6, 0x0e, + 0x00, 0x00, 0xb5, 0x0e, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x00, 0xb3, 0x0e, 0x00, 0x00, 0xb2, 0x0e, 0x00, 0x00, 0xb1, 0x0e, 0x00, 0x00, 0xb0, 0x0e, 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0xae, 0x0e, + 0x00, 0x00, 0xad, 0x0e, 0x00, 0x00, 0xac, 0x0e, 0x00, 0x00, 0xab, 0x0e, 0x00, 0x00, 0xaa, 0x0e, 0x00, 0x00, 0xa9, 0x0e, 0x00, 0x00, 0xa8, 0x0e, 0x00, 0x00, 0xa7, 0x0e, 0x00, 0x00, 0xa6, 0x0e, + 0x00, 0x00, 0xa5, 0x0e, 0x00, 0x00, 0xa4, 0x0e, 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0xa2, 0x0e, 0x00, 0x00, 0xa1, 0x0e, 0x00, 0x00, 0xa0, 0x0e, 0x00, 0x00, 0x9f, 0x0e, 0x00, 0x00, 0x9e, 0x0e, + 0x00, 0x00, 0x9d, 0x0e, 0x00, 0x00, 0x9c, 0x0e, 0x00, 0x00, 0x9b, 0x0e, 0x00, 0x00, 0x9a, 0x0e, 0x00, 0x00, 0x99, 0x0e, 0x00, 0x00, 0x98, 0x0e, 0x00, 0x00, 0x97, 0x0e, 0x00, 0x00, 0x96, 0x0e, + 0x00, 0x00, 0x95, 0x0e, 0x00, 0x00, 0x94, 0x0e, 0x00, 0x00, 0x93, 0x0e, 0x00, 0x00, 0x92, 0x0e, 0x00, 0x00, 0x91, 0x0e, 0x00, 0x00, 0x90, 0x0e, 0x00, 0x00, 0x8f, 0x0e, 0x00, 0x00, 0x8e, 0x0e, + 0x00, 0x00, 0x8d, 0x0e, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x00, 0x8b, 0x0e, 0x00, 0x00, 0x8a, 0x0e, 0x00, 0x00, 0x89, 0x0e, 0x00, 0x00, 0x88, 0x0e, 0x00, 0x00, 0x87, 0x0e, 0x00, 0x00, 0x86, 0x0e, + 0x00, 0x00, 0x85, 0x0e, 0x00, 0x00, 0x84, 0x0e, 0x00, 0x00, 0x83, 0x0e, 0x00, 0x00, 0x82, 0x0e, 0x00, 0x00, 0x81, 0x0e, 0x00, 0x00, 0x80, 0x0e, 0x00, 0x00, 0x7f, 0x0e, 0x00, 0x00, 0x7e, 0x0e, + 0x00, 0x00, 0x7d, 0x0e, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x00, 0x7b, 0x0e, 0x00, 0x00, 0x7a, 0x0e, 0x00, 0x00, 0x79, 0x0e, 0x00, 0x00, 0x78, 0x0e, 0x00, 0x00, 0x77, 0x0e, 0x00, 0x00, 0x76, 0x0e, + 0x00, 0x00, 0x75, 0x0e, 0x00, 0x00, 0x74, 0x0e, 0x00, 0x00, 0x73, 0x0e, 0x00, 0x00, 0x72, 0x0e, 0x00, 0x00, 0x71, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x6f, 0x0e, 0x00, 0x00, 0x6e, 0x0e, + 0x00, 0x00, 0x6d, 0x0e, 0x00, 0x00, 0x6c, 0x0e, 0x00, 0x00, 0x6b, 0x0e, 0x00, 0x00, 0x6a, 0x0e, 0x00, 0x00, 0x69, 0x0e, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x00, 0x67, 0x0e, 0x00, 0x00, 0x66, 0x0e, + 0x00, 0x00, 0x65, 0x0e, 0x00, 0x00, 0x64, 0x0e, 0x00, 0x00, 0x63, 0x0e, 0x00, 0x00, 0x62, 0x0e, 0x00, 0x00, 0x61, 0x0e, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x00, 0x5f, 0x0e, 0x00, 0x00, 0x5e, 0x0e, + 0x00, 0x00, 0x5d, 0x0e, 0x00, 0x00, 0x5c, 0x0e, 0x00, 0x00, 0x5b, 0x0e, 0x00, 0x00, 0x5a, 0x0e, 0x00, 0x00, 0x59, 0x0e, 0x00, 0x00, 0x58, 0x0e, 0x00, 0x00, 0x57, 0x0e, 0x00, 0x00, 0x56, 0x0e, + 0x00, 0x00, 0x55, 0x0e, 0x00, 0x00, 0x54, 0x0e, 0x00, 0x00, 0x53, 0x0e, 0x00, 0x00, 0x52, 0x0e, 0x00, 0x00, 0x51, 0x0e, 0x00, 0x00, 0x50, 0x0e, 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x4e, 0x0e, + 0x00, 0x00, 0x4d, 0x0e, 0x00, 0x00, 0x4c, 0x0e, 0x00, 0x00, 0x4b, 0x0e, 0x00, 0x00, 0x4a, 0x0e, 0x00, 0x00, 0x49, 0x0e, 0x00, 0x00, 0x48, 0x0e, 0x00, 0x00, 0x47, 0x0e, 0x00, 0x00, 0x46, 0x0e, + 0x00, 0x00, 0x45, 0x0e, 0x00, 0x00, 0x44, 0x0e, 0x00, 0x00, 0x43, 0x0e, 0x00, 0x00, 0x42, 0x0e, 0x00, 0x00, 0x41, 0x0e, 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x3f, 0x0e, 0x00, 0x00, 0x3e, 0x0e, + 0x00, 0x00, 0x3d, 0x0e, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x3a, 0x0e, 0x00, 0x00, 0x39, 0x0e, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 0x37, 0x0e, 0x00, 0x00, 0x36, 0x0e, + 0x00, 0x00, 0x35, 0x0e, 0x00, 0x00, 0x34, 0x0e, 0x00, 0x00, 0x33, 0x0e, 0x00, 0x00, 0x32, 0x0e, 0x00, 0x00, 0x31, 0x0e, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x2e, 0x0e, + 0x00, 0x00, 0x2d, 0x0e, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00, 0x2b, 0x0e, 0x00, 0x00, 0x2a, 0x0e, 0x00, 0x00, 0x29, 0x0e, 0x00, 0x00, 0x28, 0x0e, 0x00, 0x00, 0x27, 0x0e, 0x00, 0x00, 0x26, 0x0e, + 0x00, 0x00, 0x25, 0x0e, 0x00, 0x00, 0x24, 0x0e, 0x00, 0x00, 0x23, 0x0e, 0x00, 0x00, 0x22, 0x0e, 0x00, 0x00, 0x21, 0x0e, 0x00, 0x00, 0x20, 0x0e, 0x00, 0x00, 0x1f, 0x0e, 0x00, 0x00, 0x1e, 0x0e, + 0x00, 0x00, 0x1d, 0x0e, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0x1b, 0x0e, 0x00, 0x00, 0x1a, 0x0e, 0x00, 0x00, 0x19, 0x0e, 0x00, 0x00, 0x18, 0x0e, 0x00, 0x00, 0x17, 0x0e, 0x00, 0x00, 0x16, 0x0e, + 0x00, 0x00, 0x15, 0x0e +}; + +const byte DTable_C3[65540] = { + 0x0e, 0x00, 0x01, 0x00, 0x94, 0x1d, 0x00, 0x02, 0x98, 0x1d, 0x00, 0x02, 0x9c, 0x1d, 0x00, 0x02, 0xa0, 0x1d, 0x00, 0x02, 0xa4, 0x1d, 0x00, 0x02, 0xa8, 0x1d, 0x00, 0x02, 0xac, 0x1d, 0x00, 0x02, + 0xb0, 0x1d, 0x00, 0x02, 0xb4, 0x1d, 0x00, 0x02, 0xa4, 0x25, 0x01, 0x02, 0xa8, 0x25, 0x01, 0x02, 0xac, 0x25, 0x01, 0x02, 0xb0, 0x25, 0x01, 0x02, 0xb4, 0x25, 0x01, 0x02, 0xb8, 0x25, 0x01, 0x02, + 0xbc, 0x25, 0x01, 0x02, 0xc0, 0x25, 0x01, 0x02, 0xc4, 0x25, 0x01, 0x02, 0xc8, 0x25, 0x01, 0x02, 0xc8, 0x0a, 0x02, 0x03, 0xd0, 0x0a, 0x02, 0x03, 0xd8, 0x0a, 0x02, 0x03, 0x00, 0x2e, 0x03, 0x05, + 0x20, 0x2e, 0x03, 0x05, 0xb8, 0x1d, 0x00, 0x02, 0xbc, 0x1d, 0x00, 0x02, 0xc0, 0x1d, 0x00, 0x02, 0xc4, 0x1d, 0x00, 0x02, 0xc8, 0x1d, 0x00, 0x02, 0xcc, 0x1d, 0x00, 0x02, 0xd0, 0x1d, 0x00, 0x02, + 0xd4, 0x1d, 0x00, 0x02, 0xd8, 0x1d, 0x00, 0x02, 0xcc, 0x25, 0x01, 0x02, 0xd0, 0x25, 0x01, 0x02, 0xd4, 0x25, 0x01, 0x02, 0xd8, 0x25, 0x01, 0x02, 0xdc, 0x25, 0x01, 0x02, 0xe0, 0x25, 0x01, 0x02, + 0xe4, 0x25, 0x01, 0x02, 0xe8, 0x25, 0x01, 0x02, 0xec, 0x25, 0x01, 0x02, 0xf0, 0x25, 0x01, 0x02, 0xe0, 0x0a, 0x02, 0x03, 0xe8, 0x0a, 0x02, 0x03, 0xf0, 0x0a, 0x02, 0x03, 0x40, 0x2e, 0x03, 0x05, + 0x60, 0x2e, 0x03, 0x05, 0xdc, 0x1d, 0x00, 0x02, 0xe0, 0x1d, 0x00, 0x02, 0xe4, 0x1d, 0x00, 0x02, 0xe8, 0x1d, 0x00, 0x02, 0xec, 0x1d, 0x00, 0x02, 0xf0, 0x1d, 0x00, 0x02, 0xf4, 0x1d, 0x00, 0x02, + 0xf8, 0x1d, 0x00, 0x02, 0xfc, 0x1d, 0x00, 0x02, 0xf4, 0x25, 0x01, 0x02, 0xf8, 0x25, 0x01, 0x02, 0xfc, 0x25, 0x01, 0x02, 0x00, 0x26, 0x01, 0x02, 0x04, 0x26, 0x01, 0x02, 0x08, 0x26, 0x01, 0x02, + 0x0c, 0x26, 0x01, 0x02, 0x10, 0x26, 0x01, 0x02, 0x14, 0x26, 0x01, 0x02, 0x18, 0x26, 0x01, 0x02, 0xf8, 0x0a, 0x02, 0x03, 0x00, 0x0b, 0x02, 0x03, 0x08, 0x0b, 0x02, 0x03, 0x80, 0x2e, 0x03, 0x05, + 0xa0, 0x2e, 0x03, 0x05, 0x00, 0x1e, 0x00, 0x02, 0x04, 0x1e, 0x00, 0x02, 0x08, 0x1e, 0x00, 0x02, 0x0c, 0x1e, 0x00, 0x02, 0x10, 0x1e, 0x00, 0x02, 0x14, 0x1e, 0x00, 0x02, 0x18, 0x1e, 0x00, 0x02, + 0x1c, 0x1e, 0x00, 0x02, 0x20, 0x1e, 0x00, 0x02, 0x1c, 0x26, 0x01, 0x02, 0x20, 0x26, 0x01, 0x02, 0x24, 0x26, 0x01, 0x02, 0x28, 0x26, 0x01, 0x02, 0x2c, 0x26, 0x01, 0x02, 0x30, 0x26, 0x01, 0x02, + 0x34, 0x26, 0x01, 0x02, 0x38, 0x26, 0x01, 0x02, 0x3c, 0x26, 0x01, 0x02, 0x40, 0x26, 0x01, 0x02, 0x10, 0x0b, 0x02, 0x03, 0x18, 0x0b, 0x02, 0x03, 0x20, 0x0b, 0x02, 0x03, 0xc0, 0x2e, 0x03, 0x05, + 0xe0, 0x2e, 0x03, 0x05, 0x24, 0x1e, 0x00, 0x02, 0x28, 0x1e, 0x00, 0x02, 0x2c, 0x1e, 0x00, 0x02, 0x30, 0x1e, 0x00, 0x02, 0x34, 0x1e, 0x00, 0x02, 0x38, 0x1e, 0x00, 0x02, 0x3c, 0x1e, 0x00, 0x02, + 0x40, 0x1e, 0x00, 0x02, 0x44, 0x1e, 0x00, 0x02, 0x44, 0x26, 0x01, 0x02, 0x48, 0x26, 0x01, 0x02, 0x4c, 0x26, 0x01, 0x02, 0x50, 0x26, 0x01, 0x02, 0x54, 0x26, 0x01, 0x02, 0x58, 0x26, 0x01, 0x02, + 0x5c, 0x26, 0x01, 0x02, 0x60, 0x26, 0x01, 0x02, 0x64, 0x26, 0x01, 0x02, 0x68, 0x26, 0x01, 0x02, 0x28, 0x0b, 0x02, 0x03, 0x30, 0x0b, 0x02, 0x03, 0x38, 0x0b, 0x02, 0x03, 0x00, 0x2f, 0x03, 0x05, + 0x20, 0x2f, 0x03, 0x05, 0x48, 0x1e, 0x00, 0x02, 0x4c, 0x1e, 0x00, 0x02, 0x50, 0x1e, 0x00, 0x02, 0x54, 0x1e, 0x00, 0x02, 0x58, 0x1e, 0x00, 0x02, 0x5c, 0x1e, 0x00, 0x02, 0x60, 0x1e, 0x00, 0x02, + 0x64, 0x1e, 0x00, 0x02, 0x68, 0x1e, 0x00, 0x02, 0x6c, 0x26, 0x01, 0x02, 0x70, 0x26, 0x01, 0x02, 0x74, 0x26, 0x01, 0x02, 0x78, 0x26, 0x01, 0x02, 0x7c, 0x26, 0x01, 0x02, 0x80, 0x26, 0x01, 0x02, + 0x84, 0x26, 0x01, 0x02, 0x88, 0x26, 0x01, 0x02, 0x8c, 0x26, 0x01, 0x02, 0x90, 0x26, 0x01, 0x02, 0x40, 0x0b, 0x02, 0x03, 0x48, 0x0b, 0x02, 0x03, 0x50, 0x0b, 0x02, 0x03, 0x40, 0x2f, 0x03, 0x05, + 0x60, 0x2f, 0x03, 0x05, 0x6c, 0x1e, 0x00, 0x02, 0x70, 0x1e, 0x00, 0x02, 0x74, 0x1e, 0x00, 0x02, 0x78, 0x1e, 0x00, 0x02, 0x7c, 0x1e, 0x00, 0x02, 0x80, 0x1e, 0x00, 0x02, 0x84, 0x1e, 0x00, 0x02, + 0x88, 0x1e, 0x00, 0x02, 0x8c, 0x1e, 0x00, 0x02, 0x94, 0x26, 0x01, 0x02, 0x98, 0x26, 0x01, 0x02, 0x9c, 0x26, 0x01, 0x02, 0xa0, 0x26, 0x01, 0x02, 0xa4, 0x26, 0x01, 0x02, 0xa8, 0x26, 0x01, 0x02, + 0xac, 0x26, 0x01, 0x02, 0xb0, 0x26, 0x01, 0x02, 0xb4, 0x26, 0x01, 0x02, 0xb8, 0x26, 0x01, 0x02, 0x58, 0x0b, 0x02, 0x03, 0x60, 0x0b, 0x02, 0x03, 0x68, 0x0b, 0x02, 0x03, 0x80, 0x2f, 0x03, 0x05, + 0xa0, 0x2f, 0x03, 0x05, 0x90, 0x1e, 0x00, 0x02, 0x94, 0x1e, 0x00, 0x02, 0x98, 0x1e, 0x00, 0x02, 0x9c, 0x1e, 0x00, 0x02, 0xa0, 0x1e, 0x00, 0x02, 0xa4, 0x1e, 0x00, 0x02, 0xa8, 0x1e, 0x00, 0x02, + 0xac, 0x1e, 0x00, 0x02, 0xb0, 0x1e, 0x00, 0x02, 0xbc, 0x26, 0x01, 0x02, 0xc0, 0x26, 0x01, 0x02, 0xc4, 0x26, 0x01, 0x02, 0xc8, 0x26, 0x01, 0x02, 0xcc, 0x26, 0x01, 0x02, 0xd0, 0x26, 0x01, 0x02, + 0xd4, 0x26, 0x01, 0x02, 0xd8, 0x26, 0x01, 0x02, 0xdc, 0x26, 0x01, 0x02, 0xe0, 0x26, 0x01, 0x02, 0x70, 0x0b, 0x02, 0x03, 0x78, 0x0b, 0x02, 0x03, 0x80, 0x0b, 0x02, 0x03, 0xc0, 0x2f, 0x03, 0x05, + 0xe0, 0x2f, 0x03, 0x05, 0xb4, 0x1e, 0x00, 0x02, 0xb8, 0x1e, 0x00, 0x02, 0xbc, 0x1e, 0x00, 0x02, 0xc0, 0x1e, 0x00, 0x02, 0xc4, 0x1e, 0x00, 0x02, 0xc8, 0x1e, 0x00, 0x02, 0xcc, 0x1e, 0x00, 0x02, + 0xd0, 0x1e, 0x00, 0x02, 0xd4, 0x1e, 0x00, 0x02, 0xe4, 0x26, 0x01, 0x02, 0xe8, 0x26, 0x01, 0x02, 0xec, 0x26, 0x01, 0x02, 0xf0, 0x26, 0x01, 0x02, 0xf4, 0x26, 0x01, 0x02, 0xf8, 0x26, 0x01, 0x02, + 0xfc, 0x26, 0x01, 0x02, 0x00, 0x27, 0x01, 0x02, 0x04, 0x27, 0x01, 0x02, 0x08, 0x27, 0x01, 0x02, 0x88, 0x0b, 0x02, 0x03, 0x90, 0x0b, 0x02, 0x03, 0x98, 0x0b, 0x02, 0x03, 0x00, 0x30, 0x03, 0x05, + 0x20, 0x30, 0x03, 0x05, 0xd8, 0x1e, 0x00, 0x02, 0xdc, 0x1e, 0x00, 0x02, 0xe0, 0x1e, 0x00, 0x02, 0xe4, 0x1e, 0x00, 0x02, 0xe8, 0x1e, 0x00, 0x02, 0xec, 0x1e, 0x00, 0x02, 0xf0, 0x1e, 0x00, 0x02, + 0xf4, 0x1e, 0x00, 0x02, 0xf8, 0x1e, 0x00, 0x02, 0x0c, 0x27, 0x01, 0x02, 0x10, 0x27, 0x01, 0x02, 0x14, 0x27, 0x01, 0x02, 0x18, 0x27, 0x01, 0x02, 0x1c, 0x27, 0x01, 0x02, 0x20, 0x27, 0x01, 0x02, + 0x24, 0x27, 0x01, 0x02, 0x28, 0x27, 0x01, 0x02, 0x2c, 0x27, 0x01, 0x02, 0x30, 0x27, 0x01, 0x02, 0xa0, 0x0b, 0x02, 0x03, 0xa8, 0x0b, 0x02, 0x03, 0xb0, 0x0b, 0x02, 0x03, 0x40, 0x30, 0x03, 0x05, + 0x60, 0x30, 0x03, 0x05, 0xfc, 0x1e, 0x00, 0x02, 0x00, 0x1f, 0x00, 0x02, 0x04, 0x1f, 0x00, 0x02, 0x08, 0x1f, 0x00, 0x02, 0x0c, 0x1f, 0x00, 0x02, 0x10, 0x1f, 0x00, 0x02, 0x14, 0x1f, 0x00, 0x02, + 0x18, 0x1f, 0x00, 0x02, 0x1c, 0x1f, 0x00, 0x02, 0x34, 0x27, 0x01, 0x02, 0x38, 0x27, 0x01, 0x02, 0x3c, 0x27, 0x01, 0x02, 0x40, 0x27, 0x01, 0x02, 0x44, 0x27, 0x01, 0x02, 0x48, 0x27, 0x01, 0x02, + 0x4c, 0x27, 0x01, 0x02, 0x50, 0x27, 0x01, 0x02, 0x54, 0x27, 0x01, 0x02, 0x58, 0x27, 0x01, 0x02, 0xb8, 0x0b, 0x02, 0x03, 0xc0, 0x0b, 0x02, 0x03, 0xc8, 0x0b, 0x02, 0x03, 0x80, 0x30, 0x03, 0x05, + 0xa0, 0x30, 0x03, 0x05, 0x20, 0x1f, 0x00, 0x02, 0x24, 0x1f, 0x00, 0x02, 0x28, 0x1f, 0x00, 0x02, 0x2c, 0x1f, 0x00, 0x02, 0x30, 0x1f, 0x00, 0x02, 0x34, 0x1f, 0x00, 0x02, 0x38, 0x1f, 0x00, 0x02, + 0x3c, 0x1f, 0x00, 0x02, 0x40, 0x1f, 0x00, 0x02, 0x5c, 0x27, 0x01, 0x02, 0x60, 0x27, 0x01, 0x02, 0x64, 0x27, 0x01, 0x02, 0x68, 0x27, 0x01, 0x02, 0x6c, 0x27, 0x01, 0x02, 0x70, 0x27, 0x01, 0x02, + 0x74, 0x27, 0x01, 0x02, 0x78, 0x27, 0x01, 0x02, 0x7c, 0x27, 0x01, 0x02, 0x80, 0x27, 0x01, 0x02, 0xd0, 0x0b, 0x02, 0x03, 0xd8, 0x0b, 0x02, 0x03, 0xe0, 0x0b, 0x02, 0x03, 0xc0, 0x30, 0x03, 0x05, + 0xe0, 0x30, 0x03, 0x05, 0x44, 0x1f, 0x00, 0x02, 0x48, 0x1f, 0x00, 0x02, 0x4c, 0x1f, 0x00, 0x02, 0x50, 0x1f, 0x00, 0x02, 0x54, 0x1f, 0x00, 0x02, 0x58, 0x1f, 0x00, 0x02, 0x5c, 0x1f, 0x00, 0x02, + 0x60, 0x1f, 0x00, 0x02, 0x64, 0x1f, 0x00, 0x02, 0x84, 0x27, 0x01, 0x02, 0x88, 0x27, 0x01, 0x02, 0x8c, 0x27, 0x01, 0x02, 0x90, 0x27, 0x01, 0x02, 0x94, 0x27, 0x01, 0x02, 0x98, 0x27, 0x01, 0x02, + 0x9c, 0x27, 0x01, 0x02, 0xa0, 0x27, 0x01, 0x02, 0xa4, 0x27, 0x01, 0x02, 0xa8, 0x27, 0x01, 0x02, 0xe8, 0x0b, 0x02, 0x03, 0xf0, 0x0b, 0x02, 0x03, 0xf8, 0x0b, 0x02, 0x03, 0x00, 0x31, 0x03, 0x05, + 0x20, 0x31, 0x03, 0x05, 0x68, 0x1f, 0x00, 0x02, 0x6c, 0x1f, 0x00, 0x02, 0x70, 0x1f, 0x00, 0x02, 0x74, 0x1f, 0x00, 0x02, 0x78, 0x1f, 0x00, 0x02, 0x7c, 0x1f, 0x00, 0x02, 0x80, 0x1f, 0x00, 0x02, + 0x84, 0x1f, 0x00, 0x02, 0x88, 0x1f, 0x00, 0x02, 0xac, 0x27, 0x01, 0x02, 0xb0, 0x27, 0x01, 0x02, 0xb4, 0x27, 0x01, 0x02, 0xb8, 0x27, 0x01, 0x02, 0xbc, 0x27, 0x01, 0x02, 0xc0, 0x27, 0x01, 0x02, + 0xc4, 0x27, 0x01, 0x02, 0xc8, 0x27, 0x01, 0x02, 0xcc, 0x27, 0x01, 0x02, 0xd0, 0x27, 0x01, 0x02, 0x00, 0x0c, 0x02, 0x03, 0x08, 0x0c, 0x02, 0x03, 0x10, 0x0c, 0x02, 0x03, 0x40, 0x31, 0x03, 0x05, + 0x60, 0x31, 0x03, 0x05, 0x8c, 0x1f, 0x00, 0x02, 0x90, 0x1f, 0x00, 0x02, 0x94, 0x1f, 0x00, 0x02, 0x98, 0x1f, 0x00, 0x02, 0x9c, 0x1f, 0x00, 0x02, 0xa0, 0x1f, 0x00, 0x02, 0xa4, 0x1f, 0x00, 0x02, + 0xa8, 0x1f, 0x00, 0x02, 0xac, 0x1f, 0x00, 0x02, 0xd4, 0x27, 0x01, 0x02, 0xd8, 0x27, 0x01, 0x02, 0xdc, 0x27, 0x01, 0x02, 0xe0, 0x27, 0x01, 0x02, 0xe4, 0x27, 0x01, 0x02, 0xe8, 0x27, 0x01, 0x02, + 0xec, 0x27, 0x01, 0x02, 0xf0, 0x27, 0x01, 0x02, 0xf4, 0x27, 0x01, 0x02, 0xf8, 0x27, 0x01, 0x02, 0x18, 0x0c, 0x02, 0x03, 0x20, 0x0c, 0x02, 0x03, 0x28, 0x0c, 0x02, 0x03, 0x80, 0x31, 0x03, 0x05, + 0xa0, 0x31, 0x03, 0x05, 0xb0, 0x1f, 0x00, 0x02, 0xb4, 0x1f, 0x00, 0x02, 0xb8, 0x1f, 0x00, 0x02, 0xbc, 0x1f, 0x00, 0x02, 0xc0, 0x1f, 0x00, 0x02, 0xc4, 0x1f, 0x00, 0x02, 0xc8, 0x1f, 0x00, 0x02, + 0xcc, 0x1f, 0x00, 0x02, 0xd0, 0x1f, 0x00, 0x02, 0xfc, 0x27, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x04, 0x28, 0x01, 0x02, 0x08, 0x28, 0x01, 0x02, 0x0c, 0x28, 0x01, 0x02, 0x10, 0x28, 0x01, 0x02, + 0x14, 0x28, 0x01, 0x02, 0x18, 0x28, 0x01, 0x02, 0x1c, 0x28, 0x01, 0x02, 0x20, 0x28, 0x01, 0x02, 0x30, 0x0c, 0x02, 0x03, 0x38, 0x0c, 0x02, 0x03, 0x40, 0x0c, 0x02, 0x03, 0xc0, 0x31, 0x03, 0x05, + 0xe0, 0x31, 0x03, 0x05, 0xd4, 0x1f, 0x00, 0x02, 0xd8, 0x1f, 0x00, 0x02, 0xdc, 0x1f, 0x00, 0x02, 0xe0, 0x1f, 0x00, 0x02, 0xe4, 0x1f, 0x00, 0x02, 0xe8, 0x1f, 0x00, 0x02, 0xec, 0x1f, 0x00, 0x02, + 0xf0, 0x1f, 0x00, 0x02, 0xf4, 0x1f, 0x00, 0x02, 0x24, 0x28, 0x01, 0x02, 0x28, 0x28, 0x01, 0x02, 0x2c, 0x28, 0x01, 0x02, 0x30, 0x28, 0x01, 0x02, 0x34, 0x28, 0x01, 0x02, 0x38, 0x28, 0x01, 0x02, + 0x3c, 0x28, 0x01, 0x02, 0x40, 0x28, 0x01, 0x02, 0x44, 0x28, 0x01, 0x02, 0x48, 0x28, 0x01, 0x02, 0x48, 0x0c, 0x02, 0x03, 0x50, 0x0c, 0x02, 0x03, 0x58, 0x0c, 0x02, 0x03, 0x00, 0x32, 0x03, 0x05, + 0x20, 0x32, 0x03, 0x05, 0xf8, 0x1f, 0x00, 0x02, 0xfc, 0x1f, 0x00, 0x02, 0x00, 0x20, 0x00, 0x02, 0x04, 0x20, 0x00, 0x02, 0x08, 0x20, 0x00, 0x02, 0x0c, 0x20, 0x00, 0x02, 0x10, 0x20, 0x00, 0x02, + 0x14, 0x20, 0x00, 0x02, 0x18, 0x20, 0x00, 0x02, 0x4c, 0x28, 0x01, 0x02, 0x50, 0x28, 0x01, 0x02, 0x54, 0x28, 0x01, 0x02, 0x58, 0x28, 0x01, 0x02, 0x5c, 0x28, 0x01, 0x02, 0x60, 0x28, 0x01, 0x02, + 0x64, 0x28, 0x01, 0x02, 0x68, 0x28, 0x01, 0x02, 0x6c, 0x28, 0x01, 0x02, 0x70, 0x28, 0x01, 0x02, 0x60, 0x0c, 0x02, 0x03, 0x68, 0x0c, 0x02, 0x03, 0x70, 0x0c, 0x02, 0x03, 0x40, 0x32, 0x03, 0x05, + 0x60, 0x32, 0x03, 0x05, 0x1c, 0x20, 0x00, 0x02, 0x20, 0x20, 0x00, 0x02, 0x24, 0x20, 0x00, 0x02, 0x28, 0x20, 0x00, 0x02, 0x2c, 0x20, 0x00, 0x02, 0x30, 0x20, 0x00, 0x02, 0x34, 0x20, 0x00, 0x02, + 0x38, 0x20, 0x00, 0x02, 0x3c, 0x20, 0x00, 0x02, 0x74, 0x28, 0x01, 0x02, 0x78, 0x28, 0x01, 0x02, 0x7c, 0x28, 0x01, 0x02, 0x80, 0x28, 0x01, 0x02, 0x84, 0x28, 0x01, 0x02, 0x88, 0x28, 0x01, 0x02, + 0x8c, 0x28, 0x01, 0x02, 0x90, 0x28, 0x01, 0x02, 0x94, 0x28, 0x01, 0x02, 0x98, 0x28, 0x01, 0x02, 0x78, 0x0c, 0x02, 0x03, 0x80, 0x0c, 0x02, 0x03, 0x88, 0x0c, 0x02, 0x03, 0x80, 0x32, 0x03, 0x05, + 0xa0, 0x32, 0x03, 0x05, 0x40, 0x20, 0x00, 0x02, 0x44, 0x20, 0x00, 0x02, 0x48, 0x20, 0x00, 0x02, 0x4c, 0x20, 0x00, 0x02, 0x50, 0x20, 0x00, 0x02, 0x54, 0x20, 0x00, 0x02, 0x58, 0x20, 0x00, 0x02, + 0x5c, 0x20, 0x00, 0x02, 0x60, 0x20, 0x00, 0x02, 0x9c, 0x28, 0x01, 0x02, 0xa0, 0x28, 0x01, 0x02, 0xa4, 0x28, 0x01, 0x02, 0xa8, 0x28, 0x01, 0x02, 0xac, 0x28, 0x01, 0x02, 0xb0, 0x28, 0x01, 0x02, + 0xb4, 0x28, 0x01, 0x02, 0xb8, 0x28, 0x01, 0x02, 0xbc, 0x28, 0x01, 0x02, 0xc0, 0x28, 0x01, 0x02, 0x90, 0x0c, 0x02, 0x03, 0x98, 0x0c, 0x02, 0x03, 0xa0, 0x0c, 0x02, 0x03, 0xc0, 0x32, 0x03, 0x05, + 0xe0, 0x32, 0x03, 0x05, 0x64, 0x20, 0x00, 0x02, 0x68, 0x20, 0x00, 0x02, 0x6c, 0x20, 0x00, 0x02, 0x70, 0x20, 0x00, 0x02, 0x74, 0x20, 0x00, 0x02, 0x78, 0x20, 0x00, 0x02, 0x7c, 0x20, 0x00, 0x02, + 0x80, 0x20, 0x00, 0x02, 0x84, 0x20, 0x00, 0x02, 0xc4, 0x28, 0x01, 0x02, 0xc8, 0x28, 0x01, 0x02, 0xcc, 0x28, 0x01, 0x02, 0xd0, 0x28, 0x01, 0x02, 0xd4, 0x28, 0x01, 0x02, 0xd8, 0x28, 0x01, 0x02, + 0xdc, 0x28, 0x01, 0x02, 0xe0, 0x28, 0x01, 0x02, 0xe4, 0x28, 0x01, 0x02, 0xe8, 0x28, 0x01, 0x02, 0xa8, 0x0c, 0x02, 0x03, 0xb0, 0x0c, 0x02, 0x03, 0xb8, 0x0c, 0x02, 0x03, 0x00, 0x33, 0x03, 0x05, + 0x00, 0x11, 0x04, 0x06, 0x88, 0x20, 0x00, 0x02, 0x8c, 0x20, 0x00, 0x02, 0x90, 0x20, 0x00, 0x02, 0x94, 0x20, 0x00, 0x02, 0x98, 0x20, 0x00, 0x02, 0x9c, 0x20, 0x00, 0x02, 0xa0, 0x20, 0x00, 0x02, + 0xa4, 0x20, 0x00, 0x02, 0xa8, 0x20, 0x00, 0x02, 0xec, 0x28, 0x01, 0x02, 0xf0, 0x28, 0x01, 0x02, 0xf4, 0x28, 0x01, 0x02, 0xf8, 0x28, 0x01, 0x02, 0xfc, 0x28, 0x01, 0x02, 0x00, 0x29, 0x01, 0x02, + 0x04, 0x29, 0x01, 0x02, 0x08, 0x29, 0x01, 0x02, 0x0c, 0x29, 0x01, 0x02, 0x10, 0x29, 0x01, 0x02, 0xc0, 0x0c, 0x02, 0x03, 0xc8, 0x0c, 0x02, 0x03, 0xd0, 0x0c, 0x02, 0x03, 0x20, 0x33, 0x03, 0x05, + 0x40, 0x11, 0x04, 0x06, 0xac, 0x20, 0x00, 0x02, 0xb0, 0x20, 0x00, 0x02, 0xb4, 0x20, 0x00, 0x02, 0xb8, 0x20, 0x00, 0x02, 0xbc, 0x20, 0x00, 0x02, 0xc0, 0x20, 0x00, 0x02, 0xc4, 0x20, 0x00, 0x02, + 0xc8, 0x20, 0x00, 0x02, 0xcc, 0x20, 0x00, 0x02, 0x14, 0x29, 0x01, 0x02, 0x18, 0x29, 0x01, 0x02, 0x1c, 0x29, 0x01, 0x02, 0x20, 0x29, 0x01, 0x02, 0x24, 0x29, 0x01, 0x02, 0x28, 0x29, 0x01, 0x02, + 0x2c, 0x29, 0x01, 0x02, 0x30, 0x29, 0x01, 0x02, 0x34, 0x29, 0x01, 0x02, 0x38, 0x29, 0x01, 0x02, 0xd8, 0x0c, 0x02, 0x03, 0xe0, 0x0c, 0x02, 0x03, 0xe8, 0x0c, 0x02, 0x03, 0x40, 0x33, 0x03, 0x05, + 0x80, 0x11, 0x04, 0x06, 0xd0, 0x20, 0x00, 0x02, 0xd4, 0x20, 0x00, 0x02, 0xd8, 0x20, 0x00, 0x02, 0xdc, 0x20, 0x00, 0x02, 0xe0, 0x20, 0x00, 0x02, 0xe4, 0x20, 0x00, 0x02, 0xe8, 0x20, 0x00, 0x02, + 0xec, 0x20, 0x00, 0x02, 0xf0, 0x20, 0x00, 0x02, 0x3c, 0x29, 0x01, 0x02, 0x40, 0x29, 0x01, 0x02, 0x44, 0x29, 0x01, 0x02, 0x48, 0x29, 0x01, 0x02, 0x4c, 0x29, 0x01, 0x02, 0x50, 0x29, 0x01, 0x02, + 0x54, 0x29, 0x01, 0x02, 0x58, 0x29, 0x01, 0x02, 0x5c, 0x29, 0x01, 0x02, 0x60, 0x29, 0x01, 0x02, 0xf0, 0x0c, 0x02, 0x03, 0xf8, 0x0c, 0x02, 0x03, 0x00, 0x0d, 0x02, 0x03, 0x60, 0x33, 0x03, 0x05, + 0xc0, 0x11, 0x04, 0x06, 0xf4, 0x20, 0x00, 0x02, 0xf8, 0x20, 0x00, 0x02, 0xfc, 0x20, 0x00, 0x02, 0x00, 0x21, 0x00, 0x02, 0x04, 0x21, 0x00, 0x02, 0x08, 0x21, 0x00, 0x02, 0x0c, 0x21, 0x00, 0x02, + 0x10, 0x21, 0x00, 0x02, 0x14, 0x21, 0x00, 0x02, 0x64, 0x29, 0x01, 0x02, 0x68, 0x29, 0x01, 0x02, 0x6c, 0x29, 0x01, 0x02, 0x70, 0x29, 0x01, 0x02, 0x74, 0x29, 0x01, 0x02, 0x78, 0x29, 0x01, 0x02, + 0x7c, 0x29, 0x01, 0x02, 0x80, 0x29, 0x01, 0x02, 0x84, 0x29, 0x01, 0x02, 0x88, 0x29, 0x01, 0x02, 0x08, 0x0d, 0x02, 0x03, 0x10, 0x0d, 0x02, 0x03, 0x18, 0x0d, 0x02, 0x03, 0x80, 0x33, 0x03, 0x05, + 0x00, 0x12, 0x04, 0x06, 0x18, 0x21, 0x00, 0x02, 0x1c, 0x21, 0x00, 0x02, 0x20, 0x21, 0x00, 0x02, 0x24, 0x21, 0x00, 0x02, 0x28, 0x21, 0x00, 0x02, 0x2c, 0x21, 0x00, 0x02, 0x30, 0x21, 0x00, 0x02, + 0x34, 0x21, 0x00, 0x02, 0x38, 0x21, 0x00, 0x02, 0x8c, 0x29, 0x01, 0x02, 0x90, 0x29, 0x01, 0x02, 0x94, 0x29, 0x01, 0x02, 0x98, 0x29, 0x01, 0x02, 0x9c, 0x29, 0x01, 0x02, 0xa0, 0x29, 0x01, 0x02, + 0xa4, 0x29, 0x01, 0x02, 0xa8, 0x29, 0x01, 0x02, 0xac, 0x29, 0x01, 0x02, 0xb0, 0x29, 0x01, 0x02, 0x20, 0x0d, 0x02, 0x03, 0x28, 0x0d, 0x02, 0x03, 0x30, 0x0d, 0x02, 0x03, 0xa0, 0x33, 0x03, 0x05, + 0x40, 0x12, 0x04, 0x06, 0x3c, 0x21, 0x00, 0x02, 0x40, 0x21, 0x00, 0x02, 0x44, 0x21, 0x00, 0x02, 0x48, 0x21, 0x00, 0x02, 0x4c, 0x21, 0x00, 0x02, 0x50, 0x21, 0x00, 0x02, 0x54, 0x21, 0x00, 0x02, + 0x58, 0x21, 0x00, 0x02, 0x5c, 0x21, 0x00, 0x02, 0xb4, 0x29, 0x01, 0x02, 0xb8, 0x29, 0x01, 0x02, 0xbc, 0x29, 0x01, 0x02, 0xc0, 0x29, 0x01, 0x02, 0xc4, 0x29, 0x01, 0x02, 0xc8, 0x29, 0x01, 0x02, + 0xcc, 0x29, 0x01, 0x02, 0xd0, 0x29, 0x01, 0x02, 0xd4, 0x29, 0x01, 0x02, 0xd8, 0x29, 0x01, 0x02, 0x38, 0x0d, 0x02, 0x03, 0x40, 0x0d, 0x02, 0x03, 0x48, 0x0d, 0x02, 0x03, 0xc0, 0x33, 0x03, 0x05, + 0x80, 0x12, 0x04, 0x06, 0x60, 0x21, 0x00, 0x02, 0x64, 0x21, 0x00, 0x02, 0x68, 0x21, 0x00, 0x02, 0x6c, 0x21, 0x00, 0x02, 0x70, 0x21, 0x00, 0x02, 0x74, 0x21, 0x00, 0x02, 0x78, 0x21, 0x00, 0x02, + 0x7c, 0x21, 0x00, 0x02, 0x80, 0x21, 0x00, 0x02, 0xdc, 0x29, 0x01, 0x02, 0xe0, 0x29, 0x01, 0x02, 0xe4, 0x29, 0x01, 0x02, 0xe8, 0x29, 0x01, 0x02, 0xec, 0x29, 0x01, 0x02, 0xf0, 0x29, 0x01, 0x02, + 0xf4, 0x29, 0x01, 0x02, 0xf8, 0x29, 0x01, 0x02, 0xfc, 0x29, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x50, 0x0d, 0x02, 0x03, 0x58, 0x0d, 0x02, 0x03, 0x60, 0x0d, 0x02, 0x03, 0xe0, 0x33, 0x03, 0x05, + 0xc0, 0x12, 0x04, 0x06, 0x84, 0x21, 0x00, 0x02, 0x88, 0x21, 0x00, 0x02, 0x8c, 0x21, 0x00, 0x02, 0x90, 0x21, 0x00, 0x02, 0x94, 0x21, 0x00, 0x02, 0x98, 0x21, 0x00, 0x02, 0x9c, 0x21, 0x00, 0x02, + 0xa0, 0x21, 0x00, 0x02, 0xa4, 0x21, 0x00, 0x02, 0x04, 0x2a, 0x01, 0x02, 0x08, 0x2a, 0x01, 0x02, 0x0c, 0x2a, 0x01, 0x02, 0x10, 0x2a, 0x01, 0x02, 0x14, 0x2a, 0x01, 0x02, 0x18, 0x2a, 0x01, 0x02, + 0x1c, 0x2a, 0x01, 0x02, 0x20, 0x2a, 0x01, 0x02, 0x24, 0x2a, 0x01, 0x02, 0x28, 0x2a, 0x01, 0x02, 0x68, 0x0d, 0x02, 0x03, 0x70, 0x0d, 0x02, 0x03, 0x78, 0x0d, 0x02, 0x03, 0x00, 0x34, 0x03, 0x05, + 0x00, 0x13, 0x04, 0x06, 0xa8, 0x21, 0x00, 0x02, 0xac, 0x21, 0x00, 0x02, 0xb0, 0x21, 0x00, 0x02, 0xb4, 0x21, 0x00, 0x02, 0xb8, 0x21, 0x00, 0x02, 0xbc, 0x21, 0x00, 0x02, 0xc0, 0x21, 0x00, 0x02, + 0xc4, 0x21, 0x00, 0x02, 0xc8, 0x21, 0x00, 0x02, 0x2c, 0x2a, 0x01, 0x02, 0x30, 0x2a, 0x01, 0x02, 0x34, 0x2a, 0x01, 0x02, 0x38, 0x2a, 0x01, 0x02, 0x3c, 0x2a, 0x01, 0x02, 0x40, 0x2a, 0x01, 0x02, + 0x44, 0x2a, 0x01, 0x02, 0x48, 0x2a, 0x01, 0x02, 0x4c, 0x2a, 0x01, 0x02, 0x50, 0x2a, 0x01, 0x02, 0x80, 0x0d, 0x02, 0x03, 0x88, 0x0d, 0x02, 0x03, 0x90, 0x0d, 0x02, 0x03, 0x20, 0x34, 0x03, 0x05, + 0x40, 0x13, 0x04, 0x06, 0xcc, 0x21, 0x00, 0x02, 0xd0, 0x21, 0x00, 0x02, 0xd4, 0x21, 0x00, 0x02, 0xd8, 0x21, 0x00, 0x02, 0xdc, 0x21, 0x00, 0x02, 0xe0, 0x21, 0x00, 0x02, 0xe4, 0x21, 0x00, 0x02, + 0xe8, 0x21, 0x00, 0x02, 0xec, 0x21, 0x00, 0x02, 0x54, 0x2a, 0x01, 0x02, 0x58, 0x2a, 0x01, 0x02, 0x5c, 0x2a, 0x01, 0x02, 0x60, 0x2a, 0x01, 0x02, 0x64, 0x2a, 0x01, 0x02, 0x68, 0x2a, 0x01, 0x02, + 0x6c, 0x2a, 0x01, 0x02, 0x70, 0x2a, 0x01, 0x02, 0x74, 0x2a, 0x01, 0x02, 0x78, 0x2a, 0x01, 0x02, 0x98, 0x0d, 0x02, 0x03, 0xa0, 0x0d, 0x02, 0x03, 0xa8, 0x0d, 0x02, 0x03, 0x40, 0x34, 0x03, 0x05, + 0x80, 0x13, 0x04, 0x06, 0xf0, 0x21, 0x00, 0x02, 0xf4, 0x21, 0x00, 0x02, 0xf8, 0x21, 0x00, 0x02, 0xfc, 0x21, 0x00, 0x02, 0x00, 0x22, 0x00, 0x02, 0x04, 0x22, 0x00, 0x02, 0x08, 0x22, 0x00, 0x02, + 0x0c, 0x22, 0x00, 0x02, 0x10, 0x22, 0x00, 0x02, 0x7c, 0x2a, 0x01, 0x02, 0x80, 0x2a, 0x01, 0x02, 0x84, 0x2a, 0x01, 0x02, 0x88, 0x2a, 0x01, 0x02, 0x8c, 0x2a, 0x01, 0x02, 0x90, 0x2a, 0x01, 0x02, + 0x94, 0x2a, 0x01, 0x02, 0x98, 0x2a, 0x01, 0x02, 0x9c, 0x2a, 0x01, 0x02, 0xa0, 0x2a, 0x01, 0x02, 0xb0, 0x0d, 0x02, 0x03, 0xb8, 0x0d, 0x02, 0x03, 0xc0, 0x0d, 0x02, 0x03, 0x60, 0x34, 0x03, 0x05, + 0xc0, 0x13, 0x04, 0x06, 0x14, 0x22, 0x00, 0x02, 0x18, 0x22, 0x00, 0x02, 0x1c, 0x22, 0x00, 0x02, 0x20, 0x22, 0x00, 0x02, 0x24, 0x22, 0x00, 0x02, 0x28, 0x22, 0x00, 0x02, 0x2c, 0x22, 0x00, 0x02, + 0x30, 0x22, 0x00, 0x02, 0x34, 0x22, 0x00, 0x02, 0xa4, 0x2a, 0x01, 0x02, 0xa8, 0x2a, 0x01, 0x02, 0xac, 0x2a, 0x01, 0x02, 0xb0, 0x2a, 0x01, 0x02, 0xb4, 0x2a, 0x01, 0x02, 0xb8, 0x2a, 0x01, 0x02, + 0xbc, 0x2a, 0x01, 0x02, 0xc0, 0x2a, 0x01, 0x02, 0xc4, 0x2a, 0x01, 0x02, 0xc8, 0x2a, 0x01, 0x02, 0xc8, 0x0d, 0x02, 0x03, 0xd0, 0x0d, 0x02, 0x03, 0xd8, 0x0d, 0x02, 0x03, 0x80, 0x34, 0x03, 0x05, + 0x00, 0x14, 0x04, 0x06, 0x38, 0x22, 0x00, 0x02, 0x3c, 0x22, 0x00, 0x02, 0x40, 0x22, 0x00, 0x02, 0x44, 0x22, 0x00, 0x02, 0x48, 0x22, 0x00, 0x02, 0x4c, 0x22, 0x00, 0x02, 0x50, 0x22, 0x00, 0x02, + 0x54, 0x22, 0x00, 0x02, 0x58, 0x22, 0x00, 0x02, 0xcc, 0x2a, 0x01, 0x02, 0xd0, 0x2a, 0x01, 0x02, 0xd4, 0x2a, 0x01, 0x02, 0xd8, 0x2a, 0x01, 0x02, 0xdc, 0x2a, 0x01, 0x02, 0xe0, 0x2a, 0x01, 0x02, + 0xe4, 0x2a, 0x01, 0x02, 0xe8, 0x2a, 0x01, 0x02, 0xec, 0x2a, 0x01, 0x02, 0xf0, 0x2a, 0x01, 0x02, 0xe0, 0x0d, 0x02, 0x03, 0xe8, 0x0d, 0x02, 0x03, 0xf0, 0x0d, 0x02, 0x03, 0xa0, 0x34, 0x03, 0x05, + 0x40, 0x14, 0x04, 0x06, 0x5c, 0x22, 0x00, 0x02, 0x60, 0x22, 0x00, 0x02, 0x64, 0x22, 0x00, 0x02, 0x68, 0x22, 0x00, 0x02, 0x6c, 0x22, 0x00, 0x02, 0x70, 0x22, 0x00, 0x02, 0x74, 0x22, 0x00, 0x02, + 0x78, 0x22, 0x00, 0x02, 0x7c, 0x22, 0x00, 0x02, 0xf4, 0x2a, 0x01, 0x02, 0xf8, 0x2a, 0x01, 0x02, 0xfc, 0x2a, 0x01, 0x02, 0x00, 0x2b, 0x01, 0x02, 0x04, 0x2b, 0x01, 0x02, 0x08, 0x2b, 0x01, 0x02, + 0x0c, 0x2b, 0x01, 0x02, 0x10, 0x2b, 0x01, 0x02, 0x14, 0x2b, 0x01, 0x02, 0x18, 0x2b, 0x01, 0x02, 0xf8, 0x0d, 0x02, 0x03, 0x00, 0x0e, 0x02, 0x03, 0x08, 0x0e, 0x02, 0x03, 0xc0, 0x34, 0x03, 0x05, + 0x80, 0x14, 0x04, 0x06, 0x80, 0x22, 0x00, 0x02, 0x84, 0x22, 0x00, 0x02, 0x88, 0x22, 0x00, 0x02, 0x8c, 0x22, 0x00, 0x02, 0x90, 0x22, 0x00, 0x02, 0x94, 0x22, 0x00, 0x02, 0x98, 0x22, 0x00, 0x02, + 0x9c, 0x22, 0x00, 0x02, 0xa0, 0x22, 0x00, 0x02, 0x1c, 0x2b, 0x01, 0x02, 0x20, 0x2b, 0x01, 0x02, 0x24, 0x2b, 0x01, 0x02, 0x28, 0x2b, 0x01, 0x02, 0x2c, 0x2b, 0x01, 0x02, 0x30, 0x2b, 0x01, 0x02, + 0x34, 0x2b, 0x01, 0x02, 0x38, 0x2b, 0x01, 0x02, 0x3c, 0x2b, 0x01, 0x02, 0x10, 0x0e, 0x02, 0x03, 0x18, 0x0e, 0x02, 0x03, 0x20, 0x0e, 0x02, 0x03, 0x28, 0x0e, 0x02, 0x03, 0xe0, 0x34, 0x03, 0x05, + 0xc0, 0x14, 0x04, 0x06, 0xa4, 0x22, 0x00, 0x02, 0xa8, 0x22, 0x00, 0x02, 0xac, 0x22, 0x00, 0x02, 0xb0, 0x22, 0x00, 0x02, 0xb4, 0x22, 0x00, 0x02, 0xb8, 0x22, 0x00, 0x02, 0xbc, 0x22, 0x00, 0x02, + 0xc0, 0x22, 0x00, 0x02, 0xc4, 0x22, 0x00, 0x02, 0x40, 0x2b, 0x01, 0x02, 0x44, 0x2b, 0x01, 0x02, 0x48, 0x2b, 0x01, 0x02, 0x4c, 0x2b, 0x01, 0x02, 0x50, 0x2b, 0x01, 0x02, 0x54, 0x2b, 0x01, 0x02, + 0x58, 0x2b, 0x01, 0x02, 0x5c, 0x2b, 0x01, 0x02, 0x60, 0x2b, 0x01, 0x02, 0x30, 0x0e, 0x02, 0x03, 0x38, 0x0e, 0x02, 0x03, 0x40, 0x0e, 0x02, 0x03, 0x48, 0x0e, 0x02, 0x03, 0x00, 0x35, 0x03, 0x05, + 0x00, 0x15, 0x04, 0x06, 0xc8, 0x22, 0x00, 0x02, 0xcc, 0x22, 0x00, 0x02, 0xd0, 0x22, 0x00, 0x02, 0xd4, 0x22, 0x00, 0x02, 0xd8, 0x22, 0x00, 0x02, 0xdc, 0x22, 0x00, 0x02, 0xe0, 0x22, 0x00, 0x02, + 0xe4, 0x22, 0x00, 0x02, 0xe8, 0x22, 0x00, 0x02, 0x64, 0x2b, 0x01, 0x02, 0x68, 0x2b, 0x01, 0x02, 0x6c, 0x2b, 0x01, 0x02, 0x70, 0x2b, 0x01, 0x02, 0x74, 0x2b, 0x01, 0x02, 0x78, 0x2b, 0x01, 0x02, + 0x7c, 0x2b, 0x01, 0x02, 0x80, 0x2b, 0x01, 0x02, 0x84, 0x2b, 0x01, 0x02, 0x50, 0x0e, 0x02, 0x03, 0x58, 0x0e, 0x02, 0x03, 0x60, 0x0e, 0x02, 0x03, 0x68, 0x0e, 0x02, 0x03, 0x20, 0x35, 0x03, 0x05, + 0x40, 0x15, 0x04, 0x06, 0xec, 0x22, 0x00, 0x02, 0xf0, 0x22, 0x00, 0x02, 0xf4, 0x22, 0x00, 0x02, 0xf8, 0x22, 0x00, 0x02, 0xfc, 0x22, 0x00, 0x02, 0x00, 0x23, 0x00, 0x02, 0x04, 0x23, 0x00, 0x02, + 0x08, 0x23, 0x00, 0x02, 0x0c, 0x23, 0x00, 0x02, 0x88, 0x2b, 0x01, 0x02, 0x8c, 0x2b, 0x01, 0x02, 0x90, 0x2b, 0x01, 0x02, 0x94, 0x2b, 0x01, 0x02, 0x98, 0x2b, 0x01, 0x02, 0x9c, 0x2b, 0x01, 0x02, + 0xa0, 0x2b, 0x01, 0x02, 0xa4, 0x2b, 0x01, 0x02, 0xa8, 0x2b, 0x01, 0x02, 0x70, 0x0e, 0x02, 0x03, 0x78, 0x0e, 0x02, 0x03, 0x80, 0x0e, 0x02, 0x03, 0x88, 0x0e, 0x02, 0x03, 0x40, 0x35, 0x03, 0x05, + 0x80, 0x15, 0x04, 0x06, 0x10, 0x23, 0x00, 0x02, 0x14, 0x23, 0x00, 0x02, 0x18, 0x23, 0x00, 0x02, 0x1c, 0x23, 0x00, 0x02, 0x20, 0x23, 0x00, 0x02, 0x24, 0x23, 0x00, 0x02, 0x28, 0x23, 0x00, 0x02, + 0x2c, 0x23, 0x00, 0x02, 0x30, 0x23, 0x00, 0x02, 0xac, 0x2b, 0x01, 0x02, 0xb0, 0x2b, 0x01, 0x02, 0xb4, 0x2b, 0x01, 0x02, 0xb8, 0x2b, 0x01, 0x02, 0xbc, 0x2b, 0x01, 0x02, 0xc0, 0x2b, 0x01, 0x02, + 0xc4, 0x2b, 0x01, 0x02, 0xc8, 0x2b, 0x01, 0x02, 0xcc, 0x2b, 0x01, 0x02, 0x90, 0x0e, 0x02, 0x03, 0x98, 0x0e, 0x02, 0x03, 0xa0, 0x0e, 0x02, 0x03, 0xa8, 0x0e, 0x02, 0x03, 0x60, 0x35, 0x03, 0x05, + 0xc0, 0x15, 0x04, 0x06, 0x34, 0x23, 0x00, 0x02, 0x38, 0x23, 0x00, 0x02, 0x3c, 0x23, 0x00, 0x02, 0x40, 0x23, 0x00, 0x02, 0x44, 0x23, 0x00, 0x02, 0x48, 0x23, 0x00, 0x02, 0x4c, 0x23, 0x00, 0x02, + 0x50, 0x23, 0x00, 0x02, 0x54, 0x23, 0x00, 0x02, 0xd0, 0x2b, 0x01, 0x02, 0xd4, 0x2b, 0x01, 0x02, 0xd8, 0x2b, 0x01, 0x02, 0xdc, 0x2b, 0x01, 0x02, 0xe0, 0x2b, 0x01, 0x02, 0xe4, 0x2b, 0x01, 0x02, + 0xe8, 0x2b, 0x01, 0x02, 0xec, 0x2b, 0x01, 0x02, 0xf0, 0x2b, 0x01, 0x02, 0xb0, 0x0e, 0x02, 0x03, 0xb8, 0x0e, 0x02, 0x03, 0xc0, 0x0e, 0x02, 0x03, 0xc8, 0x0e, 0x02, 0x03, 0x80, 0x35, 0x03, 0x05, + 0x00, 0x16, 0x04, 0x06, 0x58, 0x23, 0x00, 0x02, 0x5c, 0x23, 0x00, 0x02, 0x60, 0x23, 0x00, 0x02, 0x64, 0x23, 0x00, 0x02, 0x68, 0x23, 0x00, 0x02, 0x6c, 0x23, 0x00, 0x02, 0x70, 0x23, 0x00, 0x02, + 0x74, 0x23, 0x00, 0x02, 0x78, 0x23, 0x00, 0x02, 0xf4, 0x2b, 0x01, 0x02, 0xf8, 0x2b, 0x01, 0x02, 0xfc, 0x2b, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x04, 0x2c, 0x01, 0x02, 0x08, 0x2c, 0x01, 0x02, + 0x0c, 0x2c, 0x01, 0x02, 0x10, 0x2c, 0x01, 0x02, 0x14, 0x2c, 0x01, 0x02, 0xd0, 0x0e, 0x02, 0x03, 0xd8, 0x0e, 0x02, 0x03, 0xe0, 0x0e, 0x02, 0x03, 0xe8, 0x0e, 0x02, 0x03, 0xa0, 0x35, 0x03, 0x05, + 0x40, 0x16, 0x04, 0x06, 0x7c, 0x23, 0x00, 0x02, 0x80, 0x23, 0x00, 0x02, 0x84, 0x23, 0x00, 0x02, 0x88, 0x23, 0x00, 0x02, 0x8c, 0x23, 0x00, 0x02, 0x90, 0x23, 0x00, 0x02, 0x94, 0x23, 0x00, 0x02, + 0x98, 0x23, 0x00, 0x02, 0x9c, 0x23, 0x00, 0x02, 0x18, 0x2c, 0x01, 0x02, 0x1c, 0x2c, 0x01, 0x02, 0x20, 0x2c, 0x01, 0x02, 0x24, 0x2c, 0x01, 0x02, 0x28, 0x2c, 0x01, 0x02, 0x2c, 0x2c, 0x01, 0x02, + 0x30, 0x2c, 0x01, 0x02, 0x34, 0x2c, 0x01, 0x02, 0x38, 0x2c, 0x01, 0x02, 0xf0, 0x0e, 0x02, 0x03, 0xf8, 0x0e, 0x02, 0x03, 0x00, 0x0f, 0x02, 0x03, 0x08, 0x0f, 0x02, 0x03, 0xc0, 0x35, 0x03, 0x05, + 0x80, 0x16, 0x04, 0x06, 0xa0, 0x23, 0x00, 0x02, 0xa4, 0x23, 0x00, 0x02, 0xa8, 0x23, 0x00, 0x02, 0xac, 0x23, 0x00, 0x02, 0xb0, 0x23, 0x00, 0x02, 0xb4, 0x23, 0x00, 0x02, 0xb8, 0x23, 0x00, 0x02, + 0xbc, 0x23, 0x00, 0x02, 0xc0, 0x23, 0x00, 0x02, 0x3c, 0x2c, 0x01, 0x02, 0x40, 0x2c, 0x01, 0x02, 0x44, 0x2c, 0x01, 0x02, 0x48, 0x2c, 0x01, 0x02, 0x4c, 0x2c, 0x01, 0x02, 0x50, 0x2c, 0x01, 0x02, + 0x54, 0x2c, 0x01, 0x02, 0x58, 0x2c, 0x01, 0x02, 0x5c, 0x2c, 0x01, 0x02, 0x10, 0x0f, 0x02, 0x03, 0x18, 0x0f, 0x02, 0x03, 0x20, 0x0f, 0x02, 0x03, 0x28, 0x0f, 0x02, 0x03, 0xe0, 0x35, 0x03, 0x05, + 0xc0, 0x16, 0x04, 0x06, 0xc4, 0x23, 0x00, 0x02, 0xc8, 0x23, 0x00, 0x02, 0xcc, 0x23, 0x00, 0x02, 0xd0, 0x23, 0x00, 0x02, 0xd4, 0x23, 0x00, 0x02, 0xd8, 0x23, 0x00, 0x02, 0xdc, 0x23, 0x00, 0x02, + 0xe0, 0x23, 0x00, 0x02, 0xe4, 0x23, 0x00, 0x02, 0x60, 0x2c, 0x01, 0x02, 0x64, 0x2c, 0x01, 0x02, 0x68, 0x2c, 0x01, 0x02, 0x6c, 0x2c, 0x01, 0x02, 0x70, 0x2c, 0x01, 0x02, 0x74, 0x2c, 0x01, 0x02, + 0x78, 0x2c, 0x01, 0x02, 0x7c, 0x2c, 0x01, 0x02, 0x80, 0x2c, 0x01, 0x02, 0x30, 0x0f, 0x02, 0x03, 0x38, 0x0f, 0x02, 0x03, 0x40, 0x0f, 0x02, 0x03, 0x48, 0x0f, 0x02, 0x03, 0x00, 0x36, 0x03, 0x05, + 0x00, 0x17, 0x04, 0x06, 0xe8, 0x23, 0x00, 0x02, 0xec, 0x23, 0x00, 0x02, 0xf0, 0x23, 0x00, 0x02, 0xf4, 0x23, 0x00, 0x02, 0xf8, 0x23, 0x00, 0x02, 0xfc, 0x23, 0x00, 0x02, 0x00, 0x24, 0x00, 0x02, + 0x04, 0x24, 0x00, 0x02, 0x08, 0x24, 0x00, 0x02, 0x84, 0x2c, 0x01, 0x02, 0x88, 0x2c, 0x01, 0x02, 0x8c, 0x2c, 0x01, 0x02, 0x90, 0x2c, 0x01, 0x02, 0x94, 0x2c, 0x01, 0x02, 0x98, 0x2c, 0x01, 0x02, + 0x9c, 0x2c, 0x01, 0x02, 0xa0, 0x2c, 0x01, 0x02, 0xa4, 0x2c, 0x01, 0x02, 0x50, 0x0f, 0x02, 0x03, 0x58, 0x0f, 0x02, 0x03, 0x60, 0x0f, 0x02, 0x03, 0x68, 0x0f, 0x02, 0x03, 0x20, 0x36, 0x03, 0x05, + 0x40, 0x17, 0x04, 0x06, 0x0c, 0x24, 0x00, 0x02, 0x10, 0x24, 0x00, 0x02, 0x14, 0x24, 0x00, 0x02, 0x18, 0x24, 0x00, 0x02, 0x1c, 0x24, 0x00, 0x02, 0x20, 0x24, 0x00, 0x02, 0x24, 0x24, 0x00, 0x02, + 0x28, 0x24, 0x00, 0x02, 0x2c, 0x24, 0x00, 0x02, 0xa8, 0x2c, 0x01, 0x02, 0xac, 0x2c, 0x01, 0x02, 0xb0, 0x2c, 0x01, 0x02, 0xb4, 0x2c, 0x01, 0x02, 0xb8, 0x2c, 0x01, 0x02, 0xbc, 0x2c, 0x01, 0x02, + 0xc0, 0x2c, 0x01, 0x02, 0xc4, 0x2c, 0x01, 0x02, 0xc8, 0x2c, 0x01, 0x02, 0x70, 0x0f, 0x02, 0x03, 0x78, 0x0f, 0x02, 0x03, 0x80, 0x0f, 0x02, 0x03, 0x88, 0x0f, 0x02, 0x03, 0x40, 0x36, 0x03, 0x05, + 0x80, 0x17, 0x04, 0x06, 0x30, 0x24, 0x00, 0x02, 0x34, 0x24, 0x00, 0x02, 0x38, 0x24, 0x00, 0x02, 0x3c, 0x24, 0x00, 0x02, 0x40, 0x24, 0x00, 0x02, 0x44, 0x24, 0x00, 0x02, 0x48, 0x24, 0x00, 0x02, + 0x4c, 0x24, 0x00, 0x02, 0x50, 0x24, 0x00, 0x02, 0xcc, 0x2c, 0x01, 0x02, 0xd0, 0x2c, 0x01, 0x02, 0xd4, 0x2c, 0x01, 0x02, 0xd8, 0x2c, 0x01, 0x02, 0xdc, 0x2c, 0x01, 0x02, 0xe0, 0x2c, 0x01, 0x02, + 0xe4, 0x2c, 0x01, 0x02, 0xe8, 0x2c, 0x01, 0x02, 0xec, 0x2c, 0x01, 0x02, 0x90, 0x0f, 0x02, 0x03, 0x98, 0x0f, 0x02, 0x03, 0xa0, 0x0f, 0x02, 0x03, 0xa8, 0x0f, 0x02, 0x03, 0x60, 0x36, 0x03, 0x05, + 0xc0, 0x17, 0x04, 0x06, 0x54, 0x24, 0x00, 0x02, 0x58, 0x24, 0x00, 0x02, 0x5c, 0x24, 0x00, 0x02, 0x60, 0x24, 0x00, 0x02, 0x64, 0x24, 0x00, 0x02, 0x68, 0x24, 0x00, 0x02, 0x6c, 0x24, 0x00, 0x02, + 0x70, 0x24, 0x00, 0x02, 0x74, 0x24, 0x00, 0x02, 0xf0, 0x2c, 0x01, 0x02, 0xf4, 0x2c, 0x01, 0x02, 0xf8, 0x2c, 0x01, 0x02, 0xfc, 0x2c, 0x01, 0x02, 0x00, 0x2d, 0x01, 0x02, 0x04, 0x2d, 0x01, 0x02, + 0x08, 0x2d, 0x01, 0x02, 0x0c, 0x2d, 0x01, 0x02, 0x10, 0x2d, 0x01, 0x02, 0xb0, 0x0f, 0x02, 0x03, 0xb8, 0x0f, 0x02, 0x03, 0xc0, 0x0f, 0x02, 0x03, 0xc8, 0x0f, 0x02, 0x03, 0x80, 0x36, 0x03, 0x05, + 0x00, 0x18, 0x04, 0x06, 0x78, 0x24, 0x00, 0x02, 0x7c, 0x24, 0x00, 0x02, 0x80, 0x24, 0x00, 0x02, 0x84, 0x24, 0x00, 0x02, 0x88, 0x24, 0x00, 0x02, 0x8c, 0x24, 0x00, 0x02, 0x90, 0x24, 0x00, 0x02, + 0x94, 0x24, 0x00, 0x02, 0x98, 0x24, 0x00, 0x02, 0x14, 0x2d, 0x01, 0x02, 0x18, 0x2d, 0x01, 0x02, 0x1c, 0x2d, 0x01, 0x02, 0x20, 0x2d, 0x01, 0x02, 0x24, 0x2d, 0x01, 0x02, 0x28, 0x2d, 0x01, 0x02, + 0x2c, 0x2d, 0x01, 0x02, 0x30, 0x2d, 0x01, 0x02, 0x34, 0x2d, 0x01, 0x02, 0xd0, 0x0f, 0x02, 0x03, 0xd8, 0x0f, 0x02, 0x03, 0xe0, 0x0f, 0x02, 0x03, 0xe8, 0x0f, 0x02, 0x03, 0xa0, 0x36, 0x03, 0x05, + 0x40, 0x18, 0x04, 0x06, 0x9c, 0x24, 0x00, 0x02, 0xa0, 0x24, 0x00, 0x02, 0xa4, 0x24, 0x00, 0x02, 0xa8, 0x24, 0x00, 0x02, 0xac, 0x24, 0x00, 0x02, 0xb0, 0x24, 0x00, 0x02, 0xb4, 0x24, 0x00, 0x02, + 0xb8, 0x24, 0x00, 0x02, 0xbc, 0x24, 0x00, 0x02, 0x38, 0x2d, 0x01, 0x02, 0x3c, 0x2d, 0x01, 0x02, 0x40, 0x2d, 0x01, 0x02, 0x44, 0x2d, 0x01, 0x02, 0x48, 0x2d, 0x01, 0x02, 0x4c, 0x2d, 0x01, 0x02, + 0x50, 0x2d, 0x01, 0x02, 0x54, 0x2d, 0x01, 0x02, 0x58, 0x2d, 0x01, 0x02, 0xf0, 0x0f, 0x02, 0x03, 0xf8, 0x0f, 0x02, 0x03, 0x00, 0x10, 0x02, 0x03, 0x08, 0x10, 0x02, 0x03, 0xc0, 0x36, 0x03, 0x05, + 0x80, 0x18, 0x04, 0x06, 0xc0, 0x24, 0x00, 0x02, 0xc4, 0x24, 0x00, 0x02, 0xc8, 0x24, 0x00, 0x02, 0xcc, 0x24, 0x00, 0x02, 0xd0, 0x24, 0x00, 0x02, 0xd4, 0x24, 0x00, 0x02, 0xd8, 0x24, 0x00, 0x02, + 0xdc, 0x24, 0x00, 0x02, 0xe0, 0x24, 0x00, 0x02, 0x5c, 0x2d, 0x01, 0x02, 0x60, 0x2d, 0x01, 0x02, 0x64, 0x2d, 0x01, 0x02, 0x68, 0x2d, 0x01, 0x02, 0x6c, 0x2d, 0x01, 0x02, 0x70, 0x2d, 0x01, 0x02, + 0x74, 0x2d, 0x01, 0x02, 0x78, 0x2d, 0x01, 0x02, 0x7c, 0x2d, 0x01, 0x02, 0x10, 0x10, 0x02, 0x03, 0x18, 0x10, 0x02, 0x03, 0x20, 0x10, 0x02, 0x03, 0x28, 0x10, 0x02, 0x03, 0xe0, 0x36, 0x03, 0x05, + 0xc0, 0x18, 0x04, 0x06, 0xe4, 0x24, 0x00, 0x02, 0xe8, 0x24, 0x00, 0x02, 0xec, 0x24, 0x00, 0x02, 0xf0, 0x24, 0x00, 0x02, 0xf4, 0x24, 0x00, 0x02, 0xf8, 0x24, 0x00, 0x02, 0xfc, 0x24, 0x00, 0x02, + 0x00, 0x25, 0x00, 0x02, 0x04, 0x25, 0x00, 0x02, 0x80, 0x2d, 0x01, 0x02, 0x84, 0x2d, 0x01, 0x02, 0x88, 0x2d, 0x01, 0x02, 0x8c, 0x2d, 0x01, 0x02, 0x90, 0x2d, 0x01, 0x02, 0x94, 0x2d, 0x01, 0x02, + 0x98, 0x2d, 0x01, 0x02, 0x9c, 0x2d, 0x01, 0x02, 0xa0, 0x2d, 0x01, 0x02, 0x30, 0x10, 0x02, 0x03, 0x38, 0x10, 0x02, 0x03, 0x40, 0x10, 0x02, 0x03, 0x48, 0x10, 0x02, 0x03, 0x00, 0x37, 0x03, 0x05, + 0x00, 0x19, 0x04, 0x06, 0x08, 0x25, 0x00, 0x02, 0x0c, 0x25, 0x00, 0x02, 0x10, 0x25, 0x00, 0x02, 0x14, 0x25, 0x00, 0x02, 0x18, 0x25, 0x00, 0x02, 0x1c, 0x25, 0x00, 0x02, 0x20, 0x25, 0x00, 0x02, + 0x24, 0x25, 0x00, 0x02, 0x28, 0x25, 0x00, 0x02, 0xa4, 0x2d, 0x01, 0x02, 0xa8, 0x2d, 0x01, 0x02, 0xac, 0x2d, 0x01, 0x02, 0xb0, 0x2d, 0x01, 0x02, 0xb4, 0x2d, 0x01, 0x02, 0xb8, 0x2d, 0x01, 0x02, + 0xbc, 0x2d, 0x01, 0x02, 0xc0, 0x2d, 0x01, 0x02, 0xc4, 0x2d, 0x01, 0x02, 0x50, 0x10, 0x02, 0x03, 0x58, 0x10, 0x02, 0x03, 0x60, 0x10, 0x02, 0x03, 0x68, 0x10, 0x02, 0x03, 0x20, 0x37, 0x03, 0x05, + 0x40, 0x19, 0x04, 0x06, 0x2c, 0x25, 0x00, 0x02, 0x30, 0x25, 0x00, 0x02, 0x34, 0x25, 0x00, 0x02, 0x38, 0x25, 0x00, 0x02, 0x3c, 0x25, 0x00, 0x02, 0x40, 0x25, 0x00, 0x02, 0x44, 0x25, 0x00, 0x02, + 0x48, 0x25, 0x00, 0x02, 0x4c, 0x25, 0x00, 0x02, 0xc8, 0x2d, 0x01, 0x02, 0xcc, 0x2d, 0x01, 0x02, 0xd0, 0x2d, 0x01, 0x02, 0xd4, 0x2d, 0x01, 0x02, 0xd8, 0x2d, 0x01, 0x02, 0xdc, 0x2d, 0x01, 0x02, + 0xe0, 0x2d, 0x01, 0x02, 0xe4, 0x2d, 0x01, 0x02, 0xe8, 0x2d, 0x01, 0x02, 0x70, 0x10, 0x02, 0x03, 0x78, 0x10, 0x02, 0x03, 0x80, 0x10, 0x02, 0x03, 0x88, 0x10, 0x02, 0x03, 0x40, 0x37, 0x03, 0x05, + 0x80, 0x19, 0x04, 0x06, 0x50, 0x25, 0x00, 0x02, 0x54, 0x25, 0x00, 0x02, 0x58, 0x25, 0x00, 0x02, 0x5c, 0x25, 0x00, 0x02, 0x60, 0x25, 0x00, 0x02, 0x64, 0x25, 0x00, 0x02, 0x68, 0x25, 0x00, 0x02, + 0x6c, 0x25, 0x00, 0x02, 0x70, 0x25, 0x00, 0x02, 0xec, 0x2d, 0x01, 0x02, 0xf0, 0x2d, 0x01, 0x02, 0xf4, 0x2d, 0x01, 0x02, 0xf8, 0x2d, 0x01, 0x02, 0xfc, 0x2d, 0x01, 0x02, 0x00, 0x2e, 0x01, 0x02, + 0x04, 0x2e, 0x01, 0x02, 0x08, 0x2e, 0x01, 0x02, 0x0c, 0x2e, 0x01, 0x02, 0x90, 0x10, 0x02, 0x03, 0x98, 0x10, 0x02, 0x03, 0xa0, 0x10, 0x02, 0x03, 0xa8, 0x10, 0x02, 0x03, 0x60, 0x37, 0x03, 0x05, + 0xc0, 0x19, 0x04, 0x06, 0x74, 0x25, 0x00, 0x02, 0x78, 0x25, 0x00, 0x02, 0x7c, 0x25, 0x00, 0x02, 0x80, 0x25, 0x00, 0x02, 0x84, 0x25, 0x00, 0x02, 0x88, 0x25, 0x00, 0x02, 0x8c, 0x25, 0x00, 0x02, + 0x90, 0x25, 0x00, 0x02, 0x94, 0x25, 0x00, 0x02, 0x10, 0x2e, 0x01, 0x02, 0x14, 0x2e, 0x01, 0x02, 0x18, 0x2e, 0x01, 0x02, 0x1c, 0x2e, 0x01, 0x02, 0x20, 0x2e, 0x01, 0x02, 0x24, 0x2e, 0x01, 0x02, + 0x28, 0x2e, 0x01, 0x02, 0x2c, 0x2e, 0x01, 0x02, 0x30, 0x2e, 0x01, 0x02, 0xb0, 0x10, 0x02, 0x03, 0xb8, 0x10, 0x02, 0x03, 0xc0, 0x10, 0x02, 0x03, 0xc8, 0x10, 0x02, 0x03, 0x80, 0x37, 0x03, 0x05, + 0x00, 0x1a, 0x04, 0x06, 0x98, 0x25, 0x00, 0x02, 0x9c, 0x25, 0x00, 0x02, 0xa0, 0x25, 0x00, 0x02, 0xa4, 0x25, 0x00, 0x02, 0xa8, 0x25, 0x00, 0x02, 0xac, 0x25, 0x00, 0x02, 0xb0, 0x25, 0x00, 0x02, + 0xb4, 0x25, 0x00, 0x02, 0xb8, 0x25, 0x00, 0x02, 0x34, 0x2e, 0x01, 0x02, 0x38, 0x2e, 0x01, 0x02, 0x3c, 0x2e, 0x01, 0x02, 0x40, 0x2e, 0x01, 0x02, 0x44, 0x2e, 0x01, 0x02, 0x48, 0x2e, 0x01, 0x02, + 0x4c, 0x2e, 0x01, 0x02, 0x50, 0x2e, 0x01, 0x02, 0x54, 0x2e, 0x01, 0x02, 0xd0, 0x10, 0x02, 0x03, 0xd8, 0x10, 0x02, 0x03, 0xe0, 0x10, 0x02, 0x03, 0xe8, 0x10, 0x02, 0x03, 0xa0, 0x37, 0x03, 0x05, + 0x40, 0x1a, 0x04, 0x06, 0xbc, 0x25, 0x00, 0x02, 0xc0, 0x25, 0x00, 0x02, 0xc4, 0x25, 0x00, 0x02, 0xc8, 0x25, 0x00, 0x02, 0xcc, 0x25, 0x00, 0x02, 0xd0, 0x25, 0x00, 0x02, 0xd4, 0x25, 0x00, 0x02, + 0xd8, 0x25, 0x00, 0x02, 0xdc, 0x25, 0x00, 0x02, 0x58, 0x2e, 0x01, 0x02, 0x5c, 0x2e, 0x01, 0x02, 0x60, 0x2e, 0x01, 0x02, 0x64, 0x2e, 0x01, 0x02, 0x68, 0x2e, 0x01, 0x02, 0x6c, 0x2e, 0x01, 0x02, + 0x70, 0x2e, 0x01, 0x02, 0x74, 0x2e, 0x01, 0x02, 0x78, 0x2e, 0x01, 0x02, 0xf0, 0x10, 0x02, 0x03, 0xf8, 0x10, 0x02, 0x03, 0x00, 0x11, 0x02, 0x03, 0x08, 0x11, 0x02, 0x03, 0xc0, 0x37, 0x03, 0x05, + 0x80, 0x1a, 0x04, 0x06, 0xe0, 0x25, 0x00, 0x02, 0xe4, 0x25, 0x00, 0x02, 0xe8, 0x25, 0x00, 0x02, 0xec, 0x25, 0x00, 0x02, 0xf0, 0x25, 0x00, 0x02, 0xf4, 0x25, 0x00, 0x02, 0xf8, 0x25, 0x00, 0x02, + 0xfc, 0x25, 0x00, 0x02, 0x00, 0x26, 0x00, 0x02, 0x7c, 0x2e, 0x01, 0x02, 0x80, 0x2e, 0x01, 0x02, 0x84, 0x2e, 0x01, 0x02, 0x88, 0x2e, 0x01, 0x02, 0x8c, 0x2e, 0x01, 0x02, 0x90, 0x2e, 0x01, 0x02, + 0x94, 0x2e, 0x01, 0x02, 0x98, 0x2e, 0x01, 0x02, 0x9c, 0x2e, 0x01, 0x02, 0x10, 0x11, 0x02, 0x03, 0x18, 0x11, 0x02, 0x03, 0x20, 0x11, 0x02, 0x03, 0x28, 0x11, 0x02, 0x03, 0xe0, 0x37, 0x03, 0x05, + 0xc0, 0x1a, 0x04, 0x06, 0x04, 0x26, 0x00, 0x02, 0x08, 0x26, 0x00, 0x02, 0x0c, 0x26, 0x00, 0x02, 0x10, 0x26, 0x00, 0x02, 0x14, 0x26, 0x00, 0x02, 0x18, 0x26, 0x00, 0x02, 0x1c, 0x26, 0x00, 0x02, + 0x20, 0x26, 0x00, 0x02, 0x24, 0x26, 0x00, 0x02, 0xa0, 0x2e, 0x01, 0x02, 0xa4, 0x2e, 0x01, 0x02, 0xa8, 0x2e, 0x01, 0x02, 0xac, 0x2e, 0x01, 0x02, 0xb0, 0x2e, 0x01, 0x02, 0xb4, 0x2e, 0x01, 0x02, + 0xb8, 0x2e, 0x01, 0x02, 0xbc, 0x2e, 0x01, 0x02, 0xc0, 0x2e, 0x01, 0x02, 0x30, 0x11, 0x02, 0x03, 0x38, 0x11, 0x02, 0x03, 0x40, 0x11, 0x02, 0x03, 0x48, 0x11, 0x02, 0x03, 0x00, 0x38, 0x03, 0x05, + 0x00, 0x1b, 0x04, 0x06, 0x28, 0x26, 0x00, 0x02, 0x2c, 0x26, 0x00, 0x02, 0x30, 0x26, 0x00, 0x02, 0x34, 0x26, 0x00, 0x02, 0x38, 0x26, 0x00, 0x02, 0x3c, 0x26, 0x00, 0x02, 0x40, 0x26, 0x00, 0x02, + 0x44, 0x26, 0x00, 0x02, 0x48, 0x26, 0x00, 0x02, 0xc4, 0x2e, 0x01, 0x02, 0xc8, 0x2e, 0x01, 0x02, 0xcc, 0x2e, 0x01, 0x02, 0xd0, 0x2e, 0x01, 0x02, 0xd4, 0x2e, 0x01, 0x02, 0xd8, 0x2e, 0x01, 0x02, + 0xdc, 0x2e, 0x01, 0x02, 0xe0, 0x2e, 0x01, 0x02, 0xe4, 0x2e, 0x01, 0x02, 0x50, 0x11, 0x02, 0x03, 0x58, 0x11, 0x02, 0x03, 0x60, 0x11, 0x02, 0x03, 0x68, 0x11, 0x02, 0x03, 0x20, 0x38, 0x03, 0x05, + 0x00, 0x37, 0x05, 0x08, 0x4c, 0x26, 0x00, 0x02, 0x50, 0x26, 0x00, 0x02, 0x54, 0x26, 0x00, 0x02, 0x58, 0x26, 0x00, 0x02, 0x5c, 0x26, 0x00, 0x02, 0x60, 0x26, 0x00, 0x02, 0x64, 0x26, 0x00, 0x02, + 0x68, 0x26, 0x00, 0x02, 0x6c, 0x26, 0x00, 0x02, 0xe8, 0x2e, 0x01, 0x02, 0xec, 0x2e, 0x01, 0x02, 0xf0, 0x2e, 0x01, 0x02, 0xf4, 0x2e, 0x01, 0x02, 0xf8, 0x2e, 0x01, 0x02, 0xfc, 0x2e, 0x01, 0x02, + 0x00, 0x2f, 0x01, 0x02, 0x04, 0x2f, 0x01, 0x02, 0x08, 0x2f, 0x01, 0x02, 0x70, 0x11, 0x02, 0x03, 0x78, 0x11, 0x02, 0x03, 0x80, 0x11, 0x02, 0x03, 0x88, 0x11, 0x02, 0x03, 0x40, 0x38, 0x03, 0x05, + 0x00, 0x38, 0x05, 0x08, 0x70, 0x26, 0x00, 0x02, 0x74, 0x26, 0x00, 0x02, 0x78, 0x26, 0x00, 0x02, 0x7c, 0x26, 0x00, 0x02, 0x80, 0x26, 0x00, 0x02, 0x84, 0x26, 0x00, 0x02, 0x88, 0x26, 0x00, 0x02, + 0x8c, 0x26, 0x00, 0x02, 0x90, 0x26, 0x00, 0x02, 0x0c, 0x2f, 0x01, 0x02, 0x10, 0x2f, 0x01, 0x02, 0x14, 0x2f, 0x01, 0x02, 0x18, 0x2f, 0x01, 0x02, 0x1c, 0x2f, 0x01, 0x02, 0x20, 0x2f, 0x01, 0x02, + 0x24, 0x2f, 0x01, 0x02, 0x28, 0x2f, 0x01, 0x02, 0x2c, 0x2f, 0x01, 0x02, 0x90, 0x11, 0x02, 0x03, 0x98, 0x11, 0x02, 0x03, 0xa0, 0x11, 0x02, 0x03, 0xa8, 0x11, 0x02, 0x03, 0x60, 0x38, 0x03, 0x05, + 0x00, 0x39, 0x05, 0x08, 0x94, 0x26, 0x00, 0x02, 0x98, 0x26, 0x00, 0x02, 0x9c, 0x26, 0x00, 0x02, 0xa0, 0x26, 0x00, 0x02, 0xa4, 0x26, 0x00, 0x02, 0xa8, 0x26, 0x00, 0x02, 0xac, 0x26, 0x00, 0x02, + 0xb0, 0x26, 0x00, 0x02, 0xb4, 0x26, 0x00, 0x02, 0x30, 0x2f, 0x01, 0x02, 0x34, 0x2f, 0x01, 0x02, 0x38, 0x2f, 0x01, 0x02, 0x3c, 0x2f, 0x01, 0x02, 0x40, 0x2f, 0x01, 0x02, 0x44, 0x2f, 0x01, 0x02, + 0x48, 0x2f, 0x01, 0x02, 0x4c, 0x2f, 0x01, 0x02, 0x50, 0x2f, 0x01, 0x02, 0xb0, 0x11, 0x02, 0x03, 0xb8, 0x11, 0x02, 0x03, 0xc0, 0x11, 0x02, 0x03, 0xc8, 0x11, 0x02, 0x03, 0x80, 0x38, 0x03, 0x05, + 0x00, 0x3a, 0x05, 0x08, 0xb8, 0x26, 0x00, 0x02, 0xbc, 0x26, 0x00, 0x02, 0xc0, 0x26, 0x00, 0x02, 0xc4, 0x26, 0x00, 0x02, 0xc8, 0x26, 0x00, 0x02, 0xcc, 0x26, 0x00, 0x02, 0xd0, 0x26, 0x00, 0x02, + 0xd4, 0x26, 0x00, 0x02, 0xd8, 0x26, 0x00, 0x02, 0x54, 0x2f, 0x01, 0x02, 0x58, 0x2f, 0x01, 0x02, 0x5c, 0x2f, 0x01, 0x02, 0x60, 0x2f, 0x01, 0x02, 0x64, 0x2f, 0x01, 0x02, 0x68, 0x2f, 0x01, 0x02, + 0x6c, 0x2f, 0x01, 0x02, 0x70, 0x2f, 0x01, 0x02, 0x74, 0x2f, 0x01, 0x02, 0xd0, 0x11, 0x02, 0x03, 0xd8, 0x11, 0x02, 0x03, 0xe0, 0x11, 0x02, 0x03, 0xe8, 0x11, 0x02, 0x03, 0xa0, 0x38, 0x03, 0x05, + 0x00, 0x3b, 0x05, 0x08, 0xdc, 0x26, 0x00, 0x02, 0xe0, 0x26, 0x00, 0x02, 0xe4, 0x26, 0x00, 0x02, 0xe8, 0x26, 0x00, 0x02, 0xec, 0x26, 0x00, 0x02, 0xf0, 0x26, 0x00, 0x02, 0xf4, 0x26, 0x00, 0x02, + 0xf8, 0x26, 0x00, 0x02, 0xfc, 0x26, 0x00, 0x02, 0x78, 0x2f, 0x01, 0x02, 0x7c, 0x2f, 0x01, 0x02, 0x80, 0x2f, 0x01, 0x02, 0x84, 0x2f, 0x01, 0x02, 0x88, 0x2f, 0x01, 0x02, 0x8c, 0x2f, 0x01, 0x02, + 0x90, 0x2f, 0x01, 0x02, 0x94, 0x2f, 0x01, 0x02, 0x98, 0x2f, 0x01, 0x02, 0xf0, 0x11, 0x02, 0x03, 0xf8, 0x11, 0x02, 0x03, 0x00, 0x12, 0x02, 0x03, 0x08, 0x12, 0x02, 0x03, 0xc0, 0x38, 0x03, 0x05, + 0x00, 0x3c, 0x05, 0x08, 0x00, 0x27, 0x00, 0x02, 0x04, 0x27, 0x00, 0x02, 0x08, 0x27, 0x00, 0x02, 0x0c, 0x27, 0x00, 0x02, 0x10, 0x27, 0x00, 0x02, 0x14, 0x27, 0x00, 0x02, 0x18, 0x27, 0x00, 0x02, + 0x1c, 0x27, 0x00, 0x02, 0x20, 0x27, 0x00, 0x02, 0x9c, 0x2f, 0x01, 0x02, 0xa0, 0x2f, 0x01, 0x02, 0xa4, 0x2f, 0x01, 0x02, 0xa8, 0x2f, 0x01, 0x02, 0xac, 0x2f, 0x01, 0x02, 0xb0, 0x2f, 0x01, 0x02, + 0xb4, 0x2f, 0x01, 0x02, 0xb8, 0x2f, 0x01, 0x02, 0xbc, 0x2f, 0x01, 0x02, 0x10, 0x12, 0x02, 0x03, 0x18, 0x12, 0x02, 0x03, 0x20, 0x12, 0x02, 0x03, 0x28, 0x12, 0x02, 0x03, 0xe0, 0x38, 0x03, 0x05, + 0x00, 0x3d, 0x05, 0x08, 0x24, 0x27, 0x00, 0x02, 0x28, 0x27, 0x00, 0x02, 0x2c, 0x27, 0x00, 0x02, 0x30, 0x27, 0x00, 0x02, 0x34, 0x27, 0x00, 0x02, 0x38, 0x27, 0x00, 0x02, 0x3c, 0x27, 0x00, 0x02, + 0x40, 0x27, 0x00, 0x02, 0x44, 0x27, 0x00, 0x02, 0xc0, 0x2f, 0x01, 0x02, 0xc4, 0x2f, 0x01, 0x02, 0xc8, 0x2f, 0x01, 0x02, 0xcc, 0x2f, 0x01, 0x02, 0xd0, 0x2f, 0x01, 0x02, 0xd4, 0x2f, 0x01, 0x02, + 0xd8, 0x2f, 0x01, 0x02, 0xdc, 0x2f, 0x01, 0x02, 0xe0, 0x2f, 0x01, 0x02, 0x30, 0x12, 0x02, 0x03, 0x38, 0x12, 0x02, 0x03, 0x40, 0x12, 0x02, 0x03, 0x48, 0x12, 0x02, 0x03, 0x00, 0x39, 0x03, 0x05, + 0x00, 0x3e, 0x05, 0x08, 0x48, 0x27, 0x00, 0x02, 0x4c, 0x27, 0x00, 0x02, 0x50, 0x27, 0x00, 0x02, 0x54, 0x27, 0x00, 0x02, 0x58, 0x27, 0x00, 0x02, 0x5c, 0x27, 0x00, 0x02, 0x60, 0x27, 0x00, 0x02, + 0x64, 0x27, 0x00, 0x02, 0x68, 0x27, 0x00, 0x02, 0xe4, 0x2f, 0x01, 0x02, 0xe8, 0x2f, 0x01, 0x02, 0xec, 0x2f, 0x01, 0x02, 0xf0, 0x2f, 0x01, 0x02, 0xf4, 0x2f, 0x01, 0x02, 0xf8, 0x2f, 0x01, 0x02, + 0xfc, 0x2f, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x04, 0x30, 0x01, 0x02, 0x50, 0x12, 0x02, 0x03, 0x58, 0x12, 0x02, 0x03, 0x60, 0x12, 0x02, 0x03, 0x68, 0x12, 0x02, 0x03, 0x20, 0x39, 0x03, 0x05, + 0x00, 0x3f, 0x05, 0x08, 0x6c, 0x27, 0x00, 0x02, 0x70, 0x27, 0x00, 0x02, 0x74, 0x27, 0x00, 0x02, 0x78, 0x27, 0x00, 0x02, 0x7c, 0x27, 0x00, 0x02, 0x80, 0x27, 0x00, 0x02, 0x84, 0x27, 0x00, 0x02, + 0x88, 0x27, 0x00, 0x02, 0x08, 0x30, 0x01, 0x02, 0x0c, 0x30, 0x01, 0x02, 0x10, 0x30, 0x01, 0x02, 0x14, 0x30, 0x01, 0x02, 0x18, 0x30, 0x01, 0x02, 0x1c, 0x30, 0x01, 0x02, 0x20, 0x30, 0x01, 0x02, + 0x24, 0x30, 0x01, 0x02, 0x28, 0x30, 0x01, 0x02, 0x2c, 0x30, 0x01, 0x02, 0x70, 0x12, 0x02, 0x03, 0x78, 0x12, 0x02, 0x03, 0x80, 0x12, 0x02, 0x03, 0x88, 0x12, 0x02, 0x03, 0x40, 0x39, 0x03, 0x05, + 0x00, 0x00, 0x05, 0x07, 0x8c, 0x27, 0x00, 0x02, 0x90, 0x27, 0x00, 0x02, 0x94, 0x27, 0x00, 0x02, 0x98, 0x27, 0x00, 0x02, 0x9c, 0x27, 0x00, 0x02, 0xa0, 0x27, 0x00, 0x02, 0xa4, 0x27, 0x00, 0x02, + 0xa8, 0x27, 0x00, 0x02, 0x30, 0x30, 0x01, 0x02, 0x34, 0x30, 0x01, 0x02, 0x38, 0x30, 0x01, 0x02, 0x3c, 0x30, 0x01, 0x02, 0x40, 0x30, 0x01, 0x02, 0x44, 0x30, 0x01, 0x02, 0x48, 0x30, 0x01, 0x02, + 0x4c, 0x30, 0x01, 0x02, 0x50, 0x30, 0x01, 0x02, 0x54, 0x30, 0x01, 0x02, 0x90, 0x12, 0x02, 0x03, 0x98, 0x12, 0x02, 0x03, 0xa0, 0x12, 0x02, 0x03, 0xa8, 0x12, 0x02, 0x03, 0x60, 0x39, 0x03, 0x05, + 0x80, 0x00, 0x05, 0x07, 0xac, 0x27, 0x00, 0x02, 0xb0, 0x27, 0x00, 0x02, 0xb4, 0x27, 0x00, 0x02, 0xb8, 0x27, 0x00, 0x02, 0xbc, 0x27, 0x00, 0x02, 0xc0, 0x27, 0x00, 0x02, 0xc4, 0x27, 0x00, 0x02, + 0xc8, 0x27, 0x00, 0x02, 0x58, 0x30, 0x01, 0x02, 0x5c, 0x30, 0x01, 0x02, 0x60, 0x30, 0x01, 0x02, 0x64, 0x30, 0x01, 0x02, 0x68, 0x30, 0x01, 0x02, 0x6c, 0x30, 0x01, 0x02, 0x70, 0x30, 0x01, 0x02, + 0x74, 0x30, 0x01, 0x02, 0x78, 0x30, 0x01, 0x02, 0x7c, 0x30, 0x01, 0x02, 0xb0, 0x12, 0x02, 0x03, 0xb8, 0x12, 0x02, 0x03, 0xc0, 0x12, 0x02, 0x03, 0xc8, 0x12, 0x02, 0x03, 0x80, 0x39, 0x03, 0x05, + 0x00, 0x01, 0x05, 0x07, 0xcc, 0x27, 0x00, 0x02, 0xd0, 0x27, 0x00, 0x02, 0xd4, 0x27, 0x00, 0x02, 0xd8, 0x27, 0x00, 0x02, 0xdc, 0x27, 0x00, 0x02, 0xe0, 0x27, 0x00, 0x02, 0xe4, 0x27, 0x00, 0x02, + 0xe8, 0x27, 0x00, 0x02, 0x80, 0x30, 0x01, 0x02, 0x84, 0x30, 0x01, 0x02, 0x88, 0x30, 0x01, 0x02, 0x8c, 0x30, 0x01, 0x02, 0x90, 0x30, 0x01, 0x02, 0x94, 0x30, 0x01, 0x02, 0x98, 0x30, 0x01, 0x02, + 0x9c, 0x30, 0x01, 0x02, 0xa0, 0x30, 0x01, 0x02, 0xa4, 0x30, 0x01, 0x02, 0xd0, 0x12, 0x02, 0x03, 0xd8, 0x12, 0x02, 0x03, 0xe0, 0x12, 0x02, 0x03, 0xe8, 0x12, 0x02, 0x03, 0xa0, 0x39, 0x03, 0x05, + 0x80, 0x01, 0x05, 0x07, 0xec, 0x27, 0x00, 0x02, 0xf0, 0x27, 0x00, 0x02, 0xf4, 0x27, 0x00, 0x02, 0xf8, 0x27, 0x00, 0x02, 0xfc, 0x27, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x04, 0x28, 0x00, 0x02, + 0x08, 0x28, 0x00, 0x02, 0xa8, 0x30, 0x01, 0x02, 0xac, 0x30, 0x01, 0x02, 0xb0, 0x30, 0x01, 0x02, 0xb4, 0x30, 0x01, 0x02, 0xb8, 0x30, 0x01, 0x02, 0xbc, 0x30, 0x01, 0x02, 0xc0, 0x30, 0x01, 0x02, + 0xc4, 0x30, 0x01, 0x02, 0xc8, 0x30, 0x01, 0x02, 0xcc, 0x30, 0x01, 0x02, 0xf0, 0x12, 0x02, 0x03, 0xf8, 0x12, 0x02, 0x03, 0x00, 0x13, 0x02, 0x03, 0x08, 0x13, 0x02, 0x03, 0xc0, 0x39, 0x03, 0x05, + 0x00, 0x02, 0x05, 0x07, 0x0c, 0x28, 0x00, 0x02, 0x10, 0x28, 0x00, 0x02, 0x14, 0x28, 0x00, 0x02, 0x18, 0x28, 0x00, 0x02, 0x1c, 0x28, 0x00, 0x02, 0x20, 0x28, 0x00, 0x02, 0x24, 0x28, 0x00, 0x02, + 0x28, 0x28, 0x00, 0x02, 0xd0, 0x30, 0x01, 0x02, 0xd4, 0x30, 0x01, 0x02, 0xd8, 0x30, 0x01, 0x02, 0xdc, 0x30, 0x01, 0x02, 0xe0, 0x30, 0x01, 0x02, 0xe4, 0x30, 0x01, 0x02, 0xe8, 0x30, 0x01, 0x02, + 0xec, 0x30, 0x01, 0x02, 0xf0, 0x30, 0x01, 0x02, 0xf4, 0x30, 0x01, 0x02, 0x10, 0x13, 0x02, 0x03, 0x18, 0x13, 0x02, 0x03, 0x20, 0x13, 0x02, 0x03, 0x28, 0x13, 0x02, 0x03, 0xe0, 0x39, 0x03, 0x05, + 0x80, 0x02, 0x05, 0x07, 0x2c, 0x28, 0x00, 0x02, 0x30, 0x28, 0x00, 0x02, 0x34, 0x28, 0x00, 0x02, 0x38, 0x28, 0x00, 0x02, 0x3c, 0x28, 0x00, 0x02, 0x40, 0x28, 0x00, 0x02, 0x44, 0x28, 0x00, 0x02, + 0x48, 0x28, 0x00, 0x02, 0xf8, 0x30, 0x01, 0x02, 0xfc, 0x30, 0x01, 0x02, 0x00, 0x31, 0x01, 0x02, 0x04, 0x31, 0x01, 0x02, 0x08, 0x31, 0x01, 0x02, 0x0c, 0x31, 0x01, 0x02, 0x10, 0x31, 0x01, 0x02, + 0x14, 0x31, 0x01, 0x02, 0x18, 0x31, 0x01, 0x02, 0x1c, 0x31, 0x01, 0x02, 0x30, 0x13, 0x02, 0x03, 0x38, 0x13, 0x02, 0x03, 0x40, 0x13, 0x02, 0x03, 0x48, 0x13, 0x02, 0x03, 0x00, 0x3a, 0x03, 0x05, + 0x00, 0x18, 0x06, 0x09, 0x4c, 0x28, 0x00, 0x02, 0x50, 0x28, 0x00, 0x02, 0x54, 0x28, 0x00, 0x02, 0x58, 0x28, 0x00, 0x02, 0x5c, 0x28, 0x00, 0x02, 0x60, 0x28, 0x00, 0x02, 0x64, 0x28, 0x00, 0x02, + 0x68, 0x28, 0x00, 0x02, 0x20, 0x31, 0x01, 0x02, 0x24, 0x31, 0x01, 0x02, 0x28, 0x31, 0x01, 0x02, 0x2c, 0x31, 0x01, 0x02, 0x30, 0x31, 0x01, 0x02, 0x34, 0x31, 0x01, 0x02, 0x38, 0x31, 0x01, 0x02, + 0x3c, 0x31, 0x01, 0x02, 0x40, 0x31, 0x01, 0x02, 0x44, 0x31, 0x01, 0x02, 0x50, 0x13, 0x02, 0x03, 0x58, 0x13, 0x02, 0x03, 0x60, 0x13, 0x02, 0x03, 0x68, 0x13, 0x02, 0x03, 0x20, 0x3a, 0x03, 0x05, + 0x00, 0x1a, 0x06, 0x09, 0x6c, 0x28, 0x00, 0x02, 0x70, 0x28, 0x00, 0x02, 0x74, 0x28, 0x00, 0x02, 0x78, 0x28, 0x00, 0x02, 0x7c, 0x28, 0x00, 0x02, 0x80, 0x28, 0x00, 0x02, 0x84, 0x28, 0x00, 0x02, + 0x88, 0x28, 0x00, 0x02, 0x48, 0x31, 0x01, 0x02, 0x4c, 0x31, 0x01, 0x02, 0x50, 0x31, 0x01, 0x02, 0x54, 0x31, 0x01, 0x02, 0x58, 0x31, 0x01, 0x02, 0x5c, 0x31, 0x01, 0x02, 0x60, 0x31, 0x01, 0x02, + 0x64, 0x31, 0x01, 0x02, 0x68, 0x31, 0x01, 0x02, 0x6c, 0x31, 0x01, 0x02, 0x70, 0x13, 0x02, 0x03, 0x78, 0x13, 0x02, 0x03, 0x80, 0x13, 0x02, 0x03, 0x88, 0x13, 0x02, 0x03, 0x40, 0x3a, 0x03, 0x05, + 0x00, 0x1c, 0x06, 0x09, 0x8c, 0x28, 0x00, 0x02, 0x90, 0x28, 0x00, 0x02, 0x94, 0x28, 0x00, 0x02, 0x98, 0x28, 0x00, 0x02, 0x9c, 0x28, 0x00, 0x02, 0xa0, 0x28, 0x00, 0x02, 0xa4, 0x28, 0x00, 0x02, + 0xa8, 0x28, 0x00, 0x02, 0x70, 0x31, 0x01, 0x02, 0x74, 0x31, 0x01, 0x02, 0x78, 0x31, 0x01, 0x02, 0x7c, 0x31, 0x01, 0x02, 0x80, 0x31, 0x01, 0x02, 0x84, 0x31, 0x01, 0x02, 0x88, 0x31, 0x01, 0x02, + 0x8c, 0x31, 0x01, 0x02, 0x90, 0x31, 0x01, 0x02, 0x94, 0x31, 0x01, 0x02, 0x90, 0x13, 0x02, 0x03, 0x98, 0x13, 0x02, 0x03, 0xa0, 0x13, 0x02, 0x03, 0xa8, 0x13, 0x02, 0x03, 0x60, 0x3a, 0x03, 0x05, + 0x00, 0x1e, 0x06, 0x09, 0xac, 0x28, 0x00, 0x02, 0xb0, 0x28, 0x00, 0x02, 0xb4, 0x28, 0x00, 0x02, 0xb8, 0x28, 0x00, 0x02, 0xbc, 0x28, 0x00, 0x02, 0xc0, 0x28, 0x00, 0x02, 0xc4, 0x28, 0x00, 0x02, + 0xc8, 0x28, 0x00, 0x02, 0x98, 0x31, 0x01, 0x02, 0x9c, 0x31, 0x01, 0x02, 0xa0, 0x31, 0x01, 0x02, 0xa4, 0x31, 0x01, 0x02, 0xa8, 0x31, 0x01, 0x02, 0xac, 0x31, 0x01, 0x02, 0xb0, 0x31, 0x01, 0x02, + 0xb4, 0x31, 0x01, 0x02, 0xb8, 0x31, 0x01, 0x02, 0xbc, 0x31, 0x01, 0x02, 0xb0, 0x13, 0x02, 0x03, 0xb8, 0x13, 0x02, 0x03, 0xc0, 0x13, 0x02, 0x03, 0x80, 0x3a, 0x03, 0x05, 0xa0, 0x3a, 0x03, 0x05, + 0x00, 0x20, 0x06, 0x09, 0xcc, 0x28, 0x00, 0x02, 0xd0, 0x28, 0x00, 0x02, 0xd4, 0x28, 0x00, 0x02, 0xd8, 0x28, 0x00, 0x02, 0xdc, 0x28, 0x00, 0x02, 0xe0, 0x28, 0x00, 0x02, 0xe4, 0x28, 0x00, 0x02, + 0xe8, 0x28, 0x00, 0x02, 0xc0, 0x31, 0x01, 0x02, 0xc4, 0x31, 0x01, 0x02, 0xc8, 0x31, 0x01, 0x02, 0xcc, 0x31, 0x01, 0x02, 0xd0, 0x31, 0x01, 0x02, 0xd4, 0x31, 0x01, 0x02, 0xd8, 0x31, 0x01, 0x02, + 0xdc, 0x31, 0x01, 0x02, 0xe0, 0x31, 0x01, 0x02, 0xe4, 0x31, 0x01, 0x02, 0xc8, 0x13, 0x02, 0x03, 0xd0, 0x13, 0x02, 0x03, 0xd8, 0x13, 0x02, 0x03, 0xc0, 0x3a, 0x03, 0x05, 0xe0, 0x3a, 0x03, 0x05, + 0x00, 0x00, 0x07, 0x0a, 0xec, 0x28, 0x00, 0x02, 0xf0, 0x28, 0x00, 0x02, 0xf4, 0x28, 0x00, 0x02, 0xf8, 0x28, 0x00, 0x02, 0xfc, 0x28, 0x00, 0x02, 0x00, 0x29, 0x00, 0x02, 0x04, 0x29, 0x00, 0x02, + 0x08, 0x29, 0x00, 0x02, 0xe8, 0x31, 0x01, 0x02, 0xec, 0x31, 0x01, 0x02, 0xf0, 0x31, 0x01, 0x02, 0xf4, 0x31, 0x01, 0x02, 0xf8, 0x31, 0x01, 0x02, 0xfc, 0x31, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, + 0x04, 0x32, 0x01, 0x02, 0x08, 0x32, 0x01, 0x02, 0x0c, 0x32, 0x01, 0x02, 0xe0, 0x13, 0x02, 0x03, 0xe8, 0x13, 0x02, 0x03, 0xf0, 0x13, 0x02, 0x03, 0x00, 0x3b, 0x03, 0x05, 0x20, 0x3b, 0x03, 0x05, + 0x00, 0x04, 0x07, 0x0a, 0x0c, 0x29, 0x00, 0x02, 0x10, 0x29, 0x00, 0x02, 0x14, 0x29, 0x00, 0x02, 0x18, 0x29, 0x00, 0x02, 0x1c, 0x29, 0x00, 0x02, 0x20, 0x29, 0x00, 0x02, 0x24, 0x29, 0x00, 0x02, + 0x28, 0x29, 0x00, 0x02, 0x10, 0x32, 0x01, 0x02, 0x14, 0x32, 0x01, 0x02, 0x18, 0x32, 0x01, 0x02, 0x1c, 0x32, 0x01, 0x02, 0x20, 0x32, 0x01, 0x02, 0x24, 0x32, 0x01, 0x02, 0x28, 0x32, 0x01, 0x02, + 0x2c, 0x32, 0x01, 0x02, 0x30, 0x32, 0x01, 0x02, 0x34, 0x32, 0x01, 0x02, 0xf8, 0x13, 0x02, 0x03, 0x00, 0x14, 0x02, 0x03, 0x08, 0x14, 0x02, 0x03, 0x40, 0x3b, 0x03, 0x05, 0x60, 0x3b, 0x03, 0x05, + 0x00, 0x08, 0x07, 0x0a, 0x2c, 0x29, 0x00, 0x02, 0x30, 0x29, 0x00, 0x02, 0x34, 0x29, 0x00, 0x02, 0x38, 0x29, 0x00, 0x02, 0x3c, 0x29, 0x00, 0x02, 0x40, 0x29, 0x00, 0x02, 0x44, 0x29, 0x00, 0x02, + 0x48, 0x29, 0x00, 0x02, 0x38, 0x32, 0x01, 0x02, 0x3c, 0x32, 0x01, 0x02, 0x40, 0x32, 0x01, 0x02, 0x44, 0x32, 0x01, 0x02, 0x48, 0x32, 0x01, 0x02, 0x4c, 0x32, 0x01, 0x02, 0x50, 0x32, 0x01, 0x02, + 0x54, 0x32, 0x01, 0x02, 0x58, 0x32, 0x01, 0x02, 0x5c, 0x32, 0x01, 0x02, 0x10, 0x14, 0x02, 0x03, 0x18, 0x14, 0x02, 0x03, 0x20, 0x14, 0x02, 0x03, 0x80, 0x3b, 0x03, 0x05, 0xa0, 0x3b, 0x03, 0x05, + 0x00, 0x20, 0x08, 0x0c, 0x4c, 0x29, 0x00, 0x02, 0x50, 0x29, 0x00, 0x02, 0x54, 0x29, 0x00, 0x02, 0x58, 0x29, 0x00, 0x02, 0x5c, 0x29, 0x00, 0x02, 0x60, 0x29, 0x00, 0x02, 0x64, 0x29, 0x00, 0x02, + 0x68, 0x29, 0x00, 0x02, 0x60, 0x32, 0x01, 0x02, 0x64, 0x32, 0x01, 0x02, 0x68, 0x32, 0x01, 0x02, 0x6c, 0x32, 0x01, 0x02, 0x70, 0x32, 0x01, 0x02, 0x74, 0x32, 0x01, 0x02, 0x78, 0x32, 0x01, 0x02, + 0x7c, 0x32, 0x01, 0x02, 0x80, 0x32, 0x01, 0x02, 0x84, 0x32, 0x01, 0x02, 0x28, 0x14, 0x02, 0x03, 0x30, 0x14, 0x02, 0x03, 0x38, 0x14, 0x02, 0x03, 0xc0, 0x3b, 0x03, 0x05, 0xe0, 0x3b, 0x03, 0x05, + 0x6c, 0x29, 0x00, 0x02, 0x70, 0x29, 0x00, 0x02, 0x74, 0x29, 0x00, 0x02, 0x78, 0x29, 0x00, 0x02, 0x7c, 0x29, 0x00, 0x02, 0x80, 0x29, 0x00, 0x02, 0x84, 0x29, 0x00, 0x02, 0x88, 0x29, 0x00, 0x02, + 0x8c, 0x29, 0x00, 0x02, 0x88, 0x32, 0x01, 0x02, 0x8c, 0x32, 0x01, 0x02, 0x90, 0x32, 0x01, 0x02, 0x94, 0x32, 0x01, 0x02, 0x98, 0x32, 0x01, 0x02, 0x9c, 0x32, 0x01, 0x02, 0xa0, 0x32, 0x01, 0x02, + 0xa4, 0x32, 0x01, 0x02, 0xa8, 0x32, 0x01, 0x02, 0xac, 0x32, 0x01, 0x02, 0x40, 0x14, 0x02, 0x03, 0x48, 0x14, 0x02, 0x03, 0x50, 0x14, 0x02, 0x03, 0x00, 0x3c, 0x03, 0x05, 0x20, 0x3c, 0x03, 0x05, + 0x90, 0x29, 0x00, 0x02, 0x94, 0x29, 0x00, 0x02, 0x98, 0x29, 0x00, 0x02, 0x9c, 0x29, 0x00, 0x02, 0xa0, 0x29, 0x00, 0x02, 0xa4, 0x29, 0x00, 0x02, 0xa8, 0x29, 0x00, 0x02, 0xac, 0x29, 0x00, 0x02, + 0xb0, 0x29, 0x00, 0x02, 0xb0, 0x32, 0x01, 0x02, 0xb4, 0x32, 0x01, 0x02, 0xb8, 0x32, 0x01, 0x02, 0xbc, 0x32, 0x01, 0x02, 0xc0, 0x32, 0x01, 0x02, 0xc4, 0x32, 0x01, 0x02, 0xc8, 0x32, 0x01, 0x02, + 0xcc, 0x32, 0x01, 0x02, 0xd0, 0x32, 0x01, 0x02, 0xd4, 0x32, 0x01, 0x02, 0x58, 0x14, 0x02, 0x03, 0x60, 0x14, 0x02, 0x03, 0x68, 0x14, 0x02, 0x03, 0x40, 0x3c, 0x03, 0x05, 0x60, 0x3c, 0x03, 0x05, + 0xb4, 0x29, 0x00, 0x02, 0xb8, 0x29, 0x00, 0x02, 0xbc, 0x29, 0x00, 0x02, 0xc0, 0x29, 0x00, 0x02, 0xc4, 0x29, 0x00, 0x02, 0xc8, 0x29, 0x00, 0x02, 0xcc, 0x29, 0x00, 0x02, 0xd0, 0x29, 0x00, 0x02, + 0xd4, 0x29, 0x00, 0x02, 0xd8, 0x32, 0x01, 0x02, 0xdc, 0x32, 0x01, 0x02, 0xe0, 0x32, 0x01, 0x02, 0xe4, 0x32, 0x01, 0x02, 0xe8, 0x32, 0x01, 0x02, 0xec, 0x32, 0x01, 0x02, 0xf0, 0x32, 0x01, 0x02, + 0xf4, 0x32, 0x01, 0x02, 0xf8, 0x32, 0x01, 0x02, 0xfc, 0x32, 0x01, 0x02, 0x70, 0x14, 0x02, 0x03, 0x78, 0x14, 0x02, 0x03, 0x80, 0x14, 0x02, 0x03, 0x80, 0x3c, 0x03, 0x05, 0xa0, 0x3c, 0x03, 0x05, + 0xd8, 0x29, 0x00, 0x02, 0xdc, 0x29, 0x00, 0x02, 0xe0, 0x29, 0x00, 0x02, 0xe4, 0x29, 0x00, 0x02, 0xe8, 0x29, 0x00, 0x02, 0xec, 0x29, 0x00, 0x02, 0xf0, 0x29, 0x00, 0x02, 0xf4, 0x29, 0x00, 0x02, + 0xf8, 0x29, 0x00, 0x02, 0x00, 0x33, 0x01, 0x02, 0x04, 0x33, 0x01, 0x02, 0x08, 0x33, 0x01, 0x02, 0x0c, 0x33, 0x01, 0x02, 0x10, 0x33, 0x01, 0x02, 0x14, 0x33, 0x01, 0x02, 0x18, 0x33, 0x01, 0x02, + 0x1c, 0x33, 0x01, 0x02, 0x20, 0x33, 0x01, 0x02, 0x24, 0x33, 0x01, 0x02, 0x88, 0x14, 0x02, 0x03, 0x90, 0x14, 0x02, 0x03, 0x98, 0x14, 0x02, 0x03, 0xc0, 0x3c, 0x03, 0x05, 0xe0, 0x3c, 0x03, 0x05, + 0xfc, 0x29, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x02, 0x04, 0x2a, 0x00, 0x02, 0x08, 0x2a, 0x00, 0x02, 0x0c, 0x2a, 0x00, 0x02, 0x10, 0x2a, 0x00, 0x02, 0x14, 0x2a, 0x00, 0x02, 0x18, 0x2a, 0x00, 0x02, + 0x1c, 0x2a, 0x00, 0x02, 0x28, 0x33, 0x01, 0x02, 0x2c, 0x33, 0x01, 0x02, 0x30, 0x33, 0x01, 0x02, 0x34, 0x33, 0x01, 0x02, 0x38, 0x33, 0x01, 0x02, 0x3c, 0x33, 0x01, 0x02, 0x40, 0x33, 0x01, 0x02, + 0x44, 0x33, 0x01, 0x02, 0x48, 0x33, 0x01, 0x02, 0x4c, 0x33, 0x01, 0x02, 0xa0, 0x14, 0x02, 0x03, 0xa8, 0x14, 0x02, 0x03, 0xb0, 0x14, 0x02, 0x03, 0x00, 0x3d, 0x03, 0x05, 0x20, 0x3d, 0x03, 0x05, + 0x20, 0x2a, 0x00, 0x02, 0x24, 0x2a, 0x00, 0x02, 0x28, 0x2a, 0x00, 0x02, 0x2c, 0x2a, 0x00, 0x02, 0x30, 0x2a, 0x00, 0x02, 0x34, 0x2a, 0x00, 0x02, 0x38, 0x2a, 0x00, 0x02, 0x3c, 0x2a, 0x00, 0x02, + 0x40, 0x2a, 0x00, 0x02, 0x50, 0x33, 0x01, 0x02, 0x54, 0x33, 0x01, 0x02, 0x58, 0x33, 0x01, 0x02, 0x5c, 0x33, 0x01, 0x02, 0x60, 0x33, 0x01, 0x02, 0x64, 0x33, 0x01, 0x02, 0x68, 0x33, 0x01, 0x02, + 0x6c, 0x33, 0x01, 0x02, 0x70, 0x33, 0x01, 0x02, 0x74, 0x33, 0x01, 0x02, 0xb8, 0x14, 0x02, 0x03, 0xc0, 0x14, 0x02, 0x03, 0xc8, 0x14, 0x02, 0x03, 0x40, 0x3d, 0x03, 0x05, 0x60, 0x3d, 0x03, 0x05, + 0x44, 0x2a, 0x00, 0x02, 0x48, 0x2a, 0x00, 0x02, 0x4c, 0x2a, 0x00, 0x02, 0x50, 0x2a, 0x00, 0x02, 0x54, 0x2a, 0x00, 0x02, 0x58, 0x2a, 0x00, 0x02, 0x5c, 0x2a, 0x00, 0x02, 0x60, 0x2a, 0x00, 0x02, + 0x64, 0x2a, 0x00, 0x02, 0x78, 0x33, 0x01, 0x02, 0x7c, 0x33, 0x01, 0x02, 0x80, 0x33, 0x01, 0x02, 0x84, 0x33, 0x01, 0x02, 0x88, 0x33, 0x01, 0x02, 0x8c, 0x33, 0x01, 0x02, 0x90, 0x33, 0x01, 0x02, + 0x94, 0x33, 0x01, 0x02, 0x98, 0x33, 0x01, 0x02, 0x9c, 0x33, 0x01, 0x02, 0xd0, 0x14, 0x02, 0x03, 0xd8, 0x14, 0x02, 0x03, 0xe0, 0x14, 0x02, 0x03, 0x80, 0x3d, 0x03, 0x05, 0xa0, 0x3d, 0x03, 0x05, + 0x68, 0x2a, 0x00, 0x02, 0x6c, 0x2a, 0x00, 0x02, 0x70, 0x2a, 0x00, 0x02, 0x74, 0x2a, 0x00, 0x02, 0x78, 0x2a, 0x00, 0x02, 0x7c, 0x2a, 0x00, 0x02, 0x80, 0x2a, 0x00, 0x02, 0x84, 0x2a, 0x00, 0x02, + 0x88, 0x2a, 0x00, 0x02, 0xa0, 0x33, 0x01, 0x02, 0xa4, 0x33, 0x01, 0x02, 0xa8, 0x33, 0x01, 0x02, 0xac, 0x33, 0x01, 0x02, 0xb0, 0x33, 0x01, 0x02, 0xb4, 0x33, 0x01, 0x02, 0xb8, 0x33, 0x01, 0x02, + 0xbc, 0x33, 0x01, 0x02, 0xc0, 0x33, 0x01, 0x02, 0xc4, 0x33, 0x01, 0x02, 0xe8, 0x14, 0x02, 0x03, 0xf0, 0x14, 0x02, 0x03, 0xf8, 0x14, 0x02, 0x03, 0xc0, 0x3d, 0x03, 0x05, 0xe0, 0x3d, 0x03, 0x05, + 0x8c, 0x2a, 0x00, 0x02, 0x90, 0x2a, 0x00, 0x02, 0x94, 0x2a, 0x00, 0x02, 0x98, 0x2a, 0x00, 0x02, 0x9c, 0x2a, 0x00, 0x02, 0xa0, 0x2a, 0x00, 0x02, 0xa4, 0x2a, 0x00, 0x02, 0xa8, 0x2a, 0x00, 0x02, + 0xac, 0x2a, 0x00, 0x02, 0xc8, 0x33, 0x01, 0x02, 0xcc, 0x33, 0x01, 0x02, 0xd0, 0x33, 0x01, 0x02, 0xd4, 0x33, 0x01, 0x02, 0xd8, 0x33, 0x01, 0x02, 0xdc, 0x33, 0x01, 0x02, 0xe0, 0x33, 0x01, 0x02, + 0xe4, 0x33, 0x01, 0x02, 0xe8, 0x33, 0x01, 0x02, 0xec, 0x33, 0x01, 0x02, 0x00, 0x15, 0x02, 0x03, 0x08, 0x15, 0x02, 0x03, 0x10, 0x15, 0x02, 0x03, 0x00, 0x3e, 0x03, 0x05, 0x20, 0x3e, 0x03, 0x05, + 0xb0, 0x2a, 0x00, 0x02, 0xb4, 0x2a, 0x00, 0x02, 0xb8, 0x2a, 0x00, 0x02, 0xbc, 0x2a, 0x00, 0x02, 0xc0, 0x2a, 0x00, 0x02, 0xc4, 0x2a, 0x00, 0x02, 0xc8, 0x2a, 0x00, 0x02, 0xcc, 0x2a, 0x00, 0x02, + 0xd0, 0x2a, 0x00, 0x02, 0xf0, 0x33, 0x01, 0x02, 0xf4, 0x33, 0x01, 0x02, 0xf8, 0x33, 0x01, 0x02, 0xfc, 0x33, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x04, 0x34, 0x01, 0x02, 0x08, 0x34, 0x01, 0x02, + 0x0c, 0x34, 0x01, 0x02, 0x10, 0x34, 0x01, 0x02, 0x14, 0x34, 0x01, 0x02, 0x18, 0x15, 0x02, 0x03, 0x20, 0x15, 0x02, 0x03, 0x28, 0x15, 0x02, 0x03, 0x40, 0x3e, 0x03, 0x05, 0x60, 0x3e, 0x03, 0x05, + 0xd4, 0x2a, 0x00, 0x02, 0xd8, 0x2a, 0x00, 0x02, 0xdc, 0x2a, 0x00, 0x02, 0xe0, 0x2a, 0x00, 0x02, 0xe4, 0x2a, 0x00, 0x02, 0xe8, 0x2a, 0x00, 0x02, 0xec, 0x2a, 0x00, 0x02, 0xf0, 0x2a, 0x00, 0x02, + 0xf4, 0x2a, 0x00, 0x02, 0x18, 0x34, 0x01, 0x02, 0x1c, 0x34, 0x01, 0x02, 0x20, 0x34, 0x01, 0x02, 0x24, 0x34, 0x01, 0x02, 0x28, 0x34, 0x01, 0x02, 0x2c, 0x34, 0x01, 0x02, 0x30, 0x34, 0x01, 0x02, + 0x34, 0x34, 0x01, 0x02, 0x38, 0x34, 0x01, 0x02, 0x3c, 0x34, 0x01, 0x02, 0x30, 0x15, 0x02, 0x03, 0x38, 0x15, 0x02, 0x03, 0x40, 0x15, 0x02, 0x03, 0x80, 0x3e, 0x03, 0x05, 0xa0, 0x3e, 0x03, 0x05, + 0xf8, 0x2a, 0x00, 0x02, 0xfc, 0x2a, 0x00, 0x02, 0x00, 0x2b, 0x00, 0x02, 0x04, 0x2b, 0x00, 0x02, 0x08, 0x2b, 0x00, 0x02, 0x0c, 0x2b, 0x00, 0x02, 0x10, 0x2b, 0x00, 0x02, 0x14, 0x2b, 0x00, 0x02, + 0x18, 0x2b, 0x00, 0x02, 0x40, 0x34, 0x01, 0x02, 0x44, 0x34, 0x01, 0x02, 0x48, 0x34, 0x01, 0x02, 0x4c, 0x34, 0x01, 0x02, 0x50, 0x34, 0x01, 0x02, 0x54, 0x34, 0x01, 0x02, 0x58, 0x34, 0x01, 0x02, + 0x5c, 0x34, 0x01, 0x02, 0x60, 0x34, 0x01, 0x02, 0x64, 0x34, 0x01, 0x02, 0x48, 0x15, 0x02, 0x03, 0x50, 0x15, 0x02, 0x03, 0x58, 0x15, 0x02, 0x03, 0xc0, 0x3e, 0x03, 0x05, 0xe0, 0x3e, 0x03, 0x05, + 0x1c, 0x2b, 0x00, 0x02, 0x20, 0x2b, 0x00, 0x02, 0x24, 0x2b, 0x00, 0x02, 0x28, 0x2b, 0x00, 0x02, 0x2c, 0x2b, 0x00, 0x02, 0x30, 0x2b, 0x00, 0x02, 0x34, 0x2b, 0x00, 0x02, 0x38, 0x2b, 0x00, 0x02, + 0x3c, 0x2b, 0x00, 0x02, 0x68, 0x34, 0x01, 0x02, 0x6c, 0x34, 0x01, 0x02, 0x70, 0x34, 0x01, 0x02, 0x74, 0x34, 0x01, 0x02, 0x78, 0x34, 0x01, 0x02, 0x7c, 0x34, 0x01, 0x02, 0x80, 0x34, 0x01, 0x02, + 0x84, 0x34, 0x01, 0x02, 0x88, 0x34, 0x01, 0x02, 0x8c, 0x34, 0x01, 0x02, 0x60, 0x15, 0x02, 0x03, 0x68, 0x15, 0x02, 0x03, 0x70, 0x15, 0x02, 0x03, 0x00, 0x3f, 0x03, 0x05, 0x20, 0x3f, 0x03, 0x05, + 0x40, 0x2b, 0x00, 0x02, 0x44, 0x2b, 0x00, 0x02, 0x48, 0x2b, 0x00, 0x02, 0x4c, 0x2b, 0x00, 0x02, 0x50, 0x2b, 0x00, 0x02, 0x54, 0x2b, 0x00, 0x02, 0x58, 0x2b, 0x00, 0x02, 0x5c, 0x2b, 0x00, 0x02, + 0x60, 0x2b, 0x00, 0x02, 0x90, 0x34, 0x01, 0x02, 0x94, 0x34, 0x01, 0x02, 0x98, 0x34, 0x01, 0x02, 0x9c, 0x34, 0x01, 0x02, 0xa0, 0x34, 0x01, 0x02, 0xa4, 0x34, 0x01, 0x02, 0xa8, 0x34, 0x01, 0x02, + 0xac, 0x34, 0x01, 0x02, 0xb0, 0x34, 0x01, 0x02, 0xb4, 0x34, 0x01, 0x02, 0x78, 0x15, 0x02, 0x03, 0x80, 0x15, 0x02, 0x03, 0x88, 0x15, 0x02, 0x03, 0x40, 0x3f, 0x03, 0x05, 0x60, 0x3f, 0x03, 0x05, + 0x64, 0x2b, 0x00, 0x02, 0x68, 0x2b, 0x00, 0x02, 0x6c, 0x2b, 0x00, 0x02, 0x70, 0x2b, 0x00, 0x02, 0x74, 0x2b, 0x00, 0x02, 0x78, 0x2b, 0x00, 0x02, 0x7c, 0x2b, 0x00, 0x02, 0x80, 0x2b, 0x00, 0x02, + 0x84, 0x2b, 0x00, 0x02, 0xb8, 0x34, 0x01, 0x02, 0xbc, 0x34, 0x01, 0x02, 0xc0, 0x34, 0x01, 0x02, 0xc4, 0x34, 0x01, 0x02, 0xc8, 0x34, 0x01, 0x02, 0xcc, 0x34, 0x01, 0x02, 0xd0, 0x34, 0x01, 0x02, + 0xd4, 0x34, 0x01, 0x02, 0xd8, 0x34, 0x01, 0x02, 0xdc, 0x34, 0x01, 0x02, 0x90, 0x15, 0x02, 0x03, 0x98, 0x15, 0x02, 0x03, 0xa0, 0x15, 0x02, 0x03, 0x80, 0x3f, 0x03, 0x05, 0xa0, 0x3f, 0x03, 0x05, + 0x88, 0x2b, 0x00, 0x02, 0x8c, 0x2b, 0x00, 0x02, 0x90, 0x2b, 0x00, 0x02, 0x94, 0x2b, 0x00, 0x02, 0x98, 0x2b, 0x00, 0x02, 0x9c, 0x2b, 0x00, 0x02, 0xa0, 0x2b, 0x00, 0x02, 0xa4, 0x2b, 0x00, 0x02, + 0xa8, 0x2b, 0x00, 0x02, 0xe0, 0x34, 0x01, 0x02, 0xe4, 0x34, 0x01, 0x02, 0xe8, 0x34, 0x01, 0x02, 0xec, 0x34, 0x01, 0x02, 0xf0, 0x34, 0x01, 0x02, 0xf4, 0x34, 0x01, 0x02, 0xf8, 0x34, 0x01, 0x02, + 0xfc, 0x34, 0x01, 0x02, 0x00, 0x35, 0x01, 0x02, 0x04, 0x35, 0x01, 0x02, 0xa8, 0x15, 0x02, 0x03, 0xb0, 0x15, 0x02, 0x03, 0xb8, 0x15, 0x02, 0x03, 0xc0, 0x3f, 0x03, 0x05, 0xe0, 0x3f, 0x03, 0x05, + 0xac, 0x2b, 0x00, 0x02, 0xb0, 0x2b, 0x00, 0x02, 0xb4, 0x2b, 0x00, 0x02, 0xb8, 0x2b, 0x00, 0x02, 0xbc, 0x2b, 0x00, 0x02, 0xc0, 0x2b, 0x00, 0x02, 0xc4, 0x2b, 0x00, 0x02, 0xc8, 0x2b, 0x00, 0x02, + 0xcc, 0x2b, 0x00, 0x02, 0x08, 0x35, 0x01, 0x02, 0x0c, 0x35, 0x01, 0x02, 0x10, 0x35, 0x01, 0x02, 0x14, 0x35, 0x01, 0x02, 0x18, 0x35, 0x01, 0x02, 0x1c, 0x35, 0x01, 0x02, 0x20, 0x35, 0x01, 0x02, + 0x24, 0x35, 0x01, 0x02, 0x28, 0x35, 0x01, 0x02, 0x2c, 0x35, 0x01, 0x02, 0xc0, 0x15, 0x02, 0x03, 0xc8, 0x15, 0x02, 0x03, 0xd0, 0x15, 0x02, 0x03, 0x00, 0x00, 0x03, 0x04, 0x10, 0x00, 0x03, 0x04, + 0xd0, 0x2b, 0x00, 0x02, 0xd4, 0x2b, 0x00, 0x02, 0xd8, 0x2b, 0x00, 0x02, 0xdc, 0x2b, 0x00, 0x02, 0xe0, 0x2b, 0x00, 0x02, 0xe4, 0x2b, 0x00, 0x02, 0xe8, 0x2b, 0x00, 0x02, 0xec, 0x2b, 0x00, 0x02, + 0xf0, 0x2b, 0x00, 0x02, 0x30, 0x35, 0x01, 0x02, 0x34, 0x35, 0x01, 0x02, 0x38, 0x35, 0x01, 0x02, 0x3c, 0x35, 0x01, 0x02, 0x40, 0x35, 0x01, 0x02, 0x44, 0x35, 0x01, 0x02, 0x48, 0x35, 0x01, 0x02, + 0x4c, 0x35, 0x01, 0x02, 0x50, 0x35, 0x01, 0x02, 0x54, 0x35, 0x01, 0x02, 0xd8, 0x15, 0x02, 0x03, 0xe0, 0x15, 0x02, 0x03, 0xe8, 0x15, 0x02, 0x03, 0x20, 0x00, 0x03, 0x04, 0x30, 0x00, 0x03, 0x04, + 0xf4, 0x2b, 0x00, 0x02, 0xf8, 0x2b, 0x00, 0x02, 0xfc, 0x2b, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x02, 0x04, 0x2c, 0x00, 0x02, 0x08, 0x2c, 0x00, 0x02, 0x0c, 0x2c, 0x00, 0x02, 0x10, 0x2c, 0x00, 0x02, + 0x14, 0x2c, 0x00, 0x02, 0x58, 0x35, 0x01, 0x02, 0x5c, 0x35, 0x01, 0x02, 0x60, 0x35, 0x01, 0x02, 0x64, 0x35, 0x01, 0x02, 0x68, 0x35, 0x01, 0x02, 0x6c, 0x35, 0x01, 0x02, 0x70, 0x35, 0x01, 0x02, + 0x74, 0x35, 0x01, 0x02, 0x78, 0x35, 0x01, 0x02, 0x7c, 0x35, 0x01, 0x02, 0xf0, 0x15, 0x02, 0x03, 0xf8, 0x15, 0x02, 0x03, 0x00, 0x16, 0x02, 0x03, 0x40, 0x00, 0x03, 0x04, 0x50, 0x00, 0x03, 0x04, + 0x18, 0x2c, 0x00, 0x02, 0x1c, 0x2c, 0x00, 0x02, 0x20, 0x2c, 0x00, 0x02, 0x24, 0x2c, 0x00, 0x02, 0x28, 0x2c, 0x00, 0x02, 0x2c, 0x2c, 0x00, 0x02, 0x30, 0x2c, 0x00, 0x02, 0x34, 0x2c, 0x00, 0x02, + 0x38, 0x2c, 0x00, 0x02, 0x80, 0x35, 0x01, 0x02, 0x84, 0x35, 0x01, 0x02, 0x88, 0x35, 0x01, 0x02, 0x8c, 0x35, 0x01, 0x02, 0x90, 0x35, 0x01, 0x02, 0x94, 0x35, 0x01, 0x02, 0x98, 0x35, 0x01, 0x02, + 0x9c, 0x35, 0x01, 0x02, 0xa0, 0x35, 0x01, 0x02, 0xa4, 0x35, 0x01, 0x02, 0x08, 0x16, 0x02, 0x03, 0x10, 0x16, 0x02, 0x03, 0x18, 0x16, 0x02, 0x03, 0x60, 0x00, 0x03, 0x04, 0x70, 0x00, 0x03, 0x04, + 0x3c, 0x2c, 0x00, 0x02, 0x40, 0x2c, 0x00, 0x02, 0x44, 0x2c, 0x00, 0x02, 0x48, 0x2c, 0x00, 0x02, 0x4c, 0x2c, 0x00, 0x02, 0x50, 0x2c, 0x00, 0x02, 0x54, 0x2c, 0x00, 0x02, 0x58, 0x2c, 0x00, 0x02, + 0x5c, 0x2c, 0x00, 0x02, 0xa8, 0x35, 0x01, 0x02, 0xac, 0x35, 0x01, 0x02, 0xb0, 0x35, 0x01, 0x02, 0xb4, 0x35, 0x01, 0x02, 0xb8, 0x35, 0x01, 0x02, 0xbc, 0x35, 0x01, 0x02, 0xc0, 0x35, 0x01, 0x02, + 0xc4, 0x35, 0x01, 0x02, 0xc8, 0x35, 0x01, 0x02, 0xcc, 0x35, 0x01, 0x02, 0x20, 0x16, 0x02, 0x03, 0x28, 0x16, 0x02, 0x03, 0x30, 0x16, 0x02, 0x03, 0x80, 0x00, 0x03, 0x04, 0x40, 0x1b, 0x04, 0x06, + 0x60, 0x2c, 0x00, 0x02, 0x64, 0x2c, 0x00, 0x02, 0x68, 0x2c, 0x00, 0x02, 0x6c, 0x2c, 0x00, 0x02, 0x70, 0x2c, 0x00, 0x02, 0x74, 0x2c, 0x00, 0x02, 0x78, 0x2c, 0x00, 0x02, 0x7c, 0x2c, 0x00, 0x02, + 0x80, 0x2c, 0x00, 0x02, 0xd0, 0x35, 0x01, 0x02, 0xd4, 0x35, 0x01, 0x02, 0xd8, 0x35, 0x01, 0x02, 0xdc, 0x35, 0x01, 0x02, 0xe0, 0x35, 0x01, 0x02, 0xe4, 0x35, 0x01, 0x02, 0xe8, 0x35, 0x01, 0x02, + 0xec, 0x35, 0x01, 0x02, 0xf0, 0x35, 0x01, 0x02, 0xf4, 0x35, 0x01, 0x02, 0x38, 0x16, 0x02, 0x03, 0x40, 0x16, 0x02, 0x03, 0x48, 0x16, 0x02, 0x03, 0x90, 0x00, 0x03, 0x04, 0x80, 0x1b, 0x04, 0x06, + 0x84, 0x2c, 0x00, 0x02, 0x88, 0x2c, 0x00, 0x02, 0x8c, 0x2c, 0x00, 0x02, 0x90, 0x2c, 0x00, 0x02, 0x94, 0x2c, 0x00, 0x02, 0x98, 0x2c, 0x00, 0x02, 0x9c, 0x2c, 0x00, 0x02, 0xa0, 0x2c, 0x00, 0x02, + 0xa4, 0x2c, 0x00, 0x02, 0xf8, 0x35, 0x01, 0x02, 0xfc, 0x35, 0x01, 0x02, 0x00, 0x36, 0x01, 0x02, 0x04, 0x36, 0x01, 0x02, 0x08, 0x36, 0x01, 0x02, 0x0c, 0x36, 0x01, 0x02, 0x10, 0x36, 0x01, 0x02, + 0x14, 0x36, 0x01, 0x02, 0x18, 0x36, 0x01, 0x02, 0x1c, 0x36, 0x01, 0x02, 0x50, 0x16, 0x02, 0x03, 0x58, 0x16, 0x02, 0x03, 0x60, 0x16, 0x02, 0x03, 0xa0, 0x00, 0x03, 0x04, 0xc0, 0x1b, 0x04, 0x06, + 0xa8, 0x2c, 0x00, 0x02, 0xac, 0x2c, 0x00, 0x02, 0xb0, 0x2c, 0x00, 0x02, 0xb4, 0x2c, 0x00, 0x02, 0xb8, 0x2c, 0x00, 0x02, 0xbc, 0x2c, 0x00, 0x02, 0xc0, 0x2c, 0x00, 0x02, 0xc4, 0x2c, 0x00, 0x02, + 0xc8, 0x2c, 0x00, 0x02, 0x20, 0x36, 0x01, 0x02, 0x24, 0x36, 0x01, 0x02, 0x28, 0x36, 0x01, 0x02, 0x2c, 0x36, 0x01, 0x02, 0x30, 0x36, 0x01, 0x02, 0x34, 0x36, 0x01, 0x02, 0x38, 0x36, 0x01, 0x02, + 0x3c, 0x36, 0x01, 0x02, 0x40, 0x36, 0x01, 0x02, 0x44, 0x36, 0x01, 0x02, 0x68, 0x16, 0x02, 0x03, 0x70, 0x16, 0x02, 0x03, 0x78, 0x16, 0x02, 0x03, 0xb0, 0x00, 0x03, 0x04, 0x00, 0x1c, 0x04, 0x06, + 0xcc, 0x2c, 0x00, 0x02, 0xd0, 0x2c, 0x00, 0x02, 0xd4, 0x2c, 0x00, 0x02, 0xd8, 0x2c, 0x00, 0x02, 0xdc, 0x2c, 0x00, 0x02, 0xe0, 0x2c, 0x00, 0x02, 0xe4, 0x2c, 0x00, 0x02, 0xe8, 0x2c, 0x00, 0x02, + 0xec, 0x2c, 0x00, 0x02, 0x48, 0x36, 0x01, 0x02, 0x4c, 0x36, 0x01, 0x02, 0x50, 0x36, 0x01, 0x02, 0x54, 0x36, 0x01, 0x02, 0x58, 0x36, 0x01, 0x02, 0x5c, 0x36, 0x01, 0x02, 0x60, 0x36, 0x01, 0x02, + 0x64, 0x36, 0x01, 0x02, 0x68, 0x36, 0x01, 0x02, 0x6c, 0x36, 0x01, 0x02, 0x80, 0x16, 0x02, 0x03, 0x88, 0x16, 0x02, 0x03, 0x90, 0x16, 0x02, 0x03, 0xc0, 0x00, 0x03, 0x04, 0x40, 0x1c, 0x04, 0x06, + 0xf0, 0x2c, 0x00, 0x02, 0xf4, 0x2c, 0x00, 0x02, 0xf8, 0x2c, 0x00, 0x02, 0xfc, 0x2c, 0x00, 0x02, 0x00, 0x2d, 0x00, 0x02, 0x04, 0x2d, 0x00, 0x02, 0x08, 0x2d, 0x00, 0x02, 0x0c, 0x2d, 0x00, 0x02, + 0x10, 0x2d, 0x00, 0x02, 0x70, 0x36, 0x01, 0x02, 0x74, 0x36, 0x01, 0x02, 0x78, 0x36, 0x01, 0x02, 0x7c, 0x36, 0x01, 0x02, 0x80, 0x36, 0x01, 0x02, 0x84, 0x36, 0x01, 0x02, 0x88, 0x36, 0x01, 0x02, + 0x8c, 0x36, 0x01, 0x02, 0x90, 0x36, 0x01, 0x02, 0x94, 0x36, 0x01, 0x02, 0x98, 0x16, 0x02, 0x03, 0xa0, 0x16, 0x02, 0x03, 0xa8, 0x16, 0x02, 0x03, 0xd0, 0x00, 0x03, 0x04, 0x80, 0x1c, 0x04, 0x06, + 0x14, 0x2d, 0x00, 0x02, 0x18, 0x2d, 0x00, 0x02, 0x1c, 0x2d, 0x00, 0x02, 0x20, 0x2d, 0x00, 0x02, 0x24, 0x2d, 0x00, 0x02, 0x28, 0x2d, 0x00, 0x02, 0x2c, 0x2d, 0x00, 0x02, 0x30, 0x2d, 0x00, 0x02, + 0x34, 0x2d, 0x00, 0x02, 0x98, 0x36, 0x01, 0x02, 0x9c, 0x36, 0x01, 0x02, 0xa0, 0x36, 0x01, 0x02, 0xa4, 0x36, 0x01, 0x02, 0xa8, 0x36, 0x01, 0x02, 0xac, 0x36, 0x01, 0x02, 0xb0, 0x36, 0x01, 0x02, + 0xb4, 0x36, 0x01, 0x02, 0xb8, 0x36, 0x01, 0x02, 0xbc, 0x36, 0x01, 0x02, 0xb0, 0x16, 0x02, 0x03, 0xb8, 0x16, 0x02, 0x03, 0xc0, 0x16, 0x02, 0x03, 0xe0, 0x00, 0x03, 0x04, 0xc0, 0x1c, 0x04, 0x06, + 0x38, 0x2d, 0x00, 0x02, 0x3c, 0x2d, 0x00, 0x02, 0x40, 0x2d, 0x00, 0x02, 0x44, 0x2d, 0x00, 0x02, 0x48, 0x2d, 0x00, 0x02, 0x4c, 0x2d, 0x00, 0x02, 0x50, 0x2d, 0x00, 0x02, 0x54, 0x2d, 0x00, 0x02, + 0x58, 0x2d, 0x00, 0x02, 0xc0, 0x36, 0x01, 0x02, 0xc4, 0x36, 0x01, 0x02, 0xc8, 0x36, 0x01, 0x02, 0xcc, 0x36, 0x01, 0x02, 0xd0, 0x36, 0x01, 0x02, 0xd4, 0x36, 0x01, 0x02, 0xd8, 0x36, 0x01, 0x02, + 0xdc, 0x36, 0x01, 0x02, 0xe0, 0x36, 0x01, 0x02, 0xe4, 0x36, 0x01, 0x02, 0xc8, 0x16, 0x02, 0x03, 0xd0, 0x16, 0x02, 0x03, 0xd8, 0x16, 0x02, 0x03, 0xf0, 0x00, 0x03, 0x04, 0x00, 0x1d, 0x04, 0x06, + 0x5c, 0x2d, 0x00, 0x02, 0x60, 0x2d, 0x00, 0x02, 0x64, 0x2d, 0x00, 0x02, 0x68, 0x2d, 0x00, 0x02, 0x6c, 0x2d, 0x00, 0x02, 0x70, 0x2d, 0x00, 0x02, 0x74, 0x2d, 0x00, 0x02, 0x78, 0x2d, 0x00, 0x02, + 0x7c, 0x2d, 0x00, 0x02, 0xe8, 0x36, 0x01, 0x02, 0xec, 0x36, 0x01, 0x02, 0xf0, 0x36, 0x01, 0x02, 0xf4, 0x36, 0x01, 0x02, 0xf8, 0x36, 0x01, 0x02, 0xfc, 0x36, 0x01, 0x02, 0x00, 0x37, 0x01, 0x02, + 0x04, 0x37, 0x01, 0x02, 0x08, 0x37, 0x01, 0x02, 0x0c, 0x37, 0x01, 0x02, 0xe0, 0x16, 0x02, 0x03, 0xe8, 0x16, 0x02, 0x03, 0xf0, 0x16, 0x02, 0x03, 0x00, 0x01, 0x03, 0x04, 0x40, 0x1d, 0x04, 0x06, + 0x80, 0x2d, 0x00, 0x02, 0x84, 0x2d, 0x00, 0x02, 0x88, 0x2d, 0x00, 0x02, 0x8c, 0x2d, 0x00, 0x02, 0x90, 0x2d, 0x00, 0x02, 0x94, 0x2d, 0x00, 0x02, 0x98, 0x2d, 0x00, 0x02, 0x9c, 0x2d, 0x00, 0x02, + 0xa0, 0x2d, 0x00, 0x02, 0x10, 0x37, 0x01, 0x02, 0x14, 0x37, 0x01, 0x02, 0x18, 0x37, 0x01, 0x02, 0x1c, 0x37, 0x01, 0x02, 0x20, 0x37, 0x01, 0x02, 0x24, 0x37, 0x01, 0x02, 0x28, 0x37, 0x01, 0x02, + 0x2c, 0x37, 0x01, 0x02, 0x30, 0x37, 0x01, 0x02, 0x34, 0x37, 0x01, 0x02, 0xf8, 0x16, 0x02, 0x03, 0x00, 0x17, 0x02, 0x03, 0x08, 0x17, 0x02, 0x03, 0x10, 0x01, 0x03, 0x04, 0x80, 0x1d, 0x04, 0x06, + 0xa4, 0x2d, 0x00, 0x02, 0xa8, 0x2d, 0x00, 0x02, 0xac, 0x2d, 0x00, 0x02, 0xb0, 0x2d, 0x00, 0x02, 0xb4, 0x2d, 0x00, 0x02, 0xb8, 0x2d, 0x00, 0x02, 0xbc, 0x2d, 0x00, 0x02, 0xc0, 0x2d, 0x00, 0x02, + 0xc4, 0x2d, 0x00, 0x02, 0x38, 0x37, 0x01, 0x02, 0x3c, 0x37, 0x01, 0x02, 0x40, 0x37, 0x01, 0x02, 0x44, 0x37, 0x01, 0x02, 0x48, 0x37, 0x01, 0x02, 0x4c, 0x37, 0x01, 0x02, 0x50, 0x37, 0x01, 0x02, + 0x54, 0x37, 0x01, 0x02, 0x58, 0x37, 0x01, 0x02, 0x5c, 0x37, 0x01, 0x02, 0x10, 0x17, 0x02, 0x03, 0x18, 0x17, 0x02, 0x03, 0x20, 0x17, 0x02, 0x03, 0x20, 0x01, 0x03, 0x04, 0xc0, 0x1d, 0x04, 0x06, + 0xc8, 0x2d, 0x00, 0x02, 0xcc, 0x2d, 0x00, 0x02, 0xd0, 0x2d, 0x00, 0x02, 0xd4, 0x2d, 0x00, 0x02, 0xd8, 0x2d, 0x00, 0x02, 0xdc, 0x2d, 0x00, 0x02, 0xe0, 0x2d, 0x00, 0x02, 0xe4, 0x2d, 0x00, 0x02, + 0xe8, 0x2d, 0x00, 0x02, 0x60, 0x37, 0x01, 0x02, 0x64, 0x37, 0x01, 0x02, 0x68, 0x37, 0x01, 0x02, 0x6c, 0x37, 0x01, 0x02, 0x70, 0x37, 0x01, 0x02, 0x74, 0x37, 0x01, 0x02, 0x78, 0x37, 0x01, 0x02, + 0x7c, 0x37, 0x01, 0x02, 0x80, 0x37, 0x01, 0x02, 0x84, 0x37, 0x01, 0x02, 0x28, 0x17, 0x02, 0x03, 0x30, 0x17, 0x02, 0x03, 0x38, 0x17, 0x02, 0x03, 0x30, 0x01, 0x03, 0x04, 0x00, 0x1e, 0x04, 0x06, + 0xec, 0x2d, 0x00, 0x02, 0xf0, 0x2d, 0x00, 0x02, 0xf4, 0x2d, 0x00, 0x02, 0xf8, 0x2d, 0x00, 0x02, 0xfc, 0x2d, 0x00, 0x02, 0x00, 0x2e, 0x00, 0x02, 0x04, 0x2e, 0x00, 0x02, 0x08, 0x2e, 0x00, 0x02, + 0x0c, 0x2e, 0x00, 0x02, 0x88, 0x37, 0x01, 0x02, 0x8c, 0x37, 0x01, 0x02, 0x90, 0x37, 0x01, 0x02, 0x94, 0x37, 0x01, 0x02, 0x98, 0x37, 0x01, 0x02, 0x9c, 0x37, 0x01, 0x02, 0xa0, 0x37, 0x01, 0x02, + 0xa4, 0x37, 0x01, 0x02, 0xa8, 0x37, 0x01, 0x02, 0xac, 0x37, 0x01, 0x02, 0x40, 0x17, 0x02, 0x03, 0x48, 0x17, 0x02, 0x03, 0x50, 0x17, 0x02, 0x03, 0x40, 0x01, 0x03, 0x04, 0x40, 0x1e, 0x04, 0x06, + 0x10, 0x2e, 0x00, 0x02, 0x14, 0x2e, 0x00, 0x02, 0x18, 0x2e, 0x00, 0x02, 0x1c, 0x2e, 0x00, 0x02, 0x20, 0x2e, 0x00, 0x02, 0x24, 0x2e, 0x00, 0x02, 0x28, 0x2e, 0x00, 0x02, 0x2c, 0x2e, 0x00, 0x02, + 0x30, 0x2e, 0x00, 0x02, 0xb0, 0x37, 0x01, 0x02, 0xb4, 0x37, 0x01, 0x02, 0xb8, 0x37, 0x01, 0x02, 0xbc, 0x37, 0x01, 0x02, 0xc0, 0x37, 0x01, 0x02, 0xc4, 0x37, 0x01, 0x02, 0xc8, 0x37, 0x01, 0x02, + 0xcc, 0x37, 0x01, 0x02, 0xd0, 0x37, 0x01, 0x02, 0xd4, 0x37, 0x01, 0x02, 0x58, 0x17, 0x02, 0x03, 0x60, 0x17, 0x02, 0x03, 0x68, 0x17, 0x02, 0x03, 0x50, 0x01, 0x03, 0x04, 0x80, 0x1e, 0x04, 0x06, + 0x34, 0x2e, 0x00, 0x02, 0x38, 0x2e, 0x00, 0x02, 0x3c, 0x2e, 0x00, 0x02, 0x40, 0x2e, 0x00, 0x02, 0x44, 0x2e, 0x00, 0x02, 0x48, 0x2e, 0x00, 0x02, 0x4c, 0x2e, 0x00, 0x02, 0x50, 0x2e, 0x00, 0x02, + 0x54, 0x2e, 0x00, 0x02, 0xd8, 0x37, 0x01, 0x02, 0xdc, 0x37, 0x01, 0x02, 0xe0, 0x37, 0x01, 0x02, 0xe4, 0x37, 0x01, 0x02, 0xe8, 0x37, 0x01, 0x02, 0xec, 0x37, 0x01, 0x02, 0xf0, 0x37, 0x01, 0x02, + 0xf4, 0x37, 0x01, 0x02, 0xf8, 0x37, 0x01, 0x02, 0x70, 0x17, 0x02, 0x03, 0x78, 0x17, 0x02, 0x03, 0x80, 0x17, 0x02, 0x03, 0x88, 0x17, 0x02, 0x03, 0x60, 0x01, 0x03, 0x04, 0xc0, 0x1e, 0x04, 0x06, + 0x58, 0x2e, 0x00, 0x02, 0x5c, 0x2e, 0x00, 0x02, 0x60, 0x2e, 0x00, 0x02, 0x64, 0x2e, 0x00, 0x02, 0x68, 0x2e, 0x00, 0x02, 0x6c, 0x2e, 0x00, 0x02, 0x70, 0x2e, 0x00, 0x02, 0x74, 0x2e, 0x00, 0x02, + 0x78, 0x2e, 0x00, 0x02, 0xfc, 0x37, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0x04, 0x38, 0x01, 0x02, 0x08, 0x38, 0x01, 0x02, 0x0c, 0x38, 0x01, 0x02, 0x10, 0x38, 0x01, 0x02, 0x14, 0x38, 0x01, 0x02, + 0x18, 0x38, 0x01, 0x02, 0x1c, 0x38, 0x01, 0x02, 0x90, 0x17, 0x02, 0x03, 0x98, 0x17, 0x02, 0x03, 0xa0, 0x17, 0x02, 0x03, 0xa8, 0x17, 0x02, 0x03, 0x70, 0x01, 0x03, 0x04, 0x00, 0x1f, 0x04, 0x06, + 0x7c, 0x2e, 0x00, 0x02, 0x80, 0x2e, 0x00, 0x02, 0x84, 0x2e, 0x00, 0x02, 0x88, 0x2e, 0x00, 0x02, 0x8c, 0x2e, 0x00, 0x02, 0x90, 0x2e, 0x00, 0x02, 0x94, 0x2e, 0x00, 0x02, 0x98, 0x2e, 0x00, 0x02, + 0x9c, 0x2e, 0x00, 0x02, 0x20, 0x38, 0x01, 0x02, 0x24, 0x38, 0x01, 0x02, 0x28, 0x38, 0x01, 0x02, 0x2c, 0x38, 0x01, 0x02, 0x30, 0x38, 0x01, 0x02, 0x34, 0x38, 0x01, 0x02, 0x38, 0x38, 0x01, 0x02, + 0x3c, 0x38, 0x01, 0x02, 0x40, 0x38, 0x01, 0x02, 0xb0, 0x17, 0x02, 0x03, 0xb8, 0x17, 0x02, 0x03, 0xc0, 0x17, 0x02, 0x03, 0xc8, 0x17, 0x02, 0x03, 0x80, 0x01, 0x03, 0x04, 0x40, 0x1f, 0x04, 0x06, + 0xa0, 0x2e, 0x00, 0x02, 0xa4, 0x2e, 0x00, 0x02, 0xa8, 0x2e, 0x00, 0x02, 0xac, 0x2e, 0x00, 0x02, 0xb0, 0x2e, 0x00, 0x02, 0xb4, 0x2e, 0x00, 0x02, 0xb8, 0x2e, 0x00, 0x02, 0xbc, 0x2e, 0x00, 0x02, + 0xc0, 0x2e, 0x00, 0x02, 0x44, 0x38, 0x01, 0x02, 0x48, 0x38, 0x01, 0x02, 0x4c, 0x38, 0x01, 0x02, 0x50, 0x38, 0x01, 0x02, 0x54, 0x38, 0x01, 0x02, 0x58, 0x38, 0x01, 0x02, 0x5c, 0x38, 0x01, 0x02, + 0x60, 0x38, 0x01, 0x02, 0x64, 0x38, 0x01, 0x02, 0xd0, 0x17, 0x02, 0x03, 0xd8, 0x17, 0x02, 0x03, 0xe0, 0x17, 0x02, 0x03, 0xe8, 0x17, 0x02, 0x03, 0x90, 0x01, 0x03, 0x04, 0x80, 0x1f, 0x04, 0x06, + 0xc4, 0x2e, 0x00, 0x02, 0xc8, 0x2e, 0x00, 0x02, 0xcc, 0x2e, 0x00, 0x02, 0xd0, 0x2e, 0x00, 0x02, 0xd4, 0x2e, 0x00, 0x02, 0xd8, 0x2e, 0x00, 0x02, 0xdc, 0x2e, 0x00, 0x02, 0xe0, 0x2e, 0x00, 0x02, + 0xe4, 0x2e, 0x00, 0x02, 0x68, 0x38, 0x01, 0x02, 0x6c, 0x38, 0x01, 0x02, 0x70, 0x38, 0x01, 0x02, 0x74, 0x38, 0x01, 0x02, 0x78, 0x38, 0x01, 0x02, 0x7c, 0x38, 0x01, 0x02, 0x80, 0x38, 0x01, 0x02, + 0x84, 0x38, 0x01, 0x02, 0x88, 0x38, 0x01, 0x02, 0xf0, 0x17, 0x02, 0x03, 0xf8, 0x17, 0x02, 0x03, 0x00, 0x18, 0x02, 0x03, 0x08, 0x18, 0x02, 0x03, 0xa0, 0x01, 0x03, 0x04, 0xc0, 0x1f, 0x04, 0x06, + 0xe8, 0x2e, 0x00, 0x02, 0xec, 0x2e, 0x00, 0x02, 0xf0, 0x2e, 0x00, 0x02, 0xf4, 0x2e, 0x00, 0x02, 0xf8, 0x2e, 0x00, 0x02, 0xfc, 0x2e, 0x00, 0x02, 0x00, 0x2f, 0x00, 0x02, 0x04, 0x2f, 0x00, 0x02, + 0x08, 0x2f, 0x00, 0x02, 0x8c, 0x38, 0x01, 0x02, 0x90, 0x38, 0x01, 0x02, 0x94, 0x38, 0x01, 0x02, 0x98, 0x38, 0x01, 0x02, 0x9c, 0x38, 0x01, 0x02, 0xa0, 0x38, 0x01, 0x02, 0xa4, 0x38, 0x01, 0x02, + 0xa8, 0x38, 0x01, 0x02, 0xac, 0x38, 0x01, 0x02, 0x10, 0x18, 0x02, 0x03, 0x18, 0x18, 0x02, 0x03, 0x20, 0x18, 0x02, 0x03, 0x28, 0x18, 0x02, 0x03, 0xb0, 0x01, 0x03, 0x04, 0x00, 0x20, 0x04, 0x06, + 0x0c, 0x2f, 0x00, 0x02, 0x10, 0x2f, 0x00, 0x02, 0x14, 0x2f, 0x00, 0x02, 0x18, 0x2f, 0x00, 0x02, 0x1c, 0x2f, 0x00, 0x02, 0x20, 0x2f, 0x00, 0x02, 0x24, 0x2f, 0x00, 0x02, 0x28, 0x2f, 0x00, 0x02, + 0x2c, 0x2f, 0x00, 0x02, 0xb0, 0x38, 0x01, 0x02, 0xb4, 0x38, 0x01, 0x02, 0xb8, 0x38, 0x01, 0x02, 0xbc, 0x38, 0x01, 0x02, 0xc0, 0x38, 0x01, 0x02, 0xc4, 0x38, 0x01, 0x02, 0xc8, 0x38, 0x01, 0x02, + 0xcc, 0x38, 0x01, 0x02, 0xd0, 0x38, 0x01, 0x02, 0x30, 0x18, 0x02, 0x03, 0x38, 0x18, 0x02, 0x03, 0x40, 0x18, 0x02, 0x03, 0x48, 0x18, 0x02, 0x03, 0xc0, 0x01, 0x03, 0x04, 0x40, 0x20, 0x04, 0x06, + 0x30, 0x2f, 0x00, 0x02, 0x34, 0x2f, 0x00, 0x02, 0x38, 0x2f, 0x00, 0x02, 0x3c, 0x2f, 0x00, 0x02, 0x40, 0x2f, 0x00, 0x02, 0x44, 0x2f, 0x00, 0x02, 0x48, 0x2f, 0x00, 0x02, 0x4c, 0x2f, 0x00, 0x02, + 0x50, 0x2f, 0x00, 0x02, 0xd4, 0x38, 0x01, 0x02, 0xd8, 0x38, 0x01, 0x02, 0xdc, 0x38, 0x01, 0x02, 0xe0, 0x38, 0x01, 0x02, 0xe4, 0x38, 0x01, 0x02, 0xe8, 0x38, 0x01, 0x02, 0xec, 0x38, 0x01, 0x02, + 0xf0, 0x38, 0x01, 0x02, 0xf4, 0x38, 0x01, 0x02, 0x50, 0x18, 0x02, 0x03, 0x58, 0x18, 0x02, 0x03, 0x60, 0x18, 0x02, 0x03, 0x68, 0x18, 0x02, 0x03, 0xd0, 0x01, 0x03, 0x04, 0x80, 0x20, 0x04, 0x06, + 0x54, 0x2f, 0x00, 0x02, 0x58, 0x2f, 0x00, 0x02, 0x5c, 0x2f, 0x00, 0x02, 0x60, 0x2f, 0x00, 0x02, 0x64, 0x2f, 0x00, 0x02, 0x68, 0x2f, 0x00, 0x02, 0x6c, 0x2f, 0x00, 0x02, 0x70, 0x2f, 0x00, 0x02, + 0x74, 0x2f, 0x00, 0x02, 0xf8, 0x38, 0x01, 0x02, 0xfc, 0x38, 0x01, 0x02, 0x00, 0x39, 0x01, 0x02, 0x04, 0x39, 0x01, 0x02, 0x08, 0x39, 0x01, 0x02, 0x0c, 0x39, 0x01, 0x02, 0x10, 0x39, 0x01, 0x02, + 0x14, 0x39, 0x01, 0x02, 0x18, 0x39, 0x01, 0x02, 0x70, 0x18, 0x02, 0x03, 0x78, 0x18, 0x02, 0x03, 0x80, 0x18, 0x02, 0x03, 0x88, 0x18, 0x02, 0x03, 0xe0, 0x01, 0x03, 0x04, 0xc0, 0x20, 0x04, 0x06, + 0x78, 0x2f, 0x00, 0x02, 0x7c, 0x2f, 0x00, 0x02, 0x80, 0x2f, 0x00, 0x02, 0x84, 0x2f, 0x00, 0x02, 0x88, 0x2f, 0x00, 0x02, 0x8c, 0x2f, 0x00, 0x02, 0x90, 0x2f, 0x00, 0x02, 0x94, 0x2f, 0x00, 0x02, + 0x98, 0x2f, 0x00, 0x02, 0x1c, 0x39, 0x01, 0x02, 0x20, 0x39, 0x01, 0x02, 0x24, 0x39, 0x01, 0x02, 0x28, 0x39, 0x01, 0x02, 0x2c, 0x39, 0x01, 0x02, 0x30, 0x39, 0x01, 0x02, 0x34, 0x39, 0x01, 0x02, + 0x38, 0x39, 0x01, 0x02, 0x3c, 0x39, 0x01, 0x02, 0x90, 0x18, 0x02, 0x03, 0x98, 0x18, 0x02, 0x03, 0xa0, 0x18, 0x02, 0x03, 0xa8, 0x18, 0x02, 0x03, 0xf0, 0x01, 0x03, 0x04, 0x00, 0x21, 0x04, 0x06, + 0x9c, 0x2f, 0x00, 0x02, 0xa0, 0x2f, 0x00, 0x02, 0xa4, 0x2f, 0x00, 0x02, 0xa8, 0x2f, 0x00, 0x02, 0xac, 0x2f, 0x00, 0x02, 0xb0, 0x2f, 0x00, 0x02, 0xb4, 0x2f, 0x00, 0x02, 0xb8, 0x2f, 0x00, 0x02, + 0xbc, 0x2f, 0x00, 0x02, 0x40, 0x39, 0x01, 0x02, 0x44, 0x39, 0x01, 0x02, 0x48, 0x39, 0x01, 0x02, 0x4c, 0x39, 0x01, 0x02, 0x50, 0x39, 0x01, 0x02, 0x54, 0x39, 0x01, 0x02, 0x58, 0x39, 0x01, 0x02, + 0x5c, 0x39, 0x01, 0x02, 0x60, 0x39, 0x01, 0x02, 0xb0, 0x18, 0x02, 0x03, 0xb8, 0x18, 0x02, 0x03, 0xc0, 0x18, 0x02, 0x03, 0xc8, 0x18, 0x02, 0x03, 0x00, 0x02, 0x03, 0x04, 0x40, 0x21, 0x04, 0x06, + 0xc0, 0x2f, 0x00, 0x02, 0xc4, 0x2f, 0x00, 0x02, 0xc8, 0x2f, 0x00, 0x02, 0xcc, 0x2f, 0x00, 0x02, 0xd0, 0x2f, 0x00, 0x02, 0xd4, 0x2f, 0x00, 0x02, 0xd8, 0x2f, 0x00, 0x02, 0xdc, 0x2f, 0x00, 0x02, + 0xe0, 0x2f, 0x00, 0x02, 0x64, 0x39, 0x01, 0x02, 0x68, 0x39, 0x01, 0x02, 0x6c, 0x39, 0x01, 0x02, 0x70, 0x39, 0x01, 0x02, 0x74, 0x39, 0x01, 0x02, 0x78, 0x39, 0x01, 0x02, 0x7c, 0x39, 0x01, 0x02, + 0x80, 0x39, 0x01, 0x02, 0x84, 0x39, 0x01, 0x02, 0xd0, 0x18, 0x02, 0x03, 0xd8, 0x18, 0x02, 0x03, 0xe0, 0x18, 0x02, 0x03, 0xe8, 0x18, 0x02, 0x03, 0x10, 0x02, 0x03, 0x04, 0x80, 0x21, 0x04, 0x06, + 0xe4, 0x2f, 0x00, 0x02, 0xe8, 0x2f, 0x00, 0x02, 0xec, 0x2f, 0x00, 0x02, 0xf0, 0x2f, 0x00, 0x02, 0xf4, 0x2f, 0x00, 0x02, 0xf8, 0x2f, 0x00, 0x02, 0xfc, 0x2f, 0x00, 0x02, 0x00, 0x30, 0x00, 0x02, + 0x04, 0x30, 0x00, 0x02, 0x88, 0x39, 0x01, 0x02, 0x8c, 0x39, 0x01, 0x02, 0x90, 0x39, 0x01, 0x02, 0x94, 0x39, 0x01, 0x02, 0x98, 0x39, 0x01, 0x02, 0x9c, 0x39, 0x01, 0x02, 0xa0, 0x39, 0x01, 0x02, + 0xa4, 0x39, 0x01, 0x02, 0xa8, 0x39, 0x01, 0x02, 0xf0, 0x18, 0x02, 0x03, 0xf8, 0x18, 0x02, 0x03, 0x00, 0x19, 0x02, 0x03, 0x08, 0x19, 0x02, 0x03, 0x20, 0x02, 0x03, 0x04, 0xc0, 0x21, 0x04, 0x06, + 0x08, 0x30, 0x00, 0x02, 0x0c, 0x30, 0x00, 0x02, 0x10, 0x30, 0x00, 0x02, 0x14, 0x30, 0x00, 0x02, 0x18, 0x30, 0x00, 0x02, 0x1c, 0x30, 0x00, 0x02, 0x20, 0x30, 0x00, 0x02, 0x24, 0x30, 0x00, 0x02, + 0x28, 0x30, 0x00, 0x02, 0xac, 0x39, 0x01, 0x02, 0xb0, 0x39, 0x01, 0x02, 0xb4, 0x39, 0x01, 0x02, 0xb8, 0x39, 0x01, 0x02, 0xbc, 0x39, 0x01, 0x02, 0xc0, 0x39, 0x01, 0x02, 0xc4, 0x39, 0x01, 0x02, + 0xc8, 0x39, 0x01, 0x02, 0xcc, 0x39, 0x01, 0x02, 0x10, 0x19, 0x02, 0x03, 0x18, 0x19, 0x02, 0x03, 0x20, 0x19, 0x02, 0x03, 0x28, 0x19, 0x02, 0x03, 0x30, 0x02, 0x03, 0x04, 0x00, 0x22, 0x04, 0x06, + 0x2c, 0x30, 0x00, 0x02, 0x30, 0x30, 0x00, 0x02, 0x34, 0x30, 0x00, 0x02, 0x38, 0x30, 0x00, 0x02, 0x3c, 0x30, 0x00, 0x02, 0x40, 0x30, 0x00, 0x02, 0x44, 0x30, 0x00, 0x02, 0x48, 0x30, 0x00, 0x02, + 0x4c, 0x30, 0x00, 0x02, 0xd0, 0x39, 0x01, 0x02, 0xd4, 0x39, 0x01, 0x02, 0xd8, 0x39, 0x01, 0x02, 0xdc, 0x39, 0x01, 0x02, 0xe0, 0x39, 0x01, 0x02, 0xe4, 0x39, 0x01, 0x02, 0xe8, 0x39, 0x01, 0x02, + 0xec, 0x39, 0x01, 0x02, 0xf0, 0x39, 0x01, 0x02, 0x30, 0x19, 0x02, 0x03, 0x38, 0x19, 0x02, 0x03, 0x40, 0x19, 0x02, 0x03, 0x48, 0x19, 0x02, 0x03, 0x40, 0x02, 0x03, 0x04, 0x40, 0x22, 0x04, 0x06, + 0x50, 0x30, 0x00, 0x02, 0x54, 0x30, 0x00, 0x02, 0x58, 0x30, 0x00, 0x02, 0x5c, 0x30, 0x00, 0x02, 0x60, 0x30, 0x00, 0x02, 0x64, 0x30, 0x00, 0x02, 0x68, 0x30, 0x00, 0x02, 0x6c, 0x30, 0x00, 0x02, + 0x70, 0x30, 0x00, 0x02, 0xf4, 0x39, 0x01, 0x02, 0xf8, 0x39, 0x01, 0x02, 0xfc, 0x39, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x04, 0x3a, 0x01, 0x02, 0x08, 0x3a, 0x01, 0x02, 0x0c, 0x3a, 0x01, 0x02, + 0x10, 0x3a, 0x01, 0x02, 0x14, 0x3a, 0x01, 0x02, 0x50, 0x19, 0x02, 0x03, 0x58, 0x19, 0x02, 0x03, 0x60, 0x19, 0x02, 0x03, 0x68, 0x19, 0x02, 0x03, 0x50, 0x02, 0x03, 0x04, 0x80, 0x22, 0x04, 0x06, + 0x74, 0x30, 0x00, 0x02, 0x78, 0x30, 0x00, 0x02, 0x7c, 0x30, 0x00, 0x02, 0x80, 0x30, 0x00, 0x02, 0x84, 0x30, 0x00, 0x02, 0x88, 0x30, 0x00, 0x02, 0x8c, 0x30, 0x00, 0x02, 0x90, 0x30, 0x00, 0x02, + 0x94, 0x30, 0x00, 0x02, 0x18, 0x3a, 0x01, 0x02, 0x1c, 0x3a, 0x01, 0x02, 0x20, 0x3a, 0x01, 0x02, 0x24, 0x3a, 0x01, 0x02, 0x28, 0x3a, 0x01, 0x02, 0x2c, 0x3a, 0x01, 0x02, 0x30, 0x3a, 0x01, 0x02, + 0x34, 0x3a, 0x01, 0x02, 0x38, 0x3a, 0x01, 0x02, 0x70, 0x19, 0x02, 0x03, 0x78, 0x19, 0x02, 0x03, 0x80, 0x19, 0x02, 0x03, 0x88, 0x19, 0x02, 0x03, 0x60, 0x02, 0x03, 0x04, 0xc0, 0x22, 0x04, 0x06, + 0x98, 0x30, 0x00, 0x02, 0x9c, 0x30, 0x00, 0x02, 0xa0, 0x30, 0x00, 0x02, 0xa4, 0x30, 0x00, 0x02, 0xa8, 0x30, 0x00, 0x02, 0xac, 0x30, 0x00, 0x02, 0xb0, 0x30, 0x00, 0x02, 0xb4, 0x30, 0x00, 0x02, + 0xb8, 0x30, 0x00, 0x02, 0x3c, 0x3a, 0x01, 0x02, 0x40, 0x3a, 0x01, 0x02, 0x44, 0x3a, 0x01, 0x02, 0x48, 0x3a, 0x01, 0x02, 0x4c, 0x3a, 0x01, 0x02, 0x50, 0x3a, 0x01, 0x02, 0x54, 0x3a, 0x01, 0x02, + 0x58, 0x3a, 0x01, 0x02, 0x5c, 0x3a, 0x01, 0x02, 0x90, 0x19, 0x02, 0x03, 0x98, 0x19, 0x02, 0x03, 0xa0, 0x19, 0x02, 0x03, 0xa8, 0x19, 0x02, 0x03, 0x70, 0x02, 0x03, 0x04, 0x00, 0x23, 0x04, 0x06, + 0xbc, 0x30, 0x00, 0x02, 0xc0, 0x30, 0x00, 0x02, 0xc4, 0x30, 0x00, 0x02, 0xc8, 0x30, 0x00, 0x02, 0xcc, 0x30, 0x00, 0x02, 0xd0, 0x30, 0x00, 0x02, 0xd4, 0x30, 0x00, 0x02, 0xd8, 0x30, 0x00, 0x02, + 0xdc, 0x30, 0x00, 0x02, 0x60, 0x3a, 0x01, 0x02, 0x64, 0x3a, 0x01, 0x02, 0x68, 0x3a, 0x01, 0x02, 0x6c, 0x3a, 0x01, 0x02, 0x70, 0x3a, 0x01, 0x02, 0x74, 0x3a, 0x01, 0x02, 0x78, 0x3a, 0x01, 0x02, + 0x7c, 0x3a, 0x01, 0x02, 0x80, 0x3a, 0x01, 0x02, 0xb0, 0x19, 0x02, 0x03, 0xb8, 0x19, 0x02, 0x03, 0xc0, 0x19, 0x02, 0x03, 0xc8, 0x19, 0x02, 0x03, 0x80, 0x02, 0x03, 0x04, 0x40, 0x23, 0x04, 0x06, + 0xe0, 0x30, 0x00, 0x02, 0xe4, 0x30, 0x00, 0x02, 0xe8, 0x30, 0x00, 0x02, 0xec, 0x30, 0x00, 0x02, 0xf0, 0x30, 0x00, 0x02, 0xf4, 0x30, 0x00, 0x02, 0xf8, 0x30, 0x00, 0x02, 0xfc, 0x30, 0x00, 0x02, + 0x00, 0x31, 0x00, 0x02, 0x84, 0x3a, 0x01, 0x02, 0x88, 0x3a, 0x01, 0x02, 0x8c, 0x3a, 0x01, 0x02, 0x90, 0x3a, 0x01, 0x02, 0x94, 0x3a, 0x01, 0x02, 0x98, 0x3a, 0x01, 0x02, 0x9c, 0x3a, 0x01, 0x02, + 0xa0, 0x3a, 0x01, 0x02, 0xa4, 0x3a, 0x01, 0x02, 0xd0, 0x19, 0x02, 0x03, 0xd8, 0x19, 0x02, 0x03, 0xe0, 0x19, 0x02, 0x03, 0xe8, 0x19, 0x02, 0x03, 0x90, 0x02, 0x03, 0x04, 0x80, 0x23, 0x04, 0x06, + 0x04, 0x31, 0x00, 0x02, 0x08, 0x31, 0x00, 0x02, 0x0c, 0x31, 0x00, 0x02, 0x10, 0x31, 0x00, 0x02, 0x14, 0x31, 0x00, 0x02, 0x18, 0x31, 0x00, 0x02, 0x1c, 0x31, 0x00, 0x02, 0x20, 0x31, 0x00, 0x02, + 0x24, 0x31, 0x00, 0x02, 0xa8, 0x3a, 0x01, 0x02, 0xac, 0x3a, 0x01, 0x02, 0xb0, 0x3a, 0x01, 0x02, 0xb4, 0x3a, 0x01, 0x02, 0xb8, 0x3a, 0x01, 0x02, 0xbc, 0x3a, 0x01, 0x02, 0xc0, 0x3a, 0x01, 0x02, + 0xc4, 0x3a, 0x01, 0x02, 0xc8, 0x3a, 0x01, 0x02, 0xf0, 0x19, 0x02, 0x03, 0xf8, 0x19, 0x02, 0x03, 0x00, 0x1a, 0x02, 0x03, 0x08, 0x1a, 0x02, 0x03, 0xa0, 0x02, 0x03, 0x04, 0xc0, 0x23, 0x04, 0x06, + 0x28, 0x31, 0x00, 0x02, 0x2c, 0x31, 0x00, 0x02, 0x30, 0x31, 0x00, 0x02, 0x34, 0x31, 0x00, 0x02, 0x38, 0x31, 0x00, 0x02, 0x3c, 0x31, 0x00, 0x02, 0x40, 0x31, 0x00, 0x02, 0x44, 0x31, 0x00, 0x02, + 0x48, 0x31, 0x00, 0x02, 0xcc, 0x3a, 0x01, 0x02, 0xd0, 0x3a, 0x01, 0x02, 0xd4, 0x3a, 0x01, 0x02, 0xd8, 0x3a, 0x01, 0x02, 0xdc, 0x3a, 0x01, 0x02, 0xe0, 0x3a, 0x01, 0x02, 0xe4, 0x3a, 0x01, 0x02, + 0xe8, 0x3a, 0x01, 0x02, 0xec, 0x3a, 0x01, 0x02, 0x10, 0x1a, 0x02, 0x03, 0x18, 0x1a, 0x02, 0x03, 0x20, 0x1a, 0x02, 0x03, 0x28, 0x1a, 0x02, 0x03, 0xb0, 0x02, 0x03, 0x04, 0x00, 0x24, 0x04, 0x06, + 0x4c, 0x31, 0x00, 0x02, 0x50, 0x31, 0x00, 0x02, 0x54, 0x31, 0x00, 0x02, 0x58, 0x31, 0x00, 0x02, 0x5c, 0x31, 0x00, 0x02, 0x60, 0x31, 0x00, 0x02, 0x64, 0x31, 0x00, 0x02, 0x68, 0x31, 0x00, 0x02, + 0x6c, 0x31, 0x00, 0x02, 0xf0, 0x3a, 0x01, 0x02, 0xf4, 0x3a, 0x01, 0x02, 0xf8, 0x3a, 0x01, 0x02, 0xfc, 0x3a, 0x01, 0x02, 0x00, 0x3b, 0x01, 0x02, 0x04, 0x3b, 0x01, 0x02, 0x08, 0x3b, 0x01, 0x02, + 0x0c, 0x3b, 0x01, 0x02, 0x10, 0x3b, 0x01, 0x02, 0x30, 0x1a, 0x02, 0x03, 0x38, 0x1a, 0x02, 0x03, 0x40, 0x1a, 0x02, 0x03, 0x48, 0x1a, 0x02, 0x03, 0xc0, 0x02, 0x03, 0x04, 0x40, 0x24, 0x04, 0x06, + 0x70, 0x31, 0x00, 0x02, 0x74, 0x31, 0x00, 0x02, 0x78, 0x31, 0x00, 0x02, 0x7c, 0x31, 0x00, 0x02, 0x80, 0x31, 0x00, 0x02, 0x84, 0x31, 0x00, 0x02, 0x88, 0x31, 0x00, 0x02, 0x8c, 0x31, 0x00, 0x02, + 0x90, 0x31, 0x00, 0x02, 0x14, 0x3b, 0x01, 0x02, 0x18, 0x3b, 0x01, 0x02, 0x1c, 0x3b, 0x01, 0x02, 0x20, 0x3b, 0x01, 0x02, 0x24, 0x3b, 0x01, 0x02, 0x28, 0x3b, 0x01, 0x02, 0x2c, 0x3b, 0x01, 0x02, + 0x30, 0x3b, 0x01, 0x02, 0x34, 0x3b, 0x01, 0x02, 0x50, 0x1a, 0x02, 0x03, 0x58, 0x1a, 0x02, 0x03, 0x60, 0x1a, 0x02, 0x03, 0x68, 0x1a, 0x02, 0x03, 0xd0, 0x02, 0x03, 0x04, 0x80, 0x24, 0x04, 0x06, + 0x94, 0x31, 0x00, 0x02, 0x98, 0x31, 0x00, 0x02, 0x9c, 0x31, 0x00, 0x02, 0xa0, 0x31, 0x00, 0x02, 0xa4, 0x31, 0x00, 0x02, 0xa8, 0x31, 0x00, 0x02, 0xac, 0x31, 0x00, 0x02, 0xb0, 0x31, 0x00, 0x02, + 0xb4, 0x31, 0x00, 0x02, 0x38, 0x3b, 0x01, 0x02, 0x3c, 0x3b, 0x01, 0x02, 0x40, 0x3b, 0x01, 0x02, 0x44, 0x3b, 0x01, 0x02, 0x48, 0x3b, 0x01, 0x02, 0x4c, 0x3b, 0x01, 0x02, 0x50, 0x3b, 0x01, 0x02, + 0x54, 0x3b, 0x01, 0x02, 0x58, 0x3b, 0x01, 0x02, 0x70, 0x1a, 0x02, 0x03, 0x78, 0x1a, 0x02, 0x03, 0x80, 0x1a, 0x02, 0x03, 0x88, 0x1a, 0x02, 0x03, 0xe0, 0x02, 0x03, 0x04, 0xc0, 0x24, 0x04, 0x06, + 0xb8, 0x31, 0x00, 0x02, 0xbc, 0x31, 0x00, 0x02, 0xc0, 0x31, 0x00, 0x02, 0xc4, 0x31, 0x00, 0x02, 0xc8, 0x31, 0x00, 0x02, 0xcc, 0x31, 0x00, 0x02, 0xd0, 0x31, 0x00, 0x02, 0xd4, 0x31, 0x00, 0x02, + 0xd8, 0x31, 0x00, 0x02, 0x5c, 0x3b, 0x01, 0x02, 0x60, 0x3b, 0x01, 0x02, 0x64, 0x3b, 0x01, 0x02, 0x68, 0x3b, 0x01, 0x02, 0x6c, 0x3b, 0x01, 0x02, 0x70, 0x3b, 0x01, 0x02, 0x74, 0x3b, 0x01, 0x02, + 0x78, 0x3b, 0x01, 0x02, 0x7c, 0x3b, 0x01, 0x02, 0x90, 0x1a, 0x02, 0x03, 0x98, 0x1a, 0x02, 0x03, 0xa0, 0x1a, 0x02, 0x03, 0xa8, 0x1a, 0x02, 0x03, 0xf0, 0x02, 0x03, 0x04, 0x00, 0x25, 0x04, 0x06, + 0xdc, 0x31, 0x00, 0x02, 0xe0, 0x31, 0x00, 0x02, 0xe4, 0x31, 0x00, 0x02, 0xe8, 0x31, 0x00, 0x02, 0xec, 0x31, 0x00, 0x02, 0xf0, 0x31, 0x00, 0x02, 0xf4, 0x31, 0x00, 0x02, 0xf8, 0x31, 0x00, 0x02, + 0xfc, 0x31, 0x00, 0x02, 0x80, 0x3b, 0x01, 0x02, 0x84, 0x3b, 0x01, 0x02, 0x88, 0x3b, 0x01, 0x02, 0x8c, 0x3b, 0x01, 0x02, 0x90, 0x3b, 0x01, 0x02, 0x94, 0x3b, 0x01, 0x02, 0x98, 0x3b, 0x01, 0x02, + 0x9c, 0x3b, 0x01, 0x02, 0xa0, 0x3b, 0x01, 0x02, 0xb0, 0x1a, 0x02, 0x03, 0xb8, 0x1a, 0x02, 0x03, 0xc0, 0x1a, 0x02, 0x03, 0xc8, 0x1a, 0x02, 0x03, 0x00, 0x03, 0x03, 0x04, 0x00, 0x03, 0x05, 0x07, + 0x00, 0x32, 0x00, 0x02, 0x04, 0x32, 0x00, 0x02, 0x08, 0x32, 0x00, 0x02, 0x0c, 0x32, 0x00, 0x02, 0x10, 0x32, 0x00, 0x02, 0x14, 0x32, 0x00, 0x02, 0x18, 0x32, 0x00, 0x02, 0x1c, 0x32, 0x00, 0x02, + 0x20, 0x32, 0x00, 0x02, 0xa4, 0x3b, 0x01, 0x02, 0xa8, 0x3b, 0x01, 0x02, 0xac, 0x3b, 0x01, 0x02, 0xb0, 0x3b, 0x01, 0x02, 0xb4, 0x3b, 0x01, 0x02, 0xb8, 0x3b, 0x01, 0x02, 0xbc, 0x3b, 0x01, 0x02, + 0xc0, 0x3b, 0x01, 0x02, 0xc4, 0x3b, 0x01, 0x02, 0xd0, 0x1a, 0x02, 0x03, 0xd8, 0x1a, 0x02, 0x03, 0xe0, 0x1a, 0x02, 0x03, 0xe8, 0x1a, 0x02, 0x03, 0x10, 0x03, 0x03, 0x04, 0x80, 0x03, 0x05, 0x07, + 0x24, 0x32, 0x00, 0x02, 0x28, 0x32, 0x00, 0x02, 0x2c, 0x32, 0x00, 0x02, 0x30, 0x32, 0x00, 0x02, 0x34, 0x32, 0x00, 0x02, 0x38, 0x32, 0x00, 0x02, 0x3c, 0x32, 0x00, 0x02, 0x40, 0x32, 0x00, 0x02, + 0x44, 0x32, 0x00, 0x02, 0xc8, 0x3b, 0x01, 0x02, 0xcc, 0x3b, 0x01, 0x02, 0xd0, 0x3b, 0x01, 0x02, 0xd4, 0x3b, 0x01, 0x02, 0xd8, 0x3b, 0x01, 0x02, 0xdc, 0x3b, 0x01, 0x02, 0xe0, 0x3b, 0x01, 0x02, + 0xe4, 0x3b, 0x01, 0x02, 0xe8, 0x3b, 0x01, 0x02, 0xf0, 0x1a, 0x02, 0x03, 0xf8, 0x1a, 0x02, 0x03, 0x00, 0x1b, 0x02, 0x03, 0x08, 0x1b, 0x02, 0x03, 0x20, 0x03, 0x03, 0x04, 0x00, 0x04, 0x05, 0x07, + 0x48, 0x32, 0x00, 0x02, 0x4c, 0x32, 0x00, 0x02, 0x50, 0x32, 0x00, 0x02, 0x54, 0x32, 0x00, 0x02, 0x58, 0x32, 0x00, 0x02, 0x5c, 0x32, 0x00, 0x02, 0x60, 0x32, 0x00, 0x02, 0x64, 0x32, 0x00, 0x02, + 0x68, 0x32, 0x00, 0x02, 0xec, 0x3b, 0x01, 0x02, 0xf0, 0x3b, 0x01, 0x02, 0xf4, 0x3b, 0x01, 0x02, 0xf8, 0x3b, 0x01, 0x02, 0xfc, 0x3b, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x04, 0x3c, 0x01, 0x02, + 0x08, 0x3c, 0x01, 0x02, 0x0c, 0x3c, 0x01, 0x02, 0x10, 0x1b, 0x02, 0x03, 0x18, 0x1b, 0x02, 0x03, 0x20, 0x1b, 0x02, 0x03, 0x28, 0x1b, 0x02, 0x03, 0x30, 0x03, 0x03, 0x04, 0x80, 0x04, 0x05, 0x07, + 0x6c, 0x32, 0x00, 0x02, 0x70, 0x32, 0x00, 0x02, 0x74, 0x32, 0x00, 0x02, 0x78, 0x32, 0x00, 0x02, 0x7c, 0x32, 0x00, 0x02, 0x80, 0x32, 0x00, 0x02, 0x84, 0x32, 0x00, 0x02, 0x88, 0x32, 0x00, 0x02, + 0x8c, 0x32, 0x00, 0x02, 0x10, 0x3c, 0x01, 0x02, 0x14, 0x3c, 0x01, 0x02, 0x18, 0x3c, 0x01, 0x02, 0x1c, 0x3c, 0x01, 0x02, 0x20, 0x3c, 0x01, 0x02, 0x24, 0x3c, 0x01, 0x02, 0x28, 0x3c, 0x01, 0x02, + 0x2c, 0x3c, 0x01, 0x02, 0x30, 0x3c, 0x01, 0x02, 0x30, 0x1b, 0x02, 0x03, 0x38, 0x1b, 0x02, 0x03, 0x40, 0x1b, 0x02, 0x03, 0x48, 0x1b, 0x02, 0x03, 0x40, 0x03, 0x03, 0x04, 0x00, 0x05, 0x05, 0x07, + 0x90, 0x32, 0x00, 0x02, 0x94, 0x32, 0x00, 0x02, 0x98, 0x32, 0x00, 0x02, 0x9c, 0x32, 0x00, 0x02, 0xa0, 0x32, 0x00, 0x02, 0xa4, 0x32, 0x00, 0x02, 0xa8, 0x32, 0x00, 0x02, 0xac, 0x32, 0x00, 0x02, + 0xb0, 0x32, 0x00, 0x02, 0x34, 0x3c, 0x01, 0x02, 0x38, 0x3c, 0x01, 0x02, 0x3c, 0x3c, 0x01, 0x02, 0x40, 0x3c, 0x01, 0x02, 0x44, 0x3c, 0x01, 0x02, 0x48, 0x3c, 0x01, 0x02, 0x4c, 0x3c, 0x01, 0x02, + 0x50, 0x3c, 0x01, 0x02, 0x54, 0x3c, 0x01, 0x02, 0x50, 0x1b, 0x02, 0x03, 0x58, 0x1b, 0x02, 0x03, 0x60, 0x1b, 0x02, 0x03, 0x68, 0x1b, 0x02, 0x03, 0x50, 0x03, 0x03, 0x04, 0x80, 0x05, 0x05, 0x07, + 0xb4, 0x32, 0x00, 0x02, 0xb8, 0x32, 0x00, 0x02, 0xbc, 0x32, 0x00, 0x02, 0xc0, 0x32, 0x00, 0x02, 0xc4, 0x32, 0x00, 0x02, 0xc8, 0x32, 0x00, 0x02, 0xcc, 0x32, 0x00, 0x02, 0xd0, 0x32, 0x00, 0x02, + 0xd4, 0x32, 0x00, 0x02, 0x58, 0x3c, 0x01, 0x02, 0x5c, 0x3c, 0x01, 0x02, 0x60, 0x3c, 0x01, 0x02, 0x64, 0x3c, 0x01, 0x02, 0x68, 0x3c, 0x01, 0x02, 0x6c, 0x3c, 0x01, 0x02, 0x70, 0x3c, 0x01, 0x02, + 0x74, 0x3c, 0x01, 0x02, 0x78, 0x3c, 0x01, 0x02, 0x70, 0x1b, 0x02, 0x03, 0x78, 0x1b, 0x02, 0x03, 0x80, 0x1b, 0x02, 0x03, 0x88, 0x1b, 0x02, 0x03, 0x60, 0x03, 0x03, 0x04, 0x00, 0x06, 0x05, 0x07, + 0xd8, 0x32, 0x00, 0x02, 0xdc, 0x32, 0x00, 0x02, 0xe0, 0x32, 0x00, 0x02, 0xe4, 0x32, 0x00, 0x02, 0xe8, 0x32, 0x00, 0x02, 0xec, 0x32, 0x00, 0x02, 0xf0, 0x32, 0x00, 0x02, 0xf4, 0x32, 0x00, 0x02, + 0xf8, 0x32, 0x00, 0x02, 0x7c, 0x3c, 0x01, 0x02, 0x80, 0x3c, 0x01, 0x02, 0x84, 0x3c, 0x01, 0x02, 0x88, 0x3c, 0x01, 0x02, 0x8c, 0x3c, 0x01, 0x02, 0x90, 0x3c, 0x01, 0x02, 0x94, 0x3c, 0x01, 0x02, + 0x98, 0x3c, 0x01, 0x02, 0x9c, 0x3c, 0x01, 0x02, 0x90, 0x1b, 0x02, 0x03, 0x98, 0x1b, 0x02, 0x03, 0xa0, 0x1b, 0x02, 0x03, 0xa8, 0x1b, 0x02, 0x03, 0x70, 0x03, 0x03, 0x04, 0x80, 0x06, 0x05, 0x07, + 0xfc, 0x32, 0x00, 0x02, 0x00, 0x33, 0x00, 0x02, 0x04, 0x33, 0x00, 0x02, 0x08, 0x33, 0x00, 0x02, 0x0c, 0x33, 0x00, 0x02, 0x10, 0x33, 0x00, 0x02, 0x14, 0x33, 0x00, 0x02, 0x18, 0x33, 0x00, 0x02, + 0x1c, 0x33, 0x00, 0x02, 0xa0, 0x3c, 0x01, 0x02, 0xa4, 0x3c, 0x01, 0x02, 0xa8, 0x3c, 0x01, 0x02, 0xac, 0x3c, 0x01, 0x02, 0xb0, 0x3c, 0x01, 0x02, 0xb4, 0x3c, 0x01, 0x02, 0xb8, 0x3c, 0x01, 0x02, + 0xbc, 0x3c, 0x01, 0x02, 0xc0, 0x3c, 0x01, 0x02, 0xb0, 0x1b, 0x02, 0x03, 0xb8, 0x1b, 0x02, 0x03, 0xc0, 0x1b, 0x02, 0x03, 0xc8, 0x1b, 0x02, 0x03, 0x80, 0x03, 0x03, 0x04, 0x00, 0x07, 0x05, 0x07, + 0x20, 0x33, 0x00, 0x02, 0x24, 0x33, 0x00, 0x02, 0x28, 0x33, 0x00, 0x02, 0x2c, 0x33, 0x00, 0x02, 0x30, 0x33, 0x00, 0x02, 0x34, 0x33, 0x00, 0x02, 0x38, 0x33, 0x00, 0x02, 0x3c, 0x33, 0x00, 0x02, + 0xc4, 0x3c, 0x01, 0x02, 0xc8, 0x3c, 0x01, 0x02, 0xcc, 0x3c, 0x01, 0x02, 0xd0, 0x3c, 0x01, 0x02, 0xd4, 0x3c, 0x01, 0x02, 0xd8, 0x3c, 0x01, 0x02, 0xdc, 0x3c, 0x01, 0x02, 0xe0, 0x3c, 0x01, 0x02, + 0xe4, 0x3c, 0x01, 0x02, 0xe8, 0x3c, 0x01, 0x02, 0xd0, 0x1b, 0x02, 0x03, 0xd8, 0x1b, 0x02, 0x03, 0xe0, 0x1b, 0x02, 0x03, 0xe8, 0x1b, 0x02, 0x03, 0x90, 0x03, 0x03, 0x04, 0x80, 0x07, 0x05, 0x07, + 0x40, 0x33, 0x00, 0x02, 0x44, 0x33, 0x00, 0x02, 0x48, 0x33, 0x00, 0x02, 0x4c, 0x33, 0x00, 0x02, 0x50, 0x33, 0x00, 0x02, 0x54, 0x33, 0x00, 0x02, 0x58, 0x33, 0x00, 0x02, 0x5c, 0x33, 0x00, 0x02, + 0xec, 0x3c, 0x01, 0x02, 0xf0, 0x3c, 0x01, 0x02, 0xf4, 0x3c, 0x01, 0x02, 0xf8, 0x3c, 0x01, 0x02, 0xfc, 0x3c, 0x01, 0x02, 0x00, 0x3d, 0x01, 0x02, 0x04, 0x3d, 0x01, 0x02, 0x08, 0x3d, 0x01, 0x02, + 0x0c, 0x3d, 0x01, 0x02, 0x10, 0x3d, 0x01, 0x02, 0xf0, 0x1b, 0x02, 0x03, 0xf8, 0x1b, 0x02, 0x03, 0x00, 0x1c, 0x02, 0x03, 0x08, 0x1c, 0x02, 0x03, 0xa0, 0x03, 0x03, 0x04, 0x00, 0x08, 0x05, 0x07, + 0x60, 0x33, 0x00, 0x02, 0x64, 0x33, 0x00, 0x02, 0x68, 0x33, 0x00, 0x02, 0x6c, 0x33, 0x00, 0x02, 0x70, 0x33, 0x00, 0x02, 0x74, 0x33, 0x00, 0x02, 0x78, 0x33, 0x00, 0x02, 0x7c, 0x33, 0x00, 0x02, + 0x14, 0x3d, 0x01, 0x02, 0x18, 0x3d, 0x01, 0x02, 0x1c, 0x3d, 0x01, 0x02, 0x20, 0x3d, 0x01, 0x02, 0x24, 0x3d, 0x01, 0x02, 0x28, 0x3d, 0x01, 0x02, 0x2c, 0x3d, 0x01, 0x02, 0x30, 0x3d, 0x01, 0x02, + 0x34, 0x3d, 0x01, 0x02, 0x38, 0x3d, 0x01, 0x02, 0x10, 0x1c, 0x02, 0x03, 0x18, 0x1c, 0x02, 0x03, 0x20, 0x1c, 0x02, 0x03, 0x28, 0x1c, 0x02, 0x03, 0xb0, 0x03, 0x03, 0x04, 0x80, 0x08, 0x05, 0x07, + 0x80, 0x33, 0x00, 0x02, 0x84, 0x33, 0x00, 0x02, 0x88, 0x33, 0x00, 0x02, 0x8c, 0x33, 0x00, 0x02, 0x90, 0x33, 0x00, 0x02, 0x94, 0x33, 0x00, 0x02, 0x98, 0x33, 0x00, 0x02, 0x9c, 0x33, 0x00, 0x02, + 0x3c, 0x3d, 0x01, 0x02, 0x40, 0x3d, 0x01, 0x02, 0x44, 0x3d, 0x01, 0x02, 0x48, 0x3d, 0x01, 0x02, 0x4c, 0x3d, 0x01, 0x02, 0x50, 0x3d, 0x01, 0x02, 0x54, 0x3d, 0x01, 0x02, 0x58, 0x3d, 0x01, 0x02, + 0x5c, 0x3d, 0x01, 0x02, 0x60, 0x3d, 0x01, 0x02, 0x30, 0x1c, 0x02, 0x03, 0x38, 0x1c, 0x02, 0x03, 0x40, 0x1c, 0x02, 0x03, 0x48, 0x1c, 0x02, 0x03, 0xc0, 0x03, 0x03, 0x04, 0x00, 0x09, 0x05, 0x07, + 0xa0, 0x33, 0x00, 0x02, 0xa4, 0x33, 0x00, 0x02, 0xa8, 0x33, 0x00, 0x02, 0xac, 0x33, 0x00, 0x02, 0xb0, 0x33, 0x00, 0x02, 0xb4, 0x33, 0x00, 0x02, 0xb8, 0x33, 0x00, 0x02, 0xbc, 0x33, 0x00, 0x02, + 0x64, 0x3d, 0x01, 0x02, 0x68, 0x3d, 0x01, 0x02, 0x6c, 0x3d, 0x01, 0x02, 0x70, 0x3d, 0x01, 0x02, 0x74, 0x3d, 0x01, 0x02, 0x78, 0x3d, 0x01, 0x02, 0x7c, 0x3d, 0x01, 0x02, 0x80, 0x3d, 0x01, 0x02, + 0x84, 0x3d, 0x01, 0x02, 0x88, 0x3d, 0x01, 0x02, 0x50, 0x1c, 0x02, 0x03, 0x58, 0x1c, 0x02, 0x03, 0x60, 0x1c, 0x02, 0x03, 0x68, 0x1c, 0x02, 0x03, 0xd0, 0x03, 0x03, 0x04, 0x80, 0x09, 0x05, 0x07, + 0xc0, 0x33, 0x00, 0x02, 0xc4, 0x33, 0x00, 0x02, 0xc8, 0x33, 0x00, 0x02, 0xcc, 0x33, 0x00, 0x02, 0xd0, 0x33, 0x00, 0x02, 0xd4, 0x33, 0x00, 0x02, 0xd8, 0x33, 0x00, 0x02, 0xdc, 0x33, 0x00, 0x02, + 0x8c, 0x3d, 0x01, 0x02, 0x90, 0x3d, 0x01, 0x02, 0x94, 0x3d, 0x01, 0x02, 0x98, 0x3d, 0x01, 0x02, 0x9c, 0x3d, 0x01, 0x02, 0xa0, 0x3d, 0x01, 0x02, 0xa4, 0x3d, 0x01, 0x02, 0xa8, 0x3d, 0x01, 0x02, + 0xac, 0x3d, 0x01, 0x02, 0xb0, 0x3d, 0x01, 0x02, 0x70, 0x1c, 0x02, 0x03, 0x78, 0x1c, 0x02, 0x03, 0x80, 0x1c, 0x02, 0x03, 0x88, 0x1c, 0x02, 0x03, 0xe0, 0x03, 0x03, 0x04, 0x00, 0x0a, 0x05, 0x07, + 0xe0, 0x33, 0x00, 0x02, 0xe4, 0x33, 0x00, 0x02, 0xe8, 0x33, 0x00, 0x02, 0xec, 0x33, 0x00, 0x02, 0xf0, 0x33, 0x00, 0x02, 0xf4, 0x33, 0x00, 0x02, 0xf8, 0x33, 0x00, 0x02, 0xfc, 0x33, 0x00, 0x02, + 0xb4, 0x3d, 0x01, 0x02, 0xb8, 0x3d, 0x01, 0x02, 0xbc, 0x3d, 0x01, 0x02, 0xc0, 0x3d, 0x01, 0x02, 0xc4, 0x3d, 0x01, 0x02, 0xc8, 0x3d, 0x01, 0x02, 0xcc, 0x3d, 0x01, 0x02, 0xd0, 0x3d, 0x01, 0x02, + 0xd4, 0x3d, 0x01, 0x02, 0xd8, 0x3d, 0x01, 0x02, 0x90, 0x1c, 0x02, 0x03, 0x98, 0x1c, 0x02, 0x03, 0xa0, 0x1c, 0x02, 0x03, 0xa8, 0x1c, 0x02, 0x03, 0xf0, 0x03, 0x03, 0x04, 0x00, 0x22, 0x06, 0x09, + 0x00, 0x34, 0x00, 0x02, 0x04, 0x34, 0x00, 0x02, 0x08, 0x34, 0x00, 0x02, 0x0c, 0x34, 0x00, 0x02, 0x10, 0x34, 0x00, 0x02, 0x14, 0x34, 0x00, 0x02, 0x18, 0x34, 0x00, 0x02, 0x1c, 0x34, 0x00, 0x02, + 0xdc, 0x3d, 0x01, 0x02, 0xe0, 0x3d, 0x01, 0x02, 0xe4, 0x3d, 0x01, 0x02, 0xe8, 0x3d, 0x01, 0x02, 0xec, 0x3d, 0x01, 0x02, 0xf0, 0x3d, 0x01, 0x02, 0xf4, 0x3d, 0x01, 0x02, 0xf8, 0x3d, 0x01, 0x02, + 0xfc, 0x3d, 0x01, 0x02, 0x00, 0x3e, 0x01, 0x02, 0xb0, 0x1c, 0x02, 0x03, 0xb8, 0x1c, 0x02, 0x03, 0xc0, 0x1c, 0x02, 0x03, 0xc8, 0x1c, 0x02, 0x03, 0x00, 0x04, 0x03, 0x04, 0x00, 0x24, 0x06, 0x09, + 0x20, 0x34, 0x00, 0x02, 0x24, 0x34, 0x00, 0x02, 0x28, 0x34, 0x00, 0x02, 0x2c, 0x34, 0x00, 0x02, 0x30, 0x34, 0x00, 0x02, 0x34, 0x34, 0x00, 0x02, 0x38, 0x34, 0x00, 0x02, 0x3c, 0x34, 0x00, 0x02, + 0x04, 0x3e, 0x01, 0x02, 0x08, 0x3e, 0x01, 0x02, 0x0c, 0x3e, 0x01, 0x02, 0x10, 0x3e, 0x01, 0x02, 0x14, 0x3e, 0x01, 0x02, 0x18, 0x3e, 0x01, 0x02, 0x1c, 0x3e, 0x01, 0x02, 0x20, 0x3e, 0x01, 0x02, + 0x24, 0x3e, 0x01, 0x02, 0x28, 0x3e, 0x01, 0x02, 0xd0, 0x1c, 0x02, 0x03, 0xd8, 0x1c, 0x02, 0x03, 0xe0, 0x1c, 0x02, 0x03, 0xe8, 0x1c, 0x02, 0x03, 0x10, 0x04, 0x03, 0x04, 0x00, 0x26, 0x06, 0x09, + 0x40, 0x34, 0x00, 0x02, 0x44, 0x34, 0x00, 0x02, 0x48, 0x34, 0x00, 0x02, 0x4c, 0x34, 0x00, 0x02, 0x50, 0x34, 0x00, 0x02, 0x54, 0x34, 0x00, 0x02, 0x58, 0x34, 0x00, 0x02, 0x5c, 0x34, 0x00, 0x02, + 0x2c, 0x3e, 0x01, 0x02, 0x30, 0x3e, 0x01, 0x02, 0x34, 0x3e, 0x01, 0x02, 0x38, 0x3e, 0x01, 0x02, 0x3c, 0x3e, 0x01, 0x02, 0x40, 0x3e, 0x01, 0x02, 0x44, 0x3e, 0x01, 0x02, 0x48, 0x3e, 0x01, 0x02, + 0x4c, 0x3e, 0x01, 0x02, 0x50, 0x3e, 0x01, 0x02, 0xf0, 0x1c, 0x02, 0x03, 0xf8, 0x1c, 0x02, 0x03, 0x00, 0x1d, 0x02, 0x03, 0x08, 0x1d, 0x02, 0x03, 0x20, 0x04, 0x03, 0x04, 0x00, 0x28, 0x06, 0x09, + 0x60, 0x34, 0x00, 0x02, 0x64, 0x34, 0x00, 0x02, 0x68, 0x34, 0x00, 0x02, 0x6c, 0x34, 0x00, 0x02, 0x70, 0x34, 0x00, 0x02, 0x74, 0x34, 0x00, 0x02, 0x78, 0x34, 0x00, 0x02, 0x7c, 0x34, 0x00, 0x02, + 0x54, 0x3e, 0x01, 0x02, 0x58, 0x3e, 0x01, 0x02, 0x5c, 0x3e, 0x01, 0x02, 0x60, 0x3e, 0x01, 0x02, 0x64, 0x3e, 0x01, 0x02, 0x68, 0x3e, 0x01, 0x02, 0x6c, 0x3e, 0x01, 0x02, 0x70, 0x3e, 0x01, 0x02, + 0x74, 0x3e, 0x01, 0x02, 0x78, 0x3e, 0x01, 0x02, 0x10, 0x1d, 0x02, 0x03, 0x18, 0x1d, 0x02, 0x03, 0x20, 0x1d, 0x02, 0x03, 0x30, 0x04, 0x03, 0x04, 0x40, 0x04, 0x03, 0x04, 0x00, 0x2a, 0x06, 0x09, + 0x80, 0x34, 0x00, 0x02, 0x84, 0x34, 0x00, 0x02, 0x88, 0x34, 0x00, 0x02, 0x8c, 0x34, 0x00, 0x02, 0x90, 0x34, 0x00, 0x02, 0x94, 0x34, 0x00, 0x02, 0x98, 0x34, 0x00, 0x02, 0x9c, 0x34, 0x00, 0x02, + 0x7c, 0x3e, 0x01, 0x02, 0x80, 0x3e, 0x01, 0x02, 0x84, 0x3e, 0x01, 0x02, 0x88, 0x3e, 0x01, 0x02, 0x8c, 0x3e, 0x01, 0x02, 0x90, 0x3e, 0x01, 0x02, 0x94, 0x3e, 0x01, 0x02, 0x98, 0x3e, 0x01, 0x02, + 0x9c, 0x3e, 0x01, 0x02, 0xa0, 0x3e, 0x01, 0x02, 0x28, 0x1d, 0x02, 0x03, 0x30, 0x1d, 0x02, 0x03, 0x38, 0x1d, 0x02, 0x03, 0x50, 0x04, 0x03, 0x04, 0x60, 0x04, 0x03, 0x04, 0x00, 0x2c, 0x06, 0x09, + 0xa0, 0x34, 0x00, 0x02, 0xa4, 0x34, 0x00, 0x02, 0xa8, 0x34, 0x00, 0x02, 0xac, 0x34, 0x00, 0x02, 0xb0, 0x34, 0x00, 0x02, 0xb4, 0x34, 0x00, 0x02, 0xb8, 0x34, 0x00, 0x02, 0xbc, 0x34, 0x00, 0x02, + 0xa4, 0x3e, 0x01, 0x02, 0xa8, 0x3e, 0x01, 0x02, 0xac, 0x3e, 0x01, 0x02, 0xb0, 0x3e, 0x01, 0x02, 0xb4, 0x3e, 0x01, 0x02, 0xb8, 0x3e, 0x01, 0x02, 0xbc, 0x3e, 0x01, 0x02, 0xc0, 0x3e, 0x01, 0x02, + 0xc4, 0x3e, 0x01, 0x02, 0xc8, 0x3e, 0x01, 0x02, 0x40, 0x1d, 0x02, 0x03, 0x48, 0x1d, 0x02, 0x03, 0x50, 0x1d, 0x02, 0x03, 0x70, 0x04, 0x03, 0x04, 0x80, 0x04, 0x03, 0x04, 0x00, 0x0c, 0x07, 0x0a, + 0xc0, 0x34, 0x00, 0x02, 0xc4, 0x34, 0x00, 0x02, 0xc8, 0x34, 0x00, 0x02, 0xcc, 0x34, 0x00, 0x02, 0xd0, 0x34, 0x00, 0x02, 0xd4, 0x34, 0x00, 0x02, 0xd8, 0x34, 0x00, 0x02, 0xdc, 0x34, 0x00, 0x02, + 0xcc, 0x3e, 0x01, 0x02, 0xd0, 0x3e, 0x01, 0x02, 0xd4, 0x3e, 0x01, 0x02, 0xd8, 0x3e, 0x01, 0x02, 0xdc, 0x3e, 0x01, 0x02, 0xe0, 0x3e, 0x01, 0x02, 0xe4, 0x3e, 0x01, 0x02, 0xe8, 0x3e, 0x01, 0x02, + 0xec, 0x3e, 0x01, 0x02, 0xf0, 0x3e, 0x01, 0x02, 0x58, 0x1d, 0x02, 0x03, 0x60, 0x1d, 0x02, 0x03, 0x68, 0x1d, 0x02, 0x03, 0x90, 0x04, 0x03, 0x04, 0xa0, 0x04, 0x03, 0x04, 0x00, 0x10, 0x07, 0x0a, + 0xe0, 0x34, 0x00, 0x02, 0xe4, 0x34, 0x00, 0x02, 0xe8, 0x34, 0x00, 0x02, 0xec, 0x34, 0x00, 0x02, 0xf0, 0x34, 0x00, 0x02, 0xf4, 0x34, 0x00, 0x02, 0xf8, 0x34, 0x00, 0x02, 0xfc, 0x34, 0x00, 0x02, + 0xf4, 0x3e, 0x01, 0x02, 0xf8, 0x3e, 0x01, 0x02, 0xfc, 0x3e, 0x01, 0x02, 0x00, 0x3f, 0x01, 0x02, 0x04, 0x3f, 0x01, 0x02, 0x08, 0x3f, 0x01, 0x02, 0x0c, 0x3f, 0x01, 0x02, 0x10, 0x3f, 0x01, 0x02, + 0x14, 0x3f, 0x01, 0x02, 0x18, 0x3f, 0x01, 0x02, 0x70, 0x1d, 0x02, 0x03, 0x78, 0x1d, 0x02, 0x03, 0x80, 0x1d, 0x02, 0x03, 0xb0, 0x04, 0x03, 0x04, 0xc0, 0x04, 0x03, 0x04, 0x00, 0x30, 0x08, 0x0c, + 0x00, 0x35, 0x00, 0x02, 0x04, 0x35, 0x00, 0x02, 0x08, 0x35, 0x00, 0x02, 0x0c, 0x35, 0x00, 0x02, 0x10, 0x35, 0x00, 0x02, 0x14, 0x35, 0x00, 0x02, 0x18, 0x35, 0x00, 0x02, 0x1c, 0x35, 0x00, 0x02, + 0x1c, 0x3f, 0x01, 0x02, 0x20, 0x3f, 0x01, 0x02, 0x24, 0x3f, 0x01, 0x02, 0x28, 0x3f, 0x01, 0x02, 0x2c, 0x3f, 0x01, 0x02, 0x30, 0x3f, 0x01, 0x02, 0x34, 0x3f, 0x01, 0x02, 0x38, 0x3f, 0x01, 0x02, + 0x3c, 0x3f, 0x01, 0x02, 0x40, 0x3f, 0x01, 0x02, 0x88, 0x1d, 0x02, 0x03, 0x90, 0x1d, 0x02, 0x03, 0x98, 0x1d, 0x02, 0x03, 0xd0, 0x04, 0x03, 0x04, 0xe0, 0x04, 0x03, 0x04, 0x20, 0x35, 0x00, 0x02, + 0x24, 0x35, 0x00, 0x02, 0x28, 0x35, 0x00, 0x02, 0x2c, 0x35, 0x00, 0x02, 0x30, 0x35, 0x00, 0x02, 0x34, 0x35, 0x00, 0x02, 0x38, 0x35, 0x00, 0x02, 0x3c, 0x35, 0x00, 0x02, 0x40, 0x35, 0x00, 0x02, + 0x44, 0x3f, 0x01, 0x02, 0x48, 0x3f, 0x01, 0x02, 0x4c, 0x3f, 0x01, 0x02, 0x50, 0x3f, 0x01, 0x02, 0x54, 0x3f, 0x01, 0x02, 0x58, 0x3f, 0x01, 0x02, 0x5c, 0x3f, 0x01, 0x02, 0x60, 0x3f, 0x01, 0x02, + 0x64, 0x3f, 0x01, 0x02, 0x68, 0x3f, 0x01, 0x02, 0xa0, 0x1d, 0x02, 0x03, 0xa8, 0x1d, 0x02, 0x03, 0xb0, 0x1d, 0x02, 0x03, 0xf0, 0x04, 0x03, 0x04, 0x00, 0x05, 0x03, 0x04, 0x44, 0x35, 0x00, 0x02, + 0x48, 0x35, 0x00, 0x02, 0x4c, 0x35, 0x00, 0x02, 0x50, 0x35, 0x00, 0x02, 0x54, 0x35, 0x00, 0x02, 0x58, 0x35, 0x00, 0x02, 0x5c, 0x35, 0x00, 0x02, 0x60, 0x35, 0x00, 0x02, 0x64, 0x35, 0x00, 0x02, + 0x6c, 0x3f, 0x01, 0x02, 0x70, 0x3f, 0x01, 0x02, 0x74, 0x3f, 0x01, 0x02, 0x78, 0x3f, 0x01, 0x02, 0x7c, 0x3f, 0x01, 0x02, 0x80, 0x3f, 0x01, 0x02, 0x84, 0x3f, 0x01, 0x02, 0x88, 0x3f, 0x01, 0x02, + 0x8c, 0x3f, 0x01, 0x02, 0x90, 0x3f, 0x01, 0x02, 0xb8, 0x1d, 0x02, 0x03, 0xc0, 0x1d, 0x02, 0x03, 0xc8, 0x1d, 0x02, 0x03, 0x10, 0x05, 0x03, 0x04, 0x20, 0x05, 0x03, 0x04, 0x68, 0x35, 0x00, 0x02, + 0x6c, 0x35, 0x00, 0x02, 0x70, 0x35, 0x00, 0x02, 0x74, 0x35, 0x00, 0x02, 0x78, 0x35, 0x00, 0x02, 0x7c, 0x35, 0x00, 0x02, 0x80, 0x35, 0x00, 0x02, 0x84, 0x35, 0x00, 0x02, 0x88, 0x35, 0x00, 0x02, + 0x94, 0x3f, 0x01, 0x02, 0x98, 0x3f, 0x01, 0x02, 0x9c, 0x3f, 0x01, 0x02, 0xa0, 0x3f, 0x01, 0x02, 0xa4, 0x3f, 0x01, 0x02, 0xa8, 0x3f, 0x01, 0x02, 0xac, 0x3f, 0x01, 0x02, 0xb0, 0x3f, 0x01, 0x02, + 0xb4, 0x3f, 0x01, 0x02, 0xb8, 0x3f, 0x01, 0x02, 0xd0, 0x1d, 0x02, 0x03, 0xd8, 0x1d, 0x02, 0x03, 0xe0, 0x1d, 0x02, 0x03, 0x30, 0x05, 0x03, 0x04, 0x40, 0x05, 0x03, 0x04, 0x8c, 0x35, 0x00, 0x02, + 0x90, 0x35, 0x00, 0x02, 0x94, 0x35, 0x00, 0x02, 0x98, 0x35, 0x00, 0x02, 0x9c, 0x35, 0x00, 0x02, 0xa0, 0x35, 0x00, 0x02, 0xa4, 0x35, 0x00, 0x02, 0xa8, 0x35, 0x00, 0x02, 0xac, 0x35, 0x00, 0x02, + 0xbc, 0x3f, 0x01, 0x02, 0xc0, 0x3f, 0x01, 0x02, 0xc4, 0x3f, 0x01, 0x02, 0xc8, 0x3f, 0x01, 0x02, 0xcc, 0x3f, 0x01, 0x02, 0xd0, 0x3f, 0x01, 0x02, 0xd4, 0x3f, 0x01, 0x02, 0xd8, 0x3f, 0x01, 0x02, + 0xdc, 0x3f, 0x01, 0x02, 0xe0, 0x3f, 0x01, 0x02, 0xe8, 0x1d, 0x02, 0x03, 0xf0, 0x1d, 0x02, 0x03, 0xf8, 0x1d, 0x02, 0x03, 0x50, 0x05, 0x03, 0x04, 0x60, 0x05, 0x03, 0x04, 0xb0, 0x35, 0x00, 0x02, + 0xb4, 0x35, 0x00, 0x02, 0xb8, 0x35, 0x00, 0x02, 0xbc, 0x35, 0x00, 0x02, 0xc0, 0x35, 0x00, 0x02, 0xc4, 0x35, 0x00, 0x02, 0xc8, 0x35, 0x00, 0x02, 0xcc, 0x35, 0x00, 0x02, 0xd0, 0x35, 0x00, 0x02, + 0xe4, 0x3f, 0x01, 0x02, 0xe8, 0x3f, 0x01, 0x02, 0xec, 0x3f, 0x01, 0x02, 0xf0, 0x3f, 0x01, 0x02, 0xf4, 0x3f, 0x01, 0x02, 0xf8, 0x3f, 0x01, 0x02, 0xfc, 0x3f, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, + 0x02, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x01, 0x00, 0x1e, 0x02, 0x03, 0x08, 0x1e, 0x02, 0x03, 0x10, 0x1e, 0x02, 0x03, 0x70, 0x05, 0x03, 0x04, 0x80, 0x05, 0x03, 0x04, 0xd4, 0x35, 0x00, 0x02, + 0xd8, 0x35, 0x00, 0x02, 0xdc, 0x35, 0x00, 0x02, 0xe0, 0x35, 0x00, 0x02, 0xe4, 0x35, 0x00, 0x02, 0xe8, 0x35, 0x00, 0x02, 0xec, 0x35, 0x00, 0x02, 0xf0, 0x35, 0x00, 0x02, 0xf4, 0x35, 0x00, 0x02, + 0x06, 0x00, 0x01, 0x01, 0x08, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x01, 0x0c, 0x00, 0x01, 0x01, 0x0e, 0x00, 0x01, 0x01, 0x10, 0x00, 0x01, 0x01, 0x12, 0x00, 0x01, 0x01, 0x14, 0x00, 0x01, 0x01, + 0x16, 0x00, 0x01, 0x01, 0x18, 0x00, 0x01, 0x01, 0x18, 0x1e, 0x02, 0x03, 0x20, 0x1e, 0x02, 0x03, 0x28, 0x1e, 0x02, 0x03, 0x90, 0x05, 0x03, 0x04, 0xa0, 0x05, 0x03, 0x04, 0xf8, 0x35, 0x00, 0x02, + 0xfc, 0x35, 0x00, 0x02, 0x00, 0x36, 0x00, 0x02, 0x04, 0x36, 0x00, 0x02, 0x08, 0x36, 0x00, 0x02, 0x0c, 0x36, 0x00, 0x02, 0x10, 0x36, 0x00, 0x02, 0x14, 0x36, 0x00, 0x02, 0x18, 0x36, 0x00, 0x02, + 0x1a, 0x00, 0x01, 0x01, 0x1c, 0x00, 0x01, 0x01, 0x1e, 0x00, 0x01, 0x01, 0x20, 0x00, 0x01, 0x01, 0x22, 0x00, 0x01, 0x01, 0x24, 0x00, 0x01, 0x01, 0x26, 0x00, 0x01, 0x01, 0x28, 0x00, 0x01, 0x01, + 0x2a, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x01, 0x01, 0x30, 0x1e, 0x02, 0x03, 0x38, 0x1e, 0x02, 0x03, 0x40, 0x1e, 0x02, 0x03, 0xb0, 0x05, 0x03, 0x04, 0xc0, 0x05, 0x03, 0x04, 0x1c, 0x36, 0x00, 0x02, + 0x20, 0x36, 0x00, 0x02, 0x24, 0x36, 0x00, 0x02, 0x28, 0x36, 0x00, 0x02, 0x2c, 0x36, 0x00, 0x02, 0x30, 0x36, 0x00, 0x02, 0x34, 0x36, 0x00, 0x02, 0x38, 0x36, 0x00, 0x02, 0x3c, 0x36, 0x00, 0x02, + 0x2e, 0x00, 0x01, 0x01, 0x30, 0x00, 0x01, 0x01, 0x32, 0x00, 0x01, 0x01, 0x34, 0x00, 0x01, 0x01, 0x36, 0x00, 0x01, 0x01, 0x38, 0x00, 0x01, 0x01, 0x3a, 0x00, 0x01, 0x01, 0x3c, 0x00, 0x01, 0x01, + 0x3e, 0x00, 0x01, 0x01, 0x40, 0x00, 0x01, 0x01, 0x48, 0x1e, 0x02, 0x03, 0x50, 0x1e, 0x02, 0x03, 0x58, 0x1e, 0x02, 0x03, 0xd0, 0x05, 0x03, 0x04, 0xe0, 0x05, 0x03, 0x04, 0x40, 0x36, 0x00, 0x02, + 0x44, 0x36, 0x00, 0x02, 0x48, 0x36, 0x00, 0x02, 0x4c, 0x36, 0x00, 0x02, 0x50, 0x36, 0x00, 0x02, 0x54, 0x36, 0x00, 0x02, 0x58, 0x36, 0x00, 0x02, 0x5c, 0x36, 0x00, 0x02, 0x60, 0x36, 0x00, 0x02, + 0x42, 0x00, 0x01, 0x01, 0x44, 0x00, 0x01, 0x01, 0x46, 0x00, 0x01, 0x01, 0x48, 0x00, 0x01, 0x01, 0x4a, 0x00, 0x01, 0x01, 0x4c, 0x00, 0x01, 0x01, 0x4e, 0x00, 0x01, 0x01, 0x50, 0x00, 0x01, 0x01, + 0x52, 0x00, 0x01, 0x01, 0x54, 0x00, 0x01, 0x01, 0x60, 0x1e, 0x02, 0x03, 0x68, 0x1e, 0x02, 0x03, 0x70, 0x1e, 0x02, 0x03, 0xf0, 0x05, 0x03, 0x04, 0x00, 0x06, 0x03, 0x04, 0x64, 0x36, 0x00, 0x02, + 0x68, 0x36, 0x00, 0x02, 0x6c, 0x36, 0x00, 0x02, 0x70, 0x36, 0x00, 0x02, 0x74, 0x36, 0x00, 0x02, 0x78, 0x36, 0x00, 0x02, 0x7c, 0x36, 0x00, 0x02, 0x80, 0x36, 0x00, 0x02, 0x84, 0x36, 0x00, 0x02, + 0x56, 0x00, 0x01, 0x01, 0x58, 0x00, 0x01, 0x01, 0x5a, 0x00, 0x01, 0x01, 0x5c, 0x00, 0x01, 0x01, 0x5e, 0x00, 0x01, 0x01, 0x60, 0x00, 0x01, 0x01, 0x62, 0x00, 0x01, 0x01, 0x64, 0x00, 0x01, 0x01, + 0x66, 0x00, 0x01, 0x01, 0x68, 0x00, 0x01, 0x01, 0x78, 0x1e, 0x02, 0x03, 0x80, 0x1e, 0x02, 0x03, 0x88, 0x1e, 0x02, 0x03, 0x10, 0x06, 0x03, 0x04, 0x20, 0x06, 0x03, 0x04, 0x88, 0x36, 0x00, 0x02, + 0x8c, 0x36, 0x00, 0x02, 0x90, 0x36, 0x00, 0x02, 0x94, 0x36, 0x00, 0x02, 0x98, 0x36, 0x00, 0x02, 0x9c, 0x36, 0x00, 0x02, 0xa0, 0x36, 0x00, 0x02, 0xa4, 0x36, 0x00, 0x02, 0xa8, 0x36, 0x00, 0x02, + 0x6a, 0x00, 0x01, 0x01, 0x6c, 0x00, 0x01, 0x01, 0x6e, 0x00, 0x01, 0x01, 0x70, 0x00, 0x01, 0x01, 0x72, 0x00, 0x01, 0x01, 0x74, 0x00, 0x01, 0x01, 0x76, 0x00, 0x01, 0x01, 0x78, 0x00, 0x01, 0x01, + 0x7a, 0x00, 0x01, 0x01, 0x7c, 0x00, 0x01, 0x01, 0x90, 0x1e, 0x02, 0x03, 0x98, 0x1e, 0x02, 0x03, 0xa0, 0x1e, 0x02, 0x03, 0x30, 0x06, 0x03, 0x04, 0x40, 0x06, 0x03, 0x04, 0xac, 0x36, 0x00, 0x02, + 0xb0, 0x36, 0x00, 0x02, 0xb4, 0x36, 0x00, 0x02, 0xb8, 0x36, 0x00, 0x02, 0xbc, 0x36, 0x00, 0x02, 0xc0, 0x36, 0x00, 0x02, 0xc4, 0x36, 0x00, 0x02, 0xc8, 0x36, 0x00, 0x02, 0xcc, 0x36, 0x00, 0x02, + 0x7e, 0x00, 0x01, 0x01, 0x80, 0x00, 0x01, 0x01, 0x82, 0x00, 0x01, 0x01, 0x84, 0x00, 0x01, 0x01, 0x86, 0x00, 0x01, 0x01, 0x88, 0x00, 0x01, 0x01, 0x8a, 0x00, 0x01, 0x01, 0x8c, 0x00, 0x01, 0x01, + 0x8e, 0x00, 0x01, 0x01, 0x90, 0x00, 0x01, 0x01, 0xa8, 0x1e, 0x02, 0x03, 0xb0, 0x1e, 0x02, 0x03, 0xb8, 0x1e, 0x02, 0x03, 0x50, 0x06, 0x03, 0x04, 0x60, 0x06, 0x03, 0x04, 0xd0, 0x36, 0x00, 0x02, + 0xd4, 0x36, 0x00, 0x02, 0xd8, 0x36, 0x00, 0x02, 0xdc, 0x36, 0x00, 0x02, 0xe0, 0x36, 0x00, 0x02, 0xe4, 0x36, 0x00, 0x02, 0xe8, 0x36, 0x00, 0x02, 0xec, 0x36, 0x00, 0x02, 0xf0, 0x36, 0x00, 0x02, + 0x92, 0x00, 0x01, 0x01, 0x94, 0x00, 0x01, 0x01, 0x96, 0x00, 0x01, 0x01, 0x98, 0x00, 0x01, 0x01, 0x9a, 0x00, 0x01, 0x01, 0x9c, 0x00, 0x01, 0x01, 0x9e, 0x00, 0x01, 0x01, 0xa0, 0x00, 0x01, 0x01, + 0xa2, 0x00, 0x01, 0x01, 0xa4, 0x00, 0x01, 0x01, 0xc0, 0x1e, 0x02, 0x03, 0xc8, 0x1e, 0x02, 0x03, 0xd0, 0x1e, 0x02, 0x03, 0x70, 0x06, 0x03, 0x04, 0x80, 0x06, 0x03, 0x04, 0xf4, 0x36, 0x00, 0x02, + 0xf8, 0x36, 0x00, 0x02, 0xfc, 0x36, 0x00, 0x02, 0x00, 0x37, 0x00, 0x02, 0x04, 0x37, 0x00, 0x02, 0x08, 0x37, 0x00, 0x02, 0x0c, 0x37, 0x00, 0x02, 0x10, 0x37, 0x00, 0x02, 0x14, 0x37, 0x00, 0x02, + 0xa6, 0x00, 0x01, 0x01, 0xa8, 0x00, 0x01, 0x01, 0xaa, 0x00, 0x01, 0x01, 0xac, 0x00, 0x01, 0x01, 0xae, 0x00, 0x01, 0x01, 0xb0, 0x00, 0x01, 0x01, 0xb2, 0x00, 0x01, 0x01, 0xb4, 0x00, 0x01, 0x01, + 0xb6, 0x00, 0x01, 0x01, 0xb8, 0x00, 0x01, 0x01, 0xd8, 0x1e, 0x02, 0x03, 0xe0, 0x1e, 0x02, 0x03, 0xe8, 0x1e, 0x02, 0x03, 0x90, 0x06, 0x03, 0x04, 0xa0, 0x06, 0x03, 0x04, 0x18, 0x37, 0x00, 0x02, + 0x1c, 0x37, 0x00, 0x02, 0x20, 0x37, 0x00, 0x02, 0x24, 0x37, 0x00, 0x02, 0x28, 0x37, 0x00, 0x02, 0x2c, 0x37, 0x00, 0x02, 0x30, 0x37, 0x00, 0x02, 0x34, 0x37, 0x00, 0x02, 0x38, 0x37, 0x00, 0x02, + 0xba, 0x00, 0x01, 0x01, 0xbc, 0x00, 0x01, 0x01, 0xbe, 0x00, 0x01, 0x01, 0xc0, 0x00, 0x01, 0x01, 0xc2, 0x00, 0x01, 0x01, 0xc4, 0x00, 0x01, 0x01, 0xc6, 0x00, 0x01, 0x01, 0xc8, 0x00, 0x01, 0x01, + 0xca, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x01, 0x01, 0xf0, 0x1e, 0x02, 0x03, 0xf8, 0x1e, 0x02, 0x03, 0x00, 0x1f, 0x02, 0x03, 0xb0, 0x06, 0x03, 0x04, 0xc0, 0x06, 0x03, 0x04, 0x3c, 0x37, 0x00, 0x02, + 0x40, 0x37, 0x00, 0x02, 0x44, 0x37, 0x00, 0x02, 0x48, 0x37, 0x00, 0x02, 0x4c, 0x37, 0x00, 0x02, 0x50, 0x37, 0x00, 0x02, 0x54, 0x37, 0x00, 0x02, 0x58, 0x37, 0x00, 0x02, 0x5c, 0x37, 0x00, 0x02, + 0xce, 0x00, 0x01, 0x01, 0xd0, 0x00, 0x01, 0x01, 0xd2, 0x00, 0x01, 0x01, 0xd4, 0x00, 0x01, 0x01, 0xd6, 0x00, 0x01, 0x01, 0xd8, 0x00, 0x01, 0x01, 0xda, 0x00, 0x01, 0x01, 0xdc, 0x00, 0x01, 0x01, + 0xde, 0x00, 0x01, 0x01, 0xe0, 0x00, 0x01, 0x01, 0x08, 0x1f, 0x02, 0x03, 0x10, 0x1f, 0x02, 0x03, 0x18, 0x1f, 0x02, 0x03, 0xd0, 0x06, 0x03, 0x04, 0xe0, 0x06, 0x03, 0x04, 0x60, 0x37, 0x00, 0x02, + 0x64, 0x37, 0x00, 0x02, 0x68, 0x37, 0x00, 0x02, 0x6c, 0x37, 0x00, 0x02, 0x70, 0x37, 0x00, 0x02, 0x74, 0x37, 0x00, 0x02, 0x78, 0x37, 0x00, 0x02, 0x7c, 0x37, 0x00, 0x02, 0x80, 0x37, 0x00, 0x02, + 0xe2, 0x00, 0x01, 0x01, 0xe4, 0x00, 0x01, 0x01, 0xe6, 0x00, 0x01, 0x01, 0xe8, 0x00, 0x01, 0x01, 0xea, 0x00, 0x01, 0x01, 0xec, 0x00, 0x01, 0x01, 0xee, 0x00, 0x01, 0x01, 0xf0, 0x00, 0x01, 0x01, + 0xf2, 0x00, 0x01, 0x01, 0xf4, 0x00, 0x01, 0x01, 0x20, 0x1f, 0x02, 0x03, 0x28, 0x1f, 0x02, 0x03, 0x30, 0x1f, 0x02, 0x03, 0xf0, 0x06, 0x03, 0x04, 0x00, 0x07, 0x03, 0x04, 0x84, 0x37, 0x00, 0x02, + 0x88, 0x37, 0x00, 0x02, 0x8c, 0x37, 0x00, 0x02, 0x90, 0x37, 0x00, 0x02, 0x94, 0x37, 0x00, 0x02, 0x98, 0x37, 0x00, 0x02, 0x9c, 0x37, 0x00, 0x02, 0xa0, 0x37, 0x00, 0x02, 0xa4, 0x37, 0x00, 0x02, + 0xf6, 0x00, 0x01, 0x01, 0xf8, 0x00, 0x01, 0x01, 0xfa, 0x00, 0x01, 0x01, 0xfc, 0x00, 0x01, 0x01, 0xfe, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, + 0x06, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x38, 0x1f, 0x02, 0x03, 0x40, 0x1f, 0x02, 0x03, 0x48, 0x1f, 0x02, 0x03, 0x10, 0x07, 0x03, 0x04, 0x20, 0x07, 0x03, 0x04, 0xa8, 0x37, 0x00, 0x02, + 0xac, 0x37, 0x00, 0x02, 0xb0, 0x37, 0x00, 0x02, 0xb4, 0x37, 0x00, 0x02, 0xb8, 0x37, 0x00, 0x02, 0xbc, 0x37, 0x00, 0x02, 0xc0, 0x37, 0x00, 0x02, 0xc4, 0x37, 0x00, 0x02, 0xc8, 0x37, 0x00, 0x02, + 0x0a, 0x01, 0x01, 0x01, 0x0c, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x14, 0x01, 0x01, 0x01, 0x16, 0x01, 0x01, 0x01, 0x18, 0x01, 0x01, 0x01, + 0x1a, 0x01, 0x01, 0x01, 0x1c, 0x01, 0x01, 0x01, 0x50, 0x1f, 0x02, 0x03, 0x58, 0x1f, 0x02, 0x03, 0x60, 0x1f, 0x02, 0x03, 0x30, 0x07, 0x03, 0x04, 0x40, 0x07, 0x03, 0x04, 0xcc, 0x37, 0x00, 0x02, + 0xd0, 0x37, 0x00, 0x02, 0xd4, 0x37, 0x00, 0x02, 0xd8, 0x37, 0x00, 0x02, 0xdc, 0x37, 0x00, 0x02, 0xe0, 0x37, 0x00, 0x02, 0xe4, 0x37, 0x00, 0x02, 0xe8, 0x37, 0x00, 0x02, 0xec, 0x37, 0x00, 0x02, + 0x1e, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x22, 0x01, 0x01, 0x01, 0x24, 0x01, 0x01, 0x01, 0x26, 0x01, 0x01, 0x01, 0x28, 0x01, 0x01, 0x01, 0x2a, 0x01, 0x01, 0x01, 0x2c, 0x01, 0x01, 0x01, + 0x2e, 0x01, 0x01, 0x01, 0x30, 0x01, 0x01, 0x01, 0x68, 0x1f, 0x02, 0x03, 0x70, 0x1f, 0x02, 0x03, 0x78, 0x1f, 0x02, 0x03, 0x50, 0x07, 0x03, 0x04, 0x60, 0x07, 0x03, 0x04, 0xf0, 0x37, 0x00, 0x02, + 0xf4, 0x37, 0x00, 0x02, 0xf8, 0x37, 0x00, 0x02, 0xfc, 0x37, 0x00, 0x02, 0x00, 0x38, 0x00, 0x02, 0x04, 0x38, 0x00, 0x02, 0x08, 0x38, 0x00, 0x02, 0x0c, 0x38, 0x00, 0x02, 0x10, 0x38, 0x00, 0x02, + 0x32, 0x01, 0x01, 0x01, 0x34, 0x01, 0x01, 0x01, 0x36, 0x01, 0x01, 0x01, 0x38, 0x01, 0x01, 0x01, 0x3a, 0x01, 0x01, 0x01, 0x3c, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, + 0x42, 0x01, 0x01, 0x01, 0x44, 0x01, 0x01, 0x01, 0x80, 0x1f, 0x02, 0x03, 0x88, 0x1f, 0x02, 0x03, 0x90, 0x1f, 0x02, 0x03, 0x70, 0x07, 0x03, 0x04, 0x40, 0x25, 0x04, 0x06, 0x14, 0x38, 0x00, 0x02, + 0x18, 0x38, 0x00, 0x02, 0x1c, 0x38, 0x00, 0x02, 0x20, 0x38, 0x00, 0x02, 0x24, 0x38, 0x00, 0x02, 0x28, 0x38, 0x00, 0x02, 0x2c, 0x38, 0x00, 0x02, 0x30, 0x38, 0x00, 0x02, 0x34, 0x38, 0x00, 0x02, + 0x46, 0x01, 0x01, 0x01, 0x48, 0x01, 0x01, 0x01, 0x4a, 0x01, 0x01, 0x01, 0x4c, 0x01, 0x01, 0x01, 0x4e, 0x01, 0x01, 0x01, 0x50, 0x01, 0x01, 0x01, 0x52, 0x01, 0x01, 0x01, 0x54, 0x01, 0x01, 0x01, + 0x56, 0x01, 0x01, 0x01, 0x58, 0x01, 0x01, 0x01, 0x98, 0x1f, 0x02, 0x03, 0xa0, 0x1f, 0x02, 0x03, 0xa8, 0x1f, 0x02, 0x03, 0x80, 0x07, 0x03, 0x04, 0x80, 0x25, 0x04, 0x06, 0x38, 0x38, 0x00, 0x02, + 0x3c, 0x38, 0x00, 0x02, 0x40, 0x38, 0x00, 0x02, 0x44, 0x38, 0x00, 0x02, 0x48, 0x38, 0x00, 0x02, 0x4c, 0x38, 0x00, 0x02, 0x50, 0x38, 0x00, 0x02, 0x54, 0x38, 0x00, 0x02, 0x58, 0x38, 0x00, 0x02, + 0x5a, 0x01, 0x01, 0x01, 0x5c, 0x01, 0x01, 0x01, 0x5e, 0x01, 0x01, 0x01, 0x60, 0x01, 0x01, 0x01, 0x62, 0x01, 0x01, 0x01, 0x64, 0x01, 0x01, 0x01, 0x66, 0x01, 0x01, 0x01, 0x68, 0x01, 0x01, 0x01, + 0x6a, 0x01, 0x01, 0x01, 0x6c, 0x01, 0x01, 0x01, 0xb0, 0x1f, 0x02, 0x03, 0xb8, 0x1f, 0x02, 0x03, 0xc0, 0x1f, 0x02, 0x03, 0x90, 0x07, 0x03, 0x04, 0xc0, 0x25, 0x04, 0x06, 0x5c, 0x38, 0x00, 0x02, + 0x60, 0x38, 0x00, 0x02, 0x64, 0x38, 0x00, 0x02, 0x68, 0x38, 0x00, 0x02, 0x6c, 0x38, 0x00, 0x02, 0x70, 0x38, 0x00, 0x02, 0x74, 0x38, 0x00, 0x02, 0x78, 0x38, 0x00, 0x02, 0x7c, 0x38, 0x00, 0x02, + 0x6e, 0x01, 0x01, 0x01, 0x70, 0x01, 0x01, 0x01, 0x72, 0x01, 0x01, 0x01, 0x74, 0x01, 0x01, 0x01, 0x76, 0x01, 0x01, 0x01, 0x78, 0x01, 0x01, 0x01, 0x7a, 0x01, 0x01, 0x01, 0x7c, 0x01, 0x01, 0x01, + 0x7e, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0xc8, 0x1f, 0x02, 0x03, 0xd0, 0x1f, 0x02, 0x03, 0xd8, 0x1f, 0x02, 0x03, 0xa0, 0x07, 0x03, 0x04, 0x00, 0x26, 0x04, 0x06, 0x80, 0x38, 0x00, 0x02, + 0x84, 0x38, 0x00, 0x02, 0x88, 0x38, 0x00, 0x02, 0x8c, 0x38, 0x00, 0x02, 0x90, 0x38, 0x00, 0x02, 0x94, 0x38, 0x00, 0x02, 0x98, 0x38, 0x00, 0x02, 0x9c, 0x38, 0x00, 0x02, 0xa0, 0x38, 0x00, 0x02, + 0x82, 0x01, 0x01, 0x01, 0x84, 0x01, 0x01, 0x01, 0x86, 0x01, 0x01, 0x01, 0x88, 0x01, 0x01, 0x01, 0x8a, 0x01, 0x01, 0x01, 0x8c, 0x01, 0x01, 0x01, 0x8e, 0x01, 0x01, 0x01, 0x90, 0x01, 0x01, 0x01, + 0x92, 0x01, 0x01, 0x01, 0x94, 0x01, 0x01, 0x01, 0xe0, 0x1f, 0x02, 0x03, 0xe8, 0x1f, 0x02, 0x03, 0xf0, 0x1f, 0x02, 0x03, 0xb0, 0x07, 0x03, 0x04, 0x40, 0x26, 0x04, 0x06, 0xa4, 0x38, 0x00, 0x02, + 0xa8, 0x38, 0x00, 0x02, 0xac, 0x38, 0x00, 0x02, 0xb0, 0x38, 0x00, 0x02, 0xb4, 0x38, 0x00, 0x02, 0xb8, 0x38, 0x00, 0x02, 0xbc, 0x38, 0x00, 0x02, 0xc0, 0x38, 0x00, 0x02, 0xc4, 0x38, 0x00, 0x02, + 0x96, 0x01, 0x01, 0x01, 0x98, 0x01, 0x01, 0x01, 0x9a, 0x01, 0x01, 0x01, 0x9c, 0x01, 0x01, 0x01, 0x9e, 0x01, 0x01, 0x01, 0xa0, 0x01, 0x01, 0x01, 0xa2, 0x01, 0x01, 0x01, 0xa4, 0x01, 0x01, 0x01, + 0xa6, 0x01, 0x01, 0x01, 0xa8, 0x01, 0x01, 0x01, 0xf8, 0x1f, 0x02, 0x03, 0x00, 0x20, 0x02, 0x03, 0x08, 0x20, 0x02, 0x03, 0xc0, 0x07, 0x03, 0x04, 0x80, 0x26, 0x04, 0x06, 0xc8, 0x38, 0x00, 0x02, + 0xcc, 0x38, 0x00, 0x02, 0xd0, 0x38, 0x00, 0x02, 0xd4, 0x38, 0x00, 0x02, 0xd8, 0x38, 0x00, 0x02, 0xdc, 0x38, 0x00, 0x02, 0xe0, 0x38, 0x00, 0x02, 0xe4, 0x38, 0x00, 0x02, 0xe8, 0x38, 0x00, 0x02, + 0xaa, 0x01, 0x01, 0x01, 0xac, 0x01, 0x01, 0x01, 0xae, 0x01, 0x01, 0x01, 0xb0, 0x01, 0x01, 0x01, 0xb2, 0x01, 0x01, 0x01, 0xb4, 0x01, 0x01, 0x01, 0xb6, 0x01, 0x01, 0x01, 0xb8, 0x01, 0x01, 0x01, + 0xba, 0x01, 0x01, 0x01, 0xbc, 0x01, 0x01, 0x01, 0x10, 0x20, 0x02, 0x03, 0x18, 0x20, 0x02, 0x03, 0x20, 0x20, 0x02, 0x03, 0xd0, 0x07, 0x03, 0x04, 0xc0, 0x26, 0x04, 0x06, 0xec, 0x38, 0x00, 0x02, + 0xf0, 0x38, 0x00, 0x02, 0xf4, 0x38, 0x00, 0x02, 0xf8, 0x38, 0x00, 0x02, 0xfc, 0x38, 0x00, 0x02, 0x00, 0x39, 0x00, 0x02, 0x04, 0x39, 0x00, 0x02, 0x08, 0x39, 0x00, 0x02, 0x0c, 0x39, 0x00, 0x02, + 0xbe, 0x01, 0x01, 0x01, 0xc0, 0x01, 0x01, 0x01, 0xc2, 0x01, 0x01, 0x01, 0xc4, 0x01, 0x01, 0x01, 0xc6, 0x01, 0x01, 0x01, 0xc8, 0x01, 0x01, 0x01, 0xca, 0x01, 0x01, 0x01, 0xcc, 0x01, 0x01, 0x01, + 0xce, 0x01, 0x01, 0x01, 0xd0, 0x01, 0x01, 0x01, 0x28, 0x20, 0x02, 0x03, 0x30, 0x20, 0x02, 0x03, 0x38, 0x20, 0x02, 0x03, 0xe0, 0x07, 0x03, 0x04, 0x00, 0x27, 0x04, 0x06, 0x10, 0x39, 0x00, 0x02, + 0x14, 0x39, 0x00, 0x02, 0x18, 0x39, 0x00, 0x02, 0x1c, 0x39, 0x00, 0x02, 0x20, 0x39, 0x00, 0x02, 0x24, 0x39, 0x00, 0x02, 0x28, 0x39, 0x00, 0x02, 0x2c, 0x39, 0x00, 0x02, 0x30, 0x39, 0x00, 0x02, + 0xd2, 0x01, 0x01, 0x01, 0xd4, 0x01, 0x01, 0x01, 0xd6, 0x01, 0x01, 0x01, 0xd8, 0x01, 0x01, 0x01, 0xda, 0x01, 0x01, 0x01, 0xdc, 0x01, 0x01, 0x01, 0xde, 0x01, 0x01, 0x01, 0xe0, 0x01, 0x01, 0x01, + 0xe2, 0x01, 0x01, 0x01, 0xe4, 0x01, 0x01, 0x01, 0x40, 0x20, 0x02, 0x03, 0x48, 0x20, 0x02, 0x03, 0x50, 0x20, 0x02, 0x03, 0xf0, 0x07, 0x03, 0x04, 0x40, 0x27, 0x04, 0x06, 0x34, 0x39, 0x00, 0x02, + 0x38, 0x39, 0x00, 0x02, 0x3c, 0x39, 0x00, 0x02, 0x40, 0x39, 0x00, 0x02, 0x44, 0x39, 0x00, 0x02, 0x48, 0x39, 0x00, 0x02, 0x4c, 0x39, 0x00, 0x02, 0x50, 0x39, 0x00, 0x02, 0x54, 0x39, 0x00, 0x02, + 0xe6, 0x01, 0x01, 0x01, 0xe8, 0x01, 0x01, 0x01, 0xea, 0x01, 0x01, 0x01, 0xec, 0x01, 0x01, 0x01, 0xee, 0x01, 0x01, 0x01, 0xf0, 0x01, 0x01, 0x01, 0xf2, 0x01, 0x01, 0x01, 0xf4, 0x01, 0x01, 0x01, + 0xf6, 0x01, 0x01, 0x01, 0xf8, 0x01, 0x01, 0x01, 0x58, 0x20, 0x02, 0x03, 0x60, 0x20, 0x02, 0x03, 0x68, 0x20, 0x02, 0x03, 0x00, 0x08, 0x03, 0x04, 0x80, 0x27, 0x04, 0x06, 0x58, 0x39, 0x00, 0x02, + 0x5c, 0x39, 0x00, 0x02, 0x60, 0x39, 0x00, 0x02, 0x64, 0x39, 0x00, 0x02, 0x68, 0x39, 0x00, 0x02, 0x6c, 0x39, 0x00, 0x02, 0x70, 0x39, 0x00, 0x02, 0x74, 0x39, 0x00, 0x02, 0x78, 0x39, 0x00, 0x02, + 0xfa, 0x01, 0x01, 0x01, 0xfc, 0x01, 0x01, 0x01, 0xfe, 0x01, 0x01, 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x06, 0x02, 0x01, 0x01, 0x08, 0x02, 0x01, 0x01, + 0x0a, 0x02, 0x01, 0x01, 0x0c, 0x02, 0x01, 0x01, 0x70, 0x20, 0x02, 0x03, 0x78, 0x20, 0x02, 0x03, 0x80, 0x20, 0x02, 0x03, 0x10, 0x08, 0x03, 0x04, 0xc0, 0x27, 0x04, 0x06, 0x7c, 0x39, 0x00, 0x02, + 0x80, 0x39, 0x00, 0x02, 0x84, 0x39, 0x00, 0x02, 0x88, 0x39, 0x00, 0x02, 0x8c, 0x39, 0x00, 0x02, 0x90, 0x39, 0x00, 0x02, 0x94, 0x39, 0x00, 0x02, 0x98, 0x39, 0x00, 0x02, 0x9c, 0x39, 0x00, 0x02, + 0x0e, 0x02, 0x01, 0x01, 0x10, 0x02, 0x01, 0x01, 0x12, 0x02, 0x01, 0x01, 0x14, 0x02, 0x01, 0x01, 0x16, 0x02, 0x01, 0x01, 0x18, 0x02, 0x01, 0x01, 0x1a, 0x02, 0x01, 0x01, 0x1c, 0x02, 0x01, 0x01, + 0x1e, 0x02, 0x01, 0x01, 0x20, 0x02, 0x01, 0x01, 0x88, 0x20, 0x02, 0x03, 0x90, 0x20, 0x02, 0x03, 0x98, 0x20, 0x02, 0x03, 0x20, 0x08, 0x03, 0x04, 0x00, 0x28, 0x04, 0x06, 0xa0, 0x39, 0x00, 0x02, + 0xa4, 0x39, 0x00, 0x02, 0xa8, 0x39, 0x00, 0x02, 0xac, 0x39, 0x00, 0x02, 0xb0, 0x39, 0x00, 0x02, 0xb4, 0x39, 0x00, 0x02, 0xb8, 0x39, 0x00, 0x02, 0xbc, 0x39, 0x00, 0x02, 0xc0, 0x39, 0x00, 0x02, + 0x22, 0x02, 0x01, 0x01, 0x24, 0x02, 0x01, 0x01, 0x26, 0x02, 0x01, 0x01, 0x28, 0x02, 0x01, 0x01, 0x2a, 0x02, 0x01, 0x01, 0x2c, 0x02, 0x01, 0x01, 0x2e, 0x02, 0x01, 0x01, 0x30, 0x02, 0x01, 0x01, + 0x32, 0x02, 0x01, 0x01, 0x34, 0x02, 0x01, 0x01, 0xa0, 0x20, 0x02, 0x03, 0xa8, 0x20, 0x02, 0x03, 0xb0, 0x20, 0x02, 0x03, 0x30, 0x08, 0x03, 0x04, 0x40, 0x28, 0x04, 0x06, 0xc4, 0x39, 0x00, 0x02, + 0xc8, 0x39, 0x00, 0x02, 0xcc, 0x39, 0x00, 0x02, 0xd0, 0x39, 0x00, 0x02, 0xd4, 0x39, 0x00, 0x02, 0xd8, 0x39, 0x00, 0x02, 0xdc, 0x39, 0x00, 0x02, 0xe0, 0x39, 0x00, 0x02, 0xe4, 0x39, 0x00, 0x02, + 0x36, 0x02, 0x01, 0x01, 0x38, 0x02, 0x01, 0x01, 0x3a, 0x02, 0x01, 0x01, 0x3c, 0x02, 0x01, 0x01, 0x3e, 0x02, 0x01, 0x01, 0x40, 0x02, 0x01, 0x01, 0x42, 0x02, 0x01, 0x01, 0x44, 0x02, 0x01, 0x01, + 0x46, 0x02, 0x01, 0x01, 0x48, 0x02, 0x01, 0x01, 0xb8, 0x20, 0x02, 0x03, 0xc0, 0x20, 0x02, 0x03, 0xc8, 0x20, 0x02, 0x03, 0x40, 0x08, 0x03, 0x04, 0x80, 0x28, 0x04, 0x06, 0xe8, 0x39, 0x00, 0x02, + 0xec, 0x39, 0x00, 0x02, 0xf0, 0x39, 0x00, 0x02, 0xf4, 0x39, 0x00, 0x02, 0xf8, 0x39, 0x00, 0x02, 0xfc, 0x39, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x02, 0x04, 0x3a, 0x00, 0x02, 0x08, 0x3a, 0x00, 0x02, + 0x4a, 0x02, 0x01, 0x01, 0x4c, 0x02, 0x01, 0x01, 0x4e, 0x02, 0x01, 0x01, 0x50, 0x02, 0x01, 0x01, 0x52, 0x02, 0x01, 0x01, 0x54, 0x02, 0x01, 0x01, 0x56, 0x02, 0x01, 0x01, 0x58, 0x02, 0x01, 0x01, + 0x5a, 0x02, 0x01, 0x01, 0x5c, 0x02, 0x01, 0x01, 0xd0, 0x20, 0x02, 0x03, 0xd8, 0x20, 0x02, 0x03, 0xe0, 0x20, 0x02, 0x03, 0x50, 0x08, 0x03, 0x04, 0xc0, 0x28, 0x04, 0x06, 0x0c, 0x3a, 0x00, 0x02, + 0x10, 0x3a, 0x00, 0x02, 0x14, 0x3a, 0x00, 0x02, 0x18, 0x3a, 0x00, 0x02, 0x1c, 0x3a, 0x00, 0x02, 0x20, 0x3a, 0x00, 0x02, 0x24, 0x3a, 0x00, 0x02, 0x28, 0x3a, 0x00, 0x02, 0x2c, 0x3a, 0x00, 0x02, + 0x5e, 0x02, 0x01, 0x01, 0x60, 0x02, 0x01, 0x01, 0x62, 0x02, 0x01, 0x01, 0x64, 0x02, 0x01, 0x01, 0x66, 0x02, 0x01, 0x01, 0x68, 0x02, 0x01, 0x01, 0x6a, 0x02, 0x01, 0x01, 0x6c, 0x02, 0x01, 0x01, + 0x6e, 0x02, 0x01, 0x01, 0xe8, 0x20, 0x02, 0x03, 0xf0, 0x20, 0x02, 0x03, 0xf8, 0x20, 0x02, 0x03, 0x00, 0x21, 0x02, 0x03, 0x60, 0x08, 0x03, 0x04, 0x00, 0x29, 0x04, 0x06, 0x30, 0x3a, 0x00, 0x02, + 0x34, 0x3a, 0x00, 0x02, 0x38, 0x3a, 0x00, 0x02, 0x3c, 0x3a, 0x00, 0x02, 0x40, 0x3a, 0x00, 0x02, 0x44, 0x3a, 0x00, 0x02, 0x48, 0x3a, 0x00, 0x02, 0x4c, 0x3a, 0x00, 0x02, 0x50, 0x3a, 0x00, 0x02, + 0x70, 0x02, 0x01, 0x01, 0x72, 0x02, 0x01, 0x01, 0x74, 0x02, 0x01, 0x01, 0x76, 0x02, 0x01, 0x01, 0x78, 0x02, 0x01, 0x01, 0x7a, 0x02, 0x01, 0x01, 0x7c, 0x02, 0x01, 0x01, 0x7e, 0x02, 0x01, 0x01, + 0x80, 0x02, 0x01, 0x01, 0x08, 0x21, 0x02, 0x03, 0x10, 0x21, 0x02, 0x03, 0x18, 0x21, 0x02, 0x03, 0x20, 0x21, 0x02, 0x03, 0x70, 0x08, 0x03, 0x04, 0x40, 0x29, 0x04, 0x06, 0x54, 0x3a, 0x00, 0x02, + 0x58, 0x3a, 0x00, 0x02, 0x5c, 0x3a, 0x00, 0x02, 0x60, 0x3a, 0x00, 0x02, 0x64, 0x3a, 0x00, 0x02, 0x68, 0x3a, 0x00, 0x02, 0x6c, 0x3a, 0x00, 0x02, 0x70, 0x3a, 0x00, 0x02, 0x74, 0x3a, 0x00, 0x02, + 0x82, 0x02, 0x01, 0x01, 0x84, 0x02, 0x01, 0x01, 0x86, 0x02, 0x01, 0x01, 0x88, 0x02, 0x01, 0x01, 0x8a, 0x02, 0x01, 0x01, 0x8c, 0x02, 0x01, 0x01, 0x8e, 0x02, 0x01, 0x01, 0x90, 0x02, 0x01, 0x01, + 0x92, 0x02, 0x01, 0x01, 0x28, 0x21, 0x02, 0x03, 0x30, 0x21, 0x02, 0x03, 0x38, 0x21, 0x02, 0x03, 0x40, 0x21, 0x02, 0x03, 0x80, 0x08, 0x03, 0x04, 0x80, 0x29, 0x04, 0x06, 0x78, 0x3a, 0x00, 0x02, + 0x7c, 0x3a, 0x00, 0x02, 0x80, 0x3a, 0x00, 0x02, 0x84, 0x3a, 0x00, 0x02, 0x88, 0x3a, 0x00, 0x02, 0x8c, 0x3a, 0x00, 0x02, 0x90, 0x3a, 0x00, 0x02, 0x94, 0x3a, 0x00, 0x02, 0x98, 0x3a, 0x00, 0x02, + 0x94, 0x02, 0x01, 0x01, 0x96, 0x02, 0x01, 0x01, 0x98, 0x02, 0x01, 0x01, 0x9a, 0x02, 0x01, 0x01, 0x9c, 0x02, 0x01, 0x01, 0x9e, 0x02, 0x01, 0x01, 0xa0, 0x02, 0x01, 0x01, 0xa2, 0x02, 0x01, 0x01, + 0xa4, 0x02, 0x01, 0x01, 0x48, 0x21, 0x02, 0x03, 0x50, 0x21, 0x02, 0x03, 0x58, 0x21, 0x02, 0x03, 0x60, 0x21, 0x02, 0x03, 0x90, 0x08, 0x03, 0x04, 0xc0, 0x29, 0x04, 0x06, 0x9c, 0x3a, 0x00, 0x02, + 0xa0, 0x3a, 0x00, 0x02, 0xa4, 0x3a, 0x00, 0x02, 0xa8, 0x3a, 0x00, 0x02, 0xac, 0x3a, 0x00, 0x02, 0xb0, 0x3a, 0x00, 0x02, 0xb4, 0x3a, 0x00, 0x02, 0xb8, 0x3a, 0x00, 0x02, 0xbc, 0x3a, 0x00, 0x02, + 0xa6, 0x02, 0x01, 0x01, 0xa8, 0x02, 0x01, 0x01, 0xaa, 0x02, 0x01, 0x01, 0xac, 0x02, 0x01, 0x01, 0xae, 0x02, 0x01, 0x01, 0xb0, 0x02, 0x01, 0x01, 0xb2, 0x02, 0x01, 0x01, 0xb4, 0x02, 0x01, 0x01, + 0xb6, 0x02, 0x01, 0x01, 0x68, 0x21, 0x02, 0x03, 0x70, 0x21, 0x02, 0x03, 0x78, 0x21, 0x02, 0x03, 0x80, 0x21, 0x02, 0x03, 0xa0, 0x08, 0x03, 0x04, 0x00, 0x2a, 0x04, 0x06, 0xc0, 0x3a, 0x00, 0x02, + 0xc4, 0x3a, 0x00, 0x02, 0xc8, 0x3a, 0x00, 0x02, 0xcc, 0x3a, 0x00, 0x02, 0xd0, 0x3a, 0x00, 0x02, 0xd4, 0x3a, 0x00, 0x02, 0xd8, 0x3a, 0x00, 0x02, 0xdc, 0x3a, 0x00, 0x02, 0xe0, 0x3a, 0x00, 0x02, + 0xb8, 0x02, 0x01, 0x01, 0xba, 0x02, 0x01, 0x01, 0xbc, 0x02, 0x01, 0x01, 0xbe, 0x02, 0x01, 0x01, 0xc0, 0x02, 0x01, 0x01, 0xc2, 0x02, 0x01, 0x01, 0xc4, 0x02, 0x01, 0x01, 0xc6, 0x02, 0x01, 0x01, + 0xc8, 0x02, 0x01, 0x01, 0x88, 0x21, 0x02, 0x03, 0x90, 0x21, 0x02, 0x03, 0x98, 0x21, 0x02, 0x03, 0xa0, 0x21, 0x02, 0x03, 0xb0, 0x08, 0x03, 0x04, 0x40, 0x2a, 0x04, 0x06, 0xe4, 0x3a, 0x00, 0x02, + 0xe8, 0x3a, 0x00, 0x02, 0xec, 0x3a, 0x00, 0x02, 0xf0, 0x3a, 0x00, 0x02, 0xf4, 0x3a, 0x00, 0x02, 0xf8, 0x3a, 0x00, 0x02, 0xfc, 0x3a, 0x00, 0x02, 0x00, 0x3b, 0x00, 0x02, 0x04, 0x3b, 0x00, 0x02, + 0xca, 0x02, 0x01, 0x01, 0xcc, 0x02, 0x01, 0x01, 0xce, 0x02, 0x01, 0x01, 0xd0, 0x02, 0x01, 0x01, 0xd2, 0x02, 0x01, 0x01, 0xd4, 0x02, 0x01, 0x01, 0xd6, 0x02, 0x01, 0x01, 0xd8, 0x02, 0x01, 0x01, + 0xda, 0x02, 0x01, 0x01, 0xa8, 0x21, 0x02, 0x03, 0xb0, 0x21, 0x02, 0x03, 0xb8, 0x21, 0x02, 0x03, 0xc0, 0x21, 0x02, 0x03, 0xc0, 0x08, 0x03, 0x04, 0x80, 0x2a, 0x04, 0x06, 0x08, 0x3b, 0x00, 0x02, + 0x0c, 0x3b, 0x00, 0x02, 0x10, 0x3b, 0x00, 0x02, 0x14, 0x3b, 0x00, 0x02, 0x18, 0x3b, 0x00, 0x02, 0x1c, 0x3b, 0x00, 0x02, 0x20, 0x3b, 0x00, 0x02, 0x24, 0x3b, 0x00, 0x02, 0x28, 0x3b, 0x00, 0x02, + 0xdc, 0x02, 0x01, 0x01, 0xde, 0x02, 0x01, 0x01, 0xe0, 0x02, 0x01, 0x01, 0xe2, 0x02, 0x01, 0x01, 0xe4, 0x02, 0x01, 0x01, 0xe6, 0x02, 0x01, 0x01, 0xe8, 0x02, 0x01, 0x01, 0xea, 0x02, 0x01, 0x01, + 0xec, 0x02, 0x01, 0x01, 0xc8, 0x21, 0x02, 0x03, 0xd0, 0x21, 0x02, 0x03, 0xd8, 0x21, 0x02, 0x03, 0xe0, 0x21, 0x02, 0x03, 0xd0, 0x08, 0x03, 0x04, 0xc0, 0x2a, 0x04, 0x06, 0x2c, 0x3b, 0x00, 0x02, + 0x30, 0x3b, 0x00, 0x02, 0x34, 0x3b, 0x00, 0x02, 0x38, 0x3b, 0x00, 0x02, 0x3c, 0x3b, 0x00, 0x02, 0x40, 0x3b, 0x00, 0x02, 0x44, 0x3b, 0x00, 0x02, 0x48, 0x3b, 0x00, 0x02, 0x4c, 0x3b, 0x00, 0x02, + 0xee, 0x02, 0x01, 0x01, 0xf0, 0x02, 0x01, 0x01, 0xf2, 0x02, 0x01, 0x01, 0xf4, 0x02, 0x01, 0x01, 0xf6, 0x02, 0x01, 0x01, 0xf8, 0x02, 0x01, 0x01, 0xfa, 0x02, 0x01, 0x01, 0xfc, 0x02, 0x01, 0x01, + 0xfe, 0x02, 0x01, 0x01, 0xe8, 0x21, 0x02, 0x03, 0xf0, 0x21, 0x02, 0x03, 0xf8, 0x21, 0x02, 0x03, 0x00, 0x22, 0x02, 0x03, 0xe0, 0x08, 0x03, 0x04, 0x00, 0x2b, 0x04, 0x06, 0x50, 0x3b, 0x00, 0x02, + 0x54, 0x3b, 0x00, 0x02, 0x58, 0x3b, 0x00, 0x02, 0x5c, 0x3b, 0x00, 0x02, 0x60, 0x3b, 0x00, 0x02, 0x64, 0x3b, 0x00, 0x02, 0x68, 0x3b, 0x00, 0x02, 0x6c, 0x3b, 0x00, 0x02, 0x70, 0x3b, 0x00, 0x02, + 0x00, 0x03, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x04, 0x03, 0x01, 0x01, 0x06, 0x03, 0x01, 0x01, 0x08, 0x03, 0x01, 0x01, 0x0a, 0x03, 0x01, 0x01, 0x0c, 0x03, 0x01, 0x01, 0x0e, 0x03, 0x01, 0x01, + 0x10, 0x03, 0x01, 0x01, 0x08, 0x22, 0x02, 0x03, 0x10, 0x22, 0x02, 0x03, 0x18, 0x22, 0x02, 0x03, 0x20, 0x22, 0x02, 0x03, 0xf0, 0x08, 0x03, 0x04, 0x40, 0x2b, 0x04, 0x06, 0x74, 0x3b, 0x00, 0x02, + 0x78, 0x3b, 0x00, 0x02, 0x7c, 0x3b, 0x00, 0x02, 0x80, 0x3b, 0x00, 0x02, 0x84, 0x3b, 0x00, 0x02, 0x88, 0x3b, 0x00, 0x02, 0x8c, 0x3b, 0x00, 0x02, 0x90, 0x3b, 0x00, 0x02, 0x94, 0x3b, 0x00, 0x02, + 0x12, 0x03, 0x01, 0x01, 0x14, 0x03, 0x01, 0x01, 0x16, 0x03, 0x01, 0x01, 0x18, 0x03, 0x01, 0x01, 0x1a, 0x03, 0x01, 0x01, 0x1c, 0x03, 0x01, 0x01, 0x1e, 0x03, 0x01, 0x01, 0x20, 0x03, 0x01, 0x01, + 0x22, 0x03, 0x01, 0x01, 0x28, 0x22, 0x02, 0x03, 0x30, 0x22, 0x02, 0x03, 0x38, 0x22, 0x02, 0x03, 0x40, 0x22, 0x02, 0x03, 0x00, 0x09, 0x03, 0x04, 0x80, 0x2b, 0x04, 0x06, 0x98, 0x3b, 0x00, 0x02, + 0x9c, 0x3b, 0x00, 0x02, 0xa0, 0x3b, 0x00, 0x02, 0xa4, 0x3b, 0x00, 0x02, 0xa8, 0x3b, 0x00, 0x02, 0xac, 0x3b, 0x00, 0x02, 0xb0, 0x3b, 0x00, 0x02, 0xb4, 0x3b, 0x00, 0x02, 0xb8, 0x3b, 0x00, 0x02, + 0x24, 0x03, 0x01, 0x01, 0x26, 0x03, 0x01, 0x01, 0x28, 0x03, 0x01, 0x01, 0x2a, 0x03, 0x01, 0x01, 0x2c, 0x03, 0x01, 0x01, 0x2e, 0x03, 0x01, 0x01, 0x30, 0x03, 0x01, 0x01, 0x32, 0x03, 0x01, 0x01, + 0x34, 0x03, 0x01, 0x01, 0x48, 0x22, 0x02, 0x03, 0x50, 0x22, 0x02, 0x03, 0x58, 0x22, 0x02, 0x03, 0x60, 0x22, 0x02, 0x03, 0x10, 0x09, 0x03, 0x04, 0xc0, 0x2b, 0x04, 0x06, 0xbc, 0x3b, 0x00, 0x02, + 0xc0, 0x3b, 0x00, 0x02, 0xc4, 0x3b, 0x00, 0x02, 0xc8, 0x3b, 0x00, 0x02, 0xcc, 0x3b, 0x00, 0x02, 0xd0, 0x3b, 0x00, 0x02, 0xd4, 0x3b, 0x00, 0x02, 0xd8, 0x3b, 0x00, 0x02, 0xdc, 0x3b, 0x00, 0x02, + 0x36, 0x03, 0x01, 0x01, 0x38, 0x03, 0x01, 0x01, 0x3a, 0x03, 0x01, 0x01, 0x3c, 0x03, 0x01, 0x01, 0x3e, 0x03, 0x01, 0x01, 0x40, 0x03, 0x01, 0x01, 0x42, 0x03, 0x01, 0x01, 0x44, 0x03, 0x01, 0x01, + 0x46, 0x03, 0x01, 0x01, 0x68, 0x22, 0x02, 0x03, 0x70, 0x22, 0x02, 0x03, 0x78, 0x22, 0x02, 0x03, 0x80, 0x22, 0x02, 0x03, 0x20, 0x09, 0x03, 0x04, 0x00, 0x2c, 0x04, 0x06, 0xe0, 0x3b, 0x00, 0x02, + 0xe4, 0x3b, 0x00, 0x02, 0xe8, 0x3b, 0x00, 0x02, 0xec, 0x3b, 0x00, 0x02, 0xf0, 0x3b, 0x00, 0x02, 0xf4, 0x3b, 0x00, 0x02, 0xf8, 0x3b, 0x00, 0x02, 0xfc, 0x3b, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x02, + 0x48, 0x03, 0x01, 0x01, 0x4a, 0x03, 0x01, 0x01, 0x4c, 0x03, 0x01, 0x01, 0x4e, 0x03, 0x01, 0x01, 0x50, 0x03, 0x01, 0x01, 0x52, 0x03, 0x01, 0x01, 0x54, 0x03, 0x01, 0x01, 0x56, 0x03, 0x01, 0x01, + 0x58, 0x03, 0x01, 0x01, 0x88, 0x22, 0x02, 0x03, 0x90, 0x22, 0x02, 0x03, 0x98, 0x22, 0x02, 0x03, 0xa0, 0x22, 0x02, 0x03, 0x30, 0x09, 0x03, 0x04, 0x40, 0x2c, 0x04, 0x06, 0x04, 0x3c, 0x00, 0x02, + 0x08, 0x3c, 0x00, 0x02, 0x0c, 0x3c, 0x00, 0x02, 0x10, 0x3c, 0x00, 0x02, 0x14, 0x3c, 0x00, 0x02, 0x18, 0x3c, 0x00, 0x02, 0x1c, 0x3c, 0x00, 0x02, 0x20, 0x3c, 0x00, 0x02, 0x24, 0x3c, 0x00, 0x02, + 0x5a, 0x03, 0x01, 0x01, 0x5c, 0x03, 0x01, 0x01, 0x5e, 0x03, 0x01, 0x01, 0x60, 0x03, 0x01, 0x01, 0x62, 0x03, 0x01, 0x01, 0x64, 0x03, 0x01, 0x01, 0x66, 0x03, 0x01, 0x01, 0x68, 0x03, 0x01, 0x01, + 0x6a, 0x03, 0x01, 0x01, 0xa8, 0x22, 0x02, 0x03, 0xb0, 0x22, 0x02, 0x03, 0xb8, 0x22, 0x02, 0x03, 0xc0, 0x22, 0x02, 0x03, 0x40, 0x09, 0x03, 0x04, 0x80, 0x2c, 0x04, 0x06, 0x28, 0x3c, 0x00, 0x02, + 0x2c, 0x3c, 0x00, 0x02, 0x30, 0x3c, 0x00, 0x02, 0x34, 0x3c, 0x00, 0x02, 0x38, 0x3c, 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x02, 0x40, 0x3c, 0x00, 0x02, 0x44, 0x3c, 0x00, 0x02, 0x48, 0x3c, 0x00, 0x02, + 0x6c, 0x03, 0x01, 0x01, 0x6e, 0x03, 0x01, 0x01, 0x70, 0x03, 0x01, 0x01, 0x72, 0x03, 0x01, 0x01, 0x74, 0x03, 0x01, 0x01, 0x76, 0x03, 0x01, 0x01, 0x78, 0x03, 0x01, 0x01, 0x7a, 0x03, 0x01, 0x01, + 0x7c, 0x03, 0x01, 0x01, 0xc8, 0x22, 0x02, 0x03, 0xd0, 0x22, 0x02, 0x03, 0xd8, 0x22, 0x02, 0x03, 0xe0, 0x22, 0x02, 0x03, 0x50, 0x09, 0x03, 0x04, 0xc0, 0x2c, 0x04, 0x06, 0x4c, 0x3c, 0x00, 0x02, + 0x50, 0x3c, 0x00, 0x02, 0x54, 0x3c, 0x00, 0x02, 0x58, 0x3c, 0x00, 0x02, 0x5c, 0x3c, 0x00, 0x02, 0x60, 0x3c, 0x00, 0x02, 0x64, 0x3c, 0x00, 0x02, 0x68, 0x3c, 0x00, 0x02, 0x6c, 0x3c, 0x00, 0x02, + 0x7e, 0x03, 0x01, 0x01, 0x80, 0x03, 0x01, 0x01, 0x82, 0x03, 0x01, 0x01, 0x84, 0x03, 0x01, 0x01, 0x86, 0x03, 0x01, 0x01, 0x88, 0x03, 0x01, 0x01, 0x8a, 0x03, 0x01, 0x01, 0x8c, 0x03, 0x01, 0x01, + 0x8e, 0x03, 0x01, 0x01, 0xe8, 0x22, 0x02, 0x03, 0xf0, 0x22, 0x02, 0x03, 0xf8, 0x22, 0x02, 0x03, 0x00, 0x23, 0x02, 0x03, 0x60, 0x09, 0x03, 0x04, 0x00, 0x2d, 0x04, 0x06, 0x70, 0x3c, 0x00, 0x02, + 0x74, 0x3c, 0x00, 0x02, 0x78, 0x3c, 0x00, 0x02, 0x7c, 0x3c, 0x00, 0x02, 0x80, 0x3c, 0x00, 0x02, 0x84, 0x3c, 0x00, 0x02, 0x88, 0x3c, 0x00, 0x02, 0x8c, 0x3c, 0x00, 0x02, 0x90, 0x3c, 0x00, 0x02, + 0x90, 0x03, 0x01, 0x01, 0x92, 0x03, 0x01, 0x01, 0x94, 0x03, 0x01, 0x01, 0x96, 0x03, 0x01, 0x01, 0x98, 0x03, 0x01, 0x01, 0x9a, 0x03, 0x01, 0x01, 0x9c, 0x03, 0x01, 0x01, 0x9e, 0x03, 0x01, 0x01, + 0xa0, 0x03, 0x01, 0x01, 0x08, 0x23, 0x02, 0x03, 0x10, 0x23, 0x02, 0x03, 0x18, 0x23, 0x02, 0x03, 0x20, 0x23, 0x02, 0x03, 0x70, 0x09, 0x03, 0x04, 0x40, 0x2d, 0x04, 0x06, 0x94, 0x3c, 0x00, 0x02, + 0x98, 0x3c, 0x00, 0x02, 0x9c, 0x3c, 0x00, 0x02, 0xa0, 0x3c, 0x00, 0x02, 0xa4, 0x3c, 0x00, 0x02, 0xa8, 0x3c, 0x00, 0x02, 0xac, 0x3c, 0x00, 0x02, 0xb0, 0x3c, 0x00, 0x02, 0xb4, 0x3c, 0x00, 0x02, + 0xa2, 0x03, 0x01, 0x01, 0xa4, 0x03, 0x01, 0x01, 0xa6, 0x03, 0x01, 0x01, 0xa8, 0x03, 0x01, 0x01, 0xaa, 0x03, 0x01, 0x01, 0xac, 0x03, 0x01, 0x01, 0xae, 0x03, 0x01, 0x01, 0xb0, 0x03, 0x01, 0x01, + 0xb2, 0x03, 0x01, 0x01, 0x28, 0x23, 0x02, 0x03, 0x30, 0x23, 0x02, 0x03, 0x38, 0x23, 0x02, 0x03, 0x40, 0x23, 0x02, 0x03, 0x80, 0x09, 0x03, 0x04, 0x80, 0x2d, 0x04, 0x06, 0xb8, 0x3c, 0x00, 0x02, + 0xbc, 0x3c, 0x00, 0x02, 0xc0, 0x3c, 0x00, 0x02, 0xc4, 0x3c, 0x00, 0x02, 0xc8, 0x3c, 0x00, 0x02, 0xcc, 0x3c, 0x00, 0x02, 0xd0, 0x3c, 0x00, 0x02, 0xd4, 0x3c, 0x00, 0x02, 0xd8, 0x3c, 0x00, 0x02, + 0xb4, 0x03, 0x01, 0x01, 0xb6, 0x03, 0x01, 0x01, 0xb8, 0x03, 0x01, 0x01, 0xba, 0x03, 0x01, 0x01, 0xbc, 0x03, 0x01, 0x01, 0xbe, 0x03, 0x01, 0x01, 0xc0, 0x03, 0x01, 0x01, 0xc2, 0x03, 0x01, 0x01, + 0xc4, 0x03, 0x01, 0x01, 0x48, 0x23, 0x02, 0x03, 0x50, 0x23, 0x02, 0x03, 0x58, 0x23, 0x02, 0x03, 0x60, 0x23, 0x02, 0x03, 0x90, 0x09, 0x03, 0x04, 0xc0, 0x2d, 0x04, 0x06, 0xdc, 0x3c, 0x00, 0x02, + 0xe0, 0x3c, 0x00, 0x02, 0xe4, 0x3c, 0x00, 0x02, 0xe8, 0x3c, 0x00, 0x02, 0xec, 0x3c, 0x00, 0x02, 0xf0, 0x3c, 0x00, 0x02, 0xf4, 0x3c, 0x00, 0x02, 0xf8, 0x3c, 0x00, 0x02, 0xfc, 0x3c, 0x00, 0x02, + 0xc6, 0x03, 0x01, 0x01, 0xc8, 0x03, 0x01, 0x01, 0xca, 0x03, 0x01, 0x01, 0xcc, 0x03, 0x01, 0x01, 0xce, 0x03, 0x01, 0x01, 0xd0, 0x03, 0x01, 0x01, 0xd2, 0x03, 0x01, 0x01, 0xd4, 0x03, 0x01, 0x01, + 0xd6, 0x03, 0x01, 0x01, 0x68, 0x23, 0x02, 0x03, 0x70, 0x23, 0x02, 0x03, 0x78, 0x23, 0x02, 0x03, 0x80, 0x23, 0x02, 0x03, 0xa0, 0x09, 0x03, 0x04, 0x00, 0x2e, 0x04, 0x06, 0x00, 0x3d, 0x00, 0x02, + 0x04, 0x3d, 0x00, 0x02, 0x08, 0x3d, 0x00, 0x02, 0x0c, 0x3d, 0x00, 0x02, 0x10, 0x3d, 0x00, 0x02, 0x14, 0x3d, 0x00, 0x02, 0x18, 0x3d, 0x00, 0x02, 0x1c, 0x3d, 0x00, 0x02, 0x20, 0x3d, 0x00, 0x02, + 0xd8, 0x03, 0x01, 0x01, 0xda, 0x03, 0x01, 0x01, 0xdc, 0x03, 0x01, 0x01, 0xde, 0x03, 0x01, 0x01, 0xe0, 0x03, 0x01, 0x01, 0xe2, 0x03, 0x01, 0x01, 0xe4, 0x03, 0x01, 0x01, 0xe6, 0x03, 0x01, 0x01, + 0xe8, 0x03, 0x01, 0x01, 0x88, 0x23, 0x02, 0x03, 0x90, 0x23, 0x02, 0x03, 0x98, 0x23, 0x02, 0x03, 0xa0, 0x23, 0x02, 0x03, 0xb0, 0x09, 0x03, 0x04, 0x40, 0x2e, 0x04, 0x06, 0x24, 0x3d, 0x00, 0x02, + 0x28, 0x3d, 0x00, 0x02, 0x2c, 0x3d, 0x00, 0x02, 0x30, 0x3d, 0x00, 0x02, 0x34, 0x3d, 0x00, 0x02, 0x38, 0x3d, 0x00, 0x02, 0x3c, 0x3d, 0x00, 0x02, 0x40, 0x3d, 0x00, 0x02, 0x44, 0x3d, 0x00, 0x02, + 0xea, 0x03, 0x01, 0x01, 0xec, 0x03, 0x01, 0x01, 0xee, 0x03, 0x01, 0x01, 0xf0, 0x03, 0x01, 0x01, 0xf2, 0x03, 0x01, 0x01, 0xf4, 0x03, 0x01, 0x01, 0xf6, 0x03, 0x01, 0x01, 0xf8, 0x03, 0x01, 0x01, + 0xfa, 0x03, 0x01, 0x01, 0xa8, 0x23, 0x02, 0x03, 0xb0, 0x23, 0x02, 0x03, 0xb8, 0x23, 0x02, 0x03, 0xc0, 0x23, 0x02, 0x03, 0xc0, 0x09, 0x03, 0x04, 0x80, 0x2e, 0x04, 0x06, 0x48, 0x3d, 0x00, 0x02, + 0x4c, 0x3d, 0x00, 0x02, 0x50, 0x3d, 0x00, 0x02, 0x54, 0x3d, 0x00, 0x02, 0x58, 0x3d, 0x00, 0x02, 0x5c, 0x3d, 0x00, 0x02, 0x60, 0x3d, 0x00, 0x02, 0x64, 0x3d, 0x00, 0x02, 0x68, 0x3d, 0x00, 0x02, + 0xfc, 0x03, 0x01, 0x01, 0xfe, 0x03, 0x01, 0x01, 0x00, 0x04, 0x01, 0x01, 0x02, 0x04, 0x01, 0x01, 0x04, 0x04, 0x01, 0x01, 0x06, 0x04, 0x01, 0x01, 0x08, 0x04, 0x01, 0x01, 0x0a, 0x04, 0x01, 0x01, + 0x0c, 0x04, 0x01, 0x01, 0xc8, 0x23, 0x02, 0x03, 0xd0, 0x23, 0x02, 0x03, 0xd8, 0x23, 0x02, 0x03, 0xe0, 0x23, 0x02, 0x03, 0xd0, 0x09, 0x03, 0x04, 0xc0, 0x2e, 0x04, 0x06, 0x6c, 0x3d, 0x00, 0x02, + 0x70, 0x3d, 0x00, 0x02, 0x74, 0x3d, 0x00, 0x02, 0x78, 0x3d, 0x00, 0x02, 0x7c, 0x3d, 0x00, 0x02, 0x80, 0x3d, 0x00, 0x02, 0x84, 0x3d, 0x00, 0x02, 0x88, 0x3d, 0x00, 0x02, 0x8c, 0x3d, 0x00, 0x02, + 0x0e, 0x04, 0x01, 0x01, 0x10, 0x04, 0x01, 0x01, 0x12, 0x04, 0x01, 0x01, 0x14, 0x04, 0x01, 0x01, 0x16, 0x04, 0x01, 0x01, 0x18, 0x04, 0x01, 0x01, 0x1a, 0x04, 0x01, 0x01, 0x1c, 0x04, 0x01, 0x01, + 0x1e, 0x04, 0x01, 0x01, 0xe8, 0x23, 0x02, 0x03, 0xf0, 0x23, 0x02, 0x03, 0xf8, 0x23, 0x02, 0x03, 0x00, 0x24, 0x02, 0x03, 0xe0, 0x09, 0x03, 0x04, 0x00, 0x2f, 0x04, 0x06, 0x90, 0x3d, 0x00, 0x02, + 0x94, 0x3d, 0x00, 0x02, 0x98, 0x3d, 0x00, 0x02, 0x9c, 0x3d, 0x00, 0x02, 0xa0, 0x3d, 0x00, 0x02, 0xa4, 0x3d, 0x00, 0x02, 0xa8, 0x3d, 0x00, 0x02, 0xac, 0x3d, 0x00, 0x02, 0xb0, 0x3d, 0x00, 0x02, + 0x20, 0x04, 0x01, 0x01, 0x22, 0x04, 0x01, 0x01, 0x24, 0x04, 0x01, 0x01, 0x26, 0x04, 0x01, 0x01, 0x28, 0x04, 0x01, 0x01, 0x2a, 0x04, 0x01, 0x01, 0x2c, 0x04, 0x01, 0x01, 0x2e, 0x04, 0x01, 0x01, + 0x30, 0x04, 0x01, 0x01, 0x08, 0x24, 0x02, 0x03, 0x10, 0x24, 0x02, 0x03, 0x18, 0x24, 0x02, 0x03, 0x20, 0x24, 0x02, 0x03, 0xf0, 0x09, 0x03, 0x04, 0x40, 0x2f, 0x04, 0x06, 0xb4, 0x3d, 0x00, 0x02, + 0xb8, 0x3d, 0x00, 0x02, 0xbc, 0x3d, 0x00, 0x02, 0xc0, 0x3d, 0x00, 0x02, 0xc4, 0x3d, 0x00, 0x02, 0xc8, 0x3d, 0x00, 0x02, 0xcc, 0x3d, 0x00, 0x02, 0xd0, 0x3d, 0x00, 0x02, 0xd4, 0x3d, 0x00, 0x02, + 0x32, 0x04, 0x01, 0x01, 0x34, 0x04, 0x01, 0x01, 0x36, 0x04, 0x01, 0x01, 0x38, 0x04, 0x01, 0x01, 0x3a, 0x04, 0x01, 0x01, 0x3c, 0x04, 0x01, 0x01, 0x3e, 0x04, 0x01, 0x01, 0x40, 0x04, 0x01, 0x01, + 0x42, 0x04, 0x01, 0x01, 0x28, 0x24, 0x02, 0x03, 0x30, 0x24, 0x02, 0x03, 0x38, 0x24, 0x02, 0x03, 0x40, 0x24, 0x02, 0x03, 0x00, 0x0a, 0x03, 0x04, 0x80, 0x0a, 0x05, 0x07, 0xd8, 0x3d, 0x00, 0x02, + 0xdc, 0x3d, 0x00, 0x02, 0xe0, 0x3d, 0x00, 0x02, 0xe4, 0x3d, 0x00, 0x02, 0xe8, 0x3d, 0x00, 0x02, 0xec, 0x3d, 0x00, 0x02, 0xf0, 0x3d, 0x00, 0x02, 0xf4, 0x3d, 0x00, 0x02, 0xf8, 0x3d, 0x00, 0x02, + 0x44, 0x04, 0x01, 0x01, 0x46, 0x04, 0x01, 0x01, 0x48, 0x04, 0x01, 0x01, 0x4a, 0x04, 0x01, 0x01, 0x4c, 0x04, 0x01, 0x01, 0x4e, 0x04, 0x01, 0x01, 0x50, 0x04, 0x01, 0x01, 0x52, 0x04, 0x01, 0x01, + 0x54, 0x04, 0x01, 0x01, 0x48, 0x24, 0x02, 0x03, 0x50, 0x24, 0x02, 0x03, 0x58, 0x24, 0x02, 0x03, 0x60, 0x24, 0x02, 0x03, 0x10, 0x0a, 0x03, 0x04, 0x00, 0x0b, 0x05, 0x07, 0xfc, 0x3d, 0x00, 0x02, + 0x00, 0x3e, 0x00, 0x02, 0x04, 0x3e, 0x00, 0x02, 0x08, 0x3e, 0x00, 0x02, 0x0c, 0x3e, 0x00, 0x02, 0x10, 0x3e, 0x00, 0x02, 0x14, 0x3e, 0x00, 0x02, 0x18, 0x3e, 0x00, 0x02, 0x1c, 0x3e, 0x00, 0x02, + 0x56, 0x04, 0x01, 0x01, 0x58, 0x04, 0x01, 0x01, 0x5a, 0x04, 0x01, 0x01, 0x5c, 0x04, 0x01, 0x01, 0x5e, 0x04, 0x01, 0x01, 0x60, 0x04, 0x01, 0x01, 0x62, 0x04, 0x01, 0x01, 0x64, 0x04, 0x01, 0x01, + 0x66, 0x04, 0x01, 0x01, 0x68, 0x24, 0x02, 0x03, 0x70, 0x24, 0x02, 0x03, 0x78, 0x24, 0x02, 0x03, 0x80, 0x24, 0x02, 0x03, 0x20, 0x0a, 0x03, 0x04, 0x80, 0x0b, 0x05, 0x07, 0x20, 0x3e, 0x00, 0x02, + 0x24, 0x3e, 0x00, 0x02, 0x28, 0x3e, 0x00, 0x02, 0x2c, 0x3e, 0x00, 0x02, 0x30, 0x3e, 0x00, 0x02, 0x34, 0x3e, 0x00, 0x02, 0x38, 0x3e, 0x00, 0x02, 0x3c, 0x3e, 0x00, 0x02, 0x40, 0x3e, 0x00, 0x02, + 0x68, 0x04, 0x01, 0x01, 0x6a, 0x04, 0x01, 0x01, 0x6c, 0x04, 0x01, 0x01, 0x6e, 0x04, 0x01, 0x01, 0x70, 0x04, 0x01, 0x01, 0x72, 0x04, 0x01, 0x01, 0x74, 0x04, 0x01, 0x01, 0x76, 0x04, 0x01, 0x01, + 0x78, 0x04, 0x01, 0x01, 0x88, 0x24, 0x02, 0x03, 0x90, 0x24, 0x02, 0x03, 0x98, 0x24, 0x02, 0x03, 0xa0, 0x24, 0x02, 0x03, 0x30, 0x0a, 0x03, 0x04, 0x00, 0x0c, 0x05, 0x07, 0x44, 0x3e, 0x00, 0x02, + 0x48, 0x3e, 0x00, 0x02, 0x4c, 0x3e, 0x00, 0x02, 0x50, 0x3e, 0x00, 0x02, 0x54, 0x3e, 0x00, 0x02, 0x58, 0x3e, 0x00, 0x02, 0x5c, 0x3e, 0x00, 0x02, 0x60, 0x3e, 0x00, 0x02, 0x64, 0x3e, 0x00, 0x02, + 0x7a, 0x04, 0x01, 0x01, 0x7c, 0x04, 0x01, 0x01, 0x7e, 0x04, 0x01, 0x01, 0x80, 0x04, 0x01, 0x01, 0x82, 0x04, 0x01, 0x01, 0x84, 0x04, 0x01, 0x01, 0x86, 0x04, 0x01, 0x01, 0x88, 0x04, 0x01, 0x01, + 0x8a, 0x04, 0x01, 0x01, 0xa8, 0x24, 0x02, 0x03, 0xb0, 0x24, 0x02, 0x03, 0xb8, 0x24, 0x02, 0x03, 0xc0, 0x24, 0x02, 0x03, 0x40, 0x0a, 0x03, 0x04, 0x80, 0x0c, 0x05, 0x07, 0x68, 0x3e, 0x00, 0x02, + 0x6c, 0x3e, 0x00, 0x02, 0x70, 0x3e, 0x00, 0x02, 0x74, 0x3e, 0x00, 0x02, 0x78, 0x3e, 0x00, 0x02, 0x7c, 0x3e, 0x00, 0x02, 0x80, 0x3e, 0x00, 0x02, 0x84, 0x3e, 0x00, 0x02, 0x88, 0x3e, 0x00, 0x02, + 0x8c, 0x04, 0x01, 0x01, 0x8e, 0x04, 0x01, 0x01, 0x90, 0x04, 0x01, 0x01, 0x92, 0x04, 0x01, 0x01, 0x94, 0x04, 0x01, 0x01, 0x96, 0x04, 0x01, 0x01, 0x98, 0x04, 0x01, 0x01, 0x9a, 0x04, 0x01, 0x01, + 0x9c, 0x04, 0x01, 0x01, 0xc8, 0x24, 0x02, 0x03, 0xd0, 0x24, 0x02, 0x03, 0xd8, 0x24, 0x02, 0x03, 0xe0, 0x24, 0x02, 0x03, 0x50, 0x0a, 0x03, 0x04, 0x00, 0x0d, 0x05, 0x07, 0x8c, 0x3e, 0x00, 0x02, + 0x90, 0x3e, 0x00, 0x02, 0x94, 0x3e, 0x00, 0x02, 0x98, 0x3e, 0x00, 0x02, 0x9c, 0x3e, 0x00, 0x02, 0xa0, 0x3e, 0x00, 0x02, 0xa4, 0x3e, 0x00, 0x02, 0xa8, 0x3e, 0x00, 0x02, 0xac, 0x3e, 0x00, 0x02, + 0x9e, 0x04, 0x01, 0x01, 0xa0, 0x04, 0x01, 0x01, 0xa2, 0x04, 0x01, 0x01, 0xa4, 0x04, 0x01, 0x01, 0xa6, 0x04, 0x01, 0x01, 0xa8, 0x04, 0x01, 0x01, 0xaa, 0x04, 0x01, 0x01, 0xac, 0x04, 0x01, 0x01, + 0xae, 0x04, 0x01, 0x01, 0xe8, 0x24, 0x02, 0x03, 0xf0, 0x24, 0x02, 0x03, 0xf8, 0x24, 0x02, 0x03, 0x00, 0x25, 0x02, 0x03, 0x60, 0x0a, 0x03, 0x04, 0x80, 0x0d, 0x05, 0x07, 0xb0, 0x3e, 0x00, 0x02, + 0xb4, 0x3e, 0x00, 0x02, 0xb8, 0x3e, 0x00, 0x02, 0xbc, 0x3e, 0x00, 0x02, 0xc0, 0x3e, 0x00, 0x02, 0xc4, 0x3e, 0x00, 0x02, 0xc8, 0x3e, 0x00, 0x02, 0xcc, 0x3e, 0x00, 0x02, 0xd0, 0x3e, 0x00, 0x02, + 0xb0, 0x04, 0x01, 0x01, 0xb2, 0x04, 0x01, 0x01, 0xb4, 0x04, 0x01, 0x01, 0xb6, 0x04, 0x01, 0x01, 0xb8, 0x04, 0x01, 0x01, 0xba, 0x04, 0x01, 0x01, 0xbc, 0x04, 0x01, 0x01, 0xbe, 0x04, 0x01, 0x01, + 0xc0, 0x04, 0x01, 0x01, 0x08, 0x25, 0x02, 0x03, 0x10, 0x25, 0x02, 0x03, 0x18, 0x25, 0x02, 0x03, 0x20, 0x25, 0x02, 0x03, 0x70, 0x0a, 0x03, 0x04, 0x00, 0x0e, 0x05, 0x07, 0xd4, 0x3e, 0x00, 0x02, + 0xd8, 0x3e, 0x00, 0x02, 0xdc, 0x3e, 0x00, 0x02, 0xe0, 0x3e, 0x00, 0x02, 0xe4, 0x3e, 0x00, 0x02, 0xe8, 0x3e, 0x00, 0x02, 0xec, 0x3e, 0x00, 0x02, 0xf0, 0x3e, 0x00, 0x02, 0xf4, 0x3e, 0x00, 0x02, + 0xc2, 0x04, 0x01, 0x01, 0xc4, 0x04, 0x01, 0x01, 0xc6, 0x04, 0x01, 0x01, 0xc8, 0x04, 0x01, 0x01, 0xca, 0x04, 0x01, 0x01, 0xcc, 0x04, 0x01, 0x01, 0xce, 0x04, 0x01, 0x01, 0xd0, 0x04, 0x01, 0x01, + 0xd2, 0x04, 0x01, 0x01, 0x28, 0x25, 0x02, 0x03, 0x30, 0x25, 0x02, 0x03, 0x38, 0x25, 0x02, 0x03, 0x40, 0x25, 0x02, 0x03, 0x80, 0x0a, 0x03, 0x04, 0x80, 0x0e, 0x05, 0x07, 0xf8, 0x3e, 0x00, 0x02, + 0xfc, 0x3e, 0x00, 0x02, 0x00, 0x3f, 0x00, 0x02, 0x04, 0x3f, 0x00, 0x02, 0x08, 0x3f, 0x00, 0x02, 0x0c, 0x3f, 0x00, 0x02, 0x10, 0x3f, 0x00, 0x02, 0x14, 0x3f, 0x00, 0x02, 0xd4, 0x04, 0x01, 0x01, + 0xd6, 0x04, 0x01, 0x01, 0xd8, 0x04, 0x01, 0x01, 0xda, 0x04, 0x01, 0x01, 0xdc, 0x04, 0x01, 0x01, 0xde, 0x04, 0x01, 0x01, 0xe0, 0x04, 0x01, 0x01, 0xe2, 0x04, 0x01, 0x01, 0xe4, 0x04, 0x01, 0x01, + 0xe6, 0x04, 0x01, 0x01, 0x48, 0x25, 0x02, 0x03, 0x50, 0x25, 0x02, 0x03, 0x58, 0x25, 0x02, 0x03, 0x60, 0x25, 0x02, 0x03, 0x90, 0x0a, 0x03, 0x04, 0x00, 0x0f, 0x05, 0x07, 0x18, 0x3f, 0x00, 0x02, + 0x1c, 0x3f, 0x00, 0x02, 0x20, 0x3f, 0x00, 0x02, 0x24, 0x3f, 0x00, 0x02, 0x28, 0x3f, 0x00, 0x02, 0x2c, 0x3f, 0x00, 0x02, 0x30, 0x3f, 0x00, 0x02, 0x34, 0x3f, 0x00, 0x02, 0xe8, 0x04, 0x01, 0x01, + 0xea, 0x04, 0x01, 0x01, 0xec, 0x04, 0x01, 0x01, 0xee, 0x04, 0x01, 0x01, 0xf0, 0x04, 0x01, 0x01, 0xf2, 0x04, 0x01, 0x01, 0xf4, 0x04, 0x01, 0x01, 0xf6, 0x04, 0x01, 0x01, 0xf8, 0x04, 0x01, 0x01, + 0xfa, 0x04, 0x01, 0x01, 0x68, 0x25, 0x02, 0x03, 0x70, 0x25, 0x02, 0x03, 0x78, 0x25, 0x02, 0x03, 0x80, 0x25, 0x02, 0x03, 0xa0, 0x0a, 0x03, 0x04, 0x80, 0x0f, 0x05, 0x07, 0x38, 0x3f, 0x00, 0x02, + 0x3c, 0x3f, 0x00, 0x02, 0x40, 0x3f, 0x00, 0x02, 0x44, 0x3f, 0x00, 0x02, 0x48, 0x3f, 0x00, 0x02, 0x4c, 0x3f, 0x00, 0x02, 0x50, 0x3f, 0x00, 0x02, 0x54, 0x3f, 0x00, 0x02, 0xfc, 0x04, 0x01, 0x01, + 0xfe, 0x04, 0x01, 0x01, 0x00, 0x05, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x05, 0x01, 0x01, 0x06, 0x05, 0x01, 0x01, 0x08, 0x05, 0x01, 0x01, 0x0a, 0x05, 0x01, 0x01, 0x0c, 0x05, 0x01, 0x01, + 0x0e, 0x05, 0x01, 0x01, 0x88, 0x25, 0x02, 0x03, 0x90, 0x25, 0x02, 0x03, 0x98, 0x25, 0x02, 0x03, 0xa0, 0x25, 0x02, 0x03, 0xb0, 0x0a, 0x03, 0x04, 0x00, 0x10, 0x05, 0x07, 0x58, 0x3f, 0x00, 0x02, + 0x5c, 0x3f, 0x00, 0x02, 0x60, 0x3f, 0x00, 0x02, 0x64, 0x3f, 0x00, 0x02, 0x68, 0x3f, 0x00, 0x02, 0x6c, 0x3f, 0x00, 0x02, 0x70, 0x3f, 0x00, 0x02, 0x74, 0x3f, 0x00, 0x02, 0x10, 0x05, 0x01, 0x01, + 0x12, 0x05, 0x01, 0x01, 0x14, 0x05, 0x01, 0x01, 0x16, 0x05, 0x01, 0x01, 0x18, 0x05, 0x01, 0x01, 0x1a, 0x05, 0x01, 0x01, 0x1c, 0x05, 0x01, 0x01, 0x1e, 0x05, 0x01, 0x01, 0x20, 0x05, 0x01, 0x01, + 0x22, 0x05, 0x01, 0x01, 0xa8, 0x25, 0x02, 0x03, 0xb0, 0x25, 0x02, 0x03, 0xb8, 0x25, 0x02, 0x03, 0xc0, 0x25, 0x02, 0x03, 0xc0, 0x0a, 0x03, 0x04, 0x80, 0x10, 0x05, 0x07, 0x78, 0x3f, 0x00, 0x02, + 0x7c, 0x3f, 0x00, 0x02, 0x80, 0x3f, 0x00, 0x02, 0x84, 0x3f, 0x00, 0x02, 0x88, 0x3f, 0x00, 0x02, 0x8c, 0x3f, 0x00, 0x02, 0x90, 0x3f, 0x00, 0x02, 0x94, 0x3f, 0x00, 0x02, 0x24, 0x05, 0x01, 0x01, + 0x26, 0x05, 0x01, 0x01, 0x28, 0x05, 0x01, 0x01, 0x2a, 0x05, 0x01, 0x01, 0x2c, 0x05, 0x01, 0x01, 0x2e, 0x05, 0x01, 0x01, 0x30, 0x05, 0x01, 0x01, 0x32, 0x05, 0x01, 0x01, 0x34, 0x05, 0x01, 0x01, + 0x36, 0x05, 0x01, 0x01, 0xc8, 0x25, 0x02, 0x03, 0xd0, 0x25, 0x02, 0x03, 0xd8, 0x25, 0x02, 0x03, 0xe0, 0x25, 0x02, 0x03, 0xd0, 0x0a, 0x03, 0x04, 0x00, 0x11, 0x05, 0x07, 0x98, 0x3f, 0x00, 0x02, + 0x9c, 0x3f, 0x00, 0x02, 0xa0, 0x3f, 0x00, 0x02, 0xa4, 0x3f, 0x00, 0x02, 0xa8, 0x3f, 0x00, 0x02, 0xac, 0x3f, 0x00, 0x02, 0xb0, 0x3f, 0x00, 0x02, 0xb4, 0x3f, 0x00, 0x02, 0x38, 0x05, 0x01, 0x01, + 0x3a, 0x05, 0x01, 0x01, 0x3c, 0x05, 0x01, 0x01, 0x3e, 0x05, 0x01, 0x01, 0x40, 0x05, 0x01, 0x01, 0x42, 0x05, 0x01, 0x01, 0x44, 0x05, 0x01, 0x01, 0x46, 0x05, 0x01, 0x01, 0x48, 0x05, 0x01, 0x01, + 0x4a, 0x05, 0x01, 0x01, 0xe8, 0x25, 0x02, 0x03, 0xf0, 0x25, 0x02, 0x03, 0xf8, 0x25, 0x02, 0x03, 0x00, 0x26, 0x02, 0x03, 0xe0, 0x0a, 0x03, 0x04, 0x80, 0x11, 0x05, 0x07, 0xb8, 0x3f, 0x00, 0x02, + 0xbc, 0x3f, 0x00, 0x02, 0xc0, 0x3f, 0x00, 0x02, 0xc4, 0x3f, 0x00, 0x02, 0xc8, 0x3f, 0x00, 0x02, 0xcc, 0x3f, 0x00, 0x02, 0xd0, 0x3f, 0x00, 0x02, 0xd4, 0x3f, 0x00, 0x02, 0x4c, 0x05, 0x01, 0x01, + 0x4e, 0x05, 0x01, 0x01, 0x50, 0x05, 0x01, 0x01, 0x52, 0x05, 0x01, 0x01, 0x54, 0x05, 0x01, 0x01, 0x56, 0x05, 0x01, 0x01, 0x58, 0x05, 0x01, 0x01, 0x5a, 0x05, 0x01, 0x01, 0x5c, 0x05, 0x01, 0x01, + 0x5e, 0x05, 0x01, 0x01, 0x08, 0x26, 0x02, 0x03, 0x10, 0x26, 0x02, 0x03, 0x18, 0x26, 0x02, 0x03, 0x20, 0x26, 0x02, 0x03, 0xf0, 0x0a, 0x03, 0x04, 0x00, 0x2e, 0x06, 0x09, 0xd8, 0x3f, 0x00, 0x02, + 0xdc, 0x3f, 0x00, 0x02, 0xe0, 0x3f, 0x00, 0x02, 0xe4, 0x3f, 0x00, 0x02, 0xe8, 0x3f, 0x00, 0x02, 0xec, 0x3f, 0x00, 0x02, 0xf0, 0x3f, 0x00, 0x02, 0xf4, 0x3f, 0x00, 0x02, 0x60, 0x05, 0x01, 0x01, + 0x62, 0x05, 0x01, 0x01, 0x64, 0x05, 0x01, 0x01, 0x66, 0x05, 0x01, 0x01, 0x68, 0x05, 0x01, 0x01, 0x6a, 0x05, 0x01, 0x01, 0x6c, 0x05, 0x01, 0x01, 0x6e, 0x05, 0x01, 0x01, 0x70, 0x05, 0x01, 0x01, + 0x72, 0x05, 0x01, 0x01, 0x28, 0x26, 0x02, 0x03, 0x30, 0x26, 0x02, 0x03, 0x38, 0x26, 0x02, 0x03, 0x40, 0x26, 0x02, 0x03, 0x00, 0x0b, 0x03, 0x04, 0x00, 0x30, 0x06, 0x09, 0xf8, 0x3f, 0x00, 0x02, + 0xfc, 0x3f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x74, 0x05, 0x01, 0x01, + 0x76, 0x05, 0x01, 0x01, 0x78, 0x05, 0x01, 0x01, 0x7a, 0x05, 0x01, 0x01, 0x7c, 0x05, 0x01, 0x01, 0x7e, 0x05, 0x01, 0x01, 0x80, 0x05, 0x01, 0x01, 0x82, 0x05, 0x01, 0x01, 0x84, 0x05, 0x01, 0x01, + 0x86, 0x05, 0x01, 0x01, 0x48, 0x26, 0x02, 0x03, 0x50, 0x26, 0x02, 0x03, 0x58, 0x26, 0x02, 0x03, 0x60, 0x26, 0x02, 0x03, 0x10, 0x0b, 0x03, 0x04, 0x00, 0x32, 0x06, 0x09, 0x0c, 0x00, 0x00, 0x01, + 0x0e, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x01, 0x16, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x01, 0x88, 0x05, 0x01, 0x01, + 0x8a, 0x05, 0x01, 0x01, 0x8c, 0x05, 0x01, 0x01, 0x8e, 0x05, 0x01, 0x01, 0x90, 0x05, 0x01, 0x01, 0x92, 0x05, 0x01, 0x01, 0x94, 0x05, 0x01, 0x01, 0x96, 0x05, 0x01, 0x01, 0x98, 0x05, 0x01, 0x01, + 0x9a, 0x05, 0x01, 0x01, 0x68, 0x26, 0x02, 0x03, 0x70, 0x26, 0x02, 0x03, 0x78, 0x26, 0x02, 0x03, 0x80, 0x26, 0x02, 0x03, 0x20, 0x0b, 0x03, 0x04, 0x00, 0x34, 0x06, 0x09, 0x1c, 0x00, 0x00, 0x01, + 0x1e, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x01, 0x26, 0x00, 0x00, 0x01, 0x28, 0x00, 0x00, 0x01, 0x2a, 0x00, 0x00, 0x01, 0x9c, 0x05, 0x01, 0x01, + 0x9e, 0x05, 0x01, 0x01, 0xa0, 0x05, 0x01, 0x01, 0xa2, 0x05, 0x01, 0x01, 0xa4, 0x05, 0x01, 0x01, 0xa6, 0x05, 0x01, 0x01, 0xa8, 0x05, 0x01, 0x01, 0xaa, 0x05, 0x01, 0x01, 0xac, 0x05, 0x01, 0x01, + 0xae, 0x05, 0x01, 0x01, 0x88, 0x26, 0x02, 0x03, 0x90, 0x26, 0x02, 0x03, 0x98, 0x26, 0x02, 0x03, 0x30, 0x0b, 0x03, 0x04, 0x40, 0x0b, 0x03, 0x04, 0x00, 0x36, 0x06, 0x09, 0x2c, 0x00, 0x00, 0x01, + 0x2e, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x01, 0x32, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x00, 0x01, 0xb0, 0x05, 0x01, 0x01, + 0xb2, 0x05, 0x01, 0x01, 0xb4, 0x05, 0x01, 0x01, 0xb6, 0x05, 0x01, 0x01, 0xb8, 0x05, 0x01, 0x01, 0xba, 0x05, 0x01, 0x01, 0xbc, 0x05, 0x01, 0x01, 0xbe, 0x05, 0x01, 0x01, 0xc0, 0x05, 0x01, 0x01, + 0xc2, 0x05, 0x01, 0x01, 0xa0, 0x26, 0x02, 0x03, 0xa8, 0x26, 0x02, 0x03, 0xb0, 0x26, 0x02, 0x03, 0x50, 0x0b, 0x03, 0x04, 0x60, 0x0b, 0x03, 0x04, 0x00, 0x14, 0x07, 0x0a, 0x3c, 0x00, 0x00, 0x01, + 0x3e, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x42, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00, 0x01, 0x46, 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x01, 0x4a, 0x00, 0x00, 0x01, 0xc4, 0x05, 0x01, 0x01, + 0xc6, 0x05, 0x01, 0x01, 0xc8, 0x05, 0x01, 0x01, 0xca, 0x05, 0x01, 0x01, 0xcc, 0x05, 0x01, 0x01, 0xce, 0x05, 0x01, 0x01, 0xd0, 0x05, 0x01, 0x01, 0xd2, 0x05, 0x01, 0x01, 0xd4, 0x05, 0x01, 0x01, + 0xd6, 0x05, 0x01, 0x01, 0xb8, 0x26, 0x02, 0x03, 0xc0, 0x26, 0x02, 0x03, 0xc8, 0x26, 0x02, 0x03, 0x70, 0x0b, 0x03, 0x04, 0x80, 0x0b, 0x03, 0x04, 0x00, 0x18, 0x07, 0x0a, 0x4c, 0x00, 0x00, 0x01, + 0x4e, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x01, 0x52, 0x00, 0x00, 0x01, 0x54, 0x00, 0x00, 0x01, 0x56, 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x01, 0x5a, 0x00, 0x00, 0x01, 0xd8, 0x05, 0x01, 0x01, + 0xda, 0x05, 0x01, 0x01, 0xdc, 0x05, 0x01, 0x01, 0xde, 0x05, 0x01, 0x01, 0xe0, 0x05, 0x01, 0x01, 0xe2, 0x05, 0x01, 0x01, 0xe4, 0x05, 0x01, 0x01, 0xe6, 0x05, 0x01, 0x01, 0xe8, 0x05, 0x01, 0x01, + 0xea, 0x05, 0x01, 0x01, 0xd0, 0x26, 0x02, 0x03, 0xd8, 0x26, 0x02, 0x03, 0xe0, 0x26, 0x02, 0x03, 0x90, 0x0b, 0x03, 0x04, 0xa0, 0x0b, 0x03, 0x04, 0x00, 0x00, 0x08, 0x0b, 0x5c, 0x00, 0x00, 0x01, + 0x5e, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00, 0x01, 0x64, 0x00, 0x00, 0x01, 0x66, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x01, 0x6a, 0x00, 0x00, 0x01, 0xec, 0x05, 0x01, 0x01, + 0xee, 0x05, 0x01, 0x01, 0xf0, 0x05, 0x01, 0x01, 0xf2, 0x05, 0x01, 0x01, 0xf4, 0x05, 0x01, 0x01, 0xf6, 0x05, 0x01, 0x01, 0xf8, 0x05, 0x01, 0x01, 0xfa, 0x05, 0x01, 0x01, 0xfc, 0x05, 0x01, 0x01, + 0xfe, 0x05, 0x01, 0x01, 0xe8, 0x26, 0x02, 0x03, 0xf0, 0x26, 0x02, 0x03, 0xf8, 0x26, 0x02, 0x03, 0xb0, 0x0b, 0x03, 0x04, 0xc0, 0x0b, 0x03, 0x04, 0x00, 0x00, 0x09, 0x0d, 0x6c, 0x00, 0x00, 0x01, + 0x6e, 0x00, 0x00, 0x01, 0x70, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00, 0x01, 0x74, 0x00, 0x00, 0x01, 0x76, 0x00, 0x00, 0x01, 0x78, 0x00, 0x00, 0x01, 0x7a, 0x00, 0x00, 0x01, 0x00, 0x06, 0x01, 0x01, + 0x02, 0x06, 0x01, 0x01, 0x04, 0x06, 0x01, 0x01, 0x06, 0x06, 0x01, 0x01, 0x08, 0x06, 0x01, 0x01, 0x0a, 0x06, 0x01, 0x01, 0x0c, 0x06, 0x01, 0x01, 0x0e, 0x06, 0x01, 0x01, 0x10, 0x06, 0x01, 0x01, + 0x12, 0x06, 0x01, 0x01, 0x00, 0x27, 0x02, 0x03, 0x08, 0x27, 0x02, 0x03, 0x10, 0x27, 0x02, 0x03, 0xd0, 0x0b, 0x03, 0x04, 0xe0, 0x0b, 0x03, 0x04, 0x7c, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x01, 0x82, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x01, 0x86, 0x00, 0x00, 0x01, 0x88, 0x00, 0x00, 0x01, 0x8a, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x01, 0x14, 0x06, 0x01, 0x01, + 0x16, 0x06, 0x01, 0x01, 0x18, 0x06, 0x01, 0x01, 0x1a, 0x06, 0x01, 0x01, 0x1c, 0x06, 0x01, 0x01, 0x1e, 0x06, 0x01, 0x01, 0x20, 0x06, 0x01, 0x01, 0x22, 0x06, 0x01, 0x01, 0x24, 0x06, 0x01, 0x01, + 0x26, 0x06, 0x01, 0x01, 0x18, 0x27, 0x02, 0x03, 0x20, 0x27, 0x02, 0x03, 0x28, 0x27, 0x02, 0x03, 0xf0, 0x0b, 0x03, 0x04, 0x00, 0x0c, 0x03, 0x04, 0x8e, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x01, + 0x92, 0x00, 0x00, 0x01, 0x94, 0x00, 0x00, 0x01, 0x96, 0x00, 0x00, 0x01, 0x98, 0x00, 0x00, 0x01, 0x9a, 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x01, 0x9e, 0x00, 0x00, 0x01, 0x28, 0x06, 0x01, 0x01, + 0x2a, 0x06, 0x01, 0x01, 0x2c, 0x06, 0x01, 0x01, 0x2e, 0x06, 0x01, 0x01, 0x30, 0x06, 0x01, 0x01, 0x32, 0x06, 0x01, 0x01, 0x34, 0x06, 0x01, 0x01, 0x36, 0x06, 0x01, 0x01, 0x38, 0x06, 0x01, 0x01, + 0x3a, 0x06, 0x01, 0x01, 0x30, 0x27, 0x02, 0x03, 0x38, 0x27, 0x02, 0x03, 0x40, 0x27, 0x02, 0x03, 0x10, 0x0c, 0x03, 0x04, 0x20, 0x0c, 0x03, 0x04, 0xa0, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x01, + 0xa4, 0x00, 0x00, 0x01, 0xa6, 0x00, 0x00, 0x01, 0xa8, 0x00, 0x00, 0x01, 0xaa, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x01, 0xae, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x01, 0x3c, 0x06, 0x01, 0x01, + 0x3e, 0x06, 0x01, 0x01, 0x40, 0x06, 0x01, 0x01, 0x42, 0x06, 0x01, 0x01, 0x44, 0x06, 0x01, 0x01, 0x46, 0x06, 0x01, 0x01, 0x48, 0x06, 0x01, 0x01, 0x4a, 0x06, 0x01, 0x01, 0x4c, 0x06, 0x01, 0x01, + 0x4e, 0x06, 0x01, 0x01, 0x48, 0x27, 0x02, 0x03, 0x50, 0x27, 0x02, 0x03, 0x58, 0x27, 0x02, 0x03, 0x30, 0x0c, 0x03, 0x04, 0x40, 0x0c, 0x03, 0x04, 0xb2, 0x00, 0x00, 0x01, 0xb4, 0x00, 0x00, 0x01, + 0xb6, 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x01, 0xba, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x01, 0xbe, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x01, 0xc2, 0x00, 0x00, 0x01, 0x50, 0x06, 0x01, 0x01, + 0x52, 0x06, 0x01, 0x01, 0x54, 0x06, 0x01, 0x01, 0x56, 0x06, 0x01, 0x01, 0x58, 0x06, 0x01, 0x01, 0x5a, 0x06, 0x01, 0x01, 0x5c, 0x06, 0x01, 0x01, 0x5e, 0x06, 0x01, 0x01, 0x60, 0x06, 0x01, 0x01, + 0x62, 0x06, 0x01, 0x01, 0x60, 0x27, 0x02, 0x03, 0x68, 0x27, 0x02, 0x03, 0x70, 0x27, 0x02, 0x03, 0x50, 0x0c, 0x03, 0x04, 0x60, 0x0c, 0x03, 0x04, 0xc4, 0x00, 0x00, 0x01, 0xc6, 0x00, 0x00, 0x01, + 0xc8, 0x00, 0x00, 0x01, 0xca, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00, 0x01, 0xd0, 0x00, 0x00, 0x01, 0xd2, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x01, 0x64, 0x06, 0x01, 0x01, + 0x66, 0x06, 0x01, 0x01, 0x68, 0x06, 0x01, 0x01, 0x6a, 0x06, 0x01, 0x01, 0x6c, 0x06, 0x01, 0x01, 0x6e, 0x06, 0x01, 0x01, 0x70, 0x06, 0x01, 0x01, 0x72, 0x06, 0x01, 0x01, 0x74, 0x06, 0x01, 0x01, + 0x76, 0x06, 0x01, 0x01, 0x78, 0x27, 0x02, 0x03, 0x80, 0x27, 0x02, 0x03, 0x88, 0x27, 0x02, 0x03, 0x70, 0x0c, 0x03, 0x04, 0x80, 0x0c, 0x03, 0x04, 0xd6, 0x00, 0x00, 0x01, 0xd8, 0x00, 0x00, 0x01, + 0xda, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x01, 0xde, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe2, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, 0x01, 0xe6, 0x00, 0x00, 0x01, 0x78, 0x06, 0x01, 0x01, + 0x7a, 0x06, 0x01, 0x01, 0x7c, 0x06, 0x01, 0x01, 0x7e, 0x06, 0x01, 0x01, 0x80, 0x06, 0x01, 0x01, 0x82, 0x06, 0x01, 0x01, 0x84, 0x06, 0x01, 0x01, 0x86, 0x06, 0x01, 0x01, 0x88, 0x06, 0x01, 0x01, + 0x8a, 0x06, 0x01, 0x01, 0x90, 0x27, 0x02, 0x03, 0x98, 0x27, 0x02, 0x03, 0xa0, 0x27, 0x02, 0x03, 0x90, 0x0c, 0x03, 0x04, 0xa0, 0x0c, 0x03, 0x04, 0xe8, 0x00, 0x00, 0x01, 0xea, 0x00, 0x00, 0x01, + 0xec, 0x00, 0x00, 0x01, 0xee, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x01, 0xf2, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x01, 0xf6, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x01, 0x8c, 0x06, 0x01, 0x01, + 0x8e, 0x06, 0x01, 0x01, 0x90, 0x06, 0x01, 0x01, 0x92, 0x06, 0x01, 0x01, 0x94, 0x06, 0x01, 0x01, 0x96, 0x06, 0x01, 0x01, 0x98, 0x06, 0x01, 0x01, 0x9a, 0x06, 0x01, 0x01, 0x9c, 0x06, 0x01, 0x01, + 0x9e, 0x06, 0x01, 0x01, 0xa8, 0x27, 0x02, 0x03, 0xb0, 0x27, 0x02, 0x03, 0xb8, 0x27, 0x02, 0x03, 0xb0, 0x0c, 0x03, 0x04, 0xc0, 0x0c, 0x03, 0x04, 0xfa, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x01, + 0xfe, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01, 0x06, 0x01, 0x00, 0x01, 0x08, 0x01, 0x00, 0x01, 0x0a, 0x01, 0x00, 0x01, 0xa0, 0x06, 0x01, 0x01, + 0xa2, 0x06, 0x01, 0x01, 0xa4, 0x06, 0x01, 0x01, 0xa6, 0x06, 0x01, 0x01, 0xa8, 0x06, 0x01, 0x01, 0xaa, 0x06, 0x01, 0x01, 0xac, 0x06, 0x01, 0x01, 0xae, 0x06, 0x01, 0x01, 0xb0, 0x06, 0x01, 0x01, + 0xb2, 0x06, 0x01, 0x01, 0xc0, 0x27, 0x02, 0x03, 0xc8, 0x27, 0x02, 0x03, 0xd0, 0x27, 0x02, 0x03, 0xd0, 0x0c, 0x03, 0x04, 0xe0, 0x0c, 0x03, 0x04, 0x0c, 0x01, 0x00, 0x01, 0x0e, 0x01, 0x00, 0x01, + 0x10, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00, 0x01, 0x14, 0x01, 0x00, 0x01, 0x16, 0x01, 0x00, 0x01, 0x18, 0x01, 0x00, 0x01, 0x1a, 0x01, 0x00, 0x01, 0x1c, 0x01, 0x00, 0x01, 0xb4, 0x06, 0x01, 0x01, + 0xb6, 0x06, 0x01, 0x01, 0xb8, 0x06, 0x01, 0x01, 0xba, 0x06, 0x01, 0x01, 0xbc, 0x06, 0x01, 0x01, 0xbe, 0x06, 0x01, 0x01, 0xc0, 0x06, 0x01, 0x01, 0xc2, 0x06, 0x01, 0x01, 0xc4, 0x06, 0x01, 0x01, + 0xc6, 0x06, 0x01, 0x01, 0xd8, 0x27, 0x02, 0x03, 0xe0, 0x27, 0x02, 0x03, 0xe8, 0x27, 0x02, 0x03, 0xf0, 0x0c, 0x03, 0x04, 0x00, 0x0d, 0x03, 0x04, 0x1e, 0x01, 0x00, 0x01, 0x20, 0x01, 0x00, 0x01, + 0x22, 0x01, 0x00, 0x01, 0x24, 0x01, 0x00, 0x01, 0x26, 0x01, 0x00, 0x01, 0x28, 0x01, 0x00, 0x01, 0x2a, 0x01, 0x00, 0x01, 0x2c, 0x01, 0x00, 0x01, 0x2e, 0x01, 0x00, 0x01, 0xc8, 0x06, 0x01, 0x01, + 0xca, 0x06, 0x01, 0x01, 0xcc, 0x06, 0x01, 0x01, 0xce, 0x06, 0x01, 0x01, 0xd0, 0x06, 0x01, 0x01, 0xd2, 0x06, 0x01, 0x01, 0xd4, 0x06, 0x01, 0x01, 0xd6, 0x06, 0x01, 0x01, 0xd8, 0x06, 0x01, 0x01, + 0xda, 0x06, 0x01, 0x01, 0xf0, 0x27, 0x02, 0x03, 0xf8, 0x27, 0x02, 0x03, 0x00, 0x28, 0x02, 0x03, 0x10, 0x0d, 0x03, 0x04, 0x20, 0x0d, 0x03, 0x04, 0x30, 0x01, 0x00, 0x01, 0x32, 0x01, 0x00, 0x01, + 0x34, 0x01, 0x00, 0x01, 0x36, 0x01, 0x00, 0x01, 0x38, 0x01, 0x00, 0x01, 0x3a, 0x01, 0x00, 0x01, 0x3c, 0x01, 0x00, 0x01, 0x3e, 0x01, 0x00, 0x01, 0x40, 0x01, 0x00, 0x01, 0xdc, 0x06, 0x01, 0x01, + 0xde, 0x06, 0x01, 0x01, 0xe0, 0x06, 0x01, 0x01, 0xe2, 0x06, 0x01, 0x01, 0xe4, 0x06, 0x01, 0x01, 0xe6, 0x06, 0x01, 0x01, 0xe8, 0x06, 0x01, 0x01, 0xea, 0x06, 0x01, 0x01, 0xec, 0x06, 0x01, 0x01, + 0xee, 0x06, 0x01, 0x01, 0x08, 0x28, 0x02, 0x03, 0x10, 0x28, 0x02, 0x03, 0x18, 0x28, 0x02, 0x03, 0x30, 0x0d, 0x03, 0x04, 0x40, 0x0d, 0x03, 0x04, 0x42, 0x01, 0x00, 0x01, 0x44, 0x01, 0x00, 0x01, + 0x46, 0x01, 0x00, 0x01, 0x48, 0x01, 0x00, 0x01, 0x4a, 0x01, 0x00, 0x01, 0x4c, 0x01, 0x00, 0x01, 0x4e, 0x01, 0x00, 0x01, 0x50, 0x01, 0x00, 0x01, 0x52, 0x01, 0x00, 0x01, 0xf0, 0x06, 0x01, 0x01, + 0xf2, 0x06, 0x01, 0x01, 0xf4, 0x06, 0x01, 0x01, 0xf6, 0x06, 0x01, 0x01, 0xf8, 0x06, 0x01, 0x01, 0xfa, 0x06, 0x01, 0x01, 0xfc, 0x06, 0x01, 0x01, 0xfe, 0x06, 0x01, 0x01, 0x00, 0x07, 0x01, 0x01, + 0x02, 0x07, 0x01, 0x01, 0x20, 0x28, 0x02, 0x03, 0x28, 0x28, 0x02, 0x03, 0x30, 0x28, 0x02, 0x03, 0x50, 0x0d, 0x03, 0x04, 0x60, 0x0d, 0x03, 0x04, 0x54, 0x01, 0x00, 0x01, 0x56, 0x01, 0x00, 0x01, + 0x58, 0x01, 0x00, 0x01, 0x5a, 0x01, 0x00, 0x01, 0x5c, 0x01, 0x00, 0x01, 0x5e, 0x01, 0x00, 0x01, 0x60, 0x01, 0x00, 0x01, 0x62, 0x01, 0x00, 0x01, 0x64, 0x01, 0x00, 0x01, 0x04, 0x07, 0x01, 0x01, + 0x06, 0x07, 0x01, 0x01, 0x08, 0x07, 0x01, 0x01, 0x0a, 0x07, 0x01, 0x01, 0x0c, 0x07, 0x01, 0x01, 0x0e, 0x07, 0x01, 0x01, 0x10, 0x07, 0x01, 0x01, 0x12, 0x07, 0x01, 0x01, 0x14, 0x07, 0x01, 0x01, + 0x16, 0x07, 0x01, 0x01, 0x38, 0x28, 0x02, 0x03, 0x40, 0x28, 0x02, 0x03, 0x48, 0x28, 0x02, 0x03, 0x70, 0x0d, 0x03, 0x04, 0x80, 0x0d, 0x03, 0x04, 0x66, 0x01, 0x00, 0x01, 0x68, 0x01, 0x00, 0x01, + 0x6a, 0x01, 0x00, 0x01, 0x6c, 0x01, 0x00, 0x01, 0x6e, 0x01, 0x00, 0x01, 0x70, 0x01, 0x00, 0x01, 0x72, 0x01, 0x00, 0x01, 0x74, 0x01, 0x00, 0x01, 0x76, 0x01, 0x00, 0x01, 0x18, 0x07, 0x01, 0x01, + 0x1a, 0x07, 0x01, 0x01, 0x1c, 0x07, 0x01, 0x01, 0x1e, 0x07, 0x01, 0x01, 0x20, 0x07, 0x01, 0x01, 0x22, 0x07, 0x01, 0x01, 0x24, 0x07, 0x01, 0x01, 0x26, 0x07, 0x01, 0x01, 0x28, 0x07, 0x01, 0x01, + 0x2a, 0x07, 0x01, 0x01, 0x50, 0x28, 0x02, 0x03, 0x58, 0x28, 0x02, 0x03, 0x60, 0x28, 0x02, 0x03, 0x90, 0x0d, 0x03, 0x04, 0xa0, 0x0d, 0x03, 0x04, 0x78, 0x01, 0x00, 0x01, 0x7a, 0x01, 0x00, 0x01, + 0x7c, 0x01, 0x00, 0x01, 0x7e, 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x01, 0x82, 0x01, 0x00, 0x01, 0x84, 0x01, 0x00, 0x01, 0x86, 0x01, 0x00, 0x01, 0x88, 0x01, 0x00, 0x01, 0x2c, 0x07, 0x01, 0x01, + 0x2e, 0x07, 0x01, 0x01, 0x30, 0x07, 0x01, 0x01, 0x32, 0x07, 0x01, 0x01, 0x34, 0x07, 0x01, 0x01, 0x36, 0x07, 0x01, 0x01, 0x38, 0x07, 0x01, 0x01, 0x3a, 0x07, 0x01, 0x01, 0x3c, 0x07, 0x01, 0x01, + 0x3e, 0x07, 0x01, 0x01, 0x68, 0x28, 0x02, 0x03, 0x70, 0x28, 0x02, 0x03, 0x78, 0x28, 0x02, 0x03, 0xb0, 0x0d, 0x03, 0x04, 0xc0, 0x0d, 0x03, 0x04, 0x8a, 0x01, 0x00, 0x01, 0x8c, 0x01, 0x00, 0x01, + 0x8e, 0x01, 0x00, 0x01, 0x90, 0x01, 0x00, 0x01, 0x92, 0x01, 0x00, 0x01, 0x94, 0x01, 0x00, 0x01, 0x96, 0x01, 0x00, 0x01, 0x98, 0x01, 0x00, 0x01, 0x9a, 0x01, 0x00, 0x01, 0x40, 0x07, 0x01, 0x01, + 0x42, 0x07, 0x01, 0x01, 0x44, 0x07, 0x01, 0x01, 0x46, 0x07, 0x01, 0x01, 0x48, 0x07, 0x01, 0x01, 0x4a, 0x07, 0x01, 0x01, 0x4c, 0x07, 0x01, 0x01, 0x4e, 0x07, 0x01, 0x01, 0x50, 0x07, 0x01, 0x01, + 0x52, 0x07, 0x01, 0x01, 0x80, 0x28, 0x02, 0x03, 0x88, 0x28, 0x02, 0x03, 0x90, 0x28, 0x02, 0x03, 0xd0, 0x0d, 0x03, 0x04, 0xe0, 0x0d, 0x03, 0x04, 0x9c, 0x01, 0x00, 0x01, 0x9e, 0x01, 0x00, 0x01, + 0xa0, 0x01, 0x00, 0x01, 0xa2, 0x01, 0x00, 0x01, 0xa4, 0x01, 0x00, 0x01, 0xa6, 0x01, 0x00, 0x01, 0xa8, 0x01, 0x00, 0x01, 0xaa, 0x01, 0x00, 0x01, 0xac, 0x01, 0x00, 0x01, 0x54, 0x07, 0x01, 0x01, + 0x56, 0x07, 0x01, 0x01, 0x58, 0x07, 0x01, 0x01, 0x5a, 0x07, 0x01, 0x01, 0x5c, 0x07, 0x01, 0x01, 0x5e, 0x07, 0x01, 0x01, 0x60, 0x07, 0x01, 0x01, 0x62, 0x07, 0x01, 0x01, 0x64, 0x07, 0x01, 0x01, + 0x66, 0x07, 0x01, 0x01, 0x98, 0x28, 0x02, 0x03, 0xa0, 0x28, 0x02, 0x03, 0xa8, 0x28, 0x02, 0x03, 0xf0, 0x0d, 0x03, 0x04, 0x00, 0x0e, 0x03, 0x04, 0xae, 0x01, 0x00, 0x01, 0xb0, 0x01, 0x00, 0x01, + 0xb2, 0x01, 0x00, 0x01, 0xb4, 0x01, 0x00, 0x01, 0xb6, 0x01, 0x00, 0x01, 0xb8, 0x01, 0x00, 0x01, 0xba, 0x01, 0x00, 0x01, 0xbc, 0x01, 0x00, 0x01, 0xbe, 0x01, 0x00, 0x01, 0x68, 0x07, 0x01, 0x01, + 0x6a, 0x07, 0x01, 0x01, 0x6c, 0x07, 0x01, 0x01, 0x6e, 0x07, 0x01, 0x01, 0x70, 0x07, 0x01, 0x01, 0x72, 0x07, 0x01, 0x01, 0x74, 0x07, 0x01, 0x01, 0x76, 0x07, 0x01, 0x01, 0x78, 0x07, 0x01, 0x01, + 0x7a, 0x07, 0x01, 0x01, 0xb0, 0x28, 0x02, 0x03, 0xb8, 0x28, 0x02, 0x03, 0xc0, 0x28, 0x02, 0x03, 0x10, 0x0e, 0x03, 0x04, 0x20, 0x0e, 0x03, 0x04, 0xc0, 0x01, 0x00, 0x01, 0xc2, 0x01, 0x00, 0x01, + 0xc4, 0x01, 0x00, 0x01, 0xc6, 0x01, 0x00, 0x01, 0xc8, 0x01, 0x00, 0x01, 0xca, 0x01, 0x00, 0x01, 0xcc, 0x01, 0x00, 0x01, 0xce, 0x01, 0x00, 0x01, 0xd0, 0x01, 0x00, 0x01, 0x7c, 0x07, 0x01, 0x01, + 0x7e, 0x07, 0x01, 0x01, 0x80, 0x07, 0x01, 0x01, 0x82, 0x07, 0x01, 0x01, 0x84, 0x07, 0x01, 0x01, 0x86, 0x07, 0x01, 0x01, 0x88, 0x07, 0x01, 0x01, 0x8a, 0x07, 0x01, 0x01, 0x8c, 0x07, 0x01, 0x01, + 0x8e, 0x07, 0x01, 0x01, 0xc8, 0x28, 0x02, 0x03, 0xd0, 0x28, 0x02, 0x03, 0xd8, 0x28, 0x02, 0x03, 0x30, 0x0e, 0x03, 0x04, 0x40, 0x0e, 0x03, 0x04, 0xd2, 0x01, 0x00, 0x01, 0xd4, 0x01, 0x00, 0x01, + 0xd6, 0x01, 0x00, 0x01, 0xd8, 0x01, 0x00, 0x01, 0xda, 0x01, 0x00, 0x01, 0xdc, 0x01, 0x00, 0x01, 0xde, 0x01, 0x00, 0x01, 0xe0, 0x01, 0x00, 0x01, 0xe2, 0x01, 0x00, 0x01, 0x90, 0x07, 0x01, 0x01, + 0x92, 0x07, 0x01, 0x01, 0x94, 0x07, 0x01, 0x01, 0x96, 0x07, 0x01, 0x01, 0x98, 0x07, 0x01, 0x01, 0x9a, 0x07, 0x01, 0x01, 0x9c, 0x07, 0x01, 0x01, 0x9e, 0x07, 0x01, 0x01, 0xa0, 0x07, 0x01, 0x01, + 0xa2, 0x07, 0x01, 0x01, 0xe0, 0x28, 0x02, 0x03, 0xe8, 0x28, 0x02, 0x03, 0xf0, 0x28, 0x02, 0x03, 0x50, 0x0e, 0x03, 0x04, 0x60, 0x0e, 0x03, 0x04, 0xe4, 0x01, 0x00, 0x01, 0xe6, 0x01, 0x00, 0x01, + 0xe8, 0x01, 0x00, 0x01, 0xea, 0x01, 0x00, 0x01, 0xec, 0x01, 0x00, 0x01, 0xee, 0x01, 0x00, 0x01, 0xf0, 0x01, 0x00, 0x01, 0xf2, 0x01, 0x00, 0x01, 0xf4, 0x01, 0x00, 0x01, 0xa4, 0x07, 0x01, 0x01, + 0xa6, 0x07, 0x01, 0x01, 0xa8, 0x07, 0x01, 0x01, 0xaa, 0x07, 0x01, 0x01, 0xac, 0x07, 0x01, 0x01, 0xae, 0x07, 0x01, 0x01, 0xb0, 0x07, 0x01, 0x01, 0xb2, 0x07, 0x01, 0x01, 0xb4, 0x07, 0x01, 0x01, + 0xb6, 0x07, 0x01, 0x01, 0xf8, 0x28, 0x02, 0x03, 0x00, 0x29, 0x02, 0x03, 0x08, 0x29, 0x02, 0x03, 0x70, 0x0e, 0x03, 0x04, 0x80, 0x2f, 0x04, 0x06, 0xf6, 0x01, 0x00, 0x01, 0xf8, 0x01, 0x00, 0x01, + 0xfa, 0x01, 0x00, 0x01, 0xfc, 0x01, 0x00, 0x01, 0xfe, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0xb8, 0x07, 0x01, 0x01, + 0xba, 0x07, 0x01, 0x01, 0xbc, 0x07, 0x01, 0x01, 0xbe, 0x07, 0x01, 0x01, 0xc0, 0x07, 0x01, 0x01, 0xc2, 0x07, 0x01, 0x01, 0xc4, 0x07, 0x01, 0x01, 0xc6, 0x07, 0x01, 0x01, 0xc8, 0x07, 0x01, 0x01, + 0xca, 0x07, 0x01, 0x01, 0x10, 0x29, 0x02, 0x03, 0x18, 0x29, 0x02, 0x03, 0x20, 0x29, 0x02, 0x03, 0x80, 0x0e, 0x03, 0x04, 0xc0, 0x2f, 0x04, 0x06, 0x08, 0x02, 0x00, 0x01, 0x0a, 0x02, 0x00, 0x01, + 0x0c, 0x02, 0x00, 0x01, 0x0e, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x12, 0x02, 0x00, 0x01, 0x14, 0x02, 0x00, 0x01, 0x16, 0x02, 0x00, 0x01, 0x18, 0x02, 0x00, 0x01, 0xcc, 0x07, 0x01, 0x01, + 0xce, 0x07, 0x01, 0x01, 0xd0, 0x07, 0x01, 0x01, 0xd2, 0x07, 0x01, 0x01, 0xd4, 0x07, 0x01, 0x01, 0xd6, 0x07, 0x01, 0x01, 0xd8, 0x07, 0x01, 0x01, 0xda, 0x07, 0x01, 0x01, 0xdc, 0x07, 0x01, 0x01, + 0xde, 0x07, 0x01, 0x01, 0x28, 0x29, 0x02, 0x03, 0x30, 0x29, 0x02, 0x03, 0x38, 0x29, 0x02, 0x03, 0x90, 0x0e, 0x03, 0x04, 0x00, 0x30, 0x04, 0x06, 0x1a, 0x02, 0x00, 0x01, 0x1c, 0x02, 0x00, 0x01, + 0x1e, 0x02, 0x00, 0x01, 0x20, 0x02, 0x00, 0x01, 0x22, 0x02, 0x00, 0x01, 0x24, 0x02, 0x00, 0x01, 0x26, 0x02, 0x00, 0x01, 0x28, 0x02, 0x00, 0x01, 0x2a, 0x02, 0x00, 0x01, 0xe0, 0x07, 0x01, 0x01, + 0xe2, 0x07, 0x01, 0x01, 0xe4, 0x07, 0x01, 0x01, 0xe6, 0x07, 0x01, 0x01, 0xe8, 0x07, 0x01, 0x01, 0xea, 0x07, 0x01, 0x01, 0xec, 0x07, 0x01, 0x01, 0xee, 0x07, 0x01, 0x01, 0xf0, 0x07, 0x01, 0x01, + 0xf2, 0x07, 0x01, 0x01, 0x40, 0x29, 0x02, 0x03, 0x48, 0x29, 0x02, 0x03, 0x50, 0x29, 0x02, 0x03, 0xa0, 0x0e, 0x03, 0x04, 0x40, 0x30, 0x04, 0x06, 0x2c, 0x02, 0x00, 0x01, 0x2e, 0x02, 0x00, 0x01, + 0x30, 0x02, 0x00, 0x01, 0x32, 0x02, 0x00, 0x01, 0x34, 0x02, 0x00, 0x01, 0x36, 0x02, 0x00, 0x01, 0x38, 0x02, 0x00, 0x01, 0x3a, 0x02, 0x00, 0x01, 0x3c, 0x02, 0x00, 0x01, 0xf4, 0x07, 0x01, 0x01, + 0xf6, 0x07, 0x01, 0x01, 0xf8, 0x07, 0x01, 0x01, 0xfa, 0x07, 0x01, 0x01, 0xfc, 0x07, 0x01, 0x01, 0xfe, 0x07, 0x01, 0x01, 0x00, 0x08, 0x01, 0x01, 0x02, 0x08, 0x01, 0x01, 0x04, 0x08, 0x01, 0x01, + 0x06, 0x08, 0x01, 0x01, 0x58, 0x29, 0x02, 0x03, 0x60, 0x29, 0x02, 0x03, 0x68, 0x29, 0x02, 0x03, 0xb0, 0x0e, 0x03, 0x04, 0x80, 0x30, 0x04, 0x06, 0x3e, 0x02, 0x00, 0x01, 0x40, 0x02, 0x00, 0x01, + 0x42, 0x02, 0x00, 0x01, 0x44, 0x02, 0x00, 0x01, 0x46, 0x02, 0x00, 0x01, 0x48, 0x02, 0x00, 0x01, 0x4a, 0x02, 0x00, 0x01, 0x4c, 0x02, 0x00, 0x01, 0x4e, 0x02, 0x00, 0x01, 0x08, 0x08, 0x01, 0x01, + 0x0a, 0x08, 0x01, 0x01, 0x0c, 0x08, 0x01, 0x01, 0x0e, 0x08, 0x01, 0x01, 0x10, 0x08, 0x01, 0x01, 0x12, 0x08, 0x01, 0x01, 0x14, 0x08, 0x01, 0x01, 0x16, 0x08, 0x01, 0x01, 0x18, 0x08, 0x01, 0x01, + 0x1a, 0x08, 0x01, 0x01, 0x70, 0x29, 0x02, 0x03, 0x78, 0x29, 0x02, 0x03, 0x80, 0x29, 0x02, 0x03, 0xc0, 0x0e, 0x03, 0x04, 0xc0, 0x30, 0x04, 0x06, 0x50, 0x02, 0x00, 0x01, 0x52, 0x02, 0x00, 0x01, + 0x54, 0x02, 0x00, 0x01, 0x56, 0x02, 0x00, 0x01, 0x58, 0x02, 0x00, 0x01, 0x5a, 0x02, 0x00, 0x01, 0x5c, 0x02, 0x00, 0x01, 0x5e, 0x02, 0x00, 0x01, 0x60, 0x02, 0x00, 0x01, 0x1c, 0x08, 0x01, 0x01, + 0x1e, 0x08, 0x01, 0x01, 0x20, 0x08, 0x01, 0x01, 0x22, 0x08, 0x01, 0x01, 0x24, 0x08, 0x01, 0x01, 0x26, 0x08, 0x01, 0x01, 0x28, 0x08, 0x01, 0x01, 0x2a, 0x08, 0x01, 0x01, 0x2c, 0x08, 0x01, 0x01, + 0x2e, 0x08, 0x01, 0x01, 0x88, 0x29, 0x02, 0x03, 0x90, 0x29, 0x02, 0x03, 0x98, 0x29, 0x02, 0x03, 0xd0, 0x0e, 0x03, 0x04, 0x00, 0x31, 0x04, 0x06, 0x62, 0x02, 0x00, 0x01, 0x64, 0x02, 0x00, 0x01, + 0x66, 0x02, 0x00, 0x01, 0x68, 0x02, 0x00, 0x01, 0x6a, 0x02, 0x00, 0x01, 0x6c, 0x02, 0x00, 0x01, 0x6e, 0x02, 0x00, 0x01, 0x70, 0x02, 0x00, 0x01, 0x72, 0x02, 0x00, 0x01, 0x30, 0x08, 0x01, 0x01, + 0x32, 0x08, 0x01, 0x01, 0x34, 0x08, 0x01, 0x01, 0x36, 0x08, 0x01, 0x01, 0x38, 0x08, 0x01, 0x01, 0x3a, 0x08, 0x01, 0x01, 0x3c, 0x08, 0x01, 0x01, 0x3e, 0x08, 0x01, 0x01, 0x40, 0x08, 0x01, 0x01, + 0x42, 0x08, 0x01, 0x01, 0xa0, 0x29, 0x02, 0x03, 0xa8, 0x29, 0x02, 0x03, 0xb0, 0x29, 0x02, 0x03, 0xe0, 0x0e, 0x03, 0x04, 0x40, 0x31, 0x04, 0x06, 0x74, 0x02, 0x00, 0x01, 0x76, 0x02, 0x00, 0x01, + 0x78, 0x02, 0x00, 0x01, 0x7a, 0x02, 0x00, 0x01, 0x7c, 0x02, 0x00, 0x01, 0x7e, 0x02, 0x00, 0x01, 0x80, 0x02, 0x00, 0x01, 0x82, 0x02, 0x00, 0x01, 0x84, 0x02, 0x00, 0x01, 0x44, 0x08, 0x01, 0x01, + 0x46, 0x08, 0x01, 0x01, 0x48, 0x08, 0x01, 0x01, 0x4a, 0x08, 0x01, 0x01, 0x4c, 0x08, 0x01, 0x01, 0x4e, 0x08, 0x01, 0x01, 0x50, 0x08, 0x01, 0x01, 0x52, 0x08, 0x01, 0x01, 0x54, 0x08, 0x01, 0x01, + 0x56, 0x08, 0x01, 0x01, 0xb8, 0x29, 0x02, 0x03, 0xc0, 0x29, 0x02, 0x03, 0xc8, 0x29, 0x02, 0x03, 0xf0, 0x0e, 0x03, 0x04, 0x80, 0x31, 0x04, 0x06, 0x86, 0x02, 0x00, 0x01, 0x88, 0x02, 0x00, 0x01, + 0x8a, 0x02, 0x00, 0x01, 0x8c, 0x02, 0x00, 0x01, 0x8e, 0x02, 0x00, 0x01, 0x90, 0x02, 0x00, 0x01, 0x92, 0x02, 0x00, 0x01, 0x94, 0x02, 0x00, 0x01, 0x96, 0x02, 0x00, 0x01, 0x58, 0x08, 0x01, 0x01, + 0x5a, 0x08, 0x01, 0x01, 0x5c, 0x08, 0x01, 0x01, 0x5e, 0x08, 0x01, 0x01, 0x60, 0x08, 0x01, 0x01, 0x62, 0x08, 0x01, 0x01, 0x64, 0x08, 0x01, 0x01, 0x66, 0x08, 0x01, 0x01, 0x68, 0x08, 0x01, 0x01, + 0x6a, 0x08, 0x01, 0x01, 0xd0, 0x29, 0x02, 0x03, 0xd8, 0x29, 0x02, 0x03, 0xe0, 0x29, 0x02, 0x03, 0x00, 0x0f, 0x03, 0x04, 0xc0, 0x31, 0x04, 0x06, 0x98, 0x02, 0x00, 0x01, 0x9a, 0x02, 0x00, 0x01, + 0x9c, 0x02, 0x00, 0x01, 0x9e, 0x02, 0x00, 0x01, 0xa0, 0x02, 0x00, 0x01, 0xa2, 0x02, 0x00, 0x01, 0xa4, 0x02, 0x00, 0x01, 0xa6, 0x02, 0x00, 0x01, 0xa8, 0x02, 0x00, 0x01, 0x6c, 0x08, 0x01, 0x01, + 0x6e, 0x08, 0x01, 0x01, 0x70, 0x08, 0x01, 0x01, 0x72, 0x08, 0x01, 0x01, 0x74, 0x08, 0x01, 0x01, 0x76, 0x08, 0x01, 0x01, 0x78, 0x08, 0x01, 0x01, 0x7a, 0x08, 0x01, 0x01, 0x7c, 0x08, 0x01, 0x01, + 0x7e, 0x08, 0x01, 0x01, 0xe8, 0x29, 0x02, 0x03, 0xf0, 0x29, 0x02, 0x03, 0xf8, 0x29, 0x02, 0x03, 0x10, 0x0f, 0x03, 0x04, 0x00, 0x32, 0x04, 0x06, 0xaa, 0x02, 0x00, 0x01, 0xac, 0x02, 0x00, 0x01, + 0xae, 0x02, 0x00, 0x01, 0xb0, 0x02, 0x00, 0x01, 0xb2, 0x02, 0x00, 0x01, 0xb4, 0x02, 0x00, 0x01, 0xb6, 0x02, 0x00, 0x01, 0xb8, 0x02, 0x00, 0x01, 0xba, 0x02, 0x00, 0x01, 0x80, 0x08, 0x01, 0x01, + 0x82, 0x08, 0x01, 0x01, 0x84, 0x08, 0x01, 0x01, 0x86, 0x08, 0x01, 0x01, 0x88, 0x08, 0x01, 0x01, 0x8a, 0x08, 0x01, 0x01, 0x8c, 0x08, 0x01, 0x01, 0x8e, 0x08, 0x01, 0x01, 0x90, 0x08, 0x01, 0x01, + 0x92, 0x08, 0x01, 0x01, 0x00, 0x2a, 0x02, 0x03, 0x08, 0x2a, 0x02, 0x03, 0x10, 0x2a, 0x02, 0x03, 0x20, 0x0f, 0x03, 0x04, 0x40, 0x32, 0x04, 0x06, 0xbc, 0x02, 0x00, 0x01, 0xbe, 0x02, 0x00, 0x01, + 0xc0, 0x02, 0x00, 0x01, 0xc2, 0x02, 0x00, 0x01, 0xc4, 0x02, 0x00, 0x01, 0xc6, 0x02, 0x00, 0x01, 0xc8, 0x02, 0x00, 0x01, 0xca, 0x02, 0x00, 0x01, 0xcc, 0x02, 0x00, 0x01, 0x94, 0x08, 0x01, 0x01, + 0x96, 0x08, 0x01, 0x01, 0x98, 0x08, 0x01, 0x01, 0x9a, 0x08, 0x01, 0x01, 0x9c, 0x08, 0x01, 0x01, 0x9e, 0x08, 0x01, 0x01, 0xa0, 0x08, 0x01, 0x01, 0xa2, 0x08, 0x01, 0x01, 0xa4, 0x08, 0x01, 0x01, + 0xa6, 0x08, 0x01, 0x01, 0x18, 0x2a, 0x02, 0x03, 0x20, 0x2a, 0x02, 0x03, 0x28, 0x2a, 0x02, 0x03, 0x30, 0x0f, 0x03, 0x04, 0x80, 0x32, 0x04, 0x06, 0xce, 0x02, 0x00, 0x01, 0xd0, 0x02, 0x00, 0x01, + 0xd2, 0x02, 0x00, 0x01, 0xd4, 0x02, 0x00, 0x01, 0xd6, 0x02, 0x00, 0x01, 0xd8, 0x02, 0x00, 0x01, 0xda, 0x02, 0x00, 0x01, 0xdc, 0x02, 0x00, 0x01, 0xde, 0x02, 0x00, 0x01, 0xa8, 0x08, 0x01, 0x01, + 0xaa, 0x08, 0x01, 0x01, 0xac, 0x08, 0x01, 0x01, 0xae, 0x08, 0x01, 0x01, 0xb0, 0x08, 0x01, 0x01, 0xb2, 0x08, 0x01, 0x01, 0xb4, 0x08, 0x01, 0x01, 0xb6, 0x08, 0x01, 0x01, 0xb8, 0x08, 0x01, 0x01, + 0xba, 0x08, 0x01, 0x01, 0x30, 0x2a, 0x02, 0x03, 0x38, 0x2a, 0x02, 0x03, 0x40, 0x2a, 0x02, 0x03, 0x40, 0x0f, 0x03, 0x04, 0xc0, 0x32, 0x04, 0x06, 0xe0, 0x02, 0x00, 0x01, 0xe2, 0x02, 0x00, 0x01, + 0xe4, 0x02, 0x00, 0x01, 0xe6, 0x02, 0x00, 0x01, 0xe8, 0x02, 0x00, 0x01, 0xea, 0x02, 0x00, 0x01, 0xec, 0x02, 0x00, 0x01, 0xee, 0x02, 0x00, 0x01, 0xf0, 0x02, 0x00, 0x01, 0xbc, 0x08, 0x01, 0x01, + 0xbe, 0x08, 0x01, 0x01, 0xc0, 0x08, 0x01, 0x01, 0xc2, 0x08, 0x01, 0x01, 0xc4, 0x08, 0x01, 0x01, 0xc6, 0x08, 0x01, 0x01, 0xc8, 0x08, 0x01, 0x01, 0xca, 0x08, 0x01, 0x01, 0xcc, 0x08, 0x01, 0x01, + 0x48, 0x2a, 0x02, 0x03, 0x50, 0x2a, 0x02, 0x03, 0x58, 0x2a, 0x02, 0x03, 0x60, 0x2a, 0x02, 0x03, 0x50, 0x0f, 0x03, 0x04, 0x00, 0x33, 0x04, 0x06, 0xf2, 0x02, 0x00, 0x01, 0xf4, 0x02, 0x00, 0x01, + 0xf6, 0x02, 0x00, 0x01, 0xf8, 0x02, 0x00, 0x01, 0xfa, 0x02, 0x00, 0x01, 0xfc, 0x02, 0x00, 0x01, 0xfe, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0xce, 0x08, 0x01, 0x01, + 0xd0, 0x08, 0x01, 0x01, 0xd2, 0x08, 0x01, 0x01, 0xd4, 0x08, 0x01, 0x01, 0xd6, 0x08, 0x01, 0x01, 0xd8, 0x08, 0x01, 0x01, 0xda, 0x08, 0x01, 0x01, 0xdc, 0x08, 0x01, 0x01, 0xde, 0x08, 0x01, 0x01, + 0x68, 0x2a, 0x02, 0x03, 0x70, 0x2a, 0x02, 0x03, 0x78, 0x2a, 0x02, 0x03, 0x80, 0x2a, 0x02, 0x03, 0x60, 0x0f, 0x03, 0x04, 0x40, 0x33, 0x04, 0x06, 0x04, 0x03, 0x00, 0x01, 0x06, 0x03, 0x00, 0x01, + 0x08, 0x03, 0x00, 0x01, 0x0a, 0x03, 0x00, 0x01, 0x0c, 0x03, 0x00, 0x01, 0x0e, 0x03, 0x00, 0x01, 0x10, 0x03, 0x00, 0x01, 0x12, 0x03, 0x00, 0x01, 0x14, 0x03, 0x00, 0x01, 0xe0, 0x08, 0x01, 0x01, + 0xe2, 0x08, 0x01, 0x01, 0xe4, 0x08, 0x01, 0x01, 0xe6, 0x08, 0x01, 0x01, 0xe8, 0x08, 0x01, 0x01, 0xea, 0x08, 0x01, 0x01, 0xec, 0x08, 0x01, 0x01, 0xee, 0x08, 0x01, 0x01, 0xf0, 0x08, 0x01, 0x01, + 0x88, 0x2a, 0x02, 0x03, 0x90, 0x2a, 0x02, 0x03, 0x98, 0x2a, 0x02, 0x03, 0xa0, 0x2a, 0x02, 0x03, 0x70, 0x0f, 0x03, 0x04, 0x80, 0x33, 0x04, 0x06, 0x16, 0x03, 0x00, 0x01, 0x18, 0x03, 0x00, 0x01, + 0x1a, 0x03, 0x00, 0x01, 0x1c, 0x03, 0x00, 0x01, 0x1e, 0x03, 0x00, 0x01, 0x20, 0x03, 0x00, 0x01, 0x22, 0x03, 0x00, 0x01, 0x24, 0x03, 0x00, 0x01, 0x26, 0x03, 0x00, 0x01, 0xf2, 0x08, 0x01, 0x01, + 0xf4, 0x08, 0x01, 0x01, 0xf6, 0x08, 0x01, 0x01, 0xf8, 0x08, 0x01, 0x01, 0xfa, 0x08, 0x01, 0x01, 0xfc, 0x08, 0x01, 0x01, 0xfe, 0x08, 0x01, 0x01, 0x00, 0x09, 0x01, 0x01, 0x02, 0x09, 0x01, 0x01, + 0xa8, 0x2a, 0x02, 0x03, 0xb0, 0x2a, 0x02, 0x03, 0xb8, 0x2a, 0x02, 0x03, 0xc0, 0x2a, 0x02, 0x03, 0x80, 0x0f, 0x03, 0x04, 0xc0, 0x33, 0x04, 0x06, 0x28, 0x03, 0x00, 0x01, 0x2a, 0x03, 0x00, 0x01, + 0x2c, 0x03, 0x00, 0x01, 0x2e, 0x03, 0x00, 0x01, 0x30, 0x03, 0x00, 0x01, 0x32, 0x03, 0x00, 0x01, 0x34, 0x03, 0x00, 0x01, 0x36, 0x03, 0x00, 0x01, 0x38, 0x03, 0x00, 0x01, 0x04, 0x09, 0x01, 0x01, + 0x06, 0x09, 0x01, 0x01, 0x08, 0x09, 0x01, 0x01, 0x0a, 0x09, 0x01, 0x01, 0x0c, 0x09, 0x01, 0x01, 0x0e, 0x09, 0x01, 0x01, 0x10, 0x09, 0x01, 0x01, 0x12, 0x09, 0x01, 0x01, 0x14, 0x09, 0x01, 0x01, + 0xc8, 0x2a, 0x02, 0x03, 0xd0, 0x2a, 0x02, 0x03, 0xd8, 0x2a, 0x02, 0x03, 0xe0, 0x2a, 0x02, 0x03, 0x90, 0x0f, 0x03, 0x04, 0x00, 0x34, 0x04, 0x06, 0x3a, 0x03, 0x00, 0x01, 0x3c, 0x03, 0x00, 0x01, + 0x3e, 0x03, 0x00, 0x01, 0x40, 0x03, 0x00, 0x01, 0x42, 0x03, 0x00, 0x01, 0x44, 0x03, 0x00, 0x01, 0x46, 0x03, 0x00, 0x01, 0x48, 0x03, 0x00, 0x01, 0x4a, 0x03, 0x00, 0x01, 0x16, 0x09, 0x01, 0x01, + 0x18, 0x09, 0x01, 0x01, 0x1a, 0x09, 0x01, 0x01, 0x1c, 0x09, 0x01, 0x01, 0x1e, 0x09, 0x01, 0x01, 0x20, 0x09, 0x01, 0x01, 0x22, 0x09, 0x01, 0x01, 0x24, 0x09, 0x01, 0x01, 0x26, 0x09, 0x01, 0x01, + 0xe8, 0x2a, 0x02, 0x03, 0xf0, 0x2a, 0x02, 0x03, 0xf8, 0x2a, 0x02, 0x03, 0x00, 0x2b, 0x02, 0x03, 0xa0, 0x0f, 0x03, 0x04, 0x40, 0x34, 0x04, 0x06, 0x4c, 0x03, 0x00, 0x01, 0x4e, 0x03, 0x00, 0x01, + 0x50, 0x03, 0x00, 0x01, 0x52, 0x03, 0x00, 0x01, 0x54, 0x03, 0x00, 0x01, 0x56, 0x03, 0x00, 0x01, 0x58, 0x03, 0x00, 0x01, 0x5a, 0x03, 0x00, 0x01, 0x5c, 0x03, 0x00, 0x01, 0x28, 0x09, 0x01, 0x01, + 0x2a, 0x09, 0x01, 0x01, 0x2c, 0x09, 0x01, 0x01, 0x2e, 0x09, 0x01, 0x01, 0x30, 0x09, 0x01, 0x01, 0x32, 0x09, 0x01, 0x01, 0x34, 0x09, 0x01, 0x01, 0x36, 0x09, 0x01, 0x01, 0x38, 0x09, 0x01, 0x01, + 0x08, 0x2b, 0x02, 0x03, 0x10, 0x2b, 0x02, 0x03, 0x18, 0x2b, 0x02, 0x03, 0x20, 0x2b, 0x02, 0x03, 0xb0, 0x0f, 0x03, 0x04, 0x80, 0x34, 0x04, 0x06, 0x5e, 0x03, 0x00, 0x01, 0x60, 0x03, 0x00, 0x01, + 0x62, 0x03, 0x00, 0x01, 0x64, 0x03, 0x00, 0x01, 0x66, 0x03, 0x00, 0x01, 0x68, 0x03, 0x00, 0x01, 0x6a, 0x03, 0x00, 0x01, 0x6c, 0x03, 0x00, 0x01, 0x6e, 0x03, 0x00, 0x01, 0x3a, 0x09, 0x01, 0x01, + 0x3c, 0x09, 0x01, 0x01, 0x3e, 0x09, 0x01, 0x01, 0x40, 0x09, 0x01, 0x01, 0x42, 0x09, 0x01, 0x01, 0x44, 0x09, 0x01, 0x01, 0x46, 0x09, 0x01, 0x01, 0x48, 0x09, 0x01, 0x01, 0x4a, 0x09, 0x01, 0x01, + 0x28, 0x2b, 0x02, 0x03, 0x30, 0x2b, 0x02, 0x03, 0x38, 0x2b, 0x02, 0x03, 0x40, 0x2b, 0x02, 0x03, 0xc0, 0x0f, 0x03, 0x04, 0xc0, 0x34, 0x04, 0x06, 0x70, 0x03, 0x00, 0x01, 0x72, 0x03, 0x00, 0x01, + 0x74, 0x03, 0x00, 0x01, 0x76, 0x03, 0x00, 0x01, 0x78, 0x03, 0x00, 0x01, 0x7a, 0x03, 0x00, 0x01, 0x7c, 0x03, 0x00, 0x01, 0x7e, 0x03, 0x00, 0x01, 0x80, 0x03, 0x00, 0x01, 0x4c, 0x09, 0x01, 0x01, + 0x4e, 0x09, 0x01, 0x01, 0x50, 0x09, 0x01, 0x01, 0x52, 0x09, 0x01, 0x01, 0x54, 0x09, 0x01, 0x01, 0x56, 0x09, 0x01, 0x01, 0x58, 0x09, 0x01, 0x01, 0x5a, 0x09, 0x01, 0x01, 0x5c, 0x09, 0x01, 0x01, + 0x48, 0x2b, 0x02, 0x03, 0x50, 0x2b, 0x02, 0x03, 0x58, 0x2b, 0x02, 0x03, 0x60, 0x2b, 0x02, 0x03, 0xd0, 0x0f, 0x03, 0x04, 0x00, 0x35, 0x04, 0x06, 0x82, 0x03, 0x00, 0x01, 0x84, 0x03, 0x00, 0x01, + 0x86, 0x03, 0x00, 0x01, 0x88, 0x03, 0x00, 0x01, 0x8a, 0x03, 0x00, 0x01, 0x8c, 0x03, 0x00, 0x01, 0x8e, 0x03, 0x00, 0x01, 0x90, 0x03, 0x00, 0x01, 0x92, 0x03, 0x00, 0x01, 0x5e, 0x09, 0x01, 0x01, + 0x60, 0x09, 0x01, 0x01, 0x62, 0x09, 0x01, 0x01, 0x64, 0x09, 0x01, 0x01, 0x66, 0x09, 0x01, 0x01, 0x68, 0x09, 0x01, 0x01, 0x6a, 0x09, 0x01, 0x01, 0x6c, 0x09, 0x01, 0x01, 0x6e, 0x09, 0x01, 0x01, + 0x68, 0x2b, 0x02, 0x03, 0x70, 0x2b, 0x02, 0x03, 0x78, 0x2b, 0x02, 0x03, 0x80, 0x2b, 0x02, 0x03, 0xe0, 0x0f, 0x03, 0x04, 0x40, 0x35, 0x04, 0x06, 0x94, 0x03, 0x00, 0x01, 0x96, 0x03, 0x00, 0x01, + 0x98, 0x03, 0x00, 0x01, 0x9a, 0x03, 0x00, 0x01, 0x9c, 0x03, 0x00, 0x01, 0x9e, 0x03, 0x00, 0x01, 0xa0, 0x03, 0x00, 0x01, 0xa2, 0x03, 0x00, 0x01, 0xa4, 0x03, 0x00, 0x01, 0x70, 0x09, 0x01, 0x01, + 0x72, 0x09, 0x01, 0x01, 0x74, 0x09, 0x01, 0x01, 0x76, 0x09, 0x01, 0x01, 0x78, 0x09, 0x01, 0x01, 0x7a, 0x09, 0x01, 0x01, 0x7c, 0x09, 0x01, 0x01, 0x7e, 0x09, 0x01, 0x01, 0x80, 0x09, 0x01, 0x01, + 0x88, 0x2b, 0x02, 0x03, 0x90, 0x2b, 0x02, 0x03, 0x98, 0x2b, 0x02, 0x03, 0xa0, 0x2b, 0x02, 0x03, 0xf0, 0x0f, 0x03, 0x04, 0x80, 0x35, 0x04, 0x06, 0xa6, 0x03, 0x00, 0x01, 0xa8, 0x03, 0x00, 0x01, + 0xaa, 0x03, 0x00, 0x01, 0xac, 0x03, 0x00, 0x01, 0xae, 0x03, 0x00, 0x01, 0xb0, 0x03, 0x00, 0x01, 0xb2, 0x03, 0x00, 0x01, 0xb4, 0x03, 0x00, 0x01, 0xb6, 0x03, 0x00, 0x01, 0x82, 0x09, 0x01, 0x01, + 0x84, 0x09, 0x01, 0x01, 0x86, 0x09, 0x01, 0x01, 0x88, 0x09, 0x01, 0x01, 0x8a, 0x09, 0x01, 0x01, 0x8c, 0x09, 0x01, 0x01, 0x8e, 0x09, 0x01, 0x01, 0x90, 0x09, 0x01, 0x01, 0x92, 0x09, 0x01, 0x01, + 0xa8, 0x2b, 0x02, 0x03, 0xb0, 0x2b, 0x02, 0x03, 0xb8, 0x2b, 0x02, 0x03, 0xc0, 0x2b, 0x02, 0x03, 0x00, 0x10, 0x03, 0x04, 0xc0, 0x35, 0x04, 0x06, 0xb8, 0x03, 0x00, 0x01, 0xba, 0x03, 0x00, 0x01, + 0xbc, 0x03, 0x00, 0x01, 0xbe, 0x03, 0x00, 0x01, 0xc0, 0x03, 0x00, 0x01, 0xc2, 0x03, 0x00, 0x01, 0xc4, 0x03, 0x00, 0x01, 0xc6, 0x03, 0x00, 0x01, 0xc8, 0x03, 0x00, 0x01, 0x94, 0x09, 0x01, 0x01, + 0x96, 0x09, 0x01, 0x01, 0x98, 0x09, 0x01, 0x01, 0x9a, 0x09, 0x01, 0x01, 0x9c, 0x09, 0x01, 0x01, 0x9e, 0x09, 0x01, 0x01, 0xa0, 0x09, 0x01, 0x01, 0xa2, 0x09, 0x01, 0x01, 0xa4, 0x09, 0x01, 0x01, + 0xc8, 0x2b, 0x02, 0x03, 0xd0, 0x2b, 0x02, 0x03, 0xd8, 0x2b, 0x02, 0x03, 0xe0, 0x2b, 0x02, 0x03, 0x10, 0x10, 0x03, 0x04, 0x00, 0x36, 0x04, 0x06, 0xca, 0x03, 0x00, 0x01, 0xcc, 0x03, 0x00, 0x01, + 0xce, 0x03, 0x00, 0x01, 0xd0, 0x03, 0x00, 0x01, 0xd2, 0x03, 0x00, 0x01, 0xd4, 0x03, 0x00, 0x01, 0xd6, 0x03, 0x00, 0x01, 0xd8, 0x03, 0x00, 0x01, 0xda, 0x03, 0x00, 0x01, 0xa6, 0x09, 0x01, 0x01, + 0xa8, 0x09, 0x01, 0x01, 0xaa, 0x09, 0x01, 0x01, 0xac, 0x09, 0x01, 0x01, 0xae, 0x09, 0x01, 0x01, 0xb0, 0x09, 0x01, 0x01, 0xb2, 0x09, 0x01, 0x01, 0xb4, 0x09, 0x01, 0x01, 0xb6, 0x09, 0x01, 0x01, + 0xe8, 0x2b, 0x02, 0x03, 0xf0, 0x2b, 0x02, 0x03, 0xf8, 0x2b, 0x02, 0x03, 0x00, 0x2c, 0x02, 0x03, 0x20, 0x10, 0x03, 0x04, 0x40, 0x36, 0x04, 0x06, 0xdc, 0x03, 0x00, 0x01, 0xde, 0x03, 0x00, 0x01, + 0xe0, 0x03, 0x00, 0x01, 0xe2, 0x03, 0x00, 0x01, 0xe4, 0x03, 0x00, 0x01, 0xe6, 0x03, 0x00, 0x01, 0xe8, 0x03, 0x00, 0x01, 0xea, 0x03, 0x00, 0x01, 0xec, 0x03, 0x00, 0x01, 0xb8, 0x09, 0x01, 0x01, + 0xba, 0x09, 0x01, 0x01, 0xbc, 0x09, 0x01, 0x01, 0xbe, 0x09, 0x01, 0x01, 0xc0, 0x09, 0x01, 0x01, 0xc2, 0x09, 0x01, 0x01, 0xc4, 0x09, 0x01, 0x01, 0xc6, 0x09, 0x01, 0x01, 0xc8, 0x09, 0x01, 0x01, + 0x08, 0x2c, 0x02, 0x03, 0x10, 0x2c, 0x02, 0x03, 0x18, 0x2c, 0x02, 0x03, 0x20, 0x2c, 0x02, 0x03, 0x30, 0x10, 0x03, 0x04, 0x80, 0x36, 0x04, 0x06, 0xee, 0x03, 0x00, 0x01, 0xf0, 0x03, 0x00, 0x01, + 0xf2, 0x03, 0x00, 0x01, 0xf4, 0x03, 0x00, 0x01, 0xf6, 0x03, 0x00, 0x01, 0xf8, 0x03, 0x00, 0x01, 0xfa, 0x03, 0x00, 0x01, 0xfc, 0x03, 0x00, 0x01, 0xfe, 0x03, 0x00, 0x01, 0xca, 0x09, 0x01, 0x01, + 0xcc, 0x09, 0x01, 0x01, 0xce, 0x09, 0x01, 0x01, 0xd0, 0x09, 0x01, 0x01, 0xd2, 0x09, 0x01, 0x01, 0xd4, 0x09, 0x01, 0x01, 0xd6, 0x09, 0x01, 0x01, 0xd8, 0x09, 0x01, 0x01, 0xda, 0x09, 0x01, 0x01, + 0x28, 0x2c, 0x02, 0x03, 0x30, 0x2c, 0x02, 0x03, 0x38, 0x2c, 0x02, 0x03, 0x40, 0x2c, 0x02, 0x03, 0x40, 0x10, 0x03, 0x04, 0xc0, 0x36, 0x04, 0x06, 0x00, 0x04, 0x00, 0x01, 0x02, 0x04, 0x00, 0x01, + 0x04, 0x04, 0x00, 0x01, 0x06, 0x04, 0x00, 0x01, 0x08, 0x04, 0x00, 0x01, 0x0a, 0x04, 0x00, 0x01, 0x0c, 0x04, 0x00, 0x01, 0x0e, 0x04, 0x00, 0x01, 0x10, 0x04, 0x00, 0x01, 0xdc, 0x09, 0x01, 0x01, + 0xde, 0x09, 0x01, 0x01, 0xe0, 0x09, 0x01, 0x01, 0xe2, 0x09, 0x01, 0x01, 0xe4, 0x09, 0x01, 0x01, 0xe6, 0x09, 0x01, 0x01, 0xe8, 0x09, 0x01, 0x01, 0xea, 0x09, 0x01, 0x01, 0xec, 0x09, 0x01, 0x01, + 0x48, 0x2c, 0x02, 0x03, 0x50, 0x2c, 0x02, 0x03, 0x58, 0x2c, 0x02, 0x03, 0x60, 0x2c, 0x02, 0x03, 0x50, 0x10, 0x03, 0x04, 0x00, 0x37, 0x04, 0x06, 0x12, 0x04, 0x00, 0x01, 0x14, 0x04, 0x00, 0x01, + 0x16, 0x04, 0x00, 0x01, 0x18, 0x04, 0x00, 0x01, 0x1a, 0x04, 0x00, 0x01, 0x1c, 0x04, 0x00, 0x01, 0x1e, 0x04, 0x00, 0x01, 0x20, 0x04, 0x00, 0x01, 0x22, 0x04, 0x00, 0x01, 0xee, 0x09, 0x01, 0x01, + 0xf0, 0x09, 0x01, 0x01, 0xf2, 0x09, 0x01, 0x01, 0xf4, 0x09, 0x01, 0x01, 0xf6, 0x09, 0x01, 0x01, 0xf8, 0x09, 0x01, 0x01, 0xfa, 0x09, 0x01, 0x01, 0xfc, 0x09, 0x01, 0x01, 0xfe, 0x09, 0x01, 0x01, + 0x68, 0x2c, 0x02, 0x03, 0x70, 0x2c, 0x02, 0x03, 0x78, 0x2c, 0x02, 0x03, 0x80, 0x2c, 0x02, 0x03, 0x60, 0x10, 0x03, 0x04, 0x40, 0x37, 0x04, 0x06, 0x24, 0x04, 0x00, 0x01, 0x26, 0x04, 0x00, 0x01, + 0x28, 0x04, 0x00, 0x01, 0x2a, 0x04, 0x00, 0x01, 0x2c, 0x04, 0x00, 0x01, 0x2e, 0x04, 0x00, 0x01, 0x30, 0x04, 0x00, 0x01, 0x32, 0x04, 0x00, 0x01, 0x34, 0x04, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x01, + 0x02, 0x0a, 0x01, 0x01, 0x04, 0x0a, 0x01, 0x01, 0x06, 0x0a, 0x01, 0x01, 0x08, 0x0a, 0x01, 0x01, 0x0a, 0x0a, 0x01, 0x01, 0x0c, 0x0a, 0x01, 0x01, 0x0e, 0x0a, 0x01, 0x01, 0x10, 0x0a, 0x01, 0x01, + 0x88, 0x2c, 0x02, 0x03, 0x90, 0x2c, 0x02, 0x03, 0x98, 0x2c, 0x02, 0x03, 0xa0, 0x2c, 0x02, 0x03, 0x70, 0x10, 0x03, 0x04, 0x80, 0x37, 0x04, 0x06, 0x36, 0x04, 0x00, 0x01, 0x38, 0x04, 0x00, 0x01, + 0x3a, 0x04, 0x00, 0x01, 0x3c, 0x04, 0x00, 0x01, 0x3e, 0x04, 0x00, 0x01, 0x40, 0x04, 0x00, 0x01, 0x42, 0x04, 0x00, 0x01, 0x44, 0x04, 0x00, 0x01, 0x46, 0x04, 0x00, 0x01, 0x12, 0x0a, 0x01, 0x01, + 0x14, 0x0a, 0x01, 0x01, 0x16, 0x0a, 0x01, 0x01, 0x18, 0x0a, 0x01, 0x01, 0x1a, 0x0a, 0x01, 0x01, 0x1c, 0x0a, 0x01, 0x01, 0x1e, 0x0a, 0x01, 0x01, 0x20, 0x0a, 0x01, 0x01, 0x22, 0x0a, 0x01, 0x01, + 0xa8, 0x2c, 0x02, 0x03, 0xb0, 0x2c, 0x02, 0x03, 0xb8, 0x2c, 0x02, 0x03, 0xc0, 0x2c, 0x02, 0x03, 0x80, 0x10, 0x03, 0x04, 0xc0, 0x37, 0x04, 0x06, 0x48, 0x04, 0x00, 0x01, 0x4a, 0x04, 0x00, 0x01, + 0x4c, 0x04, 0x00, 0x01, 0x4e, 0x04, 0x00, 0x01, 0x50, 0x04, 0x00, 0x01, 0x52, 0x04, 0x00, 0x01, 0x54, 0x04, 0x00, 0x01, 0x56, 0x04, 0x00, 0x01, 0x58, 0x04, 0x00, 0x01, 0x24, 0x0a, 0x01, 0x01, + 0x26, 0x0a, 0x01, 0x01, 0x28, 0x0a, 0x01, 0x01, 0x2a, 0x0a, 0x01, 0x01, 0x2c, 0x0a, 0x01, 0x01, 0x2e, 0x0a, 0x01, 0x01, 0x30, 0x0a, 0x01, 0x01, 0x32, 0x0a, 0x01, 0x01, 0x34, 0x0a, 0x01, 0x01, + 0xc8, 0x2c, 0x02, 0x03, 0xd0, 0x2c, 0x02, 0x03, 0xd8, 0x2c, 0x02, 0x03, 0xe0, 0x2c, 0x02, 0x03, 0x90, 0x10, 0x03, 0x04, 0x00, 0x38, 0x04, 0x06, 0x5a, 0x04, 0x00, 0x01, 0x5c, 0x04, 0x00, 0x01, + 0x5e, 0x04, 0x00, 0x01, 0x60, 0x04, 0x00, 0x01, 0x62, 0x04, 0x00, 0x01, 0x64, 0x04, 0x00, 0x01, 0x66, 0x04, 0x00, 0x01, 0x68, 0x04, 0x00, 0x01, 0x6a, 0x04, 0x00, 0x01, 0x36, 0x0a, 0x01, 0x01, + 0x38, 0x0a, 0x01, 0x01, 0x3a, 0x0a, 0x01, 0x01, 0x3c, 0x0a, 0x01, 0x01, 0x3e, 0x0a, 0x01, 0x01, 0x40, 0x0a, 0x01, 0x01, 0x42, 0x0a, 0x01, 0x01, 0x44, 0x0a, 0x01, 0x01, 0x46, 0x0a, 0x01, 0x01, + 0xe8, 0x2c, 0x02, 0x03, 0xf0, 0x2c, 0x02, 0x03, 0xf8, 0x2c, 0x02, 0x03, 0x00, 0x2d, 0x02, 0x03, 0xa0, 0x10, 0x03, 0x04, 0x40, 0x38, 0x04, 0x06, 0x6c, 0x04, 0x00, 0x01, 0x6e, 0x04, 0x00, 0x01, + 0x70, 0x04, 0x00, 0x01, 0x72, 0x04, 0x00, 0x01, 0x74, 0x04, 0x00, 0x01, 0x76, 0x04, 0x00, 0x01, 0x78, 0x04, 0x00, 0x01, 0x7a, 0x04, 0x00, 0x01, 0x7c, 0x04, 0x00, 0x01, 0x48, 0x0a, 0x01, 0x01, + 0x4a, 0x0a, 0x01, 0x01, 0x4c, 0x0a, 0x01, 0x01, 0x4e, 0x0a, 0x01, 0x01, 0x50, 0x0a, 0x01, 0x01, 0x52, 0x0a, 0x01, 0x01, 0x54, 0x0a, 0x01, 0x01, 0x56, 0x0a, 0x01, 0x01, 0x58, 0x0a, 0x01, 0x01, + 0x08, 0x2d, 0x02, 0x03, 0x10, 0x2d, 0x02, 0x03, 0x18, 0x2d, 0x02, 0x03, 0x20, 0x2d, 0x02, 0x03, 0xb0, 0x10, 0x03, 0x04, 0x80, 0x38, 0x04, 0x06, 0x7e, 0x04, 0x00, 0x01, 0x80, 0x04, 0x00, 0x01, + 0x82, 0x04, 0x00, 0x01, 0x84, 0x04, 0x00, 0x01, 0x86, 0x04, 0x00, 0x01, 0x88, 0x04, 0x00, 0x01, 0x8a, 0x04, 0x00, 0x01, 0x8c, 0x04, 0x00, 0x01, 0x8e, 0x04, 0x00, 0x01, 0x5a, 0x0a, 0x01, 0x01, + 0x5c, 0x0a, 0x01, 0x01, 0x5e, 0x0a, 0x01, 0x01, 0x60, 0x0a, 0x01, 0x01, 0x62, 0x0a, 0x01, 0x01, 0x64, 0x0a, 0x01, 0x01, 0x66, 0x0a, 0x01, 0x01, 0x68, 0x0a, 0x01, 0x01, 0x6a, 0x0a, 0x01, 0x01, + 0x28, 0x2d, 0x02, 0x03, 0x30, 0x2d, 0x02, 0x03, 0x38, 0x2d, 0x02, 0x03, 0x40, 0x2d, 0x02, 0x03, 0xc0, 0x10, 0x03, 0x04, 0xc0, 0x38, 0x04, 0x06, 0x90, 0x04, 0x00, 0x01, 0x92, 0x04, 0x00, 0x01, + 0x94, 0x04, 0x00, 0x01, 0x96, 0x04, 0x00, 0x01, 0x98, 0x04, 0x00, 0x01, 0x9a, 0x04, 0x00, 0x01, 0x9c, 0x04, 0x00, 0x01, 0x9e, 0x04, 0x00, 0x01, 0xa0, 0x04, 0x00, 0x01, 0x6c, 0x0a, 0x01, 0x01, + 0x6e, 0x0a, 0x01, 0x01, 0x70, 0x0a, 0x01, 0x01, 0x72, 0x0a, 0x01, 0x01, 0x74, 0x0a, 0x01, 0x01, 0x76, 0x0a, 0x01, 0x01, 0x78, 0x0a, 0x01, 0x01, 0x7a, 0x0a, 0x01, 0x01, 0x7c, 0x0a, 0x01, 0x01, + 0x48, 0x2d, 0x02, 0x03, 0x50, 0x2d, 0x02, 0x03, 0x58, 0x2d, 0x02, 0x03, 0x60, 0x2d, 0x02, 0x03, 0xd0, 0x10, 0x03, 0x04, 0x00, 0x39, 0x04, 0x06, 0xa2, 0x04, 0x00, 0x01, 0xa4, 0x04, 0x00, 0x01, + 0xa6, 0x04, 0x00, 0x01, 0xa8, 0x04, 0x00, 0x01, 0xaa, 0x04, 0x00, 0x01, 0xac, 0x04, 0x00, 0x01, 0xae, 0x04, 0x00, 0x01, 0xb0, 0x04, 0x00, 0x01, 0xb2, 0x04, 0x00, 0x01, 0x7e, 0x0a, 0x01, 0x01, + 0x80, 0x0a, 0x01, 0x01, 0x82, 0x0a, 0x01, 0x01, 0x84, 0x0a, 0x01, 0x01, 0x86, 0x0a, 0x01, 0x01, 0x88, 0x0a, 0x01, 0x01, 0x8a, 0x0a, 0x01, 0x01, 0x8c, 0x0a, 0x01, 0x01, 0x8e, 0x0a, 0x01, 0x01, + 0x68, 0x2d, 0x02, 0x03, 0x70, 0x2d, 0x02, 0x03, 0x78, 0x2d, 0x02, 0x03, 0x80, 0x2d, 0x02, 0x03, 0xe0, 0x10, 0x03, 0x04, 0x40, 0x39, 0x04, 0x06, 0xb4, 0x04, 0x00, 0x01, 0xb6, 0x04, 0x00, 0x01, + 0xb8, 0x04, 0x00, 0x01, 0xba, 0x04, 0x00, 0x01, 0xbc, 0x04, 0x00, 0x01, 0xbe, 0x04, 0x00, 0x01, 0xc0, 0x04, 0x00, 0x01, 0xc2, 0x04, 0x00, 0x01, 0xc4, 0x04, 0x00, 0x01, 0x90, 0x0a, 0x01, 0x01, + 0x92, 0x0a, 0x01, 0x01, 0x94, 0x0a, 0x01, 0x01, 0x96, 0x0a, 0x01, 0x01, 0x98, 0x0a, 0x01, 0x01, 0x9a, 0x0a, 0x01, 0x01, 0x9c, 0x0a, 0x01, 0x01, 0x9e, 0x0a, 0x01, 0x01, 0xa0, 0x0a, 0x01, 0x01, + 0x88, 0x2d, 0x02, 0x03, 0x90, 0x2d, 0x02, 0x03, 0x98, 0x2d, 0x02, 0x03, 0xa0, 0x2d, 0x02, 0x03, 0xf0, 0x10, 0x03, 0x04, 0x00, 0x12, 0x05, 0x07, 0xc6, 0x04, 0x00, 0x01, 0xc8, 0x04, 0x00, 0x01, + 0xca, 0x04, 0x00, 0x01, 0xcc, 0x04, 0x00, 0x01, 0xce, 0x04, 0x00, 0x01, 0xd0, 0x04, 0x00, 0x01, 0xd2, 0x04, 0x00, 0x01, 0xd4, 0x04, 0x00, 0x01, 0xd6, 0x04, 0x00, 0x01, 0xa2, 0x0a, 0x01, 0x01, + 0xa4, 0x0a, 0x01, 0x01, 0xa6, 0x0a, 0x01, 0x01, 0xa8, 0x0a, 0x01, 0x01, 0xaa, 0x0a, 0x01, 0x01, 0xac, 0x0a, 0x01, 0x01, 0xae, 0x0a, 0x01, 0x01, 0xb0, 0x0a, 0x01, 0x01, 0xb2, 0x0a, 0x01, 0x01, + 0xa8, 0x2d, 0x02, 0x03, 0xb0, 0x2d, 0x02, 0x03, 0xb8, 0x2d, 0x02, 0x03, 0xc0, 0x2d, 0x02, 0x03, 0x00, 0x11, 0x03, 0x04, 0x80, 0x12, 0x05, 0x07, 0xd8, 0x04, 0x00, 0x01, 0xda, 0x04, 0x00, 0x01, + 0xdc, 0x04, 0x00, 0x01, 0xde, 0x04, 0x00, 0x01, 0xe0, 0x04, 0x00, 0x01, 0xe2, 0x04, 0x00, 0x01, 0xe4, 0x04, 0x00, 0x01, 0xe6, 0x04, 0x00, 0x01, 0xe8, 0x04, 0x00, 0x01, 0xb4, 0x0a, 0x01, 0x01, + 0xb6, 0x0a, 0x01, 0x01, 0xb8, 0x0a, 0x01, 0x01, 0xba, 0x0a, 0x01, 0x01, 0xbc, 0x0a, 0x01, 0x01, 0xbe, 0x0a, 0x01, 0x01, 0xc0, 0x0a, 0x01, 0x01, 0xc2, 0x0a, 0x01, 0x01, 0xc4, 0x0a, 0x01, 0x01, + 0xc8, 0x2d, 0x02, 0x03, 0xd0, 0x2d, 0x02, 0x03, 0xd8, 0x2d, 0x02, 0x03, 0xe0, 0x2d, 0x02, 0x03, 0x10, 0x11, 0x03, 0x04, 0x00, 0x13, 0x05, 0x07, 0xea, 0x04, 0x00, 0x01, 0xec, 0x04, 0x00, 0x01, + 0xee, 0x04, 0x00, 0x01, 0xf0, 0x04, 0x00, 0x01, 0xf2, 0x04, 0x00, 0x01, 0xf4, 0x04, 0x00, 0x01, 0xf6, 0x04, 0x00, 0x01, 0xf8, 0x04, 0x00, 0x01, 0xfa, 0x04, 0x00, 0x01, 0xc6, 0x0a, 0x01, 0x01, + 0xc8, 0x0a, 0x01, 0x01, 0xca, 0x0a, 0x01, 0x01, 0xcc, 0x0a, 0x01, 0x01, 0xce, 0x0a, 0x01, 0x01, 0xd0, 0x0a, 0x01, 0x01, 0xd2, 0x0a, 0x01, 0x01, 0xd4, 0x0a, 0x01, 0x01, 0xd6, 0x0a, 0x01, 0x01, + 0xe8, 0x2d, 0x02, 0x03, 0xf0, 0x2d, 0x02, 0x03, 0xf8, 0x2d, 0x02, 0x03, 0x00, 0x2e, 0x02, 0x03, 0x20, 0x11, 0x03, 0x04, 0x80, 0x13, 0x05, 0x07, 0xfc, 0x04, 0x00, 0x01, 0xfe, 0x04, 0x00, 0x01, + 0x00, 0x05, 0x00, 0x01, 0x02, 0x05, 0x00, 0x01, 0x04, 0x05, 0x00, 0x01, 0x06, 0x05, 0x00, 0x01, 0x08, 0x05, 0x00, 0x01, 0x0a, 0x05, 0x00, 0x01, 0x0c, 0x05, 0x00, 0x01, 0xd8, 0x0a, 0x01, 0x01, + 0xda, 0x0a, 0x01, 0x01, 0xdc, 0x0a, 0x01, 0x01, 0xde, 0x0a, 0x01, 0x01, 0xe0, 0x0a, 0x01, 0x01, 0xe2, 0x0a, 0x01, 0x01, 0xe4, 0x0a, 0x01, 0x01, 0xe6, 0x0a, 0x01, 0x01, 0xe8, 0x0a, 0x01, 0x01, + 0x08, 0x2e, 0x02, 0x03, 0x10, 0x2e, 0x02, 0x03, 0x18, 0x2e, 0x02, 0x03, 0x20, 0x2e, 0x02, 0x03, 0x30, 0x11, 0x03, 0x04, 0x00, 0x14, 0x05, 0x07, 0x0e, 0x05, 0x00, 0x01, 0x10, 0x05, 0x00, 0x01, + 0x12, 0x05, 0x00, 0x01, 0x14, 0x05, 0x00, 0x01, 0x16, 0x05, 0x00, 0x01, 0x18, 0x05, 0x00, 0x01, 0x1a, 0x05, 0x00, 0x01, 0x1c, 0x05, 0x00, 0x01, 0x1e, 0x05, 0x00, 0x01, 0xea, 0x0a, 0x01, 0x01, + 0xec, 0x0a, 0x01, 0x01, 0xee, 0x0a, 0x01, 0x01, 0xf0, 0x0a, 0x01, 0x01, 0xf2, 0x0a, 0x01, 0x01, 0xf4, 0x0a, 0x01, 0x01, 0xf6, 0x0a, 0x01, 0x01, 0xf8, 0x0a, 0x01, 0x01, 0xfa, 0x0a, 0x01, 0x01, + 0x28, 0x2e, 0x02, 0x03, 0x30, 0x2e, 0x02, 0x03, 0x38, 0x2e, 0x02, 0x03, 0x40, 0x2e, 0x02, 0x03, 0x40, 0x11, 0x03, 0x04, 0x80, 0x14, 0x05, 0x07, 0x20, 0x05, 0x00, 0x01, 0x22, 0x05, 0x00, 0x01, + 0x24, 0x05, 0x00, 0x01, 0x26, 0x05, 0x00, 0x01, 0x28, 0x05, 0x00, 0x01, 0x2a, 0x05, 0x00, 0x01, 0x2c, 0x05, 0x00, 0x01, 0x2e, 0x05, 0x00, 0x01, 0x30, 0x05, 0x00, 0x01, 0xfc, 0x0a, 0x01, 0x01, + 0xfe, 0x0a, 0x01, 0x01, 0x00, 0x0b, 0x01, 0x01, 0x02, 0x0b, 0x01, 0x01, 0x04, 0x0b, 0x01, 0x01, 0x06, 0x0b, 0x01, 0x01, 0x08, 0x0b, 0x01, 0x01, 0x0a, 0x0b, 0x01, 0x01, 0x0c, 0x0b, 0x01, 0x01, + 0x48, 0x2e, 0x02, 0x03, 0x50, 0x2e, 0x02, 0x03, 0x58, 0x2e, 0x02, 0x03, 0x60, 0x2e, 0x02, 0x03, 0x50, 0x11, 0x03, 0x04, 0x00, 0x15, 0x05, 0x07, 0x32, 0x05, 0x00, 0x01, 0x34, 0x05, 0x00, 0x01, + 0x36, 0x05, 0x00, 0x01, 0x38, 0x05, 0x00, 0x01, 0x3a, 0x05, 0x00, 0x01, 0x3c, 0x05, 0x00, 0x01, 0x3e, 0x05, 0x00, 0x01, 0x40, 0x05, 0x00, 0x01, 0x42, 0x05, 0x00, 0x01, 0x0e, 0x0b, 0x01, 0x01, + 0x10, 0x0b, 0x01, 0x01, 0x12, 0x0b, 0x01, 0x01, 0x14, 0x0b, 0x01, 0x01, 0x16, 0x0b, 0x01, 0x01, 0x18, 0x0b, 0x01, 0x01, 0x1a, 0x0b, 0x01, 0x01, 0x1c, 0x0b, 0x01, 0x01, 0x1e, 0x0b, 0x01, 0x01, + 0x68, 0x2e, 0x02, 0x03, 0x70, 0x2e, 0x02, 0x03, 0x78, 0x2e, 0x02, 0x03, 0x80, 0x2e, 0x02, 0x03, 0x60, 0x11, 0x03, 0x04, 0x80, 0x15, 0x05, 0x07, 0x44, 0x05, 0x00, 0x01, 0x46, 0x05, 0x00, 0x01, + 0x48, 0x05, 0x00, 0x01, 0x4a, 0x05, 0x00, 0x01, 0x4c, 0x05, 0x00, 0x01, 0x4e, 0x05, 0x00, 0x01, 0x50, 0x05, 0x00, 0x01, 0x52, 0x05, 0x00, 0x01, 0x54, 0x05, 0x00, 0x01, 0x20, 0x0b, 0x01, 0x01, + 0x22, 0x0b, 0x01, 0x01, 0x24, 0x0b, 0x01, 0x01, 0x26, 0x0b, 0x01, 0x01, 0x28, 0x0b, 0x01, 0x01, 0x2a, 0x0b, 0x01, 0x01, 0x2c, 0x0b, 0x01, 0x01, 0x2e, 0x0b, 0x01, 0x01, 0x30, 0x0b, 0x01, 0x01, + 0x88, 0x2e, 0x02, 0x03, 0x90, 0x2e, 0x02, 0x03, 0x98, 0x2e, 0x02, 0x03, 0xa0, 0x2e, 0x02, 0x03, 0x70, 0x11, 0x03, 0x04, 0x00, 0x16, 0x05, 0x07, 0x56, 0x05, 0x00, 0x01, 0x58, 0x05, 0x00, 0x01, + 0x5a, 0x05, 0x00, 0x01, 0x5c, 0x05, 0x00, 0x01, 0x5e, 0x05, 0x00, 0x01, 0x60, 0x05, 0x00, 0x01, 0x62, 0x05, 0x00, 0x01, 0x64, 0x05, 0x00, 0x01, 0x32, 0x0b, 0x01, 0x01, 0x34, 0x0b, 0x01, 0x01, + 0x36, 0x0b, 0x01, 0x01, 0x38, 0x0b, 0x01, 0x01, 0x3a, 0x0b, 0x01, 0x01, 0x3c, 0x0b, 0x01, 0x01, 0x3e, 0x0b, 0x01, 0x01, 0x40, 0x0b, 0x01, 0x01, 0x42, 0x0b, 0x01, 0x01, 0x44, 0x0b, 0x01, 0x01, + 0xa8, 0x2e, 0x02, 0x03, 0xb0, 0x2e, 0x02, 0x03, 0xb8, 0x2e, 0x02, 0x03, 0xc0, 0x2e, 0x02, 0x03, 0x80, 0x11, 0x03, 0x04, 0x80, 0x16, 0x05, 0x07, 0x66, 0x05, 0x00, 0x01, 0x68, 0x05, 0x00, 0x01, + 0x6a, 0x05, 0x00, 0x01, 0x6c, 0x05, 0x00, 0x01, 0x6e, 0x05, 0x00, 0x01, 0x70, 0x05, 0x00, 0x01, 0x72, 0x05, 0x00, 0x01, 0x74, 0x05, 0x00, 0x01, 0x46, 0x0b, 0x01, 0x01, 0x48, 0x0b, 0x01, 0x01, + 0x4a, 0x0b, 0x01, 0x01, 0x4c, 0x0b, 0x01, 0x01, 0x4e, 0x0b, 0x01, 0x01, 0x50, 0x0b, 0x01, 0x01, 0x52, 0x0b, 0x01, 0x01, 0x54, 0x0b, 0x01, 0x01, 0x56, 0x0b, 0x01, 0x01, 0x58, 0x0b, 0x01, 0x01, + 0xc8, 0x2e, 0x02, 0x03, 0xd0, 0x2e, 0x02, 0x03, 0xd8, 0x2e, 0x02, 0x03, 0xe0, 0x2e, 0x02, 0x03, 0x90, 0x11, 0x03, 0x04, 0x00, 0x17, 0x05, 0x07, 0x76, 0x05, 0x00, 0x01, 0x78, 0x05, 0x00, 0x01, + 0x7a, 0x05, 0x00, 0x01, 0x7c, 0x05, 0x00, 0x01, 0x7e, 0x05, 0x00, 0x01, 0x80, 0x05, 0x00, 0x01, 0x82, 0x05, 0x00, 0x01, 0x84, 0x05, 0x00, 0x01, 0x5a, 0x0b, 0x01, 0x01, 0x5c, 0x0b, 0x01, 0x01, + 0x5e, 0x0b, 0x01, 0x01, 0x60, 0x0b, 0x01, 0x01, 0x62, 0x0b, 0x01, 0x01, 0x64, 0x0b, 0x01, 0x01, 0x66, 0x0b, 0x01, 0x01, 0x68, 0x0b, 0x01, 0x01, 0x6a, 0x0b, 0x01, 0x01, 0x6c, 0x0b, 0x01, 0x01, + 0xe8, 0x2e, 0x02, 0x03, 0xf0, 0x2e, 0x02, 0x03, 0xf8, 0x2e, 0x02, 0x03, 0x00, 0x2f, 0x02, 0x03, 0xa0, 0x11, 0x03, 0x04, 0x80, 0x17, 0x05, 0x07, 0x86, 0x05, 0x00, 0x01, 0x88, 0x05, 0x00, 0x01, + 0x8a, 0x05, 0x00, 0x01, 0x8c, 0x05, 0x00, 0x01, 0x8e, 0x05, 0x00, 0x01, 0x90, 0x05, 0x00, 0x01, 0x92, 0x05, 0x00, 0x01, 0x94, 0x05, 0x00, 0x01, 0x6e, 0x0b, 0x01, 0x01, 0x70, 0x0b, 0x01, 0x01, + 0x72, 0x0b, 0x01, 0x01, 0x74, 0x0b, 0x01, 0x01, 0x76, 0x0b, 0x01, 0x01, 0x78, 0x0b, 0x01, 0x01, 0x7a, 0x0b, 0x01, 0x01, 0x7c, 0x0b, 0x01, 0x01, 0x7e, 0x0b, 0x01, 0x01, 0x80, 0x0b, 0x01, 0x01, + 0x08, 0x2f, 0x02, 0x03, 0x10, 0x2f, 0x02, 0x03, 0x18, 0x2f, 0x02, 0x03, 0x20, 0x2f, 0x02, 0x03, 0xb0, 0x11, 0x03, 0x04, 0x00, 0x18, 0x05, 0x07, 0x96, 0x05, 0x00, 0x01, 0x98, 0x05, 0x00, 0x01, + 0x9a, 0x05, 0x00, 0x01, 0x9c, 0x05, 0x00, 0x01, 0x9e, 0x05, 0x00, 0x01, 0xa0, 0x05, 0x00, 0x01, 0xa2, 0x05, 0x00, 0x01, 0xa4, 0x05, 0x00, 0x01, 0x82, 0x0b, 0x01, 0x01, 0x84, 0x0b, 0x01, 0x01, + 0x86, 0x0b, 0x01, 0x01, 0x88, 0x0b, 0x01, 0x01, 0x8a, 0x0b, 0x01, 0x01, 0x8c, 0x0b, 0x01, 0x01, 0x8e, 0x0b, 0x01, 0x01, 0x90, 0x0b, 0x01, 0x01, 0x92, 0x0b, 0x01, 0x01, 0x94, 0x0b, 0x01, 0x01, + 0x28, 0x2f, 0x02, 0x03, 0x30, 0x2f, 0x02, 0x03, 0x38, 0x2f, 0x02, 0x03, 0x40, 0x2f, 0x02, 0x03, 0xc0, 0x11, 0x03, 0x04, 0x80, 0x18, 0x05, 0x07, 0xa6, 0x05, 0x00, 0x01, 0xa8, 0x05, 0x00, 0x01, + 0xaa, 0x05, 0x00, 0x01, 0xac, 0x05, 0x00, 0x01, 0xae, 0x05, 0x00, 0x01, 0xb0, 0x05, 0x00, 0x01, 0xb2, 0x05, 0x00, 0x01, 0xb4, 0x05, 0x00, 0x01, 0x96, 0x0b, 0x01, 0x01, 0x98, 0x0b, 0x01, 0x01, + 0x9a, 0x0b, 0x01, 0x01, 0x9c, 0x0b, 0x01, 0x01, 0x9e, 0x0b, 0x01, 0x01, 0xa0, 0x0b, 0x01, 0x01, 0xa2, 0x0b, 0x01, 0x01, 0xa4, 0x0b, 0x01, 0x01, 0xa6, 0x0b, 0x01, 0x01, 0xa8, 0x0b, 0x01, 0x01, + 0x48, 0x2f, 0x02, 0x03, 0x50, 0x2f, 0x02, 0x03, 0x58, 0x2f, 0x02, 0x03, 0x60, 0x2f, 0x02, 0x03, 0xd0, 0x11, 0x03, 0x04, 0x00, 0x19, 0x05, 0x07, 0xb6, 0x05, 0x00, 0x01, 0xb8, 0x05, 0x00, 0x01, + 0xba, 0x05, 0x00, 0x01, 0xbc, 0x05, 0x00, 0x01, 0xbe, 0x05, 0x00, 0x01, 0xc0, 0x05, 0x00, 0x01, 0xc2, 0x05, 0x00, 0x01, 0xc4, 0x05, 0x00, 0x01, 0xaa, 0x0b, 0x01, 0x01, 0xac, 0x0b, 0x01, 0x01, + 0xae, 0x0b, 0x01, 0x01, 0xb0, 0x0b, 0x01, 0x01, 0xb2, 0x0b, 0x01, 0x01, 0xb4, 0x0b, 0x01, 0x01, 0xb6, 0x0b, 0x01, 0x01, 0xb8, 0x0b, 0x01, 0x01, 0xba, 0x0b, 0x01, 0x01, 0xbc, 0x0b, 0x01, 0x01, + 0x68, 0x2f, 0x02, 0x03, 0x70, 0x2f, 0x02, 0x03, 0x78, 0x2f, 0x02, 0x03, 0x80, 0x2f, 0x02, 0x03, 0xe0, 0x11, 0x03, 0x04, 0x00, 0x38, 0x06, 0x09, 0xc6, 0x05, 0x00, 0x01, 0xc8, 0x05, 0x00, 0x01, + 0xca, 0x05, 0x00, 0x01, 0xcc, 0x05, 0x00, 0x01, 0xce, 0x05, 0x00, 0x01, 0xd0, 0x05, 0x00, 0x01, 0xd2, 0x05, 0x00, 0x01, 0xd4, 0x05, 0x00, 0x01, 0xbe, 0x0b, 0x01, 0x01, 0xc0, 0x0b, 0x01, 0x01, + 0xc2, 0x0b, 0x01, 0x01, 0xc4, 0x0b, 0x01, 0x01, 0xc6, 0x0b, 0x01, 0x01, 0xc8, 0x0b, 0x01, 0x01, 0xca, 0x0b, 0x01, 0x01, 0xcc, 0x0b, 0x01, 0x01, 0xce, 0x0b, 0x01, 0x01, 0xd0, 0x0b, 0x01, 0x01, + 0x88, 0x2f, 0x02, 0x03, 0x90, 0x2f, 0x02, 0x03, 0x98, 0x2f, 0x02, 0x03, 0xa0, 0x2f, 0x02, 0x03, 0xf0, 0x11, 0x03, 0x04, 0x00, 0x3a, 0x06, 0x09, 0xd6, 0x05, 0x00, 0x01, 0xd8, 0x05, 0x00, 0x01, + 0xda, 0x05, 0x00, 0x01, 0xdc, 0x05, 0x00, 0x01, 0xde, 0x05, 0x00, 0x01, 0xe0, 0x05, 0x00, 0x01, 0xe2, 0x05, 0x00, 0x01, 0xe4, 0x05, 0x00, 0x01, 0xd2, 0x0b, 0x01, 0x01, 0xd4, 0x0b, 0x01, 0x01, + 0xd6, 0x0b, 0x01, 0x01, 0xd8, 0x0b, 0x01, 0x01, 0xda, 0x0b, 0x01, 0x01, 0xdc, 0x0b, 0x01, 0x01, 0xde, 0x0b, 0x01, 0x01, 0xe0, 0x0b, 0x01, 0x01, 0xe2, 0x0b, 0x01, 0x01, 0xe4, 0x0b, 0x01, 0x01, + 0xa8, 0x2f, 0x02, 0x03, 0xb0, 0x2f, 0x02, 0x03, 0xb8, 0x2f, 0x02, 0x03, 0xc0, 0x2f, 0x02, 0x03, 0x00, 0x12, 0x03, 0x04, 0x00, 0x3c, 0x06, 0x09, 0xe6, 0x05, 0x00, 0x01, 0xe8, 0x05, 0x00, 0x01, + 0xea, 0x05, 0x00, 0x01, 0xec, 0x05, 0x00, 0x01, 0xee, 0x05, 0x00, 0x01, 0xf0, 0x05, 0x00, 0x01, 0xf2, 0x05, 0x00, 0x01, 0xf4, 0x05, 0x00, 0x01, 0xe6, 0x0b, 0x01, 0x01, 0xe8, 0x0b, 0x01, 0x01, + 0xea, 0x0b, 0x01, 0x01, 0xec, 0x0b, 0x01, 0x01, 0xee, 0x0b, 0x01, 0x01, 0xf0, 0x0b, 0x01, 0x01, 0xf2, 0x0b, 0x01, 0x01, 0xf4, 0x0b, 0x01, 0x01, 0xf6, 0x0b, 0x01, 0x01, 0xf8, 0x0b, 0x01, 0x01, + 0xc8, 0x2f, 0x02, 0x03, 0xd0, 0x2f, 0x02, 0x03, 0xd8, 0x2f, 0x02, 0x03, 0xe0, 0x2f, 0x02, 0x03, 0x10, 0x12, 0x03, 0x04, 0x00, 0x3e, 0x06, 0x09, 0xf6, 0x05, 0x00, 0x01, 0xf8, 0x05, 0x00, 0x01, + 0xfa, 0x05, 0x00, 0x01, 0xfc, 0x05, 0x00, 0x01, 0xfe, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00, 0x01, 0x04, 0x06, 0x00, 0x01, 0xfa, 0x0b, 0x01, 0x01, 0xfc, 0x0b, 0x01, 0x01, + 0xfe, 0x0b, 0x01, 0x01, 0x00, 0x0c, 0x01, 0x01, 0x02, 0x0c, 0x01, 0x01, 0x04, 0x0c, 0x01, 0x01, 0x06, 0x0c, 0x01, 0x01, 0x08, 0x0c, 0x01, 0x01, 0x0a, 0x0c, 0x01, 0x01, 0x0c, 0x0c, 0x01, 0x01, + 0xe8, 0x2f, 0x02, 0x03, 0xf0, 0x2f, 0x02, 0x03, 0xf8, 0x2f, 0x02, 0x03, 0x20, 0x12, 0x03, 0x04, 0x30, 0x12, 0x03, 0x04, 0x00, 0x00, 0x06, 0x08, 0x06, 0x06, 0x00, 0x01, 0x08, 0x06, 0x00, 0x01, + 0x0a, 0x06, 0x00, 0x01, 0x0c, 0x06, 0x00, 0x01, 0x0e, 0x06, 0x00, 0x01, 0x10, 0x06, 0x00, 0x01, 0x12, 0x06, 0x00, 0x01, 0x14, 0x06, 0x00, 0x01, 0x0e, 0x0c, 0x01, 0x01, 0x10, 0x0c, 0x01, 0x01, + 0x12, 0x0c, 0x01, 0x01, 0x14, 0x0c, 0x01, 0x01, 0x16, 0x0c, 0x01, 0x01, 0x18, 0x0c, 0x01, 0x01, 0x1a, 0x0c, 0x01, 0x01, 0x1c, 0x0c, 0x01, 0x01, 0x1e, 0x0c, 0x01, 0x01, 0x20, 0x0c, 0x01, 0x01, + 0x00, 0x30, 0x02, 0x03, 0x08, 0x30, 0x02, 0x03, 0x10, 0x30, 0x02, 0x03, 0x40, 0x12, 0x03, 0x04, 0x50, 0x12, 0x03, 0x04, 0x00, 0x01, 0x06, 0x08, 0x16, 0x06, 0x00, 0x01, 0x18, 0x06, 0x00, 0x01, + 0x1a, 0x06, 0x00, 0x01, 0x1c, 0x06, 0x00, 0x01, 0x1e, 0x06, 0x00, 0x01, 0x20, 0x06, 0x00, 0x01, 0x22, 0x06, 0x00, 0x01, 0x24, 0x06, 0x00, 0x01, 0x22, 0x0c, 0x01, 0x01, 0x24, 0x0c, 0x01, 0x01, + 0x26, 0x0c, 0x01, 0x01, 0x28, 0x0c, 0x01, 0x01, 0x2a, 0x0c, 0x01, 0x01, 0x2c, 0x0c, 0x01, 0x01, 0x2e, 0x0c, 0x01, 0x01, 0x30, 0x0c, 0x01, 0x01, 0x32, 0x0c, 0x01, 0x01, 0x34, 0x0c, 0x01, 0x01, + 0x18, 0x30, 0x02, 0x03, 0x20, 0x30, 0x02, 0x03, 0x28, 0x30, 0x02, 0x03, 0x60, 0x12, 0x03, 0x04, 0x70, 0x12, 0x03, 0x04, 0x00, 0x1c, 0x07, 0x0a, 0x26, 0x06, 0x00, 0x01, 0x28, 0x06, 0x00, 0x01, + 0x2a, 0x06, 0x00, 0x01, 0x2c, 0x06, 0x00, 0x01, 0x2e, 0x06, 0x00, 0x01, 0x30, 0x06, 0x00, 0x01, 0x32, 0x06, 0x00, 0x01, 0x34, 0x06, 0x00, 0x01, 0x36, 0x0c, 0x01, 0x01, 0x38, 0x0c, 0x01, 0x01, + 0x3a, 0x0c, 0x01, 0x01, 0x3c, 0x0c, 0x01, 0x01, 0x3e, 0x0c, 0x01, 0x01, 0x40, 0x0c, 0x01, 0x01, 0x42, 0x0c, 0x01, 0x01, 0x44, 0x0c, 0x01, 0x01, 0x46, 0x0c, 0x01, 0x01, 0x48, 0x0c, 0x01, 0x01, + 0x30, 0x30, 0x02, 0x03, 0x38, 0x30, 0x02, 0x03, 0x40, 0x30, 0x02, 0x03, 0x80, 0x12, 0x03, 0x04, 0x90, 0x12, 0x03, 0x04, 0x00, 0x20, 0x07, 0x0a, 0x36, 0x06, 0x00, 0x01, 0x38, 0x06, 0x00, 0x01, + 0x3a, 0x06, 0x00, 0x01, 0x3c, 0x06, 0x00, 0x01, 0x3e, 0x06, 0x00, 0x01, 0x40, 0x06, 0x00, 0x01, 0x42, 0x06, 0x00, 0x01, 0x44, 0x06, 0x00, 0x01, 0x4a, 0x0c, 0x01, 0x01, 0x4c, 0x0c, 0x01, 0x01, + 0x4e, 0x0c, 0x01, 0x01, 0x50, 0x0c, 0x01, 0x01, 0x52, 0x0c, 0x01, 0x01, 0x54, 0x0c, 0x01, 0x01, 0x56, 0x0c, 0x01, 0x01, 0x58, 0x0c, 0x01, 0x01, 0x5a, 0x0c, 0x01, 0x01, 0x5c, 0x0c, 0x01, 0x01, + 0x48, 0x30, 0x02, 0x03, 0x50, 0x30, 0x02, 0x03, 0x58, 0x30, 0x02, 0x03, 0xa0, 0x12, 0x03, 0x04, 0xb0, 0x12, 0x03, 0x04, 0x00, 0x08, 0x08, 0x0b, 0x46, 0x06, 0x00, 0x01, 0x48, 0x06, 0x00, 0x01, + 0x4a, 0x06, 0x00, 0x01, 0x4c, 0x06, 0x00, 0x01, 0x4e, 0x06, 0x00, 0x01, 0x50, 0x06, 0x00, 0x01, 0x52, 0x06, 0x00, 0x01, 0x54, 0x06, 0x00, 0x01, 0x5e, 0x0c, 0x01, 0x01, 0x60, 0x0c, 0x01, 0x01, + 0x62, 0x0c, 0x01, 0x01, 0x64, 0x0c, 0x01, 0x01, 0x66, 0x0c, 0x01, 0x01, 0x68, 0x0c, 0x01, 0x01, 0x6a, 0x0c, 0x01, 0x01, 0x6c, 0x0c, 0x01, 0x01, 0x6e, 0x0c, 0x01, 0x01, 0x70, 0x0c, 0x01, 0x01, + 0x60, 0x30, 0x02, 0x03, 0x68, 0x30, 0x02, 0x03, 0x70, 0x30, 0x02, 0x03, 0xc0, 0x12, 0x03, 0x04, 0xd0, 0x12, 0x03, 0x04, 0x56, 0x06, 0x00, 0x01, 0x58, 0x06, 0x00, 0x01, 0x5a, 0x06, 0x00, 0x01, + 0x5c, 0x06, 0x00, 0x01, 0x5e, 0x06, 0x00, 0x01, 0x60, 0x06, 0x00, 0x01, 0x62, 0x06, 0x00, 0x01, 0x64, 0x06, 0x00, 0x01, 0x66, 0x06, 0x00, 0x01, 0x72, 0x0c, 0x01, 0x01, 0x74, 0x0c, 0x01, 0x01, + 0x76, 0x0c, 0x01, 0x01, 0x78, 0x0c, 0x01, 0x01, 0x7a, 0x0c, 0x01, 0x01, 0x7c, 0x0c, 0x01, 0x01, 0x7e, 0x0c, 0x01, 0x01, 0x80, 0x0c, 0x01, 0x01, 0x82, 0x0c, 0x01, 0x01, 0x84, 0x0c, 0x01, 0x01, + 0x78, 0x30, 0x02, 0x03, 0x80, 0x30, 0x02, 0x03, 0x88, 0x30, 0x02, 0x03, 0xe0, 0x12, 0x03, 0x04, 0xf0, 0x12, 0x03, 0x04, 0x68, 0x06, 0x00, 0x01, 0x6a, 0x06, 0x00, 0x01, 0x6c, 0x06, 0x00, 0x01, + 0x6e, 0x06, 0x00, 0x01, 0x70, 0x06, 0x00, 0x01, 0x72, 0x06, 0x00, 0x01, 0x74, 0x06, 0x00, 0x01, 0x76, 0x06, 0x00, 0x01, 0x78, 0x06, 0x00, 0x01, 0x86, 0x0c, 0x01, 0x01, 0x88, 0x0c, 0x01, 0x01, + 0x8a, 0x0c, 0x01, 0x01, 0x8c, 0x0c, 0x01, 0x01, 0x8e, 0x0c, 0x01, 0x01, 0x90, 0x0c, 0x01, 0x01, 0x92, 0x0c, 0x01, 0x01, 0x94, 0x0c, 0x01, 0x01, 0x96, 0x0c, 0x01, 0x01, 0x98, 0x0c, 0x01, 0x01, + 0x90, 0x30, 0x02, 0x03, 0x98, 0x30, 0x02, 0x03, 0xa0, 0x30, 0x02, 0x03, 0x00, 0x13, 0x03, 0x04, 0x10, 0x13, 0x03, 0x04, 0x7a, 0x06, 0x00, 0x01, 0x7c, 0x06, 0x00, 0x01, 0x7e, 0x06, 0x00, 0x01, + 0x80, 0x06, 0x00, 0x01, 0x82, 0x06, 0x00, 0x01, 0x84, 0x06, 0x00, 0x01, 0x86, 0x06, 0x00, 0x01, 0x88, 0x06, 0x00, 0x01, 0x8a, 0x06, 0x00, 0x01, 0x9a, 0x0c, 0x01, 0x01, 0x9c, 0x0c, 0x01, 0x01, + 0x9e, 0x0c, 0x01, 0x01, 0xa0, 0x0c, 0x01, 0x01, 0xa2, 0x0c, 0x01, 0x01, 0xa4, 0x0c, 0x01, 0x01, 0xa6, 0x0c, 0x01, 0x01, 0xa8, 0x0c, 0x01, 0x01, 0xaa, 0x0c, 0x01, 0x01, 0xac, 0x0c, 0x01, 0x01, + 0xa8, 0x30, 0x02, 0x03, 0xb0, 0x30, 0x02, 0x03, 0xb8, 0x30, 0x02, 0x03, 0x20, 0x13, 0x03, 0x04, 0x30, 0x13, 0x03, 0x04, 0x8c, 0x06, 0x00, 0x01, 0x8e, 0x06, 0x00, 0x01, 0x90, 0x06, 0x00, 0x01, + 0x92, 0x06, 0x00, 0x01, 0x94, 0x06, 0x00, 0x01, 0x96, 0x06, 0x00, 0x01, 0x98, 0x06, 0x00, 0x01, 0x9a, 0x06, 0x00, 0x01, 0x9c, 0x06, 0x00, 0x01, 0xae, 0x0c, 0x01, 0x01, 0xb0, 0x0c, 0x01, 0x01, + 0xb2, 0x0c, 0x01, 0x01, 0xb4, 0x0c, 0x01, 0x01, 0xb6, 0x0c, 0x01, 0x01, 0xb8, 0x0c, 0x01, 0x01, 0xba, 0x0c, 0x01, 0x01, 0xbc, 0x0c, 0x01, 0x01, 0xbe, 0x0c, 0x01, 0x01, 0xc0, 0x0c, 0x01, 0x01, + 0xc0, 0x30, 0x02, 0x03, 0xc8, 0x30, 0x02, 0x03, 0xd0, 0x30, 0x02, 0x03, 0x40, 0x13, 0x03, 0x04, 0x50, 0x13, 0x03, 0x04, 0x9e, 0x06, 0x00, 0x01, 0xa0, 0x06, 0x00, 0x01, 0xa2, 0x06, 0x00, 0x01, + 0xa4, 0x06, 0x00, 0x01, 0xa6, 0x06, 0x00, 0x01, 0xa8, 0x06, 0x00, 0x01, 0xaa, 0x06, 0x00, 0x01, 0xac, 0x06, 0x00, 0x01, 0xae, 0x06, 0x00, 0x01, 0xc2, 0x0c, 0x01, 0x01, 0xc4, 0x0c, 0x01, 0x01, + 0xc6, 0x0c, 0x01, 0x01, 0xc8, 0x0c, 0x01, 0x01, 0xca, 0x0c, 0x01, 0x01, 0xcc, 0x0c, 0x01, 0x01, 0xce, 0x0c, 0x01, 0x01, 0xd0, 0x0c, 0x01, 0x01, 0xd2, 0x0c, 0x01, 0x01, 0xd4, 0x0c, 0x01, 0x01, + 0xd8, 0x30, 0x02, 0x03, 0xe0, 0x30, 0x02, 0x03, 0xe8, 0x30, 0x02, 0x03, 0x60, 0x13, 0x03, 0x04, 0x70, 0x13, 0x03, 0x04, 0xb0, 0x06, 0x00, 0x01, 0xb2, 0x06, 0x00, 0x01, 0xb4, 0x06, 0x00, 0x01, + 0xb6, 0x06, 0x00, 0x01, 0xb8, 0x06, 0x00, 0x01, 0xba, 0x06, 0x00, 0x01, 0xbc, 0x06, 0x00, 0x01, 0xbe, 0x06, 0x00, 0x01, 0xc0, 0x06, 0x00, 0x01, 0xd6, 0x0c, 0x01, 0x01, 0xd8, 0x0c, 0x01, 0x01, + 0xda, 0x0c, 0x01, 0x01, 0xdc, 0x0c, 0x01, 0x01, 0xde, 0x0c, 0x01, 0x01, 0xe0, 0x0c, 0x01, 0x01, 0xe2, 0x0c, 0x01, 0x01, 0xe4, 0x0c, 0x01, 0x01, 0xe6, 0x0c, 0x01, 0x01, 0xe8, 0x0c, 0x01, 0x01, + 0xf0, 0x30, 0x02, 0x03, 0xf8, 0x30, 0x02, 0x03, 0x00, 0x31, 0x02, 0x03, 0x80, 0x13, 0x03, 0x04, 0x90, 0x13, 0x03, 0x04, 0xc2, 0x06, 0x00, 0x01, 0xc4, 0x06, 0x00, 0x01, 0xc6, 0x06, 0x00, 0x01, + 0xc8, 0x06, 0x00, 0x01, 0xca, 0x06, 0x00, 0x01, 0xcc, 0x06, 0x00, 0x01, 0xce, 0x06, 0x00, 0x01, 0xd0, 0x06, 0x00, 0x01, 0xd2, 0x06, 0x00, 0x01, 0xea, 0x0c, 0x01, 0x01, 0xec, 0x0c, 0x01, 0x01, + 0xee, 0x0c, 0x01, 0x01, 0xf0, 0x0c, 0x01, 0x01, 0xf2, 0x0c, 0x01, 0x01, 0xf4, 0x0c, 0x01, 0x01, 0xf6, 0x0c, 0x01, 0x01, 0xf8, 0x0c, 0x01, 0x01, 0xfa, 0x0c, 0x01, 0x01, 0xfc, 0x0c, 0x01, 0x01, + 0x08, 0x31, 0x02, 0x03, 0x10, 0x31, 0x02, 0x03, 0x18, 0x31, 0x02, 0x03, 0xa0, 0x13, 0x03, 0x04, 0xb0, 0x13, 0x03, 0x04, 0xd4, 0x06, 0x00, 0x01, 0xd6, 0x06, 0x00, 0x01, 0xd8, 0x06, 0x00, 0x01, + 0xda, 0x06, 0x00, 0x01, 0xdc, 0x06, 0x00, 0x01, 0xde, 0x06, 0x00, 0x01, 0xe0, 0x06, 0x00, 0x01, 0xe2, 0x06, 0x00, 0x01, 0xe4, 0x06, 0x00, 0x01, 0xfe, 0x0c, 0x01, 0x01, 0x00, 0x0d, 0x01, 0x01, + 0x02, 0x0d, 0x01, 0x01, 0x04, 0x0d, 0x01, 0x01, 0x06, 0x0d, 0x01, 0x01, 0x08, 0x0d, 0x01, 0x01, 0x0a, 0x0d, 0x01, 0x01, 0x0c, 0x0d, 0x01, 0x01, 0x0e, 0x0d, 0x01, 0x01, 0x10, 0x0d, 0x01, 0x01, + 0x20, 0x31, 0x02, 0x03, 0x28, 0x31, 0x02, 0x03, 0x30, 0x31, 0x02, 0x03, 0xc0, 0x13, 0x03, 0x04, 0xd0, 0x13, 0x03, 0x04, 0xe6, 0x06, 0x00, 0x01, 0xe8, 0x06, 0x00, 0x01, 0xea, 0x06, 0x00, 0x01, + 0xec, 0x06, 0x00, 0x01, 0xee, 0x06, 0x00, 0x01, 0xf0, 0x06, 0x00, 0x01, 0xf2, 0x06, 0x00, 0x01, 0xf4, 0x06, 0x00, 0x01, 0xf6, 0x06, 0x00, 0x01, 0x12, 0x0d, 0x01, 0x01, 0x14, 0x0d, 0x01, 0x01, + 0x16, 0x0d, 0x01, 0x01, 0x18, 0x0d, 0x01, 0x01, 0x1a, 0x0d, 0x01, 0x01, 0x1c, 0x0d, 0x01, 0x01, 0x1e, 0x0d, 0x01, 0x01, 0x20, 0x0d, 0x01, 0x01, 0x22, 0x0d, 0x01, 0x01, 0x24, 0x0d, 0x01, 0x01, + 0x38, 0x31, 0x02, 0x03, 0x40, 0x31, 0x02, 0x03, 0x48, 0x31, 0x02, 0x03, 0xe0, 0x13, 0x03, 0x04, 0xf0, 0x13, 0x03, 0x04, 0xf8, 0x06, 0x00, 0x01, 0xfa, 0x06, 0x00, 0x01, 0xfc, 0x06, 0x00, 0x01, + 0xfe, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x02, 0x07, 0x00, 0x01, 0x04, 0x07, 0x00, 0x01, 0x06, 0x07, 0x00, 0x01, 0x08, 0x07, 0x00, 0x01, 0x26, 0x0d, 0x01, 0x01, 0x28, 0x0d, 0x01, 0x01, + 0x2a, 0x0d, 0x01, 0x01, 0x2c, 0x0d, 0x01, 0x01, 0x2e, 0x0d, 0x01, 0x01, 0x30, 0x0d, 0x01, 0x01, 0x32, 0x0d, 0x01, 0x01, 0x34, 0x0d, 0x01, 0x01, 0x36, 0x0d, 0x01, 0x01, 0x38, 0x0d, 0x01, 0x01, + 0x50, 0x31, 0x02, 0x03, 0x58, 0x31, 0x02, 0x03, 0x60, 0x31, 0x02, 0x03, 0x00, 0x14, 0x03, 0x04, 0x10, 0x14, 0x03, 0x04, 0x0a, 0x07, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x01, 0x0e, 0x07, 0x00, 0x01, + 0x10, 0x07, 0x00, 0x01, 0x12, 0x07, 0x00, 0x01, 0x14, 0x07, 0x00, 0x01, 0x16, 0x07, 0x00, 0x01, 0x18, 0x07, 0x00, 0x01, 0x1a, 0x07, 0x00, 0x01, 0x3a, 0x0d, 0x01, 0x01, 0x3c, 0x0d, 0x01, 0x01, + 0x3e, 0x0d, 0x01, 0x01, 0x40, 0x0d, 0x01, 0x01, 0x42, 0x0d, 0x01, 0x01, 0x44, 0x0d, 0x01, 0x01, 0x46, 0x0d, 0x01, 0x01, 0x48, 0x0d, 0x01, 0x01, 0x4a, 0x0d, 0x01, 0x01, 0x4c, 0x0d, 0x01, 0x01, + 0x68, 0x31, 0x02, 0x03, 0x70, 0x31, 0x02, 0x03, 0x78, 0x31, 0x02, 0x03, 0x20, 0x14, 0x03, 0x04, 0x30, 0x14, 0x03, 0x04, 0x1c, 0x07, 0x00, 0x01, 0x1e, 0x07, 0x00, 0x01, 0x20, 0x07, 0x00, 0x01, + 0x22, 0x07, 0x00, 0x01, 0x24, 0x07, 0x00, 0x01, 0x26, 0x07, 0x00, 0x01, 0x28, 0x07, 0x00, 0x01, 0x2a, 0x07, 0x00, 0x01, 0x2c, 0x07, 0x00, 0x01, 0x4e, 0x0d, 0x01, 0x01, 0x50, 0x0d, 0x01, 0x01, + 0x52, 0x0d, 0x01, 0x01, 0x54, 0x0d, 0x01, 0x01, 0x56, 0x0d, 0x01, 0x01, 0x58, 0x0d, 0x01, 0x01, 0x5a, 0x0d, 0x01, 0x01, 0x5c, 0x0d, 0x01, 0x01, 0x5e, 0x0d, 0x01, 0x01, 0x60, 0x0d, 0x01, 0x01, + 0x80, 0x31, 0x02, 0x03, 0x88, 0x31, 0x02, 0x03, 0x90, 0x31, 0x02, 0x03, 0x40, 0x14, 0x03, 0x04, 0x50, 0x14, 0x03, 0x04, 0x2e, 0x07, 0x00, 0x01, 0x30, 0x07, 0x00, 0x01, 0x32, 0x07, 0x00, 0x01, + 0x34, 0x07, 0x00, 0x01, 0x36, 0x07, 0x00, 0x01, 0x38, 0x07, 0x00, 0x01, 0x3a, 0x07, 0x00, 0x01, 0x3c, 0x07, 0x00, 0x01, 0x3e, 0x07, 0x00, 0x01, 0x62, 0x0d, 0x01, 0x01, 0x64, 0x0d, 0x01, 0x01, + 0x66, 0x0d, 0x01, 0x01, 0x68, 0x0d, 0x01, 0x01, 0x6a, 0x0d, 0x01, 0x01, 0x6c, 0x0d, 0x01, 0x01, 0x6e, 0x0d, 0x01, 0x01, 0x70, 0x0d, 0x01, 0x01, 0x72, 0x0d, 0x01, 0x01, 0x74, 0x0d, 0x01, 0x01, + 0x98, 0x31, 0x02, 0x03, 0xa0, 0x31, 0x02, 0x03, 0xa8, 0x31, 0x02, 0x03, 0x60, 0x14, 0x03, 0x04, 0x70, 0x14, 0x03, 0x04, 0x40, 0x07, 0x00, 0x01, 0x42, 0x07, 0x00, 0x01, 0x44, 0x07, 0x00, 0x01, + 0x46, 0x07, 0x00, 0x01, 0x48, 0x07, 0x00, 0x01, 0x4a, 0x07, 0x00, 0x01, 0x4c, 0x07, 0x00, 0x01, 0x4e, 0x07, 0x00, 0x01, 0x50, 0x07, 0x00, 0x01, 0x76, 0x0d, 0x01, 0x01, 0x78, 0x0d, 0x01, 0x01, + 0x7a, 0x0d, 0x01, 0x01, 0x7c, 0x0d, 0x01, 0x01, 0x7e, 0x0d, 0x01, 0x01, 0x80, 0x0d, 0x01, 0x01, 0x82, 0x0d, 0x01, 0x01, 0x84, 0x0d, 0x01, 0x01, 0x86, 0x0d, 0x01, 0x01, 0x88, 0x0d, 0x01, 0x01, + 0xb0, 0x31, 0x02, 0x03, 0xb8, 0x31, 0x02, 0x03, 0xc0, 0x31, 0x02, 0x03, 0x80, 0x14, 0x03, 0x04, 0x90, 0x14, 0x03, 0x04, 0x52, 0x07, 0x00, 0x01, 0x54, 0x07, 0x00, 0x01, 0x56, 0x07, 0x00, 0x01, + 0x58, 0x07, 0x00, 0x01, 0x5a, 0x07, 0x00, 0x01, 0x5c, 0x07, 0x00, 0x01, 0x5e, 0x07, 0x00, 0x01, 0x60, 0x07, 0x00, 0x01, 0x62, 0x07, 0x00, 0x01, 0x8a, 0x0d, 0x01, 0x01, 0x8c, 0x0d, 0x01, 0x01, + 0x8e, 0x0d, 0x01, 0x01, 0x90, 0x0d, 0x01, 0x01, 0x92, 0x0d, 0x01, 0x01, 0x94, 0x0d, 0x01, 0x01, 0x96, 0x0d, 0x01, 0x01, 0x98, 0x0d, 0x01, 0x01, 0x9a, 0x0d, 0x01, 0x01, 0x9c, 0x0d, 0x01, 0x01, + 0xc8, 0x31, 0x02, 0x03, 0xd0, 0x31, 0x02, 0x03, 0xd8, 0x31, 0x02, 0x03, 0xa0, 0x14, 0x03, 0x04, 0xb0, 0x14, 0x03, 0x04, 0x64, 0x07, 0x00, 0x01, 0x66, 0x07, 0x00, 0x01, 0x68, 0x07, 0x00, 0x01, + 0x6a, 0x07, 0x00, 0x01, 0x6c, 0x07, 0x00, 0x01, 0x6e, 0x07, 0x00, 0x01, 0x70, 0x07, 0x00, 0x01, 0x72, 0x07, 0x00, 0x01, 0x74, 0x07, 0x00, 0x01, 0x9e, 0x0d, 0x01, 0x01, 0xa0, 0x0d, 0x01, 0x01, + 0xa2, 0x0d, 0x01, 0x01, 0xa4, 0x0d, 0x01, 0x01, 0xa6, 0x0d, 0x01, 0x01, 0xa8, 0x0d, 0x01, 0x01, 0xaa, 0x0d, 0x01, 0x01, 0xac, 0x0d, 0x01, 0x01, 0xae, 0x0d, 0x01, 0x01, 0xb0, 0x0d, 0x01, 0x01, + 0xe0, 0x31, 0x02, 0x03, 0xe8, 0x31, 0x02, 0x03, 0xf0, 0x31, 0x02, 0x03, 0xc0, 0x14, 0x03, 0x04, 0xd0, 0x14, 0x03, 0x04, 0x76, 0x07, 0x00, 0x01, 0x78, 0x07, 0x00, 0x01, 0x7a, 0x07, 0x00, 0x01, + 0x7c, 0x07, 0x00, 0x01, 0x7e, 0x07, 0x00, 0x01, 0x80, 0x07, 0x00, 0x01, 0x82, 0x07, 0x00, 0x01, 0x84, 0x07, 0x00, 0x01, 0x86, 0x07, 0x00, 0x01, 0xb2, 0x0d, 0x01, 0x01, 0xb4, 0x0d, 0x01, 0x01, + 0xb6, 0x0d, 0x01, 0x01, 0xb8, 0x0d, 0x01, 0x01, 0xba, 0x0d, 0x01, 0x01, 0xbc, 0x0d, 0x01, 0x01, 0xbe, 0x0d, 0x01, 0x01, 0xc0, 0x0d, 0x01, 0x01, 0xc2, 0x0d, 0x01, 0x01, 0xc4, 0x0d, 0x01, 0x01, + 0xf8, 0x31, 0x02, 0x03, 0x00, 0x32, 0x02, 0x03, 0x08, 0x32, 0x02, 0x03, 0xe0, 0x14, 0x03, 0x04, 0xf0, 0x14, 0x03, 0x04, 0x88, 0x07, 0x00, 0x01, 0x8a, 0x07, 0x00, 0x01, 0x8c, 0x07, 0x00, 0x01, + 0x8e, 0x07, 0x00, 0x01, 0x90, 0x07, 0x00, 0x01, 0x92, 0x07, 0x00, 0x01, 0x94, 0x07, 0x00, 0x01, 0x96, 0x07, 0x00, 0x01, 0x98, 0x07, 0x00, 0x01, 0xc6, 0x0d, 0x01, 0x01, 0xc8, 0x0d, 0x01, 0x01, + 0xca, 0x0d, 0x01, 0x01, 0xcc, 0x0d, 0x01, 0x01, 0xce, 0x0d, 0x01, 0x01, 0xd0, 0x0d, 0x01, 0x01, 0xd2, 0x0d, 0x01, 0x01, 0xd4, 0x0d, 0x01, 0x01, 0xd6, 0x0d, 0x01, 0x01, 0xd8, 0x0d, 0x01, 0x01, + 0x10, 0x32, 0x02, 0x03, 0x18, 0x32, 0x02, 0x03, 0x20, 0x32, 0x02, 0x03, 0x00, 0x15, 0x03, 0x04, 0x10, 0x15, 0x03, 0x04, 0x9a, 0x07, 0x00, 0x01, 0x9c, 0x07, 0x00, 0x01, 0x9e, 0x07, 0x00, 0x01, + 0xa0, 0x07, 0x00, 0x01, 0xa2, 0x07, 0x00, 0x01, 0xa4, 0x07, 0x00, 0x01, 0xa6, 0x07, 0x00, 0x01, 0xa8, 0x07, 0x00, 0x01, 0xaa, 0x07, 0x00, 0x01, 0xda, 0x0d, 0x01, 0x01, 0xdc, 0x0d, 0x01, 0x01, + 0xde, 0x0d, 0x01, 0x01, 0xe0, 0x0d, 0x01, 0x01, 0xe2, 0x0d, 0x01, 0x01, 0xe4, 0x0d, 0x01, 0x01, 0xe6, 0x0d, 0x01, 0x01, 0xe8, 0x0d, 0x01, 0x01, 0xea, 0x0d, 0x01, 0x01, 0xec, 0x0d, 0x01, 0x01, + 0x28, 0x32, 0x02, 0x03, 0x30, 0x32, 0x02, 0x03, 0x38, 0x32, 0x02, 0x03, 0x20, 0x15, 0x03, 0x04, 0x30, 0x15, 0x03, 0x04, 0xac, 0x07, 0x00, 0x01, 0xae, 0x07, 0x00, 0x01, 0xb0, 0x07, 0x00, 0x01, + 0xb2, 0x07, 0x00, 0x01, 0xb4, 0x07, 0x00, 0x01, 0xb6, 0x07, 0x00, 0x01, 0xb8, 0x07, 0x00, 0x01, 0xba, 0x07, 0x00, 0x01, 0xbc, 0x07, 0x00, 0x01, 0xee, 0x0d, 0x01, 0x01, 0xf0, 0x0d, 0x01, 0x01, + 0xf2, 0x0d, 0x01, 0x01, 0xf4, 0x0d, 0x01, 0x01, 0xf6, 0x0d, 0x01, 0x01, 0xf8, 0x0d, 0x01, 0x01, 0xfa, 0x0d, 0x01, 0x01, 0xfc, 0x0d, 0x01, 0x01, 0xfe, 0x0d, 0x01, 0x01, 0x00, 0x0e, 0x01, 0x01, + 0x40, 0x32, 0x02, 0x03, 0x48, 0x32, 0x02, 0x03, 0x50, 0x32, 0x02, 0x03, 0x40, 0x15, 0x03, 0x04, 0x50, 0x15, 0x03, 0x04, 0xbe, 0x07, 0x00, 0x01, 0xc0, 0x07, 0x00, 0x01, 0xc2, 0x07, 0x00, 0x01, + 0xc4, 0x07, 0x00, 0x01, 0xc6, 0x07, 0x00, 0x01, 0xc8, 0x07, 0x00, 0x01, 0xca, 0x07, 0x00, 0x01, 0xcc, 0x07, 0x00, 0x01, 0xce, 0x07, 0x00, 0x01, 0x02, 0x0e, 0x01, 0x01, 0x04, 0x0e, 0x01, 0x01, + 0x06, 0x0e, 0x01, 0x01, 0x08, 0x0e, 0x01, 0x01, 0x0a, 0x0e, 0x01, 0x01, 0x0c, 0x0e, 0x01, 0x01, 0x0e, 0x0e, 0x01, 0x01, 0x10, 0x0e, 0x01, 0x01, 0x12, 0x0e, 0x01, 0x01, 0x14, 0x0e, 0x01, 0x01, + 0x58, 0x32, 0x02, 0x03, 0x60, 0x32, 0x02, 0x03, 0x68, 0x32, 0x02, 0x03, 0x60, 0x15, 0x03, 0x04, 0x80, 0x39, 0x04, 0x06, 0xd0, 0x07, 0x00, 0x01, 0xd2, 0x07, 0x00, 0x01, 0xd4, 0x07, 0x00, 0x01, + 0xd6, 0x07, 0x00, 0x01, 0xd8, 0x07, 0x00, 0x01, 0xda, 0x07, 0x00, 0x01, 0xdc, 0x07, 0x00, 0x01, 0xde, 0x07, 0x00, 0x01, 0xe0, 0x07, 0x00, 0x01, 0x16, 0x0e, 0x01, 0x01, 0x18, 0x0e, 0x01, 0x01, + 0x1a, 0x0e, 0x01, 0x01, 0x1c, 0x0e, 0x01, 0x01, 0x1e, 0x0e, 0x01, 0x01, 0x20, 0x0e, 0x01, 0x01, 0x22, 0x0e, 0x01, 0x01, 0x24, 0x0e, 0x01, 0x01, 0x26, 0x0e, 0x01, 0x01, 0x28, 0x0e, 0x01, 0x01, + 0x70, 0x32, 0x02, 0x03, 0x78, 0x32, 0x02, 0x03, 0x80, 0x32, 0x02, 0x03, 0x70, 0x15, 0x03, 0x04, 0xc0, 0x39, 0x04, 0x06, 0xe2, 0x07, 0x00, 0x01, 0xe4, 0x07, 0x00, 0x01, 0xe6, 0x07, 0x00, 0x01, + 0xe8, 0x07, 0x00, 0x01, 0xea, 0x07, 0x00, 0x01, 0xec, 0x07, 0x00, 0x01, 0xee, 0x07, 0x00, 0x01, 0xf0, 0x07, 0x00, 0x01, 0xf2, 0x07, 0x00, 0x01, 0x2a, 0x0e, 0x01, 0x01, 0x2c, 0x0e, 0x01, 0x01, + 0x2e, 0x0e, 0x01, 0x01, 0x30, 0x0e, 0x01, 0x01, 0x32, 0x0e, 0x01, 0x01, 0x34, 0x0e, 0x01, 0x01, 0x36, 0x0e, 0x01, 0x01, 0x38, 0x0e, 0x01, 0x01, 0x3a, 0x0e, 0x01, 0x01, 0x3c, 0x0e, 0x01, 0x01, + 0x88, 0x32, 0x02, 0x03, 0x90, 0x32, 0x02, 0x03, 0x98, 0x32, 0x02, 0x03, 0x80, 0x15, 0x03, 0x04, 0x00, 0x3a, 0x04, 0x06, 0xf4, 0x07, 0x00, 0x01, 0xf6, 0x07, 0x00, 0x01, 0xf8, 0x07, 0x00, 0x01, + 0xfa, 0x07, 0x00, 0x01, 0xfc, 0x07, 0x00, 0x01, 0xfe, 0x07, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x02, 0x08, 0x00, 0x01, 0x04, 0x08, 0x00, 0x01, 0x3e, 0x0e, 0x01, 0x01, 0x40, 0x0e, 0x01, 0x01, + 0x42, 0x0e, 0x01, 0x01, 0x44, 0x0e, 0x01, 0x01, 0x46, 0x0e, 0x01, 0x01, 0x48, 0x0e, 0x01, 0x01, 0x4a, 0x0e, 0x01, 0x01, 0x4c, 0x0e, 0x01, 0x01, 0x4e, 0x0e, 0x01, 0x01, 0x50, 0x0e, 0x01, 0x01, + 0xa0, 0x32, 0x02, 0x03, 0xa8, 0x32, 0x02, 0x03, 0xb0, 0x32, 0x02, 0x03, 0x90, 0x15, 0x03, 0x04, 0x40, 0x3a, 0x04, 0x06, 0x06, 0x08, 0x00, 0x01, 0x08, 0x08, 0x00, 0x01, 0x0a, 0x08, 0x00, 0x01, + 0x0c, 0x08, 0x00, 0x01, 0x0e, 0x08, 0x00, 0x01, 0x10, 0x08, 0x00, 0x01, 0x12, 0x08, 0x00, 0x01, 0x14, 0x08, 0x00, 0x01, 0x16, 0x08, 0x00, 0x01, 0x52, 0x0e, 0x01, 0x01, 0x54, 0x0e, 0x01, 0x01, + 0x56, 0x0e, 0x01, 0x01, 0x58, 0x0e, 0x01, 0x01, 0x5a, 0x0e, 0x01, 0x01, 0x5c, 0x0e, 0x01, 0x01, 0x5e, 0x0e, 0x01, 0x01, 0x60, 0x0e, 0x01, 0x01, 0x62, 0x0e, 0x01, 0x01, 0x64, 0x0e, 0x01, 0x01, + 0xb8, 0x32, 0x02, 0x03, 0xc0, 0x32, 0x02, 0x03, 0xc8, 0x32, 0x02, 0x03, 0xa0, 0x15, 0x03, 0x04, 0x80, 0x3a, 0x04, 0x06, 0x18, 0x08, 0x00, 0x01, 0x1a, 0x08, 0x00, 0x01, 0x1c, 0x08, 0x00, 0x01, + 0x1e, 0x08, 0x00, 0x01, 0x20, 0x08, 0x00, 0x01, 0x22, 0x08, 0x00, 0x01, 0x24, 0x08, 0x00, 0x01, 0x26, 0x08, 0x00, 0x01, 0x28, 0x08, 0x00, 0x01, 0x66, 0x0e, 0x01, 0x01, 0x68, 0x0e, 0x01, 0x01, + 0x6a, 0x0e, 0x01, 0x01, 0x6c, 0x0e, 0x01, 0x01, 0x6e, 0x0e, 0x01, 0x01, 0x70, 0x0e, 0x01, 0x01, 0x72, 0x0e, 0x01, 0x01, 0x74, 0x0e, 0x01, 0x01, 0x76, 0x0e, 0x01, 0x01, 0x78, 0x0e, 0x01, 0x01, + 0xd0, 0x32, 0x02, 0x03, 0xd8, 0x32, 0x02, 0x03, 0xe0, 0x32, 0x02, 0x03, 0xb0, 0x15, 0x03, 0x04, 0xc0, 0x3a, 0x04, 0x06, 0x2a, 0x08, 0x00, 0x01, 0x2c, 0x08, 0x00, 0x01, 0x2e, 0x08, 0x00, 0x01, + 0x30, 0x08, 0x00, 0x01, 0x32, 0x08, 0x00, 0x01, 0x34, 0x08, 0x00, 0x01, 0x36, 0x08, 0x00, 0x01, 0x38, 0x08, 0x00, 0x01, 0x3a, 0x08, 0x00, 0x01, 0x7a, 0x0e, 0x01, 0x01, 0x7c, 0x0e, 0x01, 0x01, + 0x7e, 0x0e, 0x01, 0x01, 0x80, 0x0e, 0x01, 0x01, 0x82, 0x0e, 0x01, 0x01, 0x84, 0x0e, 0x01, 0x01, 0x86, 0x0e, 0x01, 0x01, 0x88, 0x0e, 0x01, 0x01, 0x8a, 0x0e, 0x01, 0x01, 0x8c, 0x0e, 0x01, 0x01, + 0xe8, 0x32, 0x02, 0x03, 0xf0, 0x32, 0x02, 0x03, 0xf8, 0x32, 0x02, 0x03, 0xc0, 0x15, 0x03, 0x04, 0x00, 0x3b, 0x04, 0x06, 0x3c, 0x08, 0x00, 0x01, 0x3e, 0x08, 0x00, 0x01, 0x40, 0x08, 0x00, 0x01, + 0x42, 0x08, 0x00, 0x01, 0x44, 0x08, 0x00, 0x01, 0x46, 0x08, 0x00, 0x01, 0x48, 0x08, 0x00, 0x01, 0x4a, 0x08, 0x00, 0x01, 0x4c, 0x08, 0x00, 0x01, 0x8e, 0x0e, 0x01, 0x01, 0x90, 0x0e, 0x01, 0x01, + 0x92, 0x0e, 0x01, 0x01, 0x94, 0x0e, 0x01, 0x01, 0x96, 0x0e, 0x01, 0x01, 0x98, 0x0e, 0x01, 0x01, 0x9a, 0x0e, 0x01, 0x01, 0x9c, 0x0e, 0x01, 0x01, 0x9e, 0x0e, 0x01, 0x01, 0xa0, 0x0e, 0x01, 0x01, + 0x00, 0x33, 0x02, 0x03, 0x08, 0x33, 0x02, 0x03, 0x10, 0x33, 0x02, 0x03, 0xd0, 0x15, 0x03, 0x04, 0x40, 0x3b, 0x04, 0x06, 0x4e, 0x08, 0x00, 0x01, 0x50, 0x08, 0x00, 0x01, 0x52, 0x08, 0x00, 0x01, + 0x54, 0x08, 0x00, 0x01, 0x56, 0x08, 0x00, 0x01, 0x58, 0x08, 0x00, 0x01, 0x5a, 0x08, 0x00, 0x01, 0x5c, 0x08, 0x00, 0x01, 0x5e, 0x08, 0x00, 0x01, 0xa2, 0x0e, 0x01, 0x01, 0xa4, 0x0e, 0x01, 0x01, + 0xa6, 0x0e, 0x01, 0x01, 0xa8, 0x0e, 0x01, 0x01, 0xaa, 0x0e, 0x01, 0x01, 0xac, 0x0e, 0x01, 0x01, 0xae, 0x0e, 0x01, 0x01, 0xb0, 0x0e, 0x01, 0x01, 0xb2, 0x0e, 0x01, 0x01, 0xb4, 0x0e, 0x01, 0x01, + 0x18, 0x33, 0x02, 0x03, 0x20, 0x33, 0x02, 0x03, 0x28, 0x33, 0x02, 0x03, 0xe0, 0x15, 0x03, 0x04, 0x80, 0x3b, 0x04, 0x06, 0x60, 0x08, 0x00, 0x01, 0x62, 0x08, 0x00, 0x01, 0x64, 0x08, 0x00, 0x01, + 0x66, 0x08, 0x00, 0x01, 0x68, 0x08, 0x00, 0x01, 0x6a, 0x08, 0x00, 0x01, 0x6c, 0x08, 0x00, 0x01, 0x6e, 0x08, 0x00, 0x01, 0x70, 0x08, 0x00, 0x01, 0xb6, 0x0e, 0x01, 0x01, 0xb8, 0x0e, 0x01, 0x01, + 0xba, 0x0e, 0x01, 0x01, 0xbc, 0x0e, 0x01, 0x01, 0xbe, 0x0e, 0x01, 0x01, 0xc0, 0x0e, 0x01, 0x01, 0xc2, 0x0e, 0x01, 0x01, 0xc4, 0x0e, 0x01, 0x01, 0xc6, 0x0e, 0x01, 0x01, 0xc8, 0x0e, 0x01, 0x01, + 0x30, 0x33, 0x02, 0x03, 0x38, 0x33, 0x02, 0x03, 0x40, 0x33, 0x02, 0x03, 0xf0, 0x15, 0x03, 0x04, 0xc0, 0x3b, 0x04, 0x06, 0x72, 0x08, 0x00, 0x01, 0x74, 0x08, 0x00, 0x01, 0x76, 0x08, 0x00, 0x01, + 0x78, 0x08, 0x00, 0x01, 0x7a, 0x08, 0x00, 0x01, 0x7c, 0x08, 0x00, 0x01, 0x7e, 0x08, 0x00, 0x01, 0x80, 0x08, 0x00, 0x01, 0x82, 0x08, 0x00, 0x01, 0xca, 0x0e, 0x01, 0x01, 0xcc, 0x0e, 0x01, 0x01, + 0xce, 0x0e, 0x01, 0x01, 0xd0, 0x0e, 0x01, 0x01, 0xd2, 0x0e, 0x01, 0x01, 0xd4, 0x0e, 0x01, 0x01, 0xd6, 0x0e, 0x01, 0x01, 0xd8, 0x0e, 0x01, 0x01, 0xda, 0x0e, 0x01, 0x01, 0xdc, 0x0e, 0x01, 0x01, + 0x48, 0x33, 0x02, 0x03, 0x50, 0x33, 0x02, 0x03, 0x58, 0x33, 0x02, 0x03, 0x00, 0x16, 0x03, 0x04, 0x00, 0x3c, 0x04, 0x06, 0x84, 0x08, 0x00, 0x01, 0x86, 0x08, 0x00, 0x01, 0x88, 0x08, 0x00, 0x01, + 0x8a, 0x08, 0x00, 0x01, 0x8c, 0x08, 0x00, 0x01, 0x8e, 0x08, 0x00, 0x01, 0x90, 0x08, 0x00, 0x01, 0x92, 0x08, 0x00, 0x01, 0x94, 0x08, 0x00, 0x01, 0xde, 0x0e, 0x01, 0x01, 0xe0, 0x0e, 0x01, 0x01, + 0xe2, 0x0e, 0x01, 0x01, 0xe4, 0x0e, 0x01, 0x01, 0xe6, 0x0e, 0x01, 0x01, 0xe8, 0x0e, 0x01, 0x01, 0xea, 0x0e, 0x01, 0x01, 0xec, 0x0e, 0x01, 0x01, 0xee, 0x0e, 0x01, 0x01, 0xf0, 0x0e, 0x01, 0x01, + 0x60, 0x33, 0x02, 0x03, 0x68, 0x33, 0x02, 0x03, 0x70, 0x33, 0x02, 0x03, 0x10, 0x16, 0x03, 0x04, 0x40, 0x3c, 0x04, 0x06, 0x96, 0x08, 0x00, 0x01, 0x98, 0x08, 0x00, 0x01, 0x9a, 0x08, 0x00, 0x01, + 0x9c, 0x08, 0x00, 0x01, 0x9e, 0x08, 0x00, 0x01, 0xa0, 0x08, 0x00, 0x01, 0xa2, 0x08, 0x00, 0x01, 0xa4, 0x08, 0x00, 0x01, 0xa6, 0x08, 0x00, 0x01, 0xf2, 0x0e, 0x01, 0x01, 0xf4, 0x0e, 0x01, 0x01, + 0xf6, 0x0e, 0x01, 0x01, 0xf8, 0x0e, 0x01, 0x01, 0xfa, 0x0e, 0x01, 0x01, 0xfc, 0x0e, 0x01, 0x01, 0xfe, 0x0e, 0x01, 0x01, 0x00, 0x0f, 0x01, 0x01, 0x02, 0x0f, 0x01, 0x01, 0x04, 0x0f, 0x01, 0x01, + 0x78, 0x33, 0x02, 0x03, 0x80, 0x33, 0x02, 0x03, 0x88, 0x33, 0x02, 0x03, 0x20, 0x16, 0x03, 0x04, 0x80, 0x3c, 0x04, 0x06, 0xa8, 0x08, 0x00, 0x01, 0xaa, 0x08, 0x00, 0x01, 0xac, 0x08, 0x00, 0x01, + 0xae, 0x08, 0x00, 0x01, 0xb0, 0x08, 0x00, 0x01, 0xb2, 0x08, 0x00, 0x01, 0xb4, 0x08, 0x00, 0x01, 0xb6, 0x08, 0x00, 0x01, 0xb8, 0x08, 0x00, 0x01, 0x06, 0x0f, 0x01, 0x01, 0x08, 0x0f, 0x01, 0x01, + 0x0a, 0x0f, 0x01, 0x01, 0x0c, 0x0f, 0x01, 0x01, 0x0e, 0x0f, 0x01, 0x01, 0x10, 0x0f, 0x01, 0x01, 0x12, 0x0f, 0x01, 0x01, 0x14, 0x0f, 0x01, 0x01, 0x16, 0x0f, 0x01, 0x01, 0x18, 0x0f, 0x01, 0x01, + 0x90, 0x33, 0x02, 0x03, 0x98, 0x33, 0x02, 0x03, 0xa0, 0x33, 0x02, 0x03, 0x30, 0x16, 0x03, 0x04, 0xc0, 0x3c, 0x04, 0x06, 0xba, 0x08, 0x00, 0x01, 0xbc, 0x08, 0x00, 0x01, 0xbe, 0x08, 0x00, 0x01, + 0xc0, 0x08, 0x00, 0x01, 0xc2, 0x08, 0x00, 0x01, 0xc4, 0x08, 0x00, 0x01, 0xc6, 0x08, 0x00, 0x01, 0xc8, 0x08, 0x00, 0x01, 0xca, 0x08, 0x00, 0x01, 0x1a, 0x0f, 0x01, 0x01, 0x1c, 0x0f, 0x01, 0x01, + 0x1e, 0x0f, 0x01, 0x01, 0x20, 0x0f, 0x01, 0x01, 0x22, 0x0f, 0x01, 0x01, 0x24, 0x0f, 0x01, 0x01, 0x26, 0x0f, 0x01, 0x01, 0x28, 0x0f, 0x01, 0x01, 0x2a, 0x0f, 0x01, 0x01, 0x2c, 0x0f, 0x01, 0x01, + 0xa8, 0x33, 0x02, 0x03, 0xb0, 0x33, 0x02, 0x03, 0xb8, 0x33, 0x02, 0x03, 0x40, 0x16, 0x03, 0x04, 0x00, 0x3d, 0x04, 0x06, 0xcc, 0x08, 0x00, 0x01, 0xce, 0x08, 0x00, 0x01, 0xd0, 0x08, 0x00, 0x01, + 0xd2, 0x08, 0x00, 0x01, 0xd4, 0x08, 0x00, 0x01, 0xd6, 0x08, 0x00, 0x01, 0xd8, 0x08, 0x00, 0x01, 0xda, 0x08, 0x00, 0x01, 0xdc, 0x08, 0x00, 0x01, 0x2e, 0x0f, 0x01, 0x01, 0x30, 0x0f, 0x01, 0x01, + 0x32, 0x0f, 0x01, 0x01, 0x34, 0x0f, 0x01, 0x01, 0x36, 0x0f, 0x01, 0x01, 0x38, 0x0f, 0x01, 0x01, 0x3a, 0x0f, 0x01, 0x01, 0x3c, 0x0f, 0x01, 0x01, 0x3e, 0x0f, 0x01, 0x01, 0xc0, 0x33, 0x02, 0x03, + 0xc8, 0x33, 0x02, 0x03, 0xd0, 0x33, 0x02, 0x03, 0xd8, 0x33, 0x02, 0x03, 0x50, 0x16, 0x03, 0x04, 0x40, 0x3d, 0x04, 0x06, 0xde, 0x08, 0x00, 0x01, 0xe0, 0x08, 0x00, 0x01, 0xe2, 0x08, 0x00, 0x01, + 0xe4, 0x08, 0x00, 0x01, 0xe6, 0x08, 0x00, 0x01, 0xe8, 0x08, 0x00, 0x01, 0xea, 0x08, 0x00, 0x01, 0xec, 0x08, 0x00, 0x01, 0xee, 0x08, 0x00, 0x01, 0x40, 0x0f, 0x01, 0x01, 0x42, 0x0f, 0x01, 0x01, + 0x44, 0x0f, 0x01, 0x01, 0x46, 0x0f, 0x01, 0x01, 0x48, 0x0f, 0x01, 0x01, 0x4a, 0x0f, 0x01, 0x01, 0x4c, 0x0f, 0x01, 0x01, 0x4e, 0x0f, 0x01, 0x01, 0x50, 0x0f, 0x01, 0x01, 0xe0, 0x33, 0x02, 0x03, + 0xe8, 0x33, 0x02, 0x03, 0xf0, 0x33, 0x02, 0x03, 0xf8, 0x33, 0x02, 0x03, 0x60, 0x16, 0x03, 0x04, 0x80, 0x3d, 0x04, 0x06, 0xf0, 0x08, 0x00, 0x01, 0xf2, 0x08, 0x00, 0x01, 0xf4, 0x08, 0x00, 0x01, + 0xf6, 0x08, 0x00, 0x01, 0xf8, 0x08, 0x00, 0x01, 0xfa, 0x08, 0x00, 0x01, 0xfc, 0x08, 0x00, 0x01, 0xfe, 0x08, 0x00, 0x01, 0x00, 0x09, 0x00, 0x01, 0x52, 0x0f, 0x01, 0x01, 0x54, 0x0f, 0x01, 0x01, + 0x56, 0x0f, 0x01, 0x01, 0x58, 0x0f, 0x01, 0x01, 0x5a, 0x0f, 0x01, 0x01, 0x5c, 0x0f, 0x01, 0x01, 0x5e, 0x0f, 0x01, 0x01, 0x60, 0x0f, 0x01, 0x01, 0x62, 0x0f, 0x01, 0x01, 0x00, 0x34, 0x02, 0x03, + 0x08, 0x34, 0x02, 0x03, 0x10, 0x34, 0x02, 0x03, 0x18, 0x34, 0x02, 0x03, 0x70, 0x16, 0x03, 0x04, 0xc0, 0x3d, 0x04, 0x06, 0x02, 0x09, 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x06, 0x09, 0x00, 0x01, + 0x08, 0x09, 0x00, 0x01, 0x0a, 0x09, 0x00, 0x01, 0x0c, 0x09, 0x00, 0x01, 0x0e, 0x09, 0x00, 0x01, 0x10, 0x09, 0x00, 0x01, 0x12, 0x09, 0x00, 0x01, 0x64, 0x0f, 0x01, 0x01, 0x66, 0x0f, 0x01, 0x01, + 0x68, 0x0f, 0x01, 0x01, 0x6a, 0x0f, 0x01, 0x01, 0x6c, 0x0f, 0x01, 0x01, 0x6e, 0x0f, 0x01, 0x01, 0x70, 0x0f, 0x01, 0x01, 0x72, 0x0f, 0x01, 0x01, 0x74, 0x0f, 0x01, 0x01, 0x20, 0x34, 0x02, 0x03, + 0x28, 0x34, 0x02, 0x03, 0x30, 0x34, 0x02, 0x03, 0x38, 0x34, 0x02, 0x03, 0x80, 0x16, 0x03, 0x04, 0x00, 0x3e, 0x04, 0x06, 0x14, 0x09, 0x00, 0x01, 0x16, 0x09, 0x00, 0x01, 0x18, 0x09, 0x00, 0x01, + 0x1a, 0x09, 0x00, 0x01, 0x1c, 0x09, 0x00, 0x01, 0x1e, 0x09, 0x00, 0x01, 0x20, 0x09, 0x00, 0x01, 0x22, 0x09, 0x00, 0x01, 0x24, 0x09, 0x00, 0x01, 0x76, 0x0f, 0x01, 0x01, 0x78, 0x0f, 0x01, 0x01, + 0x7a, 0x0f, 0x01, 0x01, 0x7c, 0x0f, 0x01, 0x01, 0x7e, 0x0f, 0x01, 0x01, 0x80, 0x0f, 0x01, 0x01, 0x82, 0x0f, 0x01, 0x01, 0x84, 0x0f, 0x01, 0x01, 0x86, 0x0f, 0x01, 0x01, 0x40, 0x34, 0x02, 0x03, + 0x48, 0x34, 0x02, 0x03, 0x50, 0x34, 0x02, 0x03, 0x58, 0x34, 0x02, 0x03, 0x90, 0x16, 0x03, 0x04, 0x40, 0x3e, 0x04, 0x06, 0x26, 0x09, 0x00, 0x01, 0x28, 0x09, 0x00, 0x01, 0x2a, 0x09, 0x00, 0x01, + 0x2c, 0x09, 0x00, 0x01, 0x2e, 0x09, 0x00, 0x01, 0x30, 0x09, 0x00, 0x01, 0x32, 0x09, 0x00, 0x01, 0x34, 0x09, 0x00, 0x01, 0x36, 0x09, 0x00, 0x01, 0x88, 0x0f, 0x01, 0x01, 0x8a, 0x0f, 0x01, 0x01, + 0x8c, 0x0f, 0x01, 0x01, 0x8e, 0x0f, 0x01, 0x01, 0x90, 0x0f, 0x01, 0x01, 0x92, 0x0f, 0x01, 0x01, 0x94, 0x0f, 0x01, 0x01, 0x96, 0x0f, 0x01, 0x01, 0x98, 0x0f, 0x01, 0x01, 0x60, 0x34, 0x02, 0x03, + 0x68, 0x34, 0x02, 0x03, 0x70, 0x34, 0x02, 0x03, 0x78, 0x34, 0x02, 0x03, 0xa0, 0x16, 0x03, 0x04, 0x80, 0x3e, 0x04, 0x06, 0x38, 0x09, 0x00, 0x01, 0x3a, 0x09, 0x00, 0x01, 0x3c, 0x09, 0x00, 0x01, + 0x3e, 0x09, 0x00, 0x01, 0x40, 0x09, 0x00, 0x01, 0x42, 0x09, 0x00, 0x01, 0x44, 0x09, 0x00, 0x01, 0x46, 0x09, 0x00, 0x01, 0x48, 0x09, 0x00, 0x01, 0x9a, 0x0f, 0x01, 0x01, 0x9c, 0x0f, 0x01, 0x01, + 0x9e, 0x0f, 0x01, 0x01, 0xa0, 0x0f, 0x01, 0x01, 0xa2, 0x0f, 0x01, 0x01, 0xa4, 0x0f, 0x01, 0x01, 0xa6, 0x0f, 0x01, 0x01, 0xa8, 0x0f, 0x01, 0x01, 0xaa, 0x0f, 0x01, 0x01, 0x80, 0x34, 0x02, 0x03, + 0x88, 0x34, 0x02, 0x03, 0x90, 0x34, 0x02, 0x03, 0x98, 0x34, 0x02, 0x03, 0xb0, 0x16, 0x03, 0x04, 0xc0, 0x3e, 0x04, 0x06, 0x4a, 0x09, 0x00, 0x01, 0x4c, 0x09, 0x00, 0x01, 0x4e, 0x09, 0x00, 0x01, + 0x50, 0x09, 0x00, 0x01, 0x52, 0x09, 0x00, 0x01, 0x54, 0x09, 0x00, 0x01, 0x56, 0x09, 0x00, 0x01, 0x58, 0x09, 0x00, 0x01, 0x5a, 0x09, 0x00, 0x01, 0xac, 0x0f, 0x01, 0x01, 0xae, 0x0f, 0x01, 0x01, + 0xb0, 0x0f, 0x01, 0x01, 0xb2, 0x0f, 0x01, 0x01, 0xb4, 0x0f, 0x01, 0x01, 0xb6, 0x0f, 0x01, 0x01, 0xb8, 0x0f, 0x01, 0x01, 0xba, 0x0f, 0x01, 0x01, 0xbc, 0x0f, 0x01, 0x01, 0xa0, 0x34, 0x02, 0x03, + 0xa8, 0x34, 0x02, 0x03, 0xb0, 0x34, 0x02, 0x03, 0xb8, 0x34, 0x02, 0x03, 0xc0, 0x16, 0x03, 0x04, 0x00, 0x3f, 0x04, 0x06, 0x5c, 0x09, 0x00, 0x01, 0x5e, 0x09, 0x00, 0x01, 0x60, 0x09, 0x00, 0x01, + 0x62, 0x09, 0x00, 0x01, 0x64, 0x09, 0x00, 0x01, 0x66, 0x09, 0x00, 0x01, 0x68, 0x09, 0x00, 0x01, 0x6a, 0x09, 0x00, 0x01, 0x6c, 0x09, 0x00, 0x01, 0xbe, 0x0f, 0x01, 0x01, 0xc0, 0x0f, 0x01, 0x01, + 0xc2, 0x0f, 0x01, 0x01, 0xc4, 0x0f, 0x01, 0x01, 0xc6, 0x0f, 0x01, 0x01, 0xc8, 0x0f, 0x01, 0x01, 0xca, 0x0f, 0x01, 0x01, 0xcc, 0x0f, 0x01, 0x01, 0xce, 0x0f, 0x01, 0x01, 0xc0, 0x34, 0x02, 0x03, + 0xc8, 0x34, 0x02, 0x03, 0xd0, 0x34, 0x02, 0x03, 0xd8, 0x34, 0x02, 0x03, 0xd0, 0x16, 0x03, 0x04, 0x40, 0x3f, 0x04, 0x06, 0x6e, 0x09, 0x00, 0x01, 0x70, 0x09, 0x00, 0x01, 0x72, 0x09, 0x00, 0x01, + 0x74, 0x09, 0x00, 0x01, 0x76, 0x09, 0x00, 0x01, 0x78, 0x09, 0x00, 0x01, 0x7a, 0x09, 0x00, 0x01, 0x7c, 0x09, 0x00, 0x01, 0x7e, 0x09, 0x00, 0x01, 0xd0, 0x0f, 0x01, 0x01, 0xd2, 0x0f, 0x01, 0x01, + 0xd4, 0x0f, 0x01, 0x01, 0xd6, 0x0f, 0x01, 0x01, 0xd8, 0x0f, 0x01, 0x01, 0xda, 0x0f, 0x01, 0x01, 0xdc, 0x0f, 0x01, 0x01, 0xde, 0x0f, 0x01, 0x01, 0xe0, 0x0f, 0x01, 0x01, 0xe0, 0x34, 0x02, 0x03, + 0xe8, 0x34, 0x02, 0x03, 0xf0, 0x34, 0x02, 0x03, 0xf8, 0x34, 0x02, 0x03, 0xe0, 0x16, 0x03, 0x04, 0x80, 0x3f, 0x04, 0x06, 0x80, 0x09, 0x00, 0x01, 0x82, 0x09, 0x00, 0x01, 0x84, 0x09, 0x00, 0x01, + 0x86, 0x09, 0x00, 0x01, 0x88, 0x09, 0x00, 0x01, 0x8a, 0x09, 0x00, 0x01, 0x8c, 0x09, 0x00, 0x01, 0x8e, 0x09, 0x00, 0x01, 0x90, 0x09, 0x00, 0x01, 0xe2, 0x0f, 0x01, 0x01, 0xe4, 0x0f, 0x01, 0x01, + 0xe6, 0x0f, 0x01, 0x01, 0xe8, 0x0f, 0x01, 0x01, 0xea, 0x0f, 0x01, 0x01, 0xec, 0x0f, 0x01, 0x01, 0xee, 0x0f, 0x01, 0x01, 0xf0, 0x0f, 0x01, 0x01, 0xf2, 0x0f, 0x01, 0x01, 0x00, 0x35, 0x02, 0x03, + 0x08, 0x35, 0x02, 0x03, 0x10, 0x35, 0x02, 0x03, 0x18, 0x35, 0x02, 0x03, 0xf0, 0x16, 0x03, 0x04, 0xc0, 0x3f, 0x04, 0x06, 0x92, 0x09, 0x00, 0x01, 0x94, 0x09, 0x00, 0x01, 0x96, 0x09, 0x00, 0x01, + 0x98, 0x09, 0x00, 0x01, 0x9a, 0x09, 0x00, 0x01, 0x9c, 0x09, 0x00, 0x01, 0x9e, 0x09, 0x00, 0x01, 0xa0, 0x09, 0x00, 0x01, 0xa2, 0x09, 0x00, 0x01, 0xf4, 0x0f, 0x01, 0x01, 0xf6, 0x0f, 0x01, 0x01, + 0xf8, 0x0f, 0x01, 0x01, 0xfa, 0x0f, 0x01, 0x01, 0xfc, 0x0f, 0x01, 0x01, 0xfe, 0x0f, 0x01, 0x01, 0x00, 0x10, 0x01, 0x01, 0x02, 0x10, 0x01, 0x01, 0x04, 0x10, 0x01, 0x01, 0x20, 0x35, 0x02, 0x03, + 0x28, 0x35, 0x02, 0x03, 0x30, 0x35, 0x02, 0x03, 0x38, 0x35, 0x02, 0x03, 0x00, 0x17, 0x03, 0x04, 0x00, 0x00, 0x04, 0x05, 0xa4, 0x09, 0x00, 0x01, 0xa6, 0x09, 0x00, 0x01, 0xa8, 0x09, 0x00, 0x01, + 0xaa, 0x09, 0x00, 0x01, 0xac, 0x09, 0x00, 0x01, 0xae, 0x09, 0x00, 0x01, 0xb0, 0x09, 0x00, 0x01, 0xb2, 0x09, 0x00, 0x01, 0xb4, 0x09, 0x00, 0x01, 0x06, 0x10, 0x01, 0x01, 0x08, 0x10, 0x01, 0x01, + 0x0a, 0x10, 0x01, 0x01, 0x0c, 0x10, 0x01, 0x01, 0x0e, 0x10, 0x01, 0x01, 0x10, 0x10, 0x01, 0x01, 0x12, 0x10, 0x01, 0x01, 0x14, 0x10, 0x01, 0x01, 0x16, 0x10, 0x01, 0x01, 0x40, 0x35, 0x02, 0x03, + 0x48, 0x35, 0x02, 0x03, 0x50, 0x35, 0x02, 0x03, 0x58, 0x35, 0x02, 0x03, 0x10, 0x17, 0x03, 0x04, 0x20, 0x00, 0x04, 0x05, 0xb6, 0x09, 0x00, 0x01, 0xb8, 0x09, 0x00, 0x01, 0xba, 0x09, 0x00, 0x01, + 0xbc, 0x09, 0x00, 0x01, 0xbe, 0x09, 0x00, 0x01, 0xc0, 0x09, 0x00, 0x01, 0xc2, 0x09, 0x00, 0x01, 0xc4, 0x09, 0x00, 0x01, 0xc6, 0x09, 0x00, 0x01, 0x18, 0x10, 0x01, 0x01, 0x1a, 0x10, 0x01, 0x01, + 0x1c, 0x10, 0x01, 0x01, 0x1e, 0x10, 0x01, 0x01, 0x20, 0x10, 0x01, 0x01, 0x22, 0x10, 0x01, 0x01, 0x24, 0x10, 0x01, 0x01, 0x26, 0x10, 0x01, 0x01, 0x28, 0x10, 0x01, 0x01, 0x60, 0x35, 0x02, 0x03, + 0x68, 0x35, 0x02, 0x03, 0x70, 0x35, 0x02, 0x03, 0x78, 0x35, 0x02, 0x03, 0x20, 0x17, 0x03, 0x04, 0x40, 0x00, 0x04, 0x05, 0xc8, 0x09, 0x00, 0x01, 0xca, 0x09, 0x00, 0x01, 0xcc, 0x09, 0x00, 0x01, + 0xce, 0x09, 0x00, 0x01, 0xd0, 0x09, 0x00, 0x01, 0xd2, 0x09, 0x00, 0x01, 0xd4, 0x09, 0x00, 0x01, 0xd6, 0x09, 0x00, 0x01, 0xd8, 0x09, 0x00, 0x01, 0x2a, 0x10, 0x01, 0x01, 0x2c, 0x10, 0x01, 0x01, + 0x2e, 0x10, 0x01, 0x01, 0x30, 0x10, 0x01, 0x01, 0x32, 0x10, 0x01, 0x01, 0x34, 0x10, 0x01, 0x01, 0x36, 0x10, 0x01, 0x01, 0x38, 0x10, 0x01, 0x01, 0x3a, 0x10, 0x01, 0x01, 0x80, 0x35, 0x02, 0x03, + 0x88, 0x35, 0x02, 0x03, 0x90, 0x35, 0x02, 0x03, 0x98, 0x35, 0x02, 0x03, 0x30, 0x17, 0x03, 0x04, 0x60, 0x00, 0x04, 0x05, 0xda, 0x09, 0x00, 0x01, 0xdc, 0x09, 0x00, 0x01, 0xde, 0x09, 0x00, 0x01, + 0xe0, 0x09, 0x00, 0x01, 0xe2, 0x09, 0x00, 0x01, 0xe4, 0x09, 0x00, 0x01, 0xe6, 0x09, 0x00, 0x01, 0xe8, 0x09, 0x00, 0x01, 0xea, 0x09, 0x00, 0x01, 0x3c, 0x10, 0x01, 0x01, 0x3e, 0x10, 0x01, 0x01, + 0x40, 0x10, 0x01, 0x01, 0x42, 0x10, 0x01, 0x01, 0x44, 0x10, 0x01, 0x01, 0x46, 0x10, 0x01, 0x01, 0x48, 0x10, 0x01, 0x01, 0x4a, 0x10, 0x01, 0x01, 0x4c, 0x10, 0x01, 0x01, 0xa0, 0x35, 0x02, 0x03, + 0xa8, 0x35, 0x02, 0x03, 0xb0, 0x35, 0x02, 0x03, 0xb8, 0x35, 0x02, 0x03, 0x40, 0x17, 0x03, 0x04, 0x80, 0x00, 0x04, 0x05, 0xec, 0x09, 0x00, 0x01, 0xee, 0x09, 0x00, 0x01, 0xf0, 0x09, 0x00, 0x01, + 0xf2, 0x09, 0x00, 0x01, 0xf4, 0x09, 0x00, 0x01, 0xf6, 0x09, 0x00, 0x01, 0xf8, 0x09, 0x00, 0x01, 0xfa, 0x09, 0x00, 0x01, 0xfc, 0x09, 0x00, 0x01, 0x4e, 0x10, 0x01, 0x01, 0x50, 0x10, 0x01, 0x01, + 0x52, 0x10, 0x01, 0x01, 0x54, 0x10, 0x01, 0x01, 0x56, 0x10, 0x01, 0x01, 0x58, 0x10, 0x01, 0x01, 0x5a, 0x10, 0x01, 0x01, 0x5c, 0x10, 0x01, 0x01, 0x5e, 0x10, 0x01, 0x01, 0xc0, 0x35, 0x02, 0x03, + 0xc8, 0x35, 0x02, 0x03, 0xd0, 0x35, 0x02, 0x03, 0xd8, 0x35, 0x02, 0x03, 0x50, 0x17, 0x03, 0x04, 0xa0, 0x00, 0x04, 0x05, 0xfe, 0x09, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x02, 0x0a, 0x00, 0x01, + 0x04, 0x0a, 0x00, 0x01, 0x06, 0x0a, 0x00, 0x01, 0x08, 0x0a, 0x00, 0x01, 0x0a, 0x0a, 0x00, 0x01, 0x0c, 0x0a, 0x00, 0x01, 0x0e, 0x0a, 0x00, 0x01, 0x60, 0x10, 0x01, 0x01, 0x62, 0x10, 0x01, 0x01, + 0x64, 0x10, 0x01, 0x01, 0x66, 0x10, 0x01, 0x01, 0x68, 0x10, 0x01, 0x01, 0x6a, 0x10, 0x01, 0x01, 0x6c, 0x10, 0x01, 0x01, 0x6e, 0x10, 0x01, 0x01, 0x70, 0x10, 0x01, 0x01, 0xe0, 0x35, 0x02, 0x03, + 0xe8, 0x35, 0x02, 0x03, 0xf0, 0x35, 0x02, 0x03, 0xf8, 0x35, 0x02, 0x03, 0x60, 0x17, 0x03, 0x04, 0xc0, 0x00, 0x04, 0x05, 0x10, 0x0a, 0x00, 0x01, 0x12, 0x0a, 0x00, 0x01, 0x14, 0x0a, 0x00, 0x01, + 0x16, 0x0a, 0x00, 0x01, 0x18, 0x0a, 0x00, 0x01, 0x1a, 0x0a, 0x00, 0x01, 0x1c, 0x0a, 0x00, 0x01, 0x1e, 0x0a, 0x00, 0x01, 0x20, 0x0a, 0x00, 0x01, 0x72, 0x10, 0x01, 0x01, 0x74, 0x10, 0x01, 0x01, + 0x76, 0x10, 0x01, 0x01, 0x78, 0x10, 0x01, 0x01, 0x7a, 0x10, 0x01, 0x01, 0x7c, 0x10, 0x01, 0x01, 0x7e, 0x10, 0x01, 0x01, 0x80, 0x10, 0x01, 0x01, 0x82, 0x10, 0x01, 0x01, 0x00, 0x36, 0x02, 0x03, + 0x08, 0x36, 0x02, 0x03, 0x10, 0x36, 0x02, 0x03, 0x18, 0x36, 0x02, 0x03, 0x70, 0x17, 0x03, 0x04, 0xe0, 0x00, 0x04, 0x05, 0x22, 0x0a, 0x00, 0x01, 0x24, 0x0a, 0x00, 0x01, 0x26, 0x0a, 0x00, 0x01, + 0x28, 0x0a, 0x00, 0x01, 0x2a, 0x0a, 0x00, 0x01, 0x2c, 0x0a, 0x00, 0x01, 0x2e, 0x0a, 0x00, 0x01, 0x30, 0x0a, 0x00, 0x01, 0x32, 0x0a, 0x00, 0x01, 0x84, 0x10, 0x01, 0x01, 0x86, 0x10, 0x01, 0x01, + 0x88, 0x10, 0x01, 0x01, 0x8a, 0x10, 0x01, 0x01, 0x8c, 0x10, 0x01, 0x01, 0x8e, 0x10, 0x01, 0x01, 0x90, 0x10, 0x01, 0x01, 0x92, 0x10, 0x01, 0x01, 0x94, 0x10, 0x01, 0x01, 0x20, 0x36, 0x02, 0x03, + 0x28, 0x36, 0x02, 0x03, 0x30, 0x36, 0x02, 0x03, 0x38, 0x36, 0x02, 0x03, 0x80, 0x17, 0x03, 0x04, 0x00, 0x01, 0x04, 0x05, 0x34, 0x0a, 0x00, 0x01, 0x36, 0x0a, 0x00, 0x01, 0x38, 0x0a, 0x00, 0x01, + 0x3a, 0x0a, 0x00, 0x01, 0x3c, 0x0a, 0x00, 0x01, 0x3e, 0x0a, 0x00, 0x01, 0x40, 0x0a, 0x00, 0x01, 0x42, 0x0a, 0x00, 0x01, 0x44, 0x0a, 0x00, 0x01, 0x96, 0x10, 0x01, 0x01, 0x98, 0x10, 0x01, 0x01, + 0x9a, 0x10, 0x01, 0x01, 0x9c, 0x10, 0x01, 0x01, 0x9e, 0x10, 0x01, 0x01, 0xa0, 0x10, 0x01, 0x01, 0xa2, 0x10, 0x01, 0x01, 0xa4, 0x10, 0x01, 0x01, 0xa6, 0x10, 0x01, 0x01, 0x40, 0x36, 0x02, 0x03, + 0x48, 0x36, 0x02, 0x03, 0x50, 0x36, 0x02, 0x03, 0x58, 0x36, 0x02, 0x03, 0x90, 0x17, 0x03, 0x04, 0x20, 0x01, 0x04, 0x05, 0x46, 0x0a, 0x00, 0x01, 0x48, 0x0a, 0x00, 0x01, 0x4a, 0x0a, 0x00, 0x01, + 0x4c, 0x0a, 0x00, 0x01, 0x4e, 0x0a, 0x00, 0x01, 0x50, 0x0a, 0x00, 0x01, 0x52, 0x0a, 0x00, 0x01, 0x54, 0x0a, 0x00, 0x01, 0x56, 0x0a, 0x00, 0x01, 0xa8, 0x10, 0x01, 0x01, 0xaa, 0x10, 0x01, 0x01, + 0xac, 0x10, 0x01, 0x01, 0xae, 0x10, 0x01, 0x01, 0xb0, 0x10, 0x01, 0x01, 0xb2, 0x10, 0x01, 0x01, 0xb4, 0x10, 0x01, 0x01, 0xb6, 0x10, 0x01, 0x01, 0xb8, 0x10, 0x01, 0x01, 0x60, 0x36, 0x02, 0x03, + 0x68, 0x36, 0x02, 0x03, 0x70, 0x36, 0x02, 0x03, 0x78, 0x36, 0x02, 0x03, 0xa0, 0x17, 0x03, 0x04, 0x40, 0x01, 0x04, 0x05, 0x58, 0x0a, 0x00, 0x01, 0x5a, 0x0a, 0x00, 0x01, 0x5c, 0x0a, 0x00, 0x01, + 0x5e, 0x0a, 0x00, 0x01, 0x60, 0x0a, 0x00, 0x01, 0x62, 0x0a, 0x00, 0x01, 0x64, 0x0a, 0x00, 0x01, 0x66, 0x0a, 0x00, 0x01, 0x68, 0x0a, 0x00, 0x01, 0xba, 0x10, 0x01, 0x01, 0xbc, 0x10, 0x01, 0x01, + 0xbe, 0x10, 0x01, 0x01, 0xc0, 0x10, 0x01, 0x01, 0xc2, 0x10, 0x01, 0x01, 0xc4, 0x10, 0x01, 0x01, 0xc6, 0x10, 0x01, 0x01, 0xc8, 0x10, 0x01, 0x01, 0xca, 0x10, 0x01, 0x01, 0x80, 0x36, 0x02, 0x03, + 0x88, 0x36, 0x02, 0x03, 0x90, 0x36, 0x02, 0x03, 0x98, 0x36, 0x02, 0x03, 0xb0, 0x17, 0x03, 0x04, 0x60, 0x01, 0x04, 0x05, 0x6a, 0x0a, 0x00, 0x01, 0x6c, 0x0a, 0x00, 0x01, 0x6e, 0x0a, 0x00, 0x01, + 0x70, 0x0a, 0x00, 0x01, 0x72, 0x0a, 0x00, 0x01, 0x74, 0x0a, 0x00, 0x01, 0x76, 0x0a, 0x00, 0x01, 0x78, 0x0a, 0x00, 0x01, 0x7a, 0x0a, 0x00, 0x01, 0xcc, 0x10, 0x01, 0x01, 0xce, 0x10, 0x01, 0x01, + 0xd0, 0x10, 0x01, 0x01, 0xd2, 0x10, 0x01, 0x01, 0xd4, 0x10, 0x01, 0x01, 0xd6, 0x10, 0x01, 0x01, 0xd8, 0x10, 0x01, 0x01, 0xda, 0x10, 0x01, 0x01, 0xdc, 0x10, 0x01, 0x01, 0xa0, 0x36, 0x02, 0x03, + 0xa8, 0x36, 0x02, 0x03, 0xb0, 0x36, 0x02, 0x03, 0xb8, 0x36, 0x02, 0x03, 0xc0, 0x17, 0x03, 0x04, 0x80, 0x01, 0x04, 0x05, 0x7c, 0x0a, 0x00, 0x01, 0x7e, 0x0a, 0x00, 0x01, 0x80, 0x0a, 0x00, 0x01, + 0x82, 0x0a, 0x00, 0x01, 0x84, 0x0a, 0x00, 0x01, 0x86, 0x0a, 0x00, 0x01, 0x88, 0x0a, 0x00, 0x01, 0x8a, 0x0a, 0x00, 0x01, 0x8c, 0x0a, 0x00, 0x01, 0xde, 0x10, 0x01, 0x01, 0xe0, 0x10, 0x01, 0x01, + 0xe2, 0x10, 0x01, 0x01, 0xe4, 0x10, 0x01, 0x01, 0xe6, 0x10, 0x01, 0x01, 0xe8, 0x10, 0x01, 0x01, 0xea, 0x10, 0x01, 0x01, 0xec, 0x10, 0x01, 0x01, 0xee, 0x10, 0x01, 0x01, 0xc0, 0x36, 0x02, 0x03, + 0xc8, 0x36, 0x02, 0x03, 0xd0, 0x36, 0x02, 0x03, 0xd8, 0x36, 0x02, 0x03, 0xd0, 0x17, 0x03, 0x04, 0xa0, 0x01, 0x04, 0x05, 0x8e, 0x0a, 0x00, 0x01, 0x90, 0x0a, 0x00, 0x01, 0x92, 0x0a, 0x00, 0x01, + 0x94, 0x0a, 0x00, 0x01, 0x96, 0x0a, 0x00, 0x01, 0x98, 0x0a, 0x00, 0x01, 0x9a, 0x0a, 0x00, 0x01, 0x9c, 0x0a, 0x00, 0x01, 0x9e, 0x0a, 0x00, 0x01, 0xf0, 0x10, 0x01, 0x01, 0xf2, 0x10, 0x01, 0x01, + 0xf4, 0x10, 0x01, 0x01, 0xf6, 0x10, 0x01, 0x01, 0xf8, 0x10, 0x01, 0x01, 0xfa, 0x10, 0x01, 0x01, 0xfc, 0x10, 0x01, 0x01, 0xfe, 0x10, 0x01, 0x01, 0x00, 0x11, 0x01, 0x01, 0xe0, 0x36, 0x02, 0x03, + 0xe8, 0x36, 0x02, 0x03, 0xf0, 0x36, 0x02, 0x03, 0xf8, 0x36, 0x02, 0x03, 0xe0, 0x17, 0x03, 0x04, 0x80, 0x19, 0x05, 0x07, 0xa0, 0x0a, 0x00, 0x01, 0xa2, 0x0a, 0x00, 0x01, 0xa4, 0x0a, 0x00, 0x01, + 0xa6, 0x0a, 0x00, 0x01, 0xa8, 0x0a, 0x00, 0x01, 0xaa, 0x0a, 0x00, 0x01, 0xac, 0x0a, 0x00, 0x01, 0xae, 0x0a, 0x00, 0x01, 0xb0, 0x0a, 0x00, 0x01, 0x02, 0x11, 0x01, 0x01, 0x04, 0x11, 0x01, 0x01, + 0x06, 0x11, 0x01, 0x01, 0x08, 0x11, 0x01, 0x01, 0x0a, 0x11, 0x01, 0x01, 0x0c, 0x11, 0x01, 0x01, 0x0e, 0x11, 0x01, 0x01, 0x10, 0x11, 0x01, 0x01, 0x12, 0x11, 0x01, 0x01, 0x00, 0x37, 0x02, 0x03, + 0x08, 0x37, 0x02, 0x03, 0x10, 0x37, 0x02, 0x03, 0x18, 0x37, 0x02, 0x03, 0xf0, 0x17, 0x03, 0x04, 0x00, 0x1a, 0x05, 0x07, 0xb2, 0x0a, 0x00, 0x01, 0xb4, 0x0a, 0x00, 0x01, 0xb6, 0x0a, 0x00, 0x01, + 0xb8, 0x0a, 0x00, 0x01, 0xba, 0x0a, 0x00, 0x01, 0xbc, 0x0a, 0x00, 0x01, 0xbe, 0x0a, 0x00, 0x01, 0xc0, 0x0a, 0x00, 0x01, 0xc2, 0x0a, 0x00, 0x01, 0x14, 0x11, 0x01, 0x01, 0x16, 0x11, 0x01, 0x01, + 0x18, 0x11, 0x01, 0x01, 0x1a, 0x11, 0x01, 0x01, 0x1c, 0x11, 0x01, 0x01, 0x1e, 0x11, 0x01, 0x01, 0x20, 0x11, 0x01, 0x01, 0x22, 0x11, 0x01, 0x01, 0x24, 0x11, 0x01, 0x01, 0x20, 0x37, 0x02, 0x03, + 0x28, 0x37, 0x02, 0x03, 0x30, 0x37, 0x02, 0x03, 0x38, 0x37, 0x02, 0x03, 0x00, 0x18, 0x03, 0x04, 0x80, 0x1a, 0x05, 0x07, 0xc4, 0x0a, 0x00, 0x01, 0xc6, 0x0a, 0x00, 0x01, 0xc8, 0x0a, 0x00, 0x01, + 0xca, 0x0a, 0x00, 0x01, 0xcc, 0x0a, 0x00, 0x01, 0xce, 0x0a, 0x00, 0x01, 0xd0, 0x0a, 0x00, 0x01, 0xd2, 0x0a, 0x00, 0x01, 0xd4, 0x0a, 0x00, 0x01, 0x26, 0x11, 0x01, 0x01, 0x28, 0x11, 0x01, 0x01, + 0x2a, 0x11, 0x01, 0x01, 0x2c, 0x11, 0x01, 0x01, 0x2e, 0x11, 0x01, 0x01, 0x30, 0x11, 0x01, 0x01, 0x32, 0x11, 0x01, 0x01, 0x34, 0x11, 0x01, 0x01, 0x36, 0x11, 0x01, 0x01, 0x40, 0x37, 0x02, 0x03, + 0x48, 0x37, 0x02, 0x03, 0x50, 0x37, 0x02, 0x03, 0x58, 0x37, 0x02, 0x03, 0x10, 0x18, 0x03, 0x04, 0x00, 0x1b, 0x05, 0x07, 0xd6, 0x0a, 0x00, 0x01, 0xd8, 0x0a, 0x00, 0x01, 0xda, 0x0a, 0x00, 0x01, + 0xdc, 0x0a, 0x00, 0x01, 0xde, 0x0a, 0x00, 0x01, 0xe0, 0x0a, 0x00, 0x01, 0xe2, 0x0a, 0x00, 0x01, 0xe4, 0x0a, 0x00, 0x01, 0xe6, 0x0a, 0x00, 0x01, 0x38, 0x11, 0x01, 0x01, 0x3a, 0x11, 0x01, 0x01, + 0x3c, 0x11, 0x01, 0x01, 0x3e, 0x11, 0x01, 0x01, 0x40, 0x11, 0x01, 0x01, 0x42, 0x11, 0x01, 0x01, 0x44, 0x11, 0x01, 0x01, 0x46, 0x11, 0x01, 0x01, 0x48, 0x11, 0x01, 0x01, 0x60, 0x37, 0x02, 0x03, + 0x68, 0x37, 0x02, 0x03, 0x70, 0x37, 0x02, 0x03, 0x78, 0x37, 0x02, 0x03, 0x20, 0x18, 0x03, 0x04, 0x80, 0x1b, 0x05, 0x07, 0xe8, 0x0a, 0x00, 0x01, 0xea, 0x0a, 0x00, 0x01, 0xec, 0x0a, 0x00, 0x01, + 0xee, 0x0a, 0x00, 0x01, 0xf0, 0x0a, 0x00, 0x01, 0xf2, 0x0a, 0x00, 0x01, 0xf4, 0x0a, 0x00, 0x01, 0xf6, 0x0a, 0x00, 0x01, 0xf8, 0x0a, 0x00, 0x01, 0x4a, 0x11, 0x01, 0x01, 0x4c, 0x11, 0x01, 0x01, + 0x4e, 0x11, 0x01, 0x01, 0x50, 0x11, 0x01, 0x01, 0x52, 0x11, 0x01, 0x01, 0x54, 0x11, 0x01, 0x01, 0x56, 0x11, 0x01, 0x01, 0x58, 0x11, 0x01, 0x01, 0x5a, 0x11, 0x01, 0x01, 0x80, 0x37, 0x02, 0x03, + 0x88, 0x37, 0x02, 0x03, 0x90, 0x37, 0x02, 0x03, 0x98, 0x37, 0x02, 0x03, 0x30, 0x18, 0x03, 0x04, 0x00, 0x1c, 0x05, 0x07, 0xfa, 0x0a, 0x00, 0x01, 0xfc, 0x0a, 0x00, 0x01, 0xfe, 0x0a, 0x00, 0x01, + 0x00, 0x0b, 0x00, 0x01, 0x02, 0x0b, 0x00, 0x01, 0x04, 0x0b, 0x00, 0x01, 0x06, 0x0b, 0x00, 0x01, 0x08, 0x0b, 0x00, 0x01, 0x0a, 0x0b, 0x00, 0x01, 0x5c, 0x11, 0x01, 0x01, 0x5e, 0x11, 0x01, 0x01, + 0x60, 0x11, 0x01, 0x01, 0x62, 0x11, 0x01, 0x01, 0x64, 0x11, 0x01, 0x01, 0x66, 0x11, 0x01, 0x01, 0x68, 0x11, 0x01, 0x01, 0x6a, 0x11, 0x01, 0x01, 0x6c, 0x11, 0x01, 0x01, 0xa0, 0x37, 0x02, 0x03, + 0xa8, 0x37, 0x02, 0x03, 0xb0, 0x37, 0x02, 0x03, 0xb8, 0x37, 0x02, 0x03, 0x40, 0x18, 0x03, 0x04, 0x80, 0x1c, 0x05, 0x07, 0x0c, 0x0b, 0x00, 0x01, 0x0e, 0x0b, 0x00, 0x01, 0x10, 0x0b, 0x00, 0x01, + 0x12, 0x0b, 0x00, 0x01, 0x14, 0x0b, 0x00, 0x01, 0x16, 0x0b, 0x00, 0x01, 0x18, 0x0b, 0x00, 0x01, 0x1a, 0x0b, 0x00, 0x01, 0x1c, 0x0b, 0x00, 0x01, 0x6e, 0x11, 0x01, 0x01, 0x70, 0x11, 0x01, 0x01, + 0x72, 0x11, 0x01, 0x01, 0x74, 0x11, 0x01, 0x01, 0x76, 0x11, 0x01, 0x01, 0x78, 0x11, 0x01, 0x01, 0x7a, 0x11, 0x01, 0x01, 0x7c, 0x11, 0x01, 0x01, 0x7e, 0x11, 0x01, 0x01, 0xc0, 0x37, 0x02, 0x03, + 0xc8, 0x37, 0x02, 0x03, 0xd0, 0x37, 0x02, 0x03, 0xd8, 0x37, 0x02, 0x03, 0x50, 0x18, 0x03, 0x04, 0x00, 0x1d, 0x05, 0x07, 0x1e, 0x0b, 0x00, 0x01, 0x20, 0x0b, 0x00, 0x01, 0x22, 0x0b, 0x00, 0x01, + 0x24, 0x0b, 0x00, 0x01, 0x26, 0x0b, 0x00, 0x01, 0x28, 0x0b, 0x00, 0x01, 0x2a, 0x0b, 0x00, 0x01, 0x2c, 0x0b, 0x00, 0x01, 0x2e, 0x0b, 0x00, 0x01, 0x80, 0x11, 0x01, 0x01, 0x82, 0x11, 0x01, 0x01, + 0x84, 0x11, 0x01, 0x01, 0x86, 0x11, 0x01, 0x01, 0x88, 0x11, 0x01, 0x01, 0x8a, 0x11, 0x01, 0x01, 0x8c, 0x11, 0x01, 0x01, 0x8e, 0x11, 0x01, 0x01, 0x90, 0x11, 0x01, 0x01, 0xe0, 0x37, 0x02, 0x03, + 0xe8, 0x37, 0x02, 0x03, 0xf0, 0x37, 0x02, 0x03, 0xf8, 0x37, 0x02, 0x03, 0x60, 0x18, 0x03, 0x04, 0x80, 0x1d, 0x05, 0x07, 0x30, 0x0b, 0x00, 0x01, 0x32, 0x0b, 0x00, 0x01, 0x34, 0x0b, 0x00, 0x01, + 0x36, 0x0b, 0x00, 0x01, 0x38, 0x0b, 0x00, 0x01, 0x3a, 0x0b, 0x00, 0x01, 0x3c, 0x0b, 0x00, 0x01, 0x3e, 0x0b, 0x00, 0x01, 0x40, 0x0b, 0x00, 0x01, 0x92, 0x11, 0x01, 0x01, 0x94, 0x11, 0x01, 0x01, + 0x96, 0x11, 0x01, 0x01, 0x98, 0x11, 0x01, 0x01, 0x9a, 0x11, 0x01, 0x01, 0x9c, 0x11, 0x01, 0x01, 0x9e, 0x11, 0x01, 0x01, 0xa0, 0x11, 0x01, 0x01, 0xa2, 0x11, 0x01, 0x01, 0x00, 0x38, 0x02, 0x03, + 0x08, 0x38, 0x02, 0x03, 0x10, 0x38, 0x02, 0x03, 0x18, 0x38, 0x02, 0x03, 0x70, 0x18, 0x03, 0x04, 0x00, 0x1e, 0x05, 0x07, 0x42, 0x0b, 0x00, 0x01, 0x44, 0x0b, 0x00, 0x01, 0x46, 0x0b, 0x00, 0x01, + 0x48, 0x0b, 0x00, 0x01, 0x4a, 0x0b, 0x00, 0x01, 0x4c, 0x0b, 0x00, 0x01, 0x4e, 0x0b, 0x00, 0x01, 0x50, 0x0b, 0x00, 0x01, 0xa4, 0x11, 0x01, 0x01, 0xa6, 0x11, 0x01, 0x01, 0xa8, 0x11, 0x01, 0x01, + 0xaa, 0x11, 0x01, 0x01, 0xac, 0x11, 0x01, 0x01, 0xae, 0x11, 0x01, 0x01, 0xb0, 0x11, 0x01, 0x01, 0xb2, 0x11, 0x01, 0x01, 0xb4, 0x11, 0x01, 0x01, 0xb6, 0x11, 0x01, 0x01, 0x20, 0x38, 0x02, 0x03, + 0x28, 0x38, 0x02, 0x03, 0x30, 0x38, 0x02, 0x03, 0x38, 0x38, 0x02, 0x03, 0x80, 0x18, 0x03, 0x04, 0x80, 0x1e, 0x05, 0x07, 0x52, 0x0b, 0x00, 0x01, 0x54, 0x0b, 0x00, 0x01, 0x56, 0x0b, 0x00, 0x01, + 0x58, 0x0b, 0x00, 0x01, 0x5a, 0x0b, 0x00, 0x01, 0x5c, 0x0b, 0x00, 0x01, 0x5e, 0x0b, 0x00, 0x01, 0x60, 0x0b, 0x00, 0x01, 0xb8, 0x11, 0x01, 0x01, 0xba, 0x11, 0x01, 0x01, 0xbc, 0x11, 0x01, 0x01, + 0xbe, 0x11, 0x01, 0x01, 0xc0, 0x11, 0x01, 0x01, 0xc2, 0x11, 0x01, 0x01, 0xc4, 0x11, 0x01, 0x01, 0xc6, 0x11, 0x01, 0x01, 0xc8, 0x11, 0x01, 0x01, 0xca, 0x11, 0x01, 0x01, 0x40, 0x38, 0x02, 0x03, + 0x48, 0x38, 0x02, 0x03, 0x50, 0x38, 0x02, 0x03, 0x58, 0x38, 0x02, 0x03, 0x90, 0x18, 0x03, 0x04, 0x00, 0x1f, 0x05, 0x07, 0x62, 0x0b, 0x00, 0x01, 0x64, 0x0b, 0x00, 0x01, 0x66, 0x0b, 0x00, 0x01, + 0x68, 0x0b, 0x00, 0x01, 0x6a, 0x0b, 0x00, 0x01, 0x6c, 0x0b, 0x00, 0x01, 0x6e, 0x0b, 0x00, 0x01, 0x70, 0x0b, 0x00, 0x01, 0xcc, 0x11, 0x01, 0x01, 0xce, 0x11, 0x01, 0x01, 0xd0, 0x11, 0x01, 0x01, + 0xd2, 0x11, 0x01, 0x01, 0xd4, 0x11, 0x01, 0x01, 0xd6, 0x11, 0x01, 0x01, 0xd8, 0x11, 0x01, 0x01, 0xda, 0x11, 0x01, 0x01, 0xdc, 0x11, 0x01, 0x01, 0xde, 0x11, 0x01, 0x01, 0x60, 0x38, 0x02, 0x03, + 0x68, 0x38, 0x02, 0x03, 0x70, 0x38, 0x02, 0x03, 0x78, 0x38, 0x02, 0x03, 0xa0, 0x18, 0x03, 0x04, 0x80, 0x1f, 0x05, 0x07, 0x72, 0x0b, 0x00, 0x01, 0x74, 0x0b, 0x00, 0x01, 0x76, 0x0b, 0x00, 0x01, + 0x78, 0x0b, 0x00, 0x01, 0x7a, 0x0b, 0x00, 0x01, 0x7c, 0x0b, 0x00, 0x01, 0x7e, 0x0b, 0x00, 0x01, 0x80, 0x0b, 0x00, 0x01, 0xe0, 0x11, 0x01, 0x01, 0xe2, 0x11, 0x01, 0x01, 0xe4, 0x11, 0x01, 0x01, + 0xe6, 0x11, 0x01, 0x01, 0xe8, 0x11, 0x01, 0x01, 0xea, 0x11, 0x01, 0x01, 0xec, 0x11, 0x01, 0x01, 0xee, 0x11, 0x01, 0x01, 0xf0, 0x11, 0x01, 0x01, 0xf2, 0x11, 0x01, 0x01, 0x80, 0x38, 0x02, 0x03, + 0x88, 0x38, 0x02, 0x03, 0x90, 0x38, 0x02, 0x03, 0x98, 0x38, 0x02, 0x03, 0xb0, 0x18, 0x03, 0x04, 0x00, 0x20, 0x05, 0x07, 0x82, 0x0b, 0x00, 0x01, 0x84, 0x0b, 0x00, 0x01, 0x86, 0x0b, 0x00, 0x01, + 0x88, 0x0b, 0x00, 0x01, 0x8a, 0x0b, 0x00, 0x01, 0x8c, 0x0b, 0x00, 0x01, 0x8e, 0x0b, 0x00, 0x01, 0x90, 0x0b, 0x00, 0x01, 0xf4, 0x11, 0x01, 0x01, 0xf6, 0x11, 0x01, 0x01, 0xf8, 0x11, 0x01, 0x01, + 0xfa, 0x11, 0x01, 0x01, 0xfc, 0x11, 0x01, 0x01, 0xfe, 0x11, 0x01, 0x01, 0x00, 0x12, 0x01, 0x01, 0x02, 0x12, 0x01, 0x01, 0x04, 0x12, 0x01, 0x01, 0x06, 0x12, 0x01, 0x01, 0xa0, 0x38, 0x02, 0x03, + 0xa8, 0x38, 0x02, 0x03, 0xb0, 0x38, 0x02, 0x03, 0xb8, 0x38, 0x02, 0x03, 0xc0, 0x18, 0x03, 0x04, 0x80, 0x20, 0x05, 0x07, 0x92, 0x0b, 0x00, 0x01, 0x94, 0x0b, 0x00, 0x01, 0x96, 0x0b, 0x00, 0x01, + 0x98, 0x0b, 0x00, 0x01, 0x9a, 0x0b, 0x00, 0x01, 0x9c, 0x0b, 0x00, 0x01, 0x9e, 0x0b, 0x00, 0x01, 0xa0, 0x0b, 0x00, 0x01, 0x08, 0x12, 0x01, 0x01, 0x0a, 0x12, 0x01, 0x01, 0x0c, 0x12, 0x01, 0x01, + 0x0e, 0x12, 0x01, 0x01, 0x10, 0x12, 0x01, 0x01, 0x12, 0x12, 0x01, 0x01, 0x14, 0x12, 0x01, 0x01, 0x16, 0x12, 0x01, 0x01, 0x18, 0x12, 0x01, 0x01, 0x1a, 0x12, 0x01, 0x01, 0xc0, 0x38, 0x02, 0x03, + 0xc8, 0x38, 0x02, 0x03, 0xd0, 0x38, 0x02, 0x03, 0xd8, 0x38, 0x02, 0x03, 0xd0, 0x18, 0x03, 0x04, 0x00, 0x02, 0x06, 0x08, 0xa2, 0x0b, 0x00, 0x01, 0xa4, 0x0b, 0x00, 0x01, 0xa6, 0x0b, 0x00, 0x01, + 0xa8, 0x0b, 0x00, 0x01, 0xaa, 0x0b, 0x00, 0x01, 0xac, 0x0b, 0x00, 0x01, 0xae, 0x0b, 0x00, 0x01, 0xb0, 0x0b, 0x00, 0x01, 0x1c, 0x12, 0x01, 0x01, 0x1e, 0x12, 0x01, 0x01, 0x20, 0x12, 0x01, 0x01, + 0x22, 0x12, 0x01, 0x01, 0x24, 0x12, 0x01, 0x01, 0x26, 0x12, 0x01, 0x01, 0x28, 0x12, 0x01, 0x01, 0x2a, 0x12, 0x01, 0x01, 0x2c, 0x12, 0x01, 0x01, 0x2e, 0x12, 0x01, 0x01, 0xe0, 0x38, 0x02, 0x03, + 0xe8, 0x38, 0x02, 0x03, 0xf0, 0x38, 0x02, 0x03, 0xf8, 0x38, 0x02, 0x03, 0xe0, 0x18, 0x03, 0x04, 0x00, 0x03, 0x06, 0x08, 0xb2, 0x0b, 0x00, 0x01, 0xb4, 0x0b, 0x00, 0x01, 0xb6, 0x0b, 0x00, 0x01, + 0xb8, 0x0b, 0x00, 0x01, 0xba, 0x0b, 0x00, 0x01, 0xbc, 0x0b, 0x00, 0x01, 0xbe, 0x0b, 0x00, 0x01, 0xc0, 0x0b, 0x00, 0x01, 0x30, 0x12, 0x01, 0x01, 0x32, 0x12, 0x01, 0x01, 0x34, 0x12, 0x01, 0x01, + 0x36, 0x12, 0x01, 0x01, 0x38, 0x12, 0x01, 0x01, 0x3a, 0x12, 0x01, 0x01, 0x3c, 0x12, 0x01, 0x01, 0x3e, 0x12, 0x01, 0x01, 0x40, 0x12, 0x01, 0x01, 0x42, 0x12, 0x01, 0x01, 0x00, 0x39, 0x02, 0x03, + 0x08, 0x39, 0x02, 0x03, 0x10, 0x39, 0x02, 0x03, 0x18, 0x39, 0x02, 0x03, 0xf0, 0x18, 0x03, 0x04, 0x00, 0x04, 0x06, 0x08, 0xc2, 0x0b, 0x00, 0x01, 0xc4, 0x0b, 0x00, 0x01, 0xc6, 0x0b, 0x00, 0x01, + 0xc8, 0x0b, 0x00, 0x01, 0xca, 0x0b, 0x00, 0x01, 0xcc, 0x0b, 0x00, 0x01, 0xce, 0x0b, 0x00, 0x01, 0xd0, 0x0b, 0x00, 0x01, 0x44, 0x12, 0x01, 0x01, 0x46, 0x12, 0x01, 0x01, 0x48, 0x12, 0x01, 0x01, + 0x4a, 0x12, 0x01, 0x01, 0x4c, 0x12, 0x01, 0x01, 0x4e, 0x12, 0x01, 0x01, 0x50, 0x12, 0x01, 0x01, 0x52, 0x12, 0x01, 0x01, 0x54, 0x12, 0x01, 0x01, 0x56, 0x12, 0x01, 0x01, 0x20, 0x39, 0x02, 0x03, + 0x28, 0x39, 0x02, 0x03, 0x30, 0x39, 0x02, 0x03, 0x38, 0x39, 0x02, 0x03, 0x00, 0x19, 0x03, 0x04, 0x00, 0x05, 0x06, 0x08, 0xd2, 0x0b, 0x00, 0x01, 0xd4, 0x0b, 0x00, 0x01, 0xd6, 0x0b, 0x00, 0x01, + 0xd8, 0x0b, 0x00, 0x01, 0xda, 0x0b, 0x00, 0x01, 0xdc, 0x0b, 0x00, 0x01, 0xde, 0x0b, 0x00, 0x01, 0xe0, 0x0b, 0x00, 0x01, 0x58, 0x12, 0x01, 0x01, 0x5a, 0x12, 0x01, 0x01, 0x5c, 0x12, 0x01, 0x01, + 0x5e, 0x12, 0x01, 0x01, 0x60, 0x12, 0x01, 0x01, 0x62, 0x12, 0x01, 0x01, 0x64, 0x12, 0x01, 0x01, 0x66, 0x12, 0x01, 0x01, 0x68, 0x12, 0x01, 0x01, 0x6a, 0x12, 0x01, 0x01, 0x40, 0x39, 0x02, 0x03, + 0x48, 0x39, 0x02, 0x03, 0x50, 0x39, 0x02, 0x03, 0x10, 0x19, 0x03, 0x04, 0x20, 0x19, 0x03, 0x04, 0x00, 0x06, 0x06, 0x08, 0xe2, 0x0b, 0x00, 0x01, 0xe4, 0x0b, 0x00, 0x01, 0xe6, 0x0b, 0x00, 0x01, + 0xe8, 0x0b, 0x00, 0x01, 0xea, 0x0b, 0x00, 0x01, 0xec, 0x0b, 0x00, 0x01, 0xee, 0x0b, 0x00, 0x01, 0xf0, 0x0b, 0x00, 0x01, 0x6c, 0x12, 0x01, 0x01, 0x6e, 0x12, 0x01, 0x01, 0x70, 0x12, 0x01, 0x01, + 0x72, 0x12, 0x01, 0x01, 0x74, 0x12, 0x01, 0x01, 0x76, 0x12, 0x01, 0x01, 0x78, 0x12, 0x01, 0x01, 0x7a, 0x12, 0x01, 0x01, 0x7c, 0x12, 0x01, 0x01, 0x7e, 0x12, 0x01, 0x01, 0x58, 0x39, 0x02, 0x03, + 0x60, 0x39, 0x02, 0x03, 0x68, 0x39, 0x02, 0x03, 0x30, 0x19, 0x03, 0x04, 0x40, 0x19, 0x03, 0x04, 0x00, 0x07, 0x06, 0x08, 0xf2, 0x0b, 0x00, 0x01, 0xf4, 0x0b, 0x00, 0x01, 0xf6, 0x0b, 0x00, 0x01, + 0xf8, 0x0b, 0x00, 0x01, 0xfa, 0x0b, 0x00, 0x01, 0xfc, 0x0b, 0x00, 0x01, 0xfe, 0x0b, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x01, 0x80, 0x12, 0x01, 0x01, 0x82, 0x12, 0x01, 0x01, 0x84, 0x12, 0x01, 0x01, + 0x86, 0x12, 0x01, 0x01, 0x88, 0x12, 0x01, 0x01, 0x8a, 0x12, 0x01, 0x01, 0x8c, 0x12, 0x01, 0x01, 0x8e, 0x12, 0x01, 0x01, 0x90, 0x12, 0x01, 0x01, 0x92, 0x12, 0x01, 0x01, 0x70, 0x39, 0x02, 0x03, + 0x78, 0x39, 0x02, 0x03, 0x80, 0x39, 0x02, 0x03, 0x50, 0x19, 0x03, 0x04, 0x60, 0x19, 0x03, 0x04, 0x00, 0x24, 0x07, 0x0a, 0x02, 0x0c, 0x00, 0x01, 0x04, 0x0c, 0x00, 0x01, 0x06, 0x0c, 0x00, 0x01, + 0x08, 0x0c, 0x00, 0x01, 0x0a, 0x0c, 0x00, 0x01, 0x0c, 0x0c, 0x00, 0x01, 0x0e, 0x0c, 0x00, 0x01, 0x10, 0x0c, 0x00, 0x01, 0x94, 0x12, 0x01, 0x01, 0x96, 0x12, 0x01, 0x01, 0x98, 0x12, 0x01, 0x01, + 0x9a, 0x12, 0x01, 0x01, 0x9c, 0x12, 0x01, 0x01, 0x9e, 0x12, 0x01, 0x01, 0xa0, 0x12, 0x01, 0x01, 0xa2, 0x12, 0x01, 0x01, 0xa4, 0x12, 0x01, 0x01, 0xa6, 0x12, 0x01, 0x01, 0x88, 0x39, 0x02, 0x03, + 0x90, 0x39, 0x02, 0x03, 0x98, 0x39, 0x02, 0x03, 0x70, 0x19, 0x03, 0x04, 0x80, 0x19, 0x03, 0x04, 0x00, 0x28, 0x07, 0x0a, 0x12, 0x0c, 0x00, 0x01, 0x14, 0x0c, 0x00, 0x01, 0x16, 0x0c, 0x00, 0x01, + 0x18, 0x0c, 0x00, 0x01, 0x1a, 0x0c, 0x00, 0x01, 0x1c, 0x0c, 0x00, 0x01, 0x1e, 0x0c, 0x00, 0x01, 0x20, 0x0c, 0x00, 0x01, 0xa8, 0x12, 0x01, 0x01, 0xaa, 0x12, 0x01, 0x01, 0xac, 0x12, 0x01, 0x01, + 0xae, 0x12, 0x01, 0x01, 0xb0, 0x12, 0x01, 0x01, 0xb2, 0x12, 0x01, 0x01, 0xb4, 0x12, 0x01, 0x01, 0xb6, 0x12, 0x01, 0x01, 0xb8, 0x12, 0x01, 0x01, 0xba, 0x12, 0x01, 0x01, 0xa0, 0x39, 0x02, 0x03, + 0xa8, 0x39, 0x02, 0x03, 0xb0, 0x39, 0x02, 0x03, 0x90, 0x19, 0x03, 0x04, 0xa0, 0x19, 0x03, 0x04, 0x00, 0x10, 0x08, 0x0b, 0x22, 0x0c, 0x00, 0x01, 0x24, 0x0c, 0x00, 0x01, 0x26, 0x0c, 0x00, 0x01, + 0x28, 0x0c, 0x00, 0x01, 0x2a, 0x0c, 0x00, 0x01, 0x2c, 0x0c, 0x00, 0x01, 0x2e, 0x0c, 0x00, 0x01, 0x30, 0x0c, 0x00, 0x01, 0xbc, 0x12, 0x01, 0x01, 0xbe, 0x12, 0x01, 0x01, 0xc0, 0x12, 0x01, 0x01, + 0xc2, 0x12, 0x01, 0x01, 0xc4, 0x12, 0x01, 0x01, 0xc6, 0x12, 0x01, 0x01, 0xc8, 0x12, 0x01, 0x01, 0xca, 0x12, 0x01, 0x01, 0xcc, 0x12, 0x01, 0x01, 0xce, 0x12, 0x01, 0x01, 0xb8, 0x39, 0x02, 0x03, + 0xc0, 0x39, 0x02, 0x03, 0xc8, 0x39, 0x02, 0x03, 0xb0, 0x19, 0x03, 0x04, 0xc0, 0x19, 0x03, 0x04, 0x32, 0x0c, 0x00, 0x01, 0x34, 0x0c, 0x00, 0x01, 0x36, 0x0c, 0x00, 0x01, 0x38, 0x0c, 0x00, 0x01, + 0x3a, 0x0c, 0x00, 0x01, 0x3c, 0x0c, 0x00, 0x01, 0x3e, 0x0c, 0x00, 0x01, 0x40, 0x0c, 0x00, 0x01, 0x42, 0x0c, 0x00, 0x01, 0xd0, 0x12, 0x01, 0x01, 0xd2, 0x12, 0x01, 0x01, 0xd4, 0x12, 0x01, 0x01, + 0xd6, 0x12, 0x01, 0x01, 0xd8, 0x12, 0x01, 0x01, 0xda, 0x12, 0x01, 0x01, 0xdc, 0x12, 0x01, 0x01, 0xde, 0x12, 0x01, 0x01, 0xe0, 0x12, 0x01, 0x01, 0xe2, 0x12, 0x01, 0x01, 0xd0, 0x39, 0x02, 0x03, + 0xd8, 0x39, 0x02, 0x03, 0xe0, 0x39, 0x02, 0x03, 0xd0, 0x19, 0x03, 0x04, 0xe0, 0x19, 0x03, 0x04, 0x44, 0x0c, 0x00, 0x01, 0x46, 0x0c, 0x00, 0x01, 0x48, 0x0c, 0x00, 0x01, 0x4a, 0x0c, 0x00, 0x01, + 0x4c, 0x0c, 0x00, 0x01, 0x4e, 0x0c, 0x00, 0x01, 0x50, 0x0c, 0x00, 0x01, 0x52, 0x0c, 0x00, 0x01, 0x54, 0x0c, 0x00, 0x01, 0xe4, 0x12, 0x01, 0x01, 0xe6, 0x12, 0x01, 0x01, 0xe8, 0x12, 0x01, 0x01, + 0xea, 0x12, 0x01, 0x01, 0xec, 0x12, 0x01, 0x01, 0xee, 0x12, 0x01, 0x01, 0xf0, 0x12, 0x01, 0x01, 0xf2, 0x12, 0x01, 0x01, 0xf4, 0x12, 0x01, 0x01, 0xf6, 0x12, 0x01, 0x01, 0xe8, 0x39, 0x02, 0x03, + 0xf0, 0x39, 0x02, 0x03, 0xf8, 0x39, 0x02, 0x03, 0xf0, 0x19, 0x03, 0x04, 0x00, 0x1a, 0x03, 0x04, 0x56, 0x0c, 0x00, 0x01, 0x58, 0x0c, 0x00, 0x01, 0x5a, 0x0c, 0x00, 0x01, 0x5c, 0x0c, 0x00, 0x01, + 0x5e, 0x0c, 0x00, 0x01, 0x60, 0x0c, 0x00, 0x01, 0x62, 0x0c, 0x00, 0x01, 0x64, 0x0c, 0x00, 0x01, 0x66, 0x0c, 0x00, 0x01, 0xf8, 0x12, 0x01, 0x01, 0xfa, 0x12, 0x01, 0x01, 0xfc, 0x12, 0x01, 0x01, + 0xfe, 0x12, 0x01, 0x01, 0x00, 0x13, 0x01, 0x01, 0x02, 0x13, 0x01, 0x01, 0x04, 0x13, 0x01, 0x01, 0x06, 0x13, 0x01, 0x01, 0x08, 0x13, 0x01, 0x01, 0x0a, 0x13, 0x01, 0x01, 0x00, 0x3a, 0x02, 0x03, + 0x08, 0x3a, 0x02, 0x03, 0x10, 0x3a, 0x02, 0x03, 0x10, 0x1a, 0x03, 0x04, 0x20, 0x1a, 0x03, 0x04, 0x68, 0x0c, 0x00, 0x01, 0x6a, 0x0c, 0x00, 0x01, 0x6c, 0x0c, 0x00, 0x01, 0x6e, 0x0c, 0x00, 0x01, + 0x70, 0x0c, 0x00, 0x01, 0x72, 0x0c, 0x00, 0x01, 0x74, 0x0c, 0x00, 0x01, 0x76, 0x0c, 0x00, 0x01, 0x78, 0x0c, 0x00, 0x01, 0x0c, 0x13, 0x01, 0x01, 0x0e, 0x13, 0x01, 0x01, 0x10, 0x13, 0x01, 0x01, + 0x12, 0x13, 0x01, 0x01, 0x14, 0x13, 0x01, 0x01, 0x16, 0x13, 0x01, 0x01, 0x18, 0x13, 0x01, 0x01, 0x1a, 0x13, 0x01, 0x01, 0x1c, 0x13, 0x01, 0x01, 0x1e, 0x13, 0x01, 0x01, 0x18, 0x3a, 0x02, 0x03, + 0x20, 0x3a, 0x02, 0x03, 0x28, 0x3a, 0x02, 0x03, 0x30, 0x1a, 0x03, 0x04, 0x40, 0x1a, 0x03, 0x04, 0x7a, 0x0c, 0x00, 0x01, 0x7c, 0x0c, 0x00, 0x01, 0x7e, 0x0c, 0x00, 0x01, 0x80, 0x0c, 0x00, 0x01, + 0x82, 0x0c, 0x00, 0x01, 0x84, 0x0c, 0x00, 0x01, 0x86, 0x0c, 0x00, 0x01, 0x88, 0x0c, 0x00, 0x01, 0x8a, 0x0c, 0x00, 0x01, 0x20, 0x13, 0x01, 0x01, 0x22, 0x13, 0x01, 0x01, 0x24, 0x13, 0x01, 0x01, + 0x26, 0x13, 0x01, 0x01, 0x28, 0x13, 0x01, 0x01, 0x2a, 0x13, 0x01, 0x01, 0x2c, 0x13, 0x01, 0x01, 0x2e, 0x13, 0x01, 0x01, 0x30, 0x13, 0x01, 0x01, 0x32, 0x13, 0x01, 0x01, 0x30, 0x3a, 0x02, 0x03, + 0x38, 0x3a, 0x02, 0x03, 0x40, 0x3a, 0x02, 0x03, 0x50, 0x1a, 0x03, 0x04, 0x60, 0x1a, 0x03, 0x04, 0x8c, 0x0c, 0x00, 0x01, 0x8e, 0x0c, 0x00, 0x01, 0x90, 0x0c, 0x00, 0x01, 0x92, 0x0c, 0x00, 0x01, + 0x94, 0x0c, 0x00, 0x01, 0x96, 0x0c, 0x00, 0x01, 0x98, 0x0c, 0x00, 0x01, 0x9a, 0x0c, 0x00, 0x01, 0x9c, 0x0c, 0x00, 0x01, 0x34, 0x13, 0x01, 0x01, 0x36, 0x13, 0x01, 0x01, 0x38, 0x13, 0x01, 0x01, + 0x3a, 0x13, 0x01, 0x01, 0x3c, 0x13, 0x01, 0x01, 0x3e, 0x13, 0x01, 0x01, 0x40, 0x13, 0x01, 0x01, 0x42, 0x13, 0x01, 0x01, 0x44, 0x13, 0x01, 0x01, 0x46, 0x13, 0x01, 0x01, 0x48, 0x3a, 0x02, 0x03, + 0x50, 0x3a, 0x02, 0x03, 0x58, 0x3a, 0x02, 0x03, 0x70, 0x1a, 0x03, 0x04, 0x80, 0x1a, 0x03, 0x04, 0x9e, 0x0c, 0x00, 0x01, 0xa0, 0x0c, 0x00, 0x01, 0xa2, 0x0c, 0x00, 0x01, 0xa4, 0x0c, 0x00, 0x01, + 0xa6, 0x0c, 0x00, 0x01, 0xa8, 0x0c, 0x00, 0x01, 0xaa, 0x0c, 0x00, 0x01, 0xac, 0x0c, 0x00, 0x01, 0xae, 0x0c, 0x00, 0x01, 0x48, 0x13, 0x01, 0x01, 0x4a, 0x13, 0x01, 0x01, 0x4c, 0x13, 0x01, 0x01, + 0x4e, 0x13, 0x01, 0x01, 0x50, 0x13, 0x01, 0x01, 0x52, 0x13, 0x01, 0x01, 0x54, 0x13, 0x01, 0x01, 0x56, 0x13, 0x01, 0x01, 0x58, 0x13, 0x01, 0x01, 0x5a, 0x13, 0x01, 0x01, 0x60, 0x3a, 0x02, 0x03, + 0x68, 0x3a, 0x02, 0x03, 0x70, 0x3a, 0x02, 0x03, 0x90, 0x1a, 0x03, 0x04, 0xa0, 0x1a, 0x03, 0x04, 0xb0, 0x0c, 0x00, 0x01, 0xb2, 0x0c, 0x00, 0x01, 0xb4, 0x0c, 0x00, 0x01, 0xb6, 0x0c, 0x00, 0x01, + 0xb8, 0x0c, 0x00, 0x01, 0xba, 0x0c, 0x00, 0x01, 0xbc, 0x0c, 0x00, 0x01, 0xbe, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x5c, 0x13, 0x01, 0x01, 0x5e, 0x13, 0x01, 0x01, 0x60, 0x13, 0x01, 0x01, + 0x62, 0x13, 0x01, 0x01, 0x64, 0x13, 0x01, 0x01, 0x66, 0x13, 0x01, 0x01, 0x68, 0x13, 0x01, 0x01, 0x6a, 0x13, 0x01, 0x01, 0x6c, 0x13, 0x01, 0x01, 0x6e, 0x13, 0x01, 0x01, 0x78, 0x3a, 0x02, 0x03, + 0x80, 0x3a, 0x02, 0x03, 0x88, 0x3a, 0x02, 0x03, 0xb0, 0x1a, 0x03, 0x04, 0xc0, 0x1a, 0x03, 0x04, 0xc2, 0x0c, 0x00, 0x01, 0xc4, 0x0c, 0x00, 0x01, 0xc6, 0x0c, 0x00, 0x01, 0xc8, 0x0c, 0x00, 0x01, + 0xca, 0x0c, 0x00, 0x01, 0xcc, 0x0c, 0x00, 0x01, 0xce, 0x0c, 0x00, 0x01, 0xd0, 0x0c, 0x00, 0x01, 0xd2, 0x0c, 0x00, 0x01, 0x70, 0x13, 0x01, 0x01, 0x72, 0x13, 0x01, 0x01, 0x74, 0x13, 0x01, 0x01, + 0x76, 0x13, 0x01, 0x01, 0x78, 0x13, 0x01, 0x01, 0x7a, 0x13, 0x01, 0x01, 0x7c, 0x13, 0x01, 0x01, 0x7e, 0x13, 0x01, 0x01, 0x80, 0x13, 0x01, 0x01, 0x82, 0x13, 0x01, 0x01, 0x90, 0x3a, 0x02, 0x03, + 0x98, 0x3a, 0x02, 0x03, 0xa0, 0x3a, 0x02, 0x03, 0xd0, 0x1a, 0x03, 0x04, 0xe0, 0x1a, 0x03, 0x04, 0xd4, 0x0c, 0x00, 0x01, 0xd6, 0x0c, 0x00, 0x01, 0xd8, 0x0c, 0x00, 0x01, 0xda, 0x0c, 0x00, 0x01, + 0xdc, 0x0c, 0x00, 0x01, 0xde, 0x0c, 0x00, 0x01, 0xe0, 0x0c, 0x00, 0x01, 0xe2, 0x0c, 0x00, 0x01, 0xe4, 0x0c, 0x00, 0x01, 0x84, 0x13, 0x01, 0x01, 0x86, 0x13, 0x01, 0x01, 0x88, 0x13, 0x01, 0x01, + 0x8a, 0x13, 0x01, 0x01, 0x8c, 0x13, 0x01, 0x01, 0x8e, 0x13, 0x01, 0x01, 0x90, 0x13, 0x01, 0x01, 0x92, 0x13, 0x01, 0x01, 0x94, 0x13, 0x01, 0x01, 0x96, 0x13, 0x01, 0x01, 0xa8, 0x3a, 0x02, 0x03, + 0xb0, 0x3a, 0x02, 0x03, 0xb8, 0x3a, 0x02, 0x03, 0xf0, 0x1a, 0x03, 0x04, 0x00, 0x1b, 0x03, 0x04, 0xe6, 0x0c, 0x00, 0x01, 0xe8, 0x0c, 0x00, 0x01, 0xea, 0x0c, 0x00, 0x01, 0xec, 0x0c, 0x00, 0x01, + 0xee, 0x0c, 0x00, 0x01, 0xf0, 0x0c, 0x00, 0x01, 0xf2, 0x0c, 0x00, 0x01, 0xf4, 0x0c, 0x00, 0x01, 0xf6, 0x0c, 0x00, 0x01, 0x98, 0x13, 0x01, 0x01, 0x9a, 0x13, 0x01, 0x01, 0x9c, 0x13, 0x01, 0x01, + 0x9e, 0x13, 0x01, 0x01, 0xa0, 0x13, 0x01, 0x01, 0xa2, 0x13, 0x01, 0x01, 0xa4, 0x13, 0x01, 0x01, 0xa6, 0x13, 0x01, 0x01, 0xa8, 0x13, 0x01, 0x01, 0xaa, 0x13, 0x01, 0x01, 0xc0, 0x3a, 0x02, 0x03, + 0xc8, 0x3a, 0x02, 0x03, 0xd0, 0x3a, 0x02, 0x03, 0x10, 0x1b, 0x03, 0x04, 0x20, 0x1b, 0x03, 0x04, 0xf8, 0x0c, 0x00, 0x01, 0xfa, 0x0c, 0x00, 0x01, 0xfc, 0x0c, 0x00, 0x01, 0xfe, 0x0c, 0x00, 0x01, + 0x00, 0x0d, 0x00, 0x01, 0x02, 0x0d, 0x00, 0x01, 0x04, 0x0d, 0x00, 0x01, 0x06, 0x0d, 0x00, 0x01, 0x08, 0x0d, 0x00, 0x01, 0xac, 0x13, 0x01, 0x01, 0xae, 0x13, 0x01, 0x01, 0xb0, 0x13, 0x01, 0x01, + 0xb2, 0x13, 0x01, 0x01, 0xb4, 0x13, 0x01, 0x01, 0xb6, 0x13, 0x01, 0x01, 0xb8, 0x13, 0x01, 0x01, 0xba, 0x13, 0x01, 0x01, 0xbc, 0x13, 0x01, 0x01, 0xbe, 0x13, 0x01, 0x01, 0xd8, 0x3a, 0x02, 0x03, + 0xe0, 0x3a, 0x02, 0x03, 0xe8, 0x3a, 0x02, 0x03, 0x30, 0x1b, 0x03, 0x04, 0x40, 0x1b, 0x03, 0x04, 0x0a, 0x0d, 0x00, 0x01, 0x0c, 0x0d, 0x00, 0x01, 0x0e, 0x0d, 0x00, 0x01, 0x10, 0x0d, 0x00, 0x01, + 0x12, 0x0d, 0x00, 0x01, 0x14, 0x0d, 0x00, 0x01, 0x16, 0x0d, 0x00, 0x01, 0x18, 0x0d, 0x00, 0x01, 0x1a, 0x0d, 0x00, 0x01, 0xc0, 0x13, 0x01, 0x01, 0xc2, 0x13, 0x01, 0x01, 0xc4, 0x13, 0x01, 0x01, + 0xc6, 0x13, 0x01, 0x01, 0xc8, 0x13, 0x01, 0x01, 0xca, 0x13, 0x01, 0x01, 0xcc, 0x13, 0x01, 0x01, 0xce, 0x13, 0x01, 0x01, 0xd0, 0x13, 0x01, 0x01, 0xd2, 0x13, 0x01, 0x01, 0xf0, 0x3a, 0x02, 0x03, + 0xf8, 0x3a, 0x02, 0x03, 0x00, 0x3b, 0x02, 0x03, 0x50, 0x1b, 0x03, 0x04, 0x60, 0x1b, 0x03, 0x04, 0x1c, 0x0d, 0x00, 0x01, 0x1e, 0x0d, 0x00, 0x01, 0x20, 0x0d, 0x00, 0x01, 0x22, 0x0d, 0x00, 0x01, + 0x24, 0x0d, 0x00, 0x01, 0x26, 0x0d, 0x00, 0x01, 0x28, 0x0d, 0x00, 0x01, 0x2a, 0x0d, 0x00, 0x01, 0x2c, 0x0d, 0x00, 0x01, 0xd4, 0x13, 0x01, 0x01, 0xd6, 0x13, 0x01, 0x01, 0xd8, 0x13, 0x01, 0x01, + 0xda, 0x13, 0x01, 0x01, 0xdc, 0x13, 0x01, 0x01, 0xde, 0x13, 0x01, 0x01, 0xe0, 0x13, 0x01, 0x01, 0xe2, 0x13, 0x01, 0x01, 0xe4, 0x13, 0x01, 0x01, 0xe6, 0x13, 0x01, 0x01, 0x08, 0x3b, 0x02, 0x03, + 0x10, 0x3b, 0x02, 0x03, 0x18, 0x3b, 0x02, 0x03, 0x70, 0x1b, 0x03, 0x04, 0x80, 0x1b, 0x03, 0x04, 0x2e, 0x0d, 0x00, 0x01, 0x30, 0x0d, 0x00, 0x01, 0x32, 0x0d, 0x00, 0x01, 0x34, 0x0d, 0x00, 0x01, + 0x36, 0x0d, 0x00, 0x01, 0x38, 0x0d, 0x00, 0x01, 0x3a, 0x0d, 0x00, 0x01, 0x3c, 0x0d, 0x00, 0x01, 0x3e, 0x0d, 0x00, 0x01, 0xe8, 0x13, 0x01, 0x01, 0xea, 0x13, 0x01, 0x01, 0xec, 0x13, 0x01, 0x01, + 0xee, 0x13, 0x01, 0x01, 0xf0, 0x13, 0x01, 0x01, 0xf2, 0x13, 0x01, 0x01, 0xf4, 0x13, 0x01, 0x01, 0xf6, 0x13, 0x01, 0x01, 0xf8, 0x13, 0x01, 0x01, 0xfa, 0x13, 0x01, 0x01, 0x20, 0x3b, 0x02, 0x03, + 0x28, 0x3b, 0x02, 0x03, 0x30, 0x3b, 0x02, 0x03, 0x90, 0x1b, 0x03, 0x04, 0xa0, 0x1b, 0x03, 0x04, 0x40, 0x0d, 0x00, 0x01, 0x42, 0x0d, 0x00, 0x01, 0x44, 0x0d, 0x00, 0x01, 0x46, 0x0d, 0x00, 0x01, + 0x48, 0x0d, 0x00, 0x01, 0x4a, 0x0d, 0x00, 0x01, 0x4c, 0x0d, 0x00, 0x01, 0x4e, 0x0d, 0x00, 0x01, 0x50, 0x0d, 0x00, 0x01, 0xfc, 0x13, 0x01, 0x01, 0xfe, 0x13, 0x01, 0x01, 0x00, 0x14, 0x01, 0x01, + 0x02, 0x14, 0x01, 0x01, 0x04, 0x14, 0x01, 0x01, 0x06, 0x14, 0x01, 0x01, 0x08, 0x14, 0x01, 0x01, 0x0a, 0x14, 0x01, 0x01, 0x0c, 0x14, 0x01, 0x01, 0x0e, 0x14, 0x01, 0x01, 0x38, 0x3b, 0x02, 0x03, + 0x40, 0x3b, 0x02, 0x03, 0x48, 0x3b, 0x02, 0x03, 0xb0, 0x1b, 0x03, 0x04, 0xc0, 0x1b, 0x03, 0x04, 0x52, 0x0d, 0x00, 0x01, 0x54, 0x0d, 0x00, 0x01, 0x56, 0x0d, 0x00, 0x01, 0x58, 0x0d, 0x00, 0x01, + 0x5a, 0x0d, 0x00, 0x01, 0x5c, 0x0d, 0x00, 0x01, 0x5e, 0x0d, 0x00, 0x01, 0x60, 0x0d, 0x00, 0x01, 0x62, 0x0d, 0x00, 0x01, 0x10, 0x14, 0x01, 0x01, 0x12, 0x14, 0x01, 0x01, 0x14, 0x14, 0x01, 0x01, + 0x16, 0x14, 0x01, 0x01, 0x18, 0x14, 0x01, 0x01, 0x1a, 0x14, 0x01, 0x01, 0x1c, 0x14, 0x01, 0x01, 0x1e, 0x14, 0x01, 0x01, 0x20, 0x14, 0x01, 0x01, 0x22, 0x14, 0x01, 0x01, 0x50, 0x3b, 0x02, 0x03, + 0x58, 0x3b, 0x02, 0x03, 0x60, 0x3b, 0x02, 0x03, 0xd0, 0x1b, 0x03, 0x04, 0xe0, 0x1b, 0x03, 0x04, 0x64, 0x0d, 0x00, 0x01, 0x66, 0x0d, 0x00, 0x01, 0x68, 0x0d, 0x00, 0x01, 0x6a, 0x0d, 0x00, 0x01, + 0x6c, 0x0d, 0x00, 0x01, 0x6e, 0x0d, 0x00, 0x01, 0x70, 0x0d, 0x00, 0x01, 0x72, 0x0d, 0x00, 0x01, 0x74, 0x0d, 0x00, 0x01, 0x24, 0x14, 0x01, 0x01, 0x26, 0x14, 0x01, 0x01, 0x28, 0x14, 0x01, 0x01, + 0x2a, 0x14, 0x01, 0x01, 0x2c, 0x14, 0x01, 0x01, 0x2e, 0x14, 0x01, 0x01, 0x30, 0x14, 0x01, 0x01, 0x32, 0x14, 0x01, 0x01, 0x34, 0x14, 0x01, 0x01, 0x36, 0x14, 0x01, 0x01, 0x68, 0x3b, 0x02, 0x03, + 0x70, 0x3b, 0x02, 0x03, 0x78, 0x3b, 0x02, 0x03, 0xf0, 0x1b, 0x03, 0x04, 0x00, 0x1c, 0x03, 0x04, 0x76, 0x0d, 0x00, 0x01, 0x78, 0x0d, 0x00, 0x01, 0x7a, 0x0d, 0x00, 0x01, 0x7c, 0x0d, 0x00, 0x01, + 0x7e, 0x0d, 0x00, 0x01, 0x80, 0x0d, 0x00, 0x01, 0x82, 0x0d, 0x00, 0x01, 0x84, 0x0d, 0x00, 0x01, 0x86, 0x0d, 0x00, 0x01, 0x38, 0x14, 0x01, 0x01, 0x3a, 0x14, 0x01, 0x01, 0x3c, 0x14, 0x01, 0x01, + 0x3e, 0x14, 0x01, 0x01, 0x40, 0x14, 0x01, 0x01, 0x42, 0x14, 0x01, 0x01, 0x44, 0x14, 0x01, 0x01, 0x46, 0x14, 0x01, 0x01, 0x48, 0x14, 0x01, 0x01, 0x4a, 0x14, 0x01, 0x01, 0x80, 0x3b, 0x02, 0x03, + 0x88, 0x3b, 0x02, 0x03, 0x90, 0x3b, 0x02, 0x03, 0x10, 0x1c, 0x03, 0x04, 0x20, 0x1c, 0x03, 0x04, 0x88, 0x0d, 0x00, 0x01, 0x8a, 0x0d, 0x00, 0x01, 0x8c, 0x0d, 0x00, 0x01, 0x8e, 0x0d, 0x00, 0x01, + 0x90, 0x0d, 0x00, 0x01, 0x92, 0x0d, 0x00, 0x01, 0x94, 0x0d, 0x00, 0x01, 0x96, 0x0d, 0x00, 0x01, 0x98, 0x0d, 0x00, 0x01, 0x4c, 0x14, 0x01, 0x01, 0x4e, 0x14, 0x01, 0x01, 0x50, 0x14, 0x01, 0x01, + 0x52, 0x14, 0x01, 0x01, 0x54, 0x14, 0x01, 0x01, 0x56, 0x14, 0x01, 0x01, 0x58, 0x14, 0x01, 0x01, 0x5a, 0x14, 0x01, 0x01, 0x5c, 0x14, 0x01, 0x01, 0x5e, 0x14, 0x01, 0x01, 0x98, 0x3b, 0x02, 0x03, + 0xa0, 0x3b, 0x02, 0x03, 0xa8, 0x3b, 0x02, 0x03, 0x30, 0x1c, 0x03, 0x04, 0x40, 0x1c, 0x03, 0x04, 0x9a, 0x0d, 0x00, 0x01, 0x9c, 0x0d, 0x00, 0x01, 0x9e, 0x0d, 0x00, 0x01, 0xa0, 0x0d, 0x00, 0x01, + 0xa2, 0x0d, 0x00, 0x01, 0xa4, 0x0d, 0x00, 0x01, 0xa6, 0x0d, 0x00, 0x01, 0xa8, 0x0d, 0x00, 0x01, 0xaa, 0x0d, 0x00, 0x01, 0x60, 0x14, 0x01, 0x01, 0x62, 0x14, 0x01, 0x01, 0x64, 0x14, 0x01, 0x01, + 0x66, 0x14, 0x01, 0x01, 0x68, 0x14, 0x01, 0x01, 0x6a, 0x14, 0x01, 0x01, 0x6c, 0x14, 0x01, 0x01, 0x6e, 0x14, 0x01, 0x01, 0x70, 0x14, 0x01, 0x01, 0x72, 0x14, 0x01, 0x01, 0xb0, 0x3b, 0x02, 0x03, + 0xb8, 0x3b, 0x02, 0x03, 0xc0, 0x3b, 0x02, 0x03, 0x50, 0x1c, 0x03, 0x04, 0xc0, 0x01, 0x04, 0x05, 0xac, 0x0d, 0x00, 0x01, 0xae, 0x0d, 0x00, 0x01, 0xb0, 0x0d, 0x00, 0x01, 0xb2, 0x0d, 0x00, 0x01, + 0xb4, 0x0d, 0x00, 0x01, 0xb6, 0x0d, 0x00, 0x01, 0xb8, 0x0d, 0x00, 0x01, 0xba, 0x0d, 0x00, 0x01, 0xbc, 0x0d, 0x00, 0x01, 0x74, 0x14, 0x01, 0x01, 0x76, 0x14, 0x01, 0x01, 0x78, 0x14, 0x01, 0x01, + 0x7a, 0x14, 0x01, 0x01, 0x7c, 0x14, 0x01, 0x01, 0x7e, 0x14, 0x01, 0x01, 0x80, 0x14, 0x01, 0x01, 0x82, 0x14, 0x01, 0x01, 0x84, 0x14, 0x01, 0x01, 0x86, 0x14, 0x01, 0x01, 0xc8, 0x3b, 0x02, 0x03, + 0xd0, 0x3b, 0x02, 0x03, 0xd8, 0x3b, 0x02, 0x03, 0x60, 0x1c, 0x03, 0x04, 0xe0, 0x01, 0x04, 0x05, 0xbe, 0x0d, 0x00, 0x01, 0xc0, 0x0d, 0x00, 0x01, 0xc2, 0x0d, 0x00, 0x01, 0xc4, 0x0d, 0x00, 0x01, + 0xc6, 0x0d, 0x00, 0x01, 0xc8, 0x0d, 0x00, 0x01, 0xca, 0x0d, 0x00, 0x01, 0xcc, 0x0d, 0x00, 0x01, 0xce, 0x0d, 0x00, 0x01, 0x88, 0x14, 0x01, 0x01, 0x8a, 0x14, 0x01, 0x01, 0x8c, 0x14, 0x01, 0x01, + 0x8e, 0x14, 0x01, 0x01, 0x90, 0x14, 0x01, 0x01, 0x92, 0x14, 0x01, 0x01, 0x94, 0x14, 0x01, 0x01, 0x96, 0x14, 0x01, 0x01, 0x98, 0x14, 0x01, 0x01, 0x9a, 0x14, 0x01, 0x01, 0xe0, 0x3b, 0x02, 0x03, + 0xe8, 0x3b, 0x02, 0x03, 0xf0, 0x3b, 0x02, 0x03, 0x70, 0x1c, 0x03, 0x04, 0x00, 0x02, 0x04, 0x05, 0xd0, 0x0d, 0x00, 0x01, 0xd2, 0x0d, 0x00, 0x01, 0xd4, 0x0d, 0x00, 0x01, 0xd6, 0x0d, 0x00, 0x01, + 0xd8, 0x0d, 0x00, 0x01, 0xda, 0x0d, 0x00, 0x01, 0xdc, 0x0d, 0x00, 0x01, 0xde, 0x0d, 0x00, 0x01, 0xe0, 0x0d, 0x00, 0x01, 0x9c, 0x14, 0x01, 0x01, 0x9e, 0x14, 0x01, 0x01, 0xa0, 0x14, 0x01, 0x01, + 0xa2, 0x14, 0x01, 0x01, 0xa4, 0x14, 0x01, 0x01, 0xa6, 0x14, 0x01, 0x01, 0xa8, 0x14, 0x01, 0x01, 0xaa, 0x14, 0x01, 0x01, 0xac, 0x14, 0x01, 0x01, 0xae, 0x14, 0x01, 0x01, 0xf8, 0x3b, 0x02, 0x03, + 0x00, 0x3c, 0x02, 0x03, 0x08, 0x3c, 0x02, 0x03, 0x80, 0x1c, 0x03, 0x04, 0x20, 0x02, 0x04, 0x05, 0xe2, 0x0d, 0x00, 0x01, 0xe4, 0x0d, 0x00, 0x01, 0xe6, 0x0d, 0x00, 0x01, 0xe8, 0x0d, 0x00, 0x01, + 0xea, 0x0d, 0x00, 0x01, 0xec, 0x0d, 0x00, 0x01, 0xee, 0x0d, 0x00, 0x01, 0xf0, 0x0d, 0x00, 0x01, 0xf2, 0x0d, 0x00, 0x01, 0xb0, 0x14, 0x01, 0x01, 0xb2, 0x14, 0x01, 0x01, 0xb4, 0x14, 0x01, 0x01, + 0xb6, 0x14, 0x01, 0x01, 0xb8, 0x14, 0x01, 0x01, 0xba, 0x14, 0x01, 0x01, 0xbc, 0x14, 0x01, 0x01, 0xbe, 0x14, 0x01, 0x01, 0xc0, 0x14, 0x01, 0x01, 0xc2, 0x14, 0x01, 0x01, 0x10, 0x3c, 0x02, 0x03, + 0x18, 0x3c, 0x02, 0x03, 0x20, 0x3c, 0x02, 0x03, 0x90, 0x1c, 0x03, 0x04, 0x40, 0x02, 0x04, 0x05, 0xf4, 0x0d, 0x00, 0x01, 0xf6, 0x0d, 0x00, 0x01, 0xf8, 0x0d, 0x00, 0x01, 0xfa, 0x0d, 0x00, 0x01, + 0xfc, 0x0d, 0x00, 0x01, 0xfe, 0x0d, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x02, 0x0e, 0x00, 0x01, 0x04, 0x0e, 0x00, 0x01, 0xc4, 0x14, 0x01, 0x01, 0xc6, 0x14, 0x01, 0x01, 0xc8, 0x14, 0x01, 0x01, + 0xca, 0x14, 0x01, 0x01, 0xcc, 0x14, 0x01, 0x01, 0xce, 0x14, 0x01, 0x01, 0xd0, 0x14, 0x01, 0x01, 0xd2, 0x14, 0x01, 0x01, 0xd4, 0x14, 0x01, 0x01, 0xd6, 0x14, 0x01, 0x01, 0x28, 0x3c, 0x02, 0x03, + 0x30, 0x3c, 0x02, 0x03, 0x38, 0x3c, 0x02, 0x03, 0xa0, 0x1c, 0x03, 0x04, 0x60, 0x02, 0x04, 0x05, 0x06, 0x0e, 0x00, 0x01, 0x08, 0x0e, 0x00, 0x01, 0x0a, 0x0e, 0x00, 0x01, 0x0c, 0x0e, 0x00, 0x01, + 0x0e, 0x0e, 0x00, 0x01, 0x10, 0x0e, 0x00, 0x01, 0x12, 0x0e, 0x00, 0x01, 0x14, 0x0e, 0x00, 0x01, 0x16, 0x0e, 0x00, 0x01, 0xd8, 0x14, 0x01, 0x01, 0xda, 0x14, 0x01, 0x01, 0xdc, 0x14, 0x01, 0x01, + 0xde, 0x14, 0x01, 0x01, 0xe0, 0x14, 0x01, 0x01, 0xe2, 0x14, 0x01, 0x01, 0xe4, 0x14, 0x01, 0x01, 0xe6, 0x14, 0x01, 0x01, 0xe8, 0x14, 0x01, 0x01, 0xea, 0x14, 0x01, 0x01, 0x40, 0x3c, 0x02, 0x03, + 0x48, 0x3c, 0x02, 0x03, 0x50, 0x3c, 0x02, 0x03, 0xb0, 0x1c, 0x03, 0x04, 0x80, 0x02, 0x04, 0x05, 0x18, 0x0e, 0x00, 0x01, 0x1a, 0x0e, 0x00, 0x01, 0x1c, 0x0e, 0x00, 0x01, 0x1e, 0x0e, 0x00, 0x01, + 0x20, 0x0e, 0x00, 0x01, 0x22, 0x0e, 0x00, 0x01, 0x24, 0x0e, 0x00, 0x01, 0x26, 0x0e, 0x00, 0x01, 0x28, 0x0e, 0x00, 0x01, 0xec, 0x14, 0x01, 0x01, 0xee, 0x14, 0x01, 0x01, 0xf0, 0x14, 0x01, 0x01, + 0xf2, 0x14, 0x01, 0x01, 0xf4, 0x14, 0x01, 0x01, 0xf6, 0x14, 0x01, 0x01, 0xf8, 0x14, 0x01, 0x01, 0xfa, 0x14, 0x01, 0x01, 0xfc, 0x14, 0x01, 0x01, 0xfe, 0x14, 0x01, 0x01, 0x58, 0x3c, 0x02, 0x03, + 0x60, 0x3c, 0x02, 0x03, 0x68, 0x3c, 0x02, 0x03, 0xc0, 0x1c, 0x03, 0x04, 0xa0, 0x02, 0x04, 0x05, 0x2a, 0x0e, 0x00, 0x01, 0x2c, 0x0e, 0x00, 0x01, 0x2e, 0x0e, 0x00, 0x01, 0x30, 0x0e, 0x00, 0x01, + 0x32, 0x0e, 0x00, 0x01, 0x34, 0x0e, 0x00, 0x01, 0x36, 0x0e, 0x00, 0x01, 0x38, 0x0e, 0x00, 0x01, 0x3a, 0x0e, 0x00, 0x01, 0x00, 0x15, 0x01, 0x01, 0x02, 0x15, 0x01, 0x01, 0x04, 0x15, 0x01, 0x01, + 0x06, 0x15, 0x01, 0x01, 0x08, 0x15, 0x01, 0x01, 0x0a, 0x15, 0x01, 0x01, 0x0c, 0x15, 0x01, 0x01, 0x0e, 0x15, 0x01, 0x01, 0x10, 0x15, 0x01, 0x01, 0x12, 0x15, 0x01, 0x01, 0x70, 0x3c, 0x02, 0x03, + 0x78, 0x3c, 0x02, 0x03, 0x80, 0x3c, 0x02, 0x03, 0xd0, 0x1c, 0x03, 0x04, 0xc0, 0x02, 0x04, 0x05, 0x3c, 0x0e, 0x00, 0x01, 0x3e, 0x0e, 0x00, 0x01, 0x40, 0x0e, 0x00, 0x01, 0x42, 0x0e, 0x00, 0x01, + 0x44, 0x0e, 0x00, 0x01, 0x46, 0x0e, 0x00, 0x01, 0x48, 0x0e, 0x00, 0x01, 0x4a, 0x0e, 0x00, 0x01, 0x4c, 0x0e, 0x00, 0x01, 0x14, 0x15, 0x01, 0x01, 0x16, 0x15, 0x01, 0x01, 0x18, 0x15, 0x01, 0x01, + 0x1a, 0x15, 0x01, 0x01, 0x1c, 0x15, 0x01, 0x01, 0x1e, 0x15, 0x01, 0x01, 0x20, 0x15, 0x01, 0x01, 0x22, 0x15, 0x01, 0x01, 0x24, 0x15, 0x01, 0x01, 0x26, 0x15, 0x01, 0x01, 0x88, 0x3c, 0x02, 0x03, + 0x90, 0x3c, 0x02, 0x03, 0x98, 0x3c, 0x02, 0x03, 0xe0, 0x1c, 0x03, 0x04, 0xe0, 0x02, 0x04, 0x05, 0x4e, 0x0e, 0x00, 0x01, 0x50, 0x0e, 0x00, 0x01, 0x52, 0x0e, 0x00, 0x01, 0x54, 0x0e, 0x00, 0x01, + 0x56, 0x0e, 0x00, 0x01, 0x58, 0x0e, 0x00, 0x01, 0x5a, 0x0e, 0x00, 0x01, 0x5c, 0x0e, 0x00, 0x01, 0x5e, 0x0e, 0x00, 0x01, 0x28, 0x15, 0x01, 0x01, 0x2a, 0x15, 0x01, 0x01, 0x2c, 0x15, 0x01, 0x01, + 0x2e, 0x15, 0x01, 0x01, 0x30, 0x15, 0x01, 0x01, 0x32, 0x15, 0x01, 0x01, 0x34, 0x15, 0x01, 0x01, 0x36, 0x15, 0x01, 0x01, 0x38, 0x15, 0x01, 0x01, 0x3a, 0x15, 0x01, 0x01, 0xa0, 0x3c, 0x02, 0x03, + 0xa8, 0x3c, 0x02, 0x03, 0xb0, 0x3c, 0x02, 0x03, 0xf0, 0x1c, 0x03, 0x04, 0x00, 0x03, 0x04, 0x05, 0x60, 0x0e, 0x00, 0x01, 0x62, 0x0e, 0x00, 0x01, 0x64, 0x0e, 0x00, 0x01, 0x66, 0x0e, 0x00, 0x01, + 0x68, 0x0e, 0x00, 0x01, 0x6a, 0x0e, 0x00, 0x01, 0x6c, 0x0e, 0x00, 0x01, 0x6e, 0x0e, 0x00, 0x01, 0x70, 0x0e, 0x00, 0x01, 0x3c, 0x15, 0x01, 0x01, 0x3e, 0x15, 0x01, 0x01, 0x40, 0x15, 0x01, 0x01, + 0x42, 0x15, 0x01, 0x01, 0x44, 0x15, 0x01, 0x01, 0x46, 0x15, 0x01, 0x01, 0x48, 0x15, 0x01, 0x01, 0x4a, 0x15, 0x01, 0x01, 0x4c, 0x15, 0x01, 0x01, 0x4e, 0x15, 0x01, 0x01, 0xb8, 0x3c, 0x02, 0x03, + 0xc0, 0x3c, 0x02, 0x03, 0xc8, 0x3c, 0x02, 0x03, 0x00, 0x1d, 0x03, 0x04, 0x20, 0x03, 0x04, 0x05, 0x72, 0x0e, 0x00, 0x01, 0x74, 0x0e, 0x00, 0x01, 0x76, 0x0e, 0x00, 0x01, 0x78, 0x0e, 0x00, 0x01, + 0x7a, 0x0e, 0x00, 0x01, 0x7c, 0x0e, 0x00, 0x01, 0x7e, 0x0e, 0x00, 0x01, 0x80, 0x0e, 0x00, 0x01, 0x82, 0x0e, 0x00, 0x01, 0x50, 0x15, 0x01, 0x01, 0x52, 0x15, 0x01, 0x01, 0x54, 0x15, 0x01, 0x01, + 0x56, 0x15, 0x01, 0x01, 0x58, 0x15, 0x01, 0x01, 0x5a, 0x15, 0x01, 0x01, 0x5c, 0x15, 0x01, 0x01, 0x5e, 0x15, 0x01, 0x01, 0x60, 0x15, 0x01, 0x01, 0x62, 0x15, 0x01, 0x01, 0xd0, 0x3c, 0x02, 0x03, + 0xd8, 0x3c, 0x02, 0x03, 0xe0, 0x3c, 0x02, 0x03, 0x10, 0x1d, 0x03, 0x04, 0x40, 0x03, 0x04, 0x05, 0x84, 0x0e, 0x00, 0x01, 0x86, 0x0e, 0x00, 0x01, 0x88, 0x0e, 0x00, 0x01, 0x8a, 0x0e, 0x00, 0x01, + 0x8c, 0x0e, 0x00, 0x01, 0x8e, 0x0e, 0x00, 0x01, 0x90, 0x0e, 0x00, 0x01, 0x92, 0x0e, 0x00, 0x01, 0x94, 0x0e, 0x00, 0x01, 0x64, 0x15, 0x01, 0x01, 0x66, 0x15, 0x01, 0x01, 0x68, 0x15, 0x01, 0x01, + 0x6a, 0x15, 0x01, 0x01, 0x6c, 0x15, 0x01, 0x01, 0x6e, 0x15, 0x01, 0x01, 0x70, 0x15, 0x01, 0x01, 0x72, 0x15, 0x01, 0x01, 0x74, 0x15, 0x01, 0x01, 0x76, 0x15, 0x01, 0x01, 0xe8, 0x3c, 0x02, 0x03, + 0xf0, 0x3c, 0x02, 0x03, 0xf8, 0x3c, 0x02, 0x03, 0x20, 0x1d, 0x03, 0x04, 0x60, 0x03, 0x04, 0x05, 0x96, 0x0e, 0x00, 0x01, 0x98, 0x0e, 0x00, 0x01, 0x9a, 0x0e, 0x00, 0x01, 0x9c, 0x0e, 0x00, 0x01, + 0x9e, 0x0e, 0x00, 0x01, 0xa0, 0x0e, 0x00, 0x01, 0xa2, 0x0e, 0x00, 0x01, 0xa4, 0x0e, 0x00, 0x01, 0xa6, 0x0e, 0x00, 0x01, 0x78, 0x15, 0x01, 0x01, 0x7a, 0x15, 0x01, 0x01, 0x7c, 0x15, 0x01, 0x01, + 0x7e, 0x15, 0x01, 0x01, 0x80, 0x15, 0x01, 0x01, 0x82, 0x15, 0x01, 0x01, 0x84, 0x15, 0x01, 0x01, 0x86, 0x15, 0x01, 0x01, 0x88, 0x15, 0x01, 0x01, 0x8a, 0x15, 0x01, 0x01, 0x00, 0x3d, 0x02, 0x03, + 0x08, 0x3d, 0x02, 0x03, 0x10, 0x3d, 0x02, 0x03, 0x30, 0x1d, 0x03, 0x04, 0x80, 0x03, 0x04, 0x05, 0xa8, 0x0e, 0x00, 0x01, 0xaa, 0x0e, 0x00, 0x01, 0xac, 0x0e, 0x00, 0x01, 0xae, 0x0e, 0x00, 0x01, + 0xb0, 0x0e, 0x00, 0x01, 0xb2, 0x0e, 0x00, 0x01, 0xb4, 0x0e, 0x00, 0x01, 0xb6, 0x0e, 0x00, 0x01, 0xb8, 0x0e, 0x00, 0x01, 0x8c, 0x15, 0x01, 0x01, 0x8e, 0x15, 0x01, 0x01, 0x90, 0x15, 0x01, 0x01, + 0x92, 0x15, 0x01, 0x01, 0x94, 0x15, 0x01, 0x01, 0x96, 0x15, 0x01, 0x01, 0x98, 0x15, 0x01, 0x01, 0x9a, 0x15, 0x01, 0x01, 0x9c, 0x15, 0x01, 0x01, 0x18, 0x3d, 0x02, 0x03, 0x20, 0x3d, 0x02, 0x03, + 0x28, 0x3d, 0x02, 0x03, 0x30, 0x3d, 0x02, 0x03, 0x40, 0x1d, 0x03, 0x04, 0xa0, 0x03, 0x04, 0x05, 0xba, 0x0e, 0x00, 0x01, 0xbc, 0x0e, 0x00, 0x01, 0xbe, 0x0e, 0x00, 0x01, 0xc0, 0x0e, 0x00, 0x01, + 0xc2, 0x0e, 0x00, 0x01, 0xc4, 0x0e, 0x00, 0x01, 0xc6, 0x0e, 0x00, 0x01, 0xc8, 0x0e, 0x00, 0x01, 0xca, 0x0e, 0x00, 0x01, 0x9e, 0x15, 0x01, 0x01, 0xa0, 0x15, 0x01, 0x01, 0xa2, 0x15, 0x01, 0x01, + 0xa4, 0x15, 0x01, 0x01, 0xa6, 0x15, 0x01, 0x01, 0xa8, 0x15, 0x01, 0x01, 0xaa, 0x15, 0x01, 0x01, 0xac, 0x15, 0x01, 0x01, 0xae, 0x15, 0x01, 0x01, 0x38, 0x3d, 0x02, 0x03, 0x40, 0x3d, 0x02, 0x03, + 0x48, 0x3d, 0x02, 0x03, 0x50, 0x3d, 0x02, 0x03, 0x50, 0x1d, 0x03, 0x04, 0xc0, 0x03, 0x04, 0x05, 0xcc, 0x0e, 0x00, 0x01, 0xce, 0x0e, 0x00, 0x01, 0xd0, 0x0e, 0x00, 0x01, 0xd2, 0x0e, 0x00, 0x01, + 0xd4, 0x0e, 0x00, 0x01, 0xd6, 0x0e, 0x00, 0x01, 0xd8, 0x0e, 0x00, 0x01, 0xda, 0x0e, 0x00, 0x01, 0xdc, 0x0e, 0x00, 0x01, 0xb0, 0x15, 0x01, 0x01, 0xb2, 0x15, 0x01, 0x01, 0xb4, 0x15, 0x01, 0x01, + 0xb6, 0x15, 0x01, 0x01, 0xb8, 0x15, 0x01, 0x01, 0xba, 0x15, 0x01, 0x01, 0xbc, 0x15, 0x01, 0x01, 0xbe, 0x15, 0x01, 0x01, 0xc0, 0x15, 0x01, 0x01, 0x58, 0x3d, 0x02, 0x03, 0x60, 0x3d, 0x02, 0x03, + 0x68, 0x3d, 0x02, 0x03, 0x70, 0x3d, 0x02, 0x03, 0x60, 0x1d, 0x03, 0x04, 0xe0, 0x03, 0x04, 0x05, 0xde, 0x0e, 0x00, 0x01, 0xe0, 0x0e, 0x00, 0x01, 0xe2, 0x0e, 0x00, 0x01, 0xe4, 0x0e, 0x00, 0x01, + 0xe6, 0x0e, 0x00, 0x01, 0xe8, 0x0e, 0x00, 0x01, 0xea, 0x0e, 0x00, 0x01, 0xec, 0x0e, 0x00, 0x01, 0xee, 0x0e, 0x00, 0x01, 0xc2, 0x15, 0x01, 0x01, 0xc4, 0x15, 0x01, 0x01, 0xc6, 0x15, 0x01, 0x01, + 0xc8, 0x15, 0x01, 0x01, 0xca, 0x15, 0x01, 0x01, 0xcc, 0x15, 0x01, 0x01, 0xce, 0x15, 0x01, 0x01, 0xd0, 0x15, 0x01, 0x01, 0xd2, 0x15, 0x01, 0x01, 0x78, 0x3d, 0x02, 0x03, 0x80, 0x3d, 0x02, 0x03, + 0x88, 0x3d, 0x02, 0x03, 0x90, 0x3d, 0x02, 0x03, 0x70, 0x1d, 0x03, 0x04, 0x00, 0x04, 0x04, 0x05, 0xf0, 0x0e, 0x00, 0x01, 0xf2, 0x0e, 0x00, 0x01, 0xf4, 0x0e, 0x00, 0x01, 0xf6, 0x0e, 0x00, 0x01, + 0xf8, 0x0e, 0x00, 0x01, 0xfa, 0x0e, 0x00, 0x01, 0xfc, 0x0e, 0x00, 0x01, 0xfe, 0x0e, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x01, 0xd4, 0x15, 0x01, 0x01, 0xd6, 0x15, 0x01, 0x01, 0xd8, 0x15, 0x01, 0x01, + 0xda, 0x15, 0x01, 0x01, 0xdc, 0x15, 0x01, 0x01, 0xde, 0x15, 0x01, 0x01, 0xe0, 0x15, 0x01, 0x01, 0xe2, 0x15, 0x01, 0x01, 0xe4, 0x15, 0x01, 0x01, 0x98, 0x3d, 0x02, 0x03, 0xa0, 0x3d, 0x02, 0x03, + 0xa8, 0x3d, 0x02, 0x03, 0xb0, 0x3d, 0x02, 0x03, 0x80, 0x1d, 0x03, 0x04, 0x20, 0x04, 0x04, 0x05, 0x02, 0x0f, 0x00, 0x01, 0x04, 0x0f, 0x00, 0x01, 0x06, 0x0f, 0x00, 0x01, 0x08, 0x0f, 0x00, 0x01, + 0x0a, 0x0f, 0x00, 0x01, 0x0c, 0x0f, 0x00, 0x01, 0x0e, 0x0f, 0x00, 0x01, 0x10, 0x0f, 0x00, 0x01, 0x12, 0x0f, 0x00, 0x01, 0xe6, 0x15, 0x01, 0x01, 0xe8, 0x15, 0x01, 0x01, 0xea, 0x15, 0x01, 0x01, + 0xec, 0x15, 0x01, 0x01, 0xee, 0x15, 0x01, 0x01, 0xf0, 0x15, 0x01, 0x01, 0xf2, 0x15, 0x01, 0x01, 0xf4, 0x15, 0x01, 0x01, 0xf6, 0x15, 0x01, 0x01, 0xb8, 0x3d, 0x02, 0x03, 0xc0, 0x3d, 0x02, 0x03, + 0xc8, 0x3d, 0x02, 0x03, 0xd0, 0x3d, 0x02, 0x03, 0x90, 0x1d, 0x03, 0x04, 0x40, 0x04, 0x04, 0x05, 0x14, 0x0f, 0x00, 0x01, 0x16, 0x0f, 0x00, 0x01, 0x18, 0x0f, 0x00, 0x01, 0x1a, 0x0f, 0x00, 0x01, + 0x1c, 0x0f, 0x00, 0x01, 0x1e, 0x0f, 0x00, 0x01, 0x20, 0x0f, 0x00, 0x01, 0x22, 0x0f, 0x00, 0x01, 0x24, 0x0f, 0x00, 0x01, 0xf8, 0x15, 0x01, 0x01, 0xfa, 0x15, 0x01, 0x01, 0xfc, 0x15, 0x01, 0x01, + 0xfe, 0x15, 0x01, 0x01, 0x00, 0x16, 0x01, 0x01, 0x02, 0x16, 0x01, 0x01, 0x04, 0x16, 0x01, 0x01, 0x06, 0x16, 0x01, 0x01, 0x08, 0x16, 0x01, 0x01, 0xd8, 0x3d, 0x02, 0x03, 0xe0, 0x3d, 0x02, 0x03, + 0xe8, 0x3d, 0x02, 0x03, 0xf0, 0x3d, 0x02, 0x03, 0xa0, 0x1d, 0x03, 0x04, 0x60, 0x04, 0x04, 0x05, 0x26, 0x0f, 0x00, 0x01, 0x28, 0x0f, 0x00, 0x01, 0x2a, 0x0f, 0x00, 0x01, 0x2c, 0x0f, 0x00, 0x01, + 0x2e, 0x0f, 0x00, 0x01, 0x30, 0x0f, 0x00, 0x01, 0x32, 0x0f, 0x00, 0x01, 0x34, 0x0f, 0x00, 0x01, 0x36, 0x0f, 0x00, 0x01, 0x0a, 0x16, 0x01, 0x01, 0x0c, 0x16, 0x01, 0x01, 0x0e, 0x16, 0x01, 0x01, + 0x10, 0x16, 0x01, 0x01, 0x12, 0x16, 0x01, 0x01, 0x14, 0x16, 0x01, 0x01, 0x16, 0x16, 0x01, 0x01, 0x18, 0x16, 0x01, 0x01, 0x1a, 0x16, 0x01, 0x01, 0xf8, 0x3d, 0x02, 0x03, 0x00, 0x3e, 0x02, 0x03, + 0x08, 0x3e, 0x02, 0x03, 0x10, 0x3e, 0x02, 0x03, 0xb0, 0x1d, 0x03, 0x04, 0x80, 0x04, 0x04, 0x05, 0x38, 0x0f, 0x00, 0x01, 0x3a, 0x0f, 0x00, 0x01, 0x3c, 0x0f, 0x00, 0x01, 0x3e, 0x0f, 0x00, 0x01, + 0x40, 0x0f, 0x00, 0x01, 0x42, 0x0f, 0x00, 0x01, 0x44, 0x0f, 0x00, 0x01, 0x46, 0x0f, 0x00, 0x01, 0x48, 0x0f, 0x00, 0x01, 0x1c, 0x16, 0x01, 0x01, 0x1e, 0x16, 0x01, 0x01, 0x20, 0x16, 0x01, 0x01, + 0x22, 0x16, 0x01, 0x01, 0x24, 0x16, 0x01, 0x01, 0x26, 0x16, 0x01, 0x01, 0x28, 0x16, 0x01, 0x01, 0x2a, 0x16, 0x01, 0x01, 0x2c, 0x16, 0x01, 0x01, 0x18, 0x3e, 0x02, 0x03, 0x20, 0x3e, 0x02, 0x03, + 0x28, 0x3e, 0x02, 0x03, 0x30, 0x3e, 0x02, 0x03, 0xc0, 0x1d, 0x03, 0x04, 0xa0, 0x04, 0x04, 0x05, 0x4a, 0x0f, 0x00, 0x01, 0x4c, 0x0f, 0x00, 0x01, 0x4e, 0x0f, 0x00, 0x01, 0x50, 0x0f, 0x00, 0x01, + 0x52, 0x0f, 0x00, 0x01, 0x54, 0x0f, 0x00, 0x01, 0x56, 0x0f, 0x00, 0x01, 0x58, 0x0f, 0x00, 0x01, 0x5a, 0x0f, 0x00, 0x01, 0x2e, 0x16, 0x01, 0x01, 0x30, 0x16, 0x01, 0x01, 0x32, 0x16, 0x01, 0x01, + 0x34, 0x16, 0x01, 0x01, 0x36, 0x16, 0x01, 0x01, 0x38, 0x16, 0x01, 0x01, 0x3a, 0x16, 0x01, 0x01, 0x3c, 0x16, 0x01, 0x01, 0x3e, 0x16, 0x01, 0x01, 0x38, 0x3e, 0x02, 0x03, 0x40, 0x3e, 0x02, 0x03, + 0x48, 0x3e, 0x02, 0x03, 0x50, 0x3e, 0x02, 0x03, 0xd0, 0x1d, 0x03, 0x04, 0xc0, 0x04, 0x04, 0x05, 0x5c, 0x0f, 0x00, 0x01, 0x5e, 0x0f, 0x00, 0x01, 0x60, 0x0f, 0x00, 0x01, 0x62, 0x0f, 0x00, 0x01, + 0x64, 0x0f, 0x00, 0x01, 0x66, 0x0f, 0x00, 0x01, 0x68, 0x0f, 0x00, 0x01, 0x6a, 0x0f, 0x00, 0x01, 0x6c, 0x0f, 0x00, 0x01, 0x40, 0x16, 0x01, 0x01, 0x42, 0x16, 0x01, 0x01, 0x44, 0x16, 0x01, 0x01, + 0x46, 0x16, 0x01, 0x01, 0x48, 0x16, 0x01, 0x01, 0x4a, 0x16, 0x01, 0x01, 0x4c, 0x16, 0x01, 0x01, 0x4e, 0x16, 0x01, 0x01, 0x50, 0x16, 0x01, 0x01, 0x58, 0x3e, 0x02, 0x03, 0x60, 0x3e, 0x02, 0x03, + 0x68, 0x3e, 0x02, 0x03, 0x70, 0x3e, 0x02, 0x03, 0xe0, 0x1d, 0x03, 0x04, 0xe0, 0x04, 0x04, 0x05, 0x6e, 0x0f, 0x00, 0x01, 0x70, 0x0f, 0x00, 0x01, 0x72, 0x0f, 0x00, 0x01, 0x74, 0x0f, 0x00, 0x01, + 0x76, 0x0f, 0x00, 0x01, 0x78, 0x0f, 0x00, 0x01, 0x7a, 0x0f, 0x00, 0x01, 0x7c, 0x0f, 0x00, 0x01, 0x7e, 0x0f, 0x00, 0x01, 0x52, 0x16, 0x01, 0x01, 0x54, 0x16, 0x01, 0x01, 0x56, 0x16, 0x01, 0x01, + 0x58, 0x16, 0x01, 0x01, 0x5a, 0x16, 0x01, 0x01, 0x5c, 0x16, 0x01, 0x01, 0x5e, 0x16, 0x01, 0x01, 0x60, 0x16, 0x01, 0x01, 0x62, 0x16, 0x01, 0x01, 0x78, 0x3e, 0x02, 0x03, 0x80, 0x3e, 0x02, 0x03, + 0x88, 0x3e, 0x02, 0x03, 0x90, 0x3e, 0x02, 0x03, 0xf0, 0x1d, 0x03, 0x04, 0x00, 0x05, 0x04, 0x05, 0x80, 0x0f, 0x00, 0x01, 0x82, 0x0f, 0x00, 0x01, 0x84, 0x0f, 0x00, 0x01, 0x86, 0x0f, 0x00, 0x01, + 0x88, 0x0f, 0x00, 0x01, 0x8a, 0x0f, 0x00, 0x01, 0x8c, 0x0f, 0x00, 0x01, 0x8e, 0x0f, 0x00, 0x01, 0x90, 0x0f, 0x00, 0x01, 0x64, 0x16, 0x01, 0x01, 0x66, 0x16, 0x01, 0x01, 0x68, 0x16, 0x01, 0x01, + 0x6a, 0x16, 0x01, 0x01, 0x6c, 0x16, 0x01, 0x01, 0x6e, 0x16, 0x01, 0x01, 0x70, 0x16, 0x01, 0x01, 0x72, 0x16, 0x01, 0x01, 0x74, 0x16, 0x01, 0x01, 0x98, 0x3e, 0x02, 0x03, 0xa0, 0x3e, 0x02, 0x03, + 0xa8, 0x3e, 0x02, 0x03, 0xb0, 0x3e, 0x02, 0x03, 0x00, 0x1e, 0x03, 0x04, 0x20, 0x05, 0x04, 0x05, 0x92, 0x0f, 0x00, 0x01, 0x94, 0x0f, 0x00, 0x01, 0x96, 0x0f, 0x00, 0x01, 0x98, 0x0f, 0x00, 0x01, + 0x9a, 0x0f, 0x00, 0x01, 0x9c, 0x0f, 0x00, 0x01, 0x9e, 0x0f, 0x00, 0x01, 0xa0, 0x0f, 0x00, 0x01, 0xa2, 0x0f, 0x00, 0x01, 0x76, 0x16, 0x01, 0x01, 0x78, 0x16, 0x01, 0x01, 0x7a, 0x16, 0x01, 0x01, + 0x7c, 0x16, 0x01, 0x01, 0x7e, 0x16, 0x01, 0x01, 0x80, 0x16, 0x01, 0x01, 0x82, 0x16, 0x01, 0x01, 0x84, 0x16, 0x01, 0x01, 0x86, 0x16, 0x01, 0x01, 0xb8, 0x3e, 0x02, 0x03, 0xc0, 0x3e, 0x02, 0x03, + 0xc8, 0x3e, 0x02, 0x03, 0xd0, 0x3e, 0x02, 0x03, 0x10, 0x1e, 0x03, 0x04, 0x40, 0x05, 0x04, 0x05, 0xa4, 0x0f, 0x00, 0x01, 0xa6, 0x0f, 0x00, 0x01, 0xa8, 0x0f, 0x00, 0x01, 0xaa, 0x0f, 0x00, 0x01, + 0xac, 0x0f, 0x00, 0x01, 0xae, 0x0f, 0x00, 0x01, 0xb0, 0x0f, 0x00, 0x01, 0xb2, 0x0f, 0x00, 0x01, 0xb4, 0x0f, 0x00, 0x01, 0x88, 0x16, 0x01, 0x01, 0x8a, 0x16, 0x01, 0x01, 0x8c, 0x16, 0x01, 0x01, + 0x8e, 0x16, 0x01, 0x01, 0x90, 0x16, 0x01, 0x01, 0x92, 0x16, 0x01, 0x01, 0x94, 0x16, 0x01, 0x01, 0x96, 0x16, 0x01, 0x01, 0x98, 0x16, 0x01, 0x01, 0xd8, 0x3e, 0x02, 0x03, 0xe0, 0x3e, 0x02, 0x03, + 0xe8, 0x3e, 0x02, 0x03, 0xf0, 0x3e, 0x02, 0x03, 0x20, 0x1e, 0x03, 0x04, 0x60, 0x05, 0x04, 0x05, 0xb6, 0x0f, 0x00, 0x01, 0xb8, 0x0f, 0x00, 0x01, 0xba, 0x0f, 0x00, 0x01, 0xbc, 0x0f, 0x00, 0x01, + 0xbe, 0x0f, 0x00, 0x01, 0xc0, 0x0f, 0x00, 0x01, 0xc2, 0x0f, 0x00, 0x01, 0xc4, 0x0f, 0x00, 0x01, 0xc6, 0x0f, 0x00, 0x01, 0x9a, 0x16, 0x01, 0x01, 0x9c, 0x16, 0x01, 0x01, 0x9e, 0x16, 0x01, 0x01, + 0xa0, 0x16, 0x01, 0x01, 0xa2, 0x16, 0x01, 0x01, 0xa4, 0x16, 0x01, 0x01, 0xa6, 0x16, 0x01, 0x01, 0xa8, 0x16, 0x01, 0x01, 0xaa, 0x16, 0x01, 0x01, 0xf8, 0x3e, 0x02, 0x03, 0x00, 0x3f, 0x02, 0x03, + 0x08, 0x3f, 0x02, 0x03, 0x10, 0x3f, 0x02, 0x03, 0x30, 0x1e, 0x03, 0x04, 0x80, 0x05, 0x04, 0x05, 0xc8, 0x0f, 0x00, 0x01, 0xca, 0x0f, 0x00, 0x01, 0xcc, 0x0f, 0x00, 0x01, 0xce, 0x0f, 0x00, 0x01, + 0xd0, 0x0f, 0x00, 0x01, 0xd2, 0x0f, 0x00, 0x01, 0xd4, 0x0f, 0x00, 0x01, 0xd6, 0x0f, 0x00, 0x01, 0xd8, 0x0f, 0x00, 0x01, 0xac, 0x16, 0x01, 0x01, 0xae, 0x16, 0x01, 0x01, 0xb0, 0x16, 0x01, 0x01, + 0xb2, 0x16, 0x01, 0x01, 0xb4, 0x16, 0x01, 0x01, 0xb6, 0x16, 0x01, 0x01, 0xb8, 0x16, 0x01, 0x01, 0xba, 0x16, 0x01, 0x01, 0xbc, 0x16, 0x01, 0x01, 0x18, 0x3f, 0x02, 0x03, 0x20, 0x3f, 0x02, 0x03, + 0x28, 0x3f, 0x02, 0x03, 0x30, 0x3f, 0x02, 0x03, 0x40, 0x1e, 0x03, 0x04, 0xa0, 0x05, 0x04, 0x05, 0xda, 0x0f, 0x00, 0x01, 0xdc, 0x0f, 0x00, 0x01, 0xde, 0x0f, 0x00, 0x01, 0xe0, 0x0f, 0x00, 0x01, + 0xe2, 0x0f, 0x00, 0x01, 0xe4, 0x0f, 0x00, 0x01, 0xe6, 0x0f, 0x00, 0x01, 0xe8, 0x0f, 0x00, 0x01, 0xea, 0x0f, 0x00, 0x01, 0xbe, 0x16, 0x01, 0x01, 0xc0, 0x16, 0x01, 0x01, 0xc2, 0x16, 0x01, 0x01, + 0xc4, 0x16, 0x01, 0x01, 0xc6, 0x16, 0x01, 0x01, 0xc8, 0x16, 0x01, 0x01, 0xca, 0x16, 0x01, 0x01, 0xcc, 0x16, 0x01, 0x01, 0xce, 0x16, 0x01, 0x01, 0x38, 0x3f, 0x02, 0x03, 0x40, 0x3f, 0x02, 0x03, + 0x48, 0x3f, 0x02, 0x03, 0x50, 0x3f, 0x02, 0x03, 0x50, 0x1e, 0x03, 0x04, 0xc0, 0x05, 0x04, 0x05, 0xec, 0x0f, 0x00, 0x01, 0xee, 0x0f, 0x00, 0x01, 0xf0, 0x0f, 0x00, 0x01, 0xf2, 0x0f, 0x00, 0x01, + 0xf4, 0x0f, 0x00, 0x01, 0xf6, 0x0f, 0x00, 0x01, 0xf8, 0x0f, 0x00, 0x01, 0xfa, 0x0f, 0x00, 0x01, 0xfc, 0x0f, 0x00, 0x01, 0xd0, 0x16, 0x01, 0x01, 0xd2, 0x16, 0x01, 0x01, 0xd4, 0x16, 0x01, 0x01, + 0xd6, 0x16, 0x01, 0x01, 0xd8, 0x16, 0x01, 0x01, 0xda, 0x16, 0x01, 0x01, 0xdc, 0x16, 0x01, 0x01, 0xde, 0x16, 0x01, 0x01, 0xe0, 0x16, 0x01, 0x01, 0x58, 0x3f, 0x02, 0x03, 0x60, 0x3f, 0x02, 0x03, + 0x68, 0x3f, 0x02, 0x03, 0x70, 0x3f, 0x02, 0x03, 0x60, 0x1e, 0x03, 0x04, 0xe0, 0x05, 0x04, 0x05, 0xfe, 0x0f, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x02, 0x10, 0x00, 0x01, 0x04, 0x10, 0x00, 0x01, + 0x06, 0x10, 0x00, 0x01, 0x08, 0x10, 0x00, 0x01, 0x0a, 0x10, 0x00, 0x01, 0x0c, 0x10, 0x00, 0x01, 0x0e, 0x10, 0x00, 0x01, 0xe2, 0x16, 0x01, 0x01, 0xe4, 0x16, 0x01, 0x01, 0xe6, 0x16, 0x01, 0x01, + 0xe8, 0x16, 0x01, 0x01, 0xea, 0x16, 0x01, 0x01, 0xec, 0x16, 0x01, 0x01, 0xee, 0x16, 0x01, 0x01, 0xf0, 0x16, 0x01, 0x01, 0xf2, 0x16, 0x01, 0x01, 0x78, 0x3f, 0x02, 0x03, 0x80, 0x3f, 0x02, 0x03, + 0x88, 0x3f, 0x02, 0x03, 0x90, 0x3f, 0x02, 0x03, 0x70, 0x1e, 0x03, 0x04, 0x00, 0x06, 0x04, 0x05, 0x10, 0x10, 0x00, 0x01, 0x12, 0x10, 0x00, 0x01, 0x14, 0x10, 0x00, 0x01, 0x16, 0x10, 0x00, 0x01, + 0x18, 0x10, 0x00, 0x01, 0x1a, 0x10, 0x00, 0x01, 0x1c, 0x10, 0x00, 0x01, 0x1e, 0x10, 0x00, 0x01, 0x20, 0x10, 0x00, 0x01, 0xf4, 0x16, 0x01, 0x01, 0xf6, 0x16, 0x01, 0x01, 0xf8, 0x16, 0x01, 0x01, + 0xfa, 0x16, 0x01, 0x01, 0xfc, 0x16, 0x01, 0x01, 0xfe, 0x16, 0x01, 0x01, 0x00, 0x17, 0x01, 0x01, 0x02, 0x17, 0x01, 0x01, 0x04, 0x17, 0x01, 0x01, 0x98, 0x3f, 0x02, 0x03, 0xa0, 0x3f, 0x02, 0x03, + 0xa8, 0x3f, 0x02, 0x03, 0xb0, 0x3f, 0x02, 0x03, 0x80, 0x1e, 0x03, 0x04, 0x20, 0x06, 0x04, 0x05, 0x22, 0x10, 0x00, 0x01, 0x24, 0x10, 0x00, 0x01, 0x26, 0x10, 0x00, 0x01, 0x28, 0x10, 0x00, 0x01, + 0x2a, 0x10, 0x00, 0x01, 0x2c, 0x10, 0x00, 0x01, 0x2e, 0x10, 0x00, 0x01, 0x30, 0x10, 0x00, 0x01, 0x32, 0x10, 0x00, 0x01, 0x06, 0x17, 0x01, 0x01, 0x08, 0x17, 0x01, 0x01, 0x0a, 0x17, 0x01, 0x01, + 0x0c, 0x17, 0x01, 0x01, 0x0e, 0x17, 0x01, 0x01, 0x10, 0x17, 0x01, 0x01, 0x12, 0x17, 0x01, 0x01, 0x14, 0x17, 0x01, 0x01, 0x16, 0x17, 0x01, 0x01, 0xb8, 0x3f, 0x02, 0x03, 0xc0, 0x3f, 0x02, 0x03, + 0xc8, 0x3f, 0x02, 0x03, 0xd0, 0x3f, 0x02, 0x03, 0x90, 0x1e, 0x03, 0x04, 0x40, 0x06, 0x04, 0x05, 0x34, 0x10, 0x00, 0x01, 0x36, 0x10, 0x00, 0x01, 0x38, 0x10, 0x00, 0x01, 0x3a, 0x10, 0x00, 0x01, + 0x3c, 0x10, 0x00, 0x01, 0x3e, 0x10, 0x00, 0x01, 0x40, 0x10, 0x00, 0x01, 0x42, 0x10, 0x00, 0x01, 0x44, 0x10, 0x00, 0x01, 0x18, 0x17, 0x01, 0x01, 0x1a, 0x17, 0x01, 0x01, 0x1c, 0x17, 0x01, 0x01, + 0x1e, 0x17, 0x01, 0x01, 0x20, 0x17, 0x01, 0x01, 0x22, 0x17, 0x01, 0x01, 0x24, 0x17, 0x01, 0x01, 0x26, 0x17, 0x01, 0x01, 0x28, 0x17, 0x01, 0x01, 0xd8, 0x3f, 0x02, 0x03, 0xe0, 0x3f, 0x02, 0x03, + 0xe8, 0x3f, 0x02, 0x03, 0xf0, 0x3f, 0x02, 0x03, 0xa0, 0x1e, 0x03, 0x04, 0x60, 0x06, 0x04, 0x05, 0x46, 0x10, 0x00, 0x01, 0x48, 0x10, 0x00, 0x01, 0x4a, 0x10, 0x00, 0x01, 0x4c, 0x10, 0x00, 0x01, + 0x4e, 0x10, 0x00, 0x01, 0x50, 0x10, 0x00, 0x01, 0x52, 0x10, 0x00, 0x01, 0x54, 0x10, 0x00, 0x01, 0x56, 0x10, 0x00, 0x01, 0x2a, 0x17, 0x01, 0x01, 0x2c, 0x17, 0x01, 0x01, 0x2e, 0x17, 0x01, 0x01, + 0x30, 0x17, 0x01, 0x01, 0x32, 0x17, 0x01, 0x01, 0x34, 0x17, 0x01, 0x01, 0x36, 0x17, 0x01, 0x01, 0x38, 0x17, 0x01, 0x01, 0x3a, 0x17, 0x01, 0x01, 0xf8, 0x3f, 0x02, 0x03, 0x00, 0x00, 0x02, 0x02, + 0x04, 0x00, 0x02, 0x02, 0x08, 0x00, 0x02, 0x02, 0xb0, 0x1e, 0x03, 0x04, 0x80, 0x06, 0x04, 0x05, 0x58, 0x10, 0x00, 0x01, 0x5a, 0x10, 0x00, 0x01, 0x5c, 0x10, 0x00, 0x01, 0x5e, 0x10, 0x00, 0x01, + 0x60, 0x10, 0x00, 0x01, 0x62, 0x10, 0x00, 0x01, 0x64, 0x10, 0x00, 0x01, 0x66, 0x10, 0x00, 0x01, 0x68, 0x10, 0x00, 0x01, 0x3c, 0x17, 0x01, 0x01, 0x3e, 0x17, 0x01, 0x01, 0x40, 0x17, 0x01, 0x01, + 0x42, 0x17, 0x01, 0x01, 0x44, 0x17, 0x01, 0x01, 0x46, 0x17, 0x01, 0x01, 0x48, 0x17, 0x01, 0x01, 0x4a, 0x17, 0x01, 0x01, 0x4c, 0x17, 0x01, 0x01, 0x0c, 0x00, 0x02, 0x02, 0x10, 0x00, 0x02, 0x02, + 0x14, 0x00, 0x02, 0x02, 0x18, 0x00, 0x02, 0x02, 0xc0, 0x1e, 0x03, 0x04, 0xa0, 0x06, 0x04, 0x05, 0x6a, 0x10, 0x00, 0x01, 0x6c, 0x10, 0x00, 0x01, 0x6e, 0x10, 0x00, 0x01, 0x70, 0x10, 0x00, 0x01, + 0x72, 0x10, 0x00, 0x01, 0x74, 0x10, 0x00, 0x01, 0x76, 0x10, 0x00, 0x01, 0x78, 0x10, 0x00, 0x01, 0x7a, 0x10, 0x00, 0x01, 0x4e, 0x17, 0x01, 0x01, 0x50, 0x17, 0x01, 0x01, 0x52, 0x17, 0x01, 0x01, + 0x54, 0x17, 0x01, 0x01, 0x56, 0x17, 0x01, 0x01, 0x58, 0x17, 0x01, 0x01, 0x5a, 0x17, 0x01, 0x01, 0x5c, 0x17, 0x01, 0x01, 0x5e, 0x17, 0x01, 0x01, 0x1c, 0x00, 0x02, 0x02, 0x20, 0x00, 0x02, 0x02, + 0x24, 0x00, 0x02, 0x02, 0x28, 0x00, 0x02, 0x02, 0xd0, 0x1e, 0x03, 0x04, 0xc0, 0x06, 0x04, 0x05, 0x7c, 0x10, 0x00, 0x01, 0x7e, 0x10, 0x00, 0x01, 0x80, 0x10, 0x00, 0x01, 0x82, 0x10, 0x00, 0x01, + 0x84, 0x10, 0x00, 0x01, 0x86, 0x10, 0x00, 0x01, 0x88, 0x10, 0x00, 0x01, 0x8a, 0x10, 0x00, 0x01, 0x8c, 0x10, 0x00, 0x01, 0x60, 0x17, 0x01, 0x01, 0x62, 0x17, 0x01, 0x01, 0x64, 0x17, 0x01, 0x01, + 0x66, 0x17, 0x01, 0x01, 0x68, 0x17, 0x01, 0x01, 0x6a, 0x17, 0x01, 0x01, 0x6c, 0x17, 0x01, 0x01, 0x6e, 0x17, 0x01, 0x01, 0x70, 0x17, 0x01, 0x01, 0x2c, 0x00, 0x02, 0x02, 0x30, 0x00, 0x02, 0x02, + 0x34, 0x00, 0x02, 0x02, 0x38, 0x00, 0x02, 0x02, 0xe0, 0x1e, 0x03, 0x04, 0x00, 0x21, 0x05, 0x07, 0x8e, 0x10, 0x00, 0x01, 0x90, 0x10, 0x00, 0x01, 0x92, 0x10, 0x00, 0x01, 0x94, 0x10, 0x00, 0x01, + 0x96, 0x10, 0x00, 0x01, 0x98, 0x10, 0x00, 0x01, 0x9a, 0x10, 0x00, 0x01, 0x9c, 0x10, 0x00, 0x01, 0x9e, 0x10, 0x00, 0x01, 0x72, 0x17, 0x01, 0x01, 0x74, 0x17, 0x01, 0x01, 0x76, 0x17, 0x01, 0x01, + 0x78, 0x17, 0x01, 0x01, 0x7a, 0x17, 0x01, 0x01, 0x7c, 0x17, 0x01, 0x01, 0x7e, 0x17, 0x01, 0x01, 0x80, 0x17, 0x01, 0x01, 0x82, 0x17, 0x01, 0x01, 0x3c, 0x00, 0x02, 0x02, 0x40, 0x00, 0x02, 0x02, + 0x44, 0x00, 0x02, 0x02, 0x48, 0x00, 0x02, 0x02, 0xf0, 0x1e, 0x03, 0x04, 0x80, 0x21, 0x05, 0x07, 0xa0, 0x10, 0x00, 0x01, 0xa2, 0x10, 0x00, 0x01, 0xa4, 0x10, 0x00, 0x01, 0xa6, 0x10, 0x00, 0x01, + 0xa8, 0x10, 0x00, 0x01, 0xaa, 0x10, 0x00, 0x01, 0xac, 0x10, 0x00, 0x01, 0xae, 0x10, 0x00, 0x01, 0xb0, 0x10, 0x00, 0x01, 0x84, 0x17, 0x01, 0x01, 0x86, 0x17, 0x01, 0x01, 0x88, 0x17, 0x01, 0x01, + 0x8a, 0x17, 0x01, 0x01, 0x8c, 0x17, 0x01, 0x01, 0x8e, 0x17, 0x01, 0x01, 0x90, 0x17, 0x01, 0x01, 0x92, 0x17, 0x01, 0x01, 0x94, 0x17, 0x01, 0x01, 0x4c, 0x00, 0x02, 0x02, 0x50, 0x00, 0x02, 0x02, + 0x54, 0x00, 0x02, 0x02, 0x58, 0x00, 0x02, 0x02, 0x00, 0x1f, 0x03, 0x04, 0x00, 0x22, 0x05, 0x07, 0xb2, 0x10, 0x00, 0x01, 0xb4, 0x10, 0x00, 0x01, 0xb6, 0x10, 0x00, 0x01, 0xb8, 0x10, 0x00, 0x01, + 0xba, 0x10, 0x00, 0x01, 0xbc, 0x10, 0x00, 0x01, 0xbe, 0x10, 0x00, 0x01, 0xc0, 0x10, 0x00, 0x01, 0xc2, 0x10, 0x00, 0x01, 0x96, 0x17, 0x01, 0x01, 0x98, 0x17, 0x01, 0x01, 0x9a, 0x17, 0x01, 0x01, + 0x9c, 0x17, 0x01, 0x01, 0x9e, 0x17, 0x01, 0x01, 0xa0, 0x17, 0x01, 0x01, 0xa2, 0x17, 0x01, 0x01, 0xa4, 0x17, 0x01, 0x01, 0xa6, 0x17, 0x01, 0x01, 0x5c, 0x00, 0x02, 0x02, 0x60, 0x00, 0x02, 0x02, + 0x64, 0x00, 0x02, 0x02, 0x68, 0x00, 0x02, 0x02, 0x10, 0x1f, 0x03, 0x04, 0x80, 0x22, 0x05, 0x07, 0xc4, 0x10, 0x00, 0x01, 0xc6, 0x10, 0x00, 0x01, 0xc8, 0x10, 0x00, 0x01, 0xca, 0x10, 0x00, 0x01, + 0xcc, 0x10, 0x00, 0x01, 0xce, 0x10, 0x00, 0x01, 0xd0, 0x10, 0x00, 0x01, 0xd2, 0x10, 0x00, 0x01, 0xd4, 0x10, 0x00, 0x01, 0xa8, 0x17, 0x01, 0x01, 0xaa, 0x17, 0x01, 0x01, 0xac, 0x17, 0x01, 0x01, + 0xae, 0x17, 0x01, 0x01, 0xb0, 0x17, 0x01, 0x01, 0xb2, 0x17, 0x01, 0x01, 0xb4, 0x17, 0x01, 0x01, 0xb6, 0x17, 0x01, 0x01, 0xb8, 0x17, 0x01, 0x01, 0x6c, 0x00, 0x02, 0x02, 0x70, 0x00, 0x02, 0x02, + 0x74, 0x00, 0x02, 0x02, 0x78, 0x00, 0x02, 0x02, 0x20, 0x1f, 0x03, 0x04, 0x00, 0x23, 0x05, 0x07, 0xd6, 0x10, 0x00, 0x01, 0xd8, 0x10, 0x00, 0x01, 0xda, 0x10, 0x00, 0x01, 0xdc, 0x10, 0x00, 0x01, + 0xde, 0x10, 0x00, 0x01, 0xe0, 0x10, 0x00, 0x01, 0xe2, 0x10, 0x00, 0x01, 0xe4, 0x10, 0x00, 0x01, 0xe6, 0x10, 0x00, 0x01, 0xba, 0x17, 0x01, 0x01, 0xbc, 0x17, 0x01, 0x01, 0xbe, 0x17, 0x01, 0x01, + 0xc0, 0x17, 0x01, 0x01, 0xc2, 0x17, 0x01, 0x01, 0xc4, 0x17, 0x01, 0x01, 0xc6, 0x17, 0x01, 0x01, 0xc8, 0x17, 0x01, 0x01, 0xca, 0x17, 0x01, 0x01, 0x7c, 0x00, 0x02, 0x02, 0x80, 0x00, 0x02, 0x02, + 0x84, 0x00, 0x02, 0x02, 0x88, 0x00, 0x02, 0x02, 0x30, 0x1f, 0x03, 0x04, 0x80, 0x23, 0x05, 0x07, 0xe8, 0x10, 0x00, 0x01, 0xea, 0x10, 0x00, 0x01, 0xec, 0x10, 0x00, 0x01, 0xee, 0x10, 0x00, 0x01, + 0xf0, 0x10, 0x00, 0x01, 0xf2, 0x10, 0x00, 0x01, 0xf4, 0x10, 0x00, 0x01, 0xf6, 0x10, 0x00, 0x01, 0xf8, 0x10, 0x00, 0x01, 0xcc, 0x17, 0x01, 0x01, 0xce, 0x17, 0x01, 0x01, 0xd0, 0x17, 0x01, 0x01, + 0xd2, 0x17, 0x01, 0x01, 0xd4, 0x17, 0x01, 0x01, 0xd6, 0x17, 0x01, 0x01, 0xd8, 0x17, 0x01, 0x01, 0xda, 0x17, 0x01, 0x01, 0xdc, 0x17, 0x01, 0x01, 0x8c, 0x00, 0x02, 0x02, 0x90, 0x00, 0x02, 0x02, + 0x94, 0x00, 0x02, 0x02, 0x98, 0x00, 0x02, 0x02, 0x40, 0x1f, 0x03, 0x04, 0x00, 0x24, 0x05, 0x07, 0xfa, 0x10, 0x00, 0x01, 0xfc, 0x10, 0x00, 0x01, 0xfe, 0x10, 0x00, 0x01, 0x00, 0x11, 0x00, 0x01, + 0x02, 0x11, 0x00, 0x01, 0x04, 0x11, 0x00, 0x01, 0x06, 0x11, 0x00, 0x01, 0x08, 0x11, 0x00, 0x01, 0x0a, 0x11, 0x00, 0x01, 0xde, 0x17, 0x01, 0x01, 0xe0, 0x17, 0x01, 0x01, 0xe2, 0x17, 0x01, 0x01, + 0xe4, 0x17, 0x01, 0x01, 0xe6, 0x17, 0x01, 0x01, 0xe8, 0x17, 0x01, 0x01, 0xea, 0x17, 0x01, 0x01, 0xec, 0x17, 0x01, 0x01, 0xee, 0x17, 0x01, 0x01, 0x9c, 0x00, 0x02, 0x02, 0xa0, 0x00, 0x02, 0x02, + 0xa4, 0x00, 0x02, 0x02, 0xa8, 0x00, 0x02, 0x02, 0x50, 0x1f, 0x03, 0x04, 0x80, 0x24, 0x05, 0x07, 0x0c, 0x11, 0x00, 0x01, 0x0e, 0x11, 0x00, 0x01, 0x10, 0x11, 0x00, 0x01, 0x12, 0x11, 0x00, 0x01, + 0x14, 0x11, 0x00, 0x01, 0x16, 0x11, 0x00, 0x01, 0x18, 0x11, 0x00, 0x01, 0x1a, 0x11, 0x00, 0x01, 0x1c, 0x11, 0x00, 0x01, 0xf0, 0x17, 0x01, 0x01, 0xf2, 0x17, 0x01, 0x01, 0xf4, 0x17, 0x01, 0x01, + 0xf6, 0x17, 0x01, 0x01, 0xf8, 0x17, 0x01, 0x01, 0xfa, 0x17, 0x01, 0x01, 0xfc, 0x17, 0x01, 0x01, 0xfe, 0x17, 0x01, 0x01, 0x00, 0x18, 0x01, 0x01, 0xac, 0x00, 0x02, 0x02, 0xb0, 0x00, 0x02, 0x02, + 0xb4, 0x00, 0x02, 0x02, 0xb8, 0x00, 0x02, 0x02, 0x60, 0x1f, 0x03, 0x04, 0x00, 0x25, 0x05, 0x07, 0x1e, 0x11, 0x00, 0x01, 0x20, 0x11, 0x00, 0x01, 0x22, 0x11, 0x00, 0x01, 0x24, 0x11, 0x00, 0x01, + 0x26, 0x11, 0x00, 0x01, 0x28, 0x11, 0x00, 0x01, 0x2a, 0x11, 0x00, 0x01, 0x2c, 0x11, 0x00, 0x01, 0x02, 0x18, 0x01, 0x01, 0x04, 0x18, 0x01, 0x01, 0x06, 0x18, 0x01, 0x01, 0x08, 0x18, 0x01, 0x01, + 0x0a, 0x18, 0x01, 0x01, 0x0c, 0x18, 0x01, 0x01, 0x0e, 0x18, 0x01, 0x01, 0x10, 0x18, 0x01, 0x01, 0x12, 0x18, 0x01, 0x01, 0x14, 0x18, 0x01, 0x01, 0xbc, 0x00, 0x02, 0x02, 0xc0, 0x00, 0x02, 0x02, + 0xc4, 0x00, 0x02, 0x02, 0xc8, 0x00, 0x02, 0x02, 0x70, 0x1f, 0x03, 0x04, 0x80, 0x25, 0x05, 0x07, 0x2e, 0x11, 0x00, 0x01, 0x30, 0x11, 0x00, 0x01, 0x32, 0x11, 0x00, 0x01, 0x34, 0x11, 0x00, 0x01, + 0x36, 0x11, 0x00, 0x01, 0x38, 0x11, 0x00, 0x01, 0x3a, 0x11, 0x00, 0x01, 0x3c, 0x11, 0x00, 0x01, 0x16, 0x18, 0x01, 0x01, 0x18, 0x18, 0x01, 0x01, 0x1a, 0x18, 0x01, 0x01, 0x1c, 0x18, 0x01, 0x01, + 0x1e, 0x18, 0x01, 0x01, 0x20, 0x18, 0x01, 0x01, 0x22, 0x18, 0x01, 0x01, 0x24, 0x18, 0x01, 0x01, 0x26, 0x18, 0x01, 0x01, 0x28, 0x18, 0x01, 0x01, 0xcc, 0x00, 0x02, 0x02, 0xd0, 0x00, 0x02, 0x02, + 0xd4, 0x00, 0x02, 0x02, 0xd8, 0x00, 0x02, 0x02, 0x80, 0x1f, 0x03, 0x04, 0x00, 0x26, 0x05, 0x07, 0x3e, 0x11, 0x00, 0x01, 0x40, 0x11, 0x00, 0x01, 0x42, 0x11, 0x00, 0x01, 0x44, 0x11, 0x00, 0x01, + 0x46, 0x11, 0x00, 0x01, 0x48, 0x11, 0x00, 0x01, 0x4a, 0x11, 0x00, 0x01, 0x4c, 0x11, 0x00, 0x01, 0x2a, 0x18, 0x01, 0x01, 0x2c, 0x18, 0x01, 0x01, 0x2e, 0x18, 0x01, 0x01, 0x30, 0x18, 0x01, 0x01, + 0x32, 0x18, 0x01, 0x01, 0x34, 0x18, 0x01, 0x01, 0x36, 0x18, 0x01, 0x01, 0x38, 0x18, 0x01, 0x01, 0x3a, 0x18, 0x01, 0x01, 0x3c, 0x18, 0x01, 0x01, 0xdc, 0x00, 0x02, 0x02, 0xe0, 0x00, 0x02, 0x02, + 0xe4, 0x00, 0x02, 0x02, 0xe8, 0x00, 0x02, 0x02, 0x90, 0x1f, 0x03, 0x04, 0x80, 0x26, 0x05, 0x07, 0x4e, 0x11, 0x00, 0x01, 0x50, 0x11, 0x00, 0x01, 0x52, 0x11, 0x00, 0x01, 0x54, 0x11, 0x00, 0x01, + 0x56, 0x11, 0x00, 0x01, 0x58, 0x11, 0x00, 0x01, 0x5a, 0x11, 0x00, 0x01, 0x5c, 0x11, 0x00, 0x01, 0x3e, 0x18, 0x01, 0x01, 0x40, 0x18, 0x01, 0x01, 0x42, 0x18, 0x01, 0x01, 0x44, 0x18, 0x01, 0x01, + 0x46, 0x18, 0x01, 0x01, 0x48, 0x18, 0x01, 0x01, 0x4a, 0x18, 0x01, 0x01, 0x4c, 0x18, 0x01, 0x01, 0x4e, 0x18, 0x01, 0x01, 0x50, 0x18, 0x01, 0x01, 0xec, 0x00, 0x02, 0x02, 0xf0, 0x00, 0x02, 0x02, + 0xf4, 0x00, 0x02, 0x02, 0xf8, 0x00, 0x02, 0x02, 0xa0, 0x1f, 0x03, 0x04, 0x00, 0x27, 0x05, 0x07, 0x5e, 0x11, 0x00, 0x01, 0x60, 0x11, 0x00, 0x01, 0x62, 0x11, 0x00, 0x01, 0x64, 0x11, 0x00, 0x01, + 0x66, 0x11, 0x00, 0x01, 0x68, 0x11, 0x00, 0x01, 0x6a, 0x11, 0x00, 0x01, 0x6c, 0x11, 0x00, 0x01, 0x52, 0x18, 0x01, 0x01, 0x54, 0x18, 0x01, 0x01, 0x56, 0x18, 0x01, 0x01, 0x58, 0x18, 0x01, 0x01, + 0x5a, 0x18, 0x01, 0x01, 0x5c, 0x18, 0x01, 0x01, 0x5e, 0x18, 0x01, 0x01, 0x60, 0x18, 0x01, 0x01, 0x62, 0x18, 0x01, 0x01, 0x64, 0x18, 0x01, 0x01, 0xfc, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, + 0x04, 0x01, 0x02, 0x02, 0x08, 0x01, 0x02, 0x02, 0xb0, 0x1f, 0x03, 0x04, 0x80, 0x27, 0x05, 0x07, 0x6e, 0x11, 0x00, 0x01, 0x70, 0x11, 0x00, 0x01, 0x72, 0x11, 0x00, 0x01, 0x74, 0x11, 0x00, 0x01, + 0x76, 0x11, 0x00, 0x01, 0x78, 0x11, 0x00, 0x01, 0x7a, 0x11, 0x00, 0x01, 0x7c, 0x11, 0x00, 0x01, 0x66, 0x18, 0x01, 0x01, 0x68, 0x18, 0x01, 0x01, 0x6a, 0x18, 0x01, 0x01, 0x6c, 0x18, 0x01, 0x01, + 0x6e, 0x18, 0x01, 0x01, 0x70, 0x18, 0x01, 0x01, 0x72, 0x18, 0x01, 0x01, 0x74, 0x18, 0x01, 0x01, 0x76, 0x18, 0x01, 0x01, 0x78, 0x18, 0x01, 0x01, 0x0c, 0x01, 0x02, 0x02, 0x10, 0x01, 0x02, 0x02, + 0x14, 0x01, 0x02, 0x02, 0x18, 0x01, 0x02, 0x02, 0xc0, 0x1f, 0x03, 0x04, 0x00, 0x28, 0x05, 0x07, 0x7e, 0x11, 0x00, 0x01, 0x80, 0x11, 0x00, 0x01, 0x82, 0x11, 0x00, 0x01, 0x84, 0x11, 0x00, 0x01, + 0x86, 0x11, 0x00, 0x01, 0x88, 0x11, 0x00, 0x01, 0x8a, 0x11, 0x00, 0x01, 0x8c, 0x11, 0x00, 0x01, 0x7a, 0x18, 0x01, 0x01, 0x7c, 0x18, 0x01, 0x01, 0x7e, 0x18, 0x01, 0x01, 0x80, 0x18, 0x01, 0x01, + 0x82, 0x18, 0x01, 0x01, 0x84, 0x18, 0x01, 0x01, 0x86, 0x18, 0x01, 0x01, 0x88, 0x18, 0x01, 0x01, 0x8a, 0x18, 0x01, 0x01, 0x8c, 0x18, 0x01, 0x01, 0x1c, 0x01, 0x02, 0x02, 0x20, 0x01, 0x02, 0x02, + 0x24, 0x01, 0x02, 0x02, 0x28, 0x01, 0x02, 0x02, 0xd0, 0x1f, 0x03, 0x04, 0x00, 0x08, 0x06, 0x08, 0x8e, 0x11, 0x00, 0x01, 0x90, 0x11, 0x00, 0x01, 0x92, 0x11, 0x00, 0x01, 0x94, 0x11, 0x00, 0x01, + 0x96, 0x11, 0x00, 0x01, 0x98, 0x11, 0x00, 0x01, 0x9a, 0x11, 0x00, 0x01, 0x9c, 0x11, 0x00, 0x01, 0x8e, 0x18, 0x01, 0x01, 0x90, 0x18, 0x01, 0x01, 0x92, 0x18, 0x01, 0x01, 0x94, 0x18, 0x01, 0x01, + 0x96, 0x18, 0x01, 0x01, 0x98, 0x18, 0x01, 0x01, 0x9a, 0x18, 0x01, 0x01, 0x9c, 0x18, 0x01, 0x01, 0x9e, 0x18, 0x01, 0x01, 0xa0, 0x18, 0x01, 0x01, 0x2c, 0x01, 0x02, 0x02, 0x30, 0x01, 0x02, 0x02, + 0x34, 0x01, 0x02, 0x02, 0x38, 0x01, 0x02, 0x02, 0xe0, 0x1f, 0x03, 0x04, 0x00, 0x09, 0x06, 0x08, 0x9e, 0x11, 0x00, 0x01, 0xa0, 0x11, 0x00, 0x01, 0xa2, 0x11, 0x00, 0x01, 0xa4, 0x11, 0x00, 0x01, + 0xa6, 0x11, 0x00, 0x01, 0xa8, 0x11, 0x00, 0x01, 0xaa, 0x11, 0x00, 0x01, 0xac, 0x11, 0x00, 0x01, 0xa2, 0x18, 0x01, 0x01, 0xa4, 0x18, 0x01, 0x01, 0xa6, 0x18, 0x01, 0x01, 0xa8, 0x18, 0x01, 0x01, + 0xaa, 0x18, 0x01, 0x01, 0xac, 0x18, 0x01, 0x01, 0xae, 0x18, 0x01, 0x01, 0xb0, 0x18, 0x01, 0x01, 0xb2, 0x18, 0x01, 0x01, 0xb4, 0x18, 0x01, 0x01, 0x3c, 0x01, 0x02, 0x02, 0x40, 0x01, 0x02, 0x02, + 0x44, 0x01, 0x02, 0x02, 0x48, 0x01, 0x02, 0x02, 0xf0, 0x1f, 0x03, 0x04, 0x00, 0x0a, 0x06, 0x08, 0xae, 0x11, 0x00, 0x01, 0xb0, 0x11, 0x00, 0x01, 0xb2, 0x11, 0x00, 0x01, 0xb4, 0x11, 0x00, 0x01, + 0xb6, 0x11, 0x00, 0x01, 0xb8, 0x11, 0x00, 0x01, 0xba, 0x11, 0x00, 0x01, 0xbc, 0x11, 0x00, 0x01, 0xb6, 0x18, 0x01, 0x01, 0xb8, 0x18, 0x01, 0x01, 0xba, 0x18, 0x01, 0x01, 0xbc, 0x18, 0x01, 0x01, + 0xbe, 0x18, 0x01, 0x01, 0xc0, 0x18, 0x01, 0x01, 0xc2, 0x18, 0x01, 0x01, 0xc4, 0x18, 0x01, 0x01, 0xc6, 0x18, 0x01, 0x01, 0xc8, 0x18, 0x01, 0x01, 0x4c, 0x01, 0x02, 0x02, 0x50, 0x01, 0x02, 0x02, + 0x54, 0x01, 0x02, 0x02, 0x58, 0x01, 0x02, 0x02, 0x00, 0x20, 0x03, 0x04, 0x00, 0x0b, 0x06, 0x08, 0xbe, 0x11, 0x00, 0x01, 0xc0, 0x11, 0x00, 0x01, 0xc2, 0x11, 0x00, 0x01, 0xc4, 0x11, 0x00, 0x01, + 0xc6, 0x11, 0x00, 0x01, 0xc8, 0x11, 0x00, 0x01, 0xca, 0x11, 0x00, 0x01, 0xcc, 0x11, 0x00, 0x01, 0xca, 0x18, 0x01, 0x01, 0xcc, 0x18, 0x01, 0x01, 0xce, 0x18, 0x01, 0x01, 0xd0, 0x18, 0x01, 0x01, + 0xd2, 0x18, 0x01, 0x01, 0xd4, 0x18, 0x01, 0x01, 0xd6, 0x18, 0x01, 0x01, 0xd8, 0x18, 0x01, 0x01, 0xda, 0x18, 0x01, 0x01, 0xdc, 0x18, 0x01, 0x01, 0x5c, 0x01, 0x02, 0x02, 0x60, 0x01, 0x02, 0x02, + 0x64, 0x01, 0x02, 0x02, 0x10, 0x20, 0x03, 0x04, 0x20, 0x20, 0x03, 0x04, 0x00, 0x0c, 0x06, 0x08, 0xce, 0x11, 0x00, 0x01, 0xd0, 0x11, 0x00, 0x01, 0xd2, 0x11, 0x00, 0x01, 0xd4, 0x11, 0x00, 0x01, + 0xd6, 0x11, 0x00, 0x01, 0xd8, 0x11, 0x00, 0x01, 0xda, 0x11, 0x00, 0x01, 0xdc, 0x11, 0x00, 0x01, 0xde, 0x18, 0x01, 0x01, 0xe0, 0x18, 0x01, 0x01, 0xe2, 0x18, 0x01, 0x01, 0xe4, 0x18, 0x01, 0x01, + 0xe6, 0x18, 0x01, 0x01, 0xe8, 0x18, 0x01, 0x01, 0xea, 0x18, 0x01, 0x01, 0xec, 0x18, 0x01, 0x01, 0xee, 0x18, 0x01, 0x01, 0xf0, 0x18, 0x01, 0x01, 0x68, 0x01, 0x02, 0x02, 0x6c, 0x01, 0x02, 0x02, + 0x70, 0x01, 0x02, 0x02, 0x30, 0x20, 0x03, 0x04, 0x40, 0x20, 0x03, 0x04, 0x00, 0x2c, 0x07, 0x0a, 0xde, 0x11, 0x00, 0x01, 0xe0, 0x11, 0x00, 0x01, 0xe2, 0x11, 0x00, 0x01, 0xe4, 0x11, 0x00, 0x01, + 0xe6, 0x11, 0x00, 0x01, 0xe8, 0x11, 0x00, 0x01, 0xea, 0x11, 0x00, 0x01, 0xec, 0x11, 0x00, 0x01, 0xf2, 0x18, 0x01, 0x01, 0xf4, 0x18, 0x01, 0x01, 0xf6, 0x18, 0x01, 0x01, 0xf8, 0x18, 0x01, 0x01, + 0xfa, 0x18, 0x01, 0x01, 0xfc, 0x18, 0x01, 0x01, 0xfe, 0x18, 0x01, 0x01, 0x00, 0x19, 0x01, 0x01, 0x02, 0x19, 0x01, 0x01, 0x04, 0x19, 0x01, 0x01, 0x74, 0x01, 0x02, 0x02, 0x78, 0x01, 0x02, 0x02, + 0x7c, 0x01, 0x02, 0x02, 0x50, 0x20, 0x03, 0x04, 0x60, 0x20, 0x03, 0x04, 0x00, 0x30, 0x07, 0x0a, 0xee, 0x11, 0x00, 0x01, 0xf0, 0x11, 0x00, 0x01, 0xf2, 0x11, 0x00, 0x01, 0xf4, 0x11, 0x00, 0x01, + 0xf6, 0x11, 0x00, 0x01, 0xf8, 0x11, 0x00, 0x01, 0xfa, 0x11, 0x00, 0x01, 0xfc, 0x11, 0x00, 0x01, 0x06, 0x19, 0x01, 0x01, 0x08, 0x19, 0x01, 0x01, 0x0a, 0x19, 0x01, 0x01, 0x0c, 0x19, 0x01, 0x01, + 0x0e, 0x19, 0x01, 0x01, 0x10, 0x19, 0x01, 0x01, 0x12, 0x19, 0x01, 0x01, 0x14, 0x19, 0x01, 0x01, 0x16, 0x19, 0x01, 0x01, 0x18, 0x19, 0x01, 0x01, 0x80, 0x01, 0x02, 0x02, 0x84, 0x01, 0x02, 0x02, + 0x88, 0x01, 0x02, 0x02, 0x70, 0x20, 0x03, 0x04, 0x80, 0x20, 0x03, 0x04, 0x00, 0x34, 0x07, 0x0a, 0xfe, 0x11, 0x00, 0x01, 0x00, 0x12, 0x00, 0x01, 0x02, 0x12, 0x00, 0x01, 0x04, 0x12, 0x00, 0x01, + 0x06, 0x12, 0x00, 0x01, 0x08, 0x12, 0x00, 0x01, 0x0a, 0x12, 0x00, 0x01, 0x0c, 0x12, 0x00, 0x01, 0x1a, 0x19, 0x01, 0x01, 0x1c, 0x19, 0x01, 0x01, 0x1e, 0x19, 0x01, 0x01, 0x20, 0x19, 0x01, 0x01, + 0x22, 0x19, 0x01, 0x01, 0x24, 0x19, 0x01, 0x01, 0x26, 0x19, 0x01, 0x01, 0x28, 0x19, 0x01, 0x01, 0x2a, 0x19, 0x01, 0x01, 0x2c, 0x19, 0x01, 0x01, 0x8c, 0x01, 0x02, 0x02, 0x90, 0x01, 0x02, 0x02, + 0x94, 0x01, 0x02, 0x02, 0x90, 0x20, 0x03, 0x04, 0xa0, 0x20, 0x03, 0x04, 0x00, 0x20, 0x09, 0x0d, 0x0e, 0x12, 0x00, 0x01, 0x10, 0x12, 0x00, 0x01, 0x12, 0x12, 0x00, 0x01, 0x14, 0x12, 0x00, 0x01, + 0x16, 0x12, 0x00, 0x01, 0x18, 0x12, 0x00, 0x01, 0x1a, 0x12, 0x00, 0x01, 0x1c, 0x12, 0x00, 0x01, 0x2e, 0x19, 0x01, 0x01, 0x30, 0x19, 0x01, 0x01, 0x32, 0x19, 0x01, 0x01, 0x34, 0x19, 0x01, 0x01, + 0x36, 0x19, 0x01, 0x01, 0x38, 0x19, 0x01, 0x01, 0x3a, 0x19, 0x01, 0x01, 0x3c, 0x19, 0x01, 0x01, 0x3e, 0x19, 0x01, 0x01, 0x40, 0x19, 0x01, 0x01, 0x98, 0x01, 0x02, 0x02, 0x9c, 0x01, 0x02, 0x02, + 0xa0, 0x01, 0x02, 0x02, 0xb0, 0x20, 0x03, 0x04, 0xc0, 0x20, 0x03, 0x04, 0x1e, 0x12, 0x00, 0x01, 0x20, 0x12, 0x00, 0x01, 0x22, 0x12, 0x00, 0x01, 0x24, 0x12, 0x00, 0x01, 0x26, 0x12, 0x00, 0x01, + 0x28, 0x12, 0x00, 0x01, 0x2a, 0x12, 0x00, 0x01, 0x2c, 0x12, 0x00, 0x01, 0x2e, 0x12, 0x00, 0x01, 0x42, 0x19, 0x01, 0x01, 0x44, 0x19, 0x01, 0x01, 0x46, 0x19, 0x01, 0x01, 0x48, 0x19, 0x01, 0x01, + 0x4a, 0x19, 0x01, 0x01, 0x4c, 0x19, 0x01, 0x01, 0x4e, 0x19, 0x01, 0x01, 0x50, 0x19, 0x01, 0x01, 0x52, 0x19, 0x01, 0x01, 0x54, 0x19, 0x01, 0x01, 0xa4, 0x01, 0x02, 0x02, 0xa8, 0x01, 0x02, 0x02, + 0xac, 0x01, 0x02, 0x02, 0xd0, 0x20, 0x03, 0x04, 0xe0, 0x20, 0x03, 0x04, 0x30, 0x12, 0x00, 0x01, 0x32, 0x12, 0x00, 0x01, 0x34, 0x12, 0x00, 0x01, 0x36, 0x12, 0x00, 0x01, 0x38, 0x12, 0x00, 0x01, + 0x3a, 0x12, 0x00, 0x01, 0x3c, 0x12, 0x00, 0x01, 0x3e, 0x12, 0x00, 0x01, 0x40, 0x12, 0x00, 0x01, 0x56, 0x19, 0x01, 0x01, 0x58, 0x19, 0x01, 0x01, 0x5a, 0x19, 0x01, 0x01, 0x5c, 0x19, 0x01, 0x01, + 0x5e, 0x19, 0x01, 0x01, 0x60, 0x19, 0x01, 0x01, 0x62, 0x19, 0x01, 0x01, 0x64, 0x19, 0x01, 0x01, 0x66, 0x19, 0x01, 0x01, 0x68, 0x19, 0x01, 0x01, 0xb0, 0x01, 0x02, 0x02, 0xb4, 0x01, 0x02, 0x02, + 0xb8, 0x01, 0x02, 0x02, 0xf0, 0x20, 0x03, 0x04, 0x00, 0x21, 0x03, 0x04, 0x42, 0x12, 0x00, 0x01, 0x44, 0x12, 0x00, 0x01, 0x46, 0x12, 0x00, 0x01, 0x48, 0x12, 0x00, 0x01, 0x4a, 0x12, 0x00, 0x01, + 0x4c, 0x12, 0x00, 0x01, 0x4e, 0x12, 0x00, 0x01, 0x50, 0x12, 0x00, 0x01, 0x52, 0x12, 0x00, 0x01, 0x6a, 0x19, 0x01, 0x01, 0x6c, 0x19, 0x01, 0x01, 0x6e, 0x19, 0x01, 0x01, 0x70, 0x19, 0x01, 0x01, + 0x72, 0x19, 0x01, 0x01, 0x74, 0x19, 0x01, 0x01, 0x76, 0x19, 0x01, 0x01, 0x78, 0x19, 0x01, 0x01, 0x7a, 0x19, 0x01, 0x01, 0x7c, 0x19, 0x01, 0x01, 0xbc, 0x01, 0x02, 0x02, 0xc0, 0x01, 0x02, 0x02, + 0xc4, 0x01, 0x02, 0x02, 0x10, 0x21, 0x03, 0x04, 0x20, 0x21, 0x03, 0x04, 0x54, 0x12, 0x00, 0x01, 0x56, 0x12, 0x00, 0x01, 0x58, 0x12, 0x00, 0x01, 0x5a, 0x12, 0x00, 0x01, 0x5c, 0x12, 0x00, 0x01, + 0x5e, 0x12, 0x00, 0x01, 0x60, 0x12, 0x00, 0x01, 0x62, 0x12, 0x00, 0x01, 0x64, 0x12, 0x00, 0x01, 0x7e, 0x19, 0x01, 0x01, 0x80, 0x19, 0x01, 0x01, 0x82, 0x19, 0x01, 0x01, 0x84, 0x19, 0x01, 0x01, + 0x86, 0x19, 0x01, 0x01, 0x88, 0x19, 0x01, 0x01, 0x8a, 0x19, 0x01, 0x01, 0x8c, 0x19, 0x01, 0x01, 0x8e, 0x19, 0x01, 0x01, 0x90, 0x19, 0x01, 0x01, 0xc8, 0x01, 0x02, 0x02, 0xcc, 0x01, 0x02, 0x02, + 0xd0, 0x01, 0x02, 0x02, 0x30, 0x21, 0x03, 0x04, 0x40, 0x21, 0x03, 0x04, 0x66, 0x12, 0x00, 0x01, 0x68, 0x12, 0x00, 0x01, 0x6a, 0x12, 0x00, 0x01, 0x6c, 0x12, 0x00, 0x01, 0x6e, 0x12, 0x00, 0x01, + 0x70, 0x12, 0x00, 0x01, 0x72, 0x12, 0x00, 0x01, 0x74, 0x12, 0x00, 0x01, 0x76, 0x12, 0x00, 0x01, 0x92, 0x19, 0x01, 0x01, 0x94, 0x19, 0x01, 0x01, 0x96, 0x19, 0x01, 0x01, 0x98, 0x19, 0x01, 0x01, + 0x9a, 0x19, 0x01, 0x01, 0x9c, 0x19, 0x01, 0x01, 0x9e, 0x19, 0x01, 0x01, 0xa0, 0x19, 0x01, 0x01, 0xa2, 0x19, 0x01, 0x01, 0xa4, 0x19, 0x01, 0x01, 0xd4, 0x01, 0x02, 0x02, 0xd8, 0x01, 0x02, 0x02, + 0xdc, 0x01, 0x02, 0x02, 0x50, 0x21, 0x03, 0x04, 0x60, 0x21, 0x03, 0x04, 0x78, 0x12, 0x00, 0x01, 0x7a, 0x12, 0x00, 0x01, 0x7c, 0x12, 0x00, 0x01, 0x7e, 0x12, 0x00, 0x01, 0x80, 0x12, 0x00, 0x01, + 0x82, 0x12, 0x00, 0x01, 0x84, 0x12, 0x00, 0x01, 0x86, 0x12, 0x00, 0x01, 0x88, 0x12, 0x00, 0x01, 0xa6, 0x19, 0x01, 0x01, 0xa8, 0x19, 0x01, 0x01, 0xaa, 0x19, 0x01, 0x01, 0xac, 0x19, 0x01, 0x01, + 0xae, 0x19, 0x01, 0x01, 0xb0, 0x19, 0x01, 0x01, 0xb2, 0x19, 0x01, 0x01, 0xb4, 0x19, 0x01, 0x01, 0xb6, 0x19, 0x01, 0x01, 0xb8, 0x19, 0x01, 0x01, 0xe0, 0x01, 0x02, 0x02, 0xe4, 0x01, 0x02, 0x02, + 0xe8, 0x01, 0x02, 0x02, 0x70, 0x21, 0x03, 0x04, 0x80, 0x21, 0x03, 0x04, 0x8a, 0x12, 0x00, 0x01, 0x8c, 0x12, 0x00, 0x01, 0x8e, 0x12, 0x00, 0x01, 0x90, 0x12, 0x00, 0x01, 0x92, 0x12, 0x00, 0x01, + 0x94, 0x12, 0x00, 0x01, 0x96, 0x12, 0x00, 0x01, 0x98, 0x12, 0x00, 0x01, 0x9a, 0x12, 0x00, 0x01, 0xba, 0x19, 0x01, 0x01, 0xbc, 0x19, 0x01, 0x01, 0xbe, 0x19, 0x01, 0x01, 0xc0, 0x19, 0x01, 0x01, + 0xc2, 0x19, 0x01, 0x01, 0xc4, 0x19, 0x01, 0x01, 0xc6, 0x19, 0x01, 0x01, 0xc8, 0x19, 0x01, 0x01, 0xca, 0x19, 0x01, 0x01, 0xcc, 0x19, 0x01, 0x01, 0xec, 0x01, 0x02, 0x02, 0xf0, 0x01, 0x02, 0x02, + 0xf4, 0x01, 0x02, 0x02, 0x90, 0x21, 0x03, 0x04, 0xa0, 0x21, 0x03, 0x04, 0x9c, 0x12, 0x00, 0x01, 0x9e, 0x12, 0x00, 0x01, 0xa0, 0x12, 0x00, 0x01, 0xa2, 0x12, 0x00, 0x01, 0xa4, 0x12, 0x00, 0x01, + 0xa6, 0x12, 0x00, 0x01, 0xa8, 0x12, 0x00, 0x01, 0xaa, 0x12, 0x00, 0x01, 0xac, 0x12, 0x00, 0x01, 0xce, 0x19, 0x01, 0x01, 0xd0, 0x19, 0x01, 0x01, 0xd2, 0x19, 0x01, 0x01, 0xd4, 0x19, 0x01, 0x01, + 0xd6, 0x19, 0x01, 0x01, 0xd8, 0x19, 0x01, 0x01, 0xda, 0x19, 0x01, 0x01, 0xdc, 0x19, 0x01, 0x01, 0xde, 0x19, 0x01, 0x01, 0xe0, 0x19, 0x01, 0x01, 0xf8, 0x01, 0x02, 0x02, 0xfc, 0x01, 0x02, 0x02, + 0x00, 0x02, 0x02, 0x02, 0xb0, 0x21, 0x03, 0x04, 0xc0, 0x21, 0x03, 0x04, 0xae, 0x12, 0x00, 0x01, 0xb0, 0x12, 0x00, 0x01, 0xb2, 0x12, 0x00, 0x01, 0xb4, 0x12, 0x00, 0x01, 0xb6, 0x12, 0x00, 0x01, + 0xb8, 0x12, 0x00, 0x01, 0xba, 0x12, 0x00, 0x01, 0xbc, 0x12, 0x00, 0x01, 0xbe, 0x12, 0x00, 0x01, 0xe2, 0x19, 0x01, 0x01, 0xe4, 0x19, 0x01, 0x01, 0xe6, 0x19, 0x01, 0x01, 0xe8, 0x19, 0x01, 0x01, + 0xea, 0x19, 0x01, 0x01, 0xec, 0x19, 0x01, 0x01, 0xee, 0x19, 0x01, 0x01, 0xf0, 0x19, 0x01, 0x01, 0xf2, 0x19, 0x01, 0x01, 0xf4, 0x19, 0x01, 0x01, 0x04, 0x02, 0x02, 0x02, 0x08, 0x02, 0x02, 0x02, + 0x0c, 0x02, 0x02, 0x02, 0xd0, 0x21, 0x03, 0x04, 0xe0, 0x21, 0x03, 0x04, 0xc0, 0x12, 0x00, 0x01, 0xc2, 0x12, 0x00, 0x01, 0xc4, 0x12, 0x00, 0x01, 0xc6, 0x12, 0x00, 0x01, 0xc8, 0x12, 0x00, 0x01, + 0xca, 0x12, 0x00, 0x01, 0xcc, 0x12, 0x00, 0x01, 0xce, 0x12, 0x00, 0x01, 0xd0, 0x12, 0x00, 0x01, 0xf6, 0x19, 0x01, 0x01, 0xf8, 0x19, 0x01, 0x01, 0xfa, 0x19, 0x01, 0x01, 0xfc, 0x19, 0x01, 0x01, + 0xfe, 0x19, 0x01, 0x01, 0x00, 0x1a, 0x01, 0x01, 0x02, 0x1a, 0x01, 0x01, 0x04, 0x1a, 0x01, 0x01, 0x06, 0x1a, 0x01, 0x01, 0x08, 0x1a, 0x01, 0x01, 0x10, 0x02, 0x02, 0x02, 0x14, 0x02, 0x02, 0x02, + 0x18, 0x02, 0x02, 0x02, 0xf0, 0x21, 0x03, 0x04, 0x00, 0x22, 0x03, 0x04, 0xd2, 0x12, 0x00, 0x01, 0xd4, 0x12, 0x00, 0x01, 0xd6, 0x12, 0x00, 0x01, 0xd8, 0x12, 0x00, 0x01, 0xda, 0x12, 0x00, 0x01, + 0xdc, 0x12, 0x00, 0x01, 0xde, 0x12, 0x00, 0x01, 0xe0, 0x12, 0x00, 0x01, 0xe2, 0x12, 0x00, 0x01, 0x0a, 0x1a, 0x01, 0x01, 0x0c, 0x1a, 0x01, 0x01, 0x0e, 0x1a, 0x01, 0x01, 0x10, 0x1a, 0x01, 0x01, + 0x12, 0x1a, 0x01, 0x01, 0x14, 0x1a, 0x01, 0x01, 0x16, 0x1a, 0x01, 0x01, 0x18, 0x1a, 0x01, 0x01, 0x1a, 0x1a, 0x01, 0x01, 0x1c, 0x1a, 0x01, 0x01, 0x1c, 0x02, 0x02, 0x02, 0x20, 0x02, 0x02, 0x02, + 0x24, 0x02, 0x02, 0x02, 0x10, 0x22, 0x03, 0x04, 0x20, 0x22, 0x03, 0x04, 0xe4, 0x12, 0x00, 0x01, 0xe6, 0x12, 0x00, 0x01, 0xe8, 0x12, 0x00, 0x01, 0xea, 0x12, 0x00, 0x01, 0xec, 0x12, 0x00, 0x01, + 0xee, 0x12, 0x00, 0x01, 0xf0, 0x12, 0x00, 0x01, 0xf2, 0x12, 0x00, 0x01, 0xf4, 0x12, 0x00, 0x01, 0x1e, 0x1a, 0x01, 0x01, 0x20, 0x1a, 0x01, 0x01, 0x22, 0x1a, 0x01, 0x01, 0x24, 0x1a, 0x01, 0x01, + 0x26, 0x1a, 0x01, 0x01, 0x28, 0x1a, 0x01, 0x01, 0x2a, 0x1a, 0x01, 0x01, 0x2c, 0x1a, 0x01, 0x01, 0x2e, 0x1a, 0x01, 0x01, 0x30, 0x1a, 0x01, 0x01, 0x28, 0x02, 0x02, 0x02, 0x2c, 0x02, 0x02, 0x02, + 0x30, 0x02, 0x02, 0x02, 0x30, 0x22, 0x03, 0x04, 0x40, 0x22, 0x03, 0x04, 0xf6, 0x12, 0x00, 0x01, 0xf8, 0x12, 0x00, 0x01, 0xfa, 0x12, 0x00, 0x01, 0xfc, 0x12, 0x00, 0x01, 0xfe, 0x12, 0x00, 0x01, + 0x00, 0x13, 0x00, 0x01, 0x02, 0x13, 0x00, 0x01, 0x04, 0x13, 0x00, 0x01, 0x06, 0x13, 0x00, 0x01, 0x32, 0x1a, 0x01, 0x01, 0x34, 0x1a, 0x01, 0x01, 0x36, 0x1a, 0x01, 0x01, 0x38, 0x1a, 0x01, 0x01, + 0x3a, 0x1a, 0x01, 0x01, 0x3c, 0x1a, 0x01, 0x01, 0x3e, 0x1a, 0x01, 0x01, 0x40, 0x1a, 0x01, 0x01, 0x42, 0x1a, 0x01, 0x01, 0x44, 0x1a, 0x01, 0x01, 0x34, 0x02, 0x02, 0x02, 0x38, 0x02, 0x02, 0x02, + 0x3c, 0x02, 0x02, 0x02, 0x50, 0x22, 0x03, 0x04, 0x60, 0x22, 0x03, 0x04, 0x08, 0x13, 0x00, 0x01, 0x0a, 0x13, 0x00, 0x01, 0x0c, 0x13, 0x00, 0x01, 0x0e, 0x13, 0x00, 0x01, 0x10, 0x13, 0x00, 0x01, + 0x12, 0x13, 0x00, 0x01, 0x14, 0x13, 0x00, 0x01, 0x16, 0x13, 0x00, 0x01, 0x18, 0x13, 0x00, 0x01, 0x46, 0x1a, 0x01, 0x01, 0x48, 0x1a, 0x01, 0x01, 0x4a, 0x1a, 0x01, 0x01, 0x4c, 0x1a, 0x01, 0x01, + 0x4e, 0x1a, 0x01, 0x01, 0x50, 0x1a, 0x01, 0x01, 0x52, 0x1a, 0x01, 0x01, 0x54, 0x1a, 0x01, 0x01, 0x56, 0x1a, 0x01, 0x01, 0x58, 0x1a, 0x01, 0x01, 0x40, 0x02, 0x02, 0x02, 0x44, 0x02, 0x02, 0x02, + 0x48, 0x02, 0x02, 0x02, 0x70, 0x22, 0x03, 0x04, 0x80, 0x22, 0x03, 0x04, 0x1a, 0x13, 0x00, 0x01, 0x1c, 0x13, 0x00, 0x01, 0x1e, 0x13, 0x00, 0x01, 0x20, 0x13, 0x00, 0x01, 0x22, 0x13, 0x00, 0x01, + 0x24, 0x13, 0x00, 0x01, 0x26, 0x13, 0x00, 0x01, 0x28, 0x13, 0x00, 0x01, 0x2a, 0x13, 0x00, 0x01, 0x5a, 0x1a, 0x01, 0x01, 0x5c, 0x1a, 0x01, 0x01, 0x5e, 0x1a, 0x01, 0x01, 0x60, 0x1a, 0x01, 0x01, + 0x62, 0x1a, 0x01, 0x01, 0x64, 0x1a, 0x01, 0x01, 0x66, 0x1a, 0x01, 0x01, 0x68, 0x1a, 0x01, 0x01, 0x6a, 0x1a, 0x01, 0x01, 0x6c, 0x1a, 0x01, 0x01, 0x4c, 0x02, 0x02, 0x02, 0x50, 0x02, 0x02, 0x02, + 0x54, 0x02, 0x02, 0x02, 0x90, 0x22, 0x03, 0x04, 0xa0, 0x22, 0x03, 0x04, 0x2c, 0x13, 0x00, 0x01, 0x2e, 0x13, 0x00, 0x01, 0x30, 0x13, 0x00, 0x01, 0x32, 0x13, 0x00, 0x01, 0x34, 0x13, 0x00, 0x01, + 0x36, 0x13, 0x00, 0x01, 0x38, 0x13, 0x00, 0x01, 0x3a, 0x13, 0x00, 0x01, 0x3c, 0x13, 0x00, 0x01, 0x6e, 0x1a, 0x01, 0x01, 0x70, 0x1a, 0x01, 0x01, 0x72, 0x1a, 0x01, 0x01, 0x74, 0x1a, 0x01, 0x01, + 0x76, 0x1a, 0x01, 0x01, 0x78, 0x1a, 0x01, 0x01, 0x7a, 0x1a, 0x01, 0x01, 0x7c, 0x1a, 0x01, 0x01, 0x7e, 0x1a, 0x01, 0x01, 0x80, 0x1a, 0x01, 0x01, 0x58, 0x02, 0x02, 0x02, 0x5c, 0x02, 0x02, 0x02, + 0x60, 0x02, 0x02, 0x02, 0xb0, 0x22, 0x03, 0x04, 0xc0, 0x22, 0x03, 0x04, 0x3e, 0x13, 0x00, 0x01, 0x40, 0x13, 0x00, 0x01, 0x42, 0x13, 0x00, 0x01, 0x44, 0x13, 0x00, 0x01, 0x46, 0x13, 0x00, 0x01, + 0x48, 0x13, 0x00, 0x01, 0x4a, 0x13, 0x00, 0x01, 0x4c, 0x13, 0x00, 0x01, 0x4e, 0x13, 0x00, 0x01, 0x82, 0x1a, 0x01, 0x01, 0x84, 0x1a, 0x01, 0x01, 0x86, 0x1a, 0x01, 0x01, 0x88, 0x1a, 0x01, 0x01, + 0x8a, 0x1a, 0x01, 0x01, 0x8c, 0x1a, 0x01, 0x01, 0x8e, 0x1a, 0x01, 0x01, 0x90, 0x1a, 0x01, 0x01, 0x92, 0x1a, 0x01, 0x01, 0x94, 0x1a, 0x01, 0x01, 0x64, 0x02, 0x02, 0x02, 0x68, 0x02, 0x02, 0x02, + 0x6c, 0x02, 0x02, 0x02, 0xd0, 0x22, 0x03, 0x04, 0xe0, 0x22, 0x03, 0x04, 0x50, 0x13, 0x00, 0x01, 0x52, 0x13, 0x00, 0x01, 0x54, 0x13, 0x00, 0x01, 0x56, 0x13, 0x00, 0x01, 0x58, 0x13, 0x00, 0x01, + 0x5a, 0x13, 0x00, 0x01, 0x5c, 0x13, 0x00, 0x01, 0x5e, 0x13, 0x00, 0x01, 0x60, 0x13, 0x00, 0x01, 0x96, 0x1a, 0x01, 0x01, 0x98, 0x1a, 0x01, 0x01, 0x9a, 0x1a, 0x01, 0x01, 0x9c, 0x1a, 0x01, 0x01, + 0x9e, 0x1a, 0x01, 0x01, 0xa0, 0x1a, 0x01, 0x01, 0xa2, 0x1a, 0x01, 0x01, 0xa4, 0x1a, 0x01, 0x01, 0xa6, 0x1a, 0x01, 0x01, 0xa8, 0x1a, 0x01, 0x01, 0x70, 0x02, 0x02, 0x02, 0x74, 0x02, 0x02, 0x02, + 0x78, 0x02, 0x02, 0x02, 0xf0, 0x22, 0x03, 0x04, 0x00, 0x23, 0x03, 0x04, 0x62, 0x13, 0x00, 0x01, 0x64, 0x13, 0x00, 0x01, 0x66, 0x13, 0x00, 0x01, 0x68, 0x13, 0x00, 0x01, 0x6a, 0x13, 0x00, 0x01, + 0x6c, 0x13, 0x00, 0x01, 0x6e, 0x13, 0x00, 0x01, 0x70, 0x13, 0x00, 0x01, 0x72, 0x13, 0x00, 0x01, 0xaa, 0x1a, 0x01, 0x01, 0xac, 0x1a, 0x01, 0x01, 0xae, 0x1a, 0x01, 0x01, 0xb0, 0x1a, 0x01, 0x01, + 0xb2, 0x1a, 0x01, 0x01, 0xb4, 0x1a, 0x01, 0x01, 0xb6, 0x1a, 0x01, 0x01, 0xb8, 0x1a, 0x01, 0x01, 0xba, 0x1a, 0x01, 0x01, 0xbc, 0x1a, 0x01, 0x01, 0x7c, 0x02, 0x02, 0x02, 0x80, 0x02, 0x02, 0x02, + 0x84, 0x02, 0x02, 0x02, 0x10, 0x23, 0x03, 0x04, 0x20, 0x23, 0x03, 0x04, 0x74, 0x13, 0x00, 0x01, 0x76, 0x13, 0x00, 0x01, 0x78, 0x13, 0x00, 0x01, 0x7a, 0x13, 0x00, 0x01, 0x7c, 0x13, 0x00, 0x01, + 0x7e, 0x13, 0x00, 0x01, 0x80, 0x13, 0x00, 0x01, 0x82, 0x13, 0x00, 0x01, 0x84, 0x13, 0x00, 0x01, 0xbe, 0x1a, 0x01, 0x01, 0xc0, 0x1a, 0x01, 0x01, 0xc2, 0x1a, 0x01, 0x01, 0xc4, 0x1a, 0x01, 0x01, + 0xc6, 0x1a, 0x01, 0x01, 0xc8, 0x1a, 0x01, 0x01, 0xca, 0x1a, 0x01, 0x01, 0xcc, 0x1a, 0x01, 0x01, 0xce, 0x1a, 0x01, 0x01, 0xd0, 0x1a, 0x01, 0x01, 0x88, 0x02, 0x02, 0x02, 0x8c, 0x02, 0x02, 0x02, + 0x90, 0x02, 0x02, 0x02, 0x30, 0x23, 0x03, 0x04, 0x40, 0x23, 0x03, 0x04, 0x86, 0x13, 0x00, 0x01, 0x88, 0x13, 0x00, 0x01, 0x8a, 0x13, 0x00, 0x01, 0x8c, 0x13, 0x00, 0x01, 0x8e, 0x13, 0x00, 0x01, + 0x90, 0x13, 0x00, 0x01, 0x92, 0x13, 0x00, 0x01, 0x94, 0x13, 0x00, 0x01, 0x96, 0x13, 0x00, 0x01, 0xd2, 0x1a, 0x01, 0x01, 0xd4, 0x1a, 0x01, 0x01, 0xd6, 0x1a, 0x01, 0x01, 0xd8, 0x1a, 0x01, 0x01, + 0xda, 0x1a, 0x01, 0x01, 0xdc, 0x1a, 0x01, 0x01, 0xde, 0x1a, 0x01, 0x01, 0xe0, 0x1a, 0x01, 0x01, 0xe2, 0x1a, 0x01, 0x01, 0xe4, 0x1a, 0x01, 0x01, 0x94, 0x02, 0x02, 0x02, 0x98, 0x02, 0x02, 0x02, + 0x9c, 0x02, 0x02, 0x02, 0x50, 0x23, 0x03, 0x04, 0xe0, 0x06, 0x04, 0x05, 0x98, 0x13, 0x00, 0x01, 0x9a, 0x13, 0x00, 0x01, 0x9c, 0x13, 0x00, 0x01, 0x9e, 0x13, 0x00, 0x01, 0xa0, 0x13, 0x00, 0x01, + 0xa2, 0x13, 0x00, 0x01, 0xa4, 0x13, 0x00, 0x01, 0xa6, 0x13, 0x00, 0x01, 0xa8, 0x13, 0x00, 0x01, 0xe6, 0x1a, 0x01, 0x01, 0xe8, 0x1a, 0x01, 0x01, 0xea, 0x1a, 0x01, 0x01, 0xec, 0x1a, 0x01, 0x01, + 0xee, 0x1a, 0x01, 0x01, 0xf0, 0x1a, 0x01, 0x01, 0xf2, 0x1a, 0x01, 0x01, 0xf4, 0x1a, 0x01, 0x01, 0xf6, 0x1a, 0x01, 0x01, 0xf8, 0x1a, 0x01, 0x01, 0xa0, 0x02, 0x02, 0x02, 0xa4, 0x02, 0x02, 0x02, + 0xa8, 0x02, 0x02, 0x02, 0x60, 0x23, 0x03, 0x04, 0x00, 0x07, 0x04, 0x05, 0xaa, 0x13, 0x00, 0x01, 0xac, 0x13, 0x00, 0x01, 0xae, 0x13, 0x00, 0x01, 0xb0, 0x13, 0x00, 0x01, 0xb2, 0x13, 0x00, 0x01, + 0xb4, 0x13, 0x00, 0x01, 0xb6, 0x13, 0x00, 0x01, 0xb8, 0x13, 0x00, 0x01, 0xba, 0x13, 0x00, 0x01, 0xfa, 0x1a, 0x01, 0x01, 0xfc, 0x1a, 0x01, 0x01, 0xfe, 0x1a, 0x01, 0x01, 0x00, 0x1b, 0x01, 0x01, + 0x02, 0x1b, 0x01, 0x01, 0x04, 0x1b, 0x01, 0x01, 0x06, 0x1b, 0x01, 0x01, 0x08, 0x1b, 0x01, 0x01, 0x0a, 0x1b, 0x01, 0x01, 0x0c, 0x1b, 0x01, 0x01, 0xac, 0x02, 0x02, 0x02, 0xb0, 0x02, 0x02, 0x02, + 0xb4, 0x02, 0x02, 0x02, 0x70, 0x23, 0x03, 0x04, 0x20, 0x07, 0x04, 0x05, 0xbc, 0x13, 0x00, 0x01, 0xbe, 0x13, 0x00, 0x01, 0xc0, 0x13, 0x00, 0x01, 0xc2, 0x13, 0x00, 0x01, 0xc4, 0x13, 0x00, 0x01, + 0xc6, 0x13, 0x00, 0x01, 0xc8, 0x13, 0x00, 0x01, 0xca, 0x13, 0x00, 0x01, 0xcc, 0x13, 0x00, 0x01, 0x0e, 0x1b, 0x01, 0x01, 0x10, 0x1b, 0x01, 0x01, 0x12, 0x1b, 0x01, 0x01, 0x14, 0x1b, 0x01, 0x01, + 0x16, 0x1b, 0x01, 0x01, 0x18, 0x1b, 0x01, 0x01, 0x1a, 0x1b, 0x01, 0x01, 0x1c, 0x1b, 0x01, 0x01, 0x1e, 0x1b, 0x01, 0x01, 0x20, 0x1b, 0x01, 0x01, 0xb8, 0x02, 0x02, 0x02, 0xbc, 0x02, 0x02, 0x02, + 0xc0, 0x02, 0x02, 0x02, 0x80, 0x23, 0x03, 0x04, 0x40, 0x07, 0x04, 0x05, 0xce, 0x13, 0x00, 0x01, 0xd0, 0x13, 0x00, 0x01, 0xd2, 0x13, 0x00, 0x01, 0xd4, 0x13, 0x00, 0x01, 0xd6, 0x13, 0x00, 0x01, + 0xd8, 0x13, 0x00, 0x01, 0xda, 0x13, 0x00, 0x01, 0xdc, 0x13, 0x00, 0x01, 0xde, 0x13, 0x00, 0x01, 0x22, 0x1b, 0x01, 0x01, 0x24, 0x1b, 0x01, 0x01, 0x26, 0x1b, 0x01, 0x01, 0x28, 0x1b, 0x01, 0x01, + 0x2a, 0x1b, 0x01, 0x01, 0x2c, 0x1b, 0x01, 0x01, 0x2e, 0x1b, 0x01, 0x01, 0x30, 0x1b, 0x01, 0x01, 0x32, 0x1b, 0x01, 0x01, 0x34, 0x1b, 0x01, 0x01, 0xc4, 0x02, 0x02, 0x02, 0xc8, 0x02, 0x02, 0x02, + 0xcc, 0x02, 0x02, 0x02, 0x90, 0x23, 0x03, 0x04, 0x60, 0x07, 0x04, 0x05, 0xe0, 0x13, 0x00, 0x01, 0xe2, 0x13, 0x00, 0x01, 0xe4, 0x13, 0x00, 0x01, 0xe6, 0x13, 0x00, 0x01, 0xe8, 0x13, 0x00, 0x01, + 0xea, 0x13, 0x00, 0x01, 0xec, 0x13, 0x00, 0x01, 0xee, 0x13, 0x00, 0x01, 0xf0, 0x13, 0x00, 0x01, 0x36, 0x1b, 0x01, 0x01, 0x38, 0x1b, 0x01, 0x01, 0x3a, 0x1b, 0x01, 0x01, 0x3c, 0x1b, 0x01, 0x01, + 0x3e, 0x1b, 0x01, 0x01, 0x40, 0x1b, 0x01, 0x01, 0x42, 0x1b, 0x01, 0x01, 0x44, 0x1b, 0x01, 0x01, 0x46, 0x1b, 0x01, 0x01, 0x48, 0x1b, 0x01, 0x01, 0xd0, 0x02, 0x02, 0x02, 0xd4, 0x02, 0x02, 0x02, + 0xd8, 0x02, 0x02, 0x02, 0xa0, 0x23, 0x03, 0x04, 0x80, 0x07, 0x04, 0x05, 0xf2, 0x13, 0x00, 0x01, 0xf4, 0x13, 0x00, 0x01, 0xf6, 0x13, 0x00, 0x01, 0xf8, 0x13, 0x00, 0x01, 0xfa, 0x13, 0x00, 0x01, + 0xfc, 0x13, 0x00, 0x01, 0xfe, 0x13, 0x00, 0x01, 0x00, 0x14, 0x00, 0x01, 0x02, 0x14, 0x00, 0x01, 0x4a, 0x1b, 0x01, 0x01, 0x4c, 0x1b, 0x01, 0x01, 0x4e, 0x1b, 0x01, 0x01, 0x50, 0x1b, 0x01, 0x01, + 0x52, 0x1b, 0x01, 0x01, 0x54, 0x1b, 0x01, 0x01, 0x56, 0x1b, 0x01, 0x01, 0x58, 0x1b, 0x01, 0x01, 0x5a, 0x1b, 0x01, 0x01, 0x5c, 0x1b, 0x01, 0x01, 0xdc, 0x02, 0x02, 0x02, 0xe0, 0x02, 0x02, 0x02, + 0xe4, 0x02, 0x02, 0x02, 0xb0, 0x23, 0x03, 0x04, 0xa0, 0x07, 0x04, 0x05, 0x04, 0x14, 0x00, 0x01, 0x06, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x0a, 0x14, 0x00, 0x01, 0x0c, 0x14, 0x00, 0x01, + 0x0e, 0x14, 0x00, 0x01, 0x10, 0x14, 0x00, 0x01, 0x12, 0x14, 0x00, 0x01, 0x14, 0x14, 0x00, 0x01, 0x5e, 0x1b, 0x01, 0x01, 0x60, 0x1b, 0x01, 0x01, 0x62, 0x1b, 0x01, 0x01, 0x64, 0x1b, 0x01, 0x01, + 0x66, 0x1b, 0x01, 0x01, 0x68, 0x1b, 0x01, 0x01, 0x6a, 0x1b, 0x01, 0x01, 0x6c, 0x1b, 0x01, 0x01, 0x6e, 0x1b, 0x01, 0x01, 0x70, 0x1b, 0x01, 0x01, 0xe8, 0x02, 0x02, 0x02, 0xec, 0x02, 0x02, 0x02, + 0xf0, 0x02, 0x02, 0x02, 0xc0, 0x23, 0x03, 0x04, 0xc0, 0x07, 0x04, 0x05, 0x16, 0x14, 0x00, 0x01, 0x18, 0x14, 0x00, 0x01, 0x1a, 0x14, 0x00, 0x01, 0x1c, 0x14, 0x00, 0x01, 0x1e, 0x14, 0x00, 0x01, + 0x20, 0x14, 0x00, 0x01, 0x22, 0x14, 0x00, 0x01, 0x24, 0x14, 0x00, 0x01, 0x26, 0x14, 0x00, 0x01, 0x72, 0x1b, 0x01, 0x01, 0x74, 0x1b, 0x01, 0x01, 0x76, 0x1b, 0x01, 0x01, 0x78, 0x1b, 0x01, 0x01, + 0x7a, 0x1b, 0x01, 0x01, 0x7c, 0x1b, 0x01, 0x01, 0x7e, 0x1b, 0x01, 0x01, 0x80, 0x1b, 0x01, 0x01, 0x82, 0x1b, 0x01, 0x01, 0x84, 0x1b, 0x01, 0x01, 0xf4, 0x02, 0x02, 0x02, 0xf8, 0x02, 0x02, 0x02, + 0xfc, 0x02, 0x02, 0x02, 0xd0, 0x23, 0x03, 0x04, 0xe0, 0x07, 0x04, 0x05, 0x28, 0x14, 0x00, 0x01, 0x2a, 0x14, 0x00, 0x01, 0x2c, 0x14, 0x00, 0x01, 0x2e, 0x14, 0x00, 0x01, 0x30, 0x14, 0x00, 0x01, + 0x32, 0x14, 0x00, 0x01, 0x34, 0x14, 0x00, 0x01, 0x36, 0x14, 0x00, 0x01, 0x38, 0x14, 0x00, 0x01, 0x86, 0x1b, 0x01, 0x01, 0x88, 0x1b, 0x01, 0x01, 0x8a, 0x1b, 0x01, 0x01, 0x8c, 0x1b, 0x01, 0x01, + 0x8e, 0x1b, 0x01, 0x01, 0x90, 0x1b, 0x01, 0x01, 0x92, 0x1b, 0x01, 0x01, 0x94, 0x1b, 0x01, 0x01, 0x96, 0x1b, 0x01, 0x01, 0x98, 0x1b, 0x01, 0x01, 0x00, 0x03, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, + 0x08, 0x03, 0x02, 0x02, 0xe0, 0x23, 0x03, 0x04, 0x00, 0x08, 0x04, 0x05, 0x3a, 0x14, 0x00, 0x01, 0x3c, 0x14, 0x00, 0x01, 0x3e, 0x14, 0x00, 0x01, 0x40, 0x14, 0x00, 0x01, 0x42, 0x14, 0x00, 0x01, + 0x44, 0x14, 0x00, 0x01, 0x46, 0x14, 0x00, 0x01, 0x48, 0x14, 0x00, 0x01, 0x4a, 0x14, 0x00, 0x01, 0x9a, 0x1b, 0x01, 0x01, 0x9c, 0x1b, 0x01, 0x01, 0x9e, 0x1b, 0x01, 0x01, 0xa0, 0x1b, 0x01, 0x01, + 0xa2, 0x1b, 0x01, 0x01, 0xa4, 0x1b, 0x01, 0x01, 0xa6, 0x1b, 0x01, 0x01, 0xa8, 0x1b, 0x01, 0x01, 0xaa, 0x1b, 0x01, 0x01, 0xac, 0x1b, 0x01, 0x01, 0x0c, 0x03, 0x02, 0x02, 0x10, 0x03, 0x02, 0x02, + 0x14, 0x03, 0x02, 0x02, 0xf0, 0x23, 0x03, 0x04, 0x20, 0x08, 0x04, 0x05, 0x4c, 0x14, 0x00, 0x01, 0x4e, 0x14, 0x00, 0x01, 0x50, 0x14, 0x00, 0x01, 0x52, 0x14, 0x00, 0x01, 0x54, 0x14, 0x00, 0x01, + 0x56, 0x14, 0x00, 0x01, 0x58, 0x14, 0x00, 0x01, 0x5a, 0x14, 0x00, 0x01, 0x5c, 0x14, 0x00, 0x01, 0xae, 0x1b, 0x01, 0x01, 0xb0, 0x1b, 0x01, 0x01, 0xb2, 0x1b, 0x01, 0x01, 0xb4, 0x1b, 0x01, 0x01, + 0xb6, 0x1b, 0x01, 0x01, 0xb8, 0x1b, 0x01, 0x01, 0xba, 0x1b, 0x01, 0x01, 0xbc, 0x1b, 0x01, 0x01, 0xbe, 0x1b, 0x01, 0x01, 0xc0, 0x1b, 0x01, 0x01, 0x18, 0x03, 0x02, 0x02, 0x1c, 0x03, 0x02, 0x02, + 0x20, 0x03, 0x02, 0x02, 0x00, 0x24, 0x03, 0x04, 0x40, 0x08, 0x04, 0x05, 0x5e, 0x14, 0x00, 0x01, 0x60, 0x14, 0x00, 0x01, 0x62, 0x14, 0x00, 0x01, 0x64, 0x14, 0x00, 0x01, 0x66, 0x14, 0x00, 0x01, + 0x68, 0x14, 0x00, 0x01, 0x6a, 0x14, 0x00, 0x01, 0x6c, 0x14, 0x00, 0x01, 0x6e, 0x14, 0x00, 0x01, 0xc2, 0x1b, 0x01, 0x01, 0xc4, 0x1b, 0x01, 0x01, 0xc6, 0x1b, 0x01, 0x01, 0xc8, 0x1b, 0x01, 0x01, + 0xca, 0x1b, 0x01, 0x01, 0xcc, 0x1b, 0x01, 0x01, 0xce, 0x1b, 0x01, 0x01, 0xd0, 0x1b, 0x01, 0x01, 0xd2, 0x1b, 0x01, 0x01, 0xd4, 0x1b, 0x01, 0x01, 0x24, 0x03, 0x02, 0x02, 0x28, 0x03, 0x02, 0x02, + 0x2c, 0x03, 0x02, 0x02, 0x10, 0x24, 0x03, 0x04, 0x60, 0x08, 0x04, 0x05, 0x70, 0x14, 0x00, 0x01, 0x72, 0x14, 0x00, 0x01, 0x74, 0x14, 0x00, 0x01, 0x76, 0x14, 0x00, 0x01, 0x78, 0x14, 0x00, 0x01, + 0x7a, 0x14, 0x00, 0x01, 0x7c, 0x14, 0x00, 0x01, 0x7e, 0x14, 0x00, 0x01, 0x80, 0x14, 0x00, 0x01, 0xd6, 0x1b, 0x01, 0x01, 0xd8, 0x1b, 0x01, 0x01, 0xda, 0x1b, 0x01, 0x01, 0xdc, 0x1b, 0x01, 0x01, + 0xde, 0x1b, 0x01, 0x01, 0xe0, 0x1b, 0x01, 0x01, 0xe2, 0x1b, 0x01, 0x01, 0xe4, 0x1b, 0x01, 0x01, 0xe6, 0x1b, 0x01, 0x01, 0xe8, 0x1b, 0x01, 0x01, 0x30, 0x03, 0x02, 0x02, 0x34, 0x03, 0x02, 0x02, + 0x38, 0x03, 0x02, 0x02, 0x20, 0x24, 0x03, 0x04, 0x80, 0x08, 0x04, 0x05, 0x82, 0x14, 0x00, 0x01, 0x84, 0x14, 0x00, 0x01, 0x86, 0x14, 0x00, 0x01, 0x88, 0x14, 0x00, 0x01, 0x8a, 0x14, 0x00, 0x01, + 0x8c, 0x14, 0x00, 0x01, 0x8e, 0x14, 0x00, 0x01, 0x90, 0x14, 0x00, 0x01, 0x92, 0x14, 0x00, 0x01, 0xea, 0x1b, 0x01, 0x01, 0xec, 0x1b, 0x01, 0x01, 0xee, 0x1b, 0x01, 0x01, 0xf0, 0x1b, 0x01, 0x01, + 0xf2, 0x1b, 0x01, 0x01, 0xf4, 0x1b, 0x01, 0x01, 0xf6, 0x1b, 0x01, 0x01, 0xf8, 0x1b, 0x01, 0x01, 0xfa, 0x1b, 0x01, 0x01, 0x3c, 0x03, 0x02, 0x02, 0x40, 0x03, 0x02, 0x02, 0x44, 0x03, 0x02, 0x02, + 0x48, 0x03, 0x02, 0x02, 0x30, 0x24, 0x03, 0x04, 0xa0, 0x08, 0x04, 0x05, 0x94, 0x14, 0x00, 0x01, 0x96, 0x14, 0x00, 0x01, 0x98, 0x14, 0x00, 0x01, 0x9a, 0x14, 0x00, 0x01, 0x9c, 0x14, 0x00, 0x01, + 0x9e, 0x14, 0x00, 0x01, 0xa0, 0x14, 0x00, 0x01, 0xa2, 0x14, 0x00, 0x01, 0xa4, 0x14, 0x00, 0x01, 0xfc, 0x1b, 0x01, 0x01, 0xfe, 0x1b, 0x01, 0x01, 0x00, 0x1c, 0x01, 0x01, 0x02, 0x1c, 0x01, 0x01, + 0x04, 0x1c, 0x01, 0x01, 0x06, 0x1c, 0x01, 0x01, 0x08, 0x1c, 0x01, 0x01, 0x0a, 0x1c, 0x01, 0x01, 0x0c, 0x1c, 0x01, 0x01, 0x4c, 0x03, 0x02, 0x02, 0x50, 0x03, 0x02, 0x02, 0x54, 0x03, 0x02, 0x02, + 0x58, 0x03, 0x02, 0x02, 0x40, 0x24, 0x03, 0x04, 0xc0, 0x08, 0x04, 0x05, 0xa6, 0x14, 0x00, 0x01, 0xa8, 0x14, 0x00, 0x01, 0xaa, 0x14, 0x00, 0x01, 0xac, 0x14, 0x00, 0x01, 0xae, 0x14, 0x00, 0x01, + 0xb0, 0x14, 0x00, 0x01, 0xb2, 0x14, 0x00, 0x01, 0xb4, 0x14, 0x00, 0x01, 0xb6, 0x14, 0x00, 0x01, 0x0e, 0x1c, 0x01, 0x01, 0x10, 0x1c, 0x01, 0x01, 0x12, 0x1c, 0x01, 0x01, 0x14, 0x1c, 0x01, 0x01, + 0x16, 0x1c, 0x01, 0x01, 0x18, 0x1c, 0x01, 0x01, 0x1a, 0x1c, 0x01, 0x01, 0x1c, 0x1c, 0x01, 0x01, 0x1e, 0x1c, 0x01, 0x01, 0x5c, 0x03, 0x02, 0x02, 0x60, 0x03, 0x02, 0x02, 0x64, 0x03, 0x02, 0x02, + 0x68, 0x03, 0x02, 0x02, 0x50, 0x24, 0x03, 0x04, 0xe0, 0x08, 0x04, 0x05, 0xb8, 0x14, 0x00, 0x01, 0xba, 0x14, 0x00, 0x01, 0xbc, 0x14, 0x00, 0x01, 0xbe, 0x14, 0x00, 0x01, 0xc0, 0x14, 0x00, 0x01, + 0xc2, 0x14, 0x00, 0x01, 0xc4, 0x14, 0x00, 0x01, 0xc6, 0x14, 0x00, 0x01, 0xc8, 0x14, 0x00, 0x01, 0x20, 0x1c, 0x01, 0x01, 0x22, 0x1c, 0x01, 0x01, 0x24, 0x1c, 0x01, 0x01, 0x26, 0x1c, 0x01, 0x01, + 0x28, 0x1c, 0x01, 0x01, 0x2a, 0x1c, 0x01, 0x01, 0x2c, 0x1c, 0x01, 0x01, 0x2e, 0x1c, 0x01, 0x01, 0x30, 0x1c, 0x01, 0x01, 0x6c, 0x03, 0x02, 0x02, 0x70, 0x03, 0x02, 0x02, 0x74, 0x03, 0x02, 0x02, + 0x78, 0x03, 0x02, 0x02, 0x60, 0x24, 0x03, 0x04, 0x00, 0x09, 0x04, 0x05, 0xca, 0x14, 0x00, 0x01, 0xcc, 0x14, 0x00, 0x01, 0xce, 0x14, 0x00, 0x01, 0xd0, 0x14, 0x00, 0x01, 0xd2, 0x14, 0x00, 0x01, + 0xd4, 0x14, 0x00, 0x01, 0xd6, 0x14, 0x00, 0x01, 0xd8, 0x14, 0x00, 0x01, 0xda, 0x14, 0x00, 0x01, 0x32, 0x1c, 0x01, 0x01, 0x34, 0x1c, 0x01, 0x01, 0x36, 0x1c, 0x01, 0x01, 0x38, 0x1c, 0x01, 0x01, + 0x3a, 0x1c, 0x01, 0x01, 0x3c, 0x1c, 0x01, 0x01, 0x3e, 0x1c, 0x01, 0x01, 0x40, 0x1c, 0x01, 0x01, 0x42, 0x1c, 0x01, 0x01, 0x7c, 0x03, 0x02, 0x02, 0x80, 0x03, 0x02, 0x02, 0x84, 0x03, 0x02, 0x02, + 0x88, 0x03, 0x02, 0x02, 0x70, 0x24, 0x03, 0x04, 0x20, 0x09, 0x04, 0x05, 0xdc, 0x14, 0x00, 0x01, 0xde, 0x14, 0x00, 0x01, 0xe0, 0x14, 0x00, 0x01, 0xe2, 0x14, 0x00, 0x01, 0xe4, 0x14, 0x00, 0x01, + 0xe6, 0x14, 0x00, 0x01, 0xe8, 0x14, 0x00, 0x01, 0xea, 0x14, 0x00, 0x01, 0xec, 0x14, 0x00, 0x01, 0x44, 0x1c, 0x01, 0x01, 0x46, 0x1c, 0x01, 0x01, 0x48, 0x1c, 0x01, 0x01, 0x4a, 0x1c, 0x01, 0x01, + 0x4c, 0x1c, 0x01, 0x01, 0x4e, 0x1c, 0x01, 0x01, 0x50, 0x1c, 0x01, 0x01, 0x52, 0x1c, 0x01, 0x01, 0x54, 0x1c, 0x01, 0x01, 0x8c, 0x03, 0x02, 0x02, 0x90, 0x03, 0x02, 0x02, 0x94, 0x03, 0x02, 0x02, + 0x98, 0x03, 0x02, 0x02, 0x80, 0x24, 0x03, 0x04, 0x40, 0x09, 0x04, 0x05, 0xee, 0x14, 0x00, 0x01, 0xf0, 0x14, 0x00, 0x01, 0xf2, 0x14, 0x00, 0x01, 0xf4, 0x14, 0x00, 0x01, 0xf6, 0x14, 0x00, 0x01, + 0xf8, 0x14, 0x00, 0x01, 0xfa, 0x14, 0x00, 0x01, 0xfc, 0x14, 0x00, 0x01, 0xfe, 0x14, 0x00, 0x01, 0x56, 0x1c, 0x01, 0x01, 0x58, 0x1c, 0x01, 0x01, 0x5a, 0x1c, 0x01, 0x01, 0x5c, 0x1c, 0x01, 0x01, + 0x5e, 0x1c, 0x01, 0x01, 0x60, 0x1c, 0x01, 0x01, 0x62, 0x1c, 0x01, 0x01, 0x64, 0x1c, 0x01, 0x01, 0x66, 0x1c, 0x01, 0x01, 0x9c, 0x03, 0x02, 0x02, 0xa0, 0x03, 0x02, 0x02, 0xa4, 0x03, 0x02, 0x02, + 0xa8, 0x03, 0x02, 0x02, 0x90, 0x24, 0x03, 0x04, 0x60, 0x09, 0x04, 0x05, 0x00, 0x15, 0x00, 0x01, 0x02, 0x15, 0x00, 0x01, 0x04, 0x15, 0x00, 0x01, 0x06, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, + 0x0a, 0x15, 0x00, 0x01, 0x0c, 0x15, 0x00, 0x01, 0x0e, 0x15, 0x00, 0x01, 0x10, 0x15, 0x00, 0x01, 0x68, 0x1c, 0x01, 0x01, 0x6a, 0x1c, 0x01, 0x01, 0x6c, 0x1c, 0x01, 0x01, 0x6e, 0x1c, 0x01, 0x01, + 0x70, 0x1c, 0x01, 0x01, 0x72, 0x1c, 0x01, 0x01, 0x74, 0x1c, 0x01, 0x01, 0x76, 0x1c, 0x01, 0x01, 0x78, 0x1c, 0x01, 0x01, 0xac, 0x03, 0x02, 0x02, 0xb0, 0x03, 0x02, 0x02, 0xb4, 0x03, 0x02, 0x02, + 0xb8, 0x03, 0x02, 0x02, 0xa0, 0x24, 0x03, 0x04, 0x80, 0x09, 0x04, 0x05, 0x12, 0x15, 0x00, 0x01, 0x14, 0x15, 0x00, 0x01, 0x16, 0x15, 0x00, 0x01, 0x18, 0x15, 0x00, 0x01, 0x1a, 0x15, 0x00, 0x01, + 0x1c, 0x15, 0x00, 0x01, 0x1e, 0x15, 0x00, 0x01, 0x20, 0x15, 0x00, 0x01, 0x22, 0x15, 0x00, 0x01, 0x7a, 0x1c, 0x01, 0x01, 0x7c, 0x1c, 0x01, 0x01, 0x7e, 0x1c, 0x01, 0x01, 0x80, 0x1c, 0x01, 0x01, + 0x82, 0x1c, 0x01, 0x01, 0x84, 0x1c, 0x01, 0x01, 0x86, 0x1c, 0x01, 0x01, 0x88, 0x1c, 0x01, 0x01, 0x8a, 0x1c, 0x01, 0x01, 0xbc, 0x03, 0x02, 0x02, 0xc0, 0x03, 0x02, 0x02, 0xc4, 0x03, 0x02, 0x02, + 0xc8, 0x03, 0x02, 0x02, 0xb0, 0x24, 0x03, 0x04, 0xa0, 0x09, 0x04, 0x05, 0x24, 0x15, 0x00, 0x01, 0x26, 0x15, 0x00, 0x01, 0x28, 0x15, 0x00, 0x01, 0x2a, 0x15, 0x00, 0x01, 0x2c, 0x15, 0x00, 0x01, + 0x2e, 0x15, 0x00, 0x01, 0x30, 0x15, 0x00, 0x01, 0x32, 0x15, 0x00, 0x01, 0x34, 0x15, 0x00, 0x01, 0x8c, 0x1c, 0x01, 0x01, 0x8e, 0x1c, 0x01, 0x01, 0x90, 0x1c, 0x01, 0x01, 0x92, 0x1c, 0x01, 0x01, + 0x94, 0x1c, 0x01, 0x01, 0x96, 0x1c, 0x01, 0x01, 0x98, 0x1c, 0x01, 0x01, 0x9a, 0x1c, 0x01, 0x01, 0x9c, 0x1c, 0x01, 0x01, 0xcc, 0x03, 0x02, 0x02, 0xd0, 0x03, 0x02, 0x02, 0xd4, 0x03, 0x02, 0x02, + 0xd8, 0x03, 0x02, 0x02, 0xc0, 0x24, 0x03, 0x04, 0xc0, 0x09, 0x04, 0x05, 0x36, 0x15, 0x00, 0x01, 0x38, 0x15, 0x00, 0x01, 0x3a, 0x15, 0x00, 0x01, 0x3c, 0x15, 0x00, 0x01, 0x3e, 0x15, 0x00, 0x01, + 0x40, 0x15, 0x00, 0x01, 0x42, 0x15, 0x00, 0x01, 0x44, 0x15, 0x00, 0x01, 0x46, 0x15, 0x00, 0x01, 0x9e, 0x1c, 0x01, 0x01, 0xa0, 0x1c, 0x01, 0x01, 0xa2, 0x1c, 0x01, 0x01, 0xa4, 0x1c, 0x01, 0x01, + 0xa6, 0x1c, 0x01, 0x01, 0xa8, 0x1c, 0x01, 0x01, 0xaa, 0x1c, 0x01, 0x01, 0xac, 0x1c, 0x01, 0x01, 0xae, 0x1c, 0x01, 0x01, 0xdc, 0x03, 0x02, 0x02, 0xe0, 0x03, 0x02, 0x02, 0xe4, 0x03, 0x02, 0x02, + 0xe8, 0x03, 0x02, 0x02, 0xd0, 0x24, 0x03, 0x04, 0xe0, 0x09, 0x04, 0x05, 0x48, 0x15, 0x00, 0x01, 0x4a, 0x15, 0x00, 0x01, 0x4c, 0x15, 0x00, 0x01, 0x4e, 0x15, 0x00, 0x01, 0x50, 0x15, 0x00, 0x01, + 0x52, 0x15, 0x00, 0x01, 0x54, 0x15, 0x00, 0x01, 0x56, 0x15, 0x00, 0x01, 0x58, 0x15, 0x00, 0x01, 0xb0, 0x1c, 0x01, 0x01, 0xb2, 0x1c, 0x01, 0x01, 0xb4, 0x1c, 0x01, 0x01, 0xb6, 0x1c, 0x01, 0x01, + 0xb8, 0x1c, 0x01, 0x01, 0xba, 0x1c, 0x01, 0x01, 0xbc, 0x1c, 0x01, 0x01, 0xbe, 0x1c, 0x01, 0x01, 0xc0, 0x1c, 0x01, 0x01, 0xec, 0x03, 0x02, 0x02, 0xf0, 0x03, 0x02, 0x02, 0xf4, 0x03, 0x02, 0x02, + 0xf8, 0x03, 0x02, 0x02, 0xe0, 0x24, 0x03, 0x04, 0x00, 0x0a, 0x04, 0x05, 0x5a, 0x15, 0x00, 0x01, 0x5c, 0x15, 0x00, 0x01, 0x5e, 0x15, 0x00, 0x01, 0x60, 0x15, 0x00, 0x01, 0x62, 0x15, 0x00, 0x01, + 0x64, 0x15, 0x00, 0x01, 0x66, 0x15, 0x00, 0x01, 0x68, 0x15, 0x00, 0x01, 0x6a, 0x15, 0x00, 0x01, 0xc2, 0x1c, 0x01, 0x01, 0xc4, 0x1c, 0x01, 0x01, 0xc6, 0x1c, 0x01, 0x01, 0xc8, 0x1c, 0x01, 0x01, + 0xca, 0x1c, 0x01, 0x01, 0xcc, 0x1c, 0x01, 0x01, 0xce, 0x1c, 0x01, 0x01, 0xd0, 0x1c, 0x01, 0x01, 0xd2, 0x1c, 0x01, 0x01, 0xfc, 0x03, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, + 0x08, 0x04, 0x02, 0x02, 0xf0, 0x24, 0x03, 0x04, 0x20, 0x0a, 0x04, 0x05, 0x6c, 0x15, 0x00, 0x01, 0x6e, 0x15, 0x00, 0x01, 0x70, 0x15, 0x00, 0x01, 0x72, 0x15, 0x00, 0x01, 0x74, 0x15, 0x00, 0x01, + 0x76, 0x15, 0x00, 0x01, 0x78, 0x15, 0x00, 0x01, 0x7a, 0x15, 0x00, 0x01, 0x7c, 0x15, 0x00, 0x01, 0xd4, 0x1c, 0x01, 0x01, 0xd6, 0x1c, 0x01, 0x01, 0xd8, 0x1c, 0x01, 0x01, 0xda, 0x1c, 0x01, 0x01, + 0xdc, 0x1c, 0x01, 0x01, 0xde, 0x1c, 0x01, 0x01, 0xe0, 0x1c, 0x01, 0x01, 0xe2, 0x1c, 0x01, 0x01, 0xe4, 0x1c, 0x01, 0x01, 0x0c, 0x04, 0x02, 0x02, 0x10, 0x04, 0x02, 0x02, 0x14, 0x04, 0x02, 0x02, + 0x18, 0x04, 0x02, 0x02, 0x00, 0x25, 0x03, 0x04, 0x40, 0x0a, 0x04, 0x05, 0x7e, 0x15, 0x00, 0x01, 0x80, 0x15, 0x00, 0x01, 0x82, 0x15, 0x00, 0x01, 0x84, 0x15, 0x00, 0x01, 0x86, 0x15, 0x00, 0x01, + 0x88, 0x15, 0x00, 0x01, 0x8a, 0x15, 0x00, 0x01, 0x8c, 0x15, 0x00, 0x01, 0x8e, 0x15, 0x00, 0x01, 0xe6, 0x1c, 0x01, 0x01, 0xe8, 0x1c, 0x01, 0x01, 0xea, 0x1c, 0x01, 0x01, 0xec, 0x1c, 0x01, 0x01, + 0xee, 0x1c, 0x01, 0x01, 0xf0, 0x1c, 0x01, 0x01, 0xf2, 0x1c, 0x01, 0x01, 0xf4, 0x1c, 0x01, 0x01, 0xf6, 0x1c, 0x01, 0x01, 0x1c, 0x04, 0x02, 0x02, 0x20, 0x04, 0x02, 0x02, 0x24, 0x04, 0x02, 0x02, + 0x28, 0x04, 0x02, 0x02, 0x10, 0x25, 0x03, 0x04, 0x60, 0x0a, 0x04, 0x05, 0x90, 0x15, 0x00, 0x01, 0x92, 0x15, 0x00, 0x01, 0x94, 0x15, 0x00, 0x01, 0x96, 0x15, 0x00, 0x01, 0x98, 0x15, 0x00, 0x01, + 0x9a, 0x15, 0x00, 0x01, 0x9c, 0x15, 0x00, 0x01, 0x9e, 0x15, 0x00, 0x01, 0xa0, 0x15, 0x00, 0x01, 0xf8, 0x1c, 0x01, 0x01, 0xfa, 0x1c, 0x01, 0x01, 0xfc, 0x1c, 0x01, 0x01, 0xfe, 0x1c, 0x01, 0x01, + 0x00, 0x1d, 0x01, 0x01, 0x02, 0x1d, 0x01, 0x01, 0x04, 0x1d, 0x01, 0x01, 0x06, 0x1d, 0x01, 0x01, 0x08, 0x1d, 0x01, 0x01, 0x2c, 0x04, 0x02, 0x02, 0x30, 0x04, 0x02, 0x02, 0x34, 0x04, 0x02, 0x02, + 0x38, 0x04, 0x02, 0x02, 0x20, 0x25, 0x03, 0x04, 0x80, 0x0a, 0x04, 0x05, 0xa2, 0x15, 0x00, 0x01, 0xa4, 0x15, 0x00, 0x01, 0xa6, 0x15, 0x00, 0x01, 0xa8, 0x15, 0x00, 0x01, 0xaa, 0x15, 0x00, 0x01, + 0xac, 0x15, 0x00, 0x01, 0xae, 0x15, 0x00, 0x01, 0xb0, 0x15, 0x00, 0x01, 0xb2, 0x15, 0x00, 0x01, 0x0a, 0x1d, 0x01, 0x01, 0x0c, 0x1d, 0x01, 0x01, 0x0e, 0x1d, 0x01, 0x01, 0x10, 0x1d, 0x01, 0x01, + 0x12, 0x1d, 0x01, 0x01, 0x14, 0x1d, 0x01, 0x01, 0x16, 0x1d, 0x01, 0x01, 0x18, 0x1d, 0x01, 0x01, 0x1a, 0x1d, 0x01, 0x01, 0x3c, 0x04, 0x02, 0x02, 0x40, 0x04, 0x02, 0x02, 0x44, 0x04, 0x02, 0x02, + 0x48, 0x04, 0x02, 0x02, 0x30, 0x25, 0x03, 0x04, 0xa0, 0x0a, 0x04, 0x05, 0xb4, 0x15, 0x00, 0x01, 0xb6, 0x15, 0x00, 0x01, 0xb8, 0x15, 0x00, 0x01, 0xba, 0x15, 0x00, 0x01, 0xbc, 0x15, 0x00, 0x01, + 0xbe, 0x15, 0x00, 0x01, 0xc0, 0x15, 0x00, 0x01, 0xc2, 0x15, 0x00, 0x01, 0xc4, 0x15, 0x00, 0x01, 0x1c, 0x1d, 0x01, 0x01, 0x1e, 0x1d, 0x01, 0x01, 0x20, 0x1d, 0x01, 0x01, 0x22, 0x1d, 0x01, 0x01, + 0x24, 0x1d, 0x01, 0x01, 0x26, 0x1d, 0x01, 0x01, 0x28, 0x1d, 0x01, 0x01, 0x2a, 0x1d, 0x01, 0x01, 0x2c, 0x1d, 0x01, 0x01, 0x4c, 0x04, 0x02, 0x02, 0x50, 0x04, 0x02, 0x02, 0x54, 0x04, 0x02, 0x02, + 0x58, 0x04, 0x02, 0x02, 0x40, 0x25, 0x03, 0x04, 0xc0, 0x0a, 0x04, 0x05, 0xc6, 0x15, 0x00, 0x01, 0xc8, 0x15, 0x00, 0x01, 0xca, 0x15, 0x00, 0x01, 0xcc, 0x15, 0x00, 0x01, 0xce, 0x15, 0x00, 0x01, + 0xd0, 0x15, 0x00, 0x01, 0xd2, 0x15, 0x00, 0x01, 0xd4, 0x15, 0x00, 0x01, 0xd6, 0x15, 0x00, 0x01, 0x2e, 0x1d, 0x01, 0x01, 0x30, 0x1d, 0x01, 0x01, 0x32, 0x1d, 0x01, 0x01, 0x34, 0x1d, 0x01, 0x01, + 0x36, 0x1d, 0x01, 0x01, 0x38, 0x1d, 0x01, 0x01, 0x3a, 0x1d, 0x01, 0x01, 0x3c, 0x1d, 0x01, 0x01, 0x3e, 0x1d, 0x01, 0x01, 0x5c, 0x04, 0x02, 0x02, 0x60, 0x04, 0x02, 0x02, 0x64, 0x04, 0x02, 0x02, + 0x68, 0x04, 0x02, 0x02, 0x50, 0x25, 0x03, 0x04, 0xe0, 0x0a, 0x04, 0x05, 0xd8, 0x15, 0x00, 0x01, 0xda, 0x15, 0x00, 0x01, 0xdc, 0x15, 0x00, 0x01, 0xde, 0x15, 0x00, 0x01, 0xe0, 0x15, 0x00, 0x01, + 0xe2, 0x15, 0x00, 0x01, 0xe4, 0x15, 0x00, 0x01, 0xe6, 0x15, 0x00, 0x01, 0xe8, 0x15, 0x00, 0x01, 0x40, 0x1d, 0x01, 0x01, 0x42, 0x1d, 0x01, 0x01, 0x44, 0x1d, 0x01, 0x01, 0x46, 0x1d, 0x01, 0x01, + 0x48, 0x1d, 0x01, 0x01, 0x4a, 0x1d, 0x01, 0x01, 0x4c, 0x1d, 0x01, 0x01, 0x4e, 0x1d, 0x01, 0x01, 0x50, 0x1d, 0x01, 0x01, 0x6c, 0x04, 0x02, 0x02, 0x70, 0x04, 0x02, 0x02, 0x74, 0x04, 0x02, 0x02, + 0x78, 0x04, 0x02, 0x02, 0x60, 0x25, 0x03, 0x04, 0x00, 0x0b, 0x04, 0x05, 0xea, 0x15, 0x00, 0x01, 0xec, 0x15, 0x00, 0x01, 0xee, 0x15, 0x00, 0x01, 0xf0, 0x15, 0x00, 0x01, 0xf2, 0x15, 0x00, 0x01, + 0xf4, 0x15, 0x00, 0x01, 0xf6, 0x15, 0x00, 0x01, 0xf8, 0x15, 0x00, 0x01, 0xfa, 0x15, 0x00, 0x01, 0x52, 0x1d, 0x01, 0x01, 0x54, 0x1d, 0x01, 0x01, 0x56, 0x1d, 0x01, 0x01, 0x58, 0x1d, 0x01, 0x01, + 0x5a, 0x1d, 0x01, 0x01, 0x5c, 0x1d, 0x01, 0x01, 0x5e, 0x1d, 0x01, 0x01, 0x60, 0x1d, 0x01, 0x01, 0x62, 0x1d, 0x01, 0x01, 0x7c, 0x04, 0x02, 0x02, 0x80, 0x04, 0x02, 0x02, 0x84, 0x04, 0x02, 0x02, + 0x88, 0x04, 0x02, 0x02, 0x70, 0x25, 0x03, 0x04, 0x20, 0x0b, 0x04, 0x05, 0xfc, 0x15, 0x00, 0x01, 0xfe, 0x15, 0x00, 0x01, 0x00, 0x16, 0x00, 0x01, 0x02, 0x16, 0x00, 0x01, 0x04, 0x16, 0x00, 0x01, + 0x06, 0x16, 0x00, 0x01, 0x08, 0x16, 0x00, 0x01, 0x0a, 0x16, 0x00, 0x01, 0x0c, 0x16, 0x00, 0x01, 0x64, 0x1d, 0x01, 0x01, 0x66, 0x1d, 0x01, 0x01, 0x68, 0x1d, 0x01, 0x01, 0x6a, 0x1d, 0x01, 0x01, + 0x6c, 0x1d, 0x01, 0x01, 0x6e, 0x1d, 0x01, 0x01, 0x70, 0x1d, 0x01, 0x01, 0x72, 0x1d, 0x01, 0x01, 0x74, 0x1d, 0x01, 0x01, 0x8c, 0x04, 0x02, 0x02, 0x90, 0x04, 0x02, 0x02, 0x94, 0x04, 0x02, 0x02, + 0x98, 0x04, 0x02, 0x02, 0x80, 0x25, 0x03, 0x04, 0x40, 0x0b, 0x04, 0x05, 0x0e, 0x16, 0x00, 0x01, 0x10, 0x16, 0x00, 0x01, 0x12, 0x16, 0x00, 0x01, 0x14, 0x16, 0x00, 0x01, 0x16, 0x16, 0x00, 0x01, + 0x18, 0x16, 0x00, 0x01, 0x1a, 0x16, 0x00, 0x01, 0x1c, 0x16, 0x00, 0x01, 0x1e, 0x16, 0x00, 0x01, 0x76, 0x1d, 0x01, 0x01, 0x78, 0x1d, 0x01, 0x01, 0x7a, 0x1d, 0x01, 0x01, 0x7c, 0x1d, 0x01, 0x01, + 0x7e, 0x1d, 0x01, 0x01, 0x80, 0x1d, 0x01, 0x01, 0x82, 0x1d, 0x01, 0x01, 0x84, 0x1d, 0x01, 0x01, 0x86, 0x1d, 0x01, 0x01, 0x9c, 0x04, 0x02, 0x02, 0xa0, 0x04, 0x02, 0x02, 0xa4, 0x04, 0x02, 0x02, + 0xa8, 0x04, 0x02, 0x02, 0x90, 0x25, 0x03, 0x04, 0x60, 0x0b, 0x04, 0x05, 0x20, 0x16, 0x00, 0x01, 0x22, 0x16, 0x00, 0x01, 0x24, 0x16, 0x00, 0x01, 0x26, 0x16, 0x00, 0x01, 0x28, 0x16, 0x00, 0x01, + 0x2a, 0x16, 0x00, 0x01, 0x2c, 0x16, 0x00, 0x01, 0x2e, 0x16, 0x00, 0x01, 0x30, 0x16, 0x00, 0x01, 0x88, 0x1d, 0x01, 0x01, 0x8a, 0x1d, 0x01, 0x01, 0x8c, 0x1d, 0x01, 0x01, 0x8e, 0x1d, 0x01, 0x01, + 0x90, 0x1d, 0x01, 0x01, 0x92, 0x1d, 0x01, 0x01, 0x94, 0x1d, 0x01, 0x01, 0x96, 0x1d, 0x01, 0x01, 0x98, 0x1d, 0x01, 0x01, 0xac, 0x04, 0x02, 0x02, 0xb0, 0x04, 0x02, 0x02, 0xb4, 0x04, 0x02, 0x02, + 0xb8, 0x04, 0x02, 0x02, 0xa0, 0x25, 0x03, 0x04, 0x80, 0x0b, 0x04, 0x05, 0x32, 0x16, 0x00, 0x01, 0x34, 0x16, 0x00, 0x01, 0x36, 0x16, 0x00, 0x01, 0x38, 0x16, 0x00, 0x01, 0x3a, 0x16, 0x00, 0x01, + 0x3c, 0x16, 0x00, 0x01, 0x3e, 0x16, 0x00, 0x01, 0x40, 0x16, 0x00, 0x01, 0x42, 0x16, 0x00, 0x01, 0x9a, 0x1d, 0x01, 0x01, 0x9c, 0x1d, 0x01, 0x01, 0x9e, 0x1d, 0x01, 0x01, 0xa0, 0x1d, 0x01, 0x01, + 0xa2, 0x1d, 0x01, 0x01, 0xa4, 0x1d, 0x01, 0x01, 0xa6, 0x1d, 0x01, 0x01, 0xa8, 0x1d, 0x01, 0x01, 0xaa, 0x1d, 0x01, 0x01, 0xbc, 0x04, 0x02, 0x02, 0xc0, 0x04, 0x02, 0x02, 0xc4, 0x04, 0x02, 0x02, + 0xc8, 0x04, 0x02, 0x02, 0xb0, 0x25, 0x03, 0x04, 0xa0, 0x0b, 0x04, 0x05, 0x44, 0x16, 0x00, 0x01, 0x46, 0x16, 0x00, 0x01, 0x48, 0x16, 0x00, 0x01, 0x4a, 0x16, 0x00, 0x01, 0x4c, 0x16, 0x00, 0x01, + 0x4e, 0x16, 0x00, 0x01, 0x50, 0x16, 0x00, 0x01, 0x52, 0x16, 0x00, 0x01, 0x54, 0x16, 0x00, 0x01, 0xac, 0x1d, 0x01, 0x01, 0xae, 0x1d, 0x01, 0x01, 0xb0, 0x1d, 0x01, 0x01, 0xb2, 0x1d, 0x01, 0x01, + 0xb4, 0x1d, 0x01, 0x01, 0xb6, 0x1d, 0x01, 0x01, 0xb8, 0x1d, 0x01, 0x01, 0xba, 0x1d, 0x01, 0x01, 0xbc, 0x1d, 0x01, 0x01, 0xcc, 0x04, 0x02, 0x02, 0xd0, 0x04, 0x02, 0x02, 0xd4, 0x04, 0x02, 0x02, + 0xd8, 0x04, 0x02, 0x02, 0xc0, 0x25, 0x03, 0x04, 0xc0, 0x0b, 0x04, 0x05, 0x56, 0x16, 0x00, 0x01, 0x58, 0x16, 0x00, 0x01, 0x5a, 0x16, 0x00, 0x01, 0x5c, 0x16, 0x00, 0x01, 0x5e, 0x16, 0x00, 0x01, + 0x60, 0x16, 0x00, 0x01, 0x62, 0x16, 0x00, 0x01, 0x64, 0x16, 0x00, 0x01, 0x66, 0x16, 0x00, 0x01, 0xbe, 0x1d, 0x01, 0x01, 0xc0, 0x1d, 0x01, 0x01, 0xc2, 0x1d, 0x01, 0x01, 0xc4, 0x1d, 0x01, 0x01, + 0xc6, 0x1d, 0x01, 0x01, 0xc8, 0x1d, 0x01, 0x01, 0xca, 0x1d, 0x01, 0x01, 0xcc, 0x1d, 0x01, 0x01, 0xce, 0x1d, 0x01, 0x01, 0xdc, 0x04, 0x02, 0x02, 0xe0, 0x04, 0x02, 0x02, 0xe4, 0x04, 0x02, 0x02, + 0xe8, 0x04, 0x02, 0x02, 0xd0, 0x25, 0x03, 0x04, 0x80, 0x28, 0x05, 0x07, 0x68, 0x16, 0x00, 0x01, 0x6a, 0x16, 0x00, 0x01, 0x6c, 0x16, 0x00, 0x01, 0x6e, 0x16, 0x00, 0x01, 0x70, 0x16, 0x00, 0x01, + 0x72, 0x16, 0x00, 0x01, 0x74, 0x16, 0x00, 0x01, 0x76, 0x16, 0x00, 0x01, 0x78, 0x16, 0x00, 0x01, 0xd0, 0x1d, 0x01, 0x01, 0xd2, 0x1d, 0x01, 0x01, 0xd4, 0x1d, 0x01, 0x01, 0xd6, 0x1d, 0x01, 0x01, + 0xd8, 0x1d, 0x01, 0x01, 0xda, 0x1d, 0x01, 0x01, 0xdc, 0x1d, 0x01, 0x01, 0xde, 0x1d, 0x01, 0x01, 0xe0, 0x1d, 0x01, 0x01, 0xec, 0x04, 0x02, 0x02, 0xf0, 0x04, 0x02, 0x02, 0xf4, 0x04, 0x02, 0x02, + 0xf8, 0x04, 0x02, 0x02, 0xe0, 0x25, 0x03, 0x04, 0x00, 0x29, 0x05, 0x07, 0x7a, 0x16, 0x00, 0x01, 0x7c, 0x16, 0x00, 0x01, 0x7e, 0x16, 0x00, 0x01, 0x80, 0x16, 0x00, 0x01, 0x82, 0x16, 0x00, 0x01, + 0x84, 0x16, 0x00, 0x01, 0x86, 0x16, 0x00, 0x01, 0x88, 0x16, 0x00, 0x01, 0x8a, 0x16, 0x00, 0x01, 0xe2, 0x1d, 0x01, 0x01, 0xe4, 0x1d, 0x01, 0x01, 0xe6, 0x1d, 0x01, 0x01, 0xe8, 0x1d, 0x01, 0x01, + 0xea, 0x1d, 0x01, 0x01, 0xec, 0x1d, 0x01, 0x01, 0xee, 0x1d, 0x01, 0x01, 0xf0, 0x1d, 0x01, 0x01, 0xf2, 0x1d, 0x01, 0x01, 0xfc, 0x04, 0x02, 0x02, 0x00, 0x05, 0x02, 0x02, 0x04, 0x05, 0x02, 0x02, + 0x08, 0x05, 0x02, 0x02, 0xf0, 0x25, 0x03, 0x04, 0x80, 0x29, 0x05, 0x07, 0x8c, 0x16, 0x00, 0x01, 0x8e, 0x16, 0x00, 0x01, 0x90, 0x16, 0x00, 0x01, 0x92, 0x16, 0x00, 0x01, 0x94, 0x16, 0x00, 0x01, + 0x96, 0x16, 0x00, 0x01, 0x98, 0x16, 0x00, 0x01, 0x9a, 0x16, 0x00, 0x01, 0x9c, 0x16, 0x00, 0x01, 0xf4, 0x1d, 0x01, 0x01, 0xf6, 0x1d, 0x01, 0x01, 0xf8, 0x1d, 0x01, 0x01, 0xfa, 0x1d, 0x01, 0x01, + 0xfc, 0x1d, 0x01, 0x01, 0xfe, 0x1d, 0x01, 0x01, 0x00, 0x1e, 0x01, 0x01, 0x02, 0x1e, 0x01, 0x01, 0x04, 0x1e, 0x01, 0x01, 0x0c, 0x05, 0x02, 0x02, 0x10, 0x05, 0x02, 0x02, 0x14, 0x05, 0x02, 0x02, + 0x18, 0x05, 0x02, 0x02, 0x00, 0x26, 0x03, 0x04, 0x00, 0x2a, 0x05, 0x07, 0x9e, 0x16, 0x00, 0x01, 0xa0, 0x16, 0x00, 0x01, 0xa2, 0x16, 0x00, 0x01, 0xa4, 0x16, 0x00, 0x01, 0xa6, 0x16, 0x00, 0x01, + 0xa8, 0x16, 0x00, 0x01, 0xaa, 0x16, 0x00, 0x01, 0xac, 0x16, 0x00, 0x01, 0xae, 0x16, 0x00, 0x01, 0x06, 0x1e, 0x01, 0x01, 0x08, 0x1e, 0x01, 0x01, 0x0a, 0x1e, 0x01, 0x01, 0x0c, 0x1e, 0x01, 0x01, + 0x0e, 0x1e, 0x01, 0x01, 0x10, 0x1e, 0x01, 0x01, 0x12, 0x1e, 0x01, 0x01, 0x14, 0x1e, 0x01, 0x01, 0x16, 0x1e, 0x01, 0x01, 0x1c, 0x05, 0x02, 0x02, 0x20, 0x05, 0x02, 0x02, 0x24, 0x05, 0x02, 0x02, + 0x28, 0x05, 0x02, 0x02, 0x10, 0x26, 0x03, 0x04, 0x80, 0x2a, 0x05, 0x07, 0xb0, 0x16, 0x00, 0x01, 0xb2, 0x16, 0x00, 0x01, 0xb4, 0x16, 0x00, 0x01, 0xb6, 0x16, 0x00, 0x01, 0xb8, 0x16, 0x00, 0x01, + 0xba, 0x16, 0x00, 0x01, 0xbc, 0x16, 0x00, 0x01, 0xbe, 0x16, 0x00, 0x01, 0xc0, 0x16, 0x00, 0x01, 0x18, 0x1e, 0x01, 0x01, 0x1a, 0x1e, 0x01, 0x01, 0x1c, 0x1e, 0x01, 0x01, 0x1e, 0x1e, 0x01, 0x01, + 0x20, 0x1e, 0x01, 0x01, 0x22, 0x1e, 0x01, 0x01, 0x24, 0x1e, 0x01, 0x01, 0x26, 0x1e, 0x01, 0x01, 0x28, 0x1e, 0x01, 0x01, 0x2c, 0x05, 0x02, 0x02, 0x30, 0x05, 0x02, 0x02, 0x34, 0x05, 0x02, 0x02, + 0x38, 0x05, 0x02, 0x02, 0x20, 0x26, 0x03, 0x04, 0x00, 0x2b, 0x05, 0x07, 0xc2, 0x16, 0x00, 0x01, 0xc4, 0x16, 0x00, 0x01, 0xc6, 0x16, 0x00, 0x01, 0xc8, 0x16, 0x00, 0x01, 0xca, 0x16, 0x00, 0x01, + 0xcc, 0x16, 0x00, 0x01, 0xce, 0x16, 0x00, 0x01, 0xd0, 0x16, 0x00, 0x01, 0xd2, 0x16, 0x00, 0x01, 0x2a, 0x1e, 0x01, 0x01, 0x2c, 0x1e, 0x01, 0x01, 0x2e, 0x1e, 0x01, 0x01, 0x30, 0x1e, 0x01, 0x01, + 0x32, 0x1e, 0x01, 0x01, 0x34, 0x1e, 0x01, 0x01, 0x36, 0x1e, 0x01, 0x01, 0x38, 0x1e, 0x01, 0x01, 0x3a, 0x1e, 0x01, 0x01, 0x3c, 0x05, 0x02, 0x02, 0x40, 0x05, 0x02, 0x02, 0x44, 0x05, 0x02, 0x02, + 0x48, 0x05, 0x02, 0x02, 0x30, 0x26, 0x03, 0x04, 0x80, 0x2b, 0x05, 0x07, 0xd4, 0x16, 0x00, 0x01, 0xd6, 0x16, 0x00, 0x01, 0xd8, 0x16, 0x00, 0x01, 0xda, 0x16, 0x00, 0x01, 0xdc, 0x16, 0x00, 0x01, + 0xde, 0x16, 0x00, 0x01, 0xe0, 0x16, 0x00, 0x01, 0xe2, 0x16, 0x00, 0x01, 0xe4, 0x16, 0x00, 0x01, 0x3c, 0x1e, 0x01, 0x01, 0x3e, 0x1e, 0x01, 0x01, 0x40, 0x1e, 0x01, 0x01, 0x42, 0x1e, 0x01, 0x01, + 0x44, 0x1e, 0x01, 0x01, 0x46, 0x1e, 0x01, 0x01, 0x48, 0x1e, 0x01, 0x01, 0x4a, 0x1e, 0x01, 0x01, 0x4c, 0x1e, 0x01, 0x01, 0x4c, 0x05, 0x02, 0x02, 0x50, 0x05, 0x02, 0x02, 0x54, 0x05, 0x02, 0x02, + 0x58, 0x05, 0x02, 0x02, 0x40, 0x26, 0x03, 0x04, 0x00, 0x2c, 0x05, 0x07, 0xe6, 0x16, 0x00, 0x01, 0xe8, 0x16, 0x00, 0x01, 0xea, 0x16, 0x00, 0x01, 0xec, 0x16, 0x00, 0x01, 0xee, 0x16, 0x00, 0x01, + 0xf0, 0x16, 0x00, 0x01, 0xf2, 0x16, 0x00, 0x01, 0xf4, 0x16, 0x00, 0x01, 0xf6, 0x16, 0x00, 0x01, 0x4e, 0x1e, 0x01, 0x01, 0x50, 0x1e, 0x01, 0x01, 0x52, 0x1e, 0x01, 0x01, 0x54, 0x1e, 0x01, 0x01, + 0x56, 0x1e, 0x01, 0x01, 0x58, 0x1e, 0x01, 0x01, 0x5a, 0x1e, 0x01, 0x01, 0x5c, 0x1e, 0x01, 0x01, 0x5e, 0x1e, 0x01, 0x01, 0x5c, 0x05, 0x02, 0x02, 0x60, 0x05, 0x02, 0x02, 0x64, 0x05, 0x02, 0x02, + 0x68, 0x05, 0x02, 0x02, 0x50, 0x26, 0x03, 0x04, 0x80, 0x2c, 0x05, 0x07, 0xf8, 0x16, 0x00, 0x01, 0xfa, 0x16, 0x00, 0x01, 0xfc, 0x16, 0x00, 0x01, 0xfe, 0x16, 0x00, 0x01, 0x00, 0x17, 0x00, 0x01, + 0x02, 0x17, 0x00, 0x01, 0x04, 0x17, 0x00, 0x01, 0x06, 0x17, 0x00, 0x01, 0x60, 0x1e, 0x01, 0x01, 0x62, 0x1e, 0x01, 0x01, 0x64, 0x1e, 0x01, 0x01, 0x66, 0x1e, 0x01, 0x01, 0x68, 0x1e, 0x01, 0x01, + 0x6a, 0x1e, 0x01, 0x01, 0x6c, 0x1e, 0x01, 0x01, 0x6e, 0x1e, 0x01, 0x01, 0x70, 0x1e, 0x01, 0x01, 0x72, 0x1e, 0x01, 0x01, 0x6c, 0x05, 0x02, 0x02, 0x70, 0x05, 0x02, 0x02, 0x74, 0x05, 0x02, 0x02, + 0x78, 0x05, 0x02, 0x02, 0x60, 0x26, 0x03, 0x04, 0x00, 0x2d, 0x05, 0x07, 0x08, 0x17, 0x00, 0x01, 0x0a, 0x17, 0x00, 0x01, 0x0c, 0x17, 0x00, 0x01, 0x0e, 0x17, 0x00, 0x01, 0x10, 0x17, 0x00, 0x01, + 0x12, 0x17, 0x00, 0x01, 0x14, 0x17, 0x00, 0x01, 0x16, 0x17, 0x00, 0x01, 0x74, 0x1e, 0x01, 0x01, 0x76, 0x1e, 0x01, 0x01, 0x78, 0x1e, 0x01, 0x01, 0x7a, 0x1e, 0x01, 0x01, 0x7c, 0x1e, 0x01, 0x01, + 0x7e, 0x1e, 0x01, 0x01, 0x80, 0x1e, 0x01, 0x01, 0x82, 0x1e, 0x01, 0x01, 0x84, 0x1e, 0x01, 0x01, 0x86, 0x1e, 0x01, 0x01, 0x7c, 0x05, 0x02, 0x02, 0x80, 0x05, 0x02, 0x02, 0x84, 0x05, 0x02, 0x02, + 0x88, 0x05, 0x02, 0x02, 0x70, 0x26, 0x03, 0x04, 0x80, 0x2d, 0x05, 0x07, 0x18, 0x17, 0x00, 0x01, 0x1a, 0x17, 0x00, 0x01, 0x1c, 0x17, 0x00, 0x01, 0x1e, 0x17, 0x00, 0x01, 0x20, 0x17, 0x00, 0x01, + 0x22, 0x17, 0x00, 0x01, 0x24, 0x17, 0x00, 0x01, 0x26, 0x17, 0x00, 0x01, 0x88, 0x1e, 0x01, 0x01, 0x8a, 0x1e, 0x01, 0x01, 0x8c, 0x1e, 0x01, 0x01, 0x8e, 0x1e, 0x01, 0x01, 0x90, 0x1e, 0x01, 0x01, + 0x92, 0x1e, 0x01, 0x01, 0x94, 0x1e, 0x01, 0x01, 0x96, 0x1e, 0x01, 0x01, 0x98, 0x1e, 0x01, 0x01, 0x9a, 0x1e, 0x01, 0x01, 0x8c, 0x05, 0x02, 0x02, 0x90, 0x05, 0x02, 0x02, 0x94, 0x05, 0x02, 0x02, + 0x98, 0x05, 0x02, 0x02, 0x80, 0x26, 0x03, 0x04, 0x00, 0x2e, 0x05, 0x07, 0x28, 0x17, 0x00, 0x01, 0x2a, 0x17, 0x00, 0x01, 0x2c, 0x17, 0x00, 0x01, 0x2e, 0x17, 0x00, 0x01, 0x30, 0x17, 0x00, 0x01, + 0x32, 0x17, 0x00, 0x01, 0x34, 0x17, 0x00, 0x01, 0x36, 0x17, 0x00, 0x01, 0x9c, 0x1e, 0x01, 0x01, 0x9e, 0x1e, 0x01, 0x01, 0xa0, 0x1e, 0x01, 0x01, 0xa2, 0x1e, 0x01, 0x01, 0xa4, 0x1e, 0x01, 0x01, + 0xa6, 0x1e, 0x01, 0x01, 0xa8, 0x1e, 0x01, 0x01, 0xaa, 0x1e, 0x01, 0x01, 0xac, 0x1e, 0x01, 0x01, 0xae, 0x1e, 0x01, 0x01, 0x9c, 0x05, 0x02, 0x02, 0xa0, 0x05, 0x02, 0x02, 0xa4, 0x05, 0x02, 0x02, + 0xa8, 0x05, 0x02, 0x02, 0x90, 0x26, 0x03, 0x04, 0x80, 0x2e, 0x05, 0x07, 0x38, 0x17, 0x00, 0x01, 0x3a, 0x17, 0x00, 0x01, 0x3c, 0x17, 0x00, 0x01, 0x3e, 0x17, 0x00, 0x01, 0x40, 0x17, 0x00, 0x01, + 0x42, 0x17, 0x00, 0x01, 0x44, 0x17, 0x00, 0x01, 0x46, 0x17, 0x00, 0x01, 0xb0, 0x1e, 0x01, 0x01, 0xb2, 0x1e, 0x01, 0x01, 0xb4, 0x1e, 0x01, 0x01, 0xb6, 0x1e, 0x01, 0x01, 0xb8, 0x1e, 0x01, 0x01, + 0xba, 0x1e, 0x01, 0x01, 0xbc, 0x1e, 0x01, 0x01, 0xbe, 0x1e, 0x01, 0x01, 0xc0, 0x1e, 0x01, 0x01, 0xc2, 0x1e, 0x01, 0x01, 0xac, 0x05, 0x02, 0x02, 0xb0, 0x05, 0x02, 0x02, 0xb4, 0x05, 0x02, 0x02, + 0xb8, 0x05, 0x02, 0x02, 0xa0, 0x26, 0x03, 0x04, 0x00, 0x2f, 0x05, 0x07, 0x48, 0x17, 0x00, 0x01, 0x4a, 0x17, 0x00, 0x01, 0x4c, 0x17, 0x00, 0x01, 0x4e, 0x17, 0x00, 0x01, 0x50, 0x17, 0x00, 0x01, + 0x52, 0x17, 0x00, 0x01, 0x54, 0x17, 0x00, 0x01, 0x56, 0x17, 0x00, 0x01, 0xc4, 0x1e, 0x01, 0x01, 0xc6, 0x1e, 0x01, 0x01, 0xc8, 0x1e, 0x01, 0x01, 0xca, 0x1e, 0x01, 0x01, 0xcc, 0x1e, 0x01, 0x01, + 0xce, 0x1e, 0x01, 0x01, 0xd0, 0x1e, 0x01, 0x01, 0xd2, 0x1e, 0x01, 0x01, 0xd4, 0x1e, 0x01, 0x01, 0xd6, 0x1e, 0x01, 0x01, 0xbc, 0x05, 0x02, 0x02, 0xc0, 0x05, 0x02, 0x02, 0xc4, 0x05, 0x02, 0x02, + 0xc8, 0x05, 0x02, 0x02, 0xb0, 0x26, 0x03, 0x04, 0x80, 0x2f, 0x05, 0x07, 0x58, 0x17, 0x00, 0x01, 0x5a, 0x17, 0x00, 0x01, 0x5c, 0x17, 0x00, 0x01, 0x5e, 0x17, 0x00, 0x01, 0x60, 0x17, 0x00, 0x01, + 0x62, 0x17, 0x00, 0x01, 0x64, 0x17, 0x00, 0x01, 0x66, 0x17, 0x00, 0x01, 0xd8, 0x1e, 0x01, 0x01, 0xda, 0x1e, 0x01, 0x01, 0xdc, 0x1e, 0x01, 0x01, 0xde, 0x1e, 0x01, 0x01, 0xe0, 0x1e, 0x01, 0x01, + 0xe2, 0x1e, 0x01, 0x01, 0xe4, 0x1e, 0x01, 0x01, 0xe6, 0x1e, 0x01, 0x01, 0xe8, 0x1e, 0x01, 0x01, 0xea, 0x1e, 0x01, 0x01, 0xcc, 0x05, 0x02, 0x02, 0xd0, 0x05, 0x02, 0x02, 0xd4, 0x05, 0x02, 0x02, + 0xd8, 0x05, 0x02, 0x02, 0xc0, 0x26, 0x03, 0x04, 0x00, 0x0d, 0x06, 0x08, 0x68, 0x17, 0x00, 0x01, 0x6a, 0x17, 0x00, 0x01, 0x6c, 0x17, 0x00, 0x01, 0x6e, 0x17, 0x00, 0x01, 0x70, 0x17, 0x00, 0x01, + 0x72, 0x17, 0x00, 0x01, 0x74, 0x17, 0x00, 0x01, 0x76, 0x17, 0x00, 0x01, 0xec, 0x1e, 0x01, 0x01, 0xee, 0x1e, 0x01, 0x01, 0xf0, 0x1e, 0x01, 0x01, 0xf2, 0x1e, 0x01, 0x01, 0xf4, 0x1e, 0x01, 0x01, + 0xf6, 0x1e, 0x01, 0x01, 0xf8, 0x1e, 0x01, 0x01, 0xfa, 0x1e, 0x01, 0x01, 0xfc, 0x1e, 0x01, 0x01, 0xfe, 0x1e, 0x01, 0x01, 0xdc, 0x05, 0x02, 0x02, 0xe0, 0x05, 0x02, 0x02, 0xe4, 0x05, 0x02, 0x02, + 0xe8, 0x05, 0x02, 0x02, 0xd0, 0x26, 0x03, 0x04, 0x00, 0x0e, 0x06, 0x08, 0x78, 0x17, 0x00, 0x01, 0x7a, 0x17, 0x00, 0x01, 0x7c, 0x17, 0x00, 0x01, 0x7e, 0x17, 0x00, 0x01, 0x80, 0x17, 0x00, 0x01, + 0x82, 0x17, 0x00, 0x01, 0x84, 0x17, 0x00, 0x01, 0x86, 0x17, 0x00, 0x01, 0x00, 0x1f, 0x01, 0x01, 0x02, 0x1f, 0x01, 0x01, 0x04, 0x1f, 0x01, 0x01, 0x06, 0x1f, 0x01, 0x01, 0x08, 0x1f, 0x01, 0x01, + 0x0a, 0x1f, 0x01, 0x01, 0x0c, 0x1f, 0x01, 0x01, 0x0e, 0x1f, 0x01, 0x01, 0x10, 0x1f, 0x01, 0x01, 0x12, 0x1f, 0x01, 0x01, 0xec, 0x05, 0x02, 0x02, 0xf0, 0x05, 0x02, 0x02, 0xf4, 0x05, 0x02, 0x02, + 0xf8, 0x05, 0x02, 0x02, 0xe0, 0x26, 0x03, 0x04, 0x00, 0x0f, 0x06, 0x08, 0x88, 0x17, 0x00, 0x01, 0x8a, 0x17, 0x00, 0x01, 0x8c, 0x17, 0x00, 0x01, 0x8e, 0x17, 0x00, 0x01, 0x90, 0x17, 0x00, 0x01, + 0x92, 0x17, 0x00, 0x01, 0x94, 0x17, 0x00, 0x01, 0x96, 0x17, 0x00, 0x01, 0x14, 0x1f, 0x01, 0x01, 0x16, 0x1f, 0x01, 0x01, 0x18, 0x1f, 0x01, 0x01, 0x1a, 0x1f, 0x01, 0x01, 0x1c, 0x1f, 0x01, 0x01, + 0x1e, 0x1f, 0x01, 0x01, 0x20, 0x1f, 0x01, 0x01, 0x22, 0x1f, 0x01, 0x01, 0x24, 0x1f, 0x01, 0x01, 0x26, 0x1f, 0x01, 0x01, 0xfc, 0x05, 0x02, 0x02, 0x00, 0x06, 0x02, 0x02, 0x04, 0x06, 0x02, 0x02, + 0x08, 0x06, 0x02, 0x02, 0xf0, 0x26, 0x03, 0x04, 0x00, 0x10, 0x06, 0x08, 0x98, 0x17, 0x00, 0x01, 0x9a, 0x17, 0x00, 0x01, 0x9c, 0x17, 0x00, 0x01, 0x9e, 0x17, 0x00, 0x01, 0xa0, 0x17, 0x00, 0x01, + 0xa2, 0x17, 0x00, 0x01, 0xa4, 0x17, 0x00, 0x01, 0xa6, 0x17, 0x00, 0x01, 0x28, 0x1f, 0x01, 0x01, 0x2a, 0x1f, 0x01, 0x01, 0x2c, 0x1f, 0x01, 0x01, 0x2e, 0x1f, 0x01, 0x01, 0x30, 0x1f, 0x01, 0x01, + 0x32, 0x1f, 0x01, 0x01, 0x34, 0x1f, 0x01, 0x01, 0x36, 0x1f, 0x01, 0x01, 0x38, 0x1f, 0x01, 0x01, 0x3a, 0x1f, 0x01, 0x01, 0x0c, 0x06, 0x02, 0x02, 0x10, 0x06, 0x02, 0x02, 0x14, 0x06, 0x02, 0x02, + 0x00, 0x27, 0x03, 0x04, 0x10, 0x27, 0x03, 0x04, 0x00, 0x11, 0x06, 0x08, 0xa8, 0x17, 0x00, 0x01, 0xaa, 0x17, 0x00, 0x01, 0xac, 0x17, 0x00, 0x01, 0xae, 0x17, 0x00, 0x01, 0xb0, 0x17, 0x00, 0x01, + 0xb2, 0x17, 0x00, 0x01, 0xb4, 0x17, 0x00, 0x01, 0xb6, 0x17, 0x00, 0x01, 0x3c, 0x1f, 0x01, 0x01, 0x3e, 0x1f, 0x01, 0x01, 0x40, 0x1f, 0x01, 0x01, 0x42, 0x1f, 0x01, 0x01, 0x44, 0x1f, 0x01, 0x01, + 0x46, 0x1f, 0x01, 0x01, 0x48, 0x1f, 0x01, 0x01, 0x4a, 0x1f, 0x01, 0x01, 0x4c, 0x1f, 0x01, 0x01, 0x4e, 0x1f, 0x01, 0x01, 0x18, 0x06, 0x02, 0x02, 0x1c, 0x06, 0x02, 0x02, 0x20, 0x06, 0x02, 0x02, + 0x20, 0x27, 0x03, 0x04, 0x30, 0x27, 0x03, 0x04, 0x00, 0x12, 0x06, 0x08, 0xb8, 0x17, 0x00, 0x01, 0xba, 0x17, 0x00, 0x01, 0xbc, 0x17, 0x00, 0x01, 0xbe, 0x17, 0x00, 0x01, 0xc0, 0x17, 0x00, 0x01, + 0xc2, 0x17, 0x00, 0x01, 0xc4, 0x17, 0x00, 0x01, 0xc6, 0x17, 0x00, 0x01, 0x50, 0x1f, 0x01, 0x01, 0x52, 0x1f, 0x01, 0x01, 0x54, 0x1f, 0x01, 0x01, 0x56, 0x1f, 0x01, 0x01, 0x58, 0x1f, 0x01, 0x01, + 0x5a, 0x1f, 0x01, 0x01, 0x5c, 0x1f, 0x01, 0x01, 0x5e, 0x1f, 0x01, 0x01, 0x60, 0x1f, 0x01, 0x01, 0x62, 0x1f, 0x01, 0x01, 0x24, 0x06, 0x02, 0x02, 0x28, 0x06, 0x02, 0x02, 0x2c, 0x06, 0x02, 0x02, + 0x40, 0x27, 0x03, 0x04, 0x50, 0x27, 0x03, 0x04, 0x00, 0x38, 0x07, 0x0a, 0xc8, 0x17, 0x00, 0x01, 0xca, 0x17, 0x00, 0x01, 0xcc, 0x17, 0x00, 0x01, 0xce, 0x17, 0x00, 0x01, 0xd0, 0x17, 0x00, 0x01, + 0xd2, 0x17, 0x00, 0x01, 0xd4, 0x17, 0x00, 0x01, 0xd6, 0x17, 0x00, 0x01, 0x64, 0x1f, 0x01, 0x01, 0x66, 0x1f, 0x01, 0x01, 0x68, 0x1f, 0x01, 0x01, 0x6a, 0x1f, 0x01, 0x01, 0x6c, 0x1f, 0x01, 0x01, + 0x6e, 0x1f, 0x01, 0x01, 0x70, 0x1f, 0x01, 0x01, 0x72, 0x1f, 0x01, 0x01, 0x74, 0x1f, 0x01, 0x01, 0x76, 0x1f, 0x01, 0x01, 0x30, 0x06, 0x02, 0x02, 0x34, 0x06, 0x02, 0x02, 0x38, 0x06, 0x02, 0x02, + 0x60, 0x27, 0x03, 0x04, 0x70, 0x27, 0x03, 0x04, 0x00, 0x3c, 0x07, 0x0a, 0xd8, 0x17, 0x00, 0x01, 0xda, 0x17, 0x00, 0x01, 0xdc, 0x17, 0x00, 0x01, 0xde, 0x17, 0x00, 0x01, 0xe0, 0x17, 0x00, 0x01, + 0xe2, 0x17, 0x00, 0x01, 0xe4, 0x17, 0x00, 0x01, 0xe6, 0x17, 0x00, 0x01, 0x78, 0x1f, 0x01, 0x01, 0x7a, 0x1f, 0x01, 0x01, 0x7c, 0x1f, 0x01, 0x01, 0x7e, 0x1f, 0x01, 0x01, 0x80, 0x1f, 0x01, 0x01, + 0x82, 0x1f, 0x01, 0x01, 0x84, 0x1f, 0x01, 0x01, 0x86, 0x1f, 0x01, 0x01, 0x88, 0x1f, 0x01, 0x01, 0x8a, 0x1f, 0x01, 0x01, 0x3c, 0x06, 0x02, 0x02, 0x40, 0x06, 0x02, 0x02, 0x44, 0x06, 0x02, 0x02, + 0x80, 0x27, 0x03, 0x04, 0x90, 0x27, 0x03, 0x04, 0x00, 0x18, 0x08, 0x0b, 0xe8, 0x17, 0x00, 0x01, 0xea, 0x17, 0x00, 0x01, 0xec, 0x17, 0x00, 0x01, 0xee, 0x17, 0x00, 0x01, 0xf0, 0x17, 0x00, 0x01, + 0xf2, 0x17, 0x00, 0x01, 0xf4, 0x17, 0x00, 0x01, 0xf6, 0x17, 0x00, 0x01, 0x8c, 0x1f, 0x01, 0x01, 0x8e, 0x1f, 0x01, 0x01, 0x90, 0x1f, 0x01, 0x01, 0x92, 0x1f, 0x01, 0x01, 0x94, 0x1f, 0x01, 0x01, + 0x96, 0x1f, 0x01, 0x01, 0x98, 0x1f, 0x01, 0x01, 0x9a, 0x1f, 0x01, 0x01, 0x9c, 0x1f, 0x01, 0x01, 0x9e, 0x1f, 0x01, 0x01, 0x48, 0x06, 0x02, 0x02, 0x4c, 0x06, 0x02, 0x02, 0x50, 0x06, 0x02, 0x02, + 0xa0, 0x27, 0x03, 0x04, 0xb0, 0x27, 0x03, 0x04, 0xf8, 0x17, 0x00, 0x01, 0xfa, 0x17, 0x00, 0x01, 0xfc, 0x17, 0x00, 0x01, 0xfe, 0x17, 0x00, 0x01, 0x00, 0x18, 0x00, 0x01, 0x02, 0x18, 0x00, 0x01, + 0x04, 0x18, 0x00, 0x01, 0x06, 0x18, 0x00, 0x01, 0x08, 0x18, 0x00, 0x01, 0xa0, 0x1f, 0x01, 0x01, 0xa2, 0x1f, 0x01, 0x01, 0xa4, 0x1f, 0x01, 0x01, 0xa6, 0x1f, 0x01, 0x01, 0xa8, 0x1f, 0x01, 0x01, + 0xaa, 0x1f, 0x01, 0x01, 0xac, 0x1f, 0x01, 0x01, 0xae, 0x1f, 0x01, 0x01, 0xb0, 0x1f, 0x01, 0x01, 0xb2, 0x1f, 0x01, 0x01, 0x54, 0x06, 0x02, 0x02, 0x58, 0x06, 0x02, 0x02, 0x5c, 0x06, 0x02, 0x02, + 0xc0, 0x27, 0x03, 0x04, 0xd0, 0x27, 0x03, 0x04, 0x0a, 0x18, 0x00, 0x01, 0x0c, 0x18, 0x00, 0x01, 0x0e, 0x18, 0x00, 0x01, 0x10, 0x18, 0x00, 0x01, 0x12, 0x18, 0x00, 0x01, 0x14, 0x18, 0x00, 0x01, + 0x16, 0x18, 0x00, 0x01, 0x18, 0x18, 0x00, 0x01, 0x1a, 0x18, 0x00, 0x01, 0xb4, 0x1f, 0x01, 0x01, 0xb6, 0x1f, 0x01, 0x01, 0xb8, 0x1f, 0x01, 0x01, 0xba, 0x1f, 0x01, 0x01, 0xbc, 0x1f, 0x01, 0x01, + 0xbe, 0x1f, 0x01, 0x01, 0xc0, 0x1f, 0x01, 0x01, 0xc2, 0x1f, 0x01, 0x01, 0xc4, 0x1f, 0x01, 0x01, 0xc6, 0x1f, 0x01, 0x01, 0x60, 0x06, 0x02, 0x02, 0x64, 0x06, 0x02, 0x02, 0x68, 0x06, 0x02, 0x02, + 0xe0, 0x27, 0x03, 0x04, 0xf0, 0x27, 0x03, 0x04, 0x1c, 0x18, 0x00, 0x01, 0x1e, 0x18, 0x00, 0x01, 0x20, 0x18, 0x00, 0x01, 0x22, 0x18, 0x00, 0x01, 0x24, 0x18, 0x00, 0x01, 0x26, 0x18, 0x00, 0x01, + 0x28, 0x18, 0x00, 0x01, 0x2a, 0x18, 0x00, 0x01, 0x2c, 0x18, 0x00, 0x01, 0xc8, 0x1f, 0x01, 0x01, 0xca, 0x1f, 0x01, 0x01, 0xcc, 0x1f, 0x01, 0x01, 0xce, 0x1f, 0x01, 0x01, 0xd0, 0x1f, 0x01, 0x01, + 0xd2, 0x1f, 0x01, 0x01, 0xd4, 0x1f, 0x01, 0x01, 0xd6, 0x1f, 0x01, 0x01, 0xd8, 0x1f, 0x01, 0x01, 0xda, 0x1f, 0x01, 0x01, 0x6c, 0x06, 0x02, 0x02, 0x70, 0x06, 0x02, 0x02, 0x74, 0x06, 0x02, 0x02, + 0x00, 0x28, 0x03, 0x04, 0x10, 0x28, 0x03, 0x04, 0x2e, 0x18, 0x00, 0x01, 0x30, 0x18, 0x00, 0x01, 0x32, 0x18, 0x00, 0x01, 0x34, 0x18, 0x00, 0x01, 0x36, 0x18, 0x00, 0x01, 0x38, 0x18, 0x00, 0x01, + 0x3a, 0x18, 0x00, 0x01, 0x3c, 0x18, 0x00, 0x01, 0x3e, 0x18, 0x00, 0x01, 0xdc, 0x1f, 0x01, 0x01, 0xde, 0x1f, 0x01, 0x01, 0xe0, 0x1f, 0x01, 0x01, 0xe2, 0x1f, 0x01, 0x01, 0xe4, 0x1f, 0x01, 0x01, + 0xe6, 0x1f, 0x01, 0x01, 0xe8, 0x1f, 0x01, 0x01, 0xea, 0x1f, 0x01, 0x01, 0xec, 0x1f, 0x01, 0x01, 0xee, 0x1f, 0x01, 0x01, 0x78, 0x06, 0x02, 0x02, 0x7c, 0x06, 0x02, 0x02, 0x80, 0x06, 0x02, 0x02, + 0x20, 0x28, 0x03, 0x04, 0x30, 0x28, 0x03, 0x04, 0x40, 0x18, 0x00, 0x01, 0x42, 0x18, 0x00, 0x01, 0x44, 0x18, 0x00, 0x01, 0x46, 0x18, 0x00, 0x01, 0x48, 0x18, 0x00, 0x01, 0x4a, 0x18, 0x00, 0x01, + 0x4c, 0x18, 0x00, 0x01, 0x4e, 0x18, 0x00, 0x01, 0x50, 0x18, 0x00, 0x01, 0xf0, 0x1f, 0x01, 0x01, 0xf2, 0x1f, 0x01, 0x01, 0xf4, 0x1f, 0x01, 0x01, 0xf6, 0x1f, 0x01, 0x01, 0xf8, 0x1f, 0x01, 0x01, + 0xfa, 0x1f, 0x01, 0x01, 0xfc, 0x1f, 0x01, 0x01, 0xfe, 0x1f, 0x01, 0x01, 0x00, 0x20, 0x01, 0x01, 0x02, 0x20, 0x01, 0x01, 0x84, 0x06, 0x02, 0x02, 0x88, 0x06, 0x02, 0x02, 0x8c, 0x06, 0x02, 0x02, + 0x40, 0x28, 0x03, 0x04, 0x50, 0x28, 0x03, 0x04, 0x52, 0x18, 0x00, 0x01, 0x54, 0x18, 0x00, 0x01, 0x56, 0x18, 0x00, 0x01, 0x58, 0x18, 0x00, 0x01, 0x5a, 0x18, 0x00, 0x01, 0x5c, 0x18, 0x00, 0x01, + 0x5e, 0x18, 0x00, 0x01, 0x60, 0x18, 0x00, 0x01, 0x62, 0x18, 0x00, 0x01, 0x04, 0x20, 0x01, 0x01, 0x06, 0x20, 0x01, 0x01, 0x08, 0x20, 0x01, 0x01, 0x0a, 0x20, 0x01, 0x01, 0x0c, 0x20, 0x01, 0x01, + 0x0e, 0x20, 0x01, 0x01, 0x10, 0x20, 0x01, 0x01, 0x12, 0x20, 0x01, 0x01, 0x14, 0x20, 0x01, 0x01, 0x16, 0x20, 0x01, 0x01, 0x90, 0x06, 0x02, 0x02, 0x94, 0x06, 0x02, 0x02, 0x98, 0x06, 0x02, 0x02, + 0x60, 0x28, 0x03, 0x04, 0x70, 0x28, 0x03, 0x04, 0x64, 0x18, 0x00, 0x01, 0x66, 0x18, 0x00, 0x01, 0x68, 0x18, 0x00, 0x01, 0x6a, 0x18, 0x00, 0x01, 0x6c, 0x18, 0x00, 0x01, 0x6e, 0x18, 0x00, 0x01, + 0x70, 0x18, 0x00, 0x01, 0x72, 0x18, 0x00, 0x01, 0x74, 0x18, 0x00, 0x01, 0x18, 0x20, 0x01, 0x01, 0x1a, 0x20, 0x01, 0x01, 0x1c, 0x20, 0x01, 0x01, 0x1e, 0x20, 0x01, 0x01, 0x20, 0x20, 0x01, 0x01, + 0x22, 0x20, 0x01, 0x01, 0x24, 0x20, 0x01, 0x01, 0x26, 0x20, 0x01, 0x01, 0x28, 0x20, 0x01, 0x01, 0x2a, 0x20, 0x01, 0x01, 0x9c, 0x06, 0x02, 0x02, 0xa0, 0x06, 0x02, 0x02, 0xa4, 0x06, 0x02, 0x02, + 0x80, 0x28, 0x03, 0x04, 0x90, 0x28, 0x03, 0x04, 0x76, 0x18, 0x00, 0x01, 0x78, 0x18, 0x00, 0x01, 0x7a, 0x18, 0x00, 0x01, 0x7c, 0x18, 0x00, 0x01, 0x7e, 0x18, 0x00, 0x01, 0x80, 0x18, 0x00, 0x01, + 0x82, 0x18, 0x00, 0x01, 0x84, 0x18, 0x00, 0x01, 0x86, 0x18, 0x00, 0x01, 0x2c, 0x20, 0x01, 0x01, 0x2e, 0x20, 0x01, 0x01, 0x30, 0x20, 0x01, 0x01, 0x32, 0x20, 0x01, 0x01, 0x34, 0x20, 0x01, 0x01, + 0x36, 0x20, 0x01, 0x01, 0x38, 0x20, 0x01, 0x01, 0x3a, 0x20, 0x01, 0x01, 0x3c, 0x20, 0x01, 0x01, 0x3e, 0x20, 0x01, 0x01, 0xa8, 0x06, 0x02, 0x02, 0xac, 0x06, 0x02, 0x02, 0xb0, 0x06, 0x02, 0x02, + 0xa0, 0x28, 0x03, 0x04, 0xb0, 0x28, 0x03, 0x04, 0x88, 0x18, 0x00, 0x01, 0x8a, 0x18, 0x00, 0x01, 0x8c, 0x18, 0x00, 0x01, 0x8e, 0x18, 0x00, 0x01, 0x90, 0x18, 0x00, 0x01, 0x92, 0x18, 0x00, 0x01, + 0x94, 0x18, 0x00, 0x01, 0x96, 0x18, 0x00, 0x01, 0x98, 0x18, 0x00, 0x01, 0x40, 0x20, 0x01, 0x01, 0x42, 0x20, 0x01, 0x01, 0x44, 0x20, 0x01, 0x01, 0x46, 0x20, 0x01, 0x01, 0x48, 0x20, 0x01, 0x01, + 0x4a, 0x20, 0x01, 0x01, 0x4c, 0x20, 0x01, 0x01, 0x4e, 0x20, 0x01, 0x01, 0x50, 0x20, 0x01, 0x01, 0x52, 0x20, 0x01, 0x01, 0xb4, 0x06, 0x02, 0x02, 0xb8, 0x06, 0x02, 0x02, 0xbc, 0x06, 0x02, 0x02, + 0xc0, 0x28, 0x03, 0x04, 0xd0, 0x28, 0x03, 0x04, 0x9a, 0x18, 0x00, 0x01, 0x9c, 0x18, 0x00, 0x01, 0x9e, 0x18, 0x00, 0x01, 0xa0, 0x18, 0x00, 0x01, 0xa2, 0x18, 0x00, 0x01, 0xa4, 0x18, 0x00, 0x01, + 0xa6, 0x18, 0x00, 0x01, 0xa8, 0x18, 0x00, 0x01, 0xaa, 0x18, 0x00, 0x01, 0x54, 0x20, 0x01, 0x01, 0x56, 0x20, 0x01, 0x01, 0x58, 0x20, 0x01, 0x01, 0x5a, 0x20, 0x01, 0x01, 0x5c, 0x20, 0x01, 0x01, + 0x5e, 0x20, 0x01, 0x01, 0x60, 0x20, 0x01, 0x01, 0x62, 0x20, 0x01, 0x01, 0x64, 0x20, 0x01, 0x01, 0x66, 0x20, 0x01, 0x01, 0xc0, 0x06, 0x02, 0x02, 0xc4, 0x06, 0x02, 0x02, 0xc8, 0x06, 0x02, 0x02, + 0xe0, 0x28, 0x03, 0x04, 0xf0, 0x28, 0x03, 0x04, 0xac, 0x18, 0x00, 0x01, 0xae, 0x18, 0x00, 0x01, 0xb0, 0x18, 0x00, 0x01, 0xb2, 0x18, 0x00, 0x01, 0xb4, 0x18, 0x00, 0x01, 0xb6, 0x18, 0x00, 0x01, + 0xb8, 0x18, 0x00, 0x01, 0xba, 0x18, 0x00, 0x01, 0xbc, 0x18, 0x00, 0x01, 0x68, 0x20, 0x01, 0x01, 0x6a, 0x20, 0x01, 0x01, 0x6c, 0x20, 0x01, 0x01, 0x6e, 0x20, 0x01, 0x01, 0x70, 0x20, 0x01, 0x01, + 0x72, 0x20, 0x01, 0x01, 0x74, 0x20, 0x01, 0x01, 0x76, 0x20, 0x01, 0x01, 0x78, 0x20, 0x01, 0x01, 0x7a, 0x20, 0x01, 0x01, 0xcc, 0x06, 0x02, 0x02, 0xd0, 0x06, 0x02, 0x02, 0xd4, 0x06, 0x02, 0x02, + 0x00, 0x29, 0x03, 0x04, 0x10, 0x29, 0x03, 0x04, 0xbe, 0x18, 0x00, 0x01, 0xc0, 0x18, 0x00, 0x01, 0xc2, 0x18, 0x00, 0x01, 0xc4, 0x18, 0x00, 0x01, 0xc6, 0x18, 0x00, 0x01, 0xc8, 0x18, 0x00, 0x01, + 0xca, 0x18, 0x00, 0x01, 0xcc, 0x18, 0x00, 0x01, 0xce, 0x18, 0x00, 0x01, 0x7c, 0x20, 0x01, 0x01, 0x7e, 0x20, 0x01, 0x01, 0x80, 0x20, 0x01, 0x01, 0x82, 0x20, 0x01, 0x01, 0x84, 0x20, 0x01, 0x01, + 0x86, 0x20, 0x01, 0x01, 0x88, 0x20, 0x01, 0x01, 0x8a, 0x20, 0x01, 0x01, 0x8c, 0x20, 0x01, 0x01, 0x8e, 0x20, 0x01, 0x01, 0xd8, 0x06, 0x02, 0x02, 0xdc, 0x06, 0x02, 0x02, 0xe0, 0x06, 0x02, 0x02, + 0x20, 0x29, 0x03, 0x04, 0x30, 0x29, 0x03, 0x04, 0xd0, 0x18, 0x00, 0x01, 0xd2, 0x18, 0x00, 0x01, 0xd4, 0x18, 0x00, 0x01, 0xd6, 0x18, 0x00, 0x01, 0xd8, 0x18, 0x00, 0x01, 0xda, 0x18, 0x00, 0x01, + 0xdc, 0x18, 0x00, 0x01, 0xde, 0x18, 0x00, 0x01, 0xe0, 0x18, 0x00, 0x01, 0x90, 0x20, 0x01, 0x01, 0x92, 0x20, 0x01, 0x01, 0x94, 0x20, 0x01, 0x01, 0x96, 0x20, 0x01, 0x01, 0x98, 0x20, 0x01, 0x01, + 0x9a, 0x20, 0x01, 0x01, 0x9c, 0x20, 0x01, 0x01, 0x9e, 0x20, 0x01, 0x01, 0xa0, 0x20, 0x01, 0x01, 0xa2, 0x20, 0x01, 0x01, 0xe4, 0x06, 0x02, 0x02, 0xe8, 0x06, 0x02, 0x02, 0xec, 0x06, 0x02, 0x02, + 0x40, 0x29, 0x03, 0x04, 0x50, 0x29, 0x03, 0x04, 0xe2, 0x18, 0x00, 0x01, 0xe4, 0x18, 0x00, 0x01, 0xe6, 0x18, 0x00, 0x01, 0xe8, 0x18, 0x00, 0x01, 0xea, 0x18, 0x00, 0x01, 0xec, 0x18, 0x00, 0x01, + 0xee, 0x18, 0x00, 0x01, 0xf0, 0x18, 0x00, 0x01, 0xf2, 0x18, 0x00, 0x01, 0xa4, 0x20, 0x01, 0x01, 0xa6, 0x20, 0x01, 0x01, 0xa8, 0x20, 0x01, 0x01, 0xaa, 0x20, 0x01, 0x01, 0xac, 0x20, 0x01, 0x01, + 0xae, 0x20, 0x01, 0x01, 0xb0, 0x20, 0x01, 0x01, 0xb2, 0x20, 0x01, 0x01, 0xb4, 0x20, 0x01, 0x01, 0xb6, 0x20, 0x01, 0x01, 0xf0, 0x06, 0x02, 0x02, 0xf4, 0x06, 0x02, 0x02, 0xf8, 0x06, 0x02, 0x02, + 0x60, 0x29, 0x03, 0x04, 0x70, 0x29, 0x03, 0x04, 0xf4, 0x18, 0x00, 0x01, 0xf6, 0x18, 0x00, 0x01, 0xf8, 0x18, 0x00, 0x01, 0xfa, 0x18, 0x00, 0x01, 0xfc, 0x18, 0x00, 0x01, 0xfe, 0x18, 0x00, 0x01, + 0x00, 0x19, 0x00, 0x01, 0x02, 0x19, 0x00, 0x01, 0x04, 0x19, 0x00, 0x01, 0xb8, 0x20, 0x01, 0x01, 0xba, 0x20, 0x01, 0x01, 0xbc, 0x20, 0x01, 0x01, 0xbe, 0x20, 0x01, 0x01, 0xc0, 0x20, 0x01, 0x01, + 0xc2, 0x20, 0x01, 0x01, 0xc4, 0x20, 0x01, 0x01, 0xc6, 0x20, 0x01, 0x01, 0xc8, 0x20, 0x01, 0x01, 0xca, 0x20, 0x01, 0x01, 0xfc, 0x06, 0x02, 0x02, 0x00, 0x07, 0x02, 0x02, 0x04, 0x07, 0x02, 0x02, + 0x80, 0x29, 0x03, 0x04, 0x90, 0x29, 0x03, 0x04, 0x06, 0x19, 0x00, 0x01, 0x08, 0x19, 0x00, 0x01, 0x0a, 0x19, 0x00, 0x01, 0x0c, 0x19, 0x00, 0x01, 0x0e, 0x19, 0x00, 0x01, 0x10, 0x19, 0x00, 0x01, + 0x12, 0x19, 0x00, 0x01, 0x14, 0x19, 0x00, 0x01, 0x16, 0x19, 0x00, 0x01, 0xcc, 0x20, 0x01, 0x01, 0xce, 0x20, 0x01, 0x01, 0xd0, 0x20, 0x01, 0x01, 0xd2, 0x20, 0x01, 0x01, 0xd4, 0x20, 0x01, 0x01, + 0xd6, 0x20, 0x01, 0x01, 0xd8, 0x20, 0x01, 0x01, 0xda, 0x20, 0x01, 0x01, 0xdc, 0x20, 0x01, 0x01, 0xde, 0x20, 0x01, 0x01, 0x08, 0x07, 0x02, 0x02, 0x0c, 0x07, 0x02, 0x02, 0x10, 0x07, 0x02, 0x02, + 0xa0, 0x29, 0x03, 0x04, 0xb0, 0x29, 0x03, 0x04, 0x18, 0x19, 0x00, 0x01, 0x1a, 0x19, 0x00, 0x01, 0x1c, 0x19, 0x00, 0x01, 0x1e, 0x19, 0x00, 0x01, 0x20, 0x19, 0x00, 0x01, 0x22, 0x19, 0x00, 0x01, + 0x24, 0x19, 0x00, 0x01, 0x26, 0x19, 0x00, 0x01, 0x28, 0x19, 0x00, 0x01, 0xe0, 0x20, 0x01, 0x01, 0xe2, 0x20, 0x01, 0x01, 0xe4, 0x20, 0x01, 0x01, 0xe6, 0x20, 0x01, 0x01, 0xe8, 0x20, 0x01, 0x01, + 0xea, 0x20, 0x01, 0x01, 0xec, 0x20, 0x01, 0x01, 0xee, 0x20, 0x01, 0x01, 0xf0, 0x20, 0x01, 0x01, 0xf2, 0x20, 0x01, 0x01, 0x14, 0x07, 0x02, 0x02, 0x18, 0x07, 0x02, 0x02, 0x1c, 0x07, 0x02, 0x02, + 0xc0, 0x29, 0x03, 0x04, 0xd0, 0x29, 0x03, 0x04, 0x2a, 0x19, 0x00, 0x01, 0x2c, 0x19, 0x00, 0x01, 0x2e, 0x19, 0x00, 0x01, 0x30, 0x19, 0x00, 0x01, 0x32, 0x19, 0x00, 0x01, 0x34, 0x19, 0x00, 0x01, + 0x36, 0x19, 0x00, 0x01, 0x38, 0x19, 0x00, 0x01, 0x3a, 0x19, 0x00, 0x01, 0xf4, 0x20, 0x01, 0x01, 0xf6, 0x20, 0x01, 0x01, 0xf8, 0x20, 0x01, 0x01, 0xfa, 0x20, 0x01, 0x01, 0xfc, 0x20, 0x01, 0x01, + 0xfe, 0x20, 0x01, 0x01, 0x00, 0x21, 0x01, 0x01, 0x02, 0x21, 0x01, 0x01, 0x04, 0x21, 0x01, 0x01, 0x06, 0x21, 0x01, 0x01, 0x20, 0x07, 0x02, 0x02, 0x24, 0x07, 0x02, 0x02, 0x28, 0x07, 0x02, 0x02, + 0xe0, 0x29, 0x03, 0x04, 0xf0, 0x29, 0x03, 0x04, 0x3c, 0x19, 0x00, 0x01, 0x3e, 0x19, 0x00, 0x01, 0x40, 0x19, 0x00, 0x01, 0x42, 0x19, 0x00, 0x01, 0x44, 0x19, 0x00, 0x01, 0x46, 0x19, 0x00, 0x01, + 0x48, 0x19, 0x00, 0x01, 0x4a, 0x19, 0x00, 0x01, 0x4c, 0x19, 0x00, 0x01, 0x08, 0x21, 0x01, 0x01, 0x0a, 0x21, 0x01, 0x01, 0x0c, 0x21, 0x01, 0x01, 0x0e, 0x21, 0x01, 0x01, 0x10, 0x21, 0x01, 0x01, + 0x12, 0x21, 0x01, 0x01, 0x14, 0x21, 0x01, 0x01, 0x16, 0x21, 0x01, 0x01, 0x18, 0x21, 0x01, 0x01, 0x1a, 0x21, 0x01, 0x01, 0x2c, 0x07, 0x02, 0x02, 0x30, 0x07, 0x02, 0x02, 0x34, 0x07, 0x02, 0x02, + 0x00, 0x2a, 0x03, 0x04, 0x10, 0x2a, 0x03, 0x04, 0x4e, 0x19, 0x00, 0x01, 0x50, 0x19, 0x00, 0x01, 0x52, 0x19, 0x00, 0x01, 0x54, 0x19, 0x00, 0x01, 0x56, 0x19, 0x00, 0x01, 0x58, 0x19, 0x00, 0x01, + 0x5a, 0x19, 0x00, 0x01, 0x5c, 0x19, 0x00, 0x01, 0x5e, 0x19, 0x00, 0x01, 0x1c, 0x21, 0x01, 0x01, 0x1e, 0x21, 0x01, 0x01, 0x20, 0x21, 0x01, 0x01, 0x22, 0x21, 0x01, 0x01, 0x24, 0x21, 0x01, 0x01, + 0x26, 0x21, 0x01, 0x01, 0x28, 0x21, 0x01, 0x01, 0x2a, 0x21, 0x01, 0x01, 0x2c, 0x21, 0x01, 0x01, 0x2e, 0x21, 0x01, 0x01, 0x38, 0x07, 0x02, 0x02, 0x3c, 0x07, 0x02, 0x02, 0x40, 0x07, 0x02, 0x02, + 0x20, 0x2a, 0x03, 0x04, 0x30, 0x2a, 0x03, 0x04, 0x60, 0x19, 0x00, 0x01, 0x62, 0x19, 0x00, 0x01, 0x64, 0x19, 0x00, 0x01, 0x66, 0x19, 0x00, 0x01, 0x68, 0x19, 0x00, 0x01, 0x6a, 0x19, 0x00, 0x01, + 0x6c, 0x19, 0x00, 0x01, 0x6e, 0x19, 0x00, 0x01, 0x70, 0x19, 0x00, 0x01, 0x30, 0x21, 0x01, 0x01, 0x32, 0x21, 0x01, 0x01, 0x34, 0x21, 0x01, 0x01, 0x36, 0x21, 0x01, 0x01, 0x38, 0x21, 0x01, 0x01, + 0x3a, 0x21, 0x01, 0x01, 0x3c, 0x21, 0x01, 0x01, 0x3e, 0x21, 0x01, 0x01, 0x40, 0x21, 0x01, 0x01, 0x42, 0x21, 0x01, 0x01, 0x44, 0x07, 0x02, 0x02, 0x48, 0x07, 0x02, 0x02, 0x4c, 0x07, 0x02, 0x02, + 0x40, 0x2a, 0x03, 0x04, 0xe0, 0x0b, 0x04, 0x05, 0x72, 0x19, 0x00, 0x01, 0x74, 0x19, 0x00, 0x01, 0x76, 0x19, 0x00, 0x01, 0x78, 0x19, 0x00, 0x01, 0x7a, 0x19, 0x00, 0x01, 0x7c, 0x19, 0x00, 0x01, + 0x7e, 0x19, 0x00, 0x01, 0x80, 0x19, 0x00, 0x01, 0x82, 0x19, 0x00, 0x01, 0x44, 0x21, 0x01, 0x01, 0x46, 0x21, 0x01, 0x01, 0x48, 0x21, 0x01, 0x01, 0x4a, 0x21, 0x01, 0x01, 0x4c, 0x21, 0x01, 0x01, + 0x4e, 0x21, 0x01, 0x01, 0x50, 0x21, 0x01, 0x01, 0x52, 0x21, 0x01, 0x01, 0x54, 0x21, 0x01, 0x01, 0x56, 0x21, 0x01, 0x01, 0x50, 0x07, 0x02, 0x02, 0x54, 0x07, 0x02, 0x02, 0x58, 0x07, 0x02, 0x02, + 0x50, 0x2a, 0x03, 0x04, 0x00, 0x0c, 0x04, 0x05, 0x84, 0x19, 0x00, 0x01, 0x86, 0x19, 0x00, 0x01, 0x88, 0x19, 0x00, 0x01, 0x8a, 0x19, 0x00, 0x01, 0x8c, 0x19, 0x00, 0x01, 0x8e, 0x19, 0x00, 0x01, + 0x90, 0x19, 0x00, 0x01, 0x92, 0x19, 0x00, 0x01, 0x94, 0x19, 0x00, 0x01, 0x58, 0x21, 0x01, 0x01, 0x5a, 0x21, 0x01, 0x01, 0x5c, 0x21, 0x01, 0x01, 0x5e, 0x21, 0x01, 0x01, 0x60, 0x21, 0x01, 0x01, + 0x62, 0x21, 0x01, 0x01, 0x64, 0x21, 0x01, 0x01, 0x66, 0x21, 0x01, 0x01, 0x68, 0x21, 0x01, 0x01, 0x6a, 0x21, 0x01, 0x01, 0x5c, 0x07, 0x02, 0x02, 0x60, 0x07, 0x02, 0x02, 0x64, 0x07, 0x02, 0x02, + 0x60, 0x2a, 0x03, 0x04, 0x20, 0x0c, 0x04, 0x05, 0x96, 0x19, 0x00, 0x01, 0x98, 0x19, 0x00, 0x01, 0x9a, 0x19, 0x00, 0x01, 0x9c, 0x19, 0x00, 0x01, 0x9e, 0x19, 0x00, 0x01, 0xa0, 0x19, 0x00, 0x01, + 0xa2, 0x19, 0x00, 0x01, 0xa4, 0x19, 0x00, 0x01, 0xa6, 0x19, 0x00, 0x01, 0x6c, 0x21, 0x01, 0x01, 0x6e, 0x21, 0x01, 0x01, 0x70, 0x21, 0x01, 0x01, 0x72, 0x21, 0x01, 0x01, 0x74, 0x21, 0x01, 0x01, + 0x76, 0x21, 0x01, 0x01, 0x78, 0x21, 0x01, 0x01, 0x7a, 0x21, 0x01, 0x01, 0x7c, 0x21, 0x01, 0x01, 0x7e, 0x21, 0x01, 0x01, 0x68, 0x07, 0x02, 0x02, 0x6c, 0x07, 0x02, 0x02, 0x70, 0x07, 0x02, 0x02, + 0x70, 0x2a, 0x03, 0x04, 0x40, 0x0c, 0x04, 0x05, 0xa8, 0x19, 0x00, 0x01, 0xaa, 0x19, 0x00, 0x01, 0xac, 0x19, 0x00, 0x01, 0xae, 0x19, 0x00, 0x01, 0xb0, 0x19, 0x00, 0x01, 0xb2, 0x19, 0x00, 0x01, + 0xb4, 0x19, 0x00, 0x01, 0xb6, 0x19, 0x00, 0x01, 0xb8, 0x19, 0x00, 0x01, 0x80, 0x21, 0x01, 0x01, 0x82, 0x21, 0x01, 0x01, 0x84, 0x21, 0x01, 0x01, 0x86, 0x21, 0x01, 0x01, 0x88, 0x21, 0x01, 0x01, + 0x8a, 0x21, 0x01, 0x01, 0x8c, 0x21, 0x01, 0x01, 0x8e, 0x21, 0x01, 0x01, 0x90, 0x21, 0x01, 0x01, 0x92, 0x21, 0x01, 0x01, 0x74, 0x07, 0x02, 0x02, 0x78, 0x07, 0x02, 0x02, 0x7c, 0x07, 0x02, 0x02, + 0x80, 0x2a, 0x03, 0x04, 0x60, 0x0c, 0x04, 0x05, 0xba, 0x19, 0x00, 0x01, 0xbc, 0x19, 0x00, 0x01, 0xbe, 0x19, 0x00, 0x01, 0xc0, 0x19, 0x00, 0x01, 0xc2, 0x19, 0x00, 0x01, 0xc4, 0x19, 0x00, 0x01, + 0xc6, 0x19, 0x00, 0x01, 0xc8, 0x19, 0x00, 0x01, 0xca, 0x19, 0x00, 0x01, 0x94, 0x21, 0x01, 0x01, 0x96, 0x21, 0x01, 0x01, 0x98, 0x21, 0x01, 0x01, 0x9a, 0x21, 0x01, 0x01, 0x9c, 0x21, 0x01, 0x01, + 0x9e, 0x21, 0x01, 0x01, 0xa0, 0x21, 0x01, 0x01, 0xa2, 0x21, 0x01, 0x01, 0xa4, 0x21, 0x01, 0x01, 0xa6, 0x21, 0x01, 0x01, 0x80, 0x07, 0x02, 0x02, 0x84, 0x07, 0x02, 0x02, 0x88, 0x07, 0x02, 0x02, + 0x90, 0x2a, 0x03, 0x04, 0x80, 0x0c, 0x04, 0x05, 0xcc, 0x19, 0x00, 0x01, 0xce, 0x19, 0x00, 0x01, 0xd0, 0x19, 0x00, 0x01, 0xd2, 0x19, 0x00, 0x01, 0xd4, 0x19, 0x00, 0x01, 0xd6, 0x19, 0x00, 0x01, + 0xd8, 0x19, 0x00, 0x01, 0xda, 0x19, 0x00, 0x01, 0xdc, 0x19, 0x00, 0x01, 0xa8, 0x21, 0x01, 0x01, 0xaa, 0x21, 0x01, 0x01, 0xac, 0x21, 0x01, 0x01, 0xae, 0x21, 0x01, 0x01, 0xb0, 0x21, 0x01, 0x01, + 0xb2, 0x21, 0x01, 0x01, 0xb4, 0x21, 0x01, 0x01, 0xb6, 0x21, 0x01, 0x01, 0xb8, 0x21, 0x01, 0x01, 0xba, 0x21, 0x01, 0x01, 0x8c, 0x07, 0x02, 0x02, 0x90, 0x07, 0x02, 0x02, 0x94, 0x07, 0x02, 0x02, + 0xa0, 0x2a, 0x03, 0x04, 0xa0, 0x0c, 0x04, 0x05, 0xde, 0x19, 0x00, 0x01, 0xe0, 0x19, 0x00, 0x01, 0xe2, 0x19, 0x00, 0x01, 0xe4, 0x19, 0x00, 0x01, 0xe6, 0x19, 0x00, 0x01, 0xe8, 0x19, 0x00, 0x01, + 0xea, 0x19, 0x00, 0x01, 0xec, 0x19, 0x00, 0x01, 0xee, 0x19, 0x00, 0x01, 0xbc, 0x21, 0x01, 0x01, 0xbe, 0x21, 0x01, 0x01, 0xc0, 0x21, 0x01, 0x01, 0xc2, 0x21, 0x01, 0x01, 0xc4, 0x21, 0x01, 0x01, + 0xc6, 0x21, 0x01, 0x01, 0xc8, 0x21, 0x01, 0x01, 0xca, 0x21, 0x01, 0x01, 0xcc, 0x21, 0x01, 0x01, 0xce, 0x21, 0x01, 0x01, 0x98, 0x07, 0x02, 0x02, 0x9c, 0x07, 0x02, 0x02, 0xa0, 0x07, 0x02, 0x02, + 0xb0, 0x2a, 0x03, 0x04, 0xc0, 0x0c, 0x04, 0x05, 0xf0, 0x19, 0x00, 0x01, 0xf2, 0x19, 0x00, 0x01, 0xf4, 0x19, 0x00, 0x01, 0xf6, 0x19, 0x00, 0x01, 0xf8, 0x19, 0x00, 0x01, 0xfa, 0x19, 0x00, 0x01, + 0xfc, 0x19, 0x00, 0x01, 0xfe, 0x19, 0x00, 0x01, 0x00, 0x1a, 0x00, 0x01, 0xd0, 0x21, 0x01, 0x01, 0xd2, 0x21, 0x01, 0x01, 0xd4, 0x21, 0x01, 0x01, 0xd6, 0x21, 0x01, 0x01, 0xd8, 0x21, 0x01, 0x01, + 0xda, 0x21, 0x01, 0x01, 0xdc, 0x21, 0x01, 0x01, 0xde, 0x21, 0x01, 0x01, 0xe0, 0x21, 0x01, 0x01, 0xe2, 0x21, 0x01, 0x01, 0xa4, 0x07, 0x02, 0x02, 0xa8, 0x07, 0x02, 0x02, 0xac, 0x07, 0x02, 0x02, + 0xc0, 0x2a, 0x03, 0x04, 0xe0, 0x0c, 0x04, 0x05, 0x02, 0x1a, 0x00, 0x01, 0x04, 0x1a, 0x00, 0x01, 0x06, 0x1a, 0x00, 0x01, 0x08, 0x1a, 0x00, 0x01, 0x0a, 0x1a, 0x00, 0x01, 0x0c, 0x1a, 0x00, 0x01, + 0x0e, 0x1a, 0x00, 0x01, 0x10, 0x1a, 0x00, 0x01, 0x12, 0x1a, 0x00, 0x01, 0xe4, 0x21, 0x01, 0x01, 0xe6, 0x21, 0x01, 0x01, 0xe8, 0x21, 0x01, 0x01, 0xea, 0x21, 0x01, 0x01, 0xec, 0x21, 0x01, 0x01, + 0xee, 0x21, 0x01, 0x01, 0xf0, 0x21, 0x01, 0x01, 0xf2, 0x21, 0x01, 0x01, 0xf4, 0x21, 0x01, 0x01, 0xf6, 0x21, 0x01, 0x01, 0xb0, 0x07, 0x02, 0x02, 0xb4, 0x07, 0x02, 0x02, 0xb8, 0x07, 0x02, 0x02, + 0xd0, 0x2a, 0x03, 0x04, 0x00, 0x0d, 0x04, 0x05, 0x14, 0x1a, 0x00, 0x01, 0x16, 0x1a, 0x00, 0x01, 0x18, 0x1a, 0x00, 0x01, 0x1a, 0x1a, 0x00, 0x01, 0x1c, 0x1a, 0x00, 0x01, 0x1e, 0x1a, 0x00, 0x01, + 0x20, 0x1a, 0x00, 0x01, 0x22, 0x1a, 0x00, 0x01, 0x24, 0x1a, 0x00, 0x01, 0xf8, 0x21, 0x01, 0x01, 0xfa, 0x21, 0x01, 0x01, 0xfc, 0x21, 0x01, 0x01, 0xfe, 0x21, 0x01, 0x01, 0x00, 0x22, 0x01, 0x01, + 0x02, 0x22, 0x01, 0x01, 0x04, 0x22, 0x01, 0x01, 0x06, 0x22, 0x01, 0x01, 0x08, 0x22, 0x01, 0x01, 0x0a, 0x22, 0x01, 0x01, 0xbc, 0x07, 0x02, 0x02, 0xc0, 0x07, 0x02, 0x02, 0xc4, 0x07, 0x02, 0x02, + 0xe0, 0x2a, 0x03, 0x04, 0x20, 0x0d, 0x04, 0x05, 0x26, 0x1a, 0x00, 0x01, 0x28, 0x1a, 0x00, 0x01, 0x2a, 0x1a, 0x00, 0x01, 0x2c, 0x1a, 0x00, 0x01, 0x2e, 0x1a, 0x00, 0x01, 0x30, 0x1a, 0x00, 0x01, + 0x32, 0x1a, 0x00, 0x01, 0x34, 0x1a, 0x00, 0x01, 0x36, 0x1a, 0x00, 0x01, 0x0c, 0x22, 0x01, 0x01, 0x0e, 0x22, 0x01, 0x01, 0x10, 0x22, 0x01, 0x01, 0x12, 0x22, 0x01, 0x01, 0x14, 0x22, 0x01, 0x01, + 0x16, 0x22, 0x01, 0x01, 0x18, 0x22, 0x01, 0x01, 0x1a, 0x22, 0x01, 0x01, 0x1c, 0x22, 0x01, 0x01, 0x1e, 0x22, 0x01, 0x01, 0xc8, 0x07, 0x02, 0x02, 0xcc, 0x07, 0x02, 0x02, 0xd0, 0x07, 0x02, 0x02, + 0xf0, 0x2a, 0x03, 0x04, 0x40, 0x0d, 0x04, 0x05, 0x38, 0x1a, 0x00, 0x01, 0x3a, 0x1a, 0x00, 0x01, 0x3c, 0x1a, 0x00, 0x01, 0x3e, 0x1a, 0x00, 0x01, 0x40, 0x1a, 0x00, 0x01, 0x42, 0x1a, 0x00, 0x01, + 0x44, 0x1a, 0x00, 0x01, 0x46, 0x1a, 0x00, 0x01, 0x48, 0x1a, 0x00, 0x01, 0x20, 0x22, 0x01, 0x01, 0x22, 0x22, 0x01, 0x01, 0x24, 0x22, 0x01, 0x01, 0x26, 0x22, 0x01, 0x01, 0x28, 0x22, 0x01, 0x01, + 0x2a, 0x22, 0x01, 0x01, 0x2c, 0x22, 0x01, 0x01, 0x2e, 0x22, 0x01, 0x01, 0x30, 0x22, 0x01, 0x01, 0x32, 0x22, 0x01, 0x01, 0xd4, 0x07, 0x02, 0x02, 0xd8, 0x07, 0x02, 0x02, 0xdc, 0x07, 0x02, 0x02, + 0x00, 0x2b, 0x03, 0x04, 0x60, 0x0d, 0x04, 0x05, 0x4a, 0x1a, 0x00, 0x01, 0x4c, 0x1a, 0x00, 0x01, 0x4e, 0x1a, 0x00, 0x01, 0x50, 0x1a, 0x00, 0x01, 0x52, 0x1a, 0x00, 0x01, 0x54, 0x1a, 0x00, 0x01, + 0x56, 0x1a, 0x00, 0x01, 0x58, 0x1a, 0x00, 0x01, 0x5a, 0x1a, 0x00, 0x01, 0x34, 0x22, 0x01, 0x01, 0x36, 0x22, 0x01, 0x01, 0x38, 0x22, 0x01, 0x01, 0x3a, 0x22, 0x01, 0x01, 0x3c, 0x22, 0x01, 0x01, + 0x3e, 0x22, 0x01, 0x01, 0x40, 0x22, 0x01, 0x01, 0x42, 0x22, 0x01, 0x01, 0x44, 0x22, 0x01, 0x01, 0x46, 0x22, 0x01, 0x01, 0xe0, 0x07, 0x02, 0x02, 0xe4, 0x07, 0x02, 0x02, 0xe8, 0x07, 0x02, 0x02, + 0x10, 0x2b, 0x03, 0x04, 0x80, 0x0d, 0x04, 0x05, 0x5c, 0x1a, 0x00, 0x01, 0x5e, 0x1a, 0x00, 0x01, 0x60, 0x1a, 0x00, 0x01, 0x62, 0x1a, 0x00, 0x01, 0x64, 0x1a, 0x00, 0x01, 0x66, 0x1a, 0x00, 0x01, + 0x68, 0x1a, 0x00, 0x01, 0x6a, 0x1a, 0x00, 0x01, 0x6c, 0x1a, 0x00, 0x01, 0x48, 0x22, 0x01, 0x01, 0x4a, 0x22, 0x01, 0x01, 0x4c, 0x22, 0x01, 0x01, 0x4e, 0x22, 0x01, 0x01, 0x50, 0x22, 0x01, 0x01, + 0x52, 0x22, 0x01, 0x01, 0x54, 0x22, 0x01, 0x01, 0x56, 0x22, 0x01, 0x01, 0x58, 0x22, 0x01, 0x01, 0x5a, 0x22, 0x01, 0x01, 0xec, 0x07, 0x02, 0x02, 0xf0, 0x07, 0x02, 0x02, 0xf4, 0x07, 0x02, 0x02, + 0x20, 0x2b, 0x03, 0x04, 0xa0, 0x0d, 0x04, 0x05, 0x6e, 0x1a, 0x00, 0x01, 0x70, 0x1a, 0x00, 0x01, 0x72, 0x1a, 0x00, 0x01, 0x74, 0x1a, 0x00, 0x01, 0x76, 0x1a, 0x00, 0x01, 0x78, 0x1a, 0x00, 0x01, + 0x7a, 0x1a, 0x00, 0x01, 0x7c, 0x1a, 0x00, 0x01, 0x7e, 0x1a, 0x00, 0x01, 0x5c, 0x22, 0x01, 0x01, 0x5e, 0x22, 0x01, 0x01, 0x60, 0x22, 0x01, 0x01, 0x62, 0x22, 0x01, 0x01, 0x64, 0x22, 0x01, 0x01, + 0x66, 0x22, 0x01, 0x01, 0x68, 0x22, 0x01, 0x01, 0x6a, 0x22, 0x01, 0x01, 0x6c, 0x22, 0x01, 0x01, 0xf8, 0x07, 0x02, 0x02, 0xfc, 0x07, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x04, 0x08, 0x02, 0x02, + 0x30, 0x2b, 0x03, 0x04, 0xc0, 0x0d, 0x04, 0x05, 0x80, 0x1a, 0x00, 0x01, 0x82, 0x1a, 0x00, 0x01, 0x84, 0x1a, 0x00, 0x01, 0x86, 0x1a, 0x00, 0x01, 0x88, 0x1a, 0x00, 0x01, 0x8a, 0x1a, 0x00, 0x01, + 0x8c, 0x1a, 0x00, 0x01, 0x8e, 0x1a, 0x00, 0x01, 0x90, 0x1a, 0x00, 0x01, 0x6e, 0x22, 0x01, 0x01, 0x70, 0x22, 0x01, 0x01, 0x72, 0x22, 0x01, 0x01, 0x74, 0x22, 0x01, 0x01, 0x76, 0x22, 0x01, 0x01, + 0x78, 0x22, 0x01, 0x01, 0x7a, 0x22, 0x01, 0x01, 0x7c, 0x22, 0x01, 0x01, 0x7e, 0x22, 0x01, 0x01, 0x08, 0x08, 0x02, 0x02, 0x0c, 0x08, 0x02, 0x02, 0x10, 0x08, 0x02, 0x02, 0x14, 0x08, 0x02, 0x02, + 0x40, 0x2b, 0x03, 0x04, 0xe0, 0x0d, 0x04, 0x05, 0x92, 0x1a, 0x00, 0x01, 0x94, 0x1a, 0x00, 0x01, 0x96, 0x1a, 0x00, 0x01, 0x98, 0x1a, 0x00, 0x01, 0x9a, 0x1a, 0x00, 0x01, 0x9c, 0x1a, 0x00, 0x01, + 0x9e, 0x1a, 0x00, 0x01, 0xa0, 0x1a, 0x00, 0x01, 0xa2, 0x1a, 0x00, 0x01, 0x80, 0x22, 0x01, 0x01, 0x82, 0x22, 0x01, 0x01, 0x84, 0x22, 0x01, 0x01, 0x86, 0x22, 0x01, 0x01, 0x88, 0x22, 0x01, 0x01, + 0x8a, 0x22, 0x01, 0x01, 0x8c, 0x22, 0x01, 0x01, 0x8e, 0x22, 0x01, 0x01, 0x90, 0x22, 0x01, 0x01, 0x18, 0x08, 0x02, 0x02, 0x1c, 0x08, 0x02, 0x02, 0x20, 0x08, 0x02, 0x02, 0x24, 0x08, 0x02, 0x02, + 0x50, 0x2b, 0x03, 0x04, 0x00, 0x0e, 0x04, 0x05, 0xa4, 0x1a, 0x00, 0x01, 0xa6, 0x1a, 0x00, 0x01, 0xa8, 0x1a, 0x00, 0x01, 0xaa, 0x1a, 0x00, 0x01, 0xac, 0x1a, 0x00, 0x01, 0xae, 0x1a, 0x00, 0x01, + 0xb0, 0x1a, 0x00, 0x01, 0xb2, 0x1a, 0x00, 0x01, 0xb4, 0x1a, 0x00, 0x01, 0x92, 0x22, 0x01, 0x01, 0x94, 0x22, 0x01, 0x01, 0x96, 0x22, 0x01, 0x01, 0x98, 0x22, 0x01, 0x01, 0x9a, 0x22, 0x01, 0x01, + 0x9c, 0x22, 0x01, 0x01, 0x9e, 0x22, 0x01, 0x01, 0xa0, 0x22, 0x01, 0x01, 0xa2, 0x22, 0x01, 0x01, 0x28, 0x08, 0x02, 0x02, 0x2c, 0x08, 0x02, 0x02, 0x30, 0x08, 0x02, 0x02, 0x34, 0x08, 0x02, 0x02, + 0x60, 0x2b, 0x03, 0x04, 0x20, 0x0e, 0x04, 0x05, 0xb6, 0x1a, 0x00, 0x01, 0xb8, 0x1a, 0x00, 0x01, 0xba, 0x1a, 0x00, 0x01, 0xbc, 0x1a, 0x00, 0x01, 0xbe, 0x1a, 0x00, 0x01, 0xc0, 0x1a, 0x00, 0x01, + 0xc2, 0x1a, 0x00, 0x01, 0xc4, 0x1a, 0x00, 0x01, 0xc6, 0x1a, 0x00, 0x01, 0xa4, 0x22, 0x01, 0x01, 0xa6, 0x22, 0x01, 0x01, 0xa8, 0x22, 0x01, 0x01, 0xaa, 0x22, 0x01, 0x01, 0xac, 0x22, 0x01, 0x01, + 0xae, 0x22, 0x01, 0x01, 0xb0, 0x22, 0x01, 0x01, 0xb2, 0x22, 0x01, 0x01, 0xb4, 0x22, 0x01, 0x01, 0x38, 0x08, 0x02, 0x02, 0x3c, 0x08, 0x02, 0x02, 0x40, 0x08, 0x02, 0x02, 0x44, 0x08, 0x02, 0x02, + 0x70, 0x2b, 0x03, 0x04, 0x40, 0x0e, 0x04, 0x05, 0xc8, 0x1a, 0x00, 0x01, 0xca, 0x1a, 0x00, 0x01, 0xcc, 0x1a, 0x00, 0x01, 0xce, 0x1a, 0x00, 0x01, 0xd0, 0x1a, 0x00, 0x01, 0xd2, 0x1a, 0x00, 0x01, + 0xd4, 0x1a, 0x00, 0x01, 0xd6, 0x1a, 0x00, 0x01, 0xd8, 0x1a, 0x00, 0x01, 0xb6, 0x22, 0x01, 0x01, 0xb8, 0x22, 0x01, 0x01, 0xba, 0x22, 0x01, 0x01, 0xbc, 0x22, 0x01, 0x01, 0xbe, 0x22, 0x01, 0x01, + 0xc0, 0x22, 0x01, 0x01, 0xc2, 0x22, 0x01, 0x01, 0xc4, 0x22, 0x01, 0x01, 0xc6, 0x22, 0x01, 0x01, 0x48, 0x08, 0x02, 0x02, 0x4c, 0x08, 0x02, 0x02, 0x50, 0x08, 0x02, 0x02, 0x54, 0x08, 0x02, 0x02, + 0x80, 0x2b, 0x03, 0x04, 0x60, 0x0e, 0x04, 0x05, 0xda, 0x1a, 0x00, 0x01, 0xdc, 0x1a, 0x00, 0x01, 0xde, 0x1a, 0x00, 0x01, 0xe0, 0x1a, 0x00, 0x01, 0xe2, 0x1a, 0x00, 0x01, 0xe4, 0x1a, 0x00, 0x01, + 0xe6, 0x1a, 0x00, 0x01, 0xe8, 0x1a, 0x00, 0x01, 0xea, 0x1a, 0x00, 0x01, 0xc8, 0x22, 0x01, 0x01, 0xca, 0x22, 0x01, 0x01, 0xcc, 0x22, 0x01, 0x01, 0xce, 0x22, 0x01, 0x01, 0xd0, 0x22, 0x01, 0x01, + 0xd2, 0x22, 0x01, 0x01, 0xd4, 0x22, 0x01, 0x01, 0xd6, 0x22, 0x01, 0x01, 0xd8, 0x22, 0x01, 0x01, 0x58, 0x08, 0x02, 0x02, 0x5c, 0x08, 0x02, 0x02, 0x60, 0x08, 0x02, 0x02, 0x64, 0x08, 0x02, 0x02, + 0x90, 0x2b, 0x03, 0x04, 0x80, 0x0e, 0x04, 0x05, 0xec, 0x1a, 0x00, 0x01, 0xee, 0x1a, 0x00, 0x01, 0xf0, 0x1a, 0x00, 0x01, 0xf2, 0x1a, 0x00, 0x01, 0xf4, 0x1a, 0x00, 0x01, 0xf6, 0x1a, 0x00, 0x01, + 0xf8, 0x1a, 0x00, 0x01, 0xfa, 0x1a, 0x00, 0x01, 0xfc, 0x1a, 0x00, 0x01, 0xda, 0x22, 0x01, 0x01, 0xdc, 0x22, 0x01, 0x01, 0xde, 0x22, 0x01, 0x01, 0xe0, 0x22, 0x01, 0x01, 0xe2, 0x22, 0x01, 0x01, + 0xe4, 0x22, 0x01, 0x01, 0xe6, 0x22, 0x01, 0x01, 0xe8, 0x22, 0x01, 0x01, 0xea, 0x22, 0x01, 0x01, 0x68, 0x08, 0x02, 0x02, 0x6c, 0x08, 0x02, 0x02, 0x70, 0x08, 0x02, 0x02, 0x74, 0x08, 0x02, 0x02, + 0xa0, 0x2b, 0x03, 0x04, 0xa0, 0x0e, 0x04, 0x05, 0xfe, 0x1a, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x01, 0x02, 0x1b, 0x00, 0x01, 0x04, 0x1b, 0x00, 0x01, 0x06, 0x1b, 0x00, 0x01, 0x08, 0x1b, 0x00, 0x01, + 0x0a, 0x1b, 0x00, 0x01, 0x0c, 0x1b, 0x00, 0x01, 0x0e, 0x1b, 0x00, 0x01, 0xec, 0x22, 0x01, 0x01, 0xee, 0x22, 0x01, 0x01, 0xf0, 0x22, 0x01, 0x01, 0xf2, 0x22, 0x01, 0x01, 0xf4, 0x22, 0x01, 0x01, + 0xf6, 0x22, 0x01, 0x01, 0xf8, 0x22, 0x01, 0x01, 0xfa, 0x22, 0x01, 0x01, 0xfc, 0x22, 0x01, 0x01, 0x78, 0x08, 0x02, 0x02, 0x7c, 0x08, 0x02, 0x02, 0x80, 0x08, 0x02, 0x02, 0x84, 0x08, 0x02, 0x02, + 0xb0, 0x2b, 0x03, 0x04, 0xc0, 0x0e, 0x04, 0x05, 0x10, 0x1b, 0x00, 0x01, 0x12, 0x1b, 0x00, 0x01, 0x14, 0x1b, 0x00, 0x01, 0x16, 0x1b, 0x00, 0x01, 0x18, 0x1b, 0x00, 0x01, 0x1a, 0x1b, 0x00, 0x01, + 0x1c, 0x1b, 0x00, 0x01, 0x1e, 0x1b, 0x00, 0x01, 0x20, 0x1b, 0x00, 0x01, 0xfe, 0x22, 0x01, 0x01, 0x00, 0x23, 0x01, 0x01, 0x02, 0x23, 0x01, 0x01, 0x04, 0x23, 0x01, 0x01, 0x06, 0x23, 0x01, 0x01, + 0x08, 0x23, 0x01, 0x01, 0x0a, 0x23, 0x01, 0x01, 0x0c, 0x23, 0x01, 0x01, 0x0e, 0x23, 0x01, 0x01, 0x88, 0x08, 0x02, 0x02, 0x8c, 0x08, 0x02, 0x02, 0x90, 0x08, 0x02, 0x02, 0x94, 0x08, 0x02, 0x02, + 0xc0, 0x2b, 0x03, 0x04, 0xe0, 0x0e, 0x04, 0x05, 0x22, 0x1b, 0x00, 0x01, 0x24, 0x1b, 0x00, 0x01, 0x26, 0x1b, 0x00, 0x01, 0x28, 0x1b, 0x00, 0x01, 0x2a, 0x1b, 0x00, 0x01, 0x2c, 0x1b, 0x00, 0x01, + 0x2e, 0x1b, 0x00, 0x01, 0x30, 0x1b, 0x00, 0x01, 0x32, 0x1b, 0x00, 0x01, 0x10, 0x23, 0x01, 0x01, 0x12, 0x23, 0x01, 0x01, 0x14, 0x23, 0x01, 0x01, 0x16, 0x23, 0x01, 0x01, 0x18, 0x23, 0x01, 0x01, + 0x1a, 0x23, 0x01, 0x01, 0x1c, 0x23, 0x01, 0x01, 0x1e, 0x23, 0x01, 0x01, 0x20, 0x23, 0x01, 0x01, 0x98, 0x08, 0x02, 0x02, 0x9c, 0x08, 0x02, 0x02, 0xa0, 0x08, 0x02, 0x02, 0xa4, 0x08, 0x02, 0x02, + 0xd0, 0x2b, 0x03, 0x04, 0x00, 0x0f, 0x04, 0x05, 0x34, 0x1b, 0x00, 0x01, 0x36, 0x1b, 0x00, 0x01, 0x38, 0x1b, 0x00, 0x01, 0x3a, 0x1b, 0x00, 0x01, 0x3c, 0x1b, 0x00, 0x01, 0x3e, 0x1b, 0x00, 0x01, + 0x40, 0x1b, 0x00, 0x01, 0x42, 0x1b, 0x00, 0x01, 0x44, 0x1b, 0x00, 0x01, 0x22, 0x23, 0x01, 0x01, 0x24, 0x23, 0x01, 0x01, 0x26, 0x23, 0x01, 0x01, 0x28, 0x23, 0x01, 0x01, 0x2a, 0x23, 0x01, 0x01, + 0x2c, 0x23, 0x01, 0x01, 0x2e, 0x23, 0x01, 0x01, 0x30, 0x23, 0x01, 0x01, 0x32, 0x23, 0x01, 0x01, 0xa8, 0x08, 0x02, 0x02, 0xac, 0x08, 0x02, 0x02, 0xb0, 0x08, 0x02, 0x02, 0xb4, 0x08, 0x02, 0x02, + 0xe0, 0x2b, 0x03, 0x04, 0x20, 0x0f, 0x04, 0x05, 0x46, 0x1b, 0x00, 0x01, 0x48, 0x1b, 0x00, 0x01, 0x4a, 0x1b, 0x00, 0x01, 0x4c, 0x1b, 0x00, 0x01, 0x4e, 0x1b, 0x00, 0x01, 0x50, 0x1b, 0x00, 0x01, + 0x52, 0x1b, 0x00, 0x01, 0x54, 0x1b, 0x00, 0x01, 0x56, 0x1b, 0x00, 0x01, 0x34, 0x23, 0x01, 0x01, 0x36, 0x23, 0x01, 0x01, 0x38, 0x23, 0x01, 0x01, 0x3a, 0x23, 0x01, 0x01, 0x3c, 0x23, 0x01, 0x01, + 0x3e, 0x23, 0x01, 0x01, 0x40, 0x23, 0x01, 0x01, 0x42, 0x23, 0x01, 0x01, 0x44, 0x23, 0x01, 0x01, 0xb8, 0x08, 0x02, 0x02, 0xbc, 0x08, 0x02, 0x02, 0xc0, 0x08, 0x02, 0x02, 0xc4, 0x08, 0x02, 0x02, + 0xf0, 0x2b, 0x03, 0x04, 0x40, 0x0f, 0x04, 0x05, 0x58, 0x1b, 0x00, 0x01, 0x5a, 0x1b, 0x00, 0x01, 0x5c, 0x1b, 0x00, 0x01, 0x5e, 0x1b, 0x00, 0x01, 0x60, 0x1b, 0x00, 0x01, 0x62, 0x1b, 0x00, 0x01, + 0x64, 0x1b, 0x00, 0x01, 0x66, 0x1b, 0x00, 0x01, 0x68, 0x1b, 0x00, 0x01, 0x46, 0x23, 0x01, 0x01, 0x48, 0x23, 0x01, 0x01, 0x4a, 0x23, 0x01, 0x01, 0x4c, 0x23, 0x01, 0x01, 0x4e, 0x23, 0x01, 0x01, + 0x50, 0x23, 0x01, 0x01, 0x52, 0x23, 0x01, 0x01, 0x54, 0x23, 0x01, 0x01, 0x56, 0x23, 0x01, 0x01, 0xc8, 0x08, 0x02, 0x02, 0xcc, 0x08, 0x02, 0x02, 0xd0, 0x08, 0x02, 0x02, 0xd4, 0x08, 0x02, 0x02, + 0x00, 0x2c, 0x03, 0x04, 0x60, 0x0f, 0x04, 0x05, 0x6a, 0x1b, 0x00, 0x01, 0x6c, 0x1b, 0x00, 0x01, 0x6e, 0x1b, 0x00, 0x01, 0x70, 0x1b, 0x00, 0x01, 0x72, 0x1b, 0x00, 0x01, 0x74, 0x1b, 0x00, 0x01, + 0x76, 0x1b, 0x00, 0x01, 0x78, 0x1b, 0x00, 0x01, 0x7a, 0x1b, 0x00, 0x01, 0x58, 0x23, 0x01, 0x01, 0x5a, 0x23, 0x01, 0x01, 0x5c, 0x23, 0x01, 0x01, 0x5e, 0x23, 0x01, 0x01, 0x60, 0x23, 0x01, 0x01, + 0x62, 0x23, 0x01, 0x01, 0x64, 0x23, 0x01, 0x01, 0x66, 0x23, 0x01, 0x01, 0x68, 0x23, 0x01, 0x01, 0xd8, 0x08, 0x02, 0x02, 0xdc, 0x08, 0x02, 0x02, 0xe0, 0x08, 0x02, 0x02, 0xe4, 0x08, 0x02, 0x02, + 0x10, 0x2c, 0x03, 0x04, 0x80, 0x0f, 0x04, 0x05, 0x7c, 0x1b, 0x00, 0x01, 0x7e, 0x1b, 0x00, 0x01, 0x80, 0x1b, 0x00, 0x01, 0x82, 0x1b, 0x00, 0x01, 0x84, 0x1b, 0x00, 0x01, 0x86, 0x1b, 0x00, 0x01, + 0x88, 0x1b, 0x00, 0x01, 0x8a, 0x1b, 0x00, 0x01, 0x8c, 0x1b, 0x00, 0x01, 0x6a, 0x23, 0x01, 0x01, 0x6c, 0x23, 0x01, 0x01, 0x6e, 0x23, 0x01, 0x01, 0x70, 0x23, 0x01, 0x01, 0x72, 0x23, 0x01, 0x01, + 0x74, 0x23, 0x01, 0x01, 0x76, 0x23, 0x01, 0x01, 0x78, 0x23, 0x01, 0x01, 0x7a, 0x23, 0x01, 0x01, 0xe8, 0x08, 0x02, 0x02, 0xec, 0x08, 0x02, 0x02, 0xf0, 0x08, 0x02, 0x02, 0xf4, 0x08, 0x02, 0x02, + 0x20, 0x2c, 0x03, 0x04, 0xa0, 0x0f, 0x04, 0x05, 0x8e, 0x1b, 0x00, 0x01, 0x90, 0x1b, 0x00, 0x01, 0x92, 0x1b, 0x00, 0x01, 0x94, 0x1b, 0x00, 0x01, 0x96, 0x1b, 0x00, 0x01, 0x98, 0x1b, 0x00, 0x01, + 0x9a, 0x1b, 0x00, 0x01, 0x9c, 0x1b, 0x00, 0x01, 0x9e, 0x1b, 0x00, 0x01, 0x7c, 0x23, 0x01, 0x01, 0x7e, 0x23, 0x01, 0x01, 0x80, 0x23, 0x01, 0x01, 0x82, 0x23, 0x01, 0x01, 0x84, 0x23, 0x01, 0x01, + 0x86, 0x23, 0x01, 0x01, 0x88, 0x23, 0x01, 0x01, 0x8a, 0x23, 0x01, 0x01, 0x8c, 0x23, 0x01, 0x01, 0xf8, 0x08, 0x02, 0x02, 0xfc, 0x08, 0x02, 0x02, 0x00, 0x09, 0x02, 0x02, 0x04, 0x09, 0x02, 0x02, + 0x30, 0x2c, 0x03, 0x04, 0xc0, 0x0f, 0x04, 0x05, 0xa0, 0x1b, 0x00, 0x01, 0xa2, 0x1b, 0x00, 0x01, 0xa4, 0x1b, 0x00, 0x01, 0xa6, 0x1b, 0x00, 0x01, 0xa8, 0x1b, 0x00, 0x01, 0xaa, 0x1b, 0x00, 0x01, + 0xac, 0x1b, 0x00, 0x01, 0xae, 0x1b, 0x00, 0x01, 0xb0, 0x1b, 0x00, 0x01, 0x8e, 0x23, 0x01, 0x01, 0x90, 0x23, 0x01, 0x01, 0x92, 0x23, 0x01, 0x01, 0x94, 0x23, 0x01, 0x01, 0x96, 0x23, 0x01, 0x01, + 0x98, 0x23, 0x01, 0x01, 0x9a, 0x23, 0x01, 0x01, 0x9c, 0x23, 0x01, 0x01, 0x9e, 0x23, 0x01, 0x01, 0x08, 0x09, 0x02, 0x02, 0x0c, 0x09, 0x02, 0x02, 0x10, 0x09, 0x02, 0x02, 0x14, 0x09, 0x02, 0x02, + 0x40, 0x2c, 0x03, 0x04, 0xe0, 0x0f, 0x04, 0x05, 0xb2, 0x1b, 0x00, 0x01, 0xb4, 0x1b, 0x00, 0x01, 0xb6, 0x1b, 0x00, 0x01, 0xb8, 0x1b, 0x00, 0x01, 0xba, 0x1b, 0x00, 0x01, 0xbc, 0x1b, 0x00, 0x01, + 0xbe, 0x1b, 0x00, 0x01, 0xc0, 0x1b, 0x00, 0x01, 0xc2, 0x1b, 0x00, 0x01, 0xa0, 0x23, 0x01, 0x01, 0xa2, 0x23, 0x01, 0x01, 0xa4, 0x23, 0x01, 0x01, 0xa6, 0x23, 0x01, 0x01, 0xa8, 0x23, 0x01, 0x01, + 0xaa, 0x23, 0x01, 0x01, 0xac, 0x23, 0x01, 0x01, 0xae, 0x23, 0x01, 0x01, 0xb0, 0x23, 0x01, 0x01, 0x18, 0x09, 0x02, 0x02, 0x1c, 0x09, 0x02, 0x02, 0x20, 0x09, 0x02, 0x02, 0x24, 0x09, 0x02, 0x02, + 0x50, 0x2c, 0x03, 0x04, 0x00, 0x10, 0x04, 0x05, 0xc4, 0x1b, 0x00, 0x01, 0xc6, 0x1b, 0x00, 0x01, 0xc8, 0x1b, 0x00, 0x01, 0xca, 0x1b, 0x00, 0x01, 0xcc, 0x1b, 0x00, 0x01, 0xce, 0x1b, 0x00, 0x01, + 0xd0, 0x1b, 0x00, 0x01, 0xd2, 0x1b, 0x00, 0x01, 0xd4, 0x1b, 0x00, 0x01, 0xb2, 0x23, 0x01, 0x01, 0xb4, 0x23, 0x01, 0x01, 0xb6, 0x23, 0x01, 0x01, 0xb8, 0x23, 0x01, 0x01, 0xba, 0x23, 0x01, 0x01, + 0xbc, 0x23, 0x01, 0x01, 0xbe, 0x23, 0x01, 0x01, 0xc0, 0x23, 0x01, 0x01, 0xc2, 0x23, 0x01, 0x01, 0x28, 0x09, 0x02, 0x02, 0x2c, 0x09, 0x02, 0x02, 0x30, 0x09, 0x02, 0x02, 0x34, 0x09, 0x02, 0x02, + 0x60, 0x2c, 0x03, 0x04, 0x20, 0x10, 0x04, 0x05, 0xd6, 0x1b, 0x00, 0x01, 0xd8, 0x1b, 0x00, 0x01, 0xda, 0x1b, 0x00, 0x01, 0xdc, 0x1b, 0x00, 0x01, 0xde, 0x1b, 0x00, 0x01, 0xe0, 0x1b, 0x00, 0x01, + 0xe2, 0x1b, 0x00, 0x01, 0xe4, 0x1b, 0x00, 0x01, 0xe6, 0x1b, 0x00, 0x01, 0xc4, 0x23, 0x01, 0x01, 0xc6, 0x23, 0x01, 0x01, 0xc8, 0x23, 0x01, 0x01, 0xca, 0x23, 0x01, 0x01, 0xcc, 0x23, 0x01, 0x01, + 0xce, 0x23, 0x01, 0x01, 0xd0, 0x23, 0x01, 0x01, 0xd2, 0x23, 0x01, 0x01, 0xd4, 0x23, 0x01, 0x01, 0x38, 0x09, 0x02, 0x02, 0x3c, 0x09, 0x02, 0x02, 0x40, 0x09, 0x02, 0x02, 0x44, 0x09, 0x02, 0x02, + 0x70, 0x2c, 0x03, 0x04, 0x40, 0x10, 0x04, 0x05, 0xe8, 0x1b, 0x00, 0x01, 0xea, 0x1b, 0x00, 0x01, 0xec, 0x1b, 0x00, 0x01, 0xee, 0x1b, 0x00, 0x01, 0xf0, 0x1b, 0x00, 0x01, 0xf2, 0x1b, 0x00, 0x01, + 0xf4, 0x1b, 0x00, 0x01, 0xf6, 0x1b, 0x00, 0x01, 0xf8, 0x1b, 0x00, 0x01, 0xd6, 0x23, 0x01, 0x01, 0xd8, 0x23, 0x01, 0x01, 0xda, 0x23, 0x01, 0x01, 0xdc, 0x23, 0x01, 0x01, 0xde, 0x23, 0x01, 0x01, + 0xe0, 0x23, 0x01, 0x01, 0xe2, 0x23, 0x01, 0x01, 0xe4, 0x23, 0x01, 0x01, 0xe6, 0x23, 0x01, 0x01, 0x48, 0x09, 0x02, 0x02, 0x4c, 0x09, 0x02, 0x02, 0x50, 0x09, 0x02, 0x02, 0x54, 0x09, 0x02, 0x02, + 0x80, 0x2c, 0x03, 0x04, 0x60, 0x10, 0x04, 0x05, 0xfa, 0x1b, 0x00, 0x01, 0xfc, 0x1b, 0x00, 0x01, 0xfe, 0x1b, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x01, 0x02, 0x1c, 0x00, 0x01, 0x04, 0x1c, 0x00, 0x01, + 0x06, 0x1c, 0x00, 0x01, 0x08, 0x1c, 0x00, 0x01, 0x0a, 0x1c, 0x00, 0x01, 0xe8, 0x23, 0x01, 0x01, 0xea, 0x23, 0x01, 0x01, 0xec, 0x23, 0x01, 0x01, 0xee, 0x23, 0x01, 0x01, 0xf0, 0x23, 0x01, 0x01, + 0xf2, 0x23, 0x01, 0x01, 0xf4, 0x23, 0x01, 0x01, 0xf6, 0x23, 0x01, 0x01, 0xf8, 0x23, 0x01, 0x01, 0x58, 0x09, 0x02, 0x02, 0x5c, 0x09, 0x02, 0x02, 0x60, 0x09, 0x02, 0x02, 0x64, 0x09, 0x02, 0x02, + 0x90, 0x2c, 0x03, 0x04, 0x80, 0x10, 0x04, 0x05, 0x0c, 0x1c, 0x00, 0x01, 0x0e, 0x1c, 0x00, 0x01, 0x10, 0x1c, 0x00, 0x01, 0x12, 0x1c, 0x00, 0x01, 0x14, 0x1c, 0x00, 0x01, 0x16, 0x1c, 0x00, 0x01, + 0x18, 0x1c, 0x00, 0x01, 0x1a, 0x1c, 0x00, 0x01, 0x1c, 0x1c, 0x00, 0x01, 0xfa, 0x23, 0x01, 0x01, 0xfc, 0x23, 0x01, 0x01, 0xfe, 0x23, 0x01, 0x01, 0x00, 0x24, 0x01, 0x01, 0x02, 0x24, 0x01, 0x01, + 0x04, 0x24, 0x01, 0x01, 0x06, 0x24, 0x01, 0x01, 0x08, 0x24, 0x01, 0x01, 0x0a, 0x24, 0x01, 0x01, 0x68, 0x09, 0x02, 0x02, 0x6c, 0x09, 0x02, 0x02, 0x70, 0x09, 0x02, 0x02, 0x74, 0x09, 0x02, 0x02, + 0xa0, 0x2c, 0x03, 0x04, 0xa0, 0x10, 0x04, 0x05, 0x1e, 0x1c, 0x00, 0x01, 0x20, 0x1c, 0x00, 0x01, 0x22, 0x1c, 0x00, 0x01, 0x24, 0x1c, 0x00, 0x01, 0x26, 0x1c, 0x00, 0x01, 0x28, 0x1c, 0x00, 0x01, + 0x2a, 0x1c, 0x00, 0x01, 0x2c, 0x1c, 0x00, 0x01, 0x2e, 0x1c, 0x00, 0x01, 0x0c, 0x24, 0x01, 0x01, 0x0e, 0x24, 0x01, 0x01, 0x10, 0x24, 0x01, 0x01, 0x12, 0x24, 0x01, 0x01, 0x14, 0x24, 0x01, 0x01, + 0x16, 0x24, 0x01, 0x01, 0x18, 0x24, 0x01, 0x01, 0x1a, 0x24, 0x01, 0x01, 0x1c, 0x24, 0x01, 0x01, 0x78, 0x09, 0x02, 0x02, 0x7c, 0x09, 0x02, 0x02, 0x80, 0x09, 0x02, 0x02, 0x84, 0x09, 0x02, 0x02, + 0xb0, 0x2c, 0x03, 0x04, 0xc0, 0x10, 0x04, 0x05, 0x30, 0x1c, 0x00, 0x01, 0x32, 0x1c, 0x00, 0x01, 0x34, 0x1c, 0x00, 0x01, 0x36, 0x1c, 0x00, 0x01, 0x38, 0x1c, 0x00, 0x01, 0x3a, 0x1c, 0x00, 0x01, + 0x3c, 0x1c, 0x00, 0x01, 0x3e, 0x1c, 0x00, 0x01, 0x40, 0x1c, 0x00, 0x01, 0x1e, 0x24, 0x01, 0x01, 0x20, 0x24, 0x01, 0x01, 0x22, 0x24, 0x01, 0x01, 0x24, 0x24, 0x01, 0x01, 0x26, 0x24, 0x01, 0x01, + 0x28, 0x24, 0x01, 0x01, 0x2a, 0x24, 0x01, 0x01, 0x2c, 0x24, 0x01, 0x01, 0x2e, 0x24, 0x01, 0x01, 0x88, 0x09, 0x02, 0x02, 0x8c, 0x09, 0x02, 0x02, 0x90, 0x09, 0x02, 0x02, 0x94, 0x09, 0x02, 0x02, + 0xc0, 0x2c, 0x03, 0x04, 0xe0, 0x10, 0x04, 0x05, 0x42, 0x1c, 0x00, 0x01, 0x44, 0x1c, 0x00, 0x01, 0x46, 0x1c, 0x00, 0x01, 0x48, 0x1c, 0x00, 0x01, 0x4a, 0x1c, 0x00, 0x01, 0x4c, 0x1c, 0x00, 0x01, + 0x4e, 0x1c, 0x00, 0x01, 0x50, 0x1c, 0x00, 0x01, 0x52, 0x1c, 0x00, 0x01, 0x30, 0x24, 0x01, 0x01, 0x32, 0x24, 0x01, 0x01, 0x34, 0x24, 0x01, 0x01, 0x36, 0x24, 0x01, 0x01, 0x38, 0x24, 0x01, 0x01, + 0x3a, 0x24, 0x01, 0x01, 0x3c, 0x24, 0x01, 0x01, 0x3e, 0x24, 0x01, 0x01, 0x40, 0x24, 0x01, 0x01, 0x98, 0x09, 0x02, 0x02, 0x9c, 0x09, 0x02, 0x02, 0xa0, 0x09, 0x02, 0x02, 0xa4, 0x09, 0x02, 0x02, + 0xd0, 0x2c, 0x03, 0x04, 0x00, 0x30, 0x05, 0x07, 0x54, 0x1c, 0x00, 0x01, 0x56, 0x1c, 0x00, 0x01, 0x58, 0x1c, 0x00, 0x01, 0x5a, 0x1c, 0x00, 0x01, 0x5c, 0x1c, 0x00, 0x01, 0x5e, 0x1c, 0x00, 0x01, + 0x60, 0x1c, 0x00, 0x01, 0x62, 0x1c, 0x00, 0x01, 0x64, 0x1c, 0x00, 0x01, 0x42, 0x24, 0x01, 0x01, 0x44, 0x24, 0x01, 0x01, 0x46, 0x24, 0x01, 0x01, 0x48, 0x24, 0x01, 0x01, 0x4a, 0x24, 0x01, 0x01, + 0x4c, 0x24, 0x01, 0x01, 0x4e, 0x24, 0x01, 0x01, 0x50, 0x24, 0x01, 0x01, 0x52, 0x24, 0x01, 0x01, 0xa8, 0x09, 0x02, 0x02, 0xac, 0x09, 0x02, 0x02, 0xb0, 0x09, 0x02, 0x02, 0xb4, 0x09, 0x02, 0x02, + 0xe0, 0x2c, 0x03, 0x04, 0x80, 0x30, 0x05, 0x07, 0x66, 0x1c, 0x00, 0x01, 0x68, 0x1c, 0x00, 0x01, 0x6a, 0x1c, 0x00, 0x01, 0x6c, 0x1c, 0x00, 0x01, 0x6e, 0x1c, 0x00, 0x01, 0x70, 0x1c, 0x00, 0x01, + 0x72, 0x1c, 0x00, 0x01, 0x74, 0x1c, 0x00, 0x01, 0x76, 0x1c, 0x00, 0x01, 0x54, 0x24, 0x01, 0x01, 0x56, 0x24, 0x01, 0x01, 0x58, 0x24, 0x01, 0x01, 0x5a, 0x24, 0x01, 0x01, 0x5c, 0x24, 0x01, 0x01, + 0x5e, 0x24, 0x01, 0x01, 0x60, 0x24, 0x01, 0x01, 0x62, 0x24, 0x01, 0x01, 0x64, 0x24, 0x01, 0x01, 0xb8, 0x09, 0x02, 0x02, 0xbc, 0x09, 0x02, 0x02, 0xc0, 0x09, 0x02, 0x02, 0xc4, 0x09, 0x02, 0x02, + 0xf0, 0x2c, 0x03, 0x04, 0x00, 0x31, 0x05, 0x07, 0x78, 0x1c, 0x00, 0x01, 0x7a, 0x1c, 0x00, 0x01, 0x7c, 0x1c, 0x00, 0x01, 0x7e, 0x1c, 0x00, 0x01, 0x80, 0x1c, 0x00, 0x01, 0x82, 0x1c, 0x00, 0x01, + 0x84, 0x1c, 0x00, 0x01, 0x86, 0x1c, 0x00, 0x01, 0x88, 0x1c, 0x00, 0x01, 0x66, 0x24, 0x01, 0x01, 0x68, 0x24, 0x01, 0x01, 0x6a, 0x24, 0x01, 0x01, 0x6c, 0x24, 0x01, 0x01, 0x6e, 0x24, 0x01, 0x01, + 0x70, 0x24, 0x01, 0x01, 0x72, 0x24, 0x01, 0x01, 0x74, 0x24, 0x01, 0x01, 0x76, 0x24, 0x01, 0x01, 0xc8, 0x09, 0x02, 0x02, 0xcc, 0x09, 0x02, 0x02, 0xd0, 0x09, 0x02, 0x02, 0xd4, 0x09, 0x02, 0x02, + 0x00, 0x2d, 0x03, 0x04, 0x80, 0x31, 0x05, 0x07, 0x8a, 0x1c, 0x00, 0x01, 0x8c, 0x1c, 0x00, 0x01, 0x8e, 0x1c, 0x00, 0x01, 0x90, 0x1c, 0x00, 0x01, 0x92, 0x1c, 0x00, 0x01, 0x94, 0x1c, 0x00, 0x01, + 0x96, 0x1c, 0x00, 0x01, 0x98, 0x1c, 0x00, 0x01, 0x9a, 0x1c, 0x00, 0x01, 0x78, 0x24, 0x01, 0x01, 0x7a, 0x24, 0x01, 0x01, 0x7c, 0x24, 0x01, 0x01, 0x7e, 0x24, 0x01, 0x01, 0x80, 0x24, 0x01, 0x01, + 0x82, 0x24, 0x01, 0x01, 0x84, 0x24, 0x01, 0x01, 0x86, 0x24, 0x01, 0x01, 0x88, 0x24, 0x01, 0x01, 0xd8, 0x09, 0x02, 0x02, 0xdc, 0x09, 0x02, 0x02, 0xe0, 0x09, 0x02, 0x02, 0xe4, 0x09, 0x02, 0x02, + 0x10, 0x2d, 0x03, 0x04, 0x00, 0x32, 0x05, 0x07, 0x9c, 0x1c, 0x00, 0x01, 0x9e, 0x1c, 0x00, 0x01, 0xa0, 0x1c, 0x00, 0x01, 0xa2, 0x1c, 0x00, 0x01, 0xa4, 0x1c, 0x00, 0x01, 0xa6, 0x1c, 0x00, 0x01, + 0xa8, 0x1c, 0x00, 0x01, 0xaa, 0x1c, 0x00, 0x01, 0xac, 0x1c, 0x00, 0x01, 0x8a, 0x24, 0x01, 0x01, 0x8c, 0x24, 0x01, 0x01, 0x8e, 0x24, 0x01, 0x01, 0x90, 0x24, 0x01, 0x01, 0x92, 0x24, 0x01, 0x01, + 0x94, 0x24, 0x01, 0x01, 0x96, 0x24, 0x01, 0x01, 0x98, 0x24, 0x01, 0x01, 0x9a, 0x24, 0x01, 0x01, 0xe8, 0x09, 0x02, 0x02, 0xec, 0x09, 0x02, 0x02, 0xf0, 0x09, 0x02, 0x02, 0xf4, 0x09, 0x02, 0x02, + 0x20, 0x2d, 0x03, 0x04, 0x80, 0x32, 0x05, 0x07, 0xae, 0x1c, 0x00, 0x01, 0xb0, 0x1c, 0x00, 0x01, 0xb2, 0x1c, 0x00, 0x01, 0xb4, 0x1c, 0x00, 0x01, 0xb6, 0x1c, 0x00, 0x01, 0xb8, 0x1c, 0x00, 0x01, + 0xba, 0x1c, 0x00, 0x01, 0xbc, 0x1c, 0x00, 0x01, 0xbe, 0x1c, 0x00, 0x01, 0x9c, 0x24, 0x01, 0x01, 0x9e, 0x24, 0x01, 0x01, 0xa0, 0x24, 0x01, 0x01, 0xa2, 0x24, 0x01, 0x01, 0xa4, 0x24, 0x01, 0x01, + 0xa6, 0x24, 0x01, 0x01, 0xa8, 0x24, 0x01, 0x01, 0xaa, 0x24, 0x01, 0x01, 0xac, 0x24, 0x01, 0x01, 0xf8, 0x09, 0x02, 0x02, 0xfc, 0x09, 0x02, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x04, 0x0a, 0x02, 0x02, + 0x30, 0x2d, 0x03, 0x04, 0x00, 0x33, 0x05, 0x07, 0xc0, 0x1c, 0x00, 0x01, 0xc2, 0x1c, 0x00, 0x01, 0xc4, 0x1c, 0x00, 0x01, 0xc6, 0x1c, 0x00, 0x01, 0xc8, 0x1c, 0x00, 0x01, 0xca, 0x1c, 0x00, 0x01, + 0xcc, 0x1c, 0x00, 0x01, 0xce, 0x1c, 0x00, 0x01, 0xd0, 0x1c, 0x00, 0x01, 0xae, 0x24, 0x01, 0x01, 0xb0, 0x24, 0x01, 0x01, 0xb2, 0x24, 0x01, 0x01, 0xb4, 0x24, 0x01, 0x01, 0xb6, 0x24, 0x01, 0x01, + 0xb8, 0x24, 0x01, 0x01, 0xba, 0x24, 0x01, 0x01, 0xbc, 0x24, 0x01, 0x01, 0xbe, 0x24, 0x01, 0x01, 0x08, 0x0a, 0x02, 0x02, 0x0c, 0x0a, 0x02, 0x02, 0x10, 0x0a, 0x02, 0x02, 0x14, 0x0a, 0x02, 0x02, + 0x40, 0x2d, 0x03, 0x04, 0x80, 0x33, 0x05, 0x07, 0xd2, 0x1c, 0x00, 0x01, 0xd4, 0x1c, 0x00, 0x01, 0xd6, 0x1c, 0x00, 0x01, 0xd8, 0x1c, 0x00, 0x01, 0xda, 0x1c, 0x00, 0x01, 0xdc, 0x1c, 0x00, 0x01, + 0xde, 0x1c, 0x00, 0x01, 0xe0, 0x1c, 0x00, 0x01, 0xe2, 0x1c, 0x00, 0x01, 0xc0, 0x24, 0x01, 0x01, 0xc2, 0x24, 0x01, 0x01, 0xc4, 0x24, 0x01, 0x01, 0xc6, 0x24, 0x01, 0x01, 0xc8, 0x24, 0x01, 0x01, + 0xca, 0x24, 0x01, 0x01, 0xcc, 0x24, 0x01, 0x01, 0xce, 0x24, 0x01, 0x01, 0xd0, 0x24, 0x01, 0x01, 0x18, 0x0a, 0x02, 0x02, 0x1c, 0x0a, 0x02, 0x02, 0x20, 0x0a, 0x02, 0x02, 0x24, 0x0a, 0x02, 0x02, + 0x50, 0x2d, 0x03, 0x04, 0x00, 0x34, 0x05, 0x07, 0xe4, 0x1c, 0x00, 0x01, 0xe6, 0x1c, 0x00, 0x01, 0xe8, 0x1c, 0x00, 0x01, 0xea, 0x1c, 0x00, 0x01, 0xec, 0x1c, 0x00, 0x01, 0xee, 0x1c, 0x00, 0x01, + 0xf0, 0x1c, 0x00, 0x01, 0xf2, 0x1c, 0x00, 0x01, 0xd2, 0x24, 0x01, 0x01, 0xd4, 0x24, 0x01, 0x01, 0xd6, 0x24, 0x01, 0x01, 0xd8, 0x24, 0x01, 0x01, 0xda, 0x24, 0x01, 0x01, 0xdc, 0x24, 0x01, 0x01, + 0xde, 0x24, 0x01, 0x01, 0xe0, 0x24, 0x01, 0x01, 0xe2, 0x24, 0x01, 0x01, 0xe4, 0x24, 0x01, 0x01, 0x28, 0x0a, 0x02, 0x02, 0x2c, 0x0a, 0x02, 0x02, 0x30, 0x0a, 0x02, 0x02, 0x34, 0x0a, 0x02, 0x02, + 0x60, 0x2d, 0x03, 0x04, 0x80, 0x34, 0x05, 0x07, 0xf4, 0x1c, 0x00, 0x01, 0xf6, 0x1c, 0x00, 0x01, 0xf8, 0x1c, 0x00, 0x01, 0xfa, 0x1c, 0x00, 0x01, 0xfc, 0x1c, 0x00, 0x01, 0xfe, 0x1c, 0x00, 0x01, + 0x00, 0x1d, 0x00, 0x01, 0x02, 0x1d, 0x00, 0x01, 0xe6, 0x24, 0x01, 0x01, 0xe8, 0x24, 0x01, 0x01, 0xea, 0x24, 0x01, 0x01, 0xec, 0x24, 0x01, 0x01, 0xee, 0x24, 0x01, 0x01, 0xf0, 0x24, 0x01, 0x01, + 0xf2, 0x24, 0x01, 0x01, 0xf4, 0x24, 0x01, 0x01, 0xf6, 0x24, 0x01, 0x01, 0xf8, 0x24, 0x01, 0x01, 0x38, 0x0a, 0x02, 0x02, 0x3c, 0x0a, 0x02, 0x02, 0x40, 0x0a, 0x02, 0x02, 0x44, 0x0a, 0x02, 0x02, + 0x70, 0x2d, 0x03, 0x04, 0x00, 0x35, 0x05, 0x07, 0x04, 0x1d, 0x00, 0x01, 0x06, 0x1d, 0x00, 0x01, 0x08, 0x1d, 0x00, 0x01, 0x0a, 0x1d, 0x00, 0x01, 0x0c, 0x1d, 0x00, 0x01, 0x0e, 0x1d, 0x00, 0x01, + 0x10, 0x1d, 0x00, 0x01, 0x12, 0x1d, 0x00, 0x01, 0xfa, 0x24, 0x01, 0x01, 0xfc, 0x24, 0x01, 0x01, 0xfe, 0x24, 0x01, 0x01, 0x00, 0x25, 0x01, 0x01, 0x02, 0x25, 0x01, 0x01, 0x04, 0x25, 0x01, 0x01, + 0x06, 0x25, 0x01, 0x01, 0x08, 0x25, 0x01, 0x01, 0x0a, 0x25, 0x01, 0x01, 0x0c, 0x25, 0x01, 0x01, 0x48, 0x0a, 0x02, 0x02, 0x4c, 0x0a, 0x02, 0x02, 0x50, 0x0a, 0x02, 0x02, 0x54, 0x0a, 0x02, 0x02, + 0x80, 0x2d, 0x03, 0x04, 0x80, 0x35, 0x05, 0x07, 0x14, 0x1d, 0x00, 0x01, 0x16, 0x1d, 0x00, 0x01, 0x18, 0x1d, 0x00, 0x01, 0x1a, 0x1d, 0x00, 0x01, 0x1c, 0x1d, 0x00, 0x01, 0x1e, 0x1d, 0x00, 0x01, + 0x20, 0x1d, 0x00, 0x01, 0x22, 0x1d, 0x00, 0x01, 0x0e, 0x25, 0x01, 0x01, 0x10, 0x25, 0x01, 0x01, 0x12, 0x25, 0x01, 0x01, 0x14, 0x25, 0x01, 0x01, 0x16, 0x25, 0x01, 0x01, 0x18, 0x25, 0x01, 0x01, + 0x1a, 0x25, 0x01, 0x01, 0x1c, 0x25, 0x01, 0x01, 0x1e, 0x25, 0x01, 0x01, 0x20, 0x25, 0x01, 0x01, 0x58, 0x0a, 0x02, 0x02, 0x5c, 0x0a, 0x02, 0x02, 0x60, 0x0a, 0x02, 0x02, 0x64, 0x0a, 0x02, 0x02, + 0x90, 0x2d, 0x03, 0x04, 0x00, 0x36, 0x05, 0x07, 0x24, 0x1d, 0x00, 0x01, 0x26, 0x1d, 0x00, 0x01, 0x28, 0x1d, 0x00, 0x01, 0x2a, 0x1d, 0x00, 0x01, 0x2c, 0x1d, 0x00, 0x01, 0x2e, 0x1d, 0x00, 0x01, + 0x30, 0x1d, 0x00, 0x01, 0x32, 0x1d, 0x00, 0x01, 0x22, 0x25, 0x01, 0x01, 0x24, 0x25, 0x01, 0x01, 0x26, 0x25, 0x01, 0x01, 0x28, 0x25, 0x01, 0x01, 0x2a, 0x25, 0x01, 0x01, 0x2c, 0x25, 0x01, 0x01, + 0x2e, 0x25, 0x01, 0x01, 0x30, 0x25, 0x01, 0x01, 0x32, 0x25, 0x01, 0x01, 0x34, 0x25, 0x01, 0x01, 0x68, 0x0a, 0x02, 0x02, 0x6c, 0x0a, 0x02, 0x02, 0x70, 0x0a, 0x02, 0x02, 0x74, 0x0a, 0x02, 0x02, + 0xa0, 0x2d, 0x03, 0x04, 0x80, 0x36, 0x05, 0x07, 0x34, 0x1d, 0x00, 0x01, 0x36, 0x1d, 0x00, 0x01, 0x38, 0x1d, 0x00, 0x01, 0x3a, 0x1d, 0x00, 0x01, 0x3c, 0x1d, 0x00, 0x01, 0x3e, 0x1d, 0x00, 0x01, + 0x40, 0x1d, 0x00, 0x01, 0x42, 0x1d, 0x00, 0x01, 0x36, 0x25, 0x01, 0x01, 0x38, 0x25, 0x01, 0x01, 0x3a, 0x25, 0x01, 0x01, 0x3c, 0x25, 0x01, 0x01, 0x3e, 0x25, 0x01, 0x01, 0x40, 0x25, 0x01, 0x01, + 0x42, 0x25, 0x01, 0x01, 0x44, 0x25, 0x01, 0x01, 0x46, 0x25, 0x01, 0x01, 0x48, 0x25, 0x01, 0x01, 0x78, 0x0a, 0x02, 0x02, 0x7c, 0x0a, 0x02, 0x02, 0x80, 0x0a, 0x02, 0x02, 0x84, 0x0a, 0x02, 0x02, + 0xb0, 0x2d, 0x03, 0x04, 0x00, 0x13, 0x06, 0x08, 0x44, 0x1d, 0x00, 0x01, 0x46, 0x1d, 0x00, 0x01, 0x48, 0x1d, 0x00, 0x01, 0x4a, 0x1d, 0x00, 0x01, 0x4c, 0x1d, 0x00, 0x01, 0x4e, 0x1d, 0x00, 0x01, + 0x50, 0x1d, 0x00, 0x01, 0x52, 0x1d, 0x00, 0x01, 0x4a, 0x25, 0x01, 0x01, 0x4c, 0x25, 0x01, 0x01, 0x4e, 0x25, 0x01, 0x01, 0x50, 0x25, 0x01, 0x01, 0x52, 0x25, 0x01, 0x01, 0x54, 0x25, 0x01, 0x01, + 0x56, 0x25, 0x01, 0x01, 0x58, 0x25, 0x01, 0x01, 0x5a, 0x25, 0x01, 0x01, 0x5c, 0x25, 0x01, 0x01, 0x88, 0x0a, 0x02, 0x02, 0x8c, 0x0a, 0x02, 0x02, 0x90, 0x0a, 0x02, 0x02, 0x94, 0x0a, 0x02, 0x02, + 0xc0, 0x2d, 0x03, 0x04, 0x00, 0x14, 0x06, 0x08, 0x54, 0x1d, 0x00, 0x01, 0x56, 0x1d, 0x00, 0x01, 0x58, 0x1d, 0x00, 0x01, 0x5a, 0x1d, 0x00, 0x01, 0x5c, 0x1d, 0x00, 0x01, 0x5e, 0x1d, 0x00, 0x01, + 0x60, 0x1d, 0x00, 0x01, 0x62, 0x1d, 0x00, 0x01, 0x5e, 0x25, 0x01, 0x01, 0x60, 0x25, 0x01, 0x01, 0x62, 0x25, 0x01, 0x01, 0x64, 0x25, 0x01, 0x01, 0x66, 0x25, 0x01, 0x01, 0x68, 0x25, 0x01, 0x01, + 0x6a, 0x25, 0x01, 0x01, 0x6c, 0x25, 0x01, 0x01, 0x6e, 0x25, 0x01, 0x01, 0x70, 0x25, 0x01, 0x01, 0x98, 0x0a, 0x02, 0x02, 0x9c, 0x0a, 0x02, 0x02, 0xa0, 0x0a, 0x02, 0x02, 0xa4, 0x0a, 0x02, 0x02, + 0xd0, 0x2d, 0x03, 0x04, 0x00, 0x15, 0x06, 0x08, 0x64, 0x1d, 0x00, 0x01, 0x66, 0x1d, 0x00, 0x01, 0x68, 0x1d, 0x00, 0x01, 0x6a, 0x1d, 0x00, 0x01, 0x6c, 0x1d, 0x00, 0x01, 0x6e, 0x1d, 0x00, 0x01, + 0x70, 0x1d, 0x00, 0x01, 0x72, 0x1d, 0x00, 0x01, 0x72, 0x25, 0x01, 0x01, 0x74, 0x25, 0x01, 0x01, 0x76, 0x25, 0x01, 0x01, 0x78, 0x25, 0x01, 0x01, 0x7a, 0x25, 0x01, 0x01, 0x7c, 0x25, 0x01, 0x01, + 0x7e, 0x25, 0x01, 0x01, 0x80, 0x25, 0x01, 0x01, 0x82, 0x25, 0x01, 0x01, 0x84, 0x25, 0x01, 0x01, 0xa8, 0x0a, 0x02, 0x02, 0xac, 0x0a, 0x02, 0x02, 0xb0, 0x0a, 0x02, 0x02, 0xb4, 0x0a, 0x02, 0x02, + 0xe0, 0x2d, 0x03, 0x04, 0x00, 0x16, 0x06, 0x08, 0x74, 0x1d, 0x00, 0x01, 0x76, 0x1d, 0x00, 0x01, 0x78, 0x1d, 0x00, 0x01, 0x7a, 0x1d, 0x00, 0x01, 0x7c, 0x1d, 0x00, 0x01, 0x7e, 0x1d, 0x00, 0x01, + 0x80, 0x1d, 0x00, 0x01, 0x82, 0x1d, 0x00, 0x01, 0x86, 0x25, 0x01, 0x01, 0x88, 0x25, 0x01, 0x01, 0x8a, 0x25, 0x01, 0x01, 0x8c, 0x25, 0x01, 0x01, 0x8e, 0x25, 0x01, 0x01, 0x90, 0x25, 0x01, 0x01, + 0x92, 0x25, 0x01, 0x01, 0x94, 0x25, 0x01, 0x01, 0x96, 0x25, 0x01, 0x01, 0x98, 0x25, 0x01, 0x01, 0xb8, 0x0a, 0x02, 0x02, 0xbc, 0x0a, 0x02, 0x02, 0xc0, 0x0a, 0x02, 0x02, 0xc4, 0x0a, 0x02, 0x02, + 0xf0, 0x2d, 0x03, 0x04, 0x00, 0x17, 0x06, 0x08, 0x84, 0x1d, 0x00, 0x01, 0x86, 0x1d, 0x00, 0x01, 0x88, 0x1d, 0x00, 0x01, 0x8a, 0x1d, 0x00, 0x01, 0x8c, 0x1d, 0x00, 0x01, 0x8e, 0x1d, 0x00, 0x01, + 0x90, 0x1d, 0x00, 0x01, 0x92, 0x1d, 0x00, 0x01, 0x9a, 0x25, 0x01, 0x01, 0x9c, 0x25, 0x01, 0x01, 0x9e, 0x25, 0x01, 0x01, 0xa0, 0x25, 0x01, 0x01, 0xa2, 0x25, 0x01, 0x01, 0x00, 0x00, 0x73, 0x0e, + 0x00, 0x00, 0x72, 0x0e, 0x00, 0x00, 0x71, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x6f, 0x0e, 0x00, 0x00, 0x6e, 0x0e, 0x00, 0x00, 0x6d, 0x0e, 0x00, 0x00, 0x6c, 0x0e, 0x00, 0x00, 0x6b, 0x0e, + 0x00, 0x00, 0x6a, 0x0e, 0x00, 0x00, 0x69, 0x0e, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x00, 0x67, 0x0e, 0x00, 0x00, 0x66, 0x0e, 0x00, 0x00, 0x65, 0x0e, 0x00, 0x00, 0x64, 0x0e, 0x00, 0x00, 0x63, 0x0e, + 0x00, 0x00, 0x62, 0x0e, 0x00, 0x00, 0x61, 0x0e, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x00, 0x5f, 0x0e, 0x00, 0x00, 0x5e, 0x0e, 0x00, 0x00, 0x5d, 0x0e, 0x00, 0x00, 0x5c, 0x0e, 0x00, 0x00, 0x5b, 0x0e, + 0x00, 0x00, 0x5a, 0x0e, 0x00, 0x00, 0x59, 0x0e, 0x00, 0x00, 0x58, 0x0e, 0x00, 0x00, 0x57, 0x0e, 0x00, 0x00, 0x56, 0x0e, 0x00, 0x00, 0x55, 0x0e, 0x00, 0x00, 0x54, 0x0e, 0x00, 0x00, 0x53, 0x0e, + 0x00, 0x00, 0x52, 0x0e, 0x00, 0x00, 0x51, 0x0e, 0x00, 0x00, 0x50, 0x0e, 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x4e, 0x0e, 0x00, 0x00, 0x4d, 0x0e, 0x00, 0x00, 0x4c, 0x0e, 0x00, 0x00, 0x4b, 0x0e, + 0x00, 0x00, 0x4a, 0x0e, 0x00, 0x00, 0x49, 0x0e, 0x00, 0x00, 0x48, 0x0e, 0x00, 0x00, 0x47, 0x0e, 0x00, 0x00, 0x46, 0x0e, 0x00, 0x00, 0x45, 0x0e, 0x00, 0x00, 0x44, 0x0e, 0x00, 0x00, 0x43, 0x0e, + 0x00, 0x00, 0x42, 0x0e, 0x00, 0x00, 0x41, 0x0e, 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x3f, 0x0e, 0x00, 0x00, 0x3e, 0x0e, 0x00, 0x00, 0x3d, 0x0e, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x00, 0x3b, 0x0e, + 0x00, 0x00, 0x3a, 0x0e, 0x00, 0x00, 0x39, 0x0e, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 0x37, 0x0e, 0x00, 0x00, 0x36, 0x0e, 0x00, 0x00, 0x35, 0x0e, 0x00, 0x00, 0x34, 0x0e, 0x00, 0x00, 0x33, 0x0e, + 0x00, 0x00, 0x32, 0x0e, 0x00, 0x00, 0x31, 0x0e, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x2e, 0x0e, 0x00, 0x00, 0x2d, 0x0e, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00, 0x2b, 0x0e, + 0x00, 0x00, 0x2a, 0x0e, 0x00, 0x00, 0x29, 0x0e, 0x00, 0x00, 0x28, 0x0e, 0x00, 0x00, 0x27, 0x0e, 0x00, 0x00, 0x26, 0x0e, 0x00, 0x00, 0x25, 0x0e, 0x00, 0x00, 0x24, 0x0e, 0x00, 0x00, 0x23, 0x0e, + 0x00, 0x00, 0x22, 0x0e, 0x00, 0x00, 0x21, 0x0e, 0x00, 0x00, 0x20, 0x0e, 0x00, 0x00, 0x1f, 0x0e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x1d, 0x0e, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0x1b, 0x0e, + 0x00, 0x00, 0x1a, 0x0e, 0x00, 0x00, 0x19, 0x0e, 0x00, 0x00, 0x18, 0x0e, 0x00, 0x00, 0x17, 0x0e, 0x00, 0x00, 0x16, 0x0e, 0x00, 0x00, 0x15, 0x0e, 0x00, 0x00, 0x14, 0x0e, 0x00, 0x00, 0x13, 0x0e, + 0x00, 0x00, 0x12, 0x0e, 0x00, 0x00, 0x11, 0x0e, 0x00, 0x00, 0x10, 0x0e, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x0d, 0x0e, 0x00, 0x00, 0x0c, 0x0e, 0x00, 0x00, 0x0b, 0x0e, + 0x00, 0x00, 0x0a, 0x0e +}; + +const FSE_DTable* const DTables[6] = { + (const FSE_DTable*)DTable_0, + (const FSE_DTable*)DTable_1, + (const FSE_DTable*)DTable_2, + (const FSE_DTable*)DTable_3, + (const FSE_DTable*)DTable_4, + (const FSE_DTable*)DTable_5, +}; + diff --git a/src/plotting/GenSortKey.h b/src/plotting/GenSortKey.h new file mode 100644 index 00000000..dcb5661b --- /dev/null +++ b/src/plotting/GenSortKey.h @@ -0,0 +1,140 @@ +#pragma once + +#include "threading/ThreadPool.h" + +struct SortKeyGen +{ + template + static void Generate( ThreadPool& pool, uint64 length, uint32* keyBuffer ); + +// template +// static void Invert( ThreadPool& pool, uint64 length, const uint32* srcKeyBuffer, uint32* dstKeyBuffer ); + + template + static void Sort( ThreadPool& pool, int64 length, const uint32* keys, const T* src, T* dst ); + + template + static void Sort( ThreadPool& pool, const uint32 desiredThreadCount, int64 length, const uint32* keys, const T* src, T* dst ); + +private: + struct GenJob + { + uint64 offset; + uint64 length; + uint32* keyBuffer; + }; + + template + struct SortJob + { + int64 length; + int64 offset; + const uint32* keys; + const T* src; + T* dst; + }; + + static void GenJobThread( GenJob* job ); + + template + static void SortThread( SortJob* job ); +}; + +//----------------------------------------------------------- +template +inline void SortKeyGen::Generate( ThreadPool& pool, uint64 length, uint32* keyBuffer ) +{ + ASSERT( pool.ThreadCount() <= MAX_JOBS ); + + uint threadCount = pool.ThreadCount(); + + const uint64 entriesPerThread = length / threadCount; + const uint64 tailingEntries = length - ( entriesPerThread * threadCount ); + + GenJob jobs[MAX_JOBS]; + + for( uint64 i = 0; i < threadCount; i++ ) + { + GenJob& job = jobs[i]; + + job.length = entriesPerThread; + job.offset = i * entriesPerThread; + job.keyBuffer = keyBuffer; + } + + jobs[threadCount-1].length += tailingEntries; + + pool.RunJob( GenJobThread, jobs, threadCount ); +} + +//----------------------------------------------------------- +template +inline void SortKeyGen::Sort( ThreadPool& pool, int64 length, const uint32* keys, const T* src, T* dst ) +{ + Sort( pool, pool.ThreadCount(), length, keys, src, dst ); +} + +//----------------------------------------------------------- +template +inline void SortKeyGen::Sort( ThreadPool& pool, const uint32 desiredThreadCount, int64 length, const uint32* keys, const T* src, T* dst ) +{ + ASSERT( pool.ThreadCount() <= MAX_JOBS ); + + const int64 threadCount = desiredThreadCount == 0 ? (int64)pool.ThreadCount() : (int64)std::min( desiredThreadCount, pool.ThreadCount() ); + + const int64 entriesPerThread = length / threadCount; + const int64 tailingEntries = length - ( entriesPerThread * threadCount ); + + SortJob jobs[MAX_JOBS]; + + for( int64 i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job.length = entriesPerThread; + job.offset = i * entriesPerThread; + job.keys = keys; + job.src = src; + job.dst = dst; + } + + jobs[threadCount-1].length += tailingEntries; + + pool.RunJob( SortThread, jobs, (uint)threadCount ); +} + +// //----------------------------------------------------------- +// template +// inline void SortKeyGen::Invert( ThreadPool& pool, uint64 length, const uint32* srcKeyBuffer, uint32* dstKeyBuffer ) +// { +// +// } + +//----------------------------------------------------------- +inline void SortKeyGen::GenJobThread( GenJob* job ) +{ + const uint64 offset = job->offset; + uint64 i = offset; + const uint64 end = i + job->length; + + uint32* buffer = job->keyBuffer; + + for( ; i < end; i++ ) + buffer[i] = (uint32)i; +} + +//----------------------------------------------------------- +template +inline void SortKeyGen::SortThread( SortJob* job ) +{ + const int64 length = job->length; + const int64 offset = job->offset; + const uint32* keys = job->keys + offset; + const T* src = job->src; + T* dst = job->dst + offset; + + for( int64 i = 0; i < length; i++ ) + { + dst[i] = src[keys[i]]; + } +} diff --git a/src/plotting/GlobalPlotConfig.h b/src/plotting/GlobalPlotConfig.h new file mode 100644 index 00000000..910596cc --- /dev/null +++ b/src/plotting/GlobalPlotConfig.h @@ -0,0 +1,29 @@ +#pragma once +#include "plotting/PlotTools.h" +#include "util/KeyTools.h" + +struct GlobalPlotConfig +{ + uint32 threadCount = 0; + uint32 plotCount = 1; + + const char* plotIdStr = nullptr; + const char* plotMemoStr = nullptr; + // byte* plotId = new byte[BB_PLOT_ID_LEN]; + // byte* plotMemo = new byte[BB_PLOT_MEMO_MAX_SIZE]; + // uint16 plotMemoSize = 0; + + // #TODO: Allow multiple output paths + const char* outputFolder = nullptr; + + bool showMemo = false; + bool warmStart = false; + bool disableNuma = false; + bool disableCpuAffinity = false; + + bls::G1Element farmerPublicKey; + bls::G1Element* poolPublicKey = nullptr; // Either poolPublicKey or poolContractPuzzleHash must be set. + PuzzleHash* poolContractPuzzleHash = nullptr; // If both are set, poolContractPuzzleHash will be used over + // the poolPublicKey. +}; + diff --git a/src/plotting/PlotTools.cpp b/src/plotting/PlotTools.cpp new file mode 100644 index 00000000..99c1d2dd --- /dev/null +++ b/src/plotting/PlotTools.cpp @@ -0,0 +1,152 @@ +#include "PlotTools.h" +#include "util/Util.h" + + +#define PLOT_FILE_PREFIX_LEN (sizeof("plot-k32-2021-08-05-18-55-")-1) + +//----------------------------------------------------------- +void PlotTools::GenPlotFileName( const byte plotId[BB_PLOT_ID_LEN], char outPlotFileName[BB_PLOT_FILE_LEN] ) +{ + ASSERT( plotId ); + ASSERT( outPlotFileName ); + + time_t now = time( nullptr ); + struct tm* t = localtime( &now ); ASSERT( t ); + + const size_t r = strftime( outPlotFileName, BB_PLOT_FILE_LEN, "plot-k32-%Y-%m-%d-%H-%M-", t ); + if( r != PLOT_FILE_PREFIX_LEN ) + Fatal( "Failed to generate plot file." ); + + PlotIdToString( plotId, outPlotFileName + r ); + memcpy( outPlotFileName + r + BB_PLOT_ID_HEX_LEN, ".plot.tmp", sizeof( ".plot.tmp" ) ); +} + +//----------------------------------------------------------- +void PlotTools::PlotIdToString( const byte plotId[BB_PLOT_ID_LEN], char plotIdString[BB_PLOT_ID_HEX_LEN+1] ) +{ + ASSERT( plotId ); + ASSERT( plotIdString ); + + size_t numEncoded = 0; + BytesToHexStr( plotId, BB_PLOT_ID_LEN, plotIdString, BB_PLOT_ID_HEX_LEN, numEncoded ); + ASSERT( numEncoded == BB_PLOT_ID_LEN ); + + plotIdString[BB_PLOT_ID_HEX_LEN] = '\0'; +} + +//----------------------------------------------------------- + bool PlotTools::PlotStringToId( const char plotIdString[BB_PLOT_ID_HEX_LEN+1], byte plotId[BB_PLOT_ID_LEN] ) + { + const size_t len = strlen( plotIdString ); + if( len < 64 && len != 66 ) + return false; + + if( len == 66 ) + { + if( plotIdString[0] == '0' && plotIdString[1] == 'x' ) + plotIdString += 2; + else + return false; + } + + HexStrToBytes( plotIdString, len, plotId, BB_PLOT_ID_LEN ); + return true; + } + +//----------------------------------------------------------- +bls::G1Element PlotTools::GeneratePlotPublicKey( const bls::G1Element& localPk, bls::G1Element& farmerPk, const bool includeTaproot ) +{ + bls::G1Element plotPublicKey; + + if( includeTaproot ) + { + std::vector taprootMsg = (localPk + farmerPk).Serialize(); + taprootMsg = BytesConcat( taprootMsg, localPk.Serialize(), farmerPk.Serialize() ); + + byte tapRootHash[32]; + bls::Util::Hash256( tapRootHash, taprootMsg.data(), taprootMsg.size() ); + + bls::PrivateKey taprootSk = bls::AugSchemeMPL().KeyGen( bls::Bytes( tapRootHash, sizeof( tapRootHash ) ) ); + + plotPublicKey = localPk + farmerPk + taprootSk.GetG1Element(); + } + else + { + plotPublicKey = localPk + farmerPk; + } + + return plotPublicKey; +} + +//----------------------------------------------------------- +void PlotTools::GeneratePlotIdAndMemo( + byte plotId [BB_PLOT_ID_LEN], + byte plotMemo[BB_PLOT_MEMO_MAX_SIZE], + uint16& outMemoSize, + bls::G1Element& farmerPK, + bls::G1Element* poolPK, + PuzzleHash* contractPuzzleHash + ) +{ + // Generate random master secret key + byte seed[32]; + SysHost::Random( seed, sizeof( seed ) ); + + bls::PrivateKey sk = bls::AugSchemeMPL().KeyGen( bls::Bytes( seed, sizeof( seed ) ) ); + bls::G1Element localPk = std::move( KeyTools::MasterSkToLocalSK( sk ) ).GetG1Element(); + + // #See: chia-blockchain create_plots.py + // The plot public key is the combination of the harvester and farmer keys + // New plots will also include a taproot of the keys, for extensibility + const bool includeTaproot = contractPuzzleHash != nullptr; + + bls::G1Element plotPublicKey = std::move( GeneratePlotPublicKey( localPk, farmerPK, includeTaproot ) ); + + std::vector farmerPkBytes = farmerPK.Serialize(); + std::vector localSkBytes = sk.Serialize(); + + // The plot id is based on the harvester, farmer, and pool keys + if( !includeTaproot ) + { + std::vector bytes = poolPK->Serialize(); + + // Gen plot id + auto plotPkBytes = plotPublicKey.Serialize(); + bytes.insert( bytes.end(), plotPkBytes.begin(), plotPkBytes.end() ); + + bls::Util::Hash256( plotId, bytes.data(), bytes.size() ); + + // Gen memo + auto memoBytes = BytesConcat( poolPK->Serialize(), farmerPkBytes, localSkBytes ); + + const size_t poolMemoSize = 48 + 48 + 32; + ASSERT( memoBytes.size() == poolMemoSize ); + + memcpy( plotMemo, memoBytes.data(), poolMemoSize ); + outMemoSize = (uint16)poolMemoSize; + } + else + { + // Create a pool plot with a contract puzzle hash + ASSERT( contractPuzzleHash ); + + const auto& ph = *contractPuzzleHash; + std::vector phBytes( (uint8_t*)ph.data, (uint8_t*)ph.data + CHIA_PUZZLE_HASH_SIZE ); + + // Gen plot id + std::vector plotIdBytes = phBytes; + auto plotPkBytes = plotPublicKey.Serialize(); + + plotIdBytes.insert( plotIdBytes.end(), plotPkBytes.begin(), plotPkBytes.end() ); + bls::Util::Hash256( plotId, plotIdBytes.data(), plotIdBytes.size() ); + + // Gen memo + auto memoBytes = BytesConcat( phBytes, farmerPkBytes, localSkBytes ); + + const size_t phMemoSize = 32 + 48 + 32; + ASSERT( memoBytes.size() == phMemoSize ); + + memcpy( plotMemo, memoBytes.data(), phMemoSize ); + outMemoSize = (uint16)phMemoSize; + } +} diff --git a/src/plotting/PlotTools.h b/src/plotting/PlotTools.h new file mode 100644 index 00000000..b5e339fa --- /dev/null +++ b/src/plotting/PlotTools.h @@ -0,0 +1,56 @@ +#pragma once +#include "ChiaConsts.h" +#include "util/KeyTools.h" + +#define BB_PLOT_ID_LEN 32 +#define BB_PLOT_ID_HEX_LEN (BB_PLOT_ID_LEN * 2) + +#define BB_PLOT_MEMO_MAX_SIZE (48+48+32) + +#define BB_PLOT_FILE_LEN_TMP (sizeof( "plot-k32-2021-08-05-18-55-77a011fc20f0003c3adcc739b615041ae56351a22b690fd854ccb6726e5f43b7.plot.tmp" ) - 1) +#define BB_PLOT_FILE_LEN (BB_PLOT_FILE_LEN_TMP - 4) + +struct PlotTools +{ + static void GenPlotFileName( const byte plotId[BB_PLOT_ID_LEN], char outPlotFileName[BB_PLOT_FILE_LEN] ); + static void PlotIdToString( const byte plotId[BB_PLOT_ID_LEN], char plotIdString[BB_PLOT_ID_HEX_LEN+1] ); + + static bool PlotStringToId( const char plotIdString[BB_PLOT_ID_HEX_LEN+1], byte plotId[BB_PLOT_ID_LEN] ); + + static bls::G1Element GeneratePlotPublicKey( const bls::G1Element& localPk, bls::G1Element& farmerPk, const bool includeTaproot ); + + static void GeneratePlotIdAndMemo( + byte plotId [BB_PLOT_ID_LEN], + byte plotMemo[BB_PLOT_MEMO_MAX_SIZE], + uint16& outMemoSize, + bls::G1Element& farmerPK, + bls::G1Element* poolPK, + PuzzleHash* contractPuzzleHash + ); + // static void PlotIdToStringTmp( const byte* plotId, const byte plotIdString[BB_PLOT_FILE_LEN_TMP] ); + + // //----------------------------------------------------------- + // static uint32_t CalculateLinePointSize(uint8_t k) { return Util::ByteAlign(2 * k) / 8; } + + // // This is the full size of the deltas section in a park. However, it will not be fully filled + // static uint32_t CalculateMaxDeltasSize(uint8_t k, uint8_t table_index) + // { + // if (table_index == 1) { + // return Util::ByteAlign((kEntriesPerPark - 1) * kMaxAverageDeltaTable1) / 8; + // } + // return Util::ByteAlign((kEntriesPerPark - 1) * kMaxAverageDelta) / 8; + // } + + // static uint32_t CalculateStubsSize(uint32_t k) + // { + // return Util::ByteAlign((kEntriesPerPark - 1) * (k - kStubMinusBits)) / 8; + // } + + // static uint32_t CalculateParkSize(uint8_t k, uint8_t table_index) + // { + // return CalculateLinePointSize(k) + CalculateStubsSize(k) + + // CalculateMaxDeltasSize(k, table_index); + // } + +}; + diff --git a/src/plotting/PlotTypes.h b/src/plotting/PlotTypes.h new file mode 100644 index 00000000..85e634fa --- /dev/null +++ b/src/plotting/PlotTypes.h @@ -0,0 +1,15 @@ +#pragma once +#include "threading/AutoResetSignal.h" + +struct Pairs +{ + uint32* left ; + uint16* right; +}; + +struct Pair +{ + uint32 left; + uint32 right; +}; +static_assert( sizeof( Pair ) == 8, "Invalid Pair struct." ); \ No newline at end of file diff --git a/src/plotting/TableWriter.cpp b/src/plotting/TableWriter.cpp new file mode 100644 index 00000000..479ab5db --- /dev/null +++ b/src/plotting/TableWriter.cpp @@ -0,0 +1 @@ +#include "TableWriter.h" diff --git a/src/plotting/TableWriter.h b/src/plotting/TableWriter.h new file mode 100644 index 00000000..2ecf75e3 --- /dev/null +++ b/src/plotting/TableWriter.h @@ -0,0 +1,443 @@ +#pragma once +#include "ChiaConsts.h" +#include "threading/ThreadPool.h" +#include "threading/MTJob.h" +#include "plotting/CTables.h" + +struct TableWriter +{ + /// P7 + // Table 7's indices into the Table 6's entries. + // That is, a map that converts from F7 order into Table 6 LP order. + template + static size_t WriteP7( ThreadPool& threadPool, uint32 threadCount, const uint64 length, + const uint32* indices, byte* parkBuffer ); + + static void WriteP7Parks( const uint64 parkCount, const uint32* indices, byte* parkBuffer, uint32 jobId = 0 ); + + template + static void WriteP7Entries( const uint64 length, const TIdx* indices, byte* parkBuffer, uint32 jobId = 0 ); + + + /// C1 & C2 tables + template + static size_t WriteC12Parallel( ThreadPool& pool, uint32 threadCount, const uint64 length, + const uint32* f7Entries, uint32* parkBuffer ); + + template + static void WriteC12Entries( const uint64 length, const uint32* f7Entries, uint32* c1Buffer ); + + + /// C3 + static uint64 GetC3ParkCount( const uint64 length ); + static uint64 GetC3ParkCount( const uint64 length, uint64& outLastParkRemainder ); + + template + static size_t WriteC3Parallel( ThreadPool& pool, uint32 threadCount, const uint64 length, uint32* f7Entries, byte* c3Buffer ); + + static void WriteC3Parks( const uint64 parkCount, uint32* f7Entries, byte* writeBuffer, uint32 jobId = 0 ); + static void WriteC3Park( const uint64 length, uint32* f7Entries, byte* parkBuffer, uint32 jobId = 0 ); +}; + +struct P7Job : MTJob +{ + uint64 parkCount; + const uint32* indices; + byte* parkBuffer; + + void Run() override; +}; + +template +struct C12Job : MTJob> +{ + uint64 length; + const uint32* f7Entries; + uint32* writeBuffer; + + void Run() override; +}; + +struct C3Job : MTJob +{ + uint64 parkCount; + uint32* f7Entries; + byte* writeBuffer; + + void Run() override; +}; + + +/// +/// P7 +/// +//----------------------------------------------------------- +template +inline size_t TableWriter::WriteP7( ThreadPool& threadPool, uint32 threadCount, const uint64 length, + const uint32* indices, byte* parkBuffer ) +{ + threadCount = std::min( threadCount, MAX_JOBS ); + + const uint64 parkCount = length / kEntriesPerPark; // Number of parks that are completely filled with entries + const uint64 parksPerThread = parkCount / threadCount; + + uint64 trailingParks = parkCount - ( parksPerThread * threadCount ); + + const uint64 trailingEntries = length - ( parkCount * kEntriesPerPark ); + const uint64 totalParksWritten = parkCount + ( trailingEntries ? 1 : 0 ); + + /** + * #NOTE: 8-byte (uint64s) fields fit perfectly into the + * park size buffer, so we don't have to worry about + * race conditions where a thread might write to its last field + * which is shared with the first thread's field as well. + * 33 (K+1) * kEntriesPerPark (2048) + * = 67584 / 8 + * = 8448 / 8 + * = 1056 64-bit fields + */ + const size_t parkSize = CDiv( (_K + 1) * kEntriesPerPark, 8 ); // #TODO: Move this to its own function + static_assert( parkSize / 8 == 1056 ); + + MTJobRunner jobs( threadPool ); + + const uint32* threadIndices = indices; + byte* threadParkBuffer = parkBuffer; + + for( uint i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job.parkCount = parksPerThread; + job.indices = threadIndices; + job.parkBuffer = threadParkBuffer; + + // Assign trailing parks accross threads + if( trailingParks ) + { + job.parkCount ++; + trailingParks --; + } + + threadIndices += job.parkCount * kEntriesPerPark; + threadParkBuffer += job.parkCount * parkSize; + } + + // Run jobs + jobs.Run( threadCount ); + + // Write trailing entries into a park, if we have any + if( trailingEntries ) + { + memset( threadParkBuffer, 0, parkSize ); + WriteP7Entries( trailingEntries, threadIndices, threadParkBuffer ); + } + + return totalParksWritten * parkSize; +} + +//----------------------------------------------------------- +inline void TableWriter::WriteP7Parks( const uint64 parkCount, const uint32* indices, byte* parkBuffer, uint32 jobId ) +{ + const size_t parkSize = CDiv( (_K + 1) * kEntriesPerPark, 8 ); + + for( uint64 i = 0; i < parkCount; i++ ) + { + WriteP7Entries( kEntriesPerPark, indices, parkBuffer, jobId ); + indices += kEntriesPerPark; + parkBuffer += parkSize; + } +} + +//----------------------------------------------------------- +template +inline void TableWriter::WriteP7Entries( const uint64 length, const TIdx* indices, byte* parkBuffer, uint32 jobId ) +{ + ASSERT( length <= kEntriesPerPark ); + ASSERT( ((uintptr_t)parkBuffer & 7 ) == 0 ); + + uint64* fieldWriter = (uint64*)parkBuffer; + + const uint32 bitsPerEntry = _K + 1; + + uint64 field = 0; + uint32 bits = 0; + + // Like when serializing stubs in the LinePoint parks, + // we always store it all the way to the MSbits + // (shift all the way to the left) + for( uint64 i = 0; i < length; i++ ) + { + const uint64 index = indices[i]; + const uint freeBits = 64 - bits; + + // Filled a field? + if( freeBits <= bitsPerEntry ) + { + // Update the next field bits to what the stub bits that were not written into the current field + bits = bitsPerEntry - freeBits; + + // Write what we can (which may be nothing) into the free bits of the current field + field |= index >> bits; + + // Store field + *fieldWriter++ = Swap64( field ); + + // Write the remaining bits to the next field + // if( bits ) + // field = f7 << ( 64 - bits ); + // else + // field = 0; + + // Non-branching mask-based method + const uint remainder = 64 - bits; + uint64 mask = ( ( 1ull << bits ) - 1 ) << (remainder & 63); + field = ( index << remainder ) & mask; + } + else + { + // The entry completely fits into the current field with room to spare + field |= index << ( freeBits - bitsPerEntry ); + bits += bitsPerEntry; + } + } + + // Write any trailing fields + if( bits > 0 ) + *fieldWriter++ = Swap64( field ); +} + +//----------------------------------------------------------- +inline void P7Job::Run() +{ + TableWriter::WriteP7Parks( this->parkCount, this->indices, this->parkBuffer, this->_jobId ); +} + + +/// +/// C1 & C2 tables +/// +//----------------------------------------------------------- +template +inline size_t TableWriter::WriteC12Parallel( + ThreadPool& pool, uint32 threadCount, const uint64 length, + const uint32* f7Entries, uint32* parkBuffer ) +{ + threadCount = std::min( threadCount, MAX_JOBS ); + + const uint64 parkEntries = CDiv( length, (int)CInterval ); + const uint64 entriesPerThread = parkEntries / threadCount; + const uint64 trailingEntries = parkEntries - (entriesPerThread * threadCount); + + MTJobRunner, MAX_JOBS> jobs; + + const uint32* threadf7Entries = f7Entries; + uint32* parkWriter = parkBuffer; + + for( uint32 i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job.length = entriesPerThread; + job.f7Entries = threadf7Entries; + job.writeBuffer = parkWriter; + + #if DEBUG + job.jobIndex = i; + #endif + + threadf7Entries += entriesPerThread * CInterval; + parkWriter += entriesPerThread; + } + + jobs.Run( threadCount ); + + // Write trailing entries, if any + if( trailingEntries ) + WriteC12Entries( trailingEntries, threadf7Entries, parkWriter ); + + + if constexpr ( CInterval == kCheckpoint1Interval * kCheckpoint2Interval ) + { + // #NOTE: Unfortunately, chiapos infers the size of the C2 table by substracting + // the C3 pointer by the C2 pointer. This does not work for us + // because since we do block-aligned writes we, our C2 size disk-occupied size + // will most likely be greater than the actual C2 size. + // To work around this, we can add a trailing entry with the maximum k32 value size. + // This will force chiapos to stop at that point as the f7 is lesser than max k32 value. + // #IMPORTANT: This means that we can't have any f7's that are 0xFFFFFFFF!. + parkWriter[trailingEntries] = 0xFFFFFFFF; + } + else + { + + // Write an empty one at the end (compatibility with chiapos) + parkWriter[trailingEntries] = 0; + } + + return (parkEntries + 1) * sizeof( uint32 ); +} + +//----------------------------------------------------------- +template +inline void TableWriter::WriteC12Entries( const uint64 length, const uint32* f7Entries, uint32* c1Buffer ) +{ + uint64 f7Src = 0; + for( uint64 i = 0; i < length; i++, f7Src += CInterval ) + c1Buffer[i] = Swap32( f7Entries[f7Src] ); +} + +//----------------------------------------------------------- +template +inline void C12Job::Run() +{ + TableWriter::WriteC12Entries( this->length, this->f7Entries, this->writeBuffer ); +} + +/// +/// C3 +/// +//----------------------------------------------------------- +inline uint64 TableWriter::GetC3ParkCount( const uint64 length, uint64& outLastParkRemainder ) +{ + const uint64 c3ParkCount = length / kCheckpoint1Interval; + const uint64 lastParkRemainder = length - ( c3ParkCount * kCheckpoint1Interval ); + + // First 1 is stored in the C1 park, so we ignore it here. + // Must have at least 1 delta + if( lastParkRemainder > 1 ) + { + outLastParkRemainder = lastParkRemainder - 1; + return c3ParkCount + 1; + } + + outLastParkRemainder = 0; + return c3ParkCount; +} + +//----------------------------------------------------------- +inline uint64 TableWriter::GetC3ParkCount( const uint64 length ) +{ + uint64 remainder; + return GetC3ParkCount( length, remainder ); +} + +//----------------------------------------------------------- +template +inline size_t TableWriter::WriteC3Parallel( ThreadPool& pool, uint32 threadCount, const uint64 length, uint32* f7Entries, byte* c3Buffer ) +{ + threadCount = std::min( threadCount, MAX_JOBS ); + + const uint64 parkCount = length / kCheckpoint1Interval; + const uint64 parksPerThread = parkCount / threadCount; + + uint64 trailingParks = parkCount - ( parksPerThread * threadCount ); + + const uint64 trailingEntries = length - ( parkCount * kCheckpoint1Interval ); + + // We need to check trailingEntries > 1 because the first entry is stored in C1. + // Therefore, we need to have at least 1 delta to write an extra C3 park. + const bool hasTrailingEntries = trailingEntries > 1; + const uint64 totalParksWritten = parkCount + ( hasTrailingEntries ? 1 : 0 ); + + const size_t c3Size = CalculateC3Size(); + + MTJobRunner jobs( pool ); + + uint32* threadF7Entries = f7Entries; + byte* threadC3Buffer = c3Buffer; + + for( uint32 i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job.parkCount = parksPerThread; + job.f7Entries = threadF7Entries; + job.writeBuffer = threadC3Buffer; + + // Distribute trailing parks accross threads + if( trailingParks ) + { + job.parkCount ++; + trailingParks --; + } + + threadF7Entries += job.parkCount * kCheckpoint1Interval; + threadC3Buffer += job.parkCount * c3Size; + } + + // Run jobs + jobs.Run( threadCount ); + + // Write any trailing entries to a park + if( hasTrailingEntries ) + WriteC3Park( trailingEntries-1, threadF7Entries, threadC3Buffer ); + + return totalParksWritten * c3Size; +} + +//----------------------------------------------------------- +inline void TableWriter::WriteC3Parks( const uint64 parkCount, uint32* f7Entries, byte* writeBuffer, uint32 jobId ) +{ + const size_t c3Size = CalculateC3Size(); + + for( uint64 i = 0; i < parkCount; i++ ) + { + WriteC3Park( kCheckpoint1Interval-1, f7Entries, writeBuffer, jobId ); + + f7Entries += kCheckpoint1Interval; + writeBuffer += c3Size; + } +} + +//----------------------------------------------------------- +inline void TableWriter::WriteC3Park( const uint64 length, uint32* f7Entries, byte* parkBuffer, uint32 jobId ) +{ + ASSERT( length <= kCheckpoint1Interval-1 ); + + const size_t c3Size = CalculateC3Size(); + + // Re-use f7Entries as the delta buffer. + // We won't use f7 entries after this, so we can re-write it. + byte* deltaWriter = (byte*)f7Entries; + + // f7Entries must always start at an interval of kCheckpoint1Interval + // Therefore its first entry is a C1 entry, and not written as a delta. + uint32 prevF7 = *f7Entries; + + // Convert to deltas + for( uint64 i = 1; i <= length; i++ ) + { + const uint32 f7 = f7Entries[i]; + const uint32 delta = f7 - prevF7; + prevF7 = f7; + + ASSERT( delta < 255 ); + *deltaWriter++ = (byte)delta; + } + + ASSERT( (uint64)(deltaWriter - (byte*)f7Entries) == length ); + + // Serialize them into the C3 park buffer + const size_t compressedSize = FSE_compress_usingCTable( + parkBuffer+2, c3Size, (byte*)f7Entries, + length, (const FSE_CTable*)CTable_C3 + ); + ASSERT( (compressedSize+2) < c3Size ); + + // Store size in the first 2 bytes + *((uint16*)parkBuffer) = Swap16( (uint16)compressedSize ); + + // Zero-out remainder (not necessary, though...) + const size_t remainder = c3Size - (compressedSize + 2); + if( remainder ) + memset( parkBuffer + compressedSize + 2, 0, remainder ); +} + +//----------------------------------------------------------- +inline void C3Job::Run() +{ + TableWriter::WriteC3Parks( this->parkCount, this->f7Entries, this->writeBuffer, this->_jobId ); +} + + diff --git a/src/plotting/Tables.h b/src/plotting/Tables.h new file mode 100644 index 00000000..53b3924d --- /dev/null +++ b/src/plotting/Tables.h @@ -0,0 +1,174 @@ +#pragma once + +enum class TableId +{ + Table1 = 0, + Table2 = 1, + Table3 = 2, + Table4 = 3, + Table5 = 4, + Table6 = 5, + Table7 = 6 + + ,_Count +}; ImplementArithmeticOps( TableId ); + +/// +/// Helpers for working with metadata +/// +struct NoMeta {}; // Used for when the metadata multiplier == 0 +struct Meta4 { uint64 m0, m1; }; // Used for when the metadata multiplier == 4 +struct Meta3 : Meta4{}; // Used for when the metadata multiplier == 3 + +template +struct SizeForMeta; + +template<> struct SizeForMeta { static constexpr size_t Value = 1; }; +template<> struct SizeForMeta { static constexpr size_t Value = 2; }; +template<> struct SizeForMeta { static constexpr size_t Value = 3; }; +template<> struct SizeForMeta { static constexpr size_t Value = 4; }; +template<> struct SizeForMeta { static constexpr size_t Value = 0; }; + +template +struct TableMetaType; + +template<> struct TableMetaType { using MetaIn = NoMeta; using MetaOut = uint32; }; +template<> struct TableMetaType { using MetaIn = uint32; using MetaOut = uint64; }; +template<> struct TableMetaType { using MetaIn = uint64; using MetaOut = Meta4; }; +template<> struct TableMetaType { using MetaIn = Meta4; using MetaOut = Meta4; }; +template<> struct TableMetaType { using MetaIn = Meta4; using MetaOut = Meta3; }; +template<> struct TableMetaType { using MetaIn = Meta3; using MetaOut = uint64; }; +template<> struct TableMetaType { using MetaIn = uint64; using MetaOut = NoMeta; }; + + +/// Helper for obtaining the correct fx (y) output type per table +template struct YOut { using Type = uint64; }; +template<> struct YOut { using Type = uint32; }; + + +/// +/// For Disk Plotter +/// + +// Metadata input +template +struct TableMetaIn; + +template<> struct TableMetaIn +{ + using MetaA = NoMeta; using MetaB = NoMeta; + static constexpr size_t SizeA = 0; static constexpr size_t SizeB = 0; + static constexpr size_t Multiplier = 0; +}; + +template<> struct TableMetaIn +{ + using MetaA = uint32; using MetaB = NoMeta; + static constexpr size_t SizeA = sizeof( uint32 ); static constexpr size_t SizeB = 0; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; +template<> struct TableMetaIn +{ + using MetaA = uint64; using MetaB = NoMeta; + static constexpr size_t SizeA = sizeof( uint64 ); static constexpr size_t SizeB = 0; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; +template<> struct TableMetaIn +{ + using MetaA = uint64; using MetaB = uint64; + static constexpr size_t SizeA = sizeof( uint64 ); static constexpr size_t SizeB = sizeof( uint64 ); + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; +template<> struct TableMetaIn +{ + using MetaA = uint64; using MetaB = uint64; + static constexpr size_t SizeA = sizeof( uint64 ); static constexpr size_t SizeB = sizeof( uint64 ); + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; +template<> struct TableMetaIn +{ + using MetaA = uint64; using MetaB = uint32; + static constexpr size_t SizeA = sizeof( uint64 ); static constexpr size_t SizeB = sizeof( uint32 ); + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; +template<> struct TableMetaIn +{ + using MetaA = uint64; using MetaB = NoMeta; + static constexpr size_t SizeA = sizeof( uint64 ); static constexpr size_t SizeB = 0; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; + + +// Metadata output +template +struct TableMetaOut; + +template<> struct TableMetaOut +{ + static constexpr TableId NextTable = TableId::Table2; + + using MetaA = TableMetaIn::MetaA; using MetaB = TableMetaIn::MetaB; + static constexpr size_t SizeA = TableMetaIn::SizeA; + static constexpr size_t SizeB = TableMetaIn::SizeB; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; + +template<> struct TableMetaOut +{ + static constexpr TableId NextTable = TableId::Table3; + + using MetaA = TableMetaIn::MetaA; using MetaB = TableMetaIn::MetaB; + static constexpr size_t SizeA = TableMetaIn::SizeA; + static constexpr size_t SizeB = TableMetaIn::SizeB; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; + +template<> struct TableMetaOut +{ + static constexpr TableId NextTable = TableId::Table4; + + using MetaA = TableMetaIn::MetaA; using MetaB = TableMetaIn::MetaB; + static constexpr size_t SizeA = TableMetaIn::SizeA; + static constexpr size_t SizeB = TableMetaIn::SizeB; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; + +template<> struct TableMetaOut +{ + static constexpr TableId NextTable = TableId::Table5; + + using MetaA = TableMetaIn::MetaA; using MetaB = TableMetaIn::MetaB; + static constexpr size_t SizeA = TableMetaIn::SizeA; + static constexpr size_t SizeB = TableMetaIn::SizeB; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; + +template<> struct TableMetaOut +{ + static constexpr TableId NextTable = TableId::Table6; + + using MetaA = TableMetaIn::MetaA; using MetaB = TableMetaIn::MetaB; + static constexpr size_t SizeA = TableMetaIn::SizeA; + static constexpr size_t SizeB = TableMetaIn::SizeB; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; + +template<> struct TableMetaOut +{ + static constexpr TableId NextTable = TableId::Table7; + + using MetaA = TableMetaIn::MetaA; using MetaB = TableMetaIn::MetaB; + static constexpr size_t SizeA = TableMetaIn::SizeA; + static constexpr size_t SizeB = TableMetaIn::SizeB; + static constexpr size_t Multiplier = ( SizeA + SizeB ) / 4; +}; + + +template<> struct TableMetaOut +{ + using MetaA = NoMeta; using MetaB = NoMeta; + static constexpr size_t SizeA = 0; static constexpr size_t SizeB = 0; + static constexpr size_t Multiplier = 0; +}; + +// static_assert( sizeof( NoMeta ) == 0, "Invalid NoMeta" ); diff --git a/src/plotting/WorkHeap.cpp b/src/plotting/WorkHeap.cpp new file mode 100644 index 00000000..1d61af92 --- /dev/null +++ b/src/plotting/WorkHeap.cpp @@ -0,0 +1,267 @@ +#include "WorkHeap.h" +#include "util/Util.h" +#include "util/Log.h" + +//----------------------------------------------------------- +WorkHeap::WorkHeap( size_t size, byte* heapBuffer ) + : _heap ( heapBuffer ) + , _heapSize ( size ) + , _usedHeapSize ( 0 ) + , _heapTable ( 256u ) + , _allocationTable ( 256u ) +{ + ASSERT( _heap ); + ASSERT( _heapSize ); + + // Initialize heap table + HeapEntry& firstEntry = _heapTable.Push(); + firstEntry.address = _heap; + firstEntry.size = _heapSize; +} + +//----------------------------------------------------------- +WorkHeap::~WorkHeap() +{ +} + +//----------------------------------------------------------- +void WorkHeap::ResetHeap( const size_t heapSize, void* heapBuffer ) +{ + ASSERT( _allocationTable.Length() == 0 ); + ASSERT( _heapTable.Length() == 1 ); + + _heap = (byte*)heapBuffer; + _heapSize = heapSize; + _heapTable[0].address = (byte*)heapBuffer; + _heapTable[0].size = heapSize; +} + +//----------------------------------------------------------- +byte* WorkHeap::Alloc( size_t size, size_t alignment, bool blockUntilFreeBuffer, Duration* accumulator ) +{ + ASSERT( size ); + size = alignment * CDivT( size, alignment ); + + ASSERT( size <= _heapSize ); + + // If we have such a buffer available, grab it, if not, we will + // have to wait for enough deallocations in order to continue + for( ;; ) + { + // First, add any pending released buffers back to the heap + CompletePendingReleases(); + + byte* buffer = nullptr; + + for( size_t i = 0; i < _heapTable.Length(); i++ ) + { + HeapEntry& entry = _heapTable[i]; + ASSERT( entry.EndAddress() <= _heap + _heapSize ); + + if( entry.CanAllocate( size, alignment ) ) + { + // Found a big enough slice to use + byte* alignedAddress = (byte*)( alignment * CDivT( (uintptr_t)entry.address, (uintptr_t)alignment ) ); + + _usedHeapSize += size; + + // We need to track the size of our buffers for when they are released. + HeapEntry& allocation = _allocationTable.Push(); + allocation.address = alignedAddress; + allocation.size = size; + + const size_t addressOffset = (size_t)( alignedAddress - entry.address ); + Log::Debug( "+ Allocated @ 0x%p : %llu", alignedAddress, size ); + + if( addressOffset ) + { + // If we did not occupy all of the remaining size in the entry, + // we need to insert a new entry to the right of the current one. + const size_t remainder = (size_t)( entry.EndAddress() - allocation.EndAddress() ); + + // Adjust the current entry's size to the space between the aligned address and the base address + entry.size = addressOffset; + ASSERT( entry.size ); + + if( remainder ) + { + HeapEntry& rightEntry = _heapTable.Insert( i + 1 ); + rightEntry.address = allocation.EndAddress(); + rightEntry.size = remainder; + ASSERT( rightEntry.size ); + } + } + else + { + if( size < _heapTable[i].size ) + { + // Split/fragment the current entry + entry.address += size; + entry.size -= size; + ASSERT( entry.size ); + } + else + { + // We took the whole entry, remove it from the table. + _heapTable.Remove( i ); + } + } + + buffer = alignedAddress; + break; + } + } + + if( buffer ) + return buffer; + + if( !blockUntilFreeBuffer ) + return nullptr; + + // No buffer found, we have to wait until buffers are released and then try again + // Log::Line( "*************************** No Buffers available waiting..." ); + auto timer = TimerBegin(); + _releaseSignal.Wait(); + + if( accumulator ) + { + (*accumulator) += TimerEndTicks( timer ); + } + + + // Log::Line( " *************************** Waited %.6lf seconds for a buffer.", TimerEnd( timer ) ); + } +} + +//----------------------------------------------------------- +bool WorkHeap::Release( byte* buffer ) +{ + ASSERT( buffer ); + ASSERT( buffer >= _heap && buffer < _heap + _heapSize ); + + bool queued = _pendingReleases.Enqueue( buffer ); + ASSERT( queued ); + + // _freeHeapSize.load( std::memory_order_acquire ); + _releaseSignal.Signal(); + return queued; +} + +//----------------------------------------------------------- +bool WorkHeap::CanAllocate( size_t size, size_t alignment ) const +{ + size = alignment * CDivT( size, alignment ); + + for( size_t i = 0; i < _heapTable.Length(); i++ ) + { + HeapEntry& entry = _heapTable[i]; + + if( entry.CanAllocate( size, alignment ) ) + return true; + } + + return false; +} + +//----------------------------------------------------------- +void WorkHeap::CompletePendingReleases() +{ + const int BUFFER_SIZE = 128; + byte* releases[BUFFER_SIZE]; + + // Grab pending releases + int count; + while( ( count = _pendingReleases.Dequeue( releases, BUFFER_SIZE ) ) ) + { + // Log::Debug( "Releasing %d buffers.", count ); + + for( int i = 0; i < count; i++ ) + { + byte* buffer = releases[i]; + Log::Debug( "-? Need Free %p", buffer ); + + // Find the buffer in the allocation table + #if _DEBUG + bool foundAllocation = false; + #endif + for( size_t j = 0; j < _allocationTable.Length(); j++ ) + { + if( _allocationTable[j].address == buffer ) + { + #if _DEBUG + foundAllocation = true; + #endif + + HeapEntry allocation = _allocationTable[j]; + _allocationTable.UnorderedRemove( j ); + + _usedHeapSize -= allocation.size; + + Log::Debug( "- Free %p : %llu", buffer, allocation.size ); + + size_t insertIndex = 0; + + // Find where to place the allocation back into the + for( ; insertIndex < _heapTable.Length(); insertIndex++ ) + { + if( _heapTable[insertIndex].address > buffer ) + break; + } + + // When adding the released buffer (entry) back to the heap table, + // one of 4 scenarios can happen: + // 1: Entry can be merged with the left entry, don't create a new entry, simply extend it. + // 2: Entry can be merged with the right entry, don't create a new entry, + // change the start address of the right entry and extend size. + // 3: Entry can be merged with both left and right entry, + // extend the left entry to cover the released entry and the right entry, + // then remove the right entry. + // 4: Entry cannot be merged with the left or the right entry, create a new entry + + + // Case 1? Can we merge with the left entry? + if( insertIndex > 0 && _heapTable[insertIndex - 1].EndAddress() == buffer ) + { + // Extend size to the released entry + HeapEntry& entry = _heapTable[insertIndex - 1]; + entry.size += allocation.size; + ASSERT( entry.size ); + + // Case 3? See if we also need to merge with the right entry (fills a hole between 2 entries). + if( insertIndex < _heapTable.Length() && allocation.EndAddress() == _heapTable[insertIndex].address ) + { + // Extend size to the right entry + entry.size += _heapTable[insertIndex].size; + _heapTable.Remove( insertIndex ); + ASSERT( entry.size ); + } + } + // Case 2? Can we merge with the right entry + else if( insertIndex < _heapTable.Length() && allocation.EndAddress() == _heapTable[insertIndex].address ) + { + // Don't create a new allocation, merge with the right entry + _heapTable[insertIndex].address = allocation.address; + _heapTable[insertIndex].size += allocation.size; + ASSERT( _heapTable[insertIndex].size ); + } + // Case 4: Insert a new entry, no merges + else + { + // We need to insert a new entry + _heapTable.Insert( allocation, insertIndex ); + ASSERT( _heapTable[insertIndex].size ); + } + + break; + } + } + + #if _DEBUG + FatalIf( !foundAllocation, "Failed to find released buffer." ); + #endif + + } + } +} + + diff --git a/src/plotting/WorkHeap.h b/src/plotting/WorkHeap.h new file mode 100644 index 00000000..d4b6219d --- /dev/null +++ b/src/plotting/WorkHeap.h @@ -0,0 +1,80 @@ +#pragma once +#include "threading/AutoResetSignal.h" +#include "util/SPCQueue.h" +#include "util/Array.h" +#include "plotdisk/DiskPlotConfig.h" + +// A simple heap to be used as our working buffer provider +// for doing plotting work in memory and I/O operations. +// It is meant to have a very small amount of allocations, therefore +// allocations are tracked in a small table that is searched linearly. +class WorkHeap +{ +private: + // Represents a portion of unallocated space in our heap/work buffer + struct HeapEntry + { + byte* address; + size_t size; + + inline byte* EndAddress() const { return address + size; } + + inline bool CanAllocate( size_t allocationSize, size_t alignment ) + { + ASSERT( allocationSize == RoundUpToNextBoundaryT( allocationSize, alignment ) ); + ASSERT( RoundUpToNextBoundaryT( allocationSize, alignment ) <= 0x7FFFFFFFFFFFFFFF ); + + const intptr_t alignedAddress = (intptr_t)alignment * CDivT( (intptr_t)address, (intptr_t)alignment ); + return ( (intptr_t)EndAddress() - alignedAddress ) >= (intptr_t)allocationSize; + } + }; + +public: + WorkHeap( size_t size, byte* heapBuffer ); + ~WorkHeap(); + + void ResetHeap( const size_t heapSize, void* heapBuffer ); + + // Allocate a buffer on the heap. + // If no space is available it will block until + // some space has become available again. + byte* Alloc( size_t size, size_t alignment = sizeof( intptr_t ), bool blockUntilFreeBuffer = true, Duration* accumulator = nullptr ); + + // Add a to the pending release list. + // The buffer won't actually be released until an allocation + // attempt is called or an explicit call AddPendingReleases() to is made. + // This is meant to be called by a producer thread. + bool Release( byte* buffer ); + + bool CanAllocate( size_t size, size_t alignment = sizeof( intptr_t ) ) const; + + inline size_t FreeSize() const { return _usedHeapSize - _heapSize; } + + inline size_t HeapSize() const { return _heapSize; } + + inline const void* Heap() const { return _heap; } + + + // Makes pending released allocations available to the heap for allocation again. + void CompletePendingReleases(); + +private: + +private: + byte* _heap; + size_t _heapSize; // Size of our work heap + size_t _usedHeapSize; // How much heap space is currently being used + + Array _heapTable; // Tracks unallocated space in our work heap + Array _allocationTable; // Tracks sizes and for currently allocated buffers. Used when performing releases. + + // #TODO: Make SPCQueue dynamically allocated. + SPCQueue _pendingReleases; // Released buffers waiting to be re-added to the heap table + AutoResetSignal _releaseSignal; // Used to signal that there's pending released buffers + + // std::atomic _freeHeapSize = 0; // Current free heap size from the perspective of the consumer thread (the allocating thread) + // std::atomic _waitingSize = 0; // Required size for the next allocation. If the next release + // does not add up to this size, then it won't signal it +}; + + diff --git a/src/pos/chacha8.cpp b/src/pos/chacha8.cpp index ac72614b..56f21afc 100644 --- a/src/pos/chacha8.cpp +++ b/src/pos/chacha8.cpp @@ -1,149 +1,149 @@ -#include "chacha8.h" - -#define U32TO32_LITTLE(v) (v) -#define U8TO32_LITTLE(p) (*(const uint32_t *)(p)) -#define U32TO8_LITTLE(p, v) (((uint32_t *)(p))[0] = U32TO32_LITTLE(v)) -#define ROTL32(v, n) (((v) << (n)) | ((v) >> (32 - (n)))) - -#define ROTATE(v, c) (ROTL32(v, c)) -#define XOR(v, w) ((v) ^ (w)) -#define PLUS(v, w) ((v) + (w)) -#define PLUSONE(v) (PLUS((v), 1)) - -#define QUARTERROUND(a, b, c, d) \ - a = PLUS(a, b); \ - d = ROTATE(XOR(d, a), 16); \ - c = PLUS(c, d); \ - b = ROTATE(XOR(b, c), 12); \ - a = PLUS(a, b); \ - d = ROTATE(XOR(d, a), 8); \ - c = PLUS(c, d); \ - b = ROTATE(XOR(b, c), 7) - -static const char sigma[] = "expand 32-byte k"; -static const char tau[] = "expand 16-byte k"; - -void chacha8_keysetup(struct chacha8_ctx *x, const uint8_t *k, uint32_t kbits, const uint8_t *iv) -{ - const char *constants; - - x->input[4] = U8TO32_LITTLE(k + 0); - x->input[5] = U8TO32_LITTLE(k + 4); - x->input[6] = U8TO32_LITTLE(k + 8); - x->input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ - k += 16; - constants = sigma; - } else { /* kbits == 128 */ - constants = tau; - } - x->input[8] = U8TO32_LITTLE(k + 0); - x->input[9] = U8TO32_LITTLE(k + 4); - x->input[10] = U8TO32_LITTLE(k + 8); - x->input[11] = U8TO32_LITTLE(k + 12); - x->input[0] = U8TO32_LITTLE(constants + 0); - x->input[1] = U8TO32_LITTLE(constants + 4); - x->input[2] = U8TO32_LITTLE(constants + 8); - x->input[3] = U8TO32_LITTLE(constants + 12); - if (iv) { - x->input[14] = U8TO32_LITTLE(iv + 0); - x->input[15] = U8TO32_LITTLE(iv + 4); - } else { - x->input[14] = 0; - x->input[15] = 0; - } -} - -void chacha8_get_keystream(const struct chacha8_ctx *x, uint64_t pos, uint32_t n_blocks, uint8_t *c) -{ - uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; - uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; - int i; - - j0 = x->input[0]; - j1 = x->input[1]; - j2 = x->input[2]; - j3 = x->input[3]; - j4 = x->input[4]; - j5 = x->input[5]; - j6 = x->input[6]; - j7 = x->input[7]; - j8 = x->input[8]; - j9 = x->input[9]; - j10 = x->input[10]; - j11 = x->input[11]; - j12 = (uint32_t)pos; - j13 = pos >> 32; - j14 = x->input[14]; - j15 = x->input[15]; - - while (n_blocks--) { - x0 = j0; - x1 = j1; - x2 = j2; - x3 = j3; - x4 = j4; - x5 = j5; - x6 = j6; - x7 = j7; - x8 = j8; - x9 = j9; - x10 = j10; - x11 = j11; - x12 = j12; - x13 = j13; - x14 = j14; - x15 = j15; - for (i = 8; i > 0; i -= 2) { - QUARTERROUND(x0, x4, x8, x12); - QUARTERROUND(x1, x5, x9, x13); - QUARTERROUND(x2, x6, x10, x14); - QUARTERROUND(x3, x7, x11, x15); - QUARTERROUND(x0, x5, x10, x15); - QUARTERROUND(x1, x6, x11, x12); - QUARTERROUND(x2, x7, x8, x13); - QUARTERROUND(x3, x4, x9, x14); - } - x0 = PLUS(x0, j0); - x1 = PLUS(x1, j1); - x2 = PLUS(x2, j2); - x3 = PLUS(x3, j3); - x4 = PLUS(x4, j4); - x5 = PLUS(x5, j5); - x6 = PLUS(x6, j6); - x7 = PLUS(x7, j7); - x8 = PLUS(x8, j8); - x9 = PLUS(x9, j9); - x10 = PLUS(x10, j10); - x11 = PLUS(x11, j11); - x12 = PLUS(x12, j12); - x13 = PLUS(x13, j13); - x14 = PLUS(x14, j14); - x15 = PLUS(x15, j15); - - j12 = PLUSONE(j12); - if (!j12) { - j13 = PLUSONE(j13); - /* stopping at 2^70 bytes per nonce is user's responsibility */ - } - - U32TO8_LITTLE(c + 0, x0); - U32TO8_LITTLE(c + 4, x1); - U32TO8_LITTLE(c + 8, x2); - U32TO8_LITTLE(c + 12, x3); - U32TO8_LITTLE(c + 16, x4); - U32TO8_LITTLE(c + 20, x5); - U32TO8_LITTLE(c + 24, x6); - U32TO8_LITTLE(c + 28, x7); - U32TO8_LITTLE(c + 32, x8); - U32TO8_LITTLE(c + 36, x9); - U32TO8_LITTLE(c + 40, x10); - U32TO8_LITTLE(c + 44, x11); - U32TO8_LITTLE(c + 48, x12); - U32TO8_LITTLE(c + 52, x13); - U32TO8_LITTLE(c + 56, x14); - U32TO8_LITTLE(c + 60, x15); - - c += 64; - } -} +#include "chacha8.h" + +#define U32TO32_LITTLE(v) (v) +#define U8TO32_LITTLE(p) (*(const uint32_t *)(p)) +#define U32TO8_LITTLE(p, v) (((uint32_t *)(p))[0] = U32TO32_LITTLE(v)) +#define ROTL32(v, n) (((v) << (n)) | ((v) >> (32 - (n)))) + +#define ROTATE(v, c) (ROTL32(v, c)) +#define XOR(v, w) ((v) ^ (w)) +#define PLUS(v, w) ((v) + (w)) +#define PLUSONE(v) (PLUS((v), 1)) + +#define QUARTERROUND(a, b, c, d) \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 16); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 12); \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 8); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 7) + +static const char sigma[] = "expand 32-byte k"; +static const char tau[] = "expand 16-byte k"; + +void chacha8_keysetup(struct chacha8_ctx *x, const uint8_t *k, uint32_t kbits, const uint8_t *iv) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); + if (iv) { + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); + } else { + x->input[14] = 0; + x->input[15] = 0; + } +} + +void chacha8_get_keystream(const struct chacha8_ctx *x, uint64_t pos, uint32_t n_blocks, uint8_t *c) +{ + uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + int i; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = (uint32_t)pos; + j13 = pos >> 32; + j14 = x->input[14]; + j15 = x->input[15]; + + while (n_blocks--) { + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 8; i > 0; i -= 2) { + QUARTERROUND(x0, x4, x8, x12); + QUARTERROUND(x1, x5, x9, x13); + QUARTERROUND(x2, x6, x10, x14); + QUARTERROUND(x3, x7, x11, x15); + QUARTERROUND(x0, x5, x10, x15); + QUARTERROUND(x1, x6, x11, x12); + QUARTERROUND(x2, x7, x8, x13); + QUARTERROUND(x3, x4, x9, x14); + } + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0, x0); + U32TO8_LITTLE(c + 4, x1); + U32TO8_LITTLE(c + 8, x2); + U32TO8_LITTLE(c + 12, x3); + U32TO8_LITTLE(c + 16, x4); + U32TO8_LITTLE(c + 20, x5); + U32TO8_LITTLE(c + 24, x6); + U32TO8_LITTLE(c + 28, x7); + U32TO8_LITTLE(c + 32, x8); + U32TO8_LITTLE(c + 36, x9); + U32TO8_LITTLE(c + 40, x10); + U32TO8_LITTLE(c + 44, x11); + U32TO8_LITTLE(c + 48, x12); + U32TO8_LITTLE(c + 52, x13); + U32TO8_LITTLE(c + 56, x14); + U32TO8_LITTLE(c + 60, x15); + + c += 64; + } +} diff --git a/src/pos/chacha8.h b/src/pos/chacha8.h index dcf353b2..6933ce4b 100644 --- a/src/pos/chacha8.h +++ b/src/pos/chacha8.h @@ -1,25 +1,25 @@ -#ifndef SRC_CHACHA8_H_ -#define SRC_CHACHA8_H_ - -#include - -struct chacha8_ctx { - uint32_t input[16]; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -void chacha8_keysetup(struct chacha8_ctx *x, const uint8_t *k, uint32_t kbits, const uint8_t *iv); -void chacha8_get_keystream( - const struct chacha8_ctx *x, - uint64_t pos, - uint32_t n_blocks, - uint8_t *c); - -#ifdef __cplusplus -} -#endif - -#endif // SRC_CHACHA8_H_ +#ifndef SRC_CHACHA8_H_ +#define SRC_CHACHA8_H_ + +#include + +struct chacha8_ctx { + uint32_t input[16]; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +void chacha8_keysetup(struct chacha8_ctx *x, const uint8_t *k, uint32_t kbits, const uint8_t *iv); +void chacha8_get_keystream( + const struct chacha8_ctx *x, + uint64_t pos, + uint32_t n_blocks, + uint8_t *c); + +#ifdef __cplusplus +} +#endif + +#endif // SRC_CHACHA8_H_ diff --git a/src/sandbox/Sandbox.h b/src/sandbox/Sandbox.h new file mode 100644 index 00000000..2712d8bc --- /dev/null +++ b/src/sandbox/Sandbox.h @@ -0,0 +1,6 @@ +#pragma once + +#include "threading/ThreadPool.h" + +//----------------------------------------------------------- +void TestF1Buckets( ThreadPool& pool, const byte plotId[32], const byte memoId[128] ); \ No newline at end of file diff --git a/src/sandbox/TestF1Buckets.cpp b/src/sandbox/TestF1Buckets.cpp new file mode 100644 index 00000000..b849ccd8 --- /dev/null +++ b/src/sandbox/TestF1Buckets.cpp @@ -0,0 +1,104 @@ +#include "Sandbox.h" +#include "plotdisk/jobs/F1GenBucketized.h" +#include "plotdisk/DiskPlotConfig.h" +#include "util/Util.h" +#include "util/Log.h" +#include "plotdisk/DiskPlotDebug.h" +#include "io/FileStream.h" +#include "algorithm/RadixSort.h" + +//----------------------------------------------------------- +void TestF1Buckets( ThreadPool& pool, const byte plotId[32], const byte memoId[128] ) +{ + const size_t totalEntries = 1ull << _K; + const size_t totalBlocks = totalEntries * sizeof( uint32 ) / kF1BlockSize; + const size_t entriesPerBlock = kF1BlockSize / sizeof( uint32 ); + + ASSERT( totalEntries == totalBlocks * entriesPerBlock ); + + byte* blocks = bbvirtalloc( totalEntries * sizeof( uint32 ) ); + uint32* yBuckets = bbcvirtalloc( totalEntries * 2 ); + uint32* xBuckets = yBuckets + totalEntries; + + uint32 bucketCounts[BB_DP_BUCKET_COUNT]; + + Log::Line( "Generating in-memory bucketized F1..." ); + F1GenBucketized::GenerateF1Mem( plotId, pool, pool.ThreadCount(), blocks, yBuckets, xBuckets, bucketCounts ); + SysHost::VirtualFree( blocks ); blocks = nullptr; + + uint32* yBucketTmp = xBuckets; + + // Now validate it + uint64 refEntryCount = 0; + uint64* refEntries = nullptr; + + // Read the whole reference table into memory + Log::Line( "Loading reference table..." ); + { + char path[1024]; + sprintf( path, "%st%d.y.tmp", BB_DP_DBG_REF_DIR, 1 ); + + FileStream refTable; + FatalIf( !refTable.Open( path, FileMode::Open, FileAccess::Read, FileFlags::LargeFile | FileFlags::NoBuffering ), + "Failed to open reference table file %s.", path ); + + const size_t blockSize = refTable.BlockSize(); + const uint64 maxEntries = 1ull << _K; + + const size_t allocSize = RoundUpToNextBoundaryT( (size_t)maxEntries * sizeof( uint64 ), blockSize ); + + refEntries = bbvirtalloc( allocSize ); + + // The first block contains the entry count + FatalIf( refTable.Read( refEntries, blockSize ) != blockSize, + "Failed to read count from reference table file %s with error: %d.", path, refTable.GetError() ); + + refEntryCount = *refEntries; + + ASSERT( refEntryCount <= maxEntries ); + + size_t sizeToRead = allocSize; + byte* reader = (byte*)refEntries; + while( sizeToRead ) + { + // The rest of the blocks are entries + const ssize_t sizeRead = refTable.Read( reader, sizeToRead ); + FatalIf( sizeRead <= 0, "Failed to read entries from reference table file %s with error: %d.", path, refTable.GetError() ); + + sizeToRead -= (size_t)sizeRead; + reader += sizeRead; + } + } + + uint32* yReader = yBuckets; + const uint64* refReader = refEntries; + + for( uint bucket = 0; bucket < BB_DP_BUCKET_COUNT; bucket++ ) + { + Log::Line( "Bucket %u", bucket+1 ); + + const int64 entryCount = bucketCounts[bucket]; + + // Sort the bucket + Log::Line( " Sorting bucket..." ); + RadixSort256::Sort( pool, yReader, yBucketTmp, (uint64)entryCount ); + + // Start validating + Log::Line( " Validating entries..."); + const uint64 bucketMask = ((uint64)bucket) << 32; + + for( int64 i = 0; i < entryCount; i++, yReader++, refReader++ ) + { + const uint64 y = bucketMask | *yReader; + const uint64 yRef = *refReader; + + const uint32 y32 = *yReader; + const uint32 y32Ref = (uint32)yRef; + + FatalIf( y != yRef, "Failed to validate entry on table %d at bucket position %u:%lld | Global position: %lld", + (int)1, bucket, i, (int64)( refReader - refEntries ) ); + } + + Log::Line( " Bucket %u validated successfully!", bucket+1 ); + } +} \ No newline at end of file diff --git a/src/test/test_main.cpp b/src/sandbox/sandbox_main.cpp similarity index 100% rename from src/test/test_main.cpp rename to src/sandbox/sandbox_main.cpp diff --git a/src/test/test_numa_sort.cpp b/src/sandbox/test_numa_sort.cpp similarity index 99% rename from src/test/test_numa_sort.cpp rename to src/sandbox/test_numa_sort.cpp index 2189ba71..04acc2af 100644 --- a/src/test/test_numa_sort.cpp +++ b/src/sandbox/test_numa_sort.cpp @@ -1,12 +1,12 @@ #include "threading/ThreadPool.h" #include "SysHost.h" -#include "Util.h" +#include "util/Util.h" #include "util/Log.h" #include "algorithm/RadixSort.h" #include "pos/chacha8.h" #include "ChiaConsts.h" #include "algorithm/YSort.h" -#include "memplot/FxSort.h" +#include "plotmem/FxSort.h" #include #include diff --git a/src/threading/AutoResetSignal.cpp b/src/threading/AutoResetSignal.cpp new file mode 100644 index 00000000..883c4620 --- /dev/null +++ b/src/threading/AutoResetSignal.cpp @@ -0,0 +1,161 @@ +#include "AutoResetSignal.h" +#include "util/Util.h" +#include "util/Log.h" + +#if PLATFORM_IS_WINDOWS + #include +#endif + +//----------------------------------------------------------- +AutoResetSignal::AutoResetSignal() +{ +#if PLATFORM_IS_WINDOWS + _object = CreateEvent( NULL, FALSE, FALSE, NULL ); + PanicIf( !_object, "AutoResetSignal::AutoResetSignal() CreateEvent() failed with error: %d.", (int32)::GetLastError() ); +#else + ZeroMem( &_object ); + + int r; + r = pthread_mutex_init( &_object.mutex, 0 ); + PanicIf( r, "AutoResetSignal::AutoResetSignal() pthread_mutex_init failed with error %d.", r ); + + r = pthread_cond_init( &_object.cond , 0 ); + PanicIf( r, "AutoResetSignal::AutoResetSignal() pthread_cond_init failed with error %d.", r ); +#endif +} + + +//----------------------------------------------------------- +AutoResetSignal::~AutoResetSignal() +{ +#if PLATFORM_IS_WINDOWS + const BOOL r = ::CloseHandle( _object ); + PanicIf( !r, "AutoResetSignal::~AutoResetSignal() CloseHandle() failed with error: %d.", (int32)::GetLastError() ); +#else + // #TODO: Log error + int r; + r = pthread_mutex_destroy( &_object.mutex ); + if( r ) + Log::Error( "AutoResetSignal::~AutoResetSignal() pthread_mutex_destroy() failed." ); + + r = pthread_cond_destroy ( &_object.cond ); + if( r ) + Log::Error( "AutoResetSignal::~AutoResetSignal() pthread_cond_destroy() failed." ); +#endif +} +//----------------------------------------------------------- +void AutoResetSignal::Reset() +{ +#if PLATFORM_IS_WINDOWS + const BOOL r = ::ResetEvent( _object ); + PanicIf( !r, "AutoResetSignal::Reset ResetEvent() failed with error: %d.", (int32)GetLastError() ); +#else + int r; + + r = pthread_mutex_lock( &_object.mutex ); + PanicIf( r, "AutoResetSignal::Signal pthread_mutex_lock() failed with error %d.", r ); + + _object.signaled = false; + + r = pthread_mutex_unlock( &_object.mutex ); + PanicIf( r, "AutoResetSignal::Signal pthread_mutex_unlock() failed with error %d.", r ); +#endif +} + +//----------------------------------------------------------- +void AutoResetSignal::Signal() +{ +#if PLATFORM_IS_WINDOWS + const BOOL r = SetEvent( _object ); + PanicIf( !r, "AutoResetSignal::Signal() SetEvent() failed with error: %d.", (int32)::GetLastError() ); +#else + int r; + + r = pthread_mutex_lock( &_object.mutex ); + PanicIf( r, "AutoResetSignal::Signal pthread_mutex_lock() failed with error %d.", r ); + + _object.signaled = true; + + r = pthread_cond_signal( &_object.cond ); + PanicIf( r, "AutoResetSignal::Signal pthread_cond_signal() failed with error %d.", r ); + + r = pthread_mutex_unlock( &_object.mutex ); + PanicIf( r, "AutoResetSignal::Signal pthread_mutex_unlock() failed with error %d.", r ); +#endif +} + +//----------------------------------------------------------- +AutoResetSignal::WaitResult AutoResetSignal::Wait( int32 timeoutMS ) +{ +#if PLATFORM_IS_WINDOWS + if( timeoutMS == WaitInfinite ) + timeoutMS = INFINITE; + + const DWORD r = WaitForSingleObject( _object, (DWORD)timeoutMS ); + + switch( r ) + { + case WAIT_OBJECT_0: + return WaitResultOK; + + case WAIT_TIMEOUT: + return WaitResultTimeOut; + + default: + // We never really handle this case, so just panic out + Panic( "AutoResetSignal::Wait WaitForSingleObject() failed with error: %d.", (int32)::GetLastError() ); + return WaitResultError; + } + +#else + + int r; + int rc = 0; + + if( timeoutMS == WaitInfinite ) + { + r = pthread_mutex_lock( &_object.mutex ); + PanicIf( r, "AutoResetSignal::Wait pthread_mutex_lock() failed with error %d.", r ); + + while( !_object.signaled ) + rc = pthread_cond_wait( &_object.cond, &_object.mutex ); + + _object.signaled = false; + + r = pthread_mutex_unlock( &_object.mutex ); + PanicIf( r, "AutoResetSignal::Wait pthread_mutex_unlock() failed with error %d.", r ); + } + else + { + struct timespec t; + + r = pthread_mutex_lock( &_object.mutex ); + PanicIf( r, "AutoResetSignal::Wait pthread_mutex_lock() failed with error %d.", r ); + + clock_gettime( CLOCK_REALTIME, &t ); + timeoutMS += ( t.tv_sec * 1000 ) + ( t.tv_nsec / 1000000 ); + + t.tv_sec = (time_t)( timeoutMS / 1000 ); + t.tv_nsec = (long)( timeoutMS - (t.tv_sec * 1000) ) * 1000000; + + while( !_object.signaled && rc == 0 ) + rc = pthread_cond_timedwait( &_object.cond, &_object.mutex, &t ); + + _object.signaled = false; + + r = pthread_mutex_unlock( &_object.mutex ); + PanicIf( r, "AutoResetSignal::Wait pthread_mutex_unlock() failed with error %d.", r ); + } + + switch( rc ) + { + case 0: + return WaitResultOK; + case ETIMEDOUT: + return WaitResultTimeOut; + default: + Panic( "AutoResetSignal::Wait Unexpected return code for pthread_cond_timedwait(): %d.", rc ); + return WaitResultError; + } +#endif +} diff --git a/src/threading/AutoResetSignal.h b/src/threading/AutoResetSignal.h new file mode 100644 index 00000000..e93bd3d9 --- /dev/null +++ b/src/threading/AutoResetSignal.h @@ -0,0 +1,42 @@ +#pragma once +#include "Platform.h" + +class AutoResetSignal +{ +public: + enum + { + WaitInfinite = -1 + }; + + enum WaitResult + { + WaitResultError = 0, + WaitResultOK = 1, + WaitResultTimeOut = -1 + }; + + AutoResetSignal(); + ~AutoResetSignal(); + + void Reset(); + void Signal(); + + WaitResult Wait( int32 timeoutMS = WaitInfinite ); + +private: + +#if PLATFORM_IS_WINDOWS + HANDLE _object = NULL; +#elif PLATFORM_IS_UNIX + struct AutoResetObject + { + pthread_mutex_t mutex; + pthread_cond_t cond; + bool signaled; + }; + AutoResetObject _object; +#else + #error Unsupported platform +#endif +}; \ No newline at end of file diff --git a/src/threading/Fence.cpp b/src/threading/Fence.cpp new file mode 100644 index 00000000..03425399 --- /dev/null +++ b/src/threading/Fence.cpp @@ -0,0 +1,70 @@ +#include "Fence.h" + +//----------------------------------------------------------- +Fence::Fence() + : _value ( 0 ) + , _signal() +{ +} + +//----------------------------------------------------------- +Fence::~Fence() +{ +} + +//----------------------------------------------------------- +void Fence::Signal() +{ + _value ++; + _signal.Signal(); +} + +//----------------------------------------------------------- +void Fence::Signal( uint32 value ) +{ + // _value.store( value, std::memory_order_release ); + _value = value; + _signal.Signal(); +} + +//----------------------------------------------------------- +void Fence::Reset( uint32 value ) +{ + // _value.store( value, std::memory_order_release ); + _value = value; + _signal.Reset(); +} + +//----------------------------------------------------------- +void Fence::Wait() +{ + _signal.Wait(); +} + +//----------------------------------------------------------- +void Fence::Wait( Duration& accumulator ) +{ + const auto startTime = TimerBegin(); + _signal.Wait(); + accumulator += TimerEndTicks( startTime ); +} + +//----------------------------------------------------------- +void Fence::Wait( uint32 value ) +{ + // while( _value.load( std::memory_order_relaxed ) < value ) + while( _value < value ) + _signal.Wait(); +} + +//----------------------------------------------------------- +void Fence::Wait( uint32 value, Duration& accumulator ) +{ + while( _value < value ) + { + const auto startTime = TimerBegin(); + _signal.Wait(); + accumulator += TimerEndTicks( startTime ); + } +} + diff --git a/src/threading/Fence.h b/src/threading/Fence.h new file mode 100644 index 00000000..05e4f9f1 --- /dev/null +++ b/src/threading/Fence.h @@ -0,0 +1,137 @@ +#pragma once +#include "threading/AutoResetSignal.h" +#include "util/Util.h" + +class Fence +{ +public: + Fence(); + ~Fence(); + + // inline uint32 Value() const { return _value.load( std::memory_order_acquire ); } + inline uint32 Value() const { return _value; } + + // Should be only called by a single producer (ie. only 1 thread). + void Signal(); + + void Signal( uint32 value ); + + // Should only be used when you know that the producer thread will not call Signal anymore. + void Reset( uint32 value = 0 ); + + // Wait until the fence is signalled with any value + void Wait(); + + // Wait until the fence is signalled with any value + void Wait( Duration& accumulator ); + + // Wait until the fence reaches or passes the specified value + void Wait( uint32 value ); + + // Wait until the fence reaches or passes the specified value + void Wait( uint32 value, Duration& accumulator ); + +private: + // std::atomic _value; + // #NOTE: Don't think we need atomic, since memory ordering ought to be enforced by the mutex. + volatile uint32 _value = 0; + AutoResetSignal _signal; + +}; + +class FencePool +{ +public: + //----------------------------------------------------------- + inline + FencePool( const uint32 capacity ) + : _fences( new Fence[capacity] ) + , _availableFences( new Fence*[capacity] ) + , _capacity( capacity ) + { + ASSERT( capacity > 0 ); + + RestoreAllFences(); + } + + //----------------------------------------------------------- + inline ~FencePool() + { + delete[] _availableFences; + delete[] _fences; + } + + //----------------------------------------------------------- + inline Fence* GetFence() + { + for( uint32 i = 0; i < _capacity; i++ ) + { + if( _availableFences[i] != nullptr ) + { + Fence* fence = _availableFences[i]; + _availableFences[i] = nullptr; + fence->Reset( 0 ); + return fence; + } + } + + return nullptr; + } + + //----------------------------------------------------------- + inline Fence& RequireFence() + { + Fence* fence = GetFence(); + PanicIf( !fence, "No fences available in pool." ); + + return *fence; + } + + //----------------------------------------------------------- + inline void ReleaseFence( Fence& fence ) + { + #if _DEBUG + { + bool foundFence = false; + for( uint32 i = 0; i < _capacity; i++ ) + { + if( _fences+i == &fence ) + { + foundFence = true; + break; + } + } + ASSERT( foundFence ); + + for( uint32 i = 0; i < _capacity; i++ ) + { + ASSERT( _availableFences[i] != &fence ); + } + } + #endif + + for( uint32 i = 0; i < _capacity; i++ ) + { + if( _availableFences[i] == nullptr ) + { + _availableFences[i] = &fence; + return; + } + } + + ASSERT( 0 ); + } + + //----------------------------------------------------------- + inline void RestoreAllFences() + { + for( uint32 i = 0; i < _capacity; i++ ) + _availableFences[i] = _fences+i; + } + +private: + Fence* _fences; + Fence** _availableFences; + uint32 _capacity; +}; + diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h new file mode 100644 index 00000000..5d83130b --- /dev/null +++ b/src/threading/MTJob.h @@ -0,0 +1,479 @@ +#pragma once + +#include "Config.h" +#include "threading/ThreadPool.h" +#include +#if _DEBUG + #include "util/Log.h" +#endif + +#include + +template +struct MTJobRunner; + +template +struct MTJobSyncT +{ + std::atomic* _finishedCount; + std::atomic* _releaseLock; + uint _jobId; + uint _jobCount; + TJob* _jobs; + + // Synchronize all threads before continuing to the next step + inline void SyncThreads(); + + // Lock Threads & to perform something before continuing to the next parallel step. + // Returns true if the job id is 0, that is, the control thread. + inline bool LockThreads(); + + // Only to be called from the control thread. + // Releases threads that are waiting for the control + // thread to do some synchronized work. + inline void ReleaseThreads(); + + // Use this if LockThreads returns false. + // This is to be used by the non-control threads + // to wait for the control thread to release the lock on us. + inline void WaitForRelease(); + + // Reduce the _jobCount to the specified amount. + // This is useful when a job needs to continue + // from its Run() function, but it needs to complete + // with less threads than it originally started with. + inline bool ReduceThreadCount( uint newThreadCount ); + + // Locks the threads if this is the control thread and returns true. + // otherwise, waits for release from the control thread and returns false. + inline bool LockOrWait(); + + // Utility functions to simplify control-thread locking + // and releasing code. This helps keep code the same for all threads + // by locking only if it is the controls thread, otherwise + // waiting for release. + // BeginLockBlock() is the same as LockOrWait(). Only different for consistency in call name. + // EndLockBlock() will do nothing if this is not the control thread. + inline bool BeginLockBlock(); + inline void EndLockBlock(); + + inline uint JobId() const { return _jobId; } + inline uint JobCount() const { return _jobCount; } + + inline bool IsControlThread() const { return _jobId == 0; } + inline bool IsLastThread() const { return _jobId == _jobCount-1; } + + inline const TJob& GetJob( uint index ) const + { + ASSERT( index < _jobCount ); + return _jobs[index]; + }; + + inline const TJob& GetJob( int index ) const + { + ASSERT( index >= 0 ); + ASSERT( (uint)index < _jobCount ); + return _jobs[index]; + }; + + inline const TJob& LastJob() const { return _jobs[_jobCount-1]; } + + // For debugging + #if _DEBUG + inline void Trace( const char* msg, ... ); + #else + inline void Trace( const char* msg, ... ) {} + #endif +}; + +template +static void RunAnonymous( F&& f, Args&&... args ); + +struct MTJobSync : public MTJobSyncT {}; + +template +struct MTJob : public MTJobSyncT +{ + inline virtual ~MTJob() {} + + template + friend struct MTJobRunner; + + // Override in the job itself + virtual void Run() = 0; +}; + + +template +struct MTJobRunner +{ + MTJobRunner( ThreadPool& pool ); + + double Run(); + double Run( uint32 threadCount ); + + inline TJob& operator[]( uint64 index ) { return this->_jobs[index]; } + inline TJob& operator[]( int64 index ) { return this->_jobs[index]; } + inline TJob& operator[]( uint index ) { return this->_jobs[index]; } + inline TJob& operator[]( int index ) { return this->_jobs[index]; } + + inline TJob* Jobs() { return _jobs; } + +private: + static void RunJobWrapper( TJob* job ); + +private: + TJob _jobs[MaxJobs]; + ThreadPool& _pool; +}; + + +struct AnonMTJob : public MTJob +{ + std::function* func; + + inline void Run() override { (*func)( this ); } + + // Run anononymous job, from a lambda, for example + template>* = nullptr> + inline static void Run( ThreadPool& pool, const uint32 threadCount, F&& func ) + { + std::function f = func; + + MTJobRunner jobs( pool ); + for( uint32 i = 0; i< threadCount; i++ ) + { + auto& job = jobs[i]; + job.func = &f; + } + + jobs.Run( threadCount ); + } + + template + inline static void Run( ThreadPool& pool, F&& func ) + { + Run( pool, pool.ThreadCount(), func ); + } +}; + + + +template +inline MTJobRunner::MTJobRunner( ThreadPool& pool ) + : _pool( pool ) +{} + +template +inline double MTJobRunner::Run() +{ + return this->Run( this->_pool.ThreadCount() ); +} + +template +inline double MTJobRunner::Run( uint32 threadCount ) +{ + // Set thread ids and atomic locks + ASSERT( threadCount <= MaxJobs ); + + std::atomic finishedCount = 0; + std::atomic releaseLock = 0; + + for( uint i = 0; i < threadCount; i++ ) + { + MTJob& job = *static_cast*>( &_jobs[i] ); + + job._finishedCount = &finishedCount; + job._releaseLock = &releaseLock; + job._jobId = i; + job._jobCount = threadCount; + job._jobs = _jobs; + } + + // Run the job + const auto timer = TimerBegin(); + _pool.RunJob( RunJobWrapper, _jobs, threadCount ); + const double elapsed = TimerEnd( timer ); + + return elapsed; +} + +template +inline void MTJobRunner::RunJobWrapper( TJob* job ) +{ + //job->Run(); + static_cast*>( job )->Run(); +} + + +template +inline void MTJobSyncT::SyncThreads() +{ + if( LockThreads() ) + ReleaseThreads(); + else + WaitForRelease(); +} + +template +inline bool MTJobSyncT::LockThreads() +{ + if( this->_jobId == 0 ) + { + ASSERT( _jobId == 0 ); + + auto& finishedCount = *this->_finishedCount; + const uint threadThreshold = this->_jobCount - 1; + + // Trace( "Locking Threads..." ); + // Wait for all threads to finish + while( finishedCount.load( std::memory_order_relaxed ) != threadThreshold ); + // Trace( "---- All threads Locked ----." ); + return true; + } + + return false; +} + +template +inline void MTJobSyncT::ReleaseThreads() +{ + ASSERT( _jobId == 0 ); + + auto& finishedCount = *this->_finishedCount; + auto& releaseLock = *this->_releaseLock; + + // Trace( "Releasing threads..." ); + // Release lock & signal other threads + // Trace( "++++ Releasing all threads ++++" ); + releaseLock .store( 0, std::memory_order_release ); + finishedCount.store( 0, std::memory_order_release ); +} + +template +inline void MTJobSyncT::WaitForRelease() +{ + ASSERT( _jobId != 0 ); + + auto& finishedCount = *this->_finishedCount; + auto& releaseLock = *this->_releaseLock; + const uint threadThreshold = this->_jobCount - 1; + + // Signal the control thread that we're ready to sync + // uint count = finishedCount.load( std::memory_order_acquire ); + finishedCount++; + ASSERT( finishedCount <= threadThreshold ); + // while( !finishedCount.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); + // Trace( "- locked: %d", count ); + + // Wait for the control thread (id == 0 ) to signal us + while( finishedCount.load( std::memory_order_relaxed ) != 0 ); + + // Ensure all threads have been released (prevent re-locking before another thread has been released) + // count = releaseLock.load( std::memory_order_acquire ); + // while( !releaseLock.compare_exchange_weak( count, count+1, std::memory_order_release, std::memory_order_relaxed ) ); + ASSERT( releaseLock <= threadThreshold ); + releaseLock++; + while( releaseLock.load( std::memory_order_relaxed ) != threadThreshold ); + // Trace( " released: %d", count ); +} + + +//----------------------------------------------------------- +template +inline bool MTJobSyncT::LockOrWait() +{ + if( this->IsControlThread() ) + { + this->LockThreads(); + return true; + } + else + { + this->WaitForRelease(); + } + + return false; +} + +//----------------------------------------------------------- +template +inline bool MTJobSyncT::BeginLockBlock() +{ + return LockOrWait(); +} + +//----------------------------------------------------------- +template +inline void MTJobSyncT::EndLockBlock() +{ + if( this->IsControlThread() ) + this->ReleaseThreads(); +} + +//----------------------------------------------------------- +template +inline bool MTJobSyncT::ReduceThreadCount( uint newThreadCount ) +{ + ASSERT( newThreadCount < _jobCount ); + ASSERT( newThreadCount >= 0 ); + + // Does this thread need to synchronize? + // If not, don't participate + if( _jobId >= newThreadCount ) + return false; + + // Update our job count + this->_jobCount = newThreadCount; + + // Now synchronize + this->SyncThreads(); + + return true; +} + + +#if _DEBUG +//----------------------------------------------------------- +template +inline void MTJobSyncT::Trace( const char* msg, ... ) +{ + const size_t BUF_SIZE = 512; + char buf1[BUF_SIZE]; + char buf2[BUF_SIZE]; + + va_list args; + va_start( args, msg ); + int r = vsnprintf( buf1, BUF_SIZE, msg, args ); + va_end( args ); + ASSERT( r > 0 ); + + r = snprintf( buf2, BUF_SIZE, "[%2u]: %s\n", _jobId, buf1 ); + ASSERT( r > 0 ); + + const size_t size = std::min( BUF_SIZE, (size_t)r ); + Log::SafeWrite( buf2, size ); +} + +#endif + +/// Helper Job that calculates a prefix sum +template +struct PrefixSumJob : public MTJob +{ + inline virtual ~PrefixSumJob() {} + + TCount* counts; + + inline void CalculatePrefixSum( + uint32 bucketSize, + TCount* counts, + TCount* pfxSum, + TCount* bucketCounts ); +}; + +//----------------------------------------------------------- +template +inline void PrefixSumJob::CalculatePrefixSum( + uint32 bucketSize, + TCount* counts, + TCount* pfxSum, + TCount* bucketCounts ) +{ + const uint32 jobId = this->JobId(); + const uint32 jobCount = this->JobCount(); + + this->counts = counts; + this->SyncThreads(); + + // Add up all of the jobs counts + memset( pfxSum, 0, sizeof( TCount ) * bucketSize ); + + for( uint32 i = 0; i < jobCount; i++ ) + { + const TCount* tCounts = this->GetJob( i ).counts; + + for( uint32 j = 0; j < bucketSize; j++ ) + pfxSum[j] += tCounts[j]; + } + + // If we're the control thread, retain the total bucket count + if( this->IsControlThread() ) + { + memcpy( bucketCounts, pfxSum, sizeof( TCount ) * bucketSize ); + } + + // Calculate the prefix sum + for( uint32 i = 1; i < bucketSize; i++ ) + pfxSum[i] += pfxSum[i-1]; + + // Subtract the count from all threads after ours + // to get the correct prefix sum for this thread + for( uint32 t = jobId+1; t < jobCount; t++ ) + { + const TCount* tCounts = this->GetJob( t ).counts; + + for( uint32 i = 0; i < bucketSize; i++ ) + pfxSum[i] -= tCounts[i]; + } +} + + +//----------------------------------------------------------- +template +struct AnonPrefixSumJob : public PrefixSumJob, TCount> +{ + std::function* func; + + inline void Run() override { (*func)( this ); } + + // Run anononymous job, from a lambda, for example + template*>>* = nullptr> + inline static void Run( ThreadPool& pool, const uint32 threadCount, F&& func ) + { + std::function*)> f = func; + + MTJobRunner> jobs( pool ); + for( uint32 i = 0; i< threadCount; i++ ) + { + auto& job = jobs[i]; + job.func = &f; + } + + jobs.Run( threadCount ); + } + + template + inline static void Run( ThreadPool& pool, F&& func ) + { + Run( pool, pool.ThreadCount(), func ); + } +}; + +//----------------------------------------------------------- +template +inline void GetThreadOffsets( const uint32 id, const uint32 threadCount, const T totalCount, T& count, T& offset, T& end ) +{ + const T countPerThread = totalCount / (T)threadCount; + const T remainder = totalCount - countPerThread * (T)threadCount; + + count = countPerThread; + offset = (T)id * countPerThread; + + if( id == threadCount-1 ) + count += remainder; + + end = offset + count; +} + +//----------------------------------------------------------- +template +inline void GetThreadOffsets( MTJob* job, const T totalCount, T& count, T& offset, T& end ) +{ + GetThreadOffsets( job->JobId(), job->JobCount(), totalCount, count, offset, end ); +} + diff --git a/src/threading/Semaphore.cpp b/src/threading/Semaphore.cpp index 10c418e8..52ffc7f2 100644 --- a/src/threading/Semaphore.cpp +++ b/src/threading/Semaphore.cpp @@ -1,136 +1,169 @@ -#include "Semaphore.h" -#include "Util.h" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -//----------------------------------------------------------- -Semaphore::Semaphore( int initialCount ) - #if PLATFORM_IS_WINDOWS - : _count( initialCount ) - #endif -{ - #if PLATFORM_IS_UNIX - int r = sem_init( &_id, 0, initialCount ); - if( r != 0 ) - Fatal( "sem_init() failed." ); - #elif PLATFORM_IS_WINDOWS - _id = CreateSemaphore( NULL,(LONG)initialCount, std::numeric_limits::max(), NULL ); - if( _id == NULL ) - Fatal( "CreateSemaphore() failed." ); - #else - #error Unimplemented - #endif -} - -//----------------------------------------------------------- -Semaphore::~Semaphore() -{ - #if PLATFORM_IS_UNIX - int r = sem_destroy( &_id ); - if( r != 0 ) - Fatal( "sem_destroy() failed." ); - #elif PLATFORM_IS_WINDOWS - if( !CloseHandle( _id ) ) - Fatal( "CloseHandle( semaphore ) failed." ); - #else - #error Unimplemented - #endif -} - -//----------------------------------------------------------- -void Semaphore::Wait() -{ - #if PLATFORM_IS_UNIX - const int r = sem_wait( &_id ); - if( r != 0 ) - Fatal( "sem_wait() failed." ); - #elif PLATFORM_IS_WINDOWS - const DWORD r = WaitForSingleObject( _id, INFINITE ); - if( r != WAIT_OBJECT_0 ) - Fatal( "PLATFORM_IS_WINDOWS( semaphore ) failed." ); - #else - #error Unimplemented - #endif -} - -//----------------------------------------------------------- -bool Semaphore::Wait( long milliseconds ) -{ - if( milliseconds < 1 ) - { - Wait(); - return true; - } - - #if PLATFORM_IS_LINUX - - long seconds = milliseconds / 1000; - milliseconds -= seconds * 1000; - - struct timespec abstime; - - if( clock_gettime( CLOCK_REALTIME, &abstime ) == -1 ) - { - ASSERT( 0 ); - return false; - } - - int r = sem_timedwait( &_id, &abstime ); - - if( r != 0 && r != ETIMEDOUT ) - Fatal( "sem_wait() failed." ); - - return r == 0; - #elif PLATFORM_IS_MACOS - // #TODO: Implement on macOS with condition variable - return false; - #elif PLATFORM_IS_WINDOWS - const DWORD r = WaitForSingleObject( _id, (DWORD)milliseconds ); - return r == WAIT_OBJECT_0 || r == WAIT_TIMEOUT; - #else - #error Unimplemented - #endif -} - -//----------------------------------------------------------- -int Semaphore::GetCount() -{ - #if PLATFORM_IS_UNIX - - int value = 0; - int r = sem_getvalue( &_id, &value ); - - if( r != 0 ) - Fatal( "sem_getvalue() failed." ); - - return value; - #elif PLATFORM_IS_WINDOWS - return _count.load( std::memory_order::memory_order_release ); - #else - #error Unimplemented - #endif -} - -//----------------------------------------------------------- -void Semaphore::Release() -{ - #if PLATFORM_IS_UNIX - int r = sem_post( &_id ); - if( r != 0 ) - Fatal( "sem_post() failed." ); - #elif PLATFORM_IS_WINDOWS - LONG prevCount; - BOOL r = ::ReleaseSemaphore( _id, 1, &prevCount ); - - if( !r ) - Fatal( "ReleaseSemaphore() failed." ); - - _count++; - #else - #error Unimplemented - #endif -} - -#pragma GCC diagnostic pop - +#include "Semaphore.h" +#include "util/Util.h" + +#if PLATFORM_IS_WINDOWS + #include +#endif + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +//----------------------------------------------------------- +Semaphore::Semaphore( int initialCount ) + #if PLATFORM_IS_WINDOWS || PLATFORM_IS_APPLE + : _count( initialCount ) + #endif +{ + ASSERT( initialCount >= 0 ); + + #if PLATFORM_IS_LINUX + int r = sem_init( &_id, 0, initialCount ); + if( r != 0 ) + Panic( "sem_init() failed with error: %d.", errno ); + #elif PLATFORM_IS_WINDOWS + _id = CreateSemaphore( NULL,(LONG)initialCount, std::numeric_limits::max(), NULL ); + if( _id == NULL ) + { + Panic( "CreateSemaphore() failed with error: %d.", (int32)::GetLastError() ); + } + #elif PLATFORM_IS_APPLE + _id = dispatch_semaphore_create( (intptr_t)initialCount ); + PanicIf( !_id, "dispatch_semaphore_create failed." ); + #else + #error Unimplemented + #endif +} + +//----------------------------------------------------------- +Semaphore::~Semaphore() +{ + #if PLATFORM_IS_LINUX + int r = sem_destroy( &_id ); + if( r != 0 ) + Panic( "sem_destroy() failed with error: %d.", errno ); + #elif PLATFORM_IS_WINDOWS + if( !CloseHandle( _id ) ) + Panic( "CloseHandle( semaphore ) failed with error: %d.", (int32)::GetLastError() ); + #elif PLATFORM_IS_APPLE + dispatch_release( _id ); + #else + #error Unimplemented + #endif +} + +//----------------------------------------------------------- +void Semaphore::Wait() +{ + #if PLATFORM_IS_LINUX + const int r = sem_wait( &_id ); + if( r != 0 ) + Panic( "sem_wait() failed." ); + #elif PLATFORM_IS_WINDOWS + const DWORD r = WaitForSingleObject( _id, INFINITE ); + if( r != WAIT_OBJECT_0 ) + Panic( "Semaphore::Wait - WaitForSingleObject() failed with error: %d.", (int32)::GetLastError() ); + #elif PLATFORM_IS_APPLE + intptr_t r = dispatch_semaphore_wait( _id, DISPATCH_TIME_FOREVER ); + PanicIf( r != 0, "dispatch_semaphore_wait() failed." ); + #else + #error Unimplemented + #endif +} + +//----------------------------------------------------------- +bool Semaphore::Wait( long milliseconds ) +{ + ASSERT( milliseconds > 0 ); + + if( milliseconds < 1 ) + { + Wait(); + return true; + } + + #if PLATFORM_IS_LINUX + + long seconds = milliseconds / 1000; + milliseconds -= seconds * 1000; + + struct timespec abstime; + + if( clock_gettime( CLOCK_REALTIME, &abstime ) == -1 ) + { + ASSERT( 0 ); + return false; + } + + int r = sem_timedwait( &_id, &abstime ); + + if( r != 0 && r != ETIMEDOUT ) + Panic( "sem_wait() failed." ); + + return r == 0; + + #elif PLATFORM_IS_WINDOWS + const DWORD r = WaitForSingleObject( _id, (DWORD)milliseconds ); + + if( r != WAIT_OBJECT_0 && r != WAIT_TIMEOUT ) + Panic( "Semaphore::Wait - WaitForSingleObject() failed with error: %d", (int32)GetLastError() ); + + return r == WAIT_OBJECT_0; + #elif PLATFORM_IS_APPLE + const int64_t nanoseconds = (int64_t)milliseconds * 1000000ll; + const dispatch_time_t timeout = dispatch_time( DISPATCH_TIME_NOW, nanoseconds ); + + const intptr_t r = dispatch_semaphore_wait( _id, timeout ); + + return r == 0; // Non-zero = timed-out + #else + #error Unimplemented + #endif +} + +//----------------------------------------------------------- +int Semaphore::GetCount() +{ + #if PLATFORM_IS_LINUX + + int value = 0; + int r = sem_getvalue( &_id, &value ); + + if( r != 0 ) + Panic( "sem_getvalue() failed." ); + + return value; + #elif PLATFORM_IS_WINDOWS || PLATFORM_IS_APPLE + return _count.load( std::memory_order::memory_order_release ); + #else + #error Unimplemented + #endif +} + +//----------------------------------------------------------- +void Semaphore::Release() +{ + #if PLATFORM_IS_LINUX + int r = sem_post( &_id ); + if( r != 0 ) + Panic( "sem_post() failed." ); + #elif PLATFORM_IS_WINDOWS + LONG prevCount; + BOOL r = ::ReleaseSemaphore( _id, 1, &prevCount ); + + if( !r ) + Panic( "ReleaseSemaphore() failed with error: %d.", (int32)::GetLastError() ); + + _count++; + #elif PLATFORM_IS_APPLE + // #TODO: Return value? Apple doesn't say what it does: + // #See: https://developer.apple.com/documentation/dispatch/1452919-dispatch_semaphore_signal + dispatch_semaphore_signal( _id ); + + _count++; + #else + #error Unimplemented + #endif +} + +#pragma GCC diagnostic pop + diff --git a/src/threading/Semaphore.h b/src/threading/Semaphore.h index 8bc6c37e..d7c8afc9 100644 --- a/src/threading/Semaphore.h +++ b/src/threading/Semaphore.h @@ -1,26 +1,26 @@ -#pragma once -#include "Platform.h" -#include - -/// These are lightweight single-process semaphores. -/// (As opposed to system-wide "named" semaphores) -class Semaphore -{ -public: - - Semaphore( int initialCount = 0 ); - ~Semaphore(); - - void Wait(); - bool Wait( long milliseconds ); - void Release(); - - int GetCount(); - -private: - SemaphoreId _id; - -#if PLATFORM_IS_WINDOWS - std::atomic _count; -#endif +#pragma once +#include "Platform.h" +#include + +/// These are lightweight single-process semaphores. +/// (As opposed to system-wide "named" semaphores) +class Semaphore +{ +public: + + Semaphore( int initialCount = 0 ); + ~Semaphore(); + + void Wait(); + bool Wait( long milliseconds ); + void Release(); + + int GetCount(); + +private: + SemaphoreId _id; + +#if PLATFORM_IS_WINDOWS || PLATFORM_IS_APPLE + std::atomic _count; +#endif }; \ No newline at end of file diff --git a/src/threading/Thread.h b/src/threading/Thread.h index 09f7282c..a3f88d55 100644 --- a/src/threading/Thread.h +++ b/src/threading/Thread.h @@ -1,57 +1,76 @@ -#pragma once -#include "Platform.h" -#include - -typedef void (*ThreadRunner)( void* data ); - -class Thread -{ -public: - - Thread( size_t stackSize ); - Thread(); - ~Thread(); - -// static uint64 SetAffinity( uint64 affinity ); - // void SetName( const char* name ); - - void Run( ThreadRunner runner, void* param ); - - // Cause the current thread to sleep - static void Sleep( long milliseconds ); - - bool WaitForExit( long milliseconds = -1 ); - - bool HasExited() const; - -private: - - #if PLATFORM_IS_UNIX - static void* ThreadStarterUnix( Thread* thread ); - #elif PLATFORM_IS_WINDOWS - static DWORD ThreadStarterWin( LPVOID ); - #else - #error Unimplemented - #endif - -private: - ThreadId _threadId = 0; - ThreadRunner _runner = nullptr; - void* _runParam = nullptr; - -#if PLATFORM_IS_UNIX - // Used for launching the thread and - // suspending it until it actually runs. - pthread_mutex_t _launchMutex; - pthread_cond_t _launchCond ; -#endif - - enum class ThreadState : int - { - ReadyToRun = 0, - Running = 1, - Exited = 2 - }; - - std::atomic _state; -}; \ No newline at end of file +#pragma once +#include "Platform.h" + + +typedef void (*ThreadRunner)( void* data ); + +enum class ThreadPriority +{ + Normal = 0, + High +}; + +class Thread +{ +public: + + Thread( size_t stackSize ); + Thread(); + ~Thread(); + +// static uint64 SetAffinity( uint64 affinity ); + // void SetName( const char* name ); + template + void Run( void (*runner)( TParam* param ), TParam* param ); + + void Run( ThreadRunner runner, void* param ); + + // Cause the current thread to sleep + static void Sleep( long milliseconds ); + + bool WaitForExit( long milliseconds = -1 ); + + bool HasExited() const; + + bool SetPriority( const ThreadPriority priority ); + +private: + + #if PLATFORM_IS_UNIX + static void* ThreadStarterUnix( Thread* thread ); + #elif PLATFORM_IS_WINDOWS + static unsigned long ThreadStarterWin( intptr_t ); + #else + #error Unimplemented + #endif + +private: + ThreadId _threadId = 0; + ThreadRunner _runner = nullptr; + void* _runParam = nullptr; + +#if PLATFORM_IS_UNIX + // Used for launching the thread and + // suspending it until it actually runs. + pthread_mutex_t _launchMutex; + pthread_cond_t _launchCond ; +#endif + + enum class ThreadState : int + { + ReadyToRun = 0, + Running = 1, + Exited = 2 + }; + + std::atomic _state; +}; + + +//----------------------------------------------------------- +template +inline void Thread::Run( void ( *runner )( TParam* param ), TParam* param ) +{ + Run( reinterpret_cast( runner ), (void*)param ); +} + diff --git a/src/threading/ThreadPool.cpp b/src/threading/ThreadPool.cpp index 6f35b6ce..fecf9760 100644 --- a/src/threading/ThreadPool.cpp +++ b/src/threading/ThreadPool.cpp @@ -1,220 +1,220 @@ -#include "ThreadPool.h" -#include "Util.h" -#include "util/Log.h" -#include "SysHost.h" - - -//----------------------------------------------------------- -ThreadPool::ThreadPool( uint threadCount, Mode mode, bool disableAffinity ) - : _threadCount( threadCount ) - , _mode ( mode ) - , _disableAffinity( disableAffinity ) - , _jobSignal ( 0 ) - , _poolSignal ( 0 ) -{ - if( threadCount < 1 ) - Fatal( "threadCount must be greater than 0." ); - - _threads = new Thread [threadCount]; - _threadData = new ThreadData[threadCount]; - - auto threadRunner = mode == Mode::Fixed ? FixedThreadRunner : GreedyThreadRunner; - - for( uint i = 0; i < threadCount; i++ ) - { - _threadData[i].index = (int)i; - _threadData[i].cpuId = i; - _threadData[i].pool = this; - - Thread& t = _threads[i]; - - t.Run( threadRunner, &_threadData[i] ); - } -} - -//----------------------------------------------------------- -ThreadPool::~ThreadPool() -{ - // Signal - _exitSignal.store( true, std::memory_order_release ); - - if( _mode == Mode::Fixed ) - { - for( uint i = 0; i < _threadCount; i++ ) - _threadData[i].jobSignal.Release(); - } - else - { - for( uint i = 0; i < _threadCount; i++ ) - _jobSignal.Release(); - } - - // #TODO: Wait for all threads to finish - - // #TODO: Signal thread for exit. - // #TODO: Wait for all threads to exit - - delete[] _threads; - delete[] _threadData; - - _threads = nullptr; - _threadData = nullptr; -} - -//----------------------------------------------------------- -void ThreadPool::RunJob( JobFunc func, void* data, uint count, size_t dataSize ) -{ - ASSERT( func ); - ASSERT( data ); - ASSERT( dataSize ); - - // #TODO: Should lock here to prevent re-entrancy and wait - // until current jobs are finished, but that is not the intended usage. - if( _mode == Mode::Fixed ) - DispatchFixed( func, (byte*)data, count, dataSize ); - else - DispatchGreedy( func, (byte*)data, count, dataSize ); -} - -//----------------------------------------------------------- -void ThreadPool::DispatchFixed( JobFunc func, byte* data, uint count, size_t dataSize ) -{ - _jobFunc = func; - _jobData = (byte*)data; - _jobDataSize = dataSize; - - ASSERT( count <= _threadCount ); - - if( count > _threadCount ) - count = _threadCount; - - for( uint i = 0; i < count; i++ ) - _threadData[i].jobSignal.Release(); - - // Wait until all running jobs finish - uint releaseCount = 0; - while( releaseCount < count ) - { - _poolSignal.Wait(); - releaseCount++; - } -} - -//----------------------------------------------------------- -void ThreadPool::DispatchGreedy( JobFunc func, byte* data, uint count, size_t dataSize ) -{ - // No jobs should currently be running - ASSERT( _jobSignal.GetCount() == 0 ); - ASSERT( count ); - - _jobCount = count; - _jobFunc = func; - _jobData = (byte*)data; - _jobDataSize = dataSize; - _jobIndex.store( 0, std::memory_order_release ); - - ASSERT( _poolSignal.GetCount() == 0 ); - - // Signal release the job semaphore amount of times. - // The job threads will grab jobs from the pool as long as there is one. - for( uint i = 0; i < count; i++ ) - _jobSignal.Release(); - - // Wait until all running jobs finish - uint releaseCount = 0; - while( releaseCount < count ) - { - _poolSignal.Wait(); - releaseCount++; - } - - ASSERT( _jobIndex == count ); - ASSERT( _poolSignal.GetCount() == 0 ); - - // All jobs finished - _jobFunc = nullptr; - _jobData = nullptr; - _jobCount = 0; -} - -//----------------------------------------------------------- -void ThreadPool::FixedThreadRunner( void* tParam ) -{ - ASSERT( tParam ); - ThreadData& d = *(ThreadData*)tParam; - ThreadPool& pool = *d.pool; - - if( !pool._disableAffinity ) - SysHost::SetCurrentThreadAffinityCpuId( d.cpuId ); - - const uint index = (uint)d.index; - - std::atomic& exitSignal = pool._exitSignal; - Semaphore& poolSignal = pool._poolSignal; - Semaphore& jobSignal = d.jobSignal; - - for( ;; ) - { - if( exitSignal.load( std::memory_order::memory_order_acquire ) ) - return; - - // Wait until we are signalled to go - jobSignal.Wait(); - - // We may have been signalled to exit - if( exitSignal.load( std::memory_order_acquire ) ) - return; - - // Run job - pool._jobFunc( pool._jobData + pool._jobDataSize * index ); - - // Finished job - poolSignal.Release(); - } -} - -//----------------------------------------------------------- -void ThreadPool::GreedyThreadRunner( void* tParam ) -{ - ASSERT( tParam ); - - ThreadData& d = *(ThreadData*)tParam; - ThreadPool& pool = *d.pool; - - if( !pool._disableAffinity ) - SysHost::SetCurrentThreadAffinityCpuId( d.cpuId ); - - for( ;; ) - { - if( pool._exitSignal.load( std::memory_order::memory_order_acquire ) ) - return; - - // Wait until we are signalled to go - pool._jobSignal.Wait(); - - // We may have been signalled to exit - if( pool._exitSignal.load( std::memory_order_acquire ) ) - return; - - // Grab jobs until there's no more jobs - uint jobIndex = pool._jobIndex.load( std::memory_order_acquire ); - - while( jobIndex < pool._jobCount ) - { - bool acquired = pool._jobIndex.compare_exchange_weak( jobIndex, jobIndex+1, - std::memory_order_release, - std::memory_order_relaxed ); - - if( acquired ) - { - ASSERT( pool._jobFunc ); - - // We acquired the job, run it - pool._jobFunc( pool._jobData + pool._jobDataSize * jobIndex ); - } - } - - // Finished jobs, or there were no jobs to run, - pool._poolSignal.Release(); - } +#include "ThreadPool.h" +#include "util/Util.h" +#include "util/Log.h" +#include "SysHost.h" + + +//----------------------------------------------------------- +ThreadPool::ThreadPool( uint threadCount, Mode mode, bool disableAffinity ) + : _threadCount( threadCount ) + , _mode ( mode ) + , _disableAffinity( disableAffinity ) + , _jobSignal ( 0 ) + , _poolSignal ( 0 ) +{ + if( threadCount < 1 ) + Fatal( "threadCount must be greater than 0." ); + + _threads = new Thread [threadCount]; + _threadData = new ThreadData[threadCount]; + + auto threadRunner = mode == Mode::Fixed ? FixedThreadRunner : GreedyThreadRunner; + + for( uint i = 0; i < threadCount; i++ ) + { + _threadData[i].index = (int)i; + _threadData[i].cpuId = i; + _threadData[i].pool = this; + + Thread& t = _threads[i]; + + t.Run( threadRunner, &_threadData[i] ); + } +} + +//----------------------------------------------------------- +ThreadPool::~ThreadPool() +{ + // Signal + _exitSignal.store( true, std::memory_order_release ); + + if( _mode == Mode::Fixed ) + { + for( uint i = 0; i < _threadCount; i++ ) + _threadData[i].jobSignal.Release(); + } + else + { + for( uint i = 0; i < _threadCount; i++ ) + _jobSignal.Release(); + } + + // #TODO: Wait for all threads to finish + + // #TODO: Signal thread for exit. + // #TODO: Wait for all threads to exit + + delete[] _threads; + delete[] _threadData; + + _threads = nullptr; + _threadData = nullptr; +} + +//----------------------------------------------------------- +void ThreadPool::RunJob( JobFunc func, void* data, uint count, size_t dataSize ) +{ + ASSERT( func ); + ASSERT( data ); + ASSERT( dataSize ); + + // #TODO: Should lock here to prevent re-entrancy and wait + // until current jobs are finished, but that is not the intended usage. + if( _mode == Mode::Fixed ) + DispatchFixed( func, (byte*)data, count, dataSize ); + else + DispatchGreedy( func, (byte*)data, count, dataSize ); +} + +//----------------------------------------------------------- +void ThreadPool::DispatchFixed( JobFunc func, byte* data, uint count, size_t dataSize ) +{ + _jobFunc = func; + _jobData = (byte*)data; + _jobDataSize = dataSize; + + ASSERT( count <= _threadCount ); + + if( count > _threadCount ) + count = _threadCount; + + for( uint i = 0; i < count; i++ ) + _threadData[i].jobSignal.Release(); + + // Wait until all running jobs finish + uint releaseCount = 0; + while( releaseCount < count ) + { + _poolSignal.Wait(); + releaseCount++; + } +} + +//----------------------------------------------------------- +void ThreadPool::DispatchGreedy( JobFunc func, byte* data, uint count, size_t dataSize ) +{ + // No jobs should currently be running + ASSERT( _jobSignal.GetCount() == 0 ); + ASSERT( count ); + + _jobCount = count; + _jobFunc = func; + _jobData = (byte*)data; + _jobDataSize = dataSize; + _jobIndex.store( 0, std::memory_order_release ); + + ASSERT( _poolSignal.GetCount() == 0 ); + + // Signal release the job semaphore amount of times. + // The job threads will grab jobs from the pool as long as there is one. + for( uint i = 0; i < count; i++ ) + _jobSignal.Release(); + + // Wait until all running jobs finish + uint releaseCount = 0; + while( releaseCount < count ) + { + _poolSignal.Wait(); + releaseCount++; + } + + ASSERT( _jobIndex == count ); + ASSERT( _poolSignal.GetCount() == 0 ); + + // All jobs finished + _jobFunc = nullptr; + _jobData = nullptr; + _jobCount = 0; +} + +//----------------------------------------------------------- +void ThreadPool::FixedThreadRunner( void* tParam ) +{ + ASSERT( tParam ); + ThreadData& d = *(ThreadData*)tParam; + ThreadPool& pool = *d.pool; + + if( !pool._disableAffinity ) + SysHost::SetCurrentThreadAffinityCpuId( d.cpuId ); + + const uint index = (uint)d.index; + + std::atomic& exitSignal = pool._exitSignal; + Semaphore& poolSignal = pool._poolSignal; + Semaphore& jobSignal = d.jobSignal; + + for( ;; ) + { + if( exitSignal.load( std::memory_order::memory_order_acquire ) ) + return; + + // Wait until we are signalled to go + jobSignal.Wait(); + + // We may have been signalled to exit + if( exitSignal.load( std::memory_order_acquire ) ) + return; + + // Run job + pool._jobFunc( pool._jobData + pool._jobDataSize * index ); + + // Finished job + poolSignal.Release(); + } +} + +//----------------------------------------------------------- +void ThreadPool::GreedyThreadRunner( void* tParam ) +{ + ASSERT( tParam ); + + ThreadData& d = *(ThreadData*)tParam; + ThreadPool& pool = *d.pool; + + if( !pool._disableAffinity ) + SysHost::SetCurrentThreadAffinityCpuId( d.cpuId ); + + for( ;; ) + { + if( pool._exitSignal.load( std::memory_order::memory_order_acquire ) ) + return; + + // Wait until we are signalled to go + pool._jobSignal.Wait(); + + // We may have been signalled to exit + if( pool._exitSignal.load( std::memory_order_acquire ) ) + return; + + // Grab jobs until there's no more jobs + uint jobIndex = pool._jobIndex.load( std::memory_order_acquire ); + + while( jobIndex < pool._jobCount ) + { + bool acquired = pool._jobIndex.compare_exchange_weak( jobIndex, jobIndex+1, + std::memory_order_release, + std::memory_order_relaxed ); + + if( acquired ) + { + ASSERT( pool._jobFunc ); + + // We acquired the job, run it + pool._jobFunc( pool._jobData + pool._jobDataSize * jobIndex ); + } + } + + // Finished jobs, or there were no jobs to run, + pool._poolSignal.Release(); + } } \ No newline at end of file diff --git a/src/threading/ThreadPool.h b/src/threading/ThreadPool.h index 58592213..2812fcc7 100644 --- a/src/threading/ThreadPool.h +++ b/src/threading/ThreadPool.h @@ -1,73 +1,73 @@ -#pragma once - -#include "./Semaphore.h" -#include "Thread.h" -#include - -typedef void (*JobFunc)( void* data ); - -/// -/// Used for running parallel jobs. -/// -class ThreadPool -{ -public: - enum class Mode - { - Fixed = 0, // Only can run as many jobs as we have threads. - Greedy = 1 // Can run more jobs that we have threads. - // Threads will continue to process jobs as long - // as there are jobs available. - }; - - ThreadPool( uint threadCount, Mode mode = Mode::Fixed, bool disableAffinity = false ); - ~ThreadPool(); - - void RunJob( JobFunc func, void* data, uint count, size_t dataSize ); - - template - inline void RunJob( void (*TJobFunc)( T* ), T* data, uint count ); - - inline uint ThreadCount() { return _threadCount; } -private: - - void DispatchFixed( JobFunc func, byte* data, uint count, size_t dataSize ); - void DispatchGreedy( JobFunc func, byte* data, uint count, size_t dataSize ); - - static void FixedThreadRunner( void* tParam ); - static void GreedyThreadRunner( void* tParam ); - - struct ThreadData - { - ThreadPool* pool; - int index; - uint cpuId; // CPU Id affinity - Semaphore jobSignal; // Used for fixed mode - }; - -private: - uint _threadCount; // Reserved number of thread running jobs - Mode _mode; - bool _disableAffinity; - Thread* _threads; - ThreadData* _threadData; - Semaphore _jobSignal; // Used to signal threads that there's a new job - Semaphore _poolSignal; // Used to signal the pool that a thread has finished its job - std::atomic _exitSignal = false; // Used to signal threads to exit - - - // Current job group - std::atomic _jobIndex = 0; // Next jobi index - uint _jobCount = 0; // Current number of jobs - JobFunc _jobFunc = nullptr; - byte* _jobData = nullptr; - size_t _jobDataSize = 0; -}; - - -//----------------------------------------------------------- -template -inline void ThreadPool::RunJob( void (*TJobFunc)( T* ), T* data, uint count ) -{ - RunJob( (JobFunc)TJobFunc, data, count, sizeof( T ) ); +#pragma once + +#include "./Semaphore.h" +#include "Thread.h" +#include + +typedef void (*JobFunc)( void* data ); + +/// +/// Used for running parallel jobs. +/// +class ThreadPool +{ +public: + enum class Mode + { + Fixed = 0, // Only can run as many jobs as we have threads. + Greedy = 1 // Can run more jobs that we have threads. + // Threads will continue to process jobs as long + // as there are jobs available. + }; + + ThreadPool( uint threadCount, Mode mode = Mode::Fixed, bool disableAffinity = false ); + ~ThreadPool(); + + void RunJob( JobFunc func, void* data, uint count, size_t dataSize ); + + template + inline void RunJob( void (*TJobFunc)( T* ), T* data, uint count ); + + inline uint ThreadCount() { return _threadCount; } +private: + + void DispatchFixed( JobFunc func, byte* data, uint count, size_t dataSize ); + void DispatchGreedy( JobFunc func, byte* data, uint count, size_t dataSize ); + + static void FixedThreadRunner( void* tParam ); + static void GreedyThreadRunner( void* tParam ); + + struct ThreadData + { + ThreadPool* pool; + int index; + uint cpuId; // CPU Id affinity + Semaphore jobSignal; // Used for fixed mode + }; + +private: + uint _threadCount; // Reserved number of thread running jobs + Mode _mode; + bool _disableAffinity; + Thread* _threads; + ThreadData* _threadData; + Semaphore _jobSignal; // Used to signal threads that there's a new job + Semaphore _poolSignal; // Used to signal the pool that a thread has finished its job + std::atomic _exitSignal = false; // Used to signal threads to exit + + + // Current job group + std::atomic _jobIndex = 0; // Next jobi index + uint _jobCount = 0; // Current number of jobs + JobFunc _jobFunc = nullptr; + byte* _jobData = nullptr; + size_t _jobDataSize = 0; +}; + + +//----------------------------------------------------------- +template +inline void ThreadPool::RunJob( void (*TJobFunc)( T* ), T* data, uint count ) +{ + RunJob( (JobFunc)TJobFunc, data, count, sizeof( T ) ); } \ No newline at end of file diff --git a/src/tools/FSETableGenerator.cpp b/src/tools/FSETableGenerator.cpp new file mode 100644 index 00000000..a473cc9f --- /dev/null +++ b/src/tools/FSETableGenerator.cpp @@ -0,0 +1,195 @@ +#include +#include +#include +#include "ChiaConsts.h" + +// Need to define this for FSE_CTABLE_SIZE/FSE_DTABLE_SIZE +#define FSE_STATIC_LINKING_ONLY +#include "fse/fse.h" + + +/// +/// Offline generate tables required for ANS encoding/decoding +/// +const char USAGE[] = "fsegen [OPTIONS] []\n" +R"( +output_path: Output file path. If nothing is specified, STDOUT is used. + +OPTIONS: + -d, --decompress: Generate decompression table. +)"; + +static std::vector CreateNormalizedCount(double R); +static void DumpFSETables( FILE* file, bool compression ); + + +//----------------------------------------------------------- +int main( int argc, const char* argv[] ) +{ + argc--; + argv++; + + bool compress = true; + + const char* outFilePath = nullptr; + + for( int i = 0; i < argc; i++ ) + { + const char* arg = argv[i]; + if( strcmp( "-d", arg ) == 0 || strcmp( "--decompress", arg ) == 0 ) + compress = false; + else if( i < argc-1 ) + { + Fatal( "Unknown argument '%s'", arg ); + } + else + outFilePath = arg; + } + + FILE* file = nullptr; + if( outFilePath ) + { + file = fopen( outFilePath, "wb" ); + FatalIf( !file, "Failed to open file for writing at '%s'.", outFilePath ); + } + else + { + file = stdout; + } + + DumpFSETables( file, compress ); + return 0; +} + +//----------------------------------------------------------- +void DumpFSETables( FILE* file, bool compression ) +{ + ASSERT( file ); + const char* prefix = compression ? "C" : "D"; + + fprintf( file, "#pragma once\n" ); + fprintf( file, "#include \"fse/fse.h\"\n\n" ); + + + for( int i = 0; i < 7; i++ ) + { + double R = i < 6 ? kRValues[i] : kC3R; // Last one is for C3 entries + + std::vector nCount = CreateNormalizedCount(R); + unsigned maxSymbolValue = (unsigned)nCount.size() - 1; + unsigned tableLog = 14; + + FatalIf( maxSymbolValue > 255, "maxSymbolValue > 255" ); + + size_t err = 0; + FSE_CTable* ct = nullptr; + + if( compression ) + { + ct = FSE_createCTable( maxSymbolValue, tableLog ); + err = FSE_buildCTable( ct, nCount.data(), maxSymbolValue, tableLog ); + } + else + { + // FSE_CTable and FSE_DTable are just uint typedefs, so we can use FSE_CTable here + ct = FSE_createDTable( tableLog ); + err = FSE_buildDTable( ct, nCount.data(), maxSymbolValue, tableLog ); + } + + FatalIf( FSE_isError( err ), "Failed to build %sTable for table %d: %s", + prefix, i+1, FSE_getErrorName( err ) ); + + const size_t tableSizeBytes = compression ? + FSE_CTABLE_SIZE( tableLog, maxSymbolValue ) : FSE_DTABLE_SIZE( tableLog ); + + const size_t rowSize = 32; + const size_t nRows = tableSizeBytes / rowSize; + const size_t lastRowCount = tableSizeBytes - ( nRows * rowSize ); + + const uint8_t* bytes = (uint8_t*)ct; + + if( i < 6 ) + fprintf( file, "const byte %sTable_%d[%llu] = {\n", prefix, i, tableSizeBytes ); + else + fprintf( file, "const byte %sTable_C3[%llu] = {\n", prefix, tableSizeBytes ); + + for( size_t j = 0; j < nRows; j++ ) + { + fprintf( file, " " ); + const uint8_t* row = bytes + j * rowSize; + for( size_t r = 0; r < rowSize; r++ ) + fprintf( file, "0x%02hhx, ", row[r] ); + + fprintf( file, "\n" ); + } + + if( lastRowCount ) + { + fprintf( file, " " ); + for( size_t j = 0; j < lastRowCount; j++ ) + { + fprintf( file, "0x%02hhx", bytes[rowSize*nRows+j] ); + + if( j+1 < lastRowCount ) + fprintf( file, ", " ); + } + + fputc( '\n', file ); + } + + fprintf( file, "};\n\n" ); + fflush( file ); + } + + fprintf( file, "const FSE_%sTable* const %sTables[6] = {\n", prefix, prefix ); + for( int i = 0; i < 6; i++ ) + { + fprintf( file, " (const FSE_%sTable*)%sTable_%d,\n", prefix, prefix, i ); + } + fprintf( file, "};\n\n" ); + fclose( file ); +} + + +/// +/// Takem from chiapos +/// +std::vector CreateNormalizedCount(double R) +{ + std::vector dpdf; + int N = 0; + double E = 2.718281828459; + double MIN_PRB_THRESHOLD = 1e-50; + int TOTAL_QUANTA = 1 << 14; + double p = 1 - pow((E - 1) / E, 1.0 / R); + + while (p > MIN_PRB_THRESHOLD && N < 255) { + dpdf.push_back(p); + N++; + p = (pow(E, 1.0 / R) - 1) * pow(E - 1, 1.0 / R); + p /= pow(E, ((N + 1) / R)); + } + + std::vector ans(N, 1); + auto cmp = [&dpdf, &ans](int i, int j) { + return dpdf[i] * (log2(ans[i] + 1) - log2(ans[i])) < + dpdf[j] * (log2(ans[j] + 1) - log2(ans[j])); + }; + + std::priority_queue, decltype(cmp)> pq(cmp); + for (int i = 0; i < N; ++i) pq.push(i); + + for (int todo = 0; todo < TOTAL_QUANTA - N; ++todo) { + int i = pq.top(); + pq.pop(); + ans[i]++; + pq.push(i); + } + + for (int i = 0; i < N; ++i) { + if (ans[i] == 1) { + ans[i] = (short)-1; + } + } + return ans; +} \ No newline at end of file diff --git a/src/tools/IOTester.cpp b/src/tools/IOTester.cpp new file mode 100644 index 00000000..80d7b6cf --- /dev/null +++ b/src/tools/IOTester.cpp @@ -0,0 +1,299 @@ +#include "util/CliParser.h" +#include "util/Log.h" +#include "util/Util.h" +#include "io/HybridStream.h" +#include "plotdisk/jobs/IOJob.h" +#include "plotting/GlobalPlotConfig.h" +#include "util/jobs/MemJobs.h" + +void IOTestPrintUsage(); + +static const size_t FILE_NAME_SIZE = 32; + +static void GetTmpFileName( char fileName[FILE_NAME_SIZE] ); +static void InitPages( ThreadPool& pool, const uint32 threadCount, void* mem, const size_t size ); + + +//----------------------------------------------------------- +void IOTestMain( GlobalPlotConfig& gCfg, CliParser& cli ) +{ + size_t writeSize = 4ull GB; + const char* testDir = nullptr; + bool noDirectIO = false; + uint32 passCount = 1; + size_t memReserve = 0; + double passDelaySec = 0.0; + + while( cli.HasArgs() ) + { + if( cli.ReadSize( writeSize, "-s", "--size" ) ) + { + FatalIf( writeSize < 1, "Write size must be > 0." ); + } + else if( cli.ReadSwitch( noDirectIO, "-d", "--no-direct-io" ) ) + continue; + else if( cli.ReadSize( memReserve, "-m", "--memory" ) ) + continue; + else if( cli.ReadU32( passCount, "-p", "--passes" ) ) + { + if( passCount < 1 ) passCount = 1; + continue; + } + else if( cli.ReadF64( passDelaySec, "--delay" ) ) + { + if( passDelaySec < 0.0 ) + passDelaySec = 0; + continue; + } + else if( cli.ArgConsume( "-h", "--help" ) ) + { + IOTestPrintUsage(); + exit( 0 ); + } + else if( cli.IsLastArg() ) + { + testDir = cli.ArgConsume(); + } + else + { + Fatal( "Unexpected argument '%s'.", cli.Arg() ); + } + } + + FatalIf( testDir == nullptr || testDir[0] == 0, + "Expected an output directory as the last argument." ); + + + char* filePath = nullptr; + char* fileNamePtr = nullptr; + { + size_t dirLen = strlen( testDir ); + + filePath = new char[dirLen + FILE_NAME_SIZE + sizeof( ".tmp" ) ]; + if( dirLen > 0 ) + { + memcpy( filePath, testDir, dirLen ); + if( filePath[dirLen-1] != '/' && filePath[dirLen-1] != '\\' ) + filePath[dirLen++] = '/'; + } + + fileNamePtr = filePath + dirLen; + *fileNamePtr = 0; + memcpy( fileNamePtr + FILE_NAME_SIZE, ".tmp", sizeof( ".tmp" ) ); + } + ASSERT( filePath ); + + FileFlags flags = FileFlags::LargeFile; + if( !noDirectIO ) + flags |= FileFlags::NoBuffering; + + const uint32 maxThreads = SysHost::GetLogicalCPUCount(); + const uint32 threadCount = gCfg.threadCount == 0 ? 1 : std::min( gCfg.threadCount, maxThreads ); + + ThreadPool pool( threadCount, ThreadPool::Mode::Fixed, gCfg.disableCpuAffinity ); + + Log::Line( "Size : %.2lf MiB", (double)writeSize BtoMB ); + Log::Line( "Cache : %.2lf MiB", (double)memReserve BtoMB ); + Log::Line( "Threads: %u", threadCount ); + Log::Line( "Passes : %u", passCount ); + Log::Line( "Performing test with file %s", filePath ); + + IStream** files = new IStream*[threadCount]; + + byte* cache = nullptr; + if( memReserve > 0 ) + { + Log::Line( "Reserving memory cache..." ); + + const size_t pageSize = SysHost::GetPageSize(); + const size_t reserveAlloc = RoundUpToNextBoundaryT( memReserve, pageSize ) + pageSize * 2; + + cache = bbvirtalloc( reserveAlloc ); + InitPages( pool, threadCount, cache, reserveAlloc ); + + // Add some guard pages + SysHost::VirtualProtect( cache, pageSize, VProtect::NoAccess ); + SysHost::VirtualProtect( cache + reserveAlloc - pageSize, pageSize, VProtect::NoAccess ); + cache += pageSize; + } + + // Open main file and view to the files + { + // Generate a random file name + char fileName[FILE_NAME_SIZE]; + GetTmpFileName( fileName ); + memcpy( fileNamePtr, fileName, FILE_NAME_SIZE ); + + if( memReserve > 0 ) + { + auto* memFile = new HybridStream(); + FatalIf( !memFile->Open( cache, memReserve, filePath, FileMode::Create, FileAccess::ReadWrite, flags ), + "Failed to open temporary test file at path '%s'.", testDir ); + + files[0] = memFile; + } + else + { + auto* diskFile = new FileStream(); + FatalIf( !diskFile->Open( filePath, FileMode::Create, FileAccess::ReadWrite, flags ), + "Failed to open temporary test file at path '%s'.", testDir ); + + files[0] = diskFile; + } + + // Open other views into the same file, if we have multiple-threads + for( uint32 i = 1; i < threadCount; i++ ) + { + if( memReserve > 0 ) + { + auto* memFile = new HybridStream(); + FatalIf( !memFile->Open( cache, memReserve, filePath, FileMode::Open, FileAccess::ReadWrite, flags ), + "Failed to open temporary test file at path '%s'.", testDir ); + + files[i] = memFile; + } + else + { + auto* diskFile = new FileStream(); + FatalIf( !diskFile->Open( filePath, FileMode::Open, FileAccess::ReadWrite, flags ), + "Failed to open temporary test file at path '%s' with error: %d.", testDir, diskFile->GetError() ); + + files[i] = diskFile; + } + } + } + + // Begin test + const size_t fsBlockSize = files[0]->BlockSize(); + FatalIf( fsBlockSize < 1, "Invalid file system block size of 0." ); + + const size_t totalWriteSize = RoundUpToNextBoundaryT( writeSize, fsBlockSize ); + const double sizeMB = (double)totalWriteSize BtoMB; + + // Allocate data + Log::Line( "Allocating buffer..." ); + byte* buffer = bbvirtalloc( totalWriteSize ); + ASSERT( (uintptr_t)buffer / (uintptr_t)fsBlockSize * (uintptr_t)fsBlockSize == (uintptr_t)buffer ); + + byte** blocks = new byte*[threadCount]; + for( uint32 i = 0; i < threadCount; i++ ) + blocks[i] = bbvirtalloc( fsBlockSize ); + + + InitPages( pool, threadCount, buffer, totalWriteSize ); + + for( uint32 pass = 0; pass < passCount; pass++ ) + { + if( passCount > 1 ) + { + Log::Line( "[Pass %u/%u]", pass+1, passCount ); + } + + // Write + Log::Line( "" ); + Log::Line( "Writing..." ); + int err = 0; + auto timer = TimerBegin(); + FatalIf( !IOJob::MTWrite( pool, threadCount, files, buffer, totalWriteSize, (void**)blocks, fsBlockSize, err ), + "Failed to write with error %d (0x%x).", err, err ); + auto elapsed = TimerEnd( timer ); + + Log::Line( "Wrote %.2lf MiB in %.2lf seconds @ %.2lf MiB/s (%.2lf GiB/s) or %2.lf MB/s (%.2lf GB/s).", + sizeMB, elapsed, totalWriteSize / elapsed BtoMB, totalWriteSize / elapsed BtoGB, + totalWriteSize / elapsed / 1000000.0, totalWriteSize / elapsed / 1000000000.0 ); + + // Read + Log::Line( "" ); + Log::Line( "Reading..." ); + + for( uint32 i = 0; i < threadCount; i++ ) + { + IStream* file = files[i]; + if( !file->Seek( 0, SeekOrigin::Begin ) ) + { + err = file->GetError(); + Fatal( "Seek failed on test file with error%d (0x%x).", err, err ); + } + } + + err = 0; + timer = TimerBegin(); + FatalIf( !IOJob::MTRead( pool, threadCount, files, buffer, totalWriteSize, (void**)blocks, fsBlockSize, err ), + "Failed to read with error %d (0x%x)", err, err ); + elapsed = TimerEnd( timer ); + + Log::Line( "Read %.2lf MiB in %.2lf seconds @ %.2lf MiB/s (%.2lf GiB/s) or %2.lf MB/s (%.2lf GB/s).", + sizeMB, elapsed, totalWriteSize / elapsed BtoMB, totalWriteSize / elapsed BtoGB, + totalWriteSize / elapsed / 1000000.0, totalWriteSize / elapsed / 1000000000.0 ); + + if( pass+1 < passCount ) + { + for( uint32 i = 0; i < threadCount; i++ ) + { + IStream* file = files[i]; + if( !file->Seek( 0, SeekOrigin::Begin ) ) + { + err = file->GetError(); + Fatal( "Seek failed on test file with error%d (0x%x).", err, err ); + } + } + + if( passDelaySec > 0 ) + Thread::Sleep( (long)( passDelaySec * 1000.0 ) ); + } + } + + // Cleanup files + for( uint32 i = 0; i < threadCount; i++ ) + delete files[i]; + + remove( filePath ); +} + +//----------------------------------------------------------- +void GetTmpFileName( char fileName[FILE_NAME_SIZE] ) +{ + ASSERT( fileName ); + + byte random[FILE_NAME_SIZE/2]; + SysHost::Random( random, sizeof( random ) ); + + size_t numEncoded = 0; + BytesToHexStr( random, sizeof( random ), fileName, FILE_NAME_SIZE, numEncoded ); + ASSERT( numEncoded == sizeof( random ) ); +} + +//----------------------------------------------------------- +void InitPages( ThreadPool& pool, const uint32 threadCount, void* mem, const size_t size ) +{ + FaultMemoryPages::RunJob( pool, threadCount, mem, size ); +} + + +//----------------------------------------------------------- +static const char* USAGE = R"(iotest [OPTIONS] + +Performs read/write test on the specified disk path. + +[OPTIONS] + -s, --size : Size to write. Default is 4GB. + Ex: 512MB 1GB 16GB + + -d, --no-direct-io : Disable direct IO, which enables OS IO buffering. + + -m, --memory : Reserve memory size to use as IO cache for the file. + + -p, --passes : The number of passes to perform. By default it is 1. + + --delay : Time (in seconds) to wait between passes. + + -h, --help : Print this help message and exit. +)"; + +//----------------------------------------------------------- +void IOTestPrintUsage() +{ + Log::Line( USAGE ); +} + + diff --git a/src/tools/MemTester.cpp b/src/tools/MemTester.cpp new file mode 100644 index 00000000..34d1c1e1 --- /dev/null +++ b/src/tools/MemTester.cpp @@ -0,0 +1,99 @@ +#include "threading/ThreadPool.h" +#include "threading/MTJob.h" +#include "plotting/GlobalPlotConfig.h" +#include "util/Util.h" +#include "util/CliParser.h" +#include "util/Log.h" +#include "util/jobs/MemJobs.h" + +void MemTestPrintUsage(); + +//----------------------------------------------------------- +void MemTestMain( GlobalPlotConfig& gCfg, CliParser& cli ) +{ + size_t memSize = 16ull MB; + uint32 passCount = 1; + + while( cli.HasArgs() ) + { + if( cli.ReadSize( memSize, "-s", "--size" ) ) + { + FatalIf( memSize < 1, "Memory size must be > 0." ); + } + else if( cli.ReadU32( passCount, "-p", "--passes" ) ) + { + if( passCount < 1 ) passCount = 1; + continue; + } + else if( cli.ArgConsume( "-h", "--help" ) ) + { + MemTestPrintUsage(); + exit( 0 ); + } + else + { + Fatal( "Unexpected argument '%s'.", cli.Arg() ); + } + } + + const uint32 maxThreads = SysHost::GetLogicalCPUCount(); + const uint32 threadCount = gCfg.threadCount == 0 ? 1 : std::min( gCfg.threadCount, maxThreads ); + + ThreadPool pool( threadCount, ThreadPool::Mode::Fixed, gCfg.disableCpuAffinity ); + + Log::Line( "Size : %.2lf MiB", (double)memSize BtoMB ); + Log::Line( "Threads: %u", threadCount ); + Log::Line( "Passes : %u", passCount ); + + Log::Line( "Allocating buffer..." ); + byte* src = bbvirtalloc( memSize ); + byte* dst = bbvirtalloc( memSize ); + + FaultMemoryPages::RunJob( pool, threadCount, src, memSize ); + FaultMemoryPages::RunJob( pool, threadCount, dst, memSize ); + + const double sizeMB = (double)memSize BtoMB; + + Log::Line( "Starting Test" ); + Log::Line( "" ); + for( uint32 pass = 0; pass < passCount; pass++ ) + { + if( passCount > 1 ) + { + Log::Line( "[Pass %u/%u]", pass+1, passCount ); + } + + auto timer = TimerBegin(); + MemCpyMT::Copy( dst, src, memSize, pool, threadCount ); + auto elapsed = TimerEnd( timer ); + + Log::Line( "Copied %.2lf MiB in %.2lf seconds @ %.2lf MiB/s (%.2lf GiB/s) or %2.lf MB/s (%.2lf GB/s).", + sizeMB, elapsed, memSize / elapsed BtoMB, memSize / elapsed BtoGB, + memSize / elapsed / 1000000.0, memSize / elapsed / 1000000000.0 ); + Log::Line( "" ); + } + + + exit( 0 ); +} + +//----------------------------------------------------------- +static const char* USAGE = R"(memtest [OPTIONS] + +Performs a memory copy operation. +Specify -t in the global options to set the thread count. + +[OPTIONS] + -s, --size : Size of memory to copy. + Ex: 512MB 1GB 4GB + + -p, --passes : The number of passes to perform. By default it is 1. + + -h, --help : Print this help message and exit. +)"; + +//----------------------------------------------------------- +void MemTestPrintUsage() +{ + Log::Line( USAGE ); +} \ No newline at end of file diff --git a/src/tools/PlotComparer.cpp b/src/tools/PlotComparer.cpp new file mode 100644 index 00000000..7d09fc1f --- /dev/null +++ b/src/tools/PlotComparer.cpp @@ -0,0 +1,745 @@ +#include "io/FileStream.h" +#include "ChiaConsts.h" +#include "util/Util.h" +#include "util/Log.h" +#include "util/CliParser.h" +#include "util/BitView.h" +#include "plotting/PlotTools.h" +#include "plotting/GlobalPlotConfig.h" +#include "plotdisk/jobs/IOJob.h" +#include "threading/ThreadPool.h" +#include +#include + +class PlotInfo; + +void TestTable( TableId table, PlotInfo& ref, PlotInfo& tgt ); +void TestC3Table( PlotInfo& ref, PlotInfo& tgt ); +void TestTable( PlotInfo& ref, PlotInfo& tgt, TableId table ); + +void UnpackPark7( const byte* srcBits, uint64* dstEntries ); + +void DumpP7( PlotInfo& plot, const char* path ); + +Span ReadC1Table( PlotInfo& plot ); + +class PlotInfo +{ +public: + PlotInfo() {} + + ~PlotInfo() + { + + } + + void Open( const char* path ) + { + _path = path; + FatalIf( IsOpen(), "Plot is already open." ); + + // FileFlags::NoBuffering | FileFlags::NoBuffering ), // #TODO: allow unbuffered reading with our own buffer... For now just use like this + FatalIf( !_plotFile.Open( path, FileMode::Open, FileAccess::Read, FileFlags::None ), + "Failed to open plot '%s' with error %d.", path, _plotFile.GetError() ); + + const size_t blockSize = _plotFile.BlockSize(); + _blockBuffer = bbvirtalloc( blockSize ); + + /// + /// Read header + /// + + // Magic + { + char magic[sizeof( kPOSMagic )-1] = { 0 }; + Read( sizeof( magic ), magic ); + FatalIf( !MemCmp( magic, kPOSMagic, sizeof( magic ) ), "Invalid plot magic." ); + } + + // Plot Id + { + Read( sizeof( _id ), _id ); + + char str[65] = { 0 }; + size_t numEncoded = 0; + BytesToHexStr( _id, sizeof( _id ), str, sizeof( str ), numEncoded ); + ASSERT( numEncoded == sizeof( _id ) ); + _idString = str; + } + + // K + { + byte k = 0; + Read( 1, &k ); + _k = k; + } + + // Format Descritption + { + const uint formatDescSize = ReadUInt16(); + FatalIf( formatDescSize != sizeof( kFormatDescription ) - 1, "Invalid format description size." ); + + char desc[sizeof( kFormatDescription )-1] = { 0 }; + Read( sizeof( desc ), desc ); + FatalIf( !MemCmp( desc, kFormatDescription, sizeof( desc ) ), "Invalid format description." ); + } + + // Memo + { + uint memoSize = ReadUInt16(); + FatalIf( memoSize > sizeof( _memo ), "Invalid memo." ); + _memoLength = memoSize; + + Read( memoSize, _memo ); + + char str[BB_PLOT_MEMO_MAX_SIZE*2+1] = { 0 }; + size_t numEncoded = 0; + BytesToHexStr( _memo, memoSize, str, sizeof( str ), numEncoded ); + + _memoString = str; + } + + // Table pointers + Read( sizeof( _tablePtrs ), _tablePtrs ); + for( int i = 0; i < 10; i++ ) + _tablePtrs[i] = Swap64( _tablePtrs[i] ); + + // What follows is table data + } + +public: + const bool IsOpen() const { return _plotFile.IsOpen(); } + + const byte* PlotId() const { return _id; } + + const std::string& PlotIdStr() const { return _idString; } + + uint PlotMemoSize() const { return _memoLength; } + + const byte* PlotMemo() const { return _memo; } + + const std::string& PlotMemoStr() const { return _memoString; } + + uint K() const { return _k; } + + FileStream& PlotFile() { return _plotFile; } + + uint64 TableAddress( TableId table ) const + { + ASSERT( table >= TableId::Table1 && table <= TableId::Table7 ); + return _tablePtrs[(int)table]; + } + + uint64 CTableAddress( int c ) + { + ASSERT( c >= 1 && c <= 3 ); + + return _tablePtrs[c+6]; + } + + size_t TableSize( int tableIndex ) + { + ASSERT( tableIndex >= 0 && tableIndex < 10 ); + + const uint64 address = _tablePtrs[tableIndex]; + uint64 endAddress = _plotFile.Size(); + + // Check all table entris where we find and address that is + // greater than ours and less than the current end address + for( int i = 0; i < 10; i++ ) + { + const uint64 a = _tablePtrs[i]; + if( a > address && a < endAddress ) + endAddress = a; + } + + return (size_t)( endAddress - address ); + } + + ssize_t Read( size_t size, void* buffer ) + { + ASSERT( buffer ); + if( size == 0 ) + return 0; + + const size_t blockSize = _plotFile.BlockSize(); + + // Read-in any data already left-over in the block buffer + // if( _blockRemainder ) + // { + // const size_t copySize = std::min( _blockRemainder, size ); + // memcpy( buffer, _blockBuffer + _blockOffset, copySize ); + + // _blockOffset += copySize; + // _blockRemainder -= copySize; + + // buffer = (void*)((byte*)buffer + copySize); + // size -= copySize; + + // if( size == 0 ) + // return copySize; + // } + + const size_t blockCount = size / blockSize; + + size_t blockSizeToRead = blockCount * blockSize; + const size_t remainder = size - blockSizeToRead; + + byte* reader = (byte*)buffer; + ssize_t sizeRead = 0; + + while( blockSizeToRead ) + { + ssize_t read = _plotFile.Read( reader, blockSizeToRead ); + FatalIf( read < 0 , "Plot %s failed to read with error: %d.", _path.c_str(), _plotFile.GetError() ); + + reader += read; + sizeRead += read; + blockSizeToRead -= (size_t)read; + } + + if( remainder ) + { + ssize_t read = _plotFile.Read( reader, remainder ); + + // ssize_t read = _plotFile.Read( _blockBuffer, blockSize ); + ASSERT( read == (ssize_t)remainder || read == (ssize_t)blockSize ); + + // FatalIf( read < (ssize_t)remainder, "Failed to read a full block on plot %s.", _path.c_str() ); + + // memcpy( reader, _blockBuffer, remainder ); + sizeRead += read; + + // // Save any left over data in the block buffer + // _blockOffset = remainder; + // _blockRemainder = blockSize - remainder; + } + + return sizeRead; + } + + uint16 ReadUInt16() + { + uint16 value = 0; + Read( sizeof( value ), &value ); + return Swap16( value ); + } + + void ReadTable( int tableIndex, void* buffer ) + { + const size_t size = TableSize( tableIndex ); + + _blockRemainder = 0; + FatalIf( !_plotFile.Seek( (int64)_tablePtrs[tableIndex], SeekOrigin::Begin ), + "Failed to seek to table %u.", tableIndex+1 ); + + Read( size, buffer ); + } + + void DumpHeader() + { + Log::Line( "Plot %s", _path.c_str() ); + Log::Line( "-----------------------------------------" ); + Log::Line( "Id : %s", _idString.c_str() ); + Log::Line( "Memo : %s", _memoString.c_str() ); + Log::Line( "K : %u", _k ); + + for( int i = 0; i <= (int)TableId::Table7; i++ ) + { + const size_t size = TableSize( i ); + + Log::Line( "Table %u : %16lu ( 0x%016lx ) : %8llu MiB ( %.2lf GiB )", + i+1, _tablePtrs[i], _tablePtrs[i], + size BtoMB, (double)size BtoGB ); + + } + + for( int i = (int)TableId::Table7+1; i < 10; i++ ) + { + const size_t size = TableSize( i ); + + Log::Line( "C%u : %16lu ( 0x%016lx ) : %8llu MiB ( %.2lf GiB )", + i-6, _tablePtrs[i], _tablePtrs[i], + size BtoMB, (double)size BtoGB ); + } + } + +private: + FileStream _plotFile; + byte _id[BB_PLOT_ID_LEN] = { 0 }; + byte _memo[BB_PLOT_MEMO_MAX_SIZE] = { 0 }; + uint _memoLength = 0; + std::string _idString = ""; + std::string _memoString = ""; + uint _k = 0; + std::string _path = ""; + uint64 _tablePtrs[10] = { 0 }; + byte* _blockBuffer = nullptr; + size_t _blockRemainder = 0; + size_t _blockOffset = 0; + + // size_t _readBufferSize = 32 MB; + // byte* _readBuffer = nullptr; + +}; + + + +//----------------------------------------------------------- +const char USAGE[] = R"(plotcmp + +Compares 2 plots for matching tables. + +[ARGUMENTS] + : Path to the plot files to be compared. + -h, --help : Print this help message and exit. +)"; + +//----------------------------------------------------------- +void PlotCompareMainPrintUsage() +{ + Log::Line( "" ); + Log::Flush(); +} + + +/// Compares 2 plot's tables +//----------------------------------------------------------- +struct PlotCompareOptions +{ + const char* plotAPath = ""; + const char* plotBPath = ""; +}; + +//----------------------------------------------------------- +void PlotCompareMain( GlobalPlotConfig& gCfg, CliParser& cli ) +{ + PlotCompareOptions opts; + + while( cli.HasArgs() ) + { + if( cli.ArgConsume( "-h", "--help" ) ) + { + PlotCompareMainPrintUsage(); + exit( 0 ); + } + else + break; + } + + opts.plotAPath = cli.ArgConsume(); + opts.plotBPath = cli.ArgConsume(); + + PlotInfo refPlot; // Reference + PlotInfo tgtPlot; // Target + + { + const char* refPath = opts.plotAPath; + const char* tgtPath = opts.plotBPath; + + refPlot.Open( refPath ); + tgtPlot.Open( tgtPath ); + + refPlot.DumpHeader(); + Log::Line( "" ); + tgtPlot.DumpHeader(); + } + + FatalIf( refPlot.K() != 32, "Plot A is k%u. Only k32 plots are currently supported.", refPlot.K() ); + FatalIf( tgtPlot.K() != 32, "Plot B is k%u. Only k32 plots are currently supported.", tgtPlot.K() ); + + FatalIf( !MemCmp( refPlot.PlotId(), tgtPlot.PlotId(), BB_PLOT_ID_LEN ), "Plot id mismatch." ); + FatalIf( !MemCmp( refPlot.PlotMemo(), tgtPlot.PlotMemo(), std::min( refPlot.PlotMemoSize(), tgtPlot.PlotMemoSize() ) ), "Plot memo mismatch." ); + FatalIf( refPlot.K() != tgtPlot.K(), "K value mismatch." ); + + // Test P7, dump it + // DumpP7( refPlot, "/mnt/p5510a/reference/p7.tmp" ); + + // TestTable( refPlot, tgtPlot, TableId::Table7 ); + // TestTable( refPlot, tgtPlot, TableId::Table3 ); + + TestC3Table( refPlot, tgtPlot ); + + for( TableId table = TableId::Table1; table <= TableId::Table7; table++ ) + TestTable( refPlot, tgtPlot, table ); + + // TestC3Table( refPlot, tgtPlot ); +} + +//----------------------------------------------------------- +Span ReadC1Table( PlotInfo& plot ) +{ + const size_t tableSize = plot.TableSize( 7 ); + const uint32 entryCount = (uint)( tableSize / sizeof( uint32 ) ); + + uint32* c1 = bbvirtalloc( tableSize ); + plot.ReadTable( 7, c1 ); + + for( uint i = 0; i < entryCount; i++ ) + c1[i] = Swap32( c1[i] ); + + return Span( c1, entryCount ); +} + +//----------------------------------------------------------- +Span ReadC2Table( PlotInfo& plot ) +{ + const size_t tableSize = plot.TableSize( 8 ); + const uint32 entryCount = (uint)( tableSize / sizeof( uint32 ) ); + + uint32* c2 = bbvirtalloc( tableSize ); + plot.ReadTable( 8, c2 ); + + for( uint i = 0; i < entryCount; i++ ) + c2[i] = Swap32( c2[i] ); + + return Span( c2, entryCount ); +} + +//----------------------------------------------------------- +void TestC3Table( PlotInfo& ref, PlotInfo& tgt ) +{ + Log::Line( "Reading C tables..." ); + // const size_t refSize = ref.TableSize( 9 ); + // const size_t tgtSize = tgt.TableSize( 9 ); + + // const size_t c3Size = std::min( refSize, tgtSize ); + + // Read C1 so that we know how many parks we got + Span refC1 = ReadC1Table( ref ); + Span tgtC1 = ReadC1Table( tgt ); + + // Compare C1 + const uint64 c1Length = (uint64)std::min( refC1.length, tgtC1.length ); + { + Log::Line( "Validating C1 table... " ); + uint64 failCount = 0; + for( uint i = 0; i < c1Length; i++ ) + { + if( refC1[i] != tgtC1[i] ) + { + if( failCount == 0 ) + Log::Line( "C1 table mismatch @ index %u. Ref: %u Tgt: %u", i, refC1[i], tgtC1[i] ); + + failCount++; + } + } + + if( failCount == 0 ) + Log::Line( "Success!" ); + else + Log::Line( "C1 table mismatch: %llu entries failed.", failCount ); + } + + // Check C2 + Span refC2 = ReadC2Table( ref ); + Span tgtC2 = ReadC2Table( tgt ); + + const uint64 c2Length = (uint64)std::min( refC2.length, tgtC2.length ); + { + Log::Line( "Validating C2 table... " ); + + uint64 failCount = 0; + for( uint i = 0; i < c2Length; i++ ) + { + if( refC2[i] != tgtC2[i] ) + { + if( failCount == 0 ) + Log::Line( "C2 table mismatch @ index %u. Ref: %u Tgt: %u", i, refC2[i], tgtC2[i] ); + + failCount++; + } + } + + if( failCount == 0 ) + Log::Line( "Success!" ); + else + Log::Line( "C2 table mismatch: %llu entries failed.", failCount ); + } + + const uint64 f7Count = c1Length * (uint64)kCheckpoint1Interval; + Log::Line( "F7 Count: ~%llu", f7Count ); + + Log::Line( "Validating C3 table..." ); + { + const size_t refC3Size = ref.TableSize( 9 ); + const size_t tgtC3Size = tgt.TableSize( 9 ); + + byte* refC3 = bbvirtalloc( refC3Size ); + byte* tgtC3 = bbvirtalloc( tgtC3Size ); + + ref.ReadTable( 9, refC3 ); + tgt.ReadTable( 9, tgtC3 ); + + // const size_t c3Size = std::min( refC3Size, tgtC3Size ); + + const int64 parkCount = (int64)(c1Length - 1); + const size_t c3ParkSize = CalculateC3Size(); + + const byte* refC3Reader = refC3; + const byte* tgtC3Reader = tgtC3; + + std::vector failures; + + for( int64 i = 0; i < parkCount; i++ ) + { + if( !MemCmp( refC3Reader, tgtC3Reader, c3ParkSize ) ) + { + Log::Line( " C3 park %lld failed.", i ); + failures.push_back( i ); + } + // FatalIf( !MemCmp( refC3Reader, tgtC3Reader, c3ParkSize ), + // "C3 park mismatch @ park %lld / %lld", i, parkCount ); + + refC3Reader += c3ParkSize; + tgtC3Reader += c3ParkSize; + } + + if( failures.size() < 1 ) + Log::Line( "Success!" ); + else + Log::Line( "%llu / %lld C3 parks failed!", failures.size(), parkCount ); + + SysHost::VirtualFree( refC3 ); + SysHost::VirtualFree( tgtC3 ); + } + + SysHost::VirtualFree( refC2.values ); + SysHost::VirtualFree( tgtC2.values ); + SysHost::VirtualFree( refC1.values ); + SysHost::VirtualFree( tgtC1.values ); +} + +//----------------------------------------------------------- +uint64 CompareP7( PlotInfo& ref, PlotInfo& tgt, const byte* p7RefBytes, const byte* p7TgtBytes, const int64 parkCount ) +{ + // Double-buffer parks at a time so that we can compare entries across parks + uint64 refParks[2][kEntriesPerPark]; + uint64 tgtParks[2][kEntriesPerPark]; + + uint64 refMatch[kEntriesPerPark]; + uint64 tgtMatch[kEntriesPerPark]; + + // Unpack first park + ASSERT( parkCount ); + + const size_t parkSize = CalculatePark7Size( ref.K() ); + + UnpackPark7( p7RefBytes, refParks[0] ); + UnpackPark7( p7TgtBytes, tgtParks[0] ); + p7RefBytes += parkSize; + p7TgtBytes += parkSize; + + uint64 parkFailCount = 0; + + for( int64 p = 0; p < parkCount; p++ ) + { + const bool isLastPark = p + 1 == parkCount; + + // Load the next park, if we can + if( !isLastPark ) + { + UnpackPark7( p7RefBytes, refParks[1] ); + UnpackPark7( p7TgtBytes, tgtParks[1] ); + p7RefBytes += parkSize; + p7TgtBytes += parkSize; + } + + const uint64* ref = refParks[0]; + const uint64* tgt = tgtParks[0]; + + const int64 entriesEnd = isLastPark ? kEntriesPerPark : kEntriesPerPark * 2; + + for( int64 i = 0; i < kEntriesPerPark; i++ ) + { + if( ref[i] == tgt[i] ) + continue; + + // Potential out-of-order entries + // Try sorting and matching entry pairs until we run out of entries + int64 j = i + 1; + + bool matched = false; + for( ; j < entriesEnd; j++ ) + { + const size_t matchCount = (size_t)( j - i ) + 1; + + bbmemcpy_t( refMatch, ref+i, matchCount ); + bbmemcpy_t( tgtMatch, tgt+i, matchCount ); + + std::sort( refMatch, refMatch+matchCount ); + std::sort( tgtMatch, tgtMatch+matchCount ); + + if( memcmp( refMatch, tgtMatch, matchCount * sizeof( uint64 ) ) == 0 ) + { + matched = true; + break; + } + else + continue; + } + + if( !matched ) + { + Log::Line( "T7 park %lld failed. First entry failed at index %lld", p, i ); + parkFailCount++; + } + + i = j; + } + + // Set next park as current park + memcpy( refParks[0], refParks[1], sizeof( uint64 ) * kEntriesPerPark ); + memcpy( tgtParks[0], tgtParks[1], sizeof( uint64 ) * kEntriesPerPark ); + } + + return parkFailCount; +} + +//----------------------------------------------------------- +void TestTable( PlotInfo& ref, PlotInfo& tgt, TableId table ) +{ + Log::Line( "Reading Table %u...", table+1 ); + + const size_t parkSize = table < TableId::Table7 ? CalculateParkSize( table ) : CalculatePark7Size( ref.K() ); + + const size_t sizeRef = ref.TableSize( (int)table ); + const size_t sizeTgt = tgt.TableSize( (int)table ); + + byte* tableParksRef = bbvirtalloc( sizeRef ); + byte* tableParksTgt = bbvirtalloc( sizeTgt ); + + ref.ReadTable( (int)table, tableParksRef ); + tgt.ReadTable( (int)table, tableParksTgt ); + + const size_t tableSize = std::min( sizeRef, sizeTgt ); + const int64 parkCount = (int64)( tableSize / parkSize ); + + const byte* parkRef = tableParksRef; + const byte* parkTgt = tableParksTgt; + + Log::Line( "Validating Table %u...", table+1 ); + + uint64 failureCount = 0; + if( table == TableId::Table7 ) + { + // Because entries can be found in different orders in P7, + // we compare them in a different manner than the other parks. + // (this can happen because these entries are sorted on f7, + // and if there's multiple entries with the same value + // there's no guarantee an implementation will sort it + // into the same index as another ) + failureCount = CompareP7( ref, tgt, tableParksRef, tableParksTgt, parkCount ); + } + else + { + for( int64 i = 0; i < parkCount; i++ ) + { + if( !MemCmp( parkRef, parkTgt, parkSize ) ) + { + bool failed = true; + + if( failed ) + { + Log::Line( " T%u park %lld failed.", table+1, i ); + failureCount++; + } + + // { + // const byte* refBytes = parkRef; + // const byte* tgtBytes = parkTgt; + + // // if( table != TableId::Table7 ) + // // { + // // refBytes += 8; + // // } + + // for( uint64 b = 0; b < parkSize; b++ ) + // { + // if( refBytes[b] != tgtBytes[b] ) + // { + // Log::Line( "Byte mismatch @ byte %llu: 0x%02x (%3d) != 0x%02x (%3d)", b, + // (int)refBytes[b], (int)refBytes[b], (int)tgtBytes[b], (int)tgtBytes[b] ); + // break; + // } + // } + // } + } + + parkRef += parkSize; + parkTgt += parkSize; + } + } + + + if( failureCount < 1 ) + Log::Line( "Success!" ); + else + Log::Line( "%llu / %lld Table %u parks failed.", failureCount, parkCount, table+1 ); + + SysHost::VirtualFree( tableParksRef ); + SysHost::VirtualFree( tableParksTgt ); +} + +// Unpack a single park 7, +// ensure srcBits is algined to uint64 +//----------------------------------------------------------- +void UnpackPark7( const byte* srcBits, uint64* dstEntries ) +{ + ASSERT( ((uintptr_t)srcBits & 7 ) == 0 ); + const uint32 _k = _K; + + const uint32 bitsPerEntry = _k + 1; + CPBitReader reader( srcBits, CalculatePark7Size( _k ) * 8, 0 ); + + for( int32 i = 0; i < kEntriesPerPark; i++ ) + dstEntries[i] = reader.Read64Aligned( bitsPerEntry ); +} + +//----------------------------------------------------------- +void DumpP7( PlotInfo& plot, const char* path ) +{ + FileStream file; + FatalIf( !file.Open( path, FileMode::Create, FileAccess::Write, FileFlags::LargeFile | FileFlags::NoBuffering ), + "Failed to open file at '%s' with error: %d.", path, file.GetError() ); + + const size_t parkSize = CalculatePark7Size( plot.K() ); + + const size_t tableSize = plot.TableSize( (int)TableId::Table7 ); + const int64 parkCount = (int64)( tableSize / parkSize ); + const uint64 numEntries = (uint64)parkCount * kEntriesPerPark; + + byte* p7Bytes = bbvirtalloc( tableSize ); + + Log::Line( "Reading Table7..." ); + plot.ReadTable( (int)TableId::Table7, p7Bytes ); + + Log::Line( "Unpacking Table 7..." ); + uint64* entries = bbvirtalloc( RoundUpToNextBoundaryT( (size_t)numEntries* sizeof( uint64 ), file.BlockSize() ) ); + + const byte* parkReader = p7Bytes; + uint64* entryWriter = entries; + for( int64 i = 0; i < parkCount; i++ ) + { + UnpackPark7( p7Bytes, entryWriter ); + + parkReader += parkSize; + entryWriter += kEntriesPerPark; + } + + Log::Line( "Writing to disk..." ); + const size_t blockSize = file.BlockSize(); + + uint64* block = bbvirtalloc( blockSize ); + + int err; + FatalIf( !IOJob::WriteToFile( file, entries, numEntries * sizeof( uint64 ), block, blockSize, err ), + "Entry write failed with error: %d.", err ); + + Log::Line( "All done." ); + bbvirtfree( p7Bytes ); + bbvirtfree( entries ); + bbvirtfree( block ); +} + + diff --git a/src/tools/PlotReader.cpp b/src/tools/PlotReader.cpp new file mode 100644 index 00000000..38e6f5fd --- /dev/null +++ b/src/tools/PlotReader.cpp @@ -0,0 +1,774 @@ +#include "PlotReader.h" +#include "ChiaConsts.h" +#include "util/BitView.h" +#include "plotting/PlotTools.h" +#include "plotting/CTables.h" +#include "plotting/DTables.h" + +/// +/// Plot Reader +/// + +//----------------------------------------------------------- +PlotReader::PlotReader( IPlotFile& plot ) + : _plot( plot ) +{ + const size_t largestParkSize = RoundUpToNextBoundaryT( CalculateParkSize( TableId::Table1, plot.K() ), sizeof( uint64 ) * 2 ); + const size_t maxDecompressedDeltasSize = RoundUpToNextBoundaryT( (size_t)0x7FFF, sizeof( uint64 ) ); + + _parkBuffer = bbmalloc( largestParkSize ); + _deltasBuffer = bbmalloc ( maxDecompressedDeltasSize ); +} + +//----------------------------------------------------------- +PlotReader::~PlotReader() +{ + free( _parkBuffer ); + free( _deltasBuffer ); +} + +//----------------------------------------------------------- +uint64 PlotReader::GetC3ParkCount() const +{ + // We know how many C3 parks there are by how many + // entries we have in the C1 table - 1 (extra 0 entry added) + // However, to make sure this is the case, we'll have to + // read-in all C1 entries and ensure we hit an empty one, + // to ensure we don't run into dead/alignment-space + const size_t c1TableSize = _plot.TableSize( PlotTable::C1 ); + const size_t f7Size = CDiv( _plot.K(), 8 ); + const uint64 c3ParkCount = std::max( c1TableSize / f7Size, (size_t)1 ) - 1; + + // Or just do this: + // Same thing, but we use it + // because we want to validate the plot for farming, + // and farming goes to C1 tables before it goes to C3 + // const size_t c3ParkSize = CalculateC3Size(); + // const size_t c3TableSize = _plot.TableSize( PlotTable::C3 ); + // const size_t c3ParkCount = c3TableSize / c3ParkSize; + + return c3ParkCount; +} + +//----------------------------------------------------------- +uint64 PlotReader::GetMaxF7EntryCount() const +{ + const size_t c3ParkCount = GetC3ParkCount(); + return c3ParkCount * kCheckpoint1Interval; +} + +//----------------------------------------------------------- +size_t PlotReader::GetTableParkCount( const PlotTable table ) const +{ + switch( table ) + { + case PlotTable::C3: + return GetC3ParkCount(); + + case PlotTable::Table7: + return CDiv( GetMaxF7EntryCount(), kEntriesPerPark ); + + case PlotTable::Table1: + case PlotTable::Table2: + case PlotTable::Table3: + case PlotTable::Table4: + case PlotTable::Table5: + case PlotTable::Table6: + return _plot.TableSize( table ) / CalculateParkSize( (TableId)table ); + + default: + return 0; + } +} + +//----------------------------------------------------------- +int64 PlotReader::ReadC3Park( uint64 parkIndex, uint64* f7Buffer ) +{ + const uint32 k = _plot.K(); + const size_t f7SizeBytes = CDiv( k, 8 ); + const size_t c3ParkSize = CalculateC3Size(); + const uint64 c1Address = _plot.TableAddress( PlotTable::C1 ); + const uint64 c3Address = _plot.TableAddress( PlotTable::C3 ); + const size_t c1TableSize = _plot.TableSize( PlotTable::C1 ); + const size_t c3TableSize = _plot.TableSize( PlotTable::C3 ); + const uint64 c1EntryAddress = c1Address + parkIndex * f7SizeBytes; + const uint64 parkAddress = c3Address + parkIndex * c3ParkSize; + + + // Ensure the C1 address is within the C1 table bounds. + if( c1EntryAddress >= c1Address + c1TableSize - f7SizeBytes ) // - f7SizeBytes because the last C1 entry is an empty/dummy one + return -1; + + // First we need to read the root F7 entry for the park, which is in the C1 table. + if( !_plot.Seek( SeekOrigin::Begin, (int64)c1EntryAddress ) ) + return -1; + + uint64 c1 = 0; + if( _plot.Read( f7SizeBytes, &c1 ) != (ssize_t)f7SizeBytes ) + return -1; + + c1 = Swap64( c1 ) >> ( 64 - k ); + + // Ensure we can read this park. If it's not present, it means + // the C1 entry is the only entry in the park, so just return it. + // Read the park into our buffer + if( parkAddress >= c3Address + c3TableSize ) + { + f7Buffer[0] = c1; + return 1; + } + + if( !_plot.Seek( SeekOrigin::Begin, (int64)parkAddress ) ) + return -1; + + // Read the size of the compressed C3 deltas + uint16 compressedSize = 0; + if( _plot.Read( sizeof( uint16 ), &compressedSize ) != (ssize_t)sizeof( uint16 ) ) + return -1; + + compressedSize = Swap16( compressedSize ); + if( compressedSize > c3ParkSize ) + return -1; + + // memset( _parkBuffer, 0, _parkBufferSize ); + if( _plot.Read( c3ParkSize - sizeof( uint16 ), _parkBuffer ) != c3ParkSize - sizeof( uint16 ) ) + return -1; + + // Now we can read the f7 deltas from the C3 park + const size_t deltaCount = FSE_decompress_usingDTable( + _deltasBuffer, kCheckpoint1Interval, + _parkBuffer, compressedSize, + (const FSE_DTable*)DTable_C3 ); + + if( FSE_isError( deltaCount ) ) + return -1; // #TODO: Set error message locally + + ASSERT( deltaCount ); + for( uint32 i = 0; i < deltaCount; i++ ) + if( _deltasBuffer[i] == 0xFF ) + return -1; + + // Unpack deltas into absolute values + memset( f7Buffer, 0, kCheckpoint1Interval * sizeof( uint64 ) ); + + uint64 f7 = c1; + f7Buffer[0] = f7; + + f7Buffer++; + for( int32 i = 0; i < (int32)deltaCount; i++ ) + f7Buffer[i] = f7Buffer[i-1] + _deltasBuffer[i]; + + return (int64)deltaCount+1; +} + +//----------------------------------------------------------- +bool PlotReader::ReadP7Entries( uint64 parkIndex, uint64* p7Indices ) +{ + const uint32 k = _plot.K(); + const uint32 p7EntrySize = k + 1; + const uint64 p7TableAddress = _plot.TableAddress( PlotTable::Table7 ); + const size_t p7TableMaxSize = _plot.TableSize( PlotTable::Table7 ); + const size_t parkSizeBytes = CalculatePark7Size( k ); + + const uint64 maxParks = p7TableMaxSize / parkSizeBytes; + + // Park must be in the range of the maximum table parks encoded + if( parkIndex >= maxParks ) + return false; + + const uint64 parkAddress = p7TableAddress + parkIndex * parkSizeBytes; + + if( !_plot.Seek( SeekOrigin::Begin, (int64)parkAddress ) ) + return false; + + if( _plot.Read( parkSizeBytes, _parkBuffer ) != (ssize_t)parkSizeBytes ) + return false; + + CPBitReader parkReader( (byte*)_parkBuffer, parkSizeBytes * 8 ); + + for( uint32 i = 0; i < kEntriesPerPark; i++ ) + p7Indices[i] = parkReader.Read64( p7EntrySize ); + + return true; +} + +//----------------------------------------------------------- +bool PlotReader::ReadLPParkComponents( TableId table, uint64 parkIndex, + CPBitReader& outStubs, byte*& outDeltas, + uint128& outBaseLinePoint, uint64& outDeltaCounts ) +{ + outDeltaCounts = 0; + + ASSERT( table < TableId::Table7 ); + if( table >= TableId::Table7 ) + return false; + + const uint32 k = _plot.K(); + const size_t lpSizeBytes = LinePointSizeBytes( k ); + const size_t tableMaxSize = _plot.TableSize( (PlotTable)table ); + const size_t tableAddress = _plot.TableAddress( (PlotTable)table ); + const size_t parkSize = CalculateParkSize( table, k ); + + const uint64 maxParks = tableMaxSize / parkSize; + if( parkIndex >= maxParks ) + return false; + + const size_t parkAddress = tableAddress + parkIndex * parkSize; + + if( !_plot.Seek( SeekOrigin::Begin, (int64)parkAddress ) ) + return false; + + // Read base full line point + uint128 baseLinePoint; + { + uint64 baseLPBytes[CDiv(LinePointSizeBytes( 50 ), sizeof(uint64))] = { 0 }; + + if( _plot.Read( lpSizeBytes, baseLPBytes ) != (ssize_t)lpSizeBytes ) + return false; + + const size_t lpSizeBits = (uint32)LinePointSizeBits( k ); + + CPBitReader lpReader( (byte*)baseLPBytes, RoundUpToNextBoundary( lpSizeBits, 64 ) ); + baseLinePoint = lpReader.Read128Aligned( (uint32)lpSizeBits ); + } + + // Read stubs + const size_t stubsSizeBytes = CDiv( ( kEntriesPerPark - 1 ) * ( k - kStubMinusBits ), 8 ); + uint64* stubsBuffer = _parkBuffer; + + if( _plot.Read( stubsSizeBytes, stubsBuffer ) != (ssize_t)stubsSizeBytes ) + return false; + + // Read deltas + const size_t maxDeltasSizeBytes = CalculateMaxDeltasSize( (TableId)table ); + byte* compressedDeltaBuffer = ((byte*)_parkBuffer) + RoundUpToNextBoundary( stubsSizeBytes, sizeof( uint64 ) ); + byte* deltaBuffer = _deltasBuffer; + + uint16 compressedDeltasSize = 0; + if( _plot.Read( 2, &compressedDeltasSize ) != 2 ) + return false; + + if( !( compressedDeltasSize & 0x8000 ) && compressedDeltasSize > maxDeltasSizeBytes ) + return false; + + size_t deltaCount = 0; + if( compressedDeltasSize & 0x8000 ) + { + // Uncompressed + compressedDeltasSize &= 0x7fff; + if( _plot.Read( compressedDeltasSize, compressedDeltaBuffer ) != compressedDeltasSize ) + return false; + + deltaCount = compressedDeltasSize; + } + else + { + // Compressed + if( _plot.Read( compressedDeltasSize, compressedDeltaBuffer ) != compressedDeltasSize ) + return false; + + // Decompress deltas + deltaCount = FSE_decompress_usingDTable( + deltaBuffer, kEntriesPerPark - 1, + compressedDeltaBuffer, compressedDeltasSize, + DTables[(int)table] ); + + if( FSE_isError( deltaCount ) ) + return false; + } + + outStubs = CPBitReader( (byte*)stubsBuffer, RoundUpToNextBoundary( stubsSizeBytes * 8, 64 ) ); + outBaseLinePoint = baseLinePoint; + outDeltas = deltaBuffer; + outDeltaCounts = deltaCount; + + return true; +} + +//----------------------------------------------------------- +bool PlotReader::ReadLPPark( TableId table, uint64 parkIndex, uint128 linePoints[kEntriesPerPark], uint64& outEntryCount ) +{ + outEntryCount = 0; + + CPBitReader stubReader; + byte* deltaBuffer = nullptr; + uint128 baseLinePoint = 0; + uint64 deltaCount = 0; + + if( !ReadLPParkComponents( table, parkIndex, stubReader, deltaBuffer, baseLinePoint, deltaCount ) ) + return false; + + // Decode line points from stubs and deltas + linePoints[0] = baseLinePoint; + if( deltaCount > 0 ) + { + const uint32 stubBitSize = ( _plot.K() - kStubMinusBits ); + + for( uint64 i = 1; i <= deltaCount; i++ ) + { + // Since these entries are still deltafied, we can fit them in 64-bits + const uint64 stub = stubReader.Read64( stubBitSize ); + const uint64 lp = stub | (((uint64)deltaBuffer[i-1]) << stubBitSize ); + + // Get absolute LP from delta + linePoints[i] = linePoints[i-1] + (uint128)lp; + } + } + + outEntryCount = deltaCount + 1; + return true; +} + +// #TODO: Add 64-bit outLinePoint (templatize) +//----------------------------------------------------------- +bool PlotReader::ReadLP( TableId table, uint64 index, uint128& outLinePoint ) +{ + outLinePoint = 0; + + CPBitReader stubReader; + byte* deltaBuffer = nullptr; + uint128 baseLinePoint = 0; + uint64 deltaCount = 0; + + const uint64 parkIndex = index / kEntriesPerPark; + + if( !ReadLPParkComponents( table, parkIndex, stubReader, deltaBuffer, baseLinePoint, deltaCount ) ) + return false; + + const uint64 lpLocalIdx = index - parkIndex * kEntriesPerPark; + + if( lpLocalIdx > 0 ) + { + if( lpLocalIdx-1 >= deltaCount ) + return false; + + const uint64 maxIter = std::min( lpLocalIdx, deltaCount ); + const uint32 stubBitSize = ( _plot.K() - kStubMinusBits ); + + for( uint64 i = 0; i < maxIter; i++ ) + { + // Since these entries are still deltafied, we can fit them in 64-bits + const uint64 stub = stubReader.Read64( stubBitSize ); + const uint64 lpDelta = stub | (((uint64)deltaBuffer[i]) << stubBitSize ); + + // Get absolute LP from delta + baseLinePoint += (uint128)lpDelta; + } + } + + outLinePoint = baseLinePoint; + return true; +} + +//----------------------------------------------------------- +bool PlotReader::FetchProofFromP7Entry( uint64 p7Entry, uint64 proof[32] ) +{ + // #TODO: Implement me + ASSERT( 0 ); + return false; +} + +/// +/// Plot Files +/// +// #TODO: Move to other source files +//----------------------------------------------------------- +bool IPlotFile::ReadHeader( int& error ) +{ + error = 0; + + // Magic + { + char magic[sizeof( kPOSMagic )-1] = { 0 }; + if( Read( sizeof( magic ), magic ) != sizeof( magic ) ) + return false; + + if( !MemCmp( magic, kPOSMagic, sizeof( magic ) ) ) + { + error = -1; // #TODO: Set actual user error + return false; + } + } + + // Plot Id + { + if( Read( sizeof( _header.id ), _header.id ) != sizeof( _header.id ) ) + return false; + + // char str[65] = { 0 }; + // size_t numEncoded = 0; + // BytesToHexStr( _header.id, sizeof( _header.id ), str, sizeof( str ), numEncoded ); + // ASSERT( numEncoded == sizeof( _header.id ) ); + // _idString = str; + } + + // K + { + byte k = 0; + if( Read( 1, &k ) != 1 ) + return false; + + _header.k = k; + } + + // Format Descritption + { + const uint formatDescSize = ReadUInt16(); + FatalIf( formatDescSize != sizeof( kFormatDescription ) - 1, "Invalid format description size." ); + + char desc[sizeof( kFormatDescription )-1] = { 0 }; + if( Read( sizeof( desc ), desc ) != sizeof( desc ) ) + return false; + + if( !MemCmp( desc, kFormatDescription, sizeof( desc ) ) ) + { + error = -1; // #TODO: Set proper user error + return false; + } + } + + // Memo + { + uint memoSize = ReadUInt16(); + if( memoSize > sizeof( _header.memo ) ) + { + error = -1; // #TODO: Set proper user error + return false; + } + + _header.memoLength = memoSize; + + if( Read( memoSize, _header.memo ) != memoSize ) + { + error = -1; // #TODO: Set proper user error + return false; + } + + // char str[BB_PLOT_MEMO_MAX_SIZE*2+1] = { 0 }; + // size_t numEncoded = 0; + // BytesToHexStr( _memo, memoSize, str, sizeof( str ), numEncoded ); + + // _memoString = str; + } + + // Table pointers + if( Read( sizeof( _header.tablePtrs ), _header.tablePtrs ) != sizeof( _header.tablePtrs ) ) + { + error = -1; // #TODO: Set proper user error + return false; + } + + for( int i = 0; i < 10; i++ ) + _header.tablePtrs[i] = Swap64( _header.tablePtrs[i] ); + + // What follows is table data + return true; +} + + +/// +/// Memory Plot +/// +//----------------------------------------------------------- +MemoryPlot::MemoryPlot() + : _bytes( nullptr, 0 ) +{} + +//----------------------------------------------------------- +MemoryPlot::MemoryPlot( const MemoryPlot& plotFile ) +{ + _bytes = plotFile._bytes; + _err = 0; + _position = 0; + + int headerError = 0; + if( !ReadHeader( headerError ) ) + { + if( headerError ) + _err = headerError; + + if( _err == 0 ) + _err = -1; // #TODO: Set generic plot header read error + + _bytes.values = nullptr; + return; + } + + _plotPath = plotFile._plotPath; +} + +//----------------------------------------------------------- +MemoryPlot::~MemoryPlot() +{ + // #TODO: Don't destroy bytes unless we own them. Use a shared ptr here. + if( _bytes.values ) + SysHost::VirtualFree( _bytes.values ); + + _bytes = Span( nullptr, 0 ); +} + +//----------------------------------------------------------- +bool MemoryPlot::Open( const char* path ) +{ + ASSERT( path ); + if( !path ) + return false; + + if( IsOpen() ) + return false; + + FileStream file; // #TODO: Enable no buffering again, for now when testing disable to take advantage of caching. + if( !file.Open( path, FileMode::Open, FileAccess::Read ) )//, FileFlags::LargeFile | FileFlags::NoBuffering ) ) + { + _err = file.GetError(); + return false; + } + + const ssize_t plotSize = file.Size(); + if( plotSize <= 0 ) + { + if( plotSize < 0 ) + _err = file.GetError(); + else + _err = -1; // #TODO: Assign an actual user error. + return false; + } + + // Add an extra block at the end to be able to do an aligned read there if + // we have any remainder that does not align to a block + const size_t allocSize = RoundUpToNextBoundary( (size_t)plotSize, (int)file.BlockSize() ) + file.BlockSize(); + + byte* bytes = (byte*)SysHost::VirtualAlloc( allocSize ); + if( !bytes ) + { + _err = -1; // #TODO: Assign an actual user error. + return false; + } + + // Read the whole thing to memory + size_t readSize = RoundUpToNextBoundary( plotSize, (int)file.BlockSize() );/// file.BlockSize() * file.BlockSize(); + // size_t readRemainder = plotSize - readSize; + const size_t readEnd = readSize - plotSize; + byte* reader = bytes; + + // Read blocks + while( readSize > readEnd ) + { + const ssize_t read = file.Read( reader, readSize ); + ASSERT( read ); + + if( read < 0 ) + { + _err = file.GetError(); + SysHost::VirtualFree( bytes ); + + return false; + } + + readSize -= (size_t)read; + reader += read; + } + + // if( readRemainder ) + // { + // byte* block = (byte*)RoundUpToNextBoundary( (uintptr_t)reader, (int)file.BlockSize() ); + + // const ssize_t read = file.Read( block, (size_t)file.BlockSize() ); + // ASSERT( read ); + // ASSERT( read >= readRemainder ); + + // if( read < 0 ) + // { + // _err = file.GetError(); + // SysHost::VirtualFree( bytes ); + + // return false; + // } + + // if( reader != block ) + // memmove( reader, block, readRemainder ); + // } + + _bytes = Span( bytes, (size_t)plotSize ); + + // Read the header + int headerError = 0; + if( !ReadHeader( headerError ) ) + { + if( headerError ) + _err = headerError; + + if( _err == 0 ) + _err = -1; // #TODO: Set generic plot header read error + + _bytes.values = nullptr; + SysHost::VirtualFree( bytes ); + return false; + } + + // Lock the plot memory into read-only mode + SysHost::VirtualProtect( bytes, allocSize, VProtect::Read ); + + // Save data, good to go + _plotPath = path; + + return true; +} + +//----------------------------------------------------------- +bool MemoryPlot::IsOpen() const +{ + return _bytes.values != nullptr; +} + +//----------------------------------------------------------- +size_t MemoryPlot::PlotSize() const +{ + return _bytes.length; +} + +//----------------------------------------------------------- +bool MemoryPlot::Seek( SeekOrigin origin, int64 offset ) +{ + ssize_t absPosition = 0; + + switch( origin ) + { + case SeekOrigin::Begin: + absPosition = offset; + break; + + case SeekOrigin::Current: + absPosition = _position + offset; + break; + + case SeekOrigin::End: + absPosition = (ssize_t)_bytes.length + offset; + break; + + default: + _err = -1; // #TODO: Set proper user error. + return false; + } + + if( absPosition < 0 || absPosition > (ssize_t)_bytes.length ) + { + _err = -1; // #TODO: Set proper user error. + return false; + } + + _position = absPosition; + return true; +} + +//----------------------------------------------------------- +ssize_t MemoryPlot::Read( size_t size, void* buffer ) +{ + if( size < 1 || !buffer ) + return 0; + + ASSERT( buffer ); + + const size_t endPos = (size_t)_position + size; + + if( endPos > _bytes.length ) + { + _err = -1; // #TODO: Set proper user error + return false; + } + + memcpy( buffer, _bytes.values + _position, size ); + _position = (ssize_t)endPos; + + return (ssize_t)size; +} + +//----------------------------------------------------------- +int MemoryPlot::GetError() +{ + return _err; +} + + + +/// +/// FilePlot +/// +//----------------------------------------------------------- +FilePlot::FilePlot() +{ + +} + +//----------------------------------------------------------- +FilePlot::FilePlot( const FilePlot& file ) +{ + if( file.IsOpen() ) + Open( file._plotPath.c_str() ); // #TODO: Seek to same location + else + _plotPath = ""; +} + +//----------------------------------------------------------- +FilePlot::~FilePlot() +{ + +} + +//----------------------------------------------------------- +bool FilePlot::Open( const char* path ) +{ + if( !_file.Open( path, FileMode::Open, FileAccess::Read, FileFlags::None ) ) + return false; + + // Read the header + int headerError = 0; + if( !ReadHeader( headerError ) ) + { + // if( headerError ) + // _err = headerError; // #TODO: Set local error + + // if( _err == 0 ) + // _err = -1; // #TODO: Set generic plot header read error + _file.Close(); + return false; + } + + _plotPath = path; + return true; +} + +//----------------------------------------------------------- +bool FilePlot::IsOpen() const +{ + return _file.IsOpen(); +} + +//----------------------------------------------------------- +size_t FilePlot::PlotSize() const +{ + const ssize_t sz = ((FileStream*)&_file)->Size(); + if( sz < 0 ) + return 0; + + return (size_t)sz; +} + +//----------------------------------------------------------- +ssize_t FilePlot::Read( size_t size, void* buffer ) +{ + return _file.Read( buffer, size ); +} + +//----------------------------------------------------------- +bool FilePlot::Seek( SeekOrigin origin, int64 offset ) +{ + return _file.Seek( offset, origin ); +} + +//----------------------------------------------------------- +int FilePlot::GetError() +{ + return _file.GetError(); +} + diff --git a/src/tools/PlotReader.h b/src/tools/PlotReader.h new file mode 100644 index 00000000..e2649c9c --- /dev/null +++ b/src/tools/PlotReader.h @@ -0,0 +1,212 @@ +#pragma once +#include "plotting/PlotTools.h" +#include "io/FileStream.h" +#include "util/Util.h" +#include + +class CPBitReader; + +enum class PlotTable +{ + Table1 = 0, + Table2, + Table3, + Table4, + Table5, + Table6, + Table7, + C1, + C2, + C3, +}; ImplementArithmeticOps( PlotTable ); + +struct PlotHeader +{ + byte id [BB_PLOT_ID_LEN] = { 0 }; + byte memo[BB_PLOT_MEMO_MAX_SIZE] = { 0 }; + uint memoLength = 0; + uint32 k = 0; + uint64 tablePtrs[10] = { 0 }; +}; + +// Base Abstract class for read-only plot files +class IPlotFile +{ +public: + + inline uint K() const { return _header.k; } + + inline const byte* PlotId() const { return _header.id; } + + inline uint PlotMemoSize() const { return _header.memoLength; } + + inline const byte* PlotMemo() const { return _header.memo; } + + inline uint64 TableAddress( PlotTable table ) const + { + ASSERT( table >= PlotTable::Table1 && table <= PlotTable::C3 ); + return _header.tablePtrs[(int)table]; + } + + inline size_t TableSize( PlotTable table ) + { + ASSERT( table >= PlotTable::Table1 && table <= PlotTable::C3 ); + + const uint64 address = _header.tablePtrs[(int)table]; + uint64 endAddress = PlotSize(); + + // Check all table entris where we find and address that is + // greater than ours and less than the current end address + for( int i = 0; i < 10; i++ ) + { + const uint64 a = _header.tablePtrs[i]; + if( a > address && a < endAddress ) + endAddress = a; + } + + return (size_t)( endAddress - address ); + } + + // #NOTE: User must check for read errors! + inline uint16 ReadUInt16() + { + uint16 value = 0; + const ssize_t read = Read( sizeof( value ), &value ); + if( read < 0 ) + return 0; + + ASSERT( read == sizeof( uint16 ) ); + if( read != sizeof( uint16 ) ) + { + // #TODO: Set proper error + return 0; + } + + return Swap16( value ); + } + + // Abstract Interface +public: + virtual bool Open( const char* path ) = 0; + virtual bool IsOpen() const = 0; + + // Plot size in bytes + virtual size_t PlotSize() const = 0; + + // Read data from the plot file + virtual ssize_t Read( size_t size, void* buffer ) = 0; + + // Seek to the specific location on the plot stream, + // whatever the underlying implementation may be. + virtual bool Seek( SeekOrigin origin, int64 offset ) = 0; + + // Get last error ocurred + virtual int GetError() = 0; + +protected: + + // Implementors can call this to load the header + bool ReadHeader( int& error ); + +protected: + PlotHeader _header; +}; + +class MemoryPlot : public IPlotFile +{ +public: + MemoryPlot(); + MemoryPlot( const MemoryPlot& plotFile ); + ~MemoryPlot(); + + bool Open( const char* path ) override; + bool IsOpen() const override; + + size_t PlotSize() const override; + + ssize_t Read( size_t size, void* buffer ) override; + + bool Seek( SeekOrigin origin, int64 offset ) override; + + int GetError() override; + +private: + Span _bytes; // Plot bytes + int _err = 0; + ssize_t _position = 0; + std::string _plotPath = ""; +}; + +class FilePlot : public IPlotFile +{ +public: + FilePlot(); + FilePlot( const FilePlot& file ); + ~FilePlot(); + + bool Open( const char* path ) override; + bool IsOpen() const override; + + size_t PlotSize() const override; + + ssize_t Read( size_t size, void* buffer ) override; + + bool Seek( SeekOrigin origin, int64 offset ) override; + + int GetError() override; + +private: + FileStream _file; + std::string _plotPath = ""; +}; + +class PlotReader +{ +public: + PlotReader( IPlotFile& plot ); + ~PlotReader(); + + uint64 GetC3ParkCount() const; + + // Get the maximum potential F7 count. + // This may be more than the actual number of F7s that we have, + // since the last park is likely not full. + uint64 GetMaxF7EntryCount() const; + + size_t GetTableParkCount( const PlotTable table ) const; + + // Read a whole C3 park into f7Buffer. + // f7Buffer must hold at least as many as the amount of entries + // required per C3Park. (kCheckpoint1Interval). + // The return value should be the entries in the park. + // It should never be 0. + // If the return value is negative, there was an error reading the park. + int64 ReadC3Park( uint64 parkIndex, uint64* f7Buffer ); + + bool ReadP7Entries( uint64 parkIndex, uint64* p7Indices ); + + uint64 GetFullProofForF7Index( uint64 f7Index, byte* fullProof ); + + // void FindF7ParkIndices( uintt64 f7, std::vector indices ); + bool ReadLPPark( TableId table, uint64 parkIndex, uint128 linePoints[kEntriesPerPark], uint64& outEntryCount ); + + bool ReadLP( TableId table, uint64 index, uint128& outLinePoint ); + + bool FetchProofFromP7Entry( uint64 p7Entry, uint64 proof[32] ); + + inline IPlotFile& PlotFile() const { return _plot; } + +private: + + bool ReadLPParkComponents( TableId table, uint64 parkIndex, + CPBitReader& outStubs, byte*& outDeltas, + uint128& outBaseLinePoint, uint64& outDeltaCounts ); + +private: + IPlotFile& _plot; + + // size_t _parkBufferSize; + uint64* _parkBuffer ; // Buffer for loading compressed park data. + byte* _deltasBuffer ; // Buffer for decompressing deltas in parks that have delta. +}; + diff --git a/src/tools/PlotTools.h b/src/tools/PlotTools.h new file mode 100644 index 00000000..e34a8945 --- /dev/null +++ b/src/tools/PlotTools.h @@ -0,0 +1,12 @@ +#pragma once + + +struct ValidatePlotOptions +{ + std::string plotPath = ""; + bool inRAM = false; + bool unpacked = false; + uint32 threadCount = 0; + float startOffset = 0.0f; // Offset percent at which to start +}; + diff --git a/src/tools/PlotTools_Main.old.h b/src/tools/PlotTools_Main.old.h new file mode 100644 index 00000000..b7f838f7 --- /dev/null +++ b/src/tools/PlotTools_Main.old.h @@ -0,0 +1,115 @@ +#include "PlotTools.h" +#include "util/Log.h" +#include "util/Util.h" +#include + + +bool ValidatePlot( const ValidatePlotOptions& options ); + +int ValidatePlotCmd( int argc, const char* argv[] ); + +inline bool match( const char* ref, const char* arg ) +{ + return strcmp( ref, arg ) == 0; +} + +inline bool match( const char* ref0, const char* ref1, const char* arg ) +{ + return strcmp( ref0, arg ) == 0 || + strcmp( ref1, arg ) == 0; +} + + +//----------------------------------------------------------- +int main( int argc, const char* argv[] ) +{ + argc--; + argv++; + + for( int i = 0; i < argc; i++ ) + { + const char* arg = argv[i]; + + if( match( "validate", arg ) ) + return ValidatePlotCmd( argc-1, argv+i+1 ); + } + + Log::Line( "No command specified." ); + return 1; +} + +//----------------------------------------------------------- +int ValidatePlotCmd( int argc, const char* argv[] ) +{ + ValidatePlotOptions opts; + + int i; + const char* arg; + auto value = [&](){ + + FatalIf( ++i >= argc, "Expected a value for parameter '%s'", arg ); + return argv[i]; + }; + + auto ivalue = [&]() { + + const char* val = value(); + int64 v = 0; + + int r = sscanf( val, "%lld", &v ); + FatalIf( r != 1, "Invalid int64 value for argument '%s'.", arg ); + + return v; + }; + + auto uvalue = [&]() { + + const char* val = value(); + uint64 v = 0; + + int r = sscanf( val, "%llu", &v ); + FatalIf( r != 1, "Invalid uint64 value for argument '%s'.", arg ); + + return v; + }; + + auto fvalue = [&]() { + + const char* val = value(); + float v = 0.f; + + int r = sscanf( val, "%f", &v ); + FatalIf( r != 1, "Invalid float32 value for argument '%s'.", arg ); + + return v; + }; + + for( i = 0; i < argc; i++ ) + { + arg = argv[i]; + + if( match( "-m", "--in-ram", arg ) ) + opts.inRAM = true; + else if( match( "-t", "--threads", arg ) ) + opts.threadCount = uvalue(); + else if( match( "-o", "--offset", arg ) ) + opts.startOffset = std::max( std::min( fvalue() / 100.f, 100.f ), 0.f ); + else if( i == argc - 1 ) + opts.plotPath = arg; + else + { + Log::Error( "Unknown argument '%s'", arg ); + return 1; + } + } + + if( opts.threadCount == 0 ) + opts.threadCount = SysHost::GetLogicalCPUCount(); + else + opts.threadCount = std::min( opts.threadCount, SysHost::GetLogicalCPUCount() ); + + // #TODO: Allow many plots to be validated + return ValidatePlot( opts ) ? 0 : 1; +} + + diff --git a/src/tools/PlotValidator.cpp b/src/tools/PlotValidator.cpp new file mode 100644 index 00000000..c6c65806 --- /dev/null +++ b/src/tools/PlotValidator.cpp @@ -0,0 +1,1092 @@ +#include "plotting/CTables.h" +#include "ChiaConsts.h" +#include "util/Log.h" +#include "util/BitView.h" +#include "io/FileStream.h" +#include "PlotTools.h" +#include "PlotReader.h" +#include "plotting/PlotTools.h" +#include "plotmem/LPGen.h" +#include "pos/chacha8.h" +#include "b3/blake3.h" +#include "threading/MTJob.h" +#include "util/CliParser.h" +#include "plotting/GlobalPlotConfig.h" +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + +#define PROOF_X_COUNT 64 +#define MAX_K_SIZE 48 +#define MAX_META_MULTIPLIER 4 +#define MAX_Y_BIT_SIZE ( MAX_K_SIZE + kExtraBits ) +#define MAX_META_BIT_SIZE ( MAX_K_SIZE * MAX_META_MULTIPLIER ) +#define MAX_FX_BIT_SIZE ( MAX_Y_BIT_SIZE + MAX_META_BIT_SIZE + MAX_META_BIT_SIZE ) + +#define COLOR_NONE "\033[0m" +#define COLOR_RED "\033[31m" +#define COLOR_GREEN "\033[32m" +#define COLOR_RED_BOLD "\033[1m\033[31m" +#define COLOR_GREEN_BOLD "\033[1m\033[32m" + +typedef Bits YBits; +typedef Bits MetaBits; +typedef Bits FxBits; + +// #TODO: Add C1 & C2 table validation + +//----------------------------------------------------------- +const char USAGE[] = R"(validate [OPTIONS] + +Validates all of a plot's values to ensure they all contain valid proofs. + +[NOTES] +You can specify the thread count in the bladebit global option '-t'. + +[ARGUMENTS] + : Path to the plot file to be validated. + +[OPTIOINS] + -m, --in-ram : Loads the whole plot file into memory before validating. + + -o, --offset : Percentage offset at which to start validating. + Ex (start at 50%): bladebit validate -o 50 /path/to/my/plot + + -u, --unpack : Decompress the plot into memory before validating. + This decreases validation time substantially but + it requires around 128GiB of RAM for k=32. + This is only supported for plots with k=32 and below. + + -h, --help : Print this help message and exit. +)"; + +void PlotValidatorPrintUsage() +{ + Log::Line( USAGE ); +} + + + +struct UnpackedK32Plot +{ + // Table 1 == X's in line point form + // Table 6 is sorted on p7 + IPlotFile* plot = nullptr; + Span tables[6]; + Span f7; + + //----------------------------------------------------------- + inline const Span Table( const TableId table ) const + { + if( table >= TableId::Table7 ) + { + ASSERT( 0 ); + return Span(); + } + + return tables[(int)table]; + } + + static UnpackedK32Plot Load( IPlotFile** plotFile, ThreadPool& pool, uint32 threadCount ); + bool FetchProof( const uint64 index, uint64 fullProofXs[PROOF_X_COUNT] ); +}; + + +static void GetProofF1( uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 fullProofXs[PROOF_X_COUNT], uint64 fx[PROOF_X_COUNT] ); + +template +static bool FetchProof( PlotReader& plot, uint64 t6LPIndex, uint64 fullProofXs[PROOF_X_COUNT] ); + +static bool ValidateFullProof( const uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 fullProofXs[PROOF_X_COUNT], uint64& outF7 ); +static void ReorderProof( PlotReader& plot, uint64 fullProofXs[PROOF_X_COUNT] ); +static void GetProofF1( uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 fullProofXs[PROOF_X_COUNT], uint64 fx[PROOF_X_COUNT] ); + +static uint64 BytesToUInt64( const byte bytes[8] ); +static uint64 SliceUInt64FromBits( const byte* bytes, uint32 bitOffset, uint32 bitCount ); + +static bool FxMatch( uint64 yL, uint64 yR ); + +static void FxGen( const TableId table, const uint32 k, + const uint64 y, const MetaBits& metaL, const MetaBits& metaR, + uint64& outY, MetaBits& outMeta ); + +static bool ValidatePlot( const ValidatePlotOptions& options ); + +static uint64 ValidateInMemory( UnpackedK32Plot& plot, ThreadPool& pool ); + +// Thread-safe log +static std::mutex _logLock; +static void TVLog( const uint32 id, const char* msg, va_list args ); +// static void TLog( const uint32 id, const char* msg, ... ); + +struct ValidateJob : MTJob +{ + IPlotFile* plotFile; + UnpackedK32Plot* unpackedPlot; // If set, this will be used instead + uint64 failCount; + float startOffset; + + void Run() override; + void Log( const char* msg, ... ); +}; + + +//----------------------------------------------------------- +void PlotValidatorMain( GlobalPlotConfig& gCfg, CliParser& cli ) +{ + ValidatePlotOptions opts; + + while( cli.HasArgs() ) + { + if( cli.ReadSwitch( opts.inRAM, "-m", "--in-ram" ) ) + continue; + else if( cli.ReadSwitch( opts.unpacked, "-u", "--unpack" ) ) + continue; + else if( cli.ReadF32( opts.startOffset, "-o", "--offset" ) ) + continue; + else if( cli.ArgConsume( "-h", "--help" ) ) + { + PlotValidatorPrintUsage(); + exit( 0 ); + } + else if( cli.IsLastArg() ) + { + opts.plotPath = cli.ArgConsume(); + } + else + { + Fatal( "Unexpected argument '%s'.", cli.Arg() ); + } + } + + const uint32 maxThreads = SysHost::GetLogicalCPUCount(); + + opts.threadCount = gCfg.threadCount == 0 ? maxThreads : std::min( maxThreads, gCfg.threadCount ); + opts.startOffset = std::max( std::min( opts.startOffset / 100.f, 100.f ), 0.f ); + + ValidatePlot( opts ); + + exit( 0 ); +} + +//----------------------------------------------------------- +bool ValidatePlot( const ValidatePlotOptions& options ) +{ + LoadLTargets(); + + const uint32 threadCount = options.threadCount; + + IPlotFile* plotFile = nullptr; + IPlotFile** plotFiles = new IPlotFile*[threadCount]; + + if( options.inRAM && !options.unpacked ) + { + auto* memPlot = new MemoryPlot(); + plotFile = memPlot; + + Log::Line( "Reading plot file into memory..." ); + if( memPlot->Open( options.plotPath.c_str() ) ) + { + for( uint32 i = 0; i < threadCount; i++ ) + plotFiles[i] = new MemoryPlot( *memPlot ); + } + } + else + { + auto* filePlot = new FilePlot(); + plotFile = filePlot; + + if( filePlot->Open( options.plotPath.c_str() ) ) + { + for( uint32 i = 0; i < threadCount; i++ ) + plotFiles[i] = new FilePlot( *filePlot ); + } + } + + FatalIf( !plotFile->IsOpen(), "Failed to open plot at path '%s'.", options.plotPath.c_str() ); + FatalIf( options.unpacked && plotFile->K() != 32, "Unpacked plots are only supported for k=32 plots." ); + + Log::Line( "Validating plot %s", options.plotPath.c_str() ); + Log::Line( "K : %u", plotFile->K() ); + Log::Line( "Unpacked: %s", options.unpacked? "true" : "false" );; + + const uint64 plotC3ParkCount = plotFile->TableSize( PlotTable::C1 ) / sizeof( uint32 ) - 1; + Log::Line( "C3 Parks: %llu", plotC3ParkCount ); + Log::Line( "" ); + + + // Duplicate the plot file, + ThreadPool pool( threadCount ); + + UnpackedK32Plot unpackedPlot; + if( options.unpacked ) + { + unpackedPlot = UnpackedK32Plot::Load( plotFiles, pool, threadCount ); + unpackedPlot.plot = plotFile; + + const auto timer = TimerBegin(); + const uint64 failedCount = ValidateInMemory( unpackedPlot, pool ); + const double elapsed = TimerEnd( timer ); + + const uint64 min = (uint64)(elapsed / 60); + const uint64 sec = (uint64)( elapsed - (double)(min * 60) ); + + Log::Line( "" ); + Log::Line( "Finished validating plot in %.lf seconds ( %llu:%llu min ).", + elapsed, min, sec ); + + Log::Line( "[ %s%s%s ] Valid Proofs: %llu / %llu", + failedCount == 0 ? COLOR_GREEN_BOLD : COLOR_RED_BOLD, + failedCount ? "FAILED" : "SUCCESS", COLOR_NONE, + unpackedPlot.f7.Length() - failedCount, unpackedPlot.f7.Length() ); + + exit( failedCount == 0 ? 0 : 1 ); + } + + MTJobRunner jobs( pool ); + + for( uint32 i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job.plotFile = plotFiles[i]; + job.unpackedPlot = options.unpacked ? &unpackedPlot : nullptr; + job.startOffset = options.startOffset; + job.failCount = 0; + } + + jobs.Run( threadCount ); + + uint64 proofFailCount = 0; + for( uint32 i = 0; i < threadCount; i++ ) + proofFailCount += jobs[i].failCount; + + if( proofFailCount ) + Log::Line( "Plot has %llu invalid proofs." ); + else + Log::Line( "Perfect plot! All proofs are valid." ); + + return proofFailCount == 0; +} + +//----------------------------------------------------------- +uint64 ValidateInMemory( UnpackedK32Plot& plot, ThreadPool& pool ) +{ + Log::Line( "Validating plot in-memory" ); + Log::Line( "F7 entry count: %llu", plot.f7.Length() ); + Log::Line( "" ); + + std::atomic totalFailures = 0; + + AnonMTJob::Run( pool, [&]( AnonMTJob* self ) { + + auto Log = [=]( const char* msg, ... ) { + va_list args; + va_start( args, msg ); + TVLog( self->_jobId, msg, args ); + va_end( args ); + }; + + uint64 count, offset, end; + GetThreadOffsets( self, (uint64)plot.f7.Length(), count, offset, end ); + + Log( "Validating proofs %10llu...%-10llu", offset, end ); + self->SyncThreads(); + + const uint64 reportInterval = kCheckpoint1Interval * 20; // Report every 20 parks + + uint64 fullProofXs[PROOF_X_COUNT]; + uint64 failedCount = 0; + + for( uint64 i = offset; i < end; i++ ) + { + if( plot.FetchProof( i, fullProofXs ) ) + { + uint64 outF7 = 0; + if( ValidateFullProof( plot.plot->K(), plot.plot->PlotId(), fullProofXs, outF7 ) ) + { + const uint32 expectedF7 = plot.f7[i]; + + if( expectedF7 != outF7 ) + failedCount++; + } + else + failedCount++; + } + else + failedCount++; + + const uint64 proofsChecked = i - offset; + if( ( proofsChecked > 0 && proofsChecked % reportInterval == 0 ) || i + 1 == end ) + { + Log( "Proofs validated: %10llu / %-10llu ( %.2lf %% ) [ %sFailed: %llu%s ]", + proofsChecked, count, + (double)proofsChecked / count * 100.0, + failedCount > 0 ? COLOR_RED_BOLD : COLOR_GREEN_BOLD, + failedCount, + COLOR_NONE ); + } + } + + uint64 f = totalFailures.load( std::memory_order_acquire ); + + while( !totalFailures.compare_exchange_weak( + f, f + failedCount, + std::memory_order_release, + std::memory_order_relaxed ) ); + }); + + return totalFailures; +} + + +//----------------------------------------------------------- +void ValidateJob::Log( const char* msg, ... ) +{ + va_list args; + va_start( args, msg ); + TVLog( JobId(), msg, args ); + va_end( args ); +} + +//----------------------------------------------------------- +void ValidateJob::Run() +{ + PlotReader plot( *plotFile ); + + const uint32 k = plotFile->K(); + + uint64 c3ParkCount = 0; + uint64 c3ParkEnd = 0; + + const uint32 threadCount = this->JobCount(); + const uint64 plotC3ParkCount = plotFile->TableSize( PlotTable::C1 ) / sizeof( uint32 ) - 1; + + c3ParkCount = plotC3ParkCount / threadCount; + + uint64 startC3Park = this->JobId() * c3ParkCount; + + { + uint64 trailingParks = plotC3ParkCount - c3ParkCount * threadCount; + + if( this->JobId() < trailingParks ) + c3ParkCount ++; + + startC3Park += std::min( trailingParks, (uint64)this->JobId() ); + } + + c3ParkEnd = startC3Park + c3ParkCount; + + if( startOffset > 0.0f ) + { + startC3Park += std::min( c3ParkCount, (uint64)( c3ParkCount * startOffset ) ); + c3ParkCount = c3ParkEnd - startC3Park; + } + + Log( "Park range: %10llu..%-10llu Park count: %llu", startC3Park, c3ParkEnd, c3ParkCount ); + + /// + /// Start validating C3 parks + /// + uint64* f7Entries = bbcalloc( kCheckpoint1Interval ); + memset( f7Entries, 0, kCheckpoint1Interval * sizeof( uint64 ) ); + + uint64* p7Entries = bbcalloc( kEntriesPerPark ); + memset( p7Entries, 0, sizeof( kEntriesPerPark ) * sizeof( uint64 ) ); + + + uint64 curPark7 = 0; + if( JobId() == 0 ) + FatalIf( !plot.ReadP7Entries( 0, p7Entries ), "Failed to read P7 0." ); + + uint64 proofFailCount = 0; + uint64 fullProofXs[PROOF_X_COUNT]; + + for( uint64 c3ParkIdx = startC3Park; c3ParkIdx < c3ParkEnd; c3ParkIdx++ ) + { + const auto timer = TimerBegin(); + + const int64 f7EntryCount = plot.ReadC3Park( c3ParkIdx, f7Entries ); + + FatalIf( f7EntryCount < 0, "Could not read C3 park %llu.", c3ParkIdx ); + ASSERT( f7EntryCount <= kCheckpoint1Interval ); + + const uint64 f7IdxBase = c3ParkIdx * kCheckpoint1Interval; + + for( uint32 e = 0; e < (uint32)f7EntryCount; e++ ) + { + const uint64 f7Idx = f7IdxBase + e; + const uint64 p7ParkIndex = f7Idx / kEntriesPerPark; + const uint64 f7 = f7Entries[e]; + + if( p7ParkIndex != curPark7 ) + { + // ASSERT( p7ParkIndex == curPark7+1 ); + curPark7 = p7ParkIndex; + + FatalIf( !plot.ReadP7Entries( p7ParkIndex, p7Entries ), "Failed to read P7 %llu.", p7ParkIndex ); + } + + const uint64 p7LocalIdx = f7Idx - p7ParkIndex * kEntriesPerPark; + const uint64 t6Index = p7Entries[p7LocalIdx]; + + bool success = true; + + if( k <= 32 ) + { + success = FetchProof( plot, t6Index, fullProofXs ); + } + else + success = FetchProof( plot, t6Index, fullProofXs ); + + if( success ) + { + // ReorderProof( plot, fullProofXs ); // <-- No need for this for validation + + // Now we can validate the proof + uint64 outF7; + + if( ValidateFullProof( k, plot.PlotFile().PlotId(), fullProofXs, outF7 ) ) + success = f7 == outF7; + else + success = false; + } + else + { + success = false; + Log( "Park %llu proof fetch failed for f7[%llu] local(%llu) = %llu ( 0x%016llx ) ", + c3ParkIdx, f7Idx, e, f7, f7 ); + } + + if( !success ) + { + proofFailCount++; + } + } + + const double elapsed = TimerEnd( timer ); + Log( "%10llu..%-10llu ( %3.2lf%% ) C3 Park Validated in %2.2lf seconds | Proofs Failed: %llu", + c3ParkIdx, c3ParkEnd-1, + (double)(c3ParkIdx-startC3Park) / c3ParkCount * 100, elapsed, + proofFailCount ); + } + + // All done + this->failCount = proofFailCount; +} + + +//----------------------------------------------------------- +UnpackedK32Plot UnpackedK32Plot::Load( IPlotFile** plotFile, ThreadPool& pool, uint32 threadCount ) +{ + ASSERT( plotFile ); + const uint32 k = plotFile[0]->K(); + FatalIf( k != 32, "Only k=32 plots are supported for unpacked validation." ); + + threadCount = threadCount == 0 ? pool.ThreadCount() : threadCount; + + UnpackedK32Plot plot; + + PlotReader* readers = bbcalloc( threadCount ); + for( uint32 i = 0; i < threadCount; i++ ) + new ( (void*)&readers[i] ) PlotReader( *plotFile[i] ); + + + PlotReader& plotReader = readers[0]; + + uint64 f7Count = plotReader.GetMaxF7EntryCount(); FatalIf( f7Count < 1, "No F7s found." ); + + // Load F7s + { + Log::Line( "Unpacking f7 values..." ); + uint32* f7 = bbcvirtallocboundednuma( f7Count ); + + uint64 missingF7 = 0; + + AnonMTJob::Run( pool, threadCount, [&]( AnonMTJob* self ) { + + PlotReader& reader = readers[self->_jobId]; + + const uint64 plotParkCount = reader.GetC3ParkCount(); + + uint64 parkCount, parkOffset, parkEnd; + GetThreadOffsets( self, plotParkCount, parkCount, parkOffset, parkEnd ); + + uint64 f7Buffer[kCheckpoint1Interval]; + uint32* f7Writer = f7 + parkOffset * kCheckpoint1Interval; + + for( uint64 i = parkOffset; i < parkEnd; i++ ) + { + const int64 entryCount = reader.ReadC3Park( i, f7Buffer ); + + FatalIf( entryCount == 0, "Empty C3 park @ %llu.", i ); + + for( int64 e = 0; e < entryCount; e++ ) + f7Writer[e] = (uint32)f7Buffer[e]; + + f7Writer += entryCount; + + if( entryCount < kCheckpoint1Interval ) + { + if( self->IsLastThread() && i + 1 == parkEnd ) + { + missingF7 = kCheckpoint1Interval - entryCount; + break; + } + else + FatalErrorMsg( "C3 park %llu is not full and it is not the last park.", i ); + } + } + }); + + f7Count -= missingF7; + plot.f7.length = f7Count; + plot.f7.values = f7; + } + + // Read Park 7 + Log::Line( "Reding park 7..." ); + uint64* p7Indices = nullptr; + { + const uint64 park7Count = CDiv( f7Count, kEntriesPerPark ); + + #if _DEBUG + const size_t p7Size = plotReader.PlotFile().TableSize( PlotTable::Table7 ); + const size_t parkSize = CalculatePark7Size( plotReader.PlotFile().K() ); + const size_t potentialParkCount = p7Size / parkSize; + ASSERT( potentialParkCount >= park7Count ); + #endif + + p7Indices = bbcvirtallocboundednuma( park7Count * kEntriesPerPark ); + + AnonMTJob::Run( pool, threadCount, [=]( AnonMTJob* self ) { + + PlotReader& reader = readers[self->_jobId]; + + uint64 parkCount, parkOffset, parkEnd; + GetThreadOffsets( self, park7Count, parkCount, parkOffset, parkEnd ); + + uint64* p7Writer = p7Indices + parkOffset * kEntriesPerPark; + + for( uint64 i = parkOffset; i < parkEnd; i++ ) + { + FatalIf( !reader.ReadP7Entries( i, p7Writer ), "Failed to read park 7 %llu.", i ); + p7Writer += kEntriesPerPark; + } + }); + } + + + auto LoadBackPtrTable = [&]( const TableId table ) { + + Log::Line( "Loading table %u", table+1 ); + + const uint64 plotParkCount = plotReader.GetTableParkCount( (PlotTable)table ); + + Span backPointers = bbcvirtallocboundednuma_span( plotParkCount * kEntriesPerPark ); + uint64 missingParks = 0; + uint64 missingEntries = 0; + + + AnonMTJob::Run( pool, threadCount, [&]( AnonMTJob* self ) { + + PlotReader& reader = readers[self->_jobId]; + + uint64 parkCount, parkOffset, parkEnd; + GetThreadOffsets( self, plotParkCount, parkCount, parkOffset, parkEnd ); + + uint64 parkEntryCount; + uint128 linePoints[kEntriesPerPark]; + + Span tableWriter = backPointers.Slice( parkOffset * kEntriesPerPark, parkCount * kEntriesPerPark ); + + for( uint64 i = parkOffset; i < parkEnd; i++ ) + { + if( !reader.ReadLPPark( table, i, linePoints, parkEntryCount ) ) + { + // If its the last thread loading the park, there may be empty space + // after the actual parks end, so these are allowed, but we stop processing parks after this. + if( self->IsLastThread() ) + { + missingParks = parkEnd - i; + break; + } + else + FatalErrorMsg( "Failed to read Table %u park %llu", table+1, i ); + } + + // Since we only support in-ram validation for k <= 32, we can do 64-bit LP reading + for( uint64 e = 0; e < parkEntryCount; e++ ) + { + const BackPtr bp = LinePointToSquare64( (uint64)linePoints[e] ); + Pair pair; + pair.left = (uint32)bp.x; + pair.right = (uint32)bp.y; + tableWriter[e] = pair; + } + + if( parkEntryCount < kEntriesPerPark ) + { + // We only allow incomplete parks at the end, so stop processing parks as soon as we encounter one + if( self->IsLastThread() && i + 1 == parkEnd ) + { + missingEntries = kEntriesPerPark - parkEntryCount; + break; + } + else + FatalErrorMsg( "Encountered a non-full park for table %u at index %llu. These are unsupported", table+1, i ); + } + + tableWriter = tableWriter.Slice( kEntriesPerPark ); + } + }); + + const uint64 tableEntryCount = ( plotParkCount * kEntriesPerPark ) - ( missingParks * kEntriesPerPark + missingEntries ); + return backPointers.Slice( 0, tableEntryCount ); + }; + + /// Load T6 first so we can sort them on P7 + Log::Line( "Loading back pointer tables..." ); + auto t6 = LoadBackPtrTable( TableId::Table6 ); + ASSERT( t6.Length() == f7Count ); + { + // Span sortedT6 = bbcvirtallocboundednuma_span( t6.Length() ); + + AnonMTJob::Run( pool, threadCount, [=]( AnonMTJob* self ) { + + uint64 count, offset, end; + GetThreadOffsets( self, f7Count, count, offset, end ); + + static_assert( sizeof( uint64 ) == sizeof( Pair ) ); + const Span reader( p7Indices + offset, count ); + Span writer( (Pair*)p7Indices + offset, count ); + + for( uint64 i = 0; i < count; i++ ) + writer[i] = t6[reader[i]]; + }); + + plot.tables[(int)TableId::Table6] = Span( (Pair*)p7Indices, f7Count ); + bbvirtfreebounded( t6.values ); + } + + // Read the rest of the entries + plot.tables[(int)TableId::Table5] = LoadBackPtrTable( TableId::Table5 ); + plot.tables[(int)TableId::Table4] = LoadBackPtrTable( TableId::Table4 ); + plot.tables[(int)TableId::Table3] = LoadBackPtrTable( TableId::Table3 ); + plot.tables[(int)TableId::Table2] = LoadBackPtrTable( TableId::Table2 ); + plot.tables[(int)TableId::Table1] = LoadBackPtrTable( TableId::Table1 ); + + Log::Line( "Decompressed plot into memory." ); + return plot; +} + +//----------------------------------------------------------- +bool UnpackedK32Plot::FetchProof( const uint64 index, uint64 fullProofXs[PROOF_X_COUNT] ) +{ + if( index >= this->f7.Length() ) + return false; + + uint64 lpIndices[2][PROOF_X_COUNT]; + + uint64* lpIdxSrc = lpIndices[0]; + uint64* lpIdxDst = lpIndices[1]; + + *lpIdxSrc = index; + + uint32 lookupCount = 1; + for( TableId table = TableId::Table6; table >= TableId::Table1; table-- ) + { + ASSERT( lookupCount <= 32 ); + + const Span plotTable = this->Table( table ); + + for( uint32 i = 0, dst = 0; i < lookupCount; i++, dst += 2 ) + { + const uint64 idx = lpIdxSrc[i]; + + if( idx >= plotTable.Length() ) + return false; + + const Pair ptr = plotTable[idx]; + lpIdxDst[dst+0] = ptr.right; + lpIdxDst[dst+1] = ptr.left; + } + + lookupCount <<= 1; + std::swap( lpIdxSrc, lpIdxDst ); + } + + // Full proof x's will be at the src ptr + memcpy( fullProofXs, lpIdxSrc, sizeof( uint64 ) * PROOF_X_COUNT ); + return true; +} + +//----------------------------------------------------------- +template +bool FetchProof( PlotReader& plot, uint64 t6LPIndex, uint64 fullProofXs[PROOF_X_COUNT] ) +{ + uint64 lpIndices[2][PROOF_X_COUNT]; + // memset( lpIndices, 0, sizeof( lpIndices ) ); + + uint64* lpIdxSrc = lpIndices[0]; + uint64* lpIdxDst = lpIndices[1]; + + *lpIdxSrc = t6LPIndex; + + // Fetch line points to back pointers going through all our tables + // from 6 to 1, grabbing all of the x's that make up a proof. + uint32 lookupCount = 1; + + for( TableId table = TableId::Table6; table >= TableId::Table1; table-- ) + { + ASSERT( lookupCount <= 32 ); + + for( uint32 i = 0, dst = 0; i < lookupCount; i++, dst += 2 ) + { + const uint64 idx = lpIdxSrc[i]; + + uint128 lp = 0; + if( !plot.ReadLP( table, idx, lp ) ) + return false; + + BackPtr ptr; + if constexpr ( Use64BitLpToSquare ) + ptr = LinePointToSquare64( (uint64)lp ); + else + ptr = LinePointToSquare( lp ); + + lpIdxDst[dst+0] = ptr.y; + lpIdxDst[dst+1] = ptr.x; + } + + lookupCount <<= 1; + + std::swap( lpIdxSrc, lpIdxDst ); + // memset( lpIdxDst, 0, sizeof( uint64 ) * PROOF_X_COUNT ); + } + + // Full proof x's will be at the src ptr + memcpy( fullProofXs, lpIdxSrc, sizeof( uint64 ) * PROOF_X_COUNT ); + return true; +} + +//----------------------------------------------------------- +bool ValidateFullProof( const uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 fullProofXs[PROOF_X_COUNT], uint64& outF7 ) +{ + uint64 fx [PROOF_X_COUNT]; + MetaBits meta[PROOF_X_COUNT]; + + // Convert these x's to f1 values + { + const uint32 xShift = k - kExtraBits; + + // Prepare ChaCha key + byte key[32] = { 1 }; + memcpy( key + 1, plotId, 31 ); + + chacha8_ctx chacha; + chacha8_keysetup( &chacha, key, 256, NULL ); + + // Enough to hold 2 cha-cha blocks since a value my span over 2 blocks + byte blocks[kF1BlockSize*2]; + + for( uint32 i = 0; i < PROOF_X_COUNT; i++ ) + { + const uint64 x = fullProofXs[i]; + const uint64 blockIdx = x * k / kF1BlockSizeBits; + + chacha8_get_keystream( &chacha, blockIdx, 2, blocks ); + + // Get the starting and end locations of y in bits relative to our block + const uint64 bitStart = x * k - blockIdx * kF1BlockSizeBits; + + CPBitReader hashBits( blocks, sizeof( blocks ) * 8 ); + hashBits.Seek( bitStart ); + + // uint64 y = SliceUInt64FromBits( blocks, bitStart, k ); // #TODO: Figure out what's wrong with this method. + uint64 y = hashBits.Read64( k ); + y = ( y << kExtraBits ) | ( x >> xShift ); + + fx [i] = y; + meta[i] = MetaBits( x, k ); + } + } + + // Forward propagate f1 values to get the final f7 + uint32 iterCount = PROOF_X_COUNT; + for( TableId table = TableId::Table2; table <= TableId::Table7; table++, iterCount >>= 1) + { + for( uint32 i = 0, dst = 0; i < iterCount; i+= 2, dst++ ) + { + uint64 y0 = fx[i+0]; + uint64 y1 = fx[i+1]; + + const MetaBits* lMeta = &meta[i+0]; + const MetaBits* rMeta = &meta[i+1]; + + if( y0 > y1 ) + { + std::swap( y0, y1 ); + std::swap( lMeta, rMeta ); + } + + // Must be on the same group + if( !FxMatch( y0, y1 ) ) + return false; + + // FxGen + uint64 outY; + MetaBits outMeta; + FxGen( table, k, y0, *lMeta, *rMeta, outY, outMeta ); + + fx [dst] = outY; + meta[dst] = outMeta; + } + } + + outF7 = fx[0] >> kExtraBits; + + return true; +} + + +// #TODO: Avoid code duplication here? At least for f1 +//----------------------------------------------------------- +void ReorderProof( PlotReader& plot, uint64 fullProofXs[PROOF_X_COUNT] ) +{ + const uint32 k = plot.PlotFile().K(); + + uint64 fx [PROOF_X_COUNT]; + MetaBits meta[PROOF_X_COUNT]; + + uint64 xtmp[PROOF_X_COUNT]; + uint64* xs = fullProofXs; + + // Convert these x's to f1 values + GetProofF1( k, plot.PlotFile().PlotId(), fullProofXs, fx ); + for( uint32 i = 0; i < PROOF_X_COUNT; i++ ) + meta[i] = MetaBits( xs[i], k ); + + // Forward propagate f1 values to get the final f7 + uint32 iterCount = PROOF_X_COUNT; + for( TableId table = TableId::Table2; table <= TableId::Table7; table++, iterCount >>= 1) + { + for( uint32 i = 0, dst = 0; i < iterCount; i+= 2, dst++ ) + { + uint64 y0 = fx[i+0]; + uint64 y1 = fx[i+1]; + + const MetaBits* lMeta = &meta[i+0]; + const MetaBits* rMeta = &meta[i+1]; + + if( y0 > y1 ) + { + std::swap( y0, y1 ); + std::swap( lMeta, rMeta ); + + // Swap X's so far that have generated this y + const uint32 count = 1u << ((int)table-1); + uint64* x = xs + i * count; + bbmemcpy_t( xtmp , x , count ); + bbmemcpy_t( x , x+count, count ); + bbmemcpy_t( x+count, xtmp , count ); + } + + // FxGen + uint64 outY; + MetaBits outMeta; + FxGen( table, k, y0, *lMeta, *rMeta, outY, outMeta ); + + fx [dst] = outY; + meta[dst] = outMeta; + } + } +} + +//----------------------------------------------------------- +void GetProofF1( uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 fullProofXs[PROOF_X_COUNT], uint64 fx[PROOF_X_COUNT] ) +{ + const uint32 xShift = k - kExtraBits; + + // Prepare ChaCha key + byte key[32] = { 1 }; + memcpy( key + 1, plotId, 31 ); + + chacha8_ctx chacha; + chacha8_keysetup( &chacha, key, 256, NULL ); + + // Enough to hold 2 cha-cha blocks since a value my span over 2 blocks + byte blocks[kF1BlockSize*2]; + + for( uint32 i = 0; i < PROOF_X_COUNT; i++ ) + { + const uint64 x = fullProofXs[i]; + const uint64 blockIdx = x * k / kF1BlockSizeBits; + + chacha8_get_keystream( &chacha, blockIdx, 2, blocks ); + + // Get the starting and end locations of y in bits relative to our block + const uint64 bitStart = x * k - blockIdx * kF1BlockSizeBits; + + CPBitReader hashBits( blocks, sizeof( blocks ) * 8 ); + hashBits.Seek( bitStart ); + + // uint64 y = SliceUInt64FromBits( blocks, bitStart, k ); // #TODO: Figure out what's wrong with this method. + uint64 y = hashBits.Read64( k ); + y = ( y << kExtraBits ) | ( x >> xShift ); + + fx[i] = y; + } +} + +//----------------------------------------------------------- +bool FxMatch( uint64 yL, uint64 yR ) +{ + const uint64 groupL = yL / kBC; + const uint64 groupR = yR / kBC; + + if( groupR - groupL != 1 ) + return false; + + // Groups are adjacent, check if the y values actually match + const uint16 parity = groupL & 1; + + const uint64 groupLRangeStart = groupL * kBC; + const uint64 groupRRangeStart = groupR * kBC; + + const uint64 localLY = yL - groupLRangeStart; + const uint64 localRY = yR - groupRRangeStart; + + for( int iK = 0; iK < kExtraBitsPow; iK++ ) + { + const uint64 targetR = L_targets[parity][localLY][iK]; + + if( targetR == localRY ) + return true; + } + + return false; +} + +//----------------------------------------------------------- +void FxGen( const TableId table, const uint32 k, + const uint64 y, const MetaBits& metaL, const MetaBits& metaR, + uint64& outY, MetaBits& outMeta ) +{ + FxBits input( y, k + kExtraBits ); + + if( table < TableId::Table4 ) + { + outMeta = metaL + metaR; + input += outMeta; + } + else + { + input += metaL; + input += metaR; + } + + byte inputBytes[64]; + byte hashBytes [32]; + + input.ToBytes( inputBytes ); + + blake3_hasher hasher; + blake3_hasher_init ( &hasher ); + blake3_hasher_update ( &hasher, inputBytes, input.LengthBytes() ); + blake3_hasher_finalize( &hasher, hashBytes, sizeof( hashBytes ) ); + + outY = BytesToUInt64( hashBytes ) >> ( 64 - (k + kExtraBits) ); + + if( table >= TableId::Table4 && table < TableId::Table7 ) + { + size_t multiplier = 0; + switch( table ) + { + case TableId::Table4: multiplier = TableMetaOut::Multiplier; break; + case TableId::Table5: multiplier = TableMetaOut::Multiplier; break; + case TableId::Table6: multiplier = TableMetaOut::Multiplier; break; + default: + ASSERT( 0 ); + break; + } + + const uint32 metaBits = (uint32)( k * multiplier ); + const uint32 yBits = k + kExtraBits; + const uint32 startByte = yBits / 8 ; + const uint32 startBit = yBits - startByte * 8; + + outMeta = MetaBits( hashBytes + startByte, metaBits, startBit ); + } +} + +//----------------------------------------------------------- +/// Convertes 8 bytes to uint64 and endian-swaps it. +/// This takes any byte alignment, so that bytes does +/// not have to be aligned to 64-bit boundary. +/// This is for compatibility for how chiapos extracts +/// bytes into integers. +//----------------------------------------------------------- +inline uint64 BytesToUInt64( const byte bytes[8] ) +{ + uint64 tmp; + memcpy( &tmp, bytes, sizeof( uint64 ) ); + return Swap64( tmp ); +} + +//----------------------------------------------------------- +// Treats bytes as a set of 64-bit big-endian fields, +// from which it will extract a whole 64-bit value +// at the given bit offset. +// The result may be truncated if the requested number of +// bits + the number of bits overflows the 64-bit field. +// That is, if the local bit offset in the target bit field +// + the bitCount is greater than 64. +// This function is for compatibility with the way chiapos +// slices bits off of binary byte blobs. +//----------------------------------------------------------- +inline uint64 SliceUInt64FromBits( const byte* bytes, uint32 bitOffset, uint32 bitCount ) +{ + ASSERT( bitCount <= 64 ); + + // #TODO: This is wrong, it's not treating the bytes as 64-bit fields. + // So that we may have swapped at the wrong position. + // In fact we might have fields that span 2 64-bit values. + // So we need to split it into 2, and do 2 swaps. + const uint64 startByte = bitOffset / 8; + bytes += startByte; + + // Convert bit offset to be local to the uint64 field + bitOffset -= ( bitOffset >> 6 ) * 64; // bitOffset >> 6 == bitOffset / 64 + + uint64 field = BytesToUInt64( bytes ); + + field <<= bitOffset; // Start bits from the MSBits + field >>= 64 - bitCount; // Take the MSbits + + return field; +} + + +//----------------------------------------------------------- +void TVLog( const uint32 id, const char* msg, va_list args ) +{ + _logLock.lock(); + fprintf( stdout, "[%3u] ", id ); + vfprintf( stdout, msg, args ); + putc( '\n', stdout ); + _logLock.unlock(); +} + +//----------------------------------------------------------- +// void TLog( const uint32 id, const char* msg, ... ) +// { +// va_list args; +// va_start( args, msg ); +// TVLog( id, msg, args ); +// va_end( args ); +// } + +#pragma GCC diagnostic pop + diff --git a/src/uint128_t/LICENSE b/src/uint128_t/LICENSE new file mode 100644 index 00000000..39ce428c --- /dev/null +++ b/src/uint128_t/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 - 2017 Jason Lee @ calccrypto at gmail.com + +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. \ No newline at end of file diff --git a/src/uint128_t/README.md b/src/uint128_t/README.md new file mode 100644 index 00000000..09cebc7b --- /dev/null +++ b/src/uint128_t/README.md @@ -0,0 +1,48 @@ +# uint128_t + +An unsigned 128 bit integer type for C++ + +Copyright (c) 2013 - 2018 Jason Lee @ calccrypto at gmail.com + +Please see LICENSE file for license. + +[![Build Status](https://travis-ci.org/calccrypto/uint128_t.svg?branch=master)](https://travis-ci.org/calccrypto/uint128_t) + +## Acknowledgements +With much help from Auston Sterling + +Thanks to Stefan Deigmüller for finding +a bug in operator*. + +Thanks to François Dessenne for convincing me +to do a general rewrite of this class. + +Thanks to John Skaller for making symbols visible +when compiling as a shared library. This was originally +done in `uint256_t`, which I copied into here. + +## Usage +This is simple implementation of an unsigned 128 bit +integer type in C++. It's meant to be used like a standard +`uintX_t`, except with a larger bit size than those provided +by C/C++. + +### In Code +All that needs to be done in code is `#include "uint128_t.h"` + +```c++ +#include +#include "uint128_t.h" + +int main() { + uint128_t a = 1; + uint128_t b = 2; + std::cout << (a | b) << std::endl; + return 0; +} +``` + +### Compilation +A C++ compiler supporting at least C++11 is required. + +Compilation can be done by directly including `uint128_t.cpp` in your compile command, e.g. `g++ -std=c++11 main.cpp uint128_t.cpp`, or other ways, such as linking the `uint128_t.o` file, or creating a library, and linking the library in. diff --git a/src/uint128_t/endianness.h b/src/uint128_t/endianness.h new file mode 100644 index 00000000..517790f2 --- /dev/null +++ b/src/uint128_t/endianness.h @@ -0,0 +1,26 @@ +#ifndef _ENDIANNESS_H_ +#define _ENDIANNESS_H_ +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \ + defined(__BIG_ENDIAN__) || \ + defined(__ARMEB__) || \ + defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || \ + defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) +#ifndef __BIG_ENDIAN__ +#define __BIG_ENDIAN__ +#endif +#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \ + defined(__LITTLE_ENDIAN__) || \ + defined(__ARMEL__) || \ + defined(__THUMBEL__) || \ + defined(__AARCH64EL__) || \ + defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || \ + defined(_WIN32) || defined(__i386__) || defined(__x86_64__) || \ + defined(_X86_) || defined(_IA64_) +#ifndef __LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ +#endif +#else +#error "I don't know what architecture this is!" +#endif +#endif diff --git a/src/uint128_t/uint128_t.build b/src/uint128_t/uint128_t.build new file mode 100644 index 00000000..e423dfe9 --- /dev/null +++ b/src/uint128_t/uint128_t.build @@ -0,0 +1,10 @@ +// IMPLEMENTATION BUILD HEADER +#ifndef _UINT128_T_BUILD + #define _UINT128_T_BUILD + #include "uint128_t_config.include" + #ifndef UINT128_T_EXTERN + #define UINT128_T_EXTERN _UINT128_T_EXPORT + #endif +#endif +#include "uint128_t.include" + diff --git a/src/uint128_t/uint128_t.cpp b/src/uint128_t/uint128_t.cpp new file mode 100644 index 00000000..a8feac8e --- /dev/null +++ b/src/uint128_t/uint128_t.cpp @@ -0,0 +1,548 @@ +#if _WIN32 + #pragma warning( push ) + #pragma warning( disable: 4804 ) // 'operation' : unsafe use of type 'bool' in operation +#endif + +#include "uint128_t.build" +#include + +const uint128_t uint128_0(0); +const uint128_t uint128_1(1); + +uint128_t::uint128_t(std::string & s) { + init(s.c_str()); +} + +uint128_t::uint128_t(const char *s) { + init(s); +} + +void uint128_t::init(const char *s) { + if (s == NULL || s[0] == 0){ + LOWER = UPPER = 0; + return; + } + + while (*s == ' ') ++s; + + if (std::memcmp(s, "0x", 2) == 0){ + _init_hex(&s[2]); + } + else if (std::memcmp(s, "0o", 2) == 0){ + _init_oct(&s[2]); + } + else{ + _init_dec(s); + } +} + +void uint128_t::_init_hex(const char *s) { + // 2**128 = 0x100000000000000000000000000000000. + LOWER = UPPER = 0; + int i; + for (i = 0; *s && i < 16; ++s, ++i){ + if ('0' <= *s && *s <= '9'){ + LOWER *= 16; + LOWER += *s - '0'; + } + else if ('A' <= *s && *s <= 'F'){ + LOWER *= 16; + LOWER += *s + (10 - 'A'); + } + else if ('a' <= *s && *s <= 'f'){ + LOWER *= 16; + LOWER += *s + (10 - 'a'); + } + else{ + return; + } + } + for (; *s && i < 32; ++s, ++i){ + if ('0' <= *s && *s <= '9'){ + *this *= 16; + *this += *s - '0'; + } + else if ('A' <= *s && *s <= 'F'){ + *this *= 16; + *this += *s + (10 - 'A'); + } + else if ('a' <= *s && *s <= 'f'){ + *this *= 16; + *this += *s + (10 - 'a'); + } + else{ + return; + } + } +} + +void uint128_t::_init_dec(const char *s){ + // 2**128 = 340282366920938463463374607431768211456. + LOWER = UPPER = 0; + for (int i = 0; '0' <= *s && *s <= '9' && i < 39; ++s, ++i){ + *this *= 10; + *this += *s - '0'; + } +} + +void uint128_t::_init_oct(const char *s){ + // 2**128 = 0o4000000000000000000000000000000000000000000. + LOWER = UPPER = 0; + for (int i = 0; '0' <= *s && *s <= '7' && i < 43; ++s, ++i){ + *this *= 8; + *this += *s - '0'; + } +} + +uint128_t::operator bool() const{ + return (bool) (UPPER | LOWER); +} + +uint128_t::operator uint8_t() const{ + return (uint8_t) LOWER; +} + +uint128_t::operator uint16_t() const{ + return (uint16_t) LOWER; +} + +uint128_t::operator uint32_t() const{ + return (uint32_t) LOWER; +} + +uint128_t::operator uint64_t() const{ + return (uint64_t) LOWER; +} + +uint128_t uint128_t::operator&(const uint128_t & rhs) const{ + return uint128_t(UPPER & rhs.UPPER, LOWER & rhs.LOWER); +} + +uint128_t & uint128_t::operator&=(const uint128_t & rhs){ + UPPER &= rhs.UPPER; + LOWER &= rhs.LOWER; + return *this; +} + +uint128_t uint128_t::operator|(const uint128_t & rhs) const{ + return uint128_t(UPPER | rhs.UPPER, LOWER | rhs.LOWER); +} + +uint128_t & uint128_t::operator|=(const uint128_t & rhs){ + UPPER |= rhs.UPPER; + LOWER |= rhs.LOWER; + return *this; +} + +uint128_t uint128_t::operator^(const uint128_t & rhs) const{ + return uint128_t(UPPER ^ rhs.UPPER, LOWER ^ rhs.LOWER); +} + +uint128_t & uint128_t::operator^=(const uint128_t & rhs){ + UPPER ^= rhs.UPPER; + LOWER ^= rhs.LOWER; + return *this; +} + +uint128_t uint128_t::operator~() const{ + return uint128_t(~UPPER, ~LOWER); +} + +uint128_t uint128_t::operator<<(const uint128_t & rhs) const{ + const uint64_t shift = rhs.LOWER; + if (((bool) rhs.UPPER) || (shift >= 128)){ + return uint128_0; + } + else if (shift == 64){ + return uint128_t(LOWER, 0); + } + else if (shift == 0){ + return *this; + } + else if (shift < 64){ + return uint128_t((UPPER << shift) + (LOWER >> (64 - shift)), LOWER << shift); + } + else if ((128 > shift) && (shift > 64)){ + return uint128_t(LOWER << (shift - 64), 0); + } + else{ + return uint128_0; + } +} + +uint128_t & uint128_t::operator<<=(const uint128_t & rhs){ + *this = *this << rhs; + return *this; +} + +uint128_t uint128_t::operator>>(const uint128_t & rhs) const{ + const uint64_t shift = rhs.LOWER; + if (((bool) rhs.UPPER) || (shift >= 128)){ + return uint128_0; + } + else if (shift == 64){ + return uint128_t(0, UPPER); + } + else if (shift == 0){ + return *this; + } + else if (shift < 64){ + return uint128_t(UPPER >> shift, (UPPER << (64 - shift)) + (LOWER >> shift)); + } + else if ((128 > shift) && (shift > 64)){ + return uint128_t(0, (UPPER >> (shift - 64))); + } + else{ + return uint128_0; + } +} + +uint128_t & uint128_t::operator>>=(const uint128_t & rhs){ + *this = *this >> rhs; + return *this; +} + +bool uint128_t::operator!() const{ + return !(bool) (UPPER | LOWER); +} + +bool uint128_t::operator&&(const uint128_t & rhs) const{ + return ((bool) *this && rhs); +} + +bool uint128_t::operator||(const uint128_t & rhs) const{ + return ((bool) *this || rhs); +} + +bool uint128_t::operator==(const uint128_t & rhs) const{ + return ((UPPER == rhs.UPPER) && (LOWER == rhs.LOWER)); +} + +bool uint128_t::operator!=(const uint128_t & rhs) const{ + return ((UPPER != rhs.UPPER) | (LOWER != rhs.LOWER)); +} + +bool uint128_t::operator>(const uint128_t & rhs) const{ + if (UPPER == rhs.UPPER){ + return (LOWER > rhs.LOWER); + } + return (UPPER > rhs.UPPER); +} + +bool uint128_t::operator<(const uint128_t & rhs) const{ + if (UPPER == rhs.UPPER){ + return (LOWER < rhs.LOWER); + } + return (UPPER < rhs.UPPER); +} + +bool uint128_t::operator>=(const uint128_t & rhs) const{ + return ((*this > rhs) | (*this == rhs)); +} + +bool uint128_t::operator<=(const uint128_t & rhs) const{ + return ((*this < rhs) | (*this == rhs)); +} + +uint128_t uint128_t::operator+(const uint128_t & rhs) const{ + return uint128_t(UPPER + rhs.UPPER + ((LOWER + rhs.LOWER) < LOWER), LOWER + rhs.LOWER); +} + +uint128_t & uint128_t::operator+=(const uint128_t & rhs){ + UPPER += rhs.UPPER + ((LOWER + rhs.LOWER) < LOWER); + LOWER += rhs.LOWER; + return *this; +} + +uint128_t uint128_t::operator-(const uint128_t & rhs) const{ + return uint128_t(UPPER - rhs.UPPER - ((LOWER - rhs.LOWER) > LOWER), LOWER - rhs.LOWER); +} + +uint128_t & uint128_t::operator-=(const uint128_t & rhs){ + *this = *this - rhs; + return *this; +} + +uint128_t uint128_t::operator*(const uint128_t & rhs) const{ + // split values into 4 32-bit parts + uint64_t top[4] = {UPPER >> 32, UPPER & 0xffffffff, LOWER >> 32, LOWER & 0xffffffff}; + uint64_t bottom[4] = {rhs.UPPER >> 32, rhs.UPPER & 0xffffffff, rhs.LOWER >> 32, rhs.LOWER & 0xffffffff}; + uint64_t products[4][4]; + + // multiply each component of the values + for(int y = 3; y > -1; y--){ + for(int x = 3; x > -1; x--){ + products[3 - x][y] = top[x] * bottom[y]; + } + } + + // first row + uint64_t fourth32 = (products[0][3] & 0xffffffff); + uint64_t third32 = (products[0][2] & 0xffffffff) + (products[0][3] >> 32); + uint64_t second32 = (products[0][1] & 0xffffffff) + (products[0][2] >> 32); + uint64_t first32 = (products[0][0] & 0xffffffff) + (products[0][1] >> 32); + + // second row + third32 += (products[1][3] & 0xffffffff); + second32 += (products[1][2] & 0xffffffff) + (products[1][3] >> 32); + first32 += (products[1][1] & 0xffffffff) + (products[1][2] >> 32); + + // third row + second32 += (products[2][3] & 0xffffffff); + first32 += (products[2][2] & 0xffffffff) + (products[2][3] >> 32); + + // fourth row + first32 += (products[3][3] & 0xffffffff); + + // move carry to next digit + third32 += fourth32 >> 32; + second32 += third32 >> 32; + first32 += second32 >> 32; + + // remove carry from current digit + fourth32 &= 0xffffffff; + third32 &= 0xffffffff; + second32 &= 0xffffffff; + first32 &= 0xffffffff; + + // combine components + return uint128_t((first32 << 32) | second32, (third32 << 32) | fourth32); +} + +uint128_t & uint128_t::operator*=(const uint128_t & rhs){ + *this = *this * rhs; + return *this; +} + +void uint128_t::ConvertToVector(std::vector & ret, const uint64_t & val) const { + ret.push_back(static_cast(val >> 56)); + ret.push_back(static_cast(val >> 48)); + ret.push_back(static_cast(val >> 40)); + ret.push_back(static_cast(val >> 32)); + ret.push_back(static_cast(val >> 24)); + ret.push_back(static_cast(val >> 16)); + ret.push_back(static_cast(val >> 8)); + ret.push_back(static_cast(val)); +} + +void uint128_t::export_bits(std::vector &ret) const { + ConvertToVector(ret, const_cast(UPPER)); + ConvertToVector(ret, const_cast(LOWER)); +} + +std::pair uint128_t::divmod(const uint128_t & lhs, const uint128_t & rhs) const{ + // Save some calculations ///////////////////// + if (rhs == uint128_0){ + throw std::domain_error("Error: division or modulus by 0"); + } + else if (rhs == uint128_1){ + return std::pair (lhs, uint128_0); + } + else if (lhs == rhs){ + return std::pair (uint128_1, uint128_0); + } + else if ((lhs == uint128_0) || (lhs < rhs)){ + return std::pair (uint128_0, lhs); + } + + std::pair qr (uint128_0, uint128_0); + for(uint8_t x = lhs.bits(); x > 0; x--){ + qr.first <<= uint128_1; + qr.second <<= uint128_1; + + if ((lhs >> (x - 1U)) & 1){ + ++qr.second; + } + + if (qr.second >= rhs){ + qr.second -= rhs; + ++qr.first; + } + } + return qr; +} + +uint128_t uint128_t::operator/(const uint128_t & rhs) const{ + return divmod(*this, rhs).first; +} + +uint128_t & uint128_t::operator/=(const uint128_t & rhs){ + *this = *this / rhs; + return *this; +} + +uint128_t uint128_t::operator%(const uint128_t & rhs) const{ + return divmod(*this, rhs).second; +} + +uint128_t & uint128_t::operator%=(const uint128_t & rhs){ + *this = *this % rhs; + return *this; +} + +uint128_t & uint128_t::operator++(){ + return *this += uint128_1; +} + +uint128_t uint128_t::operator++(int){ + uint128_t temp(*this); + ++*this; + return temp; +} + +uint128_t & uint128_t::operator--(){ + return *this -= uint128_1; +} + +uint128_t uint128_t::operator--(int){ + uint128_t temp(*this); + --*this; + return temp; +} + +uint128_t uint128_t::operator+() const{ + return *this; +} + +uint128_t uint128_t::operator-() const{ + return ~*this + uint128_1; +} + +const uint64_t & uint128_t::upper() const{ + return UPPER; +} + +const uint64_t & uint128_t::lower() const{ + return LOWER; +} + +uint8_t uint128_t::bits() const{ + uint8_t out = 0; + if (UPPER){ + out = 64; + uint64_t up = UPPER; + while (up){ + up >>= 1; + out++; + } + } + else{ + uint64_t low = LOWER; + while (low){ + low >>= 1; + out++; + } + } + return out; +} + +std::string uint128_t::str(uint8_t base, const unsigned int & len) const{ + if ((base < 2) || (base > 16)){ + throw std::invalid_argument("Base must be in the range [2, 16]"); + } + std::string out = ""; + if (!(*this)){ + out = "0"; + } + else{ + std::pair qr(*this, uint128_0); + do{ + qr = divmod(qr.first, base); + out = "0123456789abcdef"[(uint8_t) qr.second] + out; + } while (qr.first); + } + if (out.size() < len){ + out = std::string(len - out.size(), '0') + out; + } + return out; +} + +uint128_t operator<<(const bool & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator<<(const uint8_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator<<(const uint16_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator<<(const uint32_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator<<(const uint64_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator<<(const int8_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator<<(const int16_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator<<(const int32_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator<<(const int64_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) << rhs; +} + +uint128_t operator>>(const bool & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +uint128_t operator>>(const uint8_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +uint128_t operator>>(const uint16_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +uint128_t operator>>(const uint32_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +uint128_t operator>>(const uint64_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +uint128_t operator>>(const int8_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +uint128_t operator>>(const int16_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +uint128_t operator>>(const int32_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +uint128_t operator>>(const int64_t & lhs, const uint128_t & rhs){ + return uint128_t(lhs) >> rhs; +} + +std::ostream & operator<<(std::ostream & stream, const uint128_t & rhs){ + if (stream.flags() & stream.oct){ + stream << rhs.str(8); + } + else if (stream.flags() & stream.dec){ + stream << rhs.str(10); + } + else if (stream.flags() & stream.hex){ + stream << rhs.str(16); + } + return stream; +} + + +#if _WIN32 + #pragma warning( pop ) +#endif \ No newline at end of file diff --git a/src/uint128_t/uint128_t.h b/src/uint128_t/uint128_t.h new file mode 100644 index 00000000..da5aa514 --- /dev/null +++ b/src/uint128_t/uint128_t.h @@ -0,0 +1,8 @@ +// PUBLIC IMPORT HEADER +#ifndef _UINT128_H_ +#define _UINT128_H_ +#include "uint128_t_config.include" +#define UINT128_T_EXTERN _UINT128_T_IMPORT +#include "uint128_t.include" +#endif + diff --git a/src/uint128_t/uint128_t.include b/src/uint128_t/uint128_t.include new file mode 100644 index 00000000..000bffad --- /dev/null +++ b/src/uint128_t/uint128_t.include @@ -0,0 +1,533 @@ +/* +uint128_t.h +An unsigned 128 bit integer type for C++ + +Copyright (c) 2013 - 2017 Jason Lee @ calccrypto at gmail.com + +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. + +With much help from Auston Sterling + +Thanks to Stefan Deigmüller for finding +a bug in operator*. + +Thanks to François Dessenne for convincing me +to do a general rewrite of this class. +*/ + +#ifndef __UINT128_T__ +#define __UINT128_T__ + +#include +#include +#include +#include +#include +#include +#include + +#include "endianness.h" + +class UINT128_T_EXTERN uint128_t; + +// Give uint128_t type traits +namespace std { // This is probably not a good idea + template <> struct is_arithmetic : std::true_type {}; + template <> struct is_integral : std::true_type {}; + template <> struct is_unsigned : std::true_type {}; +} + +class uint128_t{ + private: +#ifdef __BIG_ENDIAN__ + uint64_t UPPER, LOWER; +#endif +#ifdef __LITTLE_ENDIAN__ + uint64_t LOWER, UPPER; +#endif + + public: + // Constructors + uint128_t() = default; + uint128_t(const uint128_t & rhs) = default; + uint128_t(uint128_t && rhs) = default; + uint128_t(std::string & s); + uint128_t(const char *s); + + template ::value, T>::type > + uint128_t(const T & rhs) +#ifdef __BIG_ENDIAN__ + : UPPER(0), LOWER(rhs) +#endif +#ifdef __LITTLE_ENDIAN__ + : LOWER(rhs), UPPER(0) +#endif + { + if (std::is_signed::value) { + if (rhs < 0) { + UPPER = -1; + } + } + } + + template ::value && std::is_integral::value, void>::type> + uint128_t(const S & upper_rhs, const T & lower_rhs) +#ifdef __BIG_ENDIAN__ + : UPPER(upper_rhs), LOWER(lower_rhs) +#endif +#ifdef __LITTLE_ENDIAN__ + : LOWER(lower_rhs), UPPER(upper_rhs) +#endif + {} + + // RHS input args only + + // Assignment Operator + uint128_t & operator=(const uint128_t & rhs) = default; + uint128_t & operator=(uint128_t && rhs) = default; + + template ::value, T>::type > + uint128_t & operator=(const T & rhs){ + UPPER = 0; + + if (std::is_signed::value) { + if (rhs < 0) { + UPPER = -1; + } + } + + LOWER = rhs; + return *this; + } + + // Typecast Operators + operator bool() const; + operator uint8_t() const; + operator uint16_t() const; + operator uint32_t() const; + operator uint64_t() const; + + // Bitwise Operators + uint128_t operator&(const uint128_t & rhs) const; + + void export_bits(std::vector & ret) const; + + template ::value, T>::type > + uint128_t operator&(const T & rhs) const{ + return uint128_t(0, LOWER & (uint64_t) rhs); + } + + uint128_t & operator&=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator&=(const T & rhs){ + UPPER = 0; + LOWER &= rhs; + return *this; + } + + uint128_t operator|(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator|(const T & rhs) const{ + return uint128_t(UPPER, LOWER | (uint64_t) rhs); + } + + uint128_t & operator|=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator|=(const T & rhs){ + LOWER |= (uint64_t) rhs; + return *this; + } + + uint128_t operator^(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator^(const T & rhs) const{ + return uint128_t(UPPER, LOWER ^ (uint64_t) rhs); + } + + uint128_t & operator^=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator^=(const T & rhs){ + LOWER ^= (uint64_t) rhs; + return *this; + } + + uint128_t operator~() const; + + // Bit Shift Operators + uint128_t operator<<(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator<<(const T & rhs) const{ + return *this << uint128_t(rhs); + } + + uint128_t & operator<<=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator<<=(const T & rhs){ + *this = *this << uint128_t(rhs); + return *this; + } + + uint128_t operator>>(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator>>(const T & rhs) const{ + return *this >> uint128_t(rhs); + } + + uint128_t & operator>>=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator>>=(const T & rhs){ + *this = *this >> uint128_t(rhs); + return *this; + } + + // Logical Operators + bool operator!() const; + bool operator&&(const uint128_t & rhs) const; + bool operator||(const uint128_t & rhs) const; + + template ::value, T>::type > + bool operator&&(const T & rhs) const{ + return static_cast (*this && rhs); + } + + template ::value, T>::type > + bool operator||(const T & rhs) const{ + return static_cast (*this || rhs); + } + + // Comparison Operators + bool operator==(const uint128_t & rhs) const; + + template ::value, T>::type > + bool operator==(const T & rhs) const{ + return (!UPPER && (LOWER == (uint64_t) rhs)); + } + + bool operator!=(const uint128_t & rhs) const; + + template ::value, T>::type > + bool operator!=(const T & rhs) const{ + return (UPPER | (LOWER != (uint64_t) rhs)); + } + + bool operator>(const uint128_t & rhs) const; + + template ::value, T>::type > + bool operator>(const T & rhs) const{ + return (UPPER || (LOWER > (uint64_t) rhs)); + } + + bool operator<(const uint128_t & rhs) const; + + template ::value, T>::type > + bool operator<(const T & rhs) const{ + return (!UPPER)?(LOWER < (uint64_t) rhs):false; + } + + bool operator>=(const uint128_t & rhs) const; + + template ::value, T>::type > + bool operator>=(const T & rhs) const{ + return ((*this > rhs) | (*this == rhs)); + } + + bool operator<=(const uint128_t & rhs) const; + + template ::value, T>::type > + bool operator<=(const T & rhs) const{ + return ((*this < rhs) | (*this == rhs)); + } + + // Arithmetic Operators + uint128_t operator+(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator+(const T & rhs) const{ + return uint128_t(UPPER + ((LOWER + (uint64_t) rhs) < LOWER), LOWER + (uint64_t) rhs); + } + + uint128_t & operator+=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator+=(const T & rhs){ + return *this += uint128_t(rhs); + } + + uint128_t operator-(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator-(const T & rhs) const{ + return uint128_t((uint64_t) (UPPER - ((LOWER - rhs) > LOWER)), (uint64_t) (LOWER - rhs)); + } + + uint128_t & operator-=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator-=(const T & rhs){ + return *this = *this - uint128_t(rhs); + } + + uint128_t operator*(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator*(const T & rhs) const{ + return *this * uint128_t(rhs); + } + + uint128_t & operator*=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator*=(const T & rhs){ + return *this = *this * uint128_t(rhs); + } + + private: + std::pair divmod(const uint128_t & lhs, const uint128_t & rhs) const; + void init(const char * s); + void ConvertToVector(std::vector & current, const uint64_t & val) const; + void _init_hex(const char *s); + void _init_dec(const char *s); + void _init_oct(const char *s); + + public: + uint128_t operator/(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator/(const T & rhs) const{ + return *this / uint128_t(rhs); + } + + uint128_t & operator/=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator/=(const T & rhs){ + return *this = *this / uint128_t(rhs); + } + + uint128_t operator%(const uint128_t & rhs) const; + + template ::value, T>::type > + uint128_t operator%(const T & rhs) const{ + return *this % uint128_t(rhs); + } + + uint128_t & operator%=(const uint128_t & rhs); + + template ::value, T>::type > + uint128_t & operator%=(const T & rhs){ + return *this = *this % uint128_t(rhs); + } + + // Increment Operator + uint128_t & operator++(); + uint128_t operator++(int); + + // Decrement Operator + uint128_t & operator--(); + uint128_t operator--(int); + + // Nothing done since promotion doesn't work here + uint128_t operator+() const; + + // two's complement + uint128_t operator-() const; + + // Get private values + const uint64_t & upper() const; + const uint64_t & lower() const; + + // Get bitsize of value + uint8_t bits() const; + + // Get string representation of value + std::string str(uint8_t base = 10, const unsigned int & len = 0) const; +}; + +// useful values +UINT128_T_EXTERN extern const uint128_t uint128_0; +UINT128_T_EXTERN extern const uint128_t uint128_1; + +// lhs type T as first arguemnt +// If the output is not a bool, casts to type T + +// Bitwise Operators +template ::value, T>::type > +uint128_t operator&(const T & lhs, const uint128_t & rhs){ + return rhs & lhs; +} + +template ::value, T>::type > +T & operator&=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (rhs & lhs); +} + +template ::value, T>::type > +uint128_t operator|(const T & lhs, const uint128_t & rhs){ + return rhs | lhs; +} + +template ::value, T>::type > +T & operator|=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (rhs | lhs); +} + +template ::value, T>::type > +uint128_t operator^(const T & lhs, const uint128_t & rhs){ + return rhs ^ lhs; +} + +template ::value, T>::type > +T & operator^=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (rhs ^ lhs); +} + +// Bitshift operators +UINT128_T_EXTERN uint128_t operator<<(const bool & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator<<(const uint8_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator<<(const uint16_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator<<(const uint32_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator<<(const uint64_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator<<(const int8_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator<<(const int16_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator<<(const int32_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator<<(const int64_t & lhs, const uint128_t & rhs); + +template ::value, T>::type > +T & operator<<=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (uint128_t(lhs) << rhs); +} + +UINT128_T_EXTERN uint128_t operator>>(const bool & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator>>(const uint8_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator>>(const uint16_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator>>(const uint32_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator>>(const uint64_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator>>(const int8_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator>>(const int16_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator>>(const int32_t & lhs, const uint128_t & rhs); +UINT128_T_EXTERN uint128_t operator>>(const int64_t & lhs, const uint128_t & rhs); + +template ::value, T>::type > +T & operator>>=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (uint128_t(lhs) >> rhs); +} + +// Comparison Operators +template ::value, T>::type > +bool operator==(const T & lhs, const uint128_t & rhs){ + return (!rhs.upper() && ((uint64_t) lhs == rhs.lower())); +} + +template ::value, T>::type > +bool operator!=(const T & lhs, const uint128_t & rhs){ + return (rhs.upper() | ((uint64_t) lhs != rhs.lower())); +} + +template ::value, T>::type > +bool operator>(const T & lhs, const uint128_t & rhs){ + return (!rhs.upper()) && ((uint64_t) lhs > rhs.lower()); +} + +template ::value, T>::type > +bool operator<(const T & lhs, const uint128_t & rhs){ + if (rhs.upper()){ + return true; + } + return ((uint64_t) lhs < rhs.lower()); +} + +template ::value, T>::type > +bool operator>=(const T & lhs, const uint128_t & rhs){ + if (rhs.upper()){ + return false; + } + return ((uint64_t) lhs >= rhs.lower()); +} + +template ::value, T>::type > +bool operator<=(const T & lhs, const uint128_t & rhs){ + if (rhs.upper()){ + return true; + } + return ((uint64_t) lhs <= rhs.lower()); +} + +// Arithmetic Operators +template ::value, T>::type > +uint128_t operator+(const T & lhs, const uint128_t & rhs){ + return rhs + lhs; +} + +template ::value, T>::type > +T & operator+=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (rhs + lhs); +} + +template ::value, T>::type > +uint128_t operator-(const T & lhs, const uint128_t & rhs){ + return -(rhs - lhs); +} + +template ::value, T>::type > +T & operator-=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (-(rhs - lhs)); +} + +template ::value, T>::type > +uint128_t operator*(const T & lhs, const uint128_t & rhs){ + return rhs * lhs; +} + +template ::value, T>::type > +T & operator*=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (rhs * lhs); +} + +template ::value, T>::type > +uint128_t operator/(const T & lhs, const uint128_t & rhs){ + return uint128_t(lhs) / rhs; +} + +template ::value, T>::type > +T & operator/=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (uint128_t(lhs) / rhs); +} + +template ::value, T>::type > +uint128_t operator%(const T & lhs, const uint128_t & rhs){ + return uint128_t(lhs) % rhs; +} + +template ::value, T>::type > +T & operator%=(T & lhs, const uint128_t & rhs){ + return lhs = static_cast (uint128_t(lhs) % rhs); +} + +// IO Operator +UINT128_T_EXTERN std::ostream & operator<<(std::ostream & stream, const uint128_t & rhs); +#endif diff --git a/src/uint128_t/uint128_t_config.include b/src/uint128_t/uint128_t_config.include new file mode 100644 index 00000000..fb5746bc --- /dev/null +++ b/src/uint128_t/uint128_t_config.include @@ -0,0 +1,18 @@ +#ifndef _UINT128_T_CONFIG_ + #define _UINT128_T_CONFIG_ + #if defined(_MSC_VER) +// #if defined(_DLL) +// #define _UINT128_T_EXPORT __declspec(dllexport) +// #define _UINT128_T_IMPORT __declspec(dllimport) +// #else + #define _UINT128_T_EXPORT + #define _UINT128_T_IMPORT +// #endif + #else + // All modules on Unix are compiled with -fvisibility=hidden + // All API symbols get visibility default + // whether or not we're static linking or dynamic linking (with -fPIC) + #define _UINT128_T_EXPORT __attribute__((visibility("default"))) + #define _UINT128_T_IMPORT __attribute__((visibility("default"))) + #endif +#endif diff --git a/src/util/Array.h b/src/util/Array.h new file mode 100644 index 00000000..bda3f243 --- /dev/null +++ b/src/util/Array.h @@ -0,0 +1,57 @@ +#pragma once + +// Simply dynamic array without the stl overhead +template +class Array +{ +public: + Array(); + Array( size_t capacity ); + ~Array(); + + T& Push(); + T& Push( const T& value ); + + void Pop(); + + T& Insert( const T& value, size_t index ); + T& Insert( size_t index ); + + void Remove( size_t index ); + + // Remove an element, and if it was not the last one in + // the array, the last element is placed in its index. + void UnorderedRemove( size_t index ); + + size_t Length() const; + + T* Ptr() const; + + inline T& operator[]( unsigned int index ) const + { + ASSERT( index < _length ); + return this->_elements[index]; + } + + inline T& operator[]( size_t index ) const + { + ASSERT( index < _length ); + return this->_elements[index]; + } + inline T& operator[]( int index ) const + { + ASSERT( index > -1 && (size_t)index < _length ); + return this->_elements[index]; + } + +private: + inline void CheckCapacity( size_t count ); + +private: + T* _elements; + size_t _capacity; + size_t _length; +}; + +#include "Array.inl" + diff --git a/src/util/Array.inl b/src/util/Array.inl new file mode 100644 index 00000000..97217c02 --- /dev/null +++ b/src/util/Array.inl @@ -0,0 +1,175 @@ +#pragma once +#include "Array.h" +#include "util/Util.h" + + +template +inline Array::Array() : Array( size_t( 0 ) ) +{ +} + +template +inline Array::Array( size_t capacity ) + : _elements( nullptr ) + , _capacity( capacity ) + , _length ( 0 ) +{ + if( _capacity ) + _elements = bbcalloc( capacity ); +} + +template +inline Array::~Array() +{ + if( _elements ) + free( _elements ); +} + +template +inline T& Array::Push() +{ + CheckCapacity( 1u ); + + T* value = &_elements[_length++]; + + value = new ( (void*)value ) T(); + return *value; +} + +template +inline T& Array::Push( const T& value ) +{ + CheckCapacity( 1u ); + + T* e = &_elements[_length++]; + + *e = value; + return *e; +} + +template +inline void Array::Pop() +{ + ASSERT( _length ); + + _elements[--_length].~T(); +} + +template +inline T& Array::Insert( const T& value, size_t index ) +{ + ASSERT( index <= _length ); + + CheckCapacity( 1u ); + + // Append to the end of the array? + if( index == _length ) + return Push( value ); + + // Move-up remainder elements + const size_t remainder = _length - index; + _length++; + + bbmemcpy_t( _elements + index + 1, _elements + index, remainder ); + + T* e = &_elements[index]; + *e = value; + + return *e; +} + +template +inline T& Array::Insert( size_t index ) +{ + ASSERT( index <= _length ); + + CheckCapacity( 1u ); + + // Append to the end of the array? + if( index == _length ) + return Push(); + + const size_t remainder = _length - index; + _length++; + + bbmemcpy_t( _elements + index + 1, _elements + index, remainder ); + + T* value = new ( (void*)&_elements[index] ) T(); + + return *value; +} + +template +inline void Array::Remove( size_t index ) +{ + ASSERT( index < _length ); + + if( index == _length - 1 ) + { + Pop(); + return; + } + + _elements[index].~T(); + + --_length; + const size_t remainder = _length - index; + + bbmemcpy_t( _elements + index, _elements + index + 1, remainder ); +} + +template +inline void Array::UnorderedRemove( size_t index ) +{ + ASSERT( index < _length ); + + if( index == _length - 1 ) + { + Pop(); + return; + } + + _elements[index].~T(); + _elements[index] = _elements[--_length]; +} + +template +inline size_t Array::Length() const +{ + return _length; +} + +template +inline T* Array::Ptr() const +{ + return _elements; +} + +template +inline void Array::CheckCapacity( size_t count ) +{ + ASSERT( _length < 9223372036854775807 ); + + const size_t newLength = _length + count; + + // Do we need to resize our buffer? + if( newLength > _capacity ) + { + size_t capacityGrow = 8; + + if( _capacity ) + capacityGrow = _capacity < 1024u ? _capacity : 1024u; + + size_t newCapacity = _capacity + capacityGrow; + if( newCapacity < _capacity ) + { + if( _capacity == 9223372036854775807 ) + Fatal( "Array exceeded maximum size." ); + + newCapacity = 9223372036854775807; + } + + _elements = bbcrealloc( _elements, newCapacity ); + _capacity = newCapacity; + } +} diff --git a/src/util/BitField.h b/src/util/BitField.h new file mode 100644 index 00000000..a853885e --- /dev/null +++ b/src/util/BitField.h @@ -0,0 +1,91 @@ +#pragma once + + +/// +/// Unsafe use: It does not do any bounds checking. +/// +class BitField +{ +public: + + //----------------------------------------------------------- + inline BitField() + : _fields( nullptr ) + , _length( 0 ) + {} + + //----------------------------------------------------------- + inline BitField( uint64* buffer, const uint64 length ) + : _fields( buffer ) + , _length( length ) + {} + + //----------------------------------------------------------- + inline bool Get( uint64 index ) const + { + ASSERT( index < _length ); + + const uint64 fieldIdx = index >> 6; // Divide by 64. Safe to do with power of 2. (shift right == log2(64)) + const uint64 field = _fields[fieldIdx]; + + const uint32 rShift = (uint32)(index - (fieldIdx << 6)); // Multiply by fieldIdx (shift left == log2(64)) + return (bool)((field >> rShift) & 1u); + } + + //----------------------------------------------------------- + inline void Set( uint64 index ) + { + ASSERT( index < _length ); + + uint64* fields = _fields; + + const uint64 fieldIdx = index >> 6; + const uint64 field = fields[fieldIdx]; + + const uint32 lShift = (uint32)(index - (fieldIdx << 6)); + + fields[fieldIdx] = field | (1ull << lShift); + } + + //----------------------------------------------------------- + inline void SetBit( uint64 index, const uint64 bit ) + { + ASSERT( index < _length ); + + uint64* fields = _fields; + + const uint64 fieldIdx = index >> 6; + const uint64 field = fields[fieldIdx]; + + const uint32 lShift = (uint32)(index - (fieldIdx << 6)); + + fields[fieldIdx] = field | (bit << lShift); + } + + //----------------------------------------------------------- + inline void Clear( uint64 index ) + { + ASSERT( index < _length ); + + uint64* fields = _fields; + + const uint64 fieldIdx = index >> 6; + const uint64 field = fields[fieldIdx]; + + const uint32 lShift = (uint32)(index - (fieldIdx << 6)); + + fields[fieldIdx] = field & (~(1ull << lShift)); + } + + //----------------------------------------------------------- + inline bool operator[] ( uint64 index ) const { return Get( index ); } + inline bool operator[] ( int64 index ) const { return Get( (uint64)index ); } + +#ifndef _WIN32 + //inline bool operator[] ( size_t index ) const { return Get( (uint64)index ); } +#endif + +private: + uint64* _fields; + uint64 _length; +}; diff --git a/src/util/BitView.h b/src/util/BitView.h new file mode 100644 index 00000000..9d0ecdff --- /dev/null +++ b/src/util/BitView.h @@ -0,0 +1,895 @@ +#pragma once +#include "util/Util.h" + +// Chiapos-compatible bitreader +class CPBitReader +{ +public: + + //----------------------------------------------------------- + inline CPBitReader() + : _fields ( nullptr ) + , _sizeBits( 0 ) + , _position( 0 ) + {} + + // Expects bytesBE to be 64-bit fields in BigEndian format. + //----------------------------------------------------------- + inline CPBitReader( const byte* bytesBE, size_t sizeBits, uint64 bitOffset = 0 ) + : _fields ( bytesBE ) + , _sizeBits( sizeBits ) + , _position( bitOffset ) + {} + + //----------------------------------------------------------- + inline void Seek( uint64 position ) + { + ASSERT( position <= _sizeBits ); + _position = position; + } + + //----------------------------------------------------------- + inline uint64 Read64( const uint32 bitCount ) + { + ASSERT( _position + bitCount <= _sizeBits ); + const uint64 value = Read64( bitCount, _fields, _position, _sizeBits ); + _position += bitCount; + return value; + } + + //----------------------------------------------------------- + inline uint128 Read128Aligned( const uint32 bitCount ) + { + const uint128 value = Read128Aligned( bitCount, (uint64*)_fields, _position, _sizeBits ); + _position += bitCount; + return value; + } + + //----------------------------------------------------------- + inline uint64 Read64Aligned( const uint32 bitCount ) + { + ASSERT( _position + bitCount <= _sizeBits ); + const uint64 value = Read64Aligned( bitCount, _fields, _position, _sizeBits ); + _position += bitCount; + return value; + } + + //----------------------------------------------------------- + inline bool Read64Safe( const uint32 bitCount, uint64& outValue ) + { + if( _position + bitCount > _sizeBits || bitCount > 64 ) + return false; + + outValue = Read64( bitCount, _fields, _position, _sizeBits ); + _position += bitCount; + return true; + } + + //----------------------------------------------------------- + static inline uint64 Read64( const uint32 bitCount, const byte* fields, const uint64 position, const size_t sizeBits ) + { + return _Read64( bitCount, fields, position, sizeBits ); + } + + //----------------------------------------------------------- + // Only use if you an guarantee that bytesBE are + // aligned to 8-byte boundaries, and that the last field + // round-up to a uint64, + //----------------------------------------------------------- + static inline uint64 Read64Aligned( const uint32 bitCount, const byte* fields, const uint64 position, const size_t sizeBits ) + { + ASSERT( ((uintptr_t)((uint64*)fields + (position >> 6)) & 7) == 0 ) + return _Read64( bitCount, fields, position, sizeBits ); + } + + // Read 128 bits or less + //----------------------------------------------------------- + inline uint128 Read128Aligned( const uint32 bitCount, const uint64* fields, const uint64 position, const size_t sizeBits ) + { + ASSERT( ((uintptr_t)(fields + (position >> 6)) & 7) == 0 ) + ASSERT( bitCount <= 128 ); + ASSERT( position + bitCount <= sizeBits && position + bitCount > position ); + + const uint64 fieldIndex = _position >> 6; // _position / 64 + const uint32 bitsAvailable = (uint32)( ( (fieldIndex + 1) * 64 ) - _position ); + const uint32 shift = std::max( bitCount, bitsAvailable ) - bitCount; + + uint128 value = Swap64( fields[fieldIndex] ) >> shift; + + if( bitsAvailable < bitCount ) + { + // Have to read one more field + const uint32 bitsNeeded = bitCount - bitsAvailable; + + if( bitsNeeded > 64 ) + { + // Need data from 2 more fields + const uint32 lastFieldBitsNeeded = bitsNeeded - 64; + value = ( value << bitsNeeded ) | ( Swap64( fields[fieldIndex+1] ) << lastFieldBitsNeeded ); + value |= Swap64( fields[fieldIndex+2] ) >> ( 64 - lastFieldBitsNeeded ); + } + else + { + // Only need data from 1 more field + value = ( value << bitsNeeded ) | ( Swap64( fields[fieldIndex+1] ) >> ( 64 - bitsNeeded ) ); + } + } + + // Mask-out part of the fields we don't need + value &= ( ( ( (uint128)0xFFFFFFFFFFFFFFFFull << 64 ) | 0xFFFFFFFFFFFFFFFFull ) >> ( 128 - bitCount ) ); + + _position += bitCount; + return value; + } + +private: + //----------------------------------------------------------- + template + static inline uint64 _Read64( const uint32 bitCount, const byte* fields, const uint64 position, const size_t sizeBits ) + { + const uint64 fieldIndex = position >> 6; // position / 64 + const uint32 fieldBitIdx = (uint32)( position - fieldIndex * 64 ); // Value start bit position from the left (MSb) in the field itself + const uint32 bitsAvailable = 64 - fieldBitIdx; + + uint32 shift = 64 - std::min( fieldBitIdx + bitCount, 64u ); + + const byte* pField = fields + fieldIndex * 8; + + uint64 field; + uint64 value; + + // Check for aligned pointer + bool isPtrAligned; + bool isLastField; + + if constexpr ( CheckAlignment ) + { + isPtrAligned = ((uintptr_t)pField & 7) == 0; // % 8 + isLastField = fieldIndex == ( sizeBits >> 6 ) - 1; + + if( isPtrAligned && !isLastField ) + field = *((uint64*)pField); + else if( !isLastField ) + memcpy( &field, pField, sizeof( uint64 ) ); + else + { + // No guarantee that the last field is complete, so copy only the bytes we know we have + const size_t totalBytes = CDiv( sizeBits, 8 ); + const int32 remainderBytes = (int32)( totalBytes - fieldIndex * 8 ); + + field = 0; + byte* fieldBytes = (byte*)&field; + for( int32 i = 0; i < remainderBytes; i++ ) + fieldBytes[i] = pField[i]; + } + + field = Swap64( field ); + } + else + field = Swap64( *((uint64*)pField) ); + + value = field >> shift; + + // Need to read 1 more field? + if( bitsAvailable < bitCount ) + { + if constexpr ( CheckAlignment ) + { + pField += 8; + + if( isPtrAligned && !isLastField ) + field = *((uint64*)pField); + else if( !isLastField ) + memcpy( &field, pField, sizeof( uint64 ) ); + else + { + const size_t totalBytes = CDiv( sizeBits, 8 ); + const int32 remainderBytes = (int32)( totalBytes - fieldIndex * 8 ); + + field = 0; + byte* fieldBytes = (byte*)&field; + for( int32 i = 0; i < remainderBytes; i++ ) + fieldBytes[i] = pField[i]; + } + + field = Swap64( field ); + } + else + field = Swap64( ((uint64*)pField)[1] ); + + const uint32 remainder = bitCount - bitsAvailable; + shift = 64 - remainder; + + value = ( value << remainder ) | ( field >> shift ); + } + + return value & ( 0xFFFFFFFFFFFFFFFFull >> ( 64 - bitCount ) ); + } + +private: + const byte* _fields ; // Our fields buffer. Expected to be 64-bit field sizes in BigEndian format + size_t _sizeBits; // Size of the how much data we currently have in bits + uint64 _position; // Read poisition in bits +}; + +class BitReader +{ +public: + + //----------------------------------------------------------- + inline BitReader() + : _fields ( nullptr ) + , _sizeBits( 0 ) + , _position( 0 ) + {} + + //----------------------------------------------------------- + inline BitReader( const uint64* bits, size_t sizeBits, uint64 bitOffset = 0 ) + : _fields ( bits ) + , _sizeBits( sizeBits ) + , _position( bitOffset ) + { + // #TODO: Fix plot tool now that we're not initializing BE bytes + + // ASSERT( sizeBits / 64 * 64 == sizeBits ); + // ASSERT( sizeBits <= (size_t)std::numeric_limits::max() ); + + // const size_t fieldCount = sizeBits / 64; + + // for( uint64 i = 0; i < fieldCount; i++ ) + // bytesBE[i] = Swap64( bytesBE[i] ); + + // // Also swap any remainder bytes + // const size_t bitsRemainder = sizeBits - fieldCount * 64; + // if( bitsRemainder ) + // bytesBE[fieldCount] = Swap64( bytesBE[fieldCount] << ( 64 - bitsRemainder ) ); + } + + // Read 64 bits or less + //----------------------------------------------------------- + inline uint64 ReadBits64( const uint32 bitCount ) + { + // ASSERT( _position + bitCount <= _sizeBits ); // #TODO: Enable this + + const auto value = ReadBits64( bitCount, _fields, _position ); + + _position += bitCount; + return value; + } + + // Read 128 bits or less + //----------------------------------------------------------- + inline uint128 ReadBits128( const uint32 bitCount ) + { + ASSERT( 0 ); // #TODO: Update to support changed encoding + ASSERT( bitCount <= 128 ); + ASSERT( _position + bitCount <= _sizeBits ); + + const uint64 fieldIndex = _position >> 6; // _position / 64 + const uint32 bitsAvailable = (uint32)( ( (fieldIndex + 1) * 64 ) - _position ); + const uint32 shift = std::max( bitCount, bitsAvailable ) - bitCount; + + uint128 value = _fields[fieldIndex] >> shift; + + if( bitsAvailable < bitCount ) + { + // Have to read one more field + const uint32 bitsNeeded = bitCount - bitsAvailable; + + if( bitsNeeded > 64 ) + { + // Need data from 2 more fields + const uint32 lastFieldBitsNeeded = bitsNeeded - 64; + value = ( value << bitsNeeded ) | ( _fields[fieldIndex+1] << lastFieldBitsNeeded ); + value |= _fields[fieldIndex+2] >> ( 64 - lastFieldBitsNeeded ); + } + else + { + // Only need data from 1 more field + value = ( value << bitsNeeded ) | ( _fields[fieldIndex+1] >> ( 64 - bitsNeeded ) ); + } + } + + // Mask-out part of the fields we don't need + value &= ( ( ( (uint128)0xFFFFFFFFFFFFFFFFull << 64 ) | 0xFFFFFFFFFFFFFFFFull ) >> ( 128 - bitCount ) ); + + _position += bitCount; + return value; + } + + //----------------------------------------------------------- + inline static uint64 ReadBits64( const uint32 bitCount, const uint64* fields, const uint64 position ) + { + ASSERT( bitCount <= 64 ); + + const uint64 fieldIndex = position >> 6; // position / 64 + const uint32 fieldBits = (uint32)( position - fieldIndex * 64 ); // Bit offset in the field itself + const uint32 bitsAvailable = 64 - fieldBits; + + uint64 value = fields[fieldIndex] >> fieldBits; + + if( bitsAvailable < bitCount ) + { + // Have to read one more field + const uint64 mask = ( 1ull << bitsAvailable ) - 1 ; + value = ( value & mask ) | ( fields[fieldIndex+1] << bitsAvailable ); + } + + // Mask-out part of the value we don't need + return value & ( 0xFFFFFFFFFFFFFFFFull >> (64 - bitCount) ); + } + + // Read in BigEndian mode for compatibility w/ chiapos + //----------------------------------------------------------- + inline static uint64 ReadBits64BE( const uint32 bitCount, const uint64* fields, const uint64 position ) + { + ASSERT( bitCount <= 64 ); + + const uint64 fieldIndex = position >> 6; // position / 64 + const uint32 fieldBits = (uint32)( position - fieldIndex * 64 ); // Bit offset in the field itself + const uint32 bitsAvailable = 64 - fieldBits; + + uint64 value = Swap64( fields[fieldIndex] ) >> fieldBits; + + if( bitsAvailable < bitCount ) + { + // Have to read one more field + const uint64 mask = ( 1ull << bitsAvailable ) - 1 ; + value = ( value & mask ) | ( fields[fieldIndex+1] << bitsAvailable ); + } + + // Mask-out part of the value we don't need + return value & ( 0xFFFFFFFFFFFFFFFFull >> (64 - bitCount) ); + } + + //----------------------------------------------------------- + inline void Bump( uint32 bitCount ) + { + ASSERT( _position + bitCount > _position ); + _position += bitCount; + } + + //----------------------------------------------------------- + inline void Seek( uint64 position ) + { + ASSERT( position <= _sizeBits ); + _position = position; + } + + //----------------------------------------------------------- + inline void SeekRelative( int64 offset ) + { + if( offset < 0 ) + { + const auto subtrahend = (uint64)std::abs( offset ); + ASSERT( subtrahend <= _position ); + + _position -= subtrahend; + } + else + { + Seek( _position + (uint64)offset ); + } + } + +private: + const uint64* _fields ; // Our fields buffer + size_t _sizeBits; // Size of the how much data we currently have in bits + uint64 _position; // Read poisition in bits +}; + + +class BitWriter +{ +public: + + //----------------------------------------------------------- + inline BitWriter( uint64* fields, size_t capacity, uint64 startBitOffset = 0 ) + : _fields ( fields ) + , _capacity( capacity ) + , _position( startBitOffset ) + { + ASSERT( _position <= _capacity ); + } + + //----------------------------------------------------------- + inline BitWriter( const BitWriter& src ) + : _fields ( src._fields ) + , _capacity( src._capacity ) + , _position( src._position ) + {} + + //----------------------------------------------------------- + inline BitWriter( BitWriter&& src ) + : _fields ( src._fields ) + , _capacity( src._capacity ) + , _position( src._position ) + { + src._fields = nullptr; + src._capacity = 0; + src._position = 0; + } + + //----------------------------------------------------------- + inline BitWriter() + : _fields ( nullptr ) + , _capacity( 0 ) + , _position( 0 ) + {} + + //----------------------------------------------------------- + inline BitWriter& operator=( const BitWriter& other ) noexcept + { + this->_fields = other._fields ; + this->_capacity = other._capacity; + this->_position = other._position; + + return *this; + } + + //----------------------------------------------------------- + inline BitWriter& operator=( BitWriter&& other ) noexcept + { + this->_fields = other._fields ; + this->_capacity = other._capacity; + this->_position = other._position; + + other._fields = nullptr; + other._capacity = 0; + other._position = 0; + + return *this; + } + + //----------------------------------------------------------- + inline void Write( const uint64 value, const uint32 bitCount ) + { + ASSERT( _capacity - _position >= bitCount ); + WriteBits64( _fields, _position, value, bitCount ); + _position += bitCount; + } + + //----------------------------------------------------------- + // dstOffset: Offset in bits as to where to start writing in fields + //----------------------------------------------------------- + inline static void WriteBits64( uint64* fields, const uint64 dstOffset, const uint64 value, const uint32 bitCount ) + { + ASSERT( bitCount <= 64 ); + ASSERT( dstOffset + bitCount > dstOffset ); + + const uint64 fieldIndex = dstOffset >> 6; + const uint32 fieldBits = (uint32)( dstOffset - fieldIndex * 64 ); + const uint32 bitsFree = 64 - fieldBits; + + // Determine how many bits to write to this current field + const uint32 bitWrite = bitCount < bitsFree ? bitCount : bitsFree;// std::min( bitCount, bitsFree );// & 63; // Mod 64 + // const uint32 shift = bitWrite & 63; // Mod 64 + + // Clear out our new value region + // uint64 mask = ( ( 1ull << (64 - bitWrite) ) - 1 ) << shift; + uint64 mask = ( 0xFFFFFFFFFFFFFFFFull >> ( 64 - bitWrite ) ) << fieldBits; + + fields[fieldIndex] = ( fields[fieldIndex] & (~mask) ) | ( ( value << fieldBits ) & mask ); + + // If we still have bits to write, then write in the next field + if( bitWrite < bitCount ) + { + const uint32 remainder = bitCount - bitWrite; + mask = 0xFFFFFFFFFFFFFFFFull >> ( 64 - remainder ); + fields[fieldIndex+1] = ( fields[fieldIndex+1] & (~mask) ) | ( ( value >> bitWrite ) & mask ); + } + } + + //----------------------------------------------------------- + inline uint64* Fields() const { return _fields; } + + //----------------------------------------------------------- + inline uint64 Position() const { return _position; } + + //----------------------------------------------------------- + inline uint64 Capacity() const { return _capacity; } + + //----------------------------------------------------------- + inline void Bump( uint64 bitCount ) + { + ASSERT( _position + bitCount >= _position ); + _position += bitCount; + } + + //----------------------------------------------------------- + // Chiapos compatible method. Disabling this here for now since this makes it hard to use in a multi-threaded manner + // dstOffset: Offset in bits as to where to start writing in fields + //----------------------------------------------------------- + inline static void WriteBits64BE( uint64* fields, const uint64 dstOffset, const uint64 value, const uint32 bitCount ) + { + ASSERT( bitCount <= 64 ); + ASSERT( dstOffset + bitCount > dstOffset ); + + const uint64 fieldIndex = dstOffset >> 6; + const uint32 bitsFree = (uint32)( ( ( fieldIndex + 1 ) * 64 ) - dstOffset ); + + // Determine how many bits to write to this current field + const uint32 bitWrite = std::min( bitCount, bitsFree );// & 63; // Mod 64 + const uint32 shift = bitWrite & 63; // Mod 64 + + // Clear out our new value region + // uint64 mask = ( ( 1ull << (64 - bitWrite) ) - 1 ) << shift; + uint64 mask = 0xFFFFFFFFFFFFFFFFull >> ( 64 - bitWrite ); + + fields[fieldIndex] = ( ( fields[fieldIndex] << shift ) & (~mask) ) | ( ( value >> ( bitCount - bitWrite ) & mask ) ); + + // If we still have bits to write, then write in the next field + if( bitWrite < bitCount ) + { + const uint32 remainder = bitCount - shift; + mask = 0xFFFFFFFFFFFFFFFFull >> ( 64 - remainder ); + fields[fieldIndex+1] = value & mask; + } + } + +private: + uint64* _fields ; // Our fields buffer + size_t _capacity; // How many bits can we hold + uint64 _position; // Write poisition in bits +}; + +template +class Bits +{ +public: + //----------------------------------------------------------- + inline Bits() + { + if constexpr ( BitSize > 0 ) + _fields[0] = 0; + } + + //----------------------------------------------------------- + inline Bits( uint64 value, uint32 sizeBits ) + { + static_assert( BitSize > 0, "Attempting to write to a zero-sized Bits." ); + + _fields[0] = 0; + Write( value, sizeBits ); + } + + //----------------------------------------------------------- + inline Bits( const byte* bytesBE, uint32 sizeBits, uint64 bitOffset ) + { + ASSERT( sizeBits <= BitSize ); + + const uint64 startField = bitOffset >> 6; // div 64 + const uint64 endField = ( startField * 64 + sizeBits ) >> 6; // div 64 + const uint64 fieldCount = ( endField - startField ) + 1; + + bytesBE += startField * sizeof( uint64 ); + + // Make the bit offset local to the starting field + bitOffset -= startField * 64; + + _fields[0] = 0; + _length = 0; + + // Write partial initial field + // #TODO: Use the field directly when have 64-bit aligned memory + { + uint64 field; + memcpy( &field, bytesBE, sizeof( uint64 ) ); + field = Swap64( field ); + + const uint32 firstFieldAvail = (uint32)( 64 - bitOffset ); + const uint32 firstFieldBits = std::min( firstFieldAvail, sizeBits ); + const uint64 mask = ( 0xFFFFFFFFFFFFFFFFull >> ( 64 - firstFieldBits ) ); + + field = ( field >> ( firstFieldAvail - firstFieldBits ) & mask ); // Need to mask-out because the field may have offset and less bits than 64 + // so we don't want the high-order bits to make it into the stored field + Write( field, firstFieldBits ); + + bytesBE += sizeof( uint64 ); + } + + // Write any full fields + const int64 fullFieldCount = (uint64)std::max( 0ll, (int64)fieldCount - 2 ); + for( int64 i = 0; i < fullFieldCount; i++ ) + { + uint64 field; + memcpy( &field, bytesBE, sizeof( uint64 ) ); + field = Swap64( field ); + + Write( field, 64 ); + + bytesBE += sizeof( uint64 ); + } + + // Write any partial final field + if( fieldCount > 1 ) + { + const uint32 lastFieldBits = (uint32)( (sizeBits + bitOffset) - (fieldCount-1) * 64 ); + + uint64 field; + memcpy( &field, bytesBE, sizeof( uint64 ) ); + field = Swap64( field ); + field >>= ( 64 - lastFieldBits ); + + _fields[fieldCount-1] = 0; + Write( field, lastFieldBits ); + } + } + + //----------------------------------------------------------- + template + inline Bits( const Bits& src ) + { + static_assert( TBitsSize <= BitSize, "Bit size mismatch." ); + _length = src._length; + memcpy( _fields, src._fields, CDiv( src._length, 8 ) ); + } + + //----------------------------------------------------------- + inline void Clear() + { + _length = 0; + + if constexpr ( BitSize ) + _fields[0] = 0; + } + + //----------------------------------------------------------- + inline void Write( uint64 value, uint32 bitCount ) + { + BitWriter::WriteBits64BE( _fields, _length, value, bitCount ); + _length += bitCount; + } + + //----------------------------------------------------------- + template + inline void Write( const Bits& other ) + { + const size_t inLength = other.Length(); + const uint64* inFields = other.Fields(); + + ASSERT( _length + inLength <= BitSize ); + + const uint64 fieldCount = inLength >> 6; + for( uint64 i = 0; i < fieldCount; i++ ) + Write( inFields[i], 64 ); + + const uint32 remainderBits = (uint32)( inLength - fieldCount * 64 ); + if( remainderBits ) + Write( inFields[fieldCount], remainderBits ); + } + + //----------------------------------------------------------- + inline uint64 ReadUInt64( uint32 bitCount ) + { + ASSERT( bitCount <= BitSize ); + const uint64 value = CPBitReader::Read64( bitCount, _fields, 0 ); + + return value; + } + + //----------------------------------------------------------- + template + inline Bits& operator=( const Bits& r ) const + { + static_assert( TR <= BitSize, "Bit size mismatch." ); + + _length = r._length; + memcpy( _fields, r._fields, CDiv( r._length, 8 ) ); + + return *this; + } + + //----------------------------------------------------------- + template + inline Bits operator+( const Bits& r ) const + { + Bits result( *this ); + result.Write( r ); + + return result; + } + + //----------------------------------------------------------- + template + inline Bits& operator+=( const Bits& r ) + { + this->Write( r ); + return *this;; + } + + //----------------------------------------------------------- + inline void ToBytes( byte* bytes ) + { + const uint64 fieldCount = _length >> 6; + for( uint64 i = 0; i < fieldCount; i++ ) + { + const uint64 field = Swap64( _fields[i] ); + memcpy( bytes, &field, sizeof( field ) ); + bytes += sizeof( field ); + } + + const uint32 remainderBits = (uint32)( _length - fieldCount * 64 ); + if( remainderBits ) + { + const uint64 field = Swap64( _fields[fieldCount] << ( 64 - remainderBits ) ); + const size_t size = CDiv( remainderBits, 8 ); + + memcpy( bytes, &field, size ); + } + } + + // Length in bits + //----------------------------------------------------------- + inline size_t Length() const { return _length; } + + inline size_t LengthBytes() const { return CDiv( _length, 8 ); } + + const uint64* Fields() const { return _fields; } + +private: + uint64 _fields[CDiv( CDiv( BitSize, 8 ), 8)]; + uint64 _length = 0; // In bits +}; +// class BitView +// { +// public: +// //----------------------------------------------------------- +// BitView( uint64* buffer, size_t size, size_t entrySizeBits ) +// : _fields ( buffer ) +// , _size ( size ) +// , _EntrySize( entrySizeBits ) +// { +// ASSERT( buffer ); +// ASSERT( size ); +// ASSERT( entrySizeBits ); + +// // #TODO: Allow entries greater than 64 bits... +// static_assert( entrySizeBits > 0 && entrySizeBits < 65, "_EntrySize must be > 0 < 65" ); +// } + +// // Read an entry of _EntrySize bits at index. +// // Unsafe, this will not check bounds on release mode. +// //----------------------------------------------------------- +// uint64 Get( uint64 index ) +// { + +// } + +// // Write an entry of _EntrySize bits at index. +// // Unsafe, this will not check bounds on release mode. +// //----------------------------------------------------------- +// inline void Set( uint64 index, uint64 value ) +// { + +// } + +// uint64 operator[] ( uint64 index ); + +// private: +// uint64 GetWordIndex( uint64 entryIndex ); + +// private: +// uint64* _fields; +// size_t _EntrySize; // Size of a single entry, in bits +// size_t _size ; // Maximum size as uint64 entries. +// // That is, how many uint64 entries can we hold. +// }; + + +/// +/// Static-typed version of BitView +/// _EntrySize must be in bits. +/// +template +class BitViewT +{ +public: + BitViewT( uint64* buffer, size_t64 size ); + + // Read an entry of _EntrySize bits at index. + // Unsafe, this will not check bounds on release mode. + uint64 Get( uint64 index ); + + // Write an entry of _EntrySize bits at index. + // Unsafe, this will not check bounds on release mode. + void Set( uint64 index, uint64 value ); + + uint64 operator[] ( uint64 index ); + +private: + uint64 GetWordIndex( uint64 entryIndex ); + +private: + uint64* _fields; + size_t64 _size ; // Maximum size as uint64 entries. + // That is, how many uint64 entries can we hold. +}; + +// Bits occupied by the entry size +#define _EntryBits ( ( 1ull << _EntrySize ) -1 ) + +// Bits not occupied by the entry size +#define _InvEntryBits ( ~_EntryBits ) +#define _BitInv( x ) (~(x)) + +//----------------------------------------------------------- +template +inline BitViewT<_EntrySize>::BitViewT( uint64* buffer, size_t64 size ) + : _fields( buffer ) + , _size ( size ) +{ + ASSERT( buffer ); + ASSERT( size ); + + static_assert( _EntrySize > 0 && _EntrySize < 65, "_EntrySize must be > 0 < 65" ); +} + + +//----------------------------------------------------------- +template +inline uint64 BitViewT<_EntrySize>::Get( uint64 index ) +{ + ASSERT( index * _EntrySize + _EntrySize <= _size * 64 ); + + const uint64 wordIdx = GetWordIndex( index ); + + // 64 because our 'word' size is 64-bits/8 bytes + const uint64 bitStart = ( index * _EntrySize ) - ( wordIdx * 64 ); + const uint64 bitCount = 64 - bitStart; // Bits available in the WORD + + uint64 value = _fields[wordIdx] >> bitStart; + + // Need to read next field? + if( bitCount < _EntrySize ) + value |= _fields[wordIdx+1] << bitCount; + + return value & _EntryBits; +} + +//----------------------------------------------------------- +template +inline void BitViewT<_EntrySize>::Set( uint64 index, uint64 value ) +{ + ASSERT( index * _EntrySize + _EntrySize <= _size * 64 ); + + const uint64 wordIdx = GetWordIndex( index ); + + // 64 because our 'word' size is 64-bits/8 bytes + const uint64 bitStart = ( index * _EntrySize ) - ( wordIdx * 64 ); + const uint64 bitCount = 64 - bitStart; // Bits available in the WORD + + // Mask with only the bits of our interest +// value &= _EntryBits; + + // Mask out where the value will placed in the current WORD + uint64 idxValue = _fields[wordIdx] & _BitInv( _EntryBits << bitStart ); + _fields[wordIdx] = idxValue | ( (value & _EntryBits) << bitStart ); + + if( bitCount < _EntrySize ) + { + // Fit it into 2 consecutive WORDs + idxValue = _fields[wordIdx+1] & ( _InvEntryBits >> bitCount ); + _fields[wordIdx+1] = idxValue | ( ( value & _EntryBits ) >> bitCount ); + } +} + +//----------------------------------------------------------- +template +inline uint64 BitViewT<_EntrySize>::operator[]( uint64 index ) +{ + return Get( index ); +} + + +//----------------------------------------------------------- +template +inline uint64 BitViewT<_EntrySize>::GetWordIndex( uint64 entryIndex ) +{ + // 64 because our 'word' size is 64-bits/8 bytes + return (entryIndex * _EntrySize) / 64; +} + +#undef _EntryBits +#undef _InvEntryBits +#undef _BitInv diff --git a/src/util/CliParser.h b/src/util/CliParser.h new file mode 100644 index 00000000..8a87de7f --- /dev/null +++ b/src/util/CliParser.h @@ -0,0 +1,354 @@ +#pragma once +#include +#include "util/Util.h" +#include "util/KeyTools.h" + +class CliParser +{ +public: + //----------------------------------------------------------- + inline CliParser( int argc, const char* argv[] ) + : _i ( 0 ) + , _argc( argc ) + , _argv( argv ) + {} + + //----------------------------------------------------------- + [[nodiscard]] + inline bool HasArgs() const + { + return _i < _argc; + } + + //----------------------------------------------------------- + [[nodiscard]] + inline bool IsLastArg() const + { + return _i == _argc - 1; + } + + //----------------------------------------------------------- + inline const char* Arg() + { + FatalIf( !HasArgs(), "Expected an argument." ); + return _argv[_i]; + } + + //----------------------------------------------------------- + inline bool ArgMatch( const char* paramA, const char* paramB = nullptr ) + { + const char* arg = Arg(); + return strcmp( paramA, arg ) == 0 || + ( paramB && strcmp( paramB, arg ) == 0 ); + } + + //----------------------------------------------------------- + inline bool ArgConsume( const char* paramA, const char* paramB = nullptr ) + { + if( ArgMatch( paramA, paramB ) ) + { + NextArg(); + return true; + } + + return false; + } + + //----------------------------------------------------------- + inline const char* ArgConsume() + { + const char* arg = Arg(); + NextArg(); + + return arg; + } + + //----------------------------------------------------------- + inline bool ReadSwitch( bool& value, const char* paramA, const char* paramB = nullptr ) + { + if( ArgMatch( paramA, paramB ) ) + { + NextArg(); + value = true; + return true; + } + + return false; + } + + //----------------------------------------------------------- + inline bool ReadStr( const char*& value, const char* paramA, const char* paramB = nullptr ) + { + if( !ArgMatch( paramA, paramB ) ) + return false; + + NextArg(); + FatalIf( !HasArgs(), "Expected a value for argument '%s'.", _argv[_i-1] ); + + value = _argv[_i]; + NextArg(); + + return true; + } + + //----------------------------------------------------------- + inline uint64 ReadU64() + { + const char* strValue = Arg(); + NextArg(); + + uint64 value; + int r = sscanf( strValue, "%llu",(llu*)&value ); + FatalIf( r != 1, "Expected an uint64 value at parameter %d.", _i ); + + return value; + } + + //----------------------------------------------------------- + inline bool ReadU64( uint64& value, const char* paramA, const char* paramB = nullptr ) + { + const char* strValue = nullptr; + if( !ReadStr( strValue, paramA, paramB ) ) + return false; + + const char* arg = _argv[_i-2]; + int r = sscanf( strValue, "%llu", (llu*)&value ); + FatalIf( r != 1, "Invalid uint64 value for argument '%s'.", arg ); + + return true; + } + + //----------------------------------------------------------- + inline bool ReadI64( int64& value, const char* paramA, const char* paramB = nullptr ) + { + const char* strValue = nullptr; + if( !ReadStr( strValue, paramA, paramB ) ) + return false; + + const char* arg = _argv[_i-2]; + int r = sscanf( strValue, "%lld", &value ); + FatalIf( r != 1, "Invalid int64 value for argument '%s'.", arg ); + + return true; + } + + //----------------------------------------------------------- + inline bool ReadU32( uint32& value, const char* paramA, const char* paramB = nullptr ) + { + uint64 u64Value = 0; + if( !ReadU64( u64Value, paramA, paramB ) ) + return false; + + value = (uint32)u64Value; + const char* arg = _argv[_i-2]; + FatalIf( value != u64Value, "Invalid uint32 value for argument '%s'.", arg ); + + return true; + } + + //----------------------------------------------------------- + inline bool ReadI32( int32& value, const char* paramA, const char* paramB = nullptr ) + { + int64 i64Value = 0; + if( !ReadI64( i64Value, paramA, paramB ) ) + return false; + + value = (int32)i64Value; + const char* arg = _argv[_i-2]; + FatalIf( value != i64Value, "Invalid int32 value for argument '%s'.", arg ); + + return true; + } + + //----------------------------------------------------------- + inline bool ReadF64( float64& value, const char* paramA, const char* paramB = nullptr ) + { + const char* strValue = nullptr; + if( !ReadStr( strValue, paramA, paramB ) ) + return false; + + const char* arg = _argv[_i-2]; + int r = sscanf( strValue, "%lf", &value ); + FatalIf( r != 1, "Invalid float64 value for argument '%s'.", arg ); + + return true; + } + + //----------------------------------------------------------- + inline bool ReadF32( float32& value, const char* paramA, const char* paramB = nullptr ) + { + const char* strValue = nullptr; + if( !ReadStr( strValue, paramA, paramB ) ) + return false; + + const char* arg = _argv[_i-2]; + int r = sscanf( strValue, "%f", &value ); + FatalIf( r != 1, "Invalid float32 value for argument '%s'.", arg ); + + return true; + } + + //----------------------------------------------------------- + inline bool ReadPKey( bls::G1Element* value, const char* paramA, const char* paramB = nullptr ) + { + const char* strValue = nullptr; + if( !ReadStr( strValue, paramA, paramB ) ) + return false; + + value = new bls::G1Element(); + if( !KeyTools::HexPKeyToG1Element( strValue, *value ) ) + { + const char* arg = _argv[_i-2]; + Fatal( "Invalid public key value for argument '%s'.", arg ); + } + + return true; + } + + //----------------------------------------------------------- + inline bool ReadPKey( bls::G1Element& value, const char* paramA, const char* paramB = nullptr ) + { + const char* strValue = nullptr; + if( !ReadStr( strValue, paramA, paramB ) ) + return false; + + if( !KeyTools::HexPKeyToG1Element( strValue, value ) ) + { + const char* arg = _argv[_i-2]; + Fatal( "Invalid public key value for argument '%s'.", arg ); + } + + return true; + } + + //----------------------------------------------------------- + inline bool ReadPuzzleHash( PuzzleHash* value, const char* paramA, const char* paramB = nullptr ) + { + const char* strValue = nullptr; + if( !ReadStr( strValue, paramA, paramB ) ) + return false; + + auto* ph = new PuzzleHash(); + if( !PuzzleHash::FromAddress( *ph, strValue ) ) + { + const char* arg = _argv[_i-2]; + Fatal( "Invalid puzzle hash value '%s' for argument '%s'.", strValue, arg ); + } + + return true; + } + + //----------------------------------------------------------- + inline bool ReadSize( size_t& value, const char* paramA, const char* paramB = nullptr ) + { + const char* sizeText = nullptr; + if( !ReadStr( sizeText, paramA, paramB ) ) + return false; + + const char* arg = _argv[_i-2]; + return ReadSize( sizeText, value, arg ); + } + + //----------------------------------------------------------- + inline bool ReadSize( const char* sizeText, size_t& size, const char* arg = "" ) + { + ASSERT( sizeText ); + size = 0; + + const size_t len = strlen( sizeText ); + const char* end = sizeText + len; + + const char* suffix = sizeText; + + #ifdef _WIN32 + #define StriCmp _stricmp + #else + #define StriCmp strcasecmp + #endif + + // Try to find a suffix: + // Find the first character that's not a digit + do + { + const char c = *suffix; + if( c < '0' || c > '9' ) + break; + } + while( ++suffix < end ); + + // Apply multiplier depending on the suffix + size_t multiplier = 1; + + const size_t suffixLength = end - suffix; + if( suffixLength > 0 ) + { + if( StriCmp( "GB", suffix ) == 0 || StriCmp( "G", suffix ) == 0 ) + multiplier = 1ull GB; + else if( StriCmp( "MB", suffix ) == 0 || StriCmp( "M", suffix ) == 0 ) + multiplier = 1ull MB; + else if( StriCmp( "KB", suffix ) == 0 || StriCmp( "K", suffix ) == 0 ) + multiplier = 1ull KB; + else + { + Fatal( "Invalid suffix '%s' for argument '%s'", suffix, arg ); + } + } + + size_t parsedSize = 0; + + const size_t MAX_DIGITS = 19; + char digits[MAX_DIGITS + 1]; + + const size_t digitsLength = suffix - sizeText; + FatalIf( digitsLength < 1 || digitsLength > MAX_DIGITS, "Invalid parameters value for argument '%s'.", arg ); + + // Read digits + memcpy( digits, sizeText, digitsLength ); + digits[digitsLength] = 0; + + FatalIf( sscanf( digits, "%llu", (llu*)&parsedSize ) != 1, + "Invalid parameters value for argument '%s'.", arg ); + + size = parsedSize * multiplier; + + // Check for overflow + FatalIf( size < size, "Size overflowed for argument '%s'.", arg ); + + return true; + #undef StriCmp + } + + //----------------------------------------------------------- + inline size_t ReadSize( const char* arg ) + { + size_t size; + FatalIf( !ReadSize( Arg(), size, arg ), + "Expected a size argument for paramter '%s'", arg ); + + NextArg(); + return size; + } + + //----------------------------------------------------------- + inline size_t ReadSize() + { + size_t size; + FatalIf( !ReadSize( Arg(), size, "" ), + "Expected a size argument at index %d", _i ); + + NextArg(); + return size; + } + + //----------------------------------------------------------- + inline void NextArg() + { + _i++; + } + +private: + int _i; + int _argc; + const char** _argv; +}; + diff --git a/src/util/KeyTools.cpp b/src/util/KeyTools.cpp new file mode 100644 index 00000000..ea0037fc --- /dev/null +++ b/src/util/KeyTools.cpp @@ -0,0 +1,107 @@ +#include "KeyTools.h" +#include "util/Util.h" +#include "util/Log.h" + + + +//----------------------------------------------------------- +bool KeyTools::HexPKeyToG1Element( const char* hexKey, bls::G1Element& pkey ) +{ + ASSERT( hexKey ); + + size_t length = strlen( hexKey ); + + if( length < bls::G1Element::SIZE*2 ) + return false; + + if( hexKey[0] == '0' && hexKey[1] == 'x' ) + { + hexKey += 2; + length -= 2; + } + + if( length != bls::G1Element::SIZE*2 ) + return false; + + byte g1Buffer[bls::G1Element::SIZE]; + HexStrToBytes( hexKey, length, g1Buffer, sizeof( g1Buffer ) ); + + bls::Bytes g1Bytes( g1Buffer, sizeof( g1Buffer ) ); + + pkey = bls::G1Element::FromBytes( g1Bytes ); + + return pkey.IsValid(); +} + +//----------------------------------------------------------- +bls::PrivateKey KeyTools::MasterSkToLocalSK( bls::PrivateKey& sk ) +{ + // #SEE: chia-blockchain: derive-keys.py + // EIP 2334 bls key derivation + // https://eips.ethereum.org/EIPS/eip-2334 + // 12381 = bls spec number + // 8444 = Chia blockchain number and port number + // 0, 1, 2, 3, 4, 5, 6 farmer, pool, wallet, local, backup key, singleton, pooling authentication key numbers + + const uint32 blsSpecNum = 12381; + const uint32 chiaBlockchainPort = 8444; + const uint32 localIdx = 3; + + bls::PrivateKey ssk = bls::AugSchemeMPL().DeriveChildSk( sk, blsSpecNum ); + ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, chiaBlockchainPort ); + ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, localIdx ); + ssk = bls::AugSchemeMPL().DeriveChildSk( ssk, 0 ); + + return ssk; +} + +//----------------------------------------------------------- +void KeyTools::PrintPK( const bls::G1Element& key ) +{ + std::vector bytes = key.Serialize(); + Log::Line( "%s", HexToString( (byte*)bytes.data(), bytes.size() ).c_str() ); +} + +//----------------------------------------------------------- +void KeyTools::PrintSK( const bls::PrivateKey& key ) +{ + std::vector bytes = key.Serialize(); + Log::Line( "%s", HexToString( (byte*)bytes.data(), bytes.size() ).c_str() ); +} + + +/// +/// PuzzleHash +/// +//----------------------------------------------------------- +bool PuzzleHash::FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_LENGTH+1] ) +{ + ASSERT( address ); + if( !address ) + return false; + + if( strlen( address ) != CHIA_ADDRESS_LENGTH ) + return false; + + char hrp [CHIA_ADDRESS_LENGTH-5] = { 0 }; + byte data[CHIA_ADDRESS_LENGTH-8]; + + size_t dataLen = 0; + if( bech32_decode( hrp, data, &dataLen, address ) != BECH32_ENCODING_BECH32M ) + return false; + + if( memcmp( "xch", hrp, sizeof( "xch" ) ) != 0 ) + return false; + + byte decoded[40]; + size_t decodedSize = 0; + if( !bech32_convert_bits( decoded, &decodedSize, 8, data, dataLen, 5, 0 ) ) + return false; + + if( decodedSize != CHIA_PUZZLE_HASH_SIZE ) + return false; + + memcpy( hash.data, decoded, CHIA_PUZZLE_HASH_SIZE ); + return true; +} + diff --git a/src/util/KeyTools.h b/src/util/KeyTools.h new file mode 100644 index 00000000..3c43b751 --- /dev/null +++ b/src/util/KeyTools.h @@ -0,0 +1,51 @@ +#pragma once + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type" + +#pragma warning( push ) + +extern "C" { + #include "bech32/segwit_addr.h" +} + +#pragma GCC diagnostic ignored "-Wsign-compare" +#pragma warning( disable : 6287 ) +#pragma warning( disable : 4267 ) +#pragma warning( disable : 26495 ) +#include "bls.hpp" +#include "elements.hpp" +#include "schemes.hpp" +#include "util.hpp" +#pragma GCC diagnostic pop +#pragma warning( pop ) + + +#define CHIA_PUZZLE_HASH_SIZE 32 +#define CHIA_ADDRESS_LENGTH 62 // 3 (hrp) + 1 (divisor) + 52 (data) + 6 (checksum) + +struct XchAddress : NBytes +{}; + +struct PuzzleHash : NBytes +{ + static bool FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_LENGTH+1] ); + + void ToAddress( char address[CHIA_ADDRESS_LENGTH+1] ); + std::string ToAddressString(); + + void ToHex( char hex[CHIA_PUZZLE_HASH_SIZE+1] ) const; + std::string ToHex() const; +}; + +class KeyTools +{ +public: + static bool HexPKeyToG1Element( const char* hexKey, bls::G1Element& pkey ); + + static bls::PrivateKey MasterSkToLocalSK( bls::PrivateKey& sk ); + + static void PrintPK( const bls::G1Element& key ); + static void PrintSK( const bls::PrivateKey& key ); +}; + diff --git a/src/util/Log.cpp b/src/util/Log.cpp index ad4741dc..699180c7 100644 --- a/src/util/Log.cpp +++ b/src/util/Log.cpp @@ -1,157 +1,228 @@ -#include "Log.h" - - -FILE* Log::_outStream = nullptr; -FILE* Log::_errStream = nullptr; - -bool Log::_verbose = false; - -//----------------------------------------------------------- -inline FILE* Log::GetOutStream() -{ - if( _outStream == nullptr ) - { - _outStream = stdout; - setvbuf( stdout, NULL, _IONBF, 0 ); - } - - return _outStream; -} - -//----------------------------------------------------------- -inline FILE* Log::GetErrStream() -{ - if( _errStream == nullptr ) - { - _errStream = stderr; - setvbuf( stderr, NULL, _IONBF, 0 ); - } - - return _errStream; -} - -//----------------------------------------------------------- -void Log::Write( const char* msg, ... ) -{ - va_list args; - va_start( args, msg ); - - Write( msg, args ); - - va_end( args ); -} - -//----------------------------------------------------------- -void Log::WriteLine( const char* msg, ... ) -{ - va_list args; - va_start( args, msg ); - - WriteLine( msg, args ); - - va_end( args ); -} - -//----------------------------------------------------------- -void Log::Line( const char* msg, ... ) -{ - va_list args; - va_start( args, msg ); - - WriteLine( msg, args ); - - va_end( args ); -} - -//----------------------------------------------------------- -void Log::Write( const char* msg, va_list args ) -{ - vfprintf( GetOutStream(), msg, args ); -} - -//----------------------------------------------------------- -void Log::WriteLine( const char* msg, va_list args ) -{ - FILE* stream = GetOutStream(); - vfprintf( stream, msg, args ); - fputc( '\n', stream ); -} - -//----------------------------------------------------------- -void Log::Error( const char* msg, ... ) -{ - va_list args; - va_start( args, msg ); - - Error( msg, args ); - - va_end( args ); -} - -//----------------------------------------------------------- -void Log::WriteError( const char* msg, ... ) -{ - va_list args; - va_start( args, msg ); - - WriteError( msg, args ); - - va_end( args ); -} - -//----------------------------------------------------------- -void Log::Error( const char* msg, va_list args ) -{ - WriteError( msg, args ); - fputc( '\n', GetErrStream() ); -} - -//----------------------------------------------------------- -void Log::WriteError( const char* msg, va_list args ) -{ - vfprintf( GetErrStream(), msg, args ); -} - -//----------------------------------------------------------- -void Log::Verbose( const char* msg, ... ) -{ - if( !_verbose ) - return; - - va_list args; - va_start( args, msg ); - - FILE* stream = GetErrStream(); - vfprintf( stream, msg, args ); - fputc( '\n', stream ); - - va_end( args ); -} - -//----------------------------------------------------------- -void Log::VerboseWrite( const char* msg, ... ) -{ - if( !_verbose ) - return; - - va_list args; - va_start( args, msg ); - - vfprintf( GetErrStream(), msg, args ); - - va_end( args ); -} - - -//----------------------------------------------------------- -void Log::Flush() -{ - fflush( GetOutStream() ); -} - - -//----------------------------------------------------------- -void Log::FlushError() -{ - fflush( GetErrStream() ); -} +#include "Log.h" + +#if _DEBUG && defined( _WIN32 ) + #include + #include +#endif + +FILE* Log::_outStream = nullptr; +FILE* Log::_errStream = nullptr; + +bool Log::_verbose = false; + +// #if DBG_LOG_ENABLE + std::atomic _dbglock = 0; +// #endif + +//----------------------------------------------------------- +inline FILE* Log::GetOutStream() +{ + if( _outStream == nullptr ) + { + _outStream = stdout; + setvbuf( stdout, NULL, _IONBF, 0 ); + } + + return _outStream; +} + +//----------------------------------------------------------- +inline FILE* Log::GetErrStream() +{ + if( _errStream == nullptr ) + { + _errStream = stderr; + setvbuf( stderr, NULL, _IONBF, 0 ); + } + + return _errStream; +} + +//----------------------------------------------------------- +void Log::Write( const char* msg, ... ) +{ + va_list args; + va_start( args, msg ); + + Write( msg, args ); + + va_end( args ); +} + +//----------------------------------------------------------- +void Log::WriteLine( const char* msg, ... ) +{ + va_list args; + va_start( args, msg ); + + WriteLine( msg, args ); + + va_end( args ); +} + +//----------------------------------------------------------- +void Log::Line( const char* msg, ... ) +{ + va_list args; + va_start( args, msg ); + + WriteLine( msg, args ); + + va_end( args ); +} + +//----------------------------------------------------------- +void Log::Write( const char* msg, va_list args ) +{ + vfprintf( GetOutStream(), msg, args ); + +#if _DEBUG && defined( _WIN32 ) + //::OutputDebugStringA( (LPCSTR)msg ); +#endif +} + +//----------------------------------------------------------- +void Log::WriteLine( const char* msg, va_list args ) +{ + FILE* stream = GetOutStream(); + vfprintf( stream, msg, args ); + fputc( '\n', stream ); +} + +//----------------------------------------------------------- +void Log::Error( const char* msg, ... ) +{ + va_list args; + va_start( args, msg ); + + Error( msg, args ); + + va_end( args ); +} + +//----------------------------------------------------------- +void Log::WriteError( const char* msg, ... ) +{ + va_list args; + va_start( args, msg ); + + WriteError( msg, args ); + + va_end( args ); +} + +//----------------------------------------------------------- +void Log::Error( const char* msg, va_list args ) +{ + WriteError( msg, args ); + fputc( '\n', GetErrStream() ); +} + +//----------------------------------------------------------- +void Log::WriteError( const char* msg, va_list args ) +{ + vfprintf( GetErrStream(), msg, args ); + +#if _DEBUG && defined( _WIN32 ) + //::OutputDebugStringA( (LPCSTR)msg ); +#endif +} + +//----------------------------------------------------------- +void Log::Verbose( const char* msg, ... ) +{ + if( !_verbose ) + return; + + va_list args; + va_start( args, msg ); + + FILE* stream = GetErrStream(); + vfprintf( stream, msg, args ); + fputc( '\n', stream ); + + va_end( args ); +} + +//----------------------------------------------------------- +void Log::VerboseWrite( const char* msg, ... ) +{ + if( !_verbose ) + return; + + va_list args; + va_start( args, msg ); + + vfprintf( GetErrStream(), msg, args ); + + va_end( args ); +} + + +//----------------------------------------------------------- +void Log::Flush() +{ + fflush( GetOutStream() ); +} + + +//----------------------------------------------------------- +void Log::FlushError() +{ + fflush( GetErrStream() ); +} + + +#if DBG_LOG_ENABLE + +//----------------------------------------------------------- +void Log::Debug( const char* msg, ... ) +{ + va_list args; + va_start( args, msg ); + + DebugV( msg, args ); + + va_end( args ); +} + + +//----------------------------------------------------------- +void Log::DebugV( const char* msg, va_list args ) +{ + const size_t BUF_SIZE = 1024; + char buffer[BUF_SIZE]; + + int count = vsnprintf( buffer, BUF_SIZE, msg, args ); + + ASSERT( count >= 0 ); + count = std::min( count, (int)BUF_SIZE-1 ); + + buffer[count] = '\n'; + + DebugWrite( buffer, (size_t)count + 1 ); +} + +//----------------------------------------------------------- +void Log::DebugWrite( const char* msg, size_t size ) +{ + SafeWrite( msg, size ); +} + +#endif + +//----------------------------------------------------------- +void Log::SafeWrite( const char* msg, size_t size ) +{ + // #TODO: Just use a futex + // Lock + int lock = 0; + while( !_dbglock.compare_exchange_weak( lock, 1 ) ) + lock = 0; + + fwrite( msg, 1, size, stderr ); + fflush( stderr ); + + // Unlock + _dbglock.store( 0, std::memory_order_release ); +} \ No newline at end of file diff --git a/src/util/Log.h b/src/util/Log.h index 24572468..849cef61 100644 --- a/src/util/Log.h +++ b/src/util/Log.h @@ -1,35 +1,48 @@ -#pragma once - -class Log -{ - static bool _verbose; - -public: - static void Write( const char* msg, ... ); - static void WriteLine( const char* msg, ... ); - static void Line( const char* msg, ... ); - - static void Write( const char* msg, va_list args ); - static void WriteLine( const char* msg, va_list args ); - - static void Error( const char* msg, ... ); - static void WriteError( const char* msg, ... ); - static void Error( const char* msg, va_list args ); - static void WriteError( const char* msg, va_list args ); - - inline static void SetVerbose( bool enabled ) { _verbose = enabled; } - - static void Verbose( const char* msg, ... ); - static void VerboseWrite( const char* msg, ... ); - - static void Flush(); - static void FlushError(); -private: - - static FILE* GetOutStream(); - static FILE* GetErrStream(); - -private: - static FILE* _outStream; - static FILE* _errStream; +#pragma once + +class Log +{ + static bool _verbose; + +public: + static void Write( const char* msg, ... ); + static void WriteLine( const char* msg, ... ); + static void Line( const char* msg, ... ); + + static void Write( const char* msg, va_list args ); + static void WriteLine( const char* msg, va_list args ); + + static void Error( const char* msg, ... ); + static void WriteError( const char* msg, ... ); + static void Error( const char* msg, va_list args ); + static void WriteError( const char* msg, va_list args ); + + inline static void SetVerbose( bool enabled ) { _verbose = enabled; } + + static void Verbose( const char* msg, ... ); + static void VerboseWrite( const char* msg, ... ); + + static void Flush(); + static void FlushError(); + +#if DBG_LOG_ENABLE + static void Debug( const char* msg, ... ); + static void DebugV( const char* msg, va_list args ); + static void DebugWrite( const char* msg, size_t size ); +#else + static inline void Debug( const char* msg, ... ) {} + static void DebugV( const char* msg, va_list args ) {} + static void DebugWrite( const char* msg, size_t size ) {} +#endif + + static void SafeWrite( const char* msg, size_t size ); + +private: + + static FILE* GetOutStream(); + static FILE* GetErrStream(); + +private: + static FILE* _outStream; + static FILE* _errStream; }; \ No newline at end of file diff --git a/src/util/SPCQueue.h b/src/util/SPCQueue.h new file mode 100644 index 00000000..994dd7d6 --- /dev/null +++ b/src/util/SPCQueue.h @@ -0,0 +1,128 @@ +#pragma once +#include "threading/AutoResetSignal.h" +#include "util/Util.h" + +class SPCQueueIterator +{ + template + friend class SPCQueue; + + int _iteration; // One of potentially 2. + int _endIndex[2]; + + bool HasValues() const; + void Next(); +}; + +// Statically Fixed-Size Single Producer-Consumer Queue +template +class SPCQueue +{ +public: + SPCQueue(); + ~SPCQueue(); + + + // Adds a pending value to the queue and returns it for the user to write, + // but it does not commit it yet (makes it visible for reading). + // This allows you to enqueue multiple commands before committing/publishing them. + // Call Commit() after a successful call to Write(). + // If this call does not return true, do NOTE call Commit(). + bool Write( T*& outValue ); + + // Publish pending commands to be visible for reading. + void Commit(); + + // Does Write() and Commit() in a single call. + // Returns false if there's currently no space available in the queue. + bool Enqueue( const T& value ); + + int Dequeue( T* values, int capacity ); + + int Count() const; + +private: + int _writePosition = 0; // Current write position in our buffer. + int _pendingCount = 0; // Entries pending to be committed. + std::atomic _committedCount = 0; // Current number of committed entries + int _readPosition = 0; + T _buffer[Capacity]; +}; + + +// Dynamically-Sized Single Producer-Consumer Queue +template +class GrowableSPCQueue +{ +public: + + explicit GrowableSPCQueue(size_t capacity ); + GrowableSPCQueue(); + ~GrowableSPCQueue(); + + // Grab an entry from the heap buffer to encode + // the item into the queue, but not commit it for consumption yet. + // Use Commit() to publish the uncommitted (written) commands presently in the queue. + bool Write( T*& outValue ); + + // Publish pending commands to be visible for reading. + void Commit(); + + // Does Write() and Commit() in a single call. + bool Enqueue( const T& value ); + + int Dequeue( T* values, int capacity ); + + // Returns the amount of entries currently comitted for dequeuing. + // The value returned here may or may not be accurate + // as a thread may have enqueued or dequeued entries immediately + // before/after the comitted counts are retrieved. + // This should only be called from the consumer or the producer thread. + // Calling it from any other thread is underfined behavior. + // #TODO: Not sure if we can actually implement this in a safe manner, + // even from the consumer or producer thread. + // inline int64 Count() const + // { + // int64 producerCount = _producerState->committedCount.load( std::memory_order_relaxed ); + + // const auto* oldState = _newState.load( std::memory_order_relaxed ); + // if( oldState ) + // producerCount += oldState->committedCount.load( std::memory_order_relaxed ); + + // return producerCount; + // } + +private: + + struct ConsumerState + { + T* buffer; // Element buffer + int capacity; // Buffer capacity + std::atomic committedCount; // How many elements are ready to be read + }; + + +private: + + // Producer + int _writePosition = 0; // Current write position in our buffer. + int _pendingCount = 0; // Elements not yet committed (published) to the consumer thread + int _oldPendingCount = 0; // Pending count before we resized the buffer and switched to a new state + ConsumerState* _producerState; + ConsumerState _states[2]; + int _nextState = 1; + bool _pendingState = false; // Avoid atomic _newState check during Commit() + + // Shared + std::atomic _newState = nullptr; + + // Consumer + ConsumerState* _consumerState; + int _readPosition = 0; +}; + + +#include "SPCQueue.inl" + + + diff --git a/src/util/SPCQueue.inl b/src/util/SPCQueue.inl new file mode 100644 index 00000000..0cd0bce4 --- /dev/null +++ b/src/util/SPCQueue.inl @@ -0,0 +1,357 @@ +#pragma once +#include "util/Log.h" +#include "util/Util.h" + + +//----------------------------------------------------------- +template +SPCQueue::SPCQueue() +{} + +//----------------------------------------------------------- +template +SPCQueue::~SPCQueue() +{} + +//----------------------------------------------------------- +template +int SPCQueue::Count() const +{ + return _committedCount.load( std::memory_order_relaxed ); +} + +//----------------------------------------------------------- +template +bool SPCQueue::Enqueue( const T& value ) +{ + T* entry; + if( Write( entry ) ) + { + *entry = value; + Commit(); + return true; + } + + return false; +} + +//----------------------------------------------------------- +template +bool SPCQueue::Write( T*& outValue ) +{ + int count = _pendingCount + _committedCount.load( std::memory_order_acquire ); + ASSERT( count <= Capacity ); + + if( count < Capacity ) + { + outValue = &_buffer[_writePosition]; + + ++_writePosition %= Capacity; + _pendingCount++; + + return true; + } + + return false; +} + +//----------------------------------------------------------- +template +void SPCQueue::Commit() +{ + //ASSERT( _pendingCount ); + if( _pendingCount < 1 ) + return; + + + int commited = _committedCount.load( std::memory_order_acquire ); + ASSERT( commited < Capacity ); + + // Publish entries to the consumer thread + while( !_committedCount.compare_exchange_weak( commited, commited + _pendingCount, + std::memory_order_release, + std::memory_order_relaxed ) ); + + _pendingCount = 0; +} + +//----------------------------------------------------------- +template +int SPCQueue::Dequeue( T* values, int capacity ) +{ + ASSERT( values ); + ASSERT( capacity > 0 ); + + int curCount = _committedCount.load( std::memory_order_acquire ); + int count = std::min( capacity, curCount ); + + if( count < 1 ) + return 0; + + const int readPos = _readPosition; + _readPosition = ( readPos + count ) % Capacity; + + const int copyCount = std::min( count, Capacity - readPos ); + bbmemcpy_t( values, _buffer + readPos, (size_t)copyCount ); + + // We might have to do 2 copies if we're wrapping around the end of the buffer + const int remainder = count - copyCount; + if( remainder > 0 ) + { + #if _DEBUG + Log::Debug( "[0x%p] Wrap", this ); + #endif + bbmemcpy_t( values + copyCount, _buffer, (size_t)remainder ); + } + + // Publish to the producer thread that we've consumed entries + while( !_committedCount.compare_exchange_weak( curCount, curCount - count, + std::memory_order_release, + std::memory_order_relaxed ) ); + + return count; +} + + + + +/// +/// Dynamic +/// + +//----------------------------------------------------------- +template +GrowableSPCQueue::GrowableSPCQueue(size_t capacity ) + : _producerState( _states ) + , _consumerState( _states ) +{ + FatalIf( capacity > (size_t)std::numeric_limits::max(), + "GrowableSPCQueue capacity cannot exceed %d.", + std::numeric_limits::max() ); + + memset( _states, 0, sizeof( _states ) ); + + if( capacity > 0 ) + { + _producerState->buffer = bbcalloc( capacity ); + } + + _producerState->capacity = (int)capacity; +} + +//----------------------------------------------------------- +template +GrowableSPCQueue::GrowableSPCQueue() + : GrowableSPCQueue(0 ) +{} + +//----------------------------------------------------------- +template +GrowableSPCQueue::~GrowableSPCQueue() +{ + if( _producerState->buffer ) + free( _producerState->buffer ); + + if( _consumerState->buffer != _producerState->buffer ) + free( _consumerState->buffer ); +} + +//----------------------------------------------------------- +template +bool GrowableSPCQueue::Write(T*& outValue ) +{ + const int count = _pendingCount + _producerState->committedCount.load( std::memory_order_acquire ); + ASSERT( count <= _producerState->capacity ); + + if( count < _producerState->capacity ) + { + outValue = &_producerState->buffer[_writePosition]; + + ++_writePosition %= _producerState->capacity; + _pendingCount++; + + return true; + } + + // We ran out of buffer space, we'll have to create a new one, + // adding a signal to the consumer thread to discard the current buffer + // and use the new one once it has finished reading from it. + + if( _growSize == 0 ) + return false; + + // We only support double-buffering, that is one temporary buffer being + // used by the consumer thread while it switches to the new one, so if + // the consumer is still using an old buffer, we cannot allocate a new one. + ConsumerState* newState = _newState.load( std::memory_order_acquire ); + if( newState != nullptr ) + { + // #NOTE: Although we could technically still resize in this case if we manage to + // swap with null and acquire the _newState, we ought not to because it + // can cause deadlocks. The reason being that the consumer thread might be + // accompanied by a signal mechanism whenever the producer writes to the queue. + // In the case where the producer acquires the new state and swaps it for null + // during this resize step, and the consumer is signalled at the same time, + // the consumer thread may find no elements to consume with the consumer state. + // Which could be unexpected behavior for the user if they had signalled after committing. + return false; + } + + const size_t currentCapacity = _producerState->capacity; + + size_t newCapacity = currentCapacity + _growSize; + + const size_t MAX_CAPACITY = std::numeric_limits::max(); + + // Overflowed? + if( newCapacity < currentCapacity ) + newCapacity = MAX_CAPACITY; + + // Were we already maxed-out? + if( newCapacity == currentCapacity ) + return false; + + // Re-allocate + T* newBuffer = bbcalloc( newCapacity ); + + // Set our new state + _producerState = _states + _nextState; + _nextState = (++_nextState) % 2; + + _producerState->buffer = newBuffer; + _producerState->capacity = (int)newCapacity; + _producerState->committedCount = 0; + + _oldPendingCount = _pendingCount; + _pendingCount = 0; + + // The new state will not be published to the consumer thread until + // the next commit call. This is because we may have pending + // elements still not committed. If we change the state now, those + // elements may end up as being pending in the new state, which is false. + _pendingState = true; + + // Actually grab the new entry buffer now + return Write( outValue ); +} + +//----------------------------------------------------------- +template +void GrowableSPCQueue::Commit() +{ + if( _pendingCount < 1 && _oldPendingCount < 1 ) + return; + + // If we resized to a new state, we may have pending counts from that old state + if( _pendingState ) + { + if( _oldPendingCount > 0 ) + { + int committed = _consumerState->committedCount.load( std::memory_order_acquire ); + ASSERT( committed < _consumerState->capacity ); + + // Publish entries to the consumer thread + while( !_consumerState->committedCount.compare_exchange_weak( committed, committed + _oldPendingCount, + std::memory_order_release, + std::memory_order_relaxed ) ); + + _oldPendingCount = 0; + } + + ASSERT( _newState == nullptr ); + _newState.store( _producerState, std::memory_order_release ); + _pendingState = false; + } + + int committed = _producerState->committedCount.load( std::memory_order_acquire ); + ASSERT( committed < _producerState->capacity ); + + // Publish entries to the consumer thread + while( !_producerState->committedCount.compare_exchange_weak( committed, committed + _pendingCount, + std::memory_order_release, + std::memory_order_relaxed ) ); + + _pendingCount = 0; +} + +//----------------------------------------------------------- +template +bool GrowableSPCQueue::Enqueue(const T& value ) +{ + T* entry; + if( Write( entry ) ) + { + *entry = value; + Commit(); + return true; + } + + return false; +} + +//----------------------------------------------------------- +template +int GrowableSPCQueue::Dequeue( T* values, int capacity ) +{ + ASSERT( values ); + ASSERT( capacity > 0 ); + ASSERT( _consumerState ); + + int curCount = _consumerState->committedCount.load( std::memory_order_acquire ); + int count = std::min( capacity, curCount ); + + if( count > 0 ) + { + const size_t bufferCapacity = _consumerState->capacity; + T* consumerBuffer = _consumerState->buffer; + + const int readPos = _readPosition; + _readPosition = ( readPos + count ) % (int)bufferCapacity; + + const int copyCount = std::min( count, (int)bufferCapacity - readPos ); + bbmemcpy_t( values, consumerBuffer + readPos, (size_t)count ); + + // We might have to do 2 copies if we're wrapping around the end of the buffer + const int remainder = count - copyCount; + if( remainder > 0 ) + { + #if _DEBUG + Log::Debug( "[0x%p] Wrap", this ); + #endif + + bbmemcpy_t( values + copyCount, consumerBuffer, (size_t)remainder ); + } + + // Publish to the producer thread that we've consumed entries + while( !_consumerState->committedCount.compare_exchange_weak( curCount, curCount - count, + std::memory_order_release, + std::memory_order_relaxed ) ); + } + + // Check if we have a pending state change, if so apply it + // if we've consumed all of our current state's pending entries. + ConsumerState* newState = nullptr; + const int committedRemaining = curCount - count; + if( committedRemaining == 0 && ( newState = _newState.load( std::memory_order_acquire ) ) != nullptr ) + { + // Delete the current state's buffer + free( _consumerState->buffer ); + _consumerState->buffer = nullptr; + + // Publish to the producer that we've changed states + _newState.store( nullptr, std::memory_order_release ); + + // Change to the new state and check if we can consume some more entries + _consumerState = newState; + ASSERT( newState ); + + if( capacity > count ) + { + return count + this->Dequeue( values + count, capacity - count ); + } + } + + ASSERT( count >= 0 ); + return count; +} + diff --git a/src/util/Span.h b/src/util/Span.h new file mode 100644 index 00000000..1eb3c8f0 --- /dev/null +++ b/src/util/Span.h @@ -0,0 +1,70 @@ +#pragma once + + +template +struct Span +{ + // #TODO: Make these immutable + T* values; + size_t length; + + inline Span(){} + + inline Span( T* values, size_t length ) + : values( values ) + , length( length ) + {} + + inline size_t Length() const { return length; } + + inline T* Ptr() const { return values; } + + inline T& operator[]( unsigned int index ) const + { + ASSERT( index < length ); + return this->values[index]; + } + + inline T& operator[]( size_t index ) const + { + ASSERT( index < length ); + return this->values[index]; + } + + +// size_t not the same as uint64 on clang. +#ifdef __clang__ + inline T& operator[]( uint64 index ) const + { + ASSERT( index < length ); + return this->values[index]; + } +#endif + + inline T& operator[]( int index ) const + { + ASSERT( index > -1 && (size_t)index < length ); + return this->values[index]; + } + + inline Span Slice( const size_t index, const size_t length ) const + { + ASSERT( index <= this->length ); + ASSERT( index + length >= index ); + ASSERT( index + length <= this->length ); + + return Span( this->values + index, length ); + } + + inline Span Slice( const size_t index ) const + { + ASSERT( index <= length ); + return Slice( index, length - index ); + } + + inline Span Slice( const uint32 index ) const { return Slice( (size_t)index ); } + inline Span Slice( const int64 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } + inline Span Slice( const int32 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } +}; + +typedef Span ByteSpan; diff --git a/src/util/StackAllocator.h b/src/util/StackAllocator.h new file mode 100644 index 00000000..00a6b8ca --- /dev/null +++ b/src/util/StackAllocator.h @@ -0,0 +1,138 @@ +#pragma once + +class IAllocator +{ +public: + virtual ~IAllocator() {} + + virtual void* Alloc( const size_t size, const size_t alignment ) = 0; + + //----------------------------------------------------------- + template + inline T* AllocT( const size_t size, size_t alignment = alignof( T ) ) + { + return reinterpret_cast( Alloc( size, alignment ) ); + } + + //----------------------------------------------------------- + template + inline T* CAlloc( const size_t count, size_t alignment = alignof( T ) ) + { + const size_t allocSize = sizeof( T ) * count; + ASSERT( allocSize >= count ); + + return AllocT( allocSize, alignment ); + } + + //----------------------------------------------------------- + template + inline Span CAllocSpan( const size_t count, size_t alignment = alignof( T ) ) + { + return Span( this->CAlloc( count, alignment ), count ); + } + + //----------------------------------------------------------- + inline void* CAlloc( const size_t count, const size_t size, const size_t alignment ) + { + const size_t paddedSize = RoundUpToNextBoundaryT( size, alignment ); + + return Alloc( paddedSize * count, alignment ); + } +}; + +class DummyAllocator : public IAllocator +{ +public: + //----------------------------------------------------------- + void* Alloc( const size_t size, const size_t alignment ) override + { + const size_t paddedSize = RoundUpToNextBoundaryT( _size, alignment ); + _size = paddedSize + size; + return nullptr; + } + + //----------------------------------------------------------- + inline size_t Size() const { return _size; } + +private: + size_t _size = 0; +}; + + +// Fixed-capacity stack allocator +class StackAllocator : public IAllocator +{ +public: + + //----------------------------------------------------------- + inline StackAllocator( void* buffer, size_t capacity ) + : _buffer ( (byte*)buffer ) + , _capacity( capacity ) + {} + + //----------------------------------------------------------- + inline void* Alloc( const size_t size, const size_t alignment ) override + { + // Start address must be aligned to the specified alignment + const size_t paddedSize = RoundUpToNextBoundaryT( _size, alignment ); + + ASSERT( size > 0 ); + ASSERT( _size < _capacity ); + // ASSERT( _capacity - paddedSize >= size ); + FatalIf( !(_capacity - paddedSize >= size), "Allocation buffer overrun." ); + + void* ptr = reinterpret_cast( _buffer + paddedSize ); + _size = paddedSize + size; + + return ptr; + } + + //----------------------------------------------------------- + inline byte* Buffer() const + { + return _buffer; + } + + //----------------------------------------------------------- + inline size_t Capacity() const + { + return _capacity; + } + + //----------------------------------------------------------- + inline size_t Size() const + { + return _size; + } + + //----------------------------------------------------------- + inline size_t Remainder() const + { + return _capacity - _size; + } + + //----------------------------------------------------------- + inline byte* Top() const + { + return _buffer + _size; + } + + //----------------------------------------------------------- + inline void Pop( const size_t size ) + { + ASSERT( size >= _size ); + _size -= size; + } + + //----------------------------------------------------------- + inline void PopToMarker( const size_t sizeMarker ) + { + ASSERT( sizeMarker <= _size ); + _size = sizeMarker; + } + +private: + byte* _buffer; + size_t _capacity; // Stack capacity + size_t _size = 0; // Current allocated size/stack size +}; \ No newline at end of file diff --git a/src/util/Util.cpp b/src/util/Util.cpp new file mode 100644 index 00000000..c080142a --- /dev/null +++ b/src/util/Util.cpp @@ -0,0 +1,117 @@ +#include "util/Util.h" +#include "util/Log.h" + +//----------------------------------------------------------- +void Exit( int code ) +{ + exit( code ); +} + +//----------------------------------------------------------- +void FatalExit() +{ + Exit( 1 ); +} + +//----------------------------------------------------------- +void VFatalErrorMsg( const char* message, va_list args ) +{ + Log::Flush(); + Log::FlushError(); + + Log::Error( "\nFatal Error: " ); + Log::Error( message, args ); + Log::FlushError(); +} + +//----------------------------------------------------------- +void FatalErrorMsg( const char* message, ... ) +{ + va_list args; + va_start( args, message ); + VFatalErrorMsg( message, args ); + va_end( args ); +} + +//----------------------------------------------------------- +void PanicExit() +{ + SysHost::DumpStackTrace(); + Exit( 1 ); +} + +//----------------------------------------------------------- +void VPanicErrorMsg( const char* message, va_list args ) +{ + Log::Flush(); + Log::FlushError(); + + Log::Error( "\n*** Panic!!! *** Fatal Error: " ); + Log::Error( message, args ); + Log::FlushError(); +} + +//----------------------------------------------------------- +void PanicErrorMsg( const char* message, ... ) +{ + va_list args; + va_start( args, message ); + VPanicErrorMsg( message, args ); + va_end( args ); +} + +//----------------------------------------------------------- +void VFatal( const char* message, va_list args ) +{ + VFatalErrorMsg( message, args ); + FatalExit(); +} + +//----------------------------------------------------------- +bool AssertLog( int line, const char* file, const char* func ) +{ + Log::Error( "Assertion Failed @ %s:%d %s().", file, line, func ); + Log::FlushError(); + return true; +} + +//----------------------------------------------------------- +std::string HexToString( const byte* bytes, size_t length ) +{ + ASSERT( length ); + + const size_t slen = length * 2 + 1; + char* buffer = (char*)malloc( slen ); + memset( buffer, 0, slen ); + + size_t numEncoded; + BytesToHexStr( bytes, length, buffer, slen, numEncoded ); + + std::string str( buffer ); + free( buffer ); + + return str; +} + +//----------------------------------------------------------- +std::vector HexStringToBytes( const char* hexStr ) +{ + const size_t len = strlen( hexStr ); + + byte* buffer = (byte*)malloc( len / 2 ); + + HexStrToBytes( hexStr, len, buffer, len / 2 ); + std::vector ret( buffer, buffer + len / 2 ); + + free( buffer ); + return ret; +} + +//----------------------------------------------------------- +std::vector HexStringToBytes( const std::string& hexStr ) +{ + return HexStringToBytes( hexStr.c_str() ); +} + + + diff --git a/src/util/Util.h b/src/util/Util.h new file mode 100644 index 00000000..1b49e855 --- /dev/null +++ b/src/util/Util.h @@ -0,0 +1,544 @@ +#pragma once + +#include +#include +#include +#include "Platform.h" +#include "SysHost.h" +#include "Log.h" + +#ifdef _MSC_VER + #define Swap16( x ) _byteswap_ushort( x ) + #define Swap32( x ) _byteswap_ulong( x ) + #define Swap64( x ) _byteswap_uint64( x ) +#elif defined( __GNUC__ ) || defined( __clang__ ) + #define Swap16( x ) __builtin_bswap16( x ) + #define Swap32( x ) __builtin_bswap32( x ) + #define Swap64( x ) __builtin_bswap64( x ) +#else + #error Byte swapping intrinsics not configured for this compiler. +#endif + + +/// Byte size conversions +#define KB *(1<<10) +#define MB *(1<<20) +#define GB *(1<<30) + +#define BtoKB /(1<<10) +#define BtoMB /(1<<20) +#define BtoGB /(1<<30) + + +/// +/// Assorted utility functions +/// +void Exit( int code ); +void FatalExit(); +void PanicExit(); +void FatalErrorMsg( const char* message, ... ); +void PanicErrorMsg( const char* message, ... ); + +// Fatal: Post a message and exit with error +// Panic: Same as panic, but the error is unexpected, +// so a stack trace is also printed out. +//----------------------------------------------------------- +#ifdef _WIN32 + #define Fatal( message, ... ) { FatalErrorMsg( message, __VA_ARGS__ ); BBDebugBreak(); FatalExit(); } + #define Panic( message, ... ) { PanicErrorMsg( message, __VA_ARGS__ ); BBDebugBreak(); PanicExit(); } +#else + #define Fatal( message, ... ) { FatalErrorMsg( message, ## __VA_ARGS__ ); BBDebugBreak(); FatalExit(); } + #define Panic( message, ... ) { PanicErrorMsg( message, ## __VA_ARGS__ ); BBDebugBreak(); PanicExit(); } +#endif + +#define FatalIf( cond, message, ... ) if( (cond) ) { Fatal( message, ## __VA_ARGS__ ); } +#define PanicIf( cond, message, ... ) if( (cond) ) { Panic( message, ## __VA_ARGS__ ); } + + +//----------------------------------------------------------- +template +constexpr inline T bblog2( T x ) +{ + T r = 0; + while( x >>= 1 ) + r++; + return r; +} + +//----------------------------------------------------------- +constexpr inline int64 bbconst_ceil( const double x ) +{ + return (static_cast( static_cast(x) ) == x) ? + static_cast( x ) : + static_cast( x ) + (x > 0.0 ? 1 : 0); +} + + +// Divide a by b and apply ceiling if needed. +//----------------------------------------------------------- +template +constexpr inline T CDiv( T a, int b ) +{ + return ( a + (T)b - 1 ) / (T)b; +} + +//----------------------------------------------------------- +template +constexpr inline T CDivT( T a, T b ) +{ + return ( a + b - (T)1 ) / b; +} + +// Round up a number to the next upper boundary. +// For example, if we want to round up some bytes to the next 8-byte boundary. +//----------------------------------------------------------- +template +constexpr inline T RoundUpToNextBoundary( T value, int boundary ) +{ + return value + ( boundary - ( value % boundary ) ) % boundary; +} + +template +constexpr inline T RoundUpToNextBoundaryT( T value, T boundary ) +{ + return value + ( boundary - ( value % boundary ) ) % boundary; +} + +//----------------------------------------------------------- +inline bool MemCmp( const void* a, const void* b, size_t size ) +{ + return memcmp( a, b, size ) == 0; +} + +//----------------------------------------------------------- +template +inline T bbclamp( const T value, const T min, const T max ) +{ + return value < min ? min : value > max ? max : value; +} + +//----------------------------------------------------------- +template +inline void ZeroMem( T* ptr ) +{ + memset( ptr, 0, sizeof( T ) ); +} + +//----------------------------------------------------------- +template +inline void ZeroMem( T* ptr, size_t count ) +{ + ASSERT( count > 0 ); + memset( ptr, 0, sizeof( T ) * count ); +} + +//----------------------------------------------------------- +template +inline T* bbmalloc( size_t size ) +{ + void* ptr = malloc( size ); + FatalIf( !ptr, "bbmalloc(): Out of memory." ); + + return reinterpret_cast( ptr ); +} + +//----------------------------------------------------------- +template +inline T* bbrealloc( T* ptr, size_t newSize ) +{ + ptr = reinterpret_cast( realloc( ptr, newSize ) ); + FatalIf( !ptr, "bbrealloc(): Out of memory." ); + + return reinterpret_cast( ptr ); +} + +// #NOTE: Unlike calloc, this does not initialize memory to 0 +//----------------------------------------------------------- +template +inline T* bbcalloc( size_t count ) +{ + return bbmalloc( count * sizeof( T ) ); +} + +//----------------------------------------------------------- +template +inline Span bbcalloc_span( size_t count ) +{ + T* ptr = bbmalloc( count * sizeof( T ) ); + return Span( ptr, count ); +} + +//----------------------------------------------------------- +template +inline T* bbcrealloc( T* ptr, size_t newCount ) +{ + return bbrealloc( ptr, newCount * sizeof( T ) ); +} + +//----------------------------------------------------------- +template +inline void bbmemcpy_t( T* dst, const T* src, size_t count ) +{ + memcpy( dst, src, sizeof( T ) * count ); +} + +//----------------------------------------------------------- +inline void* bballoca( size_t size ) +{ +#if PLATFORM_IS_WINDOWS + return _malloca( size ); +#elif PLATFORM_IS_MACOS + return alloca( size ); +#elif PLATFORM_IS_LINUX + return alloca( size ); +#else + #error Unimplemented Platform +#endif +} + +//----------------------------------------------------------- +inline void bbvirtfree( void* ptr ) +{ + ASSERT( ptr ); + SysHost::VirtualFree( ptr ); +} + +//----------------------------------------------------------- +template +inline T* bbvirtalloc( size_t size ) +{ + void* ptr = SysHost::VirtualAlloc( size, false ); + FatalIf( !ptr, "VirtualAlloc failed." ); + return reinterpret_cast( ptr ); +} + +//----------------------------------------------------------- +template +inline T* bbvirtallocnuma( size_t size ) +{ + T* ptr = bbvirtalloc( size ); + + if( SysHost::GetNUMAInfo() ) + { + if( !SysHost::NumaSetMemoryInterleavedMode( ptr, size ) ) + Log::Error( "Warning: Failed to bind NUMA memory." ); + } + + return ptr; +} + +//----------------------------------------------------------- +template +inline T* bbcvirtalloc( size_t count ) +{ + return bbvirtalloc( sizeof( T ) * count ); +} + +// Allocate virtual memory with protected boundary pages +// #NOTE: Only free with bbvirtfreebounded +//----------------------------------------------------------- +template +inline T* bbvirtallocbounded( size_t size ) +{ + const size_t pageSize = SysHost::GetPageSize(); + size = RoundUpToNextBoundaryT( size, pageSize ) + pageSize * 2; + + auto* ptr = (byte*)SysHost::VirtualAlloc( size, false ); + FatalIf( !ptr, "VirtualAlloc failed." ); + + SysHost::VirtualProtect( ptr, pageSize, VProtect::NoAccess ); + SysHost::VirtualProtect( ptr + size - pageSize, pageSize, VProtect::NoAccess ); + + return reinterpret_cast( ptr + pageSize ); +} + +//----------------------------------------------------------- +template +inline T* bbvirtallocboundednuma( size_t size ) +{ + T* ptr = bbvirtallocbounded( size ); + if( SysHost::GetNUMAInfo() ) + { + if( !SysHost::NumaSetMemoryInterleavedMode( ptr, size ) ) + Log::Error( "Warning: Failed to bind NUMA memory." ); + } + + return ptr; +} + +//----------------------------------------------------------- +template +inline T* bbcvirtallocbounded( size_t count ) +{ + return bbvirtallocbounded( sizeof( T ) * count ); +} + +//----------------------------------------------------------- +template +inline T* bbcvirtallocboundednuma( size_t count ) +{ + T* ptr = bbcvirtallocbounded( count ); + if( SysHost::GetNUMAInfo() ) + { + if( !SysHost::NumaSetMemoryInterleavedMode( ptr, count * sizeof( T ) ) ) + Log::Error( "Warning: Failed to bind NUMA memory." ); + } + + return ptr; +} + +//----------------------------------------------------------- +template +inline Span bbcvirtallocboundednuma_span( size_t count ) +{ + return Span( bbcvirtallocboundednuma( count ), count ); +} + +//----------------------------------------------------------- +inline void bbvirtfreebounded( void* ptr ) +{ + ASSERT( ptr ); + SysHost::VirtualFree( ((byte*)ptr) - SysHost::GetPageSize() ); +} + + + +const char HEX_TO_BIN[256] = { + 0, // 0 00 NUL + 0, // 1 01 SOH + 0, // 2 02 STX + 0, // 3 03 ETX + 0, // 4 04 EOT + 0, // 5 05 ENQ + 0, // 6 06 ACK + 0, // 7 07 BEL + 0, // 8 08 BS + 0, // 9 09 HT + 0, // 10 0A LF + 0, // 11 0B VT + 0, // 12 0C FF + 0, // 13 0D CR + 0, // 14 0E SO + 0, // 15 0F SI + 0, // 16 10 DLE + 0, // 17 11 DC1 + 0, // 18 12 DC2 + 0, // 19 13 DC3 + 0, // 20 14 DC4 + 0, // 21 15 NAK + 0, // 22 16 SYN + 0, // 23 17 ETB + 0, // 24 18 CAN + 0, // 25 19 EM + 0, // 26 1A SUB + 0, // 27 1B ESC + 0, // 28 1C FS + 0, // 29 1D GS + 0, // 30 1E RS + 0, // 31 1F US + 0, // 32 20 space + 0, // 33 21 ! + 0, // 34 22 " + 0, // 35 23 # + 0, // 36 24 $ + 0, // 37 25 % + 0, // 38 26 & + 0, // 39 27 ' + 0, // 40 28 ( + 0, // 41 29 ) + 0, // 42 2A * + 0, // 43 2B + + 0, // 44 2C , + 0, // 45 2D - + 0, // 46 2E . + 0, // 47 2F / + 0, // 48 30 0 + 1, // 49 31 1 + 2, // 50 32 2 + 3, // 51 33 3 + 4, // 52 34 4 + 5, // 53 35 5 + 6, // 54 36 6 + 7, // 55 37 7 + 8, // 56 38 8 + 9, // 57 39 9 + 0, // 58 3A : + 0, // 59 3B ; + 0, // 60 3C < + 0, // 61 3D = + 0, // 62 3E > + 0, // 63 3F ? + 0, // 64 40 @ + 10, // 65 41 A + 11, // 66 42 B + 12, // 67 43 C + 13, // 68 44 D + 14, // 69 45 E + 15, // 70 46 F + 0, // 71 47 G + 0, // 72 48 H + 0, // 73 49 I + 0, // 74 4A J + 0, // 75 4B K + 0, // 76 4C L + 0, // 77 4D M + 0, // 78 4E N + 0, // 79 4F O + 0, // 80 50 P + 0, // 81 51 Q + 0, // 82 52 R + 0, // 83 53 S + 0, // 84 54 T + 0, // 85 55 U + 0, // 86 56 V + 0, // 87 57 W + 0, // 88 58 X + 0, // 89 59 Y + 0, // 90 5A Z + 0, // 91 5B [ + 0, // 92 5C \ // + 0, // 93 5D ] + 0, // 94 5E ^ + 0, // 95 5F _ + 0, // 96 60 ` + 10, // 97 61 a + 11, // 98 62 b + 12, // 99 63 c + 13, // 100 64 d + 14, // 101 65 e + 15, // 102 66 f + 0, // 103 67 g + 0, // 104 68 h + 0, // 105 69 i + 0, // 106 6A j + 0, // 107 6B k + 0, // 108 6C l + 0, // 109 6D m + 0, // 110 6E n + 0, // 111 6F o + 0, // 112 70 p + 0, // 113 71 q + 0, // 114 72 r + 0, // 115 73 s + 0, // 116 74 t + 0, // 117 75 u + 0, // 118 76 v + 0, // 119 77 w + 0, // 120 78 x + 0, // 121 79 y + 0, // 122 7A z + 0, // 123 7B { + 0, // 124 7C | + 0, // 125 7D } + 0, // 126 7E ~ + 0, // 127 7F DEL + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +//----------------------------------------------------------- +inline void HexStrToBytes( const char* str, const size_t strSize, + byte* dst, size_t dstSize ) +{ + ASSERT( str && strSize ); + ASSERT( dst && dstSize ); + + const size_t maxSize = (strSize / 2) * 2; + const char* end = str + maxSize; + + ASSERT( dstSize >= maxSize / 2 ); + + int i = 0; + while( str < end ) + { + byte msb = (byte)HEX_TO_BIN[(int)str[0]]; + byte lsb = (byte)HEX_TO_BIN[(int)str[1]]; + + byte v = lsb + msb * 16u; + dst[i++] = v; + str += 2; + } +} + +//----------------------------------------------------------- +// Encode bytes into hex format +// Return: +// 0 if OK +// -1 if Needed more space in the dst buffer to write +// -2 if the required dstSize would overflow +//----------------------------------------------------------- +inline int BytesToHexStr( const byte* src, size_t srcSize, + char* dst, size_t dstSize, + size_t& numEncoded, + bool uppercase = false ) +{ + const char HEXUC[] = "0123456789ABCDEF"; + const char HEXLC[] = "0123456789abcdef"; + + const char* HEX = uppercase ? HEXUC : HEXLC; + + const size_t MAX_SRC_SIZE = std::numeric_limits::max() / 2; + + numEncoded = 0; + int ret = 0; + + if( dstSize == 0 ) + { + return -1; + } + + size_t maxEncode = srcSize; + size_t dstRequired; + + // Check for overflow + if( maxEncode > MAX_SRC_SIZE ) + { + maxEncode = MAX_SRC_SIZE; + dstRequired = std::numeric_limits::max(); + numEncoded = MAX_SRC_SIZE; + ret = -2; + } + else + { + dstRequired = maxEncode * 2; + numEncoded = maxEncode; + } + + // Cap the encode count to the dst buffer size + if( dstRequired > dstSize ) + { + ret = -1; + numEncoded = dstSize/2; + } + + const byte* s = src; + const byte* end = src + numEncoded; + char* d = dst; + + while( s < end ) + { + d[0] = (char)HEX[(*s >> 4) & 0x0F]; + d[1] = (char)HEX[*s & 15]; + + s++; + d += 2; + } + + return ret; +} + +//----------------------------------------------------------- +inline std::vector BytesConcat( std::vector a, std::vector b, std::vector c ) +{ + a.insert( a.end(), b.begin(), b.end() ); + a.insert( a.end(), c.begin(), c.end() ); + return a; +} + +std::string HexToString( const byte* bytes, size_t length ); +std::vector HexStringToBytes( const char* hexStr ); +std::vector HexStringToBytes( const std::string& hexStr ); + diff --git a/src/util/jobs/MemJobs.h b/src/util/jobs/MemJobs.h new file mode 100644 index 00000000..9c55dfb6 --- /dev/null +++ b/src/util/jobs/MemJobs.h @@ -0,0 +1,127 @@ +#pragma once +#include "threading/MTJob.h" +#include "util/Util.h" + +struct FaultMemoryPages : MTJob +{ + byte* pages; + size_t pageSize; + uint64 pageCount; + + //----------------------------------------------------------- + inline void Run() override + { + const size_t pageSize = this->pageSize; + + byte* page = this->pages; + const byte* end = page + this->pageCount * pageSize; + + do { + *page = 0; + page += pageSize; + + } while( page < end ); + } + + //----------------------------------------------------------- + inline static void RunJob( ThreadPool& pool, uint32 threadCount, void* buffer, const size_t size ) + { + threadCount = std::max( 1u, std::min( threadCount, pool.ThreadCount() ) ); + + const size_t pageSize = SysHost::GetPageSize(); + const uint64 pageCount = CDiv( size, (int)pageSize ); + if( threadCount == 1 ) + { + FaultMemoryPages job; + job.pages = (byte*)buffer; + job.pageCount = pageCount; + job.pageSize = pageSize; + + job.Run(); + return; + } + + MTJobRunner jobs( pool ); + + const uint64 pagesPerThread = pageCount / threadCount; + uint64 numRemainderPages = pageCount - ( pagesPerThread * threadCount ); + + byte* pages = (byte*)buffer; + for( uint i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job.pages = pages; + job.pageSize = pageSize; + job.pageCount = pagesPerThread; + + if( numRemainderPages ) + { + job.pageCount ++; + numRemainderPages --; + } + + pages += pageSize * job.pageCount; + } + + jobs.Run( threadCount ); + } +}; + + +struct MemCpyMT : MTJob +{ + //----------------------------------------------------------- + inline static void Copy( void* dst, const void* src, size_t size, ThreadPool& pool, uint32 threadCount ) + { + if( size < 1 ) + return; + + ASSERT( dst ); + ASSERT( src ); + ASSERT( threadCount ); + + threadCount = std::max( 1u, std::min( threadCount, pool.ThreadCount() ) ); + if( threadCount == 1 ) + { + memcpy( dst, src, size ); + return; + } + + MTJobRunner jobs( pool ); + + byte* dstBytes = (byte*)dst; + const byte* srcBytes = (byte*)src; + + const size_t sizePerThread = size / threadCount; + const size_t remainder = size - sizePerThread * threadCount; + + for( uint i = 0; i < threadCount; i++ ) + { + auto& job = jobs[i]; + + job._dst = dstBytes; + job._src = srcBytes; + job._size = sizePerThread; + + dstBytes += sizePerThread; + srcBytes += sizePerThread; + } + + jobs[threadCount-1]._size += remainder; + + jobs.Run( threadCount ); + } + + //----------------------------------------------------------- + inline void Run() override + { + memcpy( _dst, _src, _size ); + } + +private: + void* _dst; + const void* _src; + size_t _size; + +}; diff --git a/strip-debug-symbols.sh b/strip-debug-symbols.sh new file mode 100755 index 00000000..2454bfa1 --- /dev/null +++ b/strip-debug-symbols.sh @@ -0,0 +1,11 @@ +#! /usr/bin/env bash + +set -e +set -o pipefail + +binary_path=$1 + +objcopy --only-keep-debug ${binary_path} ${binary_path}.debug +strip --strip-debug --strip-unneeded ${binary_path} +objcopy --add-gnu-debuglink="${binary_path}.debug" ${binary_path} + diff --git a/symbolicate-crash.sh b/symbolicate-crash.sh new file mode 100755 index 00000000..8d718a8d --- /dev/null +++ b/symbolicate-crash.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +exe_path=$1 +log_path=$2 + +if [[ ! -f "$exe_path" ]]; then + >&2 echo "Invalid bladebit executable path specified." + exit 1 +fi + +if [[ ! -f "$log_path" ]]; then + >&2 echo "Invalid log path specified." + exit 1 +fi + +set +e +which addr2line >/dev/null 2>&1 +found_addr2line=$? +set -e + +if [[ $found_addr2line -ne 0 ]]; then + >&2 echo "Could not find addr2line. Please ensure you have it installed and under PATH." + exit 1 +fi + +# Load un-symbolicated stack trace +IFS=$'\r\n' +stack_trace=( $(cat $log_path) ) + +for c in ${stack_trace[@]}; do + address=$(printf "$c" | sed -E "s/.*\[(0x.+)\].*/\1/") + line=$(addr2line -ifp --demangle -a $address -e "$exe_path") + printf "%-58s @%s\n" "$c" "$line" +done + +exit 0 \ No newline at end of file diff --git a/tests/TestBucketStream.cpp b/tests/TestBucketStream.cpp new file mode 100644 index 00000000..23516af2 --- /dev/null +++ b/tests/TestBucketStream.cpp @@ -0,0 +1,127 @@ +#include "TestUtil.h" +#include "io/BucketStream.h" +#include "io/HybridStream.h" // #TODO: Use/Implement a MemoryStream instead. + +const uint32 k = 24; +const uint32 entryCount = 1ull << k; + +const size_t cacheSize = entryCount * sizeof( uint32 ); +void* cache = bbmalloc( cacheSize ); +uint32* bucketBuffer = bbcalloc( entryCount ); + +//----------------------------------------------------------- +template +void TestBuckets() +{ + const uint32 entriesPerBucket = entryCount / _numBuckets; + const uint32 entriesPerSlice = entriesPerBucket / _numBuckets; + ASSERT( entriesPerSlice * _numBuckets == entriesPerBucket ); + + Log::Line( "Testing %u buckets", _numBuckets ); + Log::Line( " Entries/bucket: %u.", entriesPerBucket ); + Log::Line( " Entries/slice : %u.", entriesPerSlice ); + +#if PLATFORM_IS_WINDOWS + const char* path = "nul"; +#else + const char* path = "/dev/null"; +#endif + + HybridStream memStream; + FatalIf( !memStream.Open( cache, cacheSize, path, FileMode::Create, FileAccess::ReadWrite, FileFlags::LargeFile ), + "Failed to open test file." ); + + BucketStream stream( memStream, entriesPerSlice * sizeof( uint32 ), _numBuckets ); + + uint32 sliceSizes[_numBuckets]; + for( uint32 slice = 0; slice < _numBuckets; slice++ ) + sliceSizes[slice] = entriesPerSlice * sizeof( uint32 ); + + auto WriteSlice = [&]( const uint32 slice ) { + + uint32* writer = bucketBuffer; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + const uint32 entryOffset = bucket * entriesPerBucket + slice * entriesPerSlice; + + for( uint32 i = 0; i < entriesPerSlice; i++ ) + writer[i] = entryOffset + i; + + writer += entriesPerSlice; + } + + stream.WriteBucketSlices( bucketBuffer, sliceSizes ); + }; + + // Write our entries in sequential mode (entries will contain valuies 0..numEntries-1) + for( uint32 slice = 0; slice < _numBuckets; slice++ ) + WriteSlice( slice ); + + // Read it back, still in sequential mode + ENSURE( stream.Seek( 0, SeekOrigin::Begin ) ); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + stream.ReadBucket( entriesPerBucket * sizeof( uint32 ), bucketBuffer ); + + uint32 e = bucket * entriesPerBucket; + + // Validate read entries + for( uint32 i = 0; i < entriesPerBucket; i++, e++ ) + { + ENSURE( e == bucketBuffer[i] ); + } + + // Write in interleaved mode now. This will write all slices + // to the space reserved for the bucket we just read + WriteSlice( bucket ); + } + + // Now read in interleaved mode + ENSURE( stream.Seek( 0, SeekOrigin::Begin ) ); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + stream.ReadBucket( entriesPerBucket * sizeof( uint32 ), bucketBuffer ); + + uint32 e = bucket * entriesPerBucket; + + // Validate entries + for( uint32 i = 0; i < entriesPerBucket; i++, e++ ) + { + ENSURE( e == bucketBuffer[i] ); + } + + // Write in sequential mode again + WriteSlice( bucket ); + } + + // Finally, read it back, still in sequential mode again and validate + ENSURE( stream.Seek( 0, SeekOrigin::Begin ) ); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + stream.ReadBucket( entriesPerBucket * sizeof( uint32 ), bucketBuffer ); + + uint32 e = bucket * entriesPerBucket; + + // Validate read entries + for( uint32 i = 0; i < entriesPerBucket; i++, e++ ) + { + ENSURE( e == bucketBuffer[i] ); + } + } +} + +//----------------------------------------------------------- +TEST_CASE( "bucket-stream", "[unit-core]" ) +{ + SysHost::InstallCrashHandler(); + + TestBuckets<64>(); + TestBuckets<128>(); + TestBuckets<256>(); + TestBuckets<512>(); + TestBuckets<1024>(); +} \ No newline at end of file diff --git a/tests/TestSPCQueue.cpp b/tests/TestSPCQueue.cpp new file mode 100644 index 00000000..67cc6888 --- /dev/null +++ b/tests/TestSPCQueue.cpp @@ -0,0 +1,92 @@ +#include "TestUtil.h" +#include "SysHost.h" +#include "util/SPCQueue.h" +#include "threading/AutoResetSignal.h" +#include "threading/MTJob.h" + +static void ProducerThread( void* param = nullptr ); +static void ConsumerThread( void* param = nullptr ); + +namespace { + + static AutoResetSignal _signal; + static GrowableSPCQueue _queue; + static std::atomic _exitThread = false; +} + +//----------------------------------------------------------- +TEST_CASE( "spc-queue", "[unit-core]" ) +{ + Thread producer; + + producer.Run( ProducerThread, nullptr ); + + ConsumerThread(); + + producer.WaitForExit(); +} + +//----------------------------------------------------------- +void ProducerThread( void* param ) +{ + const int MAX_COUNT = std::numeric_limits::max(); + const int BATCH_SIZE = 16; + + int j; + for( int i = 0; i < MAX_COUNT; i += j ) + { + const int max = std::min( BATCH_SIZE, MAX_COUNT-i ); + for( j = 0; j < max; j++ ) + { + const int v = i+j; + if( !_queue.Enqueue( v ) ) + break; + } + + _queue.Commit(); + _signal.Signal(); + } + + _exitThread = true; + _signal.Signal(); +} + +//----------------------------------------------------------- +void ConsumerThread( void* param ) +{ + const int INTERVAL = 100000000; + const int CAPACITY = 64; + int buffer[CAPACITY]; + + int next = 0; + + for( ;; ) + { + _signal.Wait(); + + // Take all entries until there's no more + for( ;; ) + { + const int count = _queue.Dequeue( buffer, CAPACITY ); + ENSURE( count <= CAPACITY ); + + if( count == 0 ) + { + if( _exitThread ) + return; + + break; + } + + for( int i = 0; i < count; i++ ) + { + ENSURE( buffer[i] == next + i ); + } + + next += count; + if( next % INTERVAL == 0 ) + Log::Line( "Count: %d", next ); + } + } +} + diff --git a/tests/TestUtil.h b/tests/TestUtil.h new file mode 100644 index 00000000..2b92a6f5 --- /dev/null +++ b/tests/TestUtil.h @@ -0,0 +1,45 @@ +#pragma once + +#include "catch2/catch_test_macros.hpp" +#include "util/Util.h" +#include "util/Log.h" +#include "threading/MTJob.h" +#include "threading/ThreadPool.h" +#include "util/jobs/MemJobs.h" +#include "plotdisk/jobs/IOJob.h" +#include "io/FileStream.h" + +// Helper to break on the assertion failure when debugging a test. +// You can pass an argument to the catch to break on asserts, however, +// REQUIRE itself is extremely heavy to call directly. +#define ENSURE( x ) \ + if( !(x) ) { ASSERT( x ); REQUIRE( x ); } + + + +//----------------------------------------------------------- +template +T* LoadReferenceTable( const char* path, uint64& outEntryCount ) +{ + FileStream file; + FatalIf( !file.Open( path, FileMode::Open, FileAccess::Read, FileFlags::LargeFile | FileFlags::NoBuffering ), + "Failed to open reference meta table file %s.", path ); + + byte* pBlock = (byte*)alloca( file.BlockSize() * 2 ); + pBlock = (byte*)RoundUpToNextBoundary( (uintptr_t)pBlock, (uintptr_t)file.BlockSize() ); + + FatalIf( file.Read( pBlock, file.BlockSize() ) != (ssize_t)file.BlockSize(), + "Failed to read table length." ); + + const uint64 entryCount = *(uint64*)pBlock; + + const size_t allocSize = RoundUpToNextBoundaryT( sizeof( T ) * (size_t)entryCount, file.BlockSize() ); + T* entries = bbvirtallocbounded( allocSize ); + + int err = 0; + FatalIf( !IOJob::ReadFromFile( file, entries, entryCount * sizeof( T ), pBlock, file.BlockSize(), err ), + "Failed to read table file '%s' with error: %d", path, err ); + + outEntryCount = entryCount; + return entries; +} \ No newline at end of file From 6748d916a3398e3ac9843e6155abf89113552b0f Mon Sep 17 00:00:00 2001 From: Harold B Date: Thu, 5 May 2022 21:23:50 -0500 Subject: [PATCH 02/91] Fixed version to v2.0.0-alpha1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 867eb04d..a3fc5781 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ 2.0.0 --alpha0 \ No newline at end of file +-alpha1 \ No newline at end of file From 0b4794f162e33e5bc5854c16717a70bde57ad632 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Fri, 6 May 2022 21:11:16 +0000 Subject: [PATCH 03/91] log temp 1, 2, and output paths --- src/main.cpp | 2 ++ src/plotdisk/DiskPlotter.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 16acf242..5dfeb482 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -393,6 +393,8 @@ void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ) else if( cfg.poolPublicKey ) Log::Line( " Pool public key : %s", poolPublicKey ); + Log::Line( " Output path : %s", cfg.outputFolder ); + Log::Line( "" ); } diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index d95be160..50c38b58 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -71,6 +71,8 @@ DiskPlotter::DiskPlotter( const Config& cfg ) Log::Line( " I/O threads : %u" , _cx.ioThreadCount ); Log::Line( " Temp1 block sz : %u" , _cx.tmp1BlockSize ); Log::Line( " Temp2 block sz : %u" , _cx.tmp2BlockSize ); + Log::Line( " Temp1 path : %s" , _cx.tmpPath ); + Log::Line( " Temp2 path : %s" , _cx.tmpPath2 ); #if BB_IO_METRICS_ON Log::Line( " I/O metrices enabled." ); #endif From e29a8b0f43a1bdc3c75e125b925bb7912a124277 Mon Sep 17 00:00:00 2001 From: Harold B Date: Fri, 6 May 2022 16:15:06 -0500 Subject: [PATCH 04/91] Fix help command issue. Reported by morebytes --- src/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 16acf242..f4edcc76 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -273,13 +273,13 @@ void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ) { if( cli.ArgMatch( "diskplot" ) ) DiskPlotter::PrintUsage(); - if( cli.ArgMatch( "iotest" ) ) + else if( cli.ArgMatch( "iotest" ) ) IOTestPrintUsage(); - if( cli.ArgMatch( "memtest" ) ) + else if( cli.ArgMatch( "memtest" ) ) MemTestPrintUsage(); - if( cli.ArgMatch( "validate" ) ) + else if( cli.ArgMatch( "validate" ) ) PlotValidatorPrintUsage(); - if( cli.ArgMatch( "plotcmp" ) ) + else if( cli.ArgMatch( "plotcmp" ) ) PlotCompareMainPrintUsage(); else Fatal( "Unknown command '%s'.", cli.Arg() ); @@ -456,7 +456,7 @@ R"( [EXAMPLES] bladebit --help -bladebiy help diskplot +bladebit help diskplot bladebit -t 24 -f ... -c ... diskplot --f1 256MB --fx 256MB -t /my/temporary/plot/dir --f1-threads 3 --c-threads 8 --p2-threads 12 --p3-threads 8 /my/output/dir From c4cee4e65bfa0a296d5aca5fecdca6b6ea1d38cd Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 10 May 2022 19:23:09 -0500 Subject: [PATCH 05/91] Working on bounded fp --- CMakeLists.txt | 4 +- src/platform/win32/FileStream_Win32.cpp | 2 +- src/plotdisk/DiskPlotBounded.h | 4 - src/plotdisk/DiskPlotConfig.h | 2 +- src/plotdisk/DiskPlotContext.h | 4 + src/plotdisk/DiskPlotter.cpp | 104 ++-- src/plotdisk/DiskPlotter.h | 6 +- src/plotdisk/FileId.h | 8 +- src/plotdisk/k32/DiskPlotBounded.cpp | 97 ++++ src/plotdisk/k32/DiskPlotBounded.h | 29 + .../F1Bounded.inl} | 55 +- src/plotdisk/k32/FpMatchBounded.inl | 202 +++++++ src/plotdisk/k32/FxBounded.inl | 532 ++++++++++++++++++ src/util/Span.h | 6 + 14 files changed, 954 insertions(+), 101 deletions(-) delete mode 100644 src/plotdisk/DiskPlotBounded.h create mode 100644 src/plotdisk/k32/DiskPlotBounded.cpp create mode 100644 src/plotdisk/k32/DiskPlotBounded.h rename src/plotdisk/{DiskPlotBounded.cpp => k32/F1Bounded.inl} (80%) create mode 100644 src/plotdisk/k32/FpMatchBounded.inl create mode 100644 src/plotdisk/k32/FxBounded.inl diff --git a/CMakeLists.txt b/CMakeLists.txt index e2a5306d..221578b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -377,7 +377,7 @@ set(bb_include_dirs # endmacro() # BladeBit -add_library(lib_bladebit ${bb_sources} ${bb_headers}) +add_library(lib_bladebit ${bb_sources} ${bb_headers} src/plotdisk/k32/FpMatchBounded.inl src/plotdisk/k32/F1Bounded.inl) set_target_properties(lib_bladebit PROPERTIES OUTPUT_NAME bladebit @@ -391,7 +391,7 @@ target_compile_options(lib_bladebit PUBLIC $<$:${c_opts} ${debug_c target_link_options(lib_bladebit PUBLIC $<$:${link_opts} ${release_link_opts}>) target_link_options(lib_bladebit PUBLIC $<$:${link_opts} ${debug_link_opts}>) -add_executable(bladebit ${bb_headers} src/main.cpp) +add_executable(bladebit ${bb_headers} src/main.cpp src/plotdisk/k32/FxBounded.inl) target_link_libraries(bladebit PRIVATE lib_bladebit) add_executable(bladebit_dev EXCLUDE_FROM_ALL src/sandbox/sandbox_main.cpp ${src_dev} ${bb_headers}) diff --git a/src/platform/win32/FileStream_Win32.cpp b/src/platform/win32/FileStream_Win32.cpp index 402bb60d..93a60e77 100644 --- a/src/platform/win32/FileStream_Win32.cpp +++ b/src/platform/win32/FileStream_Win32.cpp @@ -184,7 +184,7 @@ ssize_t FileStream::Write( const void* buffer, size_t size ) { // We can only write in block sizes. But since the user may have // specified a size greater than DWORD, our clamping it to - // DWORD's max can cause it to become not bounded to block size, + // DWORD's max can cause it to become not k32 to block size, // even if the user's original size was block-bound. // So let's limit this to a block size. bytesToWrite = (DWORD)(bytesToWrite / _blockSize * _blockSize); diff --git a/src/plotdisk/DiskPlotBounded.h b/src/plotdisk/DiskPlotBounded.h deleted file mode 100644 index 798e13d6..00000000 --- a/src/plotdisk/DiskPlotBounded.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -// Bounded disk plotter - diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 8fa89c4a..250163e8 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -5,7 +5,7 @@ #define BB_DP_BUCKET_COUNT ( 1u << kExtraBits ) // 64 with kExtraBits == 6 // #TODO: Remove this and make buckets configurable -#define BB_DP_MIN_BUCKET_COUNT 128 // Below 128 we can't fit y+map in a qword. +#define BB_DP_MIN_BUCKET_COUNT 64 // Below 128 we can't fit y+map in a qword, so it's only available in bounded mode. #define BB_DP_MAX_BUCKET_COUNT 1024 #define BB_DP_ENTRIES_PER_BUCKET ( ( 1ull << _K ) / BB_DP_BUCKET_COUNT ) diff --git a/src/plotdisk/DiskPlotContext.h b/src/plotdisk/DiskPlotContext.h index c56a1d41..47220230 100644 --- a/src/plotdisk/DiskPlotContext.h +++ b/src/plotdisk/DiskPlotContext.h @@ -20,6 +20,7 @@ struct DiskPlotConfig uint32 ioBufferCount = 0; size_t cacheSize = 0; + bool bounded = false; // Do not overflow entries bool noTmp1DirectIO = false; // Disable direct I/O on tmp 1 bool noTmp2DirectIO = false; // Disable direct I/O on tmp 1 @@ -66,6 +67,9 @@ struct DiskPlotContext uint32 bucketCounts[(uint)TableId::_Count][BB_DP_MAX_BUCKET_COUNT+1]; uint64 entryCounts [(uint)TableId::_Count]; + uint32 bucketSlices[2][BB_DP_MAX_BUCKET_COUNT]; + + // Since back pointer table entries are not sorted along with y, // (instead we use a mapping table), and since their values are stored // in local-to-bucket coordinates, we need to know how many entries diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index d95be160..df473d99 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -11,6 +11,8 @@ #include "DiskPlotPhase3.h" #include "SysHost.h" +#include "k32/DiskPlotBounded.h" + size_t ValidateTmpPathAndGetBlockSize( DiskPlotter::Config& cfg ); @@ -29,16 +31,16 @@ DiskPlotter::DiskPlotter( const Config& cfg ) // Initialize tables for matching LoadLTargets(); + ZeroMem( &_cx ); + GlobalPlotConfig& gCfg = *cfg.globalCfg; - ZeroMem( &_cx ); - FatalIf( !GetTmpPathsBlockSizes( cfg.tmpPath, cfg.tmpPath2, _cx.tmp1BlockSize, _cx.tmp2BlockSize ), "Failed to obtain temp paths block size from t1: '%s' or %s t2: '%s'.", cfg.tmpPath, cfg.tmpPath2 ); FatalIf( _cx.tmp1BlockSize < 8 || _cx.tmp2BlockSize < 8,"File system block size is too small.." ); - const size_t heapSize = GetRequiredSizeForBuckets( cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize ); + const size_t heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize ); _cfg = cfg; _cx.cfg = &_cfg; @@ -97,7 +99,7 @@ DiskPlotter::DiskPlotter( const Config& cfg ) _cx.cacheSize = alignedCacheSize; } - _cx.cache = bbvirtallocnuma( _cx.cacheSize ); + _cx.cache = bbvirtalloc( _cx.cacheSize ); if( numa && !gCfg.disableNuma ) { if( !SysHost::NumaSetMemoryInterleavedMode( _cx.cache, _cx.cacheSize ) ) @@ -137,9 +139,9 @@ void DiskPlotter::Plot( const PlotRequest& req ) memset( _cx.bucketCounts , 0, sizeof( _cx.bucketCounts ) ); memset( _cx.entryCounts , 0, sizeof( _cx.entryCounts ) ); memset( _cx.ptrTableBucketCounts, 0, sizeof( _cx.ptrTableBucketCounts ) ); + memset( _cx.bucketSlices , 0, sizeof( _cx.bucketSlices ) ); // #TODO: Reset the rest of the state, including the heap & the ioQueue - Log::Line( "Started plot." ); auto plotTimer = TimerBegin(); @@ -149,38 +151,42 @@ void DiskPlotter::Plot( const PlotRequest& req ) _cx.ioQueue->OpenPlotFile( req.plotFileName, req.plotId, req.plotMemo, req.plotMemoSize ); + if( !_cx.cfg->bounded ) { - Log::Line( "Running Phase 1" ); - const auto timer = TimerBegin(); + { + Log::Line( "Running Phase 1" ); + const auto timer = TimerBegin(); - DiskPlotPhase1 phase1( _cx ); - phase1.Run(); + DiskPlotPhase1 phase1( _cx ); + phase1.Run(); - const double elapsed = TimerEnd( timer ); - Log::Line( "Finished Phase 1 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); - } + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 1 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } - { - Log::Line( "Running Phase 2" ); - const auto timer = TimerBegin(); + { + Log::Line( "Running Phase 2" ); + const auto timer = TimerBegin(); - DiskPlotPhase2 phase2( _cx ); - phase2.Run(); + DiskPlotPhase2 phase2( _cx ); + phase2.Run(); - const double elapsed = TimerEnd( timer ); - Log::Line( "Finished Phase 2 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); - } + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 2 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } - { - Log::Line( "Running Phase 3" ); - const auto timer = TimerBegin(); + { + Log::Line( "Running Phase 3" ); + const auto timer = TimerBegin(); - DiskPlotPhase3 phase3( _cx ); - phase3.Run(); + DiskPlotPhase3 phase3( _cx ); + phase3.Run(); - const double elapsed = TimerEnd( timer ); - Log::Line( "Finished Phase 3 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 3 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } } + Log::Line("Total plot I/O wait time: %.2lf seconds.", TicksToSeconds( _cx.ioWaitTime ) ); @@ -231,6 +237,12 @@ void DiskPlotter::Plot( const PlotRequest& req ) } } +//----------------------------------------------------------- +void DiskPlotter::PlotBounded( const PlotRequest& req ) +{ + +} + //----------------------------------------------------------- void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) { @@ -238,6 +250,8 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) { if( cli.ReadU32( cfg.numBuckets, "-b", "--buckets" ) ) continue; + if( cli.ReadSwitch( cfg.bounded, "--k32-bounded" ) ) + continue; if( cli.ReadStr( cfg.tmpPath, "-t1", "--temp1" ) ) continue; if( cli.ReadStr( cfg.tmpPath2, "-t2", "--temp2" ) ) @@ -260,6 +274,8 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) continue; if( cli.ArgConsume( "-s", "--sizes" ) ) { + // #TODO: Get sizes for bounded + FatalIf( cfg.numBuckets < BB_DP_MIN_BUCKET_COUNT || cfg.numBuckets > BB_DP_MAX_BUCKET_COUNT, "Buckets must be between %u and %u, inclusive.", (uint)BB_DP_MIN_BUCKET_COUNT, (uint)BB_DP_MAX_BUCKET_COUNT ); FatalIf( ( cfg.numBuckets & ( cfg.numBuckets - 1 ) ) != 0, "Buckets must be power of 2." ); @@ -268,10 +284,10 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) if( cfg.tmpPath ) { cfg.tmpPath2 = cfg.tmpPath2 ? cfg.tmpPath2 : cfg.tmpPath; - heapSize = GetRequiredSizeForBuckets( cfg.numBuckets, cfg.tmpPath2, cfg.tmpPath ); + heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, cfg.tmpPath2, cfg.tmpPath ); } else - heapSize = GetRequiredSizeForBuckets( cfg.numBuckets, 1, 1 ); + heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, 1, 1 ); Log::Line( "Buckets: %u | Heap Sizes: %.2lf GiB", cfg.numBuckets, (double)heapSize BtoGB ); exit( 0 ); @@ -307,6 +323,9 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) FatalIf( ( cfg.numBuckets & ( cfg.numBuckets - 1 ) ) != 0, "Buckets must be power of 2." ); + FatalIf( cfg.numBuckets >= 1024, "1024 buckets are not allowed for plots < k33." ); + FatalIf( cfg.numBuckets < 128 && !cfg.bounded, "64 buckets is only allowed for bounded k=32 plots." ); + const uint32 sysLogicalCoreCount = SysHost::GetLogicalCPUCount(); if( cfg.ioThreadCount == 0 ) @@ -360,6 +379,7 @@ bool DiskPlotter::GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPa size_t blockSizes[2] = { 0 }; + // #TODO: Don't do this. We can just use the dir to get block size for( int32 i = 0; i < 2; i++ ) { size_t len = lengths[i]; @@ -413,34 +433,40 @@ bool DiskPlotter::GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPa } //----------------------------------------------------------- -size_t DiskPlotter::GetRequiredSizeForBuckets( const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2 ) +size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2 ) { size_t blockSizes[2] = { 0 }; if( !GetTmpPathsBlockSizes( tmpPath1, tmpPath2, blockSizes[0], blockSizes[1] ) ) return 0; - return GetRequiredSizeForBuckets( numBuckets, blockSizes[0], blockSizes[1] ); + return GetRequiredSizeForBuckets( bounded, numBuckets, blockSizes[0], blockSizes[1] ); } //----------------------------------------------------------- -size_t DiskPlotter::GetRequiredSizeForBuckets( const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize ) +size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize ) { + if( bounded ) + return K32BoundedPhase1::GetRequiredSize( numBuckets, pairsBlockSize, fxBlockSize ); + switch( numBuckets ) { - case 128 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); + case 128 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); case 256 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); case 512 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); case 1024: + Fatal( "1024 buckets are currently unsupported." ); + return 0; // We need to add a bit more here (at least 1GiB) to have enough space for P2, which keeps // 2 marking table bitfields in-memory: k^32 / 8 = 0.5GiB - return 1032ull MB + DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); - +// return 1032ull MB + DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); + + default: - Fatal( "Invalid bucket size: %u.", numBuckets ); break; } + Fatal( "Invalid bucket size: %u.", numBuckets ); return 0; } @@ -503,7 +529,11 @@ Creates plots by making use of a disk to temporarily store and read values. [OPTIONS] -b, --buckets : The number of buckets to use. The default is 256. - You may specify one of: 128, 256, 512, 1024. + You may specify one of: 128, 256, 512, 1024 and 64 for if --k32-bounded is enabled. + 1024 is not available for plots of k < 33. + + --k32-bounded : Create a bounded k32 plot. That is a plot that does not overflow entries + over 2^32; -t1, --temp1 : The temporary directory to use when plotting. *REQUIRED* diff --git a/src/plotdisk/DiskPlotter.h b/src/plotdisk/DiskPlotter.h index 2a1a1483..43e5681c 100644 --- a/src/plotdisk/DiskPlotter.h +++ b/src/plotdisk/DiskPlotter.h @@ -24,13 +24,15 @@ class DiskPlotter void Plot( const PlotRequest& req ); static bool GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPath2, size_t& tmpPath1Size, size_t& tmpPath2Size ); - static size_t GetRequiredSizeForBuckets( const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2 ); - static size_t GetRequiredSizeForBuckets( const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize ); + static size_t GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2 ); + static size_t GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize ); static void ParseCommandLine( CliParser& cli, Config& cfg ); static void PrintUsage(); +private: + void PlotBounded( const PlotRequest& req ); private: DiskPlotContext _cx; diff --git a/src/plotdisk/FileId.h b/src/plotdisk/FileId.h index 817b15bb..d0614f43 100644 --- a/src/plotdisk/FileId.h +++ b/src/plotdisk/FileId.h @@ -5,13 +5,13 @@ enum class FileId { None = 0, - // Bounded Phase 1: - Y, - META, - // Phase 1 fx, key, metadata FX0, FX1, + // Bounded Phase 1: + META0, META1, + INDEX0, INDEX1, + // Table 7 fx values F7, diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp new file mode 100644 index 00000000..379723d0 --- /dev/null +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -0,0 +1,97 @@ +#include "DiskPlotBounded.h" +#include "util/Util.h" +#include "util/StackAllocator.h" +#include "threading/MTJob.h" +#include "plotdisk/DiskPlotInfo.h" +#include "plotdisk/DiskPlotContext.h" +#include "plotdisk/DiskPlotConfig.h" +#include "plotdisk/DiskBufferQueue.h" +#include "plotting/PlotTools.h" + +#include "F1Bounded.inl" +#include "FxBounded.inl" + +//----------------------------------------------------------- +K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) + : _context( context ) + , _ioQueue( _ioQueue ) +{ + const uint32 numBuckets = context.numBuckets; + + // Open files + FileSetOptions opts = FileSetOptions::None; + FileSetInitData data = {}; + + opts = FileSetOptions::UseTemp2; + _ioQueue.InitFileSet( FileId::FX0 , "y0" , numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::FX1 , "y1" , numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::META0, "meta0", numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::META1, "meta1", numBuckets, opts, &data ); +} + +//----------------------------------------------------------- +K32BoundedPhase1::~K32BoundedPhase1() +{} + +//----------------------------------------------------------- +size_t K32BoundedPhase1::GetRequiredSize( const uint32 numBuckets, const size_t t1BlockSize, const size_t t2BlockSize ) +{ + switch( numBuckets ) + { + case 64 : return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); + case 128: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); + case 256: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); + case 512: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); + default: + break; + } + + Panic( "Invalid bucket count %u.", numBuckets ); + return 0; +} + +//----------------------------------------------------------- +void K32BoundedPhase1::Run() +{ + Log::Line( "Table 1: F1 generation" ); + + switch( _context.numBuckets ) + { + case 64 : RunWithBuckets<64 >(); break; + case 128: RunWithBuckets<128>(); break; + case 256: RunWithBuckets<256>(); break; + case 512: RunWithBuckets<512>(); break; + + default: + Fatal( "Invalid bucket count %u", _context.numBuckets ); + } +} + +//----------------------------------------------------------- +template +void K32BoundedPhase1::RunWithBuckets() +{ + RunF1<_numBuckets>(); + + for( TableId table = TableId::Table2; table <= TableId::Table7; table++ ) + { + RunFx<_numBuckets>( table ); + } +} + +//----------------------------------------------------------- +template +void K32BoundedPhase1::RunF1() +{ + StackAllocator allocator( _context.heapBuffer, _context.heapSize ); + K32BoundedF1<_numBuckets> f1( _context, allocator ); + f1.Run(); +} + +//----------------------------------------------------------- +template +void K32BoundedPhase1::RunFx( const TableId table ) +{ +} + + diff --git a/src/plotdisk/k32/DiskPlotBounded.h b/src/plotdisk/k32/DiskPlotBounded.h new file mode 100644 index 00000000..8527109f --- /dev/null +++ b/src/plotdisk/k32/DiskPlotBounded.h @@ -0,0 +1,29 @@ +#pragma once +#include "plotdisk/DiskPlotContext.h" + +// Bounded k32 disk plotter +class K32BoundedPhase1 +{ +public: + K32BoundedPhase1( DiskPlotContext& context ); + ~K32BoundedPhase1(); + + void Run(); + + static size_t GetRequiredSize( const uint32 numBuckets, const size_t t1BlockSize, const size_t t2BlockSize ); + +private: + + template + void RunWithBuckets(); + + template + void RunF1(); + + template + void RunFx( const TableId table ); + +private: + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; +}; \ No newline at end of file diff --git a/src/plotdisk/DiskPlotBounded.cpp b/src/plotdisk/k32/F1Bounded.inl similarity index 80% rename from src/plotdisk/DiskPlotBounded.cpp rename to src/plotdisk/k32/F1Bounded.inl index 9955bb58..07c57e90 100644 --- a/src/plotdisk/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/F1Bounded.inl @@ -1,4 +1,4 @@ -#include "DiskPlotBounded.h" +#pragma once #include "util/Util.h" #include "util/StackAllocator.h" #include "pos/chacha8.h" @@ -7,8 +7,6 @@ #include "plotdisk/DiskPlotContext.h" #include "plotdisk/DiskPlotConfig.h" #include "plotdisk/DiskBufferQueue.h" -#include "plotting/PlotTools.h" - template class K32BoundedF1 @@ -65,7 +63,7 @@ class K32BoundedF1 chacha8_get_keystream( &chacha, blockOffset, blockCount, (byte*)blocks.Ptr() ); // Write blocks to disk buckets - WriteToBuckets( self, blockCount, blockOffset * _entriesPerBlock ); + WriteToBuckets( bucket, self, blocks.Ptr(), blockCount, blockOffset * _entriesPerBlock ); blockOffset += _blocksPerBucket; // Offset to block start at next bucket } @@ -118,8 +116,8 @@ class K32BoundedF1 { memcpy( elementCounts.Ptr(), totalCounts, sizeof( totalCounts ) ); - _ioQueue.WriteBucketElementsT( FileId::Y , yEntries.Ptr(), elementCounts.Ptr() ); - _ioQueue.WriteBucketElementsT( FileId::META, xEntries.Ptr(), elementCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( FileId::FX1 , yEntries.Ptr(), elementCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( FileId::META1, xEntries.Ptr(), elementCounts.Ptr() ); _ioQueue.SignalFence( _writeFence, bucket+1 ); _ioQueue.CommitCommands(); @@ -156,47 +154,4 @@ class K32BoundedF1 uint32* _yEntries [2]; uint32* _xEntries [2]; uint32 _elementCounts[2][_numBuckets] = {}; -}; - -template -class K32BoundedPhase1 -{ - //----------------------------------------------------------- - K32BoundedPhase1( DiskPlotContext& context ) - : _context( context ) - , _ioQueue( _ioQueue ) - { - // Open files - FileSetOptions opts = FileSetOptions::None; - FileSetInitData data = {}; - - opts = FileSetOptions::UseTemp2; - _ioQueue.InitFileSet( FileId::Y , "y" , _numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::META, "meta", _numBuckets, opts, &data ); - } - - //----------------------------------------------------------- - void Run() - { - Log::Line( "Table 1: F1 generation" ); - - { - StackAllocator allocator( _context.heapBuffer, _context.heapSize ); - K32BoundedF1<_numBuckets> f1( _context, allocator ); - f1.Run(); - } - - Fx(); - } - - //----------------------------------------------------------- - void Fx() - { - - } - -private: - DiskPlotContext& _context; - DiskBufferQueue& _ioQueue; -}; - +}; \ No newline at end of file diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl new file mode 100644 index 00000000..0fb73e20 --- /dev/null +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -0,0 +1,202 @@ +#pragma once +#include "plotdisk/DiskPlotContext.h" +#include "plotdisk/DiskPlotConfig.h" +#include "plotdisk/DiskBufferQueue.h" +#include "util/StackAllocator.h" + + +class FxMatcherBounded +{ + using Job = AnonPrefixSumJob; + +public: + + //----------------------------------------------------------- + void Match( Job* self, const Span yEntries, Span pairs, const uint32 bucket ) + { + const uint32 id = self->JobId(); + + uint32 startIndex; + const uint32 groupCount = ScanGroups( self, yEntries, bucket, startIndex ); + ASSERT( groupCount > 0 ); + + const Span groupBoundaries( _groupIndices[id], groupCount ); + + uint32 matchCount = MatchGroups( self, + startIndex, + groupCount, + groupBoundaries, + yEntries, + pairs, + bucket, + _maxMatches ); + + _matchCounts[id] = matchCount; + + self->SyncThreads(); + } + +private: + + //----------------------------------------------------------- + uint32 ScanGroups( Job* self, const Span yEntries, const uint64 bucket, uint32& outStartIndex ) + { + const uint64 yMask = bucket << 32; + const uint32 id = self->JobId(); + + int64 _, offset; + GetThreadOffsets( self, (int64)yEntries.Length(), _, offset, _ ); + + const uint32* start = yEntries.Ptr(); + const uint32* entries = start + offset; + + // Find base start position + uint64 curGroup = *entries / kBC; + while( entries > start ) + { + if( entries[-1] / kBC != curGroup ) + break; + --entries; + } + + outStartIndex = (uint32)(uintptr_t)(entries - start); + + _startPositions[id] = entries; + self->SyncThreads(); + + const uint32* end = self->IsLastThread() ? yEntries.Ptr() + yEntries.Length() : _startPositions[id+1]; + + // Now scan for all groups + uint32* groupIndices = _groupIndices[id]; + uint32 groupCount = 0; + while( ++entries < end ) + { + const uint64 g = (yMask | (uint64)*entries) / kBC; + if( g != curGroup ) + { + ASSERT( groupCount < _maxMatches ); + groupIndices[groupCount++] = (uint32)(uintptr_t)(entries - start); + + ASSERT( g - curGroup > 1 || groupCount == 1 || groupIndices[groupCount-1] - groupIndices[groupCount-2] <= 350 ); + curGroup = g; + } + } + + self->SyncThreads(); + + // Add the end location of the last R group + if( self->IsLastThread() ) + { + ASSERT( groupCount < _maxMatches ); + groupIndices[groupCount] = (uint32)yEntries.Length(); + } + else + { + ASSERT( groupCount+1 < _maxMatches ); + groupIndices[groupCount++] = (uint32)(uintptr_t)(_startPositions[id+1] - start); + groupIndices[groupCount ] = _groupIndices[id+1][0]; + } + + return groupCount; + } + + //----------------------------------------------------------- + uint32 MatchGroups( Job* self, + const uint32 startIndex, + const uint32 groupCount, + const Span groupBoundaries, + const Span yEntries, + Span pairs, + const uint32 bucket, + const uint64 maxPairs ) + { + const uint64 bucketMask = ((uint64)bucket) << 32; + + uint32 pairCount = 0; + + uint8 rMapCounts [kBC]; + uint16 rMapIndices[kBC]; + + uint64 groupLStart = startIndex; + uint64 groupL = (bucketMask | (uint64)yEntries[groupLStart]) / kBC; + + for( uint32 i = 0; i < groupCount; i++ ) + { + const uint64 groupRStart = groupBoundaries[i]; + const uint64 groupR = (bucketMask | (uint64)yEntries[groupRStart]) / kBC; + const uint64 groupLEnd = groupRStart; + + if( groupR - groupL == 1 ) + { + // Groups are adjacent, calculate matches + const uint16 parity = groupL & 1; + const uint64 groupREnd = groupBoundaries[i+1]; + + const uint64 groupLRangeStart = groupL * kBC; + const uint64 groupRRangeStart = groupR * kBC; + + ASSERT( groupREnd - groupRStart <= 350 ); + ASSERT( groupLRangeStart == groupRRangeStart - kBC ); + + // Prepare a map of range kBC to store which indices from groupR are used + // For now just iterate our bGroup to find the pairs + + // #NOTE: memset(0) works faster on average than keeping a separate a clearing buffer + memset( rMapCounts, 0, sizeof( rMapCounts ) ); + + for( uint64 iR = groupRStart; iR < groupREnd; iR++ ) + { + uint64 localRY = (bucketMask | (uint64)yEntries[iR]) - groupRRangeStart; + ASSERT( (bucketMask | (uint64)yEntries[iR]) / kBC == groupR ); + + if( rMapCounts[localRY] == 0 ) + rMapIndices[localRY] = (uint16)( iR - groupRStart ); + + rMapCounts[localRY] ++; + } + + // For each group L entry + for( uint64 iL = groupLStart; iL < groupLEnd; iL++ ) + { + const uint64 yL = bucketMask | (uint64)yEntries[iL]; + const uint64 localL = yL - groupLRangeStart; + + // Iterate kExtraBitsPow = 1 << kExtraBits = 1 << 6 == 64 + // So iterate 64 times for each L entry. + for( int iK = 0; iK < kExtraBitsPow; iK++ ) + { + const uint64 targetR = L_targets[parity][localL][iK]; + + for( uint j = 0; j < rMapCounts[targetR]; j++ ) + { + const uint64 iR = groupRStart + rMapIndices[targetR] + j; + ASSERT( iL < iR ); + + // Add a new pair + Pair& pair = pairs[pairCount++]; + pair.left = (uint32)iL; + pair.right = (uint32)iR; + + ASSERT( pairCount <= maxPairs ); + if( pairCount == maxPairs ) + return pairCount; + } + } + } + } + // Else: Not an adjacent group, skip to next one. + + // Go to next group + groupL = groupR; + groupLStart = groupRStart; + } + + return pairCount; + } + +private: + uint32 _maxMatches; + const uint32* _startPositions[BB_DP_MAX_JOBS];// = { 0 }; + uint32 _matchCounts [BB_DP_MAX_JOBS];// = { 0 }; + uint32* _groupIndices [BB_DP_MAX_JOBS]; +}; diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl new file mode 100644 index 00000000..75a51ef6 --- /dev/null +++ b/src/plotdisk/k32/FxBounded.inl @@ -0,0 +1,532 @@ +#pragma once +#include "plotdisk/DiskPlotContext.h" +#include "plotdisk/DiskPlotConfig.h" +#include "plotdisk/DiskBufferQueue.h" +#include "util/StackAllocator.h" +#include "b3/blake3.h" + +typedef uint32 K32Meta1; +typedef uint64 K32Meta2; +struct K32Meta3 { uint32 m0, m1, m2; }; +struct K32Meta4 { uint64 m0, m1; }; +struct K32NoMeta {}; + +template +struct K32MetaType{}; + +template<> struct K32MetaType{ using In = K32NoMeta; using Out = K32Meta1; }; +template<> struct K32MetaType{ using In = K32Meta1; using Out = K32Meta2; }; +template<> struct K32MetaType{ using In = K32Meta2; using Out = K32Meta4; }; +template<> struct K32MetaType{ using In = K32Meta4; using Out = K32Meta4; }; +template<> struct K32MetaType{ using In = K32Meta4; using Out = K32Meta3; }; +template<> struct K32MetaType{ using In = K32Meta3; using Out = K32Meta2; }; +template<> struct K32MetaType{ using In = K32Meta2; using Out = K32NoMeta; }; + +template struct K32TYOut { using Type = uint64; }; +template<> struct K32TYOut { using Type = uint32; }; + +template +class DiskPlotFxBounded +{ + using TMeta = uint32; + using Job = AnonPrefixSumJob; + static constexpr uint32 _k = 32; + +public: + + //----------------------------------------------------------- + DiskPlotFxBounded( DiskPlotContext& context ) + : _context( context ) + , _ioQueue( *context.ioQueue ) + , _yReadFence ( context.fencePool->RequireFence() ) + , _metaReadFence ( context.fencePool->RequireFence() ) + , _indexReadFence( context.fencePool->RequireFence() ) + , _fxWriteFence ( context.fencePool->RequireFence() ) + , _pairWriteFence( context.fencePool->RequireFence() ) + , _mapWriteFence ( context.fencePool->RequireFence() ) + { + + } + + //----------------------------------------------------------- + ~DiskPlotFxBounded() + { + } + + //----------------------------------------------------------- + static size_t GetRequiredHeapSize( const size_t t1BlockSize, const size_t t2BlockSize ) + { + return 0; + } + + //----------------------------------------------------------- + void AllocateBuffers( IAllocator& allocator, const size_t t1BlockSize, const size_t t2BlockSize ) + { + const uint64 kEntryCount = 1ull << _k; + const uint64 entriesPerBucket = (uint64)( kEntryCount * BB_DP_XTRA_ENTRIES_PER_BUCKET ); + + _y[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _y[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _yTmp = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + + _sortKey = allocator.CAllocSpan( entriesPerBucket ); + + _meta[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _meta[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _metaTmp = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + + _index[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _index[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + + _map = allocator.CAllocSpan( entriesPerBucket ); + _pairs = allocator.CAllocSpan ( entriesPerBucket ); + + _pairsL = allocator.CAllocSpan( entriesPerBucket ); + _pairsR = allocator.CAllocSpan( entriesPerBucket ); + } + + // Generate fx for a whole table + //----------------------------------------------------------- + void Run() + { + StackAllocator allocator( _context.heapBuffer, _context.heapSize ); + AllocateBuffers( allocator, _context.tmp1BlockSize, _context.tmp2BlockSize ); + + Job::Run( *_context.threadPool, _context.fpThreadCount, [=]( Job* self ) { + RunMT( self ); + }); + + // Ensure all I/O has completed + Fence& fence = _context.fencePool->RequireFence(); + fence.Reset( 0 ); + _ioQueue.SignalFence( fence, 1 ); + _ioQueue.CommitCommands(); + fence.Wait(); + + _context.fencePool->RestoreAllFences(); + } + +private: + //----------------------------------------------------------- + void RunMT( Job* self ) + { +// using TYOut = typename K32TYOut::Type; + using TMetaIn = typename K32MetaType::In; + using TMetaOut = typename K32MetaType::Out; + const TableId lTable = rTable-1; + + ReadNextBucket( self, 0 ); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + ReadNextBucket( self, bucket + 1 ); // Read next bucket in background + + WaitForFence( self, _yReadFence, bucket ); + + const uint32 entryCount = _context.bucketCounts[(int)lTable][bucket]; + + Span yInput = _y [0].Slice( entryCount ); + Span indexInput = _index [0].Slice( entryCount ); + Span sortKey = _sortKey.Slice( entryCount ); + + SortY( self, entryCount, yInput.Ptr(), _y[1].Ptr(), sortKey.Ptr(), (uint32*)_metaTmp ); + + const uint32 matchCount = Match( self, yInput ); +// WritePairs( self ); + + // Generate and write map +// WaitForFence( self, _indexReadFence, bucket ); +// WriteMap( self, indexInput, sortKey ); + + // Sort meta on Y + WaitForFence( self, _metaReadFence, bucket ); + + Span metaTmp( (TMetaIn*)_meta[0].Ptr(), yInput.Length() ); + Span metaIn ( (TMetaIn*)_metaTmp.Ptr(), yInput.Length() ); + SortOnYKey( self, sortKey, metaTmp, metaIn ); + + // Gen fx + Span yOut = _yTmp; + Span metaOut( (TMetaIn*)metaTmp.Ptr(), matchCount ); + + GenFx( self, yInput, metaIn, pairs, yOut, metaOut, bucket ); + + + // #TODO: Write bucekt +// WriteEntries( self ) + } + } + + //----------------------------------------------------------- + void SortY( Job* self, const uint32 entryCount, uint32* ySrc, uint32* yTmp, uint32* sortKeySrc, uint32* sortKeyTmp ) + { + constexpr uint32 Radix = 256; + constexpr uint32 iterations = 4; + const uint32 shiftBase = 8; + + uint32 shift = 0; + + uint32 counts [Radix]; + uint32 prefixSum [Radix]; + uint32 totalCounts[Radix]; + + uint32 length, offset, _; + GetThreadOffsets( self, entryCount, length, offset, _ ); + + uint32* input = ySrc; + uint32* tmp = yTmp; + uint32* keyInput = sortKeySrc; + uint32* keyTmp = sortKeyTmp; + + + for( uint32 iter = 0; iter < iterations ; iter++, shift += shiftBase ) + { + // Zero-out the counts + memset( counts, 0, sizeof( counts ) ); + + // Grab our scan region from the input + const uint32* src = input + offset; + const uint32* keySrc = keyInput + offset; + + // Store the occurrences of the current 'digit' + for( uint64 i = 0; i < length; i++ ) + counts[(src[i] >> shift) & 0xFF]++; + + self->CalculatePrefixSum( Radix, counts, prefixSum, totalCounts ); + + for( uint64 i = length; i > 0; ) + { + const uint32 value = src[--i]; + const uint64 idx = (value >> shift) & 0xFF; + + const uint64 dstIdx = --prefixSum[idx]; + + tmp [dstIdx] = value; + keyTmp[dstIdx] = keySrc[i]; + } + + // Swap arrays + std::swap( input, tmp ); + std::swap( keyInput, keyTmp ); + self->SyncThreads(); + } + } + + //----------------------------------------------------------- + template + void SortOnYKey( Job* self, const Span key, const Span input, Span output ) + { + + } + + //----------------------------------------------------------- + void Match( Job* self, Span yEntries ) + { + + } + + //----------------------------------------------------------- + void WriteMap( Job* self, const Span indexInput, const Span sortKey ) + { + + } + + //----------------------------------------------------------- + void WritePairs( Job* self, const Span pairs, const int64 matchCount, const uint32 bucket ) + { + // #TOOD: Write pairs raw? Or bucket-relative? Maybe raw for now + } + + //----------------------------------------------------------- + template + void WriteEntries( Job* self, + const Span yIn, + const Span metaIn, + Span yOut, + Span metaOut, + Span indices, + const uint32 bucket ) + { + // Distribute to buckets + const uint32 logBuckets = bblog2( _numBuckets ); + static_assert( kExtraBits <= logBuckets ); + + const uint32 bucketShift = _k + kExtraBits - logBuckets; + const uint64 yMask = ( 1ull << bucketShift ) - 1; + + const int64 entryCount = (int64)yIn.Length(); + + uint32 counts [_numBuckets] = {}; + uint32 pfxSum [_numBuckets]; +// uint32 totalCounts[_numBuckets]; + uint32* bucketSlices = _context.bucketSlices[(int)rTable & 1][bucket]; + + for( int64 i = 0; i < entryCount; i++ ) + counts[yIn[i] >> bucketShift]++; + + self->CalculatePrefixSum( _numBuckets, counts, pfxSum, bucketSlices ); + + // Distribute to buckets + int64 offset, _; + GetThreadOffsets( self, (int64)yIn.Length(), _, offset, _ ); + + for( int64 i = 0; i < entryCount; i++ ) + { + const uint64 y = yIn[i]; + const uint32 dstIdx = --pfxSum[y >> bucketShift]; + + yOut [dstIdx] = (uint32)(y & yMask); + metaOut[dstIdx] = metaIn[i]; + indices[dstIdx] = (uint32)(offset + i); + } + + // Write to disk + if( self->BeginLockBlock() ) + { + // #NOTE: Should we wait per file? + if( bucket > 0 ) + _fxWriteFence.Wait( bucket, _tableIOWait ); + + const FileId yId = _yId [1]; + const FileId metaId = _metaId[1]; + const FileId idxId = _idxId [1]; + + _ioQueue.WriteBucketElementsT( yId , yOut.Ptr() , bucketSlices ); + _ioQueue.WriteBucketElementsT ( metaId, metaOut.Ptr(), bucketSlices ); + _ioQueue.WriteBucketElementsT( idxId , indices.Ptr(), bucketSlices ); + _ioQueue.SignalFence( _fxWriteFence, bucket+1 ); + _ioQueue.CommitCommands(); + } + self->EndLockBlock(); + } + + //----------------------------------------------------------- + void GenFx( Job* self, + const Span yIn, + const Span metaIn, + const Span pairs ) + { + using TYOut = typename K32TYOut::Type; + using TMetaIn = typename K32MetaType::In; + using TMetaOut = typename K32MetaType::Out; + +// TMetaOut + + const Span tableMetaIn ( (TMetaIn*)metaIn.Ptr(), metaIn.Length() ); + + // Output buffers +// Span tableMetaOut( (TMetaOut*)metaOut.Ptr(), metaOut.Length() ); + +// GenFx( self, yIn, tableMetaIn, pairs, ) + } + + //----------------------------------------------------------- + template + void GenFx( Job* self, + const Span yIn, + const Span metaIn, + const Span pairs, + Span yOut, + Span metaOut, + const uint32 bucket ) + { + constexpr size_t MetaInMulti = TableMetaIn ::Multiplier; + constexpr size_t MetaOutMulti = TableMetaOut::Multiplier; + static_assert( MetaInMulti != 0, "Invalid metaKMultiplier" ); + + + const uint32 k = 32; + const uint32 shiftBits = MetaOutMulti == 0 ? 0 : kExtraBits; // Table 7 (identified by 0 metadata output) we don't have k + kExtraBits sized y's. + // so we need to shift by 32 bits, instead of 26. + const uint32 ySize = k + kExtraBits; // = 38 + const uint32 yShift = 64 - (k + shiftBits); // = 26 or 32 + const size_t metaSize = k * MetaInMulti; + const size_t metaSizeLR = metaSize * 2; + + const size_t bufferSize = CDiv( ySize + metaSizeLR, 8 ); + + const uint32 id = self->JobId(); + const uint32 matchCount = _matchCount[id]; + const uint64 yMask = (uint64)bucket << 32; + + // Hashing + uint64 input [5]; // y + L + R + uint64 output[4]; // blake3 hashed output + + blake3_hasher hasher; + + static_assert( bufferSize <= sizeof( input ), "Invalid fx input buffer size." ); + + #if _DEBUG + uint64 prevY = yIn[pairs[0].left]; + uint64 prevLeft = 0; + #endif + + for( int64 i = 0; i < matchCount; i++ ) + { + const auto& pair = pairs[i]; + const uint32 left = pair.left; + const uint32 right = pair.right; + ASSERT( left < right ); + + const uint64 y = yMask | (uint64)yIn[left]; + + #if _DEBUG + ASSERT( y >= prevY ); + ASSERT( left >= prevLeft ); + prevY = y; + prevLeft = left; + #endif + + // Extract metadata + auto& mOut = metaOut[i]; + + if constexpr( MetaInMulti == 1 ) + { + const uint64 l = metaIn[left ]; + const uint64 r = metaIn[right]; + + input[0] = Swap64( y << 26 | l >> 6 ); + input[1] = Swap64( l << 58 | r << 26 ); + + // Metadata is just L + R of 8 bytes + if constexpr( MetaOutMulti == 2 ) + mOut = l << 32 | r; + } + else if constexpr( MetaInMulti == 2 ) + { + const uint64 l = metaIn[left ]; + const uint64 r = metaIn[right]; + + input[0] = Swap64( y << 26 | l >> 38 ); + input[1] = Swap64( l << 26 | r >> 38 ); + input[2] = Swap64( r << 26 ); + + // Metadata is just L + R again of 16 bytes + if constexpr( MetaOutMulti == 4 ) + { + mOut.m0 = l; + mOut.m1 = r; + } + } + else if constexpr( MetaInMulti == 3 ) + { + const uint64 l0 = (uint64)metaIn[left ].m0 | ( (uint64)metaIn[left ].m1 << 32 ); + const uint64 l1 = metaIn[left ].m2; + const uint64 r0 = (uint64)metaIn[right].m0 | ( (uint64)metaIn[right].m1 << 32 ); + const uint64 r1 = metaIn[right].m2; + + input[0] = Swap64( y << 26 | l0 >> 38 ); + input[1] = Swap64( l0 << 26 | l1 >> 6 ); + input[2] = Swap64( l1 << 58 | r0 >> 6 ); + input[3] = Swap64( r0 << 58 | r1 << 26 ); + } + else if constexpr( MetaInMulti == 4 ) + { + // const uint64 l0 = metaInA[left ]; + // const uint64 l1 = metaInB[left ]; + // const uint64 r0 = metaInA[right]; + // const uint64 r1 = metaInB[right]; + const Meta4 l = metaIn[left]; + const Meta4 r = metaIn[right]; + + input[0] = Swap64( y << 26 | l.m0 >> 38 ); + input[1] = Swap64( l.m0 << 26 | l.m1 >> 38 ); + input[2] = Swap64( l.m1 << 26 | r.m0 >> 38 ); + input[3] = Swap64( r.m0 << 26 | r.m1 >> 38 ); + input[4] = Swap64( r.m1 << 26 ); + } + + // Hash the input + blake3_hasher_init( &hasher ); + blake3_hasher_update( &hasher, input, bufferSize ); + blake3_hasher_finalize( &hasher, (uint8_t*)output, sizeof( output ) ); + + const uint64 f = Swap64( *output ) >> yShift; + yOut[i] = (TYOut)f; + + if constexpr ( MetaOutMulti == 2 && MetaInMulti == 3 ) + { + const uint64 h0 = Swap64( output[0] ); + const uint64 h1 = Swap64( output[1] ); + + mOut = h0 << ySize | h1 >> 26; + } + else if constexpr ( MetaOutMulti == 3 ) + { + const uint64 h0 = Swap64( output[0] ); + const uint64 h1 = Swap64( output[1] ); + const uint64 h2 = Swap64( output[2] ); + + uint64 m0 = h0 << ySize | h1 >> 26; + mOut.m0 = (uint32)m0; + mOut.m0 = (uint32)(m0 >> 32); + mOut.m2 = (uint32)( ((h1 << 6) & 0xFFFFFFC0) | h2 >> 58 ); + } + else if constexpr ( MetaOutMulti == 4 && MetaInMulti != 2 ) // In = 2 is calculated above with L + R + { + const uint64 h0 = Swap64( output[0] ); + const uint64 h1 = Swap64( output[1] ); + const uint64 h2 = Swap64( output[2] ); + + mOut.m0 = h0 << ySize | h1 >> 26; + mOut.m1 = h1 << 38 | h2 >> 26; + } + } + } + + //----------------------------------------------------------- + void ReadNextBucket( Job* self, const uint32 bucket ) + { + if( !self->IsControlThread() ) + return; + + + } + + //----------------------------------------------------------- + void WaitForFence( Job* self, Fence& fence, const uint32 bucket ) + { + if( self->BeginLockBlock() ) + fence.Wait( bucket+1, _tableIOWait ); + + self->EndLockBlock(); + } + +private: + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; + + // I/O + FileId _yId [2]; + FileId _idxId [2]; + FileId _metaId[2]; + + Span _y [2]; + Span _index[2]; + Span _meta [2]; + Span _map; + Span _pairsL; + Span _pairsR; + + // Temp working buffers + Span _yTmp; + Span _sortKey; + Span _metaTmp; + Span _pairs; + + // I/O Synchronization fences + Fence& _yReadFence; + Fence& _metaReadFence; + Fence& _indexReadFence; + Fence& _fxWriteFence; + Fence& _pairWriteFence; + Fence& _mapWriteFence; + + + // I/O wait accumulator + Duration _tableIOWait = Duration::zero(); + + // Matching + uint32 _matchCount[BB_DP_MAX_JOBS]; +}; diff --git a/src/util/Span.h b/src/util/Span.h index 1eb3c8f0..00984fe3 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -31,6 +31,12 @@ struct Span return this->values[index]; } + inline T& operator[]( int64 index ) const + { + ASSERT( index < length ); + return this->values[index]; + } + // size_t not the same as uint64 on clang. #ifdef __clang__ From 046df7b5a9e7a78b0546bd99c021bfa360d28ba9 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 10 May 2022 19:50:12 -0500 Subject: [PATCH 06/91] More work on bounded fp --- src/plotdisk/DiskPlotter.cpp | 72 +++++++++++++++++++++------------- src/plotdisk/DiskPlotter.h | 3 -- src/plotdisk/k32/FxBounded.inl | 28 ++++++++----- 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index df473d99..3eb4d823 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -41,6 +41,7 @@ DiskPlotter::DiskPlotter( const Config& cfg ) FatalIf( _cx.tmp1BlockSize < 8 || _cx.tmp2BlockSize < 8,"File system block size is too small.." ); const size_t heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize ); + ASSERT( heapSize ); _cfg = cfg; _cx.cfg = &_cfg; @@ -106,11 +107,12 @@ DiskPlotter::DiskPlotter( const Config& cfg ) Log::Error( "WARNING: Failed to bind NUMA memory on the cache." ); } } - + // Initialize our Thread Pool and IO Queue - const int32 ioThreadId = -1; // Force unbounded IO thread for now. We should bind it to the last used thread, of the max threads used... + const int32 ioThreadId = -1; // Force unpinned IO thread for now. We should bind it to the last used thread, of the max threads used... _cx.threadPool = new ThreadPool( sysLogicalCoreCount, ThreadPool::Mode::Fixed, gCfg.disableCpuAffinity ); _cx.ioQueue = new DiskBufferQueue( _cx.tmpPath, _cx.tmpPath2, gCfg.outputFolder, _cx.heapBuffer, _cx.heapSize, _cx.ioThreadCount, ioThreadId ); + _cx.fencePool = new FencePool( 8 ); // if( cfg.globalCfg->warmStart ) // #TODO: IMPORTANT: Remove this after testing @@ -142,6 +144,8 @@ void DiskPlotter::Plot( const PlotRequest& req ) memset( _cx.bucketSlices , 0, sizeof( _cx.bucketSlices ) ); // #TODO: Reset the rest of the state, including the heap & the ioQueue + const bool bounded = _cx.cfg->bounded; + Log::Line( "Started plot." ); auto plotTimer = TimerBegin(); @@ -151,42 +155,60 @@ void DiskPlotter::Plot( const PlotRequest& req ) _cx.ioQueue->OpenPlotFile( req.plotFileName, req.plotId, req.plotMemo, req.plotMemoSize ); - if( !_cx.cfg->bounded ) { - { - Log::Line( "Running Phase 1" ); - const auto timer = TimerBegin(); + Log::Line( "Running Phase 1" ); + const auto timer = TimerBegin(); + if( bounded ) + { + K32BoundedPhase1 phase1( _cx ); + phase1.Run(); + } + else + { DiskPlotPhase1 phase1( _cx ); phase1.Run(); - - const double elapsed = TimerEnd( timer ); - Log::Line( "Finished Phase 1 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); } - { - Log::Line( "Running Phase 2" ); - const auto timer = TimerBegin(); + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 1 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } + + { + Log::Line( "Running Phase 2" ); + const auto timer = TimerBegin(); + if( bounded ) + { + Fatal( "Phase 2 bounded not implemented." ); + } + else + { DiskPlotPhase2 phase2( _cx ); phase2.Run(); - - const double elapsed = TimerEnd( timer ); - Log::Line( "Finished Phase 2 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); } - { - Log::Line( "Running Phase 3" ); - const auto timer = TimerBegin(); + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 2 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } + { + Log::Line( "Running Phase 3" ); + const auto timer = TimerBegin(); + + if( bounded ) + { + Fatal( "Phase 3 bounded not implemented." ); + } + else + { DiskPlotPhase3 phase3( _cx ); phase3.Run(); - - const double elapsed = TimerEnd( timer ); - Log::Line( "Finished Phase 3 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); } - } + const double elapsed = TimerEnd( timer ); + Log::Line( "Finished Phase 3 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); + } Log::Line("Total plot I/O wait time: %.2lf seconds.", TicksToSeconds( _cx.ioWaitTime ) ); @@ -237,12 +259,6 @@ void DiskPlotter::Plot( const PlotRequest& req ) } } -//----------------------------------------------------------- -void DiskPlotter::PlotBounded( const PlotRequest& req ) -{ - -} - //----------------------------------------------------------- void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) { diff --git a/src/plotdisk/DiskPlotter.h b/src/plotdisk/DiskPlotter.h index 43e5681c..34c005e3 100644 --- a/src/plotdisk/DiskPlotter.h +++ b/src/plotdisk/DiskPlotter.h @@ -31,9 +31,6 @@ class DiskPlotter static void PrintUsage(); -private: - void PlotBounded( const PlotRequest& req ); - private: DiskPlotContext _cx; Config _cfg; diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 75a51ef6..9f173319 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -36,14 +36,14 @@ public: //----------------------------------------------------------- DiskPlotFxBounded( DiskPlotContext& context ) - : _context( context ) - , _ioQueue( *context.ioQueue ) - , _yReadFence ( context.fencePool->RequireFence() ) - , _metaReadFence ( context.fencePool->RequireFence() ) - , _indexReadFence( context.fencePool->RequireFence() ) - , _fxWriteFence ( context.fencePool->RequireFence() ) - , _pairWriteFence( context.fencePool->RequireFence() ) - , _mapWriteFence ( context.fencePool->RequireFence() ) + : _context ( context ) + , _ioQueue ( *context.ioQueue ) + , _yReadFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) + , _metaReadFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) + , _indexReadFence( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) + , _fxWriteFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) + , _pairWriteFence( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) + , _mapWriteFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) { } @@ -56,14 +56,22 @@ public: //----------------------------------------------------------- static size_t GetRequiredHeapSize( const size_t t1BlockSize, const size_t t2BlockSize ) { - return 0; + DiskPlotContext cx = {}; + + DiskPlotFxBounded instance( cx ); + + DummyAllocator allocator; + instance.AllocateBuffers( allocator, t1BlockSize, t2BlockSize ); + const size_t requiredSize = allocator.Size(); + + return requiredSize; } //----------------------------------------------------------- void AllocateBuffers( IAllocator& allocator, const size_t t1BlockSize, const size_t t2BlockSize ) { const uint64 kEntryCount = 1ull << _k; - const uint64 entriesPerBucket = (uint64)( kEntryCount * BB_DP_XTRA_ENTRIES_PER_BUCKET ); + const uint64 entriesPerBucket = (uint64)( kEntryCount / _numBuckets * BB_DP_XTRA_ENTRIES_PER_BUCKET ); _y[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _y[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); From e5f9ef19b5804e0bc754dbbc3f9d35033eca426d Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 11 May 2022 03:32:54 -0500 Subject: [PATCH 07/91] Working on packed interleaved reads. --- .vscode/launch.json | 13 ++-- src/plotdisk/DiskBufferQueue.cpp | 98 ++++++++++++++++++++++------ src/plotdisk/DiskBufferQueue.h | 33 +++++++--- src/plotdisk/DiskPlotter.cpp | 6 +- src/plotdisk/k32/DiskPlotBounded.cpp | 46 ++++++++++--- src/plotdisk/k32/F1Bounded.inl | 16 +++-- src/plotdisk/k32/FxBounded.inl | 2 +- 7 files changed, 164 insertions(+), 50 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index fc18bfa4..f05c82ec 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -77,20 +77,21 @@ "--show-memo", "diskplot", "-t1", "~/plot/tmp", - // "--f1-threads", "12", - "--f1-threads", "3", - "--fp-threads", "62", - // "--fp-threads", "50", + "--f1-threads", "12", + // "--f1-threads", "3", + // "--fp-threads", "62", + "--fp-threads", "48", // "--f1-threads", "7", // "--fp-threads", "7", - // "--cache", "200G", + "--cache", "200G", // "--cache", "96G", // "--cache", "106G", // "--cache", "64G", // "-s", - // "-b", "1024", + "--k32-bounded", + "-b", "64", "--c-threads", "26", "--p2-threads", "24", diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index d573ee4b..a811bae9 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -128,6 +128,12 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC fileSet.blockBuffer = nullptr; fileSet.options = options; + if( IsFlagSet( options, FileSetOptions::Interleaved ) ) + { + fileSet.sliceSizes.values = new Span[bucketCount]{ Span( new size_t[bucketCount]{}, bucketCount ) }; + fileSet.sliceSizes.length = bucketCount; + } + const bool isCachable = IsFlagSet( options, FileSetOptions::Cachable ) && optsData->cacheSize > 0; ASSERT( !isCachable || optsData ); @@ -553,7 +559,14 @@ void DiskBufferQueue::ExecuteCommand( Command& cmd ) #if DBG_LOG_ENABLE Log::Debug( "[DiskBufferQueue] ^ Cmd WriteBuckets: (%u) addr:0x%p", cmd.buckets.fileId, cmd.buckets.buffers ); #endif - CmdWriteBuckets( cmd ); + CmdWriteBuckets( cmd, 1 ); + break; + + case Command::WriteBucketElements: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd WriteBucketElements: (%u) addr:0x%p elementSz: %llu", cmd.buckets.fileId, cmd.buckets.buffers, (llu)cmd.bucketElements.elementSize ); + #endif + CmdWriteBuckets( cmd, cmd.bucketElements.elementSize ); break; case Command::WriteFile: @@ -645,13 +658,13 @@ void DiskBufferQueue::ExecuteCommand( Command& cmd ) } //----------------------------------------------------------- -void DiskBufferQueue::CmdWriteBuckets( const Command& cmd ) +void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementSize ) { - const FileId fileId = cmd.buckets.fileId; - const uint* sizes = cmd.buckets.sizes; - const byte* buffers = cmd.buckets.buffers; + const FileId fileId = cmd.buckets.fileId; + const uint* sizes = cmd.buckets.sizes; + const byte* buffers = cmd.buckets.buffers; + FileSet& fileSet = _files[(int)fileId]; - FileSet& fileSet = _files[(int)fileId]; // ASSERT( IsFlagSet( fileBuckets.files[0]->GetFileAccess(), FileAccess::ReadWrite ) ); const uint32 bucketCount = (uint32)fileSet.files.length; @@ -660,27 +673,40 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd ) // Single-threaded for now... We don't have file handles for all the threads yet! #if _DEBUG - const size_t blockSize = _blockSize; + const size_t blockSize = fileSet.files[0]->BlockSize(); #endif - const byte* buffer = buffers; + const byte* buffer = buffers; - // if( fileSet.transform ) - // { - // IIOTransform::TransformData data = { - // .buffer = (void*)buffers, - // .numBuckets = bucketCount, - // .bucketSizes = (uint32*)sizes - // }; - - // // #TODO: Profile time elapsed here - // fileSet.transform->Write( data ); - // } + if( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ) + { + // Write in interleaved mode, a whole bucket is written at once + // #TODO: Save interleaved sizes here + size_t writeSize = 0; + for( uint i = 0; i < bucketCount; i++ ) + { + const size_t sliceSize = sizes[i] * elementSize; + writeSize += sliceSize; + + // Save slice sizes for reading + fileSet.sliceSizes[fileSet.bucket][i] = sliceSize; + } + + + // #TODO: Do we have to round-up the size to block boundary? + ASSERT( writeSize / blockSize * blockSize == writeSize ); + + ASSERT( fileSet.bucket < fileSet.files.Length() ); + WriteToFile( *fileSet.files[fileSet.bucket], writeSize, buffer, (byte*)fileSet.blockBuffer, fileSet.name, fileSet.bucket ); + fileSet.bucket++; + fileSet.bucket %= fileSet.files.Length(); + return; + } for( uint i = 0; i < bucketCount; i++ ) { - const size_t bufferSize = sizes[i]; + const size_t bufferSize = sizes[i] * elementSize; // Only write up-to the block-aligned boundary. The caller is in charge of handling unlaigned data. ASSERT( bufferSize == bufferSize / blockSize * blockSize ); @@ -698,6 +724,38 @@ void DiskBufferQueue::CndWriteFile( const Command& cmd ) WriteToFile( *fileBuckets.files[cmd.file.bucket], cmd.file.size, cmd.file.buffer, (byte*)fileBuckets.blockBuffer, fileBuckets.name, cmd.file.bucket ); } +//----------------------------------------------------------- +void DiskBufferQueue::CmdReadBuckets( const Command& cmd ) +{ + const FileId fileId = cmd.buckets.fileId; + FileSet& fileSet = _files[(int)fileId]; + + byte* buffer = (byte*)cmd.buckets.buffers; + + ASSERT( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ); + ASSERT( fileSet.sliceSizes.Ptr() ); + ASSERT( fileSet.bucket == 0 ); // Should be in bucket 0 at this point // #NOTE: Perhaps have the user specify the bucket to read instead? + + const uint32 bucketCount = (uint32)fileSet.files.Length(); + + const Span sliceSizes = fileSet.sliceSizes[fileSet.bucket]; + const size_t blockSize = fileSet.files[0]->BlockSize(); + + for( uint32 bucket = 0; bucket < bucketCount; bucket++ ) + { + const size_t sliceSize = sliceSizes[bucket]; + const size_t alignedSize = RoundUpToNextBoundaryT( sliceSize, blockSize ); + + // #TODO: Always have to read into an aligned buffer. Figure this out + + ReadFromFile( *fileSet.files[bucket], alignedSize, buffer, nullptr, const size_t blockSize, const bool directIO, const char* fileName, const uint bucket ) + + } + + fileSet.bucket++; + fileSet.bucket %= fileSet.files.Length(); +} + //----------------------------------------------------------- void DiskBufferQueue::CmdReadFile( const Command& cmd ) { diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index 0ad4b587..6def7c42 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -18,12 +18,14 @@ enum FileSetOptions Cachable = 1 << 1, // Use a in-memory cache for the file UseTemp2 = 1 << 2, // Open the file set the high-frequency temp directory - Interleaved = 1 << 3, // Alternate bucket slices between interleaved and non-interleaved + Interleaved = 1 << 3, // Write in interleaved mode. That is all slices written to a single bucket. + BlockAlign = 1 << 4, // Only write in block-aligned segments. Keeping a block-sized buffer for left overs. // The last write flushes the whole block. // This can be very memory-costly on file systems with large block sizes // as interleaved buckets will need many block buffers. // This must be used with DirectIO. + }; ImplementFlagOps( FileSetOptions ); @@ -34,16 +36,19 @@ struct FileSetInitData size_t cacheSize = 0; // Cache size in bytes // Interleaved - size_t sliceSize = 0; // Maximum size of a bucket slice + // size_t sliceSize = 0; // Maximum size of a bucket slice }; struct FileSet { - const char* name = nullptr; - Span files; - void* blockBuffer = nullptr; // For FileSetOptions::BlockAlign - size_t sliceCapacity = 0; // (in bytes) For FileSetOptions::Interleaved - FileSetOptions options = FileSetOptions::None; + const char* name = nullptr; + Span files; + void* blockBuffer = nullptr; // For FileSetOptions::BlockAlign + // size_t sliceCapacity = 0; // (in bytes) For FileSetOptions::Interleaved + Span> sliceSizes; + uint32 bucket = 0; // Current bucket. Valid when writing in interleaved mode + FileSetOptions options = FileSetOptions::None; + }; class DiskBufferQueue @@ -174,6 +179,11 @@ class DiskBufferQueue void WriteFile( FileId id, uint bucket, const void* buffer, size_t size ); + void ReadBucketElements( const FileId id, void* buffer, size_t elementCount ); + + template + void ReadBucketElementsT( const FileId id, T* buffer ); + void ReadFile( FileId id, uint bucket, void* dstBuffer, size_t readSize ); void SeekFile( FileId id, uint bucket, int64 offset, SeekOrigin origin ); @@ -283,8 +293,9 @@ class DiskBufferQueue void ExecuteCommand( Command& cmd ); - void CmdWriteBuckets( const Command& cmd ); + void CmdWriteBuckets( const Command& cmd, const size_t elementSize ); void CndWriteFile( const Command& cmd ); + void CmdReadBuckets( const Command& cmd ); void CmdReadFile( const Command& cmd ); void CmdSeekBucket( const Command& cmd ); @@ -355,3 +366,9 @@ inline void DiskBufferQueue::WriteBucketElementsT( const FileId id, const T* buc WriteBucketElements( id, (void*)buckets, sizeof( T ), counts ); } +//----------------------------------------------------------- +template +inline void DiskBufferQueue::ReadBucketElementsT( const FileId id, T* buffer ) +{ + ReadBucketElements( id, buffer, sizeof( T ) ); +} \ No newline at end of file diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 3eb4d823..821efc57 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -146,15 +146,15 @@ void DiskPlotter::Plot( const PlotRequest& req ) const bool bounded = _cx.cfg->bounded; - Log::Line( "Started plot." ); - auto plotTimer = TimerBegin(); - _cx.plotId = req.plotId; _cx.plotMemo = req.plotMemo; _cx.plotMemoSize = req.plotMemoSize; _cx.ioQueue->OpenPlotFile( req.plotFileName, req.plotId, req.plotMemo, req.plotMemoSize ); + Log::Line( "Started plot." ); + auto plotTimer = TimerBegin(); + { Log::Line( "Running Phase 1" ); const auto timer = TimerBegin(); diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 379723d0..be3f3955 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -14,19 +14,25 @@ //----------------------------------------------------------- K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) : _context( context ) - , _ioQueue( _ioQueue ) + , _ioQueue( *_context.ioQueue ) { const uint32 numBuckets = context.numBuckets; // Open files - FileSetOptions opts = FileSetOptions::None; - FileSetInitData data = {}; + FileSetOptions opts = FileSetOptions::None | FileSetOptions::Interleaved; + + if( !context.cfg->noTmp2DirectIO ) + opts |= FileSetOptions::DirectIO; - opts = FileSetOptions::UseTemp2; - _ioQueue.InitFileSet( FileId::FX0 , "y0" , numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::FX1 , "y1" , numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::META0, "meta0", numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::META1, "meta1", numBuckets, opts, &data ); + FileSetInitData data = {}; + opts |= FileSetOptions::UseTemp2; + + _ioQueue.InitFileSet( FileId::FX0 , "y0" , numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::FX1 , "y1" , numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::INDEX0, "index0", numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::INDEX1, "index1", numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::META0 , "meta0" , numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::META1 , "meta1" , numBuckets, opts, &data ); } //----------------------------------------------------------- @@ -83,9 +89,33 @@ void K32BoundedPhase1::RunWithBuckets() template void K32BoundedPhase1::RunF1() { + Log::Line( "Generating f1..." ); + auto timer = TimerBegin(); + StackAllocator allocator( _context.heapBuffer, _context.heapSize ); K32BoundedF1<_numBuckets> f1( _context, allocator ); f1.Run(); + + _context.entryCounts[(int)TableId::Table1] = 1ull << 32; + + double elapsed = TimerEnd( timer ); + Log::Line( "Finished f1 generation in %.2lf seconds. ", elapsed ); + Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _context.ioQueue->IOBufferWaitTime() ); + + #if BB_IO_METRICS_ON + const double writeThroughput = _context.ioQueue->GetAverageWriteThroughput(); + const auto& writes = _context.ioQueue->GetWriteMetrics(); + + Log::Line( " Table 1 I/O Metrics:" ); + Log::Line( " Average write throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + writeThroughput BtoMB, writeThroughput / 1000000.0, writeThroughput BtoGB, writeThroughput / 1000000000.0 ); + Log::Line( " Total size written: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + (double)writes.size BtoMB, (double)writes.size / 1000000.0, (double)writes.size BtoGB, (double)writes.size / 1000000000.0 ); + Log::Line( " Total write commands: %llu.", (llu)writes.count ); + Log::Line( "" ); + + _context.ioQueue->ClearWriteMetrics(); + #endif } //----------------------------------------------------------- diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 07c57e90..5c19e6ad 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -35,10 +35,10 @@ public: const uint32 blockBufferSize = blockCount * threadCount * _entriesPerBlock; _blockBuffer = allocator.CAllocSpan( blockBufferSize ); - _yEntries[0] = allocator.CAlloc( _entriesPerBucket ); - _yEntries[1] = allocator.CAlloc( _entriesPerBucket ); - _xEntries[0] = allocator.CAlloc( _entriesPerBucket ); - _xEntries[1] = allocator.CAlloc( _entriesPerBucket ); + _yEntries[0] = allocator.CAlloc( _entriesPerBucket, context.tmp2BlockSize ); + _yEntries[1] = allocator.CAlloc( _entriesPerBucket, context.tmp2BlockSize ); + _xEntries[0] = allocator.CAlloc( _entriesPerBucket, context.tmp2BlockSize ); + _xEntries[1] = allocator.CAlloc( _entriesPerBucket, context.tmp2BlockSize ); } //----------------------------------------------------------- @@ -68,6 +68,14 @@ public: blockOffset += _blocksPerBucket; // Offset to block start at next bucket } }); + + Fence& fence = _context.fencePool->RequireFence(); + fence.Reset( 0 ); + _ioQueue.SignalFence( fence, 1 ); + _ioQueue.CommitCommands(); + fence.Wait( 1 ); + + _context.fencePool->RestoreAllFences(); } private: diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 9f173319..617bd0fb 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -157,7 +157,7 @@ private: Span yOut = _yTmp; Span metaOut( (TMetaIn*)metaTmp.Ptr(), matchCount ); - GenFx( self, yInput, metaIn, pairs, yOut, metaOut, bucket ); + // GenFx( self, yInput, metaIn, pairs, yOut, metaOut, bucket ); // #TODO: Write bucekt From 1481a9386bb2dbf0d52f31e205a3b51512ca7090 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 11 May 2022 20:15:16 -0500 Subject: [PATCH 08/91] Work on adding padded prefix sum for multi-slice single-writes --- src/plotdisk/DiskBufferQueue.cpp | 8 ++-- src/plotdisk/k32/DiskPlotBounded.cpp | 2 +- src/plotdisk/k32/F1Bounded.inl | 50 +++++++++++++--------- src/threading/MTJob.h | 64 +++++++++++++++++++++++++--- src/util/Span.h | 6 +++ 5 files changed, 101 insertions(+), 29 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index a811bae9..abc06a85 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -130,8 +130,9 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC if( IsFlagSet( options, FileSetOptions::Interleaved ) ) { - fileSet.sliceSizes.values = new Span[bucketCount]{ Span( new size_t[bucketCount]{}, bucketCount ) }; - fileSet.sliceSizes.length = bucketCount; + fileSet.sliceSizes.SetTo( new Span[bucketCount], bucketCount ); + for( uint32 i = 0; i < bucketCount; i++ ) + fileSet.sliceSizes[i].SetTo( new size_t[bucketCount]{}, bucketCount ); } const bool isCachable = IsFlagSet( options, FileSetOptions::Cachable ) && optsData->cacheSize > 0; @@ -681,7 +682,6 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS if( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ) { // Write in interleaved mode, a whole bucket is written at once - // #TODO: Save interleaved sizes here size_t writeSize = 0; for( uint i = 0; i < bucketCount; i++ ) { @@ -748,7 +748,7 @@ void DiskBufferQueue::CmdReadBuckets( const Command& cmd ) // #TODO: Always have to read into an aligned buffer. Figure this out - ReadFromFile( *fileSet.files[bucket], alignedSize, buffer, nullptr, const size_t blockSize, const bool directIO, const char* fileName, const uint bucket ) + // ReadFromFile( *fileSet.files[bucket], alignedSize, buffer, nullptr, const size_t blockSize, const bool directIO, const char* fileName, const uint bucket ) } diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index be3f3955..784ca86a 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -122,6 +122,6 @@ void K32BoundedPhase1::RunF1() template void K32BoundedPhase1::RunFx( const TableId table ) { -} +} diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 5c19e6ad..7502f3d7 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -13,21 +13,31 @@ class K32BoundedF1 { using Job = AnonPrefixSumJob; - static constexpr uint32 _k = 32; - static constexpr uint64 _kEntryCount = 1ull << _k; - static constexpr uint32 _entriesPerBucket = (uint32)( _kEntryCount / _numBuckets ); - static constexpr uint32 _entriesPerBlock = kF1BlockSize / sizeof( uint32 ); - static constexpr uint32 _blocksPerBucket = _entriesPerBucket * sizeof( uint32 ) / kF1BlockSize; + static constexpr uint32 _k = 32; + static constexpr uint64 _kEntryCount = 1ull << _k; + static constexpr uint32 _entriesPerBucket = (uint32)( _kEntryCount / _numBuckets ); + static constexpr uint32 _entriesPerBlock = kF1BlockSize / sizeof( uint32 ); + static constexpr uint32 _blocksPerBucket = _entriesPerBucket * sizeof( uint32 ) / kF1BlockSize; + static constexpr uint32 _maxEntriesPerSlice = _entriesPerBucket / _numBuckets; + static constexpr uint32 _maxEntriesPerIOBucket = ((uint32)(_maxEntriesPerSlice * BB_DP_XTRA_ENTRIES_PER_BUCKET) * _numBuckets ); public: //----------------------------------------------------------- K32BoundedF1( DiskPlotContext& context, IAllocator& allocator ) - : _context( context ) - , _ioQueue( *context.ioQueue ) + : _context ( context ) + , _ioQueue ( *context.ioQueue ) , _writeFence( context.fencePool->RequireFence() ) { const uint32 threadCount = context.f1ThreadCount; + // We need to add padding to our buffers because each slice need to have + // their start location block-aligned for reading. + // #OR: We could do it on the IOQueue where we could keep a block + // left-over per bucket file. + // Which, when we do a multi-bucket slice read we would + // save the left over? We can't because we need to make sure the + // buffer we're given is not aligned + // Get the maximum block count per thread uint32 blockCount, _; GetThreadOffsets( threadCount-1, threadCount, _blocksPerBucket, blockCount, _, _ ); @@ -35,10 +45,10 @@ public: const uint32 blockBufferSize = blockCount * threadCount * _entriesPerBlock; _blockBuffer = allocator.CAllocSpan( blockBufferSize ); - _yEntries[0] = allocator.CAlloc( _entriesPerBucket, context.tmp2BlockSize ); - _yEntries[1] = allocator.CAlloc( _entriesPerBucket, context.tmp2BlockSize ); - _xEntries[0] = allocator.CAlloc( _entriesPerBucket, context.tmp2BlockSize ); - _xEntries[1] = allocator.CAlloc( _entriesPerBucket, context.tmp2BlockSize ); + _yEntries[0] = allocator.CAllocSpan( _maxEntriesPerIOBucket, context.tmp2BlockSize ); + _yEntries[1] = allocator.CAllocSpan( _maxEntriesPerIOBucket, context.tmp2BlockSize ); + _xEntries[0] = allocator.CAllocSpan( _maxEntriesPerIOBucket, context.tmp2BlockSize ); + _xEntries[1] = allocator.CAllocSpan( _maxEntriesPerIOBucket, context.tmp2BlockSize ); } //----------------------------------------------------------- @@ -87,6 +97,7 @@ private: const uint32 bucketBits = bblog2( _numBuckets ); const uint32 bucketBitShift = _k - bucketBits; const uint32 kMinusKExtraBits = _k - kExtraBits; + const uint32 fsBlockSize = (uint32)_ioQueue.BlockSize( FileId::FX1 ); // Distribute to buckets uint32 counts [_numBuckets] = { 0 }; @@ -98,7 +109,7 @@ private: for( uint32 i = 0; i < entryCount; i++ ) counts[Swap32( blocks[i] ) >> bucketBitShift]++; - self->CalculatePrefixSum( _numBuckets, counts, pfxSum, totalCounts ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, totalCounts ); const uint32 yBits = _k + kExtraBits - bucketBits; const uint32 yMask = (uint32)(( 1ull << yBits ) - 1); @@ -112,6 +123,7 @@ private: uint32 y = Swap32( blocks[i] ); const uint32 dst = --pfxSum[y >> bucketBitShift]; const uint32 x = xStart + i; + ASSERT( dst < _maxEntriesPerIOBucket ); y = ( ( y << kExtraBits ) | ( x >> kMinusKExtraBits ) ) & yMask; @@ -146,9 +158,8 @@ private: self->EndLockBlock(); } - const uint32 entriesPerBucket = (uint32)( _kEntryCount / _numBuckets ); - yEntries = Span( _yEntries[bucket & 1], entriesPerBucket ); - xEntries = Span( _xEntries[bucket & 1], entriesPerBucket ); + yEntries = _yEntries[bucket & 1]; + xEntries = _xEntries[bucket & 1]; totalCounts = Span( _elementCounts[bucket & 1], _numBuckets ); } @@ -159,7 +170,8 @@ private: Span _blockBuffer; // I/O buffers - uint32* _yEntries [2]; - uint32* _xEntries [2]; - uint32 _elementCounts[2][_numBuckets] = {}; -}; \ No newline at end of file + Span _yEntries [2]; + Span _xEntries [2]; + uint32 _elementCounts[2][_numBuckets] = {}; +}; + diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index 5d83130b..cd97efc9 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -2,6 +2,7 @@ #include "Config.h" #include "threading/ThreadPool.h" +#include "util/Util.h" #include #if _DEBUG #include "util/Log.h" @@ -371,16 +372,48 @@ struct PrefixSumJob : public MTJob uint32 bucketSize, TCount* counts, TCount* pfxSum, - TCount* bucketCounts ); + TCount* bucketCounts ) + { + CalculatePrefixSumImpl<0>( bucketSize, counts, pfxSum, bucketCounts ); + } + + template + inline void CalculateBlockAlignedPrefixSum( + uint32 bucketSize, + uint32 blockSize, + TCount* counts, + TCount* pfxSum, + TCount* bucketCounts ) + { + const uint32 entrySize = (uint32)sizeof( EntryType1 ); + const uint32 entriesPerBlock = blockSize / entrySize; + ASSERT( entriesPerBlock * entrySize == blockSize ); + + CalculatePrefixSumImpl<1>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock ); + } + +private: + template + inline void CalculatePrefixSumImpl( + uint32 bucketSize, + TCount* counts, + TCount* pfxSum, + TCount* bucketCounts, + const uint32* entriesPerBlocks = nullptr, + TCount* pfxSum2 = nullptr + ); }; //----------------------------------------------------------- template -inline void PrefixSumJob::CalculatePrefixSum( +template +inline void PrefixSumJob::CalculatePrefixSumImpl( uint32 bucketSize, TCount* counts, TCount* pfxSum, - TCount* bucketCounts ) + TCount* bucketCounts, + const uint32* entriesPerBlocks, + TCount* pfxSum2 ) { const uint32 jobId = this->JobId(); const uint32 jobCount = this->JobCount(); @@ -389,8 +422,9 @@ inline void PrefixSumJob::CalculatePrefixSum( this->SyncThreads(); // Add up all of the jobs counts + // Add-up all thread's bucket counts memset( pfxSum, 0, sizeof( TCount ) * bucketSize ); - + for( uint32 i = 0; i < jobCount; i++ ) { const TCount* tCounts = this->GetJob( i ).counts; @@ -400,11 +434,31 @@ inline void PrefixSumJob::CalculatePrefixSum( } // If we're the control thread, retain the total bucket count - if( this->IsControlThread() ) + if( this->IsControlThread() && bucketCounts != nullptr ) { memcpy( bucketCounts, pfxSum, sizeof( TCount ) * bucketSize ); } + uint32 alignedEntryIndex = 0; + + if constexpr ( AlignEntryCount > 0 ) + { + // We now need to add padding to the total counts to ensure the starting + // location of each slice is block aligned. + const uint32 entriesPerBlock = entriesPerBlocks[alignedEntryIndex++]; + + for( uint32 i = bucketSize-1; i > 0; i-- ) + { + // Round-up the previous bucket's entry count to be block aligned, + // then we can add that as padding to this bucket's prefix count + // ensuring the first entry of the slice falls onto the start of a block. + const uint32 entryCount = pfxSum[i-1]; + const uint32 alignedEntryCount = CDivT( entryCount, entriesPerBlock ) * entriesPerBlock; + const uint32 padding = alignedEntryCount - entryCount; + pfxSum[i] += padding; + } + } + // Calculate the prefix sum for( uint32 i = 1; i < bucketSize; i++ ) pfxSum[i] += pfxSum[i-1]; diff --git a/src/util/Span.h b/src/util/Span.h index 00984fe3..d4f3ee91 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -15,6 +15,12 @@ struct Span , length( length ) {} + inline void SetTo( T* values, const size_t length ) + { + this->values = values; + this->length = length; + } + inline size_t Length() const { return length; } inline T* Ptr() const { return values; } From 0a6e56ca5dd588216445eef2124f0a3294165437 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 13 May 2022 07:40:24 -0500 Subject: [PATCH 09/91] Trying to implement aligned slices still --- src/plotdisk/DiskBufferQueue.cpp | 27 ++++++++++++++++------ src/plotdisk/DiskBufferQueue.h | 11 +++++---- src/plotdisk/DiskPlotConfig.h | 1 + src/plotdisk/k32/F1Bounded.inl | 39 +++++++++++++++++++------------- src/threading/MTJob.h | 38 +++++++++++++++++++++++-------- 5 files changed, 79 insertions(+), 37 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index abc06a85..4049c129 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -577,6 +577,14 @@ void DiskBufferQueue::ExecuteCommand( Command& cmd ) CndWriteFile( cmd ); break; + case Command::ReadBucket: + #if DBG_LOG_ENABLE + Log::Debug( "[DiskBufferQueue] ^ Cmd ReadBucket: (%u) bucket:%u sz:%llu addr:0x%p", cmd.file.fileId, cmd.file.bucket, cmd.file.size, cmd.file.buffer ); + #endif + CmdReadBucket( cmd ); + break; + + case Command::ReadFile: #if DBG_LOG_ENABLE Log::Debug( "[DiskBufferQueue] ^ Cmd ReadFile: (%u) bucket:%u sz:%llu addr:0x%p", cmd.file.fileId, cmd.file.bucket, cmd.file.size, cmd.file.buffer ); @@ -673,11 +681,11 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS Log::Debug( " >>> Write 0x%p", buffers ); // Single-threaded for now... We don't have file handles for all the threads yet! - #if _DEBUG - const size_t blockSize = fileSet.files[0]->BlockSize(); - #endif + const size_t blockSize = fileSet.files[0]->BlockSize(); + // #if _DEBUG + // #endif - const byte* buffer = buffers; + const byte* buffer = buffers; if( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ) { @@ -686,7 +694,12 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS for( uint i = 0; i < bucketCount; i++ ) { const size_t sliceSize = sizes[i] * elementSize; - writeSize += sliceSize; + + // Slices must be block-aligned + // #TODO: This should be set as an option... + const size_t alignedSliceSize = CDivT( sliceSize, blockSize ) * blockSize; + + writeSize += alignedSliceSize; // Save slice sizes for reading fileSet.sliceSizes[fileSet.bucket][i] = sliceSize; @@ -725,7 +738,7 @@ void DiskBufferQueue::CndWriteFile( const Command& cmd ) } //----------------------------------------------------------- -void DiskBufferQueue::CmdReadBuckets( const Command& cmd ) +void DiskBufferQueue::CmdReadBucket( const Command& cmd ) { const FileId fileId = cmd.buckets.fileId; FileSet& fileSet = _files[(int)fileId]; @@ -746,7 +759,7 @@ void DiskBufferQueue::CmdReadBuckets( const Command& cmd ) const size_t sliceSize = sliceSizes[bucket]; const size_t alignedSize = RoundUpToNextBoundaryT( sliceSize, blockSize ); - // #TODO: Always have to read into an aligned buffer. Figure this out + // #TODO: Always have to read into an aligned buffer. Figure this out... // ReadFromFile( *fileSet.files[bucket], alignedSize, buffer, nullptr, const size_t blockSize, const bool directIO, const char* fileName, const uint bucket ) diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index 6def7c42..6224cf96 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -13,10 +13,10 @@ class IIOTransform; enum FileSetOptions { - None = 0, - DirectIO = 1 << 0, // Use direct IO/unbuffered file IO - Cachable = 1 << 1, // Use a in-memory cache for the file - UseTemp2 = 1 << 2, // Open the file set the high-frequency temp directory + None = 0, + DirectIO = 1 << 0, // Use direct IO/unbuffered file IO + Cachable = 1 << 1, // Use a in-memory cache for the file + UseTemp2 = 1 << 2, // Open the file set the high-frequency temp directory Interleaved = 1 << 3, // Write in interleaved mode. That is all slices written to a single bucket. @@ -61,6 +61,7 @@ class DiskBufferQueue WriteFile, WriteBuckets, WriteBucketElements, + ReadBucket, ReadFile, SeekFile, SeekBucket, @@ -295,7 +296,7 @@ class DiskBufferQueue void CmdWriteBuckets( const Command& cmd, const size_t elementSize ); void CndWriteFile( const Command& cmd ); - void CmdReadBuckets( const Command& cmd ); + void CmdReadBucket( const Command& cmd ); void CmdReadFile( const Command& cmd ); void CmdSeekBucket( const Command& cmd ); diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 250163e8..e5eadd66 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -10,6 +10,7 @@ #define BB_DP_ENTRIES_PER_BUCKET ( ( 1ull << _K ) / BB_DP_BUCKET_COUNT ) #define BB_DP_XTRA_ENTRIES_PER_BUCKET 1.1 +#define BB_DP_ENTRY_SLICE_MULTIPLIER 1.07 #define BB_DP_MAX_BC_GROUP_PER_BUCKET 300000 // There's around 284,190 groups per bucket (of bucket size 64) diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 7502f3d7..742aa4a1 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -18,9 +18,8 @@ class K32BoundedF1 static constexpr uint32 _entriesPerBucket = (uint32)( _kEntryCount / _numBuckets ); static constexpr uint32 _entriesPerBlock = kF1BlockSize / sizeof( uint32 ); static constexpr uint32 _blocksPerBucket = _entriesPerBucket * sizeof( uint32 ) / kF1BlockSize; - static constexpr uint32 _maxEntriesPerSlice = _entriesPerBucket / _numBuckets; - static constexpr uint32 _maxEntriesPerIOBucket = ((uint32)(_maxEntriesPerSlice * BB_DP_XTRA_ENTRIES_PER_BUCKET) * _numBuckets ); - + static constexpr uint32 _maxEntriesPerSlice = ((uint32)(_entriesPerBucket / _numBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); + public: //----------------------------------------------------------- K32BoundedF1( DiskPlotContext& context, IAllocator& allocator ) @@ -30,13 +29,16 @@ public: { const uint32 threadCount = context.f1ThreadCount; - // We need to add padding to our buffers because each slice need to have - // their start location block-aligned for reading. - // #OR: We could do it on the IOQueue where we could keep a block - // left-over per bucket file. - // Which, when we do a multi-bucket slice read we would - // save the left over? We can't because we need to make sure the - // buffer we're given is not aligned + // We need to pad our slices to block size + const uint32 blockSize = _ioQueue.BlockSize( FileId::FX1 ); + const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( _maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries + const uint32 entriesPerBucketAligned = entriesPerSliceAligned * _numBuckets; // in subsequent slices + ASSERT( entriesPerBucketAligned >= _entriesPerBucket ); + + #if _DEBUG + _maxEntriesPerIOBucket = entriesPerBucketAligned; + #endif + // Get the maximum block count per thread uint32 blockCount, _; @@ -45,10 +47,10 @@ public: const uint32 blockBufferSize = blockCount * threadCount * _entriesPerBlock; _blockBuffer = allocator.CAllocSpan( blockBufferSize ); - _yEntries[0] = allocator.CAllocSpan( _maxEntriesPerIOBucket, context.tmp2BlockSize ); - _yEntries[1] = allocator.CAllocSpan( _maxEntriesPerIOBucket, context.tmp2BlockSize ); - _xEntries[0] = allocator.CAllocSpan( _maxEntriesPerIOBucket, context.tmp2BlockSize ); - _xEntries[1] = allocator.CAllocSpan( _maxEntriesPerIOBucket, context.tmp2BlockSize ); + _yEntries[0] = allocator.CAllocSpan( entriesPerBucketAligned, context.tmp2BlockSize ); + _yEntries[1] = allocator.CAllocSpan( entriesPerBucketAligned, context.tmp2BlockSize ); + _xEntries[0] = allocator.CAllocSpan( entriesPerBucketAligned, context.tmp2BlockSize ); + _xEntries[1] = allocator.CAllocSpan( entriesPerBucketAligned, context.tmp2BlockSize ); } //----------------------------------------------------------- @@ -100,16 +102,17 @@ private: const uint32 fsBlockSize = (uint32)_ioQueue.BlockSize( FileId::FX1 ); // Distribute to buckets - uint32 counts [_numBuckets] = { 0 }; + uint32 counts [_numBuckets] = {}; uint32 pfxSum [_numBuckets]; uint32 totalCounts[_numBuckets]; + uint32 offsets [_numBuckets] = {}; // memset( counts, 0, sizeof( counts ) ); for( uint32 i = 0; i < entryCount; i++ ) counts[Swap32( blocks[i] ) >> bucketBitShift]++; - self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, totalCounts ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, totalCounts, offsets ); const uint32 yBits = _k + kExtraBits - bucketBits; const uint32 yMask = (uint32)(( 1ull << yBits ) - 1); @@ -173,5 +176,9 @@ private: Span _yEntries [2]; Span _xEntries [2]; uint32 _elementCounts[2][_numBuckets] = {}; + +#if _DEBUG + uint32 _maxEntriesPerIOBucket; +#endif }; diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index cd97efc9..6605c448 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -128,7 +128,6 @@ struct MTJobRunner ThreadPool& _pool; }; - struct AnonMTJob : public MTJob { std::function* func; @@ -383,13 +382,15 @@ struct PrefixSumJob : public MTJob uint32 blockSize, TCount* counts, TCount* pfxSum, - TCount* bucketCounts ) + TCount* bucketCounts, + TCount* offsets, + TCount* alignedTotalCounts ) { const uint32 entrySize = (uint32)sizeof( EntryType1 ); const uint32 entriesPerBlock = blockSize / entrySize; ASSERT( entriesPerBlock * entrySize == blockSize ); - CalculatePrefixSumImpl<1>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock ); + CalculatePrefixSumImpl<1>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock, offsets ); } private: @@ -399,8 +400,10 @@ struct PrefixSumJob : public MTJob TCount* counts, TCount* pfxSum, TCount* bucketCounts, - const uint32* entriesPerBlocks = nullptr, - TCount* pfxSum2 = nullptr + const uint32* entriesPerBlocks = nullptr, + TCount* offsets = nullptr, + TCount* alignedTotalCounts = nullptr, + TCount* pfxSum2 = nullptr ); }; @@ -413,6 +416,8 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( TCount* pfxSum, TCount* bucketCounts, const uint32* entriesPerBlocks, + TCount* offsets, + TCount* alignedTotalCounts, TCount* pfxSum2 ) { const uint32 jobId = this->JobId(); @@ -452,11 +457,26 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( // Round-up the previous bucket's entry count to be block aligned, // then we can add that as padding to this bucket's prefix count // ensuring the first entry of the slice falls onto the start of a block. - const uint32 entryCount = pfxSum[i-1]; - const uint32 alignedEntryCount = CDivT( entryCount, entriesPerBlock ) * entriesPerBlock; - const uint32 padding = alignedEntryCount - entryCount; - pfxSum[i] += padding; + const uint32 prevEntryCount = pfxSum[i-1] + offsets[i-1]; + const uint32 prevAlignedEntryCount = CDivT( prevEntryCount, entriesPerBlock ) * entriesPerBlock; + const uint32 paddingFromPrevBucket = prevAlignedEntryCount - prevEntryCount; + + // Calculate our next offset before updating our total count, which is the the entries + // our last block occupies, if its not full. + const uint32 offset = offsets[i]; + const uint32 entryCount = pfxSum[i] + offset; + const uint32 blockCount = CDivT( entryCount, entriesPerBlock ); ASSERT( blockCount > 0 ); + + offsets[i] = entryCount - ( blockCount - 1 ) * entriesPerBlock; // Update our offset for the next round + pfxSum[i] += paddingFromPrevBucket + offset; // Update our total count for alignment purposes } + + // Add the offset to the first bucket slice as well + pfxSum[0] += offsets[0]; + + const uint32 b0Aligned = CDivT( pfxSum[0], entriesPerBlock ) * entriesPerBlock; + const uint32 b0Padding = b0Aligned - pfxSum[0]; + offsets[0] = (entriesPerBlock - b0Padding) & (entriesPerBlock - 1); } // Calculate the prefix sum From 7472370124d7a676d5f01729454c24eafd648b06 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 13 May 2022 21:39:01 -0500 Subject: [PATCH 10/91] Working on a test for aligned slice I/O --- src/plotdisk/DiskBufferQueue.cpp | 17 +++-- src/plotdisk/k32/F1Bounded.inl | 15 +++-- src/threading/MTJob.h | 10 +-- tests/TestBucketSliceRead.cpp | 109 +++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 tests/TestBucketSliceRead.cpp diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 4049c129..6ac45146 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -691,21 +691,22 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS { // Write in interleaved mode, a whole bucket is written at once size_t writeSize = 0; + for( uint i = 0; i < bucketCount; i++ ) { const size_t sliceSize = sizes[i] * elementSize; - + // Slices must be block-aligned // #TODO: This should be set as an option... const size_t alignedSliceSize = CDivT( sliceSize, blockSize ) * blockSize; - - writeSize += alignedSliceSize; + ASSERT( sliceSize == alignedSliceSize ); + writeSize += sliceSize; - // Save slice sizes for reading + // Save slice sizes for reading? + // #TODO: Remove this? Have the user specify it, since they have a different alignment...? fileSet.sliceSizes[fileSet.bucket][i] = sliceSize; } - // #TODO: Do we have to round-up the size to block boundary? ASSERT( writeSize / blockSize * blockSize == writeSize ); @@ -716,11 +717,11 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS fileSet.bucket %= fileSet.files.Length(); return; } - + for( uint i = 0; i < bucketCount; i++ ) { const size_t bufferSize = sizes[i] * elementSize; - + // Only write up-to the block-aligned boundary. The caller is in charge of handling unlaigned data. ASSERT( bufferSize == bufferSize / blockSize * blockSize ); WriteToFile( *fileSet.files[i], bufferSize, buffer, (byte*)fileSet.blockBuffer, fileSet.name, i ); @@ -811,10 +812,8 @@ inline void DiskBufferQueue::WriteToFile( IStream& file, size_t size, const byte while( size ) { - ssize_t sizeWritten = file.Write( buffer, size ); - if( sizeWritten < 1 ) { const int err = file.GetError(); diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 742aa4a1..96067181 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -102,17 +102,18 @@ private: const uint32 fsBlockSize = (uint32)_ioQueue.BlockSize( FileId::FX1 ); // Distribute to buckets - uint32 counts [_numBuckets] = {}; - uint32 pfxSum [_numBuckets]; - uint32 totalCounts[_numBuckets]; - uint32 offsets [_numBuckets] = {}; + uint32 counts [_numBuckets] = {}; + uint32 pfxSum [_numBuckets]; + uint32 totalCounts [_numBuckets]; + uint32 offsets [_numBuckets] = {}; + uint32 totalWriteCounts[_numBuckets]; // memset( counts, 0, sizeof( counts ) ); for( uint32 i = 0; i < entryCount; i++ ) counts[Swap32( blocks[i] ) >> bucketBitShift]++; - self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, totalCounts, offsets ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, totalCounts, offsets, totalWriteCounts ); const uint32 yBits = _k + kExtraBits - bucketBits; const uint32 yMask = (uint32)(( 1ull << yBits ) - 1); @@ -139,8 +140,8 @@ private: { memcpy( elementCounts.Ptr(), totalCounts, sizeof( totalCounts ) ); - _ioQueue.WriteBucketElementsT( FileId::FX1 , yEntries.Ptr(), elementCounts.Ptr() ); - _ioQueue.WriteBucketElementsT( FileId::META1, xEntries.Ptr(), elementCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( FileId::FX1 , yEntries.Ptr(), totalWriteCounts ); + _ioQueue.WriteBucketElementsT( FileId::META1, xEntries.Ptr(), totalWriteCounts ); _ioQueue.SignalFence( _writeFence, bucket+1 ); _ioQueue.CommitCommands(); diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index 6605c448..bd21bd3e 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -390,7 +390,7 @@ struct PrefixSumJob : public MTJob const uint32 entriesPerBlock = blockSize / entrySize; ASSERT( entriesPerBlock * entrySize == blockSize ); - CalculatePrefixSumImpl<1>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock, offsets ); + CalculatePrefixSumImpl<1>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock, offsets, alignedTotalCounts ); } private: @@ -469,14 +469,16 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( offsets[i] = entryCount - ( blockCount - 1 ) * entriesPerBlock; // Update our offset for the next round pfxSum[i] += paddingFromPrevBucket + offset; // Update our total count for alignment purposes + alignedTotalCounts[i] = blockCount * entriesPerBlock; } // Add the offset to the first bucket slice as well pfxSum[0] += offsets[0]; - const uint32 b0Aligned = CDivT( pfxSum[0], entriesPerBlock ) * entriesPerBlock; - const uint32 b0Padding = b0Aligned - pfxSum[0]; - offsets[0] = (entriesPerBlock - b0Padding) & (entriesPerBlock - 1); + const uint32 b0BlockCount = CDivT( pfxSum[0], entriesPerBlock ); ASSERT( b0BlockCount > 0 ); + + offsets[0] = pfxSum[0] - (b0BlockCount - 1) * entriesPerBlock; + alignedTotalCounts[0] = b0BlockCount * entriesPerBlock; } // Calculate the prefix sum diff --git a/tests/TestBucketSliceRead.cpp b/tests/TestBucketSliceRead.cpp new file mode 100644 index 00000000..87e96096 --- /dev/null +++ b/tests/TestBucketSliceRead.cpp @@ -0,0 +1,109 @@ +#include "TestUtil.h" +#include "io/BucketStream.h" +#include "io/HybridStream.h" +#include "util/Util.h" +#include "threading/MTJob.h" +#include "pos/chacha8.h" +#include "ChiaConsts.h" +#include "plotdisk/DiskBufferQueue.h" + +const uint32 k = 24; +const uint32 entryCount = 1ull << k; + +Span entriesSrc; +Span entriesWrite; +Span entriesRead ; + +const FileId fileId = FileId::FX0; +DiskBufferQueue* ioQueue = nullptr; +Fence fence; + + +//----------------------------------------------------------- +template +void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) +{ + Log::Line( "Testing buckets: %u", _numBuckets ); + + fence.Reset( 0 ); + + using Job = AnonPrefixSumJob; + Job::Run( pool, threadCount, [=]( Job* self ) { + + const uint32 entriesPerBucket = entryCount / _numBuckets; + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 bucketShift = k - bucketBits; + + uint32 count, offset, end; + GetThreadOffsets( self, entriesPerBucket, count, offset, end ); + + // Distribute to buckets + for( uint32 i = offset; end < entriesPerBucket; end++ ) + { + const uint32 v = entriesSrc[i]; + entriesWrite[v >> bucketShift] = v; + } + + uint32 counts [_numBuckets] = {}; + uint32 pfxSum [_numBuckets]; + uint32 totalCounts [_numBuckets]; + uint32 offsets [_numBuckets] = {}; + uint32 alignedWriteCounts[_numBuckets]; + + memcpy( offsets, _offsets, sizeof( offsets ) ); + + self->CalculateBlockAlignedPrefixSum( _numBuckets, fileId, counts, pfxSum, totalCounts, offsets, alignedWriteCounts ); + + // Write to disk + if( self->BeginLockBlock() ) + { + ioQueue->WriteBucketElements( fileId, entriesWrite.Ptr(), sizeof( uint32 ), alignedWriteCounts ); + ioQueue->SeekBucket( fileId, 0, SeekOrigin::Begin ); + ioQueue->CommitCommands(); + ioQueue->SignalFence( fence ); + + // Wait for the writes to finish + fence.Wait(); + + // Read from disk + + } + self->EndLockBlock(); + + // Save offsets for the next run? + // memcpy( _offsets, offsets, sizeof( offsets ) ); + }); +} + +//----------------------------------------------------------- +TEST_CASE( "bucket-slice-write", "[unit-core]" ) +{ + SysHost::InstallCrashHandler(); + + const uint32 entriesPerBucket = entryCount / 64; + + entriesSrc = bbcvirtallocboundednuma_span( entriesPerBucket ); + entriesWrite = bbcvirtallocboundednuma_span( entriesPerBucket ); + entriesRead = bbcvirtallocboundednuma_span( entriesPerBucket ); + + // for( uint32 i = 0; i < entriesPerBucket; i++ ) + // entriesTmp[i] = i; + + byte key[32] = { 1 }; + { + auto bytes = HexStringToBytes( "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835" ); + memcpy( key+1, bytes.data() + 1, 31 ); + } + + Log::Line( "ChaCha gen..." ); + const uint32 blockCount = ( entriesPerBucket * sizeof( uint32 ) ) / kF1BlockSize; + + chacha8_ctx chacha; + chacha8_keysetup( &chacha, key, 256, nullptr ); + chacha8_get_keystream( &chacha, 0, blockCount, (byte*)entriesSrc.Ptr() ); + + const uint32 maxThreads = SysHost::GetLogicalCPUCount(); + ThreadPool pool( maxThreads ); + + RunForBuckets<64>( pool, maxThreads ); +} \ No newline at end of file From 310e296a4c1ab8edf78b1f225d7ee770dfd3702d Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 14 May 2022 08:26:01 -0500 Subject: [PATCH 11/91] Working on bucket slice reading --- .vscode/launch.json | 3 +- src/plotdisk/DiskBufferQueue.cpp | 65 +++++++++--- src/plotdisk/DiskBufferQueue.h | 20 +++- src/threading/MTJob.h | 12 +-- src/util/Span.h | 18 ++++ tests/TestBucketSliceRead.cpp | 169 +++++++++++++++++++++---------- 6 files changed, 209 insertions(+), 78 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index f05c82ec..b9af7da2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -165,7 +165,8 @@ // "FxSort" // "FxDisk" // "F1Disk" - "PairsAndMap" + // "PairsAndMap" + "bucket-slice-write" ] } diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 6ac45146..d3a4b1f2 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -359,6 +359,15 @@ void DiskBufferQueue::WriteFile( FileId id, uint bucket, const void* buffer, siz cmd->file.bucket = bucket; } +//----------------------------------------------------------- +void DiskBufferQueue::ReadBucketElements( const FileId id, Span& buffer, const size_t elementSize ) +{ + Command* cmd = GetCommandObject( Command::ReadBucket ); + cmd->readBucket.buffer = &buffer; + cmd->readBucket.elementSize = elementSize; + cmd->readBucket.fileId = id; +} + //----------------------------------------------------------- void DiskBufferQueue::ReadFile( FileId id, uint bucket, void* dstBuffer, size_t readSize ) { @@ -579,7 +588,7 @@ void DiskBufferQueue::ExecuteCommand( Command& cmd ) case Command::ReadBucket: #if DBG_LOG_ENABLE - Log::Debug( "[DiskBufferQueue] ^ Cmd ReadBucket: (%u) bucket:%u sz:%llu addr:0x%p", cmd.file.fileId, cmd.file.bucket, cmd.file.size, cmd.file.buffer ); + Log::Debug( "[DiskBufferQueue] ^ Cmd ReadBucket: (%u) bucket:%u esz:%llu", cmd.readBucket.fileId, cmd.readBucket.elementSize ); #endif CmdReadBucket( cmd ); break; @@ -697,10 +706,10 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS const size_t sliceSize = sizes[i] * elementSize; // Slices must be block-aligned - // #TODO: This should be set as an option... + // #TODO: This should be set as an option...? Or should we always align? const size_t alignedSliceSize = CDivT( sliceSize, blockSize ) * blockSize; - ASSERT( sliceSize == alignedSliceSize ); - writeSize += sliceSize; + // ASSERT( sliceSize == alignedSliceSize ); + writeSize += alignedSliceSize; // Save slice sizes for reading? // #TODO: Remove this? Have the user specify it, since they have a different alignment...? @@ -741,29 +750,55 @@ void DiskBufferQueue::CndWriteFile( const Command& cmd ) //----------------------------------------------------------- void DiskBufferQueue::CmdReadBucket( const Command& cmd ) { - const FileId fileId = cmd.buckets.fileId; + const FileId fileId = cmd.readBucket.fileId; FileSet& fileSet = _files[(int)fileId]; - byte* buffer = (byte*)cmd.buckets.buffers; + Span& buffer = const_cast&>( reinterpret_cast&>( cmd.readBucket.buffer ) ); - ASSERT( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ); + ASSERT( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ); // #TODO: Read bucket is just a single file read without this flag ASSERT( fileSet.sliceSizes.Ptr() ); - ASSERT( fileSet.bucket == 0 ); // Should be in bucket 0 at this point // #NOTE: Perhaps have the user specify the bucket to read instead? - + // ASSERT( fileSet.bucket == 0 ); // Should be in bucket 0 at this point // #NOTE: Perhaps have the user specify the bucket to read instead? + + const bool directIO = IsFlagSet( fileSet.options, FileSetOptions::DirectIO ); const uint32 bucketCount = (uint32)fileSet.files.Length(); - const Span sliceSizes = fileSet.sliceSizes[fileSet.bucket]; const size_t blockSize = fileSet.files[0]->BlockSize(); - for( uint32 bucket = 0; bucket < bucketCount; bucket++ ) + auto readBuffer = buffer.Slice(); + auto blockBuffer = Span( (byte*)fileSet.blockBuffer, 0 ); + size_t sizeRead = 0; + + Span tempBlock; + + for( uint32 slice = 0; slice < bucketCount; slice++ ) { - const size_t sliceSize = sliceSizes[bucket]; - const size_t alignedSize = RoundUpToNextBoundaryT( sliceSize, blockSize ); + const size_t sliceSize = sliceSizes[slice]; + const size_t alignedSize = CDivT( sliceSize, blockSize ) * blockSize; // Sizes are written aligned, and must also be read aligned + + ReadFromFile( *fileSet.files[fileSet.bucket], alignedSize, readBuffer.Ptr(), nullptr, blockSize, directIO, fileSet.name, fileSet.bucket ); - // #TODO: Always have to read into an aligned buffer. Figure this out... + // Replace the temp block we just overwrote, if we have one + if( tempBlock.Length() ) + tempBlock.CopyTo( readBuffer ); - // ReadFromFile( *fileSet.files[bucket], alignedSize, buffer, nullptr, const size_t blockSize, const bool directIO, const char* fileName, const uint bucket ) + // Copy offset temporarily (only if sliceSize is not block-aligned) + if( sliceSize < alignedSize ) + { + const auto offset = alignedSize - blockSize; ASSERT( sliceSize > offset ); + const size_t lastBlockSize = sliceSize - offset; + + readBuffer = readBuffer.Slice( offset ); + tempBlock = blockBuffer.Slice( 0, lastBlockSize ); + + readBuffer.CopyTo( tempBlock, lastBlockSize ); + } + else + { + readBuffer = readBuffer.Slice( alignedSize ); // We just read everything block aligned + tempBlock = {}; + } + sizeRead += sliceSize; } fileSet.bucket++; diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index 6224cf96..084d24df 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -18,7 +18,9 @@ enum FileSetOptions Cachable = 1 << 1, // Use a in-memory cache for the file UseTemp2 = 1 << 2, // Open the file set the high-frequency temp directory - Interleaved = 1 << 3, // Write in interleaved mode. That is all slices written to a single bucket. + + // BatchedSlices = 1 << 3, // Write bucket slices in a batch, instead of a slice per each bucket. + Interleaved = 1 << 3, // Write in interleaved mode. That is all slices written to a single bucket. BlockAlign = 1 << 4, // Only write in block-aligned segments. Keeping a block-sized buffer for left overs. // The last write flushes the whole block. @@ -101,6 +103,12 @@ class DiskBufferQueue uint32 elementSize; } bucketElements; + struct { + Span* buffer; + FileId fileId; + uint32 elementSize; + } readBucket; + struct { FileId fileId; @@ -180,10 +188,10 @@ class DiskBufferQueue void WriteFile( FileId id, uint bucket, const void* buffer, size_t size ); - void ReadBucketElements( const FileId id, void* buffer, size_t elementCount ); + void ReadBucketElements( const FileId id, Span& buffer, const size_t elementSize ); template - void ReadBucketElementsT( const FileId id, T* buffer ); + void ReadBucketElementsT( const FileId id, Span& buffer ); void ReadFile( FileId id, uint bucket, void* dstBuffer, size_t readSize ); @@ -326,6 +334,8 @@ class DiskBufferQueue // Handles to all files needed to create a plot FileSet _files[(size_t)FileId::_COUNT]; size_t _blockSize = 0; + byte* _t1BlockBuffer = nullptr; // Temporary temp1 dir block buffer user for slice reading + byte* _t2BlockBuffer = nullptr; // Temporary temp2 dir block buffer user for slice reading char* _filePathBuffer = nullptr; // For creating file sets @@ -369,7 +379,7 @@ inline void DiskBufferQueue::WriteBucketElementsT( const FileId id, const T* buc //----------------------------------------------------------- template -inline void DiskBufferQueue::ReadBucketElementsT( const FileId id, T* buffer ) +inline void DiskBufferQueue::ReadBucketElementsT( const FileId id, Span& buffer ) { - ReadBucketElements( id, buffer, sizeof( T ) ); + ReadBucketElements( id, reinterpret_cast&>( buffer ), sizeof( T ) ); } \ No newline at end of file diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index bd21bd3e..aaaf9b0f 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -438,12 +438,6 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( pfxSum[j] += tCounts[j]; } - // If we're the control thread, retain the total bucket count - if( this->IsControlThread() && bucketCounts != nullptr ) - { - memcpy( bucketCounts, pfxSum, sizeof( TCount ) * bucketSize ); - } - uint32 alignedEntryIndex = 0; if constexpr ( AlignEntryCount > 0 ) @@ -480,6 +474,12 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( offsets[0] = pfxSum[0] - (b0BlockCount - 1) * entriesPerBlock; alignedTotalCounts[0] = b0BlockCount * entriesPerBlock; } + + // If we're the control thread, retain the total bucket count + if( this->IsControlThread() && bucketCounts != nullptr ) + { + memcpy( bucketCounts, pfxSum, sizeof( TCount ) * bucketSize ); + } // Calculate the prefix sum for( uint32 i = 1; i < bucketSize; i++ ) diff --git a/src/util/Span.h b/src/util/Span.h index d4f3ee91..b59a6e7e 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -74,9 +74,27 @@ struct Span return Slice( index, length - index ); } + inline Span Slice() const + { + return Slice( 0, length ); + } + inline Span Slice( const uint32 index ) const { return Slice( (size_t)index ); } inline Span Slice( const int64 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } inline Span Slice( const int32 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } + + inline void CopyTo( Span& other, const size_t size ) const + { + ASSERT( length >= size ); + ASSERT( other.length >= size ); + + memcpy( other.values, values, size ); + } + + inline void CopyTo( Span& other ) const + { + CopyTo( other, length ); + } }; typedef Span ByteSpan; diff --git a/tests/TestBucketSliceRead.cpp b/tests/TestBucketSliceRead.cpp index 87e96096..57243309 100644 --- a/tests/TestBucketSliceRead.cpp +++ b/tests/TestBucketSliceRead.cpp @@ -6,73 +6,139 @@ #include "pos/chacha8.h" #include "ChiaConsts.h" #include "plotdisk/DiskBufferQueue.h" +#include "algorithm/RadixSort.h" const uint32 k = 24; const uint32 entryCount = 1ull << k; -Span entriesSrc; -Span entriesWrite; -Span entriesRead ; +Span entriesRef; +Span entriesTmp; +Span entriesBuffer; +// Span entriesRead ; +const char* tmpDir = "/home/harold/plot/tmp"; const FileId fileId = FileId::FX0; DiskBufferQueue* ioQueue = nullptr; Fence fence; +using Job = AnonPrefixSumJob; + +auto seed = HexStringToBytes( "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835" ); + + +//----------------------------------------------------------- +void GenerateRandomEntries( ThreadPool& pool ) +{ + ASSERT( seed.size() == 32 ); + + entriesRef = bbcvirtallocboundednuma_span( entryCount ); + entriesTmp = bbcvirtallocboundednuma_span( entryCount ); + + Job::Run( pool, [=]( Job* self ){ + + const uint32 entriesPerBlock = kF1BlockSize / sizeof( uint32 ); + const uint32 blockCount = entryCount / entriesPerBlock; + ASSERT( blockCount * entriesPerBlock == entryCount ); + + uint32 count, offset, end; + GetThreadOffsets( self, blockCount, count, offset, end ); + + byte key[32] = { 1 }; + memcpy( key+1, seed.data()+1, 31 ); + + chacha8_ctx chacha; + chacha8_keysetup( &chacha, key, 256, nullptr ); + chacha8_get_keystream( &chacha, offset, count, (byte*)entriesRef.Ptr() + offset * kF1BlockSize ); + + const uint32 mask = ( 1u << k ) - 1; + offset *= entriesPerBlock; + end *= entriesPerBlock; + for( uint32 i = offset; i < end; i++ ) + entriesRef[i] &= mask; + }); +} //----------------------------------------------------------- template void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) { Log::Line( "Testing buckets: %u", _numBuckets ); - + + // Fence* fence = &_fence; fence.Reset( 0 ); + fence.Signal(); - using Job = AnonPrefixSumJob; - Job::Run( pool, threadCount, [=]( Job* self ) { + Job::Run( pool, threadCount, [=, &fence]( Job* self ) { const uint32 entriesPerBucket = entryCount / _numBuckets; const uint32 bucketBits = bblog2( _numBuckets ); const uint32 bucketShift = k - bucketBits; + const size_t blockSize = ioQueue->BlockSize( fileId ); + + Span srcEntries = entriesRef.Slice(); uint32 count, offset, end; GetThreadOffsets( self, entriesPerBucket, count, offset, end ); - // Distribute to buckets - for( uint32 i = offset; end < entriesPerBucket; end++ ) - { - const uint32 v = entriesSrc[i]; - entriesWrite[v >> bucketShift] = v; - } - - uint32 counts [_numBuckets] = {}; uint32 pfxSum [_numBuckets]; uint32 totalCounts [_numBuckets]; uint32 offsets [_numBuckets] = {}; uint32 alignedWriteCounts[_numBuckets]; - memcpy( offsets, _offsets, sizeof( offsets ) ); - - self->CalculateBlockAlignedPrefixSum( _numBuckets, fileId, counts, pfxSum, totalCounts, offsets, alignedWriteCounts ); - - // Write to disk - if( self->BeginLockBlock() ) + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { - ioQueue->WriteBucketElements( fileId, entriesWrite.Ptr(), sizeof( uint32 ), alignedWriteCounts ); - ioQueue->SeekBucket( fileId, 0, SeekOrigin::Begin ); - ioQueue->CommitCommands(); - ioQueue->SignalFence( fence ); + uint32 counts[_numBuckets] = {}; + + // Count entries / bucket + for( uint32 i = offset; i < end; i++ ) + counts[srcEntries[i] >> bucketShift]++; + + // Prefix sum + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, totalCounts, offsets, alignedWriteCounts ); + + // Distribute entries to buckets + for( uint32 i = offset; i < end; i++ ) + { + const uint32 e = srcEntries[i]; + const uint32 dst = --pfxSum[e >> bucketShift]; + + entriesBuffer[dst] = e; + } + + // Write to disk + if( self->BeginLockBlock() ) + { + ioQueue->WriteBucketElements( fileId, entriesBuffer.Ptr(), sizeof( uint32 ), totalCounts ); + ioQueue->SignalFence( fence ); + ioQueue->CommitCommands(); + fence.Wait(); + } + self->EndLockBlock(); + + // Write next bucket slices + srcEntries = srcEntries.Slice( entriesPerBucket ); + } + }); - // Wait for the writes to finish - fence.Wait(); + // Sort the reference entries + RadixSort256::Sort( pool, entriesRef.Ptr(), entriesTmp.Ptr(), entriesRef.Length() ); - // Read from disk + ioQueue->SeekBucket( fileId, 0, SeekOrigin::Begin ); + ioQueue->CommitCommands(); + fence.Reset(); - } - self->EndLockBlock(); + // Read back entries and validate them + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + auto readBuffer = entriesBuffer.Slice(); - // Save offsets for the next run? - // memcpy( _offsets, offsets, sizeof( offsets ) ); - }); + ioQueue->ReadBucketElementsT( fileId, readBuffer ); + ioQueue->SignalFence( fence ); + ioQueue->CommitCommands(); + fence.Wait(); + + // RadixSort256::Sort( pool, entriesRef.Ptr(), entriesTmp.Ptr(), entriesRef.Length() ); + } } //----------------------------------------------------------- @@ -80,30 +146,31 @@ TEST_CASE( "bucket-slice-write", "[unit-core]" ) { SysHost::InstallCrashHandler(); - const uint32 entriesPerBucket = entryCount / 64; - - entriesSrc = bbcvirtallocboundednuma_span( entriesPerBucket ); - entriesWrite = bbcvirtallocboundednuma_span( entriesPerBucket ); - entriesRead = bbcvirtallocboundednuma_span( entriesPerBucket ); + const uint32 maxThreads = SysHost::GetLogicalCPUCount(); + ThreadPool pool( maxThreads ); - // for( uint32 i = 0; i < entriesPerBucket; i++ ) - // entriesTmp[i] = i; + const FileSetOptions flags = FileSetOptions::DirectIO | FileSetOptions::Cachable | FileSetOptions::Interleaved; + FileSetInitData opts; + opts.cacheSize = (size_t)( sizeof( uint32 ) * entryCount * 1.25); + opts.cache = bbvirtallocboundednuma( opts.cacheSize ); - byte key[32] = { 1 }; - { - auto bytes = HexStringToBytes( "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835" ); - memcpy( key+1, bytes.data() + 1, 31 ); - } + byte dummyHeap = 1; + ioQueue = new DiskBufferQueue( tmpDir, tmpDir, tmpDir, &dummyHeap, dummyHeap, 1 ); + ioQueue->InitFileSet( fileId, "test-slices", 64, flags, &opts ); - Log::Line( "ChaCha gen..." ); - const uint32 blockCount = ( entriesPerBucket * sizeof( uint32 ) ) / kF1BlockSize; + // Allocate buffers + const uint32 minBuckets = 64; + const uint32 blockSize = (uint32)ioQueue->BlockSize( fileId ); + const uint32 entriesPerBucket = entryCount / minBuckets; + const uint32 maxEntriesPerSlice = ((uint32)(entriesPerBucket / minBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); + const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries + const uint32 entriesPerBucketAligned = entriesPerSliceAligned * minBuckets; // in subsequent slices - chacha8_ctx chacha; - chacha8_keysetup( &chacha, key, 256, nullptr ); - chacha8_get_keystream( &chacha, 0, blockCount, (byte*)entriesSrc.Ptr() ); + entriesBuffer = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); + // entriesRead = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); - const uint32 maxThreads = SysHost::GetLogicalCPUCount(); - ThreadPool pool( maxThreads ); + Log::Line( "ChaCha gen..." ); + GenerateRandomEntries( pool ); RunForBuckets<64>( pool, maxThreads ); } \ No newline at end of file From 984510133311eea8e65f7bdb25ece62bf83f4a81 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 14 May 2022 21:42:37 -0500 Subject: [PATCH 12/91] Progress on batched slices. Not validating, yet, though. --- src/plotdisk/DiskBufferQueue.cpp | 112 ++++++++++++++++--------------- src/plotdisk/DiskBufferQueue.h | 33 +++++---- src/threading/MTJob.h | 12 ++-- src/util/Span.h | 23 ++++++- tests/TestBucketSliceRead.cpp | 60 +++++++++++++++-- 5 files changed, 154 insertions(+), 86 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index d3a4b1f2..76948e7e 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -326,27 +326,30 @@ void DiskBufferQueue::FinishPlot( Fence& fence ) } //----------------------------------------------------------- -void DiskBufferQueue::WriteBuckets( FileId id, const void* buckets, const uint* sizes ) +void DiskBufferQueue::WriteBuckets( FileId id, const void* buckets, const uint* writeSizes, const uint32* sliceSizes ) { Command* cmd = GetCommandObject( Command::WriteBuckets ); - cmd->buckets.sizes = sizes; - cmd->buckets.buffers = (byte*)buckets; - cmd->buckets.fileId = id; + cmd->buckets.writeSizes = writeSizes; + cmd->buckets.sliceSizes = sliceSizes != nullptr ? sliceSizes : writeSizes; + cmd->buckets.buffers = (byte*)buckets; + cmd->buckets.elementSize = 1; + cmd->buckets.fileId = id; } //----------------------------------------------------------- -void DiskBufferQueue::WriteBucketElements( const FileId id, const void* buckets, const size_t elementSize, const uint32* counts ) +void DiskBufferQueue::WriteBucketElements( const FileId id, const void* buckets, const size_t elementSize, const uint* writeCounts, const uint32* sliceCounts ) { ASSERT( buckets ); ASSERT( elementSize ); - ASSERT( counts ); + ASSERT( writeCounts ); ASSERT( elementSize < std::numeric_limits::max() ); Command* cmd = GetCommandObject( Command::WriteBucketElements ); - cmd->bucketElements.counts = counts; - cmd->bucketElements.buffers = (byte*)buckets; - cmd->bucketElements.fileId = id; - cmd->bucketElements.elementSize = (uint32)elementSize; + cmd->buckets.writeSizes = writeCounts; + cmd->buckets.sliceSizes = sliceCounts != nullptr ? sliceCounts : writeCounts; + cmd->buckets.buffers = (byte*)buckets; + cmd->buckets.elementSize = elementSize; + cmd->buckets.fileId = id; } //----------------------------------------------------------- @@ -360,7 +363,7 @@ void DiskBufferQueue::WriteFile( FileId id, uint bucket, const void* buffer, siz } //----------------------------------------------------------- -void DiskBufferQueue::ReadBucketElements( const FileId id, Span& buffer, const size_t elementSize ) +void DiskBufferQueue::ReadBucketElements( const FileId id, Span& buffer, const size_t elementSize ) { Command* cmd = GetCommandObject( Command::ReadBucket ); cmd->readBucket.buffer = &buffer; @@ -574,9 +577,9 @@ void DiskBufferQueue::ExecuteCommand( Command& cmd ) case Command::WriteBucketElements: #if DBG_LOG_ENABLE - Log::Debug( "[DiskBufferQueue] ^ Cmd WriteBucketElements: (%u) addr:0x%p elementSz: %llu", cmd.buckets.fileId, cmd.buckets.buffers, (llu)cmd.bucketElements.elementSize ); + Log::Debug( "[DiskBufferQueue] ^ Cmd WriteBucketElements: (%u) addr:0x%p elementSz: %llu", cmd.buckets.fileId, cmd.buckets.buffers, (llu)cmd.buckets.elementSize ); #endif - CmdWriteBuckets( cmd, cmd.bucketElements.elementSize ); + CmdWriteBuckets( cmd, cmd.buckets.elementSize ); break; case Command::WriteFile: @@ -679,7 +682,7 @@ void DiskBufferQueue::ExecuteCommand( Command& cmd ) void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementSize ) { const FileId fileId = cmd.buckets.fileId; - const uint* sizes = cmd.buckets.sizes; + const uint* sizes = cmd.buckets.writeSizes; const byte* buffers = cmd.buckets.buffers; FileSet& fileSet = _files[(int)fileId]; @@ -698,22 +701,20 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS if( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ) { + const uint32* sliceSizes = cmd.buckets.sliceSizes; + // Write in interleaved mode, a whole bucket is written at once size_t writeSize = 0; for( uint i = 0; i < bucketCount; i++ ) { - const size_t sliceSize = sizes[i] * elementSize; - - // Slices must be block-aligned - // #TODO: This should be set as an option...? Or should we always align? - const size_t alignedSliceSize = CDivT( sliceSize, blockSize ) * blockSize; - // ASSERT( sliceSize == alignedSliceSize ); - writeSize += alignedSliceSize; + const size_t sliceWriteSize = sizes[i] * elementSize; + ASSERT( sliceWriteSize / blockSize * blockSize == sliceWriteSize ); + + // Save slice sizes for reading-back the bucket + fileSet.sliceSizes[fileSet.bucket][i] = sliceSizes[i] * elementSize; // #TODO: Should we do element size here? - // Save slice sizes for reading? - // #TODO: Remove this? Have the user specify it, since they have a different alignment...? - fileSet.sliceSizes[fileSet.bucket][i] = sliceSize; + writeSize += sliceWriteSize; } // #TODO: Do we have to round-up the size to block boundary? @@ -724,19 +725,20 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS fileSet.bucket++; fileSet.bucket %= fileSet.files.Length(); - return; } - - for( uint i = 0; i < bucketCount; i++ ) + else { - const size_t bufferSize = sizes[i] * elementSize; + for( uint i = 0; i < bucketCount; i++ ) + { + const size_t bufferSize = sizes[i] * elementSize; - // Only write up-to the block-aligned boundary. The caller is in charge of handling unlaigned data. - ASSERT( bufferSize == bufferSize / blockSize * blockSize ); - WriteToFile( *fileSet.files[i], bufferSize, buffer, (byte*)fileSet.blockBuffer, fileSet.name, i ); + // Only write up-to the block-aligned boundary. The caller is in charge of handling unlaigned data. + ASSERT( bufferSize == bufferSize / blockSize * blockSize ); + WriteToFile( *fileSet.files[i], bufferSize, buffer, (byte*)fileSet.blockBuffer, fileSet.name, i ); - // ASSERT( IsFlagSet( fileBuckets.files[i].GetFileAccess(), FileAccess::ReadWrite ) ); - buffer += bufferSize; + // ASSERT( IsFlagSet( fileBuckets.files[i].GetFileAccess(), FileAccess::ReadWrite ) ); + buffer += bufferSize; + } } } @@ -750,44 +752,43 @@ void DiskBufferQueue::CndWriteFile( const Command& cmd ) //----------------------------------------------------------- void DiskBufferQueue::CmdReadBucket( const Command& cmd ) { - const FileId fileId = cmd.readBucket.fileId; - FileSet& fileSet = _files[(int)fileId]; + const FileId fileId = cmd.readBucket.fileId; + const size_t elementSize = cmd.readBucket.elementSize; + FileSet& fileSet = _files[(int)fileId]; - Span& buffer = const_cast&>( reinterpret_cast&>( cmd.readBucket.buffer ) ); - ASSERT( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ); // #TODO: Read bucket is just a single file read without this flag ASSERT( fileSet.sliceSizes.Ptr() ); // ASSERT( fileSet.bucket == 0 ); // Should be in bucket 0 at this point // #NOTE: Perhaps have the user specify the bucket to read instead? const bool directIO = IsFlagSet( fileSet.options, FileSetOptions::DirectIO ); const uint32 bucketCount = (uint32)fileSet.files.Length(); - const Span sliceSizes = fileSet.sliceSizes[fileSet.bucket]; + const auto sliceSizes = fileSet.sliceSizes; const size_t blockSize = fileSet.files[0]->BlockSize(); - auto readBuffer = buffer.Slice(); - auto blockBuffer = Span( (byte*)fileSet.blockBuffer, 0 ); - size_t sizeRead = 0; + auto readBuffer = Span( cmd.readBucket.buffer->Ptr(), cmd.readBucket.buffer->Length() * elementSize ); + auto blockBuffer = Span( (byte*)fileSet.blockBuffer, blockSize ); Span tempBlock; for( uint32 slice = 0; slice < bucketCount; slice++ ) { - const size_t sliceSize = sliceSizes[slice]; - const size_t alignedSize = CDivT( sliceSize, blockSize ) * blockSize; // Sizes are written aligned, and must also be read aligned + const size_t sliceSize = sliceSizes[slice][fileSet.bucket]; + const size_t readSize = sliceSize + tempBlock.Length(); + const size_t alignedSize = CDivT( readSize, blockSize ) * blockSize; // Sizes are written aligned, and must also be read aligned - ReadFromFile( *fileSet.files[fileSet.bucket], alignedSize, readBuffer.Ptr(), nullptr, blockSize, directIO, fileSet.name, fileSet.bucket ); + ReadFromFile( *fileSet.files[slice], alignedSize, readBuffer.Ptr(), nullptr, blockSize, directIO, fileSet.name, fileSet.bucket ); // Replace the temp block we just overwrote, if we have one if( tempBlock.Length() ) tempBlock.CopyTo( readBuffer ); - // Copy offset temporarily (only if sliceSize is not block-aligned) - if( sliceSize < alignedSize ) + // Copy offset temporarily (only if readSize is not block-aligned) + if( readSize < alignedSize ) { - const auto offset = alignedSize - blockSize; ASSERT( sliceSize > offset ); - const size_t lastBlockSize = sliceSize - offset; + const auto lastBlockOffset = alignedSize - blockSize; ASSERT( readSize > lastBlockOffset ); + const size_t lastBlockSize = readSize - lastBlockOffset; - readBuffer = readBuffer.Slice( offset ); + readBuffer = readBuffer.Slice( lastBlockOffset ); tempBlock = blockBuffer.Slice( 0, lastBlockSize ); readBuffer.CopyTo( tempBlock, lastBlockSize ); @@ -797,12 +798,17 @@ void DiskBufferQueue::CmdReadBucket( const Command& cmd ) readBuffer = readBuffer.Slice( alignedSize ); // We just read everything block aligned tempBlock = {}; } - - sizeRead += sliceSize; } - fileSet.bucket++; - fileSet.bucket %= fileSet.files.Length(); + size_t elementCount = 0; + for( uint32 slice = 0; slice < bucketCount; slice++ ) + elementCount += sliceSizes[slice][fileSet.bucket]; + + fileSet.bucket = (fileSet.bucket + 1) % fileSet.files.Length(); + + // Revert buffer length from bytes to element size + auto userBuffer = const_cast*>( cmd.readBucket.buffer ); + userBuffer->length = elementCount / elementSize; } //----------------------------------------------------------- diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index 084d24df..5503cabf 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -89,22 +89,15 @@ class DiskBufferQueue struct { - const uint* sizes; + const uint* writeSizes; // Size that will actually be written to disk (usually padded and block-aligned) + const uint* sliceSizes; // Actual number of slices that we have per-bucket. This used to store it for reading-back buckets. const byte* buffers; FileId fileId; + uint32 elementSize; // Size of each element in the buffer } buckets; - // Same as buckets, but written with element sizes instead - struct - { - const uint* counts; - const byte* buffers; - FileId fileId; - uint32 elementSize; - } bucketElements; - struct { - Span* buffer; + Span* buffer; FileId fileId; uint32 elementSize; } readBucket; @@ -179,16 +172,16 @@ class DiskBufferQueue void ResetHeap( const size_t heapSize, void* heapBuffer ); - void WriteBuckets( FileId id, const void* buckets, const uint* sizes ); + void WriteBuckets( FileId id, const void* buckets, const uint* writeSizes, const uint32* sliceSizes = nullptr ); - void WriteBucketElements( const FileId id, const void* buckets, const size_t elementSize, const uint32* counts ); + void WriteBucketElements( const FileId id, const void* buckets, const size_t elementSize, const uint32* writeCounts, const uint32* sliceCounts = nullptr ); template - void WriteBucketElementsT( const FileId id, const T* buckets, const uint32* counts ); + void WriteBucketElementsT( const FileId id, const T* buckets, const uint32* writeCounts, const uint32* sliceCounts = nullptr ); void WriteFile( FileId id, uint bucket, const void* buffer, size_t size ); - void ReadBucketElements( const FileId id, Span& buffer, const size_t elementSize ); + void ReadBucketElements( const FileId id, Span& buffer, const size_t elementSize ); template void ReadBucketElementsT( const FileId id, Span& buffer ); @@ -233,6 +226,10 @@ class DiskBufferQueue return _workHeap.Alloc( size, alignment, blockUntilFreeBuffer, &_ioBufferWaitTime ); } + #if _DEBUG || BB_TEST_MODE + const Span> SliceSizes( const FileId fileId ) const { return _files[(int)fileId].sliceSizes; } + #endif + // byte* GetBufferForId( const FileId fileId, const uint32 bucket, const size_t size, bool blockUntilFreeBuffer = true ); // Release/return a chunk buffer that was in use, gotten by GetBuffer() @@ -372,14 +369,14 @@ class DiskBufferQueue //----------------------------------------------------------- template -inline void DiskBufferQueue::WriteBucketElementsT( const FileId id, const T* buckets, const uint32* counts ) +inline void DiskBufferQueue::WriteBucketElementsT( const FileId id, const T* buckets, const uint32* writeCounts, const uint32* sliceCounts ) { - WriteBucketElements( id, (void*)buckets, sizeof( T ), counts ); + WriteBucketElements( id, (byte*)buckets, sizeof( T ), writeCounts, sliceCounts ); } //----------------------------------------------------------- template inline void DiskBufferQueue::ReadBucketElementsT( const FileId id, Span& buffer ) { - ReadBucketElements( id, reinterpret_cast&>( buffer ), sizeof( T ) ); + ReadBucketElements( id, reinterpret_cast&>( buffer ), sizeof( T ) ); } \ No newline at end of file diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index aaaf9b0f..bd21bd3e 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -438,6 +438,12 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( pfxSum[j] += tCounts[j]; } + // If we're the control thread, retain the total bucket count + if( this->IsControlThread() && bucketCounts != nullptr ) + { + memcpy( bucketCounts, pfxSum, sizeof( TCount ) * bucketSize ); + } + uint32 alignedEntryIndex = 0; if constexpr ( AlignEntryCount > 0 ) @@ -474,12 +480,6 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( offsets[0] = pfxSum[0] - (b0BlockCount - 1) * entriesPerBlock; alignedTotalCounts[0] = b0BlockCount * entriesPerBlock; } - - // If we're the control thread, retain the total bucket count - if( this->IsControlThread() && bucketCounts != nullptr ) - { - memcpy( bucketCounts, pfxSum, sizeof( TCount ) * bucketSize ); - } // Calculate the prefix sum for( uint32 i = 1; i < bucketSize; i++ ) diff --git a/src/util/Span.h b/src/util/Span.h index b59a6e7e..c4973ec3 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -1,5 +1,5 @@ #pragma once - +#include template struct Span @@ -8,7 +8,10 @@ struct Span T* values; size_t length; - inline Span(){} + inline Span() + : values( nullptr ) + , length( 0 ) + {} inline Span( T* values, size_t length ) : values( values ) @@ -95,6 +98,22 @@ struct Span { CopyTo( other, length ); } + + inline bool EqualElements( const Span& other, const size_t count ) const + { + ASSERT( count <= other.length ); + ASSERT( length >= count ); + + return memcmp( values, other.values, count ) == 0; + } + + inline bool EqualElements( const Span& other ) const + { + if( other.length != length ) + return false; + + return EqualElements( other, length ); + } }; typedef Span ByteSpan; diff --git a/tests/TestBucketSliceRead.cpp b/tests/TestBucketSliceRead.cpp index 57243309..96a38d90 100644 --- a/tests/TestBucketSliceRead.cpp +++ b/tests/TestBucketSliceRead.cpp @@ -66,7 +66,9 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) // Fence* fence = &_fence; fence.Reset( 0 ); - fence.Signal(); + + uint32 bucketCounts[_numBuckets] = {}; + uint32* pBucketCounts = bucketCounts; Job::Run( pool, threadCount, [=, &fence]( Job* self ) { @@ -81,8 +83,8 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) GetThreadOffsets( self, entriesPerBucket, count, offset, end ); uint32 pfxSum [_numBuckets]; - uint32 totalCounts [_numBuckets]; uint32 offsets [_numBuckets] = {}; + uint32 totalCounts [_numBuckets]; uint32 alignedWriteCounts[_numBuckets]; for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) @@ -108,10 +110,20 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) // Write to disk if( self->BeginLockBlock() ) { - ioQueue->WriteBucketElements( fileId, entriesBuffer.Ptr(), sizeof( uint32 ), totalCounts ); + ioQueue->WriteBucketElements( fileId, entriesBuffer.Ptr(), sizeof( uint32 ), alignedWriteCounts, totalCounts ); ioQueue->SignalFence( fence ); ioQueue->CommitCommands(); fence.Wait(); + + auto sliceSizes = ioQueue->SliceSizes( fileId ); + for( uint32 i = 0; i < _numBuckets; i++ ) + { + const size_t sliceSize = sliceSizes[bucket][i] / sizeof( uint32 ); + ENSURE( sliceSize == totalCounts[i] ); + } + + for( uint32 i = 0; i < _numBuckets; i++ ) + pBucketCounts[i] += totalCounts[i]; } self->EndLockBlock(); @@ -127,17 +139,51 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) ioQueue->CommitCommands(); fence.Reset(); + // Total I/O queue bucket length must match our bucket length + { + auto sliceSizes = ioQueue->SliceSizes( fileId ); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + size_t bucketLength = 0; + + for( uint32 slice = 0; slice < _numBuckets; slice++ ) + bucketLength += sliceSizes[slice][bucket]; + + ENSURE( bucketLength / sizeof( uint32 ) * sizeof( uint32 ) == bucketLength ); + + bucketLength /= sizeof( uint32 ); + ENSURE( bucketLength == bucketCounts[bucket] ); + } + } + // Read back entries and validate them + auto refSlice = entriesRef.Slice(); for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { auto readBuffer = entriesBuffer.Slice(); + const size_t capacity = readBuffer.Length(); ioQueue->ReadBucketElementsT( fileId, readBuffer ); ioQueue->SignalFence( fence ); ioQueue->CommitCommands(); fence.Wait(); - // RadixSort256::Sort( pool, entriesRef.Ptr(), entriesTmp.Ptr(), entriesRef.Length() ); + ENSURE( readBuffer.Length() <= capacity ); + ENSURE( readBuffer.Length() == bucketCounts[bucket] ); + + RadixSort256::Sort( pool, readBuffer.Ptr(), entriesTmp.Ptr(), readBuffer.Length() ); + + if( !readBuffer.EqualElements( refSlice, readBuffer.Length() ) ) + { + // Find first failure + for( uint32 i = 0; i < readBuffer.Length(); i++ ) + { + ENSURE( readBuffer[i] == refSlice[i] ); + } + } + + refSlice = refSlice.Slice( readBuffer.Length() ); } } @@ -160,9 +206,9 @@ TEST_CASE( "bucket-slice-write", "[unit-core]" ) // Allocate buffers const uint32 minBuckets = 64; - const uint32 blockSize = (uint32)ioQueue->BlockSize( fileId ); - const uint32 entriesPerBucket = entryCount / minBuckets; - const uint32 maxEntriesPerSlice = ((uint32)(entriesPerBucket / minBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); + const uint32 blockSize = (uint32)ioQueue->BlockSize( fileId ); + const uint32 entriesPerBucket = entryCount / minBuckets; + const uint32 maxEntriesPerSlice = ((uint32)(entriesPerBucket / minBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries const uint32 entriesPerBucketAligned = entriesPerSliceAligned * minBuckets; // in subsequent slices From 11cb9c6182444ff0de60ee6f6b5602b4061991d6 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 14 May 2022 23:51:57 -0500 Subject: [PATCH 13/91] Fixes to Span helper funcs. Debugging slice batch reading issues. --- src/plotdisk/DiskBufferQueue.cpp | 2 +- src/threading/MTJob.h | 40 ++++----- src/util/Span.h | 4 +- tests/TestBucketSliceRead.cpp | 147 ++++++++++++++++++++++++++++--- 4 files changed, 160 insertions(+), 33 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 76948e7e..a54458d8 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -712,7 +712,7 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS ASSERT( sliceWriteSize / blockSize * blockSize == sliceWriteSize ); // Save slice sizes for reading-back the bucket - fileSet.sliceSizes[fileSet.bucket][i] = sliceSizes[i] * elementSize; // #TODO: Should we do element size here? + fileSet.sliceSizes[fileSet.bucket][i] = sliceSizes[i] * elementSize; // #TODO: Should we not do element size here? writeSize += sliceWriteSize; } diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index bd21bd3e..e2d45ed4 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -365,26 +365,26 @@ struct PrefixSumJob : public MTJob { inline virtual ~PrefixSumJob() {} - TCount* counts; + const TCount* counts; inline void CalculatePrefixSum( - uint32 bucketSize, - TCount* counts, - TCount* pfxSum, - TCount* bucketCounts ) + uint32 bucketSize, + const TCount* counts, + TCount* pfxSum, + TCount* bucketCounts ) { CalculatePrefixSumImpl<0>( bucketSize, counts, pfxSum, bucketCounts ); } template inline void CalculateBlockAlignedPrefixSum( - uint32 bucketSize, - uint32 blockSize, - TCount* counts, - TCount* pfxSum, - TCount* bucketCounts, - TCount* offsets, - TCount* alignedTotalCounts ) + uint32 bucketSize, + uint32 blockSize, + const TCount* counts, + TCount* pfxSum, + TCount* bucketCounts, + TCount* offsets, + TCount* alignedTotalCounts ) { const uint32 entrySize = (uint32)sizeof( EntryType1 ); const uint32 entriesPerBlock = blockSize / entrySize; @@ -396,14 +396,14 @@ struct PrefixSumJob : public MTJob private: template inline void CalculatePrefixSumImpl( - uint32 bucketSize, - TCount* counts, - TCount* pfxSum, - TCount* bucketCounts, + uint32 bucketSize, + const TCount* counts, + TCount* pfxSum, + TCount* bucketCounts, const uint32* entriesPerBlocks = nullptr, - TCount* offsets = nullptr, - TCount* alignedTotalCounts = nullptr, - TCount* pfxSum2 = nullptr + TCount* offsets = nullptr, + TCount* alignedTotalCounts = nullptr, + TCount* pfxSum2 = nullptr ); }; @@ -412,7 +412,7 @@ template template inline void PrefixSumJob::CalculatePrefixSumImpl( uint32 bucketSize, - TCount* counts, + const TCount* counts, TCount* pfxSum, TCount* bucketCounts, const uint32* entriesPerBlocks, diff --git a/src/util/Span.h b/src/util/Span.h index c4973ec3..14e648e0 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -91,7 +91,7 @@ struct Span ASSERT( length >= size ); ASSERT( other.length >= size ); - memcpy( other.values, values, size ); + memcpy( other.values, values, size * sizeof( T ) ); } inline void CopyTo( Span& other ) const @@ -104,7 +104,7 @@ struct Span ASSERT( count <= other.length ); ASSERT( length >= count ); - return memcmp( values, other.values, count ) == 0; + return memcmp( values, other.values, count * sizeof( T ) ) == 0; } inline bool EqualElements( const Span& other ) const diff --git a/tests/TestBucketSliceRead.cpp b/tests/TestBucketSliceRead.cpp index 96a38d90..c4994f45 100644 --- a/tests/TestBucketSliceRead.cpp +++ b/tests/TestBucketSliceRead.cpp @@ -11,10 +11,10 @@ const uint32 k = 24; const uint32 entryCount = 1ull << k; -Span entriesRef; +Span entriesRef; // Reference entries that we will test again. Generated all at once, then sorted. +Span entriesTest; // Full set of reference entries, but bucket-sorted first. This is to test against reference entries, excluding I/O issues. Span entriesTmp; Span entriesBuffer; -// Span entriesRead ; const char* tmpDir = "/home/harold/plot/tmp"; const FileId fileId = FileId::FX0; @@ -31,9 +31,6 @@ void GenerateRandomEntries( ThreadPool& pool ) { ASSERT( seed.size() == 32 ); - entriesRef = bbcvirtallocboundednuma_span( entryCount ); - entriesTmp = bbcvirtallocboundednuma_span( entryCount ); - Job::Run( pool, [=]( Job* self ){ const uint32 entriesPerBlock = kF1BlockSize / sizeof( uint32 ); @@ -58,6 +55,80 @@ void GenerateRandomEntries( ThreadPool& pool ) }); } +//----------------------------------------------------------- +template +void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ) +{ + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 bucketShift = k - bucketBits; + + auto sliceSizes = ioQueue->SliceSizes( fileId ); + + auto refEntries = entriesRef; + + // Test the whole buffer first + { + auto entries = bbcvirtallocboundednuma_span( entryCount ); + entriesTest.CopyTo( entries ); + ENSURE( entries.EqualElements( entriesTest ) ); + + RadixSort256::Sort( pool, entries.Ptr(), entriesTmp.Ptr(), entries.Length() ); + ENSURE( entries.EqualElements( entriesRef ) ); + + bbvirtfreebounded( entries.Ptr() ); + } + + uint32 offsets[_numBuckets] = {}; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + const size_t bucketLength = bucketCounts[bucket]; + size_t ioBucketLength = 0; + + auto testBucket = entriesBuffer.Slice( 0, bucketLength ); + auto writer = testBucket; + auto reader = entriesTest; + + // Read slices from all buckets + for( uint32 slice = 0; slice < _numBuckets; slice++ ) + { + const size_t sliceSize = sliceSizes[slice][bucket] / sizeof( uint32 ); + + auto readSlice = reader.Slice( offsets[slice], sliceSize ); + readSlice.CopyTo( writer ); + + for( uint32 i = 0; i < sliceSize; i++ ) + { + ENSURE( writer[i] >> bucketShift == bucket ); + } + + if( slice + 1 < _numBuckets ) + { + size_t readOffset = 0;; + for( uint32 i = 0; i < _numBuckets; i++ ) + readOffset += sliceSizes[slice][i] / sizeof( uint32 ); + + writer = writer.Slice( sliceSize ); + reader = reader.Slice( readOffset ); + } + + offsets[slice] += sliceSize; + ioBucketLength += sliceSize; + } + + ENSURE( ioBucketLength == bucketLength ); + + // Sort the bucket + RadixSort256::Sort( pool, testBucket.Ptr(), entriesTmp.Ptr(), testBucket.Length() ); + + // Validate it + auto refBucket = refEntries.Slice( 0, bucketLength ); + ENSURE( testBucket.EqualElements( refBucket ) ); + + refEntries = refEntries.Slice( bucketLength ); + } +} + //----------------------------------------------------------- template void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) @@ -77,7 +148,9 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) const uint32 bucketShift = k - bucketBits; const size_t blockSize = ioQueue->BlockSize( fileId ); - Span srcEntries = entriesRef.Slice(); + Span srcEntries = entriesRef.Slice(); + Span testEntries = entriesTest.Slice(); + uint32 count, offset, end; GetThreadOffsets( self, entriesPerBucket, count, offset, end ); @@ -86,6 +159,7 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) uint32 offsets [_numBuckets] = {}; uint32 totalCounts [_numBuckets]; uint32 alignedWriteCounts[_numBuckets]; + uint32 prevOffsets [_numBuckets] = {}; for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { @@ -95,7 +169,10 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) for( uint32 i = offset; i < end; i++ ) counts[srcEntries[i] >> bucketShift]++; + // Prefix sum + memcpy( prevOffsets, offsets, sizeof( offsets ) ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, totalCounts, offsets, alignedWriteCounts ); // Distribute entries to buckets @@ -106,11 +183,23 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) entriesBuffer[dst] = e; } + + // Caluclate non-aligned test values + self->CalculatePrefixSum( _numBuckets, counts, pfxSum, nullptr ); + + // Distribute test entries to buckets + for( uint32 i = offset; i < end; i++ ) + { + const uint32 e = srcEntries[i]; + const uint32 dst = --pfxSum[e >> bucketShift]; + + testEntries[dst] = e; + } // Write to disk if( self->BeginLockBlock() ) { - ioQueue->WriteBucketElements( fileId, entriesBuffer.Ptr(), sizeof( uint32 ), alignedWriteCounts, totalCounts ); + ioQueue->WriteBucketElementsT( fileId, entriesBuffer.Ptr(), alignedWriteCounts, totalCounts ); ioQueue->SignalFence( fence ); ioQueue->CommitCommands(); fence.Wait(); @@ -122,11 +211,40 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) ENSURE( sliceSize == totalCounts[i] ); } + // Update total bucket coutns for( uint32 i = 0; i < _numBuckets; i++ ) pBucketCounts[i] += totalCounts[i]; + + size_t alignedBucketLength = 0; + size_t bucketLength = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + bucketLength += totalCounts[i]; + alignedBucketLength += alignedWriteCounts[i]; + } + ENSURE( entriesPerBucket == bucketLength ); + ENSURE( alignedBucketLength >= bucketLength ); + + // Validate entries against test entries + auto test = testEntries.Slice( 0, bucketLength ); + auto target = entriesBuffer.Slice( 0, alignedBucketLength ); + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + auto testSlice = test.Slice( 0, totalCounts[i] ); + auto targetSlice = target.Slice( prevOffsets[i], testSlice.Length() ); + + ENSURE( testSlice.EqualElements( targetSlice ) ); + + test = test.Slice( totalCounts[i] ); + target = target.Slice( alignedWriteCounts[i] ); + } } self->EndLockBlock(); + testEntries = testEntries.Slice( entriesPerBucket ); + // Write next bucket slices srcEntries = srcEntries.Slice( entriesPerBucket ); } @@ -157,12 +275,16 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) } } + // Validate against test non-I/O entries first + ValidateTestEntries<_numBuckets>( pool, bucketCounts ); + // Read back entries and validate them auto refSlice = entriesRef.Slice(); + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { - auto readBuffer = entriesBuffer.Slice(); - const size_t capacity = readBuffer.Length(); + auto readBuffer = entriesBuffer.Slice(); + const size_t capacity = readBuffer.Length(); ioQueue->ReadBucketElementsT( fileId, readBuffer ); ioQueue->SignalFence( fence ); @@ -210,7 +332,12 @@ TEST_CASE( "bucket-slice-write", "[unit-core]" ) const uint32 entriesPerBucket = entryCount / minBuckets; const uint32 maxEntriesPerSlice = ((uint32)(entriesPerBucket / minBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries - const uint32 entriesPerBucketAligned = entriesPerSliceAligned * minBuckets; // in subsequent slices + const uint32 entriesPerBucketAligned = entriesPerSliceAligned * minBuckets; + + + entriesRef = bbcvirtallocboundednuma_span( entryCount ); + entriesTest = bbcvirtallocboundednuma_span( entryCount ); + entriesTmp = bbcvirtallocboundednuma_span( entryCount ); entriesBuffer = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); // entriesRead = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); From 3254e2a42ade1a0a3d26510a5bbacdd22f375436 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 15 May 2022 01:51:26 -0500 Subject: [PATCH 14/91] Fixed issue with aligned prefix sum. Missing block modulo as it was before. --- src/plotdisk/DiskBufferQueue.cpp | 17 ++++++++++------- src/threading/MTJob.h | 21 +++++++++++---------- tests/TestBucketSliceRead.cpp | 9 +++++++-- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index a54458d8..b48fc843 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -109,7 +109,7 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC const bool useTmp2 = IsFlagSet( options, FileSetOptions::UseTemp2 ); const std::string& wokrDir = isPlotFile ? _plotDir : - useTmp2 ? _workDir2 : _workDir1; + useTmp2 ? _workDir2 : _workDir1; memcpy( _filePathBuffer, wokrDir.c_str(), wokrDir.length() ); const char* pathBuffer = _filePathBuffer; @@ -201,7 +201,8 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC if( i == 0 && IsFlagSet( options, FileSetOptions::DirectIO ) ) { // const size_t totalBlockSize = file->BlockSize() * bucketCount; - fileSet.blockBuffer = bbvirtalloc( file->BlockSize() ); + fileSet.blockBuffer = bbvirtalloc( file->BlockSize() ); // #TODO: This should be removed, and we should use + // a shared one per temp dir. } } @@ -760,10 +761,10 @@ void DiskBufferQueue::CmdReadBucket( const Command& cmd ) ASSERT( fileSet.sliceSizes.Ptr() ); // ASSERT( fileSet.bucket == 0 ); // Should be in bucket 0 at this point // #NOTE: Perhaps have the user specify the bucket to read instead? - const bool directIO = IsFlagSet( fileSet.options, FileSetOptions::DirectIO ); - const uint32 bucketCount = (uint32)fileSet.files.Length(); - const auto sliceSizes = fileSet.sliceSizes; - const size_t blockSize = fileSet.files[0]->BlockSize(); + const bool directIO = IsFlagSet( fileSet.options, FileSetOptions::DirectIO ); + const uint32 bucketCount = (uint32)fileSet.files.Length(); + const auto sliceSizes = fileSet.sliceSizes; + const size_t blockSize = fileSet.files[0]->BlockSize(); auto readBuffer = Span( cmd.readBucket.buffer->Ptr(), cmd.readBucket.buffer->Length() * elementSize ); auto blockBuffer = Span( (byte*)fileSet.blockBuffer, blockSize ); @@ -776,7 +777,7 @@ void DiskBufferQueue::CmdReadBucket( const Command& cmd ) const size_t readSize = sliceSize + tempBlock.Length(); const size_t alignedSize = CDivT( readSize, blockSize ) * blockSize; // Sizes are written aligned, and must also be read aligned - ReadFromFile( *fileSet.files[slice], alignedSize, readBuffer.Ptr(), nullptr, blockSize, directIO, fileSet.name, fileSet.bucket ); + ReadFromFile( *fileSet.files[slice], alignedSize, readBuffer.Ptr(), nullptr, blockSize, directIO, fileSet.name, fileSet.bucket ); // Replace the temp block we just overwrote, if we have one if( tempBlock.Length() ) @@ -785,6 +786,8 @@ void DiskBufferQueue::CmdReadBucket( const Command& cmd ) // Copy offset temporarily (only if readSize is not block-aligned) if( readSize < alignedSize ) { + ASSERT( alignedSize - readSize < blockSize ); + const auto lastBlockOffset = alignedSize - blockSize; ASSERT( readSize > lastBlockOffset ); const size_t lastBlockSize = readSize - lastBlockOffset; diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index e2d45ed4..a9507402 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -450,7 +450,8 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( { // We now need to add padding to the total counts to ensure the starting // location of each slice is block aligned. - const uint32 entriesPerBlock = entriesPerBlocks[alignedEntryIndex++]; + const uint32 entriesPerBlock = entriesPerBlocks[alignedEntryIndex++]; + const uint32 modEntriesPerBlock = entriesPerBlock - 1; for( uint32 i = bucketSize-1; i > 0; i-- ) { @@ -463,22 +464,22 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( // Calculate our next offset before updating our total count, which is the the entries // our last block occupies, if its not full. - const uint32 offset = offsets[i]; - const uint32 entryCount = pfxSum[i] + offset; - const uint32 blockCount = CDivT( entryCount, entriesPerBlock ); ASSERT( blockCount > 0 ); + const uint32 offset = offsets[i]; + const uint32 entryCount = pfxSum[i] + offset; + const uint32 alignedEntryCount = CDivT( entryCount, entriesPerBlock ) * entriesPerBlock; - offsets[i] = entryCount - ( blockCount - 1 ) * entriesPerBlock; // Update our offset for the next round - pfxSum[i] += paddingFromPrevBucket + offset; // Update our total count for alignment purposes - alignedTotalCounts[i] = blockCount * entriesPerBlock; + offsets[i] = ( entryCount - (alignedEntryCount - entriesPerBlock) ) & modEntriesPerBlock; // Update our offset for the next round + pfxSum[i] += paddingFromPrevBucket + offset; // Update our total count for alignment purposes + alignedTotalCounts[i] = alignedEntryCount; // Set number of entries that have to be written to disk (always starts and ends at a block boundary) } // Add the offset to the first bucket slice as well pfxSum[0] += offsets[0]; - const uint32 b0BlockCount = CDivT( pfxSum[0], entriesPerBlock ); ASSERT( b0BlockCount > 0 ); + const uint32 b0AlignedCount = CDivT( pfxSum[0], entriesPerBlock ) * entriesPerBlock; - offsets[0] = pfxSum[0] - (b0BlockCount - 1) * entriesPerBlock; - alignedTotalCounts[0] = b0BlockCount * entriesPerBlock; + offsets[0] = ( pfxSum[0] - (b0AlignedCount - entriesPerBlock) ) & modEntriesPerBlock; + alignedTotalCounts[0] = b0AlignedCount; } // Calculate the prefix sum diff --git a/tests/TestBucketSliceRead.cpp b/tests/TestBucketSliceRead.cpp index c4994f45..5630184a 100644 --- a/tests/TestBucketSliceRead.cpp +++ b/tests/TestBucketSliceRead.cpp @@ -24,7 +24,6 @@ Fence fence; using Job = AnonPrefixSumJob; auto seed = HexStringToBytes( "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835" ); - //----------------------------------------------------------- void GenerateRandomEntries( ThreadPool& pool ) @@ -117,6 +116,11 @@ void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ) } ENSURE( ioBucketLength == bucketLength ); + // if( bucket == 7 ) + // { + // for( uint32 i = 0; i < ioBucketLength; i++ ) + // if( testBucket[i] == 1835013 ) BBDebugBreak(); + // } // Sort the bucket RadixSort256::Sort( pool, testBucket.Ptr(), entriesTmp.Ptr(), testBucket.Length() ); @@ -182,6 +186,7 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) const uint32 dst = --pfxSum[e >> bucketShift]; entriesBuffer[dst] = e; +// if( e == 1835013 ) BBDebugBreak(); } // Caluclate non-aligned test values @@ -232,7 +237,7 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) for( uint32 i = 0; i < _numBuckets; i++ ) { - auto testSlice = test.Slice( 0, totalCounts[i] ); + auto testSlice = test .Slice( 0, totalCounts[i] ); auto targetSlice = target.Slice( prevOffsets[i], testSlice.Length() ); ENSURE( testSlice.EqualElements( targetSlice ) ); From e37f6de2d2ddf669ea9de914fac7dff472fab3b4 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 15 May 2022 01:52:03 -0500 Subject: [PATCH 15/91] Removing debugging left overs --- tests/TestBucketSliceRead.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/TestBucketSliceRead.cpp b/tests/TestBucketSliceRead.cpp index 5630184a..fc17ba76 100644 --- a/tests/TestBucketSliceRead.cpp +++ b/tests/TestBucketSliceRead.cpp @@ -186,7 +186,6 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) const uint32 dst = --pfxSum[e >> bucketShift]; entriesBuffer[dst] = e; -// if( e == 1835013 ) BBDebugBreak(); } // Caluclate non-aligned test values From 928778d9cf1ff44a64e709983fda44daae7f83c7 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 15 May 2022 02:38:39 -0500 Subject: [PATCH 16/91] Batched slices test working properly now --- .vscode/launch.json | 4 +- CMakeLists.txt | 6 + tests/TestBucketSliceRead.cpp | 313 ++++++++++++++++++++++------------ 3 files changed, 212 insertions(+), 111 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index b9af7da2..d6ee5d15 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -156,7 +156,9 @@ "program": "${workspaceRoot}/build/tests", - "environment": [], + "environment": [ + // { "name": "bbtest_thread_count", "value": "2" } + ], "args": [ "-b", diff --git a/CMakeLists.txt b/CMakeLists.txt index 221578b1..a8022376 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,6 +156,8 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") /D_HAS_EXCEPTIONS=0 ${c_opts}) + set(tests_c_opts /DBB_TEST_MODE=1 ${tests_c_opts}) + set(link_opts /SUBSYSTEM:CONSOLE /STACK:33554432,1048576 @@ -210,6 +212,8 @@ else() # *Nix set(c_opts --include=pch.h -Wall -Wno-comment -Wno-unknown-pragmas -g ${c_opts}) + set(tests_c_opts -DBB_TEST_MODE=1 ${tests_c_opts}) + set(release_c_opts -O3 #-flto -D_NDEBUG=1 @@ -412,6 +416,8 @@ target_link_libraries(fsegen PRIVATE lib_bladebit) # Tests add_executable(tests ${src_tests} ${bb_headers}) +target_compile_options(tests PUBLIC $<$:${c_opts} ${release_c_opts} ${tests_c_opts}>) +target_compile_options(tests PUBLIC $<$:${c_opts} ${debug_c_opts} ${tests_c_opts}>) set_target_properties(tests PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") target_link_libraries(tests PRIVATE lib_bladebit Catch2::Catch2WithMain) diff --git a/tests/TestBucketSliceRead.cpp b/tests/TestBucketSliceRead.cpp index fc17ba76..134f0953 100644 --- a/tests/TestBucketSliceRead.cpp +++ b/tests/TestBucketSliceRead.cpp @@ -7,6 +7,7 @@ #include "ChiaConsts.h" #include "plotdisk/DiskBufferQueue.h" #include "algorithm/RadixSort.h" +#include "util/CliParser.h" const uint32 k = 24; const uint32 entryCount = 1ull << k; @@ -25,119 +26,114 @@ using Job = AnonPrefixSumJob; auto seed = HexStringToBytes( "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835" ); -//----------------------------------------------------------- -void GenerateRandomEntries( ThreadPool& pool ) -{ - ASSERT( seed.size() == 32 ); +static void AllocateBuffers( const uint32 blockSize ); +static void InitIOQueue( const uint32 numBuckets ); +static void GenerateRandomEntries( ThreadPool& pool ); - Job::Run( pool, [=]( Job* self ){ - - const uint32 entriesPerBlock = kF1BlockSize / sizeof( uint32 ); - const uint32 blockCount = entryCount / entriesPerBlock; - ASSERT( blockCount * entriesPerBlock == entryCount ); - - uint32 count, offset, end; - GetThreadOffsets( self, blockCount, count, offset, end ); +template +static void RunForBuckets( ThreadPool& pool, const uint32 threadCount ); - byte key[32] = { 1 }; - memcpy( key+1, seed.data()+1, 31 ); +template +static void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ); - chacha8_ctx chacha; - chacha8_keysetup( &chacha, key, 256, nullptr ); - chacha8_get_keystream( &chacha, offset, count, (byte*)entriesRef.Ptr() + offset * kF1BlockSize ); - - const uint32 mask = ( 1u << k ) - 1; - offset *= entriesPerBlock; - end *= entriesPerBlock; - for( uint32 i = offset; i < end; i++ ) - entriesRef[i] &= mask; - }); -} //----------------------------------------------------------- -template -void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ) +TEST_CASE( "bucket-slice-write", "[unit-core]" ) { - const uint32 bucketBits = bblog2( _numBuckets ); - const uint32 bucketShift = k - bucketBits; + SysHost::InstallCrashHandler(); - auto sliceSizes = ioQueue->SliceSizes( fileId ); - - auto refEntries = entriesRef; + uint32 maxThreads = SysHost::GetLogicalCPUCount(); + uint32 threadStart = maxThreads; + uint32 threadEnd = maxThreads; - // Test the whole buffer first + // Parse environment vars + std::vector args; { - auto entries = bbcvirtallocboundednuma_span( entryCount ); - entriesTest.CopyTo( entries ); - ENSURE( entries.EqualElements( entriesTest ) ); + const char* e; - RadixSort256::Sort( pool, entries.Ptr(), entriesTmp.Ptr(), entries.Length() ); - ENSURE( entries.EqualElements( entriesRef ) ); - - bbvirtfreebounded( entries.Ptr() ); + if( (e = std::getenv( "bbtest_thread_count" ) ) ) + { + args.push_back( "--thread_count" ); + args.push_back( e ); + } + if( (e = std::getenv( "bbtest_end_thread" ) ) ) + { + args.push_back( "--end_thread" ); + args.push_back( e ); + } + if( std::getenv( "bbtest_all_threads" ) ) + args.push_back( "--all_threads" ); } - uint32 offsets[_numBuckets] = {}; - - for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + + if( args.size() > 0 ) { - const size_t bucketLength = bucketCounts[bucket]; - size_t ioBucketLength = 0; - - auto testBucket = entriesBuffer.Slice( 0, bucketLength ); - auto writer = testBucket; - auto reader = entriesTest; + CliParser cli( (int)args.size(), args.data() ); - // Read slices from all buckets - for( uint32 slice = 0; slice < _numBuckets; slice++ ) + while( cli.HasArgs() ) { - const size_t sliceSize = sliceSizes[slice][bucket] / sizeof( uint32 ); - - auto readSlice = reader.Slice( offsets[slice], sliceSize ); - readSlice.CopyTo( writer ); - - for( uint32 i = 0; i < sliceSize; i++ ) + if( cli.ReadU32( threadStart, "--thread_count" ) ) continue; + if( cli.ReadU32( threadEnd, "--end_thread" ) ) continue; + if( cli.ArgConsume( "--all_threads" ) ) { - ENSURE( writer[i] >> bucketShift == bucket ); + threadStart = maxThreads; + threadEnd = 1; } - - if( slice + 1 < _numBuckets ) - { - size_t readOffset = 0;; - for( uint32 i = 0; i < _numBuckets; i++ ) - readOffset += sliceSizes[slice][i] / sizeof( uint32 ); - - writer = writer.Slice( sliceSize ); - reader = reader.Slice( readOffset ); - } - - offsets[slice] += sliceSize; - ioBucketLength += sliceSize; } + + FatalIf( threadStart == 0, "threadStart == 0" ); + // FatalIf( threadEnd > threadStart, "threadEnd > threadStart: %u > %u", threadEnd , threadStart ); - ENSURE( ioBucketLength == bucketLength ); - // if( bucket == 7 ) - // { - // for( uint32 i = 0; i < ioBucketLength; i++ ) - // if( testBucket[i] == 1835013 ) BBDebugBreak(); - // } + if( threadStart > maxThreads ) + threadStart = maxThreads; + if( threadEnd > threadStart ) + threadEnd = threadStart; + } - // Sort the bucket - RadixSort256::Sort( pool, testBucket.Ptr(), entriesTmp.Ptr(), testBucket.Length() ); + ThreadPool pool( maxThreads ); - // Validate it - auto refBucket = refEntries.Slice( 0, bucketLength ); - ENSURE( testBucket.EqualElements( refBucket ) ); + for( uint32 i = threadStart; i >= threadEnd; i-- ) + { + Log::Line( "[Threads: %u]", i ); + RunForBuckets<64> ( pool, i ); + RunForBuckets<128>( pool, i ); + RunForBuckets<256>( pool, i ); + RunForBuckets<512>( pool, i ); + } +} - refEntries = refEntries.Slice( bucketLength ); +//----------------------------------------------------------- +void AllocateBuffers( const uint32 numBuckets, const uint32 blockSize ) +{ + const uint32 entriesPerBucket = entryCount / numBuckets; + const uint32 maxEntriesPerSlice = ((uint32)(entriesPerBucket / numBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); + const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries + const uint32 entriesPerBucketAligned = entriesPerSliceAligned * numBuckets; + + if( entriesRef.Ptr() == nullptr ) + { + entriesRef = bbcvirtallocboundednuma_span( entryCount ); + entriesTest = bbcvirtallocboundednuma_span( entryCount ); + entriesTmp = bbcvirtallocboundednuma_span( entryCount ); + } + + if( entriesBuffer.Ptr() ) + { + bbvirtfreebounded( entriesBuffer.Ptr() ); + entriesBuffer = Span(); } + + entriesBuffer = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); } //----------------------------------------------------------- template void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) { - Log::Line( "Testing buckets: %u", _numBuckets ); + Log::Line( " Testing buckets: %u", _numBuckets ); + InitIOQueue( _numBuckets ); + AllocateBuffers( _numBuckets, (uint32)ioQueue->BlockSize( fileId ) ); + GenerateRandomEntries( pool ); // Fence* fence = &_fence; fence.Reset( 0 ); @@ -311,43 +307,140 @@ void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) refSlice = refSlice.Slice( readBuffer.Length() ); } + + // Delete the file + // fence.Reset(); + // ioQueue->DeleteBucket( FileId::FX0 ); + // ioQueue->SignalFence( fence ); + // ioQueue->CommitCommands(); + // fence.Wait(); } //----------------------------------------------------------- -TEST_CASE( "bucket-slice-write", "[unit-core]" ) +template +void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ) { - SysHost::InstallCrashHandler(); + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 bucketShift = k - bucketBits; - const uint32 maxThreads = SysHost::GetLogicalCPUCount(); - ThreadPool pool( maxThreads ); + auto sliceSizes = ioQueue->SliceSizes( fileId ); + + auto refEntries = entriesRef; + + // Test the whole buffer first + { + auto entries = bbcvirtallocboundednuma_span( entryCount ); + entriesTest.CopyTo( entries ); + ENSURE( entries.EqualElements( entriesTest ) ); + + RadixSort256::Sort( pool, entries.Ptr(), entriesTmp.Ptr(), entries.Length() ); + ENSURE( entries.EqualElements( entriesRef ) ); + + bbvirtfreebounded( entries.Ptr() ); + } + + uint32 offsets[_numBuckets] = {}; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + const size_t bucketLength = bucketCounts[bucket]; + size_t ioBucketLength = 0; + + auto testBucket = entriesBuffer.Slice( 0, bucketLength ); + auto writer = testBucket; + auto reader = entriesTest; + + // Read slices from all buckets + for( uint32 slice = 0; slice < _numBuckets; slice++ ) + { + const size_t sliceSize = sliceSizes[slice][bucket] / sizeof( uint32 ); + + auto readSlice = reader.Slice( offsets[slice], sliceSize ); + readSlice.CopyTo( writer ); + for( uint32 i = 0; i < sliceSize; i++ ) + { + ENSURE( writer[i] >> bucketShift == bucket ); + } + + if( slice + 1 < _numBuckets ) + { + size_t readOffset = 0;; + for( uint32 i = 0; i < _numBuckets; i++ ) + readOffset += sliceSizes[slice][i] / sizeof( uint32 ); + + writer = writer.Slice( sliceSize ); + reader = reader.Slice( readOffset ); + } + + offsets[slice] += sliceSize; + ioBucketLength += sliceSize; + } + + ENSURE( ioBucketLength == bucketLength ); + // if( bucket == 7 ) + // { + // for( uint32 i = 0; i < ioBucketLength; i++ ) + // if( testBucket[i] == 1835013 ) BBDebugBreak(); + // } + + // Sort the bucket + RadixSort256::Sort( pool, testBucket.Ptr(), entriesTmp.Ptr(), testBucket.Length() ); + + // Validate it + auto refBucket = refEntries.Slice( 0, bucketLength ); + ENSURE( testBucket.EqualElements( refBucket ) ); + + refEntries = refEntries.Slice( bucketLength ); + } +} + +//----------------------------------------------------------- +void GenerateRandomEntries( ThreadPool& pool ) +{ + ASSERT( seed.size() == 32 ); + + Job::Run( pool, [=]( Job* self ){ + + const uint32 entriesPerBlock = kF1BlockSize / sizeof( uint32 ); + const uint32 blockCount = entryCount / entriesPerBlock; + ASSERT( blockCount * entriesPerBlock == entryCount ); + + uint32 count, offset, end; + GetThreadOffsets( self, blockCount, count, offset, end ); + + byte key[32] = { 1 }; + memcpy( key+1, seed.data()+1, 31 ); + + chacha8_ctx chacha; + chacha8_keysetup( &chacha, key, 256, nullptr ); + chacha8_get_keystream( &chacha, offset, count, (byte*)entriesRef.Ptr() + offset * kF1BlockSize ); + + const uint32 mask = ( 1u << k ) - 1; + offset *= entriesPerBlock; + end *= entriesPerBlock; + for( uint32 i = offset; i < end; i++ ) + entriesRef[i] &= mask; + }); +} + + +//----------------------------------------------------------- +void InitIOQueue( const uint32 numBuckets ) +{ + // #NOTE: We let it leak after, as we still don't properly terminate + // #TODO: Delete the I/O queue after fixing its termination + const FileSetOptions flags = FileSetOptions::DirectIO | FileSetOptions::Cachable | FileSetOptions::Interleaved; FileSetInitData opts; opts.cacheSize = (size_t)( sizeof( uint32 ) * entryCount * 1.25); opts.cache = bbvirtallocboundednuma( opts.cacheSize ); + char* nameBuf = new char[64]; + sprintf( nameBuf, "test-slices-%u", numBuckets ); + byte dummyHeap = 1; ioQueue = new DiskBufferQueue( tmpDir, tmpDir, tmpDir, &dummyHeap, dummyHeap, 1 ); - ioQueue->InitFileSet( fileId, "test-slices", 64, flags, &opts ); - - // Allocate buffers - const uint32 minBuckets = 64; - const uint32 blockSize = (uint32)ioQueue->BlockSize( fileId ); - const uint32 entriesPerBucket = entryCount / minBuckets; - const uint32 maxEntriesPerSlice = ((uint32)(entriesPerBucket / minBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); - const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries - const uint32 entriesPerBucketAligned = entriesPerSliceAligned * minBuckets; - - - entriesRef = bbcvirtallocboundednuma_span( entryCount ); - entriesTest = bbcvirtallocboundednuma_span( entryCount ); - entriesTmp = bbcvirtallocboundednuma_span( entryCount ); - - entriesBuffer = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); - // entriesRead = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); - - Log::Line( "ChaCha gen..." ); - GenerateRandomEntries( pool ); + ioQueue->InitFileSet( fileId, nameBuf, numBuckets, flags, &opts ); +} - RunForBuckets<64>( pool, maxThreads ); -} \ No newline at end of file From c2a9b01be92c0fc94f9940be0834eb37ed8c8a7a Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 18 May 2022 04:07:59 -0500 Subject: [PATCH 17/91] A lot of work on new bounded plot. Bug in f1 where prefix sum values are completely overflown randomly. --- .vscode/launch.json | 2 +- TODO.md | 4 +- src/plotdisk/DiskPlotter.cpp | 2 +- src/plotdisk/k32/DiskPlotBounded.cpp | 21 ++- src/plotdisk/k32/DiskPlotBounded.h | 4 +- src/plotdisk/k32/F1Bounded.inl | 73 ++++++---- src/plotdisk/k32/FpMatchBounded.inl | 73 +++++----- src/plotdisk/k32/FxBounded.inl | 201 +++++++++++++++++++-------- src/util/Span.h | 23 +++ 9 files changed, 277 insertions(+), 126 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index d6ee5d15..56bbaf19 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -85,7 +85,7 @@ // "--f1-threads", "7", // "--fp-threads", "7", - "--cache", "200G", + // "--cache", "200G", // "--cache", "96G", // "--cache", "106G", // "--cache", "64G", diff --git a/TODO.md b/TODO.md index 50bd5463..441ce161 100644 --- a/TODO.md +++ b/TODO.md @@ -6,10 +6,10 @@ - [] Fix 1024 buckets bug on P3 - [] Fix crash on P1 T4 w/ RAID, which actually seems to be w/ big block sizes. (I believe this is due to not rounding up some buffers to block sizes. There's anote about this in fp code.) - [x] Add no-direct-io flag for both tmp dirs -- [] Add no-direct-io flag for final plot +- [x] Add no-direct-io flag for final plot - [] Add synchronos tmp IO (good with cache) - [] Perhaps add a different queue for t2 if it's a different physical disk - [] Add method to reduce cache requirements to 96G instead of 192G - [] Add non-overflowing version - [] Bring in avx256 linepoint conversion (already implemented in an old BB branch) -- +- [] Allow sub temp directories or plot-speific file temp file names (allows for concurrent plotting). diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 821efc57..8ce43aec 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -380,7 +380,7 @@ bool DiskPlotter::GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPa strlen( tmpPath2 ), }; - const size_t RAND_PART = 16; + const size_t RAND_PART = 16; const size_t RAND_FILE_SIZE = RAND_PART + 4; // 5 = '.' + ".tmp" const size_t MAX_LENGTH = 1024 + RAND_FILE_SIZE + 1; char stackPath[MAX_LENGTH+1]; diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 784ca86a..924ccc18 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -81,7 +81,19 @@ void K32BoundedPhase1::RunWithBuckets() for( TableId table = TableId::Table2; table <= TableId::Table7; table++ ) { - RunFx<_numBuckets>( table ); + switch( table ) + { + case TableId::Table2: RunFx(); break; + case TableId::Table3: RunFx(); break; + case TableId::Table4: RunFx(); break; + case TableId::Table5: RunFx(); break; + case TableId::Table6: RunFx(); break; + case TableId::Table7: RunFx(); break; + + default: + PanicExit(); + break; + } } } @@ -119,9 +131,10 @@ void K32BoundedPhase1::RunF1() } //----------------------------------------------------------- -template -void K32BoundedPhase1::RunFx( const TableId table ) +template +void K32BoundedPhase1::RunFx() { - + DiskPlotFxBounded fx( _context ); + fx.Run(); } diff --git a/src/plotdisk/k32/DiskPlotBounded.h b/src/plotdisk/k32/DiskPlotBounded.h index 8527109f..e804c8cf 100644 --- a/src/plotdisk/k32/DiskPlotBounded.h +++ b/src/plotdisk/k32/DiskPlotBounded.h @@ -20,8 +20,8 @@ class K32BoundedPhase1 template void RunF1(); - template - void RunFx( const TableId table ); + template + void RunFx(); private: DiskPlotContext& _context; diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 96067181..f7350899 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -30,7 +30,7 @@ public: const uint32 threadCount = context.f1ThreadCount; // We need to pad our slices to block size - const uint32 blockSize = _ioQueue.BlockSize( FileId::FX1 ); + const uint32 blockSize = _ioQueue.BlockSize( FileId::FX0 ); const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( _maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries const uint32 entriesPerBucketAligned = entriesPerSliceAligned * _numBuckets; // in subsequent slices ASSERT( entriesPerBucketAligned >= _entriesPerBucket ); @@ -51,6 +51,13 @@ public: _yEntries[1] = allocator.CAllocSpan( entriesPerBucketAligned, context.tmp2BlockSize ); _xEntries[0] = allocator.CAllocSpan( entriesPerBucketAligned, context.tmp2BlockSize ); _xEntries[1] = allocator.CAllocSpan( entriesPerBucketAligned, context.tmp2BlockSize ); + + _offsets = allocator.CAllocSpan>( threadCount ); + for( uint32 i = 0; i < _offsets.Length(); i++ ) + { + _offsets[i] = allocator.CAllocSpan( _numBuckets ); + _offsets[i].ZeroOutElements(); + } } //----------------------------------------------------------- @@ -99,29 +106,39 @@ private: const uint32 bucketBits = bblog2( _numBuckets ); const uint32 bucketBitShift = _k - bucketBits; const uint32 kMinusKExtraBits = _k - kExtraBits; - const uint32 fsBlockSize = (uint32)_ioQueue.BlockSize( FileId::FX1 ); + const uint32 fsBlockSize = (uint32)_ioQueue.BlockSize( FileId::FX0 ); // Distribute to buckets - uint32 counts [_numBuckets] = {}; - uint32 pfxSum [_numBuckets]; - uint32 totalCounts [_numBuckets]; - uint32 offsets [_numBuckets] = {}; - uint32 totalWriteCounts[_numBuckets]; - -// memset( counts, 0, sizeof( counts ) ); - + uint32 counts [_numBuckets] = {}; + uint32 pfxSum [_numBuckets]; + uint32 totalCounts [_numBuckets]; + uint32 alignedTotalCounts[_numBuckets]; + + // Count bucket entries for( uint32 i = 0; i < entryCount; i++ ) counts[Swap32( blocks[i] ) >> bucketBitShift]++; + + // Prefix sum + Span offsets = _offsets[self->JobId()]; + + Span yEntries, xEntries, elementCounts, alignedElementCounts; + GetNextBuffer( self, bucket, yEntries, xEntries, elementCounts, alignedElementCounts ); - self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, totalCounts, offsets, totalWriteCounts ); + uint32* pTotalCounts = totalCounts; + uint32* pAlignedTotalCounts = alignedTotalCounts; - const uint32 yBits = _k + kExtraBits - bucketBits; - const uint32 yMask = (uint32)(( 1ull << yBits ) - 1); + if( self->IsControlThread() ) + { + pTotalCounts = elementCounts.Ptr(); + pAlignedTotalCounts = alignedElementCounts.Ptr(); + } - Span yEntries, xEntries, elementCounts; - GetNextBuffer( self, bucket, yEntries, xEntries, elementCounts ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, pTotalCounts, offsets.Ptr(), pAlignedTotalCounts ); // Distribute slices to buckets + const uint32 yBits = _k + kExtraBits - bucketBits; + const uint32 yMask = (uint32)(( 1ull << yBits ) - 1); + for( uint32 i = 0; i < entryCount; i++ ) { uint32 y = Swap32( blocks[i] ); @@ -138,10 +155,8 @@ private: // Write to disk if( self->BeginLockBlock() ) { - memcpy( elementCounts.Ptr(), totalCounts, sizeof( totalCounts ) ); - - _ioQueue.WriteBucketElementsT( FileId::FX1 , yEntries.Ptr(), totalWriteCounts ); - _ioQueue.WriteBucketElementsT( FileId::META1, xEntries.Ptr(), totalWriteCounts ); + _ioQueue.WriteBucketElementsT( FileId::FX0 , yEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( FileId::META0, xEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); _ioQueue.SignalFence( _writeFence, bucket+1 ); _ioQueue.CommitCommands(); @@ -152,7 +167,9 @@ private: } //----------------------------------------------------------- - void GetNextBuffer( Job* self, const uint32 bucket, Span& yEntries, Span& xEntries, Span& totalCounts ) + void GetNextBuffer( Job* self, const uint32 bucket, + Span& yEntries, Span& xEntries, + Span& elementCounts, Span& alignedElementCounts ) { if( bucket >= 2 && _writeFence.Value() < bucket-1 ) { @@ -162,9 +179,10 @@ private: self->EndLockBlock(); } - yEntries = _yEntries[bucket & 1]; - xEntries = _xEntries[bucket & 1]; - totalCounts = Span( _elementCounts[bucket & 1], _numBuckets ); + yEntries = _yEntries[bucket & 1]; + xEntries = _xEntries[bucket & 1]; + elementCounts = Span( _elementCounts[bucket & 1], _numBuckets ); + alignedElementCounts = Span( _alignedElementCounts[bucket & 1], _numBuckets ); } private: @@ -174,9 +192,12 @@ private: Span _blockBuffer; // I/O buffers - Span _yEntries [2]; - Span _xEntries [2]; - uint32 _elementCounts[2][_numBuckets] = {}; + Span _yEntries[2]; + Span _xEntries[2]; + uint32 _elementCounts [2][_numBuckets] = {}; + uint32 _alignedElementCounts[2][_numBuckets] = {}; + + Span> _offsets; #if _DEBUG uint32 _maxEntriesPerIOBucket; diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 0fb73e20..3173a8ce 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -12,34 +12,40 @@ class FxMatcherBounded public: //----------------------------------------------------------- - void Match( Job* self, const Span yEntries, Span pairs, const uint32 bucket ) + Span Match( Job* self, + const uint32 bucket, + const Span yEntries, + Span groupsBuffer, + Span pairs ) { const uint32 id = self->JobId(); - uint32 startIndex; - const uint32 groupCount = ScanGroups( self, yEntries, bucket, startIndex ); - ASSERT( groupCount > 0 ); - - const Span groupBoundaries( _groupIndices[id], groupCount ); - - uint32 matchCount = MatchGroups( self, - startIndex, - groupCount, - groupBoundaries, - yEntries, - pairs, - bucket, - _maxMatches ); + _groupBuffers[id] = groupsBuffer; - _matchCounts[id] = matchCount; - - self->SyncThreads(); + uint32 startIndex; + const Span groups = ScanGroups( self, bucket, yEntries, groupsBuffer, startIndex ); + ASSERT( groups.Length() ); + + const uint32 matchCount = MatchGroups( self, + startIndex, + groups, + yEntries, + pairs, + bucket, + pairs.Length() ); + + return pairs.Slice( 0, matchCount ); } private: //----------------------------------------------------------- - uint32 ScanGroups( Job* self, const Span yEntries, const uint64 bucket, uint32& outStartIndex ) + const Span ScanGroups( + Job* self, + const uint64 bucket, + const Span yEntries, + Span groupBuffer, + uint32& outStartIndex ) { const uint64 yMask = bucket << 32; const uint32 id = self->JobId(); @@ -67,14 +73,15 @@ private: const uint32* end = self->IsLastThread() ? yEntries.Ptr() + yEntries.Length() : _startPositions[id+1]; // Now scan for all groups - uint32* groupIndices = _groupIndices[id]; - uint32 groupCount = 0; + const uint32 maxGroups = groupBuffer.Length(); + Span groupIndices = groupBuffer; + uint32 groupCount = 0; while( ++entries < end ) { const uint64 g = (yMask | (uint64)*entries) / kBC; if( g != curGroup ) { - ASSERT( groupCount < _maxMatches ); + ASSERT( groupCount < maxGroups ); groupIndices[groupCount++] = (uint32)(uintptr_t)(entries - start); ASSERT( g - curGroup > 1 || groupCount == 1 || groupIndices[groupCount-1] - groupIndices[groupCount-2] <= 350 ); @@ -87,30 +94,30 @@ private: // Add the end location of the last R group if( self->IsLastThread() ) { - ASSERT( groupCount < _maxMatches ); + ASSERT( groupCount < maxGroups ); groupIndices[groupCount] = (uint32)yEntries.Length(); } else { - ASSERT( groupCount+1 < _maxMatches ); + ASSERT( groupCount+1 < maxGroups ); groupIndices[groupCount++] = (uint32)(uintptr_t)(_startPositions[id+1] - start); - groupIndices[groupCount ] = _groupIndices[id+1][0]; + groupIndices[groupCount ] = _groupBuffers[id+1][0]; } - return groupCount; + return groupIndices.Slice( 0, groupCount + 1 ); // There's always an extra 'ghost' group used to get the end position of the last R group } //----------------------------------------------------------- uint32 MatchGroups( Job* self, - const uint32 startIndex, - const uint32 groupCount, + const uint32 startIndex, const Span groupBoundaries, const Span yEntries, - Span pairs, - const uint32 bucket, - const uint64 maxPairs ) + Span pairs, + const uint32 bucket, + const uint64 maxPairs ) { const uint64 bucketMask = ((uint64)bucket) << 32; + const uint32 groupCount = groupBoundaries.Length() - 1; // Ignore the extra ghost group uint32 pairCount = 0; @@ -195,8 +202,6 @@ private: } private: - uint32 _maxMatches; const uint32* _startPositions[BB_DP_MAX_JOBS];// = { 0 }; - uint32 _matchCounts [BB_DP_MAX_JOBS];// = { 0 }; - uint32* _groupIndices [BB_DP_MAX_JOBS]; + Span _groupBuffers [BB_DP_MAX_JOBS]; }; diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 617bd0fb..6fffd14b 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -3,6 +3,7 @@ #include "plotdisk/DiskPlotConfig.h" #include "plotdisk/DiskBufferQueue.h" #include "util/StackAllocator.h" +#include "FpMatchBounded.inl" #include "b3/blake3.h" typedef uint32 K32Meta1; @@ -28,9 +29,11 @@ template<> struct K32TYOut { using Type = uint32; template class DiskPlotFxBounded { - using TMeta = uint32; - using Job = AnonPrefixSumJob; - static constexpr uint32 _k = 32; + using TMetaIn = typename K32MetaType::In; + using TMetaOut = typename K32MetaType::Out; + using Job = AnonPrefixSumJob; + static constexpr uint32 _k = 32; + static constexpr uint64 _maxTableEntries = 1ull << _k; public: @@ -45,7 +48,14 @@ public: , _pairWriteFence( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) , _mapWriteFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) { - + const TableId lTable = rTable - 1; + _yId [0] = FileId::FX0 + (FileId)((int)lTable & 1); + _idxId [0] = FileId::INDEX0 + (FileId)((int)lTable & 1); + _metaId[0] = FileId::META0 + (FileId)((int)lTable & 1); + + _yId [1] = FileId::FX0 + (FileId)((int)rTable & 1); + _idxId [1] = FileId::INDEX0 + (FileId)((int)rTable & 1); + _metaId[1] = FileId::META0 + (FileId)((int)rTable & 1); } //----------------------------------------------------------- @@ -72,6 +82,7 @@ public: { const uint64 kEntryCount = 1ull << _k; const uint64 entriesPerBucket = (uint64)( kEntryCount / _numBuckets * BB_DP_XTRA_ENTRIES_PER_BUCKET ); + _entriesPerBucket = entriesPerBucket; _y[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _y[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); @@ -79,15 +90,15 @@ public: _sortKey = allocator.CAllocSpan( entriesPerBucket ); - _meta[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _meta[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _metaTmp = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _meta[0] = Span( (TMetaIn*)allocator.CAlloc( entriesPerBucket, t2BlockSize ), entriesPerBucket ); + _meta[1] = Span( (TMetaIn*)allocator.CAlloc( entriesPerBucket, t2BlockSize ), entriesPerBucket ); + _metaTmp = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _index[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _index[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _map = allocator.CAllocSpan( entriesPerBucket ); - _pairs = allocator.CAllocSpan ( entriesPerBucket ); + _map = allocator.CAllocSpan( entriesPerBucket ); + _pairBuffer = allocator.CAllocSpan ( entriesPerBucket ); _pairsL = allocator.CAllocSpan( entriesPerBucket ); _pairsR = allocator.CAllocSpan( entriesPerBucket ); @@ -97,10 +108,35 @@ public: //----------------------------------------------------------- void Run() { + // Prepare input files + _ioQueue.SeekBucket( _yId[0], 0, SeekOrigin::Begin ); + + if constexpr( rTable > TableId::Table2 ) + _ioQueue.SeekBucket( _idxId[0], 0, SeekOrigin::Begin ); + + _ioQueue.SeekBucket( _metaId[0], 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); + + // Allocate buffers StackAllocator allocator( _context.heapBuffer, _context.heapSize ); AllocateBuffers( allocator, _context.tmp1BlockSize, _context.tmp2BlockSize ); - Job::Run( *_context.threadPool, _context.fpThreadCount, [=]( Job* self ) { + // Init buffers + const uint32 threadCount = _context.fpThreadCount; + + { + const uint32 matchesPerThread =_entriesPerBucket / threadCount; + auto pairBuffer = _pairBuffer; + + for( uint32 i = 0; i < threadCount; i++ ) + { + _pairs[i] = pairBuffer.Slice( 0, matchesPerThread ); + pairBuffer = pairBuffer.Slice( matchesPerThread ); + } + } + + // Run mmulti-threaded + Job::Run( *_context.threadPool, threadCount, [=]( Job* self ) { RunMT( self ); }); @@ -119,32 +155,57 @@ private: void RunMT( Job* self ) { // using TYOut = typename K32TYOut::Type; - using TMetaIn = typename K32MetaType::In; - using TMetaOut = typename K32MetaType::Out; - const TableId lTable = rTable-1; + // using TMetaIn = typename K32MetaType::In; + // using TMetaOut = typename K32MetaType::Out; + const TableId lTable = rTable-1; + const uint32 threadCount = self->JobCount(); ReadNextBucket( self, 0 ); for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { ReadNextBucket( self, bucket + 1 ); // Read next bucket in background - WaitForFence( self, _yReadFence, bucket ); - const uint32 entryCount = _context.bucketCounts[(int)lTable][bucket]; - - Span yInput = _y [0].Slice( entryCount ); - Span indexInput = _index [0].Slice( entryCount ); - Span sortKey = _sortKey.Slice( entryCount ); + // const uint32 entryCount = _context.bucketCounts[(int)lTable][bucket]; - SortY( self, entryCount, yInput.Ptr(), _y[1].Ptr(), sortKey.Ptr(), (uint32*)_metaTmp ); + Span yInput = _y[bucket]; + const uint32 entryCount = yInput.Length(); + + Span sortKey = _sortKey.SliceSize( entryCount ); + SortY( self, entryCount, yInput.Ptr(), _yTmp.Ptr(), sortKey.Ptr(), _metaTmp.As().Ptr() ); - const uint32 matchCount = Match( self, yInput ); + const Span matches = Match( self, bucket, yInput ); // WritePairs( self ); + // Count the total match count + uint64 totalMatches = 0; + self->SyncThreads(); + for( uint32 i = 0; i < threadCount; i++ ) + totalMatches += _pairs[i].Length(); + + // #TODO: This is only for the last table.. + // if( totalMatches > _maxTableEntries ) + // { + // // Prevent calculating fx for overflow matches + // if( self->IsLastThread() ) + // { + // const uint32 overflowEntries = (uint32)( totalMatches - _maxTableEntries ); + // ASSERT( overflowEntries < matches.Length() ); + + // matches = matches.Slice( 0, matches.Length() - overflowEntries ); + // } + + // totalMatches = _maxTableEntries; + // } + // Generate and write map -// WaitForFence( self, _indexReadFence, bucket ); -// WriteMap( self, indexInput, sortKey ); + if constexpr ( rTable > TableId::Table2 ) + { + WaitForFence( self, _indexReadFence, bucket ); + // Span indexInput = _index [bucket]; +// WriteMap( self, indexInput, sortKey ); // Write reverse map, given the previous table's y origin indices + } // Sort meta on Y WaitForFence( self, _metaReadFence, bucket ); @@ -154,10 +215,11 @@ private: SortOnYKey( self, sortKey, metaTmp, metaIn ); // Gen fx + if( self->IsLastThread() ) Span yOut = _yTmp; - Span metaOut( (TMetaIn*)metaTmp.Ptr(), matchCount ); + Span metaOut( (TMetaOut*)metaTmp.Ptr(), matches.Length() ); - // GenFx( self, yInput, metaIn, pairs, yOut, metaOut, bucket ); + // GenFx( self, yInput, metaIn, matches, yOut, metaOut, bucket ); // #TODO: Write bucekt @@ -166,7 +228,7 @@ private: } //----------------------------------------------------------- - void SortY( Job* self, const uint32 entryCount, uint32* ySrc, uint32* yTmp, uint32* sortKeySrc, uint32* sortKeyTmp ) + void SortY( Job* self, const uint64 entryCount, uint32* ySrc, uint32* yTmp, uint32* sortKeySrc, uint32* sortKeyTmp ) { constexpr uint32 Radix = 256; constexpr uint32 iterations = 4; @@ -174,18 +236,17 @@ private: uint32 shift = 0; - uint32 counts [Radix]; - uint32 prefixSum [Radix]; - uint32 totalCounts[Radix]; + uint32 counts [Radix]; + uint32 prefixSum [Radix]; + uint32 totalCounts[Radix]; - uint32 length, offset, _; + uint64 length, offset, _; GetThreadOffsets( self, entryCount, length, offset, _ ); - uint32* input = ySrc; - uint32* tmp = yTmp; - uint32* keyInput = sortKeySrc; - uint32* keyTmp = sortKeyTmp; - + uint32* input = ySrc; + uint32* tmp = yTmp; + uint32* keyInput = sortKeySrc; + uint32* keyTmp = sortKeyTmp; for( uint32 iter = 0; iter < iterations ; iter++, shift += shiftBase ) { @@ -204,10 +265,10 @@ private: for( uint64 i = length; i > 0; ) { - const uint32 value = src[--i]; - const uint64 idx = (value >> shift) & 0xFF; + const uint32 value = src[--i]; + const uint32 bucket = (value >> shift) & 0xFF; - const uint64 dstIdx = --prefixSum[idx]; + const uint64 dstIdx = --prefixSum[bucket]; tmp [dstIdx] = value; keyTmp[dstIdx] = keySrc[i]; @@ -224,13 +285,30 @@ private: template void SortOnYKey( Job* self, const Span key, const Span input, Span output ) { + uint32 count, offset, end; + GetThreadOffsets( self, (uint32)key.Length(), count, offset, end ); + + for( uint32 i = offset; i < end; i++ ) + output[i] = input[key[i]]; + self->SyncThreads(); } //----------------------------------------------------------- - void Match( Job* self, Span yEntries ) + Span Match( Job* self, const uint32 bucket, Span yEntries ) { + const uint32 id = self->JobId(); + const uint32 threadCount = self->JobCount(); + // use metaTmp as a buffer for group boundaries + Span groupBuffer = _metaTmp.As(); + const uint32 maxGroups = (uint32)( groupBuffer.Length() / threadCount ); + Span groupIndices = groupBuffer.Slice( maxGroups * id, maxGroups ); + + auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); + _pairs[id] = matches; + + return matches; } //----------------------------------------------------------- @@ -246,14 +324,13 @@ private: } //----------------------------------------------------------- - template void WriteEntries( Job* self, - const Span yIn, - const Span metaIn, - Span yOut, - Span metaOut, - Span indices, - const uint32 bucket ) + const Span yIn, + const Span metaIn, + Span yOut, + Span metaOut, + Span indices, + const uint32 bucket ) { // Distribute to buckets const uint32 logBuckets = bblog2( _numBuckets ); @@ -300,7 +377,7 @@ private: const FileId idxId = _idxId [1]; _ioQueue.WriteBucketElementsT( yId , yOut.Ptr() , bucketSlices ); - _ioQueue.WriteBucketElementsT ( metaId, metaOut.Ptr(), bucketSlices ); + _ioQueue.WriteBucketElementsT( metaId, (TMetaOut*)metaOut.Ptr(), bucketSlices ); _ioQueue.WriteBucketElementsT( idxId , indices.Ptr(), bucketSlices ); _ioQueue.SignalFence( _fxWriteFence, bucket+1 ); _ioQueue.CommitCommands(); @@ -354,7 +431,7 @@ private: const size_t bufferSize = CDiv( ySize + metaSizeLR, 8 ); const uint32 id = self->JobId(); - const uint32 matchCount = _matchCount[id]; + const uint32 matchCount = pairs.Length(); const uint64 yMask = (uint64)bucket << 32; // Hashing @@ -489,7 +566,16 @@ private: if( !self->IsControlThread() ) return; + _ioQueue.ReadBucketElementsT( _yId[0], _y[bucket] ); + _ioQueue.SignalFence( _yReadFence, bucket + 1 ); + + _ioQueue.ReadBucketElementsT( _idxId[0], _index[bucket] ); + _ioQueue.SignalFence( _indexReadFence, bucket + 1 ); + + _ioQueue.ReadBucketElementsT( _metaId[0], _meta[bucket] ); + _ioQueue.SignalFence( _metaReadFence, bucket + 1 ); + _ioQueue.CommitCommands(); } //----------------------------------------------------------- @@ -505,23 +591,29 @@ private: DiskPlotContext& _context; DiskBufferQueue& _ioQueue; + uint32 _entriesPerBucket = 0; + // I/O FileId _yId [2]; FileId _idxId [2]; FileId _metaId[2]; - Span _y [2]; - Span _index[2]; - Span _meta [2]; + Span _y [_numBuckets]; + Span _index[_numBuckets]; + Span _meta [_numBuckets]; Span _map; Span _pairsL; Span _pairsR; - + // Temp working buffers Span _yTmp; Span _sortKey; Span _metaTmp; - Span _pairs; + Span _pairBuffer; + Span _pairs[BB_DP_MAX_JOBS]; // Pairs buffer divided per thread + + // Matching + FxMatcherBounded _matcher; // I/O Synchronization fences Fence& _yReadFence; @@ -534,7 +626,4 @@ private: // I/O wait accumulator Duration _tableIOWait = Duration::zero(); - - // Matching - uint32 _matchCount[BB_DP_MAX_JOBS]; }; diff --git a/src/util/Span.h b/src/util/Span.h index 14e648e0..4f36f89c 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -82,6 +82,12 @@ struct Span return Slice( 0, length ); } + inline Span SliceSize( const size_t size ) const + { + ASSERT( size <= length ); + return Slice( 0, size ); + } + inline Span Slice( const uint32 index ) const { return Slice( (size_t)index ); } inline Span Slice( const int64 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } inline Span Slice( const int32 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } @@ -99,6 +105,14 @@ struct Span CopyTo( other, length ); } + inline void ZeroOutElements() + { + if( length < 1 ) + return; + + memset( values, 0, sizeof( T ) * length ); + } + inline bool EqualElements( const Span& other, const size_t count ) const { ASSERT( count <= other.length ); @@ -114,6 +128,15 @@ struct Span return EqualElements( other, length ); } + + template + inline Span As() const + { + const size_t size = sizeof( T ) * length; + const size_t targetLength = size / sizeof( TCast ); + + return Span( reinterpret_cast( values ), targetLength ); + } }; typedef Span ByteSpan; From c6018c725b248c91801db6945020c2858a5ff92f Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 18 May 2022 04:18:40 -0500 Subject: [PATCH 18/91] Quick edits --- src/plotdisk/k32/FxBounded.inl | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 6fffd14b..997c5a6c 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -154,9 +154,6 @@ private: //----------------------------------------------------------- void RunMT( Job* self ) { -// using TYOut = typename K32TYOut::Type; - // using TMetaIn = typename K32MetaType::In; - // using TMetaOut = typename K32MetaType::Out; const TableId lTable = rTable-1; const uint32 threadCount = self->JobCount(); @@ -210,14 +207,14 @@ private: // Sort meta on Y WaitForFence( self, _metaReadFence, bucket ); - Span metaTmp( (TMetaIn*)_meta[0].Ptr(), yInput.Length() ); - Span metaIn ( (TMetaIn*)_metaTmp.Ptr(), yInput.Length() ); + Span metaTmp = _meta[0].As().SliceSize( yInput.Length() ); + Span metaIn = _metaTmp.As().SliceSize( yInput.Length() ); SortOnYKey( self, sortKey, metaTmp, metaIn ); // Gen fx if( self->IsLastThread() ) Span yOut = _yTmp; - Span metaOut( (TMetaOut*)metaTmp.Ptr(), matches.Length() ); + Span metaOut = metaTmp.As().SliceSize( matches.Length() ); // GenFx( self, yInput, metaIn, matches, yOut, metaOut, bucket ); From 1a0ced4a46c81c36e32908da1412b7fdaeb35858 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 18 May 2022 22:27:59 -0500 Subject: [PATCH 19/91] fx bounded --- src/Types.h | 3 +- src/plotdisk/k32/DiskPlotBounded.cpp | 7 + src/plotdisk/k32/F1Bounded.inl | 5 +- src/plotdisk/k32/FxBounded.inl | 233 +++++++++++++++++---------- src/threading/MTJob.h | 34 ++-- 5 files changed, 186 insertions(+), 96 deletions(-) diff --git a/src/Types.h b/src/Types.h index d4056f35..75e90074 100644 --- a/src/Types.h +++ b/src/Types.h @@ -64,4 +64,5 @@ static_assert( sizeof( float64 ) == 8, "float64 must be 8" ); typedef uint128_t uint128; -typedef std::chrono::steady_clock::duration Duration; +typedef std::chrono::steady_clock::duration Duration; +typedef std::chrono::steady_clock::time_point TimePoint; diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 924ccc18..da86549e 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -134,7 +134,14 @@ void K32BoundedPhase1::RunF1() template void K32BoundedPhase1::RunFx() { + Log::Line( "Table %u", table+1 ); + auto timer = TimerBegin(); + DiskPlotFxBounded fx( _context ); fx.Run(); + + Log::Line( "Completed table %u in %.2lf seconds with %.llu entries.", table+1, TimerEnd( timer ), _context.entryCounts[(int)table] ); + Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( fx._tableIOWait ) ); + } diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index f7350899..72e1cac1 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -152,7 +152,7 @@ private: xEntries[dst] = x; } - // Write to disk + // Write to disk (and synchronize threads) if( self->BeginLockBlock() ) { _ioQueue.WriteBucketElementsT( FileId::FX0 , yEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); @@ -164,6 +164,9 @@ private: _context.bucketCounts[(int)TableId::Table1][i] += totalCounts[i]; } self->EndLockBlock(); + + // #NOTE: Somehow we're not getting synced here... So sync explicitly again + self->SyncThreads(); } //----------------------------------------------------------- diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 997c5a6c..1187d44a 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -33,7 +33,7 @@ class DiskPlotFxBounded using TMetaOut = typename K32MetaType::Out; using Job = AnonPrefixSumJob; static constexpr uint32 _k = 32; - static constexpr uint64 _maxTableEntries = 1ull << _k; + static constexpr uint64 _maxTableEntries = (1ull << _k) - 1; public: @@ -84,22 +84,32 @@ public: const uint64 entriesPerBucket = (uint64)( kEntryCount / _numBuckets * BB_DP_XTRA_ENTRIES_PER_BUCKET ); _entriesPerBucket = entriesPerBucket; - _y[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _y[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _yTmp = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + // Read buffers + _yBuffers[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _yBuffers[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _sortKey = allocator.CAllocSpan( entriesPerBucket ); + _metaBuffers[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _metaBuffers[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _meta[0] = Span( (TMetaIn*)allocator.CAlloc( entriesPerBucket, t2BlockSize ), entriesPerBucket ); - _meta[1] = Span( (TMetaIn*)allocator.CAlloc( entriesPerBucket, t2BlockSize ), entriesPerBucket ); - _metaTmp = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _indexBuffers[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _indexBuffers[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _index[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _index[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _map = allocator.CAllocSpan( entriesPerBucket ); - _pairBuffer = allocator.CAllocSpan ( entriesPerBucket ); + // Work buffers + _yTmp = allocator.CAllocSpan ( entriesPerBucket, t2BlockSize ); + _metaTmp[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _metaTmp[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _sortKey = allocator.CAllocSpan ( entriesPerBucket ); + _pairBuffer = allocator.CAllocSpan ( entriesPerBucket ); + + // Write buffers //#NOTE: No need, we can use the same buffer we just read from, + // as that buffer won't be in + // _yWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + // _indexWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + // _metaWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + + _map = allocator.CAllocSpan( entriesPerBucket ); _pairsL = allocator.CAllocSpan( entriesPerBucket ); _pairsR = allocator.CAllocSpan( entriesPerBucket ); } @@ -133,6 +143,14 @@ public: _pairs[i] = pairBuffer.Slice( 0, matchesPerThread ); pairBuffer = pairBuffer.Slice( matchesPerThread ); } + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + const uint32 bufIdx = i & 1; // % 2 + _y [i] = _yBuffers [bufIdx]; + _index[i] = _indexBuffers[bufIdx]; + _meta [i] = _metaBuffers [bufIdx].As(); + } } // Run mmulti-threaded @@ -140,6 +158,12 @@ public: RunMT( self ); }); + _context.entryCounts[(int)rTable] = _tableEntryCount; + + Log::Line( " Sorting : Completed in %.2lf seconds.", TicksToSeconds( _sortTime ) ); + Log::Line( " Matching: Completed in %.2lf seconds.", TicksToSeconds( _matchTime ) ); + Log::Line( " Fx : Completed in %.2lf seconds.", TicksToSeconds( _fxTime ) ); + // Ensure all I/O has completed Fence& fence = _context.fencePool->RequireFence(); fence.Reset( 0 ); @@ -154,8 +178,8 @@ private: //----------------------------------------------------------- void RunMT( Job* self ) { - const TableId lTable = rTable-1; - const uint32 threadCount = self->JobCount(); + const uint32 threadCount = self->JobCount(); + const uint32 id = self->JobId(); ReadNextBucket( self, 0 ); @@ -164,37 +188,41 @@ private: ReadNextBucket( self, bucket + 1 ); // Read next bucket in background WaitForFence( self, _yReadFence, bucket ); - // const uint32 entryCount = _context.bucketCounts[(int)lTable][bucket]; - Span yInput = _y[bucket]; const uint32 entryCount = yInput.Length(); Span sortKey = _sortKey.SliceSize( entryCount ); - SortY( self, entryCount, yInput.Ptr(), _yTmp.Ptr(), sortKey.Ptr(), _metaTmp.As().Ptr() ); + SortY( self, entryCount, yInput.Ptr(), _yTmp.As().Ptr(), sortKey.Ptr(), _metaTmp[0].As().Ptr() ); - const Span matches = Match( self, bucket, yInput ); -// WritePairs( self ); + Span matches = Match( self, bucket, yInput ); // Count the total match count - uint64 totalMatches = 0; - self->SyncThreads(); - for( uint32 i = 0; i < threadCount; i++ ) - totalMatches += _pairs[i].Length(); + uint32 totalMatches = 0; + uint32 matchOffset = 0; - // #TODO: This is only for the last table.. - // if( totalMatches > _maxTableEntries ) - // { - // // Prevent calculating fx for overflow matches - // if( self->IsLastThread() ) - // { - // const uint32 overflowEntries = (uint32)( totalMatches - _maxTableEntries ); - // ASSERT( overflowEntries < matches.Length() ); + for( uint32 i = 0; i < threadCount; i++ ) + totalMatches += (uint32)_pairs[i].Length(); + + for( uint32 i = 0; i < id; i++ ) + matchOffset += (uint32)_pairs[i].Length(); - // matches = matches.Slice( 0, matches.Length() - overflowEntries ); - // } + // Prevent overflow entries + const uint64 tableEntryCount = _tableEntryCount; + if( bucket == _numBuckets-1 && (tableEntryCount + totalMatches) > _maxTableEntries ) + { + // Prevent calculating fx for overflow matches + if( self->IsLastThread() ) + { + const uint32 overflowEntries = (uint32)( (tableEntryCount + totalMatches) - _maxTableEntries ); + ASSERT( overflowEntries < matches.Length() ); - // totalMatches = _maxTableEntries; - // } + matches = matches.SliceSize( matches.Length() - overflowEntries ); + } + + totalMatches = _maxTableEntries; + } + + // WritePairs( self, pairs, matchCount ); // Generate and write map if constexpr ( rTable > TableId::Table2 ) @@ -205,22 +233,34 @@ private: } // Sort meta on Y - WaitForFence( self, _metaReadFence, bucket ); + Span metaTmp = _meta[bucket].SliceSize( yInput.Length() ); + Span metaIn = _metaTmp[0].As().SliceSize( yInput.Length() ); - Span metaTmp = _meta[0].As().SliceSize( yInput.Length() ); - Span metaIn = _metaTmp.As().SliceSize( yInput.Length() ); + WaitForFence( self, _metaReadFence, bucket ); SortOnYKey( self, sortKey, metaTmp, metaIn ); // Gen fx - if( self->IsLastThread() ) - Span yOut = _yTmp; - Span metaOut = metaTmp.As().SliceSize( matches.Length() ); - - // GenFx( self, yInput, metaIn, matches, yOut, metaOut, bucket ); + { + Span yOut = _yTmp.Slice( matchOffset, matches.Length() ); + Span metaOut = _metaTmp[1].As().Slice( matchOffset, matches.Length() ); //( (TMetaOut*)metaTmp.Ptr(), matches.Length() ); + + TimePoint timer; + if( self->IsControlThread() ) + timer = TimerBegin(); + + GenFx( self, bucket, matches, yInput, metaIn, yOut, metaOut ); + self->SyncThreads(); + + if( self->IsControlThread() ) + _fxTime += TimerEndTicks( timer ); + } // #TODO: Write bucekt // WriteEntries( self ) + + if( self->IsControlThread() ) + _tableEntryCount += totalMatches; } } @@ -231,20 +271,28 @@ private: constexpr uint32 iterations = 4; const uint32 shiftBase = 8; + TimePoint timer; + if( self->IsControlThread() ) + timer = TimerBegin(); + uint32 shift = 0; uint32 counts [Radix]; uint32 prefixSum [Radix]; uint32 totalCounts[Radix]; - uint64 length, offset, _; - GetThreadOffsets( self, entryCount, length, offset, _ ); + uint64 length, offset, end; + GetThreadOffsets( self, entryCount, length, offset, end ); uint32* input = ySrc; uint32* tmp = yTmp; uint32* keyInput = sortKeySrc; uint32* keyTmp = sortKeyTmp; + // Gen sort key first + for( uint64 i = offset; i < end; i++ ) + sortKeySrc[i] = (uint32)i; + for( uint32 iter = 0; iter < iterations ; iter++, shift += shiftBase ) { // Zero-out the counts @@ -276,19 +324,30 @@ private: std::swap( keyInput, keyTmp ); self->SyncThreads(); } + + if( self->IsControlThread() ) + _sortTime += TimerEndTicks( timer ); } //----------------------------------------------------------- template void SortOnYKey( Job* self, const Span key, const Span input, Span output ) { + TimePoint timer; + if( self->IsControlThread() ) + timer = TimerBegin(); + uint32 count, offset, end; GetThreadOffsets( self, (uint32)key.Length(), count, offset, end ); for( uint32 i = offset; i < end; i++ ) output[i] = input[key[i]]; + self->SyncThreads(); + + if( self->IsControlThread() ) + _sortTime += TimerEndTicks( timer ); } //----------------------------------------------------------- @@ -298,13 +357,21 @@ private: const uint32 threadCount = self->JobCount(); // use metaTmp as a buffer for group boundaries - Span groupBuffer = _metaTmp.As(); + Span groupBuffer = _metaTmp[0].As(); const uint32 maxGroups = (uint32)( groupBuffer.Length() / threadCount ); Span groupIndices = groupBuffer.Slice( maxGroups * id, maxGroups ); + TimePoint timer; + if( self->IsControlThread() ) + timer = TimerBegin(); + auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); - _pairs[id] = matches; + self->SyncThreads(); + if( self->IsControlThread() ) + _matchTime += TimerEndTicks( timer ); + + _pairs[id] = matches; return matches; } @@ -383,34 +450,14 @@ private: } //----------------------------------------------------------- + template void GenFx( Job* self, - const Span yIn, - const Span metaIn, - const Span pairs ) - { - using TYOut = typename K32TYOut::Type; - using TMetaIn = typename K32MetaType::In; - using TMetaOut = typename K32MetaType::Out; - -// TMetaOut - - const Span tableMetaIn ( (TMetaIn*)metaIn.Ptr(), metaIn.Length() ); - - // Output buffers -// Span tableMetaOut( (TMetaOut*)metaOut.Ptr(), metaOut.Length() ); - -// GenFx( self, yIn, tableMetaIn, pairs, ) - } - - //----------------------------------------------------------- - template - void GenFx( Job* self, + const uint32 bucket, + const Span pairs, const Span yIn, const Span metaIn, - const Span pairs, Span yOut, - Span metaOut, - const uint32 bucket ) + Span metaOut ) { constexpr size_t MetaInMulti = TableMetaIn ::Multiplier; constexpr size_t MetaOutMulti = TableMetaOut::Multiplier; @@ -427,7 +474,7 @@ private: const size_t bufferSize = CDiv( ySize + metaSizeLR, 8 ); - const uint32 id = self->JobId(); + // const uint32 id = self->JobId(); const uint32 matchCount = pairs.Length(); const uint64 yMask = (uint64)bucket << 32; @@ -509,8 +556,8 @@ private: // const uint64 l1 = metaInB[left ]; // const uint64 r0 = metaInA[right]; // const uint64 r1 = metaInB[right]; - const Meta4 l = metaIn[left]; - const Meta4 r = metaIn[right]; + const K32Meta4 l = metaIn[left]; + const K32Meta4 r = metaIn[right]; input[0] = Swap64( y << 26 | l.m0 >> 38 ); input[1] = Swap64( l.m0 << 26 | l.m1 >> 38 ); @@ -560,14 +607,20 @@ private: //----------------------------------------------------------- void ReadNextBucket( Job* self, const uint32 bucket ) { + if( bucket >= _numBuckets ) + return; + if( !self->IsControlThread() ) return; _ioQueue.ReadBucketElementsT( _yId[0], _y[bucket] ); _ioQueue.SignalFence( _yReadFence, bucket + 1 ); - _ioQueue.ReadBucketElementsT( _idxId[0], _index[bucket] ); - _ioQueue.SignalFence( _indexReadFence, bucket + 1 ); + if constexpr ( rTable > TableId::Table2 ) + { + _ioQueue.ReadBucketElementsT( _idxId[0], _index[bucket] ); + _ioQueue.SignalFence( _indexReadFence, bucket + 1 ); + } _ioQueue.ReadBucketElementsT( _metaId[0], _meta[bucket] ); _ioQueue.SignalFence( _metaReadFence, bucket + 1 ); @@ -588,25 +641,39 @@ private: DiskPlotContext& _context; DiskBufferQueue& _ioQueue; - uint32 _entriesPerBucket = 0; + uint32 _entriesPerBucket = 0; + std::atomic _tableEntryCount = 0; // I/O FileId _yId [2]; FileId _idxId [2]; FileId _metaId[2]; + // Read buffers + Span _yBuffers [2]; + Span _indexBuffers[2]; + Span _metaBuffers [2]; + + // Read views Span _y [_numBuckets]; Span _index[_numBuckets]; Span _meta [_numBuckets]; + + // Write buffers + // Span _yWriteBuffer; + // Span _indexWriteBuffer; + // Span _metaWriteBuffer; Span _map; Span _pairsL; Span _pairsR; - // Temp working buffers - Span _yTmp; + // Working buffers + Span _yTmp; Span _sortKey; - Span _metaTmp; + Span _metaTmp[2]; Span _pairBuffer; + + // Working views Span _pairs[BB_DP_MAX_JOBS]; // Pairs buffer divided per thread // Matching @@ -621,6 +688,10 @@ private: Fence& _mapWriteFence; - // I/O wait accumulator +public: + // Timings Duration _tableIOWait = Duration::zero(); + Duration _sortTime = Duration::zero(); + Duration _matchTime = Duration::zero(); + Duration _fxTime = Duration::zero(); }; diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index a9507402..28d65a0b 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -47,7 +47,7 @@ struct MTJobSyncT // Locks the threads if this is the control thread and returns true. // otherwise, waits for release from the control thread and returns false. - inline bool LockOrWait(); + // inline bool LockOrWait(); // Utility functions to simplify control-thread locking // and releasing code. This helps keep code the same for all threads @@ -281,36 +281,44 @@ inline void MTJobSyncT::WaitForRelease() } +//----------------------------------------------------------- +// template +// inline bool MTJobSyncT::LockOrWait() +// { +// if( this->IsControlThread() ) +// { +// this->LockThreads(); +// return true; +// } +// else +// { +// this->WaitForRelease(); +// } + +// return false; +// } + //----------------------------------------------------------- template -inline bool MTJobSyncT::LockOrWait() +inline bool MTJobSyncT::BeginLockBlock() { if( this->IsControlThread() ) { this->LockThreads(); return true; } - else - { - this->WaitForRelease(); - } return false; } -//----------------------------------------------------------- -template -inline bool MTJobSyncT::BeginLockBlock() -{ - return LockOrWait(); -} - //----------------------------------------------------------- template inline void MTJobSyncT::EndLockBlock() { if( this->IsControlThread() ) this->ReleaseThreads(); + else + this->WaitForRelease(); } //----------------------------------------------------------- From d63f95aac027c7f1053a490b32a87da8f68a359f Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 19 May 2022 02:33:47 -0500 Subject: [PATCH 20/91] Working on having aligned meta slices as well --- src/plotdisk/k32/FxBounded.inl | 70 ++++++++++++++++++++++++---------- src/threading/MTJob.h | 37 ++++++++++++++---- 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 1187d44a..0c5d39e0 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -95,7 +95,6 @@ public: _indexBuffers[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - // Work buffers _yTmp = allocator.CAllocSpan ( entriesPerBucket, t2BlockSize ); _metaTmp[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); @@ -103,11 +102,19 @@ public: _sortKey = allocator.CAllocSpan ( entriesPerBucket ); _pairBuffer = allocator.CAllocSpan ( entriesPerBucket ); - // Write buffers //#NOTE: No need, we can use the same buffer we just read from, - // as that buffer won't be in - // _yWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - // _indexWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - // _metaWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _offsets = allocator.CAllocSpan( _context.fpThreadCount ); + for( uint32 i = 0; i < _offsets.Length(); i++ ) + { + Span offsets = allocator.CAllocSpan( _numBuckets ); + offsets.ZeroOutElements(); + + _offsets[i] = offsets.Ptr(); + } + + // Write buffers + _yWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _indexWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _metaWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _map = allocator.CAllocSpan( entriesPerBucket ); _pairsL = allocator.CAllocSpan( entriesPerBucket ); @@ -389,13 +396,17 @@ private: //----------------------------------------------------------- void WriteEntries( Job* self, + const uint32 bucket, const Span yIn, const Span metaIn, Span yOut, Span metaOut, - Span indices, - const uint32 bucket ) + Span idxOut ) { + const uint32 blockSize = (uint32)_ioQueue.BlockSize( _yId[1] ); + const uint32 id = (uint32)self->JobId(); + + // Distribute to buckets const uint32 logBuckets = bblog2( _numBuckets ); static_assert( kExtraBits <= logBuckets ); @@ -405,15 +416,29 @@ private: const int64 entryCount = (int64)yIn.Length(); - uint32 counts [_numBuckets] = {}; - uint32 pfxSum [_numBuckets]; -// uint32 totalCounts[_numBuckets]; - uint32* bucketSlices = _context.bucketSlices[(int)rTable & 1][bucket]; + uint32 counts [_numBuckets] = {}; + uint32 pfxSum [_numBuckets]; + uint32 pfxSumMeta [_numBuckets]; + // uint32 totalCounts [_numBuckets]; + uint32 alignedCountsY [_numBuckets]; + uint32 alignedCountsMeta[_numBuckets]; + + uint32* sliceCounts = _context.bucketSlices[(int)rTable & 1][bucket]; + uint32* offsets = _offsets[id]; for( int64 i = 0; i < entryCount; i++ ) counts[yIn[i] >> bucketShift]++; - self->CalculatePrefixSum( _numBuckets, counts, pfxSum, bucketSlices ); + self->CalculateBlockAlignedPrefixSum2( + _numBuckets, + blockSize, + counts, + pfxSum, + pfxSumMeta, + sliceCounts, + offsets, + alignedCountsY, + alignedCountsMeta ); // Distribute to buckets int64 offset, _; @@ -426,7 +451,7 @@ private: yOut [dstIdx] = (uint32)(y & yMask); metaOut[dstIdx] = metaIn[i]; - indices[dstIdx] = (uint32)(offset + i); + idxOut [dstIdx] = (uint32)(offset + i); } // Write to disk @@ -434,15 +459,15 @@ private: { // #NOTE: Should we wait per file? if( bucket > 0 ) - _fxWriteFence.Wait( bucket, _tableIOWait ); + _fxWriteFence.Wait( bucket, _tableIOWait ); const FileId yId = _yId [1]; const FileId metaId = _metaId[1]; const FileId idxId = _idxId [1]; - _ioQueue.WriteBucketElementsT( yId , yOut.Ptr() , bucketSlices ); - _ioQueue.WriteBucketElementsT( metaId, (TMetaOut*)metaOut.Ptr(), bucketSlices ); - _ioQueue.WriteBucketElementsT( idxId , indices.Ptr(), bucketSlices ); + _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), sliceCounts, alignedCountsY ); + _ioQueue.WriteBucketElementsT ( idxId , idxOut .Ptr(), sliceCounts, alignedCountsY ); + _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), sliceCounts, alignedCountsMeta ); _ioQueue.SignalFence( _fxWriteFence, bucket+1 ); _ioQueue.CommitCommands(); } @@ -660,9 +685,9 @@ private: Span _meta [_numBuckets]; // Write buffers - // Span _yWriteBuffer; - // Span _indexWriteBuffer; - // Span _metaWriteBuffer; + Span _yWriteBuffer; + Span _indexWriteBuffer; + Span _metaWriteBuffer; Span _map; Span _pairsL; Span _pairsR; @@ -679,6 +704,9 @@ private: // Matching FxMatcherBounded _matcher; + // Distributing to buckets + Span _offsets; + // I/O Synchronization fences Fence& _yReadFence; Fence& _metaReadFence; diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index 28d65a0b..30e97ee7 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -401,6 +401,26 @@ struct PrefixSumJob : public MTJob CalculatePrefixSumImpl<1>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock, offsets, alignedTotalCounts ); } + template + inline void CalculateBlockAlignedPrefixSum2( + uint32 bucketSize, + uint32 blockSize, + const TCount* counts, + TCount* pfxSum, + TCount* pfxSum2, + TCount* bucketCounts, + TCount* offsets, + TCount* alignedTotalCounts1, + TCount* alignedTotalCounts2 ) + { + const uint32 entrySize[2] = { (uint32)sizeof( EntryType1 ), (uint32)sizeof( EntryType2 ) }; + const uint32 entriesPerBlock[2] = { blockSize / entrySize[0], blockSize / entrySize[1] }; + ASSERT( entriesPerBlock[0] * entrySize[0] == blockSize ); + ASSERT( entriesPerBlock[1] * entrySize[1] == blockSize ); + + CalculatePrefixSumImpl<2>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock, offsets, alignedTotalCounts1, pfxSum2, alignedTotalCounts2 ); + } + private: template inline void CalculatePrefixSumImpl( @@ -408,10 +428,11 @@ struct PrefixSumJob : public MTJob const TCount* counts, TCount* pfxSum, TCount* bucketCounts, - const uint32* entriesPerBlocks = nullptr, - TCount* offsets = nullptr, - TCount* alignedTotalCounts = nullptr, - TCount* pfxSum2 = nullptr + const uint32* entriesPerBlocks = nullptr, + TCount* offsets = nullptr, + TCount* alignedTotalCounts = nullptr, + TCount* pfxSum2 = nullptr, + TCount* alignedTotalCounts2 = nullptr ); }; @@ -426,7 +447,8 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( const uint32* entriesPerBlocks, TCount* offsets, TCount* alignedTotalCounts, - TCount* pfxSum2 ) + TCount* pfxSum2, + TCount* alignedTotalCounts2 ) { const uint32 jobId = this->JobId(); const uint32 jobCount = this->JobCount(); @@ -456,6 +478,7 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( if constexpr ( AlignEntryCount > 0 ) { + AlignEntries: // We now need to add padding to the total counts to ensure the starting // location of each slice is block aligned. const uint32 entriesPerBlock = entriesPerBlocks[alignedEntryIndex++]; @@ -477,8 +500,8 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( const uint32 alignedEntryCount = CDivT( entryCount, entriesPerBlock ) * entriesPerBlock; offsets[i] = ( entryCount - (alignedEntryCount - entriesPerBlock) ) & modEntriesPerBlock; // Update our offset for the next round - pfxSum[i] += paddingFromPrevBucket + offset; // Update our total count for alignment purposes - alignedTotalCounts[i] = alignedEntryCount; // Set number of entries that have to be written to disk (always starts and ends at a block boundary) + pfxSum [i] += paddingFromPrevBucket + offset; // Update our total count for alignment purposes + alignedTotalCounts[i] = alignedEntryCount; // Set number of entries that have to be written to disk (always starts and ends at a block boundary) } // Add the offset to the first bucket slice as well From 77904766fd478986c195af13381e6693e8359de5 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 21 May 2022 01:02:08 -0500 Subject: [PATCH 21/91] More work on bounded FP --- .vscode/launch.json | 2 +- src/plotdisk/k32/FxBounded.inl | 132 +++++++++++++++++++-------------- src/threading/MTJob.h | 45 ++++------- 3 files changed, 89 insertions(+), 90 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 56bbaf19..e4184c21 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -80,7 +80,7 @@ "--f1-threads", "12", // "--f1-threads", "3", // "--fp-threads", "62", - "--fp-threads", "48", + "--fp-threads", "62", // "--f1-threads", "7", // "--fp-threads", "7", diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 0c5d39e0..0474a2c2 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -102,13 +102,29 @@ public: _sortKey = allocator.CAllocSpan ( entriesPerBucket ); _pairBuffer = allocator.CAllocSpan ( entriesPerBucket ); - _offsets = allocator.CAllocSpan( _context.fpThreadCount ); - for( uint32 i = 0; i < _offsets.Length(); i++ ) + const uint32 threadCount = _context.fpThreadCount; + + _sliceCountY[0] = allocator.CAllocSpan( _numBuckets ); + _sliceCountY[1] = allocator.CAllocSpan( _numBuckets ); + _sliceCountMeta[0] = allocator.CAllocSpan( _numBuckets ); + _sliceCountMeta[1] = allocator.CAllocSpan( _numBuckets ); + _alignedSliceCountY[0] = allocator.CAllocSpan( _numBuckets ); + _alignedSliceCountY[1] = allocator.CAllocSpan( _numBuckets ); + _alignedsliceCountMeta[0] = allocator.CAllocSpan( _numBuckets ); + _alignedsliceCountMeta[1] = allocator.CAllocSpan( _numBuckets ); + + _offsetsY = allocator.CAllocSpan( threadCount ); + _offsetsMeta = allocator.CAllocSpan( threadCount ); + + for( uint32 i = 0; i < _offsetsY.Length(); i++ ) { - Span offsets = allocator.CAllocSpan( _numBuckets ); - offsets.ZeroOutElements(); + Span offsetsY = allocator.CAllocSpan( _numBuckets ); + Span offsetsMeta = allocator.CAllocSpan( _numBuckets ); + offsetsY .ZeroOutElements(); + offsetsMeta.ZeroOutElements(); - _offsets[i] = offsets.Ptr(); + _offsetsY [i] = offsetsY .Ptr(); + _offsetsMeta[i] = offsetsMeta.Ptr(); } // Write buffers @@ -167,17 +183,13 @@ public: _context.entryCounts[(int)rTable] = _tableEntryCount; - Log::Line( " Sorting : Completed in %.2lf seconds.", TicksToSeconds( _sortTime ) ); - Log::Line( " Matching: Completed in %.2lf seconds.", TicksToSeconds( _matchTime ) ); - Log::Line( " Fx : Completed in %.2lf seconds.", TicksToSeconds( _fxTime ) ); + Log::Line( " Sorting : Completed in %.2lf seconds.", TicksToSeconds( _sortTime ) ); + Log::Line( " Distribution : Completed in %.2lf seconds.", TicksToSeconds( _distributeTime ) ); + Log::Line( " Matching : Completed in %.2lf seconds.", TicksToSeconds( _matchTime ) ); + Log::Line( " Fx : Completed in %.2lf seconds.", TicksToSeconds( _fxTime ) ); // Ensure all I/O has completed - Fence& fence = _context.fencePool->RequireFence(); - fence.Reset( 0 ); - _ioQueue.SignalFence( fence, 1 ); - _ioQueue.CommitCommands(); - fence.Wait(); - + _fxWriteFence.Wait( _numBuckets, _tableIOWait ); _context.fencePool->RestoreAllFences(); } @@ -246,7 +258,7 @@ private: WaitForFence( self, _metaReadFence, bucket ); SortOnYKey( self, sortKey, metaTmp, metaIn ); - // Gen fx + // Gen fx & write { Span yOut = _yTmp.Slice( matchOffset, matches.Length() ); Span metaOut = _metaTmp[1].As().Slice( matchOffset, matches.Length() ); //( (TMetaOut*)metaTmp.Ptr(), matches.Length() ); @@ -254,17 +266,15 @@ private: TimePoint timer; if( self->IsControlThread() ) timer = TimerBegin(); - + GenFx( self, bucket, matches, yInput, metaIn, yOut, metaOut ); self->SyncThreads(); if( self->IsControlThread() ) _fxTime += TimerEndTicks( timer ); - } - - // #TODO: Write bucekt -// WriteEntries( self ) + WriteEntries( self, bucket, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); + } if( self->IsControlThread() ) _tableEntryCount += totalMatches; @@ -398,15 +408,18 @@ private: void WriteEntries( Job* self, const uint32 bucket, const Span yIn, - const Span metaIn, + const Span metaIn, Span yOut, Span metaOut, Span idxOut ) { + TimePoint timer; + if( self->IsControlThread() ) + timer = TimerBegin(); + const uint32 blockSize = (uint32)_ioQueue.BlockSize( _yId[1] ); const uint32 id = (uint32)self->JobId(); - // Distribute to buckets const uint32 logBuckets = bblog2( _numBuckets ); static_assert( kExtraBits <= logBuckets ); @@ -416,29 +429,22 @@ private: const int64 entryCount = (int64)yIn.Length(); - uint32 counts [_numBuckets] = {}; - uint32 pfxSum [_numBuckets]; - uint32 pfxSumMeta [_numBuckets]; - // uint32 totalCounts [_numBuckets]; - uint32 alignedCountsY [_numBuckets]; - uint32 alignedCountsMeta[_numBuckets]; - - uint32* sliceCounts = _context.bucketSlices[(int)rTable & 1][bucket]; - uint32* offsets = _offsets[id]; + uint32 counts [_numBuckets] = {}; + uint32 pfxSum [_numBuckets]; + uint32 pfxSumMeta[_numBuckets]; + + const uint32 sliceIdx = bucket & 1; // % 2 + + Span ySliceCounts = _sliceCountY[sliceIdx]; + Span metaSliceCounts = _sliceCountMeta[sliceIdx]; + Span yAlignedSliceCount = _alignedSliceCountY[sliceIdx]; + Span metaAlignedsliceCount = _alignedsliceCountMeta[sliceIdx]; for( int64 i = 0; i < entryCount; i++ ) counts[yIn[i] >> bucketShift]++; - self->CalculateBlockAlignedPrefixSum2( - _numBuckets, - blockSize, - counts, - pfxSum, - pfxSumMeta, - sliceCounts, - offsets, - alignedCountsY, - alignedCountsMeta ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, ySliceCounts.Ptr(), _offsetsY[id], yAlignedSliceCount.Ptr() ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaAlignedsliceCount.Ptr(), _offsetsMeta[id], metaAlignedsliceCount.Ptr() ); // Distribute to buckets int64 offset, _; @@ -446,12 +452,14 @@ private: for( int64 i = 0; i < entryCount; i++ ) { - const uint64 y = yIn[i]; - const uint32 dstIdx = --pfxSum[y >> bucketShift]; - - yOut [dstIdx] = (uint32)(y & yMask); - metaOut[dstIdx] = metaIn[i]; - idxOut [dstIdx] = (uint32)(offset + i); + const uint64 y = yIn[i]; + const uint32 yBucket = (uint32)(y >> bucketShift); + const uint32 yDst = --pfxSum [yBucket]; + const uint32 metaDst = --pfxSumMeta[yBucket]; + + yOut [yDst] = (uint32)(y & yMask); + idxOut [yDst] = (uint32)(offset + i); + metaOut[metaDst] = metaIn[i]; } // Write to disk @@ -465,13 +473,17 @@ private: const FileId metaId = _metaId[1]; const FileId idxId = _idxId [1]; - _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), sliceCounts, alignedCountsY ); - _ioQueue.WriteBucketElementsT ( idxId , idxOut .Ptr(), sliceCounts, alignedCountsY ); - _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), sliceCounts, alignedCountsMeta ); + _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); + _ioQueue.WriteBucketElementsT ( idxId , idxOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), metaAlignedsliceCount.Ptr(), metaSliceCounts.Ptr() ); _ioQueue.SignalFence( _fxWriteFence, bucket+1 ); _ioQueue.CommitCommands(); } self->EndLockBlock(); + + + if( self->IsControlThread() ) + _distributeTime += TimerEndTicks( timer ); } //----------------------------------------------------------- @@ -663,8 +675,8 @@ private: } private: - DiskPlotContext& _context; - DiskBufferQueue& _ioQueue; + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; uint32 _entriesPerBucket = 0; std::atomic _tableEntryCount = 0; @@ -705,7 +717,12 @@ private: FxMatcherBounded _matcher; // Distributing to buckets - Span _offsets; + Span _offsetsY; + Span _offsetsMeta; + Span _sliceCountY [2]; + Span _sliceCountMeta[2]; + Span _alignedSliceCountY [2]; + Span _alignedsliceCountMeta[2]; // I/O Synchronization fences Fence& _yReadFence; @@ -718,8 +735,9 @@ private: public: // Timings - Duration _tableIOWait = Duration::zero(); - Duration _sortTime = Duration::zero(); - Duration _matchTime = Duration::zero(); - Duration _fxTime = Duration::zero(); + Duration _tableIOWait = Duration::zero(); + Duration _sortTime = Duration::zero(); + Duration _distributeTime = Duration::zero(); + Duration _matchTime = Duration::zero(); + Duration _fxTime = Duration::zero(); }; diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index 30e97ee7..e51f6ef2 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -401,26 +401,6 @@ struct PrefixSumJob : public MTJob CalculatePrefixSumImpl<1>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock, offsets, alignedTotalCounts ); } - template - inline void CalculateBlockAlignedPrefixSum2( - uint32 bucketSize, - uint32 blockSize, - const TCount* counts, - TCount* pfxSum, - TCount* pfxSum2, - TCount* bucketCounts, - TCount* offsets, - TCount* alignedTotalCounts1, - TCount* alignedTotalCounts2 ) - { - const uint32 entrySize[2] = { (uint32)sizeof( EntryType1 ), (uint32)sizeof( EntryType2 ) }; - const uint32 entriesPerBlock[2] = { blockSize / entrySize[0], blockSize / entrySize[1] }; - ASSERT( entriesPerBlock[0] * entrySize[0] == blockSize ); - ASSERT( entriesPerBlock[1] * entrySize[1] == blockSize ); - - CalculatePrefixSumImpl<2>( bucketSize, counts, pfxSum, bucketCounts, &entriesPerBlock, offsets, alignedTotalCounts1, pfxSum2, alignedTotalCounts2 ); - } - private: template inline void CalculatePrefixSumImpl( @@ -428,11 +408,10 @@ struct PrefixSumJob : public MTJob const TCount* counts, TCount* pfxSum, TCount* bucketCounts, - const uint32* entriesPerBlocks = nullptr, - TCount* offsets = nullptr, - TCount* alignedTotalCounts = nullptr, - TCount* pfxSum2 = nullptr, - TCount* alignedTotalCounts2 = nullptr + const uint32* entriesPerBlocks = nullptr, + TCount* offsets = nullptr, + TCount* alignedTotalCounts = nullptr, + TCount* pfxSum2 = nullptr ); }; @@ -447,8 +426,7 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( const uint32* entriesPerBlocks, TCount* offsets, TCount* alignedTotalCounts, - TCount* pfxSum2, - TCount* alignedTotalCounts2 ) + TCount* pfxSum2 ) { const uint32 jobId = this->JobId(); const uint32 jobCount = this->JobCount(); @@ -478,7 +456,6 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( if constexpr ( AlignEntryCount > 0 ) { - AlignEntries: // We now need to add padding to the total counts to ensure the starting // location of each slice is block aligned. const uint32 entriesPerBlock = entriesPerBlocks[alignedEntryIndex++]; @@ -500,8 +477,10 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( const uint32 alignedEntryCount = CDivT( entryCount, entriesPerBlock ) * entriesPerBlock; offsets[i] = ( entryCount - (alignedEntryCount - entriesPerBlock) ) & modEntriesPerBlock; // Update our offset for the next round - pfxSum [i] += paddingFromPrevBucket + offset; // Update our total count for alignment purposes - alignedTotalCounts[i] = alignedEntryCount; // Set number of entries that have to be written to disk (always starts and ends at a block boundary) + pfxSum[i] += paddingFromPrevBucket + offset; + + if( this->IsControlThread() ) + alignedTotalCounts[i] = alignedEntryCount; // Set number of entries that have to be written to disk (always starts and ends at a block boundary) } // Add the offset to the first bucket slice as well @@ -509,8 +488,10 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( const uint32 b0AlignedCount = CDivT( pfxSum[0], entriesPerBlock ) * entriesPerBlock; - offsets[0] = ( pfxSum[0] - (b0AlignedCount - entriesPerBlock) ) & modEntriesPerBlock; - alignedTotalCounts[0] = b0AlignedCount; + offsets[0] = ( pfxSum[0] - (b0AlignedCount - entriesPerBlock) ) & modEntriesPerBlock; + + if( this->IsControlThread() ) + alignedTotalCounts[0] = b0AlignedCount; } // Calculate the prefix sum From 12b67b4c6efa0e0da9c0bd13d50dfa83e110f4f5 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 25 May 2022 06:15:15 -0500 Subject: [PATCH 22/91] Getting Pairs and Maps written to disk on bounded mode --- src/plotdisk/k32/FxBounded.inl | 89 ++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 10 deletions(-) diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 0474a2c2..b5012829 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -34,6 +34,12 @@ class DiskPlotFxBounded using Job = AnonPrefixSumJob; static constexpr uint32 _k = 32; static constexpr uint64 _maxTableEntries = (1ull << _k) - 1; + static constexpr uint32 _bucketBits = bblog2( _numBuckets ); + + static constexpr uint32 _pairsMaxDelta = 512; + static constexpr uint32 _pairsRightBits = bblog2( _pairsMaxDelta ); + static constexpr uint32 _pairBitSize = _k - _bucketBits + _pairsRightBits; + public: @@ -133,8 +139,14 @@ public: _metaWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _map = allocator.CAllocSpan( entriesPerBucket ); - _pairsL = allocator.CAllocSpan( entriesPerBucket ); - _pairsR = allocator.CAllocSpan( entriesPerBucket ); + + byte* pairBlocks = (byte*)alloc.CAlloc( 1, t1BlockSize, t1BlockSize ); + _pairBitWriter = BitBucketWriter<1>( _ioQueue, FileId::T1 + (FileId)rTable, pairBlocks ); + + const size_t pairsWriteSize = CDiv( entriesPerBucket * _pairBitSize, 8 ); + _pairsWriteBuffer = allocator.AllocT( pairsWriteSize, t1BlockSize ) + // _pairsL = allocator.CAllocSpan( entriesPerBucket ); + // _pairsR = allocator.CAllocSpan( entriesPerBucket ); } // Generate fx for a whole table @@ -241,7 +253,7 @@ private: totalMatches = _maxTableEntries; } - // WritePairs( self, pairs, matchCount ); + WritePairs( self, matches ); // Generate and write map if constexpr ( rTable > TableId::Table2 ) @@ -395,13 +407,70 @@ private: //----------------------------------------------------------- void WriteMap( Job* self, const Span indexInput, const Span sortKey ) { - + } //----------------------------------------------------------- - void WritePairs( Job* self, const Span pairs, const int64 matchCount, const uint32 bucket ) + void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, const Span matches, const uint64 dstOffset ) { + // Need to wait for our write buffer to be ready to use again + + if( self->BeginLockBlock() ) + { + if( bucket > 0 ) + _pairWriteFence.Wait( bucket ); + + uint64 bitBucketSizes = totalMatchCount * _pairBitSize; + _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer.Ptr() ); + } + self->EndLockBlock(); + // #TOOD: Write pairs raw? Or bucket-relative? Maybe raw for now + // for( uint64 i = 0; i < matches.Length(); i++ ) + // { + // const Pair& pair = matches[i]; + + // outLeft [i] = pair.left; + // outRight[i] = (uint16)(pair.right - pair.left); + // } + + // #NOTE: For now we write compressed as in standard FP. + BitWriter writer = _pairBitWriter.GetWriter( 0, dstOffset * _pairBitSize ); + + ASSERT( matches.Length() > 2 ); + PackPairs( self, matches.Slice( 0, 2 ), writer ); + self->SyncThreads(); + PackPairs( self, matches.Slice( 2 ), writer ); + + // Write to disk + if( self->BeginLockBlock() ) + { + // _ioQueue.WriteFile( FileId::T1 + (FileId)rTable, bucket, ) + _pairBitWriter.Submit(); + _ioQueue.SignalFence( _pairWriteFence, bucket + 1 ); + _ioQueue.CommitCommands(); + } + self->EndLockBlock(); + } + + //----------------------------------------------------------- + void PackPairs( Job* self, const Span pairs, BitWriter& writer ) + { + self; + + const uint32 shift = _pairsRightBits; + const uint64 mask = ( 1ull << shift ) - 1; + + const Pair* pair = pairs.Ptr(); + const Pair* end = pair + pairs.Length(); + + while( pair < end ) + { + ASSERT( pair->right - pair->left < _pairsMaxDelta ); + + writer.Write( ( (uint64)(pair->right - pair->left) << shift ) | ( pair->left & mask ), _pairBitSize ); + pair++; + } } //----------------------------------------------------------- @@ -682,9 +751,10 @@ private: std::atomic _tableEntryCount = 0; // I/O - FileId _yId [2]; - FileId _idxId [2]; - FileId _metaId[2]; + FileId _yId [2]; + FileId _idxId [2]; + FileId _metaId[2]; + BitBucketWriter<1> _pairBitWriter; // Read buffers Span _yBuffers [2]; @@ -701,8 +771,7 @@ private: Span _indexWriteBuffer; Span _metaWriteBuffer; Span _map; - Span _pairsL; - Span _pairsR; + Span _pairsWriteBuffer; // Working buffers Span _yTmp; From 9ad6150751410fa37a8ab64a51c5c19684f5212f Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 25 May 2022 19:06:52 -0500 Subject: [PATCH 23/91] Adding/testing pair writing --- src/plotdisk/DiskFp.h | 6 ++-- src/plotdisk/k32/DiskPlotBounded.cpp | 46 +++++++++++++++++++--------- src/plotdisk/k32/F1Bounded.inl | 1 + src/plotdisk/k32/FxBounded.inl | 41 ++++++++++++------------- 4 files changed, 55 insertions(+), 39 deletions(-) diff --git a/src/plotdisk/DiskFp.h b/src/plotdisk/DiskFp.h index d353d904..f70f530e 100644 --- a/src/plotdisk/DiskFp.h +++ b/src/plotdisk/DiskFp.h @@ -5,9 +5,9 @@ #include "plotdisk/DiskPlotContext.h" #include "plotdisk/FpGroupMatcher.h" #include "plotdisk/FpFxGen.h" -#include "DiskPlotInfo.h" -#include "BitBucketWriter.h" -#include "BlockWriter.h" +#include "plotdisk/BlockWriter.h" +#include "plotdisk/DiskPlotInfo.h" +#include "plotdisk/BitBucketWriter.h" #include "util/StackAllocator.h" #include "plotting/TableWriter.h" diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index da86549e..059558e4 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -19,20 +19,38 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) const uint32 numBuckets = context.numBuckets; // Open files - FileSetOptions opts = FileSetOptions::None | FileSetOptions::Interleaved; - - if( !context.cfg->noTmp2DirectIO ) - opts |= FileSetOptions::DirectIO; - - FileSetInitData data = {}; - opts |= FileSetOptions::UseTemp2; - - _ioQueue.InitFileSet( FileId::FX0 , "y0" , numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::FX1 , "y1" , numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::INDEX0, "index0", numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::INDEX1, "index1", numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::META0 , "meta0" , numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::META1 , "meta1" , numBuckets, opts, &data ); + + // Temp1 + { + + const FileSetOptions tmp1Options = context.cfg->noTmp1DirectIO ? FileSetOptions::None : FileSetOptions::DirectIO; + + _ioQueue.InitFileSet( FileId::T1, "t1", 1, tmp1Options, nullptr ); // X (sorted on Y) + _ioQueue.InitFileSet( FileId::T2, "t2", 1, tmp1Options, nullptr ); // Back pointers + _ioQueue.InitFileSet( FileId::T3, "t3", 1, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::T4, "t4", 1, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::T5, "t5", 1, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::T6, "t6", 1, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::T7, "t7", 1, tmp1Options, nullptr ); + } + + // Temp2 + { + FileSetOptions opts = FileSetOptions::None | FileSetOptions::Interleaved; + + if( !context.cfg->noTmp2DirectIO ) + opts |= FileSetOptions::DirectIO; + + FileSetInitData data = {}; + opts |= FileSetOptions::UseTemp2; + + _ioQueue.InitFileSet( FileId::FX0 , "y0" , numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::FX1 , "y1" , numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::INDEX0, "index0", numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::INDEX1, "index1", numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::META0 , "meta0" , numBuckets, opts, &data ); + _ioQueue.InitFileSet( FileId::META1 , "meta1" , numBuckets, opts, &data ); + } } //----------------------------------------------------------- diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 72e1cac1..cfb8af63 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -166,6 +166,7 @@ private: self->EndLockBlock(); // #NOTE: Somehow we're not getting synced here... So sync explicitly again + // #NOTE2: The issue is still happening even with this sync. self->SyncThreads(); } diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index b5012829..4fe491b3 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -2,6 +2,7 @@ #include "plotdisk/DiskPlotContext.h" #include "plotdisk/DiskPlotConfig.h" #include "plotdisk/DiskBufferQueue.h" +#include "plotdisk/BitBucketWriter.h" #include "util/StackAllocator.h" #include "FpMatchBounded.inl" #include "b3/blake3.h" @@ -77,14 +78,14 @@ public: DiskPlotFxBounded instance( cx ); DummyAllocator allocator; - instance.AllocateBuffers( allocator, t1BlockSize, t2BlockSize ); + instance.AllocateBuffers( allocator, t1BlockSize, t2BlockSize, true ); const size_t requiredSize = allocator.Size(); return requiredSize; } //----------------------------------------------------------- - void AllocateBuffers( IAllocator& allocator, const size_t t1BlockSize, const size_t t2BlockSize ) + void AllocateBuffers( IAllocator& allocator, const size_t t1BlockSize, const size_t t2BlockSize, const bool dryRun ) { const uint64 kEntryCount = 1ull << _k; const uint64 entriesPerBucket = (uint64)( kEntryCount / _numBuckets * BB_DP_XTRA_ENTRIES_PER_BUCKET ); @@ -138,13 +139,14 @@ public: _indexWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _metaWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _map = allocator.CAllocSpan( entriesPerBucket ); - - byte* pairBlocks = (byte*)alloc.CAlloc( 1, t1BlockSize, t1BlockSize ); - _pairBitWriter = BitBucketWriter<1>( _ioQueue, FileId::T1 + (FileId)rTable, pairBlocks ); + _map = allocator.CAllocSpan( entriesPerBucket ); const size_t pairsWriteSize = CDiv( entriesPerBucket * _pairBitSize, 8 ); - _pairsWriteBuffer = allocator.AllocT( pairsWriteSize, t1BlockSize ) + _pairsWriteBuffer = allocator.AllocT( pairsWriteSize, t1BlockSize ); + byte* pairBlocks = (byte*)allocator.CAlloc( 1, t1BlockSize, t1BlockSize ); + + if( !dryRun ) + _pairBitWriter = BitBucketWriter<1>( _ioQueue, FileId::T1 + (FileId)rTable, pairBlocks ); // _pairsL = allocator.CAllocSpan( entriesPerBucket ); // _pairsR = allocator.CAllocSpan( entriesPerBucket ); } @@ -164,7 +166,7 @@ public: // Allocate buffers StackAllocator allocator( _context.heapBuffer, _context.heapSize ); - AllocateBuffers( allocator, _context.tmp1BlockSize, _context.tmp2BlockSize ); + AllocateBuffers( allocator, _context.tmp1BlockSize, _context.tmp2BlockSize, false ); // Init buffers const uint32 threadCount = _context.fpThreadCount; @@ -230,13 +232,15 @@ private: // Count the total match count uint32 totalMatches = 0; uint32 matchOffset = 0; - + for( uint32 i = 0; i < threadCount; i++ ) totalMatches += (uint32)_pairs[i].Length(); for( uint32 i = 0; i < id; i++ ) matchOffset += (uint32)_pairs[i].Length(); + ASSERT( totalMatches <= _entriesPerBucket ); + // Prevent overflow entries const uint64 tableEntryCount = _tableEntryCount; if( bucket == _numBuckets-1 && (tableEntryCount + totalMatches) > _maxTableEntries ) @@ -253,7 +257,7 @@ private: totalMatches = _maxTableEntries; } - WritePairs( self, matches ); + WritePairs( self, bucket, totalMatches, matches, matchOffset ); // Generate and write map if constexpr ( rTable > TableId::Table2 ) @@ -395,12 +399,12 @@ private: timer = TimerBegin(); auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); + _pairs[id] = matches; self->SyncThreads(); if( self->IsControlThread() ) _matchTime += TimerEndTicks( timer ); - _pairs[id] = matches; return matches; } @@ -413,26 +417,20 @@ private: //----------------------------------------------------------- void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, const Span matches, const uint64 dstOffset ) { + ASSERT( dstOffset + matches.length <= totalMatchCount ); + // Need to wait for our write buffer to be ready to use again - if( self->BeginLockBlock() ) { if( bucket > 0 ) _pairWriteFence.Wait( bucket ); uint64 bitBucketSizes = totalMatchCount * _pairBitSize; - _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer.Ptr() ); + _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer ); } self->EndLockBlock(); // #TOOD: Write pairs raw? Or bucket-relative? Maybe raw for now - // for( uint64 i = 0; i < matches.Length(); i++ ) - // { - // const Pair& pair = matches[i]; - - // outLeft [i] = pair.left; - // outRight[i] = (uint16)(pair.right - pair.left); - // } // #NOTE: For now we write compressed as in standard FP. BitWriter writer = _pairBitWriter.GetWriter( 0, dstOffset * _pairBitSize ); @@ -445,7 +443,6 @@ private: // Write to disk if( self->BeginLockBlock() ) { - // _ioQueue.WriteFile( FileId::T1 + (FileId)rTable, bucket, ) _pairBitWriter.Submit(); _ioQueue.SignalFence( _pairWriteFence, bucket + 1 ); _ioQueue.CommitCommands(); @@ -771,7 +768,7 @@ private: Span _indexWriteBuffer; Span _metaWriteBuffer; Span _map; - Span _pairsWriteBuffer; + byte* _pairsWriteBuffer; // Working buffers Span _yTmp; From cf276b5c33a9a7509cde82e95e9c2c696708e672 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 26 May 2022 03:49:55 -0500 Subject: [PATCH 24/91] Working on fp map writing --- src/plotdisk/DiskPlotPhase3.cpp | 200 +-------------- src/plotdisk/MapWriter.h | 352 +++++++++++++++++++++++++++ src/plotdisk/k32/DiskPlotBounded.cpp | 7 + src/plotdisk/k32/FxBounded.inl | 101 +++++++- 4 files changed, 451 insertions(+), 209 deletions(-) create mode 100644 src/plotdisk/MapWriter.h diff --git a/src/plotdisk/DiskPlotPhase3.cpp b/src/plotdisk/DiskPlotPhase3.cpp index 3d07b428..99e750f6 100644 --- a/src/plotdisk/DiskPlotPhase3.cpp +++ b/src/plotdisk/DiskPlotPhase3.cpp @@ -1,6 +1,7 @@ #include "DiskPlotPhase3.h" #include "util/BitField.h" #include "plotdisk/BitBucketWriter.h" +#include "plotdisk/MapWriter.h" #include "plotmem/LPGen.h" #include "algorithm/RadixSort.h" #include "plotting/TableWriter.h" @@ -117,205 +118,6 @@ class EntrySort }; -template -class MapWriter -{ -public: - static constexpr uint32 _k = _K; - static constexpr uint32 BucketBits = bblog2( _numBuckets ); - static constexpr uint32 AddressBitSize = _overflow ? _k + 1 : _k; - static constexpr uint32 EntryBitSize = _k - BucketBits + AddressBitSize; // ( origin address | final address ) ( k-log2(buckets) | 32 ) - -public: - - //----------------------------------------------------------- - MapWriter() {} - - //----------------------------------------------------------- - MapWriter( DiskBufferQueue& ioQueue, const FileId fileId, IAllocator& allocator, const uint64 maxEntries, const size_t blockSize, - Fence& writeFence, Duration& writeWaitTime ) - : _ioQueue ( &ioQueue ) - , _bucketWriter ( ioQueue, fileId, (byte*)allocator.CAlloc( _numBuckets+1, blockSize, blockSize ) ) - , _writeFence ( &writeFence ) - , _writeWaitTime( &writeWaitTime ) - { - const size_t writeBufferSize = RoundUpToNextBoundary( CDiv( maxEntries * EntryBitSize, 8 ), (int)blockSize ); - - _writebuffers[0] = allocator.AllocT( writeBufferSize, blockSize ); - _writebuffers[1] = allocator.AllocT( writeBufferSize, blockSize ); - } - - //----------------------------------------------------------- - void Write( ThreadPool& pool, const uint32 threadCount, - const uint32 bucket, const int64 entryCount, const uint64 mapOffset, - const uint64* map, uint64* outMap, uint64 outMapBucketCounts[_numBuckets+1] ) - { - // Write the key as a map to the final entry location. - // We do this by writing into buckets to final sorted (current) location - // into its original bucket, with the offset in that bucket. - using Job = AnonPrefixSumJob; - - uint32 _totalCounts [_numBuckets+1]; uint32* totalCounts = _totalCounts; - uint64 _totalBitCounts[_numBuckets+1]; uint64* totalBitCounts = _totalBitCounts; - - Job::Run( pool, threadCount, [=]( Job* self ) { - - const uint32 bucketBits = BucketBits; - const uint32 bucketShift = _k - bucketBits; - const uint32 bitSize = EntryBitSize; - const uint32 encodeShift = AddressBitSize; - const uint32 numBuckets = _numBuckets + 1; - - - int64 count, offset, end; - GetThreadOffsets( self, entryCount, count, offset, end ); - - uint32 counts[numBuckets] = { 0 }; - uint32 pfxSum[numBuckets]; - - const uint64* inIdx = map + offset; - const uint64* inIdxEnd = map + end; - - // Count buckets - do { - const uint64 b = *inIdx >> bucketShift; - ASSERT( b < numBuckets ); - counts[b]++; - } while( ++inIdx < inIdxEnd ); - - self->CalculatePrefixSum( numBuckets, counts, pfxSum, totalCounts ); - - // Convert map entries from source index to reverse map - const uint64 tableOffset = mapOffset + (uint64)offset; - - const uint64* reverseMap = map + offset; - uint64* outMapBuckets = outMap; - - for( int64 i = 0; i < count; i++ ) - { - const uint64 origin = reverseMap[i]; ASSERT( origin < 0x100000000 + (1ull<<_k) / _numBuckets ); - const uint64 b = origin >> bucketShift; ASSERT( b <= _numBuckets ); - const uint32 dstIdx = --pfxSum[b]; ASSERT( (int64)dstIdx < entryCount ); - - const uint64 finalIdx = tableOffset + (uint64)i; - ASSERT( finalIdx < ( 1ull << encodeShift ) ); - - outMapBuckets[dstIdx] = (origin << encodeShift) | finalIdx; - } - - auto& bitWriter = _bucketWriter; - uint64* bitCounts = totalBitCounts; - - if( self->IsControlThread() ) - { - self->LockThreads(); - - // Convert counts to bit sizes - for( uint32 i = 0; i < numBuckets; i++ ) - bitCounts[i] = (uint64)totalCounts[i] * bitSize; - - byte* writeBuffer = GetWriteBuffer( bucket ); - - // Wait for the buffer to be available first - if( bucket > 1 ) - _writeFence->Wait( bucket - 2, *_writeWaitTime ); - - bitWriter.BeginWriteBuckets( bitCounts, writeBuffer ); - - self->ReleaseThreads(); - } - else - self->WaitForRelease(); - - - // Bit-compress/pack each bucket entries (except the overflow bucket) - uint64 bitsWritten = 0; - - for( uint32 i = 0; i < _numBuckets; i++ ) - { - if( counts[i] < 1 ) - { - self->SyncThreads(); - continue; - } - - const uint64 writeOffset = pfxSum[i]; - const uint64 bitOffset = writeOffset * bitSize - bitsWritten; - bitsWritten += bitCounts[i]; - - ASSERT( bitOffset + counts[i] * bitSize <= bitCounts[i] ); - - BitWriter writer = bitWriter.GetWriter( i, bitOffset ); - - const uint64* mapToWrite = outMapBuckets + writeOffset; - const uint64* mapToWriteEnd = mapToWrite + counts[i]; - - // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields - const uint64* mapToWriteEndPass1 = mapToWrite + std::min( counts[i], 2u ); - ASSERT( counts[i] > 2 ); - - while( mapToWrite < mapToWriteEndPass1 ) - writer.Write( *mapToWrite++, bitSize ); - - self->SyncThreads(); - - while( mapToWrite < mapToWriteEnd ) - writer.Write( *mapToWrite++, bitSize ); - } - - // Write the overflow bucket and then write to disk - self->SyncThreads(); - if( self->IsControlThread() ) - { - const uint32 overflowBucket = _numBuckets; - const uint64 overflowCount = totalCounts[overflowBucket]; - - if( overflowCount ) - { - const uint64 writeOffset = pfxSum[overflowBucket]; - ASSERT( writeOffset * bitSize - bitsWritten == 0 ); - - BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); - - const uint64* mapToWrite = outMapBuckets + writeOffset; - const uint64* mapWriteEnd = mapToWrite + overflowCount; - while( mapToWrite < mapWriteEnd ) - writer.Write( *mapToWrite++, bitSize ); - } - - bitWriter.Submit(); - _ioQueue->SignalFence( *_writeFence, bucket ); - _ioQueue->CommitCommands(); - } - }); - - for( int32 b = 0; b <= (int32)_numBuckets; b++ ) - outMapBucketCounts[b] += totalCounts[b]; - } - - //----------------------------------------------------------- - void SubmitFinalBits() - { - _bucketWriter.SubmitLeftOvers(); - _ioQueue->SignalFence( *_writeFence, _numBuckets ); - _ioQueue->CommitCommands(); - } - -private: - //----------------------------------------------------------- - inline byte* GetWriteBuffer( const uint32 bucket ) - { - return _writebuffers[bucket & 1]; - } - -private: - DiskBufferQueue* _ioQueue = nullptr; - BitBucketWriter<_numBuckets+1> _bucketWriter; - byte* _writebuffers[2] = { nullptr }; - Fence* _writeFence = nullptr; - Duration* _writeWaitTime = nullptr; -}; - template class P3StepOne { diff --git a/src/plotdisk/MapWriter.h b/src/plotdisk/MapWriter.h new file mode 100644 index 00000000..62cc1912 --- /dev/null +++ b/src/plotdisk/MapWriter.h @@ -0,0 +1,352 @@ +#pragma once +#include "threading/Fence.h" +#include "util/StackAllocator.h" + +template +class MapWriter +{ +public: + static constexpr uint32 _k = _K; + static constexpr uint32 BucketBits = bblog2( _numBuckets ); + static constexpr uint32 ExtraBucket = _overflow ? 1 : 0; + static constexpr uint32 AddressBitSize = _k + ExtraBucket; + static constexpr uint32 EntryBitSize = _k - BucketBits + AddressBitSize; // ( origin address | final address ) ( k-log2(buckets) | 32 ) + + using Job = AnonPrefixSumJob; + +public: + + //----------------------------------------------------------- + MapWriter() {} + + //----------------------------------------------------------- + MapWriter( DiskBufferQueue& ioQueue, const FileId fileId, + IAllocator& allocator, const uint64 maxEntries, const size_t blockSize, + Fence& writeFence, Duration& writeWaitTime ) + : _ioQueue ( &ioQueue ) + , _bucketWriter ( ioQueue, fileId, AllocBucketWriterBuffer( allocator, blockSize ) ) + , _writeFence ( &writeFence ) + , _writeWaitTime( &writeWaitTime ) + { + AllocateWriteBuffers( maxEntries, allocator, blockSize ); + } + + // #NOTE: Use only to determine allocation size + //----------------------------------------------------------- + MapWriter( const uint64 maxEntries, IAllocator& allocator, const size_t blockSize ) + { + AllocBucketWriterBuffer( allocator, blockSize ); + AllocateWriteBuffers( maxEntries, allocator, blockSize ); + } + + //----------------------------------------------------------- + void Write( ThreadPool& pool, const uint32 threadCount, + const uint32 bucket, const int64 entryCount, const uint64 mapOffset, + const uint64* map, uint64* outMap, uint64 outMapBucketCounts[_numBuckets+ExtraBucket] ) + { + // Write the key as a map to the final entry location. + // We do this by writing into buckets to final sorted (current) location + // into its original bucket, with the offset in that bucket. + using Job = AnonPrefixSumJob; + + uint32 _totalCounts [_numBuckets+ExtraBucket]; uint32* totalCounts = _totalCounts; + uint64 _totalBitCounts[_numBuckets+ExtraBucket]; uint64* totalBitCounts = _totalBitCounts; + + Job::Run( pool, threadCount, [=]( Job* self ) { + + const uint32 bucketBits = BucketBits; + const uint32 bucketShift = _k - bucketBits; + const uint32 bitSize = EntryBitSize; + const uint32 encodeShift = AddressBitSize; + const uint32 numBuckets = _numBuckets + ExtraBucket; + + + int64 count, offset, end; + GetThreadOffsets( self, entryCount, count, offset, end ); + + uint32 counts[numBuckets] = { 0 }; + uint32 pfxSum[numBuckets]; + + const uint64* inIdx = map + offset; + const uint64* inIdxEnd = map + end; + + // Count buckets + do { + const uint64 b = *inIdx >> bucketShift; + ASSERT( b < numBuckets ); + counts[b]++; + } while( ++inIdx < inIdxEnd ); + + self->CalculatePrefixSum( numBuckets, counts, pfxSum, totalCounts ); + + // Convert map entries from source index to reverse map + const uint64 tableOffset = mapOffset + (uint64)offset; + + const uint64* reverseMap = map + offset; + uint64* outMapBuckets = outMap; + + for( int64 i = 0; i < count; i++ ) + { + const uint64 origin = reverseMap[i]; ASSERT( origin < 0x100000000 + (1ull<<_k) / _numBuckets ); + const uint64 b = origin >> bucketShift; ASSERT( b <= _numBuckets ); + const uint32 dstIdx = --pfxSum[b]; ASSERT( (int64)dstIdx < entryCount ); + + const uint64 finalIdx = tableOffset + (uint64)i; + ASSERT( finalIdx < ( 1ull << encodeShift ) ); + + outMapBuckets[dstIdx] = (origin << encodeShift) | finalIdx; + } + + auto& bitWriter = _bucketWriter; + uint64* bitCounts = totalBitCounts; + + if( self->IsControlThread() ) + { + self->LockThreads(); + + // Convert counts to bit sizes + for( uint32 i = 0; i < numBuckets; i++ ) + bitCounts[i] = (uint64)totalCounts[i] * bitSize; + + byte* writeBuffer = GetWriteBuffer( bucket ); + + // Wait for the buffer to be available first + if( bucket > 1 ) + _writeFence->Wait( bucket - 2, *_writeWaitTime ); + + bitWriter.BeginWriteBuckets( bitCounts, writeBuffer ); + + self->ReleaseThreads(); + } + else + self->WaitForRelease(); + + + // Bit-compress/pack each bucket entries (except the overflow bucket) + uint64 bitsWritten = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + if( counts[i] < 1 ) + { + self->SyncThreads(); + continue; + } + + const uint64 writeOffset = pfxSum[i]; + const uint64 bitOffset = writeOffset * bitSize - bitsWritten; + bitsWritten += bitCounts[i]; + + ASSERT( bitOffset + counts[i] * bitSize <= bitCounts[i] ); + + BitWriter writer = bitWriter.GetWriter( i, bitOffset ); + + const uint64* mapToWrite = outMapBuckets + writeOffset; + const uint64* mapToWriteEnd = mapToWrite + counts[i]; + + // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields + const uint64* mapToWriteEndPass1 = mapToWrite + std::min( counts[i], 2u ); + ASSERT( counts[i] > 2 ); + + while( mapToWrite < mapToWriteEndPass1 ) + writer.Write( *mapToWrite++, bitSize ); + + self->SyncThreads(); + + while( mapToWrite < mapToWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } + + // Write the overflow bucket and then write to disk + self->SyncThreads(); + if( self->IsControlThread() ) + { + const uint32 overflowBucket = _numBuckets; + const uint64 overflowCount = totalCounts[overflowBucket]; + + if( overflowCount ) + { + const uint64 writeOffset = pfxSum[overflowBucket]; + ASSERT( writeOffset * bitSize - bitsWritten == 0 ); + + BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); + + const uint64* mapToWrite = outMapBuckets + writeOffset; + const uint64* mapWriteEnd = mapToWrite + overflowCount; + while( mapToWrite < mapWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } + + bitWriter.Submit(); + _ioQueue->SignalFence( *_writeFence, bucket ); + _ioQueue->CommitCommands(); + } + }); + + for( int32 b = 0; b <= (int32)_numBuckets; b++ ) + outMapBucketCounts[b] += totalCounts[b]; + } + + //----------------------------------------------------------- + // template + // void WriteJob( Job* self, const uint32 bucket, const uint64 tableOffset. + // const Span indices, + // Span mapOut, + // uint64 outMapBucketCounts[_numBuckets+ExtraBucket], + // uint32 totalCounts [_numBuckets+ExtraBucket], + // uint64 totalBitCounts [_numBuckets+ExtraBucket] ) + // { + // const uint32 bucketBits = BucketBits; + // const uint32 bucketShift = _k - bucketBits; + // const uint32 bitSize = EntryBitSize; + // const uint32 encodeShift = AddressBitSize; + // const uint32 numBuckets = _numBuckets + ExtraBucket; + + // uint32 counts[numBuckets] = { 0 }; + // uint32 pfxSum[numBuckets]; + + // // Count buckets + // for( size_t i = 0; i < indices.Length(); i++ ) + // { + // const TMapIn b = indices[i] >> bucketShift; ASSERT( b < numBuckets ); + // counts[b]++; + // } + + // self->CalculatePrefixSum( numBuckets, counts, pfxSum, totalCounts ); + + // // Convert entries from source index to reverse map + // for( size_t i = 0; i < indices.Length(); i++ ) + // { + // const uint64 origin = indices[i]; ASSERT( origin < 0x100000000 + (1ull<<_k) / _numBuckets ); + // const uint64 b = origin >> bucketShift; ASSERT( b < numBuckets ); + // const uint32 dstIdx = --pfxSum[b]; ASSERT( (int64)dstIdx < entryCount ); + + // const uint64 finalIdx = tableOffset + (uint64)i; + // ASSERT( finalIdx < ( 1ull << encodeShift ) ); + + // mapOut[dstIdx] = (origin << encodeShift) | finalIdx; + // } + + // // Write + // auto& bitWriter = _bucketWriter; + // uint64* bitCounts = totalBitCounts; + + // if( self->BeginLockBlock() ) + // { + // // Convert counts to bit sizes + // for( uint32 i = 0; i < numBuckets; i++ ) + // bitCounts[i] = (uint64)totalCounts[i] * bitSize; + + // byte* writeBuffer = GetWriteBuffer( bucket ); + + // // Wait for the buffer to be available first + // if( bucket > 1 ) + // _writeFence->Wait( bucket - 2, *_writeWaitTime ); + + // bitWriter.BeginWriteBuckets( bitCounts, writeBuffer ); + // } + // self->EndLockBlock(); + + + // // Bit-compress/pack each bucket entries (except the overflow bucket) + // uint64 bitsWritten = 0; + + // for( uint32 i = 0; i < _numBuckets; i++ ) + // { + // if( counts[i] < 1 ) + // { + // self->SyncThreads(); + // continue; + // } + + // const uint64 writeOffset = pfxSum[i]; + // const uint64 bitOffset = writeOffset * bitSize - bitsWritten; + // bitsWritten += bitCounts[i]; + + // ASSERT( bitOffset + counts[i] * bitSize <= bitCounts[i] ); + + // BitWriter writer = bitWriter.GetWriter( i, bitOffset ); + + // const uint64* mapToWrite = outMapBuckets + writeOffset; + // const uint64* mapToWriteEnd = mapToWrite + counts[i]; + + // // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields + // const uint64* mapToWriteEndPass1 = mapToWrite + std::min( counts[i], 2u ); + // ASSERT( counts[i] > 2 ); + + // while( mapToWrite < mapToWriteEndPass1 ) + // writer.Write( *mapToWrite++, bitSize ); + + // self->SyncThreads(); + + // while( mapToWrite < mapToWriteEnd ) + // writer.Write( *mapToWrite++, bitSize ); + // } + + // // Write the overflow bucket and then write to disk + // if( self->BeginLockBlock() ) + // { + // if constexpr( _overflow ) + // { + // const uint32 overflowBucket = _numBuckets; + // const uint64 overflowCount = totalCounts[overflowBucket]; + + // if( overflowCount ) + // { + // const uint64 writeOffset = pfxSum[overflowBucket]; + // ASSERT( writeOffset * bitSize - bitsWritten == 0 ); + + // BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); + + // const uint64* mapToWrite = outMapBuckets + writeOffset; + // const uint64* mapWriteEnd = mapToWrite + overflowCount; + // while( mapToWrite < mapWriteEnd ) + // writer.Write( *mapToWrite++, bitSize ); + // } + // } + + // bitWriter.Submit(); + // _ioQueue->SignalFence( *_writeFence, bucket ); + // _ioQueue->CommitCommands(); + // } + // self->EndLockBlock(); + // } + + //----------------------------------------------------------- + void SubmitFinalBits() + { + _bucketWriter.SubmitLeftOvers(); + _ioQueue->SignalFence( *_writeFence, _numBuckets ); + _ioQueue->CommitCommands(); + } + +private: + //----------------------------------------------------------- + inline void AllocateWriteBuffers( const uint64 maxEntries, IAllocator& allocator, const size_t blockSize ) + { + const size_t writeBufferSize = RoundUpToNextBoundary( CDiv( maxEntries * EntryBitSize, 8 ), (int)blockSize ); + + _writebuffers[0] = allocator.AllocT( writeBufferSize, blockSize ); + _writebuffers[1] = allocator.AllocT( writeBufferSize, blockSize ); + } + + //----------------------------------------------------------- + inline byte* AllocBucketWriterBuffer( IAllocator& allocator, const size_t blockSize ) + { + return (byte*)allocator.CAlloc( _numBuckets+ExtraBucket, blockSize, blockSize ); + } + + //----------------------------------------------------------- + inline byte* GetWriteBuffer( const uint32 bucket ) + { + return _writebuffers[bucket & 1]; + } + +private: + DiskBufferQueue* _ioQueue = nullptr; + BitBucketWriter<_numBuckets+1> _bucketWriter; + byte* _writebuffers[2] = { nullptr }; + Fence* _writeFence = nullptr; + Duration* _writeWaitTime = nullptr; +}; + diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 059558e4..6840335a 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -32,6 +32,13 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) _ioQueue.InitFileSet( FileId::T5, "t5", 1, tmp1Options, nullptr ); _ioQueue.InitFileSet( FileId::T6, "t6", 1, tmp1Options, nullptr ); _ioQueue.InitFileSet( FileId::T7, "t7", 1, tmp1Options, nullptr ); + + _ioQueue.InitFileSet( FileId::MAP2, "map2", numBuckets, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::MAP3, "map3", numBuckets, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::MAP4, "map4", numBuckets, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::MAP5, "map5", numBuckets, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::MAP6, "map6", numBuckets, tmp1Options, nullptr ); + _ioQueue.InitFileSet( FileId::MAP7, "map7", numBuckets, tmp1Options, nullptr ); } // Temp2 diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 4fe491b3..ac267c54 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -3,6 +3,7 @@ #include "plotdisk/DiskPlotConfig.h" #include "plotdisk/DiskBufferQueue.h" #include "plotdisk/BitBucketWriter.h" +#include "plotdisk/MapWriter.h" #include "util/StackAllocator.h" #include "FpMatchBounded.inl" #include "b3/blake3.h" @@ -146,9 +147,19 @@ public: byte* pairBlocks = (byte*)allocator.CAlloc( 1, t1BlockSize, t1BlockSize ); if( !dryRun ) + { _pairBitWriter = BitBucketWriter<1>( _ioQueue, FileId::T1 + (FileId)rTable, pairBlocks ); + + // _mapWriter = MapWriter<_numBuckets, false>( _ioQueue, FileId::MAP2 + (FileId)(rTable-1), allocator, + // entriesPerBucket, t1BlockSize, _mapWriteFence, _tableIOWait ); + } + else + { + // _mapWriter = MapWriter<_numBuckets, false>( entriesPerBucket, allocator, t1BlockSize ); + } // _pairsL = allocator.CAllocSpan( entriesPerBucket ); // _pairsR = allocator.CAllocSpan( entriesPerBucket ); + } // Generate fx for a whole table @@ -189,6 +200,9 @@ public: _meta [i] = _metaBuffers [bufIdx].As(); } } + + // Set some initial fence status + _mapWriteFence.Signal( 0 ); // Run mmulti-threaded Job::Run( *_context.threadPool, threadCount, [=]( Job* self ) { @@ -227,6 +241,28 @@ private: Span sortKey = _sortKey.SliceSize( entryCount ); SortY( self, entryCount, yInput.Ptr(), _yTmp.As().Ptr(), sortKey.Ptr(), _metaTmp[0].As().Ptr() ); + + /// + /// Write reverse map, given the previous table's y origin indices + /// + if constexpr ( rTable > TableId::Table2 ) + { + WaitForFence( self, _indexReadFence, bucket ); + + Span indices = _metaTmp[0].As(); + + SortOnYKey( self, sortKey, _index[bucket], indices ); + WriteMap( self, indices, _map.SliceSize( entryCount ), (uint32)_tableEntryCount ); + } + else + { + // #TOOD Write T1 x + } + + + /// + /// Match + /// Span matches = Match( self, bucket, yInput ); // Count the total match count @@ -259,14 +295,6 @@ private: WritePairs( self, bucket, totalMatches, matches, matchOffset ); - // Generate and write map - if constexpr ( rTable > TableId::Table2 ) - { - WaitForFence( self, _indexReadFence, bucket ); - // Span indexInput = _index [bucket]; -// WriteMap( self, indexInput, sortKey ); // Write reverse map, given the previous table's y origin indices - } - // Sort meta on Y Span metaTmp = _meta[bucket].SliceSize( yInput.Length() ); Span metaIn = _metaTmp[0].As().SliceSize( yInput.Length() ); @@ -409,9 +437,57 @@ private: } //----------------------------------------------------------- - void WriteMap( Job* self, const Span indexInput, const Span sortKey ) + void WriteMap( Job* self, const Span bucketIndices, Span mapOut, const uint32 tableOffset ) { - + const uint32 bucketShift = _k - _bucketBits; + const uint32 bitSize = _k + bucketShift; + + uint32 counts [_numBuckets] = { 0 }; + uint32 pfxSum [_numBuckets]; + uint32 totalCounts[_numBuckets]; + + uint32 count, offset, _; + GetThreadOffsets( self, (uint32)bucketIndices.Length(), count, offset, _ ); + + auto indices = bucketIndices.Slice( offset, count ); + + // Count buckets + for( size_t i = 0; i < indices.Length(); i++ ) + { + const uint32 b = indices[i] >> bucketShift; ASSERT( b < _numBuckets ); + counts[b]++; + } + + self->CalculatePrefixSum( _numBuckets, counts, pfxSum, totalCounts ); + + // Wait for write fence + if( self->BeginLockBlock() ) + _mapWriteFence.Wait(); + self->EndLockBlock(); + + // Distribute as 64-bit entries + const uint64 outOffset = tableOffset + offset; + + for( size_t i = 0; i < indices.Length(); i++ ) + { + const uint64 origin = indices[i]; + const uint32 b = origin >> bucketShift; ASSERT( b < _numBuckets ); + + const uint32 dstIdx = --pfxSum[b]; + + mapOut[dstIdx] = (origin << _k) | (outOffset + i); // (origin, dst index) + } + + // Write map to disk + if( self->BeginLockBlock() ) + { + memcpy( _mapCounts, totalCounts , sizeof( totalCounts ) ); + + _ioQueue.WriteBucketElementsT( FileId::MAP2 + (FileId)rTable-1, mapOut.Ptr(), _mapCounts ); + _ioQueue.SignalFence( _mapWriteFence ); + _ioQueue.CommitCommands(); + } + self->EndLockBlock(); } //----------------------------------------------------------- @@ -782,6 +858,10 @@ private: // Matching FxMatcherBounded _matcher; + // Map + // MapWriter<_numBuckets, false> _mapWriter; + uint32 _mapCounts[_numBuckets]; + // Distributing to buckets Span _offsetsY; Span _offsetsMeta; @@ -807,3 +887,4 @@ public: Duration _matchTime = Duration::zero(); Duration _fxTime = Duration::zero(); }; + From aaab2148276d89e615dbfd25ceab3525ef6d9b72 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 26 May 2022 20:58:30 -0500 Subject: [PATCH 25/91] Fixed issue with incorrectly written indices --- src/plotdisk/DiskBufferQueue.cpp | 3 + src/plotdisk/DiskPlotter.cpp | 34 ++++----- src/plotdisk/DiskPlotter.h | 4 +- src/plotdisk/k32/DiskPlotBounded.cpp | 10 +-- src/plotdisk/k32/DiskPlotBounded.h | 2 +- src/plotdisk/k32/FxBounded.inl | 110 ++++++++++++++++++++++----- src/util/StackAllocator.h | 2 +- 7 files changed, 118 insertions(+), 47 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index b48fc843..7e33be0f 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -839,7 +839,10 @@ void DiskBufferQueue::CmdSeekBucket( const Command& cmd ) { int err = fileBuckets.files[i]->GetError(); Fatal( "[DiskBufferQueue] Failed to seek file %s.%u with error %d (0x%x)", fileBuckets.name, i, err, err ); + } + + // #TODO: Set the bucket number to 0 on origin == 0? } } diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 8ce43aec..9f1b1468 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -40,17 +40,6 @@ DiskPlotter::DiskPlotter( const Config& cfg ) FatalIf( _cx.tmp1BlockSize < 8 || _cx.tmp2BlockSize < 8,"File system block size is too small.." ); - const size_t heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize ); - ASSERT( heapSize ); - - _cfg = cfg; - _cx.cfg = &_cfg; - _cx.tmpPath = cfg.tmpPath; - _cx.tmpPath2 = cfg.tmpPath2; - _cx.numBuckets = cfg.numBuckets; - _cx.heapSize = heapSize; - _cx.cacheSize = cfg.cacheSize; - const uint sysLogicalCoreCount = SysHost::GetLogicalCPUCount(); const auto* numa = SysHost::GetNUMAInfo(); @@ -62,6 +51,17 @@ DiskPlotter::DiskPlotter( const Config& cfg ) _cx.p2ThreadCount = cfg.p2ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.p2ThreadCount, sysLogicalCoreCount ); _cx.p3ThreadCount = cfg.p3ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.p3ThreadCount, sysLogicalCoreCount ); + const size_t heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize, _cx.fpThreadCount ); + ASSERT( heapSize ); + + _cfg = cfg; + _cx.cfg = &_cfg; + _cx.tmpPath = cfg.tmpPath; + _cx.tmpPath2 = cfg.tmpPath2; + _cx.numBuckets = cfg.numBuckets; + _cx.heapSize = heapSize; + _cx.cacheSize = cfg.cacheSize; + Log::Line( "[Bladebit Disk Plotter]" ); Log::Line( " Heap size : %.2lf GiB ( %.2lf MiB )", (double)_cx.heapSize BtoGB, (double)_cx.heapSize BtoMB ); Log::Line( " Cache size : %.2lf GiB ( %.2lf MiB )", (double)_cx.cacheSize BtoGB, (double)_cx.cacheSize BtoMB ); @@ -300,10 +300,10 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) if( cfg.tmpPath ) { cfg.tmpPath2 = cfg.tmpPath2 ? cfg.tmpPath2 : cfg.tmpPath; - heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, cfg.tmpPath2, cfg.tmpPath ); + heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, cfg.tmpPath2, cfg.tmpPath, BB_DP_MAX_JOBS ); } else - heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, 1, 1 ); + heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, 1, 1, BB_DP_MAX_JOBS ); Log::Line( "Buckets: %u | Heap Sizes: %.2lf GiB", cfg.numBuckets, (double)heapSize BtoGB ); exit( 0 ); @@ -449,21 +449,21 @@ bool DiskPlotter::GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPa } //----------------------------------------------------------- -size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2 ) +size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2, const uint32 threadCount ) { size_t blockSizes[2] = { 0 }; if( !GetTmpPathsBlockSizes( tmpPath1, tmpPath2, blockSizes[0], blockSizes[1] ) ) return 0; - return GetRequiredSizeForBuckets( bounded, numBuckets, blockSizes[0], blockSizes[1] ); + return GetRequiredSizeForBuckets( bounded, numBuckets, blockSizes[0], blockSizes[1], threadCount ); } //----------------------------------------------------------- -size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize ) +size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize, const uint32 threadCount ) { if( bounded ) - return K32BoundedPhase1::GetRequiredSize( numBuckets, pairsBlockSize, fxBlockSize ); + return K32BoundedPhase1::GetRequiredSize( numBuckets, pairsBlockSize, fxBlockSize, threadCount ); switch( numBuckets ) { diff --git a/src/plotdisk/DiskPlotter.h b/src/plotdisk/DiskPlotter.h index 34c005e3..b2ecae14 100644 --- a/src/plotdisk/DiskPlotter.h +++ b/src/plotdisk/DiskPlotter.h @@ -24,8 +24,8 @@ class DiskPlotter void Plot( const PlotRequest& req ); static bool GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPath2, size_t& tmpPath1Size, size_t& tmpPath2Size ); - static size_t GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2 ); - static size_t GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize ); + static size_t GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const char* tmpPath1, const char* tmpPath2, const uint32 threadCount ); + static size_t GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize, const uint32 threadCount ); static void ParseCommandLine( CliParser& cli, Config& cfg ); diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 6840335a..0de9dfe0 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -65,14 +65,14 @@ K32BoundedPhase1::~K32BoundedPhase1() {} //----------------------------------------------------------- -size_t K32BoundedPhase1::GetRequiredSize( const uint32 numBuckets, const size_t t1BlockSize, const size_t t2BlockSize ) +size_t K32BoundedPhase1::GetRequiredSize( const uint32 numBuckets, const size_t t1BlockSize, const size_t t2BlockSize, const uint32 threadCount ) { switch( numBuckets ) { - case 64 : return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); - case 128: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); - case 256: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); - case 512: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); + case 64 : return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize, threadCount ); + case 128: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize, threadCount ); + case 256: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize, threadCount ); + case 512: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize, threadCount ); default: break; } diff --git a/src/plotdisk/k32/DiskPlotBounded.h b/src/plotdisk/k32/DiskPlotBounded.h index e804c8cf..9316a3f1 100644 --- a/src/plotdisk/k32/DiskPlotBounded.h +++ b/src/plotdisk/k32/DiskPlotBounded.h @@ -10,7 +10,7 @@ class K32BoundedPhase1 void Run(); - static size_t GetRequiredSize( const uint32 numBuckets, const size_t t1BlockSize, const size_t t2BlockSize ); + static size_t GetRequiredSize( const uint32 numBuckets, const size_t t1BlockSize, const size_t t2BlockSize, const uint32 threadCount ); private: diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index ac267c54..19c78062 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -8,6 +8,10 @@ #include "FpMatchBounded.inl" #include "b3/blake3.h" +#if _DEBUG + #include "algorithm/RadixSort.h" +#endif + typedef uint32 K32Meta1; typedef uint64 K32Meta2; struct K32Meta3 { uint32 m0, m1, m2; }; @@ -72,21 +76,21 @@ public: } //----------------------------------------------------------- - static size_t GetRequiredHeapSize( const size_t t1BlockSize, const size_t t2BlockSize ) + static size_t GetRequiredHeapSize( const size_t t1BlockSize, const size_t t2BlockSize, const uint32 threadCount ) { DiskPlotContext cx = {}; - DiskPlotFxBounded instance( cx ); + DiskPlotFxBounded instance( cx ); DummyAllocator allocator; - instance.AllocateBuffers( allocator, t1BlockSize, t2BlockSize, true ); + instance.AllocateBuffers( allocator, t1BlockSize, t2BlockSize, threadCount, true ); const size_t requiredSize = allocator.Size(); return requiredSize; } //----------------------------------------------------------- - void AllocateBuffers( IAllocator& allocator, const size_t t1BlockSize, const size_t t2BlockSize, const bool dryRun ) + void AllocateBuffers( IAllocator& allocator, const size_t t1BlockSize, const size_t t2BlockSize, const uint32 threadCount, const bool dryRun ) { const uint64 kEntryCount = 1ull << _k; const uint64 entriesPerBucket = (uint64)( kEntryCount / _numBuckets * BB_DP_XTRA_ENTRIES_PER_BUCKET ); @@ -110,8 +114,6 @@ public: _sortKey = allocator.CAllocSpan ( entriesPerBucket ); _pairBuffer = allocator.CAllocSpan ( entriesPerBucket ); - const uint32 threadCount = _context.fpThreadCount; - _sliceCountY[0] = allocator.CAllocSpan( _numBuckets ); _sliceCountY[1] = allocator.CAllocSpan( _numBuckets ); _sliceCountMeta[0] = allocator.CAllocSpan( _numBuckets ); @@ -128,11 +130,15 @@ public: { Span offsetsY = allocator.CAllocSpan( _numBuckets ); Span offsetsMeta = allocator.CAllocSpan( _numBuckets ); - offsetsY .ZeroOutElements(); - offsetsMeta.ZeroOutElements(); - _offsetsY [i] = offsetsY .Ptr(); - _offsetsMeta[i] = offsetsMeta.Ptr(); + if( !dryRun ) + { + offsetsY .ZeroOutElements(); + offsetsMeta.ZeroOutElements(); + + _offsetsY [i] = offsetsY .Ptr(); + _offsetsMeta[i] = offsetsMeta.Ptr(); + } } // Write buffers @@ -177,7 +183,7 @@ public: // Allocate buffers StackAllocator allocator( _context.heapBuffer, _context.heapSize ); - AllocateBuffers( allocator, _context.tmp1BlockSize, _context.tmp2BlockSize, false ); + AllocateBuffers( allocator, _context.tmp1BlockSize, _context.tmp2BlockSize, _context.fpThreadCount, false ); // Init buffers const uint32 threadCount = _context.fpThreadCount; @@ -219,6 +225,10 @@ public: // Ensure all I/O has completed _fxWriteFence.Wait( _numBuckets, _tableIOWait ); _context.fencePool->RestoreAllFences(); + + #if _DEBUG + ValidateIndices(); + #endif } private: @@ -232,6 +242,8 @@ private: for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { + // if( bucket == 63 && self->JobId() == 0 ) BBDebugBreak(); + ReadNextBucket( self, bucket + 1 ); // Read next bucket in background WaitForFence( self, _yReadFence, bucket ); @@ -248,11 +260,12 @@ private: if constexpr ( rTable > TableId::Table2 ) { WaitForFence( self, _indexReadFence, bucket ); + ASSERT( _index[bucket].Length() == entryCount ); - Span indices = _metaTmp[0].As(); + Span indices = _metaTmp[0].As().SliceSize( entryCount ); SortOnYKey( self, sortKey, _index[bucket], indices ); - WriteMap( self, indices, _map.SliceSize( entryCount ), (uint32)_tableEntryCount ); + WriteMap( self, indices, _map.SliceSize( entryCount ), _mapOffset ); } else { @@ -317,11 +330,14 @@ private: if( self->IsControlThread() ) _fxTime += TimerEndTicks( timer ); - WriteEntries( self, bucket, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); + WriteEntries( self, bucket, (uint32)_tableEntryCount + matchOffset, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); } if( self->IsControlThread() ) + { _tableEntryCount += totalMatches; + _mapOffset += entryCount; + } } } @@ -439,8 +455,7 @@ private: //----------------------------------------------------------- void WriteMap( Job* self, const Span bucketIndices, Span mapOut, const uint32 tableOffset ) { - const uint32 bucketShift = _k - _bucketBits; - const uint32 bitSize = _k + bucketShift; + const uint32 bucketShift = _k - _bucketBits; uint32 counts [_numBuckets] = { 0 }; uint32 pfxSum [_numBuckets]; @@ -549,6 +564,7 @@ private: //----------------------------------------------------------- void WriteEntries( Job* self, const uint32 bucket, + const uint32 idxOffset, const Span yIn, const Span metaIn, Span yOut, @@ -589,9 +605,6 @@ private: self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaAlignedsliceCount.Ptr(), _offsetsMeta[id], metaAlignedsliceCount.Ptr() ); // Distribute to buckets - int64 offset, _; - GetThreadOffsets( self, (int64)yIn.Length(), _, offset, _ ); - for( int64 i = 0; i < entryCount; i++ ) { const uint64 y = yIn[i]; @@ -600,7 +613,7 @@ private: const uint32 metaDst = --pfxSumMeta[yBucket]; yOut [yDst] = (uint32)(y & yMask); - idxOut [yDst] = (uint32)(offset + i); + idxOut [yDst] = idxOffset + (uint32)i; ASSERT( (uint64)idxOffset + (uint64)i < (1ull << _k) ); metaOut[metaDst] = metaIn[i]; } @@ -816,12 +829,67 @@ private: self->EndLockBlock(); } +private: + // DEBUG + #if _DEBUG + //----------------------------------------------------------- + void ValidateIndices() + { + Log::Line( "[DEBUG: Validating table %u indices]", rTable+1 ); + + // Load indices + const uint64 entryCount = _context.entryCounts[(int)rTable]; + + const FileId fileId = _idxId[1]; + _ioQueue.SeekBucket( fileId, 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); + + Span indices = bbcvirtallocboundednuma_span( entryCount ); + Span tmpIndices = bbcvirtallocboundednuma_span( entryCount ); + + { + Log::Line( " Loading indices" ); + Fence fence; + Span writer = indices; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + Span reader = tmpIndices; + + _ioQueue.ReadBucketElementsT( fileId, reader ); + _ioQueue.SignalFence( fence ); + _ioQueue.CommitCommands(); + fence.Wait(); + + reader.CopyTo( writer ); + writer = writer.Slice( reader.Length() ); + } + } + + // Now sort our entries + Log::Line( " Sorting indices" ); + RadixSort256::Sort( *_context.threadPool, indices.Ptr(), tmpIndices.Ptr(), indices.Length() ); + + // Now validate them + Log::Line( " Validating indices" ); + for( size_t i = 0; i < indices.Length(); i++ ) + { + ASSERT( indices[i] == i ); + } + + Log::Line( " Indices are valid" ); + bbvirtfreebounded( indices.Ptr() ); + bbvirtfreebounded( tmpIndices.Ptr() ); + } + #endif + private: DiskPlotContext& _context; DiskBufferQueue& _ioQueue; uint32 _entriesPerBucket = 0; - std::atomic _tableEntryCount = 0; + std::atomic _mapOffset = 0; // For writing maps + std::atomic _tableEntryCount = 0; // For writing indices // I/O FileId _yId [2]; diff --git a/src/util/StackAllocator.h b/src/util/StackAllocator.h index 00a6b8ca..649e0e1a 100644 --- a/src/util/StackAllocator.h +++ b/src/util/StackAllocator.h @@ -78,7 +78,7 @@ class StackAllocator : public IAllocator ASSERT( size > 0 ); ASSERT( _size < _capacity ); - // ASSERT( _capacity - paddedSize >= size ); + ASSERT( paddedSize <= _capacity ); FatalIf( !(_capacity - paddedSize >= size), "Allocation buffer overrun." ); void* ptr = reinterpret_cast( _buffer + paddedSize ); From 00faee51a05c95114524b68d25095ab622d52b22 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 27 May 2022 04:25:50 -0500 Subject: [PATCH 26/91] Validating y values as we're getting some empty values read on table 4 --- src/plotdisk/DiskPlotConfig.h | 2 +- src/plotdisk/DiskPlotDebug.h | 11 ++- src/plotdisk/k32/DiskPlotBounded.cpp | 15 +++- src/plotdisk/k32/FpMatchBounded.inl | 4 +- src/plotdisk/k32/FxBounded.inl | 130 +++++++++++++++++++++++---- 5 files changed, 139 insertions(+), 23 deletions(-) diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index e5eadd66..9039d571 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -57,7 +57,7 @@ // #define BB_DP_DBG_SKIP_TO_C_TABLES 1 // #define BB_DP_P1_SKIP_TO_TABLE 1 -// #define BB_DP_P1_START_TABLE TableId::Table7 +// #define BB_DP_P1_START_TABLE TableId::Table4 // Tmp file deletion (useful to keep around when developing) #if _DEBUG diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 07596edd..d12ef3d1 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -43,7 +43,10 @@ namespace Debug void LoadRefLPIndexTable( const TableId table, uint32*& buffer, uint64& outEntryCount ); template - void ValidatePairs( DiskPlotContext& context, const TableId table ); + void ValidatePairs( DiskPlotContext& context, const TableId table ); + + template + void ValidateK32Pairs( DiskPlotContext& context, const TableId table ); } template @@ -436,3 +439,9 @@ inline void Debug::ValidatePairs( DiskPlotContext& context, const TableId table bbvirtfree( tmpPairs ); } +//----------------------------------------------------------- +template +void Debug::ValidateK32Pairs( DiskPlotContext& context, const TableId table ) +{ + +} \ No newline at end of file diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 0de9dfe0..14ed29f3 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -102,9 +102,20 @@ void K32BoundedPhase1::Run() template void K32BoundedPhase1::RunWithBuckets() { - RunF1<_numBuckets>(); + TableId startTable = TableId::Table2; - for( TableId table = TableId::Table2; table <= TableId::Table7; table++ ) + #if defined( _DEBUG ) && defined( BB_DP_P1_SKIP_TO_TABLE ) + { + _context.entryCounts[0] = 1ull << 32; + ASSERT( BB_DP_P1_START_TABLE > TableId::Table2 ); + startTable = BB_DP_P1_START_TABLE; + } + #else + RunF1<_numBuckets>(); + #endif + + + for( TableId table = startTable; table <= TableId::Table7; table++ ) { switch( table ) { diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 3173a8ce..0ca40ca2 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -57,10 +57,10 @@ private: const uint32* entries = start + offset; // Find base start position - uint64 curGroup = *entries / kBC; + uint64 curGroup = (yMask | (uint64)*entries) / kBC; while( entries > start ) { - if( entries[-1] / kBC != curGroup ) + if( ( yMask | entries[-1] ) / kBC != curGroup ) break; --entries; } diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 19c78062..8c856f31 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -12,6 +12,17 @@ #include "algorithm/RadixSort.h" #endif +#define _VALIDATE_Y 1 +#if _VALIDATE_Y + uint32 _refBucketCounts[BB_DP_MAX_BUCKET_COUNT]; + Span _yRef; + Span _yRefWriter; + + template + void DbgValidateY( const TableId table, DiskPlotContext& context ); +#endif + + typedef uint32 K32Meta1; typedef uint64 K32Meta2; struct K32Meta3 { uint32 m0, m1, m2; }; @@ -146,14 +157,15 @@ public: _indexWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _metaWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _map = allocator.CAllocSpan( entriesPerBucket ); const size_t pairsWriteSize = CDiv( entriesPerBucket * _pairBitSize, 8 ); + _mapWriteBuffer = allocator.CAllocSpan ( entriesPerBucket, t1BlockSize ); _pairsWriteBuffer = allocator.AllocT( pairsWriteSize, t1BlockSize ); byte* pairBlocks = (byte*)allocator.CAlloc( 1, t1BlockSize, t1BlockSize ); if( !dryRun ) { + ASSERT( (uintptr_t)_mapWriteBuffer.Ptr() / t1BlockSize * t1BlockSize == (uintptr_t)_mapWriteBuffer.Ptr() ); _pairBitWriter = BitBucketWriter<1>( _ioQueue, FileId::T1 + (FileId)rTable, pairBlocks ); // _mapWriter = MapWriter<_numBuckets, false>( _ioQueue, FileId::MAP2 + (FileId)(rTable-1), allocator, @@ -209,7 +221,7 @@ public: // Set some initial fence status _mapWriteFence.Signal( 0 ); - + // Run mmulti-threaded Job::Run( *_context.threadPool, threadCount, [=]( Job* self ) { RunMT( self ); @@ -227,7 +239,10 @@ public: _context.fencePool->RestoreAllFences(); #if _DEBUG - ValidateIndices(); + // ValidateIndices(); + #endif + #if _VALIDATE_Y + DbgValidateY(); #endif } @@ -265,7 +280,7 @@ private: Span indices = _metaTmp[0].As().SliceSize( entryCount ); SortOnYKey( self, sortKey, _index[bucket], indices ); - WriteMap( self, indices, _map.SliceSize( entryCount ), _mapOffset ); + WriteMap( self, indices, _mapWriteBuffer, _mapOffset ); } else { @@ -330,6 +345,20 @@ private: if( self->IsControlThread() ) _fxTime += TimerEndTicks( timer ); + #if _VALIDATE_Y + if( self->IsControlThread() ) + { + if( _yRef.Ptr() == nullptr ) + { + _yRef = Span( bbcvirtallocboundednuma( 1ull << 32 ), 1ull << 32 ); + _yRefWriter = _yRef; + } + + _yTmp.SliceSize( totalMatches ).CopyTo( _yRefWriter ); + _yRefWriter = _yRefWriter.Slice( totalMatches ); + } + #endif + WriteEntries( self, bucket, (uint32)_tableEntryCount + matchOffset, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); } @@ -430,6 +459,9 @@ private: //----------------------------------------------------------- Span Match( Job* self, const uint32 bucket, Span yEntries ) { + if( rTable == TableId::Table4 && bucket == 3 && self->JobId() == 0 ) + BBDebugBreak(); + const uint32 id = self->JobId(); const uint32 threadCount = self->JobCount(); @@ -456,10 +488,11 @@ private: void WriteMap( Job* self, const Span bucketIndices, Span mapOut, const uint32 tableOffset ) { const uint32 bucketShift = _k - _bucketBits; + const uint32 blockSize = (uint32)_ioQueue.BlockSize( FileId::MAP2 ); - uint32 counts [_numBuckets] = { 0 }; - uint32 pfxSum [_numBuckets]; - uint32 totalCounts[_numBuckets]; + uint32 counts [_numBuckets] = { 0 }; + uint32 pfxSum [_numBuckets]; + uint32 offsets[_numBuckets]; uint32 count, offset, _; GetThreadOffsets( self, (uint32)bucketIndices.Length(), count, offset, _ ); @@ -473,7 +506,21 @@ private: counts[b]++; } - self->CalculatePrefixSum( _numBuckets, counts, pfxSum, totalCounts ); + uint32* pSliceCounts = nullptr; + uint32* pAlignedCounts = nullptr; + uint32* pOffsets = offsets; + + if( self->IsControlThread() ) + { + pSliceCounts = _mapSliceCounts; + pAlignedCounts = _mapAlignedCounts; + pOffsets = _mapOffsets; + } + else + memcpy( offsets, _mapOffsets, sizeof( offsets ) ); + + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, pSliceCounts, pOffsets, pAlignedCounts ); + // self->CalculatePrefixSum( _numBuckets, counts, pfxSum, totalCounts ); // Wait for write fence if( self->BeginLockBlock() ) @@ -488,7 +535,7 @@ private: const uint64 origin = indices[i]; const uint32 b = origin >> bucketShift; ASSERT( b < _numBuckets ); - const uint32 dstIdx = --pfxSum[b]; + const uint32 dstIdx = --pfxSum[b]; ASSERT( dstIdx < mapOut.Length() ); mapOut[dstIdx] = (origin << _k) | (outOffset + i); // (origin, dst index) } @@ -496,9 +543,7 @@ private: // Write map to disk if( self->BeginLockBlock() ) { - memcpy( _mapCounts, totalCounts , sizeof( totalCounts ) ); - - _ioQueue.WriteBucketElementsT( FileId::MAP2 + (FileId)rTable-1, mapOut.Ptr(), _mapCounts ); + _ioQueue.WriteBucketElementsT( FileId::MAP2 + (FileId)rTable-2, mapOut.Ptr(), _mapAlignedCounts, _mapSliceCounts ); _ioQueue.SignalFence( _mapWriteFence ); _ioQueue.CommitCommands(); } @@ -506,7 +551,8 @@ private: } //----------------------------------------------------------- - void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, const Span matches, const uint64 dstOffset ) + void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, + const Span matches, const uint64 dstOffset ) { ASSERT( dstOffset + matches.length <= totalMatchCount ); @@ -530,7 +576,7 @@ private: PackPairs( self, matches.Slice( 0, 2 ), writer ); self->SyncThreads(); PackPairs( self, matches.Slice( 2 ), writer ); - + // Write to disk if( self->BeginLockBlock() ) { @@ -602,7 +648,7 @@ private: counts[yIn[i] >> bucketShift]++; self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, ySliceCounts.Ptr(), _offsetsY[id], yAlignedSliceCount.Ptr() ); - self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaAlignedsliceCount.Ptr(), _offsetsMeta[id], metaAlignedsliceCount.Ptr() ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaSliceCounts.Ptr(), _offsetsMeta[id], metaAlignedsliceCount.Ptr() ); // Distribute to buckets for( int64 i = 0; i < entryCount; i++ ) @@ -911,7 +957,7 @@ private: Span _yWriteBuffer; Span _indexWriteBuffer; Span _metaWriteBuffer; - Span _map; + Span _mapWriteBuffer; byte* _pairsWriteBuffer; // Working buffers @@ -928,7 +974,9 @@ private: // Map // MapWriter<_numBuckets, false> _mapWriter; - uint32 _mapCounts[_numBuckets]; + uint32 _mapSliceCounts [_numBuckets]; + uint32 _mapAlignedCounts[_numBuckets]; + uint32 _mapOffsets [_numBuckets] = {}; // Distributing to buckets Span _offsetsY; @@ -956,3 +1004,51 @@ public: Duration _fxTime = Duration::zero(); }; + + +#if _VALIDATE_Y + +//----------------------------------------------------------- +template +void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context ) +{ + // + DiskBufferQueue& ioQueue = *context.ioQueue; + Fence fence; + + const Span yRef = _yRef.SliceSize( _context.entryCounts[(int)table] ); + Span yTmp = bbcvirtallocboundednuma_span( yRef.Length() ); + + // Sort ref + { + RadixSort256::Sort( *context.threadPool, yRef.Ptr(), yTmp.Ptr(), yRef.Length() ); + } + + // Read + { + Span reader = yTmp.As(); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + Span bucketReader = reader; + ioQueue.ReadBucketElementsT( fileId, bucketReader ); + ioQueue.SignalFence( fence ); + fence.Wait(); + + reader = reader.Slice( bucketReader.Length() ); + } + + } + + // Validate + { + const uint64 yMask = 1ull << 32; + } + + bbvirtfreebounded( yTmp.Ptr() ); + // Reset the writer + _yRefWriter = _yRef; +} + +#endif + From 9f9f4c03df5fdf224967dfdd345dfc0cbb75da72 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 28 May 2022 01:26:42 -0500 Subject: [PATCH 27/91] Fix issue with non-validating y. Missing seek to origin --- TODO.md | 9 ++- src/plotdisk/k32/FxBounded.inl | 125 +++++++++++++++++++++------------ 2 files changed, 85 insertions(+), 49 deletions(-) diff --git a/TODO.md b/TODO.md index 441ce161..6c40593a 100644 --- a/TODO.md +++ b/TODO.md @@ -7,9 +7,12 @@ - [] Fix crash on P1 T4 w/ RAID, which actually seems to be w/ big block sizes. (I believe this is due to not rounding up some buffers to block sizes. There's anote about this in fp code.) - [x] Add no-direct-io flag for both tmp dirs - [x] Add no-direct-io flag for final plot -- [] Add synchronos tmp IO (good with cache) - [] Perhaps add a different queue for t2 if it's a different physical disk -- [] Add method to reduce cache requirements to 96G instead of 192G -- [] Add non-overflowing version +- [-] Add k32 bounded/non-overflowing version +- [] Add synchronos tmp IO (good with cache) +- [x] Add interleaved-only writing method for bigger write chunks/more sequential I/O. + - [] Integrate this into other phases +- [x] Add method to reduce cache requirements to 96G instead of 192G + - [] Integrate cache reduction into the plotting process - [] Bring in avx256 linepoint conversion (already implemented in an old BB branch) - [] Allow sub temp directories or plot-speific file temp file names (allows for concurrent plotting). diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 8c856f31..922b61db 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -10,16 +10,16 @@ #if _DEBUG #include "algorithm/RadixSort.h" -#endif -#define _VALIDATE_Y 1 -#if _VALIDATE_Y - uint32 _refBucketCounts[BB_DP_MAX_BUCKET_COUNT]; - Span _yRef; - Span _yRefWriter; - - template - void DbgValidateY( const TableId table, DiskPlotContext& context ); + // #define _VALIDATE_Y 1 + #if _VALIDATE_Y + uint32 _refBucketCounts[BB_DP_MAX_BUCKET_COUNT]; + Span _yRef; + Span _yRefWriter; + + template + void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context ); + #endif #endif @@ -186,11 +186,16 @@ public: { // Prepare input files _ioQueue.SeekBucket( _yId[0], 0, SeekOrigin::Begin ); + _ioQueue.SeekBucket( _yId[1], 0, SeekOrigin::Begin ); if constexpr( rTable > TableId::Table2 ) + { _ioQueue.SeekBucket( _idxId[0], 0, SeekOrigin::Begin ); + _ioQueue.SeekBucket( _idxId[1], 0, SeekOrigin::Begin ); + } _ioQueue.SeekBucket( _metaId[0], 0, SeekOrigin::Begin ); + _ioQueue.SeekBucket( _metaId[1], 0, SeekOrigin::Begin ); _ioQueue.CommitCommands(); // Allocate buffers @@ -242,7 +247,7 @@ public: // ValidateIndices(); #endif #if _VALIDATE_Y - DbgValidateY(); + DbgValidateY<_numBuckets>( rTable, _yId[1], _context ); #endif } @@ -459,9 +464,6 @@ private: //----------------------------------------------------------- Span Match( Job* self, const uint32 bucket, Span yEntries ) { - if( rTable == TableId::Table4 && bucket == 3 && self->JobId() == 0 ) - BBDebugBreak(); - const uint32 id = self->JobId(); const uint32 threadCount = self->JobCount(); @@ -644,6 +646,7 @@ private: Span yAlignedSliceCount = _alignedSliceCountY[sliceIdx]; Span metaAlignedsliceCount = _alignedsliceCountMeta[sliceIdx]; + // Count for( int64 i = 0; i < entryCount; i++ ) counts[yIn[i] >> bucketShift]++; @@ -974,17 +977,17 @@ private: // Map // MapWriter<_numBuckets, false> _mapWriter; - uint32 _mapSliceCounts [_numBuckets]; - uint32 _mapAlignedCounts[_numBuckets]; - uint32 _mapOffsets [_numBuckets] = {}; + uint32 _mapSliceCounts [_numBuckets]; + uint32 _mapAlignedCounts[_numBuckets]; + uint32 _mapOffsets [_numBuckets] = {}; // Distributing to buckets - Span _offsetsY; - Span _offsetsMeta; - Span _sliceCountY [2]; - Span _sliceCountMeta[2]; - Span _alignedSliceCountY [2]; - Span _alignedsliceCountMeta[2]; + Span _offsetsY; + Span _offsetsMeta; + Span _sliceCountY [2]; + Span _sliceCountMeta[2]; + Span _alignedSliceCountY [2]; + Span _alignedsliceCountMeta[2]; // I/O Synchronization fences Fence& _yReadFence; @@ -1012,41 +1015,71 @@ public: template void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context ) { - // - DiskBufferQueue& ioQueue = *context.ioQueue; - Fence fence; + if( table > TableId::Table2 ) + { + Log::Line( "[Validating table y %u]", table+1 ); - const Span yRef = _yRef.SliceSize( _context.entryCounts[(int)table] ); - Span yTmp = bbcvirtallocboundednuma_span( yRef.Length() ); + DiskBufferQueue& ioQueue = *context.ioQueue; + Fence fence; - // Sort ref - { - RadixSort256::Sort( *context.threadPool, yRef.Ptr(), yTmp.Ptr(), yRef.Length() ); - } + ioQueue.SeekBucket( fileId, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); - // Read - { - Span reader = yTmp.As(); + Span yRef = _yRef.SliceSize( context.entryCounts[(int)table] ); + Span yTmp = bbcvirtallocboundednuma_span( yRef.Length() ); - for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + // Sort ref + { + Log::Line( " Sorting ref" ); + RadixSort256::Sort( *context.threadPool, yRef.Ptr(), yTmp.Ptr(), yRef.Length() ); + } + + // Read { - Span bucketReader = reader; - ioQueue.ReadBucketElementsT( fileId, bucketReader ); - ioQueue.SignalFence( fence ); - fence.Wait(); + Span reader = yTmp.SliceSize( yRef.Length() / 2 ); + Span tmp = yTmp.Slice( yRef.Length() / 2 ); - reader = reader.Slice( bucketReader.Length() ); + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + Log::Line( " Validating %u", bucket ); + + Span bucketReader = reader.As(); + + ioQueue.ReadBucketElementsT( fileId, bucketReader ); + ioQueue.SignalFence( fence ); + ioQueue.CommitCommands(); + fence.Wait(); + + // Sort + RadixSort256::Sort( *context.threadPool, bucketReader.Ptr(), tmp.As().Ptr(), bucketReader.Length() ); + + // Expand + const uint64 yMask = ((uint64)bucket) << 32; + Span yValues = tmp; + + for( uint32 i = 0; i < bucketReader.Length(); i++ ) + yValues[i] = yMask | (uint64)bucketReader[i]; + + // Validate + for( uint32 i = 0; i < bucketReader.Length(); i++ ) + { + const uint64 r = yRef [i]; + const uint64 y = yValues[i]; + + ASSERT( y == r ); + } + + yRef = yRef.Slice( bucketReader.Length() ); + } } - } + // Cleanup + bbvirtfreebounded( yTmp.Ptr() ); - // Validate - { - const uint64 yMask = 1ull << 32; + ioQueue.SeekBucket( fileId, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); } - bbvirtfreebounded( yTmp.Ptr() ); - // Reset the writer _yRefWriter = _yRef; } From 582afba84d6a13916605c6320cc121ab8550f8ee Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 6 Jun 2022 17:03:05 -0500 Subject: [PATCH 28/91] Reverting metadata 3 to be power-of-two sized. This is required for the way we currently pad our aligned-writes. --- src/plotdisk/k32/FxBounded.inl | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 922b61db..c2c83309 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -25,7 +25,8 @@ typedef uint32 K32Meta1; typedef uint64 K32Meta2; -struct K32Meta3 { uint32 m0, m1, m2; }; +// struct K32Meta3 { uint32 m0, m1, m2; }; +struct K32Meta3 { uint32 m0, m1; }; struct K32Meta4 { uint64 m0, m1; }; struct K32NoMeta {}; @@ -781,10 +782,14 @@ private: } else if constexpr( MetaInMulti == 3 ) { - const uint64 l0 = (uint64)metaIn[left ].m0 | ( (uint64)metaIn[left ].m1 << 32 ); - const uint64 l1 = metaIn[left ].m2; - const uint64 r0 = (uint64)metaIn[right].m0 | ( (uint64)metaIn[right].m1 << 32 ); - const uint64 r1 = metaIn[right].m2; + // const uint64 l0 = (uint64)metaIn[left ].m0 | ( (uint64)metaIn[left ].m1 << 32 ); + // const uint64 l1 = metaIn[left ].m2; + // const uint64 r0 = (uint64)metaIn[right].m0 | ( (uint64)metaIn[right].m1 << 32 ); + // const uint64 r1 = metaIn[right].m2; + const uint64 l0 = metaIn[left ].m0; + const uint64 l1 = metaIn[left ].m1 & 0xFFFFFFFF; + const uint64 r0 = metaIn[right].m0; + const uint64 r1 = metaIn[right].m1 & 0xFFFFFFFF; input[0] = Swap64( y << 26 | l0 >> 38 ); input[1] = Swap64( l0 << 26 | l1 >> 6 ); @@ -828,10 +833,13 @@ private: const uint64 h1 = Swap64( output[1] ); const uint64 h2 = Swap64( output[2] ); - uint64 m0 = h0 << ySize | h1 >> 26; - mOut.m0 = (uint32)m0; - mOut.m0 = (uint32)(m0 >> 32); - mOut.m2 = (uint32)( ((h1 << 6) & 0xFFFFFFC0) | h2 >> 58 ); + mOut.m0 = h0 << ySize | h1 >> 26; + mOut.m1 = ((h1 << 6) & 0xFFFFFFC0) | h2 >> 58; + + // uint64 m0 = h0 << ySize | h1 >> 26; + // mOut.m0 = (uint32)m0; + // mOut.m0 = (uint32)(m0 >> 32); + // mOut.m2 = (uint32)( ((h1 << 6) & 0xFFFFFFC0) | h2 >> 58 ); } else if constexpr ( MetaOutMulti == 4 && MetaInMulti != 2 ) // In = 2 is calculated above with L + R { From 036d667877ae01cb0dff11598774cea97b8d52f4 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 7 Jun 2022 03:56:19 -0500 Subject: [PATCH 29/91] Working on validaton code for P1 --- src/plotdisk/BlockWriter.h | 2 +- src/plotdisk/k32/FxBounded.inl | 255 ++++++++++++++++++++++++++++----- src/util/Span.h | 4 +- 3 files changed, 220 insertions(+), 41 deletions(-) diff --git a/src/plotdisk/BlockWriter.h b/src/plotdisk/BlockWriter.h index 0769ffc9..c73a7c13 100644 --- a/src/plotdisk/BlockWriter.h +++ b/src/plotdisk/BlockWriter.h @@ -19,7 +19,7 @@ class BlockWriter const size_t allocSize = blockSize + RoundUpToNextBoundaryT( elementCount * sizeof( T ), blockSize ); // Sanity check, should never happen as block sizes are power of 2 and - // we don't expect to use this with non Po2 elements. + // we don't expect to use this with non Pow2 elements. FatalIf( blockSize / sizeof( T ) * sizeof( T ) != blockSize, "Unexpected block size." ); _buffers[0] = allocator.AllocT( allocSize, blockSize ); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index c2c83309..95fe7fec 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -4,6 +4,7 @@ #include "plotdisk/DiskBufferQueue.h" #include "plotdisk/BitBucketWriter.h" #include "plotdisk/MapWriter.h" +#include "plotdisk/BlockWriter.h" #include "util/StackAllocator.h" #include "FpMatchBounded.inl" #include "b3/blake3.h" @@ -20,6 +21,90 @@ template void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context ); #endif + + + #define DBG_VALIDATE_TABLES 1 + + #if DBG_VALIDATE_TABLES + struct DebugPlot + { + using Job = AnonPrefixSumJob; + + Span x; + Span y; + Span f7; + Span backPointers[7] = {}; + uint64 _writeOffset[7] = {}; + uint32 _pairOffset [7] = {}; + + inline void AllocTable( const TableId table ) + { + const uint64 maxEntries = 1ull << 32; + if( table == TableId::Table2 ) + { + x = Span( bbcvirtallocboundednuma( maxEntries ), maxEntries ); + y = Span( bbcvirtallocboundednuma( maxEntries ), maxEntries ); + } + else if( table == TableId::Table7 ) + f7 = Span( bbcvirtallocboundednuma( maxEntries ), maxEntries ); + + backPointers[(int)table] = Span( bbcvirtallocboundednuma( maxEntries ), maxEntries ); + } + + inline void WriteYX( const uint64 bucket, const Span ys, const Span xs ) + { + ASSERT( ys.Length() == xs.Length() ); + + xs.CopyTo( x.Slice( _writeOffset[0] ) ); + + const uint64 yMask = bucket << 32; + auto yDst = y.Slice( _writeOffset[0] ); + for( uint32 i = 0; i < ys.Length(); i++ ) + yDst[i] = yMask | y[i]; + + _writeOffset[0] += xs.Length(); + } + + inline void WriteF7( const Span f7s ) + { + f7s.CopyTo( f7.Slice( _writeOffset[6] ) ); + } + + inline void WritePairs( Job* self, const TableId table, const uint32 threadOffset, const Span pairs, const uint32 lBucketLength, const uint32 totalPairsLength ) + { + const uint32 writeOffset = _writeOffset[(int)table] + threadOffset; + Span dst = backPointers[(int)table].Slice( writeOffset ); + + const uint32 offset = _pairOffset[(int)table]; + pairs.CopyTo( dst ); + + for( uint64 i = 0; i < pairs.Length(); i++ ) + { + dst[i].left += offset; + dst[i].right += offset; + } + + if( self->BeginLockBlock() ) + { + _writeOffset[(int)table] += totalPairsLength; + _pairOffset [(int)table] += lBucketLength; + } + self->EndLockBlock(); + } + + inline void FinishTable( const TableId table ) + { + const uint64 tableLength = _writeOffset[(int)table]; + backPointers[(int)table] = backPointers[(int)table].SliceSize( tableLength ); + + if( table == TableId::Table7 ) + f7 = f7.SliceSize( tableLength ); + } + }; + + static DebugPlot _dbgPlot; + void DbgValidatePlot( const DebugPlot& dbgPlot ); + #endif #endif @@ -50,17 +135,15 @@ class DiskPlotFxBounded using TMetaIn = typename K32MetaType::In; using TMetaOut = typename K32MetaType::Out; using Job = AnonPrefixSumJob; + static constexpr uint32 _k = 32; static constexpr uint64 _maxTableEntries = (1ull << _k) - 1; static constexpr uint32 _bucketBits = bblog2( _numBuckets ); - static constexpr uint32 _pairsMaxDelta = 512; static constexpr uint32 _pairsRightBits = bblog2( _pairsMaxDelta ); static constexpr uint32 _pairBitSize = _k - _bucketBits + _pairsRightBits; - public: - //----------------------------------------------------------- DiskPlotFxBounded( DiskPlotContext& context ) : _context ( context ) @@ -121,8 +204,8 @@ public: // Work buffers _yTmp = allocator.CAllocSpan ( entriesPerBucket, t2BlockSize ); - _metaTmp[0] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _metaTmp[1] = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _metaTmp[0] = allocator.CAllocSpan( entriesPerBucket, t1BlockSize ); // Align this to T1 as we use it to write x to disk. + _metaTmp[1] = allocator.CAllocSpan( entriesPerBucket, t1BlockSize ); _sortKey = allocator.CAllocSpan ( entriesPerBucket ); _pairBuffer = allocator.CAllocSpan ( entriesPerBucket ); @@ -160,22 +243,32 @@ public: const size_t pairsWriteSize = CDiv( entriesPerBucket * _pairBitSize, 8 ); - _mapWriteBuffer = allocator.CAllocSpan ( entriesPerBucket, t1BlockSize ); _pairsWriteBuffer = allocator.AllocT( pairsWriteSize, t1BlockSize ); byte* pairBlocks = (byte*)allocator.CAlloc( 1, t1BlockSize, t1BlockSize ); - + if( !dryRun ) - { - ASSERT( (uintptr_t)_mapWriteBuffer.Ptr() / t1BlockSize * t1BlockSize == (uintptr_t)_mapWriteBuffer.Ptr() ); _pairBitWriter = BitBucketWriter<1>( _ioQueue, FileId::T1 + (FileId)rTable, pairBlocks ); - - // _mapWriter = MapWriter<_numBuckets, false>( _ioQueue, FileId::MAP2 + (FileId)(rTable-1), allocator, - // entriesPerBucket, t1BlockSize, _mapWriteFence, _tableIOWait ); + + if constexpr ( rTable == TableId::Table2 ) + { + _xWriter = BlockWriter( allocator, FileId::T1, _mapWriteFence, t1BlockSize, entriesPerBucket ); } else { - // _mapWriter = MapWriter<_numBuckets, false>( entriesPerBucket, allocator, t1BlockSize ); + _mapWriteBuffer = allocator.CAllocSpan ( entriesPerBucket, t1BlockSize ); + ASSERT( (uintptr_t)_mapWriteBuffer.Ptr() / t1BlockSize * t1BlockSize == (uintptr_t)_mapWriteBuffer.Ptr() ); + + // if( !dryRun ) + // { + // // _mapWriter = MapWriter<_numBuckets, false>( _ioQueue, FileId::MAP2 + (FileId)(rTable-1), allocator, + // // entriesPerBucket, t1BlockSize, _mapWriteFence, _tableIOWait ); + // } + // else + // { + // // _mapWriter = MapWriter<_numBuckets, false>( entriesPerBucket, allocator, t1BlockSize ); + // } } + // _pairsL = allocator.CAllocSpan( entriesPerBucket ); // _pairsR = allocator.CAllocSpan( entriesPerBucket ); @@ -185,6 +278,10 @@ public: //----------------------------------------------------------- void Run() { + #if DBG_VALIDATE_TABLES + _dbgPlot.AllocTable( rTable ); + #endif + // Prepare input files _ioQueue.SeekBucket( _yId[0], 0, SeekOrigin::Begin ); _ioQueue.SeekBucket( _yId[1], 0, SeekOrigin::Begin ); @@ -244,6 +341,10 @@ public: _fxWriteFence.Wait( _numBuckets, _tableIOWait ); _context.fencePool->RestoreAllFences(); + #if DBG_VALIDATE_TABLES + _dbgPlot.FinishTable( rTable ); + #endif + #if _DEBUG // ValidateIndices(); #endif @@ -272,7 +373,7 @@ private: const uint32 entryCount = yInput.Length(); Span sortKey = _sortKey.SliceSize( entryCount ); - SortY( self, entryCount, yInput.Ptr(), _yTmp.As().Ptr(), sortKey.Ptr(), _metaTmp[0].As().Ptr() ); + SortY( self, entryCount, yInput.Ptr(), _yTmp.As().Ptr(), sortKey.Ptr(), _metaTmp[1].As().Ptr() ); /// @@ -283,15 +384,11 @@ private: WaitForFence( self, _indexReadFence, bucket ); ASSERT( _index[bucket].Length() == entryCount ); - Span indices = _metaTmp[0].As().SliceSize( entryCount ); + Span indices = _metaTmp[1].As().SliceSize( entryCount ); SortOnYKey( self, sortKey, _index[bucket], indices ); WriteMap( self, indices, _mapWriteBuffer, _mapOffset ); } - else - { - // #TOOD Write T1 x - } /// @@ -329,12 +426,40 @@ private: WritePairs( self, bucket, totalMatches, matches, matchOffset ); + #if DBG_VALIDATE_TABLES + _dbgPlot.WritePairs( self, rTable, matchOffset, matches, _mapOffset, totalMatches ); + #endif + // Sort meta on Y Span metaTmp = _meta[bucket].SliceSize( yInput.Length() ); - Span metaIn = _metaTmp[0].As().SliceSize( yInput.Length() ); + Span metaIn = _metaTmp[0].As().SliceSize( yInput.Length() ); // #NOTE: _metaTmp[0] is only used here, so we can use it for writing x values to disk + + if constexpr ( rTable == TableId::Table2 ) + { + // #TODO: Simplify this by not making use of the block writer's buffers? + if( self->BeginLockBlock() ) + metaIn = Span( _xWriter.GetNextBuffer( _tableIOWait ), entryCount ); + self->EndLockBlock(); + } WaitForFence( self, _metaReadFence, bucket ); SortOnYKey( self, sortKey, metaTmp, metaIn ); + + if constexpr ( rTable == TableId::Table2 ) + { + // Write x back to disk + if( self->BeginLockBlock() ) + { + #if DBG_VALIDATE_TABLES + _dbgPlot.WriteYX( bucket, yInput, metaIn ); + #endif + + _xWriter.SubmitBuffer( _ioQueue, entryCount ); + if( bucket == _numBuckets - 1 ) + _xWriter.SubmitFinalBlock( _ioQueue ); + } + self->EndLockBlock(); + } // Gen fx & write { @@ -365,7 +490,7 @@ private: } #endif - WriteEntries( self, bucket, (uint32)_tableEntryCount + matchOffset, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); + WriteEntries( self, bucket, (uint32)_tableEntryCount + matchOffset, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); } if( self->IsControlThread() ) @@ -469,7 +594,7 @@ private: const uint32 threadCount = self->JobCount(); // use metaTmp as a buffer for group boundaries - Span groupBuffer = _metaTmp[0].As(); + Span groupBuffer = _metaTmp[1].As(); const uint32 maxGroups = (uint32)( groupBuffer.Length() / threadCount ); Span groupIndices = groupBuffer.Slice( maxGroups * id, maxGroups ); @@ -955,30 +1080,31 @@ private: BitBucketWriter<1> _pairBitWriter; // Read buffers - Span _yBuffers [2]; - Span _indexBuffers[2]; - Span _metaBuffers [2]; + Span _yBuffers [2]; + Span _indexBuffers[2]; + Span _metaBuffers [2]; // Read views - Span _y [_numBuckets]; - Span _index[_numBuckets]; - Span _meta [_numBuckets]; + Span _y [_numBuckets]; + Span _index[_numBuckets]; + Span _meta [_numBuckets]; // Write buffers - Span _yWriteBuffer; - Span _indexWriteBuffer; - Span _metaWriteBuffer; - Span _mapWriteBuffer; - byte* _pairsWriteBuffer; + Span _yWriteBuffer; + Span _indexWriteBuffer; + Span _metaWriteBuffer; + Span _mapWriteBuffer; + byte* _pairsWriteBuffer; + BlockWriter _xWriter; // Used for Table2 (there's no map, but just x.) // Working buffers - Span _yTmp; - Span _sortKey; - Span _metaTmp[2]; - Span _pairBuffer; + Span _yTmp; + Span _sortKey; + Span _metaTmp[2]; + Span _pairBuffer; // Working views - Span _pairs[BB_DP_MAX_JOBS]; // Pairs buffer divided per thread + Span _pairs[BB_DP_MAX_JOBS]; // Pairs buffer divided per thread // Matching FxMatcherBounded _matcher; @@ -1005,6 +1131,9 @@ private: Fence& _pairWriteFence; Fence& _mapWriteFence; + #if DBG_VALIDATE_TABLES + uint64 _dbgPairOffset = 0; + #endif public: // Timings @@ -1013,6 +1142,9 @@ public: Duration _distributeTime = Duration::zero(); Duration _matchTime = Duration::zero(); Duration _fxTime = Duration::zero(); + +private: + }; @@ -1093,3 +1225,50 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co #endif +//----------------------------------------------------------- +template +void DbgValidatePairs( const TableId table, const uint32 bucket, + const Span pairs, const Span yIn, const Span metas, + const Span yOut ) +{ + for( size_t i = 0; i < pairs.Length(); i++ ) + { + // const Pair pair = pairs[i]; + // const uint64 y = ys [pair.left]; + // const TMeta metaL = metas[pair.left]; + // const TMeta metaR = metas[pair.right]; + + + + // + // ASSERT( ) + } +} + +#if DBG_VALIDATE_TABLES + +//----------------------------------------------------------- +template +inline void DbgValidatePlotTable( const Span pairs, const Span yIn, const Span< ) +{ + +} + +//----------------------------------------------------------- +inline void DbgValidatePlot( const DebugPlot& dbgPlot ) +{ + Span yIn; + Span yOut; + Span metaIn; + Span metaOut; + + DbgValidatePlotTable( dbgPlot ); + + for( TableId rTable = TableId::Table2; rTable <= TableId::Table7; rTable++ ) + { + + } +} + +#endif + diff --git a/src/util/Span.h b/src/util/Span.h index 4f36f89c..aa980d00 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -92,7 +92,7 @@ struct Span inline Span Slice( const int64 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } inline Span Slice( const int32 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } - inline void CopyTo( Span& other, const size_t size ) const + inline void CopyTo( Span other, const size_t size ) const { ASSERT( length >= size ); ASSERT( other.length >= size ); @@ -100,7 +100,7 @@ struct Span memcpy( other.values, values, size * sizeof( T ) ); } - inline void CopyTo( Span& other ) const + inline void CopyTo( Span other ) const { CopyTo( other, length ); } From 8b99f5a0c6451c722899a23b801872223d462df2 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 8 Jun 2022 01:07:54 -0500 Subject: [PATCH 30/91] Patching-in the compressing map writer for bounded plots. --- src/plotdisk/DiskPairReader.h | 219 ++++++++++++++++++++++++++ src/plotdisk/DiskPlotPhase3.cpp | 2 +- src/plotdisk/MapWriter.h | 263 ++++++++++++++++---------------- src/plotdisk/k32/FxBounded.inl | 217 ++++++++++++++++---------- src/plotting/PlotValidation.cpp | 5 + src/plotting/PlotValidation.h | 30 ++++ 6 files changed, 525 insertions(+), 211 deletions(-) create mode 100644 src/plotting/PlotValidation.cpp create mode 100644 src/plotting/PlotValidation.h diff --git a/src/plotdisk/DiskPairReader.h b/src/plotdisk/DiskPairReader.h index cc10d82f..4fdea33b 100644 --- a/src/plotdisk/DiskPairReader.h +++ b/src/plotdisk/DiskPairReader.h @@ -586,6 +586,225 @@ class SingleFileMapReader : public IP3LMapReader T _retainedEntries[_retainCount]; }; +// template +// class K32BoundedMapReader +// { +// //----------------------------------------------------------- +// K32BoundedMapReader() {} + +// //----------------------------------------------------------- +// K32BoundedMapReader( DiskPlotContext& context, const uint32 threadCount, const TableId table, const FileId fileId, +// IAllocator& allocator, +// const uint64* realBucketLengths = nullptr ) +// : _context ( &context ) +// , _table ( table ) +// , _fileId ( fileId ) +// , _threadCount( threadCount ) +// { +// const uint64 maxKEntries = ( 1ull << _k ); +// const uint64 maxBucketEntries = maxKEntries / _numBuckets; +// const size_t blockSize = context.ioQueue->BlockSize( fileId ); +// const size_t bufferSize = CDivT( (size_t)maxBucketEntries * _mapBits, blockSize * 8 ) * blockSize; + +// _loadBuffers[0] = allocator.Alloc( bufferSize, blockSize ); +// _loadBuffers[1] = allocator.Alloc( bufferSize, blockSize ); +// _loadBuffers[2] = allocator.Alloc( bufferSize, blockSize ); +// _loadBuffers[3] = allocator.Alloc( bufferSize, blockSize ); + +// _unpackdMaps[0] = allocator.CAlloc( maxBucketEntries ); +// _unpackdMaps[1] = allocator.CAlloc( maxBucketEntries ); + +// if( realBucketLengths ) +// memcpy( _bucketLengths, realBucketLengths, sizeof( _bucketLengths ) ); +// else +// { +// for( uint32 b = 0; b < _numBuckets-1; b++ ) +// _bucketLengths[b] = maxBucketEntries; + +// _bucketLengths[_numBuckets-1] = GetVirtualBucketLength( _numBuckets-1 ); +// _bucketLengths[_numBuckets] = GetVirtualBucketLength( _numBuckets ); +// } + +// ASSERT( _numBuckets == context.numBuckets ); +// } + +// //----------------------------------------------------------- +// void LoadNextEntries( const uint64 entryCount ) +// { +// if( _bucketsLoaded >= _numBuckets ) +// return; + +// DiskBufferQueue& ioQueue = *_context->ioQueue; + +// const size_t blockSize = ioQueue.BlockSize( _fileId ); +// const size_t blockSizeBits = blockSize * 8; + +// uint64 bucketLength = GetVirtualBucketLength( _bucketsLoaded ); +// ASSERT( bucketLength ); + +// // Need to load current bucket? +// if( _bucketEntryOffset == 0 ) +// { +// // Load length (actual bucket length) might be different than the virtual length +// const size_t loadSize = CDivT( (size_t)_bucketLengths[_bucketsLoaded] * _mapBits, blockSizeBits ) * blockSize; +// ioQueue.ReadFile( _fileId, _bucketsLoaded, GetBucketBuffer( _bucketsLoaded ), loadSize ); +// // _fence.Signal( _bucketsLoaded + 1 ); +// } + +// _bucketEntryOffset += entryCount; + +// // It is possible to cross 2 buckets, so we need to account for that. +// // But we ought never have to load more than 2 buckets on one go. +// while( _bucketEntryOffset > bucketLength ) +// { +// _bucketEntryOffset -= bucketLength; +// _bucketsLoaded++; +// ASSERT( _bucketsLoaded <= _numBuckets ); + +// // Upade bucket length and load the new bucket +// bucketLength = GetVirtualBucketLength( _bucketsLoaded ); +// ASSERT( bucketLength ); + +// const size_t loadSize = CDivT( (size_t)_bucketLengths[_bucketsLoaded] * _mapBits, blockSizeBits ) * blockSize; +// ioQueue.ReadFile( _fileId, _bucketsLoaded, GetBucketBuffer( _bucketsLoaded ), loadSize ); +// // _fence.Signal( _bucketsLoaded + 1 ); +// } +// } + +// //----------------------------------------------------------- +// void ReadEntries( const uint64 entryCount, TMap* outMap ) +// { +// ASSERT( _bucketsRead <= _numBuckets ); + +// // #TODO: Check here if we have to unpack a bucket and then check our own fence. +// AnonMTJob::Run( *_context->threadPool, _threadCount, [=]( AnonMTJob* self ) { + +// uint64 entriesToRead = entryCount; +// TMap* outWriter = outMap; +// uint64 readBucketOffset = _bucketReadOffset; +// uint32 bucketsRead = _bucketsRead; + +// while( entriesToRead ) +// { +// // Unpack the whole bucket into it's destination indices +// if( _bucketsUnpacked <= bucketsRead ) +// { +// #if _DEBUG +// const uint64 virtBucketLength = GetVirtualBucketLength( _bucketsUnpacked ); +// #endif + +// const uint64 bucketLength = _bucketLengths[_bucketsUnpacked]; + +// int64 count, offset, end; +// GetThreadOffsets( self, (int64)bucketLength, count, offset, end ); +// ASSERT( count > 0 ); + +// TMap* unpackedMap = _unpackdMaps[_bucketsUnpacked & 1]; +// BitReader reader( (uint64*)GetBucketBuffer( _bucketsUnpacked ), _mapBits * bucketLength, offset * _mapBits ); + +// const uint32 idxShift = _finalIdxBits; +// const uint64 finalIdxMask = ( 1ull << idxShift ) - 1; + +// for( int64 i = offset; i < end; i++ ) +// { +// const uint64 packedMap = reader.ReadBits64( (uint32)_mapBits ); +// const uint64 map = packedMap & finalIdxMask; +// const uint64 dstIdx = packedMap >> idxShift; + +// ASSERT( dstIdx < virtBucketLength ); +// unpackedMap[dstIdx] = (TMap)map; +// } + +// if( self->IsControlThread() ) +// { +// self->LockThreads(); +// _bucketsUnpacked++; +// self->ReleaseThreads(); +// } +// else +// self->WaitForRelease(); +// } + +// const uint64 bucketLength = GetVirtualBucketLength( bucketsRead ); +// const uint64 readCount = std::min( bucketLength - readBucketOffset, entriesToRead ); + +// const TMap* readMap = _unpackdMaps[bucketsRead & 1] + readBucketOffset; + +// // Simply copy the unpacked map to the destination buffer +// int64 count, offset, end; +// GetThreadOffsets( self, (int64)readCount, count, offset, end ); + +// if( count ) +// memcpy( outWriter + offset, readMap + offset, (size_t)count * sizeof( TMap ) ); + +// // Update read entries +// entriesToRead -= readCount; +// outWriter += readCount; + +// readBucketOffset += readCount; +// if( readBucketOffset == bucketLength ) +// { +// readBucketOffset = 0; +// bucketsRead++; +// } +// } + +// if( self->IsControlThread() ) +// { +// self->LockThreads(); +// _bucketReadOffset = readBucketOffset; +// _bucketsRead = bucketsRead; +// self->ReleaseThreads(); +// } +// else +// self->WaitForRelease(); +// }); +// } + +// //----------------------------------------------------------- +// inline uint64 GetVirtualBucketLength( const uint32 bucket ) +// { +// const uint64 maxKEntries = ( 1ull << _k ); +// const uint64 maxBucketEntries = maxKEntries / _numBuckets; + +// // All buckets before the last bucket (and before the overflow bucket) have the same entry count which is 2^k / numBuckets +// if( bucket < _numBuckets - 1 ) +// return maxBucketEntries; + +// const uint64 tableEntryCount = _context->entryCounts[(int)_table]; + +// // Last, non-overflow bucket? +// if( bucket == _numBuckets - 1 ) +// return tableEntryCount > maxKEntries ? +// maxBucketEntries : +// maxBucketEntries - ( maxKEntries - tableEntryCount ); + +// // Last bucket +// return tableEntryCount > maxKEntries ? tableEntryCount - maxKEntries : 0; +// } + +// private: +// //----------------------------------------------------------- +// inline void* GetBucketBuffer( const uint32 bucket ) +// { +// return _loadBuffers[bucket & 3]; +// } + +// private: +// DiskPlotContext* _context = nullptr; +// TableId _table = TableId::Table1; +// FileId _fileId = FileId::None; +// uint32 _threadCount = 0; +// uint32 _bucketsLoaded = 0; +// uint32 _bucketsRead = 0; +// uint32 _bucketsUnpacked = 0; +// uint64 _bucketEntryOffset = 0; +// uint64 _bucketReadOffset = 0; // Entries that have actually bean read/unpacked in a bucket + +// TMap* _unpackdMaps[2]; +// void* _loadBuffers[4]; // We do double-buffering, but since a single load may go across bucket boundaries, we need 4. +// uint64 _bucketLengths[_numBuckets+1]; // Real, non-virtual bucket lengths. This is only necessary for buckets that have been pruned (ex. in Phase 3) +// }; #pragma GCC diagnostic pop diff --git a/src/plotdisk/DiskPlotPhase3.cpp b/src/plotdisk/DiskPlotPhase3.cpp index 99e750f6..282949de 100644 --- a/src/plotdisk/DiskPlotPhase3.cpp +++ b/src/plotdisk/DiskPlotPhase3.cpp @@ -581,7 +581,7 @@ class P3StepTwo , _readFence ( readFence ) , _writeFence ( writeFence ) , _lpWriteFence( lpWriteFence ) - , _readId ( readId ) + , _readId ( readId ) , _writeId ( writeId ) { _readFence .Reset(); diff --git a/src/plotdisk/MapWriter.h b/src/plotdisk/MapWriter.h index 62cc1912..fb5402e9 100644 --- a/src/plotdisk/MapWriter.h +++ b/src/plotdisk/MapWriter.h @@ -12,7 +12,8 @@ class MapWriter static constexpr uint32 AddressBitSize = _k + ExtraBucket; static constexpr uint32 EntryBitSize = _k - BucketBits + AddressBitSize; // ( origin address | final address ) ( k-log2(buckets) | 32 ) - using Job = AnonPrefixSumJob; + using MapBitBucketWriter = BitBucketWriter<_numBuckets+ExtraBucket>; + using Job = AnonPrefixSumJob; public: @@ -188,129 +189,135 @@ class MapWriter } //----------------------------------------------------------- - // template - // void WriteJob( Job* self, const uint32 bucket, const uint64 tableOffset. - // const Span indices, - // Span mapOut, - // uint64 outMapBucketCounts[_numBuckets+ExtraBucket], - // uint32 totalCounts [_numBuckets+ExtraBucket], - // uint64 totalBitCounts [_numBuckets+ExtraBucket] ) - // { - // const uint32 bucketBits = BucketBits; - // const uint32 bucketShift = _k - bucketBits; - // const uint32 bitSize = EntryBitSize; - // const uint32 encodeShift = AddressBitSize; - // const uint32 numBuckets = _numBuckets + ExtraBucket; - - // uint32 counts[numBuckets] = { 0 }; - // uint32 pfxSum[numBuckets]; - - // // Count buckets - // for( size_t i = 0; i < indices.Length(); i++ ) - // { - // const TMapIn b = indices[i] >> bucketShift; ASSERT( b < numBuckets ); - // counts[b]++; - // } - - // self->CalculatePrefixSum( numBuckets, counts, pfxSum, totalCounts ); - - // // Convert entries from source index to reverse map - // for( size_t i = 0; i < indices.Length(); i++ ) - // { - // const uint64 origin = indices[i]; ASSERT( origin < 0x100000000 + (1ull<<_k) / _numBuckets ); - // const uint64 b = origin >> bucketShift; ASSERT( b < numBuckets ); - // const uint32 dstIdx = --pfxSum[b]; ASSERT( (int64)dstIdx < entryCount ); - - // const uint64 finalIdx = tableOffset + (uint64)i; - // ASSERT( finalIdx < ( 1ull << encodeShift ) ); - - // mapOut[dstIdx] = (origin << encodeShift) | finalIdx; - // } - - // // Write - // auto& bitWriter = _bucketWriter; - // uint64* bitCounts = totalBitCounts; - - // if( self->BeginLockBlock() ) - // { - // // Convert counts to bit sizes - // for( uint32 i = 0; i < numBuckets; i++ ) - // bitCounts[i] = (uint64)totalCounts[i] * bitSize; - - // byte* writeBuffer = GetWriteBuffer( bucket ); - - // // Wait for the buffer to be available first - // if( bucket > 1 ) - // _writeFence->Wait( bucket - 2, *_writeWaitTime ); - - // bitWriter.BeginWriteBuckets( bitCounts, writeBuffer ); - // } - // self->EndLockBlock(); - - - // // Bit-compress/pack each bucket entries (except the overflow bucket) - // uint64 bitsWritten = 0; - - // for( uint32 i = 0; i < _numBuckets; i++ ) - // { - // if( counts[i] < 1 ) - // { - // self->SyncThreads(); - // continue; - // } - - // const uint64 writeOffset = pfxSum[i]; - // const uint64 bitOffset = writeOffset * bitSize - bitsWritten; - // bitsWritten += bitCounts[i]; - - // ASSERT( bitOffset + counts[i] * bitSize <= bitCounts[i] ); - - // BitWriter writer = bitWriter.GetWriter( i, bitOffset ); - - // const uint64* mapToWrite = outMapBuckets + writeOffset; - // const uint64* mapToWriteEnd = mapToWrite + counts[i]; - - // // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields - // const uint64* mapToWriteEndPass1 = mapToWrite + std::min( counts[i], 2u ); - // ASSERT( counts[i] > 2 ); - - // while( mapToWrite < mapToWriteEndPass1 ) - // writer.Write( *mapToWrite++, bitSize ); - - // self->SyncThreads(); - - // while( mapToWrite < mapToWriteEnd ) - // writer.Write( *mapToWrite++, bitSize ); - // } - - // // Write the overflow bucket and then write to disk - // if( self->BeginLockBlock() ) - // { - // if constexpr( _overflow ) - // { - // const uint32 overflowBucket = _numBuckets; - // const uint64 overflowCount = totalCounts[overflowBucket]; - - // if( overflowCount ) - // { - // const uint64 writeOffset = pfxSum[overflowBucket]; - // ASSERT( writeOffset * bitSize - bitsWritten == 0 ); + template + void WriteJob( Job* self, const uint32 bucket, const uint64 tableOffset, + const Span indices, + Span mapOut, + uint64 outMapBucketCounts [_numBuckets+ExtraBucket], + uint32 totalCounts [_numBuckets+ExtraBucket], + uint64 sharedTotalBitCounts[_numBuckets+ExtraBucket] ) // Must be 1 instance shared across all jobs + { + const uint32 bucketBits = BucketBits; + const uint32 bucketShift = _k - bucketBits; + const uint32 bitSize = EntryBitSize; + const uint32 encodeShift = AddressBitSize; + const uint32 numBuckets = _numBuckets + ExtraBucket; + + uint32 counts[numBuckets] = { 0 }; + uint32 pfxSum[numBuckets]; + + uint32 count, offset, _; + GetThreadOffsets( self, (uint32)indices.Length(), count, offset, _ ); + + auto inIdx = indices.Slice( offset, count ); + + // Count buckets + for( size_t i = 0; i < inIdx.Length(); i++ ) + { + const TMapIn b = inIdx[i] >> bucketShift; ASSERT( b < numBuckets ); + counts[b]++; + } + + self->CalculatePrefixSum( numBuckets, counts, pfxSum, totalCounts ); + + // Convert entries from source index to reverse map + for( size_t i = 0; i < inIdx.Length(); i++ ) + { + const uint64 origin = inIdx[i]; ASSERT( origin < 0x100000000 + (1ull<<_k) / _numBuckets ); + const uint64 b = origin >> bucketShift; ASSERT( b < numBuckets ); + const uint32 dstIdx = --pfxSum[b]; ASSERT( dstIdx < indices.Length() ); + + const uint64 finalIdx = tableOffset + (uint64)i; + ASSERT( finalIdx < ( 1ull << encodeShift ) ); + + mapOut[dstIdx] = (origin << encodeShift) | finalIdx; + } + + // Write + auto& bitWriter = _bucketWriter; + uint64* bitCounts = sharedTotalBitCounts; + + if( self->BeginLockBlock() ) + { + // Convert counts to bit sizes + for( uint32 i = 0; i < numBuckets; i++ ) + bitCounts[i] = (uint64)totalCounts[i] * bitSize; + + byte* writeBuffer = GetWriteBuffer( bucket ); + + // Wait for the buffer to be available first + if( bucket > 1 ) + _writeFence->Wait( bucket - 2, *_writeWaitTime ); + + bitWriter.BeginWriteBuckets( bitCounts, writeBuffer ); + } + self->EndLockBlock(); + + + // Bit-compress/pack each bucket entries (except the overflow bucket) + uint64 bitsWritten = 0; + + for( uint32 i = 0; i < _numBuckets; i++ ) + { + if( counts[i] < 1 ) + { + self->SyncThreads(); + continue; + } + + const uint64 writeOffset = pfxSum[i]; + const uint64 bitOffset = writeOffset * bitSize - bitsWritten; + bitsWritten += bitCounts[i]; + + ASSERT( bitOffset + counts[i] * bitSize <= bitCounts[i] ); + + BitWriter writer = bitWriter.GetWriter( i, bitOffset ); + + const uint64* mapToWrite = mapOut.Ptr() + writeOffset; + const uint64* mapToWriteEnd = mapToWrite + counts[i]; + + // Compress a couple of entries first, so that we don't get any simultaneaous writes to the same fields + const uint64* mapToWriteEndPass1 = mapToWrite + std::min( counts[i], 2u ); + ASSERT( counts[i] > 2 ); + + while( mapToWrite < mapToWriteEndPass1 ) + writer.Write( *mapToWrite++, bitSize ); + + self->SyncThreads(); + + while( mapToWrite < mapToWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } + + // Write the overflow bucket and then write to disk + if( self->BeginLockBlock() ) + { + if constexpr( _overflow ) + { + Fatal( "Unimplemented" ); // #TODO: Fix compiler errors + const uint32 overflowBucket = _numBuckets; + const uint64 overflowCount = totalCounts[overflowBucket]; + + if( overflowCount ) + { + const uint64 writeOffset = pfxSum[overflowBucket]; + ASSERT( writeOffset * bitSize - bitsWritten == 0 ); - // BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); - - // const uint64* mapToWrite = outMapBuckets + writeOffset; - // const uint64* mapWriteEnd = mapToWrite + overflowCount; - // while( mapToWrite < mapWriteEnd ) - // writer.Write( *mapToWrite++, bitSize ); - // } - // } - - // bitWriter.Submit(); - // _ioQueue->SignalFence( *_writeFence, bucket ); - // _ioQueue->CommitCommands(); - // } - // self->EndLockBlock(); - // } + BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); + + const uint64* mapToWrite = mapOut.Ptr() + writeOffset; + const uint64* mapWriteEnd = mapToWrite + overflowCount; + while( mapToWrite < mapWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } + } + + bitWriter.Submit(); + _ioQueue->SignalFence( *_writeFence, bucket ); + _ioQueue->CommitCommands(); + } + self->EndLockBlock(); + } //----------------------------------------------------------- void SubmitFinalBits() @@ -343,10 +350,10 @@ class MapWriter } private: - DiskBufferQueue* _ioQueue = nullptr; - BitBucketWriter<_numBuckets+1> _bucketWriter; - byte* _writebuffers[2] = { nullptr }; - Fence* _writeFence = nullptr; - Duration* _writeWaitTime = nullptr; + DiskBufferQueue* _ioQueue = nullptr; + MapBitBucketWriter _bucketWriter; + byte* _writebuffers[2] = { nullptr }; + Fence* _writeFence = nullptr; + Duration* _writeWaitTime = nullptr; }; diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 95fe7fec..36fda3e2 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -11,6 +11,7 @@ #if _DEBUG #include "algorithm/RadixSort.h" + #include "plotting/PlotValidation.h" // #define _VALIDATE_Y 1 #if _VALIDATE_Y @@ -23,7 +24,7 @@ #endif - #define DBG_VALIDATE_TABLES 1 + // #define DBG_VALIDATE_TABLES 1 #if DBG_VALIDATE_TABLES struct DebugPlot @@ -258,20 +259,19 @@ public: _mapWriteBuffer = allocator.CAllocSpan ( entriesPerBucket, t1BlockSize ); ASSERT( (uintptr_t)_mapWriteBuffer.Ptr() / t1BlockSize * t1BlockSize == (uintptr_t)_mapWriteBuffer.Ptr() ); - // if( !dryRun ) - // { - // // _mapWriter = MapWriter<_numBuckets, false>( _ioQueue, FileId::MAP2 + (FileId)(rTable-1), allocator, - // // entriesPerBucket, t1BlockSize, _mapWriteFence, _tableIOWait ); - // } - // else - // { - // // _mapWriter = MapWriter<_numBuckets, false>( entriesPerBucket, allocator, t1BlockSize ); - // } + if( !dryRun ) + { + _mapWriter = MapWriter<_numBuckets, false>( _ioQueue, FileId::MAP2 + (FileId)(rTable-2), allocator, + entriesPerBucket, t1BlockSize, _mapWriteFence, _tableIOWait ); + } + else + { + _mapWriter = MapWriter<_numBuckets, false>( entriesPerBucket, allocator, t1BlockSize ); + } } // _pairsL = allocator.CAllocSpan( entriesPerBucket ); // _pairsR = allocator.CAllocSpan( entriesPerBucket ); - } // Generate fx for a whole table @@ -387,7 +387,7 @@ private: Span indices = _metaTmp[1].As().SliceSize( entryCount ); SortOnYKey( self, sortKey, _index[bucket], indices ); - WriteMap( self, indices, _mapWriteBuffer, _mapOffset ); + WriteMap( self, bucket, indices, _mapWriteBuffer, _mapOffset ); } @@ -613,69 +613,79 @@ private: } //----------------------------------------------------------- - void WriteMap( Job* self, const Span bucketIndices, Span mapOut, const uint32 tableOffset ) + void WriteMap( Job* self, const uint32 bucket, const Span bucketIndices, Span mapOut, const uint32 tableOffset ) { - const uint32 bucketShift = _k - _bucketBits; - const uint32 blockSize = (uint32)_ioQueue.BlockSize( FileId::MAP2 ); - - uint32 counts [_numBuckets] = { 0 }; - uint32 pfxSum [_numBuckets]; - uint32 offsets[_numBuckets]; - - uint32 count, offset, _; - GetThreadOffsets( self, (uint32)bucketIndices.Length(), count, offset, _ ); - - auto indices = bucketIndices.Slice( offset, count ); - - // Count buckets - for( size_t i = 0; i < indices.Length(); i++ ) - { - const uint32 b = indices[i] >> bucketShift; ASSERT( b < _numBuckets ); - counts[b]++; - } - - uint32* pSliceCounts = nullptr; - uint32* pAlignedCounts = nullptr; - uint32* pOffsets = offsets; - - if( self->IsControlThread() ) - { - pSliceCounts = _mapSliceCounts; - pAlignedCounts = _mapAlignedCounts; - pOffsets = _mapOffsets; - } - else - memcpy( offsets, _mapOffsets, sizeof( offsets ) ); - - self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, pSliceCounts, pOffsets, pAlignedCounts ); + uint64 outMapBucketCounts[_numBuckets]; // Pass actual bucket counts and implement them + uint32 totalCounts [_numBuckets]; + // uint64 totalBitCounts [_numBuckets]; + + _mapWriter.WriteJob( self, bucket, tableOffset, bucketIndices, mapOut, + outMapBucketCounts, totalCounts, _mapBitCounts ); + + /// + /// #TODO: Fix and re-enabled Un-compressed method?: + /// + // const uint32 bucketShift = _k - _bucketBits; + // const uint32 blockSize = (uint32)_ioQueue.BlockSize( FileId::MAP2 ); + + // uint32 counts [_numBuckets] = { 0 }; + // uint32 pfxSum [_numBuckets]; + // uint32 offsets[_numBuckets]; + + // uint32 count, offset, _; + // GetThreadOffsets( self, (uint32)bucketIndices.Length(), count, offset, _ ); + + // auto indices = bucketIndices.Slice( offset, count ); + + // // Count buckets + // for( size_t i = 0; i < indices.Length(); i++ ) + // { + // const uint32 b = indices[i] >> bucketShift; ASSERT( b < _numBuckets ); + // counts[b]++; + // } + + // uint32* pSliceCounts = nullptr; + // uint32* pAlignedCounts = nullptr; + // uint32* pOffsets = offsets; + + // if( self->IsControlThread() ) + // { + // pSliceCounts = _mapSliceCounts; + // pAlignedCounts = _mapAlignedCounts; + // pOffsets = _mapOffsets; + // } + // else + // memcpy( offsets, _mapOffsets, sizeof( offsets ) ); + + // // self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, pSliceCounts, pOffsets, pAlignedCounts ); // self->CalculatePrefixSum( _numBuckets, counts, pfxSum, totalCounts ); - // Wait for write fence - if( self->BeginLockBlock() ) - _mapWriteFence.Wait(); - self->EndLockBlock(); + // // Wait for write fence + // if( self->BeginLockBlock() ) + // _mapWriteFence.Wait(); + // self->EndLockBlock(); - // Distribute as 64-bit entries - const uint64 outOffset = tableOffset + offset; + // // Distribute as 64-bit entries + // const uint64 outOffset = tableOffset + offset; - for( size_t i = 0; i < indices.Length(); i++ ) - { - const uint64 origin = indices[i]; - const uint32 b = origin >> bucketShift; ASSERT( b < _numBuckets ); + // for( size_t i = 0; i < indices.Length(); i++ ) + // { + // const uint64 origin = indices[i]; + // const uint32 b = origin >> bucketShift; ASSERT( b < _numBuckets ); - const uint32 dstIdx = --pfxSum[b]; ASSERT( dstIdx < mapOut.Length() ); + // const uint32 dstIdx = --pfxSum[b]; ASSERT( dstIdx < mapOut.Length() ); - mapOut[dstIdx] = (origin << _k) | (outOffset + i); // (origin, dst index) - } + // mapOut[dstIdx] = (origin << _k) | (outOffset + i); // (origin, dst index) + // } - // Write map to disk - if( self->BeginLockBlock() ) - { - _ioQueue.WriteBucketElementsT( FileId::MAP2 + (FileId)rTable-2, mapOut.Ptr(), _mapAlignedCounts, _mapSliceCounts ); - _ioQueue.SignalFence( _mapWriteFence ); - _ioQueue.CommitCommands(); - } - self->EndLockBlock(); + // // Write map to disk + // if( self->BeginLockBlock() ) + // { + // _ioQueue.WriteBucketElementsT( FileId::MAP2 + (FileId)rTable-2, mapOut.Ptr(), _mapAlignedCounts, _mapSliceCounts ); + // _ioQueue.SignalFence( _mapWriteFence ); + // _ioQueue.CommitCommands(); + // } + // self->EndLockBlock(); } //----------------------------------------------------------- @@ -1110,10 +1120,11 @@ private: FxMatcherBounded _matcher; // Map - // MapWriter<_numBuckets, false> _mapWriter; - uint32 _mapSliceCounts [_numBuckets]; - uint32 _mapAlignedCounts[_numBuckets]; - uint32 _mapOffsets [_numBuckets] = {}; + MapWriter<_numBuckets, false> _mapWriter; + uint64 _mapBitCounts[_numBuckets]; // Used by the map writer. Single instace shared accross jobs + // uint32 _mapSliceCounts [_numBuckets]; + // uint32 _mapAlignedCounts[_numBuckets]; + // uint32 _mapOffsets [_numBuckets] = {}; // Distributing to buckets Span _offsetsY; @@ -1248,26 +1259,68 @@ void DbgValidatePairs( const TableId table, const uint32 bucket, #if DBG_VALIDATE_TABLES //----------------------------------------------------------- -template -inline void DbgValidatePlotTable( const Span pairs, const Span yIn, const Span< ) +template +inline void DbgValidatePlotTable( const Span pairs, const Span yIn ) { } //----------------------------------------------------------- -inline void DbgValidatePlot( const DebugPlot& dbgPlot ) +template +inline void DbgValidatePlotTable( const Span pairs, const Span yIn ) +{ + using TMetaIn = typename K32MetaType::In; + using TMetaOut = typename K32MetaType::Out; +} + +//----------------------------------------------------------- +inline void DbgValidatePlot( DiskPlotContext& context, const DebugPlot& dbgPlot ) { - Span yIn; - Span yOut; - Span metaIn; - Span metaOut; + // Span _f7s = dbgPlot.f7; - DbgValidatePlotTable( dbgPlot ); + // AnonMTJob::Run( *context.threadPool, [=]( AnonMTJob* self ){ + + // uint64 count, offset, end; + // GetThreadOffsets( self, (uint64)_f7s.Length(), count, offset, end ); + + // // Span f7s = _f7s.Slice( offset, count ); + + // uint64 fullProof[PROOF_X_COUNT]; + // Pair backPtrs [PROOF_X_COUNT/2]; + + // for( uint64 i = offset; i < end; i++ ) + // { + // const uint32 f7 = _f7s[i]; + + // // Pull full proof from back points + // uint32 ptrCount = 1; + // backPtrs[0] = ; + // for( TableId table = TableId::Table7; table > TableId::Table1; table-- ) + // { + // uint32 dst = 0; + // for( uint32 p = 0; p < ptrCount; p++ ) + // { + // dbgPlot.backPointers[6][p] + + // dst += 2; + // } + // ptrCount <<= 1; + // } + + // } + // }); + + // Span yIn; + // Span yOut; + // Span metaIn; + // Span metaOut; + + // DbgValidatePlotTable( dbgPlot ); - for( TableId rTable = TableId::Table2; rTable <= TableId::Table7; rTable++ ) - { + // for( TableId rTable = TableId::Table2; rTable <= TableId::Table7; rTable++ ) + // { - } + // } } #endif diff --git a/src/plotting/PlotValidation.cpp b/src/plotting/PlotValidation.cpp new file mode 100644 index 00000000..36d7eec5 --- /dev/null +++ b/src/plotting/PlotValidation.cpp @@ -0,0 +1,5 @@ +#include "PlotValidation.h" + +#include "pos/chacha8.h" +#include "b3/blake3.h" + diff --git a/src/plotting/PlotValidation.h b/src/plotting/PlotValidation.h new file mode 100644 index 00000000..992137fa --- /dev/null +++ b/src/plotting/PlotValidation.h @@ -0,0 +1,30 @@ +#pragma once +#include "util/BitView.h" +#include "ChiaConsts.h" +#include "plotting/PlotTools.h" + +#define PROOF_X_COUNT 64 +#define MAX_K_SIZE 48 +#define MAX_META_MULTIPLIER 4 +#define MAX_Y_BIT_SIZE ( MAX_K_SIZE + kExtraBits ) +#define MAX_META_BIT_SIZE ( MAX_K_SIZE * MAX_META_MULTIPLIER ) +#define MAX_FX_BIT_SIZE ( MAX_Y_BIT_SIZE + MAX_META_BIT_SIZE + MAX_META_BIT_SIZE ) + +typedef Bits YBits; +typedef Bits MetaBits; +typedef Bits FxBits; + + +class PlotValidation +{ + static bool ValidateFullProof( const uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 fullProofXs[PROOF_X_COUNT], uint64& outF7 ); + + static uint64 BytesToUInt64( const byte bytes[8] ); + static uint64 SliceUInt64FromBits( const byte* bytes, uint32 bitOffset, uint32 bitCount ); + + static bool FxMatch( uint64 yL, uint64 yR ); + + static void FxGen( const TableId table, const uint32 k, + const uint64 y, const MetaBits& metaL, const MetaBits& metaR, + uint64& outY, MetaBits& outMeta ); +}; \ No newline at end of file From 02657e963994195241fd86de1141cb1fbb4b2924 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 8 Jun 2022 03:57:50 -0500 Subject: [PATCH 31/91] Enabling cross-bucket matches again for testing missing entries. --- src/plotdisk/DiskBufferQueue.cpp | 1 - src/plotdisk/DiskPlotPhase2.cpp | 1 - src/plotdisk/FpGroupMatcher.h | 2 +- src/plotdisk/IOTransforms.h | 24 ----- src/plotdisk/k32/FpMatchBounded.inl | 122 +++++++++++++++++++++++--- src/plotdisk/k32/FxBounded.inl | 10 ++- src/plotdisk/transforms/FxTransform.h | 38 -------- 7 files changed, 121 insertions(+), 77 deletions(-) delete mode 100644 src/plotdisk/IOTransforms.h delete mode 100644 src/plotdisk/transforms/FxTransform.h diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 7e33be0f..f6fa70d3 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -2,7 +2,6 @@ #include "io/FileStream.h" #include "io/HybridStream.h" #include "plotdisk/DiskPlotConfig.h" -#include "plotdisk/IOTransforms.h" #include "jobs/IOJob.h" #include "util/Util.h" #include "util/Log.h" diff --git a/src/plotdisk/DiskPlotPhase2.cpp b/src/plotdisk/DiskPlotPhase2.cpp index 987fdcf6..2196dc52 100644 --- a/src/plotdisk/DiskPlotPhase2.cpp +++ b/src/plotdisk/DiskPlotPhase2.cpp @@ -1,7 +1,6 @@ #include "DiskPlotPhase2.h" #include "util/BitField.h" #include "algorithm/RadixSort.h" -#include "transforms/FxTransform.h" #include "plotdisk/DiskPlotInfo.h" #include "util/StackAllocator.h" #include "DiskPlotInfo.h" diff --git a/src/plotdisk/FpGroupMatcher.h b/src/plotdisk/FpGroupMatcher.h index 223a5c7a..6e51bb2d 100644 --- a/src/plotdisk/FpGroupMatcher.h +++ b/src/plotdisk/FpGroupMatcher.h @@ -20,7 +20,7 @@ struct FpCrossBucketInfo inline bool IsLastBucket() const { return bucket == maxBuckets-1; } inline bool IsFirstBucket() const { return bucket == 0; } - inline uint64 EntryCount() const { return (uint64)groupCount[0] + groupCount[1]; } + inline uint64 EntryCount() const { return (uint64)groupCount[0] + groupCount[1]; } }; struct FpGroupMatcher diff --git a/src/plotdisk/IOTransforms.h b/src/plotdisk/IOTransforms.h deleted file mode 100644 index 1c32b175..00000000 --- a/src/plotdisk/IOTransforms.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -class IIOTransform -{ -public: - struct TransformData - { - void* buffer; - uint32 numBuckets; - uint32* bucketSizes; - - // void* output; - // size_t inputSize; - // void* userData; - }; - -public: - inline virtual ~IIOTransform() {} - // virtual void ReadTransform( TransformData& data ) = 0; - // virtual void WriteTransform( TransformData& data ) = 0; - - inline virtual void Read( TransformData& data ) {} - inline virtual void Write( TransformData& data ) {} -}; diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 0ca40ca2..828e23d5 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -5,12 +5,36 @@ #include "util/StackAllocator.h" +struct K32BoundedFpCrossBucketInfo +{ + struct Meta4{ uint32 m[4]; }; + + uint32 groupCount[2]; // Groups sizes for the bucket's last 2 groups + + uint32 savedY [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + Meta4 savedMeta[BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + Pair pair [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + + uint32* y = nullptr; + Meta4* meta = nullptr; + uint32 matchCount = 0; + uint32 matchOffset = 0; + + inline uint64 EntryCount() const { return (uint64)groupCount[0] + groupCount[1]; } +}; + + + class FxMatcherBounded { using Job = AnonPrefixSumJob; public: - + //----------------------------------------------------------- + FxMatcherBounded( const uint32 numBuckets ) + : _numBuckets( numBuckets ) + {} + //----------------------------------------------------------- Span Match( Job* self, const uint32 bucket, @@ -26,18 +50,48 @@ public: const Span groups = ScanGroups( self, bucket, yEntries, groupsBuffer, startIndex ); ASSERT( groups.Length() ); + if( self->IsLastThread() && bucket > 0 ) + { + // Perform cross bucket matches on previous bucket, now that we have the new groups + // #TODO: This + } + const uint32 matchCount = MatchGroups( self, + bucket, + bucket, startIndex, groups, yEntries, pairs, - bucket, pairs.Length() ); + // Save cross bucket matches + if( self->IsLastThread() && bucket < _numBuckets ) + { + SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); + } + return pairs.Slice( 0, matchCount ); } -private: + + //----------------------------------------------------------- + template + inline void SaveCrossBucketMeta( const Span meta ) + { + auto& info = _xBucketInfo; + + const size_t copyCount = info.groupCount[0] + info.groupCount[1]; + ASSERT( copyCount <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + + memcpy( info.savedY, yEntries.Ptr() + groupIndices[0], copyCount * sizeof( uint32 ) ); + } + + //----------------------------------------------------------- + inline uint32 CrossBucketMatchCount() const + { + return _crossBucketMatchCount; + } //----------------------------------------------------------- const Span ScanGroups( @@ -109,14 +163,17 @@ private: //----------------------------------------------------------- uint32 MatchGroups( Job* self, + const uint32 lBucket, + const uint32 rBucket, const uint32 startIndex, const Span groupBoundaries, const Span yEntries, Span pairs, - const uint32 bucket, const uint64 maxPairs ) { - const uint64 bucketMask = ((uint64)bucket) << 32; + const uint64 lGroupMask = ((uint64)lBucket) << 32; + const uint64 rGroupMask = ((uint64)rBucket) << 32; + const uint32 groupCount = groupBoundaries.Length() - 1; // Ignore the extra ghost group uint32 pairCount = 0; @@ -125,12 +182,12 @@ private: uint16 rMapIndices[kBC]; uint64 groupLStart = startIndex; - uint64 groupL = (bucketMask | (uint64)yEntries[groupLStart]) / kBC; + uint64 groupL = (lGroupMask | (uint64)yEntries[groupLStart]) / kBC; for( uint32 i = 0; i < groupCount; i++ ) { const uint64 groupRStart = groupBoundaries[i]; - const uint64 groupR = (bucketMask | (uint64)yEntries[groupRStart]) / kBC; + const uint64 groupR = (rGroupMask | (uint64)yEntries[groupRStart]) / kBC; const uint64 groupLEnd = groupRStart; if( groupR - groupL == 1 ) @@ -153,7 +210,7 @@ private: for( uint64 iR = groupRStart; iR < groupREnd; iR++ ) { - uint64 localRY = (bucketMask | (uint64)yEntries[iR]) - groupRRangeStart; + uint64 localRY = (rGroupMask | (uint64)yEntries[iR]) - groupRRangeStart; ASSERT( (bucketMask | (uint64)yEntries[iR]) / kBC == groupR ); if( rMapCounts[localRY] == 0 ) @@ -165,7 +222,7 @@ private: // For each group L entry for( uint64 iL = groupLStart; iL < groupLEnd; iL++ ) { - const uint64 yL = bucketMask | (uint64)yEntries[iL]; + const uint64 yL = lGroupMask | (uint64)yEntries[iL]; const uint64 localL = yL - groupLRangeStart; // Iterate kExtraBitsPow = 1 << kExtraBits = 1 << 6 == 64 @@ -202,6 +259,49 @@ private: } private: - const uint32* _startPositions[BB_DP_MAX_JOBS];// = { 0 }; - Span _groupBuffers [BB_DP_MAX_JOBS]; + //----------------------------------------------------------- + uint32 CrossBucketMatch( Job* self, + const uint32 bucket, + const Span yEntries, + Span groupBoundaries, + Span pairs ) + { + + } + + //----------------------------------------------------------- + inline void SaveCrossBucketGroups( Job* self, + const uint32 bucket, + const Span groupIndices, // Last 3 group indices + const Span yEntries ) + { + auto& info = _xBucketInfo; + + info.matchOffsetPrev = info.matchOffsetCur; + info.matchOffsetCur = groupIndices[0]; + + if( bucket == _numBuckets-1 ) + return; + + info.groupCount[0] = groupIndices[1] - groupIndices[0]; + info.groupCount[1] = groupIndices[2] - groupIndices[1]; + + const size_t copyCount = info.groupCount[0] + info.groupCount[1]; + ASSERT( copyCount <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + + memcpy( info.savedY, yEntries.Ptr() + groupIndices[0], copyCount * sizeof( uint32 ) ); + // memcpy( info.savedMeta, meta + groupIndices[0], copyCount * sizeof( TMeta ) ); + + // #TODO: Re-enable asserts w/ bucket mask + // ASSERT( info.savedY[0] / kBC == info.savedY[info.groupCount[0]-1] / kBC ); + // ASSERT( info.savedY[info.groupCount[0]] / kBC == info.savedY[info.groupCount[0]+info.groupCount[1]-1] / kBC ); + } + +// private: +public: + const uint32* _startPositions[BB_DP_MAX_JOBS];// = { 0 }; + Span _groupBuffers [BB_DP_MAX_JOBS]; + K32BoundedFpCrossBucketInfo _xBucketInfo = {}; + uint32 _bucket = 0; + uint32 _numBuckets; }; diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 36fda3e2..c85f4931 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -149,6 +149,7 @@ public: DiskPlotFxBounded( DiskPlotContext& context ) : _context ( context ) , _ioQueue ( *context.ioQueue ) + , _matcher ( _numBuckets ) , _yReadFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) , _metaReadFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) , _indexReadFence( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) @@ -424,6 +425,9 @@ private: totalMatches = _maxTableEntries; } + // #TODO: Write cross-bucket pairs to previous table + // #TODO: Update previous bucket's count w/ cross-bucket match count + WritePairs( self, bucket, totalMatches, matches, matchOffset ); #if DBG_VALIDATE_TABLES @@ -444,6 +448,8 @@ private: WaitForFence( self, _metaReadFence, bucket ); SortOnYKey( self, sortKey, metaTmp, metaIn ); + + // #TODO: Save cross-bucket meta if constexpr ( rTable == TableId::Table2 ) { @@ -461,7 +467,9 @@ private: self->EndLockBlock(); } - // Gen fx & write + // #TODO: Gen cross-bucket fx & write cross-bucket entries + + /// Gen fx & write { Span yOut = _yTmp.Slice( matchOffset, matches.Length() ); Span metaOut = _metaTmp[1].As().Slice( matchOffset, matches.Length() ); //( (TMetaOut*)metaTmp.Ptr(), matches.Length() ); diff --git a/src/plotdisk/transforms/FxTransform.h b/src/plotdisk/transforms/FxTransform.h deleted file mode 100644 index 177cb530..00000000 --- a/src/plotdisk/transforms/FxTransform.h +++ /dev/null @@ -1,38 +0,0 @@ -#include "plotdisk/IOTransforms.h" -#include "util/BitView.h" - -// class FxTransform : public IIOTransform -// { -// public: -// //----------------------------------------------------------- -// inline void ReadTransform( TransformData& data ) override -// { -// // uint32* -// uint32* y; -// uint64* meta; -// } - -// //----------------------------------------------------------- -// inline void WriteTransform( TransformData& data ) override -// { - -// } - -// private: - -// //----------------------------------------------------------- -// template -// inline void PackFx( void* outBuffer, size_t outBufferSize, -// const uint32* y, const TMeta* meta, const TAddress* key, -// const int64 entryCount, const uint32 k, const uint32 keyBits, const uint32 metaBits ) -// { -// BitWriter writer( (uint64*)outBuffer, outBufferSize * 8 ); - -// for( int64 i = 0; i < entryCount; i++ ) -// { -// writer.Write( y [i], k ); -// writer.Write( key [i], keyBits ); -// writer.Write( meta[i], metaBits ); -// } -// } -// }; From 759d4c850b6cf1f3eb3f01df778533c921a60e19 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 8 Jun 2022 23:53:44 -0500 Subject: [PATCH 32/91] Working on getting cross-bucket matches in for debugging. Will refactor this out to a simpler in-memory method, as this is too complex. --- .vscode/launch.json | 1 + src/plotdisk/k32/FpMatchBounded.inl | 115 +++++++++++++++++++--------- src/plotdisk/k32/FxBounded.inl | 106 +++++++++++++++++-------- 3 files changed, 156 insertions(+), 66 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index e4184c21..2b38a350 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -92,6 +92,7 @@ // "-s", "--k32-bounded", "-b", "64", + // "-b", "128", "--c-threads", "26", "--p2-threads", "24", diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 828e23d5..2f2c238d 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -34,21 +34,52 @@ public: FxMatcherBounded( const uint32 numBuckets ) : _numBuckets( numBuckets ) {} + + //----------------------------------------------------------- + void ScanGroupsAndMatchPreviousBucket( Job* self, + const uint32 bucket, + const Span yEntries, + Span groupsBuffer ) + { + const uint32 id = self->JobId(); + _groupBuffers[id] = groupsBuffer; + + uint32 startIndex; + + Span groups = ScanGroups( self, bucket, yEntries, groupsBuffer, startIndex ); + ASSERT( groups.Length() > 0 ); + _groupBuffers[id] = groups; + + if( self->IsLastThread() ) + { + // Save cross bucket data for this bucket (to be used during the next bucket) + if( bucket < _numBuckets ) + SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); + + // Perform cross-bucket matching for the previous bucket + if( bucket > 0 ) + { + auto& info = GetCrossBucketInfo( bucket-1 ); + Span pairs( info.pair, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + + CrossBucketMatch( self, bucket-1, yEntries, groups, pairs ); + } + } + } //----------------------------------------------------------- Span Match( Job* self, const uint32 bucket, const Span yEntries, - Span groupsBuffer, Span pairs ) { const uint32 id = self->JobId(); - _groupBuffers[id] = groupsBuffer; + // _groupBuffers[id] = groupsBuffer; - uint32 startIndex; - const Span groups = ScanGroups( self, bucket, yEntries, groupsBuffer, startIndex ); - ASSERT( groups.Length() ); + // uint32 startIndex; + // _groupBuffers[id] = ScanGroups( self, bucket, yEntries, groupsBuffer, startIndex ); + // ASSERT( _groupBuffers[id].Length() > 0 ); if( self->IsLastThread() && bucket > 0 ) { @@ -56,20 +87,22 @@ public: // #TODO: This } + const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); + const uint32 matchCount = MatchGroups( self, bucket, bucket, startIndex, - groups, + _groupBuffers[id], yEntries, pairs, pairs.Length() ); - // Save cross bucket matches - if( self->IsLastThread() && bucket < _numBuckets ) - { - SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); - } + // Save cross bucket data + // if( self->IsLastThread() && bucket < _numBuckets ) + // { + // SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); + // } return pairs.Slice( 0, matchCount ); } @@ -77,20 +110,21 @@ public: //----------------------------------------------------------- template - inline void SaveCrossBucketMeta( const Span meta ) + inline void SaveCrossBucketMeta( const uint32 bucket, const Span meta ) { - auto& info = _xBucketInfo; + auto& info = GetCrossBucketInfo( bucket ); - const size_t copyCount = info.groupCount[0] + info.groupCount[1]; + const size_t copyCount = info.EntryCount(); ASSERT( copyCount <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); - memcpy( info.savedY, yEntries.Ptr() + groupIndices[0], copyCount * sizeof( uint32 ) ); + memcpy( info.savedMeta, meta.Ptr() + info.matchOffset, copyCount * sizeof( TMeta ) ); } //----------------------------------------------------------- - inline uint32 CrossBucketMatchCount() const + inline uint32 CrossBucketMatchCount( const uint32 bucket ) const { - return _crossBucketMatchCount; + ASSERT( bucket > 0 ); + return const_cast( this )->GetCrossBucketInfo( bucket ).matchCount; } //----------------------------------------------------------- @@ -163,13 +197,13 @@ public: //----------------------------------------------------------- uint32 MatchGroups( Job* self, - const uint32 lBucket, - const uint32 rBucket, - const uint32 startIndex, - const Span groupBoundaries, - const Span yEntries, - Span pairs, - const uint64 maxPairs ) + const uint32 lBucket, + const uint32 rBucket, + const uint32 startIndex, + const Span groupBoundaries, + const Span yEntries, + Span pairs, + const uint64 maxPairs ) { const uint64 lGroupMask = ((uint64)lBucket) << 32; const uint64 rGroupMask = ((uint64)rBucket) << 32; @@ -211,7 +245,7 @@ public: for( uint64 iR = groupRStart; iR < groupREnd; iR++ ) { uint64 localRY = (rGroupMask | (uint64)yEntries[iR]) - groupRRangeStart; - ASSERT( (bucketMask | (uint64)yEntries[iR]) / kBC == groupR ); + ASSERT( (rGroupMask | (uint64)yEntries[iR]) / kBC == groupR ); if( rMapCounts[localRY] == 0 ) rMapIndices[localRY] = (uint16)( iR - groupRStart ); @@ -258,13 +292,21 @@ public: return pairCount; } + //----------------------------------------------------------- + inline K32BoundedFpCrossBucketInfo& GetCrossBucketInfo( const uint32 bucket ) + { + return _xBucketInfo[bucket & 1]; // bucket % 2 + } + + private: + //----------------------------------------------------------- uint32 CrossBucketMatch( Job* self, - const uint32 bucket, - const Span yEntries, - Span groupBoundaries, - Span pairs ) + const uint32 bucket, + const Span yEntries, + Span groupBoundaries, + Span pairs ) { } @@ -275,10 +317,11 @@ private: const Span groupIndices, // Last 3 group indices const Span yEntries ) { - auto& info = _xBucketInfo; + + auto& info = GetCrossBucketInfo( bucket ); - info.matchOffsetPrev = info.matchOffsetCur; - info.matchOffsetCur = groupIndices[0]; + GetCrossBucketInfo( bucket - 1 ).matchOffset = info.matchOffset; + info.matchOffset = groupIndices[0]; if( bucket == _numBuckets-1 ) return; @@ -289,7 +332,7 @@ private: const size_t copyCount = info.groupCount[0] + info.groupCount[1]; ASSERT( copyCount <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); - memcpy( info.savedY, yEntries.Ptr() + groupIndices[0], copyCount * sizeof( uint32 ) ); + memcpy( info.savedY, yEntries.Ptr() + info.matchOffset, copyCount * sizeof( uint32 ) ); // memcpy( info.savedMeta, meta + groupIndices[0], copyCount * sizeof( TMeta ) ); // #TODO: Re-enable asserts w/ bucket mask @@ -297,11 +340,13 @@ private: // ASSERT( info.savedY[info.groupCount[0]] / kBC == info.savedY[info.groupCount[0]+info.groupCount[1]-1] / kBC ); } + // private: public: const uint32* _startPositions[BB_DP_MAX_JOBS];// = { 0 }; Span _groupBuffers [BB_DP_MAX_JOBS]; - K32BoundedFpCrossBucketInfo _xBucketInfo = {}; - uint32 _bucket = 0; + // uint32 _startIndices [BB_DP_MAX_JOBS]; + K32BoundedFpCrossBucketInfo _xBucketInfo[2] = {}; + uint32 _bucket = 0; uint32 _numBuckets; }; diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index c85f4931..a5c08cff 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -376,7 +376,6 @@ private: Span sortKey = _sortKey.SliceSize( entryCount ); SortY( self, entryCount, yInput.Ptr(), _yTmp.As().Ptr(), sortKey.Ptr(), _metaTmp[1].As().Ptr() ); - /// /// Write reverse map, given the previous table's y origin indices /// @@ -390,40 +389,47 @@ private: SortOnYKey( self, sortKey, _index[bucket], indices ); WriteMap( self, bucket, indices, _mapWriteBuffer, _mapOffset ); } + + // #TODO: Move metadata back after matching, but for simplicity let's do it here now? /// /// Match /// - Span matches = Match( self, bucket, yInput ); + // Span matches = Match( self, bucket, yInput ); // Count the total match count - uint32 totalMatches = 0; - uint32 matchOffset = 0; + // uint32 totalMatches = 0; + // uint32 matchOffset = 0; - for( uint32 i = 0; i < threadCount; i++ ) - totalMatches += (uint32)_pairs[i].Length(); + // for( uint32 i = 0; i < threadCount; i++ ) + // totalMatches += (uint32)_pairs[i].Length(); - for( uint32 i = 0; i < id; i++ ) - matchOffset += (uint32)_pairs[i].Length(); + // for( uint32 i = 0; i < id; i++ ) + // matchOffset += (uint32)_pairs[i].Length(); - ASSERT( totalMatches <= _entriesPerBucket ); + // ASSERT( totalMatches <= _entriesPerBucket ); - // Prevent overflow entries - const uint64 tableEntryCount = _tableEntryCount; - if( bucket == _numBuckets-1 && (tableEntryCount + totalMatches) > _maxTableEntries ) - { - // Prevent calculating fx for overflow matches - if( self->IsLastThread() ) - { - const uint32 overflowEntries = (uint32)( (tableEntryCount + totalMatches) - _maxTableEntries ); - ASSERT( overflowEntries < matches.Length() ); + // // Prevent overflow entries + // const uint64 tableEntryCount = _tableEntryCount; + // if( bucket == _numBuckets-1 && (tableEntryCount + totalMatches) > _maxTableEntries ) + // { + // // Prevent calculating fx for overflow matches + // if( self->IsLastThread() ) + // { + // const uint32 overflowEntries = (uint32)( (tableEntryCount + totalMatches) - _maxTableEntries ); + // ASSERT( overflowEntries < matches.Length() ); - matches = matches.SliceSize( matches.Length() - overflowEntries ); - } + // matches = matches.SliceSize( matches.Length() - overflowEntries ); + // } - totalMatches = _maxTableEntries; - } + // totalMatches = _maxTableEntries; + // } + + ScanGroupsAndCrossBucketMatch( self, bucket, yInput ); + + if( bucket > 0 ) + CompletePreviousBucket( self, bucket - 1 ); // #TODO: Write cross-bucket pairs to previous table // #TODO: Update previous bucket's count w/ cross-bucket match count @@ -434,7 +440,9 @@ private: _dbgPlot.WritePairs( self, rTable, matchOffset, matches, _mapOffset, totalMatches ); #endif - // Sort meta on Y + /// + /// Sort meta on Y + /// Span metaTmp = _meta[bucket].SliceSize( yInput.Length() ); Span metaIn = _metaTmp[0].As().SliceSize( yInput.Length() ); // #NOTE: _metaTmp[0] is only used here, so we can use it for writing x values to disk @@ -449,11 +457,12 @@ private: WaitForFence( self, _metaReadFence, bucket ); SortOnYKey( self, sortKey, metaTmp, metaIn ); - // #TODO: Save cross-bucket meta + SaveCrossBucketMetadata( self, metaIn ); + // On Table 2, metadata is our x values, which have to be saved as table 1 if constexpr ( rTable == TableId::Table2 ) { - // Write x back to disk + // Write (sorted-on-y) x back to disk if( self->BeginLockBlock() ) { #if DBG_VALIDATE_TABLES @@ -467,8 +476,6 @@ private: self->EndLockBlock(); } - // #TODO: Gen cross-bucket fx & write cross-bucket entries - /// Gen fx & write { Span yOut = _yTmp.Slice( matchOffset, matches.Length() ); @@ -596,7 +603,7 @@ private: } //----------------------------------------------------------- - Span Match( Job* self, const uint32 bucket, Span yEntries ) + void ScanGroupsAndCrossBucketMatch( Job* self, const uint32 bucket, Span yEntries ) { const uint32 id = self->JobId(); const uint32 threadCount = self->JobCount(); @@ -609,15 +616,50 @@ private: TimePoint timer; if( self->IsControlThread() ) timer = TimerBegin(); + + // Scan for groups & perform cross-bucket matches for the previous bucket + _matcher.ScanGroupsAndMatchPreviousBucket( self, bucket, yEntries, groupIndices ); + + // // Match this bucket's matches + // _matcher.Match( self, bucket, yEntries, _pairs[id] ); - auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); - _pairs[id] = matches; + // auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); + // _pairs[id] = matches; self->SyncThreads(); if( self->IsControlThread() ) _matchTime += TimerEndTicks( timer ); - return matches; + // return matches; + } + + //----------------------------------------------------------- + Span Match( Job* self const uint32 bucket, const Span yEntries const Span meta ) + { + + } + + //----------------------------------------------------------- + inline void CompletePreviousBucket( Job* self, const uint32 bucket, const Span pairs ) + { + ASSERT( bucket > 0 ); + + if( self->BeginLockBlock() ) + { + auto& info _matcher.GetCrossBucketInfo( bucket - 1 ); + + const uint32 xBucketMatchCount = info.matchCount; + + Span yIn; + Span metaIn; + Span yOut; + Span metaOut; + + GenFx( self, bucket, pairs, yIn, metaIn, yOut, metaOut ); + + // Submit w/ previous bucket + } + self->EndLockBlock(); } //----------------------------------------------------------- @@ -1121,6 +1163,8 @@ private: Span _metaTmp[2]; Span _pairBuffer; + // When doing cross-bucket matching, we save the previous bucket entries as these spans (which just point to the working buffers) + // Working views Span _pairs[BB_DP_MAX_JOBS]; // Pairs buffer divided per thread From e1580be98a0c71fd708d68fd8118b2f636d2ec84 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 11 Jun 2022 06:21:59 -0500 Subject: [PATCH 33/91] More changes re: getting cross-bucket matches to work agian... --- src/plotdisk/k32/FpMatchBounded.inl | 83 ++++++----- src/plotdisk/k32/FxBounded.inl | 221 ++++++++++++++-------------- 2 files changed, 163 insertions(+), 141 deletions(-) diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 2f2c238d..0f06dea3 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -36,10 +36,11 @@ public: {} //----------------------------------------------------------- - void ScanGroupsAndMatchPreviousBucket( Job* self, - const uint32 bucket, - const Span yEntries, - Span groupsBuffer ) + Span Match( Job* self, + const uint32 bucket, + const Span yEntries, + Span groupsBuffer, + Span pairs ) { const uint32 id = self->JobId(); _groupBuffers[id] = groupsBuffer; @@ -48,15 +49,16 @@ public: Span groups = ScanGroups( self, bucket, yEntries, groupsBuffer, startIndex ); ASSERT( groups.Length() > 0 ); + _groupBuffers[id] = groups; if( self->IsLastThread() ) { - // Save cross bucket data for this bucket (to be used during the next bucket) + // Save last 2 group's data for this bucket (to be used during the next bucket) if( bucket < _numBuckets ) SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); - // Perform cross-bucket matching for the previous bucket + // Perform cross-bucket matching for the previous bucket, wwith the first 2 groups of this bucket if( bucket > 0 ) { auto& info = GetCrossBucketInfo( bucket-1 ); @@ -65,27 +67,6 @@ public: CrossBucketMatch( self, bucket-1, yEntries, groups, pairs ); } } - } - - //----------------------------------------------------------- - Span Match( Job* self, - const uint32 bucket, - const Span yEntries, - Span pairs ) - { - const uint32 id = self->JobId(); - - // _groupBuffers[id] = groupsBuffer; - - // uint32 startIndex; - // _groupBuffers[id] = ScanGroups( self, bucket, yEntries, groupsBuffer, startIndex ); - // ASSERT( _groupBuffers[id].Length() > 0 ); - - if( self->IsLastThread() && bucket > 0 ) - { - // Perform cross bucket matches on previous bucket, now that we have the new groups - // #TODO: This - } const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); @@ -98,14 +79,49 @@ public: pairs, pairs.Length() ); - // Save cross bucket data - // if( self->IsLastThread() && bucket < _numBuckets ) - // { - // SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); - // } - return pairs.Slice( 0, matchCount ); + } + + //----------------------------------------------------------- + // Span Match( Job* self, + // const uint32 bucket, + // const Span yEntries, + // Span pairs ) + // { + // const uint32 id = self->JobId(); + + // // _groupBuffers[id] = groupsBuffer; + + // // uint32 startIndex; + // // _groupBuffers[id] = ScanGroups( self, bucket, yEntries, groupsBuffer, startIndex ); + // // ASSERT( _groupBuffers[id].Length() > 0 ); + + // if( self->IsLastThread() && bucket > 0 ) + // { + // // Perform cross bucket matches on previous bucket, now that we have the new groups + // // #TODO: This + // } + + // const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); + + // const uint32 matchCount = MatchGroups( self, + // bucket, + // bucket, + // startIndex, + // _groupBuffers[id], + // yEntries, + // pairs, + // pairs.Length() ); + + // // Save cross bucket data + // // if( self->IsLastThread() && bucket < _numBuckets ) + // // { + // // SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); + // // } + + // return pairs.Slice( 0, matchCount ); + // } //----------------------------------------------------------- @@ -317,7 +333,6 @@ private: const Span groupIndices, // Last 3 group indices const Span yEntries ) { - auto& info = GetCrossBucketInfo( bucket ); GetCrossBucketInfo( bucket - 1 ).matchOffset = info.matchOffset; diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index a5c08cff..160a132a 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -243,7 +243,6 @@ public: _indexWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); _metaWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - const size_t pairsWriteSize = CDiv( entriesPerBucket * _pairBitSize, 8 ); _pairsWriteBuffer = allocator.AllocT( pairsWriteSize, t1BlockSize ); byte* pairBlocks = (byte*)allocator.CAlloc( 1, t1BlockSize, t1BlockSize ); @@ -389,50 +388,39 @@ private: SortOnYKey( self, sortKey, _index[bucket], indices ); WriteMap( self, bucket, indices, _mapWriteBuffer, _mapOffset ); } - - // #TODO: Move metadata back after matching, but for simplicity let's do it here now? - /// /// Match /// - // Span matches = Match( self, bucket, yInput ); + Span matches = Match( self, bucket, yInput ); // Count the total match count - // uint32 totalMatches = 0; - // uint32 matchOffset = 0; - - // for( uint32 i = 0; i < threadCount; i++ ) - // totalMatches += (uint32)_pairs[i].Length(); - - // for( uint32 i = 0; i < id; i++ ) - // matchOffset += (uint32)_pairs[i].Length(); + uint32 totalMatches = 0; + uint32 matchOffset = 0; - // ASSERT( totalMatches <= _entriesPerBucket ); - - // // Prevent overflow entries - // const uint64 tableEntryCount = _tableEntryCount; - // if( bucket == _numBuckets-1 && (tableEntryCount + totalMatches) > _maxTableEntries ) - // { - // // Prevent calculating fx for overflow matches - // if( self->IsLastThread() ) - // { - // const uint32 overflowEntries = (uint32)( (tableEntryCount + totalMatches) - _maxTableEntries ); - // ASSERT( overflowEntries < matches.Length() ); + for( uint32 i = 0; i < threadCount; i++ ) + totalMatches += (uint32)_pairs[i].Length(); - // matches = matches.SliceSize( matches.Length() - overflowEntries ); - // } + for( uint32 i = 0; i < id; i++ ) + matchOffset += (uint32)_pairs[i].Length(); - // totalMatches = _maxTableEntries; - // } + ASSERT( totalMatches <= _entriesPerBucket ); - ScanGroupsAndCrossBucketMatch( self, bucket, yInput ); + // Prevent overflow entries + const uint64 tableEntryCount = _tableEntryCount; + if( bucket == _numBuckets-1 && (tableEntryCount + totalMatches) > _maxTableEntries ) + { + // Prevent calculating fx for overflow matches + if( self->IsLastThread() ) + { + const uint32 overflowEntries = (uint32)( (tableEntryCount + totalMatches) - _maxTableEntries ); + ASSERT( overflowEntries < matches.Length() ); - if( bucket > 0 ) - CompletePreviousBucket( self, bucket - 1 ); + matches = matches.SliceSize( matches.Length() - overflowEntries ); + } - // #TODO: Write cross-bucket pairs to previous table - // #TODO: Update previous bucket's count w/ cross-bucket match count + totalMatches = _maxTableEntries; + } WritePairs( self, bucket, totalMatches, matches, matchOffset ); @@ -458,6 +446,7 @@ private: SortOnYKey( self, sortKey, metaTmp, metaIn ); SaveCrossBucketMetadata( self, metaIn ); + // On Table 2, metadata is our x values, which have to be saved as table 1 if constexpr ( rTable == TableId::Table2 ) @@ -508,6 +497,9 @@ private: WriteEntries( self, bucket, (uint32)_tableEntryCount + matchOffset, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); } + // Generate fx for cross-bucket matches, and save the matches to an in-memory buffer + GenCrossBucketFx( self, bucket ); + if( self->IsControlThread() ) { _tableEntryCount += totalMatches; @@ -603,7 +595,7 @@ private: } //----------------------------------------------------------- - void ScanGroupsAndCrossBucketMatch( Job* self, const uint32 bucket, Span yEntries ) + void Match( Job* self, const uint32 bucket, Span yEntries ) { const uint32 id = self->JobId(); const uint32 threadCount = self->JobCount(); @@ -618,50 +610,112 @@ private: timer = TimerBegin(); // Scan for groups & perform cross-bucket matches for the previous bucket - _matcher.ScanGroupsAndMatchPreviousBucket( self, bucket, yEntries, groupIndices ); + // _matcher.ScanGroupsAndMatchPreviousBucket( self, bucket, yEntries, groupIndices ); // // Match this bucket's matches // _matcher.Match( self, bucket, yEntries, _pairs[id] ); - // auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); - // _pairs[id] = matches; + auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); + _pairs[id] = matches; self->SyncThreads(); if( self->IsControlThread() ) _matchTime += TimerEndTicks( timer ); - // return matches; - } + // Write cross-bucket pairs to disk + if( bucket > 0 ) + WriteCrossBucketPairs( self, bucket-1 ) + return matches; + } + //----------------------------------------------------------- - Span Match( Job* self const uint32 bucket, const Span yEntries const Span meta ) + void WriteCrossBucketPairs( Job* self, const uint32 bucket ) { + auto& info = _matcher.GetCrossBucketInfo( bucket ); + if( info.matchCount < 1 ) + return; + + if( self->BeginLockBlock() ) + { + const uint23 offset = _tableEntryCount; + const Span pairs( info.pair, info.matchCount ); + + _tableEntryCount += info.matchCount; + // #TODO: How do we handle this? We need to wait on a fence, but how? + // _pairWriteFence.Wait( bucket ); + // _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer ); + // BitWriter writer = _pairBitWriter.GetWriter( 0, dstOffset * _pairBitSize ); + // PackPairs( self, pairs, writer ); + // _pairBitWriter.Submit(); + // _ioQueue.SignalFence( _pairWriteFence, bucket + 1 ); + // _ioQueue.CommitCommands(); + } + self->EndLockBlock(); } //----------------------------------------------------------- - inline void CompletePreviousBucket( Job* self, const uint32 bucket, const Span pairs ) + void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, + const Span matches, const uint64 dstOffset ) { - ASSERT( bucket > 0 ); + ASSERT( dstOffset + matches.length <= totalMatchCount ); + // Need to wait for our write buffer to be ready to use again if( self->BeginLockBlock() ) { - auto& info _matcher.GetCrossBucketInfo( bucket - 1 ); + if( bucket > 0 ) + { + // Write crosss-bucket values pairs first, which belong to the previous bucket - const uint32 xBucketMatchCount = info.matchCount; + _pairWriteFence.Wait( bucket ); + } - Span yIn; - Span metaIn; - Span yOut; - Span metaOut; + uint64 bitBucketSizes = totalMatchCount * _pairBitSize; + _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer ); + } + self->EndLockBlock(); + + // #TOOD: Write pairs raw? Or bucket-relative? Maybe raw for now - GenFx( self, bucket, pairs, yIn, metaIn, yOut, metaOut ); + // #NOTE: For now we write compressed as in standard FP. + BitWriter writer = _pairBitWriter.GetWriter( 0, dstOffset * _pairBitSize ); - // Submit w/ previous bucket + ASSERT( matches.Length() > 2 ); + PackPairs( self, matches.Slice( 0, 2 ), writer ); + self->SyncThreads(); + PackPairs( self, matches.Slice( 2 ), writer ); + + // Write to disk + if( self->BeginLockBlock() ) + { + _pairBitWriter.Submit(); + _ioQueue.SignalFence( _pairWriteFence, bucket + 1 ); + _ioQueue.CommitCommands(); } self->EndLockBlock(); } + //----------------------------------------------------------- + void PackPairs( Job* self, const Span pairs, BitWriter& writer ) + { + self; + + const uint32 shift = _pairsRightBits; + const uint64 mask = ( 1ull << shift ) - 1; + + const Pair* pair = pairs.Ptr(); + const Pair* end = pair + pairs.Length(); + + while( pair < end ) + { + ASSERT( pair->right - pair->left < _pairsMaxDelta ); + + writer.Write( ( (uint64)(pair->right - pair->left) << shift ) | ( pair->left & mask ), _pairBitSize ); + pair++; + } + } + //----------------------------------------------------------- void WriteMap( Job* self, const uint32 bucket, const Span bucketIndices, Span mapOut, const uint32 tableOffset ) { @@ -738,63 +792,6 @@ private: // self->EndLockBlock(); } - //----------------------------------------------------------- - void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, - const Span matches, const uint64 dstOffset ) - { - ASSERT( dstOffset + matches.length <= totalMatchCount ); - - // Need to wait for our write buffer to be ready to use again - if( self->BeginLockBlock() ) - { - if( bucket > 0 ) - _pairWriteFence.Wait( bucket ); - - uint64 bitBucketSizes = totalMatchCount * _pairBitSize; - _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer ); - } - self->EndLockBlock(); - - // #TOOD: Write pairs raw? Or bucket-relative? Maybe raw for now - - // #NOTE: For now we write compressed as in standard FP. - BitWriter writer = _pairBitWriter.GetWriter( 0, dstOffset * _pairBitSize ); - - ASSERT( matches.Length() > 2 ); - PackPairs( self, matches.Slice( 0, 2 ), writer ); - self->SyncThreads(); - PackPairs( self, matches.Slice( 2 ), writer ); - - // Write to disk - if( self->BeginLockBlock() ) - { - _pairBitWriter.Submit(); - _ioQueue.SignalFence( _pairWriteFence, bucket + 1 ); - _ioQueue.CommitCommands(); - } - self->EndLockBlock(); - } - - //----------------------------------------------------------- - void PackPairs( Job* self, const Span pairs, BitWriter& writer ) - { - self; - - const uint32 shift = _pairsRightBits; - const uint64 mask = ( 1ull << shift ) - 1; - - const Pair* pair = pairs.Ptr(); - const Pair* end = pair + pairs.Length(); - - while( pair < end ) - { - ASSERT( pair->right - pair->left < _pairsMaxDelta ); - - writer.Write( ( (uint64)(pair->right - pair->left) << shift ) | ( pair->left & mask ), _pairBitSize ); - pair++; - } - } - //----------------------------------------------------------- void WriteEntries( Job* self, const uint32 bucket, @@ -876,6 +873,16 @@ private: _distributeTime += TimerEndTicks( timer ); } + //----------------------------------------------------------- + template + void GenCrossBucketFx( + Job* self, + const uint32 bucket + ) + { + + } + //----------------------------------------------------------- template void GenFx( Job* self, From 9e6f0fd32084ac41d6f4902b671e7a72b68cf879 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 12 Jun 2022 05:25:40 -0500 Subject: [PATCH 34/91] Refactoring cross-bucket match stuff so that it's simpler and easier to manage, at the expense of a a few megabytes more. --- src/plotdisk/DiskPlotConfig.h | 4 ++- src/plotdisk/DiskPlotter.cpp | 1 - src/plotdisk/k32/DiskPlotBounded.cpp | 44 ++++++++++++++++++++-------- src/plotdisk/k32/DiskPlotBounded.h | 14 ++++++++- src/plotdisk/k32/FpMatchBounded.inl | 23 +++++++++++---- src/plotdisk/k32/FxBounded.inl | 34 +++++++++++++-------- src/util/StackAllocator.h | 2 +- 7 files changed, 88 insertions(+), 34 deletions(-) diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 9039d571..b33c325e 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -72,4 +72,6 @@ // #define BB_DP_DBG_P3_START_TABLE Table7 // #define BB_DP_DBG_P3_KEEP_FILES 1 -#endif \ No newline at end of file +#endif + +#define BB_DP_FP_MATCH_X_BUCKET 1 diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 9f1b1468..8e8ee2e4 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -477,7 +477,6 @@ size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 // 2 marking table bitfields in-memory: k^32 / 8 = 0.5GiB // return 1032ull MB + DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); - default: break; } diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 14ed29f3..476ed6f4 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -1,6 +1,5 @@ #include "DiskPlotBounded.h" #include "util/Util.h" -#include "util/StackAllocator.h" #include "threading/MTJob.h" #include "plotdisk/DiskPlotInfo.h" #include "plotdisk/DiskPlotContext.h" @@ -13,16 +12,15 @@ //----------------------------------------------------------- K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) - : _context( context ) - , _ioQueue( *_context.ioQueue ) + : _context ( context ) + , _ioQueue ( *_context.ioQueue ) + , _allocator( context.heapBuffer, context.heapSize ) { const uint32 numBuckets = context.numBuckets; // Open files - // Temp1 { - const FileSetOptions tmp1Options = context.cfg->noTmp1DirectIO ? FileSetOptions::None : FileSetOptions::DirectIO; _ioQueue.InitFileSet( FileId::T1, "t1", 1, tmp1Options, nullptr ); // X (sorted on Y) @@ -67,18 +65,25 @@ K32BoundedPhase1::~K32BoundedPhase1() //----------------------------------------------------------- size_t K32BoundedPhase1::GetRequiredSize( const uint32 numBuckets, const size_t t1BlockSize, const size_t t2BlockSize, const uint32 threadCount ) { + DummyAllocator allocator; + + #if BB_DP_FP_MATCH_X_BUCKET + allocator.CAlloc( numBuckets ); + #endif + switch( numBuckets ) { - case 64 : return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize, threadCount ); - case 128: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize, threadCount ); - case 256: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize, threadCount ); - case 512: return DiskPlotFxBounded::GetRequiredHeapSize( t1BlockSize, t2BlockSize, threadCount ); + case 64 : DiskPlotFxBounded::GetRequiredHeapSize( allocator, t1BlockSize, t2BlockSize, threadCount ); break; + case 128: DiskPlotFxBounded::GetRequiredHeapSize( allocator, t1BlockSize, t2BlockSize, threadCount ); break; + case 256: DiskPlotFxBounded::GetRequiredHeapSize( allocator, t1BlockSize, t2BlockSize, threadCount ); break; + case 512: DiskPlotFxBounded::GetRequiredHeapSize( allocator, t1BlockSize, t2BlockSize, threadCount ); break; + default: + Panic( "Invalid bucket count %u.", numBuckets ); break; } - Panic( "Invalid bucket count %u.", numBuckets ); - return 0; + return allocator.Size(); } //----------------------------------------------------------- @@ -114,6 +119,12 @@ void K32BoundedPhase1::RunWithBuckets() RunF1<_numBuckets>(); #endif + #if BB_DP_FP_MATCH_X_BUCKET + _crossBucketEntries.values = _allocator.CAlloc( _numBuckets ); + _crossBucketEntries.length = _numBuckets; + + _xBucketStackMarker = _allocator.Size(); + #endif for( TableId table = startTable; table <= TableId::Table7; table++ ) { @@ -140,6 +151,7 @@ void K32BoundedPhase1::RunF1() Log::Line( "Generating f1..." ); auto timer = TimerBegin(); + StackAllocator allocator( _context.heapBuffer, _context.heapSize ); K32BoundedF1<_numBuckets> f1( _context, allocator ); f1.Run(); @@ -173,8 +185,16 @@ void K32BoundedPhase1::RunFx() Log::Line( "Table %u", table+1 ); auto timer = TimerBegin(); + #if BB_DP_FP_MATCH_X_BUCKET + _allocator.PopToMarker( _xBucketStackMarker ); + #endif + DiskPlotFxBounded fx( _context ); - fx.Run(); + fx.Run( _allocator + #if BB_DP_FP_MATCH_X_BUCKET + , _crossBucketEntries + #endif + ); Log::Line( "Completed table %u in %.2lf seconds with %.llu entries.", table+1, TimerEnd( timer ), _context.entryCounts[(int)table] ); Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( fx._tableIOWait ) ); diff --git a/src/plotdisk/k32/DiskPlotBounded.h b/src/plotdisk/k32/DiskPlotBounded.h index 9316a3f1..5fda699d 100644 --- a/src/plotdisk/k32/DiskPlotBounded.h +++ b/src/plotdisk/k32/DiskPlotBounded.h @@ -1,5 +1,8 @@ #pragma once #include "plotdisk/DiskPlotContext.h" +#include "util/StackAllocator.h" + +struct K32CrossBucketEntries; // Bounded k32 disk plotter class K32BoundedPhase1 @@ -26,4 +29,13 @@ class K32BoundedPhase1 private: DiskPlotContext& _context; DiskBufferQueue& _ioQueue; -}; \ No newline at end of file + + StackAllocator _allocator; + +#if BB_DP_FP_MATCH_X_BUCKET + size_t _xBucketStackMarker = 0; + Span _crossBucketEntries; +#endif + +}; + diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 0f06dea3..01bf4f97 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -5,6 +5,17 @@ #include "util/StackAllocator.h" +struct K32CrossBucketEntries +{ + struct Meta4{ uint32 m[4]; }; + + uint32 length; + uint64 y [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + uint32 index[BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + Meta4 meta [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; +}; + + struct K32BoundedFpCrossBucketInfo { struct Meta4{ uint32 m[4]; }; @@ -36,11 +47,11 @@ public: {} //----------------------------------------------------------- - Span Match( Job* self, - const uint32 bucket, - const Span yEntries, - Span groupsBuffer, - Span pairs ) + Span Match( Job* self, + const uint32 bucket, + const Span yEntries, + Span groupsBuffer, + Span pairs ) { const uint32 id = self->JobId(); _groupBuffers[id] = groupsBuffer; @@ -68,7 +79,7 @@ public: } } - const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); + // const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); const uint32 matchCount = MatchGroups( self, bucket, diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 160a132a..0b7737ce 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -173,17 +173,12 @@ public: } //----------------------------------------------------------- - static size_t GetRequiredHeapSize( const size_t t1BlockSize, const size_t t2BlockSize, const uint32 threadCount ) + static void GetRequiredHeapSize( IAllocator& allocator, const size_t t1BlockSize, const size_t t2BlockSize, const uint32 threadCount ) { DiskPlotContext cx = {}; DiskPlotFxBounded instance( cx ); - - DummyAllocator allocator; instance.AllocateBuffers( allocator, t1BlockSize, t2BlockSize, threadCount, true ); - const size_t requiredSize = allocator.Size(); - - return requiredSize; } //----------------------------------------------------------- @@ -276,7 +271,11 @@ public: // Generate fx for a whole table //----------------------------------------------------------- - void Run() + void Run( IAllocator& allocator + #if BB_DP_FP_MATCH_X_BUCKET + , Span crossBucketEntries + #endif + ) { #if DBG_VALIDATE_TABLES _dbgPlot.AllocTable( rTable ); @@ -297,7 +296,6 @@ public: _ioQueue.CommitCommands(); // Allocate buffers - StackAllocator allocator( _context.heapBuffer, _context.heapSize ); AllocateBuffers( allocator, _context.tmp1BlockSize, _context.tmp2BlockSize, _context.fpThreadCount, false ); // Init buffers @@ -595,7 +593,7 @@ private: } //----------------------------------------------------------- - void Match( Job* self, const uint32 bucket, Span yEntries ) + Span Match( Job* self, const uint32 bucket, Span yEntries ) { const uint32 id = self->JobId(); const uint32 threadCount = self->JobCount(); @@ -624,11 +622,17 @@ private: // Write cross-bucket pairs to disk if( bucket > 0 ) - WriteCrossBucketPairs( self, bucket-1 ) + WriteCrossBucketPairs( self, bucket-1 ); return matches; } + //----------------------------------------------------------- + void SaveCrossBucketMetadata( Job* self, const Span metaIn ) + { + + } + //----------------------------------------------------------- void WriteCrossBucketPairs( Job* self, const uint32 bucket ) { @@ -639,10 +643,10 @@ private: if( self->BeginLockBlock() ) { - const uint23 offset = _tableEntryCount; + const uint32 offset = _tableEntryCount; const Span pairs( info.pair, info.matchCount ); - _tableEntryCount += info.matchCount; + // _tableEntryCount += info.matchCount; // #TODO: How do we handle this? We need to wait on a fence, but how? // _pairWriteFence.Wait( bucket ); // _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer ); @@ -655,6 +659,12 @@ private: self->EndLockBlock(); } + //----------------------------------------------------------- + void GenCrossBucketFx( Job* self, const uint32 bucket ) + { + + } + //----------------------------------------------------------- void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, const Span matches, const uint64 dstOffset ) diff --git a/src/util/StackAllocator.h b/src/util/StackAllocator.h index 649e0e1a..dc31e096 100644 --- a/src/util/StackAllocator.h +++ b/src/util/StackAllocator.h @@ -65,7 +65,7 @@ class StackAllocator : public IAllocator public: //----------------------------------------------------------- - inline StackAllocator( void* buffer, size_t capacity ) + inline StackAllocator( void* buffer, const size_t capacity ) : _buffer ( (byte*)buffer ) , _capacity( capacity ) {} From 88f8c334e6ed4212b8d8160e73f4202f0ce0c8a9 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 12 Jun 2022 23:43:39 -0500 Subject: [PATCH 35/91] Fixed issue where each subsequent table would lose entries during FP. --- .vscode/launch.json | 2 +- src/plotdisk/k32/FpMatchBounded.inl | 28 +++++++++++------------ src/plotdisk/k32/FxBounded.inl | 35 +++++++++++++---------------- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 2b38a350..0a8eb824 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -79,7 +79,7 @@ "-t1", "~/plot/tmp", "--f1-threads", "12", // "--f1-threads", "3", - // "--fp-threads", "62", + // "--fp-threads", "1", "--fp-threads", "62", // "--f1-threads", "7", diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 01bf4f97..130af8d9 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -63,21 +63,21 @@ public: _groupBuffers[id] = groups; - if( self->IsLastThread() ) - { - // Save last 2 group's data for this bucket (to be used during the next bucket) - if( bucket < _numBuckets ) - SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); - - // Perform cross-bucket matching for the previous bucket, wwith the first 2 groups of this bucket - if( bucket > 0 ) - { - auto& info = GetCrossBucketInfo( bucket-1 ); - Span pairs( info.pair, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + // if( self->IsLastThread() ) + // { + // // Save last 2 group's data for this bucket (to be used during the next bucket) + // if( bucket < _numBuckets ) + // SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); + + // // Perform cross-bucket matching for the previous bucket, wwith the first 2 groups of this bucket + // if( bucket > 0 ) + // { + // auto& info = GetCrossBucketInfo( bucket-1 ); + // Span pairs( info.pair, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); - CrossBucketMatch( self, bucket-1, yEntries, groups, pairs ); - } - } + // CrossBucketMatch( self, bucket-1, yEntries, groups, pairs ); + // } + // } // const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 0b7737ce..31aadc35 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -301,24 +301,14 @@ public: // Init buffers const uint32 threadCount = _context.fpThreadCount; + for( uint32 i = 0; i < _numBuckets; i++ ) { - const uint32 matchesPerThread =_entriesPerBucket / threadCount; - auto pairBuffer = _pairBuffer; - - for( uint32 i = 0; i < threadCount; i++ ) - { - _pairs[i] = pairBuffer.Slice( 0, matchesPerThread ); - pairBuffer = pairBuffer.Slice( matchesPerThread ); - } - - for( uint32 i = 0; i < _numBuckets; i++ ) - { - const uint32 bufIdx = i & 1; // % 2 - _y [i] = _yBuffers [bufIdx]; - _index[i] = _indexBuffers[bufIdx]; - _meta [i] = _metaBuffers [bufIdx].As(); - } + const uint32 bufIdx = i & 1; // % 2 + _y [i] = _yBuffers [bufIdx]; + _index[i] = _indexBuffers[bufIdx]; + _meta [i] = _metaBuffers [bufIdx].As(); } + // Set some initial fence status _mapWriteFence.Signal( 0 ); @@ -403,6 +393,10 @@ private: matchOffset += (uint32)_pairs[i].Length(); ASSERT( totalMatches <= _entriesPerBucket ); + // #if _DEBUG + // if( self->IsControlThread() ) + // Log::Line( " [%3u] : %u", bucket, totalMatches ); + // #endif // Prevent overflow entries const uint64 tableEntryCount = _tableEntryCount; @@ -443,7 +437,7 @@ private: WaitForFence( self, _metaReadFence, bucket ); SortOnYKey( self, sortKey, metaTmp, metaIn ); - SaveCrossBucketMetadata( self, metaIn ); + // SaveCrossBucketMetadata( self, metaIn ); // On Table 2, metadata is our x values, which have to be saved as table 1 @@ -496,7 +490,7 @@ private: } // Generate fx for cross-bucket matches, and save the matches to an in-memory buffer - GenCrossBucketFx( self, bucket ); + // GenCrossBucketFx( self, bucket ); if( self->IsControlThread() ) { @@ -612,7 +606,10 @@ private: // // Match this bucket's matches // _matcher.Match( self, bucket, yEntries, _pairs[id] ); - + + const uint32 maxMatchesPerThread =_entriesPerBucket / threadCount; + _pairs[id] = _pairBuffer.Slice( maxMatchesPerThread * id, maxMatchesPerThread ); + auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); _pairs[id] = matches; From 6d8d326c076a3b6949c71d0e7a82669f5a547bba Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 14 Jun 2022 00:42:45 -0500 Subject: [PATCH 36/91] Phase 2 hooked-up to bounded plotter --- src/plotdisk/DiskFxGen.h | 6 - src/plotdisk/DiskPairReader.h | 254 +++------------------------ src/plotdisk/DiskPlotConfig.h | 4 +- src/plotdisk/DiskPlotPhase2.cpp | 56 +++--- src/plotdisk/DiskPlotPhase2.h | 16 +- src/plotdisk/DiskPlotter.cpp | 122 ++++++++++++- src/plotdisk/k32/DiskPlotBounded.cpp | 4 +- src/plotdisk/k32/F1Bounded.inl | 14 +- src/plotdisk/k32/FxBounded.inl | 55 +++--- 9 files changed, 226 insertions(+), 305 deletions(-) delete mode 100644 src/plotdisk/DiskFxGen.h diff --git a/src/plotdisk/DiskFxGen.h b/src/plotdisk/DiskFxGen.h deleted file mode 100644 index 325a6674..00000000 --- a/src/plotdisk/DiskFxGen.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -struct DiskFxGen -{ - -}; \ No newline at end of file diff --git a/src/plotdisk/DiskPairReader.h b/src/plotdisk/DiskPairReader.h index 4fdea33b..09b4ab98 100644 --- a/src/plotdisk/DiskPairReader.h +++ b/src/plotdisk/DiskPairReader.h @@ -20,7 +20,8 @@ struct DiskMapReader DiskMapReader() {} //----------------------------------------------------------- - DiskMapReader( DiskPlotContext& context, const uint32 threadCount, const TableId table, const FileId fileId, IAllocator& allocator, const uint64* realBucketLengths = nullptr ) + DiskMapReader( DiskPlotContext& context, const uint32 threadCount, const TableId table, const FileId fileId, + IAllocator& allocator, const uint64* realBucketLengths = nullptr ) : _context ( &context ) , _table ( table ) , _fileId ( fileId ) @@ -236,12 +237,17 @@ struct DiskMapReader // maps, have assymetric bucket counts (or not synchronized with each other), // as the maps have been sorted on y and written back to their original buckets, // and pairs were never sorted on y. -template +template struct DiskPairAndMapReader { - static constexpr uint32 _k = _K; - static constexpr uint32 _savedBits = bblog2( _numBuckets ); - static constexpr uint32 _pairBits = _k + 1 - _savedBits + 9; + static constexpr uint32 _extraBuckets = _bounded ? 0 : 1; + static constexpr uint32 _k = _K; + static constexpr uint32 _savedBits = bblog2( _numBuckets ); + static constexpr uint32 _lBits = ( _bounded ? _k : _k + 1 ) - _savedBits; + static constexpr uint32 _rBits = 9; + static constexpr uint32 _pairBits = _lBits + _rBits; + + using MapReader = DiskMapReader; //----------------------------------------------------------- DiskPairAndMapReader( DiskPlotContext& context, const uint32 threadCount, Fence& fence, const TableId table, IAllocator& allocator, bool noMap ) @@ -284,7 +290,9 @@ struct DiskPairAndMapReader void LoadNextBucket() { if( _bucketsLoaded >= _numBuckets ) + { return; + } ASSERT( _table > TableId::Table1 ); @@ -340,6 +348,7 @@ struct DiskPairAndMapReader AnonMTJob::Run( *_context.threadPool, _threadCount, [=]( AnonMTJob* self ) { + Pair* pairs = outPairs; int64 count, offset, end; GetThreadOffsets( self, bucketLength, count, offset, end ); @@ -347,17 +356,13 @@ struct DiskPairAndMapReader const size_t bitOffset = startBit + (size_t)offset * _pairBits; BitReader reader( (uint64*)pairBuffer, fullBitSize, bitOffset ); - // const uint64 pairOffset = _entriesLoaded; - const uint32 lBits = _k - _savedBits + 1; - const uint32 rBits = 9; - for( int64 i = offset; i < end; i++ ) { Pair pair; - pair.left = (uint32)reader.ReadBits64( lBits ); - pair.right = pair.left + (uint32)reader.ReadBits64( rBits ); + pair.left = (uint32)reader.ReadBits64( _lBits ); + pair.right = pair.left + (uint32)reader.ReadBits64( _rBits ); - outPairs[i] = pair; + pairs[i] = pair; } }); @@ -369,10 +374,10 @@ struct DiskPairAndMapReader } private: - DiskPlotContext& _context; - Fence& _fence; + DiskPlotContext& _context; + Fence& _fence; - DiskMapReader _mapReader; + MapReader _mapReader; void* _pairBuffers [2]; uint32 _pairOverflowBits [_numBuckets]; @@ -586,225 +591,6 @@ class SingleFileMapReader : public IP3LMapReader T _retainedEntries[_retainCount]; }; -// template -// class K32BoundedMapReader -// { -// //----------------------------------------------------------- -// K32BoundedMapReader() {} - -// //----------------------------------------------------------- -// K32BoundedMapReader( DiskPlotContext& context, const uint32 threadCount, const TableId table, const FileId fileId, -// IAllocator& allocator, -// const uint64* realBucketLengths = nullptr ) -// : _context ( &context ) -// , _table ( table ) -// , _fileId ( fileId ) -// , _threadCount( threadCount ) -// { -// const uint64 maxKEntries = ( 1ull << _k ); -// const uint64 maxBucketEntries = maxKEntries / _numBuckets; -// const size_t blockSize = context.ioQueue->BlockSize( fileId ); -// const size_t bufferSize = CDivT( (size_t)maxBucketEntries * _mapBits, blockSize * 8 ) * blockSize; - -// _loadBuffers[0] = allocator.Alloc( bufferSize, blockSize ); -// _loadBuffers[1] = allocator.Alloc( bufferSize, blockSize ); -// _loadBuffers[2] = allocator.Alloc( bufferSize, blockSize ); -// _loadBuffers[3] = allocator.Alloc( bufferSize, blockSize ); - -// _unpackdMaps[0] = allocator.CAlloc( maxBucketEntries ); -// _unpackdMaps[1] = allocator.CAlloc( maxBucketEntries ); - -// if( realBucketLengths ) -// memcpy( _bucketLengths, realBucketLengths, sizeof( _bucketLengths ) ); -// else -// { -// for( uint32 b = 0; b < _numBuckets-1; b++ ) -// _bucketLengths[b] = maxBucketEntries; - -// _bucketLengths[_numBuckets-1] = GetVirtualBucketLength( _numBuckets-1 ); -// _bucketLengths[_numBuckets] = GetVirtualBucketLength( _numBuckets ); -// } - -// ASSERT( _numBuckets == context.numBuckets ); -// } - -// //----------------------------------------------------------- -// void LoadNextEntries( const uint64 entryCount ) -// { -// if( _bucketsLoaded >= _numBuckets ) -// return; - -// DiskBufferQueue& ioQueue = *_context->ioQueue; - -// const size_t blockSize = ioQueue.BlockSize( _fileId ); -// const size_t blockSizeBits = blockSize * 8; - -// uint64 bucketLength = GetVirtualBucketLength( _bucketsLoaded ); -// ASSERT( bucketLength ); - -// // Need to load current bucket? -// if( _bucketEntryOffset == 0 ) -// { -// // Load length (actual bucket length) might be different than the virtual length -// const size_t loadSize = CDivT( (size_t)_bucketLengths[_bucketsLoaded] * _mapBits, blockSizeBits ) * blockSize; -// ioQueue.ReadFile( _fileId, _bucketsLoaded, GetBucketBuffer( _bucketsLoaded ), loadSize ); -// // _fence.Signal( _bucketsLoaded + 1 ); -// } - -// _bucketEntryOffset += entryCount; - -// // It is possible to cross 2 buckets, so we need to account for that. -// // But we ought never have to load more than 2 buckets on one go. -// while( _bucketEntryOffset > bucketLength ) -// { -// _bucketEntryOffset -= bucketLength; -// _bucketsLoaded++; -// ASSERT( _bucketsLoaded <= _numBuckets ); - -// // Upade bucket length and load the new bucket -// bucketLength = GetVirtualBucketLength( _bucketsLoaded ); -// ASSERT( bucketLength ); - -// const size_t loadSize = CDivT( (size_t)_bucketLengths[_bucketsLoaded] * _mapBits, blockSizeBits ) * blockSize; -// ioQueue.ReadFile( _fileId, _bucketsLoaded, GetBucketBuffer( _bucketsLoaded ), loadSize ); -// // _fence.Signal( _bucketsLoaded + 1 ); -// } -// } - -// //----------------------------------------------------------- -// void ReadEntries( const uint64 entryCount, TMap* outMap ) -// { -// ASSERT( _bucketsRead <= _numBuckets ); - -// // #TODO: Check here if we have to unpack a bucket and then check our own fence. -// AnonMTJob::Run( *_context->threadPool, _threadCount, [=]( AnonMTJob* self ) { - -// uint64 entriesToRead = entryCount; -// TMap* outWriter = outMap; -// uint64 readBucketOffset = _bucketReadOffset; -// uint32 bucketsRead = _bucketsRead; - -// while( entriesToRead ) -// { -// // Unpack the whole bucket into it's destination indices -// if( _bucketsUnpacked <= bucketsRead ) -// { -// #if _DEBUG -// const uint64 virtBucketLength = GetVirtualBucketLength( _bucketsUnpacked ); -// #endif - -// const uint64 bucketLength = _bucketLengths[_bucketsUnpacked]; - -// int64 count, offset, end; -// GetThreadOffsets( self, (int64)bucketLength, count, offset, end ); -// ASSERT( count > 0 ); - -// TMap* unpackedMap = _unpackdMaps[_bucketsUnpacked & 1]; -// BitReader reader( (uint64*)GetBucketBuffer( _bucketsUnpacked ), _mapBits * bucketLength, offset * _mapBits ); - -// const uint32 idxShift = _finalIdxBits; -// const uint64 finalIdxMask = ( 1ull << idxShift ) - 1; - -// for( int64 i = offset; i < end; i++ ) -// { -// const uint64 packedMap = reader.ReadBits64( (uint32)_mapBits ); -// const uint64 map = packedMap & finalIdxMask; -// const uint64 dstIdx = packedMap >> idxShift; - -// ASSERT( dstIdx < virtBucketLength ); -// unpackedMap[dstIdx] = (TMap)map; -// } - -// if( self->IsControlThread() ) -// { -// self->LockThreads(); -// _bucketsUnpacked++; -// self->ReleaseThreads(); -// } -// else -// self->WaitForRelease(); -// } - -// const uint64 bucketLength = GetVirtualBucketLength( bucketsRead ); -// const uint64 readCount = std::min( bucketLength - readBucketOffset, entriesToRead ); - -// const TMap* readMap = _unpackdMaps[bucketsRead & 1] + readBucketOffset; - -// // Simply copy the unpacked map to the destination buffer -// int64 count, offset, end; -// GetThreadOffsets( self, (int64)readCount, count, offset, end ); - -// if( count ) -// memcpy( outWriter + offset, readMap + offset, (size_t)count * sizeof( TMap ) ); - -// // Update read entries -// entriesToRead -= readCount; -// outWriter += readCount; - -// readBucketOffset += readCount; -// if( readBucketOffset == bucketLength ) -// { -// readBucketOffset = 0; -// bucketsRead++; -// } -// } - -// if( self->IsControlThread() ) -// { -// self->LockThreads(); -// _bucketReadOffset = readBucketOffset; -// _bucketsRead = bucketsRead; -// self->ReleaseThreads(); -// } -// else -// self->WaitForRelease(); -// }); -// } - -// //----------------------------------------------------------- -// inline uint64 GetVirtualBucketLength( const uint32 bucket ) -// { -// const uint64 maxKEntries = ( 1ull << _k ); -// const uint64 maxBucketEntries = maxKEntries / _numBuckets; - -// // All buckets before the last bucket (and before the overflow bucket) have the same entry count which is 2^k / numBuckets -// if( bucket < _numBuckets - 1 ) -// return maxBucketEntries; - -// const uint64 tableEntryCount = _context->entryCounts[(int)_table]; - -// // Last, non-overflow bucket? -// if( bucket == _numBuckets - 1 ) -// return tableEntryCount > maxKEntries ? -// maxBucketEntries : -// maxBucketEntries - ( maxKEntries - tableEntryCount ); - -// // Last bucket -// return tableEntryCount > maxKEntries ? tableEntryCount - maxKEntries : 0; -// } - -// private: -// //----------------------------------------------------------- -// inline void* GetBucketBuffer( const uint32 bucket ) -// { -// return _loadBuffers[bucket & 3]; -// } - -// private: -// DiskPlotContext* _context = nullptr; -// TableId _table = TableId::Table1; -// FileId _fileId = FileId::None; -// uint32 _threadCount = 0; -// uint32 _bucketsLoaded = 0; -// uint32 _bucketsRead = 0; -// uint32 _bucketsUnpacked = 0; -// uint64 _bucketEntryOffset = 0; -// uint64 _bucketReadOffset = 0; // Entries that have actually bean read/unpacked in a bucket - -// TMap* _unpackdMaps[2]; -// void* _loadBuffers[4]; // We do double-buffering, but since a single load may go across bucket boundaries, we need 4. -// uint64 _bucketLengths[_numBuckets+1]; // Real, non-virtual bucket lengths. This is only necessary for buckets that have been pruned (ex. in Phase 3) -// }; #pragma GCC diagnostic pop diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index b33c325e..e256ea11 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -46,10 +46,10 @@ #define BB_DP_TABLE_COUNTS_FNAME "table_counts.tmp" #define BB_DP_DBG_PTR_BUCKET_COUNT_FNAME "ptr_bucket_count.tmp" -#define BB_DP_DBG_TEST_DIR "/mnt/p5510a/disk_dbg/" +#define BB_DP_DBG_TEST_DIR "/home/harold/plot/dbg/" #define BB_DP_DBG_REF_DIR "/mnt/p5510a/reference/" -// #define BB_DP_DBG_SKIP_PHASE_1 1 +#define BB_DP_DBG_SKIP_PHASE_1 1 // #define BB_DP_DBG_SKIP_PHASE_2 1 // Skip all of Phase 1 except the C tables writing. diff --git a/src/plotdisk/DiskPlotPhase2.cpp b/src/plotdisk/DiskPlotPhase2.cpp index 2196dc52..d924cbc7 100644 --- a/src/plotdisk/DiskPlotPhase2.cpp +++ b/src/plotdisk/DiskPlotPhase2.cpp @@ -4,7 +4,6 @@ #include "plotdisk/DiskPlotInfo.h" #include "util/StackAllocator.h" #include "DiskPlotInfo.h" -#include "plotdisk/DiskPairReader.h" // #DEBUG #include "jobs/IOJob.h" @@ -62,21 +61,36 @@ void DiskPlotPhase2::Run() return; #endif - switch( _context.numBuckets ) + if( _context.cfg->bounded ) { - case 128 : RunWithBuckets<128 >(); break; - case 256 : RunWithBuckets<256 >(); break; - case 512 : RunWithBuckets<512 >(); break; - case 1024: RunWithBuckets<1024>(); break; - - default: - ASSERT( 0 ); - break; + switch( _context.numBuckets ) + { + default: break; + case 64 : RunWithBuckets<64 , true>(); return; + case 128 : RunWithBuckets<128 , true>(); return; + case 256 : RunWithBuckets<256 , true>(); return; + case 512 : RunWithBuckets<512 , true>(); return; + } } + else + { + switch( _context.numBuckets ) + { + default: break; + case 128 : RunWithBuckets<128 , false>(); return; + case 256 : RunWithBuckets<256 , false>(); return; + case 512 : RunWithBuckets<512 , false>(); return; + case 1024: RunWithBuckets<1024, false>(); return; + + } + } + + // Should never get here. + Fatal( "Unexpected bucket count." ); } //----------------------------------------------------------- -template +template void DiskPlotPhase2::RunWithBuckets() { DiskPlotContext& context = _context; @@ -123,7 +137,7 @@ void DiskPlotPhase2::RunWithBuckets() const auto timer = TimerBegin(); const size_t stackMarker = allocator.Size(); - DiskPairAndMapReader<_numBuckets> reader( context, context.p2ThreadCount, readFence, table, allocator, table == TableId::Table7 ); + DiskPairAndMapReader<_numBuckets, _bounded> reader( context, context.p2ThreadCount, readFence, table, allocator, table == TableId::Table7 ); ASSERT( allocator.Size() < context.heapSize ); @@ -439,17 +453,17 @@ void DiskPlotPhase2::RunWithBuckets() } //----------------------------------------------------------- -template -void DiskPlotPhase2::MarkTable( const TableId rTable, DiskPairAndMapReader<_numBuckets> reader, +template +void DiskPlotPhase2::MarkTable( const TableId rTable, DiskPairAndMapReader<_numBuckets, _bounded> reader, Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ) { switch( rTable ) { - case TableId::Table7: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; - case TableId::Table6: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; - case TableId::Table5: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; - case TableId::Table4: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; - case TableId::Table3: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table7: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table6: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table5: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table4: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; + case TableId::Table3: MarkTableBuckets( reader, pairs, map, lTableMarks, rTableMarks ); break; default: ASSERT( 0 ); @@ -458,8 +472,8 @@ void DiskPlotPhase2::MarkTable( const TableId rTable, DiskPairAndMapReader<_numB } //----------------------------------------------------------- -template -void DiskPlotPhase2::MarkTableBuckets( DiskPairAndMapReader<_numBuckets> reader, +template +void DiskPlotPhase2::MarkTableBuckets( DiskPairAndMapReader<_numBuckets, _bounded> reader, Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ) { // Load initial bucket diff --git a/src/plotdisk/DiskPlotPhase2.h b/src/plotdisk/DiskPlotPhase2.h index e324cb10..b78a2ce3 100644 --- a/src/plotdisk/DiskPlotPhase2.h +++ b/src/plotdisk/DiskPlotPhase2.h @@ -1,12 +1,9 @@ #pragma once #include "plotdisk/DiskPlotContext.h" +#include "plotdisk/DiskPairReader.h" #include "util/BitField.h" - -template -struct DiskPairAndMapReader; - class DiskPlotPhase2 { public: @@ -16,15 +13,14 @@ class DiskPlotPhase2 void Run(); private: - - template + template void RunWithBuckets(); - template - void MarkTable( const TableId rTable, DiskPairAndMapReader<_numBuckets> reader, Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ); + template + void MarkTable( const TableId rTable, DiskPairAndMapReader<_numBuckets, _bounded> reader, Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ); - template - void MarkTableBuckets( DiskPairAndMapReader<_numBuckets> reader, Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ); + template + void MarkTableBuckets( DiskPairAndMapReader<_numBuckets, _bounded> reader, Pair* pairs, uint64* map, BitField lTableMarks, const BitField rTableMarks ); private: DiskPlotContext& _context; diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 8e8ee2e4..d5f56d96 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -16,6 +16,11 @@ size_t ValidateTmpPathAndGetBlockSize( DiskPlotter::Config& cfg ); +#if _DEBUG + void DbgWriteTableCounts( DiskPlotContext& cx ); + bool DbgReadTableCounts( DiskPlotContext& cx ); +#endif + //----------------------------------------------------------- // DiskPlotter::DiskPlotter() @@ -152,6 +157,10 @@ void DiskPlotter::Plot( const PlotRequest& req ) _cx.ioQueue->OpenPlotFile( req.plotFileName, req.plotId, req.plotMemo, req.plotMemoSize ); + #if ( _DEBUG && BB_DP_DBG_SKIP_PHASE_1 ) + DbgReadTableCounts( _cx ); + #endif + Log::Line( "Started plot." ); auto plotTimer = TimerBegin(); @@ -162,14 +171,22 @@ void DiskPlotter::Plot( const PlotRequest& req ) if( bounded ) { K32BoundedPhase1 phase1( _cx ); - phase1.Run(); + #if !( _DEBUG && BB_DP_DBG_SKIP_PHASE_1 ) + phase1.Run(); + #endif } else { DiskPlotPhase1 phase1( _cx ); - phase1.Run(); + #if !( _DEBUG && BB_DP_DBG_SKIP_PHASE_1 ) + phase1.Run(); + #endif } + #if !( _DEBUG && BB_DP_DBG_SKIP_PHASE_1 ) + DbgWriteTableCounts( _cx ); + #endif + const double elapsed = TimerEnd( timer ); Log::Line( "Finished Phase 1 in %.2lf seconds ( %.1lf minutes ).", elapsed, elapsed / 60 ); } @@ -178,11 +195,11 @@ void DiskPlotter::Plot( const PlotRequest& req ) Log::Line( "Running Phase 2" ); const auto timer = TimerBegin(); - if( bounded ) - { - Fatal( "Phase 2 bounded not implemented." ); - } - else + // if( bounded ) + // { + // Fatal( "Phase 2 bounded not implemented." ); + // } + // else { DiskPlotPhase2 phase2( _cx ); phase2.Run(); @@ -608,4 +625,93 @@ bladebit -t 8 -f ... -c ... diskplot -t2 /my/temporary/plot/dir -t2 /my/other/tm void DiskPlotter::PrintUsage() { Log::Line( USAGE ); -} \ No newline at end of file +} + + +#if _DEBUG + +//----------------------------------------------------------- +void DbgWriteTableCounts( DiskPlotContext& cx ) +{ + // Write bucket counts + FileStream bucketCounts, tableCounts, backPtrBucketCounts; + + if( bucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_READ_BUCKET_COUNT_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( bucketCounts.Write( cx.bucketCounts, sizeof( cx.bucketCounts ) ) != sizeof( cx.bucketCounts ) ) + Log::Error( "Failed to write to bucket counts file." ); + } + else + Log::Error( "Failed to open bucket counts file." ); + + if( tableCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_TABLE_COUNTS_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( tableCounts.Write( cx.entryCounts, sizeof( cx.entryCounts ) ) != sizeof( cx.entryCounts ) ) + Log::Error( "Failed to write to table counts file." ); + } + else + Log::Error( "Failed to open table counts file." ); + + if( backPtrBucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_PTR_BUCKET_COUNT_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( backPtrBucketCounts.Write( cx.ptrTableBucketCounts, sizeof( cx.ptrTableBucketCounts ) ) != sizeof( cx.ptrTableBucketCounts ) ) + Log::Error( "Failed to write to back pointer bucket counts file." ); + } + else + Log::Error( "Failed to open back pointer bucket counts file." ); +} + +//----------------------------------------------------------- +bool DbgReadTableCounts( DiskPlotContext& cx ) +{ + #if( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) + + FileStream bucketCounts, tableCounts, backPtrBucketCounts; + + if( bucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_READ_BUCKET_COUNT_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( bucketCounts.Read( cx.bucketCounts, sizeof( cx.bucketCounts ) ) != sizeof( cx.bucketCounts ) ) + { + Log::Error( "Failed to read from bucket counts file." ); + return false; + } + } + else + { + Log::Error( "Failed to open bucket counts file." ); + return false; + } + + if( tableCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_TABLE_COUNTS_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( tableCounts.Read( cx.entryCounts, sizeof( cx.entryCounts ) ) != sizeof( cx.entryCounts ) ) + { + Log::Error( "Failed to read from table counts file." ); + return false; + } + } + else + { + Log::Error( "Failed to open table counts file." ); + return false; + } + + if( backPtrBucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_PTR_BUCKET_COUNT_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( backPtrBucketCounts.Read( cx.ptrTableBucketCounts, sizeof( cx.ptrTableBucketCounts ) ) != sizeof( cx.ptrTableBucketCounts ) ) + { + Fatal( "Failed to read from pointer bucket counts file." ); + } + } + else + { + Fatal( "Failed to open pointer bucket counts file." ); + } + + return true; + #else + return false; + #endif +} + +#endif // End #_DEBUG \ No newline at end of file diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 476ed6f4..7a008fe5 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -156,8 +156,6 @@ void K32BoundedPhase1::RunF1() K32BoundedF1<_numBuckets> f1( _context, allocator ); f1.Run(); - _context.entryCounts[(int)TableId::Table1] = 1ull << 32; - double elapsed = TimerEnd( timer ); Log::Line( "Finished f1 generation in %.2lf seconds. ", elapsed ); Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _context.ioQueue->IOBufferWaitTime() ); @@ -188,7 +186,7 @@ void K32BoundedPhase1::RunFx() #if BB_DP_FP_MATCH_X_BUCKET _allocator.PopToMarker( _xBucketStackMarker ); #endif - + DiskPlotFxBounded fx( _context ); fx.Run( _allocator #if BB_DP_FP_MATCH_X_BUCKET diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index cfb8af63..972124be 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -94,6 +94,18 @@ public: _ioQueue.CommitCommands(); fence.Wait( 1 ); + _context.entryCounts[(int)TableId::Table1] = 1ull << _k; + + #if _DEBUG + { + uint64 tableEntryCount = 0; + for( uint32 i = 0; i < _numBuckets; i++ ) + tableEntryCount += _context.bucketCounts[(int)TableId::Table1][i]; + + ASSERT( tableEntryCount == _context.entryCounts[(int)TableId::Table1] ); + } + #endif + _context.fencePool->RestoreAllFences(); } @@ -161,7 +173,7 @@ private: _ioQueue.CommitCommands(); for( uint32 i = 0; i < _numBuckets; i++ ) - _context.bucketCounts[(int)TableId::Table1][i] += totalCounts[i]; + _context.bucketCounts[(int)TableId::Table1][i] += elementCounts[i]; } self->EndLockBlock(); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 31aadc35..c616581c 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -135,14 +135,16 @@ class DiskPlotFxBounded { using TMetaIn = typename K32MetaType::In; using TMetaOut = typename K32MetaType::Out; + using TYOut = typename K32TYOut::Type; using Job = AnonPrefixSumJob; static constexpr uint32 _k = 32; static constexpr uint64 _maxTableEntries = (1ull << _k) - 1; static constexpr uint32 _bucketBits = bblog2( _numBuckets ); static constexpr uint32 _pairsMaxDelta = 512; + static constexpr uint32 _pairsLeftBits = _k - _bucketBits; static constexpr uint32 _pairsRightBits = bblog2( _pairsMaxDelta ); - static constexpr uint32 _pairBitSize = _k - _bucketBits + _pairsRightBits; + static constexpr uint32 _pairBitSize = _pairsLeftBits + _pairsRightBits; public: //----------------------------------------------------------- @@ -319,6 +321,16 @@ public: }); _context.entryCounts[(int)rTable] = _tableEntryCount; + + #if _DEBUG + { + uint64 tableEntryCount = 0; + for( uint32 i = 0; i < _numBuckets; i++ ) + tableEntryCount += _context.bucketCounts[(int)rTable][i]; + + ASSERT( tableEntryCount == _tableEntryCount ); + } + #endif Log::Line( " Sorting : Completed in %.2lf seconds.", TicksToSeconds( _sortTime ) ); Log::Line( " Distribution : Completed in %.2lf seconds.", TicksToSeconds( _distributeTime ) ); @@ -438,7 +450,6 @@ private: SortOnYKey( self, sortKey, metaTmp, metaIn ); // SaveCrossBucketMetadata( self, metaIn ); - // On Table 2, metadata is our x values, which have to be saved as table 1 if constexpr ( rTable == TableId::Table2 ) @@ -459,7 +470,7 @@ private: /// Gen fx & write { - Span yOut = _yTmp.Slice( matchOffset, matches.Length() ); + Span yOut = _yTmp.As().Slice( matchOffset, matches.Length() ); Span metaOut = _metaTmp[1].As().Slice( matchOffset, matches.Length() ); //( (TMetaOut*)metaTmp.Ptr(), matches.Length() ); TimePoint timer; @@ -496,6 +507,9 @@ private: { _tableEntryCount += totalMatches; _mapOffset += entryCount; + + // Save bucket length before y-sort since the pairs remain unsorted + _context.ptrTableBucketCounts[(int)rTable][bucket] = (uint32)totalMatches; } } } @@ -697,6 +711,10 @@ private: if( self->BeginLockBlock() ) { _pairBitWriter.Submit(); + + if( bucket == _numBuckets-1 ) + _pairBitWriter.SubmitLeftOvers(); + _ioQueue.SignalFence( _pairWriteFence, bucket + 1 ); _ioQueue.CommitCommands(); } @@ -708,7 +726,7 @@ private: { self; - const uint32 shift = _pairsRightBits; + const uint32 shift = _pairsLeftBits; const uint64 mask = ( 1ull << shift ) - 1; const Pair* pair = pairs.Ptr(); @@ -733,6 +751,8 @@ private: _mapWriter.WriteJob( self, bucket, tableOffset, bucketIndices, mapOut, outMapBucketCounts, totalCounts, _mapBitCounts ); + if( bucket == _numBuckets-1 && self->IsControlThread() ) + _mapWriter.SubmitFinalBits(); /// /// #TODO: Fix and re-enabled Un-compressed method?: /// @@ -803,7 +823,7 @@ private: void WriteEntries( Job* self, const uint32 bucket, const uint32 idxOffset, - const Span yIn, + const Span yIn, const Span metaIn, Span yOut, Span metaOut, @@ -820,7 +840,7 @@ private: const uint32 logBuckets = bblog2( _numBuckets ); static_assert( kExtraBits <= logBuckets ); - const uint32 bucketShift = _k + kExtraBits - logBuckets; + const uint32 bucketShift = ( std::is_same::value ? _k : _k + kExtraBits ) - logBuckets; const uint64 yMask = ( 1ull << bucketShift ) - 1; const int64 entryCount = (int64)yIn.Length(); @@ -834,14 +854,14 @@ private: Span ySliceCounts = _sliceCountY[sliceIdx]; Span metaSliceCounts = _sliceCountMeta[sliceIdx]; Span yAlignedSliceCount = _alignedSliceCountY[sliceIdx]; - Span metaAlignedsliceCount = _alignedsliceCountMeta[sliceIdx]; + Span metaAlignedSliceCount = _alignedsliceCountMeta[sliceIdx]; // Count for( int64 i = 0; i < entryCount; i++ ) counts[yIn[i] >> bucketShift]++; self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, ySliceCounts.Ptr(), _offsetsY[id], yAlignedSliceCount.Ptr() ); - self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaSliceCounts.Ptr(), _offsetsMeta[id], metaAlignedsliceCount.Ptr() ); + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaSliceCounts.Ptr(), _offsetsMeta[id], metaAlignedSliceCount.Ptr() ); // Distribute to buckets for( int64 i = 0; i < entryCount; i++ ) @@ -867,11 +887,17 @@ private: const FileId metaId = _metaId[1]; const FileId idxId = _idxId [1]; + ASSERT( ySliceCounts.Length() == metaSliceCounts.Length() ); + _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); _ioQueue.WriteBucketElementsT ( idxId , idxOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); - _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), metaAlignedsliceCount.Ptr(), metaSliceCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), metaAlignedSliceCount.Ptr(), metaSliceCounts.Ptr() ); // #TODO: Can use ySliceCounts here... _ioQueue.SignalFence( _fxWriteFence, bucket+1 ); _ioQueue.CommitCommands(); + + // Save bucket counts + for( uint32 i = 0; i < _numBuckets; i++ ) + _context.bucketCounts[(int)rTable][i] += ySliceCounts[i]; } self->EndLockBlock(); @@ -881,17 +907,6 @@ private: } //----------------------------------------------------------- - template - void GenCrossBucketFx( - Job* self, - const uint32 bucket - ) - { - - } - - //----------------------------------------------------------- - template void GenFx( Job* self, const uint32 bucket, const Span pairs, From bd8c0d3891c09fc119a17cb12e619c8f792812ca Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 15 Jun 2022 04:12:58 -0500 Subject: [PATCH 37/91] Attempting to hook-in phase 3. Initial x values are coming off wrong. Investigating Phase1 suggest that this happens after sorting on y, not sure of the reason yet. --- src/platform/unix/FileStream_Unix.cpp | 2 +- src/plotdisk/DiskPlotConfig.h | 2 +- src/plotdisk/DiskPlotPhase3.cpp | 54 ++++++++++++++++++--------- src/plotdisk/DiskPlotPhase3.h | 8 +--- src/plotdisk/DiskPlotter.cpp | 10 ++--- src/plotdisk/k32/FxBounded.inl | 36 ++++++++++++++++-- 6 files changed, 77 insertions(+), 35 deletions(-) diff --git a/src/platform/unix/FileStream_Unix.cpp b/src/platform/unix/FileStream_Unix.cpp index 2e0bf9d2..992bfd71 100644 --- a/src/platform/unix/FileStream_Unix.cpp +++ b/src/platform/unix/FileStream_Unix.cpp @@ -40,7 +40,7 @@ bool FileStream::Open( const char* path, FileStream& file, FileMode mode, FileAc fdFlags |= O_LARGEFILE; #endif - if( mode == FileMode::Create ) + if( fdFlags & O_CREAT ) fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; int fd = open( path, fdFlags, fmode ); diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index e256ea11..4d5bbf2e 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -49,7 +49,7 @@ #define BB_DP_DBG_TEST_DIR "/home/harold/plot/dbg/" #define BB_DP_DBG_REF_DIR "/mnt/p5510a/reference/" -#define BB_DP_DBG_SKIP_PHASE_1 1 +// #define BB_DP_DBG_SKIP_PHASE_1 1 // #define BB_DP_DBG_SKIP_PHASE_2 1 // Skip all of Phase 1 except the C tables writing. diff --git a/src/plotdisk/DiskPlotPhase3.cpp b/src/plotdisk/DiskPlotPhase3.cpp index 282949de..f0f90b8c 100644 --- a/src/plotdisk/DiskPlotPhase3.cpp +++ b/src/plotdisk/DiskPlotPhase3.cpp @@ -118,7 +118,7 @@ class EntrySort }; -template +template class P3StepOne { public: @@ -164,7 +164,7 @@ class P3StepOne void* rMarks = allocator.Alloc( rMarksSize, context.tmp1BlockSize ); - DiskPairAndMapReader<_numBuckets> rTableReader( context, _threadCount, _readFence, rTable, allocator, false ); + DiskPairAndMapReader<_numBuckets, _bounded> rTableReader( context, _threadCount, _readFence, rTable, allocator, false ); using L1Reader = SingleFileMapReader<_numBuckets, P3_EXTRA_L_ENTRIES_TO_LOAD, uint32>; using LNReader = DiskMapReader; @@ -383,8 +383,7 @@ class P3StepOne const uint64 x = lTable[p.left ]; const uint64 y = lTable[p.right]; - ASSERT( x || y ); - outLinePoints[i] = SquareToLinePoint( x, y ); + ASSERT( x || y ); outLinePoints[i] = SquareToLinePoint( x, y ); } } }); @@ -909,6 +908,7 @@ void DiskPlotPhase3::Run() switch( _context.numBuckets ) { + case 64 : RunBuckets<64 >(); break; case 128 : RunBuckets<128 >(); break; case 256 : RunBuckets<256 >(); break; case 512 : RunBuckets<512 >(); break; @@ -935,6 +935,7 @@ void DiskPlotPhase3::GetCacheSizes( size_t& outCacheSizeLP, size_t& outCacheSize { switch( _context.numBuckets ) { + case 64 : GetCacheSizesForBuckets<128 >( outCacheSizeLP, outCacheSizeMap ); break; case 128 : GetCacheSizesForBuckets<128 >( outCacheSizeLP, outCacheSizeMap ); break; case 256 : GetCacheSizesForBuckets<256 >( outCacheSizeLP, outCacheSizeMap ); break; case 512 : GetCacheSizesForBuckets<512 >( outCacheSizeLP, outCacheSizeMap ); break; @@ -950,7 +951,7 @@ void DiskPlotPhase3::GetCacheSizes( size_t& outCacheSizeLP, size_t& outCacheSize template void DiskPlotPhase3::GetCacheSizesForBuckets( size_t& outCacheSizeLP, size_t& outCacheSizeMap ) { - const size_t lpEntrySize = P3StepOne::_entrySizeBits; + const size_t lpEntrySize = P3StepOne::_entrySizeBits; const size_t mapEntrySizeX2 = MapWriter<_numBuckets, true>::EntryBitSize * 2; static_assert( mapEntrySizeX2 >= lpEntrySize ); @@ -990,17 +991,36 @@ void DiskPlotPhase3::RunBuckets() { Log::Line( "Compressing tables %u and %u.", rTable, rTable+1 ); const auto timer = TimerBegin(); - switch( rTable ) + + if( _context.cfg->bounded ) { - case TableId::Table2: ProcessTable(); break; - case TableId::Table3: ProcessTable(); break; - case TableId::Table4: ProcessTable(); break; - case TableId::Table5: ProcessTable(); break; - case TableId::Table6: ProcessTable(); break; - case TableId::Table7: ProcessTable(); break; - default: - ASSERT( 0 ); - break; + switch( rTable ) + { + case TableId::Table2: ProcessTable(); break; + case TableId::Table3: ProcessTable(); break; + case TableId::Table4: ProcessTable(); break; + case TableId::Table5: ProcessTable(); break; + case TableId::Table6: ProcessTable(); break; + case TableId::Table7: ProcessTable(); break; + default: + ASSERT( 0 ); + break; + } + } + else + { + switch( rTable ) + { + case TableId::Table2: ProcessTable(); break; + case TableId::Table3: ProcessTable(); break; + case TableId::Table4: ProcessTable(); break; + case TableId::Table5: ProcessTable(); break; + case TableId::Table6: ProcessTable(); break; + case TableId::Table7: ProcessTable(); break; + default: + ASSERT( 0 ); + break; + } } const double elapsed = TimerEnd( timer ); @@ -1030,7 +1050,7 @@ void DiskPlotPhase3::RunBuckets() } //----------------------------------------------------------- -template +template void DiskPlotPhase3::ProcessTable() { uint64 prunedEntryCount; @@ -1041,7 +1061,7 @@ void DiskPlotPhase3::ProcessTable() { memset( _lpPrunedBucketCounts, 0, sizeof( uint64 ) * (_numBuckets+1) ); - P3StepOne stepOne( _context, _mapReadId, _readFence, _writeFence ); + P3StepOne stepOne( _context, _mapReadId, _readFence, _writeFence ); prunedEntryCount = stepOne.Run( _lMapPrunedBucketCounts, _lpPrunedBucketCounts ); _ioWaitTime = stepOne.GetIOWaitTime(); diff --git a/src/plotdisk/DiskPlotPhase3.h b/src/plotdisk/DiskPlotPhase3.h index 43f5dc06..0f60f640 100644 --- a/src/plotdisk/DiskPlotPhase3.h +++ b/src/plotdisk/DiskPlotPhase3.h @@ -17,15 +17,9 @@ class DiskPlotPhase3 template void RunBuckets(); - template + template void ProcessTable(); - template - void TableFirstStep(); - - template - void TableSecondStep(); - template void ConvertToLinePoints( const uint32 bucket, const int64 bucketLength, const uint32* leftEntries, diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index d5f56d96..d030ebab 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -213,11 +213,11 @@ void DiskPlotter::Plot( const PlotRequest& req ) Log::Line( "Running Phase 3" ); const auto timer = TimerBegin(); - if( bounded ) - { - Fatal( "Phase 3 bounded not implemented." ); - } - else + // if( bounded ) + // { + // Fatal( "Phase 3 bounded not implemented." ); + // } + // else { DiskPlotPhase3 phase3( _cx ); phase3.Run(); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index c616581c..e32139d8 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -447,6 +447,27 @@ private: } WaitForFence( self, _metaReadFence, bucket ); + #if _DEBUG + if constexpr ( rTable == TableId::Table2 ) + { + if( self->BeginLockBlock() ) + { + uint32 zeroCount = 0; + for( uint32 i = 0; i < entryCount; i++ ) + { + if( metaTmp[i] == 0 ) + zeroCount++; + } + Log::Line( "Meta zeroes: %u, %u : %u", zeroCount, entryCount, entryCount - zeroCount ); + + // std::sort( sortKey.Ptr(), sortKey.Ptr() + sortKey.Length() ); + // for( uint32 i = 0; i < entryCount; i++ ) + // ASSERT( sortKey[i] == i ); + // Log::Line( "Sort key is ok." ); + } + self->EndLockBlock(); + } + #endif SortOnYKey( self, sortKey, metaTmp, metaIn ); // SaveCrossBucketMetadata( self, metaIn ); @@ -461,6 +482,13 @@ private: _dbgPlot.WriteYX( bucket, yInput, metaIn ); #endif +#if _DEBUG + uint32 zeroCount = 0; + for( uint32 i = 0; i < entryCount; i++ ) + if( metaIn[i] == 0 ) + zeroCount++; + Log::Line( "Meta zeroes: %u, %u : %u", zeroCount, entryCount, entryCount - zeroCount ); +#endif _xWriter.SubmitBuffer( _ioQueue, entryCount ); if( bucket == _numBuckets - 1 ) _xWriter.SubmitFinalBlock( _ioQueue ); @@ -583,6 +611,8 @@ private: template void SortOnYKey( Job* self, const Span key, const Span input, Span output ) { + ASSERT( key.Length() == input.Length() && input.Length() == output.Length() ); + TimePoint timer; if( self->IsControlThread() ) timer = TimerBegin(); @@ -593,11 +623,9 @@ private: for( uint32 i = offset; i < end; i++ ) output[i] = input[key[i]]; - - self->SyncThreads(); - - if( self->IsControlThread() ) + if( self->BeginLockBlock() ) _sortTime += TimerEndTicks( timer ); + self->EndLockBlock(); } //----------------------------------------------------------- From 154231f40722c3a34e876df597d57761f96a0de5 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 16 Jun 2022 03:39:34 -0500 Subject: [PATCH 38/91] Trying to fix various bugs throughout f1, fx --- .vscode/launch.json | 3 ++- src/plotdisk/DiskPlotConfig.h | 2 +- src/plotdisk/DiskPlotter.cpp | 5 +++- src/plotdisk/MapWriter.h | 29 +++++++++++---------- src/plotdisk/k32/DiskPlotBounded.cpp | 24 ++++++++++++++++++ src/plotdisk/k32/F1Bounded.inl | 12 ++++----- src/plotdisk/k32/FxBounded.inl | 38 ++++++---------------------- 7 files changed, 61 insertions(+), 52 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 0a8eb824..c3c1540f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -88,11 +88,12 @@ // "--cache", "200G", // "--cache", "96G", // "--cache", "106G", - // "--cache", "64G", + "--cache", "64G", // "-s", "--k32-bounded", "-b", "64", // "-b", "128", + // "-b", "256", "--c-threads", "26", "--p2-threads", "24", diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 4d5bbf2e..0430aa60 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -71,7 +71,7 @@ // #define BB_DBG_SKIP_P3_S1 1 // #define BB_DP_DBG_P3_START_TABLE Table7 - // #define BB_DP_DBG_P3_KEEP_FILES 1 + #define BB_DP_DBG_P3_KEEP_FILES 1 #endif #define BB_DP_FP_MATCH_X_BUCKET 1 diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index d030ebab..73f5a6f0 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -56,7 +56,10 @@ DiskPlotter::DiskPlotter( const Config& cfg ) _cx.p2ThreadCount = cfg.p2ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.p2ThreadCount, sysLogicalCoreCount ); _cx.p3ThreadCount = cfg.p3ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.p3ThreadCount, sysLogicalCoreCount ); - const size_t heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize, _cx.fpThreadCount ); + const size_t heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize, _cx.fpThreadCount ) + // #TODO: Remove, testing for now + + 6ull GB + ; ASSERT( heapSize ); _cfg = cfg; diff --git a/src/plotdisk/MapWriter.h b/src/plotdisk/MapWriter.h index fb5402e9..d0d0da9c 100644 --- a/src/plotdisk/MapWriter.h +++ b/src/plotdisk/MapWriter.h @@ -162,20 +162,23 @@ class MapWriter self->SyncThreads(); if( self->IsControlThread() ) { - const uint32 overflowBucket = _numBuckets; - const uint64 overflowCount = totalCounts[overflowBucket]; - - if( overflowCount ) + if constexpr ( _overflow ) { - const uint64 writeOffset = pfxSum[overflowBucket]; - ASSERT( writeOffset * bitSize - bitsWritten == 0 ); - - BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); - - const uint64* mapToWrite = outMapBuckets + writeOffset; - const uint64* mapWriteEnd = mapToWrite + overflowCount; - while( mapToWrite < mapWriteEnd ) - writer.Write( *mapToWrite++, bitSize ); + const uint32 overflowBucket = _numBuckets; + const uint64 overflowCount = totalCounts[overflowBucket]; + + if( overflowCount ) + { + const uint64 writeOffset = pfxSum[overflowBucket]; + ASSERT( writeOffset * bitSize - bitsWritten == 0 ); + + BitWriter writer = bitWriter.GetWriter( overflowBucket, 0 ); + + const uint64* mapToWrite = outMapBuckets + writeOffset; + const uint64* mapWriteEnd = mapToWrite + overflowCount; + while( mapToWrite < mapWriteEnd ) + writer.Write( *mapToWrite++, bitSize ); + } } bitWriter.Submit(); diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 7a008fe5..ef254629 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -49,11 +49,25 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) FileSetInitData data = {}; opts |= FileSetOptions::UseTemp2; + // if( context.cache ) + // { + // // #TODO: Divide cache evenly. For now just set it to fx0 + // opts |= FileSetOptions::Cachable; + // data.cacheSize = context.cacheSize / 2; + // data.cache = context.cache; + // } + _ioQueue.InitFileSet( FileId::FX0 , "y0" , numBuckets, opts, &data ); + // UnSetFlag( opts, FileSetOptions::Cachable ); _ioQueue.InitFileSet( FileId::FX1 , "y1" , numBuckets, opts, &data ); _ioQueue.InitFileSet( FileId::INDEX0, "index0", numBuckets, opts, &data ); _ioQueue.InitFileSet( FileId::INDEX1, "index1", numBuckets, opts, &data ); + + // opts |= FileSetOptions::Cachable; + // data.cache = ((byte*)data.cache) + data.cacheSize; _ioQueue.InitFileSet( FileId::META0 , "meta0" , numBuckets, opts, &data ); + // UnSetFlag( opts, FileSetOptions::Cachable ); + _ioQueue.InitFileSet( FileId::META1 , "meta1" , numBuckets, opts, &data ); } } @@ -116,7 +130,17 @@ void K32BoundedPhase1::RunWithBuckets() startTable = BB_DP_P1_START_TABLE; } #else + // #TODO: TEST, remove + for( ;; ) + { + Log::Line( "Running F1..." ); RunF1<_numBuckets>(); + _ioQueue.SeekBucket( FileId::FX0, 0, SeekOrigin::Begin ); + _ioQueue.SeekBucket( FileId::META0, 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); + memset( _context.bucketCounts[0], 0, sizeof( _context.bucketCounts[0] ) ); + _context.entryCounts[0] = 0; + } #endif #if BB_DP_FP_MATCH_X_BUCKET diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 972124be..bcbc8b20 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -27,6 +27,8 @@ public: , _ioQueue ( *context.ioQueue ) , _writeFence( context.fencePool->RequireFence() ) { + static_assert( (uint64)_blocksPerBucket * _entriesPerBlock * _numBuckets == _kEntryCount ); + const uint32 threadCount = context.f1ThreadCount; // We need to pad our slices to block size @@ -40,11 +42,13 @@ public: #endif - // Get the maximum block count per thread + // Get the maximum block count per thread (use the last thread id to get the maximum) uint32 blockCount, _; GetThreadOffsets( threadCount-1, threadCount, _blocksPerBucket, blockCount, _, _ ); const uint32 blockBufferSize = blockCount * threadCount * _entriesPerBlock; + ASSERT( blockCount * threadCount >= _blocksPerBucket ); + _blockBuffer = allocator.CAllocSpan( blockBufferSize ); _yEntries[0] = allocator.CAllocSpan( entriesPerBucketAligned, context.tmp2BlockSize ); @@ -96,7 +100,7 @@ public: _context.entryCounts[(int)TableId::Table1] = 1ull << _k; - #if _DEBUG + #if _DEBUG { uint64 tableEntryCount = 0; for( uint32 i = 0; i < _numBuckets; i++ ) @@ -176,10 +180,6 @@ private: _context.bucketCounts[(int)TableId::Table1][i] += elementCounts[i]; } self->EndLockBlock(); - - // #NOTE: Somehow we're not getting synced here... So sync explicitly again - // #NOTE2: The issue is still happening even with this sync. - self->SyncThreads(); } //----------------------------------------------------------- diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index e32139d8..d763255a 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -106,6 +106,7 @@ static DebugPlot _dbgPlot; void DbgValidatePlot( const DebugPlot& dbgPlot ); #endif + #endif @@ -441,33 +442,16 @@ private: if constexpr ( rTable == TableId::Table2 ) { // #TODO: Simplify this by not making use of the block writer's buffers? + // Set shared x buffer for other threads if( self->BeginLockBlock() ) - metaIn = Span( _xWriter.GetNextBuffer( _tableIOWait ), entryCount ); + _xWriteBuffer = Span( _xWriter.GetNextBuffer( _tableIOWait ), entryCount ); self->EndLockBlock(); + + // Grap shared buffer + metaIn = _xWriteBuffer; } WaitForFence( self, _metaReadFence, bucket ); - #if _DEBUG - if constexpr ( rTable == TableId::Table2 ) - { - if( self->BeginLockBlock() ) - { - uint32 zeroCount = 0; - for( uint32 i = 0; i < entryCount; i++ ) - { - if( metaTmp[i] == 0 ) - zeroCount++; - } - Log::Line( "Meta zeroes: %u, %u : %u", zeroCount, entryCount, entryCount - zeroCount ); - - // std::sort( sortKey.Ptr(), sortKey.Ptr() + sortKey.Length() ); - // for( uint32 i = 0; i < entryCount; i++ ) - // ASSERT( sortKey[i] == i ); - // Log::Line( "Sort key is ok." ); - } - self->EndLockBlock(); - } - #endif SortOnYKey( self, sortKey, metaTmp, metaIn ); // SaveCrossBucketMetadata( self, metaIn ); @@ -482,13 +466,6 @@ private: _dbgPlot.WriteYX( bucket, yInput, metaIn ); #endif -#if _DEBUG - uint32 zeroCount = 0; - for( uint32 i = 0; i < entryCount; i++ ) - if( metaIn[i] == 0 ) - zeroCount++; - Log::Line( "Meta zeroes: %u, %u : %u", zeroCount, entryCount, entryCount - zeroCount ); -#endif _xWriter.SubmitBuffer( _ioQueue, entryCount ); if( bucket == _numBuckets - 1 ) _xWriter.SubmitFinalBlock( _ioQueue ); @@ -1212,7 +1189,8 @@ private: Span _metaWriteBuffer; Span _mapWriteBuffer; byte* _pairsWriteBuffer; - BlockWriter _xWriter; // Used for Table2 (there's no map, but just x.) + BlockWriter _xWriter; // Used for Table2 (there's no map, but just x.) + Span _xWriteBuffer; // Set by the control thread for other threads to use // Working buffers Span _yTmp; From c3ee929c5ef7da60acbd80cd4c0d38f4e11a0103 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 16 Jun 2022 03:56:11 -0500 Subject: [PATCH 39/91] Quick debug fix --- src/plotdisk/DiskPlotter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 73f5a6f0..d9392ac0 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -186,7 +186,7 @@ void DiskPlotter::Plot( const PlotRequest& req ) #endif } - #if !( _DEBUG && BB_DP_DBG_SKIP_PHASE_1 ) + #if ( _DEBUG && !BB_DP_DBG_SKIP_PHASE_1 ) DbgWriteTableCounts( _cx ); #endif From fc9cabf4cd3b589f0eac78bd38feb2a03dbc0dec Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 16 Jun 2022 04:06:47 -0500 Subject: [PATCH 40/91] Removing f1 test stuff --- src/plotdisk/k32/DiskPlotBounded.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index ef254629..c0ebb30d 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -131,15 +131,15 @@ void K32BoundedPhase1::RunWithBuckets() } #else // #TODO: TEST, remove - for( ;; ) + // for( ;; ) { - Log::Line( "Running F1..." ); + // Log::Line( "Running F1..." ); RunF1<_numBuckets>(); - _ioQueue.SeekBucket( FileId::FX0, 0, SeekOrigin::Begin ); - _ioQueue.SeekBucket( FileId::META0, 0, SeekOrigin::Begin ); - _ioQueue.CommitCommands(); - memset( _context.bucketCounts[0], 0, sizeof( _context.bucketCounts[0] ) ); - _context.entryCounts[0] = 0; + // _ioQueue.SeekBucket( FileId::FX0, 0, SeekOrigin::Begin ); + // _ioQueue.SeekBucket( FileId::META0, 0, SeekOrigin::Begin ); + // _ioQueue.CommitCommands(); + // memset( _context.bucketCounts[0], 0, sizeof( _context.bucketCounts[0] ) ); + // _context.entryCounts[0] = 0; } #endif From 79b4aaedda39f6174191e351e2ff4f57128b3153 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 16 Jun 2022 06:48:11 -0500 Subject: [PATCH 41/91] f1 is validating. Fx is yielding bad map serializations on 256 buckets. --- .vscode/launch.json | 6 +- src/plotdisk/DiskPlotConfig.h | 2 +- src/plotdisk/DiskPlotDebug.h | 14 +++- src/plotdisk/DiskPlotPhase1.cpp | 18 ++--- src/plotdisk/k32/F1Bounded.inl | 136 ++++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 14 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c3c1540f..dd2d391f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -88,12 +88,12 @@ // "--cache", "200G", // "--cache", "96G", // "--cache", "106G", - "--cache", "64G", + // "--cache", "64G", // "-s", "--k32-bounded", - "-b", "64", + // "-b", "64", // "-b", "128", - // "-b", "256", + "-b", "256", "--c-threads", "26", "--p2-threads", "24", diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 0430aa60..d01accf3 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -47,7 +47,7 @@ #define BB_DP_DBG_PTR_BUCKET_COUNT_FNAME "ptr_bucket_count.tmp" #define BB_DP_DBG_TEST_DIR "/home/harold/plot/dbg/" -#define BB_DP_DBG_REF_DIR "/mnt/p5510a/reference/" +#define BB_DP_DBG_REF_DIR "/home/harold/plot/ref/" // #define BB_DP_DBG_SKIP_PHASE_1 1 // #define BB_DP_DBG_SKIP_PHASE_2 1 diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index d12ef3d1..2b50bb4b 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -38,6 +38,9 @@ namespace Debug template bool LoadRefTableByName( const char* fileName, T*& buffer, uint64& outEntryCount ); + template + bool LoadRefTableByName( const char* fileName, Span& buffer ); + void LoadRefLinePointTable( const TableId table, uint64*& buffer, uint64& outEntryCount ); void LoadRefLPIndexTable( const TableId table, uint32*& buffer, uint64& outEntryCount ); @@ -227,12 +230,21 @@ inline void Debug::ValidateYForTable( const FileId fileId, DiskBufferQueue& queu template inline bool Debug::LoadRefTableByName( const char* fileName, T*& buffer, uint64& outEntryCount ) { + ASSERT( fileName ); + char path[1024]; sprintf( path, "%s%s", BB_DP_DBG_REF_DIR, fileName ); - Log::Line( " Loading reference line point table '%s'.", path ); + Log::Line( " Loading reference table '%s'.", path ); return LoadRefTable( path, buffer, outEntryCount ); } +//----------------------------------------------------------- +template +inline bool Debug::LoadRefTableByName( const char* fileName, Span& buffer ) +{ + return LoadRefTableByName( fileName, buffer.values, buffer.length ); +} + //----------------------------------------------------------- template inline bool Debug::LoadRefTable( const char* path, T*& buffer, uint64& outEntryCount ) diff --git a/src/plotdisk/DiskPlotPhase1.cpp b/src/plotdisk/DiskPlotPhase1.cpp index 4a195d4a..96def02f 100644 --- a/src/plotdisk/DiskPlotPhase1.cpp +++ b/src/plotdisk/DiskPlotPhase1.cpp @@ -160,17 +160,17 @@ void DiskPlotPhase1::Run() #endif #if _DEBUG && BB_DP_DBG_VALIDATE_F1 - // if( 0 ) - { - const uint32* bucketCounts = _cx.bucketCounts[0]; - uint64 totalEntries = 0; - for( uint i = 0; i < BB_DP_BUCKET_COUNT; i++ ) - totalEntries += bucketCounts[i]; + // if constexpr ( 0 ) + // { + // const uint32* bucketCounts = _cx.bucketCounts[0]; + // uint64 totalEntries = 0; + // for( uint i = 0; i < BB_DP_BUCKET_COUNT; i++ ) + // totalEntries += bucketCounts[i]; - ASSERT( totalEntries == 1ull << _K ); + // ASSERT( totalEntries == 1ull << _K ); - Debug::ValidateYFileFromBuckets( FileId::Y0, *_cx.threadPool, *_diskQueue, TableId::Table1, _cx.bucketCounts[0] ); - } + // Debug::ValidateYFileFromBuckets( FileId::Y0, *_cx.threadPool, *_diskQueue, TableId::Table1, _cx.bucketCounts[0] ); + // } #endif #if _DEBUG && BB_DP_P1_SKIP_TO_TABLE diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index bcbc8b20..25b9005a 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -8,6 +8,13 @@ #include "plotdisk/DiskPlotConfig.h" #include "plotdisk/DiskBufferQueue.h" +#if _DEBUG + #include "plotdisk/DiskPlotDebug.h" + #include "algorithm/RadixSort.h" + void DbgValidateF1( DiskPlotContext& context ); +#endif + + template class K32BoundedF1 { @@ -111,6 +118,10 @@ public: #endif _context.fencePool->RestoreAllFences(); + + #if ( _DEBUG && BB_DP_DBG_VALIDATE_F1 ) + DbgValidateF1( _context ); + #endif } private: @@ -220,3 +231,128 @@ private: #endif }; + +#if _DEBUG + +//----------------------------------------------------------- +void DbgValidateF1( DiskPlotContext& context ) +{ + Log::Line( "[DEBUG: Validating y and x]" ); + + auto& ioQueue = *context.ioQueue; + ioQueue.SeekBucket( FileId::FX0, 0, SeekOrigin::Begin ); + ioQueue.SeekBucket( FileId::META0, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); + + const uint64 entryCount = context.entryCounts[(int)TableId::Table1]; + + Span yReference = bbcvirtallocboundednuma_span( entryCount ); + Span xReference = bbcvirtallocboundednuma_span( entryCount ); + Span yBuffer = bbcvirtallocboundednuma_span( entryCount ); + Span xBuffer = bbcvirtallocboundednuma_span( entryCount ); + Span tmpBuffer = bbcvirtallocboundednuma_span( entryCount ); + Span tmpBuffer2 = bbcvirtallocboundednuma_span( entryCount ); + + // Load reference values + Log::Line( " Loading reference values..." ); + FatalIf( !Debug::LoadRefTableByName( "y.t1.tmp", yReference ), "Failed to load reference y table." ); + ASSERT( yReference.Length() == entryCount ); + FatalIf( !Debug::LoadRefTableByName( "x.t1.tmp", xReference ), "Failed to load reference x table." ); + ASSERT( xReference.Length() == entryCount ); + ASSERT( yReference.Length() == xReference.Length() ); + + // Load our values + Log::Line( " Loading our values..." ); + Fence& fence = context.fencePool->RequireFence(); + + { + // const size_t blockSizeEntries = context.tmp2BlockSize / sizeof( uint32 ); + // const uint32 bucketSize = (uint32)RoundUpToNextBoundaryT( (size_t)entryCount / 2, blockSizeEntries ); + + Span yReader = yBuffer; + Span xReader = xBuffer; + + const uint32 numBuckets = context.numBuckets; + for( uint32 bucket = 0; bucket < numBuckets; bucket++ ) + { + Span yBucket = tmpBuffer.As(); + Span xBucket = tmpBuffer2; + + ioQueue.ReadBucketElementsT( FileId::FX0 , yBucket ); + ioQueue.ReadBucketElementsT( FileId::META0, xBucket ); + ioQueue.SignalFence( fence ); + ioQueue.CommitCommands(); + fence.Wait(); + + ASSERT( yBucket.Length() && yBucket.Length() == xBucket.Length() ); + + const uint32 k = 32; + const uint32 bucketBits = bblog2( numBuckets ); + const uint32 yBits = k + kExtraBits - bucketBits; + const uint64 yMask = ((uint64)bucket) << yBits; + + for( size_t i = 0; i < yBucket.Length(); i++ ) + yReader[i] = yMask | yBucket[i]; + + xBucket.CopyTo( xReader ); + + // Sort bucket + RadixSort256::SortWithKey( *context.threadPool, + yReader.Ptr(), tmpBuffer.Ptr(), xReader.Ptr(), tmpBuffer2.Ptr(), yBucket.Length() ); + + yReader = yReader.Slice( yBucket.Length() ); + xReader = xReader.Slice( xBucket.Length() ); + } + + ASSERT( yReader.Length() == xReader.Length() ); + } + + // Sort + // Log::Line( " Sorting..." ); + // RadixSort256::SortWithKey( *context.threadPool, yBuffer.Ptr(), tmpBuffer.Ptr(), xBuffer.Ptr(), tmpBuffer2.Ptr(), yBuffer.Length() ); + + // Compare + Log::Line( " Comparing values..." ); + for( size_t i = 0; i < yBuffer.Length(); i++ ) + { + const uint64 y = yBuffer[i]; + const uint64 yr = yReference[i]; + const uint32 x = xBuffer[i]; + const uint32 xr = xReference[i]; + + ASSERT( y == yr ); + + if( x != xr ) + { + if( xBuffer[i] == xReference[i+1] ) // 2-way match? + { + i++; + continue; + } + else if( xBuffer[i] == xReference[i+2] && // 3 way match? + xBuffer[i+2] == xReference[i] && + xBuffer[i+1] == xReference[i+1]) + { + i+=2; + continue; + } + ASSERT( false ); + } + } + // ASSERT( yReference.EqualElements( yBuffer ) ); + // ASSERT( xReference.EqualElements( xBuffer ) ); + + Log::Line( " Finished." ); + Log::Line( "" ); + + // Cleanup + context.fencePool->RestoreAllFences(); + bbvirtfreebounded( yReference.Ptr() ); + bbvirtfreebounded( xReference.Ptr() ); + bbvirtfreebounded( yBuffer.Ptr() ); + bbvirtfreebounded( xBuffer.Ptr() ); + bbvirtfreebounded( tmpBuffer.Ptr() ); + bbvirtfreebounded( tmpBuffer2.Ptr() ); +} +#endif + From 30d53338f86b87b0f817ac41dc2bb0cca7b0b4f2 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 16 Jun 2022 07:21:33 -0500 Subject: [PATCH 42/91] Fixes to y values in other bucket counts. Map still messed up in none-64 buckets. --- src/plotdisk/k32/FpMatchBounded.inl | 14 +++++++++++--- src/plotdisk/k32/FxBounded.inl | 6 +++++- src/threading/MTJob.h | 4 ++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 130af8d9..1bbd441f 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -162,7 +162,11 @@ public: Span groupBuffer, uint32& outStartIndex ) { - const uint64 yMask = bucket << 32; + const uint32 k = 32; + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 yBits = k + kExtraBits - bucketBits; + const uint64 yMask = ((uint64)bucket) << yBits; + const uint32 id = self->JobId(); int64 _, offset; @@ -232,8 +236,12 @@ public: Span pairs, const uint64 maxPairs ) { - const uint64 lGroupMask = ((uint64)lBucket) << 32; - const uint64 rGroupMask = ((uint64)rBucket) << 32; + const uint32 k = 32; + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 yBits = k + kExtraBits - bucketBits; + + const uint64 lGroupMask = ((uint64)lBucket) << yBits; + const uint64 rGroupMask = ((uint64)rBucket) << yBits; const uint32 groupCount = groupBoundaries.Length() - 1; // Ignore the extra ghost group diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index d763255a..4ec19dd0 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -930,6 +930,11 @@ private: // so we need to shift by 32 bits, instead of 26. const uint32 ySize = k + kExtraBits; // = 38 const uint32 yShift = 64 - (k + shiftBits); // = 26 or 32 + + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 yBits = k + kExtraBits - bucketBits; + const uint64 yMask = ((uint64)bucket) << yBits; + const size_t metaSize = k * MetaInMulti; const size_t metaSizeLR = metaSize * 2; @@ -937,7 +942,6 @@ private: // const uint32 id = self->JobId(); const uint32 matchCount = pairs.Length(); - const uint64 yMask = (uint64)bucket << 32; // Hashing uint64 input [5]; // y + L + R diff --git a/src/threading/MTJob.h b/src/threading/MTJob.h index e51f6ef2..3d71f8fc 100644 --- a/src/threading/MTJob.h +++ b/src/threading/MTJob.h @@ -470,8 +470,8 @@ inline void PrefixSumJob::CalculatePrefixSumImpl( const uint32 prevAlignedEntryCount = CDivT( prevEntryCount, entriesPerBlock ) * entriesPerBlock; const uint32 paddingFromPrevBucket = prevAlignedEntryCount - prevEntryCount; - // Calculate our next offset before updating our total count, which is the the entries - // our last block occupies, if its not full. + // Calculate our next offset before updating our total count, + // which is the # of entries that our last block occupies, if its not full. const uint32 offset = offsets[i]; const uint32 entryCount = pfxSum[i] + offset; const uint32 alignedEntryCount = CDivT( entryCount, entriesPerBlock ) * entriesPerBlock; From f05fa779f3880b2393d93c34cd0df462bbb5a445 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 17 Jun 2022 01:21:43 -0500 Subject: [PATCH 43/91] Fixing bugs in P1. Debugging missing indices bug in fx --- src/plotdisk/DiskPlotConfig.h | 2 +- src/plotdisk/MapWriter.h | 13 +-- src/plotdisk/k32/DiskPlotBounded.cpp | 18 ++-- src/plotdisk/k32/F1Bounded.inl | 47 ++++----- src/plotdisk/k32/FxBounded.inl | 140 +++++++++++++++++++++------ src/threading/ThreadPool.h | 3 +- 6 files changed, 151 insertions(+), 72 deletions(-) diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index d01accf3..9800ed04 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -74,4 +74,4 @@ #define BB_DP_DBG_P3_KEEP_FILES 1 #endif -#define BB_DP_FP_MATCH_X_BUCKET 1 +// #define BB_DP_FP_MATCH_X_BUCKET 1 diff --git a/src/plotdisk/MapWriter.h b/src/plotdisk/MapWriter.h index d0d0da9c..c407847b 100644 --- a/src/plotdisk/MapWriter.h +++ b/src/plotdisk/MapWriter.h @@ -101,10 +101,8 @@ class MapWriter auto& bitWriter = _bucketWriter; uint64* bitCounts = totalBitCounts; - if( self->IsControlThread() ) + if( self->BeginLockBlock() ) { - self->LockThreads(); - // Convert counts to bit sizes for( uint32 i = 0; i < numBuckets; i++ ) bitCounts[i] = (uint64)totalCounts[i] * bitSize; @@ -116,11 +114,8 @@ class MapWriter _writeFence->Wait( bucket - 2, *_writeWaitTime ); bitWriter.BeginWriteBuckets( bitCounts, writeBuffer ); - - self->ReleaseThreads(); } - else - self->WaitForRelease(); + self->EndLockBlock(); // Bit-compress/pack each bucket entries (except the overflow bucket) @@ -159,8 +154,7 @@ class MapWriter } // Write the overflow bucket and then write to disk - self->SyncThreads(); - if( self->IsControlThread() ) + if( self->BeginLockBlock() ) { if constexpr ( _overflow ) { @@ -185,6 +179,7 @@ class MapWriter _ioQueue->SignalFence( *_writeFence, bucket ); _ioQueue->CommitCommands(); } + self->EndLockBlock(); }); for( int32 b = 0; b <= (int32)_numBuckets; b++ ) diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index c0ebb30d..edd95a5c 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -131,16 +131,16 @@ void K32BoundedPhase1::RunWithBuckets() } #else // #TODO: TEST, remove - // for( ;; ) - { - // Log::Line( "Running F1..." ); + // for( uint32 i = 0; i < 0x7FFFFFFF; i++ ) + // { + // Log::Line( "Running F1 %u...", i ); RunF1<_numBuckets>(); - // _ioQueue.SeekBucket( FileId::FX0, 0, SeekOrigin::Begin ); - // _ioQueue.SeekBucket( FileId::META0, 0, SeekOrigin::Begin ); - // _ioQueue.CommitCommands(); - // memset( _context.bucketCounts[0], 0, sizeof( _context.bucketCounts[0] ) ); - // _context.entryCounts[0] = 0; - } + // _ioQueue.SeekBucket( FileId::FX0 , 0, SeekOrigin::Begin ); + // _ioQueue.SeekBucket( FileId::META0, 0, SeekOrigin::Begin ); + // _ioQueue.CommitCommands(); + // memset( _context.bucketCounts[0], 0, sizeof( _context.bucketCounts[0] ) ); + // _context.entryCounts[0] = 0; + // } #endif #if BB_DP_FP_MATCH_X_BUCKET diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 25b9005a..e9b3183d 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -100,7 +100,6 @@ public: }); Fence& fence = _context.fencePool->RequireFence(); - fence.Reset( 0 ); _ioQueue.SignalFence( fence, 1 ); _ioQueue.CommitCommands(); fence.Wait( 1 ); @@ -136,10 +135,8 @@ private: const uint32 fsBlockSize = (uint32)_ioQueue.BlockSize( FileId::FX0 ); // Distribute to buckets - uint32 counts [_numBuckets] = {}; - uint32 pfxSum [_numBuckets]; - uint32 totalCounts [_numBuckets]; - uint32 alignedTotalCounts[_numBuckets]; + uint32 counts[_numBuckets] = {}; + uint32 pfxSum[_numBuckets]; // Count bucket entries for( uint32 i = 0; i < entryCount; i++ ) @@ -148,19 +145,12 @@ private: // Prefix sum Span offsets = _offsets[self->JobId()]; + // Grab next buffer Span yEntries, xEntries, elementCounts, alignedElementCounts; GetNextBuffer( self, bucket, yEntries, xEntries, elementCounts, alignedElementCounts ); - uint32* pTotalCounts = totalCounts; - uint32* pAlignedTotalCounts = alignedTotalCounts; - - if( self->IsControlThread() ) - { - pTotalCounts = elementCounts.Ptr(); - pAlignedTotalCounts = alignedElementCounts.Ptr(); - } - - self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, pTotalCounts, offsets.Ptr(), pAlignedTotalCounts ); + // Calculate prefix sum + self->CalculateBlockAlignedPrefixSum( _numBuckets, fsBlockSize, counts, pfxSum, elementCounts.Ptr(), offsets.Ptr(), alignedElementCounts.Ptr() ); // Distribute slices to buckets const uint32 yBits = _k + kExtraBits - bucketBits; @@ -184,7 +174,7 @@ private: { _ioQueue.WriteBucketElementsT( FileId::FX0 , yEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); _ioQueue.WriteBucketElementsT( FileId::META0, xEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); - _ioQueue.SignalFence( _writeFence, bucket+1 ); + _ioQueue.SignalFence( _writeFence, bucket+2 ); _ioQueue.CommitCommands(); for( uint32 i = 0; i < _numBuckets; i++ ) @@ -198,18 +188,29 @@ private: Span& yEntries, Span& xEntries, Span& elementCounts, Span& alignedElementCounts ) { - if( bucket >= 2 && _writeFence.Value() < bucket-1 ) + const uint32 bucketIdx = bucket & 1; // % 2 + + // if( bucket >= 2 && _writeFence.Value() < bucket-1 ) + if( bucket >= 2 ) { + // #TODO: Figure out if we can avoid the lock if already signaled. + // Like what's commented out above. However, we have to make sure that + // the signal is properly visible to all threads if( self->BeginLockBlock() ) - _writeFence.Wait( bucket - 1, _context.p1TableWaitTime[(int)TableId::Table1] ); - + { + _writeFence.Wait( bucket, _context.p1TableWaitTime[(int)TableId::Table1] ); + } self->EndLockBlock(); } - yEntries = _yEntries[bucket & 1]; - xEntries = _xEntries[bucket & 1]; - elementCounts = Span( _elementCounts[bucket & 1], _numBuckets ); - alignedElementCounts = Span( _alignedElementCounts[bucket & 1], _numBuckets ); + yEntries = _yEntries[bucketIdx]; + xEntries = _xEntries[bucketIdx]; + + if( self->IsControlThread() ) + { + elementCounts = Span( _elementCounts [bucketIdx], _numBuckets ); + alignedElementCounts = Span( _alignedElementCounts[bucketIdx], _numBuckets ); + } } private: diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 4ec19dd0..8124acdf 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -23,6 +23,12 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context ); #endif + #define DBG_VALIDATE_INDICES 1 + #if DBG_VALIDATE_INDICES + static Span _dbgIndices; + static uint64 _dbgIdxCount = 0; + #endif + // #define DBG_VALIDATE_TABLES 1 @@ -187,8 +193,16 @@ public: //----------------------------------------------------------- void AllocateBuffers( IAllocator& allocator, const size_t t1BlockSize, const size_t t2BlockSize, const uint32 threadCount, const bool dryRun ) { - const uint64 kEntryCount = 1ull << _k; - const uint64 entriesPerBucket = (uint64)( kEntryCount / _numBuckets * BB_DP_XTRA_ENTRIES_PER_BUCKET ); + const uint64 kEntryCount = 1ull << _k; + const uint64 yEntriesPerBlock = t2BlockSize / sizeof( uint32 ); + const uint64 entriesPerBucket = (uint64)( kEntryCount / _numBuckets * BB_DP_XTRA_ENTRIES_PER_BUCKET ); + const uint64 entriesPerSlice = entriesPerBucket / _numBuckets; + + // #TODO: Do these for meta as well, since this is for y + const uint64 entriesPerSliceAligned = RoundUpToNextBoundaryT( entriesPerSlice, yEntriesPerBlock ) + yEntriesPerBlock; + const uint64 writeEntriesPerBucket = entriesPerSliceAligned * _numBuckets; + + _entriesPerBucket = entriesPerBucket; // Read buffers @@ -237,9 +251,9 @@ public: } // Write buffers - _yWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _indexWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); - _metaWriteBuffer = allocator.CAllocSpan( entriesPerBucket, t2BlockSize ); + _yWriteBuffer = allocator.CAllocSpan( writeEntriesPerBucket, t2BlockSize ); + _indexWriteBuffer = allocator.CAllocSpan( writeEntriesPerBucket, t2BlockSize ); + _metaWriteBuffer = allocator.CAllocSpan( writeEntriesPerBucket, t2BlockSize ); const size_t pairsWriteSize = CDiv( entriesPerBucket * _pairBitSize, 8 ); _pairsWriteBuffer = allocator.AllocT( pairsWriteSize, t1BlockSize ); @@ -330,6 +344,26 @@ public: tableEntryCount += _context.bucketCounts[(int)rTable][i]; ASSERT( tableEntryCount == _tableEntryCount ); + + #if DBG_VALIDATE_INDICES + if constexpr ( rTable > TableId::Table2 ) + { + Log::Line( "[DEBUG: Validating indices]" ); + ASSERT( _dbgIdxCount ); + + uint32* tmpIndices = bbcvirtallocbounded( _maxTableEntries ); + RadixSort256::Sort( *_context.threadPool, _dbgIndices.Ptr(), tmpIndices, _dbgIdxCount ); + bbvirtfreebounded( tmpIndices ); + + for( uint64 i = 0; i < _dbgIdxCount; i++ ) + { + ASSERT( _dbgIndices[i] == i); + } + + _dbgIdxCount = 0; + Log::Line( " OK" ); + } + #endif } #endif @@ -386,10 +420,25 @@ private: Span indices = _metaTmp[1].As().SliceSize( entryCount ); + #if (_DEBUG && DBG_VALIDATE_INDICES) + if( self->BeginLockBlock() ) + { + if( _dbgIndices.Ptr() == nullptr ) + _dbgIndices = bbcvirtallocboundednuma_span( _maxTableEntries ); + + // indices.CopyTo( _dbgIndices.Slice( _dbgIdxCount, entryCount ) ); + _index[bucket].CopyTo( _dbgIndices.Slice( _dbgIdxCount, entryCount ) ); + + _dbgIdxCount += entryCount; + } + self->EndLockBlock(); + #endif + SortOnYKey( self, sortKey, _index[bucket], indices ); WriteMap( self, bucket, indices, _mapWriteBuffer, _mapOffset ); } + /// /// Match /// @@ -406,10 +455,12 @@ private: matchOffset += (uint32)_pairs[i].Length(); ASSERT( totalMatches <= _entriesPerBucket ); - // #if _DEBUG + #if _DEBUG + _dbgIndexOffsets[id] = matchOffset; + _dbgPairLengths[id] = (uint32)matches.Length(); // if( self->IsControlThread() ) // Log::Line( " [%3u] : %u", bucket, totalMatches ); - // #endif + #endif // Prevent overflow entries const uint64 tableEntryCount = _tableEntryCount; @@ -436,13 +487,15 @@ private: /// /// Sort meta on Y /// - Span metaTmp = _meta[bucket].SliceSize( yInput.Length() ); - Span metaIn = _metaTmp[0].As().SliceSize( yInput.Length() ); // #NOTE: _metaTmp[0] is only used here, so we can use it for writing x values to disk + WaitForFence( self, _metaReadFence, bucket ); + + Span metaUnsorted = _meta[bucket].SliceSize( entryCount ); + Span metaIn = _metaTmp[0].As().SliceSize( entryCount ); if constexpr ( rTable == TableId::Table2 ) { - // #TODO: Simplify this by not making use of the block writer's buffers? - // Set shared x buffer for other threads + // #TODO: Simplify this, allowing BlockWriter to let the user specify a buffer, like in BitWriter + // Get and set shared x buffer for other threads if( self->BeginLockBlock() ) _xWriteBuffer = Span( _xWriter.GetNextBuffer( _tableIOWait ), entryCount ); self->EndLockBlock(); @@ -451,10 +504,10 @@ private: metaIn = _xWriteBuffer; } - WaitForFence( self, _metaReadFence, bucket ); - SortOnYKey( self, sortKey, metaTmp, metaIn ); - - // SaveCrossBucketMetadata( self, metaIn ); + SortOnYKey( self, sortKey, metaUnsorted, metaIn ); + #if BB_DP_FP_MATCH_X_BUCKET + // SaveCrossBucketMetadata( self, metaIn ); + #endif // On Table 2, metadata is our x values, which have to be saved as table 1 if constexpr ( rTable == TableId::Table2 ) @@ -506,7 +559,9 @@ private: } // Generate fx for cross-bucket matches, and save the matches to an in-memory buffer - // GenCrossBucketFx( self, bucket ); + #if BB_DP_FP_MATCH_X_BUCKET + // GenCrossBucketFx( self, bucket ); + #endif if( self->IsControlThread() ) { @@ -632,17 +687,23 @@ private: auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); _pairs[id] = matches; - self->SyncThreads(); - if( self->IsControlThread() ) + if( self->BeginLockBlock() ) + { _matchTime += TimerEndTicks( timer ); + } + self->EndLockBlock(); + // Write cross-bucket pairs to disk - if( bucket > 0 ) - WriteCrossBucketPairs( self, bucket-1 ); + #if BB_DP_FP_MATCH_X_BUCKET + if( bucket > 0 ) + WriteCrossBucketPairs( self, bucket-1 ); + #endif return matches; } + #if BB_DP_FP_MATCH_X_BUCKET //----------------------------------------------------------- void SaveCrossBucketMetadata( Job* self, const Span metaIn ) { @@ -680,6 +741,7 @@ private: { } + #endif //----------------------------------------------------------- void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, @@ -842,11 +904,12 @@ private: const uint32 id = (uint32)self->JobId(); // Distribute to buckets - const uint32 logBuckets = bblog2( _numBuckets ); - static_assert( kExtraBits <= logBuckets ); + const uint32 bucketBits = bblog2( _numBuckets ); + static_assert( kExtraBits <= bucketBits ); - const uint32 bucketShift = ( std::is_same::value ? _k : _k + kExtraBits ) - logBuckets; - const uint64 yMask = ( 1ull << bucketShift ) - 1; + const uint32 yBits = ( std::is_same::value ? _k : _k + kExtraBits ); + const uint32 bucketShift = yBits - bucketBits; + const TYOut yMask = std::is_same::value ? 0xFFFFFFFF : ( 1ull << bucketShift ) - 1; // No masking-out for Table 7 const int64 entryCount = (int64)yIn.Length(); @@ -871,7 +934,7 @@ private: // Distribute to buckets for( int64 i = 0; i < entryCount; i++ ) { - const uint64 y = yIn[i]; + const TYOut y = yIn[i]; const uint32 yBucket = (uint32)(y >> bucketShift); const uint32 yDst = --pfxSum [yBucket]; const uint32 metaDst = --pfxSumMeta[yBucket]; @@ -884,7 +947,7 @@ private: // Write to disk if( self->BeginLockBlock() ) { - // #NOTE: Should we wait per file? + // #TODO: Either use a spin wait or have all threads suspend here if( bucket > 0 ) _fxWriteFence.Wait( bucket, _tableIOWait ); @@ -892,6 +955,19 @@ private: const FileId metaId = _metaId[1]; const FileId idxId = _idxId [1]; + // #TEST + #if _DEBUG + { + uint64 totalCounts = _dbgPairLengths[0]; + + for( uint32 i = 1; i < self->JobCount(); i++ ) + { + ASSERT( _dbgIndexOffsets[i] == totalCounts ); + totalCounts += _dbgPairLengths[i]; + } + } + #endif + ASSERT( ySliceCounts.Length() == metaSliceCounts.Length() ); _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); @@ -1233,9 +1309,6 @@ private: Fence& _pairWriteFence; Fence& _mapWriteFence; - #if DBG_VALIDATE_TABLES - uint64 _dbgPairOffset = 0; - #endif public: // Timings @@ -1246,7 +1319,16 @@ public: Duration _fxTime = Duration::zero(); private: + +#if _DEBUG + #if DBG_VALIDATE_TABLES + uint64 _dbgPairOffset = 0; + #endif + // #TEST + uint32 _dbgIndexOffsets[BB_DP_MAX_JOBS] = { 0 }; + uint32 _dbgPairLengths [BB_DP_MAX_JOBS] = { 0 }; +#endif }; diff --git a/src/threading/ThreadPool.h b/src/threading/ThreadPool.h index 2812fcc7..162d637d 100644 --- a/src/threading/ThreadPool.h +++ b/src/threading/ThreadPool.h @@ -70,4 +70,5 @@ template inline void ThreadPool::RunJob( void (*TJobFunc)( T* ), T* data, uint count ) { RunJob( (JobFunc)TJobFunc, data, count, sizeof( T ) ); -} \ No newline at end of file +} + From 63c696a750669cdf845de1226d8f8800b314f0de Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 17 Jun 2022 20:56:38 -0500 Subject: [PATCH 44/91] Fix allocator not popping back to zero. Fx missing indices bug suddenly stopped happening? --- src/plotdisk/k32/DiskPlotBounded.cpp | 3 ++- src/plotdisk/k32/FxBounded.inl | 38 ++++++++++++---------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index edd95a5c..ae881c3a 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -209,6 +209,8 @@ void K32BoundedPhase1::RunFx() #if BB_DP_FP_MATCH_X_BUCKET _allocator.PopToMarker( _xBucketStackMarker ); + #else + _allocator.PopToMarker( 0 ); #endif DiskPlotFxBounded fx( _context ); @@ -220,6 +222,5 @@ void K32BoundedPhase1::RunFx() Log::Line( "Completed table %u in %.2lf seconds with %.llu entries.", table+1, TimerEnd( timer ), _context.entryCounts[(int)table] ); Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( fx._tableIOWait ) ); - } diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 8124acdf..d5154030 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -298,6 +298,12 @@ public: _dbgPlot.AllocTable( rTable ); #endif + #if (_DEBUG && DBG_VALIDATE_INDICES) + if( _dbgIndices.Ptr() == nullptr ) + _dbgIndices = bbcvirtallocboundednuma_span( _maxTableEntries ); + _dbgIdxCount = 0; + #endif + // Prepare input files _ioQueue.SeekBucket( _yId[0], 0, SeekOrigin::Begin ); _ioQueue.SeekBucket( _yId[1], 0, SeekOrigin::Begin ); @@ -423,9 +429,6 @@ private: #if (_DEBUG && DBG_VALIDATE_INDICES) if( self->BeginLockBlock() ) { - if( _dbgIndices.Ptr() == nullptr ) - _dbgIndices = bbcvirtallocboundednuma_span( _maxTableEntries ); - // indices.CopyTo( _dbgIndices.Slice( _dbgIdxCount, entryCount ) ); _index[bucket].CopyTo( _dbgIndices.Slice( _dbgIdxCount, entryCount ) ); @@ -455,9 +458,9 @@ private: matchOffset += (uint32)_pairs[i].Length(); ASSERT( totalMatches <= _entriesPerBucket ); + + // #TEST #if _DEBUG - _dbgIndexOffsets[id] = matchOffset; - _dbgPairLengths[id] = (uint32)matches.Length(); // if( self->IsControlThread() ) // Log::Line( " [%3u] : %u", bucket, totalMatches ); #endif @@ -927,10 +930,17 @@ private: // Count for( int64 i = 0; i < entryCount; i++ ) counts[yIn[i] >> bucketShift]++; - + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, ySliceCounts.Ptr(), _offsetsY[id], yAlignedSliceCount.Ptr() ); self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaSliceCounts.Ptr(), _offsetsMeta[id], metaAlignedSliceCount.Ptr() ); +// #if _DEBUG +// if( self->IsLastThread() ) +// { +// ASSERT( (uint64)pfxSum[_numBuckets-1] < 17200000 ); +// } +// #endif + // Distribute to buckets for( int64 i = 0; i < entryCount; i++ ) { @@ -955,19 +965,6 @@ private: const FileId metaId = _metaId[1]; const FileId idxId = _idxId [1]; - // #TEST - #if _DEBUG - { - uint64 totalCounts = _dbgPairLengths[0]; - - for( uint32 i = 1; i < self->JobCount(); i++ ) - { - ASSERT( _dbgIndexOffsets[i] == totalCounts ); - totalCounts += _dbgPairLengths[i]; - } - } - #endif - ASSERT( ySliceCounts.Length() == metaSliceCounts.Length() ); _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); @@ -1325,9 +1322,6 @@ private: #if DBG_VALIDATE_TABLES uint64 _dbgPairOffset = 0; #endif - // #TEST - uint32 _dbgIndexOffsets[BB_DP_MAX_JOBS] = { 0 }; - uint32 _dbgPairLengths [BB_DP_MAX_JOBS] = { 0 }; #endif }; From e4a2f088e63975fb1c187f0e05257f82997869bf Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 18 Jun 2022 06:57:30 -0500 Subject: [PATCH 45/91] Completing cross-bucket matches for validation --- .vscode/launch.json | 4 +- src/plotdisk/DiskPlotConfig.h | 4 +- src/plotdisk/k32/FpMatchBounded.inl | 104 +++++++++++++++++++++------ src/plotdisk/k32/FxBounded.inl | 107 ++++------------------------ 4 files changed, 103 insertions(+), 116 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index dd2d391f..a9cb2689 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -91,9 +91,9 @@ // "--cache", "64G", // "-s", "--k32-bounded", - // "-b", "64", + "-b", "64", // "-b", "128", - "-b", "256", + // "-b", "256", "--c-threads", "26", "--p2-threads", "24", diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 9800ed04..ff5c01ad 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -72,6 +72,8 @@ // #define BB_DP_DBG_P3_START_TABLE Table7 #define BB_DP_DBG_P3_KEEP_FILES 1 + + // For testing correctness: Allow cross-bucket matches. + #define BB_DP_FP_MATCH_X_BUCKET 1 #endif -// #define BB_DP_FP_MATCH_X_BUCKET 1 diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 1bbd441f..04d19c05 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -63,21 +63,27 @@ public: _groupBuffers[id] = groups; - // if( self->IsLastThread() ) - // { - // // Save last 2 group's data for this bucket (to be used during the next bucket) - // if( bucket < _numBuckets ) - // SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); - - // // Perform cross-bucket matching for the previous bucket, wwith the first 2 groups of this bucket - // if( bucket > 0 ) - // { - // auto& info = GetCrossBucketInfo( bucket-1 ); - // Span pairs( info.pair, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); - - // CrossBucketMatch( self, bucket-1, yEntries, groups, pairs ); - // } - // } + #if BB_DP_FP_MATCH_X_BUCKET + if( self->IsLastThread() ) + { + // Save last 2 group's data for this bucket (to be used during the next bucket) + if( bucket < _numBuckets ) + SaveCrossBucketGroups( self, bucket, groups.Slice( groups.Length()-3 ), yEntries ); + } + + if( bucket > 0 ) + { + // Perform cross-bucket matching for the previous bucket, with the first 2 groups of this bucket + if( self->BeginLockBlock() ) + { + auto& info = GetCrossBucketInfo( bucket-1 ); + Span pairs( info.pair, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + + CrossBucketMatch( self, bucket-1, yEntries, groups, pairs ); + } + self->EndLockBlock(); + } + #endif // BB_DP_FP_MATCH_X_BUCKET // const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); @@ -227,6 +233,7 @@ public: } //----------------------------------------------------------- + template uint32 MatchGroups( Job* self, const uint32 lBucket, const uint32 rBucket, @@ -234,7 +241,8 @@ public: const Span groupBoundaries, const Span yEntries, Span pairs, - const uint64 maxPairs ) + const uint64 maxPairs, + const uint32 groupLEndOverride = 0 ) { const uint32 k = 32; const uint32 bucketBits = bblog2( _numBuckets ); @@ -257,7 +265,10 @@ public: { const uint64 groupRStart = groupBoundaries[i]; const uint64 groupR = (rGroupMask | (uint64)yEntries[groupRStart]) / kBC; - const uint64 groupLEnd = groupRStart; + uint64 groupLEnd = groupRStart; + + if constexpr ( overrideLGroupEnd ) + groupLEnd = groupLEndOverride; if( groupR - groupL == 1 ) { @@ -334,16 +345,67 @@ public: } -private: - +private: //----------------------------------------------------------- uint32 CrossBucketMatch( Job* self, const uint32 bucket, - const Span yEntries, - Span groupBoundaries, + const Span curYEntries, + Span curBucketGroupBoundaries, Span pairs ) { + ASSERT( self->JobId() == 0 ); + ASSERT( curBucketGroupBoundaries.Length() > 2 ); + + auto& info = GetCrossBucketInfo( bucket ); + + const uint32 prevBucketLength = info.groupCount[0] + info.groupCount[1]; + + // Grab the first 2 groups from this bucket + const uint32 curBucketLengths[3] = { + prevBucketLength, + curBucketGroupBoundaries[1] - curBucketGroupBoundaries[0], + curBucketGroupBoundaries[2] - curBucketGroupBoundaries[1] + }; + + const Span groupBoundaries( (uint32*)curBucketLengths, 3 ); + + const uint32 curBucketLength = groupBoundaries[1] + groupBoundaries[2]; + + bbmemcpy_t( info.savedY + prevBucketLength, curYEntries.Ptr(), curBucketLength ); + Span yEntries( info.savedY, prevBucketLength + curBucketLength ); + + // Do matches + const uint32 k = 32; + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 yBits = k + kExtraBits - bucketBits; + + const uint64 lGroupMask = ((uint64)bucket) << yBits; + const uint64 rGroupMask = ((uint64)bucket+1) << yBits; + + uint32 lastGrpMatchIndex = 1; + uint32 matchCount = 0; + + // If the first entry group is the same from the prev's bucket last group, + // then we can perform matches with the penultimate bucket + const uint64 penultimateGroup = lGroupMask | yEntries[info.groupCount[0]]; + const uint64 firstGroup = rGroupMask | yEntries[prevBucketLength]; + if( penultimateGroup == firstGroup ) + { + matchCount = MatchGroups( self, bucket, bucket+1, 0, groupBoundaries, yEntries, pairs, pairs.Length(), info.groupCount[0] ); + } + else + { + // We have different groups at the bucket boundary, so update the boundaries for the next match accordingly + lastGrpMatchIndex = 0; + } + + auto remPairs = pairs.Slice( matchCount ); + ASSERT( remPairs.Length() > 0 ); + + matchCount += MatchGroups( self, bucket, bucket+1, info.groupCount[0], groupBoundaries.Slice(lastGrpMatchIndex), yEntries, remPairs, remPairs.Length() ); + + return matchCount; } //----------------------------------------------------------- diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index d5154030..fa190323 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -23,96 +23,12 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context ); #endif - #define DBG_VALIDATE_INDICES 1 + // #define DBG_VALIDATE_INDICES 1 #if DBG_VALIDATE_INDICES static Span _dbgIndices; static uint64 _dbgIdxCount = 0; #endif - - // #define DBG_VALIDATE_TABLES 1 - - #if DBG_VALIDATE_TABLES - struct DebugPlot - { - using Job = AnonPrefixSumJob; - - Span x; - Span y; - Span f7; - Span backPointers[7] = {}; - uint64 _writeOffset[7] = {}; - uint32 _pairOffset [7] = {}; - - inline void AllocTable( const TableId table ) - { - const uint64 maxEntries = 1ull << 32; - if( table == TableId::Table2 ) - { - x = Span( bbcvirtallocboundednuma( maxEntries ), maxEntries ); - y = Span( bbcvirtallocboundednuma( maxEntries ), maxEntries ); - } - else if( table == TableId::Table7 ) - f7 = Span( bbcvirtallocboundednuma( maxEntries ), maxEntries ); - - backPointers[(int)table] = Span( bbcvirtallocboundednuma( maxEntries ), maxEntries ); - } - - inline void WriteYX( const uint64 bucket, const Span ys, const Span xs ) - { - ASSERT( ys.Length() == xs.Length() ); - - xs.CopyTo( x.Slice( _writeOffset[0] ) ); - - const uint64 yMask = bucket << 32; - auto yDst = y.Slice( _writeOffset[0] ); - for( uint32 i = 0; i < ys.Length(); i++ ) - yDst[i] = yMask | y[i]; - - _writeOffset[0] += xs.Length(); - } - - inline void WriteF7( const Span f7s ) - { - f7s.CopyTo( f7.Slice( _writeOffset[6] ) ); - } - - inline void WritePairs( Job* self, const TableId table, const uint32 threadOffset, const Span pairs, const uint32 lBucketLength, const uint32 totalPairsLength ) - { - const uint32 writeOffset = _writeOffset[(int)table] + threadOffset; - Span dst = backPointers[(int)table].Slice( writeOffset ); - - const uint32 offset = _pairOffset[(int)table]; - pairs.CopyTo( dst ); - - for( uint64 i = 0; i < pairs.Length(); i++ ) - { - dst[i].left += offset; - dst[i].right += offset; - } - - if( self->BeginLockBlock() ) - { - _writeOffset[(int)table] += totalPairsLength; - _pairOffset [(int)table] += lBucketLength; - } - self->EndLockBlock(); - } - - inline void FinishTable( const TableId table ) - { - const uint64 tableLength = _writeOffset[(int)table]; - backPointers[(int)table] = backPointers[(int)table].SliceSize( tableLength ); - - if( table == TableId::Table7 ) - f7 = f7.SliceSize( tableLength ); - } - }; - - static DebugPlot _dbgPlot; - void DbgValidatePlot( const DebugPlot& dbgPlot ); - #endif - #endif @@ -165,6 +81,9 @@ public: , _fxWriteFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) , _pairWriteFence( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) , _mapWriteFence ( context.fencePool ? context.fencePool->RequireFence() : *(Fence*)nullptr ) + #if BB_DP_FP_MATCH_X_BUCKET + + #endif { const TableId lTable = rTable - 1; _yId [0] = FileId::FX0 + (FileId)((int)lTable & 1); @@ -508,8 +427,9 @@ private: } SortOnYKey( self, sortKey, metaUnsorted, metaIn ); + #if BB_DP_FP_MATCH_X_BUCKET - // SaveCrossBucketMetadata( self, metaIn ); + SaveCrossBucketMetadata( self, bucket, metaIn ); #endif // On Table 2, metadata is our x values, which have to be saved as table 1 @@ -563,7 +483,7 @@ private: // Generate fx for cross-bucket matches, and save the matches to an in-memory buffer #if BB_DP_FP_MATCH_X_BUCKET - // GenCrossBucketFx( self, bucket ); + GenCrossBucketFx( self, bucket ); #endif if( self->IsControlThread() ) @@ -706,17 +626,18 @@ private: return matches; } - #if BB_DP_FP_MATCH_X_BUCKET +#if BB_DP_FP_MATCH_X_BUCKET //----------------------------------------------------------- - void SaveCrossBucketMetadata( Job* self, const Span metaIn ) + void SaveCrossBucketMetadata( Job* self, const uint32 bucket, const Span metaIn ) { - + if( self->IsControlThread() ) + _matcher.SaveCrossBucketMeta( bucket, metaIn ); } //----------------------------------------------------------- void WriteCrossBucketPairs( Job* self, const uint32 bucket ) { - auto& info = _matcher.GetCrossBucketInfo( bucket ); + auto& info = _matcher.GetCrossBucketInfo( bucket-1 ); if( info.matchCount < 1 ) return; @@ -744,7 +665,7 @@ private: { } - #endif +#endif // BB_DP_FP_MATCH_X_BUCKET //----------------------------------------------------------- void WritePairs( Job* self, const uint32 bucket, const uint32 totalMatchCount, @@ -1306,6 +1227,8 @@ private: Fence& _pairWriteFence; Fence& _mapWriteFence; + #if BB_DP_FP_MATCH_X_BUCKET + #endif public: // Timings From 218a628af5898531b35cbb416210395f9307dfc1 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 19 Jun 2022 06:32:31 -0500 Subject: [PATCH 46/91] Completing cross-bucket matches. Need to add and save fx --- src/plotdisk/k32/FpMatchBounded.inl | 53 ++++++++++++++++------------- src/plotdisk/k32/FxBounded.inl | 13 +++++++ 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 04d19c05..45679aeb 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -26,8 +26,6 @@ struct K32BoundedFpCrossBucketInfo Meta4 savedMeta[BB_DP_CROSS_BUCKET_MAX_ENTRIES]; Pair pair [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; - uint32* y = nullptr; - Meta4* meta = nullptr; uint32 matchCount = 0; uint32 matchOffset = 0; @@ -87,14 +85,8 @@ public: // const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); - const uint32 matchCount = MatchGroups( self, - bucket, - bucket, - startIndex, - _groupBuffers[id], - yEntries, - pairs, - pairs.Length() ); + const uint32 matchCount = MatchGroups( self, bucket, bucket,startIndex, _groupBuffers[id], + yEntries, pairs, pairs.Length() ); return pairs.Slice( 0, matchCount ); @@ -343,34 +335,37 @@ public: { return _xBucketInfo[bucket & 1]; // bucket % 2 } - private: //----------------------------------------------------------- uint32 CrossBucketMatch( Job* self, const uint32 bucket, const Span curYEntries, - Span curBucketGroupBoundaries, - Span pairs ) + Span curBucketGroupBoundaries ) { ASSERT( self->JobId() == 0 ); ASSERT( curBucketGroupBoundaries.Length() > 2 ); auto& info = GetCrossBucketInfo( bucket ); + Span pairs( info.pair, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + const uint32 prevBucketLength = info.groupCount[0] + info.groupCount[1]; // Grab the first 2 groups from this bucket - const uint32 curBucketLengths[3] = { + const uint32 _groupBoundaries[3] = { prevBucketLength, - curBucketGroupBoundaries[1] - curBucketGroupBoundaries[0], - curBucketGroupBoundaries[2] - curBucketGroupBoundaries[1] + curBucketGroupBoundaries[0] + prevBucketLength, + curBucketGroupBoundaries[1] + prevBucketLength }; - const Span groupBoundaries( (uint32*)curBucketLengths, 3 ); + const Span groupBoundaries( (uint32*)_groupBoundaries, 3 ); const uint32 curBucketLength = groupBoundaries[1] + groupBoundaries[2]; + // Copy y from the 2 first groups of the current bucket to our existing y buffer + // Buffer y now looks like this: + // [prev_bcuket_penultimate_group][prev_bucket_last_group][cur_bucket_first_group][cur_bucket_second_group] bbmemcpy_t( info.savedY + prevBucketLength, curYEntries.Ptr(), curBucketLength ); Span yEntries( info.savedY, prevBucketLength + curBucketLength ); @@ -385,17 +380,20 @@ private: uint32 lastGrpMatchIndex = 1; uint32 matchCount = 0; - // If the first entry group is the same from the prev's bucket last group, - // then we can perform matches with the penultimate bucket - const uint64 penultimateGroup = lGroupMask | yEntries[info.groupCount[0]]; - const uint64 firstGroup = rGroupMask | yEntries[prevBucketLength]; + // If the cur bucket's first group is the same from the prev's bucket last group, + // then we can perform matches against the penultimate bucket + const uint64 lastGroup = ( lGroupMask | yEntries[info.groupCount[0]] ) / kBC; + const uint64 firstGroup = ( rGroupMask | yEntries[prevBucketLength] ) / kBC; - if( penultimateGroup == firstGroup ) + if( lastGroup == firstGroup ) { matchCount = MatchGroups( self, bucket, bucket+1, 0, groupBoundaries, yEntries, pairs, pairs.Length(), info.groupCount[0] ); } else { + ASSERT( firstGroup > lastGroup ); + ASSERT( firstGroup - lastGroup <= 4 ); + // We have different groups at the bucket boundary, so update the boundaries for the next match accordingly lastGrpMatchIndex = 0; } @@ -403,7 +401,16 @@ private: auto remPairs = pairs.Slice( matchCount ); ASSERT( remPairs.Length() > 0 ); - matchCount += MatchGroups( self, bucket, bucket+1, info.groupCount[0], groupBoundaries.Slice(lastGrpMatchIndex), yEntries, remPairs, remPairs.Length() ); + matchCount += MatchGroups( self, bucket, bucket+1, info.groupCount[0], groupBoundaries.Slice(lastGrpMatchIndex), yEntries, remPairs, remPairs.Length(), prevBucketLength ); + + info.matchCount = matchCount; + + // Update offset on the pairs + for( uint32 i = 0; i < matchCount; i++ ) + { + info.pair[i].left += info.matchOffset; + info.pair[i].right += info.matchOffset; + } return matchCount; } diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index fa190323..23cd2c76 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -663,7 +663,20 @@ private: //----------------------------------------------------------- void GenCrossBucketFx( Job* self, const uint32 bucket ) { + auto& info = _matcher.GetCrossBucketInfo( bucket-1 ); + if( info.matchCount < 1 ) + return; + + if( self->BeginLockBlock() ) + { + const Span pairs( info.pair , info.matchCount ); + const Span y ( info.savedY , info.matchCount ); + const Span meta ( (TMetaIn*)info.savedMeta, info.matchCount ); + + GenFx( self, bucket, pairs, y, meta, yOut, metaOut ); + } + self->EndLockBlock(); } #endif // BB_DP_FP_MATCH_X_BUCKET From 55640a44794f36180f1eeab350427f853661ef95 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 22 Jun 2022 04:56:05 -0500 Subject: [PATCH 47/91] Cross bucket fx seems to be working now, missing distributlion of it and loading of it in subsequent tables. --- src/plotdisk/k32/FpMatchBounded.inl | 49 ++++++++++++++++++++--------- src/plotdisk/k32/FxBounded.inl | 21 +++++++++++-- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 45679aeb..51de1b5e 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -20,16 +20,21 @@ struct K32BoundedFpCrossBucketInfo { struct Meta4{ uint32 m[4]; }; - uint32 groupCount[2]; // Groups sizes for the bucket's last 2 groups + uint32 groupCount[2]; // Groups sizes for the prev bucket's last 2 groups, and + // the current bucket's first 2 groups uint32 savedY [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; Meta4 savedMeta[BB_DP_CROSS_BUCKET_MAX_ENTRIES]; Pair pair [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; - uint32 matchCount = 0; - uint32 matchOffset = 0; + uint32 matchCount = 0; + uint32 matchOffset = 0; + uint32 curBucketMetaLength = 0; // Number of meta entries needed to be kept from the current bucket + // (Length of first 2 groups of current bucket) + + + inline uint32 PrevBucketEntryCount() const { return groupCount[0] + groupCount[1]; } - inline uint64 EntryCount() const { return (uint64)groupCount[0] + groupCount[1]; } }; @@ -77,7 +82,7 @@ public: auto& info = GetCrossBucketInfo( bucket-1 ); Span pairs( info.pair, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); - CrossBucketMatch( self, bucket-1, yEntries, groups, pairs ); + CrossBucketMatch( self, bucket-1, yEntries, groups ); } self->EndLockBlock(); } @@ -139,10 +144,22 @@ public: { auto& info = GetCrossBucketInfo( bucket ); - const size_t copyCount = info.EntryCount(); + if( bucket > 0 ) + { + auto& prevInfo = GetCrossBucketInfo( bucket - 1 ); + + const uint32 prevEntryCount = prevInfo.PrevBucketEntryCount(); + ASSERT( prevEntryCount + prevInfo.curBucketMetaLength <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + + // Copy current metadata for previous bucket fx + bbmemcpy_t( (TMeta*)prevInfo.savedMeta + prevEntryCount, meta.Ptr(), prevInfo.curBucketMetaLength ); + } + + const size_t copyCount = info.PrevBucketEntryCount(); ASSERT( copyCount <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + ASSERT( meta.Length() - info.matchOffset >= copyCount ); - memcpy( info.savedMeta, meta.Ptr() + info.matchOffset, copyCount * sizeof( TMeta ) ); + bbmemcpy_t( (TMeta*)info.savedMeta, meta.Ptr() + info.matchOffset, copyCount ); } //----------------------------------------------------------- @@ -347,6 +364,7 @@ private: ASSERT( curBucketGroupBoundaries.Length() > 2 ); auto& info = GetCrossBucketInfo( bucket ); + info.curBucketMetaLength = curBucketGroupBoundaries[1]; Span pairs( info.pair, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); @@ -361,7 +379,8 @@ private: const Span groupBoundaries( (uint32*)_groupBoundaries, 3 ); - const uint32 curBucketLength = groupBoundaries[1] + groupBoundaries[2]; + const uint32 curBucketLength = curBucketGroupBoundaries[1]; + ASSERT( curBucketLength <= BB_DP_CROSS_BUCKET_MAX_ENTRIES - prevBucketLength ); // Copy y from the 2 first groups of the current bucket to our existing y buffer // Buffer y now looks like this: @@ -406,11 +425,11 @@ private: info.matchCount = matchCount; // Update offset on the pairs - for( uint32 i = 0; i < matchCount; i++ ) - { - info.pair[i].left += info.matchOffset; - info.pair[i].right += info.matchOffset; - } + // for( uint32 i = 0; i < matchCount; i++ ) + // { + // info.pair[i].left += info.matchOffset; + // info.pair[i].right += info.matchOffset; + // } return matchCount; } @@ -431,9 +450,9 @@ private: info.groupCount[0] = groupIndices[1] - groupIndices[0]; info.groupCount[1] = groupIndices[2] - groupIndices[1]; - + const size_t copyCount = info.groupCount[0] + info.groupCount[1]; - ASSERT( copyCount <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + ASSERT( copyCount < BB_DP_CROSS_BUCKET_MAX_ENTRIES ); memcpy( info.savedY, yEntries.Ptr() + info.matchOffset, copyCount * sizeof( uint32 ) ); // memcpy( info.savedMeta, meta + groupIndices[0], copyCount * sizeof( TMeta ) ); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 23cd2c76..3e8ff016 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -213,6 +213,10 @@ public: #endif ) { + #if BB_DP_FP_MATCH_X_BUCKET + _crossBucketEntries = crossBucketEntries; + #endif + #if DBG_VALIDATE_TABLES _dbgPlot.AllocTable( rTable ); #endif @@ -670,11 +674,21 @@ private: if( self->BeginLockBlock() ) { - const Span pairs( info.pair , info.matchCount ); - const Span y ( info.savedY , info.matchCount ); - const Span meta ( (TMetaIn*)info.savedMeta, info.matchCount ); + const uint32 prevBucketLength = info.PrevBucketEntryCount(); + + const Span pairs( info.pair , info.matchCount ); + const Span y ( info.savedY , prevBucketLength ); + const Span meta ( (TMetaIn*)info.savedMeta, prevBucketLength + info.curBucketMetaLength ); + + Span yOut = _yTmp .As() .SliceSize( info.matchCount ); + Span metaOut = _metaTmp[1].As().SliceSize( info.matchCount ); GenFx( self, bucket, pairs, y, meta, yOut, metaOut ); + + // Copy values to in-memory cross-bucket cache + + // Distribute to the correct bucket + // _crossBucketEntries; } self->EndLockBlock(); } @@ -1241,6 +1255,7 @@ private: Fence& _mapWriteFence; #if BB_DP_FP_MATCH_X_BUCKET + Span _crossBucketEntries; #endif public: From 7aaee4fcdf370f8e9bcf4d56b57e3bade722825c Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 22 Jun 2022 21:06:23 -0500 Subject: [PATCH 48/91] Cross-bucket entries seem to be working. Pending validation --- src/plotdisk/k32/DiskPlotBounded.cpp | 26 ++++++-- src/plotdisk/k32/DiskPlotBounded.h | 2 +- src/plotdisk/k32/FpMatchBounded.inl | 32 +++++++++- src/plotdisk/k32/FxBounded.inl | 94 +++++++++++++++++++++------- 4 files changed, 124 insertions(+), 30 deletions(-) diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index ae881c3a..9ce638e9 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -83,6 +83,7 @@ size_t K32BoundedPhase1::GetRequiredSize( const uint32 numBuckets, const size_t #if BB_DP_FP_MATCH_X_BUCKET allocator.CAlloc( numBuckets ); + allocator.CAlloc( numBuckets ); #endif switch( numBuckets ) @@ -130,7 +131,7 @@ void K32BoundedPhase1::RunWithBuckets() startTable = BB_DP_P1_START_TABLE; } #else - // #TODO: TEST, remove + // #TODO: TEST, removes // for( uint32 i = 0; i < 0x7FFFFFFF; i++ ) // { // Log::Line( "Running F1 %u...", i ); @@ -144,8 +145,10 @@ void K32BoundedPhase1::RunWithBuckets() #endif #if BB_DP_FP_MATCH_X_BUCKET - _crossBucketEntries.values = _allocator.CAlloc( _numBuckets ); - _crossBucketEntries.length = _numBuckets; + _crossBucketEntries[0].values = _allocator.CAlloc( _numBuckets ); + _crossBucketEntries[1].values = _allocator.CAlloc( _numBuckets ); + _crossBucketEntries[0].length = _numBuckets; + _crossBucketEntries[1].length = _numBuckets; _xBucketStackMarker = _allocator.Size(); #endif @@ -209,6 +212,20 @@ void K32BoundedPhase1::RunFx() #if BB_DP_FP_MATCH_X_BUCKET _allocator.PopToMarker( _xBucketStackMarker ); + + const uint xBucketIdxIn = (uint)(table-1) & 1; + const uint xBucketIdxOut = (uint)table & 1; + auto& crossBucketIn = _crossBucketEntries[xBucketIdxIn]; + auto& crossBucketOut = _crossBucketEntries[xBucketIdxOut]; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + crossBucketOut[bucket].length = 0; + + if( table == TableId::Table2 ) + { + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + crossBucketIn[bucket].length = 0; + } #else _allocator.PopToMarker( 0 ); #endif @@ -216,7 +233,8 @@ void K32BoundedPhase1::RunFx() DiskPlotFxBounded fx( _context ); fx.Run( _allocator #if BB_DP_FP_MATCH_X_BUCKET - , _crossBucketEntries + , crossBucketIn + , crossBucketOut #endif ); diff --git a/src/plotdisk/k32/DiskPlotBounded.h b/src/plotdisk/k32/DiskPlotBounded.h index 5fda699d..95216f86 100644 --- a/src/plotdisk/k32/DiskPlotBounded.h +++ b/src/plotdisk/k32/DiskPlotBounded.h @@ -34,7 +34,7 @@ class K32BoundedPhase1 #if BB_DP_FP_MATCH_X_BUCKET size_t _xBucketStackMarker = 0; - Span _crossBucketEntries; + Span _crossBucketEntries[2]; #endif }; diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 51de1b5e..e2350377 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -10,9 +10,34 @@ struct K32CrossBucketEntries struct Meta4{ uint32 m[4]; }; uint32 length; - uint64 y [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + uint32 y [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; uint32 index[BB_DP_CROSS_BUCKET_MAX_ENTRIES]; Meta4 meta [BB_DP_CROSS_BUCKET_MAX_ENTRIES]; + + inline Span CopyYAndExtend( const Span dst ) const + { + if( length == 0 ) + return dst; + bbmemcpy_t( dst.Ptr() + dst.Length(), y, length ); + return Span( dst.Ptr(), dst.Length() + length ); + } + + inline Span CopyIndexAndExtend( const Span dst ) const + { + if( length == 0 ) + return dst; + bbmemcpy_t( dst.Ptr() + dst.Length(), index, length ); + return Span( dst.Ptr(), dst.Length() + length ); + } + + template + inline Span CopyMetaAndExtend( const Span dst ) const + { + if( length == 0 ) + return dst; + bbmemcpy_t( dst.Ptr() + dst.Length(), (TMeta*)meta, length ); + return Span( dst.Ptr(), dst.Length() + length ); + } }; @@ -155,6 +180,9 @@ public: bbmemcpy_t( (TMeta*)prevInfo.savedMeta + prevEntryCount, meta.Ptr(), prevInfo.curBucketMetaLength ); } + if( bucket == _numBuckets -1 ) + return; + const size_t copyCount = info.PrevBucketEntryCount(); ASSERT( copyCount <= BB_DP_CROSS_BUCKET_MAX_ENTRIES ); ASSERT( meta.Length() - info.matchOffset >= copyCount ); @@ -442,7 +470,7 @@ private: { auto& info = GetCrossBucketInfo( bucket ); - GetCrossBucketInfo( bucket - 1 ).matchOffset = info.matchOffset; + // GetCrossBucketInfo( bucket - 1 ).matchOffset = info.matchOffset; info.matchOffset = groupIndices[0]; if( bucket == _numBuckets-1 ) diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 3e8ff016..b52bc41d 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -209,12 +209,14 @@ public: //----------------------------------------------------------- void Run( IAllocator& allocator #if BB_DP_FP_MATCH_X_BUCKET - , Span crossBucketEntries + , Span crossBucketEntriesIn + , Span crossBucketEntriesOut #endif ) { #if BB_DP_FP_MATCH_X_BUCKET - _crossBucketEntries = crossBucketEntries; + _crossBucketEntriesIn = crossBucketEntriesIn; + _crossBucketEntriesOut = crossBucketEntriesOut; #endif #if DBG_VALIDATE_TABLES @@ -328,14 +330,12 @@ private: for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { - // if( bucket == 63 && self->JobId() == 0 ) BBDebugBreak(); - ReadNextBucket( self, bucket + 1 ); // Read next bucket in background WaitForFence( self, _yReadFence, bucket ); Span yInput = _y[bucket]; const uint32 entryCount = yInput.Length(); - + Span sortKey = _sortKey.SliceSize( entryCount ); SortY( self, entryCount, yInput.Ptr(), _yTmp.As().Ptr(), sortKey.Ptr(), _metaTmp[1].As().Ptr() ); @@ -345,22 +345,22 @@ private: if constexpr ( rTable > TableId::Table2 ) { WaitForFence( self, _indexReadFence, bucket ); - ASSERT( _index[bucket].Length() == entryCount ); - Span indices = _metaTmp[1].As().SliceSize( entryCount ); + Span unsortedIndices = _index[bucket]; ASSERT( unsortedIndices.Length() == entryCount ); + Span indices = _metaTmp[1].As().SliceSize( entryCount ); #if (_DEBUG && DBG_VALIDATE_INDICES) if( self->BeginLockBlock() ) { // indices.CopyTo( _dbgIndices.Slice( _dbgIdxCount, entryCount ) ); - _index[bucket].CopyTo( _dbgIndices.Slice( _dbgIdxCount, entryCount ) ); + unsortedIndices.CopyTo( _dbgIndices.Slice( _dbgIdxCount, entryCount ) ); _dbgIdxCount += entryCount; } self->EndLockBlock(); #endif - SortOnYKey( self, sortKey, _index[bucket], indices ); + SortOnYKey( self, sortKey, unsortedIndices, indices ); WriteMap( self, bucket, indices, _mapWriteBuffer, _mapOffset ); } @@ -414,8 +414,8 @@ private: /// Sort meta on Y /// WaitForFence( self, _metaReadFence, bucket ); - - Span metaUnsorted = _meta[bucket].SliceSize( entryCount ); + + Span metaUnsorted = _meta[bucket].SliceSize( entryCount ); ASSERT( metaUnsorted.Length() == entryCount ); Span metaIn = _metaTmp[0].As().SliceSize( entryCount ); if constexpr ( rTable == TableId::Table2 ) @@ -462,6 +462,11 @@ private: if( self->IsControlThread() ) timer = TimerBegin(); + // Generate fx for cross-bucket matches, and save the matches to an in-memory buffer + #if BB_DP_FP_MATCH_X_BUCKET + GenCrossBucketFx( self, bucket ); + #endif + GenFx( self, bucket, matches, yInput, metaIn, yOut, metaOut ); self->SyncThreads(); @@ -485,11 +490,6 @@ private: WriteEntries( self, bucket, (uint32)_tableEntryCount + matchOffset, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); } - // Generate fx for cross-bucket matches, and save the matches to an in-memory buffer - #if BB_DP_FP_MATCH_X_BUCKET - GenCrossBucketFx( self, bucket ); - #endif - if( self->IsControlThread() ) { _tableEntryCount += totalMatches; @@ -497,6 +497,11 @@ private: // Save bucket length before y-sort since the pairs remain unsorted _context.ptrTableBucketCounts[(int)rTable][bucket] = (uint32)totalMatches; + + #if BB_DP_FP_MATCH_X_BUCKET + if( bucket > 0 ) + _context.ptrTableBucketCounts[(int)rTable][bucket-1] += _matcher.GetCrossBucketInfo( bucket - 1 ).matchCount; + #endif } } } @@ -674,21 +679,51 @@ private: if( self->BeginLockBlock() ) { + const uint32 matchCount = info.matchCount; const uint32 prevBucketLength = info.PrevBucketEntryCount(); - const Span pairs( info.pair , info.matchCount ); + const Span pairs( info.pair , matchCount ); const Span y ( info.savedY , prevBucketLength ); const Span meta ( (TMetaIn*)info.savedMeta, prevBucketLength + info.curBucketMetaLength ); - Span yOut = _yTmp .As() .SliceSize( info.matchCount ); - Span metaOut = _metaTmp[1].As().SliceSize( info.matchCount ); + Span yOut = _yTmp .As() .SliceSize( matchCount ); + Span metaOut = _metaTmp[1].As().SliceSize( matchCount ); GenFx( self, bucket, pairs, y, meta, yOut, metaOut ); - // Copy values to in-memory cross-bucket cache + // Distribute new values to in-memory cross-bucket cache + { + const uint32 bucketBits = bblog2( _numBuckets ); + static_assert( kExtraBits <= bucketBits ); + + const uint32 yBits = ( std::is_same::value ? _k : _k + kExtraBits ); + const uint32 bucketShift = yBits - bucketBits; + const TYOut yMask = std::is_same::value ? 0xFFFFFFFF : ( 1ull << bucketShift ) - 1; // No masking-out for Table 7 + + const uint32 indxeBase = _tableEntryCount.load( std::memory_order_acquire ); + _tableEntryCount.store( indxeBase + matchCount, std::memory_order_release ); - // Distribute to the correct bucket - // _crossBucketEntries; + auto& crossBucketEntries = _crossBucketEntriesOut; + + for( uint32 i = 0; i < matchCount; i++ ) + { + const TYOut y = yOut[i]; + const uint32 yBucket = (uint32)(y >> bucketShift); + + auto& bucketFile = crossBucketEntries[yBucket]; + const uint32 bucketLength = bucketFile.length; + + Span metaDst( (TMetaOut*)bucketFile.meta, BB_DP_CROSS_BUCKET_MAX_ENTRIES ); + + bucketFile.y [bucketLength] = (uint32)(y & yMask); + bucketFile.index[bucketLength] = indxeBase + i; + metaDst [bucketLength] = metaOut[i]; + + bucketFile.length = bucketLength + 1; + + _context.bucketCounts[(int)rTable][yBucket]++; + } + } } self->EndLockBlock(); } @@ -1125,8 +1160,20 @@ private: void WaitForFence( Job* self, Fence& fence, const uint32 bucket ) { if( self->BeginLockBlock() ) + { fence.Wait( bucket+1, _tableIOWait ); + #if BB_DP_FP_MATCH_X_BUCKET + // Add cross-bucket entries saved in the memory cache + if( &fence == &_yReadFence ) + _y[bucket] = _crossBucketEntriesIn[bucket].CopyYAndExtend( _y[bucket] ); + else if( &fence == &_indexReadFence ) + _index[bucket] = _crossBucketEntriesIn[bucket].CopyIndexAndExtend( _index[bucket] ); + else if( &fence == &_metaReadFence ) + _meta[bucket] = _crossBucketEntriesIn[bucket].CopyMetaAndExtend( _meta[bucket] ); + #endif + } + self->EndLockBlock(); } @@ -1255,7 +1302,8 @@ private: Fence& _mapWriteFence; #if BB_DP_FP_MATCH_X_BUCKET - Span _crossBucketEntries; + Span _crossBucketEntriesIn; + Span _crossBucketEntriesOut; #endif public: From 167739db7e4550dbb4fa367b3891bc8894ec61b8 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 25 Jun 2022 02:57:45 -0500 Subject: [PATCH 49/91] Brought-in cross-bucket matches for validation against reference values. This led us to fixing a metadata bug for tables 5/6. cross-bucket pair and map serialization is still pending, so it won't work past phase 1. This fix yields correct entries, but there is still a pair or map issue causing failures for Phase 3 --- src/plotdisk/DiskPlotConfig.h | 4 +- src/plotdisk/DiskPlotDebug.h | 14 +++++ src/plotdisk/k32/F1Bounded.inl | 8 +-- src/plotdisk/k32/FpMatchBounded.inl | 2 +- src/plotdisk/k32/FxBounded.inl | 98 ++++++++++++++++------------- 5 files changed, 74 insertions(+), 52 deletions(-) diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index ff5c01ad..35ff1471 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -20,7 +20,7 @@ // How many extra entries to load from the next bucket to ensure we have enough to hold the 2 groups's // worth of entries. This is so that we can besure that we can complete matches from groups from the previous // bucket that continue on to the next bucket. There's around 280-320 entries per group on k32. This should be enough -#define BB_DP_CROSS_BUCKET_MAX_ENTRIES 768 +#define BB_DP_CROSS_BUCKET_MAX_ENTRIES 1024 // Pretty big right now, but when buckets == 1024 it is needed. // Might change it to dynamic. @@ -74,6 +74,6 @@ #define BB_DP_DBG_P3_KEEP_FILES 1 // For testing correctness: Allow cross-bucket matches. - #define BB_DP_FP_MATCH_X_BUCKET 1 + // #define BB_DP_FP_MATCH_X_BUCKET 1 #endif diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 2b50bb4b..5206a217 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -41,6 +41,8 @@ namespace Debug template bool LoadRefTableByName( const char* fileName, Span& buffer ); + void LoadYRefTable( const TableId table, Span& buffer ); + void LoadRefLinePointTable( const TableId table, uint64*& buffer, uint64& outEntryCount ); void LoadRefLPIndexTable( const TableId table, uint32*& buffer, uint64& outEntryCount ); @@ -275,6 +277,18 @@ inline bool Debug::LoadRefTable( const char* path, T*& buffer, uint64& outEntryC return success; } +//----------------------------------------------------------- +inline void Debug::LoadYRefTable( const TableId table, Span& buffer ) +{ + ASSERT( table < TableId::Table7 && table > TableId::Table1 ); + + char path[1024]; + sprintf( path, "%st%d.y.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); + Log::Line( " Loading reference Y table '%s'.", path ); + + FatalIf( !Debug::LoadRefTable( path, buffer.values, buffer.length ), "Failed to load reference Y table." ); +} + //----------------------------------------------------------- inline void Debug::LoadRefLinePointTable( const TableId table, uint64*& buffer, uint64& outEntryCount ) { diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index e9b3183d..e5cfa8aa 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -135,8 +135,8 @@ private: const uint32 fsBlockSize = (uint32)_ioQueue.BlockSize( FileId::FX0 ); // Distribute to buckets - uint32 counts[_numBuckets] = {}; - uint32 pfxSum[_numBuckets]; + uint32 counts[_numBuckets] = {}; + uint32 pfxSum[_numBuckets]; // Count bucket entries for( uint32 i = 0; i < entryCount; i++ ) @@ -163,9 +163,7 @@ private: const uint32 x = xStart + i; ASSERT( dst < _maxEntriesPerIOBucket ); - y = ( ( y << kExtraBits ) | ( x >> kMinusKExtraBits ) ) & yMask; - - yEntries[dst] = y; + yEntries[dst] = ( ( (uint64)y << kExtraBits ) | ( x >> kMinusKExtraBits ) ) & yMask; xEntries[dst] = x; } diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index e2350377..1796b9d8 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -210,7 +210,7 @@ public: const uint32 yBits = k + kExtraBits - bucketBits; const uint64 yMask = ((uint64)bucket) << yBits; - const uint32 id = self->JobId(); + const uint32 id = self->JobId(); int64 _, offset; GetThreadOffsets( self, (int64)yEntries.Length(), _, offset, _ ); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index b52bc41d..24ef8b1f 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -12,15 +12,20 @@ #if _DEBUG #include "algorithm/RadixSort.h" #include "plotting/PlotValidation.h" + #include "plotdisk/DiskPlotDebug.h" // #define _VALIDATE_Y 1 #if _VALIDATE_Y - uint32 _refBucketCounts[BB_DP_MAX_BUCKET_COUNT]; - Span _yRef; - Span _yRefWriter; + // uint32 _refBucketCounts[BB_DP_MAX_BUCKET_COUNT]; + // Span _yRef; + // Span _yRefWriter; template - void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context ); + void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context + #if BB_DP_FP_MATCH_X_BUCKET + ,const Span crossBucketEntriesIn + #endif + ); #endif // #define DBG_VALIDATE_INDICES 1 @@ -35,7 +40,7 @@ typedef uint32 K32Meta1; typedef uint64 K32Meta2; // struct K32Meta3 { uint32 m0, m1, m2; }; -struct K32Meta3 { uint32 m0, m1; }; +struct K32Meta3 { uint64 m0, m1; }; struct K32Meta4 { uint64 m0, m1; }; struct K32NoMeta {}; @@ -315,7 +320,11 @@ public: // ValidateIndices(); #endif #if _VALIDATE_Y - DbgValidateY<_numBuckets>( rTable, _yId[1], _context ); + DbgValidateY<_numBuckets>( rTable, _yId[1], _context + #if BB_DP_FP_MATCH_X_BUCKET + , _crossBucketEntriesOut + #endif + ); #endif } @@ -464,7 +473,8 @@ private: // Generate fx for cross-bucket matches, and save the matches to an in-memory buffer #if BB_DP_FP_MATCH_X_BUCKET - GenCrossBucketFx( self, bucket ); + if( bucket > 0 ) + GenCrossBucketFx( self, bucket-1 ); #endif GenFx( self, bucket, matches, yInput, metaIn, yOut, metaOut ); @@ -474,17 +484,17 @@ private: _fxTime += TimerEndTicks( timer ); #if _VALIDATE_Y - if( self->IsControlThread() ) - { - if( _yRef.Ptr() == nullptr ) - { - _yRef = Span( bbcvirtallocboundednuma( 1ull << 32 ), 1ull << 32 ); - _yRefWriter = _yRef; - } - - _yTmp.SliceSize( totalMatches ).CopyTo( _yRefWriter ); - _yRefWriter = _yRefWriter.Slice( totalMatches ); - } + // if( self->IsControlThread() ) + // { + // if( _yRef.Ptr() == nullptr ) + // { + // _yRef = Span( bbcvirtallocboundednuma( 1ull << 32 ), 1ull << 32 ); + // _yRefWriter = _yRef; + // } + + // _yTmp.SliceSize( totalMatches ).CopyTo( _yRefWriter ); + // _yRefWriter = _yRefWriter.Slice( totalMatches ); + // } #endif WriteEntries( self, bucket, (uint32)_tableEntryCount + matchOffset, yOut, metaOut, _yWriteBuffer, _metaWriteBuffer, _indexWriteBuffer ); @@ -672,7 +682,9 @@ private: //----------------------------------------------------------- void GenCrossBucketFx( Job* self, const uint32 bucket ) { - auto& info = _matcher.GetCrossBucketInfo( bucket-1 ); + ASSERT( bucket < _numBuckets ); + + auto& info = _matcher.GetCrossBucketInfo( bucket ); if( info.matchCount < 1 ) return; @@ -1061,15 +1073,11 @@ private: } else if constexpr( MetaInMulti == 3 ) { - // const uint64 l0 = (uint64)metaIn[left ].m0 | ( (uint64)metaIn[left ].m1 << 32 ); - // const uint64 l1 = metaIn[left ].m2; - // const uint64 r0 = (uint64)metaIn[right].m0 | ( (uint64)metaIn[right].m1 << 32 ); - // const uint64 r1 = metaIn[right].m2; const uint64 l0 = metaIn[left ].m0; const uint64 l1 = metaIn[left ].m1 & 0xFFFFFFFF; const uint64 r0 = metaIn[right].m0; const uint64 r1 = metaIn[right].m1 & 0xFFFFFFFF; - + input[0] = Swap64( y << 26 | l0 >> 38 ); input[1] = Swap64( l0 << 26 | l1 >> 6 ); input[2] = Swap64( l1 << 58 | r0 >> 6 ); @@ -1077,10 +1085,6 @@ private: } else if constexpr( MetaInMulti == 4 ) { - // const uint64 l0 = metaInA[left ]; - // const uint64 l1 = metaInB[left ]; - // const uint64 r0 = metaInA[right]; - // const uint64 r1 = metaInB[right]; const K32Meta4 l = metaIn[left]; const K32Meta4 r = metaIn[right]; @@ -1114,11 +1118,6 @@ private: mOut.m0 = h0 << ySize | h1 >> 26; mOut.m1 = ((h1 << 6) & 0xFFFFFFC0) | h2 >> 58; - - // uint64 m0 = h0 << ySize | h1 >> 26; - // mOut.m0 = (uint32)m0; - // mOut.m0 = (uint32)(m0 >> 32); - // mOut.m2 = (uint32)( ((h1 << 6) & 0xFFFFFFC0) | h2 >> 58 ); } else if constexpr ( MetaOutMulti == 4 && MetaInMulti != 2 ) // In = 2 is calculated above with L + R { @@ -1325,14 +1324,17 @@ private: }; - #if _VALIDATE_Y //----------------------------------------------------------- template -void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context ) +void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& context + #if BB_DP_FP_MATCH_X_BUCKET + ,const Span crossBucketEntriesIn + #endif + ) { - if( table > TableId::Table2 ) + if( table > TableId::Table1 && table < TableId::Table7 ) { Log::Line( "[Validating table y %u]", table+1 ); @@ -1342,17 +1344,21 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co ioQueue.SeekBucket( fileId, 0, SeekOrigin::Begin ); ioQueue.CommitCommands(); - Span yRef = _yRef.SliceSize( context.entryCounts[(int)table] ); - Span yTmp = bbcvirtallocboundednuma_span( yRef.Length() ); + Span yRef = bbcvirtallocboundednuma_span( 1ull << 32 );// context.entryCounts[(int)table] ); //_yRef.SliceSize( context.entryCounts[(int)table] ); + Span yTmp = bbcvirtallocboundednuma_span( yRef.Length() ); - // Sort ref + // Load ref { - Log::Line( " Sorting ref" ); - RadixSort256::Sort( *context.threadPool, yRef.Ptr(), yTmp.Ptr(), yRef.Length() ); + Log::Line( " Loading ref" ); + Debug::LoadYRefTable( table, yRef ); } - // Read + // Read our entries { + const uint32 k = 32; + const uint32 bucketBits = bblog2( _numBuckets ); + const uint32 yBits = k + kExtraBits - bucketBits; + Span reader = yTmp.SliceSize( yRef.Length() / 2 ); Span tmp = yTmp.Slice( yRef.Length() / 2 ); @@ -1367,11 +1373,15 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co ioQueue.CommitCommands(); fence.Wait(); + #if BB_DP_FP_MATCH_X_BUCKET + bucketReader = crossBucketEntriesIn[bucket].CopyYAndExtend( bucketReader ); + #endif + // Sort RadixSort256::Sort( *context.threadPool, bucketReader.Ptr(), tmp.As().Ptr(), bucketReader.Length() ); // Expand - const uint64 yMask = ((uint64)bucket) << 32; + const uint64 yMask = ((uint64)bucket) << yBits; Span yValues = tmp; for( uint32 i = 0; i < bucketReader.Length(); i++ ) @@ -1397,7 +1407,7 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co ioQueue.CommitCommands(); } - _yRefWriter = _yRef; + // _yRefWriter = _yRef; } #endif From 9658c199cca355565d6fd9b5973c733e06302c33 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 26 Jun 2022 21:37:21 -0500 Subject: [PATCH 50/91] Adding some code for pair validation against diskplot unbounded pairs. --- src/plotdisk/DiskPlotConfig.h | 20 +++- src/plotdisk/DiskPlotDebug.h | 167 +++++++++++++++++++++++++++++++- src/plotdisk/DiskPlotPhase1.cpp | 2 + src/plotdisk/k32/FxBounded.inl | 119 +++-------------------- 4 files changed, 196 insertions(+), 112 deletions(-) diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 35ff1471..373ffa16 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -74,6 +74,24 @@ #define BB_DP_DBG_P3_KEEP_FILES 1 // For testing correctness: Allow cross-bucket matches. - // #define BB_DP_FP_MATCH_X_BUCKET 1 + #define BB_DP_FP_MATCH_X_BUCKET 1 + + // Dump pairs written raw and in global form to a file + #define BB_DP_DBG_DUMP_PAIRS 1 + #if BB_DP_DBG_DUMP_PAIRS + #define BB_DBG_DumpPairs( numBuckets, table, context ) Debug::DumpPairs( table, context ) + #else + #define BB_DBG_DumpPairs( numBuckets, table, context ) + #endif + + // Validate table pairs against dumped pairs + #define BB_DP_DBG_VALIDATE_BOUNDED_PAIRS 1 + #if BB_DP_DBG_VALIDATE_BOUNDED_PAIRS + #define BB_DBG_ValidateBoundedPairs( numBuckets, table, context ) Debug::ValidateK32Pairs( table, context ) + #else + #define BB_DBG_ValidateBoundedPairs( numBuckets, table, context ) + #endif + + #endif diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 5206a217..50d1c7a8 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -7,6 +7,8 @@ #include "threading/MTJob.h" #include "plotdisk/DiskPlotInfo.h" #include "plotdisk/DiskPlotContext.h" +#include "plotdisk/DiskPairReader.h" +#include "plotdisk/BlockWriter.h" #include "plotdisk/jobs/IOJob.h" #include "io/FileStream.h" #include "util/BitView.h" @@ -51,7 +53,10 @@ namespace Debug void ValidatePairs( DiskPlotContext& context, const TableId table ); template - void ValidateK32Pairs( DiskPlotContext& context, const TableId table ); + void ValidateK32Pairs( const TableId table, DiskPlotContext& context ); + + template + void DumpPairs( const TableId table, DiskPlotContext& context ); } template @@ -320,7 +325,6 @@ inline void Debug::ValidatePairs( DiskPlotContext& context, const TableId table uint64 refCount = 0; Pair* refPairs = nullptr; - { char path[1024]; sprintf( path, "%sp1.t%d.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); @@ -467,7 +471,162 @@ inline void Debug::ValidatePairs( DiskPlotContext& context, const TableId table //----------------------------------------------------------- template -void Debug::ValidateK32Pairs( DiskPlotContext& context, const TableId table ) +void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) +{ + Log::Line( "[DEBUG: Validating pairs for table %u]", table+1 ); + + const uint32 _k = 32; + const uint32 _maxEntriesPerBucket = ( ( 1ull << _k ) / _numBuckets ) * 2; + + const uint64 entryCount = context.entryCounts[(int)table]; + Span reference = bbcvirtallocboundednuma_span( entryCount ); + Span bucketPairs = bbcvirtallocboundednuma_span( _maxEntriesPerBucket ); + + Log::Line( " Reading reference table." ); + { + char path[1024]; + sprintf( path, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table ); + + FileStream dbgDir; + FatalIf( !dbgDir.Open( path, FileMode::Open, FileAccess::Read ), + "Failed to open debug directory at '%s'.", BB_DP_DBG_REF_DIR ); + + void* block = bbvirtallocbounded( dbgDir.BlockSize() ); + const size_t readSize = sizeof( Pair ) * entryCount; + + int err; + FatalIf( !IOJob::ReadFromFile( path, reference.Ptr(), readSize, block, dbgDir.BlockSize(), err ), + "Failed to read from refeerence pairs file at '%' with error: %d", path, err ); + + bbvirtfreebounded( block ); + } + + Log::Line( " Validating..." ); + const size_t heapSize = 41ull GB; + const byte* heap = bbvirtallocboundednuma( heapSize ); + + Fence fence; + StackAllocator allocator( heap, heapSize ); + DiskPairAndMapReader<_numBuckets, true> reader( context, context.fpThreadCount, fence, table, allocator, true ); + + Span const refPairs = reference; + + const int32 lTable = (int32)table-1; + + uint32 offset = 0; + uint64 iGlobal = 0; + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + Log::Line( " Bucket %u", bucket ); + + Span pairs = bucketPairs; + + Duration _; + reader.LoadNextBucket(); + pairs.length = reader.UnpackBucket( bucket, pairs.Length(), nullptr, _ ); + + // Validate + for( uint64 i = 0; i < pairs.Length(); i++ ) + { + const Pair ref = reference[i]; + const Pair entry = pairs[i]; + + ASSERT( ref.left == ref.left && ref.right == entry.right ); + } + + // Apply offset & go to next bucket + offset += context.bucketCounts[lTable][bucket]; + + refPairs = refPairs.Slice( pairs.Length() ); + iGlobal += pairs.Length(); + } + + // Cleanup + bbvirtfreebounded( heap ); + bbvirtfreebounded( reference.Ptr() ); + bbvirtfreebounded( bucketPairs.Ptr() ); + + Log::Line( "[DEBUG: Completed]" ); +} + +//----------------------------------------------------------- +template +void Debug::DumpPairs( const TableId table, DiskPlotContext& context ) { + Log::Line( "[DEBUG: Dumping pairs for table %u]", table+1 ); + + char pairsPath[1024]; + sprintf( pairsPath, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); + + FileStream pairsFile; + FatalIf( !pairsFile.Open( pairsPath, FileMode::OpenOrCreate, FileAccess::Write, FileFlags::NoBuffering | FileFlags::LargeFile ), + "Failed to open pairs file at '%s'.", pairsPath ); + + const FileId fileId = FileId::T1 + (FileId)table; + context.ioQueue->SeekFile( fileId, 0, 0, SeekOrigin::Begin ); + context.ioQueue->CommitCommands(); + + void* block = bbvirtallocbounded( pairsFile.BlockSize() ); + Span pairTable = bbcvirtallocboundednuma_span( context.entryCounts[(int)table] ); + + const size_t heapSize = 4ull GB; + byte* heap = bbvirtallocboundednuma( heapSize ); + + Fence fence; + StackAllocator allocator( heap, heapSize ); + + uint64 pairCount = 0; + + // Read + { + Span pairs = pairTable; + DiskPairAndMapReader<_numBuckets, _bounded> reader( context, context.fpThreadCount, fence, table, allocator, true ); + + const int lTable = (int)table-1; + uint32 offset = 0; + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + reader.LoadNextBucket(); + + Duration _; + const uint64 pairsRead = reader.UnpackBucket( bucket, pairs.Ptr(), nullptr, _ ); + ASSERT( pairsRead <= pairs.Length() ); + + // Offset pairs globally + Span bucketPairs = pairs.SliceSize( pairsRead ); + for( uint64 i = 0; i < bucketPairs.Length(); i++ ) + { + auto p = bucketPairs[i]; + p.left += offset; + p.right += offset; + + bucketPairs[i] = p; + } + + pairCount += pairsRead; + pairs = pairs.Slice( pairsRead ); + + offset += context.bucketCounts[lTable][bucket]; + } + + ASSERT( pairs.Length() == 0 ); + } + + // Write unpacked + { + int err; + const size_t sizeWrite = sizeof( Pair ) * pairTable.Length(); + + FatalIf( !IOJob::WriteToFile( pairsFile, pairTable.Ptr(), sizeWrite, block, pairsFile.BlockSize(), err ), + "Failed to write to pairs file '%s' with error: %d", pairsPath, err ); + } + + // Cleanup + bbvirtfreebounded( block ); + bbvirtfreebounded( pairTable.Ptr() ); + bbvirtfreebounded( heap ); + + Log::Line( "[DEBUG] Completed." ); +} -} \ No newline at end of file diff --git a/src/plotdisk/DiskPlotPhase1.cpp b/src/plotdisk/DiskPlotPhase1.cpp index 96def02f..4a2d0cc8 100644 --- a/src/plotdisk/DiskPlotPhase1.cpp +++ b/src/plotdisk/DiskPlotPhase1.cpp @@ -402,6 +402,8 @@ void DiskPlotPhase1::ForwardPropagateBuckets() Debug::ValidateYForTable( _fxOut, *_cx.ioQueue, *_cx.threadPool, _cx.bucketCounts[(int)table] ); Debug::ValidatePairs<256>( _cx, table ); #endif + + BB_DBG_DumpPairs( _numBuckets, table, _cx ); } //----------------------------------------------------------- diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 24ef8b1f..338acd4f 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -318,14 +318,17 @@ public: #if _DEBUG // ValidateIndices(); - #endif - #if _VALIDATE_Y - DbgValidateY<_numBuckets>( rTable, _yId[1], _context - #if BB_DP_FP_MATCH_X_BUCKET - , _crossBucketEntriesOut - #endif - ); - #endif + + #if _VALIDATE_Y + DbgValidateY<_numBuckets>( rTable, _yId[1], _context + #if BB_DP_FP_MATCH_X_BUCKET + , _crossBucketEntriesOut + #endif + ); + #endif + + BB_DBG_ValidateBoundedPairs( _numBuckets, rTable, _context ); + #endif // _DEBUG } private: @@ -1312,15 +1315,6 @@ public: Duration _distributeTime = Duration::zero(); Duration _matchTime = Duration::zero(); Duration _fxTime = Duration::zero(); - -private: - -#if _DEBUG - - #if DBG_VALIDATE_TABLES - uint64 _dbgPairOffset = 0; - #endif -#endif }; @@ -1336,7 +1330,7 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co { if( table > TableId::Table1 && table < TableId::Table7 ) { - Log::Line( "[Validating table y %u]", table+1 ); + Log::Line( "[DEBUG: Validating table y %u]", table+1 ); DiskBufferQueue& ioQueue = *context.ioQueue; Fence fence; @@ -1412,92 +1406,3 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co #endif -//----------------------------------------------------------- -template -void DbgValidatePairs( const TableId table, const uint32 bucket, - const Span pairs, const Span yIn, const Span metas, - const Span yOut ) -{ - for( size_t i = 0; i < pairs.Length(); i++ ) - { - // const Pair pair = pairs[i]; - // const uint64 y = ys [pair.left]; - // const TMeta metaL = metas[pair.left]; - // const TMeta metaR = metas[pair.right]; - - - - // - // ASSERT( ) - } -} - -#if DBG_VALIDATE_TABLES - -//----------------------------------------------------------- -template -inline void DbgValidatePlotTable( const Span pairs, const Span yIn ) -{ - -} - -//----------------------------------------------------------- -template -inline void DbgValidatePlotTable( const Span pairs, const Span yIn ) -{ - using TMetaIn = typename K32MetaType::In; - using TMetaOut = typename K32MetaType::Out; -} - -//----------------------------------------------------------- -inline void DbgValidatePlot( DiskPlotContext& context, const DebugPlot& dbgPlot ) -{ - // Span _f7s = dbgPlot.f7; - - // AnonMTJob::Run( *context.threadPool, [=]( AnonMTJob* self ){ - - // uint64 count, offset, end; - // GetThreadOffsets( self, (uint64)_f7s.Length(), count, offset, end ); - - // // Span f7s = _f7s.Slice( offset, count ); - - // uint64 fullProof[PROOF_X_COUNT]; - // Pair backPtrs [PROOF_X_COUNT/2]; - - // for( uint64 i = offset; i < end; i++ ) - // { - // const uint32 f7 = _f7s[i]; - - // // Pull full proof from back points - // uint32 ptrCount = 1; - // backPtrs[0] = ; - // for( TableId table = TableId::Table7; table > TableId::Table1; table-- ) - // { - // uint32 dst = 0; - // for( uint32 p = 0; p < ptrCount; p++ ) - // { - // dbgPlot.backPointers[6][p] - - // dst += 2; - // } - // ptrCount <<= 1; - // } - - // } - // }); - - // Span yIn; - // Span yOut; - // Span metaIn; - // Span metaOut; - - // DbgValidatePlotTable( dbgPlot ); - - // for( TableId rTable = TableId::Table2; rTable <= TableId::Table7; rTable++ ) - // { - - // } -} - -#endif - From acc1d215230ae970bcce04dfc25c8a8ca75757ef Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sun, 26 Jun 2022 22:32:32 -0500 Subject: [PATCH 51/91] Finished up cross-bucket pair serialization. Added test for pairs --- src/plotdisk/DiskPlotDebug.h | 24 ++++++----- src/plotdisk/k32/FxBounded.inl | 74 ++++++++++++++++++---------------- src/plotting/PlotTypes.h | 12 ++++++ 3 files changed, 66 insertions(+), 44 deletions(-) diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 50d1c7a8..071f7caa 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -473,11 +473,15 @@ inline void Debug::ValidatePairs( DiskPlotContext& context, const TableId table template void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) { - Log::Line( "[DEBUG: Validating pairs for table %u]", table+1 ); + Log::Line( "[DEBUG] Validating pairs for table %u", table+1 ); const uint32 _k = 32; const uint32 _maxEntriesPerBucket = ( ( 1ull << _k ) / _numBuckets ) * 2; + const FileId fileId = FileId::T1 + (FileId)table; + context.ioQueue->SeekFile( fileId, 0, 0, SeekOrigin::Begin ); + context.ioQueue->CommitCommands(); + const uint64 entryCount = context.entryCounts[(int)table]; Span reference = bbcvirtallocboundednuma_span( entryCount ); Span bucketPairs = bbcvirtallocboundednuma_span( _maxEntriesPerBucket ); @@ -485,10 +489,10 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) Log::Line( " Reading reference table." ); { char path[1024]; - sprintf( path, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table ); + sprintf( path, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); FileStream dbgDir; - FatalIf( !dbgDir.Open( path, FileMode::Open, FileAccess::Read ), + FatalIf( !dbgDir.Open( BB_DP_DBG_REF_DIR, FileMode::Open, FileAccess::Read ), "Failed to open debug directory at '%s'.", BB_DP_DBG_REF_DIR ); void* block = bbvirtallocbounded( dbgDir.BlockSize() ); @@ -496,20 +500,20 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) int err; FatalIf( !IOJob::ReadFromFile( path, reference.Ptr(), readSize, block, dbgDir.BlockSize(), err ), - "Failed to read from refeerence pairs file at '%' with error: %d", path, err ); + "Failed to read from refeerence pairs file at '%s' with error: %d", path, err ); bbvirtfreebounded( block ); } Log::Line( " Validating..." ); const size_t heapSize = 41ull GB; - const byte* heap = bbvirtallocboundednuma( heapSize ); + void* heap = bbvirtallocboundednuma( heapSize ); Fence fence; StackAllocator allocator( heap, heapSize ); DiskPairAndMapReader<_numBuckets, true> reader( context, context.fpThreadCount, fence, table, allocator, true ); - Span const refPairs = reference; + Span refPairs = reference; const int32 lTable = (int32)table-1; @@ -524,7 +528,7 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) Duration _; reader.LoadNextBucket(); - pairs.length = reader.UnpackBucket( bucket, pairs.Length(), nullptr, _ ); + pairs.length = reader.UnpackBucket( bucket, pairs.Ptr(), nullptr, _ ); // Validate for( uint64 i = 0; i < pairs.Length(); i++ ) @@ -532,7 +536,7 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) const Pair ref = reference[i]; const Pair entry = pairs[i]; - ASSERT( ref.left == ref.left && ref.right == entry.right ); + ASSERT( ref.left == entry.left && ref.right == entry.right ); } // Apply offset & go to next bucket @@ -547,14 +551,14 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) bbvirtfreebounded( reference.Ptr() ); bbvirtfreebounded( bucketPairs.Ptr() ); - Log::Line( "[DEBUG: Completed]" ); + Log::Line( "[DEBUG] Completed" ); } //----------------------------------------------------------- template void Debug::DumpPairs( const TableId table, DiskPlotContext& context ) { - Log::Line( "[DEBUG: Dumping pairs for table %u]", table+1 ); + Log::Line( "[DEBUG] Dumping pairs for table %u", table+1 ); char pairsPath[1024]; sprintf( pairsPath, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 338acd4f..b0bfc696 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -208,6 +208,13 @@ public: // _pairsL = allocator.CAllocSpan( entriesPerBucket ); // _pairsR = allocator.CAllocSpan( entriesPerBucket ); + + #if BB_DP_FP_MATCH_X_BUCKET + { + const size_t crossBucketPairAllocSize = (size_t)_pairBitSize * BB_DP_CROSS_BUCKET_MAX_ENTRIES; + _crossBucketWriteBuffer = allocator.AllocT( crossBucketPairAllocSize, t1BlockSize ); + } + #endif } // Generate fx for a whole table @@ -418,10 +425,6 @@ private: WritePairs( self, bucket, totalMatches, matches, matchOffset ); - #if DBG_VALIDATE_TABLES - _dbgPlot.WritePairs( self, rTable, matchOffset, matches, _mapOffset, totalMatches ); - #endif - /// /// Sort meta on Y /// @@ -637,13 +640,6 @@ private: _matchTime += TimerEndTicks( timer ); } self->EndLockBlock(); - - - // Write cross-bucket pairs to disk - #if BB_DP_FP_MATCH_X_BUCKET - if( bucket > 0 ) - WriteCrossBucketPairs( self, bucket-1 ); - #endif return matches; } @@ -659,27 +655,34 @@ private: //----------------------------------------------------------- void WriteCrossBucketPairs( Job* self, const uint32 bucket ) { - auto& info = _matcher.GetCrossBucketInfo( bucket-1 ); + ASSERT( bucket < _numBuckets ); + ASSERT( self->JobId() == 0 ); // Only to be called by the control thread + auto& info = _matcher.GetCrossBucketInfo( bucket ); if( info.matchCount < 1 ) return; + + const Span pairs( info.pair, info.matchCount ); + const uint32 offset = _context.bucketCounts[(int)rTable-1][bucket]; + + // Apply pair offset + for( uint32 i = 0; i < info.matchCount; i++ ) + pairs[i].AddOffset( offset ); - if( self->BeginLockBlock() ) - { - const uint32 offset = _tableEntryCount; - const Span pairs( info.pair, info.matchCount ); - - // _tableEntryCount += info.matchCount; - // #TODO: How do we handle this? We need to wait on a fence, but how? - // _pairWriteFence.Wait( bucket ); - // _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer ); - // BitWriter writer = _pairBitWriter.GetWriter( 0, dstOffset * _pairBitSize ); - // PackPairs( self, pairs, writer ); - // _pairBitWriter.Submit(); - // _ioQueue.SignalFence( _pairWriteFence, bucket + 1 ); - // _ioQueue.CommitCommands(); - } - self->EndLockBlock(); + // Bit-serialize + uint64 bitBucketSizes = pairs.Length() * _pairBitSize; + _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _crossBucketWriteBuffer ); + + BitWriter writer = _pairBitWriter.GetWriter( 0, 0 ); + PackPairs( self, pairs, writer ); + + // #TODO: Keep a different buffer? But for now, we have to remove the offsets, as we + // still have to perform cross-bucket fx with them + for( uint32 i = 0; i < info.matchCount; i++ ) + pairs[i].SubstractOffset( offset ); + + // Submit to disk + _pairBitWriter.Submit(); } //----------------------------------------------------------- @@ -749,24 +752,25 @@ private: const Span matches, const uint64 dstOffset ) { ASSERT( dstOffset + matches.length <= totalMatchCount ); - - // Need to wait for our write buffer to be ready to use again + if( self->BeginLockBlock() ) { + // Wait for our write buffer to be ready to use again if( bucket > 0 ) { - // Write crosss-bucket values pairs first, which belong to the previous bucket - _pairWriteFence.Wait( bucket ); + + #if BB_DP_FP_MATCH_X_BUCKET + WriteCrossBucketPairs( self, bucket - 1 ); + #endif } + // Ready the bit-writer for serialization uint64 bitBucketSizes = totalMatchCount * _pairBitSize; _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer ); } self->EndLockBlock(); - // #TOOD: Write pairs raw? Or bucket-relative? Maybe raw for now - // #NOTE: For now we write compressed as in standard FP. BitWriter writer = _pairBitWriter.GetWriter( 0, dstOffset * _pairBitSize ); @@ -1306,6 +1310,8 @@ private: #if BB_DP_FP_MATCH_X_BUCKET Span _crossBucketEntriesIn; Span _crossBucketEntriesOut; + + byte* _crossBucketWriteBuffer = nullptr; #endif public: diff --git a/src/plotting/PlotTypes.h b/src/plotting/PlotTypes.h index 85e634fa..b028e6a9 100644 --- a/src/plotting/PlotTypes.h +++ b/src/plotting/PlotTypes.h @@ -11,5 +11,17 @@ struct Pair { uint32 left; uint32 right; + + inline void AddOffset( const uint32 offset ) + { + left += offset; + right += offset; + } + + inline void SubstractOffset( const uint32 offset ) + { + left -= offset; + right -= offset; + } }; static_assert( sizeof( Pair ) == 8, "Invalid Pair struct." ); \ No newline at end of file From 846ae819e4e8549730609df5078815a63a5c982e Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 28 Jun 2022 06:21:54 -0500 Subject: [PATCH 52/91] Fixed issues with pair validation, however, pairs still not validating in table 4. --- .vscode/launch.json | 4 ++-- src/plotdisk/DiskPairReader.h | 2 +- src/plotdisk/DiskPlotDebug.h | 8 +++----- src/plotdisk/k32/FxBounded.inl | 11 ++++++----- src/plotting/PlotTypes.h | 8 ++++++-- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a9cb2689..dd2d391f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -91,9 +91,9 @@ // "--cache", "64G", // "-s", "--k32-bounded", - "-b", "64", + // "-b", "64", // "-b", "128", - // "-b", "256", + "-b", "256", "--c-threads", "26", "--p2-threads", "24", diff --git a/src/plotdisk/DiskPairReader.h b/src/plotdisk/DiskPairReader.h index 09b4ab98..16bb2d62 100644 --- a/src/plotdisk/DiskPairReader.h +++ b/src/plotdisk/DiskPairReader.h @@ -243,7 +243,7 @@ struct DiskPairAndMapReader static constexpr uint32 _extraBuckets = _bounded ? 0 : 1; static constexpr uint32 _k = _K; static constexpr uint32 _savedBits = bblog2( _numBuckets ); - static constexpr uint32 _lBits = ( _bounded ? _k : _k + 1 ) - _savedBits; + static constexpr uint32 _lBits = _k + 1 - _savedBits; static constexpr uint32 _rBits = 9; static constexpr uint32 _pairBits = _lBits + _rBits; diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 071f7caa..ecf35c4c 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -232,7 +232,6 @@ inline void Debug::ValidateYForTable( const FileId fileId, DiskBufferQueue& queu bbvirtfree( tmp ); } - //----------------------------------------------------------- template inline bool Debug::LoadRefTableByName( const char* fileName, T*& buffer, uint64& outEntryCount ) @@ -505,7 +504,6 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) bbvirtfreebounded( block ); } - Log::Line( " Validating..." ); const size_t heapSize = 41ull GB; void* heap = bbvirtallocboundednuma( heapSize ); @@ -522,7 +520,7 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { - Log::Line( " Bucket %u", bucket ); + Log::Line( " Validating Bucket %u", bucket ); Span pairs = bucketPairs; @@ -533,8 +531,8 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) // Validate for( uint64 i = 0; i < pairs.Length(); i++ ) { - const Pair ref = reference[i]; - const Pair entry = pairs[i]; + const Pair ref = refPairs[i]; + const Pair entry = pairs[i].AddOffset( offset ); ASSERT( ref.left == entry.left && ref.right == entry.right ); } diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index b0bfc696..672b515b 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -70,7 +70,7 @@ class DiskPlotFxBounded static constexpr uint64 _maxTableEntries = (1ull << _k) - 1; static constexpr uint32 _bucketBits = bblog2( _numBuckets ); static constexpr uint32 _pairsMaxDelta = 512; - static constexpr uint32 _pairsLeftBits = _k - _bucketBits; + static constexpr uint32 _pairsLeftBits = _k - _bucketBits + 1; // Buckets may overflow, so need an extra bit static constexpr uint32 _pairsRightBits = bblog2( _pairsMaxDelta ); static constexpr uint32 _pairBitSize = _pairsLeftBits + _pairsRightBits; @@ -629,7 +629,7 @@ private: // // Match this bucket's matches // _matcher.Match( self, bucket, yEntries, _pairs[id] ); - const uint32 maxMatchesPerThread =_entriesPerBucket / threadCount; + const uint32 maxMatchesPerThread = _entriesPerBucket / threadCount; _pairs[id] = _pairBuffer.Slice( maxMatchesPerThread * id, maxMatchesPerThread ); auto matches = _matcher.Match( self, bucket, yEntries, groupIndices, _pairs[id] ); @@ -663,7 +663,7 @@ private: return; const Span pairs( info.pair, info.matchCount ); - const uint32 offset = _context.bucketCounts[(int)rTable-1][bucket]; + const uint32 offset = info.matchOffset; // Apply pair offset for( uint32 i = 0; i < info.matchCount; i++ ) @@ -745,6 +745,7 @@ private: } self->EndLockBlock(); } + #endif // BB_DP_FP_MATCH_X_BUCKET //----------------------------------------------------------- @@ -766,7 +767,7 @@ private: } // Ready the bit-writer for serialization - uint64 bitBucketSizes = totalMatchCount * _pairBitSize; + uint64 bitBucketSizes = (uint64)totalMatchCount * _pairBitSize; _pairBitWriter.BeginWriteBuckets( &bitBucketSizes, _pairsWriteBuffer ); } self->EndLockBlock(); @@ -775,7 +776,7 @@ private: BitWriter writer = _pairBitWriter.GetWriter( 0, dstOffset * _pairBitSize ); ASSERT( matches.Length() > 2 ); - PackPairs( self, matches.Slice( 0, 2 ), writer ); + PackPairs( self, matches.SliceSize( 2 ), writer ); self->SyncThreads(); PackPairs( self, matches.Slice( 2 ), writer ); diff --git a/src/plotting/PlotTypes.h b/src/plotting/PlotTypes.h index b028e6a9..6817b9ac 100644 --- a/src/plotting/PlotTypes.h +++ b/src/plotting/PlotTypes.h @@ -12,16 +12,20 @@ struct Pair uint32 left; uint32 right; - inline void AddOffset( const uint32 offset ) + inline Pair& AddOffset( const uint32 offset ) { left += offset; right += offset; + + return *this; } - inline void SubstractOffset( const uint32 offset ) + inline Pair& SubstractOffset( const uint32 offset ) { left -= offset; right -= offset; + + return *this; } }; static_assert( sizeof( Pair ) == 8, "Invalid Pair struct." ); \ No newline at end of file From a5947c36af6977e49103c37173f9fefa33f46fde Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 28 Jun 2022 21:21:32 -0500 Subject: [PATCH 53/91] Some debug changes, tracking changeset for y-validation regression. --- src/plotdisk/DiskPlotConfig.h | 12 +++- src/plotdisk/DiskPlotDebug.cpp | 82 +++++++++++++++++++++++ src/plotdisk/DiskPlotDebug.h | 3 + src/plotdisk/DiskPlotter.cpp | 97 +--------------------------- src/plotdisk/k32/DiskPlotBounded.cpp | 3 + src/plotdisk/k32/FxBounded.inl | 2 +- 6 files changed, 102 insertions(+), 97 deletions(-) diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 373ffa16..3886114d 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -57,7 +57,7 @@ // #define BB_DP_DBG_SKIP_TO_C_TABLES 1 // #define BB_DP_P1_SKIP_TO_TABLE 1 -// #define BB_DP_P1_START_TABLE TableId::Table4 +// #define BB_DP_P1_START_TABLE TableId::Table3 // Tmp file deletion (useful to keep around when developing) #if _DEBUG @@ -92,6 +92,16 @@ #define BB_DBG_ValidateBoundedPairs( numBuckets, table, context ) #endif + #define BB_DP_DBG_WriteTableCounts( context ) Debug::WriteTableCounts( context ) + #define BB_DP_DBG_ReadTableCounts( context ) Debug::ReadTableCounts( context ) +#else + #define BB_DP_DBG_WriteTableCounts( context ) + #define BB_DP_DBG_ReadTableCounts( context ) #endif + + + + + diff --git a/src/plotdisk/DiskPlotDebug.cpp b/src/plotdisk/DiskPlotDebug.cpp index 19263132..d2e680b0 100644 --- a/src/plotdisk/DiskPlotDebug.cpp +++ b/src/plotdisk/DiskPlotDebug.cpp @@ -614,7 +614,89 @@ void Debug::ValidateLinePoints( DiskPlotContext& context, TableId table, uint32 // void ValidatePark7( DiskBufferQueue& ioQueue, uint64 park7Size ) +//----------------------------------------------------------- +void Debug::WriteTableCounts( const DiskPlotContext& cx ) +{ + // Write bucket counts + FileStream bucketCounts, tableCounts, backPtrBucketCounts; + + if( bucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_READ_BUCKET_COUNT_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( bucketCounts.Write( cx.bucketCounts, sizeof( cx.bucketCounts ) ) != sizeof( cx.bucketCounts ) ) + Log::Error( "Failed to write to bucket counts file." ); + } + else + Log::Error( "Failed to open bucket counts file." ); + + if( tableCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_TABLE_COUNTS_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( tableCounts.Write( cx.entryCounts, sizeof( cx.entryCounts ) ) != sizeof( cx.entryCounts ) ) + Log::Error( "Failed to write to table counts file." ); + } + else + Log::Error( "Failed to open table counts file." ); + + if( backPtrBucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_PTR_BUCKET_COUNT_FNAME, FileMode::Create, FileAccess::Write ) ) + { + if( backPtrBucketCounts.Write( cx.ptrTableBucketCounts, sizeof( cx.ptrTableBucketCounts ) ) != sizeof( cx.ptrTableBucketCounts ) ) + Log::Error( "Failed to write to back pointer bucket counts file." ); + } + else + Log::Error( "Failed to open back pointer bucket counts file." ); +} + +//----------------------------------------------------------- +bool Debug::ReadTableCounts( DiskPlotContext& cx ) +{ + #if( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) + + FileStream bucketCounts, tableCounts, backPtrBucketCounts; + + if( bucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_READ_BUCKET_COUNT_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( bucketCounts.Read( cx.bucketCounts, sizeof( cx.bucketCounts ) ) != sizeof( cx.bucketCounts ) ) + { + Log::Error( "Failed to read from bucket counts file." ); + return false; + } + } + else + { + Log::Error( "Failed to open bucket counts file." ); + return false; + } + if( tableCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_TABLE_COUNTS_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( tableCounts.Read( cx.entryCounts, sizeof( cx.entryCounts ) ) != sizeof( cx.entryCounts ) ) + { + Log::Error( "Failed to read from table counts file." ); + return false; + } + } + else + { + Log::Error( "Failed to open table counts file." ); + return false; + } + + if( backPtrBucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_PTR_BUCKET_COUNT_FNAME, FileMode::Open, FileAccess::Read ) ) + { + if( backPtrBucketCounts.Read( cx.ptrTableBucketCounts, sizeof( cx.ptrTableBucketCounts ) ) != sizeof( cx.ptrTableBucketCounts ) ) + { + Fatal( "Failed to read from pointer bucket counts file." ); + } + } + else + { + Fatal( "Failed to open pointer bucket counts file." ); + } + + return true; + #else + return false; + #endif +} diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index ecf35c4c..155c7809 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -57,6 +57,9 @@ namespace Debug template void DumpPairs( const TableId table, DiskPlotContext& context ); + + void WriteTableCounts( const DiskPlotContext& context ); + bool ReadTableCounts( DiskPlotContext& context ); } template diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index d9392ac0..874be5e9 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -16,11 +16,6 @@ size_t ValidateTmpPathAndGetBlockSize( DiskPlotter::Config& cfg ); -#if _DEBUG - void DbgWriteTableCounts( DiskPlotContext& cx ); - bool DbgReadTableCounts( DiskPlotContext& cx ); -#endif - //----------------------------------------------------------- // DiskPlotter::DiskPlotter() @@ -161,7 +156,7 @@ void DiskPlotter::Plot( const PlotRequest& req ) _cx.ioQueue->OpenPlotFile( req.plotFileName, req.plotId, req.plotMemo, req.plotMemoSize ); #if ( _DEBUG && BB_DP_DBG_SKIP_PHASE_1 ) - DbgReadTableCounts( _cx ); + BB_DP_DBG_ReadTableCounts( _cx ); #endif Log::Line( "Started plot." ); @@ -187,7 +182,7 @@ void DiskPlotter::Plot( const PlotRequest& req ) } #if ( _DEBUG && !BB_DP_DBG_SKIP_PHASE_1 ) - DbgWriteTableCounts( _cx ); + BB_DP_DBG_WriteTableCounts( _cx ); #endif const double elapsed = TimerEnd( timer ); @@ -630,91 +625,3 @@ void DiskPlotter::PrintUsage() Log::Line( USAGE ); } - -#if _DEBUG - -//----------------------------------------------------------- -void DbgWriteTableCounts( DiskPlotContext& cx ) -{ - // Write bucket counts - FileStream bucketCounts, tableCounts, backPtrBucketCounts; - - if( bucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_READ_BUCKET_COUNT_FNAME, FileMode::Create, FileAccess::Write ) ) - { - if( bucketCounts.Write( cx.bucketCounts, sizeof( cx.bucketCounts ) ) != sizeof( cx.bucketCounts ) ) - Log::Error( "Failed to write to bucket counts file." ); - } - else - Log::Error( "Failed to open bucket counts file." ); - - if( tableCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_TABLE_COUNTS_FNAME, FileMode::Create, FileAccess::Write ) ) - { - if( tableCounts.Write( cx.entryCounts, sizeof( cx.entryCounts ) ) != sizeof( cx.entryCounts ) ) - Log::Error( "Failed to write to table counts file." ); - } - else - Log::Error( "Failed to open table counts file." ); - - if( backPtrBucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_PTR_BUCKET_COUNT_FNAME, FileMode::Create, FileAccess::Write ) ) - { - if( backPtrBucketCounts.Write( cx.ptrTableBucketCounts, sizeof( cx.ptrTableBucketCounts ) ) != sizeof( cx.ptrTableBucketCounts ) ) - Log::Error( "Failed to write to back pointer bucket counts file." ); - } - else - Log::Error( "Failed to open back pointer bucket counts file." ); -} - -//----------------------------------------------------------- -bool DbgReadTableCounts( DiskPlotContext& cx ) -{ - #if( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) - - FileStream bucketCounts, tableCounts, backPtrBucketCounts; - - if( bucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_READ_BUCKET_COUNT_FNAME, FileMode::Open, FileAccess::Read ) ) - { - if( bucketCounts.Read( cx.bucketCounts, sizeof( cx.bucketCounts ) ) != sizeof( cx.bucketCounts ) ) - { - Log::Error( "Failed to read from bucket counts file." ); - return false; - } - } - else - { - Log::Error( "Failed to open bucket counts file." ); - return false; - } - - if( tableCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_TABLE_COUNTS_FNAME, FileMode::Open, FileAccess::Read ) ) - { - if( tableCounts.Read( cx.entryCounts, sizeof( cx.entryCounts ) ) != sizeof( cx.entryCounts ) ) - { - Log::Error( "Failed to read from table counts file." ); - return false; - } - } - else - { - Log::Error( "Failed to open table counts file." ); - return false; - } - - if( backPtrBucketCounts.Open( BB_DP_DBG_TEST_DIR BB_DP_DBG_PTR_BUCKET_COUNT_FNAME, FileMode::Open, FileAccess::Read ) ) - { - if( backPtrBucketCounts.Read( cx.ptrTableBucketCounts, sizeof( cx.ptrTableBucketCounts ) ) != sizeof( cx.ptrTableBucketCounts ) ) - { - Fatal( "Failed to read from pointer bucket counts file." ); - } - } - else - { - Fatal( "Failed to open pointer bucket counts file." ); - } - - return true; - #else - return false; - #endif -} - -#endif // End #_DEBUG \ No newline at end of file diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 9ce638e9..a885f787 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -240,5 +240,8 @@ void K32BoundedPhase1::RunFx() Log::Line( "Completed table %u in %.2lf seconds with %.llu entries.", table+1, TimerEnd( timer ), _context.entryCounts[(int)table] ); Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( fx._tableIOWait ) ); + + + BB_DP_DBG_WriteTableCounts( _context ); } diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 672b515b..a610039c 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -14,7 +14,7 @@ #include "plotting/PlotValidation.h" #include "plotdisk/DiskPlotDebug.h" - // #define _VALIDATE_Y 1 + #define _VALIDATE_Y 1 #if _VALIDATE_Y // uint32 _refBucketCounts[BB_DP_MAX_BUCKET_COUNT]; // Span _yRef; From 119bae8dfe25454ddc3ebd1642cbe2be6e6c8fa6 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 29 Jun 2022 04:56:40 -0500 Subject: [PATCH 54/91] Implemented debug code to skip to a certain table for faster debugging validation errors. --- src/plotdisk/DiskBufferQueue.cpp | 82 ++++++++++++++++++++++++++++ src/plotdisk/DiskBufferQueue.h | 21 +++++++ src/plotdisk/DiskPlotConfig.h | 14 ++--- src/plotdisk/DiskPlotDebug.cpp | 3 +- src/plotdisk/DiskPlotter.cpp | 2 +- src/plotdisk/k32/DiskPlotBounded.cpp | 30 ++++++---- src/plotdisk/k32/FxBounded.inl | 2 +- 7 files changed, 131 insertions(+), 23 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index f6fa70d3..c237778d 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -469,6 +469,24 @@ void DiskBufferQueue::CompletePendingReleases() _workHeap.CompletePendingReleases(); } +#if _DEBUG +//----------------------------------------------------------- +void DiskBufferQueue::DebugWriteSliceSizes( const TableId table, const FileId fileId ) +{ + Command* cmd = GetCommandObject( Command::DBG_WriteSliceSizes ); + cmd->dbgSliceSizes.table = table; + cmd->dbgSliceSizes.fileId = fileId; +} + +//----------------------------------------------------------- +void DiskBufferQueue::DebugReadSliceSizes( const TableId table, const FileId fileId ) +{ + Command* cmd = GetCommandObject( Command::DBG_ReadSliceSizes ); + cmd->dbgSliceSizes.table = table; + cmd->dbgSliceSizes.fileId = fileId; +} +#endif + //----------------------------------------------------------- inline DiskBufferQueue::Command* DiskBufferQueue::GetCommandObject( Command::CommandType type ) { @@ -671,6 +689,15 @@ void DiskBufferQueue::ExecuteCommand( Command& cmd ) CmdTruncateBucket( cmd ); break; + #if _DEBUG + case Command::DBG_WriteSliceSizes: + CmdDbgWriteSliceSizes( cmd ); + break; + + case Command::DBG_ReadSliceSizes: + CmdDbgReadSliceSizes( cmd ); + break; + #endif default: ASSERT( 0 ); @@ -1071,6 +1098,61 @@ inline const char* DiskBufferQueue::DbgGetCommandName( Command::CommandType type } } +#if _DEBUG +//----------------------------------------------------------- +void DiskBufferQueue::CmdDbgWriteSliceSizes( const Command& cmd ) +{ + const FileId fileId = cmd.dbgSliceSizes.fileId;; + const char* fName = ( fileId == FileId::FX0 || fileId == FileId::FX1 ) ? "y" : + ( fileId == FileId::META0 || fileId == FileId::META1 ) ? "meta" : "index"; + + char path[1024]; + sprintf( path, "%st%d.%s.slices.tmp", BB_DP_DBG_TEST_DIR, (int)cmd.dbgSliceSizes.table+1, fName ); + + FileStream file; + FatalIf( !file.Open( path, FileMode::Create, FileAccess::Write ), "Failed to open '%s' for writing.", path ); + + FileSet& fileSet = _files[(int)cmd.dbgSliceSizes.fileId]; + const uint32 numBuckets = (uint32)fileSet.files.Length(); + + for( uint32 i = 0; i < numBuckets; i++ ) + { + auto slices = fileSet.sliceSizes[i]; + const size_t sizeWrite = sizeof( size_t ) * numBuckets; + + FatalIf( file.Write( slices.Ptr(), sizeWrite ) != sizeWrite, + "Failed to write slice size for table %d", (int)cmd.dbgSliceSizes.table+1 ); + } +} + +//----------------------------------------------------------- +void DiskBufferQueue::CmdDbgReadSliceSizes( const Command& cmd ) +{ + const FileId fileId = cmd.dbgSliceSizes.fileId;; + const char* fName = ( fileId == FileId::FX0 || fileId == FileId::FX1 ) ? "y" : + ( fileId == FileId::META0 || fileId == FileId::META1 ) ? "meta" : "index"; + + char path[1024]; + sprintf( path, "%st%d.%s.slices.tmp", BB_DP_DBG_TEST_DIR, (int)cmd.dbgSliceSizes.table+1, fName ); + + FileStream file; + FatalIf( !file.Open( path, FileMode::Open, FileAccess::Read ), "Failed to open '%s' for reading.", path ); + + FileSet& fileSet = _files[(int)cmd.dbgSliceSizes.fileId]; + const uint32 numBuckets = (uint32)fileSet.files.Length(); + + for( uint32 i = 0; i < numBuckets; i++ ) + { + auto slices = fileSet.sliceSizes[i]; + const size_t sizeRead = sizeof( size_t ) * numBuckets; + + FatalIf( file.Read( slices.Ptr(), sizeRead ) != sizeRead, + "Failed to read slice size for table %d", (int)cmd.dbgSliceSizes.table+1 ); + } +} + + +#endif /// /// File-Deleter Thread diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index 5503cabf..c8bebc9d 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -73,6 +73,9 @@ class DiskBufferQueue SignalFence, WaitForFence, TruncateBucket, + + DBG_WriteSliceSizes, // Read/Write slice sizes to disk. Used for skipping tables + DBG_ReadSliceSizes }; CommandType type; @@ -133,6 +136,14 @@ class DiskBufferQueue FileId fileId; ssize_t position; } truncateBucket; + + #if _DEBUG + struct + { + TableId table; + FileId fileId; + } dbgSliceSizes; + #endif }; }; @@ -230,6 +241,11 @@ class DiskBufferQueue const Span> SliceSizes( const FileId fileId ) const { return _files[(int)fileId].sliceSizes; } #endif + #if _DEBUG + void DebugWriteSliceSizes( const TableId table, const FileId fileId ); + void DebugReadSliceSizes( const TableId table, const FileId fileId ); + #endif + // byte* GetBufferForId( const FileId fileId, const uint32 bucket, const size_t size, bool blockUntilFreeBuffer = true ); // Release/return a chunk buffer that was in use, gotten by GetBuffer() @@ -319,6 +335,11 @@ class DiskBufferQueue static const char* DbgGetCommandName( Command::CommandType type ); + #if _DEBUG + void CmdDbgWriteSliceSizes( const Command& cmd ); + void CmdDbgReadSliceSizes( const Command& cmd ); + #endif + private: std::string _workDir1; // Temporary 1 directory in which we will store our long-lived temporary files diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 3886114d..3881ee92 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -42,9 +42,9 @@ // #define BB_DP_DBG_DONT_DELETE_TMP_FILES_PHASE 3 -#define BB_DP_DBG_READ_BUCKET_COUNT_FNAME "bucket_count.tmp" -#define BB_DP_TABLE_COUNTS_FNAME "table_counts.tmp" -#define BB_DP_DBG_PTR_BUCKET_COUNT_FNAME "ptr_bucket_count.tmp" +#define BB_DP_DBG_READ_BUCKET_COUNT_FNAME "bucket_count.tmp" +#define BB_DP_TABLE_COUNTS_FNAME "table_counts.tmp" +#define BB_DP_DBG_PTR_BUCKET_COUNT_FNAME "ptr_bucket_count.tmp" #define BB_DP_DBG_TEST_DIR "/home/harold/plot/dbg/" #define BB_DP_DBG_REF_DIR "/home/harold/plot/ref/" @@ -56,8 +56,8 @@ // #NOTE: BB_DP_DBG_SKIP_PHASE_1 Must be defined // #define BB_DP_DBG_SKIP_TO_C_TABLES 1 -// #define BB_DP_P1_SKIP_TO_TABLE 1 -// #define BB_DP_P1_START_TABLE TableId::Table3 +#define BB_DP_P1_SKIP_TO_TABLE 1 +#define BB_DP_P1_START_TABLE TableId::Table3 // Tmp file deletion (useful to keep around when developing) #if _DEBUG @@ -77,7 +77,7 @@ #define BB_DP_FP_MATCH_X_BUCKET 1 // Dump pairs written raw and in global form to a file - #define BB_DP_DBG_DUMP_PAIRS 1 + // #define BB_DP_DBG_DUMP_PAIRS 1 #if BB_DP_DBG_DUMP_PAIRS #define BB_DBG_DumpPairs( numBuckets, table, context ) Debug::DumpPairs( table, context ) #else @@ -85,7 +85,7 @@ #endif // Validate table pairs against dumped pairs - #define BB_DP_DBG_VALIDATE_BOUNDED_PAIRS 1 + // #define BB_DP_DBG_VALIDATE_BOUNDED_PAIRS 1 #if BB_DP_DBG_VALIDATE_BOUNDED_PAIRS #define BB_DBG_ValidateBoundedPairs( numBuckets, table, context ) Debug::ValidateK32Pairs( table, context ) #else diff --git a/src/plotdisk/DiskPlotDebug.cpp b/src/plotdisk/DiskPlotDebug.cpp index d2e680b0..d5c5406d 100644 --- a/src/plotdisk/DiskPlotDebug.cpp +++ b/src/plotdisk/DiskPlotDebug.cpp @@ -8,6 +8,7 @@ #include "jobs/IOJob.h" #include "DiskPlotContext.h" #include "DiskBufferQueue.h" +#include "plotdisk/k32/FpMatchBounded.inl" #define BB_DBG_WRITE_LP_BUCKET_COUNTS 1 @@ -700,5 +701,3 @@ bool Debug::ReadTableCounts( DiskPlotContext& cx ) - - diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 874be5e9..8ed7bcdd 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -155,7 +155,7 @@ void DiskPlotter::Plot( const PlotRequest& req ) _cx.ioQueue->OpenPlotFile( req.plotFileName, req.plotId, req.plotMemo, req.plotMemoSize ); - #if ( _DEBUG && BB_DP_DBG_SKIP_PHASE_1 ) + #if ( _DEBUG && ( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) ) BB_DP_DBG_ReadTableCounts( _cx ); #endif diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index a885f787..19fc84e0 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -126,22 +126,22 @@ void K32BoundedPhase1::RunWithBuckets() #if defined( _DEBUG ) && defined( BB_DP_P1_SKIP_TO_TABLE ) { - _context.entryCounts[0] = 1ull << 32; + ASSERT( _context.entryCounts[0] == 1ull << 32 ); ASSERT( BB_DP_P1_START_TABLE > TableId::Table2 ); startTable = BB_DP_P1_START_TABLE; + + { + Fence fence; + _ioQueue.DebugReadSliceSizes( startTable-1, (uint)(startTable-1) %2 == 0 ? FileId::FX0 : FileId::FX1 ); + _ioQueue.DebugReadSliceSizes( startTable-1, (uint)(startTable-1) %2 == 0 ? FileId::INDEX0 : FileId::INDEX1 ); + _ioQueue.DebugReadSliceSizes( startTable-1, (uint)(startTable-1) %2 == 0 ? FileId::META0 : FileId::META1 ); + _ioQueue.SignalFence( fence ); + _ioQueue.CommitCommands(); + fence.Wait(); + } } #else - // #TODO: TEST, removes - // for( uint32 i = 0; i < 0x7FFFFFFF; i++ ) - // { - // Log::Line( "Running F1 %u...", i ); RunF1<_numBuckets>(); - // _ioQueue.SeekBucket( FileId::FX0 , 0, SeekOrigin::Begin ); - // _ioQueue.SeekBucket( FileId::META0, 0, SeekOrigin::Begin ); - // _ioQueue.CommitCommands(); - // memset( _context.bucketCounts[0], 0, sizeof( _context.bucketCounts[0] ) ); - // _context.entryCounts[0] = 0; - // } #endif #if BB_DP_FP_MATCH_X_BUCKET @@ -241,7 +241,13 @@ void K32BoundedPhase1::RunFx() Log::Line( "Completed table %u in %.2lf seconds with %.llu entries.", table+1, TimerEnd( timer ), _context.entryCounts[(int)table] ); Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( fx._tableIOWait ) ); + #if _DEBUG + BB_DP_DBG_WriteTableCounts( _context ); - BB_DP_DBG_WriteTableCounts( _context ); + _ioQueue.DebugWriteSliceSizes( table, (uint)table %2 == 0 ? FileId::FX0 : FileId::FX1 ); + _ioQueue.DebugWriteSliceSizes( table, (uint)table %2 == 0 ? FileId::INDEX0 : FileId::INDEX1 ); + _ioQueue.DebugWriteSliceSizes( table, (uint)table %2 == 0 ? FileId::META0 : FileId::META1 ); + _ioQueue.CommitCommands(); + #endif } diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index a610039c..ad128b6b 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -1335,7 +1335,7 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co #endif ) { - if( table > TableId::Table1 && table < TableId::Table7 ) + if( table > TableId::Table2 && table < TableId::Table7 ) { Log::Line( "[DEBUG: Validating table y %u]", table+1 ); From 3d3c98af9739cc7b784ff907cc015bd0c86df3c0 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 6 Jul 2022 01:03:07 -0500 Subject: [PATCH 55/91] Fixed P1 issue where metadata came out corrupted. --- src/plotdisk/DiskFp.h | 22 +++++++++---- src/plotdisk/DiskPlotConfig.h | 25 ++++++++++---- src/plotdisk/DiskPlotDebug.cpp | 60 ++++++++++++++++++++++++++++++++++ src/plotdisk/DiskPlotDebug.h | 18 ++++++++++ src/plotdisk/FpGroupMatcher.h | 16 +++++---- src/plotdisk/k32/FxBounded.inl | 30 ++++++++--------- 6 files changed, 136 insertions(+), 35 deletions(-) diff --git a/src/plotdisk/DiskFp.h b/src/plotdisk/DiskFp.h index f70f530e..64afaa85 100644 --- a/src/plotdisk/DiskFp.h +++ b/src/plotdisk/DiskFp.h @@ -297,6 +297,8 @@ class DiskFp WriteMap( bucket, inEntryCount, map, (uint64*)_meta[1] ); + BB_DBG_DP_DumpUnboundedY( table-1, bucket, _context, Span( y, inEntryCount ) ); + const TMetaIn* inMeta = ( table == TableId::Table2 ) ? (TMetaIn*)map : meta; TYOut* outY = (TYOut*)_y[1]; @@ -305,16 +307,22 @@ class DiskFp // Match const int64 outEntryCount = MatchEntries( bucket, inEntryCount, y, inMeta, pairs ); - const int64 crossMatchCount = _crossBucketInfo.matchCount; + #if !BB_DP_DBG_UNBOUNDED_DISABLE_CROSS_BUCKET + const int64 crossMatchCount = _crossBucketInfo.matchCount; + #else + const int64 crossMatchCount = 0; + #endif const int64 writeEntrtyCount = outEntryCount + crossMatchCount; - if( bucket > 0 ) - { - ProcessCrossBucketEntries( bucket - 1, pairs - crossMatchCount, outY, outMeta ); - ASSERT( crossMatchCount <= std::numeric_limits::max() ); + #if !BB_DP_DBG_UNBOUNDED_DISABLE_CROSS_BUCKET + if( bucket > 0 ) + { + ProcessCrossBucketEntries( bucket - 1, pairs - crossMatchCount, outY, outMeta ); + ASSERT( crossMatchCount <= std::numeric_limits::max() ); - _context.ptrTableBucketCounts[(int)table][bucket-1] += (uint32)crossMatchCount; - } + _context.ptrTableBucketCounts[(int)table][bucket-1] += (uint32)crossMatchCount; + } + #endif WritePairsToDisk( bucket, writeEntrtyCount, pairs - crossMatchCount ); diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 3881ee92..c2cb1bc0 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -42,9 +42,9 @@ // #define BB_DP_DBG_DONT_DELETE_TMP_FILES_PHASE 3 -#define BB_DP_DBG_READ_BUCKET_COUNT_FNAME "bucket_count.tmp" -#define BB_DP_TABLE_COUNTS_FNAME "table_counts.tmp" -#define BB_DP_DBG_PTR_BUCKET_COUNT_FNAME "ptr_bucket_count.tmp" +#define BB_DP_DBG_READ_BUCKET_COUNT_FNAME "bucket_count.tmp" +#define BB_DP_TABLE_COUNTS_FNAME "table_counts.tmp" +#define BB_DP_DBG_PTR_BUCKET_COUNT_FNAME "ptr_bucket_count.tmp" #define BB_DP_DBG_TEST_DIR "/home/harold/plot/dbg/" #define BB_DP_DBG_REF_DIR "/home/harold/plot/ref/" @@ -56,8 +56,8 @@ // #NOTE: BB_DP_DBG_SKIP_PHASE_1 Must be defined // #define BB_DP_DBG_SKIP_TO_C_TABLES 1 -#define BB_DP_P1_SKIP_TO_TABLE 1 -#define BB_DP_P1_START_TABLE TableId::Table3 +// #define BB_DP_P1_SKIP_TO_TABLE 1 +// #define BB_DP_P1_START_TABLE TableId::Table3 // Tmp file deletion (useful to keep around when developing) #if _DEBUG @@ -71,10 +71,14 @@ // #define BB_DBG_SKIP_P3_S1 1 // #define BB_DP_DBG_P3_START_TABLE Table7 - #define BB_DP_DBG_P3_KEEP_FILES 1 + // DiskPlot Unbounded disable writing cross-bucket entries + #define BB_DP_DBG_UNBOUNDED_DISABLE_CROSS_BUCKET 1 // For testing correctness: Allow cross-bucket matches. - #define BB_DP_FP_MATCH_X_BUCKET 1 + // #define BB_DP_FP_MATCH_X_BUCKET 1 + + // Don't delete temporary files during phase 3 + #define BB_DP_DBG_P3_KEEP_FILES 1 // Dump pairs written raw and in global form to a file // #define BB_DP_DBG_DUMP_PAIRS 1 @@ -84,6 +88,13 @@ #define BB_DBG_DumpPairs( numBuckets, table, context ) #endif + // #define BB_DP_DBG_UNBOUNDED_DUMP_Y 1 + #if BB_DP_DBG_UNBOUNDED_DUMP_Y + #define BB_DBG_DP_DumpUnboundedY( table, bucket, context, y ) Debug::DumpDPUnboundedY( table, bucket, context, y ) + #else + #define BB_DBG_DP_DumpUnboundedY( table, bucket, context, y ) + #endif + // Validate table pairs against dumped pairs // #define BB_DP_DBG_VALIDATE_BOUNDED_PAIRS 1 #if BB_DP_DBG_VALIDATE_BOUNDED_PAIRS diff --git a/src/plotdisk/DiskPlotDebug.cpp b/src/plotdisk/DiskPlotDebug.cpp index d5c5406d..749041c6 100644 --- a/src/plotdisk/DiskPlotDebug.cpp +++ b/src/plotdisk/DiskPlotDebug.cpp @@ -699,5 +699,65 @@ bool Debug::ReadTableCounts( DiskPlotContext& cx ) #endif } +//----------------------------------------------------------- +void Debug::DumpDPUnboundedY( const TableId table, const uint32 bucket, const DiskPlotContext& context, const Span y ) +{ + if( y.Length() < 1 || table < TableId::Table2 ) + return; + char path[1024]; + sprintf( path, "%st%d.y-dp-unbounded.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); + + const FileMode mode = bucket > 0 ? FileMode::Open : FileMode::Create; + + FileStream file; + FatalIf( !file.Open( path, mode, FileAccess::Write ), + "Failed to open '%s' for writing.", path ); + FatalIf( !file.Seek( (int64)file.Size(), SeekOrigin::Begin ), "Failed to seek file '%s'.", path ); + + size_t sizeWrite = y.Length() * sizeof( uint64 ); + + Span yWrite = y; + while( sizeWrite ) + { + const ssize_t written = file.Write( yWrite.Ptr(), sizeWrite ); + FatalIf( written <= 0, "Failed to write with eerror %d to file '%s'.", file.GetError(), path ); + + sizeWrite -= (size_t)written; + + yWrite = yWrite.Slice( (size_t)written/sizeof( uint64 ) ); + } +} + +//----------------------------------------------------------- +void Debug::LoadDPUnboundedY( const TableId table, Span& inOutY ) +{ + // It's written unaligned for now, so we can determine the length by its size + char path[1024]; + sprintf( path, "%st%d.y-dp-unbounded.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); + + Log::Line( " Loading reference disk-plot Y table at '%s'.", path ); + + FileStream file; + FatalIf( !file.Open( path, FileMode::Open, FileAccess::Read ), + "Failed to open file '%s'.", path ); + + const uint64 entryCount = file.Size() / sizeof( uint64 ); + ASSERT( entryCount > 0 ); + + if( inOutY.values == nullptr ) + inOutY = bbcvirtallocboundednuma_span( entryCount ); + else + { + FatalIf( entryCount > inOutY.Length(), "Y buffer too small." ); + } + + void* block = bbvirtallocbounded( file.BlockSize() ); + + int err; + FatalIf( !IOJob::ReadFromFile( file, inOutY.Ptr(), file.Size(), block, file.BlockSize(), err ), + "Error %d when reading from file '%s'.", err, path ); + + bbvirtfreebounded( block ); +} diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 155c7809..728547db 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -43,6 +43,9 @@ namespace Debug template bool LoadRefTableByName( const char* fileName, Span& buffer ); + template + bool LoadRefTableByName( const TableId table, const char* fileName, Span& buffer ); + void LoadYRefTable( const TableId table, Span& buffer ); void LoadRefLinePointTable( const TableId table, uint64*& buffer, uint64& outEntryCount ); @@ -60,6 +63,9 @@ namespace Debug void WriteTableCounts( const DiskPlotContext& context ); bool ReadTableCounts( DiskPlotContext& context ); + + void DumpDPUnboundedY( const TableId table, const uint32 bucket, const DiskPlotContext& context, const Span y ); + void LoadDPUnboundedY( const TableId table, Span& y ); } template @@ -254,6 +260,18 @@ inline bool Debug::LoadRefTableByName( const char* fileName, Span& buffer ) return LoadRefTableByName( fileName, buffer.values, buffer.length ); } +//----------------------------------------------------------- +template +inline bool Debug::LoadRefTableByName( const TableId table, const char* fileName, Span& buffer ) +{ + ASSERT( fileName ); + + char fname[1024]; + sprintf( fname, fileName, (int32)table+1 ); + + return LoadRefTableByName( fname, buffer.values, buffer.length ); +} + //----------------------------------------------------------- template inline bool Debug::LoadRefTable( const char* path, T*& buffer, uint64& outEntryCount ) diff --git a/src/plotdisk/FpGroupMatcher.h b/src/plotdisk/FpGroupMatcher.h index 6e51bb2d..2ac54cca 100644 --- a/src/plotdisk/FpGroupMatcher.h +++ b/src/plotdisk/FpGroupMatcher.h @@ -111,9 +111,11 @@ struct FpGroupMatcher } // Cross-bucket matching - // Perform cross-bucket matches with the previous bucket - if( self->IsControlThread() && !crossBucketInfo->IsFirstBucket() ) - this->CrossBucketMatch( *crossBucketInfo, yEntries, meta, groupIndices ); + #if !BB_DP_DBG_UNBOUNDED_DISABLE_CROSS_BUCKET + // Perform cross-bucket matches with the previous bucket + if( self->IsControlThread() && !crossBucketInfo->IsFirstBucket() ) + this->CrossBucketMatch( *crossBucketInfo, yEntries, meta, groupIndices ); + #endif // Now perform matches _matchCounts[id] = MatchGroups( startIndex, groupCount, groupIndices, yEntries, _pairs[id], _maxMatches, id ); @@ -129,9 +131,11 @@ struct FpGroupMatcher memcpy( _outPairs + copyOffset, _pairs[id], sizeof( Pair ) * _matchCounts[id] ); - // Save the last 2 groups for cross-bucket matching - if( self->IsLastThread() ) - SaveCrossBucketInfo( *crossBucketInfo, groupIndices + groupCount - 2, yEntries, meta ); + #if !BB_DP_DBG_UNBOUNDED_DISABLE_CROSS_BUCKET + // Save the last 2 groups for cross-bucket matching + if( self->IsLastThread() ) + SaveCrossBucketInfo( *crossBucketInfo, groupIndices + groupCount - 2, yEntries, meta ); + #endif }); const uint64* allMatches = _matchCounts; diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index ad128b6b..5bcbae43 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -930,6 +930,7 @@ private: Span yAlignedSliceCount = _alignedSliceCountY[sliceIdx]; Span metaAlignedSliceCount = _alignedsliceCountMeta[sliceIdx]; + // Count for( int64 i = 0; i < entryCount; i++ ) counts[yIn[i] >> bucketShift]++; @@ -937,12 +938,12 @@ private: self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, ySliceCounts.Ptr(), _offsetsY[id], yAlignedSliceCount.Ptr() ); self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaSliceCounts.Ptr(), _offsetsMeta[id], metaAlignedSliceCount.Ptr() ); -// #if _DEBUG -// if( self->IsLastThread() ) -// { -// ASSERT( (uint64)pfxSum[_numBuckets-1] < 17200000 ); -// } -// #endif + if( bucket > 0 ) + { + if( self->BeginLockBlock() ) + _fxWriteFence.Wait( bucket, _tableIOWait ); // #TODO: Double-buffer to avoid waiting here // #TODO: Either use a spin wait or have all threads suspend here + self->EndLockBlock(); + } // Distribute to buckets for( int64 i = 0; i < entryCount; i++ ) @@ -960,10 +961,6 @@ private: // Write to disk if( self->BeginLockBlock() ) { - // #TODO: Either use a spin wait or have all threads suspend here - if( bucket > 0 ) - _fxWriteFence.Wait( bucket, _tableIOWait ); - const FileId yId = _yId [1]; const FileId metaId = _metaId[1]; const FileId idxId = _idxId [1]; @@ -972,7 +969,7 @@ private: _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); _ioQueue.WriteBucketElementsT ( idxId , idxOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); - _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), metaAlignedSliceCount.Ptr(), metaSliceCounts.Ptr() ); // #TODO: Can use ySliceCounts here... + _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), metaAlignedSliceCount.Ptr(), ySliceCounts.Ptr() ); // #TODO: Can use ySliceCounts here... _ioQueue.SignalFence( _fxWriteFence, bucket+1 ); _ioQueue.CommitCommands(); @@ -1345,15 +1342,18 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co ioQueue.SeekBucket( fileId, 0, SeekOrigin::Begin ); ioQueue.CommitCommands(); - Span yRef = bbcvirtallocboundednuma_span( 1ull << 32 );// context.entryCounts[(int)table] ); //_yRef.SliceSize( context.entryCounts[(int)table] ); - Span yTmp = bbcvirtallocboundednuma_span( yRef.Length() ); - + Span yRef; // Load ref { Log::Line( " Loading ref" ); - Debug::LoadYRefTable( table, yRef ); + // Debug::LoadRefTableByName( table, "t%d.y-dp-unbounded.tmp", yRef ); + Debug::LoadDPUnboundedY( table, yRef ); } + Span yTmp = bbcvirtallocboundednuma_span( yRef.Length() ); + + // Read our entries + // Read our entries { const uint32 k = 32; From c8b4efebe7f0b8c11f018b8119e8538c8e966bc0 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 8 Jul 2022 02:26:03 -0500 Subject: [PATCH 56/91] Map issue fix --- src/plotdisk/MapWriter.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plotdisk/MapWriter.h b/src/plotdisk/MapWriter.h index c407847b..63b5fe0f 100644 --- a/src/plotdisk/MapWriter.h +++ b/src/plotdisk/MapWriter.h @@ -188,7 +188,7 @@ class MapWriter //----------------------------------------------------------- template - void WriteJob( Job* self, const uint32 bucket, const uint64 tableOffset, + void WriteJob( Job* self, const uint32 bucket, const uint64 mapOffset, const Span indices, Span mapOut, uint64 outMapBucketCounts [_numBuckets+ExtraBucket], @@ -218,17 +218,19 @@ class MapWriter self->CalculatePrefixSum( numBuckets, counts, pfxSum, totalCounts ); + const uint64 tableOffset = mapOffset + (uint64)offset; + // Convert entries from source index to reverse map for( size_t i = 0; i < inIdx.Length(); i++ ) { const uint64 origin = inIdx[i]; ASSERT( origin < 0x100000000 + (1ull<<_k) / _numBuckets ); const uint64 b = origin >> bucketShift; ASSERT( b < numBuckets ); const uint32 dstIdx = --pfxSum[b]; ASSERT( dstIdx < indices.Length() ); - const uint64 finalIdx = tableOffset + (uint64)i; - ASSERT( finalIdx < ( 1ull << encodeShift ) ); - + mapOut[dstIdx] = (origin << encodeShift) | finalIdx; + + ASSERT( finalIdx < ( 1ull << encodeShift ) ); } // Write From 21d1b62aa70ff9ee611658df007efea8ba462f8f Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 8 Jul 2022 02:29:50 -0500 Subject: [PATCH 57/91] Fix build issue --- src/plotdisk/DiskFp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plotdisk/DiskFp.h b/src/plotdisk/DiskFp.h index 64afaa85..596b587f 100644 --- a/src/plotdisk/DiskFp.h +++ b/src/plotdisk/DiskFp.h @@ -297,7 +297,9 @@ class DiskFp WriteMap( bucket, inEntryCount, map, (uint64*)_meta[1] ); + #if BB_DP_DBG_UNBOUNDED_DUMP_Y BB_DBG_DP_DumpUnboundedY( table-1, bucket, _context, Span( y, inEntryCount ) ); + #endif const TMetaIn* inMeta = ( table == TableId::Table2 ) ? (TMetaIn*)map : meta; From dfd4fb87cc15e5a6092be9bf1cdacee793ec9be6 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 8 Jul 2022 05:21:06 -0500 Subject: [PATCH 58/91] Adding uncomitted validation code --- src/plotdisk/DiskPlotDebug.h | 126 +++++++++++++++++++++++++------- src/plotdisk/DiskPlotPhase1.cpp | 8 +- src/plotdisk/k32/FxBounded.inl | 10 ++- 3 files changed, 116 insertions(+), 28 deletions(-) diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 728547db..47c4d3bd 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -497,30 +497,62 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) const uint32 _k = 32; const uint32 _maxEntriesPerBucket = ( ( 1ull << _k ) / _numBuckets ) * 2; + const bool hasMap = table < TableId::Table7; - const FileId fileId = FileId::T1 + (FileId)table; - context.ioQueue->SeekFile( fileId, 0, 0, SeekOrigin::Begin ); + const FileId pairsId = FileId::T1 + (FileId)table; + const FileId mapId = FileId::MAP2 + (FileId)table-1; + context.ioQueue->SeekFile( pairsId, 0, 0, SeekOrigin::Begin ); + context.ioQueue->SeekBucket( mapId, 0, SeekOrigin::Begin ); context.ioQueue->CommitCommands(); - const uint64 entryCount = context.entryCounts[(int)table]; - Span reference = bbcvirtallocboundednuma_span( entryCount ); - Span bucketPairs = bbcvirtallocboundednuma_span( _maxEntriesPerBucket ); + const uint64 entryCount = context.entryCounts[(int)table]; + Span reference = bbcvirtallocboundednuma_span( entryCount ); + Span bucketPairs = bbcvirtallocboundednuma_span( _maxEntriesPerBucket ); + Span referenceMap; + Span bucketMap; + + if( hasMap ) + { + referenceMap = bbcvirtallocboundednuma_span( entryCount ); + bucketMap = bbcvirtallocboundednuma_span( _maxEntriesPerBucket ); + } Log::Line( " Reading reference table." ); { - char path[1024]; - sprintf( path, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); + void* block = nullptr; + size_t blockSize = 0; + { FileStream dbgDir; FatalIf( !dbgDir.Open( BB_DP_DBG_REF_DIR, FileMode::Open, FileAccess::Read ), "Failed to open debug directory at '%s'.", BB_DP_DBG_REF_DIR ); - void* block = bbvirtallocbounded( dbgDir.BlockSize() ); + blockSize = dbgDir.BlockSize(); + block = bbvirtallocbounded( blockSize ); + } + + { + char path[1024]; + sprintf( path, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); + const size_t readSize = sizeof( Pair ) * entryCount; int err; - FatalIf( !IOJob::ReadFromFile( path, reference.Ptr(), readSize, block, dbgDir.BlockSize(), err ), - "Failed to read from refeerence pairs file at '%s' with error: %d", path, err ); + FatalIf( !IOJob::ReadFromFile( path, reference.Ptr(), readSize, block, blockSize, err ), + "Failed to read from reference pairs file at '%s' with error: %d", path, err ); + } + + if( hasMap ) + { + char path[1024]; + sprintf( path, "%st%d.map.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); + + const size_t readSize = sizeof( uint64 ) * entryCount; + + int err; + FatalIf( !IOJob::ReadFromFile( path, referenceMap.Ptr(), readSize, block, blockSize, err ), + "Failed to read from reference map file at '%s' with error: %d", path, err ); + } bbvirtfreebounded( block ); } @@ -530,9 +562,10 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) Fence fence; StackAllocator allocator( heap, heapSize ); - DiskPairAndMapReader<_numBuckets, true> reader( context, context.fpThreadCount, fence, table, allocator, true ); + DiskPairAndMapReader<_numBuckets, true> reader( context, context.fpThreadCount, fence, table, allocator, !hasMap ); - Span refPairs = reference; + Span refPairs = reference; + Span refMap = referenceMap; const int32 lTable = (int32)table-1; @@ -543,17 +576,18 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) { Log::Line( " Validating Bucket %u", bucket ); - Span pairs = bucketPairs; + Span pairs = bucketPairs; + Span map = bucketMap; Duration _; reader.LoadNextBucket(); - pairs.length = reader.UnpackBucket( bucket, pairs.Ptr(), nullptr, _ ); + pairs.length = reader.UnpackBucket( bucket, pairs.Ptr(), map.Ptr(), _ ); // Validate for( uint64 i = 0; i < pairs.Length(); i++ ) { const Pair ref = refPairs[i]; - const Pair entry = pairs[i].AddOffset( offset ); + const Pair entry = pairs [i].AddOffset( offset ); ASSERT( ref.left == entry.left && ref.right == entry.right ); } @@ -563,6 +597,9 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) refPairs = refPairs.Slice( pairs.Length() ); iGlobal += pairs.Length(); + + if( hasMap ) + refMap = refMap.Slice( pairs.Length() ); } // Cleanup @@ -577,21 +614,44 @@ void Debug::ValidateK32Pairs( const TableId table, DiskPlotContext& context ) template void Debug::DumpPairs( const TableId table, DiskPlotContext& context ) { + ASSERT( table > TableId::Table1 ); + Log::Line( "[DEBUG] Dumping pairs for table %u", table+1 ); + const bool hasMap = table < TableId::Table7; + + const FileId pairsId = FileId::T1 + (FileId)table; + const FileId mapId = FileId::MAP2 + (FileId)table-1; + char pairsPath[1024]; - sprintf( pairsPath, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); + char mapPath [1024]; + FileStream pairsFile, mapFile; - FileStream pairsFile; + sprintf( pairsPath, "%st%d.pairs.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); FatalIf( !pairsFile.Open( pairsPath, FileMode::OpenOrCreate, FileAccess::Write, FileFlags::NoBuffering | FileFlags::LargeFile ), "Failed to open pairs file at '%s'.", pairsPath ); - const FileId fileId = FileId::T1 + (FileId)table; - context.ioQueue->SeekFile( fileId, 0, 0, SeekOrigin::Begin ); + void* block = bbvirtallocbounded( pairsFile.BlockSize() ); + Span pairTable = bbcvirtallocboundednuma_span( context.entryCounts[(int)table] ); + Span mapTable; + + context.ioQueue->SeekFile( pairsId, 0, 0, SeekOrigin::Begin ); + + if( hasMap ) + { + sprintf( mapPath, "%st%d.map.tmp", BB_DP_DBG_REF_DIR, (int32)table+1 ); + + FatalIf( !mapFile.Open( mapPath, FileMode::OpenOrCreate, FileAccess::Write, FileFlags::NoBuffering | FileFlags::LargeFile ), + "Failed to open map file at '%s'.", mapPath ); + + context.ioQueue->SeekBucket( mapId, 0, SeekOrigin::Begin ); + + mapTable = bbcvirtallocboundednuma_span( context.entryCounts[(int)table] ); + } + + // Submit seek commands context.ioQueue->CommitCommands(); - void* block = bbvirtallocbounded( pairsFile.BlockSize() ); - Span pairTable = bbcvirtallocboundednuma_span( context.entryCounts[(int)table] ); const size_t heapSize = 4ull GB; byte* heap = bbvirtallocboundednuma( heapSize ); @@ -601,10 +661,12 @@ void Debug::DumpPairs( const TableId table, DiskPlotContext& context ) uint64 pairCount = 0; - // Read + // Read from disk { - Span pairs = pairTable; - DiskPairAndMapReader<_numBuckets, _bounded> reader( context, context.fpThreadCount, fence, table, allocator, true ); + Span pairs = pairTable; + Span map = mapTable; + + DiskPairAndMapReader<_numBuckets, _bounded> reader( context, context.fpThreadCount, fence, table, allocator, !hasMap ); const int lTable = (int)table-1; uint32 offset = 0; @@ -613,11 +675,12 @@ void Debug::DumpPairs( const TableId table, DiskPlotContext& context ) reader.LoadNextBucket(); Duration _; - const uint64 pairsRead = reader.UnpackBucket( bucket, pairs.Ptr(), nullptr, _ ); + const uint64 pairsRead = reader.UnpackBucket( bucket, pairs.Ptr(), map.Ptr(), _ ); ASSERT( pairsRead <= pairs.Length() ); // Offset pairs globally Span bucketPairs = pairs.SliceSize( pairsRead ); + for( uint64 i = 0; i < bucketPairs.Length(); i++ ) { auto p = bucketPairs[i]; @@ -630,10 +693,14 @@ void Debug::DumpPairs( const TableId table, DiskPlotContext& context ) pairCount += pairsRead; pairs = pairs.Slice( pairsRead ); + if( hasMap ) + map = map.Slice( pairsRead); + offset += context.bucketCounts[lTable][bucket]; } ASSERT( pairs.Length() == 0 ); + ASSERT( map.Length() == 0 ); } // Write unpacked @@ -643,12 +710,21 @@ void Debug::DumpPairs( const TableId table, DiskPlotContext& context ) FatalIf( !IOJob::WriteToFile( pairsFile, pairTable.Ptr(), sizeWrite, block, pairsFile.BlockSize(), err ), "Failed to write to pairs file '%s' with error: %d", pairsPath, err ); + + if( hasMap ) + { + const size_t mapSizeWrite = sizeof( uint64 ) * mapTable.Length(); + FatalIf( !IOJob::WriteToFile( mapFile, mapTable.Ptr(), mapSizeWrite, block, mapFile.BlockSize(), err ), + "Failed to write to map file '%s' with error: %d", mapPath, err ); + } } // Cleanup bbvirtfreebounded( block ); bbvirtfreebounded( pairTable.Ptr() ); bbvirtfreebounded( heap ); + if( hasMap ) + bbvirtfreebounded( mapTable.Ptr() ); Log::Line( "[DEBUG] Completed." ); } diff --git a/src/plotdisk/DiskPlotPhase1.cpp b/src/plotdisk/DiskPlotPhase1.cpp index 4a2d0cc8..ff0f389c 100644 --- a/src/plotdisk/DiskPlotPhase1.cpp +++ b/src/plotdisk/DiskPlotPhase1.cpp @@ -403,7 +403,13 @@ void DiskPlotPhase1::ForwardPropagateBuckets() Debug::ValidatePairs<256>( _cx, table ); #endif - BB_DBG_DumpPairs( _numBuckets, table, _cx ); + #if BB_DP_DBG_DUMP_PAIRS + if( table > TableId::Table2 ) + BB_DBG_DumpPairs( _numBuckets, table-1, _cx ); + + if( table == TableId::Table7 ) + BB_DBG_DumpPairs( _numBuckets, table, _cx ); + #endif } //----------------------------------------------------------- diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 5bcbae43..6e0a7c4f 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -14,7 +14,7 @@ #include "plotting/PlotValidation.h" #include "plotdisk/DiskPlotDebug.h" - #define _VALIDATE_Y 1 + // #define _VALIDATE_Y 1 #if _VALIDATE_Y // uint32 _refBucketCounts[BB_DP_MAX_BUCKET_COUNT]; // Span _yRef; @@ -334,7 +334,12 @@ public: ); #endif + #if BB_DP_DBG_VALIDATE_BOUNDED_PAIRS + if( rTable > TableId::Table2 ) + BB_DBG_ValidateBoundedPairs( _numBuckets, rTable-1, _context ); + if( rTable == TableId::Table7 ) BB_DBG_ValidateBoundedPairs( _numBuckets, rTable, _context ); + #endif #endif // _DEBUG } @@ -400,6 +405,7 @@ private: matchOffset += (uint32)_pairs[i].Length(); ASSERT( totalMatches <= _entriesPerBucket ); + ASSERT( matchOffset < totalMatches ); // #TEST #if _DEBUG @@ -1332,7 +1338,7 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co #endif ) { - if( table > TableId::Table2 && table < TableId::Table7 ) + if( table >= TableId::Table2 && table < TableId::Table7 ) { Log::Line( "[DEBUG: Validating table y %u]", table+1 ); From ffcc3cef3d3f3947c9041b2efa62cb0432814fb1 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Sat, 9 Jul 2022 08:45:18 -0500 Subject: [PATCH 59/91] Added C-table writing. --- src/plotdisk/DiskBufferQueue.cpp | 2 +- src/plotdisk/DiskPlotConfig.h | 2 +- src/plotdisk/DiskPlotDebug.cpp | 2 +- src/plotdisk/DiskPlotter.cpp | 2 +- src/plotdisk/MapWriter.h | 1 + src/plotdisk/k32/CTableWriterBounded.h | 358 +++++++++++++++++++++++++ src/plotdisk/k32/DiskPlotBounded.cpp | 47 +++- 7 files changed, 399 insertions(+), 15 deletions(-) create mode 100644 src/plotdisk/k32/CTableWriterBounded.h diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index c237778d..35b78acf 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -157,7 +157,7 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC fileSet.files[i] = file; const FileMode fileMode = - #if _DEBUG && ( BB_DP_DBG_READ_EXISTING_F1 || BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) + #if _DEBUG && ( BB_DP_DBG_READ_EXISTING_F1 || BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE || BB_DP_DBG_SKIP_TO_C_TABLES ) !isPlotFile ? FileMode::OpenOrCreate : FileMode::Create; #else FileMode::Create; diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index c2cb1bc0..a07ecfac 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -57,7 +57,7 @@ // #define BB_DP_DBG_SKIP_TO_C_TABLES 1 // #define BB_DP_P1_SKIP_TO_TABLE 1 -// #define BB_DP_P1_START_TABLE TableId::Table3 +// #define BB_DP_P1_START_TABLE TableId::Table7 // Tmp file deletion (useful to keep around when developing) #if _DEBUG diff --git a/src/plotdisk/DiskPlotDebug.cpp b/src/plotdisk/DiskPlotDebug.cpp index 749041c6..1179f8b2 100644 --- a/src/plotdisk/DiskPlotDebug.cpp +++ b/src/plotdisk/DiskPlotDebug.cpp @@ -649,7 +649,7 @@ void Debug::WriteTableCounts( const DiskPlotContext& cx ) //----------------------------------------------------------- bool Debug::ReadTableCounts( DiskPlotContext& cx ) { - #if( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) + #if( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE || BB_DP_DBG_SKIP_TO_C_TABLES ) FileStream bucketCounts, tableCounts, backPtrBucketCounts; diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 8ed7bcdd..ee60dd4e 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -155,7 +155,7 @@ void DiskPlotter::Plot( const PlotRequest& req ) _cx.ioQueue->OpenPlotFile( req.plotFileName, req.plotId, req.plotMemo, req.plotMemoSize ); - #if ( _DEBUG && ( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE ) ) + #if ( _DEBUG && ( BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE || BB_DP_DBG_SKIP_TO_C_TABLES ) ) BB_DP_DBG_ReadTableCounts( _cx ); #endif diff --git a/src/plotdisk/MapWriter.h b/src/plotdisk/MapWriter.h index 63b5fe0f..c9c32464 100644 --- a/src/plotdisk/MapWriter.h +++ b/src/plotdisk/MapWriter.h @@ -1,6 +1,7 @@ #pragma once #include "threading/Fence.h" #include "util/StackAllocator.h" +#include "plotdisk/BitBucketWriter.h" template class MapWriter diff --git a/src/plotdisk/k32/CTableWriterBounded.h b/src/plotdisk/k32/CTableWriterBounded.h new file mode 100644 index 00000000..851b7c6a --- /dev/null +++ b/src/plotdisk/k32/CTableWriterBounded.h @@ -0,0 +1,358 @@ +#pragma once +#include "plotdisk/DiskPlotConfig.h" +#include "plotdisk/DiskPlotContext.h" +#include "plotdisk/DiskBufferQueue.h" +#include "plotdisk/MapWriter.h" +#include "util/Util.h" +#include "util/StackAllocator.h" +#include "threading/MTJob.h" +#include "threading/Fence.h" +#include "algorithm/RadixSort.h" +#include "plotting/TableWriter.h" + +template +class CTableWriterBounded +{ + static constexpr uint32 _k = 32; + static constexpr uint64 _kEntryCount = 1ull << _k; + static constexpr uint64 _entriesPerBucket = (uint64)( _kEntryCount / _numBuckets * BB_DP_XTRA_ENTRIES_PER_BUCKET ); +public: + + //----------------------------------------------------------- + CTableWriterBounded( DiskPlotContext& context ) + : _context ( context ) + , _ioQueue ( *context.ioQueue ) + , _readFence ( context.fencePool->RequireFence() ) + , _writeFence ( context.fencePool->RequireFence() ) + , _threadCount( context.cThreadCount ) + {} + + //----------------------------------------------------------- + ~CTableWriterBounded() + { + _context.fencePool->RestoreAllFences(); + } + + //----------------------------------------------------------- + void Run( IAllocator& allocator ) + { + auto& context = _context; + + // #TODO: Make the whole thing parallel? + uint32 c1NextCheckpoint = 0; // How many C1 entries to skip until the next checkpoint. If there's any entries here, it means the last bucket wrote a + uint32 c2NextCheckpoint = 0; // checkpoint entry and still had entries which did not reach the next checkpoint. + // Ex. Last bucket had 10005 entries, so it wrote a checkpoint at 0 and 10000, then it counted 5 more entries, so + // the next checkpoint would be after 9995 entries. + + // These buffers are small enough on k32 (around 1.6MiB for C1, C2 is negligible), we keep the whole thing in memory, + // while we write C3 to the actual file + const uint32 c1Interval = kCheckpoint1Interval; + const uint32 c2Interval = kCheckpoint1Interval * kCheckpoint2Interval; + + const uint64 tableLength = _context.entryCounts[(int)TableId::Table7]; + const uint32 c1TotalEntries = (uint32)CDiv( tableLength, (int)c1Interval ) + 1; // +1 because chiapos adds an extra '0' entry at the end + const uint32 c2TotalEntries = (uint32)CDiv( tableLength, (int)c2Interval ) + 1; // +1 because we add a short-circuit entry to prevent C2 lookup overflows + // #TODO: Remove the extra c2 entry? + + const size_t c1TableSizeBytes = c1TotalEntries * sizeof( uint32 ); + const size_t c2TableSizeBytes = c2TotalEntries * sizeof( uint32 ); + + + uint32 c3ParkOverflowCount = 0; // Overflow entries from a bucket that did not make it into a C3 park this bucket. Saved for the next bucket. + uint32 c3ParkOverflow[kCheckpoint1Interval]; // They are then copied to a "prefix region" in the f7 buffer of the next park. + + size_t c3TableSizeBytes = 0; // Total size of the C3 table + + // Allocate buffers + AllocIOBuffers( allocator ); + + Span _mapOut = allocator.CAllocSpan( _entriesPerBucket ); + + // Use same buffers as map tmp + uint32* f7Tmp = _mapOut.As().SliceSize( _entriesPerBucket ).Ptr(); + uint32* idxTmp = _mapOut.As().Slice( _entriesPerBucket ).Ptr(); + + Span c1Buffer = allocator.CAllocSpan( c1TotalEntries ); + Span c2Buffer = allocator.CAllocSpan( c2TotalEntries ); + + + /// + /// Begin + /// + + // Prepare read bucket files + _ioQueue.SeekBucket( FileId::FX0 , 0, SeekOrigin::Begin ); + _ioQueue.SeekBucket( FileId::INDEX0, 0, SeekOrigin::Begin ); + + // Seek to the start of the C3 table instead of writing garbage data. + _ioQueue.SeekFile( FileId::PLOT, 0, (int64)(c1TableSizeBytes + c2TableSizeBytes), SeekOrigin::Current ); + _ioQueue.CommitCommands(); + + // Load initial bucket + LoadBucket( 0 ); + + uint32* c1Writer = c1Buffer.Ptr(); + uint32* c2Writer = c2Buffer.Ptr(); + + for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) + { + // Load next bucket in the background + LoadBucket( bucket + 1 ); + + // Wait for our bucket data to be available + auto bucketData = ReadBucket( bucket ); + + Span f7 = bucketData.first; + Span indices = bucketData.second; + ASSERT( f7.Length() == indices.Length() ); + ASSERT( f7.Length() == context.bucketCounts[(int)TableId::Table7][bucket] ); + + const uint32 bucketLength = f7.Length(); + + // Sort on f7 + RadixSort256::SortWithKey( *context.threadPool, _threadCount, f7.Ptr(), f7Tmp, indices.Ptr(), idxTmp, bucketLength ); + + // Write the map top disk + WriteMap( bucket, indices, _mapOut ); + + /// Now handle f7 and write them into C tables + /// We will set the addersses to these tables accordingly. + + // Write C1 + { + ASSERT( bucketLength > c1NextCheckpoint ); + + // #TODO: Do C1 multi-threaded? For now jsut single-thread it... + for( uint32 i = c1NextCheckpoint; i < bucketLength; i += c1Interval ) + *c1Writer++ = Swap32( f7[i] ); + + // Track how many entries we covered in the last checkpoint region + const uint32 c1Length = bucketLength - c1NextCheckpoint; + const uint32 c1CheckPointCount = CDiv( c1Length, (int)c1Interval ); + + c1NextCheckpoint = c1CheckPointCount * c1Interval - c1Length; + } + + // Write C2 + { + // C2 has so few entries on k=32 that there's no sense in doing it multi-threaded + if( c2NextCheckpoint >= bucketLength ) + c2NextCheckpoint -= bucketLength; // No entries to write in this bucket + else + { + for( uint32 i = c2NextCheckpoint; i < bucketLength; i += c2Interval ) + *c2Writer++ = Swap32( f7[i] ); + + // Track how many entries we covered in the last checkpoint region + const uint32 c2Length = bucketLength - c2NextCheckpoint; + const uint32 c2CheckPointCount = CDiv( c2Length, (int)c2Interval ); + + c2NextCheckpoint = c2CheckPointCount * c2Interval - c2Length; + } + } + + // Write C3 + { + const bool isLastBucket = bucket == _numBuckets-1; + + uint32* c3F7 = f7.Ptr(); + uint32 c3BucketLength = bucketLength; + + if( c3ParkOverflowCount ) + { + // Copy our overflow to the prefix region of our f7 buffer + c3F7 -= c3ParkOverflowCount; + c3BucketLength += c3ParkOverflowCount; + + memcpy( c3F7, c3ParkOverflow, sizeof( uint32 ) * c3ParkOverflowCount ); + c3ParkOverflowCount = 0; + } + + + #if _DEBUG + // #TODO: TEST: Remove this + // Dump f7's that have the value of 0xFFFFFFFF for now, + // this is just for compatibility with RAM bladebit + // for testing plots against it. + // if( isLastBucket ) + // { + // while( c3F7[c3BucketLength-1] == 0xFFFFFFFF ) + // c3BucketLength--; + // } + #endif + + // See TableWriter::GetC3ParkCount for details + uint32 parkCount = c3BucketLength / kCheckpoint1Interval; + uint32 overflowEntries = c3BucketLength - ( parkCount * kCheckpoint1Interval ); + + // Greater than 1 because the first entry is excluded as it is written in C1 instead. + if( isLastBucket && overflowEntries > 1 ) + { + overflowEntries = 0; + parkCount++; + } + else if( overflowEntries && !isLastBucket ) + { + // Save any entries that don't fill-up a full park for the next bucket + memcpy( c3ParkOverflow, c3F7 + c3BucketLength - overflowEntries, overflowEntries * sizeof( uint32 ) ); + + c3ParkOverflowCount = overflowEntries; + c3BucketLength -= overflowEntries; + } + + const size_t c3BufferSize = CalculateC3Size() * parkCount; + byte* c3Buffer = GetWriteBuffer( bucket ); + + // #NOTE: This function uses re-writes our f7 buffer, so ensure it is done after + // that buffer is no longer needed. + const size_t sizeWritten = TableWriter::WriteC3Parallel( *_context.threadPool, + _threadCount, c3BucketLength, c3F7, c3Buffer ); + ASSERT( sizeWritten == c3BufferSize ); + + c3TableSizeBytes += sizeWritten; + + // Write the C3 table to the plot file directly + _ioQueue.WriteFile( FileId::PLOT, 0, c3Buffer, c3BufferSize ); + _ioQueue.SignalFence( _writeFence, bucket ); + _ioQueue.CommitCommands(); + } + } + + // Seek back to the begining of the C1 table and + // write C1 and C2 buffers to file, then seek back to the end of the C3 table + + c1Buffer[c1TotalEntries-1] = 0; // Chiapos adds a trailing 0 + c2Buffer[c2TotalEntries-1] = 0xFFFFFFFF; // C2 overflow protection // #TODO: Remove? + + _readFence.Reset( 0 ); + + _ioQueue.SeekBucket( FileId::PLOT, -(int64)( c1TableSizeBytes + c2TableSizeBytes + c3TableSizeBytes ), SeekOrigin::Current ); + _ioQueue.WriteFile( FileId::PLOT, 0, c1Buffer.Ptr(), c1TableSizeBytes ); + _ioQueue.WriteFile( FileId::PLOT, 0, c2Buffer.Ptr(), c2TableSizeBytes ); + _ioQueue.SeekBucket( FileId::PLOT, (int64)c3TableSizeBytes, SeekOrigin::Current ); + _ioQueue.SignalFence( _readFence, 1 ); + _ioQueue.CommitCommands(); + + // Save C table addresses into the plot context. + // And set the starting address for the table 1 to be written + const size_t headerSize = _ioQueue.PlotHeaderSize(); + + _context.plotTablePointers[7] = headerSize; // C1 + _context.plotTablePointers[8] = _context.plotTablePointers[7] + c1TableSizeBytes; // C2 + _context.plotTablePointers[9] = _context.plotTablePointers[8] + c2TableSizeBytes; // C3 + _context.plotTablePointers[0] = _context.plotTablePointers[9] + c3TableSizeBytes; // T1 + + // Save sizes + _context.plotTableSizes[7] = c1TableSizeBytes; + _context.plotTableSizes[8] = c2TableSizeBytes; + _context.plotTableSizes[9] = c3TableSizeBytes; + + // Wait for all commands to finish + _readFence.Wait( 1 ); + } + +private: + + //----------------------------------------------------------- + void AllocIOBuffers( IAllocator& allocator ) + { + _mapWriter = MapWriter<_numBuckets, false>( _ioQueue, FileId::MAP7, allocator, + _entriesPerBucket, _context.tmp1BlockSize, + _context.fencePool->RequireFence(), _tableIOWait ); + + const size_t blockSize = _context.tmp2BlockSize; + const uint32 prefixRegionCount = (uint32)RoundUpToNextBoundaryT( (size_t)kCheckpoint1Interval, blockSize / sizeof( uint32 ) ); + + // Allocate and init read buffer views + uint32* f7[2] = { + allocator.CAlloc( _entriesPerBucket + prefixRegionCount, blockSize ), + allocator.CAlloc( _entriesPerBucket + prefixRegionCount, blockSize ) + }; + + // Assign after prefix region + for( uint32 i = 0; i < _numBuckets; i++ ) + _f7ReadBuffer[i] = Span( f7[i&1] + prefixRegionCount, _entriesPerBucket ); // & 1 == % 2 + + // Allocate and init index buffer views + Span indices[2] = { + allocator.CAllocSpan( _entriesPerBucket, blockSize ), + allocator.CAllocSpan( _entriesPerBucket, blockSize ) + }; + + for( uint32 i = 0; i < _numBuckets; i++ ) + _idxReadBuffer[i] = indices[i&1]; + + + // Allocate write buffers + _f7WriteBuffer[0] = allocator.CAllocSpan( _entriesPerBucket, blockSize ); + _f7WriteBuffer[1] = allocator.CAllocSpan( _entriesPerBucket, blockSize ); + } + + //----------------------------------------------------------- + void WriteMap( const uint32 bucket, Span indices, Span mapBuffer ) + { + auto* mapWriter = &_mapWriter; + + using Job = AnonPrefixSumJob; + + Job::Run( *_context.threadPool, _threadCount, [=]( Job* self ) { + + uint64 outMapBucketCounts[_numBuckets]; + uint32 totalCounts [_numBuckets]; + + mapWriter->WriteJob( self, bucket, _mapOffset, indices, mapBuffer, + outMapBucketCounts, totalCounts, _mapBitCounts ); + + if( bucket == _numBuckets-1 && self->IsControlThread() ) + mapWriter->SubmitFinalBits(); + }); + + _mapOffset += indices.Length(); + } + + //----------------------------------------------------------- + inline void LoadBucket( const uint32 bucket ) + { + if( bucket >= _numBuckets ) + return; + + _ioQueue.ReadBucketElementsT( FileId::FX0 , _f7ReadBuffer [bucket] ); + _ioQueue.ReadBucketElementsT( FileId::INDEX0, _idxReadBuffer[bucket] ); + _ioQueue.SignalFence( _readFence, bucket + 1 ); + _ioQueue.CommitCommands(); + } + + //----------------------------------------------------------- + inline std::pair, Span> ReadBucket( const uint32 bucket ) + { + _readFence.Wait( bucket + 1, _tableIOWait ); + return std::pair, Span>( _f7ReadBuffer[bucket], _idxReadBuffer[bucket] ); + } + + //----------------------------------------------------------- + inline byte* GetWriteBuffer( const uint32 bucket ) + { + if( bucket > 1 ) + _writeFence.Wait( bucket - 2, _tableIOWait ); + + return (byte*)_f7WriteBuffer[bucket & 1].Ptr(); + } + +private: + DiskPlotContext& _context; + DiskBufferQueue& _ioQueue; + Fence& _readFence; + Fence& _writeFence; + + Span _f7ReadBuffer [_numBuckets]; + Span _idxReadBuffer[_numBuckets]; + Span _f7WriteBuffer[2]; + + MapWriter<_numBuckets, false> _mapWriter; + uint64 _mapOffset = 0; + uint64 _mapBitCounts[BB_DP_MAX_JOBS] = {}; + + Duration _tableIOWait = Duration::zero(); + uint32 _threadCount = 0; +}; + diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 19fc84e0..3131408f 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -5,6 +5,7 @@ #include "plotdisk/DiskPlotContext.h" #include "plotdisk/DiskPlotConfig.h" #include "plotdisk/DiskBufferQueue.h" +#include "CTableWriterBounded.h" #include "plotting/PlotTools.h" #include "F1Bounded.inl" @@ -124,17 +125,31 @@ void K32BoundedPhase1::RunWithBuckets() { TableId startTable = TableId::Table2; - #if defined( _DEBUG ) && defined( BB_DP_P1_SKIP_TO_TABLE ) + #if defined( _DEBUG ) && ( defined( BB_DP_P1_SKIP_TO_TABLE ) || defined( BB_DP_DBG_SKIP_TO_C_TABLES ) ) { ASSERT( _context.entryCounts[0] == 1ull << 32 ); - ASSERT( BB_DP_P1_START_TABLE > TableId::Table2 ); - startTable = BB_DP_P1_START_TABLE; + + #if BB_DP_P1_SKIP_TO_TABLE + ASSERT( BB_DP_P1_START_TABLE > TableId::Table2 ); + startTable = BB_DP_P1_START_TABLE; + #endif { + #if BB_DP_DBG_SKIP_TO_C_TABLES + const FileId fxId = FileId::FX0; + const FileId idxId = FileId::INDEX0; + const FileId metaId = FileId::META0; + startTable = TableId::Table7; + #else + const FileId fxId = (uint)(startTable-1) %2 == 0 ? FileId::FX0 : FileId::FX1; + const FileId idxId = (uint)(startTable-1) %2 == 0 ? FileId::INDEX0 : FileId::INDEX1; + const FileId metaId = (uint)(startTable-1) %2 == 0 ? FileId::META0 : FileId::META1; + #endif + Fence fence; - _ioQueue.DebugReadSliceSizes( startTable-1, (uint)(startTable-1) %2 == 0 ? FileId::FX0 : FileId::FX1 ); - _ioQueue.DebugReadSliceSizes( startTable-1, (uint)(startTable-1) %2 == 0 ? FileId::INDEX0 : FileId::INDEX1 ); - _ioQueue.DebugReadSliceSizes( startTable-1, (uint)(startTable-1) %2 == 0 ? FileId::META0 : FileId::META1 ); + _ioQueue.DebugReadSliceSizes( startTable, fxId ); + _ioQueue.DebugReadSliceSizes( startTable, idxId ); + _ioQueue.DebugReadSliceSizes( startTable, metaId ); _ioQueue.SignalFence( fence ); _ioQueue.CommitCommands(); fence.Wait(); @@ -153,6 +168,7 @@ void K32BoundedPhase1::RunWithBuckets() _xBucketStackMarker = _allocator.Size(); #endif +#if !( defined( _DEBUG ) && defined( BB_DP_DBG_SKIP_TO_C_TABLES ) ) for( TableId table = startTable; table <= TableId::Table7; table++ ) { switch( table ) @@ -169,6 +185,16 @@ void K32BoundedPhase1::RunWithBuckets() break; } } +#endif + + // Process F7 and write C tables to plot + { + _allocator.PopToMarker( 0 ); + + Log::Line( "Sorting F7 & Writing C Tables" ); + CTableWriterBounded<_numBuckets> cWriter( _context ); + cWriter.Run( _allocator ); + } } //----------------------------------------------------------- @@ -213,10 +239,10 @@ void K32BoundedPhase1::RunFx() #if BB_DP_FP_MATCH_X_BUCKET _allocator.PopToMarker( _xBucketStackMarker ); - const uint xBucketIdxIn = (uint)(table-1) & 1; - const uint xBucketIdxOut = (uint)table & 1; - auto& crossBucketIn = _crossBucketEntries[xBucketIdxIn]; - auto& crossBucketOut = _crossBucketEntries[xBucketIdxOut]; + const uint xBucketIdxIn = (uint)(table-1) & 1; + const uint xBucketIdxOut = (uint)table & 1; + auto& crossBucketIn = _crossBucketEntries[xBucketIdxIn]; + auto& crossBucketOut = _crossBucketEntries[xBucketIdxOut]; for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) crossBucketOut[bucket].length = 0; @@ -250,4 +276,3 @@ void K32BoundedPhase1::RunFx() _ioQueue.CommitCommands(); #endif } - From 2e0aaece2407b299cd9b796dd5b66da3595bf17d Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 11 Jul 2022 23:12:45 -0500 Subject: [PATCH 60/91] Added caching for bounded plotting --- .vscode/launch.json | 8 ++-- src/plotdisk/DiskPlotPhase3.cpp | 2 +- src/plotdisk/k32/DiskPlotBounded.cpp | 63 ++++++++++++++++++---------- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index dd2d391f..76492bdb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -85,15 +85,15 @@ // "--f1-threads", "7", // "--fp-threads", "7", - // "--cache", "200G", + "--cache", "196G", // "--cache", "96G", - // "--cache", "106G", + // "--cache", "200G", // "--cache", "64G", // "-s", "--k32-bounded", - // "-b", "64", + "-b", "64", // "-b", "128", - "-b", "256", + // "-b", "256", "--c-threads", "26", "--p2-threads", "24", diff --git a/src/plotdisk/DiskPlotPhase3.cpp b/src/plotdisk/DiskPlotPhase3.cpp index f0f90b8c..fba876f5 100644 --- a/src/plotdisk/DiskPlotPhase3.cpp +++ b/src/plotdisk/DiskPlotPhase3.cpp @@ -935,7 +935,7 @@ void DiskPlotPhase3::GetCacheSizes( size_t& outCacheSizeLP, size_t& outCacheSize { switch( _context.numBuckets ) { - case 64 : GetCacheSizesForBuckets<128 >( outCacheSizeLP, outCacheSizeMap ); break; + case 64 : GetCacheSizesForBuckets<64 >( outCacheSizeLP, outCacheSizeMap ); break; case 128 : GetCacheSizesForBuckets<128 >( outCacheSizeLP, outCacheSizeMap ); break; case 256 : GetCacheSizesForBuckets<256 >( outCacheSizeLP, outCacheSizeMap ); break; case 512 : GetCacheSizesForBuckets<512 >( outCacheSizeLP, outCacheSizeMap ); break; diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 3131408f..7251b495 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -42,7 +42,7 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) // Temp2 { - FileSetOptions opts = FileSetOptions::None | FileSetOptions::Interleaved; + FileSetOptions opts = FileSetOptions::Interleaved; if( !context.cfg->noTmp2DirectIO ) opts |= FileSetOptions::DirectIO; @@ -50,26 +50,47 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) FileSetInitData data = {}; opts |= FileSetOptions::UseTemp2; - // if( context.cache ) - // { - // // #TODO: Divide cache evenly. For now just set it to fx0 - // opts |= FileSetOptions::Cachable; - // data.cacheSize = context.cacheSize / 2; - // data.cache = context.cache; - // } - - _ioQueue.InitFileSet( FileId::FX0 , "y0" , numBuckets, opts, &data ); - // UnSetFlag( opts, FileSetOptions::Cachable ); - _ioQueue.InitFileSet( FileId::FX1 , "y1" , numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::INDEX0, "index0", numBuckets, opts, &data ); - _ioQueue.InitFileSet( FileId::INDEX1, "index1", numBuckets, opts, &data ); - - // opts |= FileSetOptions::Cachable; - // data.cache = ((byte*)data.cache) + data.cacheSize; - _ioQueue.InitFileSet( FileId::META0 , "meta0" , numBuckets, opts, &data ); - // UnSetFlag( opts, FileSetOptions::Cachable ); - - _ioQueue.InitFileSet( FileId::META1 , "meta1" , numBuckets, opts, &data ); + size_t metaCacheSize = 0; + + if( context.cache ) + { + // In fully interleaved mode (bigger writes chunks), we need 192GiB for k=32 + // In alternating mode, we need 96 GiB. + // #TODO: Support alternating mode + + opts |= FileSetOptions::Cachable; + data.cache = context.cache; + + // Proportion out the size required per file: + // A single y or index file requires at maximum 16GiB + // A asingle meta file at its maximum will require 64GiB + // Divide the whole cache into 12 equal parts, where each meta file represent 4 parts. + // Ex: 192 / 12 = 16. This gives us 4 files of 16GiB and 2 files of 64GiB + size_t singleFileCacheSize = context.cacheSize / 12; + + // Align to block size + singleFileCacheSize = numBuckets * RoundUpToNextBoundaryT( singleFileCacheSize / numBuckets - context.tmp2BlockSize, context.tmp2BlockSize ); + + data.cacheSize = singleFileCacheSize; + metaCacheSize = data.cacheSize * 4; // Meta needs 4 times as much as y and index + + ASSERT( data.cacheSize && metaCacheSize ); + } + + auto InitCachableFileSet = [=]( FileId fileId, const char* fileName, uint32 numBuckets, FileSetOptions opts, FileSetInitData& data ) { + + _ioQueue.InitFileSet( fileId, fileName, numBuckets, opts, &data ); + data.cache = (byte*)data.cache + data.cacheSize; + }; + + InitCachableFileSet( FileId::FX0 , "y0" , numBuckets, opts, data ); + InitCachableFileSet( FileId::FX1 , "y1" , numBuckets, opts, data ); + InitCachableFileSet( FileId::INDEX0, "index0", numBuckets, opts, data ); + InitCachableFileSet( FileId::INDEX1, "index1", numBuckets, opts, data ); + + data.cacheSize = metaCacheSize; + InitCachableFileSet( FileId::META0, "meta0", numBuckets, opts, data ); + InitCachableFileSet( FileId::META1, "meta1", numBuckets, opts, data ); } } From 5cfdc3c93a436f5663768cb73a0c5633999105de Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 11 Jul 2022 23:21:04 -0500 Subject: [PATCH 61/91] Trivial --- src/plotdisk/DiskPlotPhase2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plotdisk/DiskPlotPhase2.cpp b/src/plotdisk/DiskPlotPhase2.cpp index d924cbc7..6ddea5da 100644 --- a/src/plotdisk/DiskPlotPhase2.cpp +++ b/src/plotdisk/DiskPlotPhase2.cpp @@ -57,7 +57,7 @@ DiskPlotPhase2::~DiskPlotPhase2() {} //----------------------------------------------------------- void DiskPlotPhase2::Run() { -#if BB_DP_DBG_SKIP_PHASE_2 +#if _DEBUG && BB_DP_DBG_SKIP_PHASE_2 return; #endif From 2f4ac5b96ac3c43e09c728e103a09453a7879586 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 14 Jul 2022 06:21:26 -0500 Subject: [PATCH 62/91] alpha stuff --- src/plotdisk/DiskPlotter.cpp | 11 +++++++++++ src/tools/PlotReader.h | 6 +++--- test/checker.py | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100755 test/checker.py diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index ee60dd4e..bf084248 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -38,6 +38,17 @@ DiskPlotter::DiskPlotter( const Config& cfg ) FatalIf( !GetTmpPathsBlockSizes( cfg.tmpPath, cfg.tmpPath2, _cx.tmp1BlockSize, _cx.tmp2BlockSize ), "Failed to obtain temp paths block size from t1: '%s' or %s t2: '%s'.", cfg.tmpPath, cfg.tmpPath2 ); + // #TODO: Remove when fixed + { + FatalIf( cfg.numBuckets == 128, "128 Buckets is currently not serializing plots correctly. Please select a differnt bucket count." ); + + if( gCfg.plotCount != 1 ) + { + Log::Line( "[WARNING] Consecutive plots are currently not supported. Forcing plot count to 1." ); + gCfg.plotCount = 1; + } + } + FatalIf( _cx.tmp1BlockSize < 8 || _cx.tmp2BlockSize < 8,"File system block size is too small.." ); const uint sysLogicalCoreCount = SysHost::GetLogicalCPUCount(); diff --git a/src/tools/PlotReader.h b/src/tools/PlotReader.h index e2649c9c..196e3bf5 100644 --- a/src/tools/PlotReader.h +++ b/src/tools/PlotReader.h @@ -24,9 +24,9 @@ struct PlotHeader { byte id [BB_PLOT_ID_LEN] = { 0 }; byte memo[BB_PLOT_MEMO_MAX_SIZE] = { 0 }; - uint memoLength = 0; - uint32 k = 0; - uint64 tablePtrs[10] = { 0 }; + uint memoLength = 0; + uint32 k = 0; + uint64 tablePtrs[10] = { 0 }; }; // Base Abstract class for read-only plot files diff --git a/test/checker.py b/test/checker.py new file mode 100755 index 00000000..799b406c --- /dev/null +++ b/test/checker.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +import sys + +argv = sys.argv[1:] +f7_path = argv[0] +# plot_path = argv[1] +# nssd_plot_path = argv[2] + +print( f'F7 path: {f7_path}') + +f7=40008 +f7=f'{f7:-08x}' + +challenge=f'{f7}0000000000000000000000000000000000000000000000000000000000000000'[:64] +print( challenge ) From ee84e72e559ac59c1d2b02083b7f4d99c649a61b Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 15 Jul 2022 05:21:54 -0500 Subject: [PATCH 63/91] P3 now pre-calculates its heap size like P1, therefore we can get the correct heap requirements from the beginning. Fixed several other small cli stuff in prep for next release --- .vscode/launch.json | 16 +- src/plotdisk/DiskBufferQueue.cpp | 2 +- src/plotdisk/DiskPairReader.h | 141 +++++++++++----- src/plotdisk/DiskPlotContext.h | 3 +- src/plotdisk/DiskPlotPhase3.cpp | 279 ++++++++++++++++++++++++------- src/plotdisk/DiskPlotPhase3.h | 4 + src/plotdisk/DiskPlotter.cpp | 119 ++++--------- src/util/CliParser.h | 15 ++ 8 files changed, 378 insertions(+), 201 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 76492bdb..622b4c65 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -65,7 +65,7 @@ "-f", "ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef", "-p", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8", // "-c", "xch1uf48n3f50xrs7zds0uek9wp9wmyza6crnex6rw8kwm3jnm39y82q5mvps6", - // "-t", "7", + "-t", "62", "-w", // "-v", "-i", "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835", // No overflow @@ -77,21 +77,19 @@ "--show-memo", "diskplot", "-t1", "~/plot/tmp", - "--f1-threads", "12", - // "--f1-threads", "3", - // "--fp-threads", "1", - "--fp-threads", "62", - - // "--f1-threads", "7", - // "--fp-threads", "7", + "--f1-threads", "24", + // "--fp-threads", "62", + "--c-threads", "28", + "--p2-threads", "24", "--cache", "196G", // "--cache", "96G", // "--cache", "200G", // "--cache", "64G", // "-s", - "--k32-bounded", + // "--k32-bounded", "-b", "64", + // "--sizes", // "-b", "128", // "-b", "256", diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 35b78acf..f4467fe2 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -1099,6 +1099,7 @@ inline const char* DiskBufferQueue::DbgGetCommandName( Command::CommandType type } #if _DEBUG + //----------------------------------------------------------- void DiskBufferQueue::CmdDbgWriteSliceSizes( const Command& cmd ) { @@ -1151,7 +1152,6 @@ void DiskBufferQueue::CmdDbgReadSliceSizes( const Command& cmd ) } } - #endif /// diff --git a/src/plotdisk/DiskPairReader.h b/src/plotdisk/DiskPairReader.h index 16bb2d62..f48c759e 100644 --- a/src/plotdisk/DiskPairReader.h +++ b/src/plotdisk/DiskPairReader.h @@ -27,18 +27,11 @@ struct DiskMapReader , _fileId ( fileId ) , _threadCount( threadCount ) { + const size_t blockSize = context.ioQueue->BlockSize( fileId ); const uint64 maxKEntries = ( 1ull << _k ); const uint64 maxBucketEntries = maxKEntries / _numBuckets; - const size_t blockSize = context.ioQueue->BlockSize( fileId ); - const size_t bufferSize = CDivT( (size_t)maxBucketEntries * _mapBits, blockSize * 8 ) * blockSize; - - _loadBuffers[0] = allocator.Alloc( bufferSize, blockSize ); - _loadBuffers[1] = allocator.Alloc( bufferSize, blockSize ); - _loadBuffers[2] = allocator.Alloc( bufferSize, blockSize ); - _loadBuffers[3] = allocator.Alloc( bufferSize, blockSize ); - - _unpackdMaps[0] = allocator.CAlloc( maxBucketEntries ); - _unpackdMaps[1] = allocator.CAlloc( maxBucketEntries ); + + Allocate( allocator, blockSize ); if( realBucketLengths ) memcpy( _bucketLengths, realBucketLengths, sizeof( _bucketLengths ) ); @@ -54,6 +47,13 @@ struct DiskMapReader ASSERT( _numBuckets == context.numBuckets ); } + // Allocation-checker dummy + //----------------------------------------------------------- + DiskMapReader( IAllocator& allocator, const size_t blockSize ) + { + Allocate( allocator, blockSize ); + } + //----------------------------------------------------------- void LoadNextEntries( const uint64 entryCount ) { @@ -210,6 +210,22 @@ struct DiskMapReader } private: + //----------------------------------------------------------- + inline void Allocate( IAllocator& allocator, const size_t blockSize ) + { + const uint64 maxKEntries = ( 1ull << _k ); + const uint64 maxBucketEntries = maxKEntries / _numBuckets; + const size_t bufferSize = CDivT( (size_t)maxBucketEntries * _mapBits, blockSize * 8 ) * blockSize; + + _loadBuffers[0] = allocator.Alloc( bufferSize, blockSize ); + _loadBuffers[1] = allocator.Alloc( bufferSize, blockSize ); + _loadBuffers[2] = allocator.Alloc( bufferSize, blockSize ); + _loadBuffers[3] = allocator.Alloc( bufferSize, blockSize ); + + _unpackdMaps[0] = allocator.CAlloc( maxBucketEntries ); + _unpackdMaps[1] = allocator.CAlloc( maxBucketEntries ); + } + //----------------------------------------------------------- inline void* GetBucketBuffer( const uint32 bucket ) { @@ -249,29 +265,29 @@ struct DiskPairAndMapReader using MapReader = DiskMapReader; + // #TODO: Don't do this nonesense, just forget about not having nullables and just use pointers... + //----------------------------------------------------------- + DiskPairAndMapReader() {} + //----------------------------------------------------------- DiskPairAndMapReader( DiskPlotContext& context, const uint32 threadCount, Fence& fence, const TableId table, IAllocator& allocator, bool noMap ) - : _context ( context ) - , _fence ( fence ) + : _context ( &context ) + , _fence ( &fence ) , _table ( table ) , _threadCount( threadCount ) , _mapReader ( context, threadCount, table, FileId::MAP2 + (FileId)table - 1, allocator ) , _noMap ( noMap ) { - DiskBufferQueue& ioQueue = *_context.ioQueue; - - const uint64 maxBucketEntries = (uint64)DiskPlotInfo::MaxBucketEntries; - const size_t blockSize = ioQueue.BlockSize( FileId::T1 + (FileId)table ); + DiskBufferQueue& ioQueue = *_context->ioQueue; - const size_t bufferSize = blockSize + CDivT( (size_t)maxBucketEntries * _pairBits, blockSize * 8 ) * blockSize; + const size_t blockSize = ioQueue.BlockSize( FileId::T1 + (FileId)table ); - _pairBuffers[0] = allocator.Alloc( bufferSize, blockSize ); - _pairBuffers[1] = allocator.Alloc( bufferSize, blockSize ); + Allocate( allocator, blockSize ); size_t prevOverflowBits = 0; for( uint32 i = 0; i < _numBuckets; i++ ) { - const size_t bucketLength = _context.ptrTableBucketCounts[(int)_table][i]; + const size_t bucketLength = _context->ptrTableBucketCounts[(int)_table][i]; const size_t bucketBitSize = bucketLength * _pairBits - prevOverflowBits; const size_t bucketByteSize = CDiv( bucketBitSize, 8 ); const size_t bucketBlockAlignedSize = CDivT( bucketByteSize, blockSize ) * blockSize; @@ -286,6 +302,14 @@ struct DiskPairAndMapReader } } + // Allocation size-check dummy + //----------------------------------------------------------- + DiskPairAndMapReader( IAllocator& allocator, const size_t blockSize ) + { + Allocate( allocator, blockSize ); + MapReader reader( allocator, blockSize ); + } + //----------------------------------------------------------- void LoadNextBucket() { @@ -296,7 +320,7 @@ struct DiskPairAndMapReader ASSERT( _table > TableId::Table1 ); - DiskBufferQueue& ioQueue = *_context.ioQueue; + DiskBufferQueue& ioQueue = *_context->ioQueue; const FileId fileId = FileId::T1 + (FileId)_table; const size_t blockSize = ioQueue.BlockSize( FileId::T1 + (FileId)_table); @@ -311,22 +335,22 @@ struct DiskPairAndMapReader // Load accompanying map entries if( !_noMap ) - _mapReader.LoadNextEntries( _context.ptrTableBucketCounts[(int)_table][bucket] ); + _mapReader.LoadNextEntries( _context->ptrTableBucketCounts[(int)_table][bucket] ); - ioQueue.SignalFence( _fence, bucket+1 ); + ioQueue.SignalFence( *_fence, bucket+1 ); ioQueue.CommitCommands(); } //----------------------------------------------------------- uint64 UnpackBucket( const uint32 bucket, Pair* outPairs, uint64* outMap, Duration& ioWait ) { - DiskBufferQueue& ioQueue = *_context.ioQueue; + DiskBufferQueue& ioQueue = *_context->ioQueue; const uint32 loadIdx = bucket & 1; // Same as % 2 const size_t blockSize = ioQueue.BlockSize( FileId::T1 + (FileId)_table ); const size_t blockBitSize = blockSize * 8; - _fence.Wait( bucket + 1, ioWait ); + _fence->Wait( bucket + 1, ioWait ); const byte* pairBuffer = (byte*)_pairBuffers[loadIdx]; @@ -344,9 +368,9 @@ struct DiskPairAndMapReader const size_t fullBitSize = _pairBucketLoadSize[bucket] * 8 + blockBitSize - startBit; - const int64 bucketLength = (int64)_context.ptrTableBucketCounts[(int)_table][bucket]; + const int64 bucketLength = (int64)_context->ptrTableBucketCounts[(int)_table][bucket]; - AnonMTJob::Run( *_context.threadPool, _threadCount, [=]( AnonMTJob* self ) { + AnonMTJob::Run( *_context->threadPool, _threadCount, [=]( AnonMTJob* self ) { Pair* pairs = outPairs; @@ -374,8 +398,19 @@ struct DiskPairAndMapReader } private: - DiskPlotContext& _context; - Fence& _fence; + //----------------------------------------------------------- + inline void Allocate( IAllocator& allocator, const size_t blockSize ) + { + const uint64 maxBucketEntries = (uint64)DiskPlotInfo::MaxBucketEntries; + const size_t bufferSize = blockSize + CDivT( (size_t)maxBucketEntries * _pairBits, blockSize * 8 ) * blockSize; + + _pairBuffers[0] = allocator.Alloc( bufferSize, blockSize ); + _pairBuffers[1] = allocator.Alloc( bufferSize, blockSize ); + } + +private: + DiskPlotContext* _context = nullptr; + Fence* _fence = nullptr; MapReader _mapReader; @@ -385,8 +420,8 @@ struct DiskPairAndMapReader uint64 _entriesLoaded = 0; uint32 _bucketsLoaded = 0; - uint32 _threadCount; - TableId _table; + uint32 _threadCount = 0; + TableId _table = (TableId)0; bool _noMap; }; @@ -401,29 +436,29 @@ template class BlockReader { public: - + + //----------------------------------------------------------- + BlockReader() {} + //----------------------------------------------------------- BlockReader( const FileId fileId, DiskBufferQueue* ioQueue, const uint64 maxLength, IAllocator& allocator, const size_t blockSize, const uint64 retainOffset ) - : _fileId( fileId ) + : _fileId ( fileId ) , _entriesPerBlock( blockSize / sizeof( T ) ) - , _ioQueue( ioQueue ) + , _ioQueue ( ioQueue ) { // #TODO: Check that sizeof( T ) is power of 2 ASSERT( _entriesPerBlock * sizeof( T ) == blockSize ); - - const size_t prefixZoneCount = RoundUpToNextBoundaryT( retainOffset, _entriesPerBlock ); - - // Add another retain offset here because we space for retained entries at the start and at the end - const size_t allocCount = prefixZoneCount + RoundUpToNextBoundaryT( _entriesPerBlock + maxLength + retainOffset, _entriesPerBlock ); - - _loadBuffer[0] = allocator.CAlloc( allocCount, blockSize ) + prefixZoneCount; - _loadBuffer[1] = allocator.CAlloc( allocCount, blockSize ) + prefixZoneCount; + Allocate( allocator, blockSize, maxLength, retainOffset ); } + // Size-check dummy //----------------------------------------------------------- - BlockReader() - {} + BlockReader( IAllocator& allocator, const size_t blockSize, const uint64 maxLength, const uint64 retainOffset ) + : _entriesPerBlock( blockSize / sizeof( T ) ) + { + Allocate( allocator, blockSize, maxLength, retainOffset ); + } // #NOTE: User is responsible for using a Fence after this call //----------------------------------------------------------- @@ -496,6 +531,18 @@ class BlockReader } private: + //----------------------------------------------------------- + inline void Allocate( IAllocator& allocator, const size_t blockSize, const uint64 maxLength, const uint64 retainOffset ) + { + const size_t prefixZoneCount = RoundUpToNextBoundaryT( retainOffset, _entriesPerBlock ); + + // Add another retain offset here because we space for retained entries at the start and at the end + const size_t allocCount = prefixZoneCount + RoundUpToNextBoundaryT( _entriesPerBlock + maxLength + retainOffset, _entriesPerBlock ); + + _loadBuffer[0] = allocator.CAlloc( allocCount, blockSize ) + prefixZoneCount; + _loadBuffer[1] = allocator.CAlloc( allocCount, blockSize ) + prefixZoneCount; + } + //----------------------------------------------------------- inline uint64 GetPreloadedEntryCount() { @@ -544,6 +591,12 @@ class SingleFileMapReader : public IP3LMapReader memcpy( _bucketCounts, bucketCounts, sizeof( _bucketCounts ) ); } + // Size-check dummy + //----------------------------------------------------------- + SingleFileMapReader( IAllocator& allocator, const size_t blockSize, const uint64 maxLength ) + : _reader( allocator, blockSize, maxLength, _retainCount ) + {} + //----------------------------------------------------------- void LoadNextBucket() override { diff --git a/src/plotdisk/DiskPlotContext.h b/src/plotdisk/DiskPlotContext.h index 47220230..6c4c3af5 100644 --- a/src/plotdisk/DiskPlotContext.h +++ b/src/plotdisk/DiskPlotContext.h @@ -20,7 +20,8 @@ struct DiskPlotConfig uint32 ioBufferCount = 0; size_t cacheSize = 0; - bool bounded = false; // Do not overflow entries + bool bounded = true; // Do not overflow entries + bool alternateBuckets = false; // Alternate bucket writing method between interleaved and not bool noTmp1DirectIO = false; // Disable direct I/O on tmp 1 bool noTmp2DirectIO = false; // Disable direct I/O on tmp 1 diff --git a/src/plotdisk/DiskPlotPhase3.cpp b/src/plotdisk/DiskPlotPhase3.cpp index fba876f5..6fe45550 100644 --- a/src/plotdisk/DiskPlotPhase3.cpp +++ b/src/plotdisk/DiskPlotPhase3.cpp @@ -129,7 +129,22 @@ class P3StepOne static constexpr uint32 _idxBits = _k + 1; static constexpr uint32 _entrySizeBits = _lpBits + _idxBits; // LP, origin index + using PMReader = DiskPairAndMapReader<_numBuckets, _bounded>; + using L1Reader = SingleFileMapReader<_numBuckets, P3_EXTRA_L_ENTRIES_TO_LOAD, uint32>; + using LNReader = DiskMapReader; + public: + + // Dummy for size calculation + //----------------------------------------------------------- + P3StepOne() + : _context ( *(DiskPlotContext*)nullptr ) + , _ioQueue ( *(DiskBufferQueue*)nullptr ) + , _mapReadId ( (FileId)0 ) + , _readFence ( *(Fence*)nullptr ) + , _writeFence( *(Fence*)nullptr ) + {} + //----------------------------------------------------------- P3StepOne( DiskPlotContext& context, const FileId mapReadId, Fence& readFence, Fence& writeFence ) : _context ( context ) @@ -147,62 +162,103 @@ class P3StepOne inline Duration GetIOWaitTime() const { return _ioWaitTime; } //----------------------------------------------------------- - uint64 Run( const uint64 inLMapBucketCounts[_numBuckets+1], uint64 outLPBucketCounts[_numBuckets+1] ) + void Allocate( const bool dryRun, IAllocator& allocator, const size_t tmp1BlockSize, const size_t tmp2BlockSize, const uint64* inLMapBucketCounts, + void*& rMarks, + PMReader& rTableReader, + IP3LMapReader*& lReader, + L1Reader& lTable1Reader, + LNReader& lTableNReader, + uint32*& lTableNEntries, + Pair*& pairs, + uint64*& map + ) { - DiskPlotContext& context = _context; - DiskBufferQueue& ioQueue = _ioQueue; - - ioQueue.SeekBucket( FileId::LP, 0, SeekOrigin::Begin ); - ioQueue.CommitCommands(); - const TableId lTable = rTable - 1; const uint64 maxBucketEntries = (uint64)( ( (1ull << _k) / _numBuckets ) * P3_BUCKET_MULTIPLER ); - const size_t rMarksSize = RoundUpToNextBoundary( context.entryCounts[(int)rTable] / 8, (int)context.tmp1BlockSize ); - - // Allocate buffers - StackAllocator allocator( context.heapBuffer, context.heapSize ); - - void* rMarks = allocator.Alloc( rMarksSize, context.tmp1BlockSize ); + const size_t rMarksSize = RoundUpToNextBoundary( maxBucketEntries * _numBuckets / 8, (int)tmp1BlockSize ); + //RoundUpToNextBoundary( _context.entryCounts[(int)rTable] / 8, (int)context.tmp1BlockSize ); - DiskPairAndMapReader<_numBuckets, _bounded> rTableReader( context, _threadCount, _readFence, rTable, allocator, false ); - using L1Reader = SingleFileMapReader<_numBuckets, P3_EXTRA_L_ENTRIES_TO_LOAD, uint32>; - using LNReader = DiskMapReader; + rMarks = allocator.Alloc( rMarksSize, tmp1BlockSize ); + rTableReader = dryRun ? PMReader( allocator, tmp1BlockSize ) + : PMReader( _context, _threadCount, _readFence, rTable, allocator, false ); - - IP3LMapReader* lReader = nullptr; - - L1Reader lTable1Reader; - LNReader lTableNReader; - uint32* lTableNEntries = nullptr; + lReader = nullptr; + lTableNEntries = nullptr; if constexpr ( lTable == TableId::Table1 ) { - lTable1Reader = L1Reader( FileId::T1, &ioQueue, allocator, maxBucketEntries, context.tmp1BlockSize, context.bucketCounts[(int)TableId::Table1] ); + lTable1Reader = dryRun ? L1Reader( allocator, tmp1BlockSize, maxBucketEntries ) + : L1Reader( FileId::T1, _context.ioQueue, allocator, maxBucketEntries, tmp2BlockSize, _context.bucketCounts[(int)TableId::Table1] ); lReader = &lTable1Reader; } else { - lTableNReader = LNReader( _context, _context.p3ThreadCount, lTable, _mapReadId, allocator, inLMapBucketCounts ); + lTableNReader = dryRun ? LNReader( allocator, tmp2BlockSize ) + : LNReader( _context, _context.p3ThreadCount, lTable, _mapReadId, allocator, inLMapBucketCounts ); lTableNEntries = allocator.CAlloc( maxBucketEntries + P3_EXTRA_L_ENTRIES_TO_LOAD ); } { - const size_t perBucketWriteSize = CDiv( maxBucketEntries * _entrySizeBits / _numBuckets, (int)context.tmp2BlockSize * 8 ) * context.tmp2BlockSize; - const size_t writeBufferAllocSize = RoundUpToNextBoundary( perBucketWriteSize * _numBuckets, (int)context.tmp2BlockSize ); + const size_t perBucketWriteSize = CDiv( maxBucketEntries * _entrySizeBits / _numBuckets, (int)tmp2BlockSize * 8 ) * tmp2BlockSize; + const size_t writeBufferAllocSize = RoundUpToNextBoundary( perBucketWriteSize * _numBuckets, (int)tmp2BlockSize ); - _lpWriteBuffer[0] = allocator.AllocT( writeBufferAllocSize, context.tmp2BlockSize ); - _lpWriteBuffer[1] = allocator.AllocT( writeBufferAllocSize, context.tmp2BlockSize ); + _lpWriteBuffer[0] = allocator.AllocT( writeBufferAllocSize, tmp2BlockSize ); + _lpWriteBuffer[1] = allocator.AllocT( writeBufferAllocSize, tmp2BlockSize ); - byte* blockBuffers = (byte*)allocator.CAlloc( _numBuckets, context.tmp2BlockSize, context.tmp2BlockSize ); - _lpWriter = BitBucketWriter<_numBuckets>( ioQueue, FileId::LP, blockBuffers ); - } + byte* blockBuffers = (byte*)allocator.CAlloc( _numBuckets, tmp2BlockSize, tmp2BlockSize ); - Pair* pairs = allocator.CAlloc ( maxBucketEntries ); - uint64* map = allocator.CAlloc( maxBucketEntries ); + if( !dryRun ) + _lpWriter = BitBucketWriter<_numBuckets>( *_context.ioQueue, FileId::LP, blockBuffers ); + } + pairs = allocator.CAlloc ( maxBucketEntries ); + map = allocator.CAlloc( maxBucketEntries ); _rPrunedLinePoints = allocator.CAlloc( maxBucketEntries ); _rPrunedMap = allocator.CAlloc( maxBucketEntries ); + } + + + //----------------------------------------------------------- + uint64 Run( const uint64 inLMapBucketCounts[_numBuckets+1], uint64 outLPBucketCounts[_numBuckets+1] ) + { + DiskPlotContext& context = _context; + DiskBufferQueue& ioQueue = _ioQueue; + + ioQueue.SeekBucket( FileId::LP, 0, SeekOrigin::Begin ); + ioQueue.CommitCommands(); + + #if _DEBUG + const uint64 maxBucketEntries = (uint64)( ( (1ull << _k) / _numBuckets ) * P3_BUCKET_MULTIPLER ); + #endif + + const TableId lTable = rTable - 1; + const size_t rMarksSize = RoundUpToNextBoundary( context.entryCounts[(int)rTable] / 8, (int)context.tmp1BlockSize ); + + // Allocate buffers + StackAllocator allocator( context.heapBuffer, context.heapSize ); + + void* rMarks; + PMReader rTableReader; + IP3LMapReader* lReader; + L1Reader lTable1Reader; + LNReader lTableNReader; + uint32* lTableNEntries; + Pair* pairs; + uint64* map; + + Allocate( false, allocator, context.tmp1BlockSize, context.tmp2BlockSize, inLMapBucketCounts, + rMarks, + rTableReader, + lReader, + lTable1Reader, + lTableNReader, + lTableNEntries, + pairs, + map ); + + Log::Line( "Step 1 Allocated %.2lf / %.2lf MiB", (double)allocator.Size() BtoMB, (double)allocator.Capacity() BtoMB ); + auto GetLLoadCount = [=]( const uint32 bucket ) { @@ -233,8 +289,6 @@ class P3StepOne LoadBucket( 0 ); - Log::Line( "Allocated %.2lf / %.2lf MiB", (double)allocator.Size() BtoMB, (double)allocator.Capacity() BtoMB ); - for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) { // Load next bucket in the background @@ -286,6 +340,34 @@ class P3StepOne return _prunedEntryCount; } + //----------------------------------------------------------- + inline static size_t GetRequiredHeapSize( const size_t tmp1BlockSize, const size_t tmp2BlockSize ) + { + void* rMarks; + PMReader rTableReader; + IP3LMapReader* lReader; + L1Reader lTable1Reader; + LNReader lTableNReader; + uint32* lTableNEntries; + Pair* pairs; + uint64* map; + + DummyAllocator allocator; + + P3StepOne instance; + instance.Allocate( true, allocator, tmp1BlockSize, tmp2BlockSize, nullptr, + rMarks, + rTableReader, + lReader, + lTable1Reader, + lTableNReader, + lTableNEntries, + pairs, + map ); + + return allocator.Size(); + } + private: //----------------------------------------------------------- uint64 ConvertToLinePoints( @@ -570,8 +652,23 @@ class P3StepTwo static constexpr uint32 _lpBits = _k * 2 - ( _bucketBits + 1 ); // LPs have at most 2*k-1. Because we ommit the bucket bits, we substract those too. static constexpr uint32 _idxBits = _k + 1; static constexpr uint32 _entrySizeBits = _lpBits + _idxBits; // LP, origin index + static constexpr bool _overflow = rTable == TableId::Table7; + + using S2MapWriter = MapWriter<_numBuckets, _overflow>; public: + // Dummy constructor: Used simply to run allocation (yes, ugly/hacky-looking ) + //----------------------------------------------------------- + P3StepTwo() + : _context ( *(DiskPlotContext*)nullptr ) + , _ioQueue ( *(DiskBufferQueue*)nullptr ) + , _readFence ( *(Fence*)nullptr ) + , _writeFence ( *(Fence*)nullptr ) + , _lpWriteFence( *(Fence*)nullptr ) + , _readId ( (FileId)0 ) + , _writeId ( (FileId)0 ) + {} + //----------------------------------------------------------- P3StepTwo( DiskPlotContext& context, Fence& readFence, Fence& writeFence, Fence& lpWriteFence, const FileId readId, const FileId writeId ) : _context ( context ) @@ -592,40 +689,78 @@ class P3StepTwo inline Duration GetIOWaitTime() const { return _ioWaitTime; } //----------------------------------------------------------- - void Run( const uint64 inLPBucketCounts[_numBuckets+1], uint64 outLMapBucketCounts[_numBuckets+1] ) + inline static size_t GetRequiredHeapSize( const size_t tmp1BlockSize, const size_t tmp2BlockSize ) { - constexpr bool _overflow = rTable == TableId::Table7; - - _ioQueue.SeekBucket( FileId::LP, 0, SeekOrigin::Begin ); - _ioQueue.CommitCommands(); + DummyAllocator allocator; + S2MapWriter mapWriter; + byte* readBuffers[2]; + uint64* linePoints; + uint64* tmpLinePoints; + uint64* indices; + uint64* tmpIndices; + + P3StepTwo instance; + instance.Allocate( true, allocator, tmp1BlockSize, tmp2BlockSize, + mapWriter, readBuffers, linePoints, tmpLinePoints, indices, tmpIndices ); + + return allocator.Size(); + } + //----------------------------------------------------------- + inline void Allocate( bool dryRun, IAllocator& allocator, const size_t tmp1BlockSize, const size_t tmp2BlockSize, + S2MapWriter& outMapWriter, byte* readBuffers[2], uint64*& linePoints, uint64*& tmpLinePoints, uint64*& indices, uint64*& tmpIndices ) + { const TableId lTable = rTable - 1; const uint64 maxBucketEntries = (uint64)( ( (1ull << _k) / _numBuckets ) * P3_BUCKET_MULTIPLER ); - // Allocate buffers and needed structures - StackAllocator allocator( _context.heapBuffer, _context.heapSize ); + const size_t readBufferSize = RoundUpToNextBoundary( CDiv( maxBucketEntries * _entrySizeBits, 8 ), (int)tmp2BlockSize ); - const size_t readBufferSize = RoundUpToNextBoundary( CDiv( maxBucketEntries * _entrySizeBits, 8 ), (int)_context.tmp2BlockSize ); - byte* readBuffers[2] = { - allocator.AllocT( readBufferSize, _context.tmp2BlockSize ), - allocator.AllocT( readBufferSize, _context.tmp2BlockSize ), - }; + readBuffers[0] = allocator.AllocT( readBufferSize, tmp2BlockSize ); + readBuffers[1] = allocator.AllocT( readBufferSize, tmp2BlockSize ), - uint64* linePoints = allocator.CAlloc( maxBucketEntries + kEntriesPerPark ); // Need to add kEntriesPerPark so we can copy - uint64* tmpLinePoints = allocator.CAlloc( maxBucketEntries + kEntriesPerPark ); // the park overflows from the previous bucket. - uint64* indices = allocator.CAlloc( maxBucketEntries ); - uint64* tmpIndices = allocator.CAlloc( maxBucketEntries ); + linePoints = allocator.CAlloc( maxBucketEntries + kEntriesPerPark ); // Need to add kEntriesPerPark so we can copy + tmpLinePoints = allocator.CAlloc( maxBucketEntries + kEntriesPerPark ); // the park overflows from the previous bucket. + indices = allocator.CAlloc( maxBucketEntries ); + tmpIndices = allocator.CAlloc( maxBucketEntries ); - MapWriter<_numBuckets, _overflow> mapWriter( _ioQueue, _writeId, allocator, maxBucketEntries, _context.tmp2BlockSize, _writeFence, _ioWaitTime ); + if( dryRun ) + outMapWriter = S2MapWriter( maxBucketEntries, allocator, tmp2BlockSize ); + else + outMapWriter = S2MapWriter( _ioQueue, _writeId, allocator, maxBucketEntries, tmp2BlockSize, _writeFence, _ioWaitTime ); const size_t parkSize = CalculateParkSize( lTable ); + _maxParkCount = maxBucketEntries / kEntriesPerPark; _lpLeftOverBuffer = allocator.CAlloc( kEntriesPerPark ); _parkBuffers[0] = allocator.AllocT( parkSize * _maxParkCount ); _parkBuffers[1] = allocator.AllocT( parkSize * _maxParkCount ); + _finalPark = allocator.AllocT( parkSize ); + } + + //----------------------------------------------------------- + void Run( const uint64 inLPBucketCounts[_numBuckets+1], uint64 outLMapBucketCounts[_numBuckets+1] ) + { + _ioQueue.SeekBucket( FileId::LP, 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); + + // const TableId lTable = rTable - 1; + const uint64 maxBucketEntries = (uint64)( ( (1ull << _k) / _numBuckets ) * P3_BUCKET_MULTIPLER ); + + // Allocate buffers and needed structures + S2MapWriter mapWriter; + byte* readBuffers[2]; + uint64* linePoints; + uint64* tmpLinePoints; + uint64* indices; + uint64* tmpIndices; + + StackAllocator allocator( _context.heapBuffer, _context.heapSize ); + Allocate( false, allocator, _context.tmp1BlockSize, _context.tmp2BlockSize, + mapWriter, readBuffers, linePoints, tmpLinePoints, indices, tmpIndices ); Log::Line( "Step 2 using %.2lf / %.2lf GiB.", (double)allocator.Size() BtoGB, (double)allocator.Capacity() BtoGB ); + // Start processing buckets auto LoadBucket = [=]( uint32 bucket ) { const size_t readSize = RoundUpToNextBoundary( CDiv( inLPBucketCounts[bucket] * _entrySizeBits, 8 ), (int)_context.tmp2BlockSize ); @@ -697,7 +832,7 @@ class P3StepTwo } // #NOTE: sortedLinePoints get mutated here - WriteLinePointsToPlot( allocator, bucket, (uint64)entryCount, sortedLinePoints, hasNextBucket ); + WriteLinePointsToPlot( bucket, (uint64)entryCount, sortedLinePoints, hasNextBucket ); mapOffset += (uint64)entryCount; } @@ -742,7 +877,7 @@ class P3StepTwo } //----------------------------------------------------------- - void WriteLinePointsToPlot( IAllocator& allocator, const uint32 bucket, const uint64 entryCount, uint64* inLinePoints, const bool hasNextBucket ) + void WriteLinePointsToPlot( const uint32 bucket, const uint64 entryCount, uint64* inLinePoints, const bool hasNextBucket ) { ASSERT( entryCount ); ASSERT( inLinePoints ); @@ -802,11 +937,10 @@ class P3StepTwo if( overflowEntries ) { // #NOTE: This functions mutates inLinePoints - byte* finalPark = allocator.AllocT( parkSize ); - WritePark( parkSize, overflowEntries, lpOverflowStart, finalPark, lTable ); + WritePark( parkSize, overflowEntries, lpOverflowStart, _finalPark, lTable ); _context.plotTableSizes[(int)lTable] += parkSize; - ioQueue.WriteFile( FileId::PLOT, 0, finalPark, parkSize ); + ioQueue.WriteFile( FileId::PLOT, 0, _finalPark, parkSize ); ioQueue.CommitCommands(); } @@ -837,6 +971,7 @@ class P3StepTwo uint64 _lpParkLeftOvers = 0; uint64 _maxParkCount = 0; byte* _parkBuffers[2] = { nullptr }; + byte* _finalPark = nullptr; }; @@ -930,6 +1065,34 @@ void DiskPlotPhase3::Run() #endif } +//----------------------------------------------------------- +size_t DiskPlotPhase3::GetRequiredHeapSize( const uint32 numBuckets, const bool bounded, const size_t t1BlockSize, const size_t t2BlockSize ) +{ + switch( numBuckets ) + { + case 128 : return bounded ? GetRequiredHeapSizeForBuckets<128 , true>( t1BlockSize, t2BlockSize ) : GetRequiredHeapSizeForBuckets<128 , false>( t1BlockSize, t2BlockSize ); + case 64 : return bounded ? GetRequiredHeapSizeForBuckets<64 , true>( t1BlockSize, t2BlockSize ) : GetRequiredHeapSizeForBuckets<64 , false>( t1BlockSize, t2BlockSize ); + case 256 : return bounded ? GetRequiredHeapSizeForBuckets<256 , true>( t1BlockSize, t2BlockSize ) : GetRequiredHeapSizeForBuckets<256 , false>( t1BlockSize, t2BlockSize ); + case 512 : return bounded ? GetRequiredHeapSizeForBuckets<512 , true>( t1BlockSize, t2BlockSize ) : GetRequiredHeapSizeForBuckets<512 , false>( t1BlockSize, t2BlockSize ); + case 1024: return bounded ? GetRequiredHeapSizeForBuckets<1024, true>( t1BlockSize, t2BlockSize ) : GetRequiredHeapSizeForBuckets<1024, false>( t1BlockSize, t2BlockSize ); + + default: + break; + } + + Fatal( "Unexpected bucket size %u.", numBuckets ); +} + +//----------------------------------------------------------- +template +size_t DiskPlotPhase3::GetRequiredHeapSizeForBuckets( const size_t t1BlockSize, const size_t t2BlockSize ) +{ + const size_t s1Size = P3StepOne::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); + const size_t s2Size = P3StepTwo::GetRequiredHeapSize( t1BlockSize, t2BlockSize ); + + return std::max( s1Size, s2Size ); +} + //----------------------------------------------------------- void DiskPlotPhase3::GetCacheSizes( size_t& outCacheSizeLP, size_t& outCacheSizeMap ) { @@ -969,6 +1132,8 @@ void DiskPlotPhase3::GetCacheSizesForBuckets( size_t& outCacheSizeLP, size_t& ou ASSERT( outCacheSizeMap + outCacheSizeLP <= fullCache ); } + + //----------------------------------------------------------- template void DiskPlotPhase3::RunBuckets() diff --git a/src/plotdisk/DiskPlotPhase3.h b/src/plotdisk/DiskPlotPhase3.h index 0f60f640..a47a3c55 100644 --- a/src/plotdisk/DiskPlotPhase3.h +++ b/src/plotdisk/DiskPlotPhase3.h @@ -12,6 +12,7 @@ class DiskPlotPhase3 void Run(); + static size_t GetRequiredHeapSize( const uint32 numBuckets, const bool bounded, const size_t t1BlockSize, const size_t t2BlockSize ); private: template @@ -65,6 +66,9 @@ class DiskPlotPhase3 template void GetCacheSizesForBuckets( size_t& outCacheSizeLP, size_t& outCacheSizeMap ); + + template + static size_t GetRequiredHeapSizeForBuckets( const size_t t1BlockSize, const size_t t2BlockSize ); private: DiskPlotContext& _context; diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index bf084248..75f9b5a8 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -32,12 +32,9 @@ DiskPlotter::DiskPlotter( const Config& cfg ) LoadLTargets(); ZeroMem( &_cx ); - + GlobalPlotConfig& gCfg = *cfg.globalCfg; - FatalIf( !GetTmpPathsBlockSizes( cfg.tmpPath, cfg.tmpPath2, _cx.tmp1BlockSize, _cx.tmp2BlockSize ), - "Failed to obtain temp paths block size from t1: '%s' or %s t2: '%s'.", cfg.tmpPath, cfg.tmpPath2 ); - // #TODO: Remove when fixed { FatalIf( cfg.numBuckets == 128, "128 Buckets is currently not serializing plots correctly. Please select a differnt bucket count." ); @@ -49,6 +46,9 @@ DiskPlotter::DiskPlotter( const Config& cfg ) } } + FatalIf( !GetTmpPathsBlockSizes( cfg.tmpPath, cfg.tmpPath2, _cx.tmp1BlockSize, _cx.tmp2BlockSize ), + "Failed to obtain temp paths block size from t1: '%s' or %s t2: '%s'.", cfg.tmpPath, cfg.tmpPath2 ); + FatalIf( _cx.tmp1BlockSize < 8 || _cx.tmp2BlockSize < 8,"File system block size is too small.." ); const uint sysLogicalCoreCount = SysHost::GetLogicalCPUCount(); @@ -62,10 +62,7 @@ DiskPlotter::DiskPlotter( const Config& cfg ) _cx.p2ThreadCount = cfg.p2ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.p2ThreadCount, sysLogicalCoreCount ); _cx.p3ThreadCount = cfg.p3ThreadCount == 0 ? gCfg.threadCount : std::min( cfg.p3ThreadCount, sysLogicalCoreCount ); - const size_t heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize, _cx.fpThreadCount ) - // #TODO: Remove, testing for now - + 6ull GB - ; + const size_t heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, _cx.tmp1BlockSize, _cx.tmp2BlockSize, _cx.fpThreadCount ); ASSERT( heapSize ); _cfg = cfg; @@ -292,7 +289,9 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) { if( cli.ReadU32( cfg.numBuckets, "-b", "--buckets" ) ) continue; - if( cli.ReadSwitch( cfg.bounded, "--k32-bounded" ) ) + if( cli.ReadUnswitch( cfg.bounded, "--unbounded" ) ) + continue; + if( cli.ReadSwitch( cfg.alternateBuckets, "-a", "--alternate" ) ) continue; if( cli.ReadStr( cfg.tmpPath, "-t1", "--temp1" ) ) continue; @@ -316,8 +315,6 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) continue; if( cli.ArgConsume( "-s", "--sizes" ) ) { - // #TODO: Get sizes for bounded - FatalIf( cfg.numBuckets < BB_DP_MIN_BUCKET_COUNT || cfg.numBuckets > BB_DP_MAX_BUCKET_COUNT, "Buckets must be between %u and %u, inclusive.", (uint)BB_DP_MIN_BUCKET_COUNT, (uint)BB_DP_MAX_BUCKET_COUNT ); FatalIf( ( cfg.numBuckets & ( cfg.numBuckets - 1 ) ) != 0, "Buckets must be power of 2." ); @@ -395,83 +392,19 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) //----------------------------------------------------------- bool DiskPlotter::GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPath2, size_t& tmpPath1Size, size_t& tmpPath2Size ) { - ASSERT( tmpPath1 ); - ASSERT( tmpPath2 ); - - bool success = false; - - const char* paths[2] = { tmpPath1, tmpPath2 }; - const size_t lengths[2] = { - strlen( tmpPath1 ), - strlen( tmpPath2 ), - }; - - const size_t RAND_PART = 16; - const size_t RAND_FILE_SIZE = RAND_PART + 4; // 5 = '.' + ".tmp" - const size_t MAX_LENGTH = 1024 + RAND_FILE_SIZE + 1; - char stackPath[MAX_LENGTH+1]; - - const size_t pathLength = std::max( lengths[0], lengths[1] ) + RAND_FILE_SIZE + 1; - - char* path = nullptr; - if( pathLength > MAX_LENGTH ) - path = bbmalloc( pathLength + RAND_FILE_SIZE + 2 ); // +2 = '/' + '\0' - else - path = stackPath; - - size_t blockSizes[2] = { 0 }; - - // #TODO: Don't do this. We can just use the dir to get block size - for( int32 i = 0; i < 2; i++ ) - { - size_t len = lengths[i]; - memcpy( path, paths[i], len ); - - if( path[len-1] != '/' && path[len-1] != '\\' ) - path[len++] = '/'; - - path[len++] = '.'; - - byte filename[RAND_PART/2]; - SysHost::Random( filename, sizeof( filename ) ); - - size_t encoded; - if( BytesToHexStr( filename, sizeof( filename ), path+len, RAND_PART, encoded ) != 0 ) - { - Log::Error( "GetTmpPathsBlockSizes: Hex conversion failed." ); - goto EXIT; - } + ASSERT( tmpPath1 && *tmpPath1 ); + ASSERT( tmpPath2 && *tmpPath2 ); - len += RAND_PART; - memcpy( path+len, ".tmp", sizeof( ".tmp" ) ); + FileStream tmp1Dir, tmp2Dir; - #if _DEBUG - if( path == stackPath ) - ASSERT( path+len+ sizeof( ".tmp" ) <= stackPath + sizeof( stackPath ) ); - #endif + if( !tmp1Dir.Open( tmpPath1, FileMode::Open, FileAccess::Read ) ) + return false; + if( !tmp2Dir.Open( tmpPath2, FileMode::Open, FileAccess::Read ) ) + return false; - FileStream file; - if( !file.Open( path, FileMode::Create, FileAccess::ReadWrite ) ) - { - Log::Error( "GetTmpPathsBlockSizes: Failed to open temp file '%s'.", path ); - goto EXIT; - } - - blockSizes[i] = file.BlockSize(); - file.Close(); - - remove( path ); - } - - tmpPath1Size = blockSizes[0]; - tmpPath2Size = blockSizes[1]; - success = true; - -EXIT: - if( path && path != stackPath ) - free( path ); - - return success; + tmpPath1Size = tmp1Dir.BlockSize(); + tmpPath2Size = tmp2Dir.BlockSize(); + return true; } //----------------------------------------------------------- @@ -489,11 +422,16 @@ size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 size_t DiskPlotter::GetRequiredSizeForBuckets( const bool bounded, const uint32 numBuckets, const size_t fxBlockSize, const size_t pairsBlockSize, const uint32 threadCount ) { if( bounded ) - return K32BoundedPhase1::GetRequiredSize( numBuckets, pairsBlockSize, fxBlockSize, threadCount ); + { + const size_t p1HeapSize = K32BoundedPhase1::GetRequiredSize( numBuckets, pairsBlockSize, fxBlockSize, threadCount ); + const size_t p3HeapSize = DiskPlotPhase3::GetRequiredHeapSize( numBuckets, bounded, pairsBlockSize, fxBlockSize ); + + return std::max( p1HeapSize, p3HeapSize ); + } switch( numBuckets ) { - case 128 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); + case 128 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); case 256 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); case 512 : return DiskFp::GetRequiredHeapSize( fxBlockSize, pairsBlockSize ); case 1024: @@ -573,8 +511,11 @@ Creates plots by making use of a disk to temporarily store and read values. You may specify one of: 128, 256, 512, 1024 and 64 for if --k32-bounded is enabled. 1024 is not available for plots of k < 33. - --k32-bounded : Create a bounded k32 plot. That is a plot that does not overflow entries - over 2^32; + --ubounded : Create an unbounded k32 plot. That is a plot that does not cut-off entries that + overflow 2^32; + + -a, --alternate : Halves the temp2 cache size requirements by alternating bucket writing methods + between tables. -t1, --temp1 : The temporary directory to use when plotting. *REQUIRED* diff --git a/src/util/CliParser.h b/src/util/CliParser.h index 8a87de7f..4aba32f5 100644 --- a/src/util/CliParser.h +++ b/src/util/CliParser.h @@ -76,6 +76,21 @@ class CliParser return false; } + // Same as ReadSwitch but set's the value to false if + // this parameter is matched. + //----------------------------------------------------------- + inline bool ReadUnswitch( bool& value, const char* paramA, const char* paramB = nullptr ) + { + if( ArgMatch( paramA, paramB ) ) + { + NextArg(); + value = false; + return true; + } + + return false; + } + //----------------------------------------------------------- inline bool ReadStr( const char*& value, const char* paramA, const char* paramB = nullptr ) { From d02fdab15059114794f7f0d6dec94fa38252728f Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 15 Jul 2022 22:11:43 -0500 Subject: [PATCH 64/91] Deleting P1 files. Fixed T7 writing metadata. --- src/plotdisk/DiskBufferQueue.cpp | 1 + src/plotdisk/k32/DiskPlotBounded.cpp | 26 ++++++++++++++++++++++++++ src/plotdisk/k32/FxBounded.inl | 23 +++++++++++++++++------ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index f4467fe2..e8b4cda9 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -437,6 +437,7 @@ void DiskBufferQueue::WaitForFence( Fence& fence ) void DiskBufferQueue::DeleteFile( FileId id, uint bucket ) { // Log::Line( "DeleteFile( %u : %u )", id, bucket ); + // #TODO: See DeleteBucket Command* cmd = GetCommandObject( Command::DeleteFile ); cmd->deleteFile.fileId = id; cmd->deleteFile.bucket = bucket; diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 7251b495..36c63006 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -205,6 +205,23 @@ void K32BoundedPhase1::RunWithBuckets() PanicExit(); break; } + + #if !BB_DP_P1_KEEP_FILES + if( table == TableId::Table6 ) + { + // #TODO: Support alternating mode (only 1 metadata file) + _ioQueue.DeleteBucket( FileId::META0 ); + _ioQueue.CommitCommands(); + } + else if( table == TableId::Table7 ) + { + // #TODO: Support alternating mode (only 1 metadata file) + _ioQueue.DeleteBucket( FileId::FX1 ); + _ioQueue.DeleteBucket( FileId::INDEX1 ); + _ioQueue.DeleteBucket( FileId::META1 ); + _ioQueue.CommitCommands(); + } + #endif } #endif @@ -216,6 +233,15 @@ void K32BoundedPhase1::RunWithBuckets() CTableWriterBounded<_numBuckets> cWriter( _context ); cWriter.Run( _allocator ); } + + #if !BB_DP_P1_KEEP_FILES + // #TODO: Support alternating mode (only 1 metadata file) + _ioQueue.DeleteBucket( FileId::FX0 ); + _ioQueue.DeleteBucket( FileId::INDEX0 ); + _ioQueue.CommitCommands(); + + // # TODO: Wait for deletion? + #endif } //----------------------------------------------------------- diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 6e0a7c4f..c6e25bf5 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -245,14 +245,16 @@ public: _ioQueue.SeekBucket( _yId[0], 0, SeekOrigin::Begin ); _ioQueue.SeekBucket( _yId[1], 0, SeekOrigin::Begin ); - if constexpr( rTable > TableId::Table2 ) + if( rTable > TableId::Table2 ) { _ioQueue.SeekBucket( _idxId[0], 0, SeekOrigin::Begin ); _ioQueue.SeekBucket( _idxId[1], 0, SeekOrigin::Begin ); } _ioQueue.SeekBucket( _metaId[0], 0, SeekOrigin::Begin ); - _ioQueue.SeekBucket( _metaId[1], 0, SeekOrigin::Begin ); + if( rTable < TableId::Table7 ) + _ioQueue.SeekBucket( _metaId[1], 0, SeekOrigin::Begin ); + _ioQueue.CommitCommands(); // Allocate buffers @@ -942,7 +944,9 @@ private: counts[yIn[i] >> bucketShift]++; self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, ySliceCounts.Ptr(), _offsetsY[id], yAlignedSliceCount.Ptr() ); - self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaSliceCounts.Ptr(), _offsetsMeta[id], metaAlignedSliceCount.Ptr() ); + + if constexpr ( rTable < TableId::Table7 ) + self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaSliceCounts.Ptr(), _offsetsMeta[id], metaAlignedSliceCount.Ptr() ); if( bucket > 0 ) { @@ -957,11 +961,15 @@ private: const TYOut y = yIn[i]; const uint32 yBucket = (uint32)(y >> bucketShift); const uint32 yDst = --pfxSum [yBucket]; - const uint32 metaDst = --pfxSumMeta[yBucket]; yOut [yDst] = (uint32)(y & yMask); idxOut [yDst] = idxOffset + (uint32)i; ASSERT( (uint64)idxOffset + (uint64)i < (1ull << _k) ); - metaOut[metaDst] = metaIn[i]; + + if constexpr ( rTable < TableId::Table7 ) + { + const uint32 metaDst = --pfxSumMeta[yBucket]; + metaOut[metaDst] = metaIn[i]; + } } // Write to disk @@ -975,7 +983,10 @@ private: _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); _ioQueue.WriteBucketElementsT ( idxId , idxOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); - _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), metaAlignedSliceCount.Ptr(), ySliceCounts.Ptr() ); // #TODO: Can use ySliceCounts here... + + if( rTable < TableId::Table7 ) + _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), metaAlignedSliceCount.Ptr(), ySliceCounts.Ptr() ); // #TODO: Can use ySliceCounts here... + _ioQueue.SignalFence( _fxWriteFence, bucket+1 ); _ioQueue.CommitCommands(); From 88349d99e0ed01711dff165e6d8173a6b4f323f9 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 15 Jul 2022 23:03:55 -0500 Subject: [PATCH 65/91] Added I/O metrics to P1 --- src/plotdisk/DiskBufferQueue.cpp | 8 ++-- src/plotdisk/DiskBufferQueue.h | 72 ++++++++++++++++++++++++++-- src/plotdisk/k32/DiskPlotBounded.cpp | 16 +------ 3 files changed, 75 insertions(+), 21 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index e8b4cda9..915bd58c 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -878,7 +878,7 @@ inline void DiskBufferQueue::WriteToFile( IStream& file, size_t size, const byte { // if( !_useDirectIO ) // { - #if BB_IO_METRICS_ON + #if _DEBUG || BB_IO_METRICS_ON _writeMetrics.size += size; _writeMetrics.count++; const auto timer = TimerBegin(); @@ -898,7 +898,7 @@ inline void DiskBufferQueue::WriteToFile( IStream& file, size_t size, const byte buffer += sizeWritten; } - #if BB_IO_METRICS_ON + #if _DEBUG || BB_IO_METRICS_ON _writeMetrics.time += TimerEndTicks( timer ); #endif // } @@ -946,7 +946,7 @@ inline void DiskBufferQueue::WriteToFile( IStream& file, size_t size, const byte //----------------------------------------------------------- inline void DiskBufferQueue::ReadFromFile( IStream& file, size_t size, byte* buffer, byte* blockBuffer, const size_t blockSize, const bool directIO, const char* fileName, const uint bucket ) { - #if BB_IO_METRICS_ON + #if _DEBUG || BB_IO_METRICS_ON _readMetrics.size += size; _readMetrics.count++; const auto timer = TimerBegin(); @@ -999,7 +999,7 @@ inline void DiskBufferQueue::ReadFromFile( IStream& file, size_t size, byte* buf // } } - #if BB_IO_METRICS_ON + #if _DEBUG || BB_IO_METRICS_ON _readMetrics.time += TimerEndTicks( timer ); #endif diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index c8bebc9d..4e8b310a 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -153,7 +153,7 @@ class DiskBufferQueue int64 bucket; // If < 0, delete all buckets }; -#if BB_IO_METRICS_ON +#if _DEBUG || BB_IO_METRICS_ON public: struct IOMetric { @@ -269,7 +269,7 @@ class DiskBufferQueue inline void ResetIOBufferWaitCounter() { _ioBufferWaitTime = Duration::zero(); } - #if BB_IO_METRICS_ON + #if _DEBUG || BB_IO_METRICS_ON //----------------------------------------------------------- inline const IOMetric& GetReadMetrics() const { return _readMetrics; } inline const IOMetric& GetWriteMetrics() const { return _writeMetrics;} @@ -290,6 +290,68 @@ class DiskBufferQueue return throughput; } + //----------------------------------------------------------- + inline void DumpDiskMetrics( const TableId table ) + { + const double readThroughput = GetAverageReadThroughput(); + const auto& reads = GetReadMetrics(); + const double writeThroughput = GetAverageWriteThroughput(); + const auto& writes = GetWriteMetrics(); + + Log::Line( " Table %u I/O Metrics:", (uint32)table+1 ); + + Log::Line( " Average read throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + readThroughput BtoMB, readThroughput / 1000000.0, readThroughput BtoGB, readThroughput / 1000000000.0 ); + Log::Line( " Total size read: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + (double)reads.size BtoMB, (double)reads.size / 1000000.0, (double)reads.size BtoGB, (double)reads.size / 1000000000.0 ); + Log::Line( " Total read commands: %llu.", (llu)reads.count ); + + Log::Line( " Average write throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + writeThroughput BtoMB, writeThroughput / 1000000.0, writeThroughput BtoGB, writeThroughput / 1000000000.0 ); + Log::Line( " Total size written: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + (double)writes.size BtoMB, (double)writes.size / 1000000.0, (double)writes.size BtoGB, (double)writes.size / 1000000000.0 ); + Log::Line( " Total write commands: %llu.", (llu)writes.count ); + Log::Line( "" ); + + ClearReadMetrics(); + ClearWriteMetrics(); + } + + //----------------------------------------------------------- + inline void DumpReadMetrics( const TableId table ) + { + const double readThroughput = GetAverageReadThroughput(); + const auto& reads = GetReadMetrics(); + + Log::Line( " Table %u Disk Read Metrics:", (uint32)table+1 ); + + Log::Line( " Average read throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + readThroughput BtoMB, readThroughput / 1000000.0, readThroughput BtoGB, readThroughput / 1000000000.0 ); + Log::Line( " Total size read: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + (double)reads.size BtoMB, (double)reads.size / 1000000.0, (double)reads.size BtoGB, (double)reads.size / 1000000000.0 ); + Log::Line( " Total read commands: %llu.", (llu)reads.count ); + + ClearReadMetrics(); + } + + //----------------------------------------------------------- + inline void DumpWriteMetrics( const TableId table ) + { + const double writeThroughput = GetAverageWriteThroughput(); + const auto& writes = GetWriteMetrics(); + + Log::Line( " Table %u Disk Write Metrics:", (uint32)table+1 ); + + Log::Line( " Average write throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + writeThroughput BtoMB, writeThroughput / 1000000.0, writeThroughput BtoGB, writeThroughput / 1000000000.0 ); + Log::Line( " Total size written: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", + (double)writes.size BtoMB, (double)writes.size / 1000000.0, (double)writes.size BtoGB, (double)writes.size / 1000000000.0 ); + Log::Line( " Total write commands: %llu.", (llu)writes.count ); + Log::Line( "" ); + + ClearWriteMetrics(); + } + //----------------------------------------------------------- inline void ClearReadMetrics() { @@ -301,6 +363,10 @@ class DiskBufferQueue { _writeMetrics = {}; } + #else + inline void DumpDiskMetrics(){} + inline void ClearWriteMetrics(){} + inline void ClearReadMetrics(){} #endif private: @@ -381,7 +447,7 @@ class DiskBufferQueue bool _deleterExit = false; int32 _threadBindId; -#if BB_IO_METRICS_ON +#if _DEBUG || BB_IO_METRICS_ON IOMetric _readMetrics = {}; IOMetric _writeMetrics = {}; #endif diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 36c63006..d729b523 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -260,20 +260,7 @@ void K32BoundedPhase1::RunF1() Log::Line( "Finished f1 generation in %.2lf seconds. ", elapsed ); Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _context.ioQueue->IOBufferWaitTime() ); - #if BB_IO_METRICS_ON - const double writeThroughput = _context.ioQueue->GetAverageWriteThroughput(); - const auto& writes = _context.ioQueue->GetWriteMetrics(); - - Log::Line( " Table 1 I/O Metrics:" ); - Log::Line( " Average write throughput %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", - writeThroughput BtoMB, writeThroughput / 1000000.0, writeThroughput BtoGB, writeThroughput / 1000000000.0 ); - Log::Line( " Total size written: %.2lf MiB ( %.2lf MB ) or %.2lf GiB ( %.2lf GB ).", - (double)writes.size BtoMB, (double)writes.size / 1000000.0, (double)writes.size BtoGB, (double)writes.size / 1000000000.0 ); - Log::Line( " Total write commands: %llu.", (llu)writes.count ); - Log::Line( "" ); - - _context.ioQueue->ClearWriteMetrics(); - #endif + _context.ioQueue->DumpWriteMetrics( TableId::Table1 ); } //----------------------------------------------------------- @@ -313,6 +300,7 @@ void K32BoundedPhase1::RunFx() Log::Line( "Completed table %u in %.2lf seconds with %.llu entries.", table+1, TimerEnd( timer ), _context.entryCounts[(int)table] ); Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( fx._tableIOWait ) ); + _context.ioQueue->DumpDiskMetrics( table ); #if _DEBUG BB_DP_DBG_WriteTableCounts( _context ); From a0ae9c69663c6d75129c69a30e90ee4957997aef Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 15 Jul 2022 23:18:23 -0500 Subject: [PATCH 66/91] Adding CTables I/O wait time as well --- src/plotdisk/k32/CTableWriterBounded.h | 2 ++ src/plotdisk/k32/DiskPlotBounded.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/plotdisk/k32/CTableWriterBounded.h b/src/plotdisk/k32/CTableWriterBounded.h index 851b7c6a..fd6300ba 100644 --- a/src/plotdisk/k32/CTableWriterBounded.h +++ b/src/plotdisk/k32/CTableWriterBounded.h @@ -250,6 +250,8 @@ class CTableWriterBounded // Wait for all commands to finish _readFence.Wait( 1 ); } + + inline Duration IOWait() const { return _tableIOWait; } private: diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index d729b523..f8b7cc45 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -230,8 +230,13 @@ void K32BoundedPhase1::RunWithBuckets() _allocator.PopToMarker( 0 ); Log::Line( "Sorting F7 & Writing C Tables" ); + auto timer = TimerBegin(); CTableWriterBounded<_numBuckets> cWriter( _context ); + cWriter.Run( _allocator ); + + Log::Line( "Completed F7 tables in %.2lf seconds.", TimerEnd( timer ) ); + Log::Line( "F7/C Tables I/O wait time: %.2lf seconds.", TicksToSeconds( cWriter.IOWait() ) ); } #if !BB_DP_P1_KEEP_FILES From 5640adbbdf9a82a64345d222b3950d8b331f3362 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 15 Jul 2022 23:31:57 -0500 Subject: [PATCH 67/91] Fixed I/O wait times --- src/plotdisk/k32/DiskPlotBounded.cpp | 8 ++++++-- src/plotdisk/k32/F1Bounded.inl | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index f8b7cc45..03836ebd 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -237,6 +237,7 @@ void K32BoundedPhase1::RunWithBuckets() Log::Line( "Completed F7 tables in %.2lf seconds.", TimerEnd( timer ) ); Log::Line( "F7/C Tables I/O wait time: %.2lf seconds.", TicksToSeconds( cWriter.IOWait() ) ); + _context.ioWaitTime += cWriter.IOWait(); } #if !BB_DP_P1_KEEP_FILES @@ -253,17 +254,18 @@ void K32BoundedPhase1::RunWithBuckets() template void K32BoundedPhase1::RunF1() { + _context.ioWaitTime = Duration::zero(); + Log::Line( "Generating f1..." ); auto timer = TimerBegin(); - StackAllocator allocator( _context.heapBuffer, _context.heapSize ); K32BoundedF1<_numBuckets> f1( _context, allocator ); f1.Run(); double elapsed = TimerEnd( timer ); Log::Line( "Finished f1 generation in %.2lf seconds. ", elapsed ); - Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _context.ioQueue->IOBufferWaitTime() ); + Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _context.ioWaitTime ); _context.ioQueue->DumpWriteMetrics( TableId::Table1 ); } @@ -305,7 +307,9 @@ void K32BoundedPhase1::RunFx() Log::Line( "Completed table %u in %.2lf seconds with %.llu entries.", table+1, TimerEnd( timer ), _context.entryCounts[(int)table] ); Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( fx._tableIOWait ) ); + _context.ioQueue->DumpDiskMetrics( table ); + _context.ioWaitTime += fx._tableIOWait; #if _DEBUG BB_DP_DBG_WriteTableCounts( _context ); diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index e5cfa8aa..2abb8887 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -102,7 +102,7 @@ public: Fence& fence = _context.fencePool->RequireFence(); _ioQueue.SignalFence( fence, 1 ); _ioQueue.CommitCommands(); - fence.Wait( 1 ); + fence.Wait( 1, _context.ioWaitTime ); _context.entryCounts[(int)TableId::Table1] = 1ull << _k; @@ -196,7 +196,7 @@ private: // the signal is properly visible to all threads if( self->BeginLockBlock() ) { - _writeFence.Wait( bucket, _context.p1TableWaitTime[(int)TableId::Table1] ); + _writeFence.Wait( bucket, _context.p1TableWaitTime[(int)TableId::Table1], _context.ioWaitTime ); } self->EndLockBlock(); } From 907be68739484c21e576ee8d7d3490caf162751f Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 15 Jul 2022 23:37:25 -0500 Subject: [PATCH 68/91] Fix I/O wait time assignment in f1 --- src/plotdisk/k32/DiskPlotBounded.cpp | 6 ++++-- src/plotdisk/k32/F1Bounded.inl | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 03836ebd..528984c8 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -265,8 +265,9 @@ void K32BoundedPhase1::RunF1() double elapsed = TimerEnd( timer ); Log::Line( "Finished f1 generation in %.2lf seconds. ", elapsed ); - Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _context.ioWaitTime ); - + Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _context.p1TableWaitTime[(int)TableId::Table1] ); + + _context.ioWaitTime += _context.p1TableWaitTime[(int)TableId::Table1]; _context.ioQueue->DumpWriteMetrics( TableId::Table1 ); } @@ -309,6 +310,7 @@ void K32BoundedPhase1::RunFx() Log::Line( "Table %u I/O wait time: %.2lf seconds.", table+1, TicksToSeconds( fx._tableIOWait ) ); _context.ioQueue->DumpDiskMetrics( table ); + _context.p1TableWaitTime[(int)table] = fx._tableIOWait; _context.ioWaitTime += fx._tableIOWait; #if _DEBUG diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 2abb8887..95346664 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -196,7 +196,7 @@ private: // the signal is properly visible to all threads if( self->BeginLockBlock() ) { - _writeFence.Wait( bucket, _context.p1TableWaitTime[(int)TableId::Table1], _context.ioWaitTime ); + _writeFence.Wait( bucket, _context.p1TableWaitTime[(int)TableId::Table1] ); } self->EndLockBlock(); } From d5bd812fcd289d578d30a4497baa3c70644f2edb Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 18 Jul 2022 19:28:43 -0500 Subject: [PATCH 69/91] Fixes some build errors --- .vscode/settings.json | 3 ++- src/plotdisk/DiskBufferQueue.h | 2 ++ src/plotdisk/DiskPlotDebug.h | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index e7653b02..be694e05 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -100,7 +100,8 @@ "ios": "cpp", "locale": "cpp", "stack": "cpp", - "*.include": "cpp" + "*.include": "cpp", + "relic_core.h": "c" }, "cSpell.words": [ "Ryzen" diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index 4e8b310a..8024bb0b 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -364,6 +364,8 @@ class DiskBufferQueue _writeMetrics = {}; } #else + inline void DumpWriteMetrics() {} + inline void DumpReadMetrics() {} inline void DumpDiskMetrics(){} inline void ClearWriteMetrics(){} inline void ClearReadMetrics(){} diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 47c4d3bd..75aeb017 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -311,7 +311,7 @@ inline void Debug::LoadYRefTable( const TableId table, Span& buffer ) sprintf( path, "%st%d.y.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); Log::Line( " Loading reference Y table '%s'.", path ); - FatalIf( !Debug::LoadRefTable( path, buffer.values, buffer.length ), "Failed to load reference Y table." ); + FatalIf( !Debug::LoadRefTable( path, buffer.values, buffer.length ), "Failed to load reference Y table." ); } //----------------------------------------------------------- @@ -323,7 +323,7 @@ inline void Debug::LoadRefLinePointTable( const TableId table, uint64*& buffer, sprintf( path, "%slp.t%d.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); Log::Line( " Loading reference line point table '%s'.", path ); - FatalIf( !Debug::LoadRefTable( path, buffer, outEntryCount ), "Failed to load reference line point table." ); + FatalIf( !Debug::LoadRefTable( path, buffer, outEntryCount ), "Failed to load reference line point table." ); } //----------------------------------------------------------- From b4897e7cdf168c8ceba270d5870f9e5894e9daed Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 18 Jul 2022 19:31:59 -0500 Subject: [PATCH 70/91] Actually fixed build error --- src/plotdisk/DiskBufferQueue.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index 8024bb0b..6dab7f87 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -364,9 +364,9 @@ class DiskBufferQueue _writeMetrics = {}; } #else - inline void DumpWriteMetrics() {} - inline void DumpReadMetrics() {} - inline void DumpDiskMetrics(){} + inline void DumpWriteMetrics( const TableId table ) {} + inline void DumpReadMetrics( const TableId table ) {} + inline void DumpDiskMetrics( const TableId table ){} inline void ClearWriteMetrics(){} inline void ClearReadMetrics(){} #endif From dad873ebecd5a0863d397f14febe7ce89cd3c4f2 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 18 Jul 2022 19:38:34 -0500 Subject: [PATCH 71/91] Other fixes for macos --- src/plotdisk/DiskPlotDebug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index 75aeb017..a692f415 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -311,7 +311,7 @@ inline void Debug::LoadYRefTable( const TableId table, Span& buffer ) sprintf( path, "%st%d.y.tmp", BB_DP_DBG_REF_DIR, (int)table+1 ); Log::Line( " Loading reference Y table '%s'.", path ); - FatalIf( !Debug::LoadRefTable( path, buffer.values, buffer.length ), "Failed to load reference Y table." ); + FatalIf( !Debug::LoadRefTable( path, buffer.values, (uint64&)buffer.length ), "Failed to load reference Y table." ); } //----------------------------------------------------------- From dbe01016bbe9a33f0b430f30038b99301218db30 Mon Sep 17 00:00:00 2001 From: Harold B Date: Mon, 18 Jul 2022 15:22:51 -0500 Subject: [PATCH 72/91] Fixed more macOS build issues --- .idea/vcs.xml | 20 ++++++++++++++++++++ src/plotdisk/k32/CTableWriterBounded.h | 4 ++-- src/plotdisk/k32/FxBounded.inl | 22 +++++++++++----------- src/util/Span.h | 4 +++- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7f..69e7b3f7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,25 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/plotdisk/k32/CTableWriterBounded.h b/src/plotdisk/k32/CTableWriterBounded.h index fd6300ba..e6204a35 100644 --- a/src/plotdisk/k32/CTableWriterBounded.h +++ b/src/plotdisk/k32/CTableWriterBounded.h @@ -69,8 +69,8 @@ class CTableWriterBounded Span _mapOut = allocator.CAllocSpan( _entriesPerBucket ); // Use same buffers as map tmp - uint32* f7Tmp = _mapOut.As().SliceSize( _entriesPerBucket ).Ptr(); - uint32* idxTmp = _mapOut.As().Slice( _entriesPerBucket ).Ptr(); + uint32* f7Tmp = _mapOut.template As().SliceSize( _entriesPerBucket ).Ptr(); + uint32* idxTmp = _mapOut.template As().Slice( _entriesPerBucket ).Ptr(); Span c1Buffer = allocator.CAllocSpan( c1TotalEntries ); Span c2Buffer = allocator.CAllocSpan( c2TotalEntries ); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index c6e25bf5..cc8c0808 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -268,7 +268,7 @@ public: const uint32 bufIdx = i & 1; // % 2 _y [i] = _yBuffers [bufIdx]; _index[i] = _indexBuffers[bufIdx]; - _meta [i] = _metaBuffers [bufIdx].As(); + _meta [i] = _metaBuffers [bufIdx].template As(); } @@ -363,7 +363,7 @@ private: const uint32 entryCount = yInput.Length(); Span sortKey = _sortKey.SliceSize( entryCount ); - SortY( self, entryCount, yInput.Ptr(), _yTmp.As().Ptr(), sortKey.Ptr(), _metaTmp[1].As().Ptr() ); + SortY( self, entryCount, yInput.Ptr(), _yTmp.template As().Ptr(), sortKey.Ptr(), _metaTmp[1].template As().Ptr() ); /// /// Write reverse map, given the previous table's y origin indices @@ -373,7 +373,7 @@ private: WaitForFence( self, _indexReadFence, bucket ); Span unsortedIndices = _index[bucket]; ASSERT( unsortedIndices.Length() == entryCount ); - Span indices = _metaTmp[1].As().SliceSize( entryCount ); + Span indices = _metaTmp[1].template As().SliceSize( entryCount ); #if (_DEBUG && DBG_VALIDATE_INDICES) if( self->BeginLockBlock() ) @@ -439,7 +439,7 @@ private: WaitForFence( self, _metaReadFence, bucket ); Span metaUnsorted = _meta[bucket].SliceSize( entryCount ); ASSERT( metaUnsorted.Length() == entryCount ); - Span metaIn = _metaTmp[0].As().SliceSize( entryCount ); + Span metaIn = _metaTmp[0].template As().SliceSize( entryCount ); if constexpr ( rTable == TableId::Table2 ) { @@ -478,8 +478,8 @@ private: /// Gen fx & write { - Span yOut = _yTmp.As().Slice( matchOffset, matches.Length() ); - Span metaOut = _metaTmp[1].As().Slice( matchOffset, matches.Length() ); //( (TMetaOut*)metaTmp.Ptr(), matches.Length() ); + Span yOut = _yTmp.template As().Slice( matchOffset, matches.Length() ); + Span metaOut = _metaTmp[1].template As().Slice( matchOffset, matches.Length() ); //( (TMetaOut*)metaTmp.Ptr(), matches.Length() ); TimePoint timer; if( self->IsControlThread() ) @@ -623,7 +623,7 @@ private: const uint32 threadCount = self->JobCount(); // use metaTmp as a buffer for group boundaries - Span groupBuffer = _metaTmp[1].As(); + Span groupBuffer = _metaTmp[1].template As(); const uint32 maxGroups = (uint32)( groupBuffer.Length() / threadCount ); Span groupIndices = groupBuffer.Slice( maxGroups * id, maxGroups ); @@ -712,8 +712,8 @@ private: const Span y ( info.savedY , prevBucketLength ); const Span meta ( (TMetaIn*)info.savedMeta, prevBucketLength + info.curBucketMetaLength ); - Span yOut = _yTmp .As() .SliceSize( matchCount ); - Span metaOut = _metaTmp[1].As().SliceSize( matchCount ); + Span yOut = _yTmp .template As() .SliceSize( matchCount ); + Span metaOut = _metaTmp[1].template As().SliceSize( matchCount ); GenFx( self, bucket, pairs, y, meta, yOut, metaOut ); @@ -1384,7 +1384,7 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co { Log::Line( " Validating %u", bucket ); - Span bucketReader = reader.As(); + Span bucketReader = reader.template As(); ioQueue.ReadBucketElementsT( fileId, bucketReader ); ioQueue.SignalFence( fence ); @@ -1396,7 +1396,7 @@ void DbgValidateY( const TableId table, const FileId fileId, DiskPlotContext& co #endif // Sort - RadixSort256::Sort( *context.threadPool, bucketReader.Ptr(), tmp.As().Ptr(), bucketReader.Length() ); + RadixSort256::Sort( *context.threadPool, bucketReader.Ptr(), tmp.template As().Ptr(), bucketReader.Length() ); // Expand const uint64 yMask = ((uint64)bucket) << yBits; diff --git a/src/util/Span.h b/src/util/Span.h index aa980d00..af3d3929 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -46,7 +46,6 @@ struct Span return this->values[index]; } - // size_t not the same as uint64 on clang. #ifdef __clang__ inline T& operator[]( uint64 index ) const @@ -88,6 +87,9 @@ struct Span return Slice( 0, size ); } +#ifdef __clang__ + inline Span Slice( const uint64 index ) const { return Slice( (size_t)index ); } +#endif inline Span Slice( const uint32 index ) const { return Slice( (size_t)index ); } inline Span Slice( const int64 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } inline Span Slice( const int32 index ) const { ASSERT( index >= 0); return Slice( (size_t)index ); } From 90254e1e19a667870af125d3cfbd747cbfc8a529 Mon Sep 17 00:00:00 2001 From: Harold B Date: Mon, 18 Jul 2022 15:30:28 -0500 Subject: [PATCH 73/91] Windows build fixes --- src/plotdisk/DiskBufferQueue.cpp | 2 +- src/plotdisk/k32/FpMatchBounded.inl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 915bd58c..4c5ccf3b 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -348,7 +348,7 @@ void DiskBufferQueue::WriteBucketElements( const FileId id, const void* buckets, cmd->buckets.writeSizes = writeCounts; cmd->buckets.sliceSizes = sliceCounts != nullptr ? sliceCounts : writeCounts; cmd->buckets.buffers = (byte*)buckets; - cmd->buckets.elementSize = elementSize; + cmd->buckets.elementSize = (uint32)elementSize; cmd->buckets.fileId = id; } diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 1796b9d8..6fcccc5d 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -235,7 +235,7 @@ public: const uint32* end = self->IsLastThread() ? yEntries.Ptr() + yEntries.Length() : _startPositions[id+1]; // Now scan for all groups - const uint32 maxGroups = groupBuffer.Length(); + const uint32 maxGroups = (uint32)groupBuffer.Length(); Span groupIndices = groupBuffer; uint32 groupCount = 0; while( ++entries < end ) @@ -288,7 +288,7 @@ public: const uint64 lGroupMask = ((uint64)lBucket) << yBits; const uint64 rGroupMask = ((uint64)rBucket) << yBits; - const uint32 groupCount = groupBoundaries.Length() - 1; // Ignore the extra ghost group + const uint32 groupCount = (uint32)(groupBoundaries.Length() - 1); // Ignore the extra ghost group uint32 pairCount = 0; From edac8ff13f8239174bfb447e0763412f6864d9f9 Mon Sep 17 00:00:00 2001 From: Harold B Date: Mon, 18 Jul 2022 15:41:58 -0500 Subject: [PATCH 74/91] More fixes --- src/plotdisk/DiskBufferQueue.cpp | 2 +- src/plotdisk/k32/CTableWriterBounded.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 4c5ccf3b..60d10a3b 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -367,7 +367,7 @@ void DiskBufferQueue::ReadBucketElements( const FileId id, Span& buffer, c { Command* cmd = GetCommandObject( Command::ReadBucket ); cmd->readBucket.buffer = &buffer; - cmd->readBucket.elementSize = elementSize; + cmd->readBucket.elementSize = (uint32)elementSize; cmd->readBucket.fileId = id; } diff --git a/src/plotdisk/k32/CTableWriterBounded.h b/src/plotdisk/k32/CTableWriterBounded.h index e6204a35..67e1f2ef 100644 --- a/src/plotdisk/k32/CTableWriterBounded.h +++ b/src/plotdisk/k32/CTableWriterBounded.h @@ -107,7 +107,7 @@ class CTableWriterBounded ASSERT( f7.Length() == indices.Length() ); ASSERT( f7.Length() == context.bucketCounts[(int)TableId::Table7][bucket] ); - const uint32 bucketLength = f7.Length(); + const uint32 bucketLength = (uint32)f7.Length(); // Sort on f7 RadixSort256::SortWithKey( *context.threadPool, _threadCount, f7.Ptr(), f7Tmp, indices.Ptr(), idxTmp, bucketLength ); From a1f08a2fc29b71ed46ed839aac291fdb412c3282 Mon Sep 17 00:00:00 2001 From: Harold B Date: Mon, 18 Jul 2022 15:47:33 -0500 Subject: [PATCH 75/91] More windows build fixes --- src/plotdisk/k32/F1Bounded.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index 95346664..c34d98cc 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -25,7 +25,7 @@ class K32BoundedF1 static constexpr uint32 _entriesPerBucket = (uint32)( _kEntryCount / _numBuckets ); static constexpr uint32 _entriesPerBlock = kF1BlockSize / sizeof( uint32 ); static constexpr uint32 _blocksPerBucket = _entriesPerBucket * sizeof( uint32 ) / kF1BlockSize; - static constexpr uint32 _maxEntriesPerSlice = ((uint32)(_entriesPerBucket / _numBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); + static constexpr uint32 _maxEntriesPerSlice = (uint32)((_entriesPerBucket / _numBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); public: //----------------------------------------------------------- @@ -274,7 +274,7 @@ void DbgValidateF1( DiskPlotContext& context ) const uint32 numBuckets = context.numBuckets; for( uint32 bucket = 0; bucket < numBuckets; bucket++ ) { - Span yBucket = tmpBuffer.As(); + Span yBucket = tmpBuffer.template As(); Span xBucket = tmpBuffer2; ioQueue.ReadBucketElementsT( FileId::FX0 , yBucket ); From 5b4786576ef34f56a9186b17f2b6f9e36ff17bb8 Mon Sep 17 00:00:00 2001 From: Harold B Date: Mon, 18 Jul 2022 15:52:40 -0500 Subject: [PATCH 76/91] More windows build fixes --- src/plotdisk/k32/F1Bounded.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index c34d98cc..e23a3eca 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -39,7 +39,7 @@ public: const uint32 threadCount = context.f1ThreadCount; // We need to pad our slices to block size - const uint32 blockSize = _ioQueue.BlockSize( FileId::FX0 ); + const uint32 blockSize = (uint32)_ioQueue.BlockSize( FileId::FX0 ); const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( _maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries const uint32 entriesPerBucketAligned = entriesPerSliceAligned * _numBuckets; // in subsequent slices ASSERT( entriesPerBucketAligned >= _entriesPerBucket ); From e4c07eb22a44cb8b6326fe1a40f07df39bf1e401 Mon Sep 17 00:00:00 2001 From: Harold B Date: Mon, 18 Jul 2022 15:58:18 -0500 Subject: [PATCH 77/91] More windows build fixes --- src/plotdisk/k32/FxBounded.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index cc8c0808..bf8ce897 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -360,7 +360,7 @@ private: WaitForFence( self, _yReadFence, bucket ); Span yInput = _y[bucket]; - const uint32 entryCount = yInput.Length(); + const uint32 entryCount = (uint32)yInput.Length(); Span sortKey = _sortKey.SliceSize( entryCount ); SortY( self, entryCount, yInput.Ptr(), _yTmp.template As().Ptr(), sortKey.Ptr(), _metaTmp[1].template As().Ptr() ); From a94374235b812d102f530638ca5e44aee705d866 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 18 Jul 2022 16:24:47 -0500 Subject: [PATCH 78/91] More windows build fixes --- src/plotdisk/k32/FxBounded.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index bf8ce897..ec537a87 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -1031,7 +1031,7 @@ private: const size_t bufferSize = CDiv( ySize + metaSizeLR, 8 ); // const uint32 id = self->JobId(); - const uint32 matchCount = pairs.Length(); + const uint32 matchCount = (uint32)pairs.Length(); // Hashing uint64 input [5]; // y + L + R From 78661fd1046ac7b906781ff671be4fdc2618b295 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Mon, 18 Jul 2022 23:28:58 -0500 Subject: [PATCH 79/91] Fix crash w/ entries > 2^32 --- src/plotdisk/k32/FxBounded.inl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index ec537a87..478939c7 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -419,16 +419,18 @@ private: const uint64 tableEntryCount = _tableEntryCount; if( bucket == _numBuckets-1 && (tableEntryCount + totalMatches) > _maxTableEntries ) { + const uint32 overflowEntries = (uint32)( (tableEntryCount + totalMatches) - _maxTableEntries ); + // Prevent calculating fx for overflow matches if( self->IsLastThread() ) { - const uint32 overflowEntries = (uint32)( (tableEntryCount + totalMatches) - _maxTableEntries ); ASSERT( overflowEntries < matches.Length() ); matches = matches.SliceSize( matches.Length() - overflowEntries ); } - totalMatches = _maxTableEntries; + totalMatches -= overflowEntries; + ASSERT( tableEntryCount + totalMatches == _maxTableEntries ); } WritePairs( self, bucket, totalMatches, matches, matchOffset ); From dbabf290e6894f7d899496f2f3bee768d80df068 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 9 Aug 2022 17:55:50 -0500 Subject: [PATCH 80/91] Cache reduction to ~99GiB via the -a/--alternate switch (#190) * Added cache reduction to ~99GiB via the -a/--alternate switch * Fixing regression on getting disk block size on windows. * Fixed f1 time not accumulating last I/O wait to the correct accumulator. * Fixes other minor issues --- .idea/vcs.xml | 15 +++ .vscode/launch.json | 5 +- src/io/FileStream.h | 5 + src/main.cpp | 17 +-- src/platform/unix/FileStream_Unix.cpp | 25 ++++ src/platform/win32/FileStream_Win32.cpp | 103 ++++++++++++++++ src/plotdisk/BlockWriter.h | 10 +- src/plotdisk/DiskBufferQueue.cpp | 156 +++++++++++++++++++----- src/plotdisk/DiskBufferQueue.h | 56 +++++---- src/plotdisk/DiskPlotConfig.h | 2 +- src/plotdisk/DiskPlotPhase3.cpp | 1 + src/plotdisk/DiskPlotter.cpp | 28 ++--- src/plotdisk/k32/CTableWriterBounded.h | 4 +- src/plotdisk/k32/DiskPlotBounded.cpp | 81 ++++++++---- src/plotdisk/k32/F1Bounded.inl | 11 +- src/plotdisk/k32/FpMatchBounded.inl | 2 +- src/plotdisk/k32/FxBounded.inl | 66 +++++++--- src/util/Span.h | 2 +- 18 files changed, 446 insertions(+), 143 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 69e7b3f7..e88cc20c 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -12,15 +12,30 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 622b4c65..e35fc117 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -76,14 +76,15 @@ "--show-memo", "diskplot", + "-a", "-t1", "~/plot/tmp", "--f1-threads", "24", // "--fp-threads", "62", "--c-threads", "28", "--p2-threads", "24", - "--cache", "196G", - // "--cache", "96G", + // "--cache", "196G", + "--cache", "99G", // "--cache", "200G", // "--cache", "64G", // "-s", diff --git a/src/io/FileStream.h b/src/io/FileStream.h index eaaf9ab1..3521faa1 100644 --- a/src/io/FileStream.h +++ b/src/io/FileStream.h @@ -81,6 +81,11 @@ class FileStream : public IStream inline intptr_t Id() { return (intptr_t)_fd; } + static size_t GetBlockSizeForPath( const char* pathU8 ); + + // Change name or location of file + static bool Move( const char* oldPathU8, const char* newPathU8, int32* outError = nullptr ); + private: inline bool HasValidFD() const { diff --git a/src/main.cpp b/src/main.cpp index 16acf242..944ae89f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -273,13 +273,13 @@ void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ) { if( cli.ArgMatch( "diskplot" ) ) DiskPlotter::PrintUsage(); - if( cli.ArgMatch( "iotest" ) ) + else if( cli.ArgMatch( "iotest" ) ) IOTestPrintUsage(); - if( cli.ArgMatch( "memtest" ) ) + else if( cli.ArgMatch( "memtest" ) ) MemTestPrintUsage(); - if( cli.ArgMatch( "validate" ) ) + else if( cli.ArgMatch( "validate" ) ) PlotValidatorPrintUsage(); - if( cli.ArgMatch( "plotcmp" ) ) + else if( cli.ArgMatch( "plotcmp" ) ) PlotCompareMainPrintUsage(); else Fatal( "Unknown command '%s'.", cli.Arg() ); @@ -456,12 +456,13 @@ R"( [EXAMPLES] bladebit --help -bladebiy help diskplot +bladebit help diskplot -bladebit -t 24 -f ... -c ... diskplot --f1 256MB --fx 256MB -t /my/temporary/plot/dir - --f1-threads 3 --c-threads 8 --p2-threads 12 --p3-threads 8 /my/output/dir +# Simple config: +bladebit -t 24 -f -c diskplot --t1 /my/temporary/plot/dir /my/output/dir -bladebit -t 8 -f ... -c ... diskplot --f1 64MB --fx 128MB -t /my/temporary/plot/dir /my/output/dir +# With fine-grained control over threads per phase/section (see bladebit -h diskplot): +bladebit -t 30 -f -c diskplot --f1-threads 16 --c-threads 16 --p2-threads 8 --t1 /my/temporary/plot/dir /my/output/dir )"; //----------------------------------------------------------- diff --git a/src/platform/unix/FileStream_Unix.cpp b/src/platform/unix/FileStream_Unix.cpp index 992bfd71..32dc604b 100644 --- a/src/platform/unix/FileStream_Unix.cpp +++ b/src/platform/unix/FileStream_Unix.cpp @@ -311,3 +311,28 @@ bool FileStream::Exists( const char* path ) return false; } + +//----------------------------------------------------------- +size_t FileStream::GetBlockSizeForPath( const char* pathU8 ) +{ + FileStream file; + if( !file.Open( pathU8, FileMode::Open, FileAccess::Read ) ) + { + Log::Error( "GetBlockSizeForPath() failed with error %d.", (int32)file.GetError() ); + return 0; + } + + return file.BlockSize(); +} + +//----------------------------------------------------------- +bool FileStream::Move( const char* oldPathU8, const char* newPathU8, int32* outError ) +{ + const bool moved = rename( oldPathU8, newPathU8 ) == 0; + + if( !moved && outError ) + *outError = (int32)errno; + + return moved; +} + diff --git a/src/platform/win32/FileStream_Win32.cpp b/src/platform/win32/FileStream_Win32.cpp index 93a60e77..90865fed 100644 --- a/src/platform/win32/FileStream_Win32.cpp +++ b/src/platform/win32/FileStream_Win32.cpp @@ -2,6 +2,7 @@ #include "util/Util.h" #include "util/Log.h" #include +#include //#include //#include //#pragma comment( lib, "Shlwapi.lib" ) @@ -375,6 +376,108 @@ wchar_t* Utf8ToUtf16( const char* utf8Str, wchar_t* stackBuffer16, const size_t return str16; } +//----------------------------------------------------------- +size_t FileStream::GetBlockSizeForPath( const char* pathU8 ) +{ + wchar_t path16Stack[BUF16_STACK_LEN]; + + wchar_t* path16 = Utf8ToUtf16( pathU8, path16Stack, BUF16_STACK_LEN ); + if( !path16 ) + return 0; + + + const DWORD dwShareMode = FILE_SHARE_READ; + const DWORD dwCreationDisposition = OPEN_EXISTING; + + DWORD dwFlags = FILE_FLAG_BACKUP_SEMANTICS ; + DWORD dwAccess = GENERIC_READ; + + HANDLE fd = CreateFile( path16, dwAccess, dwShareMode, NULL, + dwCreationDisposition, dwFlags, NULL ); + + size_t blockSize = 0; + if( fd != INVALID_HANDLE_VALUE ) + { + if( !GetFileClusterSize( fd, blockSize ) ) + blockSize = 0; + } + + if( path16 != path16Stack ) + free( path16 ); + + return blockSize; +// ASSERT( pathU8 ); +// +// const int path16Len = ::MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, pathU8, -1, nullptr, 0 ); +// +// if( !path16Len ) +// { +// Log::Error( "[Warning] MultiByteToWideChar() failed with error %d", (int)::GetLastError() ); +// ASSERT( 0 ); +// return 0; +// } +// +// wchar_t* pathU16 = bbcalloc( path16Len ); +// const int written = ::MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, pathU8, -1, pathU16, path16Len ); +// ASSERT( written == path16Len); +// +// if( !written ) +// { +// free( pathU16 ); +// Log::Error( "[Warning] MultiByteToWideChar() failed with error %d", (int)::GetLastError() ); +// ASSERT( 0 ); +// return 0; +// } +// +// DWORD sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters; +// +// const BOOL r = GetDiskFreeSpaceW( +// pathU16, +// §orsPerCluster, +// &bytesPerSector, +// &numberOfFreeClusters, +// &totalNumberOfClusters ); +// ASSERT( r ); +// free( pathU16 ); +// +// if( !r ) +// return 0; +// +// return bytesPerSector * sectorsPerCluster; +} + +//----------------------------------------------------------- +bool FileStream::Move( const char* oldPathU8, const char* newPathU8, int32* outError ) +{ + wchar_t oldPathU16Stack[BUF16_STACK_LEN]; + wchar_t newPathU16Stack[BUF16_STACK_LEN]; + + wchar_t* oldPath16 = Utf8ToUtf16( oldPathU8, oldPathU16Stack, BUF16_STACK_LEN ); + if( !oldPath16 ) + return false; + + wchar_t* newPath16 = Utf8ToUtf16( newPathU8, newPathU16Stack, BUF16_STACK_LEN ); + if( !newPath16 ) + { + if( oldPath16 != oldPathU16Stack ) + free( oldPath16 ); + return false; + } + + const BOOL moved = ::MoveFileW( oldPath16, newPath16 ); + + if( !moved && outError ) + *outError = (int32)::GetLastError(); + + if( oldPath16 != oldPathU16Stack ) + free( oldPath16 ); + + if( newPath16 != newPathU16Stack ) + free( newPath16 ); + + return (bool)moved; +} + //----------------------------------------------------------- //bool GetFileClusterSize( wchar_t* filePath, size_t& outClusterSize ) bool GetFileClusterSize( HANDLE hFile, size_t& outClusterSize ) diff --git a/src/plotdisk/BlockWriter.h b/src/plotdisk/BlockWriter.h index c73a7c13..d6c99327 100644 --- a/src/plotdisk/BlockWriter.h +++ b/src/plotdisk/BlockWriter.h @@ -11,8 +11,9 @@ class BlockWriter //----------------------------------------------------------- inline BlockWriter( IAllocator& allocator, const FileId fileId, Fence& fence, const size_t blockSize, const size_t elementCount ) - : _fileId( fileId ) - , _fence( &fence ) + : _fileId ( fileId ) + , _fence ( &fence ) + , _blockSize( (uint32)blockSize ) { static_assert( sizeof( T ) == 1 || ( sizeof( T ) & 1) == 0 ); @@ -31,6 +32,8 @@ class BlockWriter //----------------------------------------------------------- inline T* GetNextBuffer( Duration& writeWaitTime ) { + ASSERT( _buffers[0] ); + if( _bufferIdx > 1 ) _fence->Wait( _bufferIdx - 2, writeWaitTime ); @@ -42,7 +45,7 @@ class BlockWriter { ASSERT( elementCount ); - const size_t blockSize = queue.BlockSize( _fileId ); + const size_t blockSize = _blockSize; const size_t elementsPerBlock = blockSize / sizeof( T ); T* buf = _buffers[_bufferIdx & 1]; @@ -84,6 +87,7 @@ class BlockWriter private: FileId _fileId = FileId::None; int32 _bufferIdx = 0; + uint32 _blockSize = 1; T* _buffers[2] = { nullptr }; T* _remainder = nullptr; size_t _remainderCount = 0; // Number of elements saved in our remainder buffer diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 60d10a3b..413cb94b 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -75,7 +75,6 @@ DiskBufferQueue::~DiskBufferQueue() _deleterThread.WaitForExit(); // #TODO: Wait for command thread - // #TODO: Delete our file sets free( _filePathBuffer ); @@ -127,11 +126,21 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC fileSet.blockBuffer = nullptr; fileSet.options = options; - if( IsFlagSet( options, FileSetOptions::Interleaved ) ) + if( IsFlagSet( options, FileSetOptions::Interleaved ) || IsFlagSet( options, FileSetOptions::Alternating ) ) { - fileSet.sliceSizes.SetTo( new Span[bucketCount], bucketCount ); + fileSet.readSliceSizes.SetTo( new Span[bucketCount], bucketCount ); + fileSet.writeSliceSizes.SetTo( new Span[bucketCount], bucketCount ); for( uint32 i = 0; i < bucketCount; i++ ) - fileSet.sliceSizes[i].SetTo( new size_t[bucketCount]{}, bucketCount ); + { + fileSet.readSliceSizes[i].SetTo( new size_t[bucketCount]{}, bucketCount ); + fileSet.writeSliceSizes[i].SetTo( new size_t[bucketCount]{}, bucketCount ); + } + } + + if( IsFlagSet( options, FileSetOptions::Alternating ) ) + { + fileSet.maxSliceSize = optsData->maxSliceSize; + ASSERT( fileSet.maxSliceSize ); } const bool isCachable = IsFlagSet( options, FileSetOptions::Cachable ) && optsData->cacheSize > 0; @@ -304,17 +313,22 @@ void DiskBufferQueue::FinishPlot( Fence& fence ) const uint32 RETRY_COUNT = 10; const long MS_WAIT_TIME = 1000; + Log::Line( "Renaming plot to '%s'", _plotFullName.c_str() ); + + int32 error = 0; + for( uint32 i = 0; i < RETRY_COUNT; i++ ) { - int r = rename( plotPath, _plotFullName.c_str() ); - if( !r ) + const bool success = FileStream::Move( plotPath, _plotFullName.c_str(), &error ); + + if( success ) break; - Log::Line( "Error: Could not rename plot file with error: %d.", (int32)errno ); + Log::Line( "Error: Could not rename plot file with error: %d.", error ); if( i+1 == RETRY_COUNT) { - Log::Line( "Error:: Failed to to rename plot file after %u retries. Please rename manually." ); + Log::Line( "Error:: Failed to to rename plot file after %u retries. Please rename manually.", RETRY_COUNT ); break; } @@ -337,7 +351,7 @@ void DiskBufferQueue::WriteBuckets( FileId id, const void* buckets, const uint* } //----------------------------------------------------------- -void DiskBufferQueue::WriteBucketElements( const FileId id, const void* buckets, const size_t elementSize, const uint* writeCounts, const uint32* sliceCounts ) +void DiskBufferQueue::WriteBucketElements( const FileId id, const bool interleaved, const void* buckets, const size_t elementSize, const uint* writeCounts, const uint32* sliceCounts ) { ASSERT( buckets ); ASSERT( elementSize ); @@ -350,6 +364,7 @@ void DiskBufferQueue::WriteBucketElements( const FileId id, const void* buckets, cmd->buckets.buffers = (byte*)buckets; cmd->buckets.elementSize = (uint32)elementSize; cmd->buckets.fileId = id; + cmd->buckets.interleaved = interleaved; } //----------------------------------------------------------- @@ -363,12 +378,13 @@ void DiskBufferQueue::WriteFile( FileId id, uint bucket, const void* buffer, siz } //----------------------------------------------------------- -void DiskBufferQueue::ReadBucketElements( const FileId id, Span& buffer, const size_t elementSize ) +void DiskBufferQueue::ReadBucketElements( const FileId id, const bool interleaved, Span& buffer, const size_t elementSize ) { Command* cmd = GetCommandObject( Command::ReadBucket ); cmd->readBucket.buffer = &buffer; cmd->readBucket.elementSize = (uint32)elementSize; cmd->readBucket.fileId = id; + cmd->readBucket.interleaved = interleaved; } //----------------------------------------------------------- @@ -722,12 +738,10 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS // Single-threaded for now... We don't have file handles for all the threads yet! const size_t blockSize = fileSet.files[0]->BlockSize(); - // #if _DEBUG - // #endif const byte* buffer = buffers; - if( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ) + if( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) || IsFlagSet( fileSet.options, FileSetOptions::Alternating ) ) { const uint32* sliceSizes = cmd.buckets.sliceSizes; @@ -740,19 +754,59 @@ void DiskBufferQueue::CmdWriteBuckets( const Command& cmd, const size_t elementS ASSERT( sliceWriteSize / blockSize * blockSize == sliceWriteSize ); // Save slice sizes for reading-back the bucket - fileSet.sliceSizes[fileSet.bucket][i] = sliceSizes[i] * elementSize; // #TODO: Should we not do element size here? + fileSet.writeSliceSizes[fileSet.writeBucket][i] = sliceSizes[i] * elementSize; // #TODO: Should we not apply element size here? writeSize += sliceWriteSize; } // #TODO: Do we have to round-up the size to block boundary? ASSERT( writeSize / blockSize * blockSize == writeSize ); + ASSERT( fileSet.writeBucket < fileSet.files.Length() ); + + if( IsFlagSet( fileSet.options, FileSetOptions::Alternating ) ) + { + const bool interleaved = cmd.buckets.interleaved; - ASSERT( fileSet.bucket < fileSet.files.Length() ); - WriteToFile( *fileSet.files[fileSet.bucket], writeSize, buffer, (byte*)fileSet.blockBuffer, fileSet.name, fileSet.bucket ); + // When in alternating mode we have to issue bucketCount writes per bucket as we need t o ensure + // they are all offset to the bucket slice boundary. + // #NOTE: We can avoid this on interleaved writes if we add that said offset to the prefix um offset. + const uint64 maxSliceSize = fileSet.maxSliceSize; - fileSet.bucket++; - fileSet.bucket %= fileSet.files.Length(); + for( uint slice = 0; slice < bucketCount; slice++ ) + { + ASSERT( sizes[slice] <= maxSliceSize / elementSize ); + + const size_t sliceWriteSize = sizes[slice] * elementSize; + const uint32 fileBucketIdx = interleaved ? fileSet.writeBucket : slice; + IStream& file = *fileSet.files[fileBucketIdx]; + + // Seek to the start of the (fixed-size) slice boundary + { + const uint32 sliceSeekIdx = interleaved ? slice : fileSet.writeBucket; + const int64 sliceOffset = (int64)( sliceSeekIdx * maxSliceSize ); + + FatalIf( !file.Seek( sliceOffset, SeekOrigin::Begin ), + "Failed to seek file %s.%u.tmp to slice boundary.", fileSet.name, fileBucketIdx ); + } + + WriteToFile( file, sliceWriteSize, buffer, (byte*)fileSet.blockBuffer, fileSet.name, fileBucketIdx ); + + buffer += sliceWriteSize; + } + } + else + { + WriteToFile( *fileSet.files[fileSet.writeBucket], writeSize, buffer, (byte*)fileSet.blockBuffer, fileSet.name, fileSet.writeBucket ); + } + + if( ++fileSet.writeBucket >= bucketCount ) + { + ASSERT( fileSet.writeBucket <= fileSet.files.Length() ); + + // When the last bucket was written, reset the write bucket and swap file slices + fileSet.writeBucket = 0; + std::swap( fileSet.writeSliceSizes, fileSet.readSliceSizes ); + } } else { @@ -783,14 +837,37 @@ void DiskBufferQueue::CmdReadBucket( const Command& cmd ) const FileId fileId = cmd.readBucket.fileId; const size_t elementSize = cmd.readBucket.elementSize; FileSet& fileSet = _files[(int)fileId]; + const uint32 bucketCount = (uint32)fileSet.files.Length(); + + const bool alternating = IsFlagSet( fileSet.options, FileSetOptions::Alternating ); + const bool alternatingNonInterleaved = alternating && !cmd.readBucket.interleaved; + + // #NOTE: Not implemented in the single-read method for code simplicity. + // if( IsFlagSet( fileSet.options, FileSetOptions::Alternating ) && !cmd.readBucket.interleaved ) + // { + // // Read a single file instead + // Command readCmd; + // readCmd.file.buffer = cmd.readBucket.buffer->Ptr(); ASSERT( readCmd.file.buffer ); + // readCmd.file.fileId = fileId; + // readCmd.file.bucket = fileSet.readBucket; + // readCmd.file.size = fileSet.sliceSizes[fileSet.readBucket][0] * elementSize; ASSERT( readCmd.file.size ); + + // CmdReadFile( cmd ); + + // // Update user buffer length + // auto userBuffer = const_cast*>( cmd.readBucket.buffer ); + // userBuffer->length = readCmd.file.size; //readCmd.file.size / elementSize; + + // fileSet.readBucket = (fileSet.readBucket + 1) % fileSet.files.Length(); + // return; + // } - ASSERT( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) ); // #TODO: Read bucket is just a single file read without this flag - ASSERT( fileSet.sliceSizes.Ptr() ); - // ASSERT( fileSet.bucket == 0 ); // Should be in bucket 0 at this point // #NOTE: Perhaps have the user specify the bucket to read instead? + ASSERT( IsFlagSet( fileSet.options, FileSetOptions::Interleaved ) || IsFlagSet( fileSet.options, FileSetOptions::Alternating ) ); // #TODO: Read bucket is just a single file read without this flag + ASSERT( fileSet.readSliceSizes.Ptr() ); + // ASSERT( fileSet.readBucket == 0 ); // Should be in bucket 0 at this point // #NOTE: Perhaps have the user specify the bucket to read instead? const bool directIO = IsFlagSet( fileSet.options, FileSetOptions::DirectIO ); - const uint32 bucketCount = (uint32)fileSet.files.Length(); - const auto sliceSizes = fileSet.sliceSizes; + const auto sliceSizes = fileSet.readSliceSizes; const size_t blockSize = fileSet.files[0]->BlockSize(); auto readBuffer = Span( cmd.readBucket.buffer->Ptr(), cmd.readBucket.buffer->Length() * elementSize ); @@ -798,13 +875,28 @@ void DiskBufferQueue::CmdReadBucket( const Command& cmd ) Span tempBlock; + const uint64 maxSliceSize = fileSet.maxSliceSize; + for( uint32 slice = 0; slice < bucketCount; slice++ ) { - const size_t sliceSize = sliceSizes[slice][fileSet.bucket]; - const size_t readSize = sliceSize + tempBlock.Length(); - const size_t alignedSize = CDivT( readSize, blockSize ) * blockSize; // Sizes are written aligned, and must also be read aligned + const size_t sliceSize = sliceSizes[slice][fileSet.readBucket]; + const size_t readSize = sliceSize + tempBlock.Length(); + const size_t alignedSize = CDivT( readSize, blockSize ) * blockSize; // Sizes are written aligned, and must also be read aligned + + const uint32 fileBucketIdx = alternatingNonInterleaved ? fileSet.readBucket : slice; + IStream& stream = *fileSet.files[fileBucketIdx]; - ReadFromFile( *fileSet.files[slice], alignedSize, readBuffer.Ptr(), nullptr, blockSize, directIO, fileSet.name, fileSet.bucket ); + // When alternating, we need to seek to the start of the slice boundary + if( alternating ) + { + const uint32 sliceOffsetIdx = alternatingNonInterleaved ? slice : fileSet.readBucket; + const int64 sliceOffset = (int64)( sliceOffsetIdx * maxSliceSize ); + + FatalIf( !stream.Seek( sliceOffset, SeekOrigin::Begin ), + "Failed to seek while reading alternating bucket %s.%u.tmp.", fileSet.name, fileBucketIdx ); + } + + ReadFromFile( stream, alignedSize, readBuffer.Ptr(), nullptr, blockSize, directIO, fileSet.name, fileBucketIdx ); // Replace the temp block we just overwrote, if we have one if( tempBlock.Length() ) @@ -832,9 +924,9 @@ void DiskBufferQueue::CmdReadBucket( const Command& cmd ) size_t elementCount = 0; for( uint32 slice = 0; slice < bucketCount; slice++ ) - elementCount += sliceSizes[slice][fileSet.bucket]; + elementCount += sliceSizes[slice][fileSet.readBucket]; - fileSet.bucket = (fileSet.bucket + 1) % fileSet.files.Length(); + fileSet.readBucket = (fileSet.readBucket + 1) % fileSet.files.Length(); // Revert buffer length from bytes to element size auto userBuffer = const_cast*>( cmd.readBucket.buffer ); @@ -1100,7 +1192,6 @@ inline const char* DiskBufferQueue::DbgGetCommandName( Command::CommandType type } #if _DEBUG - //----------------------------------------------------------- void DiskBufferQueue::CmdDbgWriteSliceSizes( const Command& cmd ) { @@ -1119,7 +1210,7 @@ void DiskBufferQueue::CmdDbgWriteSliceSizes( const Command& cmd ) for( uint32 i = 0; i < numBuckets; i++ ) { - auto slices = fileSet.sliceSizes[i]; + auto slices = fileSet.writeSliceSizes[i]; const size_t sizeWrite = sizeof( size_t ) * numBuckets; FatalIf( file.Write( slices.Ptr(), sizeWrite ) != sizeWrite, @@ -1145,7 +1236,7 @@ void DiskBufferQueue::CmdDbgReadSliceSizes( const Command& cmd ) for( uint32 i = 0; i < numBuckets; i++ ) { - auto slices = fileSet.sliceSizes[i]; + auto slices = fileSet.readSliceSizes[i]; const size_t sizeRead = sizeof( size_t ) * numBuckets; FatalIf( file.Read( slices.Ptr(), sizeRead ) != sizeRead, @@ -1153,6 +1244,7 @@ void DiskBufferQueue::CmdDbgReadSliceSizes( const Command& cmd ) } } + #endif /// diff --git a/src/plotdisk/DiskBufferQueue.h b/src/plotdisk/DiskBufferQueue.h index 6dab7f87..68cb3ce8 100644 --- a/src/plotdisk/DiskBufferQueue.h +++ b/src/plotdisk/DiskBufferQueue.h @@ -18,38 +18,40 @@ enum FileSetOptions Cachable = 1 << 1, // Use a in-memory cache for the file UseTemp2 = 1 << 2, // Open the file set the high-frequency temp directory + Interleaved = 1 << 3, // Write in interleaved mode. That is all slices written to a single bucket. - // BatchedSlices = 1 << 3, // Write bucket slices in a batch, instead of a slice per each bucket. - Interleaved = 1 << 3, // Write in interleaved mode. That is all slices written to a single bucket. + Alternating = 1 << 4, // Alternate between bucket writing/reading modes. This allows for lower cache size. - BlockAlign = 1 << 4, // Only write in block-aligned segments. Keeping a block-sized buffer for left overs. + BlockAlign = 1 << 5, // Only write in block-aligned segments. Keeping a block-sized buffer for left overs. // The last write flushes the whole block. // This can be very memory-costly on file systems with large block sizes // as interleaved buckets will need many block buffers. // This must be used with DirectIO. - }; ImplementFlagOps( FileSetOptions ); struct FileSetInitData { // Cachable - void* cache = nullptr; // Cache buffer - size_t cacheSize = 0; // Cache size in bytes + void* cache = nullptr; // Cache buffer + size_t cacheSize = 0; // Cache size in bytes - // Interleaved - // size_t sliceSize = 0; // Maximum size of a bucket slice + // For alternating mode + uint64 maxSliceSize = 0; // Maximum size (in bytes) of a bucket slice }; struct FileSet { - const char* name = nullptr; + const char* name = nullptr; Span files; - void* blockBuffer = nullptr; // For FileSetOptions::BlockAlign - // size_t sliceCapacity = 0; // (in bytes) For FileSetOptions::Interleaved - Span> sliceSizes; - uint32 bucket = 0; // Current bucket. Valid when writing in interleaved mode - FileSetOptions options = FileSetOptions::None; + Span readFiles; // When FileSetOptions::Alternating is enabled, we have to keep separate read streams + void* blockBuffer = nullptr; // For FileSetOptions::BlockAlign + uint64 maxSliceSize = 0; // Maximum size (in bytes) of a bucket slice, for FileSetOptions::Alternating + Span> readSliceSizes ; + Span> writeSliceSizes; + uint32 readBucket = 0; // Current read/write bucket that generated slices. Valid when writing in interleaved mode and alternating mode + uint32 writeBucket = 0; + FileSetOptions options = FileSetOptions::None; }; @@ -92,17 +94,19 @@ class DiskBufferQueue struct { - const uint* writeSizes; // Size that will actually be written to disk (usually padded and block-aligned) - const uint* sliceSizes; // Actual number of slices that we have per-bucket. This used to store it for reading-back buckets. + const uint* writeSizes; // Size that will actually be written to disk (usually padded and block-aligned) + const uint* sliceSizes; // Actual number of slices that we have per-bucket. This used to store it for reading-back buckets. const byte* buffers; FileId fileId; - uint32 elementSize; // Size of each element in the buffer + uint32 elementSize; // Size of each element in the buffer + bool interleaved; // Write interleaved or not? } buckets; struct { Span* buffer; FileId fileId; uint32 elementSize; + bool interleaved; // Read in interleaved mode } readBucket; struct @@ -185,17 +189,17 @@ class DiskBufferQueue void WriteBuckets( FileId id, const void* buckets, const uint* writeSizes, const uint32* sliceSizes = nullptr ); - void WriteBucketElements( const FileId id, const void* buckets, const size_t elementSize, const uint32* writeCounts, const uint32* sliceCounts = nullptr ); + void WriteBucketElements( const FileId id, const bool interleaved, const void* buckets, const size_t elementSize, const uint32* writeCounts, const uint32* sliceCounts = nullptr ); template - void WriteBucketElementsT( const FileId id, const T* buckets, const uint32* writeCounts, const uint32* sliceCounts = nullptr ); + void WriteBucketElementsT( const FileId id, const bool interleaved, const T* buckets, const uint32* writeCounts, const uint32* sliceCounts = nullptr ); void WriteFile( FileId id, uint bucket, const void* buffer, size_t size ); - void ReadBucketElements( const FileId id, Span& buffer, const size_t elementSize ); + void ReadBucketElements( const FileId id, const bool interleaved, Span& buffer, const size_t elementSize ); template - void ReadBucketElementsT( const FileId id, Span& buffer ); + void ReadBucketElementsT( const FileId id, const bool interleaved, Span& buffer ); void ReadFile( FileId id, uint bucket, void* dstBuffer, size_t readSize ); @@ -238,7 +242,7 @@ class DiskBufferQueue } #if _DEBUG || BB_TEST_MODE - const Span> SliceSizes( const FileId fileId ) const { return _files[(int)fileId].sliceSizes; } + // const Span> SliceSizes( const FileId fileId ) const { return _files[(int)fileId].sliceSizes; } #endif #if _DEBUG @@ -458,14 +462,14 @@ class DiskBufferQueue //----------------------------------------------------------- template -inline void DiskBufferQueue::WriteBucketElementsT( const FileId id, const T* buckets, const uint32* writeCounts, const uint32* sliceCounts ) +inline void DiskBufferQueue::WriteBucketElementsT( const FileId id, const bool interleaved, const T* buckets, const uint32* writeCounts, const uint32* sliceCounts ) { - WriteBucketElements( id, (byte*)buckets, sizeof( T ), writeCounts, sliceCounts ); + WriteBucketElements( id, interleaved, (byte*)buckets, sizeof( T ), writeCounts, sliceCounts ); } //----------------------------------------------------------- template -inline void DiskBufferQueue::ReadBucketElementsT( const FileId id, Span& buffer ) +inline void DiskBufferQueue::ReadBucketElementsT( const FileId id, const bool interleaved, Span& buffer ) { - ReadBucketElements( id, reinterpret_cast&>( buffer ), sizeof( T ) ); + ReadBucketElements( id, interleaved, reinterpret_cast&>( buffer ), sizeof( T ) ); } \ No newline at end of file diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index a07ecfac..4fa6db19 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -10,7 +10,7 @@ #define BB_DP_ENTRIES_PER_BUCKET ( ( 1ull << _K ) / BB_DP_BUCKET_COUNT ) #define BB_DP_XTRA_ENTRIES_PER_BUCKET 1.1 -#define BB_DP_ENTRY_SLICE_MULTIPLIER 1.07 +#define BB_DP_ENTRY_SLICE_MULTIPLIER 1.025 #define BB_DP_MAX_BC_GROUP_PER_BUCKET 300000 // There's around 284,190 groups per bucket (of bucket size 64) diff --git a/src/plotdisk/DiskPlotPhase3.cpp b/src/plotdisk/DiskPlotPhase3.cpp index 6fe45550..259a567a 100644 --- a/src/plotdisk/DiskPlotPhase3.cpp +++ b/src/plotdisk/DiskPlotPhase3.cpp @@ -1081,6 +1081,7 @@ size_t DiskPlotPhase3::GetRequiredHeapSize( const uint32 numBuckets, const bool } Fatal( "Unexpected bucket size %u.", numBuckets ); + return 0; } //----------------------------------------------------------- diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 75f9b5a8..4479944c 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -395,16 +395,10 @@ bool DiskPlotter::GetTmpPathsBlockSizes( const char* tmpPath1, const char* tmpPa ASSERT( tmpPath1 && *tmpPath1 ); ASSERT( tmpPath2 && *tmpPath2 ); - FileStream tmp1Dir, tmp2Dir; + tmpPath1Size = FileStream::GetBlockSizeForPath( tmpPath1 ); + tmpPath2Size = FileStream::GetBlockSizeForPath( tmpPath2 ); - if( !tmp1Dir.Open( tmpPath1, FileMode::Open, FileAccess::Read ) ) - return false; - if( !tmp2Dir.Open( tmpPath2, FileMode::Open, FileAccess::Read ) ) - return false; - - tmpPath1Size = tmp1Dir.BlockSize(); - tmpPath2Size = tmp2Dir.BlockSize(); - return true; + return tmpPath1Size && tmpPath2Size; } //----------------------------------------------------------- @@ -511,7 +505,7 @@ Creates plots by making use of a disk to temporarily store and read values. You may specify one of: 128, 256, 512, 1024 and 64 for if --k32-bounded is enabled. 1024 is not available for plots of k < 33. - --ubounded : Create an unbounded k32 plot. That is a plot that does not cut-off entries that + --unbounded : Create an unbounded k32 plot. That is a plot that does not cut-off entries that overflow 2^32; -a, --alternate : Halves the temp2 cache size requirements by alternating bucket writing methods @@ -555,20 +549,22 @@ Creates plots by making use of a disk to temporarily store and read values. [NOTES] If you don't specify any thread count overrides, the default thread count -specified in the global options will be used. +specified in the global options will be used +(specified as -t before the diskplot command). Phases 2 and 3 are typically more I/O bound than Phase 1 as these phases perform less computational work than Phase 1 and thus the CPU finishes the currently loaded workload quicker and will proceed to -grab another buffer from disk with a shorter frequency. Because of this +grab another buffer from the disk within a shorter time frame. Because of this you would typically lower the thread count for these phases if you are -incurring I/O waits. +incurring high I/O waits. [EXAMPLES] -bladebit -t 24 -f ... -c ... diskplot --b 128 --cache 32G -t1 /my/temporary/plot/dir - --f1-threads 3 --fp-threads 16 --c-threads 8 --p2-threads 12 --p3-threads 8 /my/output/dir +# Simple config: +bladebit -t 24 -f -c diskplot --t1 /my/temporary/plot/dir /my/output/dir -bladebit -t 8 -f ... -c ... diskplot -t2 /my/temporary/plot/dir -t2 /my/other/tmp/dir /my/output/dir +# With fine-grained control over threads per phase/section (see bladebit -h diskplot): +bladebit -t 30 -f -c diskplot --f1-threads 16 --c-threads 16 --p2-threads 8 --t1 /my/temporary/plot/dir /my/output/dir )"; //----------------------------------------------------------- diff --git a/src/plotdisk/k32/CTableWriterBounded.h b/src/plotdisk/k32/CTableWriterBounded.h index 67e1f2ef..4818194f 100644 --- a/src/plotdisk/k32/CTableWriterBounded.h +++ b/src/plotdisk/k32/CTableWriterBounded.h @@ -318,8 +318,8 @@ class CTableWriterBounded if( bucket >= _numBuckets ) return; - _ioQueue.ReadBucketElementsT( FileId::FX0 , _f7ReadBuffer [bucket] ); - _ioQueue.ReadBucketElementsT( FileId::INDEX0, _idxReadBuffer[bucket] ); + _ioQueue.ReadBucketElementsT( FileId::FX0 , true, _f7ReadBuffer [bucket] ); + _ioQueue.ReadBucketElementsT( FileId::INDEX0, true, _idxReadBuffer[bucket] ); _ioQueue.SignalFence( _readFence, bucket + 1 ); _ioQueue.CommitCommands(); } diff --git a/src/plotdisk/k32/DiskPlotBounded.cpp b/src/plotdisk/k32/DiskPlotBounded.cpp index 528984c8..3224ba70 100644 --- a/src/plotdisk/k32/DiskPlotBounded.cpp +++ b/src/plotdisk/k32/DiskPlotBounded.cpp @@ -42,12 +42,12 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) // Temp2 { - FileSetOptions opts = FileSetOptions::Interleaved; + FileSetInitData data = {}; + FileSetOptions opts = context.cfg->alternateBuckets ? FileSetOptions::Alternating : FileSetOptions::Interleaved; if( !context.cfg->noTmp2DirectIO ) opts |= FileSetOptions::DirectIO; - FileSetInitData data = {}; opts |= FileSetOptions::UseTemp2; size_t metaCacheSize = 0; @@ -55,8 +55,7 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) if( context.cache ) { // In fully interleaved mode (bigger writes chunks), we need 192GiB for k=32 - // In alternating mode, we need 96 GiB. - // #TODO: Support alternating mode + // In alternating mode, we need 96 GiB (around 99GiB if we account for disk block-alignment requirements). opts |= FileSetOptions::Cachable; data.cache = context.cache; @@ -64,9 +63,9 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) // Proportion out the size required per file: // A single y or index file requires at maximum 16GiB // A asingle meta file at its maximum will require 64GiB - // Divide the whole cache into 12 equal parts, where each meta file represent 4 parts. + // Divide the whole cache into 12 (6 for alternating mode) equal parts, where each meta file represent 4 parts. // Ex: 192 / 12 = 16. This gives us 4 files of 16GiB and 2 files of 64GiB - size_t singleFileCacheSize = context.cacheSize / 12; + size_t singleFileCacheSize = context.cacheSize / ( context.cfg->alternateBuckets ? 6 : 12 ); // Align to block size singleFileCacheSize = numBuckets * RoundUpToNextBoundaryT( singleFileCacheSize / numBuckets - context.tmp2BlockSize, context.tmp2BlockSize ); @@ -83,14 +82,38 @@ K32BoundedPhase1::K32BoundedPhase1( DiskPlotContext& context ) data.cache = (byte*)data.cache + data.cacheSize; }; - InitCachableFileSet( FileId::FX0 , "y0" , numBuckets, opts, data ); - InitCachableFileSet( FileId::FX1 , "y1" , numBuckets, opts, data ); - InitCachableFileSet( FileId::INDEX0, "index0", numBuckets, opts, data ); - InitCachableFileSet( FileId::INDEX1, "index1", numBuckets, opts, data ); + if( _context.cfg->alternateBuckets ) + { + const uint64 blockSize = context.tmp2BlockSize; + const uint64 tableEntries = 1ull << 32; + const uint64 bucketEntries = tableEntries / numBuckets; + const uint64 sliceEntries = bucketEntries / numBuckets; - data.cacheSize = metaCacheSize; - InitCachableFileSet( FileId::META0, "meta0", numBuckets, opts, data ); - InitCachableFileSet( FileId::META1, "meta1", numBuckets, opts, data ); + const uint64 ysPerBlock = blockSize / sizeof( uint32 ); + const uint64 metasPerBlock = blockSize / (sizeof( uint32 ) * 4); + + const uint64 sliceSizeY = RoundUpToNextBoundaryT( (uint64)(sliceEntries * BB_DP_ENTRY_SLICE_MULTIPLIER), ysPerBlock ) * sizeof( uint32 ); + const uint64 sliceSizeMeta = RoundUpToNextBoundaryT( (uint64)(sliceEntries * BB_DP_ENTRY_SLICE_MULTIPLIER), metasPerBlock ) * sizeof( uint32 ) * 4; + + data.maxSliceSize = sliceSizeY; + InitCachableFileSet( FileId::FX0 , "y0" , numBuckets, opts, data ); + InitCachableFileSet( FileId::INDEX0, "index0", numBuckets, opts, data ); + + data.maxSliceSize = sliceSizeMeta; + data.cacheSize = metaCacheSize; + InitCachableFileSet( FileId::META0, "meta0", numBuckets, opts, data ); + } + else + { + InitCachableFileSet( FileId::FX0 , "y0" , numBuckets, opts, data ); + InitCachableFileSet( FileId::FX1 , "y1" , numBuckets, opts, data ); + InitCachableFileSet( FileId::INDEX0, "index0", numBuckets, opts, data ); + InitCachableFileSet( FileId::INDEX1, "index1", numBuckets, opts, data ); + + data.cacheSize = metaCacheSize; + InitCachableFileSet( FileId::META0, "meta0", numBuckets, opts, data ); + InitCachableFileSet( FileId::META1, "meta1", numBuckets, opts, data ); + } } } @@ -126,8 +149,6 @@ size_t K32BoundedPhase1::GetRequiredSize( const uint32 numBuckets, const size_t //----------------------------------------------------------- void K32BoundedPhase1::Run() { - Log::Line( "Table 1: F1 generation" ); - switch( _context.numBuckets ) { case 64 : RunWithBuckets<64 >(); break; @@ -209,16 +230,22 @@ void K32BoundedPhase1::RunWithBuckets() #if !BB_DP_P1_KEEP_FILES if( table == TableId::Table6 ) { - // #TODO: Support alternating mode (only 1 metadata file) - _ioQueue.DeleteBucket( FileId::META0 ); - _ioQueue.CommitCommands(); + if( !_context.cfg->alternateBuckets ) + { + _ioQueue.DeleteBucket( FileId::META0 ); + _ioQueue.CommitCommands(); + } } else if( table == TableId::Table7 ) { - // #TODO: Support alternating mode (only 1 metadata file) - _ioQueue.DeleteBucket( FileId::FX1 ); - _ioQueue.DeleteBucket( FileId::INDEX1 ); - _ioQueue.DeleteBucket( FileId::META1 ); + if( _context.cfg->alternateBuckets ) + _ioQueue.DeleteBucket( FileId::META0 ); + else + { + _ioQueue.DeleteBucket( FileId::FX1 ); + _ioQueue.DeleteBucket( FileId::INDEX1 ); + _ioQueue.DeleteBucket( FileId::META1 ); + } _ioQueue.CommitCommands(); } #endif @@ -241,11 +268,9 @@ void K32BoundedPhase1::RunWithBuckets() } #if !BB_DP_P1_KEEP_FILES - // #TODO: Support alternating mode (only 1 metadata file) _ioQueue.DeleteBucket( FileId::FX0 ); _ioQueue.DeleteBucket( FileId::INDEX0 ); _ioQueue.CommitCommands(); - // # TODO: Wait for deletion? #endif } @@ -256,14 +281,15 @@ void K32BoundedPhase1::RunF1() { _context.ioWaitTime = Duration::zero(); + Log::Line( "Table 1: F1 generation" ); Log::Line( "Generating f1..." ); - auto timer = TimerBegin(); + const auto timer = TimerBegin(); StackAllocator allocator( _context.heapBuffer, _context.heapSize ); K32BoundedF1<_numBuckets> f1( _context, allocator ); f1.Run(); + const double elapsed = TimerEnd( timer ); - double elapsed = TimerEnd( timer ); Log::Line( "Finished f1 generation in %.2lf seconds. ", elapsed ); Log::Line( "Table 1 I/O wait time: %.2lf seconds.", _context.p1TableWaitTime[(int)TableId::Table1] ); @@ -315,10 +341,11 @@ void K32BoundedPhase1::RunFx() #if _DEBUG BB_DP_DBG_WriteTableCounts( _context ); - + // #TODO: Update this for alternating mode _ioQueue.DebugWriteSliceSizes( table, (uint)table %2 == 0 ? FileId::FX0 : FileId::FX1 ); _ioQueue.DebugWriteSliceSizes( table, (uint)table %2 == 0 ? FileId::INDEX0 : FileId::INDEX1 ); _ioQueue.DebugWriteSliceSizes( table, (uint)table %2 == 0 ? FileId::META0 : FileId::META1 ); _ioQueue.CommitCommands(); #endif } + diff --git a/src/plotdisk/k32/F1Bounded.inl b/src/plotdisk/k32/F1Bounded.inl index e23a3eca..9069033b 100644 --- a/src/plotdisk/k32/F1Bounded.inl +++ b/src/plotdisk/k32/F1Bounded.inl @@ -102,7 +102,7 @@ public: Fence& fence = _context.fencePool->RequireFence(); _ioQueue.SignalFence( fence, 1 ); _ioQueue.CommitCommands(); - fence.Wait( 1, _context.ioWaitTime ); + fence.Wait( 1, _context.p1TableWaitTime[(int)TableId::Table1] ); _context.entryCounts[(int)TableId::Table1] = 1ull << _k; @@ -170,8 +170,8 @@ private: // Write to disk (and synchronize threads) if( self->BeginLockBlock() ) { - _ioQueue.WriteBucketElementsT( FileId::FX0 , yEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); - _ioQueue.WriteBucketElementsT( FileId::META0, xEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( FileId::FX0 , true, yEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( FileId::META0, true, xEntries.Ptr(), alignedElementCounts.Ptr(), elementCounts.Ptr() ); _ioQueue.SignalFence( _writeFence, bucket+2 ); _ioQueue.CommitCommands(); @@ -277,8 +277,8 @@ void DbgValidateF1( DiskPlotContext& context ) Span yBucket = tmpBuffer.template As(); Span xBucket = tmpBuffer2; - ioQueue.ReadBucketElementsT( FileId::FX0 , yBucket ); - ioQueue.ReadBucketElementsT( FileId::META0, xBucket ); + ioQueue.ReadBucketElementsT( FileId::FX0 , true, yBucket ); + ioQueue.ReadBucketElementsT( FileId::META0, true, xBucket ); ioQueue.SignalFence( fence ); ioQueue.CommitCommands(); fence.Wait(); @@ -353,5 +353,6 @@ void DbgValidateF1( DiskPlotContext& context ) bbvirtfreebounded( tmpBuffer.Ptr() ); bbvirtfreebounded( tmpBuffer2.Ptr() ); } + #endif diff --git a/src/plotdisk/k32/FpMatchBounded.inl b/src/plotdisk/k32/FpMatchBounded.inl index 6fcccc5d..70726a80 100644 --- a/src/plotdisk/k32/FpMatchBounded.inl +++ b/src/plotdisk/k32/FpMatchBounded.inl @@ -115,7 +115,7 @@ public: // const uint32 startIndex = (uint32)(uintptr_t)(_startPositions[id] - yEntries.Ptr()); - const uint32 matchCount = MatchGroups( self, bucket, bucket,startIndex, _groupBuffers[id], + const uint32 matchCount = MatchGroups( self, bucket, bucket, startIndex, _groupBuffers[id], yEntries, pairs, pairs.Length() ); return pairs.Slice( 0, matchCount ); diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 478939c7..03aa1934 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -68,6 +68,9 @@ class DiskPlotFxBounded static constexpr uint32 _k = 32; static constexpr uint64 _maxTableEntries = (1ull << _k) - 1; + static constexpr uint64 _maxSliceEntries = (uint64)((_maxTableEntries / _numBuckets / _numBuckets ) * BB_DP_ENTRY_SLICE_MULTIPLIER); + + static constexpr uint32 _bucketBits = bblog2( _numBuckets ); static constexpr uint32 _pairsMaxDelta = 512; static constexpr uint32 _pairsLeftBits = _k - _bucketBits + 1; // Buckets may overflow, so need an extra bit @@ -91,6 +94,7 @@ public: #endif { const TableId lTable = rTable - 1; + _yId [0] = FileId::FX0 + (FileId)((int)lTable & 1); _idxId [0] = FileId::INDEX0 + (FileId)((int)lTable & 1); _metaId[0] = FileId::META0 + (FileId)((int)lTable & 1); @@ -98,6 +102,18 @@ public: _yId [1] = FileId::FX0 + (FileId)((int)rTable & 1); _idxId [1] = FileId::INDEX0 + (FileId)((int)rTable & 1); _metaId[1] = FileId::META0 + (FileId)((int)rTable & 1); + + if( context.cfg && context.cfg->alternateBuckets ) + { + _interleaved = ((uint)rTable & 1) == 0; // Only even tables have interleaved writes when alternating mode is enabled + + _yId [0] = FileId::FX0; + _idxId [0] = FileId::INDEX0; + _metaId[0] = FileId::META0; + _yId [1] = FileId::FX0; + _idxId [1] = FileId::INDEX0; + _metaId[1] = FileId::META0; + } } //----------------------------------------------------------- @@ -916,8 +932,8 @@ private: if( self->IsControlThread() ) timer = TimerBegin(); - const uint32 blockSize = (uint32)_ioQueue.BlockSize( _yId[1] ); - const uint32 id = (uint32)self->JobId(); + const uint32 blockSize = (uint32)_ioQueue.BlockSize( _yId[1] ); + const uint32 id = (uint32)self->JobId(); // Distribute to buckets const uint32 bucketBits = bblog2( _numBuckets ); @@ -947,7 +963,7 @@ private: self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, ySliceCounts.Ptr(), _offsetsY[id], yAlignedSliceCount.Ptr() ); - if constexpr ( rTable < TableId::Table7 ) + if ( rTable < TableId::Table7 ) self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSumMeta, metaSliceCounts.Ptr(), _offsetsMeta[id], metaAlignedSliceCount.Ptr() ); if( bucket > 0 ) @@ -964,8 +980,8 @@ private: const uint32 yBucket = (uint32)(y >> bucketShift); const uint32 yDst = --pfxSum [yBucket]; - yOut [yDst] = (uint32)(y & yMask); - idxOut [yDst] = idxOffset + (uint32)i; ASSERT( (uint64)idxOffset + (uint64)i < (1ull << _k) ); + yOut [yDst] = (uint32)(y & yMask); + idxOut[yDst] = idxOffset + (uint32)i; ASSERT( (uint64)idxOffset + (uint64)i < (1ull << _k) ); if constexpr ( rTable < TableId::Table7 ) { @@ -983,11 +999,22 @@ private: ASSERT( ySliceCounts.Length() == metaSliceCounts.Length() ); - _ioQueue.WriteBucketElementsT ( yId , yOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); - _ioQueue.WriteBucketElementsT ( idxId , idxOut .Ptr(), yAlignedSliceCount.Ptr() , ySliceCounts.Ptr() ); - + #if _DEBUG + { + const uint64 maxSliceEntries = _maxSliceEntries; + for( uint32 i = 0; i < _numBuckets; i++ ) + { + ASSERT( yAlignedSliceCount[i] <= maxSliceEntries ); + ASSERT( metaAlignedSliceCount[i] <= maxSliceEntries ); + } + } + #endif + + _ioQueue.WriteBucketElementsT( yId , _interleaved, yOut .Ptr(), yAlignedSliceCount.Ptr(), ySliceCounts.Ptr() ); + _ioQueue.WriteBucketElementsT( idxId, _interleaved, idxOut .Ptr(), yAlignedSliceCount.Ptr(), ySliceCounts.Ptr() ); + if( rTable < TableId::Table7 ) - _ioQueue.WriteBucketElementsT( metaId, metaOut.Ptr(), metaAlignedSliceCount.Ptr(), ySliceCounts.Ptr() ); // #TODO: Can use ySliceCounts here... + _ioQueue.WriteBucketElementsT( metaId, _interleaved, metaOut.Ptr(), metaAlignedSliceCount.Ptr(), ySliceCounts.Ptr() ); _ioQueue.SignalFence( _fxWriteFence, bucket+1 ); _ioQueue.CommitCommands(); @@ -998,7 +1025,6 @@ private: } self->EndLockBlock(); - if( self->IsControlThread() ) _distributeTime += TimerEndTicks( timer ); } @@ -1164,16 +1190,18 @@ private: if( !self->IsControlThread() ) return; - _ioQueue.ReadBucketElementsT( _yId[0], _y[bucket] ); + const bool interleaved = !_interleaved; // If the rTable is interleaved, then the L table is not interleaved and vice-versa. + + _ioQueue.ReadBucketElementsT( _yId[0], interleaved, _y[bucket] ); _ioQueue.SignalFence( _yReadFence, bucket + 1 ); if constexpr ( rTable > TableId::Table2 ) { - _ioQueue.ReadBucketElementsT( _idxId[0], _index[bucket] ); + _ioQueue.ReadBucketElementsT( _idxId[0], interleaved, _index[bucket] ); _ioQueue.SignalFence( _indexReadFence, bucket + 1 ); } - _ioQueue.ReadBucketElementsT( _metaId[0], _meta[bucket] ); + _ioQueue.ReadBucketElementsT( _metaId[0], interleaved, _meta[bucket] ); _ioQueue.SignalFence( _metaReadFence, bucket + 1 ); _ioQueue.CommitCommands(); @@ -1211,6 +1239,8 @@ private: // Load indices const uint64 entryCount = _context.entryCounts[(int)rTable]; + const bool interleaved = ((uint32)rTable & 1) == 0; + const FileId fileId = _idxId[1]; _ioQueue.SeekBucket( fileId, 0, SeekOrigin::Begin ); _ioQueue.CommitCommands(); @@ -1227,7 +1257,7 @@ private: { Span reader = tmpIndices; - _ioQueue.ReadBucketElementsT( fileId, reader ); + _ioQueue.ReadBucketElementsT( fileId, interleaved, reader ); _ioQueue.SignalFence( fence ); _ioQueue.CommitCommands(); fence.Wait(); @@ -1286,6 +1316,9 @@ private: byte* _pairsWriteBuffer; BlockWriter _xWriter; // Used for Table2 (there's no map, but just x.) Span _xWriteBuffer; // Set by the control thread for other threads to use + + // Writers for when using alternating mode, for non-interleaved writes + bool _interleaved = true; // Working buffers Span _yTmp; @@ -1293,8 +1326,6 @@ private: Span _metaTmp[2]; Span _pairBuffer; - // When doing cross-bucket matching, we save the previous bucket entries as these spans (which just point to the working buffers) - // Working views Span _pairs[BB_DP_MAX_JOBS]; // Pairs buffer divided per thread @@ -1304,9 +1335,6 @@ private: // Map MapWriter<_numBuckets, false> _mapWriter; uint64 _mapBitCounts[_numBuckets]; // Used by the map writer. Single instace shared accross jobs - // uint32 _mapSliceCounts [_numBuckets]; - // uint32 _mapAlignedCounts[_numBuckets]; - // uint32 _mapOffsets [_numBuckets] = {}; // Distributing to buckets Span _offsetsY; diff --git a/src/util/Span.h b/src/util/Span.h index af3d3929..18af7585 100644 --- a/src/util/Span.h +++ b/src/util/Span.h @@ -42,7 +42,7 @@ struct Span inline T& operator[]( int64 index ) const { - ASSERT( index < length ); + ASSERT( index < (int64)length ); return this->values[index]; } From a053067f8e1ee84a822977e5f1c6b1018aa0a6ac Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 9 Aug 2022 18:24:22 -0500 Subject: [PATCH 81/91] Fixes a directory handle leak when getting the block size on windows. --- src/platform/win32/FileStream_Win32.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/win32/FileStream_Win32.cpp b/src/platform/win32/FileStream_Win32.cpp index 90865fed..935dc7f6 100644 --- a/src/platform/win32/FileStream_Win32.cpp +++ b/src/platform/win32/FileStream_Win32.cpp @@ -400,6 +400,8 @@ size_t FileStream::GetBlockSizeForPath( const char* pathU8 ) { if( !GetFileClusterSize( fd, blockSize ) ) blockSize = 0; + + ::CloseHandle( fd ); } if( path16 != path16Stack ) From 04efa15979f805347c18103f30d707c86562af5a Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 9 Aug 2022 18:32:47 -0500 Subject: [PATCH 82/91] Logging iif alternating mode is enabled --- src/plotdisk/DiskPlotter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 4479944c..4f302b35 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -77,6 +77,7 @@ DiskPlotter::DiskPlotter( const Config& cfg ) Log::Line( " Heap size : %.2lf GiB ( %.2lf MiB )", (double)_cx.heapSize BtoGB, (double)_cx.heapSize BtoMB ); Log::Line( " Cache size : %.2lf GiB ( %.2lf MiB )", (double)_cx.cacheSize BtoGB, (double)_cx.cacheSize BtoMB ); Log::Line( " Bucket count : %u" , _cx.numBuckets ); + Log::Line( " Alternating I/O: %s" , cfg.alternateBuckets ? "true" : "false" ); Log::Line( " F1 threads : %u" , _cx.f1ThreadCount ); Log::Line( " FP threads : %u" , _cx.fpThreadCount ); Log::Line( " C threads : %u" , _cx.cThreadCount ); From 904003341e78edc7554be13d2d9c91b5aaf03d26 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 9 Aug 2022 18:54:20 -0500 Subject: [PATCH 83/91] Bump version to apha2, force io metrics on. --- VERSION | 2 +- src/plotdisk/DiskPlotConfig.h | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index a3fc5781..0b303383 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ 2.0.0 --alpha1 \ No newline at end of file +-alpha2 \ No newline at end of file diff --git a/src/plotdisk/DiskPlotConfig.h b/src/plotdisk/DiskPlotConfig.h index 4fa6db19..cff87cbe 100644 --- a/src/plotdisk/DiskPlotConfig.h +++ b/src/plotdisk/DiskPlotConfig.h @@ -112,7 +112,15 @@ #endif +// Beta-mode +// (Force for now) +#define BB_BETA_MODE 1 +#if BB_BETA_MODE + #ifdef BB_IO_METRICS_ON + #undef BB_IO_METRICS_ON + #endif - + #define BB_IO_METRICS_ON 1 +#endif From 5b6c2c035f74fc65cfb58a565d255fe48ec7fa9f Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 31 Aug 2022 15:46:16 -0500 Subject: [PATCH 84/91] Fixes 128 buckets and -n regression (#205) * Fixes 128 buckets * Added support for -n again. * Fixed regression when adding support for -n parameter. --- .vscode/launch.json | 23 ++++++--- src/plotdisk/DiskBufferQueue.cpp | 84 ++++++++++++++++++++------------ src/plotdisk/DiskPlotDebug.h | 6 ++- src/plotdisk/DiskPlotPhase3.cpp | 2 +- src/plotdisk/DiskPlotter.cpp | 19 +++----- src/util/Util.h | 1 + 6 files changed, 82 insertions(+), 53 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index e35fc117..20733749 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -53,7 +53,14 @@ "program": "${workspaceFolder}/build/bladebit", "osx": { - "MIMode": "lldb" + "MIMode": "lldb", + "args": [ + "-f", "ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef", + "-p", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8", + "-i", "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835", + "diskplot", + "-t1", "/Volumes/Plotting", "/Volumes/Plotting" + ] }, "windows": { @@ -68,6 +75,7 @@ "-t", "62", "-w", // "-v", + "-n", "3", "-i", "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835", // No overflow "--memo", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef01b7bf8a22a9ac82a003e07b551c851ea683839f3e1beb8ac9ede57d2c020669", @@ -76,22 +84,22 @@ "--show-memo", "diskplot", - "-a", "-t1", "~/plot/tmp", "--f1-threads", "24", // "--fp-threads", "62", "--c-threads", "28", "--p2-threads", "24", - - // "--cache", "196G", - "--cache", "99G", + + // "-a", + "--cache", "196G", + // "--cache", "99G", // "--cache", "200G", // "--cache", "64G", // "-s", // "--k32-bounded", - "-b", "64", + // "-b", "64", // "--sizes", - // "-b", "128", + "-b", "128", // "-b", "256", "--c-threads", "26", @@ -99,6 +107,7 @@ "--p3-threads", "48", "~/plot/tmp" ], + // ,"stopAtEntry": true "environment": [] diff --git a/src/plotdisk/DiskBufferQueue.cpp b/src/plotdisk/DiskBufferQueue.cpp index 413cb94b..a02c6320 100644 --- a/src/plotdisk/DiskBufferQueue.cpp +++ b/src/plotdisk/DiskBufferQueue.cpp @@ -118,29 +118,35 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC flags |= FileFlags::NoBuffering; FileSet& fileSet = _files[(uint)fileId]; - ASSERT( !fileSet.files.values ); - fileSet.name = name; - fileSet.files.values = new IStream*[bucketCount]; - fileSet.files.length = bucketCount; - fileSet.blockBuffer = nullptr; - fileSet.options = options; - - if( IsFlagSet( options, FileSetOptions::Interleaved ) || IsFlagSet( options, FileSetOptions::Alternating ) ) + if( !fileSet.name ) { - fileSet.readSliceSizes.SetTo( new Span[bucketCount], bucketCount ); - fileSet.writeSliceSizes.SetTo( new Span[bucketCount], bucketCount ); - for( uint32 i = 0; i < bucketCount; i++ ) + ASSERT( !fileSet.files.values ); + + fileSet.name = name; + fileSet.files.values = new IStream*[bucketCount]; + fileSet.files.length = bucketCount; + fileSet.blockBuffer = nullptr; + fileSet.options = options; + + memset( fileSet.files.values, 0, sizeof( uintptr_t ) * bucketCount ); + + if( IsFlagSet( options, FileSetOptions::Interleaved ) || IsFlagSet( options, FileSetOptions::Alternating ) ) { - fileSet.readSliceSizes[i].SetTo( new size_t[bucketCount]{}, bucketCount ); - fileSet.writeSliceSizes[i].SetTo( new size_t[bucketCount]{}, bucketCount ); + fileSet.readSliceSizes.SetTo( new Span[bucketCount], bucketCount ); + fileSet.writeSliceSizes.SetTo( new Span[bucketCount], bucketCount ); + for( uint32 i = 0; i < bucketCount; i++ ) + { + fileSet.readSliceSizes[i].SetTo( new size_t[bucketCount]{}, bucketCount ); + fileSet.writeSliceSizes[i].SetTo( new size_t[bucketCount]{}, bucketCount ); + } } - } - if( IsFlagSet( options, FileSetOptions::Alternating ) ) - { - fileSet.maxSliceSize = optsData->maxSliceSize; - ASSERT( fileSet.maxSliceSize ); + if( IsFlagSet( options, FileSetOptions::Alternating ) ) + { + fileSet.maxSliceSize = optsData->maxSliceSize; + ASSERT( fileSet.maxSliceSize ); + } } const bool isCachable = IsFlagSet( options, FileSetOptions::Cachable ) && optsData->cacheSize > 0; @@ -156,14 +162,18 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC // #TODO: Try using a single file and opening multiple handles to that file as buckets... for( uint i = 0; i < bucketCount; i++ ) { - IStream* file = nullptr; - - if( isCachable ) - file = new HybridStream(); - else - file = new FileStream(); + IStream* file = fileSet.files[i]; + + if( !file ) + { + if( isCachable ) + file = new HybridStream(); + else + file = new FileStream(); - fileSet.files[i] = file; + fileSet.files[i] = file; + } + const FileMode fileMode = #if _DEBUG && ( BB_DP_DBG_READ_EXISTING_F1 || BB_DP_DBG_SKIP_PHASE_1 || BB_DP_P1_SKIP_TO_TABLE || BB_DP_DBG_SKIP_TO_C_TABLES ) @@ -205,10 +215,12 @@ bool DiskBufferQueue::InitFileSet( FileId fileId, const char* name, uint bucketC Fatal( "Failed to open temp work file @ %s with error: %d.", pathBuffer, file->GetError() ); } - - if( i == 0 && IsFlagSet( options, FileSetOptions::DirectIO ) ) + + // Always align for now. + if( i == 0 && !fileSet.blockBuffer )//&& IsFlagSet( options, FileSetOptions::DirectIO ) ) { // const size_t totalBlockSize = file->BlockSize() * bucketCount; + ASSERT( file->BlockSize() ); fileSet.blockBuffer = bbvirtalloc( file->BlockSize() ); // #TODO: This should be removed, and we should use // a shared one per temp dir. } @@ -258,7 +270,7 @@ void DiskBufferQueue::OpenPlotFile( const char* fileName, const byte* plotId, co byte* header = _plotHeaderbuffer; - // Encode the headers + // Encode the header { // Magic byte* headerWriter = header; @@ -1203,7 +1215,12 @@ void DiskBufferQueue::CmdDbgWriteSliceSizes( const Command& cmd ) sprintf( path, "%st%d.%s.slices.tmp", BB_DP_DBG_TEST_DIR, (int)cmd.dbgSliceSizes.table+1, fName ); FileStream file; - FatalIf( !file.Open( path, FileMode::Create, FileAccess::Write ), "Failed to open '%s' for writing.", path ); + if( !file.Open( path, FileMode::Create, FileAccess::Write ) ) + { + Log::Error( "Failed to open '%s' for writing.", path ); + return; + } + // FatalIf( !file.Open( path, FileMode::Create, FileAccess::Write ), "Failed to open '%s' for writing.", path ); FileSet& fileSet = _files[(int)cmd.dbgSliceSizes.fileId]; const uint32 numBuckets = (uint32)fileSet.files.Length(); @@ -1213,8 +1230,13 @@ void DiskBufferQueue::CmdDbgWriteSliceSizes( const Command& cmd ) auto slices = fileSet.writeSliceSizes[i]; const size_t sizeWrite = sizeof( size_t ) * numBuckets; - FatalIf( file.Write( slices.Ptr(), sizeWrite ) != sizeWrite, - "Failed to write slice size for table %d", (int)cmd.dbgSliceSizes.table+1 ); + if( file.Write( slices.Ptr(), sizeWrite ) != sizeWrite ) + { + Log::Error( "Failed to write slice size for table %d", (int)cmd.dbgSliceSizes.table+1 ); + return; + } + // FatalIf( file.Write( slices.Ptr(), sizeWrite ) != sizeWrite, + // "Failed to write slice size for table %d", (int)cmd.dbgSliceSizes.table+1 ); } } diff --git a/src/plotdisk/DiskPlotDebug.h b/src/plotdisk/DiskPlotDebug.h index a692f415..42169010 100644 --- a/src/plotdisk/DiskPlotDebug.h +++ b/src/plotdisk/DiskPlotDebug.h @@ -257,7 +257,11 @@ inline bool Debug::LoadRefTableByName( const char* fileName, T*& buffer, uint64& template inline bool Debug::LoadRefTableByName( const char* fileName, Span& buffer ) { - return LoadRefTableByName( fileName, buffer.values, buffer.length ); + // T*& buffer = buffer.values; + uint64 outEntryCount = 0; + bool r = LoadRefTableByName( fileName, buffer.values, outEntryCount ); + buffer.length = (size_t)outEntryCount; + return r; } //----------------------------------------------------------- diff --git a/src/plotdisk/DiskPlotPhase3.cpp b/src/plotdisk/DiskPlotPhase3.cpp index 259a567a..2d641b59 100644 --- a/src/plotdisk/DiskPlotPhase3.cpp +++ b/src/plotdisk/DiskPlotPhase3.cpp @@ -809,7 +809,7 @@ class P3StepTwo // If our iteration count is not even, it means the final // output of the sort is saved in the tmp buffers. - constexpr int32 maxSortIter = (int)CDiv( 64 - _bucketBits, 8 ); + constexpr int32 maxSortIter = (int)CDiv( _lpBits, 8 ); if( ( maxSortIter & 1 ) != 0) { diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 5e6dc163..0f55f143 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -35,17 +35,6 @@ DiskPlotter::DiskPlotter( const Config& cfg ) GlobalPlotConfig& gCfg = *cfg.globalCfg; - // #TODO: Remove when fixed - { - FatalIf( cfg.numBuckets == 128, "128 Buckets is currently not serializing plots correctly. Please select a differnt bucket count." ); - - if( gCfg.plotCount != 1 ) - { - Log::Line( "[WARNING] Consecutive plots are currently not supported. Forcing plot count to 1." ); - gCfg.plotCount = 1; - } - } - FatalIf( !GetTmpPathsBlockSizes( cfg.tmpPath, cfg.tmpPath2, _cx.tmp1BlockSize, _cx.tmp2BlockSize ), "Failed to obtain temp paths block size from t1: '%s' or %s t2: '%s'.", cfg.tmpPath, cfg.tmpPath2 ); @@ -156,7 +145,10 @@ void DiskPlotter::Plot( const PlotRequest& req ) memset( _cx.entryCounts , 0, sizeof( _cx.entryCounts ) ); memset( _cx.ptrTableBucketCounts, 0, sizeof( _cx.ptrTableBucketCounts ) ); memset( _cx.bucketSlices , 0, sizeof( _cx.bucketSlices ) ); - // #TODO: Reset the rest of the state, including the heap & the ioQueue + memset( _cx.p1TableWaitTime , 0, sizeof( _cx.p1TableWaitTime ) ); + _cx.ioWaitTime = Duration::zero(); + _cx.cTableWaitTime = Duration::zero(); + _cx.p7WaitTime = Duration::zero(); const bool bounded = _cx.cfg->bounded; @@ -256,10 +248,11 @@ void DiskPlotter::Plot( const PlotRequest& req ) ioQueue.WriteFile( FileId::PLOT, 0, _cx.plotTablePointers, sizeof( _cx.plotTablePointers ) ); // Wait for all IO commands to finish - Fence fence; + Fence& fence = _cx.fencePool->RequireFence(); ioQueue.SignalFence( fence ); ioQueue.CommitCommands(); fence.Wait(); + _cx.fencePool->ReleaseFence( fence ); const double elapsed = TimerEnd( timer ); Log::Line( "Completed pending writes in %.2lf seconds.", elapsed ); diff --git a/src/util/Util.h b/src/util/Util.h index 1b49e855..d6a3f7cc 100644 --- a/src/util/Util.h +++ b/src/util/Util.h @@ -207,6 +207,7 @@ inline void bbvirtfree( void* ptr ) template inline T* bbvirtalloc( size_t size ) { + ASSERT( size ); void* ptr = SysHost::VirtualAlloc( size, false ); FatalIf( !ptr, "VirtualAlloc failed." ); return reinterpret_cast( ptr ); From 747112d2c86e661a6ef49e1411075670d46ba7a7 Mon Sep 17 00:00:00 2001 From: William Allen Date: Wed, 14 Sep 2022 22:55:47 -0500 Subject: [PATCH 85/91] Create codeql-analysis.yml (#203) * Create codeql-analysis.yml * Update codeql-analysis.yml Adding numactl manually building --- .github/workflows/codeql-analysis.yml | 65 +++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..19d93171 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,65 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '32 4 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp', 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Build + # uses: github/codeql-action/autobuild@v2 + run: | + sudo apt update + sudo apt install -y build-essential cmake libgmp-dev libnuma-dev + cmake . -Bbuild + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 From fbdc5e7aa7da7146558641d642a2ffb50e0171d7 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 22 Sep 2022 18:16:19 -0500 Subject: [PATCH 86/91] Added support for testnet contract addresses (txch). (#213) - Added tests to support it. --- src/util/KeyTools.cpp | 22 +- src/util/KeyTools.h | 15 +- src/util/Util.h | 34 ++ test/checker.py | 15 - tests/TestAddressesAndKeys.cpp | 42 ++ tests/TestBucketSliceRead.cpp | 892 ++++++++++++++-------------- tests/TestUtil.h | 2 +- tests/TestXchAddressData.h | 1010 ++++++++++++++++++++++++++++++++ 8 files changed, 1561 insertions(+), 471 deletions(-) delete mode 100755 test/checker.py create mode 100644 tests/TestAddressesAndKeys.cpp create mode 100644 tests/TestXchAddressData.h diff --git a/src/util/KeyTools.cpp b/src/util/KeyTools.cpp index ea0037fc..4df99278 100644 --- a/src/util/KeyTools.cpp +++ b/src/util/KeyTools.cpp @@ -74,23 +74,25 @@ void KeyTools::PrintSK( const bls::PrivateKey& key ) /// PuzzleHash /// //----------------------------------------------------------- -bool PuzzleHash::FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_LENGTH+1] ) +bool PuzzleHash::FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_MAX_LENGTH+1] ) { ASSERT( address ); if( !address ) return false; - if( strlen( address ) != CHIA_ADDRESS_LENGTH ) + const size_t addrLen = strlen( address ); + if( addrLen != CHIA_ADDRESS_LENGTH && addrLen != CHIA_TESTNET_ADDRESS_LENGTH ) return false; - char hrp [CHIA_ADDRESS_LENGTH-5] = { 0 }; - byte data[CHIA_ADDRESS_LENGTH-8]; + char hrp [CHIA_ADDRESS_MAX_LENGTH-5] = {}; + byte data[CHIA_ADDRESS_MAX_LENGTH-8]; size_t dataLen = 0; if( bech32_decode( hrp, data, &dataLen, address ) != BECH32_ENCODING_BECH32M ) return false; - if( memcmp( "xch", hrp, sizeof( "xch" ) ) != 0 ) + if( memcmp( "xch", hrp, sizeof( "xch" ) ) != 0 && + memcmp( "txch", hrp, sizeof( "txch" ) ) != 0 ) return false; byte decoded[40]; @@ -105,3 +107,13 @@ bool PuzzleHash::FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_ return true; } +//----------------------------------------------------------- +bool PuzzleHash::FromHex( const char hex[CHIA_PUZZLE_HASH_SIZE*2+1], PuzzleHash& outHash ) +{ + const size_t hexLen = strlen( hex ); + if( hexLen != CHIA_PUZZLE_HASH_SIZE*2 ) + return false; + + return HexStrToBytesSafe( hex, hexLen, outHash.data, CHIA_PUZZLE_HASH_SIZE ); +} + diff --git a/src/util/KeyTools.h b/src/util/KeyTools.h index 3c43b751..43d327ce 100644 --- a/src/util/KeyTools.h +++ b/src/util/KeyTools.h @@ -21,21 +21,28 @@ extern "C" { #pragma warning( pop ) -#define CHIA_PUZZLE_HASH_SIZE 32 -#define CHIA_ADDRESS_LENGTH 62 // 3 (hrp) + 1 (divisor) + 52 (data) + 6 (checksum) +#define CHIA_PUZZLE_HASH_SIZE 32 +#define CHIA_ADDRESS_MAX_LENGTH 63 // 4 (hrp) + 1 (divisor) + 52 (data) + 6 (checksum) + // hrp is either xch or txch + + #define CHIA_ADDRESS_LENGTH 62 + #define CHIA_TESTNET_ADDRESS_LENGTH 63 struct XchAddress : NBytes {}; struct PuzzleHash : NBytes { - static bool FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_LENGTH+1] ); + static bool FromAddress( PuzzleHash& hash, const char address[CHIA_ADDRESS_MAX_LENGTH+1] ); - void ToAddress( char address[CHIA_ADDRESS_LENGTH+1] ); + void ToAddress( char address[CHIA_ADDRESS_MAX_LENGTH+1] ); std::string ToAddressString(); void ToHex( char hex[CHIA_PUZZLE_HASH_SIZE+1] ) const; std::string ToHex() const; + + static bool FromHex( const char hex[CHIA_PUZZLE_HASH_SIZE*2+1], PuzzleHash& outHash ); + }; class KeyTools diff --git a/src/util/Util.h b/src/util/Util.h index d6a3f7cc..0ac15677 100644 --- a/src/util/Util.h +++ b/src/util/Util.h @@ -464,6 +464,40 @@ inline void HexStrToBytes( const char* str, const size_t strSize, } } +//----------------------------------------------------------- +inline bool HexStrToBytesSafe( const char* str, const size_t strSize, + byte* dst, size_t dstSize ) +{ + if( !str || !strSize || !dst || !dstSize ) + return false; + + const size_t maxSize = (strSize / 2) * 2; + const char* end = str + maxSize; + + if( dstSize < maxSize / 2 ) + return false; + + int i = 0; + while( str < end ) + { + const int char0 = (int)str[0]; + const int char1 = (int)str[1]; + + if( (char0 - (int)'0' > 9 && char0 - (int)'A' > 5 && char0 - (int)'a' > 5) || + (char1 - (int)'0' > 9 && char1 - (int)'A' > 5 && char1 - (int)'a' > 5) ) + return false; + + byte msb = (byte)HEX_TO_BIN[char0]; + byte lsb = (byte)HEX_TO_BIN[char1]; + + byte v = lsb + msb * 16u; + dst[i++] = v; + str += 2; + } + + return true; +} + //----------------------------------------------------------- // Encode bytes into hex format // Return: diff --git a/test/checker.py b/test/checker.py deleted file mode 100755 index 799b406c..00000000 --- a/test/checker.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python3 -import sys - -argv = sys.argv[1:] -f7_path = argv[0] -# plot_path = argv[1] -# nssd_plot_path = argv[2] - -print( f'F7 path: {f7_path}') - -f7=40008 -f7=f'{f7:-08x}' - -challenge=f'{f7}0000000000000000000000000000000000000000000000000000000000000000'[:64] -print( challenge ) diff --git a/tests/TestAddressesAndKeys.cpp b/tests/TestAddressesAndKeys.cpp new file mode 100644 index 00000000..a4b27f57 --- /dev/null +++ b/tests/TestAddressesAndKeys.cpp @@ -0,0 +1,42 @@ +#include "TestUtil.h" +#include "util/KeyTools.h" +#include "TestXchAddressData.h" +#include "util/Util.h" + +//----------------------------------------------------------- +TEST_CASE( "mainnet-contract-address-decode", "[unit-core][contract-address]" ) +{ + const uint64 numAddresses = (uint64)( sizeof( TestMainnetAddress) / sizeof( AddrHashTestPair ) ); + PuzzleHash generatedHash; + + for( uint64 i = 0; i < numAddresses; i++ ) + { + const AddrHashTestPair& pair = TestMainnetAddress[i]; + + ENSURE( PuzzleHash::FromAddress( generatedHash, pair.address ) ); + + PuzzleHash expectedHash; + ENSURE( PuzzleHash::FromHex( pair.hash, expectedHash ) ); + + ENSURE( memcmp( generatedHash.data, expectedHash.data, CHIA_PUZZLE_HASH_SIZE ) == 0 ); + } +} + +//----------------------------------------------------------- +TEST_CASE( "testnet-contract-address-decode", "[unit-core][contract-address]" ) +{ + const uint64 numAddresses = (uint64)( sizeof( TestTestnetAddress) / sizeof( AddrHashTestPair ) ); + PuzzleHash generatedHash; + + for( uint64 i = 0; i < numAddresses; i++ ) + { + const AddrHashTestPair& pair = TestTestnetAddress[i]; + + ENSURE( PuzzleHash::FromAddress( generatedHash, pair.address ) ); + + PuzzleHash expectedHash; + ENSURE( PuzzleHash::FromHex( pair.hash, expectedHash ) ); + + ENSURE( memcmp( generatedHash.data, expectedHash.data, CHIA_PUZZLE_HASH_SIZE ) == 0 ); + } +} \ No newline at end of file diff --git a/tests/TestBucketSliceRead.cpp b/tests/TestBucketSliceRead.cpp index 134f0953..ddd2eb1d 100644 --- a/tests/TestBucketSliceRead.cpp +++ b/tests/TestBucketSliceRead.cpp @@ -1,446 +1,446 @@ -#include "TestUtil.h" -#include "io/BucketStream.h" -#include "io/HybridStream.h" -#include "util/Util.h" -#include "threading/MTJob.h" -#include "pos/chacha8.h" -#include "ChiaConsts.h" -#include "plotdisk/DiskBufferQueue.h" -#include "algorithm/RadixSort.h" -#include "util/CliParser.h" - -const uint32 k = 24; -const uint32 entryCount = 1ull << k; - -Span entriesRef; // Reference entries that we will test again. Generated all at once, then sorted. -Span entriesTest; // Full set of reference entries, but bucket-sorted first. This is to test against reference entries, excluding I/O issues. -Span entriesTmp; -Span entriesBuffer; - -const char* tmpDir = "/home/harold/plot/tmp"; -const FileId fileId = FileId::FX0; -DiskBufferQueue* ioQueue = nullptr; -Fence fence; - -using Job = AnonPrefixSumJob; - -auto seed = HexStringToBytes( "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835" ); - -static void AllocateBuffers( const uint32 blockSize ); -static void InitIOQueue( const uint32 numBuckets ); -static void GenerateRandomEntries( ThreadPool& pool ); - -template -static void RunForBuckets( ThreadPool& pool, const uint32 threadCount ); - -template -static void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ); - - -//----------------------------------------------------------- -TEST_CASE( "bucket-slice-write", "[unit-core]" ) -{ - SysHost::InstallCrashHandler(); - - uint32 maxThreads = SysHost::GetLogicalCPUCount(); - uint32 threadStart = maxThreads; - uint32 threadEnd = maxThreads; - - // Parse environment vars - std::vector args; - { - const char* e; - - if( (e = std::getenv( "bbtest_thread_count" ) ) ) - { - args.push_back( "--thread_count" ); - args.push_back( e ); - } - if( (e = std::getenv( "bbtest_end_thread" ) ) ) - { - args.push_back( "--end_thread" ); - args.push_back( e ); - } - if( std::getenv( "bbtest_all_threads" ) ) - args.push_back( "--all_threads" ); - } - - - if( args.size() > 0 ) - { - CliParser cli( (int)args.size(), args.data() ); - - while( cli.HasArgs() ) - { - if( cli.ReadU32( threadStart, "--thread_count" ) ) continue; - if( cli.ReadU32( threadEnd, "--end_thread" ) ) continue; - if( cli.ArgConsume( "--all_threads" ) ) - { - threadStart = maxThreads; - threadEnd = 1; - } - } - - FatalIf( threadStart == 0, "threadStart == 0" ); - // FatalIf( threadEnd > threadStart, "threadEnd > threadStart: %u > %u", threadEnd , threadStart ); - - if( threadStart > maxThreads ) - threadStart = maxThreads; - if( threadEnd > threadStart ) - threadEnd = threadStart; - } - - ThreadPool pool( maxThreads ); - - for( uint32 i = threadStart; i >= threadEnd; i-- ) - { - Log::Line( "[Threads: %u]", i ); - RunForBuckets<64> ( pool, i ); - RunForBuckets<128>( pool, i ); - RunForBuckets<256>( pool, i ); - RunForBuckets<512>( pool, i ); - } -} - -//----------------------------------------------------------- -void AllocateBuffers( const uint32 numBuckets, const uint32 blockSize ) -{ - const uint32 entriesPerBucket = entryCount / numBuckets; - const uint32 maxEntriesPerSlice = ((uint32)(entriesPerBucket / numBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); - const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries - const uint32 entriesPerBucketAligned = entriesPerSliceAligned * numBuckets; - - if( entriesRef.Ptr() == nullptr ) - { - entriesRef = bbcvirtallocboundednuma_span( entryCount ); - entriesTest = bbcvirtallocboundednuma_span( entryCount ); - entriesTmp = bbcvirtallocboundednuma_span( entryCount ); - } - - if( entriesBuffer.Ptr() ) - { - bbvirtfreebounded( entriesBuffer.Ptr() ); - entriesBuffer = Span(); - } - - entriesBuffer = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); -} - -//----------------------------------------------------------- -template -void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) -{ - Log::Line( " Testing buckets: %u", _numBuckets ); - InitIOQueue( _numBuckets ); - AllocateBuffers( _numBuckets, (uint32)ioQueue->BlockSize( fileId ) ); - GenerateRandomEntries( pool ); - - // Fence* fence = &_fence; - fence.Reset( 0 ); - - uint32 bucketCounts[_numBuckets] = {}; - uint32* pBucketCounts = bucketCounts; - - Job::Run( pool, threadCount, [=, &fence]( Job* self ) { - - const uint32 entriesPerBucket = entryCount / _numBuckets; - const uint32 bucketBits = bblog2( _numBuckets ); - const uint32 bucketShift = k - bucketBits; - const size_t blockSize = ioQueue->BlockSize( fileId ); - - Span srcEntries = entriesRef.Slice(); - Span testEntries = entriesTest.Slice(); - - - uint32 count, offset, end; - GetThreadOffsets( self, entriesPerBucket, count, offset, end ); - - uint32 pfxSum [_numBuckets]; - uint32 offsets [_numBuckets] = {}; - uint32 totalCounts [_numBuckets]; - uint32 alignedWriteCounts[_numBuckets]; - uint32 prevOffsets [_numBuckets] = {}; - - for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) - { - uint32 counts[_numBuckets] = {}; - - // Count entries / bucket - for( uint32 i = offset; i < end; i++ ) - counts[srcEntries[i] >> bucketShift]++; - - - // Prefix sum - memcpy( prevOffsets, offsets, sizeof( offsets ) ); - - self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, totalCounts, offsets, alignedWriteCounts ); - - // Distribute entries to buckets - for( uint32 i = offset; i < end; i++ ) - { - const uint32 e = srcEntries[i]; - const uint32 dst = --pfxSum[e >> bucketShift]; - - entriesBuffer[dst] = e; - } - - // Caluclate non-aligned test values - self->CalculatePrefixSum( _numBuckets, counts, pfxSum, nullptr ); - - // Distribute test entries to buckets - for( uint32 i = offset; i < end; i++ ) - { - const uint32 e = srcEntries[i]; - const uint32 dst = --pfxSum[e >> bucketShift]; - - testEntries[dst] = e; - } - - // Write to disk - if( self->BeginLockBlock() ) - { - ioQueue->WriteBucketElementsT( fileId, entriesBuffer.Ptr(), alignedWriteCounts, totalCounts ); - ioQueue->SignalFence( fence ); - ioQueue->CommitCommands(); - fence.Wait(); - - auto sliceSizes = ioQueue->SliceSizes( fileId ); - for( uint32 i = 0; i < _numBuckets; i++ ) - { - const size_t sliceSize = sliceSizes[bucket][i] / sizeof( uint32 ); - ENSURE( sliceSize == totalCounts[i] ); - } - - // Update total bucket coutns - for( uint32 i = 0; i < _numBuckets; i++ ) - pBucketCounts[i] += totalCounts[i]; - - size_t alignedBucketLength = 0; - size_t bucketLength = 0; - - for( uint32 i = 0; i < _numBuckets; i++ ) - { - bucketLength += totalCounts[i]; - alignedBucketLength += alignedWriteCounts[i]; - } - ENSURE( entriesPerBucket == bucketLength ); - ENSURE( alignedBucketLength >= bucketLength ); - - // Validate entries against test entries - auto test = testEntries.Slice( 0, bucketLength ); - auto target = entriesBuffer.Slice( 0, alignedBucketLength ); - - for( uint32 i = 0; i < _numBuckets; i++ ) - { - auto testSlice = test .Slice( 0, totalCounts[i] ); - auto targetSlice = target.Slice( prevOffsets[i], testSlice.Length() ); - - ENSURE( testSlice.EqualElements( targetSlice ) ); - - test = test.Slice( totalCounts[i] ); - target = target.Slice( alignedWriteCounts[i] ); - } - } - self->EndLockBlock(); - - testEntries = testEntries.Slice( entriesPerBucket ); - - // Write next bucket slices - srcEntries = srcEntries.Slice( entriesPerBucket ); - } - }); - - // Sort the reference entries - RadixSort256::Sort( pool, entriesRef.Ptr(), entriesTmp.Ptr(), entriesRef.Length() ); - - ioQueue->SeekBucket( fileId, 0, SeekOrigin::Begin ); - ioQueue->CommitCommands(); - fence.Reset(); - - // Total I/O queue bucket length must match our bucket length - { - auto sliceSizes = ioQueue->SliceSizes( fileId ); - - for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) - { - size_t bucketLength = 0; - - for( uint32 slice = 0; slice < _numBuckets; slice++ ) - bucketLength += sliceSizes[slice][bucket]; - - ENSURE( bucketLength / sizeof( uint32 ) * sizeof( uint32 ) == bucketLength ); - - bucketLength /= sizeof( uint32 ); - ENSURE( bucketLength == bucketCounts[bucket] ); - } - } - - // Validate against test non-I/O entries first - ValidateTestEntries<_numBuckets>( pool, bucketCounts ); - - // Read back entries and validate them - auto refSlice = entriesRef.Slice(); - - for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) - { - auto readBuffer = entriesBuffer.Slice(); - const size_t capacity = readBuffer.Length(); - - ioQueue->ReadBucketElementsT( fileId, readBuffer ); - ioQueue->SignalFence( fence ); - ioQueue->CommitCommands(); - fence.Wait(); - - ENSURE( readBuffer.Length() <= capacity ); - ENSURE( readBuffer.Length() == bucketCounts[bucket] ); - - RadixSort256::Sort( pool, readBuffer.Ptr(), entriesTmp.Ptr(), readBuffer.Length() ); - - if( !readBuffer.EqualElements( refSlice, readBuffer.Length() ) ) - { - // Find first failure - for( uint32 i = 0; i < readBuffer.Length(); i++ ) - { - ENSURE( readBuffer[i] == refSlice[i] ); - } - } - - refSlice = refSlice.Slice( readBuffer.Length() ); - } - - // Delete the file - // fence.Reset(); - // ioQueue->DeleteBucket( FileId::FX0 ); - // ioQueue->SignalFence( fence ); - // ioQueue->CommitCommands(); - // fence.Wait(); -} - -//----------------------------------------------------------- -template -void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ) -{ - const uint32 bucketBits = bblog2( _numBuckets ); - const uint32 bucketShift = k - bucketBits; - - auto sliceSizes = ioQueue->SliceSizes( fileId ); - - auto refEntries = entriesRef; - - // Test the whole buffer first - { - auto entries = bbcvirtallocboundednuma_span( entryCount ); - entriesTest.CopyTo( entries ); - ENSURE( entries.EqualElements( entriesTest ) ); - - RadixSort256::Sort( pool, entries.Ptr(), entriesTmp.Ptr(), entries.Length() ); - ENSURE( entries.EqualElements( entriesRef ) ); - - bbvirtfreebounded( entries.Ptr() ); - } - - uint32 offsets[_numBuckets] = {}; - - for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) - { - const size_t bucketLength = bucketCounts[bucket]; - size_t ioBucketLength = 0; - - auto testBucket = entriesBuffer.Slice( 0, bucketLength ); - auto writer = testBucket; - auto reader = entriesTest; - - // Read slices from all buckets - for( uint32 slice = 0; slice < _numBuckets; slice++ ) - { - const size_t sliceSize = sliceSizes[slice][bucket] / sizeof( uint32 ); - - auto readSlice = reader.Slice( offsets[slice], sliceSize ); - readSlice.CopyTo( writer ); - - for( uint32 i = 0; i < sliceSize; i++ ) - { - ENSURE( writer[i] >> bucketShift == bucket ); - } - - if( slice + 1 < _numBuckets ) - { - size_t readOffset = 0;; - for( uint32 i = 0; i < _numBuckets; i++ ) - readOffset += sliceSizes[slice][i] / sizeof( uint32 ); - - writer = writer.Slice( sliceSize ); - reader = reader.Slice( readOffset ); - } - - offsets[slice] += sliceSize; - ioBucketLength += sliceSize; - } - - ENSURE( ioBucketLength == bucketLength ); - // if( bucket == 7 ) - // { - // for( uint32 i = 0; i < ioBucketLength; i++ ) - // if( testBucket[i] == 1835013 ) BBDebugBreak(); - // } - - // Sort the bucket - RadixSort256::Sort( pool, testBucket.Ptr(), entriesTmp.Ptr(), testBucket.Length() ); - - // Validate it - auto refBucket = refEntries.Slice( 0, bucketLength ); - ENSURE( testBucket.EqualElements( refBucket ) ); - - refEntries = refEntries.Slice( bucketLength ); - } -} - -//----------------------------------------------------------- -void GenerateRandomEntries( ThreadPool& pool ) -{ - ASSERT( seed.size() == 32 ); - - Job::Run( pool, [=]( Job* self ){ - - const uint32 entriesPerBlock = kF1BlockSize / sizeof( uint32 ); - const uint32 blockCount = entryCount / entriesPerBlock; - ASSERT( blockCount * entriesPerBlock == entryCount ); - - uint32 count, offset, end; - GetThreadOffsets( self, blockCount, count, offset, end ); - - byte key[32] = { 1 }; - memcpy( key+1, seed.data()+1, 31 ); - - chacha8_ctx chacha; - chacha8_keysetup( &chacha, key, 256, nullptr ); - chacha8_get_keystream( &chacha, offset, count, (byte*)entriesRef.Ptr() + offset * kF1BlockSize ); - - const uint32 mask = ( 1u << k ) - 1; - offset *= entriesPerBlock; - end *= entriesPerBlock; - for( uint32 i = offset; i < end; i++ ) - entriesRef[i] &= mask; - }); -} - - -//----------------------------------------------------------- -void InitIOQueue( const uint32 numBuckets ) -{ - // #NOTE: We let it leak after, as we still don't properly terminate - // #TODO: Delete the I/O queue after fixing its termination - - const FileSetOptions flags = FileSetOptions::DirectIO | FileSetOptions::Cachable | FileSetOptions::Interleaved; - FileSetInitData opts; - opts.cacheSize = (size_t)( sizeof( uint32 ) * entryCount * 1.25); - opts.cache = bbvirtallocboundednuma( opts.cacheSize ); - - char* nameBuf = new char[64]; - sprintf( nameBuf, "test-slices-%u", numBuckets ); - - byte dummyHeap = 1; - ioQueue = new DiskBufferQueue( tmpDir, tmpDir, tmpDir, &dummyHeap, dummyHeap, 1 ); - ioQueue->InitFileSet( fileId, nameBuf, numBuckets, flags, &opts ); -} - +//#include "TestUtil.h" +//#include "io/BucketStream.h" +//#include "io/HybridStream.h" +//#include "util/Util.h" +//#include "threading/MTJob.h" +//#include "pos/chacha8.h" +//#include "ChiaConsts.h" +//#include "plotdisk/DiskBufferQueue.h" +//#include "algorithm/RadixSort.h" +//#include "util/CliParser.h" +// +//const uint32 k = 24; +//const uint32 entryCount = 1ull << k; +// +//Span entriesRef; // Reference entries that we will test again. Generated all at once, then sorted. +//Span entriesTest; // Full set of reference entries, but bucket-sorted first. This is to test against reference entries, excluding I/O issues. +//Span entriesTmp; +//Span entriesBuffer; +// +//const char* tmpDir = "/home/harold/plot/tmp"; +//const FileId fileId = FileId::FX0; +//DiskBufferQueue* ioQueue = nullptr; +//Fence fence; +// +//using Job = AnonPrefixSumJob; +// +//auto seed = HexStringToBytes( "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835" ); +// +//static void AllocateBuffers( const uint32 blockSize ); +//static void InitIOQueue( const uint32 numBuckets ); +//static void GenerateRandomEntries( ThreadPool& pool ); +// +//template +//static void RunForBuckets( ThreadPool& pool, const uint32 threadCount ); +// +//template +//static void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ); +// +// +////----------------------------------------------------------- +//TEST_CASE( "bucket-slice-write", "[unit-core]" ) +//{ +// SysHost::InstallCrashHandler(); +// +// uint32 maxThreads = SysHost::GetLogicalCPUCount(); +// uint32 threadStart = maxThreads; +// uint32 threadEnd = maxThreads; +// +// // Parse environment vars +// std::vector args; +// { +// const char* e; +// +// if( (e = std::getenv( "bbtest_thread_count" ) ) ) +// { +// args.push_back( "--thread_count" ); +// args.push_back( e ); +// } +// if( (e = std::getenv( "bbtest_end_thread" ) ) ) +// { +// args.push_back( "--end_thread" ); +// args.push_back( e ); +// } +// if( std::getenv( "bbtest_all_threads" ) ) +// args.push_back( "--all_threads" ); +// } +// +// +// if( args.size() > 0 ) +// { +// CliParser cli( (int)args.size(), args.data() ); +// +// while( cli.HasArgs() ) +// { +// if( cli.ReadU32( threadStart, "--thread_count" ) ) continue; +// if( cli.ReadU32( threadEnd, "--end_thread" ) ) continue; +// if( cli.ArgConsume( "--all_threads" ) ) +// { +// threadStart = maxThreads; +// threadEnd = 1; +// } +// } +// +// FatalIf( threadStart == 0, "threadStart == 0" ); +// // FatalIf( threadEnd > threadStart, "threadEnd > threadStart: %u > %u", threadEnd , threadStart ); +// +// if( threadStart > maxThreads ) +// threadStart = maxThreads; +// if( threadEnd > threadStart ) +// threadEnd = threadStart; +// } +// +// ThreadPool pool( maxThreads ); +// +// for( uint32 i = threadStart; i >= threadEnd; i-- ) +// { +// Log::Line( "[Threads: %u]", i ); +// RunForBuckets<64> ( pool, i ); +// RunForBuckets<128>( pool, i ); +// RunForBuckets<256>( pool, i ); +// RunForBuckets<512>( pool, i ); +// } +//} +// +////----------------------------------------------------------- +//void AllocateBuffers( const uint32 numBuckets, const uint32 blockSize ) +//{ +// const uint32 entriesPerBucket = entryCount / numBuckets; +// const uint32 maxEntriesPerSlice = (uint32)((entriesPerBucket / numBuckets) * BB_DP_ENTRY_SLICE_MULTIPLIER); +// const uint32 entriesPerSliceAligned = RoundUpToNextBoundaryT( maxEntriesPerSlice, blockSize ) + blockSize / sizeof( uint32 ); // Need an extra block for when we offset the entries +// const uint32 entriesPerBucketAligned = entriesPerSliceAligned * numBuckets; +// +// if( entriesRef.Ptr() == nullptr ) +// { +// entriesRef = bbcvirtallocboundednuma_span( entryCount ); +// entriesTest = bbcvirtallocboundednuma_span( entryCount ); +// entriesTmp = bbcvirtallocboundednuma_span( entryCount ); +// } +// +// if( entriesBuffer.Ptr() ) +// { +// bbvirtfreebounded( entriesBuffer.Ptr() ); +// entriesBuffer = Span(); +// } +// +// entriesBuffer = bbcvirtallocboundednuma_span( (size_t)( entriesPerBucketAligned ) ); +//} +// +////----------------------------------------------------------- +//template +//void RunForBuckets( ThreadPool& pool, const uint32 threadCount ) +//{ +// Log::Line( " Testing buckets: %u", _numBuckets ); +// InitIOQueue( _numBuckets ); +// AllocateBuffers( _numBuckets, (uint32)ioQueue->BlockSize( fileId ) ); +// GenerateRandomEntries( pool ); +// +// // Fence* fence = &_fence; +// fence.Reset( 0 ); +// +// uint32 bucketCounts[_numBuckets] = {}; +// uint32* pBucketCounts = bucketCounts; +// +// Job::Run( pool, threadCount, [=, &fence]( Job* self ) { +// +// const uint32 entriesPerBucket = entryCount / _numBuckets; +// const uint32 bucketBits = bblog2( _numBuckets ); +// const uint32 bucketShift = k - bucketBits; +// const size_t blockSize = ioQueue->BlockSize( fileId ); +// +// Span srcEntries = entriesRef.Slice(); +// Span testEntries = entriesTest.Slice(); +// +// +// uint32 count, offset, end; +// GetThreadOffsets( self, entriesPerBucket, count, offset, end ); +// +// uint32 pfxSum [_numBuckets]; +// uint32 offsets [_numBuckets] = {}; +// uint32 totalCounts [_numBuckets]; +// uint32 alignedWriteCounts[_numBuckets]; +// uint32 prevOffsets [_numBuckets] = {}; +// +// for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) +// { +// uint32 counts[_numBuckets] = {}; +// +// // Count entries / bucket +// for( uint32 i = offset; i < end; i++ ) +// counts[srcEntries[i] >> bucketShift]++; +// +// +// // Prefix sum +// memcpy( prevOffsets, offsets, sizeof( offsets ) ); +// +// self->CalculateBlockAlignedPrefixSum( _numBuckets, blockSize, counts, pfxSum, totalCounts, offsets, alignedWriteCounts ); +// +// // Distribute entries to buckets +// for( uint32 i = offset; i < end; i++ ) +// { +// const uint32 e = srcEntries[i]; +// const uint32 dst = --pfxSum[e >> bucketShift]; +// +// entriesBuffer[dst] = e; +// } +// +// // Caluclate non-aligned test values +// self->CalculatePrefixSum( _numBuckets, counts, pfxSum, nullptr ); +// +// // Distribute test entries to buckets +// for( uint32 i = offset; i < end; i++ ) +// { +// const uint32 e = srcEntries[i]; +// const uint32 dst = --pfxSum[e >> bucketShift]; +// +// testEntries[dst] = e; +// } +// +// // Write to disk +// if( self->BeginLockBlock() ) +// { +// ioQueue->WriteBucketElementsT( fileId, entriesBuffer.Ptr(), alignedWriteCounts, totalCounts ); +// ioQueue->SignalFence( fence ); +// ioQueue->CommitCommands(); +// fence.Wait(); +// +// auto sliceSizes = ioQueue->SliceSizes( fileId ); +// for( uint32 i = 0; i < _numBuckets; i++ ) +// { +// const size_t sliceSize = sliceSizes[bucket][i] / sizeof( uint32 ); +// ENSURE( sliceSize == totalCounts[i] ); +// } +// +// // Update total bucket coutns +// for( uint32 i = 0; i < _numBuckets; i++ ) +// pBucketCounts[i] += totalCounts[i]; +// +// size_t alignedBucketLength = 0; +// size_t bucketLength = 0; +// +// for( uint32 i = 0; i < _numBuckets; i++ ) +// { +// bucketLength += totalCounts[i]; +// alignedBucketLength += alignedWriteCounts[i]; +// } +// ENSURE( entriesPerBucket == bucketLength ); +// ENSURE( alignedBucketLength >= bucketLength ); +// +// // Validate entries against test entries +// auto test = testEntries.Slice( 0, bucketLength ); +// auto target = entriesBuffer.Slice( 0, alignedBucketLength ); +// +// for( uint32 i = 0; i < _numBuckets; i++ ) +// { +// auto testSlice = test .Slice( 0, totalCounts[i] ); +// auto targetSlice = target.Slice( prevOffsets[i], testSlice.Length() ); +// +// ENSURE( testSlice.EqualElements( targetSlice ) ); +// +// test = test.Slice( totalCounts[i] ); +// target = target.Slice( alignedWriteCounts[i] ); +// } +// } +// self->EndLockBlock(); +// +// testEntries = testEntries.Slice( entriesPerBucket ); +// +// // Write next bucket slices +// srcEntries = srcEntries.Slice( entriesPerBucket ); +// } +// }); +// +// // Sort the reference entries +// RadixSort256::Sort( pool, entriesRef.Ptr(), entriesTmp.Ptr(), entriesRef.Length() ); +// +// ioQueue->SeekBucket( fileId, 0, SeekOrigin::Begin ); +// ioQueue->CommitCommands(); +// fence.Reset(); +// +// // Total I/O queue bucket length must match our bucket length +// { +// auto sliceSizes = ioQueue->SliceSizes( fileId ); +// +// for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) +// { +// size_t bucketLength = 0; +// +// for( uint32 slice = 0; slice < _numBuckets; slice++ ) +// bucketLength += sliceSizes[slice][bucket]; +// +// ENSURE( bucketLength / sizeof( uint32 ) * sizeof( uint32 ) == bucketLength ); +// +// bucketLength /= sizeof( uint32 ); +// ENSURE( bucketLength == bucketCounts[bucket] ); +// } +// } +// +// // Validate against test non-I/O entries first +// ValidateTestEntries<_numBuckets>( pool, bucketCounts ); +// +// // Read back entries and validate them +// auto refSlice = entriesRef.Slice(); +// +// for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) +// { +// auto readBuffer = entriesBuffer.Slice(); +// const size_t capacity = readBuffer.Length(); +// +// ioQueue->ReadBucketElementsT( fileId, readBuffer ); +// ioQueue->SignalFence( fence ); +// ioQueue->CommitCommands(); +// fence.Wait(); +// +// ENSURE( readBuffer.Length() <= capacity ); +// ENSURE( readBuffer.Length() == bucketCounts[bucket] ); +// +// RadixSort256::Sort( pool, readBuffer.Ptr(), entriesTmp.Ptr(), readBuffer.Length() ); +// +// if( !readBuffer.EqualElements( refSlice, readBuffer.Length() ) ) +// { +// // Find first failure +// for( uint32 i = 0; i < readBuffer.Length(); i++ ) +// { +// ENSURE( readBuffer[i] == refSlice[i] ); +// } +// } +// +// refSlice = refSlice.Slice( readBuffer.Length() ); +// } +// +// // Delete the file +// // fence.Reset(); +// // ioQueue->DeleteBucket( FileId::FX0 ); +// // ioQueue->SignalFence( fence ); +// // ioQueue->CommitCommands(); +// // fence.Wait(); +//} +// +////----------------------------------------------------------- +//template +//void ValidateTestEntries( ThreadPool& pool, uint32 bucketCounts[_numBuckets] ) +//{ +// const uint32 bucketBits = bblog2( _numBuckets ); +// const uint32 bucketShift = k - bucketBits; +// +// auto sliceSizes = ioQueue->SliceSizes( fileId ); +// +// auto refEntries = entriesRef; +// +// // Test the whole buffer first +// { +// auto entries = bbcvirtallocboundednuma_span( entryCount ); +// entriesTest.CopyTo( entries ); +// ENSURE( entries.EqualElements( entriesTest ) ); +// +// RadixSort256::Sort( pool, entries.Ptr(), entriesTmp.Ptr(), entries.Length() ); +// ENSURE( entries.EqualElements( entriesRef ) ); +// +// bbvirtfreebounded( entries.Ptr() ); +// } +// +// uint32 offsets[_numBuckets] = {}; +// +// for( uint32 bucket = 0; bucket < _numBuckets; bucket++ ) +// { +// const size_t bucketLength = bucketCounts[bucket]; +// size_t ioBucketLength = 0; +// +// auto testBucket = entriesBuffer.Slice( 0, bucketLength ); +// auto writer = testBucket; +// auto reader = entriesTest; +// +// // Read slices from all buckets +// for( uint32 slice = 0; slice < _numBuckets; slice++ ) +// { +// const size_t sliceSize = sliceSizes[slice][bucket] / sizeof( uint32 ); +// +// auto readSlice = reader.Slice( offsets[slice], sliceSize ); +// readSlice.CopyTo( writer ); +// +// for( uint32 i = 0; i < sliceSize; i++ ) +// { +// ENSURE( writer[i] >> bucketShift == bucket ); +// } +// +// if( slice + 1 < _numBuckets ) +// { +// size_t readOffset = 0;; +// for( uint32 i = 0; i < _numBuckets; i++ ) +// readOffset += sliceSizes[slice][i] / sizeof( uint32 ); +// +// writer = writer.Slice( sliceSize ); +// reader = reader.Slice( readOffset ); +// } +// +// offsets[slice] += sliceSize; +// ioBucketLength += sliceSize; +// } +// +// ENSURE( ioBucketLength == bucketLength ); +// // if( bucket == 7 ) +// // { +// // for( uint32 i = 0; i < ioBucketLength; i++ ) +// // if( testBucket[i] == 1835013 ) BBDebugBreak(); +// // } +// +// // Sort the bucket +// RadixSort256::Sort( pool, testBucket.Ptr(), entriesTmp.Ptr(), testBucket.Length() ); +// +// // Validate it +// auto refBucket = refEntries.Slice( 0, bucketLength ); +// ENSURE( testBucket.EqualElements( refBucket ) ); +// +// refEntries = refEntries.Slice( bucketLength ); +// } +//} +// +////----------------------------------------------------------- +//void GenerateRandomEntries( ThreadPool& pool ) +//{ +// ASSERT( seed.size() == 32 ); +// +// Job::Run( pool, [=]( Job* self ){ +// +// const uint32 entriesPerBlock = kF1BlockSize / sizeof( uint32 ); +// const uint32 blockCount = entryCount / entriesPerBlock; +// ASSERT( blockCount * entriesPerBlock == entryCount ); +// +// uint32 count, offset, end; +// GetThreadOffsets( self, blockCount, count, offset, end ); +// +// byte key[32] = { 1 }; +// memcpy( key+1, seed.data()+1, 31 ); +// +// chacha8_ctx chacha; +// chacha8_keysetup( &chacha, key, 256, nullptr ); +// chacha8_get_keystream( &chacha, offset, count, (byte*)entriesRef.Ptr() + offset * kF1BlockSize ); +// +// const uint32 mask = ( 1u << k ) - 1; +// offset *= entriesPerBlock; +// end *= entriesPerBlock; +// for( uint32 i = offset; i < end; i++ ) +// entriesRef[i] &= mask; +// }); +//} +// +// +////----------------------------------------------------------- +//void InitIOQueue( const uint32 numBuckets ) +//{ +// // #NOTE: We let it leak after, as we still don't properly terminate +// // #TODO: Delete the I/O queue after fixing its termination +// +// const FileSetOptions flags = FileSetOptions::DirectIO | FileSetOptions::Cachable | FileSetOptions::Interleaved; +// FileSetInitData opts; +// opts.cacheSize = (size_t)( sizeof( uint32 ) * entryCount * 1.25); +// opts.cache = bbvirtallocboundednuma( opts.cacheSize ); +// +// char* nameBuf = new char[64]; +// sprintf( nameBuf, "test-slices-%u", numBuckets ); +// +// byte dummyHeap = 1; +// ioQueue = new DiskBufferQueue( tmpDir, tmpDir, tmpDir, &dummyHeap, dummyHeap, 1 ); +// ioQueue->InitFileSet( fileId, nameBuf, numBuckets, flags, &opts ); +//} +// diff --git a/tests/TestUtil.h b/tests/TestUtil.h index 2b92a6f5..6c3679eb 100644 --- a/tests/TestUtil.h +++ b/tests/TestUtil.h @@ -42,4 +42,4 @@ T* LoadReferenceTable( const char* path, uint64& outEntryCount ) outEntryCount = entryCount; return entries; -} \ No newline at end of file +} diff --git a/tests/TestXchAddressData.h b/tests/TestXchAddressData.h new file mode 100644 index 00000000..a0efad91 --- /dev/null +++ b/tests/TestXchAddressData.h @@ -0,0 +1,1010 @@ +#pragma once + +struct AddrHashTestPair { const char* hash; const char* address; }; + +const AddrHashTestPair TestMainnetAddress[500] = { + { "8a0e1ed4c0872349f48c74d4ba4d08f3f4420e8f0984d5f7c51f8e6925a624b8", "xch13g8pa4xqsu35nayvwn2t5ngg706yyr50pxzdta79r78xjfdxyjuq9esszx" }, + { "7014f9516b1e944db6559743b8c666f5bf1ad42a6aa6ee8abd3d0d6c85f7f965", "xch1wq20j5ttr62ymdj4japm33nx7kl344p2d2nwaz4a85xkep0hl9js42uksa" }, + { "41b875f70355be93a150b88e436e14f8ccf799ca3baa41587b1e19d47ba5f699", "xch1gxu8tacr2klf8g2shz8yxms5lrx00xw28w4yzkrmrcvag7a976vs7mqrm8" }, + { "d88983f5b59bfaeb8ec8bae5c285fd1cbca0566e3665a8d979646166711104d7", "xch1mzyc8ad4n0awhrkghtju9p0arj72q4nwxej63ktev3skvug3qnts9mhnfe" }, + { "8cbfc07b48217424f4eac1474392aa81dc046d489ba7b32b3b1ffbbf45251c4d", "xch13jluq76gy96zfa82c9r58y42s8wqgm2gnwnmx2emrlam73f9r3xs82w6e7" }, + { "5ca6b5cd1e1f2c4a9ad8e8d104e08f7154d0b5f39f91823dd4d74a8480e47bad", "xch1tjnttng7ruky4xkcargsfcy0w92dpd0nn7gcy0w56a9gfq8y0wks25864g" }, + { "b5d1a4b0f545b9b053bdcfea08951501a91282313f3687ed8bff712cb00480be", "xch1khg6fv84gkumq5aael4q39g4qx539q338umg0mvtlacjevqyszlqmsutu6" }, + { "fc5133617536a584b8aaaff201291457c1da9e52be934ae4365efe5834c6a338", "xch1l3gnxct4x6jcfw924leqz2g52lqa48jjh6f54epktml9sdxx5vuqkxsnws" }, + { "41692904663fe839d165e86bce5aa695bee9b8f79b1bd8ad6a25b387394da104", "xch1g95jjprx8l5rn5t9ap4uuk4xjklwnw8hnvda3tt2ykecww2d5yzqeqa7n6" }, + { "0424ef1cc2b3b085cbd3b5753b8071c0bd8eee580036625ac8988e26411fc092", "xch1qsjw78xzkwcgtj7nk46nhqr3cz7camjcqqmxykkgnz8zvsglczfq5kzcye" }, + { "2cbb91689e70def71ded912fc3a48452fe50126378b82781debd33a0d82de708", "xch19jaez6y7wr00w80djyhu8fyy2tl9qynr0zuz0qw7h5e6pkpduuyq3m95yv" }, + { "873a8948453f2b446d22bc4a1ef857febd65a43d996641c77d3f607fc97f4732", "xch1suagjjz98u45gmfzh39pa7zhl67ktfpan9nyr3ma8as8ljtlgueq2gx6lv" }, + { "66055e453f8db1c1526b89c040121499a4567971dc1068bb45526cec5f4626d7", "xch1vcz4u3fl3kcuz5nt38qyqys5nxj9v7t3msgx3w692fkwch6xymtsspaa57" }, + { "7ae1b430fe6c7f9b872ae48215d711ec5a98c053322857e62db1940650df83b9", "xch10tsmgv87d3lehpe2ujppt4c3a3df3sznxg590e3dkx2qv5xlswustja7ly" }, + { "66cfa298f452e19c2a550e994c3bd0bd0fdaff93a02afbca779c5c5c870f00f9", "xch1vm869x852tsec2j4p6v5cw7sh58a4lun5q40hjnhn3w9epc0qrusgu6vqv" }, + { "78adc08ad4d0a1ec7b55c74f83646d412a2baff5be6f4de828c2de4766027e41", "xch10zkupzk56zs7c764ca8cxerdgy4zhtl4heh5m6pgct0ywesz0eqsetvjjh" }, + { "d189d61fe52e555a8d27eb740b32cb141bc8509a34fdcd7a4d950e4ead1e1193", "xch16xyav8l99e244rf8ad6qkvktzsdus5y6xn7u67jdj58yatg7zxfsax4wml" }, + { "6eb41f9040454b496a9f852f7dd992d101dc81a593ef3bcb0af3159a2924efd7", "xch1d66plyzqg495j65ls5hhmkvj6yqaeqd9j0hnhjc27v2e52fyaltsvzl5af" }, + { "adf30875d9a5390eb215babcb135ca3d867b837d0c98105a7d755d6b4690cf52", "xch14hessawe55usavs4h27tzdw28kr8hqmapjvpqknaw4wkk35seafq2xtp8y" }, + { "d0f27ba25fc985041058593ab5a8b055dc15f2b516e093ac9def5c5a0db376df", "xch16re8hgjlexzsgyzctyatt29s2hwptu44zmsf8tyaaaw95rdnwm0shsnh9p" }, + { "dc3966398b4a81138d6c6d0ff01fd361ad10668b72690f0f76e13dd7531cef5e", "xch1msukvwvtf2q38rtvd58lq87nvxk3qe5twf5s7rmkuy7aw5cuaa0q6cn2fk" }, + { "5ad93fc8fb489b9b24d15a5a481d5afb9e8072056d5b4c4427215ba73a259a0c", "xch1ttvnlj8mfzdekfx3tfdys826lw0gqus9d4d5c3p8y9d6ww39ngxqkf026c" }, + { "1b168721a4309295a56802b05556dadad3f996ae28284740ac8030e47b5f3d0a", "xch1rvtgwgdyxzfftftgq2c924k6mtfln94w9q5yws9vsqcwg76l859qfja48t" }, + { "16dccbbd664357a2cc1a65f0b921180a52adb373b5dec739fbf1a879c8a86a5c", "xch1zmwvh0txgdt69nq6vhctjggcpff2mvmnkh0vww0m7x58nj9gdfwqptx2jd" }, + { "86ef65e2f035e48b133feb637428d1b2cf71cf7cf311e367d23a576fc0f02047", "xch1smhktchsxhjgkyelad3hg2x3kt8hrnmu7vg7xe7j8ftkls8syprsy5wql6" }, + { "78fd057869f7085ae01859fe3dc53e86d643333f7bf52eef9a670bd8e6e83194", "xch10r7s27rf7uy94cqct8lrm3f7smtyxvel006jamu6vu9a3ehgxx2qxecqj6" }, + { "14a725a2a6ec2399768934dfb04fe2d38751ba54dad4e738d5f9d63e3f181cb6", "xch1zjnjtg4xas3eja5fxn0mqnlz6wr4rwj5mt2wwwx4l8tru0ccrjmqeu6nf5" }, + { "37425e8bfa9469fee2b7c60dff8410d43cf948235deb07df12ee2cafc230c5c5", "xch1xap9azl6j35lac4hccxllpqs6s70jjprth4s0hcjack2ls3schzsenfwnv" }, + { "7bfbe0734c7e6dff81fecd7b7f11821545065efe895598525780bb802e810488", "xch100a7qu6v0ekllq07e4ah7yvzz4zsvhh7392es5jhszacqt5pqjyqfalzwk" }, + { "5339a0f50bd40b426800804b2e21157130487652af50e9b46979da9b83168f23", "xch12vu6pagt6s95y6qqsp9jugg4wycysajj4agwndrf08dfhqck3u3sx3zxwf" }, + { "7bfe58e78fdf490acb5d5086d7cb49ffd4ab13b40138a01f4c8d38c6b0e3f9e1", "xch100l93eu0mays4j6a2zrd0j6fll22kya5qyu2q86v35uvdv8rl8ssjputfd" }, + { "a4fc23947b551b42f91c37b997d6553687753ad3734fefc12ccc162b949c60bd", "xch15n7z89rm25d597gux7ue04j4x6rh2wknwd87lsfvestzh9yuvz7spuz8nz" }, + { "3fc0ec2462970a2a5391879a5e4c5e27a1ff39f95a73d5e5f51aa11b9ca268f1", "xch18lqwcfrzju9z55u3s7d9unz7y7sl7w0etfeate04r2s3h89zdrcsya6x4e" }, + { "7bde8d40369a659b524e5a3f072b8034b3851bb54865862a115e08c84ed35cc3", "xch1000g6spknfjek5jwtglsw2uqxjec2xa4fpjcv2s3tcyvsnkntnps0y4lsg" }, + { "766c51b3c03dad84fefdec6a75c94e698e51e477c03878aca66bc4f88bd3d74a", "xch1wek9rv7q8kkcflhaa348tj2wdx89rerhcqu83t9xd0z03z7n6a9q7tt5w2" }, + { "1525bec539cf495d81c296bba4ad53271f72ddc4b419ba9ae3fdc5135bb519db", "xch1z5jma3feeay4mqwzj6a6ft2nyu0h9hwyksvm4xhrlhz3xka4r8dsgvn8nq" }, + { "f6455db36e0756473e22b527dc5bc0fb286cf0fe01c30548848b762df6fcf0db", "xch17ez4mvmwqatyw03zk5nack7qlv5xeu87q8ps2jyy3dmzmahu7rds9td8n7" }, + { "4b91f9fe925ea15e47e800da0074ff4c2be5b6cbd0c31763d6b20515a0eb7380", "xch1fwglnl5jt6s4u3lgqrdqqa8lfs47tdkt6rp3wc7kkgz3tg8twwqqua4dnd" }, + { "d846a588186a596dc19656e1045b91b4eb0cd078aba5ac75da92c8d404eef814", "xch1mpr2tzqcdfvkmsvk2mssgku3kn4se5rc4wj6caw6jtydgp8wlq2qsnnnxj" }, + { "d82e68c7386d9eac27e36edbd70d94847577f6a4e874d2e497511da8b1847a6e", "xch1mqhx33ecdk02cflrdmdawrv5s36h0a4yap6d9eyh2yw63vvy0fhqfsmw3c" }, + { "90505d961a0e9c5669ab5dca244c0e37dcea462dc4e69b85177c2e47dd2ddc7b", "xch1jpg9m9s6p6w9v6dtth9zgnqwxlww533dcnnfhpgh0shy0hfdm3astfr7dt" }, + { "7322d37141efeea14ec2df3aa9021914380c7e1d507ee05af20a59c1c1fec98f", "xch1wv3dxu2palh2znkzmua2jqsezsuqclsa2plwqkhjpfvurs07ex8stxv0xn" }, + { "e28fbd9cd38fcfd6300dc5834113d836331de09202c8bd7899f3a10ef2307f7d", "xch1u28mm8xn3l8avvqdckp5zy7cxce3mcyjqtyt67ye7wssau3s0a7s4sslae" }, + { "e2ee8bea518b7a75929b938b97967be34b750ad3b6fd6f155e1b387aba6383c2", "xch1uthgh6j33da8ty5mjw9e09nmud9h2zknkm7k7927rvu84wnrs0pqp5qv8p" }, + { "515d94b6f7c54f301c453a4ca62fb0aaaa99cec2986991c096cf093cc0fbc6f5", "xch129wefdhhc48nq8z98fx2vtas424fnnkznp5ersykeuynes8mcm6serhjxc" }, + { "90de55da8f335ec60522823f85d03b613695b00c27e5feec5822910b7be4bd64", "xch1jr09tk50xd0vvpfzsglct5pmvymftvqvyljlamzcy2gsk7lyh4jqm2jwnq" }, + { "b675335015a7e489e2a37efd2bab075042fd737a44716053f0c5b59bbbe50312", "xch1ke6nx5q45ljgnc4r0m7jh2c82pp06um6g3ckq5lsck6ehwl9qvfq8t3t5s" }, + { "e3d15b0d2ef52de584e472c5f60ce15699143ad2f1c23a15d0515474c1223214", "xch1u0g4krfw75k7tp8ywtzlvr8p26v3gwkj78pr59ws2928fsfzxg2q0fuyxp" }, + { "3f836fa7668348af94cbdadde7c3a67fc85d3188a79a68d2a08ed57561f93ae0", "xch187pklfmxsdy2l9xtmtw70sax0ly96vvg57dx354q3m2h2c0e8tsqesepfr" }, + { "5a83113740bddb5017f666305b2f3ef9074a90e04f5940d094bf6506a970f6bb", "xch1t2p3zd6qhhd4q9lkvcc9kte7lyr54y8qfav5p5y5hajsd2ts76assgvhlw" }, + { "660acce1f0046d92118cc6d5b012d89a8c36bc2d49d18a58761b52a944168d5a", "xch1vc9vec0sq3keyyvvcm2mqykcn2xrd0pdf8gc5krkrdf2j3qk34dqwarhg6" }, + { "81bc5408d7ee34461fae5677b1d0345403a193c8f0699c918ffbb1a60a53e325", "xch1sx79gzxhac6yv8aw2emmr5p52sp6ry7g7p5eeyv0lwc6vzjnuvjsfrwt6q" }, + { "bbc05fd626a6d215d54a1bc7f4387c21687ac906adf8d2be9b6c5df9a34a2a25", "xch1h0q9l43x5mfpt422r0rlgwruy9584jgx4hud905md3wlng629gjs22k3yk" }, + { "fc2f269cade613e26af714e8649cf932fa04be9cdd0033078e69fd98139bae83", "xch1lshjd89ducf7y6hhzn5xf88extaqf05um5qrxpuwd87esyum46pss07gt8" }, + { "8d2ae00ff8df50ab5ca74561c0e28597650c98b24b8aede0d5256a5635a72656", "xch1354wqrlcmag2kh98g4supc59jajsex9jfw9wmcx4y449vdd8yetqp4sv6f" }, + { "9219072419f74543435c761cb5e482a62ed25c7bfcef874d3c6d39bb7b3943f8", "xch1jgvswfqe7az5xs6uwcwtteyz5chdyhrmlnhcwnfud5umk7eeg0uqza0s5l" }, + { "f2e4eefc14e563c3409742635eb8cfcdcb11006b7b0a8e4a71a5f5150ece65e9", "xch17tjwalq5u43uxsyhgf34awx0eh93zqrt0v9gujn35h632rkwvh5sjn4ym0" }, + { "73571a1ecbe43dcf942bd6a2135dd4719570f33c578ce7e4d9dc10e67c4d5318", "xch1wdt358ktus7ul9pt663pxhw5wx2hpueu27xw0exemsgwvlzd2vvqzpulpn" }, + { "48df40ed8ebdee50eb17cf336bfbda02b259b58d04c4f6d9663d00ee37ddc8d4", "xch1fr05pmvwhhh9p6cheuekh776q2e9ndvdqnz0dktx85qwud7aer2q228ftg" }, + { "87bd96c8e96586fac49e6a62e4b92e8bfc01aa7f474be7ae0cc2eb1e8fe82fe4", "xch1s77edj8fvkr043y7df3wfwfw307qr2nlga970tsvct43arlg9ljq7d6r4u" }, + { "984ceafca4d01a86804251113ba6e6d4e0b6c3ed40c163ed7e54c9e35c429de7", "xch1npxw4l9y6qdgdqzz2ygnhfhx6nstdsldgrqk8mt72ny7xhzznhnsahx5x0" }, + { "cb869c56662dcc6f6947716a7352198c6474d4ca85ee2d15f05923e44f99be51", "xch1ewrfc4nx9hxx7628w948x5se33j8f4x2shhz690sty37gnuehegsca4xdv" }, + { "bfc15d0d20e24baffb853343bd4a9109b82a75e7009ade1e127ea0d3d7bc007f", "xch1hlq46rfquf96l7u9xdpm6j53pxuz5a08qzddu8sj06sd84auqplsu2lxhf" }, + { "b7e76ec9898b3e02c91a61a304a42f7239b96fd440e28f794b1fdb03f4fa6411", "xch1klnkajvf3vlq9jg6vx3sffp0wgumjm75gr3g772trlds8a86vsgs20ye24" }, + { "760d1f28a5477b53db71648ab24e751030d772ecf98c0665ce8ccaf749601eca", "xch1wcx37299gaa48km3vj9tynn4zqcdwuhvlxxqveww3n90wjtqrm9q0n7295" }, + { "e0924aff74f674506460d504e2e122d9229f2c363d009a7ce8f6a773da577713", "xch1uzfy4lm57e69qerq65zw9cfzmy3f7tpk85qf5l8g76nh8kjhwufsadkeue" }, + { "98bc8ad9e345b070b2bd8cdbaaa5c90d7dda5aca0a998a0f4a0c4ca0151bd2bb", "xch1nz7g4k0rgkc8pv4a3nd64fwfp47a5kk2p2vc5r62p3x2q9gm62as9n5eaw" }, + { "17c082d2495cb7d05f2e8cdb70ca4eab9e2270f47cb10897b11512e1defe1adc", "xch1zlqg95jftjmaqhew3ndhpjjw4w0zyu850jcs39a3z5fwrhh7rtwqqqvcxu" }, + { "392c5387e1b0b23e71b2646788bcdc87b72f4569de01a4b19a7dc23cb3c7fff1", "xch18yk98plpkzeruudjv3nc30xus7mj73tfmcq6fvv60hprev78llcs37wxwf" }, + { "f00357f7b07056254ba19f1c1b376c936acb821d12be5678b4a37d3006aaface", "xch17qp40aaswptz2japnuwpkdmvjd4vhqsaz2l9v7955d7nqp42lt8qlq06tz" }, + { "6f29a1ee6a6cd55f1702a54f1178ae84adb4ad32cf6456bc0c75b2eacb456614", "xch1du56rmn2dn2479cz5483z79wsjkmftfjeaj9d0qvwkew4j69vc2q7tdlp0" }, + { "724468c273fb8a7066e9b52bc8ae086d6d8fc0194945250b9a56787edaf07f02", "xch1wfzx3snnlw98qehfk54u3tsgd4kclsqef9zj2zu62eu8akhs0upqgjlx6q" }, + { "e7b5e7c9a5cee794d723a19e60bdeb5960ce513076b5e06e7be0ed594530670f", "xch1u7670jd9emnef4er5x0xp00tt9svu5fsw667qmnmurk4j3fsvu8sllne2f" }, + { "f655b9433234a0c3f5f9283815eaec4de8f6df656b1523c3472904ec4a18a148", "xch17e2mjsejxjsv8a0e9qupt6hvfh50dhm9dv2j8s689yzwcjsc59yqch6nfz" }, + { "86390ac94d346c153545f286b170a878eb9853816193912f714b8d3d15817567", "xch1scus4j2dx3kp2d2972rtzu9g0r4es5upvxfeztm3fwxn69vpw4ns623gz3" }, + { "d2915b8b22bf2ec7344525ea357d5102a5b8b34861d2c93594c0dd1603e81d77", "xch162g4hzezhuhvwdz9yh4r2l23q2jm3v6gv8fvjdv5crw3vqlgr4msx99rm9" }, + { "fdbc97105170ef625ab108e6dc382277adb2327e1231b82c38fa308b1ef80e8b", "xch1lk7fwyz3wrhkyk43prndcwpzw7kmyvn7zgcmstpclgcgk8hcp69sw0guh9" }, + { "5023a71217faf946d49efba9f7a8461bb8ab40662a479ee18657dd8c1fd1ee31", "xch12q36wyshltu5d4y7lw5l02zxrwu2ksrx9freacvx2lwcc873accsqlye75" }, + { "eaa081377a7eecf0837de142d427e881384966a0332de469b48e80e418e23c71", "xch1a2sgzdm60mk0pqmau9pdgflgsyuyje4qxvk7g6d536qwgx8z83csyx9kdg" }, + { "ba9dfcb30a426f9d9e56b5112415dc06ffff1e7070883ec694f5b13ef07e3f77", "xch1h2wlevc2gfhem8jkk5gjg9wuqmll78nswzyra3557kcnaur78amshmm3fn" }, + { "04ad7ce5b6ae7ce3e52fcca3b13afcc43d3dfbfe0b37ffd3e90e769b3ecf7fb5", "xch1qjkheedk4e7w8ef0ej3mzwhucs7nm7l7pvmll5lfpemfk0k0076sfn5ay9" }, + { "ca9d3150a0f0c4c1770189a3f7f61a78c8522c2949bc058286fb607396731532", "xch1e2wnz59q7rzvzacp3x3l0as60ry9ytpffx7qtq5xlds889nnz5eqx4ph8k" }, + { "9d44185d89ca65abc3f2a35ef937dfe4ae822978288735548acd2863cefde0b9", "xch1n4zpshvfefj6hslj5d00jd7lujhgy2tc9zrn24y2e55x8nhauzuse645f2" }, + { "820dc87cd6d6845be6a8aaa0d71a26bd0ed0d446a7ea482abc7f7767b1a374ae", "xch1sgxuslxk66z9he4g42sdwx3xh58dp4zx5l4ys24u0amk0vdrwjhqt4mfn0" }, + { "5bf39594c129b9c3fb4d2a1b06d03c61e61217a2baacba78911bd54f8d2316d5", "xch1t0eet9xp9xuu876d9gdsd5puv8npy9azh2kt57y3r025lrfrzm2sef52az" }, + { "c4b6ace9790059ddf5bcc646e93e8350291198225ae6a36156941b0e6f0951ab", "xch1cjm2e6teqpvamaducerwj05r2q53rxpzttn2xc2kjsdsumcf2x4sp3fkyu" }, + { "53a76cb9c1cbc57e9f6a0d600a0d992b5f69bcbcb78531563e274dd7b52da373", "xch12wnkewwpe0zha8m2p4sq5rve9d0kn09uk7znz437yaxa0dfd5des03a02j" }, + { "c9bccc299aceb49d9c4195176e3a30365ee1d9f86f7d6608724074a7bb1ff8c5", "xch1ex7vc2v6e66fm8zpj5tkuw3sxe0wrk0cda7kvzrjgp620wcllrzs4nanx8" }, + { "d372d2a28b5d68921d36e25b27c9af26c37eb8def9706377bf10e63309212440", "xch16ded9g5tt45fy8fkufdj0jd0ymphawx7l9cxxaalzrnrxzfpy3qqsprpd7" }, + { "a9b188f6202c16450bca14f8bc2d2467ed27bd2ef6fbd7aba3a6f67a25cd0874", "xch14xcc3a3q9sty2z72znutctfyvlkj00fw7maa02ar5mm85fwdpp6qs93uuj" }, + { "4be316aeb524e3b5b381e07b3bf337128ea1ee08aff2ac7071dde37157df3dff", "xch1f033dt44yn3mtvupupanhuehz282rmsg4le2cur3mh3hz47l8hls92859f" }, + { "7d628efe76de31c7b994f39239dd4f05e1c17c00b5bd7fcac3433354d92d1acc", "xch1043galnkmccu0wv57wfrnh20qhsuzlqqkk7hljkrgve4fkfdrtxq9aewrd" }, + { "585c604fe3970830ab184e679cfcf346187196386e8a5da5662911cc21eca66c", "xch1tpwxqnlrjuyrp2ccfeneel8ngcv8r93cd699mftx9ygucg0v5ekqj32hyl" }, + { "cadf42e1d47448951207585a021d766eb4941873922752305e8459bf50ff02f6", "xch1et059cw5w3yf2ys8tpdqy8tkd66fgxrnjgn4yvz7s3vm758lqtmqw3qdpj" }, + { "f9deae8b24deed355a426f623852f0f63afba131b4fa244d44ffc309717e89fa", "xch1l802azeymmkn2kjzda3rs5hs7ca0hgf3knazgn2yllpsjut738aqp84dlk" }, + { "3770ed1020201d17d7b2ac7a1a3cb19d78abea707d6aafc88932659cd6b97075", "xch1xacw6ypqyqw304aj43ap5093n4u2h6ns0442ljyfxfjee44ewp6s7sh2sl" }, + { "be00868a3140ecb7cbc61ef05b9b74d3e3db960d1ddb5ca1d171eab9466e2684", "xch1hcqgdz33grkt0j7xrmc9hxm5603ah9sdrhd4egw3w84tj3nwy6zq83xuqg" }, + { "63904f0bff3a87bc699449b8a6ac68bc1234df614b90f9b2d39110842df56967", "xch1vwgy7zll82rmc6v5fxu2dtrghsfrfhmpfwg0nvknjygggt04d9ns98udsx" }, + { "4e7872dd16ec6c6324eeafddc074f8e5db643b8ecd7de50f64fee082cab7aaf4", "xch1feu89hgka3kxxf8w4lwuqa8cuhdkgwuwe4772rmylmsg9j4h4t6qd0kggh" }, + { "90babf775ef194d66541cc543e88e980e7ba865beacc6c83fc233c71d91bf657", "xch1jzat7a677x2dve2pe32raz8fsrnm4pjmatxxeqluyv78rkgm7etse5w7uq" }, + { "b6b4ac59b7826eb96a0a59023d5bf956da0324066a728205a51192f06adcbd4d", "xch1k662ckdhsfhtj6s2typr6kle2mdqxfqxdfegypd9zxf0q6kuh4xsrr2cmx" }, + { "8cb337dce669b623333be245e2cc2e76f297748649f003a5e3cda4a36c270996", "xch13jen0h8xdxmzxvemufz79npwwmefwayxf8cq8f0rekj2xmp8pxtq54kqef" }, + { "2b480ab24d3774a3e296444c53862a7cc9db543e399ddb54c45bf381b9ef4309", "xch19dyq4vjdxa628c5kg3x98p320nyak4p78xwak4xyt0ecrw00gvyst9v6e9" }, + { "7d22f6afbc46f5900f0d885e6864b060ac18f7639b66bde87c43c0363d977e46", "xch10530dtaugm6eqrcd3p0xse9svzkp3amrndntm6rug0qrv0vh0erq25nnk5" }, + { "992c0d1244ba613b0e8e48f569e07aa4d65ca05400c499da4056c7007ba21b4d", "xch1nykq6yjyhfsnkr5wfr6kncr65nt9egz5qrzfnkjq2mrsq7azrdxsxnhmrx" }, + { "e3392895c1480418bcf15a04bf2135737032006b11cf7ffee8cb8063606c1b1d", "xch1uvuj39wpfqzp3083tgzt7gf4wdcryqrtz88hllhgewqxxcrvrvws97wcsz" }, + { "7cbe85733c6b5b3cd45b0180c8a4ace9fd66a05c30571af7dc371f044c881857", "xch10jlg2ueudddne4zmqxqv3f9va87kdgzuxpt34a7uxu0sgnygrptsvk0vjx" }, + { "fa0d2265f98b44e5083d4fded5dd309eec94e42e08ce86c4bd2fc47663c68497", "xch1lgxjye0e3dzw2zpafl0dthfsnmkffepwpr8gd39a9lz8vc7xsjtsws6382" }, + { "547ffc4b2011a8361f2fc2965f51a652cce0daf00d7c9713160dd7e1335d9667", "xch123llcjeqzx5rv8e0c2t975dx2txwpkhsp47fwyckpht7zv6ajenscmjkp5" }, + { "d473ce04d4be21632b1672d8f375a0a5a46485c18c7a5c1488eb1d67f0ba0a7a", "xch163euupx5hcskx2ckwtv0xadq5kjxfpwp33a9c9ygavwk0u96pfaqny5tlc" }, + { "fe8d8a221e8f600a928284f3e2f0e00854ba85145a4aeea0eb79980d77a56aa8", "xch1l6xc5gs73asq4y5zsne79u8qpp2t4pg5tf9wag8t0xvq6aa9d25qqjfu9x" }, + { "45841f96edd5aa2056d82b1c273bb2869009709089795ebd61d6b98dd8bdfb6e", "xch1gkzpl9hd6k4zq4kc9vwzwwajs6gqjuys39u4a0tp66ucmk9aldhqtnm3wn" }, + { "678fe3256ad16b12b07e511b0fe3d8be49a3271e5ed930e24cdb9af4f1f5114a", "xch1v787xft269439vr72ydslc7chey6xfc7tmvnpcjvmwd0fu04z99qvufyj3" }, + { "be6acf6105452c2d1bc93dcfe6e9459537d2d5cb38c51a57502eb72991ae5fd8", "xch1he4v7cg9g5kz6x7f8h87d629j5ma94wt8rz3546s96mjnydwtlvq9myq4r" }, + { "c47deea4dde2c6ed2aa21b82bed098dac804687a69920a03c90fe97889e5c353", "xch1c377afxautrw624zrwpta5ycmtyqg6r6dxfq5q7fpl5h3z09cdfsx9rqpg" }, + { "de3e34edbbad5f680f81ed301fe32f31a92ad4ca6ed0424bd0f3f72d8d54936f", "xch1mclrfmdm440ksrupa5cplce0xx5j44x2dmgyyj7s70mjmr25jdhs04dga8" }, + { "a64dbdf8615bcb9622ebff58b42af5da9ed593c79a44b35f01e59f6f809ba8b3", "xch15exmm7rpt09evghtlavtg2h4m20dty78nfztxhcpuk0klqym4zesvyye4y" }, + { "ac9e894edac515d10d0c761e06e1307f57f6521266421018e3873771b7adf241", "xch14j0gjnk6c52azrgvwc0qdcfs0atlv5sjveppqx8rsumhrdad7fqsdhyqv4" }, + { "5ed528142caec9645b827e21c7680c7495be48d1b8be9a7a07cb06837863561c", "xch1tm2js9pv4mykgkuz0csuw6qvwj2mujx3hzlf57s8evrgx7rr2cwqnp2v6p" }, + { "3f139a4940033d5d189de9e1d0862c5e3f6f9433399f0f5b9482f5a48bcb0ce2", "xch18ufe5j2qqv746xyaa8sapp3vtclkl9pn8x0s7ku5st66fz7tpn3q4e2s5p" }, + { "0556c9b286983b3928462df8aa6c821c594cb476900f16d6078262eddd53e34e", "xch1q4tvnv5xnqanj2zx9hu25myzr3v5edrkjq83d4s8sf3wmh2nud8qm2tahm" }, + { "e4603366a9d0b484591ed3dd38c8eb3ab8c3d8c8bcfe8bfcdb38d8c2085eb445", "xch1u3srxe4f6z6ggkg760wn3j8t82uv8kxghnlghlxm8rvvyzz7k3zs4dezav" }, + { "d0d973bb91d6c1a10e05da50f3f1ed92d8ebdece5d3e9d3a28099acb4d511079", "xch16rvh8wu36mq6zrs9mfg08u0djtvwhhkwt5lf6w3gpxdvkn23zpushcrj68" }, + { "408630194c89f4d5eeaa3da633282433a0e24f53fc841f0758ad9d2570d8826f", "xch1gzrrqx2v386dtm428knrx2pyxwswyn6nljzp7p6c4kwj2uxcsfhsd3z59y" }, + { "a5becd8343dfad296b22af2aba3e8e49e903a534fe772f66fa7441533e44e791", "xch15klvmq6rm7kjj6ez4u4t505wf85s8ff5lemj7eh6w3q4x0jyu7gsmm292q" }, + { "16933d71771afef11d8bc6c69a5dc5508ff8ad125726777a8cc2822df8a60099", "xch1z6fn6uthrtl0z8vtcmrf5hw92z8l3tgj2un8w75vc2pzm79xqzvsqyjplm" }, + { "5b03773e753f0696050a539e9121703589fbf96badf7b8023c258eb39a0a8a1d", "xch1tvphw0n48urfvpg22w0fzgtsxkylh7tt4hmmsq3uyk8t8xs23gws8xdn9y" }, + { "91707409f917e2ed912d8f736ab23c093a22d69516e92afd79db97623c560e40", "xch1j9c8gz0ezl3wmyfd3aek4v3upyaz9454zm5j4ltemwtky0zkpeqq7v2xfc" }, + { "7f30852fb0119fdeea1fd1ceeb363abdb798cda8b297217d8f33e39d3f2e4d5d", "xch10ucg2taszx0aa6sl688wkd36hkme3ndgk2tjzlv0x03e60ewf4wsaj6vug" }, + { "c7bbd77458f598ca09cbd62c510033e9345b3977240a7c91d5cfe931920d50b6", "xch1c7aawazc7kvv5zwt6ck9zqpnay69kwthys98eyw4el5nrysd2zmqkwrlty" }, + { "c717ea5b4715c75b29b78a92fc365ed11fb2e8690a0ac1e443881814eb8b17df", "xch1cut75k68zhr4k2dh32f0cdj76y0m96rfpg9vrezr3qvpf6utzl0syn00du" }, + { "99af211be0eab3392179c4d3be4653677e57f05210475e2dbbf404fd81df09d8", "xch1nxhjzxlqa2enjgtecnfmu3jnval90uzjzpr4utdm7sz0mqwlp8vqzkwurx" }, + { "db6c1c8b92d3c45fe262e6920040132879d6ab297bc60d2f420e3b2b62da3777", "xch1mdkpezuj60z9lcnzu6fqqsqn9puad2ef00rq6t6zpcajkck6xamsvlydmz" }, + { "9587dd99de617c438b966d43b0e0ec4ca6f27d1ca755d0da096d3acb1331f7be", "xch1jkramxw7v97y8zukd4pmpc8vfjn0ylgu5a2apksfd5avkye377lqcapqsj" }, + { "d67ef6eb053390719b61c2843ae271144e08d5861486ae00141af2b3c360a392", "xch16el0d6c9xwg8rxmpc2zr4cn3z38q34vxzjr2uqq5rtet8smq5wfqkt883j" }, + { "51860cf3cb02aa780a3c80818fb314be02ecb80cc2d4d9e297e527751b1a88da", "xch12xrqeu7tq248sz3uszqclvc5hcpwewqvct2dnc5hu5nh2xc63rdqz9phav" }, + { "67bf9f817919aa629fa57334937d0b106c0c526db498951a92d3a40c869d1ebc", "xch1v7lelqterx4x98a9wv6fxlgtzpkqc5ndkjvf2x5j6wjqep5ar67qp94pqq" }, + { "87903e04360e67495dc2652c7d9d7fc6a94a1b524a19522077973757b22b0ce6", "xch1s7gruppkpen5jhwzv5k8m8tlc6555x6jfgv4ygrhjum40v3tpnnqw2e2za" }, + { "73eca7566574f1cceddf18c05afc3fb38bd48abb8170790d2a92c8fad63300f4", "xch1w0k2w4n9wncuemwlrrq94lplkw9afz4ms9c8jrf2jty0443nqr6q67flsj" }, + { "5cbc8508798cb47d7f2249455a8a9c0cd5e1f76da44fb81dd25704cb829cbd29", "xch1tj7g2zre3j686lezf9z44z5upn27ramd538ms8wj2uzvhq5uh55sje7jss" }, + { "3fd5f3f6f848f702e549bc3cfb085bd6b0566bffd194254cdf6d8a49b7d61461", "xch18l2l8ahcfrms9e2fhs70kzzm66c9v6ll6x2z2nxldk9ynd7kz3ss72x9dm" }, + { "d39fc33569166cd1643e842ae2987d31be9500733c55e2d568016610c5596639", "xch16w0uxdtfzekdzep7ss4w9xraxxlf2qrn832794tgq9npp32evcus0zwler" }, + { "f69334ed8b126bb43f1fdf71ae738875413ce8899fb272970eff3cea4be85a2e", "xch176fnfmvtzf4mg0clmac6uuugw4qne6yfn7e899cwlu7w5jlgtghq8dwsr4" }, + { "9338a34aa4b95050b6071a25f35b7ed2d086d9eda9981660a7ca620619edf0af", "xch1jvu2xj4yh9g9pds8rgjlxkm76tggdk0d4xvpvc98ef3qvx0d7zhssemdzc" }, + { "98103c82a1d46229c9cd266752cd216c513a443cc4ffaa201fd17cca64b56827", "xch1nqgreq4p633znjwdyen49nfpd3gn53pucnl65gql697v5e94dqnsekvejr" }, + { "e14bbc3e9c08d67283de130cb9a9bdeda2a03b2b5b7220f681cb3172a4b7ebe3", "xch1u99mc05uprt89q77zvxtn2daak32qwettdezpa5pevch9f9ha03s35kfjf" }, + { "a03b9b1f091a314921dbe4edbb917317a6ea6b6dd90bf1b2bb2e7419380bb9be", "xch15qaek8cfrgc5jgwmunkmhytnz7nw56mdmy9lrv4m9e6pjwqthxlqm0r8yx" }, + { "1ba59c4237d32cc82442aa91a5eb9f404deb14e6088ead29619c43da9a4f2277", "xch1rwjecs3h6vkvsfzz42g6t6ulgpx7k98xpz8262tpn3pa4xj0yfmsz4jzxn" }, + { "8e9ef3fc980dc4763af9c9de4d07f9d89b95f273ae1973ddae7c5420bd312e1e", "xch136008lycphz8vwhee80y6plemzdetunn4cvh8hdw032zp0f39c0qnvx2kn" }, + { "9b44d6decfd5ffac4abbeb279361d57615359660c5fad6237b9376c80d711e5b", "xch1ndzddhk06hl6cj4mavnexcw4wc2nt9nqchadvgmmjdmvsrt3redse7lw4u" }, + { "db9c1f782ed48167a6134d8709f82ebd46aa8586503274099d9e64cd20a3147a", "xch1mwwp77pw6jqk0fsnfkrsn7pwh4r24pvx2qe8gzvanejv6g9rz3aqzpnclp" }, + { "6b6f031bbc25c38308cbb015fa79a81527bca7be3646a4576b07db5e67c08956", "xch1ddhsxxauyhpcxzxtkq2l57dgz5nmefa7xer2g4mtqld4ue7q39tqwaj46p" }, + { "1d2ef4972e4d54df08b7f1433bf3e3f150c506b90a1d20b11eb576198ba85e76", "xch1r5h0f9ewf42d7z9h79pnhulr79gv2p4epgwjpvg7k4mpnzagtemqpl3tpr" }, + { "169684797e20b8b9633148682d3f43fa05c3be4e4cd90a627492068c36ec78b8", "xch1z6tgg7t7yzutjce3fp5z606rlgzu80jwfnvs5cn5jgrgcdhv0zuqrrun0k" }, + { "e7f939f6e74674ce4fcfb4234c701811dc8127a665b7d1737f42e2477b581a57", "xch1ulunnah8ge6vun70ks35cuqcz8wgzfaxvkmazumlgt3yw76crftsjwj24j" }, + { "f58f05aecd85b15be03baa96ab3375cdceca0a57edb0a652abb74a4653a78516", "xch17k8sttkdskc4hcpm42t2kvm4eh8v5zjhakc2v54tka9yv5a8s5tqmprdhq" }, + { "99fb4fb50ffa9d44e0b01af1ae49ef64c77de8db50a7499fcf7fdb62279f916f", "xch1n8a5ldg0l2w5fc9srtc6uj00vnrhm6xm2zn5n8700ldkyfulj9hs3qjgdz" }, + { "0e526f191ba1247007a81c2d72a53b07090217a2cb5ae3a77fef0a58093807ec", "xch1pefx7xgm5yj8qpagrskh9ffmquysy9azeddw8fmlau99szfcqlkqgepkzl" }, + { "eeb1e9021039132505536966099e8ea3a78c93985a2ed1e2280755314bab0748", "xch1a6c7jqss8yfj2p2nd9nqn85w5wnceyuctghdrc3gqa2nzjatqayq06hex6" }, + { "aed1a2e6a81a806fb7b497c425f6fa517a1f35647b804aafaeddf23b381aff92", "xch14mg69e4gr2qxlda5jlzztah629ap7dty0wqy4tawmherkwq6l7fqd5jk75" }, + { "49c3d8eef5fec295592926af8459041b4f947c320216608210d320d9dcabeab8", "xch1f8pa3mh4lmpf2kffy6hcgkgyrd8eglpjqgtxpqss6vsdnh9ta2uqpjgjvh" }, + { "d98c1f1716aa333b094c245627679127771a48fb756fdcb8d25ec470ab13a2c8", "xch1mxxp79ck4genkz2vy3tzweu3yam35j8mw4haewxjtmz8p2cn5tyq3rln35" }, + { "cbd4fbc18bb427756a0235916d7464a876bea2248b8c4c47c53cc0c0071dce79", "xch1e020hsvtksnh26szxkgk6ary4pmtag3y3wxyc3798nqvqpcaeeuses6066" }, + { "515692a85257faef8036ef91c410b6ef665567839e641fdf78818266e175dbef", "xch129tf92zj2lawlqpka7gugy9kaan92eurnejplhmcsxpxdct4m0hstxl5hd" }, + { "b5159098980b09cbf59c7569337834ee39f2d3c095ef95101150c2a387d9e803", "xch1k52epxycpvyuhavuw45nx7p5acul957qjhhe2yq32rp28p7eaqpsdjwuz0" }, + { "66dd7d2849c67065f83fa81f9ca0065cdacf9460f5ae991d7f4f41f58f83a7ba", "xch1vmwh62zfcecxt7pl4q0eegqxtndvl9rq7khfj8tlfaqltrur57aqfa57dh" }, + { "35159b6150964308dd6f08fb86f2eea4ff60af923df9573f1a418d33d131620a", "xch1x52ekc2sjeps3ht0pracduhw5nlkptuj8hu4w0c6gxxn85f3vg9qweuxlp" }, + { "78ab40d3e3f69851715185d0c723400e5f54da41ecc89dbc7ba5f6f7fb16f8a9", "xch10z45p5lr76v9zu23shgvwg6qpe04fkjpanyfm0rm5hm007cklz5sz4wqjr" }, + { "6fddd5de12c05b01cba2128599c138877abfbdad6f54d8f2ab56a3dcf9f068d4", "xch1dlwathsjcpdsrjazz2zensfcsaatl0ddda2d3u4t263ae70sdr2qjxfdrc" }, + { "6f34985d8919c49901c7c4daa32e5d23101d92e0b674ac5d0d5cf0b0f4ce36cb", "xch1du6fshvfr8zfjqw8cnd2xtjayvgpmyhqke62chgdtnctpaxwxm9s0gs3j4" }, + { "754221345fb4e7199ceb93d2ab999e17deb33e4f87288c4ff4a7191977cfbec3", "xch1w4pzzdzlknn3n88tj0f2hxv7zl0tx0j0su5gcnl55uv3ja70hmpswpy530" }, + { "d4fe544f093e92a268f942d54a292e24dce7b693061764246b3e12ea546fe1be", "xch16nl9gncf86f2y68egt2552fwynww0d5nqctkgfrt8cfw54r0uxlqnhchl5" }, + { "a577d254ad12ba83544180457a324fe32ef61d2e336e37a08e5eb6ea32147abf", "xch154may49dz2agx4zpspzh5vj0uvh0v8fwxdhr0gywt6mw5vs502ls7yxlal" }, + { "1536629c2f334abf53f6febf1cb30065d2a05271b10c0c9b126f3bde89fccdd9", "xch1z5mx98p0xd9t75lkl6l3evcqvhf2q5n3kyxqexcjduaaaz0uehvsyqh26c" }, + { "9112874c42781146fbd66e10184c90d95f7b2d1cde57384eeb40a80a7b6b96b9", "xch1jyfgwnzz0qg5d77kdcgpsnysm90hktgumetnsnhtgz5q57mtj6usu0p488" }, + { "68ef16716754336e6d8c695ea7c6601185bce243d0b8a4e8ec8d7614c458bdbb", "xch1drh3vut82sekumvvd90203nqzxzmecjr6zu2f68v34mpf3zchkasu3qa6a" }, + { "50ae47b4da8b0fd0b0a8ceb8ac32f92311a58a843a99cf1b83bf4720971447f8", "xch12zhy0dx63v8apv9ge6u2cvheyvg6tz5y82vu7xurharjp9c5gluqk7msvp" }, + { "e9726b207b5d0da1ce99144bca081f51ab0cc671bc60c9cf280293afe85c66fe", "xch1a9exkgrmt5x6rn5ez39u5zql2x4se3n3h3svnnegq2f6l6zuvmlqpwau5j" }, + { "7c28388dd8a5074925a65727ef223f670213140c8ab35dabcd9dfdf2948c7d94", "xch10s5r3rwc55r5jfdx2un77g3lvuppx9qv32e4m27dnh7l99yv0k2qhvg924" }, + { "b2407ee819720bf54b409a0332fabf6394eb6b8f8c88890501673035eacc66a0", "xch1kfq8a6qewg9l2j6qngpn974lvw2wk6u03jygjpgpvucrt6kvv6sqxd9zcl" }, + { "5938e4014ba0bc71226fd01f57fba2fe039739bd2c57e591fb78bf2a852fc556", "xch1tyuwgq2t5z78zgn06q0407azlcpewwda93t7ty0m0zlj4pf0c4tqxtn2gy" }, + { "9db3922edc092eafc1503ea284f2b4f88e593464abbc2b64bb330622293e5d90", "xch1nkeeytkupyh2ls2s863gfu45lz89jdry4w7zke9mxvrzy2f7tkgqxcpzvk" }, + { "e3bbf86780091e6d908f65389dd20324a1b486de46ce581f672756591c18506f", "xch1uwalseuqpy0xmyy0v5ufm5sryjsmfpk7gm89s8m8yat9j8qc2phsc3wlk4" }, + { "c7b4ccf59805fce22a03e50ca6775db784ad0391b548b3c901e32cfe89035358", "xch1c76veavcqh7wy2sru5x2va6ak7z26qu3k4yt8jgpuvk0azgr2dvqf3e2t3" }, + { "41fa8f51178cef220585526c4b1f0348e847101215c3bd1ddf61e0fb8e6a8381", "xch1g8ag75gh3nhjypv92fkyk8crfr5ywyqjzhpm68wlv8s0hrn2swqsrt3g4z" }, + { "88c340e5bc0acfa8a14f23596fc98ea4cd9b8238bc1367410f1a37023c66da82", "xch13rp5pedupt863g20ydvkljvw5nxehq3chsfkwsg0rgmsy0rxm2pqt2f0sw" }, + { "29e2843bd6144c99ba6512fa954ddd676831fcd4211116480af1caf2cfbd69b1", "xch1983ggw7kz3xfnwn9ztaf2nwava5rrlx5yyg3vjq278909naadxcsyuhuen" }, + { "0666dbd9a84b56185503100b03e2dd81ccd9abfebbd916acf4ba289b6d8e42d7", "xch1qendhkdgfdtps4grzq9s8ckas8xdn2l7h0v3dt85hg5fkmvwgttsj5nxhe" }, + { "4b7fbe8c6a7bbe92db1feb29915be4166ed776b70a0347d8ce1cc4d1ac3979ab", "xch1fdlmarr20wlf9kclav5ezklyzehdwa4hpgp50kxwrnzdrtpe0x4s7eha8w" }, + { "4b9041a665dfd569abf7a86eab36bf3b2775e8885555ccd549a2c9a1d708862f", "xch1fwgyrfn9ml2kn2lh4ph2kd4l8vnht6yg242ue42f5ty6r4cgschswd4q5e" }, + { "69e9c6867dd7c7606f279e608ae702ab958a37adf3dc769f98d26c1cece122da", "xch1d85udpna6lrkqme8nesg4ecz4w2c5dad70w8d8uc6fkpem8pytdqf5k4da" }, + { "7350fbcda1234666b2517d11a638e6f279c4923a16b5a18e6aad1e4ebfe07e24", "xch1wdg0hndpydrxdvj305g6vw8x7fuufy36z666rrn2450ya0lq0cjqetqlrc" }, + { "c04e435141274bae53e7f2b49384427091b07f7d850c4fcdda5204d20d9d4bf5", "xch1cp8yx52pya96u5l8726f8pzzwzgmqlmas5xylnw62gzdyrvaf06sq3kyh7" }, + { "f25bb1db3c8baff19ebbec6c38b6d5e012fd68b039f68ed2a3d3002dc781c447", "xch17fdmrkeu3whlr84ma3kr3dk4uqf0669s88mga54r6vqzm3upc3rsga82dt" }, + { "a37c6ab3a7c2411aae627e27b4b4037c605c71f9a80178c62535f18d557d2efb", "xch15d7x4va8cfq34tnz0cnmfdqr03s9cu0e4qqh3339xhcc64ta9masfqrm9d" }, + { "eb8b208a697e50c524fe4b82b6358c4319f623a83bf754bbb9b567febbf8670a", "xch1aw9jpznf0egv2f87fwptvdvvgvvlvgag80m4fwaek4nlawlcvu9qvv80u0" }, + { "27f56b194ebc9db214cae3bcb027b155346f88606d1201b0e47e0ec484be8ed8", "xch1yl6kkx2whjwmy9x2uw7tqfa3256xlzrqd5fqrv8y0c8vfp973mvqar5am8" }, + { "498b2343634561985a0aef33138f78072de72f3a53a9eb64c3963ee34d0f0ef2", "xch1fx9jxsmrg4sesks2aue38rmcquk7wte62w57kexrjclwxng0pmeq6k08c9" }, + { "14b7b71064b55542cb1f89d7bc8d30a121589a461e52a806375f249761062f09", "xch1zjmmwyryk4259jcl38tmerfs5ys43xjxref2sp3htujfwcgx9uysger2r4" }, + { "6e8c2b9ab4b1b1bbfe2ab98a5a9d3b1bfbee9d6c8a427a896d8c151295432d90", "xch1d6xzhx45kxcmhl32hx9948fmr0a7a8tv3fp84ztd3s23992r9kgq20ca7s" }, + { "7871d4796140fa1f876b2d6389068e7b828f8d3789c8a11bb7654fdd18757ffc", "xch10pcag7tpgraplpmt943cjp5w0wpglrfh38y2zxahv48a6xr40l7q5tr5pg" }, + { "98bcda0f0f0f3ada91395683781c61be8db73d781f56778031748d764c495628", "xch1nz7d5rc0puad4yfe26phs8rph6xmw0tcrat80qp3wjxhvnzf2c5qczgj5q" }, + { "c2718d42cf855868f8a40def58321b77a24d8fef541356b9802472a6132f1449", "xch1cfcc6sk0s4vx379yphh4svsmw73ymrl02sf4dwvqy3e2vye0z3ysd6w3kj" }, + { "632216ac979407007462b84a04ab0de1d15e49fce35205c5449bfafaadb35ddb", "xch1vv3pdtyhjsrsqarzhp9qf2cdu8g4uj0uudfqt32yn0a04tdnthdsedjf0j" }, + { "201f3dda55e43e441bfb405778518f539c655b574a586a520886a59f90e947fb", "xch1yq0nmkj4uslygxlmgpths5v02wwx2k6hffvx55sgs6jely8fglaswqsgrf" }, + { "0623d8c6349542a413c2986d597ed7e1d9afb399f5a0e9a756dc117e954c096b", "xch1qc3a3335j4p2gy7znpk4jlkhu8v6lvue7kswnf6kmsgha92vp94sz40v9t" }, + { "ed047b82f05f9eec3a1e11e2215736b9ab0439727a91c492fc08ad955a22a89a", "xch1a5z8hqhst70wcws7z83zz4ekhx4sgwtj02gufyhupzke2k3z4zdq4xpfvl" }, + { "de5f9784b8ec06fed891bc647977b108776e722aac0a1d2d95e7bfd5b966f549", "xch1me0e0p9casr0aky3h3j8jaa3ppmkuu324s9p6tv4u7latwtx74ysfgp2ww" }, + { "c56faaaf909b3dd444a66e4978e5fced2f836c2c4963bf4da5dc40a8f55e6c5e", "xch1c4h64tusnv7ag39xdeyh3e0ua5hcxmpvf93m7nd9m3q23a27d30qe0a478" }, + { "1790854019d349e5186b08110de89748331eb878eb97dbba7b08f2fd834d0e3f", "xch1z7gg2sqe6dy72xrtpqgsm6yhfqe3awrcawtahwnmpre0mq6dpcls5tlqex" }, + { "c1dd09ed2d8079568a9a97ffe01da5092502b769ac06ccfea18c5432286ae45f", "xch1c8wsnmfdspu4dz56jll7q8d9pyjs9dmf4srvel4p332ry2r2u30sza4xlc" }, + { "8b674eeca7d3054aa3b1cc11b49faf4ae9fa16064378da7e31f235cdd7ce3228", "xch13dn5am986vz54ga3esgmf8a0ft5l59sxgdud5l337g6um47wxg5qpgy6cu" }, + { "a18c9dfe506d0547762b2332ae55456277657e56f201ba6215a81b1a277fe431", "xch15xxfmljsd5z5wa3tyve2u429vfmk2ljk7gqm5cs44qd35fmluscsjze0z0" }, + { "f344cd5b0460133b5aa40770620258ef54e6308a759c17c343595afdfede17a3", "xch17dzv6kcyvqfnkk4yqacxyqjcaa2wvvy2wkwp0s6rt9d0mlk7z73s0m5hk9" }, + { "b4bf56f871c4073c9969edbf37de37cc0b0018cab9a38fdb9095f26447ad9f44", "xch1kjl4d7r3csrnextfakln0h3hes9sqxx2hx3clkusjhexg3adnazq3l002v" }, + { "b65fb494f6840cb17e72c907f3e544492dff21218416e0c4ec9d3ae01132768e", "xch1ke0mf98kssxtzlnjeyrl8e2yfykl7gfpsstwp38vn5awqyfjw68qyp9kdl" }, + { "5cd23e58733382b8fa9985853747a4a44924117993c10f9424bc0443bebed539", "xch1tnfrukrnxwpt375eskznw3ay53yjgytej0qsl9pyhszy804765usgx6pcq" }, + { "673011951433c9435cb3850c74c65d9518a5a6a5f211b3981a5b0203119e6378", "xch1vucpr9g5x0y5xh9ns5x8f3jaj5v2tf497ggm8xq6tvpqxyv7vduq5l9ngz" }, + { "25c52638b456ed0e72b0a157e2a6605a0a93052369d633127fe2265844a4a005", "xch1yhzjvw952mksuu4s59t79fnqtg9fxpfrd8trxynlugn9s39y5qzs3xt4lz" }, + { "716b144f6bf4692f252ec050f870878eedbe0313e4da1343919946be84e0b2b6", "xch1w943gnmt735j7ffwcpg0suy83mkmuqcnundpxsu3n9rtap8qk2mqst5xr5" }, + { "2d33fda9f8c5959faad4a6fe1318a4768d60dbe863323a8d63562cbb2f6ad7e3", "xch195elm20cck2el2k55mlpxx9yw6xkpklgvver4rtr2cktktm26l3shg7y05" }, + { "94c739b67870e0528b10811f0f27e7f3a81c6204ef9c98b5e67364695749f044", "xch1jnrnndncwrs99zcssy0s7fl87w5pccsya7wf3d0xwdjxj46f7pzqjtu9zx" }, + { "2d2bfea13be90f123a8d8c5c444cc3dd2d637e09c081ca1c421aca145b156748", "xch1954lagfmay83yw5d33wygnxrm5kkxlsfczqu58zzrt9pgkc4vayq0cdek0" }, + { "6fac44f35d0760a1632c7f495e34e9c6cad3cb03b2d7ff95a794b016e30d2af6", "xch1d7kyfu6aqas2zcev0ay4ud8fcm9d8jcrkttll9d8jjcpdccd9tmq9vewr8" }, + { "2a874996265e31f83d4be8438412e9d78f8cb86ed287a2fa75b0d0a61918b0f2", "xch192r5n93xtccls02tappcgyhf678cewrw62r697n4krg2vxgckreqekaj0t" }, + { "d1e0328625b6154a996bf42586a9ba7406b23a7171ace5b45d8d32eeffab4713", "xch168sr9p39kc254xtt7sjcd2d6wsrtywn3wxkwtdza35ewalatgufs22gt3h" }, + { "c799151f34b1355f2625ac438e7192098a045bc4ca785f0a3e26c9b6cdc9d68e", "xch1c7v328e5ky647f3943pcuuvjpx9qgk7yefu97z37ymymdnwf668qfj7et9" }, + { "0cfc678a16f607b68014e81e945d53491fc545b79cfd6047404bb06effa87a3a", "xch1pn7x0zsk7crmdqq5aq0fgh2nfy0u23dhnn7kq36qfwcxalag0gaq35y7rm" }, + { "366c4de7e100f1131a381d73a9d9df1beb38cefdecffd9a7c412cd66ed13907e", "xch1xekymelpqrc3xx3cr4e6nkwlr04n3nhaanlanf7yztxkdmgnjplqrx0uv3" }, + { "6baa25e9a379080df8eeff7e4c27b567ba8e75b7762275733a197262698925cd", "xch1dw4zt6dr0yyqm78wlalycfa4v7aguadhwc382ue6r9exy6vfyhxsxeljf2" }, + { "d83559f4bbd43173e991f038ec7d480afa24954b000d38a264262ce039c4b6be", "xch1mq64na9m6sch86v37quwcl2gptazf92tqqxn3gnyyckwqwwyk6lq8wwmxp" }, + { "315512fedfed2f5001da7ae8635d48ef537b1772af96387f7459de9cd21a1455", "xch1x9239lkla5h4qqw60t5xxh2gaafhk9mj47trslm5t80fe5s6z32shuz5eq" }, + { "3ff2e549b2e2c589d028573ab80239eb87a2b1068a52f43788e3307d8e9f79f9", "xch18lew2jdjutzcn5pg2uatsq3eawr69vgx3ff0gduguvc8mr5l08us9pphqv" }, + { "5fe659e7b9f16673df485a6b63a074d92d2c4634702e18e11644b558964d27a2", "xch1tln9neae79n88h6gtf4k8gr5mykjc335wqhp3cgkgj6439jdy73qmm52s6" }, + { "08b8494497469a7ab2c05e399bc3f9426d31a229cd5f504a2698678313df87f1", "xch1pzuyj3yhg6d84vkqtcuehslegfknrg3fe404qj3xnpncxy7lslcs47wxgt" }, + { "de55837155e2943572adc36e8c672f229d8441c5263f7bff797bd61bfb1a9fdc", "xch1me2cxu24u22r2u4dcdhgcee0y2wcgsw9yclhhlme00tph7c6nlwq4axgky" }, + { "e30468271215ed0100bd464917c04f3b63189c13afc86452b36acc50298d09fa", "xch1uvzxsfcjzhkszq9agey30sz08d3338qn4lyxg54ndtx9q2vdp8aq9pyntu" }, + { "96bb8171ab25802fe0ed9cf38160a19d838a376e419bb024a533236ffb77afe2", "xch1j6aczudtykqzlc8dnneczc9pnkpc5dmwgxdmqf99xv3kl7mh4l3qucd953" }, + { "d384ccf5f901bb1b2489ec68b72572790ad3e319e88f5aae06e5a033c09e4929", "xch16wzvea0eqxa3kfyfa35twftj0y9d8cceaz844tsxuksr8sy7fy5suz0kpn" }, + { "1ea6f6b13ba30a4a9e4d4563d5419f7a44e1a0fda2e9fc4dd32ec4c8dd6ed1fd", "xch1r6n0dvfm5v9y48jdg43a2svl0fzwrg8a5t5lcnwn9mzv3htw687shj67uu" }, + { "58ba22935dd3397dd6871236b3a54c307af17a03885cf4455699ebb2fc221357", "xch1tzaz9y6a6vuhm458zgmt8f2vxpa0z7sr3pw0g32kn84m9lpzzdtsz2fuqj" }, + { "5ca0e0fbcc84a60ba9142fcf41658b53afc4702f5db3d47d2699864a50a6c38a", "xch1tjswp77vsjnqh2g59l85zevt2whugup0tkeaglfxnxry559xcw9qrenv9g" }, + { "0588e35eb4c71f1a09332df99e30c21d771a644b17feeb45cac38b2f221c84ad", "xch1qkywxh45cu035zfn9hueuvxzr4m35eztzllwk3w2cw9j7gsusjks5f6f6g" }, + { "3086b2c7840feaa0b80d1e29ac15b1a1c575467ac42e7d89ea88149181b38fef", "xch1xzrt93uypl42pwqdrc56c9d358zh23n6csh8mz023q2frqdn3lhsuwkyyp" }, + { "830fdf56bfcac4bc59d4dfb705208f80964cbca3c3464dc5aa8f2858b9dc0271", "xch1sv8a744letztckw5m7ms2gy0sztye09rcdrym3d23u593wwuqfcsaehdcz" }, + { "de12fc6ede06e735a31519744ff011fd3b8f0c1006f48557925a7081f0c52b95", "xch1mcf0cmk7qmnntgc4r96yluq3l5ac7rqsqm6g24ujtfcgrux99w2sdpexyq" }, + { "5ef971410d802ba5fac1c4e7d23239f1097b085851d45a76f260e93ca33a9540", "xch1tmuhzsgdsq46t7kpcnnayv3e7yyhkzzc28295ahjvr5nege6j4qq8e6ayf" }, + { "e60cbf578923784489b3c50f44c0d9a3720228d94f5502d940f6f378507cbbde", "xch1ucxt74ufyduyfzdnc585fsxe5deqy2xefa2s9k2q7mehs5ruh00qva20zh" }, + { "88aff402d76f8a11388535c0190da798d2ce2f4e29473d61132a8613165fef01", "xch13zhlgqkhd79pzwy9xhqpjrd8nrfvut6w99rn6cgn92rpx9jlauqszdlnrs" }, + { "bb264d81b622e751e2cd1a16bac5f0b7bd98deed1be1cc3c4ffce1570202ae43", "xch1hvnymqdkytn4rckdrgtt430sk77e3hhdr0suc0z0lns4wqsz4eps3mcj28" }, + { "32398674b6cca58ac4d3aabd6eb40438de074960984af33674ac2d70330baea2", "xch1xgucva9kejjc43xn427kadqy8r0qwjtqnp90xdn54skhqvct463qw839sx" }, + { "cf8eb146a73e33b3bfb43aa51bbb633062acce06b8e96f32f789f55105bb1aa1", "xch1e78tz3488cem80a582j3hwmrxp32ensxhr5k7vhh3864zpdmr2ss8pmsed" }, + { "253fb587cc6943063432297956b230942ab41b6ff9c4b5361a5d764c7afbe370", "xch1y5lmtp7vd9psvdpj99u4dv3sjs4tgxm0l8zt2ds6t4myc7hmudcqv7jfl9" }, + { "690bcfb3587fd4044bb8aee4bb95c88b9aae4a307e31dc0e68bfb5bfc35a3a75", "xch1dy9ulv6c0l2qgjac4mjth9wg3wd2uj3s0ccacrngh76mls668f6sgm5lpl" }, + { "6c685cef7ecfa72571b6ff21d9fc9a6f19b89f8d556b9816b16b2dca5b5ae8f4", "xch1d359emm7e7nj2udklusanly6duvm38ud244es943dvku5k66ar6qjkqfw8" }, + { "77c5e0ace00e021aa753992afb66a9ab9c9abcfbea754e82fe83012d384d77e2", "xch1wlz7pt8qpcpp4f6nny40ke4f4wwf408maf65aqh7svqj6wzdwl3qkrmpgl" }, + { "b24c490d346cf6104803ecb4c95883cf86b99246f415f251b8a2c7cc3f974e67", "xch1kfxyjrf5dnmpqjqraj6vjkyre7rtnyjx7s2ly5dc5truc0uhfensqyc0mw" }, + { "66ea7ea4809cc37a48629ddc85fe7c57261072f1c348a118e5c3b554fce8cb57", "xch1vm48afyqnnph5jrznhwgtlnu2unpquh3cdy2zx89cw64fl8gedtsl89r7x" }, + { "852d72f0771c8368b5d1825b7395961a04b51ae27aefb771c4a98503536f972c", "xch1s5kh9urhrjpk3dw3sfdh89vkrgzt2xhz0thmwuwy4xzsx5m0jukqhjedl6" }, + { "749210a93152a9a7dfeb9de628c907725255519cc0df6db055e61bf3ac0737e9", "xch1wjfpp2f322560hltnhnz3jg8wff925vucr0kmvz4ucdl8tq8xl5szf98dd" }, + { "0c2e687240e4600178d6aea32399d9f74bd1262fc7f5a9c82413c67b68e10d63", "xch1pshxsujqu3sqz7xk463j8xwe7a9azf30cl66njpyz0r8k68pp43szf54pm" }, + { "dd26d7e085c0d17d736e677a9e48ab00af46980864d0b6f44e3c013af3b41945", "xch1m5nd0cy9crgh6umwvaafuj9tqzh5dxqgvngtdazw8sqn4ua5r9zsqcegxx" }, + { "5dbf6a716866993e41d7885cfa234b0d434bcb97de0e048b5162fd65e63b4b5e", "xch1tklk5utgv6vnuswh3pw05g6tp4p5hjuhmc8qfz63vt7kte3mfd0qtmhzce" }, + { "173471257569ad3a2985da6356c27f0edd81ad03a55394f7ba8c2cc1ce3ba177", "xch1zu68zft4dxkn52v9mf34dsnlpmwcrtgr54fefaa63skvrn3m59msddf5vw" }, + { "975acf72daaa5a923d6e5330e9e46f4c28b7b43c31901b3a6a0fc4b771cdf86e", "xch1jadv7uk64fdfy0tw2vcwner0fs5t0dpuxxgpkwn2plztwuwdlphqpm4ssx" }, + { "b73c6f3fb43d82b56c577be0f109f89f20f4999bea6f90c3ed14167c95701403", "xch1ku7x70a58kpt2mzh00s0zz0cnus0fxvmafhepsldzst8e9tszspsjch4cs" }, + { "eebd699ab87def0e8fe3b86098edbdf8bc27090d31002de50e617dc27851efcd", "xch1a67knx4c0hhsarlrhpsf3mdalz7zwzgdxyqzmegwv97uy7z3alxs3m8ycc" }, + { "54a250b705a4e64d806848fb60356f182166a0196f6c7a0b8690a5b8e5c38772", "xch12j39pdc95nnymqrgfrakqdt0rqskdgqedak85zuxjzjm3ewrsaeq47d6wm" }, + { "4a07697ae8b3913bf1772acc42970c1ce7880bbad36e0d65052f93f7973b9f1c", "xch1fgrkj7hgkwgnhuth9txy99cvrnncsza66dhq6eg997fl09emnuwqwquzhp" }, + { "82116256b724a000abd30cdf82e7a3ddd7809c92af92a653b6079c60a4132082", "xch1sggky44hyjsqp27npn0c9earmhtcp8yj47f2v5akq7wxpfqnyzpqzz5ams" }, + { "92720b36fd15cb73eb4f8101f3821c0645b574b0c89ff679c3681c2401a4cc54", "xch1jfeqkdhazh9h8660syql8qsuqezm2a9sez0lv7wrdqwzgqdye32q3ll6aw" }, + { "16dfeb4c3ff98721dc1598e8b559e0cf4c45aba809abb9d7c18be28f597172c7", "xch1zm07knpllxrjrhq4nr5t2k0qeaxyt2agpx4mn47p303g7kt3wtrsx3jxvn" }, + { "6b4df45800335cd820db2f7d14a7301110c925ecbdda64d8fe552f5bb4f24d6c", "xch1ddxlgkqqxdwdsgxm9a73ffeszygvjf0vhhdxfk8725h4hd8jf4kqjahdrz" }, + { "c845f4db4589f75aab82dfa0f39004c114451baf642569bdcf817c569ea7d8ca", "xch1epzlfk6938m442uzm7s08yqycy2y2xa0vsjkn0w0s979d848mr9q3wv6l7" }, + { "b9706afb30a87917fbe296404a9be31473e8985fbfc303136a8dd0219ebe1603", "xch1h9cx47es4pu307lzjeqy4xlrz3e73xzlhlpsxym23hgzr847zcpsn9vyz2" }, + { "482b0dccb47e11329a66c4432e3ff38186cc306557ca14edec0fd22905bfd1a8", "xch1fq4smn950cgn9xnxc3pju0lnsxrvcvr92l9pfm0vplfzjpdl6x5q2794st" }, + { "0461a1aab15eba666635c0b93ded280798d0a16d7013089d8679955e85027ea6", "xch1q3s6r243t6axve34czunmmfgq7vdpgtdwqfs38vx0x24apgz06nqv7u465" }, + { "506bccedb854950164f47e67366c5c84b7c509a89f0777ea212e7215bcd8baec", "xch12p4uemdc2j2sze850ennvmzusjmu2zdgnurh063p9eept0xchtkqvrr3w3" }, + { "7dd0a0b014936f658877e0956759231f12946f2b6c6c984ab19ecc4b5fae8477", "xch10hg2pvq5jdhktzrhuz2kwkfrruffgmetd3kfsj43nmxykhaws3ms9r906h" }, + { "2a741ac28574d4ab79e64dc01822a184f9ebb5754d47a4e8d355028d36031235", "xch19f6p4s59wn22k70xfhqpsg4psnu7hdt4f4r6f6xn25pg6dsrzg6slcsgwq" }, + { "1b418f4014ed8036d87433a468f4786db68446057520b508b2f2fbe3df34d5ce", "xch1rdqc7sq5akqrdkr5xwjx3arcdkmgg3s9w5st2z9j7ta78he56h8qwaph95" }, + { "a66913c21bba00f0433d052dba0ba0a4ff7f4ba2470a8d454c58a5e7f428013b", "xch15e538ssmhgq0qseaq5km5zaq5nlh7jazgu9g632vtzj70apgqyas6hq0a5" }, + { "41e8ad75f358f0d6e0f9cf35bc4a6022db073e10719a586e4c851adfab5534ff", "xch1g8526a0ntrcddc8eeu6mcjnqytdsw0sswxd9smjvs5ddl264xnlsz3fzhe" }, + { "27673b7b37bc67b11c90ff4410ed70bce387b313d74f36ce8101245e11c3c776", "xch1yannk7ehh3nmz8yslazppmtshn3c0vcn6a8ndn5pqyj9uywrcamqr8wfxy" }, + { "756ec2a76898badea84025b8902c9b427ba9abb18d6978dda7ecaafa2fa41563", "xch1w4hv9fmgnzada2zqykufqtymgfa6n2a3345h3hd8aj405tayz43swqgkw3" }, + { "fadd914404348190d597041d42959acd94d0c4db9574375b4ade9d9b93b45ca0", "xch1ltwez3qyxjqep4vhqsw599v6ek2dp3xmj46rwk62m6wehya5tjsqtg8fhw" }, + { "a37613c85ba103d9f978fc3cefb52b9e12c2e6018ecc40d0c4f9e276a4ca6bd4", "xch15dmp8jzm5ypan7tcls7wldftncfv9esp3mxyp5xyl838dfx2d02qas5xtq" }, + { "a6f66f464f2b7a0a3f26ea81ced176629f04c16ac7643890ec31e2a36ddfe2aa", "xch15mmx73j09daq50exa2qua5tkv20sfst2cajr3y8vx832xmwlu24qamx7jm" }, + { "4004f710093709d3da7be82bf45aa1b88ca4a3aca84cd42c63495dfe9b0adb34", "xch1gqz0wyqfxuya8knmaq4lgk4phzx2fgav4pxdgtrrf9wlaxc2mv6qggst3s" }, + { "0152f7b0dfb7a157b5b49d524bfc6d89c8b7ac00d0527eb3b20fe8a0951940c3", "xch1q9f00vxlk7s40dd5n4fyhlrd38yt0tqq6pf8avajpl52p9gegrpshwnudd" }, + { "e09196a7013b25500c6ffc7757b9aed8235ac55a5e2a37ac980486b156128afe", "xch1uzgedfcp8vj4qrr0l3m40wdwmq344326tc4r0tycqjrtz4sj3tlq8ldsff" }, + { "406d5f27b07400b8ab9eec40fc71a8dfc00f442fbf6d757ff373392074d42013", "xch1gpk47faswsqt32u7a3q0cudgmlqq73p0hakh2llnwvujqax5yqfsp8wv0r" }, + { "aad3fa2a5224f798541c55900a9b1b91355438cd91fad7d23e9d0f47329de1a8", "xch14tfl52jjynmes4qu2kgq4xcmjy64gwxdj8ad0537n585wv5aux5qrdprqm" }, + { "e70b3a8c4fa514c673cd591953bea9d8c14dc55b275a83279ef2e099be546e8d", "xch1uu9n4rz0552vvu7dtyv4804fmrq5m32myadgxfu77tsfn0j5d6xsdfrz7s" }, + { "df0ae06e3a4134276ab4239abc690a7a744d3e11941dd123e077c9cdb139fba1", "xch1mu9wqm36gy6zw645ywdtc6g20f6y60s3jswazglqwlyumvfelwsswkw6r0" }, + { "c955802d73672e17520eb1aacf67ce693687a453664441c15a8669bf3f4c72fb", "xch1e92cqttnvuhpw5swkx4v7e7wdymg0fznvezyrs26se5m706vwtasmzhkfe" }, + { "73a945fec0a4510ce200e02b1fba440749a39d27c9699c3480affc86090ff88d", "xch1ww55tlkq53gsecsquq43lwjyqay688f8e95ecdyq4l7gvzg0lzxsc46k7f" }, + { "7680df5843d8a06e0aaab77ac25b561cc0dd15c6b32fef42747d30ed9d559912", "xch1w6qd7kzrmzsxuz42kaavyk6krnqd69wxkvh77sn505cwm824nyfqdjpdge" }, + { "2a781dde498e1d1fa4ccf23e9bc13728e5175cde5117ca00521c7978dc666718", "xch19fupmhjf3cw3lfxv7glfhsfh9rj3whx72ytu5qzjr3uh3hrxvuvqwrtpas" }, + { "81aa219a6e9a0855a250fb25666dc275271d0fd8048b0e018716a855ee4c3c0c", "xch1sx4zrxnwngy9tgjslvjkvmwzw5n36r7cqj9suqv8z659tmjv8sxqjwz4vf" }, + { "3aa910423a04b6b6c007196b0d9b5bca9aeeb17f912df3aac96cdd556f6c07d0", "xch18253qs36qjmtdsq8r94smx6me2dwavtljykl82kfdnw42mmvqlgq4tywgj" }, + { "8284236c03366ebc98a69a0cdcd403b9253c853847a5afddb62c855a2803253f", "xch1s2zzxmqrxehtex9xngxde4qrhyjnepfcg7j6lhdk9jz452qry5lswzt9pk" }, + { "b49d0e445f7c4e949946b70b3fccd1ba3357c3c6dd5d2f2c90a4a2a2e39f7081", "xch1kjwsu3zl038ffx2xku9nlnx3hge40s7xm4wj7tys5j329culwzqstzdldh" }, + { "d9613bfdac0dc606450ba2bb2c607e6c322d62befbc80a0f551774ee16af60b1", "xch1m9snhldvphrqv3gt52ajccr7dsez6c47l0yq5r64za6wu940vzcsmmq4u9" }, + { "5a3fb368d350a349680d11838b6d63f24e0d41bb3d2af72c0d53daf9cdc9fed9", "xch1tglmx6xn2z35j6qdzxpckmtr7f8q6sdm8540wtqd20d0nnwflmvswckxwd" }, + { "5e286878cf8319f443cfba4b8393b4e2048d356fbc230997cc70c7ae377ed30b", "xch1tc5xs7x0svvlgs70hf9c8ya5ugzg6dt0hs3sn97vwrr6udm76v9sq2s26f" }, + { "17d7cae9aae36c380afa6b61b14067a5a06a62605854918ae3ca825826099866", "xch1zltu46d2udkrszh6ddsmzsr85ksx5cnqtp2frzhre2p9sfsfnpnq6xajqe" }, + { "7e3d285499efa6798ce2cf01434cf2166900e18eb6c3899cb22d18ced7349031", "xch10c7js4yea7n8nr8zeuq5xn8jze5spcvwkmpcn89j95vva4e5jqcspthmgl" }, + { "897203f2b10b65072d5a6c29a3f89f695ca830410a483d1745ecebf019ddd278", "xch139eq8u43pdjswt26ds5687yld9w2svzppfyr6969an4lqxwa6fuqt6qpq6" }, + { "b9a2ddd3814c126776718febf8fedc4ece9239ef11e25565666d599d69d286f3", "xch1hx3dm5upfsfxwan33l4l3lkufm8fyw00z8392etxd4ve66wjsmesd7z67r" }, + { "3fce3fa3263b627211bb234ee8d11520747b5bf4b016f4a35e363c1d9490352a", "xch18l8rlgex8d38yydmyd8w35g4yp68kkl5kqt0fg67xc7pm9ysx54qy7p0g9" }, + { "5c8435d9e1c35cc9822ba70911408ca1423d57312c4c2b8d55821171bace4dbb", "xch1tjzrtk0pcdwvnq3t5uy3zsyv59pr64e393xzhr24sgghrwkwfkasf393w7" }, + { "097f358e0b553f6c91f32c8186fdc96d4adbb12809c4f338089ce8fd1ad2f764", "xch1p9lntrst25lkey0n9jqcdlwfd49dhvfgp8z0xwqgnn506xkj7ajqmcx4w2" }, + { "2af44ca67b4294128b47808a8ba9dfec7edf86bac05f8d2ee0c5afee214d064e", "xch19t6yefnmg22p9z68sz9gh2wla3ldlp46cp0c6thqckh7ug2dqe8qlqgy39" }, + { "5b93097ef44ab61bac9517001ba2fbfc3cda9e9f9a2e3d3ba21402ee8811963b", "xch1twfsjlh5f2mphty4zuqphghmls7d485lnghr6wazzspwazq3jcasge4jny" }, + { "a3dc7b9c4d2f5495bf0731ce762a2c5ca465d9b5d1e05559eab7be241824ce4c", "xch150w8h8zd9a2ft0c8x888v23vtjjxtkd468s92k02k7lzgxpyeexqphlres" }, + { "da78d7872724445791baefda8045368ec58784769cffa4500d8798f9834f01e7", "xch1mfud0pe8y3z90yd6aldgq3fk3mzc0prknnl6g5qds7v0nq60q8nsm8ezdg" }, + { "80a032feeacfc28676f4c83bc8a8b2ed181848c02f13864e2050bebbe6aef467", "xch1szsr9lh2elpgvah5eqau329ja5vpsjxq9ufcvn3q2zlthe4w73ns64aycc" }, + { "7dfac970c6345d7c97a366b3f8aa675b7caca4f3d6d2a2739fabe585c0a96e1b", "xch10havjuxxx3whe9arv6el32n8td72ef8n6mf2yuul40jcts9fdcdsm50huj" }, + { "77fa2e69cbe2ecb352d0bdfc2d215cdd79fc1f33c72e491cf1ffe8c0e9b08a9f", "xch1wlazu6wtutktx5kshh7z6g2um4ulc8encuhyj883ll5vp6ds320s5a4yql" }, + { "f13b0c71b6ebf43e4ee2c67f73055b2f66276a78921a358baab2efc8c040bb78", "xch17yascudka06runhzcelhxp2m9anzw6ncjgdrtza2kthu3szqhduqq2kk3x" }, + { "8d58068351331fead5f103362d9b855e048dd797eefdf954cac462af95acf38d", "xch134vqdq63xv074403qvmzmxu9tczgm4uham7lj4x2c332l9dv7wxsuqzsz0" }, + { "8ac233b041021421cb5b121f4cb853c2852cce15b7f094526f1801ae7902eb93", "xch13tpr8vzpqg2zrj6mzg05ewznc2zjens4klcfg5n0rqq6u7gzawfsyypcay" }, + { "0ba71fd5a055c31f0e75b13028ae7b6ece5251e2f95b43efb4045b037f23355e", "xch1pwn3l4dq2hp37rn4kycz3tnmdm89y50zl9d58ma5q3dsxlerx40qulz524" }, + { "bb19f2dd7933e315ad5a8f8103542b416226bf893ce6c1b7012bc97aa4c02812", "xch1hvvl9htex033tt2637qsx4ptg93zd0uf8nnvrdcp90yh4fxq9qfqeta8un" }, + { "4bb8294fe6bbdb5720d2cadfadb4f13551f8b577919bd2cfd4b98607ee2042f0", "xch1fwuzjnlxh0d4wgxjet06md83x4gl3dthjxda9n75hxrq0m3qgtcqnsp2c2" }, + { "983212233de7435bec98f1d36382979fd17bdee49c2367c5b08f263590519e86", "xch1nqepygeauap4hmyc78fk8q5hnlghhhhyns3k03ds3unrtyz3n6rq67wccu" }, + { "934e5b92ad876837af088e5a891f4988f40501f454c4dce67258a521e3b36082", "xch1jd89hy4dsa5r0tcg3edgj86f3r6q2q052nzdeenjtzjjrcanvzpqf3t6fp" }, + { "12d0d36e031e46cad8c7b819fe1cbd396c55202f81163a1573a3a25309ea9f34", "xch1ztgdxmsrrerv4kx8hqvlu89a89k92gp0sytr59tn5w39xz02nu6qgn4pnv" }, + { "9eb467020b2da7b731d0f630f08f816bf5c098a7870fa86ce0eaad8ab4a8a576", "xch1n66xwqst9knmwvws7cc0prupd06upx98su86sm8qa2kc4d9g54mqsy5yr9" }, + { "527e3d9cf4da5a731d638dcd6e389feb495c117aaa94ddb9903c5a4a9510f4d2", "xch12flrm885mfd8x8tr3hxkuwylady4cyt6422dmwvs83dy49gs7nfqvdtlja" }, + { "dfad8f7ed2dba3e0b48179b214e84b131bf8edee13bfee4f480e273c5fe968ed", "xch1m7kc7lkjmw37pdyp0xepf6ztzvdl3m0wzwl7un6gpcnnchlfdrksp2zmcz" }, + { "99d7f0069cec79f2cf648ae76136d7be02f9a8e2163cd29ab2315084085ef233", "xch1n8tlqp5ua3ul9nmy3tnkzdkhhcp0n28zzc7d9x4jx9gggzz77gesnwucam" }, + { "524ab1f7a1c90605dea38804a2f645901ec79106fbaeb0b102767d9789043014", "xch12f9traapeyrqth4r3qz29aj9jq0v0ygxlwhtpvgzwe7e0zgyxq2qqlttxw" }, + { "351446b4d41bdb708a8bc233f0583550fce2d4ad89baa4be2fc45ca7730de384", "xch1x52yddx5r0dhpz5tcgelqkp42r7w949d3xa2f030c3w2wucduwzqn7xl9j" }, + { "23ea384ae055e9958943d48cba6669a9faaa178bf321f77f09da05bff3dc1d53", "xch1y04rsjhq2h5etz2r6jxt5enf48a259ut7vslwlcfmgzmlu7ur4fs39f0h2" }, + { "25ce2e65578d72f69300713fdb43ec7fa94bf78ab1d7f6273be6d0a347bfebb4", "xch1yh8zue2h34e0dycqwylakslv0755hau2k8tlvfemumg2x3alaw6qfmk8zk" }, + { "723863646195f3050e56fdafa5bf9d01a31b91e674674981d16c107d34efbd6b", "xch1wguxxerpjhes2rjklkh6t0uaqx33hy0xw3n5nqw3dsg86d80h44sh2nsjs" }, + { "e51e6187bc071c7173e083e5ea3eb36f6d03fd448c2f1ed318de85c586a5ad40", "xch1u50xrpauquw8zulqs0j7504ndaks8l2y3sh3a5ccm6zutp4944qqjwwytt" }, + { "989307afe29190ffe087a6101116b5b8c773c35a3e0f7b103f2b7d116a5894d6", "xch1nzfs0tlzjxg0lcy85cgpz944hrrh8s668c8hkypl9d73z6jcjntqls8tsj" }, + { "ff7a61aad6fb28fce630bc04009a19aa6066434bdeead946c0220eb00c71695c", "xch1laaxr2kklv50ee3shszqpxse4fsxvs6tmm4dj3kqyg8tqrr3d9wq6d4t9z" }, + { "f89bc4a51779c38c95d3e29b44c17d7be4730f0557f02d8e4e5f176ee4a84216", "xch1lzduffgh08pce9wnu2d5fsta00j8xrc92lczmrjwtutkae9gggtqmt99xc" }, + { "344c4484d3d95b561d56b9356c4dcd10dd11d6f42bababa5f998f36a9d7a3d46", "xch1x3xyfpxnm9d4v82khy6kcnwdzrw3r4h59w46hf0enrek48t684rqg2n5gr" }, + { "58e0c37d3050c0929befd80c25ac7b2f51558d0f43b00622a04f66091cb91038", "xch1trsvxlfs2rqf9xl0mqxzttrm9ag4trg0gwcqvg4qfanqj89ezquq02jncp" }, + { "39f031182acb448cb5bb19610b9cf4b061832749db7b5d28b6ec5ae8b54d2c6e", "xch188crzxp2edzgeddmr9ssh885kpscxf6fmda4629ka3dw3d2d93hqdynryv" }, + { "966be2905bdaafc01d294066badbfc620ccfb41d03edbec109949bba7ef19fa0", "xch1je479yzmm2huq8ffgpnt4kluvgxvldqaq0kmasgfjjdm5lh3n7sqq9p9p2" }, + { "6b1b2a6b5469b3420e59b063c8a8575238c4e2e855f23630504167f7c270685b", "xch1dvdj5665dxe5yrjekp3u32zh2guvfchg2hervvzsg9nl0snsdpdscg6a0p" }, + { "3121d2390d087e052f97c7d373b86bc8ef1c6e3612a572317e5c1f5fe3f7ae24", "xch1xysaywgdpplq2tuhclfh8wrterh3cm3kz2jhyvt7ts04lclh4cjq95j4xn" }, + { "070c439d1fd0f4dbf8818d417d407225d0b83aebc8de899d60ebdcdb278b3f74", "xch1quxy88gl6r6dh7yp34qh6srjyhgtswhter0gn8tqa0wdkfut8a6q96tggx" }, + { "b1b177e2316b97014b759c27d78db56d9b6dc4989ee87982dbba86a93f15190a", "xch1kxch0c33dwtszjm4nsna0rd4dkdkm3ycnm58nqkmh2r2j0c4ry9qcrex3q" }, + { "de724cc2dc9610b99e33b912cea0a95cbcd78edd442c58bc6b86809901685b13", "xch1meeyeskujcgtn83nhyfvag9ftj7d0rkagsk930rts6qfjqtgtvfsa039fn" }, + { "c49e7a716c4c794b324694663d4cccea67b1b74cee1eb17564e3026e8cee1964", "xch1cj085utvf3u5kvjxj3nr6nxvafnmrd6vac0tzatyuvpxar8wr9jqclnhqm" }, + { "d77c97d89a90e6fe7dcf10819446c62ecb00190ac6fe95d1ae90d7437b770eac", "xch16a7f0ky6jrn0ulw0zzqeg3kx9m9sqxg2cmlft5dwjrt5x7mhp6kqspd6kh" }, + { "14776f84272743694a9c78411b72001278e0cc2139514af4116ee6773dd5aeb5", "xch1z3mklpp8yapkjj5u0pq3kusqzfuwpnpp89g54aq3dmn8w0w4466scmert6" }, + { "988c20bdf34f75fbfba127597f745a0c72a7fad85422e1235f257576cfc1864e", "xch1nzxzp00nfa6lh7apyavh7az6p3e207kc2s3wzg6ly46hdn7pse8q7zjhpq" }, + { "8e2d0bb3f8f55423e7a84dce5d5482890aa670fbc71633d55c4025554fcc4a21", "xch13ckshvlc742z8eagfh8964yz3y92vu8mcutr842ugqj42n7vfgss28cesp" }, + { "7304b9176af0be636cc55fb70804fd0cfc5bf21c9b2e77e7ac9cc0ff810856a4", "xch1wvztj9m27zlxxmx9t7mssp8apn79husunvh80eavnnq0lqgg26jqylz4ts" }, + { "c08fb0bcb0ad5555d34bf95291d01aff9ac2879b48a3c1ec07d02618598137ab", "xch1cz8mp09s4424t56tl9ffr5q6l7dv9pumfz3urmq86qnpskvpx74sk9j6wu" }, + { "edffd355f1a031b4de96997cd95649ac86b0f7e04f9ad6f9f640d46b09002a31", "xch1ahlax4035qcmfh5kn97dj4jf4jrtpalqf7ddd70kgr2xkzgq9gcs5lawnl" }, + { "166f47315a684fa6418a324d4fb72c35e2c601c506126177299675dccd5ef187", "xch1zeh5wv26dp86vsv2xfx5ldevxh3vvqw9qcfxzaefje6aen277xrs2jq4m0" }, + { "fdba8cb3e84cd4865f7a70f40b0c981556305b2aac794871e7f2bfa2743511c5", "xch1lkagevlgfn2gvhm6wr6qkrycz4trqke243u5su0872l6yap4z8zs42hhgq" }, + { "ce875fa4499adf2ebdd7959183ad94e16d46869f14bfef1a60a60626d0a4094c", "xch1e6r4lfzfnt0ja0whjkgc8tv5u9k5dp5lzjl77xnq5crzd59yp9xqswxp5h" }, + { "352547da79879f1016a9ce5d238853a90b0829eb94ce69bfc4421b932360f950", "xch1x5j50knes703q94feewj8zzn4y9ss20tjn8xn07yggdexgmql9gqe2vk4k" }, + { "e3d0c99b334cd1170e0e96c9387bd88ec422eca3e25390e2effcb0ec4d0118bc", "xch1u0gvnxenfng3wrswjmyns77c3mzz9m9ruffepch0ljcwcngprz7qn0tecv" }, + { "ba5da8d5914a73bf25f7bfe7a1fbdec3e3fed0fab0d9b889bdcfc9f23ab16217", "xch1hfw634v3ffem7f0hhln6r777c03la586krvm3zdaelylyw43vgtsm3yl8r" }, + { "89f8169e6462885d329e6279e34986ef0a10d6791e6309e72395297c930480c2", "xch138upd8nyv2y96v57vfu7xjvxau9pp4nere3sneerj55heycysrpqed6kyh" }, + { "370bf7c805e41a5569f2246d80fb5a021604d696c922fb5553a094a0fe4dbb3f", "xch1xu9l0jq9usd9260jy3kcp766qgtqf45key30k42n5z22pljdhvlsvm5v5k" }, + { "b0022d1726a46e927e7513cf594735b2a27ec52a83bdda652f9fd8063dd0224a", "xch1kqpz69ex53hfyln4z084j3e4k238a3f2sw7a5ef0nlvqv0wsyf9qlh2t4q" }, + { "5dd23a33676e0d7587d03f5a441b4a7025d81aa66a864ed47aebb06bf5e75b14", "xch1thfr5vm8dcxhtp7s8adygx62wqjasx4xd2rya4r6awcxha08tv2qrs0w2m" }, + { "9e510b9a47d465b851c6107e440a8367402ea38054e09a6016e15c00b84883b8", "xch1negshxj863jms5wxzplygz5rvaqzaguq2nsf5cqku9wqpwzgswuqlryz0e" }, + { "1b2dd52d180f7bc161b198d6a0bea4fc536f6a044690a0a51fa4b2191c6b949d", "xch1rvka2tgcpaauzcd3nrt2p04yl3fk76syg6g2pfgl5jepj8rtjjwsdxrx5q" }, + { "4a054b91fd024cf51e9aaf1521f1d4fcbff7b72a0b733bb48908b40547413e27", "xch1fgz5hy0aqfx028564u2jruw5ljll0de2pdenhdyfpz6q236p8cnsv83kgk" }, + { "c1817447ff8848e6d0b197f564c09b48858134b940fea2e44813e8a9d16d3d36", "xch1cxqhg3ll3pywd593jl6kfsymfzzczd9egrl29ezgz052n5td85mqwjr7d2" }, + { "c1bd1967a1eefaf52ffb64145160512a29ac41e5158880fc47b2c7d817b67e81", "xch1cx73jeapama02tlmvs29zcz39g56cs09zkygplz8ktras9ak06qs5h6ucm" }, + { "3a1f599d44cab4268d74b94e91e4f974afeda073339318980dab90d3e90774fa", "xch18g04n82ye26zdrt5h98fre8ewjh7mgrnxwf33xqd4wgd86g8wnaq67pcvd" }, + { "66a5fe92cf20f7932b6f0bf6760770a9ca5f005d918a326112dd0beb6cb900ad", "xch1v6jlayk0yrmex2m0p0m8vpms48997qzajx9rycgjm597km9eqzksgv0rae" }, + { "56321a85ce4765b5a76d67d04f9f336cec56dc61bbf8d2e9fe387d1058f4d2aa", "xch12cep4pwwgajmtfmdvlgyl8endnk9dhrph0ud96078p73qk85624qqylxg8" }, + { "4c896dc7096057538f6a9eaf5b2cefdc233069d2828019b7aa304e54098b7111", "xch1fjykm3cfvpt48rm2n6h4kt80ms3nq6wjs2qpnda2xp89gzvtwygsqzc3ta" }, + { "5d5ca17a80f224cece764324c195a9db8c0ed94714f2a145399d31c6dfb03fa1", "xch1t4w2z75q7gjvannkgvjvr9dfmwxqak28zne2z3fen5cudhas87ssarawny" }, + { "439cafe6e03207169b230b3dc53f598ff290a84192b9bf3b1693b094d0289890", "xch1gww2lehqxgr3dxerpv7u206e3lefp2zpj2um7wckjwcff5pgnzgqeqvztj" }, + { "c69ba7e619a5ec9ed351f96638189e5d1924dd058bbaaa1ad8df876ab71f37ae", "xch1c6d60ese5hkfa563l9nrsxy7t5vjfhg93wa25xkcm7rk4dclx7hqvwm7g9" }, + { "c238cb240ca043dfee5741f88892b034fc5ecc662778089b84a20f0c5226d0ed", "xch1cguvkfqv5ppalmjhg8ug3y4sxn79anrxyauq3xuy5g8sc53x6rkspe7tg0" }, + { "e300c413984c92b358f384a918258036b573351f649e0236fa1916f566f26b2e", "xch1uvqvgyucfjftxk8nsj53sfvqx66hxdglvj0qydh6ryt02ehjdvhqy06clv" }, + { "b36ef08111a5e8c82e1d51e020166dd23a4d28c1afde97be03b7e65c62a7a83c", "xch1kdh0pqg35h5vstsa28szq9nd6gay62xp4l0f00srkln9cc484q7qngd0mu" }, + { "a5f12c1035f8e14a66ca18e80fcbb8a3b2ec378fd35633733c0510c332329c3d", "xch15hcjcyp4lrs55ek2rr5qljac5wewcdu06dtrxueuq5gvxv3jns7sexk8sq" }, + { "6e400110e4826db5426e2495fc4faaa1275a934cd5c8f293b708afb48d61f742", "xch1deqqzy8ysfkm2snwyj2lcna25yn44y6v6hy09yahpzhmfrtp7apq3qp0u5" }, + { "6f158da2ad22c92e186ee6c16c7313789c819381e287e7477ca28f563befbe03", "xch1du2cmg4dytyjuxrwumqkcucn0zwgryupu2r7w3mu5284vwl0hcpsy8cses" }, + { "c80fdcfdaa9d1cfe03add6e4dc17001a11d980e094aee8f2d304139c3abb1860", "xch1eq8aeld2n5w0uqad6mjdc9cqrgganq8qjjhw3uknqsfecw4mrpsqutrd8u" }, + { "57c208e0f7782b9e8fc60e998e5ca2c8b0e43f77bacb783eab1656e64fa631fd", "xch12lpq3c8h0q4ear7xp6vcuh9zezcwg0mhht9hs04tzetwvnaxx87sgkq0ru" }, + { "fc56c3deef7ed52e80f1a2372525f950458c6130460cd8fba60bde931b2eeda7", "xch1l3tv8hh00m2jaq835gmj2f0e2pzcccfsgcxd37axp00fxxewaknsyyfscd" }, + { "8ee3d70214fb266010541d471018b54acae380f5956a7fbfcd3ea3bc858cd6d7", "xch13m3awqs5lvnxqyz5r4r3qx94ft9w8q84j448l07d863mepvv6mts6zctmy" }, + { "dcee8c785e53e2892f46ca2a7e9d185bdb3c765b6d49608b52dc95c48d6ab363", "xch1mnhgc7z7203gjt6xeg48a8gct0dncajmd4ykpz6jmj2ufrt2kd3s8t6w6j" }, + { "9831709d3b10c7c84c3738841b904e14db0efb811f3475e69d2b7f52345d4789", "xch1nqchp8fmzrrusnph8zzphyzwzndsa7upru68te5a9dl4ydzag7ysj422ru" }, + { "e398c4f1435b847a5526ca3db610c852760f320708309f6636d3f1d023c63988", "xch1uwvvfu2rtwz854fxeg7mvyxg2fmq7vs8pqcf7e3k60caqg7x8xyqeqrgqd" }, + { "6cb2a610b8f5678c31883909addeb794b5e780bc06e1d21ac1646710eb4ace2d", "xch1dje2vy9c74nccvvg8yy6mh4hjj670q9uqmsayxkpv3n3p662ecks7wkx8j" }, + { "b93f4bf1c11586498507166da4bbb8896c5b25b727d7082fec85640da577435b", "xch1hyl5huwpzkrynpg8zek6fwac39k9kfdhyltsstlvs4jqmfthgddsjhdnwu" }, + { "ef556a6143797ce1687db6e5afe75fbf8b62a0728378b73708256b9dee29b04e", "xch1aa2k5c2r097wz6rakmj6le6lh79k9grjsdutwdcgy44emm3fkp8qtwyvgm" }, + { "48412bf8825cb7c69f3cddd308ca0da14d2c9c1368348958b62729ce100dae54", "xch1fpqjh7yztjmud8eumhfs3jsd59xje8qndq6gjk9kyu5uuyqd4e2qdjrvnj" }, + { "e5b844d8b09221dd36c36f8afae512889c437c79871c993bef658061097697ca", "xch1ukuyfk9sjgsa6dkrd7904egj3zwyxlresuwfjwl0vkqxzztkjl9qn740my" }, + { "9b48a4066e7044fcc9ccc49e11f5f52c15df3c1cad04b693d9dbc013d11d591d", "xch1ndy2gpnwwpz0ejwvcj0pra049s2a70qu45ztdy7em0qp85gatywshykaap" }, + { "321d76a528a07c7f2785db13c4d742cba9fe71d33c4e9e41198f5116f832f98d", "xch1xgwhdffg5p787fu9mvfuf46zew5luuwn838fusge3ag3d7pjlxxs5lk63f" }, + { "d62097bba0d222a3096880b4982ce8199539959a2463c98a4b804a3e082fbaf4", "xch16csf0waq6g32xztgsz6fst8grx2nn9v6y33unzjtsp9ruzp0ht6q57u45z" }, + { "629b744492fc32273f4e318249c24757d52922bce088bf9c121680847ef9d955", "xch1v2dhg3yjlsezw06wxxpynsj82l2jjg4uuzytl8qjz6qgglhem92sdxxcer" }, + { "c03decd2732b45b1f49ea3b5da0c272e46f8705a974b6163e096782dd6bfdfd1", "xch1cq77e5nn9dzmray75w6a5rp89er0suz6ja9kzclqjeuzm44lmlgsqdynhc" }, + { "52f0919c668eaa7a1a2a1bf88970eaa3a110b3240cd59aa23ab5ff2e95e7f1c4", "xch12tcfr8rx36485x32r0ugju825ws3pveypn2e4g36khlja90878zqmcmjvz" }, + { "84fb3c9bea595f2ee146f8fa1c5230376a5e13b8cf9d4d0a6dab4eef0bb53f9f", "xch1snanexl2t90jac2xlrapc53sxa49uyace7w56znd4d8w7za4870s2jpda4" }, + { "dd16ff0d785e7256b509abe15a8937d37f6402663cb904e59610d0cd60548fce", "xch1m5t07rtctee9ddgf40s44zfh6dlkgqnx8jusfevkzrgv6cz53l8qr7t9x6" }, + { "a28cbd088d52dc399f8769c90ed7c6407412dad175ec673498733e6d0dd23055", "xch152xt6zyd2twrn8u8d8ysa47xgp6p9kk3whkxwdycwvlx6rwjxp2secguqy" }, + { "2be9db14eff865db73d5fd7167433e68dff667dcb7b1c670ef703922b1afa4bf", "xch1905ak980lpjaku74l4ckwse7dr0lve7uk7cuvu80wquj9vd05jls5w8krm" }, + { "e601b1133424cb7b376a5ee656f645e1435ce2493ccbe971996040148f2763ff", "xch1ucqmzye5yn9hkdm2tmn9daj9u9p4ecjf8n97juvevpqpfre8v0lsyrclvy" }, + { "4ccc4d260a2880591cc6a1d2ff62e0b5ae2d04a5f65b43c8396887668f0af312", "xch1fnxy6fs29zq9j8xx58f07chqkkhz6p997ed58jpedzrkdrc27vfqrvl9q7" }, + { "7145909a8c06a4f2a9cd851016bfcdf98a2173e01c8da6de5568a7af75c556a4", "xch1w9zepx5vq6j092wds5gpd07dlx9zzulqrjx6dhj4dzn67aw926jq7h4axm" }, + { "afce48a671b3dd4d8b65002612031566562d3e8cf444720d441185b4e9db3121", "xch14l8y3fn3k0w5mzm9qqnpyqc4vetz605v73z8yr2yzxzmf6wmxyssjcru7t" }, + { "2a98f214b81d9aac9a15867b1ffafd3a7e39902809e79c0cb087787881d91fd4", "xch192v0y99crkd2exs4sea3l7ha8flrnypgp8necr9ssau83qwerl2qtemnwk" }, + { "110efe19df4b3bccf3d9ca23b5d249419d1f199c41eb92a6763bfde5e7abfbe7", "xch1zy80uxwlfvaueu7eeg3mt5jfgxw37xvug84e9fnk8077teatl0ns679szp" }, + { "3f750d35eaa0dd9e3f22038c546f6fafc5924cf3cd285be9cd7e98d5706eb8a4", "xch18a6s6d025rweu0ezqwx9gmm04lzeyn8ne559h6wd06vd2urwhzjqwaz4aa" }, + { "bc26dc6ffa043ec8c9409893d5387901695951d9eb8bbd9bf00b7fe1639d2d23", "xch1hsndcml6qslv3j2qnzfa2wreq954j5weaw9mmxlspdl7zcua953sy3e42g" }, + { "16a564067ab6c665a755773e799581c05a1f601588b57d580b7bf03cf1f9461d", "xch1z6jkgpn6kmrxtf64wul8n9vpcpdp7cq43z6h6kqt00creu0egcwsgaq5r0" }, + { "8e4e7bad3ad05a44d9ddcef72bdafdefd68c19167787a019f87dec54dcb11e7c", "xch13e88htf66pdyfkwaemmjhkhaaltgcxgkw7r6qx0c0hk9fh93re7qpxpkhx" }, + { "44d8e4e0e0ec9527ceab3703841436515d65ec227b460218239a33b1fa22c786", "xch1gnvwfc8qaj2j0n4txupcg9pk29wktmpz0drqyxprngemr73zc7rquypv7q" }, + { "870658843f4cb122efebfb4d0eb753e075b2c6021930e49da6c760d9ed7f2614", "xch1sur93pplfjcj9mltldxsad6nup6m93szrycwf8dxcasdnmtlyc2qt88sqv" }, + { "7db61b091934761d8157af1cd780d96a1feeba90e93281fe2f0b9a683dba992b", "xch10kmpkzgex3mpmq2h4uwd0qxedg07aw5sayegrl30pwdxs0d6ny4sr77usj" }, + { "3e6fc446e338d5f90bec5084b0322273aef4c09192054de9b1f27929a65e1679", "xch18ehug3hr8r2ljzlv2zztqv3zwwh0fsy3jgz5m6d37fujnfj7zeusadgl4s" }, + { "a5755567dfdc11fc63e12e2ca7a90c44f648208a65b7422d085feb5808a04e51", "xch154642e7lmsglcclp9ck202gvgnmysgy2vkm5ytggtl44sz9qfegsw40fhw" }, + { "a4d087900f2874f246444648a308e4bb95c0c0fe172703484f393b59b03b26b6", "xch15ngg0yq09p60y3jygey2xz8yhw2ups87zunsxjz08ya4nvpmy6mqghewhg" }, + { "44da0d7ea7ceba27a5da9390d9c4cdc214672268f6615cf8242cb3ab4d501b39", "xch1gndq6l48e6az0fw6jwgdn3xdcg2xwgng7es4e7py9je6kn2srvuskztm0n" }, + { "75f170df5668bbd17cf3efc4cda06e447aa0dbbb9312ba2c28a1743259bcb226", "xch1whchph6kdzaazl8nalzvmgrwg3a2pkamjvft5tpg596rykdukgnq2nuf4k" }, + { "f9362c7184dddb6e7b5fbec43a718c766c628e5d721c2a3eff6ea50557af1fcf", "xch1lymzcuvymhdku76lhmzr5uvvwekx9rjawgwz50hld6js24a0rl8s9j6ga8" }, + { "0bd7c1edcec268f57bdd24a2ffa4b002ec24005c2b27b63715ad8acfab28dcfe", "xch1p0turmwwcf50277ayj30lf9sqtkzgqzu9vnmvdc44k9vl2egmnlqx446vg" }, + { "8c1159550a0575413e875e2590f4f670ee0f06c8520fca26d2900d76f1609785", "xch13sg4j4g2q465z058tcjepa8kwrhq7pkg2g8u5fkjjqxhdutqj7zspe82zl" }, + { "7e09fd9c5c0c783ff3e64410eb8aaefd8c4428bf75413423eb888f08fd62556d", "xch10cylm8zup3urlulxgsgwhz4wlkxyg29lw4qngglt3z8s3ltz24ksdurku3" }, + { "037d1881e646c91c258b330e9706e7306aed39e08c3cdf58d9c3ecc94044886f", "xch1qd733q0xgmy3cfvtxv8fwph8xp4w6w0q3s7d7kxec0kvjszy3phsj06gjg" }, + { "b9157d37f8a774cee923ebbe80ab8e6137957ffc6412eafb676b32b52f6491ee", "xch1hy2h6dlc5a6va6frawlgp2uwvyme2lluvsfw47m8dvet2tmyj8hqpyur98" }, + { "a34bb05d48cf71cd8136b214208a0f00e4347c89b8e049428b242b6ae90afdf1", "xch15d9mqh2geacumqfkkg2zpzs0qrjrglyfhrsyjs5tys4k46g2lhcsh4vy8q" }, + { "c6e8e7768a3fc56e3bd1ecfb70f1ace50d1340987c6790c937bd7a4b122ddd3b", "xch1cm5wwa528lzkuw73anahpudvu5x3xsyc03nepjfhh4ayky3dm5asytnsc7" }, + { "6a468a3ea9728348c2ff91d8b2d5768c065caba9c9bde9b34f2da0385f963b0f", "xch1dfrg504fw2p53shlj8vt94tk3sr9e2afex77nv609ksrshuk8v8s76dkxc" }, + { "9440fe2a06d7079da10d85103fe48af8f1ef5d9f7c6fcd912fcdee638191f08d", "xch1j3q0u2sx6uremggds5grley2lrc77hvl03humyf0ehhx8qv37zxsrysym3" }, + { "c39786bafce251f9ab3fc8eef475896f870dc24a3ee08ecdeef95348a8cd16fb", "xch1cwtcdwhuufgln2elerh0gavfd7rsmsj28msgan0wl9f532xdzmascs2sje" }, + { "d33e48a28c90f4e83ece8ef56d16c803f534c97e5f08844160209e95e20c2e90", "xch16vly3g5vjr6ws0kw3m6k69kgq06nfjt7tuyggstqyz0ftcsv96gqm0eus2" }, + { "104fd1a80bfd6481786569d86df372621c75348a1c90b58b2c77709c0b62c1ee", "xch1zp8ar2qtl4jgz7r9d8vxmumjvgw82dy2rjgttzevwacfczmzc8hqmdcq99" }, + { "1a8758a2d9f8004ee55937cbfbfcfb32f18d82123259946bbd4dcb05f07e8a09", "xch1r2r43gkelqqyae2exl9lhl8mxtccmqsjxfveg6aafh9stur73gysjx93xh" }, + { "c49a0845962cb847ada1038ed031e1b7f32108e69ee217f0c770bb214875f967", "xch1cjdqs3vk9juy0tdpqw8dqv0pklejzz8xnm3p0ux8wzajzjr4l9nstdyhlx" }, + { "b2670a160a79596851b01e43f2e0b6cdaa5553cb429e782743767ddd7ec5e97a", "xch1kfns59s209vks5dsrepl9c9kek49257tg208sf6rwe7a6lk9a9aqger2zz" }, + { "634546a541c8240166069faeaff9049c3464e4e1a702db81e8e2b31cbed699bc", "xch1vdz5df2peqjqzesxn7h2l7gyns6xfe8p5updhq0gu2e3e0kknx7q490an7" }, + { "4457d14a803319393b148b448ecd8c4ff118eea7acef80b3a4e852f3d4c6b4f2", "xch1g3tazj5qxvvnjwc53dzganvvflc33m484nhcpvayapf084xxkneq872mfm" }, + { "73225f05a371f03cbc545a8c3646267684dfd46224c0a1909cbefbde1d4695e6", "xch1wv397pdrw8cre0z5t2xrv33xw6zdl4rzynq2ryyuhmaau82xjhnqs67yf4" }, + { "7a39af038a0258e85ab0af5493a48c9b8dcdb50f892cd95adb85b2a607316092", "xch10gu67qu2qfvwsk4s4a2f8fyvnwxumdg03ykdjkkmske2vpe3vzfqns95s5" }, + { "a773d41ec67961c8e3c960ac5d7dd77aa550baa16ee9a2cf55890f111688d798", "xch15aeag8kx09su3c7fvzk96lwh02j4pw4pdm569n643y83z95g67vqgt8xd0" }, + { "2c8106109473f8eff8b43b6ba242e5f7f9530f3b6f919266f6d88d0fdcf5c503", "xch19jqsvyy5w0uwl7958d46ysh97lu4xremd7geyehkmzxslh84c5psjlgpaa" }, + { "7ce770e03f1d08ffd2ce5f5ebcea3bff02a0f69ecb23d8374d527867f6997474", "xch10nnhpcplr5y0l5kwta0te63mlup2pa57ev3asd6d2fux0a5ew36qs3fumf" }, + { "c67c0d3f1a1ddb1ee01db17dfb1c9f8dcc55cc73b64fd20b4c89f5f28d6ea8de", "xch1ce7q60c6rhd3acqak97lk8yl3hx9tnrnke8ayz6v386l9rtw4r0qllx7ru" }, + { "2192bd744d293501766b4cd6203883cbc8fefc2aeabfbf4d707ea23f572407e8", "xch1yxft6azd9y6szantfntzqwyre0y0alp2a2lm7nts063r74eyql5qr3rd5v" }, + { "abc093e1704adcbcff1066b85bc47091e34b8da0809183144d002eb356ae9931", "xch140qf8ctsftwtelcsv6u9h3rsj835hrdqszgcx9zdqqhtx44wnycs2d7ttg" }, + { "68e4a482930b4c42be625a99d1140d6104e59b9a2e5b01342de4c6c811660d94", "xch1drj2fq5npdxy90nzt2vaz9qdvyzwtxu69edszdpdunrvsytxpk2quew3eh" }, + { "79fea79dde4a548c0555e533b1cee9dcd127f06e497e24fcd5f4d908423d46e6", "xch108l208w7ff2gcp24u5emrnhfmngj0urwf9lzflx47nvsss3agmnqqhgnv2" }, + { "6a78d6e55f7ff2eeda08c52dadc6d956f60137c408aacffbbb9a8b907813522e", "xch1dfudde2l0lewaksgc5k6m3ke2mmqzd7ypz4vl7amn29eq7qn2ghq998qxc" }, + { "dc81222558555b80fceb1f094a4fbd2637075f950b811c591ea4fb18ddc229cd", "xch1mjqjyf2c24dcpl8truy55naaycmswhu4pwq3ckg75na33hwz98xs2rdnut" }, + { "f62fdc6c0d3e550ad87ebefa6df4f99a6a412d5713514646a33566deae616613", "xch17chacmqd8e2s4kr7hmaxma8enf4yzt2hzdg5v34rx4ndatnpvcfsvd706h" }, + { "7e382fb4fac8c1b48c5228c4e3652a06915a42b9c1ae0956f1e77ecb5980674f", "xch10cuzld86erqmfrzj9rzwxef2q6g45s4ecxhqj4h3ualvkkvqva8s7hcjs3" }, + { "b51bb990523ead64c9f0829ae5f334bf142466d8a877dfc0c104fa6bd3e6b783", "xch1k5dmnyzj86kkfj0ss2dwtue5hu2zgekc4pmalsxpqnaxh5lxk7psrh9vqx" }, + { "749926c8c9fda4f40f50209d4673d3c41164ffc1e44620abb835d443efb322c9", "xch1wjvjdjxflkj0gr6syzw5vu7ncsgkfl7pu3rzp2acxh2y8manytystgattd" }, + { "c737fd5e51128205a1203634f787acb901367701398fc290f87853bea95b9ee6", "xch1cuml6hj3z2pqtgfqxc600pavhyqnvacp8x8u9y8c0pfma22mnmnqxvc8zv" }, + { "3f3966c3a0efee9478bc62ae81b295837798c24dd08906a7b5566a548a4f7021", "xch18uukdsaqalhfg79uv2hgrv54sdme3sjd6zysdfa42e49fzj0wqssrxt7k5" }, + { "c67ad576943db070aaabdcfca6be9bb86d882313637b7138b6d8476022b06205", "xch1cead2a558kc8p24tmn72d05mhpkcsgcnvdahzw9kmprkqg4svgzsx3jc5e" }, + { "d29cf31da701868a2a5c2df168bf53731fee3d1a19452299bd928f084d346454", "xch162w0x8d8qxrg52ju9hck306nwv07u0g6r9zj9xdaj28ssnf5v32qd9eh8u" }, + { "98fc37ddc4e598ec966ae85923738ea7afb258d0affb5864dc9c8114cd2734de", "xch1nr7r0hwyukvwe9n2apvjxuuw57hmykxs4la4sexunjq3fnf8xn0qjzw2tt" }, + { "8728dad713765b9d056ab936e26dafbf9194ae2f4e8c8bdbe96bb69eb933205a", "xch1su5d44cnwede6pt2hymwymd0h7geft30f6xghklfdwmfawfnypdqzcux6m" }, + { "7ea8a5b4f23d9b2a7c831465351037c257e2ceda70e15c652c6abf504d1e006b", "xch10652td8j8kdj5lyrz3jn2yphcft79nk6wrs4cefvd2l4qng7qp4sr4zcq6" }, + { "394d4d5a10f26d5ee018efb4eb77b458fd0de9a2526853e933459cd5e096f77e", "xch189x56kss7fk4acqca76wkaa5tr7sm6dz2f5986fngkwdtcyk7alq9tca89" }, + { "ae1634a5d0a550310aee240ab381e56660ddfcbbdcbad30d206b40585d50e477", "xch14ctrffws54grzzhwys9t8q09vesdml9mmjadxrfqddq9sh2su3ms9055rx" }, + { "ba051dfb6e0e247785732ee33974afc85f79386bbdc6c61c95c513a34f90b9b7", "xch1hgz3m7mwpcj80ptn9m3nja90ep0hjwrthhrvv8y4c5f6xnushxms98ep0u" }, + { "c7febca1087ab3d54693d9f9d8f76c6098b767856872f6f25408d0db4ecb8c42", "xch1cllteggg02ea235nm8ua3amvvzvtweu9dpe0duj5prgdknkt33pq044pqf" }, + { "0a33a55e3fb4d9b8caa4159ab1fd5436219327e3018f8568fd04f895cb0291f6", "xch1pge62h3lknvm3j4yzkdtrl25xcsexflrqx8c268aqnuftjczj8mqkcd0p9" }, + { "96651689d267bd1d04b3c5ef21e0235f026862f286ed2d8f22434eba68be1c5c", "xch1jej3dzwjv7736p9nchhjrcprtupxschjsmkjmrezgd8t5697r3wqt78at0" }, + { "44feee47cd13d62f9a1227ca99049d4a6f5d9c6ae55b995332696122e8431824", "xch1gnlwu37dz0tzlxsjyl9fjpyaffh4m8r2u4dej5ejd9sj96zrrqjqe6mflm" }, + { "d901c9200f17d51c42931d1242e61ff7a2632bd7cddb25f8f166a398ff3bfd45", "xch1myqujgq0zl23cs5nr5fy9esl773xx27hehdjt783v63e3leml4zsctps6y" }, + { "34bdbd4c5be52ea22ecc8732cafbf461cf78cfbb01d3329ae5a5354e1b2f0607", "xch1xj7m6nzmu5h2ytkvsuev47l5v88h3namq8fn9xh95565uxe0qcrsc892dr" }, + { "eb716ba19e5a75cb873a899d4f728221141a4dba1e0720c600dde9aaee09208e", "xch1adckhgv7tf6uhpe63xw57u5zyy2p5nd6rcrjp3sqmh564msfyz8q2jjkhx" }, + { "324671778f388833e8eecb0e9d5247a1b1d7b13699bae9908f29d588b7b98708", "xch1xfr8zau08zyr868wev8f65j85xca0vfknxawnyy0982c3daesuyq2y597u" }, + { "520e3cd3af5a90b69cc2853300b9d34eaab6cb6b4ecb489d8bc5b6bb79afda50", "xch12g8re5a0t2gtd8xzs5espwwnf64tdjmtfm9538vtckmtk7d0mfgq3zegtq" }, + { "e7d061b35d19581a1f567c929af5c302c10162c638611fb1d2c6c89082dd3d9b", "xch1ulgxrv6ar9vp586k0jff4awrqtqszckx8ps3lvwjcmyfpqka8kdsphh0au" }, + { "1c357003bfa3569075bc2543a5200e722ed442b18b08dba4fb675c03889ab473", "xch1rs6hqqal5dtfqaduy4p62gqwwghdgs433vydhf8mvawq8zy6k3eshdlp4v" }, + { "35a864af7e717a1fc7eaec567325288b54538ea7cd4544ca724065b51c9255e2", "xch1xk5xftm7w9apl3l2a3t8xffg3d298r48e4z5fjnjgpjm28yj2h3qp89f3j" }, + { "54dd0cb2fb25a03131a908e1ea0978ec112180721c09d4e545e9931611d07a7f", "xch12nwsevhmyksrzvdfprs75ztcasgjrqrjrsyafe29axf3vyws0fls4zlm5m" }, + { "194a8957ac37c92a63e10fe997c3fe1e7ca9e0f358f38a4a0f7517074f9d6a1c", "xch1r99gj4avxlyj5clppl5e0sl7re72nc8ntrec5js0w5tswnuadgwqrz9dhp" }, + { "3c399f2e55a81c8fcabaa90b8fa99ec92bb0faed7ea6e950be9a8040f9106472", "xch18sue7tj44qwglj464y9cl2v7ey4mp7hd06nwj597n2qyp7gsv3eqzehfdx" }, + { "4ad31982c5444e7dbaa17d2d8db12dac57ec3d6a2c10c1749756d2da4bf2c74f", "xch1ftf3nqk9g388mw4p05kcmvfd43t7c0t29sgvzayh2mfd5jljca8sns7kj7" }, + { "7f76cb4f779edb8e9bd877af6d6bd9ee1345d6e28378caa91cf3fb05d20cb092", "xch10amvknmhnmdcax7cw7hk667eacf5t4hzsduv42gu70ast5svkzfqsn8t52" }, + { "cf9e09899a88c5a1074fafd3a1760fd340bd8a9d6d7ac6dd35dbeeafda4bfda4", "xch1e70qnzv63rz6zp604lf6zas06dqtmz5ad4avdhf4m0h2lkjtlkjqdqned0" }, + { "6038a84d9da932cd6328549bfa81934158520371a7f4f8fdd57f843fd41b4f37", "xch1vqu2snva4yev6ceg2jdl4qvng9v9yqm35l603lw407zrl4qmfumswkjw98" }, + { "6c469ae21ac525c78ef713487db1f454cd9d1b50af16ca4fd41c99a9f0e062dd", "xch1d3rf4cs6c5ju0rhhzdy8mv052nxe6x6s4utv5n75rjv6nu8qvtwsj7x06m" }, + { "55a8b2e8374a4b9afb80bd131761e431ec5d667f5ff757acb8db8cc9977c84bd", "xch12k5t96phff9e47uqh5f3wc0yx8k96enltlm40t9cmwxvn9musj7sju3stl" }, + { "fc0b2c3b247b806ddb356c7c34e4677b6886976b6b695dcc6bce93765f4ceb1d", "xch1ls9jcwey0wqxmke4d37rfer80d5gd9mtdd54mnrte6fhvh6vavws4ve86y" }, + { "04f86e09f12a594f953c5f9307bb051593567fbc86cb353a8a070217e9fa0429", "xch1qnuxuz039fv5l9fut7fs0wc9zkf4vlausm9n2w52qupp0606qs5szl8940" }, + { "f4e07c8d585f43ce1e1d8742a190d90619c9b35aab3dfd13aac1cfd2e5bf74c8", "xch17ns8er2ctapuu8sasap2ryxeqcvunv664v7l6ya2c88a9edlwnyqp3xdju" }, + { "5ec14a64c7765480abe899f29a3c5acfc6464303157931293722d8777e737425", "xch1tmq55ex8we2gp2lgn8ef50z6elryvscrz4unz2fhytv8wlnnwsjsxm2whw" }, + { "2cd47b4580045857429544995005915e06a666424f633f2f8e0323b5d726e3b4", "xch19n28k3vqq3v9ws54gjv4qpv3tcr2vejzfa3n7tuwqv3mt4exuw6qxz3y8f" }, + { "fc19017ca468165bf7669554f856c332473a35f4ad07893a800f9e788c2989ed", "xch1lsvszl9ydqt9hamxj420s4krxfrn5d0545rcjw5qp7083rpf38ks2uy0zc" }, + { "ba9329bf9b462b0f89d9020e5bbec28e7f42848d621bc99bec8c5143effabc5f", "xch1h2fjn0umgc4slzweqg89h0kz3el59pydvgdunxlv33g58ml6h30smuu36j" }, + { "231ed880c7edb327ff2f7b0e068970ba3d369fe83537b189ddb9b7f73a85a228", "xch1yv0d3qx8akej0le00v8qdztshg7nd8lgx5mmrzwahxmlww595g5qnnhtup" }, +}; + +const AddrHashTestPair TestTestnetAddress[500] = { + { "9740b064a2302220c3667b74f6ea2e3354e8a8a2da396a7d82ed40b6b638752f", "txch1jaqtqe9zxq3zpsmx0d60d63wxd2w329zmguk5lvza4qtdd3cw5hs7zd2m9" }, + { "7d58f2ff9ce54f0772ae37cfc31d3fac957ef11aa275909b5a4c84ff4f8cfca0", "txch104v09luuu48swu4wxl8ux8fl4j2haug65f6epx66fjz07nuvljsqwm9gk5" }, + { "6b6420ed999f8a9836b236d45c52b712a9d9629097d2b19b3af41dd67dbd64ef", "txch1ddjzpmven79fsd4jxm29c54hz25ajc5sjlftrxe67swavldavnhsa3kjz0" }, + { "c683cd02c13b1ab5598a0190d6c31f868a3369d9f22f3362747e0eed69c4faf1", "txch1c6pu6qkp8vdt2kv2qxgddscls69rx6we7ghnxcn50c8w66wyltcsutc03h" }, + { "a72b31143023e2fd82cb815120452734df543b904aff3777686798c2cfa4f4a2", "txch15u4nz9psy030mqkts9gjq3f8xn04gwusftlnwamgv7vv9nay7j3qxa2jyh" }, + { "ed8b62a526f8f7ac30af299b5b155015db5a90519e67bb2461bab918df3b23f6", "txch1ak9k9ffxlrm6cv909xd4k92szhd44yz3nenmkfrph2u33hemy0mqh9j0f4" }, + { "5ee6a0aeb0a3db3ef3eeddb3b857268735fd043677643b1f11a329c0703a45d2", "txch1tmn2pt4s50dnaulwmkems4exsu6l6ppkwajrk8c35v5uqup6ghfqh5xa5h" }, + { "cae5b086517618d3f86d063ee0b66f37dee25e6abd1f2e63d28e16fec4d7d9a5", "txch1etjmppj3wcvd87rdqclwpdn0xl0wyhn2h50juc7j3ct0a3xhmxjs99er75" }, + { "1affc3e9e1c30e32841b21ce83b105997ffe7a617122117d7ab808670288131e", "txch1rtlu860pcv8r9pqmy88g8vg9n9llu7npwy3pzlt6hqyxwq5gzv0qds5sva" }, + { "a53c24f80164cc584cb28d89490f169cc26ceaf8341bbcb9b78975da89115457", "txch1557zf7qpvnx9sn9j3ky5jrcknnpxe6hcxsdmewdh396a4zg323tsf9yqxe" }, + { "d72eeee892abd9916ce89730797b394783119d43dc006684e5146cadf8c30cb9", "txch16uhwa6yj40vezm8gjuc8j7eeg7p3r82rmsqxdp89z3k2m7xrpjusdysza9" }, + { "03514a85c196ce777093c69cc69cb8bf9d724d239ef61dbc768d854482797e0c", "txch1qdg54pwpjm88wuync6wvd89ch7whynfrnmmpm0rk3kz5fqne0cxqrp8gyh" }, + { "3a859aa73dada3a210b8652b3e5531ed0d972c7cc5f294b8abf86366921cc68e", "txch182ze4fea4k36yy9cv54nu4f3a5xewtrucheffw9tlp3kdysuc68qw267ca" }, + { "954dd27ad1461ca3c909c9c7f150fd30d8851d9bc6cff85eb96a967f3ee1994f", "txch1j4xay7k3gcw28jgfe8rlz58axrvg28vmcm8lsh4ed2t870hpn98s7uv0p2" }, + { "9da7baf5cfbeec642ef5c0dc8b74f4a0e342d3f851473a36143192956a7c5f00", "txch1nknm4aw0hmkxgth4crwgka855r3595lc29rn5ds5xxff26nutuqqpm7848" }, + { "87eda63a803edf4d05333a540d5793a31cb88d906de8468d129199fb387eef3b", "txch1slk6vw5q8m056pfn8f2q64un5vwt3rvsdh5ydrgjjxvlkwr7auase0p3jy" }, + { "1d1a46775742b6c2bad5ae7d0c0dadbc410d72eb04482ae1b1bc5e41a02ff333", "txch1r5dyva6hg2mv9wk44e7scrddh3qs6uhtq3yz4cd3h30yrgp07vesgz9jm9" }, + { "a526da787c604cdfedf3978c9ac67518c919708242fdee7855cb010c64a6161e", "txch155nd57ruvpxdlm0nj7xf43n4rry3juyzgt77u7z4evqsce9xzc0qmgkdvr" }, + { "f51e78fbc2600418bd4975df0404421906cae1617d14c89ddd213058f2c38cba", "txch17508377zvqzp302fwh0sgpzzryrv4ctp052v38wayyc93ukr3jaqw0cgam" }, + { "e54e66dff6201c30296c4b722cfbf35ae0755b8735150506a54b7eb2543dd4e6", "txch1u48xdhlkyqwrq2tvfdeze7lntts82ku8x52s2p49fdlty4pa6nnqpsetra" }, + { "e012ee4a99a2844a6da36afba048e18424d8639aef4b5a874a2507d15d1cd7e6", "txch1uqfwuj5e52zy5mdrdta6qj8pssjdscu6aa944p62y5razhgu6lnq20nh58" }, + { "4bdc971e2d178123b6449037eca08acd09973a616dec5df97f12945b52ce15eb", "txch1f0wfw83dz7qj8djyjqm7egy2e5yewwnpdhk9m7tlz229k5kwzh4s4n27t6" }, + { "b7076adfbc95f7576380ef52205af483fcffe3c013893eec7097c9393665a18f", "txch1kurk4haujhm4wcuqaafzqkh5s070lc7qzwynamrsjlynjdn95x8scyu047" }, + { "d0e77f7caa113285793f544885c3767fa620fa225b53ecd4fa35e18c3b465719", "txch16rnh7l92zyeg27fl23ygtsmk07nzp73ztdf7e486xhsccw6x2uvsvd8nqu" }, + { "2fa684730e18f8fdf74f96f9d2af1073261e3da9b3988504ba0335bffced67ef", "txch197nggucwrru0ma60jmua9tcswvnpu0dfkwvg2p96qv6mll8dvlhscdzwqh" }, + { "60bc978d7e30fc254ba9c68d44a47e5b39850e44e0a953b25761297dcb8c125f", "txch1vz7f0rt7xr7z2jafc6x5ffr7tvuc2rjyuz548vjhvy5hmjuvzf0sxaemr4" }, + { "655e61bda2037174e6d3f13b96238ad5fc4fd5f56e6cca3efb4ef83cb676ab95", "txch1v40xr0dzqdchfekn7yaevgu26h7yl404dekv50hmfmurednk4w2slqdjqy" }, + { "5cc2875c6ba7477ec3b2305a25793ee3df9558e98e0e510807c28474a420db9f", "txch1tnpgwhrt5arhasajxpdz27f7u00e2k8f3c89zzq8c2z8ffpqmw0sjjr36r" }, + { "6a9fbbc8a51d5e6b2e0159d154bbf03304bae73f61d9956445910a3422682405", "txch1d20mhj99r40xktspt8g4fwlsxvzt4eelv8ve2ez9jy9rggngyszslzd6xe" }, + { "d7f2bcbe92ab30a871d90cf7ce25a7f22858c4f0f7b79cdb74e2eb39f134710b", "txch16lete05j4vc2suwepnmuufd87g59338s77meekm5ut4nnuf5wy9s5gx5u8" }, + { "be909944d70bab89576d125fd278e6bd0e7dd0f03037173a4837aae2262d3668", "txch1h6gfj3xhpw4cj4mdzf0ay78xh588m58sxqm3wwjgx74wyf3dxe5q566uay" }, + { "da2cd08a17ea231b316366e5175eda9c6a7ca3173c098eeee59e8749213dfe35", "txch1mgkdpzshag33kvtrvmj3whk6n348egch8sycamh9n6r5jgfalc6scerce0" }, + { "44eddfc72368d05786aacccd2ce7add7f6eb32de86379572de9150ea8a234a34", "txch1gnkal3erdrg90p42enxjeead6lmwkvk7scme2uk7j9gw4z3rfg6qdj5h3q" }, + { "7b254b6d62a14d9b4840a7b177c6383999969db0ffe514ddbce70b975e443fad", "txch10vj5kmtz59xekjzq57ch033c8xved8dsllj3fhduuu9ewhjy87ks5gygj2" }, + { "9307afb221b7033a0f999144dca3f94b2cd8c8b78cabff270c7ad94c9ba6b4df", "txch1jvr6lv3pkupn5ruej9zdeglefvkd3j9h3j4l7fcv0tv5exaxkn0s6l66qc" }, + { "2c0918b148dcf3fb140e761d1b01a8aeb8d0792e0b379f03f4e0f5af907853cf", "txch19sy33v2gmnelk9qwwcw3kqdg46udq7fwpvme7ql5ur66lyrc208sj8s085" }, + { "1dea37e0131038c645b97724e73b147a00bfb6f7521f5f53419610de89fc75b4", "txch1rh4r0cqnzquvv3dewujwwwc50gqtldhh2g04756pjcgdaz0uwk6q8qv6j7" }, + { "96ced6560348bbbd92ad022588108a83830671c74336c45145eff732c9f054c8", "txch1jm8dv4srfzammy4dqgjcsyy2swpsvuw8gvmvg529almn9j0s2nyq8k4p2q" }, + { "87044e21b34e43ec877e096a23b1141f09e7a444f7699b75b21bea278ec54968", "txch1suzyugdnfep7epm7p94z8vg5ruy70fzy7a5ekadjr04z0rk9f95qyxpksa" }, + { "5fe7d8c2e81ead3ac3a42f8f901fd76dc27827abde64777871949485e32c57d7", "txch1tlna3shgr6kn4say978eq87hdhp8sfatmej8w7r3jj2gtcev2ltsp8scz2" }, + { "429e51f3f02cd75f68cb31a25713646883443de2c2a137b501bc8c52c37c0ee3", "txch1g209ruls9nt476xtxx39wymydzp5g00zc2sn0dgphjx99smupm3s6m04fl" }, + { "21db91c2e9140a36c0591af3930ce491326df318319e20872482a7c02c8e1bb9", "txch1y8dershfzs9rdszerteexr8yjyexmuccxx0zppeys2nuqtywrwus703fmy" }, + { "f586e51cca48903fcaef4d185bed3b0cf5665d6adc0be3d79d382c47334faec6", "txch17krw28x2fzgrljh0f5v9hmfmpn6kvht2ms9784ua8qkywv604mrq5pr0c9" }, + { "f09bf6fe4c0fb0d368c8dee3c42a5ef1f16347e92ce962224e323810ac5b5269", "txch17zdldljvp7cdx6xgmm3ug2j778ckx3lf9n5kygjwxgupptzm2f5sd9hm40" }, + { "62053d9eeef9adde72ce12ebcccaab5ddda52363c30961750b3f3f4bed0ddf0a", "txch1vgznm8hwlxkauukwzt4uej4tthw62gmrcvykzagt8ul5hmgdmu9qsvrg2s" }, + { "12e035a9499bc44b6287bf9953f7d24ec0e1d6485714814af48ead004e72aa1f", "txch1ztsrt22fn0zykc58h7v48a7jfmqwr4jg2u2gzjh536ksqnnj4g0sklp9sw" }, + { "97a2b1627e49fdcc4079bc14fd2d342fa3057062e6e5b12ae48bffd10d28570b", "txch1j73tzcn7f87ucsrehs206tf5973s2urzumjmz2hy30lazrfg2u9s0ss0x0" }, + { "934460fe5f05616a7258ed48070143aab99fa476255d806071010847a7d0fae9", "txch1jdzxpljlq4sk5ujca4yqwq2r42uelfrky4wcqcr3qyyy0f7slt5szhfz9a" }, + { "4b66c9230416e9e21e7dabcb3e7e30354ea42071d8ea4aefb1001ce9b98177e5", "txch1fdnvjgcyzm57y8na409nul3sx482ggr3mr4y4ma3qqwwnwvpwljsz79ttl" }, + { "59882b007bfa255796cd3196f50fbafd4319bc84a373a1da64ea4647fda787b5", "txch1txyzkqrmlgj409kdxxt02ra6l4p3n0yy5de6rknyafry0ld8s76s2f77r0" }, + { "996a5fdfa47093de8ccec1ae913e7baa0cf0b97927004e78918485d0128b1ced", "txch1n949lhaywzfaarxwcxhfz0nm4gx0pwteyuqyu7y3sjzaqy5trnksqhzk5h" }, + { "c9c992ea785f799d74cf1494422bf82521dc0a555109e94cdc2cb15d0110bc46", "txch1e8ye96nctaue6ax0zj2yy2lcy5saczj42yy7jnxu9jc46qgsh3rqylpdn8" }, + { "7a0dffdf5bad7ebdaec7e580b8c17e480a95f9e0e2428bfb28dadc7f8993f9f1", "txch10gxllh6m44ltmtk8ukqt3st7fq9ft70qufpgh7egmtw8lzvnl8cs7w6uvj" }, + { "8c28a725777d7b8c7ec38508dffd7132a3916bc68615b527a9fceece39d32708", "txch13s52wfth04acclkrs5ydllt3x23ez67xsc2m2faflnhvuwwnyuyqzqhg9m" }, + { "f22f82c2f383d426d08c12e66206a47492b454d705e7ebbeea629eb2614d6423", "txch17ghc9shns02zd5yvztnxyp4ywjftg4xhqhn7h0h2v20tyc2dvs3s26y27v" }, + { "db6256bafb51cc1d32c12de0855153117d7a8571b811d9e2ab4d8ac323895d7b", "txch1md39dwhm28xp6vkp9hsg252nz97h4pt3hqganc4tfk9vxguft4asfhpkuz" }, + { "e2e83cb9cbe79897982227d2326d879df28fb16e3fac48d1ec46cb5149ec8cbb", "txch1ut5rewwtu7vf0xpzylfrymv8nheglvtw87ky350vgm94zj0v3jaszl8skh" }, + { "6ea1108e481fe642b5156f50741aac0cf2af681e56b3305c13e1023e70c3d93f", "txch1d6s3prjgrlny9dg4dag8gx4vpne276q726enqhqnuypruuxrmylsglkhw2" }, + { "39381074715a78f730d3001bb16bbaaa2ef6da102a5e0a1bc259787c2d197ff7", "txch18yupqar3tfu0wvxnqqdmz6a64gh0dkss9f0q5x7zt9u8ctge0lms7tyv42" }, + { "6bfb85b9922121b894011d4ccba5cf29456f5b5e8d30d8fff18a47894c9b2c94", "txch1d0actwvjyysm39qpr4xvhfw099zk7k6735cd3ll33frcjnym9j2qc644lp" }, + { "a61467de45044f891865c08fd12e6d6b4370e15ab9b20dc606551b5a08621c8d", "txch15c2x0hj9q38cjxr9cz8aztndddphpc26hxeqm3sx25d45zrzrjxsucmpxm" }, + { "380519b0ea190821b0cf3160d7b349bc98dd4452431143abbb39d8bb0ab1e3f9", "txch18qz3nv82ryyzrvx0x9sd0v6fhjvd63zjgvg582am88vtkz43u0us95arzc" }, + { "6d692255a4cee014d476ccb2049ca1c08f2365ae182bffe83e8d78256136992c", "txch1d45jy4dyemspf4rkejeqf89pcz8jxedwrq4ll6p734uz2cfknykqe7e26h" }, + { "ee3b39c1f4a2397d11d2e7effd23deff2eb2d302a885b5b920d5fd74d98fb3c6", "txch1acanns055guh6ywjulhl6g77luht95cz4zzmtwfq6h7hfkv0k0rqas3zvk" }, + { "b8427e46d02f5315206e51514b1a7b6ab2d270d9f9a0684979f3d11a35e6b49a", "txch1hpp8u3ks9af32grw29g5kxnmd2edyuxelxsxsjte70g35d0xkjdqnjz4y4" }, + { "26942ef547f39480c9453ce90e1910aa3c652f40f89730abe336b7f9b76d58d3", "txch1y62zaa287w2gpj298n5suxgs4g7x2t6qlztnp2lrx6mlndmdtrfs90upan" }, + { "f389205493272364d364eb0265b042d77e0961014d6855dd2a20686c8ac6f6ba", "txch17wyjq4ynyu3kf5myavpxtvzz6alqjcgpf459thf2yp5xezkx76aq05z9vy" }, + { "a7b399251379bb2241da200b79387c294d15bccafc6a49939f0db86d92a58485", "txch157eejfgn0xajysw6yq9hjwru99x3t0x2l34ynyulpkuxmy49sjzsxpwu29" }, + { "bcf2307c7f846ad073259f4c9c99da866c8f11a4840471deee62b7be55d6f39a", "txch1hnerqlrls34dque9naxfexw6sekg7ydyssz8rhhwv2mmu4wk7wdqcyju7q" }, + { "939b5277c236ef35c9ed224780911f28bb7c85bf010955bf193e1cf2bd78852b", "txch1jwd4ya7zxmhntj0dyfrcpygl9zahepdlqyy4t0ce8cw090tcs54sfudvgf" }, + { "c63bfa5e4026826d89c1557656b7eadbc7a507d82bfef9cb49a05e25f24c5644", "txch1ccal5hjqy6pxmzwp24m9ddl2m0r62p7c90l0nj6f5p0ztujv2ezqdu4xpl" }, + { "b9aac918d526ae4d344b2743fb11145378b608fd2793bcdf7ce92713fbc51e53", "txch1hx4vjxx4y6hy6dztyaplkyg52dutvz8ay7fmehmuayn38779refssw9xx5" }, + { "b01c4f12eb4c6d61497f550689ae403b20de3a097d94cae5defb19ace2a4e18a", "txch1kqwy7yhtf3kkzjtl25rgntjq8vsduwsf0k2v4ew7lvv6ec4yux9q3qezlw" }, + { "64a0b6c19513fbfe48b7a6c67c029e9156a28b91661226181570de47ab8871e2", "txch1vjstdsv4z0aluj9h5mr8cq57j9t29zu3vcfzvxq4wr0y02ugw83qvpewy9" }, + { "ba4e48f7ebe669b4aa2b796a03cc9e71d9960fe8e5e8ea7465053cd8826e130c", "txch1hf8y3altue5mf23t094q8ny7w8vevrlguh5w5ar9q57d3qnwzvxqqskyke" }, + { "da838468e3d8cd7e7f33aaad338dfb59f2d29b46df84f440fd16376082121a1d", "txch1m2pcg68rmrxhulen42kn8r0mt8ed9x6xm7z0gs8azcmkpqsjrgwsruyrts" }, + { "ec68dded73e358d02a9861c918f6b461a90d949e99b09a21a0f143277c4350a4", "txch1a35dmmtnudvdq25cv8y33a45vx5sm9y7nxcf5gdq79pjwlzr2zjqn4v9fy" }, + { "8624505193ad2cbcc4c74a6c087db48d14e2f918c73636fe23e4c52403f02922", "txch1scj9q5vn45kte3x8ffkqsld5352w97gccumrdl3runzjgqls9y3qswdrtu" }, + { "7505a9d3992b56e1dbcf85acc6dd6665b4837e5653c5ab47527cdd6b2913adfa", "txch1w5z6n5ue9dtwrk70skkvdhtxvk6gxljk20z6k36j0nwkk2gn4haq8zkdl9" }, + { "6e3be66204aa63ce6848c6338ae438e8b7733f128a76c4e532bdefeba13749ce", "txch1dca7vcsy4f3uu6zgccec4epcazmhx0cj3fmvfefjhhh7hgfhf88qyfa9kz" }, + { "73950fe45954e0cddfb3a1514c46ba6775594faaa179463348816f38facc3587", "txch1ww2sleze2nsvmhan59g5c346va64jna259u5vv6gs9hn37kvxkrsy08wqa" }, + { "a052e3438faabfc90d8742d4d88cf3bfae9a6eb8a87b4e88842acd1e6382b7bf", "txch15pfwxsu042lujrv8gt2d3r8nh7hf5m4c4pa5azyy9tx3ucuzk7lswcth9y" }, + { "62455ffb132c43c4325cb2e3ce0484a2b9b4fa711055d2b059e549a73d77e0e5", "txch1vfz4l7cn93pugvjukt3uupyy52umf7n3zp2a9vzeu4y6w0thurjsnykav3" }, + { "25bc77435a42aa03b13651db0996aadda2862206391d52bdae1a3e55654eb436", "txch1yk78ws66g24q8vfk28dsn942mk3gvgsx8yw490dwrgl92e2wksmqw9fkld" }, + { "ab5138403a5b8935a0895e2c87aee8b11efac6e2001c7461026331f4a90e7f05", "txch14dgnssp6twyntgyftckg0thgky0043hzqqw8gcgzvvclf2gw0uzst6wmlq" }, + { "21d6df7761cf2d188faa44ca67369443f7ff1e514e7b35bf80765d486d0122aa", "txch1y8td7ampeuk33ra2gn9xwd55g0ml78j3feant0uqwew5smgpy24qfgnpv7" }, + { "05f517d053e21137b4500f9f0a365133703b56fc3b1e9ffd0bc609bd10cc0a00", "txch1qh6305znuggn0dzsp70s5dj3xdcrk4hu8v0fllgtccym6yxvpgqqkuhzfl" }, + { "9e84529a061b137c3a90c395911f3fa2a67f844a0b784a84f4251e1883c85c69", "txch1n6z99xsxrvfhcw5scw2ez8el52n8lpz2pduy4p85y50p3q7gt35sj7gaxa" }, + { "43408de4f1688bd046a761ed77507e2a48aed88a30237bacda8f3e00a7f3fe30", "txch1gdqgme83dz9aq348v8khw5r79fy2aky2xq3hhtx63ulqpflnlccqnqycd9" }, + { "2d70254d2ce797ac9e1bc5df07bbef75cb7b6e6f158597fdb4942068f914cb54", "txch194cz2nfvu7t6e8smch0s0wl0wh9hkmn0zkze0ld5jssx37g5ed2qn4fgnz" }, + { "1b34072d54cb48d6517bf9dbe4ec08d9cfcd06f54b85247829ec7b0e37b921e3", "txch1rv6qwt25edydv5tml8d7fmqgm88u6ph4fwzjg7pfa3asudaey83sv2fs44" }, + { "9d9c55b171d997e816fbb54c6edc2099d693a5fab77ce3b21a762c5f2cf9cfdc", "txch1nkw9tvt3mxt7s9hmk4xxahpqn8tf8f06ka7w8vs6wck97t8eelwqvu9632" }, + { "2ef6b069a98ae9681df42cff25be127dcc6f39800a3171e61ce948d44beae72f", "txch19mmtq6df3t5ks8059nljt0sj0hxx7wvqpgchresua9ydgjl2uuhs7s30fm" }, + { "a818023c89d9dd1baeea11a7fc286e393711559e3a3cc7cdf2e4e11c01b7f648", "txch14qvqy0yfm8w3hth2zxnlc2rw8ym3z4v78g7v0n0juns3cqdh7eyq5znu0f" }, + { "a7f0745526a3f697f5aeee8ac99a6cf14e16d4fc8b079cd30e8594ebcfc62672", "txch15lc8g4fx50mf0adwa69vnxnv798pd48u3vree5cwsk2whn7xyeeqvjtcy4" }, + { "9f1b2377d8d831180aee6955206f825f63da070cebb4983aa41047813e156e4d", "txch1nudjxa7cmqc3szhwd92jqmuzta3a5pcvaw6fsw4yzprcz0s4dexsfpvw04" }, + { "1657370338675862f10a48b558d6eaafbeae752b98533282ee9e62aca332fe1a", "txch1zetnwqecvavx9ug2fz6434h247l2uaftnpfn9qhwne32egejlcdqcn6884" }, + { "3d7f13e3c3e1c44875e4675d49e820dcce559d1fe0cd3e849bcba02b5b36ba76", "txch184l38c7ru8zysa0yvaw5n6pqmn89t8glurxnapymewszkkekhfmqmpseq6" }, + { "fe5c7b1821954cd0a3d7bef5f115c5d5d03aaad52c21e54f9fcf8704ec291706", "txch1lew8kxppj4xdpg7hhm6lz9w96hgr42k49ss72nule7rsfmpfzurq9rwmmu" }, + { "9c47944883008f5887c6657f758d12c06b2b5eed0b61e9804f79ca76f7f07a53", "txch1n3regjyrqz843p7xv4lhtrgjcp4jkhhdpds7nqz00898dals0ffseacd4l" }, + { "8c8e7194daac0b0199cfaef2d3c9395b176dcf196753a7968cd8857bed592625", "txch13j88r9x64s9srxw04med8jfetvtkmncevaf6095vmzzhhm2eycjsvwz2yn" }, + { "f754bd9704b6e0c8b1ee909d2350e0600da8466bb258487feccde619cdb6cf23", "txch17a2tm9cykmsv3v0wjzwjx58qvqx6s3ntkfvysllvehnpnndkeu3syl0k63" }, + { "4b1770ac6bfa05e55dcef10d55378c9f53795a89ab2b162f04fd377e4bf22caf", "txch1fvthptrtlgz72hww7yx42duvnafhjk5f4v43vtcyl5mhujlj9jhsvs7xcw" }, + { "ccc415d6c69ad8bc1f2d1f97d59bdf2122ce3763008d5e476bfac09a160fc9ad", "txch1enzpt4kxntvtc8edr7tatx7lyy3vudmrqzx4u3mtltqf59s0exksv7f0m5" }, + { "c4e2689fab5126b1ad360f7b73911865322dc0bca97258d9f98e876019aed125", "txch1cn3x38at2yntrtfkpaah8ygcv5ezms9u49e93k0e36rkqxdw6yjs6wfme3" }, + { "95f3aeff540f3b0772df0127db387a8e64040858edb81bbd81dc8ae4efcbfeb8", "txch1jhe6al65puaswuklqynakwr63ejqgzzcakuph0vpmj9wfm7tl6uqrg869t" }, + { "86fcccef9397887daa3826991d3465145c81ccf323edba948c5654e6c58a92fc", "txch1sm7vemunj7y8m23cy6v36dr9z3wgrn8ny0km49yv2e2wd3v2jt7qh6ux77" }, + { "baacf6cc242ad9ec11ae4c61d107bc3e2da4be34053f72ec09dd2e6e7cd06891", "txch1h2k0dnpy9tv7cydwf3sazpau8ck6f035q5lh9mqfm5hxulxsdzgsakrxuh" }, + { "a4080fa2af74f7c623bcefefe0a4e8a688e5bc899572cc13b59afc7bed08a913", "txch15syqlg40wnmuvgaualh7pf8g56ywt0yfj4evcya4nt78hmgg4yfsrr6mrg" }, + { "9ccc237e0b8b32d123e9b969929fad47df09565f71a86f3c62074a56ba2ac8e0", "txch1nnxzxlst3vedzglfh95e98adgl0sj4jlwx5x70rzqa99dw32ersqvjgmpq" }, + { "b06469f07df7745febc5f8026a0f273ef042117c5859ac378276a84b74ae9034", "txch1kpjxnura7a69l679lqpx5re88mcyyytutpv6cduzw65yka9wjq6qn7cuhe" }, + { "3d58607deec9a8f3f2f3736bb94ebc2279df2e587bc2fd2b6ed3ec280e4854d6", "txch184vxql0wex508uhnwd4mjn4uyfua7tjc00p062mw60kzsrjg2ntqheazal" }, + { "44548d4e7fcb038c2087a01e75934ff881de8db53df638b0612bd57b2a1c1f9b", "txch1g32g6nnlevpccgy85q08ty60lzqaard48hmr3vrp902hk2sur7dsvfgf87" }, + { "2635f7702c0b2572a9efb173b5244eca5b218e85cf42d88b61d2207448dbff69", "txch1yc6lwupvpvjh9200k9em2fzwefdjrr59eapd3zmp6gs8gjxmla5ssj6ueh" }, + { "4a7eec2af54565b02b97a5554f59758b87e83333c40d6c43f12e86ae94912c1c", "txch1fflwc2h4g4jmq2uh54257kt43wr7svencsxkcsl396r2a9y39swqwmz27r" }, + { "5ad21d476bae2b0f6828ace21fbcfac478d7f2fa64f9ea2c81891abfa3f2b993", "txch1ttfp63mt4c4s76pg4n3pl086c3ud0uh6vnu75typ3ydtlgljhxfs4ecc7k" }, + { "83e1bc6ad3692c1de94287cef62de30e0be51457a691c0ec7c0b5fbe3b50c49f", "txch1s0smc6kndykpm62zsl80vt0rpc9729zh56gupmrupd0muw6scj0ssjugqj" }, + { "cdfaa0af702d633786dff157eb16cb78c15bb762ec57b56fd862b9e522b78039", "txch1eha2ptms943n0pkl79t7k9kt0rq4hdmza3tm2m7cv2u72g4hsqusme39mn" }, + { "6136c036d7b60ebea703a5eeb183e92813661cb70da5fa22d6d921d7df47fd9e", "txch1vymvqdkhkc8tafcr5hhtrqlf9qfkv89hpkjl5gkkmysa0h68lk0qfsa4gp" }, + { "efaf7bcee0e299ac9004ce11668df62fe6c04ae5f8e75a4002f441d242096707", "txch1a7hhhnhqu2v6eyqyecgkdr0k9lnvqjh9lrn45sqz73qayssfvursj0afp9" }, + { "b9bc6233bed3810896f3d056cbbe8992875845c6c9566649cb5d110dbe867800", "txch1hx7xyva76wqs39hn6ptvh05fj2r4s3wxe9txvjwtt5gsm05x0qqqhqzaj6" }, + { "f82cc440ccf543c70128ffc2415a14fe554116618349f45dee245d8546e07f73", "txch1lqkvgsxv74puwqfgllpyzks5le25z9npsdylgh0wy3wc23hq0aes9jl5u5" }, + { "c03496a3d175738fcb68b7d473f6c321c7f123edc93f521709f4a280ff261c95", "txch1cq6fdg73w4ecljmgkl288akry8rlzgldeyl4y9cf7j3gplexrj2sg2kq3e" }, + { "daff021f3e5f42e77981777b9b8a04bf05c798adc3a1852f305392e8fdceef43", "txch1mtlsy8e7tapww7vpwaaehzsyhuzu0x9dcwsc2tes2wfw3lwwaapsk9uncj" }, + { "dee3978c1ce854df8b181c4cf356e8d392102c84155b96eea0bc3c3056096a08", "txch1mm3e0rquap2dlzccr3x0x4hg6wfpqtyyz4dedm4qhs7rq4sfdgyqlewjzh" }, + { "d8f1ba3302ce5033d844bbbb47233a32fe49b5f387cbbc23e1cdd79bf4b8fbeb", "txch1mrcm5vczeegr8kzyhwa5wge6xtlynd0nsl9mcglpehteha9cl04s4z0dc9" }, + { "fd60c1413f1f3dec1db5c1857346a8660d3b3077d1200ed53a352310d54fdedd", "txch1l4svzsflru77c8d4cxzhx34gvcxnkvrh6ysqa4f6x533p420mmwswdmj2c" }, + { "94914dd4f9ea78872473d325ac5cf57a21e07b94130e5fa7ecef667e50e61ce4", "txch1jjg5m48eafugwfrn6vj6ch840gs7q7u5zv89lflvaan8u58xrnjqrd6ye5" }, + { "1a424feee9e66f867ad17f1d4dc8e79bf67ae5e2eb1bea2e2486da77b458c535", "txch1rfpylmhfuehcv7k30uw5mj88n0m84e0zavd75t3ysmd80dzcc56sjuxww8" }, + { "756ea32e4c14b96ae9bef277aa049dc86564f45f0e012ef51844cc266075400f", "txch1w4h2xtjvzjuk46d77fm65pyaepjkfazlpcqjaagcgnxzvcr4gq8sj00vav" }, + { "0544e436e43fe7a63f267d350898a6d620eea7e7245fe6d9025defe5a982da3f", "txch1q4zwgdhy8ln6v0ex056s3x9x6cswafl8y307dkgzthh7t2vzmglstl2fnn" }, + { "de454c7d898a43f937aae8a768581196c4f0acb3be088e74693d331aba624d0a", "txch1mez5clvf3fpljda2aznkskq3jmz0pt9nhcyguarf85e34wnzf59qcle9v7" }, + { "1a03b3acf89f98bc8c05b8c1b25471e771c28a2085f02ceed5e01fff898b931c", "txch1rgpm8t8cn7vterq9hrqmy4r3uacu9z3qshczemk4uq0llzvtjvwqu7jjxn" }, + { "21719ceacca8e9582e77265f8f61d983a13f5a426ccea7ba27b49c4e21404aa1", "txch1y9cee6kv4r54stnhye0c7cweswsn7kjzdn820w38kjwyug2qf2ssnyhk7k" }, + { "fd37c7192b8dd4abb1c44d241d828ab4d1542bb18a5e5470471441d90e27a4b0", "txch1l5muwxft3h22hvwyf5jpmq52kng4g2a33f09guz8z3qajr385jcqcg0s62" }, + { "a1f8d9dc332263438d9f10128ee74327aa1445dfc299525365ebbbaf56bc8e67", "txch158udnhpnyf358rvlzqfgae6ry74pg3wlc2v4y5m9awa6744u3ens8cem8w" }, + { "ccc9712b45d6da9df002df8660ee935ea0d152ac702f795e4eca4c0e5dd0f112", "txch1enyhz2696mdfmuqzm7rxpm5nt6sdz54vwqhhjhjwefxquhws7yfqtnxvtu" }, + { "9a1bd7f94e8ab5cf6f3f88ba272bd4ed2ec0613f78e2b25506c111ad128e6663", "txch1ngda072w326u7mel3zazw275a5hvqcfl0r3ty4gxcyg66y5wve3shqd9lh" }, + { "4ab6d4dda06cd126006496b45ebe709f66c4852251bc9ef1aed1c33ac662e700", "txch1f2mdfhdqdngjvqryj669a0nsnanvfpfz2x7faudw68pn43nzuuqq4fdtw7" }, + { "98b1a626b0c798f68149dd81cac40ae1a42d4e6c82ac0b6f4b8c2e3720604658", "txch1nzc6vf4sc7v0dq2fmkqu43q2uxjz6nnvs2kqkm6t3shrwgrqgevqkmtv9l" }, + { "dd1a4a609eb22bcd25ef00d0a4515fdb973af39234c6a10658bc8e2050eafe90", "txch1m5dy5cy7kg4u6f00qrg2g52lmwtn4uujxnr2zpjchj8zq582l6gqs0k7c5" }, + { "8094b6678d468a511f809515493eec815bdff28eaf1586febad24730fa860717", "txch1sz2tveudg699z8uqj525j0hvs9dalu5w4u2cdl466frnp75xqutspp7u6u" }, + { "0ba0195b4947cc84e3a0abb63fd065cbfb21933b8ed0f0c18420b7079e2e92b5", "txch1pwspjk6fglxgfcaq4wmrl5r9e0ajryem3mg0psvyyzms083wj26svc5rsy" }, + { "0fdfbdc81bff7cc02a57553305199c0c67a5e38423900f1f79505fcc9116545e", "txch1pl0mmjqmla7vq2jh25es2xvup3n6tcuyywgq78me2p0ueygk230qgucr68" }, + { "5997f1b926bcd4a3a493e126fed47aac194ad84b3fd19b24ef0c53e581d1a6fe", "txch1txtlrwfxhn228fynuyn0a4r64sv54kzt8lgekf80p3f7tqw35mlq37r89x" }, + { "c06efc0dea762ec0781c4fc40a9a3d2649d2498c2debf8e6a8249a0e23371727", "txch1cph0cr02wchvq7quflzq4x3ayeyayjvv9h4l3e4gyjdqugehzunsqwfq5u" }, + { "405cad9783eea7e714b0e840a68e2e0dc5a7545ab6194afb551b3e43046b7a3e", "txch1gpw2m9ura6n7w99sapq2dr3wphz6w4z6kcv54764rvlyxprt0glqckz6w0" }, + { "8c055f4ef9370b28d6e94819ec3d5fde6abd1e48a4988c04262bca88bee7ece3", "txch13sz47nhexu9j34hffqv7c02lme4t68jg5jvgcppx909g30h8an3s5m7tyz" }, + { "42b0d631ac924f53d504aceeae56050a3f6eff507ca80d8a79946b134b666fb8", "txch1g2cdvvdvjf8484gy4nh2u4s9pglkal6s0j5qmznej343xjmxd7uq8k3293" }, + { "0185ed491a1ca31d522865abad724681d3ceb2f3e967c12b311952ddcd792ac0", "txch1qxz76jg6rj33653gvk466ujxs8fuavhna9nuz2e3r9fdmnte9tqqxc4p73" }, + { "da1b3212bdb2151cad1b39cc564e4102a8c62ec75701c4fb3669f41a65e66990", "txch1mgdnyy4akg23etgm88x9vnjpq25vvtk82uquf7ekd86p5e0xdxgqpa7wcc" }, + { "faf3431041713603f7a013aaa03e1d06b452679de390044a2c71d48fc9cbba02", "txch1lte5xyzpwymq8aaqzw42q0saq669yeuauwgqgj3vw82gljwthgpqqtuns2" }, + { "d595d979b349711212c758f7d74fae571c3c714caa8925a5bc0a6ddcfb37a2a8", "txch16k2aj7dnf9c3yyk8trmawnaw2uwrcu2v42yjtfdupfkae7eh525q8zt6zs" }, + { "e4ea59018d1f4f64e212f0d8974ef4c7d25c639e546aabc7da1f82a0c3ce4c57", "txch1un49jqvdra8kfcsj7rvfwnh5clf9ccu72342h376r7p2ps7wf3tsqw43wj" }, + { "8cd19d923ca953e0708e48ace2afca3f1c5d67acc81742b5de3fac599cc75b84", "txch13ngemy3u49f7quywfzkw9t728uw96eaveqt59dw787k9n8x8twzqr7g4nh" }, + { "1861ac5caab96d754d99b205490a24b8cca751c16a8f5effb0106c3c06da422a", "txch1rps6ch92h9kh2nvekgz5jz3yhrx2w5wpd284alaszpkrcpk6gg4qw0m5hu" }, + { "18f74d0fc362e16d8e73a9b222bb72e99626b4540969eaa6d3f6c659d496c714", "txch1rrm56r7rvtskmrnn4xez9wmjaxtzddz5p9574fkn7mr9n4ykcu2qjxn704" }, + { "5cc4851f319598a02635f92e970cf6eda677601ecc9426cbd31c7d72121216f7", "txch1tnzg28e3jkv2qf34lyhfwr8kakn8wcq7ej2zdj7nr37hyysjzmmsd8rdvd" }, + { "1469a51dfa021bea102e81938d41773526b8805fe2ab86df9f1f834447584f87", "txch1z3562806qgd75ypwsxfc6sthx5nt3qzlu24cdhulr7p5g36cf7rsaxmsv4" }, + { "31b12b3d0955f07605ddd7b8ef9ab1b1ccdbe46e73c9ff808716cce06b681ce1", "txch1xxcjk0gf2hc8vpwa67uwlx43k8xdherww0yllqy8zmxwq6mgrnss3das36" }, + { "7321e6b930631e41ab31141bd933105cf1ff2f20d899336caebad59041deb00a", "txch1wvs7dwfsvv0yr2e3zsdajvcstncl7teqmzvnxm9wht2eqsw7kq9qc5t8a3" }, + { "de8d36935a8aa0164b3320e0720f332d792a7467bfa7a49e2a02bc37a7e34410", "txch1m6xndy6632spvjenyrs8yren94uj5ar8h7n6f832q27r0flrgsgqrz6694" }, + { "6a8ba6116c8395ac69df0288f89becc1b0e0f625e8396dd5dbb82a223837455e", "txch1d296vytvsw26c6wlq2y03xlvcxcwpa39aqukm4wmhq4zywphg40qql0sy4" }, + { "4793b6ce8e685a3b2e6a452f18eedada00240fe30e85272056e3e75b02949939", "txch1g7fmdn5wdpdrktn2g5h33mk6mgqzgrlrp6zjwgzku0n4kq55nyus444tks" }, + { "9fa4525e2e684a9cb8639148d2ee6da627058c66b497e88a4aa288f95dc218cb", "txch1n7j9yh3wdp9fewrrj9yd9mnd5cnstrrxkjt73zj252y0jhwzrr9s88rphs" }, + { "3cf567b538703cc1a071ddea42962aa2145f239456a430a13f43bada7b725460", "txch18n6k0dfcwq7vrgr3mh4y99325g297gu526jrpgflgwad57mj23sqd7fkag" }, + { "0defb683e2387f24f0190965f5f8405b17662fad20b7953d95ae821cdee05f2a", "txch1phhmdqlz8pljfuqep9jlt7zqtvtkvtadyzme20v446ppehhqtu4qq4gsc3" }, + { "33af6a5aef0bfd0b23f0effe805203c96fa2424f4e5c548c27da33430ee4b119", "txch1xwhk5kh0p07skglsallgq5sre9h6ysj0few9frp8mge5xrhykyvsdxt8q9" }, + { "740e872c98a98d32c5a5b0192edd3fcc399edd40825b6beddd1bf98ae50c4070", "txch1ws8gwtyc4xxn93d9kqvjahflesueah2qsfdkhmwar0uc4egvgpcqr28pc9" }, + { "74cf919e65ae3d3d2cd2f2da8948f361bd712752f4fd0dd9aeae4288d7038361", "txch1wn8er8n94c7n6txj7tdgjj8nvx7hzf6j7n7smkdw4epg34crsdssuzhm22" }, + { "093e81dd994c4179ec32119b8e78653a0f5d9d3d247bd5c2ae482c6c97cc5568", "txch1pylgrhvef3qhnmpjzxdcu7r98g84m8fay3aats4wfqkxe97v245qf82a7s" }, + { "3629b05a8544c42a1a41db9c6106f0da71687908c16528ad6ff814080acd4cce", "txch1xc5mqk59gnzz5xjpmwwxzphsmfcks7ggc9jj3tt0lq2qszkdfn8qrjg4wu" }, + { "77223f922dee41bf395805cb0388b3804e02f5a678552d5a931a278a169d2814", "txch1wu3rly3daeqm7w2cqh9s8z9nsp8q9adx0p2j6k5nrgnc595a9q2qp03pg3" }, + { "60dd233a6f0fa4b9a156edadc3dc04c106d740317eb189c355efef85b023e17f", "txch1vrwjxwn0p7jtng2kakku8hqycyrdwsp306ccns64alhctvpru9lszxar6e" }, + { "4f1d29ab8876cd970f14d945094ad9ba35a062224c7e820801953136a0874615", "txch1fuwjn2ugwmxewrc5m9zsjjkehg66qc3zf3lgyzqpj5cndgy8gc2s0vpmzs" }, + { "daa44f58cdc43e8d3e093dc7f376ad900d0264b835c3d34288d52d49ec79e397", "txch1m2jy7kxdcslg60sf8hrlxa4djqxsye9cxhpaxs5g65k5nmreuwts5ht3a6" }, + { "d58fd57bff9b74ab1ce0e5672b3edfe330047d56178d9405ac3b1d192b41a276", "txch16k8a27llnd62k88qu4njk0kluvcqgl2kz7xegpdv8vw3j26p5fmqum6yrs" }, + { "34aee0738be6cf9e8048dfbac71d6d102e2d368054b667255343dcc6b072653c", "txch1xjhwquutum8eaqzgm7avw8tdzqhz6d5q2jmxwf2ng0wvdvrjv57qa6h09m" }, + { "354f8948f813b35fb3eb34ebc10b418571387baa51c6cd0625a47bf92be0f08e", "txch1x48cjj8czwe4lvltxn4uzz6ps4cns7a228rv6p3953alj2lq7z8qpf8y0l" }, + { "9d01b86c623ba77c567bd663300047a620f5b3dccfc38df4d93e6efd59e4e160", "txch1n5qmsmrz8wnhc4nm6e3nqqz85cs0tv7uelpcmaxe8eh06k0yu9sq4p3ljf" }, + { "122156f59514c858df507ee56fa7122d8c1adb8e6a456a7418199269dff42fe1", "txch1zgs4dav4zny93h6s0mjklfcj9kxp4kuwdfzk5aqcrxfxnhl59lssuqcr2d" }, + { "798236229cc4d7411328aa4d1a55a596f19bfd521bfd063a1b4676d630b2d35e", "txch10xprvg5ucnt5zyeg4fx354d9jmcehl2jr07svwsmgemdvv9j6d0qcuz53z" }, + { "45139c8ae7c8fb4cc7d100b455601349f472728ce7b9fc499bae56a802883a0f", "txch1g5feezh8era5e373qz692cqnf868yu5vu7ulcjvm4et2sq5g8g8sjlulfu" }, + { "42e590eb11d8a1bad6a123744c34b28ad002f376afb3729e750406dc52497162", "txch1gtjep6c3mzsm444pyd6ycd9j3tgq9umk47eh98n4qsrdc5jfw93qywp5at" }, + { "5f40e752c0ff524bc6d5ad89633a05cc4ce3e242b6ce1dcd7a32720fcf8d911c", "txch1taqww5kqlafyh3k44kykxws9e3xw8cjzkm8pmnt6xfeqlnudjywqtjfcnz" }, + { "4ce31293683f05c1b3c491d41cb4a9615504ce1358f96695b0ec1bbc7540493e", "txch1fn339ymg8uzurv7yj82ped9fv92sfnsntrukd9dsasdmca2qfylq0ylexk" }, + { "c455528f2a34be1e09590edb9d36908751608791cadf6b403d3124c8fe124aac", "txch1c3249re2xjlpuz2epmde6d5ssagkppu3et0kkspaxyjv3lsjf2kqpelyux" }, + { "098936507c93c4016534fdac95e1c198e4c748a12d5fdc4796610a7e156e0211", "txch1pxynv5ruj0zqzef5lkkftcwpnrjvwj9p940ac3ukvy98u9twqggsj6es0g" }, + { "eb9864e6675e128d16123680d20c53f43c8aaf66774873960b610f06ab9cc9f4", "txch1awvxfen8tcfg69sjx6qdyrzn7s7g4tmxway889stvy8sd2uue86qsuqc2d" }, + { "451deae07660740ef89f323c7f9411d0dd731223b01125757b1d838b16c1d997", "txch1g5w74crkvp6qa7ylxg78l9q36rwhxy3rkqgj2atmrkpck9kpmxtswywwpf" }, + { "d9d71344fad154b24013718f156efe0ec4b275eebc98cad37a2c608d9e519fe2", "txch1m8t3x386692tysqnwx832mh7pmztya0whjvv45m693sgm8j3nl3qym8394" }, + { "f0d2daef0225e09362053d187a94226c87d50523bbdd1f2e42fd6f12e2a43f82", "txch17rfd4mczyhsfxcs985v849pzdjra2pfrh0w37tjzl4h39c4y87pq82mq6d" }, + { "fface3a45d8389a9512b3f8f1760c404754fbafc7e5d7cdb3df2146dc6c8993c", "txch1l7kw8fzaswy6j5ft8783wcxyq365lwhu0ewhekea7g2xm3kgny7q6tafxq" }, + { "093d2107acb97c08fdca329e27c267645d0cad0bcb399c03f6ec00ab4cad33ea", "txch1py7jzpavh97q3lw2x20z0sn8v3wsetgtevuecqlkasq2kn9dx04qxrmf88" }, + { "8b34458cdd0c5fe94156814555f9dec7395acc2f5ddc8daf612e20c31c111d5b", "txch13v6ytrxap307js2ks9z4t7w7cuu44np0thwgmtmp9csvx8q3r4dst3078h" }, + { "be1a6079cb05ed60d2de489e31513dd7fc15bd997381df7f204ce7f139b76815", "txch1hcdxq7wtqhkkp5k7fz0rz5fa6l7pt0vewwqa7leqfnnlzwdhdq2sl72g60" }, + { "3e22b6ceacd5bc6940deb391bb66ef6fa77d83b042dd1ba5725b630f86f14ef9", "txch18c3tdn4v6k7xjsx7kwgmkeh0d7nhmqasgtw3hftjtd3slph3fmus0jx3wl" }, + { "37ea0b0bddac1744d9bf822ad894dc68c7f1364c7997b73f98db3475a7e4a985", "txch1xl4qkz7a4st5fkdlsg4d39xudrrlzdjv0xtmw0ucmv68tfly4xzstwsael" }, + { "5c6c5dc4767e0d283c667505d4d933ed147b22792a9c29b7e994e1173e4ad921", "txch1t3k9m3rk0cxjs0rxw5zafkfna528kgne92wzndlfjns3w0j2myssx0670u" }, + { "cb711d1a88a56ec1ac4ec7c1049d4bd071c7e341437362854a7654eb0fa69ab6", "txch1edc36x5g54hvrtzwclqsf82t6pcu0c6pgdek9p22we2wkraxn2mq4yvk0u" }, + { "c1c7ea7a35819f70bef6ceb8140c5a9f05771958defc841c0e8413c8af064c6f", "txch1c8r75734sx0hp0hke6upgrz6nuzhwx2cmm7gg8qwssfu3tcxf3hsdm2rmz" }, + { "dbddcb0983fd8448c037fe5d4b5aa4cd48162ef46d83d148f290a8c447b4a294", "txch1m0wukzvrlkzy3sphlew5kk4ye4ypvth5dkpazj8jjz5vg3a5522q3rnfap" }, + { "7cc8213c746bfe071afaadeadbb7a9172b249481ca7593f2e133ee95ee5c5075", "txch10nyzz0r5d0lqwxh64h4dhdafzu4jf9ypef6e8uhpx0hftmju2p6sw8ec7p" }, + { "8bab36e4644d835e967e1a5c9ecc0de07c424d5e7ec99c4e5ed3d1a5d8bfb5fd", "txch13w4nderyfkp4a9n7rfwfanqdup7yyn270myecnj760g6tk9lkh7sc0xamy" }, + { "951657faa5f09077f0572d18f452ee54458f7515252938c0c2f546623b061a81", "txch1j5t907497zg80uzh95v0g5hw23zc7ag4y55n3sxz74rxywcxr2qstef0gj" }, + { "aae04197d0a90751a9fdecbde36be247f466f7ea45cda3fffdf5266c67f8acb6", "txch14tsyr97s4yr4r20aaj77x6lzgl6xdal2ghx68lla75nxcelc4jmqrwnyue" }, + { "ced0ce6098dad2ee94509cc702b30e3acd79b2600ecab6dc23e9745280eb36af", "txch1emgvucycmtfwa9zsnnrs9vcw8txhnvnqpm9tdhpra9699q8tx6hstp070c" }, + { "4abfea84e9d06f6d9944e1e06c2bda9299cdfee74cd2057ab6fd019c824568b0", "txch1f2l74p8f6phkmx2yu8sxc276j2vumlh8fnfq274kl5qeeqj9dzcqgtwplg" }, + { "5520500a6d513ca29c4542d9c090123fb57e92f83cffa093b4e58c79b918580b", "txch125s9qznd2y7298z9gtvupyqj876hayhc8nl6pya5ukx8nwgctq9sxk748g" }, + { "5dd73b629bc51a7c590c035f40bf6e9ee90368943787e87d00a4ec66b8095578", "txch1thtnkc5mc5d8ckgvqd05p0mwnm5sx6y5x7r7slgq5nkxdwqf24uqlxmpjm" }, + { "fff1984a34b05b6f4217b37d296cf75916542365e279567e335b9c803a697265", "txch1llcesj35kpdk7sshkd7jjm8htyt9ggm9ufu4vl3ntwwgqwnfwfjsqwdcux" }, + { "99cafca023a6738d7d4fd969448ee4a75e47e46c737e46d247284aa6d8a59b80", "txch1n890egpr5eec6l20m955frhy5a0y0ervwdlyd5j89p92dk99nwqql7q03n" }, + { "0fe6b58f9e32e9237670ce7fd54c4d6cc7ff0fcad1c838ba48159575651c92a8", "txch1plnttru7xt5jxanseela2nzddnrl7r7268yr3wjgzk2h2eguj25qrkd0cz" }, + { "974c47a6b5b9876be65a4b036e1e2a1f6c9c87583e70fcb114c8f56a0d363bef", "txch1jaxy0f44hxrkhej6fvpku832rakfep6c8ec0evg5er6k5rfk80hszckumm" }, + { "708ea22742cb0122b42d53fdc2e41cc6ee6428ec9315dc67d3b813f72bed07bc", "txch1wz82yf6zevqj9dpd207u9equcmhxg28vjv2ace7nhqflw2ldq77q0uzurn" }, + { "eeaf4e72fb775a3959ab4e9d79e26541527bf64d6f7195423ab0a66d46012b5a", "txch1a6h5uuhmwadrjkdtf6whncn9g9f8hajddace2s36kznx63sp9ddqal27wq" }, + { "1006572cb658026468f8bb0e265a90935153607944af0333de63c33c316097aa", "txch1zqr9wt9ktqpxg68chv8zvk5sjdg4xcregjhsxv77v0pncvtqj74q9fnjvg" }, + { "3c5eec71bf413cb4a8877bf32347ff0f624d75d5edecc79cfabd64cd7caaba23", "txch1830wcudlgy7tf2y800ejx3llpa3y6aw4ahkv0886h4jv6l92hg3swjeu7r" }, + { "ca009eba8d3fac01a5b4f1814677f1e6b3ecf326f595406ce3dccd424ac982b7", "txch1egqfaw5d87kqrfd57xq5val3u6e7euex7k25qm8rmnx5yjkfs2ms4pjasq" }, + { "28acc6e27ada5e6b5cc9dd4c0c2ff798fd28508b83529a1a1bb5899b8c86e2ae", "txch19zkvdcn6mf0xkhxfm4xqctlhnr7js5ytsdff5xsmkkyehryxu2hqccsf97" }, + { "8dbf018b58167df4cebbefdd4303c5896e04da187d1442e3303e765a65d0abb0", "txch13klsrz6cze7lfn4malw5xq7939hqfksc052y9ces8em95ews4wcqzrd2hs" }, + { "fc94ec034188bac443a65dd01497b280bfdd4530980ce731a9f0f41d0a541c2b", "txch1lj2wcq6p3zavgsaxthgpf9ajszla63fsnqxwwvdf7r6p6zj5rs4s0lgl8z" }, + { "6d28b19c5bfc994d9847667d675d9867c83dda256394421ee3aa606eae7543c5", "txch1d55tr8zmljv5mxz8ve7kwhvcvlyrmk39vw2yy8hr4fsxatn4g0zsna4e9n" }, + { "bab538f692717fd5d1a59d67388823edf71b0417801dd4459dececfc5278b606", "txch1h26n3a5jw9lat5d9n4nn3zprahm3kpqhsqwag3vaank0c5nckcrqatqd0v" }, + { "1acd0afb08d6196d5e2720438e266c390a7559a400d2d31d1c1f5c1b6c073b70", "txch1rtxs47cg6cvk6h38yppcufnv8y982kdyqrfdx8gurawpkmq88dcqkg7jk8" }, + { "9bb681c8a6f416a632776bfa1d6ae2e2c89e1ee732134a64b67de3374d69b1f8", "txch1nwmgrj9x7st2vvnhd0ap66hzutyfu8h8xgf55e9k0h3nwntfk8uqp434kv" }, + { "f22144d456c56f4d61fbe7b639013a970de3c13c6aacfcf7010658c286caddbe", "txch17gs5f4zkc4h56c0mu7mrjqf6jux78sfud2k0eacpqevv9pk2mklqpzvnyz" }, + { "197260f9878cef5e39c23451fd98062547a8486a134bf6825fa118f0d3855cd9", "txch1r9exp7v83nh4uwwzx3glmxqxy4r6sjr2zd9ldqjl5yv0p5u9tnvszgp85l" }, + { "fd9f2eae002d4b91960c816212bdb26178de667be7d4ff255f92b6c1b6204571", "txch1lk0jatsq949er9svs93p90djv9uduenmul207f2lj2mvrd3qg4cs728q80" }, + { "6820707a4f25a27281ce2fcfc86976296e41e7e224327380354681cee951bc1a", "txch1dqs8q7j0yk389qww9l8us6tk99hyrelzyse88qp4g6qua623hsdq2j3zag" }, + { "7c23f7804a648c8d7efcaa1f038e8463bdca7a37ca880d04d868b21f16cec653", "txch10s3l0qz2vjxg6lhu4g0s8r5yvw7u573he2yq6pxcdzep79kwcefsnayk92" }, + { "05198144d37bf334846f623626fe4008ca29ad628db693522f32d2636f8d4a90", "txch1q5vcz3xn00enfpr0vgmzdljqpr9znttz3kmfx530xtfxxmudf2gqhjqf0v" }, + { "909cbe2fba0bf3388517279ef3417f74c8ffc892449161eabf70354e82fa837a", "txch1jzwtuta6p0en3pghy700xstlwny0ljyjgjgkr64lwq65aqh6sdaqr7fqhc" }, + { "3f15c99586cf70ff73822650a07b7cf965c5c4539116ff29902a4ae10affa334", "txch18u2un9vxeac07uuzyeg2q7mul9jut3znjyt072vs9f9wzzhl5v6q8qpnu2" }, + { "96370fb816d01a7b88d094bd6b5072e59511895bf9167236cab4090a00239333", "txch1jcmslwqk6qd8hzxsjj7kk5rjuk23rz2mlyt8ydk2ksys5qprjvesq30l35" }, + { "53618e7d31913100eb77140f7f431d0a277ebb1cc62c9ba9d0d305cb72aea691", "txch12dsculf3jycsp6mhzs8h7scapgnhawcucckfh2ws6vzuku4w56gsg96ty8" }, + { "995ac500fd5975a9ffe8e5bcc9f513cd73acd8003a2b9d64d9d35c97ca7c3c67", "txch1n9dv2q8at966nllguk7vnagne4e6ekqq8g4e6exe6dwf0jnu83nst8r3du" }, + { "45fcb43ae6ad55ae614bbff7e07786315df91857149c829288b02a048b547c18", "txch1gh7tgwhx4426uc2thlm7qauxx9wljxzhzjwg9y5gkq4qfz650svqe3jfnv" }, + { "4c859578c1e9d5a2052a0f3dbcad2ad1b1d5bc0a935ac8f14fe8ff3b4b4f9259", "txch1fjze27xpa826ypf2pu7metf26xcat0q2jddv3u20arlnkj60jfvs3egxre" }, + { "8fa3cc283481e0de4eca8167e0cdc32d8c65fc596962664bac1420b5f1dd6d55", "txch1373uc2p5s8sdunk2s9n7pnwr9kxxtlzed93xvjavzssttuwad42sqa4w6m" }, + { "10c4dd93920cd2d23cdc5f959ee0adf1ca6b356659eab3817c455413c945da97", "txch1zrzdmyujpnfdy0xut72eac9d789xkdtxt84t8qtug42p8j29m2tsakv97t" }, + { "7dc7289e6087f9bfa12bb7b96d3d0d8b7637fec69f88ae782c414b9764286a4d", "txch10hrj38nqslumlgftk7uk60gd3dmr0lkxn7y2u7pvg99ewepgdfxs7vrza6" }, + { "43baad281030a078079cab1fe58522fa515311fbcc4c0f535ab37df06efd654e", "txch1gwa262qsxzs8spuu4v07tpfzlfg4xy0me3xq7566kd7lqmhav48qy73dyc" }, + { "bc0c2ebf13298fb319a4f82386fb724d5600274a2ea93a4d9d0b0f96066f293c", "txch1hsxza0cn9x8mxxdylq3cd7mjf4tqqf62965n5nvapv8evpn09y7qj8p6lm" }, + { "733986643c933b7144bc3f589402ef6edc16116341cbfcbc73d93b9e0b829165", "txch1wvucvepujvahz39u8avfgqh0dmwpvytrg89le0rnmyaeuzuzj9js4tq6xw" }, + { "a686fc664301718b026e3d839c21bde176ffd6d44fd99ae5a8ce794d37915ab5", "txch156r0cejrq9cckqnw8kpecgdau9m0l4k5flve4edgeeu56du3t26smksnw4" }, + { "29765e012857f4c46301cf407287ed29f37f05ce5a07c7ae857d6eee107545a4", "txch199m9uqfg2l6vgccpeaq89pld98eh7pwwtgru0t5904hwuyr4gkjqp9n7je" }, + { "f96afd6836ddaa4119fdb9ad27ae917a5163f57a3141dcc55f875abce6ffbe2a", "txch1l94066pkmk4yzx0ahxkj0t530fgk8at6x9qae32lsadteehlhc4qzghl8u" }, + { "273d752c1ce751ca51ac2f68398010210d7ec33c3daea20f048daef91db93ad5", "txch1yu7h2tquuagu55dv9a5rnqqsyyxhaseu8kh2yrcy3kh0j8de8t2spqrak9" }, + { "1470998e5009d6a5868717063795801cd38be215ed2716826af908fd308787e9", "txch1z3cfnrjsp8t2tp58zurr09vqrnfchcs4a5n3dqn2lyy06vy8sl5sd4lfzt" }, + { "344294b27e55c39ede360133c7b34aa8c65e1b87ce878297454713c1c9ec241c", "txch1x3pffvn72hpeah3kqyeu0v624rr9uxu8e6rc9969gufurj0vyswqw88ukq" }, + { "0cad2f5a3f165823cf7a9623a55787bf936eeba9bc273bf42fdd1bb5208ba871", "txch1pjkj7k3lzevz8nm6jc3624u8h7fka6afhsnnhap0m5dm2gyt4pcsuzyvj7" }, + { "46f8abd5d4dcbc194ca2dde648aea428937aeddd0204c8fe8684c7ca26c964de", "txch1gmu2h4w5mj7pjn9zmhny3t4y9zfh4mwaqgzv3l5xsnru5fkfvn0qf9xpnd" }, + { "c671d9fe7b36840b63b08bc5f3a532c530d7827b1b320643ad2587b221936940", "txch1cecanlnmx6zqkcas30zl8ffjc5cd0qnmrveqvsadykrmygvnd9qqw27206" }, + { "4b22bc572b70c78288e8a6347dabc9048478a1b2a2d8d562668cb0a914e794b1", "txch1fv3tc4etwrrc9z8g5c68m27fqjz83gdj5tvd2cnx3jc2j988jjcsv2mnnf" }, + { "e42929f8ea4876e1815b0b5bd904a30989ecfcf4927f8e49e7b115d2758b1815", "txch1us5jn782fpmwrq2mpddajp9rpxy7el85jflcuj08ky2ayavtrq2s0slk3r" }, + { "d545ce3f0d57eae3275199fc8eb82106d76b3bf38234816cb33b607b626986bb", "txch164zuu0cd2l4wxf63n87gawppqmtkkwlnsg6gzm9n8ds8kcnfs6asr7jd72" }, + { "c30d8e741828d0a4e507a1baba2bb0c8412ef56723553a2181b2147cd3365e3f", "txch1cvxcuaqc9rg2feg85xat52asepqjaat8yd2n5gvpkg28e5ektclshkuxyy" }, + { "998a20032f055b3ce2ad2e1eef46a5a36e6a96e5ccdb3e623b715bdcfd78fa3e", "txch1nx9zqqe0q4dnec4d9c0w73495dhx49h9endnuc3mw9daeltclglqhc2hnm" }, + { "b302baf80806cefeb330249c3c1b9c0977c0003db60ee507801de5c704cc2c44", "txch1kvpt47qgqm80avesyjwrcxuup9muqqpakc8w2puqrhjuwpxv93zqfm430v" }, + { "f8ca4f9186c2d40ad64ccd5bcec0311039dd5943fbb3df57913e1923ace4ebd6", "txch1lr9ylyvxct2q44jve4duasp3zqua6k2rlwea74u38cvj8t8ya0tqcmshse" }, + { "c57cb0703bb5fb584c819fdbb49d849236428a503c5a349c406c51c27ef40c31", "txch1c47tqupmkha4snypnldmf8vyjgmy9zjs83drf8zqd3guylh5pscsjkved7" }, + { "a8dc3d05fbcb7e72fd55c4d461ea7657dbbbbdf42d21f20e25d2516f132b8a52", "txch14rwr6p0medl89l24cn2xr6nk2ldmh00595slyr396fgk7yet3ffqp5zdwl" }, + { "09ea909703b4085c8cf9c80c339a90ce0aad348298e512abba8fd512cd5e95e5", "txch1p84fp9crksy9er8eeqxr8x5sec926dyznrj392a63l239n27jhjs48c7zu" }, + { "98f1a924aa4c6ab9abcf4f00296f14473ee027a8ae38fe7c7f90878517a38cad", "txch1nrc6jf92f34tn270fuqzjmc5gulwqfag4cu0ulrljzrc29ar3jks7csrxm" }, + { "eb44e91d62c5f11f27e9143d6652eeebc66859933d05e949193df46d11de1c54", "txch1adzwj8tzchc37flfzs7kv5hwa0rxskvn85z7jjge8h6x6yw7r32q2v7t7p" }, + { "dfae4aceb36dac3527169adffa926c8df3bd5e67ecbd4aee711b13ffbbd84c2c", "txch1m7hy4n4ndkkr2fcknt0l4ynv3hem6hn8aj754mn3rvfllw7cfskqj5css4" }, + { "1ce47708d924f9c231c2366f2b8123735c5becdb45f8b81792a2d39310a3a797", "txch1rnj8wzxeynuuyvwzxehjhqfrwdw9hmxmghuts9uj5tfexy9r57tsarn0a4" }, + { "741f48e788af034208bdce41ebb65b621efb558107efe3ba951e01ebcd4e99d3", "txch1ws053eug4up5yz9aeeq7hdjmvg00k4vpqlh78w54rcq7hn2wn8fskemxhm" }, + { "1b9573282415229ea805a1a27284607bc8632ddc6d3dd129693ba683af92e324", "txch1rw2hx2pyz53fa2q95x389prq00yxxtwud57az2tf8wng8tujuvjqcp4zug" }, + { "733de339e70ada19434bd8ca279731f05160b55c117dfc033f610ce48b0832a2", "txch1wv77xw08ptdpjs6tmr9z09e37pgkpd2uz97lcqelvyxwfzcgx23q2klf5s" }, + { "44c4ccb452f398b6273dac29effa9976ee658afc24a3a2ab0016b018ce18106f", "txch1gnzvedzj7wvtvfea4s57l75ewmhxtzhuyj3692cqz6cp3nsczphs94z9av" }, + { "8056cbeddf92e6b4f8063d66ec9e71b1f2799a8f2a8156a7b7148fb59ff118e7", "txch1sptvhmwljtntf7qx84nwe8n3k8e8nx5092q4dfahzj8mt8l3rrns7t9cd9" }, + { "7943d9471c1389550b8201a40b7e9220e73a76e7ca2cde5bbde50d4366f8a480", "txch109paj3cuzwy42zuzqxjqkl5jyrnn5ah8egkdukaau5x5xehc5jqqj025gg" }, + { "653a686b725f964984fa9777b7f875f80b9e15d650107fcc88094f030051ac98", "txch1v5axs6mjt7tynp86jamm07r4lq9eu9wk2qg8lnygp98sxqz34jvqtgn372" }, + { "a71e06a43adcd3fcc850f877549b8250b96576b16468939f56ff4873668ed364", "txch15u0qdfp6mnflejzslpm4fxuz2zuk2a43v35f886klay8xe5w6djqkygmrw" }, + { "fac5428fb29dde39ce0d8f54708c99a698d4f78a664454ac3c194568b881c809", "txch1ltz59rajnh0rnnsd3a28prye56vdfau2vez9ftpur9zk3wypeqys5ry3ph" }, + { "d2047172e045178af6572e53c25c775c0a7f65cac6d9aed4f1ed3c8d58177a1f", "txch16gz8zuhqg5tc4ajh9efuyhrhts987ew2cmv6a483a57g6kqh0g0sl62q33" }, + { "b2abf9492bce0f81fd26199b9d97397c1c9f00df767aa1d204dee191aac02727", "txch1k24ljjftec8crlfxrxdem9ee0swf7qxlwea2r5symmser2kqyuns3ymqgw" }, + { "8fc07dcd315e6215f53a74a25a089407f04c682bd69e5747dbe756851356a3ef", "txch13lq8mnf3te3ptaf6wj395zy5qlcyc6pt6609w37muatg2y6k50hseac3r3" }, + { "2ecd4986836945b1aac0a0e00721b03b600da0bdd9b4eb68a6e3e99d0e08af81", "txch19mx5np5rd9zmr2kq5rsqwgds8dsqmg9amx6wk69xu05e6rsg47qs0g50ws" }, + { "015db94b3f74f2b2dcc1e6c1f0df8d9273297bc7ece94849b54990f7a72852d5", "txch1q9wmjjelwnet9hxpumqlphudjfejj778an55sjd4fxg00feg2t2sdxx22l" }, + { "2ce102313356271fc7d55f60c76e89ea60354eb08a951c4f03c1c47c4380885f", "txch19nssyvfn2cn3l374tasvwm5fafsr2n4s3223cncrc8z8csuq3p0snd0m0w" }, + { "ff5c9504e7fef885e08b60b586eb662357617e76733b8dc9ed138815b9ce432b", "txch1lawf2p88lmugtcytvz6cd6mxydtkzlnkwvacmj0dzwyptwwwgv4slkx7el" }, + { "a4daf1ac6c56e3c795228067c66c7e4227e6e0ea6ac5ec7dd041b2ed806cd0c9", "txch15nd0rtrv2m3u09fzspnuvmr7ggn7dc82dtz7clwsgxewmqrv6ryshcz8qx" }, + { "73eccd5737c223f36691853ef4597fa2b363828d68169d34462c525e2a745c91", "txch1w0kv64ehcg3lxe53s5l0gktl52ek8q5ddqtf6dzx93f9u2n5tjgs3d6m8a" }, + { "f9c3ec051e40fa8f4b016895c0a41372882069ee4177f5b94efa80dd03751b63", "txch1l8p7cpg7grag7jcpdz2upfqnw2yzq60wg9mltw2wl2qd6qm4rd3swns8he" }, + { "b3171d9bc907b56a3b32f049327a3ca34099c090967ecd7c92c033af2fbaddf9", "txch1kvt3mx7fq76k5wej7pyny73u5dqfnsysjelv6lyjcqe67ta6mhustmrl0j" }, + { "8df1aa4e5d0ad34a60ed4f89bd994c707879594e396e953b4df6aa7a2b0665dd", "txch13hc65njaptf55c8df7ymmx2vwpu8jk2w89hf2w6d764852cxvhwshag3yy" }, + { "549e8770f4b3710e278a128acb9e3894a2df8975c9ce748c866b9f4d3a7e960d", "txch12j0gwu85kdcsufu2z29vh83cjj3dlzt4e888fryxdw056wn7jcxs0wfhqz" }, + { "74ba88794f61bb1027bacaae907a2c51e3e8c688253f732c367a62c534b93a69", "txch1wjags720vxa3qfa6e2hfq73v2837335gy5lhxtpk0f3v2d9e8f5s5mthlp" }, + { "d2602bdc18c007cf9e0d1a91a7132065c0db4f8c092e526b0fbe6a8b1fee674b", "txch16fszhhqccqrul8sdr2g6wyeqvhqdknuvpyh9y6c0he4gk8lwva9sqdc8ew" }, + { "265f0687e7b0f4b084b8f457fd4caddb63ea0d5f0a14087e653871be28151024", "txch1ye0sdpl8kr6tpp9c73tl6n9dmd375r2lpg2qsln98pcmu2q4zqjqfc9u44" }, + { "0920e1aabf76677fc24c61d35c6957b1b1057151a036f537c0752e5796a2d90a", "txch1pyswr24lwenhlsjvv8f4c62hkxcs2u235qm02d7qw5h9094zmy9q8fr7ue" }, + { "ed23a997f0905e967f17d0e1301dce404625ffed6e591dcc763d0dffea420c93", "txch1a536n9lsjp0fvlch6rsnq8wwgprztllddev3mnrk85xll6jzpjfsyutfns" }, + { "48d45375771413cea4f177a0bd18d5f0625b14fcbdf846158091569d4a3458df", "txch1fr29xathzsfuaf83w7st6xx47p39k98uhhuyv9vqj9tf6j35tr0senmcel" }, + { "b9845eab94383cae588ef7022004684418bf52913d0ed264e5bd2d82cc80db6c", "txch1hxz9a2u58q72ukyw7upzqprggsvt7553858dye89h5kc9nyqmdkqxurk0y" }, + { "58291c05c3d694ac232f4ff78f500603dec0d5266047915596004fd267533fbb", "txch1tq53cpwr6622cge0flmc75qxq00vp4fxvprez4vkqp8aye6n87asv05xnh" }, + { "c3091f3168d56377b2cc38f28381be909c1ee26edb85342c117c625c610c067b", "txch1cvy37vtg643h0vkv8reg8qd7jzwpacnwmwzngtq30339ccgvqeasf9s4jh" }, + { "d0be66f006d4dfea21aa6c348f2a6581e13f0c47dc4f1cba3110bdd1020f50e7", "txch16zlxduqx6n075gd2ds6g72n9s8sn7rz8m383ew33zz7azqs02rnsm3p65t" }, + { "6763c83dccfa1236994f2a41e688e6713fdd0729531a69f466598b1a7c1c2bb1", "txch1va3us0wvlgfrdx209fq7dz8xwyla6pef2vdxnarxtx935lqu9wcs2jxpvu" }, + { "2334136575d91c688987afd7db254ba2034fe63f411a554137f31af1e01870c8", "txch1yv6pxet4mywx3zv84ltakf2t5gp5le3lgyd92sfh7vd0rcqcwryqhf92ng" }, + { "8c8e0e538f0ac181103a5cbf51bdd4d319e070b6a1358d02dc00c5c28b831cd2", "txch13j8qu5u0ptqczyp6tjl4r0w56vv7qu9k5y6c6qkuqrzu9zurrnfqt5vapn" }, + { "b9f6178617d3e410547b6f3118dbd16f93b3a3523eb6955b5cb9e3c6c259ddd8", "txch1h8mp0psh60jpq4rmduc33k73d7fm8g6j86mf2k6uh83udsjemhvqgfz9nk" }, + { "9ce65d4f94e651782fb7cbfa8a61f8ff6dfe0d05d8df8071c45b9c7934b42c27", "txch1nnn96nu5ueghstahe0ag5c0claklurg9mr0cquwytww8jd959snsel6pqp" }, + { "ef44c30226a14c5828c8551b2ce29576f681509b21504eaba2a13743b64b4c48", "txch1aazvxq3x59x9s2xg25djec54wmmgz5ymy9gya2az5ym58djtf3yq3r2fpl" }, + { "acb91976422c7ffa4205443f06d048d2bac5a1bc70a79e7f76835b6821be1be1", "txch14ju3jajz93ll5ss9gslsd5zg62avtgduwzneulmksddksgd7r0ss8pnygl" }, + { "64fa6feb1b6ded5653fd5e47179e40961938be7c884901686897ae064909174e", "txch1vnaxl6cmdhk4v5later308jqjcvn30nu3pysz6rgj7hqvjgfza8qaexa07" }, + { "fe3fcc343eadb48ae75c3e541dfe900abc45e9e66413c3881447eec067bef52e", "txch1lclucdp74k6g4e6u8e2pml5sp27yt60xvsfu8zq5glhvqea775hqt7mugk" }, + { "ead027a7b7559adf271e26f93736251af977571afd3c7b19d26328a7412c40b8", "txch1atgz0fah2kdd7fc7ymunwd39rtuhw4c6l578kxwjvv52wsfvgzuqagmuwt" }, + { "7b28e67de39bde041b1bf5b762a4c55571419aeea64376506c5dc6bf0662f7f5", "txch10v5wvl0rn00qgxcm7kmk9fx924c5rxhw5ephv5rvthrt7pnz7l6szcln65" }, + { "e7a26d9a157500941bf4eca8cf4fc7626623a5bad08204d485ead8ed4e2c65dd", "txch1u73xmxs4w5qfgxl5aj5v7n78vfnz8fd66zpqf4y9atvw6n3vvhwsa607rx" }, + { "88b33fdba4bb061347251da4d54817e78625c0e9f38f73e3dd834185c3d2c2f1", "txch13zenlkayhvrpx3e9rkjd2jqhu7rzts8f7w8h8c7asdqcts7jctcs472m5c" }, + { "10fb5a0eed28acfd3f163f652cd586f98b8ff372a5f72287724dac504abe0175", "txch1zra45rhd9zk060ck8ajje4vxlx9clumj5hmj9pmjfkk9qj47q96s8l24da" }, + { "d534df189d478cc3d5efdc047c40f849bf3056d91bb24a93f56b68b970746113", "txch1656d7xyag7xv8400msz8cs8cfxlnq4kerwey4yl4dd5tjur5vyfs3jjj27" }, + { "1de2b007735cca90b3004e216572e6b40a1c1ca9616a9f2a8aa379c52327457d", "txch1rh3tqpmntn9fpvcqfcsk2uhxks9pc89fv94f72525duu2ge8g47sre5dhw" }, + { "8b0689675b3c2d8ad6257d5de54a3383cfd1a6c6d5cb6b45bc8e4bd81e452fae", "txch13vrgje6m8skc443904w72j3ns08arfkx6h9kk3du3e9as8j997hq7u73py" }, + { "20913b99147d0df88f8f26e346d07f5424849c08252394eaf49c8b27fb290d6a", "txch1yzgnhxg505xl3ru0ym35d5rl2sjgf8qgy53ef6h5nj9j07efp44q0mqak7" }, + { "7a8a366fe1137739e8f8a0355f70c7de8106af1cab25272172b6c95c703b1ea5", "txch1029rvmlpzdmnn68c5q647ux8m6qsdtcu4vjjwgtjkmy4cupmr6jsac2gpz" }, + { "218dabf102e5cca09cadc9599962f1c996bbb0779420bb89edb7df22eec4ae57", "txch1yxx6hugzuhx2p89de9vejch3extthvrhjssthz0dkl0j9mky4etskcyx9h" }, + { "fbbe8655ba663500a81971ae25182f0c025143f7842cba3cc15417a9b32ae8ea", "txch1lwlgv4d6vc6sp2qewxhz2xp0psp9zslhsskt50xp2st6nve2ar4qhw4hjw" }, + { "47117b0851077c17cb8b3e3126078bcb114c9bffe3d8cc9d2d64d68cd1379beb", "txch1gughkzz3qa7p0jut8ccjvputevg5exllu0vve8fdvntge5fhn04sqs00nl" }, + { "fc7a52490e4245607a9d398865843ebe74ad24d36d765b8427e45abf2b559a6d", "txch1l3a9yjgwgfzkq75a8xyxtpp7he626fxnd4m9hpp8u3dt7264nfks0q4g9g" }, + { "39dbdcc5efda054e731829a2588fc98e7c10b8a516f3610bd07f23414302e013", "txch188dae300mgz5uucc9x393r7f3e7ppw99zmekzz7s0u35zsczuqfsa4j96h" }, + { "dab2f34cea5a75875083eb8626e49771e45694ae65a96cbad21b424c9335bced", "txch1m2e0xn82tf6cw5yrawrzdeyhw8j9d99wvk5kewkjrdpyeye4hnksl5e0xw" }, + { "e373a1685d43a4504530381a81de77cbb67268ade5d227d47b27c392b44cd59f", "txch1ude6z6zagwj9q3fs8qdgrhnhewm8y69duhfz04rmylpe9dzv6k0sku5jn0" }, + { "1d3b788edd6e9c83a9c2e2536e85b25bd15e4b3e6031d79656ec83bad13f78b3", "txch1r5ah3rkad6wg82wzuffkapdjt0g4uje7vqca09jkajpm45fl0zesargg25" }, + { "c4fdf7439243f08ea7025716cc78e337b4bc6486a8d5d7f154f75d37d12db7e4", "txch1cn7lwsujg0cgafcz2utvc78rx76tceyx4r2a0u257awn05fdkljq5l26ec" }, + { "df585ca5ecb8211d33c6eb33f6fe43616e06e1e9d8e0ad8bca0e5edc17590837", "txch1mav9ef0vhqs36v7xaveldljrv9hqdc0fmrs2mz72pe0dc96epqmsr3xr52" }, + { "0b6406e5e40e1d4a1237c7a3bb4838c65ae71683a637e72456285038860354e7", "txch1pdjqde0ypcw55y3hc73mkjpccedww95r5cm7wfzk9pgr3psr2nns9ee6nz" }, + { "1f4c5a691230488fa3eef60330b99375a28dc33094eaeac3349f9e0f570acb82", "txch1rax956gjxpyglglw7cpnpwvnwk3gmsesjn4w4se5n70q74c2ewpqjxykw0" }, + { "fde220ede29a9471b85cae7cc62a745f2773b8076196a82a72d96a916d2b70c2", "txch1lh3zpm0zn228rwzu4e7vv2n5tunh8wq8vxt2s2njm94fzmftwrpq758l9q" }, + { "60baf86de30044de53ef40d94e203d0f0c427dfd5d51af7f15656222eb32a396", "txch1vza0sm0rqpzdu5l0grv5ugpapuxyyl0at4g67lc4v43z96ej5wtqxe0vmy" }, + { "981156624e33e5220d35e0e56d36bb57707e230bd922e9efdec5d48f95ce3a2e", "txch1nqg4vcjwx0jjyrf4urjk6d4m2ac8ugctmy3wnm77ch2gl9ww8ghq6jszna" }, + { "27eda1e1489c1bdf65e94e5bc224dda804576581ce71aa85d02a8f751a9007b5", "txch1ylk6rc2gnsda7e0ffeduyfxa4qz9wevpeec64pws928h2x5sq76slas0yj" }, + { "146a0a45772f1727dc18b570531f85cdb91cc5f910bd286c4e121ef63c7dfa86", "txch1z34q53th9utj0hqck4c9x8u9eku3e30ezz7jsmzwzg00v0ral2rqskxspw" }, + { "ecf4671df810c51757ca3815b9ee8159a653446381228f6002a0cb714e8938cc", "txch1an6xw80czrz3w4728q2mnm5ptxn9x3rrsy3g7cqz5r9hzn5f8rxqe2l0ms" }, + { "7324121ab3fadf2b4bc37927944f2ceb99ed62067ba6bcced32ae5f8f9f502e9", "txch1wvjpyx4nlt0jkj7r0ynegnevawv76csx0wntenkn9tjl3704qt5s2lrjvf" }, + { "c4156687d1580c8cc600e76302701a594283cafbbbf43088ab08652d21bcea08", "txch1cs2kdp73tqxge3squa3syuq6t9pg8jhmh06rpz9tppjj6gduagyqn2c669" }, + { "de183ccd645055b6f12c110f16ee0f805da15df8ccfa112f013911a22b41db70", "txch1mcvrenty2p2mdufvzy83dms0spw6zh0cenapztcp8yg6y26pmdcqfanfhf" }, + { "3b0d7ba71d2dfee3af8ddefa026962419bb03d0fb80ab1b745bb6738e66c10d6", "txch18vxhhfca9hlw8tudmmaqy6tzgxdmq0g0hq9trd69hdnn3envzrtqqtjl85" }, + { "80612976713701a7c6b69b82932fb65b8c3cfd0e922d0e91fea29a67de939426", "txch1spsjjan3xuq6034knwpfxtaktwxrelgwjgksay0752dx0h5njsnqsarct7" }, + { "5a0b22a9ec5192965910f1d4df24f8746e253049f038987a299c881801a94b93", "txch1tg9j920v2xffvkgs782d7f8cw3hz2vzf7qufs73fnjypsqdffwfs970dvv" }, + { "237b1d9fc5f7793f0ab6b77a9a8b39ce1ce5ab462310425e8d305d396a159864", "txch1yda3m8797aun7z4kkaaf4zeeecwwt26xyvgyyh5dxpwnj6s4npjqt2zq7n" }, + { "56fff6f5021015fe035b6733d8840e08eb8bf4dae52a50190f7ab9a10165ea17", "txch12mlldagzzq2luq6mvuea3pqwpr4chax6u549qxg002u6zqt9agts9smg5l" }, + { "0f65a0c341c3e160815b352847268051623c0d9e67b2195148b79fc40bef59cc", "txch1paj6ps6pc0skpq2mx55ywf5q293rcrv7v7epj52gk70ugzl0t8xqtq4y48" }, + { "0fdb15f597c7eaf5a3890a826996bef2846aecfbb2b45a90821c06330fa687b3", "txch1pld3tavhcl40tgufp2pxn94772zx4m8mk2694yyzrsrrxraxs7esapjcnv" }, + { "5284ccd4971f290fc92da6a73f9e01cbe00f1b90b40a08ee65dd61e6a9a6b0af", "txch122zve4yhru5sljfd56nnl8spe0sq7xusks9q3mn9m4s7d2dxkzhskzz8ga" }, + { "58f88d201ba97cff4a018a8f96c365c50de82f06beb0ff1e8bd0a9121ff589c9", "txch1trug6gqm49707jsp328edsm9c5x7stcxh6c0785t6z53y8l438ysnak6zh" }, + { "70d4049684e2336e58eea25df277f88e1c33945f579201ec3606e3ded5ceb84c", "txch1wr2qf95yugekuk8w5fwlyalc3cwr89zl27fqrmpkqm3aa4wwhpxqg245s3" }, + { "d3b3c188aceab611ebb3cc2645cffb49fca44d9edc77926ca6e3532f24c254db", "txch16weurz9va2mpr6anesnytnlmf872gnv7m3meym9xudfj7fxz2ndsnws7qa" }, + { "6eebf8bf0d5d61227ec1b15d4197f6b6b13707dd22d4364dc749de8a8895465b", "txch1dm4l30cdt4sjylkpk9w5r9lkk6cnwp7ayt2rvnw8f80g4zy4gedswjqg5x" }, + { "104ae84afc24b0ac97253d6d6188d94f4dfaef0409f7b40f77d94a886425b13d", "txch1zp9wsjhuyjc2e9e984kkrzxefaxl4mcyp8mmgrmhm99gsep9ky7smfa8p9" }, + { "1dbca008aa71422839fc7b1697b3d156bd939db5374e7375b7823831dcc36eec", "txch1rk72qz92w9pzsw0u0vtf0v73267e88d4xa88xadhsgurrhxrdmkqlqw5pe" }, + { "5ef8420eb592de4a3ee2cef833e1fd5f4e097e4a04ea3e674bd503e6f0b5cddf", "txch1tmuyyr44jt0y50hzemur8c0ata8qjlj2qn4rue6t65p7du94eh0sc89u2q" }, + { "6a4d10adc5fbd12362c9fcd3aad751b0c8dd779cc84a7b732a3cfd7d0211fe4d", "txch1dfx3ptw9l0gjxckflnf64463kryd6auuep98kue28n7h6qs3lexs2hzjns" }, + { "82167527b0b0db7de13a15ed09698b59cf87719aac8997bc1c6a1671511176d1", "txch1sgt82faskrdhmcf6zhksj6vtt88cwuv64jye00qudgt8z5g3wmgsh3p2g6" }, + { "7c637bcdf93b3b54f608df734278be5c1e39837b46ad184ed87d5d14d170fa8b", "txch1033hhn0e8va4fasgmae5y797ts0rnqmmg6k3snkc04w3f5tsl29s7gkglv" }, + { "ba86be5894bcddeccdaa9f1903a0a4f03e85a73bb2fdc197ff3e16f9924600c7", "txch1h2rtuky5hnw7end2nuvs8g9y7qlgtfemkt7ur9ll8ct0nyjxqrrspawqy6" }, + { "7c2672ee04dedbb18423a2c669f9b4fab86019d5b187e69acdf1c57a3ab1a535", "txch10sn89msymmdmrppr5trxn7d5l2uxqxw4kxr7dxkd78zh5w43556sj8l245" }, + { "19b9e2676e17836de4643b1d30c6913378e59bf5b3391dd14a82182106bace6d", "txch1rxu7yemwz7pkmery8vwnp353xduwtxl4kvu3m522sgvzzp46eeks04t98l" }, + { "deac0b898bba894d021d405c6e566a41b1029aa2e4c1a1b4917daa6b234ad06b", "txch1m6kqhzvth2y56qsagpwxu4n2gxcs9x4zunq6rdy30k4xkg626p4skjne07" }, + { "a72e4dafe557fbb7ee2bb47ad0d9cb59be8ae5871493f43051ffedd62b8dcf19", "txch15uhymtl92lam0m3tk3adpkwttxlg4ev8zjflgvz3llkav2udeuvsp55q8d" }, + { "6e42f72a6d41ae9475831e8339659ae0e0761c901dd0ef84b7cde6b56c889009", "txch1dep0w2ndgxhfgavrr6pnjev6urs8v8ysrhgwlp9hehnt2mygjqysn5s6tu" }, + { "4fef17938596e5633379258c9c838ace44bd02e53d0a186fd845682400cc6a63", "txch1flh30yu9jmjkxvmeykxfequ2eezt6qh9859psm7cg45zgqxvdf3sey7jp2" }, + { "6ec6c720d486226be22c6e717f55785595f91a0bc7d64cc602cdf819fae26f4f", "txch1dmrvwgx5sc3xhc3vdech74tc2k2ljxstcltye3szehupn7hzda8sgqwrgu" }, + { "04445e7d983790e246a6fc791159b6263da12ea56bbb17bb8e28633a200c4480", "txch1q3z9ulvcx7gwy34xl3u3zkdkyc76zt49dwa30wuw9p3n5gqvgjqqxawlrc" }, + { "73263d4838965e61fabe86c84bcb63526d23c045be50a5691296c7dc2d7dd345", "txch1wvnr6jpcje0xr747smyyhjmr2fkj8sz9heg226gjjmractta6dzsn3ydxq" }, + { "8a185143e15b9118a32e04e87f8d67d4e54cb48ac37e3194609b9ad21c5a9098", "txch13gv9zslptwg33gewqn58lrt86nj5edy2cdlrr9rqnwddy8z6jzvqsesr5f" }, + { "ed36dd41e65a762b69014580bd7a3a5621dc63ecc428614da8e2c73e568f186f", "txch1a5md6s0xtfmzk6gpgkqt67362csacclvcs5xzndgutrnu450rphsfxe2q5" }, + { "849a269273b9dade2b98551404a4f46dbe705ee996bd3c6bedf95ba04d2e5d28", "txch1sjdzdynnh8ddu2uc252qff85dkl8qhhfj67nc6ldl9d6qnfwt55qvlnuvh" }, + { "efe1dfcfb3475ea275bd3f22c8f32270ed551456038d793ec2ba9fd0e72f6cac", "txch1alsalnanga02yada8u3v3uezwrk429zkqwxhj0kzh20apee0djkqywzt5l" }, + { "074a8f7811aaf486fadbfef100ce84fa0f7f50e7ab7eb6f9e3d35cb2281b2ae7", "txch1qa9g77q34t6gd7kmlmcspn5ylg8h75884dltd70r6dwty2qm9tns4m37e2" }, + { "c637c81b60ba60417c27b7bcf94c2c05ab0649059c12612a60b42eb8695fa61d", "txch1ccmusxmqhfsyzlp8k770jnpvqk4svjg9nsfxz2nqkshts62l5cwsxv0err" }, + { "362364cef70d956c92127170caf68a5e8e4cb398dbeb2a83fff20c1b69fff270", "txch1xc3kfnhhpk2keysjw9cv4a52t68yevucm04j4qll7gxpk60l7fcq06c4rk" }, + { "447e1a7507d73283973c0422e8cfcc188089cbc66f597a416e7c9edc6338da71", "txch1g3lp5ag86ueg89euqs3w3n7vrzqgnj7xdavh5stw0j0dccecmfcsluxjxy" }, + { "4a5ec013d277cfce8fb922cf04a5fe64e17f733de051ac949c7b54e138a18e92", "txch1ff0vqy7jwl8uaraeyt8sff07vnsh7ueaupg6e9yu0d2wzw9p36fqtd6ufl" }, + { "e86c67bd15113a90e4914da5904215f047e71bed0f5203b8d8e9c3dd0e18ed82", "txch1apkx00g4zyafpey3fkjeqss47pr7wxldpafq8wxca8pa6rscakpqyx5wvn" }, + { "686be23a2b1353ad91ad6ca7e06589ac1e70510367f6985b20aceb31b9efc11f", "txch1dp47yw3tzdf6mydddjn7qevf4s08q5grvlmfskeq4n4nrw00cy0s93ss3t" }, + { "b75f240bfd35237372843a8c4d361d6516780a183baf1fd976b6946a29fa75c5", "txch1ka0jgzlax53hxu5y82xy6dsav5t8szsc8wh3lktkk62x5206whzsl56ckd" }, + { "e452898f6ec85dacc4a7e9945ff926221800cf80119b8b1877ed1a58a44118fd", "txch1u3fgnrmwepw6e398ax29l7fxygvqpnuqzxdckxrha5d93fzprr7s2w37m9" }, + { "49a9d753a604dcd65fb5cf265433f06174a5e9b99f661c47c1762a63a23dbaf1", "txch1fx5aw5axqnwdvha4eun9gvlsv962t6denanpc37pwc4x8g3ahtcse9lek5" }, + { "d569056661ffcb95e5e559c58936d7aa30921e0731d94d820dca73e282d565a1", "txch1645s2enpll9ete09t8zcjdkh4gcfy8s8x8v5mqsdefe79qk4vksspxf5yz" }, + { "8c0014d383a616915256b3723541ab2a3d5187f2f4b30721eeace327e8651b7b", "txch13sqpf5ur5ctfz5jkkder2sdt9g74rplj7jeswg0w4n3j06r9rdasegzk0p" }, + { "342067db6979764a1066a7bfcfb5ee09940833d426579dace43dbb331dea04d3", "txch1xssx0kmf09my5yrx57luld0wpx2qsv75yetemt8y8kanx802qnfshsadsx" }, + { "456064cf325902db2cb96db6c5c309ff631d6bad700434cb70f9727984da89db", "txch1g4sxfnejtypdkt9edkmvtscfla3366adwqzrfjmsl9e8npx638dsg5dmgk" }, + { "abfed1c6bd5e2e7c02b50402abc71d11aa849575caf34b744037e42863c827b4", "txch140ldr34atch8cq44qsp2h3cazx4gf9t4ete5kazqxljzsc7gy76q9q7ph8" }, + { "8ac516f026f6fdcdf358a35a9825ea99c55558bd0a320d61b08e85abbcaac865", "txch13tz3dupx7m7umu6c5ddfsf02n8z42k9apgeq6cds36z6h092epjsz8yl2n" }, + { "369cc0eb5e6bf5349ebe69ab822cb249682972e4757b6324782baba4518f81db", "txch1x6wvp667d06nf847dx4cyt9jf95zjuhyw4akxfrc9w46g5v0s8ds3m5w7j" }, + { "d240911bb7aec423ab58bbfe5bb8288ec11b0049e3a1cbe945b70ddebddd2209", "txch16fqfzxah4mzz826ch0l9hwpg3mq3kqzfuwsuh629kuxaa0waygysnjltxm" }, + { "8762f2cd65d9c651144af197d54c353f82699b5e765daf8f014f7931931e1d59", "txch1sa309nt9m8r9z9z27xta2np487pxnx67wew6lrcpfaunryc7r4vsddcphr" }, + { "7ee57e21b7e3dfbcefbeeedaeaf6a74a20194e0ac1bec001f24167c03f6e4960", "txch10mjhugdhu00mema7amdw4a48fgspjns2cxlvqq0jg9nuq0mwf9sq6upv7a" }, + { "8f87256225fe92ae1b61400eec33e0620c90ee9b437a47656acc516d38aa46e4", "txch137rj2c39l6f2uxmpgq8wcvlqvgxfpm5mgdaywet2e3gk6w92gmjq8jklrd" }, + { "737069b905bb33d7232ccb28e14378fb014624f2694cd125eb7c1241c36bbd81", "txch1wdcxnwg9hveawgevev5wzsmclvq5vf8jd9xdzf0t0sfyrsmthkqsc3qgrt" }, + { "c0bbdb9cbc009fb3ca14ec499533c53b4321fad41613f2c56f0694630b05e365", "txch1czaah89uqz0m8js5a3ye2v798dpjr7k5zcfl93t0q62xxzc9udjs8tyryt" }, + { "eb24f55b952da341089434c3c048a1e95f21d5996b54ff93f9a20b3253e9cfd6", "txch1avj02ku49k35zzy5xnpuqj9pa90jr4vedd20lyle5g9ny5lfeltq4dcuyr" }, + { "0e7e66bea8da3da09408d3b892583d267823c260a2cb80c18cfbb56ca444455a", "txch1pelxd04gmg76p9qg6wufykpayeuz8snq5t9cpsvvlw6kefzyg4dqrva789" }, + { "ef6b57e9558b5f2ae5867698aede4ae06c0dc1385b4960a52ae535fe108c4cfb", "txch1aa4406243d0j4evxw6v2ahj2upkqmsfctdykpff2u56luyyvfnas20j9v0" }, + { "46d9af92b29dd9d133cbd9012e9ed08e93c8d766b923eaa4f11f9481d497c80a", "txch1gmv6ly4jnhvazv7tmyqja8ks36fu34mxhy374f83r72gr4yheq9qa56l20" }, + { "4f21a5ec8d79e270ab56ff82d925ee7f00d114f8753f193bd809db522360bd11", "txch1fus6tmyd0838p26kl7pdjf0w0uqdz98cw5l3jw7cp8d4ygmqh5gsc5ecla" }, + { "a0657db926307b6798fddd1a769ac2712c3921a145c6a6c472aa60aac11749e3", "txch15pjhmwfxxpak0x8am5d8dxkzwykrjgdpghr2d3rj4fs24sghf83stpdxd8" }, + { "45f03225cc0a1e30dda82cab00669fda41ec4ec583334130b1065a9d918b0ec3", "txch1ghcryfwvpg0rphdg9j4sqe5lmfq7cnk9sve5zv93qedfmyvtpmpsxwk5l2" }, + { "b5e964526e45df649f1f37cf6e52cbb2b20a3112a94ffda9ccbd034308c6634d", "txch1kh5kg5nwgh0kf8clxl8ku5ktk2eq5vgj498lm2wvh5p5xzxxvdxssrs7ck" }, + { "92cecc9d36bbd164099e5f2fe7ba69cd5add26c5f83d5f2852e694b18aa02b42", "txch1jt8ve8fkh0gkgzv7tuh70wnfe4dd6fk9lq7472zju62trz4q9dpqlq59w6" }, + { "152c9d33ce7b45de394b4373dc89978429d52f3f890c64cba3c00200f41232d6", "txch1z5kf6v7w0dzauw2tgdeaezvhss5a2tel3yxxfjarcqpqpaqjxttqkaxedz" }, + { "3b5b5480832a9780af9abc0f0539c3cee5c87f9622b776aadcbc9ad050bdc0c5", "txch18dd4fqyr92tcptu6hs8s2wwremjusluky2mhd2kuhjddq59acrzsxvngz4" }, + { "ec2c997c18d89b150574d98a0c629e8af5abde608f2f49e946c88e38616413f2", "txch1askfjlqcmzd32pt5mx9qcc573t66hhnq3uh5n62xez8rsctyz0eqvxmwkc" }, + { "b1f66bca4862f3c96192077a411bd34740fe9a13ea5f0c6a5121d2b43d437799", "txch1k8mxhjjgvteujcvjqaayzx7ngaq0axsnaf0sc6j3y8ftg02rw7vswd0lrr" }, + { "64808327bf07c9b2d511f39fa4f715c9846da2e7f937966f3f5d005ae1399315", "txch1vjqgxfalqlym94g37w06fac4exzxmgh8lymevmelt5q94cfejv2szx7xl0" }, + { "8f5a1a4161d54f979fc640897750249d0c33a7e3a6574a14211803ed0c36e384", "txch13adp5stp648e087xgzyhw5pyn5xr8flr5et559pprqp76rpkuwzqpasveg" }, + { "53fa1e5f8a50aae5ba50eca48949a6b1edafb94dd2e9468e3d9da1ef54931640", "txch120apuhu22z4wtwjsajjgjjdxk8k6lw2d6t55dr3anks774ynzeqqpddqh3" }, + { "406ba86059826cd2671dd3ead60d9cd6262899a32bfb3744cc9eaa50419e30cb", "txch1gp46sczesfkdyeca604dvrvu6cnz3xdr90anw3xvn649qsv7xr9sfvxym4" }, + { "582299ada562c2edb25697b2fac703fe204ab923301c315085ae6dcc792d2092", "txch1tq3fntd9vtpwmvjkj7e043crlcsy4wfrxqwrz5y94ekuc7fdyzfqsg40fn" }, + { "35442aa4751caac7f066e85ec989a266f934fceb70dc04a27934be85fbb0be5e", "txch1x4zz4fr4rj4v0urxap0vnzdzvmunfl8twrwqfgnexjlgt7ashe0qdg2jec" }, + { "edacd5d303229c89bcf0348f782606bde69e1a99e5e71e62a8b41c765f86d566", "txch1akkdt5cry2wgn08sxj8hsfsxhhnfux5euhn3uc4gksw8vhux64nqpj59k9" }, + { "7fef78077939b7aa4a1c61686b155c5f02430656dbc55aad7febad20d5c7f96e", "txch10lhhspme8xm65jsuv95xk92utupyxpjkm0z44ttlawkjp4w8l9hqtmkmxs" }, + { "d33536510dad4ad0aa94b3981d036ca354e59e46fa0216fb6e6938550542fda5", "txch16v6nv5gd449dp255kwvp6qmv5d2wt8jxlgppd7mwdyu92p2zlkjs54r989" }, + { "70eac01e675ff3843523d8afd76f89d31bbe266f9f018af267e1562090d304e1", "txch1wr4vq8n8tlecgdfrmzhawmuf6vdmufn0nuqc4un8u9tzpyxnqnssm3cpxm" }, + { "9fe54efcb2e78594052e1620647935c8924d849a99cf413f711e0a7cab3263a0", "txch1nlj5al9ju7zegpfwzcsxg7f4ezfympy6n885z0m3rc98e2ejvwsq7ytqym" }, + { "e530d4b70a44afeba0d3681c046007acc5ea1a35a7109024f28213e6a597e404", "txch1u5cdfdc2gjh7hgxndqwqgcq84nz75x345ugfqf8jsgf7dfvhuszqqngz2z" }, + { "54db68f796228c4092bade30bec8fa269019e7fd1b1238931d7c6ea202cecc3e", "txch12ndk3auky2xypy46mcctaj86y6gpnelarvfr3yca03h2yqkweslqkutthx" }, + { "eecce35b0c934a225e13ec48b0f388f529c68147aca4f00cada748e243597736", "txch1amxwxkcvjd9zyhsna3ytpuug755udq284jj0qr9d5aywys6ewumqgx7gdw" }, + { "d089427b8b675a7d52585cdd6157c660c594fd284604d92c924d219cc25dd55b", "txch16zy5y7utvad865jctnwkz47xvrzeflfggczdjtyjf5seesja64ds9athjy" }, + { "257645bf413c47753e5018297ec3572accaaf989675be6311114b4deb920895d", "txch1y4myt06p83rh20jsrq5has6h9tx247vfvad7vvg3zj6dawfq39wsurz5vc" }, + { "4217fc0c04394c084f090abc71ad52a081327d6cc89833101847c388aae39011", "txch1ggtlcrqy89xqsncfp278rt2j5zqnyltvezvrxyqcglpc32hrjqgs253zj9" }, + { "cad3eb7c68b2b6258c569d4bb04392d82f6c7667c29fc1415d089ab0526a3dc2", "txch1etf7klrgk2mztrzkn49mqsujmqhkcan8c20uzs2apzdtq5n28hpqhahsyy" }, + { "4113852af428199f9e6627431a09f8feea91f5c8b3da3967111bab53962a7726", "txch1gyfc22h59qvel8nxyap35z0clm4frawgk0drjec3rw448932wunqd27mnn" }, + { "86df57e815de17f1b80c4e8e440c25d39cfd230562eef6312e10b6861be781da", "txch1sm0406q4mctlrwqvf68ygrp96ww06gc9vth0vvfwzzmgvxl8s8dq3lnmfa" }, + { "2543685ce1a3ca12994299c8c7a770d7f6eaf32f0b51dfa780655bf64f53b36a", "txch1y4pksh8p509p9x2zn8yv0fms6lmw4ue0pdgalfuqv4dlvn6nkd4q9zph2z" }, + { "01c8151c6ecafcbd172090bf49e1c436980be3d4edc7a9c3a26319320d62e9d3", "txch1q8yp28rwet7t69eqjzl5ncwyx6vqhc75ahr6nsazvvvnyrtza8fsuzsyn2" }, + { "f26658dd3ef599bf977e84369c4595c311d94b40d1e36ab11ff14fed4e81422b", "txch17fn93hf77kvml9m7ssmfc3v4cvgajj6q683k4vgl79876n5pgg4shz3n6y" }, + { "6f3b8ce1c9528771cd1882d67eda89c435ac1f3247341bb3db7b6d20707fd564", "txch1duacecwf22rhrngcstt8ak5fcs66c8ejgu6phv7m0dkjqurl64jq8zyeat" }, + { "a0faa61e81386b79630f57599469d1bf78e0e8b330c7a3c954848c88fced341a", "txch15ra2v85p8p4hjcc02aveg6w3hauwp69nxrr68j25sjxg3l8dxsdqdsuggj" }, + { "eea78fb27f813c1b709616605496c719a0d073f5ad2c0eca7b8adcd8312a1a75", "txch1a6nclvnlsy7pkuykzes9f9k8rxsdqul445kqajnm3twdsvf2rf6sz876fr" }, + { "7c8b04d6aa4578ac308d6ae4c47d9ab6a8ee9766a1da02e8ff2599ee11b73d19", "txch10j9sf442g4u2cvyddtjvglv6k65wa9mx58dq968lykv7uydh85vspekadc" }, + { "c35e6a0d531c4244978d29ea54f85cb9b0fbee459d79790643131c3c77d877bb", "txch1cd0x5r2nr3pyf9ud9849f7zuhxc0hmj9n4uhjpjrzvwrca7cw7as0k7gjk" }, + { "bbb563be5651b49ebf4c5a3c8bb41df0ca29b052f9898b2e24b00a1f7b5ab925", "txch1hw6k80jk2x6fa06vtg7ghdqa7r9znvzjlxyckt3ykq9p7766hyjscw73gv" }, + { "370df14aafe51c8bbdbafeab42bafe5983f50ce0e2e3ce4d57bbbd7a53ec3b9b", "txch1xuxlzj40u5wgh0d6l6459wh7txpl2r8qut3uun2hhw7h55lv8wdsx632ps" }, + { "6d119b0e258940fe2b36142b33eedc0babf02fa5ff856ac62c5b9f6ece373f99", "txch1d5gekr3939q0u2ekzs4n8mkupw4lqta9l7zk433vtw0kan3h87vsdwk3cs" }, + { "31a1d0759e1f0426c0b24386607c9f84946b87ac549afe03d0f95723bf5de4ae", "txch1xxsaqav7ruzzds9jgwrxqlylsj2xhpav2jd0uq7sl9tj806aujhqsnn79j" }, + { "023b0bc6f0ff730a75f45fe8491a9ce34d71d46aea9f51bbc546ebd7d45d4c22", "txch1qgash3hslaes5a05tl5yjx5uudxhr4r2a204rw79gm4a04zafs3qrkh0sq" }, + { "fe693be0ac003cdddd0aa1dfab3726c2700844924a95f7b78b07a27468079f75", "txch1le5nhc9vqq7dmhg25806kdexcfcqs3yjf22l0dutq738g6q8na6szzek8w" }, + { "44e617d3f9d4d26f1b532de3d73986d527465c92da02b11481d84ee704f80abe", "txch1gnnp05le6nfx7x6n9h3awwvx65n5vhyjmgptz9ypmp8wwp8cp2lqztdsea" }, + { "f447ec98ada6f9889ed493fff1c835bcf978d9a0260084bbdfacd15c7ca7a7f5", "txch173r7ex9d5muc38k5j0llrjp4hnuh3kdqycqgfw7l4ng4cl985l6sxfpmly" }, + { "f1c843757250600725acaadf8806290ddc527c5209bb0b29337a42348c0feed6", "txch178yyxatj2psqwfdv4t0csp3fphw9ylzjpxask2fn0fprfrq0amtqd2cj8k" }, + { "6dcd7933c81b6eb471cf8d563e269ac02b5456dc1d801a2bc7f9998c16d4d8e8", "txch1dhxhjv7grdhtguw034truf56cq44g4kurkqp5278lxvcc9k5mr5qrd30ly" }, + { "d64aa4dcc4bb024d241d87fdf47ea206fd4549ab648cd3c7c1f100519aadb527", "txch16e92fhxyhvpy6fqasl7lgl4zqm752jdtvjxd837p7yq9rx4dk5nsamwewz" }, + { "e468ea48db87bb2fdff4f59e566107decbdfa7ffbaeb4085455a96bb62ceb873", "txch1u35w5jxms7ajlhl57k09vcg8mm9alfllht45pp29t2ttkckwhpes50yjz9" }, + { "2281003c00ef688327fb68843f48f43e6977ea3c015b30065eaa9cb7965543ed", "txch1y2qsq0qqaa5gxflmdzzr7j858e5h063uq9dnqpj742wt09j4g0kszkawtv" }, + { "bad393e3928397cd478483cc6d79fae6be09b3290ac0ae3f5d803e686bab04fa", "txch1htfe8cujswtu63uys0xx6706u6lqnvefptq2u06asqlxs6atqnaqzefxh6" }, + { "f42e6d8046e4f30d83c29cd4188e0830f95c4725488634928bf3b50d01d6a39e", "txch17shxmqzxunesmq7znn2p3rsgxru4c3e9fzrrfy5t7w6s6qwk5w0q3ugana" }, + { "479fb588e0ecd80ffbf9012fcc0c10959f214858f5b6eeb4882dfb7e5566041a", "txch1g70mtz8qanvql7leqyhucrqsjk0jzjzc7kmwadyg9hahu4txqsdqqr7nh4" }, + { "e34acdb37b15d8c0185d99da9c036fde15dc3e31a14ac434b077bc1a9283760d", "txch1ud9vmvmmzhvvqxzan8dfcqm0mc2ac033599vgd9sw77p4y5rwcxsxrv865" }, + { "7f394c68c60863d9b912137a38ce41efadffe28458ec74165920d37d4c23b576", "txch10uu5c6xxpp3anwgjzdar3njpa7kllc5ytrk8g9jeyrfh6nprk4mqnn3ewy" }, + { "085ce8043606b4d45c03e8030ff4a1a7b2404add6c6ef9180c174babdececba1", "txch1ppwwsppkq66dghqraqpsla9p57eyqjkad3h0jxqvza96hhkwewsstv5w2d" }, + { "63207f0c61235a6d398b958da889c9f1f02055d745a705c95b6752466d5f44af", "txch1vvs87rrpyddx6wvtjkx63zwf78czq4whgknstj2mvafyvm2lgjhsntgkea" }, + { "8164ce23efe7a4cf51629406479d2bf6239c7e291677b923bf2e21732c3a2f45", "txch1s9jvugl0u7jv75tzjsry08ft7c3ecl3fzemmjgal9cshxtp69azs7qugud" }, + { "73ad844ee4777ffb842d8b5dc527578536be5f100f5767336c0159613dc9384b", "txch1wwkcgnhywallhppd3dwu2f6hs5mtuhcspatkwvmvq9vkz0wf8p9srv36wj" }, + { "92630a3e0948419a999e7f50aa61e25d15f953bf74c6cb6a0e670e08b1f250e5", "txch1jf3s50sffpqe4xv70ag25c0zt52lj5alwnrvk6swvu8q3v0j2rjs53ad6p" }, + { "017096f243423314136b72ab87a6f4dbec065b49aad4478bb8bb7e85f1b6e047", "txch1q9cfdujrgge3gymtw24c0fh5m0kqvk6f4t2y0zachdlgtudkuprsa0j809" }, + { "08287da359856dd0a44516220a7405c8f4fe333de6f4b643d402f7fa004cd388", "txch1pq58mg6es4kapfz9zc3q5aq9er60uveaum6tvs75qtml5qzv6wyq95ex7p" }, + { "b61c0b598613f0f17c09c9662cb2cb1c01bd5e518a178423a9c2bb431d061f47", "txch1kcwqkkvxz0c0zlqfe9nzevktrsqm6hj33gtcggafc2a5x8gxrarsq2ny07" }, + { "b39900d80c8c601a976d795f707d1a1f1e4632ea6f54d73f20d81570bc763431", "txch1kwvspkqv33sp49md090hqlg6ru0yvvh2da2dw0eqmq2hp0rkxscslzqhgt" }, + { "f73bd112ebd018550d3719576c1ba23d5958696ea9bf4cbf6b15131228279dce", "txch17uaazyht6qv92rfhr9tkcxaz84v4s6tw4xl5e0mtz5f3y2p8nh8q6xys6m" }, + { "82223810d79cbe879918446f8d0f9e2e76ef988cd7dd6b577be6ec7002f21c34", "txch1sg3rsyxhnjlg0xgcg3hc6ru79emwlxyv6lwkk4mmumk8qqhjrs6qhe64e8" }, + { "295d716956a3f315f6ff669c46a49cffe094effd406d1f34e7af28ff68caaa8f", "txch199whz62k50e3tahlv6wydfyullsffmlagpk37d884u5076x2428sl9js9z" }, + { "834a40026b82830eaf4da8b62bf769069729d905a813408dc784fd7294d82a3d", "txch1sd9yqqnts2psat6d4zmzhamfq6tjnkg94qf5prw8sn7h99xc9g7stktagd" }, + { "9514e52eca63f5fc4813de586ff14665b1bd753bb60fa7a05ab4b4a23dcf9113", "txch1j52w2tk2v06lcjqnmevxlu2xvkcm6afmkc860gz6kj62y0w0jyfsvk8zxu" }, + { "6c6b7afdf8966ca381548848f3f084cf11d6b55e6743facc1d7fedefaa816a47", "txch1d34h4l0cjek28q253py08uyyeugadd27vapl4nqa0lk7l25pdfrsff3mqh" }, + { "dac2f7fefc09326d609f836b905a83cf917d3becd649369c22e8037548b694ce", "txch1mtp00lhupyex6cylsd4eqk5re7gh6wlv6eynd8pzaqph2j9kjn8q2mm2kf" }, + { "5a9ddd14e6199b528bed92460f09e5ddadf16d62adfc7ffba922654d3421e85f", "txch1t2wa698xrxd49zldjfrq7z09mkklzmtz4h78l7afyfj56dppap0sf8azup" }, + { "42e5d55424544c60483af0020fa5469684a3644f60ea87d49ca6b38aad58f0ce", "txch1gtja24py23xxqjp67qpqlf2xj6z2xez0vr4g04yu56ec4t2c7r8qmksnat" }, + { "c25968cb67b8f121fcbc8f9bca154cf19b4374eae060be2982c191d1dcc6bd93", "txch1cfvk3jm8hrcjrl9u37du592v7xd5xa82upstu2vzcxgarhxxhkfsphz0jf" }, + { "5e23a0bf00edea77914db18659930f302cb765c02ced96cc18b4307f86edd22b", "txch1tc36p0cqah480y2dkxr9nyc0xqktwewq9nkednqcksc8lphd6g4s39q3kf" }, + { "67c137e35970616b1aa8b82385c469fabc8971bf65cba8959b7989bfdd3e9d39", "txch1vlqn0c6ewpskkx4ghq3ct3rfl27gjudlvh9639vm0xymlhf7n5usjlavjc" }, + { "b964e559d6ba0c4128d3096144d59012cec65d2bfe1cf6271099ce03a56b1b4b", "txch1h9jw2kwkhgxyz2xnp9s5f4vszt8vvhftlcw0vfcsn88q8fttrd9smduhj8" }, + { "c516afae32a9250b0fd79f5da6be19316ae74129f9fc6efe032142bbb00dc3a8", "txch1c5t2lt3j4yjskr7hnaw6d0sex94wwsffl87xalsry9pthvqdcw5qyzdhjt" }, + { "5d5a17d3034712028842ecb4fff6dccaaf99e106d8b8515bcdb67804e89a9daa", "txch1t4dp05crgufq9zzzaj60lakue2hencgxmzu9zk7dkeuqf6y6nk4qv5u26t" }, + { "9e331b161c0988359da1c27f36e918c2335a662c439f2b96abb3619a637d0cae", "txch1nce3k9supxyrt8dpcflnd6gccge45e3vgw0jh94tkdse5cmapjhqhn0473" }, + { "582ce73e4c77d60012945c3d6350370cdb2af6333409fa60b506f4a6e4bd2946", "txch1tqkww0jvwltqqy55ts7kx5phpndj4a3nxsyl5c94qm62de9a99rqywqp92" }, + { "4da8f6ba5b92ef20109684d977d843b9aefb47a51d53a6ba97fbd11366da4310", "txch1fk50dwjmjthjqyyksnvh0kzrhxh0k3a9r4f6dw5hl0g3xek6gvgq86tlw2" }, + { "febfabee0c7b62debec48762e751558b97ab54729fc296b162323c2fd8463955", "txch1l6l6hmsv0d3da0kysa3ww5243wt6k4rjnlpfdvtzxg7zlkzx892sgzyrsm" }, + { "4fb9770c9127ef646dada9e1d55a6cbaeea9e60f354aeb4773a487c665016b94", "txch1f7uhwry3ylhkgmdd48sa2knvhth2nes0x49wk3mn5jruvegpdw2q6gcygz" }, + { "f824cc1566f8a53d0aaa4da1756520c8461031c87a1d63d89841d858114d6a54", "txch1lqjvc9txlzjn6z42fksh2efqeprpqvwg0gwk8kycg8v9sy2ddf2q24vw2y" }, + { "e574f7bc5f11b98f793074d861b5e0f9292a2b25998493e975e9a11240f4f193", "txch1u46000zlzxuc77fswnvxrd0qly5j52e9nxzf86t4axs3ys857xfsrcpds4" }, + { "9cbaa6b9a0cb6b37e13a3a1cfd8692f38ab01eaca1005e29ee2c5e271dc6ed24", "txch1nja2dwdqed4n0cf68gw0mp5j7w9tq84v5yq9u20w930zw8wxa5jq3nxh44" }, + { "140608ba69f6f0556f31cecc245f7abe13bdc15bb67c3f3ebde1ae04f8757567", "txch1zsrq3wnf7mc92me3emxzghm6hcfmms2mke7r704auxhqf7r4w4nscd9gt8" }, + { "e157ca0c6ee66e5316abd1a68269b64588c2035477719b1490b0b77830372d7e", "txch1u9tu5rrwueh9x94t6xngy6dkgkyvyq65wacek9yskzmhsvph94lqenuq5p" }, + { "15a418f5d57ecbd33bc46c76d6108cc59b8621aff05b641e22dfebf2ec032d39", "txch1zkjp3aw40m9axw7yd3mdvyyvckdcvgd07pdkg83zml4l9mqr95usn2nhvk" }, + { "88aa08520bb7710b67a36eb43c21f0e81dd22e2a26f0c385cb206d7fb29d1f54", "txch13z4qs5stkacskeard66rcg0saqwayt32ymcv8pwtypkhlv5ara2qa9qs2n" }, + { "1caf19f00f4ff21dd8282940bbe8ba0ff4ac44ccbbae6a90aa0af0305922259f", "txch1rjh3nuq0flepmkpg99qth696pl62c3xvhwhx4y92ptcrqkfzyk0sj9wgt0" }, + { "c71faab73c148b3b0120261e709382335d15dc743064df8e72ba3377069789e4", "txch1cu064deuzj9nkqfqyc08pyuzxdw3thr5xpjdlrnjhgehwp5h38jqyl6ws9" }, + { "6e71192dcc34563609ca9b8fbfb8db5ac09bf44942e74e1abd83395fdb595529", "txch1dec3jtwvx3trvzw2nw8mlwxmttqfhazfgtn5ux4asvu4lk6e255s7vkymp" }, + { "510e88adee17a55ccdd71defca67ae9aaf7637cf83abd9501a37654d03d647c5", "txch12y8g3t0wz7j4enwhrhhu5eawn2hhvd70sw4aj5q6xaj56q7kglzs039wvy" }, + { "0ec95d90e5d7c2c8ebf060803a4d32a7581d7430ccff994f43670a885aa3e156", "txch1pmy4my896lpv36lsvzqr5nfj5avp6apsenlejn6rvu9gsk4ru9tqkm5ypm" }, + { "8b1e222dc681fa549eb01336fa1eab89858902914f8b83390152d7fd033a337f", "txch13v0zytwxs8a9f84szvm0584t3xzcjq53f79cxwgp2ttl6qe6xdlsx0upm3" }, + { "a4a365c1f57906bf462f17b8731ff47a4a3d23cc9da6953bc33162bc3e1db462", "txch15j3kts040yrt7330z7u8x8l50f9r6g7vnknf2w7rx93tc0sak33q0y2tes" }, + { "9175c583d644733a3773fda684d2143a02cb2d3184f2c0fea807183d453a3f10", "txch1j96utq7kg3en5dmnlkngf5s58gpvktf3snevpl4gquvr63f68ugq8rzef3" }, + { "b65a628cf24a7870160b4a244ea09cf6e233dbb48e94781f30763fe454cf7ead", "txch1kedx9r8jffu8q9stfgjyagyu7m3r8ka53628s8eswcl7g4x006ksuvkwa5" }, + { "85d1bafcbbd93e0e575b584811dd1c45231303a061c0460d30eb9bcf247819b9", "txch1shgm4l9mmylqu46mtpyprhgug533xqaqv8qyvrfsawdu7frcrxusdzv6ze" }, +}; + From a395f44cab55524a757a5cdb30dad4d08ee307f4 Mon Sep 17 00:00:00 2001 From: Harold B Date: Fri, 23 Sep 2022 16:31:57 -0500 Subject: [PATCH 87/91] Version bump to 2.0.0-beta1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0b303383..eab045f4 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ 2.0.0 --alpha2 \ No newline at end of file +-beta1 \ No newline at end of file From 0d30b057b5bddb7f283a5e6a03e6466606053ca9 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Fri, 21 Oct 2022 16:12:51 -0500 Subject: [PATCH 88/91] Added support for ram plotting in new CLI interface. (#229) * Added support for `ramplot` command in new CLI interface. * Fixed final f7 value pointing to a non-existent proof. * Added some more plot validation work. * Fixed issue with `diskplot --sizes` crash --- .vscode/launch.json | 42 ++--- src/main.cpp | 73 ++++++++- src/plotdisk/DiskPlotter.cpp | 14 +- src/plotdisk/k32/FxBounded.inl | 21 --- src/plotmem/MemPhase3.cpp | 6 - src/plotmem/MemPlotter.h | 2 + src/plotting/PlotTools.h | 2 + src/plotting/PlotTypes.h | 19 ++- src/plotting/Tables.h | 25 ++- src/tools/PlotReader.cpp | 281 ++++++++++++++++++++++++++++++++- src/tools/PlotReader.h | 38 +++-- src/tools/PlotValidator.cpp | 164 +++++++++++++++++-- src/util/BitView.h | 8 + 13 files changed, 598 insertions(+), 97 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 20733749..246a5532 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -33,10 +33,12 @@ "args": [ "-f", "ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef", "-p", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8", - "-n", "2", + "-i", "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835", + // "-n", "1", "-w", "-v", - "${workspaceFolder}/.sandbox" + "ramplot", + "~/plot/tmp" ] }, @@ -73,9 +75,9 @@ "-p", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8", // "-c", "xch1uf48n3f50xrs7zds0uek9wp9wmyza6crnex6rw8kwm3jnm39y82q5mvps6", "-t", "62", - "-w", + // "-w", // "-v", - "-n", "3", + // "-n", "3", "-i", "c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835", // No overflow "--memo", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef01b7bf8a22a9ac82a003e07b551c851ea683839f3e1beb8ac9ede57d2c020669", @@ -83,7 +85,9 @@ // "--memo", "80a836a74b077cabaca7a76d1c3c9f269f7f3a8f2fa196a65ee8953eb81274eb8b7328d474982617af5a0fe71b47e9b8ade0cc43610ce7540ab96a524d0ab17f5df7866ef13d1221a7203e5d10ad2a4ae37f7b73f6cdfd6ddf4122e8a1c2f8ef207d52406afa2b6d7d92ea778f407205bd9dca40816c1b1cacfca2a6612b93eb", "--show-memo", + "diskplot", + "-t1", "~/plot/tmp", "--f1-threads", "24", // "--fp-threads", "62", @@ -91,15 +95,15 @@ "--p2-threads", "24", // "-a", - "--cache", "196G", + // "--cache", "110G", // "--cache", "99G", - // "--cache", "200G", + "--cache", "200G", // "--cache", "64G", // "-s", // "--k32-bounded", - // "-b", "64", + "-b", "64", // "--sizes", - "-b", "128", + // "-b", "128", // "-b", "256", "--c-threads", "26", @@ -172,18 +176,17 @@ "args": [ "-b", - // "F1CompressToBits" // "F1GenBucketized" // "FxSort" // "FxDisk" // "F1Disk" // "PairsAndMap" - "bucket-slice-write" + // "bucket-slice-write" + // "line-point-deltas" ] } - ,{ "name" : "Plot Tool", @@ -205,20 +208,23 @@ "args": [ /// Validate - "-t", "32", + // "-t", "32", // "-t", "1", - // "validate", + "validate", + + "--f7", "2534554965", + "~/plot/tmp/plot-k32-2022-10-18-22-25-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot" + // "-m", // "-u", - // "-o", "99.7", - // "/mnt/p5510a/disk_tmp/plot-k32-2022-04-12-13-03-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot.tmp", + // "~/plot/tmp/plot-k32-2022-10-17-15-05-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot", // "/mnt/p5510a/disk_tmp/plot.dat" /// Compare - "plotcmp", - "/mnt/p5510a/disk_tmp/plot-k32-2022-04-12-13-53-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot", - "/mnt/p5510a/disk_tmp/plot-k32-2022-04-12-13-03-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot" + // "plotcmp", + // "/mnt/p5510a/disk_tmp/plot-k32-2022-04-12-13-53-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot", + // "/mnt/p5510a/disk_tmp/plot-k32-2022-04-12-13-03-c6b84729c23dc6d60c92f22c17083f47845c1179227c5509f07a5d2804a7b835.plot" ] }, diff --git a/src/main.cpp b/src/main.cpp index 2376edf6..7938fc3e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include "plotting/GlobalPlotConfig.h" #include "util/CliParser.h" #include "plotdisk/DiskPlotter.h" +#include "plotmem/MemPlotter.h" #include "Version.h" #if PLATFORM_IS_UNIX @@ -27,12 +28,20 @@ void PlotCompareMain( GlobalPlotConfig& gCfg, CliParser& cli ); void PlotCompareMainPrintUsage(); +enum class PlotterType +{ + None = 0, + Ram, + Disk +}; struct Plotter { + PlotterType type; union { void* _ptr; DiskPlotter* disk; + MemPlotter* mem; }; }; @@ -48,12 +57,12 @@ int main( int argc, const char* argv[] ) Log::Line( "*** Warning: Debug mode is ENABLED ***" ); #endif - ZeroMem( &_plotter ); + _plotter = {}; GlobalPlotConfig cfg; ParseCommandLine( cfg, --argc, ++argv ); - FatalIf( !_plotter._ptr, "No command chosen." ); + FatalIf( !_plotter._ptr, "No plot command chosen." ); const int64 plotCount = cfg.plotCount > 0 ? (int64)cfg.plotCount : std::numeric_limits::max(); @@ -121,7 +130,20 @@ int main( int argc, const char* argv[] ) } Log::Line( "" ); - if( _plotter.disk ) + if( _plotter.type == PlotterType::Ram ) + { + auto& plotter = *_plotter.mem; + + PlotRequest req = {}; + req.plotId = plotId; + req.memo = plotMemo; + req.memoSize = plotMemoSize; + req.outPath = plotOutPath; + req.IsFinalPlot = i == plotCount-1; + + plotter.Run( req ); + } + else if( _plotter.type == PlotterType::Disk ) { auto& plotter = *_plotter.disk; @@ -132,6 +154,10 @@ int main( int argc, const char* argv[] ) req.plotFileName = plotFileName; plotter.Plot( req ); } + else + { + Fatal( "Unknown plotter type." ); + } } } @@ -144,6 +170,9 @@ void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ) const char* poolPublicKey = nullptr; const char* poolContractAddress = nullptr; + DiskPlotter::Config diskCfg = {}; + MemPlotConfig ramCfg = {}; + while( cli.HasArgs() ) { if( cli.ReadU32( cfg.threadCount, "-t", "--threads" ) ) @@ -239,12 +268,22 @@ void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ) } #endif - DiskPlotter::Config diskCfg; + // DiskPlotter::Config diskCfg; diskCfg.globalCfg = &cfg; DiskPlotter::ParseCommandLine( cli, diskCfg ); - _plotter.disk = new DiskPlotter( diskCfg ); + _plotter.type = PlotterType::Disk; + break; + } + else if( cli.ArgConsume( "ramplot" ) ) + { + ramCfg.threadCount = cfg.threadCount == 0 ? + SysHost::GetLogicalCPUCount() : + bbclamp( cfg.threadCount, 1u, SysHost::GetLogicalCPUCount() ); + ramCfg.warmStart = cfg.warmStart; + ramCfg.gCfg = &cfg; + _plotter.type = PlotterType::Ram; break; } else if( cli.ArgConsume( "iotest" ) ) @@ -374,6 +413,12 @@ void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ) // Config Summary Log::Line( "" ); + Log::Line( "Bladebit Chia Plotter" ); + Log::Line( "Version : %s", BLADEBIT_VERSION_STR ); + Log::Line( "Git Commit : %s", BLADEBIT_GIT_COMMIT ); + Log::Line( "Compiled With: %s", BBGetCompilerVersion() ); + Log::Line( "" ); + Log::Line( "[Global Plotting Config]" ); if( cfg.plotCount == 0 ) Log::Line( " Will create plots indefinitely." ); @@ -396,6 +441,23 @@ void ParseCommandLine( GlobalPlotConfig& cfg, int argc, const char* argv[] ) Log::Line( " Output path : %s", cfg.outputFolder ); Log::Line( "" ); + + // Create plotter + switch( _plotter.type ) + { + case PlotterType::Disk: + _plotter.disk = new DiskPlotter( diskCfg ); + break; + + case PlotterType::Ram: + _plotter.mem = new MemPlotter( ramCfg ); + break; + + default: + Fatal( "No plotter chosen." ); + break; + } + Log::Line( "" ); } @@ -404,6 +466,7 @@ static const char* USAGE = "bladebit [GLOBAL_OPTIONS] [COMMAND_OPTIONS R"( [COMMANDS] diskplot : Create a plot by making use of a disk. + ramplot : Create a plot completely in-ram. iotest : Perform a write and read test on a specified disk. memtest : Perform a memory (RAM) copy test. validate : Validates all entries in a plot to ensure they all evaluate to a valid proof. diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 0f55f143..7679ce12 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -314,16 +314,14 @@ void DiskPlotter::ParseCommandLine( CliParser& cli, Config& cfg ) FatalIf( cfg.numBuckets < BB_DP_MIN_BUCKET_COUNT || cfg.numBuckets > BB_DP_MAX_BUCKET_COUNT, "Buckets must be between %u and %u, inclusive.", (uint)BB_DP_MIN_BUCKET_COUNT, (uint)BB_DP_MAX_BUCKET_COUNT ); FatalIf( ( cfg.numBuckets & ( cfg.numBuckets - 1 ) ) != 0, "Buckets must be power of 2." ); + FatalIf( !cfg.tmpPath, "Please specify at least 1 temporary path." ); + + const uint32 threadCount = bbclamp( cfg.globalCfg->threadCount, 1u, SysHost::GetLogicalCPUCount() ); size_t heapSize = 0; - if( cfg.tmpPath ) - { - cfg.tmpPath2 = cfg.tmpPath2 ? cfg.tmpPath2 : cfg.tmpPath; - heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, cfg.tmpPath2, cfg.tmpPath, BB_DP_MAX_JOBS ); - } - else - heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, 1, 1, BB_DP_MAX_JOBS ); - + cfg.tmpPath2 = cfg.tmpPath2 ? cfg.tmpPath2 : cfg.tmpPath; + heapSize = GetRequiredSizeForBuckets( cfg.bounded, cfg.numBuckets, cfg.tmpPath2, cfg.tmpPath, threadCount ); + Log::Line( "Buckets: %u | Heap Sizes: %.2lf GiB", cfg.numBuckets, (double)heapSize BtoGB ); exit( 0 ); } diff --git a/src/plotdisk/k32/FxBounded.inl b/src/plotdisk/k32/FxBounded.inl index 03aa1934..fbfb2e4e 100644 --- a/src/plotdisk/k32/FxBounded.inl +++ b/src/plotdisk/k32/FxBounded.inl @@ -37,27 +37,6 @@ #endif -typedef uint32 K32Meta1; -typedef uint64 K32Meta2; -// struct K32Meta3 { uint32 m0, m1, m2; }; -struct K32Meta3 { uint64 m0, m1; }; -struct K32Meta4 { uint64 m0, m1; }; -struct K32NoMeta {}; - -template -struct K32MetaType{}; - -template<> struct K32MetaType{ using In = K32NoMeta; using Out = K32Meta1; }; -template<> struct K32MetaType{ using In = K32Meta1; using Out = K32Meta2; }; -template<> struct K32MetaType{ using In = K32Meta2; using Out = K32Meta4; }; -template<> struct K32MetaType{ using In = K32Meta4; using Out = K32Meta4; }; -template<> struct K32MetaType{ using In = K32Meta4; using Out = K32Meta3; }; -template<> struct K32MetaType{ using In = K32Meta3; using Out = K32Meta2; }; -template<> struct K32MetaType{ using In = K32Meta2; using Out = K32NoMeta; }; - -template struct K32TYOut { using Type = uint64; }; -template<> struct K32TYOut { using Type = uint32; }; - template class DiskPlotFxBounded { diff --git a/src/plotmem/MemPhase3.cpp b/src/plotmem/MemPhase3.cpp index bc7cf634..c9f1b7c3 100644 --- a/src/plotmem/MemPhase3.cpp +++ b/src/plotmem/MemPhase3.cpp @@ -152,12 +152,6 @@ uint64 MemPhase3::ProcessTable( uint32* lEntries, uint64* lpBuffer, Pair* rTable lEntries, lEntriesSortTmp, newLength ); - // #NOTE: Because the C2 table size is inferred by substracting table pointers - // in chiapos, we need to make sure we don't have any f7 entries with the - // value of 0xFFFFFFFF. See WriteC12Parallel in Phase4 for more details. - while( newLength && cx.t7YBuffer[newLength-1] == 0xFFFFFFFF ) - --newLength; - cx.entryCount[(uint)TableId::Table7] = newLength; } diff --git a/src/plotmem/MemPlotter.h b/src/plotmem/MemPlotter.h index a7411fed..fb931c19 100644 --- a/src/plotmem/MemPlotter.h +++ b/src/plotmem/MemPlotter.h @@ -1,10 +1,12 @@ #pragma once #include "PlotContext.h" +#include "plotting/GlobalPlotConfig.h" struct NumaInfo; struct MemPlotConfig { + GlobalPlotConfig* gCfg; uint threadCount; bool warmStart; bool noNUMA; diff --git a/src/plotting/PlotTools.h b/src/plotting/PlotTools.h index b5e339fa..63ce8f41 100644 --- a/src/plotting/PlotTools.h +++ b/src/plotting/PlotTools.h @@ -2,6 +2,8 @@ #include "ChiaConsts.h" #include "util/KeyTools.h" +#define BB_PLOT_PROOF_X_COUNT 32 + #define BB_PLOT_ID_LEN 32 #define BB_PLOT_ID_HEX_LEN (BB_PLOT_ID_LEN * 2) diff --git a/src/plotting/PlotTypes.h b/src/plotting/PlotTypes.h index 6817b9ac..379970cf 100644 --- a/src/plotting/PlotTypes.h +++ b/src/plotting/PlotTypes.h @@ -1,5 +1,4 @@ #pragma once -#include "threading/AutoResetSignal.h" struct Pairs { @@ -28,4 +27,20 @@ struct Pair return *this; } }; -static_assert( sizeof( Pair ) == 8, "Invalid Pair struct." ); \ No newline at end of file +static_assert( sizeof( Pair ) == 8, "Invalid Pair struct." ); + + +enum class PlotTable +{ + Table1 = 0, + Table2, + Table3, + Table4, + Table5, + Table6, + Table7, + C1, + C2, + C3, +}; ImplementArithmeticOps( PlotTable ); + diff --git a/src/plotting/Tables.h b/src/plotting/Tables.h index 53b3924d..3acf900d 100644 --- a/src/plotting/Tables.h +++ b/src/plotting/Tables.h @@ -41,7 +41,7 @@ template<> struct TableMetaType { using MetaIn = Meta3; using template<> struct TableMetaType { using MetaIn = uint64; using MetaOut = NoMeta; }; -/// Helper for obtaining the correct fx (y) output type per table + template struct YOut { using Type = uint64; }; template<> struct YOut { using Type = uint32; }; @@ -172,3 +172,26 @@ template<> struct TableMetaOut }; // static_assert( sizeof( NoMeta ) == 0, "Invalid NoMeta" ); + + +/// For bounded k32 +typedef uint32 K32Meta1; +typedef uint64 K32Meta2; +struct K32Meta3 { uint64 m0, m1; }; +struct K32Meta4 { uint64 m0, m1; }; +struct K32NoMeta {}; + +template +struct K32MetaType{}; + +template<> struct K32MetaType{ using In = K32NoMeta; using Out = K32Meta1; }; +template<> struct K32MetaType{ using In = K32Meta1; using Out = K32Meta2; }; +template<> struct K32MetaType{ using In = K32Meta2; using Out = K32Meta4; }; +template<> struct K32MetaType{ using In = K32Meta4; using Out = K32Meta4; }; +template<> struct K32MetaType{ using In = K32Meta4; using Out = K32Meta3; }; +template<> struct K32MetaType{ using In = K32Meta3; using Out = K32Meta2; }; +template<> struct K32MetaType{ using In = K32Meta2; using Out = K32NoMeta; }; + +/// Helper for obtaining the correct fx (y) output type per table +template struct K32TYOut { using Type = uint64; }; +template<> struct K32TYOut { using Type = uint32; }; diff --git a/src/tools/PlotReader.cpp b/src/tools/PlotReader.cpp index 38e6f5fd..bb4a84d6 100644 --- a/src/tools/PlotReader.cpp +++ b/src/tools/PlotReader.cpp @@ -4,6 +4,7 @@ #include "plotting/PlotTools.h" #include "plotting/CTables.h" #include "plotting/DTables.h" +#include "plotmem/LPGen.h" /// /// Plot Reader @@ -25,6 +26,15 @@ PlotReader::~PlotReader() { free( _parkBuffer ); free( _deltasBuffer ); + + if( _c2Entries.values ) + bbvirtfreebounded( _c2Entries.values ); + + if( _c1Buffer ) + bbvirtfreebounded( _c1Buffer ); + + if( _c3Buffer.Ptr() ) + bbvirtfreebounded( _c3Buffer.Ptr() ); } //----------------------------------------------------------- @@ -35,9 +45,7 @@ uint64 PlotReader::GetC3ParkCount() const // However, to make sure this is the case, we'll have to // read-in all C1 entries and ensure we hit an empty one, // to ensure we don't run into dead/alignment-space - const size_t c1TableSize = _plot.TableSize( PlotTable::C1 ); - const size_t f7Size = CDiv( _plot.K(), 8 ); - const uint64 c3ParkCount = std::max( c1TableSize / f7Size, (size_t)1 ) - 1; + const uint64 c3ParkCount = GetMaximumC1Entries(); // Or just do this: // Same thing, but we use it @@ -81,6 +89,59 @@ size_t PlotReader::GetTableParkCount( const PlotTable table ) const } } +//----------------------------------------------------------- +uint64 PlotReader::GetMaximumC1Entries() const +{ + // -1 because an extra 0 entry is added at the end + const size_t c1TableSize = _plot.TableSize( PlotTable::C1 ); + const size_t f7Size = CDiv( _plot.K(), 8 ); + const uint64 c3ParkCount = std::max( c1TableSize / f7Size, (size_t)1 ) - 1; + + return c3ParkCount; +} + +//----------------------------------------------------------- +bool PlotReader::GetActualC1EntryCount( uint64& outC1Count ) +{ + outC1Count = 0; + + const uint64 maxC1Entries = GetMaxF7EntryCount(); + + if( maxC1Entries < 1 ) + return true; + + const size_t f7SizeBytes = CDiv( _plot.K(), 8 ); + const uint64 c1Address = _plot.TableAddress( PlotTable::C1 ); + const size_t c1TableSize = _plot.TableSize( PlotTable::C1 ); + size_t c1ReadAddress = c1Address + c1TableSize - f7SizeBytes; + + // Read entries from the end of the table until the start, until we find an entry that is + // not zero/higher than the previous one + if( !_plot.Seek( SeekOrigin::Begin, (int64)c1ReadAddress ) ) + return false; + + const uint32 k = _plot.K(); + uint64 c1 = 0; + while( c1ReadAddress >= c1Address ) + { + uint64 newC1; + if( _plot.Read( f7SizeBytes, &newC1 ) != (ssize_t)f7SizeBytes ) + return false; + + newC1 = Swap64( newC1 ) >> ( 64 - k ); + if( newC1 > c1 ) + break; + + if( c1ReadAddress <= c1Address ) + return false; + + c1ReadAddress -= f7SizeBytes; + } + + outC1Count = ( c1ReadAddress - c1Address ) / f7SizeBytes; + return true; +} + //----------------------------------------------------------- int64 PlotReader::ReadC3Park( uint64 parkIndex, uint64* f7Buffer ) { @@ -368,6 +429,220 @@ bool PlotReader::FetchProofFromP7Entry( uint64 p7Entry, uint64 proof[32] ) return false; } +//----------------------------------------------------------- +Span PlotReader::GetP7IndicesForF7( const uint64 f7, Span indices ) +{ + if( indices.Length() == 0 ) + return {}; + + if( !LoadC2Entries() ) + return {}; + + uint64 c2Index = 0; + + for( uint64 i = 0; ; ) + { + const uint64 c2 = _c2Entries[i]; + + if( c2 > f7 || ++i >= _c2Entries.Length() ) + { + if( c2Index > 0 ) c2Index--; + break; + } + + c2Index++; + } + + const uint64 c1StartIndex = c2Index * kCheckpoint2Interval; + + const uint32 k = _plot.K(); + const size_t f7SizeBytes = CDiv( k, 8 ); + const size_t f7BitCount = f7SizeBytes * 8; + const uint64 c1TableAddress = _plot.TableAddress( PlotTable::C1 ); + const size_t c1TableSize = _plot.TableSize( PlotTable::C1 ); + const uint64 c1TableEnd = c1TableAddress + c1TableSize; + const uint64 c1EntryAddress = c1TableAddress + c1StartIndex * f7SizeBytes; + + + const uint64 c1EndAddress = std::min( c1EntryAddress + ( kCheckpoint1Interval * f7SizeBytes ), c1TableEnd ); + + const size_t readSize = c1EndAddress - c1EntryAddress; + const uint64 c1EntryCount = readSize / f7SizeBytes; + + if( c1EntryCount < 1 ) + return {}; + + if( !_plot.Seek( SeekOrigin::Begin, (int64)c1EntryAddress ) ) + { + Log::Error( "Seek to C1 address failed: %d", _plot.GetError() ); + return {}; + } + + // Read C1 entries until we find one equal or larger than the f7 we're looking for + if( !_c1Buffer ) + _c1Buffer = bbcvirtallocbounded( kCheckpoint1Interval * f7SizeBytes ); + + if( _plot.Read( readSize, _c1Buffer ) != (ssize_t)readSize ) + { + Log::Error( "Failed to read C1 entries: %d", _plot.GetError() ); + return {}; + } + + CPBitReader reader( _c1Buffer, readSize * 8 ); + uint64 c3Park = c1StartIndex; + uint64 c1 = 0; + + for( uint64 i = 0; ; ) + { + c1 = reader.Read64( (uint32)f7BitCount ); + + if( c1 >= f7 || ++i >= c1EntryCount ) + { + if( c3Park > 0 ) c3Park--; + break; + } + + c3Park++; + } + + const uint64 parkCount = c1 == f7 && c3Park > 0 ? 2 : 1; // If we got the same c1 as f7, then the previous + // needs to be read as well because we may have duplicate f7s + // in the previous park's last entries. + + if( _c3Buffer.Ptr() == nullptr ) + { + _c3Buffer.values = bbcvirtallocbounded( kCheckpoint1Interval * 2 ); + _c3Buffer.length = kCheckpoint1Interval * 2; + } + + uint64 c3Count = (uint64)ReadC3Park( c3Park, _c3Buffer.Ptr() ); + + if( parkCount > 1 ) + { + ASSERT( parkCount == 2 ); + c3Count += (uint64)ReadC3Park( c3Park+1, _c3Buffer.Ptr() + c3Count ); + } + + // Grab as many matches as we can + const Span c3Entries = _c3Buffer.SliceSize( (size_t)c3Count ); + const uint64 c3StartIndex = c3Park * kCheckpoint1Interval; + uint64 matchCount = 0; + + for( uint64 i = 0; i < c3Entries.Length(); i++ ) + { + if( c3Entries[i] == f7 ) + { + while( matchCount < indices.Length() && i < c3Count && c3Entries[i] == f7 ) + indices[matchCount++] = c3StartIndex + i++; + + return indices.SliceSize( matchCount ); + } + } + + return {}; +} + + +//----------------------------------------------------------- +bool PlotReader::FetchProof( const uint64 t6LPIndex, uint64 fullProofXs[BB_PLOT_PROOF_X_COUNT] ) +{ + uint64 lpIndices[2][BB_PLOT_PROOF_X_COUNT]; + + uint64* lpIdxSrc = lpIndices[0]; + uint64* lpIdxDst = lpIndices[1]; + + *lpIdxSrc = t6LPIndex; + + // Fetch line points to back pointers going through all our tables + // from 6 to 1, grabbing all of the x's that make up a proof. + uint32 lookupCount = 1; + + for( TableId table = TableId::Table6; table >= TableId::Table1; table-- ) + { + ASSERT( lookupCount <= 32 ); + + for( uint32 i = 0, dst = 0; i < lookupCount; i++, dst += 2 ) + { + const uint64 idx = lpIdxSrc[i]; + + uint128 lp = 0; + if( !ReadLP( table, idx, lp ) ) + return false; + + BackPtr ptr; + if( table < TableId::Table6 && _plot.K() <= 32 ) + ptr = LinePointToSquare64( (uint64)lp ); + else + ptr = LinePointToSquare( lp ); + + lpIdxDst[dst+0] = ptr.y; + lpIdxDst[dst+1] = ptr.x; + } + + lookupCount <<= 1; + + std::swap( lpIdxSrc, lpIdxDst ); + // memset( lpIdxDst, 0, sizeof( uint64 ) * PROOF_X_COUNT ); + } + + // Full proof x's will be at the src ptr + memcpy( fullProofXs, lpIdxSrc, sizeof( uint64 ) * BB_PLOT_PROOF_X_COUNT ); + return true; +} + +//----------------------------------------------------------- +bool PlotReader::LoadC2Entries() +{ + if( _c2Entries.Ptr() ) + return true; + + const size_t c2Size = _plot.TableSize( PlotTable::C2 ); + if( c2Size == 0 ) + return false; + + const size_t f7ByteSize = CDiv( _plot.K(), 8 ); + + const uint64 c2MaxEntries = c2Size / f7ByteSize; + if( c2MaxEntries < 1 ) + return false; + + if( !_plot.Seek( SeekOrigin::Begin, (int64)_plot.TableAddress( PlotTable::C2 ) ) ) + return false; + + + byte* buffer = bbvirtallocbounded( c2Size ); + + if( _plot.Read( c2Size, buffer ) != (ssize_t)c2Size ) + { + bbvirtfreebounded( buffer ); + return false; + } + + _c2Entries = bbcalloc_span( c2MaxEntries ); + + const size_t f7BitCount = f7ByteSize * 8; + CPBitReader reader( buffer, c2Size * 8 ); + + uint64 prevF7 = 0; + uint64 i; + for( i = 0; i < c2MaxEntries; i++ ) + { + const uint64 f7 = reader.Read64( (uint32)f7BitCount ); + + // Short circuit if we encounter an unsorted/out-of-order c2 entry + if( f7 < prevF7 ) + break; + + _c2Entries[i] = f7; + prevF7 = f7; + } + + _c2Entries.length = i; + + bbvirtfreebounded( buffer ); + return true; +} + /// /// Plot Files /// diff --git a/src/tools/PlotReader.h b/src/tools/PlotReader.h index 196e3bf5..9d051be8 100644 --- a/src/tools/PlotReader.h +++ b/src/tools/PlotReader.h @@ -1,25 +1,12 @@ #pragma once #include "plotting/PlotTools.h" +#include "plotting/PlotTypes.h" #include "io/FileStream.h" #include "util/Util.h" #include class CPBitReader; -enum class PlotTable -{ - Table1 = 0, - Table2, - Table3, - Table4, - Table5, - Table6, - Table7, - C1, - C2, - C3, -}; ImplementArithmeticOps( PlotTable ); - struct PlotHeader { byte id [BB_PLOT_ID_LEN] = { 0 }; @@ -175,6 +162,15 @@ class PlotReader size_t GetTableParkCount( const PlotTable table ) const; + uint64 GetMaximumC1Entries() const; + + // Returns the number of apparent C1 entries (same as C3 park count), + // excluding any empty space appearing after the table for alignment, + // This may not be accurate if the C1 entries are malformed and + // not sorted in ascending order. + // This method performs various reads until it find a seemingly valid C1 entries + bool GetActualC1EntryCount( uint64& outC1Count ); + // Read a whole C3 park into f7Buffer. // f7Buffer must hold at least as many as the amount of entries // required per C3Park. (kCheckpoint1Interval). @@ -187,6 +183,8 @@ class PlotReader uint64 GetFullProofForF7Index( uint64 f7Index, byte* fullProof ); + bool FetchProof( uint64 t6LPIndex, uint64 fullProofXs[BB_PLOT_PROOF_X_COUNT] ); + // void FindF7ParkIndices( uintt64 f7, std::vector indices ); bool ReadLPPark( TableId table, uint64 parkIndex, uint128 linePoints[kEntriesPerPark], uint64& outEntryCount ); @@ -196,17 +194,25 @@ class PlotReader inline IPlotFile& PlotFile() const { return _plot; } + Span GetP7IndicesForF7( const uint64 f7, Span indices ); + private: bool ReadLPParkComponents( TableId table, uint64 parkIndex, CPBitReader& outStubs, byte*& outDeltas, uint128& outBaseLinePoint, uint64& outDeltaCounts ); + bool LoadC2Entries(); private: IPlotFile& _plot; + uint32 _version; // size_t _parkBufferSize; - uint64* _parkBuffer ; // Buffer for loading compressed park data. - byte* _deltasBuffer ; // Buffer for decompressing deltas in parks that have delta. + uint64* _parkBuffer ; // Buffer for loading compressed park data. + byte* _deltasBuffer ; // Buffer for decompressing deltas in parks that have delta. + + Span _c2Entries; + byte* _c1Buffer = nullptr; + Span _c3Buffer; }; diff --git a/src/tools/PlotValidator.cpp b/src/tools/PlotValidator.cpp index c6c65806..fdbd5bbe 100644 --- a/src/tools/PlotValidator.cpp +++ b/src/tools/PlotValidator.cpp @@ -58,6 +58,8 @@ You can specify the thread count in the bladebit global option '-t'. it requires around 128GiB of RAM for k=32. This is only supported for plots with k=32 and below. + --f7 : Specify an f7 to find and validate in the plot. + -h, --help : Print this help message and exit. )"; @@ -98,6 +100,7 @@ static void GetProofF1( uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 full template static bool FetchProof( PlotReader& plot, uint64 t6LPIndex, uint64 fullProofXs[PROOF_X_COUNT] ); +static void GetProofForChallenge( const char* plotPath, const char* challengeHex ); static bool ValidateFullProof( const uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 fullProofXs[PROOF_X_COUNT], uint64& outF7 ); static void ReorderProof( PlotReader& plot, uint64 fullProofXs[PROOF_X_COUNT] ); static void GetProofF1( uint32 k, const byte plotId[BB_PLOT_ID_LEN], uint64 fullProofXs[PROOF_X_COUNT], uint64 fx[PROOF_X_COUNT] ); @@ -137,6 +140,9 @@ void PlotValidatorMain( GlobalPlotConfig& gCfg, CliParser& cli ) { ValidatePlotOptions opts; + const char* challenge = nullptr; + int64 f7 = -1; + while( cli.HasArgs() ) { if( cli.ReadSwitch( opts.inRAM, "-m", "--in-ram" ) ) @@ -145,6 +151,10 @@ void PlotValidatorMain( GlobalPlotConfig& gCfg, CliParser& cli ) continue; else if( cli.ReadF32( opts.startOffset, "-o", "--offset" ) ) continue; + else if( cli.ReadStr( challenge, "--prove" ) ) + continue; + else if( cli.ReadI64( f7, "--f7" ) ) // Same as proof, but the challenge is made from an f7 + continue; else if( cli.ArgConsume( "-h", "--help" ) ) { PlotValidatorPrintUsage(); @@ -160,6 +170,22 @@ void PlotValidatorMain( GlobalPlotConfig& gCfg, CliParser& cli ) } } + // Check for f7 + if( f7 >= 0 ) + { + challenge = new char[65]; + sprintf( (char*)challenge, "%08llx", f7 ); + memset( (void*)(challenge+8), '0', 64-8 ); + ((char*)challenge)[64] = 0; + } + + // Check for challenge + if( challenge != nullptr ) + { + GetProofForChallenge( opts.plotPath.c_str(), challenge ); + Exit( 0 ); + } + const uint32 maxThreads = SysHost::GetLogicalCPUCount(); opts.threadCount = gCfg.threadCount == 0 ? maxThreads : std::min( maxThreads, gCfg.threadCount ); @@ -208,11 +234,11 @@ bool ValidatePlot( const ValidatePlotOptions& options ) FatalIf( options.unpacked && plotFile->K() != 32, "Unpacked plots are only supported for k=32 plots." ); Log::Line( "Validating plot %s", options.plotPath.c_str() ); - Log::Line( "K : %u", plotFile->K() ); - Log::Line( "Unpacked: %s", options.unpacked? "true" : "false" );; + Log::Line( "K : %u", plotFile->K() ); + Log::Line( "Unpacked : %s", options.unpacked? "true" : "false" );; const uint64 plotC3ParkCount = plotFile->TableSize( PlotTable::C1 ) / sizeof( uint32 ) - 1; - Log::Line( "C3 Parks: %llu", plotC3ParkCount ); + Log::Line( "Maximum C3 Parks: %llu", plotC3ParkCount ); Log::Line( "" ); @@ -309,13 +335,31 @@ uint64 ValidateInMemory( UnpackedK32Plot& plot, ThreadPool& pool ) const uint32 expectedF7 = plot.f7[i]; if( expectedF7 != outF7 ) - failedCount++; + { + if( failedCount++ == 0 ) + { + Log( "Proof failed: Expected %llu but got %llu @ %llu (park %llu).", + (uint64)expectedF7, outF7, i, i / kCheckpoint1Interval ); + } + } } else - failedCount++; + { + if( failedCount++ == 0 ) + { + Log( "Proof failed: Validation error for f7 %llu @ %llu (park %llu).", + (uint64)plot.f7[i], i, i / kCheckpoint1Interval ); + } + } } else - failedCount++; + { + if( failedCount++ == 0 ) + { + Log( "Proof failed: Fetch failure for f7 %llu @ %llu (park %llu).", + (uint64)plot.f7[i], i, i / kCheckpoint1Interval ); + } + } const uint64 proofsChecked = i - offset; if( ( proofsChecked > 0 && proofsChecked % reportInterval == 0 ) || i + 1 == end ) @@ -476,6 +520,80 @@ void ValidateJob::Run() this->failCount = proofFailCount; } +// #TODO: Support K>32 +//----------------------------------------------------------- +void GetProofForChallenge( const char* plotPath, const char* challengeHex ) +{ + FatalIf( !plotPath || !*plotPath, "Invalid plot path." ); + FatalIf( !challengeHex || !*challengeHex, "Invalid challenge." ); + + const size_t lenChallenge = strlen( challengeHex ); + FatalIf( lenChallenge != 64, "Invalid challenge, should be 32 bytes." ); + + uint64 challenge[4] = {}; + HexStrToBytes( challengeHex, lenChallenge, (byte*)challenge, 32 ); + + FilePlot plot; + FatalIf( !plot.Open( plotPath ), "Failed to open plot at %s.", plotPath ); + FatalIf( plot.K() != 32, "Only k32 plots are supported." ); + + // Read F7 value + CPBitReader f7Reader( (byte*)challenge, sizeof( challenge ) * 8 ); + const uint32 f7 = (uint32)f7Reader.Read64( 32 ); + + // Find this f7 in the plot file + PlotReader reader( plot ); + + uint64 _indices[64] = {}; + Span indices( _indices, sizeof( _indices ) / sizeof( uint64 ) ); // #TODO: Should simply return the start index and count + + auto matches = reader.GetP7IndicesForF7( f7, indices ); + FatalIf( matches.Length() == 0, "Could not find f7 %llu in plot", f7 ); + + uint64 fullProofXs[PROOF_X_COUNT]; + uint64 proof [32] = {}; + char proofStr[513] = {}; + uint64 p7Entries[kEntriesPerPark] = {}; + + int64 prevP7Park = -1; + + for( uint64 i = 0; i < matches.Length(); i++ ) + { + const uint64 p7Index = matches[i]; + const uint64 p7Park = p7Index / kEntriesPerPark; + + // uint64 o = reader.GetFullProofForF7Index( matches[i], proof ); + if( (int64)p7Park != prevP7Park ) + { + FatalIf( !reader.ReadP7Entries( p7Park, p7Entries ), "Failed to read P7 %llu.", p7Park ); + } + + prevP7Park = (int64)p7Park; + + const uint64 localP7Index = p7Index - p7Park * kEntriesPerPark; + const uint64 t6Index = p7Entries[localP7Index]; + + const bool gotProof = FetchProof( reader, t6Index, fullProofXs ); + + if( gotProof ) + { + ReorderProof( reader, fullProofXs ); + + BitWriter writer( proof, sizeof( proof ) * 8 ); + + for( uint32 j = 0; j < PROOF_X_COUNT; j++ ) + writer.Write64BE( fullProofXs[j], 32 ); + + for( uint32 j = 0; j < PROOF_X_COUNT/2; j++ ) + proof[j] = Swap64( proof[j] ); + + size_t encoded; + BytesToHexStr( (byte*)proof, sizeof( proof ), proofStr, sizeof( proofStr ), encoded ); + // Log::Line( "[%llu] : %s", i, proofStr ); + Log::Line( proofStr ); + } + } +} //----------------------------------------------------------- UnpackedK32Plot UnpackedK32Plot::Load( IPlotFile** plotFile, ThreadPool& pool, uint32 threadCount ) @@ -495,6 +613,9 @@ UnpackedK32Plot UnpackedK32Plot::Load( IPlotFile** plotFile, ThreadPool& pool, u PlotReader& plotReader = readers[0]; + // uint64 c1EntryCount = 0; + // FatalIf( !plotReader.GetActualC1EntryCount( c1EntryCount ), "Failed to obtain C1 entry count." ); + uint64 f7Count = plotReader.GetMaxF7EntryCount(); FatalIf( f7Count < 1, "No F7s found." ); // Load F7s @@ -502,7 +623,7 @@ UnpackedK32Plot UnpackedK32Plot::Load( IPlotFile** plotFile, ThreadPool& pool, u Log::Line( "Unpacking f7 values..." ); uint32* f7 = bbcvirtallocboundednuma( f7Count ); - uint64 missingF7 = 0; + std::atomic sharedF7Count = 0; AnonMTJob::Run( pool, threadCount, [&]( AnonMTJob* self ) { @@ -513,8 +634,10 @@ UnpackedK32Plot UnpackedK32Plot::Load( IPlotFile** plotFile, ThreadPool& pool, u uint64 parkCount, parkOffset, parkEnd; GetThreadOffsets( self, plotParkCount, parkCount, parkOffset, parkEnd ); - uint64 f7Buffer[kCheckpoint1Interval]; - uint32* f7Writer = f7 + parkOffset * kCheckpoint1Interval; + uint64 f7Buffer[kCheckpoint1Interval]; + + uint32* f7Start = f7 + parkOffset * kCheckpoint1Interval; + uint32* f7Writer = f7Start; for( uint64 i = parkOffset; i < parkEnd; i++ ) { @@ -522,27 +645,34 @@ UnpackedK32Plot UnpackedK32Plot::Load( IPlotFile** plotFile, ThreadPool& pool, u FatalIf( entryCount == 0, "Empty C3 park @ %llu.", i ); - for( int64 e = 0; e < entryCount; e++ ) - f7Writer[e] = (uint32)f7Buffer[e]; - - f7Writer += entryCount; + if( entryCount > 0 ) + { + for( int64 e = 0; e < entryCount; e++ ) + f7Writer[e] = (uint32)f7Buffer[e]; + + f7Writer += entryCount; + } if( entryCount < kCheckpoint1Interval ) { - if( self->IsLastThread() && i + 1 == parkEnd ) + if( self->IsLastThread() ) { - missingF7 = kCheckpoint1Interval - entryCount; + // Short-circuit as soon as we find a partial park in the last thread break; } else - FatalErrorMsg( "C3 park %llu is not full and it is not the last park.", i ); + Fatal( "[%u/%u] C3 park %llu is not full and it is not the last park.", self->_jobId, self->_jobCount, i ); } } + + sharedF7Count += (uint64)(uintptr_t)(f7Writer - f7Start); }); - f7Count -= missingF7; + f7Count = sharedF7Count; plot.f7.length = f7Count; plot.f7.values = f7; + + Log::Line( "Actual C3 Parks : %llu", CDiv( f7Count, kCheckpoint1Interval ) ); } // Read Park 7 diff --git a/src/util/BitView.h b/src/util/BitView.h index 9d0ecdff..75a7ea93 100644 --- a/src/util/BitView.h +++ b/src/util/BitView.h @@ -449,6 +449,14 @@ class BitWriter _position += bitCount; } + //----------------------------------------------------------- + inline void Write64BE( const uint64 value, const uint32 bitCount ) + { + ASSERT( _capacity - _position >= bitCount ); + WriteBits64BE( _fields, _position, value, bitCount ); + _position += bitCount; + } + //----------------------------------------------------------- // dstOffset: Offset in bits as to where to start writing in fields //----------------------------------------------------------- From 57efebc32bbf13429ff0313a104d90d27302e25e Mon Sep 17 00:00:00 2001 From: Harold B Date: Mon, 31 Oct 2022 13:31:11 -0500 Subject: [PATCH 89/91] Updated readme for RC - Fixed minor help output issue - Change version to RC --- README.md | 79 ++++++++++++++++++++++++++++-------- VERSION | 2 +- src/main.cpp | 4 +- src/plotdisk/DiskPlotter.cpp | 4 +- 4 files changed, 66 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index ea17e8a3..6d9c8337 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,29 @@ [![Release Builds](https://github.com/Chia-Network/bladebit/actions/workflows/build-release.yml/badge.svg?branch=master&event=push)](https://github.com/Chia-Network/bladebit/actions/workflows/build-release.yml) -A fast **RAM-only**, **k32-only**, Chia plotter. +A high-performance **k32-only**, Chia (XCH) plotter supporting in-RAM and disk-based plotting. ## Requirements -**416 GiB of RAM are required** to run it, plus a few more megabytes for stack space and small allocations. + +### In-RAM +**416 GiB of RAM are required** to run it, and a few more megabytes for stack space and small allocations. 64-bit is supported only, for obvious reasons. + +### Disk-based +A minimum of **4 GiB of RAM** is required, with lower bucket counts requiring up to 12 GiB of RAM. + +Around **480 GiB** of total temporary space is required when plotting to disk in the default mode, or around 390 GiB with `--alternate` mode enabled. + +The exact amounts of RAM and disk space required may vary slightly depending on the system's page size and the target disk file system block size (block-alignment is required for direct I/O). + +SSDs are highly recommended for disk-based plotting. + + ## Prerequisites -Only **Linux** & **Windows** are supported. +Linux, Windows and MacOS (both intel and ARM (Apple Silicon)) are supported. + ### Linux @@ -27,6 +41,14 @@ sudo apt install -y build-essential cmake libgmp-dev libnuma-dev ### Windows Must have at least [Visual Studio 2019](https://visualstudio.microsoft.com/vs/) or its build tools installed. +### macOS +Must have Xcode or Xcode build tools installed. +`brew install cmake` + +Optionally install `gmp`: +`brew install gmp` + + ## Building ```bash @@ -49,7 +71,7 @@ On Windows it will be under `build/Release/`. Run **bladebit** with the `-h` for complete usage and command line options: ```bash -# Linux +# Linux & macOS build/bladebit -h # Windows @@ -57,29 +79,50 @@ build/Release/bladebit.exe -h ``` -## License -Licensed under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). See [LICENSE](LICENSE). +The bladebit CLI uses the format `bladebit `. + +Use the aforementioned `-h` parameter to get the full list of sub-commands and `GLOBAL_OPTIONS`. +The `sub_command`-specific `COMMAND_OPTIONS` can be obtained by using the `help` sub command with the desired command as the parameter: + +```bash +bladebit help ramplot +bladebit help diskplot +``` + +### In-RAM +Basic `ramplot` usage: +```bash +# OG plots +./bladebit -f -p ramplot +# Portable plots +./bladebit -f -c ramplot +``` -# Other Details +### Disk-Based +Basic `diskplot` usage: +```bash -## Disk I/O -Writes to disk only occur to the final plot file, and it is done sequentially, un-buffered, with direct I/O. This means that writes will be block-aligned. If you've gotten faster writes elsewhere in your drive than you will get with this, it is likely that it is using buffered writes, therefore it "finishes" before it actually finishes writing to disk. The kernel will handle the I/O in the background from cache (you can confirm this with tools such as iotop). The final writes here ought to pretty much saturate your sequential writes. Writes begin happening in the background at Phase 3 and will continue to do so, depending on the disk I/O throughput, through the next plot, if it did not finish beforehand. At some point in Phase 1 of the next plot, it might stall if it still has not finished writing to disk and a buffer it requires is still being written to disk. On the system I tested, there was no interruption when using an NVMe drive. +# OG plots +./bladebit -f -p diskplot -t1 +# Portable plots +./bladebit -f -c diskplot -t1 -## Pool Plots -Pool plots are fully supported and tested against the chia-blockchain implementation. The community has also verified that pool plots are working properly and winning proofs with them. +# Differing temp directories: +./bladebit -f ... -c ... diskplot -t1 /path/to/temp_1 -t2 /path/to/temp2 /my/output/dir -## NUMA systems -Memory is bound on interleaved mode for NUMA systems which currently gives the best performance on systems with several nodes. This is the default behavior on NUMA systems, it can be disabled with with the `-m or --no-numa` switch. +# With a 100 GiB temp2 cache and alternating mode +./bladebit -f ... -c ... diskplot -a --cache 100G -t1 /path/to/temp_1 -t2 /path/to/temp2 /my/output/dir +# With fine-grained thread control depending on the workload +./bladebit -f ... -c ... diskplot --f1-threads 12 --fp-threads 32 -t1 /path/to/temp_1 /my/output/dir +``` -## Huge TLBs -This is not supported yet. Some folks have reported some gains when using huge page sizes. Although this was something I wanted to test, I focused first instead on things that did not necessarily depended on system config. But I'd like to add support for it in the future (trivial from the development point of view, I have just not configured the test system with huge page sizes). -## Other Observations -This implementation is highly memory-bound so optimizing your system towards fast memory access is essential. CPUs with large caches will benefit as well. +## License +Licensed under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). See [LICENSE](LICENSE). -Copyright 2021 Harold Brenes, Chia Network Inc +Copyright 2022 Harold Brenes, Chia Network Inc diff --git a/VERSION b/VERSION index eab045f4..ebdd3604 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ 2.0.0 --beta1 \ No newline at end of file +-rc1 \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 7938fc3e..b1396401 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -524,10 +524,10 @@ bladebit --help bladebit help diskplot # Simple config: -bladebit -t 24 -f -c diskplot --t1 /my/temporary/plot/dir /my/output/dir +bladebit -t 24 -f -c diskplot -t1 /my/temporary/plot/dir /my/output/dir # With fine-grained control over threads per phase/section (see bladebit -h diskplot): -bladebit -t 30 -f -c diskplot --f1-threads 16 --c-threads 16 --p2-threads 8 --t1 /my/temporary/plot/dir /my/output/dir +bladebit -t 30 -f -c diskplot --f1-threads 16 --c-threads 16 --p2-threads 8 -t1 /my/temporary/plot/dir /my/output/dir )"; //----------------------------------------------------------- diff --git a/src/plotdisk/DiskPlotter.cpp b/src/plotdisk/DiskPlotter.cpp index 7679ce12..93b2db79 100644 --- a/src/plotdisk/DiskPlotter.cpp +++ b/src/plotdisk/DiskPlotter.cpp @@ -555,10 +555,10 @@ incurring high I/O waits. [EXAMPLES] # Simple config: -bladebit -t 24 -f -c diskplot --t1 /my/temporary/plot/dir /my/output/dir +bladebit -t 24 -f -c diskplot -t1 /my/temporary/plot/dir /my/output/dir # With fine-grained control over threads per phase/section (see bladebit -h diskplot): -bladebit -t 30 -f -c diskplot --f1-threads 16 --c-threads 16 --p2-threads 8 --t1 /my/temporary/plot/dir /my/output/dir +bladebit -t 30 -f -c diskplot --f1-threads 16 --c-threads 16 --p2-threads 8 -t1 /my/temporary/plot/dir /my/output/dir )"; //----------------------------------------------------------- From cdc10c34b168fd865599200d876e7e83a136f60c Mon Sep 17 00:00:00 2001 From: Harold B Date: Thu, 3 Nov 2022 12:57:53 -0500 Subject: [PATCH 90/91] Version bump to general release 2.0.0 --- VERSION | 1 - 1 file changed, 1 deletion(-) diff --git a/VERSION b/VERSION index ebdd3604..227cea21 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1 @@ 2.0.0 --rc1 \ No newline at end of file From 3196955e7ae829cf64c2f7f953ce1da450b6d994 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Thu, 3 Nov 2022 15:15:11 -0500 Subject: [PATCH 91/91] CI version fixes (#240) * [CI] Fix version string when no suffix. * [CI] Show built binaries before zipping on windows * [CI] Explicit macOS image, workaround tar issue in newer images (thanks @altendky) --- .github/actions/build-asset-unix.sh | 7 +++++ .github/actions/get-version.sh | 13 +++++--- .github/workflows/build-release.yml | 3 +- embed-version.sh | 13 ++++---- extract-version.sh | 47 +++++++++++++++-------------- 5 files changed, 49 insertions(+), 34 deletions(-) diff --git a/.github/actions/build-asset-unix.sh b/.github/actions/build-asset-unix.sh index 2ff28d7c..b7fc8920 100755 --- a/.github/actions/build-asset-unix.sh +++ b/.github/actions/build-asset-unix.sh @@ -25,6 +25,12 @@ bash -eo pipefail ../embed-version.sh cmake --build . --target bladebit --config Release -j $thread_count chmod +x ./bladebit +if [[ $OSTYPE == 'msys'* ]] || [[ $OSTYPE == 'cygwin'* ]]; then + ls -la Release +else + ls -la +fi + # Ensure bladebit version matches expected version bb_version="$(./bladebit --version | xargs)" @@ -33,6 +39,7 @@ if [[ "$bb_version" != "$BB_VERSION" ]]; then exit 1 fi +tar --version tar -czvf $BB_ARTIFACT_NAME bladebit mkdir ../bin mv $BB_ARTIFACT_NAME ../bin/ diff --git a/.github/actions/get-version.sh b/.github/actions/get-version.sh index 4c7ed90b..81dea115 100755 --- a/.github/actions/get-version.sh +++ b/.github/actions/get-version.sh @@ -6,12 +6,15 @@ set -eo pipefail os=$1 arch=$2 -version_cmp=($(./extract-version.sh)) +shift $# -ver_maj=${version_cmp[0]} -ver_min=${version_cmp[1]} -ver_rev=${version_cmp[2]} -ver_suffix=${version_cmp[3]} +# version_cmp=($(./extract-version.sh)) +. ./extract-version.sh + +ver_maj=$bb_ver_maj +ver_min=$bb_ver_min +ver_rev=$bb_ver_rev +ver_suffix=$bb_version_suffix version="${ver_maj}.${ver_min}.${ver_rev}${ver_suffix}" diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index db4d6908..bef7e232 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -163,6 +163,7 @@ jobs: mkdir ../bin cd Release + ls -la 7z.exe a -tzip ../../bin/${BB_ARTIFACT_NAME} bladebit.exe ls -la ../../bin @@ -203,7 +204,7 @@ jobs: if-no-files-found: error build-macos-x86-64: - runs-on: macOS-latest + runs-on: macOS-11 steps: - name: Cleanup Environment uses: Chia-Network/actions/clean-workspace@main diff --git a/embed-version.sh b/embed-version.sh index c2e1dd7b..f9c8d834 100755 --- a/embed-version.sh +++ b/embed-version.sh @@ -2,13 +2,14 @@ set -eo pipefail cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" -version=($(./extract-version.sh)) +# version=($(./extract-version.sh)) +. ./extract-version.sh -ver_maj=${version[0]} -ver_min=${version[1]} -ver_rev=${version[2]} -ver_suffix=${version[3]} -git_commit=${version[4]} +ver_maj=$bb_ver_maj +ver_min=$bb_ver_min +ver_rev=$bb_ver_rev +ver_suffix=$bb_version_suffix +git_commit=$bb_git_commit echo "Version: $ver_maj.$ver_min.$ver_rev$ver_suffix" echo "Commit : $git_commit" diff --git a/extract-version.sh b/extract-version.sh index c15e8107..5797c556 100755 --- a/extract-version.sh +++ b/extract-version.sh @@ -8,28 +8,30 @@ ver_component=$1 # The user specified a specified component from the full veris # See the case switch below. # Grab version specified in the file -set IFS= +_IFS=IFS +IFS= version_str=$(cat VERSION | head -n 1 | xargs) -version_suffix=$(cat VERSION | tail -n 1 | xargs) +bb_version_suffix=$(cat VERSION | tail -n 1 | xargs) version_header='src/Version.h' +IFS=$_IFS -if [[ "$version_str" == "$version_suffix" ]]; then - version_suffix= +if [[ "$version_str" == "$bb_version_suffix" ]]; then + bb_version_suffix= fi -ver_maj=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1/' | xargs) -ver_min=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\2/' | xargs) -ver_rev=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\3/' | xargs) +bb_ver_maj=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1/' | xargs) +bb_ver_min=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\2/' | xargs) +bb_ver_rev=$(printf $version_str | sed -E -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\3/' | xargs) -git_commit=$GITHUB_SHA -if [[ -z $git_commit ]]; then +bb_git_commit=$GITHUB_SHA +if [[ -z $bb_git_commit ]]; then set +e - git_commit=$(git rev-parse HEAD) + bb_git_commit=$(git rev-parse HEAD) set -e fi -if [[ -z $git_commit ]]; then - git_commit="unknown" +if [[ -z $bb_git_commit ]]; then + bb_git_commit="unknown" fi # Check if the user wants a specific component @@ -38,23 +40,23 @@ if [[ -n $ver_component ]]; then case "$ver_component" in "major") - echo -n $ver_maj + echo -n $bb_ver_maj ;; "minor") - echo -n $ver_min + echo -n $bb_ver_min ;; "revision") - echo -n $ver_rev + echo -n $bb_ver_rev ;; "suffix") - echo -n $version_suffix + echo -n $bb_version_suffix ;; "commit") - echo -n $git_commit + echo -n $bb_git_commit ;; *) @@ -66,8 +68,9 @@ if [[ -n $ver_component ]]; then fi # Emit all version components -echo "$ver_maj" -echo "$ver_min" -echo "$ver_rev" -echo "$version_suffix" -echo "$git_commit" +# echo "$bb_ver_maj" +# echo "$bb_ver_min" +# echo "$bb_ver_rev" +# echo "$bb_version_suffix" +# echo "$bb_git_commit" +