diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bc4fe2febde..24620f8d7ca 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,8 +1,2 @@ # Allow anyone to review any change by default. * - -# Require the rpc-reviewers team to review changes to the rpc code. -include/xrpl/protocol/ @xrplf/rpc-reviewers -src/libxrpl/protocol/ @xrplf/rpc-reviewers -src/xrpld/rpc/ @xrplf/rpc-reviewers -src/xrpld/app/misc/ @xrplf/rpc-reviewers diff --git a/include/xrpl/basics/Number.h b/include/xrpl/basics/Number.h index 41c60d30a13..71deda889dc 100644 --- a/include/xrpl/basics/Number.h +++ b/include/xrpl/basics/Number.h @@ -360,6 +360,10 @@ abs(Number x) noexcept Number power(Number const& f, unsigned n); +// logarithm with base 10 +Number +lg(Number const& value); + // Returns f^(1/d) // Uses Newton–Raphson iterations until the result stops changing // to find the root of the polynomial g(x) = x^d - f diff --git a/include/xrpl/protocol/IOUAmount.h b/include/xrpl/protocol/IOUAmount.h index 93fba4150d7..c9838a6a804 100644 --- a/include/xrpl/protocol/IOUAmount.h +++ b/include/xrpl/protocol/IOUAmount.h @@ -58,6 +58,13 @@ class IOUAmount : private boost::totally_ordered, normalize(); public: + /* The range for the mantissa when normalized */ + static std::int64_t constexpr minMantissa = 1000000000000000ull; + static std::int64_t constexpr maxMantissa = 9999999999999999ull; + /* The range for the exponent when normalized */ + static int constexpr minExponent = -96; + static int constexpr maxExponent = 80; + IOUAmount() = default; explicit IOUAmount(Number const& other); IOUAmount(beast::Zero); diff --git a/include/xrpl/protocol/Protocol.h b/include/xrpl/protocol/Protocol.h index 84b8c3889b2..535fd615c1c 100644 --- a/include/xrpl/protocol/Protocol.h +++ b/include/xrpl/protocol/Protocol.h @@ -132,6 +132,13 @@ std::uint8_t constexpr vaultMaximumIOUScale = 18; * another vault; counted from 0 */ std::uint8_t constexpr maxAssetCheckDepth = 5; +/** The maximum length of a Data field in Escrow object that can be updated by + * Wasm code */ +std::size_t constexpr maxWasmDataLength = 4 * 1024; + +/** The maximum length of a parameters passed from Wasm code*/ +std::size_t constexpr maxWasmParamLength = 1024; + /** A ledger index. */ using LedgerIndex = std::uint32_t; diff --git a/include/xrpl/protocol/TER.h b/include/xrpl/protocol/TER.h index 0a3a3b999ee..73b4fa2f8ad 100644 --- a/include/xrpl/protocol/TER.h +++ b/include/xrpl/protocol/TER.h @@ -141,6 +141,8 @@ enum TEMcodes : TERUnderlyingType { temARRAY_TOO_LARGE, temBAD_TRANSFER_FEE, temINVALID_INNER_BATCH, + + temBAD_WASM, }; //------------------------------------------------------------------------------ diff --git a/src/libxrpl/basics/Number.cpp b/src/libxrpl/basics/Number.cpp index f43288b57b1..50583cc2909 100644 --- a/src/libxrpl/basics/Number.cpp +++ b/src/libxrpl/basics/Number.cpp @@ -623,6 +623,48 @@ power(Number const& f, unsigned n) return r; } +// Continued fraction approximation of ln(x) +static Number +ln(Number const& x, unsigned iterations = 50) +{ + if (x <= 0) + throw std::runtime_error("Not positive value"); + + Number const z = (x - 1) / (x + 1); + Number const zz = z * z; + Number denom = Number(1, -10); + + // Construct the fraction from the bottom up + for (int i = iterations; i > 0; --i) + { + Number k(2 * i - 1); + denom = k - (i * i * zz / denom); + } + + auto const r = 2 * z / denom; + return r; +} + +Number +lg(Number const& x) +{ + static Number const ln10 = ln(Number(10)); + + if (x <= Number(10)) + { + auto const r = ln(x) / ln10; + return r; + } + + // ln(x) = ln(normX * 10^norm) = ln(normX) + norm * ln(10) + int diffExp = 15 + x.exponent(); + Number const normalX = x / Number(1, diffExp); // (1 <= normalX < 10) + auto const lnX = ln(normalX) + diffExp * ln10; + + auto const r = lnX / ln10; + return r; +} + // Returns f^(1/d) // Uses Newton–Raphson iterations until the result stops changing // to find the non-negative root of the polynomial g(x) = x^d - f diff --git a/src/libxrpl/protocol/IOUAmount.cpp b/src/libxrpl/protocol/IOUAmount.cpp index 9bd1ceb5eb3..b4f3f18e2e1 100644 --- a/src/libxrpl/protocol/IOUAmount.cpp +++ b/src/libxrpl/protocol/IOUAmount.cpp @@ -58,13 +58,6 @@ setSTNumberSwitchover(bool v) *getStaticSTNumberSwitchover() = v; } -/* The range for the mantissa when normalized */ -static std::int64_t constexpr minMantissa = 1000000000000000ull; -static std::int64_t constexpr maxMantissa = 9999999999999999ull; -/* The range for the exponent when normalized */ -static int constexpr minExponent = -96; -static int constexpr maxExponent = 80; - IOUAmount IOUAmount::minPositiveAmount() { @@ -312,7 +305,8 @@ mulRatio( { if (!result) { - return IOUAmount(-minMantissa, minExponent); + return IOUAmount( + -IOUAmount::minMantissa, IOUAmount::minExponent); } // This subtraction cannot underflow because `result` is not zero return IOUAmount(result.mantissa() - 1, result.exponent()); diff --git a/src/libxrpl/protocol/TER.cpp b/src/libxrpl/protocol/TER.cpp index a396949afe2..5d62643a13d 100644 --- a/src/libxrpl/protocol/TER.cpp +++ b/src/libxrpl/protocol/TER.cpp @@ -220,6 +220,7 @@ transResults() MAKE_ERROR(temARRAY_TOO_LARGE, "Malformed: Array is too large."), MAKE_ERROR(temBAD_TRANSFER_FEE, "Malformed: Transfer fee is outside valid range."), MAKE_ERROR(temINVALID_INNER_BATCH, "Malformed: Invalid inner batch transaction."), + MAKE_ERROR(temBAD_WASM, "Malformed: Provided WASM code is invalid."), MAKE_ERROR(terRETRY, "Retry transaction."), MAKE_ERROR(terFUNDS_SPENT, "DEPRECATED."), diff --git a/src/test/app/HostFuncImpl_test.cpp b/src/test/app/HostFuncImpl_test.cpp new file mode 100644 index 00000000000..8dd83fc74ae --- /dev/null +++ b/src/test/app/HostFuncImpl_test.cpp @@ -0,0 +1,2983 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#include + +#include + +namespace ripple { +namespace test { + +static Bytes +toBytes(std::uint8_t value) +{ + return {value}; +} + +static Bytes +toBytes(std::uint16_t value) +{ + auto const* b = reinterpret_cast(&value); + auto const* e = reinterpret_cast(&value + 1); + return Bytes{b, e}; +} + +static Bytes +toBytes(std::uint32_t value) +{ + auto const* b = reinterpret_cast(&value); + auto const* e = reinterpret_cast(&value + 1); + return Bytes{b, e}; +} + +static Bytes +toBytes(Asset const& asset) +{ + if (asset.holds()) + { + Serializer s; + auto const& issue = asset.get(); + s.addBitString(issue.currency); + if (!isXRP(issue.currency)) + s.addBitString(issue.account); + auto const data = s.getData(); + return data; + } + + auto const& mptIssue = asset.get(); + auto const& mptID = mptIssue.getMptID(); + return Bytes{mptID.cbegin(), mptID.cend()}; +} + +static Bytes +toBytes(STAmount const& amount) +{ + Serializer msg; + amount.add(msg); + auto const data = msg.getData(); + + return data; +} + +static ApplyContext +createApplyContext( + test::jtx::Env& env, + OpenView& ov, + STTx const& tx = STTx(ttESCROW_FINISH, [](STObject&) {})) +{ + ApplyContext ac{ + env.app(), + ov, + tx, + tesSUCCESS, + env.current()->fees().base, + tapNONE, + env.journal}; + return ac; +} + +struct HostFuncImpl_test : public beast::unit_test::suite +{ + void + testGetLedgerSqn() + { + testcase("getLedgerSqn"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + auto const result = hfs.getLedgerSqn(); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == env.current()->info().seq); + } + + void + testGetParentLedgerTime() + { + testcase("getParentLedgerTime"); + using namespace test::jtx; + + Env env{*this}; + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + + { + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + auto const result = hfs.getParentLedgerTime(); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT( + result.value() == + env.current() + ->parentCloseTime() + .time_since_epoch() + .count()); + } + + env.close( + env.now() + + std::chrono::seconds(std::numeric_limits::max() - 1)); + { + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + auto const result = hfs.getParentLedgerTime(); + if (BEAST_EXPECTS( + !result.has_value(), std::to_string(result.value()))) + BEAST_EXPECT(result.error() == HostFunctionError::INTERNAL); + } + } + + void + testGetParentLedgerHash() + { + testcase("getParentLedgerHash"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + auto const result = hfs.getParentLedgerHash(); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == env.current()->info().parentHash); + } + + void + testGetBaseFee() + { + testcase("getBaseFee"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + auto const result = hfs.getBaseFee(); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == env.current()->fees().base.drops()); + + { + Env env2( + *this, + envconfig([](std::unique_ptr cfg) { + cfg->FEES.reference_fee = + static_cast( + std::numeric_limits::max()) + + 1; + return cfg; + }), + testable_amendments()); + // Run past the flag ledger so that a Fee change vote occurs and + // updates FeeSettings. (It also activates all supported + // amendments.) + for (auto i = env.current()->seq(); i <= 257; ++i) + env.close(); + + OpenView ov2{*env2.current()}; + ApplyContext ac2 = createApplyContext(env2, ov2); + WasmHostFunctionsImpl hfs2(ac2, dummyEscrow); + auto const result2 = hfs2.getBaseFee(); + if (BEAST_EXPECT(!result2.has_value())) + BEAST_EXPECT(result2.error() == HostFunctionError::INTERNAL); + } + } + + void + testIsAmendmentEnabled() + { + testcase("isAmendmentEnabled"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + // Use featureTokenEscrow for testing + auto const amendmentId = featureTokenEscrow; + + // Test by id + { + auto const result = hfs.isAmendmentEnabled(amendmentId); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == 1); + } + + // Test by name + std::string const amendmentName = "TokenEscrow"; + { + auto const result = hfs.isAmendmentEnabled(amendmentName); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == 1); + } + + // Test with a fake amendment id (all zeros) + uint256 fakeId; + { + auto const result = hfs.isAmendmentEnabled(fakeId); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == 0); + } + + // Test with a fake amendment name + std::string fakeName = "FakeAmendment"; + { + auto const result = hfs.isAmendmentEnabled(fakeName); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == 0); + } + } + + void + testCacheLedgerObj() + { + testcase("cacheLedgerObj"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = keylet::escrow(env.master, 2); + auto const accountKeylet = keylet::account(env.master); + { + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + BEAST_EXPECT( + hfs.cacheLedgerObj(accountKeylet.key, -1).error() == + HostFunctionError::SLOT_OUT_RANGE); + BEAST_EXPECT( + hfs.cacheLedgerObj(accountKeylet.key, 257).error() == + HostFunctionError::SLOT_OUT_RANGE); + BEAST_EXPECT( + hfs.cacheLedgerObj(dummyEscrow.key, 0).error() == + HostFunctionError::LEDGER_OBJ_NOT_FOUND); + BEAST_EXPECT(hfs.cacheLedgerObj(accountKeylet.key, 0).value() == 1); + + for (int i = 1; i <= 256; ++i) + { + auto const result = hfs.cacheLedgerObj(accountKeylet.key, i); + BEAST_EXPECT(result.has_value() && result.value() == i); + } + BEAST_EXPECT( + hfs.cacheLedgerObj(accountKeylet.key, 0).error() == + HostFunctionError::SLOTS_FULL); + } + + { + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + for (int i = 1; i <= 256; ++i) + { + auto const result = hfs.cacheLedgerObj(accountKeylet.key, 0); + BEAST_EXPECT(result.has_value() && result.value() == i); + } + BEAST_EXPECT( + hfs.cacheLedgerObj(accountKeylet.key, 0).error() == + HostFunctionError::SLOTS_FULL); + } + } + + void + testGetTxField() + { + testcase("getTxField"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + STTx const stx = STTx(ttESCROW_FINISH, [&](auto& obj) { + obj.setAccountID(sfAccount, env.master.id()); + obj.setAccountID(sfOwner, env.master.id()); + obj.setFieldU32(sfOfferSequence, env.seq(env.master)); + obj.setFieldArray(sfMemos, STArray{}); + }); + ApplyContext ac = createApplyContext(env, ov, stx); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + + { + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + auto const account = hfs.getTxField(sfAccount); + BEAST_EXPECT( + account && std::ranges::equal(*account, env.master.id())); + + auto const owner = hfs.getTxField(sfOwner); + BEAST_EXPECT(owner && std::ranges::equal(*owner, env.master.id())); + + auto const txType = hfs.getTxField(sfTransactionType); + BEAST_EXPECT(txType && *txType == toBytes(ttESCROW_FINISH)); + + auto const offerSeq = hfs.getTxField(sfOfferSequence); + BEAST_EXPECT(offerSeq && *offerSeq == toBytes(env.seq(env.master))); + + auto const notPresent = hfs.getTxField(sfDestination); + if (BEAST_EXPECT(!notPresent.has_value())) + BEAST_EXPECT( + notPresent.error() == HostFunctionError::FIELD_NOT_FOUND); + + auto const memos = hfs.getTxField(sfMemos); + if (BEAST_EXPECT(!memos.has_value())) + BEAST_EXPECT( + memos.error() == HostFunctionError::NOT_LEAF_FIELD); + + auto const nonField = hfs.getTxField(sfInvalid); + if (BEAST_EXPECT(!nonField.has_value())) + BEAST_EXPECT( + nonField.error() == HostFunctionError::FIELD_NOT_FOUND); + + auto const nonField2 = hfs.getTxField(sfGeneric); + if (BEAST_EXPECT(!nonField2.has_value())) + BEAST_EXPECT( + nonField2.error() == HostFunctionError::FIELD_NOT_FOUND); + } + + { + auto const iouAsset = env.master["USD"]; + STTx const stx2 = STTx(ttAMM_DEPOSIT, [&](auto& obj) { + obj.setAccountID(sfAccount, env.master.id()); + obj.setFieldIssue(sfAsset, STIssue{sfAsset, xrpIssue()}); + obj.setFieldIssue( + sfAsset2, STIssue{sfAsset2, iouAsset.issue()}); + }); + ApplyContext ac2 = createApplyContext(env, ov, stx2); + WasmHostFunctionsImpl hfs(ac2, dummyEscrow); + + auto const asset = hfs.getTxField(sfAsset); + std::vector expectedAsset(20, 0); + BEAST_EXPECT(asset && *asset == expectedAsset); + + auto const asset2 = hfs.getTxField(sfAsset2); + BEAST_EXPECT(asset2 && *asset2 == toBytes(Asset(iouAsset))); + } + + { + auto const iouAsset = env.master["GBP"]; + auto const mptId = makeMptID(1, env.master); + STTx const stx2 = STTx(ttAMM_DEPOSIT, [&](auto& obj) { + obj.setAccountID(sfAccount, env.master.id()); + obj.setFieldIssue(sfAsset, STIssue{sfAsset, iouAsset.issue()}); + obj.setFieldIssue(sfAsset2, STIssue{sfAsset2, MPTIssue{mptId}}); + }); + ApplyContext ac2 = createApplyContext(env, ov, stx2); + WasmHostFunctionsImpl hfs(ac2, dummyEscrow); + + auto const asset = hfs.getTxField(sfAsset); + if (BEAST_EXPECT(asset.has_value())) + { + BEAST_EXPECT(*asset == toBytes(Asset(iouAsset))); + } + + auto const asset2 = hfs.getTxField(sfAsset2); + if (BEAST_EXPECT(asset2.has_value())) + { + BEAST_EXPECT(*asset2 == toBytes(Asset(mptId))); + } + } + + { + std::uint8_t const expectedScale = 8; + STTx const stx2 = STTx(ttMPTOKEN_ISSUANCE_CREATE, [&](auto& obj) { + obj.setAccountID(sfAccount, env.master.id()); + obj.setFieldU8(sfAssetScale, expectedScale); + }); + ApplyContext ac2 = createApplyContext(env, ov, stx2); + WasmHostFunctionsImpl hfs(ac2, dummyEscrow); + + auto const actualScale = hfs.getTxField(sfAssetScale); + if (BEAST_EXPECT(actualScale.has_value())) + { + BEAST_EXPECT( + std::ranges::equal(*actualScale, toBytes(expectedScale))); + } + } + } + + void + testGetCurrentLedgerObjField() + { + testcase("getCurrentLedgerObjField"); + using namespace test::jtx; + using namespace std::chrono; + + Env env{*this}; + + // Fund the account and create an escrow so the ledger object exists + env(escrow::create(env.master, env.master, XRP(100)), + escrow::finish_time(env.now() + 1s)); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + // Find the escrow ledger object + auto const escrowKeylet = + keylet::escrow(env.master, env.seq(env.master) - 1); + BEAST_EXPECT(env.le(escrowKeylet)); + + WasmHostFunctionsImpl hfs(ac, escrowKeylet); + + // Should return the Account field from the escrow ledger object + auto const account = hfs.getCurrentLedgerObjField(sfAccount); + if (BEAST_EXPECTS( + account.has_value(), + std::to_string(static_cast(account.error())))) + BEAST_EXPECT(std::ranges::equal(*account, env.master.id())); + + // Should return the Amount field from the escrow ledger object + auto const amountField = hfs.getCurrentLedgerObjField(sfAmount); + if (BEAST_EXPECT(amountField.has_value())) + { + BEAST_EXPECT(*amountField == toBytes(XRP(100))); + } + + // Should return nullopt for a field not present + auto const notPresent = hfs.getCurrentLedgerObjField(sfOwner); + BEAST_EXPECT( + !notPresent.has_value() && + notPresent.error() == HostFunctionError::FIELD_NOT_FOUND); + + { + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master) + 5); + WasmHostFunctionsImpl hfs2(ac, dummyEscrow); + auto const account = hfs2.getCurrentLedgerObjField(sfAccount); + if (BEAST_EXPECT(!account.has_value())) + { + BEAST_EXPECT( + account.error() == HostFunctionError::LEDGER_OBJ_NOT_FOUND); + } + } + } + + void + testGetLedgerObjField() + { + testcase("getLedgerObjField"); + using namespace test::jtx; + using namespace std::chrono; + + Env env{*this}; + // Fund the account and create an escrow so the ledger object exists + env(escrow::create(env.master, env.master, XRP(100)), + escrow::finish_time(env.now() + 1s)); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const accountKeylet = keylet::account(env.master.id()); + auto const escrowKeylet = + keylet::escrow(env.master.id(), env.seq(env.master) - 1); + WasmHostFunctionsImpl hfs(ac, escrowKeylet); + + // Cache the escrow ledger object in slot 1 + auto cacheResult = hfs.cacheLedgerObj(accountKeylet.key, 1); + BEAST_EXPECT(cacheResult.has_value() && cacheResult.value() == 1); + + // Should return the Account field from the cached ledger object + auto const account = hfs.getLedgerObjField(1, sfAccount); + if (BEAST_EXPECTS( + account.has_value(), + std::to_string(static_cast(account.error())))) + BEAST_EXPECT(std::ranges::equal(*account, env.master.id())); + + // Should return the Balance field from the cached ledger object + auto const balanceField = hfs.getLedgerObjField(1, sfBalance); + if (BEAST_EXPECT(balanceField.has_value())) + { + BEAST_EXPECT(*balanceField == toBytes(env.balance(env.master))); + } + + // Should return error for slot out of range + auto const outOfRange = hfs.getLedgerObjField(0, sfAccount); + BEAST_EXPECT( + !outOfRange.has_value() && + outOfRange.error() == HostFunctionError::SLOT_OUT_RANGE); + + auto const tooHigh = hfs.getLedgerObjField(257, sfAccount); + BEAST_EXPECT( + !tooHigh.has_value() && + tooHigh.error() == HostFunctionError::SLOT_OUT_RANGE); + + // Should return error for empty slot + auto const emptySlot = hfs.getLedgerObjField(2, sfAccount); + BEAST_EXPECT( + !emptySlot.has_value() && + emptySlot.error() == HostFunctionError::EMPTY_SLOT); + + // Should return error for field not present + auto const notPresent = hfs.getLedgerObjField(1, sfOwner); + BEAST_EXPECT( + !notPresent.has_value() && + notPresent.error() == HostFunctionError::FIELD_NOT_FOUND); + } + + void + testGetTxNestedField() + { + testcase("getTxNestedField"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + + // Create a transaction with a nested array field + STTx const stx = STTx(ttESCROW_FINISH, [&](auto& obj) { + obj.setAccountID(sfAccount, env.master.id()); + STArray memos; + STObject memoObj(sfMemo); + memoObj.setFieldVL(sfMemoData, Slice("hello", 5)); + memos.push_back(memoObj); + obj.setFieldArray(sfMemos, memos); + }); + + ApplyContext ac = createApplyContext(env, ov, stx); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + // Locator for sfMemos[0].sfMemo.sfMemoData + // Locator is a sequence of int32_t codes: + // [sfMemos.fieldCode, 0, sfMemoData.fieldCode] + std::vector locatorVec = { + sfMemos.fieldCode, 0, sfMemoData.fieldCode}; + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + + auto const result = hfs.getTxNestedField(locator); + if (BEAST_EXPECTS( + result.has_value(), + std::to_string(static_cast(result.error())))) + { + std::string memoData( + result.value().begin(), result.value().end()); + BEAST_EXPECT(memoData == "hello"); + } + } + + { + // can use the nested locator for base fields too + std::vector locatorVec = {sfAccount.fieldCode}; + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + + auto const account = hfs.getTxNestedField(locator); + if (BEAST_EXPECTS( + account.has_value(), + std::to_string(static_cast(account.error())))) + { + BEAST_EXPECT(std::ranges::equal(*account, env.master.id())); + } + } + + auto expectError = [&](std::vector const& locatorVec, + HostFunctionError expectedError) { + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result = hfs.getTxNestedField(locator); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECTS( + result.error() == expectedError, + std::to_string(static_cast(result.error()))); + }; + // Locator for non-existent base field + expectError( + {sfSigners.fieldCode, // sfSigners does not exist + 0, + sfAccount.fieldCode}, + HostFunctionError::FIELD_NOT_FOUND); + + // Locator for non-existent index + expectError( + {sfMemos.fieldCode, + 1, // index 1 does not exist + sfMemoData.fieldCode}, + HostFunctionError::INDEX_OUT_OF_BOUNDS); + + // Locator for non-existent nested field + expectError( + {sfMemos.fieldCode, + 0, + sfURI.fieldCode}, // sfURI does not exist in the memo + HostFunctionError::FIELD_NOT_FOUND); + + // Locator for non-existent base sfield + expectError( + {field_code(20000, 20000), // nonexistent SField code + 0, + sfAccount.fieldCode}, + HostFunctionError::INVALID_FIELD); + + // Locator for non-existent nested sfield + expectError( + {sfMemos.fieldCode, // nonexistent SField code + 0, + field_code(20000, 20000)}, + HostFunctionError::INVALID_FIELD); + + // Locator for STArray + expectError({sfMemos.fieldCode}, HostFunctionError::NOT_LEAF_FIELD); + + // Locator for nesting into non-array/object field + expectError( + {sfAccount.fieldCode, // sfAccount is not an array or object + 0, + sfAccount.fieldCode}, + HostFunctionError::LOCATOR_MALFORMED); + + // Locator for empty locator + expectError({}, HostFunctionError::LOCATOR_MALFORMED); + + // Locator for malformed locator (not multiple of 4) + { + std::vector locatorVec = {sfMemos.fieldCode}; + Slice malformedLocator( + reinterpret_cast(locatorVec.data()), 3); + auto const malformedResult = hfs.getTxNestedField(malformedLocator); + BEAST_EXPECT( + !malformedResult.has_value() && + malformedResult.error() == + HostFunctionError::LOCATOR_MALFORMED); + } + } + + void + testGetCurrentLedgerObjNestedField() + { + testcase("getCurrentLedgerObjNestedField"); + using namespace test::jtx; + + Env env{*this}; + Account const alice("alice"); + Account const becky("becky"); + // Create a SignerList for env.master + env(signers(env.master, 2, {{alice, 1}, {becky, 1}})); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + // Find the signer ledger object + auto const signerKeylet = keylet::signers(env.master.id()); + BEAST_EXPECT(env.le(signerKeylet)); + + WasmHostFunctionsImpl hfs(ac, signerKeylet); + + // Locator for base field + std::vector baseLocator = {sfSignerQuorum.fieldCode}; + Slice baseLocatorSlice( + reinterpret_cast(baseLocator.data()), + baseLocator.size() * sizeof(int32_t)); + auto const signerQuorum = + hfs.getCurrentLedgerObjNestedField(baseLocatorSlice); + if (BEAST_EXPECTS( + signerQuorum.has_value(), + std::to_string(static_cast(signerQuorum.error())))) + { + BEAST_EXPECT(*signerQuorum == toBytes(static_cast(2))); + } + + auto expectError = [&](std::vector const& locatorVec, + HostFunctionError expectedError) { + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result = hfs.getCurrentLedgerObjNestedField(locator); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECTS( + result.error() == expectedError, + std::to_string(static_cast(result.error()))); + }; + // Locator for non-existent base field + expectError( + {sfSigners.fieldCode, // sfSigners does not exist + 0, + sfAccount.fieldCode}, + HostFunctionError::FIELD_NOT_FOUND); + // Locator for nesting into non-array/object field + expectError( + {sfSignerQuorum + .fieldCode, // sfSignerQuorum is not an array or object + 0, + sfAccount.fieldCode}, + HostFunctionError::LOCATOR_MALFORMED); + + // Locator for empty locator + Slice emptyLocator(nullptr, 0); + auto const emptyResult = + hfs.getCurrentLedgerObjNestedField(emptyLocator); + BEAST_EXPECT( + !emptyResult.has_value() && + emptyResult.error() == HostFunctionError::LOCATOR_MALFORMED); + + // Locator for malformed locator (not multiple of 4) + std::vector malformedLocatorVec = {sfMemos.fieldCode}; + Slice malformedLocator( + reinterpret_cast(malformedLocatorVec.data()), 3); + auto const malformedResult = + hfs.getCurrentLedgerObjNestedField(malformedLocator); + BEAST_EXPECT( + !malformedResult.has_value() && + malformedResult.error() == HostFunctionError::LOCATOR_MALFORMED); + + { + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master) + 5); + WasmHostFunctionsImpl dummyHfs(ac, dummyEscrow); + std::vector const locatorVec = {sfAccount.fieldCode}; + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result = + dummyHfs.getCurrentLedgerObjNestedField(locator); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECTS( + result.error() == HostFunctionError::LEDGER_OBJ_NOT_FOUND, + std::to_string(static_cast(result.error()))); + } + } + + void + testGetLedgerObjNestedField() + { + testcase("getLedgerObjNestedField"); + using namespace test::jtx; + + Env env{*this}; + Account const alice("alice"); + Account const becky("becky"); + // Create a SignerList for env.master + env(signers(env.master, 2, {{alice, 1}, {becky, 1}})); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + // Cache the SignerList ledger object in slot 1 + auto const signerListKeylet = keylet::signers(env.master.id()); + auto cacheResult = hfs.cacheLedgerObj(signerListKeylet.key, 1); + BEAST_EXPECT(cacheResult.has_value() && cacheResult.value() == 1); + + // Locator for sfSignerEntries[0].sfAccount + { + std::vector const locatorVec = { + sfSignerEntries.fieldCode, 0, sfAccount.fieldCode}; + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + + auto const result = hfs.getLedgerObjNestedField(1, locator); + if (BEAST_EXPECTS( + result.has_value(), + std::to_string(static_cast(result.error())))) + { + BEAST_EXPECT(std::ranges::equal(*result, alice.id())); + } + } + + // Locator for sfSignerEntries[1].sfAccount + { + std::vector const locatorVec = { + sfSignerEntries.fieldCode, 1, sfAccount.fieldCode}; + Slice const locator = Slice( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result2 = hfs.getLedgerObjNestedField(1, locator); + if (BEAST_EXPECTS( + result2.has_value(), + std::to_string(static_cast(result2.error())))) + { + BEAST_EXPECT(std::ranges::equal(*result2, becky.id())); + } + } + + // Locator for sfSignerEntries[0].sfSignerWeight + { + std::vector const locatorVec = { + sfSignerEntries.fieldCode, 0, sfSignerWeight.fieldCode}; + Slice const locator = Slice( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const weightResult = hfs.getLedgerObjNestedField(1, locator); + if (BEAST_EXPECTS( + weightResult.has_value(), + std::to_string(static_cast(weightResult.error())))) + { + // Should be 1 + auto const expected = toBytes(static_cast(1)); + BEAST_EXPECT(*weightResult == expected); + } + } + + // Locator for base field sfSignerQuorum + { + std::vector const locatorVec = {sfSignerQuorum.fieldCode}; + Slice const locator = Slice( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const quorumResult = hfs.getLedgerObjNestedField(1, locator); + if (BEAST_EXPECTS( + quorumResult.has_value(), + std::to_string(static_cast(quorumResult.error())))) + { + auto const expected = toBytes(static_cast(2)); + BEAST_EXPECT(*quorumResult == expected); + } + } + + // Helper for error checks + auto expectError = [&](std::vector const& locatorVec, + HostFunctionError expectedError, + int slot = 1) { + Slice const locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result = hfs.getLedgerObjNestedField(slot, locator); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECTS( + result.error() == expectedError, + std::to_string(static_cast(result.error()))); + }; + + // Error: base field not found + expectError( + {sfSigners.fieldCode, // sfSigners does not exist + 0, + sfAccount.fieldCode}, + HostFunctionError::FIELD_NOT_FOUND); + + // Error: index out of bounds + expectError( + {sfSignerEntries.fieldCode, + 2, // index 2 does not exist + sfAccount.fieldCode}, + HostFunctionError::INDEX_OUT_OF_BOUNDS); + + // Error: nested field not found + expectError( + { + sfSignerEntries.fieldCode, + 0, + sfDestination.fieldCode // sfDestination does not exist + }, + HostFunctionError::FIELD_NOT_FOUND); + + // Error: invalid field code + expectError( + {field_code(99999, 99999), 0, sfAccount.fieldCode}, + HostFunctionError::INVALID_FIELD); + + // Error: invalid nested field code + expectError( + {sfSignerEntries.fieldCode, 0, field_code(99999, 99999)}, + HostFunctionError::INVALID_FIELD); + + // Error: slot out of range + expectError( + {sfSignerQuorum.fieldCode}, HostFunctionError::SLOT_OUT_RANGE, 0); + expectError( + {sfSignerQuorum.fieldCode}, HostFunctionError::SLOT_OUT_RANGE, 257); + + // Error: empty slot + expectError( + {sfSignerQuorum.fieldCode}, HostFunctionError::EMPTY_SLOT, 2); + + // Error: locator for STArray (not leaf field) + expectError( + {sfSignerEntries.fieldCode}, HostFunctionError::NOT_LEAF_FIELD); + + // Error: nesting into non-array/object field + expectError( + {sfSignerQuorum.fieldCode, 0, sfAccount.fieldCode}, + HostFunctionError::LOCATOR_MALFORMED); + + // Error: empty locator + expectError({}, HostFunctionError::LOCATOR_MALFORMED); + + // Error: locator malformed (not multiple of 4) + std::vector const locatorVec = {sfSignerEntries.fieldCode}; + Slice const locator = + Slice(reinterpret_cast(locatorVec.data()), 3); + auto const malformed = hfs.getLedgerObjNestedField(1, locator); + BEAST_EXPECT( + !malformed.has_value() && + malformed.error() == HostFunctionError::LOCATOR_MALFORMED); + } + + void + testGetTxArrayLen() + { + testcase("getTxArrayLen"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + + // Transaction with an array field + STTx stx = STTx(ttESCROW_FINISH, [&](auto& obj) { + obj.setAccountID(sfAccount, env.master.id()); + STArray memos; + { + STObject memoObj(sfMemo); + memoObj.setFieldVL(sfMemoData, Slice("hello", 5)); + memos.push_back(memoObj); + } + { + STObject memoObj(sfMemo); + memoObj.setFieldVL(sfMemoData, Slice("world", 5)); + memos.push_back(memoObj); + } + obj.setFieldArray(sfMemos, memos); + }); + + ApplyContext ac = createApplyContext(env, ov, stx); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + // Should return 1 for sfMemos + auto const memosLen = hfs.getTxArrayLen(sfMemos); + if (BEAST_EXPECT(memosLen.has_value())) + BEAST_EXPECT(memosLen.value() == 2); + + // Should return error for non-array field + auto const notArray = hfs.getTxArrayLen(sfAccount); + if (BEAST_EXPECT(!notArray.has_value())) + BEAST_EXPECT(notArray.error() == HostFunctionError::NO_ARRAY); + + // Should return error for missing array field + auto const missingArray = hfs.getTxArrayLen(sfSigners); + if (BEAST_EXPECT(!missingArray.has_value())) + BEAST_EXPECT( + missingArray.error() == HostFunctionError::FIELD_NOT_FOUND); + } + + void + testGetCurrentLedgerObjArrayLen() + { + testcase("getCurrentLedgerObjArrayLen"); + using namespace test::jtx; + + Env env{*this}; + Account const alice("alice"); + Account const becky("becky"); + // Create a SignerList for env.master + env(signers(env.master, 2, {{alice, 1}, {becky, 1}})); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const signerKeylet = keylet::signers(env.master.id()); + WasmHostFunctionsImpl hfs(ac, signerKeylet); + + auto const entriesLen = + hfs.getCurrentLedgerObjArrayLen(sfSignerEntries); + if (BEAST_EXPECT(entriesLen.has_value())) + BEAST_EXPECT(entriesLen.value() == 2); + + auto const arrLen = hfs.getCurrentLedgerObjArrayLen(sfMemos); + if (BEAST_EXPECT(!arrLen.has_value())) + BEAST_EXPECT(arrLen.error() == HostFunctionError::FIELD_NOT_FOUND); + + // Should return NO_ARRAY for non-array field + auto const notArray = hfs.getCurrentLedgerObjArrayLen(sfAccount); + if (BEAST_EXPECT(!notArray.has_value())) + BEAST_EXPECT(notArray.error() == HostFunctionError::NO_ARRAY); + + { + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master) + 5); + WasmHostFunctionsImpl dummyHfs(ac, dummyEscrow); + auto const len = dummyHfs.getCurrentLedgerObjArrayLen(sfMemos); + if (BEAST_EXPECT(!len.has_value())) + BEAST_EXPECT( + len.error() == HostFunctionError::LEDGER_OBJ_NOT_FOUND); + } + } + + void + testGetLedgerObjArrayLen() + { + testcase("getLedgerObjArrayLen"); + using namespace test::jtx; + + Env env{*this}; + Account const alice("alice"); + Account const becky("becky"); + // Create a SignerList for env.master + env(signers(env.master, 2, {{alice, 1}, {becky, 1}})); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + auto const signerListKeylet = keylet::signers(env.master.id()); + auto cacheResult = hfs.cacheLedgerObj(signerListKeylet.key, 1); + BEAST_EXPECT(cacheResult.has_value() && cacheResult.value() == 1); + + { + auto const arrLen = hfs.getLedgerObjArrayLen(1, sfSignerEntries); + if (BEAST_EXPECT(arrLen.has_value())) + // Should return 2 for sfSignerEntries + BEAST_EXPECT(arrLen.value() == 2); + } + { + auto const arrLen = hfs.getLedgerObjArrayLen(0, sfSignerEntries); + if (BEAST_EXPECT(!arrLen.has_value())) + BEAST_EXPECT( + arrLen.error() == HostFunctionError::SLOT_OUT_RANGE); + } + + { + // Should return error for non-array field + auto const notArray = hfs.getLedgerObjArrayLen(1, sfAccount); + if (BEAST_EXPECT(!notArray.has_value())) + BEAST_EXPECT(notArray.error() == HostFunctionError::NO_ARRAY); + } + + { + // Should return error for empty slot + auto const emptySlot = hfs.getLedgerObjArrayLen(2, sfSignerEntries); + if (BEAST_EXPECT(!emptySlot.has_value())) + BEAST_EXPECT( + emptySlot.error() == HostFunctionError::EMPTY_SLOT); + } + + { + // Should return error for missing array field + auto const missingArray = hfs.getLedgerObjArrayLen(1, sfMemos); + if (BEAST_EXPECT(!missingArray.has_value())) + BEAST_EXPECT( + missingArray.error() == HostFunctionError::FIELD_NOT_FOUND); + } + } + + void + testGetTxNestedArrayLen() + { + testcase("getTxNestedArrayLen"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + + STTx stx = STTx(ttESCROW_FINISH, [&](auto& obj) { + STArray memos; + STObject memoObj(sfMemo); + memoObj.setFieldVL(sfMemoData, Slice("hello", 5)); + memos.push_back(memoObj); + obj.setFieldArray(sfMemos, memos); + }); + + ApplyContext ac = createApplyContext(env, ov, stx); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + // Helper for error checks + auto expectError = [&](std::vector const& locatorVec, + HostFunctionError expectedError, + int slot = 1) { + Slice const locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result = hfs.getTxNestedArrayLen(locator); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECTS( + result.error() == expectedError, + std::to_string(static_cast(result.error()))); + }; + + // Locator for sfMemos + { + std::vector locatorVec = {sfMemos.fieldCode}; + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const arrLen = hfs.getTxNestedArrayLen(locator); + BEAST_EXPECT(arrLen.has_value() && arrLen.value() == 1); + } + + // Error: non-array field + expectError({sfAccount.fieldCode}, HostFunctionError::NO_ARRAY); + + // Error: missing field + expectError({sfSigners.fieldCode}, HostFunctionError::FIELD_NOT_FOUND); + } + + void + testGetCurrentLedgerObjNestedArrayLen() + { + testcase("getCurrentLedgerObjNestedArrayLen"); + using namespace test::jtx; + + Env env{*this}; + Account const alice("alice"); + Account const becky("becky"); + // Create a SignerList for env.master + env(signers(env.master, 2, {{alice, 1}, {becky, 1}})); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const signerKeylet = keylet::signers(env.master.id()); + WasmHostFunctionsImpl hfs(ac, signerKeylet); + + // Helper for error checks + auto expectError = [&](std::vector const& locatorVec, + HostFunctionError expectedError, + int slot = 1) { + Slice const locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result = hfs.getCurrentLedgerObjNestedArrayLen(locator); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECTS( + result.error() == expectedError, + std::to_string(static_cast(result.error()))); + }; + + // Locator for sfSignerEntries + { + std::vector locatorVec = {sfSignerEntries.fieldCode}; + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const arrLen = hfs.getCurrentLedgerObjNestedArrayLen(locator); + BEAST_EXPECT(arrLen.has_value() && arrLen.value() == 2); + } + + // Error: non-array field + expectError({sfSignerQuorum.fieldCode}, HostFunctionError::NO_ARRAY); + + // Error: missing field + expectError({sfSigners.fieldCode}, HostFunctionError::FIELD_NOT_FOUND); + + { + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master) + 5); + WasmHostFunctionsImpl dummyHfs(ac, dummyEscrow); + std::vector locatorVec = {sfAccount.fieldCode}; + Slice const locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result = + dummyHfs.getCurrentLedgerObjNestedArrayLen(locator); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECTS( + result.error() == HostFunctionError::LEDGER_OBJ_NOT_FOUND, + std::to_string(static_cast(result.error()))); + } + } + + void + testGetLedgerObjNestedArrayLen() + { + testcase("getLedgerObjNestedArrayLen"); + using namespace test::jtx; + + Env env{*this}; + Account const alice("alice"); + Account const becky("becky"); + env(signers(env.master, 2, {{alice, 1}, {becky, 1}})); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + auto const signerListKeylet = keylet::signers(env.master.id()); + auto cacheResult = hfs.cacheLedgerObj(signerListKeylet.key, 1); + BEAST_EXPECT(cacheResult.has_value() && cacheResult.value() == 1); + + // Locator for sfSignerEntries + std::vector locatorVec = {sfSignerEntries.fieldCode}; + Slice locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const arrLen = hfs.getLedgerObjNestedArrayLen(1, locator); + if (BEAST_EXPECT(arrLen.has_value())) + BEAST_EXPECT(arrLen.value() == 2); + + // Helper for error checks + auto expectError = [&](std::vector const& locatorVec, + HostFunctionError expectedError, + int slot = 1) { + Slice const locator( + reinterpret_cast(locatorVec.data()), + locatorVec.size() * sizeof(int32_t)); + auto const result = hfs.getLedgerObjNestedArrayLen(slot, locator); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECTS( + result.error() == expectedError, + std::to_string(static_cast(result.error()))); + }; + + // Error: non-array field + expectError({sfSignerQuorum.fieldCode}, HostFunctionError::NO_ARRAY); + + // Error: missing field + expectError({sfSigners.fieldCode}, HostFunctionError::FIELD_NOT_FOUND); + + // Slot out of range + expectError(locatorVec, HostFunctionError::SLOT_OUT_RANGE, 0); + expectError(locatorVec, HostFunctionError::SLOT_OUT_RANGE, 257); + + // Empty slot + expectError(locatorVec, HostFunctionError::EMPTY_SLOT, 2); + + // Error: empty locator + expectError({}, HostFunctionError::LOCATOR_MALFORMED); + + // Error: locator malformed (not multiple of 4) + Slice malformedLocator( + reinterpret_cast(locator.data()), 3); + auto const malformed = + hfs.getLedgerObjNestedArrayLen(1, malformedLocator); + BEAST_EXPECT( + !malformed.has_value() && + malformed.error() == HostFunctionError::LOCATOR_MALFORMED); + + // Error: locator for non-STArray field + expectError( + {sfSignerQuorum.fieldCode, 0, sfAccount.fieldCode}, + HostFunctionError::LOCATOR_MALFORMED); + } + + void + testUpdateData() + { + testcase("updateData"); + using namespace test::jtx; + + Env env{*this}; + env(escrow::create(env.master, env.master, XRP(100)), + escrow::finish_time(env.now() + std::chrono::seconds(1))); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const escrowKeylet = + keylet::escrow(env.master, env.seq(env.master) - 1); + WasmHostFunctionsImpl hfs(ac, escrowKeylet); + + // Should succeed for small data + std::vector data(10, 0x42); + auto const result = hfs.updateData(Slice(data.data(), data.size())); + BEAST_EXPECT(result.has_value() && result.value() == 0); + + // Should fail for too large data + std::vector bigData(maxWasmDataLength + 1, 0x42); + auto const tooBig = + hfs.updateData(Slice(bigData.data(), bigData.size())); + if (BEAST_EXPECT(!tooBig.has_value())) + BEAST_EXPECT( + tooBig.error() == HostFunctionError::DATA_FIELD_TOO_LARGE); + } + + void + testCheckSignature() + { + testcase("checkSignature"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + // Generate a keypair and sign a message + auto const kp = generateKeyPair(KeyType::secp256k1, randomSeed()); + PublicKey const& pk = kp.first; + SecretKey const& sk = kp.second; + std::string const& message = "hello signature"; + auto const sig = sign(pk, sk, Slice(message.data(), message.size())); + + // Should succeed for valid signature + { + auto const result = hfs.checkSignature( + Slice(message.data(), message.size()), + Slice(sig.data(), sig.size()), + Slice(pk.data(), pk.size())); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == 1); + } + + // Should fail for invalid signature + { + std::string badSig(sig.size(), 0xFF); + auto const result = hfs.checkSignature( + Slice(message.data(), message.size()), + Slice(badSig.data(), badSig.size()), + Slice(pk.data(), pk.size())); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == 0); + } + + // Should fail for invalid public key + { + std::string badPk(pk.size(), 0x00); + auto const result = hfs.checkSignature( + Slice(message.data(), message.size()), + Slice(sig.data(), sig.size()), + Slice(badPk.data(), badPk.size())); + BEAST_EXPECT(!result.has_value()); + BEAST_EXPECT(result.error() == HostFunctionError::INVALID_PARAMS); + } + + // Should fail for empty public key + { + auto const result = hfs.checkSignature( + Slice(message.data(), message.size()), + Slice(sig.data(), sig.size()), + Slice(nullptr, 0)); + BEAST_EXPECT(!result.has_value()); + BEAST_EXPECT(result.error() == HostFunctionError::INVALID_PARAMS); + } + + // Should fail for empty signature + { + auto const result = hfs.checkSignature( + Slice(message.data(), message.size()), + Slice(nullptr, 0), + Slice(pk.data(), pk.size())); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == 0); + } + + // Should fail for empty message + { + auto const result = hfs.checkSignature( + Slice(nullptr, 0), + Slice(sig.data(), sig.size()), + Slice(pk.data(), pk.size())); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == 0); + } + } + + void + testComputeSha512HalfHash() + { + testcase("computeSha512HalfHash"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + std::string data = "hello world"; + auto const result = + hfs.computeSha512HalfHash(Slice(data.data(), data.size())); + BEAST_EXPECT(result.has_value()); + + // Should match direct call to sha512Half + auto expected = sha512Half(Slice(data.data(), data.size())); + BEAST_EXPECT(result.value() == expected); + } + + void + testKeyletFunctions() + { + testcase("keylet functions"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + auto compareKeylet = [](std::vector const& bytes, + Keylet const& kl) { + return std::ranges::equal(bytes, kl.key); + }; +// Lambda to compare a Bytes (std::vector) to a keylet +#define COMPARE_KEYLET(hfsFunc, keyletFunc, ...) \ + { \ + auto actual = hfs.hfsFunc(__VA_ARGS__); \ + auto expected = keyletFunc(__VA_ARGS__); \ + if (BEAST_EXPECT(actual.has_value())) \ + { \ + BEAST_EXPECT(compareKeylet(actual.value(), expected)); \ + } \ + } +#define COMPARE_KEYLET_FAIL(hfsFunc, expected, ...) \ + { \ + auto actual = hfs.hfsFunc(__VA_ARGS__); \ + if (BEAST_EXPECT(!actual.has_value())) \ + { \ + BEAST_EXPECTS( \ + actual.error() == expected, \ + std::to_string(HfErrorToInt(actual.error()))); \ + } \ + } + + COMPARE_KEYLET(accountKeylet, keylet::account, env.master.id()); + COMPARE_KEYLET_FAIL( + accountKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount()); + + COMPARE_KEYLET( + ammKeylet, keylet::amm, xrpIssue(), env.master["USD"].issue()); + COMPARE_KEYLET_FAIL( + ammKeylet, + HostFunctionError::INVALID_PARAMS, + xrpIssue(), + xrpIssue()); + COMPARE_KEYLET_FAIL( + ammKeylet, + HostFunctionError::INVALID_PARAMS, + makeMptID(1, env.master.id()), + xrpIssue()); + + COMPARE_KEYLET(checkKeylet, keylet::check, env.master.id(), 1); + COMPARE_KEYLET_FAIL( + checkKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount(), 1); + + std::string const credType = "test"; + COMPARE_KEYLET( + credentialKeylet, + keylet::credential, + env.master.id(), + env.master.id(), + Slice(credType.data(), credType.size())); + + Account const alice("alice"); + constexpr std::string_view longCredType = + "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]" + "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p"; + static_assert(longCredType.size() > maxCredentialTypeLength); + COMPARE_KEYLET_FAIL( + credentialKeylet, + HostFunctionError::INVALID_PARAMS, + env.master.id(), + alice.id(), + Slice(longCredType.data(), longCredType.size())); + COMPARE_KEYLET_FAIL( + credentialKeylet, + HostFunctionError::INVALID_ACCOUNT, + xrpAccount(), + alice.id(), + Slice(credType.data(), credType.size())); + COMPARE_KEYLET_FAIL( + credentialKeylet, + HostFunctionError::INVALID_ACCOUNT, + env.master.id(), + xrpAccount(), + Slice(credType.data(), credType.size())); + + COMPARE_KEYLET(didKeylet, keylet::did, env.master.id()); + COMPARE_KEYLET_FAIL( + didKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount()); + + COMPARE_KEYLET( + delegateKeylet, keylet::delegate, env.master.id(), alice.id()); + COMPARE_KEYLET_FAIL( + delegateKeylet, + HostFunctionError::INVALID_PARAMS, + env.master.id(), + env.master.id()); + COMPARE_KEYLET_FAIL( + delegateKeylet, + HostFunctionError::INVALID_ACCOUNT, + env.master.id(), + xrpAccount()); + COMPARE_KEYLET_FAIL( + delegateKeylet, + HostFunctionError::INVALID_ACCOUNT, + xrpAccount(), + env.master.id()); + + COMPARE_KEYLET( + depositPreauthKeylet, + keylet::depositPreauth, + env.master.id(), + alice.id()); + COMPARE_KEYLET_FAIL( + depositPreauthKeylet, + HostFunctionError::INVALID_PARAMS, + env.master.id(), + env.master.id()); + COMPARE_KEYLET_FAIL( + depositPreauthKeylet, + HostFunctionError::INVALID_ACCOUNT, + env.master.id(), + xrpAccount()); + COMPARE_KEYLET_FAIL( + depositPreauthKeylet, + HostFunctionError::INVALID_ACCOUNT, + xrpAccount(), + env.master.id()); + + COMPARE_KEYLET(escrowKeylet, keylet::escrow, env.master.id(), 1); + COMPARE_KEYLET_FAIL( + escrowKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount(), 1); + + Currency usd = to_currency("USD"); + COMPARE_KEYLET( + lineKeylet, keylet::line, env.master.id(), alice.id(), usd); + COMPARE_KEYLET_FAIL( + lineKeylet, + HostFunctionError::INVALID_PARAMS, + env.master.id(), + env.master.id(), + usd); + COMPARE_KEYLET_FAIL( + lineKeylet, + HostFunctionError::INVALID_ACCOUNT, + env.master.id(), + xrpAccount(), + usd); + COMPARE_KEYLET_FAIL( + lineKeylet, + HostFunctionError::INVALID_ACCOUNT, + xrpAccount(), + env.master.id(), + usd); + COMPARE_KEYLET_FAIL( + lineKeylet, + HostFunctionError::INVALID_PARAMS, + env.master.id(), + alice.id(), + to_currency("")); + + { + auto actual = hfs.mptIssuanceKeylet(env.master.id(), 1); + auto expected = keylet::mptIssuance(1, env.master.id()); + if (BEAST_EXPECT(actual.has_value())) + { + BEAST_EXPECT(compareKeylet(actual.value(), expected)); + } + } + { + auto actual = hfs.mptIssuanceKeylet(xrpAccount(), 1); + if (BEAST_EXPECT(!actual.has_value())) + BEAST_EXPECT( + actual.error() == HostFunctionError::INVALID_ACCOUNT); + } + + auto const sampleMPTID = makeMptID(1, env.master.id()); + COMPARE_KEYLET(mptokenKeylet, keylet::mptoken, sampleMPTID, alice.id()); + COMPARE_KEYLET_FAIL( + mptokenKeylet, + HostFunctionError::INVALID_PARAMS, + MPTID{}, + alice.id()); + COMPARE_KEYLET_FAIL( + mptokenKeylet, + HostFunctionError::INVALID_ACCOUNT, + sampleMPTID, + xrpAccount()); + + COMPARE_KEYLET(nftOfferKeylet, keylet::nftoffer, env.master.id(), 1); + COMPARE_KEYLET_FAIL( + nftOfferKeylet, + HostFunctionError::INVALID_ACCOUNT, + xrpAccount(), + 1); + + COMPARE_KEYLET(offerKeylet, keylet::offer, env.master.id(), 1); + COMPARE_KEYLET_FAIL( + offerKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount(), 1); + + COMPARE_KEYLET(oracleKeylet, keylet::oracle, env.master.id(), 1); + COMPARE_KEYLET_FAIL( + oracleKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount(), 1); + + COMPARE_KEYLET( + paychanKeylet, keylet::payChan, env.master.id(), alice.id(), 1); + COMPARE_KEYLET_FAIL( + paychanKeylet, + HostFunctionError::INVALID_PARAMS, + env.master.id(), + env.master.id(), + 1); + COMPARE_KEYLET_FAIL( + paychanKeylet, + HostFunctionError::INVALID_ACCOUNT, + env.master.id(), + xrpAccount(), + 1); + COMPARE_KEYLET_FAIL( + paychanKeylet, + HostFunctionError::INVALID_ACCOUNT, + xrpAccount(), + env.master.id(), + 1); + + COMPARE_KEYLET( + permissionedDomainKeylet, + keylet::permissionedDomain, + env.master.id(), + 1); + COMPARE_KEYLET_FAIL( + permissionedDomainKeylet, + HostFunctionError::INVALID_ACCOUNT, + xrpAccount(), + 1); + + COMPARE_KEYLET(signersKeylet, keylet::signers, env.master.id()); + COMPARE_KEYLET_FAIL( + signersKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount()); + + COMPARE_KEYLET(ticketKeylet, keylet::ticket, env.master.id(), 1); + COMPARE_KEYLET_FAIL( + ticketKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount(), 1); + + COMPARE_KEYLET(vaultKeylet, keylet::vault, env.master.id(), 1); + COMPARE_KEYLET_FAIL( + vaultKeylet, HostFunctionError::INVALID_ACCOUNT, xrpAccount(), 1); + } + + void + testGetNFT() + { + testcase("getNFT"); + using namespace test::jtx; + + Env env{*this}; + Account const alice("alice"); + env.fund(XRP(1000), alice); + env.close(); + + // Mint NFT for alice + uint256 const nftId = token::getNextID(env, alice, 0u, 0u); + std::string const uri = "https://example.com/nft"; + env(token::mint(alice), token::uri(uri)); + env.close(); + uint256 const nftId2 = token::getNextID(env, alice, 0u, 0u); + env(token::mint(alice)); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = keylet::escrow(alice, env.seq(alice)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + // Should succeed for valid NFT + { + auto const result = hfs.getNFT(alice.id(), nftId); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(std::ranges::equal(*result, uri)); + } + + // Should fail for invalid account + { + auto const result = hfs.getNFT(xrpAccount(), nftId); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECT( + result.error() == HostFunctionError::INVALID_ACCOUNT); + } + + // Should fail for invalid nftId + { + auto const result = hfs.getNFT(alice.id(), uint256()); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECT( + result.error() == HostFunctionError::INVALID_PARAMS); + } + + // Should fail for invalid nftId + { + auto const badId = token::getNextID(env, alice, 0u, 1u); + auto const result = hfs.getNFT(alice.id(), badId); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECT( + result.error() == HostFunctionError::LEDGER_OBJ_NOT_FOUND); + } + + { + auto const result = hfs.getNFT(alice.id(), nftId2); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECT( + result.error() == HostFunctionError::FIELD_NOT_FOUND); + } + } + + void + testGetNFTIssuer() + { + testcase("getNFTIssuer"); + using namespace test::jtx; + + Env env{*this}; + // Mint NFT for env.master + uint32_t const taxon = 12345; + uint256 const nftId = token::getNextID(env, env.master, taxon); + env(token::mint(env.master, taxon)); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + // Should succeed for valid NFT id + { + auto const result = hfs.getNFTIssuer(nftId); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(std::ranges::equal(*result, env.master.id())); + } + + // Should fail for zero NFT id + { + auto const result = hfs.getNFTIssuer(uint256()); + if (BEAST_EXPECT(!result.has_value())) + BEAST_EXPECT( + result.error() == HostFunctionError::INVALID_PARAMS); + } + } + + void + testGetNFTTaxon() + { + testcase("getNFTTaxon"); + using namespace test::jtx; + + Env env{*this}; + + uint32_t const taxon = 54321; + uint256 const nftId = token::getNextID(env, env.master, taxon); + env(token::mint(env.master, taxon)); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + auto const result = hfs.getNFTTaxon(nftId); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == taxon); + } + + void + testGetNFTFlags() + { + testcase("getNFTFlags"); + using namespace test::jtx; + + Env env{*this}; + + // Mint NFT with default flags + uint256 const nftId = + token::getNextID(env, env.master, 0u, tfTransferable); + env(token::mint(env.master, 0), txflags(tfTransferable)); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.getNFTFlags(nftId); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == tfTransferable); + } + + // Should return 0 for zero NFT id + { + auto const result = hfs.getNFTFlags(uint256()); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == 0); + } + } + + void + testGetNFTTransferFee() + { + testcase("getNFTTransferFee"); + using namespace test::jtx; + + Env env{*this}; + + uint16_t const transferFee = 250; + uint256 const nftId = + token::getNextID(env, env.master, 0u, tfTransferable, transferFee); + env(token::mint(env.master, 0), + token::xferFee(transferFee), + txflags(tfTransferable)); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.getNFTTransferFee(nftId); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == transferFee); + } + + // Should return 0 for zero NFT id + { + auto const result = hfs.getNFTTransferFee(uint256()); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == 0); + } + } + + void + testGetNFTSerial() + { + testcase("getNFTSerial"); + using namespace test::jtx; + + Env env{*this}; + + // Mint NFT with serial 0 + uint256 const nftId = token::getNextID(env, env.master, 0u); + auto const serial = env.seq(env.master); + env(token::mint(env.master)); + env.close(); + + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.getNFTSerial(nftId); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == serial); + } + + // Should return 0 for zero NFT id + { + auto const result = hfs.getNFTSerial(uint256()); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT(result.value() == 0); + } + } + + void + testTrace() + { + testcase("trace"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + std::string msg = "test trace"; + std::string data = "abc"; + auto const slice = Slice(data.data(), data.size()); + auto const result = hfs.trace(msg, slice, false); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == msg.size() + data.size()); + + auto const resultHex = hfs.trace(msg, slice, true); + BEAST_EXPECT(resultHex.has_value()); + BEAST_EXPECT(resultHex.value() == msg.size() + data.size() * 2); + } + + void + testTraceNum() + { + testcase("traceNum"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + std::string msg = "trace number"; + int64_t num = 123456789; + auto const result = hfs.traceNum(msg, num); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(result.value() == msg.size() + sizeof(num)); + } + + void + testTraceAccount() + { + testcase("traceAccount"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + std::string msg = "trace account"; + // Valid account + { + auto const result = hfs.traceAccount(msg, env.master.id()); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT( + result.value() == + msg.size() + toBase58(env.master.id()).size()); + } + } + + void + testTraceAmount() + { + testcase("traceAmount"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + std::string msg = "trace amount"; + STAmount amount = XRP(12345); + { + auto const result = hfs.traceAmount(msg, amount); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT( + result.value() == msg.size() + amount.getFullText().size()); + } + + // IOU amount + Account const alice("alice"); + env.fund(XRP(1000), alice); + env.close(); + STAmount iouAmount = env.master["USD"](100); + { + auto const result = hfs.traceAmount(msg, iouAmount); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT( + result.value() == + msg.size() + iouAmount.getFullText().size()); + } + + // MPT amount + { + auto const mptId = makeMptID(42, env.master.id()); + Asset mptAsset = Asset(mptId); + STAmount mptAmount(mptAsset, 123456); + auto const result = hfs.traceAmount(msg, mptAmount); + if (BEAST_EXPECT(result.has_value())) + BEAST_EXPECT( + result.value() == + msg.size() + mptAmount.getFullText().size()); + } + } + + // clang-format off + + int const normalExp = 15; + + Bytes const floatIntMin = {0x99, 0x20, 0xc4, 0x9b, 0xa5, 0xe3, 0x53, 0xf8}; // -2^63 + Bytes const floatIntZero = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 0 + Bytes const floatIntMax = {0xd9, 0x20, 0xc4, 0x9b, 0xa5, 0xe3, 0x53, 0xf8}; // 2^63-1 + Bytes const floatUIntMax = {0xd9, 0x46, 0x8d, 0xb8, 0xba, 0xc7, 0x10, 0xcb}; // 2^64 + Bytes const floatMaxExp = {0xEC, 0x43, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1e(80+15) + Bytes const floatPreMaxExp = {0xEC, 0x03, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1e(79+15) + Bytes const floatMinusMaxExp = {0xAC, 0x43, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // -1e(80+15) + Bytes const floatMaxIOU = {0xEC, 0x63, 0x86, 0xF2, 0x6F, 0xC0, 0xFF, 0xFF}; // 1e(81+15)-1 + Bytes const floatMinExp = {0xC0, 0x43, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1e-96 + Bytes const float1 = {0xD4, 0x83, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1 + Bytes const floatMinus1 = {0x94, 0x83, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // -1 + Bytes const float1More = {0xD4, 0x83, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x01}; // 1.000 000 000 000 001 + Bytes const float2 = {0xD4, 0x87, 0x1A, 0xFD, 0x49, 0x8D, 0x00, 0x00}; // 2 + Bytes const float10 = {0xD4, 0xC3, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 10 + Bytes const floatInvalidZero = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // INVALID + Bytes const floatPi = {0xD4, 0x8B, 0x29, 0x43, 0x0A, 0x25, 0x6D, 0x21}; // 3.141592653589793 + + std::string const invalid = "invalid_data"; + + // clang-format on + + void + testFloatTrace() + { + testcase("FloatTrace"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + std::string msg = "trace float"; + + { + auto const result = hfs.traceFloat(msg, makeSlice(invalid)); + BEAST_EXPECT( + result && + *result == + msg.size() + 14 /* error msg size*/ + invalid.size() * 2); + } + + { + auto const result = hfs.traceFloat(msg, makeSlice(floatMaxExp)); + BEAST_EXPECT( + result && *result == msg.size() + 19 /* string represenation*/); + } + } + + void + testFloatFromInt() + { + testcase("FloatFromInt"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = + hfs.floatFromInt(std::numeric_limits::min(), -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatFromInt(std::numeric_limits::min(), 4); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatFromInt(std::numeric_limits::min(), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntMin); + } + + { + auto const result = hfs.floatFromInt(0, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero); + } + + { + auto const result = + hfs.floatFromInt(std::numeric_limits::max(), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntMax); + } + } + + void + testFloatFromUint() + { + testcase("FloatFromUint"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = + hfs.floatFromUint(std::numeric_limits::min(), -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatFromUint(std::numeric_limits::min(), 4); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatFromUint(0, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero); + } + + { + auto const result = + hfs.floatFromUint(std::numeric_limits::max(), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatUIntMax); + } + } + + void + testFloatSet() + { + testcase("FloatSet"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatSet(1, 0, -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatSet(1, 0, 4); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatSet(1, Number::maxExponent + normalExp + 1, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + + { + auto const result = + hfs.floatSet(1, IOUAmount::maxExponent + normalExp + 1, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + + { + auto const result = + hfs.floatSet(1, IOUAmount::minExponent + normalExp - 1, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero); + } + + { + auto const result = + hfs.floatSet(1, IOUAmount::maxExponent + normalExp, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxExp); + } + + { + auto const result = + hfs.floatSet(-1, IOUAmount::maxExponent + normalExp, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinusMaxExp); + } + + { + auto const result = + hfs.floatSet(1, IOUAmount::maxExponent + normalExp - 1, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatPreMaxExp); + } + + { + auto const result = + hfs.floatSet(IOUAmount::maxMantissa, IOUAmount::maxExponent, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxIOU); + } + + { + auto const result = + hfs.floatSet(1, IOUAmount::minExponent + normalExp, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinExp); + } + + { + auto const result = hfs.floatSet(10, -1, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == float1); + } + } + + void + testFloatCompare() + { + testcase("FloatCompare"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatCompare(Slice(), Slice()); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatCompare(makeSlice(floatInvalidZero), Slice()); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatCompare(makeSlice(float1), makeSlice(invalid)); + BEAST_EXPECT( + !result && + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto x = floatMaxExp; + // exp = 81 + 97 = 178 + x[1] |= 0x80; + x[1] &= 0xBF; + auto const result = + hfs.floatCompare(makeSlice(x), makeSlice(floatMaxExp)); + BEAST_EXPECT( + !result && + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatCompare( + makeSlice(floatIntMin), makeSlice(floatIntZero)); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == 2); + } + + { + auto const result = hfs.floatCompare( + makeSlice(floatIntMax), makeSlice(floatIntZero)); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == 1); + } + + { + auto const result = + hfs.floatCompare(makeSlice(float1), makeSlice(float1)); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == 0); + } + } + + void + testFloatAdd() + { + testcase("floatAdd"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatAdd(Slice(), Slice(), -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatAdd(Slice(), Slice(), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatAdd(makeSlice(float1), makeSlice(invalid), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatAdd(makeSlice(floatMaxIOU), makeSlice(floatMaxExp), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + + { + auto const result = hfs.floatAdd( + makeSlice(floatIntMin), makeSlice(floatIntZero), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntMin); + } + + { + auto const result = + hfs.floatAdd(makeSlice(floatIntMax), makeSlice(floatIntMin), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero); + } + } + + void + testFloatSubtract() + { + testcase("floatSubtract"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatSubtract(Slice(), Slice(), -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatSubtract(Slice(), Slice(), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatSubtract(makeSlice(float1), makeSlice(invalid), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatSubtract( + makeSlice(floatMaxIOU), makeSlice(floatMinusMaxExp), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + + { + auto const result = hfs.floatSubtract( + makeSlice(floatIntMin), makeSlice(floatIntZero), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntMin); + } + + { + auto const result = hfs.floatSubtract( + makeSlice(floatIntZero), makeSlice(float1), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMinus1); + } + } + + void + testFloatMultiply() + { + testcase("floatMultiply"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatMultiply(Slice(), Slice(), -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatMultiply(Slice(), Slice(), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatMultiply(makeSlice(float1), makeSlice(invalid), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatMultiply( + makeSlice(floatMaxIOU), makeSlice(float1More), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + + { + auto const result = + hfs.floatMultiply(makeSlice(float1), makeSlice(float1), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == float1); + } + + { + auto const result = hfs.floatMultiply( + makeSlice(floatIntZero), makeSlice(floatMaxIOU), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero); + } + + { + auto const result = hfs.floatMultiply( + makeSlice(float10), makeSlice(floatPreMaxExp), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxExp); + } + } + + void + testFloatDivide() + { + testcase("floatDivide"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatDivide(Slice(), Slice(), -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatDivide(Slice(), Slice(), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatDivide(makeSlice(float1), makeSlice(invalid), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatDivide(makeSlice(float1), makeSlice(floatIntZero), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + + { + auto const y = hfs.floatSet( + IOUAmount::maxMantissa, -normalExp - 1, 0); // 0.9999999... + if (BEAST_EXPECT(y)) + { + auto const result = + hfs.floatDivide(makeSlice(floatMaxIOU), makeSlice(*y), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + } + + { + auto const result = + hfs.floatDivide(makeSlice(floatIntZero), makeSlice(float1), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero); + } + + { + auto const result = + hfs.floatDivide(makeSlice(floatMaxExp), makeSlice(float10), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatPreMaxExp); + } + } + + void + testFloatRoot() + { + testcase("floatRoot"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatRoot(Slice(), 2, -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatRoot(makeSlice(invalid), 3, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatRoot(makeSlice(float1), -2, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatRoot(makeSlice(floatIntZero), 2, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatIntZero); + } + + { + auto const result = hfs.floatRoot(makeSlice(floatMaxIOU), 1, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxIOU); + } + + { + auto const x = hfs.floatSet(100, 0, 0); // 100 + if (BEAST_EXPECT(x)) + { + auto const result = hfs.floatRoot(makeSlice(*x), 2, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == float10); + } + } + + { + auto const x = hfs.floatSet(1000, 0, 0); // 1000 + if (BEAST_EXPECT(x)) + { + auto const result = hfs.floatRoot(makeSlice(*x), 3, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == float10); + } + } + + { + auto const x = hfs.floatSet(1, -2, 0); // 0.01 + auto const y = hfs.floatSet(1, -1, 0); // 0.1 + if (BEAST_EXPECT(x && y)) + { + auto const result = hfs.floatRoot(makeSlice(*x), 2, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == *y); + } + } + } + + void + testFloatPower() + { + testcase("floatPower"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatPower(Slice(), 2, -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatPower(makeSlice(invalid), 3, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatPower(makeSlice(float1), -2, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 2, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + + { + auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 81, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 2, 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == + HostFunctionError::FLOAT_COMPUTATION_ERROR); + } + + { + auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 0, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == float1); + } + + { + auto const result = hfs.floatPower(makeSlice(floatMaxIOU), 1, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxIOU); + } + + { + auto const x = hfs.floatSet(100, 0, 0); // 100 + if (BEAST_EXPECT(x)) + { + auto const result = hfs.floatPower(makeSlice(float10), 2, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == *x); + } + } + + { + auto const x = hfs.floatSet(1, -1, 0); // 0.1 + auto const y = hfs.floatSet(1, -2, 0); // 0.01 + if (BEAST_EXPECT(x && y)) + { + auto const result = hfs.floatPower(makeSlice(*x), 2, 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == *y); + } + } + } + + void + testFloatLog() + { + testcase("floatLog"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + { + auto const result = hfs.floatLog(Slice(), -1); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = hfs.floatLog(makeSlice(invalid), 0); + BEAST_EXPECT(!result) && + BEAST_EXPECT( + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + // perf test logs + // { + // auto const result = hfs.floatLog(makeSlice(floatPi), 0); + // if (BEAST_EXPECT(result)) + // { + // std::cout << "lg(" << floatToString(makeSlice(floatPi)) + // << ") = " << floatToString(makeSlice(*result)) + // << std::endl; + // } + // } + // { + // auto const result = hfs.floatLog(makeSlice(floatIntMax), 0); + // if (BEAST_EXPECT(result)) + // { + // std::cout << "lg(" << floatToString(makeSlice(floatIntMax)) + // << ") = " << floatToString(makeSlice(*result)) + // << std::endl; + // } + // } + + // { + // auto const result = hfs.floatLog(makeSlice(floatMaxExp), 0); + // if (BEAST_EXPECT(result)) + // { + // std::cout << "lg(" << floatToString(makeSlice(floatMaxExp)) + // << ") = " << floatToString(makeSlice(*result)) + // << std::endl; + // } + // } + + // { + // auto const result = hfs.floatLog(makeSlice(floatMaxIOU), 0); + // if (BEAST_EXPECT(result)) + // { + // std::cout << "lg(" << floatToString(makeSlice(floatMaxIOU)) + // << ") = " << floatToString(makeSlice(*result)) + // << std::endl; + // } + // } + + { + auto const x = + hfs.floatSet(9'500'000'000'000'001, -14, 0); // almost 80+15 + if (BEAST_EXPECT(x)) + { + auto const result = hfs.floatLog(makeSlice(floatMaxExp), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == *x); + } + } + + { + auto const x = hfs.floatSet(100, 0, 0); // 100 + if (BEAST_EXPECT(x)) + { + auto const result = hfs.floatLog(makeSlice(*x), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == float2); + } + } + + { + auto const x = hfs.floatSet(1000, 0, 0); // 1000 + auto const y = hfs.floatSet(3, 0, 0); // 0.1 + if (BEAST_EXPECT(x && y)) + { + auto const result = hfs.floatLog(makeSlice(*x), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == *y); + } + } + + { + auto const x = hfs.floatSet(1, -2, 0); // 0.01 + auto const y = + hfs.floatSet(-1999999993734431, -15, 0); // almost -2 + if (BEAST_EXPECT(x && y)) + { + auto const result = hfs.floatLog(makeSlice(*x), 0); + BEAST_EXPECT(result) && BEAST_EXPECT(*result == *y); + } + } + } + + void + testFloatNonIOU() + { + testcase("float Xrp+Mpt"); + using namespace test::jtx; + + Env env{*this}; + OpenView ov{*env.current()}; + ApplyContext ac = createApplyContext(env, ov); + auto const dummyEscrow = + keylet::escrow(env.master, env.seq(env.master)); + WasmHostFunctionsImpl hfs(ac, dummyEscrow); + + auto const y = hfs.floatSet(20, 0, 0); + if (!BEAST_EXPECT(y)) + return; + + Bytes x(8); + + // XRP + memset(x.data(), 0, x.size()); + x[0] = 0x40; + x[7] = 10; + + { + auto const result = + hfs.floatCompare(makeSlice(x), makeSlice(float10)); + BEAST_EXPECT( + !result && + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatAdd(makeSlice(float10), makeSlice(x), 0); + BEAST_EXPECT( + !result && + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + // MPT + memset(x.data(), 0, x.size()); + x[0] = 0x60; + x[7] = 10; + + { + auto const result = + hfs.floatCompare(makeSlice(x), makeSlice(float10)); + BEAST_EXPECT( + !result && + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + + { + auto const result = + hfs.floatAdd(makeSlice(float10), makeSlice(x), 0); + BEAST_EXPECT( + !result && + result.error() == HostFunctionError::FLOAT_INPUT_MALFORMED); + } + } + + void + testFloats() + { + testFloatTrace(); + testFloatFromInt(); + testFloatFromUint(); + testFloatSet(); + testFloatCompare(); + testFloatAdd(); + testFloatSubtract(); + testFloatMultiply(); + testFloatDivide(); + testFloatRoot(); + testFloatPower(); + testFloatLog(); + testFloatNonIOU(); + } + + void + run() override + { + testGetLedgerSqn(); + testGetParentLedgerTime(); + testGetParentLedgerHash(); + testGetBaseFee(); + testIsAmendmentEnabled(); + testCacheLedgerObj(); + testGetTxField(); + testGetCurrentLedgerObjField(); + testGetLedgerObjField(); + testGetTxNestedField(); + testGetCurrentLedgerObjNestedField(); + testGetLedgerObjNestedField(); + testGetTxArrayLen(); + testGetCurrentLedgerObjArrayLen(); + testGetLedgerObjArrayLen(); + testGetTxNestedArrayLen(); + testGetCurrentLedgerObjNestedArrayLen(); + testGetLedgerObjNestedArrayLen(); + testUpdateData(); + testCheckSignature(); + testComputeSha512HalfHash(); + testKeyletFunctions(); + testGetNFT(); + testGetNFTIssuer(); + testGetNFTTaxon(); + testGetNFTFlags(); + testGetNFTTransferFee(); + testGetNFTSerial(); + testTrace(); + testTraceNum(); + testTraceAccount(); + testTraceAmount(); + testFloats(); + } +}; + +BEAST_DEFINE_TESTSUITE(HostFuncImpl, app, ripple); + +} // namespace test +} // namespace ripple diff --git a/src/test/app/TestHostFunctions.h b/src/test/app/TestHostFunctions.h new file mode 100644 index 00000000000..11d613bc8dc --- /dev/null +++ b/src/test/app/TestHostFunctions.h @@ -0,0 +1,1360 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#include +#include + +#include +#include +#include +#include + +#include + +namespace ripple { + +namespace test { + +struct TestLedgerDataProvider : public HostFunctions +{ + jtx::Env* env_; + void const* rt_ = nullptr; + +public: + TestLedgerDataProvider(jtx::Env* env) : env_(env) + { + } + + virtual void + setRT(void const* rt) override + { + rt_ = rt; + } + + virtual void const* + getRT() const override + { + return rt_; + } + + Expected + getLedgerSqn() override + { + return env_->current()->seq(); + } +}; + +struct TestHostFunctions : public HostFunctions +{ + test::jtx::Env& env_; + AccountID accountID_; + Bytes data_; + int clock_drift_ = 0; + void const* rt_ = nullptr; + +public: + TestHostFunctions(test::jtx::Env& env, int cd = 0) + : env_(env), clock_drift_(cd) + { + accountID_ = env_.master.id(); + std::string t = "10000"; + data_ = Bytes{t.begin(), t.end()}; + } + + virtual void + setRT(void const* rt) override + { + rt_ = rt; + } + + virtual void const* + getRT() const override + { + return rt_; + } + + beast::Journal + getJournal() override + { + return env_.journal; + } + + Expected + getLedgerSqn() override + { + return 12345; + } + + Expected + getParentLedgerTime() override + { + return 67890; + } + + Expected + getParentLedgerHash() override + { + return env_.current()->info().parentHash; + } + + Expected + getBaseFee() override + { + return 10; + } + + Expected + isAmendmentEnabled(uint256 const& amendmentId) override + { + return 1; + } + + Expected + isAmendmentEnabled(std::string_view const& amendmentName) override + { + return 1; + } + + virtual Expected + cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override + { + return 1; + } + + Expected + getTxField(SField const& fname) override + { + if (fname == sfAccount) + return Bytes(accountID_.begin(), accountID_.end()); + else if (fname == sfFee) + { + int64_t x = 235; + uint8_t const* p = reinterpret_cast(&x); + return Bytes{p, p + sizeof(x)}; + } + else if (fname == sfSequence) + { + auto const x = getLedgerSqn(); + if (!x) + return Unexpected(x.error()); + std::uint32_t const data = x.value(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return Bytes{b, e}; + } + return Bytes(); + } + + Expected + getCurrentLedgerObjField(SField const& fname) override + { + auto const& sn = fname.getName(); + if (sn == "Destination" || sn == "Account") + return Bytes(accountID_.begin(), accountID_.end()); + else if (sn == "Data") + return data_; + else if (sn == "FinishAfter") + { + auto t = + env_.current()->parentCloseTime().time_since_epoch().count(); + std::string s = std::to_string(t); + return Bytes{s.begin(), s.end()}; + } + + return Unexpected(HostFunctionError::INTERNAL); + } + + Expected + getLedgerObjField(int32_t cacheIdx, SField const& fname) override + { + if (fname == sfBalance) + { + int64_t x = 10'000; + uint8_t const* p = reinterpret_cast(&x); + return Bytes{p, p + sizeof(x)}; + } + else if (fname == sfAccount) + { + return Bytes(accountID_.begin(), accountID_.end()); + } + return data_; + } + + Expected + getTxNestedField(Slice const& locator) override + { + if (locator.size() == 4) + { + int32_t const* l = reinterpret_cast(locator.data()); + int32_t const sfield = l[0]; + if (sfield == sfAccount.fieldCode) + { + return Bytes(accountID_.begin(), accountID_.end()); + } + } + uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, + 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, + 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, + 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; + return Bytes(&a[0], &a[sizeof(a)]); + } + + Expected + getCurrentLedgerObjNestedField(Slice const& locator) override + { + if (locator.size() == 4) + { + int32_t const* l = reinterpret_cast(locator.data()); + int32_t const sfield = l[0]; + if (sfield == sfAccount.fieldCode) + { + return Bytes(accountID_.begin(), accountID_.end()); + } + } + uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, + 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, + 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, + 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; + return Bytes(&a[0], &a[sizeof(a)]); + } + + Expected + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override + { + if (locator.size() == 4) + { + int32_t const* l = reinterpret_cast(locator.data()); + int32_t const sfield = l[0]; + if (sfield == sfAccount.fieldCode) + { + return Bytes(accountID_.begin(), accountID_.end()); + } + } + uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, + 0xbf, 0x49, 0xd2, 0x45, 0x9f, 0xa4, 0xa0, 0x34, + 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, 0xfc, 0xee, + 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; + return Bytes(&a[0], &a[sizeof(a)]); + } + + Expected + getTxArrayLen(SField const& fname) override + { + return 32; + } + + Expected + getCurrentLedgerObjArrayLen(SField const& fname) override + { + return 32; + } + + Expected + getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override + { + return 32; + } + + Expected + getTxNestedArrayLen(Slice const& locator) override + { + return 32; + } + + Expected + getCurrentLedgerObjNestedArrayLen(Slice const& locator) override + { + return 32; + } + + Expected + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override + { + return 32; + } + + Expected + updateData(Slice const& data) override + { + return 0; + } + + Expected + checkSignature( + Slice const& message, + Slice const& signature, + Slice const& pubkey) override + { + return 1; + } + + Expected + computeSha512HalfHash(Slice const& data) override + { + return env_.current()->info().parentHash; + } + + Expected + accountKeylet(AccountID const& account) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::account(account); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + ammKeylet(Asset const& issue1, Asset const& issue2) override + { + if (issue1 == issue2) + return Unexpected(HostFunctionError::INVALID_PARAMS); + if (issue1.holds() || issue2.holds()) + return Unexpected(HostFunctionError::INVALID_PARAMS); + auto const keylet = keylet::amm(issue1, issue2); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + credentialKeylet( + AccountID const& subject, + AccountID const& issuer, + Slice const& credentialType) override + { + if (!subject || !issuer || credentialType.empty() || + credentialType.size() > maxCredentialTypeLength) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::credential(subject, issuer, credentialType); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + escrowKeylet(AccountID const& account, std::uint32_t seq) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::escrow(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + oracleKeylet(AccountID const& account, std::uint32_t documentId) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::oracle(account, documentId); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + getNFT(AccountID const& account, uint256 const& nftId) override + { + if (!account || !nftId) + { + return Unexpected(HostFunctionError::INVALID_PARAMS); + } + + std::string s = "https://ripple.com"; + return Bytes(s.begin(), s.end()); + } + + Expected + getNFTIssuer(uint256 const& nftId) override + { + return Bytes(accountID_.begin(), accountID_.end()); + } + + Expected + getNFTTaxon(uint256 const& nftId) override + { + return 4; + } + + Expected + getNFTFlags(uint256 const& nftId) override + { + return 8; + } + + Expected + getNFTTransferFee(uint256 const& nftId) override + { + return 10; + } + + Expected + getNFTSerial(uint256 const& nftId) override + { + return 4; + } + + Expected + trace(std::string_view const& msg, Slice const& data, bool asHex) override + { +#ifdef DEBUG_OUTPUT + auto& j = std::cerr; +#else + auto j = getJournal().trace(); +#endif + if (!asHex) + { + j << "WAMR TRACE: " << msg << " " + << std::string_view( + reinterpret_cast(data.data()), data.size()); + } + else + { + std::string hex; + hex.reserve(data.size() * 2); + boost::algorithm::hex( + data.begin(), data.end(), std::back_inserter(hex)); + j << "WAMR DEV TRACE: " << msg << " " << hex; + } + +#ifdef DEBUG_OUTPUT + j << std::endl; +#endif + + return msg.size() + data.size() * (asHex ? 2 : 1); + } + + Expected + traceNum(std::string_view const& msg, int64_t data) override + { +#ifdef DEBUG_OUTPUT + auto& j = std::cerr; +#else + auto j = getJournal().trace(); +#endif + j << "WAMR TRACE NUM: " << msg << " " << data; + +#ifdef DEBUG_OUTPUT + j << std::endl; +#endif + return msg.size() + sizeof(data); + } + + Expected + traceAccount(std::string_view const& msg, AccountID const& account) override + { +#ifdef DEBUG_OUTPUT + auto j = getJournal().error(); +#else + auto j = getJournal().trace(); +#endif + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + + auto const accountStr = toBase58(account); + + j << "WAMR TRACE ACCOUNT: " << msg << " " << accountStr; + return msg.size() + accountStr.size(); + } + + Expected + traceFloat(std::string_view const& msg, Slice const& data) override + { +#ifdef DEBUG_OUTPUT + auto& j = std::cerr; +#else + auto j = getJournal().trace(); +#endif + auto const s = floatToString(data); + j << "WAMR TRACE FLOAT: " << msg << " " << s; + +#ifdef DEBUG_OUTPUT + j << std::endl; +#endif + return msg.size() + s.size(); + } + + Expected + traceAmount(std::string_view const& msg, STAmount const& amount) override + { +#ifdef DEBUG_OUTPUT + auto j = getJournal().error(); +#else + auto j = getJournal().trace(); +#endif + auto const amountStr = amount.getFullText(); + j << "WAMR TRACE AMOUNT: " << msg << " " << amountStr; + return msg.size() + amountStr.size(); + } + + Expected + floatFromInt(int64_t x, int32_t mode) override + { + return floatFromIntImpl(x, mode); + } + + Expected + floatFromUint(uint64_t x, int32_t mode) override + { + return floatFromUintImpl(x, mode); + } + + Expected + floatSet(int64_t mantissa, int32_t exponent, int32_t mode) override + { + return floatSetImpl(mantissa, exponent, mode); + } + + Expected + floatCompare(Slice const& x, Slice const& y) override + { + return floatCompareImpl(x, y); + } + + Expected + floatAdd(Slice const& x, Slice const& y, int32_t mode) override + { + return floatAddImpl(x, y, mode); + } + + Expected + floatSubtract(Slice const& x, Slice const& y, int32_t mode) override + { + return floatSubtractImpl(x, y, mode); + } + + Expected + floatMultiply(Slice const& x, Slice const& y, int32_t mode) override + { + return floatMultiplyImpl(x, y, mode); + } + + Expected + floatDivide(Slice const& x, Slice const& y, int32_t mode) override + { + return floatDivideImpl(x, y, mode); + } + + Expected + floatRoot(Slice const& x, int32_t n, int32_t mode) override + { + return floatRootImpl(x, n, mode); + } + + Expected + floatPower(Slice const& x, int32_t n, int32_t mode) override + { + return floatPowerImpl(x, n, mode); + } + + Expected + floatLog(Slice const& x, int32_t mode) override + { + return floatLogImpl(x, mode); + } +}; + +struct TestHostFunctionsSink : public TestHostFunctions +{ + test::StreamSink sink_; + beast::Journal jlog_; + void const* rt_ = nullptr; + +public: + explicit TestHostFunctionsSink(test::jtx::Env& env, int cd = 0) + : TestHostFunctions(env, cd) + , sink_(beast::severities::kDebug) + , jlog_(sink_) + { + } + + test::StreamSink& + getSink() + { + return sink_; + } + + beast::Journal + getJournal() override + { + return jlog_; + } +}; + +struct PerfHostFunctions : public TestHostFunctions +{ + Keylet leKey; + std::shared_ptr currentLedgerObj = nullptr; + bool isLedgerObjCached = false; + + static int constexpr MAX_CACHE = 256; + std::array, MAX_CACHE> cache; + // std::optional data_; // deferred data update, not used in + // performance + std::shared_ptr tx_; + + void const* rt_ = nullptr; + + PerfHostFunctions( + test::jtx::Env& env, + Keylet const& k, + std::shared_ptr&& tx) + : TestHostFunctions(env), leKey(k), tx_(std::move(tx)) + { + } + + Expected + getLedgerSqn() override + { + auto seq = env_.current()->seq(); + if (seq > std::numeric_limits::max()) + return Unexpected(HostFunctionError::INTERNAL); // LCOV_EXCL_LINE + return static_cast(seq); + } + + Expected + getParentLedgerTime() override + { + auto time = + env_.current()->parentCloseTime().time_since_epoch().count(); + if (time > std::numeric_limits::max()) + return Unexpected(HostFunctionError::INTERNAL); + return static_cast(time); + } + + Expected + getParentLedgerHash() override + { + return env_.current()->info().parentHash; + } + + Expected + getBaseFee() override + { + auto fee = env_.current()->fees().base.drops(); + if (fee > std::numeric_limits::max()) + return Unexpected(HostFunctionError::INTERNAL); + return static_cast(fee); + } + + Expected + isAmendmentEnabled(uint256 const& amendmentId) override + { + return env_.current()->rules().enabled(amendmentId); + } + + Expected + isAmendmentEnabled(std::string_view const& amendmentName) override + { + auto const& table = env_.app().getAmendmentTable(); + auto const amendment = table.find(std::string(amendmentName)); + return env_.current()->rules().enabled(amendment); + } + + Expected, HostFunctionError> + getCurrentLedgerObj() + { + if (!isLedgerObjCached) + { + isLedgerObjCached = true; + currentLedgerObj = env_.le(leKey); + } + if (currentLedgerObj) + return currentLedgerObj; + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + } + + Expected, HostFunctionError> + peekCurrentLedgerObj(int32_t cacheIdx) + { + --cacheIdx; + if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + + if (!cache[cacheIdx]) + { // return Unexpected(HostFunctionError::INVALID_SLOT); + auto const r = getCurrentLedgerObj(); + if (!r) + return Unexpected(r.error()); + cache[cacheIdx] = *r; + } + + return cache[cacheIdx]; + } + + Expected + normalizeCacheIndex(int32_t cacheIdx) + { + --cacheIdx; + if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + if (!cache[cacheIdx]) + return Unexpected(HostFunctionError::EMPTY_SLOT); + return cacheIdx; + } + + virtual Expected + cacheLedgerObj(uint256 const&, int32_t cacheIdx) override + { + // auto const& keylet = keylet::unchecked(objId); + + static int32_t intIdx = 0; + + if (cacheIdx < 0 || cacheIdx > MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + + if (!cacheIdx) + { + for (cacheIdx = 0; cacheIdx < MAX_CACHE; ++cacheIdx) + if (!cache[cacheIdx]) + break; + if (cacheIdx >= MAX_CACHE) + cacheIdx = intIdx++ % MAX_CACHE; + } + else + --cacheIdx; + + if (cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOTS_FULL); + + cache[cacheIdx] = env_.le(leKey); + if (!cache[cacheIdx]) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + return cacheIdx + 1; + } + + static Expected + getAnyFieldData(STBase const* obj) + { + // auto const& fname = obj.getFName(); + if (!obj) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + auto const stype = obj->getSType(); + switch (stype) + { + // LCOV_EXCL_START + case STI_UNKNOWN: + case STI_NOTPRESENT: + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + break; + // LCOV_EXCL_STOP + case STI_OBJECT: + case STI_ARRAY: + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); + break; + case STI_ACCOUNT: { + auto const* account(static_cast(obj)); + auto const& data = account->value(); + return Bytes{data.begin(), data.end()}; + } + break; + case STI_AMOUNT: + // will be processed by serializer + break; + case STI_ISSUE: { + auto const* issue(static_cast(obj)); + Asset const& asset(issue->value()); + // XRP and IOU will be processed by serializer + if (asset.holds()) + { + // MPT + auto const& mptIssue = asset.get(); + auto const& mptID = mptIssue.getMptID(); + return Bytes{mptID.cbegin(), mptID.cend()}; + } + } + break; + case STI_VL: { + auto const* vl(static_cast(obj)); + auto const& data = vl->value(); + return Bytes{data.begin(), data.end()}; + } + break; + case STI_UINT16: { + auto const& num( + static_cast const*>(obj)); + std::uint16_t const data = num->value(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return Bytes{b, e}; + } + case STI_UINT32: { + auto const* num( + static_cast const*>(obj)); + std::uint32_t const data = num->value(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return Bytes{b, e}; + } + break; + default: + break; // default to serializer + } + + Serializer msg; + obj->add(msg); + auto const data = msg.getData(); + + return data; + } + + Expected + getTxField(SField const& fname) override + { + return getAnyFieldData(tx_->peekAtPField(fname)); + } + + Expected + getCurrentLedgerObjField(SField const& fname) override + { + auto const sle = getCurrentLedgerObj(); + if (!sle) + return Unexpected(sle.error()); + return getAnyFieldData((*sle)->peekAtPField(fname)); + } + + Expected + getLedgerObjField(int32_t cacheIdx, SField const& fname) override + { + auto const sle = peekCurrentLedgerObj(cacheIdx); + if (!sle) + return Unexpected(sle.error()); + return getAnyFieldData((*sle)->peekAtPField(fname)); + } + + static inline bool + noField(STBase const* field) + { + return !field || (STI_NOTPRESENT == field->getSType()) || + (STI_UNKNOWN == field->getSType()); + } + + static Expected + locateField(STObject const& obj, Slice const& locator) + { + if (locator.empty() || (locator.size() & 3)) // must be multiple of 4 + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + + int32_t const* locPtr = + reinterpret_cast(locator.data()); + int32_t const locSize = locator.size() / 4; + STBase const* field = nullptr; + auto const& knownSFields = SField::getKnownCodeToField(); + + { + int32_t const sfieldCode = locPtr[0]; + auto const it = knownSFields.find(sfieldCode); + if (it == knownSFields.end()) + return Unexpected(HostFunctionError::INVALID_FIELD); + + auto const& fname(*it->second); + field = obj.peekAtPField(fname); + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + } + + for (int i = 1; i < locSize; ++i) + { + int32_t const sfieldCode = locPtr[i]; + + if (STI_ARRAY == field->getSType()) + { + auto const* arr = static_cast(field); + if (sfieldCode >= arr->size()) + return Unexpected(HostFunctionError::INDEX_OUT_OF_BOUNDS); + field = &(arr->operator[](sfieldCode)); + } + else if (STI_OBJECT == field->getSType()) + { + auto const* o = static_cast(field); + + auto const it = knownSFields.find(sfieldCode); + if (it == knownSFields.end()) + return Unexpected(HostFunctionError::INVALID_FIELD); + + auto const& fname(*it->second); + field = o->peekAtPField(fname); + } + else // simple field must be the last one + { + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + } + + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + } + + return field; + } + + Expected + getTxNestedField(Slice const& locator) override + { + // std::cout << tx_->getJson(JsonOptions::none).toStyledString() << + // std::endl; + auto const r = locateField(*tx_, locator); + if (!r) + return Unexpected(r.error()); + return getAnyFieldData(*r); + } + + Expected + getCurrentLedgerObjNestedField(Slice const& locator) override + { + auto const sle = getCurrentLedgerObj(); + if (!sle) + return Unexpected(sle.error()); + + auto const r = locateField(**sle, locator); + if (!r) + return Unexpected(r.error()); + + return getAnyFieldData(*r); + } + + Expected + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override + { + auto const sle = peekCurrentLedgerObj(cacheIdx); + if (!sle) + return Unexpected(sle.error()); + + auto const r = locateField(**sle, locator); + if (!r) + return Unexpected(r.error()); + + return getAnyFieldData(*r); + } + + Expected + getTxArrayLen(SField const& fname) override + { + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + auto const* field = tx_->peekAtPField(fname); + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getCurrentLedgerObjArrayLen(SField const& fname) override + { + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + auto const sle = getCurrentLedgerObj(); + if (!sle) + return Unexpected(sle.error()); + + auto const* field = (*sle)->peekAtPField(fname); + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override + { + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + auto const sle = peekCurrentLedgerObj(cacheIdx); + if (!sle) + return Unexpected(sle.error()); + + auto const* field = (*sle)->peekAtPField(fname); + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getTxNestedArrayLen(Slice const& locator) override + { + auto const r = locateField(*tx_, locator); + if (!r) + return Unexpected(r.error()); + auto const* field = r.value(); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getCurrentLedgerObjNestedArrayLen(Slice const& locator) override + { + auto const sle = getCurrentLedgerObj(); + if (!sle) + return Unexpected(sle.error()); + + auto const r = locateField(**sle, locator); + if (!r) + return Unexpected(r.error()); + auto const* field = r.value(); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override + { + auto const sle = peekCurrentLedgerObj(cacheIdx); + if (!sle) + return Unexpected(sle.error()); + + auto const r = locateField(**sle, locator); + if (!r) + return Unexpected(r.error()); + + auto const* field = r.value(); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; + } + + Expected + updateData(Slice const& data) override + { + if (data.size() > maxWasmDataLength) + return Unexpected(HostFunctionError::DATA_FIELD_TOO_LARGE); + + ripple::detail::ApplyViewBase v( + env_.app().openLedger().current().get(), tapNONE); + + auto sle = v.peek(leKey); + if (!sle) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + + sle->setFieldVL(sfData, data); + v.update(sle); + + return data.size(); + } + + Expected + checkSignature( + Slice const& message, + Slice const& signature, + Slice const& pubkey) override + { + if (!publicKeyType(pubkey)) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + PublicKey const pk(pubkey); + return verify(pk, message, signature, /*canonical*/ true); + } + + Expected + computeSha512HalfHash(Slice const& data) override + { + auto const hash = sha512Half(data); + return hash; + } + + Expected + accountKeylet(AccountID const& account) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::account(account); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + ammKeylet(Asset const& issue1, Asset const& issue2) override + { + if (issue1 == issue2) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + // note: this should be removed with the MPT DEX amendment + if (issue1.holds() || issue2.holds()) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + auto const keylet = keylet::amm(issue1, issue2); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + checkKeylet(AccountID const& account, std::uint32_t seq) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::check(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + credentialKeylet( + AccountID const& subject, + AccountID const& issuer, + Slice const& credentialType) override + { + if (!subject || !issuer) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + + if (credentialType.empty() || + credentialType.size() > maxCredentialTypeLength) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + auto const keylet = keylet::credential(subject, issuer, credentialType); + + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + didKeylet(AccountID const& account) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::did(account); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + delegateKeylet(AccountID const& account, AccountID const& authorize) + override + { + if (!account || !authorize) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + if (account == authorize) + return Unexpected(HostFunctionError::INVALID_PARAMS); + auto const keylet = keylet::delegate(account, authorize); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + depositPreauthKeylet(AccountID const& account, AccountID const& authorize) + override + { + if (!account || !authorize) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + if (account == authorize) + return Unexpected(HostFunctionError::INVALID_PARAMS); + auto const keylet = keylet::depositPreauth(account, authorize); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + escrowKeylet(AccountID const& account, std::uint32_t seq) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::escrow(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + lineKeylet( + AccountID const& account1, + AccountID const& account2, + Currency const& currency) override + { + if (!account1 || !account2) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + if (account1 == account2) + return Unexpected(HostFunctionError::INVALID_PARAMS); + if (currency.isZero()) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + auto const keylet = keylet::line(account1, account2, currency); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) override + { + if (!issuer) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + + auto const keylet = keylet::mptIssuance(seq, issuer); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + mptokenKeylet(MPTID const& mptid, AccountID const& holder) override + { + if (!mptid) + return Unexpected(HostFunctionError::INVALID_PARAMS); + if (!holder) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + + auto const keylet = keylet::mptoken(mptid, holder); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + nftOfferKeylet(AccountID const& account, std::uint32_t seq) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::nftoffer(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + offerKeylet(AccountID const& account, std::uint32_t seq) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::offer(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + oracleKeylet(AccountID const& account, std::uint32_t documentId) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::oracle(account, documentId); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + paychanKeylet( + AccountID const& account, + AccountID const& destination, + std::uint32_t seq) override + { + if (!account || !destination) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + if (account == destination) + return Unexpected(HostFunctionError::INVALID_PARAMS); + auto const keylet = keylet::payChan(account, destination, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) + override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::permissionedDomain(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + signersKeylet(AccountID const& account) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::signers(account); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + ticketKeylet(AccountID const& account, std::uint32_t seq) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::ticket(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + vaultKeylet(AccountID const& account, std::uint32_t seq) override + { + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::vault(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; + } + + Expected + getNFT(AccountID const& account, uint256 const& nftId) override + { + if (!account || !nftId) + { + getJournal().trace() << "WAMR getNFT: Invalid account or NFT ID"; + return Unexpected(HostFunctionError::INVALID_PARAMS); + } + + auto obj = nft::findToken(*env_.current(), account, nftId); + if (!obj) + { + getJournal().trace() << "WAMR getNFT: NFT not found"; + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + } + + auto ouri = obj->at(~sfURI); + if (!ouri) + return Bytes(); + + Slice const s = ouri->value(); + return Bytes(s.begin(), s.end()); + } + + Expected + getNFTIssuer(uint256 const& nftId) override + { + auto const issuer = nft::getIssuer(nftId); + if (!issuer) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + return Bytes{issuer.begin(), issuer.end()}; + } + + Expected + getNFTTaxon(uint256 const& nftId) override + { + return nft::toUInt32(nft::getTaxon(nftId)); + } + + Expected + getNFTFlags(uint256 const& nftId) override + { + return nft::getFlags(nftId); + } + + Expected + getNFTTransferFee(uint256 const& nftId) override + { + return nft::getTransferFee(nftId); + } + + Expected + getNFTSerial(uint256 const& nftId) override + { + return nft::getSerial(nftId); + } +}; + +} // namespace test +} // namespace ripple diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp new file mode 100644 index 00000000000..00909bcbe3e --- /dev/null +++ b/src/test/app/Wasm_test.cpp @@ -0,0 +1,730 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#ifdef _DEBUG +// #define DEBUG_OUTPUT 1 +#endif + +#include + +#include +#include + +namespace ripple { +namespace test { + +bool +testGetDataIncrement(); + +using Add_proto = int32_t(int32_t, int32_t); +static wasm_trap_t* +Add(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + int32_t Val1 = params->data[0].of.i32; + int32_t Val2 = params->data[1].of.i32; + // printf("Host function \"Add\": %d + %d\n", Val1, Val2); + results->data[0] = WASM_I32_VAL(Val1 + Val2); + return nullptr; +} + +struct Wasm_test : public beast::unit_test::suite +{ + void + testGetDataHelperFunctions() + { + testcase("getData helper functions"); + BEAST_EXPECT(testGetDataIncrement()); + } + + void + testWasmLib() + { + testcase("wasmtime lib test"); + // clang-format off + /* The WASM module buffer. */ + Bytes const wasm = {/* WASM header */ + 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, + /* Type section */ + 0x01, 0x07, 0x01, + /* function type {i32, i32} -> {i32} */ + 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, + /* Import section */ + 0x02, 0x13, 0x01, + /* module name: "extern" */ + 0x06, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6E, + /* extern name: "func-add" */ + 0x08, 0x66, 0x75, 0x6E, 0x63, 0x2D, 0x61, 0x64, 0x64, + /* import desc: func 0 */ + 0x00, 0x00, + /* Function section */ + 0x03, 0x02, 0x01, 0x00, + /* Export section */ + 0x07, 0x0A, 0x01, + /* export name: "addTwo" */ + 0x06, 0x61, 0x64, 0x64, 0x54, 0x77, 0x6F, + /* export desc: func 0 */ + 0x00, 0x01, + /* Code section */ + 0x0A, 0x0A, 0x01, + /* code body */ + 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0B}; + // clang-format on + auto& vm = WasmEngine::instance(); + + std::vector imports; + WasmImpFunc( + imports, "func-add", reinterpret_cast(&Add)); + + auto re = vm.run(wasm, "addTwo", wasmParams(1234, 5678), imports); + + // if (res) printf("invokeAdd get the result: %d\n", res.value()); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 6'912, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 2, std::to_string(re->cost)); + } + } + + void + testBadWasm() + { + testcase("bad wasm test"); + + using namespace test::jtx; + + Env env{*this}; + HostFunctions hfs; + + { + auto wasmHex = "00000000"; + auto wasmStr = boost::algorithm::unhex(std::string(wasmHex)); + std::vector wasm(wasmStr.begin(), wasmStr.end()); + std::string funcName("mock_escrow"); + + auto re = runEscrowWasm(wasm, funcName, {}, &hfs, 15, env.journal); + BEAST_EXPECT(!re); + } + + { + auto wasmHex = "00112233445566778899AA"; + auto wasmStr = boost::algorithm::unhex(std::string(wasmHex)); + std::vector wasm(wasmStr.begin(), wasmStr.end()); + std::string funcName("mock_escrow"); + + auto const re = + preflightEscrowWasm(wasm, funcName, {}, &hfs, env.journal); + BEAST_EXPECT(!isTesSuccess(re)); + } + + { + // FinishFunction wrong function name + // pub fn bad() -> bool { + // unsafe { host_lib::getLedgerSqn() >= 5 } + // } + auto const badWasmHex = + "0061736d010000000105016000017f02190108686f73745f6c69620c6765" + "744c656467657253716e00000302010005030100100611027f00418080c0" + "000b7f00418080c0000b072b04066d656d6f727902000362616400010a5f" + "5f646174615f656e6403000b5f5f686561705f6261736503010a09010700" + "100041044a0b004d0970726f64756365727302086c616e67756167650104" + "52757374000c70726f6365737365642d6279010572757374631d312e3835" + "2e31202834656231363132353020323032352d30332d31352900490f7461" + "726765745f6665617475726573042b0f6d757461626c652d676c6f62616c" + "732b087369676e2d6578742b0f7265666572656e63652d74797065732b0a" + "6d756c746976616c7565"; + auto wasmStr = boost::algorithm::unhex(std::string(badWasmHex)); + std::vector wasm(wasmStr.begin(), wasmStr.end()); + + auto const re = preflightEscrowWasm( + wasm, ESCROW_FUNCTION_NAME, {}, &hfs, env.journal); + BEAST_EXPECT(!isTesSuccess(re)); + } + } + + void + testWasmLedgerSqn() + { + testcase("Wasm get ledger sequence"); + + auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex); + Bytes wasm(wasmStr.begin(), wasmStr.end()); + + using namespace test::jtx; + + Env env{*this}; + TestLedgerDataProvider hf(&env); + + std::vector imports; + WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hf, 33); + auto& engine = WasmEngine::instance(); + + auto re = engine.run( + wasm, + ESCROW_FUNCTION_NAME, + {}, + imports, + &hf, + 1'000'000, + env.journal); + + // code takes 11 gas + 1 getLedgerSqn call + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 0, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 39, std::to_string(re->cost)); + } + + env.close(); + env.close(); + + // empty module - run the same instance + re = engine.run( + {}, ESCROW_FUNCTION_NAME, {}, imports, &hf, 1'000'000, env.journal); + + // code takes 22 gas + 2 getLedgerSqn calls + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 5, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 78, std::to_string(re->cost)); + } + } + + void + testWasmFib() + { + testcase("Wasm fibo"); + + auto const ws = boost::algorithm::unhex(fibWasmHex); + Bytes const wasm(ws.begin(), ws.end()); + auto& engine = WasmEngine::instance(); + + auto const re = engine.run(wasm, "fib", wasmParams(10)); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 55, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 755, std::to_string(re->cost)); + } + } + + void + testWasmSha() + { + testcase("Wasm sha"); + + auto const ws = boost::algorithm::unhex(sha512PureWasmHex); + Bytes const wasm(ws.begin(), ws.end()); + auto& engine = WasmEngine::instance(); + + auto const re = + engine.run(wasm, "sha512_process", wasmParams(sha512PureWasmHex)); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 34'432, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 157'452, std::to_string(re->cost)); + } + } + + void + testWasmB58() + { + testcase("Wasm base58"); + auto const ws = boost::algorithm::unhex(b58WasmHex); + Bytes const wasm(ws.begin(), ws.end()); + auto& engine = WasmEngine::instance(); + + Bytes outb; + outb.resize(1024); + + auto const minsz = std::min( + static_cast(512), + static_cast(b58WasmHex.size())); + auto const s = std::string_view(b58WasmHex.c_str(), minsz); + + auto const re = engine.run(wasm, "b58enco", wasmParams(outb, s)); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 700, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 3'066'129, std::to_string(re->cost)); + } + } + + void + testWasmSP1Verifier() + { + testcase("Wasm sp1 zkproof verifier"); + auto const ws = boost::algorithm::unhex(sp1WasmHex); + Bytes const wasm(ws.begin(), ws.end()); + auto& engine = WasmEngine::instance(); + + auto const re = engine.run(wasm, "sp1_groth16_verifier"); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); + BEAST_EXPECTS( + re->cost == 4'191'711'969ll, std::to_string(re->cost)); + } + } + + void + testWasmBG16Verifier() + { + testcase("Wasm BG16 zkproof verifier"); + auto const ws = boost::algorithm::unhex(zkProofWasmHex); + Bytes const wasm(ws.begin(), ws.end()); + auto& engine = WasmEngine::instance(); + + auto const re = engine.run(wasm, "bellman_groth16_test"); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 332'205'984, std::to_string(re->cost)); + } + } + + void + testHFCost() + { + testcase("wasm test host functions cost"); + + using namespace test::jtx; + + Env env(*this); + { + std::string const wasmHex = allHostFunctionsWasmHex; + std::string const wasmStr = boost::algorithm::unhex(wasmHex); + std::vector const wasm(wasmStr.begin(), wasmStr.end()); + + auto& engine = WasmEngine::instance(); + + TestHostFunctions hfs(env, 0); + std::vector imp = createWasmImport(&hfs); + for (auto& i : imp) + i.gas = 0; + + auto re = engine.run( + wasm, + ESCROW_FUNCTION_NAME, + {}, + imp, + &hfs, + 1'000'000, + env.journal); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 847, std::to_string(re->cost)); + } + + env.close(); + } + + env.close(); + env.close(); + env.close(); + env.close(); + env.close(); + + { + std::string const wasmHex = allHostFunctionsWasmHex; + std::string const wasmStr = boost::algorithm::unhex(wasmHex); + std::vector const wasm(wasmStr.begin(), wasmStr.end()); + + auto& engine = WasmEngine::instance(); + + TestHostFunctions hfs(env, 0); + std::vector const imp = createWasmImport(&hfs); + + auto re = engine.run( + wasm, + ESCROW_FUNCTION_NAME, + {}, + imp, + &hfs, + 1'000'000, + env.journal); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 40'107, std::to_string(re->cost)); + } + + env.close(); + } + } + + void + testEscrowWasmDN() + { + testcase("escrow wasm devnet test"); + + std::string const wasmStr = + boost::algorithm::unhex(allHostFunctionsWasmHex); + std::vector wasm(wasmStr.begin(), wasmStr.end()); + + using namespace test::jtx; + Env env{*this}; + { + TestHostFunctions nfs(env, 0); + auto re = + runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000); + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 40'107, std::to_string(re->cost)); + } + } + + { // fail because trying to access nonexistent field + struct BadTestHostFunctions : public TestHostFunctions + { + explicit BadTestHostFunctions(Env& env) : TestHostFunctions(env) + { + } + Expected + getTxField(SField const& fname) override + { + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + } + }; + BadTestHostFunctions nfs(env); + auto re = + runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000); + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == -201, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 4'806, std::to_string(re->cost)); + } + } + + { // fail because trying to allocate more than MAX_PAGES memory + struct BadTestHostFunctions : public TestHostFunctions + { + explicit BadTestHostFunctions(Env& env) : TestHostFunctions(env) + { + } + Expected + getTxField(SField const& fname) override + { + return Bytes((MAX_PAGES + 1) * 64 * 1024, 1); + } + }; + BadTestHostFunctions nfs(env); + auto re = + runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000); + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == -201, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 4'806, std::to_string(re->cost)); + } + } + + { // fail because recursion too deep + + auto const wasmStr = boost::algorithm::unhex(deepRecursionHex); + std::vector wasm(wasmStr.begin(), wasmStr.end()); + + TestHostFunctionsSink nfs(env); + std::string funcName("recursive"); + auto re = runEscrowWasm(wasm, funcName, {}, &nfs, 1'000'000'000); + BEAST_EXPECT(!re && re.error()); + // std::cout << "bad case (deep recursion) result " << re.error() + // << std::endl; + + auto const& sink = nfs.getSink(); + auto countSubstr = [](std::string const& str, + std::string const& substr) { + std::size_t pos = 0; + int occurrences = 0; + while ((pos = str.find(substr, pos)) != std::string::npos) + { + occurrences++; + pos += substr.length(); + } + return occurrences; + }; + + auto const s = sink.messages().str(); + BEAST_EXPECT( + countSubstr(s, "WAMR Error: failure to call func") == 1); + BEAST_EXPECT( + countSubstr(s, "Exception: wasm operand stack overflow") > 0); + } + + { + auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex); + Bytes wasm(wasmStr.begin(), wasmStr.end()); + TestLedgerDataProvider ledgerDataProvider(&env); + + std::vector imports; + WASM_IMPORT_FUNC2( + imports, getLedgerSqn, "get_ledger_sqn2", &ledgerDataProvider); + + auto& engine = WasmEngine::instance(); + + auto re = engine.run( + wasm, + ESCROW_FUNCTION_NAME, + {}, + imports, + nullptr, + 1'000'000, + env.journal); + + // expected import not provided + BEAST_EXPECT(!re); + } + } + + void + testFloat() + { + testcase("float point"); + + std::string const funcName("finish"); + + using namespace test::jtx; + + Env env(*this); + { + std::string const wasmHex = floatTestsWasmHex; + std::string const wasmStr = boost::algorithm::unhex(wasmHex); + std::vector const wasm(wasmStr.begin(), wasmStr.end()); + + TestHostFunctions hf(env, 0); + auto re = runEscrowWasm(wasm, funcName, {}, &hf, 100'000); + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 97'411, std::to_string(re->cost)); + } + env.close(); + } + + { + std::string const wasmHex = float0Hex; + std::string const wasmStr = boost::algorithm::unhex(wasmHex); + std::vector const wasm(wasmStr.begin(), wasmStr.end()); + + TestHostFunctions hf(env, 0); + auto re = runEscrowWasm(wasm, funcName, {}, &hf, 100'000); + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 2'053, std::to_string(re->cost)); + } + env.close(); + } + } + + void + perfTest() + { + testcase("Perf test host functions"); + + using namespace jtx; + using namespace std::chrono; + + // std::string const funcName("test"); + auto const& wasmHex = hfPerfTest; + std::string const wasmStr = boost::algorithm::unhex(wasmHex); + std::vector const wasm(wasmStr.begin(), wasmStr.end()); + + // std::string const credType = "abcde"; + // std::string const credType2 = "fghijk"; + // std::string const credType3 = "0123456"; + // char const uri[] = "uri"; + + Account const alan{"alan"}; + Account const bob{"bob"}; + Account const issuer{"issuer"}; + + { + Env env(*this); + // Env env(*this, envconfig(), {}, nullptr, + // beast::severities::kTrace); + env.fund(XRP(5000), alan, bob, issuer); + env.close(); + + // // create escrow + // auto const seq = env.seq(alan); + // auto const k = keylet::escrow(alan, seq); + // // auto const allowance = 3'600; + // auto escrowCreate = escrow::create(alan, bob, XRP(1000)); + // XRPAmount txnFees = env.current()->fees().base + 1000; + // env(escrowCreate, + // escrow::finish_function(wasmHex), + // escrow::finish_time(env.now() + 11s), + // escrow::cancel_time(env.now() + 100s), + // escrow::data("1000000000"), // 1000 XRP in drops + // memodata("memo1234567"), + // memodata("2memo1234567"), + // fee(txnFees)); + + // // create depositPreauth + // auto const k = keylet::depositPreauth( + // bob, + // {{issuer.id(), makeSlice(credType)}, + // {issuer.id(), makeSlice(credType2)}, + // {issuer.id(), makeSlice(credType3)}}); + // env(deposit::authCredentials( + // bob, + // {{issuer, credType}, + // {issuer, credType2}, + // {issuer, credType3}})); + + // create nft + [[maybe_unused]] uint256 const nft0{ + token::getNextID(env, alan, 0u)}; + env(token::mint(alan, 0u)); + auto const k = keylet::nftoffer(alan, 0); + [[maybe_unused]] uint256 const nft1{ + token::getNextID(env, alan, 0u)}; + + env(token::mint(alan, 0u), + token::uri( + "https://github.com/XRPLF/XRPL-Standards/discussions/" + "279?id=github.com/XRPLF/XRPL-Standards/discussions/" + "279&ut=github.com/XRPLF/XRPL-Standards/discussions/" + "279&sid=github.com/XRPLF/XRPL-Standards/discussions/" + "279&aot=github.com/XRPLF/XRPL-Standards/disc")); + [[maybe_unused]] uint256 const nft2{ + token::getNextID(env, alan, 0u)}; + env(token::mint(alan, 0u)); + env.close(); + + PerfHostFunctions nfs(env, k, env.tx()); + + auto re = runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs); + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECT(re->result); + std::cout << "Res: " << re->result << " cost: " << re->cost + << std::endl; + } + + // env(escrow::finish(alan, alan, seq), + // escrow::comp_allowance(allowance), + // fee(txnFees), + // ter(tesSUCCESS)); + + env.close(); + } + } + + void + testCodecovWasm() + { + testcase("Codecov wasm test"); + + using namespace test::jtx; + + Env env{*this}; + + auto const wasmStr = boost::algorithm::unhex(codecovTestsWasmHex); + Bytes const wasm(wasmStr.begin(), wasmStr.end()); + TestHostFunctions hfs(env, 0); + + auto const allowance = 152'154; + auto re = runEscrowWasm( + wasm, ESCROW_FUNCTION_NAME, {}, &hfs, allowance, env.journal); + + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECT(re->result); + BEAST_EXPECTS(re->cost == allowance, std::to_string(re->cost)); + } + } + + void + testDisabledFloat() + { + testcase("disabled float"); + + using namespace test::jtx; + Env env{*this}; + + auto const wasmStr = boost::algorithm::unhex(disabledFloatHex); + Bytes wasm(wasmStr.begin(), wasmStr.end()); + std::string const funcName("finish"); + TestHostFunctions hfs(env, 0); + + { + // f32 set constant, opcode disabled exception + auto const re = + runEscrowWasm(wasm, funcName, {}, &hfs, 1'000'000, env.journal); + if (BEAST_EXPECT(!re.has_value())) + { + BEAST_EXPECT(re.error() == tecFAILED_PROCESSING); + } + } + + { + // f32 add, can't create module exception + wasm[0x117] = 0x92; + auto const re = + runEscrowWasm(wasm, funcName, {}, &hfs, 1'000'000, env.journal); + if (BEAST_EXPECT(!re.has_value())) + { + BEAST_EXPECT(re.error() == tecFAILED_PROCESSING); + } + } + } + + void + run() override + { + using namespace test::jtx; + + testGetDataHelperFunctions(); + testWasmLib(); + testBadWasm(); + testWasmLedgerSqn(); + + testWasmFib(); + testWasmSha(); + testWasmB58(); + + // running too long + // testWasmSP1Verifier(); + testWasmBG16Verifier(); + + testHFCost(); + + testEscrowWasmDN(); + testFloat(); + + testCodecovWasm(); + testDisabledFloat(); + + // perfTest(); + } +}; + +BEAST_DEFINE_TESTSUITE(Wasm, app, ripple); + +} // namespace test +} // namespace ripple diff --git a/src/test/app/wasm_fixtures/.gitignore b/src/test/app/wasm_fixtures/.gitignore new file mode 100644 index 00000000000..08b2e8a2569 --- /dev/null +++ b/src/test/app/wasm_fixtures/.gitignore @@ -0,0 +1,3 @@ +**/target +**/debug +*.wasm diff --git a/src/test/app/wasm_fixtures/all_host_functions/Cargo.lock b/src/test/app/wasm_fixtures/all_host_functions/Cargo.lock new file mode 100644 index 00000000000..7f6a6bc7175 --- /dev/null +++ b/src/test/app/wasm_fixtures/all_host_functions/Cargo.lock @@ -0,0 +1,15 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "all_host_functions" +version = "0.1.0" +dependencies = [ + "xrpl-std", +] + +[[package]] +name = "xrpl-std" +version = "0.5.1-devnet5" +source = "git+https://github.com/ripple/craft.git?branch=last-hfs2#ec4a3fb2ea45a7f27b7190976d37d3596e2ec29e" diff --git a/src/test/app/wasm_fixtures/all_host_functions/Cargo.toml b/src/test/app/wasm_fixtures/all_host_functions/Cargo.toml new file mode 100644 index 00000000000..959056f374e --- /dev/null +++ b/src/test/app/wasm_fixtures/all_host_functions/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "all_host_functions" +version = "0.1.0" +edition = "2024" + +# This empty workspace definition keeps this project independent of the parent workspace +[workspace] + +[lib] +crate-type = ["cdylib"] + +[dependencies] +xrpl-std = { git = "https://github.com/ripple/craft.git", branch = "last-hfs2", package = "xrpl-std" } + +[profile.dev] +panic = "abort" + +[profile.release] +panic = "abort" +opt-level = "z" +lto = true diff --git a/src/test/app/wasm_fixtures/all_host_functions/src/lib.rs b/src/test/app/wasm_fixtures/all_host_functions/src/lib.rs new file mode 100644 index 00000000000..c8a27aed876 --- /dev/null +++ b/src/test/app/wasm_fixtures/all_host_functions/src/lib.rs @@ -0,0 +1,772 @@ +#![cfg_attr(target_arch = "wasm32", no_std)] + +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +// +// Host Functions Test +// Tests 26 host functions (across 7 categories) +// +// With craft you can run this test with: +// craft test --project host_functions_test --test-case host_functions_test +// +// Amount Format Update: +// - XRP amounts now return as 8-byte serialized rippled objects +// - IOU and MPT amounts return in variable-length serialized format +// - Format details: https://xrpl.org/docs/references/protocol/binary-format#amount-fields +// +// Error Code Ranges: +// -100 to -199: Ledger Header Functions (3 functions) +// -200 to -299: Transaction Data Functions (5 functions) +// -300 to -399: Current Ledger Object Functions (4 functions) +// -400 to -499: Any Ledger Object Functions (5 functions) +// -500 to -599: Keylet Generation Functions (4 functions) +// -600 to -699: Utility Functions (4 functions) +// -700 to -799: Data Update Functions (1 function) +// + +use xrpl_std::core::current_tx::escrow_finish::EscrowFinish; +use xrpl_std::core::current_tx::traits::TransactionCommonFields; +use xrpl_std::host; +use xrpl_std::host::trace::{trace, trace_account_buf, trace_data, trace_num, DataRepr}; +use xrpl_std::sfield; + +#[unsafe(no_mangle)] +pub extern "C" fn finish() -> i32 { + let _ = trace("=== HOST FUNCTIONS TEST ==="); + let _ = trace("Testing 26 host functions"); + + // Category 1: Ledger Header Data Functions (3 functions) + // Error range: -100 to -199 + match test_ledger_header_functions() { + 0 => (), + err => return err, + } + + // Category 2: Transaction Data Functions (5 functions) + // Error range: -200 to -299 + match test_transaction_data_functions() { + 0 => (), + err => return err, + } + + // Category 3: Current Ledger Object Functions (4 functions) + // Error range: -300 to -399 + match test_current_ledger_object_functions() { + 0 => (), + err => return err, + } + + // Category 4: Any Ledger Object Functions (5 functions) + // Error range: -400 to -499 + match test_any_ledger_object_functions() { + 0 => (), + err => return err, + } + + // Category 5: Keylet Generation Functions (4 functions) + // Error range: -500 to -599 + match test_keylet_generation_functions() { + 0 => (), + err => return err, + } + + // Category 6: Utility Functions (4 functions) + // Error range: -600 to -699 + match test_utility_functions() { + 0 => (), + err => return err, + } + + // Category 7: Data Update Functions (1 function) + // Error range: -700 to -799 + match test_data_update_functions() { + 0 => (), + err => return err, + } + + let _ = trace("SUCCESS: All host function tests passed!"); + 1 // Success return code for WASM finish function +} + +/// Test Category 1: Ledger Header Data Functions (3 functions) +/// - get_ledger_sqn() - Get ledger sequence number +/// - get_parent_ledger_time() - Get parent ledger timestamp +/// - get_parent_ledger_hash() - Get parent ledger hash +fn test_ledger_header_functions() -> i32 { + let _ = trace("--- Category 1: Ledger Header Functions ---"); + + // Test 1.1: get_ledger_sqn() - should return current ledger sequence number + let sqn_result = unsafe { host::get_ledger_sqn() }; + + if sqn_result <= 0 { + let _ = trace_num("ERROR: get_ledger_sqn failed:", sqn_result as i64); + return -101; // Ledger sequence number test failed + } + let _ = trace_num("Ledger sequence number:", sqn_result as i64); + + // Test 1.2: get_parent_ledger_time() - should return parent ledger timestamp + let time_result = unsafe { host::get_parent_ledger_time() }; + + if time_result <= 0 { + let _ = trace_num("ERROR: get_parent_ledger_time failed:", time_result as i64); + return -102; // Parent ledger time test failed + } + let _ = trace_num("Parent ledger time:", time_result as i64); + + // Test 1.3: get_parent_ledger_hash() - should return parent ledger hash (32 bytes) + let mut hash_buffer = [0u8; 32]; + let hash_result = + unsafe { host::get_parent_ledger_hash(hash_buffer.as_mut_ptr(), hash_buffer.len()) }; + + if hash_result != 32 { + let _ = trace_num( + "ERROR: get_parent_ledger_hash wrong length:", + hash_result as i64, + ); + return -103; // Parent ledger hash test failed - should be exactly 32 bytes + } + let _ = trace_data("Parent ledger hash:", &hash_buffer, DataRepr::AsHex); + + let _ = trace("SUCCESS: Ledger header functions"); + 0 +} + +/// Test Category 2: Transaction Data Functions (5 functions) +/// Tests all functions for accessing current transaction data +fn test_transaction_data_functions() -> i32 { + let _ = trace("--- Category 2: Transaction Data Functions ---"); + + // Test 2.1: get_tx_field() - Basic transaction field access + // Test with Account field (required, 20 bytes) + let mut account_buffer = [0u8; 20]; + let account_len = unsafe { + host::get_tx_field( + sfield::Account, + account_buffer.as_mut_ptr(), + account_buffer.len(), + ) + }; + + if account_len != 20 { + let _ = trace_num( + "ERROR: get_tx_field(Account) wrong length:", + account_len as i64, + ); + return -201; // Basic transaction field test failed + } + let _ = trace_account_buf("Transaction Account:", &account_buffer); + + // Test with Fee field (XRP amount - 8 bytes in new serialized format) + // New format: XRP amounts are always 8 bytes (positive: value | cPositive flag, negative: just value) + let mut fee_buffer = [0u8; 8]; + let fee_len = + unsafe { host::get_tx_field(sfield::Fee, fee_buffer.as_mut_ptr(), fee_buffer.len()) }; + + if fee_len != 8 { + let _ = trace_num( + "ERROR: get_tx_field(Fee) wrong length (expected 8 bytes for XRP):", + fee_len as i64, + ); + return -202; // Fee field test failed - XRP amounts should be exactly 8 bytes + } + let _ = trace_num("Transaction Fee length:", fee_len as i64); + let _ = trace_data( + "Transaction Fee (serialized XRP amount):", + &fee_buffer, + DataRepr::AsHex, + ); + + // Test with Sequence field (required, 4 bytes uint32) + let mut seq_buffer = [0u8; 4]; + let seq_len = + unsafe { host::get_tx_field(sfield::Sequence, seq_buffer.as_mut_ptr(), seq_buffer.len()) }; + + if seq_len != 4 { + let _ = trace_num( + "ERROR: get_tx_field(Sequence) wrong length:", + seq_len as i64, + ); + return -203; // Sequence field test failed + } + let _ = trace_data("Transaction Sequence:", &seq_buffer, DataRepr::AsHex); + + // NOTE: get_tx_field2() through get_tx_field6() have been deprecated. + // Use get_tx_field() with appropriate parameters for all transaction field access. + + // Test 2.2: get_tx_nested_field() - Nested field access with locator + let locator = [0x01, 0x00]; // Simple locator for first element + let mut nested_buffer = [0u8; 32]; + let nested_result = unsafe { + host::get_tx_nested_field( + locator.as_ptr(), + locator.len(), + nested_buffer.as_mut_ptr(), + nested_buffer.len(), + ) + }; + + if nested_result < 0 { + let _ = trace_num( + "INFO: get_tx_nested_field not applicable:", + nested_result as i64, + ); + // Expected - locator may not match transaction structure + } else { + let _ = trace_num("Nested field length:", nested_result as i64); + let _ = trace_data( + "Nested field:", + &nested_buffer[..nested_result as usize], + DataRepr::AsHex, + ); + } + + // Test 2.3: get_tx_array_len() - Get array length + let signers_len = unsafe { host::get_tx_array_len(sfield::Signers) }; + let _ = trace_num("Signers array length:", signers_len as i64); + + let memos_len = unsafe { host::get_tx_array_len(sfield::Memos) }; + let _ = trace_num("Memos array length:", memos_len as i64); + + // Test 2.4: get_tx_nested_array_len() - Get nested array length with locator + let nested_array_len = + unsafe { host::get_tx_nested_array_len(locator.as_ptr(), locator.len()) }; + + if nested_array_len < 0 { + let _ = trace_num( + "INFO: get_tx_nested_array_len not applicable:", + nested_array_len as i64, + ); + } else { + let _ = trace_num("Nested array length:", nested_array_len as i64); + } + + let _ = trace("SUCCESS: Transaction data functions"); + 0 +} + +/// Test Category 3: Current Ledger Object Functions (4 functions) +/// Tests functions that access the current ledger object being processed +fn test_current_ledger_object_functions() -> i32 { + let _ = trace("--- Category 3: Current Ledger Object Functions ---"); + + // Test 3.1: get_current_ledger_obj_field() - Access field from current ledger object + // Test with Balance field (XRP amount - 8 bytes in new serialized format) + let mut balance_buffer = [0u8; 8]; + let balance_result = unsafe { + host::get_current_ledger_obj_field( + sfield::Balance, + balance_buffer.as_mut_ptr(), + balance_buffer.len(), + ) + }; + + if balance_result <= 0 { + let _ = trace_num( + "INFO: get_current_ledger_obj_field(Balance) failed (may be expected):", + balance_result as i64, + ); + // This might fail if current ledger object doesn't have balance field + } else if balance_result == 8 { + let _ = trace_num( + "Current object balance length (XRP amount):", + balance_result as i64, + ); + let _ = trace_data( + "Current object balance (serialized XRP amount):", + &balance_buffer, + DataRepr::AsHex, + ); + } else { + let _ = trace_num( + "Current object balance length (non-XRP amount):", + balance_result as i64, + ); + let _ = trace_data( + "Current object balance:", + &balance_buffer[..balance_result as usize], + DataRepr::AsHex, + ); + } + + // Test with Account field + let mut current_account_buffer = [0u8; 20]; + let current_account_result = unsafe { + host::get_current_ledger_obj_field( + sfield::Account, + current_account_buffer.as_mut_ptr(), + current_account_buffer.len(), + ) + }; + + if current_account_result <= 0 { + let _ = trace_num( + "INFO: get_current_ledger_obj_field(Account) failed:", + current_account_result as i64, + ); + } else { + let _ = trace_account_buf("Current ledger object account:", ¤t_account_buffer); + } + + // Test 3.2: get_current_ledger_obj_nested_field() - Nested field access + let locator = [0x01, 0x00]; // Simple locator + let mut current_nested_buffer = [0u8; 32]; + let current_nested_result = unsafe { + host::get_current_ledger_obj_nested_field( + locator.as_ptr(), + locator.len(), + current_nested_buffer.as_mut_ptr(), + current_nested_buffer.len(), + ) + }; + + if current_nested_result < 0 { + let _ = trace_num( + "INFO: get_current_ledger_obj_nested_field not applicable:", + current_nested_result as i64, + ); + } else { + let _ = trace_num("Current nested field length:", current_nested_result as i64); + let _ = trace_data( + "Current nested field:", + ¤t_nested_buffer[..current_nested_result as usize], + DataRepr::AsHex, + ); + } + + // Test 3.3: get_current_ledger_obj_array_len() - Array length in current object + let current_array_len = unsafe { host::get_current_ledger_obj_array_len(sfield::Signers) }; + let _ = trace_num( + "Current object Signers array length:", + current_array_len as i64, + ); + + // Test 3.4: get_current_ledger_obj_nested_array_len() - Nested array length + let current_nested_array_len = + unsafe { host::get_current_ledger_obj_nested_array_len(locator.as_ptr(), locator.len()) }; + + if current_nested_array_len < 0 { + let _ = trace_num( + "INFO: get_current_ledger_obj_nested_array_len not applicable:", + current_nested_array_len as i64, + ); + } else { + let _ = trace_num( + "Current nested array length:", + current_nested_array_len as i64, + ); + } + + let _ = trace("SUCCESS: Current ledger object functions"); + 0 +} + +/// Test Category 4: Any Ledger Object Functions (5 functions) +/// Tests functions that work with cached ledger objects +fn test_any_ledger_object_functions() -> i32 { + let _ = trace("--- Category 4: Any Ledger Object Functions ---"); + + // First we need to cache a ledger object to test the other functions + // Get the account from transaction and generate its keylet + let escrow_finish = EscrowFinish; + let account_id = escrow_finish.get_account().unwrap(); + + // Test 4.1: cache_ledger_obj() - Cache a ledger object + let mut keylet_buffer = [0u8; 32]; + let keylet_result = unsafe { + host::account_keylet( + account_id.0.as_ptr(), + account_id.0.len(), + keylet_buffer.as_mut_ptr(), + keylet_buffer.len(), + ) + }; + + if keylet_result != 32 { + let _ = trace_num( + "ERROR: account_keylet failed for caching test:", + keylet_result as i64, + ); + return -401; // Keylet generation failed for caching test + } + + let cache_result = + unsafe { host::cache_ledger_obj(keylet_buffer.as_ptr(), keylet_result as usize, 0) }; + + if cache_result <= 0 { + let _ = trace_num( + "INFO: cache_ledger_obj failed (expected with test fixtures):", + cache_result as i64, + ); + // Test fixtures may not contain the account object - this is expected + // We'll test the interface but expect failures + + // Test 4.2-4.5 with invalid slot (should fail gracefully) + let mut test_buffer = [0u8; 32]; + + // Test get_ledger_obj_field with invalid slot + let field_result = unsafe { + host::get_ledger_obj_field( + 1, + sfield::Balance, + test_buffer.as_mut_ptr(), + test_buffer.len(), + ) + }; + if field_result < 0 { + let _ = trace_num( + "INFO: get_ledger_obj_field failed as expected (no cached object):", + field_result as i64, + ); + } + + // Test get_ledger_obj_nested_field with invalid slot + let locator = [0x01, 0x00]; + let nested_result = unsafe { + host::get_ledger_obj_nested_field( + 1, + locator.as_ptr(), + locator.len(), + test_buffer.as_mut_ptr(), + test_buffer.len(), + ) + }; + if nested_result < 0 { + let _ = trace_num( + "INFO: get_ledger_obj_nested_field failed as expected:", + nested_result as i64, + ); + } + + // Test get_ledger_obj_array_len with invalid slot + let array_result = unsafe { host::get_ledger_obj_array_len(1, sfield::Signers) }; + if array_result < 0 { + let _ = trace_num( + "INFO: get_ledger_obj_array_len failed as expected:", + array_result as i64, + ); + } + + // Test get_ledger_obj_nested_array_len with invalid slot + let nested_array_result = + unsafe { host::get_ledger_obj_nested_array_len(1, locator.as_ptr(), locator.len()) }; + if nested_array_result < 0 { + let _ = trace_num( + "INFO: get_ledger_obj_nested_array_len failed as expected:", + nested_array_result as i64, + ); + } + + let _ = trace("SUCCESS: Any ledger object functions (interface tested)"); + return 0; + } + + // If we successfully cached an object, test the access functions + let slot = cache_result; + let _ = trace_num("Successfully cached object in slot:", slot as i64); + + // Test 4.2: get_ledger_obj_field() - Access field from cached object + let mut cached_balance_buffer = [0u8; 8]; + let cached_balance_result = unsafe { + host::get_ledger_obj_field( + slot, + sfield::Balance, + cached_balance_buffer.as_mut_ptr(), + cached_balance_buffer.len(), + ) + }; + + if cached_balance_result <= 0 { + let _ = trace_num( + "INFO: get_ledger_obj_field(Balance) failed:", + cached_balance_result as i64, + ); + } else if cached_balance_result == 8 { + let _ = trace_num( + "Cached object balance length (XRP amount):", + cached_balance_result as i64, + ); + let _ = trace_data( + "Cached object balance (serialized XRP amount):", + &cached_balance_buffer, + DataRepr::AsHex, + ); + } else { + let _ = trace_num( + "Cached object balance length (non-XRP amount):", + cached_balance_result as i64, + ); + let _ = trace_data( + "Cached object balance:", + &cached_balance_buffer[..cached_balance_result as usize], + DataRepr::AsHex, + ); + } + + // Test 4.3: get_ledger_obj_nested_field() - Nested field from cached object + let locator = [0x01, 0x00]; + let mut cached_nested_buffer = [0u8; 32]; + let cached_nested_result = unsafe { + host::get_ledger_obj_nested_field( + slot, + locator.as_ptr(), + locator.len(), + cached_nested_buffer.as_mut_ptr(), + cached_nested_buffer.len(), + ) + }; + + if cached_nested_result < 0 { + let _ = trace_num( + "INFO: get_ledger_obj_nested_field not applicable:", + cached_nested_result as i64, + ); + } else { + let _ = trace_num("Cached nested field length:", cached_nested_result as i64); + let _ = trace_data( + "Cached nested field:", + &cached_nested_buffer[..cached_nested_result as usize], + DataRepr::AsHex, + ); + } + + // Test 4.4: get_ledger_obj_array_len() - Array length from cached object + let cached_array_len = unsafe { host::get_ledger_obj_array_len(slot, sfield::Signers) }; + let _ = trace_num( + "Cached object Signers array length:", + cached_array_len as i64, + ); + + // Test 4.5: get_ledger_obj_nested_array_len() - Nested array length from cached object + let cached_nested_array_len = + unsafe { host::get_ledger_obj_nested_array_len(slot, locator.as_ptr(), locator.len()) }; + + if cached_nested_array_len < 0 { + let _ = trace_num( + "INFO: get_ledger_obj_nested_array_len not applicable:", + cached_nested_array_len as i64, + ); + } else { + let _ = trace_num( + "Cached nested array length:", + cached_nested_array_len as i64, + ); + } + + let _ = trace("SUCCESS: Any ledger object functions"); + 0 +} + +/// Test Category 5: Keylet Generation Functions (4 functions) +/// Tests keylet generation functions for different ledger entry types +fn test_keylet_generation_functions() -> i32 { + let _ = trace("--- Category 5: Keylet Generation Functions ---"); + + let escrow_finish = EscrowFinish; + let account_id = escrow_finish.get_account().unwrap(); + + // Test 5.1: account_keylet() - Generate keylet for account + let mut account_keylet_buffer = [0u8; 32]; + let account_keylet_result = unsafe { + host::account_keylet( + account_id.0.as_ptr(), + account_id.0.len(), + account_keylet_buffer.as_mut_ptr(), + account_keylet_buffer.len(), + ) + }; + + if account_keylet_result != 32 { + let _ = trace_num( + "ERROR: account_keylet failed:", + account_keylet_result as i64, + ); + return -501; // Account keylet generation failed + } + let _ = trace_data("Account keylet:", &account_keylet_buffer, DataRepr::AsHex); + + // Test 5.2: credential_keylet() - Generate keylet for credential + let mut credential_keylet_buffer = [0u8; 32]; + let credential_keylet_result = unsafe { + host::credential_keylet( + account_id.0.as_ptr(), // Subject + account_id.0.len(), + account_id.0.as_ptr(), // Issuer - same account for test + account_id.0.len(), + b"TestType".as_ptr(), // Credential type + 9usize, // Length of "TestType" + credential_keylet_buffer.as_mut_ptr(), + credential_keylet_buffer.len(), + ) + }; + + if credential_keylet_result <= 0 { + let _ = trace_num( + "INFO: credential_keylet failed (expected - interface issue):", + credential_keylet_result as i64, + ); + // This is expected to fail due to unusual parameter types + } else { + let _ = trace_data( + "Credential keylet:", + &credential_keylet_buffer[..credential_keylet_result as usize], + DataRepr::AsHex, + ); + } + + // Test 5.3: escrow_keylet() - Generate keylet for escrow + let mut escrow_keylet_buffer = [0u8; 32]; + let escrow_keylet_result = unsafe { + host::escrow_keylet( + account_id.0.as_ptr(), + account_id.0.len(), + 1000, // Sequence number + escrow_keylet_buffer.as_mut_ptr(), + escrow_keylet_buffer.len(), + ) + }; + + if escrow_keylet_result != 32 { + let _ = trace_num("ERROR: escrow_keylet failed:", escrow_keylet_result as i64); + return -503; // Escrow keylet generation failed + } + let _ = trace_data("Escrow keylet:", &escrow_keylet_buffer, DataRepr::AsHex); + + // Test 5.4: oracle_keylet() - Generate keylet for oracle + let mut oracle_keylet_buffer = [0u8; 32]; + let oracle_keylet_result = unsafe { + host::oracle_keylet( + account_id.0.as_ptr(), + account_id.0.len(), + 42, // Document ID + oracle_keylet_buffer.as_mut_ptr(), + oracle_keylet_buffer.len(), + ) + }; + + if oracle_keylet_result != 32 { + let _ = trace_num("ERROR: oracle_keylet failed:", oracle_keylet_result as i64); + return -504; // Oracle keylet generation failed + } + let _ = trace_data("Oracle keylet:", &oracle_keylet_buffer, DataRepr::AsHex); + + let _ = trace("SUCCESS: Keylet generation functions"); + 0 +} + +/// Test Category 6: Utility Functions (4 functions) +/// Tests utility functions for hashing, NFT access, and tracing +fn test_utility_functions() -> i32 { + let _ = trace("--- Category 6: Utility Functions ---"); + + // Test 6.1: compute_sha512_half() - SHA512 hash computation (first 32 bytes) + let test_data = b"Hello, XRPL WASM world!"; + let mut hash_output = [0u8; 32]; + let hash_result = unsafe { + host::compute_sha512_half( + test_data.as_ptr(), + test_data.len(), + hash_output.as_mut_ptr(), + hash_output.len(), + ) + }; + + if hash_result != 32 { + let _ = trace_num("ERROR: compute_sha512_half failed:", hash_result as i64); + return -601; // SHA512 half computation failed + } + let _ = trace_data("Input data:", test_data, DataRepr::AsHex); + let _ = trace_data("SHA512 half hash:", &hash_output, DataRepr::AsHex); + + // Test 6.2: get_nft() - NFT data retrieval + let escrow_finish = EscrowFinish; + let account_id = escrow_finish.get_account().unwrap(); + let nft_id = [0u8; 32]; // Dummy NFT ID for testing + let mut nft_buffer = [0u8; 256]; + let nft_result = unsafe { + host::get_nft( + account_id.0.as_ptr(), + account_id.0.len(), + nft_id.as_ptr(), + nft_id.len(), + nft_buffer.as_mut_ptr(), + nft_buffer.len(), + ) + }; + + if nft_result <= 0 { + let _ = trace_num( + "INFO: get_nft failed (expected - no such NFT):", + nft_result as i64, + ); + // This is expected - test account likely doesn't own the dummy NFT + } else { + let _ = trace_num("NFT data length:", nft_result as i64); + let _ = trace_data( + "NFT data:", + &nft_buffer[..nft_result as usize], + DataRepr::AsHex, + ); + } + + // Test 6.3: trace() - Debug logging with data + let trace_message = b"Test trace message"; + let trace_data_payload = b"payload"; + let trace_result = unsafe { + host::trace( + trace_message.as_ptr(), + trace_message.len(), + trace_data_payload.as_ptr(), + trace_data_payload.len(), + 1, // as_hex = true + ) + }; + + if trace_result < 0 { + let _ = trace_num("ERROR: trace() failed:", trace_result as i64); + return -603; // Trace function failed + } + let _ = trace_num("Trace function bytes written:", trace_result as i64); + + // Test 6.4: trace_num() - Debug logging with number + let test_number = 42i64; + let trace_num_result = trace_num("Test number trace", test_number); + + use xrpl_std::host::Result; + match trace_num_result { + Result::Ok(_) => { + let _ = trace_num("Trace_num function succeeded", 0); + } + Result::Err(_) => { + let _ = trace_num("ERROR: trace_num() failed:", -604); + return -604; // Trace number function failed + } + } + + let _ = trace("SUCCESS: Utility functions"); + 0 +} + +/// Test Category 7: Data Update Functions (1 function) +/// Tests the function for modifying the current ledger entry +fn test_data_update_functions() -> i32 { + let _ = trace("--- Category 7: Data Update Functions ---"); + + // Test 7.1: update_data() - Update current ledger entry data + let update_payload = b"Updated ledger entry data from WASM test"; + + let update_result = unsafe { host::update_data(update_payload.as_ptr(), update_payload.len()) }; + + if update_result != 0 { + let _ = trace_num("ERROR: update_data failed:", update_result as i64); + return -701; // Data update failed + } + + let _ = trace_data( + "Successfully updated ledger entry with:", + update_payload, + DataRepr::AsHex, + ); + let _ = trace("SUCCESS: Data update functions"); + 0 +} diff --git a/src/test/app/wasm_fixtures/all_keylets/Cargo.lock b/src/test/app/wasm_fixtures/all_keylets/Cargo.lock new file mode 100644 index 00000000000..3491dc00fa4 --- /dev/null +++ b/src/test/app/wasm_fixtures/all_keylets/Cargo.lock @@ -0,0 +1,15 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "all_keylets" +version = "0.0.1" +dependencies = [ + "xrpl-std", +] + +[[package]] +name = "xrpl-std" +version = "0.5.1-devnet5" +source = "git+https://github.com/ripple/craft.git?branch=lastdevnet#c3a92273195a211ac9b41d641b0d20f60f982bb2" diff --git a/src/test/app/wasm_fixtures/all_keylets/Cargo.toml b/src/test/app/wasm_fixtures/all_keylets/Cargo.toml new file mode 100644 index 00000000000..620e28fceb1 --- /dev/null +++ b/src/test/app/wasm_fixtures/all_keylets/Cargo.toml @@ -0,0 +1,21 @@ +[package] +edition = "2024" +name = "all_keylets" +version = "0.0.1" + +# This empty workspace definition keeps this project independent of the parent workspace +[workspace] + +[lib] +crate-type = ["cdylib"] + +[profile.release] +lto = true +opt-level = 's' +panic = "abort" + +[dependencies] +xrpl-std = { git = "https://github.com/ripple/craft.git", branch = "lastdevnet", package = "xrpl-std" } + +[profile.dev] +panic = "abort" diff --git a/src/test/app/wasm_fixtures/all_keylets/src/lib.rs b/src/test/app/wasm_fixtures/all_keylets/src/lib.rs new file mode 100644 index 00000000000..970db7bd50b --- /dev/null +++ b/src/test/app/wasm_fixtures/all_keylets/src/lib.rs @@ -0,0 +1,179 @@ +#![cfg_attr(target_arch = "wasm32", no_std)] + +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +use crate::host::{Error, Result, Result::Err, Result::Ok}; +use xrpl_std::core::ledger_objects::current_escrow::CurrentEscrow; +use xrpl_std::core::ledger_objects::current_escrow::get_current_escrow; +use xrpl_std::core::ledger_objects::ledger_object; +use xrpl_std::core::ledger_objects::traits::CurrentEscrowFields; +use xrpl_std::core::types::amount::asset::{Asset, IouAsset, XrpAsset}; +use xrpl_std::core::types::amount::currency_code::CurrencyCode; +use xrpl_std::core::types::amount::mpt_id::MptId; +use xrpl_std::core::types::keylets; +use xrpl_std::host; +use xrpl_std::host::trace::{DataRepr, trace, trace_account, trace_data, trace_num}; +use xrpl_std::sfield; + +#[unsafe(no_mangle)] +pub fn object_exists( + keylet_result: Result, + keylet_type: &str, + field: i32, +) -> Result { + match keylet_result { + Ok(keylet) => { + let _ = trace_data(keylet_type, &keylet, DataRepr::AsHex); + + let slot = unsafe { host::cache_ledger_obj(keylet.as_ptr(), keylet.len(), 0) }; + if slot <= 0 { + let _ = trace_num("Error: ", slot.into()); + return Err(Error::from_code(slot)); + } + if field == 0 { + let new_field = sfield::PreviousTxnID; + let _ = trace_num("Getting field: ", new_field.into()); + match ledger_object::get_hash_256_field(slot, new_field) { + Ok(data) => { + let _ = trace_data("Field data: ", &data.0, DataRepr::AsHex); + } + Err(result_code) => { + let _ = trace_num("Error getting field: ", result_code.into()); + return Err(result_code); + } + } + } else { + let _ = trace_num("Getting field: ", field.into()); + match ledger_object::get_account_id_field(slot, field) { + Ok(data) => { + let _ = trace_data("Field data: ", &data.0, DataRepr::AsHex); + } + Err(result_code) => { + let _ = trace_num("Error getting field: ", result_code.into()); + return Err(result_code); + } + } + } + + Ok(true) + } + Err(error) => { + let _ = trace_num("Error getting keylet: ", error.into()); + Err(error) + } + } +} + +#[unsafe(no_mangle)] +pub extern "C" fn finish() -> i32 { + let _ = trace("$$$$$ STARTING WASM EXECUTION $$$$$"); + + let escrow: CurrentEscrow = get_current_escrow(); + + let account = escrow.get_account().unwrap_or_panic(); + let _ = trace_account("Account:", &account); + + let destination = escrow.get_destination().unwrap_or_panic(); + let _ = trace_account("Destination:", &destination); + + let mut seq = 5; + + macro_rules! check_object_exists { + ($keylet:expr, $type:expr, $field:expr) => { + match object_exists($keylet, $type, $field) { + Ok(_exists) => { + // false isn't returned + let _ = trace(concat!( + $type, + " object exists, proceeding with escrow finish." + )); + } + Err(error) => { + let _ = trace_num("Current seq value:", seq.try_into().unwrap()); + return error.code(); + } + } + }; + } + + let account_keylet = keylets::account_keylet(&account); + check_object_exists!(account_keylet, "Account", sfield::Account); + + let currency_code: &[u8; 3] = b"USD"; + let currency: CurrencyCode = CurrencyCode::from(*currency_code); + let line_keylet = keylets::line_keylet(&account, &destination, ¤cy); + check_object_exists!(line_keylet, "Trustline", sfield::Generic); + seq += 1; + + let asset1 = Asset::XRP(XrpAsset {}); + let asset2 = Asset::IOU(IouAsset::new(destination, currency)); + check_object_exists!( + keylets::amm_keylet(&asset1, &asset2), + "AMM", + sfield::Account + ); + + let check_keylet = keylets::check_keylet(&account, seq); + check_object_exists!(check_keylet, "Check", sfield::Account); + seq += 1; + + let cred_type: &[u8] = b"termsandconditions"; + let credential_keylet = keylets::credential_keylet(&account, &account, cred_type); + check_object_exists!(credential_keylet, "Credential", sfield::Subject); + seq += 1; + + let delegate_keylet = keylets::delegate_keylet(&account, &destination); + check_object_exists!(delegate_keylet, "Delegate", sfield::Account); + seq += 1; + + let deposit_preauth_keylet = keylets::deposit_preauth_keylet(&account, &destination); + check_object_exists!(deposit_preauth_keylet, "DepositPreauth", sfield::Account); + seq += 1; + + let did_keylet = keylets::did_keylet(&account); + check_object_exists!(did_keylet, "DID", sfield::Account); + seq += 1; + + let escrow_keylet = keylets::escrow_keylet(&account, seq); + check_object_exists!(escrow_keylet, "Escrow", sfield::Account); + seq += 1; + + let mpt_issuance_keylet = keylets::mpt_issuance_keylet(&account, seq); + let mpt_id = MptId::new(seq.try_into().unwrap(), account); + check_object_exists!(mpt_issuance_keylet, "MPTIssuance", sfield::Issuer); + seq += 1; + + let mptoken_keylet = keylets::mptoken_keylet(&mpt_id, &destination); + check_object_exists!(mptoken_keylet, "MPToken", sfield::Account); + + let nft_offer_keylet = keylets::nft_offer_keylet(&destination, 6); + check_object_exists!(nft_offer_keylet, "NFTokenOffer", sfield::Owner); + + let offer_keylet = keylets::offer_keylet(&account, seq); + check_object_exists!(offer_keylet, "Offer", sfield::Account); + seq += 1; + + let paychan_keylet = keylets::paychan_keylet(&account, &destination, seq); + check_object_exists!(paychan_keylet, "PayChannel", sfield::Account); + seq += 1; + + let pd_keylet = keylets::permissioned_domain_keylet(&account, seq); + check_object_exists!(pd_keylet, "PermissionedDomain", sfield::Owner); + seq += 1; + + let signers_keylet = keylets::signers_keylet(&account); + check_object_exists!(signers_keylet, "SignerList", sfield::Generic); + seq += 1; + + seq += 1; // ticket sequence number is one greater + let ticket_keylet = keylets::ticket_keylet(&account, seq); + check_object_exists!(ticket_keylet, "Ticket", sfield::Account); + seq += 1; + + let vault_keylet = keylets::vault_keylet(&account, seq); + check_object_exists!(vault_keylet, "Vault", sfield::Account); + // seq += 1; + + 1 // All keylets exist, finish the escrow. +} diff --git a/src/test/app/wasm_fixtures/b58.c b/src/test/app/wasm_fixtures/b58.c new file mode 100644 index 00000000000..00b6178ec05 --- /dev/null +++ b/src/test/app/wasm_fixtures/b58.c @@ -0,0 +1,73 @@ +#include + +static char const b58digits_ordered[] = + "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +uint8_t e_data[32 * 1024]; + +void* +allocate(int sz) +{ + static int idx = 0; + if (idx >= 32) + return 0; + if (sz > 1024) + return 0; + return &e_data[idx++ << 10]; +} + +void +deallocate(void* p) +{ +} + +extern int32_t +b58enco(char* b58, int32_t b58sz, void const* data, int32_t binsz) +{ + uint8_t const* bin = data; + int32_t carry; + int32_t i, j, high, zcount = 0; + int32_t size; + + while (zcount < binsz && !bin[zcount]) + ++zcount; + + size = (binsz - zcount) * 138 / 100 + 1; + uint8_t* buf = allocate(size); + if (!buf) + return 0; + // memset(buf, 0, size); + for (i = 0; i < size; ++i) + buf[i] = 0; + + for (i = zcount, high = size - 1; i < binsz; ++i, high = j) + { + for (carry = bin[i], j = size - 1; (j > high) || carry; --j) + { + carry += 256 * buf[j]; + buf[j] = carry % 58; + carry /= 58; + if (!j) + break; + } + } + + for (j = 0; j < size && !buf[j]; ++j) + ; + + if (b58sz <= zcount + size - j) + return 0; + + if (zcount) + { + // memset(b58, '1', zcount); + for (i = 0; i < zcount; ++i) + b58[i] = '1'; + } + + for (i = zcount; j < size; ++i, ++j) + b58[i] = b58digits_ordered[buf[j]]; + b58[i] = '\0'; + + return i + 1; +} diff --git a/src/test/app/wasm_fixtures/codecov_tests/Cargo.lock b/src/test/app/wasm_fixtures/codecov_tests/Cargo.lock new file mode 100644 index 00000000000..000ecf39a86 --- /dev/null +++ b/src/test/app/wasm_fixtures/codecov_tests/Cargo.lock @@ -0,0 +1,15 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "codecov_tests" +version = "0.0.1" +dependencies = [ + "xrpl-wasm-std", +] + +[[package]] +name = "xrpl-wasm-std" +version = "0.5.1-devnet5" +source = "git+https://github.com/ripple/craft.git?branch=main#638276c92d790f5b738faa9f42855f02a2c7c7dc" diff --git a/src/test/app/wasm_fixtures/codecov_tests/Cargo.toml b/src/test/app/wasm_fixtures/codecov_tests/Cargo.toml new file mode 100644 index 00000000000..ea776999a9c --- /dev/null +++ b/src/test/app/wasm_fixtures/codecov_tests/Cargo.toml @@ -0,0 +1,18 @@ +[package] +edition = "2024" +name = "codecov_tests" +version = "0.0.1" + +# This empty workspace definition keeps this project independent of the parent workspace +[workspace] + +[lib] +crate-type = ["cdylib"] + +[profile.release] +lto = true +opt-level = 's' +panic = "abort" + +[dependencies] +xrpl-std = { git = "https://github.com/ripple/craft.git", branch = "main", package = "xrpl-wasm-std" } diff --git a/src/test/app/wasm_fixtures/codecov_tests/src/host_bindings_loose.rs b/src/test/app/wasm_fixtures/codecov_tests/src/host_bindings_loose.rs new file mode 100644 index 00000000000..c99a0047d5e --- /dev/null +++ b/src/test/app/wasm_fixtures/codecov_tests/src/host_bindings_loose.rs @@ -0,0 +1,47 @@ +//TODO add docs after discussing the interface +//Note that Craft currently does not honor the rounding modes +#[allow(unused)] +pub const FLOAT_ROUNDING_MODES_TO_NEAREST: i32 = 0; +#[allow(unused)] +pub const FLOAT_ROUNDING_MODES_TOWARDS_ZERO: i32 = 1; +#[allow(unused)] +pub const FLOAT_ROUNDING_MODES_DOWNWARD: i32 = 2; +#[allow(unused)] +pub const FLOAT_ROUNDING_MODES_UPWARD: i32 = 3; + +// pub enum RippledRoundingModes{ +// ToNearest = 0, +// TowardsZero = 1, +// DOWNWARD = 2, +// UPWARD = 3 +// } + +#[allow(unused)] +#[link(wasm_import_module = "host_lib")] +unsafe extern "C" { + pub fn get_parent_ledger_hash(out_buff_ptr: i32, out_buff_len: i32) -> i32; + + pub fn cache_ledger_obj(keylet_ptr: i32, keylet_len: i32, cache_num: i32) -> i32; + + pub fn get_tx_nested_array_len(locator_ptr: i32, locator_len: i32) -> i32; + + pub fn account_keylet( + account_ptr: i32, + account_len: i32, + out_buff_ptr: *mut u8, + out_buff_len: usize, + ) -> i32; + + pub fn line_keylet( + account1_ptr: *const u8, + account1_len: usize, + account2_ptr: *const u8, + account2_len: usize, + currency_ptr: i32, + currency_len: i32, + out_buff_ptr: *mut u8, + out_buff_len: usize, + ) -> i32; + + pub fn trace_num(msg_read_ptr: i32, msg_read_len: i32, number: i64) -> i32; +} diff --git a/src/test/app/wasm_fixtures/codecov_tests/src/lib.rs b/src/test/app/wasm_fixtures/codecov_tests/src/lib.rs new file mode 100644 index 00000000000..f02550ba967 --- /dev/null +++ b/src/test/app/wasm_fixtures/codecov_tests/src/lib.rs @@ -0,0 +1,1519 @@ +#![cfg_attr(target_arch = "wasm32", no_std)] + +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +use core::panic; +use xrpl_std::core::current_tx::escrow_finish::{get_current_escrow_finish, EscrowFinish}; +use xrpl_std::core::current_tx::traits::TransactionCommonFields; +use xrpl_std::core::locator::Locator; +use xrpl_std::core::types::amount::asset::Asset; +use xrpl_std::core::types::amount::asset::XrpAsset; +use xrpl_std::core::types::amount::mpt_id::MptId; +use xrpl_std::core::types::keylets; +use xrpl_std::host; +use xrpl_std::host::error_codes; +use xrpl_std::host::trace::{trace, trace_num as trace_number}; +use xrpl_std::sfield; + +mod host_bindings_loose; +include!("host_bindings_loose.rs"); + +fn check_result(result: i32, expected: i32, test_name: &'static str) { + match result { + code if code == expected => { + let _ = trace_number(test_name, code.into()); + } + code if code >= 0 => { + let _ = trace(test_name); + let _ = trace_number("TEST FAILED", code.into()); + panic!("Unexpected success code: {}", code); + } + code => { + let _ = trace(test_name); + let _ = trace_number("TEST FAILED", code.into()); + panic!("Error code: {}", code); + } + } +} + +fn with_buffer(mut f: F) -> R +where + F: FnMut(*mut u8, usize) -> R, +{ + let mut buf = [0u8; N]; + f(buf.as_mut_ptr(), buf.len()) +} + +#[unsafe(no_mangle)] +pub extern "C" fn finish() -> i32 { + let _ = trace("$$$$$ STARTING WASM EXECUTION $$$$$"); + + // ######################################## + // Step #1: Test all host function happy paths + // Note: not testing all the keylet functions, + // that's in a separate test file (all_keylets). + // The float tests are also in a separate file (float_tests). + // ######################################## + check_result(unsafe { host::get_ledger_sqn() }, 12345, "get_ledger_sqn"); + check_result( + unsafe { host::get_parent_ledger_time() }, + 67890, + "get_parent_ledger_time", + ); + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { host::get_parent_ledger_hash(ptr, len) }, + 32, + "get_parent_ledger_hash", + ); + }); + check_result(unsafe { host::get_base_fee() }, 10, "get_base_fee"); + let amendment_name: &[u8] = b"test_amendment"; + let amendment_id: [u8; 32] = [1; 32]; + check_result( + unsafe { host::amendment_enabled(amendment_name.as_ptr(), amendment_name.len()) }, + 1, + "amendment_enabled", + ); + check_result( + unsafe { host::amendment_enabled(amendment_id.as_ptr(), amendment_id.len()) }, + 1, + "amendment_enabled", + ); + let tx: EscrowFinish = get_current_escrow_finish(); + let account = tx.get_account().unwrap_or_panic(); // get_tx_field under the hood + let keylet = keylets::account_keylet(&account).unwrap_or_panic(); // account_keylet under the hood + check_result( + unsafe { host::cache_ledger_obj(keylet.as_ptr(), keylet.len(), 0) }, + 1, + "cache_ledger_obj", + ); + with_buffer::<20, _, _>(|ptr, len| { + check_result( + unsafe { host::get_current_ledger_obj_field(sfield::Account, ptr, len) }, + 20, + "get_current_ledger_obj_field", + ); + }); + with_buffer::<20, _, _>(|ptr, len| { + check_result( + unsafe { host::get_ledger_obj_field(1, sfield::Account, ptr, len) }, + 20, + "get_ledger_obj_field", + ); + }); + let mut locator = Locator::new(); + locator.pack(sfield::Account); + with_buffer::<20, _, _>(|ptr, len| { + check_result( + unsafe { host::get_tx_nested_field(locator.as_ptr(), locator.len(), ptr, len) }, + 20, + "get_tx_nested_field", + ); + }); + with_buffer::<20, _, _>(|ptr, len| { + check_result( + unsafe { + host::get_current_ledger_obj_nested_field(locator.as_ptr(), locator.len(), ptr, len) + }, + 20, + "get_current_ledger_obj_nested_field", + ); + }); + with_buffer::<20, _, _>(|ptr, len| { + check_result( + unsafe { + host::get_ledger_obj_nested_field(1, locator.as_ptr(), locator.len(), ptr, len) + }, + 20, + "get_ledger_obj_nested_field", + ); + }); + check_result( + unsafe { host::get_tx_array_len(sfield::Memos) }, + 32, + "get_tx_array_len", + ); + check_result( + unsafe { host::get_current_ledger_obj_array_len(sfield::Memos) }, + 32, + "get_current_ledger_obj_array_len", + ); + check_result( + unsafe { host::get_ledger_obj_array_len(1, sfield::Memos) }, + 32, + "get_ledger_obj_array_len", + ); + check_result( + unsafe { host::get_tx_nested_array_len(locator.as_ptr(), locator.len()) }, + 32, + "get_tx_nested_array_len", + ); + check_result( + unsafe { host::get_current_ledger_obj_nested_array_len(locator.as_ptr(), locator.len()) }, + 32, + "get_current_ledger_obj_nested_array_len", + ); + check_result( + unsafe { host::get_ledger_obj_nested_array_len(1, locator.as_ptr(), locator.len()) }, + 32, + "get_ledger_obj_nested_array_len", + ); + check_result( + unsafe { host::update_data(account.0.as_ptr(), account.0.len()) }, + 0, + "update_data", + ); + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { host::compute_sha512_half(locator.as_ptr(), locator.len(), ptr, len) }, + 32, + "compute_sha512_half", + ); + }); + let message: &[u8] = b"test message"; + let pubkey: &[u8] = b"test pubkey"; //tx.get_public_key().unwrap_or_panic(); + let signature: &[u8] = b"test signature"; + check_result( + unsafe { + host::check_sig( + message.as_ptr(), + message.len(), + pubkey.as_ptr(), + pubkey.len(), + signature.as_ptr(), + signature.len(), + ) + }, + 1, + "check_sig", + ); + + let nft_id: [u8; 32] = amendment_id; + with_buffer::<18, _, _>(|ptr, len| { + check_result( + unsafe { + host::get_nft( + account.0.as_ptr(), + account.0.len(), + nft_id.as_ptr(), + nft_id.len(), + ptr, + len, + ) + }, + 18, + "get_nft", + ) + }); + with_buffer::<20, _, _>(|ptr, len| { + check_result( + unsafe { host::get_nft_issuer(nft_id.as_ptr(), nft_id.len(), ptr, len) }, + 20, + "get_nft_issuer", + ) + }); + with_buffer::<4, _, _>(|ptr, len| { + check_result( + unsafe { host::get_nft_taxon(nft_id.as_ptr(), nft_id.len(), ptr, len) }, + 4, + "get_nft_taxon", + ) + }); + check_result( + unsafe { host::get_nft_flags(nft_id.as_ptr(), nft_id.len()) }, + 8, + "get_nft_flags", + ); + check_result( + unsafe { host::get_nft_transfer_fee(nft_id.as_ptr(), nft_id.len()) }, + 10, + "get_nft_transfer_fee", + ); + with_buffer::<4, _, _>(|ptr, len| { + check_result( + unsafe { host::get_nft_serial(nft_id.as_ptr(), nft_id.len(), ptr, len) }, + 4, + "get_nft_serial", + ) + }); + let message = "testing trace"; + check_result( + unsafe { + host::trace_account( + message.as_ptr(), + message.len(), + account.0.as_ptr(), + account.0.len(), + ) + }, + 47, + "trace_account", + ); + let amount = &[0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F]; // 95 drops of XRP + check_result( + unsafe { + host::trace_amount( + message.as_ptr(), + message.len(), + amount.as_ptr(), + amount.len(), + ) + }, + 19, + "trace_amount", + ); + + // ######################################## + // Step #2: Test set_data edge cases + // ######################################## + check_result( + unsafe { host_bindings_loose::get_parent_ledger_hash(-1, 4) }, + error_codes::INVALID_PARAMS, + "get_parent_ledger_hash_neg_ptr", + ); + with_buffer::<4, _, _>(|ptr, _len| { + check_result( + unsafe { host_bindings_loose::get_parent_ledger_hash(ptr as i32, -1) }, + error_codes::INVALID_PARAMS, + "get_parent_ledger_hash_neg_len", + ) + }); + with_buffer::<3, _, _>(|ptr, len| { + check_result( + unsafe { host_bindings_loose::get_parent_ledger_hash(ptr as i32, len as i32) }, + error_codes::BUFFER_TOO_SMALL, + "get_parent_ledger_hash_buf_too_small", + ) + }); + with_buffer::<4, _, _>(|ptr, _len| { + check_result( + unsafe { host_bindings_loose::get_parent_ledger_hash(ptr as i32, 1_000_000_000) }, + error_codes::POINTER_OUT_OF_BOUNDS, + "get_parent_ledger_hash_len_too_long", + ) + }); + let message = "testing trace"; + check_result( + unsafe { + host::trace_account( + message.as_ptr(), + message.len(), + account.0.as_ptr(), + account.0.len(), + ) + }, + 47, + "trace_account", + ); + let amount = &[0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F]; // 95 drops of XRP + check_result( + unsafe { + host::trace_amount( + message.as_ptr(), + message.len(), + amount.as_ptr(), + amount.len(), + ) + }, + 19, + "trace_amount", + ); + + // ######################################## + // Step #3: Test getData[Type] edge cases + // ######################################## + + // uint64 + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_from_uint( + locator.as_ptr().wrapping_add(1_000_000_000), + 8, + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_from_uint_len_oob", + ) + }); + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_from_uint( + locator.as_ptr(), + locator.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::INVALID_PARAMS, + "float_from_uint_wrong_len", + ) + }); + + // SField + check_result( + unsafe { host::get_tx_array_len(2) }, // not a valid SField value + error_codes::INVALID_FIELD, + "get_tx_array_len_invalid_sfield", + ); + + // Slice + check_result( + unsafe { host_bindings_loose::get_tx_nested_array_len(-1, locator.len() as i32) }, + error_codes::INVALID_PARAMS, + "get_tx_nested_array_len_neg_ptr", + ); + check_result( + unsafe { host_bindings_loose::get_tx_nested_array_len(locator.as_ptr() as i32, -1) }, + error_codes::INVALID_PARAMS, + "get_tx_nested_array_len_neg_len", + ); + let long_len = 4 * 1024 + 1; + check_result( + unsafe { + host_bindings_loose::get_tx_nested_array_len(locator.as_ptr() as i32, long_len as i32) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "get_tx_nested_array_len_too_long", + ); + check_result( + unsafe { + host_bindings_loose::get_tx_nested_array_len( + locator.as_ptr() as i32 + 1_000_000_000, + locator.len() as i32, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "get_tx_nested_array_len_ptr_oob", + ); + + // uint256 + check_result( + unsafe { + host_bindings_loose::cache_ledger_obj( + locator.as_ptr() as i32 + 1_000_000_000, + locator.len() as i32, + 1, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "cache_ledger_obj_ptr_oob", + ); + check_result( + unsafe { + host_bindings_loose::cache_ledger_obj(locator.as_ptr() as i32, locator.len() as i32, 1) + }, + error_codes::INVALID_PARAMS, + "cache_ledger_obj_wrong_len", + ); + + // AccountID + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host_bindings_loose::account_keylet( + locator.as_ptr() as i32 + 1_000_000_000, + locator.len() as i32, + ptr, + len, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "account_keylet_len_oob", + ) + }); + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host_bindings_loose::account_keylet( + locator.as_ptr() as i32, + locator.len() as i32, + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "account_keylet_wrong_len", + ) + }); + + // Currency + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host_bindings_loose::line_keylet( + account.0.as_ptr(), + account.0.len(), + account.0.as_ptr(), + account.0.len(), + locator.as_ptr() as i32 + 1_000_000_000, + locator.len() as i32, + ptr, + len, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "line_keylet_len_oob_currency", + ) + }); + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host_bindings_loose::line_keylet( + account.0.as_ptr(), + account.0.len(), + account.0.as_ptr(), + account.0.len(), + locator.as_ptr() as i32, + locator.len() as i32, + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "line_keylet_wrong_len_currency", + ) + }); + + // Asset + let asset1_bytes = Asset::XRP(XrpAsset {}).as_bytes(); + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host::amm_keylet( + asset1_bytes.as_ptr(), + asset1_bytes.len(), + locator.as_ptr().wrapping_add(1_000_000_000), + locator.len(), + ptr, + len, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "amm_keylet_len_oob_asset2", + ) + }); + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host::amm_keylet( + asset1_bytes.as_ptr(), + asset1_bytes.len(), + locator.as_ptr(), + locator.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "amm_keylet_len_wrong_len_asset2", + ) + }); + let currency: &[u8] = b"USD00000000000000000"; // 20 bytes + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host::amm_keylet( + asset1_bytes.as_ptr(), + asset1_bytes.len(), + currency.as_ptr(), + currency.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "amm_keylet_len_wrong_non_xrp_currency_len", + ) + }); + let xrpissue: &[u8] = &[0; 40]; // 40 bytes + with_buffer::<32, _, _>(|ptr, len| { + check_result( + unsafe { + host::amm_keylet( + xrpissue.as_ptr(), + xrpissue.len(), + asset1_bytes.as_ptr(), + asset1_bytes.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "amm_keylet_len_wrong_xrp_currency_len", + ) + }); + let mptid = MptId::new(1, account); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::amm_keylet( + mptid.as_ptr(), + mptid.len(), + asset1_bytes.as_ptr(), + asset1_bytes.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "amm_keylet_mpt", + ) + }); + + // string + check_result( + unsafe { + host_bindings_loose::trace_num( + locator.as_ptr() as i32 + 1_000_000_000, + locator.len() as i32, + 42, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "trace_num_oob_str", + ); + + // ######################################## + // Step #4: Test other host function edge cases + // ######################################## + + // invalid SFields + + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::get_tx_field(2, ptr, len) }, + error_codes::INVALID_FIELD, + "get_tx_field_invalid_sfield", + ); + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::get_current_ledger_obj_field(2, ptr, len) }, + error_codes::INVALID_FIELD, + "get_current_ledger_obj_field_invalid_sfield", + ); + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::get_ledger_obj_field(1, 2, ptr, len) }, + error_codes::INVALID_FIELD, + "get_ledger_obj_field_invalid_sfield", + ); + }); + check_result( + unsafe { host::get_tx_array_len(2) }, + error_codes::INVALID_FIELD, + "get_tx_array_len_invalid_sfield", + ); + check_result( + unsafe { host::get_current_ledger_obj_array_len(2) }, + error_codes::INVALID_FIELD, + "get_current_ledger_obj_array_len_invalid_sfield", + ); + check_result( + unsafe { host::get_ledger_obj_array_len(1, 2) }, + error_codes::INVALID_FIELD, + "get_ledger_obj_array_len_invalid_sfield", + ); + + // invalid Slice + + check_result( + unsafe { host::amendment_enabled(amendment_name.as_ptr(), long_len) }, + error_codes::DATA_FIELD_TOO_LARGE, + "amendment_enabled_too_big_slice", + ); + check_result( + unsafe { host::amendment_enabled(amendment_name.as_ptr(), 65) }, + error_codes::DATA_FIELD_TOO_LARGE, + "amendment_enabled_too_long", + ); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::get_tx_nested_field(locator.as_ptr(), long_len, ptr, len) }, + error_codes::DATA_FIELD_TOO_LARGE, + "get_tx_nested_field_too_big_slice", + ); + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::get_current_ledger_obj_nested_field(locator.as_ptr(), long_len, ptr, len) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "get_current_ledger_obj_nested_field_too_big_slice", + ); + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::get_ledger_obj_nested_field(1, locator.as_ptr(), long_len, ptr, len) }, + error_codes::DATA_FIELD_TOO_LARGE, + "get_ledger_obj_nested_field_too_big_slice", + ); + }); + check_result( + unsafe { host::get_tx_nested_array_len(locator.as_ptr(), long_len) }, + error_codes::DATA_FIELD_TOO_LARGE, + "get_tx_nested_array_len_too_big_slice", + ); + check_result( + unsafe { host::get_current_ledger_obj_nested_array_len(locator.as_ptr(), long_len) }, + error_codes::DATA_FIELD_TOO_LARGE, + "get_current_ledger_obj_nested_array_len_too_big_slice", + ); + check_result( + unsafe { host::get_ledger_obj_nested_array_len(1, locator.as_ptr(), long_len) }, + error_codes::DATA_FIELD_TOO_LARGE, + "get_ledger_obj_nested_array_len_too_big_slice", + ); + check_result( + unsafe { host::update_data(locator.as_ptr(), long_len) }, + error_codes::DATA_FIELD_TOO_LARGE, + "update_data_too_big_slice", + ); + check_result( + unsafe { + host::check_sig( + message.as_ptr(), + long_len, + pubkey.as_ptr(), + pubkey.len(), + signature.as_ptr(), + signature.len(), + ) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "check_sig", + ); + check_result( + unsafe { + host::check_sig( + message.as_ptr(), + message.len(), + pubkey.as_ptr(), + long_len, + signature.as_ptr(), + signature.len(), + ) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "check_sig", + ); + check_result( + unsafe { + host::check_sig( + message.as_ptr(), + message.len(), + pubkey.as_ptr(), + pubkey.len(), + signature.as_ptr(), + long_len, + ) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "check_sig", + ); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::compute_sha512_half(locator.as_ptr(), long_len, ptr, len) }, + error_codes::DATA_FIELD_TOO_LARGE, + "compute_sha512_half_too_big_slice", + ); + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::amm_keylet( + asset1_bytes.as_ptr(), + long_len, + asset1_bytes.as_ptr(), + asset1_bytes.len(), + ptr, + len, + ) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "amm_keylet_too_big_slice", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::credential_keylet( + account.0.as_ptr(), + account.0.len(), + account.0.as_ptr(), + account.0.len(), + locator.as_ptr(), + long_len, + ptr, + len, + ) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "credential_keylet_too_big_slice", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::mptoken_keylet( + mptid.as_ptr(), + long_len, + account.0.as_ptr(), + account.0.len(), + ptr, + len, + ) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "mptoken_keylet_too_big_slice_mptid", + ) + }); + check_result( + unsafe { + host::trace( + message.as_ptr(), + message.len(), + locator.as_ptr().wrapping_add(1_000_000_000), + locator.len(), + 0, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "trace_oob_slice", + ); + let float: [u8; 8] = [0xD4, 0x83, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00]; + check_result( + unsafe { + host::trace_opaque_float( + message.as_ptr(), + message.len(), + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "trace_opaque_float_oob_slice", + ); + check_result( + unsafe { + host::trace_amount( + message.as_ptr(), + message.len(), + locator.as_ptr().wrapping_add(1_000_000_000), + locator.len(), + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "trace_amount_oob_slice", + ); + check_result( + unsafe { + host::float_compare( + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + float.as_ptr(), + float.len(), + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_compare_oob_slice1", + ); + check_result( + unsafe { + host::float_compare( + float.as_ptr(), + float.len(), + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_compare_oob_slice2", + ); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_add( + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + float.as_ptr(), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_add_oob_slice1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_add( + float.as_ptr(), + float.len(), + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_add_oob_slice2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_subtract( + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + float.as_ptr(), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_subtract_oob_slice1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_subtract( + float.as_ptr(), + float.len(), + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_subtract_oob_slice2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_multiply( + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + float.as_ptr(), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_multiply_oob_slice1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_multiply( + float.as_ptr(), + float.len(), + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_multiply_oob_slice2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_divide( + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + float.as_ptr(), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_divide_oob_slice1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_divide( + float.as_ptr(), + float.len(), + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_divide_oob_slice2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_root( + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + 3, + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_root_oob_slice", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_pow( + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + 3, + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_pow_oob_slice", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::float_log( + float.as_ptr().wrapping_add(1_000_000_000), + float.len(), + ptr, + len, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "float_log_oob_slice", + ) + }); + + // invalid UInt256 + + check_result( + unsafe { host::cache_ledger_obj(locator.as_ptr(), locator.len(), 0) }, + error_codes::INVALID_PARAMS, + "cache_ledger_obj_wrong_size_uint256", + ); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::get_nft( + account.0.as_ptr(), + account.0.len(), + locator.as_ptr(), + locator.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "get_nft_wrong_size_uint256", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::get_nft_issuer(locator.as_ptr(), locator.len(), ptr, len) }, + error_codes::INVALID_PARAMS, + "get_nft_issuer_wrong_size_uint256", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::get_nft_taxon(locator.as_ptr(), locator.len(), ptr, len) }, + error_codes::INVALID_PARAMS, + "get_nft_taxon_wrong_size_uint256", + ) + }); + check_result( + unsafe { host::get_nft_flags(locator.as_ptr(), locator.len()) }, + error_codes::INVALID_PARAMS, + "get_nft_flags_wrong_size_uint256", + ); + check_result( + unsafe { host::get_nft_transfer_fee(locator.as_ptr(), locator.len()) }, + error_codes::INVALID_PARAMS, + "get_nft_transfer_fee_wrong_size_uint256", + ); + with_buffer::<4, _, _>(|ptr, len| { + check_result( + unsafe { host::get_nft_serial(locator.as_ptr(), locator.len(), ptr, len) }, + error_codes::INVALID_PARAMS, + "get_nft_serial_wrong_size_uint256", + ) + }); + + // invalid AccountID + + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::account_keylet(locator.as_ptr(), locator.len(), ptr, len) }, + error_codes::INVALID_PARAMS, + "account_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::check_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) }, + error_codes::INVALID_PARAMS, + "check_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::credential_keylet( + locator.as_ptr(), // invalid AccountID size + locator.len(), + account.0.as_ptr(), + account.0.len(), + locator.as_ptr(), // valid slice size + locator.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "credential_keylet_wrong_size_accountid1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::credential_keylet( + account.0.as_ptr(), + account.0.len(), + locator.as_ptr(), // invalid AccountID size + locator.len(), + locator.as_ptr(), // valid slice size + locator.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "credential_keylet_wrong_size_accountid2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::delegate_keylet( + locator.as_ptr(), // invalid AccountID size + locator.len(), + account.0.as_ptr(), + account.0.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "delegate_keylet_wrong_size_accountid1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::delegate_keylet( + account.0.as_ptr(), + account.0.len(), + locator.as_ptr(), // invalid AccountID size + locator.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "delegate_keylet_wrong_size_accountid2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::deposit_preauth_keylet( + locator.as_ptr(), // invalid AccountID size + locator.len(), + account.0.as_ptr(), + account.0.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "deposit_preauth_keylet_wrong_size_accountid1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::deposit_preauth_keylet( + account.0.as_ptr(), + account.0.len(), + locator.as_ptr(), // invalid AccountID size + locator.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "deposit_preauth_keylet_wrong_size_accountid2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::did_keylet(locator.as_ptr(), locator.len(), ptr, len) }, + error_codes::INVALID_PARAMS, + "did_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::escrow_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) }, + error_codes::INVALID_PARAMS, + "escrow_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::line_keylet( + locator.as_ptr(), // invalid AccountID size + locator.len(), + account.0.as_ptr(), + account.0.len(), + currency.as_ptr(), + currency.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "line_keylet_wrong_size_accountid1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::line_keylet( + account.0.as_ptr(), + account.0.len(), + locator.as_ptr(), // invalid AccountID size + locator.len(), + currency.as_ptr(), + currency.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "line_keylet_wrong_size_accountid2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::mpt_issuance_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) }, + error_codes::INVALID_PARAMS, + "mpt_issuance_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::mptoken_keylet( + mptid.as_ptr(), + mptid.len(), + locator.as_ptr(), + locator.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "mptoken_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::nft_offer_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) }, + error_codes::INVALID_PARAMS, + "nft_offer_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::offer_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) }, + error_codes::INVALID_PARAMS, + "offer_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::oracle_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) }, + error_codes::INVALID_PARAMS, + "oracle_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::paychan_keylet( + locator.as_ptr(), // invalid AccountID size + locator.len(), + account.0.as_ptr(), + account.0.len(), + 1, + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "paychan_keylet_wrong_size_accountid1", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::paychan_keylet( + account.0.as_ptr(), + account.0.len(), + locator.as_ptr(), // invalid AccountID size + locator.len(), + 1, + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "paychan_keylet_wrong_size_accountid2", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::permissioned_domain_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) + }, + error_codes::INVALID_PARAMS, + "permissioned_domain_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::signers_keylet(locator.as_ptr(), locator.len(), ptr, len) }, + error_codes::INVALID_PARAMS, + "signers_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::ticket_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) }, + error_codes::INVALID_PARAMS, + "ticket_keylet_wrong_size_accountid", + ) + }); + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { host::vault_keylet(locator.as_ptr(), locator.len(), 1, ptr, len) }, + error_codes::INVALID_PARAMS, + "vault_keylet_wrong_size_accountid", + ) + }); + let uint256: &[u8] = b"00000000000000000000000000000001"; + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::get_nft( + locator.as_ptr(), + locator.len(), + uint256.as_ptr(), + uint256.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "get_nft_wrong_size_accountid", + ) + }); + check_result( + unsafe { + host::trace_account( + message.as_ptr(), + message.len(), + locator.as_ptr(), + locator.len(), + ) + }, + error_codes::INVALID_PARAMS, + "trace_account_wrong_size_accountid", + ); + + // invalid Currency was already tested above + // invalid string + + check_result( + unsafe { + host::trace( + message.as_ptr().wrapping_add(1_000_000_000), + message.len(), + uint256.as_ptr(), + uint256.len(), + 0, + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "trace_oob_string", + ); + check_result( + unsafe { + host::trace_opaque_float( + message.as_ptr().wrapping_add(1_000_000_000), + message.len(), + float.as_ptr(), + float.len(), + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "trace_opaque_float_oob_string", + ); + check_result( + unsafe { + host::trace_account( + message.as_ptr().wrapping_add(1_000_000_000), + message.len(), + account.0.as_ptr(), + account.0.len(), + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "trace_account_oob_string", + ); + check_result( + unsafe { + host::trace_amount( + message.as_ptr().wrapping_add(1_000_000_000), + message.len(), + amount.as_ptr(), + amount.len(), + ) + }, + error_codes::POINTER_OUT_OF_BOUNDS, + "trace_amount_oob_string", + ); + + // trace too large + + check_result( + unsafe { + host::trace( + locator.as_ptr(), + locator.len(), + locator.as_ptr(), + long_len, + 0, + ) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "trace_too_long", + ); + check_result( + unsafe { host::trace_num(locator.as_ptr(), long_len, 1) }, + error_codes::DATA_FIELD_TOO_LARGE, + "trace_num_too_long", + ); + check_result( + unsafe { + host::trace_opaque_float(message.as_ptr(), long_len, float.as_ptr(), float.len()) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "trace_opaque_float_too_long", + ); + check_result( + unsafe { + host::trace_account( + message.as_ptr(), + long_len, + account.0.as_ptr(), + account.0.len(), + ) + }, + error_codes::DATA_FIELD_TOO_LARGE, + "trace_account_too_long", + ); + check_result( + unsafe { host::trace_amount(message.as_ptr(), long_len, amount.as_ptr(), amount.len()) }, + error_codes::DATA_FIELD_TOO_LARGE, + "trace_amount_too_long", + ); + + // trace amount errors + + check_result( + unsafe { + host::trace_amount( + message.as_ptr(), + message.len(), + locator.as_ptr(), + locator.len(), + ) + }, + error_codes::INVALID_PARAMS, + "trace_amount_wrong_length", + ); + + // other misc errors + + with_buffer::<2, _, _>(|ptr, len| { + check_result( + unsafe { + host::mptoken_keylet( + locator.as_ptr(), + locator.len(), + account.0.as_ptr(), + account.0.len(), + ptr, + len, + ) + }, + error_codes::INVALID_PARAMS, + "mptoken_keylet_mptid_wrong_length", + ) + }); + + 1 // <-- If we get here, finish the escrow. +} diff --git a/src/test/app/wasm_fixtures/copyFixtures.py b/src/test/app/wasm_fixtures/copyFixtures.py new file mode 100644 index 00000000000..cd53184b5e7 --- /dev/null +++ b/src/test/app/wasm_fixtures/copyFixtures.py @@ -0,0 +1,134 @@ +import os +import sys +import subprocess +import re + +OPT = "-Oz" + + +def update_fixture(project_name, wasm): + fixture_name = ( + re.sub(r"_([a-z])", lambda m: m.group(1).upper(), project_name) + "WasmHex" + ) + print(f"Updating fixture: {fixture_name}") + + cpp_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "fixtures.cpp")) + h_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "fixtures.h")) + with open(cpp_path, "r", encoding="utf8") as f: + cpp_content = f.read() + + pattern = rf'extern std::string const {fixture_name} =[ \n]+"[^;]*;' + if re.search(pattern, cpp_content, flags=re.MULTILINE): + updated_cpp_content = re.sub( + pattern, + f'extern std::string const {fixture_name} = "{wasm}";', + cpp_content, + flags=re.MULTILINE, + ) + else: + with open(h_path, "r", encoding="utf8") as f: + h_content = f.read() + updated_h_content = ( + h_content.rstrip() + f"\n\n extern std::string const {fixture_name};\n" + ) + with open(h_path, "w", encoding="utf8") as f: + f.write(updated_h_content) + updated_cpp_content = ( + cpp_content.rstrip() + + f'\n\nextern std::string const {fixture_name} = "{wasm}";\n' + ) + + with open(cpp_path, "w", encoding="utf8") as f: + f.write(updated_cpp_content) + + +def process_rust(project_name): + project_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), project_name) + ) + wasm_location = f"target/wasm32v1-none/release/{project_name}.wasm" + build_cmd = ( + f"(cd {project_path} " + f"&& cargo build --target wasm32v1-none --release " + f"&& wasm-opt {wasm_location} {OPT} -o {wasm_location}" + ")" + ) + try: + result = subprocess.run( + build_cmd, shell=True, check=True, capture_output=True, text=True + ) + print(f"stdout: {result.stdout}") + if result.stderr: + print(f"stderr: {result.stderr}") + print(f"WASM file for {project_name} has been built and optimized.") + except subprocess.CalledProcessError as e: + print(f"exec error: {e}") + sys.exit(1) + + src_path = os.path.abspath( + os.path.join( + os.path.dirname(__file__), + f"{project_name}/target/wasm32v1-none/release/{project_name}.wasm", + ) + ) + with open(src_path, "rb") as f: + data = f.read() + wasm = data.hex() + update_fixture(project_name, wasm) + + +def process_c(project_name): + project_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), f"{project_name}.c") + ) + wasm_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), f"{project_name}.wasm") + ) + build_cmd = ( + f"$CC --sysroot=$SYSROOT " + f"-O3 -ffast-math --target=wasm32 -fno-exceptions -fno-threadsafe-statics -fvisibility=default -Wl,--export-all -Wl,--no-entry -Wl,--allow-undefined -DNDEBUG --no-standard-libraries -fno-builtin-memset " + f"-o {wasm_path} {project_path}" + f"&& wasm-opt {wasm_path} {OPT} -o {wasm_path}" + ) + try: + result = subprocess.run( + build_cmd, shell=True, check=True, capture_output=True, text=True + ) + print(f"stdout: {result.stdout}") + if result.stderr: + print(f"stderr: {result.stderr}") + print( + f"WASM file for {project_name} has been built with WASI support using clang." + ) + except subprocess.CalledProcessError as e: + print(f"exec error: {e}") + sys.exit(1) + + with open(wasm_path, "rb") as f: + data = f.read() + wasm = data.hex() + update_fixture(project_name, wasm) + + +if __name__ == "__main__": + if len(sys.argv) > 2: + print("Usage: python copyFixtures.py []") + sys.exit(1) + if len(sys.argv) == 2: + if os.path.isdir(os.path.join(os.path.dirname(__file__), sys.argv[1])): + process_rust(sys.argv[1]) + else: + process_c(sys.argv[1]) + print("Fixture has been processed.") + else: + dirs = [ + d + for d in os.listdir(os.path.dirname(__file__)) + if os.path.isdir(os.path.join(os.path.dirname(__file__), d)) + ] + c_files = [f for f in os.listdir(os.path.dirname(__file__)) if f.endswith(".c")] + for d in dirs: + process_rust(d) + for c in c_files: + process_c(c[:-2]) + print("All fixtures have been processed.") diff --git a/src/test/app/wasm_fixtures/disableFloat.wat b/src/test/app/wasm_fixtures/disableFloat.wat new file mode 100644 index 00000000000..035a849e30d --- /dev/null +++ b/src/test/app/wasm_fixtures/disableFloat.wat @@ -0,0 +1,34 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (result i32))) + (func (;0;) (type 0)) + (func (;1;) (type 1) (result i32) + f32.const -2048 + f32.const 2050 + f32.sub + drop + i32.const 1) + (memory (;0;) 2) + (global (;0;) i32 (i32.const 1024)) + (global (;1;) i32 (i32.const 1024)) + (global (;2;) i32 (i32.const 2048)) + (global (;3;) i32 (i32.const 2048)) + (global (;4;) i32 (i32.const 67584)) + (global (;5;) i32 (i32.const 1024)) + (global (;6;) i32 (i32.const 67584)) + (global (;7;) i32 (i32.const 131072)) + (global (;8;) i32 (i32.const 0)) + (global (;9;) i32 (i32.const 1)) + (export "memory" (memory 0)) + (export "__wasm_call_ctors" (func 0)) + (export "finish" (func 1)) + (export "buf" (global 0)) + (export "__dso_handle" (global 1)) + (export "__data_end" (global 2)) + (export "__stack_low" (global 3)) + (export "__stack_high" (global 4)) + (export "__global_base" (global 5)) + (export "__heap_base" (global 6)) + (export "__heap_end" (global 7)) + (export "__memory_base" (global 8)) + (export "__table_base" (global 9))) diff --git a/src/test/app/wasm_fixtures/fib.c b/src/test/app/wasm_fixtures/fib.c new file mode 100644 index 00000000000..4410923054f --- /dev/null +++ b/src/test/app/wasm_fixtures/fib.c @@ -0,0 +1,12 @@ +// typedef long long mint; +typedef int mint; + +mint +fib(mint n) +{ + if (!n) + return 0; + if (n <= 2) + return 1; + return fib(n - 1) + fib(n - 2); +} diff --git a/src/test/app/wasm_fixtures/fixtures.cpp b/src/test/app/wasm_fixtures/fixtures.cpp new file mode 100644 index 00000000000..ea46b49d398 --- /dev/null +++ b/src/test/app/wasm_fixtures/fixtures.cpp @@ -0,0 +1,10326 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +// TODO: consider moving these to separate files (and figure out the build) + +#include + +extern std::string const fibWasmHex = + "0061736d0100000001090260000060017f017f0303020001071b02115f5f" + "7761736d5f63616c6c5f63746f727300000366696200010a440202000b3f" + "01017f200045044041000f0b2000410348044041010f0b200041026a2100" + "0340200041036b100120016a2101200041026b220041044a0d000b200141" + "016a0b"; + +extern std::string const b58WasmHex = + "0061736d0100000001150460000060017f017f60017f0060047f7f7f7f01" + "7f0305040001020305030100020607017f0041d0080b074906066d656d6f" + "72790200115f5f7761736d5f63616c6c5f63746f7273000008616c6c6f63" + "617465000106655f6461746103000a6465616c6c6f636174650002076235" + "38656e636f00030ae8050402000b3401017f024020004180084a0d0041c0" + "082802002200411f4a0d0041c008200041016a3602002000410a7441d008" + "6a21010b20010b02000baa0501097f41d088060240200341004c0d000340" + "200220066a2d00000d012003200641016a2206470d000b200321060b2003" + "20066b220c418a016c41e4006d220741106a4170716b21090240200c4100" + "480d00200741016a220a410771210541002104200741074f0440200a41f8" + "ffff1f71210a0340200420096a4200370300200a200441086a2204470d00" + "0b0b2005450d00200420096a21040340200441003a0000200441016a2104" + "200541016b22050d000b0b200320064a0440200621052007210403402002" + "20056a2d0000210802402004220a20074e0440200721042008450d010b20" + "0721040340200420096a220b200b2d000041087420086a220b200b413a6d" + "2208413a6c6b3a00002004450440410021040c020b200441016b2204200a" + "4a0d00200b413a6b418d7f490d000b0b200541016a22052003470d000b0b" + "200741016a22022103410021040240200c4100480d000340200420096a2d" + "00000d012002200441016a2204470d000b200221040b2001200320066a20" + "046b4a047f02402006450d002006410771210841002105200641084f0440" + "200641787121010340200020056a42b1e2c48993a6cc9831370000200120" + "0541086a2205470d000b0b2008450d00200020056a21050340200541313a" + "0000200541016a2105200841016b22080d000b0b0240200420074a0d0020" + "0420076a410171047f200405200020066a200420096a2d00004180086a2d" + "00003a0000200641016a2106200441016a0b210520042007460d00200520" + "096a2101200720056b2102200020066a2103417f21040340200320046a22" + "0741016a200120046a220541016a2d00004180086a2d00003a0000200741" + "026a200541026a2d00004180086a2d00003a00002002200441026a220447" + "0d000b200420066a41016a21060b200020066a41003a0000200641016a05" + "41000b0b0b4101004180080b3a3132333435363738394142434445464748" + "4a4b4c4d4e505152535455565758595a6162636465666768696a6b6d6e6f" + "707172737475767778797a00490f7461726765745f666561747572657304" + "2b0f6d757461626c652d676c6f62616c732b087369676e2d6578742b0f72" + "65666572656e63652d74797065732b0a6d756c746976616c7565"; + +extern std::string const sha512PureWasmHex = + "0061736d0100000001130460000060017f017f60017f0060027f7f017f03" + "05040001020305030100020607017f0041800d0b075006066d656d6f7279" + "0200115f5f7761736d5f63616c6c5f63746f7273000008616c6c6f636174" + "65000106655f6461746103000a6465616c6c6f6361746500020e73686135" + "31325f70726f6365737300030aa4060402000b0f0041800d410020004180" + "80024d1b0b02000b8b0602147e037f200141ff006a41ff014f044041c08c" + "06211620014180016d41016bac210b41808d02290300210c41888d022903" + "00210d41908d02290300210e41988d02290300210f41a08d022903002110" + "41a88d02290300211141b08d02290300211241b88d022903002113034041" + "002101200c21092013210a201221082011210520102103200f2115200e21" + "06200d2102034020022107200120166a200020016a290000220242388620" + "024280fe0383422886842002428080fc0783421886200242808080f80f83" + "4208868484200242088842808080f80f832002421888428080fc07838420" + "024228884280fe03832002423888848484220237030020014180086a2903" + "00200a200322044232892004422e89852004421789857c2008220a200442" + "7f858320052208200483847c7c20027c2203200922024224892002421e89" + "85200242198985200220072006221485832006200783857c7c2109200320" + "157c2103200421052006211520072106200141086a2201418001470d000b" + "200020016a21004180092117411e210103402002210620162001410e6b41" + "0f714103746a221820182903002016200141056b410f714103746a290300" + "20162001410d6b410f714103746a2903002202423f892002423889852002" + "420788857c7c20162001410f714103746a2903002202422d892002420389" + "852002420688857c22023703002017290300200a20032205423289200542" + "2e89852005421789857c2005427f852008832004200583847c7c20027c22" + "03200922024224892002421e898520024219898520022006200785832006" + "200783857c7c2109200320147c2103201741086a21172008210a20042108" + "200521042007211420062107200141016a220141de00470d000b41b88d02" + "200a20137c221337030041b08d02200820127c221237030041a88d022004" + "20117c221137030041a08d02200320107c221037030041988d02200f2014" + "7c220f37030041908d022007200e7c220e37030041888d022002200d7c22" + "0d37030041808d022009200c7c220c370300200b420052200b42017d210b" + "0d000b0b41808d020b0b880501004180080b800522ae28d7982f8a42cd65" + "ef23914437712f3b4deccffbc0b5bcdb8981a5dbb5e938b548f35bc25639" + "19d005b6f111f1599b4f19afa4823f9218816ddad55e1cab420203a398aa" + "07d8be6f7045015b83128cb2e44ebe853124e2b4ffd5c37d0c556f897bf2" + "745dbe72b196163bfeb1de803512c725a706dc9b942669cf74f19bc1d24a" + "f19ec1699be4e3254f388647beefb5d58c8bc69dc10f659cac77cca10c24" + "75022b596f2ce92d83e4a66eaa84744ad4fb41bddca9b05cb5531183da88" + "f976abdf66ee52513e981032b42d6dc631a83f21fb98c82703b0e40eefbe" + "c77f59bfc28fa83df30be0c625a70a934791a7d56f8203e05163ca06706e" + "0e0a67292914fc2fd246850ab72726c9265c38211b2eed2ac45afc6d2c4d" + "dfb3959d130d3853de63af8b54730a65a8b2773cbb0a6a76e6aeed472ec9" + "c2813b358214852c72926403f14ca1e8bfa2013042bc4b661aa89197f8d0" + "708b4bc230be5406a3516cc71852efd619e892d110a96555240699d62a20" + "715785350ef4b8d1bb3270a06a10c8d0d2b816c1a41953ab4151086c371e" + "99eb8edf4c774827a8489be1b5bcb034635ac9c5b30c1c39cb8a41e34aaa" + "d84e73e363774fca9c5ba3b8b2d6f36f2e68fcb2ef5dee828f74602f1743" + "6f63a57872abf0a11478c884ec39641a0802c78c281e6323faffbe90e9bd" + "82deeb6c50a41579c6b2f7a3f9be2b5372e3f27871c69c6126eace3e27ca" + "07c2c021c7b886d11eebe0cdd67ddaea78d16eee7f4f7df5ba6f1772aa67" + "f006a698c8a2c57d630aae0df9be04983f111b471c13350b711b847d0423" + "f577db289324c7407babca32bcbec9150abe9e3c4c0d109cc4671d43b642" + "3ecbbed4c54c2a7e65fc9c297f59ecfad63aab6fcb5f1758474a8c19446c" + "00490f7461726765745f6665617475726573042b0f6d757461626c652d67" + "6c6f62616c732b087369676e2d6578742b0f7265666572656e63652d7479" + "7065732b0a6d756c746976616c7565"; + +extern std::string const zkProofWasmHex = + "0061736d0100000001600f60037f7f7f017f60027f7f017f60027f7f0060" + "037f7f7f0060000060057f7f7f7f7f0060047f7f7f7f0060067f7f7f7f7f" + "7f0060017f017f6000017f60017f0060047f7f7f7f017f60027e7e017f60" + "057f7f7f7f7f017f60057f7e7e7e7e00038c018a01030402030202020302" + "030505030206020601000006010606070303080202020302090208020202" + "030a0806020a030b06060202030302020303030203030203020202010302" + "030203060a02000202080a020c0807010d02030206060102020803080302" + "030202020a02060303020a03020301010a0d030101010001010301020604" + "0a0a020200000e000004050170010e0e05030100110619037f01418080c0" + "000b7f0041bd97c0000b7f0041c097c0000b075d06066d656d6f72790200" + "08616c6c6f63617465001b13646573657269616c697a655f67315f776173" + "6d001c1462656c6c6d616e5f67726f746831365f7465737400210a5f5f64" + "6174615f656e6403010b5f5f686561705f6261736503020914010041010b" + "0d15767778717e830111547d137a7b0ad6f3048a014b01017f0240024002" + "4020010d00410021010c010b2002450d01200120026e2203200320026c20" + "01476a21010b2000200136020820004101360204200020013602000f0b10" + "8180808000000b4701017f23808080800041206b22002480808080002000" + "41003602182000410136020c200041e090c0800036020820004204370210" + "200041086a41fc82c0800010a480808000000b0f002000200141e8001083" + "808080000b170002402000450d002001200020026c108d808080000b0b0e" + "002000200141011083808080000b0f002000200141a0021083808080000b" + "0e002000200141201083808080000b4201017f0240200028020822032000" + "280200470d00200020021088808080000b2000280204200341e8006c6a20" + "0141e8001086818080001a2000200341016a3602080b5a01017f23808080" + "800041106b2202248080808000200241086a20002000280200410141e800" + "108b80808000024020022802082200418180808078460d00200020022802" + "0c2001108c80808000000b200241106a2480808080000b6401027f238080" + "80800041106b2203248080808000200341086a20024101410141f081c080" + "00108a8080800020032802082104200328020c2001200210868180800021" + "01200020023602082000200136020420002004360200200341106a248080" + "8080000b6401017f23808080800041106b2205248080808000200541046a" + "200120022003108e8080800020052802082103024020052802040d002000" + "200528020c36020420002003360200200541106a2480808080000f0b2003" + "200528020c2004108c80808000000bfd0102037f017e2380808080004110" + "6b22052480808080004100210602400240200220036a22032002490d0020" + "0441076a417871ad2001280200220741017422022003200220034b1b2202" + "4104200241044b1b2203ad7e2208422088a70d002008a7220241f8ffffff" + "074b0d01024002402007450d00024020040d00200541086a4108200210d7" + "80808000200528020821040c020b2001280204200720046c200210cb8080" + "800021040c010b20054108200210d780808000200528020021040b024020" + "040d00410821060c020b2001200336020020012004360204418180808078" + "21060b0b2000200236020420002006360200200541106a2480808080000b" + "1200024020000d00200210cf808080000b000b6c01027f02400240200041" + "7c6a2802002202417871220341044108200241037122021b20016a490d00" + "02402002450d002003200141276a4b0d020b200010c9808080000f0b41e9" + "92c08000419893c0800010ca80808000000b41a893c0800041d893c08000" + "10ca80808000000bc70103017f017e017f23808080800041106b22042480" + "8080800002400240200220036a417f6a410020026b71ad2001ad7e220542" + "2088a70d002005a7220341808080807820026b4b0d00024020030d002000" + "200236020841002102200041003602040c020b200441086a2002200310d7" + "80808000024020042802082206450d002000200636020820002001360204" + "410021020c020b2000200336020820002002360204410121020c010b2000" + "4100360204410121020b20002002360200200441106a2480808080000b88" + "0303017f097e017f23808080800041306b22022480808080002002420042" + "002001290330220342abd5feffffffbfffb97f56ad7d2204200129033822" + "057d220642ffffcf8aebffffd51e7c220720052003842001290340220884" + "20012903482209842001290350220a842001290358220b8450220c1b3703" + "082002420042abd5feffffffbfffb97f20037d200c1b3703002002420020" + "042004200554ad7d2007200654ad7c423f87220320087d220442a4ecc3b5" + "8fd4b498e7007c2205200c1b3703102002420020032003200854ad7d2005" + "200454ad7c423f87220320097d220442bfa5949ccff0d2bbe4007c220520" + "0c1b3703182002420020032003200954ad7d2005200454ad7c423f872203" + "200a7d220442d7d9ae9ae4f6e98dcb007c2205200c1b3703202002420020" + "032003200a54ad7d2005200454ad7c423f87200b7d429acdffcba3bdc480" + "1a7c200c1b370328200041306a200241e086c0800020012d0060220c1090" + "80808000200020014130108681808000200c3a0060200241306a24808080" + "80000b9e0101027e20002002290328200129032822048542002003ad42ff" + "01837d220583200485370328200020022903202001290320220485200583" + "200485370320200020022903182001290318220485200583200485370318" + "200020022903102001290310220485200583200485370310200020022903" + "082001290308220485200583200485370308200020022903002001290300" + "2204852005832004853703000bec0201057f23808080800041c0006b2202" + "248080808000410121030240200128021c2204418082c080004111200128" + "0220220528020c220611808080800080808080000d000240024020012d00" + "144104710d0041012103200441fa8ec08000410120061180808080008080" + "8080000d02200141e091c080004102109280808000450d010c020b200441" + "fb8ec080004102200611808080800080808080000d014101210320024101" + "3a0017200241186a41086a200141086a290200370300200241186a41106a" + "200141106a290200370300200241186a41186a200141186a280200360200" + "2002200536020c20022004360208200241dc8ec080003602382002200129" + "02003703182002200241176a3602102002200241086a360234200241186a" + "41e091c0800041021092808080000d01200241086a41f88ec08000410210" + "93808080000d010b200441ec8cc080004101200611808080800080808080" + "0021030b200241c0006a24808080800020030bbf0b010b7f024002400240" + "200028020022032000280208220472450d0002402004410171450d002001" + "20026a210502400240200028020c22060d0041002107200121080c010b41" + "00210741002109200121080340200822042005460d020240024020042c00" + "002208417f4c0d00200441016a21080c010b0240200841604f0d00200441" + "026a21080c010b0240200841704f0d00200441036a21080c010b20044104" + "6a21080b200820046b20076a21072006200941016a2209470d000b0b2008" + "2005460d00024020082c00002204417f4a0d0020044160491a0b02400240" + "2007450d00024020072002490d0020072002460d01410021040c020b2001" + "20076a2c000041404e0d00410021040c010b200121040b2007200220041b" + "21022004200120041b21010b024020030d00200028021c20012002200028" + "022028020c11808080800080808080000f0b2000280204210a0240200241" + "10490d0020022001200141036a417c7122076b22096a220b410371210341" + "00210641002104024020012007460d004100210402402009417c4b0d0041" + "0021044100210503402004200120056a22082c000041bf7f4a6a20084101" + "6a2c000041bf7f4a6a200841026a2c000041bf7f4a6a200841036a2c0000" + "41bf7f4a6a2104200541046a22050d000b0b200121080340200420082c00" + "0041bf7f4a6a2104200841016a2108200941016a22090d000b0b02402003" + "450d002007200b417c716a22082c000041bf7f4a210620034101460d0020" + "0620082c000141bf7f4a6a210620034102460d00200620082c000241bf7f" + "4a6a21060b200b4102762105200620046a21060340200721032005450d04" + "200541c001200541c001491b220b410371210c200b410274210d41002108" + "024020054104490d002003200d41f007716a210941002108200321040340" + "200428020c2207417f734107762007410676724181828408712004280208" + "2207417f7341077620074106767241818284087120042802042207417f73" + "41077620074106767241818284087120042802002207417f734107762007" + "4106767241818284087120086a6a6a6a2108200441106a22042009470d00" + "0b0b2005200b6b21052003200d6a2107200841087641ff81fc0771200841" + "ff81fc07716a418180046c41107620066a2106200c450d000b2003200b41" + "fc01714102746a22082802002204417f7341077620044106767241818284" + "08712104200c4101460d0220082802042207417f73410776200741067672" + "41818284087120046a2104200c4102460d0220082802082208417f734107" + "7620084106767241818284087120046a21040c020b024020020d00410021" + "060c030b2002410371210802400240200241044f0d004100210641002109" + "0c010b41002106200121042002410c71220921070340200620042c000041" + "bf7f4a6a200441016a2c000041bf7f4a6a200441026a2c000041bf7f4a6a" + "200441036a2c000041bf7f4a6a2106200441046a21042007417c6a22070d" + "000b0b2008450d02200120096a21040340200620042c000041bf7f4a6a21" + "06200441016a21042008417f6a22080d000c030b0b200028021c20012002" + "200028022028020c11808080800080808080000f0b200441087641ff811c" + "71200441ff81fc07716a418180046c41107620066a21060b02400240200a" + "20064d0d00200a20066b2105024002400240410020002d00182204200441" + "03461b22040e03020001020b20052104410021050c010b20054101762104" + "200541016a41017621050b200441016a2104200028021021092000280220" + "2108200028021c210703402004417f6a2204450d02200720092008280210" + "1181808080008080808000450d000b41010f0b200028021c200120022000" + "28022028020c11808080800080808080000f0b0240200720012002200828" + "020c1180808080008080808000450d0041010f0b41002104034002402005" + "2004470d0020052005490f0b200441016a21042007200920082802101181" + "808080008080808000450d000b2004417f6a2005490bdf04010c7f200141" + "7f6a21032000280204210420002802002105200028020821064100210741" + "002108410021094100210a02400340200a4101710d010240024020092002" + "4b0d000340200120096a210a0240024002400240200220096b220b41074b" + "0d0020022009470d01200221090c050b02400240200a41036a417c71220c" + "200a6b220d450d00410021000340200a20006a2d0000410a460d05200d20" + "0041016a2200470d000b200d200b41786a220e4d0d010c030b200b41786a" + "210e0b03404180828408200c2802002200418a94a8d000736b2000724180" + "828408200c41046a2802002200418a94a8d000736b200072714180818284" + "7871418081828478470d02200c41086a210c200d41086a220d200e4d0d00" + "0c020b0b410021000340200a20006a2d0000410a460d02200b200041016a" + "2200470d000b200221090c030b0240200d200b470d00200221090c030b20" + "0a200d6a210c2002200d6b20096b210b4100210002400340200c20006a2d" + "0000410a460d01200b200041016a2200470d000b200221090c030b200020" + "0d6a21000b200020096a220c41016a21090240200c20024f0d00200a2000" + "6a2d0000410a470d004100210a2009210d200921000c030b200920024d0d" + "000b0b20082002460d024101210a2008210d200221000b0240024020062d" + "0000450d00200541f48ec080004104200428020c11808080800080808080" + "000d010b200020086b210b4100210c024020002008460d00200320006a2d" + "0000410a46210c0b200120086a21002006200c3a0000200d210820052000" + "200b200428020c1180808080008080808000450d010b0b410121070b2007" + "0ba80101017f23808080800041306b220424808080800020042003360208" + "20042002360204200420012d00c80122033a000f024020034101460d0020" + "04420137021c200441013602142004419482c08000360210200441818080" + "800036022c2004200441286a3602182004200441046a3602282004410f6a" + "41c886c08000200441106a419c82c08000109680808000000b2000200141" + "c8011086818080001a200441306a2480808080000b140020012000280200" + "20002802041092808080000b4401017f23808080800041106b2204248080" + "8080002004200136020c20042000360208200441086a41b886c080002004" + "410c6a41b886c080002002200310d380808000000ba70101017f23808080" + "800041306b22042480808080002004200336020820042002360204200420" + "012d006822033a000f024020034101460d002004420137021c2004410136" + "02142004419482c08000360210200441818080800036022c200420044128" + "6a3602182004200441046a3602282004410f6a41c886c08000200441106a" + "419c82c08000109680808000000b2000200141e8001086818080001a2004" + "41306a2480808080000b45000240024020042003490d0020022004490d01" + "2000200420036b3602042000200120036a3602000f0b2003200420051099" + "80808000000b200420022005109a80808000000b0f0020002001200210fc" + "80808000000b0f0020002001200210f580808000000b4001017f23808080" + "800041106b2201248080808000200141086a200041014101419883c08000" + "108a80808000200128020c2100200141106a24808080800020000b9a0101" + "017f23808080800041b0016b2202248080808000200241086a2001280204" + "20012802084100413041a883c080001098808080000240200228020c4130" + "460d00200241106a41b883c08000109d80808000000b20024180016a2002" + "28020841301089818080001a200241106a20024180016a109e8080800020" + "00200241106a41c883c080004118109780808000200241b0016a24808080" + "80000b970101017f23808080800041c0006b22022480808080002002412b" + "36020c200241f880c08000360208200241e880c080003602142002200036" + "02102002410236021c200241cc8ec0800036021820024202370224200241" + "8280808000ad422086200241106aad843703382002418380808000ad4220" + "86200241086aad843703302002200241306a360220200241186a200110a4" + "80808000000ba50801077f23808080800041c0086b220224808080800020" + "012d0000220341077610a3808080002104200341067641017110a3808080" + "002105200341057641017110a3808080002106200241a0066a2001413010" + "86818080001a200220022d00a006411f713a00a006200241e8006a200241" + "a0066a10dc80808000200241b0076a410041301085818080001a200241c0" + "026a200241b0076a200241e8006a20022d00980122071090808080002002" + "4190056a10a8808080002002200520047110a380808000200610d2808080" + "007110a380808000200241c0026a10a9808080007110a38080800022013a" + "00f805200110d2808080002108200241a0066a200241c0026a10bd808080" + "0020024180046a200241a0066a200241c0026a10a780808000200241e007" + "6a20024180046a418089c0800010b98080800020024180046a200241e007" + "6a41c087c0800010df80808000200241a0066a20024180046a10bd808080" + "00200241a0066a200241e0076a10db808080002103200241f0026a200241" + "80046a41301086818080001a200220033a00a00320024100413010858180" + "800022024190086a2002200241f0026a2003109080808000200241a0066a" + "20024190086a10b28080800020024180046a41306a20024190086a200241" + "a0066a200620024190086a10de808080007310a380808000109080808000" + "20024180046a200241c0026a41301086818080001a20032004200510d280" + "8080007110a3808080007110a3808080002103200241a0066a2002418004" + "6a41e0001086818080001a200220033a008807200220053a008007200241" + "d0016a20024190056a200241a0066a200810aa8080800020022007200120" + "03200173410020086b71737110a3808080003a00b802200241e8006a10a8" + "808080002002200241e8006a200241d0016a20022d00b802220310aa8080" + "8000200241a0066a200210a58080800020024190056a200241a0066a10e4" + "8080800020024180046a20024190056a10e480808000200241f0026a2002" + "4180046a10e58080800020024190056a200241e8001086818080001a2002" + "4190056a41b089c0800010dd80808000200241a0066a20024190056a10a5" + "80808000200241b0076a200241f0026a200241a0066a41e0006a220510a7" + "80808000200241e0076a200241a0066a200241f0026a41e0006a220110a7" + "8080800020024190086a200241f0026a41306a200510a780808000200241" + "80046a200241a0066a41306a200110a7808080002003200110a980808000" + "2201200510a98080800022057110a380808000200110d280808000200510" + "d2808080007110a380808000200241b0076a200241e0076a10db80808000" + "7110a38080800020024190086a20024180046a10db808080007110a38080" + "80007210a3808080007110a38080800021052000200241e8001086818080" + "0020053a0068200241c0086a2480808080000b970101017f238080808000" + "41c0026b2203248080808000200341086a20012002410041e00041e083c0" + "80001098808080000240200328020c41e000460d00200341106a41f083c0" + "8000109d80808000000b200341e0016a200328020841e000108981808000" + "1a200341106a200341e0016a10a0808080002000200341106a41c883c080" + "004118109480808000200341c0026a2480808080000bff1d02137f017e23" + "808080800041a0276b220224808080800020012d0000220341077610a380" + "8080002104200341067641017110a3808080002105200341057641017110" + "a380808000210620024180106a200141301086818080001a200220022d00" + "8010411f713a008010200241a0216a20024180106a10dc80808000200241" + "80226a200141306a10dc80808000200241e01f6a41004130108581808000" + "1a200241801f6a200241e01f6a200241a0216a20022d00d0212207109080" + "80800020022d00b0222101200241c0206a410041301085818080001a2002" + "41e0226a200241c0206a20024180226a2001109080808000200241e0226a" + "41306a200241801f6a41301086818080001a200241e00d6a10e780808000" + "2002200520047110a380808000200610d2808080007110a3808080002002" + "41e0226a10e0808080007110a38080800022033a00a80f200310d2808080" + "00210820024180106a200241e0226a10ba80808000200241c00b6a200241" + "80106a200241e0226a10b380808000200241c0236a200241c00b6a41e089" + "c0800010bc80808000200241c0236a10e08080800021032002410041e000" + "108581808000220220033a0060200310d2808080002109200241a0246a20" + "0241c0236a41a088c0800010e38080800020024180106a200241a0246a10" + "ba8080800020024180256a20024180106a200241c0236a10b38080800020" + "0241e0256a200241a0246a200241c0236a10b38080800020024180106a20" + "0241e0256a41306a10b28080800020024180106a41306a200241e0256a41" + "30108681808000210a200241d0016a41306a410041301085818080001a20" + "0241d0016a41e086c0800041301086818080001a200241c0266a200241d0" + "016a10e28080800020024180256a200241c0266a10c28080800021032002" + "41c00b6a20024180106a41e0001086818080001a200220033a00a00c2003" + "10d280808000210b200a41004130108581808000210320024180106a41e0" + "86c0800041301086818080001a20024180076a20024180256a2002418010" + "6a10bc8080800020024198036a20024180076a41d088c0800010e3808080" + "0020024180106a20024198036a200241e0256a10b3808080002002410110" + "a3808080003a00e01020024180076a200241c00b6a20024180106a200b10" + "da80808000200241c00b6a410041e0001085818080001a20024198036a20" + "0241c00b6a20024180076a20022d00e007220a10b0808080002002418010" + "6a20024198036a10ba80808000200a20024180106a200241c0236a10c280" + "8080007110a380808000210a20024180106a20024198036a41e000108681" + "8080001a2002200a3a00e01020024180076a200220024180106a200910da" + "808080002002410041e00010858180800022024198036a20022002418007" + "6a20022d00e007220910b08080800020024180106a20024198036a10e280" + "808000200241c00b6a41e0006a220b20024198036a20024180106a200620" + "024198036a41306a220a10de80808000200a10a98080800020024198036a" + "10de808080007110a3808080007210a3808080007310a38080800010b080" + "808000200241c00b6a200241e0226a41e0001086818080001a2009200420" + "0510d2808080007110a3808080007110a380808000210420024180106a20" + "0241c00b6a41c0011086818080001a200220043a00c811200220053a00c0" + "11200241c00b6a200241e00d6a20024180106a200810d980808000200120" + "0420022d00a80f220573410020086b712005737110a38080800021012002" + "200241c00b6a41c801108681808000220241cc016a200241c00b6a41cc01" + "6a280000360000200220022800890d3600c9012002200120077110a38080" + "8000220c3a00c80120024198036a10e780808000200241d0016a20024198" + "036a2002200c10d980808000200241e0046a200241d0016a10e880808000" + "200241c00b6a410041301085818080001a200242ba8a92abf1a7dbf21437" + "03980c200242e8a0ee96fe89bcf2143703900c200242a4a0a0f4c7f1c686" + "a27f3703880c200242acfced84e38c82c4d0003703800c200242d5cb9694" + "b3cac8f92a3703f80b200242c38bd5b3c8bcf286897f3703f00b200242d2" + "8ff6dfdbdddf950e3703b80e2002429df8bab6e9ac96d12d3703b00e2002" + "42a7a9d3d3fd9088e5513703a80e200242f1fdbada86bba3842f3703a00e" + "200242fcfcc9d492d8f78b5c3703980e200242da9f8cd5a5f4e9e7fb0037" + "03900e200242c8bd89ecc7dfe4ea0b3703880e200242b9e1f3e3fac9d3bc" + "1d3703800e20024298fcc0c8d1dfcad6927f3703f80d200242b2ee88db88" + "999194383703f00d200242838386b6d8a788cac2003703e80d200242d1b5" + "f2aada8bd6973e3703e00d2003200241e0046a41306a10b2808080002002" + "4180106a200241e0046a41301086818080001a20024180076a2002418010" + "6a200241c00b6a10b3808080002003200241f0056a10b280808000200241" + "80106a200241e0046a41e0006a220141301086818080001a20024180076a" + "41e0006a220d20024180106a200241e00d6a10b3808080002003200241d0" + "066a10b28080800020024180106a200241e0046a41c0016a220541301086" + "818080001a20024180076a41c0016a20024180106a41e000108681808000" + "210e2003410041301085818080001a20024180106a41e086c08000413010" + "86818080001a200241a0096a410041e0001085818080001a200241a0096a" + "41e0006a20024180106a41e0001086818080002109200241a0096a41c001" + "6a410041e000108581808000210a200241c0266a41306a210f2002418010" + "6a41e0006a2110200241e00d6a41e0006a211120024180106a41c0016a21" + "12200241c00b6a41c0016a2113200241e00d6a41c0016a21144280808280" + "8080a080e9002115024003402015500d01200241e0196a200110ba808080" + "00200241c01a6a200241e0196a200241e0196a10bc80808000200241a01b" + "6a200241c01a6a200241c01a6a10bc80808000200241801c6a200241a01b" + "6a200241a01b6a10bc80808000200241e01c6a2001200510b38080800020" + "0241c01d6a200510ba80808000200241a01e6a200241c01d6a41c08ac080" + "0010b380808000200241801f6a200241a01e6a200241801c6a10b3808080" + "00200241e01f6a200241e0196a200241a01e6a10bc80808000200241c020" + "6a200241e01c6a200241801c6a10b380808000200241a0216a200241a01e" + "6a200241a01e6a10bc8080800020024180226a200241a0216a200241a01e" + "6a10bc80808000200241e0226a200241e0196a20024180226a10bb808080" + "00200241c0236a200241e0226a200241e01f6a10b380808000200241a024" + "6a200241801f6a200241c0236a10bc8080800020024180256a200241e004" + "6a200110b380808000200241e0256a200241e0226a20024180256a10b380" + "808000200241e00d6a200241e0256a200241e0256a10bc80808000201120" + "0241a0246a41e00010868180800021082014200241c0206a41e000108681" + "8080002107200f410041301085818080001a200241c0266a41e086c08000" + "41301086818080001a20024180106a410041e0001085818080001a201020" + "0241c0266a41e00010868180800021042012410041e00010858180800021" + "06200241c00b6a200241e00d6a20024180106a200510e080808000220310" + "b080808000200b20082004200310b080808000201320072006200310b080" + "808000200241e0046a200241c00b6a41a0021086818080001a0240201542" + "0183500d00200241a0126a200241a0096a200241e0046a10b38080800020" + "024180136a2009200110b380808000200241e0136a200a200510b3808080" + "00200241c0146a200241a0096a200910bc80808000200241a0156a200241" + "e0046a200110bc8080800020024180166a200241c0146a200241a0156a10" + "b380808000200241e0166a200241a0126a20024180136a10bc8080800020" + "0241c0176a20024180166a200241e0166a10bb80808000200241a0186a20" + "09200a10bc8080800020024180196a2001200510bc80808000200241e019" + "6a200241a0186a20024180196a10b380808000200241c01a6a2002418013" + "6a200241e0136a10bc80808000200241a01b6a200241e0196a200241c01a" + "6a10bb80808000200241801c6a200241a0096a200a10bc80808000200241" + "e01c6a200241e0046a200510bc80808000200241c01d6a200241801c6a20" + "0241e01c6a10b380808000200241a01e6a200241a0126a200241e0136a10" + "bc80808000200241801f6a200241c01d6a200241a01e6a10bb8080800020" + "0241e01f6a200241a0126a200241a0126a10bc80808000200241c0206a20" + "0241e01f6a200241a0126a10bc80808000200241a0216a200241e0136a41" + "c08ac0800010b38080800020024180226a20024180136a200241a0216a10" + "bc80808000200241e0226a20024180136a200241a0216a10bb8080800020" + "0241c0236a200241801f6a41c08ac0800010b380808000200241a0246a20" + "0241a01b6a200241c0236a10b38080800020024180256a200241c0176a20" + "0241e0226a10b38080800020024180106a20024180256a200241a0246a10" + "bb80808000200241e0256a200241c0236a200241c0206a10b38080800020" + "0241c0266a200241e0226a20024180226a10b3808080002004200241c026" + "6a200241e0256a10bc80808000200241c00b6a200241c0206a200241c017" + "6a10b380808000200241e00d6a20024180226a200241a01b6a10b3808080" + "002006200241e00d6a200241c00b6a10bc80808000200241a0096a200241" + "80106a41a0021086818080001a0b201542018821150c000b0b2002418010" + "6a41e0006a200910e28080800020024180106a41c0016a200a41e0001086" + "818080001a20024180106a200241a0096a41e0001086818080001a200241" + "a0096a20024180106a41a0021086818080001a200241c0266a2002418007" + "6a200241a0096a41c0016a220110b380808000200241c00b6a200241a009" + "6a200e10b380808000200241e00d6a200d200110b3808080002002418010" + "6a200241a0096a41e0006a200e10b380808000200e10e080808000220520" + "0110e08080800022017110a380808000200510d280808000200110d28080" + "80007110a380808000200241c0266a200241c00b6a10c2808080007110a3" + "80808000200241e00d6a20024180106a10c2808080007110a38080800072" + "10a380808000200c7110a38080800021012000200241d0016a41c8011086" + "8180800020013a00c801200241a0276a2480808080000ba0d50103097f25" + "7e347f23808080800041e0ec006b2200248080808000200042d2b4bbf88c" + "a0d28d053700f40c2000428dcfdee5fd81c2bb0c3700ec0c200042afbed3" + "efd9fc81acea003700e40c20004283c4c699c3e0e5bf313700dc0c200042" + "869e99a9baa4ebe5e5003700d40c2000428dbfe3e0ae86d0a7b27f3700cc" + "0c200042908484d9e8fa99f80e3700c40c2000428bdfe7adc3a8cae04f37" + "00bc0c200042d687f295e888f880cd003700b40c20004281ddcf86b5f2d0" + "cf633700ac0c200042aef2a7aaae91d5accb003700a40c200042eb8fbebf" + "aee5caf4967f37009c0c200042b9b3d69fbf86ace8bb7f3700940c200042" + "d4fa86d5a0e3d296a87f37008c0c200042c5eddc9291a0c9e3a27f370084" + "0c2000428594fecef0de91d0643700fc0b20004289ae81b0d7a1feb5d300" + "3700f40b200042d4f18391eaffb8ed2e3700ec0b2000428cc8d9c6afddd3" + "d2ca003700e40b200042bca4908cdbc4caa54e3700dc0b200042b9cfe7bf" + "d99fbcbd563700d40b200042a4f788c3999fcac2c6003700cc0b200042b7" + "93c2cbbcbec3ee8e7f3700c40b200042a188aeeaaf8e90ba9b7f3700bc0b" + "200042c1fb969fd3cb97a0f5003700b40b200042ff9ce790fc9fe0fa6837" + "00ac0b200042b2dcb096dfcda7b9293700a40b200042a9e3f3c0c2c5cf85" + "2a37009c0b200042ad95c395bdd085ec393700940b200042c1f0c9e1f6d5" + "88e04537008c0b200042cfe1a7fed79ab1b2da003700840b200042d38490" + "85a5b6dff17d3700fc0a200042daf4a7a781f39dc7f8003700f40a200042" + "b88d9b949dd3aa86713700ec0a20004286b08ace96d5b8e0493700e40a20" + "0042e291f4f2d7e689e0443700dc0a200042c188fdead38de5d7f1003700" + "d40a200042fec2c2f2fb858b84283700cc0a200042fe8ebfddfaafafefec" + "003700c40a20004291f5b996b996cbc8bf7f3700bc0a200042b497cfc0d9" + "e3f284043700b40a2000428c9691f2e7bca4ec2d3700ac0a20004287e0c3" + "c29eccb3d21c3700a40a200042c8bbf68fceb0ad9eda0037009c0a200042" + "85c5e3e89284a997fd003700940a20004297bd8ec1effea3935437008c0a" + "200042eea8f8adc2cdbed9bb7f3700840a200042f5a3a4828bfd9ac1ac7f" + "3700fc09200042a087bbac98e0e282827f3700f4092000429a8683e6d8cc" + "ddd7113700ec09200042f0e1a982ee8890e33b3700e40920004286f6f2ba" + "80bf8bc3d5003700dc0920004297cfaad29bac9ec8243700d409200042c9" + "d3b292ffc082e01e3700cc09200042a9a3ffacc691beef6a3700c4092000" + "42a2d1f7c2ff94dce2543700bc09200042c78cfef2b8eabef8713700b409" + "20004286edaddda1fbf6baa37f3700ac09200042fdddbb9dedd1e9ef3337" + "00a409200042c6b2d8f2a9dae59d9f7f37009c09200042b59fb2d0b3e4cf" + "e32337009409200042c5c8c2fe9f869487c00037008c09200042ee91eb8f" + "c9a9c69cd1003700840920004283afa5ac9ded86b7253700fc08200042be" + "b9e4bccb88c99f3c3700f408200042c4d7d7c08b8db9e7f5003700ec0820" + "0042bf948bc7d7b1b0fcc1003700e4082000429a9ed5eea2d281c0e70037" + "00dc08200042acf185b19c87b3c3dd003700d40820004294bcf3c5dec192" + "ebb67f3700cc082000429db89ddb8fc9add13b3700c408200042e99baac8" + "a8faa582817f3700bc08200042daccdaad88c1f9b35b3700b408200042b5" + "d48be3dada8f8b223700ac08200042bdfdafd8a0e7aee4d8003700a40820" + "0042b9a7fddeeba08a8a3e37009c08200042e893cdd1ffdb94af08370094" + "08200042b58bef84d587bf842937008c08200042f4d8c597c3f6bd9f5a37" + "008408200042b3ccedc1b3d5cb987f3700fc07200042e0a38ecbbad9b6b8" + "b97f3700f407200042918cc8bfb089f7ab2f3700ec07200042dca8f8e4f3" + "82aee38f7f3700e407200042a3bfc29bc5d8edebca003700dc072000428e" + "81e4d981f589f1283700d40720004296f48083b9fcdab5b67f3700cc0720" + "0042cf938386a9d3d78a023700c4072000429687f1eff8ebacafef003700" + "bc072000429ef0afffc392fc88163700b407200042dbcda6cadfc8f38797" + "7f3700ac07200042cec2c1f9b5a7ec8e773700a407200042a5c192ecc6ad" + "99ef8f7f37009c07200042fd908df7cd8eeaab1837009407200042b18585" + "d2b981fac47637008c072000428af4e7cfa4fac8c4d70037008407200042" + "d6e7eeadc1c4f395a07f3700fc06200042a394d5b790978ebcec003700f4" + "0620004284f5dcaa92b5c09f663700ec06200042dcbedda48ae58eebe000" + "3700e406200042ac8bc7ea9baff0cf1b3700dc06200041940d6a42003700" + "002000418c0d6a4200370000200041840d6a4200370000200042003700fc" + "0c2000419c0d6a200041dc066a4130108980808000200041a80d6a200041" + "9c0d6a109c80808000200041940e6a200041dc066a41306a413010898080" + "8000200041a00e6a200041940e6a109c808080002000418c0f6a200041dc" + "066a41e0006a41e000108980808000200041980f6a20002802900f200028" + "02940f109f80808000200041e4106a2000419c086a41e000108980808000" + "200041f0106a20002802e81020002802ec10109f80808000200041bc126a" + "200041fc086a4130108980808000200041c8126a200041bc126a109c8080" + "8000200041b4136a200041ac096a41e000108980808000200041c0136a20" + "002802b81320002802bc13109f8080800020004188156a2000418c0a6a41" + "900110898080800020004194156a41086a22014100360200200042808080" + "80800137029415200041d0066a200028028c152202200028029015220341" + "004130418084c08000109880808000200041a0156a20002802d006200028" + "02d406108980808000200041b0156a200041a0156a109c80808000200041" + "94156a200041b0156a419084c08000108780808000200041c8066a200220" + "03413041e00041a084c08000109880808000200041b0156a20002802c806" + "20002802cc0610898080800020002802a01520002802a415108480808000" + "200041a0156a41086a2204200041b0156a41086a22052802003602002000" + "20002902b0153703a015200041b0156a200041a0156a109c808080002000" + "4194156a200041b0156a41b084c08000108780808000200041c0066a2002" + "200341e00041900141c084c08000109880808000200041b0156a20002802" + "c00620002802c40610898080800020002802a01520002802a41510848080" + "800020042005280200360200200020002902b0153703a015200041b0156a" + "200041a0156a109c8080800020004194156a200041b0156a41d084c08000" + "108780808000200041c81c6a200128020036020020002000290294153703" + "c01c200041b0156a200041a80d6a41e8001086818080001a200041b0156a" + "41e8006a200041a00e6a41e8001086818080001a20004180176a20004198" + "0f6a41c8011086818080002106200041c8186a200041f0106a41c8011086" + "818080002107200041901a6a200041c8126a41e8001086818080001a2000" + "41f81a6a200041c0136a41c8011086818080002108200041f8326a200041" + "9c0b6a109e80808000200041d01c6a200041f8326a41e084c08000411710" + "9780808000200041f8326a200041cc0b6a10a080808000200041b81d6a20" + "0041f8326a41f784c080004117109480808000200041f8326a200041ac0c" + "6a109e80808000200041801f6a200041f8326a418e85c080004117109780" + "808000200041e81f6a200041d01c6a41e8001086818080001a200041e81f" + "6a41e8006a200041b81d6a41c8011086818080001a20004198226a200041" + "801f6a41e8001086818080001a200041a0e8006a41c00041201080808080" + "0002400240024002400240024020002802a4684101470d00200041b8066a" + "20002802a8684108412041d880c08000108a80808000200041003602c85b" + "200020002802bc0622033602c45b200020002802b80622023602c05b2000" + "41f8326a41c0004120108080808000024020002802fc324101470d004100" + "21050240200220002802803322014f0d00200041b0066a200041c0db006a" + "410020014120108b8080800020002802b0062202418180808078470d0520" + "002802c45b210320002802c85b21050b200041dc0c6a2102200320054105" + "746a210341c000210103402001450d03200041b0046a2002290000220942" + "0042edb8ca9f8fb2facc494200108781808000200041c0046a2009420042" + "a3b8c9bcb8b9bbb62b4200108781808000200041d0046a20094200428ff3" + "d092e792c5e9054200108781808000200041e0046a200942004291fee7fa" + "99bbb6a4074200108781808000200041f0056a2002290008220a420042ed" + "b8ca9f8fb2facc49420010878180800020004180066a200a420042a3b8c9" + "bcb8b9bbb62b420010878180800020004190066a200a4200428ff3d092e7" + "92c5e9054200108781808000200041a0066a200a42004291fee7fa99bbb6" + "a4074200108781808000200041b0056a2002290010220b420042edb8ca9f" + "8fb2facc494200108781808000200041c0056a200b420042a3b8c9bcb8b9" + "bbb62b4200108781808000200041d0056a200b4200428ff3d092e792c5e9" + "054200108781808000200041e0056a200b42004291fee7fa99bbb6a40742" + "00108781808000200041f0046a2002290018220c420042edb8ca9f8fb2fa" + "cc49420010878180800020004180056a200c420042a3b8c9bcb8b9bbb62b" + "420010878180800020004190056a200c4200428ff3d092e792c5e9054200" + "108781808000200041a0056a200c42004291fee7fa99bbb6a40742001087" + "81808000200041a0046a20002903b004220d42ffffffff6f7e220e420042" + "8180808070420010878180800020004190046a200e420042feb7f9ffaf80" + "e9ded3004200108781808000200041c0036a200e42004285b087cd8081f6" + "9c334200108781808000200041f0026a200e420042c8faf5ccb2eae9f6f3" + "00420010878180800020004180046a20002903f005220f20002903c00422" + "10200041b0046a41086a2903007c22117c22122000290390047c22132000" + "41a0046a41086a290300200d20002903a004220e7c200e54ad7c7c220d42" + "ffffffff6f7e220e42004281808080704200108781808000200041f0036a" + "200e420042feb7f9ffaf80e9ded3004200108781808000200041e0036a20" + "0e42004285b087cd8081f69c334200108781808000200041d0036a200e42" + "0042c8faf5ccb2eae9f6f3004200108781808000200041b0036a20004190" + "046a41086a2903002013201254ad7c200d201354ad7c221420002903c003" + "7c2213200041c0046a41086a2903002011201054ad7c221520002903d004" + "7c22102000290380067c2211200041f0056a41086a2903002012200f54ad" + "7c7c221220002903b0057c22167c220f20002903f0037c22172000418004" + "6a41086a290300200029038004220e200d7c200e54ad7c7c220d42ffffff" + "ff6f7e220e42004281808080704200108781808000200041a0036a200e42" + "0042feb7f9ffaf80e9ded300420010878180800020004190036a200e4200" + "4285b087cd8081f69c33420010878180800020004180036a200e420042c8" + "faf5ccb2eae9f6f3004200108781808000200041e0026a200041f0036a41" + "086a2903002017200f54ad7c200d201754ad7c221820002903e0037c2217" + "200041c0036a41086a2903002013201454ad7c200f201354ad7c22192000" + "2903f0027c2213200041d0046a41086a2903002010201554ad7c221a2000" + "2903e0047c220f2000290390067c221420004180066a41086a2903002011" + "201054ad7c2012201154ad7c7c221020002903c0057c2211200041b0056a" + "41086a2903002016201254ad7c7c221220002903f0047c221b7c221c7c22" + "1520002903a0037c2216200041b0036a41086a29030020002903b003220e" + "200d7c200e54ad7c7c220d42ffffffff6f7e220e42004281808080704200" + "108781808000200041d0026a200e420042feb7f9ffaf80e9ded300420010" + "8781808000200041c0026a200e42004285b087cd8081f69c334200108781" + "808000200041b0026a200e420042c8faf5ccb2eae9f6f300420010878180" + "8000200041d0036a41086a290300211d20004180056a41086a290300211e" + "200041d0056a41086a290300211f200041a0066a41086a29030021202000" + "2903e00521212000290390052122200029038003212320004180036a4108" + "6a290300212420004190036a41086a290300212520004190056a41086a29" + "03002126200041e0056a41086a290300212720002903a005212820002903" + "b0022129200041b0026a41086a290300212a20002903c002212b200041c0" + "026a41086a290300212c200020002903d002222d200041e0046a41086a29" + "0300200f201a54ad7c221a20002903a0067c220e20004190066a41086a29" + "03002014200f54ad7c2010201454ad7c7c220f20002903d0057c22142000" + "41c0056a41086a2903002011201054ad7c2012201154ad7c7c2210200029" + "0380057c2211200041f0046a41086a290300201b201254ad7c7c22122000" + "41f0026a41086a2903002013201954ad7c201c201354ad7c7c2213200029" + "03d0037c2219200041e0036a41086a2903002017201854ad7c2015201754" + "ad7c7c22172000290390037c2218200041a0036a41086a29030020162015" + "54ad7c200d201654ad7c7c22167c2215200041e0026a41086a2903002000" + "2903e002221b200d7c201b54ad7c7c221b3703f8322000202b2023202220" + "212020200e201a54ad7c200f200e54ad7c221a7c220e201f2014200f54ad" + "7c2010201454ad7c7c220d7c220f201e2011201054ad7c2012201154ad7c" + "7c22102013201254ad7c2212201d2019201354ad7c2017201954ad7c7c22" + "137c221120252018201754ad7c2016201854ad7c7c22177c2214200041d0" + "026a41086a2903002015202d54ad7c201b201554ad7c7c22153703803320" + "0020292012201054ad2013201254ad7c221620282027200e201a54ad7c20" + "0d200e54ad7c22197c220e2026200f200d54ad7c2010200f54ad7c7c2210" + "7c221220242011201354ad7c2017201154ad7c7c22137c220d202c201420" + "1754ad7c2015201454ad7c7c22113703883320002012201654ad20132012" + "54ad7c200041a0056a41086a290300200e201954ad7c2010200e54ad7c7c" + "202a200d201354ad7c2011200d54ad7c7c37039033200041a0e8006a2000" + "41f8326a10a28080800020002903a068210e20002903a868211220002903" + "b068211320002903b868210d200942ffffffff0f7c200954ad427f7c2209" + "2009200a7c220a200954ad7c200a4282c88680d0ff96a1ac7f7c200a54ad" + "7c427f7c423f872209200b20097c2209200b54ad7c200942fbcff8b2fffe" + "89e34c7c200954ad7c427f7c423f872209200c20097c2209200c54ad7c20" + "0942b8858ab3cd9596898c7f7c200954ad7ca741016a41017110a3808080" + "0021042000411836028457200041a585c0800036028057200020043a00c0" + "52200441ff01714101470d04200341186a200d370300200341106a201337" + "0300200341086a20123703002003200e370300200341206a210320054101" + "6a210520022001412020014120491b22046a2102200120046b21010c000b" + "0b2000410036028833200041013602fc32200041d085c080003602f83220" + "00420437028033200041f8326a41d880c0800010a480808000000b200041" + "0036028833200041013602fc32200041d085c080003602f8322000420437" + "028033200041f8326a41d880c0800010a480808000000b20002802c45b21" + "2e20002802c05b212f200541016a20002802c81c470d0220004180236a20" + "002802c41c220210a580808000200241e8006a2130200041d4d2006a2131" + "200041c0d2006a41086a2132200041a0ce006a2133200041c0db006a4130" + "6a2134200041a0dc006a2135410021040340024020042005470d00200041" + "f8326a20004180236a41e0006a10a68080800041002102200041a0e8006a" + "410041301085818080001a200041c0db006a200041a0e8006a200041f832" + "6a20002d00a833109080808000200041a0e8006a20004180236a200041c0" + "db006a10a780808000200041a0e8006a41306a20004180236a41306a2000" + "41c0db006a10a7808080002000410010a3808080003a008069200041f832" + "6a10a88080800020004190246a200041a0e8006a200041f8326a200041c0" + "db006a10a98080800010aa80808000200041f8246a200041b81d6a10ab80" + "80800020004188256a200710ab8080800020004198256a200810ab808080" + "00200041a8256a200610ab80808000200041b82e6a20004190246a108f80" + "808000200041c0376a200041801f6a108f80808000200041803c6a200041" + "b0156a108f808080002000200041a8256a3602942a2000200041803c6a36" + "02902a200020004198256a36028c2a2000200041c0376a3602882a200020" + "004188256a3602842a2000200041b82e6a3602802a2000200041f8246a36" + "02fc292000200041e81f6a3602f829200042043702c4642000200041f829" + "6a3602c064200041b8256a10ac80808000200041f8326a41a0026a210520" + "0041b8256a41a0026a213620004180d7006a41c0016a213320004180d700" + "6a41e0006a2134200041c0db006a41e0036a2135200041a0e8006a41e003" + "6a2132200041c0db006a4180036a2106200041a0e8006a4180036a210720" + "0041c0db006a41a0026a2108200041a0e8006a41a0026a2131200041c0d2" + "006a41c0016a2137200041c0d2006a41e0006a2138200041c0db006a41c0" + "016a2139200041a0e8006a41c0016a213a200041c0db006a41e0006a213b" + "200041a0e8006a41e0006a213c41c000213d034002400240203d450d0020" + "02410171210342808082808080a080e900203d417f6a223d413f71ad88a7" + "21022003450d02200041f8326a200041b8256a41c0041086818080001a20" + "0041b8256a200041c0e4006a200041f8326a10ad80808000200241017145" + "0d01200041c0db006a200041b8256a41c0041086818080001a20002802c4" + "64410374210120002802c064210320002802c8642130024003402001450d" + "01200328020422042d000c20032802002d00607210a38080800021022000" + "41a0e8006a200041c0db006a200441046a280200200441086a2802002030" + "41dc8cc0800010ae80808000200328020010af80808000200041c0d2006a" + "200041a0e8006a200041c0db006a200210b0808080002038203c203b2002" + "10b0808080002037203a2039200210b08080800020004180d7006a203120" + "08200210b080808000203420072006200210b08080800020332032203520" + "0210b080808000200041f8326a200041c0d2006a41a0021086818080001a" + "200520004180d7006a41a0021086818080001a200041c0db006a200041f8" + "326a41c0041086818080001a200141786a2101200341086a21030c000b0b" + "2000203041016a3602c864200041b8256a200041c0db006a41c004108681" + "8080001a0c010b200041f8326a200041b8256a41c0041086818080001a20" + "0041b8256a200041c0e4006a200041f8326a10ad80808000200041f8326a" + "41a0026a223e203610b180808000200041f8326a200041b8256a41a00210" + "86818080001a200041b8256a200041f8326a41c0041086818080001a2000" + "41f8296a200041b8256a41c0041086818080001a200041c0d2006a41306a" + "2230200041b8256a41306a10b280808000200041c0d2006a200041b8256a" + "41301086818080001a200041c0db006a41306a2201200041b8256a419001" + "6a10b280808000200041c0db006a200041b8256a41e0006a413010868180" + "80001a200041a0e8006a41306a2203200041b8256a41f0016a10b2808080" + "00200041a0e8006a200041b8256a41c0016a41301086818080001a200041" + "f8326a410041301085818080001a200042c18e8ea3d58c88f8183703d033" + "200042d2a1c19ee8addffc033703c8332000429e97eb8de0d783db8e7f37" + "03c03320004295b7949cfdd590b8d8003703b833200042d2cbb6fee1c8c8" + "d5dd003703b033200042f1e0c7b3c8bcf2814d3703a83320004180d7006a" + "41e0006a2232200041c0db006a200041f8326a10b380808000200041f832" + "6a41306a410041301085818080002105200042ba8a92abf1a7dbf2143703" + "a033200042e8a0ee96fe89bcf21437039833200042a4a0a0f4c7f1c686a2" + "7f37039033200042acfced84e38c82c4d00037038833200042d5cb9694b3" + "cac8f92a37038033200042c38bd5b3c8bcf286897f3703f83220004180d7" + "006a41c0016a2204200041a0e8006a200041f8326a10b380808000200041" + "80d7006a200041c0d2006a41e0001086818080001a20004180ce006a4130" + "6a2202200041b8256a41d0026a10b28080800020004180ce006a200041b8" + "256a41a0026a41301086818080001a2030200041b8256a41b0036a10b280" + "808000200041c0d2006a200041b8256a4180036a41301086818080001a20" + "03200041b8256a4190046a10b280808000200041a0e8006a200041b8256a" + "41e0036a41301086818080001a200041f8326a410041301085818080001a" + "200042c18e8ea3d58c88f8183703d033200042d2a1c19ee8addffc033703" + "c8332000429e97eb8de0d783db8e7f3703c03320004295b7949cfdd590b8" + "d8003703b833200042d2cbb6fee1c8c8d5dd003703b033200042f1e0c7b3" + "c8bcf2814d3703a833200041c0db006a41e0006a2235200041c0d2006a20" + "0041f8326a10b3808080002005410041301085818080002133200042ba8a" + "92abf1a7dbf2143703a033200042e8a0ee96fe89bcf21437039833200042" + "a4a0a0f4c7f1c686a27f37039033200042acfced84e38c82c4d000370388" + "33200042d5cb9694b3cac8f92a37038033200042c38bd5b3c8bcf286897f" + "3703f832200041c0db006a41c0016a223b200041a0e8006a200041f8326a" + "10b380808000200041c0db006a20004180ce006a41e0001086818080001a" + "200042afff91c4a8fbbb87113703f86820004289bd83adbef9849c2e3703" + "f068200042d0d1a385a497e78d413703e86820004294a7e7acc2baa5a44f" + "3703e068200042ecf9a5e2bf8da8a1d8003703d868200042c6ac97e7d4d5" + "9afbb27f3703d068200042ebcded87fbc188f9083703c868200042cd9cab" + "eda5fde4f11c3703c068200042eed3f096abd9ebada37f3703b868200042" + "8fc5dc88cd998ff4977f3703b0682000429386aaa8abf2d7b4463703a868" + "200042e5a8e798abaaa584073703a068200041a0e8006a41e0006a410041" + "c0011085818080002108203e200041c0db006a200041a0e8006a10b48080" + "8000200041f8326a20004180d7006a41a0021086818080001a2002203310" + "b28080800020004180ce006a200041f8326a41301086818080001a200041" + "80d7006a41306a2207200041f8326a4190016a10b28080800020004180d7" + "006a200041f8326a41e0006a223f41301086818080001a2001200041f832" + "6a41f0016a10b280808000200041c0db006a200041f8326a41c0016a2240" + "41301086818080001a200041a0e8006a410041301085818080001a200042" + "c18e8ea3d58c88f8183703f868200042d2a1c19ee8addffc033703f06820" + "00429e97eb8de0d783db8e7f3703e86820004295b7949cfdd590b8d80037" + "03e068200042d2cbb6fee1c8c8d5dd003703d868200042f1e0c7b3c8bcf2" + "814d3703d068200041c0d2006a41e0006a223820004180d7006a200041a0" + "e8006a10b3808080002003410041301085818080002103200042ba8a92ab" + "f1a7dbf2143703c868200042e8a0ee96fe89bcf2143703c068200042a4a0" + "a0f4c7f1c686a27f3703b868200042acfced84e38c82c4d0003703b06820" + "0042d5cb9694b3cac8f92a3703a868200042c38bd5b3c8bcf286897f3703" + "a068200041c0d2006a41c0016a2234200041c0db006a200041a0e8006a10" + "b380808000200041c0d2006a20004180ce006a41e0001086818080001a20" + "0041c0c9006a41306a2205200041f8326a41d0026a10b280808000200041" + "c0c9006a203e41301086818080001a2002200041f8326a41b0036a10b280" + "80800020004180ce006a200041f8326a4180036a22414130108681808000" + "1a2001200041f8326a4190046a10b280808000200041c0db006a200041f8" + "326a41e0036a224241301086818080001a200041a0e8006a410041301085" + "818080001a200042c18e8ea3d58c88f8183703f868200042d2a1c19ee8ad" + "dffc033703f0682000429e97eb8de0d783db8e7f3703e86820004295b794" + "9cfdd590b8d8003703e068200042d2cbb6fee1c8c8d5dd003703d8682000" + "42f1e0c7b3c8bcf2814d3703d068203220004180ce006a200041a0e8006a" + "10b3808080002003410041301085818080002143200042ba8a92abf1a7db" + "f2143703c868200042e8a0ee96fe89bcf2143703c068200042a4a0a0f4c7" + "f1c686a27f3703b868200042acfced84e38c82c4d0003703b068200042d5" + "cb9694b3cac8f92a3703a868200042c38bd5b3c8bcf286897f3703a06820" + "04200041c0db006a200041a0e8006a10b38080800020004180d7006a2000" + "41c0c9006a41e0001086818080001a200042afff91c4a8fbbb8711370398" + "5c20004289bd83adbef9849c2e3703905c200042d0d1a385a497e78d4137" + "03885c20004294a7e7acc2baa5a44f3703805c200042ecf9a5e2bf8da8a1" + "d8003703f85b200042c6ac97e7d4d59afbb27f3703f05b200042ebcded87" + "fbc188f9083703e85b200042cd9cabeda5fde4f11c3703e05b200042eed3" + "f096abd9ebada37f3703d85b2000428fc5dc88cd998ff4977f3703d05b20" + "00429386aaa8abf2d7b4463703c85b200042e5a8e798abaaa584073703c0" + "5b2035410041c001108581808000213c200041a0e8006a41a0026a220320" + "004180d7006a200041c0db006a10b480808000200041a0e8006a200041c0" + "d2006a41a0021086818080001a2005204310b280808000200041c0c9006a" + "200041a0e8006a41301086818080001a2030200041a0e8006a4190016a22" + "4410b280808000200041c0d2006a200841301086818080001a2007200041" + "a0e8006a41f0016a224510b28080800020004180d7006a200041a0e8006a" + "41c0016a223a41301086818080001a200041c0db006a4100413010858180" + "80001a200042c18e8ea3d58c88f8183703985c200042d2a1c19ee8addffc" + "033703905c2000429e97eb8de0d783db8e7f3703885c20004295b7949cfd" + "d590b8d8003703805c200042d2cbb6fee1c8c8d5dd003703f85b200042f1" + "e0c7b3c8bcf2814d3703f05b20004180ce006a41e0006a2236200041c0d2" + "006a200041c0db006a10b380808000200141004130108581808000210120" + "0042ba8a92abf1a7dbf2143703e85b200042e8a0ee96fe89bcf2143703e0" + "5b200042a4a0a0f4c7f1c686a27f3703d85b200042acfced84e38c82c4d0" + "003703d05b200042d5cb9694b3cac8f92a3703c85b200042c38bd5b3c8bc" + "f286897f3703c05b20004180ce006a41c0016a224620004180d7006a2000" + "41c0db006a10b38080800020004180ce006a200041c0c9006a41e0001086" + "818080001a20004180c5006a41306a2231200041a0e8006a41d0026a2247" + "10b28080800020004180c5006a200341301086818080001a2005200041a0" + "e8006a41b0036a224810b280808000200041c0c9006a200041a0e8006a41" + "80036a224941301086818080001a2007200041a0e8006a4190046a224a10" + "b28080800020004180d7006a200041a0e8006a41e0036a224b4130108681" + "8080001a200041c0db006a410041301085818080001a200042c18e8ea3d5" + "8c88f8183703985c200042d2a1c19ee8addffc033703905c2000429e97eb" + "8de0d783db8e7f3703885c20004295b7949cfdd590b8d8003703805c2000" + "42d2cbb6fee1c8c8d5dd003703f85b200042f1e0c7b3c8bcf2814d3703f0" + "5b2038200041c0c9006a200041c0db006a10b38080800020014100413010" + "85818080002135200042ba8a92abf1a7dbf2143703e85b200042e8a0ee96" + "fe89bcf2143703e05b200042a4a0a0f4c7f1c686a27f3703d85b200042ac" + "fced84e38c82c4d0003703d05b200042d5cb9694b3cac8f92a3703c85b20" + "0042c38bd5b3c8bcf286897f3703c05b203420004180d7006a200041c0db" + "006a10b380808000200041c0d2006a20004180c5006a41e0001086818080" + "001a200042afff91c4a8fbbb87113703d85720004289bd83adbef9849c2e" + "3703d057200042d0d1a385a497e78d413703c85720004294a7e7acc2baa5" + "a44f3703c057200042ecf9a5e2bf8da8a1d8003703b857200042c6ac97e7" + "d4d59afbb27f3703b057200042ebcded87fbc188f9083703a857200042cd" + "9cabeda5fde4f11c3703a057200042eed3f096abd9ebada37f3703985720" + "00428fc5dc88cd998ff4977f370390572000429386aaa8abf2d7b4463703" + "8857200042e5a8e798abaaa58407370380572032410041c0011085818080" + "00213d200041c0db006a41a0026a2232200041c0d2006a20004180d7006a" + "10b480808000200041c0db006a20004180ce006a41a0021086818080001a" + "2031203510b28080800020004180c5006a200041c0db006a413010868180" + "80001a2002200041c0db006a4190016a224c10b28080800020004180ce00" + "6a203c41301086818080001a2030200041c0db006a41f0016a224d10b280" + "808000200041c0d2006a203b41301086818080001a20004180d7006a4100" + "41301085818080001a200042c18e8ea3d58c88f8183703d857200042d2a1" + "c19ee8addffc033703d0572000429e97eb8de0d783db8e7f3703c8572000" + "4295b7949cfdd590b8d8003703c057200042d2cbb6fee1c8c8d5dd003703" + "b857200042f1e0c7b3c8bcf2814d3703b057200041c0c9006a41e0006a22" + "0620004180ce006a20004180d7006a10b380808000200741004130108581" + "8080002101200042ba8a92abf1a7dbf2143703a857200042e8a0ee96fe89" + "bcf2143703a057200042a4a0a0f4c7f1c686a27f37039857200042acfced" + "84e38c82c4d00037039057200042d5cb9694b3cac8f92a37038857200042" + "c38bd5b3c8bcf286897f37038057200041c0c9006a41c0016a2207200041" + "c0d2006a20004180d7006a10b380808000200041c0c9006a20004180c500" + "6a41e0001086818080001a200041c0c0006a41306a2237200041c0db006a" + "41d0026a224e10b280808000200041c0c0006a203241301086818080001a" + "2031200041c0db006a41b0036a224f10b28080800020004180c5006a2000" + "41c0db006a4180036a225041301086818080001a2030200041c0db006a41" + "90046a225110b280808000200041c0d2006a200041c0db006a41e0036a22" + "5241301086818080001a20004180d7006a410041301085818080001a2000" + "42c18e8ea3d58c88f8183703d857200042d2a1c19ee8addffc033703d057" + "2000429e97eb8de0d783db8e7f3703c85720004295b7949cfdd590b8d800" + "3703c057200042d2cbb6fee1c8c8d5dd003703b857200042f1e0c7b3c8bc" + "f2814d3703b057203620004180c5006a20004180d7006a10b38080800020" + "01410041301085818080002101200042ba8a92abf1a7dbf2143703a85720" + "0042e8a0ee96fe89bcf2143703a057200042a4a0a0f4c7f1c686a27f3703" + "9857200042acfced84e38c82c4d00037039057200042d5cb9694b3cac8f9" + "2a37038857200042c38bd5b3c8bcf286897f370380572046200041c0d200" + "6a20004180d7006a10b38080800020004180ce006a200041c0c0006a41e0" + "001086818080001a200042afff91c4a8fbbb87113703985320004289bd83" + "adbef9849c2e37039053200042d0d1a385a497e78d413703885320004294" + "a7e7acc2baa5a44f37038053200042ecf9a5e2bf8da8a1d8003703f85220" + "0042c6ac97e7d4d59afbb27f3703f052200042ebcded87fbc188f9083703" + "e852200042cd9cabeda5fde4f11c3703e052200042eed3f096abd9ebada3" + "7f3703d8522000428fc5dc88cd998ff4977f3703d0522000429386aaa8ab" + "f2d7b4463703c852200042e5a8e798abaaa584073703c0522038410041c0" + "01108581808000213820004180d7006a41a0026a225320004180ce006a20" + "0041c0d2006a10b48080800020004180d7006a200041c0c9006a41a00210" + "86818080001a2037200110b280808000200041c0c0006a20004180d7006a" + "41301086818080001a200520004180d7006a4190016a10b2808080002000" + "41c0c9006a203d41301086818080001a200220004180d7006a41f0016a10" + "b28080800020004180ce006a200441301086818080001a200041c0d2006a" + "410041301085818080001a200042c18e8ea3d58c88f81837039853200042" + "d2a1c19ee8addffc03370390532000429e97eb8de0d783db8e7f37038853" + "20004295b7949cfdd590b8d80037038053200042d2cbb6fee1c8c8d5dd00" + "3703f852200042f1e0c7b3c8bcf2814d3703f05220004180c5006a41e000" + "6a2254200041c0c9006a200041c0d2006a10b38080800020304100413010" + "85818080002139200042ba8a92abf1a7dbf2143703e852200042e8a0ee96" + "fe89bcf2143703e052200042a4a0a0f4c7f1c686a27f3703d852200042ac" + "fced84e38c82c4d0003703d052200042d5cb9694b3cac8f92a3703c85220" + "0042c38bd5b3c8bcf286897f3703c05220004180c5006a41c0016a225520" + "004180ce006a200041c0d2006a10b38080800020004180c5006a200041c0" + "c0006a41e0001086818080001a200041803c6a41306a223020004180d700" + "6a41d0026a10b280808000200041803c6a205341301086818080001a2037" + "20004180d7006a41b0036a10b280808000200041c0c0006a20004180d700" + "6a4180036a41301086818080001a200220004180d7006a4190046a10b280" + "80800020004180ce006a20004180d7006a41e0036a41301086818080001a" + "200041c0d2006a410041301085818080001a200042c18e8ea3d58c88f818" + "37039853200042d2a1c19ee8addffc03370390532000429e97eb8de0d783" + "db8e7f3703885320004295b7949cfdd590b8d80037038053200042d2cbb6" + "fee1c8c8d5dd003703f852200042f1e0c7b3c8bcf2814d3703f052200620" + "0041c0c0006a200041c0d2006a10b3808080002039410041301085818080" + "002139200042ba8a92abf1a7dbf2143703e852200042e8a0ee96fe89bcf2" + "143703e052200042a4a0a0f4c7f1c686a27f3703d852200042acfced84e3" + "8c82c4d0003703d052200042d5cb9694b3cac8f92a3703c852200042c38b" + "d5b3c8bcf286897f3703c052200720004180ce006a200041c0d2006a10b3" + "80808000200041c0c9006a200041803c6a41e0001086818080001a200042" + "afff91c4a8fbbb87113703d84e20004289bd83adbef9849c2e3703d04e20" + "0042d0d1a385a497e78d413703c84e20004294a7e7acc2baa5a44f3703c0" + "4e200042ecf9a5e2bf8da8a1d8003703b84e200042c6ac97e7d4d59afbb2" + "7f3703b04e200042ebcded87fbc188f9083703a84e200042cd9cabeda5fd" + "e4f11c3703a04e200042eed3f096abd9ebada37f3703984e2000428fc5dc" + "88cd998ff4977f3703904e2000429386aaa8abf2d7b4463703884e200042" + "e5a8e798abaaa584073703804e2036410041c00110858180800021362000" + "41c0d2006a41a0026a2256200041c0c9006a20004180ce006a10b4808080" + "00200041c0d2006a20004180c5006a41a0021086818080001a2030203910" + "b280808000200041803c6a200041c0d2006a41301086818080001a203720" + "0041c0d2006a4190016a225710b280808000200041c0c0006a2038413010" + "86818080001a2005200041c0d2006a41f0016a225810b280808000200041" + "c0c9006a203441301086818080001a20004180ce006a4100413010858180" + "80001a200042c18e8ea3d58c88f8183703d84e200042d2a1c19ee8addffc" + "033703d04e2000429e97eb8de0d783db8e7f3703c84e20004295b7949cfd" + "d590b8d8003703c04e200042d2cbb6fee1c8c8d5dd003703b84e200042f1" + "e0c7b3c8bcf2814d3703b04e2054200041c0c0006a20004180ce006a10b3" + "808080002002410041301085818080002102200042ba8a92abf1a7dbf214" + "3703a84e200042e8a0ee96fe89bcf2143703a04e200042a4a0a0f4c7f1c6" + "86a27f3703984e200042acfced84e38c82c4d0003703904e200042d5cb96" + "94b3cac8f92a3703884e200042c38bd5b3c8bcf286897f3703804e205520" + "0041c0c9006a20004180ce006a10b38080800020004180c5006a20004180" + "3c6a41e0001086818080001a200041c0376a41306a2259200041c0d2006a" + "41d0026a225a10b280808000200041c0376a205641301086818080001a20" + "30200041c0d2006a41b0036a225b10b280808000200041803c6a200041c0" + "d2006a4180036a225c41301086818080001a2037200041c0d2006a419004" + "6a225d10b280808000200041c0c0006a200041c0d2006a41e0036a225e41" + "301086818080001a20004180ce006a410041301085818080001a200042c1" + "8e8ea3d58c88f8183703d84e200042d2a1c19ee8addffc033703d04e2000" + "429e97eb8de0d783db8e7f3703c84e20004295b7949cfdd590b8d8003703" + "c04e200042d2cbb6fee1c8c8d5dd003703b84e200042f1e0c7b3c8bcf281" + "4d3703b04e2006200041803c6a20004180ce006a10b38080800020024100" + "4130108581808000215f200042ba8a92abf1a7dbf2143703a84e200042e8" + "a0ee96fe89bcf2143703a04e200042a4a0a0f4c7f1c686a27f3703984e20" + "0042acfced84e38c82c4d0003703904e200042d5cb9694b3cac8f92a3703" + "884e200042c38bd5b3c8bcf286897f3703804e2007200041c0c0006a2000" + "4180ce006a10b380808000200041c0c9006a200041c0376a41e000108681" + "8080001a200042afff91c4a8fbbb87113703d84e20004289bd83adbef984" + "9c2e3703d04e200042d0d1a385a497e78d413703c84e20004294a7e7acc2" + "baa5a44f3703c04e200042ecf9a5e2bf8da8a1d8003703b84e200042c6ac" + "97e7d4d59afbb27f3703b04e200042ebcded87fbc188f9083703a84e2000" + "42cd9cabeda5fde4f11c3703a04e200042eed3f096abd9ebada37f370398" + "4e2000428fc5dc88cd998ff4977f3703904e2000429386aaa8abf2d7b446" + "3703884e200042e5a8e798abaaa584073703804e2036410041c001108581" + "8080002160200041b82e6a41a0026a200041c0c9006a20004180ce006a10" + "b480808000200041b82e6a20004180c5006a41a0021086818080001a2000" + "41a0e8006a200041f8296a10b58080800020004180ce006a200041f8296a" + "41a0026a226110b580808000200041f8326a20004180ce006a10b6808080" + "00200041c0c9006a200041a0e8006a200041f8326a10b780808000200041" + "f8326a2006200710b38080800020004180e0006a200041f8326a203310b8" + "8080800020004180e0006a41306a2230200041f8326a203310b980808000" + "200041f8326a200041c0c9006a10ba80808000200041a0e2006a200041f8" + "326a20004180e0006a10bb80808000200041f8326a200710ba8080800020" + "0041c0e4006a200041f8326a203310b880808000200041c0e4006a41306a" + "2236200041f8326a203310b980808000200041f8326a200041c0c9006a20" + "0610b380808000200041c0376a200041c0e4006a200041f8326a10bb8080" + "8000200041803c6a200610ba80808000200041f8326a200041c0c9006a20" + "0710b380808000200041c0c0006a200041803c6a200041f8326a10bb8080" + "8000200041a0e8006a2006200041c0c0006a10b380808000200041f8326a" + "2007200041c0376a10b380808000200041c0db006a200041a0e8006a2000" + "41f8326a10bc8080800020004180c5006a200041c0db006a203510b88080" + "80002031200041c0db006a203510b980808000200041f8326a200041c0c9" + "006a200041a0e2006a10b380808000200041c0d2006a20004180c5006a20" + "0041f8326a10bc80808000200041a0e8006a200041c0d2006a10bd808080" + "00200041f8326a203910bd80808000200041e0e6006a200041a0e8006a20" + "0041f8326a10b980808000200041c0db006a200041e0e6006a10a6808080" + "0020004180d7006a410041301085818080001a200041c0e7006a20004180" + "d7006a200041c0db006a20002d00f05b2202109080808000200041f8326a" + "200041c0d2006a200041c0e7006a10a780808000200041a0e8006a200041" + "c0e7006a10b28080800020332039200041a0e8006a10a780808000200041" + "a0e8006a200041f8326a41e0001086818080001a200020023a0080692000" + "4180d7006a410041e0001085818080001a200041c0db006a20004180d700" + "6a200041a0e8006a200210b080808000200041f8326a200041c0db006a20" + "0041a0e2006a10b380808000203f200041c0db006a200041c0376a10b380" + "8080002040200041c0db006a200041c0c0006a10b380808000200041c0db" + "006a200041f8326a41a0021086818080001a200020023a00e05d20004180" + "d7006a410041a0021085818080001a200041c0d2006a20004180d7006a20" + "0041c0db006a200210b0808080002038203d203c200210b0808080002034" + "2004203b200210b080808000200041a0e8006a200041f8296a200041c0d2" + "006a10b480808000200041f8326a200041c0d2006a10b180808000200320" + "61200041f8326a10b480808000200041f8326a200041a0e8006a41c00410" + "86818080001a200020023a00b837200041803c6a410041c0041085818080" + "001a200041c0db006a200041803c6a200041f8326a200210b08080800020" + "3c200041803c6a41e0006a203f200210b080808000203b200041803c6a41" + "c0016a2040200210b080808000200041a0e8006a200041803c6a41a0026a" + "203e200210b0808080002008200041803c6a4180036a2041200210b08080" + "8000203a200041803c6a41e0036a2042200210b080808000200041c0376a" + "200041c0db006a41a0021086818080001a200041c0376a41a0026a200041" + "a0e8006a41a0021086818080002161200041c0c0006a200041b82e6a2000" + "41c0376a10be80808000200041c0376a200041c0c0006a41c00410868180" + "80001a205f203710b28080800020004180ce006a200041c0c0006a413010" + "86818080001a2001200041c0c0006a4190016a10b28080800020004180d7" + "006a200041c0c0006a41e0006a41301086818080001a2035200041c0c000" + "6a41f0016a10b280808000200041c0db006a200041c0c0006a41c0016a41" + "301086818080001a200041a0e8006a410041301085818080001a200042c1" + "8e8ea3d58c88f8183703f868200042d2a1c19ee8addffc033703f0682000" + "429e97eb8de0d783db8e7f3703e86820004295b7949cfdd590b8d8003703" + "e068200042d2cbb6fee1c8c8d5dd003703d868200042f1e0c7b3c8bcf281" + "4d3703d068203820004180d7006a200041a0e8006a10b380808000204341" + "0041301085818080002133200042ba8a92abf1a7dbf2143703c868200042" + "e8a0ee96fe89bcf2143703c068200042a4a0a0f4c7f1c686a27f3703b868" + "200042acfced84e38c82c4d0003703b068200042d5cb9694b3cac8f92a37" + "03a868200042c38bd5b3c8bcf286897f3703a0682034200041c0db006a20" + "0041a0e8006a10b380808000200041c0d2006a20004180ce006a41e00010" + "86818080001a2005200041c0c0006a41d0026a10b280808000200041c0c9" + "006a200041c0c0006a41a0026a223741301086818080001a205f200041c0" + "c0006a41b0036a10b28080800020004180ce006a200041c0c0006a418003" + "6a41301086818080001a2035200041c0c0006a4190046a10b28080800020" + "0041c0db006a200041c0c0006a41e0036a41301086818080001a200041a0" + "e8006a410041301085818080001a200042c18e8ea3d58c88f8183703f868" + "200042d2a1c19ee8addffc033703f0682000429e97eb8de0d783db8e7f37" + "03e86820004295b7949cfdd590b8d8003703e068200042d2cbb6fee1c8c8" + "d5dd003703d868200042f1e0c7b3c8bcf2814d3703d068203d20004180ce" + "006a200041a0e8006a10b380808000203341004130108581808000210620" + "0042ba8a92abf1a7dbf2143703c868200042e8a0ee96fe89bcf2143703c0" + "68200042a4a0a0f4c7f1c686a27f3703b868200042acfced84e38c82c4d0" + "003703b068200042d5cb9694b3cac8f92a3703a868200042c38bd5b3c8bc" + "f286897f3703a0682004200041c0db006a200041a0e8006a10b380808000" + "20004180d7006a200041c0c9006a41e0001086818080001a200042afff91" + "c4a8fbbb87113703985c20004289bd83adbef9849c2e3703905c200042d0" + "d1a385a497e78d413703885c20004294a7e7acc2baa5a44f3703805c2000" + "42ecf9a5e2bf8da8a1d8003703f85b200042c6ac97e7d4d59afbb27f3703" + "f05b200042ebcded87fbc188f9083703e85b200042cd9cabeda5fde4f11c" + "3703e05b200042eed3f096abd9ebada37f3703d85b2000428fc5dc88cd99" + "8ff4977f3703d05b2000429386aaa8abf2d7b4463703c85b200042e5a8e7" + "98abaaa584073703c05b203c410041c00110858180800021432003200041" + "80d7006a200041c0db006a10b480808000200041a0e8006a200041c0d200" + "6a41a0021086818080001a2005200610b280808000200041c0c9006a2000" + "41a0e8006a41301086818080001a2039204410b280808000200041c0d200" + "6a200841301086818080001a2001204510b28080800020004180d7006a20" + "3a41301086818080001a200041c0db006a410041301085818080001a2000" + "42c18e8ea3d58c88f8183703985c200042d2a1c19ee8addffc033703905c" + "2000429e97eb8de0d783db8e7f3703885c20004295b7949cfdd590b8d800" + "3703805c200042d2cbb6fee1c8c8d5dd003703f85b200042f1e0c7b3c8bc" + "f2814d3703f05b2060200041c0d2006a200041c0db006a10b38080800020" + "35410041301085818080002133200042ba8a92abf1a7dbf2143703e85b20" + "0042e8a0ee96fe89bcf2143703e05b200042a4a0a0f4c7f1c686a27f3703" + "d85b200042acfced84e38c82c4d0003703d05b200042d5cb9694b3cac8f9" + "2a3703c85b200042c38bd5b3c8bcf286897f3703c05b204620004180d700" + "6a200041c0db006a10b38080800020004180ce006a200041c0c9006a41e0" + "001086818080001a2031204710b28080800020004180c5006a2003413010" + "86818080001a2005204810b280808000200041c0c9006a20494130108681" + "8080001a2001204a10b28080800020004180d7006a204b41301086818080" + "001a200041c0db006a410041301085818080001a200042c18e8ea3d58c88" + "f8183703985c200042d2a1c19ee8addffc033703905c2000429e97eb8de0" + "d783db8e7f3703885c20004295b7949cfdd590b8d8003703805c200042d2" + "cbb6fee1c8c8d5dd003703f85b200042f1e0c7b3c8bcf2814d3703f05b20" + "38200041c0c9006a200041c0db006a10b380808000203341004130108581" + "8080002133200042ba8a92abf1a7dbf2143703e85b200042e8a0ee96fe89" + "bcf2143703e05b200042a4a0a0f4c7f1c686a27f3703d85b200042acfced" + "84e38c82c4d0003703d05b200042d5cb9694b3cac8f92a3703c85b200042" + "c38bd5b3c8bcf286897f3703c05b203420004180d7006a200041c0db006a" + "10b380808000200041c0d2006a20004180c5006a41e0001086818080001a" + "200042afff91c4a8fbbb87113703d85720004289bd83adbef9849c2e3703" + "d057200042d0d1a385a497e78d413703c85720004294a7e7acc2baa5a44f" + "3703c057200042ecf9a5e2bf8da8a1d8003703b857200042c6ac97e7d4d5" + "9afbb27f3703b057200042ebcded87fbc188f9083703a857200042cd9cab" + "eda5fde4f11c3703a057200042eed3f096abd9ebada37f37039857200042" + "8fc5dc88cd998ff4977f370390572000429386aaa8abf2d7b44637038857" + "200042e5a8e798abaaa5840737038057203d410041c00110858180800021" + "072032200041c0d2006a20004180d7006a10b480808000200041c0db006a" + "20004180ce006a41a0021086818080001a200041c0c0006a200041c0db00" + "6a41c0041086818080001a200041c0c0006a200041c0376a10bf80808000" + "200041a0e8006a200041c0c0006a10c0808080002032200310b180808000" + "200041c0db006a200041a0e8006a41a0021086818080001a200041c0376a" + "200041c0db006a41c0041086818080001a20004180c5006a200041c0c000" + "6a10c180808000200041c0c9006a20004180c5006a10c080808000200041" + "80ce006a200041c0376a20004180c5006a10be80808000200041c0376a20" + "004180ce006a10c180808000200041b82e6a200041c0376a10c180808000" + "200041c0d2006a200041b82e6a10c180808000200041c0d2006a200041c0" + "c9006a10bf80808000200041c0c9006a200041c0d2006a10c18080800020" + "0320004180ce006a41a0026a10b180808000200041a0e8006a20004180ce" + "006a41a0021086818080001a20004180ce006a200041a0e8006a41c00410" + "86818080001a200041a0e8006a20004180ce006a200041c0c0006a10be80" + "808000200041c0c9006a200041a0e8006a10bf808080002003203710b180" + "808000200041a0e8006a200041c0c0006a41a0021086818080001a200041" + "80ce006a200041a0e8006a41c0041086818080001a200041c0376a200041" + "c0c0006a10bf80808000200041a0e2006a41306a2205205910b280808000" + "200041a0e2006a200041c0376a41301086818080001a2001200041c0376a" + "4190016a10b28080800020004180d7006a200041c0376a41e0006a413010" + "86818080001a2033200041c0376a41f0016a10b280808000200041c0db00" + "6a200041c0376a41c0016a41301086818080001a200041a0e8006a410041" + "301085818080001a200042c18e8ea3d58c88f8183703f868200042d2a1c1" + "9ee8addffc033703f0682000429e97eb8de0d783db8e7f3703e868200042" + "95b7949cfdd590b8d8003703e068200042d2cbb6fee1c8c8d5dd003703d8" + "68200042f1e0c7b3c8bcf2814d3703d068200041c0e4006a41e0006a2237" + "20004180d7006a200041a0e8006a10b38080800020064100413010858180" + "80002106200042ba8a92abf1a7dbf2143703c868200042e8a0ee96fe89bc" + "f2143703c068200042a4a0a0f4c7f1c686a27f3703b868200042acfced84" + "e38c82c4d0003703b068200042d5cb9694b3cac8f92a3703a868200042c3" + "8bd5b3c8bcf286897f3703a068200041c0e4006a41c0016a2235200041c0" + "db006a200041a0e8006a10b380808000200041c0e4006a200041a0e2006a" + "41e0001086818080001a2030200041c0376a41d0026a10b2808080002000" + "4180e0006a206141301086818080001a2005200041c0376a41b0036a10b2" + "80808000200041a0e2006a200041c0376a4180036a41301086818080001a" + "2033200041c0376a4190046a10b280808000200041c0db006a200041c037" + "6a41e0036a41301086818080001a200041a0e8006a410041301085818080" + "001a200042c18e8ea3d58c88f8183703f868200042d2a1c19ee8addffc03" + "3703f0682000429e97eb8de0d783db8e7f3703e86820004295b7949cfdd5" + "90b8d8003703e068200042d2cbb6fee1c8c8d5dd003703d868200042f1e0" + "c7b3c8bcf2814d3703d0682007200041a0e2006a200041a0e8006a10b380" + "808000200641004130108581808000213c200042ba8a92abf1a7dbf21437" + "03c868200042e8a0ee96fe89bcf2143703c068200042a4a0a0f4c7f1c686" + "a27f3703b868200042acfced84e38c82c4d0003703b068200042d5cb9694" + "b3cac8f92a3703a868200042c38bd5b3c8bcf286897f3703a06820042000" + "41c0db006a200041a0e8006a10b38080800020004180d7006a20004180e0" + "006a41e0001086818080001a200042afff91c4a8fbbb87113703985c2000" + "4289bd83adbef9849c2e3703905c200042d0d1a385a497e78d413703885c" + "20004294a7e7acc2baa5a44f3703805c200042ecf9a5e2bf8da8a1d80037" + "03f85b200042c6ac97e7d4d59afbb27f3703f05b200042ebcded87fbc188" + "f9083703e85b200042cd9cabeda5fde4f11c3703e05b200042eed3f096ab" + "d9ebada37f3703d85b2000428fc5dc88cd998ff4977f3703d05b20004293" + "86aaa8abf2d7b4463703c85b200042e5a8e798abaaa584073703c05b2043" + "410041c001108581808000213d200320004180d7006a200041c0db006a10" + "b480808000200041a0e8006a200041c0e4006a41a0021086818080001a20" + "30203c10b28080800020004180e0006a200041a0e8006a41301086818080" + "001a2036204410b280808000200041c0e4006a200841301086818080001a" + "2001204510b28080800020004180d7006a203a41301086818080001a2000" + "41c0db006a410041301085818080001a200042c18e8ea3d58c88f8183703" + "985c200042d2a1c19ee8addffc033703905c2000429e97eb8de0d783db8e" + "7f3703885c20004295b7949cfdd590b8d8003703805c200042d2cbb6fee1" + "c8c8d5dd003703f85b200042f1e0c7b3c8bcf2814d3703f05b200041a0e2" + "006a41e0006a2243200041c0e4006a200041c0db006a10b3808080002033" + "410041301085818080002133200042ba8a92abf1a7dbf2143703e85b2000" + "42e8a0ee96fe89bcf2143703e05b200042a4a0a0f4c7f1c686a27f3703d8" + "5b200042acfced84e38c82c4d0003703d05b200042d5cb9694b3cac8f92a" + "3703c85b200042c38bd5b3c8bcf286897f3703c05b200041a0e2006a41c0" + "016a224620004180d7006a200041c0db006a10b380808000200041a0e200" + "6a20004180e0006a41e0001086818080001a200041c0e7006a41306a2206" + "204710b280808000200041c0e7006a200341301086818080001a20302048" + "10b28080800020004180e0006a204941301086818080001a2001204a10b2" + "8080800020004180d7006a204b41301086818080001a200041c0db006a41" + "0041301085818080001a200042c18e8ea3d58c88f8183703985c200042d2" + "a1c19ee8addffc033703905c2000429e97eb8de0d783db8e7f3703885c20" + "004295b7949cfdd590b8d8003703805c200042d2cbb6fee1c8c8d5dd0037" + "03f85b200042f1e0c7b3c8bcf2814d3703f05b203720004180e0006a2000" + "41c0db006a10b3808080002033410041301085818080002133200042ba8a" + "92abf1a7dbf2143703e85b200042e8a0ee96fe89bcf2143703e05b200042" + "a4a0a0f4c7f1c686a27f3703d85b200042acfced84e38c82c4d0003703d0" + "5b200042d5cb9694b3cac8f92a3703c85b200042c38bd5b3c8bcf286897f" + "3703c05b203520004180d7006a200041c0db006a10b380808000200041c0" + "e4006a200041c0e7006a41e0001086818080001a200042afff91c4a8fbbb" + "87113703d85720004289bd83adbef9849c2e3703d057200042d0d1a385a4" + "97e78d413703c85720004294a7e7acc2baa5a44f3703c057200042ecf9a5" + "e2bf8da8a1d8003703b857200042c6ac97e7d4d59afbb27f3703b0572000" + "42ebcded87fbc188f9083703a857200042cd9cabeda5fde4f11c3703a057" + "200042eed3f096abd9ebada37f370398572000428fc5dc88cd998ff4977f" + "370390572000429386aaa8abf2d7b44637038857200042e5a8e798abaaa5" + "8407370380572007410041c00110858180800021072032200041c0e4006a" + "20004180d7006a10b480808000200041c0db006a200041a0e2006a41a002" + "1086818080001a2006203310b280808000200041c0e7006a200041c0db00" + "6a41301086818080001a2005204c10b280808000200041a0e2006a203d41" + "301086818080001a2036204d10b280808000200041c0e4006a203b413010" + "86818080001a20004180d7006a410041301085818080001a200042c18e8e" + "a3d58c88f8183703d857200042d2a1c19ee8addffc033703d0572000429e" + "97eb8de0d783db8e7f3703c85720004295b7949cfdd590b8d8003703c057" + "200042d2cbb6fee1c8c8d5dd003703b857200042f1e0c7b3c8bcf2814d37" + "03b05720004180e0006a41e0006a200041a0e2006a20004180d7006a10b3" + "808080002001410041301085818080002101200042ba8a92abf1a7dbf214" + "3703a857200042e8a0ee96fe89bcf2143703a057200042a4a0a0f4c7f1c6" + "86a27f37039857200042acfced84e38c82c4d00037039057200042d5cb96" + "94b3cac8f92a37038857200042c38bd5b3c8bcf286897f37038057200041" + "80e0006a41c0016a200041c0e4006a20004180d7006a10b3808080002000" + "4180e0006a200041c0e7006a41e0001086818080001a200041e0e6006a41" + "306a204e10b280808000200041e0e6006a203241301086818080001a2006" + "204f10b280808000200041c0e7006a205041301086818080001a20362051" + "10b280808000200041c0e4006a205241301086818080001a20004180d700" + "6a410041301085818080001a200042c18e8ea3d58c88f8183703d8572000" + "42d2a1c19ee8addffc033703d0572000429e97eb8de0d783db8e7f3703c8" + "5720004295b7949cfdd590b8d8003703c057200042d2cbb6fee1c8c8d5dd" + "003703b857200042f1e0c7b3c8bcf2814d3703b0572043200041c0e7006a" + "20004180d7006a10b3808080002001410041301085818080002101200042" + "ba8a92abf1a7dbf2143703a857200042e8a0ee96fe89bcf2143703a05720" + "0042a4a0a0f4c7f1c686a27f37039857200042acfced84e38c82c4d00037" + "039057200042d5cb9694b3cac8f92a37038857200042c38bd5b3c8bcf286" + "897f370380572046200041c0e4006a20004180d7006a10b3808080002000" + "41a0e2006a200041e0e6006a41e0001086818080001a200042afff91c4a8" + "fbbb87113703986520004289bd83adbef9849c2e37039065200042d0d1a3" + "85a497e78d413703886520004294a7e7acc2baa5a44f37038065200042ec" + "f9a5e2bf8da8a1d8003703f864200042c6ac97e7d4d59afbb27f3703f064" + "200042ebcded87fbc188f9083703e864200042cd9cabeda5fde4f11c3703" + "e064200042eed3f096abd9ebada37f3703d8642000428fc5dc88cd998ff4" + "977f3703d0642000429386aaa8abf2d7b4463703c864200042e5a8e798ab" + "aaa584073703c0642037410041c00110858180800021372053200041a0e2" + "006a200041c0e4006a10b48080800020004180d7006a20004180e0006a41" + "a0021086818080001a200041c0376a20004180d7006a41c0041086818080" + "001a200041c0d2006a20004180ce006a10bf808080002005203910b28080" + "8000200041a0e2006a200041c0d2006a41301086818080001a2001205710" + "b28080800020004180d7006a203841301086818080001a2033205810b280" + "808000200041c0db006a203441301086818080001a200041a0e8006a4100" + "41301085818080001a200042c18e8ea3d58c88f8183703f868200042d2a1" + "c19ee8addffc033703f0682000429e97eb8de0d783db8e7f3703e8682000" + "4295b7949cfdd590b8d8003703e068200042d2cbb6fee1c8c8d5dd003703" + "d868200042f1e0c7b3c8bcf2814d3703d068203720004180d7006a200041" + "a0e8006a10b380808000203c410041301085818080002134200042ba8a92" + "abf1a7dbf2143703c868200042e8a0ee96fe89bcf2143703c068200042a4" + "a0a0f4c7f1c686a27f3703b868200042acfced84e38c82c4d0003703b068" + "200042d5cb9694b3cac8f92a3703a868200042c38bd5b3c8bcf286897f37" + "03a0682035200041c0db006a200041a0e8006a10b380808000200041c0e4" + "006a200041a0e2006a41e0001086818080001a2030205a10b28080800020" + "004180e0006a205641301086818080001a2005205b10b280808000200041" + "a0e2006a205c41301086818080001a2033205d10b280808000200041c0db" + "006a205e41301086818080001a200041a0e8006a41004130108581808000" + "1a200042c18e8ea3d58c88f8183703f868200042d2a1c19ee8addffc0337" + "03f0682000429e97eb8de0d783db8e7f3703e86820004295b7949cfdd590" + "b8d8003703e068200042d2cbb6fee1c8c8d5dd003703d868200042f1e0c7" + "b3c8bcf2814d3703d0682007200041a0e2006a200041a0e8006a10b38080" + "80002034410041301085818080002134200042ba8a92abf1a7dbf2143703" + "c868200042e8a0ee96fe89bcf2143703c068200042a4a0a0f4c7f1c686a2" + "7f3703b868200042acfced84e38c82c4d0003703b068200042d5cb9694b3" + "cac8f92a3703a868200042c38bd5b3c8bcf286897f3703a0682004200041" + "c0db006a200041a0e8006a10b38080800020004180d7006a20004180e000" + "6a41e0001086818080001a200042afff91c4a8fbbb87113703985c200042" + "89bd83adbef9849c2e3703905c200042d0d1a385a497e78d413703885c20" + "004294a7e7acc2baa5a44f3703805c200042ecf9a5e2bf8da8a1d8003703" + "f85b200042c6ac97e7d4d59afbb27f3703f05b200042ebcded87fbc188f9" + "083703e85b200042cd9cabeda5fde4f11c3703e05b200042eed3f096abd9" + "ebada37f3703d85b2000428fc5dc88cd998ff4977f3703d05b2000429386" + "aaa8abf2d7b4463703c85b200042e5a8e798abaaa584073703c05b203d41" + "0041c0011085818080002138200320004180d7006a200041c0db006a10b4" + "80808000200041a0e8006a200041c0e4006a41a0021086818080001a2000" + "41c0d2006a200041a0e8006a41c0041086818080001a20004180c5006a20" + "0041b82e6a10bf808080002005203110b280808000200041a0e2006a2000" + "4180c5006a41301086818080001a200120004180c5006a4190016a10b280" + "80800020004180d7006a205441301086818080001a203320004180c5006a" + "41f0016a10b280808000200041c0db006a205541301086818080001a2000" + "41a0e8006a410041301085818080001a200042c18e8ea3d58c88f8183703" + "f868200042d2a1c19ee8addffc033703f0682000429e97eb8de0d783db8e" + "7f3703e86820004295b7949cfdd590b8d8003703e068200042d2cbb6fee1" + "c8c8d5dd003703d868200042f1e0c7b3c8bcf2814d3703d0682037200041" + "80d7006a200041a0e8006a10b38080800020344100413010858180800021" + "34200042ba8a92abf1a7dbf2143703c868200042e8a0ee96fe89bcf21437" + "03c068200042a4a0a0f4c7f1c686a27f3703b868200042acfced84e38c82" + "c4d0003703b068200042d5cb9694b3cac8f92a3703a868200042c38bd5b3" + "c8bcf286897f3703a0682035200041c0db006a200041a0e8006a10b38080" + "8000200041c0e4006a200041a0e2006a41e0001086818080001a20302000" + "4180c5006a41d0026a10b28080800020004180e0006a20004180c5006a41" + "a0026a41301086818080001a200520004180c5006a41b0036a10b2808080" + "00200041a0e2006a20004180c5006a4180036a41301086818080001a2033" + "20004180c5006a4190046a10b280808000200041c0db006a20004180c500" + "6a41e0036a41301086818080001a200041a0e8006a410041301085818080" + "001a200042c18e8ea3d58c88f8183703f868200042d2a1c19ee8addffc03" + "3703f0682000429e97eb8de0d783db8e7f3703e86820004295b7949cfdd5" + "90b8d8003703e068200042d2cbb6fee1c8c8d5dd003703d868200042f1e0" + "c7b3c8bcf2814d3703d0682007200041a0e2006a200041a0e8006a10b380" + "8080002034410041301085818080002105200042ba8a92abf1a7dbf21437" + "03c868200042e8a0ee96fe89bcf2143703c068200042a4a0a0f4c7f1c686" + "a27f3703b868200042acfced84e38c82c4d0003703b068200042d5cb9694" + "b3cac8f92a3703a868200042c38bd5b3c8bcf286897f3703a06820042000" + "41c0db006a200041a0e8006a10b38080800020004180d7006a20004180e0" + "006a41e0001086818080001a200042afff91c4a8fbbb87113703985c2000" + "4289bd83adbef9849c2e3703905c200042d0d1a385a497e78d413703885c" + "20004294a7e7acc2baa5a44f3703805c200042ecf9a5e2bf8da8a1d80037" + "03f85b200042c6ac97e7d4d59afbb27f3703f05b200042ebcded87fbc188" + "f9083703e85b200042cd9cabeda5fde4f11c3703e05b200042eed3f096ab" + "d9ebada37f3703d85b2000428fc5dc88cd998ff4977f3703d05b20004293" + "86aaa8abf2d7b4463703c85b200042e5a8e798abaaa584073703c05b2038" + "410041c0011085818080001a200320004180d7006a200041c0db006a10b4" + "80808000200041a0e8006a200041c0e4006a41a0021086818080001a2030" + "200510b28080800020004180e0006a200041a0e8006a4130108681808000" + "1a2036204410b280808000200041c0e4006a200841301086818080001a20" + "01204510b28080800020004180d7006a203a41301086818080001a200041" + "c0db006a410041301085818080001a200042c18e8ea3d58c88f818370398" + "5c200042d2a1c19ee8addffc033703905c2000429e97eb8de0d783db8e7f" + "3703885c20004295b7949cfdd590b8d8003703805c200042d2cbb6fee1c8" + "c8d5dd003703f85b200042f1e0c7b3c8bcf2814d3703f05b2043200041c0" + "e4006a200041c0db006a10b3808080002033410041301085818080002104" + "200042ba8a92abf1a7dbf2143703e85b200042e8a0ee96fe89bcf2143703" + "e05b200042a4a0a0f4c7f1c686a27f3703d85b200042acfced84e38c82c4" + "d0003703d05b200042d5cb9694b3cac8f92a3703c85b200042c38bd5b3c8" + "bcf286897f3703c05b204620004180d7006a200041c0db006a10b3808080" + "00200041a0e2006a20004180e0006a41e0001086818080001a2006204710" + "b280808000200041c0e7006a200341301086818080001a2030204810b280" + "80800020004180e0006a204941301086818080001a2001204a10b2808080" + "0020004180d7006a204b41301086818080001a200041c0db006a41004130" + "1085818080001a200042c18e8ea3d58c88f8183703985c200042d2a1c19e" + "e8addffc033703905c2000429e97eb8de0d783db8e7f3703885c20004295" + "b7949cfdd590b8d8003703805c200042d2cbb6fee1c8c8d5dd003703f85b" + "200042f1e0c7b3c8bcf2814d3703f05b203720004180e0006a200041c0db" + "006a10b3808080002004410041301085818080001a200042ba8a92abf1a7" + "dbf2143703e85b200042e8a0ee96fe89bcf2143703e05b200042a4a0a0f4" + "c7f1c686a27f3703d85b200042acfced84e38c82c4d0003703d05b200042" + "d5cb9694b3cac8f92a3703c85b200042c38bd5b3c8bcf286897f3703c05b" + "203520004180d7006a200041c0db006a10b380808000200041c0e4006a20" + "0041c0e7006a41e0001086818080001a200042afff91c4a8fbbb87113703" + "d85720004289bd83adbef9849c2e3703d057200042d0d1a385a497e78d41" + "3703c85720004294a7e7acc2baa5a44f3703c057200042ecf9a5e2bf8da8" + "a1d8003703b857200042c6ac97e7d4d59afbb27f3703b057200042ebcded" + "87fbc188f9083703a857200042cd9cabeda5fde4f11c3703a057200042ee" + "d3f096abd9ebada37f370398572000428fc5dc88cd998ff4977f37039057" + "2000429386aaa8abf2d7b44637038857200042e5a8e798abaaa584073703" + "80572007410041c0011085818080001a2032200041c0e4006a20004180d7" + "006a10b480808000200041c0db006a200041a0e2006a41a0021086818080" + "001a20004180c5006a200041c0db006a41c0041086818080001a20004180" + "c5006a200041c0376a10bf8080800020004180c5006a200041c0d2006a10" + "bf80808000200041f8296a20004180c5006a200041c0c9006a10be808080" + "00200020023a00a068024020024101470d00200041a0e8006a200041f829" + "6a41c0041086818080001a200041f8326a10ac80808000200041a0e8006a" + "200041f8326a10c2808080002008203f10c2808080007110a38080800020" + "3a204010c2808080007110a3808080002003203e10c28080800020492041" + "10c2808080007110a380808000204b204210c2808080007110a380808000" + "7110a380808000210220002802a82520002802ac25108580808000200028" + "029825200028029c25108580808000200028028825200028028c25108580" + "80800020002802f82420002802fc24108580808000202f202e1086808080" + "0020002802c01c20002802c41c10828080800020002802a01520002802a4" + "15108480808000200028028815200028028c1510848080800020002802b4" + "1320002802b81310848080800020002802bc1220002802c0121084808080" + "0020002802e41020002802e810108480808000200028028c0f2000280290" + "0f10848080800020002802940e20002802980e108480808000200028029c" + "0d20002802a00d108480808000200241ff017141004721020c080b200041" + "003602f832200041a0e8006a41c886c08000200041f8326a41cc86c08000" + "109680808000000b200041c0c0006a200041b8256a203610b48080800020" + "004180c5006a200041b8256a203610c380808000200041c0c9006a203610" + "b68080800020004180ce006a200041c0c9006a200041b8256a10c3808080" + "00200041c0d2006a20004180ce006a20004180c5006a10b4808080002000" + "4180d7006a200041c0d2006a200041c0c0006a10b780808000200041c0db" + "006a200041c0c0006a200041c0c0006a10c380808000200041a0e8006a20" + "0041c0c0006a10b680808000200041f8326a20004180d7006a200041a0e8" + "006a10b7808080002005200041c0db006a41a0021086818080001a200041" + "b8256a200041f8326a41c0041086818080001a410121020c000b0b200041" + "80d7006a2030200441e8006c6a10a580808000200041a0026a202e200441" + "05746a2202290300220c42ffffffff6f7e22094200428180808070420010" + "878180800020004190026a2009420042feb7f9ffaf80e9ded30042001087" + "8180800020004180026a200942004285b087cd8081f69c33420010878180" + "8000200041f0016a2009420042c8faf5ccb2eae9f6f30042001087818080" + "00200041e0016a200029039002220e20022903087c220b200041a0026a41" + "086a290300200c20002903a00222097c200954ad7c7c220c42ffffffff6f" + "7e220942004281808080704200108781808000200041d0016a2009420042" + "feb7f9ffaf80e9ded300420010878180800020004180016a200942004285" + "b087cd8081f69c334200108781808000200041306a2009420042c8faf5cc" + "b2eae9f6f3004200108781808000200041c0016a20002903d00122132000" + "29038002221220022903107c220a20004190026a41086a290300200b200e" + "54ad7c200c200b54ad7c7c220d7c220b200041e0016a41086a2903002000" + "2903e0012209200c7c200954ad7c7c220c42ffffffff6f7e220942004281" + "808080704200108781808000200041b0016a2009420042feb7f9ffaf80e9" + "ded3004200108781808000200041a0016a200942004285b087cd8081f69c" + "33420010878180800020004190016a2009420042c8faf5ccb2eae9f6f300" + "4200108781808000200041f0006a20002903b001221020002903f0012211" + "20022903187c220e20004180026a41086a290300200a201254ad7c200d20" + "0a54ad7c7c220a2000290380017c2212200041d0016a41086a290300200b" + "201354ad7c200c200b54ad7c7c22137c220b200041c0016a41086a290300" + "20002903c0012209200c7c200954ad7c7c220c42ffffffff6f7e22094200" + "4281808080704200108781808000200041e0006a2009420042feb7f9ffaf" + "80e9ded3004200108781808000200041d0006a200942004285b087cd8081" + "f69c334200108781808000200041c0006a2009420042c8faf5ccb2eae9f6" + "f3004200108781808000200041a0016a41086a290300210d200041306a41" + "086a290300210f200029039001211720002903502114200041d0006a4108" + "6a2903002115200020002903602216200041f0016a41086a290300200e20" + "1154ad7c200a200e54ad7c221120002903307c220920004180016a41086a" + "2903002012200a54ad7c2013201254ad7c7c220a20002903a0017c220e20" + "0041b0016a41086a290300200b201054ad7c200c200b54ad7c7c22127c22" + "0b200041f0006a41086a29030020002903702213200c7c201354ad7c7c22" + "133703f832200020142017200f2009201154ad7c200a200954ad7c22107c" + "2209200d200e200a54ad7c2012200e54ad7c7c220c7c220a200041e0006a" + "41086a290300200b201654ad7c2013200b54ad7c7c220b37038033200020" + "004190016a41086a2903002009201054ad7c200c200954ad7c220e200029" + "03407c22092015200a200c54ad7c200b200a54ad7c7c220b370388332000" + "200041c0006a41086a2903002009200e54ad7c200b200954ad7c37039033" + "200041a0e8006a200041f8326a10a280808000200020002903b868370398" + "4e200020002903b0683703904e200020002903a8683703884e2000200029" + "03a0683703804e200041c0db006a410041301085818080001a2035410041" + "301085818080001a203441e086c0800041301086818080001a4101210220" + "0041013602e052200041003602d452200041003602c852200020333602c4" + "52200020004180ce006a3602c05203400240024020020d00200041086a20" + "0041c0d2006a10c48080800020002d0009210120002d000821030c010b20" + "0041003602e0520240024020002802c852450d00200041286a2002203210" + "c58080800020002802280d01200028022c21020b024020002802c0522201" + "450d0020002802c45221030340024020032001470d00200020033602c452" + "0c020b2000428080808080013702cc5220002003417f6a22033602c85220" + "0041206a2002203210c580808000024020002802200d0020002802242102" + "0c010b0b200020033602c4520c010b200041003602c852024020002802d4" + "52450d00200041186a2002203110c58080800020002802180d0120002802" + "1c21020b41002103200041003602d45220020d010b200041106a200041c0" + "d2006a10c48080800020002d0011210120002d001021030b024020034101" + "71450d00200041f8326a200041c0db006a10c680808000200041c0db006a" + "200041f8326a4190011086818080001a200041f8326a200041c0db006a20" + "004180d7006a10c780808000200041a0e8006a200041c0db006a200041f8" + "326a200110c880808000200041c0db006a200041a0e8006a419001108681" + "8080001a20002802e05221020c010b0b200041a0e8006a200041c0db006a" + "4190011086818080001a200041f8326a20004180236a200041a0e8006a10" + "c78080800020004180236a200041f8326a4190011086818080001a200441" + "016a21040c000b0b2000420137028433200041013602fc322000419482c0" + "80003602f83220004181808080003602a4682000200041a0e8006a360280" + "33200020004180d7006a3602a068200041c0d2006a41c886c08000200041" + "f8326a419c82c08000109680808000000b200220002802b40641b092c080" + "00108c80808000000b202f202e10868080800020002802c01c20002802c4" + "1c10828080800020002802a01520002802a4151084808080002000280288" + "15200028028c1510848080800020002802b41320002802b8131084808080" + "0020002802bc1220002802c01210848080800020002802e41020002802e8" + "10108480808000200028028c0f20002802900f1084808080002000280294" + "0e20002802980e108480808000200028029c0d20002802a00d1084808080" + "00410021020b200041e0ec006a24808080800020020ba60201087e200020" + "01290300220242ffffffff0f7c2203200254ad427f7c2202200220012903" + "0822047c2202200454ad7c20024282c88680d0ff96a1ac7f7c2204200254" + "ad7c427f7c423f8722022002200129031022057c2202200554ad7c200242" + "fbcff8b2fffe89e34c7c2205200254ad7c427f7c423f8722022002200129" + "031822067c2202200654ad7c200242b8858ab3cd9596898c7f7c22062002" + "54ad7c427f7c220242818080807083220720037c22083703002000200242" + "feb7f9ffaf80e9ded30083220920047c22032008200754ad7c2207370308" + "200020024285b087cd8081f69c3383220820057c22042003200954ad2007" + "200354ad7c7c22033703102000200242c8faf5ccb2eae9f6f3008320067c" + "2004200854ad2003200454ad7c7c3703180b1901017f2380808080004110" + "6b220120003a000f20012d000f0b3601017f23808080800041106b220224" + "8080808000200241013b010c200220013602082002200036020420024104" + "6a10f380808000000b6501017f23808080800041306b2202248080808000" + "200041306a200141306a41301086818080001a200041e0006a41e086c080" + "00200241004130108581808000220220012d006010908080800020002001" + "41301086818080001a200241306a2480808080000b25002000200141f087" + "c0800010df808080002000200110a98080800010d2808080003a00300be7" + "2502017f4c7e23808080800041b0096b2203248080808000200341c0046a" + "200229030022044200200129030022054200108781808000200341d0046a" + "20022903082206420020054200108781808000200341e0046a2002290310" + "2207420020054200108781808000200341f0046a20022903182208420020" + "05420010878180800020034180056a200229032022094200200542001087" + "8180800020034190056a2002290328220a42002005420010878180800020" + "0341a0056a20012903082205420020044200108781808000200341f0056a" + "2005420020064200108781808000200341c0066a20054200200742001087" + "8180800020034190076a2005420020084200108781808000200341e0076a" + "2005420020094200108781808000200341b0086a20054200200a42001087" + "81808000200341b0056a2001290310220542002004420010878180800020" + "034180066a2005420020064200108781808000200341d0066a2005420020" + "074200108781808000200341a0076a200542002008420010878180800020" + "0341f0076a2005420020094200108781808000200341c0086a2005420020" + "0a4200108781808000200341c0056a200129031822054200200442001087" + "8180800020034190066a2005420020064200108781808000200341e0066a" + "2005420020074200108781808000200341b0076a20054200200842001087" + "8180800020034180086a2005420020094200108781808000200341d0086a" + "20054200200a4200108781808000200341d0056a20012903202205420020" + "044200108781808000200341a0066a200542002006420010878180800020" + "0341f0066a2005420020074200108781808000200341c0076a2005420020" + "08420010878180800020034190086a200542002009420010878180800020" + "0341e0086a20054200200a4200108781808000200341e0056a2001290328" + "2205420020044200108781808000200341b0066a20054200200642001087" + "8180800020034180076a2005420020074200108781808000200341d0076a" + "2005420020084200108781808000200341a0086a20054200200942001087" + "81808000200341f0086a20054200200a4200108781808000200341b0046a" + "20032903c004220542fdfff3ffcffffff9897f7e2204420042abd5feffff" + "ffbfffb97f4200108781808000200341a0046a2004420042ffffcf8aebff" + "ffd51e4200108781808000200341b0036a2004420042a4ecc3b58fd4b498" + "e7004200108781808000200341c0026a2004420042bfa5949ccff0d2bbe4" + "004200108781808000200341d0016a2004420042d7d9ae9ae4f6e98dcb00" + "4200108781808000200341e0006a20044200429acdffcba3bdc4801a4200" + "10878180800020034190046a200341b0046a41086a290300200520032903" + "b00422047c200454ad7c220720032903a0047c220520032903a005220820" + "032903d0042209200341c0046a41086a2903007c220a7c220b7c220642fd" + "fff3ffcffffff9897f7e2204420042abd5feffffffbfffb97f4200108781" + "80800020034180046a2004420042ffffcf8aebffffd51e42001087818080" + "00200341f0036a2004420042a4ecc3b58fd4b498e7004200108781808000" + "200341e0036a2004420042bfa5949ccff0d2bbe400420010878180800020" + "0341d0036a2004420042d7d9ae9ae4f6e98dcb0042001087818080002003" + "41c0036a20044200429acdffcba3bdc4801a4200108781808000200341a0" + "036a200341a0046a41086a2903002005200754ad7c2006200554ad7c220c" + "20032903b0037c220520032903f005220d200341d0046a41086a29030020" + "0a200954ad7c220e20032903e0047c220f7c2207200341a0056a41086a29" + "0300200b200854ad7c7c220820032903b0057c22107c2209200329038004" + "7c220a20034190046a41086a290300200329039004220420067c200454ad" + "7c7c220642fdfff3ffcffffff9897f7e2204420042abd5feffffffbfffb9" + "7f420010878180800020034190036a2004420042ffffcf8aebffffd51e42" + "0010878180800020034180036a2004420042a4ecc3b58fd4b498e7004200" + "108781808000200341f0026a2004420042bfa5949ccff0d2bbe400420010" + "8781808000200341e0026a2004420042d7d9ae9ae4f6e98dcb0042001087" + "81808000200341d0026a20044200429acdffcba3bdc4801a420010878180" + "8000200341b0026a20034180046a41086a290300200a200954ad7c200620" + "0a54ad7c221120032903f0037c220a200341b0036a41086a290300200520" + "0c54ad7c2009200554ad7c221220032903c0027c2205200341e0046a4108" + "6a290300200f200e54ad7c220f20032903f0047c220920032903c0067c22" + "0b200341f0056a41086a2903002007200d54ad7c2008200754ad7c7c2207" + "2003290380067c220c200341b0056a41086a2903002010200854ad7c7c22" + "0820032903c0057c22107c22137c220d2003290390037c220e200341a003" + "6a41086a29030020032903a003220420067c200454ad7c7c220642fdfff3" + "ffcffffff9897f7e2204420042abd5feffffffbfffb97f42001087818080" + "00200341a0026a2004420042ffffcf8aebffffd51e420010878180800020" + "034190026a2004420042a4ecc3b58fd4b498e70042001087818080002003" + "4180026a2004420042bfa5949ccff0d2bbe4004200108781808000200341" + "f0016a2004420042d7d9ae9ae4f6e98dcb004200108781808000200341e0" + "016a20044200429acdffcba3bdc4801a4200108781808000200341c0016a" + "20034190036a41086a290300200e200d54ad7c2006200e54ad7c22142003" + "290380037c220e200341f0036a41086a290300200a201154ad7c200d200a" + "54ad7c221520032903e0037c220a200341c0026a41086a29030020052012" + "54ad7c2013200554ad7c221220032903d0017c2205200341f0046a41086a" + "2903002009200f54ad7c22132003290380057c220d2003290390077c220f" + "200341c0066a41086a290300200b200954ad7c2007200b54ad7c7c220920" + "032903d0067c220b20034180066a41086a290300200c200754ad7c200820" + "0c54ad7c7c22072003290390067c220c200341c0056a41086a2903002010" + "200854ad7c7c220820032903d0057c22167c22177c22187c221020032903" + "a0027c2211200341b0026a41086a29030020032903b002220420067c2004" + "54ad7c7c220642fdfff3ffcffffff9897f7e2204420042abd5feffffffbf" + "ffb97f4200108781808000200341b0016a2004420042ffffcf8aebffffd5" + "1e4200108781808000200341a0016a2004420042a4ecc3b58fd4b498e700" + "420010878180800020034190016a2004420042bfa5949ccff0d2bbe40042" + "0010878180800020034180016a2004420042d7d9ae9ae4f6e98dcb004200" + "108781808000200341f0006a20044200429acdffcba3bdc4801a42001087" + "81808000200341d0006a200341a0026a41086a2903002011201054ad7c20" + "06201154ad7c22192003290390027c221120034180036a41086a29030020" + "0e201454ad7c2010200e54ad7c221a20032903f0027c220e200341e0036a" + "41086a290300200a201554ad7c2018200a54ad7c221820032903d0037c22" + "0a200341d0016a41086a2903002005201254ad7c2017200554ad7c221520" + "032903607c220520034180056a41086a290300200d201354ad7c22172003" + "290390057c221020032903e0077c221220034190076a41086a290300200f" + "200d54ad7c2009200f54ad7c7c220d20032903a0077c220f200341d0066a" + "41086a290300200b200954ad7c2007200b54ad7c7c220920032903e0067c" + "220b20034190066a41086a290300200c200754ad7c2008200c54ad7c7c22" + "0720032903a0067c220c200341d0056a41086a2903002016200854ad7c7c" + "220820032903e0057c22167c221b7c221c7c221d7c221320032903b0017c" + "2214200341c0016a41086a29030020032903c001220420067c200454ad7c" + "7c220642fdfff3ffcffffff9897f7e2204420042abd5feffffffbfffb97f" + "4200108781808000200341c0006a2004420042ffffcf8aebffffd51e4200" + "108781808000200341306a2004420042a4ecc3b58fd4b498e70042001087" + "81808000200341206a2004420042bfa5949ccff0d2bbe400420010878180" + "8000200341106a2004420042d7d9ae9ae4f6e98dcb004200108781808000" + "200320044200429acdffcba3bdc4801a4200108781808000200341c0036a" + "41086a290300211e200341b0066a41086a290300211f200341f0066a4108" + "6a2903002120200341b0076a41086a2903002121200341f0076a41086a29" + "03002122200341b0086a41086a290300212320032903c008212420032903" + "8008212520032903c0072126200329038007212720032903d00221282003" + "41d0026a41086a2903002129200341e0026a41086a290300212a20034180" + "076a41086a290300212b200341c0076a41086a290300212c20034180086a" + "41086a290300212d200341c0086a41086a290300212e20032903d008212f" + "200329039008213020032903d007213120032903e0012132200341e0016a" + "41086a290300213320032903f0012134200341f0016a41086a2903002135" + "20034180026a41086a2903002136200341d0076a41086a29030021372003" + "4190086a41086a2903002138200341d0086a41086a290300213920032903" + "e008213a20032903a008213b2003290370213c200341f0006a41086a2903" + "00213d200329038001213e20034180016a41086a290300213f2003290390" + "01214020034190016a41086a2903002141200341a0016a41086a29030021" + "42200341a0086a41086a2903002143200341e0086a41086a290300214420" + "032903f008214520032903002146200341086a2903002147200329031021" + "48200341106a41086a29030021492003290320214a200341206a41086a29" + "0300214b2003290330214c200341306a41086a290300214d200320032903" + "40224e20034190056a41086a2903002010201754ad7c224f20032903b008" + "7c2204200341e0076a41086a2903002012201054ad7c200d201254ad7c7c" + "221020032903f0077c2212200341a0076a41086a290300200f200d54ad7c" + "2009200f54ad7c7c220d20032903b0077c220f200341e0066a41086a2903" + "00200b200954ad7c2007200b54ad7c7c220920032903f0067c220b200341" + "a0066a41086a290300200c200754ad7c2008200c54ad7c7c220720032903" + "b0067c220c200341e0056a41086a2903002016200854ad7c7c2208200341" + "e0006a41086a2903002005201554ad7c201b200554ad7c7c220520032903" + "c0037c2215200341d0036a41086a290300200a201854ad7c201c200a54ad" + "7c7c220a20032903e0027c2216200341f0026a41086a290300200e201a54" + "ad7c201d200e54ad7c7c220e2003290380027c221720034190026a41086a" + "2903002011201954ad7c2013201154ad7c7c221120032903a0017c221820" + "0341b0016a41086a2903002014201354ad7c2006201454ad7c7c22197c22" + "13200341d0006a41086a2903002003290350221420067c201454ad7c7c22" + "1a370380092003204c204020342028202720262025202420232004204f54" + "ad7c2010200454ad7c221b7c220420222012201054ad7c200d201254ad7c" + "7c22067c22102021200f200d54ad7c2009200f54ad7c7c220d7c220f2020" + "200b200954ad7c2007200b54ad7c7c22097c220b201f200c200754ad7c20" + "08200c54ad7c7c22072005200854ad7c2208201e2015200554ad7c200a20" + "1554ad7c7c22057c220c202a2016200a54ad7c200e201654ad7c7c220a7c" + "221220362017200e54ad7c2011201754ad7c7c220e7c2214204220182011" + "54ad7c2019201854ad7c7c22117c2215200341c0006a41086a2903002013" + "204e54ad7c201a201354ad7c7c2213370388092003204a203e2032200820" + "0754ad2005200854ad7c221620312030202f202e2004201b54ad7c200620" + "0454ad7c22177c2204202d2010200654ad7c200d201054ad7c7c22067c22" + "08202c200f200d54ad7c2009200f54ad7c7c220d7c220f202b200b200954" + "ad7c2007200b54ad7c7c22107c22072029200c200554ad7c200a200c54ad" + "7c7c22057c220920352012200a54ad7c200e201254ad7c7c220a7c220b20" + "412014200e54ad7c2011201454ad7c7c220c7c220e204d2015201154ad7c" + "2013201554ad7c7c22113703900920032048203c2007201654ad20052007" + "54ad7c2212203b203a20392004201754ad7c2006200454ad7c22137c2204" + "20382008200654ad7c200d200854ad7c7c22067c22072037200f200d54ad" + "7c2010200f54ad7c7c220d7c220820332009200554ad7c200a200954ad7c" + "7c22057c2209203f200b200a54ad7c200c200b54ad7c7c220a7c220b204b" + "200e200c54ad7c2011200e54ad7c7c220c37039809200320462008201254" + "ad2005200854ad7c2208204520442004201354ad7c2006200454ad7c220e" + "7c220420432007200654ad7c200d200754ad7c7c220d7c2206203d200920" + "0554ad7c200a200954ad7c7c22057c22072049200b200a54ad7c200c200b" + "54ad7c7c22093703a00920032006200854ad2005200654ad7c200341f008" + "6a41086a2903002004200e54ad7c200d200454ad7c7c20472007200554ad" + "7c2009200754ad7c7c3703a809200020034180096a10d680808000200341" + "b0096a2480808080000b3701017f20004100413010858180800021004101" + "10a3808080002101200041306a41e086c0800041301086818080001a2000" + "20013a00600b3a01017f23808080800041306b2201248080808000200020" + "0141004130108581808000220110db808080002100200141306a24808080" + "800020000b42002000200120022003109080808000200041306a20014130" + "6a200241306a2003109080808000200020022d006020012d006022027341" + "0020036b712002733a00600bd80d010b7f23808080800041c0176b220224" + "808080800020012d00c0012103410021042002410010a3808080003a0088" + "03200242f2b7f89e96d4f0950b37038003200242ed95f3a18a8ad68b6737" + "03f802200242bac6f6c9ec89d7a4f9003703f002200242a0d793dfa38deb" + "d6867f3703e802200242dcc3d1d8a2e189d5183703e002200242dde092fb" + "ad92bfe0ad7f3703d802200242e5b583f4e7b1ffc1003703d002200242a2" + "cbbc87dfaeeae9073703c802200242df92b5f096bdedf7bb7f3703c00220" + "0242dac6a9d0caada1f3673703b802200242dab8daf1f5c3bebed9003703" + "b002200242ca98a58286dfc2b9cc003703a802200242f3db839b97c18ac9" + "113703a002200242c78ad690efa1bbdb4237039802200242e7e686aac8d9" + "ad8d1b3703900220024286f099948ec3dfd83b37038802200242c3c1b5e6" + "dbb3b1d0aa7f3703800220024286ec8ff1d98ef0d4a57f3703f801200242" + "d7f9c29aa4b2e4c0053703f001200242ebec8cc3b1ecedb3ef003703e801" + "200242e9ddf2d1d1b3a6ca987f3703e00120024280cbabf1d3f6a4d4a17f" + "3703d8012002429aacd2bde8e4fefab37f3703d0012002429094d094a0f4" + "a3f9753703c80120022001200241c8016a200310d980808000200241c005" + "6a200210e880808000200241c8016a41c400410841a002108e8080800020" + "022802cc0121010240024020022802c8014101460d0020022802d0012105" + "200241c8016a200241c0056a41a0021086818080001a200241c8016a41a0" + "026a200241c8011086818080002106200241003602b805200220053602b4" + "05200220013602b005200241c0056a41c0016a2107200241c0056a41e000" + "6a2108200241c8016a41e0006a2109200241c8046a210a200241c8016a41" + "c0016a2105200241b0056a210b413f2101024003402001417f460d014280" + "8082808080a080e9002001413f71ad88a7210c0240024020044101710d00" + "200c21040c010b41012104200241c8016a10ed80808000200c410171450d" + "00200241e0076a200510ba80808000200241c0086a200a10ba8080800020" + "0241a0096a200241e0076a200610b380808000200241e0166a200a200510" + "bc8080800020024180166a200241e0166a10ba80808000200241a0156a20" + "024180166a200241c0086a10bb8080800020024180166a200241a0156a20" + "0241e0076a10bb80808000200241800a6a20024180166a200241e0076a10" + "b380808000200241e00a6a200241a0096a200241c8016a10bb8080800020" + "0241c00b6a200241e00a6a10ba80808000200241a00c6a200241c00b6a20" + "0241c00b6a10bc80808000200241800d6a200241a00c6a200241a00c6a10" + "bc80808000200241e00d6a200241800d6a200241e00a6a10b38080800020" + "0241e0166a200241800a6a200910bb80808000200241c00e6a200241e016" + "6a200910bb80808000200241a00f6a200241c00e6a200610b38080800020" + "024180106a200241800d6a200241c8016a10b380808000200241e0166a20" + "0241c00e6a10ba8080800020024180166a200241e0166a200241e00d6a10" + "bb80808000200241e0166a20024180166a20024180106a10bb8080800020" + "0241c8016a200241e0166a20024180106a10bb80808000200241e0166a20" + "05200241e00a6a10bc8080800020024180166a200241e0166a10ba808080" + "00200241a0156a20024180166a200241e0076a10bb808080002005200241" + "a0156a200241c00b6a10bb80808000200241e0106a200a200510bc808080" + "00200241e0166a20024180106a200241c8016a10bb80808000200241c011" + "6a200241e0166a200241c00e6a10b380808000200241a0126a2009200241" + "e00d6a10b38080800020024180136a200241a0126a200241a0126a10bc80" + "8080002009200241c0116a20024180136a10bb80808000200241e0166a20" + "0241e0106a10ba80808000200241e0136a200241e0166a200241c0086a10" + "bb80808000200241c0146a200510ba80808000200241a0156a200241e013" + "6a200241c0146a10bb80808000200241e0166a200241a00f6a200241a00f" + "6a10bc8080800020024180166a200241e0166a200241a0156a10bb808080" + "00200241c0056a2005200510bc80808000200241e0166a200241c00e6a10" + "e2808080002008200241e0166a200241e0166a10bc808080002007200241" + "80166a41e0001086818080001a200b200241c0056a41bc8cc0800010ee80" + "8080000b2001417f6a21010c000b0b200241c8016a10ed80808000200220" + "022802b80522013602e016200141c400470d01200020033a000c2000200b" + "290200370200200041086a200b41086a280200360200200241c0176a2480" + "808080000f0b200120022802d00141888cc08000108c80808000000b2002" + "41003602c005200241e0166a200241c0056a10ef80808000000b8e010101" + "7f2380808080004180036b2201248080808000200141a0026a41306a4100" + "41301085818080001a200141a0026a41e086c0800041301086818080001a" + "2001200141a0026a41e000108681808000220141e0006a410041c0011085" + "818080001a200041a0026a410041a0021085818080001a2000200141a002" + "1086818080001a20014180036a2480808080000bd70301157f2380808080" + "0041c00d6b2203248080808000200241e0036a210420024180036a210520" + "0241a0026a2106200241c0016a2107200241e0006a210820012802044103" + "742109200341c0046a41a0026a210a200341a00b6a41c0016a210b200341" + "a00b6a41e0006a210c200341e0036a210d20034180036a210e200341a002" + "6a210f20034180096a41c0016a211020034180096a41e0006a2111200341" + "c0016a2112200341e0006a21132001280200211420012802082115034002" + "4020090d002001201541016a3602082000200241c0041086818080001a20" + "0341c00d6a2480808080000f0b201428020422162d000c20142802002d00" + "607210a380808000211720032002201641046a280200201641086a280200" + "201541cc8cc0800010ae80808000201428020010af808080002003418009" + "6a20032002201710b080808000201120132008201710b080808000201020" + "122007201710b080808000200341a00b6a200f2006201710b08080800020" + "0c200e2005201710b080808000200b200d2004201710b080808000200341" + "c0046a20034180096a41a0021086818080001a200a200341a00b6a41a002" + "1086818080001a2002200341c0046a41c0041086818080001a200941786a" + "2109201441086a21140c000b0b22000240200120024b0d00200220012003" + "10f080808000000b2000200241a0026c6a0bd60301027f23808080800041" + "e00f6b22042480808080002004200241e000108681808000220441e0006a" + "200241e0006a41e0001086818080001a2004200341306a220510dd808080" + "00200441306a200510dd80808000200441e0006a200310dd808080002004" + "41e0006a41306a200310dd80808000200441c0016a2001200241c0016a22" + "02200441e0006a10e980808000200441c00d6a200141e0036a200410b380" + "808000200441a00b6a200441c00d6a200441c00d6a41306a220310b88080" + "8000200441a00b6a41306a200441c00d6a200310b980808000200441e003" + "6a41e0006a200141a0026a2203200410b380808000200441e0036a41c001" + "6a20014180036a200410b380808000200441e0036a200441a00b6a41e000" + "1086818080001a20044180066a200441e0006a200410bc80808000200441" + "e0066a2003200110c38080800020044180096a200441e0066a2002200441" + "80066a10e980808000200441c00d6a20044180096a200441c0016a10b780" + "808000200441a00b6a200441c00d6a200441e0036a10b780808000200441" + "c00d6a200441e0036a10b6808080002000200441c00d6a200441c0016a10" + "c380808000200041a0026a200441a00b6a41a0021086818080001a200441" + "e00f6a2480808080000b2700200020012002200310908080800020004130" + "6a200141306a200241306a20031090808080000b30002000200110e28080" + "8000200041e0006a200141e0006a10e280808000200041c0016a200141c0" + "016a10e2808080000bbd0201097e2000420042002001290300220242abd5" + "feffffffbfffb97f56ad7d2203200129030822047d220542ffffcf8aebff" + "ffd51e7c2206200420028420012903102207842001290318220884200129" + "03202209842001290328220a845022011b3703082000420042abd5feffff" + "ffbfffb97f20027d20011b3703002000420020032003200454ad7d200620" + "0554ad7c423f87220220077d220342a4ecc3b58fd4b498e7007c22042001" + "1b3703102000420020022002200754ad7d2004200354ad7c423f87220220" + "087d220342bfa5949ccff0d2bbe4007c220420011b370318200042002002" + "2002200854ad7d2004200354ad7c423f87220220097d220342d7d9ae9ae4" + "f6e98dcb007c220420011b3703202000420020022002200954ad7d200420" + "0354ad7c423f87200a7d429acdffcba3bdc4801a7c20011b3703280bc701" + "01057f23808080800041c0016b2203248080808000200341306a22042001" + "41306a220510b280808000200320014130108681808000220341e0006a41" + "306a200241306a220641301086818080002107200341e0006a2002413010" + "86818080001a20002003200341e0006a10e1808080002004200541301086" + "818080001a200320014130108681808000220341e0006a20064130108681" + "8080001a2007200241301086818080001a200041306a2003200341e0006a" + "10e180808000200341c0016a2480808080000bcd0b01167f238080808000" + "41a0086b22032480808080002003200241e0006a220420024190016a2205" + "10b980808000200341306a2004200510b880808000200341e0006a200241" + "c0016a2206200241f0016a220710b98080800020034190016a2006200710" + "b880808000200341e0036a41306a2208200141306a220910b28080800020" + "0341e0036a41e0006a200141e0006a220a4130108681808000210b200341" + "e0036a4190016a220c20014190016a220d10b280808000200341e0036a41" + "c0016a200141c0016a220e4130108681808000210f200341e0036a41f001" + "6a2210200141f0016a221110b280808000200341e0036a20014130108681" + "8080001a20034180066a41306a200241306a221241301086818080002113" + "20034180066a200241301086818080001a20034180066a41e0006a200341" + "90016a4130108681808000211420034180066a4190016a200341e0006a41" + "30108681808000211520034180066a41c0016a200341306a413010868180" + "8000211620034180066a41f0016a200341301086818080002117200341c0" + "016a200341e0036a20034180066a10ea8080800020082009413010868180" + "80002108200b200a41301086818080002118200c200d4130108681808000" + "210b200f200e4130108681808000210f201020114130108681808000210c" + "200341e0036a200141301086818080001a20034180066a20124130108681" + "8080001a20132002413010868180800021102014200341e0006a41301086" + "818080002113201520034190016a41301086818080002114201620034130" + "10868180800021152017200341306a41301086818080002116200341c001" + "6a41306a200341e0036a20034180066a10ea808080002008200910b28080" + "80002018200a41301086818080002117200b200d10b280808000200f200e" + "4130108681808000210f200c201110b280808000200341e0036a20014130" + "1086818080001a20034180066a200441301086818080001a201020054130" + "108681808000211020142012413010868180800021142013200241301086" + "818080002113201520034190016a413010868180800021152016200341e0" + "006a41301086818080002116200341a0026a200341e0036a20034180066a" + "10ea8080800020082009413010868180800021082017200a413010868180" + "80002117200b200d4130108681808000210b200f200e4130108681808000" + "210f200c20114130108681808000210c200341e0036a2001413010868180" + "80001a20034180066a200541301086818080001a20102004413010868180" + "800021102013201241301086818080002113201420024130108681808000" + "21142015200341e0006a41301086818080002115201620034190016a4130" + "1086818080002116200341a0026a41306a200341e0036a20034180066a10" + "ea808080002008200910b2808080002017200a4130108681808000211720" + "0b200d10b280808000200f200e4130108681808000210f200c201110b280" + "808000200341e0036a200141301086818080001a20034180066a20064130" + "1086818080001a2010200741301086818080002110201320044130108681" + "808000211320142005413010868180800021142016201241301086818080" + "002116201520024130108681808000211520034180036a200341e0036a20" + "034180066a10ea808080002008200941301086818080001a2017200a4130" + "1086818080001a200b200d41301086818080001a200f200e413010868180" + "80001a200c201141301086818080001a200341e0036a2001413010868180" + "80001a20034180066a200741301086818080001a20102006413010868180" + "80001a2013200541301086818080001a2014200441301086818080001a20" + "15201241301086818080001a2016200241301086818080001a2003418003" + "6a41306a200341e0036a20034180066a10ea808080002000200341c0016a" + "41e000108681808000220241e0006a200341a0026a41e000108681808000" + "1a200241c0016a20034180036a41e0001086818080001a200341a0086a24" + "80808080000bb30301027f23808080800041e0066b220224808080800020" + "02200110ba80808000200241e0006a2001200141e0006a220310b3808080" + "00200241c0016a200241e0006a200241e0006a10bc808080002002418006" + "6a2001200310bb80808000200241a0056a20024180066a200141c0016a22" + "0110bc80808000200241a0026a200241a0056a10ba808080002002418003" + "6a2003200110b380808000200241e0036a20024180036a20024180036a10" + "bc80808000200241c0046a200110ba8080800020024180066a200241e003" + "6a200241e0036a41306a220110b88080800020024180066a41306a220320" + "0241e0036a200110b980808000200020024180066a200210bc8080800020" + "024180066a200241c0046a200241c0046a41306a220110b8808080002003" + "200241c0046a200110b980808000200041e0006a20024180066a200241c0" + "016a10bc8080800020024180066a200241c0016a200241a0026a10bc8080" + "8000200241a0056a20024180066a200241e0036a10bc8080800020024180" + "066a200241a0056a200210bb80808000200041c0016a20024180066a2002" + "41c0046a10bb80808000200241e0066a2480808080000b7c01037f238080" + "80800041e0006b22022480808080002002200141c0016a2203200141f001" + "6a220410b880808000200241306a2003200410b980808000200041c0016a" + "200141e0006a41e0001086818080001a2000200241e00010868180800041" + "e0006a200141e0001086818080001a200241e0006a2480808080000b3e00" + "20002001200210bb80808000200041e0006a200141e0006a200241e0006a" + "10bb80808000200041c0016a200141c0016a200241c0016a10bb80808000" + "0b3601017f23808080800041306b22032480808080002003200210b28080" + "800020002003200110b980808000200341306a2480808080000b87020201" + "7f0c7e23808080800041306b220324808080800020012903082104200229" + "030821052002290328210620012903282107200229032021082001290320" + "21092002290318210a2001290318210b2002290310210c2001290310210d" + "20032002290300220e20012903007c220f3703002003200520047c220420" + "0f200e54ad7c220e3703082003200c200d7c220d2004200554ad200e2004" + "54ad7c7c22043703102003200a200b7c2205200d200c54ad2004200d54ad" + "7c7c22043703182003200820097c220c2005200a54ad2004200554ad7c7c" + "22053703202003200620077c200c200854ad2005200c54ad7c7c37032820" + "00200310d680808000200341306a2480808080000b7401027f2380808080" + "004190016b220224808080800020022001200141306a220310b980808000" + "200241306a2001200310b880808000200241e0006a2001200110b9808080" + "0020002002200241306a10a780808000200041306a200241e0006a200310" + "a78080800020024190016a2480808080000b230020002001200210b88080" + "8000200041306a200141306a200241306a10b8808080000b230020002001" + "200210b980808000200041306a200141306a200241306a10b9808080000b" + "c71f02017f3b7e23808080800041c0076b2202248080808000200241c004" + "6a200129030822034200200129030022044200108781808000200241d004" + "6a20012903102205420020044200108781808000200241e0046a20012903" + "182206420020044200108781808000200241f0046a200129032022074200" + "2004420010878180800020024180056a2001290328220842002004420010" + "8781808000200241a0056a2005420020034200108781808000200241b005" + "6a2006420020034200108781808000200241c0056a200742002003420010" + "8781808000200241d0056a2008420020034200108781808000200241f005" + "6a200642002005420010878180800020024180066a200742002005420010" + "878180800020024190066a2008420020054200108781808000200241b006" + "6a2007420020064200108781808000200241c0066a200842002006420010" + "8781808000200241e0066a20084200200742001087818080002002419005" + "6a2004420020044200108781808000200241e0056a200342002003420010" + "8781808000200241a0066a2005420020054200108781808000200241d006" + "6a2006420020064200108781808000200241f0066a200742002007420010" + "878180800020024180076a2008420020084200108781808000200241b004" + "6a200229039005220642fdfff3ffcffffff9897f7e2203420042abd5feff" + "ffffbfffb97f4200108781808000200241a0046a2003420042ffffcf8aeb" + "ffffd51e420010878180800020024190046a2003420042a4ecc3b58fd4b4" + "98e700420010878180800020024180046a2003420042bfa5949ccff0d2bb" + "e4004200108781808000200241f0036a2003420042d7d9ae9ae4f6e98dcb" + "004200108781808000200241e0036a20034200429acdffcba3bdc4801a42" + "00108781808000200241d0036a20024190056a41086a2903002209200229" + "03c00422084201867c220420022903a0047c2205200241b0046a41086a29" + "030020022903b00422032006427d837c200354ad7c7c220642fdfff3ffcf" + "fffff9897f7e2203420042abd5feffffffbfffb97f420010878180800020" + "0241c0036a2003420042ffffcf8aebffffd51e4200108781808000200241" + "d0026a2003420042a4ecc3b58fd4b498e7004200108781808000200241e0" + "016a2003420042bfa5949ccff0d2bbe4004200108781808000200241f000" + "6a2003420042d7d9ae9ae4f6e98dcb004200108781808000200220034200" + "429acdffcba3bdc4801a4200108781808000200241b0036a20022903c003" + "220a20022903e005220b20022903d004220c200241c0046a41086a290300" + "7c22074201862008423f88847c22082004200954ad7c2209200229039004" + "7c220d200241a0046a41086a2903002005200454ad7c2006200554ad7c7c" + "220e7c2204200241d0036a41086a29030020022903d003220320067c2003" + "54ad7c7c220542fdfff3ffcffffff9897f7e2203420042abd5feffffffbf" + "ffb97f4200108781808000200241a0036a2003420042ffffcf8aebffffd5" + "1e420010878180800020024190036a2003420042a4ecc3b58fd4b498e700" + "420010878180800020024180036a2003420042bfa5949ccff0d2bbe40042" + "00108781808000200241f0026a2003420042d7d9ae9ae4f6e98dcb004200" + "108781808000200241e0026a20034200429acdffcba3bdc4801a42001087" + "81808000200241c0026a20022903a003220f200241e0056a41086a290300" + "2008200b54ad7c2009200854ad7c2210200241d0046a41086a2903002007" + "200c54ad7c220c20022903e0047c220620022903a0057c22084201862007" + "423f88847c22072002290380047c220b20024190046a41086a290300200d" + "200954ad7c200e200d54ad7c7c220920022903d0027c220d200241c0036a" + "41086a2903002004200a54ad7c2005200454ad7c7c220a7c2204200241b0" + "036a41086a29030020022903b003220320057c200354ad7c7c220542fdff" + "f3ffcffffff9897f7e2203420042abd5feffffffbfffb97f420010878180" + "8000200241b0026a2003420042ffffcf8aebffffd51e4200108781808000" + "200241a0026a2003420042a4ecc3b58fd4b498e700420010878180800020" + "024190026a2003420042bfa5949ccff0d2bbe40042001087818080002002" + "4180026a2003420042d7d9ae9ae4f6e98dcb004200108781808000200241" + "f0016a20034200429acdffcba3bdc4801a4200108781808000200241d001" + "6a20022903b0022211200241d0026a41086a290300200d200954ad7c200a" + "200d54ad7c221220022903e0017c220d20024180046a41086a290300200b" + "200754ad7c2009200b54ad7c221320022903f0037c22092007201054ad22" + "0e20022903a0067c2207200241e0046a41086a2903002006200c54ad7c22" + "1020022903f0047c220b20022903b0057c220a200241a0056a41086a2903" + "002008200654ad7c7c22064201862008423f88847c22147c22157c220820" + "02290390037c220c200241a0036a41086a2903002004200f54ad7c200520" + "0454ad7c7c22167c2204200241c0026a41086a29030020022903c0022203" + "20057c200354ad7c7c220542fdfff3ffcffffff9897f7e2203420042abd5" + "feffffffbfffb97f4200108781808000200241c0016a2003420042ffffcf" + "8aebffffd51e4200108781808000200241b0016a2003420042a4ecc3b58f" + "d4b498e7004200108781808000200241a0016a2003420042bfa5949ccff0" + "d2bbe400420010878180800020024190016a2003420042d7d9ae9ae4f6e9" + "8dcb00420010878180800020024180016a20034200429acdffcba3bdc480" + "1a4200108781808000200241e0006a20022903c0012217200241a0066a41" + "086a2903002007200e54ad7c2014200754ad7c2214200241f0046a41086a" + "290300200b201054ad7c22182002290380057c220720022903c0057c220e" + "200241b0056a41086a290300200a200b54ad7c2006200a54ad7c7c220b20" + "022903f0057c220a4201862006423f88847c220620022903e0037c220f20" + "0241f0036a41086a2903002009201354ad7c2015200954ad7c7c22092002" + "2903707c2210200241e0016a41086a290300200d201254ad7c2008200d54" + "ad7c7c220d2002290380037c221220024190036a41086a290300200c2008" + "54ad7c2016200c54ad7c7c220820022903a0027c220c200241b0026a4108" + "6a2903002004201154ad7c2005200454ad7c7c22157c2204200241d0016a" + "41086a29030020022903d001220320057c200354ad7c7c220542fdfff3ff" + "cffffff9897f7e2203420042abd5feffffffbfffb97f4200108781808000" + "200241d0006a2003420042ffffcf8aebffffd51e42001087818080002002" + "41c0006a2003420042a4ecc3b58fd4b498e7004200108781808000200241" + "306a2003420042bfa5949ccff0d2bbe4004200108781808000200241206a" + "2003420042d7d9ae9ae4f6e98dcb004200108781808000200241106a2003" + "4200429acdffcba3bdc4801a4200108781808000200241086a2903002116" + "200241d0066a41086a290300211920024180066a41086a290300211a2002" + "41d0056a41086a290300211b200229039006211c20022903b006211d2002" + "2903e002211e200241e0026a41086a290300211f200241f0026a41086a29" + "03002120200241b0066a41086a290300212120024190066a41086a290300" + "212220022903c006212320022903f006210320022903f0012124200241f0" + "016a41086a2903002125200229038002212620024180026a41086a290300" + "212720024190026a41086a2903002128200241c0066a41086a2903002129" + "20022903e006212a200241f0066a41086a290300212b200229038001212c" + "20024180016a41086a290300212d200229039001212e20024190016a4108" + "6a290300212f20022903a0012130200241a0016a41086a29030021312002" + "41b0016a41086a2903002132200241e0066a41086a290300213320022903" + "8007211120022903102134200241106a41086a2903002135200229032021" + "36200241206a41086a290300213720022903302138200241306a41086a29" + "030021392002290340213a200241c0006a41086a290300213b2002200229" + "0350223c2006201454ad223d20022903d0067c221320024180056a41086a" + "2903002007201854ad7c221820022903d0057c2214200241c0056a41086a" + "290300200e200754ad7c200b200e54ad7c7c22072002290380067c220e20" + "0241f0056a41086a290300200a200b54ad7c7c220b420186200a423f8884" + "7c220a200241e0036a41086a290300200f200654ad7c2009200f54ad7c7c" + "220620022903007c220f200241f0006a41086a2903002010200954ad7c20" + "0d201054ad7c7c220920022903f0027c221020024180036a41086a290300" + "2012200d54ad7c2008201254ad7c7c220d2002290390027c2212200241a0" + "026a41086a290300200c200854ad7c2015200c54ad7c7c220820022903b0" + "017c220c200241c0016a41086a2903002004201754ad7c2005200454ad7c" + "7c22157c2204200241e0006a41086a2903002002290360221720057c2017" + "54ad7c7c2217370390072002203a20302026201e20192013203d54ad7c20" + "0a201354ad7c2213201d201c201b2014201854ad7c2007201454ad7c2214" + "7c2205201a200e200754ad7c200b200e54ad7c7c22077c220e420186200b" + "423f88847c220b2006200a54ad7c220a2016200f200654ad7c2009200f54" + "ad7c7c22067c220f20202010200954ad7c200d201054ad7c7c22097c2210" + "20282012200d54ad7c2008201254ad7c7c220d7c22122032200c200854ad" + "7c2015200c54ad7c7c22087c220c200241d0006a41086a2903002004203c" + "54ad7c2017200454ad7c7c22153703980720022038202e2024200a200b54" + "ad2006200a54ad7c22162003202320222005201454ad7c2007200554ad7c" + "22147c22042021200e200754ad7c7c2205420186200e423f88847c220720" + "0b201354ad7c22137c220b201f200f200654ad7c2009200f54ad7c7c2206" + "7c220a20272010200954ad7c200d201054ad7c7c22097c220e2031201220" + "0d54ad7c2008201254ad7c7c220d7c220f203b200c200854ad7c2015200c" + "54ad7c7c220c3703a00720022036202c200b201654ad2006200b54ad7c22" + "0b202b2007200354ad7c2013200754ad7c2210202a20292004201454ad7c" + "2005200454ad7c22127c22034201862005423f88847c22137c2204202520" + "0a200654ad7c2009200a54ad7c7c22057c2206202f200e200954ad7c200d" + "200e54ad7c7c22077c22082039200f200d54ad7c200c200f54ad7c7c2209" + "3703a807200220342004200b54ad2005200454ad7c220d20112033200320" + "1254ad7c220b4201862003423f88847c22032013201054ad7c220a7c2204" + "202d2006200554ad7c2007200654ad7c7c22057c220620372008200754ad" + "7c2009200854ad7c7c22073703b00720022004200d54ad2005200454ad7c" + "200b423f8820024180076a41086a2903002003201154ad7c200a200354ad" + "7c7c7c20352006200554ad7c2007200654ad7c7c3703b807200020024190" + "076a10d680808000200241c0076a2480808080000be60101037f23808080" + "80004180126b220324808080800020032001200210b480808000200341a0" + "026a200141a0026a2204200241a0026a220510b480808000200341c0046a" + "2002200510c380808000200341e0066a2004200110c38080800020034180" + "096a200341e0066a200341c0046a10b480808000200341a00b6a20034180" + "096a200310b780808000200341c00d6a200341a00b6a200341a0026a10b7" + "80808000200341e00f6a200341a0026a10b6808080002000200341e00f6a" + "200310c380808000200041a0026a200341c00d6a41a0021086818080001a" + "20034180126a2480808080000b3c01017f23808080800041c0046b220224" + "808080800020022000200110be808080002000200241c004108681808000" + "1a200241c0046a2480808080000bd80701077f23808080800041c00d6b22" + "022480808080002002200141e000108681808000220241e0006a200141e0" + "006a220341e0001086818080001a200241c0016a200141c0016a220441e0" + "001086818080001a200241a0026a200141a0026a220541e0001086818080" + "001a20024180036a20014180036a220641e0001086818080001a200241e0" + "036a200141e0036a220741e0001086818080001a200241a00b6a20012006" + "10eb80808000200241c0046a200241a00b6a41e0001086818080001a2002" + "41a0056a200241a00b6a41e0006a220841e0001086818080001a20022002" + "41c0046a200110bb80808000200241a00b6a2002200210bc808080002002" + "200241a00b6a200241c0046a10bc8080800020024180036a200241a0056a" + "200610bc80808000200241a00b6a20024180036a20024180036a10bc8080" + "800020024180036a200241a00b6a200241a0056a10bc80808000200241a0" + "0b6a2005200410eb8080800020024180066a200241a00b6a41e000108681" + "8080001a200241e0066a200841e0001086818080001a200241a00b6a2003" + "200710eb80808000200241c0076a200241a00b6a41e0001086818080001a" + "200241a0086a200841e0001086818080001a200241e0006a20024180066a" + "200310bb80808000200241a00b6a200241e0006a200241e0006a10bc8080" + "8000200241e0006a200241a00b6a20024180066a10bc80808000200241e0" + "036a200241e0066a200710bc80808000200241a00b6a200241e0036a2002" + "41e0036a10bc80808000200241e0036a200241a00b6a200241e0066a10bc" + "80808000200241a00b6a200241a0086a200241a0086a41306a220110b880" + "808000200241a00b6a41306a200241a0086a200110b98080800020024180" + "066a200241a00b6a41e0001086818080001a200241a0026a20024180066a" + "200510bc80808000200241a00b6a200241a0026a200241a0026a10bc8080" + "8000200241a0026a200241a00b6a20024180066a10bc80808000200241c0" + "016a200241c0076a200410bb80808000200241a00b6a200241c0016a2002" + "41c0016a10bc80808000200241c0016a200241a00b6a200241c0076a10bc" + "8080800020024180096a200241e0001086818080001a20024180096a41e0" + "006a200241e0006a41e0001086818080001a20024180096a41c0016a2002" + "41c0016a41e0001086818080001a200241a00b6a200241a0026a41e00010" + "86818080001a200820024180036a41e0001086818080001a200241a00b6a" + "41c0016a200241e0036a41e0001086818080001a200020024180096a41a0" + "0210868180800041a0026a200241a00b6a41a0021086818080001a200241" + "c00d6a2480808080000bcd0102037f017e2380808080004180096b220224" + "8080808000200210ac8080800041002103413f2104034002400240024020" + "04417f460d0042012004413f71ad8642808084808080c080528321052003" + "4101710d01200542005221030c020b200041a0026a200241a0026a10b180" + "8080002000200241a0021086818080001a20024180096a2480808080000f" + "0b200241c0046a200210c0808080002002200241c0046a41c00410868180" + "80001a410121030b02402005500d002002200110bf808080000b2004417f" + "6a21040c000b0b23002000200110db80808000200041306a200141306a10" + "db808080007110a3808080000b3e0020002001200210bc80808000200041" + "e0006a200141e0006a200241e0006a10bc80808000200041c0016a200141" + "c0016a200241c0016a10bc808080000bbc0101047f23808080800041106b" + "2202248080808000200141086a21030340200241086a200310e680808000" + "02400240024020022d0008450d0020022d00092101410121040c010b0240" + "20012802002204450d00200420012802042205470d020b2002200141146a" + "10e68080800020022d0001210120022d000021040b200020013a00012000" + "20044101713a0000200241106a2480808080000f0b200142808080808001" + "37020c20012005417f6a2204360208200120043602040c000b0b6f01057f" + "23808080800041106b220324808080800041002104410121054100210602" + "400340200120062207460d01200341086a200210d080808000200741016a" + "210620032d00080d000b200120076b2104410021050b2000200436020420" + "002005360200200341106a2480808080000bf50401037f23808080800041" + "b0096b22022480808080002002200141306a220310bd8080800020024130" + "6a2002200210b980808000200241e0006a200241306a200241306a10b980" + "80800020024190016a200241e0006a200241e0006a10b980808000200241" + "c0016a2003200141e0006a220410a780808000200241f0016a200410bd80" + "808000200241d0086a200241f0016a200241f0016a10b980808000200241" + "80096a200241d0086a200241d0086a10b980808000200241c0076a200241" + "80096a20024180096a10b980808000200241a0026a200241c0076a200241" + "80096a10b980808000200241d0026a200241a0026a20024190016a10a780" + "80800020024180036a2002200241a0026a10b980808000200241b0036a20" + "0241c0016a20024190016a10a780808000200241e0036a200241a0026a20" + "0241a0026a10b98080800020024190046a200241e0036a200241a0026a10" + "b980808000200241c0046a200220024190046a10b880808000200241f004" + "6a200241c0046a20024180036a10a780808000200241a0056a200241d002" + "6a200241f0046a10b980808000200241d0056a2001200310a78080800020" + "024180066a200241c0046a200241d0056a10a780808000200241b0066a20" + "024180066a20024180066a10b980808000200241b0066a41306a200241a0" + "056a41301086818080001a200241b0066a41e0006a200241b0036a413010" + "86818080001a200241c0076a410041301085818080001a200241c0076a41" + "e0006a410041301085818080001a200241c0076a41306a41e086c0800041" + "301086818080001a2000200241b0066a200241c0076a200410a980808000" + "10c880808000200241b0096a2480808080000bf60601057f238080808000" + "41900d6b220324808080800020032001200210a780808000200341306a20" + "0141306a2204200241306a220510a780808000200341e0006a200141e000" + "6a2206200241e0006a220710a78080800020034190016a2001200410b980" + "808000200341c0016a2002200510b980808000200341f0016a2003419001" + "6a200341c0016a10a780808000200341a0026a2003200341306a10b98080" + "8000200341d0026a200341f0016a200341a0026a10b88080800020034180" + "036a2004200610b980808000200341b0036a2005200710b9808080002003" + "41e0036a20034180036a200341b0036a10a78080800020034190046a2003" + "41306a200341e0006a10b980808000200341c0046a200341e0036a200341" + "90046a10b880808000200341f0046a2001200610b980808000200341a005" + "6a2002200710b980808000200341d0056a200341f0046a200341a0056a10" + "a78080800020034180066a2003200341e0006a10b980808000200341b006" + "6a200341d0056a20034180066a10b880808000200341e0066a2003200310" + "b98080800020034190076a200341e0066a200310b980808000200341800c" + "6a200341e0006a200341e0006a10b980808000200341b00c6a200341800c" + "6a200341800c6a10b980808000200341e00c6a200341b00c6a200341b00c" + "6a10b980808000200341c0076a200341e00c6a200341b00c6a10b9808080" + "00200341f0076a200341306a200341c0076a10b980808000200341a0086a" + "200341306a200341c0076a10b880808000200341a00b6a200341b0066a20" + "0341b0066a10b980808000200341d00b6a200341a00b6a200341a00b6a10" + "b980808000200341e00c6a200341d00b6a200341d00b6a10b98080800020" + "0341d0086a200341e00c6a200341d00b6a10b98080800020034180096a20" + "0341c0046a200341d0086a10a780808000200341b0096a200341d0026a20" + "0341a0086a10a7808080002000200341b0096a20034180096a10b8808080" + "00200341e0096a200341d0086a20034190076a10a780808000200341900a" + "6a200341a0086a200341f0076a10a780808000200041306a200341900a6a" + "200341e0096a10b980808000200341c00a6a20034190076a200341d0026a" + "10a780808000200341f00a6a200341f0076a200341c0046a10a780808000" + "200041e0006a200341f00a6a200341c00a6a10b980808000200341900d6a" + "2480808080000b41002000200120022003109080808000200041306a2001" + "41306a200241306a2003109080808000200041e0006a200141e0006a2002" + "41e0006a20031090808080000bbe0601057f200041786a22012000417c6a" + "280200220241787122006a21030240024020024101710d00200241027145" + "0d012001280200220220006a21000240200120026b2201410028029c97c0" + "8000470d0020032802044103714103470d014100200036029497c0800020" + "032003280204417e7136020420012000410172360204200320003602000f" + "0b2001200210cc808080000b024002400240024002400240200328020422" + "024102710d00200341002802a097c08000460d022003410028029c97c080" + "00460d0320032002417871220210cc808080002001200220006a22004101" + "72360204200120006a20003602002001410028029c97c08000470d014100" + "200036029497c080000f0b20032002417e71360204200120004101723602" + "04200120006a20003602000b2000418002490d0220012000108481808000" + "41002101410041002802b497c08000417f6a22003602b497c0800020000d" + "04024041002802fc94c080002200450d00410021010340200141016a2101" + "200028020822000d000b0b4100200141ff1f200141ff1f4b1b3602b497c0" + "80000f0b410020013602a097c080004100410028029897c0800020006a22" + "0036029897c080002001200041017236020402402001410028029c97c080" + "00470d004100410036029497c080004100410036029c97c080000b200041" + "002802ac97c0800022044d0d0341002802a097c080002200450d03410021" + "02410028029897c0800022054129490d0241f494c0800021010340024020" + "01280200220320004b0d002000200320012802046a490d040b2001280208" + "21010c000b0b4100200136029c97c080004100410028029497c080002000" + "6a220036029497c0800020012000410172360204200120006a2000360200" + "0f0b200041f80171418495c080006a210302400240410028028c97c08000" + "220241012000410376742200710d004100200220007236028c97c0800020" + "0321000c010b200328020821000b200320013602082000200136020c2001" + "200336020c200120003602080f0b024041002802fc94c080002201450d00" + "410021020340200241016a2102200128020822010d000b0b4100200241ff" + "1f200241ff1f4b1b3602b497c08000200520044d0d004100417f3602ac97" + "c080000b0b4d01017f23808080800041206b220224808080800020024100" + "36021020024101360204200242043702082002412e36021c200220003602" + "182002200241186a3602002002200110a480808000000b800601057f0240" + "024002402000417c6a220328020022044178712205410441082004410371" + "22061b20016a490d0002402006450d002005200141276a4b0d020b411020" + "02410b6a4178712002410b491b210102400240024020060d002001418002" + "490d0120052001410472490d01200520016b418180084f0d010c020b2000" + "41786a220720056a21060240024002400240200520014f0d002006410028" + "02a097c08000460d032006410028029c97c08000460d0220062802042204" + "4102710d042004417871220420056a22052001490d042006200410cc8080" + "8000200520016b22024110490d0120032001200328020041017172410272" + "360200200720016a22012002410372360204200720056a22052005280204" + "4101723602042001200210cd8080800020000f0b200520016b2202410f4d" + "0d0420032001200441017172410272360200200720016a22052002410372" + "360204200620062802044101723602042005200210cd8080800020000f0b" + "20032005200328020041017172410272360200200720056a220220022802" + "0441017236020420000f0b410028029497c0800020056a22052001490d01" + "02400240200520016b2202410f4b0d002003200441017120057241027236" + "0200200720056a2202200228020441017236020441002102410021010c01" + "0b20032001200441017172410272360200200720016a2201200241017236" + "0204200720056a2205200236020020052005280204417e713602040b4100" + "200136029c97c080004100200236029497c0800020000f0b410028029897" + "c0800020056a220520014b0d040b0240200210ce8080800022050d004100" + "0f0b20052000417c4178200328020022014103711b20014178716a220120" + "0220012002491b1086818080002102200010c980808000200221000b2000" + "0f0b41e992c08000419893c0800010ca80808000000b41a893c0800041d8" + "93c0800010ca80808000000b200320012004410171724102723602002007" + "20016a2202200520016b22054101723602044100200536029897c0800041" + "0020023602a097c0800020000b820301047f200028020c21020240024002" + "402001418002490d002000280218210302400240024020022000470d0020" + "0041144110200028021422021b6a28020022010d01410021020c020b2000" + "2802082201200236020c200220013602080c010b200041146a200041106a" + "20021b21040340200421052001220241146a200241106a20022802142201" + "1b210420024114411020011b6a28020022010d000b200541003602000b20" + "03450d020240200028021c41027441f493c080006a22012802002000460d" + "0020034110411420032802102000461b6a20023602002002450d030c020b" + "2001200236020020020d014100410028029097c08000417e200028021c77" + "7136029097c080000c020b0240200220002802082204460d002004200236" + "020c200220043602080f0b4100410028028c97c08000417e200141037677" + "7136028c97c080000f0b20022003360218024020002802102201450d0020" + "022001360210200120023602180b20002802142201450d00200220013602" + "14200120023602180f0b0ba00401027f200020016a210202400240200028" + "020422034101710d002003410271450d012000280200220320016a210102" + "40200020036b2200410028029c97c08000470d0020022802044103714103" + "470d014100200136029497c0800020022002280204417e71360204200020" + "01410172360204200220013602000c020b2000200310cc808080000b0240" + "024002400240200228020422034102710d00200241002802a097c0800046" + "0d022002410028029c97c08000460d0320022003417871220310cc808080" + "002000200320016a2201410172360204200020016a200136020020004100" + "28029c97c08000470d014100200136029497c080000f0b20022003417e71" + "36020420002001410172360204200020016a20013602000b024020014180" + "02490d00200020011084818080000f0b200141f80171418495c080006a21" + "0202400240410028028c97c08000220341012001410376742201710d0041" + "00200320017236028c97c08000200221010c010b200228020821010b2002" + "20003602082001200036020c2000200236020c200020013602080f0b4100" + "20003602a097c080004100410028029897c0800020016a220136029897c0" + "8000200020014101723602042000410028029c97c08000470d0141004100" + "36029497c080004100410036029c97c080000f0b4100200036029c97c080" + "004100410028029497c0800020016a220136029497c08000200020014101" + "72360204200020016a20013602000f0b0bc12502087f017e024002400240" + "02400240024002400240200041f4014b0d00410028028c97c08000220141" + "102000410b6a41f803712000410b491b220241037622037622004103710d" + "012002410028029497c080004d0d0720000d02410028029097c080002200" + "0d030c070b2000410b6a22034178712102410028029097c080002204450d" + "06411f21050240200041f4ffff074b0d002002410620034108766722006b" + "7641017120004101746b413e6a21050b410020026b210302402005410274" + "41f493c080006a28020022010d0041002100410021060c040b4100210020" + "024100411920054101766b2005411f461b74210741002106034002402001" + "220128020441787122082002490d00200820026b220820034f0d00200821" + "032001210620080d004100210320012106200121000c060b200128021422" + "082000200820012007411d764104716a41106a2802002201471b20002008" + "1b2100200741017421072001450d040c000b0b024002402000417f734101" + "7120036a22074103742200418495c080006a22022000418c95c080006a28" + "020022032802082206460d002006200236020c200220063602080c010b41" + "002001417e2007777136028c97c080000b20032000410372360204200320" + "006a22002000280204410172360204200341086a0f0b0240024020002003" + "7441022003742200410020006b72716822084103742203418495c080006a" + "22062003418c95c080006a28020022002802082207460d00200720063602" + "0c200620073602080c010b41002001417e2008777136028c97c080000b20" + "002002410372360204200020026a2207200320026b220241017236020420" + "0020036a20023602000240410028029497c080002201450d002001417871" + "418495c080006a2106410028029c97c08000210302400240410028028c97" + "c08000220841012001410376742201710d004100200820017236028c97c0" + "8000200621010c010b200628020821010b20062003360208200120033602" + "0c2003200636020c200320013602080b4100200736029c97c08000410020" + "0236029497c08000200041086a0f0b20006841027441f493c080006a2802" + "00220628020441787120026b210320062101024002400340024020062802" + "1022000d00200628021422000d0020012802182105024002400240200128" + "020c22002001470d00200141144110200128021422001b6a28020022060d" + "01410021000c020b20012802082206200036020c200020063602080c010b" + "200141146a200141106a20001b21070340200721082006220041146a2000" + "41106a200028021422061b210720004114411020061b6a28020022060d00" + "0b200841003602000b2005450d030240200128021c41027441f493c08000" + "6a22062802002001460d0020054110411420052802102001461b6a200036" + "02002000450d040c030b2006200036020020000d024100410028029097c0" + "8000417e200128021c777136029097c080000c030b200028020441787120" + "026b22062003200620034922061b21032000200120061b2101200021060c" + "000b0b20002005360218024020012802102206450d002000200636021020" + "0620003602180b20012802142206450d0020002006360214200620003602" + "180b02400240024020034110490d0020012002410372360204200120026a" + "22022003410172360204200220036a2003360200410028029497c0800022" + "07450d012007417871418495c080006a2106410028029c97c08000210002" + "400240410028028c97c08000220841012007410376742207710d00410020" + "0820077236028c97c08000200621070c010b200628020821070b20062000" + "3602082007200036020c2000200636020c200020073602080c010b200120" + "0320026a2200410372360204200120006a22002000280204410172360204" + "0c010b4100200236029c97c080004100200336029497c080000b20014108" + "6a0f0b024020002006720d004100210641022005742200410020006b7220" + "04712200450d0320006841027441f493c080006a28020021000b2000450d" + "010b0340200020062000280204417871220120026b220820034922051b21" + "04200120024921072008200320051b21080240200028021022010d002000" + "28021421010b2006200420071b21062003200820071b2103200121002001" + "0d000b0b2006450d000240410028029497c0800022002002490d00200320" + "0020026b4f0d010b20062802182105024002400240200628020c22002006" + "470d00200641144110200628021422001b6a28020022010d01410021000c" + "020b20062802082201200036020c200020013602080c010b200641146a20" + "0641106a20001b21070340200721082001220041146a200041106a200028" + "021422011b210720004114411020011b6a28020022010d000b2008410036" + "02000b02402005450d0002400240200628021c41027441f493c080006a22" + "012802002006460d0020054110411420052802102006461b6a2000360200" + "2000450d020c010b2001200036020020000d004100410028029097c08000" + "417e200628021c777136029097c080000c010b2000200536021802402006" + "2802102201450d0020002001360210200120003602180b20062802142201" + "450d0020002001360214200120003602180b0240024020034110490d0020" + "062002410372360204200620026a22002003410172360204200020036a20" + "0336020002402003418002490d00200020031084818080000c020b200341" + "f80171418495c080006a210202400240410028028c97c080002201410120" + "03410376742203710d004100200120037236028c97c08000200221030c01" + "0b200228020821030b200220003602082003200036020c2000200236020c" + "200020033602080c010b2006200320026a2200410372360204200620006a" + "220020002802044101723602040b200641086a0f0b024002400240024002" + "4002400240410028029497c08000220020024f0d000240410028029897c0" + "8000220020024b0d0041002100200241af80046a22064110764000220341" + "7f4622070d0720034110742201450d07410041002802a497c08000410020" + "064180807c7120071b22086a22003602a497c08000410041002802a897c0" + "800022032000200320004b1b3602a897c0800002400240024041002802a0" + "97c080002203450d0041f494c08000210003402000280200220620002802" + "0422076a2001460d02200028020822000d000c030b0b0240024041002802" + "b097c080002200450d00200020014d0d010b410020013602b097c080000b" + "410041ff1f3602b497c08000410020083602f894c08000410020013602f4" + "94c080004100418495c0800036029095c080004100418c95c08000360298" + "95c080004100418495c0800036028c95c080004100419495c080003602a0" + "95c080004100418c95c0800036029495c080004100419c95c080003602a8" + "95c080004100419495c0800036029c95c08000410041a495c080003602b0" + "95c080004100419c95c080003602a495c08000410041ac95c080003602b8" + "95c08000410041a495c080003602ac95c08000410041b495c080003602c0" + "95c08000410041ac95c080003602b495c08000410041bc95c080003602c8" + "95c08000410041b495c080003602bc95c080004100410036028095c08000" + "410041c495c080003602d095c08000410041bc95c080003602c495c08000" + "410041c495c080003602cc95c08000410041cc95c080003602d895c08000" + "410041cc95c080003602d495c08000410041d495c080003602e095c08000" + "410041d495c080003602dc95c08000410041dc95c080003602e895c08000" + "410041dc95c080003602e495c08000410041e495c080003602f095c08000" + "410041e495c080003602ec95c08000410041ec95c080003602f895c08000" + "410041ec95c080003602f495c08000410041f495c0800036028096c08000" + "410041f495c080003602fc95c08000410041fc95c0800036028896c08000" + "410041fc95c0800036028496c080004100418496c0800036029096c08000" + "4100418c96c0800036029896c080004100418496c0800036028c96c08000" + "4100419496c080003602a096c080004100418c96c0800036029496c08000" + "4100419c96c080003602a896c080004100419496c0800036029c96c08000" + "410041a496c080003602b096c080004100419c96c080003602a496c08000" + "410041ac96c080003602b896c08000410041a496c080003602ac96c08000" + "410041b496c080003602c096c08000410041ac96c080003602b496c08000" + "410041bc96c080003602c896c08000410041b496c080003602bc96c08000" + "410041c496c080003602d096c08000410041bc96c080003602c496c08000" + "410041cc96c080003602d896c08000410041c496c080003602cc96c08000" + "410041d496c080003602e096c08000410041cc96c080003602d496c08000" + "410041dc96c080003602e896c08000410041d496c080003602dc96c08000" + "410041e496c080003602f096c08000410041dc96c080003602e496c08000" + "410041ec96c080003602f896c08000410041e496c080003602ec96c08000" + "410041f496c0800036028097c08000410041ec96c080003602f496c08000" + "410041fc96c0800036028897c08000410041f496c080003602fc96c08000" + "410020013602a097c08000410041fc96c0800036028497c0800041002008" + "41586a220036029897c0800020012000410172360204200120006a412836" + "0204410041808080013602ac97c080000c080b200320014f0d0020062003" + "4b0d00200028020c450d030b410041002802b097c0800022002001200020" + "01491b3602b097c08000200120086a210641f494c0800021000240024002" + "400340200028020022072006460d01200028020822000d000c020b0b2000" + "28020c450d010b41f494c080002100024003400240200028020022062003" + "4b0d002003200620002802046a2206490d020b200028020821000c000b0b" + "410020013602a097c080004100200841586a220036029897c08000200120" + "00410172360204200120006a4128360204410041808080013602ac97c080" + "002003200641606a41787141786a22002000200341106a491b2207411b36" + "020441002902f494c080002109200741106a41002902fc94c08000370200" + "20072009370208410020083602f894c08000410020013602f494c0800041" + "00200741086a3602fc94c080004100410036028095c080002007411c6a21" + "00034020004107360200200041046a22002006490d000b20072003460d07" + "20072007280204417e713602042003200720036b22004101723602042007" + "200036020002402000418002490d00200320001084818080000c080b2000" + "41f80171418495c080006a210602400240410028028c97c0800022014101" + "2000410376742200710d004100200120007236028c97c08000200621000c" + "010b200628020821000b200620033602082000200336020c200320063602" + "0c200320003602080c070b200020013602002000200028020420086a3602" + "04200120024103723602042007410f6a41787141786a2206200120026a22" + "006b2103200641002802a097c08000460d032006410028029c97c0800046" + "0d040240200628020422024103714101470d0020062002417871220210cc" + "80808000200220036a2103200620026a220628020421020b20062002417e" + "7136020420002003410172360204200020036a2003360200024020034180" + "02490d00200020031084818080000c060b200341f80171418495c080006a" + "210202400240410028028c97c08000220641012003410376742203710d00" + "4100200620037236028c97c08000200221030c010b200228020821030b20" + "0220003602082003200036020c2000200236020c200020033602080c050b" + "4100200020026b220336029897c08000410041002802a097c08000220020" + "026a22063602a097c0800020062003410172360204200020024103723602" + "04200041086a21000c060b410028029c97c0800021030240024020002002" + "6b2206410f4b0d004100410036029c97c080004100410036029497c08000" + "20032000410372360204200320006a220020002802044101723602040c01" + "0b4100200636029497c080004100200320026a220136029c97c080002001" + "2006410172360204200320006a2006360200200320024103723602040b20" + "0341086a0f0b2000200720086a360204410041002802a097c08000220041" + "0f6a417871220341786a22063602a097c080004100200020036b41002802" + "9897c0800020086a22036a41086a220136029897c0800020062001410172" + "360204200020036a4128360204410041808080013602ac97c080000c030b" + "410020003602a097c080004100410028029897c0800020036a2203360298" + "97c08000200020034101723602040c010b4100200036029c97c080004100" + "410028029497c0800020036a220336029497c08000200020034101723602" + "04200020036a20033602000b200141086a0f0b41002100410028029897c0" + "8000220320024d0d004100200320026b220336029897c080004100410028" + "02a097c08000220020026a22063602a097c0800020062003410172360204" + "20002002410372360204200041086a0f0b20000b4301017f238080808000" + "41206b2201248080808000200141003602182001410136020c200141d085" + "c0800036020820014204370210200141086a200010a480808000000b4e01" + "037f024020012802042202200128020822034e0d0020012003417f6a2204" + "36020820012802002d000020044107717641017110a38080800021040b20" + "0020043a0001200020022003483a00000b18002001200085220042002000" + "7d84427f5510a3808080000b10002000417f7341017110a3808080000bf2" + "0202017f017e23808080800041f0006b2206248080808000200620013602" + "0c2006200036020820062003360214200620023602102006410236021c20" + "0641c08dc08000360218024020042802000d002006410336025c200641f4" + "8dc08000360258200642033702642006418280808000ad42208622072006" + "41106aad8437034820062007200641086aad843703402006418380808000" + "ad422086200641186aad843703382006200641386a360260200641d8006a" + "200510a480808000000b200641206a41106a200441106a29020037030020" + "0641206a41086a200441086a290200370300200620042902003703202006" + "410436025c200641a88ec080003602582006420437026420064182808080" + "00ad4220862207200641106aad8437035020062007200641086aad843703" + "482006418480808000ad422086200641206aad8437034020064183808080" + "00ad422086200641186aad843703382006200641386a360260200641d800" + "6a200510a480808000000bb30301037f2380808080004180016b22022480" + "8080800020002802002100024002400240200128021422034110710d0020" + "03412071450d0120002d0000210341810121000340200220006a417e6a20" + "03410f712204413072200441376a2004410a491b3a0000200341ff017122" + "0441047621032000417f6a21002004410f4b0d000b200141fd8ec0800041" + "02200220006a417f6a41810120006b10d58080800021000c020b20002d00" + "00210341810121000340200220006a417e6a2003410f7122044130722004" + "41d7006a2004410a491b3a0000200341ff0171220441047621032000417f" + "6a21002004410f4b0d000b200141fd8ec080004102200220006a417f6a41" + "810120006b10d58080800021000c010b024002400240024020002d000022" + "0341e400490d002002200341e4006e2204419c7f6c20036a41ff01714101" + "7441ff8ec080006a2f00003b0001410021000c010b410221002003410a4f" + "0d01200321040b200220006a20044130723a00000c010b41012100200220" + "0341017441ff8ec080006a2f00003b00010b200141014100200220006a20" + "0041037310d58080800021000b20024180016a24808080800020000bb605" + "01087f20002802142205410171220620046a21070240024020054104710d" + "00410021010c010b0240024020020d00410021080c010b02402002410371" + "22090d000c010b410021082001210a03402008200a2c000041bf7f4a6a21" + "08200a41016a210a2009417f6a22090d000b0b200820076a21070b412b41" + "8080c40020061b2106024020002802000d000240200028021c220a200028" + "0220220820062001200210f480808000450d0041010f0b200a2003200420" + "0828020c11808080800080808080000f0b02400240024002402000280204" + "220a20074b0d00200028021c220a2000280220220820062001200210f480" + "808000450d0141010f0b2005410871450d01200028021021052000413036" + "021020002d0018210b4101210c200041013a0018200028021c2208200028" + "0220220920062001200210f4808080000d02200a20076b41016a210a0240" + "0340200a417f6a220a450d01200841302009280210118180808000808080" + "8000450d000b41010f0b0240200820032004200928020c11808080800080" + "80808000450d0041010f0b2000200b3a00182000200536021041000f0b20" + "0a20032004200828020c1180808080008080808000210c0c010b200a2007" + "6b2105024002400240410120002d0018220a200a4103461b220a0e030200" + "01020b2005210a410021050c010b2005410176210a200541016a41017621" + "050b200a41016a210a2000280210210720002802202108200028021c2109" + "02400340200a417f6a220a450d0120092007200828021011818080800080" + "80808000450d000b41010f0b4101210c2009200820062001200210f48080" + "80000d00200920032004200828020c11808080800080808080000d004100" + "210a034002402005200a470d0020052005490f0b200a41016a210a200920" + "0720082802101181808080008080808000450d000b200a417f6a2005490f" + "0b200c0be802010d7e2000200129032822022001290300220342d5aa8180" + "8080c080c6007c2204200354ad427f7c22052005200129030822067c2205" + "200654ad7c2005428180b0f5948080aa617c2207200554ad7c427f7c423f" + "8722052005200129031022087c2205200854ad7c200542dc93bccaf0abcb" + "e7987f7c2209200554ad7c427f7c423f87220520052001290318220a7c22" + "05200a54ad7c200542c1daebe3b08fadc49b7f7c220b200554ad7c427f7c" + "423f87220520052001290320220c7c2205200c54ad7c200542a9a6d1e59b" + "8996f2b47f7c220d200554ad7c427f7c423f872205200220057c22052002" + "54ad7c200542e6b280b4dcc2bbff657c220e200554ad7c2205427f7c2202" + "83420020057d2205200e83843703282000200c2002832005200d83843703" + "202000200a2002832005200b838437031820002008200283200520098384" + "370310200020062002832005200783843703082000200320028320052004" + "83843703000b2c0002402002450d0041002d00e893c080001a200210ce80" + "80800021010b20002002360204200020013602000b5a01017f2380808080" + "0041106b2202248080808000200241086a20002000280200410141a00210" + "8b80808000024020022802082200418180808078460d002000200228020c" + "2001108c80808000000b200241106a2480808080000b4800200020012002" + "200310b080808000200041e0006a200141e0006a200241e0006a200310b0" + "80808000200020022d00c00120012d00c001220273410020036b71200273" + "3a00c0010b2b00200020012002200310b080808000200020022d00602001" + "2d0060220273410020036b712002733a00600b8501002000290300200129" + "030010d1808080002000290308200129030810d1808080007110a3808080" + "002000290310200129031010d1808080007110a380808000200029031820" + "0129031810d1808080007110a3808080002000290320200129032010d180" + "8080007110a3808080002000290328200129032810d1808080007110a380" + "8080000bda0602017f067e23808080800041306b22022480808080002002" + "2001290000220342388620034280fe0383422886842003428080fc078342" + "1886200342808080f80f834208868484200342088842808080f80f832003" + "421888428080fc07838420034228884280fe038320034238888484842204" + "37032820022001290008220342388620034280fe03834228868420034280" + "80fc0783421886200342808080f80f834208868484200342088842808080" + "f80f832003421888428080fc07838420034228884280fe03832003423888" + "848484220537032020022001290010220342388620034280fe0383422886" + "842003428080fc0783421886200342808080f80f83420886848420034208" + "8842808080f80f832003421888428080fc07838420034228884280fe0383" + "2003423888848484220637031820022001290018220342388620034280fe" + "0383422886842003428080fc0783421886200342808080f80f8342088684" + "84200342088842808080f80f832003421888428080fc0783842003422888" + "4280fe038320034238888484842207370310200220012900202203423886" + "20034280fe0383422886842003428080fc0783421886200342808080f80f" + "834208868484200342088842808080f80f832003421888428080fc078384" + "20034228884280fe03832003423888848484220837030820022001290028" + "220342388620034280fe0383422886842003428080fc0783421886200342" + "808080f80f834208868484200342088842808080f80f8320034218884280" + "80fc07838420034228884280fe0383200342388884848422033703002002" + "419087c0800010dd80808000200342d5aa81808080c080c6007c200354ad" + "427f7c2203200820037c2203200854ad7c2003428180b0f5948080aa617c" + "200354ad7c427f7c423f872203200720037c2203200754ad7c200342dc93" + "bccaf0abcbe7987f7c200354ad7c427f7c423f872203200620037c220320" + "0654ad7c200342c1daebe3b08fadc49b7f7c200354ad7c427f7c423f8722" + "03200520037c2203200554ad7c200342a9a6d1e59b8996f2b47f7c200354" + "ad7c427f7c423f872203200420037c2203200454ad7c200342e6b280b4dc" + "c2bbff657c200354ad7ca741016a41017110a38080800021012000200241" + "3010868180800020013a0030200241306a2480808080000b3901017f2380" + "8080800041306b220224808080800020022000200110a780808000200020" + "0241301086818080001a200241306a2480808080000b9b1602017f177e23" + "808080800041a0056b2201248080808000200141b0046a20002903002202" + "42fdfff3ffcffffff9897f7e2203420042abd5feffffffbfffb97f420010" + "8781808000200141a0046a2003420042ffffcf8aebffffd51e4200108781" + "80800020014190046a2003420042a4ecc3b58fd4b498e700420010878180" + "800020014180046a2003420042bfa5949ccff0d2bbe40042001087818080" + "00200141f0036a2003420042d7d9ae9ae4f6e98dcb004200108781808000" + "200141e0036a20034200429acdffcba3bdc4801a42001087818080002001" + "41d0036a20012903a004220420002903087c2205200141b0046a41086a29" + "0300200220012903b00422037c200354ad7c7c220242fdfff3ffcffffff9" + "897f7e2203420042abd5feffffffbfffb97f4200108781808000200141c0" + "036a2003420042ffffcf8aebffffd51e4200108781808000200141d0026a" + "2003420042a4ecc3b58fd4b498e7004200108781808000200141e0016a20" + "03420042bfa5949ccff0d2bbe4004200108781808000200141f0006a2003" + "420042d7d9ae9ae4f6e98dcb004200108781808000200120034200429acd" + "ffcba3bdc4801a4200108781808000200141b0036a20012903c003220620" + "0129039004220720002903107c2208200141a0046a41086a290300200520" + "0454ad7c2002200554ad7c7c22097c2205200141d0036a41086a29030020" + "012903d003220320027c200354ad7c7c220242fdfff3ffcffffff9897f7e" + "2203420042abd5feffffffbfffb97f4200108781808000200141a0036a20" + "03420042ffffcf8aebffffd51e420010878180800020014190036a200342" + "0042a4ecc3b58fd4b498e700420010878180800020014180036a20034200" + "42bfa5949ccff0d2bbe4004200108781808000200141f0026a2003420042" + "d7d9ae9ae4f6e98dcb004200108781808000200141e0026a20034200429a" + "cdffcba3bdc4801a4200108781808000200141c0026a20012903a003220a" + "200129038004220b20002903187c220420014190046a41086a2903002008" + "200754ad7c2009200854ad7c7c220820012903d0027c2207200141c0036a" + "41086a2903002005200654ad7c2002200554ad7c7c220c7c2205200141b0" + "036a41086a29030020012903b003220320027c200354ad7c7c220242fdff" + "f3ffcffffff9897f7e2203420042abd5feffffffbfffb97f420010878180" + "8000200141b0026a2003420042ffffcf8aebffffd51e4200108781808000" + "200141a0026a2003420042a4ecc3b58fd4b498e700420010878180800020" + "014190026a2003420042bfa5949ccff0d2bbe40042001087818080002001" + "4180026a2003420042d7d9ae9ae4f6e98dcb004200108781808000200141" + "f0016a20034200429acdffcba3bdc4801a4200108781808000200141d001" + "6a20012903b002220d20012903f003220e20002903207c22062001418004" + "6a41086a2903002004200b54ad7c2008200454ad7c7c220420012903e001" + "7c2209200141d0026a41086a2903002007200854ad7c200c200754ad7c7c" + "22082001290390037c2207200141a0036a41086a2903002005200a54ad7c" + "2002200554ad7c7c220c7c2205200141c0026a41086a29030020012903c0" + "02220320027c200354ad7c7c220242fdfff3ffcffffff9897f7e22034200" + "42abd5feffffffbfffb97f4200108781808000200141c0016a2003420042" + "ffffcf8aebffffd51e4200108781808000200141b0016a2003420042a4ec" + "c3b58fd4b498e7004200108781808000200141a0016a2003420042bfa594" + "9ccff0d2bbe400420010878180800020014190016a2003420042d7d9ae9a" + "e4f6e98dcb00420010878180800020014180016a20034200429acdffcba3" + "bdc4801a4200108781808000200141e0006a20012903c001220f20012903" + "e003221020002903287c220a200141f0036a41086a2903002006200e54ad" + "7c2004200654ad7c7c220620012903707c220b200141e0016a41086a2903" + "002009200454ad7c2008200954ad7c7c22042001290380037c2209200141" + "90036a41086a2903002007200854ad7c200c200754ad7c7c220820012903" + "a0027c2207200141b0026a41086a2903002005200d54ad7c2002200554ad" + "7c7c220c7c2205200141d0016a41086a29030020012903d001220320027c" + "200354ad7c7c220242fdfff3ffcffffff9897f7e2203420042abd5feffff" + "ffbfffb97f4200108781808000200141d0006a2003420042ffffcf8aebff" + "ffd51e4200108781808000200141c0006a2003420042a4ecc3b58fd4b498" + "e7004200108781808000200141306a2003420042bfa5949ccff0d2bbe400" + "4200108781808000200141206a2003420042d7d9ae9ae4f6e98dcb004200" + "108781808000200141106a20034200429acdffcba3bdc4801a4200108781" + "808000200141b0016a41086a290300210d20014190026a41086a29030021" + "0e200141f0026a41086a2903002111200141086a290300211220012903e0" + "022113200129038002211420012903a001211520012903402116200141c0" + "006a41086a2903002117200120012903502218200141e0036a41086a2903" + "00200a201054ad7c2006200a54ad7c221020012903007c2203200141f000" + "6a41086a290300200b200654ad7c2004200b54ad7c7c220620012903f002" + "7c220a20014180036a41086a2903002009200454ad7c2008200954ad7c7c" + "22042001290390027c2209200141a0026a41086a2903002007200854ad7c" + "200c200754ad7c7c220820012903b0017c2207200141c0016a41086a2903" + "002005200f54ad7c2002200554ad7c7c220b7c2205200141e0006a41086a" + "2903002001290360220c20027c200c54ad7c7c220c3703f0042001201620" + "152014201320122003201054ad7c2006200354ad7c220f7c22032011200a" + "200654ad7c2004200a54ad7c7c22027c2206200e2009200454ad7c200820" + "0954ad7c7c22047c2209200d2007200854ad7c200b200754ad7c7c22087c" + "2207200141d0006a41086a2903002005201854ad7c200c200554ad7c7c22" + "0a3703f8042001200141e0026a41086a2903002003200f54ad7c20022003" + "54ad7c220b20012903f0017c220320014180026a41086a29030020062002" + "54ad7c2004200654ad7c7c22052001290390017c2202200141a0016a4108" + "6a2903002009200454ad7c2008200954ad7c7c220420012903307c220620" + "172007200854ad7c200a200754ad7c7c2208370380052001200141f0016a" + "41086a2903002003200b54ad7c2005200354ad7c22072001290380017c22" + "0320014190016a41086a2903002002200554ad7c2004200254ad7c7c2205" + "20012903207c2202200141306a41086a2903002006200454ad7c20082006" + "54ad7c7c220837038805200120014180016a41086a2903002003200754ad" + "7c2005200354ad7c220420012903107c2203200141206a41086a29030020" + "02200554ad7c2008200254ad7c7c2205370390052001200141106a41086a" + "2903002003200454ad7c2005200354ad7c37039805200141c0046a200141" + "f0046a10d68080800020012903c004220342aad580808080a080237c2003" + "54ad427f7c2203200320012903c80422057c2203200554ad7c2003428180" + "d8ba8a8080d5707c200354ad7c427f7c423f872203200320012903d00422" + "057c2203200554ad7c200342ee899ea5f8d5e5b3cc007c200354ad7c427f" + "7c423f872203200320012903d80422057c2203200554ad7c200342a1edf5" + "b1d8c796e2cd007c200354ad7c427f7c423f872203200320012903e00422" + "057c2203200554ad7c20034295d3e8f2cd848bb95a7c200354ad7c427f7c" + "423f872203200320012903e80422057c2203200554ad7c200342b399809a" + "aee1ddff727c200354ad7ca741016a41017110a38080800010d280808000" + "2100200141a0056a24808080800020000bb60103037f017e017f23808080" + "800041e0006b2203248080808000200341e086c080004130108681808000" + "2104200241306a21050240034020052002460d01200541786a2205290300" + "2106413f210303402003417f460d01200441306a200410bd808080002004" + "200441306a41301086818080002107024020062003413f71ad8842018350" + "0d002007200110dd808080000b2003417f6a21030c000b0b0b2000200441" + "301086818080001a200441e0006a2480808080000b1c00200010a9808080" + "00200041306a10a9808080007110a3808080000bf50706027f067e027f01" + "7e017f027e23808080800041f0016b220324808080800041002104420021" + "05420021064200210742002108420021094200210a02400340200441054b" + "0d01200420044106496a210b200120044103746a210c4200210d41a07f21" + "0e02400340200e450d01200341b0016a2002200e6a220441e0006a290300" + "4200200c200e6a41e0006a290300220f4200108781808000200341a0016a" + "200441e8006a2903004200200f420010878180800020034190016a200441" + "f0006a2903004200200f420010878180800020034180016a200441f8006a" + "2903004200200f4200108781808000200341f0006a20044180016a290300" + "4200200f4200108781808000200341e0006a20044188016a290300420020" + "0f4200108781808000200d200341e0006a41086a29030020032903602210" + "200a7c220f201054ad7c200f200341f0006a41086a290300200329037022" + "1020097c220a201054ad7c200a20034180016a41086a2903002003290380" + "01221020087c2209201054ad7c200920034190016a41086a290300200329" + "039001221020077c2208201054ad7c2008200341a0016a41086a29030020" + "032903a001221020067c2207201054ad7c2007200341b0016a41086a2903" + "0020032903b001220620057c2205200654ad7c7c2206200754ad7c7c2207" + "200854ad7c7c2208200954ad7c7c2209200a54ad7c7c220a200f54ad7c7c" + "210d200e41306a210e0c000b0b200341d0006a200542fdfff3ffcffffff9" + "897f7e220f420042abd5feffffffbfffb97f4200108781808000200341c0" + "006a200f420042ffffcf8aebffffd51e4200108781808000200341306a20" + "0f420042a4ecc3b58fd4b498e7004200108781808000200341206a200f42" + "0042bfa5949ccff0d2bbe4004200108781808000200341106a200f420042" + "d7d9ae9ae4f6e98dcb0042001087818080002003200f4200429acdffcba3" + "bdc4801a4200108781808000200d200341086a2903002003290300221020" + "0a7c220f201054ad7c200f200341106a41086a2903002003290310221020" + "097c220a201054ad7c200a200341206a41086a2903002003290320221020" + "087c2209201054ad7c2009200341306a41086a2903002003290330221020" + "077c2208201054ad7c2008200341c0006a41086a29030020032903402210" + "20067c2207201054ad7c2007200341d0006a41086a290300200329035022" + "0620057c200654ad7c7c2205200754ad7c7c2206200854ad7c7c22072009" + "54ad7c7c2208200a54ad7c7c2209200f54ad7c7c210a200b21040c000b0b" + "2003200a3703e801200320093703e001200320083703d801200320073703" + "d001200320063703c801200320053703c0012000200341c0016a10d68080" + "8000200341f0016a2480808080000b1c002000200110b280808000200041" + "306a200141306a10b2808080000be20103037f017e017f23808080800041" + "c0016b2203248080808000200341306a410041301085818080001a200341" + "e086c0800041301086818080002104200241306a21050240034020052002" + "460d01200541786a22052903002106413f210303402003417f460d012004" + "41e0006a200410ba808080002004200441e0006a41e00010868180800021" + "07024020062003413f71ad88420183500d00200741e0006a2007200110b3" + "808080002007200741e0006a41e0001086818080001a0b2003417f6a2103" + "0c000b0b0b2000200441e0001086818080001a200441c0016a2480808080" + "000b900202017f017e23808080800041b0036b2202248080808000200241" + "004130108581808000220241e0006a410041301085818080001a20024130" + "6a41e086c0800041301086818080001a20024190016a2001419001108681" + "8080001a42808082808080a080e90021030240034020034200510d012002" + "41a0026a20024190016a10c68080800020024190016a200241a0026a4190" + "011086818080001a02402003420183500d00200241a0026a200220024190" + "016a10c7808080002002200241a0026a4190011086818080001a0b200342" + "018821030c000b0b200241a0026a200210e58080800020002002200241a0" + "026a41900110868180800022024190011086818080001a200241b0036a24" + "80808080000b3400200041306a200141306a10b280808000200041e0006a" + "200141e0006a41301086818080001a2000200141301086818080001a0b6b" + "01037f23808080800041106b22022480808080000240024020012802000d" + "00410021030c010b200241086a200110d0808080004101210320022d0009" + "210420022d00080d0041002103200141003602000b200020043a00012000" + "20033a0000200241106a2480808080000b7501027f23808080800041e000" + "6b2201248080808000200141306a410041301085818080001a200141e086" + "c0800041301086818080002101410110a38080800021022000410041e000" + "108581808000220041e0006a200141e0001086818080001a200020023a00" + "c001200141e0006a2480808080000b920101017f23808080800041c0016b" + "2202248080808000200041e0006a200141e0006a41e0001086818080001a" + "200241306a410041301085818080001a200241e086c08000413010868180" + "8000220241e0006a410041e0001085818080001a200041c0016a20022002" + "41e0006a20012d00c00110b0808080002000200141e0001086818080001a" + "200241c0016a2480808080000baa0201047f23808080800041e0036b2204" + "24808080800020042001200210b380808000200441e0006a200141e0006a" + "2205200310b38080800020044180036a200141c0016a2206200310b38080" + "8000200441a0026a20044180036a20044180036a41306a220710b8808080" + "00200441a0026a41306a20044180036a200710b9808080002000200441a0" + "026a200410bc80808000200441a0026a2002200310bc8080800020044180" + "036a2001200510bc80808000200441c0016a200441a0026a20044180036a" + "10b38080800020044180036a200441c0016a200410bb80808000200041e0" + "006a20044180036a200441e0006a10bb8080800020044180036a20062002" + "10b380808000200041c0016a20044180036a200441e0006a10bc80808000" + "200441e0036a2480808080000bf50706027f067e027f017e017f027e2380" + "8080800041f0016b22032480808080004100210442002105420021064200" + "210742002108420021094200210a02400340200441054b0d012004200441" + "06496a210b200120044103746a210c4200210d41e07d210e02400340200e" + "450d01200341b0016a2002200e6a220441a0026a2903004200200c200e6a" + "41a0026a290300220f4200108781808000200341a0016a200441a8026a29" + "03004200200f420010878180800020034190016a200441b0026a29030042" + "00200f420010878180800020034180016a200441b8026a2903004200200f" + "4200108781808000200341f0006a200441c0026a2903004200200f420010" + "8781808000200341e0006a200441c8026a2903004200200f420010878180" + "8000200d200341e0006a41086a29030020032903602210200a7c220f2010" + "54ad7c200f200341f0006a41086a2903002003290370221020097c220a20" + "1054ad7c200a20034180016a41086a290300200329038001221020087c22" + "09201054ad7c200920034190016a41086a29030020032903900122102007" + "7c2208201054ad7c2008200341a0016a41086a29030020032903a0012210" + "20067c2207201054ad7c2007200341b0016a41086a29030020032903b001" + "220620057c2205200654ad7c7c2206200754ad7c7c2207200854ad7c7c22" + "08200954ad7c7c2209200a54ad7c7c220a200f54ad7c7c210d200e41306a" + "210e0c000b0b200341d0006a200542fdfff3ffcffffff9897f7e220f4200" + "42abd5feffffffbfffb97f4200108781808000200341c0006a200f420042" + "ffffcf8aebffffd51e4200108781808000200341306a200f420042a4ecc3" + "b58fd4b498e7004200108781808000200341206a200f420042bfa5949ccf" + "f0d2bbe4004200108781808000200341106a200f420042d7d9ae9ae4f6e9" + "8dcb0042001087818080002003200f4200429acdffcba3bdc4801a420010" + "8781808000200d200341086a29030020032903002210200a7c220f201054" + "ad7c200f200341106a41086a2903002003290310221020097c220a201054" + "ad7c200a200341206a41086a2903002003290320221020087c2209201054" + "ad7c2009200341306a41086a2903002003290330221020077c2208201054" + "ad7c2008200341c0006a41086a2903002003290340221020067c22072010" + "54ad7c2007200341d0006a41086a2903002003290350220620057c200654" + "ad7c7c2205200754ad7c7c2206200854ad7c7c2207200954ad7c7c220820" + "0a54ad7c7c2209200f54ad7c7c210a200b21040c000b0b2003200a3703e8" + "01200320093703e001200320083703d801200320073703d0012003200637" + "03c801200320053703c0012000200341c0016a10d680808000200341f001" + "6a2480808080000bdc0101027f2380808080004180036b22032480808080" + "002003200110ba80808000200341e0006a200210ba80808000200341c001" + "6a200341e0006a200341e0006a41306a220410b880808000200341c0016a" + "41306a200341e0006a200410b9808080002000200341c0016a200310bc80" + "808000200341c0016a2001200210bc80808000200341a0026a200341c001" + "6a10ba80808000200341c0016a200341a0026a41e0001086818080001a20" + "0341c0016a200310ec80808000200041e0006a200341c0016a200341e000" + "6a10bb8080800020034180036a2480808080000b3c01017f238080808000" + "41e0006b220224808080800020022000200110bb808080002000200241e0" + "001086818080001a200241e0006a2480808080000b9f0701037f23808080" + "800041a0116b2201248080808000200141a0026a200010ba808080002001" + "4180036a200041e0006a220210ba80808000200141e0036a20014180036a" + "10ba80808000200141c0106a20014180036a200010bc80808000200141e0" + "0f6a200141c0106a10ba80808000200141800f6a200141e00f6a200141a0" + "026a10bb80808000200141c0046a200141800f6a200141e0036a10bb8080" + "8000200141a0056a200141c0046a200141c0046a10bc80808000200141c0" + "106a200141a0026a200141a0026a10bc8080800020014180066a200141c0" + "106a200141a0026a10bc80808000200141e0066a200020014180066a10bc" + "80808000200141c0076a20014180066a10ba80808000200141a0086a2000" + "41c0016a220310ba80808000200141c0106a200141c0076a200141a0056a" + "10bb80808000200141e00f6a200141c0106a200141a0056a10bb80808000" + "2000200141e00f6a41e0001086818080002100200141c0106a2003200210" + "bc80808000200141e00f6a200141c0106a10ba80808000200141800f6a20" + "0141e00f6a20014180036a10bb80808000200141e00f6a200141800f6a20" + "0141a0086a10bb808080002003200141e00f6a41e0001086818080002103" + "200141c0106a200141a0056a200010bb80808000200141e00f6a200141c0" + "106a20014180066a10b3808080002002200141e00f6a41e0001086818080" + "00210220014180096a200141e0036a200141e0036a10bc80808000200141" + "e0096a20014180096a20014180096a10bc80808000200141c00a6a200141" + "e0096a200141e0096a10bc808080002002200141c00a6a10ec8080800020" + "0141a00b6a20014180066a200141a0086a10b380808000200141800c6a20" + "0141a00b6a200141a00b6a10bc80808000200141e00c6a200141800c6a10" + "e280808000200141c0106a200141e0066a10ba80808000200141e00f6a20" + "0141c0106a200141a0026a10bb80808000200141c00d6a200141e00f6a20" + "0141c0076a10bb80808000200141a00e6a20014180036a20014180036a10" + "bc80808000200141800f6a200141a00e6a200141a00e6a10bc8080800020" + "0141e00f6a200141c00d6a200141800f6a10bb80808000200141c0106a20" + "03200141a0086a10b3808080002001200141c0106a200141c0106a10bc80" + "808000200141e0006a200141e00c6a41e0001086818080001a200141c001" + "6a200141e00f6a41e0001086818080001a200041e8036a200141ac8cc080" + "0010ee80808000200141a0116a2480808080000b4201017f024020002802" + "0822032000280200470d002000200210d8808080000b2000280204200341" + "a0026c6a200141a0021086818080001a2000200341016a3602080b4c0101" + "7f23808080800041106b2202248080808000200241988cc0800036020c20" + "022000360208200241086a41b08dc080002002410c6a41b08dc080002001" + "419c8cc0800010d380808000000b7902017f017e23808080800041306b22" + "0324808080800020032001360204200320003602002003410236020c2003" + "41a08dc08000360208200342023702142003418580808000ad4220862204" + "2003ad8437032820032004200341046aad843703202003200341206a3602" + "10200341086a200210a480808000000b0f002000280200200110f2808080" + "000be10201067f23808080800041106b2202248080808000410a21030240" + "024020004190ce004f0d00200021040c010b410a21030340200241066a20" + "036a2205417c6a20004190ce006e220441f0b1036c20006a220641ffff03" + "7141e4006e220741017441ff8ec080006a2f00003b00002005417e6a2007" + "419c7f6c20066a41ffff037141017441ff8ec080006a2f00003b00002003" + "417c6a2103200041ffc1d72f4b21052004210020050d000b0b0240024020" + "0441e3004b0d00200421000c010b200241066a2003417e6a22036a200441" + "ffff037141e4006e2200419c7f6c20046a41ffff037141017441ff8ec080" + "006a2f00003b00000b024002402000410a490d00200241066a2003417e6a" + "22036a200041017441ff8ec080006a2f00003b00000c010b200241066a20" + "03417f6a22036a20004130723a00000b200141014100200241066a20036a" + "410a20036b10d5808080002100200241106a24808080800020000b380201" + "7f017e23808080800041106b220124808080800020002902002102200120" + "0036020c20012002370204200141046a108181808000000b490002402002" + "418080c400460d002000200220012802101181808080008080808000450d" + "0041010f0b024020030d0041000f0b200020032004200128020c11808080" + "800080808080000b7902017f017e23808080800041306b22032480808080" + "0020032001360204200320003602002003410236020c2003419c91c08000" + "360208200342023702142003418580808000ad4220862204200341046aad" + "84370328200320042003ad843703202003200341206a360210200341086a" + "200210a480808000000b1c0020002802002001200028020428020c118180" + "80800080808080000b14002001200028020020002802041092808080000b" + "1400200128021c2001280220200010f9808080000bbb05010a7f23808080" + "800041306b22032480808080002003200136022c20032000360228200341" + "033a00242003422037021c41002104200341003602142003410036020c02" + "400240024002400240200228021022050d00200228020c2200450d012002" + "280208220120004103746a21062000417f6a41ffffffff017141016a2104" + "2002280200210003400240200041046a2802002207450d00200328022820" + "002802002007200328022c28020c11808080800080808080000d040b2001" + "2802002003410c6a200141046a28020011818080800080808080000d0320" + "0041086a2100200141086a22012006470d000c020b0b2002280214220145" + "0d00200141057421082001417f6a41ffffff3f7141016a21042002280208" + "2109200228020021004100210703400240200041046a2802002201450d00" + "200328022820002802002001200328022c28020c11808080800080808080" + "000d030b2003200520076a220141106a28020036021c20032001411c6a2d" + "00003a00242003200141186a2802003602202001410c6a28020021064100" + "210a4100210b024002400240200141086a2802000e03010002010b200641" + "0374210c4100210b2009200c6a220c2802000d01200c28020421060b4101" + "210b0b200320063602102003200b36020c200141046a2802002106024002" + "40024020012802000e03010002010b2006410374210b2009200b6a220b28" + "02000d01200b28020421060b4101210a0b200320063602182003200a3602" + "142009200141146a2802004103746a22012802002003410c6a200141046a" + "28020011818080800080808080000d02200041086a21002008200741206a" + "2207470d000b0b200420022802044f0d0120032802282002280200200441" + "03746a22012802002001280204200328022c28020c118080808000808080" + "8000450d010b410121010c010b410021010b200341306a24808080800020" + "010b6001027f20002802042102200028020021030240200028020822002d" + "0000450d00200341f48ec080004104200228020c11808080800080808080" + "00450d0041010f0b20002001410a463a0000200320012002280210118180" + "80800080808080000b1200200041dc8ec08000200110f9808080000b7902" + "017f017e23808080800041306b2203248080808000200320013602042003" + "20003602002003410236020c200341d091c0800036020820034202370214" + "2003418580808000ad4220862204200341046aad84370328200320042003" + "ad843703202003200341206a360210200341086a200210a480808000000b" + "ab0201037f2380808080004180016b220224808080800020002802002100" + "024002400240200128021422034110710d0020034120710d012000280200" + "200110f28080800021000c020b2000280200210041810121030340200220" + "036a417e6a2000410f712204413072200441d7006a2004410a491b3a0000" + "2003417f6a21032000410f4b21042000410476210020040d000b200141fd" + "8ec080004102200220036a417f6a41810120036b10d58080800021000c01" + "0b2000280200210041810121030340200220036a417e6a2000410f712204" + "413072200441376a2004410a491b3a00002003417f6a21032000410f4b21" + "042000410476210020040d000b200141fd8ec080004102200220036a417f" + "6a41810120036b10d58080800021000b20024180016a2480808080002000" + "0b0900200041003602000b990101027f23808080800041106b2204248080" + "808000410041002802f093c08000220541016a3602f093c0800002402005" + "4100480d000240024041002d00bc97c080000d00410041002802b897c080" + "0041016a3602b897c0800041002802ec93c08000417f4a0d010c020b2004" + "41086a200020011182808080008080808000000b410041003a00bc97c080" + "002002450d00108081808000000b000b0300000b0b002000108281808000" + "000bba0101037f23808080800041106b2201248080808000200028020022" + "0228020c2103024002400240024020022802040e020001020b20030d0141" + "012102410021030c020b20030d0020022802002202280204210320022802" + "0021020c010b20014180808080783602002001200036020c200141868080" + "8000200028020822002d000820002d000910ff80808000000b2001200336" + "0204200120023602002001418780808000200028020822002d000820002d" + "000910ff80808000000b0c00200020012902003703000bc30201047f411f" + "21020240200141ffffff074b0d002001410620014108766722026b764101" + "7120024101746b413e6a21020b200042003702102000200236021c200241" + "027441f493c080006a21030240410028029097c080004101200274220471" + "0d0020032000360200200020033602182000200036020c20002000360208" + "4100410028029097c0800020047236029097c080000f0b02400240024020" + "0328020022042802044178712001470d00200421020c010b200141004119" + "20024101766b2002411f461b742103034020042003411d764104716a4110" + "6a22052802002202450d0220034101742103200221042002280204417871" + "2001470d000b0b20022802082203200036020c2002200036020820004100" + "3602182000200236020c200020033602080f0b2005200036020020002004" + "3602182000200036020c200020003602080baa0301057f02400240200241" + "104f0d00200021030c010b02402000410020006b41037122046a22052000" + "4d0d002004417f6a21062000210302402004450d00200421072000210303" + "40200320013a0000200341016a21032007417f6a22070d000b0b20064107" + "490d000340200320013a0000200341076a20013a0000200341066a20013a" + "0000200341056a20013a0000200341046a20013a0000200341036a20013a" + "0000200341026a20013a0000200341016a20013a0000200341086a220320" + "05470d000b0b024020052005200220046b2202417c716a22034f0d002001" + "41ff017141818284086c2107034020052007360200200541046a22052003" + "490d000b0b200241037121020b02402003200320026a22074f0d00200241" + "7f6a2104024020024107712205450d000340200320013a0000200341016a" + "21032005417f6a22050d000b0b20044107490d000340200320013a000020" + "0341076a20013a0000200341066a20013a0000200341056a20013a000020" + "0341046a20013a0000200341036a20013a0000200341026a20013a000020" + "0341016a20013a0000200341086a22032007470d000b0b20000ba5050108" + "7f02400240200241104f0d00200021030c010b02402000410020006b4103" + "7122046a220520004d0d002004417f6a2106200021032001210702402004" + "450d002004210820002103200121070340200320072d00003a0000200741" + "016a2107200341016a21032008417f6a22080d000b0b20064107490d0003" + "40200320072d00003a0000200341016a200741016a2d00003a0000200341" + "026a200741026a2d00003a0000200341036a200741036a2d00003a000020" + "0341046a200741046a2d00003a0000200341056a200741056a2d00003a00" + "00200341066a200741066a2d00003a0000200341076a200741076a2d0000" + "3a0000200741086a2107200341086a22032005470d000b0b200520022004" + "6b2208417c7122066a210302400240200120046a22074103710d00200520" + "034f0d0120072101034020052001280200360200200141046a2101200541" + "046a22052003490d000c020b0b200520034f0d0020074103742202411871" + "21042007417c71220941046a2101410020026b411871210a200928020021" + "0203402005200220047620012802002202200a7472360200200141046a21" + "01200541046a22052003490d000b0b20084103712102200720066a21010b" + "02402003200320026a22054f0d002002417f6a2108024020024107712207" + "450d000340200320012d00003a0000200141016a2101200341016a210320" + "07417f6a22070d000b0b20084107490d000340200320012d00003a000020" + "0341016a200141016a2d00003a0000200341026a200141026a2d00003a00" + "00200341036a200141036a2d00003a0000200341046a200141046a2d0000" + "3a0000200341056a200141056a2d00003a0000200341066a200141066a2d" + "00003a0000200341076a200141076a2d00003a0000200141086a21012003" + "41086a22032005470d000b0b20000b6e01067e2000200342ffffffff0f83" + "2205200142ffffffff0f8322067e22072003422088220820067e22062005" + "200142208822097e7c22054220867c220a3703002000200820097e200520" + "0654ad4220862005422088847c200a200754ad7c200420017e200320027e" + "7c7c3703080bea0901087f024002400240200020016b20024f0d00200120" + "026a2103200020026a210420024110490d014100200441037122056b2106" + "02402004417c71220720044f0d002005417f6a21080240024020050d0020" + "0321090c010b2005210a2003210903402004417f6a22042009417f6a2209" + "2d00003a0000200a417f6a220a0d000b0b20084103490d002009417c6a21" + "0903402004417f6a200941036a2d00003a00002004417e6a200941026a2d" + "00003a00002004417d6a200941016a2d00003a00002004417c6a22042009" + "2d00003a00002009417c6a210920072004490d000b0b2007200220056b22" + "09417c7122026b2104410020026b210a02400240200320066a2203410371" + "0d00200420074f0d01200920016a417c6a210103402007417c6a22072001" + "2802003602002001417c6a210120042007490d000c020b0b200420074f0d" + "002003410374220241187121052003417c712208417c6a2101410020026b" + "41187121062008280200210203402007417c6a2207200220067420012802" + "002202200576723602002001417c6a210120042007490d000b0b20094103" + "7121022003200a6a21030c010b02400240200241104f0d00200021040c01" + "0b02402000410020006b410371220a6a220920004d0d00200a417f6a2105" + "20002104200121070240200a450d00200a21032000210420012107034020" + "0420072d00003a0000200741016a2107200441016a21042003417f6a2203" + "0d000b0b20054107490d000340200420072d00003a0000200441016a2007" + "41016a2d00003a0000200441026a200741026a2d00003a0000200441036a" + "200741036a2d00003a0000200441046a200741046a2d00003a0000200441" + "056a200741056a2d00003a0000200441066a200741066a2d00003a000020" + "0441076a200741076a2d00003a0000200741086a2107200441086a220420" + "09470d000b0b20092002200a6b2203417c7122056a210402400240200120" + "0a6a22074103710d00200920044f0d012007210103402009200128020036" + "0200200141046a2101200941046a22092004490d000c020b0b200920044f" + "0d0020074103742202411871210a2007417c71220841046a210141002002" + "6b411871210620082802002102034020092002200a762001280200220220" + "067472360200200141046a2101200941046a22092004490d000b0b200341" + "03712102200720056a21010b2004200420026a22094f0d012002417f6a21" + "03024020024107712207450d000340200420012d00003a0000200141016a" + "2101200441016a21042007417f6a22070d000b0b20034107490d01034020" + "0420012d00003a0000200441016a200141016a2d00003a0000200441026a" + "200141026a2d00003a0000200441036a200141036a2d00003a0000200441" + "046a200141046a2d00003a0000200441056a200141056a2d00003a000020" + "0441066a200141066a2d00003a0000200441076a200141076a2d00003a00" + "00200141086a2101200441086a22042009470d000c020b0b200420026b22" + "0720044f0d002002417f6a2109024020024103712201450d000340200441" + "7f6a22042003417f6a22032d00003a00002001417f6a22010d000b0b2009" + "4103490d002003417c6a210103402004417f6a200141036a2d00003a0000" + "2004417e6a200141026a2d00003a00002004417d6a200141016a2d00003a" + "00002004417c6a220420012d00003a00002001417c6a210120072004490d" + "000b0b20000b0e002000200120021088818080000b0bf2130100418080c0" + "000be8132f72757374632f34656231363132353065333430633866343866" + "3636653262393239656634613562656437633138312f6c6962726172792f" + "636f72652f7372632f697465722f7472616974732f6974657261746f722e" + "72730000100058000000b307000009000000000000000000000001000000" + "0800000063616c6c65642060526573756c743a3a756e7772617028296020" + "6f6e20616e2060457272602076616c75652f72757374632f346562313631" + "323530653334306338663438663636653262393239656634613562656437" + "633138312f6c6962726172792f616c6c6f632f7372632f736c6963652e72" + "73000000a30010004a000000a10000001900000054727946726f6d536c69" + "63654572726f720000000100000000000000d80210005e000000b4020000" + "090000002f72757374632f34656231363132353065333430633866343866" + "3636653262393239656634613562656437633138312f6c6962726172792f" + "636f72652f7372632f736c6963652f697465722e727300002c0110004e00" + "0000f6050000150000007372632f6c69622e727300008c0110000a000000" + "1f000000160000008c0110000a00000028000000310000008c0110000a00" + "000028000000440000004661696c656420746f20646573657269616c697a" + "6520766b8c0110000a0000002f000000310000008c0110000a0000002f00" + "0000440000008c0110000a000000620000001f0000008c0110000a000000" + "630000000a0000008c0110000a00000064000000170000008c0110000a00" + "0000650000000a0000008c0110000a00000066000000170000008c011000" + "0a000000670000000a0000004661696c656420746f20646573657269616c" + "697a6520614661696c656420746f20646573657269616c697a6520624661" + "696c656420746f20646573657269616c697a652063496e76616c69642062" + "7974657320666f72205363616c61726361706163697479206f766572666c" + "6f770000bd021000110000002f686f6d652f6f706964736b6f706e79692f" + "2e636172676f2f72656769737472792f7372632f696e6465782e63726174" + "65732e696f2d313934396366386336623562353537662f737562746c652d" + "322e362e312f7372632f6c69622e72730000000000000400000004000000" + "0900000001000000d80210005e000000bd0200000900000000000000fdff" + "02000000097602000cc40b00f4ebba58c7535798485f455752705358ce77" + "6dec56a2971a075c93e480fac35ef6154617341c341fdff4f104d109a6e6" + "760ad5b6954c6c47e58dc0839d93a988eb672d9519b5853e799aaae3ca92" + "e58f9811abeaffffffbf7feeffff54acffffaa07893dac3da834ccd9af44" + "e13ce1d21dd935ebd290ede9c692a6f95f8e7a448006a9aafffffffffeb9" + "ffff53b1feffab1e24f6b0f6a0d23067bf1285f3844b7764d7ac4b43b6a7" + "1b4b9ae67f39ea11011aaaeaffffffbf7feeffff54acffffaa07893dac3d" + "a834ccd9af44e13ce1d21dd935ebd290ede9c692a6f95f8e7a44800655d5" + "ffffff7fffdcffffa958ffff550f127b587b506998b35f89c279c2a53bb2" + "6bd6a521dbd38d254df3bf1cf588000df3ff0c00000027aa0a0034fc3200" + "cc537f800a6b7ae98f47d724bae6be7ed3b12fab78bf3b73c98e7ede833d" + "5145d609e8648a791b36f1302a5ace7eabddb8f3f77715c63acaa8169b02" + "fd74f82f6ac26e1c706066b7363660611b24aba41b05f3ff0c00000027aa" + "0a0034fc3200cc537f800a6b7ae98f47d724bae6be7ed3b12fab78bf3b73" + "c98e7ede833d5145d609f3ff0c00000027aa0a0034fc3200cc537f800a6b" + "7ae98f47d724bae6be7ed3b12fab78bf3b73c98e7ede833d5145d6092e55" + "270000007644200048439a00b8dc598b6e4acee97e6fc65ba9c0b73003b1" + "b7541efbfcb14061e1b40b7f09be81032e55270000007644200048439a00" + "b8dc598b6e4acee97e6fc65ba9c0b73003b1b7541efbfcb14061e1b40b7f" + "09be81032f686f6d652f6f706964736b6f706e79692f2e636172676f2f72" + "656769737472792f7372632f696e6465782e6372617465732e696f2d3139" + "34396366386336623562353537662f626c7331325f3338312d302e382e30" + "2f7372632f70616972696e67732e72730000a00510006600000016020000" + "1500000044000000a0051000660000001b02000009000000a00510006600" + "0000050200001d000000a005100066000000090200001d000000a0051000" + "660000003802000032000000a00510006600000044020000320000002969" + "6e646578206f7574206f6620626f756e64733a20746865206c656e206973" + "20206275742074686520696e64657820697320006d061000200000008d06" + "1000120000000000000004000000040000000a0000003d3d617373657274" + "696f6e20606c6566742020726967687460206661696c65640a20206c6566" + "743a200a2072696768743a200000c206100010000000d206100017000000" + "e90610000900000020726967687460206661696c65643a200a20206c6566" + "743a20000000c2061000100000000c071000100000001c07100009000000" + "e9061000090000003a200000010000000000000048071000020000000000" + "00000c000000040000000b0000000c0000000d000000202020202c0a2828" + "0a3078303030313032303330343035303630373038303931303131313231" + "333134313531363137313831393230323132323233323432353236323732" + "383239333033313332333333343335333633373338333934303431343234" + "333434343534363437343834393530353135323533353435353536353735" + "383539363036313632363336343635363636373638363937303731373237" + "333734373537363737373837393830383138323833383438353836383738" + "3838393930393139323933393439353936393739383939617474656d7074" + "20746f20646976696465206279207a65726f4708100019000000206f7574" + "206f662072616e676520666f7220736c696365206f66206c656e67746820" + "72616e676520656e6420696e6465782000008a0810001000000068081000" + "22000000736c69636520696e646578207374617274732061742020627574" + "20656e64732061742000ac08100016000000c20810000d00000028292f72" + "757374632f34656231363132353065333430633866343866363665326239" + "3239656634613562656437633138312f6c6962726172792f616c6c6f632f" + "7372632f7261775f7665632e72730000e20810004c000000280200001100" + "00002f727573742f646570732f646c6d616c6c6f632d302e322e372f7372" + "632f646c6d616c6c6f632e7273617373657274696f6e206661696c65643a" + "207073697a65203e3d2073697a65202b206d696e5f6f7665726865616400" + "4009100029000000a804000009000000617373657274696f6e206661696c" + "65643a207073697a65203c3d2073697a65202b206d61785f6f7665726865" + "616400004009100029000000ae0400000d00000000c94e046e616d65000e" + "0d7761736d5f6c69622e7761736d01914e8a01008a015f5a4e3130325f24" + "4c5424636f72652e2e697465722e2e61646170746572732e2e6d61702e2e" + "4d6170244c5424492443244624475424247532302461732475323024636f" + "72652e2e697465722e2e7472616974732e2e6974657261746f722e2e4974" + "657261746f72244754243973697a655f68696e7431376833383630386236" + "62663263303736666145014c5f5a4e34636f72653970616e69636b696e67" + "313170616e69635f636f6e7374323370616e69635f636f6e73745f646976" + "5f62795f7a65726f3137683033346433623765633138373166373545024d" + "5f5a4e34636f726533707472343364726f705f696e5f706c616365244c54" + "247761736d5f6c69622e2e566572696679696e674b657924475424313768" + "393064303131346662343063613937644503475f5a4e35616c6c6f633772" + "61775f7665633230526177566563496e6e6572244c542441244754243130" + "6465616c6c6f636174653137683235303163353461663065323831336145" + "04505f5a4e34636f726533707472343664726f705f696e5f706c61636524" + "4c5424616c6c6f632e2e7665632e2e566563244c54247538244754242447" + "5424313768663462323737666433376462353031654505565f5a4e34636f" + "726533707472353264726f705f696e5f706c616365244c5424626c733132" + "5f3338312e2e70616972696e67732e2e4732507265706172656424475424" + "313768623964653634383231343939353539344506675f5a4e34636f7265" + "33707472363964726f705f696e5f706c616365244c5424616c6c6f632e2e" + "7665632e2e566563244c5424626c7331325f3338312e2e7363616c61722e" + "2e5363616c61722447542424475424313768376265333235646130373238" + "386634384507385f5a4e35616c6c6f63337665633136566563244c542454" + "244324412447542434707573683137686236356465366561306165303964" + "31374508435f5a4e35616c6c6f63377261775f7665633139526177566563" + "244c54245424432441244754243867726f775f6f6e653137686531306535" + "65303538376531393262664509495f5a4e35616c6c6f6335736c69636532" + "395f244c5424696d706c2475323024247535622454247535642424475424" + "36746f5f76656331376836333665656464383765653761373437450a4d5f" + "5a4e35616c6c6f63377261775f7665633230526177566563496e6e657224" + "4c542441244754243136776974685f63617061636974795f696e31376861" + "653336636161393636356566343833450b4b5f5a4e35616c6c6f63377261" + "775f7665633230526177566563496e6e6572244c54244124475424313467" + "726f775f616d6f7274697a65643137686439353064656131373163323030" + "3035450c335f5a4e35616c6c6f63377261775f766563313268616e646c65" + "5f6572726f7231376863613161646630343635323765396532450d0e5f5f" + "727573745f6465616c6c6f630e4c5f5a4e35616c6c6f63377261775f7665" + "633230526177566563496e6e6572244c5424412447542431357472795f61" + "6c6c6f636174655f696e3137686534626630623334333637646136646345" + "0f5e5f5a4e36355f244c5424626c7331325f3338312e2e67312e2e473141" + "6666696e65247532302461732475323024636f72652e2e6f70732e2e6172" + "6974682e2e4e656724475424336e65673137683434323138626332316532" + "65356663314510725f5a4e36395f244c5424626c7331325f3338312e2e66" + "702e2e4670247532302461732475323024737562746c652e2e436f6e6469" + "74696f6e616c6c7953656c65637461626c65244754243138636f6e646974" + "696f6e616c5f73656c656374313768386165306466613830666434313139" + "364511605f5a4e36375f244c5424636f72652e2e61727261792e2e547279" + "46726f6d536c6963654572726f72247532302461732475323024636f7265" + "2e2e666d742e2e44656275672447542433666d7431376863303634386262" + "31393264393231376545122e5f5a4e34636f726533666d7439466f726d61" + "747465723370616431376833316663303133336231396665333065451367" + "5f5a4e36385f244c5424636f72652e2e666d742e2e6275696c646572732e" + "2e50616441646170746572247532302461732475323024636f72652e2e66" + "6d742e2e5772697465244754243977726974655f73747231376834353537" + "3732653638643462343039364514385f5a4e36737562746c65313743744f" + "7074696f6e244c5424542447542436657870656374313768623863663632" + "323139313530313333334515495f5a4e34345f244c542424524624542475" + "32302461732475323024636f72652e2e666d742e2e446973706c61792447" + "542433666d74313768353633396538653836623831393165364516355f5a" + "4e34636f72653970616e69636b696e6731336173736572745f6661696c65" + "64313768393337633632373834633734396537664517385f5a4e36737562" + "746c65313743744f7074696f6e244c542454244754243665787065637431" + "3768633764316533383030323138386237654518705f5a4e38315f244c54" + "24616c6c6f632e2e7665632e2e566563244c542454244324412447542424" + "7532302461732475323024636f72652e2e6f70732e2e696e6465782e2e49" + "6e646578244c542449244754242447542435696e64657831376862376565" + "6135613738316438393239374519405f5a4e34636f726535736c69636535" + "696e6465783232736c6963655f696e6465785f6f726465725f6661696c31" + "376866663036393161306536326561633864451a425f5a4e34636f726535" + "736c69636535696e6465783234736c6963655f656e645f696e6465785f6c" + "656e5f6661696c31376861383936346133343065666132346537451b0861" + "6c6c6f636174651c13646573657269616c697a655f67315f7761736d1d32" + "5f5a4e34636f726536726573756c743133756e777261705f6661696c6564" + "31376861313838333239383461636266333830451e3e5f5a4e39626c7331" + "325f333831326731384731416666696e65313566726f6d5f636f6d707265" + "7373656431376832333963336331363436646339303436451f355f5a4e38" + "7761736d5f6c69623139646573657269616c697a655f67325f7761736d31" + "37683530336430613839336365653362666645203e5f5a4e39626c733132" + "5f333831326732384732416666696e65313566726f6d5f636f6d70726573" + "7365643137686333616566303334336638323663626245211462656c6c6d" + "616e5f67726f746831365f7465737422335f5a4e39626c7331325f333831" + "367363616c6172365363616c617233737562313768656363643066636134" + "373035653937364523285f5a4e36737562746c6539626c61636b5f626f78" + "313768633661663135363636663731396234384524305f5a4e34636f7265" + "3970616e69636b696e673970616e69635f666d7431376862393162616461" + "636536656538323837452585015f5a4e3130325f244c5424626c7331325f" + "3338312e2e67312e2e473150726f6a656374697665247532302461732475" + "323024636f72652e2e636f6e766572742e2e46726f6d244c542424524624" + "626c7331325f3338312e2e67312e2e4731416666696e6524475424244754" + "243466726f6d3137686634356430353636343237373335316445262e5f5a" + "4e39626c7331325f33383132667032467036696e76657274313768366335" + "3632643539653638646633633245272b5f5a4e39626c7331325f33383132" + "6670324670336d756c313768646666623336663036373139613633374528" + "365f5a4e39626c7331325f333831326731384731416666696e6538696465" + "6e746974793137686236366162643638326233626339356345292f5f5a4e" + "39626c7331325f3338313266703246703769735f7a65726f313768333962" + "31303634343730313433376536452a785f5a4e37355f244c5424626c7331" + "325f3338312e2e67312e2e4731416666696e652475323024617324753230" + "24737562746c652e2e436f6e646974696f6e616c6c7953656c6563746162" + "6c65244754243138636f6e646974696f6e616c5f73656c65637431376833" + "323735393935653930646636613863452b85015f5a4e3130325f244c5424" + "626c7331325f3338312e2e70616972696e67732e2e473250726570617265" + "64247532302461732475323024636f72652e2e636f6e766572742e2e4672" + "6f6d244c5424626c7331325f3338312e2e67322e2e4732416666696e6524" + "475424244754243466726f6d313768353930643863663565363536346465" + "66452c2f5f5a4e39626c7331325f33383134667031323446703132336f6e" + "6531376839346666616330666264306163343332452d90015f5a4e313033" + "5f244c5424626c7331325f3338312e2e70616972696e67732e2e6d756c74" + "695f6d696c6c65725f6c6f6f702e2e416464657224753230246173247532" + "3024626c7331325f3338312e2e70616972696e67732e2e4d696c6c65724c" + "6f6f70447269766572244754243133646f75626c696e675f737465703137" + "6833346536393232613038346336343933452e705f5a4e38315f244c5424" + "616c6c6f632e2e7665632e2e566563244c54245424432441244754242475" + "32302461732475323024636f72652e2e6f70732e2e696e6465782e2e496e" + "646578244c542449244754242447542435696e6465783137686539346538" + "6262303063326535366564452f2e5f5a4e39626c7331325f333831387061" + "6972696e677333656c6c3137683264393865303762336132336635313345" + "30745f5a4e37315f244c5424626c7331325f3338312e2e6670322e2e4670" + "32247532302461732475323024737562746c652e2e436f6e646974696f6e" + "616c6c7953656c65637461626c65244754243138636f6e646974696f6e61" + "6c5f73656c6563743137686366633738633362393036656661383945315a" + "5f5a4e36315f244c5424626c7331325f3338312e2e6670362e2e46703624" + "7532302461732475323024636f72652e2e6f70732e2e61726974682e2e4e" + "656724475424336e65673137686230666536353636326461326334343345" + "322b5f5a4e39626c7331325f333831326670324670336e65673137683861" + "363566633733316133386134393745332d5f5a4e39626c7331325f333831" + "3366703233467032336d756c313768326433373464346666306563343037" + "6245345a5f5a4e36315f244c5424626c7331325f3338312e2e6670362e2e" + "467036247532302461732475323024636f72652e2e6f70732e2e61726974" + "682e2e4d756c24475424336d756c31376865613934393735323931313764" + "3166634535305f5a4e39626c7331325f3338313366703633467036367371" + "756172653137683866633831663539663666313530643145363c5f5a4e39" + "626c7331325f333831336670363346703631376d756c5f62795f6e6f6e72" + "6573696475653137686432663865613131393236643732653945375a5f5a" + "4e36315f244c5424626c7331325f3338312e2e6670362e2e467036247532" + "302461732475323024636f72652e2e6f70732e2e61726974682e2e537562" + "24475424337375623137686137396663636566323762323631323445382b" + "5f5a4e39626c7331325f3338313266703246703373756231376865646439" + "32336439323032346633366445392b5f5a4e39626c7331325f3338313266" + "703246703361646431376863366562626430363731666432643965453a30" + "5f5a4e39626c7331325f3338313366703233467032367371756172653137" + "6865663238666434623836356230653732453b2d5f5a4e39626c7331325f" + "333831336670323346703233737562313768636330663365343532313765" + "61393964453c2d5f5a4e39626c7331325f33383133667032334670323361" + "646431376864363030363832376137333934646563453d2e5f5a4e39626c" + "7331325f3338313266703246703673717561726531376835616337663530" + "666666393136623065453e605f5a4e36375f244c542424524624626c7331" + "325f3338312e2e667031322e2e4670313224753230246173247532302463" + "6f72652e2e6f70732e2e61726974682e2e4d756c24475424336d756c3137" + "6863613137343239383666636366353565453f6a5f5a4e36395f244c5424" + "626c7331325f3338312e2e667031322e2e46703132247532302461732475" + "323024636f72652e2e6f70732e2e61726974682e2e4d756c41737369676e" + "2447542431306d756c5f61737369676e3137683037326534616130343436" + "63356334314540655f5a4e39626c7331325f3338313870616972696e6773" + "31364d696c6c65724c6f6f70526573756c74323066696e616c5f6578706f" + "6e656e74696174696f6e31376379636c6f746f6d69635f73717561726531" + "3768613463633461633966316338323538644541635f5a4e39626c733132" + "5f3338313870616972696e677331364d696c6c65724c6f6f70526573756c" + "74323066696e616c5f6578706f6e656e74696174696f6e31356379636f6c" + "6f746f6d69635f6578703137686166636437313637356662666432373645" + "425d5f5a4e36325f244c5424626c7331325f3338312e2e6670322e2e4670" + "32247532302461732475323024737562746c652e2e436f6e7374616e7454" + "696d654571244754243563745f6571313768316264323735363036643361" + "6461366445435a5f5a4e36315f244c5424626c7331325f3338312e2e6670" + "362e2e467036247532302461732475323024636f72652e2e6f70732e2e61" + "726974682e2e416464244754243361646431376835343330336164316564" + "646333613837454491015f5a4e3131345f244c5424636f72652e2e697465" + "722e2e61646170746572732e2e666c617474656e2e2e466c61744d617024" + "4c542449244324552443244624475424247532302461732475323024636f" + "72652e2e697465722e2e7472616974732e2e6974657261746f722e2e4974" + "657261746f7224475424346e657874313768633964373737363930666232" + "373033334545385f5a4e34636f7265336f70733866756e6374696f6e3546" + "6e4d75743863616c6c5f6d75743137686638313366653737616237633761" + "35634546395f5a4e39626c7331325f3338313267313132473150726f6a65" + "637469766536646f75626c65313768386366636435343461313633326664" + "384547365f5a4e39626c7331325f3338313267313132473150726f6a6563" + "74697665336164643137686338666437656633383137383263636145487c" + "5f5a4e37395f244c5424626c7331325f3338312e2e67312e2e473150726f" + "6a656374697665247532302461732475323024737562746c652e2e436f6e" + "646974696f6e616c6c7953656c65637461626c65244754243138636f6e64" + "6974696f6e616c5f73656c65637431376839346663383463303336386533" + "3262334549415f5a4e38646c6d616c6c6f6338646c6d616c6c6f63313744" + "6c6d616c6c6f63244c542441244754243466726565313768623937643238" + "61316165313165356635454a2c5f5a4e34636f72653970616e69636b696e" + "673570616e696331376832323065356136376635653365303666454b0e5f" + "5f727573745f7265616c6c6f634c4a5f5a4e38646c6d616c6c6f6338646c" + "6d616c6c6f633137446c6d616c6c6f63244c542441244754243132756e6c" + "696e6b5f6368756e6b31376831623634356162376339333032303939454d" + "4b5f5a4e38646c6d616c6c6f6338646c6d616c6c6f633137446c6d616c6c" + "6f63244c542441244754243133646973706f73655f6368756e6b31376832" + "633732313930393066616265323362454e435f5a4e38646c6d616c6c6f63" + "38646c6d616c6c6f633137446c6d616c6c6f63244c54244124475424366d" + "616c6c6f6331376863663263663139323661376530646165454f385f5a4e" + "35616c6c6f63377261775f766563313763617061636974795f6f76657266" + "6c6f7731376863393936333961626361313337633131455085015f5a4e31" + "30325f244c5424636f72652e2e697465722e2e61646170746572732e2e6d" + "61702e2e4d6170244c542449244324462447542424753230246173247532" + "3024636f72652e2e697465722e2e7472616974732e2e6974657261746f72" + "2e2e4974657261746f7224475424346e6578743137683161356136633566" + "303263666237373445514d5f5a4e34365f244c5424753634247532302461" + "732475323024737562746c652e2e436f6e7374616e7454696d6545712447" + "54243563745f657131376839613065366130383065643661303532455253" + "5f5a4e35345f244c5424737562746c652e2e43686f696365247532302461" + "732475323024636f72652e2e6f70732e2e6269742e2e4e6f742447542433" + "6e6f743137686532353261643837343163616538663445533b5f5a4e3463" + "6f72653970616e69636b696e6731396173736572745f6661696c65645f69" + "6e6e6572313768363939386636356530343630623966324554475f5a4e34" + "325f244c54242452462454247532302461732475323024636f72652e2e66" + "6d742e2e44656275672447542433666d7431376866396562386538303434" + "3436393737334555385f5a4e34636f726533666d7439466f726d61747465" + "7231327061645f696e74656772616c313768336538303336383966363939" + "303466334556335f5a4e39626c7331325f33383132667032467031307375" + "6274726163745f7031376833353337643137643839306564373430455736" + "5f5a4e35616c6c6f6335616c6c6f6336476c6f62616c3130616c6c6f635f" + "696d706c313768636263383565313966363066396565314558435f5a4e35" + "616c6c6f63377261775f7665633139526177566563244c54245424432441" + "244754243867726f775f6f6e653137683761366133613131343862316565" + "66624559785f5a4e37355f244c5424626c7331325f3338312e2e67322e2e" + "4732416666696e65247532302461732475323024737562746c652e2e436f" + "6e646974696f6e616c6c7953656c65637461626c65244754243138636f6e" + "646974696f6e616c5f73656c656374313768346631633532376163323663" + "39393332455a7a5f5a4e37375f244c5424737562746c652e2e43744f7074" + "696f6e244c54245424475424247532302461732475323024737562746c65" + "2e2e436f6e646974696f6e616c6c7953656c65637461626c652447542431" + "38636f6e646974696f6e616c5f73656c6563743137686230353564346638" + "6331363261313862455b5b5f5a4e36305f244c5424626c7331325f333831" + "2e2e66702e2e4670247532302461732475323024737562746c652e2e436f" + "6e7374616e7454696d654571244754243563745f65713137683764613737" + "3038613961336631623237455c335f5a4e39626c7331325f333831326670" + "324670313066726f6d5f6279746573313768663632643265653863383835" + "61616633455d665f5a4e36355f244c5424626c7331325f3338312e2e6670" + "2e2e4670247532302461732475323024636f72652e2e6f70732e2e617269" + "74682e2e4d756c41737369676e2447542431306d756c5f61737369676e31" + "376862613864393933386331336334313962455e425f5a4e39626c733132" + "5f33383132667032467032356c657869636f67726170686963616c6c795f" + "6c61726765737431376864623239383362653765626662373630455f345f" + "5a4e39626c7331325f3338313266703246703131706f775f76617274696d" + "65313768386339643861353637336531663765654560315f5a4e39626c73" + "31325f33383133667032334670323769735f7a65726f3137683232633162" + "33626231383039373337664561385f5a4e39626c7331325f333831326670" + "324670313573756d5f6f665f70726f647563747331376864373831613962" + "66366162336638386645622d5f5a4e39626c7331325f3338313366703233" + "467032336e6567313768336535623432323139303537623839334563365f" + "5a4e39626c7331325f33383133667032334670323131706f775f76617274" + "696d653137683839356266623030643732663461646145643b5f5a4e3962" + "6c7331325f3338313267313132473150726f6a656374697665386d756c5f" + "62795f78313768313830336335636330383333313036354565665f5a4e37" + "335f244c542424524624626c7331325f3338312e2e67312e2e473150726f" + "6a656374697665247532302461732475323024636f72652e2e6f70732e2e" + "61726974682e2e4e656724475424336e6567313768363961333962383136" + "613036626237614566455f5a4e34636f7265346974657238616461707465" + "727337666c617474656e3137616e645f7468656e5f6f725f636c65617231" + "3768373932316661373530366638613637624567365f5a4e39626c733132" + "5f333831326732384732416666696e65386964656e746974793137683532" + "3261303037353662633832613639456885015f5a4e3130325f244c542462" + "6c7331325f3338312e2e67322e2e473250726f6a65637469766524753230" + "2461732475323024636f72652e2e636f6e766572742e2e46726f6d244c54" + "2424524624626c7331325f3338312e2e67322e2e4732416666696e652447" + "5424244754243466726f6d31376831393034396666373534383632623533" + "4569335f5a4e39626c7331325f3338313366703633467036396d756c5f62" + "795f303131376837316231356266356135313961376133456a385f5a4e39" + "626c7331325f333831326670324670313573756d5f6f665f70726f647563" + "747331376862306665663033383436356461336561456b5e5f5a4e39626c" + "7331325f3338313870616972696e677331364d696c6c65724c6f6f705265" + "73756c74323066696e616c5f6578706f6e656e74696174696f6e31306670" + "345f73717561726531376835333530613232303537323261303037456c68" + "5f5a4e36375f244c5424626c7331325f3338312e2e6670322e2e46703224" + "7532302461732475323024636f72652e2e6f70732e2e61726974682e2e53" + "756241737369676e2447542431307375625f61737369676e313768656138" + "64663864303262303833343633456dd5015f5a4e3137325f244c5424244c" + "5424626c7331325f3338312e2e70616972696e67732e2e47325072657061" + "726564247532302461732475323024636f72652e2e636f6e766572742e2e" + "46726f6d244c5424626c7331325f3338312e2e67322e2e4732416666696e" + "6524475424244754242e2e66726f6d2e2e41646465722475323024617324" + "75323024626c7331325f3338312e2e70616972696e67732e2e4d696c6c65" + "724c6f6f70447269766572244754243133646f75626c696e675f73746570" + "31376833303230646632373566636537643064456e385f5a4e35616c6c6f" + "63337665633136566563244c542454244324412447542434707573683137" + "6836633466633030383766393064366561456f355f5a4e34636f72653970" + "616e69636b696e6731336173736572745f6661696c656431376838396134" + "30623862613963643736636345703a5f5a4e34636f72653970616e69636b" + "696e67313870616e69635f626f756e64735f636865636b31376835613339" + "3334316633393435306165354571625f5a4e34636f726533666d74336e75" + "6d33696d7035325f244c5424696d706c2475323024636f72652e2e666d74" + "2e2e446973706c61792475323024666f7224753230247533322447542433" + "666d74313768646131373032323936653330396138624572445f5a4e3463" + "6f726533666d74336e756d33696d7032315f244c5424696d706c24753230" + "2475333224475424345f666d743137686531613333633761616434313031" + "3465457311727573745f626567696e5f756e77696e6474465f5a4e34636f" + "726533666d7439466f726d617474657231327061645f696e74656772616c" + "313277726974655f70726566697831376865323164633232613535336139" + "3935324575535f5a4e34636f726535736c69636535696e6465783234736c" + "6963655f656e645f696e6465785f6c656e5f6661696c38646f5f70616e69" + "633772756e74696d65313768623465303239633465666136373431314576" + "475f5a4e34325f244c54242452462454247532302461732475323024636f" + "72652e2e666d742e2e44656275672447542433666d743137683763663234" + "64633163663734653663354577495f5a4e34345f244c5424245246245424" + "7532302461732475323024636f72652e2e666d742e2e446973706c617924" + "47542433666d74313768363963313766643162653433346236384578585f" + "5a4e35395f244c5424636f72652e2e666d742e2e417267756d656e747324" + "7532302461732475323024636f72652e2e666d742e2e446973706c617924" + "47542433666d74313768356530663632333530333933336330664579265f" + "5a4e34636f726533666d7435777269746531376862633530306361396130" + "663033323632457a695f5a4e36385f244c5424636f72652e2e666d742e2e" + "6275696c646572732e2e5061644164617074657224753230246173247532" + "3024636f72652e2e666d742e2e577269746524475424313077726974655f" + "6368617231376837323761393336343062616631636662457b305f5a4e34" + "636f726533666d743557726974653977726974655f666d74313768653264" + "32326663306535326231396336457c515f5a4e34636f726535736c696365" + "35696e6465783232736c6963655f696e6465785f6f726465725f6661696c" + "38646f5f70616e69633772756e74696d6531376836346563303433376262" + "666263656363457d475f5a4e34325f244c54242452462454247532302461" + "732475323024636f72652e2e666d742e2e44656275672447542433666d74" + "31376837396432393730376137363931633337457e375f5a4e34636f7265" + "3570616e6963313250616e69635061796c6f61643661735f737472313768" + "33653762626665396537333233373036457f3b5f5a4e337374643970616e" + "69636b696e673230727573745f70616e69635f776974685f686f6f6b3137" + "68396561303139313462356439323635394580010a727573745f70616e69" + "638101455f5a4e3373746433737973396261636b747261636532365f5f72" + "7573745f656e645f73686f72745f6261636b747261636531376865376239" + "323038656534343338376436458201585f5a4e337374643970616e69636b" + "696e673139626567696e5f70616e69635f68616e646c657232385f247537" + "62242475376224636c6f7375726524753764242475376424313768393666" + "3161333534313164393334366245830183015f5a4e39395f244c54247374" + "642e2e70616e69636b696e672e2e626567696e5f70616e69635f68616e64" + "6c65722e2e5374617469635374725061796c6f6164247532302461732475" + "323024636f72652e2e70616e69632e2e50616e69635061796c6f61642447" + "54243661735f737472313768653362376630636337353061633833394584" + "01505f5a4e38646c6d616c6c6f6338646c6d616c6c6f633137446c6d616c" + "6c6f63244c542441244754243138696e736572745f6c617267655f636875" + "6e6b31376866646432333135363766663933346634458501066d656d7365" + "748601066d656d6370798701085f5f6d756c7469338801365f5a4e313763" + "6f6d70696c65725f6275696c74696e73336d656d376d656d6d6f76653137" + "6830343030366431613866396435653532458901076d656d6d6f76650712" + "01000f5f5f737461636b5f706f696e746572090a0100072e726f64617461" + "004d0970726f64756365727302086c616e6775616765010452757374000c" + "70726f6365737365642d6279010572757374631d312e38352e3120283465" + "6231363132353020323032352d30332d31352900490f7461726765745f66" + "65617475726573042b0a6d756c746976616c75652b0f6d757461626c652d" + "676c6f62616c732b0f7265666572656e63652d74797065732b087369676e" + "2d657874"; + +extern std::string const sp1WasmHex = + "0061736d0100000001630f60027f7f0060037f7f7f0060027f7f017f6003" + "7f7f7f017f60017f0060047f7f7f7f0060017f017f60057f7f7f7f7f0060" + "047f7f7f7f017f6000017f60077f7e7e7e7e7e7e0060000060097f7e7e7e" + "7e7e7e7e7e0060037f7e7e0060047f7e7e7f000351500906010004010001" + "000000060100000001010107040800000000000102080202040101000505" + "00010502000a0b0c00010100000100000401040000010100000101000200" + "0100000107010202030d0e000405017001080805030100110619037f0141" + "8080c0000b7f0041b0abc0000b7f0041b0abc0000b073c04066d656d6f72" + "790200147370315f67726f746831365f766572696669657200000a5f5f64" + "6174615f656e6403010b5f5f686561705f626173650302090d010041010b" + "071c1f1e323429420a81c10950add60202537f2d7e230041c0206b220124" + "0041e8a5c0002d0000410247044041e8a5c00041e8a5c0002d0000220541" + "0120051b3a00000240200504400340024002400240200541016b0e030005" + "01020b034041e8a5c0002d000022054101460d000b02400240200541016b" + "0e03000601030b000b41a49bc000412641cc9bc0001011000b41a89ac000" + "410d41949bc0001011000b41e8a5c00041e8a5c0002d0000220541012005" + "1b3a000020050d000b0b41e8a5c00041023a000041e4a5c000418c033602" + "0041e0a5c00041e892c0003602000b0b41bda9c0002d00001a41e4a5c000" + "280200211241e0a5c000280200211f024002400240024002400240024002" + "400240024002400240024002400240024002400240024002400240024002" + "400240024002404184021001220a450d00200a41c1befe827c3600800220" + "0a42e5979c9b97e3c7eb897f3700f801200a42cbb091f7e585f1e3d30037" + "00f001200a4285cca8c2988cc0acd0003700e801200a42c29391f580c1f3" + "da093700e001200a42d1f9cfc9da8dc8bcb37f3700d801200a42c1a5a5db" + "99d68fcfc8003700d001200a42a4e6aeaa96968ae30c3700c801200a42bb" + "86f4fee5c1aa8eab7f3700c001200a42ecff83a2ceee9ae7173700b80120" + "0a429fc5d69be5fafb80763700b001200a42bcd1e08deea2cfa58b7f3700" + "a801200a42aeb3eac1cda3e3c0bf7f3700a001200a42e2d8abdbae8cd3ae" + "5c37009801200a42eafbbf9fa891deb20437009001200a42afd29dfa8281" + "ecce9f7f37008801200a42b799d9dcb883f8df3b37008001200a42b3c1c2" + "a8e0a2cbc0cc00370078200a4295af8cdda2f981d269370070200a42f4eb" + "86b4cfc69bc339370068200a42f8e5b7c0c1e199bff000370060200a42c1" + "e7c485b4aac3c28c7f370058200a42f3e7ec98bff992d83b370050200a42" + "e880deac81addbc8967f370048200a4288c5f6c6eba0ef9844370040200a" + "42bdb2cf80ada892e5ec00370038200a42f887b4d9f0accbdb4c37003020" + "0a42e1c6ffa3c2dec48dcb00370028200a42fc81d7948085c1fc2c370020" + "200a42f79d8ff3bcb283ece500370018200a42beb6d5a58deadbe2d90037" + "0010200a4291c09b97b2989bf3b97f370008200a4291ec82edf9a3afba48" + "37000041bda9c0002d00001a41e0001001221d450d00201d420037000020" + "1d4200370020201d41053a001f201d4200370040201d41053a003f201d41" + "083a005f201d41176a4200370000201d41106a4200370000201d41086a42" + "00370000201d41286a4200370000201d41306a4200370000201d41376a42" + "00370000201d41c8006a4200370000201d41d0006a4200370000201d41d7" + "006a420037000041bda9c0002d00001a41c20010012205450d0020054180" + "80c00041c200104c2152200141a00f6a201f20121002024020012802a00f" + "200a280000470d002001418280c4003602e01c2001410036029c03200142" + "c080808020370294032001205241026a360290032001200141e01c6a3602" + "a003200141106a20014190036a100320012d0010044020012d0011210502" + "4020012802a003280200418280c400470d00200128029403450d00200128" + "029803450d040b41bda9c0002d00001a410810012202450d02200141d000" + "6a2116200a41e4016a2109200a41c4016a2122200a41a4016a2120200220" + "053a0000200141013602a80c200120023602a40c200141083602a00c2001" + "41b00f6a200141a0036a280200360200200141a80f6a20014198036a2902" + "0037030020012001290290033703a00f4101210503400240200141086a20" + "0141a00f6a100320012d0008450d0020012d0009210620012802a00c2005" + "460440024020012802b00f280200418280c400470d0020012802a40f450d" + "0020012802a80f450d070b230041206b220f240002404108200141a00c6a" + "220e280200220c4101742208200541016a220220022008491b2202200241" + "084d1b220241004e047f200f200c047f200f200c36021c200f200e280204" + "36021441010541000b360218200f41086a41012002200f41146a1028200f" + "2802084101470d01200f2802101a200f28020c0541000b41c096c0001019" + "000b200f28020c210c200e2002360200200e200c360204200f41206a2400" + "20012802a40c21020b200220056a20063a00002001200541016a22053602" + "a80c0c010b0b20012802a00c210220012802a40c210620012802e01c4182" + "80c4004704402002450d02200641046b2802002205417871221241044108" + "200541037122051b20026a490d05200541002012200241276a4b1b0d0620" + "0610040c020b2002418080808078460d0102400240024002402005412046" + "0440200141a80f6a2205200641176a290000370300200141b00f6a222320" + "06411f6a2d00003a00002001200629000f3703a00f200628000b21242006" + "28000721262006280003213520062d0002212d20062d0001214720062d00" + "00214820020440200641046b2802002208417871220c4104410820084103" + "7122081b20026a490d0c20084100200c200241276a4b1b0d0d200610040b" + "200141206a22062005290300370300200141286a220520232d00003a0000" + "200120012903a00f370318200141f0006a201d41e0001002200141c7006a" + "2006290300370000200141cf006a20052d00003a0000201641086a200141" + "f8006a290000370000201641106a20014180016a29000037000020164118" + "6a20014188016a290000370000200120012d0070411f713a007020162001" + "2900703700002001202436003b2001202636003720012035360033200120" + "2d3a0032200120473a0031200120483a00302001200129031837003f200a" + "290014225742388620574280fe0383422886842057428080fc0783421886" + "205742808080f80f834208868484205742088842808080f80f8320574218" + "88428080fc07838420574228884280fe03832057423888848484215e200a" + "411c6a290000225742388620574280fe0383422886842057428080fc0783" + "421886205742808080f80f834208868484205742088842808080f80f8320" + "57421888428080fc07838420574228884280fe0383205742388884848421" + "65417f200a290004225742b0c8b99297bc8cd02985200a410c6a29000022" + "5842b8a195b29bb0a0acdd008584420052205842388620584280fe038342" + "2886842058428080fc0783421886205842808080f80f8342088684842058" + "42088842808080f80f832058421888428080fc07838420584228884280fe" + "03832058423888848484225842ddb0858ce8b691a8b87f54205742388620" + "574280fe0383422886842057428080fc0783421886205742808080f80f83" + "4208868484205742088842808080f80f832057421888428080fc07838420" + "574228884280fe03832057423888848484225742a9c0c689aece93b23054" + "205742a9c0c689aece93b230511b1b2205417f470440200541ff01710d07" + "206542c6faf3c3ed82a3903c56205e428d95c7c396d2dac0977f56205e42" + "8d95c7c396d2dac0977f511b0d070b200120583703b018200120653703a0" + "18200120573703b8182001205e3703a818200a2900342257423886205742" + "80fe0383422886842057428080fc0783421886205742808080f80f834208" + "868484205742088842808080f80f832057421888428080fc078384205742" + "28884280fe03832057423888848484215e200a413c6a2900002257423886" + "20574280fe0383422886842057428080fc0783421886205742808080f80f" + "834208868484205742088842808080f80f832057421888428080fc078384" + "20574228884280fe038320574238888484842165417f200a290024225742" + "b0c8b99297bc8cd02985200a412c6a290000225842b8a195b29bb0a0acdd" + "008584420052205842388620584280fe0383422886842058428080fc0783" + "421886205842808080f80f834208868484205842088842808080f80f8320" + "58421888428080fc07838420584228884280fe0383205842388884848422" + "5842ddb0858ce8b691a8b87f54205742388620574280fe03834228868420" + "57428080fc0783421886205742808080f80f834208868484205742088842" + "808080f80f832057421888428080fc07838420574228884280fe03832057" + "423888848484225742a9c0c689aece93b23054205742a9c0c689aece93b2" + "30511b1b2205417f470440200541ff01710d07206542c6faf3c3ed82a390" + "3c56205e428d95c7c396d2dac0977f56205e428d95c7c396d2dac0977f51" + "1b0d070b200120583703d01a200120653703c01a200120573703d81a2001" + "205e3703c81a200141e0066a200141a0186a200141c01a6a100520012d00" + "e0060d06200141e50c6a2205200141a8076a290300370000200141dd0c6a" + "2206200141a0076a290300370000200141d50c6a220220014198076a2903" + "00370000200141cd0c6a222320014190076a290300370000200141c50c6a" + "222420014188076a290300370000200141bd0c6a222620014180076a2903" + "00370000200141b50c6a2235200141f8066a290300370000200120012903" + "f0063700ad0c200141a51d6a222d20052900003700002001419d1d6a2205" + "2006290000370000200141951d6a220620022900003700002001418d1d6a" + "22022023290000370000200141851d6a22232024290000370000200141fd" + "1c6a22242026290000370000200141f51c6a222620352900003700002001" + "20012900ad0c3700ed1c200141d80a6a202d290000370300200141d00a6a" + "2005290000370300200141c80a6a2006290000370300200141c00a6a2002" + "290000370300200141b80a6a2023290000370300200141b00a6a20242900" + "00370300200120262900003703a80a200120012900ed1c3703a00a200a29" + "0054225742388620574280fe0383422886842057428080fc078342188620" + "5742808080f80f834208868484205742088842808080f80f832057421888" + "428080fc07838420574228884280fe038320574238888484842165200a41" + "dc006a290000225742388620574280fe0383422886842057428080fc0783" + "421886205742808080f80f834208868484205742088842808080f80f8320" + "57421888428080fc07838420574228884280fe0383205742388884848421" + "6a417f200a290044225742b0c8b99297bc8cd02985200a41cc006a290000" + "225842b8a195b29bb0a0acdd008584420052205842388620584280fe0383" + "422886842058428080fc0783421886205842808080f80f83420886848420" + "5842088842808080f80f832058421888428080fc07838420584228884280" + "fe03832058423888848484226242ddb0858ce8b691a8b87f542057423886" + "20574280fe0383422886842057428080fc0783421886205742808080f80f" + "834208868484205742088842808080f80f832057421888428080fc078384" + "20574228884280fe03832057423888848484225e42a9c0c689aece93b230" + "54205e42a9c0c689aece93b230511b1b2205417f470440200541ff01710d" + "07206a42c6faf3c3ed82a3903c562065428d95c7c396d2dac0977f562065" + "428d95c7c396d2dac0977f511b0d070b200a290074225742388620574280" + "fe0383422886842057428080fc0783421886205742808080f80f83420886" + "8484205742088842808080f80f832057421888428080fc07838420574228" + "884280fe03832057423888848484215a200a41fc006a2900002257423886" + "20574280fe0383422886842057428080fc0783421886205742808080f80f" + "834208868484205742088842808080f80f832057421888428080fc078384" + "20574228884280fe03832057423888848484215c417f200a290064225742" + "b0c8b99297bc8cd02985200a41ec006a290000225842b8a195b29bb0a0ac" + "dd008584420052205842388620584280fe0383422886842058428080fc07" + "83421886205842808080f80f834208868484205842088842808080f80f83" + "2058421888428080fc07838420584228884280fe03832058423888848484" + "225942ddb0858ce8b691a8b87f54205742388620574280fe038342288684" + "2057428080fc0783421886205742808080f80f8342088684842057420888" + "42808080f80f832057421888428080fc07838420574228884280fe038320" + "57423888848484225442a9c0c689aece93b23054205442a9c0c689aece93" + "b230511b1b2205417f470440200541ff01710d07205c42c6faf3c3ed82a3" + "903c56205a428d95c7c396d2dac0977f56205a428d95c7c396d2dac0977f" + "511b0d070b200a29009401225742388620574280fe038342288684205742" + "8080fc0783421886205742808080f80f8342088684842057420888428080" + "80f80f832057421888428080fc07838420574228884280fe038320574238" + "88848484215b200a419c016a290000225742388620574280fe0383422886" + "842057428080fc0783421886205742808080f80f83420886848420574208" + "8842808080f80f832057421888428080fc07838420574228884280fe0383" + "20574238888484842161417f200a29008401225742b0c8b99297bc8cd029" + "85200a418c016a290000225842b8a195b29bb0a0acdd0085844200522058" + "42388620584280fe0383422886842058428080fc07834218862058428080" + "80f80f834208868484205842088842808080f80f832058421888428080fc" + "07838420584228884280fe03832058423888848484225842ddb0858ce8b6" + "91a8b87f54205742388620574280fe0383422886842057428080fc078342" + "1886205742808080f80f834208868484205742088842808080f80f832057" + "421888428080fc07838420574228884280fe038320574238888484842257" + "42a9c0c689aece93b23054205742a9c0c689aece93b230511b1b2205417f" + "470440200541ff01710d07206142c6faf3c3ed82a3903c56205b428d95c7" + "c396d2dac0977f56205b428d95c7c396d2dac0977f511b0d070b200141e0" + "066a2020100620012d00e0060d06200141f51c6a200141f8066a29030022" + "53370000200141b80b6a20014188076a290300370300200141b00b6a2001" + "4180076a290300370300200120012903f0063703a00b200120533703a80b" + "200120623703900b2001206a3703800b200120593703f00a2001205c3703" + "e00a2001205e3703980b200120653703880b200120543703f80a2001205a" + "3703e80a200120573703d80b200120583703d00b2001205b3703c80b2001" + "20613703c00b200141e0066a200141e00a6a200141a00b6a100720012d00" + "e0060d06200141801f6a200141ad186a200141cd1a6a200141ee1c6a2001" + "41ae0c6a200141f0066a418001104c418001104c418001104c418001104c" + "418001104c1a200141e0066a2022100620012d00e0060d06200141b5186a" + "2205200141f8066a22062903002257370000200141f80a6a20014188076a" + "2202290300370300200141f00a6a20014180076a22202903003703002001" + "20012903f0063703e00a200120573703e80a200141e0066a200910062001" + "2d00e0060d06200520062903002257370000200141b80b6a200229030037" + "0300200141b00b6a2020290300370300200120012903f0063703a00b2001" + "20573703a80b200141e0066a200141e00a6a200141a00b6a100520012d00" + "e0060d06200141e50c6a2205200141a8076a290300370000200141dd0c6a" + "2206200141a0076a290300370000200141d50c6a220220014198076a2903" + "00370000200141cd0c6a222020014190076a290300370000200141c50c6a" + "222220014188076a290300370000200141bd0c6a220920014180076a2903" + "00370000200141b50c6a2223200141f8066a290300370000200120012903" + "f0063700ad0c200141a51d6a222420052900003700002001419d1d6a2205" + "2006290000370000200141951d6a220620022900003700002001418d1d6a" + "22022020290000370000200141851d6a22202022290000370000200141fd" + "1c6a22222009290000370000200141f51c6a220920232900003700002001" + "20012900ad0c3700ed1c200141d8086a2024290000370300200141d0086a" + "2005290000370300200141c8086a2006290000370300200141c0086a2002" + "290000370300200141b8086a2020290000370300200141b0086a20222900" + "00370300200141a8086a2009290000370300200120012900ed1c3703a008" + "200141e8076a20012903a80a370300200141f0076a200141b00a6a290300" + "370300200141f8076a200141b80a6a29030037030020014180086a200141" + "c00a6a29030037030020014188086a200141c80a6a290300370300200141" + "90086a200141d00a6a29030037030020014198086a200141d80a6a290300" + "370300200120012903a00a3703e007200141e0066a200141801f6a418001" + "104c1a20014190016a2001419d036a200141ad0f6a200141e0066a418002" + "104c418002104c418002104c1a2012411f4d0d0f200141a00f6a201f1008" + "20012d00a00f0d06200141e50c6a200141e80f6a29030022573700002001" + "41dd0c6a200141e00f6a2903002258370000200141d50c6a200141d80f6a" + "290300225e370000200141cd0c6a200141d00f6a29030022653700002001" + "41f00b6a200141c00f6a290300370300200141f80b6a200141c80f6a2903" + "00370300200141800c6a2065370300200141880c6a205e37030020014190" + "0c6a2058370300200141980c6a2057370300200120012903b00f3703e00b" + "2001200141b80f6a2903003703e80b201241ff004d0d10200141a00f6a20" + "1f41406b100920012d00a00f0d06200141a0186a200141ad0c6a200141b0" + "0f6a418001104c418001104c1a201241bf014d0d11200141a00f6a201f41" + "80016a100920012d00a00f0d06200141c01a6a200141ad0c6a200141b00f" + "6a418001104c418001104c1a2012419f024d0d12200141a00f6a201f41e0" + "016a100920012d00a00f0d06200141e01c6a200141ad0c6a200141b00f6a" + "418001104c418001104c1a201241a002460d13201241a102460d14201241" + "a2024d0d15201241a302460d16201f2d00a0022105201f2d00a102210620" + "1f2d00a3022102201f2d00a202212041002126200141003602a80b200142" + "8080808080023702a00b2005200641087472202041107472200241187472" + "220504404101200541187420054180fe03714108747220054108764180fe" + "0371200541187672722205200541014d1b210c200141ad0c6a2105200141" + "b00f6a210641a40221024100212241102108410021200340202041f6ffff" + "3f460d19200241206a220920124b0d1a200141a00f6a2002201f6a100820" + "012d00a00f0d0320052006290000370000200541386a2202200641386a29" + "0000370000200541306a2223200641306a290000370000200541286a2224" + "200641286a290000370000200541206a2226200641206a29000037000020" + "0541186a2235200641186a290000370000200541106a222d200641106a29" + "0000370000200541086a2247200641086a290000370000200141901f6a22" + "48202d290000370300200141981f6a222d2035290000370300200141a01f" + "6a22352026290000370300200141a81f6a22262024290000370300200141" + "b01f6a22242023290000370300200141b81f6a2223200229000037030020" + "0120052900003703801f200120472900003703881f20012802a00b202046" + "044041002108230041206b2203240002400240200141a00b6a221b280200" + "220f417f460d00200f4101742202200f41016a220e2002200e4b1b220241" + "ffffff1f4b0d0041042002200241044d1b2202410674220e41f0ffffff07" + "4b0d002003200f047f2003200f41067436021c2003201b28020436021441" + "100541000b360218200341086a4110200e200341146a1028200328020841" + "01470d0120032802101a200328020c21080b200841dc90c0001019000b20" + "0328020c210f201b2002360200201b200f360204200341206a2400200128" + "02a40b21080b200820226a220220012903801f370300200241386a202329" + "0300370300200241306a2024290300370300200241286a20262903003703" + "00200241206a2035290300370300200241186a202d290300370300200241" + "106a2048290300370300200241086a20012903881f370300200120204101" + "6a22203602a80b202241406b212220092102200c2020470d000b20012802" + "a00b21260b20012902a40b216a200141a00c6a200141a0186a100a200141" + "a00d6a200141e01c6a418001104c1a200141a00e6a200141c01a6a418001" + "104c1a200141d6126a200141980c6a290300370100200141ce126a200141" + "900c6a290300370100200141c6126a200141880c6a290300370100200141" + "be126a200141800c6a290300370100200141b6126a200141f80b6a290300" + "370100200141ae126a200141f00b6a290300370100200141a6126a200129" + "03e80b370100200120012903e00b37019e1220012d00a00c210520012d00" + "a10c2106200141a00f6a200141a00c6a41027241fe02104c1a200141e006" + "6a200141a00f6a41be03104c1a2026418080808078460d0620014190036a" + "410272200141e0066a41be03104c1a200120263602d006200120063a0091" + "03200120053a0090034100210241bda9c0002d00001a2001206a3702d406" + "41c000100b2220450d07206a4220882262a72122206aa72135200141b00f" + "6a2105200141306a2106410021120340230041206b22092400200941186a" + "221b2006290000225342388620534280fe0383422886842053428080fc07" + "83421886205342808080f80f834208868484205342088842808080f80f83" + "2053421888428080fc07838420534228884280fe03832053423888848484" + "370300200941106a2208200641086a290000225342388620534280fe0383" + "422886842053428080fc0783421886205342808080f80f83420886848420" + "5342088842808080f80f832053421888428080fc07838420534228884280" + "fe0383205342388884848437030020092006290010225342388620534280" + "fe0383422886842053428080fc0783421886205342808080f80f83420886" + "8484205342088842808080f80f832053421888428080fc07838420534228" + "884280fe038320534238888484843703082009200641186a290000225342" + "388620534280fe0383422886842053428080fc0783421886205342808080" + "f80f834208868484205342088842808080f80f832053421888428080fc07" + "838420534228884280fe0383205342388884848437030020094201420042" + "0042004281808080bfb2fdf0c3004291e1e5cd8789fa9928102b200141a0" + "0f6a220c41003a0000200c41286a201b290300370300200c41206a200829" + "0300370300200c41186a2009290308370300200c20092903003703102009" + "41206a240020012d00a00f4101460d1a200141f8066a200541186a290300" + "2257370300200141f0066a200541106a2903002258370300200120052903" + "00225e3703e0062001200541086a29030022653703e80620202012410574" + "6a220641186a2057370300200641106a2058370300200641086a20653703" + "002006205e370300410121122002410171211f4101210220162106201f45" + "0d000b206a42ffffffffffffffff03560d1a2022410674220541f1ffffff" + "074f0d1a2005450d0341bda9c0002d00001a2005100b2206450d07200620" + "352005104c211220624203520d02206a428080808010540d042001419006" + "6a212d20014190056a214720014190046a2148200141f81a6a221f201241" + "386a290300370300200141f01a6a2216201241306a290300370300200141" + "e81a6a2222201241286a290300370300200141e01a6a2209201241206a29" + "0300370300200141d81a6a2223201241186a290300370300200141d01a6a" + "2224201241106a290300370300200120122903003703c01a200120124108" + "6a2903003703c81a2020210541c00021060340200141d80c6a201f290300" + "370300200141d00c6a2016290300370300200141c80c6a20222903003703" + "00200141c00c6a2009290300370300200141b80c6a202329030037030020" + "0141b00c6a2024290300370300200120012903c81a3703a80c2001200129" + "03c01a3703a00c200120053602e00c2001200620126a22023602e40c2001" + "41e01c6a21312002210c4100212e41002136230041a0046b220424002004" + "41306a212b20044180036a2137200441e0036a210f200441f0016a210e20" + "0441c0026a211b200441e0026a2108200441b0026a2149200441d0026a21" + "4a41ff012141034002402004204141ff0071104f2005204141037641f0ff" + "ffff01716a22422903002004290300832159204241086a29030020044108" + "6a29030083215302400240027f0240024002400240024020364101714504" + "4041002053205984500d061a200441e0006a200441206a29030037030020" + "0441e8006a200441286a290300370300200441f0006a202b290300370300" + "200441f8006a200441386a29030037030020044180016a200441406b2903" + "0037030020044188016a200441c8006a2903003703002004200429031037" + "035020042004290318370358202e0d010c030b202e450d0120044188026a" + "200441c8006a222e29030037030020044180026a200441406b2250290300" + "370300200441f8016a200441386a2203290300370300200e202b29030037" + "0300200441e8016a200441286a2236290300370300200441e0016a200441" + "206a2242290300370300200420042903183703d801200420042903103703" + "d001200441d8036a224b4200370300200441d0036a220242003703002004" + "42003703f803200442003703f003200442003703e803200442013703e003" + "200442003703c803200442003703c003024002400240200441d0016a2004" + "41c0036a104a450440200e200f104a450d010b204b420037030020024200" + "370300200442003703f803200442003703f003200442003703e803200442" + "013703e003200442003703c803200442003703c003027f0240200441d001" + "6a200441c0036a104a450440200e200f104a450d010b2049202b29030037" + "0300204941186a202b41186a290300370300204941106a202b41106a2903" + "00370300204941086a202b41086a290300370300200441a0026a20422903" + "00370300200441a8026a2036290300370300200420042903103703900220" + "0420042903183703980220082102204a0c010b204a4200370300200441a0" + "026a4200370300200441a8026a4200370300204a41086a4200370300204a" + "41106a4200370300204a41186a4200370300200442003703900220044200" + "37039802201b210220490b214b2002420037030820024200370300204b42" + "00370308204b4201370300200441c0036a20044190026a20044190026a10" + "40200441f0026a200441c0036a104120042802f002410171450d01200441" + "c8016a203741386a290300370300200441c0016a203741306a2903003703" + "00200441b8016a203741286a290300370300200441b0016a203741206a29" + "0300370300200441a8016a203741186a290300370300200441a0016a2037" + "41106a29030037030020042037290300370390012004203741086a290300" + "370398010c020b200441a0016a2042290300370300200441a8016a203629" + "0300370300200441b0016a202b290300370300200441b8016a2003290300" + "370300200441c0016a2050290300370300200441c8016a202e2903003703" + "00200420042903103703900120042004290318370398010c010b41c4a0c0" + "00412041e4a0c0001021000b2042200441a0016a29030037030020362004" + "41a8016a290300370300202b200441b0016a2903003703002003200441b8" + "016a2903003703002050200441c0016a290300370300202e200441c8016a" + "290300370300200420042903900137031020042004290398013703182053" + "205984500d04200441e0006a2042290300370300200441e8006a20362903" + "00370300200441f0006a202b290300370300200441f8006a200329030037" + "030020044180016a205029030037030020044188016a202e290300370300" + "20042004290310370350200420042903183703580b200441c0036a200441" + "d0006a200c100c0c020b20532059844200520d002041450d044101213641" + "00212e0c050b200441f8036a200c41386a290300370300200441f0036a20" + "0c41306a290300370300200441e8036a200c41286a290300370300200f20" + "0c41206a290300370300200441d8036a200c41186a290300370300200441" + "d0036a200c41106a2903003703002004200c2903003703c0032004200c41" + "086a2903003703c8030b200441c8006a200441f8036a2903003703002004" + "41406b200441f0036a290300370300200441386a200441e8036a29030037" + "0300202b200f290300370300200441286a200441d8036a29030037030020" + "0441206a200441d0036a290300370300200420042903c803370318200420" + "042903c0033703100b4101212e41010b213620410d01202e0d020b4184a1" + "c0001020000b204141016b21410c010b0b20312004290310370300203141" + "086a2004290318370300203141386a200441c8006a290300370300203141" + "306a200441406b290300370300203141286a200441386a29030037030020" + "3141206a200441306a290300370300203141186a200441286a2903003703" + "00203141106a200441206a290300370300200441a0046a2400200541206a" + "2105200141c01a6a200141a00c6a200141e01c6a100c200641406b220641" + "c001470d000b200141b00f6a2205200141c01a6a100d201241c001100e20" + "0141c01a6a200141ed066a200541e000104c41e000104c1a200141e0066a" + "20014190026a100d200141a0186a21024200215c42002154420021532001" + "41e0066a220541386a2903002161200541286a290300215b200529033021" + "592005290320215e027e200529034022652005290350226a84200541c800" + "6a2903002262200541d8006a290300225a84845004402059215c20612154" + "205b2153205e0c010b42002059205e84205b20618484500d001a427f4200" + "427f4200205e42788342c7faf3c3ed82a3903c561b225c205b205c56ad7d" + "205c205b7d225b42f3eab8bce9ada5bfe8007d2253205b54ad7c42017c22" + "5b20597d225442a4cffaf397c9eed7c7007d225c205454ad2059205b56ad" + "7d427f511b20617d42a9c0c689aece93b2307c215442c7faf3c3ed82a390" + "3c205e7d0b21612002206a370350200220653703402002205c3703302002" + "20613703202002205a370358200220623703482002205437033820022053" + "37032820022005290300370300200241186a200541186a29030037030020" + "0241106a200541106a290300370300200241086a200541086a2903003703" + "0020014180196a20014190016a100f200141a01b6a2047100f200141e01c" + "6a200141d0026a100d200141c01d6a2048100f200141e0066a202d100d20" + "0141801f6a20014190036a100f200141c0076a2108420021654200215b42" + "00215c42002153024002400240200141801f6a2202290380012002418801" + "6a290300844200520d0020022903900120024198016a290300844200520d" + "0020022903a001200241a8016a290300844200520d0020022903b0012002" + "41b8016a29030084500d010b200241f8006a2903002159200241e8006a29" + "0300215e2002290370215420022903602161200229035022582002290340" + "226a84200241d8006a290300225a200241c8006a29030022628484420052" + "0440427f4200427f4200206a42788342c7faf3c3ed82a3903c561b226520" + "62206556ad7d206520627d226542f3eab8bce9ada5bfe8007d2253206554" + "ad7c42017c225c20587d225b42a4cffaf397c9eed7c7007d2265205b54ad" + "2058205c56ad7d427f511b205a7d42a9c0c689aece93b2307c215c42c7fa" + "f3c3ed82a3903c206a7d215b0b420021584200216a420021624200215a20" + "542061842059205e84844200520440427f4200427f4200206142788342c7" + "faf3c3ed82a3903c561b22582058205e54ad7d2058205e7d225e42f3eab8" + "bce9ada5bfe8007d226a205e54ad7c42017c225e20547d225842a4cffaf3" + "97c9eed7c7007d2262205854ad2054205e56ad7d427f511b20597d42a9c0" + "c689aece93b2307c215a42c7faf3c3ed82a3903c20617d21580b20082002" + "4180016a22052903003703800120082002290300370300200841b8016a20" + "0541386a290300370300200841b0016a200541306a290300370300200841" + "a8016a200541286a290300370300200841a0016a200541206a2903003703" + "0020084198016a200541186a29030037030020084190016a200541106a29" + "030037030020084188016a200541086a290300370300200841086a200241" + "086a290300370300200841106a200241106a290300370300200841186a20" + "0241186a290300370300200841206a200241206a29030037030020084128" + "6a200241286a290300370300200841306a200241306a2903003703002008" + "41386a200241386a2903003703002008205a370378200820623703702008" + "206a370368200820583703602008205c3703582008206537035020082053" + "3703482008205b3703400c010b2008200241c001104c1a0b200141a00f6a" + "200141a0186a41a002104c1a200141c0116a200141c01a6a41a002104c1a" + "200141e0136a200141e01c6a41a002104c1a20014180166a200141e0066a" + "41a002104c1a200141a00c6a2131230041b0d1006b220024002000410036" + "023820004280808080800237023020004100360244200042808080808002" + "37023c41102133200041306a10362000280234223b200141a00f6a220341" + "e000104c1a20004101360238200341e0006a2102200028023c4504402000" + "413c6a1038200028024021330b2033200241c001104c1a200341a0026a21" + "022000410136024420002802304101460440200041306a10362000280234" + "213b0b203b41e0006a200241e000104c1a2000410236023820034180036a" + "2102200028023c41014604402000413c6a1038200028024021330b203341" + "c0016a200241c001104c1a200341c0046a21022000410236024420002802" + "304102460440200041306a10362000280234213b0b203b41c0016a200241" + "e000104c1a20004103360238200341a0056a2102200028023c4102460440" + "2000413c6a1038200028024021330b20334180036a200241c001104c1a20" + "0341e0066a21022000410336024420002802304103460440200041306a10" + "362000280234213b0b203b41a0026a200241e000104c1a20004104360238" + "200341c0076a2103200028023c41034604402000413c6a10382000280240" + "21330b203341c0046a200341c001104c1a20004104360244200041003602" + "502000428080808080023702482000410036025c20004280808080800237" + "025420004180046a2151200041e00d6a2104200041b0076a212c20004190" + "c1006a2143200041d0c0006a2128200041f0c0006a2144200041c00d6a21" + "0b200041d0286a2106200041d01f6a211820004180c7006a212b200041b0" + "c7006a2107200041c0c7006a213c200041f0c6006a2102200041800e6a21" + "2d200041903b6a213d200041f03a6a2127200041d03a6a213e200041f00d" + "6a213f200041b00d6a221041086a212e200041f8c6006a214c200041b8c7" + "006a214d20004188c7006a214e200041c8c7006a211220004198c7006a21" + "1f200041d8c7006a2122200041a8c7006a2123200041e8c7006a21244110" + "2138411021050340200041e0006a203b204f41e0006c6a22031041200041" + "b0016a2033204f41c0016c6a220d104502402000280260410171450d0020" + "002802b001410171450d00200041a00d6a2003104120002802a00d410171" + "45044041a4a3c0001020000b200041f8026a2211201041386a2903003703" + "00200041f0026a2213201041306a290300370300200041e8026a22092010" + "41286a290300370300200041e0026a2215201041206a2903003703002000" + "41d8026a220f201041186a290300370300200041d0026a2225201041106a" + "290300370300200020102903003703c0022000202e2903003703c8022000" + "280248203946044041002108230041206b220e240002400240200041c800" + "6a221b280200220c417f460d00200c4101742205200c41016a2216200520" + "164b1b220541ffffff1f4b0d0041042005200541044d1b22054106742216" + "41f0ffffff074b0d00200e200c047f200e200c41067436021c200e201b28" + "020436021441100541000b360218200e41086a2016200e41146a1037200e" + "2802084101470d01200e2802101a200e28020c21080b200841b4a3c00010" + "19000b200e28020c210c201b2005360200201b200c360204200e41206a24" + "00200028024c21050b200520394106746a220320002903c0023703002003" + "41386a2011290300370300200341306a2013290300370300200341286a20" + "09290300370300200341206a2015290300370300200341186a200f290300" + "370300200341106a2025290300370300200341086a20002903c802370300" + "2000203941016a2239360250200041a00d6a200d10450240024020002802" + "a00d4101710440200041b03a6a2010418001104c1a200041d80d6a222542" + "00370300200041d00d6a223a4200370300200041c80d6a22294200370300" + "200b4200370300200041b80d6a220d420037030020104200370300203f42" + "00370300203f41086a4200370300203f41106a4200370300203f41186a42" + "00370300203f41206a4200370300203f41286a4200370300200042003703" + "e80d200042013703e00d200042003703a80d200042003703a00d027f0240" + "0240200041b03a6a200041a00d6a104a0d00203e200b104a0d0020272004" + "104a0d00203d202d104a450d010b203c4200370300200220272903003703" + "00203c41086a4200370300203c41106a4200370300203c41186a42003703" + "00203c41206a4200370300203c41286a4200370300200241386a20274138" + "6a290300370300200241306a202741306a290300370300200241286a2027" + "41286a290300370300200241206a202741206a290300370300200241186a" + "202741186a290300370300200241106a202741106a290300370300200241" + "086a202741086a290300370300200041e8c6006a200041e83a6a29030037" + "0300200041e0c6006a200041e03a6a290300370300200041d8c6006a2000" + "41d83a6a290300370300200041d0c6006a203e290300370300200041c8c6" + "006a200041c83a6a290300370300200041c0c6006a200041c03a6a290300" + "370300200020002903b83a3703b846200020002903b03a3703b04620070c" + "010b200041c0c6006a4200370300200041c8c6006a4200370300200041d0" + "c6006a4200370300200041d8c6006a4200370300200041e0c6006a420037" + "0300200041e8c6006a4200370300200042003703b046200042003703b846" + "202b41f000104b1a20020b220342003703082003420137030041bda9c000" + "2d00001a41809901100b221e450d0141002109200041003602b819200020" + "1e3602b419200041e6003602b019200041b03d6a200041b03a6a100a4140" + "212a0340200041a00d6a200041b0c6006a2002102f200041c8c3006a2215" + "200d290300370300200041c0c3006a220f20102903003703002000200029" + "03a80d3703b843200020002903a00d3703b043200041b0c3006a42a4fdf9" + "e1b6c191889e7f42c6cae3a18ba9ade04b42aed88286b4db88945c4294a0" + "e38497e789991842c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b" + "200041a8076a2211200b41186a221b290300370300200041a0076a221320" + "0b41106a22342903003703002000200b41086a2240290300370398072000" + "200b2903003703900720004190076a42a4fdf9e1b6c191889e7f42c6cae3" + "a18ba9ade04b42aed88286b4db88945c4294a0e38497e789991842c7faf3" + "c3ed82a3903c428d95c7c396d2dac0977f102b200041c81f6a2015290300" + "370300200041c01f6a200f29030037030020182000290390073703002018" + "41086a200029039807370300201841106a2013290300370300201841186a" + "2011290300370300200020002903b8433703b81f200020002903b0433703" + "b01f200041e8346a2203200241386a290300370300200041e0346a200241" + "306a290300370300200041d8346a2232200241286a290300370300200041" + "d0346a200241206a290300370300200041c8346a220e200241186a290300" + "370300200041c0346a200241106a2903003703002000200241086a290300" + "3703b834200020022903003703b034200041b0346a20022002102f200041" + "e8376a2219200741386a290300370300200041e0376a200741306a290300" + "370300200041d8376a221a200741286a290300370300200041d0376a2007" + "41206a290300370300200041c8376a222f200741186a2903003703002000" + "41c0376a2230200741106a2903003703002000200741086a2903003703b8" + "37200020072903003703b037200041b0376a20072007102f20002903b837" + "226942018620002903b037226b423f88842155206b420186215402400240" + "027e203029030022664201862069423f8884225342ddb0858ce8b691a8b8" + "7f85202f290300227820787c2066423f887c225642a9c0c689aece93b230" + "8584500440205442c7faf3c3ed82a3903c542055428d95c7c396d2dac097" + "7f542055428d95c7c396d2dac0977f511b450d0242a9c0c689aece93b230" + "215642ddb0858ce8b691a8b87f0c010b205342deb0858ce8b691a8b87f54" + "205642a9c0c689aece93b23054205642a9c0c689aece93b230511b450d01" + "20530b215a2054215f205521580c010b205620532055205442c7faf3c3ed" + "82a3903c7d225f20545aad22547d225942f3eab8bce9ada5bfe8007c2258" + "205954ad2054205556ad7d7c2255205354ad205542a2cffaf397c9eed7c7" + "007c225a205554ad7c50ad7d42a9c0c689aece93b2307d21560b201a2903" + "00226742018620002903d037226f423f88842154206f4201862153024002" + "4020002903e037225e4201862067423f8884225942ddb0858ce8b691a8b8" + "7f852019290300227720777c205e423f887c225542a9c0c689aece93b230" + "8584500440205342c7faf3c3ed82a3903c542054428d95c7c396d2dac097" + "7f542054428d95c7c396d2dac0977f511b450d0142a9c0c689aece93b230" + "215542ddb0858ce8b691a8b87f21602053215b205421700c020b205942de" + "b0858ce8b691a8b87f54205542a9c0c689aece93b23054205542a9c0c689" + "aece93b230511b450d002053215b20542170205921600c010b2055205920" + "54205342c7faf3c3ed82a3903c7d225b20535aad22537d226042f3eab8bc" + "e9ada5bfe8007c2270206054ad2053205456ad7d7c2254205954ad205442" + "a2cffaf397c9eed7c7007c2260205454ad7c50ad7d42a9c0c689aece93b2" + "307d21550b02400240027e205a20667c225a205820697c2254206954ad20" + "54205f206b7c2259206b54ad7c2253205454ad7c7c225442ddb0858ce8b6" + "91a8b87f85205a206654ad2054205a54ad7c205620787c7c225642a9c0c6" + "89aece93b2308584500440205942c7faf3c3ed82a3903c542053428d95c7" + "c396d2dac0977f542053428d95c7c396d2dac0977f511b450d0242a9c0c6" + "89aece93b230215642ddb0858ce8b691a8b87f0c010b205442deb0858ce8" + "b691a8b87f54205642a9c0c689aece93b23054205642a9c0c689aece93b2" + "30511b450d0120540b215f205921582053215c0c010b2056205420532059" + "42c7faf3c3ed82a3903c7d225820595aad22597d225a42f3eab8bce9ada5" + "bfe8007c225c205a54ad2053205954ad7d7c2253205454ad205342a2cffa" + "f397c9eed7c7007c225f205354ad7c50ad7d42a9c0c689aece93b2307d21" + "560b02400240205e20607c225a206720707c2254206754ad2054205b206f" + "7c2259206f54ad7c2253205454ad7c7c225442ddb0858ce8b691a8b87f85" + "205a205e54ad2054205a54ad7c205520777c7c225542a9c0c689aece93b2" + "308584500440205942c7faf3c3ed82a3903c542053428d95c7c396d2dac0" + "977f542053428d95c7c396d2dac0977f511b450d0142a9c0c689aece93b2" + "30215542ddb0858ce8b691a8b87f21542059215a205321590c020b205442" + "deb0858ce8b691a8b87f54205542a9c0c689aece93b23054205542a9c0c6" + "89aece93b230511b450d002059215a205321590c010b2055205420532059" + "42c7faf3c3ed82a3903c7d225a20595aad22607d225b42f3eab8bce9ada5" + "bfe8007c2259205b54ad2053206054ad7d7c2253205454ad205342a2cffa" + "f397c9eed7c7007c2254205354ad7c50ad7d42a9c0c689aece93b2307d21" + "550b200020543703e0222000205a3703d0222000205f3703c02220002058" + "3703b022200020553703e822200020593703d822200020563703c8222000" + "205c3703b822200042d4fdc3d783f6c4cb003703d80d200042f4fbe3f6de" + "f5ab964d3703d00d200042d2b0b4a9ce90e8a7a77f3703c80d200042d2ab" + "8caee8a0afd1643703c00d200042aed5e2f58ca8a78a2b3703b80d200042" + "c3d581df919386df817f3703b00d200042a3dfefced5bcb1dab57f3703a8" + "0d200042e5f184a5c2dbf9b3323703a00d200041b0256a200041a00d6a20" + "0041b0226a102f20002903b825226442018620002903b025226e423f8884" + "2155206e420186215402400240027e20002903c02522704201862064423f" + "8884225342ddb0858ce8b691a8b87f85200041c8256a2219290300226020" + "607c2070423f887c225642a9c0c689aece93b2308584500440205442c7fa" + "f3c3ed82a3903c542055428d95c7c396d2dac0977f542055428d95c7c396" + "d2dac0977f511b450d0242a9c0c689aece93b230215642ddb0858ce8b691" + "a8b87f0c010b205342deb0858ce8b691a8b87f54205642a9c0c689aece93" + "b23054205642a9c0c689aece93b230511b450d0120530b215a2054215f20" + "5521580c010b205620532055205442c7faf3c3ed82a3903c7d225f20545a" + "ad22547d225942f3eab8bce9ada5bfe8007c2258205954ad2054205556ad" + "7d7c2255205354ad205542a2cffaf397c9eed7c7007c225a205554ad7c50" + "ad7d42a9c0c689aece93b2307d21560b200041d8256a221a290300227142" + "018620002903d0252265423f888421542065420186215302400240200029" + "03e025225c4201862071423f8884225942ddb0858ce8b691a8b87f852000" + "41e8256a2217290300225b205b7c205c423f887c225542a9c0c689aece93" + "b2308584500440205342c7faf3c3ed82a3903c542054428d95c7c396d2da" + "c0977f542054428d95c7c396d2dac0977f511b450d0142a9c0c689aece93" + "b230215542ddb0858ce8b691a8b87f21682053216c205421730c020b2059" + "42deb0858ce8b691a8b87f54205542a9c0c689aece93b23054205542a9c0" + "c689aece93b230511b450d002053216c20542173205921680c010b205520" + "592054205342c7faf3c3ed82a3903c7d226c20535aad22537d226842f3ea" + "b8bce9ada5bfe8007c2273206854ad2053205456ad7d7c2254205954ad20" + "5442a2cffaf397c9eed7c7007c2268205454ad7c50ad7d42a9c0c689aece" + "93b2307d21550b02400240027e205a20707c225a205820647c2254206454" + "ad2054205f206e7c2259206e54ad7c2253205454ad7c7c225442ddb0858c" + "e8b691a8b87f85205a207054ad2054205a54ad7c205620607c7c225a42a9" + "c0c689aece93b2308584500440205942c7faf3c3ed82a3903c542053428d" + "95c7c396d2dac0977f542053428d95c7c396d2dac0977f511b450d0242a9" + "c0c689aece93b230215a42ddb0858ce8b691a8b87f0c010b205442deb085" + "8ce8b691a8b87f54205a42a9c0c689aece93b23054205a42a9c0c689aece" + "93b230511b450d0120540b21742059217d2053216a0c010b205a20542053" + "205942c7faf3c3ed82a3903c7d227d20595aad22567d225942f3eab8bce9" + "ada5bfe8007c226a205954ad2053205654ad7d7c2256205454ad205642a2" + "cffaf397c9eed7c7007c2274205654ad7c50ad7d42a9c0c689aece93b230" + "7d215a0b02400240205c20687c2259207120737c2256207154ad20562065" + "206c7c2253206554ad7c2254205654ad7c7c225642ddb0858ce8b691a8b8" + "7f852059205c54ad2056205954ad7c2055205b7c7c225f42a9c0c689aece" + "93b2308584500440205342c7faf3c3ed82a3903c542054428d95c7c396d2" + "dac0977f542054428d95c7c396d2dac0977f511b450d0142a9c0c689aece" + "93b230215f42ddb0858ce8b691a8b87f21732053217b205421790c020b20" + "5642deb0858ce8b691a8b87f54205f42a9c0c689aece93b23054205f42a9" + "c0c689aece93b230511b450d002053217b20542179205621730c010b205f" + "20562054205342c7faf3c3ed82a3903c7d227b20535aad22557d225342f3" + "eab8bce9ada5bfe8007c2279205354ad2054205554ad7d7c2255205654ad" + "205542a2cffaf397c9eed7c7007c2273205554ad7c50ad7d42a9c0c689ae" + "ce93b2307d215f0b02400240027e207420002903c03422547c2256206a20" + "002903b83422537c2255206a54ad2055207d20002903b03422587c226820" + "7d54ad7c2259205554ad7c7c225542ddb0858ce8b691a8b87f8520562074" + "54ad2055205654ad7c205a200e29030022567c7c226d42a9c0c689aece93" + "b2308584500440206842c7faf3c3ed82a3903c542059428d95c7c396d2da" + "c0977f542059428d95c7c396d2dac0977f511b450d0242a9c0c689aece93" + "b230216d42ddb0858ce8b691a8b87f0c010b205542deb0858ce8b691a8b8" + "7f54206d42a9c0c689aece93b23054206d42a9c0c689aece93b230511b45" + "0d0120550b2172206821752059217a0c010b206d20552059206842c7faf3" + "c3ed82a3903c7d227520685aad22687d226c42f3eab8bce9ada5bfe8007c" + "227a206c54ad2059206854ad7d7c2259205554ad205942a2cffaf397c9ee" + "d7c7007c2272205954ad7c50ad7d42a9c0c689aece93b2307d216d0b0240" + "0240207320002903e03422597c22552079203229030022687c2263207954" + "ad2063207b20002903d034226c7c2261207b54ad7c2262206354ad7c7c22" + "5d42ddb0858ce8b691a8b87f852055207354ad2055205d56ad7c205f2003" + "29030022557c7c226342a9c0c689aece93b2308584500440206142c7faf3" + "c3ed82a3903c542062428d95c7c396d2dac0977f542062428d95c7c396d2" + "dac0977f511b450d0142a9c0c689aece93b230216342ddb0858ce8b691a8" + "b87f215d20612157206221610c020b205d42deb0858ce8b691a8b87f5420" + "6342a9c0c689aece93b23054206342a9c0c689aece93b230511b450d0020" + "612157206221610c010b2063205d2062206142c7faf3c3ed82a3903c7d22" + "5720615aad227c7d227642f3eab8bce9ada5bfe8007c2261207654ad2062" + "207c54ad7d7c2262205d54ad206242a2cffaf397c9eed7c7007c225d2062" + "54ad7c50ad7d42a9c0c689aece93b2307d21630b2011206d370300201320" + "723703002000207a37039807200020753703900720004190076a42a4fdf9" + "e1b6c191889e7f42c6cae3a18ba9ade04b42aed88286b4db88945c4294a0" + "e38497e789991842c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b" + "200d20633703002010205d370300200020613703a80d200020573703a00d" + "200041a00d6a42a4fdf9e1b6c191889e7f42c6cae3a18ba9ade04b42aed8" + "8286b4db88945c4294a0e38497e789991842c7faf3c3ed82a3903c428d95" + "c7c396d2dac0977f102b200041c8286a22032011290300370300200041c0" + "286a220e2013290300370300200620002903a00d370300200641086a2000" + "2903a80d370300200641106a2010290300370300200641186a200d290300" + "37030020002000290398073703b82820002000290390073703b028024002" + "40027e20002903c04722612000290380477c226d204d290300225d204c29" + "03007c2263205d54ad206320002903b047225d20002903f0467c2262205d" + "54ad7c225d206354ad7c7c226342ddb0858ce8b691a8b87f852061206d56" + "ad2063206d54ad7c2012290300204e2903007c7c226d42a9c0c689aece93" + "b2308584500440206242c7faf3c3ed82a3903c54205d428d95c7c396d2da" + "c0977f54205d428d95c7c396d2dac0977f511b450d0242a9c0c689aece93" + "b230216d42ddb0858ce8b691a8b87f0c010b206342deb0858ce8b691a8b8" + "7f54206d42a9c0c689aece93b23054206d42a9c0c689aece93b230511b45" + "0d0120630b217220622175205d217a0c010b206d2063205d206242c7faf3" + "c3ed82a3903c7d227520625aad22627d226142f3eab8bce9ada5bfe8007c" + "227a206154ad205d206254ad7d7c225d206354ad205d42a2cffaf397c9ee" + "d7c7007c2272205d54ad7c50ad7d42a9c0c689aece93b2307d216d0b0240" + "024020002903e047225720002903a0477c226320222903002262201f2903" + "007c225d206254ad205d20002903d04722622000290390477c2261206254" + "ad7c2262205d54ad7c7c225d42ddb0858ce8b691a8b87f852057206356ad" + "205d206354ad7c202429030020232903007c7c226342a9c0c689aece93b2" + "308584500440206142c7faf3c3ed82a3903c542062428d95c7c396d2dac0" + "977f542062428d95c7c396d2dac0977f511b450d0142a9c0c689aece93b2" + "30216342ddb0858ce8b691a8b87f215d20612157206221610c020b205d42" + "deb0858ce8b691a8b87f54206342a9c0c689aece93b23054206342a9c0c6" + "89aece93b230511b450d0020612157206221610c010b2063205d20622061" + "42c7faf3c3ed82a3903c7d225720615aad227c7d227642f3eab8bce9ada5" + "bfe8007c2261207654ad2062207c54ad7d7c2262205d54ad206242a2cffa" + "f397c9eed7c7007c225d206254ad7c50ad7d42a9c0c689aece93b2307d21" + "630b200d206d3703002010207237030020292061370300200b2057370300" + "203a205d37030020252063370300200041c0c0006a224520723703002000" + "41c8c0006a2232206d37030020282057370300200041d8c0006a22142061" + "370300200041e0c0006a205d370300200041e8c0006a221c206337030020" + "0020753703a00d200020753703b0402000207a3703a80d2000207a3703b8" + "40200041b0c0006a200041a00d6a200041a00d6a102f02400240027e2054" + "20667c226d205320697c2262206954ad20622058206b7c2263206b54ad7c" + "225d206254ad7c7c226b42ddb0858ce8b691a8b87f852066206d56ad206b" + "206d54ad7c205620787c7c226942a9c0c689aece93b23085845004402063" + "42c7faf3c3ed82a3903c54205d428d95c7c396d2dac0977f54205d428d95" + "c7c396d2dac0977f511b450d0242a9c0c689aece93b230216942ddb0858c" + "e8b691a8b87f0c010b206b42deb0858ce8b691a8b87f54206942a9c0c689" + "aece93b23054206942a9c0c689aece93b230511b450d01206b0b216d2063" + "2178205d21630c010b2069206b205d206342c7faf3c3ed82a3903c7d2278" + "20635aad22667d226d42f3eab8bce9ada5bfe8007c2263206d54ad205d20" + "6654ad7d7c2266206b54ad206642a2cffaf397c9eed7c7007c226d206654" + "ad7c50ad7d42a9c0c689aece93b2307d21690b024002402059205e7c226b" + "206720687c2266206754ad2066206c206f7c225d206f54ad7c2267206654" + "ad7c7c226642ddb0858ce8b691a8b87f85205e206b56ad2066206b54ad7c" + "205520777c7c226b42a9c0c689aece93b2308584500440205d42c7faf3c3" + "ed82a3903c542067428d95c7c396d2dac0977f542067428d95c7c396d2da" + "c0977f511b450d0142a9c0c689aece93b230216b42ddb0858ce8b691a8b8" + "7f216f205d21772067215e0c020b206642deb0858ce8b691a8b87f54206b" + "42a9c0c689aece93b23054206b42a9c0c689aece93b230511b450d00205d" + "21772067215e2066216f0c010b206b20662067205d42c7faf3c3ed82a390" + "3c7d2277205d5aad226f7d225d42f3eab8bce9ada5bfe8007c225e205d54" + "ad2067206f54ad7d7c2267206654ad206742a2cffaf397c9eed7c7007c22" + "6f206754ad7c50ad7d42a9c0c689aece93b2307d216b0b20002903b84021" + "5d20002903b040216102400240417f20002903c0402267206d8520322903" + "002266206985844200522067206d54206620695420662069511b1b222141" + "7f470440202141ff01710d01206120785a205d20635a205d2063511b0d01" + "0b20662067205d206142c7faf3c3ed82a3903c7c2262206154ad7c226120" + "5d54ad206142f3eab8bce9ada5bfe8007d225d206154ad7c7c2261206754" + "ad7c206142a3cffaf397c9eed7c7007d2275206154ad7c42a9c0c689aece" + "93b2307c21660c010b20672175206121620b205d20637d227a2062207854" + "ad225754ad217c205d206354ad21762014290300215d20002903d0402172" + "02400240417f20002903e0402263206f85201c2903002267206b85844200" + "522063206f542067206b542067206b511b1b2214417f470440201441ff01" + "710d01207220775a205d205e5a205d205e511b0d010b20672063205d2072" + "42c7faf3c3ed82a3903c7c2261207254ad7c2272205d54ad207242f3eab8" + "bce9ada5bfe8007d225d207254ad7c7c2272206354ad7c207242a3cffaf3" + "97c9eed7c7007d227e207254ad7c42a9c0c689aece93b2307c21670c010b" + "2063217e207221610b206d427f85216d2076207c7c2172206f427f852163" + "205d205e54ad205d205e7d225d2061207754ad227c54ad7c217602400240" + "417f20542070852056206085844200522054207056205620605620562060" + "511b1b2214417f470440201441ff01710d012058206e5820532064582053" + "2064511b0d010b206020702064206e42c7faf3c3ed82a3903c7c225e206e" + "54ad7c226f206454ad206f42f3eab8bce9ada5bfe8007d226e206f54ad7c" + "7c2264207054ad206442a3cffaf397c9eed7c7007d2270206454ad7c7c42" + "a9c0c689aece93b2307c21600c010b206e215e2064216e0b206d20757c21" + "64420120727d21722063207e7c216f420120767d2175206020567d205442" + "7f85227620707c2260207654ad206042012053206e56ad7d206e20537d22" + "702058205e56ad226e54ad7d7c227f206054ad7c50ad7d21762070206e7d" + "216e205e20587d217e02400240417f2059205c852055205b858442005220" + "59205c562055205b562055205b511b1b2214417f470440201441ff01710d" + "012065206c5a206820715820682071511b0d010b205b205c2071206542c7" + "faf3c3ed82a3903c7c225e206554ad7c2260207154ad206042f3eab8bce9" + "ada5bfe8007d2271206054ad7c7c2260205c54ad206042a3cffaf397c9ee" + "d7c7007d225c206054ad7c7c42a9c0c689aece93b2307c215b0c010b2065" + "215e0b206420727c2160206f20757c2170200f200041c0c6006a29030037" + "03002015200041c8c6006a290300370300200041d0c3006a200041d0c600" + "6a290300370300200041d8c3006a2214200041d8c6006a29030037030020" + "0041e0c3006a200041e0c6006a290300370300200041e8c3006a221c2000" + "41e8c6006a2903003703002000207f3703c02b2000207e3703b02b200020" + "002903b0463703b043200020002903b8463703b8432000205e206c7d3703" + "d02b200020763703c82b2000206e3703b82b2000207120687d226e205e20" + "6c54ad225e7d3703d82b20002059427f852265205c7c225c420120682071" + "56ad7d205e206e56ad7d7c22713703e02b2000205b20557d205c207156ad" + "205c206554ad7c50ad7d3703e82b200041b0c3006a200041b0c6006a2000" + "41b0c6006a102f200041c8076a22212017290300370300200041c0076a20" + "0041e0256a290300370300200041b8076a2217201a290300370300202c20" + "0041d0256a290300370300201120192903003703002013200041c0256a29" + "0300370300200020002903b82537039807200020002903b0253703900720" + "004190076a200041b0256a200041b0256a102f0240417f20542074852056" + "205a858442005220542074542056205a542056205a511b1b2219417f4704" + "40201941ff01710d012058207d5a2053206a5a2053206a511b0d010b2056" + "20542053205842c7faf3c3ed82a3903c7c225b205854ad7c2258205354ad" + "205842f3eab8bce9ada5bfe8007d225c205854ad7c7c2253205454ad2053" + "42a3cffaf397c9eed7c7007d2254205354ad7c7c42a9c0c689aece93b230" + "7c2156205b2158205c21530b2064206d5421192060206454211a2063206f" + "56210c206f20705621162056205a7d2074427f85225a20547c2256205a54" + "ad205642012053206a54ad7d2053206a7d22542058207d54ad225354ad7d" + "7c225a205654ad7c50ad7d215b205420537d21532058207d7d2158024002" + "40417f20592073852055205f858442005220592073542055205f54205520" + "5f511b1b2208417f470440200841ff01710d01206c207b5a206820795a20" + "682079511b0d010b205520592068206c42c7faf3c3ed82a3903c7c225620" + "6c54ad7c225c206854ad205c42f3eab8bce9ada5bfe8007d2254205c54ad" + "7c7c225c205954ad205c42a3cffaf397c9eed7c7007d2259205c54ad7c7c" + "42a9c0c689aece93b2307c21550c010b206c2156206821540b2019ad215c" + "201aad2164200cad21712016ad216c2000205a3703c031200020583703b0" + "3120002056207b7d3703d0312000205b3703c831200020533703b8312000" + "205420797d22532056207b54ad225a7d3703d83120002073427f85225820" + "597c225642012054207954ad7d2053205a54ad7d7c22543703e031200020" + "55205f7d2054205654ad2056205854ad7c50ad7d3703e831200041b0c600" + "6a200041b01f6a200041b0316a102f2010200e290300370300200d200329" + "0300370300200b20062903003703002029200041d8286a29030037030020" + "3a200041e0286a2903003703002025200041e8286a290300370300200020" + "002903b0283703a00d200020002903b8283703a80d200041a00d6a200041" + "b0286a200041b0286a102f20002903980722544201862000290390072253" + "423f888421552053420186215a02400240027e20002903a0072259420186" + "2054423f8884225f42ddb0858ce8b691a8b87f852011290300226820687c" + "2059423f887c225642a9c0c689aece93b2308584500440205a42c7faf3c3" + "ed82a3903c542055428d95c7c396d2dac0977f542055428d95c7c396d2da" + "c0977f511b450d0242a9c0c689aece93b230215642ddb0858ce8b691a8b8" + "7f0c010b205f42deb0858ce8b691a8b87f54205642a9c0c689aece93b230" + "54205642a9c0c689aece93b230511b450d01205f0b216f205a215e205521" + "740c010b2056205f2055205a42c7faf3c3ed82a3903c7d225e205a5aad22" + "5a7d225842f3eab8bce9ada5bfe8007c2274205854ad2055205a54ad7d7c" + "2255205f54ad205542a2cffaf397c9eed7c7007c226f205554ad7c50ad7d" + "42a9c0c689aece93b2307d21560b205c20647c2173206c20717c216c2017" + "290300225a42018620002903b007225f423f8884215b205f420186215c02" + "40024020002903c0072258420186205a423f8884226442ddb0858ce8b691" + "a8b87f852021290300227120717c2058423f887c225542a9c0c689aece93" + "b2308584500440205c42c7faf3c3ed82a3903c54205b428d95c7c396d2da" + "c0977f54205b428d95c7c396d2dac0977f511b450d0142a9c0c689aece93" + "b230215542ddb0858ce8b691a8b87f216e205c2165205b216a0c020b2064" + "42deb0858ce8b691a8b87f54205542a9c0c689aece93b23054205542a9c0" + "c689aece93b230511b450d00205c2165205b216a2064216e0c010b205520" + "64205b205c42c7faf3c3ed82a3903c7d2265205c5aad225c7d226e42f3ea" + "b8bce9ada5bfe8007c226a206e54ad205b205c54ad7d7c225b206454ad20" + "5b42a2cffaf397c9eed7c7007c226e205b54ad7c50ad7d42a9c0c689aece" + "93b2307d21550b2073502103206c50210e02400240027e2059206f7c225b" + "205420747c2264205454ad20642053205e7c225c205354ad7c2253206454" + "ad7c7c225442ddb0858ce8b691a8b87f852059205b56ad2054205b54ad7c" + "205620687c7c225642a9c0c689aece93b2308584500440205c42c7faf3c3" + "ed82a3903c542053428d95c7c396d2dac0977f542053428d95c7c396d2da" + "c0977f511b450d0242a9c0c689aece93b230215642ddb0858ce8b691a8b8" + "7f0c010b205442deb0858ce8b691a8b87f54205642a9c0c689aece93b230" + "54205642a9c0c689aece93b230511b450d0120540b215b205c2164205321" + "5c0c010b205620542053205c42c7faf3c3ed82a3903c7d2264205c5aad22" + "597d225b42f3eab8bce9ada5bfe8007c225c205b54ad2053205954ad7d7c" + "2253205454ad205342a2cffaf397c9eed7c7007c225b205354ad7c50ad7d" + "42a9c0c689aece93b2307d21560b2003ad2168206620697d216c200ead21" + "662067206b7d2167024002402058206e7c2269205a206a7c2254205a54ad" + "2054205f20657c2259205f54ad7c2253205454ad7c7c225442ddb0858ce8" + "b691a8b87f852058206956ad2054206954ad7c205520717c7c225542a9c0" + "c689aece93b2308584500440205942c7faf3c3ed82a3903c542053428d95" + "c7c396d2dac0977f542053428d95c7c396d2dac0977f511b450d0142a9c0" + "c689aece93b230215542ddb0858ce8b691a8b87f215a2059217120532169" + "0c020b205442deb0858ce8b691a8b87f54205542a9c0c689aece93b23054" + "205542a9c0c689aece93b230511b450d0020592171205321692054215a0c" + "010b205520542053205942c7faf3c3ed82a3903c7d227120595aad22597d" + "225a42f3eab8bce9ada5bfe8007c2269205a54ad2053205954ad7d7c2253" + "205454ad205342a2cffaf397c9eed7c7007c225a205354ad7c50ad7d42a9" + "c0c689aece93b2307d21550b206c20687d216b207a20577d215320672066" + "7d2168205d207c7d215920002903a80d215820002903a00d216602400240" + "417f20002903b00d225f205b85200d290300225420568584420052205b20" + "5f56205420565420542056511b1b2203417f470440200341ff01710d0120" + "642066582058205c5a2058205c511b0d010b2054205f2058206642c7faf3" + "c3ed82a3903c7c226c206654ad7c2267205854ad206742f3eab8bce9ada5" + "bfe8007d2266206754ad7c7c2258205f54ad7c205842a3cffaf397c9eed7" + "c7007d2267205854ad7c42a9c0c689aece93b2307c21540c010b205f2167" + "2066216c205821660b206220787d215f206120777d2158205420567d205b" + "427f85225420677c2256205454ad2056205c206656ad2066205c7d225420" + "64206c56ad225b54ad7c7d42017c2266205654ad7c50ad7d21672054205b" + "7d216f206c20647d216c2029290300215b20002903c00d21640240024041" + "7f20002903d00d2254205a8520252903002256205585844200522054205a" + "54205520565620552056511b1b2203417f470440200341ff01710d012064" + "20715a205b20695a205b2069511b0d010b20562054205b206442c7faf3c3" + "ed82a3903c7c225c206454ad7c2264205b54ad206442f3eab8bce9ada5bf" + "e8007d225b206454ad7c7c2264205454ad7c206442a3cffaf397c9eed7c7" + "007d2254206454ad7c42a9c0c689aece93b2307c21560c010b2064215c0b" + "20002066370380472000206c3703f0462000205c20717d37039047200020" + "67370388472000206f3703f8462000205b20697d2264205c207154ad225c" + "7d370398472000205a427f85225a20547c2254205b206954ad205c206456" + "ad7c7d42017c225b3703a0472000205620557d2054205a54ad2054205b56" + "ad7c50ad7d3703a847200020683703e831200020703703e0312000205937" + "03d831200020583703d031200020603703c0312000206b3703c831200020" + "5f3703b031200020533703b8312007200041b0346a200041b0316a102f42" + "002164200042003703e831200042003703e031200042003703d831200042" + "013703d031200042003703c831200042003703c031200042003703b83120" + "0042093703b031200041b02e6a200041b0316a200041b02b6a102f420021" + "714200216c4200216642002167205f2060842053206b8484420052044042" + "c7faf3c3ed82a3903c205f7d2166427f4200427f4200205f42788342c7fa" + "f3c3ed82a3903c561b22562053205656ad7d205620537d225642f3eab8bc" + "e9ada5bfe8007d2267205654ad7c42017c225620607d225542a4cffaf397" + "c9eed7c7007d2271205554ad2056206054ad7d427f511b206b7d42a9c0c6" + "89aece93b2307c216c0b4200216b4200216f4200215e2058207084205920" + "688484420052044042c7faf3c3ed82a3903c20587d2164427f4200427f42" + "00205842788342c7faf3c3ed82a3903c561b22562056205954ad7d205620" + "597d225642f3eab8bce9ada5bfe8007d226b205654ad7c42017c22562070" + "7d225542a4cffaf397c9eed7c7007d226f205554ad2056207054ad7d427f" + "511b20687d42a9c0c689aece93b2307c215e0b20002903b8432254420186" + "20002903b0432253423f888421552053420186215a02400240027e200029" + "03c04322594201862054423f8884225f42ddb0858ce8b691a8b87f852015" + "290300227020707c2059423f887c225642a9c0c689aece93b23085845004" + "40205a42c7faf3c3ed82a3903c542055428d95c7c396d2dac0977f542055" + "428d95c7c396d2dac0977f511b450d0242a9c0c689aece93b230215642dd" + "b0858ce8b691a8b87f0c010b205f42deb0858ce8b691a8b87f54205642a9" + "c0c689aece93b23054205642a9c0c689aece93b230511b450d01205f0b21" + "68205a2174205521730c010b2056205f2055205a42c7faf3c3ed82a3903c" + "7d2274205a5aad225a7d225842f3eab8bce9ada5bfe8007c2273205854ad" + "2055205a54ad7d7c2255205f54ad205542a2cffaf397c9eed7c7007c2268" + "205554ad7c50ad7d42a9c0c689aece93b2307d21560b2014290300225a42" + "018620002903d043225f423f88842160205f420186215b02400240200029" + "03e0432258420186205a423f8884226942ddb0858ce8b691a8b87f85201c" + "290300225c205c7c2058423f887c225542a9c0c689aece93b23085845004" + "40205b42c7faf3c3ed82a3903c542060428d95c7c396d2dac0977f542060" + "428d95c7c396d2dac0977f511b450d0142a9c0c689aece93b230215542dd" + "b0858ce8b691a8b87f216e205b21652060216a0c020b206942deb0858ce8" + "b691a8b87f54205542a9c0c689aece93b23054205542a9c0c689aece93b2" + "30511b450d00205b21652060216a2069216e0c010b205520692060205b42" + "c7faf3c3ed82a3903c7d2265205b5aad225b7d226e42f3eab8bce9ada5bf" + "e8007c226a206e54ad205b206056ad7d7c2260206954ad206042a2cffaf3" + "97c9eed7c7007c226e206054ad7c50ad7d42a9c0c689aece93b2307d2155" + "0b02400240027e205920687c225b205420737c2269205454ad2069205320" + "747c2260205354ad7c2253206954ad7c7c225442ddb0858ce8b691a8b87f" + "852059205b56ad2054205b54ad7c205620707c7c225642a9c0c689aece93" + "b2308584500440206042c7faf3c3ed82a3903c542053428d95c7c396d2da" + "c0977f542053428d95c7c396d2dac0977f511b450d0242a9c0c689aece93" + "b230215642ddb0858ce8b691a8b87f0c010b205442deb0858ce8b691a8b8" + "7f54205642a9c0c689aece93b23054205642a9c0c689aece93b230511b45" + "0d0120540b215b20602170205321690c010b205620542053206042c7faf3" + "c3ed82a3903c7d227020605aad22597d226042f3eab8bce9ada5bfe8007c" + "2269206054ad2053205954ad7d7c2253205454ad205342a2cffaf397c9ee" + "d7c7007c225b205354ad7c50ad7d42a9c0c689aece93b2307d21560b0240" + "02402058206e7c2260205a206a7c2254205a54ad2054205f20657c225920" + "5f54ad7c2253205454ad7c7c225442ddb0858ce8b691a8b87f8520582060" + "56ad2054206054ad7c2055205c7c7c225542a9c0c689aece93b230858450" + "0440205942c7faf3c3ed82a3903c542053428d95c7c396d2dac0977f5420" + "53428d95c7c396d2dac0977f511b450d0142a9c0c689aece93b230215542" + "ddb0858ce8b691a8b87f21542059215a205321590c020b205442deb0858c" + "e8b691a8b87f54205542a9c0c689aece93b23054205542a9c0c689aece93" + "b230511b450d002059215a205321590c010b205520542053205942c7faf3" + "c3ed82a3903c7d225a20595aad225f7d225842f3eab8bce9ada5bfe8007c" + "2259205854ad2053205f54ad7d7c2253205454ad205342a2cffaf397c9ee" + "d7c7007c2254205354ad7c50ad7d42a9c0c689aece93b2307d21550b2000" + "41e81c6a2203200041e82e6a290300370300200041e01c6a220e200041e0" + "2e6a290300370300200041d81c6a2219200041d82e6a2903003703002000" + "41d01c6a221a200041d02e6a290300370300200041c81c6a2217200041c8" + "2e6a290300370300200041c01c6a2214200041c02e6a2903003703002000" + "20002903b82e3703b81c200020002903b02e3703b01c20002802b0192009" + "460440200041b0196a41c4a2c000103920002802b419211e0b2017290300" + "21532019290300215f2003290300215820002903b81c2160201e200941c0" + "016c6a220320553703b80120142903002155201a290300215c200e290300" + "216820002903b01c2174200320543703b001200320593703a8012003205a" + "3703a00120032056370398012003205b3703900120032069370388012003" + "2070370380012003205e3703782003206f3703702003206b370368200320" + "643703602003206c37035820032071370350200320673703482003206637" + "034020032074370300200341386a2058370300200341306a206837030020" + "0341286a205f370300200341206a205c370300200341186a205337030020" + "0341106a2055370300200341086a20603703002000200941016a22033602" + "b81902400240200041b0196a027f02400240202a41e4a1c0006a2d000041" + "016b0e03000401040b200041b0c9006a200041b0c6006a200041b03a6a10" + "49200041b0c9006a210e200320002802b019470d0241d4a2c0000c010b20" + "0041b0ce006a200041b0c6006a200041b03d6a1049200041b0ce006a210e" + "200320002802b019470d0141e4a2c0000b103920002802b419211e0b201e" + "200341c0016c6a200e41c001104c1a2000200941026a22033602b8190b20" + "032109202a41016a222a0d000b200042a0dcae8f86aaf9e4163703c80720" + "0042948fe8babd91b3d2cb003703c007200042cebbf2dbd0c38ad7323703" + "b807200042a297bfa0c6a3f5b2163703b007200042f7a3e4fb84f3d1d92f" + "3703a807200042c3e2e6aacf87fb85cc003703a0072000428ce68c968ce2" + "b0c6b77f37039807200042bdaabdbbf1aae5f1997f370390072015203e41" + "186a290300370300200f203e41106a2903003703002000203e41086a2903" + "003703b8432000203e2903003703b043200041b0c3006a42c6faf3c3ed82" + "a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689" + "aece93b23042c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b200d" + "200041c83a6a2903003703002010200041c03a6a290300370300200b2000" + "2903b043370300204020002903b8433703002034200f290300370300201b" + "2015290300370300200020002903b83a3703a80d200020002903b03a3703" + "a00d200041b0c0006a20004190076a200041a00d6a102f2000429a8984e2" + "ca978fe0073703c807200042abdee5e3feb4ad82073703c007200042d2b7" + "89fd98b99fc0213703b807200042e3e18eb1b2ecdfe9827f3703b0072000" + "42dcebebc4d4e0bc9e063703a807200042b9f38bb78bd3b1af5c3703a007" + "20004298b3a5ceda9db8d55b37039807200042daa6808de7a880aa5c3703" + "90072015203d41186a290300370300200f203d41106a2903003703002000" + "203d41086a2903003703b8432000203d2903003703b043200041b0c3006a" + "42c6faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8" + "b87f42a9c0c689aece93b23042c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f102b200d202741186a2903003703002010202741106a2903003703" + "00200b20002903b043370300204020002903b8433703002034200f290300" + "370300201b20152903003703002000202741086a2903003703a80d200020" + "272903003703a00d204420004190076a200041a00d6a102f200042a0dcae" + "8f86aaf9e4163703e843200042948fe8babd91b3d2cb003703e043200042" + "cebbf2dbd0c38ad7323703d843200042a297bfa0c6a3f5b2163703d04320" + "0042f7a3e4fb84f3d1d92f3703c843200042c3e2e6aacf87fb85cc003703" + "c0432000428ce68c968ce2b0c6b77f3703b843200042bdaabdbbf1aae5f1" + "997f3703b043202f202841186a2903003703002030202841106a29030037" + "03002000202841086a2903003703b837200020282903003703b037200041" + "b0376a42c6faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8" + "b691a8b87f42a9c0c689aece93b23042c7faf3c3ed82a3903c428d95c7c3" + "96d2dac0977f102b2011203229030037030020132045290300370300202c" + "20002903b037370300202c41086a220d20002903b837370300202c41106a" + "22092030290300370300202c41186a2215202f2903003703002000200029" + "03b84037039807200020002903b04037039007200041a00d6a200041b0c3" + "006a20004190076a102f2000429a8984e2ca978fe0073703e843200042ab" + "dee5e3feb4ad82073703e043200042d2b789fd98b99fc0213703d8432000" + "42e3e18eb1b2ecdfe9827f3703d043200042dcebebc4d4e0bc9e063703c8" + "43200042b9f38bb78bd3b1af5c3703c04320004298b3a5ceda9db8d55b37" + "03b843200042daa6808de7a880aa5c3703b043202f204341186a29030037" + "03002030204341106a2903003703002000204341086a2903003703b83720" + "0020432903003703b037200041b0376a42c6faf3c3ed82a3903c428d95c7" + "c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b23042c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f102b2011204441186a2903" + "003703002013204441106a290300370300202c20002903b037370300200d" + "20002903b837370300200920302903003703002015202f29030037030020" + "00204441086a2903003703980720002044290300370390072004200041b0" + "c3006a20004190076a102f200041b0c3006a200041a00d6a100a20004190" + "076a200041b0c6006a200041b0c0006a104920002802b019221120034604" + "40200041b0196a41a4a2c000103920002802b019211120002802b419211e" + "0b201e200341c0016c6a20004190076a41c001104c1a2000200341016a22" + "0d3602b819200041a00d6a200041b0c6006a200041b0c3006a1049200d20" + "11470d02200041b0196a41b4a2c000103920002802b419211e0c020b41c4" + "a3c00010200b000b201e200d41c0016c6a200041a00d6a41c001104c1a20" + "0041b8196a220d200341026a36020020004180036a200041b03a6a418001" + "104c1a205141086a200d280200360200205120002902b019370200200028" + "025420464604404100211b230041206b220e240002400240200041d4006a" + "22162802002209417f460d00410420094101742208200941016a220c2008" + "200c4b1b2208200841044d1b220cad4290017e22534220884200520d0020" + "53a7220841f0ffffff074b0d00200e2009047f200e20094190016c36021c" + "200e201628020436021441100541000b360218200e41086a2008200e4114" + "6a1037200e2802084101470d01200e2802101a200e28020c211b0b201b41" + "d4a3c0001019000b200e28020c21092016200c3602002016200936020420" + "0e41206a2400200028025821380b203820464190016c6a20004180036a41" + "9001104c1a2000204641016a224636025c0b204f41016a224f4104470d00" + "0b0240024002400240024002400240024002400240024002402046450440" + "2000280254210320004190076a41f002104b1a20030d010c020b41002118" + "200041a0076a41f002104b1a200042003703980720004201370390072046" + "2039203920464b1b210820384184016a211b200041e00e6a2134200041b0" + "cf006a2119200041f0ce006a211a200041f0c3006a2114200041b0c4006a" + "2121200041b0ca006a2140200041f0c9006a2145200041b0c7006a214c20" + "004190086a212c200041f0c6006a214d200041d0076a212820004190096a" + "211c200041d0096a214e200041d0086a2117200041d0ce006a2110200041" + "d0c9006a21134100210c0240024002400340200041b0c3006a2000419007" + "6a2017103b200042003703e849200042003703e049200042003703d84920" + "0042013703d049200042003703c849200042003703c049200042003703b8" + "49200042093703b049200041b0ce006a204e200041b0c9006a102f201941" + "386a2203201c41386a290300370300201941306a2202201c41306a290300" + "370300201941286a2207201c41286a290300370300201941206a220b201c" + "41206a290300370300201941186a220d201c41186a290300370300201941" + "106a2211201c41106a290300370300201941086a2206201c41086a290300" + "3703002019201c290300370300201a2017290300370300201a41086a2209" + "201741086a290300370300201a41106a2215201741106a29030037030020" + "1a41186a220f201741186a290300370300201a41206a2225201741206a29" + "0300370300201a41286a2229201741286a290300370300201a41306a222a" + "201741306a290300370300201a41386a221e201741386a29030037030020" + "0041b0c6006a200041b0ce006a20004190076a1030204d201a2028103020" + "4c2019202c1030200041b0ce006a201741c001104c1a200041b0c9006a20" + "004190076a2017103020452028201a10302040202c20191030200041b0ce" + "006a200041b0c6006a200041b0c9006a103b200041b0c9006a200041b0ce" + "006a200041b0c3006a103c200042003703e846200042003703e046200042" + "003703d846200042013703d046200042003703c846200042003703c04620" + "0042003703b846200042093703b046200041b0ce006a2021200041b0c600" + "6a102f201a20002903b043370300200920002903b8433703002015200041" + "c0c3006a290300370300200f200041c8c3006a2903003703002025200041" + "d0c3006a2903003703002029200041d8c3006a290300370300202a200041" + "e0c3006a290300370300201e200041e8c3006a2903003703002003201441" + "386a2903003703002002201441306a2903003703002007201441286a2903" + "00370300200b201441206a290300370300200d201441186a290300370300" + "2011201441106a2903003703002006201441086a29030037030020192014" + "290300370300200041a00d6a200041b0c9006a200041b0ce006a103c2000" + "41b0ce006a200041b0c3006a200041b0c3006a1030201a20142014103020" + "192021202110302034200041b0ce006a41c001104c1a20004190076a2000" + "41a00d6a418003104c1a200c41016a2116201b2106200521022008210f02" + "7f02402039450440200c41a4a1c0006a2d00000d01201841016a21182016" + "220c41c000460d040c030b02400340200641046a280200220320184b0440" + "200241386a2903002156200241306a2903002155200241286a2903002154" + "200241206a2903002153200041c8ce006a220d2006280200201841c0016c" + "6a220341d8006a290300370300200041c0ce006a2211200341d0006a2903" + "003703002000200341c8006a2903003703b84e200020032903403703b04e" + "200041b0ce006a205320542055205642c7faf3c3ed82a3903c428d95c7c3" + "96d2dac0977f102b200041b80d6a2207200341f8006a2903003703002000" + "41b00d6a220b200341f0006a2903003703002000200341e8006a29030037" + "03a80d200020032903603703a00d200041a00d6a205320542055205642c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f102b200041c8c9006a2225" + "200d290300370300200041c0c9006a222920112903003703002013200029" + "03a00d370300201341086a222a20002903a80d370300201341106a221e20" + "0b290300370300201341186a222f2007290300370300200020002903b84e" + "3703b849200020002903b04e3703b049200241186a290300215620024110" + "6a2903002155200241086a290300215420022903002153200041c8c6006a" + "220920034198016a290300370300200041c0c6006a221520034190016a29" + "0300370300200020034188016a2903003703b84620002003290380013703" + "b046200041b0c6006a205320542055205642c7faf3c3ed82a3903c428d95" + "c7c396d2dac0977f102b2007200341b8016a290300370300200b200341b0" + "016a2903003703002000200341a8016a2903003703a80d200020032903a0" + "013703a00d200041a00d6a205320542055205642c7faf3c3ed82a3903c42" + "8d95c7c396d2dac0977f102b200d20092903003703002011201529030037" + "0300201020002903a00d370300201041086a223020002903a80d37030020" + "1041106a223a200b290300370300201041186a2232200729030037030020" + "0020002903b8463703b84e200020002903b0463703b04e200041a00d6a20" + "004190076a2003200041b0c9006a200041b0ce006a104820004190076a20" + "0041a00d6a418003104c1a20064190016a2106200241406b2102200f4101" + "6b220f0d010c020b0b201820034194a2c0001010000b201b210620052102" + "2008210e201841016a220f200c41a4a1c0006a2d0000450d011a03402006" + "41046a2802002203200f4b0440200241386a2903002156200241306a2903" + "002155200241286a2903002154200241206a2903002153200d2006280200" + "200f41c0016c6a220341d8006a2903003703002011200341d0006a290300" + "3703002000200341c8006a2903003703b84e200020032903403703b04e20" + "0041b0ce006a205320542055205642c7faf3c3ed82a3903c428d95c7c396" + "d2dac0977f102b2007200341f8006a290300370300200b200341f0006a29" + "03003703002000200341e8006a2903003703a80d200020032903603703a0" + "0d200041a00d6a205320542055205642c7faf3c3ed82a3903c428d95c7c3" + "96d2dac0977f102b2025200d290300370300202920112903003703002013" + "20002903a00d370300202a20002903a80d370300201e200b290300370300" + "202f2007290300370300200020002903b84e3703b849200020002903b04e" + "3703b049200241186a2903002156200241106a2903002155200241086a29" + "0300215420022903002153200920034198016a2903003703002015200341" + "90016a290300370300200020034188016a2903003703b846200020032903" + "80013703b046200041b0c6006a205320542055205642c7faf3c3ed82a390" + "3c428d95c7c396d2dac0977f102b2007200341b8016a290300370300200b" + "200341b0016a2903003703002000200341a8016a2903003703a80d200020" + "032903a0013703a00d200041a00d6a205320542055205642c7faf3c3ed82" + "a3903c428d95c7c396d2dac0977f102b200d200929030037030020112015" + "290300370300201020002903a00d370300203020002903a80d370300203a" + "200b29030037030020322007290300370300200020002903b8463703b84e" + "200020002903b0463703b04e200041a00d6a20004190076a2003200041b0" + "c9006a200041b0ce006a104820004190076a200041a00d6a418003104c1a" + "20064190016a2106200241406b2102200e41016b220e0d010c020b0b200f" + "20034184a2c0001010000b201841026a0b21182016220c41c000470d000b" + "2039450d0020384184016a2107200041d0ce006a210b200041d0c9006a21" + "0d201841c0016c2125200521022008210903402018200741046a28020022" + "034f0d02200241386a2903002156200241306a2903002155200241286a29" + "03002154200241206a2903002153200041c8ce006a221320072802002025" + "6a220341d8006a290300370300200041c0ce006a2206200341d0006a2903" + "003703002000200341c8006a2903003703b84e200020032903403703b04e" + "200041b0ce006a205320542055205642c7faf3c3ed82a3903c428d95c7c3" + "96d2dac0977f102b200041b80d6a2211200341f8006a2903003703002000" + "41b00d6a2210200341f0006a2903003703002000200341e8006a29030037" + "03a80d200020032903603703a00d200041a00d6a205320542055205642c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f102b200041c8c9006a2013" + "290300370300200041c0c9006a2006290300370300200d20002903a00d37" + "0300200d41086a20002903a80d370300200d41106a201029030037030020" + "0d41186a2011290300370300200020002903b84e3703b849200020002903" + "b04e3703b049200241186a2903002156200241106a290300215520024108" + "6a290300215420022903002153200041c8c6006a221520034198016a2903" + "00370300200041c0c6006a220f20034190016a2903003703002000200341" + "88016a2903003703b84620002003290380013703b046200041b0c6006a20" + "5320542055205642c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b" + "2011200341b8016a2903003703002010200341b0016a2903003703002000" + "200341a8016a2903003703a80d200020032903a0013703a00d200041a00d" + "6a205320542055205642c7faf3c3ed82a3903c428d95c7c396d2dac0977f" + "102b201320152903003703002006200f290300370300200b20002903a00d" + "370300200b41086a20002903a80d370300200b41106a2010290300370300" + "200b41186a2011290300370300200020002903b8463703b84e2000200029" + "03b0463703b04e200041a00d6a20004190076a2003200041b0c9006a2000" + "41b0ce006a104820004190076a200041a00d6a418003104c1a2007419001" + "6a2107200241406b2102200941016b22090d000b20384184016a21072000" + "41d0ce006a210b200041d0c9006a210d201841016a221841c0016c210f20" + "05210203402018200741046a28020022034f0d03200241386a2903002156" + "200241306a2903002155200241286a2903002154200241206a2903002153" + "200041c8ce006a22132007280200200f6a220341d8006a29030037030020" + "0041c0ce006a2206200341d0006a2903003703002000200341c8006a2903" + "003703b84e200020032903403703b04e200041b0ce006a20532054205520" + "5642c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b200041b80d6a" + "2211200341f8006a290300370300200041b00d6a2210200341f0006a2903" + "003703002000200341e8006a2903003703a80d200020032903603703a00d" + "200041a00d6a205320542055205642c7faf3c3ed82a3903c428d95c7c396" + "d2dac0977f102b200041c8c9006a2013290300370300200041c0c9006a20" + "06290300370300200d20002903a00d370300200d41086a20002903a80d37" + "0300200d41106a2010290300370300200d41186a20112903003703002000" + "20002903b84e3703b849200020002903b04e3703b049200241186a290300" + "2156200241106a2903002155200241086a29030021542002290300215320" + "0041c8c6006a220920034198016a290300370300200041c0c6006a221520" + "034190016a290300370300200020034188016a2903003703b84620002003" + "290380013703b046200041b0c6006a205320542055205642c7faf3c3ed82" + "a3903c428d95c7c396d2dac0977f102b2011200341b8016a290300370300" + "2010200341b0016a2903003703002000200341a8016a2903003703a80d20" + "0020032903a0013703a00d200041a00d6a205320542055205642c7faf3c3" + "ed82a3903c428d95c7c396d2dac0977f102b201320092903003703002006" + "2015290300370300200b20002903a00d370300200b41086a20002903a80d" + "370300200b41106a2010290300370300200b41186a201129030037030020" + "0020002903b8463703b84e200020002903b0463703b04e200041a00d6a20" + "004190076a2003200041b0c9006a200041b0ce006a104820004190076a20" + "0041a00d6a418003104c1a20074190016a2107200241406b210220084101" + "6b22080d000b0b20004190046a20004190076a418003104c1a200041b03d" + "6a20004190046a103d200041b03a6a200041d0056a221f103d2000420037" + "03e834200042003703e034200042003703d834200042013703d034200042" + "003703c834200042003703c034200042003703b834200042093703b03420" + "0041b0ce006a200041b03b6a200041b0346a102f200041b8cf006a223620" + "0041f83a6a290300370300200041c0cf006a2237200041803b6a29030037" + "0300200041c8cf006a2242200041883b6a290300370300200041d0cf006a" + "2241200041903b6a290300370300200041d8cf006a2247200041983b6a29" + "0300370300200041e0cf006a2248200041a03b6a290300370300200041e8" + "cf006a224b200041a83b6a290300370300200041f8ce006a222220002903" + "b83a37030020004180cf006a2223200041c03a6a22492903003703002000" + "4188cf006a2224200041c83a6a224a29030037030020004190cf006a224f" + "200041d03a6a225029030037030020004198cf006a2227200041d83a6a22" + "39290300370300200041a0cf006a223f200041e03a6a223c290300370300" + "200041a8cf006a223e200041e83a6a2244290300370300200020002903f0" + "3a3703b04f200020002903b03a3703f04e200041b0376a200041b03d6a20" + "0041b0ce006a103c200041e8106a2217200041e8376a220f290300370300" + "200041e0106a2214200041e0376a2225290300370300200041d8106a221c" + "200041d8376a2229290300370300200041d0106a2221200041d0376a222a" + "290300370300200041c8106a220c200041c8376a221e2903003703002000" + "41c0106a2216200041c0376a222f290300370300200020002903b8373703" + "b810200020002903b0373703b010200041b0106a200041b0376a200041b0" + "376a102f200041e8136a2208200041a8386a222c290300370300200041e0" + "136a2228200041a0386a221b290300370300200041d8136a223420004198" + "386a2240290300370300200041d0136a224520004190386a224c29030037" + "0300200041c8136a221020004188386a224d290300370300200041c0136a" + "221320004180386a224e290300370300200041c0316a2230200041c0386a" + "223d290300370300200041c8316a223a200041c8386a2243290300370300" + "200041d0316a2232200041d0386a2251290300370300200041d8316a220e" + "200041d8386a2204290300370300200041e0316a2219200041e0386a222e" + "290300370300200041e8316a221a200041e8386a222d2903003703002000" + "200041f8376a22122903003703b813200020002903f0373703b013200020" + "002903b0383703b0312000200041b8386a222b2903003703b831200041b0" + "136a200041f0376a2215200041b0386a2218102f200042003703e8342000" + "42003703e034200042003703d834200042013703d034200042003703c834" + "200042003703c034200042003703b834200042093703b034200041b0ce00" + "6a200041b0136a200041b0346a102f2008200041e8ce006a220329030037" + "03002028200041e0ce006a22022903003703002034200041d8ce006a2207" + "2903003703002045200041d0ce006a220d2903003703002010200041c8ce" + "006a22112903003703002013200041c0ce006a220b290300370300200020" + "002903b84e3703b813200020002903b04e3703b013200041b80a6a220620" + "0c290300370300200041b00a6a22092016290300370300200020002903b8" + "103703a80a200020002903b0103703a00a200041a00a6a20002903b01320" + "002903b8132013290300201029030042c7faf3c3ed82a3903c428d95c7c3" + "96d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d20" + "0041c83d6a22132017290300370300200041c03d6a221020142903003703" + "002000201c2903003703b83d200020212903003703b03d200041b03d6a20" + "4529030020342903002028290300200829030042c7faf3c3ed82a3903c42" + "8d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b2" + "30102d201120062903002256370300200b20092903002255370300200d20" + "002903b03d2254370300200220102903002253370300200720002903b83d" + "225937030020032013290300225a370300200020002903a80a225f3703b8" + "4e200020002903a00a22583703b04e2017205a3703002014205337030020" + "1c205937030020212054370300200c205637030020162055370300200020" + "5f3703b810200020583703b010200041e8166a2217202d29030037030020" + "0041e0166a2214202e290300370300200041d8166a221c20042903003703" + "00200041d0166a22212051290300370300200041c8166a220c2043290300" + "370300200041c0166a2216203d2903003703002000202b2903003703b816" + "200020002903b0383703b016200041b0166a20182018102f200041b0ce00" + "6a200041b0166a200041b0346a102f201720032903003703002014200229" + "0300370300201c20072903003703002021200d290300370300200c201129" + "03003703002016200b290300370300200041c0196a2208202f2903003703" + "00200041c8196a2228201e290300370300200041d0196a2234202a290300" + "370300200041d8196a22452029290300370300200041e0196a223d202529" + "0300370300200041e8196a2243200f290300370300200020002903b84e37" + "03b816200020002903b04e3703b016200020002903b0373703b019200020" + "002903b8373703b819200041e8226a202c290300370300200041e0226a20" + "1b290300370300200041d8226a2040290300370300200041d0226a204c29" + "0300370300200041c8226a204d290300370300200041c0226a204e290300" + "370300200020122903003703b822200020002903f0373703b022200041b0" + "196a200041b0376a2015102f2006200c2903003703002009201629030037" + "0300200020002903b8163703a80a200020002903b0163703a00a200041a0" + "0a6a20002903b01920002903b8192008290300202829030042c7faf3c3ed" + "82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c6" + "89aece93b230102d20132017290300370300201020142903003703002000" + "201c2903003703b83d200020212903003703b03d200041b03d6a20342903" + "002045290300203d290300204329030042c7faf3c3ed82a3903c428d95c7" + "c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d" + "201120062903002256370300200b20092903002255370300200d20002903" + "b03d2254370300200220102903002253370300200720002903b83d225937" + "030020032013290300225a370300200020002903a80a225f3703b84e2000" + "20002903a00a22583703b04e2017205a37030020142053370300201c2059" + "37030020212054370300200c2056370300201620553703002000205f3703" + "b816200020583703b016200041e81c6a2217202c290300370300200041e0" + "1c6a2214201b290300370300200041d81c6a221c20402903003703002000" + "41d01c6a2221204c290300370300200041c81c6a220c204d290300370300" + "200041c01c6a2216204e290300370300200020122903003703b81c200020" + "002903f0373703b01c200041b01c6a20152015102f200041e81f6a220820" + "0f290300370300200041e01f6a222c2025290300370300200041d81f6a22" + "282029290300370300200041d01f6a221b202a290300370300200041c81f" + "6a2234201e290300370300200041c01f6a2240202f290300370300200020" + "002903b8373703b81f200020002903b0373703b01f200041b01f6a200041" + "b0376a2018102f2006200c29030037030020092016290300370300200020" + "002903b81c3703a80a200020002903b01c3703a00a200041a00a6a200029" + "03b01f20002903b81f2040290300203429030042c7faf3c3ed82a3903c42" + "8d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b2" + "30102d20132017290300370300201020142903003703002000201c290300" + "3703b83d200020212903003703b03d200041b03d6a201b29030020282903" + "00202c290300200829030042c7faf3c3ed82a3903c428d95c7c396d2dac0" + "977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2011200629" + "03002256370300200b20092903002255370300200d20002903b03d225437" + "0300200220102903002253370300200720002903b83d2259370300200320" + "13290300225a370300200020002903a80a225f3703b84e200020002903a0" + "0a22583703b04e2017205a37030020142053370300201c20593703002021" + "2054370300200c2056370300201620553703002000205f3703b81c200020" + "583703b01c200041b0316a2018200041b0166a102f200041b0226a201520" + "0041b01c6a102f200041b0ce006a200041b0316a200041b0226a1030201a" + "200329030037030020192002290300370300200e20072903003703002032" + "200d290300370300203a20112903003703002030200b2903003703002000" + "20002903b84e3703b831200020002903b04e3703b031200041b0ce006a20" + "0041b0316a200041b0346a102f201a200329030037030020192002290300" + "370300200e20072903003703002032200d290300370300203a2011290300" + "3703002030200b290300370300200041c0256a202f290300370300200041" + "c8256a201e290300370300200041d0256a202a290300370300200041d825" + "6a2029290300370300200041e0256a2025290300370300200041e8256a20" + "0f290300370300200020002903b84e3703b831200020002903b04e3703b0" + "31200020002903b0373703b025200020002903b8373703b825200041b025" + "6a200041b0376a200041b0106a102f200041b0ce006a200041b0316a2000" + "41b0256a1030201a200329030037030020192002290300370300200e2007" + "2903003703002032200d290300370300203a20112903003703002030200b" + "290300370300200020002903b84e3703b831200020002903b04e3703b031" + "200041b03d6a200041b0316a103120002802b03d4101710440200041e82e" + "6a2206200041f83d6a22092903002256370300200041e02e6a2229200041" + "f03d6a222a2903002255370300200041d82e6a221e200041e83d6a221529" + "03002254370300200041d02e6a222f200041e03d6a221829030022533703" + "00200041c82e6a2230200041d83d6a220f2903002259370300200041c02e" + "6a223a200041d03d6a2225290300225a370300200041c0286a2232205a37" + "0300200041c8286a220e2059370300200041d0286a221920533703002000" + "41d8286a221a2054370300200041e0286a22172055370300200041e8286a" + "22142056370300200020002903c03d22563703b02e200020563703b02820" + "00201329030022563703b82e200020563703b828200041b0286a20102000" + "41b0106a102f200041e82b6a221c2009290300370300200041e02b6a2221" + "202a290300370300200041d82b6a222a2015290300370300200041d02b6a" + "220c2018290300370300200041c82b6a2216200f290300370300200041c0" + "2b6a22082025290300370300200020132903003703b82b200020002903c0" + "3d3703b02b200041b02b6a2010200041b0166a102f200041b02e6a201020" + "0041b01c6a102f2003201429030037030020022017290300370300200720" + "1a290300370300200d20192903003703002011200e290300370300200b20" + "32290300370300202220002903b82b370300202320082903003703002024" + "2016290300370300204f200c2903003703002027202a290300370300203f" + "2021290300370300203e201c290300370300200020002903b8283703b84e" + "200020002903b0283703b04e200020002903b02b3703f04e204b20062903" + "00370300204820292903003703002047201e2903003703002041202f2903" + "00370300204220302903003703002037203a290300370300203620002903" + "b82e370300200020002903b02e3703b04f200041c0c0006a200041b0ce00" + "6a41c001104c2106200042003703b840200042013703b040200041b0ce00" + "6a20004190046a2006103b200041b03d6a201f2006103b200041f0cf006a" + "200041b03d6a103e200041b00d6a200041b0ce006a418003104c21292000" + "42003703a80d200042013703a00d200041f0c4006a201f103e200041b0c3" + "006a20004190046a41c001104c1a200041b0c6006a200041b0c3006a2029" + "103f200742003703002002420037030020034200370300200042a9c0c689" + "aece93b2303703c84e200042b099b385febcf6b6de003703c04e200042bd" + "dcd9dcfbd3c1c7423703b84e200042c8faf383d69cd1de643703b04e2000" + "42003703d04e200041b0c0006a200041f0c6006a200041b0ce006a102f20" + "0742003703002002420037030020034200370300200042003703c84e2000" + "42ac97d286eaf99af1d9003703c04e200042cfb8ede69afe98f9543703b8" + "4e200042feffffbf97e6d1b1d7003703b04e200042003703d04e200041b0" + "3e6a200041b0c7006a200041b0ce006a102f2010200041c0c6006a290300" + "3703002013200041c8c6006a2903003703002025200041d0c6006a290300" + "370300200f200041d8c6006a2903003703002018200041e0c6006a290300" + "3703002015200041e8c6006a290300370300200920002903b84037030020" + "0041803e6a2006290300370300200041883e6a200041c8c0006a29030037" + "0300200041903e6a200041d0c0006a290300370300200041983e6a200041" + "d8c0006a2210290300370300200041a03e6a200041e0c0006a2213290300" + "370300200041a83e6a200041e8c0006a2206290300370300200020002903" + "b0463703b03d200020002903b8463703b83d200020002903b0403703f03d" + "200742003703002002420037030020034200370300200042a9c0c689aece" + "93b2303703c84e200042b099b385febcf6b6de003703c04e200042bddcd9" + "dcfbd3c1c7423703b84e200042c8faf383d69cd1de643703b04e20004200" + "3703d04e200041b03a6a200041b0c8006a200041b0ce006a102f20104200" + "3703002013420037030020064200370300200042003703c840200042ac97" + "d286eaf99af1d9003703c040200042cfb8ede69afe98f9543703b8402000" + "42feffffbf97e6d1b1d7003703b040200042003703d040200041b0cf006a" + "2210200041f0c8006a200041b0c0006a102f200b20004180c8006a290300" + "370300201120004188c8006a290300370300200d20004190c8006a290300" + "370300200720004198c8006a2903003703002002200041a0c8006a290300" + "3703002003200041a8c8006a290300370300202220002903b83a37030020" + "2320492903003703002024204a290300370300204f205029030037030020" + "272039290300370300203f203c290300370300203e204429030037030020" + "0020002903f0473703b04e2000200041f8c7006a2903003703b84e200020" + "002903b03a3703f04e20394200370300203c420037030020444200370300" + "200042a9c0c689aece93b2303703c83a200042b099b385febcf6b6de0037" + "03c03a200042bddcd9dcfbd3c1c7423703b83a200042c9faf383d69cd1de" + "643703b03a200042003703d03a200041b0c0006a200041b0ce006a200041" + "b03a6a102f200041f0c0006a200041f0ce006a200041b03a6a102f200041" + "b0c1006a2010200041b03a6a102f200041b0c9006a200041b03d6a41c001" + "104c1a200041f0ca006a200041b0c0006a41c001104c1a200041a0076a22" + "0d200041b0c9006a200041b0c6006a103f20004200370398072000420137" + "039007200041a00a6a200d418003104c1a200042003703c8492000420037" + "03c049200042003703b849200042f193a4d3c4d6e4f4c4003703b0494100" + "2107200b41f002104b1a200042003703b84e200042013703b04e41ff0121" + "03200041286a210b0340200041206a200341ff0071104f200b2903002000" + "41b0c9006a200341037641f0ffffff01716a220229030883215620002903" + "20200229030083215520074101710440200041a00d6a200041b0ce006a10" + "46200041b0ce006a200041a00d6a418003104c1a0b205520568442005204" + "40200041a00d6a200d200041b0ce006a103f200041b0ce006a200041a00d" + "6a418003104c1a410121070b200341016b2203417f470d000b200041f011" + "6a200041f0cf006a103e200041b0106a200041b0ce006a41c001104c1a20" + "0041b0136a200041b0106a1046200041b0166a200041b0136a1046200041" + "b0196a200041b0166a200041b0136a103f200042003703c8492000420037" + "03c049200042003703b849200042f193a4d3c4d6e4f4c4003703b0494100" + "2107200041c0ce006a41f002104b1a200042003703b84e200042013703b0" + "4e41ff012103200041186a210b0340200041106a200341ff0071104f200b" + "290300200041b0c9006a200341037641f0ffffff01716a22022903088321" + "562000290310200229030083215520074101710440200041a00d6a200041" + "b0ce006a1046200041b0ce006a200041a00d6a418003104c1a0b20552056" + "844200520440200041a00d6a200041b0196a200041b0ce006a103f200041" + "b0ce006a200041a00d6a418003104c1a410121070b200341016b2203417f" + "470d000b200041f01d6a200041f0cf006a103e200041b01c6a200041b0ce" + "006a41c001104c1a200041b01f6a200041b01c6a1046200042003703c849" + "200042003703c049200042003703b849200042f193a4d3c4d6e4f4c40037" + "03b04941002107200041c0ce006a41f002104b1a200042003703b84e2000" + "42013703b04e41ff012103200041086a210b03402000200341ff0071104f" + "200b290300200041b0c9006a200341037641f0ffffff01716a2202290308" + "8321562000290300200229030083215520074101710440200041a00d6a20" + "0041b0ce006a1046200041b0ce006a200041a00d6a418003104c1a0b2055" + "2056844200520440200041a00d6a200041b01f6a200041b0ce006a103f20" + "0041b0ce006a200041a00d6a418003104c1a410121070b200341016b2203" + "417f470d000b200041f0236a2203200041f0cf006a2211103e200041b022" + "6a200041b0ce006a41c001104c1a200041f0266a200041f01a6a103e2000" + "41b0256a200041b0196a41c001104c1a200041f0296a2003103e200041b0" + "286a200041b0226a41c001104c1a200041b02b6a200041b0286a200041b0" + "1c6a103f200041b02e6a200041b02b6a200041b0256a103f200041b0316a" + "200041b02e6a200041b0136a103f200041b0346a200041b02e6a200041b0" + "1c6a103f200041b0376a200d200041b0346a103f200041b03a6a200041b0" + "316a41011047200041a00d6a200041f0326a41011047200042e6cfeba7bb" + "dee5b4243703e8492000428e97d490e19f9f99a67f3703e049200042e58f" + "bbf7f8cee4bcf4003703d849200042acc5cd87f88bbcae4a3703d0492000" + "42dfcf96c3c2e3adc2123703c849200042e0969ab7d7fbe7dc683703c049" + "200042f6c2bcc982c187a9dc003703b849200042f0c8a7e6adbbcd855637" + "03b049200041b0ce006a200041a00d6a200041b0c9006a102f200041f0ce" + "006a2210200041e00d6a220d200041b0c9006a102f200041b0cf006a2213" + "200041a00e6a2203200041b0c9006a102f200041f03b6a200041b0ce006a" + "41c001104c1a200041b03d6a200041b03a6a200041b0376a103f200041c8" + "0d6a22024200370300200041d00d6a22074200370300200041d80d6a220b" + "4200370300200042a9c0c689aece93b2303703b80d200042b099b385febc" + "f6b6de003703b00d200042bddcd9dcfbd3c1c7423703a80d200042c8faf3" + "83d69cd1de643703a00d200042003703c00d200041b0ce006a200041f02e" + "6a200041a00d6a102f2002420037030020074200370300200b4200370300" + "200042003703b80d200042ac97d286eaf99af1d9003703b00d200042cfb8" + "ede69afe98f9543703a80d200042feffffbf97e6d1b1d7003703a00d2000" + "42003703c00d200041b0ca006a200041b02f6a200041a00d6a102f200041" + "c0c9006a200041c02e6a290300370300200041c8c9006a200041c82e6a29" + "0300370300200041d0c9006a200041d02e6a290300370300200041d8c900" + "6a200041d82e6a290300370300200041e0c9006a200041e02e6a29030037" + "0300200041e8c9006a200041e82e6a290300370300200041f8c9006a2000" + "2903b84e37030020004180ca006a200041c0ce006a290300370300200041" + "88ca006a200041c8ce006a29030037030020004190ca006a200041d0ce00" + "6a29030037030020004198ca006a200041d8ce006a220629030037030020" + "0041a0ca006a200041e0ce006a2209290300370300200041a8ca006a2000" + "41e8ce006a2215290300370300200020002903b02e3703b0492000200029" + "03b82e3703b849200020002903b04e3703f0492002420037030020074200" + "370300200b4200370300200042a9c0c689aece93b2303703b80d200042b0" + "99b385febcf6b6de003703b00d200042bddcd9dcfbd3c1c7423703a80d20" + "0042c8faf383d69cd1de643703a00d200042003703c00d200041b0c6006a" + "200041b0306a200041a00d6a102f20064200370300200942003703002015" + "4200370300200042003703c84e200042ac97d286eaf99af1d9003703c04e" + "200042cfb8ede69afe98f9543703b84e200042feffffbf97e6d1b1d70037" + "03b04e200042003703d04e2003200041f0306a200041b0ce006a102f2000" + "41b00d6a220620004180306a290300370300200041b80d6a220920004188" + "306a290300370300200041c00d6a221520004190306a2903003703002002" + "20004198306a2903003703002007200041a0306a290300370300200b2000" + "41a8306a290300370300200041e80d6a20002903b846370300200041f00d" + "6a200041c0c6006a290300370300200041f80d6a200041c8c6006a290300" + "370300200041800e6a200041d0c6006a290300370300200041880e6a2000" + "41d8c6006a2202290300370300200041900e6a200041e0c6006a22072903" + "00370300200041980e6a200041e8c6006a220b2903003703002000200029" + "03f02f3703a00d2000200041f82f6a2903003703a80d200020002903b046" + "3703e00d2002420037030020074200370300200b4200370300200042a9c0" + "c689aece93b2303703c846200042b099b385febcf6b6de003703c0462000" + "42bddcd9dcfbd3c1c7423703b846200042c9faf383d69cd1de643703b046" + "200042003703d046200041b0ce006a200041a00d6a200041b0c6006a102f" + "2010200d200041b0c6006a102f20132003200041b0c6006a102f200041b0" + "c0006a200041b0c9006a41c001104c1a200041f0c1006a200041b0ce006a" + "41c001104c1a200041b0c3006a200041b0c0006a200041b03d6a103f2000" + "41f0c7006a200041e00b6a103e200041b0c6006a200041a00a6a41c00110" + "4c1a200041b0c9006a200041b0c6006a200041b0316a103f200041b0ce00" + "6a200041b0c9006a41031047200041a00d6a200041f0ca006a4103104720" + "0042f3fa9ddfe096fed5003703a84e2000429da7d8abb3dcfbe5063703a0" + "4e200042ecf3d0beb9bce981ff003703984e200042818283a6bfc5aacaf6" + "003703904e200042bbc98be4fcb9a0ee193703884e20004290d5b285cd91" + "d8f46f3703804e200042caa4d7f2dbf1aca6897f3703f84d200042ffccd2" + "f691a7dfb7683703f04d200041b0cc006a200041a00d6a200041f0cd006a" + "102f200041f0cc006a200d200041f0cd006a102f200041b0cd006a200320" + "0041f0cd006a102f2011200041b0cc006a41c001104c1a2006200041b0ce" + "006a200041b0c3006a103f2009290300215620002903b00d215520004190" + "076a201541f002104c1a20384184016a2103024002400240024002400240" + "0340200341046b280200220204402003280200220b41046b280200220741" + "7871220d200241c0016c220241044108200741037122071b72490d022007" + "4100200d20024127724b1b0d03200b10040b20034190016a210320464101" + "6b22460d000b200028025422030440203841046b28020022024178712207" + "20034190016c220341044108200241037122021b72490d03200241002007" + "200341276a4b1b0d04203810040b20002802482203450d0b200541046b28" + "0200220241787122072003410674220341044108200241037122021b7249" + "0d0420024100200720034127724b1b0d05200510040c0b0b41f996c00041" + "2e41a897c0001011000b41b897c000412e41e897c0001011000b41f996c0" + "00412e41a897c0001011000b41b897c000412e41e897c0001011000b41f9" + "96c000412e41a897c0001011000b41b897c000412e41e897c0001011000b" + "41f4a2c000411f4194a3c0001021000b2018200341f4a1c0001010000b20" + "18200341e4a1c0001010000b203841046b28020022024178712207200341" + "90016c220341044108200241037122021b72490d02200241002007200341" + "276a4b1b0d03203810040b200028024822030440200541046b2802002202" + "41787122072003410674220341044108200241037122021b72490d042002" + "4100200720034127724b1b0d05200510040b42002156420121550b203120" + "5637030820312055370300203141106a20004190076a41f002104c1a2000" + "28023c22030440203341046b28020022024178712207200341c0016c2203" + "41044108200241037122021b72490d0520024100200720034127724b1b0d" + "06203310040b200028023022030440203b41046b28020022024178712207" + "200341e0006c220341044108200241037122021b72490d07200241002007" + "200341276a4b1b0d08203b10040b200041b0d1006a24000c080b41f996c0" + "00412e41a897c0001011000b41b897c000412e41e897c0001011000b41f9" + "96c000412e41a897c0001011000b41b897c000412e41e897c0001011000b" + "41f996c000412e41a897c0001011000b41b897c000412e41e897c0001011" + "000b41f996c000412e41a897c0001011000b41b897c000412e41e897c000" + "1011000b200141f0066a41f002104b1a200142003703e806200142013703" + "e006200141a00c6a200141e0066a104a0d03200141c00c6a20014180076a" + "104a0d03200141e00c6a200141a0076a104a0d03200141800d6a200141c0" + "076a104a0d03200141a00d6a200141e0076a104a0d03200141c00d6a2001" + "4180086a104a0d03200141e00d6a200141a0086a104a0d03200141800e6a" + "200141c0086a104a0d03200141a00e6a200141e0086a104a0d03200141c0" + "0e6a20014180096a104a0d03200141e00e6a200141a0096a104a0d032001" + "41800f6a200141c0096a104a1a0c030b2002450d05200641046b28020022" + "05417871221241044108200541037122051b20026a490d0c200541002012" + "200241276a4b1b0d0d200610040c050b20012802a00b2205450d04200820" + "05410674100e0c040b206a428080808010540d0020122005100e0b202041" + "c000100e2026450d0220352026410674100e0c020b4100410041dc91c000" + "1010000b20012802e01c1a0b205241046b2802002205417871220641c600" + "41ca00200541037122051b490d1420054100200641ea004f1b0d15205210" + "04201d41046b280200220541787141e40041e800200541037122061b490d" + "162006410020054188014f1b0d17201d1004200a41046b28020022054178" + "71221d418802418c02200541037122051b490d1820054100201d41ac024f" + "1b0d19200a1004200141c0206a240041010f0b000b230041206b22052400" + "200541003602182005410136020c200541a099c000360208200542043702" + "10200541086a41f88bc000101a000b41f996c000412e41a897c000101100" + "0b41b897c000412e41e897c0001011000b41f996c000412e41a897c00010" + "11000b41b897c000412e41e897c0001011000b41f996c000412e41a897c0" + "001011000b41b897c000412e41e897c0001011000b4120201241cc8fc000" + "1012000b418001201241dc8fc0001012000b41c001201241ec8fc0001012" + "000b41a002201241fc8fc0001012000b41a00241a002418c90c000101000" + "0b41a10241a102419c90c0001010000b41a20241a20241ac90c000101000" + "0b41a30241a30241bc90c0001010000b230041306b220224002002410436" + "0204200241643602002002410236020c200241b884c00036020820024202" + "3702142002200241046aad4280808080108437032820022002ad42808080" + "8010843703202002200241206a360210200241086a41cc90c000101a000b" + "2009201241cc90c0001012000b200120012d00a10f3a00e00641b89cc000" + "412b200141e0066a41988ec00041d892c0001013000b41a89cc000101400" + "0b41f996c000412e41a897c0001011000b41b897c000412e41e897c00010" + "11000b41f996c000412e41a897c0001011000b41b897c000412e41e897c0" + "001011000b41f996c000412e41a897c0001011000b41b897c000412e41e8" + "97c0001011000b962502087f017e02400240024002400240024002402000" + "41f4014d0440418ca9c000280200220341102000410b6a41f80371200041" + "0b491b220441037622017622004103710d0120044194a9c0002802004d0d" + "0720000d024190a9c00028020022000d030c070b2000410b6a2201417871" + "21044190a9c0002802002208450d06411f2107200041f4ffff074d044020" + "04410620014108766722006b7641017120004101746b413e6a21070b4100" + "20046b2101200741027441f4a5c0006a2802002203450440410021000c04" + "0b410021002004411920074101766b41002007411f471b74210503400240" + "200328020441787122062004490d00200620046b220620014f0d00200321" + "02200622010d0041002101200321000c060b200328021422062000200620" + "032005411d764104716a41106a2802002203471b200020061b2100200541" + "0174210520030d000b0c030b02402000417f7341017120016a2205410374" + "22004184a7c0006a22042000418ca7c0006a280200220128020822024704" + "402002200436020c200420023602080c010b418ca9c0002003417e200577" + "713602000b20012000410372360204200020016a22002000280204410172" + "360204200141086a0f0b0240200020017441022001742200410020006b72" + "7168220641037422014184a7c0006a22022001418ca7c0006a2802002200" + "28020822054704402005200236020c200220053602080c010b418ca9c000" + "2003417e200677713602000b20002004410372360204200020046a220520" + "0120046b2204410172360204200020016a20043602004194a9c000280200" + "2203044020034178714184a7c0006a2102419ca9c0002802002101027f41" + "8ca9c00028020022064101200341037674220371450440418ca9c0002003" + "20067236020020020c010b20022802080b21032002200136020820032001" + "36020c2001200236020c200120033602080b419ca9c00020053602004194" + "a9c0002004360200200041086a0f0b20006841027441f4a5c0006a280200" + "220228020441787120046b21012002210302400340024002402002280210" + "22000d00200228021422000d002003280218210702400240200320032802" + "0c2200460440200341144110200328021422001b6a28020022020d014100" + "21000c020b20032802082202200036020c200020023602080c010b200341" + "146a200341106a20001b21050340200521062002220041146a200041106a" + "200028021422021b210520004114411020021b6a28020022020d000b2006" + "41003602000b2007450d032003200328021c41027441f4a5c0006a220228" + "020047044020074110411420072802102003461b6a20003602002000450d" + "040c020b2002200036020020000d014190a9c0004190a9c000280200417e" + "200328021c77713602000c030b200028020441787120046b220220012001" + "20024b22021b21012000200320021b2103200021020c010b0b2000200736" + "021820032802102202044020002002360210200220003602180b20032802" + "142202450d0020002002360214200220003602180b02400240200141104f" + "044020032004410372360204200320046a22042001410172360204200120" + "046a20013602004194a9c0002802002205450d0120054178714184a7c000" + "6a2102419ca9c0002802002100027f418ca9c00028020022064101200541" + "037674220571450440418ca9c000200520067236020020020c010b200228" + "02080b2105200220003602082005200036020c2000200236020c20002005" + "3602080c010b2003200120046a2200410372360204200020036a22002000" + "2802044101723602040c010b419ca9c00020043602004194a9c000200136" + "02000b200341086a0f0b2000200272450440410021024102200774220041" + "0020006b722008712200450d0320006841027441f4a5c0006a2802002100" + "0b2000450d010b03402002200020022000280204417871220320046b2206" + "20014922071b200320044922051b210220012006200120071b20051b2101" + "20002802102203047f20030520002802140b22000d000b0b2002450d0020" + "044194a9c00028020022004d2001200020046b4f710d0020022802182107" + "024002402002200228020c2200460440200241144110200228021422001b" + "6a28020022030d01410021000c020b20022802082203200036020c200020" + "033602080c010b200241146a200241106a20001b21050340200521062003" + "220041146a200041106a200028021422031b210520004114411020031b6a" + "28020022030d000b200641003602000b02402007450d0002402002200228" + "021c41027441f4a5c0006a22032802004704402007411041142007280210" + "2002461b6a20003602002000450d020c010b2003200036020020000d0041" + "90a9c0004190a9c000280200417e200228021c77713602000c010b200020" + "0736021820022802102203044020002003360210200320003602180b2002" + "2802142203450d0020002003360214200320003602180b0240200141104f" + "044020022004410372360204200220046a22042001410172360204200120" + "046a200136020020014180024f0440411f210020044200370210200141ff" + "ffff074d04402001410620014108766722006b7641017120004101746b41" + "3e6a21000b2004200036021c200041027441f4a5c0006a21034101200074" + "22054190a9c0002802007145044020032004360200200420033602182004" + "200436020c200420043602084190a9c0004190a9c0002802002005723602" + "000c030b0240024020012003280200220528020441787146044020052100" + "0c010b2001411920004101766b41002000411f471b742103034020052003" + "411d764104716a41106a22062802002200450d0220034101742103200021" + "0520002802044178712001470d000b0b20002802082201200436020c2000" + "2004360208200441003602182004200036020c200420013602080c030b20" + "062004360200200420053602182004200436020c200420043602080c020b" + "200141f801714184a7c0006a2100027f418ca9c000280200220341012001" + "41037674220171450440418ca9c000200120037236020020000c010b2000" + "2802080b2101200020043602082001200436020c2004200036020c200420" + "013602080c010b2002200120046a2200410372360204200020026a220020" + "002802044101723602040b200241086a0f0b024002400240024002400240" + "20044194a9c00028020022004b044020044198a9c00028020022004f0440" + "41002100200441af80046a220241107640002201417f4622050d07200141" + "10742203450d0741a4a9c000410020024180807c7120051b220641a4a9c0" + "002802006a220036020041a8a9c00041a8a9c00028020022012000200020" + "01491b3602000240024041a0a9c0002802002201044041f4a6c000210003" + "4020002802002202200028020422056a2003460d02200028020822000d00" + "0b0c020b41b0a9c00028020022004100200020034d1b45044041b0a9c000" + "20033602000b41b4a9c00041ff1f36020041f8a6c000200636020041f4a6" + "c00020033602004190a7c0004184a7c0003602004198a7c000418ca7c000" + "360200418ca7c0004184a7c00036020041a0a7c0004194a7c00036020041" + "94a7c000418ca7c00036020041a8a7c000419ca7c000360200419ca7c000" + "4194a7c00036020041b0a7c00041a4a7c00036020041a4a7c000419ca7c0" + "0036020041b8a7c00041aca7c00036020041aca7c00041a4a7c000360200" + "41c0a7c00041b4a7c00036020041b4a7c00041aca7c00036020041c8a7c0" + "0041bca7c00036020041bca7c00041b4a7c0003602004180a7c000410036" + "020041d0a7c00041c4a7c00036020041c4a7c00041bca7c00036020041cc" + "a7c00041c4a7c00036020041d8a7c00041cca7c00036020041d4a7c00041" + "cca7c00036020041e0a7c00041d4a7c00036020041dca7c00041d4a7c000" + "36020041e8a7c00041dca7c00036020041e4a7c00041dca7c00036020041" + "f0a7c00041e4a7c00036020041eca7c00041e4a7c00036020041f8a7c000" + "41eca7c00036020041f4a7c00041eca7c0003602004180a8c00041f4a7c0" + "0036020041fca7c00041f4a7c0003602004188a8c00041fca7c000360200" + "4184a8c00041fca7c0003602004190a8c0004184a8c0003602004198a8c0" + "00418ca8c000360200418ca8c0004184a8c00036020041a0a8c0004194a8" + "c0003602004194a8c000418ca8c00036020041a8a8c000419ca8c0003602" + "00419ca8c0004194a8c00036020041b0a8c00041a4a8c00036020041a4a8" + "c000419ca8c00036020041b8a8c00041aca8c00036020041aca8c00041a4" + "a8c00036020041c0a8c00041b4a8c00036020041b4a8c00041aca8c00036" + "020041c8a8c00041bca8c00036020041bca8c00041b4a8c00036020041d0" + "a8c00041c4a8c00036020041c4a8c00041bca8c00036020041d8a8c00041" + "cca8c00036020041cca8c00041c4a8c00036020041e0a8c00041d4a8c000" + "36020041d4a8c00041cca8c00036020041e8a8c00041dca8c00036020041" + "dca8c00041d4a8c00036020041f0a8c00041e4a8c00036020041e4a8c000" + "41dca8c00036020041f8a8c00041eca8c00036020041eca8c00041e4a8c0" + "003602004180a9c00041f4a8c00036020041f4a8c00041eca8c000360200" + "4188a9c00041fca8c00036020041fca8c00041f4a8c00036020041a0a9c0" + "0020033602004184a9c00041fca8c0003602004198a9c000200641286b22" + "0036020020032000410172360204200020036a412836020441aca9c00041" + "808080013602000c080b200120034f0d0020012002490d00200028020c45" + "0d030b41b0a9c00041b0a9c0002802002200200320002003491b36020020" + "0320066a210241f4a6c00021000240024003402002200028020022054704" + "40200028020822000d010c020b0b200028020c450d010b41f4a6c0002100" + "034002402001200028020022024f04402001200220002802046a2202490d" + "010b200028020821000c010b0b41a0a9c00020033602004198a9c0002006" + "41286b220036020020032000410172360204200020036a412836020441ac" + "a9c00041808080013602002001200241206b41787141086b220020002001" + "41106a491b2205411b36020441f4a6c0002902002109200541106a41fca6" + "c0002902003702002005200937020841f8a6c000200636020041f4a6c000" + "200336020041fca6c000200541086a3602004180a7c00041003602002005" + "411c6a2100034020004107360200200041046a22002002490d000b200120" + "05460d0720052005280204417e713602042001200520016b220041017236" + "02042005200036020020004180024f04402001200010350c080b200041f8" + "01714184a7c0006a2102027f418ca9c00028020022034101200041037674" + "220071450440418ca9c000200020037236020020020c010b20022802080b" + "2100200220013602082000200136020c2001200236020c20012000360208" + "0c070b200020033602002000200028020420066a36020420032004410372" + "3602042005410f6a41787141086b2202200320046a22006b2101200241a0" + "a9c000280200460d032002419ca9c000280200460d042002280204220441" + "037141014604402002200441787122041016200120046a2101200220046a" + "220228020421040b20022004417e71360204200020014101723602042000" + "20016a200136020020014180024f04402000200110350c060b200141f801" + "714184a7c0006a2104027f418ca9c0002802002202410120014103767422" + "0171450440418ca9c000200120027236020020040c010b20042802080b21" + "01200420003602082001200036020c2000200436020c200020013602080c" + "050b4198a9c000200020046b220136020041a0a9c00041a0a9c000280200" + "220020046a22023602002002200141017236020420002004410372360204" + "200041086a21000c060b419ca9c00028020021010240200020046b220241" + "0f4d0440419ca9c00041003602004194a9c0004100360200200120004103" + "72360204200020016a220020002802044101723602040c010b4194a9c000" + "2002360200419ca9c000200120046a220336020020032002410172360204" + "200020016a2002360200200120044103723602040b200141086a0f0b2000" + "200520066a36020441a0a9c00041a0a9c0002802002200410f6a41787122" + "0141086b22023602004198a9c000200020016b4198a9c00028020020066a" + "22016a41086a220336020020022003410172360204200020016a41283602" + "0441aca9c00041808080013602000c030b41a0a9c00020003602004198a9" + "c0004198a9c00028020020016a2201360200200020014101723602040c01" + "0b419ca9c00020003602004194a9c0004194a9c00028020020016a220136" + "020020002001410172360204200020016a20013602000b200341086a0f0b" + "410021004198a9c000280200220120044d0d004198a9c000200120046b22" + "0136020041a0a9c00041a0a9c000280200220020046a2202360200200220" + "0141017236020420002004410372360204200041086a0f0b20000bc60602" + "037f037e230041a0026b22032400200341286a41c100104b210420034118" + "6a41f08bc000290300370300200341106a41e88bc0002903003703002003" + "41086a41e08bc00029030037030020034200370320200341d88bc0002903" + "003703000240200241c0004f0440200320024106762205ad370320200320" + "01200510272004200120024140716a2002413f712202104c1a0c010b2004" + "20012002104c1a0b200320023a0068200341f0006a200341f000104c1a20" + "034198016a220120032d00d80122026a22044180013a00002002ad220742" + "3b862003290390012206420986220820074203868422074280fe03834228" + "86842007428080fc0783421886200742808080f80f834208868484200642" + "018642808080f80f832006420f88428080fc0783842006421f884280fe03" + "8320084238888484842106024002402002413f470440200441016a200241" + "3f73104b1a200241387341074b0d010b200341f0006a2001410110272003" + "4190026a420037030020034188026a420037030020034180026a42003703" + "00200341f8016a4200370300200341f0016a4200370300200341e8016a42" + "00370300200342003703e0012003200637039802200341f0006a200341e0" + "016a410110270c010b200320063703d001200341f0006a2001410110270b" + "2000200328028c01220241187420024180fe037141087472200241087641" + "80fe03712002411876727236001c20002003280288012202411874200241" + "80fe03714108747220024108764180fe0371200241187672723600182000" + "200328028401220241187420024180fe03714108747220024108764180fe" + "0371200241187672723600142000200328028001220241187420024180fe" + "03714108747220024108764180fe03712002411876727236001020002003" + "28027c220241187420024180fe03714108747220024108764180fe037120" + "02411876727236000c20002003280278220241187420024180fe03714108" + "747220024108764180fe0371200241187672723600082000200328027422" + "0241187420024180fe03714108747220024108764180fe03712002411876" + "727236000420002003280270220241187420024180fe0371410874722002" + "4108764180fe037120024118767272360000200341a0026a24000bee0201" + "077f024020012802042202450440410021020c010b200128021021062001" + "200220022001280208220320022003491b22046b36020420012001280200" + "220720046a360200027f0240024002400240027f02400240024020030440" + "200128020c2208410174210520072d0000220241c1006b41ff0171410649" + "0d01200241e1006b41ff01714106490d02200241306b220341ff0171410a" + "490d0320050c040b4100410041848bc0001010000b200241376b21030c01" + "0b200241d7006b21030b20044101460d0320072d0001220241c1006b41ff" + "01714106490d01200241e1006b41ff01714106490d02200241306b220441" + "ff0171410a490d0420054101720b21032006200241ff0171360200200620" + "0541807e71200341ff01717236020441000c040b200241376b21040c020b" + "200241d7006b21040c010b4101410141948bc0001010000b200420034104" + "7472210341010b21022001200841016a36020c0b200020033a0001200020" + "023a00000bb40801057f200041086b2201200041046b2802002203417871" + "22006a21020240024020034101710d002003410271450d01200128020022" + "0320006a2100200120036b2201419ca9c000280200460440200228020441" + "03714103470d014194a9c000200036020020022002280204417e71360204" + "20012000410172360204200220003602000f0b2001200310160b02400240" + "0240024002400240024020022802042203410271450440200241a0a9c000" + "280200460d022002419ca9c000280200460d032002200341787122031016" + "2001200020036a2200410172360204200020016a20003602002001419ca9" + "c000280200470d014194a9c00020003602000f0b20022003417e71360204" + "20012000410172360204200020016a20003602000b2000418002490d0241" + "1f210220014200370210200041ffffff074d044020004106200041087667" + "22026b7641017120024101746b413e6a21020b2001200236021c20024102" + "7441f4a5c0006a2103410120027422044190a9c000280200710d03200320" + "01360200200120033602182001200136020c200120013602084190a9c000" + "4190a9c0002802002004723602000c040b41a0a9c00020013602004198a9" + "c0004198a9c00028020020006a220036020020012000410172360204419c" + "a9c00028020020014604404194a9c0004100360200419ca9c00041003602" + "000b200041aca9c00028020022044d0d0541a0a9c0002802002200450d05" + "410021034198a9c00028020022054129490d0441f4a6c000210103402000" + "200128020022024f04402000200220012802046a490d060b200128020821" + "010c000b000b419ca9c00020013602004194a9c0004194a9c00028020020" + "006a220036020020012000410172360204200020016a20003602000f0b20" + "0041f801714184a7c0006a2102027f418ca9c00028020022034101200041" + "037674220071450440418ca9c000200020037236020020020c010b200228" + "02080b2100200220013602082000200136020c2001200236020c20012000" + "3602080f0b02400240200020032802002204280204417871460440200421" + "020c010b2000411920024101766b41002002411f471b7421030340200420" + "03411d764104716a41106a22052802002202450d02200341017421032002" + "210420022802044178712000470d000b0b20022802082200200136020c20" + "022001360208200141003602182001200236020c200120003602080c010b" + "20052001360200200120043602182001200136020c200120013602080b41" + "00210141b4a9c00041b4a9c00028020041016b220036020020000d0141fc" + "a6c000280200220004400340200141016a2101200028020822000d000b0b" + "41b4a9c00041ff1f2001200141ff1f4d1b3602000f0b41fca6c000280200" + "220104400340200341016a2103200128020822010d000b0b41b4a9c00041" + "ff1f2003200341ff1f4d1b360200200420054f0d0041aca9c000417f3602" + "000b0b810802077f067e230041c0026b2203240020034198026a20024118" + "6a290300220a37030020034190026a200241106a290300220d3703002003" + "200241086a290300220b3703880220032002290300220c3703800242ddb0" + "858ce8b691a8b87f210e20034180026a200c200b200d200a42c7faf3c3ed" + "82a3903c428d95c7c396d2dac0977f102b200341b0026a2204200141106a" + "290300220a370300200341b8026a2205200141186a290300220d37030020" + "032001290300220b3703a0022003200141086a290300220c3703a8022003" + "41a0026a200b200c200a200d42c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f102b200341a0026a200b200c200a200d42c7faf3c3ed82a3903c42" + "8d95c7c396d2dac0977f102b02400240024020032903a002220a42037c22" + "0c200a54ad220a20032903a8027c220b200a54ad220a20042903007c220d" + "42ddb0858ce8b691a8b87f852005290300200a200d56ad7c220a42a9c0c6" + "89aece93b2308584500440200c42c7faf3c3ed82a3903c54200b428d95c7" + "c396d2dac0977f54200b428d95c7c396d2dac0977f511b450d0242a9c0c6" + "89aece93b230210a0c010b200d42deb0858ce8b691a8b87f54200a42a9c0" + "c689aece93b23054200a42a9c0c689aece93b230511b450d01200d210e0b" + "200c210f200b210c0c010b200a200d200b200c42c7faf3c3ed82a3903c7d" + "220f200c5aad220e7d220a42f3eab8bce9ada5bfe8007c220c200a54ad20" + "0b200e54ad7d7c220b200d54ad200b42a2cffaf397c9eed7c7007c220e20" + "0b54ad7c50ad7d42a9c0c689aece93b2307d210a0b2003200e3703b00120" + "03200f3703a0012003200a3703b8012003200c3703a8012000027f200341" + "80026a200341a0016a104a45044020034180016a22042002290300370100" + "20034198016a2205200241186a29030037010020034190016a2206200241" + "106a29030037010020034188016a2207200241086a290300370100200341" + "f8006a2202200141186a290300370100200341f0006a2208200141106a29" + "0300370100200341e8006a2209200141086a290300370100200320012903" + "00370160200341ca006a22012005290100370100200341c2006a22052006" + "2901003701002003413a6a22062007290100370100200341326a22072004" + "2901003701002003412a6a22042002290100370100200341226a22022008" + "2901003701002003411a6a22082009290100370100200320032901603701" + "12200041c8006a2001290100370100200041406b20052901003701002000" + "41386a2006290100370100200041306a2007290100370100200041286a20" + "04290100370100200041206a2002290100370100200041186a2008290100" + "3701002000200329011237011041000c010b200041003a000141010b3a00" + "00200341c0026a24000baa0401047e2001290010220242388620024280fe" + "0383422886842002428080fc0783421886200242808080f80f8342088684" + "84200242088842808080f80f832002421888428080fc0783842002422888" + "4280fe038320024238888484842104200141186a29000022024238862002" + "4280fe0383422886842002428080fc0783421886200242808080f80f8342" + "08868484200242088842808080f80f832002421888428080fc0783842002" + "4228884280fe0383200242388884848421050240417f2001290000220242" + "b0c8b99297bc8cd02985200141086a290000220342b8a195b29bb0a0acdd" + "008584420052200342388620034280fe0383422886842003428080fc0783" + "421886200342808080f80f834208868484200342088842808080f80f8320" + "03421888428080fc07838420034228884280fe0383200342388884848422" + "0342ddb0858ce8b691a8b87f54200242388620024280fe03834228868420" + "02428080fc0783421886200242808080f80f834208868484200242088842" + "808080f80f832002421888428080fc07838420024228884280fe03832002" + "423888848484220242a9c0c689aece93b23054200242a9c0c689aece93b2" + "30511b1b2201417f470440200141ff01710d01200542c6faf3c3ed82a390" + "3c562004428d95c7c396d2dac0977f562004428d95c7c396d2dac0977f51" + "1b0d010b2000200337032020002005370310200020023703282000200437" + "0318200041003a00000f0b200041023a0001200041013a00000bb40c0204" + "7f027e230041d0066b2203240020034188036a200241386a290300370300" + "20034180036a200241306a290300370300200341f8026a200241286a2903" + "00370300200341f0026a2204200241206a290300370300200341e8026a20" + "0241186a290300370300200341e0026a200241106a290300370300200320" + "022903003703d0022003200241086a2903003703d802200341d0026a2002" + "2002102f200341a0036a200141106a290300370300200341a8036a200141" + "186a290300370300200341b0036a200141206a290300370300200341b803" + "6a200141286a290300370300200341c0036a200141306a29030037030020" + "0341c8036a200141386a2903003703002003200129030037039003200320" + "0141086a2903003703980320034190036a20012001102f200341d0006a20" + "034190036a2001102f200342d4fdc3d783f6c4cb003703c805200342f4fb" + "e3f6def5ab964d3703c005200342d2b0b4a9ce90e8a7a77f3703b8052003" + "42d2ab8caee8a0afd1643703b005200342aed5e2f58ca8a78a2b3703a805" + "200342c3d581df919386df817f3703a005200342a3dfefced5bcb1dab57f" + "37039805200342e5f184a5c2dbf9b33237039005200341106a200341d000" + "6a20034190056a103002400240200341d0026a200341106a104a45044020" + "04200341306a104a450d010b200041013b01000c010b200341c8026a4200" + "370300200341c0026a4200370300200341b8026a4200370300200341b002" + "6a4200370300200341a8026a4200370300200341a0016a200141106a2903" + "00370300200341a8016a200141186a290300370300200341b0016a200141" + "206a290300370300200341b8016a200141286a290300370300200341c001" + "6a200141306a290300370300200341c8016a200141386a29030037030020" + "0342003703a00220032001290300370390012003200141086a2903003703" + "980120034188026a200241386a29030037030020034180026a200241306a" + "290300370300200341f8016a200241286a290300370300200341f0016a20" + "0241206a290300370300200341e8016a200241186a290300370300200341" + "e0016a200241106a290300370300200341d8016a200241086a2903003703" + "0020034201370390022003420037039802200320022903003703d0012003" + "41e0036a4200370300200341e8036a4200370300200341f0036a42003703" + "00200341f8036a420037030020034180046a420037030020034188046a42" + "00370300200342003703d003200342003703d803200342a9c0c689aece93" + "b230370368200342ddb0858ce8b691a8b87f37036020034291e1e5cd8789" + "fa992837035820034280808080bfb2fdf0c300370350200341a0046a41f0" + "00104b1a2003420037039804200342013703900441ff0121040340200320" + "0441ff0071104f200341086a290300200341d0006a200441037641f0ffff" + "ff01716a2206290308832107200329030020062903008321082005044020" + "034190056a200341d0036a1043200341d0036a20034190056a41c001104c" + "1a0b2007200884420052044020034190056a200341d0036a20034190016a" + "1044200341d0036a20034190056a41c001104c1a410121050b200441016b" + "2204417f470d000b20034190056a200341d0036a20034190016a10440240" + "20032903900620034198066a290300844200520d0020032903a006200341" + "a8066a290300844200520d0020032903b006200341b8066a290300844200" + "520d0020032903c006200341c8066a290300844200520d00200341c8056a" + "200141386a290300370300200341c0056a200141306a2903003703002003" + "41b8056a200141286a290300370300200341b0056a200141206a29030037" + "0300200341a8056a200141186a290300370300200341a0056a200141106a" + "290300370300200341d8056a200241086a290300370300200341e0056a20" + "0241106a290300370300200341e8056a200241186a290300370300200341" + "f0056a200241206a290300370300200341f8056a200241286a2903003703" + "0020034180066a200241306a29030037030020034188066a200241386a29" + "03003703002003200129030037039005200320022903003703d005200320" + "0141086a29030037039805200041106a20034190056a418001104c1a2000" + "41003a00000c010b20004181023b01000b200341d0066a24000ba8150207" + "7f137e230041a0016b22022400200241106a2001102a20022d0011210620" + "022d001021072000027f024020022d0030220841c101470440200235011a" + "2109200233011e210a2002290112211620022903202114200241d8006a22" + "01200241286a29030022173703002002201437035020022009200a422086" + "842219421086201642308884220937034820022007ad42ff018320164210" + "862006ad42ff01834208868484220a37034042ddb0858ce8b691a8b87f21" + "0f200241406b200a20092014201742c7faf3c3ed82a3903c428d95c7c396" + "d2dac0977f102b200241406b200a20092014201742c7faf3c3ed82a3903c" + "428d95c7c396d2dac0977f102b0240024002402002290340220942037c22" + "0b200954ad220920022903487c220a200954ad220c20022903507c220942" + "ddb0858ce8b691a8b87f8520012903002009200c54ad7c220e42a9c0c689" + "aece93b2308584500440200b42c7faf3c3ed82a3903c54200a428d95c7c3" + "96d2dac0977f54200a428d95c7c396d2dac0977f511b450d0242a9c0c689" + "aece93b230210e0c010b200942deb0858ce8b691a8b87f54200e42a9c0c6" + "89aece93b23054200e42a9c0c689aece93b230511b450d012009210f0b20" + "0b2110200a210d0c010b200e2009200a200b42c7faf3c3ed82a3903c7d22" + "10200b5aad220b7d220c42f3eab8bce9ada5bfe8007c220d200c54ad200a" + "200b54ad7d7c220a200954ad200a42a2cffaf397c9eed7c7007c220f200a" + "54ad7c50ad7d42a9c0c689aece93b2307d210e0b4190aac0002d00004102" + "470440230041e0006b220324004190aac0004190aac0002d000022044101" + "20041b3a00000240200404400340024002400240200441ff017141016b0e" + "03000501020b03404190aac0002d000022044101460d000b024002402004" + "41016b0e03000601030b000b41a49bc000412641cc9bc0001011000b41a8" + "9ac000410d41949bc0001011000b4190aac0004190aac0002d0000220441" + "0120041b3a000020040d000b0b200341186a220442a9c0c689aece93b230" + "370300200341106a220542ddb0858ce8b691a8b87f3703002003428d95c7" + "c396d2dac0977f370308200342c4faf3c3ed82a3903c370300200341386a" + "220142003703002003420037033020034200370328200342043703202003" + "42a9c0c689aece93b230370358200342ddb0858ce8b691a8b87f37035020" + "03428d95c7c396d2dac0977f370348200342c7faf3c3ed82a3903c370340" + "200341206a200341406b103a200320032903202003290328200329033020" + "0129030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b4190aa" + "c00041023a00004188aac00020042903003703004180aac0002005290300" + "37030041f8a9c000200329030837030041f0a9c00020032903003703000b" + "200341e0006a24000b20024198016a4188aac00029030037030020024190" + "016a4180aac000290300370300200241f8a9c00029030037038801200241" + "f0a9c00029030037038001420021094201210a41ff0121014200210b4200" + "210c0340200220024180016a200141037641f0ffffff01716a2205290300" + "2005290308200141ff0071104e200241286a2205200b3703002002200937" + "03202002200c3703182002200a370310200241106a200a200c2009200b42" + "c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b2005290300210b20" + "0229032021092002290318210c2002290310210a20022802004101710440" + "2005200b370300200220093703202002200a3703102002200c3703182002" + "41106a2010200d200f200e42c7faf3c3ed82a3903c428d95c7c396d2dac0" + "977f102b2005290300210b2002290318210c200229032021092002290310" + "210a0b200141016b2201417f470d000b200241286a2201200b3703002002" + "20093703202002200c3703182002200a370310200241106a2010200d200f" + "200e42c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b2002200b37" + "0378200220093703702002200c3703682002200a370360200241e0006a20" + "02290310220e2002290318220b2002290320220c2001290300220a42c7fa" + "f3c3ed82a3903c428d95c7c396d2dac0977f102b41e0a9c0002d00004102" + "470440102c0b20024198016a41d8a9c00029030037030020024190016a41" + "d0a9c000290300370300200241c8a9c00029030037038801200241c0a9c0" + "002903003703800141e0a9c0002d00004102470440102c0b20024180016a" + "420142004200420041c0a9c00029030041c8a9c00029030041d0a9c00029" + "030041d8a9c000290300102d2002290388012110200229038001210d0240" + "0240417f200229039001220f42ddb0858ce8b691a8b87f8520024198016a" + "290300220942a9c0c689aece93b2308584420052200f42ddb0858ce8b691" + "a8b87f54200942a9c0c689aece93b23054200942a9c0c689aece93b23051" + "1b1b2201417f470440200141ff01710d01200d42c7faf3c3ed82a3903c54" + "2010428d95c7c396d2dac0977f542010428d95c7c396d2dac0977f511b45" + "0d010b2002200f3703202002200d37031020022009370328200220103703" + "18027e0240200241e0006a200241106a104a0440420021104200210f4200" + "2109200c200e84200a200b8484420052044042c7faf3c3ed82a3903c200e" + "7d2115427f4200427f4200200e42788342c7faf3c3ed82a3903c561b2209" + "2009200b54ad7d2009200b7d220942f3eab8bce9ada5bfe8007d22102009" + "54ad7c42017c2209200c7d220d42a4cffaf397c9eed7c7007d220f200d54" + "ad2009200c54ad7d427f511b200a7d42a9c0c689aece93b2307c21090b20" + "0e201554200b201054200b2010511b200c200f542009200a562009200a51" + "1b200c200f852009200a8584221b501b4101460d0120152111200f211220" + "09210d200e211a200b2118200c210f200a210920100c020b200041033a00" + "010c050b200e2111200c2112200a210d2015211a20102118200b0b211302" + "40024002400240417f201b420052200f2012562009200d562009200d511b" + "1b2201047f2001052011201a54201320185420132018511b0d01200e2015" + "85200b201085844200520b4101460d010b200841c001470d014200210942" + "00210a4200210b4200210c2011201284200d20138484500d04427f420042" + "7f4200201142788342c7faf3c3ed82a3903c561b22092009201354ad7d20" + "0920137d220942f3eab8bce9ada5bfe8007d220a200954ad7c42017c2209" + "20127d220c42a4cffaf397c9eed7c7007d220b200c54ad2009201254ad7d" + "427f511b200d7d42a9c0c689aece93b2307c210c42c7faf3c3ed82a3903c" + "20117d21090c040b2008418001460d010b201121092013210a2012210b20" + "0d210c0c020b420021094200210a4200210b4200210c2011201284200d20" + "138484500d01427f4200427f4200201142788342c7faf3c3ed82a3903c56" + "1b22092009201354ad7d200920137d220942f3eab8bce9ada5bfe8007d22" + "0a200954ad7c42017c220920127d220c42a4cffaf397c9eed7c7007d220b" + "200c54ad2009201254ad7d427f511b200d7d42a9c0c689aece93b2307c21" + "0c42c7faf3c3ed82a3903c20117d21090c010b41e09dc0001020000b2000" + "2014370320200020163701122000200b3703402000200937033020002006" + "3a0011200020073a0010200020193e011a200020173703282000200c3703" + "482000200a3703382000411e6a20194220883d010041000c020b20002006" + "3a0002200020073a00010b41010b3a0000200241a0016a24000ba02f0208" + "7f187e230041c0086b22022400200241f0046a2001102a20022d00f10421" + "0620022d00f0042107024002400240024020022d009005220941c1014704" + "4020024198016a220520022901fa04370300200241a6016a220420024188" + "056a2203290100370100200241a0016a220820024182056a290100370300" + "200220022901f20437039001200241f0046a200141206a102e20022d00f0" + "04450440200241d5076a2003290300220c37000020024188016a20024198" + "056a290300220b37030020024180016a20024190056a290300220a370300" + "200241c8006a200b370300200241406b200a370300200220022903800522" + "0b3703702002200c3703782002200b3703302002200c370338200220063a" + "0051200220073a0050200241e8006a22012004290100370100200241e200" + "6a2008290300370100200241da006a200529030037010020022002290390" + "01370152200941c000460d0220024180026a200241406b29030037030020" + "024188026a200241c8006a29030037030020024190026a200241d0006a29" + "030037030020024198026a200241d8006a290300370300200241a0026a20" + "0241e0006a290300370300200241a8026a20012903003703002002200229" + "03303703f001200220022903383703f801200241f0016a200241306a2002" + "41306a102f20024180086a200241f0016a200241306a102f200242d4fdc3" + "d783f6c4cb003703a805200242f4fbe3f6def5ab964d3703a005200242d2" + "b0b4a9ce90e8a7a77f37039805200242d2ab8caee8a0afd1643703900520" + "0242aed5e2f58ca8a78a2b37038805200242c3d581df919386df817f3703" + "8005200242a3dfefced5bcb1dab57f3703f804200242e5f184a5c2dbf9b3" + "323703f004200241b0016a20024180086a200241f0046a103041f0aac000" + "2d00004102470440230041e0006b2203240041f0aac00041f0aac0002d00" + "002204410120041b3a00000240200404400340024002400240200441ff01" + "7141016b0e03000501020b034041f0aac0002d000022044101460d000b02" + "400240200441016b0e03000601030b000b41a49bc000412641cc9bc00010" + "11000b41a89ac000410d41949bc0001011000b41f0aac00041f0aac0002d" + "00002204410120041b3a000020040d000b0b200341186a220442a9c0c689" + "aece93b230370300200341106a220842ddb0858ce8b691a8b87f37030020" + "03428d95c7c396d2dac0977f370308200342c4faf3c3ed82a3903c370300" + "200341386a22014200370300200342003703302003420037032820034204" + "370320200342a9c0c689aece93b230370358200342ddb0858ce8b691a8b8" + "7f3703502003428d95c7c396d2dac0977f370348200342c7faf3c3ed82a3" + "903c370340200341206a200341406b103a20032003290320200329032820" + "03290330200129030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f" + "102b41f0aac00041023a000041e8aac000200429030037030041e0aac000" + "200829030037030041d8aac000200329030837030041d0aac00020032903" + "003703000b200341e0006a24000b200241c8046a41e8aac0002903003703" + "00200241c0046a41e0aac000290300370300200241d8aac0002903003703" + "b804200241d0aac0002903003703b0044200210c4201210b41ff01210120" + "0241a8076a2104200241b8076a21034200210a0340200241206a200241b0" + "046a200141037641f0ffffff01716a22052903002005290308200141ff00" + "71104e2002200a3703f8072002200c3703f0072002200f3703e807200220" + "0e3703e0072002200d3703d807200220103703d007200220113703c80720" + "02200b3703c0072002200a3703b8082002200c3703b0082002200f3703a8" + "082002200e3703a0082002200d3703980820022010370390082002201137" + "0388082002200b370380082002280220210520024180076a200241c0076a" + "20024180086a102f20024198076a290300210d2004290300210f20032903" + "00210a2002290388072111200229038007210b2002290390072110200229" + "03a007210e20022903b007210c200541017104402002200a3703b8082002" + "200c3703b0082002200f3703a8082002200e3703a0082002200d37039808" + "200220103703900820022011370388082002200b37038008200241c0076a" + "20024180086a200241b0016a102f200241e8076a290300210f200241f807" + "6a290300210a20022903c007210b20022903d007211020022903e007210e" + "20022903f007210c20022903c8072111200241d8076a290300210d0b2001" + "41016b2201417f470d000b2002200c3703e0022002200e3703d002200220" + "103703c0022002200b3703b0022002200a3703e8022002200f3703d80220" + "02200d3703c802200220113703b802200241f0026a200241b0026a200241" + "b0016a102f200241b0036a200241b0026a200241f0026a102f41c0aac000" + "2d0000410247044041c0aac00041c0aac0002d00002201410120011b3a00" + "000240200104400340024002400240200141016b0e03000501020b034041" + "c0aac0002d000022014101460d000b02400240200141016b0e0300060103" + "0b000b41a49bc000412641cc9bc0001011000b41a89ac000410d41949bc0" + "001011000b41c0aac00041c0aac0002d00002201410120011b3a00002001" + "0d000b0b41b8aac00042a9c0c689aece93b23037030041b0aac00042ddb0" + "858ce8b691a8b87f37030041a8aac000428d95c7c396d2dac0977f370300" + "41a0aac00042c7faf3c3ed82a3903c37030041c0aac00041023a00000b0b" + "200241d8066a41b8aac000290300370300200241d0066a41b0aac0002903" + "00370300200241a8aac0002903003703c806200241a0aac0002903003703" + "c0064200210c4201210b41ff012101200241a8076a2104200241b8076a21" + "034200210a4200210e4200210f420021104200210d420021110340200241" + "106a200241c0066a200141037641f0ffffff01716a220529030020052903" + "08200141ff0071104e2002200a3703f8072002200c3703f0072002200f37" + "03e8072002200e3703e0072002200d3703d807200220103703d007200220" + "113703c8072002200b3703c0072002200a3703b8082002200c3703b00820" + "02200f3703a8082002200e3703a0082002200d3703980820022010370390" + "0820022011370388082002200b370380082002280210210520024180076a" + "200241c0076a20024180086a102f20024198076a290300210d2004290300" + "210f2003290300210a2002290388072111200229038007210b2002290390" + "07211020022903a007210e20022903b007210c200541017104402002200a" + "3703b8082002200c3703b0082002200f3703a8082002200e3703a0082002" + "200d37039808200220103703900820022011370388082002200b37038008" + "200241c0076a20024180086a200241b0036a102f200241e8076a29030021" + "0f200241f8076a290300210a20022903c007210b20022903d00721102002" + "2903e007210e20022903f007210c20022903c8072111200241d8076a2903" + "00210d0b200141016b2201417f470d000b2002200c3703b0082002200e37" + "03a00820022010370390082002200b370380082002200a3703b808200220" + "0f3703a8082002200d370398082002201137038808200241f0036a200241" + "80086a200241b0036a102f200241a8086a22014200370300200241b0086a" + "22054200370300200241b8086a22044200370300200242a9c0c689aece93" + "b23037039808200242ddb0858ce8b691a8b87f370390082002428d95c7c3" + "96d2dac0977f37038808200242c6faf3c3ed82a3903c3703800820024200" + "3703a008200241a0086a21030240200241f0036a20024180086a104a4504" + "4020024190046a2003104a450d010b200142003703002005420037030020" + "044200370300200242a9c0c689aece93b23037039808200242ddb0858ce8" + "b691a8b87f370390082002428d95c7c396d2dac0977f37038808200242c6" + "faf3c3ed82a3903c37038008200242003703a008200241b0036a20024180" + "086a104a450440200241d0036a2003104a450d050b4200210c2002419808" + "6a4200370300200241a0086a4200370300200241a8086a42003703002002" + "41b0086a4200370300200241b8086a420037030020024200370388084201" + "210b20024201370380082002420037039008200241c0066a200241b0036a" + "20024180086a103041a0abc0002d00004102470440230041e0006b220324" + "0041a0abc00041a0abc0002d00002204410120041b3a0000024020040440" + "0340024002400240200441ff017141016b0e03000501020b034041a0abc0" + "002d000022044101460d000b02400240200441016b0e03000601030b000b" + "41a49bc000412641cc9bc0001011000b41a89ac000410d41949bc0001011" + "000b41a0abc00041a0abc0002d00002204410120041b3a000020040d000b" + "0b200341186a220442a9c0c689aece93b230370300200341106a220842dd" + "b0858ce8b691a8b87f3703002003428d95c7c396d2dac0977f3703082003" + "42c6faf3c3ed82a3903c370300200341386a220142003703002003420037" + "03302003420037032820034202370320200342a9c0c689aece93b2303703" + "58200342ddb0858ce8b691a8b87f3703502003428d95c7c396d2dac0977f" + "370348200342c7faf3c3ed82a3903c370340200341206a200341406b103a" + "2003200329032020032903282003290330200129030042c7faf3c3ed82a3" + "903c428d95c7c396d2dac0977f102b41a0abc00041023a00004198abc000" + "20042903003703004190abc00020082903003703004188abc00020032903" + "083703004180abc00020032903003703000b200341e0006a24000b200241" + "e8046a4198abc000290300370300200241e0046a4190abc0002903003703" + "0020024188abc0002903003703d80420024180abc0002903003703d00441" + "ff012101200241a8076a2104200241b8076a21034200210a4200210e4200" + "210f420021104200210d4200211103402002200241d0046a200141037641" + "f0ffffff01716a22052903002005290308200141ff0071104e2002200a37" + "03f8072002200c3703f0072002200f3703e8072002200e3703e007200220" + "0d3703d807200220103703d007200220113703c8072002200b3703c00720" + "02200a3703b8082002200c3703b0082002200f3703a8082002200e3703a0" + "082002200d37039808200220103703900820022011370388082002200b37" + "0380082002280200210520024180076a200241c0076a20024180086a102f" + "20024198076a290300210d2004290300210f2003290300210a2002290388" + "072111200229038007210b200229039007211020022903a007210e200229" + "03b007210c200541017104402002200a3703b8082002200c3703b0082002" + "200f3703a8082002200e3703a0082002200d370398082002201037039008" + "20022011370388082002200b37038008200241c0076a20024180086a2002" + "41c0066a102f200241e8076a290300210f200241f8076a290300210a2002" + "2903c007210b20022903d007211020022903e007210e20022903f007210c" + "20022903c8072111200241d8076a290300210d0b200141016b2201417f47" + "0d000b2002200c3703b0062002200e3703a0062002201037039006200220" + "0b370380062002200a3703b8062002200f3703a8062002200d3703980620" + "0220113703880620024180056a20024180066a200241f0026a102f0c050b" + "20004181063b01000c050b200020022d00f1043a0002200041810a3b0100" + "0c040b200020063a0002200020073a0001200041013a00000c030b200241" + "f8066a4200370300200241f0066a4200370300200241e8066a4200370300" + "200241e0066a4200370300200241d8066a4200370300200242003703d006" + "200242003703c806200242013703c006200242ba90b590b9f2a4c7193703" + "f807200242a5baed8ff3f6afb0f2003703f00720024292cea7adb3a692d5" + "713703e807200242c2a5ccf7fab6a1f2977f3703e007200242f6bcfc90f1" + "ddb780183703d807200242f988f1f2e58c80b5c2003703d007200242ddb5" + "fbbacfdac8a1e7003703c807200242ededcbcccdabafefc6003703c00720" + "0241f0046a200241c0066a10310240024020022802f00441017104402002" + "41b8086a2201200241b8056a2205290300370300200241b0086a200241b0" + "056a2204290300370300200241a8086a2203200241a8056a220629030037" + "0300200241a0086a200241a0056a29030037030020024198086a20024198" + "056a220729030037030020024190086a20024190056a2903003703002002" + "20022903800537038008200220024188056a290300370388082002418006" + "6a200241c0076a20024180086a102f200242f5e0ffc285baa283093703f8" + "0720024295e7b0c8d6b5a6cf6c3703f007200242f39dce85b7a6cca5bc7f" + "3703e807200242dbae8a89cddbb6d6d5003703e007200242ebdbb1dcddd4" + "97e4123703d8072002428f81adee88b0dcd5ca003703d007200242fba68f" + "e290edf9e8633703c807200242aafbe9b79680b3f3cc003703c007200241" + "f0046a200241c0066a103120022802f004410171450d0120012005290300" + "370300200241b0086a200429030037030020032006290300370300200241" + "a0086a200241a0056a29030037030020024198086a200729030037030020" + "024190086a20024190056a29030037030020022002290380053703800820" + "0220024188056a2903003703880820024180076a200241c0076a20024180" + "086a102f200241f0046a20024180066a20024180076a100720022d00f004" + "4101460d02200041106a20024180056a418001104c1a200041003a00000c" + "050b41f09dc000412c41989fc0001021000b41f09dc000412c41989fc000" + "1021000b200220022d00f1043a00800841b89cc000412b20024180086a41" + "a89fc00041b4a0c0001013000b20024198086a420037030020024190086a" + "4200370300200242003703b808200242003703b008200242003703a80820" + "0242013703a0082002420037038808200242003703800820024180056a20" + "024180086a200241f0026a102f0b200241a8056a290300210e200241b805" + "6a290300210c20022903a005210f20022903b005210b200229039005220d" + "20022903800522158420024198056a290300221220024188056a29030022" + "1384844200520440427f4200427f4200201542788342c7faf3c3ed82a390" + "3c561b220a200a201354ad7d200a20137d220a42f3eab8bce9ada5bfe800" + "7d2217200a54ad7c42017c220a200d7d221042a4cffaf397c9eed7c7007d" + "2218201054ad200a200d54ad7d427f511b20127d42a9c0c689aece93b230" + "7c211642c7faf3c3ed82a3903c20157d21190b4200211142002110420021" + "0a200b200f84200c200e84844200520440427f4200427f4200200f427883" + "42c7faf3c3ed82a3903c561b220a200a200e54ad7d200a200e7d220a42f3" + "eab8bce9ada5bfe8007d2211200a54ad7c42017c220a200b7d221442a4cf" + "faf397c9eed7c7007d2210201454ad200a200b54ad7d427f511b200c7d42" + "a9c0c689aece93b2307c210a42c7faf3c3ed82a3903c200f7d21140b0240" + "0240417f200b201085200a200c8584420052200b201054200a200c56200a" + "200c511b1b2201450440200f201454200e201154200e2011511b0d01200f" + "201485200e2011858442005221010b2019211c2017211d2018211a201621" + "1b2014211e2011211f20102120200a21210240200141ff01710e02000201" + "0b027e200d20188520122016858450044020152019542013201754201320" + "17511b0d02200d211a20120c010b200d20185a201220165a20122016511b" + "450d0120160b211b0c010b2015211c2013211d200d211a2012211b200f21" + "1e200e211f200b2120200c212120192115201721132018210d2016211220" + "14210f2011210e2010210b200a210c0b200041186a200229037837030020" + "0020022903703703102000200229039001370132200041286a2002418801" + "6a290300370300200041206a20024180016a2903003703002000413a6a20" + "024198016a290300370100200041c2006a200241a0016a29030037010020" + "0041c8006a200241a6016a29010037010020094180014604402000202037" + "0380012000201e3703702000201a3703602000201c370350200020063a00" + "31200020073a0030200041003a000020002021370388012000201f370378" + "2000201b3703682000201d3703580c010b2000200b370380012000200f37" + "03702000200d37036020002015370350200020063a0031200020073a0030" + "200041003a00002000200c370388012000200e3703782000201237036820" + "0020133703580b200241c0086a24000b9f0602027f0c7e23004180016b22" + "022400200241386a4200370300200241306a4200370300200241286a4200" + "370300200241206a22034200370300200241186a4200370300200241106a" + "4200370300200241d8006a4200370300200241e0006a4200370300200241" + "e8006a4200370300200241f0006a4200370300200241f8006a4200370300" + "200242003703482002420137034020024200370308200242003703002002" + "420037035002400240024020012002104a0d00200141206a2003104a0d00" + "200141406b200241406b104a0d00200141e0006a200241e0006a104a450d" + "010b200141f8006a290300210e200141e8006a2903002106200129037021" + "0c2001290360210d200129035022042001290340220884200141d8006a29" + "0300220b200141c8006a290300220984844200520440427f4200427f4200" + "200842788342c7faf3c3ed82a3903c561b22052005200954ad7d20052009" + "7d220542f3eab8bce9ada5bfe8007d220f200554ad7c42017c220a20047d" + "220742a4cffaf397c9eed7c7007d2205200754ad2004200a56ad7d427f51" + "1b200b7d42a9c0c689aece93b2307c210a42c7faf3c3ed82a3903c20087d" + "21070b4200210442002108420021094200210b200c200d842006200e8484" + "4200520440427f4200427f4200200d42788342c7faf3c3ed82a3903c561b" + "22042004200654ad7d200420067d220642f3eab8bce9ada5bfe8007d2208" + "200654ad7c42017c2206200c7d220442a4cffaf397c9eed7c7007d220920" + "0454ad2006200c54ad7d427f511b200e7d42a9c0c689aece93b2307c210b" + "42c7faf3c3ed82a3903c200d7d21040b2000200937037020002004370360" + "20002005370350200020073703402000200b370378200020083703682000" + "200a3703582000200f37034820002001290300370300200041386a200141" + "386a290300370300200041306a200141306a290300370300200041286a20" + "0141286a290300370300200041206a200141206a29030037030020004118" + "6a200141186a290300370300200041106a200141106a2903003703002000" + "41086a200141086a2903003703000c010b20002001418001104c1a0b2002" + "4180016a24000bc10201067f41102000410b6a4178712000410b491b2204" + "411c6a1001220045044041000f0b200041086b210102402000410f714504" + "40200121000c010b200041046b220528020022064178712000410f6a4170" + "7141086b2200200020016b4111494104746a220020016b22026b21032006" + "410371044020002003200028020441017172410272360204200020036a22" + "032003280204410172360204200520022005280200410171724102723602" + "00200120026a220320032802044101723602042001200210170c010b2001" + "2802002101200020033602042000200120026a3602000b02402000280204" + "2201410371450d0020014178712202200441106a4d0d0020002004200141" + "017172410272360204200020046a2201200220046b220441037236020420" + "0020026a220220022802044101723602042001200410170b200041086a0b" + "de0a01047f230041f0026b22032400200341a8026a220442003703002003" + "41a0026a22054200370300200342003703c802200342003703c002200342" + "003703b802200342013703b0022003420037039802200342003703900220" + "0341b0026a21060240024002400240200120034190026a104a4504402001" + "41206a2006104a450d010b20044200370300200542003703002003420037" + "03c802200342003703c002200342003703b802200342013703b002200342" + "00370398022003420037039002200220034190026a104a45044020024120" + "6a2006104a450d020b200341206a2104200341406b2105200341a8026a42" + "00370300200341a0026a4200370300200342003703c802200342003703c0" + "02200342003703b802200342013703b00220034200370398022003420037" + "039002027f0240200120034190026a104a450440200141206a200341b002" + "6a104a450d010b20042001290320370300200441186a200141386a290300" + "370300200441106a200141306a290300370300200441086a200141286a29" + "0300370300200341106a200141106a290300370300200341186a20014118" + "6a290300370300200320012903003703002003200141086a290300370308" + "200341d0006a0c010b20054200370300200341106a420037030020034118" + "6a4200370300200541086a4200370300200541106a420037030020054118" + "6a4200370300200342003703002003420037030820042105200341306a0b" + "210620034180016a2101200341a0016a2104200642003703082006420037" + "03002005420037030820054201370300200341a8026a4200370300200341" + "a0026a4200370300200342003703c802200342003703c002200342003703" + "b802200342013703b00220034200370398022003420037039002027f0240" + "200220034190026a104a450440200241206a200341b0026a104a450d010b" + "20012002290320370300200141186a200241386a29030037030020014110" + "6a200241306a290300370300200141086a200241286a2903003703002003" + "41f0006a200241106a290300370300200341f8006a200241186a29030037" + "0300200320022903003703602003200241086a290300370368200341b001" + "6a0c010b20044200370300200341f0006a4200370300200341f8006a4200" + "370300200441086a4200370300200441106a4200370300200441186a4200" + "37030020034200370360200342003703682001210420034190016a0b2205" + "420037030820054200370300200442003703082004420137030020034190" + "026a2003200341e0006a1040200341c0016a20034190026a104120032802" + "c001410171450d02200020032903d001370300200041386a20034188026a" + "290300370300200041306a20034180026a290300370300200041286a2003" + "41f8016a290300370300200041206a200341f0016a290300370300200041" + "186a200341e8016a290300370300200041106a200341e0016a2903003703" + "00200041086a200341d8016a2903003703000c030b200020022903003703" + "00200041386a200241386a290300370300200041306a200241306a290300" + "370300200041286a200241286a290300370300200041206a200241206a29" + "0300370300200041186a200241186a290300370300200041106a20024110" + "6a290300370300200041086a200241086a2903003703000c020b20002001" + "290300370300200041386a200141386a290300370300200041306a200141" + "306a290300370300200041286a200141286a290300370300200041206a20" + "0141206a290300370300200041186a200141186a29030037030020004110" + "6a200141106a290300370300200041086a200141086a2903003703000c01" + "0b41c4a0c000412041f4a0c0001021000b200341f0026a24000bf2020201" + "7f067e230041e0006b22022400200241386a4200370300200241306a4200" + "370300200242003703582002420037035020024200370348420121042002" + "42013703402002420037032820024200370320027e02402001200241206a" + "104a450440200141206a200241406b104a450d010b200241106a20014110" + "6a290300370300200241186a200141186a29030037030020022001290300" + "3703002002200141086a290300370308200141286a290300210520012903" + "30210620012903202107200141386a2903000c010b42002104200241106a" + "4200370300200241186a4200370300200242003703002002420037030842" + "01210742000b210820004200370358200042003703502000200437034020" + "002006370330200020073703202000200229030037030020002003370348" + "2000200837033820002005370328200041086a2002290308370300200041" + "186a200241186a290300370300200041106a200241106a29030037030020" + "0241e0006a24000b5b01027f0240200041046b2802002202417871220341" + "044108200241037122021b20016a4f0440200241002003200141276a4b1b" + "0d01200010040f0b41f996c000412e41a897c0001011000b41b897c00041" + "2e41e897c0001011000bc30802027f047e230041a0026b22022400200241" + "d8016a4200370300200241d0016a4200370300200241c8016a4200370300" + "200241c0016a22034200370300200241b8016a4200370300200241b0016a" + "4200370300200241f8016a420037030020024180026a4200370300200241" + "88026a420037030020024190026a420037030020024198026a4200370300" + "200242003703e80142012105200242013703e001200242003703a8012002" + "42003703a001200242003703f0010240024002402001200241a0016a104a" + "0d00200141206a2003104a0d00200141406b200241e0016a104a0d002001" + "41e0006a20024180026a104a450d010b200241106a420037030020024118" + "6a4200370300200241206a4200370300200241286a420037030020024140" + "6b200141e0006a290300370300200241c8006a200141e8006a2903003703" + "00200241d0006a200141f0006a290300370300200241d8006a200141f800" + "6a2903003703002002420037030020024200370308200220012903503703" + "302002200141d8006a290300370338200141c8006a290300210620012903" + "40210720024198016a200141386a29030037030020024190016a20014130" + "6a29030037030020024188016a200141286a29030037030020024180016a" + "200141206a290300370300200241f8006a200141186a2903003703002002" + "41f0006a200141106a2903003703002002200141086a2903003703682002" + "20012903003703600c010b42002105200241f0006a4200370300200241f8" + "006a420037030020024180016a420037030020024188016a420037030020" + "024190016a420037030020024198016a4200370300200241406b42003703" + "00200241c8006a4200370300200241d0006a4200370300200241d8006a42" + "00370300200241106a4200370300200241186a4200370300200241206a42" + "00370300200241286a420037030020024200370360200242003703682002" + "420037033020024200370338200242003703002002420037030842012107" + "0b2000200737034020002002290360370300200020022903303703502000" + "2006370348200041086a2002290368370300200041d8006a200229033837" + "0300200041386a20024198016a290300370300200041306a20024190016a" + "290300370300200041286a20024188016a290300370300200041206a2002" + "4180016a290300370300200041186a200241f8006a290300370300200041" + "106a200241f0006a290300370300200041e0006a200241406b2903003703" + "00200041e8006a200241c8006a290300370300200041f0006a200241d000" + "6a290300370300200041f8006a200241d8006a2903003703002000200437" + "0388012000200537038001200020022903003703900120004198016a2002" + "290308370300200041a0016a200241106a290300370300200041a8016a20" + "0241186a290300370300200041b0016a200241206a290300370300200041" + "b8016a200241286a290300370300200241a0026a24000b6802017f017e23" + "0041306b2203240020032001360204200320003602002003410236020c20" + "0341c481c00036020820034202370214200342808080801022042003ad84" + "37032820032004200341046aad843703202003200341206a360210200341" + "086a2002101a000b4101017f230041206b22032400200341003602102003" + "4101360204200342043702082003200136021c2003200036021820032003" + "41186a36020020032002101a000b6801017f230041306b22032400200320" + "01360204200320003602002003410236020c2003418484c0003602082003" + "42023702142003200341046aad4280808080108437032820032003ad4280" + "80808010843703202003200341206a360210200341086a2002101a000b79" + "01017f230041406a220524002005200136020c2005200036020820052003" + "360214200520023602102005410236021c200541d881c000360218200542" + "023702242005200541106aad428080808020843703382005200541086aad" + "428080808030843703302005200541306a360220200541186a2004101a00" + "0b3601017f230041206b22012400200141003602182001410136020c2001" + "41d480c00036020820014204370210200141086a2000101a000bcc060105" + "7f0240024002400240200041046b22062802002207417871220441044108" + "200741037122051b20016a4f044020054100200141276a22082004491b0d" + "0102400240200241094f04402003100b22040d0141000f0b41102003410b" + "6a4178712003410b491b2101024020054504402001418002490d01200420" + "01410472490d01200420016b418180084f0d010c030b200041086b220220" + "046a2105024002400240200120044b0440200541a0a9c000280200460d03" + "2005419ca9c000280200460d02200528020422074102710d042007417871" + "220720046a22042001490d04200520071016200420016b22034110490d01" + "20062001200628020041017172410272360200200120026a220120034103" + "72360204200220046a220420042802044101723602042001200310172000" + "0f0b200420016b2203410f4d0d0520062001200741017172410272360200" + "200120026a22012003410372360204200520052802044101723602042001" + "2003101720000f0b20062004200628020041017172410272360200200220" + "046a2201200128020441017236020420000f0b4194a9c00028020020046a" + "22042001490d010240200420016b2203410f4d0440200620074101712004" + "72410272360200200220046a220120012802044101723602044100210341" + "0021010c010b20062001200741017172410272360200200120026a220120" + "03410172360204200220046a2204200336020020042004280204417e7136" + "02040b419ca9c00020013602004194a9c000200336020020000f0b4198a9" + "c00028020020046a220420014b0d070b20031001220145044041000f0b20" + "012000417c4178200628020022044103711b20044178716a220420032003" + "20044b1b104c21012000100420010f0b200420002001200320012003491b" + "104c210420062802002203417871220541044108200341037122031b2001" + "6a490d0320034100200520084b1b0d0420001004200421000b20000f0b41" + "f996c000412e41a897c0001011000b41b897c000412e41e897c000101100" + "0b41f996c000412e41a897c0001011000b41b897c000412e41e897c00010" + "11000b20062001200741017172410272360200200120026a220320042001" + "6b22014101723602044198a9c000200136020041a0a9c000200336020020" + "000bf10201047f200028020c21020240024020014180024f044020002802" + "1821040240024020002002460440200041144110200028021422021b6a28" + "020022010d01410021020c020b20002802082201200236020c2002200136" + "02080c010b200041146a200041106a20021b210303402003210520012202" + "41146a200241106a200228021422011b210320024114411020011b6a2802" + "0022010d000b200541003602000b2004450d022000200028021c41027441" + "f4a5c0006a220128020047044020044110411420042802102000461b6a20" + "023602002002450d030c020b2001200236020020020d014190a9c0004190" + "a9c000280200417e200028021c77713602000c020b200028020822032002" + "4704402003200236020c200220033602080f0b418ca9c000418ca9c00028" + "0200417e200141037677713602000f0b2002200436021820002802102201" + "044020022001360210200120023602180b20002802142201450d00200220" + "01360214200120023602180b0ba90601047f200020016a21020240024020" + "0028020422034101710d002003410271450d012000280200220320016a21" + "01200020036b2200419ca9c0002802004604402002280204410371410347" + "0d014194a9c000200136020020022002280204417e713602042000200141" + "0172360204200220013602000c020b2000200310160b0240024002402002" + "2802042203410271450440200241a0a9c000280200460d022002419ca9c0" + "00280200460d0320022003417871220310162000200120036a2201410172" + "360204200020016a20013602002000419ca9c000280200470d014194a9c0" + "0020013602000f0b20022003417e71360204200020014101723602042000" + "20016a20013602000b20014180024f0440411f2102200042003702102001" + "41ffffff074d04402001410620014108766722026b764101712002410174" + "6b413e6a21020b2000200236021c200241027441f4a5c0006a2103410120" + "027422044190a9c000280200714504402003200036020020002003360218" + "2000200036020c200020003602084190a9c0004190a9c000280200200472" + "3602000f0b02400240200120032802002204280204417871460440200421" + "020c010b2001411920024101766b41002002411f471b7421030340200420" + "03411d764104716a41106a22052802002202450d02200341017421032002" + "210420022802044178712001470d000b0b20022802082201200036020c20" + "022000360208200041003602182000200236020c200020013602080f0b20" + "052000360200200020043602182000200036020c200020003602080f0b20" + "0141f801714184a7c0006a2102027f418ca9c00028020022034101200141" + "037674220171450440418ca9c000200120037236020020020c010b200228" + "02080b2101200220003602082001200036020c2000200236020c20002001" + "3602080f0b41a0a9c00020003602004198a9c0004198a9c0002802002001" + "6a2201360200200020014101723602042000419ca9c000280200470d0141" + "94a9c0004100360200419ca9c00041003602000f0b419ca9c00020003602" + "004194a9c0004194a9c00028020020016a22013602002000200141017236" + "0204200020016a20013602000b0b8e0201057f230041206b220324002000" + "2802002202417f460440410020011019000b410820024101742204200241" + "016a2205200420054b1b2204200441084d1b220441004804404100200110" + "19000b20032002047f2003200236021c2003200028020436021441010541" + "000b360218200341086a2105027f0240200341146a220228020404402002" + "280208220645044041bda9c0002d00001a0c020b20022802002006410120" + "0410150c020b41bda9c0002d00001a0b200410010b210220052004360208" + "20052002410120021b360204200520024536020020032802084101460440" + "20032802101a200328020c20011019000b200328020c2102200020043602" + "0020002002360204200341206a24000b0d002000450440200110140b000b" + "f40102027f017e230041106b22022400200241013b010c20022001360208" + "20022000360204230041106b22002400200241046a220129020021042000" + "200136020c20002004370204230041106b22022400200041046a22012802" + "00220028020c2103024002400240024020002802040e020001020b20030d" + "0141012100410021030c020b20030d002000280200220028020421032000" + "28020021000c010b20024180808080783602002002200136020c20012802" + "0822012d0008210020012d00091a2002410420001033000b200220033602" + "0420022000360200200128020822012d0008210020012d00091a20024105" + "20001033000b6801017f230041306b220324002003200136020420032000" + "3602002003410236020c200341e483c00036020820034202370214200320" + "0341046aad4280808080108437032820032003ad42808080801084370320" + "2003200341206a360210200341086a2002101a000bcf06010b7f20002802" + "002102230041106b22072400410a2103024020024190ce00490440200221" + "000c010b0340200741066a20036a220441046b20024190ce006e220041f0" + "b1036c20026a220541ffff037141e4006e220641017441e881c0006a2f00" + "003b0000200441026b2006419c7f6c20056a41ffff037141017441e881c0" + "006a2f00003b0000200341046b2103200241ffc1d72f4b21042000210220" + "040d000b0b0240200041e3004d0440200021020c010b200341026b220320" + "0741066a6a200041ffff037141e4006e2202419c7f6c20006a41ffff0371" + "41017441e881c0006a2f00003b00000b02402002410a4f0440200341026b" + "2203200741066a6a200241017441e881c0006a2f00003b00000c010b2003" + "41016b2203200741066a6a20024130723a00000b027f200741066a20036a" + "210941012108410a20036b220a2001280214220241017122056a21062008" + "410020024104711b2108412b418080c40020051b21052001280200450440" + "4101200128021c22002001280220220320052008101d0d011a2000200920" + "0a200328020c1103000c010b0240024002402006200128020422004f0440" + "200128021c22002001280220220320052008101d450d0141010c040b2002" + "410871450d01200128021021022001413036021020012d0018210c410121" + "0b200141013a0018200128021c22032001280220220420052008101d0d02" + "200020066b41016a210002400340200041016b2200450d01200341302004" + "280210110200450d000b41010c040b410120032009200a200428020c1103" + "000d031a2001200c3a00182001200236021041000c030b20002009200a20" + "0328020c110300210b0c010b200020066b2102024002400240410120012d" + "0018220020004103461b220041016b0e020001020b20022100410021020c" + "010b20024101762100200241016a41017621020b200041016a2100200128" + "0210210620012802202103200128021c210402400340200041016b220045" + "0d01200420062003280210110200450d000b41010c020b4101210b200420" + "0320052008101d0d0020042009200a200328020c1103000d004100210003" + "40410020002002460d021a200041016a2100200420062003280210110200" + "450d000b200041016b2002490c010b200b0b2102200741106a240020020b" + "380002402002418080c400460d00200020022001280210110200450d0041" + "010f0b200345044041000f0b200020034100200128020c1103000bfd0a01" + "0c7f20002802042107200028020021030240024020012802002209200128" + "0208220072044002402000410171450d00200320076a2106024020012802" + "0c2205450440200321020c010b200321020340200222002006460d02027f" + "200041016a20002c0000220241004e0d001a200041026a20024160490d00" + "1a200041036a20024170490d001a200041046a0b220220006b20046a2104" + "2005200841016a2208470d000b0b20022006460d0020022c00001a200420" + "07027f02402004450d00200420074f044020042007460d0141000c020b20" + "0320046a2c000041404e0d0041000c010b20030b22001b21072000200320" + "001b21030b2009450440200128021c20032007200128022028020c110300" + "0f0b2001280204210c200741104f044020072003200341036a417c712204" + "6b22086a220a41037121094100210541002100200320044704402008417c" + "4d04404100210603402000200320066a22022c000041bf7f4a6a20024101" + "6a2c000041bf7f4a6a200241026a2c000041bf7f4a6a200241036a2c0000" + "41bf7f4a6a2100200641046a22060d000b0b200321020340200020022c00" + "0041bf7f4a6a2100200241016a2102200841016a22080d000b0b02402009" + "450d002004200a417c716a22022c000041bf7f4a210520094101460d0020" + "0520022c000141bf7f4a6a210520094102460d00200520022c000241bf7f" + "4a6a21050b200a4102762106200020056a21050340200421092006450d04" + "41c0012006200641c0014f1b220a410371210b200a410274210d41002102" + "200641044f04402004200d41f007716a2108200421000340200028020c22" + "04417f7341077620044106767241818284087120002802082204417f7341" + "077620044106767241818284087120002802042204417f73410776200441" + "06767241818284087120002802002204417f734107762004410676724181" + "8284087120026a6a6a6a2102200041106a22002008470d000b0b2006200a" + "6b21062009200d6a2104200241087641ff81fc0771200241ff81fc07716a" + "418180046c41107620056a2105200b450d000b2009200a41fc0171410274" + "6a22022802002200417f734107762000410676724181828408712100200b" + "4101460d0220022802042204417f73410776200441067672418182840871" + "20006a2100200b4102460d0220022802082202417f734107762002410676" + "7241818284087120006a21000c020b2007450440410021050c030b200741" + "03712102027f200741044904404100210041000c010b20032c000041bf7f" + "4a20032c000141bf7f4a6a20032c000241bf7f4a6a20032c000341bf7f4a" + "6a22052007410c7122004104460d001a200520032c000441bf7f4a6a2003" + "2c000541bf7f4a6a20032c000641bf7f4a6a20032c000741bf7f4a6a2205" + "20004108460d001a200520032c000841bf7f4a6a20032c000941bf7f4a6a" + "20032c000a41bf7f4a6a20032c000b41bf7f4a6a0b21052002450d022000" + "20036a21000340200520002c000041bf7f4a6a2105200041016a21002002" + "41016b22020d000b0c020b200128021c20032007200128022028020c1103" + "000f0b200041087641ff811c71200041ff81fc07716a418180046c411076" + "20056a21050b02402005200c490440200c20056b21060240024002402001" + "2d00182200410020004103471b220041016b0e020001020b200621004100" + "21060c010b20064101762100200641016a41017621060b200041016a2100" + "2001280210210820012802202102200128021c21040340200041016b2200" + "450d02200420082002280210110200450d000b41010f0b200128021c2003" + "2007200128022028020c1103000f0b200420032007200228020c11030004" + "4041010f0b4100210003402000200646044041000f0b200041016a210020" + "0420082002280210110200450d000b200041016b2006490b140020002802" + "002001200028020428020c1102000b0e0041e480c000412b20001011000b" + "5901017f230041306b220324002003200136020c20032000360208200341" + "01360214200341dc80c0003602102003420137021c2003200341086aad42" + "8080808030843703282003200341286a360218200341106a2002101a000b" + "7f01017f027f0240027f0240200228020404402002280208220345044020" + "01450d0441bda9c0002d00001a0c020b200228020020034104200110150c" + "020b2001450d0241bda9c0002d00001a0b200110010b2202410420021b21" + "032002450c010b4104210341000b21022000200136020820002003360204" + "200020023602000bdd0101087f230041206b220224002000280200220341" + "7f460440410020011019000b20034101742204200341016a220620042006" + "4b1b220441ffffffff034b0440410020011019000b024041042004200441" + "044d1b2207410274220641fcffffff074d047f4100210420022003047f20" + "02200341027436021c2002200028020436021441040520040b3602182002" + "41086a2006200241146a102220022802084101470d012002280210210520" + "0228020c0520050b210820052109200820011019000b200228020c210320" + "00200736020020002003360204200241206a24000bd10d021c7f077e2300" + "41206b220c2400200341016b211102400240024002402003044020034102" + "6b210520034101460d0402402001280208221420036b221941016a220e41" + "ffffffff034b0d00200e410274220441fdffffff074f0d00200220114102" + "746a2802002115200220054102746a3502002123027f2004450440410421" + "0b41000c010b41bda9c0002d00001a20041001220b450d05200b41046b2d" + "00004103710440200b2004104b1a0b200e0b21102001280200211a201421" + "09200e044020012802042212200941027420034102746b6a211320034101" + "7121162003417e71210d201241086b211b201241046b211c42002015ad22" + "2242208622247d2125200e210f0340024020090440201c20094102742204" + "6a22050d010b41ec87c0001020000b027f0240200941024f044020052802" + "0021052004201b6a350200212120082015490d012005ad2008ad7c212041" + "7f0c020b417f417e20141b410141fc87c0001010000b2005ad2008ad4220" + "868422202020202280222620227e7d21202026a70b21070240202042ffff" + "ffff0f560d00202520204220867c20217c21210340202120247c22212007" + "ad20237e5a0d01200741016b2107202020227c2220428080808010540d00" + "0b0b02400240024002402009200f41016b220f4f0440200f410274211720" + "09200f460d04201220176a21182007ad212102400240201145044042ffff" + "ffff0f2120410021060c010b4100210642ffffffff0f2120201321042002" + "210503402004202020043502007c202120053502007e7d42ffffffff1f7d" + "22203e0200200441046a220a200a35020020204220887c2021200541046a" + "3502007e7d42ffffffff1f7d22203e020020204220882120200441086a21" + "04200541086a2105200d200641026a2206470d000b2016450d010b201820" + "0641027422046a2205202020053502007c2021200220046a3502007e7d42" + "ffffffff1f7d22203e0200202042208821200b20082020a7417f734f0d04" + "20114504404100210a410021080c030b41002104410021084100210a0340" + "200420136a22052005280200221d200220046a221e2802006a220620086a" + "2208360200200541046a22052005280200221f201e41046a2802006a2205" + "2006201d49200620084b726a22063602002005201f49200520064b722108" + "200441086a2104200d200a41026a220a470d000b0c010b200f2009418c88" + "c000101b000b2016450d010b2018200a41027422046a2205200528020020" + "0220046a2802006a20086a3602000b200741016b21070b200b20176a2007" + "3602002001200941016b2209360208201341046b2113201220094102746a" + "2802002108200f0d000b0b2009201a460440200141dc87c00010230b2001" + "200941016a220d3602082001280204220a200941027422046a2008360200" + "20080d03200d41ffffffff0371210702400340200721052004417c460d01" + "200541016b21072004200a6a2106200441046b21042006280200450d000b" + "2005200d4b0d040c030b410021050c020b41cc87c0001014000b20114100" + "41ac87c0001010000b200120053602082005210d0b024002400240024002" + "40200d200128020022044102764f0d002004200d490d012004450d002004" + "41027421040240200d450440200a41046b28020022054178712207410441" + "08200541037122051b20046a490d04200541002007200441276a4b1b0d05" + "200a1004410421040c010b200a20044104200d41027410152204450d060b" + "2001200d360200200120043602040b41002106200e450d03200b200e4102" + "746a41046b2802000440200e21060c040b201441027420034102746b2104" + "201941026a210503402004417c460d04200541016b21052004200b6a2107" + "200441046b21042007280200450d000b200e20052005200e4b1b21060c03" + "0b200c4100360218200c410136020c200c41ec84c000360208200c420437" + "0210200c41086a41f484c000101a000b41f996c000412e41a897c0001011" + "000b41b897c000412e41e897c0001011000b024002400240024020104102" + "7620064d0440201021040c010b200620104b0d01410021042010450d0020" + "1041027421052006450440200b41046b2802002207417871220a41044108" + "200741037122071b20056a490d0320074100200a200541276a4b1b0d0420" + "0b10044104210b0c010b200b20054104200622044102741015220b450d04" + "0b200020063602082000200b360204200020043602002000200129020037" + "020c200041146a200141086a280200360200200c41206a24000f0b200c41" + "00360218200c410136020c200c41ec84c000360208200c4204370210200c" + "41086a41f484c000101a000b41f996c000412e41a897c0001011000b41b8" + "97c000412e41e897c00010110b000b2005410141bc87c0001010000be609" + "010c7f230041306b220724002001280200210c0240024002400240024002" + "400240024002400240024002400240024020024504402001280204210b20" + "0c418080808078470d02200b41086a280200220441ffffffff034d044020" + "04410274220641fdffffff07490d020b41a89cc0001014000b2001280204" + "220b2001200c418080808078461b2208280208220941feffffff014f0d04" + "41bda9c0002d00001a200941026a220141027410012205450d0720054100" + "360200200720053602102007200136020c41012101200741013602142008" + "2802082206410274210d200828020421082006200941016a4b0440200741" + "0c6a2105230041206b22042400024002402006417f460d00200528020022" + "09410174220a200641016a22012001200a491b220141ffffffff034b0d00" + "41042001200141044d1b220f410274220a41fcffffff074b0d0020042009" + "047f2004200941027436021c2004200528020436021441040541000b3602" + "18200441086a200a200441146a102220042802084101470d012004280210" + "1a200428020c210e0b200e41c096c0001019000b200428020c2101200520" + "0f36020020052001360204200441206a2400200728021021052007280214" + "21010b200520014102746a2008200d104c1a2007200120066a2204360214" + "0c030b200b41046a28020021092006450440410421054100210141042009" + "2006104c1a0c020b41bda9c0002d00001a20042101200610012205450d06" + "200520092006104c1a0c010b20012802082104200c2101200b21050b2007" + "2004360214200720053602102007200136020c0b200341ff0171450d0202" + "40200220044d044020022004470d01200221040c040b2002410041c889c0" + "00101b000b20044102742109200241027421012003411f71210841002003" + "6b411f71210d410021030340200120056a22062006280200220620087420" + "03723602002006200d7621032009200141046a2201470d000b0c010b41a8" + "89c00010140c020b2003450d00200728020c20044604402007410c6a41b8" + "89c0001023200728021021050b200520044102746a200336020020072004" + "41016a22043602140b41002108200728020c210a02402004450d00200520" + "0441027422016a41046b2802000440200421080c010b200541046b210d20" + "0441ffffffff037121030340200321062001450d01200641016b21032001" + "200d6a2109200141046b21012009280200450d000b200420062004200649" + "1b21080b0240200a41027620084d0440200a21010c010b2008200a4b0d02" + "41002101200a450d00200a41027421032008450440200541046b28020022" + "06417871220941044108200641037122061b20036a490d04200641002009" + "200341276a4b1b0d0520051004410421050c010b20052003410420082201" + "41027410152205450d010b20002008360208200020053602042000200136" + "02002002450d06200c41808080807872418080808078460d06200b41046b" + "28020022014178712203200c410274220641044108200141037122011b6a" + "490d04200141002003200641276a4b1b0d05200b10040c060b000b200741" + "003602282007410136021c200741ec84c000360218200742043702202007" + "41186a41f484c000101a000b41f996c000412e41a897c0001011000b41b8" + "97c000412e41e897c0001011000b41f996c000412e41a897c0001011000b" + "41b897c000412e41e897c0001011000b200741306a24000bc60201027f41" + "bda9c0002d00001a024002400240412010012202450d0020022001290000" + "370200200220012900083702082002200129001037021020022001280018" + "3602182002200128001c220336021c410821012000027f410820030d001a" + "41082002411c6a2802000d001a4107200241186a2802000d001a41062002" + "41146a2802000d001a4105200241106a2802000d001a41042002410c6a28" + "02000d001a4103200241086a2802000d001a4102200241046a2802000d00" + "1a2002280200450440200241046b28020022014178714124412820014103" + "7122031b490d0320034100200141c8004f1b0d0420021004410421024100" + "210141000c010b200241204104410410152202450d014101210141010b36" + "020820002002360204200020013602000f0b000b41f996c000412e41a897" + "c0001011000b41b897c000412e41e897c0001011000bcc3e01227f200120" + "024106746a2124200028021c21222000280218211f2000280214211e2000" + "280210211b200028020c2123200028020821202000280204211d20002802" + "002102034020022001280000220341187420034180fe0371410874722003" + "4108764180fe03712003411876727222152022201b411a77201b41157773" + "201b410777736a201e201f73201b71201f736a6a4198dfa894046a220420" + "1d202073200271201d202071732002411e772002411377732002410a7773" + "6a6a2203411e772003411377732003410a777320032002201d7371200220" + "1d71736a201f2001280004220541187420054180fe037141087472200541" + "08764180fe03712005411876727222136a200420236a2207201b201e7371" + "201e736a2007411a772007411577732007410777736a419189dd89076a22" + "066a2205411e772005411377732005410a77732005200220037371200220" + "0371736a201e2001280008220441187420044180fe037141087472200441" + "08764180fe03712004411876727222146a200620206a220c2007201b7371" + "201b736a200c411a77200c41157773200c410777736a41b188fcd1046b22" + "0d6a2204411e772004411377732004410a77732004200320057371200320" + "0571736a201b200128000c220641187420064180fe037141087472200641" + "08764180fe03712006411876727222116a200d201d6a220d2007200c7371" + "2007736a200d411a77200d41157773200d410777736a41dbc8a8b2016b22" + "086a2206411e772006411377732006410a77732006200420057371200420" + "0571736a20072001280010220f411874200f4180fe037141087472200f41" + "08764180fe0371200f411876727222166a200220086a220f200c200d7371" + "200c736a200f411a77200f41157773200f410777736a41db84dbca036a22" + "096a2207411e772007411377732007410a77732007200420067371200420" + "0671736a2001280014220841187420084180fe0371410874722008410876" + "4180fe0371200841187672722218200c6a200320096a220c200d200f7371" + "200d736a200c411a77200c41157773200c410777736a41f1a3c4cf056a22" + "096a2203411e772003411377732003410a77732003200620077371200620" + "0771736a2001280018220841187420084180fe0371410874722008410876" + "4180fe0371200841187672722219200d6a200520096a220d200c200f7371" + "200f736a200d411a77200d41157773200d410777736a41dcfa81ee066b22" + "096a2205411e772005411377732005410a77732005200320077371200320" + "0771736a200128001c220841187420084180fe0371410874722008410876" + "4180fe037120084118767272221a200f6a200420096a220f200c200d7371" + "200c736a200f411a77200f41157773200f410777736a41abc28ea7056b22" + "096a2204411e772004411377732004410a77732004200320057371200320" + "0571736a2001280020220841187420084180fe0371410874722008410876" + "4180fe0371200841187672722202200c6a200620096a220c200d200f7371" + "200d736a200c411a77200c41157773200c410777736a41e8aae1bf026b22" + "096a2206411e772006411377732006410a77732006200420057371200420" + "0571736a2001280024220841187420084180fe0371410874722008410876" + "4180fe037120084118767272220a200d6a200720096a220d200c200f7371" + "200f736a200d411a77200d41157773200d410777736a4181b68d94016a22" + "096a2207411e772007411377732007410a77732007200420067371200420" + "0671736a2001280028220841187420084180fe0371410874722008410876" + "4180fe037120084118767272220b200f6a200320096a220f200c200d7371" + "200c736a200f411a77200f41157773200f410777736a41be8bc6a1026a22" + "096a2203411e772003411377732003410a77732003200620077371200620" + "0771736a200128002c220841187420084180fe0371410874722008410876" + "4180fe0371200841187672722210200c6a200520096a2208200d200f7371" + "200d736a2008411a772008411577732008410777736a41c3fbb1a8056a22" + "096a2205411e772005411377732005410a77732005200320077371200320" + "0771736a2001280030220c411874200c4180fe037141087472200c410876" + "4180fe0371200c4118767272221c200d6a200420096a22092008200f7371" + "200f736a2009411a772009411577732009410777736a41f4baf995076a22" + "0d6a2204411e772004411377732004410a77732004200320057371200320" + "0571736a2001280034220c411874200c4180fe037141087472200c410876" + "4180fe0371200c41187672722221200f6a2006200d6a220e200820097371" + "2008736a200e411a77200e41157773200e410777736a41829c85f9076b22" + "0d6a2206411e772006411377732006410a77732006200420057371200420" + "0571736a2001280038220c411874200c4180fe037141087472200c410876" + "4180fe0371200c4118767272220c20086a2007200d6a22122009200e7371" + "2009736a2012411a772012411577732012410777736a41d9f28fa1066b22" + "0f6a2207411e772007411377732007410a77732007200420067371200420" + "0671736a200128003c220d411874200d4180fe037141087472200d410876" + "4180fe0371200d4118767272220d20096a2003200f6a2217200e20127371" + "200e736a2017411a772017411577732017410777736a418c9d90f3036b22" + "086a2203411e772003411377732003410a77732003200620077371200620" + "0771736a20134119772013410e777320134103767320156a200a6a200c41" + "0f77200c410d7773200c410a76736a220f200e6a200520086a2215201220" + "1773712012736a2015411a772015411577732015410777736a41bfac92db" + "016b22096a2205411e772005411377732005410a77732005200320077371" + "2003200771736a20144119772014410e777320144103767320136a200b6a" + "200d410f77200d410d7773200d410a76736a220820126a200420096a2213" + "2015201773712017736a2013411a772013411577732013410777736a41fa" + "f08682016b220e6a2204411e772004411377732004410a77732004200320" + "0573712003200571736a20114119772011410e777320114103767320146a" + "20106a200f410f77200f410d7773200f410a76736a220920176a2006200e" + "6a22142013201573712015736a2014411a77201441157773201441077773" + "6a41c6bb86fe006a22126a2206411e772006411377732006410a77732006" + "2004200573712004200571736a20164119772016410e7773201641037673" + "20116a201c6a2008410f772008410d77732008410a76736a220e20156a20" + "0720126a22112013201473712013736a2011411a77201141157773201141" + "0777736a41ccc3b2a0026a22176a2207411e772007411377732007410a77" + "7320072004200673712004200671736a20184119772018410e7773201841" + "03767320166a20216a2009410f772009410d77732009410a76736a221220" + "136a200320176a22162011201473712014736a2016411a77201641157773" + "2016410777736a41efd8a4ef026a22156a2203411e772003411377732003" + "410a777320032006200773712006200771736a20194119772019410e7773" + "20194103767320186a200c6a200e410f77200e410d7773200e410a76736a" + "221720146a200520156a22182011201673712011736a2018411a77201841" + "1577732018410777736a41aa89d2d3046a22136a2205411e772005411377" + "732005410a777320052003200773712003200771736a201a411977201a41" + "0e7773201a4103767320196a200d6a2012410f772012410d77732012410a" + "76736a221520116a200420136a22192016201873712016736a2019411a77" + "2019411577732019410777736a41dcd3c2e5056a22146a2204411e772004" + "411377732004410a777320042003200573712003200571736a2002411977" + "2002410e7773200241037673201a6a200f6a2017410f772017410d777320" + "17410a76736a221320166a200620146a221a2018201973712018736a201a" + "411a77201a41157773201a410777736a41da91e6b7076a22116a2206411e" + "772006411377732006410a777320062004200573712004200571736a200a" + "411977200a410e7773200a4103767320026a20086a2015410f772015410d" + "77732015410a76736a221420186a200720116a22022019201a7371201973" + "6a2002411a772002411577732002410777736a41aedd86be066b22166a22" + "07411e772007411377732007410a77732007200420067371200420067173" + "6a200b411977200b410e7773200b41037673200a6a20096a2013410f7720" + "13410d77732013410a76736a221120196a200320166a220a2002201a7371" + "201a736a200a411a77200a41157773200a410777736a4193f3b8be056b22" + "186a2203411e772003411377732003410a77732003200620077371200620" + "0771736a20104119772010410e7773201041037673200b6a200e6a201441" + "0f772014410d77732014410a76736a2216201a6a200520186a220b200220" + "0a73712002736a200b411a77200b41157773200b410777736a41b8b0f3ff" + "046b22196a2205411e772005411377732005410a77732005200320077371" + "2003200771736a201c411977201c410e7773201c4103767320106a20126a" + "2011410f772011410d77732011410a76736a221820026a200420196a2202" + "200a200b7371200a736a2002411a772002411577732002410777736a41b9" + "809a85046b221a6a2204411e772004411377732004410a77732004200320" + "0573712003200571736a20214119772021410e7773202141037673201c6a" + "20176a2016410f772016410d77732016410a76736a2219200a6a2006201a" + "6a220a2002200b7371200b736a200a411a77200a41157773200a41077773" + "6a418de8ffc8036b22106a2206411e772006411377732006410a77732006" + "2004200573712004200571736a200c411977200c410e7773200c41037673" + "20216a20156a2018410f772018410d77732018410a76736a221a200b6a20" + "0720106a220b2002200a73712002736a200b411a77200b41157773200b41" + "0777736a41b9dde1d2026b22106a2207411e772007411377732007410a77" + "7320072004200673712004200671736a200d411977200d410e7773200d41" + "037673200c6a20136a2019410f772019410d77732019410a76736a220c20" + "026a200320106a2202200a200b7371200a736a2002411a77200241157773" + "2002410777736a41d1c6a9366a22106a2203411e77200341137773200341" + "0a777320032006200773712006200771736a200f411977200f410e777320" + "0f41037673200d6a20146a201a410f77201a410d7773201a410a76736a22" + "0d200a6a200520106a220a2002200b7371200b736a200a411a77200a4115" + "7773200a410777736a41e7d2a4a1016a22106a2205411e77200541137773" + "2005410a777320052003200773712003200771736a20084119772008410e" + "7773200841037673200f6a20116a200c410f77200c410d7773200c410a76" + "736a220f200b6a200420106a220b2002200a73712002736a200b411a7720" + "0b41157773200b410777736a418595dcbd026a22106a2204411e77200441" + "1377732004410a777320042003200573712003200571736a200941197720" + "09410e777320094103767320086a20166a200d410f77200d410d7773200d" + "410a76736a220820026a200620106a2202200a200b7371200a736a200241" + "1a772002411577732002410777736a41b8c2ecf0026a22106a2206411e77" + "2006411377732006410a777320062004200573712004200571736a200e41" + "1977200e410e7773200e4103767320096a20186a200f410f77200f410d77" + "73200f410a76736a2209200a6a200720106a220a2002200b7371200b736a" + "200a411a77200a41157773200a410777736a41fcdbb1e9046a22106a2207" + "411e772007411377732007410a777320072004200673712004200671736a" + "20124119772012410e7773201241037673200e6a20196a2008410f772008" + "410d77732008410a76736a220e200b6a200320106a220b2002200a737120" + "02736a200b411a77200b41157773200b410777736a41939ae099056a2210" + "6a2203411e772003411377732003410a7773200320062007737120062007" + "71736a20174119772017410e777320174103767320126a201a6a2009410f" + "772009410d77732009410a76736a221220026a200520106a2202200a200b" + "7371200a736a2002411a772002411577732002410777736a41d4e6a9a806" + "6a22106a2205411e772005411377732005410a7773200520032007737120" + "03200771736a20154119772015410e777320154103767320176a200c6a20" + "0e410f77200e410d7773200e410a76736a2217200a6a200420106a220a20" + "02200b7371200b736a200a411a77200a41157773200a410777736a41bb95" + "a8b3076a22106a2204411e772004411377732004410a7773200420032005" + "73712003200571736a20134119772013410e777320134103767320156a20" + "0d6a2012410f772012410d77732012410a76736a2215200b6a200620106a" + "220b2002200a73712002736a200b411a77200b41157773200b410777736a" + "41d2edf4f1076b22106a2206411e772006411377732006410a7773200620" + "04200573712004200571736a20144119772014410e777320144103767320" + "136a200f6a2017410f772017410d77732017410a76736a221320026a2007" + "20106a2202200a200b7371200a736a2002411a7720024115777320024107" + "77736a41fba6b7ec066b22106a2207411e772007411377732007410a7773" + "20072004200673712004200671736a20114119772011410e777320114103" + "767320146a20086a2015410f772015410d77732015410a76736a2214200a" + "6a200320106a220a2002200b7371200b736a200a411a77200a4115777320" + "0a410777736a41dfae80ea056b22106a2203411e77200341137773200341" + "0a777320032006200773712006200771736a20164119772016410e777320" + "164103767320116a20096a2013410f772013410d77732013410a76736a22" + "11200b6a200520106a220b2002200a73712002736a200b411a77200b4115" + "7773200b410777736a41b5b396bf056b22106a2205411e77200541137773" + "2005410a777320052003200773712003200771736a20184119772018410e" + "777320184103767320166a200e6a2014410f772014410d77732014410a76" + "736a221620026a200420106a2202200a200b7371200a736a2002411a7720" + "02411577732002410777736a4190e9d1ed036b22106a2204411e77200441" + "1377732004410a777320042003200573712003200571736a201941197720" + "19410e777320194103767320186a20126a2011410f772011410d77732011" + "410a76736a2218200a6a200620106a220a2002200b7371200b736a200a41" + "1a77200a41157773200a410777736a41dddccec4036b22106a2206411e77" + "2006411377732006410a777320062004200573712004200571736a201a41" + "1977201a410e7773201a4103767320196a20176a2016410f772016410d77" + "732016410a76736a2219200b6a200720106a220b2002200a73712002736a" + "200b411a77200b41157773200b410777736a41e7afb4f3026b22106a2207" + "411e772007411377732007410a777320072004200673712004200671736a" + "200c411977200c410e7773200c41037673201a6a20156a2018410f772018" + "410d77732018410a76736a221a20026a200320106a2202200a200b737120" + "0a736a2002411a772002411577732002410777736a41dcf39bcb026b2210" + "6a2203411e772003411377732003410a7773200320062007737120062007" + "71736a200d411977200d410e7773200d41037673200c6a20136a2019410f" + "772019410d77732019410a76736a220c200a6a200520106a220a2002200b" + "7371200b736a200a411a77200a41157773200a410777736a41fb94c7df00" + "6b22106a2205411e772005411377732005410a7773200520032007737120" + "03200771736a200f411977200f410e7773200f41037673200d6a20146a20" + "1a410f77201a410d7773201a410a76736a220d200b6a200420106a220b20" + "02200a73712002736a200b411a77200b41157773200b410777736a41f0c0" + "aa83016a22106a2204411e772004411377732004410a7773200420032005" + "73712003200571736a20084119772008410e7773200841037673200f6a20" + "116a200c410f77200c410d7773200c410a76736a220f20026a200620106a" + "2202200a200b7371200a736a2002411a772002411577732002410777736a" + "41968293cd016a221c6a2206411e772006411377732006410a7773200620" + "04200573712004200571736a20094119772009410e777320094103767320" + "086a20166a200d410f77200d410d7773200d410a76736a2210200a6a2007" + "201c6a22082002200b7371200b736a2008411a7720084115777320084107" + "77736a4188d8ddf1016a221c6a2207411e772007411377732007410a7773" + "20072004200673712004200671736a200e411977200e410e7773200e4103" + "767320096a20186a200f410f77200f410d7773200f410a76736a220a200b" + "6a2003201c6a22092002200873712002736a2009411a7720094115777320" + "09410777736a41cceea1ba026a221c6a2203411e77200341137773200341" + "0a777320032006200773712006200771736a20124119772012410e777320" + "1241037673200e6a20196a2010410f772010410d77732010410a76736a22" + "0b20026a2005201c6a220e2008200973712008736a200e411a77200e4115" + "7773200e410777736a41b5f9c2a5036a22026a2205411e77200541137773" + "2005410a777320052003200773712003200771736a20174119772017410e" + "777320174103767320126a201a6a200a410f77200a410d7773200a410a76" + "736a221220086a200220046a22082009200e73712009736a2008411a7720" + "08411577732008410777736a41b399f0c8036a22026a2204411e77200441" + "1377732004410a777320042003200573712003200571736a201541197720" + "15410e777320154103767320176a200c6a200b410f77200b410d7773200b" + "410a76736a221720096a200220066a22092008200e7371200e736a200941" + "1a772009411577732009410777736a41cad4e2f6046a22026a2206411e77" + "2006411377732006410a777320062004200573712004200571736a201341" + "19772013410e777320134103767320156a200d6a2012410f772012410d77" + "732012410a76736a2215200e6a200220076a220e2008200973712008736a" + "200e411a77200e41157773200e410777736a41cf94f3dc056a22026a2207" + "411e772007411377732007410a777320072004200673712004200671736a" + "20144119772014410e777320144103767320136a200f6a2017410f772017" + "410d77732017410a76736a221320086a200220036a22082009200e737120" + "09736a2008411a772008411577732008410777736a41f3dfb9c1066a2202" + "6a2203411e772003411377732003410a7773200320062007737120062007" + "71736a20114119772011410e777320114103767320146a20106a2015410f" + "772015410d77732015410a76736a221420096a200220056a22092008200e" + "7371200e736a2009411a772009411577732009410777736a41ee85bea407" + "6a22026a2205411e772005411377732005410a7773200520032007737120" + "03200771736a20164119772016410e777320164103767320116a200a6a20" + "13410f772013410d77732013410a76736a2211200e6a200220046a220e20" + "08200973712008736a200e411a77200e41157773200e410777736a41efc6" + "95c5076a22026a2204411e772004411377732004410a7773200420032005" + "73712003200571736a20184119772018410e777320184103767320166a20" + "0b6a2014410f772014410d77732014410a76736a221620086a200220066a" + "22082009200e73712009736a2008411a772008411577732008410777736a" + "41ec8fded9076b22026a2206411e772006411377732006410a7773200620" + "04200573712004200571736a20194119772019410e777320194103767320" + "186a20126a2011410f772011410d77732011410a76736a221220096a2002" + "20076a22092008200e7371200e736a2009411a7720094115777320094107" + "77736a41f8fbe399076b22116a2207411e772007411377732007410a7773" + "20072004200673712004200671736a201a411977201a410e7773201a4103" + "767320196a20176a2016410f772016410d77732016410a76736a2217200e" + "6a200320116a220e2008200973712008736a200e411a77200e4115777320" + "0e410777736a41868084fa066b22116a2203411e77200341137773200341" + "0a777320032006200773712006200771736a200c411977200c410e777320" + "0c41037673201a6a20156a2012410f772012410d77732012410a76736a22" + "1220086a200520116a22052009200e73712009736a2005411a7720054115" + "77732005410777736a4195a6bedd056b22156a2208411e77200841137773" + "2008410a777320082003200773712003200771736a200c200d411977200d" + "410e7773200d410376736a20136a2017410f772017410d77732017410a76" + "736a20096a200420156a22042005200e7371200e736a2004411a77200441" + "1577732004410777736a4189b89988046b22096a220c2003200873712003" + "200871736a200c411e77200c41137773200c410a77736a200d200f411977" + "200f410e7773200f410376736a20146a2012410f772012410d7773201241" + "0a76736a200e6a200620096a22062004200573712005736a2006411a7720" + "06411577732006410777736a418e8ebacc036b220d6a2102200c201d6a21" + "1d2007201b6a200d6a211b200820206a21202006201e6a211e200320236a" + "21232004201f6a211f200520226a2122200141406b22012024470d000b20" + "00202236021c2000201f3602182000201e3602142000201b360210200020" + "2336020c200020203602082000201d360204200020023602000b89010101" + "7f027f0240200328020404402003280208220445044020012002450d031a" + "41bda9c0002d00001a20014109490d022002100b0c030b20032802002004" + "2001200210150c020b20012002450d011a41bda9c0002d00001a20014109" + "490d002002100b0c010b200210010b210320002002360208200020032001" + "20031b36020420002003453602000b3000200128021c20002d0000410274" + "220041b4a5c0006a280200200041a8a5c0006a280200200128022028020c" + "1103000bfc0402037f017e23004180016b220224000240024020012d0000" + "220441c00171220341c000470440200241186a200141186a290000370300" + "200241106a200141106a290000370300200241086a200141086a29000037" + "030020022001290000220537030020022005a7413f713a0000200241406b" + "2002102e20022d0040450d01200220022d00413a007f41a88ec000411f20" + "0241ff006a41988ec00041c88ec0001013000b02402004413f710d002001" + "2d00010d0020012d00020d0020012d00030d0020012d00040d0020012d00" + "050d0020012d00060d0020012d00070d0020012d00080d0020012d00090d" + "0020012d000a0d0020012d000b0d0020012d000c0d0020012d000d0d0020" + "012d000e0d0020012d000f0d0020012d00100d0020012d00110d0020012d" + "00120d0020012d00130d0020012d00140d0020012d00150d0020012d0016" + "0d0020012d00170d0020012d00180d0020012d00190d0020012d001a0d00" + "20012d001b0d0020012d001c0d0020012d001d0d0020012d001e0d002001" + "2d001f0d00200041c1013a0020200041033a00000c020b20004200370300" + "200041c0003a0020200041186a4200370300200041106a42003703002000" + "41086a42003703000c010b200241386a200241e8006a2903003703002002" + "41306a200241e0006a290300370300200220022903503703202002200241" + "d8006a2903003703282003044020002002290320370300200020033a0020" + "200041086a2002290328370300200041186a200241386a29030037030020" + "0041106a200241306a2903003703000c010b200241003602502002410136" + "0244200241a88cc00036024020024204370248200241406b419c8dc00010" + "1a000b20024180016a24000bf90a02057f097e23004190036b2207240020" + "00290300220c200041086a290300220d8450047e420005200741f0016a20" + "0c2001104d20074190026a200d2001104d200741e0016a200c2002104d20" + "074180026a200d2002104d200741b0016a200c2003104d200741a0016a20" + "0d2003104d200741d0016a200c2004104d200741c0016a200d2004104d20" + "072903f0012112200741c8016a290300200741a8016a290300220d200729" + "03c0017c220c200d54ad7c200c200741d8016a2903007c220d200c54ad7c" + "200d20072903d001220e20072903a0017c220c200e54ad200c2007418802" + "6a29030020074198026a290300220f2007290380027c220e200f54ad7c20" + "0e200741e8016a2903007c220f200e54ad7c200f20072903e00122102007" + "290390027c220e201054ad200e200741f8016a2903007c2213200e54ad7c" + "7c2210200f54ad7c7c2211200c54ad7c2011200741b8016a290300201020" + "072903b0017c220e201054ad7c7c220f201154ad7c7c2210200d54ad7c0b" + "21112000290310220c200041186a290300220d8450047e420005200741f0" + "006a200c2001104d20074190016a200d2001104d200741e0006a200c2002" + "104d20074180016a200d2002104d200741306a200c2003104d200741206a" + "200d2003104d200741d0006a200c2004104d200741406b200d2004104d20" + "0741c8006a290300200741286a290300220320072903407c2204200354ad" + "7c2004200741d8006a2903007c2203200454ad7c20032007290350220220" + "117c2204200254ad200420072903207c2202200454ad7c20022007418801" + "6a29030020074198016a29030022012007290380017c2204200154ad7c20" + "04200741e8006a2903007c2201200454ad7c20012007290360220c200f7c" + "2204200c54ad20042007290390017c220c200454ad7c200c200741f8006a" + "29030020072903702204200e7c220e200454ad7c7c220f200c54ad7c7c22" + "0c200154ad7c7c2204200254ad7c2004200741386a290300200729033022" + "0120107c2202200154ad7c2002200c7c2210200254ad7c7c2211200454ad" + "7c7c2214200354ad7c0b2104200720143703d002200720103703c0022007" + "200e3703b002200720123703a002200720043703d802200720113703c802" + "2007200f3703b802200720133703a80220074188036a4200370300200741" + "80036a4200370300200741f8026a4200370300200742003703f002200741" + "f0026a210a41ff032109420021034200210442002101420021024201210d" + "0340200741106a2009410776410474220b200741a0026a6a220829030020" + "08290308200941ff00712208104e2004423f88210c20044201862003423f" + "888421042007290310420183200342018684210302400240024002400240" + "200c200142018684220c42ddb0858ce8b691a8b87f852002420186200142" + "3f8884220242a9c0c689aece93b230858450044020032005542004200654" + "20042006511b450d0142ddb0858ce8b691a8b87f210142a9c0c689aece93" + "b23021020c020b200c42ddb0858ce8b691a8b87f58200242a9c0c689aece" + "93b23058200242a9c0c689aece93b230511b450d00200c21010c010b2002" + "42a9c0c689aece93b2307d200c42a3cffaf397c9eed7c7007c2202200420" + "0654ad200420067d22042003200554ad220f54ad7c7d220142017c221020" + "0254ad200c42ddb0858ce8b691a8b87f54ad7d2010420052ad7c50ad7d21" + "022004200f7d2104200320057d2103200941016a41810249200d42005271" + "0d014200210d0b2009450d010c020b4201210d20072008104f200a200b6a" + "22082008290300200729030084370300200841086a220820082903002007" + "41086a2903008437030020090d010b200020023703182000200137031020" + "0020043703082000200337030020074190036a24000f0b200941016b2109" + "0c000b000beb0101017f41e0a9c00041e0a9c0002d00002200410120001b" + "3a00000240200004400340024002400240200041016b0e03000501020b03" + "4041e0a9c0002d000022004101460d000b02400240200041016b0e030006" + "01030b000b41a49bc000412641cc9bc0001011000b41a89ac000410d4194" + "9bc0001011000b41e0a9c00041e0a9c0002d00002200410120001b3a0000" + "20000d000b0b41d8a9c00042a9c0c689aece93b23037030041d0a9c00042" + "ddb0858ce8b691a8b87f37030041c8a9c000428d95c7c396d2dac0977f37" + "030041c0a9c00042c7faf3c3ed82a3903c37030041e0a9c00041023a0000" + "0b0b840202047e017f200041086a29030021092000290300210a0240417f" + "2000290310220b200385200041186a290300220c20048584420052200320" + "0b562004200c562004200c511b1b220d417f470440200d41ff01710d0120" + "01200a58200220095820022009511b0d010b20072007200b7c220756ad20" + "07200620097c220b200654ad200b2005200a7c220a200554ad7c2209200b" + "54ad7c7c220b200754ad7c2008200c7c7c210c0b2000200a20017d370300" + "2000200920027d22072001200a56ad22017d37030820002003427f852203" + "200b7c220a2002200956ad2001200756ad7c7d42017c2209370310200020" + "0c20047d2003200a56ad2009200a54ad7c50ad7d3703180bbe3c020e7f04" + "7e23004180016b2203240041bda9c0002d00001a0240412010012202450d" + "00200242a9c0c689aece93b230370018200242ddb0858ce8b691a8b87f37" + "00102002428d95c7c396d2dac0977f370008200242c7faf3c3ed82a3903c" + "3700002003200210262000027f0240024002400240024002400240024002" + "40024002400240024002400240027f024002400240024002400240024002" + "7f02400240027f0240024002400240024002400240024002400240024002" + "400240024002400240024002400240200241046b28020022044178714124" + "4128200441037122051b4f044020054100200441c8004f1b0d0120021004" + "41bda9c0002d00001a412010012202450d30200241186a2204200141186a" + "290000370000200220012900002210370000200241106a2205200141106a" + "290000370000200241086a2208200141086a29000037000020022002411f" + "6a22012d00003a0000200120103c000020022d0001210120022002411e6a" + "22072d00003a0001200720013a00002002411d6a22012d00002107200120" + "022d00023a0000200220073a00022002411c6a22012d0000210720012002" + "2d00033a0000200220073a00032002411b6a22012d00002107200120022d" + "00043a0000200220073a00042002411a6a22012d00002107200120022d00" + "053a0000200220073a0005200241196a22012d00002107200120022d0006" + "3a0000200220073a000620042d00002101200420022d00073a0000200220" + "013a0007200241176a22012d00002104200120082d00003a000020082004" + "3a0000200241166a22012d00002104200120022d00093a0000200220043a" + "0009200241156a22012d00002104200120022d000a3a0000200220043a00" + "0a200241146a22012d00002104200120022d000b3a0000200220043a000b" + "200241136a22012d00002104200120022d000c3a0000200220043a000c20" + "0241126a22012d00002104200120022d000d3a0000200220043a000d2002" + "41116a22012d00002104200120022d000e3a0000200220043a000e20052d" + "00002101200520022d000f3a0000200220013a000f2003410c6a20021026" + "200241046b280200220141787141244128200141037122041b490d022004" + "4100200141c8004f1b0d032002100420032802082202450d120240024002" + "40200241016b220241feffffff0371450440200241ffffffff0371220441" + "016a2205410371210142002110200328020422082102200441034f044020" + "0541fcffffff07712104034020104280017c2110200241106a2102200441" + "046b22040d000b0b2001450d020340200235020020108620117c21112010" + "42207c2110200241046a2102200141016b22010d000b2011428080808010" + "540d010b200341406b200341146a2802003602002003200329020c370338" + "200341d0006a200341086a28020022043602002003200329020037034820" + "04450d0720032802402207450440200341206a418098c000280200220236" + "02002003412c6a2002360200200341f897c0002902002210370318200320" + "10370224200328024822020440200328024c220441046b28020022014178" + "7122052002410274220241044108200141037122011b6a490d0a20014100" + "2005200241276a4b1b0d0b200410040b20032802382202450d2520032802" + "3c220441046b280200220141787122052002410274220241044108200141" + "037122011b6a490d0b200141002005200241276a4b1b0d0c200410040c25" + "0b0240027f02400240024020044101460440200328024c220c2802002202" + "4101470d012003412c6a418098c000280200360200200341206a20034114" + "6a2802003602002003200329020c370318200341f897c000290200370224" + "20032802482202450d2a200c41046b280200220141787122042002410274" + "220241044108200141037122011b6a490d12200141002004200241276a4b" + "1b0d13200c10040c2a0b200328024c210c200328023c210b0240417f2004" + "200747200420074b1b22050d0020074102742102200b41046b2106200441" + "02742101200c41046b2109200420076b21070340200204402001450d0720" + "0220066a2105200120096a2108200241046b2102200141046b2101417f20" + "082802002208200528020022054720052008491b2205450d010c020b0b41" + "7f4100200741ffffffff03711b21050b200541ff01710e020204010b2002" + "450d1220074102742101200328023c2109200241ffff034d044020094104" + "6b2106410021040340200120066a22052005280200220541107622082008" + "20044110747220026e220420026c6b411074200541ffff03717222052002" + "6e22082004411074723602002005200220086c6b2104200141046b22010d" + "000b0c280b2002ad2110200741ffffffff036a220541ffffffff03712202" + "45044042002111200120096a0c270b200241016a41feffffff0771210120" + "0741027420096a41086b2102420021110340200241046a22042004350200" + "201142208684221120108022123e0200200220023502002011201020127e" + "7d42208684221120108022123e02002011201020127e7d2111200241086b" + "2102200141026b22010d000b0c250b2003412c6a200341146a2802003602" + "002003200329020c370224200341186a0c010b2003410036024020032802" + "38047f200b05200341386a418c87c0001023200328023c0b410136020020" + "0341406b4101360200200341206a41013602002003200329033837031820" + "0341246a0b220241086a418098c000280200360200200241f897c0002902" + "0037020020032802482202450d25200c41046b2802002201417871220420" + "02410274220241044108200141037122011b6a490d102001410020042002" + "41276a4b1b0d11200c10040c250b200c20044102746a41046b2202450d20" + "20022802002202672208450440200341f8006a200341146a280200360200" + "2003200329020c370370200341186a200341f0006a200c20041024200328" + "02482202450d25200c41046b280200220141787122042002410274220241" + "044108200141037122011b6a490d12200141002004200241276a4b1b0d13" + "200c10040c250b024002402003280238418080808078470d00200b280208" + "0d002003410036026c20034280808080c0003702640c010b200341e4006a" + "2003410c6a2002452008411f7110250b200341186a200341e4006a027f02" + "402003280248418080808078470d00200c2802080d004100210420034100" + "3602704100210541040c010b200341f0006a20032002452008411f711025" + "200328027021042003280278210520032802740b220120051024200341e0" + "006a200341206a28020036020020032003290218370358200328022c2105" + "200328022821092003280224210c20040440200141046b28020022074178" + "7122062004410274220441044108200741037122071b6a490d1420074100" + "2006200441276a4b1b0d15200110040b02400240200c4180808080784604" + "404100210120092802080d0141042105410021040c220b41002101200545" + "0d20200520024522044d0d20200520046b210b20020d0102400240200b41" + "0274220a20092206200620044102746a22056b4b04402005200a6a210120" + "06200a6a2106200a4110490d0141002006410371220d6b210e0240200641" + "7c71220220064f0d00200d41016b210f0240200d450440200121040c010b" + "200d2107200121040340200641016b2206200441016b22042d00003a0000" + "200741016b22070d000b0b200f4103490d00200441046b21040340200641" + "016b200441036a2d00003a0000200641026b200441026a2d00003a000020" + "0641036b200441016a2d00003a0000200641046b220620042d00003a0000" + "200441046b210420022006490d000b0b2002200a200d6b2204417c71220a" + "6b21064100200a6b210702402001200e6a2201410371450440200220064d" + "0d01200420056a41046b21050340200241046b2202200528020036020020" + "0541046b2105200220064b0d000b0c010b200220064d0d00200141037422" + "0a411871210d2001417c71220f41046b21054100200a6b411871210e200f" + "280200210a0340200241046b2202200a200e742005280200220a200d7672" + "360200200541046b2105200220064b0d000b0b2004410371210a20012007" + "6a21010c010b200a41104f044002402006410020066b41037122076a2204" + "20064d0d00200741016b210d200521022007044020072101034020062002" + "2d00003a0000200241016a2102200641016a2106200141016b22010d000b" + "0b200d4107490d000340200620022d00003a0000200641016a200241016a" + "2d00003a0000200641026a200241026a2d00003a0000200641036a200241" + "036a2d00003a0000200641046a200241046a2d00003a0000200641056a20" + "0241056a2d00003a0000200641066a200241066a2d00003a000020064107" + "6a200241076a2d00003a0000200241086a2102200641086a22062004470d" + "000b0b2004200a20076b2201417c71220d6a21060240200520076a220241" + "0371450440200420064f0d01200221050340200420052802003602002005" + "41046a2105200441046a22042006490d000b0c010b200420064f0d002002" + "410374220a41187121072002417c71220f41046a21054100200a6b411871" + "210e200f280200210a03402004200a2007762005280200220a200e747236" + "0200200541046a2105200441046a22042006490d000b0b2001410371210a" + "2002200d6a21050b20062006200a6a22044f0d01200a41016b2101200a41" + "0771220204400340200620052d00003a0000200541016a2105200641016a" + "2106200241016b22020d000b0b20014107490d010340200620052d00003a" + "0000200641016a200541016a2d00003a0000200641026a200541026a2d00" + "003a0000200641036a200541036a2d00003a0000200641046a200541046a" + "2d00003a0000200641056a200541056a2d00003a0000200641066a200541" + "066a2d00003a0000200641076a200541076a2d00003a0000200541086a21" + "05200641086a22062004470d000b0c010b2006200a6b220220064f0d0020" + "0a41016b2104200a410371220504400340200641016b2206200141016b22" + "012d00003a0000200541016b22050d000b0b20044103490d00200141046b" + "21050340200641016b200541036a2d00003a0000200641026b200541026a" + "2d00003a0000200641036b200541016a2d00003a0000200641046b220620" + "052d00003a0000200541046b210520022006490d000b0b0c010b41042105" + "200941046a28020021072009280208220420024522024d04402004410274" + "21022004044041bda9c0002d00001a200210012205450d360b2005200720" + "02104c1a0c210b41bda9c0002d00001a200420026b220b41027422011001" + "2209450d342009200720024102746a2001104c1a200b210c0b2008411f71" + "2201450d1c200b450440410021010c1e0b41002105410020086b411f7121" + "042009200b4102746a2102200b41016b41ffffffff0371220741016a2206" + "410371210820074103490d1b200641fcffffff077121070340200241046b" + "220620062802002206200176200572360200200241086b22052006200474" + "20052802002205200176723602002002410c6b2206200520047420062802" + "00220620017672360200200241106b220220062004742002280200220520" + "01767236020020052004742105200741046b22070d000b0c1b0b2011500d" + "14200328021421022003280210210502402011428080045a04402002450d" + "0320024102742104200241ffffffff036a220741ffffffff037122020d01" + "42002110200420056a0c180b2002450d022011a721040c180b200241016a" + "41feffffff07712101200420056a41086b21024200211003402002350200" + "200241046a35020020104220868420118242208684201182211020024108" + "6b2102200141026b22010d000b0c150b2003280210210520032802142202" + "0d160b410421074100210241000c170b41f996c000412e41a897c0001011" + "000b41b897c000412e41e897c0001011000b41f996c000412e41a897c000" + "1011000b41b897c000412e41e897c0001011000b20034100360228200341" + "0136021c200341a099c00036021820034204370220200341186a41fc86c0" + "00101a000b41f996c000412e41a897c0001011000b41b897c000412e41e8" + "97c0001011000b41f996c000412e41a897c0001011000b41b897c000412e" + "41e897c0001011000b41f996c000412e41a897c0001011000b41b897c000" + "412e41e897c0001011000b200341003602282003410136021c200341a099" + "c00036021820034204370220200341186a41ec86c000101a000b41f996c0" + "00412e41a897c0001011000b41b897c000412e41e897c0001011000b41f9" + "96c000412e41a897c0001011000b41b897c000412e41e897c0001011000b" + "41f996c000412e41a897c0001011000b41b897c000412e41e897c0001011" + "000b200341003602282003410136021c200341a099c00036021820034204" + "370220200341186a41989ac000101a000b200241086a0b21022007410171" + "047e201005200241046b3502002010422086842011820ba721010c010b20" + "0241027421024100210103402001411074200241046b220220056a280200" + "220141107672200470411074200141ffff037172200470210120020d000b" + "0b41002102200341206a418098c000280200360200200341f897c0002902" + "0037031820014504404104210741000c010b200341186a41f498c0001023" + "200328021c220720013602004101210220032802180b210a024002400240" + "0240200328020022010440200841046b2802002204417871220620014102" + "74220141044108200441037122041b6a490d01200441002006200141276a" + "4b1b0d02200810040b200328020c2201450d0e200541046b280200220441" + "787122082001410274220141044108200441037122041b6a490d02200441" + "002008200141276a4b1b0d03200510040c0e0b41f996c000412e41a897c0" + "001011000b41b897c000412e41e897c0001011000b41f996c000412e41a8" + "97c0001011000b41b897c000412e41e897c0001011000b2008450d002002" + "41046b21020340200220022802002207200176200572360200200241046b" + "210220072004742105200841016b22080d000b0b41002101200b450d0020" + "09200b41027422026a41046b2802000440200b21010c010b200941046b21" + "07200b41ffffffff037121040340200421052002450d01200441016b2104" + "200220076a2108200241046b21022008280200450d000b200b2005200520" + "0b4b1b21010b2001200c4102764f0d00024002402001200c4d0440410021" + "04200c450440200921050c050b200c41027421022001450440200941046b" + "2802002205417871220841044108200541037122051b20026a490d022005" + "41002008200241276a4b1b0d0320091004410421050c050b200121042009" + "200241042001410274101522050d040c180b200341003602282003410136" + "021c200341ec84c00036021820034204370220200341186a41f484c00010" + "1a000b41f996c000412e41a897c0001011000b41b897c000412e41e897c0" + "001011000b200c2104200921050b200341206a200341e0006a2802003602" + "00200320032903583703182003200136022c200320053602282003200436" + "02240c040b419c87c0001020000b200241086a0b21022005410171047e20" + "1105200241046b22022002350200201142208684221120108022123e0200" + "2011201020127e7d0ba721040b2003280238210b02402009200741027422" + "026a41046b2802000d00200941046b210620072101034020012105200245" + "0440410021070c020b200541016b2101200220066a2108200241046b2102" + "2008280200450d000b20072005200520074b1b21070b0240200b41027620" + "074d0440200b21020c010b2007200b4b0d0341002102200b450d00200b41" + "027421012007450440200941046b28020022054178712208410441082005" + "41037122051b20016a490d05200541002008200141276a4b1b0d06200910" + "04410421090c010b2009200141042007220241027410152209450d100b20" + "034100360250200404402003280248047f200c05200341c8006a41dc86c0" + "001023200328024c0b2004360200200341013602500b2003412c6a200341" + "d0006a280200360200200320032903483702242003200936021c20032002" + "3602180b200328022c2102200328022821072003280224210a2003280218" + "2201450d00200328021c220541046b280200220441787122082001410274" + "220141044108200441037122041b6a490d04200441002008200141276a4b" + "1b0d05200510040b200245044041bda9c0002d00001a4101210d41011001" + "2204450d0e200441003a0000410121010c080b4100210102402002ad4205" + "86200720024102746a41046b28020067ad7d221042038820104207834200" + "52ad7c221050044041012104410021050c010b41bda9c0002d00001a2010" + "a7220510012204450d0e0b200341003602202003200436021c2003200536" + "02182007200241016b22054102746a210920050440200241027441046b21" + "06410021020340200220076a280200210120032802182002460440200341" + "186a41ac88c0001018200328021c21040b200220046a20013a0000200320" + "0241016a2205360220200141087621082003280218200546044020034118" + "6a41ac88c0001018200328021c21040b200220046a41016a20083a000020" + "03200541016a220536022020014110762108200328021820054604402003" + "41186a41ac88c0001018200328021c21040b200220046a41026a20083a00" + "002003200541016a22053602202001411876210120032802182005460440" + "200341186a41ac88c0001018200328021c21040b200220046a41036a2001" + "3a00002003200541016a2205360220200241046a21012005210220012006" + "470d000b0b20092802002202450d05034020032802182001460440200341" + "186a419c88c00010180b200328021c220420016a20023a00002003200141" + "016a2201360220200241ff014b21052002410876210220050d000b0c060b" + "200341003602282003410136021c200341ec84c000360218200342043702" + "20200341186a41f484c000101a000b41f996c000412e41a897c000101100" + "0b41b897c000412e41e897c0001011000b41f996c000412e41a897c00010" + "11000b41b897c000412e41e897c0001011000b200328021c21040b200328" + "0218210d200141014b0d010b200341306a4200370300200341286a420037" + "0300200341206a4200370300200342003703180c010b200120046a210c41" + "002102200141017622084101470440200141016b2105200841feffffff07" + "71210b0340200420056a22062d000021092006200220046a22082d00003a" + "0000200820093a0000200c2002417e736a22062d00002109200620084101" + "6a22082d00003a0000200820093a0000200541026b2105200b200241026a" + "2202470d000b0b20014102710440200220046a22052d000021082005200c" + "2002417f736a22022d00003a0000200220083a00000b200341306a420037" + "0300200341286a4200370300200341206a42003703002003420037031820" + "0141204b0d010b200320016b41386a20042001104c1a2003290328221042" + "388620104280fe0383422886842010428080fc0783421886201042808080" + "f80f834208868484201042088842808080f80f832010421888428080fc07" + "838420104228884280fe038320104238888484842112200341306a290300" + "221042388620104280fe0383422886842010428080fc0783421886201042" + "808080f80f834208868484201042088842808080f80f8320104218884280" + "80fc07838420104228884280fe038320104238888484842113417f200329" + "0318221042b0c8b99297bc8cd02985200341206a290300221142b8a195b2" + "9bb0a0acdd008584420052201142388620114280fe038342288684201142" + "8080fc0783421886201142808080f80f8342088684842011420888428080" + "80f80f832011421888428080fc07838420114228884280fe038320114238" + "88848484221142ddb0858ce8b691a8b87f54201042388620104280fe0383" + "422886842010428080fc0783421886201042808080f80f83420886848420" + "1042088842808080f80f832010421888428080fc07838420104228884280" + "fe03832010423888848484221042a9c0c689aece93b23054201042a9c0c6" + "89aece93b230511b1b2202417f47044041022101200241ff01710d022013" + "42c7faf3c3ed82a3903c542012428d95c7c396d2dac0977f542012428d95" + "c7c396d2dac0977f511b450d020b20002011370320200020133703102000" + "20103703282000201237031841000c020b410021010b200020013a000141" + "010b3a00000240024002400240200a0440200741046b2802002202417871" + "2201200a410274220541044108200241037122021b6a490d012002410020" + "01200541276a4b1b0d02200710040b200d0440200441046b280200220241" + "7871220141044108200241037122021b200d6a490d03200241002001200d" + "41276a4b1b0d04200410040b20034180016a24000f0b41f996c000412e41" + "a897c0001011000b41b897c000412e41e897c0001011000b41f996c00041" + "2e41a897c0001011000b41b897c000412e41e897c0001011000b000bc80d" + "02057f167e230041e0006b22032400200341386a2204200141186a290300" + "370300200341306a2205200141106a290300370300200320012903003703" + "202003200141086a29030037032842ddb0858ce8b691a8b87f2112200341" + "206a20022903002219200241086a290300221a2002290310221b20024118" + "6a290300221c42c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b20" + "042903002113200529030021142003290320211520032903282116200341" + "106a2206200141306a290300370300200341186a2207200141386a290300" + "370300200320012903203703002003200141286a29030037030820032002" + "290320220e200241286a290300220c20022903302211200241386a290300" + "221d42c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b2004200729" + "030037030020052006290300370300200320032903083703282003200329" + "0300370320200341206a42c6faf3c3ed82a3903c428d95c7c396d2dac097" + "7f42ddb0858ce8b691a8b87f42a9c0c689aece93b23042c7faf3c3ed82a3" + "903c428d95c7c396d2dac0977f102b02400240024020142005290300220b" + "7c220d2016200329032822087c2209200854ad2009201520032903202208" + "7c220a200854ad7c2208200954ad7c7c220942ddb0858ce8b691a8b87f85" + "200b200d56ad2009200d54ad7c201320042903007c7c220d42a9c0c689ae" + "ce93b2308584500440200a42c7faf3c3ed82a3903c542008428d95c7c396" + "d2dac0977f542008428d95c7c396d2dac0977f511b450d0242a9c0c689ae" + "ce93b230210d0c010b200942deb0858ce8b691a8b87f54200d42a9c0c689" + "aece93b23054200d42a9c0c689aece93b230511b450d01200921120b200a" + "2117200821180c010b200d20092008200a42c7faf3c3ed82a3903c7d2217" + "200a5aad220a7d220b42f3eab8bce9ada5bfe8007c2218200b54ad200820" + "0a54ad7d7c2208200954ad200842a2cffaf397c9eed7c7007c2212200854" + "ad7c50ad7d42a9c0c689aece93b2307d210d0b42ddb0858ce8b691a8b87f" + "210f024002402001290330221020012903107c2209200141286a29030022" + "0a200141086a2903007c2208200a54ad20082001290320220a2001290300" + "7c220b200a54ad7c220a200854ad7c7c220842ddb0858ce8b691a8b87f85" + "2009201054ad2008200954ad7c200141386a290300200141186a2903007c" + "7c220942a9c0c689aece93b2308584500440200b42c7faf3c3ed82a3903c" + "54200a428d95c7c396d2dac0977f54200a428d95c7c396d2dac0977f511b" + "450d01200b2110200a210b42a9c0c689aece93b23021090c020b200842de" + "b0858ce8b691a8b87f54200942a9c0c689aece93b23054200942a9c0c689" + "aece93b230511b450d00200b2110200a210b2008210f0c010b2009200820" + "0a200b42c7faf3c3ed82a3903c7d2210200b5aad220f7d220942f3eab8bc" + "e9ada5bfe8007c220b200954ad200a200f54ad7d7c220a200854ad200a42" + "a2cffaf397c9eed7c7007c220f200a54ad7c50ad7d42a9c0c689aece93b2" + "307d21090b2003200f37035020032010370340200320093703582003200b" + "37034842ddb0858ce8b691a8b87f210b024002402011201b7c2209200c20" + "1a7c2208200c54ad2008200e20197c220c200e54ad7c220a200854ad7c7c" + "220842ddb0858ce8b691a8b87f852009201154ad2008200954ad7c201c20" + "1d7c7c220942a9c0c689aece93b2308584500440200c42c7faf3c3ed82a3" + "903c54200a428d95c7c396d2dac0977f54200a428d95c7c396d2dac0977f" + "511b450d01200c210e200a210c42a9c0c689aece93b23021090c020b2008" + "42deb0858ce8b691a8b87f54200942a9c0c689aece93b23054200942a9c0" + "c689aece93b230511b450d00200c210e200a210c2008210b0c010b200920" + "08200a200c42c7faf3c3ed82a3903c7d220e200c5aad22117d220b42f3ea" + "b8bce9ada5bfe8007c220c200b54ad200a201154ad7d7c220a200854ad20" + "0a42a2cffaf397c9eed7c7007c220b200a54ad7c50ad7d42a9c0c689aece" + "93b2307d21090b200341406b200e200c200b200942c7faf3c3ed82a3903c" + "428d95c7c396d2dac0977f102b200341406b201520162014201342c7faf3" + "c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9" + "c0c689aece93b230102d200341406b200329030020032903082003290310" + "200341186a29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42" + "ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2000200d37031820" + "002012370310200020183703082000201737030020002003290340370320" + "200041286a2003290348370300200041306a200341d0006a290300370300" + "200041386a200341d8006a290300370300200341e0006a24000ba706010a" + "7e42ddb0858ce8b691a8b87f210a02400240024020022903102206200129" + "03107c2207200241086a2903002203200141086a2903007c2204200354ad" + "20042002290300220320012903007c2205200354ad7c2203200454ad7c7c" + "220442ddb0858ce8b691a8b87f852006200756ad2004200754ad7c200241" + "186a290300200141186a2903007c7c220742a9c0c689aece93b230858450" + "0440200542c7faf3c3ed82a3903c542003428d95c7c396d2dac0977f5420" + "03428d95c7c396d2dac0977f511b450d0242a9c0c689aece93b23021070c" + "010b200442deb0858ce8b691a8b87f54200742a9c0c689aece93b2305420" + "0742a9c0c689aece93b230511b450d012004210a0b2005210b2003210c0c" + "010b200720042003200542c7faf3c3ed82a3903c7d220b20055aad22057d" + "220642f3eab8bce9ada5bfe8007c220c200654ad2003200554ad7d7c2203" + "200454ad200342a2cffaf397c9eed7c7007c220a200354ad7c50ad7d42a9" + "c0c689aece93b2307d21070b42ddb0858ce8b691a8b87f21080240024020" + "02290330220920012903307c2204200241286a2903002205200141286a29" + "03007c2203200554ad20032002290320220520012903207c2206200554ad" + "7c2205200354ad7c7c220342ddb0858ce8b691a8b87f852004200954ad20" + "03200454ad7c200241386a290300200141386a2903007c7c220442a9c0c6" + "89aece93b2308584500440200642c7faf3c3ed82a3903c542005428d95c7" + "c396d2dac0977f542005428d95c7c396d2dac0977f511b450d0120062109" + "2005210642a9c0c689aece93b23021040c020b200342deb0858ce8b691a8" + "b87f54200442a9c0c689aece93b23054200442a9c0c689aece93b230511b" + "450d002006210920052106200321080c010b200420032005200642c7faf3" + "c3ed82a3903c7d220920065aad22087d220442f3eab8bce9ada5bfe8007c" + "2206200454ad2005200854ad7d7c2205200354ad200542a2cffaf397c9ee" + "d7c7007c2208200554ad7c50ad7d42a9c0c689aece93b2307d21040b2000" + "2008370330200020093703202000200a3703102000200b37030020002004" + "37033820002006370328200020073703182000200c3703080bf10802087f" + "087e23004180016b22022400200141386a290300210e200141286a290300" + "210b200141186a2203290300210d2001290330210f2001290320210a2001" + "290310210c02400240024020012903002210200141086a22042903002211" + "844200520d00200c200d844200520d00200a200b844200520d00200e200f" + "84500d010b200241186a22052003290300370300200241106a2206200141" + "106a22072903003703002002200429030037030820022001290300370300" + "200220102011200c200d42c7faf3c3ed82a3903c428d95c7c396d2dac097" + "7f102b200241386a2204200141206a220341186a29030037030020024130" + "6a2208200341106a22092903003703002002200341086a29030037032820" + "022003290300370320200241206a200a200b200f200e42c7faf3c3ed82a3" + "903c428d95c7c396d2dac0977f102b200241206a42c6faf3c3ed82a3903c" + "428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93" + "b23042c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b2002200229" + "032020022903282008290300200429030042c7faf3c3ed82a3903c428d95" + "c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b23010" + "2d2000027e2002290300220d2006290300220c842002290308220b200529" + "0300220a84845004404200210f42000c010b200241d8006a2204200a3703" + "002002200c3703502002200d3703402002200b370348200242a9c0c689ae" + "ce93b230370378200242ddb0858ce8b691a8b87f3703702002428d95c7c3" + "96d2dac0977f370368200242c7faf3c3ed82a3903c370360200241406b20" + "0241e0006a103a2004290300210d2002290348210c2002290340210b2002" + "290350210a200241d0006a20072903003703002004200141186a29030037" + "0300200220012903003703402002200141086a290300370348200241406b" + "200b200c200a200d42c7faf3c3ed82a3903c428d95c7c396d2dac0977f10" + "2b200241f8006a2201200341186a290300370300200241f0006a22042009" + "2903003703002002200341086a2903003703682002200329030037036020" + "0241e0006a200b200c200a200d42c7faf3c3ed82a3903c428d95c7c396d2" + "dac0977f102b2004290300220c20022903602210842001290300220e2002" + "290368220b84845004404200210c4200210b4200210a4200210e4200210f" + "42010c010b4200210f427f4200427f4200201042788342c7faf3c3ed82a3" + "903c561b220a200a200b54ad7d200a200b7d220a42f3eab8bce9ada5bfe8" + "007d220b200a54ad7c42017c2211200c7d220d42a4cffaf397c9eed7c700" + "7d220a200d54ad200c201156ad7d427f511b200e7d42a9c0c689aece93b2" + "307c210e42c7faf3c3ed82a3903c20107d210c42010b3703002000200a37" + "03402000200c370330200020022903403703102000200f3703082000200e" + "3703482000200b370338200041186a2002290348370300200041206a2002" + "41d0006a290300370300200041286a200241d8006a2903003703000c010b" + "20004200370308200042003703000b20024180016a24000b090020004100" + "3602000b7b01027f230041106b2203240041f0a5c00041f0a5c000280200" + "220441016a360200024020044100480d00024041bca9c0002d0000450440" + "41b8a9c00041b8a9c00028020041016a36020041eca5c00028020041004e" + "0d010c020b200341086a20002001110000000b41bca9c00041003a000020" + "02450d00000b000b0c00200020012902003703000bba0201047f411f2102" + "20004200370210200141ffffff074d04402001410620014108766722026b" + "7641017120024101746b413e6a21020b2000200236021c200241027441f4" + "a5c0006a2103410120027422044190a9c000280200714504402003200036" + "0200200020033602182000200036020c200020003602084190a9c0004190" + "a9c0002802002004723602000f0b02400240200120032802002204280204" + "417871460440200421020c010b2001411920024101766b41002002411f47" + "1b742103034020042003411d764104716a41106a22052802002202450d02" + "200341017421032002210420022802044178712001470d000b0b20022802" + "082203200036020c20022000360208200041003602182000200236020c20" + "0020033602080f0b20052000360200200020043602182000200036020c20" + "0020003602080bd20102067f017e230041206b2201240002400240200028" + "02002203417f460d00410420034101742202200341016a2204200220044b" + "1b2202200241044d1b2204ad42e0007e22074220884200520d002007a722" + "0641f0ffffff074b0d004100210220012003047f2001200341e0006c3602" + "1c2001200028020436021441100520020b360218200141086a2006200141" + "146a103720012802084101470d0120012802102102200128020c21050b20" + "0541dca4c0001019000b200128020c210320002004360200200020033602" + "04200141206a24000b7f01017f027f0240027f0240200228020404402002" + "28020822034504402001450d0441bda9c0002d00001a0c020b2002280200" + "20034110200110150c020b2001450d0241bda9c0002d00001a0b2001100b" + "0b2202411020021b21032002450c010b4110210341000b21022000200136" + "020820002003360204200020023602000bd20102067f017e230041206b22" + "0124000240024020002802002203417f460d004104200341017422022003" + "41016a2204200220044b1b2202200241044d1b2204ad42c0017e22074220" + "884200520d002007a7220641f0ffffff074b0d004100210220012003047f" + "2001200341c0016c36021c2001200028020436021441100520020b360218" + "200141086a2006200141146a103720012802084101470d01200128021021" + "02200128020c21050b200541eca4c0001019000b200128020c2103200020" + "0436020020002003360204200141206a24000bdd0102067f017e23004120" + "6b2202240020002802002204417f460440410020011019000b4104200441" + "01742203200441016a2205200320054b1b2203200341044d1b2205ad42c0" + "017e22084220884200520440410020011019000b02402008a7220741f0ff" + "ffff074d04404100210320022004047f2002200441c0016c36021c200220" + "0028020436021441100520030b360218200241086a2007200241146a1037" + "20022802084101470d01200228020c2106200228021021030b2006200110" + "19000b200228020c21042000200536020020002004360204200241206a24" + "000b830b02037f167e230041c0016b22022400200241186a220320004118" + "6a290300370300200241106a2204200041106a2903003703002002200029" + "03003703002002200041086a290300370308200241386a200141186a2903" + "002218370300200241306a200141106a2903002213370300200220014108" + "6a2903002214370328200220012903002215370320200242003703582002" + "42003703502002420037034820024201370340200241f8006a2201420037" + "0300200241f0006a42003703002002420037036820024200370360200329" + "0300210e2004290300210f2002290308210a200229030021072013211020" + "182111201521082014210b03400240200242003703980120024200370390" + "0120024200370388012002420137038001200220024180016a104a450440" + "200241406b21010c010b200241b8016a20024198016a2903003703002002" + "41b0016a20024190016a29030037030020022002290388013703a8012002" + "2002290380013703a001200241206a200241a0016a104a450440200241e0" + "006a21010c010b200241d8006a2903002112200229035021052002290348" + "21162002290340210d2007a74101714504400340200a423f862007420188" + "8421070240200da74101714504402016423f86200d42018884210d200542" + "3f8620164201888421160c010b200520137c2209201420167c2205201454" + "ad2005200d20157c220d201554ad7c2206200554ad7c7c2205423f862006" + "4201888421162006423f86200d42018884210d2009201354ad2005200954" + "ad7c201220187c7c21120b200f423f86200a42018884210a200e423f8620" + "0f42018884210f200e420188210e2012423f862005420188842105201242" + "018821122007420183500d000b2002200f3703102002200e3703180b2002" + "20053703502002200d370340200220073703002002201237035820022016" + "3703482002200a3703082001290300210920022903702106200229036821" + "172002290360210c2008a74101714504400340200b423f86200842018884" + "21080240200c420183a70440200620137c2219201420177c2206201454ad" + "2006200c20157c221a201554ad7c220c200654ad7c7c2206423f86200c42" + "0188842117200c423f86201a42018884210c2013201956ad2006201954ad" + "7c200920187c7c21090c010b2017423f86200c42018884210c2006423f86" + "20174201888421170b2010423f86200b42018884210b2011423f86201042" + "0188842110201142018821112009423f8620064201888421062009420188" + "21092008420183500d000b20022010370330200220113703380b20022006" + "3703702002200c3703602002200837032020022009370378200220173703" + "682002200b37032802400240200f201085200e2011858450044020072008" + "54200a200b54200a200b511b0d010c020b200f201056200e201156200e20" + "11511b0d010b2002200820077d427e8322063703202002200b200a7d2209" + "2007200856ad22087d220c37032820024201200a200b56ad2008200956ad" + "7c7d2208200f7d220b20107c220942017d221037033020022011200e7d20" + "09420052ad2009200b54ad2008200f54ad7d7c50ad7d2211370338200241" + "e0006a200d2016200520122015201420132018102d20062108200c210b0c" + "020b2002200720087d427e8322123703002002200a200b7d220520072008" + "54ad22077d220d37030820024201200a200b54ad2005200754ad7c7d2207" + "200f7c220520107d220a42017d220f3703102002200e20117d200a420052" + "ad2005200754ad2005201054ad7d7c50ad7d220e370318200241406b200c" + "2017200620092015201420132018102d20122107200d210a0c010b0b2000" + "2001290300370300200041186a200141186a290300370300200041106a20" + "0141106a290300370300200041086a200141086a290300370300200241c0" + "016a24000bc92602357f187e230041c0066b22032400200341386a222b20" + "0141386a2226290300370300200341306a222c200141306a220e29030037" + "0300200341286a222d200141286a220f290300370300200341206a222e20" + "0141206a2210290300370300200341186a222f200141186a221129030037" + "0300200341106a2230200141106a22122903003703002003200129030037" + "03002003200141086a2227290300370308200320012002102f200341f800" + "6a2214200141f8006a2204290300370300200341f0006a2215200141f000" + "6a2205290300370300200341e8006a2216200141e8006a22062903003703" + "00200341e0006a2217200141e0006a2207290300370300200341d8006a22" + "0a200141d8006a2208290300370300200341d0006a220b200141d0006a22" + "092903003703002003200141c8006a220c29030037034820032001290340" + "370340200341406b200141406b2213200241406b2228102f200341b8016a" + "2220200141b8016a290300370300200341b0016a2221200141b0016a2903" + "00370300200341a8016a2222200141a8016a290300370300200341a0016a" + "2223200141a0016a29030037030020034198016a222420014198016a2903" + "0037030020034190016a222520014190016a290300370300200320014188" + "016a2903003703880120032001290380013703800120034180016a200141" + "80016a222920024180016a222a102f200341f8016a221820042903003703" + "00200341f0016a22192005290300370300200341e8016a221a2006290300" + "370300200341e0016a221b2007290300370300200341d8016a221c200829" + "0300370300200341d0016a221d20092903003703002003200c2903003703" + "c801200320012903403703c001200341c0016a201320291030200341b802" + "6a200241f8006a290300370300200341b0026a200241f0006a2903003703" + "00200341a8026a200241e8006a290300370300200341a0026a200241e000" + "6a29030037030020034198026a200241d8006a2903003703002003419002" + "6a200241d0006a2903003703002003200241c8006a290300370388022003" + "20022903403703800220034180026a2028202a1030200341c0056a200341" + "c0016a20034180026a102f2018200341f8056a2204290300370300201920" + "0341f0056a2205290300370300201a200341e8056a220629030037030020" + "1b200341e0056a2207290300370300201c200341d8056a22082903003703" + "00201d200341d0056a2209290300370300200320032903c8053703c80120" + "0320032903c0053703c00120034198066a220c201c290300370300200341" + "90066a220d201d290300370300200320032903c801370388062003200329" + "03c0013703800620034180066a2003290340223820032903482239200b29" + "0300223a200a290300223b42c7faf3c3ed82a3903c428d95c7c396d2dac0" + "977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200341b806" + "6a220a2018290300370300200341b0066a220b2019290300370300200320" + "1a2903003703a8062003201b2903003703a006200341a0066a2017290300" + "223c2016290300223d2015290300223e2014290300223f42c7faf3c3ed82" + "a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689" + "aece93b230102d2008200c29030022403703002009200d29030022413703" + "00200720032903a00622423703002005200b290300224337030020062003" + "2903a80622443703002004200a2903002245370300200320032903880622" + "463703c805200320032903800622473703c0052018204537030020192043" + "370300201a2044370300201b2042370300201c2040370300201d20413703" + "00200320463703c801200320473703c001200c201c290300370300200d20" + "1d290300370300200320032903c80137038806200320032903c001370380" + "0620034180066a2003290380012003290388012025290300202429030042" + "c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b8" + "7f42a9c0c689aece93b230102d200a2018290300370300200b2019290300" + "3703002003201a2903003703a8062003201b2903003703a006200341a006" + "6a202329030020222903002021290300202029030042c7faf3c3ed82a390" + "3c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece" + "93b230102d2008200c29030022403703002009200d290300224137030020" + "0720032903a00622423703002005200b2903002243370300200620032903" + "a80622443703002004200a29030022453703002003200329038806224637" + "03c805200320032903800622473703c00520182045370300201920433703" + "00201a2044370300201b2042370300201c2040370300201d204137030020" + "0320463703c801200320473703c001200342003703b805200342003703b0" + "05200342003703a805200342013703a00520034200370398052003420037" + "03900520034200370388052003420937038005200341c0056a200341c001" + "6a20034180056a102f201820042903003703002019200529030037030020" + "1a2006290300370300201b2007290300370300201c200829030037030020" + "1d2009290300370300200320032903c8053703c801200320032903c00537" + "03c001200341c0056a200341c0016a200310302018200429030037030020" + "192005290300370300201a2006290300370300201b200729030037030020" + "1c2008290300370300201d2009290300370300200320032903c8053703c8" + "01200320032903c0053703c001200341d0026a2214201229030037030020" + "0341d8026a22152011290300370300200341e0026a221620102903003703" + "00200341e8026a2217200f290300370300200341f0026a221e200e290300" + "370300200341f8026a221f2026290300370300200320012903003703c002" + "200320272903003703c802200341c0026a200120131030200341b8036a20" + "0241386a2231290300370300200341b0036a200241306a22322903003703" + "00200341a8036a200241286a2233290300370300200341a0036a20024120" + "6a223429030037030020034198036a200241186a22352903003703002003" + "4190036a200241106a22362903003703002003200241086a223729030037" + "038803200320022903003703800320034180036a200220281030200341c0" + "056a200341c0026a20034180036a102f201f2004290300370300201e2005" + "290300370300201720062903003703002016200729030037030020152008" + "29030037030020142009290300370300200320032903c8053703c8022003" + "20032903c0053703c002200c2015290300370300200d2014290300370300" + "200320032903c80237038806200320032903c0023703800620034180066a" + "200329030022402003290308224120302903002242202f290300224342c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f" + "42a9c0c689aece93b230102d200a201f290300370300200b201e29030037" + "0300200320172903003703a806200320162903003703a006200341a0066a" + "202e2903002244202d2903002245202c2903002246202b290300224742c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f" + "42a9c0c689aece93b230102d2008200c29030022483703002009200d2903" + "002249370300200720032903a006224a3703002005200b290300224b3703" + "00200620032903a806224c3703002004200a290300224d37030020032003" + "29038806224e3703c8052003200329038006224f3703c005201f204d3703" + "00201e204b3703002017204c3703002016204a3703002015204837030020" + "1420493703002003204e3703c8022003204f3703c002200c201529030037" + "0300200d2014290300370300200320032903c80237038806200320032903" + "c0023703800620034180066a20382039203a203b42c7faf3c3ed82a3903c" + "428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93" + "b230102d200a201f290300370300200b201e290300370300200320172903" + "003703a806200320162903003703a006200341a0066a203c203d203e203f" + "42c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8" + "b87f42a9c0c689aece93b230102d2008200c29030022383703002009200d" + "2903002239370300200720032903a006223a3703002005200b290300223b" + "370300200620032903a806223c3703002004200a290300223d3703002003" + "200329038806223e3703c8052003200329038006223f3703c005201f203d" + "370300201e203b3703002017203c3703002016203a370300201520383703" + "00201420393703002003203e3703c8022003203f3703c002200341f8036a" + "2020290300370300200341f0036a2021290300370300200341e8036a2022" + "290300370300200341e0036a2023290300370300200341d8036a20242903" + "00370300200341d0036a202529030037030020032003290388013703c803" + "20032003290380013703c003200341c0036a20034180016a20034180056a" + "102f200341c0056a200341c0026a200341c0036a1030201f200429030037" + "0300201e2005290300370300201720062903003703002016200729030037" + "03002015200829030037030020142009290300370300200320032903c805" + "3703c802200320032903c0053703c00220034190046a2213201229030037" + "030020034198046a22122011290300370300200341a0046a221120102903" + "00370300200341a8046a2210200f290300370300200341b0046a220f200e" + "290300370300200341b8046a220e20262903003703002003200129030037" + "038004200320272903003703880420034180046a200120291030200341f8" + "046a2031290300370300200341f0046a2032290300370300200341e8046a" + "2033290300370300200341e0046a2034290300370300200341d8046a2035" + "290300370300200341d0046a2036290300370300200320372903003703c8" + "04200320022903003703c004200341c0046a2002202a1030200341c0056a" + "20034180046a200341c0046a102f200e2004290300370300200f20052903" + "003703002010200629030037030020112007290300370300201220082903" + "0037030020132009290300370300200320032903c8053703880420032003" + "2903c00537038004200c2012290300370300200d20132903003703002003" + "2003290388043703880620032003290380043703800620034180066a2040" + "20412042204342c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0" + "858ce8b691a8b87f42a9c0c689aece93b230102d200a200e290300370300" + "200b200f290300370300200320102903003703a806200320112903003703" + "a006200341a0066a204420452046204742c7faf3c3ed82a3903c428d95c7" + "c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d" + "2008200c29030022383703002009200d2903002239370300200720032903" + "a006223a3703002005200b290300223b370300200620032903a806223c37" + "03002004200a290300223d3703002003200329038806223e3703c8052003" + "200329038006223f3703c005200e203d370300200f203b3703002010203c" + "3703002011203a37030020122038370300201320393703002003203e3703" + "88042003203f37038004200341c0056a20034180046a200341406b103020" + "0e2004290300370300200f20052903003703002010200629030037030020" + "112007290300370300201220082903003703002013200929030037030020" + "0320032903c80537038804200320032903c00537038004200c2012290300" + "370300200d20132903003703002003200329038804370388062003200329" + "0380043703800620034180066a2003290380012003290388012025290300" + "202429030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb085" + "8ce8b691a8b87f42a9c0c689aece93b230102d200a200e29030037030020" + "0b200f290300370300200320102903003703a806200320112903003703a0" + "06200341a0066a202329030020222903002021290300202029030042c7fa" + "f3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42" + "a9c0c689aece93b230102d2008200c29030022383703002009200d290300" + "2239370300200720032903a006223a3703002005200b290300223b370300" + "200620032903a806223c3703002004200a290300223d3703002003200329" + "038806223e3703c8052003200329038006223f3703c005200e203d370300" + "200f203b3703002010203c3703002011203a370300201220383703002013" + "20393703002003203e370388042003203f37038004200041386a20182903" + "00370300200041306a2019290300370300200041286a201a290300370300" + "200041206a201b290300370300200041186a201c29030037030020004110" + "6a201d290300370300200041086a20032903c801370300200020032903c0" + "01370300200020032903c002370340200041c8006a20032903c802370300" + "200041d0006a2014290300370300200041d8006a20152903003703002000" + "41e0006a2016290300370300200041e8006a2017290300370300200041f0" + "006a201e290300370300200041f8006a201f290300370300200041b8016a" + "200e290300370300200041b0016a200f290300370300200041a8016a2010" + "290300370300200041a0016a201129030037030020004198016a20122903" + "0037030020004190016a201329030037030020004188016a200329038804" + "370300200020032903800437038001200341c0066a24000b830c02137f04" + "7e23004180026b22032400200341d8006a2207200141186a290300370300" + "200341d0006a2208200141106a2903003703002003200141086a29030037" + "034820032001290300370340200341406b2002290300200241086a290300" + "2002290310200241186a29030042c7faf3c3ed82a3903c428d95c7c396d2" + "dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200341" + "98016a2204200141386a29030037030020034190016a2205200141306a29" + "03003703002003200141286a290300370388012003200129032037038001" + "20034180016a2002290320200241286a2903002002290330200241386a29" + "030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b6" + "91a8b87f42a9c0c689aece93b230102d200341186a220b20072903003703" + "00200341106a220c2008290300370300200341206a220d20032903800137" + "0300200341286a220e200329038801370300200341306a220f2005290300" + "370300200341386a22102004290300370300200320032903483703082003" + "2003290340370300200241f8006a2903002116200241e8006a2903002117" + "2002290370211820022903602119200341f8016a2209200141d8006a2903" + "00370300200341f0016a2206200141d0006a2903003703002003200141c8" + "006a2903003703e801200320012903403703e001200341e0016a20022903" + "40200241c8006a2903002002290350200241d8006a29030042c7faf3c3ed" + "82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c6" + "89aece93b230102d2004200141f8006a2903003703002005200141f0006a" + "2903003703002003200141e8006a29030037038801200320012903603703" + "800120034180016a201920172018201642c7faf3c3ed82a3903c428d95c7" + "c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d" + "2007200929030037030020082006290300370300200341e0006a22112003" + "29038001370300200341e8006a2212200329038801370300200341f0006a" + "22132005290300370300200341f8006a2214200429030037030020032003" + "2903e801370348200320032903e001370340200241b8016a290300211620" + "0241a8016a290300211720022903b001211820022903a0012119200341d8" + "016a220a20014198016a290300370300200341d0016a221520014190016a" + "290300370300200320014188016a2903003703c801200320012903800137" + "03c001200341c0016a20022903800120024188016a290300200229039001" + "20024198016a29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f" + "42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2009200141b801" + "6a2903003703002006200141b0016a2903003703002003200141a8016a29" + "03003703e801200320012903a0013703e001200341e0016a201920172018" + "201642c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b6" + "91a8b87f42a9c0c689aece93b230102d2004200a29030037030020052015" + "290300370300200341a0016a220120032903e001370300200341a8016a22" + "0220032903e801370300200341b0016a220a2006290300370300200341b8" + "016a22062009290300370300200320032903c80137038801200320032903" + "c00137038001200041386a2010290300370300200041306a200f29030037" + "0300200041286a200e290300370300200041206a200d2903003703002000" + "41186a200b290300370300200041106a200c290300370300200041086a20" + "032903083703002000200329030037030020002003290340370340200041" + "c8006a2003290348370300200041d0006a2008290300370300200041d800" + "6a2007290300370300200041e0006a2011290300370300200041e8006a20" + "12290300370300200041f0006a2013290300370300200041f8006a201429" + "0300370300200041b8016a2006290300370300200041b0016a200a290300" + "370300200041a8016a2002290300370300200041a0016a20012903003703" + "0020004198016a200429030037030020004190016a200529030037030020" + "004188016a20032903880137030020002003290380013703800120034180" + "026a24000bf11902287f087e23004180056b22022400200241386a222420" + "0141386a220a290300370300200241306a2225200141306a220329030037" + "0300200241286a2226200141286a2204290300370300200241206a222720" + "0141206a2205290300370300200241186a2228200141186a220f29030037" + "0300200241106a2229200141106a22062903003703002002200129030037" + "03002002200141086a2207290300370308200220012001102f200241f800" + "6a2210200a290300370300200241f0006a22112003290300370300200241" + "e8006a22122004290300370300200241e0006a2213200529030037030020" + "0241d8006a2214200f290300370300200241d0006a221520062903003703" + "002002200729030037034820022001290300370340200241406b20012001" + "41406b2218102f20024180046a200241406b200241406b10302010200241" + "b8046a220b2903003703002011200241b0046a220c290300370300201220" + "0241a8046a220d2903003703002013200241a0046a220e29030037030020" + "1420024198046a2208290300370300201520024190046a22092903003703" + "0020022002290388043703482002200229038004370340200141f8006a22" + "19290300212a200141f0006a221a290300212b200141e8006a221b290300" + "212c200141e0006a221c290300212d200241f8046a2217200f2903003703" + "00200241f0046a220f2006290300370300200220072903003703e8042002" + "20012903003703e004200241e0046a2001290340200141c8006a221d2903" + "00200141d0006a221e290300200141d8006a221f29030042c7faf3c3ed82" + "a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689" + "aece93b230102d2008200a29030037030020092003290300370300200220" + "0429030037038804200220052903003703800420024180046a202d202c20" + "2b202a42c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8" + "b691a8b87f42a9c0c689aece93b230102d20024198036a22032017290300" + "37030020024190036a2204200f290300370300200241a0036a2205200229" + "038004370300200241a8036a2206200229038804370300200241b0036a22" + "072009290300370300200241b8036a221620082903003703002002200229" + "03e80437038803200220022903e0043703800320024180046a2002418003" + "6a20014180016a220a10302016200b2903003703002007200c2903003703" + "002006200d2903003703002005200e290300370300200320082903003703" + "002004200929030037030020022002290388043703880320022002290380" + "043703800320024180046a20024180036a20024180036a102f2016200b29" + "03003703002007200c2903003703002006200d2903003703002005200e29" + "030037030020032008290300370300200420092903003703002002200229" + "0388043703880320022002290380043703800320024190016a2203201e29" + "030037030020024198016a2204201f290300370300200241a0016a220520" + "1c290300370300200241a8016a2206201b290300370300200241b0016a22" + "07201a290300370300200241b8016a221620192903003703002002200129" + "0340370380012002201d2903003703880120024180016a2018200a102f20" + "024180046a20024180016a20024180016a10302016200b29030037030020" + "07200c2903003703002006200d2903003703002005200e29030037030020" + "042008290300370300200320092903003703002002200229038804370388" + "01200220022903800437038001200241d0016a221820014190016a290300" + "370300200241d8016a221920014198016a290300370300200241e0016a22" + "1a200141a0016a290300370300200241e8016a221b200141a8016a290300" + "370300200241f0016a221c200141b0016a290300370300200241f8016a22" + "1d200141b8016a29030037030020022001290380013703c0012002200141" + "88016a2903003703c801200241c0016a200a200a102f200241b8026a221e" + "2016290300370300200241b0026a22162007290300370300200241a8026a" + "22072006290300370300200241a0026a2206200529030037030020024198" + "026a2205200429030037030020024190026a220420032903003703002002" + "42003703f803200242003703f003200242003703e803200242013703e003" + "200242003703d803200242003703d003200242003703c803200242093703" + "c00320022002290388013703880220022002290380013703800220024180" + "026a20024180016a200241c0036a102f20024180046a20024180026a2002" + "1030201e200b2903003703002016200c2903003703002007200d29030037" + "03002006200e290300370300200520082903003703002004200929030037" + "0300200241d0026a22032018290300370300200241d8026a221f20192903" + "00370300200241e0026a2220201a290300370300200241e8026a2221201b" + "290300370300200241f0026a2222201c290300370300200241f8026a2223" + "201d29030037030020022002290388043703880220022002290380043703" + "8002200220022903c0013703c002200220022903c8013703c802200241c0" + "026a200241c0016a200241c0036a102f20024180046a200241c0026a2002" + "41406b10302023200b2903003703002022200c2903003703002021200d29" + "03003703002020200e290300370300201f20082903003703002003200929" + "030037030020022002290388043703c80220022002290380043703c00220" + "024180046a200241406b20024180036a10302010200b2903003703002011" + "200c2903003703002012200d2903003703002013200e2903003703002014" + "200829030037030020152009290300370300200220022903880437034820" + "0220022903800437034020024180046a200241406b20024180016a103020" + "10200b2903003703002011200c2903003703002012200d29030037030020" + "13200e290300370300201420082903003703002015200929030037030020" + "022002290388043703482002200229038004370340200241d8046a220120" + "14290300370300200241d0046a220a201529030037030020022002290348" + "3703c804200220022903403703c004200241c0046a200229030020022903" + "082029290300202829030042c7faf3c3ed82a3903c428d95c7c396d2dac0" + "977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2017201029" + "0300370300200f2011290300370300200220122903003703e80420022013" + "2903003703e004200241e0046a2027290300202629030020252903002024" + "29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8" + "b691a8b87f42a9c0c689aece93b230102d20082001290300222a37030020" + "09200a290300222b370300200e20022903e004222c370300200c200f2903" + "00222d370300200d20022903e804222e370300200b2017290300222f3703" + "00200220022903c804223037038804200220022903c00422313703800420" + "10202f3703002011202d3703002012202e3703002013202c370300201420" + "2a3703002015202b37030020022030370348200220313703402001201429" + "0300370300200a2015290300370300200220022903483703c80420022002" + "2903403703c004200241c0046a20022903c00120022903c8012018290300" + "201929030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb085" + "8ce8b691a8b87f42a9c0c689aece93b230102d2017201029030037030020" + "0f2011290300370300200220122903003703e804200220132903003703e0" + "04200241e0046a201a290300201b290300201c290300201d29030042c7fa" + "f3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42" + "a9c0c689aece93b230102d20082001290300222a3703002009200a290300" + "222b370300200e20022903e004222c370300200c200f290300222d370300" + "200d20022903e804222e370300200b2017290300222f3703002002200229" + "03c804223037038804200220022903c0042231370380042010202f370300" + "2011202d3703002012202e3703002013202c3703002014202a3703002015" + "202b3703002002203037034820022031370340200041386a201e29030037" + "0300200041306a2016290300370300200041286a20072903003703002000" + "41206a2006290300370300200041186a2005290300370300200041106a20" + "04290300370300200041086a200229038802370300200020022903800237" + "0300200020022903c002370340200041c8006a20022903c8023703002000" + "41d0006a2003290300370300200041d8006a201f290300370300200041e0" + "006a2020290300370300200041e8006a2021290300370300200041f0006a" + "2022290300370300200041f8006a2023290300370300200041b8016a2010" + "290300370300200041b0016a2011290300370300200041a8016a20122903" + "00370300200041a0016a201329030037030020004198016a201429030037" + "030020004190016a201529030037030020004188016a2002290348370300" + "200020022903403703800120024180056a24000bfe09011d7e2001290310" + "22022001290300220484200141186a2903002215200141086a2903002203" + "8484420052044042c7faf3c3ed82a3903c20047d2118427f4200427f4200" + "200442788342c7faf3c3ed82a3903c561b220b2003200b56ad7d200b2003" + "7d220342f3eab8bce9ada5bfe8007d2219200354ad7c42017c220320027d" + "220c42a4cffaf397c9eed7c7007d220b200c54ad2002200356ad7d427f51" + "1b20157d42a9c0c689aece93b2307c210c0b420021152001290330220220" + "01290320220484200141386a2903002208200141286a2903002203848442" + "00520440427f4200427f4200200442788342c7faf3c3ed82a3903c561b22" + "062003200656ad7d200620037d220342f3eab8bce9ada5bfe8007d221520" + "0354ad7c42017c220320027d220642a4cffaf397c9eed7c7007d221a2006" + "54ad2002200356ad7d427f511b20087d42a9c0c689aece93b2307c211b42" + "c7faf3c3ed82a3903c20047d21060b200141f8006a2903002108200141e8" + "006a290300210220012903702104200129036021032001290350220e2001" + "290340220f84200141d8006a2903002205200141c8006a29030022108484" + "4200520440427f4200427f4200200f42788342c7faf3c3ed82a3903c561b" + "22092009201054ad7d200920107d220942f3eab8bce9ada5bfe8007d221c" + "200954ad7c42017c2216200e7d220d42a4cffaf397c9eed7c7007d220920" + "0d54ad200e201656ad7d427f511b20057d42a9c0c689aece93b2307c2116" + "42c7faf3c3ed82a3903c200f7d210d0b4200210e4200210f420021102003" + "2004842002200884844200520440427f4200427f4200200342788342c7fa" + "f3c3ed82a3903c561b22072002200756ad7d200720027d220242f3eab8bc" + "e9ada5bfe8007d220e200254ad7c42017c220220047d220742a4cffaf397" + "c9eed7c7007d220f200754ad2002200454ad7d427f511b20087d42a9c0c6" + "89aece93b2307c211042c7faf3c3ed82a3903c20037d21070b200141b801" + "6a2903002108200141a8016a290300210220012903b001210420012903a0" + "01210342002105200129039001221220012903800122138420014198016a" + "290300221e20014188016a290300221484844200520440427f4200427f42" + "00201342788342c7faf3c3ed82a3903c561b220a200a201454ad7d200a20" + "147d220a42f3eab8bce9ada5bfe8007d221d200a54ad7c42017c22172012" + "7d221142a4cffaf397c9eed7c7007d220a201154ad2012201756ad7d427f" + "511b201e7d42a9c0c689aece93b2307c211742c7faf3c3ed82a3903c2013" + "7d21110b4200211242002113420021142003200484200220088484420052" + "0440427f4200427f4200200342788342c7faf3c3ed82a3903c561b220520" + "02200556ad7d200520027d220242f3eab8bce9ada5bfe8007d2212200254" + "ad7c42017c220220047d220542a4cffaf397c9eed7c7007d2213200554ad" + "2002200454ad7d427f511b20087d42a9c0c689aece93b2307c211442c7fa" + "f3c3ed82a3903c20037d21050b200020133703b001200020053703a00120" + "00200a3703900120002011370380012000200f3703702000200737036020" + "0020093703502000200d3703402000201a37033020002006370320200020" + "0b37031020002018370300200020143703b801200020123703a801200020" + "17370398012000201d37038801200020103703782000200e370368200020" + "163703582000201c3703482000201b370338200020153703282000200c37" + "0318200020193703080b960501057f230041800c6b220324002003200120" + "02103b20034180036a200141c0016a220441c001104c1a200341c0046a20" + "0241c0016a220541c001104c1a200341c0016a20042005103b2003420037" + "03b809200342003703b009200342003703a809200342013703a009200342" + "003703980920034200370390092003420037038809200342093703800920" + "0341c00a6a200341c0026a20034180096a102f200341c80b6a2003418802" + "6a290300370300200341d00b6a20034190026a290300370300200341d80b" + "6a20034198026a290300370300200341e00b6a200341a0026a2903003703" + "00200341e80b6a200341a8026a290300370300200341f00b6a200341b002" + "6a290300370300200341f80b6a200341b8026a290300370300200341880b" + "6a20032903c801370300200341900b6a200341d0016a2903003703002003" + "41980b6a200341d8016a290300370300200341a00b6a200341e0016a2903" + "00370300200341a80b6a200341e8016a290300370300200341b00b6a2003" + "41f0016a290300370300200341b80b6a200341f8016a2903003703002003" + "2003290380023703c00b200320032903c0013703800b20034180066a2003" + "41c00a6a20031030200341c0066a200341800b6a2206200341406b103020" + "034180076a200341c00b6a220720034180016a103020034180096a200120" + "041030200341c0096a200141406b200341c0036a1030200341800a6a2001" + "4180016a20034180046a1030200341c00a6a200220051030200620024140" + "6b20034180056a1030200720024180016a200341c0056a1030200341c007" + "6a20034180096a200341c00a6a103b200341c00a6a200341c0076a200310" + "3c200041c0016a200341c00a6a200341c0016a103c200020034180066a41" + "c001104c1a200341800c6a24000bd741020e7f227e230041c0036b220324" + "0002400240200129034022212001290350222084200141c8006a29030022" + "23200141d8006a2903002222848442005204402002290340221d20022903" + "50221584200241c8006a2903002224200241d8006a290300221e8484500d" + "01200341f8016a2204200141406b220641186a2205290300370300200341" + "f0016a2208200641106a220b290300370300200320062903003703e00120" + "03200641086a220c2903003703e801200341e0016a202120232020202242" + "c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b20034198026a2209" + "200241406b220741186a220d29030037030020034190026a220a20074110" + "6a220e2903003703002003200741086a220f290300370388022003200729" + "03003703800220034180026a201d20242015201e42c7faf3c3ed82a3903c" + "428d95c7c396d2dac0977f102b200341186a2210200141186a2903003703" + "00200341106a200141106a2903003703002003200141086a290300370308" + "20032001290300370300200320032903800222162003290388022219200a" + "29030022252009290300222842c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f102b200341386a2209200241186a290300370300200341306a220a" + "200241106a2903003703002003200241086a290300370328200320022903" + "00370320200341206a20032903e001222c20032903e80122302008290300" + "22312004290300223242c7faf3c3ed82a3903c428d95c7c396d2dac0977f" + "102b200341b8036a22042005290300370300200341b0036a2205200b2903" + "003703002003200c2903003703a803200320062903003703a003200341a0" + "036a202c20302031203242c7faf3c3ed82a3903c428d95c7c396d2dac097" + "7f102b200429030021132005290300211f20032903a803211c20032903a0" + "0321172004200d2903003703002005200e2903003703002003200f290300" + "3703a803200320072903003703a003200341a0036a201620192025202842" + "c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b2004290300211220" + "05290300211420032903a803211120032903a003211a200341d0006a2001" + "41306a290300370300200341d8006a2206200141386a2903003703002003" + "20012903203703402003200141286a290300370348200341406b201a2011" + "2014201242c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b200341" + "f8006a2207200241386a290300370300200341f0006a2208200241306a29" + "03003703002003200241286a290300370368200320022903203703602003" + "41e0006a2017201c201f201342c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f102b02402003200341206a104a450440200341406b200341e0006a" + "104a450d010b200420092903003703002005200a29030037030020032003" + "2903283703a803200320032903203703a003200341a0036a200329030020" + "032903082003290310201029030042c7faf3c3ed82a3903c428d95c7c396" + "d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2004" + "290300211f2005290300211c20032903a003211720032903a80321122004" + "200729030037030020052008290300370300200320032903683703a80320" + "0320032903603703a003200341a0036a2003290340200329034820032903" + "50200629030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0" + "858ce8b691a8b87f42a9c0c689aece93b230102d20124201862017423f88" + "842114201742018621112004290300211a2005290300211b20032903a803" + "211820032903a003212602400240201c4201862012423f8884222942ddb0" + "858ce8b691a8b87f85201f201f7c201c423f887c221342a9c0c689aece93" + "b2308584500440201142c7faf3c3ed82a3903c542014428d95c7c396d2da" + "c0977f542014428d95c7c396d2dac0977f511b450d0142a9c0c689aece93" + "b230211342ddb0858ce8b691a8b87f21292011212a201421110c020b2029" + "42deb0858ce8b691a8b87f54201342a9c0c689aece93b23054201342a9c0" + "c689aece93b230511b450d002011212a201421110c010b20132029201420" + "1142c7faf3c3ed82a3903c7d222a20115aad222d7d222742f3eab8bce9ad" + "a5bfe8007c2211202754ad2014202d54ad7d7c2214202954ad201442a2cf" + "faf397c9eed7c7007c2229201454ad7c50ad7d42a9c0c689aece93b2307d" + "21130b200341b8036a22012013370300200320293703b0032003202a3703" + "a003200320113703a80342ddb0858ce8b691a8b87f2114200341a0036a20" + "2a20112029201342c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b" + "2003201f3703d8012003201c3703d001200320123703c801200320173703" + "c001200341c0016a20032903a003222920032903a803222a20032903b003" + "222d2001290300222742c7faf3c3ed82a3903c428d95c7c396d2dac0977f" + "102b20184201862026423f888421112026420186212602400240201b4201" + "862018423f8884221842ddb0858ce8b691a8b87f85201a201a7c201b423f" + "887c221342a9c0c689aece93b2308584500440202642c7faf3c3ed82a390" + "3c542011428d95c7c396d2dac0977f542011428d95c7c396d2dac0977f51" + "1b450d012026211a2011211b42a9c0c689aece93b23021130c020b201842" + "deb0858ce8b691a8b87f54201342a9c0c689aece93b23054201342a9c0c6" + "89aece93b230511b450d002026211a2011211b201821140c010b20132018" + "2011202642c7faf3c3ed82a3903c7d221a20265aad22147d222642f3eab8" + "bce9ada5bfe8007c221b202654ad2011201454ad7d7c2211201854ad2011" + "42a2cffaf397c9eed7c7007c2214201154ad7c50ad7d42a9c0c689aece93" + "b2307d21130b20034198016a2201200341186a2903003703002003419001" + "6a2202200341106a29030037030020032003290308370388012003200329" + "03003703800142ddb0858ce8b691a8b87f212e20034180016a2029202a20" + "2d202742c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b200341b8" + "036a2204200341d8006a290300370300200341b0036a2205200341d0006a" + "290300370300200320032903483703a803200320032903403703a0032003" + "41a0036a20032903c001221120032903c801221820032903d00122272003" + "41d8016a290300222b42c7faf3c3ed82a3903c428d95c7c396d2dac0977f" + "102b200320133703b802200320143703b0022003201b3703a8022003201a" + "3703a002200429030021262005290300212920032903a803212a20032903" + "a003212d200341a0026a201a201b2014201342c7faf3c3ed82a3903c428d" + "95c7c396d2dac0977f102b200341a0026a201120182027202b42c7faf3c3" + "ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0" + "c689aece93b230102d200329038801222b4201862003290380012211423f" + "88842118201142018621270240024020022903002211420186202b423f88" + "84222b42ddb0858ce8b691a8b87f852011423f882001290300221120117c" + "7c221142a9c0c689aece93b2308584500440202742c7faf3c3ed82a3903c" + "542018428d95c7c396d2dac0977f542018428d95c7c396d2dac0977f511b" + "450d012027212f2018212742a9c0c689aece93b23021110c020b202b42de" + "b0858ce8b691a8b87f54201142a9c0c689aece93b23054201142a9c0c689" + "aece93b230511b450d002027212f20182127202b212e0c010b2011202b20" + "18202742c7faf3c3ed82a3903c7d222f20275aad222e7d221142f3eab8bc" + "e9ada5bfe8007c2227201154ad2018202e54ad7d7c2218202b54ad201842" + "a2cffaf397c9eed7c7007c222e201854ad7c50ad7d42a9c0c689aece93b2" + "307d21110b42ddb0858ce8b691a8b87f2118200341a0026a202f2027202e" + "201142c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b6" + "91a8b87f42a9c0c689aece93b230102d200320133703b801200320143703" + "b0012003201b3703a8012003201a3703a00120034180016a20032903a002" + "20032903a80220032903b002200341b8026a29030042c7faf3c3ed82a390" + "3c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece" + "93b230102d200341a0016a20032903800120032903880120032903900120" + "034198016a29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f10" + "2b202a420186202d423f88842114202d4201862111024002402029420186" + "202a423f8884221a42ddb0858ce8b691a8b87f85202620267c2029423f88" + "7c221342a9c0c689aece93b2308584500440201142c7faf3c3ed82a3903c" + "542014428d95c7c396d2dac0977f542014428d95c7c396d2dac0977f511b" + "450d012011211b2014211142a9c0c689aece93b23021130c020b201a42de" + "b0858ce8b691a8b87f54201342a9c0c689aece93b23054201342a9c0c689" + "aece93b230511b450d002011211b20142111201a21180c010b2013201a20" + "14201142c7faf3c3ed82a3903c7d221b20115aad22187d222642f3eab8bc" + "e9ada5bfe8007c2211202654ad2014201854ad7d7c2214201a54ad201442" + "a2cffaf397c9eed7c7007c2218201454ad7c50ad7d42a9c0c689aece93b2" + "307d21130b42ddb0858ce8b691a8b87f2114200341a0016a201b20112018" + "201342c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b6" + "91a8b87f42a9c0c689aece93b230102d02400240201520207c2213202320" + "247c2220202454ad2020201d20217c2224201d54ad7c2223202054ad7c7c" + "222042ddb0858ce8b691a8b87f852013201554ad2013202056ad7c201e20" + "227c7c222142a9c0c689aece93b2308584500440202442c7faf3c3ed82a3" + "903c542023428d95c7c396d2dac0977f542023428d95c7c396d2dac0977f" + "511b450d01202421222023211342a9c0c689aece93b23021210c020b2020" + "42deb0858ce8b691a8b87f54202142a9c0c689aece93b23054202142a9c0" + "c689aece93b230511b450d002024212220232113202021140c010b202120" + "202023202442c7faf3c3ed82a3903c7d222220245aad221d7d221542f3ea" + "b8bce9ada5bfe8007c2213201554ad201d202356ad7d7c2223202054ad20" + "2342a2cffaf397c9eed7c7007c2214202354ad7c50ad7d42a9c0c689aece" + "93b2307d21210b200341d8026a22012021370300200341d0026a22022014" + "370300200320223703c002200320133703c802200341c0026a2022201320" + "14202142c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b200341c0" + "026a202c20302031203242c7faf3c3ed82a3903c428d95c7c396d2dac097" + "7f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200341c0026a" + "201620192025202842c7faf3c3ed82a3903c428d95c7c396d2dac0977f42" + "ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200341c0026a2017" + "2012201c201f42c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b20" + "0041186a200341b8026a290300370300200041106a200341b0026a290300" + "370300200041086a20032903a802370300200020032903a0023703002000" + "20032903a001370320200041286a20032903a801370300200041306a2003" + "41b0016a290300370300200041386a200341b8016a290300370300200020" + "032903c002370340200041c8006a20032903c802370300200041d0006a20" + "02290300370300200041d8006a20012903003703000c030b200341b8036a" + "2204200141186a290300221b370300200341b0036a2205200141106a2903" + "0022183703002003200141086a29030022163703a8032003200129030022" + "193703a00342ddb0858ce8b691a8b87f2112200341a0036a201920162018" + "201b42c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b2004290300" + "211d2005290300211520032903a803212420032903a003211f2004200141" + "206a220241186a2903003703002005200241106a29030037030020032002" + "41086a2903003703a803200320022903003703a003200341a0036a200129" + "0320200141286a2903002001290330200141386a29030042c7faf3c3ed82" + "a3903c428d95c7c396d2dac0977f102b2005290300211320032903a00321" + "1c20032903a8032117200420042903002225370300200320133703b00320" + "0320173703a8032003201c3703a003200341a0036a201c20172013202542" + "c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b2004290300211420" + "032903b003211e20032903a803211120032903a003211a02400240024020" + "1320187c2218201620177c2216201754ad20162019201c7c2219201c54ad" + "7c2217201654ad7c7c221c42ddb0858ce8b691a8b87f852013201856ad20" + "18201c56ad7c201b20257c7c221342a9c0c689aece93b230858450044020" + "1942c7faf3c3ed82a3903c542017428d95c7c396d2dac0977f542017428d" + "95c7c396d2dac0977f511b450d0242a9c0c689aece93b23021130c010b20" + "1c42deb0858ce8b691a8b87f54201342a9c0c689aece93b23054201342a9" + "c0c689aece93b230511b450d01201c21120b2019211b201721180c010b20" + "13201c2017201942c7faf3c3ed82a3903c7d221b20195aad22127d221642" + "f3eab8bce9ada5bfe8007c2218201654ad2012201756ad7d7c2217201c54" + "ad201742a2cffaf397c9eed7c7007c2212201754ad7c50ad7d42a9c0c689" + "aece93b2307d21130b200341b8036a22012013370300200341b0036a2204" + "20123703002003201b3703a003200320183703a80342ddb0858ce8b691a8" + "b87f211c200341a0036a201b20182012201342c7faf3c3ed82a3903c428d" + "95c7c396d2dac0977f102b20034198036a22052001290300370300200341" + "90036a22062004290300370300200320032903a803370388032003200329" + "03a0033703800320034180036a201f20242015201d42c7faf3c3ed82a390" + "3c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece" + "93b230102d20012005290300370300200420062903003703002003200329" + "0388033703a80320032003290380033703a003200341a0036a201a201120" + "1e201442c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8" + "b691a8b87f42a9c0c689aece93b230102d20032903a803221b4201862003" + "2903a0032213423f88842117201342018621120240024002402004290300" + "2213420186201b423f8884221642ddb0858ce8b691a8b87f852013423f88" + "2001290300221320137c7c221342a9c0c689aece93b23085845004402012" + "42c7faf3c3ed82a3903c542017428d95c7c396d2dac0977f542017428d95" + "c7c396d2dac0977f511b450d0242a9c0c689aece93b23021130c010b2016" + "42deb0858ce8b691a8b87f54201342a9c0c689aece93b23054201342a9c0" + "c689aece93b230511b450d012016211c0b2012211b201721180c010b2013" + "20162017201242c7faf3c3ed82a3903c7d221b20125aad221c7d221242f3" + "eab8bce9ada5bfe8007c2218201254ad2017201c54ad7d7c2217201654ad" + "201742a2cffaf397c9eed7c7007c221c201754ad7c50ad7d42a9c0c689ae" + "ce93b2307d21130b2024420186201f423f8884211742ddb0858ce8b691a8" + "b87f2116201f42018621190240024020154201862024423f8884222842dd" + "b0858ce8b691a8b87f85201d201d7c2015423f887c221242a9c0c689aece" + "93b2308584500440201942c7faf3c3ed82a3903c542017428d95c7c396d2" + "dac0977f542017428d95c7c396d2dac0977f511b450d0120192125201721" + "1942a9c0c689aece93b23021120c020b202842deb0858ce8b691a8b87f54" + "201242a9c0c689aece93b23054201242a9c0c689aece93b230511b450d00" + "2019212520172119202821160c010b201220282017201942c7faf3c3ed82" + "a3903c7d222520195aad22167d222c42f3eab8bce9ada5bfe8007c221920" + "2c54ad2016201756ad7d7c2217202854ad201742a2cffaf397c9eed7c700" + "7c2216201754ad7c50ad7d42a9c0c689aece93b2307d21120b42ddb0858c" + "e8b691a8b87f211702400240201520167c2228201920247c2215201954ad" + "2015201f20257c221f202554ad7c2219201554ad7c7c221542ddb0858ce8" + "b691a8b87f852016202856ad2015202854ad7c2012201d7c7c221d42a9c0" + "c689aece93b2308584500440201f42c7faf3c3ed82a3903c542019428d95" + "c7c396d2dac0977f542019428d95c7c396d2dac0977f511b450d01201f21" + "242019211f42a9c0c689aece93b230211d0c020b201542deb0858ce8b691" + "a8b87f54201d42a9c0c689aece93b23054201d42a9c0c689aece93b23051" + "1b450d00201f21242019211f201521170c010b201d20152019201f42c7fa" + "f3c3ed82a3903c7d2224201f5aad22177d221242f3eab8bce9ada5bfe800" + "7c221f201254ad2017201956ad7d7c2212201554ad201242a2cffaf397c9" + "eed7c7007c2217201254ad7c50ad7d42a9c0c689aece93b2307d211d0b20" + "0320173703b003200320243703a0032003201d3703b8032003201f3703a8" + "0342ddb0858ce8b691a8b87f2119200341a0036a2024201f2017201d42c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f102b2018420186201b423f" + "88842112201b420186211602400240201c4201862018423f8884222542dd" + "b0858ce8b691a8b87f85201320137c201c423f887c221542a9c0c689aece" + "93b2308584500440201642c7faf3c3ed82a3903c542012428d95c7c396d2" + "dac0977f542012428d95c7c396d2dac0977f511b450d0120162128201221" + "1642a9c0c689aece93b23021150c020b202542deb0858ce8b691a8b87f54" + "201542a9c0c689aece93b23054201542a9c0c689aece93b230511b450d00" + "2016212820122116202521190c010b201520252012201642c7faf3c3ed82" + "a3903c7d222820165aad22197d222c42f3eab8bce9ada5bfe8007c221620" + "2c54ad2012201954ad7d7c2212202554ad201242a2cffaf397c9eed7c700" + "7c2219201254ad7c50ad7d42a9c0c689aece93b2307d21150b42ddb0858c" + "e8b691a8b87f2112200341a0036a202820162019201542c7faf3c3ed82a3" + "903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689ae" + "ce93b230102d2011420186201a423f88842116201a420186211a02400240" + "201e4201862011423f8884221942ddb0858ce8b691a8b87f85201420147c" + "201e423f887c221542a9c0c689aece93b2308584500440201a42c7faf3c3" + "ed82a3903c542016428d95c7c396d2dac0977f542016428d95c7c396d2da" + "c0977f511b450d01201a21112016211a42a9c0c689aece93b23021150c02" + "0b201942deb0858ce8b691a8b87f54201542a9c0c689aece93b230542015" + "42a9c0c689aece93b230511b450d00201a21112016211a201921120c010b" + "201520192016201a42c7faf3c3ed82a3903c7d2211201a5aad22127d2214" + "42f3eab8bce9ada5bfe8007c221a201454ad2012201656ad7d7c22142019" + "54ad201442a2cffaf397c9eed7c7007c2212201454ad7c50ad7d42a9c0c6" + "89aece93b2307d21150b201a4201862011423f8884211e42ddb0858ce8b6" + "91a8b87f211420114201862111024002402012420186201a423f88842216" + "42ddb0858ce8b691a8b87f85201520157c2012423f887c221542a9c0c689" + "aece93b2308584500440201142c7faf3c3ed82a3903c54201e428d95c7c3" + "96d2dac0977f54201e428d95c7c396d2dac0977f511b450d012011211a20" + "1e211142a9c0c689aece93b23021150c020b201642deb0858ce8b691a8b8" + "7f54201542a9c0c689aece93b23054201542a9c0c689aece93b230511b45" + "0d002011211a201e2111201621140c010b20152016201e201142c7faf3c3" + "ed82a3903c7d221a20115aad22127d221442f3eab8bce9ada5bfe8007c22" + "11201454ad2012201e56ad7d7c2212201654ad201242a2cffaf397c9eed7" + "c7007c2214201254ad7c50ad7d42a9c0c689aece93b2307d21150b201142" + "0186201a423f8884211242ddb0858ce8b691a8b87f2116201a420186211e" + "0240024020144201862011423f8884221142ddb0858ce8b691a8b87f8520" + "1520157c2014423f887c221542a9c0c689aece93b2308584500440201e42" + "c7faf3c3ed82a3903c542012428d95c7c396d2dac0977f542012428d95c7" + "c396d2dac0977f511b450d01201e21142012211e42a9c0c689aece93b230" + "21150c020b201142deb0858ce8b691a8b87f54201542a9c0c689aece93b2" + "3054201542a9c0c689aece93b230511b450d00201e21142012211e201121" + "160c010b201520112012201e42c7faf3c3ed82a3903c7d2214201e5aad22" + "1a7d221642f3eab8bce9ada5bfe8007c221e201654ad2012201a54ad7d7c" + "2212201154ad201242a2cffaf397c9eed7c7007c2216201254ad7c50ad7d" + "42a9c0c689aece93b2307d21150b20034198036a2201200241186a290300" + "37030020034190036a2204200241106a2903003703002003200229030037" + "0380032003200241086a2903003703880342ddb0858ce8b691a8b87f2112" + "20034180036a202120232020202242c7faf3c3ed82a3903c428d95c7c396" + "d2dac0977f102b2003201d3703f802200320173703f0022003201f3703e8" + "02200320243703e002200129030021212004290300212320032903800321" + "22200329038803211d200120133703002003201c37039003200320183703" + "88032003201b3703800320034180036a20032903a00320032903a8032003" + "2903b003200341b8036a29030042c7faf3c3ed82a3903c428d95c7c396d2" + "dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200341" + "e0026a200329038003200329038803200329039003200129030042c7faf3" + "c3ed82a3903c428d95c7c396d2dac0977f102b200341e0026a2014201e20" + "16201542c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8" + "b691a8b87f42a9c0c689aece93b230102d201d4201862022423f88842120" + "20224201862122024002402023420186201d423f8884221342ddb0858ce8" + "b691a8b87f85202120217c2023423f887c222142a9c0c689aece93b23085" + "84500440202242c7faf3c3ed82a3903c542020428d95c7c396d2dac0977f" + "542020428d95c7c396d2dac0977f511b450d01202221232020212242a9c0" + "c689aece93b23021210c020b201342deb0858ce8b691a8b87f54202142a9" + "c0c689aece93b23054202142a9c0c689aece93b230511b450d0020222123" + "20202122201321120c010b202120132020202242c7faf3c3ed82a3903c7d" + "222320225aad221d7d221542f3eab8bce9ada5bfe8007c2222201554ad20" + "1d202056ad7d7c2220201354ad202042a2cffaf397c9eed7c7007c221220" + "2054ad7c50ad7d42a9c0c689aece93b2307d21210b200020123703502000" + "2023370340200020032903a003370300200020032903e002370320200020" + "2137035820002022370348200041086a20032903a803370300200041286a" + "20032903e802370300200041186a200341b8036a29030037030020004110" + "6a200341b0036a290300370300200041306a200341f0026a290300370300" + "200041386a200341f8026a2903003703000c020b2000200241e000104c1a" + "0c010b2000200141e000104c1a0b200341c0036a24000b970802067f087e" + "230041a0016b220224000240200129034022082001290350220984200141" + "c8006a290300220a200141d8006a290300220b8484420052044020024200" + "370318200242003703102002420037030820024201370300024020014140" + "6b2002104a450440200241206a2001290320220837030020002001290300" + "2209370310200041306a2008370300200241386a200141386a2903002208" + "370300200241306a200141306a290300220a370300200241286a20014128" + "6a290300220b370300200241106a200141106a290300220c370300200241" + "186a200141186a290300220d370300200041186a200141086a290300220e" + "370300200041206a200c370300200041286a200d370300200041386a200b" + "370300200041406b200a370300200041c8006a2008370300200220093703" + "002002200e3703080c010b20024198016a2204200b370300200220093703" + "900120022008370380012002200a37038801200242a9c0c689aece93b230" + "370318200242ddb0858ce8b691a8b87f3703102002428d95c7c396d2dac0" + "977f370308200242c7faf3c3ed82a3903c37030020024180016a2002103a" + "20022903800121082002290388012109200229039001210a200241186a22" + "032004290300220b3703002002200a370310200220093703082002200837" + "0300200220082009200a200b42c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f102b2003290300210c2002290310210d2002290308210e20022903" + "00210f200241d0006a2204200141106a290300370300200241d8006a2205" + "200141186a290300370300200220012903003703402002200141086a2903" + "00370348200241406b200f200e200d200c42c7faf3c3ed82a3903c428d95" + "c7c396d2dac0977f102b200241f8006a2206200141386a29030037030020" + "0241f0006a2207200141306a2903003703002002200141286a2903003703" + "68200220012903203703602003200b3703002002200a3703102002200937" + "0308200220083703002002200f200e200d200c42c7faf3c3ed82a3903c42" + "8d95c7c396d2dac0977f102b200241e0006a200229030020022903082002" + "290310200329030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f10" + "2b200320052903002208370300200241106a200429030022093703002002" + "41206a2002290360220a370300200241286a2002290368220b3703002002" + "41306a2007290300220c370300200241386a2006290300220d3703002000" + "2002290340220e370310200041186a2002290348220f370300200041206a" + "2009370300200041286a2008370300200041306a200a370300200041386a" + "200b370300200041406b200c370300200041c8006a200d3703002002200f" + "3703082002200e3703000b20004200370308200042013703000c010b2000" + "4200370308200042003703000b200241a0016a24000b3000200128021c20" + "002d0000410274220041cca5c0006a280200200041c0a5c0006a28020020" + "0128022028020c1103000bf917021d7f087e23004180066b220224002002" + "41b8036a2208200141386a290300370300200241b0036a2209200141306a" + "290300370300200241a8036a2213200141286a290300370300200241a003" + "6a2214200141206a29030037030020024198036a2203200141186a290300" + "37030020024190036a2204200141106a2903003703002002200129030037" + "0380032002200141086a2903003703880320024180036a20012001102f20" + "0241f8036a2205200141f8006a290300370300200241f0036a2206200141" + "f0006a290300370300200241e8036a2207200141e8006a29030037030020" + "0241e0036a220a200141e0006a290300370300200241d8036a220b200141" + "d8006a290300370300200241d0036a220c200141d0006a29030037030020" + "02200141c8006a2903003703c803200220012903403703c003200241c003" + "6a200141406b221e201e102f200241b8046a221520052903003703002002" + "41b0046a22162006290300370300200241a8046a22172007290300370300" + "200241a0046a2218200a29030037030020024198046a2219200b29030037" + "030020024190046a221a200c290300370300200220022903c80337038804" + "200220022903c0033703800420024180046a200241c0036a200241c0036a" + "102f200241c0026a2001200241c0036a1030200241f8046a221b200241f8" + "026a2205290300370300200241f0046a220e200241f0026a220a29030037" + "0300200241e8046a220f200241e8026a2206290300370300200241e0046a" + "2210200241e0026a220c290300370300200241d8046a220d200241d8026a" + "2207290300370300200241d0046a2211200241d0026a220b290300370300" + "200220022903c8023703c804200220022903c0023703c004200241c0046a" + "200241c0026a200241c0026a102f200241d8056a2212200d290300370300" + "200241d0056a220d2011290300370300200220022903c8043703c8052002" + "20022903c0043703c005200241c0056a2002290380032002290388032004" + "290300200329030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42" + "ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200241f8056a2203" + "201b290300370300200241f0056a2204200e2903003703002002200f2903" + "003703e805200220102903003703e005200241e0056a2014290300201329" + "03002009290300200829030042c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d20024198" + "026a2208201229030037030020024190026a2209200d2903003703002002" + "41a8026a221320022903e805370300200241b0026a221420042903003703" + "00200241b8026a221b2003290300370300200220022903c8053703880220" + "0220022903c00537038002200220022903e0053703a00220122008290300" + "370300200d200929030037030020022002290388023703c8052002200229" + "0380023703c005200241c0056a200229038004200229038804201a290300" + "201929030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb085" + "8ce8b691a8b87f42a9c0c689aece93b230102d2003201b29030037030020" + "042014290300370300200220132903003703e805200220022903a0023703" + "e005200241e0056a201829030020172903002016290300201529030042c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f" + "42a9c0c689aece93b230102d200241186a22152012290300370300200241" + "106a2216200d290300370300200241206a221720022903e0053703002002" + "41286a221820022903e805370300200241306a2219200429030037030020" + "0241386a221a2003290300370300200220022903c8053703082002200229" + "03c005370300200241c0026a200220021030201a20052903003703002019" + "200a290300370300201820062903003703002017200c2903003703002015" + "20072903003703002016200b290300370300200220022903c80237030820" + "0220022903c002370300200241c0026a20024180036a20024180036a1030" + "200241406b200241c0026a20024180036a103020024190056a220e200241" + "d0006a29030037030020024198056a220f200241d8006a29030037030020" + "0241a0056a2210200241e0006a290300370300200241a8056a2211200241" + "e8006a290300370300200241b0056a221c200241f0006a29030037030020" + "0241b8056a221d200241f8006a2903003703002002200229034037038005" + "200220022903483703880520024180056a200241406b200241406b102f20" + "0241c0026a2002200210302003200f2903003703002004200e2903003703" + "0020022002290388053703e80520022002290380053703e005200241e005" + "6a20022903c00220022903c80220022903d002200729030042c7faf3c3ed" + "82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c6" + "89aece93b230102d2008201d2903003703002009201c2903003703002002" + "201129030037038802200220102903003703800220024180026a20022903" + "e002200629030020022903f002200529030042c7faf3c3ed82a3903c428d" + "95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230" + "102d2008290300211f200929030021202003290300212120042903002122" + "2002290388022123200229038002212420022903e805212520022903e005" + "212620024180016a20024180046a20024180046a1030200241c0026a2002" + "4180016a20024180016a1030200241b8016a220e20052903003703002002" + "41b0016a220f200a290300370300200241a8016a22102006290300370300" + "200241a0016a2211200c29030037030020024198016a221c200729030037" + "030020024190016a221d200b290300370300200220022903c80237038801" + "200220022903c00237038001200241c0026a20024180016a20024180016a" + "1030200e2005290300370300200f200a2903003703002010200629030037" + "03002011200c290300370300201c2007290300370300201d200b29030037" + "0300200220022903c80237038801200220022903c00237038001200241c0" + "016a201e20014180016a102f200320152903003703002004201629030037" + "0300200220022903083703e805200220022903003703e005200241e0056a" + "202620252022202142c7faf3c3ed82a3903c428d95c7c396d2dac0977f42" + "ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2008201a29030037" + "030020092019290300370300200220182903003703880220022017290300" + "3703800220024180026a202420232020201f42c7faf3c3ed82a3903c428d" + "95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230" + "102d20072003290300370300200b20042903003703002006200229038802" + "370300200a200929030037030020052008290300370300200220022903e8" + "053703c802200220022903e0053703c00220022002290380023703e00220" + "024180026a200241406b200241c0026a102f20122008290300370300200d" + "200929030037030020022002290388023703c80520022002290380023703" + "c005200241c0056a200229038001200229038801201d290300201c290300" + "42c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8" + "b87f42a9c0c689aece93b230102d2003201b290300370300200420142903" + "00370300200220132903003703e805200220022903a0023703e005200241" + "e0056a20112903002010290300200f290300200e29030042c7faf3c3ed82" + "a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689" + "aece93b230102d20072012290300370300200b200d290300370300200c20" + "022903e005370300200620022903e805370300200a200429030037030020" + "052003290300370300200220022903c8053703c802200220022903c00537" + "03c00220004180016a200241c0016a200241c0016a10302000201f370338" + "200020203703302000202337032820002024370320200020213703182000" + "20223703102000202537030820002026370300200020022903c002370340" + "200041c8006a20022903c802370300200041d0006a200b29030037030020" + "0041d8006a2007290300370300200041e0006a200c290300370300200041" + "e8006a2006290300370300200041f0006a200a290300370300200041f800" + "6a200529030037030020024180066a24000bbd21021c7f087e230041800b" + "6b22032400024002400240024020012903800120014188016a2903008442" + "00520d0020012903900120014198016a290300844200520d0020012903a0" + "01200141a8016a290300844200520d0020012903b001200141b8016a2903" + "0084500d010b024020022903800120024188016a290300844200520d0020" + "022903900120024198016a290300844200520d0020022903a001200241a8" + "016a290300844200520d0020022903b001200241b8016a29030084500d02" + "0b200341b8086a221420014180016a220441386a290300370300200341b0" + "086a200441306a290300370300200341a8086a2215200441286a29030037" + "0300200341a0086a200441206a29030037030020034198086a2216200441" + "186a29030037030020034190086a200441106a2903003703002003200429" + "0300370380082003200441086a2903003703880820034180086a20042004" + "102f200341f8086a221720024180016a220541386a290300370300200341" + "f0086a200541306a290300370300200341e8086a2218200541286a290300" + "370300200341e0086a200541206a290300370300200341d8086a22192005" + "41186a290300370300200341d0086a200541106a29030037030020032005" + "41086a2903003703c808200320052903003703c008200341c0086a200520" + "05102f20032001200341c0086a102f200341406b200220034180086a102f" + "20034180016a200420034180086a102f200341c0016a2005200341c0086a" + "102f20034180026a200141406b200341c0016a102f200341c0026a200241" + "406b20034180016a102f024002402003200341406b104a0d00200341206a" + "200341e0006a104a0d0020034180026a200341c0026a104a0d00200341a0" + "026a200341e0026a104a450d010b200341386a290300211f200341286a29" + "03002120200329033021212003290320212220034198076a2201200341d8" + "006a29030037030020034190076a2202200341d0006a2903003703002003" + "200329034837038807200320032903403703800720034180076a20032903" + "0020032903082003290310200341186a29030042c7faf3c3ed82a3903c42" + "8d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b2" + "30102d200341d8076a2206200341f8006a290300370300200341d0076a22" + "09200341f0006a2903003703002003200341e8006a2903003703c8072003" + "20032903603703c007200341c0076a202220202021201f42c7faf3c3ed82" + "a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689" + "aece93b230102d20034198036a200129030037030020034190036a200229" + "0300370300200341a8036a20032903c807370300200341b0036a20092903" + "00370300200341b8036a2006290300370300200320032903880737038803" + "200320032903800737038003200320032903c0073703a003200341b8026a" + "290300211f200341a8026a290300212020032903b002212120032903a002" + "21222001200341d8026a2903003703002002200341d0026a290300370300" + "200320032903c80237038807200320032903c0023703800720034180076a" + "20032903800220032903880220032903900220034198026a29030042c7fa" + "f3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42" + "a9c0c689aece93b230102d2006200341f8026a2903003703002009200341" + "f0026a2903003703002003200341e8026a2903003703c807200320032903" + "e0023703c007200341c0076a202220202021201f42c7faf3c3ed82a3903c" + "428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93" + "b230102d200341d8036a2001290300370300200341d0036a200229030037" + "0300200341e8036a20032903c807370300200341f0036a20092903003703" + "00200341f8036a200629030037030020032003290388073703c803200320" + "03290380073703c003200320032903c0073703e003200341c0076a200341" + "80036a20034180036a1030200341b8096a200341f8076a220c2903003703" + "00200341b0096a200341f0076a2211290300370300200341a8096a200341" + "e8076a220d290300370300200341a0096a200341e0076a221a2903003703" + "0020034198096a200629030037030020034190096a200929030037030020" + "0320032903c80737038809200320032903c0073703800920034180096a20" + "0341c0076a200341c0076a102f20034180046a20034180036a2003418009" + "6a102f200341c0046a200341c0036a200341c0036a103020034180056a20" + "0320034180096a102f200341c0056a20034180026a20034180046a102f20" + "0341d0096a220a200341d0046a290300370300200341d8096a2207200341" + "d8046a290300370300200341e0096a220b200341e0046a29030037030020" + "0341e8096a220e200341e8046a290300370300200341f0096a220f200341" + "f0046a290300370300200341f8096a2210200341f8046a29030037030020" + "0320032903c0043703c009200320032903c8043703c809200341c0096a20" + "0341c0046a200341c0046a102f200341d8066a2208200729030037030020" + "0341d0066a2207200a290300370300200320032903c8093703c806200320" + "032903c0093703c006200341c0066a200329038004200329038804200329" + "03900420034198046a29030042c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d20062010" + "2903003703002009200f2903003703002003200e2903003703c807200320" + "0b2903003703c007200341c0076a20032903a004200341a8046a29030020" + "032903b004200341b8046a29030042c7faf3c3ed82a3903c428d95c7c396" + "d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2001" + "200829030037030020022007290300370300200341a8076a220e20032903" + "c807370300200341b0076a220f2009290300370300200341b8076a221020" + "06290300370300200320032903c80637038807200320032903c006370380" + "07200320032903c0073703a007200341c0076a20034180056a2003418005" + "6a103020034198066a2212200129030037030020034190066a2213200229" + "030037030020032003290388073703880620032003290380073703800620" + "034180066a20032903c00720032903c80720032903d007200629030042c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f" + "42a9c0c689aece93b230102d200820102903003703002007200f29030037" + "03002003200e2903003703c806200320032903a0073703c006200341c006" + "6a20032903e007200d29030020032903f007200c29030042c7faf3c3ed82" + "a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689" + "aece93b230102d2008290300211f20072903002120201229030021212013" + "290300212220032903c806212320032903c0062124200329038806212520" + "03290380062126200820034198056a290300370300200720034190056a29" + "030037030020032003290388053703c80620032003290380053703c00620" + "0341c0066a202620252022202142c7faf3c3ed82a3903c428d95c7c396d2" + "dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200120" + "0341b8056a2903003703002002200341b0056a2903003703002003200341" + "a8056a29030037038807200320032903a0053703800720034180076a2024" + "20232020201f42c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0" + "858ce8b691a8b87f42a9c0c689aece93b230102d20062008290300370300" + "20092007290300370300200d200329038807370300201120022903003703" + "00200c2001290300370300200320032903c8063703c807200320032903c0" + "063703c00720032003290380073703e00720034180076a200341c0046a20" + "0341c0076a102f200341c0076a200341c0056a200341c0056a1030200341" + "f80a6a220a2001290300370300200341f00a6a220b200229030037030020" + "032003290388073703e80a20032003290380073703e00a200341e00a6a20" + "032903c00720032903c80720032903d007200629030042c7faf3c3ed82a3" + "903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689ae" + "ce93b230102d200820102903003703002007200f2903003703002003200e" + "2903003703c806200320032903a0073703c006200341c0066a20032903e0" + "07200d29030020032903f007200c29030042c7faf3c3ed82a3903c428d95" + "c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b23010" + "2d2012200a2903003703002013200b290300370300200341a0066a221b20" + "032903c006370300200341a8066a221c20032903c806370300200341b006" + "6a221d2007290300370300200341b8066a221e2008290300370300200320" + "032903e80a37038806200320032903e00a37038006200341c0076a200420" + "051030200341b80a6a2204200c290300370300200341b00a6a2205201129" + "0300370300200341a80a6a220c200d290300370300200341a00a6a220d20" + "1a290300370300200341980a6a22112006290300370300200341900a6a22" + "062009290300370300200320032903c8073703880a200320032903c00737" + "03800a200341800a6a200341c0076a200341c0076a102f200a2011290300" + "370300200b2006290300370300200320032903880a3703e80a2003200329" + "03800a3703e00a200341e00a6a2003290380082003290388082003290390" + "08201629030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0" + "858ce8b691a8b87f42a9c0c689aece93b230102d20082004290300370300" + "200720052903003703002003200c2903003703c8062003200d2903003703" + "c006200341c0066a20032903a008201529030020032903b0082014290300" + "42c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8" + "b87f42a9c0c689aece93b230102d2001200a2903003703002002200b2903" + "00370300200e20032903c806370300200f20072903003703002010200829" + "0300370300200320032903e80a37038807200320032903e00a3703800720" + "0320032903c0063703a007200341d80a6a22042001290300370300200341" + "d00a6a2201200229030037030020032003290388073703c80a2003200329" + "0380073703c00a200341c00a6a20032903c00820032903c80820032903d0" + "08201929030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0" + "858ce8b691a8b87f42a9c0c689aece93b230102d200a2010290300370300" + "200b200f2903003703002003200e2903003703e80a200320032903a00737" + "03e00a200341e00a6a20032903e008201829030020032903f00820172903" + "0042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691" + "a8b87f42a9c0c689aece93b230102d200820042903003703002007200129" + "0300370300200341e8066a20032903e80a370300200341f0066a200b2903" + "00370300200341f8066a200a290300370300200320032903c80a3703c806" + "200320032903c00a3703c006200320032903e00a3703e00620004180016a" + "200341c0066a20034180036a102f2000201f370338200020203703302000" + "202337032820002024370320200020213703182000202237031020002025" + "370308200020263703002000200329038006370340200041c8006a200329" + "038806370300200041d0006a2013290300370300200041d8006a20122903" + "00370300200041e0006a201b290300370300200041e8006a201c29030037" + "0300200041f0006a201d290300370300200041f8006a201e290300370300" + "0c030b2000200110430c020b2000200241c001104c1a0c010b2000200141" + "c001104c1a0b200341800b6a24000bf50602037f067e230041c0026b2202" + "24000240024002400240024020012903800120014188016a290300844200" + "520d0020012903900120014198016a290300844200520d0020012903a001" + "200141a8016a290300844200520d0020012903b001200141b8016a290300" + "84500d010b200241d8006a4200370300200241e0006a2204420037030020" + "0241e8006a4200370300200241f0006a4200370300200241f8006a420037" + "030020024200370348200242013703402002420037035020014180016a22" + "03200241406b104a450440200141a0016a2004104a450d020b200241406b" + "200310312002280240410171450d02200241386a20024188016a29030022" + "05370300200241306a20024180016a22032903002206370300200241286a" + "200241f8006a2903002207370300200241206a200241f0006a2903002208" + "370300200241186a200241e8006a2903002209370300200241106a200241" + "e0006a290300220a37030020024190026a200a37030020024198026a2009" + "370300200241a0026a2008370300200241a8026a2007370300200241b002" + "6a2006370300200241b8026a200537030020022002290350220537030020" + "02200241d8006a2903002206370308200220053703800220022006370388" + "0220024180026a20022002102f200241406b200120024180026a102f2002" + "41c0016a200220024180026a102f2003200141406b200241c0016a102f20" + "0041106a200241406b418001104c1a20004200370308200042013703000c" + "030b20004200370308200042003703000c020b200241b8016a200141f800" + "6a290300370300200241b0016a200141f0006a290300370300200241a801" + "6a200141e8006a290300370300200241a0016a200141e0006a2903003703" + "0020024198016a200141d8006a29030037030020024190016a200141d000" + "6a29030037030020024188016a200141c8006a290300370300200241d000" + "6a200141106a290300370300200241d8006a200141186a29030037030020" + "0241e0006a200141206a290300370300200241e8006a200141286a290300" + "370300200241f0006a200141306a290300370300200241f8006a20014138" + "6a2903003703002002200129034037038001200220012903003703402002" + "200141086a290300370348200041106a200241406b418001104c1a200042" + "00370308200042013703000c010b4194a1c0001020000b200241c0026a24" + "000bd64502497f107e230041a00f6b22022400200241386a223f200141f8" + "006a220e290300370300200241306a2240200141f0006a220f2903003703" + "00200241286a2241200141e8006a2210290300370300200241206a224220" + "0141e0006a2211290300370300200241186a2243200141d8006a22122903" + "00370300200241106a2244200141d0006a22202903003703002002200129" + "03403703002002200141c8006a2221290300370308200141a8016a222329" + "03002153200141a0016a22242903002154200141b8016a22252903002155" + "200141b0016a2230290300215620014188016a2235290300215720014198" + "016a2236290300215820014190016a22372903002159200129038001215a" + "200241f8006a200141f8016a2213290300370300200241f0006a200141f0" + "016a2214290300370300200241e8006a200141e8016a2215290300370300" + "200241e0006a200141e0016a2216290300370300200241d8006a200141d8" + "016a2217290300370300200241d0006a200141d0016a220d290300370300" + "20024190016a20014190026a220429030037030020024198016a20014198" + "026a2206290300370300200241a0016a200141a0026a2207290300370300" + "200241a8016a200141a8026a2208290300370300200241b0016a200141b0" + "026a2205290300370300200241b8016a200141b8026a2209290300370300" + "2002200141c8016a2222290300370348200220012903c001370340200220" + "012903800237038001200220014188026a220a29030037038801200241f8" + "016a200141f8026a2238290300370300200241f0016a200141f0026a2245" + "290300370300200241e8016a200141e8026a2246290300370300200241e0" + "016a200141e0026a2247290300370300200241d8016a200141d8026a2248" + "290300370300200241d0016a200141d0026a2249290300370300200241b8" + "026a2226200141386a2231290300370300200241b0026a2227200141306a" + "2232290300370300200241a8026a2228200141286a223a29030037030020" + "0241a0026a2229200141206a223b29030037030020024198026a222a2001" + "41186a223c29030037030020024190026a222b200141106a223d29030037" + "03002002200141c8026a224a2903003703c801200220012903c0023703c0" + "012002200141086a223e2903003703880220022001290300370380022002" + "4180026a200120014180026a2203102f200241f8026a2219203129030037" + "0300200241f0026a221a2032290300370300200241e8026a221b203a2903" + "00370300200241e0026a221c203b290300370300200241d8026a221d203c" + "290300370300200241d0026a221e203d2903003703002002203e29030037" + "03c802200220012903003703c002200241c0026a200120031030200241b8" + "036a220b2009290300370300200241b0036a220920052903003703002002" + "41a8036a22052008290300370300200241a0036a220c2007290300370300" + "20024198036a2218200629030037030020024190036a221f200429030037" + "0300200242003703b80d200242003703b00d200242003703a80d20024201" + "3703a00d200242003703980d200242003703900d200242003703880d2002" + "42093703800d2002200a2903003703880320022001290380023703800320" + "024180036a2003200241800d6a102f200241c00b6a20024180036a200110" + "30200b200241f80b6a22062903003703002009200241f00b6a2207290300" + "3703002005200241e80b6a2208290300370300200c200241e00b6a220529" + "03003703002018200241d80b6a2203290300370300201f200241d00b6a22" + "04290300370300200220022903c80b37038803200220022903c00b370380" + "03200241c00b6a200241c0026a20024180036a102f201920062903003703" + "00201a2007290300370300201b2008290300370300201c20052903003703" + "00201d2003290300370300201e2004290300370300200220022903c80b37" + "03c802200220022903c00b3703c002200241980f6a220b201d2903003703" + "00200241900f6a220c201e290300370300200220022903c8023703880f20" + "0220022903c0023703800f200241800f6a20022903800220022903880220" + "2b290300202a29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f" + "42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200241980a6a22" + "092019290300370300200241900a6a220a201a2903003703002002201b29" + "03003703880a2002201c2903003703800a200241800a6a20292903002028" + "2903002027290300202629030042c7faf3c3ed82a3903c428d95c7c396d2" + "dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200320" + "0b290300224b3703002004200c290300224c370300200520022903800a22" + "4d3703002007200a290300224e370300200820022903880a224f37030020" + "0620092903002250370300200220022903880f22513703c80b2002200229" + "03800f22523703c00b20192050370300201a204e370300201b204f370300" + "201c204d370300201d204b370300201e204c370300200220513703c80220" + "0220523703c002200241c0036a20024180026a200241800d6a102f200b20" + "1d290300370300200c201e290300370300200220022903c8023703880f20" + "0220022903c0023703800f200241800f6a20022903c00320022903c80320" + "022903d003200241d8036a29030042c7faf3c3ed82a3903c428d95c7c396" + "d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2009" + "2019290300370300200a201a2903003703002002201b2903003703880a20" + "02201c2903003703800a200241800a6a20022903e003200241e8036a2903" + "0020022903f003200241f8036a29030042c7faf3c3ed82a3903c428d95c7" + "c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d" + "2003200b290300224b3703002004200c290300224c370300200520022903" + "800a224d3703002007200a290300224e370300200820022903880a224f37" + "0300200620092903002250370300200220022903880f22513703c80b2002" + "20022903800f22523703c00b20192050370300201a204e370300201b204f" + "370300201c204d370300201d204b370300201e204c370300200220513703" + "c802200220523703c002200241c00b6a20024180026a20024180026a1030" + "202620062903003703002027200729030037030020282008290300370300" + "20292005290300370300202a2003290300370300202b2004290300370300" + "200220022903c80b37038802200220022903c00b3703800220024190046a" + "221f200d29030037030020024198046a222c2017290300370300200241a0" + "046a222d2016290300370300200241a8046a222e20152903003703002002" + "41b0046a222f2014290300370300200241b8046a22392013290300370300" + "200220012903c00137038004200220222903003703880420024180046a20" + "0141c0016a223320014180016a2234102f200241f8046a22182013290300" + "370300200241f0046a22132014290300370300200241e8046a2214201529" + "0300370300200241e0046a22152016290300370300200241d8046a221620" + "17290300370300200241d0046a2217200d29030037030020022022290300" + "3703c804200220012903c0013703c004200241c0046a2033203410302002" + "41b8056a220d2025290300370300200241b0056a22222030290300370300" + "200241a8056a22252023290300370300200241a0056a2223202429030037" + "030020024198056a2224203629030037030020024190056a223020372903" + "003703002002203529030037038805200220012903800137038005200241" + "80056a2034200241800d6a102f200241c00b6a20024180056a2033103020" + "0d2006290300370300202220072903003703002025200829030037030020" + "232005290300370300202420032903003703002030200429030037030020" + "0220022903c80b37038805200220022903c00b37038005200241c00b6a20" + "0241c0046a20024180056a102f2018200629030037030020132007290300" + "370300201420082903003703002015200529030037030020162003290300" + "37030020172004290300370300200220022903c80b3703c8042002200229" + "03c00b3703c004200b2016290300370300200c2017290300370300200220" + "022903c8043703880f200220022903c0043703800f200241800f6a200229" + "038004200229038804201f290300202c29030042c7faf3c3ed82a3903c42" + "8d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b2" + "30102d20092018290300370300200a201329030037030020022014290300" + "3703880a200220152903003703800a200241800a6a202d290300202e2903" + "00202f290300203929030042c7faf3c3ed82a3903c428d95c7c396d2dac0" + "977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2003200b29" + "0300224b3703002004200c290300224c370300200520022903800a224d37" + "03002007200a290300224e370300200820022903880a224f370300200620" + "092903002250370300200220022903880f22513703c80b20022002290380" + "0f22523703c00b201820503703002013204e3703002014204f3703002015" + "204d3703002016204b3703002017204c370300200220513703c804200220" + "523703c004200241c0056a20024180046a200241800d6a102f200b201629" + "0300370300200c2017290300370300200220022903c8043703880f200220" + "022903c0043703800f200241800f6a20022903c00520022903c805200229" + "03d005200241d8056a29030042c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d20092018" + "290300370300200a2013290300370300200220142903003703880a200220" + "152903003703800a200241800a6a20022903e005200241e8056a29030020" + "022903f005200241f8056a29030042c7faf3c3ed82a3903c428d95c7c396" + "d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2003" + "200b290300224b3703002004200c290300224c370300200520022903800a" + "224d3703002007200a290300224e370300200820022903880a224f370300" + "200620092903002250370300200220022903880f22513703c80b20022002" + "2903800f22523703c00b201820503703002013204e3703002014204f3703" + "002015204d3703002016204b3703002017204c370300200220513703c804" + "200220523703c004200241c00b6a20024180046a20024180046a10302039" + "2006290300370300202f2007290300370300202e2008290300370300202d" + "2005290300370300202c2003290300370300201f20042903003703002002" + "20022903c80b37038804200220022903c00b3703800420024190066a2222" + "202029030037030020024198066a22332012290300370300200241a0066a" + "22342011290300370300200241a8066a22232010290300370300200241b0" + "066a2224200f290300370300200241b8066a2225200e2903003703002002" + "200129034037038006200220212903003703880620024180066a20014140" + "6b200141c0026a2230102f200241f8066a220d200e290300370300200241" + "f0066a220e200f290300370300200241e8066a220f201029030037030020" + "0241e0066a22102011290300370300200241d8066a221120122903003703" + "00200241d0066a22122020290300370300200220212903003703c8062002" + "20012903403703c006200241c0066a200220301030200241b8076a222020" + "38290300370300200241b0076a22212045290300370300200241a8076a22" + "352046290300370300200241a0076a223620472903003703002002419807" + "6a2237204829030037030020024190076a22382049290300370300200220" + "4a29030037038807200220012903c0023703800720024180076a20302002" + "41800d6a102f200241c00b6a20024180076a200210302020200629030037" + "030020212007290300370300203520082903003703002036200529030037" + "03002037200329030037030020382004290300370300200220022903c80b" + "37038807200220022903c00b37038007200241c00b6a200241c0066a2002" + "4180076a102f200d2006290300370300200e2007290300370300200f2008" + "290300370300201020052903003703002011200329030037030020122004" + "290300370300200220022903c80b3703c806200220022903c00b3703c006" + "200b2011290300370300200c2012290300370300200220022903c8063703" + "880f200220022903c0063703800f200241800f6a20022903800620022903" + "88062022290300203329030042c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2009200d" + "290300370300200a200e2903003703002002200f2903003703880a200220" + "102903003703800a200241800a6a20342903002023290300202429030020" + "2529030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858c" + "e8b691a8b87f42a9c0c689aece93b230102d2003200b290300224b370300" + "2004200c290300224c370300200520022903800a224d3703002007200a29" + "0300224e370300200820022903880a224f37030020062009290300225037" + "0300200220022903880f22513703c80b200220022903800f22523703c00b" + "200d2050370300200e204e370300200f204f3703002010204d3703002011" + "204b3703002012204c370300200220513703c806200220523703c0062002" + "41c0076a20024180066a200241800d6a102f200b2011290300370300200c" + "2012290300370300200220022903c8063703880f200220022903c0063703" + "800f200241800f6a20022903c00720022903c80720022903d007200241d8" + "076a29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb085" + "8ce8b691a8b87f42a9c0c689aece93b230102d2009200d29030037030020" + "0a200e2903003703002002200f2903003703880a20022010290300370380" + "0a200241800a6a20022903e007200241e8076a29030020022903f0072002" + "41f8076a29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42dd" + "b0858ce8b691a8b87f42a9c0c689aece93b230102d2003200b290300224b" + "3703002004200c290300224c370300200520022903800a224d3703002007" + "200a290300224e370300200820022903880a224f37030020062009290300" + "2250370300200220022903880f22513703c80b200220022903800f225237" + "03c00b200d2050370300200e204e370300200f204f3703002010204d3703" + "002011204b3703002012204c370300200220513703c806200220523703c0" + "06200241c00b6a20024180066a20024180066a1030202520062903003703" + "002024200729030037030020232008290300370300203420052903003703" + "002033200329030037030020222004290300370300200220022903c80b37" + "038806200220022903c00b370380062009201d290300370300200a201e29" + "0300370300200220022903c8023703880a200220022903c0023703800a20" + "0241800a6a2001290300203e290300203d290300203c29030042c7faf3c3" + "ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0" + "c689aece93b230102d200320192903003703002004201a29030037030020" + "02201b2903003703c80b2002201c2903003703c00b200241c00b6a203b29" + "0300203a2903002032290300203129030042c7faf3c3ed82a3903c428d95" + "c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b23010" + "2d200241d80d6a221c2009290300370300200241d00d6a221d200a290300" + "370300200241e00d6a221e20022903c00b370300200241e80d6a22202002" + "2903c80b370300200241f00d6a22212004290300370300200241f80d6a22" + "312003290300370300200220022903880a3703c80d200220022903800a37" + "03c00d200241c00b6a200241c00d6a200241c00d6a103020312006290300" + "3703002021200729030037030020202008290300370300201e2005290300" + "370300201c2003290300370300201d2004290300370300200220022903c8" + "0b3703c80d200220022903c00b3703c00d200241c00b6a200241c00d6a20" + "0241c0026a10302031200629030037030020212007290300370300202020" + "08290300370300201e2005290300370300201c2003290300370300201d20" + "0429030037030020024190086a2232202b29030037030020024198086a22" + "2b202a290300370300200241a0086a222a2029290300370300200241a808" + "6a22292028290300370300200241b0086a22282027290300370300200241" + "b8086a22272026290300370300200220022903c80b3703c80d2002200229" + "03c00b3703c00d2002200229038002370380082002200229038802370388" + "0820024180086a20024180026a20024180016a1030200241c00b6a200241" + "80086a20024180086a103020272006290300370300202820072903003703" + "0020292008290300370300202a2005290300370300202b20032903003703" + "0020322004290300370300200220022903c80b37038808200220022903c0" + "0b37038008200241c00b6a20024180086a20024180026a10302027200629" + "03003703002028200729030037030020292008290300370300202a200529" + "0300370300202b200329030037030020322004290300370300200241d008" + "6a22012022290300370300200241d8086a220b2033290300370300200241" + "e0086a220c2034290300370300200241e8086a2219202329030037030020" + "0241f0086a221a2024290300370300200241f8086a221b20252903003703" + "00200220022903c80b37038808200220022903c00b370380082002200229" + "0380063703c00820022002290388063703c808200241c0086a2002418006" + "6a200241800d6a102f200241c00b6a200241c0086a200241406b1030201b" + "2006290300370300201a200729030037030020192008290300370300200c" + "2005290300370300200b2003290300370300200120042903003703002002" + "20022903c80b3703c808200220022903c00b3703c008200241c00b6a2002" + "41c0086a200241c0086a1030201b2006290300370300201a200729030037" + "030020192008290300370300200c2005290300370300200b200329030037" + "030020012004290300370300200220022903c80b3703c808200220022903" + "c00b3703c00820024180096a20024180066a200241800d6a102f200241c0" + "0b6a200241c0086a20024180096a1030201b2006290300370300201a2007" + "29030037030020192008290300370300200c2005290300370300200b2003" + "29030037030020012004290300370300200220022903c80b3703c8082002" + "20022903c00b3703c00820092011290300370300200a2012290300370300" + "200220022903c8063703880a200220022903c0063703800a200241800a6a" + "205a20572059205842c7faf3c3ed82a3903c428d95c7c396d2dac0977f42" + "ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2003200d29030037" + "03002004200e2903003703002002200f2903003703c80b20022010290300" + "3703c00b200241c00b6a205420532056205542c7faf3c3ed82a3903c428d" + "95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230" + "102d200241980e6a220d2009290300370300200241900e6a220e200a2903" + "00370300200241a00e6a220f20022903c00b370300200241a80e6a221020" + "022903c80b370300200241b00e6a22112004290300370300200241b80e6a" + "22122003290300370300200220022903880a3703880e200220022903800a" + "3703800e200241c00b6a200241800e6a200241800e6a1030201220062903" + "003703002011200729030037030020102008290300370300200f20052903" + "00370300200d2003290300370300200e2004290300370300200220022903" + "c80b3703880e200220022903c00b3703800e200241c00b6a200241800e6a" + "200241c0066a103020122006290300370300201120072903003703002010" + "2008290300370300200f2005290300370300200d2003290300370300200e" + "2004290300370300200220022903c80b3703880e200220022903c00b3703" + "800e20092016290300370300200a2017290300370300200220022903c804" + "3703880a200220022903c0043703800a200241800a6a2002290300200229" + "03082044290300204329030042c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d20032018" + "29030037030020042013290300370300200220142903003703c80b200220" + "152903003703c00b200241c00b6a20422903002041290300204029030020" + "3f29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858c" + "e8b691a8b87f42a9c0c689aece93b230102d200241d80e6a221820092903" + "00370300200241d00e6a2213200a290300370300200241e00e6a22142002" + "2903c00b370300200241e80e6a221520022903c80b370300200241f00e6a" + "22162004290300370300200241f80e6a2217200329030037030020022002" + "2903880a3703c80e200220022903800a3703c00e200241c00b6a200241c0" + "0e6a200241c00e6a10302017200629030037030020162007290300370300" + "201520082903003703002014200529030037030020182003290300370300" + "20132004290300370300200220022903c80b3703c80e200220022903c00b" + "3703c00e200241c00b6a200241c00e6a200241c0046a1030201720062903" + "003703002016200729030037030020152008290300370300201420052903" + "003703002018200329030037030020132004290300370300200241d0096a" + "2226201f290300370300200241d8096a221f202c290300370300200241e0" + "096a222c202d290300370300200241e8096a222d202e2903003703002002" + "41f0096a222e202f290300370300200241f8096a222f2039290300370300" + "200220022903c80b3703c80e200220022903c00b3703c00e200220022903" + "80043703c00920022002290388043703c809200241c0096a20024180046a" + "200241c0016a1030200241c00b6a200241c0096a200241c0096a1030202f" + "2006290300370300202e2007290300370300202d2008290300370300202c" + "2005290300370300201f2003290300370300202620042903003703002002" + "20022903c80b3703c809200220022903c00b3703c009200241c00b6a2002" + "41c0096a20024180046a1030202f2006290300370300202e200729030037" + "0300202d2008290300370300202c2005290300370300201f200329030037" + "030020262004290300370300200220022903c80b3703c809200220022903" + "c00b3703c009200241b80a6a2031290300370300200241b00a6a20212903" + "00370300200241a80a6a2020290300370300200241a00a6a201e29030037" + "03002009201c290300370300200a201d290300370300200220022903c80d" + "3703880a200220022903c00d3703800a200241c80a6a20022903c80e3703" + "00200241d00a6a2013290300370300200241d80a6a201829030037030020" + "0241e00a6a2014290300370300200241e80a6a2015290300370300200241" + "f00a6a2016290300370300200241f80a6a20172903003703002002200229" + "03c00e3703c00a200241b80b6a2012290300370300200241b00b6a201129" + "0300370300200241a80b6a2010290300370300200241a00b6a200f290300" + "370300200241980b6a200d290300370300200241900b6a200e2903003703" + "00200241880b6a20022903880e370300200220022903800e3703800b2006" + "201b2903003703002007201a290300370300200820192903003703002005" + "200c2903003703002003200b290300370300200420012903003703002002" + "20022903c8083703c80b200220022903c0083703c00b200241880c6a2002" + "29038808370300200241900c6a2032290300370300200241980c6a202b29" + "0300370300200241a00c6a202a290300370300200241a80c6a2029290300" + "370300200241b00c6a2028290300370300200241b80c6a20272903003703" + "0020022002290380083703800c200241f80c6a202f290300370300200241" + "f00c6a202e290300370300200241e80c6a202d290300370300200241e00c" + "6a202c290300370300200241d80c6a201f290300370300200241d00c6a20" + "26290300370300200241c80c6a20022903c809370300200220022903c009" + "3703c00c2000200241800a6a41c001104c41c0016a200241c00b6a41c001" + "104c1a200241a00f6a24000bcc1101047f23004180026b22032400024020" + "024101712206450440200341386a200141386a290300370300200341306a" + "200141306a290300370300200341286a200141286a290300370300200341" + "206a200141206a290300370300200341186a200141186a29030037030020" + "0341106a200141106a290300370300200320012903003703002003200141" + "086a29030037030820034190016a200141d0006a29030037030020034198" + "016a200141d8006a290300370300200341a0016a200141e0006a29030037" + "0300200341a8016a200141e8006a290300370300200341b0016a200141f0" + "006a290300370300200341b8016a200141f8006a29030037030020032001" + "290340370380012003200141c8006a290300370388010c010b200341d801" + "6a2204200141386a290300370300200341d0016a2205200141306a290300" + "370300200320012903203703c0012003200141286a2903003703c8012003" + "41c0016a42c6faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858c" + "e8b691a8b87f42a9c0c689aece93b23042c7faf3c3ed82a3903c428d95c7" + "c396d2dac0977f102b200341186a200141186a290300370300200341106a" + "200141106a290300370300200341286a20032903c801370300200341306a" + "2005290300370300200341386a20042903003703002003200141086a2903" + "0037030820032001290300370300200320032903c0013703202004200141" + "f8006a2903003703002005200141f0006a2903003703002003200141e800" + "6a2903003703c801200320012903603703c001200341c0016a42c6faf3c3" + "ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0" + "c689aece93b23042c7faf3c3ed82a3903c428d95c7c396d2dac0977f102b" + "20034198016a200141d8006a29030037030020034190016a200141d0006a" + "290300370300200341a8016a20032903c801370300200341b0016a200529" + "0300370300200341b8016a20042903003703002003200141c8006a290300" + "370388012003200129034037038001200320032903c0013703a0010b0240" + "0240024002402002410670220441026b0e020102000b200342a0dcae8f86" + "aaf9e4163703f801200342948fe8babd91b3d2cb003703f001200342cebb" + "f2dbd0c38ad7323703e801200342a297bfa0c6a3f5b2163703e001200342" + "f7a3e4fb84f3d1d92f3703d801200342c3e2e6aacf87fb85cc003703d001" + "2003428ce68c968ce2b0c6b77f3703c801200342bdaabdbbf1aae5f1997f" + "3703c0010c020b200341e0016a22024200370300200241086a4200370300" + "200241106a4200370300200241186a4200370300200342a9c0c689aece93" + "b2303703d801200342b099b385febcf6b6de003703d001200342bddcd9dc" + "fbd3c1c7423703c801200342c8faf383d69cd1de643703c0010c010b2003" + "42efecc59e9bc8f7f8043703f801200342cf9298e1decdc3f9a97f3703f0" + "01200342b1ccfcc7f9b7ccef0f3703e801200342de8d96d5bae5aa863837" + "03e0012003428aded7ba8b8fb8ab083703d801200342accbfcacf98ec7ff" + "ba7f3703d001200342d385a5ebd5a7ffaf807f3703c801200342edf6f3de" + "87dd9bbafb003703c0010b20014180016a2102200341406b20034180016a" + "200341c0016a102f02402006450440200341b8016a200241386a29030037" + "0300200341b0016a200241306a290300370300200341a8016a200241286a" + "290300370300200341a0016a200241206a29030037030020034198016a20" + "0241186a29030037030020034190016a200241106a290300370300200320" + "02290300370380012003200241086a290300370388010c010b200341d801" + "6a2206200141b8016a290300370300200341d0016a2205200141b0016a29" + "0300370300200320012903a0013703c0012003200141a8016a2903003703" + "c801200341c0016a42c6faf3c3ed82a3903c428d95c7c396d2dac0977f42" + "ddb0858ce8b691a8b87f42a9c0c689aece93b23042c7faf3c3ed82a3903c" + "428d95c7c396d2dac0977f102b20034198016a200241186a290300370300" + "20034190016a200241106a290300370300200341a8016a20032903c80137" + "0300200341b0016a2005290300370300200341b8016a2006290300370300" + "2003200241086a2903003703880120032002290300370380012003200329" + "03c0013703a0010b0240024002400240200441026b0e020102000b200342" + "ee95f6bfbedb978a2c3703f80120034292b9acd88396a09d9f7f3703f001" + "200342e38efbdea1ddf4c2363703e801200342a682aee99ce2d19d413703" + "e00120034281d0baa7e6ebd3da053703d80120034284bde0d0f596f0f980" + "7f3703d001200342f2d8d3f4fbbed999533703c801200342e2cefa90d9ea" + "87c5847f3703c0010c020b200341e0016a22014200370300200141086a42" + "00370300200141106a4200370300200141186a4200370300200342003703" + "d801200342ac97d286eaf99af1d9003703d001200342cfb8ede69afe98f9" + "543703c801200342feffffbf97e6d1b1d7003703c0010c010b2003429294" + "c48c9eb3faea233703f80120034284bac8e6f0ddbdd87e3703f001200342" + "e5adfe9b87c1a7a5a47f3703e8012003429fc7b098d7b3fbf1df003703e0" + "01200342ab9b828ee18ce3e20b3703d801200342ce88c9adfb9eb8df1937" + "03d001200342cbd7c1add7a8c299663703c801200342e6e0afe6c3d7a48d" + "0e3703c0010b20004180016a20034180016a200341c0016a102f20004138" + "6a200341386a290300370300200041306a200341306a2903003703002000" + "41286a200341286a290300370300200041206a200341206a290300370300" + "200041186a200341186a290300370300200041106a200341106a29030037" + "0300200041086a2003290308370300200020032903003703002000200329" + "0340370340200041c8006a2003290348370300200041d0006a200341d000" + "6a290300370300200041d8006a200341d8006a290300370300200041e000" + "6a200341e0006a290300370300200041e8006a200341e8006a2903003703" + "00200041f0006a200341f0006a290300370300200041f8006a200341f800" + "6a29030037030020034180026a24000bbd46027c7f107e230041e00b6b22" + "052400200541b8016a2234200141b8016a2235290300370300200541b001" + "6a2236200141b0016a2237290300370300200541a8016a2238200141a801" + "6a2239290300370300200541a0016a223a200141a0016a223b2903003703" + "0020054198016a223c20014198016a223d29030037030020054190016a22" + "3e20014190016a223f290300370300200541d0016a222e200141d0016a22" + "4f290300370300200541d8016a222f200141d8016a225029030037030020" + "0541e0016a2230200141e0016a2251290300370300200541e8016a223120" + "0141e8016a2252290300370300200541f0016a2232200141f0016a225329" + "0300370300200541f8016a2233200141f8016a2254290300370300200520" + "012903800137038001200520012903c0013703c001200520014188016a22" + "40290300370388012005200141c8016a22552903003703c801200541b802" + "6a2256200141f8026a2220290300370300200541b0026a2257200141f002" + "6a2221290300370300200541a8026a2258200141e8026a22282903003703" + "00200541a0026a2259200141e0026a222929030037030020054198026a22" + "5a200141d8026a222a29030037030020054190026a225b200141d0026a22" + "2b290300370300200541d0026a2241200141106a22062903003703002005" + "41d8026a2242200141186a2207290300370300200541e0026a2243200141" + "206a2208290300370300200541e8026a2244200141286a22092903003703" + "00200541f0026a2245200141306a220a290300370300200541f8026a2246" + "200141386a220b2903003703002005200141c8026a222c29030037038802" + "200520012903c00237038002200520012903003703c0022005200141086a" + "220c2903003703c802200541c0026a20012002102f200541b8036a225c20" + "35290300370300200541b0036a225d2037290300370300200541a8036a22" + "5e2039290300370300200541a0036a225f203b2903003703002005419803" + "6a2260203d29030037030020054190036a2261203f290300370300200520" + "402903003703880320052001290380013703800320054180036a20014180" + "016a220d2004102f200541f8036a2262200141b8026a2903003703002005" + "41f0036a2263200141b0026a290300370300200541e8036a2264200141a8" + "026a290300370300200541e0036a2265200141a0026a2903003703002005" + "41d8036a226620014198026a290300370300200541d0036a226720014190" + "026a290300370300200520014188026a2903003703c80320052001290380" + "023703c003200541c0036a20014180026a22472003102f200541b8046a22" + "68200b290300370300200541b0046a2269200a290300370300200541a804" + "6a226a2009290300370300200541a0046a226b2008290300370300200541" + "98046a226c200729030037030020054190046a226d200629030037030020" + "05200c29030037038804200520012903003703800420054180046a200120" + "471030200541f8046a226e200b290300370300200541f0046a226f200a29" + "0300370300200541e8046a22702009290300370300200541e0046a227120" + "08290300370300200541d8046a22722007290300370300200541d0046a22" + "7320062903003703002005200c2903003703c804200520012903003703c0" + "04200541c0046a2001200d1030200541b8056a2248200141f8006a221229" + "0300370300200541b0056a2249200141f0006a2213290300370300200541" + "a8056a224a200141e8006a2214290300370300200541a0056a224b200141" + "e0006a221529030037030020054198056a224c200141d8006a221c290300" + "37030020054190056a224d200141d0006a221d2903003703002005200141" + "c8006a221e29030037038805200520012903403703800520054180056a20" + "0141406b221f200141c0016a22741030200541c0096a20054180056a2001" + "41c0026a222d10302048200541f8096a220c2903003703002049200541f0" + "096a220d290300370300204a200541e8096a220e290300370300204b2005" + "41e0096a220f290300370300204c200541d8096a2210290300370300204d" + "200541d0096a2211290300370300200520052903c8093703880520052005" + "2903c00937038005200541d0056a2222201d290300370300200541d8056a" + "2223201c290300370300200541e0056a22242015290300370300200541e8" + "056a22252014290300370300200541f0056a222620132903003703002005" + "41f8056a22272012290300370300200520012903403703c0052005201e29" + "03003703c805200541c0056a201f2004102f200541b8066a221620272903" + "00370300200541b0066a22172026290300370300200541a8066a22182025" + "290300370300200541a0066a2219202429030037030020054198066a221a" + "202329030037030020054190066a221b2022290300370300200520052903" + "c80537038806200520052903c0053703800620054180066a200541c0056a" + "200541c0036a1030200542003703b80b200542003703b00b200542003703" + "a80b200542013703a00b200542003703980b200542003703900b20054200" + "3703880b200542093703800b200541c0096a20054180066a200541800b6a" + "102f2016200c2903003703002017200d2903003703002018200e29030037" + "03002019200f290300370300201a2010290300370300201b201129030037" + "0300200520052903c80937038806200520052903c00937038006200541c0" + "096a20054180066a200541c0026a10302016200c29030022810137030020" + "17200d2903002282013703002018200e2903002283013703002019200f29" + "0300228401370300201a2010290300228501370300201b20112903002286" + "01370300200541106a2275208601370300200541186a2276208501370300" + "200541206a2277208401370300200541286a227820830137030020054130" + "6a2279208201370300200541386a227a208101370300200520052903c809" + "22810137038806200520052903c009228201370380062005208201370300" + "2005208101370308200541f8066a22062020290300370300200541f0066a" + "22072021290300370300200541e8066a22082028290300370300200541e0" + "066a22092029290300370300200541d8066a220a202a2903003703002005" + "41d0066a220b202b2903003703002005202c2903003703c8062005200129" + "03c0023703c006200541c0066a202d2003102f200541c0096a200541c005" + "6a200541c0066a10302027200c2903003703002026200d29030037030020" + "25200e2903003703002024200f2903003703002023201029030037030020" + "222011290300370300200520052903c8093703c805200520052903c00937" + "03c005200541c0096a200541c0066a20054180036a10302006200c290300" + "2281013703002007200d2903002282013703002008200e29030022830137" + "03002009200f290300228401370300200a2010290300228501370300200b" + "2011290300228601370300201b208601370300201a208501370300201920" + "840137030020182083013703002017208201370300201620810137030020" + "0520052903c8092281013703c806200520052903c0092282013703c00620" + "052082013703800620052081013703880620054180066a200541c0066a20" + "0541800b6a102f2006201229030037030020072013290300370300200820" + "1429030037030020092015290300370300200a201c290300370300200b20" + "1d2903003703002005201e2903003703c806200520012903403703c00620" + "0541c0066a201f2002102f200541c0096a200541c0056a200541c0066a10" + "302027200c2903003703002026200d2903003703002025200e2903003703" + "002024200f29030037030020232010290300370300202220112903003703" + "00200520052903c8093703c805200520052903c0093703c005200541c009" + "6a20054180066a200541c0066a10302016200c2903002281013703002017" + "200d2903002282013703002018200e2903002283013703002019200f2903" + "00228401370300201a2010290300228501370300201b2011290300228601" + "370300200541d0006a227b208601370300200541d8006a227c2085013703" + "00200541e0006a227d208401370300200541e8006a227e20830137030020" + "0541f0006a227f208201370300200541f8006a2280012081013703002005" + "20052903c80922810137038806200520052903c009228201370380062005" + "2082013703402005208101370348200541b8076a221c200241386a222829" + "0300370300200541b0076a221d200241306a2229290300370300200541a8" + "076a221e200241286a222a290300370300200541a0076a221f200241206a" + "222b29030037030020054198076a2220200241186a222c29030037030020" + "054190076a2221200241106a222d2903003703002005200241086a224e29" + "030037038807200520022903003703800720054180076a20022004103020" + "06206e2903003703002007206f2903003703002008207029030037030020" + "092071290300370300200a2072290300370300200b207329030037030020" + "0520052903c8043703c806200520052903c0043703c006200541c0066a20" + "0541c0046a20054180076a102f200541d80b6a2214200a29030037030020" + "0541d00b6a2215200b290300370300200520052903c8063703c80b200520" + "052903c0063703c00b200541c00b6a20052903c00220052903c802204129" + "0300204229030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42dd" + "b0858ce8b691a8b87f42a9c0c689aece93b230102d20054198086a221220" + "0629030037030020054190086a2213200729030037030020052008290300" + "37038808200520092903003703800820054180086a204329030020442903" + "002045290300204629030042c7faf3c3ed82a3903c428d95c7c396d2dac0" + "977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d2010201429" + "030022810137030020112015290300228201370300200f20052903800822" + "8301370300200d2013290300228401370300200e20052903880822850137" + "0300200c2012290300228601370300200520052903c80b2287013703c809" + "200520052903c00b2288013703c009200620860137030020072084013703" + "0020082085013703002009208301370300200a208101370300200b208201" + "37030020052087013703c80620052088013703c0062014200a2903003703" + "002015200b290300370300200520052903c8063703c80b200520052903c0" + "063703c00b200541c00b6a20052903800322810120052903880322820120" + "61290300228301206029030022840142c7faf3c3ed82a3903c428d95c7c3" + "96d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d20" + "122006290300370300201320072903003703002005200829030037038808" + "200520092903003703800820054180086a205f290300228501205e290300" + "228601205d290300228701205c29030022880142c7faf3c3ed82a3903c42" + "8d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b2" + "30102d2010201429030022890137030020112015290300228a0137030020" + "0f200529038008228b01370300200d2013290300228c01370300200e2005" + "29038808228d01370300200c2012290300228e01370300200520052903c8" + "0b228f013703c809200520052903c00b2290013703c0092006208e013703" + "002007208c013703002008208d013703002009208b01370300200a208901" + "370300200b208a013703002005208f013703c80620052090013703c00620" + "162054290300370300201720532903003703002018205229030037030020" + "192051290300370300201a2050290300370300201b204f29030037030020" + "05205529030037038806200520012903c0013703800620054180066a2074" + "2003102f200541c0096a200541c0056a20054180066a10302027200c2903" + "003703002026200d2903003703002025200e2903003703002024200f2903" + "003703002023201029030037030020222011290300370300200520052903" + "c8093703c805200520052903c0093703c005200541c0096a200541c0066a" + "20054180066a10302006200c2903003703002007200d2903003703002008" + "200e2903003703002009200f290300370300200a2010290300370300200b" + "2011290300370300200520052903c8093703c806200520052903c0093703" + "c0062021203f2903003703002020203d290300370300201f203b29030037" + "0300201e2039290300370300201d2037290300370300201c203529030037" + "030020052001290380013703800720052040290300370388072005418007" + "6a20054180016a2047103020342006290300370300203620072903003703" + "0020382008290300370300203a2009290300370300203c200a2903003703" + "00203e200b290300370300200541d0076a200441106a2903003703002005" + "41d8076a200441186a290300370300200541e0076a200441206a29030037" + "0300200541e8076a200441286a290300370300200541f0076a200441306a" + "290300370300200541f8076a200441386a290300370300200520052903c8" + "0637038801200520052903c00637038001200520042903003703c0072005" + "200441086a2903003703c807200541c0076a2004200310302006201c2903" + "003703002007201d2903003703002008201e2903003703002009201f2903" + "00370300200a2020290300370300200b2021290300370300200520052903" + "88073703c80620052005290380073703c006200541c0066a20054180076a" + "200541c0076a102f2014200a2903003703002015200b2903003703002005" + "20052903c8063703c80b200520052903c0063703c00b200541c00b6a2081" + "0120820120830120840142c7faf3c3ed82a3903c428d95c7c396d2dac097" + "7f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d201220062903" + "003703002013200729030037030020052008290300370388082005200929" + "03003703800820054180086a20850120860120870120880142c7faf3c3ed" + "82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c6" + "89aece93b230102d20102014290300228101370300201120152903002282" + "01370300200f200529038008228301370300200d20132903002284013703" + "00200e200529038808228501370300200c20122903002286013703002005" + "20052903c80b2287013703c809200520052903c00b2288013703c0092006" + "208601370300200720840137030020082085013703002009208301370300" + "200a208101370300200b20820137030020052087013703c8062005208801" + "3703c0062014200a2903003703002015200b290300370300200520052903" + "c8063703c80b200520052903c0063703c00b200541c00b6a20052903c003" + "22810120052903c8032282012067290300228301206629030022840142c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f" + "42a9c0c689aece93b230102d201220062903003703002013200729030037" + "03002005200829030037038808200520092903003703800820054180086a" + "206529030022850120642903002286012063290300228701206229030022" + "880142c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b6" + "91a8b87f42a9c0c689aece93b230102d2010201429030022890137030020" + "112015290300228a01370300200f200529038008228b01370300200d2013" + "290300228c01370300200e200529038808228d01370300200c2012290300" + "228e01370300200520052903c80b228f013703c809200520052903c00b22" + "90013703c0092006208e013703002007208c013703002008208d01370300" + "2009208b01370300200a208901370300200b208a013703002005208f0137" + "03c80620052090013703c006201620062903003703002017200729030037" + "03002018200829030037030020192009290300370300201a200a29030037" + "0300201b200b290300370300200520052903c80637038806200520052903" + "c0063703800620054180066a200541c0066a200541800b6a102f20062033" + "290300370300200720322903003703002008203129030037030020092030" + "290300370300200a202f290300370300200b202e29030037030020052005" + "2903c8013703c806200520052903c0013703c006200541c0066a200541c0" + "016a2002102f200541c0096a200541c0056a200541c0066a10302027200c" + "2903003703002026200d2903003703002025200e2903003703002024200f" + "290300370300202320102903003703002022201129030037030020052005" + "2903c8093703c805200520052903c0093703c005200541c0096a20054180" + "066a200541c0066a10302016200c2903002289013703002017200d290300" + "228a013703002018200e290300228b013703002019200f290300228c0137" + "0300201a2010290300228d01370300201b2011290300228e01370300202e" + "208e01370300202f208d013703002030208c013703002031208b01370300" + "2032208a013703002033208901370300200520052903c809228901370388" + "06200520052903c009228a01370380062005208a013703c0012005208901" + "3703c8012006205629030037030020072057290300370300200820582903" + "0037030020092059290300370300200a205a290300370300200b205b2903" + "0037030020052005290388023703c80620052005290380023703c0062005" + "41c0066a20054180026a2004102f200541c0096a200541c0056a200541c0" + "066a10302027200c2903003703002026200d2903003703002025200e2903" + "003703002024200f29030037030020232010290300370300202220112903" + "00370300201b200b290300370300201a200a290300370300201920092903" + "003703002018200829030037030020172007290300370300201620062903" + "00370300200520052903c8093703c805200520052903c0093703c0052005" + "20052903c00637038006200520052903c8063703880620054180066a2005" + "41c0066a200541800b6a102f201c2028290300370300201d202929030037" + "0300201e202a290300370300201f202b2903003703002020202c29030037" + "03002021202d2903003703002005204e2903003703880720052002290300" + "3703800720054180076a2002200310302006206829030037030020072069" + "2903003703002008206a2903003703002009206b290300370300200a206c" + "290300370300200b206d29030037030020052005290388043703c8062005" + "2005290380043703c006200541c0066a20054180046a20054180076a102f" + "2014200a2903003703002015200b290300370300200520052903c8063703" + "c80b200520052903c0063703c00b200541c00b6a20052903c00220052903" + "c8022041290300204229030042c7faf3c3ed82a3903c428d95c7c396d2da" + "c0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d20122006" + "290300370300201320072903003703002005200829030037038808200520" + "092903003703800820054180086a20432903002044290300204529030020" + "4629030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858c" + "e8b691a8b87f42a9c0c689aece93b230102d201020142903002289013703" + "0020112015290300228a01370300200f200529038008228b01370300200d" + "2013290300228c01370300200e200529038808228d01370300200c201229" + "0300228e01370300200520052903c80b228f013703c809200520052903c0" + "0b2290013703c0092006208e013703002007208c013703002008208d0137" + "03002009208b01370300200a208901370300200b208a013703002005208f" + "013703c80620052090013703c0062014200a2903003703002015200b2903" + "00370300200520052903c8063703c80b200520052903c0063703c00b2005" + "41c00b6a20810120820120830120840142c7faf3c3ed82a3903c428d95c7" + "c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d" + "201220062903003703002013200729030037030020052008290300370388" + "08200520092903003703800820054180086a208501208601208701208801" + "42c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8" + "b87f42a9c0c689aece93b230102d20102014290300228101370300201120" + "15290300228201370300200f200529038008228301370300200d20132903" + "00228401370300200e200529038808228501370300200c20122903002286" + "01370300200520052903c80b2287013703c809200520052903c00b228801" + "3703c0092006208601370300200720840137030020082085013703002009" + "208301370300200a208101370300200b20820137030020052087013703c8" + "0620052088013703c006200541c0096a20054180066a200541c0066a1030" + "2016200c2903003703002017200d2903003703002018200e290300370300" + "2019200f290300370300201a2010290300370300201b2011290300370300" + "200520052903c80937038806200520052903c009370380062021202d2903" + "003703002020202c290300370300201f202b290300370300201e202a2903" + "00370300201d2029290300370300201c2028290300370300200520022903" + "00370380072005204e2903003703880720054180076a2002200410302005" + "41c0096a20054180076a20031030201c200c290300370300201d200d2903" + "00370300201e200e290300370300201f200f290300370300202020102903" + "0037030020212011290300370300200b204d290300370300200a204c2903" + "003703002009204b2903003703002008204a290300370300200720492903" + "0037030020062048290300370300200520052903c8093703880720052005" + "2903c0093703800720052005290380053703c00620052005290388053703" + "c806200541c0066a20054180056a20054180076a102f2014200a29030037" + "03002015200b290300370300200520052903c8063703c80b200520052903" + "c0063703c00b200541c00b6a20052903c00520052903c805202229030020" + "2329030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858c" + "e8b691a8b87f42a9c0c689aece93b230102d201220062903003703002013" + "200729030037030020052008290300370388082005200929030037038008" + "20054180086a202429030020252903002026290300202729030042c7faf3" + "c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9" + "c0c689aece93b230102d2010201429030022810137030020112015290300" + "228201370300200f200529038008228301370300200d2013290300228401" + "370300200e200529038808228501370300200c2012290300228601370300" + "200520052903c80b2287013703c809200520052903c00b2288013703c009" + "200620860137030020072084013703002008208501370300200920830137" + "0300200a208101370300200b20820137030020052087013703c806200520" + "88013703c006200541b8086a207a290300370300200541b0086a20792903" + "00370300200541a8086a2078290300370300200541a0086a207729030037" + "030020122076290300370300201320752903003703002005200529030837" + "0388082005200529030037038008200541c8086a20052903483703002005" + "41d0086a207b290300370300200541d8086a207c290300370300200541e0" + "086a207d290300370300200541e8086a207e290300370300200541f0086a" + "207f290300370300200541f8086a20800129030037030020052005290340" + "3703c008200541b8096a2034290300370300200541b0096a203629030037" + "0300200541a8096a2038290300370300200541a0096a203a290300370300" + "20054198096a203c29030037030020054190096a203e2903003703002005" + "4188096a200529038801370300200520052903800137038009200c203329" + "0300370300200d2032290300370300200e2031290300370300200f203029" + "03003703002010202f2903003703002011202e2903003703002005200529" + "03c8013703c809200520052903c0013703c009200541880a6a2005290388" + "06370300200541900a6a201b290300370300200541980a6a201a29030037" + "0300200541a00a6a2019290300370300200541a80a6a2018290300370300" + "200541b00a6a2017290300370300200541b80a6a20162903003703002005" + "2005290380063703800a200541f80a6a2006290300370300200541f00a6a" + "2007290300370300200541e80a6a2008290300370300200541e00a6a2009" + "290300370300200541d80a6a200a290300370300200541d00a6a200b2903" + "00370300200541c80a6a20052903c806370300200520052903c0063703c0" + "0a200020054180086a41c001104c41c0016a200541c0096a41c001104c1a" + "200541e00b6a24000ba21d02297f0d7e23004180066b2203240020034180" + "046a20014180016a22162002102f20034198036a2204200141186a220c29" + "030037030020034190036a2205200141106a220d29030037030020032001" + "41086a220f29030037038803200320012903003703800320034180036a20" + "032903800420032903880420032903900420034198046a220929030042c7" + "faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f" + "42a9c0c689aece93b230102d200341d8036a2206200141386a2210290300" + "370300200341d0036a2207200141306a2211290300370300200320014128" + "6a22122903003703c8032003200141206a22172903003703c003200341c0" + "036a20032903a004200341a8046a220a29030020032903b004200341b804" + "6a220b29030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0" + "858ce8b691a8b87f42a9c0c689aece93b230102d200341186a220e200429" + "0300370300200341106a22082005290300370300200341206a2213200329" + "03c003370300200341286a221420032903c803370300200341306a221520" + "07290300370300200341386a221820062903003703002003200329038803" + "370308200320032903800337030020034180046a2016200241406b221f10" + "2f2004200141d8006a22202903003703002005200141d0006a2221290300" + "3703002003200141c8006a22222903003703880320032001290340370380" + "0320034180036a2003290380042003290388042003290390042009290300" + "42c7faf3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8" + "b87f42a9c0c689aece93b230102d2006200141f8006a2223290300370300" + "2007200141f0006a22242903003703002003200141e8006a222529030037" + "03c8032003200141e0006a22262903003703c003200341c0036a20032903" + "a004200a29030020032903b004200b29030042c7faf3c3ed82a3903c428d" + "95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230" + "102d200341d8006a22192004290300370300200341d0006a221a20052903" + "00370300200341e0006a221b20032903c003370300200341e8006a221c20" + "032903c803370300200341f0006a221d2007290300370300200341f8006a" + "221e20062903003703002003200329038803370348200320032903800337" + "0340200341f8046a2018290300370300200341f0046a2015290300370300" + "200341e8046a2014290300370300200341e0046a20132903003703002003" + "41d8046a200e290300370300200341d0046a200829030037030020032003" + "2903083703c804200320032903003703c004200341c0046a20032003102f" + "200341b8056a201e290300370300200341b0056a201d2903003703002003" + "41a8056a201c290300370300200341a0056a201b29030037030020034198" + "056a201929030037030020034190056a201a290300370300200320032903" + "4837038805200320032903403703800520034180056a200341406b200341" + "406b102f20034180016a2003200341c0046a102f200341c0016a20012003" + "41c0046a102f20034180046a201620034180056a102f200341c0036a2003" + "4180046a20034180016a103020034180046a200341c0016a200341c0016a" + "1030200341d8026a220e2006290300370300200341d0026a220820072903" + "00370300200320032903c8033703c802200320032903c0033703c0022003" + "41c0026a200329038004200329038804200329039004200929030042c7fa" + "f3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42" + "a9c0c689aece93b230102d2004200341f8036a2213290300370300200520" + "0341f0036a22142903003703002003200341e8036a221529030037038803" + "200320032903e0033703800320034180036a20032903a004200a29030020" + "032903b004200b29030042c7faf3c3ed82a3903c428d95c7c396d2dac097" + "7f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d20034198026a" + "2218200e29030037030020034190026a22272008290300370300200341a8" + "026a2228200329038803370300200341b0026a2229200529030037030020" + "0341b8026a222a2004290300370300200320032903c80237038802200320" + "032903c0023703800220032003290380033703a00220034180046a200320" + "034180026a102f2010200b2903003703002011200341b0046a2210290300" + "3703002012200a2903003703002017200341a0046a222b29030037030020" + "0c2009290300370300200d20034190046a2211290300370300200f200329" + "03880437030020012003290380043703002004200341d8016a2903003703" + "002005200341d0016a290300370300200320032903c80137038803200320" + "032903c0013703800320034180036a200329038002200329038802202729" + "0300201829030042c7faf3c3ed82a3903c428d95c7c396d2dac0977f42dd" + "b0858ce8b691a8b87f42a9c0c689aece93b230102d2006200341f8016a29" + "03003703002007200341f0016a2903003703002003200341e8016a290300" + "3703c803200320032903e0013703c003200341c0036a20032903a0022028" + "2903002029290300202a29030042c7faf3c3ed82a3903c428d95c7c396d2" + "dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d200920" + "0429030037030020112005290300370300200a20032903c8033703002010" + "2007290300370300200b2006290300370300200320032903880337038804" + "200320032903800337038004200320032903c0033703a004200341c0036a" + "200341406b20034180046a102f20034180046a20034180016a200141406b" + "102f200341f8056a220c2006290300370300200341f0056a220d20072903" + "00370300200320032903c8033703e805200320032903c0033703e0052003" + "41e0056a200329038004200329038804200329039004200929030042c7fa" + "f3c3ed82a3903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42" + "a9c0c689aece93b230102d200e2013290300370300200820142903003703" + "00200320152903003703c802200320032903e0033703c002200341c0026a" + "20032903a004200a29030020032903b004200b29030042c7faf3c3ed82a3" + "903c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689ae" + "ce93b230102d2004200c2903003703002005200d290300370300200341a0" + "036a221720032903c002370300200341a8036a220f20032903c802370300" + "200341b0036a22122008290300370300200341b8036a2208200e29030037" + "0300200320032903e80537038803200320032903e0053703800320232008" + "290300370300202420122903003703002025200f29030037030020262017" + "290300370300202020042903003703002021200529030037030020222003" + "29038803370300200120032903800337034020034180046a201620034180" + "016a102f200141b8016a200b290300370300200141b0016a201029030037" + "0300200141a8016a200a290300370300200141a0016a202b290300370300" + "20014198016a200929030037030020014190016a20112903003703002001" + "4188016a2003290388043703002001200329038004370380012003420037" + "03f802200342003703f002200342003703e802200342013703e002200342" + "003703d802200342003703d002200342003703c802200342093703c00220" + "0341c0036a200341406b2002102f20034180046a2003201f102f200341d8" + "056a22012006290300370300200341d0056a220620072903003703002003" + "20032903c8033703c805200320032903c0033703c005200341c0056a2003" + "29038004200329038804200329039004200929030042c7faf3c3ed82a390" + "3c428d95c7c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece" + "93b230102d200c2013290300370300200d20142903003703002003201529" + "03003703e805200320032903e0033703e005200341e0056a20032903a004" + "200a29030020032903b004200b29030042c7faf3c3ed82a3903c428d95c7" + "c396d2dac0977f42ddb0858ce8b691a8b87f42a9c0c689aece93b230102d" + "2004200129030037030020052006290300370300200f20032903e8053703" + "002012200d2903003703002008200c290300370300200320032903c80537" + "038803200320032903c00537038003200320032903e0053703a003200341" + "80046a200341c0026a20034180036a102f201e2903002136201d29030021" + "34201c290300212d201b2903002135201a29030022302003290340223184" + "201929030022382003290348223284844200520440427f4200427f420020" + "3142788342c7faf3c3ed82a3903c561b222e202e203254ad7d202e20327d" + "222e42f3eab8bce9ada5bfe8007d2237202e54ad7c42017c223320307d22" + "2f42a4cffaf397c9eed7c7007d222e202f54ad2030203356ad7d427f511b" + "20387d42a9c0c689aece93b2307c213342c7faf3c3ed82a3903c20317d21" + "2f0b4200213042002131420021322034203584202d203684844200520440" + "427f4200427f4200203542788342c7faf3c3ed82a3903c561b222c202c20" + "2d54ad7d202c202d7d222d42f3eab8bce9ada5bfe8007d2230202d54ad7c" + "42017c222d20347d222c42a4cffaf397c9eed7c7007d2231202c54ad202d" + "203454ad7d427f511b20367d42a9c0c689aece93b2307c213242c7faf3c3" + "ed82a3903c20357d212c0b20002003290380043703002000200329030037" + "0340200041086a200329038804370300200041c8006a2003290308370300" + "200041386a200341b8046a290300370300200041306a200341b0046a2903" + "00370300200041286a200341a8046a290300370300200041206a200341a0" + "046a290300370300200041186a20034198046a290300370300200041106a" + "20034190046a290300370300200041d0006a200341106a29030037030020" + "0041d8006a200341186a290300370300200041e0006a200341206a290300" + "370300200041e8006a200341286a290300370300200041f0006a20034130" + "6a290300370300200041f8006a200341386a290300370300200020323703" + "b801200020313703b001200020303703a8012000202c3703a00120002033" + "370398012000202e3703900120002037370388012000202f370380012003" + "4180066a24000b4201047f412021020240034020002d0000220320012d00" + "002204460440200041016a2100200141016a2101200241016b22020d010c" + "020b0b200320046b21050b20050b8a0301047f0240200141104904402000" + "21020c010b02402000410020006b41037122046a220320004d0d00200021" + "0220040440200421050340200241003a0000200241016a2102200541016b" + "22050d000b0b200441016b4107490d000340200241003a0000200241076a" + "41003a0000200241066a41003a0000200241056a41003a0000200241046a" + "41003a0000200241036a41003a0000200241026a41003a0000200241016a" + "41003a0000200241086a22022003470d000b0b2003200120046b2201417c" + "716a220220034b0440034020034100360200200341046a22032002490d00" + "0b0b200141037121010b02402002200120026a22054f0d00200141016b21" + "042001410771220304400340200241003a0000200241016a210220034101" + "6b22030d000b0b20044107490d000340200241003a0000200241076a4100" + "3a0000200241066a41003a0000200241056a41003a0000200241046a4100" + "3a0000200241036a41003a0000200241026a41003a0000200241016a4100" + "3a0000200241086a22022005470d000b0b20000b940501087f0240200241" + "10490440200021030c010b02402000410020006b41037122066a22052000" + "4d0d00200641016b21082000210320012104200604402006210703402003" + "20042d00003a0000200441016a2104200341016a2103200741016b22070d" + "000b0b20084107490d000340200320042d00003a0000200341016a200441" + "016a2d00003a0000200341026a200441026a2d00003a0000200341036a20" + "0441036a2d00003a0000200341046a200441046a2d00003a000020034105" + "6a200441056a2d00003a0000200341066a200441066a2d00003a00002003" + "41076a200441076a2d00003a0000200441086a2104200341086a22032005" + "470d000b0b2005200220066b2207417c7122086a21030240200120066a22" + "04410371450440200320054d0d0120042101034020052001280200360200" + "200141046a2101200541046a22052003490d000b0c010b200320054d0d00" + "2004410374220241187121062004417c71220941046a2101410020026b41" + "1871210a2009280200210203402005200220067620012802002202200a74" + "72360200200141046a2101200541046a22052003490d000b0b2007410371" + "2102200420086a21010b02402003200220036a22054f0d00200241016b21" + "072002410771220404400340200320012d00003a0000200141016a210120" + "0341016a2103200441016b22040d000b0b20074107490d00034020032001" + "2d00003a0000200341016a200141016a2d00003a0000200341026a200141" + "026a2d00003a0000200341036a200141036a2d00003a0000200341046a20" + "0141046a2d00003a0000200341056a200141056a2d00003a000020034106" + "6a200141066a2d00003a0000200341076a200141076a2d00003a00002001" + "41086a2101200341086a22032005470d000b0b20000b6201047e20002002" + "42ffffffff0f832203200142ffffffff0f8322047e220520024220882202" + "20047e22042003200142208822017e7c22034220867c2206370300200020" + "05200656ad200120027e2003200454ad4220862003422088847c7c370308" + "0b5601017e0240200341c000714504402003450d012002410020036b413f" + "71ad8620012003413f71ad220488842101200220048821020c010b200220" + "03413f71ad882101420021020b20002001370300200020023703080b5a01" + "027e420121020240200141c000714504402001450d0142002001413f71ad" + "2202864201410020016b413f71ad88842103420120028621020c010b4201" + "2001413f71ad862103420021020b20002002370300200020033703080b0b" + "e1250100418080c0000bd725307830306165613865396338336337336437" + "343033363932336465316234613636643138353437643538656565346561" + "6366656537303233356564323931393534636361706163697479206f7665" + "72666c6f77004200100011000000010000000000000063616c6c65642060" + "4f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e656020" + "76616c7565696e646578206f7574206f6620626f756e64733a2074686520" + "6c656e20697320206275742074686520696e646578206973200000008f00" + "100020000000af001000120000003a2000000100000000000000d4001000" + "020000003030303130323033303430353036303730383039313031313132" + "313331343135313631373138313932303231323232333234323532363237" + "323832393330333133323333333433353336333733383339343034313432" + "343334343435343634373438343935303531353235333534353535363537" + "353835393630363136323633363436353636363736383639373037313732" + "373337343735373637373738373938303831383238333834383538363837" + "38383839393039313932393339343935393639373938393972616e676520" + "737461727420696e64657820206f7574206f662072616e676520666f7220" + "736c696365206f66206c656e67746820b001100012000000c20110002200" + "000072616e676520656e6420696e64657820f401100010000000c2011000" + "22000000736c69636520696e646578207374617274732061742020627574" + "20656e6473206174200014021000160000002a0210000d00000054726965" + "6420746f20736872696e6b20746f2061206c617267657220636170616369" + "74794802100024000000f40a10004c000000b3020000090000002f686f6d" + "652f6f706964736b6f706e79692f2e636172676f2f72656769737472792f" + "7372632f696e6465782e6372617465732e696f2d31393439636638633662" + "3562353537662f6e756d2d626967696e742d302e342e362f7372632f6269" + "6775696e742e72732f686f6d652f6f706964736b6f706e79692f2e636172" + "676f2f72656769737472792f7372632f696e6465782e6372617465732e69" + "6f2d313934396366386336623562353537662f6e756d2d626967696e742d" + "302e342e362f7372632f62696775696e742f6164646974696f6e2e727300" + "0000ea0210006f000000890000001b000000a80c10006f00000057000000" + "09000000a80c10006f000000a3000000090000008402100066000000ad00" + "000013000000a80c10006f000000c40000001f000000a80c10006f000000" + "150100000e000000a80c10006f000000160100000e000000a80c10006f00" + "00001a0100000f000000a80c10006f000000510100000c000000a80c1000" + "6f0000002001000021000000a80c10006f0000002101000018000000a80c" + "10006f000000420100003c000000040c10006e0000006d0200000d000000" + "040c10006e00000066020000110000002f686f6d652f6f706964736b6f70" + "6e79692f2e636172676f2f72656769737472792f7372632f696e6465782e" + "6372617465732e696f2d313934396366386336623562353537662f6e756d" + "2d626967696e742d302e342e362f7372632f62696775696e742f73686966" + "742e72733c0410006c0000001e0000001c0000003c0410006c0000002e00" + "0000120000003c0410006c00000028000000190000002f72757374632f34" + "656231363132353065333430633866343866363665326239323965663461" + "3562656437633138312f6c6962726172792f636f72652f7372632f736c69" + "63652f697465722e72732f686f6d652f6f706964736b6f706e79692f2e63" + "6172676f2f72656769737472792f7372632f696e6465782e637261746573" + "2e696f2d313934396366386336623562353537662f6865782d302e342e33" + "2f7372632f6c69622e7273000000260510005b000000c700000025000000" + "260510005b000000c7000000410000004e6f744d656d626572496e76616c" + "6964536c6963654c656e677468496e76616c696455353132456e636f6469" + "6e6700000000000067e6096a85ae67bb72f36e3c3af54fa57f520e518c68" + "059babd9831f19cde05bd80410004e000000f605000015000000496e7661" + "6c696420636f6d7072657373656420706f696e7420666c61670000000806" + "10001d0000002f686f6d652f6f706964736b6f706e79692f2e636172676f" + "2f72656769737472792f7372632f696e6465782e6372617465732e696f2d" + "313934396366386336623562353537662f7370312d76657269666965722d" + "342e312e332f7372632f636f6e7374616e74732e72730000300610006a00" + "00001f000000120000002f686f6d652f6f706964736b6f706e79692f2e63" + "6172676f2f72656769737472792f7372632f696e6465782e637261746573" + "2e696f2d313934396366386336623562353537662f7370312d7665726966" + "6965722d342e312e332f7372632f636f6e7665727465722e727300000000" + "00000100000001000000060000004661696c656420746f20636f6e766572" + "74207820627974657320746f20467100ac0610006a0000001f0000003700" + "00002f686f6d652f6f706964736b6f706e79692f2e636172676f2f726567" + "69737472792f7372632f696e6465782e6372617465732e696f2d31393439" + "6366386336623562353537662f7370312d76657269666965722d342e312e" + "332f7372632f67726f746831362f636f6e7665727465722e727300005807" + "100072000000290000003e00000058071000720000002a0000003d000000" + "58071000720000002b0000003e00000058071000720000002c0000003e00" + "000058071000720000002e0000002500000058071000720000002e000000" + "3200000058071000720000002e0000003f00000058071000720000002e00" + "00004c0000005807100072000000320000003f0000005807100072000000" + "330000000b0000002f686f6d652f6f706964736b6f706e79692f2e636172" + "676f2f72656769737472792f7372632f696e6465782e6372617465732e69" + "6f2d313934396366386336623562353537662f7370312d76657269666965" + "722d342e312e332f7372632f67726f746831362f7665726966792e727300" + "6c0810006f0000002d000000160000002f686f6d652f6f706964736b6f70" + "6e79692f2e636172676f2f72656769737472792f7372632f696e6465782e" + "6372617465732e696f2d313934396366386336623562353537662f737031" + "2d76657269666965722d342e312e332f7372632f67726f746831362f6d6f" + "642e7273ec0810006c0000006d00000044000000ad4d9aa7e302d9df4174" + "9d5507949d05dbea33fbb16c643b22f599a2be6df2e2e1a1575c2e494d36" + "13e95e43b622318d9225c820e46acd08e8c987b44051195bc967032fcbf7" + "76d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c0e187847" + "ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab998e" + "9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" + "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992" + "f6edc980d3486a83b99e6c876acec4d309746e28cd96fa8e01864daa8459" + "9384f354a62eabe81511aa8e3034cbd75d42e708aa4ed80303fb0e4fb90c" + "d0ff6e9092132b65c9ae2605f3ef5540d3a64503c84fe5e1d9ec6eb1bd3a" + "906bbc80830e8e5400000003ced6e0c13f353262ae2dbbe49ce6a0b67576" + "d38aaf5958564be7648356830ef7db611b8f696f28ffb6250c7ffac66efb" + "d638d97f0d6c843c23691c3af532c9e3a974086bde6c91267b201137cfe6" + "ee8cd50ff0a3da861e808503e7df4da87b8d00000000000000002f727573" + "74632f346562313631323530653334306338663438663636653262393239" + "656634613562656437633138312f6c6962726172792f616c6c6f632f7372" + "632f7261775f7665632e7273f40a10004c00000028020000110000002f72" + "7573742f646570732f646c6d616c6c6f632d302e322e372f7372632f646c" + "6d616c6c6f632e7273617373657274696f6e206661696c65643a20707369" + "7a65203e3d2073697a65202b206d696e5f6f7665726865616400500b1000" + "29000000a804000009000000617373657274696f6e206661696c65643a20" + "7073697a65203c3d2073697a65202b206d61785f6f766572686561640000" + "500b100029000000ae0400000d0000000000000004000000000000002f68" + "6f6d652f6f706964736b6f706e79692f2e636172676f2f72656769737472" + "792f7372632f696e6465782e6372617465732e696f2d3139343963663863" + "36623562353537662f6e756d2d626967696e742d302e342e362f7372632f" + "62696775696e742f636f6e766572742e72730000040c10006e000000f001" + "000016000000617474656d707420746f20646976696465206279207a6572" + "6f000000840c1000190000002f686f6d652f6f706964736b6f706e79692f" + "2e636172676f2f72656769737472792f7372632f696e6465782e63726174" + "65732e696f2d313934396366386336623562353537662f6e756d2d626967" + "696e742d302e342e362f7372632f62696775696e742f6469766973696f6e" + "2e727300a80c10006f00000070000000090000004f6e63652070616e6963" + "6b65642f686f6d652f6f706964736b6f706e79692f2e636172676f2f7265" + "6769737472792f7372632f696e6465782e6372617465732e696f2d313934" + "396366386336623562353537662f7370696e2d302e392e382f7372632f6f" + "6e63652e72730000350d10005d000000e60000002a0000004f6e63652070" + "726576696f75736c7920706f69736f6e656420627920612070616e69636b" + "65640000350d10005d0000004e010000250000002f72757374632f346562" + "313631323530653334306338663438663636653262393239656634613562" + "656437633138312f6c6962726172792f616c6c6f632f7372632f736c6963" + "652e72730000dc0d10004a000000a10000001900000063616c6c65642060" + "526573756c743a3a756e77726170282960206f6e20616e20604572726020" + "76616c75652f686f6d652f6f706964736b6f706e79692f2e636172676f2f" + "72656769737472792f7372632f696e6465782e6372617465732e696f2d31" + "3934396366386336623562353537662f7375627374726174652d626e2d73" + "756363696e63742d302e362e302d76342d72632e382f7372632f6669656c" + "64732f66702e72730000630e10007b000000e9020000230000004661696c" + "656420746f20636f6d707574652074686520696e7665727365206f662074" + "68652064697669736f722f686f6d652f6f706964736b6f706e79692f2e63" + "6172676f2f72656769737472792f7372632f696e6465782e637261746573" + "2e696f2d313934396366386336623562353537662f737562737472617465" + "2d626e2d73756363696e63742d302e362e302d76342d72632e382f737263" + "2f6669656c64732f6671322e72731c0f10007c000000430100000e000000" + "000000000100000001000000070000002f686f6d652f6f706964736b6f70" + "6e79692f2e636172676f2f72656769737472792f7372632f696e6465782e" + "6372617465732e696f2d313934396366386336623562353537662f737562" + "7374726174652d626e2d73756363696e63742d302e362e302d76342d7263" + "2e382f7372632f67726f7570732f6d6f642e7273b80f10007c000000b100" + "00002c000000556e61626c6520746f20636f6e7665727420473120746f20" + "416666696e654731b80f10007c0000000001000012000000b80f10007c00" + "00002001000012000000b80f10007c000000400100000d000000b80f1000" + "7c0000006b01000029000000010001000000030003000000030001000300" + "000300000000000100000300010000030000000003000100000003000300" + "00010000000300000300010001000000b80f10007c000000150300002600" + "0000b80f10007c0000001003000026000000b80f10007c00000008030000" + "2e000000b80f10007c000000020300002a000000b80f10007c0000009b03" + "000010000000b80f10007c0000009c03000010000000b80f10007c000000" + "8f03000014000000b80f10007c0000009203000018000000b80f10007c00" + "000095030000180000006d696c6c6572206c6f6f702063616e6e6f742070" + "726f64756365207a65726f00b80f10007c000000221100000a000000b80f" + "10007c000000191100002a000000b80f10007c0000001911000017000000" + "b80f10007c0000001a1100002e000000b80f10007c0000001a1100001b00" + "00002f686f6d652f6f706964736b6f706e79692f2e636172676f2f726567" + "69737472792f7372632f696e6465782e6372617465732e696f2d31393439" + "6366386336623562353537662f7375627374726174652d626e2d73756363" + "696e63742d302e362e302d76342d72632e382f7372632f6c69622e727300" + "0000e4111000750000003b0300000c000000e4111000750000003c030000" + "0c0000004e6f744f6e43757276654e6f74496e53756267726f7570496e76" + "616c6964496e7075744c656e677468000000120000001300000009000000" + "ad051000bf051000a40510000a0000000d000000120000007c1210008612" + "1000931210004d0970726f64756365727302086c616e6775616765010452" + "757374000c70726f6365737365642d6279010572757374631d312e38352e" + "31202834656231363132353020323032352d30332d31352900490f746172" + "6765745f6665617475726573042b0f6d757461626c652d676c6f62616c73" + "2b087369676e2d6578742b0f7265666572656e63652d74797065732b0a6d" + "756c746976616c7565"; + +extern std::string const ledgerSqnWasmHex = + "0061736d010000000108026000017f60000002160103656e760e6765745f6c65646765725f" + "73716e000003030201000503010002063e0a7f004180080b7f004180080b7f004180100b7f" + "004180100b7f00418090040b7f004180080b7f00418090040b7f00418080080b7f0041000b" + "7f0041010b07b0010d066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300" + "010666696e69736800020362756603000c5f5f64736f5f68616e646c6503010a5f5f646174" + "615f656e6403020b5f5f737461636b5f6c6f7703030c5f5f737461636b5f6869676803040d" + "5f5f676c6f62616c5f6261736503050b5f5f686561705f6261736503060a5f5f686561705f" + "656e6403070d5f5f6d656d6f72795f6261736503080c5f5f7461626c655f6261736503090a" + "150202000b1001017f100022004100200041044b1b0b007f0970726f647563657273010c70" + "726f6365737365642d62790105636c616e675f31392e312e352d776173692d73646b202868" + "747470733a2f2f6769746875622e636f6d2f6c6c766d2f6c6c766d2d70726f6a6563742061" + "62346235613264623538323935386166316565333038613739306366646234326264323437" + "32302900490f7461726765745f6665617475726573042b0f6d757461626c652d676c6f6261" + "6c732b087369676e2d6578742b0f7265666572656e63652d74797065732b0a6d756c746976" + "616c7565"; + +extern std::string const allHostFunctionsWasmHex = + "0061736d0100000001540c60047f7f7f7f017f60027f7f017f60037f7f7f017f60057f7f7f" + "7f7f017f6000017f60017f017f60037f7f7f0060037f7f7e017f60087f7f7f7f7f7f7f7f01" + "7f60067f7f7f7f7f7f017f60017f0060027f7f0002ae061a08686f73745f6c69620c676574" + "5f74785f6669656c64000208686f73745f6c69620974726163655f6e756d000708686f7374" + "5f6c6962057472616365000308686f73745f6c69620e6765745f6c65646765725f73716e00" + "0408686f73745f6c6962166765745f706172656e745f6c65646765725f74696d6500040868" + "6f73745f6c6962166765745f706172656e745f6c65646765725f68617368000108686f7374" + "5f6c69620d74726163655f6163636f756e74000008686f73745f6c6962136765745f74785f" + "6e65737465645f6669656c64000008686f73745f6c6962106765745f74785f61727261795f" + "6c656e000508686f73745f6c6962176765745f74785f6e65737465645f61727261795f6c65" + "6e000108686f73745f6c69621c6765745f63757272656e745f6c65646765725f6f626a5f66" + "69656c64000208686f73745f6c6962236765745f63757272656e745f6c65646765725f6f62" + "6a5f6e65737465645f6669656c64000008686f73745f6c6962206765745f63757272656e74" + "5f6c65646765725f6f626a5f61727261795f6c656e000508686f73745f6c6962276765745f" + "63757272656e745f6c65646765725f6f626a5f6e65737465645f61727261795f6c656e0001" + "08686f73745f6c69620e6163636f756e745f6b65796c6574000008686f73745f6c69621063" + "616368655f6c65646765725f6f626a000208686f73745f6c6962146765745f6c6564676572" + "5f6f626a5f6669656c64000008686f73745f6c69621b6765745f6c65646765725f6f626a5f" + "6e65737465645f6669656c64000308686f73745f6c6962186765745f6c65646765725f6f62" + "6a5f61727261795f6c656e000108686f73745f6c69621f6765745f6c65646765725f6f626a" + "5f6e65737465645f61727261795f6c656e000208686f73745f6c69621163726564656e7469" + "616c5f6b65796c6574000808686f73745f6c69620d657363726f775f6b65796c6574000308" + "686f73745f6c69620d6f7261636c655f6b65796c6574000308686f73745f6c696213636f6d" + "707574655f7368613531325f68616c66000008686f73745f6c6962076765745f6e66740009" + "08686f73745f6c69620b7570646174655f64617461000103060506060a0b04050301001106" + "19037f01418080c0000b7f0041af99c0000b7f0041b099c0000b072e04066d656d6f727902" + "000666696e697368001e0a5f5f646174615f656e6403010b5f5f686561705f626173650302" + "0aff1b051900200241094f0440000b20002002360204200020013602000b1900200241214f" + "0440000b20002002360204200020013602000b970101057f230041206b2201240020014118" + "6a22044100360200200141106a220542003703002001420037030802404181802020014108" + "6a4114100022034114470440024020034100480440200020033602040c010b2000417f3602" + "040b410121020c010b20002001290308370001200041116a2004280200360000200041096a" + "20052903003700000b200020023a0000200141206a24000b460020012d0000410146044041" + "8080c000410b20013402041001000b20002001290001370000200041106a200141116a2800" + "00360000200041086a200141096a2900003700000be81901097f230041b0036b2200240041" + "8b80c000411b41004100410010021a41a680c000411941004100410010021a41e780c00041" + "2b41004100410010021a027f02400240024002400240024002401003220141004a04404192" + "81c00041172001ad10011a1004220141004c0d0141a981c00041132001ad10011a200041c8" + "016a22034200370300200041c0016a22054200370300200041b8016a220442003703002000" + "42003703b001200041b0016a22064120100522014120470d0241bc81c00041132006412041" + "0110021a41cf81c000412041004100410010021a41dc82c000412e41004100410010021a20" + "0041a0016a410036020020004198016a420037030020004200370390014181802020004190" + "016a22024114100022014114470d03418a83c00041142002411410061a2000420037037041" + "888018200041f0006a22024108100022014108470d04419e83c0004117420810011a41b583" + "c000412820024108410110021a2000410036025041848008200041d0006a22024104100022" + "014104470d0541dd83c000411520024104410110021a200041013b003c2003420037030020" + "05420037030020044200370300200042003703b00102402000413c6a410220064120100722" + "0141004e044041f283c00041142001ad10011a200041306a20062001101b418684c000410d" + "20002802302000280234410110021a0c010b419384c00041292001ac10011a0b41bc84c000" + "41154183803c1008ac10011a41d184c00041134189803c1008ac10011a02402000413c6a41" + "021009220141004e044041e484c00041142001ad10011a0c010b41f884c000412d2001ac10" + "011a0b41a585c000412341004100410010021a41de86c000413341004100410010021a2000" + "420037037041828018200041f0006a22014108100a220241004c0d06200241084604404191" + "87c000412b420810011a41bc87c000412f20014108410110021a0c080b41eb87c000412f20" + "02ad10011a200041286a200041f0006a2002101a419a88c00041172000280228200028022c" + "410110021a0c070b41bf82c000411d2001ac10011a419b7f0c070b419a82c00041252001ac" + "10011a419a7f0c060b41ef81c000412b2001ac10011a41997f0c050b41b486c000412a2001" + "ac10011a41b77e0c040b41f385c00041c1002001ac10011a41b67e0c030b41c885c000412b" + "2001ac10011a41b57e0c020b41b188c00041c5002002ac10011a0b200041a0016a41003602" + "0020004198016a4200370300200042003703900102404181802020004190016a2202411410" + "0a220141004a044041f688c000411e2002411410061a0c010b419489c00041332001ac1001" + "1a0b200041013b0050200041c8016a4200370300200041c0016a4200370300200041b8016a" + "4200370300200042003703b0010240200041d0006a4102200041b0016a22014120100b2202" + "41004e044041c789c000411c2002ad10011a200041206a20012002101b41e389c000411520" + "002802202000280224410110021a0c010b41f889c00041392002ac10011a0b41b18ac00041" + "244183803c100cac10011a0240200041d0006a4102100d220141004e044041d58ac000411c" + "2001ad10011a0c010b41f18ac000413d2001ac10011a0b41ae8bc000412841004100410010" + "021a41d68bc000412f41004100410010021a200041b0016a2202101c200041f0006a220120" + "02101d200041a8016a4200370300200041a0016a420037030020004198016a420037030020" + "00420037039001024002400240024002402001411420004190016a22024120100e22014120" + "460440200241204100100f220441004a044041858cc00041232004ad10011a200042003703" + "50200441828018200041d0006a220141081010220241004c0d022002410846044041a88cc0" + "00412a420810011a41d28cc000412e20014108410110021a0c060b41808dc000412e2002ad" + "10011a200041186a200041d0006a2002101a41ae8dc00041162000280218200028021c4101" + "10021a0c050b41e68fc000413c2004ac10011a200041c8016a4200370300200041c0016a42" + "00370300200041b8016a4200370300200042003703b001410141828018200041b0016a4120" + "101022014100480d020c030b41ba92c000412e2001ac10011a41ef7c0c050b41c48dc00041" + "2b2002ac10011a0c020b41a290c00041c1002001ac10011a0b200041013b00504101200041" + "d0006a4102200041b0016a412010112201410048044041e390c00041352001ac10011a0b41" + "014183803c101222014100480440419891c00041322001ac10011a0b4101200041d0006a41" + "0210132201410048044041ca91c00041392001ac10011a0b418392c0004137410041004100" + "10021a0c010b200041013b003c200041c8016a4200370300200041c0016a42003703002000" + "41b8016a4200370300200042003703b001024020042000413c6a4102200041b0016a220141" + "201011220241004e044041ef8dc000411b2002ad10011a200041106a20012002101b418a8e" + "c000411420002802102000280214410110021a0c010b419e8ec00041312002ac10011a0b41" + "cf8ec000412320044183803c1012ac10011a024020042000413c6a41021013220141004e04" + "4041f28ec000411b2001ad10011a0c010b418d8fc00041352001ac10011a0b41c28fc00041" + "2441004100410010021a0b41e892c000412f41004100410010021a200041b0016a2201101c" + "2000413c6a22042001101d200041e8006a4200370300200041e0006a4200370300200041d8" + "006a4200370300200042003703500240024002400240024020044114200041d0006a220241" + "20100e22014120460440419793c000410f20024120410110021a20004188016a4200370300" + "20004180016a4200370300200041f8006a4200370300200042003703700240200441142004" + "411441a693c0004109200041f0006a220141201014220241004a0440200041086a20012002" + "101b41ae93c00041122000280208200028020c410110021a0c010b41c093c000413c2002ac" + "10011a0b200041a8016a22084200370300200041a0016a2203420037030020004198016a22" + "05420037030020004200370390012000413c6a2202411441e80720004190016a2207412010" + "1522014120470d0141fc93c000410e20074120410110021a200041c8016a42003703002000" + "41c0016a4200370300200041b8016a4200370300200042003703b00120024114412a200041" + "b0016a22044120101622014120470d02418a94c000410e20044120410110021a419894c000" + "412441004100410010021a419195c000412541004100410010021a20004188016a42003703" + "0020004180016a4200370300200041f8006a42003703002000420037037041b695c0004117" + "200041f0006a22024120101722014120470d0341cd95c000410b41b695c000411741011002" + "1a41d895c000411120024120410110021a2004101c200041d0006a22062004101d20084200" + "3703002003420037030020054200370300200042003703900102404100200422036b410371" + "220220036a220520034d0d0020020440200221010340200341003a0000200341016a210320" + "0141016b22010d000b0b200241016b4107490d000340200341003a0000200341076a41003a" + "0000200341066a41003a0000200341056a41003a0000200341046a41003a0000200341036a" + "41003a0000200341026a41003a0000200341016a41003a0000200341086a22032005470d00" + "0b0b200541800220026b2201417c716a220320054b0440034020054100360200200541046a" + "22052003490d000b0b024020032001410371220120036a22024f0d00200122050440034020" + "0341003a0000200341016a2103200541016b22050d000b0b200141016b4107490d00034020" + "0341003a0000200341076a41003a0000200341066a41003a0000200341056a41003a000020" + "0341046a41003a0000200341036a41003a0000200341026a41003a0000200341016a41003a" + "0000200341086a22032002470d000b0b024020064114200741202004418002101822014100" + "4a044041e995c00041102001ad10011a20014181024f0d0641f995c0004109200420014101" + "10021a0c010b418296c000412e2001ac10011a0b41b096c000411241c296c0004107410110" + "0222014100480d0541c996c000411d2001ad10011a41e696c0004111422a10014100480440" + "41ad97c000411a42a47b10011a41a47b0c070b41f796c000411c420010011a419397c00041" + "1a41004100410010021a41ff97c000412941004100410010021a41a898c000412810192201" + "45044041d098c000412741a898c0004128410110021a41f798c000411e4100410041001002" + "1a41bf80c000412841004100410010021a41010c070b419599c000411a2001ac10011a41c3" + "7a0c060b41f494c000411d2001ac10011a418b7c0c050b41d894c000411c2001ac10011a41" + "897c0c040b41bc94c000411c2001ac10011a41887c0c030b41dd97c00041222001ac10011a" + "41a77b0c020b000b41c797c00041162001ac10011a41a57b0b200041b0036a24000b0bb919" + "0100418080c0000baf196572726f725f636f64653d3d3d3d20484f53542046554e4354494f" + "4e532054455354203d3d3d54657374696e6720323620686f73742066756e6374696f6e7353" + "5543434553533a20416c6c20686f73742066756e6374696f6e207465737473207061737365" + "64212d2d2d2043617465676f727920313a204c6564676572204865616465722046756e6374" + "696f6e73202d2d2d4c65646765722073657175656e6365206e756d6265723a506172656e74" + "206c65646765722074696d653a506172656e74206c656467657220686173683a5355434345" + "53533a204c6564676572206865616465722066756e6374696f6e734552524f523a20676574" + "5f706172656e745f6c65646765725f686173682077726f6e67206c656e6774683a4552524f" + "523a206765745f706172656e745f6c65646765725f74696d65206661696c65643a4552524f" + "523a206765745f6c65646765725f73716e206661696c65643a2d2d2d2043617465676f7279" + "20323a205472616e73616374696f6e20446174612046756e6374696f6e73202d2d2d547261" + "6e73616374696f6e204163636f756e743a5472616e73616374696f6e20466565206c656e67" + "74683a5472616e73616374696f6e20466565202873657269616c697a65642058525020616d" + "6f756e74293a5472616e73616374696f6e2053657175656e63653a4e657374656420666965" + "6c64206c656e6774683a4e6573746564206669656c643a494e464f3a206765745f74785f6e" + "65737465645f6669656c64206e6f74206170706c696361626c653a5369676e657273206172" + "726179206c656e6774683a4d656d6f73206172726179206c656e6774683a4e657374656420" + "6172726179206c656e6774683a494e464f3a206765745f74785f6e65737465645f61727261" + "795f6c656e206e6f74206170706c696361626c653a535543434553533a205472616e736163" + "74696f6e20646174612066756e6374696f6e734552524f523a206765745f74785f6669656c" + "642853657175656e6365292077726f6e67206c656e6774683a4552524f523a206765745f74" + "785f6669656c6428466565292077726f6e67206c656e677468202865787065637465642038" + "20627974657320666f7220585250293a4552524f523a206765745f74785f6669656c642841" + "63636f756e74292077726f6e67206c656e6774683a2d2d2d2043617465676f727920333a20" + "43757272656e74204c6564676572204f626a6563742046756e6374696f6e73202d2d2d4375" + "7272656e74206f626a6563742062616c616e6365206c656e677468202858525020616d6f75" + "6e74293a43757272656e74206f626a6563742062616c616e6365202873657269616c697a65" + "642058525020616d6f756e74293a43757272656e74206f626a6563742062616c616e636520" + "6c656e67746820286e6f6e2d58525020616d6f756e74293a43757272656e74206f626a6563" + "742062616c616e63653a494e464f3a206765745f63757272656e745f6c65646765725f6f62" + "6a5f6669656c642842616c616e636529206661696c656420286d6179206265206578706563" + "746564293a43757272656e74206c6564676572206f626a656374206163636f756e743a494e" + "464f3a206765745f63757272656e745f6c65646765725f6f626a5f6669656c64284163636f" + "756e7429206661696c65643a43757272656e74206e6573746564206669656c64206c656e67" + "74683a43757272656e74206e6573746564206669656c643a494e464f3a206765745f637572" + "72656e745f6c65646765725f6f626a5f6e65737465645f6669656c64206e6f74206170706c" + "696361626c653a43757272656e74206f626a656374205369676e657273206172726179206c" + "656e6774683a43757272656e74206e6573746564206172726179206c656e6774683a494e46" + "4f3a206765745f63757272656e745f6c65646765725f6f626a5f6e65737465645f61727261" + "795f6c656e206e6f74206170706c696361626c653a535543434553533a2043757272656e74" + "206c6564676572206f626a6563742066756e6374696f6e732d2d2d2043617465676f727920" + "343a20416e79204c6564676572204f626a6563742046756e6374696f6e73202d2d2d537563" + "6365737366756c6c7920636163686564206f626a65637420696e20736c6f743a4361636865" + "64206f626a6563742062616c616e6365206c656e677468202858525020616d6f756e74293a" + "436163686564206f626a6563742062616c616e6365202873657269616c697a656420585250" + "20616d6f756e74293a436163686564206f626a6563742062616c616e6365206c656e677468" + "20286e6f6e2d58525020616d6f756e74293a436163686564206f626a6563742062616c616e" + "63653a494e464f3a206765745f6c65646765725f6f626a5f6669656c642842616c616e6365" + "29206661696c65643a436163686564206e6573746564206669656c64206c656e6774683a43" + "6163686564206e6573746564206669656c643a494e464f3a206765745f6c65646765725f6f" + "626a5f6e65737465645f6669656c64206e6f74206170706c696361626c653a436163686564" + "206f626a656374205369676e657273206172726179206c656e6774683a436163686564206e" + "6573746564206172726179206c656e6774683a494e464f3a206765745f6c65646765725f6f" + "626a5f6e65737465645f61727261795f6c656e206e6f74206170706c696361626c653a5355" + "43434553533a20416e79206c6564676572206f626a6563742066756e6374696f6e73494e46" + "4f3a2063616368655f6c65646765725f6f626a206661696c65642028657870656374656420" + "776974682074657374206669787475726573293a494e464f3a206765745f6c65646765725f" + "6f626a5f6669656c64206661696c656420617320657870656374656420286e6f2063616368" + "6564206f626a656374293a494e464f3a206765745f6c65646765725f6f626a5f6e65737465" + "645f6669656c64206661696c65642061732065787065637465643a494e464f3a206765745f" + "6c65646765725f6f626a5f61727261795f6c656e206661696c656420617320657870656374" + "65643a494e464f3a206765745f6c65646765725f6f626a5f6e65737465645f61727261795f" + "6c656e206661696c65642061732065787065637465643a535543434553533a20416e79206c" + "6564676572206f626a6563742066756e6374696f6e732028696e7465726661636520746573" + "746564294552524f523a206163636f756e745f6b65796c6574206661696c656420666f7220" + "63616368696e6720746573743a2d2d2d2043617465676f727920353a204b65796c65742047" + "656e65726174696f6e2046756e6374696f6e73202d2d2d4163636f756e74206b65796c6574" + "3a546573745479706543726564656e7469616c206b65796c65743a494e464f3a2063726564" + "656e7469616c5f6b65796c6574206661696c656420286578706563746564202d20696e7465" + "7266616365206973737565293a457363726f77206b65796c65743a4f7261636c65206b6579" + "6c65743a535543434553533a204b65796c65742067656e65726174696f6e2066756e637469" + "6f6e734552524f523a206f7261636c655f6b65796c6574206661696c65643a4552524f523a" + "20657363726f775f6b65796c6574206661696c65643a4552524f523a206163636f756e745f" + "6b65796c6574206661696c65643a2d2d2d2043617465676f727920363a205574696c697479" + "2046756e6374696f6e73202d2d2d48656c6c6f2c205852504c205741534d20776f726c6421" + "496e70757420646174613a5348413531322068616c6620686173683a4e4654206461746120" + "6c656e6774683a4e465420646174613a494e464f3a206765745f6e6674206661696c656420" + "286578706563746564202d206e6f2073756368204e4654293a54657374207472616365206d" + "6573736167657061796c6f616454726163652066756e6374696f6e20627974657320777269" + "7474656e3a54657374206e756d62657220747261636554726163655f6e756d2066756e6374" + "696f6e20737563636565646564535543434553533a205574696c6974792066756e6374696f" + "6e734552524f523a2074726163655f6e756d2829206661696c65643a4552524f523a207472" + "6163652829206661696c65643a4552524f523a20636f6d707574655f7368613531325f6861" + "6c66206661696c65643a2d2d2d2043617465676f727920373a204461746120557064617465" + "2046756e6374696f6e73202d2d2d55706461746564206c656467657220656e747279206461" + "74612066726f6d205741534d20746573745375636365737366756c6c792075706461746564" + "206c656467657220656e74727920776974683a535543434553533a20446174612075706461" + "74652066756e6374696f6e734552524f523a207570646174655f64617461206661696c6564" + "3a004d0970726f64756365727302086c616e6775616765010452757374000c70726f636573" + "7365642d6279010572757374631d312e39302e30202831313539653738633420323032352d" + "30392d313429002c0f7461726765745f6665617475726573022b0f6d757461626c652d676c" + "6f62616c732b087369676e2d657874"; + +extern std::string const deepRecursionHex = + "0061736d01000000013f0b60017f0060037f7f7f017f60027f7f017f60027f" + "7f0060000060037f7f7f006000017f60037e7f7f017f60047f7f7f7f017f60" + "017f017f60047f7f7f7f00032f2e0302040400030501030302020600030302" + "0700080301050202020404090202000a0a0102020403030300000a03010405" + "017001101005030100110619037f01418080c0000b7f0041b49ac0000b7f00" + "41c09ac0000b073905066d656d6f7279020005726563757200000972656375" + "7273697665000c0a5f5f646174615f656e6403010b5f5f686561705f626173" + "6503020915010041010b0f010a0b1e10171819262c1d1f2223240a927c2ea7" + "0704017f017e027f017e23808080800041e0006b2202248080808000200220" + "003602040240200041004c0d002001200128020041016a3602002000417f6a" + "20011080808080000b2002410236020c2002418480c0800036020820024201" + "37021420024181808080003602242002200241206a3602102002200241046a" + "3602202002410636022c2002419490c08000360228024041002d00c096c080" + "004103460d001082808080000b0240024002400240024041002903a89ac080" + "0022034200520d00024041002802b09ac0800022000d001083808080004100" + "2802b09ac0800021000b20002000280200220141016a3602002001417f4c0d" + "012000450d02200020002802002201417f6a36020020002903082103200141" + "01470d0020001084808080000b0240024002402003410029039896c0800051" + "0d0041002d00a496c08000210141012100410041013a00a496c08000200220" + "013a00382001450d012002420037025420024281808080c00037024c200241" + "bc91c08000360248200241386a200241c8006a108580808000000b02404100" + "2802a096c080002200417f460d00200041016a21000c020b419c92c0800041" + "2641e092c08000108680808000000b4100200337039896c080000b41002000" + "3602a096c080002002419896c0800036023041042100200241043a00382002" + "200241306a360240200241386a41c085c08000200241086a10878080800021" + "0120022d003821040240024020010d00420021034117200441ff0171764101" + "710d01200228023c220028020021010240200041046a280200220428020022" + "05450d002001200511808080800080808080000b024020042802042204450d" + "00200120041088808080000b2000410c108880808000410421000c010b2004" + "41ff01714104460d032002290338220642807e8321032006a721000b200228" + "023022012001280208417f6a2204360208024020040d00200141003a000c20" + "0142003703000b200041ff01714104470d03200241e0006a2480808080000f" + "0b000b418087c0800041de0041f487c08000108680808000000b2002410036" + "02582002410136024c2002418491c0800036024820024204370250200241c8" + "006a418c91c08000108980808000000b200220032000ad42ff018384370330" + "2002410236024c200241f48fc0800036024820024202370254200241828080" + "8000ad422086200241306aad843703402002418380808000ad422086200241" + "286aad843703382002200241386a360250200241c8006a418490c080001089" + "80808000000b2701017f200028020022002000411f7522027320026bad2000" + "417f73411f7620011091808080000bf10101027f23808080800041206b2200" + "248080808000024002400240024041002d00c096c080000e0400000301000b" + "410041023a00c096c0800041002d009096c080001a418008109c8080800022" + "01450d01410041033a00c096c08000410020013602b096c080004100428080" + "80808080013703a896c080004100420037039896c08000410041003a00b896" + "c08000410041003602b496c08000410041003a00a496c08000410041003602" + "a096c080000b200041206a2480808080000f0b000b20004100360218200041" + "0136020c200041bc93c0800036020820004204370210200041086a418c92c0" + "8000108980808000000bf90103027f037e017f23808080800041206b220024" + "808080800041002d009096c080001a0240024002404120109c808080002201" + "450d0020014102360210200142818080801037030041002903d096c0800021" + "0203402002427f510d024100200242017c220341002903d096c08000220420" + "0420025122051b3703d096c08000200421022005450d000b410020033703a8" + "9ac080002001200337030841002802b09ac08000450d022000410036021820" + "00410136020c200041c484c0800036020820004204370210200041086a419c" + "85c080001089808080000b000b109b80808000000b410020013602b09ac080" + "00200041206a2480808080000b5b01027f024020002802104101470d002000" + "280214220141003a000020002802182202450d00200120021088808080000b" + "02402000417f460d00200020002802042201417f6a36020420014101470d00" + "200041201088808080000b0b3a01017f23808080800041106b220224808080" + "8000200241ac85c0800036020c20022000360208200241086a2002410c6a20" + "01109680808000000b6a01017f23808080800041306b220324808080800020" + "03200136020c2003200036020820034101360214200341d488c08000360210" + "2003420137021c2003418380808000ad422086200341086aad843703282003" + "200341286a360218200341106a2002108980808000000bbf05010a7f238080" + "80800041306b2203248080808000200341033a002c2003412036021c410021" + "04200341003602282003200136022420032000360220200341003602142003" + "410036020c02400240024002400240200228021022050d00200228020c2200" + "450d0120022802082101200041037421062000417f6a41ffffffff01714101" + "6a21042002280200210003400240200041046a2802002207450d0020032802" + "2020002802002007200328022428020c11818080800080808080000d040b20" + "012802002003410c6a200128020411828080800080808080000d0320014108" + "6a2101200041086a2100200641786a22060d000c020b0b2002280214220145" + "0d00200141057421082001417f6a41ffffff3f7141016a2104200228020821" + "09200228020021004100210603400240200041046a2802002201450d002003" + "28022020002802002001200328022428020c11818080800080808080000d03" + "0b2003200520066a220141106a28020036021c20032001411c6a2d00003a00" + "2c2003200141186a2802003602282001410c6a28020021074100210a410021" + "0b024002400240200141086a2802000e03010002010b2007410374210c4100" + "210b2009200c6a220c2802040d01200c28020021070b4101210b0b20032007" + "3602102003200b36020c200141046a28020021070240024002402001280200" + "0e03010002010b2007410374210b2009200b6a220b2802040d01200b280200" + "21070b4101210a0b200320073602182003200a3602142009200141146a2802" + "004103746a22012802002003410c6a20012802041182808080008080808000" + "0d02200041086a21002008200641206a2206470d000b0b200420022802044f" + "0d012003280220200228020020044103746a22012802002001280204200328" + "022428020c1181808080008080808000450d010b410121010c010b41002101" + "0b200341306a24808080800020010b6c01027f024002402000417c6a280200" + "2202417871220341044108200241037122021b20016a490d0002402002450d" + "002003200141276a4b0d020b2000108d808080000f0b418186c0800041b086" + "c08000108e80808000000b41c086c0800041f086c08000108e80808000000b" + "5601017f23808080800041206b2202248080808000200241106a200041106a" + "290200370300200241086a200041086a290200370300200241013b011c2002" + "2001360218200220002902003703002002109280808000000be50301017f23" + "808080800041c0006b22022480808080000240024002400240024002402000" + "2d00000e0400010203000b2002200028020436020441002d009096c080001a" + "4114109c808080002200450d04200041106a410028008093c0800036000020" + "0041086a41002900f892c08000370000200041002900f092c0800037000020" + "0241143602102002200036020c200241143602082002410336022c200241a0" + "8fc08000360228200242023702342002418180808000ad422086200241046a" + "ad843703202002418480808000ad422086200241086aad8437031820022002" + "41186a36023020012802142001280218200241286a10878080800021002002" + "2802082201450d03200228020c20011088808080000c030b20002d00012100" + "2002410136022c200241d488c0800036022820024201370234200241838080" + "8000ad422086200241186aad8437030820022000410274220041c493c08000" + "6a28020036021c2002200041e894c080006a2802003602182002200241086a" + "36023020012802142001280218200241286a10878080800021000c020b2001" + "20002802042200280200200028020410958080800021000c010b2000280204" + "220028020020012000280204280210118280808000808080800021000b2002" + "41c0006a24808080800020000f0b000b140020012000280200200028020410" + "95808080000b3f01027f23808080800041106b220024808080800020004100" + "36020c41a08d062000410c6a108080808000200028020c2101200041106a24" + "808080800020010bbe0601057f200041786a22012000417c6a280200220241" + "787122006a21030240024020024101710d002002410271450d012001280200" + "220220006a21000240200120026b220141002802809ac08000470d00200328" + "02044103714103470d01410020003602f899c0800020032003280204417e71" + "36020420012000410172360204200320003602000f0b2001200210a8808080" + "000b024002400240024002400240200328020422024102710d002003410028" + "02849ac08000460d02200341002802809ac08000460d032003200241787122" + "0210a8808080002001200220006a2200410172360204200120006a20003602" + "00200141002802809ac08000470d01410020003602f899c080000f0b200320" + "02417e7136020420012000410172360204200120006a20003602000b200041" + "8002490d022001200010a78080800041002101410041002802989ac0800041" + "7f6a22003602989ac0800020000d04024041002802e097c080002200450d00" + "410021010340200141016a2101200028020822000d000b0b4100200141ff1f" + "200141ff1f4b1b3602989ac080000f0b410020013602849ac0800041004100" + "2802fc99c0800020006a22003602fc99c08000200120004101723602040240" + "200141002802809ac08000470d00410041003602f899c08000410041003602" + "809ac080000b200041002802909ac0800022044d0d0341002802849ac08000" + "2200450d034100210241002802fc99c0800022054129490d0241d897c08000" + "2101034002402001280200220320004b0d002000200320012802046a490d04" + "0b200128020821010c000b0b410020013602809ac08000410041002802f899" + "c0800020006a22003602f899c0800020012000410172360204200120006a20" + "003602000f0b200041f8017141e897c080006a21030240024041002802f099" + "c08000220241012000410376742200710d00410020022000723602f099c080" + "00200321000c010b200328020821000b200320013602082000200136020c20" + "01200336020c200120003602080f0b024041002802e097c080002201450d00" + "410021020340200241016a2102200128020822010d000b0b4100200241ff1f" + "200241ff1f4b1b3602989ac08000200520044d0d004100417f3602909ac080" + "000b0b4d01017f23808080800041206b220224808080800020024100360210" + "20024101360204200242043702082002412e36021c20022000360218200220" + "0241186a36020020022001108980808000000b7d02017f017e238080808000" + "41306b22022480808080002002200036020020022001360204200241023602" + "0c2002418484c08000360208200242023702142002418580808000ad422086" + "2203200241046aad84370328200220032002ad843703202002200241206a36" + "0210200241086a41b083c08000108980808000000b11002000350200410120" + "011091808080000bdf0703027f017e097f23808080800041306b2203248080" + "808000412721040240024020004290ce005a0d00200021050c010b41272104" + "0340200341096a20046a2206417c6a20004290ce0080220542f0b1037e2000" + "7ca7220741ffff037141e4006e220841017441c481c080006a2f00003b0000" + "2006417e6a2008419c7f6c20076a41ffff037141017441c481c080006a2f00" + "003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b" + "02400240200542e300560d002005a721060c010b200341096a2004417e6a22" + "046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff037141" + "017441c481c080006a2f00003b00000b024002402006410a490d0020034109" + "6a2004417e6a22046a200641017441c481c080006a2f00003b00000c010b20" + "0341096a2004417f6a22046a20064130723a00000b412720046b2109024002" + "4020010d00412820046b2107200228021c2106412d21010c010b412b418080" + "c400200228021c220641017122071b2101200720096a21070b200341096a20" + "046a210a2006410471410276210b0240024020022802000d00024020022802" + "142204200228021822062001200b109380808000450d00410121040c020b20" + "04200a2009200628020c118180808000808080800021040c010b0240024002" + "402002280204220c20074b0d0020022802142204200228021822062001200b" + "109380808000450d01410121040c030b2006410871450d012002280210210d" + "2002413036021020022d0020210e41012104200241013a0020200228021422" + "06200228021822082001200b1093808080000d02200c20076b41016a210402" + "4003402004417f6a2204450d01200641302008280210118280808000808080" + "8000450d000b410121040c030b02402006200a2009200828020c1181808080" + "008080808000450d00410121040c030b2002200e3a00202002200d36021041" + "0021040c020b2004200a2009200628020c118180808000808080800021040c" + "010b200c20076b210c02400240024020022d002022040e0402000100020b20" + "0c21044100210c0c010b200c4101762104200c41016a410176210c0b200441" + "016a2104200228021021082002280218210620022802142107024003402004" + "417f6a2204450d012007200820062802101182808080008080808000450d00" + "0b410121040c010b41012104200720062001200b1093808080000d00200720" + "0a2009200628020c11818080800080808080000d004100210403400240200c" + "2004470d00200c200c4921040c020b200441016a2104200720082006280210" + "1182808080008080808000450d000b2004417f6a200c4921040b200341306a" + "24808080800020040b5d01027f23808080800041206b220124808080800020" + "002802182102200141106a200041106a290200370300200141086a20004108" + "6a2902003703002001200036021c2001200236021820012000290200370300" + "200110a980808000000b490002402002418080c400460d0020002002200128" + "02101182808080008080808000450d0041010f0b024020030d0041000f0b20" + "0020034100200128020c11818080800080808080000b7d02017f017e238080" + "80800041306b22022480808080002002200036020020022001360204200241" + "0236020c200241a484c08000360208200242023702142002418580808000ad" + "4220862203200241046aad84370328200220032002ad843703202002200241" + "206a360210200241086a41c083c08000108980808000000bc20b010b7f2000" + "28020821030240024002400240200028020022040d002003410171450d010b" + "02402003410171450d00200120026a210502400240200028020c22060d0041" + "002107200121080c010b410021074100210920012108034020082203200546" + "0d020240024020032c00002208417f4c0d00200341016a21080c010b024020" + "0841604f0d00200341026a21080c010b0240200841704f0d00200341036a21" + "080c010b200341046a21080b200820036b20076a21072006200941016a2209" + "470d000b0b20082005460d00024020082c00002203417f4a0d002003416049" + "1a0b024002402007450d000240200720024f0d00200120076a2c000041bf7f" + "4a0d01410021030c020b20072002460d00410021030c010b200121030b2007" + "200220031b21022003200120031b21010b024020040d002000280214200120" + "02200028021828020c11818080800080808080000f0b2000280204210a0240" + "20024110490d0020022001200141036a417c7122076b22096a220b41037121" + "044100210641002103024020012007460d004100210302402009417c4b0d00" + "410021034100210503402003200120056a22082c000041bf7f4a6a20084101" + "6a2c000041bf7f4a6a200841026a2c000041bf7f4a6a200841036a2c000041" + "bf7f4a6a2103200541046a22050d000b0b200121080340200320082c000041" + "bf7f4a6a2103200841016a2108200941016a22090d000b0b02402004450d00" + "2007200b417c716a22082c000041bf7f4a210620044101460d00200620082c" + "000141bf7f4a6a210620044102460d00200620082c000241bf7f4a6a21060b" + "200b4102762105200620036a21060340200721042005450d04200541c00120" + "0541c001491b220b410371210c200b410274210d4100210802402005410449" + "0d002004200d41f007716a210941002108200421030340200328020c220741" + "7f7341077620074106767241818284087120032802082207417f7341077620" + "074106767241818284087120032802042207417f7341077620074106767241" + "818284087120032802002207417f7341077620074106767241818284087120" + "086a6a6a6a2108200341106a22032009470d000b0b2005200b6b2105200420" + "0d6a2107200841087641ff81fc0771200841ff81fc07716a418180046c4110" + "7620066a2106200c450d000b2004200b41fc01714102746a22082802002203" + "417f734107762003410676724181828408712103200c4101460d0220082802" + "042207417f7341077620074106767241818284087120036a2103200c410246" + "0d0220082802082208417f7341077620084106767241818284087120036a21" + "030c020b024020020d00410021060c030b2002410371210802400240200241" + "044f0d0041002106410021090c010b41002106200121032002410c71220921" + "070340200620032c000041bf7f4a6a200341016a2c000041bf7f4a6a200341" + "026a2c000041bf7f4a6a200341036a2c000041bf7f4a6a2106200341046a21" + "032007417c6a22070d000b0b2008450d02200120096a21030340200620032c" + "000041bf7f4a6a2106200341016a21032008417f6a22080d000c030b0b2000" + "28021420012002200028021828020c11818080800080808080000f0b200341" + "087641ff811c71200341ff81fc07716a418180046c41107620066a21060b02" + "400240200a20064d0d00200a20066b21054100210302400240024020002d00" + "200e0402000102020b20052103410021050c010b2005410176210320054101" + "6a41017621050b200341016a21032000280210210920002802182108200028" + "0214210703402003417f6a2203450d02200720092008280210118280808000" + "8080808000450d000b41010f0b200028021420012002200028021828020c11" + "818080800080808080000f0b0240200720012002200828020c118180808000" + "8080808000450d0041010f0b410021030340024020052003470d0020052005" + "490f0b200341016a2103200720092008280210118280808000808080800045" + "0d000b2003417f6a2005490b820302017f017e23808080800041f0006b2203" + "248080808000200341b085c0800036020c20032000360208200341b085c080" + "00360214200320013602102003410236021c200341bc80c080003602180240" + "20022802000d002003410336025c200341f080c08000360258200342033702" + "642003418680808000ad4220862204200341106aad84370348200320042003" + "41086aad843703402003418380808000ad422086200341186aad8437033820" + "03200341386a360260200341d8006a41e891c08000108980808000000b2003" + "41206a41106a200241106a290200370300200341206a41086a200241086a29" + "0200370300200320022902003703202003410436025c200341a481c0800036" + "0258200342043702642003418680808000ad4220862204200341106aad8437" + "035020032004200341086aad843703482003418780808000ad422086200341" + "206aad843703402003418380808000ad422086200341186aad843703382003" + "200341386a360260200341d8006a41e891c08000108980808000000b1c0020" + "002802002001200028020428020c11828080800080808080000b1400200128" + "0214200128021820001087808080000b22002001280214419480c08000410e" + "200128021828020c11818080800080808080000b6001017f23808080800041" + "306b22002480808080002000410136020c200041b480c08000360208200042" + "013702142000418880808000ad4220862000412f6aad843703202000200041" + "206a360210200041086a41cc8fc08000108980808000000b4701017f238080" + "80800041206b2200248080808000200041003602182000410136020c200041" + "bc88c0800036020820004204370210200041086a41c488c080001089808080" + "00000bcb2502087f017e02400240024002400240024002400240200041f501" + "490d0041002101200041cdff7b4f0d052000410b6a22014178712102410028" + "02f499c080002203450d04411f21040240200041f4ffff074b0d0020024106" + "20014108766722006b7641017120004101746b413e6a21040b410020026b21" + "010240200441027441d896c080006a28020022050d0041002100410021060c" + "020b4100210020024100411920044101766b2004411f461b74210741002106" + "034002402005220528020441787122082002490d00200820026b220820014f" + "0d00200821012005210620080d004100210120052106200521000c040b2005" + "28021422082000200820052007411d764104716a41106a2802002205471b20" + "0020081b2100200741017421072005450d020c000b0b024041002802f099c0" + "8000220541102000410b6a41f803712000410b491b22024103762201762200" + "410371450d00024002402000417f7341017120016a2207410374220041e897" + "c080006a2201200041f097c080006a28020022022802082206460d00200620" + "0136020c200120063602080c010b41002005417e200777713602f099c08000" + "0b20022000410372360204200220006a220020002802044101723602042002" + "41086a0f0b200241002802f899c080004d0d0302400240024020000d004100" + "2802f499c080002200450d0620006841027441d896c080006a280200220628" + "020441787120026b21012006210503400240200628021022000d0020062802" + "1422000d0020052802182104024002400240200528020c22002005470d0020" + "0541144110200528021422001b6a28020022060d01410021000c020b200528" + "02082206200036020c200020063602080c010b200541146a200541106a2000" + "1b21070340200721082006220041146a200041106a200028021422061b2107" + "20004114411020061b6a28020022060d000b200841003602000b2004450d04" + "0240200528021c41027441d896c080006a22062802002005460d0020044110" + "411420042802102005461b6a20003602002000450d050c040b200620003602" + "0020000d03410041002802f499c08000417e200528021c77713602f499c080" + "000c040b200028020441787120026b22062001200620014922061b21012000" + "200520061b2105200021060c000b0b02400240200020017441022001742200" + "410020006b7271682208410374220141e897c080006a2206200141f097c080" + "006a28020022002802082207460d002007200636020c200620073602080c01" + "0b41002005417e200877713602f099c080000b200020024103723602042000" + "20026a2207200120026b2206410172360204200020016a2006360200024041" + "002802f899c080002205450d00200541787141e897c080006a210141002802" + "809ac0800021020240024041002802f099c080002208410120054103767422" + "05710d00410020082005723602f099c08000200121050c010b200128020821" + "050b200120023602082005200236020c2002200136020c200220053602080b" + "410020073602809ac08000410020063602f899c08000200041086a0f0b2000" + "2004360218024020052802102206450d002000200636021020062000360218" + "0b20052802142206450d0020002006360214200620003602180b0240024002" + "4020014110490d0020052002410372360204200520026a2202200141017236" + "0204200220016a200136020041002802f899c080002207450d012007417871" + "41e897c080006a210641002802809ac0800021000240024041002802f099c0" + "8000220841012007410376742207710d00410020082007723602f099c08000" + "200621070c010b200628020821070b200620003602082007200036020c2000" + "200636020c200020073602080c010b2005200120026a220041037236020420" + "0520006a220020002802044101723602040c010b410020023602809ac08000" + "410020013602f899c080000b200541086a0f0b024020002006720d00410021" + "0641022004742200410020006b722003712200450d0320006841027441d896" + "c080006a28020021000b2000450d010b034020002006200028020441787122" + "0520026b220820014922041b2103200520024921072008200120041b210802" + "40200028021022050d00200028021421050b2006200320071b210620012008" + "20071b21012005210020050d000b0b2006450d00024041002802f899c08000" + "22002002490d002001200020026b4f0d010b20062802182104024002400240" + "200628020c22002006470d00200641144110200628021422001b6a28020022" + "050d01410021000c020b20062802082205200036020c200020053602080c01" + "0b200641146a200641106a20001b21070340200721082005220041146a2000" + "41106a200028021422051b210720004114411020051b6a28020022050d000b" + "200841003602000b2004450d030240200628021c41027441d896c080006a22" + "052802002006460d0020044110411420042802102006461b6a200036020020" + "00450d040c030b2005200036020020000d02410041002802f499c08000417e" + "200628021c77713602f499c080000c030b0240024002400240024002404100" + "2802f899c08000220020024f0d00024041002802fc99c08000220020024b0d" + "0041002101200241af80046a220641107640002200417f4622070d07200041" + "10742205450d07410041002802889ac08000410020064180807c7120071b22" + "086a22003602889ac080004100410028028c9ac0800022012000200120004b" + "1b36028c9ac0800002400240024041002802849ac080002201450d0041d897" + "c080002100034020002802002206200028020422076a2005460d0220002802" + "0822000d000c030b0b0240024041002802949ac080002200450d0020002005" + "4d0d010b410020053602949ac080000b410041ff1f3602989ac08000410020" + "083602dc97c08000410020053602d897c08000410041e897c080003602f497" + "c08000410041f097c080003602fc97c08000410041e897c080003602f097c0" + "8000410041f897c0800036028498c08000410041f097c080003602f897c080" + "004100418098c0800036028c98c08000410041f897c0800036028098c08000" + "4100418898c0800036029498c080004100418098c0800036028898c0800041" + "00419098c0800036029c98c080004100418898c0800036029098c080004100" + "419898c080003602a498c080004100419098c0800036029898c08000410041" + "a098c080003602ac98c080004100419898c080003602a098c0800041004100" + "3602e497c08000410041a898c080003602b498c08000410041a098c0800036" + "02a898c08000410041a898c080003602b098c08000410041b098c080003602" + "bc98c08000410041b098c080003602b898c08000410041b898c080003602c4" + "98c08000410041b898c080003602c098c08000410041c098c080003602cc98" + "c08000410041c098c080003602c898c08000410041c898c080003602d498c0" + "8000410041c898c080003602d098c08000410041d098c080003602dc98c080" + "00410041d098c080003602d898c08000410041d898c080003602e498c08000" + "410041d898c080003602e098c08000410041e098c080003602ec98c0800041" + "0041e098c080003602e898c08000410041e898c080003602f498c080004100" + "41f098c080003602fc98c08000410041e898c080003602f098c08000410041" + "f898c0800036028499c08000410041f098c080003602f898c0800041004180" + "99c0800036028c99c08000410041f898c0800036028099c080004100418899" + "c0800036029499c080004100418099c0800036028899c080004100419099c0" + "800036029c99c080004100418899c0800036029099c080004100419899c080" + "003602a499c080004100419099c0800036029899c08000410041a099c08000" + "3602ac99c080004100419899c080003602a099c08000410041a899c0800036" + "02b499c08000410041a099c080003602a899c08000410041b099c080003602" + "bc99c08000410041a899c080003602b099c08000410041b899c080003602c4" + "99c08000410041b099c080003602b899c08000410041c099c080003602cc99" + "c08000410041b899c080003602c099c08000410041c899c080003602d499c0" + "8000410041c099c080003602c899c08000410041d099c080003602dc99c080" + "00410041c899c080003602d099c08000410041d899c080003602e499c08000" + "410041d099c080003602d899c08000410041e099c080003602ec99c0800041" + "0041d899c080003602e099c08000410020053602849ac08000410041e099c0" + "80003602e899c080004100200841586a22003602fc99c08000200520004101" + "72360204200520006a4128360204410041808080013602909ac080000c080b" + "200120054f0d00200620014b0d00200028020c450d030b410041002802949a" + "c080002200200520002005491b3602949ac08000200520086a210641d897c0" + "800021000240024002400340200028020022072006460d0120002802082200" + "0d000c020b0b200028020c450d010b41d897c0800021000240034002402000" + "280200220620014b0d002001200620002802046a2206490d020b2000280208" + "21000c000b0b410020053602849ac080004100200841586a22003602fc99c0" + "800020052000410172360204200520006a4128360204410041808080013602" + "909ac080002001200641606a41787141786a22002000200141106a491b2207" + "411b36020441002902d897c080002109200741106a41002902e097c0800037" + "020020072009370208410020083602dc97c08000410020053602d897c08000" + "4100200741086a3602e097c08000410041003602e497c080002007411c6a21" + "00034020004107360200200041046a22002006490d000b20072001460d0720" + "072007280204417e713602042001200720016b220041017236020420072000" + "36020002402000418002490d002001200010a7808080000c080b200041f801" + "7141e897c080006a21060240024041002802f099c080002205410120004103" + "76742200710d00410020052000723602f099c08000200621000c010b200628" + "020821000b200620013602082000200136020c2001200636020c2001200036" + "02080c070b200020053602002000200028020420086a360204200520024103" + "723602042007410f6a41787141786a2201200520026a22006b210220014100" + "2802849ac08000460d03200141002802809ac08000460d0402402001280204" + "22064103714101470d0020012006417871220610a880808000200620026a21" + "02200120066a220128020421060b20012006417e7136020420002002410172" + "360204200020026a200236020002402002418002490d002000200210a78080" + "80000c060b200241f8017141e897c080006a21010240024041002802f099c0" + "8000220641012002410376742202710d00410020062002723602f099c08000" + "200121020c010b200128020821020b200120003602082002200036020c2000" + "200136020c200020023602080c050b4100200020026b22013602fc99c08000" + "410041002802849ac08000220020026a22063602849ac08000200620014101" + "7236020420002002410372360204200041086a21010c060b41002802809ac0" + "8000210102400240200020026b2206410f4b0d00410041003602809ac08000" + "410041003602f899c0800020012000410372360204200120006a2200200028" + "02044101723602040c010b410020063602f899c080004100200120026a2205" + "3602809ac0800020052006410172360204200120006a200636020020012002" + "4103723602040b200141086a0f0b2000200720086a36020441004100280284" + "9ac080002200410f6a417871220141786a22063602849ac080004100200020" + "016b41002802fc99c0800020086a22016a41086a22053602fc99c080002006" + "2005410172360204200020016a4128360204410041808080013602909ac080" + "000c030b410020003602849ac08000410041002802fc99c0800020026a2202" + "3602fc99c08000200020024101723602040c010b410020003602809ac08000" + "410041002802f899c0800020026a22023602f899c080002000200241017236" + "0204200020026a20023602000b200541086a0f0b4100210141002802fc99c0" + "8000220020024d0d004100200020026b22013602fc99c08000410041002802" + "849ac08000220020026a22063602849ac08000200620014101723602042000" + "2002410372360204200041086a0f0b20010f0b200020043602180240200628" + "02102205450d0020002005360210200520003602180b20062802142205450d" + "0020002005360214200520003602180b0240024020014110490d0020062002" + "410372360204200620026a22002001410172360204200020016a2001360200" + "02402001418002490d002000200110a7808080000c020b200141f8017141e8" + "97c080006a21020240024041002802f099c080002205410120014103767422" + "01710d00410020052001723602f099c08000200221010c010b200228020821" + "010b200220003602082001200036020c2000200236020c200020013602080c" + "010b2006200120026a2200410372360204200620006a220020002802044101" + "723602040b200641086a0b3000024020002802002d00000d002001418c83c0" + "800041051095808080000f0b2001419183c0800041041095808080000b1400" + "2001200028020420002802081095808080000b7001037f2000280204210102" + "40024020002d0000220041044b0d0020004103470d010b2001280200210002" + "40200141046a28020022022802002203450d00200020031180808080008080" + "8080000b024020022802042202450d00200020021088808080000b2001410c" + "1088808080000b0bab08010a7f23808080800041206b220424808080800002" + "40024002400240024020012802100d002001417f3602102003410020032002" + "41036a417c7120026b22056b41077120032005491b22066b21072003200649" + "0d0102402006450d0002400240200220036a2208417f6a22092d0000410a47" + "0d002006417f6a21060c010b200220076a220a2009460d0102402008417e6a" + "22092d0000410a470d002006417e6a21060c010b200a2009460d0102402008" + "417d6a22092d0000410a470d002006417d6a21060c010b200a2009460d0102" + "402008417c6a22092d0000410a470d002006417c6a21060c010b200a200946" + "0d0102402008417b6a22092d0000410a470d002006417b6a21060c010b200a" + "2009460d0102402008417a6a22092d0000410a470d002006417a6a21060c01" + "0b200a2009460d010240200841796a22092d0000410a470d00200641796a21" + "060c010b200a2009460d01200641787221060b200620076a41016a21060c04" + "0b20052003200320054b1b210b410020066b21082002417c6a210c2006417f" + "7320026a210a02400340200a21052008210620072209200b4d0d0120064178" + "6a2108200541786a210a41808284082002200941786a22076a280200220d41" + "8a94a8d000736b200d724180828408200c20096a280200220d418a94a8d000" + "736b200d727141808182847871418081828478460d000b0b200920034b0d02" + "02400340200320066a450d012006417f6a2106200520036a21092005417f6a" + "210520092d0000410a470d000b200320066a41016a21060c040b0240024020" + "01411c6a28020022060d00410021060c010b2006200141186a2802006a417f" + "6a2d0000410a470d0041002106200141003a00202001411c6a41003602000b" + "0240200128021420066b20034b0d002000200141146a2002200310a1808080" + "000c050b200128021820066a2002200310ad808080001a200041043a000020" + "01411c6a200620036a3602000c040b109a80808000000b20072003108f8080" + "8000000b20092003109480808000000b0240200320064f0d00200441003602" + "182004410136020c2004418c89c0800036020820044204370210200441086a" + "419489c08000108980808000000b02402001411c6a2802002205450d000240" + "0240200128021420056b20064d0d00200141186a28020020056a2002200610" + "ad808080001a2001411c6a200520066a22053602000c010b200441086a2001" + "41146a2002200610a180808000024020042d00084104460d00200020042903" + "083702000c030b2001411c6a28020021050b2005450d00200141003a002020" + "01411c6a41003602000b200220066a210502402001280214200320066b2206" + "4b0d002000200141146a2005200610a1808080000c010b200141186a280200" + "2005200610ad808080001a200041043a00002001411c6a20063602000b2001" + "200128021041016a360210200441206a2480808080000b7101027f20012802" + "002104024020012802082205450d00200420056b20034f0d00410021052001" + "4100360208200141003a000c0b0240200420034d0d00200128020420056a20" + "02200310ad808080001a200041043a00002001200520036a3602080f0b2000" + "4204370200200141003a000c0bc90103027f017e027f23808080800041106b" + "2203248080808000200341086a20002802082802002001200210a080808000" + "024020032d000822024104460d002000280204210420032903082105024002" + "4020002d0000220141044b0d0020014103470d010b20042802002101024020" + "0441046a28020022062802002207450d002001200711808080800080808080" + "000b024020062802042206450d00200120061088808080000b2004410c1088" + "808080000b200020053702000b200341106a24808080800020024104470b9c" + "0303027f017e037f23808080800041106b2202248080808000200241003602" + "0402400240024002402001418001490d002001418010490d01200141808004" + "4f0d0220022001413f71418001723a000620022001410c7641e001723a0004" + "20022001410676413f71418001723a0005410321010c030b200220013a0004" + "410121010c020b20022001413f71418001723a00052002200141067641c001" + "723a0004410221010c010b20022001413f71418001723a0007200220014112" + "7641f001723a000420022001410676413f71418001723a000620022001410c" + "76413f71418001723a0005410421010b200241086a20002802082802002002" + "41046a200110a080808000024020022d000822014104460d00200028020421" + "03200229030821040240024020002d0000220541044b0d0020054103470d01" + "0b200328020021050240200341046a28020022062802002207450d00200520" + "0711808080800080808080000b024020062802042206450d00200520061088" + "808080000b2003410c1088808080000b200020043702000b200241106a2480" + "8080800020014104470b1200200041c085c0800020011087808080000b0300" + "000b0900200041003602000bc30201047f411f21020240200141ffffff074b" + "0d002001410620014108766722026b7641017120024101746b413e6a21020b" + "200042003702102000200236021c200241027441d896c080006a2103024041" + "002802f499c0800041012002742204710d0020032000360200200020033602" + "182000200036020c20002000360208410041002802f499c080002004723602" + "f499c080000f0b024002400240200328020022042802044178712001470d00" + "200421020c010b20014100411920024101766b2002411f461b742103034020" + "042003411d764104716a41106a22052802002202450d022003410174210320" + "02210420022802044178712001470d000b0b20022802082203200036020c20" + "022000360208200041003602182000200236020c200020033602080f0b2005" + "2000360200200020043602182000200036020c200020003602080b82030104" + "7f200028020c21020240024002402001418002490d00200028021821030240" + "0240024020022000470d00200041144110200028021422021b6a2802002201" + "0d01410021020c020b20002802082201200236020c200220013602080c010b" + "200041146a200041106a20021b21040340200421052001220241146a200241" + "106a200228021422011b210420024114411020011b6a28020022010d000b20" + "0541003602000b2003450d020240200028021c41027441d896c080006a2201" + "2802002000460d0020034110411420032802102000461b6a20023602002002" + "450d030c020b2001200236020020020d01410041002802f499c08000417e20" + "0028021c77713602f499c080000c020b0240200220002802082204460d0020" + "04200236020c200220043602080f0b410041002802f099c08000417e200141" + "037677713602f099c080000f0b20022003360218024020002802102201450d" + "0020022001360210200120023602180b20002802142201450d002002200136" + "0214200120023602180f0b0b0b00200010aa80808000000bb50101037f2380" + "8080800041106b2201248080808000200028020c2102024002400240024020" + "002802040e020001020b20020d0141012102410021030c020b20020d002000" + "28020022022802042103200228020021020c010b2001418080808078360200" + "2001200036020c2001418980808000200028021c22002d001c20002d001d10" + "ab80808000000b20012003360204200120023602002001418a808080002000" + "28021c22002d001c20002d001d10ab80808000000b990101027f2380808080" + "0041106b2204248080808000410041002802cc96c08000220541016a3602cc" + "96c08000024020054100480d000240024041002d00a09ac080000d00410041" + "0028029c9ac0800041016a36029c9ac0800041002802c896c08000417f4a0d" + "010c020b200441086a200020011183808080008080808000000b410041003a" + "00a09ac080002002450d0010a580808000000b000b0c002000200129020037" + "03000bc10201087f02400240200241104f0d00200021030c010b2000410020" + "006b41037122046a210502402004450d002000210320012106034020032006" + "2d00003a0000200641016a2106200341016a22032005490d000b0b20052002" + "20046b2207417c7122086a210302400240200120046a2209410371450d0020" + "084101480d012009410374220641187121022009417c71220a41046a210141" + "0020066b4118712104200a2802002106034020052006200276200128020022" + "0620047472360200200141046a2101200541046a22052003490d000c020b0b" + "20084101480d0020092101034020052001280200360200200141046a210120" + "0541046a22052003490d000b0b20074103712102200920086a21010b024020" + "02450d00200320026a21050340200320012d00003a0000200141016a210120" + "0341016a22032005490d000b0b20000b0b96160100418080c0000b8c160a00" + "000001000000000000000000100001000000426f72726f774d75744572726f" + "72616c726561647920626f72726f7765643a2022001000120000003d3d6173" + "73657274696f6e20606c6566742020726967687460206661696c65640a2020" + "6c6566743a200a2072696768743a2000003e001000100000004e0010001700" + "0000650010000900000020726967687460206661696c65643a200a20206c65" + "66743a200000003e0010001000000088001000100000009800100009000000" + "65001000090000003030303130323033303430353036303730383039313031" + "31313231333134313531363137313831393230323132323233323432353236" + "32373238323933303331333233333334333533363337333833393430343134" + "32343334343435343634373438343935303531353235333534353535363537" + "35383539363036313632363336343635363636373638363937303731373237" + "33373437353736373737383739383038313832383338343835383638373838" + "3839393039313932393339343935393639373938393966616c736574727565" + "636f72652f7372632f736c6963652f6d656d6368722e727300000095011000" + "18000000830000001e00000095011000180000009f0000000900000072616e" + "676520737461727420696e64657820206f7574206f662072616e676520666f" + "7220736c696365206f66206c656e67746820d001100012000000e201100022" + "00000072616e676520656e6420696e646578201402100010000000e2011000" + "220000007265656e7472616e7420696e69740000340210000e0000002f7275" + "7374632f633266373463336639323861656235303366313562346539656635" + "373738653737663330353862382f6c6962726172792f636f72652f7372632f" + "63656c6c2f6f6e63652e72730000004c0210004d0000002301000042000000" + "000000000000000004000000040000000b0000000c0000000c000000040000" + "000d0000000e0000000f0000002f727573742f646570732f646c6d616c6c6f" + "632d302e322e362f7372632f646c6d616c6c6f632e7273617373657274696f" + "6e206661696c65643a207073697a65203e3d2073697a65202b206d696e5f6f" + "7665726865616400d802100029000000a80400000900000061737365727469" + "6f6e206661696c65643a207073697a65203c3d2073697a65202b206d61785f" + "6f766572686561640000d802100029000000ae0400000d000000757365206f" + "66207374643a3a7468726561643a3a63757272656e742829206973206e6f74" + "20706f737369626c6520616674657220746865207468726561642773206c6f" + "63616c206461746120686173206265656e2064657374726f7965647374642f" + "7372632f7468726561642f6d6f642e727300de03100015000000f102000013" + "0000006661696c656420746f2067656e657261746520756e69717565207468" + "726561642049443a2062697473706163652065786861757374656400040410" + "0037000000de03100015000000c40400000d00000001000000000000007374" + "642f7372632f696f2f62756666657265642f6c696e65777269746572736869" + "6d2e72736d6964203e206c656e000081041000090000005c04100025000000" + "0f01000029000000656e74697479206e6f7420666f756e647065726d697373" + "696f6e2064656e696564636f6e6e656374696f6e2072656675736564636f6e" + "6e656374696f6e207265736574686f737420756e726561636861626c656e65" + "74776f726b20756e726561636861626c65636f6e6e656374696f6e2061626f" + "727465646e6f7420636f6e6e65637465646164647265737320696e20757365" + "61646472657373206e6f7420617661696c61626c656e6574776f726b20646f" + "776e62726f6b656e2070697065656e7469747920616c726561647920657869" + "7374736f7065726174696f6e20776f756c6420626c6f636b6e6f7420612064" + "69726563746f727969732061206469726563746f72796469726563746f7279" + "206e6f7420656d707479726561642d6f6e6c792066696c6573797374656d20" + "6f722073746f72616765206d656469756d66696c6573797374656d206c6f6f" + "70206f7220696e646972656374696f6e206c696d69742028652e672e207379" + "6d6c696e6b206c6f6f70297374616c65206e6574776f726b2066696c652068" + "616e646c65696e76616c696420696e70757420706172616d65746572696e76" + "616c6964206461746174696d6564206f75747772697465207a65726f6e6f20" + "73746f726167652073706163657365656b206f6e20756e7365656b61626c65" + "2066696c6566696c6573797374656d2071756f746120657863656564656466" + "696c6520746f6f206c617267657265736f7572636520627573796578656375" + "7461626c652066696c652062757379646561646c6f636b63726f73732d6465" + "76696365206c696e6b206f722072656e616d65746f6f206d616e79206c696e" + "6b73696e76616c69642066696c656e616d65617267756d656e74206c697374" + "20746f6f206c6f6e676f7065726174696f6e20696e74657272757074656475" + "6e737570706f72746564756e657870656374656420656e64206f662066696c" + "656f7574206f66206d656d6f72796f74686572206572726f72756e63617465" + "676f72697a6564206572726f7220286f73206572726f722029000000010000" + "0000000000910710000b0000009c071000010000007374642f7372632f696f" + "2f737464696f2e727300b8071000130000002c030000140000006661696c65" + "64207072696e74696e6720746f203a20000000dc07100013000000ef071000" + "02000000b8071000130000005d040000090000007374646f75747374642f73" + "72632f696f2f6d6f642e72736120666f726d617474696e6720747261697420" + "696d706c656d656e746174696f6e2072657475726e656420616e206572726f" + "72207768656e2074686520756e6465726c79696e672073747265616d206469" + "64206e6f740000002b081000560000001a0810001100000028070000150000" + "0063616e6e6f74207265637572736976656c792061637175697265206d7574" + "65789c081000200000007374642f7372632f7379732f73796e632f6d757465" + "782f6e6f5f746872656164732e7273c4081000240000001400000009000000" + "7374642f7372632f73796e632f6f6e63652e7273f808100014000000d90000" + "00140000006c6f636b20636f756e74206f766572666c6f7720696e20726565" + "6e7472616e74206d757465787374642f7372632f73796e632f7265656e7472" + "616e745f6c6f636b2e7273420910001e000000220100002d0000006f706572" + "6174696f6e207375636365737366756c6f6e652d74696d6520696e69746961" + "6c697a6174696f6e206d6179206e6f7420626520706572666f726d65642072" + "65637572736976656c79840910003800000010000000110000001200000010" + "0000001000000013000000120000000d0000000e000000150000000c000000" + "0b00000015000000150000000f0000000e0000001300000026000000380000" + "0019000000170000000c000000090000000a00000010000000170000001900" + "00000e0000000d00000014000000080000001b0000000e0000001000000016" + "000000150000000b000000160000000d0000000b00000013000000a4041000" + "b4041000c5041000d7041000e7041000f70410000a0510001c051000290510" + "00370510004c0510005805100063051000780510008d0510009c051000aa05" + "1000bd051000e30510001b061000340610004b06100057061000600610006a" + "0610007a06100091061000aa061000b8061000c5061000d9061000e1061000" + "fc0610000a0710001a07100030071000450710005007100066071000730710" + "007e071000009118046e616d65000e0d7761736d5f6c69622e7761736d01d9" + "172e0005726563757201625f5a4e34636f726533666d74336e756d33696d70" + "35325f244c5424696d706c2475323024636f72652e2e666d742e2e44697370" + "6c61792475323024666f7224753230246933322447542433666d7431376863" + "6564393063376136333963303164644502495f5a4e337374643473796e6339" + "6f6e63655f6c6f636b31374f6e63654c6f636b244c54245424475424313069" + "6e697469616c697a6531376837663563353038646139653162303962450342" + "5f5a4e34636f72653463656c6c346f6e636531374f6e636543656c6c244c54" + "245424475424387472795f696e697431376863653633626632323835313931" + "65373145043e5f5a4e35616c6c6f633473796e633136417263244c54245424" + "432441244754243964726f705f736c6f773137686565396163636361643963" + "63313036394505355f5a4e34636f72653970616e69636b696e673133617373" + "6572745f6661696c6564313768323332363266326333633738623661624506" + "325f5a4e34636f7265366f7074696f6e31336578706563745f6661696c6564" + "313768663038613939653264373333366336614507265f5a4e34636f726533" + "666d743577726974653137683933353534653462653731663263376145080e" + "5f5f727573745f6465616c6c6f6309305f5a4e34636f72653970616e69636b" + "696e673970616e69635f666d74313768363534306363623264356664633361" + "62450a595f5a4e36305f244c54247374642e2e696f2e2e6572726f722e2e45" + "72726f72247532302461732475323024636f72652e2e666d742e2e44697370" + "6c61792447542433666d743137683930323731633762326136636538333945" + "0b495f5a4e34345f244c54242452462454247532302461732475323024636f" + "72652e2e666d742e2e446973706c61792447542433666d7431376837666634" + "643062383630396332343732450c097265637572736976650d415f5a4e3864" + "6c6d616c6c6f6338646c6d616c6c6f633137446c6d616c6c6f63244c542441" + "24475424346672656531376833393833346161616165336538393436450e2c" + "5f5a4e34636f72653970616e69636b696e673570616e696331376830346565" + "623931376464393363323239450f445f5a4e34636f726535736c6963653569" + "6e6465783236736c6963655f73746172745f696e6465785f6c656e5f666169" + "6c313768663931613361666538376231643434334510625f5a4e34636f7265" + "33666d74336e756d33696d7035325f244c5424696d706c2475323024636f72" + "652e2e666d742e2e446973706c61792475323024666f722475323024753332" + "2447542433666d74313768626633653032323834383365333735614511305f" + "5a4e34636f726533666d74336e756d33696d7037666d745f75363431376864" + "353231666136656636613036373261451211727573745f626567696e5f756e" + "77696e6413465f5a4e34636f726533666d7439466f726d6174746572313270" + "61645f696e74656772616c313277726974655f707265666978313768613961" + "343332383062363030366431324514425f5a4e34636f726535736c69636535" + "696e6465783234736c6963655f656e645f696e6465785f6c656e5f6661696c" + "3137683038386235366532393962656161616645152e5f5a4e34636f726533" + "666d7439466f726d6174746572337061643137683437363961653338393337" + "346363353145163b5f5a4e34636f72653970616e69636b696e673139617373" + "6572745f6661696c65645f696e6e6572313768366637653332353764383461" + "353034324517475f5a4e34325f244c54242452462454247532302461732475" + "323024636f72652e2e666d742e2e44656275672447542433666d7431376833" + "6136626161316262343761643230344518585f5a4e35395f244c5424636f72" + "652e2e666d742e2e417267756d656e7473247532302461732475323024636f" + "72652e2e666d742e2e446973706c61792447542433666d7431376836386133" + "65386535303963616663363445195c5f5a4e36335f244c5424636f72652e2e" + "63656c6c2e2e426f72726f774d75744572726f722475323024617324753230" + "24636f72652e2e666d742e2e44656275672447542433666d74313768313564" + "33643334333462646463636338451a395f5a4e34636f72653463656c6c3232" + "70616e69635f616c72656164795f626f72726f776564313768333134623532" + "61316263343662666534451b395f5a4e337374643674687265616438546872" + "6561644964336e657739657868617573746564313768333336626637613134" + "38383034346338451c435f5a4e38646c6d616c6c6f6338646c6d616c6c6f63" + "3137446c6d616c6c6f63244c54244124475424366d616c6c6f633137686536" + "3539333961346338393763633135451d475f5a4e34325f244c542424524624" + "54247532302461732475323024636f72652e2e666d742e2e44656275672447" + "542433666d7431376865313837343338386530376266653235451e595f5a4e" + "36305f244c5424616c6c6f632e2e737472696e672e2e537472696e67247532" + "302461732475323024636f72652e2e666d742e2e446973706c617924475424" + "33666d7431376863653432323661613166373236633163451f7a5f5a4e3463" + "6f726533707472383864726f705f696e5f706c616365244c54247374642e2e" + "696f2e2e57726974652e2e77726974655f666d742e2e41646170746572244c" + "5424616c6c6f632e2e7665632e2e566563244c542475382447542424475424" + "24475424313768313636646336316162303333346331654520605f5a4e3631" + "5f244c54247374642e2e696f2e2e737464696f2e2e5374646f75744c6f636b" + "2475323024617324753230247374642e2e696f2e2e57726974652447542439" + "77726974655f616c6c31376832346238323631303436316432353666452155" + "5f5a4e3373746432696f386275666665726564396275667772697465723138" + "427566577269746572244c54245724475424313477726974655f616c6c5f63" + "6f6c64313768353834626462626165623066623162624522735f5a4e38305f" + "244c54247374642e2e696f2e2e57726974652e2e77726974655f666d742e2e" + "41646170746572244c54245424475424247532302461732475323024636f72" + "652e2e666d742e2e5772697465244754243977726974655f73747231376837" + "6661636635626330656663643830384523325f5a4e34636f726533666d7435" + "5772697465313077726974655f636861723137686630623362653165633139" + "64653565374524305f5a4e34636f726533666d743557726974653977726974" + "655f666d743137686638383038663064663065343531336445250a72757374" + "5f70616e696326375f5a4e34636f72653570616e6963313250616e69635061" + "796c6f61643661735f73747231376836313439663134326439613265303265" + "4527505f5a4e38646c6d616c6c6f6338646c6d616c6c6f633137446c6d616c" + "6c6f63244c542441244754243138696e736572745f6c617267655f6368756e" + "6b3137686566653835316132373538326461376245284a5f5a4e38646c6d61" + "6c6c6f6338646c6d616c6c6f633137446c6d616c6c6f63244c542441244754" + "243132756e6c696e6b5f6368756e6b31376839333465336463333833626235" + "3861334529455f5a4e3373746433737973396261636b747261636532365f5f" + "727573745f656e645f73686f72745f6261636b747261636531376834646333" + "646534376432323032316239452a585f5a4e337374643970616e69636b696e" + "673139626567696e5f70616e69635f68616e646c657232385f247537622424" + "75376224636c6f737572652475376424247537642431376865313761333937" + "376638396331313738452b3b5f5a4e337374643970616e69636b696e673230" + "727573745f70616e69635f776974685f686f6f6b3137683737366537396339" + "6636353931626535452c83015f5a4e39395f244c54247374642e2e70616e69" + "636b696e672e2e626567696e5f70616e69635f68616e646c65722e2e537461" + "7469635374725061796c6f6164247532302461732475323024636f72652e2e" + "70616e69632e2e50616e69635061796c6f6164244754243661735f73747231" + "376865623366373232643232346534326638452d066d656d63707907120100" + "0f5f5f737461636b5f706f696e746572090a0100072e726f64617461005509" + "70726f64756365727302086c616e6775616765010452757374000c70726f63" + "65737365642d62790105727573746325312e38332e302d6e696768746c7920" + "2863326637346333663920323032342d30392d30392900490f746172676574" + "5f6665617475726573042b0a6d756c746976616c75652b0f6d757461626c65" + "2d676c6f62616c732b0f7265666572656e63652d74797065732b087369676e" + "2d657874"; + +extern std::string const hfPerfTest = + "0061736d0100000001190460057f7f7f7f7f017f60047f7f7f7f017f6000006000017f0236" + "0303656e7609666c6f61745f6c6f67000003656e76057472616365000003656e7612747261" + "63655f6f70617175655f666c6f617400010303020203050301000206aa011c7f0041b0090b" + "7f004193090b7f0041b0080b7f0041c0080b7f0041e0080b7f004180090b7f004180080b7f" + "004184080b7f004188080b7f00418c080b7f004190080b7f004194080b7f004198080b7f00" + "419c080b7f0041a0080b7f0041a4080b7f0041a8080b7f0041ac080b7f00419b090b7f0041" + "80080b7f0041b0110b7f0041b0110b7f0041b091040b7f004180080b7f0041b091040b7f00" + "418080080b7f0041000b7f0041010b0785031f066d656d6f72790200115f5f7761736d5f63" + "616c6c5f63746f727300030666696e697368000403627566030001610301086572725f6865" + "61640302096572725f6461746131030305696e707574030406726573756c74030508495445" + "525f4d4158030609484153485f53495a450307084143435f53495a4503080d43555252454e" + "43595f53495a4503090b4b45594c45545f53495a45030a0a53465f4163636f756e74030b0e" + "53465f44657374696e6174696f6e030c0853465f4d656d6f73030d0753465f4d656d6f030e" + "0b53465f4d656d6f44617461030f0753465f4461746103101753465f417574686f72697a65" + "43726564656e7469616c730311016203120c5f5f64736f5f68616e646c6503130a5f5f6461" + "74615f656e6403140b5f5f737461636b5f6c6f7703150c5f5f737461636b5f686967680316" + "0d5f5f676c6f62616c5f6261736503170b5f5f686561705f6261736503180a5f5f68656170" + "5f656e6403190d5f5f6d656d6f72795f62617365031a0c5f5f7461626c655f62617365031b" + "0a7c0202000b7701017f41807821000340200041b0116a4200370300200041086a22000d00" + "0b41c0843d210002400340419309410841b009418008410010004108460440200041016b22" + "000d010c020b0b41b008410f41c0084113410010011a0b41e0084111419309410810021a41" + "8009411241b009410810021a41010b0b9f0104004180080b53809698002000000014000000" + "1400000020000000010008000300080009000f000a000e000d0007001b0007001a000f0066" + "6c6f61745f6c6f67206572726f7200696e76616c69642072657475726e2073697a650041e0" + "080b11666c6f61745f6c6f6720696e7075743a20004180090b12666c6f61745f6c6f672072" + "6573756c743a20004193090b10d48b29430a256d21d920c49ba5e353f8007f0970726f6475" + "63657273010c70726f6365737365642d62790105636c616e675f31392e312e352d77617369" + "2d73646b202868747470733a2f2f6769746875622e636f6d2f6c6c766d2f6c6c766d2d7072" + "6f6a6563742061623462356132646235383239353861663165653330386137393063666462" + "3432626432343732302900490f7461726765745f6665617475726573042b0f6d757461626c" + "652d676c6f62616c732b087369676e2d6578742b0f7265666572656e63652d74797065732b" + "0a6d756c746976616c7565"; + +extern std::string const allKeyletsWasmHex = + "0061736d0100000001530a60057f7f7f7f7f017f60047f7f7f7f017f60067f7f7f7f7f7f01" + "7f60037f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7e017f60077f7f7f7f7f7f7f01" + "7f60057f7f7f7f7f006000017f60037f7f7f000284051808686f73745f6c69620974726163" + "655f6e756d000508686f73745f6c6962057472616365000008686f73745f6c696210636163" + "68655f6c65646765725f6f626a000308686f73745f6c6962146765745f6c65646765725f6f" + "626a5f6669656c64000108686f73745f6c69621c6765745f63757272656e745f6c65646765" + "725f6f626a5f6669656c64000308686f73745f6c69620d74726163655f6163636f756e7400" + "0108686f73745f6c69620e6163636f756e745f6b65796c6574000108686f73745f6c69620b" + "6c696e655f6b65796c6574000408686f73745f6c69620a616d6d5f6b65796c657400020868" + "6f73745f6c69620c636865636b5f6b65796c6574000008686f73745f6c6962116372656465" + "6e7469616c5f6b65796c6574000408686f73745f6c69620f64656c65676174655f6b65796c" + "6574000208686f73745f6c6962166465706f7369745f707265617574685f6b65796c657400" + "0208686f73745f6c69620a6469645f6b65796c6574000108686f73745f6c69620d65736372" + "6f775f6b65796c6574000008686f73745f6c6962136d70745f69737375616e63655f6b6579" + "6c6574000008686f73745f6c69620e6d70746f6b656e5f6b65796c6574000208686f73745f" + "6c6962106e66745f6f666665725f6b65796c6574000008686f73745f6c69620c6f66666572" + "5f6b65796c6574000008686f73745f6c69620e7061796368616e5f6b65796c657400060868" + "6f73745f6c69621a7065726d697373696f6e65645f646f6d61696e5f6b65796c6574000008" + "686f73745f6c69620e7369676e6572735f6b65796c6574000108686f73745f6c69620d7469" + "636b65745f6b65796c6574000008686f73745f6c69620c7661756c745f6b65796c65740000" + "03040307080905030100110619037f01418080c0000b7f0041958bc0000b7f0041a08bc000" + "0b073e05066d656d6f727902000d6f626a6563745f65786973747300180666696e69736800" + "190a5f5f646174615f656e6403010b5f5f686561705f6261736503020ae53503900602047f" + "037e230041f0006b22052400024020012d0000410146044041c280c0004116200128020422" + "01ac10001a200041013a0000200020013602040c010b200541186a200141196a2900003703" + "00200541106a200141116a290000370300200541086a200141096a29000037030020052001" + "2900013703002002200320054120410110011a02402005412041001002220141004a044002" + "400240024002402004450440418b80c000410f4285801410001a200541d8006a4200370300" + "200541d0006a4200370300200541c8006a4200370300200542003703402001418580142005" + "41406b4120100322014120460d0141a680c0004115417f20012001417f4e1b2201ac10001a" + "200041013a0000200020013602040c070b418b80c000410f2004ac10001a200541d0006a41" + "00360200200541c8006a42003703002005420037034020012004200541406b411410032201" + "417e47044020014114460d04200141004e0d0241ad8ac00041172001ac10001a0c030b417e" + "21010c020b200541286a200541cf006a22012900002209370300200541306a200541d7006a" + "2202290000220a370300200541386a200541df006a22032d000022043a0000200520052900" + "47220b37032020052f014021062005280142210720052d0046210820012009370000200220" + "0a370000200320043a0000200520083a004620052007360142200520063b01402005200b37" + "0047419a80c000410c200541406b4120410110011a0c040b41c48ac0004131421410001a41" + "f58ac00041202001ad10001a417321010b41a680c00041152001ac10001a200041013a0000" + "200020013602040c030b200520052900473703602005200541cc006a220129000037006520" + "0520052f014022023b016e2005200529036037032020052005290065370025200528004321" + "03200520052d00423a0042200520023b014020052003360043200120052900253700002005" + "2005290320370047419a80c000410c200541406b4114410110011a0c010b41bb80c0004107" + "2001ac10001a200041013a0000200020013602040c010b20004180023b01000b200541f000" + "6a24000bd92802077f027e23004180076b2200240041d880c000412341004100410010011a" + "20004198016a2201410036020020004190016a220242003703002000420037038801024020" + "00027f02404181802020004188016a22044114100422034114460440200041066a20002d00" + "8a013a00002000200029008f013703e001200020004194016a22052900003700e501200041" + "106a20002900e501370000200020002f0188013b01042000200028008b0136000720002000" + "2903e00137000b41fb80c0004108200041046a2206411410051a2001410036020020024200" + "37030020004200370388014183802020044114100422034114470d032000411a6a20002d00" + "8a013a00002000200029008f013703e001200020052900003700e501200041246a20002900" + "e501370000200020002f0188013b01182000200028008b0136001b200020002903e0013700" + "1f418381c000410c200041186a411410051a200041a0016a22054200370300200142003703" + "002002420037030020004200370388012006411420044120100622034120460d0102402003" + "4100480440200020033602300c010b2000417f3602300b41010c020b0c020b200041c5006a" + "20052903003700002000413d6a2001290300370000200041356a2002290300370000200020" + "002903880137002d41000b3a002c20004188016a2000412c6a418f81c00041074181802010" + "18024020002d0088014101460440200028028c01210341878ac0004112420510001a0c010b" + "41002103419681c000413541004100410010011a200041de006a41c4003a0000200041d800" + "6a4100360200200041e3006a41003a0000200041d5a6013b015c2000420037035020004100" + "36005f200041a0016a2202420037030020004198016a2204420037030020004190016a2205" + "420037030020004200370388010240200041046a4114200041186a4114200041d0006a4114" + "20004188016a4120100722014120470440024020014100480440200020013602680c010b20" + "00417f3602680b410121030c010b200041fd006a2002290300370000200041f5006a200429" + "0300370000200041ed006a200529030037000020002000290388013700650b200020033a00" + "6420004188016a200041e4006a41cb81c00041094100101820002d00880141014604402000" + "28028c01210341878ac0004112420510001a0c010b41d481c000413741004100410010011a" + "200041f0016a200041286a2203280100360200200041e8016a200041206a22042901003703" + "00200041fc016a200041d8006a290300220737020020004184026a200041e0006a28020022" + "02360200200020002901183703e0012000200029035022083702f401200041e8066a220120" + "02360200200041e0066a22022007370300200020083703d806200041f4066a200429010037" + "0200200041fc066a2003280100360200200020002901183702ec0620004188026a200041d8" + "066a22034128101a2000418c016a200041e0016a41d000101a2000410136028801200041f0" + "066a220442003703002001420037030020024200370300200042003703d8062000027f4199" + "8ac0004114200041b4016a4128200341201008220341204704400240200341004804402000" + "20033602e4010c010b2000417f3602e4010b41010c010b200041f9016a2004290300370000" + "200041f1016a2001290300370000200041e9016a2002290300370000200020002903d80637" + "00e10141000b3a00e001200041b4026a200041e0016a418b82c00041034181802010182000" + "2d00b402410146044020002802b802210341878ac0004112420610001a0c010b4100210341" + "8e82c000413141004100410010011a200041f8016a22024200370300200041f0016a220442" + "00370300200041e8016a22054200370300200042003703e0010240200041046a4114410620" + "0041e0016a4120100922014120470440024020014100480440200020013602c0020c010b20" + "00417f3602c0020b410121030c010b200041d5026a2002290300370000200041cd026a2004" + "290300370000200041c5026a2005290300370000200020002903e0013700bd020b20002003" + "3a00bc02200041e0016a200041bc026a41bf82c000410541818020101820002d00e0014101" + "46044020002802e401210341878ac0004112420610001a0c010b4100210341c482c0004133" + "41004100410010011a200041f8016a22024200370300200041f0016a220442003703002000" + "41e8016a22054200370300200042003703e0010240200041046a220141142001411441f782" + "c0004112200041e0016a4120100a22014120470440024020014100480440200020013602e4" + "020c010b2000417f3602e4020b410121030c010b200041f9026a2002290300370000200041" + "f1026a2004290300370000200041e9026a2005290300370000200020002903e0013700e102" + "0b200020033a00e002200041e0016a200041e0026a418983c000410a41988020101820002d" + "00e001410146044020002802e401210341878ac0004112420710001a0c010b410021034193" + "83c000413841004100410010011a200041f8016a22024200370300200041f0016a22044200" + "370300200041e8016a22054200370300200042003703e0010240200041046a411420004118" + "6a4114200041e0016a4120100b220141204704400240200141004804402000200136028803" + "0c010b2000417f360288030b410121030c010b2000419d036a200229030037000020004195" + "036a20042903003700002000418d036a2005290300370000200020002903e001370085030b" + "200020033a008403200041e0016a20004184036a41cb83c000410841818020101820002d00" + "e001410146044020002802e401210341878ac0004112420810001a0c010b41d383c0004136" + "41004100410010011a230041206b22012400200141186a22044200370300200141106a2205" + "4200370300200141086a2206420037030020014200370300200041a8036a2202027f200041" + "046a4114200041186a411420014120100c2203412047044002402003410048044020022003" + "3602040c010b2002417f3602040b41010c010b20022001290300370001200241196a200429" + "0300370000200241116a2005290300370000200241096a200629030037000041000b3a0000" + "200141206a2400200041e0016a2002418984c000410e41818020101820002d00e001410146" + "044020002802e401210341878ac0004112420910001a0c010b419784c000413c4100410041" + "0010011a230041206b22012400200141186a22044200370300200141106a22054200370300" + "200141086a2206420037030020014200370300200041cc036a2202027f200041046a411420" + "014120100d22034120470440024020034100480440200220033602040c010b2002417f3602" + "040b41010c010b20022001290300370001200241196a2004290300370000200241116a2005" + "290300370000200241096a200629030037000041000b3a0000200141206a2400200041e001" + "6a200241d384c000410341818020101820002d00e001410146044020002802e40121034187" + "8ac0004112420a10001a0c010b41d684c000413141004100410010011a230041206b220124" + "00200141186a22044200370300200141106a22054200370300200141086a22064200370300" + "20014200370300200041f0036a2202027f200041046a4114410b20014120100e2203412047" + "0440024020034100480440200220033602040c010b2002417f3602040b41010c010b200220" + "01290300370001200241196a2004290300370000200241116a200529030037000020024109" + "6a200629030037000041000b3a0000200141206a2400200041e0016a2002418785c0004106" + "41818020101820002d00e001410146044020002802e401210341878ac0004112420b10001a" + "0c010b418d85c000413441004100410010011a230041206b22012400200141186a22044200" + "370300200141106a22054200370300200141086a2206420037030020014200370300200041" + "94046a2202027f200041046a4114410c20014120100f220341204704400240200341004804" + "40200220033602040c010b2002417f3602040b41010c010b20022001290300370001200241" + "196a2004290300370000200241116a2005290300370000200241096a200629030037000041" + "000b3a0000200141206a2400200041f4016a200041146a280100360200200041ec016a2000" + "410c6a290100370200200020002901043702e401200041808080e0003602e001200041d806" + "6a200241c185c000410b41848020101820002d00d806410146044020002802dc0621034187" + "8ac0004112420c10001a0c010b41cc85c000413941004100410010011a230041206b220124" + "00200141186a22044200370300200141106a22054200370300200141086a22064200370300" + "20014200370300200041b8046a2202027f200041e0016a4118200041186a41142001412010" + "1022034120470440024020034100480440200220033602040c010b2002417f3602040b4101" + "0c010b20022001290300370001200241196a2004290300370000200241116a200529030037" + "0000200241096a200629030037000041000b3a0000200141206a2400200041d8066a200241" + "8586c000410741818020101820002d00d806410146044020002802dc06210341878ac00041" + "12420d10001a0c010b418c86c000413541004100410010011a230041206b22012400200141" + "186a22044200370300200141106a22054200370300200141086a2206420037030020014200" + "370300200041dc046a2202027f200041186a41144106200141201011220341204704400240" + "20034100480440200220033602040c010b2002417f3602040b41010c010b20022001290300" + "370001200241196a2004290300370000200241116a2005290300370000200241096a200629" + "030037000041000b3a0000200141206a2400200041d8066a200241c186c000410c41828020" + "101820002d00d806410146044020002802dc06210341878ac0004112420d10001a0c010b41" + "cd86c000413a41004100410010011a230041206b22012400200141186a2204420037030020" + "0141106a22054200370300200141086a220642003703002001420037030020004180056a22" + "02027f200041046a4114410d20014120101222034120470440024020034100480440200220" + "033602040c010b2002417f3602040b41010c010b20022001290300370001200241196a2004" + "290300370000200241116a2005290300370000200241096a200629030037000041000b3a00" + "00200141206a2400200041d8066a2002418787c000410541818020101820002d00d8064101" + "46044020002802dc06210341878ac0004112420d10001a0c010b418c87c000413341004100" + "410010011a230041206b22012400200141186a22044200370300200141106a220542003703" + "00200141086a2206420037030020014200370300200041a4056a2202027f200041046a4114" + "200041186a4114410e20014120101322034120470440024020034100480440200220033602" + "040c010b2002417f3602040b41010c010b20022001290300370001200241196a2004290300" + "370000200241116a2005290300370000200241096a200629030037000041000b3a00002001" + "41206a2400200041d8066a200241bf87c000410a41818020101820002d00d8064101460440" + "20002802dc06210341878ac0004112420e10001a0c010b41c987c000413841004100410010" + "011a230041206b22012400200141186a22044200370300200141106a220542003703002001" + "41086a2206420037030020014200370300200041c8056a2202027f200041046a4114410f20" + "014120101422034120470440024020034100480440200220033602040c010b2002417f3602" + "040b41010c010b20022001290300370001200241196a2004290300370000200241116a2005" + "290300370000200241096a200629030037000041000b3a0000200141206a2400200041d806" + "6a2002418188c000411241828020101820002d00d806410146044020002802dc0621034187" + "8ac0004112420f10001a0c010b419388c00041c00041004100410010011a230041206b2201" + "2400200141186a22044200370300200141106a22054200370300200141086a220642003703" + "0020014200370300200041ec056a2202027f200041046a4114200141201015220341204704" + "40024020034100480440200220033602040c010b2002417f3602040b41010c010b20022001" + "290300370001200241196a2004290300370000200241116a2005290300370000200241096a" + "200629030037000041000b3a0000200141206a2400200041d8066a200241d388c000410a41" + "00101820002d00d806410146044020002802dc06210341878ac0004112421010001a0c010b" + "41dd88c000413841004100410010011a230041206b22012400200141186a22044200370300" + "200141106a22054200370300200141086a220642003703002001420037030020004190066a" + "2202027f200041046a41144112200141201016220341204704400240200341004804402002" + "20033602040c010b2002417f3602040b41010c010b20022001290300370001200241196a20" + "04290300370000200241116a2005290300370000200241096a200629030037000041000b3a" + "0000200141206a2400200041d8066a2002419589c000410641818020101820002d00d80641" + "0146044020002802dc06210341878ac0004112421210001a0c010b419b89c0004134410041" + "00410010011a230041206b22012400200141186a22044200370300200141106a2205420037" + "0300200141086a2206420037030020014200370300200041b4066a2202027f200041046a41" + "14411320014120101722034120470440024020034100480440200220033602040c010b2002" + "417f3602040b41010c010b20022001290300370001200241196a2004290300370000200241" + "116a2005290300370000200241096a200629030037000041000b3a0000200141206a240020" + "0041d8066a200241cf89c00041054181802010184101210320002d00d80641014604402000" + "2802dc06210341878ac0004112421310001a0c010b41d489c000413341004100410010011a" + "0b20004180076a240020030f0b418080c000410b417f20032003417f4e1bac1000000bf506" + "010b7f230041106b2106200241104f0440024020002000410020006b41037122056a22044f" + "0d002001210320050440200521070340200020032d00003a0000200341016a210320004101" + "6a2100200741016b22070d000b0b200541016b4107490d000340200020032d00003a000020" + "0041016a200341016a2d00003a0000200041026a200341026a2d00003a0000200041036a20" + "0341036a2d00003a0000200041046a200341046a2d00003a0000200041056a200341056a2d" + "00003a0000200041066a200341066a2d00003a0000200041076a200341076a2d00003a0000" + "200341086a2103200041086a22002004470d000b0b2004200220056b220b417c71220c6a21" + "000240200120056a22034103712201450440200020044d0d01200321010340200420012802" + "00360200200141046a2101200441046a22042000490d000b0c010b41002102200641003602" + "0c2006410c6a2001722105410420016b22074101710440200520032d00003a000041012102" + "0b20074102710440200220056a200220036a2f01003b01000b200320016b21022001410374" + "2107200628020c210902402000200441046a4d0440200421050c010b410020076b41187121" + "08034020042009200776200241046a2202280200220920087472360200200441086a210a20" + "0441046a220521042000200a4b0d000b0b41002104200641003a0008200641003a0006027f" + "200141014604404100210141002108200641086a0c010b200241056a2d0000200620024104" + "6a2d000022013a000841087421084102210d200641066a0b210a20052003410171047f200a" + "200241046a200d6a2d00003a000020062d0006411074210420062d00080520010b41ff0171" + "200420087272410020076b411871742009200776723602000b200b41037121022003200c6a" + "21010b02402000200020026a22044f0d002002410771220304400340200020012d00003a00" + "00200141016a2101200041016a2100200341016b22030d000b0b200241016b4107490d0003" + "40200020012d00003a0000200041016a200141016a2d00003a0000200041026a200141026a" + "2d00003a0000200041036a200141036a2d00003a0000200041046a200141046a2d00003a00" + "00200041056a200141056a2d00003a0000200041066a200141066a2d00003a000020004107" + "6a200141076a2d00003a0000200141086a2101200041086a22002004470d000b0b0b0b930b" + "0200418080c0000b990a6572726f725f636f64653d47657474696e67206669656c643a2046" + "69656c6420646174613a204572726f722067657474696e67206669656c643a204572726f72" + "3a204572726f722067657474696e67206b65796c65743a202424242424205354415254494e" + "47205741534d20455845435554494f4e2024242424244163636f756e743a44657374696e61" + "74696f6e3a4163636f756e744163636f756e74206f626a656374206578697374732c207072" + "6f63656564696e67207769746820657363726f772066696e6973682e54727573746c696e65" + "54727573746c696e65206f626a656374206578697374732c2070726f63656564696e672077" + "69746820657363726f772066696e6973682e414d4d414d4d206f626a656374206578697374" + "732c2070726f63656564696e67207769746820657363726f772066696e6973682e43686563" + "6b436865636b206f626a656374206578697374732c2070726f63656564696e672077697468" + "20657363726f772066696e6973682e7465726d73616e64636f6e646974696f6e7343726564" + "656e7469616c43726564656e7469616c206f626a656374206578697374732c2070726f6365" + "6564696e67207769746820657363726f772066696e6973682e44656c656761746544656c65" + "67617465206f626a656374206578697374732c2070726f63656564696e6720776974682065" + "7363726f772066696e6973682e4465706f736974507265617574684465706f736974507265" + "61757468206f626a656374206578697374732c2070726f63656564696e6720776974682065" + "7363726f772066696e6973682e444944444944206f626a656374206578697374732c207072" + "6f63656564696e67207769746820657363726f772066696e6973682e457363726f77457363" + "726f77206f626a656374206578697374732c2070726f63656564696e672077697468206573" + "63726f772066696e6973682e4d505449737375616e63654d505449737375616e6365206f62" + "6a656374206578697374732c2070726f63656564696e67207769746820657363726f772066" + "696e6973682e4d50546f6b656e4d50546f6b656e206f626a656374206578697374732c2070" + "726f63656564696e67207769746820657363726f772066696e6973682e4e46546f6b656e4f" + "666665724e46546f6b656e4f66666572206f626a656374206578697374732c2070726f6365" + "6564696e67207769746820657363726f772066696e6973682e4f666665724f66666572206f" + "626a656374206578697374732c2070726f63656564696e67207769746820657363726f7720" + "66696e6973682e5061794368616e6e656c5061794368616e6e656c206f626a656374206578" + "697374732c2070726f63656564696e67207769746820657363726f772066696e6973682e50" + "65726d697373696f6e6564446f6d61696e5065726d697373696f6e6564446f6d61696e206f" + "626a656374206578697374732c2070726f63656564696e67207769746820657363726f7720" + "66696e6973682e5369676e65724c6973745369676e65724c697374206f626a656374206578" + "697374732c2070726f63656564696e67207769746820657363726f772066696e6973682e54" + "69636b65745469636b6574206f626a656374206578697374732c2070726f63656564696e67" + "207769746820657363726f772066696e6973682e5661756c745661756c74206f626a656374" + "206578697374732c2070726f63656564696e67207769746820657363726f772066696e6973" + "682e43757272656e74207365712076616c75653a0041ad8ac0000b68456e636f756e746572" + "6564206572726f725f636f64653a4279746520617272617920776173206578706563746564" + "20746f20686176652074686973206d616e792062797465733a204279746520617272617920" + "6861642074686973206d616e792062797465733a20004d0970726f64756365727302086c61" + "6e6775616765010452757374000c70726f6365737365642d6279010572757374631d312e39" + "302e30202831313539653738633420323032352d30392d313429002c0f7461726765745f66" + "65617475726573022b0f6d757461626c652d676c6f62616c732b087369676e2d657874"; + +extern std::string const codecovTestsWasmHex = + "0061736d0100000001570b60047f7f7f7f017f60057f7f7f7f7f017f60027f7f017f60067f" + "7f7f7f7f7f017f60077f7f7f7f7f7f7f017f6000017f60037f7f7f017f60017f017f60087f" + "7f7f7f7f7f7f7f017f60037f7f7e017f60047f7f7f7f0002990d3c08686f73745f6c696205" + "7472616365000108686f73745f6c69620974726163655f6e756d000908686f73745f6c6962" + "0e6765745f6c65646765725f73716e000508686f73745f6c6962166765745f706172656e74" + "5f6c65646765725f74696d65000508686f73745f6c6962166765745f706172656e745f6c65" + "646765725f68617368000208686f73745f6c69620c6765745f626173655f66656500050868" + "6f73745f6c696211616d656e646d656e745f656e61626c6564000208686f73745f6c69620c" + "6765745f74785f6669656c64000608686f73745f6c69620e6163636f756e745f6b65796c65" + "74000008686f73745f6c69621063616368655f6c65646765725f6f626a000608686f73745f" + "6c69621c6765745f63757272656e745f6c65646765725f6f626a5f6669656c64000608686f" + "73745f6c6962146765745f6c65646765725f6f626a5f6669656c64000008686f73745f6c69" + "62136765745f74785f6e65737465645f6669656c64000008686f73745f6c6962236765745f" + "63757272656e745f6c65646765725f6f626a5f6e65737465645f6669656c64000008686f73" + "745f6c69621b6765745f6c65646765725f6f626a5f6e65737465645f6669656c6400010868" + "6f73745f6c6962106765745f74785f61727261795f6c656e000708686f73745f6c69622067" + "65745f63757272656e745f6c65646765725f6f626a5f61727261795f6c656e000708686f73" + "745f6c6962186765745f6c65646765725f6f626a5f61727261795f6c656e000208686f7374" + "5f6c6962176765745f74785f6e65737465645f61727261795f6c656e000208686f73745f6c" + "6962276765745f63757272656e745f6c65646765725f6f626a5f6e65737465645f61727261" + "795f6c656e000208686f73745f6c69621f6765745f6c65646765725f6f626a5f6e65737465" + "645f61727261795f6c656e000608686f73745f6c69620b7570646174655f64617461000208" + "686f73745f6c696213636f6d707574655f7368613531325f68616c66000008686f73745f6c" + "696209636865636b5f736967000308686f73745f6c6962076765745f6e6674000308686f73" + "745f6c69620e6765745f6e66745f697373756572000008686f73745f6c69620d6765745f6e" + "66745f7461786f6e000008686f73745f6c69620d6765745f6e66745f666c61677300020868" + "6f73745f6c6962146765745f6e66745f7472616e736665725f666565000208686f73745f6c" + "69620e6765745f6e66745f73657269616c000008686f73745f6c69620d74726163655f6163" + "636f756e74000008686f73745f6c69620c74726163655f616d6f756e74000008686f73745f" + "6c69620f666c6f61745f66726f6d5f75696e74000108686f73745f6c69620b6c696e655f6b" + "65796c6574000808686f73745f6c69620a616d6d5f6b65796c6574000308686f73745f6c69" + "621163726564656e7469616c5f6b65796c6574000808686f73745f6c69620e6d70746f6b65" + "6e5f6b65796c6574000308686f73745f6c69621274726163655f6f70617175655f666c6f61" + "74000008686f73745f6c69620d666c6f61745f636f6d70617265000008686f73745f6c6962" + "09666c6f61745f616464000408686f73745f6c69620e666c6f61745f737562747261637400" + "0408686f73745f6c69620e666c6f61745f6d756c7469706c79000408686f73745f6c69620c" + "666c6f61745f646976696465000408686f73745f6c69620a666c6f61745f726f6f74000308" + "686f73745f6c696209666c6f61745f706f77000308686f73745f6c696209666c6f61745f6c" + "6f67000108686f73745f6c69620c636865636b5f6b65796c6574000108686f73745f6c6962" + "0f64656c65676174655f6b65796c6574000308686f73745f6c6962166465706f7369745f70" + "7265617574685f6b65796c6574000308686f73745f6c69620a6469645f6b65796c65740000" + "08686f73745f6c69620d657363726f775f6b65796c6574000108686f73745f6c6962136d70" + "745f69737375616e63655f6b65796c6574000108686f73745f6c6962106e66745f6f666665" + "725f6b65796c6574000108686f73745f6c69620c6f666665725f6b65796c6574000108686f" + "73745f6c69620d6f7261636c655f6b65796c6574000108686f73745f6c69620e7061796368" + "616e5f6b65796c6574000408686f73745f6c69621a7065726d697373696f6e65645f646f6d" + "61696e5f6b65796c6574000108686f73745f6c69620e7369676e6572735f6b65796c657400" + "0008686f73745f6c69620d7469636b65745f6b65796c6574000108686f73745f6c69620c76" + "61756c745f6b65796c657400010303020a0505030100110619037f01418080c0000b7f0041" + "f69dc0000b7f0041809ec0000b072e04066d656d6f727902000666696e697368003d0a5f5f" + "646174615f656e6403010b5f5f686561705f6261736503020ac12a02460002402000200147" + "04402002200341004100410010001a20004100480d01418b80c000410b2000ad1001000b20" + "0220032000ac10011a0f0b418b80c000410b2000ac1001000bf72902087f027e230041f001" + "6b22002400419680c000412341004100410010001a100241b9e00041b980c000410e103c10" + "0341b2920441c780c0004116103c200041f0006a22034200370300200041e8006a22044200" + "370300200041e0006a2202420037030020004200370358200041d8006a2201412010044120" + "41a58cc0004116103c1005410a41dd80c000410c103c200041186a428182848890a0c08001" + "370300200041106a428182848890a0c08001370300200041086a428182848890a0c0800137" + "03002000428182848890a0c0800137030041e980c000410e1006410141f780c0004111103c" + "200041201006410141f780c0004111103c2004410036020020024200370300200042003703" + "5841818020200141141007220541144604400240200041266a20002d005a3a000020002000" + "29005f3703c8012000200041e4006a2900003700cd01200041306a20002900cd0137000020" + "0020002f01583b01242000200028005b360027200020002903c80137002b20034200370300" + "200442003703002002420037030020004200370358200041246a4114200141201008220541" + "20470d002000413a6a20002d005a3a0000200041d0016a200041e7006a2900002208370300" + "200041d8016a200041ef006a2900002209370300200041c7006a2008370000200041cf006a" + "2009370000200041d7006a200041f7006a2d00003a0000200020002f01583b013820002000" + "28005b36003b2000200029005f37003f200041386a4120410010094101418881c000411010" + "3c2004410036020020024200370300200042003703584181802020014114100a411441bb8c" + "c000411c103c20044100360200200242003703002000420037035841014181802020014114" + "100b411441d78cc0004114103c02402001410020016b41037122046a220220014d0d002004" + "0440200421050340200141003a0000200141016a2101200541016b22050d000b0b20044101" + "6b4107490d000340200141003a0000200141076a41003a0000200141066a41003a00002001" + "41056a41003a0000200141046a41003a0000200141036a41003a0000200141026a41003a00" + "00200141016a41003a0000200141086a22012002470d000b0b200241c40020046b2204417c" + "716a220120024b0440034020024100360200200241046a22022001490d000b0b0240200120" + "04410371220420016a22054f0d002004220204400340200141003a0000200141016a210120" + "0241016b22020d000b0b200441016b4107490d000340200141003a0000200141076a41003a" + "0000200141066a41003a0000200141056a41003a0000200141046a41003a0000200141036a" + "41003a0000200141026a41003a0000200141016a41003a0000200141086a22012005470d00" + "0b0b2000418180203602c801410021010340200641c000490440200041d8006a20066a2000" + "41c8016a20016a2d00003a0000200020002802980141016a220636029801200141016a2201" + "4104470d010b0b200041d8016a22024100360200200041d0016a2203420037030020004200" + "3703c801200041d8006a22012006200041c8016a22054114100c411441eb8cc0004113103c" + "2002410036020020034200370300200042003703c801200120002802980120054114100d41" + "1441fe8cc0004123103c2002410036020020034200370300200042003703c8014101200120" + "002802980120054114100e411441a18dc000411b103c4189803c100f4120419881c0004110" + "103c4189803c1010412041a881c0004120103c41014189803c1011412041c881c000411810" + "3c20012000280298011012412041e081c0004117103c20012000280298011013412041f781" + "c0004127103c4101200120002802980110144120419e82c000411f103c200041246a220441" + "141015410041bd82c000410b103c200041e0016a2206420037030020024200370300200342" + "00370300200042003703c8012001200028029801200541201016412041bc8dc0004113103c" + "41c882c000410c41d482c000410b41df82c000410e1017410141ed82c0004109103c200041" + "b8016a200041186a290300370300200041b0016a200041106a290300370300200041a8016a" + "200041086a290300370300200020002903003703a001200241003b01002003420037030020" + "0042003703c80120044114200041a0016a22074120200541121018411241cf8dc000410710" + "3c2002410036020020034200370300200042003703c80120074120200541141019411441d6" + "8dc000410e103c200041003602c8012007412020054104101a410441e48dc000410d103c20" + "074120101b410841f682c000410d103c20074120101c410a418383c0004114103c20004100" + "3602c8012007412020054104101d410441f18dc000410e103c419783c000410d2004411410" + "1e412f41a483c000410d103c419783c000410d41b183c0004108101f411341b983c000410c" + "103c417f41041004417141c583c000411e103c200041003602c8012005417f1004417141ff" + "8dc000411e103c200041ca016a41003a0000200041003b01c801200541031004417d419d8e" + "c0004124103c200041003602c8012005418094ebdc031004417341c18ec0004123103c4197" + "83c000410d20044114101e412f41a483c000410d103c419783c000410d41b183c000410810" + "1f411341b983c000410c103c20064200370300200242003703002003420037030020004200" + "3703c801200041d894ebdc036a220741082005412041001020417341e48ec0004117103c20" + "0642003703002002420037030020034200370300200042003703c801200120002802980120" + "05412041001020417141fb8ec0004119103c4102100f416f41e383c000411f103c417f2000" + "2802980110124171418284c000411f103c2001417f1012417141a184c000411f103c200141" + "81201012417441c084c0004120103c20072000280298011012417341e084c000411f103c20" + "0720002802980141011009417341ff84c0004118103c200120002802980141011009417141" + "9785c000411a103c200642003703002002420037030020034200370300200042003703c801" + "2007200028029801200541201008417341948fc0004116103c200642003703002002420037" + "030020034200370300200042003703c8012001200028029801200541201008417141aa8fc0" + "004118103c200642003703002002420037030020034200370300200042003703c801200441" + "14200441142007200028029801200541201021417341c28fc000411c103c20064200370300" + "2002420037030020034200370300200042003703c801200441142004411420012000280298" + "01200541201021417141de8fc000411e103c20064200370300200242003703002003420037" + "0300200042003703c80141e29dc00041142007200028029801200541201022417341fc8fc0" + "004119103c200642003703002002420037030020034200370300200042003703c80141e29d" + "c000411420012000280298012005412010224171419590c000411f103c2006420037030020" + "02420037030020034200370300200042003703c80141e29dc000411441b185c00041142005" + "41201022417141b490c0004129103c20064200370300200242003703002003420037030020" + "0042003703c80141c585c000412841e29dc0004114200541201022417141dd90c000412510" + "3c200041dc016a200041346a280100360200200041d4016a2000412c6a2901003702002000" + "20002901243702cc01200041808080083602c801200041003b01c0012005411841e29dc000" + "4114200041c0016a2203410210224171418291c000410e103c2007200028029801422a1001" + "417341ed85c0004111103c200041003b01c0014102200341021007416f419091c000411b10" + "3c200041003b01c001410220034102100a416f41ab91c000412b103c200041003b01c00141" + "01410220034102100b416f41d691c0004123103c4102100f416f41e383c000411f103c4102" + "1010416f41fe85c000412f103c410141021011416f41ad86c0004127103c41e980c0004181" + "201006417441d486c000411f103c41e980c00041c1001006417441f386c000411a103c2000" + "41003b01c001200141812020034102100c417441f991c0004121103c200041003b01c00120" + "0141812020034102100d4174419a92c0004131103c200041003b01c0014101200141812020" + "034102100e417441cb92c0004129103c200141812010124174418d87c0004125103c200141" + "81201013417441b287c0004135103c410120014181201014417441e787c000412d103c2001" + "41812010154174419488c0004119103c419783c00041812041d482c000410b41df82c00041" + "0e1017417441ed82c0004109103c419783c000410d41d482c00041812041df82c000410e10" + "17417441ed82c0004109103c419783c000410d41d482c000410b41df82c000418120101741" + "7441ed82c0004109103c200041003b01c0012001418120200341021016417441f492c00041" + "21103c200041003b01c00141e29dc00041812041e29dc00041142003410210224174419593" + "c0004118103c200041003b01c00120044114200441142001418120200341021023417441ad" + "93c000411f103c200041003b01c001200541812020044114200341021024417441cc93c000" + "4122103c419783c000410d200720002802980141001000417341ad88c000410f103c200042" + "d487b6f4c7d4b1c0003700c001419783c000410d200041c095ebdc036a2206410810254173" + "41bc88c000411c103c419783c000410d2007200028029801101f417341d888c0004116103c" + "20064108200341081026417341ee88c0004118103c200341082006410810264173418689c0" + "004118103c200041003b01ec012006410820034108200041ec016a22024102410010274173" + "41ee93c0004114103c200041003b01ec012003410820064108200241024100102741734182" + "94c0004114103c200041003b01ec01200641082003410820024102410010284173419694c0" + "004119103c200041003b01ec0120034108200641082002410241001028417341af94c00041" + "19103c200041003b01ec0120064108200341082002410241001029417341c894c000411910" + "3c200041003b01ec0120034108200641082002410241001029417341e194c0004119103c20" + "0041003b01ec012006410820034108200241024100102a417341fa94c0004117103c200041" + "003b01ec012003410820064108200241024100102a4173419195c0004117103c200041003b" + "01ec01200641084103200241024100102b417341a895c0004114103c200041003b01ec0120" + "0641084103200241024100102c417341bc95c0004113103c200041003b01ec012006410820" + "0241024100102d417341cf95c0004113103c2001200028029801410010094171419e89c000" + "4123103c200041003b01ec01200441142001200028029801200241021018417141e295c000" + "411a103c200041003b01ec012001200028029801200241021019417141fc95c0004121103c" + "200041003b01ec01200120002802980120024102101a4171419d96c0004120103c20012000" + "28029801101b417141c189c0004120103c2001200028029801101c417141e189c000412710" + "3c200041003602ec01200120002802980120024104101d417141bd96c0004121103c200041" + "003b01ec012001200028029801200241021008417141de96c0004123103c200041003b01ec" + "012001200028029801410120024102102e4171418197c0004121103c200041003b01ec0120" + "0120002802980122062004411420012006200241021023417141a297c0004127103c200041" + "003b01ec01200441142001200028029801220620012006200241021023417141c997c00041" + "27103c200041003b01ec0120012000280298012004411420024102102f417141f097c00041" + "25103c200041003b01ec0120044114200120002802980120024102102f4171419598c00041" + "25103c200041003b01ec01200120002802980120044114200241021030417141ba98c00041" + "2c103c200041003b01ec01200441142001200028029801200241021030417141e698c00041" + "2c103c200041003b01ec0120012000280298012002410210314171419299c000411f103c20" + "0041003b01ec0120012000280298014101200241021032417141b199c0004122103c200041" + "003b01ec0120012000280298012004411441b185c0004114200241021021417141d399c000" + "4121103c200041003b01ec0120044114200120002802980141b185c0004114200241021021" + "417141f499c0004121103c200041003b01ec01200120002802980141012002410210334171" + "41959ac0004128103c200041003b01ec012005411820012000280298012002410210244171" + "41bd9ac0004123103c200041003b01ec0120012000280298014101200241021034417141e0" + "9ac0004125103c200041003b01ec0120012000280298014101200241021035417141859bc0" + "004121103c200041003b01ec0120012000280298014101200241021036417141a69bc00041" + "22103c200041003b01ec012001200028029801200441144101200241021037417141c89bc0" + "004124103c200041003b01ec012004411420012000280298014101200241021037417141ec" + "9bc0004124103c200041003b01ec0120012000280298014101200241021038417141909cc0" + "00412f103c200041003b01ec012001200028029801200241021039417141bf9cc000412310" + "3c200041003b01ec012001200028029801410120024102103a417141e29cc0004122103c20" + "0041003b01ec012001200028029801410120024102103b417141849dc0004121103c200041" + "003b01ec01200120002802980141888ac0004120200241021018417141a59dc000411c103c" + "419783c000410d2001200028029801101e417141a88ac0004122103c419797abdd03410d41" + "888ac000412041001000417341ca8ac0004110103c419797abdd03410d2003410810254173" + "41da8ac000411d103c419797abdd03410d20044114101e417341f78ac0004118103c419797" + "abdd03410d41b183c0004108101f4173418f8bc0004117103c200120002802980120014181" + "2041001000417441a68bc000410e103c200141812042011001417441b48bc0004112103c41" + "9783c000418120200341081025417441c68bc000411b103c419783c0004181202004411410" + "1e417441e18bc0004116103c419783c00041812041b183c0004108101f417441f78bc00041" + "15103c419783c000410d2001200028029801101f4171418c8cc0004119103c200041003b01" + "ec01200120002802980120044114200241021024417141c19dc0004121103c200041f0016a" + "240041010f0b0b418080c000410b417f20052005417f4e1bac1001000b0bcd1d0200418080" + "c0000bc5056572726f725f636f64653d54455354204641494c454424242424242053544152" + "54494e47205741534d20455845435554494f4e2024242424246765745f6c65646765725f73" + "716e6765745f706172656e745f6c65646765725f74696d656765745f626173655f66656574" + "6573745f616d656e646d656e74616d656e646d656e745f656e61626c656463616368655f6c" + "65646765725f6f626a6765745f74785f61727261795f6c656e6765745f63757272656e745f" + "6c65646765725f6f626a5f61727261795f6c656e6765745f6c65646765725f6f626a5f6172" + "7261795f6c656e6765745f74785f6e65737465645f61727261795f6c656e6765745f637572" + "72656e745f6c65646765725f6f626a5f6e65737465645f61727261795f6c656e6765745f6c" + "65646765725f6f626a5f6e65737465645f61727261795f6c656e7570646174655f64617461" + "74657374206d65737361676574657374207075626b657974657374207369676e6174757265" + "636865636b5f7369676765745f6e66745f666c6167736765745f6e66745f7472616e736665" + "725f66656574657374696e6720747261636574726163655f6163636f756e74400000000000" + "005f74726163655f616d6f756e746765745f706172656e745f6c65646765725f686173685f" + "6e65675f7074726765745f74785f61727261795f6c656e5f696e76616c69645f736669656c" + "646765745f74785f6e65737465645f61727261795f6c656e5f6e65675f7074726765745f74" + "785f6e65737465645f61727261795f6c656e5f6e65675f6c656e6765745f74785f6e657374" + "65645f61727261795f6c656e5f746f6f5f6c6f6e676765745f74785f6e65737465645f6172" + "7261795f6c656e5f7074725f6f6f6263616368655f6c65646765725f6f626a5f7074725f6f" + "6f6263616368655f6c65646765725f6f626a5f77726f6e675f6c656e555344303030303030" + "30303030303030303030300041ed85c0000bf51774726163655f6e756d5f6f6f625f737472" + "6765745f63757272656e745f6c65646765725f6f626a5f61727261795f6c656e5f696e7661" + "6c69645f736669656c646765745f6c65646765725f6f626a5f61727261795f6c656e5f696e" + "76616c69645f736669656c64616d656e646d656e745f656e61626c65645f746f6f5f626967" + "5f736c696365616d656e646d656e745f656e61626c65645f746f6f5f6c6f6e676765745f74" + "785f6e65737465645f61727261795f6c656e5f746f6f5f6269675f736c6963656765745f63" + "757272656e745f6c65646765725f6f626a5f6e65737465645f61727261795f6c656e5f746f" + "6f5f6269675f736c6963656765745f6c65646765725f6f626a5f6e65737465645f61727261" + "795f6c656e5f746f6f5f6269675f736c6963657570646174655f646174615f746f6f5f6269" + "675f736c69636574726163655f6f6f625f736c69636574726163655f6f70617175655f666c" + "6f61745f6f6f625f736c69636574726163655f616d6f756e745f6f6f625f736c696365666c" + "6f61745f636f6d706172655f6f6f625f736c69636531666c6f61745f636f6d706172655f6f" + "6f625f736c6963653263616368655f6c65646765725f6f626a5f77726f6e675f73697a655f" + "75696e743235366765745f6e66745f666c6167735f77726f6e675f73697a655f75696e7432" + "35366765745f6e66745f7472616e736665725f6665655f77726f6e675f73697a655f75696e" + "74323536303030303030303030303030303030303030303030303030303030303030303174" + "726163655f6163636f756e745f77726f6e675f73697a655f6163636f756e74696474726163" + "655f6f6f625f737472696e6774726163655f6f70617175655f666c6f61745f6f6f625f7374" + "72696e6774726163655f6163636f756e745f6f6f625f737472696e6774726163655f616d6f" + "756e745f6f6f625f737472696e6774726163655f746f6f5f6c6f6e6774726163655f6e756d" + "5f746f6f5f6c6f6e6774726163655f6f70617175655f666c6f61745f746f6f5f6c6f6e6774" + "726163655f6163636f756e745f746f6f5f6c6f6e6774726163655f616d6f756e745f746f6f" + "5f6c6f6e6774726163655f616d6f756e745f77726f6e675f6c656e6774686765745f706172" + "656e745f6c65646765725f686173686765745f63757272656e745f6c65646765725f6f626a" + "5f6669656c646765745f6c65646765725f6f626a5f6669656c646765745f74785f6e657374" + "65645f6669656c646765745f63757272656e745f6c65646765725f6f626a5f6e6573746564" + "5f6669656c646765745f6c65646765725f6f626a5f6e65737465645f6669656c64636f6d70" + "7574655f7368613531325f68616c666765745f6e66746765745f6e66745f69737375657267" + "65745f6e66745f7461786f6e6765745f6e66745f73657269616c6765745f706172656e745f" + "6c65646765725f686173685f6e65675f6c656e6765745f706172656e745f6c65646765725f" + "686173685f6275665f746f6f5f736d616c6c6765745f706172656e745f6c65646765725f68" + "6173685f6c656e5f746f6f5f6c6f6e67666c6f61745f66726f6d5f75696e745f6c656e5f6f" + "6f62666c6f61745f66726f6d5f75696e745f77726f6e675f6c656e6163636f756e745f6b65" + "796c65745f6c656e5f6f6f626163636f756e745f6b65796c65745f77726f6e675f6c656e6c" + "696e655f6b65796c65745f6c656e5f6f6f625f63757272656e63796c696e655f6b65796c65" + "745f77726f6e675f6c656e5f63757272656e6379616d6d5f6b65796c65745f6c656e5f6f6f" + "625f617373657432616d6d5f6b65796c65745f6c656e5f77726f6e675f6c656e5f61737365" + "7432616d6d5f6b65796c65745f6c656e5f77726f6e675f6e6f6e5f7872705f63757272656e" + "63795f6c656e616d6d5f6b65796c65745f6c656e5f77726f6e675f7872705f63757272656e" + "63795f6c656e616d6d5f6b65796c65745f6d70746765745f74785f6669656c645f696e7661" + "6c69645f736669656c646765745f63757272656e745f6c65646765725f6f626a5f6669656c" + "645f696e76616c69645f736669656c646765745f6c65646765725f6f626a5f6669656c645f" + "696e76616c69645f736669656c646765745f74785f6e65737465645f6669656c645f746f6f" + "5f6269675f736c6963656765745f63757272656e745f6c65646765725f6f626a5f6e657374" + "65645f6669656c645f746f6f5f6269675f736c6963656765745f6c65646765725f6f626a5f" + "6e65737465645f6669656c645f746f6f5f6269675f736c696365636f6d707574655f736861" + "3531325f68616c665f746f6f5f6269675f736c696365616d6d5f6b65796c65745f746f6f5f" + "6269675f736c69636563726564656e7469616c5f6b65796c65745f746f6f5f6269675f736c" + "6963656d70746f6b656e5f6b65796c65745f746f6f5f6269675f736c6963655f6d70746964" + "666c6f61745f6164645f6f6f625f736c69636531666c6f61745f6164645f6f6f625f736c69" + "636532666c6f61745f73756274726163745f6f6f625f736c69636531666c6f61745f737562" + "74726163745f6f6f625f736c69636532666c6f61745f6d756c7469706c795f6f6f625f736c" + "69636531666c6f61745f6d756c7469706c795f6f6f625f736c69636532666c6f61745f6469" + "766964655f6f6f625f736c69636531666c6f61745f6469766964655f6f6f625f736c696365" + "32666c6f61745f726f6f745f6f6f625f736c696365666c6f61745f706f775f6f6f625f736c" + "696365666c6f61745f6c6f675f6f6f625f736c6963656765745f6e66745f77726f6e675f73" + "697a655f75696e743235366765745f6e66745f6973737565725f77726f6e675f73697a655f" + "75696e743235366765745f6e66745f7461786f6e5f77726f6e675f73697a655f75696e7432" + "35366765745f6e66745f73657269616c5f77726f6e675f73697a655f75696e743235366163" + "636f756e745f6b65796c65745f77726f6e675f73697a655f6163636f756e74696463686563" + "6b5f6b65796c65745f77726f6e675f73697a655f6163636f756e74696463726564656e7469" + "616c5f6b65796c65745f77726f6e675f73697a655f6163636f756e7469643163726564656e" + "7469616c5f6b65796c65745f77726f6e675f73697a655f6163636f756e7469643264656c65" + "676174655f6b65796c65745f77726f6e675f73697a655f6163636f756e7469643164656c65" + "676174655f6b65796c65745f77726f6e675f73697a655f6163636f756e746964326465706f" + "7369745f707265617574685f6b65796c65745f77726f6e675f73697a655f6163636f756e74" + "6964316465706f7369745f707265617574685f6b65796c65745f77726f6e675f73697a655f" + "6163636f756e746964326469645f6b65796c65745f77726f6e675f73697a655f6163636f75" + "6e746964657363726f775f6b65796c65745f77726f6e675f73697a655f6163636f756e7469" + "646c696e655f6b65796c65745f77726f6e675f73697a655f6163636f756e746964316c696e" + "655f6b65796c65745f77726f6e675f73697a655f6163636f756e746964326d70745f697373" + "75616e63655f6b65796c65745f77726f6e675f73697a655f6163636f756e7469646d70746f" + "6b656e5f6b65796c65745f77726f6e675f73697a655f6163636f756e7469646e66745f6f66" + "6665725f6b65796c65745f77726f6e675f73697a655f6163636f756e7469646f666665725f" + "6b65796c65745f77726f6e675f73697a655f6163636f756e7469646f7261636c655f6b6579" + "6c65745f77726f6e675f73697a655f6163636f756e7469647061796368616e5f6b65796c65" + "745f77726f6e675f73697a655f6163636f756e746964317061796368616e5f6b65796c6574" + "5f77726f6e675f73697a655f6163636f756e746964327065726d697373696f6e65645f646f" + "6d61696e5f6b65796c65745f77726f6e675f73697a655f6163636f756e7469647369676e65" + "72735f6b65796c65745f77726f6e675f73697a655f6163636f756e7469647469636b65745f" + "6b65796c65745f77726f6e675f73697a655f6163636f756e7469647661756c745f6b65796c" + "65745f77726f6e675f73697a655f6163636f756e7469646765745f6e66745f77726f6e675f" + "73697a655f6163636f756e7469646d70746f6b656e5f6b65796c65745f6d707469645f7772" + "6f6e675f6c656e677468004d0970726f64756365727302086c616e67756167650104527573" + "74000c70726f6365737365642d6279010572757374631d312e38352e312028346562313631" + "32353020323032352d30332d313529002c0f7461726765745f6665617475726573022b0f6d" + "757461626c652d676c6f62616c732b087369676e2d657874"; + +extern std::string const floatTestsWasmHex = + "0061736d0100000001430860077f7f7f7f7f7f7f017f60057f7f7f7f7f017f60047f7f7f7f" + "017f60067f7f7f7f7f7f017f60047e7f7f7f017f60057f7e7f7f7f017f60037f7f7e017f60" + "00017f02c9020e08686f73745f6c6962057472616365000108686f73745f6c69620e666c6f" + "61745f66726f6d5f696e74000408686f73745f6c69621274726163655f6f70617175655f66" + "6c6f6174000208686f73745f6c69620f666c6f61745f66726f6d5f75696e74000108686f73" + "745f6c696209666c6f61745f736574000508686f73745f6c69620d666c6f61745f636f6d70" + "617265000208686f73745f6c696209666c6f61745f616464000008686f73745f6c69620e66" + "6c6f61745f7375627472616374000008686f73745f6c69620e666c6f61745f6d756c746970" + "6c79000008686f73745f6c69620c666c6f61745f646976696465000008686f73745f6c6962" + "09666c6f61745f706f77000308686f73745f6c69620974726163655f6e756d000608686f73" + "745f6c69620a666c6f61745f726f6f74000308686f73745f6c696209666c6f61745f6c6f67" + "00010302010705030100110619037f01418080c0000b7f0041d28ac0000b7f0041e08ac000" + "0b072e04066d656d6f727902000666696e697368000e0a5f5f646174615f656e6403010b5f" + "5f686561705f6261736503020af20e01ef0e01047f230041206b22012400418080c000411d" + "41004100410010001a200142003703100240428ce000200141106a22004108410010014108" + "460440419d80c00041172000410810021a41b480c000411e20004108410110001a0c010b41" + "d280c000411e41004100410010001a0b2001428ce0003703180240200141186a4108200141" + "106a2200410841001003410846044041f080c00041172000410810021a0c010b418781c000" + "411e41004100410010001a0b0240410242fb00200141106a22004108410010044108460440" + "41a581c00041212000410810021a0c010b41c681c000412641004100410010001a0b41ec81" + "c0004115418182c000410810021a419182c0004116418982c000410810021a41a782c00041" + "1b41004100410010001a2001420037031802404201200141186a2200410841001001410846" + "044041c282c000410f2000410810021a0c010b41d182c000411641004100410010001a0b02" + "40200141186a4108418182c0004108100545044041e782c000411b41004100410010001a0c" + "010b418283c000411b41004100410010001a0b0240200141186a4108418982c00041081005" + "4101460440419d83c000412341004100410010001a0c010b41c083c0004124410041004100" + "10001a0b0240418982c0004108200141186a41081005410246044041e483c0004123410041" + "00410010001a0c010b418784c000412441004100410010001a0b41ab84c000412041004100" + "410010001a200142d487b6f4c7d4b1c000370310410921000340200141106a220241084181" + "82c000410820024108410010061a200041016b22000d000b20014200370318420a20014118" + "6a22004108410010011a02402000410820024108100545044041cb84c00041144100410041" + "0010001a0c010b41df84c000411341004100410010001a0b410b21000340200141106a2202" + "4108418182c000410820024108410010071a200041016b22000d000b024020024108418982" + "c0004108100545044041f284c000411941004100410010001a0c010b418b85c00041184100" + "4100410010001a0b41a385c000412341004100410010001a20014200370300420a20014108" + "410010011a200142d487b6f4c7d4b1c000370308410621000340200141086a220241082001" + "410820024108410010081a200041016b22000d000b2001420037031042c0843d200141106a" + "22004108410010011a02402000410820024108100545044041c685c0004119410041004100" + "10001a0c010b41df85c000411841004100410010001a0b410721000340200141086a220241" + "082001410820024108410010091a200041016b22000d000b20014200370318417f42012001" + "41186a22004108410010041a02402002410820004108100545044041f785c0004117410041" + "00410010001a0c010b418e86c000411641004100410010001a0b41a486c000411741004100" + "410010001a20014200370308418182c00041084103200141086a220041084100100a1a41bb" + "86c00041122000410810021a418982c00041084106200041084100100a1a41cd86c0004118" + "2000410810021a200142003703104209200141106a22024108410010011a20024108410220" + "0041084100100a1a41e586c00041142000410810021a200241084100200041084100100a1a" + "41f986c00041172000410810021a200142003703184200200141186a22034108410010011a" + "200341084102200041084100100a1a419087c00041142000410810021a41a487c000413820" + "0341084100200041084100100aac100b1a41dc87c000411841004100410010001a20014200" + "370308420920004108410010011a20014200370310200041084102200241084100100c1a41" + "f487c00041122002410810021a200041084103200241084100100c1a418688c00041122002" + "410810021a2001420037031842c0843d20034108410010011a200341084103200241084100" + "100c1a419888c00041182002410810021a200341084106200241084100100c1a41b088c000" + "411c2002410810021a41cc88c000411741004100410010001a2001420037031042c0843d20" + "024108410010011a2001420037031820024108200341084100100d1a41e388c00041142003" + "410810021a41f788c000411a41004100410010001a20014200370318418182c00041084189" + "82c000410820034108410010081a0240418982c0004108200341081005450440419189c000" + "411641004100410010001a0c010b41a789c000411541004100410010001a0b418982c00041" + "08418982c0004108200141186a22004108410010081a0240418182c0004108200041081005" + "45044041bc89c000411741004100410010001a0c010b41d389c00041164100410041001000" + "1a0b41e989c000411a41004100410010001a2001420037031020014200370318420a200141" + "186a22024108410010011a418182c000410820024108200141106a22004108410010091a41" + "838ac00041192000410810021a418182c00041082000410820004108410010091a419c8ac0" + "00410f2000410810021a02402002410820004108100545044041ab8ac00041144100410041" + "0010001a0c010b41bf8ac000411341004100410010001a0b200141206a240041010b0bdc0a" + "0100418080c0000bd20a0a24242420746573745f666c6f61745f66726f6d5f7761736d2024" + "24242020666c6f61742066726f6d206936342031323330303a2020666c6f61742066726f6d" + "20693634203132333030206173204845583a2020666c6f61742066726f6d20693634203132" + "3330303a206661696c65642020666c6f61742066726f6d207536342031323330303a202066" + "6c6f61742066726f6d207536342031323330303a206661696c65642020666c6f6174206672" + "6f6d2065787020322c206d616e7469737361203132333a2020666c6f61742066726f6d2065" + "787020322c206d616e746973736120333a206661696c65642020666c6f61742066726f6d20" + "636f6e737420313ad4838d7ea4c6800094838d7ea4c680002020666c6f61742066726f6d20" + "636f6e7374202d313a0a24242420746573745f666c6f61745f636f6d706172652024242420" + "20666c6f61742066726f6d20313a2020666c6f61742066726f6d20313a206661696c656420" + "20666c6f61742066726f6d2031203d3d20464c4f41545f4f4e452020666c6f61742066726f" + "6d203120213d20464c4f41545f4f4e452020666c6f61742066726f6d2031203e20464c4f41" + "545f4e454741544956455f4f4e452020666c6f61742066726f6d203120213e20464c4f4154" + "5f4e454741544956455f4f4e452020464c4f41545f4e454741544956455f4f4e45203c2066" + "6c6f61742066726f6d20312020464c4f41545f4e454741544956455f4f4e4520213c20666c" + "6f61742066726f6d20310a24242420746573745f666c6f61745f6164645f73756274726163" + "742024242420207265706561746564206164643a20676f6f64202072657065617465642061" + "64643a20626164202072657065617465642073756274726163743a20676f6f642020726570" + "65617465642073756274726163743a206261640a24242420746573745f666c6f61745f6d75" + "6c7469706c795f6469766964652024242420207265706561746564206d756c7469706c793a" + "20676f6f6420207265706561746564206d756c7469706c793a206261642020726570656174" + "6564206469766964653a20676f6f6420207265706561746564206469766964653a20626164" + "0a24242420746573745f666c6f61745f706f77202424242020666c6f61742063756265206f" + "6620313a2020666c6f61742036746820706f776572206f66202d313a2020666c6f61742073" + "7175617265206f6620393a2020666c6f61742030746820706f776572206f6620393a202066" + "6c6f617420737175617265206f6620303a2020666c6f61742030746820706f776572206f66" + "20302028657870656374696e6720494e56414c49445f504152414d53206572726f72293a0a" + "24242420746573745f666c6f61745f726f6f74202424242020666c6f61742073717274206f" + "6620393a2020666c6f61742063627274206f6620393a2020666c6f61742063627274206f66" + "20313030303030303a2020666c6f61742036746820726f6f74206f6620313030303030303a" + "0a24242420746573745f666c6f61745f6c6f672024242420206c6f675f3130206f66203130" + "30303030303a0a24242420746573745f666c6f61745f6e65676174652024242420206e6567" + "61746520636f6e737420313a20676f6f6420206e656761746520636f6e737420313a206261" + "6420206e656761746520636f6e7374202d313a20676f6f6420206e656761746520636f6e73" + "74202d313a206261640a24242420746573745f666c6f61745f696e76657274202424242020" + "696e76657274206120666c6f61742066726f6d2031303a2020696e7665727420616761696e" + "3a2020696e766572742074776963653a20676f6f642020696e766572742074776963653a20" + "626164004d0970726f64756365727302086c616e6775616765010452757374000c70726f63" + "65737365642d6279010572757374631d312e39302e30202831313539653738633420323032" + "352d30392d313429002c0f7461726765745f6665617475726573022b0f6d757461626c652d" + "676c6f62616c732b087369676e2d657874"; + +extern std::string const float0Hex = + "0061736d0100000001290560057f7f7f7f7f017f60047e7f7f7f017f6007" + "7f7f7f7f7f7f7f017f60047f7f7f7f017f6000017f025f0408686f73745f" + "6c6962057472616365000008686f73745f6c69620e666c6f61745f66726f" + "6d5f696e74000108686f73745f6c69620e666c6f61745f73756274726163" + "74000208686f73745f6c69620d666c6f61745f636f6d7061726500030302" + "010405030100110619037f01418080c0000b7f00419281c0000b7f0041a0" + "81c0000b072e04066d656d6f727902000666696e69736800040a5f5f6461" + "74615f656e6403010b5f5f686561705f6261736503020abe0201bb020101" + "7f23808080800041206b2200248080808000418080c08000411541004100" + "41001080808080001a200042003703084200200041086a41084100108180" + "8080001a20004200370310420a200041106a410841001081808080001a20" + "0042003703180240200041106a4108200041106a4108200041186a410841" + "001082808080004108460d00419580c08000411541004100410010808080" + "80001a0b02400240200041086a4108200041186a41081083808080000d00" + "41aa80c0800041174100410041001080808080001a0c010b41c180c08000" + "41164100410041001080808080001a0b02400240200041086a410841d780" + "c0800041081083808080000d0041df80c08000411a410041004100108080" + "8080001a0c010b41f980c0800041194100410041001080808080001a0b20" + "0041206a24808080800041010b0b9c010100418080c0000b92010a242424" + "20746573745f666c6f61745f30202424242020666c6f61742031302d3130" + "3a206661696c65642020666c6f6174203020636f6d706172653a20676f6f" + "642020666c6f6174203020636f6d706172653a2062616480000000000000" + "002020464c4f41545f5a45524f20636f6d706172653a20676f6f64202046" + "4c4f41545f5a45524f20636f6d706172653a20626164009502046e616d65" + "001110666c6f61745f74657374732e7761736d01da0105002b5f5a4e3878" + "72706c5f73746434686f7374357472616365313768616338383262323664" + "656162656436364501355f5a4e387872706c5f73746434686f7374313466" + "6c6f61745f66726f6d5f696e743137683032343066386533613839643139" + "39654502355f5a4e387872706c5f73746434686f73743134666c6f61745f" + "737562747261637431376864363430633135323334353432393563450334" + "5f5a4e387872706c5f73746434686f73743133666c6f61745f636f6d7061" + "72653137683663386465656231323864393638386645040666696e697368" + "071201000f5f5f737461636b5f706f696e746572090a0100072e726f6461" + "7461004d0970726f64756365727302086c616e6775616765010452757374" + "000c70726f6365737365642d6279010572757374631d312e38392e302028" + "32393438333838336520323032352d30382d3034290094010f7461726765" + "745f6665617475726573082b0b62756c6b2d6d656d6f72792b0f62756c6b" + "2d6d656d6f72792d6f70742b1663616c6c2d696e6469726563742d6f7665" + "726c6f6e672b0a6d756c746976616c75652b0f6d757461626c652d676c6f" + "62616c732b136e6f6e7472617070696e672d6670746f696e742b0f726566" + "6572656e63652d74797065732b087369676e2d657874"; + +extern std::string const disabledFloatHex = + "0061736d010000000108026000006000017f03030200010503010002063e" + "0a7f004180080b7f004180080b7f004180100b7f004180100b7f00418090" + "040b7f004180080b7f00418090040b7f00418080080b7f0041000b7f0041" + "010b07b0010d066d656d6f72790200115f5f7761736d5f63616c6c5f6374" + "6f727300000666696e69736800010362756603000c5f5f64736f5f68616e" + "646c6503010a5f5f646174615f656e6403020b5f5f737461636b5f6c6f77" + "03030c5f5f737461636b5f6869676803040d5f5f676c6f62616c5f626173" + "6503050b5f5f686561705f6261736503060a5f5f686561705f656e640307" + "0d5f5f6d656d6f72795f6261736503080c5f5f7461626c655f6261736503" + "090a150202000b100043000000c54300200045921a41010b"; diff --git a/src/test/app/wasm_fixtures/fixtures.h b/src/test/app/wasm_fixtures/fixtures.h new file mode 100644 index 00000000000..0e7e3785ea8 --- /dev/null +++ b/src/test/app/wasm_fixtures/fixtures.h @@ -0,0 +1,52 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#pragma once + +// TODO: consider moving these to separate files (and figure out the build) + +#include + +extern std::string const ledgerSqnWasmHex; + +extern std::string const allHostFunctionsWasmHex; + +extern std::string const deepRecursionHex; + +extern std::string const fibWasmHex; + +extern std::string const b58WasmHex; + +extern std::string const sha512PureWasmHex; + +extern std::string const zkProofWasmHex; + +extern std::string const sp1WasmHex; + +extern std::string const hfPerfTest; + +extern std::string const allKeyletsWasmHex; + +extern std::string const codecovTestsWasmHex; + +extern std::string const floatTestsWasmHex; + +extern std::string const float0Hex; + +extern std::string const disabledFloatHex; diff --git a/src/test/app/wasm_fixtures/float_tests/Cargo.lock b/src/test/app/wasm_fixtures/float_tests/Cargo.lock new file mode 100644 index 00000000000..972bf3ce61e --- /dev/null +++ b/src/test/app/wasm_fixtures/float_tests/Cargo.lock @@ -0,0 +1,15 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "float_tests" +version = "0.0.1" +dependencies = [ + "xrpl-std", +] + +[[package]] +name = "xrpl-std" +version = "0.0.1" +source = "git+https://github.com/ripple/craft.git?branch=main#94fb247e0c21b9e7fecb91ce71ef7f74ef4a7931" diff --git a/src/test/app/wasm_fixtures/float_tests/Cargo.toml b/src/test/app/wasm_fixtures/float_tests/Cargo.toml new file mode 100644 index 00000000000..b4dec2aa504 --- /dev/null +++ b/src/test/app/wasm_fixtures/float_tests/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "float_tests" +version = "0.0.1" +edition = "2024" + +# This empty workspace definition keeps this project independent of the parent workspace +[workspace] + +[lib] +crate-type = ["cdylib"] + +[profile.release] +lto = true +opt-level = 's' +panic = "abort" + +[dependencies] +xrpl-std = { git = "https://github.com/ripple/craft.git", branch = "main", package = "xrpl-std" } + +[profile.dev] +panic = "abort" diff --git a/src/test/app/wasm_fixtures/float_tests/src/lib.rs b/src/test/app/wasm_fixtures/float_tests/src/lib.rs new file mode 100644 index 00000000000..9688ebd6029 --- /dev/null +++ b/src/test/app/wasm_fixtures/float_tests/src/lib.rs @@ -0,0 +1,460 @@ +#![allow(unused_imports)] +#![allow(unused_variables)] +#![cfg_attr(target_arch = "wasm32", no_std)] + +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +use xrpl_std::core::locator::Locator; +use xrpl_std::decode_hex_32; +use xrpl_std::host::trace::DataRepr::AsHex; +use xrpl_std::host::trace::{trace, trace_data, trace_float, trace_num, DataRepr}; +use xrpl_std::host::{ + cache_ledger_obj, float_add, float_compare, float_divide, float_from_int, float_from_uint, + float_log, float_multiply, float_pow, float_root, float_set, float_subtract, + get_ledger_obj_array_len, get_ledger_obj_field, get_ledger_obj_nested_field, + trace_opaque_float, FLOAT_NEGATIVE_ONE, FLOAT_ONE, FLOAT_ROUNDING_MODES_TO_NEAREST, +}; +use xrpl_std::sfield; +use xrpl_std::sfield::{ + Account, AccountTxnID, Balance, Domain, EmailHash, Flags, LedgerEntryType, MessageKey, + OwnerCount, PreviousTxnID, PreviousTxnLgrSeq, RegularKey, Sequence, TicketCount, TransferRate, +}; + +fn test_float_from_wasm() { + let _ = trace("\n$$$ test_float_from_wasm $$$"); + + let mut f: [u8; 8] = [0u8; 8]; + if 8 == unsafe { float_from_int(12300, f.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) } { + let _ = trace_float(" float from i64 12300:", &f); + let _ = trace_data(" float from i64 12300 as HEX:", &f, AsHex); + } else { + let _ = trace(" float from i64 12300: failed"); + } + + let u64_value: u64 = 12300; + if 8 == unsafe { + float_from_uint( + &u64_value as *const u64 as *const u8, + 8, + f.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + } { + let _ = trace_float(" float from u64 12300:", &f); + } else { + let _ = trace(" float from u64 12300: failed"); + } + + if 8 == unsafe { float_set(2, 123, f.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) } { + let _ = trace_float(" float from exp 2, mantissa 123:", &f); + } else { + let _ = trace(" float from exp 2, mantissa 3: failed"); + } + + let _ = trace_float(" float from const 1:", &FLOAT_ONE); + let _ = trace_float(" float from const -1:", &FLOAT_NEGATIVE_ONE); +} + +fn test_float_compare() { + let _ = trace("\n$$$ test_float_compare $$$"); + + let mut f1: [u8; 8] = [0u8; 8]; + if 8 != unsafe { float_from_int(1, f1.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) } { + let _ = trace(" float from 1: failed"); + } else { + let _ = trace_float(" float from 1:", &f1); + } + + if 0 == unsafe { float_compare(f1.as_ptr(), 8, FLOAT_ONE.as_ptr(), 8) } { + let _ = trace(" float from 1 == FLOAT_ONE"); + } else { + let _ = trace(" float from 1 != FLOAT_ONE"); + } + + if 1 == unsafe { float_compare(f1.as_ptr(), 8, FLOAT_NEGATIVE_ONE.as_ptr(), 8) } { + let _ = trace(" float from 1 > FLOAT_NEGATIVE_ONE"); + } else { + let _ = trace(" float from 1 !> FLOAT_NEGATIVE_ONE"); + } + + if 2 == unsafe { float_compare(FLOAT_NEGATIVE_ONE.as_ptr(), 8, f1.as_ptr(), 8) } { + let _ = trace(" FLOAT_NEGATIVE_ONE < float from 1"); + } else { + let _ = trace(" FLOAT_NEGATIVE_ONE !< float from 1"); + } +} + +fn test_float_add_subtract() { + let _ = trace("\n$$$ test_float_add_subtract $$$"); + + let mut f_compute: [u8; 8] = FLOAT_ONE; + for i in 0..9 { + unsafe { + float_add( + f_compute.as_ptr(), + 8, + FLOAT_ONE.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + // let _ = trace_float(" float:", &f_compute); + } + let mut f10: [u8; 8] = [0u8; 8]; + if 8 != unsafe { float_from_int(10, f10.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) } { + // let _ = trace(" float from 10: failed"); + } + if 0 == unsafe { float_compare(f10.as_ptr(), 8, f_compute.as_ptr(), 8) } { + let _ = trace(" repeated add: good"); + } else { + let _ = trace(" repeated add: bad"); + } + + for i in 0..11 { + unsafe { + float_subtract( + f_compute.as_ptr(), + 8, + FLOAT_ONE.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + } + if 0 == unsafe { float_compare(f_compute.as_ptr(), 8, FLOAT_NEGATIVE_ONE.as_ptr(), 8) } { + let _ = trace(" repeated subtract: good"); + } else { + let _ = trace(" repeated subtract: bad"); + } +} + +fn test_float_multiply_divide() { + let _ = trace("\n$$$ test_float_multiply_divide $$$"); + + let mut f10: [u8; 8] = [0u8; 8]; + unsafe { float_from_int(10, f10.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) }; + let mut f_compute: [u8; 8] = FLOAT_ONE; + for i in 0..6 { + unsafe { + float_multiply( + f_compute.as_ptr(), + 8, + f10.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + // let _ = trace_float(" float:", &f_compute); + } + let mut f1000000: [u8; 8] = [0u8; 8]; + unsafe { + float_from_int( + 1000000, + f1000000.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + + if 0 == unsafe { float_compare(f1000000.as_ptr(), 8, f_compute.as_ptr(), 8) } { + let _ = trace(" repeated multiply: good"); + } else { + let _ = trace(" repeated multiply: bad"); + } + + for i in 0..7 { + unsafe { + float_divide( + f_compute.as_ptr(), + 8, + f10.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + } + let mut f01: [u8; 8] = [0u8; 8]; + unsafe { float_set(-1, 1, f01.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) }; + + if 0 == unsafe { float_compare(f_compute.as_ptr(), 8, f01.as_ptr(), 8) } { + let _ = trace(" repeated divide: good"); + } else { + let _ = trace(" repeated divide: bad"); + } +} + +fn test_float_pow() { + let _ = trace("\n$$$ test_float_pow $$$"); + + let mut f_compute: [u8; 8] = [0u8; 8]; + unsafe { + float_pow( + FLOAT_ONE.as_ptr(), + 8, + 3, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float cube of 1:", &f_compute); + + unsafe { + float_pow( + FLOAT_NEGATIVE_ONE.as_ptr(), + 8, + 6, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float 6th power of -1:", &f_compute); + + let mut f9: [u8; 8] = [0u8; 8]; + unsafe { float_from_int(9, f9.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) }; + unsafe { + float_pow( + f9.as_ptr(), + 8, + 2, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float square of 9:", &f_compute); + + unsafe { + float_pow( + f9.as_ptr(), + 8, + 0, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float 0th power of 9:", &f_compute); + + let mut f0: [u8; 8] = [0u8; 8]; + unsafe { float_from_int(0, f0.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) }; + unsafe { + float_pow( + f0.as_ptr(), + 8, + 2, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float square of 0:", &f_compute); + + let r = unsafe { + float_pow( + f0.as_ptr(), + 8, + 0, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_num( + " float 0th power of 0 (expecting INVALID_PARAMS error):", + r as i64, + ); +} + +fn test_float_root() { + let _ = trace("\n$$$ test_float_root $$$"); + + let mut f9: [u8; 8] = [0u8; 8]; + unsafe { float_from_int(9, f9.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) }; + let mut f_compute: [u8; 8] = [0u8; 8]; + unsafe { + float_root( + f9.as_ptr(), + 8, + 2, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float sqrt of 9:", &f_compute); + unsafe { + float_root( + f9.as_ptr(), + 8, + 3, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float cbrt of 9:", &f_compute); + + let mut f1000000: [u8; 8] = [0u8; 8]; + unsafe { + float_from_int( + 1000000, + f1000000.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + unsafe { + float_root( + f1000000.as_ptr(), + 8, + 3, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float cbrt of 1000000:", &f_compute); + unsafe { + float_root( + f1000000.as_ptr(), + 8, + 6, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" float 6th root of 1000000:", &f_compute); +} + +fn test_float_log() { + let _ = trace("\n$$$ test_float_log $$$"); + + let mut f1000000: [u8; 8] = [0u8; 8]; + unsafe { + float_from_int( + 1000000, + f1000000.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let mut f_compute: [u8; 8] = [0u8; 8]; + unsafe { + float_log( + f1000000.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" log_10 of 1000000:", &f_compute); +} + +fn test_float_negate() { + let _ = trace("\n$$$ test_float_negate $$$"); + + let mut f_compute: [u8; 8] = [0u8; 8]; + unsafe { + float_multiply( + FLOAT_ONE.as_ptr(), + 8, + FLOAT_NEGATIVE_ONE.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + // let _ = trace_float(" float:", &f_compute); + if 0 == unsafe { float_compare(FLOAT_NEGATIVE_ONE.as_ptr(), 8, f_compute.as_ptr(), 8) } { + let _ = trace(" negate const 1: good"); + } else { + let _ = trace(" negate const 1: bad"); + } + + unsafe { + float_multiply( + FLOAT_NEGATIVE_ONE.as_ptr(), + 8, + FLOAT_NEGATIVE_ONE.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + // let _ = trace_float(" float:", &f_compute); + if 0 == unsafe { float_compare(FLOAT_ONE.as_ptr(), 8, f_compute.as_ptr(), 8) } { + let _ = trace(" negate const -1: good"); + } else { + let _ = trace(" negate const -1: bad"); + } +} + +fn test_float_invert() { + let _ = trace("\n$$$ test_float_invert $$$"); + + let mut f_compute: [u8; 8] = [0u8; 8]; + let mut f10: [u8; 8] = [0u8; 8]; + unsafe { float_from_int(10, f10.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) }; + unsafe { + float_divide( + FLOAT_ONE.as_ptr(), + 8, + f10.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" invert a float from 10:", &f_compute); + unsafe { + float_divide( + FLOAT_ONE.as_ptr(), + 8, + f_compute.as_ptr(), + 8, + f_compute.as_mut_ptr(), + 8, + FLOAT_ROUNDING_MODES_TO_NEAREST, + ) + }; + let _ = trace_float(" invert again:", &f_compute); + + // if f10's value is 7, then invert twice won't match the original value + if 0 == unsafe { float_compare(f10.as_ptr(), 8, f_compute.as_ptr(), 8) } { + let _ = trace(" invert twice: good"); + } else { + let _ = trace(" invert twice: bad"); + } +} + +#[unsafe(no_mangle)] +pub extern "C" fn finish() -> i32 { + test_float_from_wasm(); + test_float_compare(); + test_float_add_subtract(); + test_float_multiply_divide(); + test_float_pow(); + test_float_root(); + test_float_log(); + test_float_negate(); + test_float_invert(); + + 1 +} diff --git a/src/test/app/wasm_fixtures/ledgerSqn.c b/src/test/app/wasm_fixtures/ledgerSqn.c new file mode 100644 index 00000000000..3458b02872c --- /dev/null +++ b/src/test/app/wasm_fixtures/ledgerSqn.c @@ -0,0 +1,27 @@ +#include + +int32_t +get_ledger_sqn(); +// int32_t trace(uint8_t const*, int32_t, uint8_t const*, int32_t, int32_t); +// int32_t trace_num(uint8_t const*, int32_t, int64_t); + +// uint8_t buf[1024]; + +// char const test_res[] = "sqn: "; +// char const test_name[] = "TEST get_ledger_sqn"; + +int +finish() +{ + // trace((uint8_t const *)test_name, sizeof(test_name) - 1, 0, 0, 0); + + // memset(buf, 0, sizeof(buf)); + // for(int i = 0; i < sizeof(buf); ++i) buf[i] = 0; + + int x = get_ledger_sqn(); + // if (x >= 0) + // x = *((int32_t*)buf); + // trace_num((uint8_t const *)test`_res, sizeof(test_res) - 1, x); + + return x < 0 ? x : (x >= 5 ? x : 0); +} diff --git a/src/test/app/wasm_fixtures/sha512Pure.c b/src/test/app/wasm_fixtures/sha512Pure.c new file mode 100644 index 00000000000..fe82aa2a659 --- /dev/null +++ b/src/test/app/wasm_fixtures/sha512Pure.c @@ -0,0 +1,145 @@ +#include +#include + +static uint64_t const K512[] = { + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, + 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, + 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, + 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, + 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, + 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275, + 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, + 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, + 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, + 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, + 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, + 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, + 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001, + 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, + 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, + 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, + 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, + 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, + 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207, + 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, + 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, + 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, + 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, + 0x5fcb6fab3ad6faec, 0x6c44198c4a475817}; + +#define ROTATE(x, y) (((x) >> (y)) | ((x) << (64 - (y)))) +#define Sigma0(x) (ROTATE((x), 28) ^ ROTATE((x), 34) ^ ROTATE((x), 39)) +#define Sigma1(x) (ROTATE((x), 14) ^ ROTATE((x), 18) ^ ROTATE((x), 41)) +#define sigma0(x) (ROTATE((x), 1) ^ ROTATE((x), 8) ^ ((x) >> 7)) +#define sigma1(x) (ROTATE((x), 19) ^ ROTATE((x), 61) ^ ((x) >> 6)) + +#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +static inline uint64_t +B2U64(uint8_t val, uint8_t sh) +{ + return ((uint64_t)val) << sh; +} + +void* +allocate(int sz) +{ + return malloc(sz); +} +void +deallocate(void* p) +{ + free(p); +} + +uint8_t e_data[32 * 1024]; + +uint8_t* +sha512_process(uint8_t const* data, int32_t length) +{ + static uint64_t state[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + + uint64_t a, b, c, d, e, f, g, h, s0, s1, T1, T2; + uint64_t X[16]; + + uint64_t blocks = length / 128; + while (blocks--) + { + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + unsigned i; + for (i = 0; i < 16; i++) + { + X[i] = B2U64(data[0], 56) | B2U64(data[1], 48) | + B2U64(data[2], 40) | B2U64(data[3], 32) | B2U64(data[4], 24) | + B2U64(data[5], 16) | B2U64(data[6], 8) | B2U64(data[7], 0); + data += 8; + + T1 = h; + T1 += Sigma1(e); + T1 += Ch(e, f, g); + T1 += K512[i]; + T1 += X[i]; + + T2 = Sigma0(a); + T2 += Maj(a, b, c); + + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + for (i = 16; i < 80; i++) + { + s0 = X[(i + 1) & 0x0f]; + s0 = sigma0(s0); + s1 = X[(i + 14) & 0x0f]; + s1 = sigma1(s1); + + T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; + T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; + T2 = Sigma0(a) + Maj(a, b, c); + + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + } + + return (uint8_t*)(state); +} + +// int main () +//{ +// return 0; +// } diff --git a/src/test/app/wasm_fixtures/sp1/Cargo.lock b/src/test/app/wasm_fixtures/sp1/Cargo.lock new file mode 100644 index 00000000000..4374624cd2c --- /dev/null +++ b/src/test/app/wasm_fixtures/sp1/Cargo.lock @@ -0,0 +1,1384 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytemuck" +version = "1.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "camino" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "cc" +version = "1.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-link", +] + +[[package]] +name = "clap" +version = "4.5.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "libredox" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +dependencies = [ + "bitflags", + "libc", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "p3-baby-bear" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecc3edc6fb8186268e05031c26a8b2b1e567957d63adcae1026d55d6bb189b" +dependencies = [ + "num-bigint", + "p3-field", + "p3-mds", + "p3-poseidon2", + "p3-symmetric", + "rand", + "serde", +] + +[[package]] +name = "p3-dft" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eece7b035978976138622b116fefe6c4cc372b1ce70739c40e7a351a9bb68f1f" +dependencies = [ + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "tracing", +] + +[[package]] +name = "p3-field" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f0edf3fde4fd0d1455e901fc871c558010ae18db6e68f1b0fa111391855316" +dependencies = [ + "itertools", + "num-bigint", + "num-traits", + "p3-util", + "rand", + "serde", +] + +[[package]] +name = "p3-matrix" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60961b4d7ffd2e8412ce4e66e213de610356df71cc4e396519c856a664138a27" +dependencies = [ + "itertools", + "p3-field", + "p3-maybe-rayon", + "p3-util", + "rand", + "serde", + "tracing", +] + +[[package]] +name = "p3-maybe-rayon" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbe762738c382c9483410f52348ab9de41bb42c391e8171643a71486cf1ef8f" + +[[package]] +name = "p3-mds" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4127956cc6c783b7d021c5c42d5d89456d5f3bda4a7b165fcc2a3fd4e78fbede" +dependencies = [ + "itertools", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-symmetric", + "p3-util", + "rand", +] + +[[package]] +name = "p3-poseidon2" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be09497da406a98e89dc05c1ce539eeef29541bad61a5b2108a44ffe94dd0b4c" +dependencies = [ + "gcd", + "p3-field", + "p3-mds", + "p3-symmetric", + "rand", + "serde", +] + +[[package]] +name = "p3-symmetric" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e7d954033f657d48490344ca4b3dbcc054962a0e92831b736666bb2f5e5820b" +dependencies = [ + "itertools", + "p3-field", + "serde", +] + +[[package]] +name = "p3-util" +version = "0.2.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6ce0b6bee23fd54e05306f6752ae80b0b71a91166553ab39d7899801497237" +dependencies = [ + "serde", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "sp1" +version = "0.0.1" +dependencies = [ + "sp1-verifier", +] + +[[package]] +name = "sp1-build" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05372b4e3eecca255ba8e385f8dc294861a3b4ea0b0a9946873e39941011db4c" +dependencies = [ + "anyhow", + "cargo_metadata", + "chrono", + "clap", + "dirs", +] + +[[package]] +name = "sp1-lib" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e166e94b13146c65de433cf29acc1030f021414fbebfc24cd4eeaeb787ba3443" +dependencies = [ + "bincode", + "elliptic-curve", + "serde", + "sp1-primitives", +] + +[[package]] +name = "sp1-primitives" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a85ffe9606bd2cc93575ce608f063ca08521cee9bdebf611914c5b2d90d7412" +dependencies = [ + "bincode", + "blake3", + "cfg-if", + "hex", + "lazy_static", + "num-bigint", + "p3-baby-bear", + "p3-field", + "p3-poseidon2", + "p3-symmetric", + "serde", + "sha2", +] + +[[package]] +name = "sp1-verifier" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94a7db4a54984acf4d64c6ba55c4698104f02ef213cc21882e233b4409e7155" +dependencies = [ + "blake3", + "cfg-if", + "hex", + "lazy_static", + "sha2", + "sp1-build", + "substrate-bn-succinct", + "thiserror 2.0.12", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "substrate-bn-succinct" +version = "0.6.0-v4.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ac8ce0a40e721f790e2ef99beab32b99b3121c58edaaa140ffd8f1795a6af7" +dependencies = [ + "bytemuck", + "byteorder", + "cfg-if", + "crunchy", + "lazy_static", + "num-bigint", + "rand", + "rustc-hex", + "sp1-lib", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/src/test/app/wasm_fixtures/sp1/Cargo.toml b/src/test/app/wasm_fixtures/sp1/Cargo.toml new file mode 100644 index 00000000000..d730160aeaa --- /dev/null +++ b/src/test/app/wasm_fixtures/sp1/Cargo.toml @@ -0,0 +1,16 @@ +[package] +edition = "2021" +name = "sp1" +version = "0.0.1" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +sp1-verifier = "4.1.3" + +[profile.release] +opt-level = 3 # "z" for size or "3" for speed +lto = true # Link Time Optimization +codegen-units = 1 # Single unit = better optimization +panic = "abort" # Smaller binary, faster execution diff --git a/src/test/app/wasm_fixtures/sp1/src/lib.rs b/src/test/app/wasm_fixtures/sp1/src/lib.rs new file mode 100644 index 00000000000..f918e4f42df --- /dev/null +++ b/src/test/app/wasm_fixtures/sp1/src/lib.rs @@ -0,0 +1,37 @@ +use sp1_verifier::Groth16Verifier; + +#[no_mangle] +pub fn sp1_groth16_verifier() -> bool { + let groth16_vk = *sp1_verifier::GROTH16_VK_BYTES; + + let proof: Vec = vec![ + 17, 182, 160, 157, 31, 189, 116, 200, 17, 224, 230, 34, 195, 108, 230, 185, 62, 91, 181, + 212, 80, 111, 197, 89, 247, 206, 99, 206, 147, 13, 216, 101, 252, 192, 149, 2, 40, 4, 249, + 44, 97, 227, 127, 36, 244, 18, 27, 75, 248, 3, 45, 11, 103, 45, 183, 204, 61, 217, 19, 208, + 66, 73, 202, 108, 136, 162, 221, 184, 6, 189, 49, 196, 104, 128, 151, 21, 104, 109, 145, + 150, 243, 51, 27, 243, 203, 75, 176, 59, 193, 51, 177, 64, 83, 13, 133, 140, 248, 242, 13, + 24, 12, 103, 126, 112, 244, 181, 129, 246, 52, 110, 134, 57, 149, 23, 163, 43, 202, 7, 164, + 233, 179, 160, 16, 5, 22, 45, 129, 76, 183, 76, 150, 139, 27, 224, 191, 59, 47, 105, 71, + 47, 8, 176, 157, 159, 234, 253, 239, 131, 138, 120, 101, 4, 98, 236, 106, 235, 98, 76, 93, + 220, 174, 153, 58, 216, 28, 141, 129, 191, 188, 40, 184, 225, 22, 61, 75, 139, 159, 162, + 117, 83, 214, 239, 1, 246, 236, 255, 64, 228, 116, 107, 206, 23, 59, 3, 221, 95, 14, 170, + 28, 171, 36, 179, 75, 101, 177, 40, 198, 12, 193, 82, 105, 155, 177, 62, 158, 72, 209, 252, + 51, 169, 109, 32, 121, 179, 194, 73, 164, 14, 8, 206, 181, 9, 5, 38, 74, 136, 97, 0, 89, + 80, 75, 88, 228, 94, 46, 196, 199, 83, 229, 11, 103, 115, 25, 31, 215, 137, 65, 159, 95, + 192, + ]; + + let sp1_public_values = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, + ]; + + let sp1_vkey_hash: String = + "0x00aea8e9c83c73d74036923de1b4a66d18547d58eee4eacfee70235ed291954c".to_string(); + + let _ = Groth16Verifier::verify(&proof, &sp1_public_values, &sp1_vkey_hash, groth16_vk); + + true +} diff --git a/src/test/app/wasm_fixtures/zk_proof/Cargo.lock b/src/test/app/wasm_fixtures/zk_proof/Cargo.lock new file mode 100644 index 00000000000..f042837723f --- /dev/null +++ b/src/test/app/wasm_fixtures/zk_proof/Cargo.lock @@ -0,0 +1,106 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "bls12_381" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc6d6292be3a19e6379786dac800f551e5865a5bb51ebbe3064ab80433f403" +dependencies = [ + "ff", + "group", + "pairing", + "rand_core", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zk_proof" +version = "0.0.1" +dependencies = [ + "bls12_381", + "group", +] diff --git a/src/test/app/wasm_fixtures/zk_proof/Cargo.toml b/src/test/app/wasm_fixtures/zk_proof/Cargo.toml new file mode 100644 index 00000000000..3e556d43176 --- /dev/null +++ b/src/test/app/wasm_fixtures/zk_proof/Cargo.toml @@ -0,0 +1,19 @@ +[package] +edition = "2021" +name = "zk_proof" +version = "0.0.1" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +# bellman = "=0.14.0" +bls12_381 = "=0.8.0" +group = "0.13.0" + +[profile.release] +# opt-level = 3 # Optimize for time +opt-level = "z" # Optimize for size +lto = true # Enable Link Time Optimization +codegen-units = 1 +panic = "abort" # Remove unnecessary panic machinery diff --git a/src/test/app/wasm_fixtures/zk_proof/src/lib.rs b/src/test/app/wasm_fixtures/zk_proof/src/lib.rs new file mode 100644 index 00000000000..4d44d8e3424 --- /dev/null +++ b/src/test/app/wasm_fixtures/zk_proof/src/lib.rs @@ -0,0 +1,254 @@ +use bls12_381::multi_miller_loop; +use bls12_381::Scalar; +use bls12_381::{G1Affine, G2Affine, G2Prepared}; +use group::prime::PrimeCurveAffine; +use group::Curve; + +use std::mem; +use std::os::raw::c_void; +// use std::time::{Instant}; + +// Groth16 proof struct +pub struct Proof { + pub a: G1Affine, + pub b: G2Affine, + pub c: G1Affine, +} + +// Groth16 verification key struct +pub struct VerifyingKey { + pub alpha_g1: G1Affine, + pub beta_g1: G1Affine, + pub beta_g2: G2Affine, + pub gamma_g2: G2Affine, + pub delta_g1: G1Affine, + pub delta_g2: G2Affine, + pub ic: Vec, +} + +#[no_mangle] +pub extern "C" fn allocate(size: usize) -> *mut c_void { + let mut buffer = Vec::with_capacity(size); + let pointer = buffer.as_mut_ptr(); + mem::forget(buffer); + pointer as *mut c_void + // } +} + +#[no_mangle] +fn deserialize_g1_wasm(buffer: &mut Vec) -> G1Affine { + let d_g1 = G1Affine::from_compressed(&buffer[0..48].try_into().unwrap()) + .expect("Failed to deserialize vk"); + + d_g1 +} + +fn deserialize_g2_wasm(buffer: &mut Vec) -> G2Affine { + let d_g2 = G2Affine::from_compressed(&buffer[0..96].try_into().unwrap()) + .expect("Failed to deserialize vk"); + + d_g2 +} + +#[no_mangle] +// pub extern fn bellman_groth16_test(pointer: *mut u8, capacity: usize) -> bool { +pub extern "C" fn bellman_groth16_test() -> bool { + // let mut bytes = Vec::new(); + // unsafe { + // // println!("Test in vm {:?}", pointer); + // let v = Vec::from_raw_parts(pointer, capacity, capacity); //TODO no need to deallocate?? + // bytes.extend_from_slice(&v); + // } + + // Hardcode the input bytes for testing in different WASM VMs + // let bytes = [172, 197, 81, 189, 121, 193, 159, 27, 92, 95, 151, 164, 40, 59, 214, 96, 132, 58, 87, 37, 169, 1, 63, 230, 35, 74, 245, 6, 185, 56, 120, 108, 214, 179, 187, 21, 36, 206, 43, 160, 10, 250, 249, 73, 210, 35, 137, 87, 177, 66, 65, 154, 11, 232, 137, 246, 125, 72, 227, 222, 116, 168, 87, 24, 165, 160, 132, 109, 108, 101, 222, 143, 78, 97, 48, 95, 59, 177, 29, 247, 219, 166, 73, 249, 69, 206, 15, 151, 30, 248, 235, 63, 148, 240, 17, 22, 150, 67, 252, 141, 95, 179, 94, 111, 207, 201, 192, 144, 154, 94, 21, 2, 22, 58, 96, 144, 227, 107, 107, 182, 142, 0, 57, 27, 168, 39, 226, 40, 163, 159, 112, 83, 196, 182, 215, 74, 92, 20, 158, 60, 23, 184, 198, 143, 17, 6, 242, 7, 75, 220, 87, 47, 224, 145, 99, 169, 203, 218, 112, 185, 51, 102, 59, 56, 171, 46, 49, 255, 116, 108, 241, 50, 180, 247, 62, 218, 181, 197, 155, 80, 61, 252, 8, 41, 232, 73, 51, 250, 223, 82, 94, 8, 185, 83, 223, 187, 6, 41, 20, 62, 189, 254, 11, 11, 58, 187, 200, 88, 53, 234, 98, 172, 213, 62, 22, 34, 90, 166, 182, 133, 8, 230, 103, 219, 233, 141, 10, 137, 210, 151, 4, 129, 29, 92, 103, 251, 72, 182, 162, 59, 20, 222, 188, 232, 13, 74, 214, 182, 172, 120, 33, 198, 57, 204, 134, 93, 26, 79, 213, 45, 146, 6, 128, 103, 63, 202, 226, 120, 141, 193, 248, 65, 196, 235, 21, 184, 104, 228, 206, 117, 190, 28, 153, 183, 68, 36, 63, 60, 131, 87, 137, 213, 105, 27, 110, 37, 238, 200, 250, 145, 76, 25, 57, 81, 69, 164, 208, 255, 49, 80, 14, 64, 181, 143, 12, 58, 35, 63, 199, 35, 70, 25, 86, 158, 210, 150, 59, 159, 253, 238, 174, 211, 142, 166, 223, 51, 134, 118, 171, 27, 218, 219, 117, 163, 71, 134, 95, 142, 83, 251, 240, 241, 162, 232, 93, 248, 167, 112, 197, 212, 169, 209, 159, 101, 140, 248, 222, 234, 201, 169, 76, 242, 7, 10, 192, 30, 151, 167, 74, 186, 97, 121, 144, 36, 6, 187, 92, 7, 248, 45, 134, 85, 240, 112, 74, 224, 70, 64, 198, 59, 26, 195, 192, 140, 101, 118, 175, 17, 160, 195, 142, 133, 1, 139, 5, 130, 245, 17, 73, 176, 232, 107, 130, 172, 110, 20, 190, 37, 108, 250, 178, 187, 151, 158, 35, 248, 246, 143, 38, 212, 133, 226, 24, 45, 33, 164, 46, 125, 200, 157, 253, 225, 132, 181, 60, 90, 7, 240, 80, 232, 97, 206, 164, 28, 12, 75, 68, 126, 230, 145, 216, 45, 180, 203, 19, 152, 29, 203, 9, 4, 145, 122, 206, 146, 179, 44, 145, 191, 126, 199, 175, 171, 127, 189, 222, 108, 126, 161, 80, 190, 47, 44, 8, 40, 65, 68, 95, 61, 109, 148, 175, 113, 226, 8, 93, 126, 53, 39, 192, 196, 6, 152, 194, 105, 169, 226, 192, 201, 184, 198, 134, 210, 153, 170, 12, 241, 90, 250, 233, 20, 152, 119, 142, 120, 83, 2, 164, 80, 178, 125, 227, 253, 207, 240, 201, 127, 213, 196, 100, 90, 65, 120, 50, 108, 175, 34, 192, 197, 173, 202, 176, 210, 131, 22, 216, 57, 169, 241, 28, 40, 44, 62, 11, 42, 50, 46, 204, 242, 109, 158, 114, 41, 127, 206, 25, 194, 255, 128, 245, 232, 193, 189, 229, 51, 93, 94, 64, 117, 33, 132, 75, 253, 114, 64, 116, 155, 183, 137, 112, 201, 243, 13, 221, 142, 164, 59, 98, 152, 249, 40, 133, 70, 185, 231, 249, 151, 253, 240, 122, 214, 60, 18, 132, 177, 37, 42, 75, 206, 12, 100, 214, 248, 234, 78, 165, 74, 212, 248, 32, 162, 254, 227, 218, 46, 9, 87, 0, 118, 13, 249, 107, 83, 5, 138, 223, 9, 247, 70, 160, 228, 197, 54, 87, 18, 1, 37, 199, 162, 84, 189, 161, 10, 26, 75, 45, 168, 185, 153, 245, 243, 51, 176, 208, 187, 235, 135, 239, 231, 42, 43, 233, 150, 46, 249, 73, 229, 138, 84, 89, 75, 129, 238, 211, 80, 147, 67, 159, 227, 214, 131, 188, 130, 70, 224, 1, 77, 139, 239, 185, 53, 68, 41, 193, 207, 16, 2, 33, 139, 214, 103, 240, 14, 141, 223, 24, 236, 50, 64, 79, 178, 6, 79, 38, 165, 35, 173, 203, 101, 3, 162, 49, 51, 4, 151, 127, 49, 47, 223, 244, 157, 229, 7, 88, 106, 141, 167, 183, 220, 15, 8, 119, 12, 82, 218, 14, 207, 0, 73, 27, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let bytes = [ + 147, 235, 138, 182, 249, 146, 149, 28, 58, 36, 144, 99, 188, 155, 153, 135, 239, 79, 76, + 109, 152, 156, 202, 1, 153, 84, 239, 184, 69, 145, 133, 48, 156, 80, 122, 227, 231, 161, + 137, 232, 67, 183, 34, 186, 230, 135, 25, 90, 136, 201, 110, 134, 208, 93, 78, 82, 153, + 239, 208, 236, 160, 231, 192, 150, 215, 128, 193, 255, 107, 39, 133, 12, 136, 148, 119, 17, + 59, 198, 100, 49, 37, 89, 132, 205, 45, 79, 151, 112, 247, 140, 94, 179, 215, 165, 52, 182, + 153, 68, 204, 210, 218, 156, 69, 74, 192, 30, 160, 13, 80, 188, 23, 112, 21, 124, 91, 147, + 21, 140, 217, 226, 248, 60, 182, 119, 18, 34, 32, 41, 181, 128, 165, 97, 168, 76, 98, 44, + 114, 122, 128, 215, 68, 156, 18, 91, 5, 33, 22, 141, 249, 137, 49, 252, 82, 122, 206, 58, + 183, 108, 176, 15, 38, 183, 87, 254, 34, 102, 195, 78, 166, 227, 96, 180, 137, 173, 131, + 178, 179, 25, 89, 159, 5, 73, 125, 24, 25, 86, 227, 19, 184, 117, 228, 173, 150, 1, 82, + 142, 48, 251, 236, 132, 73, 79, 201, 165, 192, 191, 195, 60, 100, 198, 251, 187, 161, 220, + 63, 143, 38, 21, 189, 219, 194, 100, 64, 186, 102, 7, 186, 213, 227, 92, 228, 52, 181, 171, + 223, 222, 218, 206, 221, 22, 15, 46, 77, 175, 34, 43, 221, 110, 21, 89, 149, 213, 68, 242, + 140, 185, 176, 73, 88, 216, 75, 237, 209, 10, 75, 251, 152, 101, 15, 146, 168, 27, 81, 8, + 61, 76, 103, 230, 171, 23, 144, 171, 6, 118, 157, 233, 234, 214, 132, 106, 30, 171, 121, + 77, 147, 175, 170, 62, 48, 251, 12, 221, 202, 109, 80, 97, 180, 27, 45, 87, 162, 19, 168, + 152, 27, 205, 113, 91, 83, 52, 99, 109, 17, 149, 189, 244, 174, 164, 192, 79, 133, 111, + 195, 215, 232, 129, 166, 204, 3, 169, 248, 49, 18, 190, 198, 145, 177, 169, 10, 4, 66, 134, + 46, 11, 163, 170, 94, 230, 234, 234, 43, 122, 51, 230, 100, 106, 149, 228, 208, 217, 87, + 231, 125, 170, 47, 143, 151, 45, 208, 64, 91, 10, 188, 136, 15, 155, 131, 200, 141, 243, + 200, 5, 109, 22, 98, 189, 193, 44, 40, 95, 126, 145, 234, 190, 205, 179, 172, 224, 147, + 253, 238, 162, 157, 60, 126, 9, 174, 34, 16, 161, 197, 60, 243, 211, 241, 78, 114, 51, 167, + 214, 53, 149, 172, 56, 149, 32, 66, 123, 48, 240, 179, 53, 154, 29, 134, 34, 141, 204, 168, + 184, 158, 165, 115, 241, 119, 228, 11, 35, 82, 186, 132, 103, 65, 243, 215, 31, 105, 201, + 191, 155, 210, 53, 194, 76, 63, 199, 181, 28, 138, 181, 181, 211, 145, 15, 139, 244, 38, + 56, 159, 161, 95, 46, 147, 141, 163, 221, 88, 167, 134, 73, 45, 70, 98, 98, 167, 55, 52, + 234, 110, 150, 79, 248, 157, 167, 84, 210, 89, 10, 193, 169, 32, 40, 218, 7, 236, 206, 85, + 178, 174, 157, 132, 181, 192, 119, 60, 205, 46, 217, 120, 97, 59, 82, 121, 11, 189, 21, + 213, 176, 255, 225, 57, 76, 239, 38, 99, 226, 55, 98, 227, 10, 45, 193, 69, 255, 247, 39, + 121, 86, 150, 6, 220, 98, 41, 132, 237, 189, 169, 110, 213, 115, 33, 228, 197, 61, 219, + 202, 58, 54, 70, 223, 179, 208, 139, 232, 103, 76, 165, 169, 68, 6, 148, 47, 244, 26, 203, + 186, 110, 69, 44, 175, 128, 119, 212, 188, 167, 223, 87, 119, 238, 199, 201, 61, 78, 96, + 175, 0, 156, 145, 196, 253, 162, 175, 172, 227, 80, 251, 96, 61, 189, 35, 13, 97, 22, 157, + 86, 249, 128, 148, 172, 66, 80, 172, 208, 222, 131, 0, 207, 80, 163, 27, 155, 113, 57, 186, + 246, 139, 111, 71, 117, 152, 184, 60, 1, 230, 44, 169, 213, 88, 82, 156, 194, 234, 41, 183, + 87, 36, 175, 154, 156, 128, 59, 187, 208, 101, 9, 51, 205, 42, 174, 29, 215, 43, 150, 183, + 129, 125, 2, 84, 210, 149, 245, 126, 140, 166, 255, 134, 116, 162, 107, 82, 178, 158, 38, + 11, 135, 91, 224, 157, 112, 189, 164, 250, 1, 215, 49, 21, 214, 211, 73, 243, 251, 58, 198, + 1, 165, 196, 122, 13, 238, 252, 227, 229, 149, 47, 13, 173, 171, 176, 185, 220, 82, 96, + 163, 4, 36, 199, 152, 88, 3, 162, 49, 51, 4, 151, 127, 49, 47, 223, 244, 157, 229, 7, 88, + 106, 141, 167, 183, 220, 15, 8, 119, 12, 82, 218, 14, 207, 0, 73, 27, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + // ***** Test deserialization and reconstruction of vk ***** + // let start_key_recons = Instant::now(); + // println!("Start verification key reconstruction"); + + // alpha_g1 + let mut vec_alpha_g1 = bytes[0..48].to_vec(); + let r_alpha_g1 = deserialize_g1_wasm(&mut vec_alpha_g1); + + // beta_g1 + let mut vec_beta_g1 = bytes[48..96].to_vec(); + let r_beta_g1 = deserialize_g1_wasm(&mut vec_beta_g1); + + // beta_g2 + let mut vec_beta_g2 = bytes[96..192].to_vec(); + let r_beta_g2 = deserialize_g2_wasm(&mut vec_beta_g2); + + // gamma_g2 + let mut vec_gamma_g2 = bytes[192..288].to_vec(); + let r_gamma_g2 = deserialize_g2_wasm(&mut vec_gamma_g2); + + // delta_g1 + let mut vec_delta_g1 = bytes[288..336].to_vec(); + let r_delta_g1 = deserialize_g1_wasm(&mut vec_delta_g1); + + // delta_g2 + let mut vec_delta_g2 = bytes[336..432].to_vec(); + let r_delta_g2 = deserialize_g2_wasm(&mut vec_delta_g2); + + // ic + let vec_ic = bytes[432..576].to_vec(); + // println!("\nic vector: {:?}", vec_ic); + let mut r_ic: Vec = Vec::new(); + let mut vec_ic_de = vec_ic[0..48].to_vec(); + r_ic.push(deserialize_g1_wasm(&mut vec_ic_de)); + vec_ic_de = vec_ic[48..96].to_vec(); + r_ic.push(deserialize_g1_wasm(&mut vec_ic_de)); + vec_ic_de = vec_ic[96..144].to_vec(); + r_ic.push(deserialize_g1_wasm(&mut vec_ic_de)); + + // Reconstruct vk + // replace following if using bellman::{groth16, groth16::Proof}; + // let deserialized_vk = groth16::VerifyingKey:: { + let deserialized_vk = VerifyingKey { + alpha_g1: r_alpha_g1, + beta_g1: r_beta_g1, + beta_g2: r_beta_g2, + gamma_g2: r_gamma_g2, + delta_g1: r_delta_g1, + delta_g2: r_delta_g2, + ic: r_ic, + }; + + // Uncomment following if using bellman::{groth16, groth16::Proof}; + // let pvk = groth16::prepare_verifying_key(&deserialized_vk); + // println!("Key reconstruction time: {:?}", start_key_recons.elapsed()); + + // ***** Reconstruct proof ***** + // let start_proof_recons = Instant::now(); + + // proof.g1 + let r_a = G1Affine::from_compressed(&bytes[576..624].try_into().unwrap()) + .expect("Failed to deserialize a"); + // proof.g2 + let r_b = G2Affine::from_compressed(&bytes[624..720].try_into().unwrap()) + .expect("Failed to deserialize b"); + // proof.g1 + let r_c = G1Affine::from_compressed(&bytes[720..768].try_into().unwrap()) + .expect("Failed to deserialize c"); + + // Replace following if using bellman::{groth16, groth16::Proof}; + // let r_proof: Proof = Proof{a: r_a, b: r_b, c: r_c}; + let r_proof: Proof = Proof { + a: r_a, + b: r_b, + c: r_c, + }; + // println!("Proof reconstruction time: {:?}", start_proof_recons.elapsed()); + + // ***** Reconstruct input ***** + // let start_input_recons = Instant::now(); + + let last_64_bytes = &bytes[bytes.len() - 64..]; + + let r_inputs: Vec = last_64_bytes + .chunks(32) // Each Scalar in bls12_381 uses 32 bytes + .map(|chunk| { + Scalar::from_bytes(chunk.try_into().unwrap()).expect("Invalid bytes for Scalar") + }) + .collect(); + + // println!("Input reconstruction time: {:?}", start_input_recons.elapsed()); + + /***** proof verification *****/ + // uncomment following if bellman groth16 is used + // assert!(groth16::verify_proof(&pvk, &r_proof, &r_inputs).is_ok()); + // let start_verify = Instant::now(); + + // Ensure the number of inputs matches the vk.ic length minus 1 (for IC[0]) + if (r_inputs.len() + 1) != deserialized_vk.ic.len() { + return false; + } + + /***** Compute linear combination: input_acc = IC[0] + sum(input[i] * IC[i+1]) *****/ + let mut acc = deserialized_vk.ic[0].to_curve(); // Convert G1Affine to G1Projective + + // Computes multi-scalar multiplication, + // which is a weighted sum of elliptic curve points. + // In Groth16, this builds the point: + // acc = IC₀ + input₁ × IC₁ + input₂ × IC₂ + ... + inputₙ × ICₙ + // Where: ICᵢ are fixed elliptic curve points (from the verifying key). + // inputᵢ are the public inputs to the circuit. + // Example: public_inputs = [x₁, x₂], vk.ic = [IC₀, IC₁, IC₂], acc = IC₀ + x₁ * IC₁ + x₂ * IC₂ + // This binds the public inputs to the proof + for (input, ic_point) in r_inputs.iter().zip(&deserialized_vk.ic[1..]) { + acc += ic_point.to_curve() * input; + } + + let acc_affine = acc.to_affine(); // converts the point acc from projective form back to affine form. + + // Preparing G2 elements for pairing by converting them into G2Prepared format. + let proof_b_prepared = G2Prepared::from(r_proof.b); + let gamma_g2_prepared = G2Prepared::from(deserialized_vk.gamma_g2); + let delta_g2_prepared = G2Prepared::from(deserialized_vk.delta_g2); + let beta_g2_prepared = G2Prepared::from(deserialized_vk.beta_g2); + + // Compute required product of pairings in their Miller loop form + // Groth16 verifier checks if e(A, B) * e(acc, γ)⁻¹ * e(C, δ)⁻¹ * e(α, β)⁻¹ == 1 + // which boils down to + // let start_miller = Instant::now(); + let ml_result = multi_miller_loop(&[ + (&r_proof.a, &proof_b_prepared), // e(A,B) + (&(-acc_affine), &gamma_g2_prepared), // e(acc, γ)⁻¹ + (&(-r_proof.c), &delta_g2_prepared), // e(C, δ)⁻¹ + (&(-deserialized_vk.alpha_g1), &beta_g2_prepared), //e(α, β)⁻¹ + ]); + // println!("Miller time: {:?}", start_miller.elapsed()); + + // let start_final = Instant::now(); + let result = ml_result.final_exponentiation(); + // println!("Final time: {:?}", start_final.elapsed()); + // println!("Proof verification time: {:?}", start_verify.elapsed()); + + // true + result == bls12_381::Gt::identity() +} diff --git a/src/xrpld/app/wasm/HostFunc.h b/src/xrpld/app/wasm/HostFunc.h new file mode 100644 index 00000000000..4478a8cd568 --- /dev/null +++ b/src/xrpld/app/wasm/HostFunc.h @@ -0,0 +1,514 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ripple { + +enum class HostFunctionError : int32_t { + INTERNAL = -1, + FIELD_NOT_FOUND = -2, + BUFFER_TOO_SMALL = -3, + NO_ARRAY = -4, + NOT_LEAF_FIELD = -5, + LOCATOR_MALFORMED = -6, + SLOT_OUT_RANGE = -7, + SLOTS_FULL = -8, + EMPTY_SLOT = -9, + LEDGER_OBJ_NOT_FOUND = -10, + DECODING = -11, + DATA_FIELD_TOO_LARGE = -12, + POINTER_OUT_OF_BOUNDS = -13, + NO_MEM_EXPORTED = -14, + INVALID_PARAMS = -15, + INVALID_ACCOUNT = -16, + INVALID_FIELD = -17, + INDEX_OUT_OF_BOUNDS = -18, + FLOAT_INPUT_MALFORMED = -19, + FLOAT_COMPUTATION_ERROR = -20, +}; + +inline int32_t +HfErrorToInt(HostFunctionError e) +{ + return static_cast(e); +} + +std::string +floatToString(Slice const& data); + +Expected +floatFromIntImpl(int64_t x, int32_t mode); + +Expected +floatFromUintImpl(uint64_t x, int32_t mode); + +Expected +floatSetImpl(int64_t mantissa, int32_t exponent, int32_t mode); + +Expected +floatCompareImpl(Slice const& x, Slice const& y); + +Expected +floatAddImpl(Slice const& x, Slice const& y, int32_t mode); + +Expected +floatSubtractImpl(Slice const& x, Slice const& y, int32_t mode); + +Expected +floatMultiplyImpl(Slice const& x, Slice const& y, int32_t mode); + +Expected +floatDivideImpl(Slice const& x, Slice const& y, int32_t mode); + +Expected +floatRootImpl(Slice const& x, int32_t n, int32_t mode); + +Expected +floatPowerImpl(Slice const& x, int32_t n, int32_t mode); + +Expected +floatLogImpl(Slice const& x, int32_t mode); + +struct HostFunctions +{ + // LCOV_EXCL_START + virtual void + setRT(void const*) + { + } + + virtual void const* + getRT() const + { + return nullptr; + } + + virtual beast::Journal + getJournal() + { + return beast::Journal{beast::Journal::getNullSink()}; + } + + virtual Expected + getLedgerSqn() + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getParentLedgerTime() + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getParentLedgerHash() + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getBaseFee() + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + isAmendmentEnabled(uint256 const& amendmentId) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + isAmendmentEnabled(std::string_view const& amendmentName) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getTxField(SField const& fname) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getCurrentLedgerObjField(SField const& fname) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getLedgerObjField(int32_t cacheIdx, SField const& fname) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getTxNestedField(Slice const& locator) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getCurrentLedgerObjNestedField(Slice const& locator) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getTxArrayLen(SField const& fname) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getCurrentLedgerObjArrayLen(SField const& fname) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getTxNestedArrayLen(Slice const& locator) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getCurrentLedgerObjNestedArrayLen(Slice const& locator) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + updateData(Slice const& data) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + checkSignature( + Slice const& message, + Slice const& signature, + Slice const& pubkey) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + computeSha512HalfHash(Slice const& data) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + accountKeylet(AccountID const& account) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + ammKeylet(Asset const& issue1, Asset const& issue2) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + checkKeylet(AccountID const& account, std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + credentialKeylet( + AccountID const& subject, + AccountID const& issuer, + Slice const& credentialType) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + didKeylet(AccountID const& account) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + delegateKeylet(AccountID const& account, AccountID const& authorize) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + depositPreauthKeylet(AccountID const& account, AccountID const& authorize) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + escrowKeylet(AccountID const& account, std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + lineKeylet( + AccountID const& account1, + AccountID const& account2, + Currency const& currency) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + mptokenKeylet(MPTID const& mptid, AccountID const& holder) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + nftOfferKeylet(AccountID const& account, std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + offerKeylet(AccountID const& account, std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + oracleKeylet(AccountID const& account, std::uint32_t docId) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + paychanKeylet( + AccountID const& account, + AccountID const& destination, + std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + signersKeylet(AccountID const& account) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + ticketKeylet(AccountID const& account, std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + vaultKeylet(AccountID const& account, std::uint32_t seq) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getNFT(AccountID const& account, uint256 const& nftId) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getNFTIssuer(uint256 const& nftId) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getNFTTaxon(uint256 const& nftId) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getNFTFlags(uint256 const& nftId) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getNFTTransferFee(uint256 const& nftId) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + getNFTSerial(uint256 const& nftId) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + trace(std::string_view const& msg, Slice const& data, bool asHex) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + traceNum(std::string_view const& msg, int64_t data) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + traceAccount(std::string_view const& msg, AccountID const& account) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + traceFloat(std::string_view const& msg, Slice const& data) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + traceAmount(std::string_view const& msg, STAmount const& amount) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatFromInt(int64_t x, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatFromUint(uint64_t x, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatSet(int64_t mantissa, int32_t exponent, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatCompare(Slice const& x, Slice const& y) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatAdd(Slice const& x, Slice const& y, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatSubtract(Slice const& x, Slice const& y, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatMultiply(Slice const& x, Slice const& y, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatDivide(Slice const& x, Slice const& y, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatRoot(Slice const& x, int32_t n, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatPower(Slice const& x, int32_t n, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual Expected + floatLog(Slice const& x, int32_t mode) + { + return Unexpected(HostFunctionError::INTERNAL); + } + + virtual ~HostFunctions() = default; + // LCOV_EXCL_STOP +}; + +} // namespace ripple diff --git a/src/xrpld/app/wasm/HostFuncImpl.h b/src/xrpld/app/wasm/HostFuncImpl.h new file mode 100644 index 00000000000..f56aa102a5a --- /dev/null +++ b/src/xrpld/app/wasm/HostFuncImpl.h @@ -0,0 +1,299 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2023 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#pragma once + +#include +#include + +namespace ripple { +class WasmHostFunctionsImpl : public HostFunctions +{ + ApplyContext& ctx; + Keylet leKey; + std::shared_ptr currentLedgerObj = nullptr; + bool isLedgerObjCached = false; + + static int constexpr MAX_CACHE = 256; + std::array, MAX_CACHE> cache; + std::optional data_; + + void const* rt_ = nullptr; + + Expected, HostFunctionError> + getCurrentLedgerObj() + { + if (!isLedgerObjCached) + { + isLedgerObjCached = true; + currentLedgerObj = ctx.view().read(leKey); + } + if (currentLedgerObj) + return currentLedgerObj; + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + } + + Expected + normalizeCacheIndex(int32_t cacheIdx) + { + --cacheIdx; + if (cacheIdx < 0 || cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + if (!cache[cacheIdx]) + return Unexpected(HostFunctionError::EMPTY_SLOT); + return cacheIdx; + } + +public: + WasmHostFunctionsImpl(ApplyContext& ctx, Keylet const& leKey) + : ctx(ctx), leKey(leKey) + { + } + + virtual void + setRT(void const* rt) override + { + rt_ = rt; + } + + virtual void const* + getRT() const override + { + return rt_; + } + + beast::Journal + getJournal() override + { + return ctx.journal; + } + + std::optional const& + getData() const + { + return data_; + } + + Expected + getLedgerSqn() override; + + Expected + getParentLedgerTime() override; + + Expected + getParentLedgerHash() override; + + Expected + getBaseFee() override; + + Expected + isAmendmentEnabled(uint256 const& amendmentId) override; + + Expected + isAmendmentEnabled(std::string_view const& amendmentName) override; + + Expected + cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override; + + Expected + getTxField(SField const& fname) override; + + Expected + getCurrentLedgerObjField(SField const& fname) override; + + Expected + getLedgerObjField(int32_t cacheIdx, SField const& fname) override; + + Expected + getTxNestedField(Slice const& locator) override; + + Expected + getCurrentLedgerObjNestedField(Slice const& locator) override; + + Expected + getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) override; + + Expected + getTxArrayLen(SField const& fname) override; + + Expected + getCurrentLedgerObjArrayLen(SField const& fname) override; + + Expected + getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) override; + + Expected + getTxNestedArrayLen(Slice const& locator) override; + + Expected + getCurrentLedgerObjNestedArrayLen(Slice const& locator) override; + + Expected + getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) override; + + Expected + updateData(Slice const& data) override; + + Expected + checkSignature( + Slice const& message, + Slice const& signature, + Slice const& pubkey) override; + + Expected + computeSha512HalfHash(Slice const& data) override; + + Expected + accountKeylet(AccountID const& account) override; + + Expected + ammKeylet(Asset const& issue1, Asset const& issue2) override; + + Expected + checkKeylet(AccountID const& account, std::uint32_t seq) override; + + Expected + credentialKeylet( + AccountID const& subject, + AccountID const& issuer, + Slice const& credentialType) override; + + Expected + didKeylet(AccountID const& account) override; + + Expected + delegateKeylet(AccountID const& account, AccountID const& authorize) + override; + + Expected + depositPreauthKeylet(AccountID const& account, AccountID const& authorize) + override; + + Expected + escrowKeylet(AccountID const& account, std::uint32_t seq) override; + + Expected + lineKeylet( + AccountID const& account1, + AccountID const& account2, + Currency const& currency) override; + + Expected + mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) override; + + Expected + mptokenKeylet(MPTID const& mptid, AccountID const& holder) override; + + Expected + nftOfferKeylet(AccountID const& account, std::uint32_t seq) override; + + Expected + offerKeylet(AccountID const& account, std::uint32_t seq) override; + + Expected + oracleKeylet(AccountID const& account, std::uint32_t docId) override; + + Expected + paychanKeylet( + AccountID const& account, + AccountID const& destination, + std::uint32_t seq) override; + + Expected + permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) + override; + + Expected + signersKeylet(AccountID const& account) override; + + Expected + ticketKeylet(AccountID const& account, std::uint32_t seq) override; + + Expected + vaultKeylet(AccountID const& account, std::uint32_t seq) override; + + Expected + getNFT(AccountID const& account, uint256 const& nftId) override; + + Expected + getNFTIssuer(uint256 const& nftId) override; + + Expected + getNFTTaxon(uint256 const& nftId) override; + + Expected + getNFTFlags(uint256 const& nftId) override; + + Expected + getNFTTransferFee(uint256 const& nftId) override; + + Expected + getNFTSerial(uint256 const& nftId) override; + + Expected + trace(std::string_view const& msg, Slice const& data, bool asHex) override; + + Expected + traceNum(std::string_view const& msg, int64_t data) override; + + Expected + traceAccount(std::string_view const& msg, AccountID const& account) + override; + + Expected + traceFloat(std::string_view const& msg, Slice const& data) override; + + Expected + traceAmount(std::string_view const& msg, STAmount const& amount) override; + + Expected + floatFromInt(int64_t x, int32_t mode) override; + + Expected + floatFromUint(uint64_t x, int32_t mode) override; + + Expected + floatSet(int64_t mantissa, int32_t exponent, int32_t mode) override; + + Expected + floatCompare(Slice const& x, Slice const& y) override; + + Expected + floatAdd(Slice const& x, Slice const& y, int32_t mode) override; + + Expected + floatSubtract(Slice const& x, Slice const& y, int32_t mode) override; + + Expected + floatMultiply(Slice const& x, Slice const& y, int32_t mode) override; + + Expected + floatDivide(Slice const& x, Slice const& y, int32_t mode) override; + + Expected + floatRoot(Slice const& x, int32_t n, int32_t mode) override; + + Expected + floatPower(Slice const& x, int32_t n, int32_t mode) override; + + Expected + floatLog(Slice const& x, int32_t mode) override; +}; + +} // namespace ripple diff --git a/src/xrpld/app/wasm/HostFuncWrapper.h b/src/xrpld/app/wasm/HostFuncWrapper.h new file mode 100644 index 00000000000..6bfa576b9dc --- /dev/null +++ b/src/xrpld/app/wasm/HostFuncWrapper.h @@ -0,0 +1,553 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#pragma once + +#include + +namespace ripple { + +using getLedgerSqn_proto = int32_t(); +wasm_trap_t* +getLedgerSqn_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getParentLedgerTime_proto = int32_t(); +wasm_trap_t* +getParentLedgerTime_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getParentLedgerHash_proto = int32_t(uint8_t*, int32_t); +wasm_trap_t* +getParentLedgerHash_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getBaseFee_proto = int32_t(); +wasm_trap_t* +getBaseFee_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using isAmendmentEnabled_proto = int32_t(uint8_t const*, int32_t); +wasm_trap_t* +isAmendmentEnabled_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using cacheLedgerObj_proto = int32_t(uint8_t const*, int32_t, int32_t); +wasm_trap_t* +cacheLedgerObj_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getTxField_proto = int32_t(int32_t, uint8_t*, int32_t); +wasm_trap_t* +getTxField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getCurrentLedgerObjField_proto = int32_t(int32_t, uint8_t*, int32_t); +wasm_trap_t* +getCurrentLedgerObjField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getLedgerObjField_proto = int32_t(int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +getLedgerObjField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getTxNestedField_proto = + int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +getTxNestedField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getCurrentLedgerObjNestedField_proto = + int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +getCurrentLedgerObjNestedField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getLedgerObjNestedField_proto = + int32_t(int32_t, uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +getLedgerObjNestedField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getTxArrayLen_proto = int32_t(int32_t); +wasm_trap_t* +getTxArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getCurrentLedgerObjArrayLen_proto = int32_t(int32_t); +wasm_trap_t* +getCurrentLedgerObjArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getLedgerObjArrayLen_proto = int32_t(int32_t, int32_t); +wasm_trap_t* +getLedgerObjArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getTxNestedArrayLen_proto = int32_t(uint8_t const*, int32_t); +wasm_trap_t* +getTxNestedArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getCurrentLedgerObjNestedArrayLen_proto = + int32_t(uint8_t const*, int32_t); +wasm_trap_t* +getCurrentLedgerObjNestedArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getLedgerObjNestedArrayLen_proto = + int32_t(int32_t, uint8_t const*, int32_t); +wasm_trap_t* +getLedgerObjNestedArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using updateData_proto = int32_t(uint8_t const*, int32_t); +wasm_trap_t* +updateData_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using checkSignature_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t const*, + int32_t); +wasm_trap_t* +checkSignature_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using computeSha512HalfHash_proto = + int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +computeSha512HalfHash_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using accountKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +accountKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using ammKeylet_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t); +wasm_trap_t* +ammKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using checkKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +checkKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using credentialKeylet_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t); +wasm_trap_t* +credentialKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using delegateKeylet_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t); +wasm_trap_t* +delegateKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using depositPreauthKeylet_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t); +wasm_trap_t* +depositPreauthKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using didKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +didKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using escrowKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +escrowKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using lineKeylet_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t); +wasm_trap_t* +lineKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using mptIssuanceKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +mptIssuanceKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using mptokenKeylet_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t); +wasm_trap_t* +mptokenKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using nftOfferKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +nftOfferKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using offerKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +offerKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using oracleKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +oracleKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using paychanKeylet_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + int32_t, + uint8_t*, + int32_t); +wasm_trap_t* +paychanKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using permissionedDomainKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +permissionedDomainKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using signersKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +signersKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using ticketKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +ticketKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using vaultKeylet_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t); +wasm_trap_t* +vaultKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getNFT_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t); +wasm_trap_t* +getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results); + +using getNFTIssuer_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +getNFTIssuer_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getNFTTaxon_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +getNFTTaxon_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getNFTFlags_proto = int32_t(uint8_t const*, int32_t); +wasm_trap_t* +getNFTFlags_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getNFTTransferFee_proto = int32_t(uint8_t const*, int32_t); +wasm_trap_t* +getNFTTransferFee_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using getNFTSerial_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t); +wasm_trap_t* +getNFTSerial_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using trace_proto = + int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, int32_t); +wasm_trap_t* +trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results); + +using traceNum_proto = int32_t(uint8_t const*, int32_t, int64_t); +wasm_trap_t* +traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results); + +using traceAccount_proto = + int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t); +wasm_trap_t* +traceAccount_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using traceFloat_proto = + int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t); +wasm_trap_t* +traceFloat_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using traceAmount_proto = + int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t); +wasm_trap_t* +traceAmount_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatFromInt_proto = int32_t(int64_t, uint8_t*, int32_t, int32_t); +wasm_trap_t* +floatFromInt_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatFromUint_proto = + int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t); +wasm_trap_t* +floatFromUint_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatSet_proto = int32_t(int32_t, int64_t, uint8_t*, int32_t, int32_t); +wasm_trap_t* +floatSet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results); + +using floatCompare_proto = + int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t); +wasm_trap_t* +floatCompare_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatAdd_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t, + int32_t); +wasm_trap_t* +floatAdd_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results); + +using floatSubtract_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t, + int32_t); +wasm_trap_t* +floatSubtract_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatMultiply_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t, + int32_t); +wasm_trap_t* +floatMultiply_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatDivide_proto = int32_t( + uint8_t const*, + int32_t, + uint8_t const*, + int32_t, + uint8_t*, + int32_t, + int32_t); +wasm_trap_t* +floatDivide_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatRoot_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t, int32_t); +wasm_trap_t* +floatRoot_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatPower_proto = + int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t, int32_t); +wasm_trap_t* +floatPower_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results); + +using floatLog_proto = + int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t); +wasm_trap_t* +floatLog_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results); + +} // namespace ripple diff --git a/src/xrpld/app/wasm/ParamsHelper.h b/src/xrpld/app/wasm/ParamsHelper.h new file mode 100644 index 00000000000..7f183895526 --- /dev/null +++ b/src/xrpld/app/wasm/ParamsHelper.h @@ -0,0 +1,266 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== +#pragma once + +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace bft = boost::function_types; + +namespace ripple { + +using Bytes = std::vector; +using Hash = ripple::uint256; + +struct wmem +{ + std::uint8_t* p = nullptr; + std::size_t s = 0; +}; + +template +struct WasmResult +{ + T result; + int64_t cost; +}; +typedef WasmResult EscrowResult; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +enum WasmTypes { WT_I32, WT_I64, WT_U8V }; + +struct WasmImportFunc +{ + std::string name; + std::optional result; + std::vector params; + void* udata = nullptr; + // wasm_func_callback_with_env_t + void* wrap = nullptr; + uint32_t gas = 0; +}; + +#define WASM_IMPORT_FUNC(v, f, ...) \ + WasmImpFunc( \ + v, #f, reinterpret_cast(&f##_wrap), ##__VA_ARGS__) + +#define WASM_IMPORT_FUNC2(v, f, n, ...) \ + WasmImpFunc( \ + v, n, reinterpret_cast(&f##_wrap), ##__VA_ARGS__) + +template +void +WasmImpArgs(WasmImportFunc& e) +{ + if constexpr (N < C) + { + using at = typename boost::mpl::at_c::type; + if constexpr (std::is_pointer_v) + e.params.push_back(WT_I32); + else if constexpr (std::is_same_v) + e.params.push_back(WT_I32); + else if constexpr (std::is_same_v) + e.params.push_back(WT_I64); + else + static_assert(std::is_pointer_v, "Unsupported argument type"); + + return WasmImpArgs(e); + } + return; +} + +template +void +WasmImpRet(WasmImportFunc& e) +{ + if constexpr (std::is_pointer_v) + e.result = WT_I32; + else if constexpr (std::is_same_v) + e.result = WT_I32; + else if constexpr (std::is_same_v) + e.result = WT_I64; + else if constexpr (std::is_void_v) + e.result.reset(); +#if (defined(__GNUC__) && (__GNUC__ >= 14)) || \ + ((defined(__clang_major__)) && (__clang_major__ >= 18)) + else + static_assert(false, "Unsupported return type"); +#endif +} + +template +void +WasmImpFuncHelper(WasmImportFunc& e) +{ + using rt = typename bft::result_type::type; + using pt = typename bft::parameter_types::type; + // typename boost::mpl::at_c::type + + WasmImpRet(e); + WasmImpArgs<0, bft::function_arity::value, pt>(e); + // WasmImpWrap(e, std::forward(f)); +} + +template +void +WasmImpFunc( + std::vector& v, + std::string_view imp_name, + void* f_wrap, + void* data = nullptr, + uint32_t gas = 0) +{ + WasmImportFunc e; + e.name = imp_name; + e.udata = data; + e.wrap = f_wrap; + e.gas = gas; + WasmImpFuncHelper(e); + v.push_back(std::move(e)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +struct WasmParamVec +{ + std::uint8_t const* d = nullptr; + std::int32_t sz = 0; +}; + +struct WasmParam +{ + WasmTypes type = WT_I32; + union + { + std::int32_t i32; + std::int64_t i64 = 0; + float f32; + double f64; + WasmParamVec u8v; + } of; +}; + +template +inline void +wasmParamsHlp(std::vector& v, std::int32_t p, Types&&... args) +{ + v.push_back({.type = WT_I32, .of = {.i32 = p}}); + wasmParamsHlp(v, std::forward(args)...); +} + +template +inline void +wasmParamsHlp(std::vector& v, std::int64_t p, Types&&... args) +{ + v.push_back({.type = WT_I64, .of = {.i64 = p}}); + wasmParamsHlp(v, std::forward(args)...); +} + +// We are not supporting float/double for now +// Leaving this code here so that it is easier to add later if needed +// template +// inline void +// wasmParamsHlp(std::vector& v, float p, Types&&... args) +// { +// v.push_back({.type = WT_F32, .of = {.f32 = p}}); +// wasmParamsHlp(v, std::forward(args)...); +// } + +// template +// inline void +// wasmParamsHlp(std::vector& v, double p, Types&&... args) +// { +// v.push_back({.type = WT_F64, .of = {.f64 = p}}); +// wasmParamsHlp(v, std::forward(args)...); +// } + +template +inline void +wasmParamsHlp( + std::vector& v, + std::uint8_t const* dt, + std::int32_t sz, + Types&&... args) +{ + v.push_back({.type = WT_U8V, .of = {.u8v = {.d = dt, .sz = sz}}}); + wasmParamsHlp(v, std::forward(args)...); +} + +template +inline void +wasmParamsHlp(std::vector& v, Bytes const& p, Types&&... args) +{ + wasmParamsHlp( + v, + p.data(), + static_cast(p.size()), + std::forward(args)...); +} + +template +inline void +wasmParamsHlp( + std::vector& v, + std::string_view const& p, + Types&&... args) +{ + wasmParamsHlp( + v, + reinterpret_cast(p.data()), + static_cast(p.size()), + std::forward(args)...); +} + +template +inline void +wasmParamsHlp(std::vector& v, std::string const& p, Types&&... args) +{ + wasmParamsHlp( + v, + reinterpret_cast(p.c_str()), + static_cast(p.size()), + std::forward(args)...); +} + +inline void +wasmParamsHlp(std::vector& v) +{ + return; +} + +template +inline std::vector +wasmParams(Types&&... args) +{ + std::vector v; + v.reserve(sizeof...(args)); + wasmParamsHlp(v, std::forward(args)...); + return v; +} + +} // namespace ripple diff --git a/src/xrpld/app/wasm/WamrVM.h b/src/xrpld/app/wasm/WamrVM.h new file mode 100644 index 00000000000..a32257feb6c --- /dev/null +++ b/src/xrpld/app/wasm/WamrVM.h @@ -0,0 +1,327 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2023 Ripple Labs Inc. + + 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. +*/ +//============================================================================== +#pragma once + +#include + +#include +#include + +namespace ripple { + +struct WamrResult +{ + wasm_val_vec_t r; + bool f; // failure flag + + WamrResult(unsigned N = 0) : r{0, nullptr, 0, 0, nullptr}, f(false) + { + if (N) + wasm_val_vec_new_uninitialized(&r, N); + } + + ~WamrResult() + { + if (r.size) + wasm_val_vec_delete(&r); + } + + WamrResult(WamrResult const&) = delete; + WamrResult& + operator=(WamrResult const&) = delete; + + WamrResult(WamrResult&& o) + { + *this = std::move(o); + } + + WamrResult& + operator=(WamrResult&& o) + { + r = o.r; + o.r = {0, nullptr, 0, 0, nullptr}; + f = o.f; + o.f = false; + return *this; + } + // operator wasm_val_vec_t &() {return r;} +}; + +using ModulePtr = std::unique_ptr; +using InstancePtr = + std::unique_ptr; + +using FuncInfo = std::pair; + +struct InstanceWrapper +{ + wasm_extern_vec_t exports_; + InstancePtr instance_; + wasm_exec_env_t execEnv_ = nullptr; + beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); + +private: + static InstancePtr + init( + wasm_store_t* s, + wasm_module_t* m, + int32_t maxPages, + wasm_extern_vec_t* expt, + wasm_extern_vec_t const& imports, + beast::Journal j); + +public: + InstanceWrapper(); + + InstanceWrapper(InstanceWrapper&& o); + + InstanceWrapper& + operator=(InstanceWrapper&& o); + + InstanceWrapper( + wasm_store_t* s, + wasm_module_t* m, + int32_t maxPages, + int64_t gas, + wasm_extern_vec_t const& imports, + beast::Journal j); + + ~InstanceWrapper(); + + operator bool() const; + + FuncInfo + getFunc( + std::string_view funcName, + wasm_exporttype_vec_t const& export_types) const; + + wmem + getMem() const; + + std::int64_t + getGas() const; +}; + +struct ModuleWrapper +{ + ModulePtr module_; + InstanceWrapper instanceWrap_; + wasm_exporttype_vec_t exportTypes_; + beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); + +private: + static ModulePtr + init(wasm_store_t* s, Bytes const& wasmBin, beast::Journal j); + +public: + ModuleWrapper(); + ModuleWrapper(ModuleWrapper&& o); + ModuleWrapper& + operator=(ModuleWrapper&& o); + ModuleWrapper( + wasm_store_t* s, + Bytes const& wasmBin, + bool instantiate, + int32_t maxPages, + int64_t gas, + std::vector const& imports, + beast::Journal j); + ~ModuleWrapper(); + + operator bool() const; + + FuncInfo + getFunc(std::string_view funcName) const; + wmem + getMem() const; + + InstanceWrapper const& + getInstance(int i = 0) const; + + int + addInstance( + wasm_store_t* s, + int32_t maxPages, + int64_t gas, + wasm_extern_vec_t const& imports = WASM_EMPTY_VEC); + + std::int64_t + getGas(); + +private: + static void + makeImpParams(wasm_valtype_vec_t& v, WasmImportFunc const& imp); + static void + makeImpReturn(wasm_valtype_vec_t& v, WasmImportFunc const& imp); + wasm_extern_vec_t + buildImports(wasm_store_t* s, std::vector const& imports); +}; + +class WamrEngine +{ + std::unique_ptr engine_; + std::unique_ptr store_; + std::unique_ptr moduleWrap_; + std::int32_t defMaxPages_ = -1; + beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); + + std::mutex m_; // 1 instance mutex + +public: + WamrEngine(); + ~WamrEngine() = default; + + Expected, TER> + run(Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports, + HostFunctions* hfs, + int64_t gas, + beast::Journal j); + + NotTEC + check( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports, + beast::Journal j); + + std::int32_t + initMaxPages(std::int32_t def); + + std::int64_t + getGas(); + + // Host functions helper functionality + wasm_trap_t* + newTrap(std::string_view msg); + + beast::Journal + getJournal() const; + +private: + InstanceWrapper const& + getRT(int m = 0, int i = 0); + + wmem + getMem() const; + + int32_t + allocate(int32_t size); + + Expected, TER> + runHlp( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports, + HostFunctions* hfs, + int64_t gas); + + NotTEC + checkHlp( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports); + + int + addModule( + Bytes const& wasmCode, + bool instantiate, + int64_t gas, + std::vector const& imports); + void + clearModules(); + + // int addInstance(); + + int32_t + runFunc(std::string_view const funcName, int32_t p); + + int32_t + makeModule( + Bytes const& wasmCode, + wasm_extern_vec_t const& imports = WASM_EMPTY_VEC); + + FuncInfo + getFunc(std::string_view funcName); + + std::vector + convertParams(std::vector const& params); + + static int + compareParamTypes( + wasm_valtype_vec_t const* ftp, + std::vector const& p); + + static void + add_param(std::vector& in, int32_t p); + static void + add_param(std::vector& in, int64_t p); + + template + inline WamrResult + call(std::string_view func, Types&&... args); + + template + inline WamrResult + call(FuncInfo const& f, Types&&... args); + + template + inline WamrResult + call(FuncInfo const& f, std::vector& in); + + template + inline WamrResult + call( + FuncInfo const& f, + std::vector& in, + std::int32_t p, + Types&&... args); + + template + inline WamrResult + call( + FuncInfo const& f, + std::vector& in, + std::int64_t p, + Types&&... args); + + template + inline WamrResult + call( + FuncInfo const& f, + std::vector& in, + uint8_t const* d, + std::size_t sz, + Types&&... args); + + template + inline WamrResult + call( + FuncInfo const& f, + std::vector& in, + Bytes const& p, + Types&&... args); +}; + +} // namespace ripple diff --git a/src/xrpld/app/wasm/WasmVM.h b/src/xrpld/app/wasm/WasmVM.h new file mode 100644 index 00000000000..32eb239f609 --- /dev/null +++ b/src/xrpld/app/wasm/WasmVM.h @@ -0,0 +1,111 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== +#pragma once + +#include + +#include + +namespace ripple { + +static std::string_view const W_ENV = "env"; +static std::string_view const W_HOST_LIB = "host_lib"; +static std::string_view const W_MEM = "memory"; +static std::string_view const W_STORE = "store"; +static std::string_view const W_LOAD = "load"; +static std::string_view const W_SIZE = "size"; +static std::string_view const W_ALLOC = "allocate"; +static std::string_view const W_DEALLOC = "deallocate"; +static std::string_view const W_PROC_EXIT = "proc_exit"; + +static std::string_view const ESCROW_FUNCTION_NAME = "finish"; + +uint32_t const MAX_PAGES = 128; // 8MB = 64KB*128 + +class WamrEngine; +class WasmEngine +{ + std::unique_ptr const impl; + + WasmEngine(); + + WasmEngine(WasmEngine const&) = delete; + WasmEngine(WasmEngine&&) = delete; + WasmEngine& + operator=(WasmEngine const&) = delete; + WasmEngine& + operator=(WasmEngine&&) = delete; + +public: + ~WasmEngine() = default; + + static WasmEngine& + instance(); + + Expected, TER> + run(Bytes const& wasmCode, + std::string_view funcName = {}, + std::vector const& params = {}, + std::vector const& imports = {}, + HostFunctions* hfs = nullptr, + int64_t gasLimit = -1, + beast::Journal j = beast::Journal{beast::Journal::getNullSink()}); + + NotTEC + check( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params = {}, + std::vector const& imports = {}, + beast::Journal j = beast::Journal{beast::Journal::getNullSink()}); + + std::int32_t + initMaxPages(std::int32_t def); + + // Host functions helper functionality + void* + newTrap(std::string_view msg = {}); + + beast::Journal + getJournal() const; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +std::vector +createWasmImport(HostFunctions* hfs); + +Expected +runEscrowWasm( + Bytes const& wasmCode, + std::string_view funcName = ESCROW_FUNCTION_NAME, + std::vector const& params = {}, + HostFunctions* hfs = nullptr, + int64_t gasLimit = -1, + beast::Journal j = beast::Journal(beast::Journal::getNullSink())); + +NotTEC +preflightEscrowWasm( + Bytes const& wasmCode, + std::string_view funcName = ESCROW_FUNCTION_NAME, + std::vector const& params = {}, + HostFunctions* hfs = nullptr, + beast::Journal j = beast::Journal(beast::Journal::getNullSink())); + +} // namespace ripple diff --git a/src/xrpld/app/wasm/detail/HostFuncImpl.cpp b/src/xrpld/app/wasm/detail/HostFuncImpl.cpp new file mode 100644 index 00000000000..f6517767dcd --- /dev/null +++ b/src/xrpld/app/wasm/detail/HostFuncImpl.cpp @@ -0,0 +1,1324 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#include +#include +#include + +#include +#include + +#ifdef _DEBUG +// #define DEBUG_OUTPUT 1 +// #define DEBUG_OUTPUT_WAMR 1 +#endif + +namespace ripple { + +Expected +WasmHostFunctionsImpl::getLedgerSqn() +{ + auto seq = ctx.view().seq(); + if (seq > std::numeric_limits::max()) + return Unexpected(HostFunctionError::INTERNAL); // LCOV_EXCL_LINE + return static_cast(seq); +} + +Expected +WasmHostFunctionsImpl::getParentLedgerTime() +{ + auto time = ctx.view().parentCloseTime().time_since_epoch().count(); + if (time > std::numeric_limits::max()) + return Unexpected(HostFunctionError::INTERNAL); + return static_cast(time); +} + +Expected +WasmHostFunctionsImpl::getParentLedgerHash() +{ + return ctx.view().info().parentHash; +} + +Expected +WasmHostFunctionsImpl::getBaseFee() +{ + auto fee = ctx.view().fees().base.drops(); + if (fee > std::numeric_limits::max()) + return Unexpected(HostFunctionError::INTERNAL); + return static_cast(fee); +} + +Expected +WasmHostFunctionsImpl::isAmendmentEnabled(uint256 const& amendmentId) +{ + return ctx.view().rules().enabled(amendmentId); +} + +Expected +WasmHostFunctionsImpl::isAmendmentEnabled(std::string_view const& amendmentName) +{ + auto const& table = ctx.app.getAmendmentTable(); + auto const amendment = table.find(std::string(amendmentName)); + return ctx.view().rules().enabled(amendment); +} + +Expected +WasmHostFunctionsImpl::cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) +{ + auto const& keylet = keylet::unchecked(objId); + if (cacheIdx < 0 || cacheIdx > MAX_CACHE) + return Unexpected(HostFunctionError::SLOT_OUT_RANGE); + + if (cacheIdx == 0) + { + for (cacheIdx = 0; cacheIdx < MAX_CACHE; ++cacheIdx) + if (!cache[cacheIdx]) + break; + } + else + { + cacheIdx--; // convert to 0-based index + } + + if (cacheIdx >= MAX_CACHE) + return Unexpected(HostFunctionError::SLOTS_FULL); + + cache[cacheIdx] = ctx.view().read(keylet); + if (!cache[cacheIdx]) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + return cacheIdx + 1; // return 1-based index +} + +static Expected +getAnyFieldData(STBase const* obj) +{ + // auto const& fname = obj.getFName(); + if (!obj) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + auto const stype = obj->getSType(); + switch (stype) + { + // LCOV_EXCL_START + case STI_UNKNOWN: + case STI_NOTPRESENT: + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + break; + // LCOV_EXCL_STOP + case STI_OBJECT: + case STI_ARRAY: + return Unexpected(HostFunctionError::NOT_LEAF_FIELD); + break; + case STI_ACCOUNT: { + auto const* account(static_cast(obj)); + auto const& data = account->value(); + return Bytes{data.begin(), data.end()}; + } + break; + case STI_AMOUNT: + // will be processed by serializer + break; + case STI_ISSUE: { + auto const* issue(static_cast(obj)); + Asset const& asset(issue->value()); + // XRP and IOU will be processed by serializer + if (asset.holds()) + { + // MPT + auto const& mptIssue = asset.get(); + auto const& mptID = mptIssue.getMptID(); + return Bytes{mptID.cbegin(), mptID.cend()}; + } + } + break; + case STI_VL: { + auto const* vl(static_cast(obj)); + auto const& data = vl->value(); + return Bytes{data.begin(), data.end()}; + } + break; + case STI_UINT16: { + auto const& num(static_cast const*>(obj)); + std::uint16_t const data = num->value(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return Bytes{b, e}; + } + case STI_UINT32: { + auto const* num(static_cast const*>(obj)); + std::uint32_t const data = num->value(); + auto const* b = reinterpret_cast(&data); + auto const* e = reinterpret_cast(&data + 1); + return Bytes{b, e}; + } + break; + default: + break; // default to serializer + } + + Serializer msg; + obj->add(msg); + auto const data = msg.getData(); + + return data; +} + +Expected +WasmHostFunctionsImpl::getTxField(SField const& fname) +{ + return getAnyFieldData(ctx.tx.peekAtPField(fname)); +} + +Expected +WasmHostFunctionsImpl::getCurrentLedgerObjField(SField const& fname) +{ + auto const sle = getCurrentLedgerObj(); + if (!sle.has_value()) + return Unexpected(sle.error()); + return getAnyFieldData(sle.value()->peekAtPField(fname)); +} + +Expected +WasmHostFunctionsImpl::getLedgerObjField(int32_t cacheIdx, SField const& fname) +{ + auto const normalizedIdx = normalizeCacheIndex(cacheIdx); + if (!normalizedIdx.has_value()) + return Unexpected(normalizedIdx.error()); + return getAnyFieldData(cache[normalizedIdx.value()]->peekAtPField(fname)); +} + +static inline bool +noField(STBase const* field) +{ + return !field || (STI_NOTPRESENT == field->getSType()) || + (STI_UNKNOWN == field->getSType()); +} + +static Expected +locateField(STObject const& obj, Slice const& locator) +{ + if (locator.empty() || (locator.size() & 3)) // must be multiple of 4 + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + + int32_t const* locPtr = reinterpret_cast(locator.data()); + int32_t const locSize = locator.size() / 4; + STBase const* field = nullptr; + auto const& knownSFields = SField::getKnownCodeToField(); + + { + int32_t const sfieldCode = locPtr[0]; + auto const it = knownSFields.find(sfieldCode); + if (it == knownSFields.end()) + return Unexpected(HostFunctionError::INVALID_FIELD); + + auto const& fname(*it->second); + field = obj.peekAtPField(fname); + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + } + + for (int i = 1; i < locSize; ++i) + { + int32_t const sfieldCode = locPtr[i]; + + if (STI_ARRAY == field->getSType()) + { + auto const* arr = static_cast(field); + if (sfieldCode >= arr->size()) + return Unexpected(HostFunctionError::INDEX_OUT_OF_BOUNDS); + field = &(arr->operator[](sfieldCode)); + } + else if (STI_OBJECT == field->getSType()) + { + auto const* o = static_cast(field); + + auto const it = knownSFields.find(sfieldCode); + if (it == knownSFields.end()) + return Unexpected(HostFunctionError::INVALID_FIELD); + + auto const& fname(*it->second); + field = o->peekAtPField(fname); + } + else // simple field must be the last one + { + return Unexpected(HostFunctionError::LOCATOR_MALFORMED); + } + + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + } + + return field; +} + +Expected +WasmHostFunctionsImpl::getTxNestedField(Slice const& locator) +{ + auto const r = locateField(ctx.tx, locator); + if (!r) + return Unexpected(r.error()); + + return getAnyFieldData(r.value()); +} + +Expected +WasmHostFunctionsImpl::getCurrentLedgerObjNestedField(Slice const& locator) +{ + auto const sle = getCurrentLedgerObj(); + if (!sle.has_value()) + return Unexpected(sle.error()); + + auto const r = locateField(*sle.value(), locator); + if (!r) + return Unexpected(r.error()); + + return getAnyFieldData(r.value()); +} + +Expected +WasmHostFunctionsImpl::getLedgerObjNestedField( + int32_t cacheIdx, + Slice const& locator) +{ + auto const normalizedIdx = normalizeCacheIndex(cacheIdx); + if (!normalizedIdx.has_value()) + return Unexpected(normalizedIdx.error()); + + auto const r = locateField(*cache[normalizedIdx.value()], locator); + if (!r) + return Unexpected(r.error()); + + return getAnyFieldData(r.value()); +} + +Expected +WasmHostFunctionsImpl::getTxArrayLen(SField const& fname) +{ + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + auto const* field = ctx.tx.peekAtPField(fname); + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); // LCOV_EXCL_LINE + int32_t const sz = static_cast(field)->size(); + + return sz; +} + +Expected +WasmHostFunctionsImpl::getCurrentLedgerObjArrayLen(SField const& fname) +{ + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + auto const sle = getCurrentLedgerObj(); + if (!sle.has_value()) + return Unexpected(sle.error()); + + auto const* field = sle.value()->peekAtPField(fname); + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); // LCOV_EXCL_LINE + int32_t const sz = static_cast(field)->size(); + + return sz; +} + +Expected +WasmHostFunctionsImpl::getLedgerObjArrayLen( + int32_t cacheIdx, + SField const& fname) +{ + if (fname.fieldType != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + + auto const normalizedIdx = normalizeCacheIndex(cacheIdx); + if (!normalizedIdx.has_value()) + return Unexpected(normalizedIdx.error()); + + auto const* field = cache[normalizedIdx.value()]->peekAtPField(fname); + if (noField(field)) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); // LCOV_EXCL_LINE + + int32_t const sz = static_cast(field)->size(); + + return sz; +} + +Expected +WasmHostFunctionsImpl::getTxNestedArrayLen(Slice const& locator) +{ + auto const r = locateField(ctx.tx, locator); + if (!r) + return Unexpected(r.error()); + + auto const* field = r.value(); + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; +} + +Expected +WasmHostFunctionsImpl::getCurrentLedgerObjNestedArrayLen(Slice const& locator) +{ + auto const sle = getCurrentLedgerObj(); + if (!sle.has_value()) + return Unexpected(sle.error()); + auto const r = locateField(*sle.value(), locator); + if (!r) + return Unexpected(r.error()); + + auto const* field = r.value(); + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; +} + +Expected +WasmHostFunctionsImpl::getLedgerObjNestedArrayLen( + int32_t cacheIdx, + Slice const& locator) +{ + auto const normalizedIdx = normalizeCacheIndex(cacheIdx); + if (!normalizedIdx.has_value()) + return Unexpected(normalizedIdx.error()); + + auto const r = locateField(*cache[normalizedIdx.value()], locator); + if (!r) + return Unexpected(r.error()); + + auto const* field = r.value(); + if (field->getSType() != STI_ARRAY) + return Unexpected(HostFunctionError::NO_ARRAY); + int32_t const sz = static_cast(field)->size(); + + return sz; +} + +Expected +WasmHostFunctionsImpl::updateData(Slice const& data) +{ + if (data.size() > maxWasmDataLength) + { + return Unexpected(HostFunctionError::DATA_FIELD_TOO_LARGE); + } + data_ = Bytes(data.begin(), data.end()); + return 0; +} + +Expected +WasmHostFunctionsImpl::checkSignature( + Slice const& message, + Slice const& signature, + Slice const& pubkey) +{ + if (!publicKeyType(pubkey)) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + PublicKey const pk(pubkey); + return verify(pk, message, signature, /*canonical*/ true); +} + +Expected +WasmHostFunctionsImpl::computeSha512HalfHash(Slice const& data) +{ + auto const hash = sha512Half(data); + return hash; +} + +Expected +WasmHostFunctionsImpl::accountKeylet(AccountID const& account) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::account(account); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::ammKeylet(Asset const& issue1, Asset const& issue2) +{ + if (issue1 == issue2) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + // note: this should be removed with the MPT DEX amendment + if (issue1.holds() || issue2.holds()) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + auto const keylet = keylet::amm(issue1, issue2); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::checkKeylet(AccountID const& account, std::uint32_t seq) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::check(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::credentialKeylet( + AccountID const& subject, + AccountID const& issuer, + Slice const& credentialType) +{ + if (!subject || !issuer) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + + if (credentialType.empty() || + credentialType.size() > maxCredentialTypeLength) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + auto const keylet = keylet::credential(subject, issuer, credentialType); + + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::didKeylet(AccountID const& account) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::did(account); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::delegateKeylet( + AccountID const& account, + AccountID const& authorize) +{ + if (!account || !authorize) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + if (account == authorize) + return Unexpected(HostFunctionError::INVALID_PARAMS); + auto const keylet = keylet::delegate(account, authorize); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::depositPreauthKeylet( + AccountID const& account, + AccountID const& authorize) +{ + if (!account || !authorize) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + if (account == authorize) + return Unexpected(HostFunctionError::INVALID_PARAMS); + auto const keylet = keylet::depositPreauth(account, authorize); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::escrowKeylet(AccountID const& account, std::uint32_t seq) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::escrow(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::lineKeylet( + AccountID const& account1, + AccountID const& account2, + Currency const& currency) +{ + if (!account1 || !account2) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + if (account1 == account2) + return Unexpected(HostFunctionError::INVALID_PARAMS); + if (currency.isZero()) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + auto const keylet = keylet::line(account1, account2, currency); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::mptIssuanceKeylet( + AccountID const& issuer, + std::uint32_t seq) +{ + if (!issuer) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + + auto const keylet = keylet::mptIssuance(seq, issuer); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::mptokenKeylet( + MPTID const& mptid, + AccountID const& holder) +{ + if (!mptid) + return Unexpected(HostFunctionError::INVALID_PARAMS); + if (!holder) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + + auto const keylet = keylet::mptoken(mptid, holder); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::nftOfferKeylet( + AccountID const& account, + std::uint32_t seq) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::nftoffer(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::offerKeylet(AccountID const& account, std::uint32_t seq) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::offer(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::oracleKeylet( + AccountID const& account, + std::uint32_t documentId) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::oracle(account, documentId); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::paychanKeylet( + AccountID const& account, + AccountID const& destination, + std::uint32_t seq) +{ + if (!account || !destination) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + if (account == destination) + return Unexpected(HostFunctionError::INVALID_PARAMS); + auto const keylet = keylet::payChan(account, destination, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::permissionedDomainKeylet( + AccountID const& account, + std::uint32_t seq) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::permissionedDomain(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::signersKeylet(AccountID const& account) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::signers(account); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::ticketKeylet(AccountID const& account, std::uint32_t seq) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::ticket(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::vaultKeylet(AccountID const& account, std::uint32_t seq) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + auto const keylet = keylet::vault(account, seq); + return Bytes{keylet.key.begin(), keylet.key.end()}; +} + +Expected +WasmHostFunctionsImpl::getNFT(AccountID const& account, uint256 const& nftId) +{ + if (!account) + return Unexpected(HostFunctionError::INVALID_ACCOUNT); + + if (!nftId) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + auto obj = nft::findToken(ctx.view(), account, nftId); + if (!obj) + return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND); + + auto ouri = obj->at(~sfURI); + if (!ouri) + return Unexpected(HostFunctionError::FIELD_NOT_FOUND); + + Slice const s = ouri->value(); + return Bytes(s.begin(), s.end()); +} + +Expected +WasmHostFunctionsImpl::getNFTIssuer(uint256 const& nftId) +{ + auto const issuer = nft::getIssuer(nftId); + if (!issuer) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + return Bytes{issuer.begin(), issuer.end()}; +} + +Expected +WasmHostFunctionsImpl::getNFTTaxon(uint256 const& nftId) +{ + return nft::toUInt32(nft::getTaxon(nftId)); +} + +Expected +WasmHostFunctionsImpl::getNFTFlags(uint256 const& nftId) +{ + return nft::getFlags(nftId); +} + +Expected +WasmHostFunctionsImpl::getNFTTransferFee(uint256 const& nftId) +{ + return nft::getTransferFee(nftId); +} + +Expected +WasmHostFunctionsImpl::getNFTSerial(uint256 const& nftId) +{ + return nft::getSerial(nftId); +} + +Expected +WasmHostFunctionsImpl::trace( + std::string_view const& msg, + Slice const& data, + bool asHex) +{ +#ifdef DEBUG_OUTPUT + auto j = getJournal().error(); +#else + auto j = getJournal().trace(); +#endif + if (!asHex) + { + j << "WAMR TRACE (" << leKey.key << "): " << msg << " " + << std::string_view( + reinterpret_cast(data.data()), data.size()); + } + else + { + std::string hex; + hex.reserve(data.size() * 2); + boost::algorithm::hex( + data.begin(), data.end(), std::back_inserter(hex)); + j << "WAMR DEV TRACE (" << leKey.key << "): " << msg << " " << hex; + } + + return msg.size() + data.size() * (asHex ? 2 : 1); +} + +Expected +WasmHostFunctionsImpl::traceNum(std::string_view const& msg, int64_t data) +{ +#ifdef DEBUG_OUTPUT + auto j = getJournal().error(); +#else + auto j = getJournal().trace(); +#endif + j << "WAMR TRACE NUM(" << leKey.key << "): " << msg << " " << data; + return msg.size() + sizeof(data); +} + +Expected +WasmHostFunctionsImpl::traceAccount( + std::string_view const& msg, + AccountID const& account) +{ +#ifdef DEBUG_OUTPUT + auto j = getJournal().error(); +#else + auto j = getJournal().trace(); +#endif + + auto const accountStr = toBase58(account); + + j << "WAMR TRACE ACCOUNT(" << leKey.key << "): " << msg << " " + << accountStr; + return msg.size() + accountStr.size(); +} + +Expected +WasmHostFunctionsImpl::traceFloat( + std::string_view const& msg, + Slice const& data) +{ +#ifdef DEBUG_OUTPUT + auto j = getJournal().error(); +#else + auto j = getJournal().trace(); +#endif + auto const s = floatToString(data); + j << "WAMR TRACE FLOAT(" << leKey.key << "): " << msg << " " << s; + return msg.size() + s.size(); +} + +Expected +WasmHostFunctionsImpl::traceAmount( + std::string_view const& msg, + STAmount const& amount) +{ +#ifdef DEBUG_OUTPUT + auto j = getJournal().error(); +#else + auto j = getJournal().trace(); +#endif + auto const amountStr = amount.getFullText(); + j << "WAMR TRACE AMOUNT(" << leKey.key << "): " << msg << " " << amountStr; + return msg.size() + amountStr.size(); +} + +Expected +WasmHostFunctionsImpl::floatFromInt(int64_t x, int32_t mode) +{ + return floatFromIntImpl(x, mode); +} + +Expected +WasmHostFunctionsImpl::floatFromUint(uint64_t x, int32_t mode) +{ + return floatFromUintImpl(x, mode); +} + +Expected +WasmHostFunctionsImpl::floatSet( + int64_t mantissa, + int32_t exponent, + int32_t mode) +{ + return floatSetImpl(mantissa, exponent, mode); +} + +Expected +WasmHostFunctionsImpl::floatCompare(Slice const& x, Slice const& y) +{ + return floatCompareImpl(x, y); +} + +Expected +WasmHostFunctionsImpl::floatAdd(Slice const& x, Slice const& y, int32_t mode) +{ + return floatAddImpl(x, y, mode); +} + +Expected +WasmHostFunctionsImpl::floatSubtract( + Slice const& x, + Slice const& y, + int32_t mode) +{ + return floatSubtractImpl(x, y, mode); +} + +Expected +WasmHostFunctionsImpl::floatMultiply( + Slice const& x, + Slice const& y, + int32_t mode) +{ + return floatMultiplyImpl(x, y, mode); +} + +Expected +WasmHostFunctionsImpl::floatDivide(Slice const& x, Slice const& y, int32_t mode) +{ + return floatDivideImpl(x, y, mode); +} + +Expected +WasmHostFunctionsImpl::floatRoot(Slice const& x, int32_t n, int32_t mode) +{ + return floatRootImpl(x, n, mode); +} + +Expected +WasmHostFunctionsImpl::floatPower(Slice const& x, int32_t n, int32_t mode) +{ + return floatPowerImpl(x, n, mode); +} + +Expected +WasmHostFunctionsImpl::floatLog(Slice const& x, int32_t mode) +{ + return floatLogImpl(x, mode); +} + +class Number2 : public Number +{ +protected: + static Bytes const FLOAT_NULL; + + bool good_; + +public: + Number2(Slice const& data) : Number(), good_(false) + { + if (data.size() != 8) + return; + + if (std::ranges::equal(FLOAT_NULL, data)) + { + good_ = true; + return; + } + + uint64_t const v = SerialIter(data).get64(); + if (!(v & STAmount::cIssuedCurrency)) + return; + + int64_t const neg = (v & STAmount::cPositive) ? 1 : -1; + int32_t const e = static_cast((v >> (64 - 10)) & 0xFFull); + if (e < 1 || e > 177) + return; + + int64_t const m = neg * static_cast(v & ((1ull << 54) - 1)); + if (!m) + return; + + Number x(m, e + IOUAmount::minExponent - 1); + *static_cast(this) = x; + good_ = true; + } + + Number2() : Number(), good_(true) + { + } + + Number2(int64_t x) : Number(x), good_(true) + { + } + + Number2(uint64_t x) : Number(0), good_(false) + { + using mtype = std::invoke_result_t; + if (x <= std::numeric_limits::max()) + *this = Number(x); + else + *this = Number(x / 10, 1) + Number(x % 10); + + good_ = true; + } + + Number2(int64_t mantissa, int32_t exponent) + : Number(mantissa, exponent), good_(true) + { + } + + Number2(Number const& n) : Number(n), good_(true) + { + } + + operator bool() const + { + return good_; + } + + Expected + toBytes() const + { + uint64_t v = mantissa() >= 0 ? STAmount::cPositive : 0; + v |= STAmount::cIssuedCurrency; + + uint64_t const absM = mantissa() >= 0 ? mantissa() : -mantissa(); + if (!absM) + { + using etype = + std::invoke_result_t; + if (exponent() != std::numeric_limits::lowest()) + { + return Unexpected( + HostFunctionError:: + FLOAT_COMPUTATION_ERROR); // LCOV_EXCL_LINE + } + return FLOAT_NULL; + } + else if (absM > ((1ull << 54) - 1)) + { + return Unexpected( + HostFunctionError::FLOAT_COMPUTATION_ERROR); // LCOV_EXCL_LINE + } + else if (exponent() > IOUAmount::maxExponent) + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + else if (exponent() < IOUAmount::minExponent) + return FLOAT_NULL; + + int const e = exponent() - IOUAmount::minExponent + 1; //+97 + v |= absM; + v |= ((uint64_t)e) << 54; + + Serializer msg; + msg.add64(v); + auto const data = msg.getData(); + +#ifdef DEBUG_OUTPUT + std::cout << "m: " << std::setw(20) << mantissa() + << ", e: " << std::setw(12) << exponent() << ", hex: "; + std::cout << std::hex << std::uppercase << std::setfill('0'); + for (auto const& c : data) + std::cout << std::setw(2) << (unsigned)c << " "; + std::cout << std::dec << std::setfill(' ') << std::endl; +#endif + + return data; + } +}; + +Bytes const Number2::FLOAT_NULL = + {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +struct SetRound +{ + Number::rounding_mode oldMode_; + bool good_; + + SetRound(int32_t mode) : oldMode_(Number::getround()), good_(false) + { + if (mode < Number::rounding_mode::to_nearest || + mode > Number::rounding_mode::upward) + return; + + Number::setround(static_cast(mode)); + good_ = true; + } + + ~SetRound() + { + Number::setround(oldMode_); + } + + operator bool() const + { + return good_; + } +}; + +std::string +floatToString(Slice const& data) +{ + Number2 const num(data); + if (!num) + { + std::string hex; + hex.reserve(data.size() * 2); + boost::algorithm::hex( + data.begin(), data.end(), std::back_inserter(hex)); + return "Invalid data: " + hex; + } + + auto const s = to_string(num); + return s; +} + +Expected +floatFromIntImpl(int64_t x, int32_t mode) +{ + try + { + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + Number2 num(x); + return num.toBytes(); + } + // LCOV_EXCL_START + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP +} + +Expected +floatFromUintImpl(uint64_t x, int32_t mode) +{ + try + { + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + Number2 num(x); + return num.toBytes(); + } + // LCOV_EXCL_START + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP +} + +Expected +floatSetImpl(int64_t mantissa, int32_t exponent, int32_t mode) +{ + try + { + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 num(mantissa, exponent); + return num.toBytes(); + } + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); +} + +Expected +floatCompareImpl(Slice const& x, Slice const& y) +{ + try + { + Number2 xx(x); + if (!xx) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 yy(y); + if (!yy) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + return xx < yy ? 2 : (xx == yy ? 0 : 1); + } + // LCOV_EXCL_START + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP +} + +Expected +floatAddImpl(Slice const& x, Slice const& y, int32_t mode) +{ + try + { + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + Number2 xx(x); + if (!xx) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 yy(y); + if (!yy) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 res = xx + yy; + + return res.toBytes(); + } + // LCOV_EXCL_START + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP +} + +Expected +floatSubtractImpl(Slice const& x, Slice const& y, int32_t mode) +{ + try + { + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 xx(x); + if (!xx) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 yy(y); + if (!yy) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 res = xx - yy; + + return res.toBytes(); + } + // LCOV_EXCL_START + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP +} + +Expected +floatMultiplyImpl(Slice const& x, Slice const& y, int32_t mode) +{ + try + { + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 xx(x); + if (!xx) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 yy(y); + if (!yy) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 res = xx * yy; + + return res.toBytes(); + } + // LCOV_EXCL_START + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP +} + +Expected +floatDivideImpl(Slice const& x, Slice const& y, int32_t mode) +{ + try + { + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 xx(x); + if (!xx) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 yy(y); + if (!yy) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + Number2 res = xx / yy; + + return res.toBytes(); + } + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); +} + +Expected +floatRootImpl(Slice const& x, int32_t n, int32_t mode) +{ + try + { + if (n < 1) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + Number2 xx(x); + if (!xx) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + Number2 res(root(xx, n)); + + return res.toBytes(); + } + // LCOV_EXCL_START + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP +} + +Expected +floatPowerImpl(Slice const& x, int32_t n, int32_t mode) +{ + try + { + if ((n < 0) || (n > IOUAmount::maxExponent)) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + Number2 xx(x); + if (!xx) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + if (xx == Number() && !n) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + Number2 res(power(xx, n, 1)); + + return res.toBytes(); + } + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); +} + +Expected +floatLogImpl(Slice const& x, int32_t mode) +{ + try + { + SetRound rm(mode); + if (!rm) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + Number2 xx(x); + if (!xx) + return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED); + + Number2 res(lg(xx)); + + return res.toBytes(); + } + // LCOV_EXCL_START + catch (...) + { + } + return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP +} + +} // namespace ripple diff --git a/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp b/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp new file mode 100644 index 00000000000..d7995f6b32a --- /dev/null +++ b/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp @@ -0,0 +1,2041 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#include +#include +#include +#include + +#include +#include +#include + +namespace ripple { + +using SFieldCRef = std::reference_wrapper; + +static int32_t +setData( + InstanceWrapper const* runtime, + int32_t dst, + int32_t dstSize, + uint8_t const* src, + int32_t srcSize) +{ + if (!srcSize) + return 0; // LCOV_EXCL_LINE + + if (dst < 0 || dstSize < 0 || !src || srcSize < 0) + return HfErrorToInt(HostFunctionError::INVALID_PARAMS); + + auto memory = runtime ? runtime->getMem() : wmem(); + + // LCOV_EXCL_START + if (!memory.s) + return HfErrorToInt(HostFunctionError::NO_MEM_EXPORTED); + // LCOV_EXCL_STOP + if (dst + dstSize > memory.s) + return HfErrorToInt(HostFunctionError::POINTER_OUT_OF_BOUNDS); + if (srcSize > dstSize) + return HfErrorToInt(HostFunctionError::BUFFER_TOO_SMALL); + + memcpy(memory.p + dst, src, srcSize); + + return srcSize; +} + +template +Expected +getDataInt32(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const result = params->data[i].of.i32; + i++; + return result; +} + +template +Expected +getDataInt64(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const result = params->data[i].of.i64; + i++; + return result; +} + +template +Expected +getDataUInt64(IW const* runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const r = getDataSlice(runtime, params, i); + if (!r) + return Unexpected(r.error()); + if (r->size() != sizeof(uint64_t)) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + return *reinterpret_cast(r->data()); +} + +template +Expected +getDataSField(IW const* _runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const& m = SField::getKnownCodeToField(); + auto const it = m.find(params->data[i].of.i32); + if (it == m.end()) + { + return Unexpected(HostFunctionError::INVALID_FIELD); + } + i++; + return *it->second; +} + +template +Expected +getDataSlice( + IW const* runtime, + wasm_val_vec_t const* params, + int32_t& i, + bool isUpdate = false) +{ + auto const ptr = params->data[i].of.i32; + auto const size = params->data[i + 1].of.i32; + if (ptr < 0 || size < 0) + return Unexpected(HostFunctionError::INVALID_PARAMS); + + if (!size) + return Slice(); + + if (size > (isUpdate ? maxWasmDataLength : maxWasmParamLength)) + return Unexpected(HostFunctionError::DATA_FIELD_TOO_LARGE); + + auto memory = runtime ? runtime->getMem() : wmem(); + // LCOV_EXCL_START + if (!memory.s) + return Unexpected(HostFunctionError::NO_MEM_EXPORTED); + // LCOV_EXCL_STOP + + if (ptr + size > memory.s) + return Unexpected(HostFunctionError::POINTER_OUT_OF_BOUNDS); + + Slice data(memory.p + ptr, size); + i += 2; + return data; +} + +template +Expected +getDataUInt256(IW const* runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const slice = getDataSlice(runtime, params, i); + if (!slice) + { + return Unexpected(slice.error()); + } + + if (slice->size() != uint256::bytes) + { + return Unexpected(HostFunctionError::INVALID_PARAMS); + } + return uint256::fromVoid(slice->data()); +} + +template +Expected +getDataAccountID(IW const* runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const slice = getDataSlice(runtime, params, i); + if (!slice) + { + return Unexpected(slice.error()); + } + + if (slice->size() != AccountID::bytes) + { + return Unexpected(HostFunctionError::INVALID_PARAMS); + } + + return AccountID::fromVoid(slice->data()); +} + +template +static Expected +getDataCurrency(IW const* runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const slice = getDataSlice(runtime, params, i); + if (!slice) + { + return Unexpected(slice.error()); + } + + if (slice->size() != Currency::bytes) + { + return Unexpected(HostFunctionError::INVALID_PARAMS); + } + + return Currency::fromVoid(slice->data()); +} + +template +static Expected +getDataAsset(IW const* runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const slice = getDataSlice(runtime, params, i); + if (!slice) + { + return Unexpected(slice.error()); + } + + if (slice->size() == MPTID::bytes) + { + auto const mptid = MPTID::fromVoid(slice->data()); + return Asset{mptid}; + } + + if (slice->size() == Currency::bytes) + { + auto const currency = Currency::fromVoid(slice->data()); + auto const issue = Issue{currency, xrpAccount()}; + if (!issue.native()) + return Unexpected(HostFunctionError::INVALID_PARAMS); + return Asset{issue}; + } + + if (slice->size() == (AccountID::bytes + Currency::bytes)) + { + auto const issue = Issue( + Currency::fromVoid(slice->data()), + AccountID::fromVoid(slice->data() + Currency::bytes)); + + if (issue.native()) + return Unexpected(HostFunctionError::INVALID_PARAMS); + return Asset{issue}; + } + + return Unexpected(HostFunctionError::INVALID_PARAMS); +} + +template +Expected +getDataString(IW const* runtime, wasm_val_vec_t const* params, int32_t& i) +{ + auto const slice = getDataSlice(runtime, params, i); + if (!slice) + return Unexpected(slice.error()); + return std::string_view( + reinterpret_cast(slice->data()), slice->size()); +} + +std::nullptr_t +hfResult(wasm_val_vec_t* results, int32_t value) +{ + results->data[0] = WASM_I32_VAL(value); + results->num_elems = 1; + return nullptr; +} + +std::nullptr_t +hfResult(wasm_val_vec_t* results, HostFunctionError value) +{ + results->data[0] = WASM_I32_VAL(HfErrorToInt(value)); + results->num_elems = 1; + return nullptr; +} + +template +std::nullptr_t +returnResult( + InstanceWrapper const* runtime, + wasm_val_vec_t const* params, + wasm_val_vec_t* results, + Expected const& res, + int32_t index) +{ + if (!res) + { + return hfResult(results, res.error()); + } + + using t = std::decay_t; + if constexpr (std::is_same_v) + { + return hfResult( + results, + setData( + runtime, + params->data[index].of.i32, + params->data[index + 1].of.i32, + res->data(), + res->size())); + } + else if constexpr (std::is_same_v) + { + return hfResult( + results, + setData( + runtime, + params->data[index].of.i32, + params->data[index + 1].of.i32, + res->data(), + res->size())); + } + else if constexpr (std::is_same_v) + { + return hfResult(results, res.value()); + } + else if constexpr (std::is_same_v) + { + auto const resultValue = res.value(); + return hfResult( + results, + setData( + runtime, + params->data[index].of.i32, + params->data[index + 1].of.i32, + reinterpret_cast(&resultValue), + static_cast(sizeof(resultValue)))); + } + else + { + static_assert( + [] { return false; }(), "Unhandled return type in returnResult"); + } +} + +wasm_trap_t* +getLedgerSqn_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + return returnResult(runtime, params, results, hf->getLedgerSqn(), index); +} + +wasm_trap_t* +getParentLedgerTime_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + return returnResult( + runtime, params, results, hf->getParentLedgerTime(), index); +} + +wasm_trap_t* +getParentLedgerHash_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + return returnResult( + runtime, params, results, hf->getParentLedgerHash(), index); +} + +wasm_trap_t* +getBaseFee_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + return returnResult(runtime, params, results, hf->getBaseFee(), index); +} + +wasm_trap_t* +isAmendmentEnabled_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const slice = getDataSlice(runtime, params, index); + if (!slice) + { + return hfResult(results, slice.error()); + } + + if (slice->size() == uint256::bytes) + { + if (auto ret = hf->isAmendmentEnabled(uint256::fromVoid(slice->data())); + *ret == 1) + { + return returnResult(runtime, params, results, ret, index); + } + } + + if (slice->size() > 64) + { + return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE); + } + + auto const str = std::string_view( + reinterpret_cast(slice->data()), slice->size()); + return returnResult( + runtime, params, results, hf->isAmendmentEnabled(str), index); +} + +wasm_trap_t* +cacheLedgerObj_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const id = getDataUInt256(runtime, params, index); + if (!id) + { + return hfResult(results, id.error()); + } + + auto const cache = getDataInt32(runtime, params, index); + if (!cache) + { + return hfResult(results, cache.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, params, results, hf->cacheLedgerObj(*id, *cache), index); +} + +wasm_trap_t* +getTxField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const fname = getDataSField(runtime, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + return returnResult( + runtime, params, results, hf->getTxField(*fname), index); +} + +wasm_trap_t* +getCurrentLedgerObjField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const fname = getDataSField(runtime, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + runtime, params, results, hf->getCurrentLedgerObjField(*fname), index); +} + +wasm_trap_t* +getLedgerObjField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const cache = getDataInt32(runtime, params, index); + if (!cache) + { + return hfResult(results, cache.error()); // LCOV_EXCL_LINE + } + + auto const fname = getDataSField(runtime, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + runtime, params, results, hf->getLedgerObjField(*cache, *fname), index); +} + +wasm_trap_t* +getTxNestedField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getDataSlice(runtime, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + runtime, params, results, hf->getTxNestedField(*bytes), index); +} + +wasm_trap_t* +getCurrentLedgerObjNestedField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getDataSlice(runtime, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + return returnResult( + runtime, + params, + results, + hf->getCurrentLedgerObjNestedField(*bytes), + index); +} + +wasm_trap_t* +getLedgerObjNestedField_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const cache = getDataInt32(runtime, params, index); + if (!cache) + { + return hfResult(results, cache.error()); // LCOV_EXCL_LINE + } + + auto const bytes = getDataSlice(runtime, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + runtime, + params, + results, + hf->getLedgerObjNestedField(*cache, *bytes), + index); +} + +wasm_trap_t* +getTxArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const fname = getDataSField(runtime, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + runtime, params, results, hf->getTxArrayLen(*fname), index); +} + +wasm_trap_t* +getCurrentLedgerObjArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const fname = getDataSField(runtime, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + runtime, + params, + results, + hf->getCurrentLedgerObjArrayLen(*fname), + index); +} + +wasm_trap_t* +getLedgerObjArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const cache = getDataInt32(runtime, params, index); + if (!cache) + { + return hfResult(results, cache.error()); // LCOV_EXCL_LINE + } + + auto const fname = getDataSField(runtime, params, index); + if (!fname) + { + return hfResult(results, fname.error()); + } + + return returnResult( + runtime, + params, + results, + hf->getLedgerObjArrayLen(*cache, *fname), + index); +} + +wasm_trap_t* +getTxNestedArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getDataSlice(runtime, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + runtime, params, results, hf->getTxNestedArrayLen(*bytes), index); +} + +wasm_trap_t* +getCurrentLedgerObjNestedArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getDataSlice(runtime, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + runtime, + params, + results, + hf->getCurrentLedgerObjNestedArrayLen(*bytes), + index); +} +wasm_trap_t* +getLedgerObjNestedArrayLen_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const cache = getDataInt32(runtime, params, index); + if (!cache) + { + return hfResult(results, cache.error()); // LCOV_EXCL_LINE + } + + auto const bytes = getDataSlice(runtime, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + return returnResult( + runtime, + params, + results, + hf->getLedgerObjNestedArrayLen(*cache, *bytes), + index); +} + +wasm_trap_t* +updateData_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getDataSlice(runtime, params, index, true); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + + return returnResult( + runtime, params, results, hf->updateData(*bytes), index); +} + +wasm_trap_t* +checkSignature_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const message = getDataSlice(runtime, params, index); + if (!message) + { + return hfResult(results, message.error()); + } + + auto const signature = getDataSlice(runtime, params, index); + if (!signature) + { + return hfResult(results, signature.error()); + } + + auto const pubkey = getDataSlice(runtime, params, index); + if (!pubkey) + { + return hfResult(results, pubkey.error()); + } + + return returnResult( + runtime, + params, + results, + hf->checkSignature(*message, *signature, *pubkey), + index); +} + +wasm_trap_t* +computeSha512HalfHash_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const bytes = getDataSlice(runtime, params, index); + if (!bytes) + { + return hfResult(results, bytes.error()); + } + return returnResult( + runtime, params, results, hf->computeSha512HalfHash(*bytes), index); +} + +wasm_trap_t* +accountKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + return returnResult( + runtime, params, results, hf->accountKeylet(*acc), index); +} + +wasm_trap_t* +ammKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const issue1 = getDataAsset(runtime, params, index); + if (!issue1) + { + return hfResult(results, issue1.error()); + } + + auto const issue2 = getDataAsset(runtime, params, index); + if (!issue2) + { + return hfResult(results, issue2.error()); + } + + return returnResult( + runtime, + params, + results, + hf->ammKeylet(issue1.value(), issue2.value()), + index); +} + +wasm_trap_t* +checkKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, params, results, hf->checkKeylet(acc.value(), *seq), index); +} + +wasm_trap_t* +credentialKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const subj = getDataAccountID(runtime, params, index); + if (!subj) + { + return hfResult(results, subj.error()); + } + + auto const iss = getDataAccountID(runtime, params, index); + if (!iss) + { + return hfResult(results, iss.error()); + } + + auto const credType = getDataSlice(runtime, params, index); + if (!credType) + { + return hfResult(results, credType.error()); + } + + return returnResult( + runtime, + params, + results, + hf->credentialKeylet(*subj, *iss, *credType), + index); +} + +wasm_trap_t* +delegateKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const authorize = getDataAccountID(runtime, params, index); + if (!authorize) + { + return hfResult(results, authorize.error()); + } + + return returnResult( + runtime, + params, + results, + hf->delegateKeylet(acc.value(), authorize.value()), + index); +} + +wasm_trap_t* +depositPreauthKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const authorize = getDataAccountID(runtime, params, index); + if (!authorize) + { + return hfResult(results, authorize.error()); + } + + return returnResult( + runtime, + params, + results, + hf->depositPreauthKeylet(acc.value(), authorize.value()), + index); +} + +wasm_trap_t* +didKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + return returnResult( + runtime, params, results, hf->didKeylet(acc.value()), index); +} + +wasm_trap_t* +escrowKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, params, results, hf->escrowKeylet(*acc, *seq), index); +} + +wasm_trap_t* +lineKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc1 = getDataAccountID(runtime, params, index); + if (!acc1) + { + return hfResult(results, acc1.error()); + } + + auto const acc2 = getDataAccountID(runtime, params, index); + if (!acc2) + { + return hfResult(results, acc2.error()); + } + + auto const currency = getDataCurrency(runtime, params, index); + if (!currency) + { + return hfResult(results, currency.error()); + } + + return returnResult( + runtime, + params, + results, + hf->lineKeylet(acc1.value(), acc2.value(), currency.value()), + index); +} + +wasm_trap_t* +mptIssuanceKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, + params, + results, + hf->mptIssuanceKeylet(acc.value(), seq.value()), + index); +} + +wasm_trap_t* +mptokenKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const slice = getDataSlice(runtime, params, index); + if (!slice) + { + return hfResult(results, slice.error()); + } + + if (slice->size() != MPTID::bytes) + { + return hfResult(results, HostFunctionError::INVALID_PARAMS); + } + auto const mptid = MPTID::fromVoid(slice->data()); + + auto const holder = getDataAccountID(runtime, params, index); + if (!holder) + { + return hfResult(results, holder.error()); + } + + return returnResult( + runtime, + params, + results, + hf->mptokenKeylet(mptid, holder.value()), + index); +} + +wasm_trap_t* +nftOfferKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, + params, + results, + hf->nftOfferKeylet(acc.value(), seq.value()), + index); +} + +wasm_trap_t* +offerKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, + params, + results, + hf->offerKeylet(acc.value(), seq.value()), + index); +} + +wasm_trap_t* +oracleKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const documentId = getDataInt32(runtime, params, index); + if (!documentId) + { + return hfResult(results, documentId.error()); // LCOV_EXCL_LINE + } + return returnResult( + runtime, params, results, hf->oracleKeylet(*acc, *documentId), index); +} + +wasm_trap_t* +paychanKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const dest = getDataAccountID(runtime, params, index); + if (!dest) + { + return hfResult(results, dest.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, + params, + results, + hf->paychanKeylet(acc.value(), dest.value(), seq.value()), + index); +} + +wasm_trap_t* +permissionedDomainKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, + params, + results, + hf->permissionedDomainKeylet(acc.value(), seq.value()), + index); +} + +wasm_trap_t* +signersKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + return returnResult( + runtime, params, results, hf->signersKeylet(acc.value()), index); +} + +wasm_trap_t* +ticketKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, + params, + results, + hf->ticketKeylet(acc.value(), seq.value()), + index); +} + +wasm_trap_t* +vaultKeylet_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const seq = getDataInt32(runtime, params, index); + if (!seq) + { + return hfResult(results, seq.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, + params, + results, + hf->vaultKeylet(acc.value(), seq.value()), + index); +} + +wasm_trap_t* +getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const acc = getDataAccountID(runtime, params, index); + if (!acc) + { + return hfResult(results, acc.error()); + } + + auto const nftId = getDataUInt256(runtime, params, index); + if (!nftId) + { + return hfResult(results, nftId.error()); + } + + return returnResult( + runtime, params, results, hf->getNFT(*acc, *nftId), index); +} + +wasm_trap_t* +getNFTIssuer_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const nftId = getDataUInt256(runtime, params, index); + if (!nftId) + { + return hfResult(results, nftId.error()); + } + + return returnResult( + runtime, params, results, hf->getNFTIssuer(*nftId), index); +} + +wasm_trap_t* +getNFTTaxon_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const nftId = getDataUInt256(runtime, params, index); + if (!nftId) + { + return hfResult(results, nftId.error()); + } + + return returnResult( + runtime, params, results, hf->getNFTTaxon(*nftId), index); +} + +wasm_trap_t* +getNFTFlags_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const nftId = getDataUInt256(runtime, params, index); + if (!nftId) + { + return hfResult(results, nftId.error()); + } + + return returnResult( + runtime, params, results, hf->getNFTFlags(*nftId), index); +} + +wasm_trap_t* +getNFTTransferFee_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const nftId = getDataUInt256(runtime, params, index); + if (!nftId) + { + return hfResult(results, nftId.error()); + } + + return returnResult( + runtime, params, results, hf->getNFTTransferFee(*nftId), index); +} + +wasm_trap_t* +getNFTSerial_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + auto const nftId = getDataUInt256(runtime, params, index); + if (!nftId) + { + return hfResult(results, nftId.error()); + } + + return returnResult( + runtime, params, results, hf->getNFTSerial(*nftId), index); +} + +wasm_trap_t* +trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + + if (params->data[1].of.i32 + params->data[3].of.i32 > maxWasmParamLength) + { + return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE); + } + + auto const msg = getDataString(runtime, params, index); + if (!msg) + { + return hfResult(results, msg.error()); + } + + auto const data = getDataSlice(runtime, params, index); + if (!data) + { + return hfResult(results, data.error()); + } + + auto const asHex = getDataInt32(runtime, params, index); + if (!asHex) + { + return hfResult(results, asHex.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, params, results, hf->trace(*msg, *data, *asHex), index); +} + +wasm_trap_t* +traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + int index = 0; + if (params->data[1].of.i32 > maxWasmParamLength) + { + return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE); + } + + auto const msg = getDataString(runtime, params, index); + if (!msg) + { + return hfResult(results, msg.error()); + } + + auto const number = getDataInt64(runtime, params, index); + if (!number) + { + return hfResult(results, number.error()); // LCOV_EXCL_LINE + } + + return returnResult( + runtime, params, results, hf->traceNum(*msg, *number), index); +} + +wasm_trap_t* +traceAccount_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + if (params->data[1].of.i32 > maxWasmParamLength) + return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE); + + int i = 0; + auto const msg = getDataString(runtime, params, i); + if (!msg) + return hfResult(results, msg.error()); + + auto const account = getDataAccountID(runtime, params, i); + if (!account) + return hfResult(results, account.error()); + + return returnResult( + runtime, params, results, hf->traceAccount(*msg, *account), i); +} + +wasm_trap_t* +traceFloat_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + if (params->data[1].of.i32 > maxWasmParamLength) + return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE); + + int i = 0; + auto const msg = getDataString(runtime, params, i); + if (!msg) + return hfResult(results, msg.error()); + + auto const number = getDataSlice(runtime, params, i); + if (!number) + return hfResult(results, number.error()); + + return returnResult( + runtime, params, results, hf->traceFloat(*msg, *number), i); +} + +wasm_trap_t* +traceAmount_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + if (params->data[1].of.i32 > maxWasmParamLength) + return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE); + + int i = 0; + auto const msg = getDataString(runtime, params, i); + if (!msg) + return hfResult(results, msg.error()); + + auto const amountSliceOpt = getDataSlice(runtime, params, i); + if (!amountSliceOpt) + return hfResult(results, amountSliceOpt.error()); + + auto const amountSlice = amountSliceOpt.value(); + auto serialIter = SerialIter(amountSlice); + + std::optional amount; + try + { + amount = STAmount(serialIter, sfGeneric); + } + catch (std::exception const&) + { + amount = std::nullopt; + } + if (!amount || !amount.value()) + return hfResult(results, HostFunctionError::INVALID_PARAMS); + + return returnResult( + runtime, params, results, hf->traceAmount(*msg, *amount), i); +} + +wasm_trap_t* +floatFromInt_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataInt64(runtime, params, i); + if (!x) + return hfResult(results, x.error()); // LCOV_EXCL_LINE + + i = 3; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 1; + return returnResult( + runtime, params, results, hf->floatFromInt(*x, *rounding), i); +} + +wasm_trap_t* +floatFromUint_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataUInt64(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + i = 4; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 2; + return returnResult( + runtime, params, results, hf->floatFromUint(*x, *rounding), i); +} + +wasm_trap_t* +floatSet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const exp = getDataInt32(runtime, params, i); + if (!exp) + return hfResult(results, exp.error()); // LCOV_EXCL_LINE + + auto const mant = getDataInt64(runtime, params, i); + if (!mant) + return hfResult(results, mant.error()); // LCOV_EXCL_LINE + + i = 4; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 2; + return returnResult( + runtime, params, results, hf->floatSet(*mant, *exp, *rounding), i); +} + +wasm_trap_t* +floatCompare_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataSlice(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + auto const y = getDataSlice(runtime, params, i); + if (!y) + return hfResult(results, y.error()); + + return returnResult(runtime, params, results, hf->floatCompare(*x, *y), i); +} + +wasm_trap_t* +floatAdd_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataSlice(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + auto const y = getDataSlice(runtime, params, i); + if (!y) + return hfResult(results, y.error()); + + i = 6; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 4; + return returnResult( + runtime, params, results, hf->floatAdd(*x, *y, *rounding), i); +} + +wasm_trap_t* +floatSubtract_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataSlice(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + auto const y = getDataSlice(runtime, params, i); + if (!y) + return hfResult(results, y.error()); + + i = 6; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 4; + return returnResult( + runtime, params, results, hf->floatSubtract(*x, *y, *rounding), i); +} + +wasm_trap_t* +floatMultiply_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataSlice(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + auto const y = getDataSlice(runtime, params, i); + if (!y) + return hfResult(results, y.error()); + + i = 6; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 4; + return returnResult( + runtime, params, results, hf->floatMultiply(*x, *y, *rounding), i); +} + +wasm_trap_t* +floatDivide_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataSlice(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + auto const y = getDataSlice(runtime, params, i); + if (!y) + return hfResult(results, y.error()); + + i = 6; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 4; + return returnResult( + runtime, params, results, hf->floatDivide(*x, *y, *rounding), i); +} + +wasm_trap_t* +floatRoot_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataSlice(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + auto const n = getDataInt32(runtime, params, i); + if (!n) + return hfResult(results, n.error()); // LCOV_EXCL_LINE + + i = 5; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 3; + return returnResult( + runtime, params, results, hf->floatRoot(*x, *n, *rounding), i); +} + +wasm_trap_t* +floatPower_wrap( + void* env, + wasm_val_vec_t const* params, + wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataSlice(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + auto const n = getDataInt32(runtime, params, i); + if (!n) + return hfResult(results, n.error()); // LCOV_EXCL_LINE + + i = 5; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 3; + return returnResult( + runtime, params, results, hf->floatPower(*x, *n, *rounding), i); +} + +wasm_trap_t* +floatLog_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) +{ + auto* hf = reinterpret_cast(env); + auto const* runtime = reinterpret_cast(hf->getRT()); + + int i = 0; + auto const x = getDataSlice(runtime, params, i); + if (!x) + return hfResult(results, x.error()); + + i = 4; + auto const rounding = getDataInt32(runtime, params, i); + if (!rounding) + return hfResult(results, rounding.error()); // LCOV_EXCL_LINE + + i = 2; + return returnResult( + runtime, params, results, hf->floatLog(*x, *rounding), i); +} + +// LCOV_EXCL_START +namespace test { + +class MockInstanceWrapper +{ + wmem mem_; + +public: + MockInstanceWrapper(wmem memory) : mem_(memory) + { + } + + // Mock methods to simulate the behavior of InstanceWrapper + wmem + getMem() const + { + return mem_; + } +}; + +bool +testGetDataIncrement() +{ + wasm_val_t values[4]; + + std::array buffer = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; + MockInstanceWrapper runtime(wmem{buffer.data(), buffer.size()}); + + { + // test int32_t + wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(42); + + int index = 0; + auto const result = getDataInt32(&runtime, ¶ms, index); + if (!result || result.value() != 42 || index != 1) + return false; + } + + { + // test int64_t + wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I64_VAL(1234); + + int index = 0; + auto const result = getDataInt64(&runtime, ¶ms, index); + if (!result || result.value() != 1234 || index != 1) + return false; + } + + { + // test SFieldCRef + wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(sfAccount.fieldCode); + + int index = 0; + auto const result = getDataSField(&runtime, ¶ms, index); + if (!result || result.value().get() != sfAccount || index != 1) + return false; + } + + { + // test Slice + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(3); + + int index = 0; + auto const result = getDataSlice(&runtime, ¶ms, index); + if (!result || result.value() != Slice(buffer.data(), 3) || index != 2) + return false; + } + + { + // test string + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(5); + + int index = 0; + auto const result = getDataString(&runtime, ¶ms, index); + if (!result || + result.value() != + std::string_view( + reinterpret_cast(buffer.data()), 5) || + index != 2) + return false; + } + + { + // test account + AccountID const id(calcAccountID( + generateKeyPair(KeyType::secp256k1, generateSeed("alice")).first)); + + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(id.bytes); + memcpy(&buffer[0], id.data(), id.bytes); + + int index = 0; + auto const result = getDataAccountID(&runtime, ¶ms, index); + if (!result || result.value() != id || index != 2) + return false; + } + + { + // test uint256 + + Hash h1 = sha512Half(Slice(buffer.data(), 8)); + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(h1.bytes); + memcpy(&buffer[0], h1.data(), h1.bytes); + + int index = 0; + auto const result = getDataUInt256(&runtime, ¶ms, index); + if (!result || result.value() != h1 || index != 2) + return false; + } + + { + // test Currency + + Currency const c = xrpCurrency(); + wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + + values[0] = WASM_I32_VAL(0); + values[1] = WASM_I32_VAL(c.bytes); + memcpy(&buffer[0], c.data(), c.bytes); + + int index = 0; + auto const result = getDataCurrency(&runtime, ¶ms, index); + if (!result || result.value() != c || index != 2) + return false; + } + + return true; +} + +} // namespace test +// LCOV_EXCL_STOP + +} // namespace ripple diff --git a/src/xrpld/app/wasm/detail/WamrVM.cpp b/src/xrpld/app/wasm/detail/WamrVM.cpp new file mode 100644 index 00000000000..4d94e1cb8fe --- /dev/null +++ b/src/xrpld/app/wasm/detail/WamrVM.cpp @@ -0,0 +1,1052 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2020 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#include + +#include + +#include +#include + +#ifdef _DEBUG +// #define DEBUG_OUTPUT 1 +// #define DEBUG_OUTPUT_WAMR 1 +#endif + +// #define SHOW_CALL_TIME 1 + +namespace ripple { + +namespace { + +// LCOV_EXCL_START +static log_level_t +getLogLevel(beast::severities::Severity severity) +{ + using namespace beast::severities; + switch (severity) + { + case kTrace: + return WASM_LOG_LEVEL_VERBOSE; + case kDebug: + return WASM_LOG_LEVEL_DEBUG; + case kInfo: + case kWarning: + return WASM_LOG_LEVEL_WARNING; + case kError: + return WASM_LOG_LEVEL_ERROR; + default: + UNREACHABLE("WAMR invalid severity"); + [[fallthrough]]; + case kFatal: + case kNone: + break; + } + + return WASM_LOG_LEVEL_FATAL; +} + +static beast::severities::Severity +getLogLevel(uint32_t severity) +{ + using namespace beast::severities; + switch (severity) + { + case WASM_LOG_LEVEL_VERBOSE: + return kTrace; + case WASM_LOG_LEVEL_DEBUG: + return kDebug; + case WASM_LOG_LEVEL_WARNING: + return kWarning; + case WASM_LOG_LEVEL_ERROR: + return kError; + default: + UNREACHABLE("WAMR invalid reverse severity"); + [[fallthrough]]; + case WASM_LOG_LEVEL_FATAL: + break; + } + + return kFatal; +} + +// This function is called from WAMR to log messages. +extern "C" void +wamr_log_to_rippled( + uint32_t logLevel, + char const* file, + int line, + char const* fmt, + ...) +{ + beast::Journal j = WasmEngine::instance().getJournal(); + + std::ostringstream oss; + + // Format the variadic args + if (file) + { + oss << "WAMR (" << file << ":" << line << "): "; + } + else + { + oss << "WAMR: "; + } + + va_list args; + va_start(args, fmt); + + char formatted[4096]; + vsnprintf(formatted, sizeof(formatted), fmt, args); + formatted[sizeof(formatted) - 1] = '\0'; + + va_end(args); + + oss << formatted; + + j.stream(getLogLevel(logLevel)) << oss.str(); +#ifdef DEBUG_OUTPUT_WAMR + std::cerr << oss.str() << std::endl; +#endif +} + +void +print_wasm_error(std::string_view msg, wasm_trap_t* trap, beast::Journal jlog) +{ +#ifdef DEBUG_OUTPUT + auto& j = std::cerr; +#else + auto j = jlog.warn(); +#endif + + wasm_byte_vec_t error_message WASM_EMPTY_VEC; + + if (trap) + wasm_trap_message(trap, &error_message); + + if (error_message.num_elems) + { + error_message.data[error_message.num_elems - 1] = 0; // just in case + j << "WAMR Error: " << msg << ", " << error_message.data; + } + else + j << "WAMR Error: " << msg; + + if (error_message.size) + wasm_byte_vec_delete(&error_message); + wasm_trap_delete(trap); + +#ifdef DEBUG_OUTPUT + j << std::endl; +#endif +} +// LCOV_EXCL_STOP + +} // namespace + +InstancePtr +InstanceWrapper::init( + wasm_store_t* s, + wasm_module_t* m, + int32_t maxPages, + wasm_extern_vec_t* expt, + wasm_extern_vec_t const& imports, + beast::Journal j) +{ + wasm_trap_t* trap = nullptr; + InstantiationArgs inst_args{ + 128 * 1024, + 256 * 1024, + static_cast(maxPages > 0 ? maxPages : 0)}; + + InstancePtr mi = InstancePtr( + wasm_instance_new_with_args_ex(s, m, &imports, &trap, &inst_args), + &wasm_instance_delete); + + if (!mi || trap) + { + print_wasm_error("can't create instance", trap, j); + throw std::runtime_error("can't create instance"); + } + wasm_instance_exports(mi.get(), expt); + return mi; +} + +InstanceWrapper::InstanceWrapper() + : exports_{0, nullptr, 0, 0, nullptr} + , instance_(nullptr, &wasm_instance_delete) +{ +} + +InstanceWrapper::InstanceWrapper(InstanceWrapper&& o) + : exports_{0, nullptr, 0, 0, nullptr} + , instance_(nullptr, &wasm_instance_delete) +{ + *this = std::move(o); +} + +InstanceWrapper::InstanceWrapper( + wasm_store_t* s, + wasm_module_t* m, + int32_t maxPages, + int64_t gas, + wasm_extern_vec_t const& imports, + beast::Journal j) + : exports_ WASM_EMPTY_VEC + , instance_(init(s, m, maxPages, &exports_, imports, j)) + , execEnv_(wasm_instance_exec_env(instance_.get())) + , j_(j) +{ + wasm_runtime_set_instruction_count_limit(execEnv_, gas); +} + +InstanceWrapper::~InstanceWrapper() +{ + if (exports_.size) + wasm_extern_vec_delete(&exports_); +} + +InstanceWrapper& +InstanceWrapper::operator=(InstanceWrapper&& o) +{ + if (this == &o) + return *this; + + if (exports_.size) + wasm_extern_vec_delete(&exports_); + exports_ = o.exports_; + o.exports_ = {0, nullptr, 0, 0, nullptr}; + + instance_ = std::move(o.instance_); + execEnv_ = o.execEnv_; + o.execEnv_ = nullptr; + + j_ = o.j_; + + return *this; +} + +InstanceWrapper::operator bool() const +{ + return static_cast(instance_); +} + +FuncInfo +InstanceWrapper::getFunc( + std::string_view funcName, + wasm_exporttype_vec_t const& export_types) const +{ + wasm_func_t* f = nullptr; + wasm_functype_t* ft = nullptr; + + if (!instance_) + throw std::runtime_error("no instance"); + + if (!export_types.num_elems) + throw std::runtime_error("no export"); + if (export_types.num_elems != exports_.num_elems) + throw std::runtime_error("invalid export"); + + for (unsigned i = 0; i < export_types.num_elems; ++i) + { + auto const* exp_type(export_types.data[i]); + + wasm_name_t const* name = wasm_exporttype_name(exp_type); + wasm_externtype_t const* exn_type = wasm_exporttype_type(exp_type); + if (wasm_externtype_kind(exn_type) == WASM_EXTERN_FUNC) + { + if (funcName == std::string_view(name->data, name->size - 1)) + { + auto* exn(exports_.data[i]); + if (wasm_extern_kind(exn) != WASM_EXTERN_FUNC) + throw std::runtime_error("invalid export"); + + ft = wasm_externtype_as_functype( + const_cast(exn_type)); + f = wasm_extern_as_func(exn); + break; + } + } + } + + if (!f || !ft) + throw std::runtime_error( + "can't find function <" + std::string(funcName) + ">"); + + return {f, ft}; +} + +wmem +InstanceWrapper::getMem() const +{ + if (!instance_) + throw std::runtime_error("no instance"); + + wasm_memory_t* mem = nullptr; + for (unsigned i = 0; i < exports_.num_elems; ++i) + { + auto* e(exports_.data[i]); + if (wasm_extern_kind(e) == WASM_EXTERN_MEMORY) + { + mem = wasm_extern_as_memory(e); + break; + } + } + + if (!mem) + throw std::runtime_error("no memory exported"); + + return { + reinterpret_cast(wasm_memory_data(mem)), + wasm_memory_data_size(mem)}; +} + +std::int64_t +InstanceWrapper::getGas() const +{ + return execEnv_ ? wasm_runtime_get_instruction_count_limit(execEnv_) : 0; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ModulePtr +ModuleWrapper::init(wasm_store_t* s, Bytes const& wasmBin, beast::Journal j) +{ + wasm_byte_vec_t const code{ + wasmBin.size(), + (char*)(wasmBin.data()), + wasmBin.size(), + sizeof(std::remove_reference_t::value_type), + nullptr}; + ModulePtr m = ModulePtr(wasm_module_new(s, &code), &wasm_module_delete); + if (!m) + throw std::runtime_error("can't create module"); + + return m; +} + +ModuleWrapper::ModuleWrapper() + : module_(nullptr, &wasm_module_delete) + , exportTypes_{0, nullptr, 0, 0, nullptr} +{ +} + +ModuleWrapper::ModuleWrapper(ModuleWrapper&& o) + : module_(nullptr, &wasm_module_delete) + , exportTypes_{0, nullptr, 0, 0, nullptr} +{ + *this = std::move(o); +} + +ModuleWrapper::ModuleWrapper( + wasm_store_t* s, + Bytes const& wasmBin, + bool instantiate, + int32_t maxPages, + int64_t gas, + std::vector const& imports, + beast::Journal j) + : module_(init(s, wasmBin, j)) + , exportTypes_{0, nullptr, 0, 0, nullptr} + , j_(j) +{ + wasm_module_exports(module_.get(), &exportTypes_); + if (instantiate) + { + auto wimports = buildImports(s, imports); + addInstance(s, maxPages, gas, wimports); + } +} + +ModuleWrapper::~ModuleWrapper() +{ + if (exportTypes_.size) + wasm_exporttype_vec_delete(&exportTypes_); +} + +ModuleWrapper& +ModuleWrapper::operator=(ModuleWrapper&& o) +{ + if (this == &o) + return *this; + + module_ = std::move(o.module_); + instanceWrap_ = std::move(o.instanceWrap_); + if (exportTypes_.size) + wasm_exporttype_vec_delete(&exportTypes_); + exportTypes_ = o.exportTypes_; + o.exportTypes_ = {0, nullptr, 0, 0, nullptr}; + j_ = o.j_; + + return *this; +} + +ModuleWrapper::operator bool() const +{ + return instanceWrap_; +} + +void +ModuleWrapper::makeImpParams(wasm_valtype_vec_t& v, WasmImportFunc const& imp) +{ + auto const paramSize = imp.params.size(); + + if (paramSize) + { + wasm_valtype_vec_new(&v, paramSize, nullptr); + v.num_elems = paramSize; + } + else + v = WASM_EMPTY_VEC; + for (unsigned i = 0; i < paramSize; ++i) + { + auto const vt = imp.params[i]; + switch (vt) + { + case WT_I32: + v.data[i] = wasm_valtype_new_i32(); + break; + case WT_I64: + v.data[i] = wasm_valtype_new_i64(); + break; + default: + throw std::runtime_error("invalid import type"); + } + } +} + +void +ModuleWrapper::makeImpReturn(wasm_valtype_vec_t& v, WasmImportFunc const& imp) +{ + if (imp.result) + { + wasm_valtype_vec_new(&v, 1, nullptr); + v.num_elems = 1; + switch (*imp.result) + { + case WT_I32: + v.data[0] = wasm_valtype_new_i32(); + break; + case WT_I64: + v.data[0] = wasm_valtype_new_i64(); + break; + default: + throw std::runtime_error("invalid return type"); + } + } + else + v = WASM_EMPTY_VEC; +} + +wasm_extern_vec_t +ModuleWrapper::buildImports( + wasm_store_t* s, + std::vector const& imports) +{ + wasm_importtype_vec_t importTypes = WASM_EMPTY_VEC; + wasm_module_imports(module_.get(), &importTypes); + std:: + unique_ptr + itDeleter(&importTypes, &wasm_importtype_vec_delete); + + wasm_extern_vec_t wimports = WASM_EMPTY_VEC; + if (!importTypes.num_elems) + return wimports; + + wasm_extern_vec_new(&wimports, importTypes.size, nullptr); + wimports.num_elems = importTypes.num_elems; + + unsigned impCnt = 0; + for (unsigned i = 0; i < importTypes.num_elems; ++i) + { + wasm_importtype_t const* importtype = importTypes.data[i]; + if (wasm_importtype_is_linked(importtype)) + { + // create a placeholder + wimports.data[i] = wasm_extern_new_empty( + s, wasm_externtype_kind(wasm_importtype_type(importtype))); + ++impCnt; + continue; + } + + // wasm_name_t const* mn = wasm_importtype_module(importtype); + // auto modName = std::string_view(mn->data, mn->num_elems - 1); + wasm_name_t const* fn = wasm_importtype_name(importtype); + auto fieldName = std::string_view(fn->data, fn->num_elems - 1); + + // for multi-module support + // if ((W_ENV != modName) && (W_HOST_LIB != modName)) + // continue; + + bool impSet = false; + for (auto const& imp : imports) + { + if (imp.name != fieldName) + continue; + + wasm_valtype_vec_t params, results; + makeImpReturn(results, imp); + makeImpParams(params, imp); + + using ftype_ptr = std:: + unique_ptr; + ftype_ptr ftype( + wasm_functype_new(¶ms, &results), &wasm_functype_delete); + wasm_func_t* func = wasm_func_new_with_env( + s, + ftype.get(), + reinterpret_cast(imp.wrap), + imp.udata, + nullptr); + if (!func) + { + // LCOV_EXCL_START + throw std::runtime_error( + "can't create import function " + imp.name); + // LCOV_EXCL_STOP + } + + if (imp.gas && !wasm_func_set_gas(func, imp.gas)) + { + // LCOV_EXCL_START + throw std::runtime_error( + "can't set gas for import function " + imp.name); + // LCOV_EXCL_STOP + } + + wimports.data[i] = wasm_func_as_extern(func); + ++impCnt; + impSet = true; + + break; + } + + if (!impSet) + { + print_wasm_error( + std::string("Import not found: ") + fieldName.data(), + nullptr, + j_); + } + } + + if (impCnt != importTypes.num_elems) + { + print_wasm_error( + std::string("Imports not finished: ") + std::to_string(impCnt) + + "/" + std::to_string(importTypes.num_elems), + nullptr, + j_); + } + + return wimports; +} + +FuncInfo +ModuleWrapper::getFunc(std::string_view funcName) const +{ + return instanceWrap_.getFunc(funcName, exportTypes_); +} + +wmem +ModuleWrapper::getMem() const +{ + return instanceWrap_.getMem(); +} + +InstanceWrapper const& +ModuleWrapper::getInstance(int) const +{ + return instanceWrap_; +} + +int +ModuleWrapper::addInstance( + wasm_store_t* s, + int32_t maxPages, + int64_t gas, + wasm_extern_vec_t const& imports) +{ + instanceWrap_ = {s, module_.get(), maxPages, gas, imports, j_}; + return 0; +} + +// int +// my_module_t::delInstance(int i) +// { +// if (i >= mod_inst.size()) +// return -1; +// if (!mod_inst[i]) +// mod_inst[i] = my_mod_inst_t(); +// return i; +// } + +std::int64_t +ModuleWrapper::getGas() +{ + return instanceWrap_.getGas(); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// void +// WamrEngine::clearModules() +// { +// modules.clear(); +// store.reset(); // to free the memory before creating new store +// store = {wasm_store_new(engine.get()), &wasm_store_delete}; +// } + +WamrEngine::WamrEngine() + : engine_(wasm_engine_new(), &wasm_engine_delete) + , store_(nullptr, &wasm_store_delete) +{ + wasm_runtime_set_default_running_mode(Mode_Interp); + wasm_runtime_set_log_level(WASM_LOG_LEVEL_FATAL); + // wasm_runtime_set_log_level(WASM_LOG_LEVEL_VERBOSE); +} + +int +WamrEngine::addModule( + Bytes const& wasmCode, + bool instantiate, + int64_t gas, + std::vector const& imports) +{ + moduleWrap_.reset(); + store_.reset(); // to free the memory before creating new store + store_ = {wasm_store_new(engine_.get()), &wasm_store_delete}; + moduleWrap_ = std::make_unique( + store_.get(), wasmCode, instantiate, defMaxPages_, gas, imports, j_); + + if (!moduleWrap_) + throw std::runtime_error("can't create module wrapper"); + + return moduleWrap_ ? 0 : -1; +} + +// int +// WamrEngine::addInstance() +// { +// return module->addInstance(store.get(), defMaxPages); +// } + +FuncInfo +WamrEngine::getFunc(std::string_view funcName) +{ + return moduleWrap_->getFunc(funcName); +} + +std::vector +WamrEngine::convertParams(std::vector const& params) +{ + std::vector v; + v.reserve(params.size()); + for (auto const& p : params) + { + switch (p.type) + { + case WT_I32: + v.push_back(WASM_I32_VAL(p.of.i32)); + break; + case WT_I64: + v.push_back(WASM_I64_VAL(p.of.i64)); + break; + case WT_U8V: { + auto const sz = p.of.u8v.sz; + auto const ptr = allocate(sz); + auto mem = getMem(); + memcpy(mem.p + ptr, p.of.u8v.d, sz); + + v.push_back(WASM_I32_VAL(ptr)); + v.push_back(WASM_I32_VAL(sz)); + } + break; + default: + throw std::runtime_error( + "unknown parameter type: " + std::to_string(p.type)); + break; + } + } + + return v; +} + +int +WamrEngine::compareParamTypes( + wasm_valtype_vec_t const* ftp, + std::vector const& p) +{ + if (ftp->num_elems != p.size()) + return std::min(ftp->num_elems, p.size()); + + for (unsigned i = 0; i < ftp->num_elems; ++i) + { + auto const t1 = wasm_valtype_kind(ftp->data[i]); + auto const t2 = p[i].kind; + if (t1 != t2) + return i; + } + + return -1; +} + +void +WamrEngine::add_param(std::vector& in, int32_t p) +{ + in.emplace_back(); + auto& el(in.back()); + memset(&el, 0, sizeof(el)); + el = WASM_I32_VAL(p); // WASM_I32; +} + +void +WamrEngine::add_param(std::vector& in, int64_t p) +{ + in.emplace_back(); + auto& el(in.back()); + el = WASM_I64_VAL(p); +} + +template +WamrResult +WamrEngine::call(std::string_view func, Types&&... args) +{ + // Lookup our export function + auto f = getFunc(func); + return call(f, std::forward(args)...); +} + +template +WamrResult +WamrEngine::call(FuncInfo const& f, Types&&... args) +{ + std::vector in; + return call(f, in, std::forward(args)...); +} + +#ifdef SHOW_CALL_TIME +static inline uint64_t +usecs() +{ + uint64_t x = + std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count(); + return x; +} +#endif + +template +WamrResult +WamrEngine::call(FuncInfo const& f, std::vector& in) +{ + // wasm_val_t rs[1] = {WASM_I32_VAL(0)}; + WamrResult ret(NR); + // if (NR) { wasm_val_vec_new_uninitialized(&ret, NR); // + // wasm_val_vec_new(&ret, NR, &rs[0]); // ret = WASM_ARRAY_VEC(rs); } + + wasm_val_vec_t const inv = in.empty() + ? wasm_val_vec_t WASM_EMPTY_VEC + : wasm_val_vec_t{ + in.size(), + in.data(), + in.size(), + sizeof(std::remove_reference_t::value_type), + nullptr}; + +#ifdef SHOW_CALL_TIME + auto const start = usecs(); +#endif + + wasm_trap_t* trap = wasm_func_call(f.first, &inv, &ret.r); + +#ifdef SHOW_CALL_TIME + auto const finish = usecs(); + auto const delta_ms = (finish - start) / 1000; + std::cout << "wasm_func_call: " << delta_ms << "ms" << std::endl; +#endif + + if (trap) + { + ret.f = true; + print_wasm_error("failure to call func", trap, j_); + } + + // assert(results[0].kind == WASM_I32); + // if (NR) printf("Result P5: %d\n", ret[0].of.i32); + + return ret; +} + +template +WamrResult +WamrEngine::call( + FuncInfo const& f, + std::vector& in, + std::int32_t p, + Types&&... args) +{ + add_param(in, p); + return call(f, in, std::forward(args)...); +} + +template +WamrResult +WamrEngine::call( + FuncInfo const& f, + std::vector& in, + std::int64_t p, + Types&&... args) +{ + add_param(in, p); + return call(f, in, std::forward(args)...); +} + +template +WamrResult +WamrEngine::call( + FuncInfo const& f, + std::vector& in, + uint8_t const* d, + std::size_t sz, + Types&&... args) +{ + auto const ptr = allocate(sz); + auto mem = getMem(); + memcpy(mem.p + ptr, d, sz); + + add_param(in, ptr); + add_param(in, static_cast(sz)); + return call(f, in, std::forward(args)...); +} + +template +WamrResult +WamrEngine::call( + FuncInfo const& f, + std::vector& in, + Bytes const& p, + Types&&... args) +{ + return call(f, in, p.data(), p.size(), std::forward(args)...); +} + +Expected, TER> +WamrEngine::run( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports, + HostFunctions* hfs, + int64_t gas, + beast::Journal j) +{ + j_ = j; + wasm_runtime_set_log_level( + std::min(getLogLevel(j_.sink().threshold()), WASM_LOG_LEVEL_ERROR)); + try + { + return runHlp(wasmCode, funcName, params, imports, hfs, gas); + } + catch (std::exception const& e) + { + print_wasm_error(std::string("exception: ") + e.what(), nullptr, j_); + } + catch (...) + { + print_wasm_error(std::string("exception: unknown"), nullptr, j_); + } + return Unexpected(tecFAILED_PROCESSING); +} + +Expected, TER> +WamrEngine::runHlp( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports, + HostFunctions* hfs, + int64_t gas) +{ + // currently only 1 module support, possible parallel UT run + std::lock_guard lg(m_); + + // Create and instantiate the module. + if (!wasmCode.empty()) + { + [[maybe_unused]] int const m = addModule(wasmCode, true, gas, imports); + } + + if (!moduleWrap_ || !moduleWrap_->instanceWrap_) + throw std::runtime_error("no instance"); + + if (hfs) + hfs->setRT(&getRT()); + + // Call main + auto const f = getFunc(!funcName.empty() ? funcName : "_start"); + auto const* ftp = wasm_functype_params(f.second); + + // not const because passed directly to wamr function (which accept non + // const) + auto p = convertParams(params); + + if (int const comp = compareParamTypes(ftp, p); comp >= 0) + throw std::runtime_error( + "invalid parameter type #" + std::to_string(comp)); + + auto const res = call<1>(f, p); + + if (res.f) + throw std::runtime_error("<" + std::string(funcName) + "> failure"); + else if (!res.r.num_elems) + throw std::runtime_error( + "<" + std::string(funcName) + "> return nothing"); + + assert(res.r.data[0].kind == WASM_I32); + if (gas == -1) + gas = std::numeric_limits::max(); + WasmResult const ret{ + res.r.data[0].of.i32, gas - moduleWrap_->getGas()}; + + // #ifdef DEBUG_OUTPUT + // auto& j = std::cerr; + // #else + // auto j = j_.debug(); + // #endif + // j << "WAMR Res: " << ret.result << " cost: " << ret.cost << std::endl; + + return ret; +} + +NotTEC +WamrEngine::check( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports, + beast::Journal j) +{ + j_ = j; + wasm_runtime_set_log_level( + std::min(getLogLevel(j_.sink().threshold()), WASM_LOG_LEVEL_ERROR)); + try + { + return checkHlp(wasmCode, funcName, params, imports); + } + catch (std::exception const& e) + { + print_wasm_error(std::string("exception: ") + e.what(), nullptr, j_); + } + catch (...) + { + print_wasm_error(std::string("exception: unknown"), nullptr, j_); + } + + return temBAD_WASM; +} + +NotTEC +WamrEngine::checkHlp( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports) +{ + // currently only 1 module support, possible parallel UT run + std::lock_guard lg(m_); + + // Create and instantiate the module. + if (wasmCode.empty()) + throw std::runtime_error("empty nodule"); + + int const m = addModule(wasmCode, true, -1, imports); + if ((m < 0) || !moduleWrap_ || !moduleWrap_->instanceWrap_) + throw std::runtime_error("no instance"); + + // Looking for a func and compare parameter types + auto const f = getFunc(!funcName.empty() ? funcName : "_start"); + auto const* ftp = wasm_functype_params(f.second); + auto const p = convertParams(params); + + if (int const comp = compareParamTypes(ftp, p); comp >= 0) + throw std::runtime_error( + "invalid parameter type #" + std::to_string(comp)); + + return tesSUCCESS; +} + +std::int32_t +WamrEngine::initMaxPages(std::int32_t def) +{ + defMaxPages_ = def; + return def; +} + +std::int64_t +WamrEngine::getGas() +{ + return moduleWrap_ ? moduleWrap_->getGas() : 0; +} + +wmem +WamrEngine::getMem() const +{ + return moduleWrap_ ? moduleWrap_->getMem() : wmem(); +} + +InstanceWrapper const& +WamrEngine::getRT(int m, int i) +{ + if (!moduleWrap_) + throw std::runtime_error("no module"); + return moduleWrap_->getInstance(i); +} + +int32_t +WamrEngine::allocate(int32_t sz) +{ + auto res = call<1>(W_ALLOC, static_cast(sz)); + + if (res.f || !res.r.num_elems || (res.r.data[0].kind != WASM_I32) || + !res.r.data[0].of.i32) + throw std::runtime_error( + "can't allocate memory, " + std::to_string(sz) + " bytes"); + return res.r.data[0].of.i32; +} + +wasm_trap_t* +WamrEngine::newTrap(std::string_view txt) +{ + wasm_message_t msg = WASM_EMPTY_VEC; + + if (!txt.empty()) + wasm_name_new(&msg, txt.size(), txt.data()); + + return wasm_trap_new(store_.get(), &msg); +} + +beast::Journal +WamrEngine::getJournal() const +{ + return j_; +} + +} // namespace ripple diff --git a/src/xrpld/app/wasm/detail/WasmVM.cpp b/src/xrpld/app/wasm/detail/WasmVM.cpp new file mode 100644 index 00000000000..f2d3799ca86 --- /dev/null +++ b/src/xrpld/app/wasm/detail/WasmVM.cpp @@ -0,0 +1,242 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2025 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#ifdef _DEBUG +// #define DEBUG_OUTPUT 1 +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace ripple { + +static void +setCommonHostFunctions(HostFunctions* hfs, std::vector& i) +{ + // clang-format off + WASM_IMPORT_FUNC2(i, getLedgerSqn, "get_ledger_sqn", hfs, 60); + WASM_IMPORT_FUNC2(i, getParentLedgerTime, "get_parent_ledger_time", hfs, 60); + WASM_IMPORT_FUNC2(i, getParentLedgerHash, "get_parent_ledger_hash", hfs, 60); + WASM_IMPORT_FUNC2(i, getBaseFee, "get_base_fee", hfs, 60); + WASM_IMPORT_FUNC2(i, isAmendmentEnabled, "amendment_enabled", hfs, 100); + + WASM_IMPORT_FUNC2(i, cacheLedgerObj, "cache_ledger_obj", hfs, 5'000); + WASM_IMPORT_FUNC2(i, getTxField, "get_tx_field", hfs, 70); + WASM_IMPORT_FUNC2(i, getCurrentLedgerObjField, "get_current_ledger_obj_field", hfs, 70); + WASM_IMPORT_FUNC2(i, getLedgerObjField, "get_ledger_obj_field", hfs, 70); + WASM_IMPORT_FUNC2(i, getTxNestedField, "get_tx_nested_field", hfs, 110); + WASM_IMPORT_FUNC2(i, getCurrentLedgerObjNestedField, "get_current_ledger_obj_nested_field", hfs, 110); + WASM_IMPORT_FUNC2(i, getLedgerObjNestedField, "get_ledger_obj_nested_field", hfs, 110); + WASM_IMPORT_FUNC2(i, getTxArrayLen, "get_tx_array_len", hfs, 40); + WASM_IMPORT_FUNC2(i, getCurrentLedgerObjArrayLen, "get_current_ledger_obj_array_len", hfs, 40); + WASM_IMPORT_FUNC2(i, getLedgerObjArrayLen, "get_ledger_obj_array_len", hfs, 40); + WASM_IMPORT_FUNC2(i, getTxNestedArrayLen, "get_tx_nested_array_len", hfs, 70); + WASM_IMPORT_FUNC2(i, getCurrentLedgerObjNestedArrayLen, "get_current_ledger_obj_nested_array_len", hfs, 70); + WASM_IMPORT_FUNC2(i, getLedgerObjNestedArrayLen, "get_ledger_obj_nested_array_len", hfs, 70); + + WASM_IMPORT_FUNC2(i, checkSignature, "check_sig", hfs, 300); + WASM_IMPORT_FUNC2(i, computeSha512HalfHash, "compute_sha512_half", hfs, 2000); + + WASM_IMPORT_FUNC2(i, accountKeylet, "account_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, ammKeylet, "amm_keylet", hfs, 450); + WASM_IMPORT_FUNC2(i, checkKeylet, "check_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, credentialKeylet, "credential_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, delegateKeylet, "delegate_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, depositPreauthKeylet, "deposit_preauth_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, didKeylet, "did_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, escrowKeylet, "escrow_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, lineKeylet, "line_keylet", hfs, 400); + WASM_IMPORT_FUNC2(i, mptIssuanceKeylet, "mpt_issuance_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, mptokenKeylet, "mptoken_keylet", hfs, 500); + WASM_IMPORT_FUNC2(i, nftOfferKeylet, "nft_offer_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, offerKeylet, "offer_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, oracleKeylet, "oracle_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, paychanKeylet, "paychan_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, permissionedDomainKeylet, "permissioned_domain_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, signersKeylet, "signers_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, ticketKeylet, "ticket_keylet", hfs, 350); + WASM_IMPORT_FUNC2(i, vaultKeylet, "vault_keylet", hfs, 350); + + WASM_IMPORT_FUNC2(i, getNFT, "get_nft", hfs, 1000); + WASM_IMPORT_FUNC2(i, getNFTIssuer, "get_nft_issuer", hfs, 70); + WASM_IMPORT_FUNC2(i, getNFTTaxon, "get_nft_taxon", hfs, 60); + WASM_IMPORT_FUNC2(i, getNFTFlags, "get_nft_flags", hfs, 60); + WASM_IMPORT_FUNC2(i, getNFTTransferFee, "get_nft_transfer_fee", hfs, 60); + WASM_IMPORT_FUNC2(i, getNFTSerial, "get_nft_serial", hfs, 60); + + WASM_IMPORT_FUNC (i, trace, hfs, 500); + WASM_IMPORT_FUNC2(i, traceNum, "trace_num", hfs, 500); + WASM_IMPORT_FUNC2(i, traceAccount, "trace_account", hfs, 500); + WASM_IMPORT_FUNC2(i, traceFloat, "trace_opaque_float", hfs, 500); + WASM_IMPORT_FUNC2(i, traceAmount, "trace_amount", hfs, 500); + + WASM_IMPORT_FUNC2(i, floatFromInt, "float_from_int", hfs, 100); + WASM_IMPORT_FUNC2(i, floatFromUint, "float_from_uint", hfs, 130); + WASM_IMPORT_FUNC2(i, floatSet, "float_set", hfs, 100); + WASM_IMPORT_FUNC2(i, floatCompare, "float_compare", hfs, 80); + WASM_IMPORT_FUNC2(i, floatAdd, "float_add", hfs, 160); + WASM_IMPORT_FUNC2(i, floatSubtract, "float_subtract", hfs, 160); + WASM_IMPORT_FUNC2(i, floatMultiply, "float_multiply", hfs, 300); + WASM_IMPORT_FUNC2(i, floatDivide, "float_divide", hfs, 300); + WASM_IMPORT_FUNC2(i, floatRoot, "float_root", hfs, 5'500); + WASM_IMPORT_FUNC2(i, floatPower, "float_pow", hfs, 5'500); + WASM_IMPORT_FUNC2(i, floatLog, "float_log", hfs, 12'000); + // clang-format on +} + +std::vector +createWasmImport(HostFunctions* hfs) +{ + std::vector i; + + if (hfs) + { + setCommonHostFunctions(hfs, i); + WASM_IMPORT_FUNC2(i, updateData, "update_data", hfs, 1000); + } + + return i; +} + +Expected +runEscrowWasm( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + HostFunctions* hfs, + int64_t gasLimit, + beast::Journal j) +{ + // create VM and set cost limit + auto& vm = WasmEngine::instance(); + vm.initMaxPages(MAX_PAGES); + + auto const ret = vm.run( + wasmCode, + funcName, + params, + createWasmImport(hfs), + hfs, + gasLimit, + hfs ? hfs->getJournal() : j); + + // std::cout << "runEscrowWasm, mod size: " << wasmCode.size() + // << ", gasLimit: " << gasLimit << ", funcName: " << funcName; + + if (!ret) + { +#ifdef DEBUG_OUTPUT + std::cout << ", error: " << ret.error() << std::endl; +#endif + return Unexpected(ret.error()); + } + +#ifdef DEBUG_OUTPUT + std::cout << ", ret: " << ret->result << ", gas spent: " << ret->cost + << std::endl; +#endif + return EscrowResult{ret->result, ret->cost}; +} + +NotTEC +preflightEscrowWasm( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + HostFunctions* hfs, + beast::Journal j) +{ + // create VM and set cost limit + auto& vm = WasmEngine::instance(); + vm.initMaxPages(MAX_PAGES); + + auto const ret = vm.check( + wasmCode, + funcName, + params, + createWasmImport(hfs), + hfs ? hfs->getJournal() : j); + + return ret; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +WasmEngine::WasmEngine() : impl(std::make_unique()) +{ +} + +WasmEngine& +WasmEngine::instance() +{ + static WasmEngine e; + return e; +} + +Expected, TER> +WasmEngine::run( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports, + HostFunctions* hfs, + int64_t gasLimit, + beast::Journal j) +{ + return impl->run(wasmCode, funcName, params, imports, hfs, gasLimit, j); +} + +NotTEC +WasmEngine::check( + Bytes const& wasmCode, + std::string_view funcName, + std::vector const& params, + std::vector const& imports, + beast::Journal j) +{ + return impl->check(wasmCode, funcName, params, imports, j); +} + +std::int32_t +WasmEngine::initMaxPages(std::int32_t def) +{ + return impl->initMaxPages(def); +} + +void* +WasmEngine::newTrap(std::string_view msg) +{ + return impl->newTrap(msg); +} + +beast::Journal +WasmEngine::getJournal() const +{ + return impl->getJournal(); +} + +} // namespace ripple